KIMAP

storejob.cpp
1/*
2 SPDX-FileCopyrightText: 2009 Kevin Ottens <ervin@kde.org>
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
16namespace KIMAP
17{
18class StoreJobPrivate : public JobPrivate
19{
20public:
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
67using namespace KIMAP;
68
69StoreJob::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
77StoreJob::~StoreJob()
78{
79}
80
81void StoreJob::setSequenceSet(const ImapSet &set)
82{
83 Q_D(StoreJob);
84 d->set = set;
85}
86
87ImapSet StoreJob::sequenceSet() const
88{
89 Q_D(const StoreJob);
90 return d->set;
91}
92
93void StoreJob::setUidBased(bool uidBased)
94{
95 Q_D(StoreJob);
96 d->uidBased = uidBased;
97}
98
99bool StoreJob::isUidBased() const
100{
101 Q_D(const StoreJob);
102 return d->uidBased;
103}
104
105void StoreJob::setFlags(const MessageFlags &flags)
106{
107 Q_D(StoreJob);
108 d->flags = flags;
109}
110
111MessageFlags StoreJob::flags() const
112{
113 Q_D(const StoreJob);
114 return d->flags;
115}
116
117void StoreJob::setGMLabels(const MessageFlags &gmLabels)
118{
119 Q_D(StoreJob);
120 d->gmLabels = gmLabels;
121}
122
123MessageFlags StoreJob::gmLabels() const
124{
125 Q_D(const StoreJob);
126 return d->gmLabels;
127}
128
129void StoreJob::setMode(StoreMode mode)
130{
131 Q_D(StoreJob);
132 d->mode = mode;
133}
134
135StoreJob::StoreMode StoreJob::mode() const
136{
137 Q_D(const StoreJob);
138 return d->mode;
139}
140
141QMap<int, MessageFlags> StoreJob::resultingFlags() const
142{
143 Q_D(const StoreJob);
144 return d->resultingFlags;
145}
146
147void 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
182void 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"
Represents a set of natural numbers (1->∞) in a as compact as possible form.
Definition imapset.h:127
void setErrorText(const QString &errorText)
void emitResult()
void setError(int errorCode)
QString i18n(const char *text, const TYPE &arg...)
QString name(StandardAction id)
void chop(qsizetype n)
QByteArray & remove(qsizetype pos, qsizetype len)
QList< QByteArray > split(char sep) const const
QList< T > toList() const const
const_iterator constBegin() const const
const_iterator constEnd() const const
bool isEmpty() const const
Q_D(Todo)
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Fri Jul 19 2024 11:56:18 by doxygen 1.11.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.