1 | /* |
2 | Copyright (c) 2009 Constantin Berzan <exit3219@gmail.com> |
3 | |
4 | This library is free software; you can redistribute it and/or modify it |
5 | under the terms of the GNU Library General Public License as published by |
6 | the Free Software Foundation; either version 2 of the License, or (at your |
7 | option) any later version. |
8 | |
9 | This library is distributed in the hope that it will be useful, but WITHOUT |
10 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
11 | FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public |
12 | License for more details. |
13 | |
14 | You should have received a copy of the GNU Library General Public License |
15 | along with this library; see the file COPYING.LIB. If not, write to the |
16 | Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA |
17 | 02110-1301, USA. |
18 | */ |
19 | |
20 | #include "messagequeuejob.h" |
21 | |
22 | #include "transport.h" |
23 | #include "transportattribute.h" |
24 | #include "transportmanager.h" |
25 | |
26 | #include <KDebug> |
27 | #include <KLocalizedString> |
28 | |
29 | #include <akonadi/collection.h> |
30 | #include <akonadi/item.h> |
31 | #include <akonadi/itemcreatejob.h> |
32 | #include <akonadi/kmime/addressattribute.h> |
33 | #include <akonadi/kmime/messageflags.h> |
34 | #include <akonadi/kmime/specialmailcollections.h> |
35 | #include <akonadi/kmime/specialmailcollectionsrequestjob.h> |
36 | |
37 | using namespace Akonadi; |
38 | using namespace KMime; |
39 | using namespace MailTransport; |
40 | |
41 | /** |
42 | @internal |
43 | */ |
44 | class MailTransport::MessageQueueJob::Private |
45 | { |
46 | public: |
47 | Private( MessageQueueJob *qq ) |
48 | : q( qq ) |
49 | { |
50 | started = false; |
51 | } |
52 | |
53 | MessageQueueJob *const q; |
54 | |
55 | Message::Ptr message; |
56 | TransportAttribute transportAttribute; |
57 | DispatchModeAttribute dispatchModeAttribute; |
58 | SentBehaviourAttribute sentBehaviourAttribute; |
59 | SentActionAttribute sentActionAttribute; |
60 | AddressAttribute addressAttribute; |
61 | bool started; |
62 | |
63 | /** |
64 | Returns true if this message has everything it needs and is ready to be |
65 | sent. |
66 | */ |
67 | bool validate(); |
68 | |
69 | // slot |
70 | void outboxRequestResult( KJob *job ); |
71 | |
72 | }; |
73 | |
74 | bool MessageQueueJob::Private::validate() |
75 | { |
76 | if ( !message ) { |
77 | q->setError( UserDefinedError ); |
78 | q->setErrorText( i18n( "Empty message." ) ); |
79 | q->emitResult(); |
80 | return false; |
81 | } |
82 | |
83 | if ( addressAttribute.to().count() + addressAttribute.cc().count() + |
84 | addressAttribute.bcc().count() == 0 ) { |
85 | q->setError( UserDefinedError ); |
86 | q->setErrorText( i18n( "Message has no recipients." ) ); |
87 | q->emitResult(); |
88 | return false; |
89 | } |
90 | |
91 | const int transport = transportAttribute.transportId(); |
92 | if ( TransportManager::self()->transportById( transport, false ) == 0 ) { |
93 | q->setError( UserDefinedError ); |
94 | q->setErrorText( i18n( "Message has invalid transport." ) ); |
95 | q->emitResult(); |
96 | return false; |
97 | } |
98 | |
99 | if ( sentBehaviourAttribute.sentBehaviour() == SentBehaviourAttribute::MoveToCollection && |
100 | !( sentBehaviourAttribute.moveToCollection().isValid() ) ) { |
101 | q->setError( UserDefinedError ); |
102 | q->setErrorText( i18n( "Message has invalid sent-mail folder." ) ); |
103 | q->emitResult(); |
104 | return false; |
105 | } else if ( sentBehaviourAttribute.sentBehaviour() == |
106 | SentBehaviourAttribute::MoveToDefaultSentCollection ) { |
107 | // TODO require SpecialMailCollections::SentMail here? |
108 | } |
109 | |
110 | return true; // all ok |
111 | } |
112 | |
113 | void MessageQueueJob::Private::outboxRequestResult( KJob *job ) |
114 | { |
115 | Q_ASSERT( !started ); |
116 | started = true; |
117 | |
118 | if ( job->error() ) { |
119 | kError() << "Failed to get the Outbox folder:" << job->error() << job->errorString(); |
120 | q->setError( job->error() ); |
121 | q->emitResult(); |
122 | return; |
123 | } |
124 | |
125 | if ( !validate() ) { |
126 | // The error has been set; the result has been emitted. |
127 | return; |
128 | } |
129 | |
130 | SpecialMailCollectionsRequestJob *requestJob = |
131 | qobject_cast<SpecialMailCollectionsRequestJob*>( job ); |
132 | if ( !requestJob ) { |
133 | return; |
134 | } |
135 | |
136 | // Create item. |
137 | Item item; |
138 | item.setMimeType( QLatin1String( "message/rfc822" ) ); |
139 | item.setPayload<Message::Ptr>( message ); |
140 | |
141 | // Set attributes. |
142 | item.addAttribute( addressAttribute.clone() ); |
143 | item.addAttribute( dispatchModeAttribute.clone() ); |
144 | item.addAttribute( sentBehaviourAttribute.clone() ); |
145 | item.addAttribute( sentActionAttribute.clone() ); |
146 | item.addAttribute( transportAttribute.clone() ); |
147 | |
148 | // Update status flags |
149 | if ( KMime::isSigned( message.get() ) ) { |
150 | item.setFlag( Akonadi::MessageFlags::Signed ); |
151 | } |
152 | |
153 | if ( KMime::isEncrypted( message.get() ) ) { |
154 | item.setFlag( Akonadi::MessageFlags::Encrypted ); |
155 | } |
156 | |
157 | if ( KMime::isInvitation( message.get() ) ) { |
158 | item.setFlag( Akonadi::MessageFlags::HasInvitation ); |
159 | } |
160 | |
161 | if ( KMime::hasAttachment( message.get() ) ) { |
162 | item.setFlag( Akonadi::MessageFlags::HasAttachment ); |
163 | } |
164 | |
165 | // Set flags. |
166 | item.setFlag( Akonadi::MessageFlags::Queued ); |
167 | |
168 | // Store the item in the outbox. |
169 | const Collection collection = requestJob->collection(); |
170 | Q_ASSERT( collection.isValid() ); |
171 | ItemCreateJob *cjob = new ItemCreateJob( item, collection ); // job autostarts |
172 | q->addSubjob( cjob ); |
173 | } |
174 | |
175 | MessageQueueJob::MessageQueueJob( QObject *parent ) |
176 | : KCompositeJob( parent ), d( new Private( this ) ) |
177 | { |
178 | } |
179 | |
180 | MessageQueueJob::~MessageQueueJob() |
181 | { |
182 | delete d; |
183 | } |
184 | |
185 | Message::Ptr MessageQueueJob::message() const |
186 | { |
187 | return d->message; |
188 | } |
189 | |
190 | DispatchModeAttribute &MessageQueueJob::dispatchModeAttribute() |
191 | { |
192 | return d->dispatchModeAttribute; |
193 | } |
194 | |
195 | AddressAttribute &MessageQueueJob::addressAttribute() |
196 | { |
197 | return d->addressAttribute; |
198 | } |
199 | |
200 | TransportAttribute &MessageQueueJob::transportAttribute() |
201 | { |
202 | return d->transportAttribute; |
203 | } |
204 | |
205 | SentBehaviourAttribute &MessageQueueJob::sentBehaviourAttribute() |
206 | { |
207 | return d->sentBehaviourAttribute; |
208 | } |
209 | |
210 | SentActionAttribute &MessageQueueJob::sentActionAttribute() |
211 | { |
212 | return d->sentActionAttribute; |
213 | } |
214 | |
215 | void MessageQueueJob::setMessage( Message::Ptr message ) |
216 | { |
217 | d->message = message; |
218 | } |
219 | |
220 | void MessageQueueJob::start() |
221 | { |
222 | SpecialMailCollectionsRequestJob *rjob = new SpecialMailCollectionsRequestJob( this ); |
223 | rjob->requestDefaultCollection( SpecialMailCollections::Outbox ); |
224 | connect( rjob, SIGNAL(result(KJob*)), this, SLOT(outboxRequestResult(KJob*)) ); |
225 | rjob->start(); |
226 | } |
227 | |
228 | void MessageQueueJob::slotResult( KJob *job ) |
229 | { |
230 | // error handling |
231 | KCompositeJob::slotResult( job ); |
232 | |
233 | if ( !error() ) { |
234 | emitResult(); |
235 | } |
236 | } |
237 | |
238 | #include "moc_messagequeuejob.cpp" |
239 | |