aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authordec05eba <dec05eba@protonmail.com>2020-07-23 01:39:37 +0200
committerdec05eba <dec05eba@protonmail.com>2020-07-23 01:39:37 +0200
commitb7fadd729d278e8daccac12c5268928c2ced1ad0 (patch)
tree9a96cc6b8f734879164f99743a72c2e3ed749867 /src
parent795cc3d873df13bfe2abaa56b17ea247bc892c20 (diff)
Show youtube search result in the order they appear on the website
Diffstat (limited to 'src')
-rw-r--r--src/plugins/Youtube.cpp50
1 files changed, 43 insertions, 7 deletions
diff --git a/src/plugins/Youtube.cpp b/src/plugins/Youtube.cpp
index b68e513..6923d04 100644
--- a/src/plugins/Youtube.cpp
+++ b/src/plugins/Youtube.cpp
@@ -3,6 +3,7 @@
#include <json/reader.h>
#include <json/writer.h>
#include <string.h>
+#include <unordered_set>
namespace QuickMedia {
static void iterate_suggestion_result(const Json::Value &value, std::vector<std::string> &result_items, int &iterate_count) {
@@ -16,7 +17,7 @@ namespace QuickMedia {
}
}
- static std::unique_ptr<BodyItem> parse_content_video_renderer(const Json::Value &content_item_json) {
+ static std::unique_ptr<BodyItem> parse_content_video_renderer(const Json::Value &content_item_json, std::unordered_set<std::string> &added_videos) {
if(!content_item_json.isObject())
return nullptr;
@@ -29,6 +30,9 @@ namespace QuickMedia {
return nullptr;
std::string video_id_str = video_id_json.asString();
+ if(added_videos.find(video_id_str) != added_videos.end())
+ return nullptr;
+
std::string thumbnail_url = "https://img.youtube.com/vi/" + video_id_str + "/hqdefault.jpg";
const char *title = nullptr;
@@ -51,6 +55,7 @@ namespace QuickMedia {
auto body_item = std::make_unique<BodyItem>(title);
body_item->url = "https://www.youtube.com/watch?v=" + video_id_str;
body_item->thumbnail_url = std::move(thumbnail_url);
+ added_videos.insert(video_id_str);
return body_item;
}
@@ -91,6 +96,8 @@ namespace QuickMedia {
if(!json_root.isArray())
return PluginResult::ERR;
+ std::unordered_set<std::string> added_videos;
+
for(const Json::Value &json_item : json_root) {
if(!json_item.isObject())
continue;
@@ -137,7 +144,7 @@ namespace QuickMedia {
continue;
const Json::Value &rich_item_contents = rich_item_renderer_json["content"];
- std::unique_ptr<BodyItem> body_item = parse_content_video_renderer(rich_item_contents);
+ std::unique_ptr<BodyItem> body_item = parse_content_video_renderer(rich_item_contents, added_videos);
if(body_item)
result_items.push_back(std::move(body_item));
}
@@ -242,16 +249,43 @@ namespace QuickMedia {
return continuation_json.asString();
}
- static void parse_item_section_renderer(const Json::Value &item_section_renderer_json, std::string &continuation_token, BodyItems &result_items) {
+ static void parse_item_section_renderer(const Json::Value &item_section_renderer_json, std::string &continuation_token, std::unordered_set<std::string> &added_videos, BodyItems &result_items) {
if(continuation_token.empty())
continuation_token = item_section_renderer_get_continuation_token(item_section_renderer_json);
const Json::Value &item_contents_json = item_section_renderer_json["contents"];
if(!item_contents_json.isArray())
return;
-
+
+ for(const Json::Value &content_item_json : item_contents_json) {
+ if(!content_item_json.isObject())
+ continue;
+
+ const Json::Value &shelf_renderer_json = content_item_json["shelfRenderer"];
+ if(!shelf_renderer_json.isObject())
+ continue;
+
+ const Json::Value &item_content_json = shelf_renderer_json["content"];
+ if(!item_content_json.isObject())
+ continue;
+
+ const Json::Value &vertical_list_renderer_json = item_content_json["verticalListRenderer"];
+ if(!vertical_list_renderer_json.isObject())
+ continue;
+
+ const Json::Value &items_json = vertical_list_renderer_json["items"];
+ if(!items_json.isArray())
+ continue;
+
+ for(const Json::Value &item_json : items_json) {
+ std::unique_ptr<BodyItem> body_item = parse_content_video_renderer(item_json, added_videos);
+ if(body_item)
+ result_items.push_back(std::move(body_item));
+ }
+ }
+
for(const Json::Value &content_item_json : item_contents_json) {
- std::unique_ptr<BodyItem> body_item = parse_content_video_renderer(content_item_json);
+ std::unique_ptr<BodyItem> body_item = parse_content_video_renderer(content_item_json, added_videos);
if(body_item)
result_items.push_back(std::move(body_item));
}
@@ -288,6 +322,7 @@ namespace QuickMedia {
return SuggestionResult::ERR;
std::string continuation_token;
+ std::unordered_set<std::string> added_videos; /* The input contains duplicates, filter them out! */
for(const Json::Value &json_item : json_root) {
if(!json_item.isObject())
@@ -325,7 +360,7 @@ namespace QuickMedia {
if(!item_section_renderer_json.isObject())
continue;
- parse_item_section_renderer(item_section_renderer_json, continuation_token, result_items);
+ parse_item_section_renderer(item_section_renderer_json, continuation_token, added_videos, result_items);
}
}
@@ -367,6 +402,7 @@ namespace QuickMedia {
return;
std::string next_continuation_token;
+ std::unordered_set<std::string> added_videos;
for(const Json::Value &json_item : json_root) {
if(!json_item.isObject())
@@ -385,7 +421,7 @@ namespace QuickMedia {
continue;
// Note: item_section_continuation json object is compatible with item_section_renderer json object
- parse_item_section_renderer(item_section_continuation_json, next_continuation_token, result_items);
+ parse_item_section_renderer(item_section_continuation_json, next_continuation_token, added_videos, result_items);
}
}