1/*
2 SPDX-FileCopyrightText: 2014 Aleix Pol Gonzalez <aleixpol@blue-systems.com>
3
4 SPDX-License-Identifier: LGPL-2.1-or-later
5*/
6
7#include <purpose/job.h>
8#include <purpose/pluginbase.h>
9
10#include <KIO/CopyJob>
11#include <KLocalizedString>
12#include <KPluginFactory>
13#include <QFile>
14#include <QFileInfo>
15#include <QJsonArray>
16#include <QStandardPaths>
17
18static QUrl addPathToUrl(const QUrl &url, const QString &relPath)
19{
20 QString path = url.path();
21 if (!path.endsWith(c: QLatin1Char('/'))) {
22 path += QLatin1Char('/');
23 }
24 path += relPath;
25 QUrl u(url);
26 u.setPath(path);
27 return u;
28}
29
30class SaveAsShareJob : public Purpose::Job
31{
32 Q_OBJECT
33public:
34 SaveAsShareJob(QObject *parent)
35 : Purpose::Job(parent)
36 {
37 setCapabilities(Killable | Suspendable);
38 }
39
40 void start() override
41 {
42 const QJsonArray inputUrls = data().value(key: QLatin1String("urls")).toArray();
43
44 if (inputUrls.isEmpty()) {
45 setErrorText(i18n("No URLs to save"));
46 setError(1);
47 emitResult();
48 return;
49 }
50
51 QList<QUrl> urls;
52 bool containsData = false;
53 for (const QJsonValue &val : inputUrls) {
54 urls.append(t: QUrl(val.toString()));
55 containsData |= urls.last().scheme() == QLatin1String("data");
56 }
57
58 m_dest = QUrl(data().value(key: QLatin1String("destinationPath")).toString());
59 if (containsData && !(urls.count() == 1 && m_dest.isLocalFile() && !QFileInfo(m_dest.toLocalFile()).isDir())) {
60 for (const QUrl &url : urls) {
61 QUrl dest = addPathToUrl(url: m_dest, QStringLiteral("data"));
62 auto job = KIO::copy(src: url, dest);
63 connect(sender: job, signal: &KJob::finished, context: this, slot: &SaveAsShareJob::fileCopied);
64 m_jobs.insert(value: job);
65 }
66 } else {
67 auto job = KIO::copy(src: urls, dest: m_dest);
68 connect(sender: job, signal: &KJob::finished, context: this, slot: &SaveAsShareJob::fileCopied);
69 m_jobs.insert(value: job);
70 }
71 }
72
73 bool doKill() override
74 {
75 bool killed = true;
76 for (KJob *job : m_jobs)
77 killed &= job->kill();
78 return killed;
79 }
80
81 void fileCopied(KJob *job)
82 {
83 auto r = m_jobs.remove(value: job);
84 Q_ASSERT(r);
85
86 setError(error() + job->error());
87 setErrorText(errorText() + QLatin1Char(' ') + job->errorText());
88 if (job->error() == 0 && m_jobs.isEmpty()) {
89 setOutput({{QStringLiteral("url"), m_dest.toString()}});
90 }
91 emitResult();
92 }
93
94private:
95 QUrl m_dest;
96 QSet<KJob *> m_jobs;
97};
98
99class SaveAsPlugin : public Purpose::PluginBase
100{
101 Q_OBJECT
102public:
103 using PluginBase::PluginBase;
104 Purpose::Job *createJob() const override
105 {
106 return new SaveAsShareJob(nullptr);
107 }
108};
109
110K_PLUGIN_CLASS_WITH_JSON(SaveAsPlugin, "saveasplugin.json")
111
112#include "saveasplugin.moc"
113

source code of purpose/src/plugins/saveas/saveasplugin.cpp