youtubeapi.cpp 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196
  1. #include "youtubeapi.hpp"
  2. #include <iostream>
  3. namespace ytapi {
  4. bool performCurlRequest(
  5. std::string url,
  6. std::string key,
  7. std::stringstream* response)
  8. {
  9. // Добавляем ключ API
  10. url += "&key=" + key;
  11. // TODO: oAuth
  12. CURL* handle = curl_easy_init();
  13. if (!handle) return false;
  14. curl_easy_setopt(handle, CURLOPT_URL, url.c_str());
  15. curl_easy_setopt(handle, CURLOPT_WRITEFUNCTION, &writeHttpToString);
  16. curl_easy_setopt(handle, CURLOPT_WRITEDATA, response);
  17. int result = curl_easy_perform(handle);
  18. curl_easy_cleanup(handle);
  19. if (result != CURLE_OK) {
  20. // Произошла ошибка
  21. return false;
  22. }
  23. return true;
  24. }
  25. void performCurlDownload(std::string url, std::string save_path) {
  26. CURL* handle = curl_easy_init();
  27. if (!handle) return;
  28. FILE* fp;
  29. fp = fopen(save_path.c_str(), "wb");
  30. curl_easy_setopt(handle, CURLOPT_URL, url.c_str());
  31. curl_easy_setopt(handle, CURLOPT_WRITEFUNCTION, &writeHttpToFile);
  32. curl_easy_setopt(handle, CURLOPT_WRITEDATA, fp);
  33. curl_easy_perform(handle);
  34. curl_easy_cleanup(handle);
  35. fclose(fp);
  36. }
  37. std::string urlencode(const std::string& decoded) {
  38. const auto encoded_value = curl_easy_escape(nullptr, decoded.c_str(), static_cast<int>(decoded.length()));
  39. std::string result(encoded_value);
  40. curl_free(encoded_value);
  41. return result;
  42. }
  43. std::string urldecode(const std::string& encoded) {
  44. int output_length;
  45. const auto decoded_value = curl_easy_unescape(
  46. nullptr,
  47. encoded.c_str(),
  48. static_cast<int>(encoded.length()),
  49. &output_length
  50. );
  51. std::string result(decoded_value, output_length);
  52. curl_free(decoded_value);
  53. return result;
  54. }
  55. size_t writeHttpToString(char* ptr, size_t size, size_t nmemb, void* userdata)
  56. {
  57. std::string data((const char*) ptr, (size_t) size * nmemb);
  58. *((std::stringstream*) userdata) << data;
  59. return size * nmemb;
  60. }
  61. size_t writeHttpToFile(void* ptr, size_t size, size_t nmemb, FILE* userdata)
  62. {
  63. size_t written = fwrite(ptr, size, nmemb, userdata);
  64. return written;
  65. }
  66. SearchResults getVideoIDsByQuery(std::string query, std::string key)
  67. {
  68. std::stringstream response;
  69. std::string url;
  70. // Формирование URL
  71. url += "https://youtube.googleapis.com/youtube/v3/search?type=video&part=snippet&maxResult=25&q=";
  72. url += urlencode(query);
  73. bool successfull = performCurlRequest(url, key, &response);
  74. if (!successfull) {
  75. // Пустой ответ если произошла ошибка
  76. return SearchResults{Status::NET_ERROR, {}};
  77. }
  78. // Парсинг ответа
  79. auto json = nlohmann::json::parse(response.str());
  80. auto items = json["items"];
  81. std::vector<std::string> output;
  82. for (auto it = items.begin(); it != items.end(); ++it) {
  83. auto item = it.value();
  84. auto yt_id = item["id"]["videoId"];
  85. output.push_back(yt_id);
  86. }
  87. return SearchResults{Status::OK, output};
  88. }
  89. // TODO: https://www.returnyoutubedislike.com/
  90. Video getVideoByYTID(std::string yt_id, std::string key) {
  91. std::stringstream response;
  92. //std::stringstream response_rating;
  93. std::string url;
  94. Video output;
  95. // -- Общие сведения --
  96. url = "https://youtube.googleapis.com/youtube/v3/videos?part=snippet,contentDetails,statistics&id=";
  97. url += yt_id;
  98. performCurlRequest(url, key, &response);
  99. auto json = nlohmann::json::parse(response);
  100. auto item = json["items"][0];
  101. auto snippet = item["snippet"];
  102. auto content_details = item["contentDetails"];
  103. auto stats = item["statistics"];
  104. output.yt_id = yt_id;
  105. output.title = Glib::ustring(snippet["title"]);
  106. output.description = Glib::ustring(snippet["description"]);
  107. output.duration = std::string(content_details["duration"]);
  108. output.author_yt_id = std::string(snippet["channelId"]);
  109. output.author_name = Glib::ustring(snippet["channelTitle"]);
  110. output.published_at = std::string(snippet["publishedAt"]);
  111. output.views_count = std::stoi(stats["viewCount"].template get<std::string>());
  112. // -- Оценка видео --
  113. // TODO: с помощью API узнавать оценку видео которую я поставил
  114. output.rating = 0;
  115. // -- Превью --
  116. // С помощью .back() получаем самое большое изображение превью и
  117. // сохраняем его в ответ видео
  118. output.big_thumbnail = snippet["thumbnails"].back()["url"];
  119. return output;
  120. }
  121. void downloadMediumThumnail(std::string yt_id, std::string save_path)
  122. {
  123. // Формирование URL
  124. std::string url = "https://img.youtube.com/vi/" + yt_id + "/mqdefault.jpg";
  125. performCurlDownload(url, save_path);
  126. }
  127. void downloadLargeThumnail(std::string yt_id, std::string save_path)
  128. {
  129. // Формирование URL
  130. std::string url = "https://img.youtube.com/vi/" + yt_id + "/maxresdefault.jpg";
  131. performCurlDownload(url, save_path);
  132. }
  133. void downloadThumbnail(std::string url, std::string save_path)
  134. {
  135. performCurlDownload(url, save_path);
  136. }
  137. /*void setVideoRating(std::string ytid, int rating, std::string secret)
  138. {
  139. std::string url = "https://www.googleapis.com/youtube/v3/videos/rate";
  140. url += "?id=" + ytid;
  141. url += "&rating=";
  142. std::string rating_value;
  143. switch(rating)
  144. {
  145. case 0:
  146. rating_value = "none";
  147. break;
  148. case 1:
  149. rating_value = "like";
  150. break;
  151. case 2:
  152. rating_value = "dislike";
  153. break;
  154. default:
  155. rating_value = "none";
  156. break;
  157. }
  158. url += rating;
  159. std::stringstream response;
  160. performCurlRequest(
  161. url,
  162. secret,
  163. &response
  164. );
  165. // TODO: обработка ошибок
  166. }*/
  167. }