1 | /* |
2 | Copyright (c) 2009 Kevin Ottens <ervin@kde.org> |
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 | #ifndef KIMAP_FETCHJOB_H |
21 | #define KIMAP_FETCHJOB_H |
22 | |
23 | #include "kimap_export.h" |
24 | |
25 | #include "imapset.h" |
26 | #include "job.h" |
27 | |
28 | #include "kmime/kmime_content.h" |
29 | #include "kmime/kmime_message.h" |
30 | |
31 | #include <boost/shared_ptr.hpp> |
32 | |
33 | namespace KIMAP { |
34 | |
35 | class Session; |
36 | struct Message; |
37 | class FetchJobPrivate; |
38 | |
39 | typedef boost::shared_ptr<KMime::Content> ContentPtr; |
40 | typedef QMap<QByteArray, ContentPtr> MessageParts; |
41 | |
42 | typedef boost::shared_ptr<KMime::Message> MessagePtr; |
43 | typedef QList<QByteArray> MessageFlags; |
44 | |
45 | typedef QPair<QByteArray, QVariant> MessageAttribute; |
46 | |
47 | /** |
48 | * Fetch message data from the server |
49 | * |
50 | * All data is returned using the signals, so you need to connect to |
51 | * the relevant signal (or all of them) before starting the job. |
52 | * |
53 | * This job will always use BODY.PEEK rather than BODY to fetch message |
54 | * content, so it will not set the \Seen flag. |
55 | * |
56 | * This job can only be run when the session is in the selected state. |
57 | */ |
58 | class KIMAP_EXPORT FetchJob : public Job |
59 | { |
60 | Q_OBJECT |
61 | Q_DECLARE_PRIVATE( FetchJob ) |
62 | |
63 | friend class SessionPrivate; |
64 | |
65 | public: |
66 | /** |
67 | * Used to indicate what message data should be fetched. |
68 | * |
69 | * This doesn't provide the same fine-grained control over |
70 | * what is fetched that the IMAP FETCH command normally |
71 | * does, but the common cases are catered for. |
72 | */ |
73 | class KIMAP_EXPORT FetchScope |
74 | { |
75 | public: |
76 | FetchScope(); |
77 | |
78 | /** |
79 | * Used to indicate what part of the message should be fetched. |
80 | */ |
81 | enum Mode { |
82 | /** |
83 | * Fetch RFC-2822 or MIME message headers. |
84 | * |
85 | * To fetch MIME headers for a MIME part, populate the @p parts field. |
86 | * |
87 | * If the RFC-2822 headers are requested (so @p parts is empty), the |
88 | * returned information is: |
89 | * - To, From, Message-id, References In-Reply-To, Subject and Date headers |
90 | * - The message size (in octets) |
91 | * - The internal date of the message |
92 | * - The message flags |
93 | * - The message UID |
94 | */ |
95 | , |
96 | /** |
97 | * Fetch the message flags (the UID is also fetched) |
98 | */ |
99 | Flags, |
100 | /** |
101 | * Fetch the MIME message body structure (the UID is also fetched) |
102 | */ |
103 | Structure, |
104 | /** |
105 | * Fetch the message content (the UID is also fetched) |
106 | * |
107 | * To fetch only certain MIME parts (see Structure), populate the |
108 | * @p parts field. |
109 | */ |
110 | Content, |
111 | /** |
112 | * Fetch the complete message. |
113 | */ |
114 | Full, |
115 | /** |
116 | * Fetch the message MIME headers and the content of parts specified in the @p parts |
117 | * field. |
118 | * |
119 | * If @p parts is empty, this mode will return the full message, just like |
120 | * FetchScope::Content |
121 | * |
122 | * Use case: |
123 | * -# Start a FetchJob with the FetchScope::Structure mode to retrieve the structure |
124 | * of the message. |
125 | * -# Parse the structure to identify the parts that are interesting (ie: probably |
126 | * everything but attachments). |
127 | * -# Start another FetchJob with FetchScope::HeaderAndContent to fetch those parts. |
128 | * -# At the request of the user, you can repeat the step above to fetch the attachments. |
129 | * |
130 | * @since 4.7 |
131 | */ |
132 | HeaderAndContent, |
133 | |
134 | /** |
135 | * Fetch message size (in octets), internal date of the message, flags, UID |
136 | * and all RFC822 headers. |
137 | * |
138 | * The @p parts field is ignored when using this scope |
139 | * |
140 | * @since 4.12 |
141 | */ |
142 | |
143 | }; |
144 | |
145 | /** |
146 | * Specify which message parts to operate on. |
147 | * |
148 | * This refers to multipart-MIME message parts or MIME-IMB encapsulated |
149 | * message parts. |
150 | * |
151 | * Note that this is ignored unless @p mode is Headers or Content. |
152 | * |
153 | * If @p mode is Headers, this sets the parts to get the MIME headers |
154 | * for. If this list is empty, the headers for the whole message |
155 | * (the RFC-2822 headers) are fetched. |
156 | * |
157 | * If @p mode is Content, this sets the parts to fetch. Parts are |
158 | * fetched wholesale. If this list is empty, the whole message body |
159 | * is fetched (all MIME parts together). |
160 | */ |
161 | QList<QByteArray> parts; |
162 | /** |
163 | * Specify what message data should be fetched. |
164 | */ |
165 | Mode mode; |
166 | |
167 | /** |
168 | * Specify to fetch only items with mod-sequence higher then @p changedSince. |
169 | * |
170 | * The server must have CONDSTORE capability (RFC4551). |
171 | * |
172 | * Default value is 0 (ignored). |
173 | * |
174 | * @since 4.12 |
175 | */ |
176 | quint64 changedSince; |
177 | }; |
178 | |
179 | explicit FetchJob( Session *session ); |
180 | virtual ~FetchJob(); |
181 | |
182 | /** |
183 | * Set which messages to fetch data for. |
184 | * |
185 | * If sequence numbers are given, isUidBased() should be false. If UIDs |
186 | * are given, isUidBased() should be true. |
187 | * |
188 | * @param set the sequence numbers or UIDs of the messages to fetch data for |
189 | */ |
190 | void setSequenceSet( const ImapSet &set ); |
191 | /** |
192 | * The messages that will be fetched. |
193 | */ |
194 | ImapSet sequenceSet() const; |
195 | |
196 | /** |
197 | * Set how the sequence set should be interpreted. |
198 | * |
199 | * @param uidBased if @c true the argument to setSequenceSet will be |
200 | * interpreted as UIDs, if @c false it will be interpreted |
201 | * as sequence numbers |
202 | */ |
203 | void setUidBased(bool uidBased); |
204 | /** |
205 | * How to interpret the sequence set. |
206 | * |
207 | * @return if @c true the result of sequenceSet() should be |
208 | * interpreted as UIDs, if @c false it should be interpreted |
209 | * as sequence numbers |
210 | */ |
211 | bool isUidBased() const; |
212 | |
213 | /** |
214 | * Sets what data should be fetched. |
215 | * |
216 | * The default scope is FetchScope::Content (all content parts). |
217 | * |
218 | * @param scope a FetchScope object describing what data |
219 | * should be fetched |
220 | */ |
221 | void setScope( const FetchScope &scope ); |
222 | /** |
223 | * Specifies what data will be fetched. |
224 | */ |
225 | FetchScope scope() const; |
226 | |
227 | // TODO: KF5: Move this to FetchScope |
228 | /** |
229 | * Enables retrieving of Gmail-specific extensions |
230 | * |
231 | * The FETCH response will contain X-GM-MSGID, X-GM-THRID and X-GM-LABELS |
232 | * |
233 | * Do NOT enable this, unless talking to Gmail servers, otherwise the |
234 | * request may fail. |
235 | * |
236 | * @param enabled Whether the Gmail support should be enabled |
237 | * @since 4.14 |
238 | */ |
239 | void setGmailExtensionsEnabled(bool enabled); |
240 | |
241 | /** |
242 | * Returns whether Gmail support is enabled |
243 | * |
244 | * @since 4.14 |
245 | * @see setGmailExtensionsEnabled() |
246 | */ |
247 | bool setGmailExtensionsEnabled() const; |
248 | |
249 | // XXX: [alexmerry, 2010-07-24]: BIC? Behaviour change |
250 | /** @deprecated returns an empty map; use the signals instead */ |
251 | KIMAP_DEPRECATED QMap<qint64, MessagePtr> messages() const; |
252 | /** @deprecated returns an empty map; use the signals instead */ |
253 | KIMAP_DEPRECATED QMap<qint64, MessageParts> parts() const; |
254 | /** @deprecated returns an empty map; use the signals instead */ |
255 | KIMAP_DEPRECATED QMap<qint64, MessageFlags> flags() const; |
256 | /** @deprecated returns an empty map; use the signals instead */ |
257 | KIMAP_DEPRECATED QMap<qint64, qint64> sizes() const; |
258 | /** @deprecated returns an empty map; use the signals instead */ |
259 | KIMAP_DEPRECATED QMap<qint64, qint64> uids() const; |
260 | |
261 | Q_SIGNALS: |
262 | /** |
263 | * Provides header and message results. |
264 | * |
265 | * This signal will be emitted if the requested scope mode |
266 | * was FetchScope::Full, FetchScope::Flags or |
267 | * FetchScope::Headers with no parts specified |
268 | * |
269 | * This signal may be emitted any number of times before |
270 | * the result() signal is emitted. The result() signal will |
271 | * only be emitted once all results have been reported via |
272 | * one of the signals. |
273 | * |
274 | * Note that, depending on the scope, some of the parameters |
275 | * of this signal may be empty maps. |
276 | * |
277 | * @param mailBox the name of the mailbox the fetch job was |
278 | * executed on |
279 | * @param uids a map from message sequence numbers to message UIDs; |
280 | * this will always be populated |
281 | * @param sizes a map from message sequence numbers to message sizes |
282 | * (sizes are in octets and refer to the transfer encoding of |
283 | * the message); populated if the scope is FetchScope::Full or |
284 | * FetchScope::Headers |
285 | * @param flags a map from message sequence numbers to message flags; |
286 | * populated if the scope is FetchScope::Flags, FetchScope::Full |
287 | * of FetchScope::Headers |
288 | * @param messages a map from message sequence numbers to message contents (including |
289 | * headers); populated if the scope is FetchScope::Full, |
290 | * FetchScope::Headers or FetchScope::Structure |
291 | */ |
292 | void ( const QString &mailBox, |
293 | const QMap<qint64, qint64> &uids, |
294 | const QMap<qint64, qint64> &sizes, |
295 | const QMap<qint64, KIMAP::MessageFlags> &flags, |
296 | const QMap<qint64, KIMAP::MessagePtr> &messages ); |
297 | |
298 | /** |
299 | * An overloaded version of headersReceived(), which includes additional attribute |
300 | * specified in the FETCH response, but that don't belong to actual content of the |
301 | * message. |
302 | * |
303 | * @param mailBox the name of the mailbox the fetch job was |
304 | * executed on |
305 | * @param uids a map from message sequence numbers to message UIDs; |
306 | * this will always be populated |
307 | * @param attrs a map from message sequence numbers to a pair of attribute |
308 | * name and value |
309 | * @param sizes a map from message sequence numbers to message sizes |
310 | * (sizes are in octets and refer to the transfer encoding of |
311 | * the message); populated if the scope is FetchScope::Full or |
312 | * FetchScope::Headers |
313 | * @param flags a map from message sequence numbers to message flags; |
314 | * populated if the scope is FetchScope::Flags, FetchScope::Full |
315 | * of FetchScope::Headers |
316 | * @param messages a map from message sequence numbers to message contents (including |
317 | * headers); populated if the scope is FetchScope::Full, |
318 | * FetchScope::Headers or FetchScope::Structure |
319 | * |
320 | * @overload |
321 | * @since 4.14 |
322 | */ |
323 | void ( const QString &mailBox, |
324 | const QMap<qint64, qint64> &uids, |
325 | const QMap<qint64, qint64> &sizes, |
326 | const QMap<qint64, KIMAP::MessageAttribute > &attrs, |
327 | const QMap<qint64, KIMAP::MessageFlags> &flags, |
328 | const QMap<qint64, KIMAP::MessagePtr> &messages ); |
329 | |
330 | /** |
331 | * Provides header and message results. |
332 | * |
333 | * This signal will be emitted if the requested scope mode |
334 | * was FetchScope::Content or FetchScope::Headers with no |
335 | * parts specified or FetchScope::Structure. |
336 | * |
337 | * This signal may be emitted any number of times before |
338 | * the result() signal is emitted. The result() signal will |
339 | * only be emitted once all results have been reported via |
340 | * one of the signals. |
341 | * |
342 | * |
343 | * @param mailBox the name of the mailbox the fetch job was |
344 | * executed on |
345 | * @param uids a map from message sequence numbers to message UIDs |
346 | * @param messages a map from message sequence numbers to message contents |
347 | */ |
348 | void messagesReceived( const QString &mailBox, |
349 | const QMap<qint64, qint64> &uids, |
350 | const QMap<qint64, KIMAP::MessagePtr> &messages ); |
351 | |
352 | |
353 | /** |
354 | * An overloaded version of messagesReceived(), which includes additional attribute |
355 | * specified in the FETCH response, but that don't belong to actual content of the |
356 | * message. |
357 | * |
358 | * @param mailBox the name of the mailbox the fetch job was |
359 | * executed on |
360 | * @param uids a map from message sequence numbers to message UIDs |
361 | * @param attrs a map from message sequence numbers to pair of attribute |
362 | * name and it's value |
363 | * @param messages a map from message sequence numbers to message contents |
364 | * |
365 | * @overload |
366 | * @since 4.14 |
367 | */ |
368 | void messagesReceived( const QString &mailBox, |
369 | const QMap<qint64, qint64> &uids, |
370 | const QMap<qint64, KIMAP::MessageAttribute > &attrs, |
371 | const QMap<qint64, KIMAP::MessagePtr> &messages ); |
372 | /** |
373 | * Provides header and message results. |
374 | * |
375 | * This signal will be emitted if the requested scope mode |
376 | * was FetchScope::Content or FetchScope::Headers with |
377 | * specified parts. |
378 | * |
379 | * This signal may be emitted any number of times before |
380 | * the result() signal is emitted. The result() signal will |
381 | * only be emitted once all results have been reported via |
382 | * one of the signals. |
383 | * |
384 | * @param mailBox the name of the mailbox the fetch job was |
385 | * executed on |
386 | * @param uids a map from message sequence numbers to message UIDs |
387 | * @param parts a map from message sequence numbers to message part collections |
388 | */ |
389 | void partsReceived( const QString &mailBox, |
390 | const QMap<qint64, qint64> &uids, |
391 | const QMap<qint64, KIMAP::MessageParts> &parts ); |
392 | |
393 | /** |
394 | * An overloaded version of partsReceived(), which includes additional attribute |
395 | * specified in the FETCH response, but that don't belong to actual content of the |
396 | * message. |
397 | * |
398 | * @param mailBox the name of the mailbox the fetch job was |
399 | * executed on |
400 | * @param uids a map from message sequence numbers to message UIDs |
401 | * @param attrs a map from message sequence numbers to pair of attribute |
402 | * @param parts a map from message sequence numbers to message part collections |
403 | * |
404 | * @overload |
405 | * @since 4.14 |
406 | */ |
407 | void partsReceived( const QString &mailBox, |
408 | const QMap<qint64, qint64> &uids, |
409 | const QMap<qint64, KIMAP::MessageAttribute > &attrs, |
410 | const QMap<qint64, KIMAP::MessageParts> &parts ); |
411 | |
412 | protected: |
413 | virtual void doStart(); |
414 | virtual void handleResponse(const Message &response); |
415 | |
416 | private: |
417 | Q_PRIVATE_SLOT( d_func(), void emitPendings() ) |
418 | }; |
419 | |
420 | } |
421 | |
422 | #endif |
423 | |