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;
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.1.9) Gecko/20100401 Ubuntu/9.10 (karmic) Firefox/3.5.9");
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-Encoding", "gzip,deflate");
63 request.setRawHeader("Accept-Charset", "ISO-8859-1,utf-8;q=0.7,*;q=0.7");
64 request.setRawHeader("Keep-Alive", "300");
65 request.setRawHeader("Connection", "keep-alive");
66 request.setRawHeader("Cache-Control", "max-age=0");
67 QNetworkReply *reply = _network->get(request);
68 connect(reply, SIGNAL(downloadProgress(qint64,qint64)), this, SLOT(DownloadProgress(qint64,qint64)));
69 connect(reply, SIGNAL(error(QNetworkReply::NetworkError)), this, SLOT(NetworkError(QNetworkReply::NetworkError)));
72 void AbstractSearchClient::DownloadProgress(qint64 a,qint64 b)
74 //std::cout << "Search Progress of " << qPrintable(objectName()) << " - " << a << ", " << b << std::endl;
76 emit Progress(_search_task_id, a, b);
79 void AbstractSearchClient::NetworkError(QNetworkReply::NetworkError error)
81 emit SearchFinished(_search_task_id, false);
82 std::cout << "ERROR: " << error << std::endl;
83 emit Error(_search_task_id);
84 sender()->deleteLater();
88 QList<QTime> AbstractSearchClient::TimesFromString(const QList<QString> &time_strings)
90 QList<QTime> schedule_times;
92 Q_FOREACH(const QString time_str, time_strings) {
93 if (time_str.endsWith("am", Qt::CaseInsensitive) || time_str.endsWith("pm", Qt::CaseInsensitive)) {
100 while (i < time_strings.length()) {
102 while (i < time_strings.length()) {
103 if (time_strings[i].endsWith("am", Qt::CaseInsensitive)) {
106 } else if (time_strings[i].endsWith("pm", Qt::CaseInsensitive)) {
113 QString time_str = time_strings[j] + (am ? "am" : "pm");
114 QTime time = TimeUtils::FromTimeString(time_str);
115 if (time.isValid()) {
116 schedule_times.append(time);
118 std::cout << "ERROR: time " << qPrintable(time_str) << " is invalid." << std::endl;
122 if (i < time_strings.length()) {
123 QString time_str = time_strings[i];
124 QTime time = TimeUtils::FromTimeString(time_str);
125 if (time.isValid()) {
126 schedule_times.append(time);
128 std::cout << "ERROR: time " << qPrintable(time_str) << " is invalid." << std::endl;
130 schedule_times.append(time);
135 Q_FOREACH(const QString time_str, time_strings) {
136 QTime time = TimeUtils::FromTimeString(time_str);
137 if (time.isValid()) {
138 schedule_times.append(time);
140 std::cout << "ERROR: time " << qPrintable(time_str) << " is invalid." << std::endl;
144 return schedule_times;
147 void AbstractSearchClient::FixLocation(QUrl *url)
149 // Try to fix the Google url which returns
150 // wrong locations in some links
151 if (_location.isNull()) {
152 // Fetch location from url on first call (which is still correct)
153 if (url->hasQueryItem("loc")) {
154 _location = url->queryItemValue("loc");
155 } else if (url->hasQueryItem("near")) {
156 _location = url->queryItemValue("near");
157 } else if (url->hasQueryItem("defaultloc")) {
158 _location = url->queryItemValue("defaultloc");
161 // Replace with fetched location in later calls
162 if (url->hasQueryItem("loc")) {
163 url->removeAllQueryItems("loc");
164 url->addQueryItem("loc", _location);
166 if (url->hasQueryItem("near")) {
167 url->removeAllQueryItems("near");
168 url->addQueryItem("near", _location);
170 if (url->hasQueryItem("defaultloc")) {
171 url->removeAllQueryItems("defaultloc");
172 url->addQueryItem("defaultloc", _location);
177 QMutex AbstractSearchClient::_next_search_task_id_mutex;
178 int AbstractSearchClient::_next_search_task_id = 1;