KIMAP2

setmetadatajob.cpp
1/*
2 Copyright (c) 2009 Andras Mantia <amantia@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 "setmetadatajob.h"
21
22#include "kimap_debug.h"
23
24#include "metadatajobbase_p.h"
25#include "message_p.h"
26#include "session_p.h"
27#include "rfccodecs.h"
28
29namespace KIMAP2
30{
31class SetMetaDataJobPrivate : public MetaDataJobBasePrivate
32{
33public:
34 SetMetaDataJobPrivate(Session *session, const QString &name) : MetaDataJobBasePrivate(session, name), metaDataErrors(Q_NULLPTR), maxAcceptedSize(-1) { }
35 ~SetMetaDataJobPrivate() { }
36
39 QByteArray entryName;
40 SetMetaDataJob::MetaDataErrors metaDataErrors;
41 qint64 maxAcceptedSize;
42};
43}
44
45using namespace KIMAP2;
46
47SetMetaDataJob::SetMetaDataJob(Session *session)
48 : MetaDataJobBase(*new SetMetaDataJobPrivate(session, "SetMetaData"))
49{
50}
51
52SetMetaDataJob::~SetMetaDataJob()
53{
54}
55
56void SetMetaDataJob::doStart()
57{
59 QByteArray parameters;
60 parameters = '\"' + KIMAP2::encodeImapFolderName(d->mailBox.toUtf8()) + "\" ";
61 d->entriesIt = d->entries.constBegin();
62
63 QByteArray command = "SETMETADATA";
64 bool bSimpleData = true;
65
66 if (d->serverCapability == Annotatemore) {
67 command = "SETANNOTATION";
68 parameters += '\"' + d->entryName + "\" ";
69 } else {
70 for (; d->entriesIt != d->entries.constEnd(); ++d->entriesIt) {
71 if (d->entriesIt.value().contains('\r') || d->entriesIt.value().contains('\n')) {
72 bSimpleData = false;
73 break;
74 }
75 }
76 d->entriesIt = d->entries.constBegin();
77 }
78
79 parameters += '(';
80 if (bSimpleData == true) {
81 for ( ; d->entriesIt != d->entries.constEnd(); ++d->entriesIt ) {
82 parameters += '\"' + d->entriesIt.key() + "\" ";
83 if (d->entriesIt.value().isEmpty()) {
84 parameters += "NIL";
85 } else {
86 parameters += "\"" + d->entriesIt.value() + "\"";
87 }
88 parameters += " ";
89
90 }
91 parameters[parameters.length() - 1] = ')';
92 } else {
93 if (!d->entries.isEmpty()) {
94 parameters += '\"' + d->entriesIt.key() + "\"";
95 int size = d->entriesIt.value().size();
96 parameters += " {" + QByteArray::number( size==0 ? 3 : size ) + '}';
97 }
98 }
99
100 if (d->entries.isEmpty()) {
101 parameters += ')';
102 }
103
104 d->sendCommand(command, parameters);
105// qCDebug(KIMAP2_LOG) << "SENT: " << command << " " << parameters;
106}
107
108void SetMetaDataJob::handleResponse(const Message &response)
109{
111
112 //TODO: Test if a server can really return more then one untagged NO response. If not, no need to OR the error codes
113 if (!response.content.isEmpty() &&
114 d->tags.contains(response.content.first().toString())) {
115 if (response.content[1].toString() == "NO") {
116 setError(UserDefinedError);
117 setErrorText(QString("%1 failed, server replied: %2").arg(d->m_name).arg(QLatin1String(response.toString().constData())));
118 if (response.content[2].toString() == "[ANNOTATEMORE TOOMANY]" ||
119 response.content[2].toString() == "[METADATA TOOMANY]") {
120 d->metaDataErrors |= TooMany;
121 } else if (response.content[2].toString() == "[ANNOTATEMORE TOOBIG]" ||
122 response.content[2].toString().startsWith("[METADATA MAXSIZE")) { //krazy:exclude=strings
123 d->metaDataErrors |= TooBig;
124 d->maxAcceptedSize = -1;
125 if (response.content[2].toString().startsWith("[METADATA MAXSIZE")) { //krazy:exclude=strings
126 QByteArray max = response.content[2].toString();
127 max.replace("[METADATA MAXSIZE", ""); //krazy:exclude=doublequote_chars
128 max.replace("]", ""); //krazy:exclude=doublequote_chars
129 d->maxAcceptedSize = max.toLongLong();
130 }
131 } else if (response.content[2].toString() == "[METADATA NOPRIVATE]") {
132 d->metaDataErrors |= NoPrivate;
133 }
134 } else if (response.content.size() < 2) {
135 setErrorText(QString("%1 failed, malformed reply from the server.").arg(d->m_name));
136 } else if (response.content[1].toString() != "OK") {
137 setError(UserDefinedError);
138 setErrorText(QString("%1 failed, server replied: %2").arg(d->m_name).arg(QLatin1String(response.toString().constData())));
139 }
140 emitResult();
141 } else if (d->serverCapability == Metadata && response.content[0].toString() == "+") {
142 QByteArray content = "";
143 if (d->entriesIt.value().isEmpty()) {
144 content += "NIL";
145 } else {
146 content += d->entriesIt.value();
147 }
148 ++d->entriesIt;
149 if (d->entriesIt == d->entries.constEnd()) {
150 content += ')';
151 } else {
152 content += " \"" + d->entriesIt.key() + '\"';
153 int size = d->entriesIt.value().size();
154 content += " {" + QByteArray::number( size==0 ? 3 : size ) + '}';
155 }
156// qCDebug(KIMAP2_LOG) << "SENT: " << content;
157 d->sessionInternal()->sendData(content);
158 }
159}
160
161void SetMetaDataJob::addMetaData(const QByteArray &name, const QByteArray &value)
162{
164 if (d->serverCapability == Annotatemore && (name.startsWith("/shared") || name.startsWith("/private"))) {
165 const QByteArray &attribute = d->getAttribute(name);
166 d->entries[attribute] = value;
167 d->entryName = d->removePrefix(name);
168 } else {
169 d->entries[name] = value;
170 }
171}
172
174{
176 d->entryName = entry;
177}
178
180{
181 Q_D(const SetMetaDataJob);
182 return d->metaDataErrors;
183}
Base class for jobs that operate on mailbox metadata.
@ Annotatemore
Used to indicate that the server supports the draft-daboo-imap-annotatemore-07 version of the extensi...
@ Metadata
Used to indicate that the server supports the RFC 5464 version of the extension.
Sets mailbox metadata.
@ TooMany
Cannot add a new metadata item, because the limit has already been reached.
@ NoPrivate
The server does not support private metadata entries.
@ TooBig
A metadata value was too big (see maxAcceptedSize())
MetaDataErrors metaDataErrors() const
The metadata errors received from the server.
void addMetaData(const QByteArray &name, const QByteArray &value)
Adds a metadata entry or attribute to the list of modifications to make.
KIMAP2_DEPRECATED void setEntry(const QByteArray &entry)
Sets the metadata entry name to operate on (in Annotatemore mode)
void setErrorText(const QString &errorText)
void emitResult()
void setError(int errorCode)
QString name(StandardShortcut id)
const_iterator constBegin() const const
qsizetype length() const const
QByteArray number(double n, char format, int precision)
QByteArray & replace(QByteArrayView before, QByteArrayView after)
qsizetype size() const const
qlonglong toLongLong(bool *ok, int base) const const
QString arg(Args &&... args) const const
bool startsWith(QChar c, Qt::CaseSensitivity cs) const const
This file is part of the IMAP support library and defines the RfcCodecs class.
KIMAP2_EXPORT QByteArray encodeImapFolderName(const QByteArray &src)
Converts an Unicode IMAP mailbox to a QByteArray which can be used in IMAP communication.
Q_D(Todo)
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Tue Mar 26 2024 11:21:18 by doxygen 1.10.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.