aboutsummaryrefslogtreecommitdiff
path: root/plugins/Youtube.hpp
blob: 746619c401536fa9f641efc7ac1d98d232e7488c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
#pragma once

#include "Page.hpp"
#include "../include/AsyncTask.hpp"
#include <unordered_set>

namespace QuickMedia {
    class YoutubeSearchPage : public Page {
    public:
        YoutubeSearchPage(Program *program) : Page(program) {}
        const char* get_title() const override { return "Search"; }
        bool search_is_filter() override { return false; }
        SearchResult search(const std::string &str, BodyItems &result_items) override;
        PluginResult get_page(const std::string &str, int page, BodyItems &result_items) override;
        PluginResult submit(const std::string &title, const std::string &url, std::vector<Tab> &result_tabs) override;
    private:
        PluginResult search_get_continuation(const std::string &url, const std::string &continuation_token, BodyItems &result_items);
    private:
        std::string search_url;
        std::string continuation_token;
        int current_page = 0;
        std::unordered_set<std::string> added_videos;
    };

    class YoutubeCommentsPage : public LazyFetchPage {
    public:
        YoutubeCommentsPage(Program *program, const std::string &xsrf_token, const std::string &continuation_token) : LazyFetchPage(program), xsrf_token(xsrf_token), continuation_token(continuation_token) {}
        const char* get_title() const override { return "Comments"; }
        PluginResult get_page(const std::string &str, int page, BodyItems &result_items) override;
        PluginResult submit(const std::string &title, const std::string &url, std::vector<Tab> &result_tabs) override;
        PluginResult lazy_fetch(BodyItems &result_items) override;
    private:
        int current_page = 0;
        std::string xsrf_token;
        std::string continuation_token;
    };

    class YoutubeCommentRepliesPage : public LazyFetchPage {
    public:
        YoutubeCommentRepliesPage(Program *program, const std::string &xsrf_token, const std::string &continuation_token) : LazyFetchPage(program), xsrf_token(xsrf_token), continuation_token(continuation_token) {}
        const char* get_title() const override { return "Comment replies"; }
        PluginResult get_page(const std::string &str, int page, BodyItems &result_items) override;
        PluginResult submit(const std::string &title, const std::string &url, std::vector<Tab> &result_tabs) override;
        PluginResult lazy_fetch(BodyItems &result_items) override;
    private:
        int current_page = 0;
        std::string xsrf_token;
        std::string continuation_token;
    };

    class YoutubeChannelPage : public LazyFetchPage, public TrackablePage {
    public:
        YoutubeChannelPage(Program *program, std::string url, std::string continuation_token, std::string title) : LazyFetchPage(program), TrackablePage(title, url), url(url), continuation_token(std::move(continuation_token)), title(title) {}
        const char* get_title() const override { return title.c_str(); }
        bool search_is_filter() override { return false; }
        SearchResult search(const std::string &str, BodyItems &result_items) override;
        PluginResult get_page(const std::string &str, int page, BodyItems &result_items) override;
        PluginResult submit(const std::string &title, const std::string &url, std::vector<Tab> &result_tabs) override;
        PluginResult lazy_fetch(BodyItems &result_items) override;

        TrackResult track(const std::string &str) override;
        bool is_trackable() const override { return true; }

        std::unordered_set<std::string> added_videos;
    private:
        PluginResult search_get_continuation(const std::string &url, const std::string &continuation_token, BodyItems &result_items);
    private:
        const std::string url;
        std::string continuation_token;
        const std::string title;
        int current_page = 0;
    };

    struct YoutubeSubscriptionTaskResult {
        std::shared_ptr<BodyItem> body_item;
        time_t timestamp = 0;
    };

    class YoutubeSubscriptionsPage : public LazyFetchPage {
    public:
        YoutubeSubscriptionsPage(Program *program) : LazyFetchPage(program) {}
        const char* get_title() const override { return "Subscriptions"; }
        PluginResult submit(const std::string &title, const std::string &url, std::vector<Tab> &result_tabs) override;
        PluginResult lazy_fetch(BodyItems &result_items) override;
    private:
        std::array<AsyncTask<std::vector<YoutubeSubscriptionTaskResult>>, 4> subscription_load_tasks; // TODO: Use multiple curl outputs instead?
    };

    class YoutubeRecommendedPage : public LazyFetchPage {
    public:
        YoutubeRecommendedPage(Program *program) : LazyFetchPage(program) {}
        const char* get_title() const override { return "Recommended"; }
        PluginResult get_page(const std::string &str, int page, BodyItems &result_items) override;
        PluginResult submit(const std::string &title, const std::string &url, std::vector<Tab> &result_tabs) override;
        PluginResult lazy_fetch(BodyItems &result_items) override;
        bool reload_on_page_change() override { return true; }
    private:
        PluginResult search_get_continuation(const std::string &continuation_token, BodyItems &result_items);
    private:
        int current_page = 0;
        std::string continuation_token;
        std::unordered_set<std::string> added_videos;
    };

    class YoutubeRelatedVideosPage : public RelatedVideosPage {
    public:
        YoutubeRelatedVideosPage(Program *program) : RelatedVideosPage(program) {}
        PluginResult submit(const std::string&, const std::string&, std::vector<Tab> &result_tabs) override;
    };

    class YoutubeVideoPage : public VideoPage {
    public:
        YoutubeVideoPage(Program *program, const std::string &url) : VideoPage(program), url(url) {}
        const char* get_title() const override { return ""; }
        BodyItems get_related_media(const std::string &url, std::string &channel_url) override;
        std::unique_ptr<Page> create_search_page(Program *program, int &search_delay) override;
        std::unique_ptr<Page> create_comments_page(Program *program) override;
        std::unique_ptr<RelatedVideosPage> create_related_videos_page(Program *program, const std::string &video_url, const std::string &video_title) override;
        std::unique_ptr<Page> create_channels_page(Program *program, const std::string &channel_url) override;
        std::string get_url() override { return url; }
    private:
        std::string xsrf_token;
        std::string comments_continuation_token;
        std::string url;

        std::string playback_url;
        std::string watchtime_url;
        std::string tracking_url;
    };
}