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