Initial commit (software version 0.2.0)
[movie-schedule] / src / searchclients / abstractsearchclient.cpp
1 // Copyright 2010 Jochen Becher
2 //
3 // This file is part of MovieSchedule.
4 //
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.
9 //
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.
14 //
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/>.
17
18 #include "abstractsearchclient.h"
19
20 #include <QMutexLocker>
21 #include <iostream>
22
23 AbstractSearchClient::AbstractSearchClient(QObject *parent)
24     : QObject(parent),
25     _network(new QNetworkAccessManager(this)),
26     _search_task_id(INVALID_SEARCH_TASK_ID),
27     _start(0)
28 {
29     connect(_network, SIGNAL(finished(QNetworkReply *)),
30              this, SLOT(ReplyFinished(QNetworkReply*)));
31     {
32         QMutexLocker locker(&_next_search_task_id_mutex);
33         _search_task_id = _next_search_task_id++;
34     }
35 }
36
37 AbstractSearchClient::~AbstractSearchClient()
38 {
39 }
40
41 void AbstractSearchClient::Search(const QUrl &url, int start)
42 {
43     _start = start;
44     if (start == 0) {
45         emit SearchStarted(_search_task_id);
46     }
47     QNetworkRequest request;
48     QUrl xurl(url);
49     if (_start != 0) {
50         xurl.addQueryItem("start", QString::number(_start));
51     }
52     FixLocation(&xurl);
53     //std::cout << "URL: " << qPrintable(QString(xurl.toEncoded())) << std::endl;
54     request.setUrl(xurl);
55     //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");
56     request.setRawHeader("User-Agent", "Mozilla/5.0");
57     //request.setRawHeader("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8");
58     request.setRawHeader("Accept", "application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8");
59     request.setRawHeader("Accept-Language", "en-gb;q=1.0,en;q=0.9,de-de;q=0.5,de;q=0.3");
60     //request.setRawHeader("Accept-Encoding", "gzip,deflate");
61     request.setRawHeader("Accept-Charset", "ISO-8859-1,utf-8;q=0.7,*;q=0.7");
62     request.setRawHeader("Keep-Alive", "300");
63     request.setRawHeader("Connection", "keep-alive");
64     request.setRawHeader("Cache-Control", "max-age=0");
65     QNetworkReply *reply = _network->get(request);
66     connect(reply, SIGNAL(downloadProgress(qint64,qint64)), this, SLOT(DownloadProgress(qint64,qint64)));
67     connect(reply, SIGNAL(error(QNetworkReply::NetworkError)), this, SLOT(NetworkError(QNetworkReply::NetworkError)));
68 }
69
70 void AbstractSearchClient::DownloadProgress(qint64 a,qint64 b)
71 {
72     //std::cout << "Search Progress of " << qPrintable(objectName()) << " - " << a << ", " << b << std::endl;
73     //sleep(1);
74     emit Progress(_search_task_id, a, b);
75 }
76
77 void AbstractSearchClient::NetworkError(QNetworkReply::NetworkError error)
78 {
79     emit SearchFinished(_search_task_id, false);
80     std::cout << "ERROR: " << error << std::endl;
81     emit Error(_search_task_id);
82     sender()->deleteLater();
83     deleteLater();
84 }
85
86 void AbstractSearchClient::FixLocation(QUrl *url)
87 {
88     // Try to fix the Google url which returns
89     // wrong locations in some links
90     if (_location.isNull()) {
91         // Fetch location from url on first call (which is still correct)
92         if (url->hasQueryItem("loc")) {
93             _location = url->queryItemValue("loc");
94         } else if (url->hasQueryItem("near")) {
95             _location = url->queryItemValue("near");
96         } else if (url->hasQueryItem("defaultloc")) {
97             _location = url->queryItemValue("defaultloc");
98         }
99     } else {
100         // Replace with fetched location in later calls
101         if (url->hasQueryItem("loc")) {
102             url->removeAllQueryItems("loc");
103             url->addQueryItem("loc", _location);
104         }
105         if (url->hasQueryItem("near")) {
106             url->removeAllQueryItems("near");
107             url->addQueryItem("near", _location);
108         }
109         if (url->hasQueryItem("defaultloc")) {
110             url->removeAllQueryItems("defaultloc");
111             url->addQueryItem("defaultloc", _location);
112         }
113     }
114 }
115
116 QMutex AbstractSearchClient::_next_search_task_id_mutex;
117 int AbstractSearchClient::_next_search_task_id = 1;