Initial checkin
[opensuse:qtobs.git] / obsaccess.cpp
1 /*
2  *  Qt OBS - A Qt based OBS client
3  *
4  *  Copyright (C) 2010 Novell Inc, Klaas Freitag <freitag@suse.de>
5  *
6  *  This program is free software: you can redistribute it and/or modify
7  *  it under the terms of the GNU General Public License as published by
8  *  the Free Software Foundation, either version 2 of the License, or
9  *  (at your option) version 3.
10  *
11  *  This program is distributed in the hope that it will be useful,
12  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  *  GNU General Public License for more details.
15  *
16  *  You should have received a copy of the GNU General Public License
17  *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
18  *
19  *  --
20  *  Written by Klaas Freitag <freitag@suse.de>
21  *  Contributors:
22  */
23
24 #include <QAuthenticator>
25 #include <QUrl>
26 #include <QDebug>
27 #include <QNetworkRequest>
28 #include <QDomDocument>
29 #include <QXmlSimpleReader>
30 #include <QXmlInputSource>
31
32 #include "obsaccess.h"
33 #if 0
34 OBSAccess::OBSAccess()
35 {
36   OBSAccess( QUrl("https://api.opensuse.org") );
37 }
38 #endif
39 OBSAccess::OBSAccess( const QUrl& baseUrl )
40 {
41   mManager = new QNetworkAccessManager( this );
42   mOBSBase = baseUrl;
43
44   connect( mManager, SIGNAL( authenticationRequired ( QNetworkReply* , QAuthenticator* )),
45            this, SLOT( authenticate(QNetworkReply*,QAuthenticator*)) );
46   connect( mManager, SIGNAL( proxyAuthenticationRequired( const QNetworkProxy&, QAuthenticator* )),
47            this, SLOT( slotProxyAuthenticate( const QNetworkProxy&, QAuthenticator* ) ) );
48   connect( mManager, SIGNAL(finished(QNetworkReply*)),
49            this, SLOT(replyFinished(QNetworkReply*)));
50
51 }
52
53 void OBSAccess::setCredentials( const QString& username, const QString& passwd )
54 {
55   mOBSUser = username;
56   mOBSPasswd = passwd;
57 }
58
59 void OBSAccess::authenticate( QNetworkReply* /*reply*/, QAuthenticator* authenticator)
60 {
61   qDebug() << "Authenticate here!" << endl;
62   if( authenticator ) {
63     authenticator->setPassword( mOBSPasswd );
64     authenticator->setUser( mOBSUser );
65   }
66 }
67
68 void OBSAccess::slotProxyAuthenticate( const QNetworkProxy&, QAuthenticator* )
69 {
70   qDebug() << "Proxy Authentication!" << endl;
71 }
72
73 void OBSAccess::getPath( const QString& path )
74 {
75   QUrl url( mOBSBase.toString()+path );
76
77   if( !url.isValid() ) {
78     qDebug() << "Invalid OBS URL" << endl;
79     return;
80   }
81   QNetworkRequest request;
82   qDebug() << "Url: " << url.toString() << endl;
83   request.setUrl( url );
84   request.setRawHeader("User-Agent", "QtOBS 0.8");
85
86   mReply = mManager->get(request);
87
88   connect( mReply, SIGNAL( readyRead() ), this, SLOT( slotReadyRead()) );
89   connect( mReply, SIGNAL( sslErrors(QList<QSslError>)),
90            this, SLOT( slotSSLErrors( QList<QSslError> ) ) );
91   connect( mReply, SIGNAL( error(QNetworkReply::NetworkError) ),
92            this, SLOT( slotNetworkError(QNetworkReply::NetworkError)) );
93   connect( mReply, SIGNAL( finished()), this, SLOT(slotReplyFinished()));
94 }
95
96 void OBSAccess::slotReadyRead()
97 {
98   if( mXmlStreamReader ) {
99     QByteArray arr = mReply->readAll();
100     qDebug() << "DATA: " << arr;
101     mXmlStreamReader->addData( arr );
102   }
103 }
104
105 void OBSAccess::slotReplyFinished()
106 {
107   qDebug() << "========= Reply Finished!" << endl;
108   if( mXmlStreamReader->parse() ) {
109     emit parsingOk();
110   } else {
111     emit parsingFailed();
112   }
113 }
114
115
116 QXmlStreamReader* OBSAccess::xmlReadHandler()
117 {
118     return mXmlStreamReader;
119 }
120
121 void OBSAccess::setXmlReadHandler( OBSXmlReader *reader )
122 {
123   mXmlStreamReader = reader;
124 }
125
126 void OBSAccess::slotSSLErrors( QList<QSslError> )
127 {
128   qDebug() << "SSL shit happens!" << endl;
129 }
130
131 void OBSAccess::replyFinished(QNetworkReply* reply)
132 {
133   /*
134          * Reply is finished!
135          * We'll ask for the reply about the Redirection attribute
136          * http://doc.trolltech.com/qnetworkrequest.html#Attribute-enum
137          */
138   QVariant possibleRedirectUrl =
139       reply->attribute(QNetworkRequest::RedirectionTargetAttribute);
140
141   /* We'll deduct if the redirection is valid in the redirectUrl function */
142   mUrlRedirectedTo = this->redirectUrl(possibleRedirectUrl.toUrl(),
143                                        mUrlRedirectedTo);
144
145   /* If the URL is not empty, we're being redirected. */
146   if(!mUrlRedirectedTo.isEmpty()) {
147     QString text = QString("Redirected to ").append(mUrlRedirectedTo.toString());
148
149     /* We'll do another request to the redirection url. */
150     mManager->get(QNetworkRequest(mUrlRedirectedTo));
151   } else {
152     /*
153      * We weren't redirected anymore
154      * so we arrived to the final destination...
155      */
156     QString text = QString("Arrived to ").append(reply->url().toString());
157     qDebug() << text << endl;
158     /* ...so this can be cleared. */
159     mUrlRedirectedTo.clear();
160   }
161
162
163   /* Clean up. */
164   // reply->deleteLater();
165 }
166
167 QUrl OBSAccess::redirectUrl(const QUrl& possibleRedirectUrl,
168                                const QUrl& oldRedirectUrl) const
169 {
170   QUrl redirectUrl;
171   /*
172    * Check if the URL is empty and
173    * that we aren't being fooled into a infinite redirect loop.
174    * We could also keep track of how many redirects we have been to
175    * and set a limit to it, but we'll leave that to you.
176    */
177   if(!possibleRedirectUrl.isEmpty() &&
178      possibleRedirectUrl != oldRedirectUrl) {
179     redirectUrl = possibleRedirectUrl;
180   }
181   return redirectUrl;
182 }
183
184 void OBSAccess::slotNetworkError( QNetworkReply::NetworkError error )
185 {
186   qDebug() << "Error: " << error << endl;
187 }