File indexing completed on 2024-04-21 15:32:08
0001 /** =========================================================== 0002 * @file 0003 * 0004 * This file is a part of KDE project 0005 * <a href="https://commits.kde.org/libmediawiki">libmediawiki</a> 0006 * 0007 * @date 2011-03-22 0008 * @brief a MediaWiki C++ interface for KDE 0009 * 0010 * @author Copyright (C) 2011-2012 by Gilles Caulier 0011 * <a href="mailto:caulier dot gilles at gmail dot com">caulier dot gilles at gmail dot com</a> 0012 * @author Copyright (C) 2010 by Alexandre Mendes 0013 * <a href="mailto:alex dot mendes1988 at gmail dot com">alex dot mendes1988 at gmail dot com</a> 0014 * 0015 * This program is free software; you can redistribute it 0016 * and/or modify it under the terms of the GNU General 0017 * Public License as published by the Free Software Foundation; 0018 * either version 2, or (at your option) 0019 * any later version. 0020 * 0021 * This program is distributed in the hope that it will be useful, 0022 * but WITHOUT ANY WARRANTY; without even the implied warranty of 0023 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 0024 * GNU General Public License for more details. 0025 * 0026 * ============================================================ */ 0027 0028 #include "queryinfo.h" 0029 0030 0031 // Qt includes 0032 0033 #include <QDateTime> 0034 #include <QTimer> 0035 #include <QUrl> 0036 #include <QUrlQuery> 0037 #include <QXmlStreamReader> 0038 #include <QRegExp> 0039 0040 #include <QNetworkAccessManager> 0041 #include <QNetworkCookie> 0042 #include <QNetworkReply> 0043 #include <QNetworkRequest> 0044 0045 // Local includes 0046 0047 #include "mediawiki.h" 0048 #include "job_p.h" 0049 0050 namespace mediawiki 0051 { 0052 0053 class QueryInfoPrivate : public JobPrivate 0054 { 0055 0056 public: 0057 0058 QueryInfoPrivate(MediaWiki& mediawiki) 0059 : JobPrivate(mediawiki) 0060 {} 0061 0062 QVector<Protection> protections; 0063 QMap<QString, QString> requestParameter; 0064 Page page; 0065 }; 0066 0067 QueryInfo::QueryInfo(MediaWiki& mediawiki, QObject* const parent) 0068 : Job(*new QueryInfoPrivate(mediawiki), parent) 0069 { 0070 } 0071 0072 QueryInfo::~QueryInfo() 0073 { 0074 } 0075 0076 void QueryInfo::setPageName(const QString& title) 0077 { 0078 Q_D(QueryInfo); 0079 d->requestParameter[QStringLiteral("titles")] = title; 0080 } 0081 0082 void QueryInfo::setToken(const QString& token) 0083 { 0084 Q_D(QueryInfo); 0085 d->requestParameter[QStringLiteral("intoken")] = token; 0086 } 0087 0088 void QueryInfo::setPageId(unsigned int id) 0089 { 0090 Q_D(QueryInfo); 0091 d->requestParameter[QStringLiteral("pageids")] = QString::number(id); 0092 } 0093 0094 void QueryInfo::setRevisionId(unsigned int id) 0095 { 0096 Q_D(QueryInfo); 0097 d->requestParameter[QStringLiteral("revids")] = QString::number(id); 0098 } 0099 0100 void QueryInfo::start() 0101 { 0102 QTimer::singleShot(0, this, SLOT(doWorkSendRequest())); 0103 } 0104 0105 void QueryInfo::doWorkSendRequest() 0106 { 0107 Q_D(QueryInfo); 0108 0109 // Set the url 0110 QUrl url = d->mediawiki.url(); 0111 QUrlQuery query; 0112 query.addQueryItem(QStringLiteral("format"), QStringLiteral("xml")); 0113 query.addQueryItem(QStringLiteral("action"), QStringLiteral("query")); 0114 query.addQueryItem(QStringLiteral("prop"), QStringLiteral("info")); 0115 query.addQueryItem(QStringLiteral("inprop"), QStringLiteral("protection|talkid|watched|subjectid|url|readable|preload")); 0116 0117 QMapIterator<QString, QString> i(d->requestParameter); 0118 while (i.hasNext()) 0119 { 0120 i.next(); 0121 query.addQueryItem(i.key(), i.value()); 0122 } 0123 url.setQuery(query); 0124 0125 // Set the request 0126 QNetworkRequest request(url); 0127 request.setRawHeader("User-Agent", d->mediawiki.userAgent().toUtf8()); 0128 QByteArray cookie = ""; 0129 QList<QNetworkCookie> mediawikiCookies = d->manager->cookieJar()->cookiesForUrl(d->mediawiki.url()); 0130 0131 for(int i = 0 ; i < mediawikiCookies.size(); ++i) 0132 { 0133 cookie += mediawikiCookies.at(i).toRawForm(QNetworkCookie::NameAndValueOnly); 0134 cookie += ';'; 0135 } 0136 request.setRawHeader( "Cookie", cookie ); 0137 0138 // Send the request 0139 d->reply = d->manager->get(request); 0140 connectReply(); 0141 0142 connect(d->reply, SIGNAL(finished()), 0143 this, SLOT(doWorkProcessReply())); 0144 } 0145 0146 void QueryInfo::doWorkProcessReply() 0147 { 0148 Q_D(QueryInfo); 0149 0150 disconnect(d->reply, SIGNAL(finished()), 0151 this, SLOT(doWorkProcessReply())); 0152 0153 if (d->reply->error() == QNetworkReply::NoError) 0154 { 0155 // Replace & in & 0156 QString content = QString::fromUtf8(d->reply->readAll()); 0157 QRegExp regex(QStringLiteral("&(?!\\w+;)")); 0158 content.replace(regex, QStringLiteral("&")); 0159 QXmlStreamReader reader(content); 0160 QVector<Protection> protect; 0161 0162 while (!reader.atEnd() && !reader.hasError()) 0163 { 0164 QXmlStreamReader::TokenType token = reader.readNext(); 0165 QXmlStreamAttributes attrs = reader.attributes(); 0166 0167 if (token == QXmlStreamReader::StartElement) 0168 { 0169 if (reader.name() == QLatin1String("page")) 0170 { 0171 d->page.setPageId(attrs.value(QStringLiteral("pageid")).toString().toUInt()); 0172 d->page.setTitle(attrs.value(QStringLiteral("title")).toString()); 0173 d->page.setNs(attrs.value(QStringLiteral("ns")).toString().toUInt()); 0174 d->page.setTouched(QDateTime::fromString(attrs.value(QStringLiteral("touched")).toString(), QStringLiteral("yyyy'-'MM'-'dd'T'hh':'mm':'ss'Z'"))); 0175 d->page.setLastRevId(attrs.value(QStringLiteral("lastrevid")).toString().toUInt()); 0176 d->page.setCounter(attrs.value(QStringLiteral("counter")).toString().toUInt()); 0177 d->page.setLength(attrs.value(QStringLiteral("length")).toString().toUInt()); 0178 d->page.setStarttimestamp(QDateTime::fromString(attrs.value(QStringLiteral("starttimestamp")).toString(), QStringLiteral("yyyy'-'MM'-'dd'T'hh':'mm':'ss'Z'"))); 0179 d->page.setEditToken(attrs.value(QStringLiteral("edittoken")).toString()); 0180 d->page.setTalkid(attrs.value(QStringLiteral("talkid")).toString().toUInt()); 0181 d->page.setFullurl(QUrl(attrs.value(QStringLiteral("fullurl")).toString())); 0182 d->page.setEditurl(QUrl(attrs.value(QStringLiteral("editurl")).toString())); 0183 d->page.setReadable(attrs.value(QStringLiteral("readable")).toString()); 0184 d->page.setPreload(attrs.value(QStringLiteral("preload")).toString()); 0185 } 0186 else if (reader.name() == QLatin1String("protection")) 0187 { 0188 protect.clear(); 0189 } 0190 else if (reader.name() == QLatin1String("pr")) 0191 { 0192 QString expiry(attrs.value(QStringLiteral("expiry")).toString()); 0193 QString level(attrs.value(QStringLiteral("level")).toString()); 0194 QString type(attrs.value(QStringLiteral("type")).toString()); 0195 QString source; 0196 0197 if(!attrs.value(QStringLiteral("source")).toString().isEmpty()) 0198 { 0199 source = attrs.value(QStringLiteral("source")).toString(); 0200 } 0201 else if(!attrs.value(QStringLiteral("cascade")).toString().isEmpty()) 0202 { 0203 source = attrs.value(QStringLiteral("cascade")).toString(); 0204 } 0205 0206 Protection p; 0207 p.setExpiry(expiry); 0208 p.setLevel(level); 0209 p.setType(type); 0210 p.setSource(source); 0211 protect.push_back(p); 0212 } 0213 } 0214 else if (token == QXmlStreamReader::EndElement) 0215 { 0216 if (reader.name() == QLatin1String("page")) 0217 { 0218 d->protections = protect; 0219 } 0220 } 0221 } 0222 if (!reader.hasError()) 0223 { 0224 setError(KJob::NoError); 0225 emit protection(protect); 0226 emit page(d->page); 0227 } 0228 else 0229 { 0230 setError(Job::XmlError); 0231 } 0232 } 0233 else 0234 { 0235 setError(Job::NetworkError); 0236 } 0237 0238 emitResult(); 0239 } 0240 0241 } // namespace mediawiki