File indexing completed on 2025-01-05 03:53:37

0001 /* ============================================================
0002  *
0003  * This file is a part of digiKam project
0004  * https://www.digikam.org
0005  *
0006  * Date        : 2011-02-11
0007  * Description : a tool to export images to MediaWiki web service
0008  *
0009  * SPDX-FileCopyrightText: 2011      by Alexandre Mendes <alex dot mendes1988 at gmail dot com>
0010  * SPDX-FileCopyrightText: 2011-2024 by Gilles Caulier <caulier dot gilles at gmail dot com>
0011  * SPDX-FileCopyrightText: 2012      by Nathan Damie <nathan dot damie at gmail dot com>
0012  * SPDX-FileCopyrightText: 2012      by Iliya Ivanov <ilko2002 at abv dot bg>
0013  * SPDX-FileCopyrightText: 2012      by Peter Potrowl <peter dot potrowl at gmail dot com>
0014  *
0015  * SPDX-License-Identifier: GPL-2.0-or-later
0016  *
0017  * ============================================================ */
0018 
0019 #include "mediawikitalker.h"
0020 
0021 // Qt includes
0022 
0023 #include <QApplication>
0024 #include <QMessageBox>
0025 #include <QFile>
0026 #include <QTimer>
0027 #include <QStringList>
0028 
0029 // KDE includes
0030 
0031 #include <klocalizedstring.h>
0032 
0033 // MediaWiki includes
0034 
0035 #include "mediawiki_upload.h"
0036 #include "mediawiki_iface.h"
0037 
0038 // Local includes
0039 
0040 #include "digikam_debug.h"
0041 #include "digikam_globals.h"
0042 
0043 namespace DigikamGenericMediaWikiPlugin
0044 {
0045 
0046 class Q_DECL_HIDDEN MediaWikiTalker::Private
0047 {
0048 public:
0049 
0050     explicit Private()
0051     {
0052         interface = nullptr;
0053         MediaWiki = nullptr;
0054     }
0055 
0056     QList<QUrl>                              urls;
0057     DInfoInterface*                          interface;
0058     Iface*                                   MediaWiki;
0059     QString                                  error;
0060     QString                                  currentFile;
0061     QMap <QString, QMap <QString, QString> > imageDesc;
0062 };
0063 
0064 MediaWikiTalker::MediaWikiTalker(DInfoInterface* const iface,
0065                                  Iface* const MediaWiki,
0066                                  QObject* const parent)
0067     : KJob(parent),
0068       d   (new Private)
0069 {
0070     d->interface = iface;
0071     d->MediaWiki = MediaWiki;
0072 }
0073 
0074 MediaWikiTalker::~MediaWikiTalker()
0075 {
0076     delete d;
0077 }
0078 
0079 void MediaWikiTalker::start()
0080 {
0081     QTimer::singleShot(0, this, SLOT(slotUploadHandle()));
0082 }
0083 
0084 void MediaWikiTalker::slotBegin()
0085 {
0086     start();
0087 }
0088 
0089 void MediaWikiTalker::setImageMap(const QMap <QString,QMap <QString,QString> >& imageDesc)
0090 {
0091     d->imageDesc = imageDesc;
0092     qCDebug(DIGIKAM_WEBSERVICES_LOG) << "Map length:" << imageDesc.size();
0093 }
0094 
0095 void MediaWikiTalker::slotUploadHandle(KJob* j)
0096 {
0097     if (j != nullptr)
0098     {
0099         qCDebug(DIGIKAM_WEBSERVICES_LOG) << "Upload error" << j->error() << j->errorString() << j->errorText();
0100         Q_EMIT signalUploadProgress(100);
0101 
0102         disconnect(j, SIGNAL(result(KJob*)),
0103                    this, SLOT(slotUploadHandle(KJob*)));
0104 
0105         disconnect(j, SIGNAL(percent(KJob*,ulong)),
0106                    this, SLOT(slotUploadProgress(KJob*,ulong)));
0107 
0108         // Error from previous upload
0109 
0110         if ((int)j->error() != 0)
0111         {
0112             const QString errorText = j->errorText();
0113 
0114             if (errorText.isEmpty())
0115             {
0116                 d->error.append(i18n("Error on file '%1'\n", d->currentFile));
0117             }
0118             else
0119             {
0120                 d->error.append(i18n("Error on file '%1': %2\n", d->currentFile, errorText));
0121             }
0122         }
0123     }
0124 
0125     // Upload next image
0126 
0127     if (!d->imageDesc.isEmpty())
0128     {
0129         QList<QString> keys         = d->imageDesc.keys();
0130         QMap<QString, QString> info = d->imageDesc.take(keys.first());
0131 
0132         qCDebug(DIGIKAM_WEBSERVICES_LOG) << "Path:" << keys.first();
0133 
0134         QFile* const file = new QFile(keys.first(),this);
0135 
0136         if (!file->open(QIODevice::ReadOnly))
0137         {
0138             qCDebug(DIGIKAM_WEBSERVICES_LOG) << "File open error:" << keys.first();
0139             delete file;
0140             return;
0141         }
0142 
0143         //Q_EMIT fileUploadProgress(done = 0, total file.size());
0144 
0145         Upload* const e1 = new Upload(*d->MediaWiki, this);
0146         e1->setFile(file);
0147         d->currentFile   = file->fileName();
0148         qCDebug(DIGIKAM_WEBSERVICES_LOG) << "Name:" << file->fileName();
0149         e1->setFilename(info[QLatin1String("title")].replace(QLatin1Char(' '), QLatin1Char('_')));
0150         qCDebug(DIGIKAM_WEBSERVICES_LOG) << "Title:" << info[QLatin1String("title")];
0151 
0152         if (!info[QLatin1String("comments")].isEmpty())
0153         {
0154             e1->setComment(info[QLatin1String("comments")]);
0155         }
0156         else
0157         {
0158             e1->setComment(i18n("Uploaded via digiKam uploader"));
0159         }
0160 
0161         e1->setText(buildWikiText(info));
0162         keys.removeFirst();
0163 
0164         connect(e1, SIGNAL(result(KJob*)),
0165                 this, SLOT(slotUploadHandle(KJob*)));
0166 
0167         connect(e1, SIGNAL(percent(KJob*,ulong)),
0168                 this, SLOT(slotUploadProgress(KJob*,ulong)));
0169 
0170         Q_EMIT signalUploadProgress(0);
0171         e1->start();
0172     }
0173     else
0174     {
0175         // Finish upload
0176 
0177         if (d->error.size() > 0)
0178         {
0179             QMessageBox::critical(QApplication::activeWindow(), i18nc("@title:window", "Error"), d->error);
0180         }
0181         else
0182         {
0183             Q_EMIT signalEndUpload();
0184         }
0185 
0186         d->error.clear();
0187     }
0188 }
0189 
0190 QString MediaWikiTalker::buildWikiText(const QMap<QString, QString>& info) const
0191 {
0192     QString text = QString::fromUtf8("=={{int:filedesc}}==");
0193     text.append(QLatin1String("\n{{Information"));
0194     text.append(QLatin1String("\n|Description=")).append(info[QLatin1String("description")]);
0195     text.append(QLatin1String("\n|Source="));
0196 
0197     if (!info[QLatin1String("source")].isEmpty())
0198     {
0199         text.append(info[QLatin1String("source")]);
0200     }
0201 
0202     text.append(QLatin1String("\n|Author="));
0203 
0204     if (!info[QLatin1String("author")].isEmpty())
0205     {
0206         text.append(info[QLatin1String("author")]);
0207     }
0208 
0209     text.append(QLatin1String("\n|Date=")).append(info[QLatin1String("date")]);
0210     text.append(QLatin1String("\n|Permission="));
0211     text.append(QLatin1String("\n|other_versions="));
0212     text.append(QLatin1String("\n}}\n"));
0213 
0214     QString latitude  = info[QLatin1String("latitude")];
0215     QString longitude = info[QLatin1String("longitude")];
0216 
0217     if (!latitude.isEmpty() && !longitude.isEmpty())
0218     {
0219         qCDebug(DIGIKAM_WEBSERVICES_LOG) << "Latitude:" << latitude << "; longitude:" << longitude;
0220         text.append(QLatin1String("{{Location|")).append(latitude).append(QLatin1String("|")).append(longitude).append(QLatin1String("}}\n"));
0221     }
0222 
0223     if (!info[QLatin1String("genText")].isEmpty())
0224     {
0225         text.append(info[QLatin1String("genText")]).append(QLatin1Char('\n'));
0226     }
0227 
0228     if (!info[QLatin1String("license")].isEmpty())
0229     {
0230         text.append(QLatin1String("\n=={{int:license-header}}==\n"));
0231         text.append(info[QLatin1String("license")]).append(QLatin1String("\n\n"));
0232     }
0233 
0234     QStringList categories;
0235 
0236     if (!info[QLatin1String("categories")].isEmpty())
0237     {
0238         categories = info[QLatin1String("categories")].split(QLatin1Char('\n'), QT_SKIP_EMPTY_PARTS);
0239 
0240         for (int i = 0 ; i < categories.size() ; ++i)
0241         {
0242             text.append(QLatin1String("[[Category:")).append(categories[i]).append(QLatin1String("]]\n"));
0243         }
0244     }
0245 
0246     if (!info[QLatin1String("genCategories")].isEmpty())
0247     {
0248         categories = info[QLatin1String("genCategories")].split(QLatin1Char('\n'), QT_SKIP_EMPTY_PARTS);
0249 
0250         for (int i = 0 ; i < categories.size() ; ++i)
0251         {
0252             text.append(QLatin1String("[[Category:")).append(categories[i]).append(QLatin1String("]]\n"));
0253         }
0254     }
0255 
0256     return text;
0257 }
0258 
0259 void MediaWikiTalker::slotUploadProgress(KJob* job, unsigned long percent)
0260 {
0261     Q_UNUSED(job)
0262     Q_EMIT signalUploadProgress((int)percent);
0263 }
0264 
0265 } // namespace DigikamGenericMediaWikiPlugin
0266 
0267 #include "moc_mediawikitalker.cpp"