youtubeapi.cpp 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. #include "youtubeapi.hpp"
  2. namespace ytapi {
  3. std::string urlencode(const std::string& decoded) {
  4. const auto encoded_value = curl_easy_escape(nullptr, decoded.c_str(), static_cast<int>(decoded.length()));
  5. std::string result(encoded_value);
  6. curl_free(encoded_value);
  7. return result;
  8. }
  9. std::string urldecode(const std::string& encoded) {
  10. int output_length;
  11. const auto decoded_value = curl_easy_unescape(
  12. nullptr,
  13. encoded.c_str(),
  14. static_cast<int>(encoded.length()),
  15. &output_length
  16. );
  17. std::string result(decoded_value, output_length);
  18. curl_free(decoded_value);
  19. return result;
  20. }
  21. size_t write_http_data(char* ptr, size_t size, size_t nmemb, void* userdata) {
  22. std::string data((const char*) ptr, (size_t) size * nmemb);
  23. *((std::stringstream*) userdata) << data;
  24. return size * nmemb;
  25. }
  26. std::vector<db::video> getVideosByQuery(std::string api_key, std::string query) {
  27. std::stringstream response;
  28. std::string url;
  29. std::vector<db::video> output;
  30. CURL* handle;
  31. handle = curl_easy_init();
  32. if (!handle) {
  33. return output;
  34. }
  35. // Формирование URL
  36. url += "https://youtube.googleapis.com/youtube/v3/search?type=video&part=snippet&maxResult=25&q=";
  37. url += urlencode(query);
  38. url += "&key=";
  39. url += api_key;
  40. curl_easy_setopt(handle, CURLOPT_URL, url.c_str());
  41. curl_easy_setopt(handle, CURLOPT_WRITEFUNCTION, &write_http_data);
  42. curl_easy_setopt(handle, CURLOPT_WRITEDATA, &response);
  43. curl_easy_perform(handle);
  44. curl_easy_cleanup(handle);
  45. return output;
  46. }
  47. std::vector<db::video> getVideosFromJSON(std::string input) {
  48. auto json = nlohmann::json::parse(input);
  49. auto items = json["items"];
  50. std::vector<db::video> output;
  51. for (auto it = items.begin(); it != items.end(); ++it) {
  52. auto item = it.value();
  53. auto yt_id = item["id"]["videoId"];
  54. auto snippet = item["snippet"];
  55. // Проверить существует ли видео в базе данных
  56. db::video current_video;
  57. if (db::getVideoByYTID(yt_id, &current_video)) {
  58. output.push_back(current_video);
  59. continue;
  60. }
  61. // Видео в базе данных не существует. Добавляем!
  62. // 1. Ищем автора по его yt_id
  63. db::author current_author;
  64. if (!db::getAuthorByYTID(snippet["channelId"], &current_author)) {
  65. // 1.5 Автора в базе данных нет, создаём
  66. current_author.yt_id = snippet["channelId"];
  67. current_author.name = Glib::ustring(snippet["channelTitle"]);
  68. db::addAuthor(&current_author);
  69. }
  70. // Перезаписать snippet
  71. // 2. Заполняем объект видео данными из JSON
  72. current_video.yt_id = yt_id;
  73. current_video.title = Glib::ustring(snippet["title"]);
  74. current_video.description = Glib::ustring(snippet["description"]);
  75. current_video.published_at = std::string(snippet["publishedAt"]);
  76. current_video.author_obj = current_author;
  77. // 3. Добавляем видео в БД
  78. db::addVideo(&current_video);
  79. // 4. И в выходной массив
  80. output.push_back(current_video);
  81. }
  82. return output;
  83. }
  84. }