aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordec05eba <dec05eba@protonmail.com>2022-10-28 13:35:52 +0200
committerdec05eba <dec05eba@protonmail.com>2022-10-28 13:35:52 +0200
commitb5c6432fbf3b12d1a65fdfded14c49abb49bc93c (patch)
tree25e65ba20196c4a5957d2e40db9c1ebb8d09d132
parent506b58f0322716bc33b2fea2760f17a9fc559271 (diff)
Youtube: fix channel page not loading (jesus what a clusterfuck)
-rw-r--r--src/plugins/Youtube.cpp133
1 files changed, 102 insertions, 31 deletions
diff --git a/src/plugins/Youtube.cpp b/src/plugins/Youtube.cpp
index caf3a25..4dbb6c4 100644
--- a/src/plugins/Youtube.cpp
+++ b/src/plugins/Youtube.cpp
@@ -691,11 +691,11 @@ namespace QuickMedia {
if(!json_root.isObject())
return;
- const Json::Value &response_json = json_root["response"];
- if(!response_json.isObject())
- return;
+ const Json::Value *response_json = &json_root["response"];
+ if(!response_json->isObject())
+ response_json = &json_root;
- const Json::Value &contents_json = response_json["contents"];
+ const Json::Value &contents_json = (*response_json)["contents"];
if(!contents_json.isObject())
return;
@@ -720,8 +720,41 @@ namespace QuickMedia {
continue;
const Json::Value &section_list_renderer = content_json["sectionListRenderer"];
- if(!section_list_renderer.isObject())
+ if(!section_list_renderer.isObject()) {
+ const Json::Value &rich_grid_renderer_json = content_json["richGridRenderer"];
+ if(!rich_grid_renderer_json.isObject())
+ continue;
+
+ const Json::Value &contents2_json = rich_grid_renderer_json["contents"];
+ if(!contents2_json.isArray())
+ continue;
+
+ for(const Json::Value &content_item_json : contents2_json) {
+ if(!content_item_json.isObject())
+ continue;
+
+ if(continuation_token.empty())
+ continuation_token = item_section_renderer_get_continuation_token(content_item_json);
+
+ const Json::Value &rich_item_renderer_json = content_item_json["richItemRenderer"];
+ if(!rich_item_renderer_json.isObject())
+ continue;
+
+ const Json::Value &item_content_json = rich_item_renderer_json["content"];
+ if(!item_content_json.isObject())
+ continue;
+
+ const Json::Value &video_renderer_json = item_content_json["videoRenderer"];
+ if(!video_renderer_json.isObject())
+ continue;
+
+ auto body_item = parse_common_video_item(video_renderer_json, added_videos);
+ if(body_item)
+ body_items.push_back(std::move(body_item));
+ }
+
continue;
+ }
const Json::Value &contents2_json = section_list_renderer["contents"];
if(!contents2_json.isArray())
@@ -1487,6 +1520,43 @@ namespace QuickMedia {
return PluginResult::OK;
}
+ static void channel_page_continuation_get_content(const Json::Value &continuation_items_json, std::string &new_continuation_token, std::unordered_set<std::string> &added_videos, BodyItems &result_items) {
+ if(!continuation_items_json.isArray())
+ return;
+
+ for(const Json::Value &item_json : continuation_items_json) {
+ if(!item_json.isObject())
+ continue;
+
+ if(new_continuation_token.empty())
+ new_continuation_token = item_section_renderer_get_continuation_token(item_json);
+
+ const Json::Value &grid_video_renderer_json = item_json["gridVideoRenderer"];
+ const Json::Value &item_section_renderer_json = item_json["itemSectionRenderer"];
+ const Json::Value &rich_item_renderer_json = item_json["richItemRenderer"];
+
+ if(grid_video_renderer_json.isObject()) {
+ auto body_item = parse_common_video_item(grid_video_renderer_json, added_videos);
+ if(body_item)
+ result_items.push_back(std::move(body_item));
+ } else if(item_section_renderer_json.isObject()) {
+ parse_item_section_renderer(item_section_renderer_json, added_videos, result_items);
+ } else if(rich_item_renderer_json.isObject()) {
+ const Json::Value &content_json = rich_item_renderer_json["content"];
+ if(!content_json.isObject())
+ continue;
+
+ const Json::Value &video_renderer_json = content_json["videoRenderer"];
+ if(!video_renderer_json.isObject())
+ continue;
+
+ auto body_item = parse_common_video_item(video_renderer_json, added_videos);
+ if(body_item)
+ result_items.push_back(std::move(body_item));
+ }
+ }
+ }
+
PluginResult YoutubeChannelPage::search_get_continuation(const std::string &url, const std::string &current_continuation_token, BodyItems &result_items) {
if(current_continuation_token.empty())
return PluginResult::OK;
@@ -1534,38 +1604,37 @@ namespace QuickMedia {
if(!json_root.isObject())
return PluginResult::ERR;
- const Json::Value &on_response_received_actions_json = json_root["onResponseReceivedActions"];
- if(!on_response_received_actions_json.isArray())
- return PluginResult::ERR;
-
std::string new_continuation_token;
- for(const Json::Value &json_item : on_response_received_actions_json) {
- if(!json_item.isObject())
- continue;
-
- const Json::Value &append_continuation_items_action_json = json_item["appendContinuationItemsAction"];
- if(!append_continuation_items_action_json.isObject())
- continue;
+ result_items.clear();
- const Json::Value &continuation_items_json = append_continuation_items_action_json["continuationItems"];
- if(!continuation_items_json.isArray())
- continue;
+ const Json::Value &on_response_received_actions_json = json_root["onResponseReceivedActions"];
+ if(on_response_received_actions_json.isArray()) {
+ for(const Json::Value &json_item : on_response_received_actions_json) {
+ if(!json_item.isObject())
+ continue;
- for(const Json::Value &item_json : continuation_items_json) {
- if(!item_json.isObject())
+ const Json::Value &append_continuation_items_action_json = json_item["appendContinuationItemsAction"];
+ if(!append_continuation_items_action_json.isObject())
continue;
- if(new_continuation_token.empty())
- new_continuation_token = item_section_renderer_get_continuation_token(item_json);
+ channel_page_continuation_get_content(append_continuation_items_action_json["continuationItems"], new_continuation_token, added_videos, result_items);
+ }
+ } else {
+ // What a cluster-fuck. Sometimes youtube returns the same front page twice, so we try to parse it
+ // and if we dont get any new items then request the page again (I hope we got a new continuation key???).
- const Json::Value &grid_video_renderer = item_json["gridVideoRenderer"];
- if(grid_video_renderer.isObject()) {
- auto body_item = parse_common_video_item(grid_video_renderer, added_videos);
- if(body_item)
- result_items.push_back(std::move(body_item));
- } else {
- parse_item_section_renderer(item_json["itemSectionRenderer"], added_videos, result_items);
- }
+ const Json::Value &continuation_contents_json = json_root["continuationContents"];
+ if(!continuation_contents_json.isObject())
+ return PluginResult::ERR;
+
+ const Json::Value &rich_grid_continuation_json = continuation_contents_json["richGridContinuation"];
+ if(!rich_grid_continuation_json.isObject())
+ return PluginResult::ERR;
+
+ channel_page_continuation_get_content(rich_grid_continuation_json["contents"], new_continuation_token, added_videos, result_items);
+ if(result_items.empty()) { // Hopefully we dont have an infinite loop...
+ continuation_token = std::move(new_continuation_token);
+ return search_get_continuation(url, current_continuation_token, result_items);
}
}
@@ -1600,6 +1669,7 @@ namespace QuickMedia {
if(result != DownloadResult::OK) return download_result_to_plugin_result(result);
if(json_root.isObject()) {
+ search_page_submit_suggestion_handler(json_root, continuation_token, result_items, added_videos);
parse_channel_videos(json_root, continuation_token, added_videos, result_items);
return PluginResult::OK;
}
@@ -1608,6 +1678,7 @@ namespace QuickMedia {
return PluginResult::ERR;
for(const Json::Value &json_item : json_root) {
+ search_page_submit_suggestion_handler(json_root, continuation_token, result_items, added_videos);
parse_channel_videos(json_item, continuation_token, added_videos, result_items);
}