1 /*
2 SPDX-FileCopyrightText: 2011, 2012, 2013 Rolf Eike Beer <kde@opensource.sf-tec.de>
3 SPDX-License-Identifier: GPL-2.0-or-later
4 */
5
6 #include "foldercompressjob.h"
7
8 #include <KArchive>
9 #include <KLocalizedString>
10 #include <KTar>
11 #include <KZip>
12
13 #include <QDir>
14 #include <QMetaObject>
15 #include <QStringList>
16 #include <QTemporaryFile>
17
18 class FolderCompressJobPrivate {
19 FolderCompressJob * const q_ptr;
20 Q_DECLARE_PUBLIC(FolderCompressJob)
21
22 public:
23 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);
24
25 const QString m_description;
26 const QList<QUrl> m_sources;
27 const QUrl m_dest;
28 QTemporaryFile * const m_tempfile;
29 const QStringList m_keys;
30 QStringList m_options;
31 const KGpgEncrypt::EncryptOptions m_encOptions;
32 const int m_archiveType;
33 };
34
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)35 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)
36 : q_ptr(parent),
37 m_description(i18n("Processing folder compression and encryption")),
38 m_sources(sources),
39 m_dest(dest),
40 m_tempfile(tempfile),
41 m_keys(keys),
42 m_options(options),
43 m_encOptions(encOptions),
44 m_archiveType(archive)
45 {
46 }
47
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)48 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)
49 : KJob(parent),
50 d_ptr(new FolderCompressJobPrivate(this, sources, dest, tempfile, keys, options, encOptions, archive))
51 {
52 }
53
~FolderCompressJob()54 FolderCompressJob::~FolderCompressJob()
55 {
56 delete d_ptr;
57 }
58
59 void
start()60 FolderCompressJob::start()
61 {
62 Q_D(FolderCompressJob);
63
64 Q_EMIT description(this, d->m_description, qMakePair(i18nc("State of operation as in status", "State"), i18nc("Job is started up", "Startup")));
65 QMetaObject::invokeMethod(this, "doWork", Qt::QueuedConnection);
66 }
67
68 void
doWork()69 FolderCompressJob::doWork()
70 {
71 Q_D(FolderCompressJob);
72 KArchive *arch = nullptr;
73
74 switch (d->m_archiveType) {
75 case 0:
76 arch = new KZip(d->m_tempfile->fileName());
77 break;
78 case 1:
79 arch = new KTar(d->m_tempfile->fileName(), QLatin1String( "application/x-gzip" ));
80 break;
81 case 2:
82 arch = new KTar(d->m_tempfile->fileName(), QLatin1String( "application/x-bzip" ));
83 break;
84 case 3:
85 arch = new KTar(d->m_tempfile->fileName(), QLatin1String( "application/x-tar" ));
86 break;
87 case 4:
88 arch = new KTar(d->m_tempfile->fileName(), QLatin1String( "application/x-xz" ));
89 break;
90 default:
91 Q_ASSERT(0);
92 return;
93 }
94
95 if (!arch->open(QIODevice::WriteOnly)) {
96 setError(UserDefinedError);
97 setErrorText(i18n("Unable to create temporary file"));
98 delete arch;
99 emitResult();
100 return;
101 }
102
103 for (const QUrl &url : d->m_sources)
104 arch->addLocalDirectory(url.path(), url.fileName());
105 arch->close();
106 delete arch;
107
108 setPercent(50);
109
110 QDir outPath = d->m_sources.first().path();
111 outPath.cdUp();
112
113 d->m_options << QLatin1String("--output") << QDir::toNativeSeparators(outPath.path() + QDir::separator()) + d->m_dest.fileName();
114
115 Q_EMIT description(this, d->m_description, qMakePair(i18nc("State of operation as in status", "State"),
116 i18nc("Status message 'Encrypting <filename>' (operation starts)", "Encrypting %1", d->m_dest.path())));
117
118
119 KGpgEncrypt *enc = new KGpgEncrypt(this, d->m_keys, QList<QUrl>({QUrl::fromLocalFile(d->m_tempfile->fileName())}), d->m_encOptions, d->m_options);
120 connect(enc, &KGpgEncrypt::done, this, &FolderCompressJob::slotEncryptionDone);
121 enc->start();
122 }
123
124 void
slotEncryptionDone(int result)125 FolderCompressJob::slotEncryptionDone(int result)
126 {
127 Q_D(FolderCompressJob);
128
129 sender()->deleteLater();
130
131 if ((result != KGpgTransaction::TS_OK) && (result != KGpgTransaction::TS_USER_ABORTED)) {
132 setError(KJob::UserDefinedError + 1);
133 setErrorText(i18n("The encryption failed with error code %1", result));
134 Q_EMIT description(this, d->m_description, qMakePair(i18nc("State of operation as in status", "State"), i18n("Encryption failed.")));
135 } else {
136 Q_EMIT description(this, d->m_description, qMakePair(i18nc("State of operation as in status", "State"),
137 i18nc("Status message 'Encrypted <filename>' (operation was completed)", "Encrypted %1", d->m_dest.path())));
138 }
139
140 emitResult();
141 }
142
143 QString
extensionForArchive(const int archive)144 FolderCompressJob::extensionForArchive(const int archive)
145 {
146 switch (archive) {
147 case 0:
148 return QLatin1String(".zip");
149 case 1:
150 return QLatin1String(".tar.gz");
151 case 2:
152 return QLatin1String(".tar.bz2");
153 case 3:
154 return QLatin1String(".tar");
155 case 4:
156 return QLatin1String(".tar.xz");
157 default:
158 Q_ASSERT(archive <= archiveNames().count());
159 Q_ASSERT(archive >= 0);
160 return QString();
161 }
162 }
163
164 const QStringList &
archiveNames()165 FolderCompressJob::archiveNames()
166 {
167 static const QStringList archives =
168 QStringList(i18n("Zip")) <<
169 i18n("Tar/Gzip") <<
170 i18n("Tar/Bzip2") <<
171 i18n("Tar") <<
172 i18n("Tar/XZ");
173
174 return archives;
175 }
176