~ubuntu-branches/debian/jessie/attica-kf5/jessie

« back to all changes in this revision

Viewing changes to src/providermanager.cpp

  • Committer: Package Import Robot
  • Author(s): Maximiliano Curia
  • Date: 2014-07-15 10:53:09 UTC
  • Revision ID: package-import@ubuntu.com-20140715105309-nnjxenwcs6h4qznf
Tags: upstream-5.0.0
Import upstream version 5.0.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
    This file is part of KDE.
 
3
 
 
4
    Copyright (c) 2009 Eckhart Wörner <ewoerner@kde.org>
 
5
    Copyright (c) 2009 Frederik Gladhorn <gladhorn@kde.org>
 
6
 
 
7
    This library is free software; you can redistribute it and/or
 
8
    modify it under the terms of the GNU Lesser General Public
 
9
    License as published by the Free Software Foundation; either
 
10
    version 2.1 of the License, or (at your option) version 3, or any
 
11
    later version accepted by the membership of KDE e.V. (or its
 
12
    successor approved by the membership of KDE e.V.), which shall
 
13
    act as a proxy defined in Section 6 of version 3 of the license.
 
14
 
 
15
    This library is distributed in the hope that it will be useful,
 
16
    but WITHOUT ANY WARRANTY; without even the implied warranty of
 
17
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 
18
    Lesser General Public License for more details.
 
19
 
 
20
    You should have received a copy of the GNU Lesser General Public
 
21
    License along with this library.  If not, see <http://www.gnu.org/licenses/>.
 
22
 
 
23
*/
 
24
 
 
25
#include "providermanager.h"
 
26
 
 
27
#include <QtCore/QDebug>
 
28
#include <QtCore/QFile>
 
29
#include <QtCore/QPluginLoader>
 
30
#include <QtCore/QSet>
 
31
#include <QtCore/QSignalMapper>
 
32
#include <QtCore/QTimer>
 
33
#include <QtCore/QProcess>
 
34
#include <QtNetwork/QAuthenticator>
 
35
#include <QtNetwork/QNetworkReply>
 
36
#if QT_VERSION >= 0x050000
 
37
#include <QtCore/QXmlStreamReader>
 
38
#else
 
39
#include <QtXml/QXmlStreamReader>
 
40
#endif // QT_VERSION
 
41
 
 
42
#include "platformdependent.h"
 
43
#include "qtplatformdependent_p.h"
 
44
#include <QLibraryInfo>
 
45
 
 
46
using namespace Attica;
 
47
 
 
48
#if QT_VERSION < 0x040700
 
49
uint qHash(const QUrl &key)
 
50
{
 
51
    return qHash(key.toString());
 
52
}
 
53
#endif
 
54
 
 
55
class ProviderManager::Private
 
56
{
 
57
public:
 
58
    PlatformDependent *m_internals;
 
59
    QHash<QUrl, Provider> m_providers;
 
60
    QHash<QUrl, QList<QString> > m_providerFiles;
 
61
    QSignalMapper m_downloadMapping;
 
62
    QHash<QString, QNetworkReply *> m_downloads;
 
63
    QPluginLoader m_pluginLoader;
 
64
    bool m_authenticationSuppressed;
 
65
 
 
66
    Private()
 
67
        : m_internals(0)
 
68
        , m_authenticationSuppressed(false)
 
69
    {
 
70
    }
 
71
    ~Private()
 
72
    {
 
73
        // do not delete m_internals: it is the root component of a plugin!
 
74
    }
 
75
};
 
76
 
 
77
PlatformDependent *ProviderManager::loadPlatformDependent(const ProviderFlags &flags)
 
78
{
 
79
    // OS specific stuff
 
80
#if defined Q_WS_WIN
 
81
#define PATH_SEPARATOR ';'
 
82
#define LIB_EXTENSION "dll"
 
83
#else
 
84
#define PATH_SEPARATOR ':'
 
85
#define LIB_EXTENSION "so"
 
86
#endif
 
87
 
 
88
    if (flags & ProviderManager::DisablePlugins) {
 
89
        //qDebug() << "Disabling provider plugins per application request";
 
90
        return new QtPlatformDependent;
 
91
    }
 
92
 
 
93
    // use qt plugin dir, if that is not found, fall back to kde plugin path (the old way)
 
94
    QStringList paths;
 
95
    paths.append(QLibraryInfo::location(QLibraryInfo::PluginsPath));
 
96
 
 
97
    // old plugin location, required for attica < 0.1.5
 
98
    QString program(QLatin1String("kde4-config"));
 
99
    QStringList arguments;
 
100
    arguments << QLatin1String("--path") << QLatin1String("lib");
 
101
 
 
102
    QProcess process;
 
103
    process.start(program, arguments);
 
104
    process.waitForFinished();
 
105
 
 
106
    /* Try to find the KDE plugin. This can be extended to include other platform specific plugins. */
 
107
    paths.append(QString(QLatin1String(process.readAllStandardOutput())).trimmed().split(QLatin1Char(PATH_SEPARATOR)));
 
108
    //qDebug() << "Plugin paths: " << paths;
 
109
 
 
110
    QString pluginName(QLatin1String("attica_kde"));
 
111
 
 
112
    foreach (const QString &path, paths) {
 
113
        QString libraryPath(path + QLatin1Char('/') + pluginName + QLatin1Char('.') + QLatin1String(LIB_EXTENSION));
 
114
        //qDebug() << "Trying to load Attica plugin: " << libraryPath;
 
115
        if (QFile::exists(libraryPath)) {
 
116
            d->m_pluginLoader.setFileName(libraryPath);
 
117
            QObject *plugin = d->m_pluginLoader.instance();
 
118
            if (plugin) {
 
119
                PlatformDependent *platformDependent = qobject_cast<PlatformDependent *>(plugin);
 
120
                if (platformDependent) {
 
121
                    //qDebug() << "Using Attica with KDE support";
 
122
                    return platformDependent;
 
123
                }
 
124
            }
 
125
        }
 
126
    }
 
127
    //qDebug() << "Using Attica without KDE support";
 
128
    return new QtPlatformDependent;
 
129
}
 
130
 
 
131
ProviderManager::ProviderManager(const ProviderFlags &flags)
 
132
    : d(new Private)
 
133
{
 
134
    d->m_internals = loadPlatformDependent(flags);
 
135
    connect(d->m_internals->nam(), SIGNAL(authenticationRequired(QNetworkReply*,QAuthenticator*)), SLOT(authenticate(QNetworkReply*,QAuthenticator*)));
 
136
    connect(&d->m_downloadMapping, SIGNAL(mapped(QString)), SLOT(fileFinished(QString)));
 
137
}
 
138
 
 
139
void ProviderManager::loadDefaultProviders()
 
140
{
 
141
    QTimer::singleShot(0, this, SLOT(slotLoadDefaultProvidersInternal()));
 
142
}
 
143
 
 
144
void ProviderManager::setAuthenticationSuppressed(bool suppressed)
 
145
{
 
146
    d->m_authenticationSuppressed = suppressed;
 
147
}
 
148
 
 
149
void ProviderManager::clear()
 
150
{
 
151
    d->m_providerFiles.clear();
 
152
    d->m_providers.clear();
 
153
}
 
154
 
 
155
void ProviderManager::slotLoadDefaultProvidersInternal()
 
156
{
 
157
    foreach (const QUrl &url, d->m_internals->getDefaultProviderFiles()) {
 
158
        addProviderFile(url);
 
159
    }
 
160
    if (d->m_downloads.isEmpty()) {
 
161
        emit defaultProvidersLoaded();
 
162
    }
 
163
}
 
164
 
 
165
QList<QUrl> ProviderManager::defaultProviderFiles()
 
166
{
 
167
    return d->m_internals->getDefaultProviderFiles();
 
168
}
 
169
 
 
170
ProviderManager::~ProviderManager()
 
171
{
 
172
    delete d;
 
173
}
 
174
 
 
175
void ProviderManager::addProviderFileToDefaultProviders(const QUrl &url)
 
176
{
 
177
    d->m_internals->addDefaultProviderFile(url);
 
178
    addProviderFile(url);
 
179
}
 
180
 
 
181
void ProviderManager::removeProviderFileFromDefaultProviders(const QUrl &url)
 
182
{
 
183
    d->m_internals->removeDefaultProviderFile(url);
 
184
}
 
185
 
 
186
void ProviderManager::addProviderFile(const QUrl &url)
 
187
{
 
188
    QString localFile = url.toLocalFile();
 
189
    if (!localFile.isEmpty()) {
 
190
        QFile file(localFile);
 
191
        if (!file.open(QIODevice::ReadOnly)) {
 
192
            qWarning() << "ProviderManager::addProviderFile: could not open provider file: " << url.toString();
 
193
            return;
 
194
        }
 
195
        addProviderFromXml(QLatin1String(file.readAll()));
 
196
    } else {
 
197
        if (!d->m_downloads.contains(url.toString())) {
 
198
            QNetworkReply *reply = d->m_internals->get(QNetworkRequest(url));
 
199
            connect(reply, SIGNAL(finished()), &d->m_downloadMapping, SLOT(map()));
 
200
            d->m_downloadMapping.setMapping(reply, url.toString());
 
201
            d->m_downloads.insert(url.toString(), reply);
 
202
        }
 
203
    }
 
204
}
 
205
 
 
206
void ProviderManager::fileFinished(const QString &url)
 
207
{
 
208
    QNetworkReply *reply = d->m_downloads.take(url);
 
209
    parseProviderFile(QLatin1String(reply->readAll()), url);
 
210
    reply->deleteLater();
 
211
}
 
212
 
 
213
void ProviderManager::addProviderFromXml(const QString &providerXml)
 
214
{
 
215
    parseProviderFile(providerXml, QString());
 
216
}
 
217
 
 
218
void ProviderManager::parseProviderFile(const QString &xmlString, const QString &url)
 
219
{
 
220
    QXmlStreamReader xml(xmlString);
 
221
    while (!xml.atEnd() && xml.readNext()) {
 
222
        if (xml.isStartElement() && xml.name() == QLatin1String("provider")) {
 
223
            QUrl baseUrl;
 
224
            QString name;
 
225
            QUrl icon;
 
226
            QString person;
 
227
            QString friendV;
 
228
            QString message;
 
229
            QString achievement;
 
230
            QString activity;
 
231
            QString content;
 
232
            QString fan;
 
233
            QString forum;
 
234
            QString knowledgebase;
 
235
            QString event;
 
236
            QString comment;
 
237
            QString registerUrl;
 
238
 
 
239
            while (!xml.atEnd() && xml.readNext()) {
 
240
                if (xml.isStartElement()) {
 
241
                    if (xml.name() == QLatin1String("location")) {
 
242
                        baseUrl = QUrl(xml.readElementText());
 
243
                    } else if (xml.name() == QLatin1String("name")) {
 
244
                        name = xml.readElementText();
 
245
                    } else if (xml.name() == QLatin1String("icon")) {
 
246
                        icon = QUrl(xml.readElementText());
 
247
                    } else if (xml.name() == QLatin1String("person")) {
 
248
                        person = xml.attributes().value(QLatin1String("ocsversion")).toString();
 
249
                    } else if (xml.name() == QLatin1String("friend")) {
 
250
                        friendV = xml.attributes().value(QLatin1String("ocsversion")).toString();
 
251
                    } else if (xml.name() == QLatin1String("message")) {
 
252
                        message = xml.attributes().value(QLatin1String("ocsversion")).toString();
 
253
                    } else if (xml.name() == QLatin1String("achievement")) {
 
254
                        achievement = xml.attributes().value(QLatin1String("ocsversion")).toString();
 
255
                    } else if (xml.name() == QLatin1String("activity")) {
 
256
                        activity = xml.attributes().value(QLatin1String("ocsversion")).toString();
 
257
                    } else if (xml.name() == QLatin1String("content")) {
 
258
                        content = xml.attributes().value(QLatin1String("ocsversion")).toString();
 
259
                    } else if (xml.name() == QLatin1String("fan")) {
 
260
                        fan = xml.attributes().value(QLatin1String("ocsversion")).toString();
 
261
                    } else if (xml.name() == QLatin1String("forum")) {
 
262
                        forum = xml.attributes().value(QLatin1String("ocsversion")).toString();
 
263
                    } else if (xml.name() == QLatin1String("knowledgebase")) {
 
264
                        knowledgebase = xml.attributes().value(QLatin1String("ocsversion")).toString();
 
265
                    } else if (xml.name() == QLatin1String("event")) {
 
266
                        event = xml.attributes().value(QLatin1String("ocsversion")).toString();
 
267
                    } else if (xml.name() == QLatin1String("comment")) {
 
268
                        comment = xml.attributes().value(QLatin1String("ocsversion")).toString();
 
269
                    } else if (xml.name() == QLatin1String("register")) {
 
270
                        registerUrl = xml.readElementText();
 
271
                    }
 
272
                } else if (xml.isEndElement() && xml.name() == QLatin1String("provider")) {
 
273
                    break;
 
274
                }
 
275
            }
 
276
            if (!baseUrl.isEmpty()) {
 
277
                //qDebug() << "Adding provider" << baseUrl;
 
278
                d->m_providers.insert(baseUrl, Provider(d->m_internals, baseUrl, name, icon,
 
279
                                                        person, friendV, message, achievement, activity, content, fan, forum, knowledgebase,
 
280
                                                        event, comment, registerUrl));
 
281
                emit providerAdded(d->m_providers.value(baseUrl));
 
282
            }
 
283
        }
 
284
    }
 
285
 
 
286
    if (d->m_downloads.isEmpty()) {
 
287
        emit defaultProvidersLoaded();
 
288
    }
 
289
}
 
290
 
 
291
Provider ProviderManager::providerByUrl(const QUrl &url) const
 
292
{
 
293
    return d->m_providers.value(url);
 
294
}
 
295
 
 
296
QList<Provider> ProviderManager::providers() const
 
297
{
 
298
    return d->m_providers.values();
 
299
}
 
300
 
 
301
bool ProviderManager::contains(const QString &provider) const
 
302
{
 
303
    return d->m_providers.contains(QUrl(provider));
 
304
}
 
305
 
 
306
QList<QUrl> ProviderManager::providerFiles() const
 
307
{
 
308
    return d->m_providerFiles.keys();
 
309
}
 
310
 
 
311
void ProviderManager::authenticate(QNetworkReply *reply, QAuthenticator *auth)
 
312
{
 
313
    QUrl baseUrl;
 
314
    QList<QUrl> urls = d->m_providers.keys();
 
315
    foreach (const QUrl &url, urls) {
 
316
        if (url.isParentOf(reply->url())) {
 
317
            baseUrl = url;
 
318
            break;
 
319
        }
 
320
    }
 
321
 
 
322
    //qDebug() << "ProviderManager::authenticate" << baseUrl;
 
323
 
 
324
    QString user;
 
325
    QString password;
 
326
    if (auth->user().isEmpty() && auth->password().isEmpty()) {
 
327
        if (d->m_internals->hasCredentials(baseUrl)) {
 
328
            if (d->m_internals->loadCredentials(baseUrl, user, password)) {
 
329
                //qDebug() << "ProviderManager::authenticate: loading authentication";
 
330
                auth->setUser(user);
 
331
                auth->setPassword(password);
 
332
                return;
 
333
            }
 
334
        }
 
335
    }
 
336
 
 
337
    if (!d->m_authenticationSuppressed && d->m_internals->askForCredentials(baseUrl, user, password)) {
 
338
        //qDebug() << "ProviderManager::authenticate: asking internals for new credentials";
 
339
        //auth->setUser(user);
 
340
        //auth->setPassword(password);
 
341
        return;
 
342
    }
 
343
 
 
344
    qWarning() << "ProviderManager::authenticate: No authentication credentials provided, aborting." << reply->url().toString();
 
345
    emit authenticationCredentialsMissing(d->m_providers.value(baseUrl));
 
346
    reply->abort();
 
347
}
 
348
 
 
349
void ProviderManager::proxyAuthenticationRequired(const QNetworkProxy &proxy, QAuthenticator *authenticator)
 
350
{
 
351
}
 
352
 
 
353
void ProviderManager::initNetworkAccesssManager()
 
354
{
 
355
    connect(d->m_internals->nam(), SIGNAL(authenticationRequired(QNetworkReply*,QAuthenticator*)), this, SLOT(authenticate(QNetworkReply*,QAuthenticator*)));
 
356
    connect(d->m_internals->nam(), SIGNAL(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*)), this, SLOT(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*)));
 
357
}
 
358
 
 
359
#include "providermanager.moc"