aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordec05eba <dec05eba@protonmail.com>2022-04-06 06:55:08 +0200
committerdec05eba <dec05eba@protonmail.com>2022-04-06 06:55:08 +0200
commit19c58ef32be910c5c0c9f37740d0601e37eaafa7 (patch)
tree0404006fb350aab7b70c22392b8955ea0dfaa8c8
parenta5c749701af2fe58fafff36f679a593bc3380421 (diff)
Youtube: fix search, channel page, related videos and comments
For these pages, the json response root is not longer an array. It's instead the first json object in the array.
-rw-r--r--src/plugins/Lbry.cpp4
-rw-r--r--src/plugins/Youtube.cpp282
2 files changed, 135 insertions, 151 deletions
diff --git a/src/plugins/Lbry.cpp b/src/plugins/Lbry.cpp
index feac2c5..92532cb 100644
--- a/src/plugins/Lbry.cpp
+++ b/src/plugins/Lbry.cpp
@@ -83,6 +83,8 @@ namespace QuickMedia {
std::string description;
if(is_channel) {
+ // TODO: Followers
+
const Json::Value &meta_json = result_json["meta"];
if(meta_json.isObject()) {
const Json::Value &claims_in_channel_json = meta_json["claims_in_channel"];
@@ -98,6 +100,8 @@ namespace QuickMedia {
description += name_json.asString();
}
} else {
+ // TODO: Views
+
const Json::Value &timestamp_json = result_json["timestamp"];
if(timestamp_json.isInt64())
description = seconds_to_relative_time_str(time_now - timestamp_json.asInt64());
diff --git a/src/plugins/Youtube.cpp b/src/plugins/Youtube.cpp
index 1cbf477..c32e22e 100644
--- a/src/plugins/Youtube.cpp
+++ b/src/plugins/Youtube.cpp
@@ -678,89 +678,85 @@ namespace QuickMedia {
static BodyItems parse_channel_videos(const Json::Value &json_root, std::string &continuation_token, std::unordered_set<std::string> &added_videos) {
BodyItems body_items;
- if(!json_root.isArray())
+
+ if(!json_root.isObject())
+ return body_items;
+
+ const Json::Value &response_json = json_root["response"];
+ if(!response_json.isObject())
+ return body_items;
+
+ const Json::Value &contents_json = response_json["contents"];
+ if(!contents_json.isObject())
+ return body_items;
+
+ const Json::Value &tcbrr_json = contents_json["twoColumnBrowseResultsRenderer"];
+ if(!tcbrr_json.isObject())
+ return body_items;
+
+ const Json::Value &tabs_json = tcbrr_json["tabs"];
+ if(!tabs_json.isArray())
return body_items;
std::string new_continuation_token;
- for(const Json::Value &json_item : json_root) {
- if(!json_item.isObject())
+ for(const Json::Value &tab_json : tabs_json) {
+ if(!tab_json.isObject())
continue;
- const Json::Value &response_json = json_item["response"];
- if(!response_json.isObject())
+ const Json::Value &tab_renderer_json = tab_json["tabRenderer"];
+ if(!tab_renderer_json.isObject())
continue;
-
- const Json::Value &contents_json = response_json["contents"];
- if(!contents_json.isObject())
+
+ const Json::Value &content_json = tab_renderer_json["content"];
+ if(!content_json.isObject())
continue;
- const Json::Value &tcbrr_json = contents_json["twoColumnBrowseResultsRenderer"];
- if(!tcbrr_json.isObject())
+ const Json::Value &section_list_renderer = content_json["sectionListRenderer"];
+ if(!section_list_renderer.isObject())
continue;
- const Json::Value &tabs_json = tcbrr_json["tabs"];
- if(!tabs_json.isArray())
+ const Json::Value &contents2_json = section_list_renderer["contents"];
+ if(!contents2_json.isArray())
continue;
-
- for(const Json::Value &tab_json : tabs_json) {
- if(!tab_json.isObject())
- continue;
-
- const Json::Value &tab_renderer_json = tab_json["tabRenderer"];
- if(!tab_renderer_json.isObject())
+
+ for(const Json::Value &content_item_json : contents2_json) {
+ if(!content_item_json.isObject())
continue;
- const Json::Value &content_json = tab_renderer_json["content"];
- if(!content_json.isObject())
+ const Json::Value &item_section_renderer_json = content_item_json["itemSectionRenderer"];
+ if(!item_section_renderer_json.isObject())
continue;
- const Json::Value &section_list_renderer = content_json["sectionListRenderer"];
- if(!section_list_renderer.isObject())
+ const Json::Value &item_contents_json = item_section_renderer_json["contents"];
+ if(!item_contents_json.isArray())
continue;
- const Json::Value &contents2_json = section_list_renderer["contents"];
- if(!contents2_json.isArray())
- continue;
-
- for(const Json::Value &content_item_json : contents2_json) {
- if(!content_item_json.isObject())
+ for(const Json::Value &content_json : item_contents_json) {
+ if(!content_json.isObject())
continue;
-
- const Json::Value &item_section_renderer_json = content_item_json["itemSectionRenderer"];
- if(!item_section_renderer_json.isObject())
+
+ const Json::Value &grid_renderer_json = content_json["gridRenderer"];
+ if(!grid_renderer_json.isObject())
continue;
- const Json::Value &item_contents_json = item_section_renderer_json["contents"];
- if(!item_contents_json.isArray())
+ const Json::Value &items_json = grid_renderer_json["items"];
+ if(!items_json.isArray())
continue;
- for(const Json::Value &content_json : item_contents_json) {
- if(!content_json.isObject())
+ for(const Json::Value &item_json : items_json) {
+ if(!item_json.isObject())
continue;
- const Json::Value &grid_renderer_json = content_json["gridRenderer"];
- if(!grid_renderer_json.isObject())
- continue;
+ if(new_continuation_token.empty())
+ new_continuation_token = item_section_renderer_get_continuation_token(item_json);
- const Json::Value &items_json = grid_renderer_json["items"];
- if(!items_json.isArray())
+ const Json::Value &grid_video_renderer = item_json["gridVideoRenderer"];
+ if(!grid_video_renderer.isObject())
continue;
- for(const Json::Value &item_json : 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 = item_json["gridVideoRenderer"];
- if(!grid_video_renderer.isObject())
- continue;
-
- auto body_item = parse_common_video_item(grid_video_renderer, added_videos);
- if(body_item)
- body_items.push_back(std::move(body_item));
- }
+ auto body_item = parse_common_video_item(grid_video_renderer, added_videos);
+ if(body_item)
+ body_items.push_back(std::move(body_item));
}
}
}
@@ -901,31 +897,26 @@ namespace QuickMedia {
DownloadResult result = download_json(json_root, search_url + "&pbj=1&gl=US&hl=en", std::move(additional_args), true);
if(result != DownloadResult::OK) return download_result_to_plugin_result(result);
- if(!json_root.isArray())
+ if(!json_root.isObject())
return PluginResult::ERR;
- for(const Json::Value &json_item : json_root) {
- if(!json_item.isObject())
- continue;
-
- const Json::Value &response_json = json_item["response"];
- if(!response_json.isObject())
- continue;
+ const Json::Value &response_json = json_root["response"];
+ if(!response_json.isObject())
+ return PluginResult::OK;
- const Json::Value &contents_json = response_json["contents"];
- if(!contents_json.isObject())
- continue;
+ const Json::Value &contents_json = response_json["contents"];
+ if(!contents_json.isObject())
+ return PluginResult::OK;
- const Json::Value &tcsrr_json = contents_json["twoColumnSearchResultsRenderer"];
- if(!tcsrr_json.isObject())
- continue;
+ const Json::Value &tcsrr_json = contents_json["twoColumnSearchResultsRenderer"];
+ if(!tcsrr_json.isObject())
+ return PluginResult::OK;
- const Json::Value &primary_contents_json = tcsrr_json["primaryContents"];
- if(!primary_contents_json.isObject())
- continue;
+ const Json::Value &primary_contents_json = tcsrr_json["primaryContents"];
+ if(!primary_contents_json.isObject())
+ return PluginResult::OK;
- parse_section_list_renderer(primary_contents_json["sectionListRenderer"], continuation_token, result_items, added_videos);
- }
+ parse_section_list_renderer(primary_contents_json["sectionListRenderer"], continuation_token, result_items, added_videos);
return PluginResult::OK;
}
@@ -956,49 +947,44 @@ namespace QuickMedia {
DownloadResult result = download_json(json_root, next_url, std::move(additional_args), true);
if(result != DownloadResult::OK) return download_result_to_plugin_result(result);
- if(!json_root.isArray())
+ if(!json_root.isObject())
return PluginResult::ERR;
+ const Json::Value &response_json = json_root["response"];
+ if(!response_json.isObject())
+ return PluginResult::OK;
+
+ const Json::Value &on_response_received_commands_json = response_json["onResponseReceivedCommands"];
+ if(!on_response_received_commands_json.isArray())
+ return PluginResult::OK;
+
std::string new_continuation_token;
- for(const Json::Value &json_item : json_root) {
- if(!json_item.isObject())
+ for(const Json::Value &response_received_command : on_response_received_commands_json) {
+ if(!response_received_command.isObject())
continue;
- const Json::Value &response_json = json_item["response"];
- if(!response_json.isObject())
+ const Json::Value &append_continuation_items_action_json = response_received_command["appendContinuationItemsAction"];
+ if(!append_continuation_items_action_json.isObject())
continue;
- const Json::Value &on_response_received_commands_json = response_json["onResponseReceivedCommands"];
- if(!on_response_received_commands_json.isArray())
+ const Json::Value &continuation_items_json = append_continuation_items_action_json["continuationItems"];
+ if(!continuation_items_json.isArray())
continue;
- for(const Json::Value &response_received_command : on_response_received_commands_json) {
- if(!response_received_command.isObject())
+ for(const Json::Value &continuation_item : continuation_items_json) {
+ if(!continuation_item.isObject())
continue;
- const Json::Value &append_continuation_items_action_json = response_received_command["appendContinuationItemsAction"];
- if(!append_continuation_items_action_json.isObject())
- continue;
+ if(new_continuation_token.empty()) {
+ // Note: item_section_renderer is compatible with continuation_item
+ new_continuation_token = item_section_renderer_get_continuation_token(continuation_item);
+ }
- const Json::Value &continuation_items_json = append_continuation_items_action_json["continuationItems"];
- if(!continuation_items_json.isArray())
+ const Json::Value &item_section_renderer_json = continuation_item["itemSectionRenderer"];
+ if(!item_section_renderer_json.isObject())
continue;
- for(const Json::Value &continuation_item : continuation_items_json) {
- if(!continuation_item.isObject())
- continue;
-
- if(new_continuation_token.empty()) {
- // Note: item_section_renderer is compatible with continuation_item
- new_continuation_token = item_section_renderer_get_continuation_token(continuation_item);
- }
-
- const Json::Value &item_section_renderer_json = continuation_item["itemSectionRenderer"];
- if(!item_section_renderer_json.isObject())
- continue;
-
- parse_item_section_renderer(item_section_renderer_json, added_videos, result_items);
- }
+ parse_item_section_renderer(item_section_renderer_json, added_videos, result_items);
}
}
@@ -1911,66 +1897,60 @@ namespace QuickMedia {
DownloadResult download_result = download_json(json_root, "https://www.youtube.com/watch?v=" + video_id + "&pbj=1&gl=US&hl=en", additional_args, true);
if(download_result != DownloadResult::OK) return result_items;
- if(!json_root.isArray())
+ if(!json_root.isObject())
return result_items;
- std::unordered_set<std::string> added_videos;
+ const Json::Value &response_json = json_root["response"];
+ if(!response_json.isObject())
+ return result_items;
- for(const Json::Value &json_item : json_root) {
- if(!json_item.isObject())
- continue;
+ const Json::Value &contents_json = response_json["contents"];
+ if(!contents_json.isObject())
+ return result_items;
- const Json::Value &response_json = json_item["response"];
- if(!response_json.isObject())
- continue;
+ const Json::Value &tcwnr_json = contents_json["twoColumnWatchNextResults"];
+ if(!tcwnr_json.isObject())
+ return result_items;
- const Json::Value &contents_json = response_json["contents"];
- if(!contents_json.isObject())
- return result_items;
+ if(comments_continuation_token.empty())
+ comments_continuation_token = two_column_watch_next_results_get_comments_continuation_token(tcwnr_json);
- const Json::Value &tcwnr_json = contents_json["twoColumnWatchNextResults"];
- if(!tcwnr_json.isObject())
- return result_items;
+ const Json::Value &secondary_results_json = tcwnr_json["secondaryResults"];
+ if(!secondary_results_json.isObject())
+ return result_items;
- if(comments_continuation_token.empty())
- comments_continuation_token = two_column_watch_next_results_get_comments_continuation_token(tcwnr_json);
+ const Json::Value &secondary_results2_json = secondary_results_json["secondaryResults"];
+ if(!secondary_results2_json.isObject())
+ return result_items;
+
+ const Json::Value &results_json = secondary_results2_json["results"];
+ if(!results_json.isArray())
+ return result_items;
- const Json::Value &secondary_results_json = tcwnr_json["secondaryResults"];
- if(!secondary_results_json.isObject())
- return result_items;
+ std::unordered_set<std::string> added_videos;
+ for(const Json::Value &item_json : results_json) {
+ if(!item_json.isObject())
+ continue;
- const Json::Value &secondary_results2_json = secondary_results_json["secondaryResults"];
- if(!secondary_results2_json.isObject())
- return result_items;
+ auto body_item = parse_compact_video_renderer_json(item_json, added_videos);
+ if(body_item)
+ result_items.push_back(std::move(body_item));
- const Json::Value &results_json = secondary_results2_json["results"];
- if(!results_json.isArray())
- return result_items;
-
- for(const Json::Value &item_json : results_json) {
- if(!item_json.isObject())
+ const Json::Value &compact_autoplay_renderer_json = item_json["compactAutoplayRenderer"];
+ if(!compact_autoplay_renderer_json.isObject())
+ continue;
+
+ const Json::Value &item_contents_json = compact_autoplay_renderer_json["contents"];
+ if(!item_contents_json.isArray())
+ continue;
+
+ for(const Json::Value &content_item_json : item_contents_json) {
+ if(!content_item_json.isObject())
continue;
-
- auto body_item = parse_compact_video_renderer_json(item_json, added_videos);
+
+ auto body_item = parse_compact_video_renderer_json(content_item_json, added_videos);
if(body_item)
result_items.push_back(std::move(body_item));
-
- const Json::Value &compact_autoplay_renderer_json = item_json["compactAutoplayRenderer"];
- if(!compact_autoplay_renderer_json.isObject())
- continue;
-
- const Json::Value &item_contents_json = compact_autoplay_renderer_json["contents"];
- if(!item_contents_json.isArray())
- continue;
-
- for(const Json::Value &content_item_json : item_contents_json) {
- if(!content_item_json.isObject())
- continue;
-
- auto body_item = parse_compact_video_renderer_json(content_item_json, added_videos);
- if(body_item)
- result_items.push_back(std::move(body_item));
- }
}
}