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 | #include "storejob.h" |
21 | |
22 | #include <KDE/KDebug> |
23 | #include <KDE/KLocalizedString> |
24 | |
25 | #include "job_p.h" |
26 | #include "message_p.h" |
27 | #include "session_p.h" |
28 | |
29 | namespace KIMAP |
30 | { |
31 | class StoreJobPrivate : public JobPrivate |
32 | { |
33 | public: |
34 | StoreJobPrivate( Session *session, const QString& name ) : JobPrivate( session, name ) { } |
35 | ~StoreJobPrivate() { } |
36 | |
37 | QByteArray addFlags(const QByteArray ¶m, const MessageFlags &flags) { |
38 | QByteArray parameters; |
39 | switch ( mode ) { |
40 | case StoreJob::SetFlags: |
41 | parameters += param; |
42 | break; |
43 | case StoreJob::AppendFlags: |
44 | parameters += "+" + param; |
45 | break; |
46 | case StoreJob::RemoveFlags: |
47 | parameters += "-" + param; |
48 | break; |
49 | } |
50 | |
51 | parameters += " (" ; |
52 | foreach ( const QByteArray &flag, flags ) { |
53 | parameters += flag + ' '; |
54 | } |
55 | if ( !flags.isEmpty() ) { |
56 | parameters.chop( 1 ); |
57 | } |
58 | parameters += ')'; |
59 | |
60 | return parameters; |
61 | } |
62 | |
63 | ImapSet set; |
64 | bool uidBased; |
65 | StoreJob::StoreMode mode; |
66 | MessageFlags flags; |
67 | MessageFlags gmLabels; |
68 | |
69 | QMap<int, MessageFlags> resultingFlags; |
70 | }; |
71 | } |
72 | |
73 | using namespace KIMAP; |
74 | |
75 | StoreJob::StoreJob( Session *session ) |
76 | : Job( *new StoreJobPrivate( session, i18n( "Store" ) ) ) |
77 | { |
78 | Q_D( StoreJob ); |
79 | d->uidBased = false; |
80 | d->mode = SetFlags; |
81 | } |
82 | |
83 | StoreJob::~StoreJob() |
84 | { |
85 | } |
86 | |
87 | void StoreJob::setSequenceSet( const ImapSet &set ) |
88 | { |
89 | Q_D( StoreJob ); |
90 | d->set = set; |
91 | } |
92 | |
93 | ImapSet StoreJob::sequenceSet() const |
94 | { |
95 | Q_D( const StoreJob ); |
96 | return d->set; |
97 | } |
98 | |
99 | void StoreJob::setUidBased(bool uidBased) |
100 | { |
101 | Q_D( StoreJob ); |
102 | d->uidBased = uidBased; |
103 | } |
104 | |
105 | bool StoreJob::isUidBased() const |
106 | { |
107 | Q_D( const StoreJob ); |
108 | return d->uidBased; |
109 | } |
110 | |
111 | void StoreJob::setFlags( const MessageFlags &flags ) |
112 | { |
113 | Q_D( StoreJob ); |
114 | d->flags = flags; |
115 | } |
116 | |
117 | MessageFlags StoreJob::flags() const |
118 | { |
119 | Q_D( const StoreJob ); |
120 | return d->flags; |
121 | } |
122 | |
123 | void StoreJob::setGMLabels( const MessageFlags &gmLabels ) |
124 | { |
125 | Q_D( StoreJob ); |
126 | d->gmLabels = gmLabels; |
127 | } |
128 | |
129 | MessageFlags StoreJob::gmLabels() const |
130 | { |
131 | Q_D( const StoreJob ); |
132 | return d->gmLabels; |
133 | } |
134 | |
135 | void StoreJob::setMode( StoreMode mode ) |
136 | { |
137 | Q_D( StoreJob ); |
138 | d->mode = mode; |
139 | } |
140 | |
141 | StoreJob::StoreMode StoreJob::mode() const |
142 | { |
143 | Q_D( const StoreJob ); |
144 | return d->mode; |
145 | } |
146 | |
147 | QMap<int, MessageFlags> StoreJob::resultingFlags() const |
148 | { |
149 | Q_D( const StoreJob ); |
150 | return d->resultingFlags; |
151 | } |
152 | |
153 | void StoreJob::doStart() |
154 | { |
155 | Q_D( StoreJob ); |
156 | |
157 | if ( d->set.isEmpty() ) { |
158 | kWarning() << "Empty uid set passed to store job" ; |
159 | setError( KJob::UserDefinedError ); |
160 | setErrorText( QLatin1String("Empty uid set passed to store job" ) ); |
161 | emitResult(); |
162 | return; |
163 | } |
164 | |
165 | QByteArray parameters = d->set.toImapSequenceSet()+' '; |
166 | |
167 | if (!d->flags.isEmpty()) { |
168 | parameters += d->addFlags("FLAGS" , d->flags); |
169 | } |
170 | if (!d->gmLabels.isEmpty()) { |
171 | if (!d->flags.isEmpty()) { |
172 | parameters += ' '; |
173 | } |
174 | parameters += d->addFlags("X-GM-LABELS" , d->gmLabels); |
175 | } |
176 | |
177 | kDebug() << parameters; |
178 | |
179 | QByteArray command = "STORE" ; |
180 | if ( d->uidBased ) { |
181 | command = "UID " + command; |
182 | } |
183 | |
184 | d->tags << d->sessionInternal()->sendCommand( command, parameters ); |
185 | } |
186 | |
187 | void StoreJob::handleResponse( const Message &response ) |
188 | { |
189 | Q_D( StoreJob ); |
190 | |
191 | if ( handleErrorReplies( response ) == NotHandled ) { |
192 | if ( response.content.size() == 4 && |
193 | response.content[2].toString() == "FETCH" && |
194 | response.content[3].type() == Message::Part::List ) { |
195 | |
196 | int id = response.content[1].toString().toInt(); |
197 | qint64 uid = 0; |
198 | bool uidFound = false; |
199 | QList<QByteArray> resultingFlags; |
200 | |
201 | QList<QByteArray> content = response.content[3].toList(); |
202 | |
203 | for ( QList<QByteArray>::ConstIterator it = content.constBegin(); |
204 | it != content.constEnd(); ++it ) { |
205 | QByteArray str = *it; |
206 | ++it; |
207 | |
208 | if ( str == "FLAGS" ) { |
209 | if ( ( *it ).startsWith( '(' ) && ( *it ).endsWith( ')' ) ) { |
210 | QByteArray str = *it; |
211 | str.chop( 1 ); |
212 | str.remove( 0, 1 ); |
213 | resultingFlags = str.split( ' ' ); |
214 | } else { |
215 | resultingFlags << *it; |
216 | } |
217 | } else if ( str == "UID" ) { |
218 | uid = it->toLongLong( &uidFound ); |
219 | } |
220 | } |
221 | |
222 | if ( !d->uidBased ) { |
223 | d->resultingFlags[id] = resultingFlags; |
224 | } else if ( uidFound ) { |
225 | d->resultingFlags[uid] = resultingFlags; |
226 | } else { |
227 | kWarning() << "We asked for UID but the server didn't give it back, resultingFlags not stored." ; |
228 | } |
229 | } |
230 | } |
231 | } |
232 | |