KIMAP

storejob.cpp
1 /*
2  SPDX-FileCopyrightText: 2009 Kevin Ottens <[email protected]>
3 
4  SPDX-License-Identifier: LGPL-2.0-or-later
5 */
6 
7 #include "storejob.h"
8 
9 #include "kimap_debug.h"
10 #include <KLocalizedString>
11 
12 #include "job_p.h"
13 #include "response_p.h"
14 #include "session_p.h"
15 
16 namespace KIMAP
17 {
18 class StoreJobPrivate : public JobPrivate
19 {
20 public:
21  StoreJobPrivate(Session *session, const QString &name)
22  : JobPrivate(session, name)
23  , uidBased(false)
24  {
25  }
26  ~StoreJobPrivate()
27  {
28  }
29 
30  QByteArray addFlags(const QByteArray &param, const MessageFlags &flags)
31  {
32  QByteArray parameters;
33  switch (mode) {
34  case StoreJob::SetFlags:
35  parameters += param;
36  break;
37  case StoreJob::AppendFlags:
38  parameters += "+" + param;
39  break;
40  case StoreJob::RemoveFlags:
41  parameters += "-" + param;
42  break;
43  }
44 
45  parameters += " (";
46  for (const QByteArray &flag : flags) {
47  parameters += flag + ' ';
48  }
49  if (!flags.isEmpty()) {
50  parameters.chop(1);
51  }
52  parameters += ')';
53 
54  return parameters;
55  }
56 
57  ImapSet set;
58  bool uidBased;
59  StoreJob::StoreMode mode;
60  MessageFlags flags;
61  MessageFlags gmLabels;
62 
63  QMap<int, MessageFlags> resultingFlags;
64 };
65 }
66 
67 using namespace KIMAP;
68 
69 StoreJob::StoreJob(Session *session)
70  : Job(*new StoreJobPrivate(session, i18n("Store")))
71 {
72  Q_D(StoreJob);
73  d->uidBased = false;
74  d->mode = SetFlags;
75 }
76 
77 StoreJob::~StoreJob()
78 {
79 }
80 
81 void StoreJob::setSequenceSet(const ImapSet &set)
82 {
83  Q_D(StoreJob);
84  d->set = set;
85 }
86 
87 ImapSet StoreJob::sequenceSet() const
88 {
89  Q_D(const StoreJob);
90  return d->set;
91 }
92 
93 void StoreJob::setUidBased(bool uidBased)
94 {
95  Q_D(StoreJob);
96  d->uidBased = uidBased;
97 }
98 
99 bool StoreJob::isUidBased() const
100 {
101  Q_D(const StoreJob);
102  return d->uidBased;
103 }
104 
105 void StoreJob::setFlags(const MessageFlags &flags)
106 {
107  Q_D(StoreJob);
108  d->flags = flags;
109 }
110 
111 MessageFlags StoreJob::flags() const
112 {
113  Q_D(const StoreJob);
114  return d->flags;
115 }
116 
117 void StoreJob::setGMLabels(const MessageFlags &gmLabels)
118 {
119  Q_D(StoreJob);
120  d->gmLabels = gmLabels;
121 }
122 
123 MessageFlags StoreJob::gmLabels() const
124 {
125  Q_D(const StoreJob);
126  return d->gmLabels;
127 }
128 
129 void StoreJob::setMode(StoreMode mode)
130 {
131  Q_D(StoreJob);
132  d->mode = mode;
133 }
134 
135 StoreJob::StoreMode StoreJob::mode() const
136 {
137  Q_D(const StoreJob);
138  return d->mode;
139 }
140 
141 QMap<int, MessageFlags> StoreJob::resultingFlags() const
142 {
143  Q_D(const StoreJob);
144  return d->resultingFlags;
145 }
146 
147 void StoreJob::doStart()
148 {
149  Q_D(StoreJob);
150 
151  if (d->set.isEmpty()) {
152  qCWarning(KIMAP_LOG) << "Empty uid set passed to store job";
153  setError(KJob::UserDefinedError);
154  setErrorText(QStringLiteral("Empty uid set passed to store job"));
155  emitResult();
156  return;
157  }
158 
159  d->set.optimize();
160  QByteArray parameters = d->set.toImapSequenceSet() + ' ';
161 
162  if (!d->flags.isEmpty()) {
163  parameters += d->addFlags("FLAGS", d->flags);
164  }
165  if (!d->gmLabels.isEmpty()) {
166  if (!d->flags.isEmpty()) {
167  parameters += ' ';
168  }
169  parameters += d->addFlags("X-GM-LABELS", d->gmLabels);
170  }
171 
172  qCDebug(KIMAP_LOG) << parameters;
173 
174  QByteArray command = "STORE";
175  if (d->uidBased) {
176  command = "UID " + command;
177  }
178 
179  d->tags << d->sessionInternal()->sendCommand(command, parameters);
180 }
181 
182 void StoreJob::handleResponse(const Response &response)
183 {
184  Q_D(StoreJob);
185 
186  if (handleErrorReplies(response) == NotHandled) {
187  if (response.content.size() == 4 && response.content[2].toString() == "FETCH" && response.content[3].type() == Response::Part::List) {
188  int id = response.content[1].toString().toInt();
189  qint64 uid = 0;
190  bool uidFound = false;
191  QList<QByteArray> resultingFlags;
192 
193  QList<QByteArray> content = response.content[3].toList();
194 
195  for (QList<QByteArray>::ConstIterator it = content.constBegin(); it != content.constEnd(); ++it) {
196  QByteArray str = *it;
197  ++it;
198 
199  if (str == "FLAGS") {
200  if ((*it).startsWith('(') && (*it).endsWith(')')) {
201  QByteArray str = *it;
202  str.chop(1);
203  str.remove(0, 1);
204  resultingFlags = str.split(' ');
205  } else {
206  resultingFlags << *it;
207  }
208  } else if (str == "UID") {
209  uid = it->toLongLong(&uidFound);
210  }
211  }
212 
213  if (!d->uidBased) {
214  d->resultingFlags[id] = resultingFlags;
215  } else if (uidFound) {
216  d->resultingFlags[uid] = resultingFlags;
217  } else {
218  qCWarning(KIMAP_LOG) << "We asked for UID but the server didn't give it back, resultingFlags not stored.";
219  }
220  }
221  }
222 }
223 
224 #include "moc_storejob.cpp"
QList< QByteArray > split(char sep) const const
QList::const_iterator constBegin() const const
QByteArray & remove(int pos, int len)
void chop(int n)
QString i18n(const char *text, const TYPE &arg...)
Represents a set of natural numbers (1->∞) in a as compact as possible form.
Definition: imapset.h:126
QList::const_iterator constEnd() const const
const char * name(StandardAction id)
Q_D(Todo)
This file is part of the KDE documentation.
Documentation copyright © 1996-2023 The KDE developers.
Generated on Sun Dec 3 2023 03:51:44 by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.