]> git.sur5r.net Git - minitube/blob - src/networkaccess.cpp
4c4058ee95a56bef68343afb5fe66042382c51e6
[minitube] / src / networkaccess.cpp
1 #include "networkaccess.h"
2 #include "constants.h"
3 #include <QtGui>
4
5 namespace The {
6     NetworkAccess* http();
7 }
8
9 /*
10 const QString USER_AGENT = QString(Constants::APP_NAME)
11                            + " " + Constants::VERSION
12                            + " (" + Constants::WEBSITE + ")";
13 */
14
15 const QString USER_AGENT = "Mozilla/5.0 (X11; U; Linux x86; en-US; rv:1.9.2.12) Gecko/20101028 Firefox/3.6.12";
16
17 NetworkReply::NetworkReply(QNetworkReply *networkReply) : QObject(networkReply) {
18     this->networkReply = networkReply;
19 }
20
21 void NetworkReply::finished() {
22
23     QUrl redirection = networkReply->attribute(QNetworkRequest::RedirectionTargetAttribute).toUrl();
24     if (redirection.isValid()) {
25
26         // qDebug() << "Redirect!"; // << redirection;
27
28         QNetworkReply *redirectReply = The::http()->simpleGet(redirection, networkReply->operation());
29
30         setParent(redirectReply);
31         networkReply->deleteLater();
32         networkReply = redirectReply;
33
34         // when the request is finished we'll invoke the target method
35         connect(networkReply, SIGNAL(finished()), this, SLOT(finished()), Qt::AutoConnection);
36
37         return;
38     }
39
40
41     emit finished(networkReply);
42
43     // get the HTTP response body
44     QByteArray bytes = networkReply->readAll();
45
46     emit data(bytes);
47
48     // bye bye my reply
49     // this will also delete this NetworkReply as the QNetworkReply is its parent
50     networkReply->deleteLater();
51 }
52
53 void NetworkReply::requestError(QNetworkReply::NetworkError code) {
54     emit error(networkReply);
55 }
56
57 /* --- NetworkAccess --- */
58
59 NetworkAccess::NetworkAccess( QObject* parent) : QObject( parent ) {}
60
61 QNetworkReply* NetworkAccess::manualGet(QNetworkRequest request, int operation) {
62
63     QNetworkAccessManager *manager = The::networkAccessManager();
64
65     QNetworkReply *networkReply;
66     switch (operation) {
67
68     case QNetworkAccessManager::GetOperation:
69         qDebug() << "GET" << request.url().toEncoded();
70         networkReply = manager->get(request);
71         break;
72
73     case QNetworkAccessManager::HeadOperation:
74         qDebug() << "HEAD" << request.url().toEncoded();
75         networkReply = manager->head(request);
76         break;
77
78     default:
79         qDebug() << "Unknown operation:" << operation;
80         return 0;
81
82     }
83
84     // error handling
85     connect(networkReply, SIGNAL(error(QNetworkReply::NetworkError)),
86             this, SLOT(error(QNetworkReply::NetworkError)));
87
88     return networkReply;
89 }
90
91 QNetworkReply* NetworkAccess::simpleGet(QUrl url, int operation) {
92
93     QNetworkRequest request(url);
94     request.setRawHeader("User-Agent", USER_AGENT.toUtf8());
95     request.setRawHeader("Accept-Charset", "ISO-8859-1,utf-8;q=0.7,*;q=0.7");
96     request.setRawHeader("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8");
97     request.setRawHeader("Accept-Language", "en-us,en;q=0.5");
98     // request.setRawHeader("Connection", "Keep-Alive");
99
100     return manualGet(request, operation);
101 }
102
103 NetworkReply* NetworkAccess::get(const QUrl url) {
104
105     QNetworkReply *networkReply = simpleGet(url);
106     NetworkReply *reply = new NetworkReply(networkReply);
107
108     // error signal
109     connect(networkReply, SIGNAL(error(QNetworkReply::NetworkError)),
110             reply, SLOT(requestError(QNetworkReply::NetworkError)));
111
112     // when the request is finished we'll invoke the target method
113     connect(networkReply, SIGNAL(finished()), reply, SLOT(finished()), Qt::AutoConnection);
114
115     return reply;
116
117 }
118
119 NetworkReply* NetworkAccess::head(const QUrl url) {
120
121     QNetworkReply *networkReply = simpleGet(url, QNetworkAccessManager::HeadOperation);
122     NetworkReply *reply = new NetworkReply(networkReply);
123
124     // error signal
125     connect(networkReply, SIGNAL(error(QNetworkReply::NetworkError)),
126             reply, SLOT(requestError(QNetworkReply::NetworkError)));
127
128     // when the request is finished we'll invoke the target method
129     connect(networkReply, SIGNAL(finished()), reply, SLOT(finished()), Qt::AutoConnection);
130
131     return reply;
132
133 }
134
135 /*** sync ***/
136
137
138 QNetworkReply* NetworkAccess::syncGet(QUrl url) {
139
140     working = true;
141
142     networkReply = simpleGet(url);
143     connect(networkReply, SIGNAL(metaDataChanged()),
144             this, SLOT(syncMetaDataChanged()), Qt::AutoConnection);
145     connect(networkReply, SIGNAL(finished()),
146             this, SLOT(syncFinished()), Qt::AutoConnection);
147     connect(networkReply, SIGNAL(error(QNetworkReply::NetworkError)),
148             this, SLOT(error(QNetworkReply::NetworkError)));
149
150     // A little trick to make this function blocking
151     while (working) {
152         // Do something else, maybe even network processing events
153         qApp->processEvents();
154     }
155
156     networkReply->deleteLater();
157     return networkReply;
158
159 }
160
161 void NetworkAccess::syncMetaDataChanged() {
162
163     QUrl redirection = networkReply->attribute(QNetworkRequest::RedirectionTargetAttribute).toUrl();
164     if (redirection.isValid()) {
165
166         qDebug() << "Redirect" << redirection;
167         networkReply->deleteLater();
168         syncGet(redirection);
169
170         /*
171         QNetworkAccessManager *manager = The::networkAccessManager();
172         networkReply->deleteLater();
173         networkReply = manager->get(QNetworkRequest(redirection));
174         connect(networkReply, SIGNAL(metaDataChanged()),
175                 this, SLOT(metaDataChanged()), Qt::AutoConnection);
176         connect(networkReply, SIGNAL(finished()),
177                 this, SLOT(finished()), Qt::AutoConnection);
178         */
179     }
180
181 }
182
183 void NetworkAccess::syncFinished() {
184     // got it!
185     working = false;
186 }
187
188 void NetworkAccess::error(QNetworkReply::NetworkError code) {
189     // get the QNetworkReply that sent the signal
190     QNetworkReply *networkReply = static_cast<QNetworkReply *>(sender());
191     if (!networkReply) {
192         qDebug() << "Cannot get sender";
193         return;
194     }
195
196     // Ignore HEADs
197     if (networkReply->operation() == QNetworkAccessManager::HeadOperation)
198         return;
199
200     // report the error in the status bar
201     QMainWindow* mainWindow = dynamic_cast<QMainWindow*>(qApp->topLevelWidgets().first());
202     if (mainWindow) mainWindow->statusBar()->showMessage(
203             tr("Network error: %1").arg(networkReply->errorString()));
204
205     qDebug() << "Network error:" << networkReply->errorString() << code;
206
207     networkReply->deleteLater();
208 }
209
210 QByteArray NetworkAccess::syncGetBytes(QUrl url) {
211     return syncGet(url)->readAll();
212 }
213
214 QString NetworkAccess::syncGetString(QUrl url) {
215     return QString::fromUtf8(syncGetBytes(url));
216 }