youtubeapi.cpp 5.6 KB

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