File indexing completed on 2024-04-28 04:42:50

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