KIMAP2

getmetadatajob.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 "getmetadatajob.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 GetMetaDataJobPrivate : public MetaDataJobBasePrivate
32{
33public:
34 GetMetaDataJobPrivate(Session *session, const QString &name) : MetaDataJobBasePrivate(session, name), maxSize(-1), depth("0") { }
35 ~GetMetaDataJobPrivate() { }
36
37 qint64 maxSize;
38 QByteArray depth;
39 QSet<QByteArray> entries;
40 QSet<QByteArray> attributes;
42 // ^ mailbox ^ entry ^attribute ^ value
43};
44}
45
46using namespace KIMAP2;
47
48GetMetaDataJob::GetMetaDataJob(Session *session)
49 : MetaDataJobBase(*new GetMetaDataJobPrivate(session, "GetMetaData"))
50{
51}
52
53GetMetaDataJob::~GetMetaDataJob()
54{
55}
56
57static QList<QByteArray> sort(const QSet<QByteArray> &set)
58{
59 QList<QByteArray> sortedEntries = set.toList();
60 qSort(sortedEntries);
61 return sortedEntries;
62}
63
64void GetMetaDataJob::doStart()
65{
67 QByteArray parameters;
68 parameters = '\"' + KIMAP2::encodeImapFolderName(d->mailBox.toUtf8()) + "\" ";
69
70 QByteArray command = "GETMETADATA";
71 if (d->serverCapability == Annotatemore) {
72 d->m_name = "GetAnnotation";
73 command = "GETANNOTATION";
74 if (d->entries.size() > 1) {
75 parameters += '(';
76 }
77 Q_FOREACH (const QByteArray &entry, sort(d->entries)) {
78 parameters += '\"' + entry + "\" ";
79 }
80 if (d->entries.size() > 1) {
81 parameters[parameters.length() - 1 ] = ')';
82 parameters += ' ';
83 }
84
85 if (d->attributes.size() > 1) {
86 parameters += '(';
87 }
88 Q_FOREACH (const QByteArray &attribute, sort(d->attributes)) {
89 parameters += '\"' + attribute + "\" ";
90 }
91 if (d->attributes.size() > 1) {
92 parameters[parameters.length() - 1 ] = ')';
93 } else {
94 parameters.truncate(parameters.length() - 1);
95 }
96
97 } else {
98
99 QByteArray options;
100 if (d->depth != "0") {
101 options = "DEPTH " + d->depth;
102 }
103 if (d->maxSize != -1) {
104 if (!options.isEmpty()) {
105 options += ' ';
106 }
107 options += "MAXSIZE " + QByteArray::number(d->maxSize);
108 }
109
110 if (!options.isEmpty()) {
111 parameters = "(" + options + ") " + parameters;
112 }
113
114 if (d->entries.size() >= 1) {
115 parameters += '(';
116 Q_FOREACH (const QByteArray &entry, sort(d->entries)) {
117 parameters += entry + " ";
118 }
119 parameters[parameters.length() - 1 ] = ')';
120 } else {
121 parameters.truncate(parameters.length() - 1);
122 }
123 }
124
125 d->sendCommand(command, parameters);
126// qCDebug(KIMAP2_LOG) << "SENT: " << command << " " << parameters;
127}
128
129void GetMetaDataJob::handleResponse(const Message &response)
130{
132// qCDebug(KIMAP2_LOG) << "GOT: " << response.toString();
133
134 //TODO: handle NO error messages having [METADATA MAXSIZE NNN], [METADATA TOOMANY], [METADATA NOPRIVATE] (see rfc5464)
135 // or [ANNOTATEMORE TOOBIG], [ANNOTATEMORE TOOMANY] respectively
136 if (handleErrorReplies(response) == NotHandled) {
137 if (response.content.size() >= 4) {
138 if (d->serverCapability == Annotatemore && response.content[1].toString() == "ANNOTATION") {
139 QString mailBox = QString::fromUtf8(KIMAP2::decodeImapFolderName(response.content[2].toString()));
140
141 int i = 3;
142 while (i < response.content.size() - 1) {
143 QByteArray entry = response.content[i].toString();
144 QList<QByteArray> attributes = response.content[i + 1].toList();
145 int j = 0;
146 while (j < attributes.size() - 1) {
147 d->metadata[mailBox][entry][attributes[j]] = attributes[j + 1];
148 j += 2;
149 }
150 i += 2;
151 }
152 } else if (d->serverCapability == Metadata && response.content[1].toString() == "METADATA") {
153 QString mailBox = QString::fromUtf8(KIMAP2::decodeImapFolderName(response.content[2].toString()));
154
155 const QList<QByteArray> &entries = response.content[3].toList();
156 int i = 0;
157 while (i < entries.size() - 1) {
158 const QByteArray &value = entries[i + 1];
159 QByteArray &targetValue = d->metadata[mailBox][entries[i]][""];
160 if (value != "NIL") { //This just indicates no value
161 targetValue = value;
162 }
163 i += 2;
164 }
165 }
166 }
167 }
168}
169
170void GetMetaDataJob::addEntry(const QByteArray &entry, const QByteArray &attribute)
171{
173 if (d->serverCapability == Annotatemore && attribute.isNull()) {
174 qCWarning(KIMAP2_LOG) << "In ANNOTATEMORE mode an attribute must be specified with addEntry!";
175 }
176 d->entries.insert(entry);
177 d->attributes.insert(attribute);
178}
179
181{
183 d->entries.insert(d->removePrefix(entry));
184 d->attributes.insert(d->getAttribute(entry));
185}
186
188{
190 d->maxSize = size;
191}
192
194{
196
197 switch (depth) {
198 case OneLevel:
199 d->depth = "1"; //krazy:exclude=doublequote_chars
200 break;
201 case AllLevels:
202 d->depth = "infinity";
203 break;
204 default:
205 d->depth = "0"; //krazy:exclude=doublequote_chars
206 }
207}
208
209QByteArray GetMetaDataJob::metaData(const QString &mailBox, const QByteArray &entry, const QByteArray &attribute) const
210{
211 Q_D(const GetMetaDataJob);
212 QByteArray attr = attribute;
213
214 if (d->serverCapability == Metadata) {
215 attr = "";
216 }
217
219 if (d->metadata.contains(mailBox)) {
220 if (d->metadata[mailBox].contains(entry)) {
221 result = d->metadata[mailBox][entry].value(attr);
222 }
223 }
224 return result;
225}
226
228{
229 qCDebug(KIMAP2_LOG) << entry;
230 Q_D(const GetMetaDataJob);
231 return d->metadata.value(d->mailBox).value(d->removePrefix(entry)).value(d->getAttribute(entry));
232}
233
235{
236 Q_D(const GetMetaDataJob);
237 return d->metadata[mailBox];
238}
239
245
247{
248 Q_D(const GetMetaDataJob);
249 const QMap<QByteArray, QMap<QByteArray, QByteArray> > &entries = d->metadata[mailbox];
251 foreach (const QByteArray &entry, entries.keys()) {
252 const QMap<QByteArray, QByteArray> &values = entries[entry];
253 foreach (const QByteArray &attribute, values.keys()) {
254 map.insert(d->addPrefix(entry, attribute), values[attribute]);
255 }
256 }
257 return map;
258}
259
261{
262 Q_D(const GetMetaDataJob);
264
266 while (i.hasNext()) {
267 i.next();
268 mailboxHash.insert(i.key(), allMetaDataForMailbox(i.key()));
269 }
270 return mailboxHash;
271}
272
Fetches mailbox metadata.
Depth
Used to specify the depth of the metadata heirachy to walk.
@ AllLevels
The requested entries and all their descendants.
@ OneLevel
The requested entries and all their direct children.
QMap< QByteArray, QByteArray > allMetaDataForMailbox(const QString &mailbox) const
Get all the metadata for the mailbox.
KIMAP2_DEPRECATED void addEntry(const QByteArray &entry, const QByteArray &attribute=QByteArray())
Add an entry to the query list.
void addRequestedEntry(const QByteArray &entry)
Add an entry to the query list.
void setDepth(Depth depth)
Sets whether to retrieve children or descendants of the requested entries.
QHash< QString, QMap< QByteArray, QByteArray > > allMetaDataForMailboxes() const
Get all the metadata for for all mailboxes.
void setMaximumSize(qint64 size)
Limits the size of returned metadata entries.
KIMAP2_DEPRECATED QByteArray metaData(const QString &mailBox, const QByteArray &entry, const QByteArray &attribute=QByteArray()) const
Get a single metadata entry.
QMap< QByteArray, QByteArray > allMetaData() const
Get all the metadata for the mailbox set with setMailBox().
Base class for jobs that operate on mailbox metadata.
QString mailBox() const
The mailbox that will be acted upon.
@ 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.
void result(KJob *job)
QString name(StandardAction id)
bool isEmpty() const const
bool isNull() const const
qsizetype length() const const
QByteArray number(double n, char format, int precision)
void truncate(qsizetype pos)
iterator insert(const Key &key, const T &value)
QList< T > toList() const const
qsizetype size() const const
QList< Key > keys() const const
bool hasNext() const const
const Key & key() const const
QString fromUtf8(QByteArrayView str)
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 Sat Dec 21 2024 16:56:30 by doxygen 1.12.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.