File indexing completed on 2024-05-12 05:11:11
0001 /* 0002 SPDX-FileCopyrightText: 2009 Constantin Berzan <exit3219@gmail.com> 0003 0004 SPDX-License-Identifier: LGPL-2.0-or-later 0005 */ 0006 0007 #include "messagequeuejob.h" 0008 0009 #include "transportattribute.h" 0010 0011 #include "akonadi_mime_debug.h" 0012 #include <KLocalizedString> 0013 0014 #include <Akonadi/Item> 0015 #include <Akonadi/ItemCreateJob> 0016 #include <Akonadi/MessageFlags> 0017 #include <Akonadi/SpecialMailCollections> 0018 #include <Akonadi/SpecialMailCollectionsRequestJob> 0019 0020 using namespace Akonadi; 0021 using namespace KMime; 0022 0023 /** 0024 @internal 0025 */ 0026 class Akonadi::MessageQueueJobPrivate 0027 { 0028 public: 0029 explicit MessageQueueJobPrivate(MessageQueueJob *qq) 0030 : q(qq) 0031 { 0032 } 0033 0034 MessageQueueJob *const q; 0035 0036 Message::Ptr message; 0037 TransportAttribute transportAttribute; 0038 DispatchModeAttribute dispatchModeAttribute; 0039 SentBehaviourAttribute sentBehaviourAttribute; 0040 SentActionAttribute sentActionAttribute; 0041 AddressAttribute addressAttribute; 0042 bool started = false; 0043 0044 /** 0045 Returns true if this message has everything it needs and is ready to be 0046 sent. 0047 */ 0048 [[nodiscard]] bool validate() const; 0049 0050 // slot 0051 void outboxRequestResult(KJob *job); 0052 }; 0053 0054 bool MessageQueueJobPrivate::validate() const 0055 { 0056 if (!message) { 0057 q->setError(KJob::UserDefinedError); 0058 q->setErrorText(i18n("Empty message.")); 0059 q->emitResult(); 0060 return false; 0061 } 0062 0063 if ((addressAttribute.to().count() + addressAttribute.cc().count() + addressAttribute.bcc().count()) == 0) { 0064 q->setError(KJob::UserDefinedError); 0065 q->setErrorText(i18n("Message has no recipients.")); 0066 q->emitResult(); 0067 return false; 0068 } 0069 0070 if (sentBehaviourAttribute.sentBehaviour() == SentBehaviourAttribute::MoveToCollection && !(sentBehaviourAttribute.moveToCollection().isValid())) { 0071 q->setError(KJob::UserDefinedError); 0072 q->setErrorText(i18n("Message has invalid sent-mail folder.")); 0073 q->emitResult(); 0074 return false; 0075 } else if (sentBehaviourAttribute.sentBehaviour() == SentBehaviourAttribute::MoveToDefaultSentCollection) { 0076 // TODO require SpecialMailCollections::SentMail here? 0077 } 0078 0079 return true; // all ok 0080 } 0081 0082 void MessageQueueJobPrivate::outboxRequestResult(KJob *job) 0083 { 0084 Q_ASSERT(!started); 0085 started = true; 0086 0087 if (job->error()) { 0088 qCritical() << "Failed to get the Outbox folder:" << job->error() << job->errorString(); 0089 q->setError(job->error()); 0090 q->emitResult(); 0091 return; 0092 } 0093 0094 if (!validate()) { 0095 // The error has been set; the result has been emitted. 0096 return; 0097 } 0098 0099 auto requestJob = qobject_cast<SpecialMailCollectionsRequestJob *>(job); 0100 if (!requestJob) { 0101 return; 0102 } 0103 0104 // Create item. 0105 Item item; 0106 item.setMimeType(QStringLiteral("message/rfc822")); 0107 item.setPayload<Message::Ptr>(message); 0108 0109 // Set attributes. 0110 item.addAttribute(addressAttribute.clone()); 0111 item.addAttribute(dispatchModeAttribute.clone()); 0112 item.addAttribute(sentBehaviourAttribute.clone()); 0113 item.addAttribute(sentActionAttribute.clone()); 0114 item.addAttribute(transportAttribute.clone()); 0115 0116 Akonadi::MessageFlags::copyMessageFlags(*message, item); 0117 // Set flags. 0118 item.setFlag(Akonadi::MessageFlags::Queued); 0119 0120 // Store the item in the outbox. 0121 const Collection collection = requestJob->collection(); 0122 Q_ASSERT(collection.isValid()); 0123 auto cjob = new ItemCreateJob(item, collection); // job autostarts 0124 q->addSubjob(cjob); 0125 } 0126 0127 MessageQueueJob::MessageQueueJob(QObject *parent) 0128 : KCompositeJob(parent) 0129 , d(new MessageQueueJobPrivate(this)) 0130 { 0131 } 0132 0133 MessageQueueJob::~MessageQueueJob() = default; 0134 0135 Message::Ptr MessageQueueJob::message() const 0136 { 0137 return d->message; 0138 } 0139 0140 DispatchModeAttribute &MessageQueueJob::dispatchModeAttribute() 0141 { 0142 return d->dispatchModeAttribute; 0143 } 0144 0145 AddressAttribute &MessageQueueJob::addressAttribute() 0146 { 0147 return d->addressAttribute; 0148 } 0149 0150 TransportAttribute &MessageQueueJob::transportAttribute() 0151 { 0152 return d->transportAttribute; 0153 } 0154 0155 SentBehaviourAttribute &MessageQueueJob::sentBehaviourAttribute() 0156 { 0157 return d->sentBehaviourAttribute; 0158 } 0159 0160 SentActionAttribute &MessageQueueJob::sentActionAttribute() 0161 { 0162 return d->sentActionAttribute; 0163 } 0164 0165 void MessageQueueJob::setMessage(const Message::Ptr &message) 0166 { 0167 d->message = message; 0168 } 0169 0170 void MessageQueueJob::start() 0171 { 0172 auto rjob = new SpecialMailCollectionsRequestJob(this); 0173 rjob->requestDefaultCollection(SpecialMailCollections::Outbox); 0174 connect(rjob, &SpecialMailCollectionsRequestJob::result, this, [this](KJob *job) { 0175 d->outboxRequestResult(job); 0176 }); 0177 rjob->start(); 0178 } 0179 0180 void MessageQueueJob::slotResult(KJob *job) 0181 { 0182 // error handling 0183 KCompositeJob::slotResult(job); 0184 0185 if (!error()) { 0186 emitResult(); 0187 } 0188 } 0189 0190 #include "moc_messagequeuejob.cpp"