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"