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 Ludovic Delfau <ludovicdelfau at gmail dot com> 0011 * 0012 * SPDX-License-Identifier: GPL-2.0-or-later 0013 * 0014 * ============================================================ */ 0015 0016 #include "mediawiki_queryimageinfo.h" 0017 0018 // Qt includes 0019 0020 #include <QString> 0021 #include <QTimer> 0022 #include <QUrl> 0023 #include <QUrlQuery> 0024 #include <QXmlStreamReader> 0025 #include <QNetworkReply> 0026 #include <QNetworkRequest> 0027 0028 // KDE includes 0029 0030 #include <klocalizedstring.h> 0031 0032 // Local includes 0033 0034 #include "mediawiki_job_p.h" 0035 #include "mediawiki_iface.h" 0036 0037 namespace MediaWiki 0038 { 0039 0040 class Q_DECL_HIDDEN QueryImageinfoPrivate : public JobPrivate 0041 { 0042 public: 0043 0044 explicit QueryImageinfoPrivate(Iface& MediaWiki) 0045 : JobPrivate(MediaWiki) 0046 { 0047 onlyOneSignal = false; 0048 } 0049 0050 static inline qint64 toQInt64(const QString& qstring) 0051 { 0052 bool ok; 0053 qint64 result = qstring.toLongLong(&ok); 0054 return (ok ? result : -1); 0055 } 0056 0057 static inline void addQueryItemIfNotNull(QUrlQuery& query, const QString& key, const QString& value) 0058 { 0059 if (!value.isNull()) 0060 { 0061 query.addQueryItem(key, value); 0062 } 0063 } 0064 0065 public: 0066 0067 bool onlyOneSignal; 0068 0069 QString title; 0070 QString iiprop; 0071 QString limit; 0072 QString begin; 0073 QString end; 0074 QString width; 0075 QString height; 0076 }; 0077 0078 QueryImageinfo::QueryImageinfo(Iface& MediaWiki, QObject* const parent) 0079 : Job(*new QueryImageinfoPrivate(MediaWiki), parent) 0080 { 0081 Q_D(QueryImageinfo); 0082 Q_UNUSED(d); 0083 } 0084 0085 QueryImageinfo::~QueryImageinfo() 0086 { 0087 } 0088 0089 void QueryImageinfo::setTitle(const QString& title) 0090 { 0091 Q_D(QueryImageinfo); 0092 d->title = title; 0093 } 0094 0095 void QueryImageinfo::setProperties(Properties properties) 0096 { 0097 Q_D(QueryImageinfo); 0098 0099 QString iiprop; 0100 0101 if (properties & QueryImageinfo::Timestamp) 0102 { 0103 iiprop.append(QStringLiteral("timestamp|")); 0104 } 0105 if (properties & QueryImageinfo::User) 0106 { 0107 iiprop.append(QStringLiteral("user|")); 0108 } 0109 if (properties & QueryImageinfo::Comment) 0110 { 0111 iiprop.append(QStringLiteral("comment|")); 0112 } 0113 if (properties & QueryImageinfo::Url) 0114 { 0115 iiprop.append(QStringLiteral("url|")); 0116 } 0117 if (properties & QueryImageinfo::Size) 0118 { 0119 iiprop.append(QStringLiteral("size|")); 0120 } 0121 if (properties & QueryImageinfo::Sha1) 0122 { 0123 iiprop.append(QStringLiteral("sha1|")); 0124 } 0125 if (properties & QueryImageinfo::Mime) 0126 { 0127 iiprop.append(QStringLiteral("mime|")); 0128 } 0129 if (properties & QueryImageinfo::Metadata) 0130 { 0131 iiprop.append(QStringLiteral("metadata|")); 0132 } 0133 0134 iiprop.chop(1); 0135 d->iiprop = iiprop; 0136 } 0137 0138 void QueryImageinfo::setLimit(unsigned int limit) 0139 { 0140 Q_D(QueryImageinfo); 0141 d->limit = (limit > 0u) ? QString::number(limit) : QString(); 0142 } 0143 0144 void QueryImageinfo::setOnlyOneSignal(bool onlyOneSignal) 0145 { 0146 Q_D(QueryImageinfo); 0147 d->onlyOneSignal = onlyOneSignal; 0148 } 0149 0150 void QueryImageinfo::setBeginTimestamp(const QDateTime& begin) 0151 { 0152 Q_D(QueryImageinfo); 0153 d->begin = begin.toString(QStringLiteral("yyyy-MM-dd'T'hh:mm:ss'Z'")); 0154 } 0155 0156 void QueryImageinfo::setEndTimestamp(const QDateTime& end) 0157 { 0158 Q_D(QueryImageinfo); 0159 d->end = end.toString(QStringLiteral("yyyy-MM-dd'T'hh:mm:ss'Z'")); 0160 } 0161 0162 void QueryImageinfo::setWidthScale(unsigned int width) 0163 { 0164 Q_D(QueryImageinfo); 0165 d->width = (width > 0u) ? QString::number(width) : QString(); 0166 } 0167 0168 void QueryImageinfo::setHeightScale(unsigned int height) 0169 { 0170 Q_D(QueryImageinfo); 0171 d->height = (height > 0u) ? QString::number(height) : QString(); 0172 0173 if (d->width.isNull()) 0174 { 0175 d->width = d->height; 0176 } 0177 } 0178 0179 void QueryImageinfo::start() 0180 { 0181 QTimer::singleShot(0, this, SLOT(doWorkSendRequest())); 0182 } 0183 0184 void QueryImageinfo::doWorkSendRequest() 0185 { 0186 Q_D(QueryImageinfo); 0187 0188 // Requirements. 0189 if (d->title.isEmpty()) 0190 { 0191 setError(QueryImageinfo::MissingMandatoryParameter); 0192 setErrorText(i18n("You cannot query the information of an " 0193 "image if you do not provide the title of that image.")); 0194 emitResult(); 0195 return; 0196 } 0197 0198 // Set the url 0199 QUrl url = d->MediaWiki.url(); 0200 QUrlQuery query; 0201 query.addQueryItem(QStringLiteral("format"), QStringLiteral("xml")); 0202 query.addQueryItem(QStringLiteral("action"), QStringLiteral("query")); 0203 query.addQueryItem(QStringLiteral("titles"), d->title); 0204 query.addQueryItem(QStringLiteral("prop"), QStringLiteral("imageinfo")); 0205 QueryImageinfoPrivate::addQueryItemIfNotNull(query, QStringLiteral("iiprop"), d->iiprop); 0206 QueryImageinfoPrivate::addQueryItemIfNotNull(query, QStringLiteral("iilimit"), d->limit); 0207 QueryImageinfoPrivate::addQueryItemIfNotNull(query, QStringLiteral("iistart"), d->begin); 0208 QueryImageinfoPrivate::addQueryItemIfNotNull(query, QStringLiteral("iiend"), d->end); 0209 QueryImageinfoPrivate::addQueryItemIfNotNull(query, QStringLiteral("iiurlwidth"), d->width); 0210 QueryImageinfoPrivate::addQueryItemIfNotNull(query, QStringLiteral("iiurlheight"), d->height); 0211 url.setQuery(query); 0212 0213 // Set the request 0214 QNetworkRequest request(url); 0215 request.setRawHeader("User-Agent", d->MediaWiki.userAgent().toUtf8()); 0216 0217 // Send the request 0218 d->reply = d->manager->get(request); 0219 connectReply(); 0220 0221 connect(d->reply, SIGNAL(finished()), 0222 this, SLOT(doWorkProcessReply())); 0223 } 0224 0225 void QueryImageinfo::doWorkProcessReply() 0226 { 0227 Q_D(QueryImageinfo); 0228 0229 disconnect(d->reply, SIGNAL(finished()), 0230 this, SLOT(doWorkProcessReply())); 0231 0232 d->begin.clear(); 0233 0234 if (d->reply->error() == QNetworkReply::NoError) 0235 { 0236 QXmlStreamReader reader(d->reply); 0237 QList<Imageinfo> imageinfos; 0238 Imageinfo imageinfo; 0239 0240 while (!reader.atEnd() && !reader.hasError()) 0241 { 0242 QXmlStreamReader::TokenType token = reader.readNext(); 0243 0244 if (token == QXmlStreamReader::StartElement) 0245 { 0246 if (reader.name() == QLatin1String("imageinfo")) 0247 { 0248 if (!reader.attributes().value(QStringLiteral("iistart")).isNull()) 0249 { 0250 d->begin = reader.attributes().value(QStringLiteral("iistart")).toString(); 0251 } 0252 } 0253 else if (reader.name() == QLatin1String("ii")) 0254 { 0255 imageinfo.setTimestamp(QDateTime::fromString(reader.attributes().value(QStringLiteral("timestamp")).toString(), QStringLiteral("yyyy-MM-dd'T'hh:mm:ss'Z'"))); 0256 imageinfo.setUser(reader.attributes().value(QStringLiteral("user")).toString()); 0257 imageinfo.setComment(reader.attributes().value(QStringLiteral("comment")).toString()); 0258 imageinfo.setUrl(QUrl::fromEncoded(reader.attributes().value(QStringLiteral("url")).toString().toLocal8Bit())); 0259 imageinfo.setDescriptionUrl(QUrl::fromEncoded(reader.attributes().value(QStringLiteral("descriptionurl")).toString().toLocal8Bit())); 0260 imageinfo.setThumbUrl(QUrl::fromEncoded(reader.attributes().value(QStringLiteral("thumburl")).toString().toLocal8Bit())); 0261 imageinfo.setThumbWidth(QueryImageinfoPrivate::toQInt64(reader.attributes().value(QStringLiteral("thumbwidth")).toString())); 0262 imageinfo.setThumbHeight(QueryImageinfoPrivate::toQInt64(reader.attributes().value(QStringLiteral("thumbheight")).toString())); 0263 imageinfo.setSize(QueryImageinfoPrivate::toQInt64(reader.attributes().value(QStringLiteral("size")).toString())); 0264 imageinfo.setWidth(QueryImageinfoPrivate::toQInt64(reader.attributes().value(QStringLiteral("width")).toString())); 0265 imageinfo.setHeight(QueryImageinfoPrivate::toQInt64(reader.attributes().value(QStringLiteral("height")).toString())); 0266 imageinfo.setSha1(reader.attributes().value(QStringLiteral("sha1")).toString()); 0267 imageinfo.setMime(reader.attributes().value(QStringLiteral("mime")).toString()); 0268 } 0269 else if (reader.name() == QLatin1String("metadata")) 0270 { 0271 if (!reader.attributes().isEmpty()) 0272 { 0273 imageinfo.metadata()[reader.attributes().value(QStringLiteral("name")).toString()] = reader.attributes().value(QStringLiteral("value")).toString(); 0274 } 0275 } 0276 } 0277 else if (token == QXmlStreamReader::EndElement) 0278 { 0279 if (reader.name() == QLatin1String("ii")) 0280 { 0281 imageinfos.push_back(imageinfo); 0282 imageinfo = Imageinfo(); 0283 } 0284 } 0285 } 0286 0287 if (!reader.hasError()) 0288 { 0289 Q_EMIT result(imageinfos); 0290 0291 if (d->begin.isNull() || d->onlyOneSignal) 0292 { 0293 setError(KJob::NoError); 0294 } 0295 else 0296 { 0297 QTimer::singleShot(0, this, SLOT(doWorkSendRequest())); 0298 return; 0299 } 0300 } 0301 else 0302 { 0303 setError(QueryImageinfo::XmlError); 0304 } 0305 } 0306 else 0307 { 0308 setError(QueryImageinfo::NetworkError); 0309 } 0310 0311 emitResult(); 0312 } 0313 0314 } // namespace MediaWiki 0315 0316 #include "moc_mediawiki_queryimageinfo.cpp"