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