File indexing completed on 2025-03-09 04:54:12
0001 /* 0002 SPDX-FileCopyrightText: 2009 Constantin Berzan <exit3219@gmail.com> 0003 0004 Based on KMail code by various authors. 0005 0006 SPDX-License-Identifier: LGPL-2.0-or-later 0007 */ 0008 0009 #include "attachmentcompressjob.h" 0010 0011 #include <KLocalizedString> 0012 #include <KZip> 0013 0014 #include <QBuffer> 0015 #include <QDateTime> 0016 #include <QSharedPointer> 0017 #include <QTimer> 0018 0019 using namespace MessageCore; 0020 static const mode_t archivePerms = S_IFREG | 0644; 0021 0022 class MessageCore::AttachmentCompressJob::AttachmentCompressJobPrivate 0023 { 0024 public: 0025 AttachmentCompressJobPrivate(AttachmentCompressJob *qq); 0026 0027 void doStart(); // slot 0028 0029 AttachmentCompressJob *const q; 0030 AttachmentPart::Ptr mOriginalPart; 0031 AttachmentPart::Ptr mCompressedPart; 0032 bool mCompressedPartLarger = false; 0033 }; 0034 0035 AttachmentCompressJob::AttachmentCompressJobPrivate::AttachmentCompressJobPrivate(AttachmentCompressJob *qq) 0036 : q(qq) 0037 { 0038 } 0039 0040 void AttachmentCompressJob::AttachmentCompressJobPrivate::doStart() 0041 { 0042 Q_ASSERT(mOriginalPart); 0043 const QByteArray decoded = mOriginalPart->data(); 0044 0045 QByteArray array; 0046 QBuffer dev(&array); 0047 KZip zip(&dev); 0048 if (!zip.open(QIODevice::WriteOnly)) { 0049 q->setError(KJob::UserDefinedError); 0050 q->setErrorText(i18n("Could not initiate attachment compression.")); 0051 q->emitResult(); 0052 return; 0053 } 0054 0055 // Compress. 0056 zip.setCompression(KZip::DeflateCompression); 0057 QDateTime zipTime = QDateTime::currentDateTime(); 0058 if (!zip.writeFile(mOriginalPart->name(), decoded, archivePerms, QString(/*user*/), QString(/*group*/), zipTime, zipTime, zipTime)) { 0059 q->setError(KJob::UserDefinedError); 0060 q->setErrorText(i18n("Could not compress the attachment.")); 0061 q->emitResult(); 0062 return; 0063 } 0064 zip.close(); 0065 mCompressedPartLarger = (array.size() >= decoded.size()); 0066 0067 // Create new part. 0068 Q_ASSERT(mCompressedPart == nullptr); 0069 mCompressedPart = AttachmentPart::Ptr(new AttachmentPart); 0070 mCompressedPart->setName(mOriginalPart->name() + QLatin1StringView(".zip")); // TODO not sure name should be .zipped too 0071 mCompressedPart->setFileName(mOriginalPart->fileName() + QLatin1StringView(".zip")); 0072 mCompressedPart->setDescription(mOriginalPart->description()); 0073 mCompressedPart->setInline(mOriginalPart->isInline()); 0074 mCompressedPart->setMimeType("application/zip"); 0075 mCompressedPart->setCompressed(true); 0076 mCompressedPart->setEncrypted(mOriginalPart->isEncrypted()); 0077 mCompressedPart->setSigned(mOriginalPart->isSigned()); 0078 mCompressedPart->setData(array); 0079 q->emitResult(); // Success. 0080 0081 // TODO consider adding a copy constructor to AttachmentPart. 0082 } 0083 0084 AttachmentCompressJob::AttachmentCompressJob(const AttachmentPart::Ptr &part, QObject *parent) 0085 : KJob(parent) 0086 , d(new AttachmentCompressJobPrivate(this)) 0087 { 0088 d->mOriginalPart = part; 0089 } 0090 0091 AttachmentCompressJob::~AttachmentCompressJob() = default; 0092 0093 void AttachmentCompressJob::start() 0094 { 0095 QTimer::singleShot(0, this, [this]() { 0096 d->doStart(); 0097 }); 0098 } 0099 0100 const AttachmentPart::Ptr AttachmentCompressJob::originalPart() const 0101 { 0102 return d->mOriginalPart; 0103 } 0104 0105 void AttachmentCompressJob::setOriginalPart(const AttachmentPart::Ptr &part) 0106 { 0107 d->mOriginalPart = part; 0108 } 0109 0110 AttachmentPart::Ptr AttachmentCompressJob::compressedPart() const 0111 { 0112 return d->mCompressedPart; 0113 } 0114 0115 bool AttachmentCompressJob::isCompressedPartLarger() const 0116 { 0117 return d->mCompressedPartLarger; 0118 } 0119 0120 #include "moc_attachmentcompressjob.cpp"