1 // Copyright 2010 Jochen Becher
3 // This file is part of MovieSchedule.
5 // MovieSchedule is free software: you can redistribute it and/or modify
6 // it under the terms of the GNU General Public License as published by
7 // the Free Software Foundation, either version 3 of the License, or
8 // (at your option) any later version.
10 // MovieSchedule is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 // GNU General Public License for more details.
15 // You should have received a copy of the GNU General Public License
16 // along with MovieSchedule. If not, see <http://www.gnu.org/licenses/>.
18 #include "abstractsearchclient.h"
20 #include "utils/timeutils.h"
22 #include <QMutexLocker>
25 AbstractSearchClient::AbstractSearchClient(QObject *parent)
27 _network(new QNetworkAccessManager(this)),
28 _search_task_id(INVALID_SEARCH_TASK_ID),
31 connect(_network, SIGNAL(finished(QNetworkReply *)),
32 this, SLOT(ReplyFinished(QNetworkReply*)));
34 QMutexLocker locker(&_next_search_task_id_mutex);
35 _search_task_id = _next_search_task_id++;
39 AbstractSearchClient::~AbstractSearchClient()
43 void AbstractSearchClient::Search(const QUrl &url, int start)
47 emit SearchStarted(_search_task_id);
49 QNetworkRequest request;
51 if (_start != 0 && !url.hasQueryItem("start")) {
52 xurl.addQueryItem("start", QString::number(_start));
55 //std::cout << "URL: " << qPrintable(QString(xurl.toEncoded())) << std::endl;
57 //request.setRawHeader("User-Agent", "Mozilla/5.0 (X11; U; Linux i686; de; rv:1.9.2.8) Gecko/20100723 Ubuntu/9.10 (karmic) Firefox/3.6.8");
58 request.setRawHeader("User-Agent", "Mozilla/5.0");
59 //request.setRawHeader("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8");
60 request.setRawHeader("Accept", "application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8");
61 request.setRawHeader("Accept-Language", "en-gb;q=1.0,en;q=0.9,de-de;q=0.5,de;q=0.3");
62 //request.setRawHeader("Accept-Language", "en-us,en;q=0.8,de-de;q=0.5,de;q=0.3");
63 //request.setRawHeader("Accept-Encoding", "gzip,deflate");
64 request.setRawHeader("Accept-Charset", "ISO-8859-1,utf-8;q=0.7,*;q=0.7");
65 request.setRawHeader("Keep-Alive", "115");
66 request.setRawHeader("Connection", "keep-alive");
67 request.setRawHeader("Cache-Control", "max-age=0");
68 QNetworkReply *reply = _network->get(request);
69 connect(reply, SIGNAL(downloadProgress(qint64,qint64)), this, SLOT(DownloadProgress(qint64,qint64)));
70 connect(reply, SIGNAL(error(QNetworkReply::NetworkError)), this, SLOT(NetworkError(QNetworkReply::NetworkError)));
73 void AbstractSearchClient::SearchEncodedUrl(const QString &encoded_url, int start)
75 QUrl url = QUrl::fromEncoded((QString("http://www.google.com") + encoded_url).toAscii());
79 void AbstractSearchClient::DownloadProgress(qint64 a,qint64 b)
81 //std::cout << "Search Progress of " << qPrintable(objectName()) << " - " << a << ", " << b << std::endl;
83 emit Progress(_search_task_id, a, b);
86 void AbstractSearchClient::NetworkError(QNetworkReply::NetworkError error)
88 emit SearchFinished(_search_task_id, false);
89 std::cout << "ERROR: " << error << std::endl;
90 emit Error(_search_task_id);
91 sender()->deleteLater();
95 QList<QTime> AbstractSearchClient::TimesFromString(const QList<QString> &time_strings)
97 QList<QTime> schedule_times;
99 Q_FOREACH(const QString time_str, time_strings) {
100 if (time_str.endsWith("am", Qt::CaseInsensitive) || time_str.endsWith("pm", Qt::CaseInsensitive)) {
107 while (i < time_strings.length()) {
109 while (i < time_strings.length()) {
110 if (time_strings[i].endsWith("am", Qt::CaseInsensitive)) {
113 } else if (time_strings[i].endsWith("pm", Qt::CaseInsensitive)) {
120 QString time_str = time_strings[j] + (am ? "am" : "pm");
121 QTime time = TimeUtils::FromTimeString(time_str);
122 if (time.isValid()) {
123 schedule_times.append(time);
125 std::cout << "ERROR: time " << qPrintable(time_str) << " is invalid." << std::endl;
129 if (i < time_strings.length()) {
130 QString time_str = time_strings[i];
131 QTime time = TimeUtils::FromTimeString(time_str);
132 if (time.isValid()) {
133 schedule_times.append(time);
135 std::cout << "ERROR: time " << qPrintable(time_str) << " is invalid." << std::endl;
137 schedule_times.append(time);
142 Q_FOREACH(const QString time_str, time_strings) {
143 QTime time = TimeUtils::FromTimeString(time_str);
144 if (time.isValid()) {
145 schedule_times.append(time);
147 std::cout << "ERROR: time " << qPrintable(time_str) << " is invalid." << std::endl;
151 return schedule_times;
154 void AbstractSearchClient::FixLocation(QUrl *url)
157 // Try to fix the Google url which returns
158 // wrong locations in some links
159 if (_location.isNull()) {
160 // Fetch location from url on first call (which is still correct)
161 if (url->hasQueryItem("loc")) {
162 _location = url->queryItemValue("loc");
163 } else if (url->hasQueryItem("near")) {
164 _location = url->queryItemValue("near");
165 } else if (url->hasQueryItem("defaultloc")) {
166 _location = url->queryItemValue("defaultloc");
169 // Replace with fetched location in later calls
170 if (url->hasQueryItem("loc")) {
171 url->removeAllQueryItems("loc");
172 url->addQueryItem("loc", _location);
174 if (url->hasQueryItem("near")) {
175 url->removeAllQueryItems("near");
176 url->addQueryItem("near", _location);
178 if (url->hasQueryItem("defaultloc")) {
179 url->removeAllQueryItems("defaultloc");
180 url->addQueryItem("defaultloc", _location);
188 QMutex AbstractSearchClient::_next_search_task_id_mutex;
189 int AbstractSearchClient::_next_search_task_id = 1;