File indexing completed on 2024-04-14 05:43:32

0001 /*
0002     SPDX-FileCopyrightText: 2011, 2012, 2013 Rolf Eike Beer <kde@opensource.sf-tec.de>
0003     SPDX-License-Identifier: GPL-2.0-or-later
0004 */
0005 
0006 #include "foldercompressjob.h"
0007 
0008 #include <KArchive>
0009 #include <KLocalizedString>
0010 #include <KTar>
0011 #include <KZip>
0012 
0013 #include <QDir>
0014 #include <QMetaObject>
0015 #include <QTemporaryFile>
0016 
0017 class FolderCompressJobPrivate {
0018     FolderCompressJob * const q_ptr;
0019     Q_DECLARE_PUBLIC(FolderCompressJob)
0020 
0021 public:
0022     FolderCompressJobPrivate(FolderCompressJob *parent, const QList<QUrl> &sources, const QUrl &dest, QTemporaryFile *tempfile, const QStringList &keys, const QStringList &options, const KGpgEncrypt::EncryptOptions encOptions, const int archive);
0023 
0024     const QString m_description;
0025     const QList<QUrl> m_sources;
0026     const QUrl m_dest;
0027     QTemporaryFile * const m_tempfile;
0028     const QStringList m_keys;
0029     QStringList m_options;
0030     const KGpgEncrypt::EncryptOptions m_encOptions;
0031     const int m_archiveType;
0032 };
0033 
0034 FolderCompressJobPrivate::FolderCompressJobPrivate(FolderCompressJob *parent, const QList<QUrl> &sources, const QUrl &dest, QTemporaryFile *tempfile, const QStringList &keys, const QStringList &options, const KGpgEncrypt::EncryptOptions encOptions, const int archive)
0035     : q_ptr(parent),
0036     m_description(i18n("Processing folder compression and encryption")),
0037     m_sources(sources),
0038     m_dest(dest),
0039     m_tempfile(tempfile),
0040     m_keys(keys),
0041     m_options(options),
0042     m_encOptions(encOptions),
0043     m_archiveType(archive)
0044 {
0045 }
0046 
0047 FolderCompressJob::FolderCompressJob(QObject *parent, const QList<QUrl> &sources, const QUrl &dest, QTemporaryFile *tempfile, const QStringList &keys, const QStringList &options,  const KGpgEncrypt::EncryptOptions encOptions, const int archive)
0048     : KJob(parent),
0049     d_ptr(new FolderCompressJobPrivate(this, sources, dest, tempfile, keys, options, encOptions, archive))
0050 {
0051 }
0052 
0053 FolderCompressJob::~FolderCompressJob()
0054 {
0055     delete d_ptr;
0056 }
0057 
0058 void
0059 FolderCompressJob::start()
0060 {
0061     Q_D(FolderCompressJob);
0062 
0063     Q_EMIT description(this, d->m_description, qMakePair(i18nc("State of operation as in status", "State"), i18nc("Job is started up", "Startup")));
0064     QMetaObject::invokeMethod(this, "doWork", Qt::QueuedConnection);
0065 }
0066 
0067 void
0068 FolderCompressJob::doWork()
0069 {
0070     Q_D(FolderCompressJob);
0071     KArchive *arch = nullptr;
0072 
0073     switch (d->m_archiveType) {
0074     case 0:
0075         arch = new KZip(d->m_tempfile->fileName());
0076         break;
0077     case 1:
0078         arch = new KTar(d->m_tempfile->fileName(), QLatin1String( "application/x-gzip" ));
0079         break;
0080     case 2:
0081         arch = new KTar(d->m_tempfile->fileName(), QLatin1String( "application/x-bzip" ));
0082         break;
0083     case 3:
0084         arch = new KTar(d->m_tempfile->fileName(), QLatin1String( "application/x-tar" ));
0085         break;
0086     case 4:
0087         arch = new KTar(d->m_tempfile->fileName(), QLatin1String( "application/x-xz" ));
0088         break;
0089     default:
0090         Q_ASSERT(0);
0091         return;
0092     }
0093 
0094     if (!arch->open(QIODevice::WriteOnly)) {
0095         setError(UserDefinedError);
0096         setErrorText(i18n("Unable to create temporary file"));
0097         delete arch;
0098         emitResult();
0099         return;
0100     }
0101 
0102     for (const QUrl &url : d->m_sources)
0103         arch->addLocalDirectory(url.path(), url.fileName());
0104     arch->close();
0105     delete arch;
0106 
0107     setPercent(50);
0108 
0109     QDir outPath = d->m_sources.first().path();
0110     outPath.cdUp();
0111 
0112     d->m_options << QLatin1String("--output") << QDir::toNativeSeparators(outPath.path() + QDir::separator()) + d->m_dest.fileName();
0113 
0114     Q_EMIT description(this, d->m_description, qMakePair(i18nc("State of operation as in status", "State"),
0115             i18nc("Status message 'Encrypting <filename>' (operation starts)", "Encrypting %1", d->m_dest.path())));
0116         
0117 
0118     KGpgEncrypt *enc = new KGpgEncrypt(this, d->m_keys, QList<QUrl>({QUrl::fromLocalFile(d->m_tempfile->fileName())}), d->m_encOptions, d->m_options);
0119     connect(enc, &KGpgEncrypt::done, this, &FolderCompressJob::slotEncryptionDone);
0120     enc->start();
0121 }
0122 
0123 void
0124 FolderCompressJob::slotEncryptionDone(int result)
0125 {
0126     Q_D(FolderCompressJob);
0127 
0128     sender()->deleteLater();
0129 
0130     if ((result != KGpgTransaction::TS_OK) && (result != KGpgTransaction::TS_USER_ABORTED)) {
0131         setError(KJob::UserDefinedError + 1);
0132         setErrorText(i18n("The encryption failed with error code %1", result));
0133         Q_EMIT description(this, d->m_description, qMakePair(i18nc("State of operation as in status", "State"), i18n("Encryption failed.")));
0134     } else {
0135         Q_EMIT description(this, d->m_description, qMakePair(i18nc("State of operation as in status", "State"),
0136                 i18nc("Status message 'Encrypted <filename>' (operation was completed)", "Encrypted %1", d->m_dest.path())));
0137     }
0138 
0139     emitResult();
0140 }
0141 
0142 QString
0143 FolderCompressJob::extensionForArchive(const int archive)
0144 {
0145     switch (archive) {
0146     case 0:
0147         return QLatin1String(".zip");
0148     case 1:
0149         return QLatin1String(".tar.gz");
0150     case 2:
0151         return QLatin1String(".tar.bz2");
0152     case 3:
0153         return QLatin1String(".tar");
0154     case 4:
0155         return QLatin1String(".tar.xz");
0156     default:
0157         Q_ASSERT(archive <= archiveNames().count());
0158         Q_ASSERT(archive >= 0);
0159         return QString();
0160     }
0161 }
0162 
0163 const QStringList &
0164 FolderCompressJob::archiveNames()
0165 {
0166     static const QStringList archives =
0167             QStringList(i18n("Zip")) <<
0168                     i18n("Tar/Gzip") <<
0169                     i18n("Tar/Bzip2") <<
0170                     i18n("Tar") <<
0171                     i18n("Tar/XZ");
0172 
0173     return archives;
0174 }