File indexing completed on 2025-03-09 04:54:12
0001 /* 0002 SPDX-FileCopyrightText: 2009 Constantin Berzan <exit3219@gmail.com> 0003 0004 Parts based on KMail code by various authors. 0005 0006 SPDX-License-Identifier: LGPL-2.0-or-later 0007 */ 0008 0009 #include "attachmentfromurljob.h" 0010 0011 #include "messagecore_debug.h" 0012 #include <KIO/TransferJob> 0013 #include <KLocalizedString> 0014 0015 #include <QFileInfo> 0016 #include <QMimeDatabase> 0017 #include <QUrlQuery> 0018 0019 using namespace MessageCore; 0020 0021 class MessageCore::AttachmentFromUrlJob::AttachmentLoadJobPrivate 0022 { 0023 public: 0024 explicit AttachmentLoadJobPrivate(AttachmentFromUrlJob *qq); 0025 0026 void transferJobData(KIO::Job *job, const QByteArray &jobData); 0027 void transferJobResult(KJob *job); 0028 0029 AttachmentFromUrlJob *const q; 0030 QByteArray mData; 0031 }; 0032 0033 AttachmentFromUrlJob::AttachmentLoadJobPrivate::AttachmentLoadJobPrivate(AttachmentFromUrlJob *qq) 0034 : q(qq) 0035 { 0036 } 0037 0038 void AttachmentFromUrlJob::AttachmentLoadJobPrivate::transferJobData(KIO::Job *job, const QByteArray &jobData) 0039 { 0040 Q_UNUSED(job) 0041 mData += jobData; 0042 } 0043 0044 void AttachmentFromUrlJob::AttachmentLoadJobPrivate::transferJobResult(KJob *job) 0045 { 0046 if (job->error()) { 0047 // TODO this loses useful stuff from KIO, like detailed error descriptions, causes+solutions, 0048 // ... use UiDelegate somehow? 0049 q->setError(job->error()); 0050 q->setErrorText(job->errorString()); 0051 q->emitResult(); 0052 return; 0053 } 0054 0055 Q_ASSERT(dynamic_cast<KIO::TransferJob *>(job)); 0056 auto transferJob = static_cast<KIO::TransferJob *>(job); 0057 0058 // Determine the MIME type and filename of the attachment. 0059 const QString mimeTypeName = transferJob->mimetype(); 0060 qCDebug(MESSAGECORE_LOG) << "Mimetype is" << mimeTypeName; 0061 0062 QString fileName = q->url().fileName(); 0063 fileName.replace(QLatin1Char('\n'), QLatin1Char('_')); 0064 if (fileName.isEmpty()) { 0065 QMimeDatabase db; 0066 const auto mimeType = db.mimeTypeForName(mimeTypeName); 0067 if (mimeType.isValid()) { 0068 fileName = i18nc("a file called 'unknown.ext'", "unknown%1", mimeType.preferredSuffix()); 0069 } else { 0070 fileName = i18nc("a file called 'unknown'", "unknown"); 0071 } 0072 } 0073 0074 // Create the AttachmentPart. 0075 Q_ASSERT(q->attachmentPart() == nullptr); // Not created before. 0076 0077 AttachmentPart::Ptr part = AttachmentPart::Ptr(new AttachmentPart); 0078 QUrlQuery query(q->url()); 0079 const QString value = query.queryItemValue(QStringLiteral("charset")); 0080 part->setCharset(value.toLatin1()); 0081 part->setMimeType(mimeTypeName.toLatin1()); 0082 part->setName(fileName); 0083 part->setFileName(fileName); 0084 part->setData(mData); 0085 part->setUrl(q->url()); 0086 q->setAttachmentPart(part); 0087 q->emitResult(); // Success. 0088 } 0089 0090 AttachmentFromUrlJob::AttachmentFromUrlJob(const QUrl &url, QObject *parent) 0091 : AttachmentFromUrlBaseJob(url, parent) 0092 , d(new AttachmentLoadJobPrivate(this)) 0093 { 0094 } 0095 0096 AttachmentFromUrlJob::~AttachmentFromUrlJob() = default; 0097 0098 void AttachmentFromUrlJob::doStart() 0099 { 0100 if (!url().isValid()) { 0101 setError(KJob::UserDefinedError); 0102 setErrorText(i18n("\"%1\" not found. Please specify the full path.", url().toDisplayString())); 0103 emitResult(); 0104 return; 0105 } 0106 0107 if (maximumAllowedSize() != -1 && url().isLocalFile()) { 0108 const qint64 size = QFileInfo(url().toLocalFile()).size(); 0109 if (size > maximumAllowedSize()) { 0110 setError(KJob::UserDefinedError); 0111 setErrorText(i18n("You may not attach files bigger than %1. Share it with storage service.", KIO::convertSize(maximumAllowedSize()))); 0112 emitResult(); 0113 return; 0114 } 0115 } 0116 0117 Q_ASSERT(d->mData.isEmpty()); // Not started twice. 0118 0119 KIO::TransferJob *job = KIO::get(url(), KIO::NoReload, (uiDelegate() ? KIO::DefaultFlags : KIO::HideProgressInfo)); 0120 connect(job, &KIO::TransferJob::result, this, [this](KJob *job) { 0121 d->transferJobResult(job); 0122 }); 0123 connect(job, &KIO::TransferJob::data, this, [this](KIO::Job *job, const QByteArray &ba) { 0124 d->transferJobData(job, ba); 0125 }); 0126 } 0127 0128 #include "moc_attachmentfromurljob.cpp"