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