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 {
58  Q_D(SetMetaDataJob);
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 {
110  Q_D(SetMetaDataJob);
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 {
163  Q_D(SetMetaDataJob);
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 {
175  Q_D(SetMetaDataJob);
176  d->entryName = entry;
177 }
178 
180 {
181  Q_D(const SetMetaDataJob);
182  return d->metaDataErrors;
183 }
QString::const_iterator constBegin() const const
MetaDataErrors metaDataErrors() const
The metadata errors received from the server.
This file is part of the IMAP support library and defines the RfcCodecs class.
void emitResult()
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 setError(int errorCode)
bool startsWith(const QByteArray &ba) const const
int length() const const
void setErrorText(const QString &errorText)
QByteArray number(int n, int base)
QByteArray & replace(int pos, int len, const char *after)
Sets mailbox metadata.
Definition: acl.cpp:25
Base class for jobs that operate on mailbox metadata.
qlonglong toLongLong(bool *ok, int base) const const
KIMAP2_DEPRECATED void setEntry(const QByteArray &entry)
Sets the metadata entry name to operate on (in Annotatemore mode)
QString arg(qlonglong a, int fieldWidth, int base, QChar fillChar) const const
void addMetaData(const QByteArray &name, const QByteArray &value)
Adds a metadata entry or attribute to the list of modifications to make.
QByteArray::const_iterator constBegin() const const
int size() const const
This file is part of the KDE documentation.
Documentation copyright © 1996-2021 The KDE developers.
Generated on Mon Nov 29 2021 23:00:39 by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.