aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--TODO3
-rw-r--r--plugins/Youtube.hpp2
-rw-r--r--src/plugins/Youtube.cpp180
3 files changed, 4 insertions, 181 deletions
diff --git a/TODO b/TODO
index 6ecd650..03d1d25 100644
--- a/TODO
+++ b/TODO
@@ -212,4 +212,5 @@ Improve pinephone video load performance by not restarting mpv on next video. In
Very large resolutions, such as 7680x2160 (id 272) for video https://www.youtube.com/watch?v=GxaH40zpvYc are not supported by the youtube android video loader. Find a way to fix that.
Use std::move(string) for all places where text.set_string is called.
Use reference for text.get_string() in all places.
-Cleanup font sizes that are not visible (or not used for a while). Also do the same for character ranges font texture. \ No newline at end of file
+Cleanup font sizes that are not visible (or not used for a while). Also do the same for character ranges font texture.
+Show video upload date in video description on youtube. \ No newline at end of file
diff --git a/plugins/Youtube.hpp b/plugins/Youtube.hpp
index 2a3b36e..53fb3b7 100644
--- a/plugins/Youtube.hpp
+++ b/plugins/Youtube.hpp
@@ -27,7 +27,6 @@ namespace QuickMedia {
struct YoutubeVideoDetails {
std::string title;
std::string author;
- std::string rating;
std::string views;
std::string description;
};
@@ -174,7 +173,6 @@ namespace QuickMedia {
private:
std::string timestamp;
std::string comments_continuation_token;
- int64_t num_likes = -1;
std::string livestream_url;
std::vector<YoutubeVideoFormat> video_formats;
std::vector<YoutubeAudioFormat> audio_formats;
diff --git a/src/plugins/Youtube.cpp b/src/plugins/Youtube.cpp
index 8ffaebf..9a9ed81 100644
--- a/src/plugins/Youtube.cpp
+++ b/src/plugins/Youtube.cpp
@@ -75,49 +75,6 @@ namespace QuickMedia {
static std::string ysc;
static std::string visitor_info1_live;
- static bool is_whitespace(char c) {
- return (c >= 8 && c <= 13) || c == ' ';
- }
-
- // TODO: Cache this and redownload it when a network request fails with this api key? Do that in the same place as the signature, which means it would be done asynchronously
- static std::string youtube_page_find_api_key() {
- size_t api_key_index;
- size_t api_key_index_end;
- size_t api_key_length;
- std::string website_result;
- std::string::iterator api_key_start;
-
- if(download_to_string("https://www.youtube.com/?gl=US&hl=en", website_result, {}, true) != DownloadResult::OK)
- goto fallback;
-
- api_key_index = website_result.find("INNERTUBE_API_KEY");
- if(api_key_index == std::string::npos)
- goto fallback;
-
- api_key_index += 17;
- api_key_start = std::find_if(website_result.begin() + api_key_index, website_result.end(), [](char c) {
- return c != '"' && c != ':' && !is_whitespace(c);
- });
-
- if(api_key_start == website_result.end())
- goto fallback;
-
- api_key_index = api_key_start - website_result.begin();
- api_key_index_end = website_result.find('"', api_key_index);
- if(api_key_index_end == std::string::npos)
- goto fallback;
-
- api_key_length = api_key_index_end - api_key_index;
- if(api_key_length > 512) // sanity check
- goto fallback;
-
- return website_result.substr(api_key_index, api_key_length);
-
- fallback:
- fprintf(stderr, "Failed to fetch youtube api key, fallback to %s\n", api_key.c_str());
- return "AIzaSyAO_FJ2SlqU8Q4STEHLGCilw_Y9_11qcW8";
- }
-
static std::string cpn;
static bool generate_random_characters(char *buffer, int buffer_size, const char *alphabet, size_t alphabet_size) {
@@ -2036,109 +1993,6 @@ namespace QuickMedia {
return "";
}
- // Returns -1 if not found
- static int64_t toggle_button_renderer_get_likes(const Json::Value &toggle_button_renderer_json) {
- if(!toggle_button_renderer_json.isObject())
- return -1;
-
- const Json::Value &default_text_json = toggle_button_renderer_json["defaultText"];
- if(!default_text_json.isObject())
- return -1;
-
- const Json::Value &simple_text_json = default_text_json["simpleText"];
- if(!simple_text_json.isString())
- return -1;
-
- // The accessibility text for videos with 0 likes is "No Likes". We instead check for 0 in the simple text.
- if(strcmp(simple_text_json.asCString(), "0") == 0)
- return 0;
-
- const Json::Value &accessibility_json = default_text_json["accessibility"];
- if(!accessibility_json.isObject())
- return -1;
-
- const Json::Value &accessibility_data_json = accessibility_json["accessibilityData"];
- if(!accessibility_data_json.isObject())
- return -1;
-
- const Json::Value &label_json = accessibility_data_json["label"];
- if(!label_json.isString())
- return -1;
-
- std::string label = label_json.asString();
- size_t space_index = label.find(' ');
- if(space_index != std::string::npos)
- label.erase(space_index);
-
- string_replace_all(label, ",", "");
-
- errno = 0;
- char *endptr;
- const int64_t num_likes = strtoll(label.c_str(), &endptr, 10);
- if(endptr != label.c_str() && errno == 0)
- return num_likes;
- return -1;
- }
-
- // Returns -1 if not found
- static int64_t two_column_watch_next_results_get_video_likes(const Json::Value &tcwnr_json) {
- if(!tcwnr_json.isObject())
- return -1;
-
- const Json::Value &results_json = tcwnr_json["results"];
- if(!results_json.isObject())
- return -1;
-
- const Json::Value &results2_json = results_json["results"];
- if(!results2_json.isObject())
- return -1;
-
- const Json::Value &contents_json = results2_json["contents"];
- if(!contents_json.isArray())
- return -1;
-
- for(const Json::Value &content_item_json : contents_json) {
- if(!content_item_json.isObject())
- continue;
-
- const Json::Value &video_primary_info_renderer_json = content_item_json["videoPrimaryInfoRenderer"];
- if(!video_primary_info_renderer_json.isObject())
- continue;
-
- const Json::Value &video_actions_json = video_primary_info_renderer_json["videoActions"];
- if(!video_actions_json.isObject())
- continue;
-
- const Json::Value &menu_renderer_json = video_actions_json["menuRenderer"];
- if(!menu_renderer_json.isObject())
- continue;
-
- const Json::Value &top_level_buttons_json = menu_renderer_json["topLevelButtons"];
- if(!top_level_buttons_json.isArray())
- continue;
-
- for(const Json::Value &top_level_button_json : top_level_buttons_json) {
- if(!top_level_button_json.isObject())
- continue;
-
- const Json::Value &toggle_button_renderer_json = top_level_button_json["toggleButtonRenderer"];
- if(!toggle_button_renderer_json.isObject())
- continue;
-
- const Json::Value &target_id_json = toggle_button_renderer_json["targetId"];
- if(!target_id_json.isString())
- continue;
-
- if(strcmp(target_id_json.asCString(), "watch-like") != 0)
- continue;
-
- return toggle_button_renderer_get_likes(toggle_button_renderer_json);
- }
- }
-
- return -1;
- }
-
static int youtube_url_timestamp_to_seconds(const std::string &timestamp) {
int hours = 0;
int minutes = 0;
@@ -2183,7 +2037,6 @@ namespace QuickMedia {
BodyItems YoutubeVideoPage::get_related_media(const std::string &url) {
comments_continuation_token.clear();
- num_likes = -1;
BodyItems result_items;
std::string video_id;
@@ -2229,9 +2082,6 @@ namespace QuickMedia {
if(comments_continuation_token.empty())
comments_continuation_token = two_column_watch_next_results_get_comments_continuation_token(tcwnr_json);
- if(num_likes == -1)
- num_likes = two_column_watch_next_results_get_video_likes(tcwnr_json);
-
const Json::Value &secondary_results_json = tcwnr_json["secondaryResults"];
if(!secondary_results_json.isObject())
return result_items;
@@ -2274,11 +2124,7 @@ namespace QuickMedia {
return result_items;
}
- static int64_t round_double(double value) {
- return value + 0.5;
- }
-
- static std::shared_ptr<BodyItem> video_details_to_body_item(const YoutubeVideoDetails &video_details, int64_t num_likes) {
+ static std::shared_ptr<BodyItem> video_details_to_body_item(const YoutubeVideoDetails &video_details) {
auto body_item = BodyItem::create(video_details.title);
std::string description;
@@ -2286,25 +2132,6 @@ namespace QuickMedia {
description = number_separate_thousand_commas(video_details.views) + " view" + (video_details.views == "1" ? "" : "s");
}
- if(!video_details.rating.empty()) {
- if(!description.empty())
- description += " • ";
-
- double average_rating = atof(video_details.rating.c_str());
- // Minimum rating for a video is 1.0, even if a video only has dislikes
- average_rating -= 1.0;
- if(average_rating < 0.00000001)
- average_rating = 0.00000001;
-
- if(num_likes == -1) {
- description += "rated " + std::to_string(average_rating / 4.0 * 5.0).substr(0, 4) + "/5.0";
- } else {
- const int64_t num_ratings = num_likes * (4.0 / average_rating);
- const int64_t num_dislikes = (num_ratings - num_likes);
- description += "👍 " + number_separate_thousand_commas(std::to_string(num_likes)) + " 👎 " + number_separate_thousand_commas(std::to_string(num_dislikes));
- }
- }
-
if(!video_details.author.empty()) {
if(!description.empty())
description += '\n';
@@ -2325,7 +2152,7 @@ namespace QuickMedia {
PluginResult YoutubeVideoPage::get_related_pages(const BodyItems &related_videos, const std::string &channel_url, std::vector<Tab> &result_tabs) {
auto description_page_body = create_body();
- description_page_body->append_item(video_details_to_body_item(video_details, num_likes));
+ description_page_body->append_item(video_details_to_body_item(video_details));
auto related_page_body = create_body(false, true);
related_page_body->set_items(related_videos);
@@ -2506,7 +2333,6 @@ namespace QuickMedia {
static void video_details_clear(YoutubeVideoDetails &video_details) {
video_details.title.clear();
video_details.author.clear();
- video_details.rating.clear();
video_details.views.clear();
video_details.description.clear();
}
@@ -2568,13 +2394,11 @@ namespace QuickMedia {
const Json::Value &title_json = video_details_json["title"];
const Json::Value &author_json = video_details_json["author"];
- const Json::Value &average_rating_json = video_details_json["averageRating"];
const Json::Value &view_count_json = video_details_json["viewCount"];
const Json::Value &short_description_json = video_details_json["shortDescription"];
if(title_json.isString()) video_details.title = title_json.asString();
if(author_json.isString()) video_details.author = author_json.asString();
- if(average_rating_json.isDouble()) video_details.rating = std::to_string(average_rating_json.asDouble());
if(view_count_json.isString()) video_details.views = view_count_json.asString();
if(short_description_json.isString()) video_details.description = short_description_json.asString();