1 /* ============================================================
2  *
3  * This file is a part of digiKam project
4  * https://www.digikam.org
5  *
6  * Date        : 2011-02-11
7  * Description : a tool to export images to MediaWiki web service
8  *
9  * Copyright (C) 2011      by Alexandre Mendes <alex dot mendes1988 at gmail dot com>
10  * Copyright (C) 2011-2021 by Gilles Caulier <caulier dot gilles at gmail dot com>
11  * Copyright (C) 2012      by Nathan Damie <nathan dot damie at gmail dot com>
12  * Copyright (C) 2012      by Iliya Ivanov <ilko2002 at abv dot bg>
13  * Copyright (C) 2012      by Peter Potrowl <peter dot potrowl at gmail dot com>
14  *
15  * This program is free software; you can redistribute it
16  * and/or modify it under the terms of the GNU General
17  * Public License as published by the Free Software Foundation;
18  * either version 2, or (at your option) any later version.
19  *
20  * This program is distributed in the hope that it will be useful,
21  * but WITHOUT ANY WARRANTY; without even the implied warranty of
22  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23  * GNU General Public License for more details.
24  *
25  * ============================================================ */
26 
27 #include "mediawikitalker.h"
28 
29 // Qt includes
30 
31 #include <QApplication>
32 #include <QMessageBox>
33 #include <QFile>
34 #include <QTimer>
35 #include <QStringList>
36 
37 // KDE includes
38 
39 #include <klocalizedstring.h>
40 
41 // MediaWiki includes
42 
43 #include "mediawiki_upload.h"
44 #include "mediawiki_iface.h"
45 
46 // Local includes
47 
48 #include "digikam_debug.h"
49 
50 namespace DigikamGenericMediaWikiPlugin
51 {
52 
53 class Q_DECL_HIDDEN MediaWikiTalker::Private
54 {
55 public:
56 
Private()57     explicit Private()
58     {
59         interface = nullptr;
60         MediaWiki = nullptr;
61     }
62 
63     QList<QUrl>                              urls;
64     DInfoInterface*                          interface;
65     Iface*                                   MediaWiki;
66     QString                                  error;
67     QString                                  currentFile;
68     QMap <QString, QMap <QString, QString> > imageDesc;
69 };
70 
MediaWikiTalker(DInfoInterface * const iface,Iface * const MediaWiki,QObject * const parent)71 MediaWikiTalker::MediaWikiTalker(DInfoInterface* const iface,
72                                  Iface* const MediaWiki,
73                                  QObject* const parent)
74     : KJob(parent),
75       d   (new Private)
76 {
77     d->interface = iface;
78     d->MediaWiki = MediaWiki;
79 }
80 
~MediaWikiTalker()81 MediaWikiTalker::~MediaWikiTalker()
82 {
83     delete d;
84 }
85 
start()86 void MediaWikiTalker::start()
87 {
88     QTimer::singleShot(0, this, SLOT(slotUploadHandle()));
89 }
90 
slotBegin()91 void MediaWikiTalker::slotBegin()
92 {
93     start();
94 }
95 
setImageMap(const QMap<QString,QMap<QString,QString>> & imageDesc)96 void MediaWikiTalker::setImageMap(const QMap <QString,QMap <QString,QString> >& imageDesc)
97 {
98     d->imageDesc = imageDesc;
99     qCDebug(DIGIKAM_WEBSERVICES_LOG) << "Map length:" << imageDesc.size();
100 }
101 
slotUploadHandle(KJob * j)102 void MediaWikiTalker::slotUploadHandle(KJob* j)
103 {
104     if (j != nullptr)
105     {
106         qCDebug(DIGIKAM_WEBSERVICES_LOG) << "Upload error" << j->error() << j->errorString() << j->errorText();
107         emit signalUploadProgress(100);
108 
109         disconnect(j, SIGNAL(result(KJob*)),
110                    this, SLOT(slotUploadHandle(KJob*)));
111 
112         disconnect(j, SIGNAL(percent(KJob*,ulong)),
113                    this, SLOT(slotUploadProgress(KJob*,ulong)));
114 
115         // Error from previous upload
116 
117         if ((int)j->error() != 0)
118         {
119             const QString errorText = j->errorText();
120 
121             if (errorText.isEmpty())
122             {
123                 d->error.append(i18n("Error on file '%1'\n", d->currentFile));
124             }
125             else
126             {
127                 d->error.append(i18n("Error on file '%1': %2\n", d->currentFile, errorText));
128             }
129         }
130     }
131 
132     // Upload next image
133 
134     if (!d->imageDesc.isEmpty())
135     {
136         QList<QString> keys         = d->imageDesc.keys();
137         QMap<QString, QString> info = d->imageDesc.take(keys.first());
138 
139         qCDebug(DIGIKAM_WEBSERVICES_LOG) << "Path:" << keys.first();
140 
141         QFile* const file = new QFile(keys.first(),this);
142 
143         if (!file->open(QIODevice::ReadOnly))
144         {
145             qCDebug(DIGIKAM_WEBSERVICES_LOG) << "File open error:" << keys.first();
146             delete file;
147             return;
148         }
149 
150         //emit fileUploadProgress(done = 0, total file.size());
151 
152         Upload* const e1 = new Upload(*d->MediaWiki, this);
153         e1->setFile(file);
154         d->currentFile   = file->fileName();
155         qCDebug(DIGIKAM_WEBSERVICES_LOG) << "Name:" << file->fileName();
156         e1->setFilename(info[QLatin1String("title")].replace(QLatin1Char(' '), QLatin1Char('_')));
157         qCDebug(DIGIKAM_WEBSERVICES_LOG) << "Title:" << info[QLatin1String("title")];
158 
159         if (!info[QLatin1String("comments")].isEmpty())
160         {
161             e1->setComment(info[QLatin1String("comments")]);
162         }
163         else
164         {
165             e1->setComment(i18n("Uploaded via digiKam uploader"));
166         }
167 
168         e1->setText(buildWikiText(info));
169         keys.removeFirst();
170 
171         connect(e1, SIGNAL(result(KJob*)),
172                 this, SLOT(slotUploadHandle(KJob*)));
173 
174         connect(e1, SIGNAL(percent(KJob*,ulong)),
175                 this, SLOT(slotUploadProgress(KJob*,ulong)));
176 
177         emit signalUploadProgress(0);
178         e1->start();
179     }
180     else
181     {
182         // Finish upload
183 
184         if (d->error.size() > 0)
185         {
186             QMessageBox::critical(QApplication::activeWindow(), i18n("Error"), d->error);
187         }
188         else
189         {
190             emit signalEndUpload();
191         }
192 
193         d->error.clear();
194     }
195 }
196 
buildWikiText(const QMap<QString,QString> & info) const197 QString MediaWikiTalker::buildWikiText(const QMap<QString, QString>& info) const
198 {
199     QString text = QString::fromUtf8("=={{int:filedesc}}==");
200     text.append(QLatin1String("\n{{Information"));
201     text.append(QLatin1String("\n|Description=")).append(info[QLatin1String("description")]);
202     text.append(QLatin1String("\n|Source="));
203 
204     if (!info[QLatin1String("source")].isEmpty())
205     {
206         text.append(info[QLatin1String("source")]);
207     }
208 
209     text.append(QLatin1String("\n|Author="));
210 
211     if (!info[QLatin1String("author")].isEmpty())
212     {
213         text.append(info[QLatin1String("author")]);
214     }
215 
216     text.append(QLatin1String("\n|Date=")).append(info[QLatin1String("date")]);
217     text.append(QLatin1String("\n|Permission="));
218     text.append(QLatin1String("\n|other_versions="));
219     text.append(QLatin1String("\n}}\n"));
220 
221     QString latitude  = info[QLatin1String("latitude")];
222     QString longitude = info[QLatin1String("longitude")];
223 
224     if (!latitude.isEmpty() && !longitude.isEmpty())
225     {
226         qCDebug(DIGIKAM_WEBSERVICES_LOG) << "Latitude:" << latitude << "; longitude:" << longitude;
227         text.append(QLatin1String("{{Location|")).append(latitude).append(QLatin1String("|")).append(longitude).append(QLatin1String("}}\n"));
228     }
229 
230     if (!info[QLatin1String("genText")].isEmpty())
231     {
232         text.append(info[QLatin1String("genText")]).append(QLatin1Char('\n'));
233     }
234 
235     if (!info[QLatin1String("license")].isEmpty())
236     {
237         text.append(QLatin1String("\n=={{int:license-header}}==\n"));
238         text.append(info[QLatin1String("license")]).append(QLatin1String("\n\n"));
239     }
240 
241     QStringList categories;
242 
243     if (!info[QLatin1String("categories")].isEmpty())
244     {
245         categories = info[QLatin1String("categories")].split(QLatin1Char('\n'), QString::SkipEmptyParts);
246 
247         for (int i = 0 ; i < categories.size() ; ++i)
248         {
249             text.append(QLatin1String("[[Category:")).append(categories[i]).append(QLatin1String("]]\n"));
250         }
251     }
252 
253     if (!info[QLatin1String("genCategories")].isEmpty())
254     {
255         categories = info[QLatin1String("genCategories")].split(QLatin1Char('\n'), QString::SkipEmptyParts);
256 
257         for (int i = 0 ; i < categories.size() ; ++i)
258         {
259             text.append(QLatin1String("[[Category:")).append(categories[i]).append(QLatin1String("]]\n"));
260         }
261     }
262 
263     return text;
264 }
265 
slotUploadProgress(KJob * job,unsigned long percent)266 void MediaWikiTalker::slotUploadProgress(KJob* job, unsigned long percent)
267 {
268     Q_UNUSED(job)
269     emit signalUploadProgress((int)percent);
270 }
271 
272 } // namespace DigikamGenericMediaWikiPlugin
273