summaryrefslogtreecommitdiffstats
path: root/examples/imapresource/imapserverproxy.cpp
diff options
context:
space:
mode:
authorChristian Mollekopf <chrigi_1@fastmail.fm>2016-06-08 17:08:36 +0200
committerChristian Mollekopf <chrigi_1@fastmail.fm>2016-06-08 17:08:36 +0200
commit6c85a913c06661aa3f095cdf4bf278d5d65b6930 (patch)
treeed96474a8f3cf682ecbfb68c5135e23077177dae /examples/imapresource/imapserverproxy.cpp
parent16d4e7fcbe4e7817b4cbe4f7d2644520e1af1658 (diff)
downloadsink-6c85a913c06661aa3f095cdf4bf278d5d65b6930.tar.gz
sink-6c85a913c06661aa3f095cdf4bf278d5d65b6930.zip
Less hardcoded assumptions and a new RID scheme
By using (folder local id:imap uid) for mails, we don't have to change mail rid's on folder renames.
Diffstat (limited to 'examples/imapresource/imapserverproxy.cpp')
-rw-r--r--examples/imapresource/imapserverproxy.cpp79
1 files changed, 64 insertions, 15 deletions
diff --git a/examples/imapresource/imapserverproxy.cpp b/examples/imapresource/imapserverproxy.cpp
index 8c12b6c..db68a53 100644
--- a/examples/imapresource/imapserverproxy.cpp
+++ b/examples/imapresource/imapserverproxy.cpp
@@ -21,6 +21,7 @@
21#include <QDir> 21#include <QDir>
22#include <QFile> 22#include <QFile>
23#include <KIMAP/KIMAP/LoginJob> 23#include <KIMAP/KIMAP/LoginJob>
24#include <kimap/namespacejob.h>
24#include <KIMAP/KIMAP/SelectJob> 25#include <KIMAP/KIMAP/SelectJob>
25#include <KIMAP/KIMAP/AppendJob> 26#include <KIMAP/KIMAP/AppendJob>
26#include <KIMAP/KIMAP/CreateJob> 27#include <KIMAP/KIMAP/CreateJob>
@@ -98,15 +99,33 @@ KAsync::Job<void> ImapServerProxy::login(const QString &username, const QString
98 QObject::connect(capabilitiesJob, &KIMAP::CapabilitiesJob::capabilitiesReceived, [this](const QStringList &capabilities) { 99 QObject::connect(capabilitiesJob, &KIMAP::CapabilitiesJob::capabilitiesReceived, [this](const QStringList &capabilities) {
99 mCapabilities = capabilities; 100 mCapabilities = capabilities;
100 }); 101 });
102 auto namespaceJob = new KIMAP::NamespaceJob(mSession);
103
101 return runJob(loginJob).then(runJob(capabilitiesJob)).then<void>([this](){ 104 return runJob(loginJob).then(runJob(capabilitiesJob)).then<void>([this](){
102 Trace() << "Supported capabilities: " << mCapabilities; 105 Trace() << "Supported capabilities: " << mCapabilities;
103 QStringList requiredExtensions = QStringList() << "UIDPLUS"; 106 QStringList requiredExtensions = QStringList() << "UIDPLUS" << "NAMESPACE";
104 for (const auto &requiredExtension : requiredExtensions) { 107 for (const auto &requiredExtension : requiredExtensions) {
105 if (!mCapabilities.contains(requiredExtension)) { 108 if (!mCapabilities.contains(requiredExtension)) {
106 Warning() << "Server doesn't support required capability: " << requiredExtension; 109 Warning() << "Server doesn't support required capability: " << requiredExtension;
107 //TODO fail the job 110 //TODO fail the job
108 } 111 }
109 } 112 }
113 }).then(runJob(namespaceJob)).then<void>([this, namespaceJob](){
114 for (const auto &ns :namespaceJob->personalNamespaces()) {
115 mPersonalNamespaces << ns.name;
116 mPersonalNamespaceSeparator = ns.separator;
117 }
118 for (const auto &ns :namespaceJob->sharedNamespaces()) {
119 mSharedNamespaces << ns.name;
120 mSharedNamespaceSeparator = ns.separator;
121 }
122 for (const auto &ns :namespaceJob->userNamespaces()) {
123 mUserNamespaces << ns.name;
124 mUserNamespaceSeparator = ns.separator;
125 }
126 Trace() << "Found personal namespaces: " << mPersonalNamespaces << mPersonalNamespaceSeparator;
127 Trace() << "Found shared namespaces: " << mSharedNamespaces << mSharedNamespaceSeparator;
128 Trace() << "Found user namespaces: " << mUserNamespaces << mUserNamespaceSeparator;
110 }); 129 });
111} 130}
112 131
@@ -271,16 +290,6 @@ KAsync::Job<void> ImapServerProxy::list(KIMAP::ListJob::Option option, const std
271 // listJob->setQueriedNamespaces(serverNamespaces()); 290 // listJob->setQueriedNamespaces(serverNamespaces());
272 QObject::connect(listJob, &KIMAP::ListJob::mailBoxesReceived, 291 QObject::connect(listJob, &KIMAP::ListJob::mailBoxesReceived,
273 listJob, callback); 292 listJob, callback);
274 //Figure out the separator character on the first list issued.
275 if (mSeparatorCharacter.isNull()) {
276 QObject::connect(listJob, &KIMAP::ListJob::mailBoxesReceived,
277 listJob, [this](const QList<KIMAP::MailBoxDescriptor> &mailboxes,const QList<QList<QByteArray> > &flags) {
278 if (!mailboxes.isEmpty() && mSeparatorCharacter.isNull()) {
279 mSeparatorCharacter = mailboxes.first().separator;
280 }
281 }
282 );
283 }
284 return runJob(listJob); 293 return runJob(listJob);
285} 294}
286 295
@@ -295,6 +304,40 @@ KAsync::Job<void> ImapServerProxy::remove(const QString &mailbox, const QByteArr
295 return remove(mailbox, set); 304 return remove(mailbox, set);
296} 305}
297 306
307KAsync::Job<QString> ImapServerProxy::createSubfolder(const QString &parentMailbox, const QString &folderName)
308{
309 auto folder = QSharedPointer<QString>::create();
310 return KAsync::start<void, KAsync::Job<void>>([this, parentMailbox, folderName, folder]() {
311 Q_ASSERT(!mPersonalNamespaceSeparator.isNull());
312 if (parentMailbox.isEmpty()) {
313 *folder = mPersonalNamespaces.toList().first() + folderName;
314 } else {
315 *folder = parentMailbox + mPersonalNamespaceSeparator + folderName;
316 }
317 Trace() << "Creating subfolder: " << *folder;
318 return create(*folder);
319 })
320 .then<QString>([=]() {
321 return *folder;
322 });
323}
324
325KAsync::Job<QString> ImapServerProxy::renameSubfolder(const QString &oldMailbox, const QString &newName)
326{
327 auto folder = QSharedPointer<QString>::create();
328 return KAsync::start<void, KAsync::Job<void>>([this, oldMailbox, newName, folder]() {
329 Q_ASSERT(!mPersonalNamespaceSeparator.isNull());
330 auto parts = oldMailbox.split(mPersonalNamespaceSeparator);
331 parts.removeLast();
332 *folder = parts.join(mPersonalNamespaceSeparator) + mPersonalNamespaceSeparator + newName;
333 Trace() << "Renaming subfolder: " << oldMailbox << *folder;
334 return rename(oldMailbox, *folder);
335 })
336 .then<QString>([=]() {
337 return *folder;
338 });
339}
340
298KAsync::Job<void> ImapServerProxy::fetchFolders(std::function<void(const QVector<Folder> &)> callback) 341KAsync::Job<void> ImapServerProxy::fetchFolders(std::function<void(const QVector<Folder> &)> callback)
299{ 342{
300 Trace() << "Fetching folders"; 343 Trace() << "Fetching folders";
@@ -302,17 +345,23 @@ KAsync::Job<void> ImapServerProxy::fetchFolders(std::function<void(const QVector
302 QVector<Folder> list; 345 QVector<Folder> list;
303 for (const auto &mailbox : mailboxes) { 346 for (const auto &mailbox : mailboxes) {
304 Trace() << "Found mailbox: " << mailbox.name; 347 Trace() << "Found mailbox: " << mailbox.name;
305 list << Folder{mailbox.name.split(mailbox.separator)}; 348 list << Folder{mailbox.name.split(mailbox.separator), mailbox.name, mailbox.separator};
306 } 349 }
307 callback(list); 350 callback(list);
308 }); 351 });
309} 352}
310 353
354QString ImapServerProxy::mailboxFromFolder(const Folder &folder) const
355{
356 Q_ASSERT(!mPersonalNamespaceSeparator.isNull());
357 return folder.pathParts.join(mPersonalNamespaceSeparator);
358}
359
311KAsync::Job<void> ImapServerProxy::fetchMessages(const Folder &folder, std::function<void(const QVector<Message> &)> callback) 360KAsync::Job<void> ImapServerProxy::fetchMessages(const Folder &folder, std::function<void(const QVector<Message> &)> callback)
312{ 361{
313 Q_ASSERT(!mSeparatorCharacter.isNull()); 362 Q_ASSERT(!mPersonalNamespaceSeparator.isNull());
314 return select(folder.pathParts.join(mSeparatorCharacter)).then<void, KAsync::Job<void>>([this, callback, folder]() -> KAsync::Job<void> { 363 return select(mailboxFromFolder(folder)).then<void, KAsync::Job<void>>([this, callback, folder]() -> KAsync::Job<void> {
315 return fetchHeaders(folder.pathParts.join(mSeparatorCharacter)).then<void, KAsync::Job<void>, QList<qint64>>([this, callback](const QList<qint64> &uidsToFetch){ 364 return fetchHeaders(mailboxFromFolder(folder)).then<void, KAsync::Job<void>, QList<qint64>>([this, callback](const QList<qint64> &uidsToFetch){
316 Trace() << "Uids to fetch: " << uidsToFetch; 365 Trace() << "Uids to fetch: " << uidsToFetch;
317 if (uidsToFetch.isEmpty()) { 366 if (uidsToFetch.isEmpty()) {
318 Trace() << "Nothing to fetch"; 367 Trace() << "Nothing to fetch";