Branch 'kolab/integration/4.13.0' - 18 commits - resources/CMakeLists.txt resources/imap resources/kolab

Christian Mollekopf mollekopf at kolabsys.com
Wed May 21 00:40:42 CEST 2014


 resources/CMakeLists.txt                                    |    2 
 resources/imap/messagehelper.cpp                            |    5 ++
 resources/imap/moveitemstask.cpp                            |   10 ++++
 resources/imap/removeitemstask.cpp                          |    5 ++
 resources/imap/resourcetask.cpp                             |   18 +++++--
 resources/imap/retrieveitemstask.cpp                        |   23 ++++++++-
 resources/imap/tests/testmoveitemstask.cpp                  |    4 -
 resources/imap/tests/testretrievecollectionmetadatatask.cpp |   20 +++++++-
 resources/imap/tests/testretrieveitemstask.cpp              |   30 ++++++------
 resources/kolab/CMakeLists.txt                              |    7 ++
 resources/kolab/kolabhelpers.cpp                            |    7 +-
 resources/kolab/kolabresource.cpp                           |    4 +
 resources/kolab/kolabresourcestate.cpp                      |    5 ++
 resources/kolab/kolabretrievecollectionstask.h              |    2 
 14 files changed, 114 insertions(+), 28 deletions(-)

New commits:
commit ed6fc6b7bfec9bb5f1976fc3eddf38fd13197c26
Author: Christian Mollekopf <chrigi_1 at fastmail.fm>
Date:   Wed May 21 00:38:11 2014 +0200

    IMAP-Resource: Adapted tests.

diff --git a/resources/imap/tests/testretrieveitemstask.cpp b/resources/imap/tests/testretrieveitemstask.cpp
index f2444c8..b22a7bc 100644
--- a/resources/imap/tests/testretrieveitemstask.cpp
+++ b/resources/imap/tests/testretrieveitemstask.cpp
@@ -157,7 +157,8 @@ private slots:
     callNames.clear();
     callNames << "itemsRetrievedIncremental" << "applyCollectionChanges" << "itemsRetrievedIncremental" << "itemsRetrievalDone";
 
-    QTest::newRow( "second listing, checking for flag changes" ) << collection << scenario << callNames;
+    //Disabled test since the flag sync is disabled if CONDSTORE is not supported
+//     QTest::newRow( "second listing, checking for flag changes" ) << collection << scenario << callNames;
 
 
     collection = createCollectionChain( QLatin1String("/INBOX/Foo") );
@@ -233,7 +234,7 @@ private slots:
              << "S: A000009 OK fetch done";
 
     callNames.clear();
-    callNames << "itemsRetrieved" << "applyCollectionChanges" << "itemsRetrievalDone";
+    callNames << "itemsRetrievedIncremental" << "applyCollectionChanges" << "itemsRetrievedIncremental"<< "itemsRetrievalDone";
 
     QTest::newRow( "uidnext changed, fetch new messages and list flags" ) << collection << scenario << callNames;
 
@@ -318,15 +319,18 @@ private slots:
              << "S: * OK [ UIDVALIDITY 1149151135 ]"
              << "S: * OK [ UIDNEXT 9 ]"
              << "S: * OK [ HIGHESTMODSEQ 123456789 ]"
-             << "S: A000005 OK select done"
-             << "C: A000006 UID SEARCH UID 1:9"
-             << "S: * SEARCH 1 2 3 4 5 6 7 8 9"
-             << "S: A000006 OK search done"
-             << "C: A000007 UID FETCH 1:9 (FLAGS UID)"
-             << "S: * 5 FETCH ( UID 8 FLAGS () )"
-             << "S: A000007 OK fetch done";
+             << "S: A000005 OK select done";
+    //Disabled since the flag sync is disabled if CONDSTORE is not supported
+//              << "C: A000006 UID SEARCH UID 1:9"
+//              << "S: * SEARCH 1 2 3 4 5 6 7 8 9"
+//              << "S: A000006 OK search done"
+//              << "C: A000007 UID FETCH 1:9 (FLAGS UID)"
+//              << "S: * 5 FETCH ( UID 8 FLAGS () )"
+//              << "S: A000007 OK fetch done";
     callNames.clear();
-    callNames << "itemsRetrievedIncremental" << "applyCollectionChanges" << "itemsRetrievedIncremental" << "itemsRetrievalDone";
+
+    //Disabled since the flag sync is disabled if CONDSTORE is not supported
+    callNames << /*"itemsRetrievedIncremental" << */"applyCollectionChanges" << "itemsRetrievedIncremental" << "itemsRetrievalDone";
 
     //Don't rely on yahoos highestmodseq implementation
     QTest::newRow( "yahoo highestmodseq test" ) << collection << scenario << callNames;


commit ec652ade5a870388a0156621cebdb827a6a231ee
Author: Christian Mollekopf <chrigi_1 at fastmail.fm>
Date:   Tue May 20 23:50:49 2014 +0200

    IMAP-Resource: Avoid resyncing all flags during every sync.
    
    Without CONDSTORE we end up syncing all flags during every sync,
    even if nothing has changed. This patch mitigates, by sacrificing flag updates
    when no new messages are available.

diff --git a/resources/imap/retrieveitemstask.cpp b/resources/imap/retrieveitemstask.cpp
index 5ebb047..7c49ef3 100644
--- a/resources/imap/retrieveitemstask.cpp
+++ b/resources/imap/retrieveitemstask.cpp
@@ -597,6 +597,14 @@ void RetrieveItemsTask::onFinalSelectDone(KJob *job)
         m_uidBasedFetch = true;
         m_incremental = true;
         m_flagsChanged = !(highestModSeq == oldHighestModSeq);
+        //Workaround: If the server doesn't support CONDSTORE we would end up syncing all flags during every sync.
+        //Instead we only sync flags when new messages are available or removed and skip this step.
+        //WARNING: This sacrifices consitency as we will not detect flag changes until a new message enters the mailbox.
+        if (!serverSupportsCondstore()) {
+            kDebug(5327) << "Avoiding flag sync due to missing CONDSTORE support";
+            taskComplete();
+            return;
+        }
         setTotalItems(messageCount);
         listFlagsForImapSet(KIMAP::ImapSet(1, nextUid));
     } else if (messageCount > realMessageCount) {


commit a5e476b4cddb147bbd1d945dfed6279ca727056c
Author: Christian Mollekopf <chrigi_1 at fastmail.fm>
Date:   Tue May 20 23:43:47 2014 +0200

    IMAP-Resource: Avoid complete resync due to not yet uploaded messages.
    
    This can happen if items were not yet uploaded (i.e. failed), so the local
    message count is actually larger than expected.

diff --git a/resources/imap/retrieveitemstask.cpp b/resources/imap/retrieveitemstask.cpp
index 86e523a..5ebb047 100644
--- a/resources/imap/retrieveitemstask.cpp
+++ b/resources/imap/retrieveitemstask.cpp
@@ -565,16 +565,17 @@ void RetrieveItemsTask::onFinalSelectDone(KJob *job)
         KIMAP::ImapSet imapSet;
         imapSet.add(m_messageUidsMissingBody);
         retrieveItems(imapSet, scope, true, true);
-    } else if (nextUid > oldNextUid && ((realMessageCount + nextUid - oldNextUid) == messageCount)) {
+    } else if (nextUid > oldNextUid && ((realMessageCount + nextUid - oldNextUid) >= messageCount) && realMessageCount > 0) {
         //Optimization:
         //New messages are available, but we know no messages have been removed.
         //Fetch new messages, and then check for changed flags and removed messages
         //We can make an incremental update and use modseq.
+        //The local message count can be larger if we locally have messages that were not yet uploaded.
         kDebug( 5327 ) << "Incrementally fetching new messages: UidNext: " << nextUid << " Old UidNext: " << oldNextUid << " message count " << messageCount << realMessageCount;
         setTotalItems(qMax(1ll, messageCount - realMessageCount));
         m_flagsChanged = !(highestModSeq == oldHighestModSeq);
         retrieveItems(KIMAP::ImapSet(qMax(1, oldNextUid), nextUid), scope, true, true);
-    } else if (nextUid > oldNextUid && messageCount > (realMessageCount + nextUid - oldNextUid)) {
+    } else if (nextUid > oldNextUid && messageCount > (realMessageCount + nextUid - oldNextUid) && realMessageCount > 0) {
         //Error recovery:
         //New messages are available, but not enough to justify the difference between the local and remote message count.
         //This can be triggered if we i.e. clear the local cache, but the keep the annotations.
@@ -588,10 +589,11 @@ void RetrieveItemsTask::onFinalSelectDone(KJob *job)
         kDebug( 5327 ) << "Fetching new messages: UidNext: " << nextUid << " Old UidNext: " << oldNextUid;
         setTotalItems(messageCount);
         retrieveItems(KIMAP::ImapSet(qMax(1, oldNextUid), nextUid), scope, false, true);
-    } else if (messageCount == realMessageCount && oldNextUid == nextUid) {
+    } else if (messageCount <= realMessageCount && oldNextUid == nextUid) {
         //Optimization:
         //We know no messages were added or removed (if the message count and uidnext is still the same)
         //We only check the flags incrementally and can make use of modseq
+        //The local message count can be larger if we locally have messages that were not yet uploaded.
         m_uidBasedFetch = true;
         m_incremental = true;
         m_flagsChanged = !(highestModSeq == oldHighestModSeq);


commit 97599ba895f08c5a5cbb187d41d6445bf30faf91
Author: Christian Mollekopf <chrigi_1 at fastmail.fm>
Date:   Fri May 16 00:24:28 2014 +0200

    IMAP-Resource: Don't crash if we failed to download a message.

diff --git a/resources/imap/messagehelper.cpp b/resources/imap/messagehelper.cpp
index 8697caf..929c521 100644
--- a/resources/imap/messagehelper.cpp
+++ b/resources/imap/messagehelper.cpp
@@ -35,6 +35,11 @@ Akonadi::Item MessageHelper::createItemFromMessage(KMime::Message::Ptr message,
         i.setMimeType(KMime::Message::mimeType());
         i.setFlags(Akonadi::Item::Flags::fromList(ResourceTask::toAkonadiFlags(flags)));
     } else {
+        if (!message) {
+            kWarning() << "Got empty message: " << uid;
+            ok = false;
+            return Akonadi::Item();
+        }
         // Sometimes messages might not have a body at all
         if (message->body().isEmpty() && (scope.mode == KIMAP::FetchJob::FetchScope::Full || scope.mode == KIMAP::FetchJob::FetchScope::Content)) {
             // In that case put a space in as body so that it gets cached


commit 9355ac7f010cdbfed7fb245c8839ff8cca639932
Author: Christian Mollekopf <chrigi_1 at fastmail.fm>
Date:   Fri May 16 00:22:15 2014 +0200

    Revert "IMAP-Resource: Don't crash if we failed to download a message."
    
    This reverts commit 50d56bae06e24fbb816dc9fb98b9c9aca3bebe8a.
    
    We CAN get no message if we're fetching header only.

diff --git a/resources/imap/retrieveitemstask.cpp b/resources/imap/retrieveitemstask.cpp
index 9777994..86e523a 100644
--- a/resources/imap/retrieveitemstask.cpp
+++ b/resources/imap/retrieveitemstask.cpp
@@ -210,13 +210,8 @@ void BatchFetcher::onHeadersReceived(const QString &mailBox, const QMap<qint64,
     Akonadi::Item::List addedItems;
     foreach (qint64 number, uids.keys()) { //krazy:exclude=foreach
         //kDebug( 5327 ) << "Flags: " << i.flags();
-        const KIMAP::MessagePtr msg = messages[number];
-        if (!msg) {
-            kWarning() << "Failed to download message. Message is empty. " << uids[number];
-            continue;
-        }
         bool ok;
-        const Akonadi::Item item = m_messageHelper->createItemFromMessage(msg, uids[number], sizes[number], flags[number], fetch->scope(), ok);
+        const Akonadi::Item item = m_messageHelper->createItemFromMessage(messages[number], uids[number], sizes[number], flags[number], fetch->scope(), ok);
         if (ok) {
             m_fetchedItemsInCurrentBatch++;
             addedItems << item;
@@ -573,7 +568,7 @@ void RetrieveItemsTask::onFinalSelectDone(KJob *job)
     } else if (nextUid > oldNextUid && ((realMessageCount + nextUid - oldNextUid) == messageCount)) {
         //Optimization:
         //New messages are available, but we know no messages have been removed.
-        //Fetch new messages, and then check for changed flags.
+        //Fetch new messages, and then check for changed flags and removed messages
         //We can make an incremental update and use modseq.
         kDebug( 5327 ) << "Incrementally fetching new messages: UidNext: " << nextUid << " Old UidNext: " << oldNextUid << " message count " << messageCount << realMessageCount;
         setTotalItems(qMax(1ll, messageCount - realMessageCount));


commit 8a581c13f2b69c8be16ee0ad6f3f2aafa91cbc76
Author: Christian Mollekopf <chrigi_1 at fastmail.fm>
Date:   Thu May 15 21:26:07 2014 +0200

    IMAP-Resource: Don't crash if we failed to download a message.
    
    Apparently happended to dvratil, perhaps because of an unreliable network connection or alike.

diff --git a/resources/imap/retrieveitemstask.cpp b/resources/imap/retrieveitemstask.cpp
index 86e523a..9777994 100644
--- a/resources/imap/retrieveitemstask.cpp
+++ b/resources/imap/retrieveitemstask.cpp
@@ -210,8 +210,13 @@ void BatchFetcher::onHeadersReceived(const QString &mailBox, const QMap<qint64,
     Akonadi::Item::List addedItems;
     foreach (qint64 number, uids.keys()) { //krazy:exclude=foreach
         //kDebug( 5327 ) << "Flags: " << i.flags();
+        const KIMAP::MessagePtr msg = messages[number];
+        if (!msg) {
+            kWarning() << "Failed to download message. Message is empty. " << uids[number];
+            continue;
+        }
         bool ok;
-        const Akonadi::Item item = m_messageHelper->createItemFromMessage(messages[number], uids[number], sizes[number], flags[number], fetch->scope(), ok);
+        const Akonadi::Item item = m_messageHelper->createItemFromMessage(msg, uids[number], sizes[number], flags[number], fetch->scope(), ok);
         if (ok) {
             m_fetchedItemsInCurrentBatch++;
             addedItems << item;
@@ -568,7 +573,7 @@ void RetrieveItemsTask::onFinalSelectDone(KJob *job)
     } else if (nextUid > oldNextUid && ((realMessageCount + nextUid - oldNextUid) == messageCount)) {
         //Optimization:
         //New messages are available, but we know no messages have been removed.
-        //Fetch new messages, and then check for changed flags and removed messages
+        //Fetch new messages, and then check for changed flags.
         //We can make an incremental update and use modseq.
         kDebug( 5327 ) << "Incrementally fetching new messages: UidNext: " << nextUid << " Old UidNext: " << oldNextUid << " message count " << messageCount << realMessageCount;
         setTotalItems(qMax(1ll, messageCount - realMessageCount));


commit a036b88af0b95f3c391d9d1d208a6952e5e10470
Author: Kevin Ottens <ervin at kde.org>
Date:   Mon May 12 11:51:19 2014 +0200

    Add unit tests for the no relevant capability available case
    
    REVIEW: 118093

diff --git a/resources/imap/tests/testretrievecollectionmetadatatask.cpp b/resources/imap/tests/testretrievecollectionmetadatatask.cpp
index 22c8e9d..c6113f8 100644
--- a/resources/imap/tests/testretrievecollectionmetadatatask.cpp
+++ b/resources/imap/tests/testretrievecollectionmetadatatask.cpp
@@ -253,6 +253,24 @@ private slots:
     rights = Akonadi::Collection::AllRights;
     QTest::newRow( "METADATA" ) << collection << capabilities << scenario
                                     << callNames << rights << expectedAnnotations;
+
+    collection = createCollectionChain( QLatin1String("/INBOX/Foo") );
+    collection.setRights( 0 );
+    collection.addAttribute( new TimestampAttribute( QDateTime::currentDateTime().toTime_t() ) );
+
+    capabilities.clear();
+    expectedAnnotations.clear();
+
+    callNames.clear();
+    callNames << "collectionAttributesRetrieved";
+
+    rights = 0;
+
+    scenario.clear();
+    scenario << defaultPoolConnectionScenario();
+
+    QTest::newRow( "no capabilities" ) << collection << capabilities << scenario
+                                       << callNames << rights << expectedAnnotations;
   }
 
   void shouldCollectionRetrieveMetadata()


commit c6e0368f4f5e208111cfbd38365f06ed464835db
Author: Christian Mollekopf <chrigi_1 at fastmail.fm>
Date:   Tue May 13 11:57:20 2014 +0200

    IMAP-Resoure: Fixed test
    
    moveitemstask: Just passed by chance, this was always supposed store the
    attribute (it passed because the test only waited for one callName, and then already succeeded.
    
    retrievecollectionmetadata: adapted to kdepimlibs changes
    retrieveitemsttask: We're hitting the optimization code-path.

diff --git a/resources/imap/tests/testmoveitemstask.cpp b/resources/imap/tests/testmoveitemstask.cpp
index 080b4d6..ef5322c 100644
--- a/resources/imap/tests/testmoveitemstask.cpp
+++ b/resources/imap/tests/testmoveitemstask.cpp
@@ -206,9 +206,9 @@ private slots:
              << "S: A000007 OK search done";
 
     callNames.clear();
-    callNames << "itemsChangesCommitted";
+    callNames << "itemsChangesCommitted" << "applyCollectionChanges";
 
-    QTest::newRow( "moving mail, no COPYUID, message didn't have unique Message-ID" ) << item << source << target << scenario << callNames;
+    QTest::newRow( "moving mail, no COPYUID, message didn't have unique Message-ID, but last one matches old uidnext" ) << item << source << target << scenario << callNames;
   }
 
   void shouldCopyAndDeleteMessage()
diff --git a/resources/imap/tests/testretrievecollectionmetadatatask.cpp b/resources/imap/tests/testretrievecollectionmetadatatask.cpp
index 59d34fe..22c8e9d 100644
--- a/resources/imap/tests/testretrievecollectionmetadatatask.cpp
+++ b/resources/imap/tests/testretrievecollectionmetadatatask.cpp
@@ -231,7 +231,7 @@ private slots:
 
     scenario.clear();
     scenario << defaultPoolConnectionScenario()
-             << "C: A000003 GETMETADATA \"INBOX/Foo\" (DEPTH infinity) (/shared)"
+             << "C: A000003 GETMETADATA (DEPTH infinity) \"INBOX/Foo\" (/shared)"
              << "S: * METADATA \"INBOX/Foo\" (/shared/vendor/kolab/folder-test \"true\")"
              << "S: * METADATA \"INBOX/Foo\" (/shared/vendor/kolab/folder-test2 \"NIL\")"
              << "S: * METADATA \"INBOX/Foo\" (/shared/vendor/cmu/cyrus-imapd/lastupdate \"true\")"
diff --git a/resources/imap/tests/testretrieveitemstask.cpp b/resources/imap/tests/testretrieveitemstask.cpp
index 9eb6624..f2444c8 100644
--- a/resources/imap/tests/testretrieveitemstask.cpp
+++ b/resources/imap/tests/testretrieveitemstask.cpp
@@ -377,7 +377,7 @@ private slots:
     collection.attribute<UidNextAttribute>(Akonadi::Collection::AddIfMissing)->setUidNext(105);
     collection.attribute<UidValidityAttribute>(Akonadi::Entity::AddIfMissing)->setUidValidity(1149151135);
     collection.setCachePolicy( policy );
-    stats.setCount(15);
+    stats.setCount(104);
     collection.setStatistics( stats );
 
     scenario.clear();
@@ -389,7 +389,7 @@ private slots:
              << "C: A000005 SELECT \"INBOX/Foo\""
              << "S: * FLAGS (\\Answered \\Flagged \\Draft \\Deleted \\Seen)"
              << "S: * OK [ PERMANENTFLAGS (\\Answered \\Flagged \\Draft \\Deleted \\Seen) ]"
-             << "S: * 120 EXISTS"
+             << "S: * 119 EXISTS"
              << "S: * 0 RECENT"
              << "S: * OK [ UIDVALIDITY 1149151135  ]"
              << "S: * OK [ UIDNEXT 120  ]"
@@ -429,7 +429,7 @@ private slots:
              << "S: A000010 OK fetch done";
 
     callNames.clear();
-    callNames << "itemsRetrieved" << "itemsRetrieved" << "itemsRetrieved" << "applyCollectionChanges" << "itemsRetrievalDone";
+    callNames << "itemsRetrievedIncremental" << "itemsRetrievedIncremental" << "itemsRetrievedIncremental" << "applyCollectionChanges" << "itemsRetrievedIncremental" << "itemsRetrievalDone";
 
     QTest::newRow( "test batch processing" ) << collection << scenario << callNames;
 


commit f6c64cdd5061c1be8f246faab467d13ebbbbc097
Author: Christian Mollekopf <chrigi_1 at fastmail.fm>
Date:   Sat May 10 17:16:42 2014 +0200

    Kolab-Resource: load imap resource translations.

diff --git a/resources/kolab/kolabresource.cpp b/resources/kolab/kolabresource.cpp
index c2b2979..c9b790d 100644
--- a/resources/kolab/kolabresource.cpp
+++ b/resources/kolab/kolabresource.cpp
@@ -28,6 +28,7 @@
 #include <KLocalizedString>
 #include <Akonadi/CollectionFetchJob>
 #include <Akonadi/CollectionFetchScope>
+#include <KLocale>
 
 #include "kolabretrievecollectionstask.h"
 #include "kolabresourcestate.h"
@@ -36,7 +37,8 @@
 KolabResource::KolabResource(const QString& id)
     :ImapResource(id)
 {
-
+    //Load translations from imap resource
+    KGlobal::locale()->insertCatalog("akonadi_imap_resource");
 }
 
 KolabResource::~KolabResource()


commit eb67aebf9af845d6b1178ef8bdacc88fe490d661
Author: Christian Mollekopf <chrigi_1 at fastmail.fm>
Date:   Sat May 10 17:16:27 2014 +0200

    Kolab-Resource: Don't populate unhandled folders.
    
    That should avoid that we i.e. download the content of a file folder in the first place.

diff --git a/resources/kolab/kolabresourcestate.cpp b/resources/kolab/kolabresourcestate.cpp
index 1d5c624..47981e7 100644
--- a/resources/kolab/kolabresourcestate.cpp
+++ b/resources/kolab/kolabresourcestate.cpp
@@ -21,6 +21,7 @@
 #include "kolabhelpers.h"
 #include "kolabmessagehelper.h"
 #include <collectionannotationsattribute.h>
+#include <noselectattribute.h>
 #include <Akonadi/EntityDisplayAttribute>
 #include <Akonadi/CachePolicy>
 #include <Akonadi/KMime/MessageParts>
@@ -64,6 +65,10 @@ void KolabResourceState::collectionAttributesRetrieved(const Akonadi::Collection
                 col.setCachePolicy(cachePolicy);
             }
         }
+        if (!KolabHelpers::isHandledType(folderType)) {
+            //If we don't handle the folder, make sure we don't download the messages
+            col.attribute<NoSelectAttribute>(Akonadi::Entity::AddIfMissing);
+        }
     }
     ResourceState::collectionAttributesRetrieved(col);
 }


commit b4c50f039d68ff0ccc63020965c11cd1b9ab4f14
Author: Christian Mollekopf <chrigi_1 at fastmail.fm>
Date:   Sat May 10 17:15:45 2014 +0200

    IMAP-Resource: Be a bit more verbose.

diff --git a/resources/imap/moveitemstask.cpp b/resources/imap/moveitemstask.cpp
index f79d623..0cf4ded 100644
--- a/resources/imap/moveitemstask.cpp
+++ b/resources/imap/moveitemstask.cpp
@@ -50,12 +50,14 @@ MoveItemsTask::~MoveItemsTask()
 void MoveItemsTask::doStart( KIMAP::Session *session )
 {
   if ( item().remoteId().isEmpty() ) {
+    kWarning() << "Failed: messages has no rid";
     emitError( i18n( "Cannot move message, it does not exist on the server." ) );
     changeProcessed();
     return;
   }
 
   if ( sourceCollection().remoteId().isEmpty() ) {
+    kWarning() << "Failed: source collection has no rid";
     emitError( i18n( "Cannot move message out of '%1', '%1' does not exist on the server.",
                      sourceCollection().name() ) );
     changeProcessed();
@@ -63,6 +65,7 @@ void MoveItemsTask::doStart( KIMAP::Session *session )
   }
 
   if ( targetCollection().remoteId().isEmpty() ) {
+    kWarning() << "Failed: target collection has no rid";
     emitError( i18n( "Cannot move message to '%1', '%1' does not exist on the server.",
                      targetCollection().name() ) );
     changeProcessed();
@@ -73,6 +76,7 @@ void MoveItemsTask::doStart( KIMAP::Session *session )
   const QString newMailBox = mailBoxForCollection( targetCollection() );
 
   if ( oldMailBox == newMailBox ) {
+    kDebug() << "Nothing to do, same mailbox";
     changeProcessed();
     return;
   }
@@ -93,6 +97,7 @@ void MoveItemsTask::doStart( KIMAP::Session *session )
 void MoveItemsTask::onSelectDone( KJob *job )
 {
   if ( job->error() ) {
+    kWarning() << "Select failed: " << job->errorString();
     cancelTask( job->errorString() );
 
   } else {
@@ -119,6 +124,7 @@ void MoveItemsTask::triggerCopyJob( KIMAP::Session *session )
 
         set.add( item.remoteId().toLong() );
     } catch ( Akonadi::PayloadException e ) {
+        kWarning() << "Copy failed, payload exception " << item.id() << item.remoteId();
         cancelTask( i18n( "Failed to copy item, it has no message payload. Remote id: %1", item.remoteId() ) );
         return;
     }
@@ -141,6 +147,7 @@ void MoveItemsTask::triggerCopyJob( KIMAP::Session *session )
 void MoveItemsTask::onCopyDone( KJob *job )
 {
   if ( job->error()  ) {
+    kWarning() << job->errorString();
     cancelTask( job->errorString() );
 
   } else {
@@ -166,6 +173,7 @@ void MoveItemsTask::onCopyDone( KJob *job )
 void MoveItemsTask::onStoreFlagsDone( KJob *job )
 {
   if ( job->error() ) {
+    kWarning() << "Failed to mark message as deleted on source server: " << job->errorString();
     emitWarning( i18n( "Failed to mark the message from '%1' for deletion on the IMAP server. "
                        "It will reappear on next sync.",
                        sourceCollection().name() ) );
@@ -191,6 +199,7 @@ void MoveItemsTask::onStoreFlagsDone( KJob *job )
 void MoveItemsTask::onPreSearchSelectDone( KJob *job )
 {
   if ( job->error() ) {
+    kWarning() << "Select failed: " << job->errorString();
     cancelTask( job->errorString() );
     return;
   }
@@ -232,6 +241,7 @@ void MoveItemsTask::onPreSearchSelectDone( KJob *job )
 void MoveItemsTask::onSearchDone( KJob *job )
 {
   if ( job->error() ) {
+    kWarning() << "Search failed: " << job->errorString();
     cancelTask( job->errorString() );
     return;
   }
diff --git a/resources/imap/removeitemstask.cpp b/resources/imap/removeitemstask.cpp
index d18d884..300ff43 100644
--- a/resources/imap/removeitemstask.cpp
+++ b/resources/imap/removeitemstask.cpp
@@ -48,6 +48,8 @@ void RemoveItemsTask::doStart( KIMAP::Session *session )
 
   const QString mailBox = mailBoxForCollection( items().first().parentCollection() );
 
+  kDebug(5327) << "Deleting " << items().size() << " messages from " << mailBox;
+
   if ( session->selectedMailBox() != mailBox ) {
     KIMAP::SelectJob *select = new KIMAP::SelectJob( session );
     select->setMailBox( mailBox );
@@ -65,6 +67,7 @@ void RemoveItemsTask::doStart( KIMAP::Session *session )
 void RemoveItemsTask::onSelectDone( KJob *job )
 {
   if ( job->error() ) {
+    kWarning() << "Failed to select mailbox: " << job->errorString();
     cancelTask( job->errorString() );
   } else {
     KIMAP::SelectJob *select = static_cast<KIMAP::SelectJob*>( job );
@@ -90,7 +93,9 @@ void RemoveItemsTask::triggerStoreJob( KIMAP::Session *session )
 
 void RemoveItemsTask::onStoreFlagsDone( KJob *job )
 {
+  //TODO use UID EXPUNGE if available
   if ( job->error() ) {
+    kWarning() << "Failed to append flags: " << job->errorString();
     cancelTask( job->errorString() );
   } else {
     changeProcessed();


commit 26288f4fae5760d47c61658ac1e5a477c618c2fe
Author: Christian Mollekopf <chrigi_1 at fastmail.fm>
Date:   Sat May 10 17:15:23 2014 +0200

    IMAP-Resource: Don't populate the resource with flags only.
    
    Catch another case that can easily be triggered by clearing the cache,
    while leaving the attribute intact. We tried to do an incremental sync in that
    case, and the resource would populate the whole collection with flags only.
    We now detect that something is off with the messagecount, and do a full sync instead.

diff --git a/resources/imap/retrieveitemstask.cpp b/resources/imap/retrieveitemstask.cpp
index 47c48bd..86e523a 100644
--- a/resources/imap/retrieveitemstask.cpp
+++ b/resources/imap/retrieveitemstask.cpp
@@ -574,6 +574,15 @@ void RetrieveItemsTask::onFinalSelectDone(KJob *job)
         setTotalItems(qMax(1ll, messageCount - realMessageCount));
         m_flagsChanged = !(highestModSeq == oldHighestModSeq);
         retrieveItems(KIMAP::ImapSet(qMax(1, oldNextUid), nextUid), scope, true, true);
+    } else if (nextUid > oldNextUid && messageCount > (realMessageCount + nextUid - oldNextUid)) {
+        //Error recovery:
+        //New messages are available, but not enough to justify the difference between the local and remote message count.
+        //This can be triggered if we i.e. clear the local cache, but the keep the annotations.
+        //If we didn't catch this case, we end up inserting flags only for every missing message.
+        kWarning() << "Detected inconsistency in local cache, we're missing some messages. Server: " << messageCount << " Local: "<< realMessageCount;
+        kWarning() << "Refetching complete mailbox.";
+        setTotalItems(messageCount);
+        retrieveItems(KIMAP::ImapSet(1, nextUid), scope, false, true);
     } else if (nextUid > oldNextUid) {
         //New messages are available. Fetch new messages, and then check for changed flags and removed messages
         kDebug( 5327 ) << "Fetching new messages: UidNext: " << nextUid << " Old UidNext: " << oldNextUid;


commit e79f7eb869e463db0cca9a0f2915885ada6c26ac
Author: Christophe Giboudeaux <cgiboudeaux at gmx.com>
Date:   Fri May 9 21:32:00 2014 +0200

    Fix build.

diff --git a/resources/kolab/kolabhelpers.cpp b/resources/kolab/kolabhelpers.cpp
index bd3b54f..db54d49 100644
--- a/resources/kolab/kolabhelpers.cpp
+++ b/resources/kolab/kolabhelpers.cpp
@@ -24,8 +24,8 @@
 #include <Akonadi/ItemFetchJob>
 #include <Akonadi/ItemFetchScope>
 #include <akonadi/notes/noteutils.h>
-#include <kolab/kolabobject.h>
-#include <kolab/errorhandler.h>
+#include <kolabobject.h>
+#include <errorhandler.h>
 
 bool KolabHelpers::checkForErrors(const Akonadi::Item &item)
 {


commit d39e6289715efe23cd6a2e924f741d3577acb1f3
Author: Christian Mollekopf <chrigi_1 at fastmail.fm>
Date:   Fri May 9 15:37:09 2014 +0200

    IMAP-Resource: Make sure we really detatch the collection.
    
    Akonadi::Collection silently shared attributes with other copies because it
    doesn't properly detatch, because Entity::attribute is const.
    This resultet in uidnext getting modified even if the task was canceled,
    because ResourceState::cancelTask modified the original copy of the collection
    (which erroneously received the updated attributes due to the detatch bug).
    
    We now force a detatch to avoid nasty surprises.

diff --git a/resources/imap/resourcetask.cpp b/resources/imap/resourcetask.cpp
index b4c4d36..2f76423 100644
--- a/resources/imap/resourcetask.cpp
+++ b/resources/imap/resourcetask.cpp
@@ -180,9 +180,19 @@ int ResourceTask::intervalCheckTime() const
   return m_resource->intervalCheckTime();
 }
 
+static Akonadi::Collection detatchCollection(const Akonadi::Collection &collection)
+{
+  //HACK: Attributes are accessed via a const function, and the implicitly shared private pointer thus doesn't detach.
+  //We force a detach to avoid surprises. (RetrieveItemsTask used to write back the collection changes, even though the task was canceled)
+  //Once this is fixed this function can go away.
+  Akonadi::Collection col = collection;
+  col.setId(col.id());
+  return col;
+}
+
 Akonadi::Collection ResourceTask::collection() const
 {
-  return m_resource->collection();
+  return detatchCollection(m_resource->collection());
 }
 
 Akonadi::Item ResourceTask::item() const
@@ -197,17 +207,17 @@ Akonadi::Item::List ResourceTask::items() const
 
 Akonadi::Collection ResourceTask::parentCollection() const
 {
-  return m_resource->parentCollection();
+  return detatchCollection(m_resource->parentCollection());
 }
 
 Akonadi::Collection ResourceTask::sourceCollection() const
 {
-  return m_resource->sourceCollection();
+  return detatchCollection(m_resource->sourceCollection());
 }
 
 Akonadi::Collection ResourceTask::targetCollection() const
 {
-  return m_resource->targetCollection();
+  return detatchCollection(m_resource->targetCollection());
 }
 
 QSet<QByteArray> ResourceTask::parts() const


commit b492eea3e0f46bc147162ede89c528b85501e3f8
Author: Montel Laurent <montel at kde.org>
Date:   Fri May 9 13:36:32 2014 +0200

    It needs libkolab

diff --git a/resources/CMakeLists.txt b/resources/CMakeLists.txt
index d72af87..548268c 100644
--- a/resources/CMakeLists.txt
+++ b/resources/CMakeLists.txt
@@ -48,6 +48,7 @@ endif()
 macro_optional_add_subdirectory( kdeaccounts )
 if (Libkolab_FOUND AND Libkolabxml_FOUND)
     macro_optional_add_subdirectory( kolabproxy )
+    add_subdirectory( kolab )
 endif()
 
 macro_optional_add_subdirectory( localbookmarks )
@@ -75,4 +76,3 @@ add_subdirectory( vcarddir )
 add_subdirectory( icaldir )
 add_subdirectory( vcard )
 add_subdirectory( folderarchivesettings )
-add_subdirectory( kolab )
\ No newline at end of file


commit 7f32e42d81df968aea8f4a5c08dbdb1c927a4d10
Author: Christian Mollekopf <chrigi_1 at fastmail.fm>
Date:   Thu May 8 18:11:15 2014 +0200

    Kolab-Resource: Fixed build.
    
    At least I hope so....

diff --git a/resources/kolab/CMakeLists.txt b/resources/kolab/CMakeLists.txt
index dc8aba4..875950b 100644
--- a/resources/kolab/CMakeLists.txt
+++ b/resources/kolab/CMakeLists.txt
@@ -40,6 +40,13 @@ qt4_add_dbus_adaptor(kolabresource_SRCS
 
 kde4_add_kcfg_files(kolabresource_SRCS ../imap/settingsbase.kcfgc)
 
+if (KDEPIM_MOBILE_UI)
+kde4_add_ui_files(kolabresource_SRCS ../imap/setupserverview_mobile.ui)
+else ()
+kde4_add_ui_files(kolabresource_SRCS ../imap/setupserverview_desktop.ui)
+endif ()
+kde4_add_ui_files(kolabresource_SRCS ../imap/serverinfo.ui)
+
 kde4_add_executable(akonadi_kolab_resource ${kolabresource_SRCS})
 target_link_libraries(akonadi_kolab_resource
     ${KDEPIMLIBS_AKONADI_LIBS}


commit 4cc7db877677974cd292322e6d81ab57553ad710
Author: Montel Laurent <montel at kde.org>
Date:   Thu May 8 17:33:27 2014 +0200

    Add endline

diff --git a/resources/kolab/kolabhelpers.cpp b/resources/kolab/kolabhelpers.cpp
index 4896e44..bd3b54f 100644
--- a/resources/kolab/kolabhelpers.cpp
+++ b/resources/kolab/kolabhelpers.cpp
@@ -383,4 +383,5 @@ bool KolabHelpers::isHandledType(Kolab::FolderType type)
             break;
     }
     return false;
-}
\ No newline at end of file
+}
+


commit 91523bd7c3b9137a80d549ac7dde9c1f67486ef1
Author: Montel Laurent <montel at kde.org>
Date:   Thu May 8 17:32:47 2014 +0200

    Remove extra ;

diff --git a/resources/kolab/kolabretrievecollectionstask.h b/resources/kolab/kolabretrievecollectionstask.h
index 5869149..3e9a14d 100644
--- a/resources/kolab/kolabretrievecollectionstask.h
+++ b/resources/kolab/kolabretrievecollectionstask.h
@@ -53,7 +53,7 @@ private:
     void createCollection(const QString &mailbox, const QList<QByteArray> &flags);
 
     int mJobs;
-    QHash<QString, Akonadi::Collection> mMailCollections;;
+    QHash<QString, Akonadi::Collection> mMailCollections;
     QSet<QString> mSubscribedMailboxes;
 };
 




More information about the commits mailing list