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