Messagelib

attachmentfromfolderjob.cpp
1 /*
2  SPDX-FileCopyrightText: 2011 Martin Bedn├ír <[email protected]>
3 
4  SPDX-License-Identifier: GPL-2.0-or-later
5 */
6 
7 #include "attachmentfromfolderjob.h"
8 
9 #include "messagecore_debug.h"
10 #include <KLocalizedString>
11 
12 #include <QBuffer>
13 #include <QDir>
14 #include <QScopedPointer>
15 #include <QSharedPointer>
16 
17 static const mode_t archivePermsAttachment = S_IFREG | 0644;
18 
19 using namespace MessageCore;
20 
21 class AttachmentFromFolderJob::AttachmentLoadJobPrivate
22 {
23 public:
24  AttachmentLoadJobPrivate(AttachmentFromFolderJob *qq);
25 
26  void compressFolder();
27  void addEntity(const QFileInfoList &f, const QString &path);
28 
29  AttachmentFromFolderJob *const q;
31  AttachmentPart::Ptr mCompressedFolder;
33  QDateTime mArchiveTime = QDateTime::currentDateTime();
34 };
35 
36 AttachmentFromFolderJob::AttachmentLoadJobPrivate::AttachmentLoadJobPrivate(AttachmentFromFolderJob *qq)
37  : q(qq)
38  , mZip(nullptr)
39 {
40 }
41 
42 void AttachmentFromFolderJob::AttachmentLoadJobPrivate::compressFolder()
43 {
44  qCDebug(MESSAGECORE_LOG) << "starting compression";
45  QString fileName = q->url().fileName();
46  QByteArray array;
47  QBuffer dev(&array);
48  mZip.reset(new KZip(&dev));
49  if (!mZip->open(QIODevice::WriteOnly)) {
50  q->setError(KJob::UserDefinedError);
51  q->setErrorText(i18n("Could not create compressed file."));
52  q->emitResult();
53  return;
54  }
55  mZip->setCompression(mCompression);
56  const QString filename = q->url().fileName();
57  if (!mZip->writeDir(filename, QString(), QString(), 040755, mArchiveTime, mArchiveTime, mArchiveTime)) {
58  qCWarning(MESSAGECORE_LOG) << " Impossible to write file " << fileName;
59  }
60  qCDebug(MESSAGECORE_LOG) << "writing root directory : " << filename;
61  addEntity(QDir(q->url().path()).entryInfoList(QDir::Dirs | QDir::NoDotAndDotDot | QDir::NoSymLinks | QDir::Files, QDir::DirsFirst),
62  fileName + QLatin1Char('/'));
63  mZip->close();
64 
65  Q_ASSERT(mCompressedFolder == nullptr);
66 
67  mCompressedFolder = AttachmentPart::Ptr(new AttachmentPart);
68  const QString newName = fileName + QLatin1String(".zip");
69  mCompressedFolder->setName(newName);
70  mCompressedFolder->setFileName(newName);
71  mCompressedFolder->setMimeType("application/zip");
72  mCompressedFolder->setUrl(q->url());
73  // mCompressedFolder->setCompressed( true );
74  mCompressedFolder->setData(array);
75  // mCompressedFolder->setCompressible(false);
76  q->setAttachmentPart(mCompressedFolder);
77  q->emitResult();
78 
79  // TODO:add allowCompression bool to AttachmentPart && modify GUI to disable decompressing.
80  // Or leave attachment as uncompressed and let it be compressed again?
81 }
82 
83 void AttachmentFromFolderJob::AttachmentLoadJobPrivate::addEntity(const QFileInfoList &f, const QString &path)
84 {
85  for (const QFileInfo &info : f) {
86  qCDebug(MESSAGECORE_LOG) << q->maximumAllowedSize() << "Attachment size : " << mZip->device()->size();
87 
88  if (q->maximumAllowedSize() != -1 && mZip->device()->size() > q->maximumAllowedSize()) {
89  q->setError(KJob::UserDefinedError);
90  q->setErrorText(i18n("The resulting attachment would be larger than the maximum allowed size, aborting."));
91  q->emitResult();
92  return;
93  }
94 
95  const QString infoFileName = info.fileName();
96  if (info.isDir()) {
97  qCDebug(MESSAGECORE_LOG) << "adding directory " << infoFileName << "to zip";
98  if (!mZip->writeDir(path + infoFileName, QString(), QString(), 040755, mArchiveTime, mArchiveTime, mArchiveTime)) {
99  q->setError(KJob::UserDefinedError);
100  q->setErrorText(i18n("Could not add %1 to the archive", infoFileName));
101  q->emitResult();
102  return;
103  }
104  addEntity(QDir(info.filePath()).entryInfoList(QDir::Dirs | QDir::NoDotAndDotDot | QDir::NoSymLinks | QDir::Files, QDir::DirsFirst),
105  path + infoFileName + QLatin1Char('/'));
106  }
107 
108  if (info.isFile()) {
109  qCDebug(MESSAGECORE_LOG) << "Adding file " << path + infoFileName << "to zip";
110  QFile file(info.filePath());
111  if (!file.open(QIODevice::ReadOnly)) {
112  q->setError(KJob::UserDefinedError);
113  q->setErrorText(i18n("Could not open %1 for reading.", file.fileName()));
114  q->emitResult();
115  return;
116  }
117  if (!mZip->writeFile(path + infoFileName, file.readAll(), archivePermsAttachment, QString(), QString(), mArchiveTime, mArchiveTime, mArchiveTime)) {
118  q->setError(KJob::UserDefinedError);
119  q->setErrorText(i18n("Could not add %1 to the archive", file.fileName()));
120  q->emitResult();
121  }
122  file.close();
123  }
124  }
125 }
126 
127 AttachmentFromFolderJob::AttachmentFromFolderJob(const QUrl &url, QObject *parent)
128  : AttachmentFromUrlBaseJob(url, parent)
129  , d(new AttachmentLoadJobPrivate(this))
130 {
131 }
132 
133 AttachmentFromFolderJob::~AttachmentFromFolderJob() = default;
134 
135 void AttachmentFromFolderJob::setCompression(KZip::Compression compression)
136 {
137  d->mCompression = compression;
138 }
139 
140 KZip::Compression AttachmentFromFolderJob::compression() const
141 {
142  return d->mCompression;
143 }
144 
145 void AttachmentFromFolderJob::doStart()
146 {
147  d->compressFolder();
148 }
A class that encapsulates an attachment.
DeflateCompression
QString i18n(const char *text, const TYPE &arg...)
QDateTime currentDateTime()
virtual void close() override
QObject * parent() const const
This file is part of the KDE documentation.
Documentation copyright © 1996-2021 The KDE developers.
Generated on Sun Dec 5 2021 23:04:52 by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.