File indexing completed on 2024-05-19 04:03:04

0001 /*
0002     SPDX-FileCopyrightText: 2014 Aleix Pol Gonzalez <aleixpol@blue-systems.com>
0003 
0004     SPDX-License-Identifier: LGPL-2.1-or-later
0005 */
0006 
0007 #include <purpose/job.h>
0008 #include <purpose/pluginbase.h>
0009 
0010 #include <KIO/CopyJob>
0011 #include <KLocalizedString>
0012 #include <KPluginFactory>
0013 #include <QFile>
0014 #include <QFileInfo>
0015 #include <QJsonArray>
0016 #include <QStandardPaths>
0017 
0018 static QUrl addPathToUrl(const QUrl &url, const QString &relPath)
0019 {
0020     QString path = url.path();
0021     if (!path.endsWith(QLatin1Char('/'))) {
0022         path += QLatin1Char('/');
0023     }
0024     path += relPath;
0025     QUrl u(url);
0026     u.setPath(path);
0027     return u;
0028 }
0029 
0030 class SaveAsShareJob : public Purpose::Job
0031 {
0032     Q_OBJECT
0033 public:
0034     SaveAsShareJob(QObject *parent)
0035         : Purpose::Job(parent)
0036     {
0037         setCapabilities(Killable | Suspendable);
0038     }
0039 
0040     void start() override
0041     {
0042         const QJsonArray inputUrls = data().value(QLatin1String("urls")).toArray();
0043 
0044         if (inputUrls.isEmpty()) {
0045             setErrorText(i18n("No URLs to save"));
0046             setError(1);
0047             emitResult();
0048             return;
0049         }
0050 
0051         QList<QUrl> urls;
0052         bool containsData = false;
0053         for (const QJsonValue &val : inputUrls) {
0054             urls.append(QUrl(val.toString()));
0055             containsData |= urls.last().scheme() == QLatin1String("data");
0056         }
0057 
0058         m_dest = QUrl(data().value(QLatin1String("destinationPath")).toString());
0059         if (containsData && !(urls.count() == 1 && m_dest.isLocalFile() && !QFileInfo(m_dest.toLocalFile()).isDir())) {
0060             for (const QUrl &url : urls) {
0061                 QUrl dest = addPathToUrl(m_dest, QStringLiteral("data"));
0062                 auto job = KIO::copy(url, dest);
0063                 connect(job, &KJob::finished, this, &SaveAsShareJob::fileCopied);
0064                 m_jobs.insert(job);
0065             }
0066         } else {
0067             auto job = KIO::copy(urls, m_dest);
0068             connect(job, &KJob::finished, this, &SaveAsShareJob::fileCopied);
0069             m_jobs.insert(job);
0070         }
0071     }
0072 
0073     bool doKill() override
0074     {
0075         bool killed = true;
0076         for (KJob *job : m_jobs)
0077             killed &= job->kill();
0078         return killed;
0079     }
0080 
0081     void fileCopied(KJob *job)
0082     {
0083         auto r = m_jobs.remove(job);
0084         Q_ASSERT(r);
0085 
0086         setError(error() + job->error());
0087         setErrorText(errorText() + QLatin1Char(' ') + job->errorText());
0088         if (job->error() == 0 && m_jobs.isEmpty()) {
0089             setOutput({{QStringLiteral("url"), m_dest.toString()}});
0090         }
0091         emitResult();
0092     }
0093 
0094 private:
0095     QUrl m_dest;
0096     QSet<KJob *> m_jobs;
0097 };
0098 
0099 class SaveAsPlugin : public Purpose::PluginBase
0100 {
0101     Q_OBJECT
0102 public:
0103     using PluginBase::PluginBase;
0104     Purpose::Job *createJob() const override
0105     {
0106         return new SaveAsShareJob(nullptr);
0107     }
0108 };
0109 
0110 K_PLUGIN_CLASS_WITH_JSON(SaveAsPlugin, "saveasplugin.json")
0111 
0112 #include "saveasplugin.moc"