]> git.sur5r.net Git - minitube/blob - src/yt/invidious/ivsearch.cpp
New upstream version 3.8
[minitube] / src / yt / invidious / ivsearch.cpp
1 #include "ivsearch.h"
2
3 #include "http.h"
4 #include "httputils.h"
5 #include "invidious.h"
6 #include "ivlistparser.h"
7 #include "mainwindow.h"
8 #include "searchparams.h"
9 #include "video.h"
10
11 namespace {
12 int invidiousFixedMax = 20;
13 }
14
15 IVSearch::IVSearch(SearchParams *searchParams, QObject *parent)
16     : IVVideoSource(parent), searchParams(searchParams) {
17     searchParams->setParent(this);
18 }
19
20 void IVSearch::reallyLoadVideos(int max, int startIndex) {
21     QUrl url = Invidious::instance().method("search");
22     if (url.isEmpty()) {
23         QTimer::singleShot(500, this, [this] { handleError("No baseUrl"); });
24         return;
25     }
26
27     QUrlQuery q(url);
28
29     // invidious always returns 20 results
30     int page = ((startIndex - 1) / invidiousFixedMax) + 1;
31     q.addQueryItem("page", QString::number(page));
32
33     if (!searchParams->keywords().isEmpty()) {
34         q.addQueryItem("q", searchParams->keywords());
35     }
36
37     if (!searchParams->channelId().isEmpty())
38         q.addQueryItem("channelId", searchParams->channelId());
39
40     switch (searchParams->sortBy()) {
41     case SearchParams::SortByNewest:
42         q.addQueryItem("sort_by", "upload_date");
43         break;
44     case SearchParams::SortByViewCount:
45         q.addQueryItem("sort_by", "view_count");
46         break;
47     case SearchParams::SortByRating:
48         q.addQueryItem("sort_by", "rating");
49         break;
50     }
51
52     switch (searchParams->duration()) {
53     case SearchParams::DurationShort:
54         q.addQueryItem("duration", "short");
55         break;
56     case SearchParams::DurationMedium:
57         q.addQueryItem("duration", "medium");
58         break;
59     case SearchParams::DurationLong:
60         q.addQueryItem("duration", "long");
61         break;
62     }
63
64     switch (searchParams->time()) {
65     case SearchParams::TimeToday:
66         q.addQueryItem("date", "today");
67         break;
68     case SearchParams::TimeWeek:
69         q.addQueryItem("date", "week");
70         break;
71     case SearchParams::TimeMonth:
72         q.addQueryItem("date", "month");
73         break;
74     }
75
76     switch (searchParams->quality()) {
77     case SearchParams::QualityHD:
78         q.addQueryItem("features", "hd");
79         break;
80     }
81
82     url.setQuery(q);
83
84     // qWarning() << "YT3 search" << url.toString();
85     auto reply = Invidious::cachedHttp().get(url);
86     connect(reply, SIGNAL(data(QByteArray)), SLOT(parseResults(QByteArray)));
87     connect(reply, &HttpReply::error, this, &IVSearch::handleError);
88 }
89
90 void IVSearch::parseResults(const QByteArray &data) {
91     if (aborted) return;
92
93     QJsonDocument doc = QJsonDocument::fromJson(data);
94     const QJsonArray items = doc.array();
95     if (items.isEmpty()) {
96         handleError("No videos");
97         return;
98     }
99
100     IVListParser parser(items);
101     const QVector<Video *> &videos = parser.getVideos();
102
103     if (items.size() > invidiousFixedMax) invidiousFixedMax = items.size();
104
105     if (name.isEmpty() && !searchParams->channelId().isEmpty()) {
106         if (!videos.isEmpty()) {
107             name = videos.at(0)->getChannelTitle();
108             if (!searchParams->keywords().isEmpty()) {
109                 name += QLatin1String(": ") + searchParams->keywords();
110             }
111         }
112         emit nameChanged(name);
113     }
114
115     emit gotVideos(videos);
116     emit finished(videos.size());
117 }
118
119 QString IVSearch::getName() {
120     if (!name.isEmpty()) return name;
121     if (!searchParams->keywords().isEmpty()) return searchParams->keywords();
122     return QString();
123 }
124
125 const QList<QAction *> &IVSearch::getActions() {
126     static const QList<QAction *> channelActions = {
127             MainWindow::instance()->getAction("subscribeChannel")};
128     if (searchParams->channelId().isEmpty()) {
129         static const QList<QAction *> noActions;
130         return noActions;
131     }
132     return channelActions;
133 }
134
135 int IVSearch::maxResults() {
136     return invidiousFixedMax;
137 }