diff options
Diffstat (limited to 'examples/imapresource')
-rw-r--r-- | examples/imapresource/imapresource.cpp | 10 | ||||
-rw-r--r-- | examples/imapresource/imapserverproxy.cpp | 26 | ||||
-rw-r--r-- | examples/imapresource/imapserverproxy.h | 9 |
3 files changed, 37 insertions, 8 deletions
diff --git a/examples/imapresource/imapresource.cpp b/examples/imapresource/imapresource.cpp index 0b3dcf5..8577b8c 100644 --- a/examples/imapresource/imapresource.cpp +++ b/examples/imapresource/imapresource.cpp | |||
@@ -119,6 +119,8 @@ public: | |||
119 | QByteArray createFolder(const Imap::Folder &f) | 119 | QByteArray createFolder(const Imap::Folder &f) |
120 | { | 120 | { |
121 | const auto parentFolderRid = parentRid(f); | 121 | const auto parentFolderRid = parentRid(f); |
122 | bool isToplevel = parentFolderRid.isEmpty(); | ||
123 | |||
122 | SinkTraceCtx(mLogCtx) << "Creating folder: " << f.name() << parentFolderRid << f.flags; | 124 | SinkTraceCtx(mLogCtx) << "Creating folder: " << f.name() << parentFolderRid << f.flags; |
123 | 125 | ||
124 | const auto remoteId = folderRid(f); | 126 | const auto remoteId = folderRid(f); |
@@ -126,22 +128,20 @@ public: | |||
126 | folder.setName(f.name()); | 128 | folder.setName(f.name()); |
127 | folder.setIcon("folder"); | 129 | folder.setIcon("folder"); |
128 | folder.setEnabled(f.subscribed); | 130 | folder.setEnabled(f.subscribed); |
129 | QHash<QByteArray, Query::Comparator> mergeCriteria; | ||
130 | auto specialPurpose = [&] { | 131 | auto specialPurpose = [&] { |
131 | if (hasSpecialPurposeFlag(f.flags)) { | 132 | if (hasSpecialPurposeFlag(f.flags)) { |
132 | return getSpecialPurposeType(f.flags); | 133 | return getSpecialPurposeType(f.flags); |
133 | } else if (SpecialPurpose::isSpecialPurposeFolderName(f.name()) && parentFolderRid.isEmpty()) { | 134 | } else if (SpecialPurpose::isSpecialPurposeFolderName(f.name()) && isToplevel) { |
134 | return SpecialPurpose::getSpecialPurposeType(f.name()); | 135 | return SpecialPurpose::getSpecialPurposeType(f.name()); |
135 | } | 136 | } |
136 | return QByteArray{}; | 137 | return QByteArray{}; |
137 | }(); | 138 | }(); |
138 | if (!specialPurpose.isEmpty()) { | 139 | if (!specialPurpose.isEmpty()) { |
139 | folder.setSpecialPurpose(QByteArrayList() << specialPurpose); | 140 | folder.setSpecialPurpose(QByteArrayList() << specialPurpose); |
140 | mergeCriteria.insert(ApplicationDomain::Folder::SpecialPurpose::name, Query::Comparator(specialPurpose, Query::Comparator::Contains)); | ||
141 | } | 141 | } |
142 | 142 | ||
143 | if (!parentFolderRid.isEmpty()) { | 143 | if (!isToplevel) { |
144 | folder.setParent(syncStore().resolveRemoteId(ENTITY_TYPE_FOLDER, parentFolderRid)); | 144 | folder.setParent(syncStore().resolveRemoteId(ApplicationDomain::Folder::name, parentFolderRid)); |
145 | } | 145 | } |
146 | createOrModify(ApplicationDomain::getTypeName<ApplicationDomain::Folder>(), remoteId, folder); | 146 | createOrModify(ApplicationDomain::getTypeName<ApplicationDomain::Folder>(), remoteId, folder); |
147 | return remoteId; | 147 | return remoteId; |
diff --git a/examples/imapresource/imapserverproxy.cpp b/examples/imapresource/imapserverproxy.cpp index 08a0081..d3ad2d4 100644 --- a/examples/imapresource/imapserverproxy.cpp +++ b/examples/imapresource/imapserverproxy.cpp | |||
@@ -457,10 +457,23 @@ bool Imap::flagsContain(const QByteArray &f, const QByteArrayList &flags) | |||
457 | return caseInsensitiveContains(f, flags); | 457 | return caseInsensitiveContains(f, flags); |
458 | } | 458 | } |
459 | 459 | ||
460 | static void reportFolder(const Folder &f, QSharedPointer<QSet<QString>> reportedList, std::function<void(const Folder &)> callback) { | ||
461 | if (!reportedList->contains(f.path())) { | ||
462 | reportedList->insert(f.path()); | ||
463 | auto c = f; | ||
464 | c.noselect = true; | ||
465 | callback(c); | ||
466 | if (!f.parentPath().isEmpty()){ | ||
467 | reportFolder(f.parentFolder(), reportedList, callback); | ||
468 | } | ||
469 | } | ||
470 | } | ||
471 | |||
460 | KAsync::Job<void> ImapServerProxy::fetchFolders(std::function<void(const Folder &)> callback) | 472 | KAsync::Job<void> ImapServerProxy::fetchFolders(std::function<void(const Folder &)> callback) |
461 | { | 473 | { |
462 | SinkTrace() << "Fetching folders"; | 474 | SinkTrace() << "Fetching folders"; |
463 | auto subscribedList = QSharedPointer<QSet<QString>>::create() ; | 475 | auto subscribedList = QSharedPointer<QSet<QString>>::create() ; |
476 | auto reportedList = QSharedPointer<QSet<QString>>::create() ; | ||
464 | return list(KIMAP2::ListJob::NoOption, [=](const KIMAP2::MailBoxDescriptor &mailbox, const QList<QByteArray> &){ | 477 | return list(KIMAP2::ListJob::NoOption, [=](const KIMAP2::MailBoxDescriptor &mailbox, const QList<QByteArray> &){ |
465 | *subscribedList << mailbox.name; | 478 | *subscribedList << mailbox.name; |
466 | }).then(list(KIMAP2::ListJob::IncludeUnsubscribed, [=](const KIMAP2::MailBoxDescriptor &mailbox, const QList<QByteArray> &flags) { | 479 | }).then(list(KIMAP2::ListJob::IncludeUnsubscribed, [=](const KIMAP2::MailBoxDescriptor &mailbox, const QList<QByteArray> &flags) { |
@@ -471,17 +484,24 @@ KAsync::Job<void> ImapServerProxy::fetchFolders(std::function<void(const Folder | |||
471 | bool sent = caseInsensitiveContains(FolderFlags::Sent, flags); | 484 | bool sent = caseInsensitiveContains(FolderFlags::Sent, flags); |
472 | bool drafts = caseInsensitiveContains(FolderFlags::Drafts, flags); | 485 | bool drafts = caseInsensitiveContains(FolderFlags::Drafts, flags); |
473 | bool trash = caseInsensitiveContains(FolderFlags::Trash, flags); | 486 | bool trash = caseInsensitiveContains(FolderFlags::Trash, flags); |
474 | bool isgmailParent = mailbox.name.toLower() == "[gmail]" || mailbox.name.toLower() == "[Google Mail]"; | ||
475 | /** | 487 | /** |
476 | * Because gmail duplicates messages all over the place we only support a few selected folders for now that should be mostly exclusive. | 488 | * Because gmail duplicates messages all over the place we only support a few selected folders for now that should be mostly exclusive. |
477 | */ | 489 | */ |
478 | if (!(inbox || sent || drafts || trash || isgmailParent)) { | 490 | if (!(inbox || sent || drafts || trash)) { |
479 | return; | 491 | return; |
480 | } | 492 | } |
481 | } | 493 | } |
482 | SinkLog() << "Found mailbox: " << mailbox.name << flags << FolderFlags::Noselect << noselect << " sub: " << subscribed; | 494 | SinkLog() << "Found mailbox: " << mailbox.name << flags << FolderFlags::Noselect << noselect << " sub: " << subscribed; |
483 | auto ns = getNamespace(mailbox.name); | 495 | auto ns = getNamespace(mailbox.name); |
484 | callback(Folder{mailbox.name, ns, mailbox.separator, noselect, subscribed, flags}); | 496 | auto folder = Folder{mailbox.name, ns, mailbox.separator, noselect, subscribed, flags}; |
497 | |||
498 | //call callback for parents if that didn't already happen. | ||
499 | //This is necessary because we can have missing bits in the hierarchy in IMAP, but this will not work in sink because we'd end up with an incomplete tree. | ||
500 | if (!folder.parentPath().isEmpty() && !reportedList->contains(folder.parentPath())) { | ||
501 | reportFolder(folder.parentFolder(), reportedList, callback); | ||
502 | } | ||
503 | reportedList->insert(folder.path()); | ||
504 | callback(folder); | ||
485 | })); | 505 | })); |
486 | } | 506 | } |
487 | 507 | ||
diff --git a/examples/imapresource/imapserverproxy.h b/examples/imapresource/imapserverproxy.h index 0d70ba5..2d90f39 100644 --- a/examples/imapresource/imapserverproxy.h +++ b/examples/imapresource/imapserverproxy.h | |||
@@ -118,6 +118,15 @@ struct Folder { | |||
118 | return parentPath; | 118 | return parentPath; |
119 | } | 119 | } |
120 | 120 | ||
121 | Folder parentFolder() const | ||
122 | { | ||
123 | Folder parent; | ||
124 | parent.mPath = parentPath(); | ||
125 | parent.mNamespace = mNamespace; | ||
126 | parent.mSeparator = mSeparator; | ||
127 | return parent; | ||
128 | } | ||
129 | |||
121 | QString name() const | 130 | QString name() const |
122 | { | 131 | { |
123 | auto pathParts = mPath.split(mSeparator); | 132 | auto pathParts = mPath.split(mSeparator); |