KIMAP2

setmetadatajob.cpp
1 /*
2  Copyright (c) 2009 Andras Mantia <[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 "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 
29 namespace KIMAP2
30 {
31 class SetMetaDataJobPrivate : public MetaDataJobBasePrivate
32 {
33 public:
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 
45 using namespace KIMAP2;
46 
47 SetMetaDataJob::SetMetaDataJob(Session *session)
48  : MetaDataJobBase(*new SetMetaDataJobPrivate(session, "SetMetaData"))
49 {
50 }
51 
52 SetMetaDataJob::~SetMetaDataJob()
53 {
54 }
55 
56 void 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 
108 void 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 
161 void 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 }
KIMAP2_EXPORT QString encodeImapFolderName(const QString &src)
Converts an Unicode IMAP mailbox to a QString which can be used in IMAP communication.
Definition: rfccodecs.cpp:192
void setErrorText(const QString &errorText)
@ TooMany
Cannot add a new metadata item, because the limit has already been reached.
@ NoPrivate
The server does not support private metadata entries.
Base class for jobs that operate on mailbox metadata.
QByteArray::const_iterator constBegin() const const
QByteArray number(int n, int base)
@ Annotatemore
Used to indicate that the server supports the draft-daboo-imap-annotatemore-07 version of the extensi...
@ TooBig
A metadata value was too big (see maxAcceptedSize())
qlonglong toLongLong(bool *ok, int base) const const
QString::const_iterator constBegin() const const
MetaDataErrors metaDataErrors() const
The metadata errors received from the server.
QByteArray & replace(int pos, int len, const char *after)
bool startsWith(const QString &s, Qt::CaseSensitivity cs) const const
@ Metadata
Used to indicate that the server supports the RFC 5464 version of the extension.
QString arg(qlonglong a, int fieldWidth, int base, QChar fillChar) const const
KIMAP2_DEPRECATED void setEntry(const QByteArray &entry)
Sets the metadata entry name to operate on (in Annotatemore mode)
QString name(StandardShortcut id)
int size() const const
void emitResult()
int length() const const
Provides handlers for various RFC/MIME encodings.
void setError(int errorCode)
Q_D(Todo)
Sets mailbox metadata.
void addMetaData(const QByteArray &name, const QByteArray &value)
Adds a metadata entry or attribute to the list of modifications to make.
This file is part of the KDE documentation.
Documentation copyright © 1996-2023 The KDE developers.
Generated on Tue Feb 7 2023 04:11:30 by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.