KIMAP

setmetadatajob.cpp
1 /*
2  SPDX-FileCopyrightText: 2009 Andras Mantia <[email protected]>
3 
4  SPDX-License-Identifier: LGPL-2.0-or-later
5 */
6 
7 #include "setmetadatajob.h"
8 
9 #include <KLocalizedString>
10 #include "kimap_debug.h"
11 
12 #include "metadatajobbase_p.h"
13 #include "response_p.h"
14 #include "session_p.h"
15 #include "rfccodecs.h"
16 
17 namespace KIMAP
18 {
19 class SetMetaDataJobPrivate : public MetaDataJobBasePrivate
20 {
21 public:
22  SetMetaDataJobPrivate(Session *session, const QString &name) : MetaDataJobBasePrivate(session, name), metaDataErrors({}), maxAcceptedSize(-1) { }
23  ~SetMetaDataJobPrivate() { }
24 
27  QByteArray entryName;
28  SetMetaDataJob::MetaDataErrors metaDataErrors;
29  qint64 maxAcceptedSize;
30 };
31 }
32 
33 using namespace KIMAP;
34 
35 SetMetaDataJob::SetMetaDataJob(Session *session)
36  : MetaDataJobBase(*new SetMetaDataJobPrivate(session, i18n("SetMetaData")))
37 {
38 }
39 
40 SetMetaDataJob::~SetMetaDataJob()
41 {
42 }
43 
44 void SetMetaDataJob::doStart()
45 {
46  Q_D(SetMetaDataJob);
47  QByteArray parameters = '\"' + KIMAP::encodeImapFolderName(d->mailBox.toUtf8()) + "\" ";
48  d->entriesIt = d->entries.constBegin();
49 
50  QByteArray command = "SETMETADATA";
51  bool bSimpleData = true;
52 
53  if (d->serverCapability == Annotatemore) {
54  command = "SETANNOTATION";
55  parameters += '\"' + d->entryName + "\" ";
56  } else {
57  for (; d->entriesIt != d->entries.constEnd(); ++d->entriesIt) {
58  if (d->entriesIt.value().contains('\r') || d->entriesIt.value().contains('\n')) {
59  bSimpleData = false;
60  break;
61  }
62  }
63  d->entriesIt = d->entries.constBegin();
64  }
65 
66  parameters += '(';
67  if (bSimpleData == true) {
68  for ( ; d->entriesIt != d->entries.constEnd(); ++d->entriesIt ) {
69  parameters += '\"' + d->entriesIt.key() + "\" ";
70  if (d->entriesIt.value().isEmpty()) {
71  parameters += "NIL";
72  } else {
73  parameters += "\"" + d->entriesIt.value() + "\"";
74  }
75  parameters += " ";
76 
77  }
78  parameters[parameters.length() - 1] = ')';
79  } else {
80  if (!d->entries.isEmpty()) {
81  parameters += '\"' + d->entriesIt.key() + "\"";
82  int size = d->entriesIt.value().size();
83  parameters += " {" + QByteArray::number( size==0 ? 3 : size ) + '}';
84  }
85  }
86 
87  if (d->entries.isEmpty()) {
88  parameters += ')';
89  }
90 
91  d->tags << d->sessionInternal()->sendCommand(command, parameters);
92 // qCDebug(KIMAP_LOG) << "SENT: " << command << " " << parameters;
93 }
94 
95 void SetMetaDataJob::handleResponse(const Response &response)
96 {
97  Q_D(SetMetaDataJob);
98 
99  //TODO: Test if a server can really return more then one untagged NO response. If not, no need to OR the error codes
100  if (!response.content.isEmpty() &&
101  d->tags.contains(response.content.first().toString())) {
102  if (response.content[1].toString() == "NO") {
103  setError(UserDefinedError);
104  setErrorText(i18n("%1 failed, server replied: %2", d->m_name, QLatin1String(response.toString().constData())));
105  const QByteArray responseBa = response.content[2].toString();
106  if (responseBa == "[ANNOTATEMORE TOOMANY]" ||
107  responseBa == "[METADATA TOOMANY]") {
108  d->metaDataErrors |= TooMany;
109  } else if (responseBa == "[ANNOTATEMORE TOOBIG]" ||
110  responseBa.startsWith("[METADATA MAXSIZE")) { //krazy:exclude=strings
111  d->metaDataErrors |= TooBig;
112  d->maxAcceptedSize = -1;
113  if (responseBa.startsWith("[METADATA MAXSIZE")) { //krazy:exclude=strings
114  QByteArray max = responseBa;
115  max.replace("[METADATA MAXSIZE", ""); //krazy:exclude=doublequote_chars
116  max.replace("]", ""); //krazy:exclude=doublequote_chars
117  d->maxAcceptedSize = max.toLongLong();
118  }
119  } else if (responseBa == "[METADATA NOPRIVATE]") {
120  d->metaDataErrors |= NoPrivate;
121  }
122  } else if (response.content.size() < 2) {
123  setErrorText(i18n("%1 failed, malformed reply from the server.", d->m_name));
124  } else if (response.content[1].toString() != "OK") {
125  setError(UserDefinedError);
126  setErrorText(i18n("%1 failed, server replied: %2", d->m_name, QLatin1String(response.toString().constData())));
127  }
128  emitResult();
129  } else if (d->serverCapability == Metadata && response.content[0].toString() == "+") {
130  QByteArray content = "";
131  if (d->entriesIt.value().isEmpty()) {
132  content += "NIL";
133  } else {
134  content += d->entriesIt.value();
135  }
136  ++d->entriesIt;
137  if (d->entriesIt == d->entries.constEnd()) {
138  content += ')';
139  } else {
140  content += " \"" + d->entriesIt.key() + '\"';
141  int size = d->entriesIt.value().size();
142  content += " {" + QByteArray::number( size==0 ? 3 : size ) + '}';
143  }
144 // qCDebug(KIMAP_LOG) << "SENT: " << content;
145  d->sessionInternal()->sendData(content);
146  }
147 }
148 
149 void SetMetaDataJob::addMetaData(const QByteArray &name, const QByteArray &value)
150 {
151  Q_D(SetMetaDataJob);
152  if (d->serverCapability == Annotatemore && (name.startsWith("/shared") || name.startsWith("/private"))) {
153  const QByteArray &attribute = d->getAttribute(name);
154  d->entries[attribute] = value;
155  d->entryName = d->removePrefix(name);
156  } else {
157  d->entries[name] = value;
158  }
159 }
160 
162 {
163  Q_D(SetMetaDataJob);
164  d->entryName = entry;
165 }
166 
168 {
169  Q_D(const SetMetaDataJob);
170  return d->metaDataErrors;
171 }
QString::const_iterator constBegin() const const
This file is part of the IMAP support library and defines the RfcCodecs class.
void emitResult()
MetaDataErrors metaDataErrors() const
The metadata errors received from the server.
void setError(int errorCode)
bool startsWith(const QByteArray &ba) const const
KIMAP_EXPORT QString encodeImapFolderName(const QString &src)
Converts an Unicode IMAP mailbox to a QString which can be used in IMAP communication.
Definition: rfccodecs.cpp:178
void addMetaData(const QByteArray &name, const QByteArray &value)
Adds a metadata entry or attribute to the list of modifications to make.
int length() const const
void setErrorText(const QString &errorText)
QByteArray number(int n, int base)
QByteArray & replace(int pos, int len, const char *after)
qlonglong toLongLong(bool *ok, int base) const const
QString i18n(const char *text, const TYPE &arg...)
KIMAP_DEPRECATED void setEntry(const QByteArray &entry)
Sets the metadata entry name to operate on (in Annotatemore mode)
Base class for jobs that operate on mailbox metadata.
Sets mailbox metadata.
QByteArray::const_iterator constBegin() const const
Definition: acl.cpp:12
int size() const const
This file is part of the KDE documentation.
Documentation copyright © 1996-2020 The KDE developers.
Generated on Sat Oct 24 2020 23:16:51 by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.