KIMAP2

storejob.cpp
1 /*
2  Copyright (c) 2009 Kevin Ottens <[email protected]>
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 "kimap_debug.h"
23 
24 #include "job_p.h"
25 #include "message_p.h"
26 #include "session_p.h"
27 
28 namespace KIMAP2
29 {
30 class StoreJobPrivate : public JobPrivate
31 {
32 public:
33  StoreJobPrivate(Session *session, const QString &name) : JobPrivate(session, name) { }
34  ~StoreJobPrivate() { }
35 
36  QByteArray addFlags(const QByteArray &param, const MessageFlags &flags)
37  {
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 KIMAP2;
74 
75 StoreJob::StoreJob(Session *session)
76  : Job(*new StoreJobPrivate(session, "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  qCWarning(KIMAP2_LOG) << "Empty uid set passed to store job";
159  setError(KJob::UserDefinedError);
160  setErrorText(QStringLiteral("Empty uid set passed to store job"));
161  emitResult();
162  return;
163  }
164 
165  d->set.optimize();
166  QByteArray parameters = d->set.toImapSequenceSet() + ' ';
167 
168  if (!d->flags.isEmpty() || d->mode == SetFlags) {
169  parameters += d->addFlags("FLAGS", d->flags);
170  }
171  if (!d->gmLabels.isEmpty()) {
172  if (!d->flags.isEmpty()) {
173  parameters += ' ';
174  }
175  parameters += d->addFlags("X-GM-LABELS", d->gmLabels);
176  }
177 
178  qCDebug(KIMAP2_LOG) << parameters;
179 
180  QByteArray command = "STORE";
181  if (d->uidBased) {
182  command = "UID " + command;
183  }
184 
185  d->sendCommand(command, parameters);
186 }
187 
188 void StoreJob::handleResponse(const Message &response)
189 {
190  Q_D(StoreJob);
191 
192  if (handleErrorReplies(response) == NotHandled) {
193  if (response.content.size() == 4 &&
194  response.content[2].toString() == "FETCH" &&
195  response.content[3].type() == Message::Part::List) {
196 
197  int id = response.content[1].toString().toInt();
198  qint64 uid = 0;
199  bool uidFound = false;
200  QList<QByteArray> resultingFlags;
201 
202  QList<QByteArray> content = response.content[3].toList();
203 
204  for (QList<QByteArray>::ConstIterator it = content.constBegin();
205  it != content.constEnd(); ++it) {
206  QByteArray str = *it;
207  ++it;
208 
209  if (str == "FLAGS") {
210  if ((*it).startsWith('(') && (*it).endsWith(')')) {
211  QByteArray str = *it;
212  str.chop(1);
213  str.remove(0, 1);
214  resultingFlags = str.split(' ');
215  } else {
216  resultingFlags << *it;
217  }
218  } else if (str == "UID") {
219  uid = it->toLongLong(&uidFound);
220  }
221  }
222 
223  if (!d->uidBased) {
224  d->resultingFlags[id] = resultingFlags;
225  } else if (uidFound) {
226  d->resultingFlags[uid] = resultingFlags;
227  } else {
228  qCWarning(KIMAP2_LOG) << "We asked for UID but the server didn't give it back, resultingFlags not stored.";
229  }
230  }
231  }
232 }
QList< QByteArray > split(char sep) const const
QList::const_iterator constBegin() const const
QByteArray & remove(int pos, int len)
void chop(int n)
Represents a set of natural numbers (1->∞) in a as compact as possible form.
Definition: imapset.h:141
bool isEmpty() const const
QList::const_iterator constEnd() const const
QString name(StandardShortcut id)
Q_D(Todo)
This file is part of the KDE documentation.
Documentation copyright © 1996-2023 The KDE developers.
Generated on Mon Feb 6 2023 04:10:17 by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.