123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196 |
- #include "youtubeapi.hpp"
- #include <iostream>
- namespace ytapi {
- bool performCurlRequest(
- std::string url,
- std::string key,
- std::stringstream* response)
- {
- // Добавляем ключ API
- url += "&key=" + key;
- // TODO: oAuth
-
- CURL* handle = curl_easy_init();
- if (!handle) return false;
- curl_easy_setopt(handle, CURLOPT_URL, url.c_str());
- curl_easy_setopt(handle, CURLOPT_WRITEFUNCTION, &writeHttpToString);
- curl_easy_setopt(handle, CURLOPT_WRITEDATA, response);
- int result = curl_easy_perform(handle);
- curl_easy_cleanup(handle);
- if (result != CURLE_OK) {
- // Произошла ошибка
- return false;
- }
- return true;
- }
- void performCurlDownload(std::string url, std::string save_path) {
- CURL* handle = curl_easy_init();
- if (!handle) return;
- FILE* fp;
- fp = fopen(save_path.c_str(), "wb");
- curl_easy_setopt(handle, CURLOPT_URL, url.c_str());
- curl_easy_setopt(handle, CURLOPT_WRITEFUNCTION, &writeHttpToFile);
- curl_easy_setopt(handle, CURLOPT_WRITEDATA, fp);
- curl_easy_perform(handle);
- curl_easy_cleanup(handle);
- fclose(fp);
- }
-
- std::string urlencode(const std::string& decoded) {
- const auto encoded_value = curl_easy_escape(nullptr, decoded.c_str(), static_cast<int>(decoded.length()));
- std::string result(encoded_value);
- curl_free(encoded_value);
- return result;
- }
- std::string urldecode(const std::string& encoded) {
- int output_length;
- const auto decoded_value = curl_easy_unescape(
- nullptr,
- encoded.c_str(),
- static_cast<int>(encoded.length()),
- &output_length
- );
- std::string result(decoded_value, output_length);
- curl_free(decoded_value);
- return result;
- }
- size_t writeHttpToString(char* ptr, size_t size, size_t nmemb, void* userdata)
- {
- std::string data((const char*) ptr, (size_t) size * nmemb);
- *((std::stringstream*) userdata) << data;
- return size * nmemb;
- }
- size_t writeHttpToFile(void* ptr, size_t size, size_t nmemb, FILE* userdata)
- {
- size_t written = fwrite(ptr, size, nmemb, userdata);
- return written;
- }
- SearchResults getVideoIDsByQuery(std::string query, std::string key)
- {
- std::stringstream response;
- std::string url;
- // Формирование URL
- url += "https://youtube.googleapis.com/youtube/v3/search?type=video&part=snippet&maxResult=25&q=";
- url += urlencode(query);
-
- bool successfull = performCurlRequest(url, key, &response);
- if (!successfull) {
- // Пустой ответ если произошла ошибка
- return SearchResults{Status::NET_ERROR, {}};
- }
- // Парсинг ответа
- auto json = nlohmann::json::parse(response.str());
- auto items = json["items"];
- std::vector<std::string> output;
-
- for (auto it = items.begin(); it != items.end(); ++it) {
- auto item = it.value();
- auto yt_id = item["id"]["videoId"];
- output.push_back(yt_id);
- }
- return SearchResults{Status::OK, output};
- }
- // TODO: https://www.returnyoutubedislike.com/
- Video getVideoByYTID(std::string yt_id, std::string key) {
- std::stringstream response;
- //std::stringstream response_rating;
- std::string url;
- Video output;
- // -- Общие сведения --
- url = "https://youtube.googleapis.com/youtube/v3/videos?part=snippet,contentDetails,statistics&id=";
- url += yt_id;
- performCurlRequest(url, key, &response);
- auto json = nlohmann::json::parse(response);
- auto item = json["items"][0];
- auto snippet = item["snippet"];
- auto content_details = item["contentDetails"];
- auto stats = item["statistics"];
- output.yt_id = yt_id;
- output.title = Glib::ustring(snippet["title"]);
- output.description = Glib::ustring(snippet["description"]);
- output.duration = std::string(content_details["duration"]);
- output.author_yt_id = std::string(snippet["channelId"]);
- output.author_name = Glib::ustring(snippet["channelTitle"]);
- output.published_at = std::string(snippet["publishedAt"]);
- output.views_count = std::stoi(stats["viewCount"].template get<std::string>());
- // -- Оценка видео --
- // TODO: с помощью API узнавать оценку видео которую я поставил
- output.rating = 0;
- // -- Превью --
- // С помощью .back() получаем самое большое изображение превью и
- // сохраняем его в ответ видео
- output.big_thumbnail = snippet["thumbnails"].back()["url"];
- return output;
- }
- void downloadMediumThumnail(std::string yt_id, std::string save_path)
- {
- // Формирование URL
- std::string url = "https://img.youtube.com/vi/" + yt_id + "/mqdefault.jpg";
- performCurlDownload(url, save_path);
- }
-
- void downloadLargeThumnail(std::string yt_id, std::string save_path)
- {
- // Формирование URL
- std::string url = "https://img.youtube.com/vi/" + yt_id + "/maxresdefault.jpg";
- performCurlDownload(url, save_path);
- }
- void downloadThumbnail(std::string url, std::string save_path)
- {
- performCurlDownload(url, save_path);
- }
- /*void setVideoRating(std::string ytid, int rating, std::string secret)
- {
- std::string url = "https://www.googleapis.com/youtube/v3/videos/rate";
- url += "?id=" + ytid;
- url += "&rating=";
- std::string rating_value;
- switch(rating)
- {
- case 0:
- rating_value = "none";
- break;
- case 1:
- rating_value = "like";
- break;
- case 2:
- rating_value = "dislike";
- break;
- default:
- rating_value = "none";
- break;
- }
- url += rating;
- std::stringstream response;
- performCurlRequest(
- url,
- secret,
- &response
- );
- // TODO: обработка ошибок
- }*/
- }
|