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 | |
18 | static 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 | |
30 | class SaveAsShareJob : public Purpose::Job |
31 | { |
32 | Q_OBJECT |
33 | public: |
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 | |
94 | private: |
95 | QUrl m_dest; |
96 | QSet<KJob *> m_jobs; |
97 | }; |
98 | |
99 | class SaveAsPlugin : public Purpose::PluginBase |
100 | { |
101 | Q_OBJECT |
102 | public: |
103 | using PluginBase::PluginBase; |
104 | Purpose::Job *createJob() const override |
105 | { |
106 | return new SaveAsShareJob(nullptr); |
107 | } |
108 | }; |
109 | |
110 | K_PLUGIN_CLASS_WITH_JSON(SaveAsPlugin, "saveasplugin.json" ) |
111 | |
112 | #include "saveasplugin.moc" |
113 | |