Branch 'kolab/integration/4.13.0' - 3 commits - resources/imap

Christian Mollekopf mollekopf at kolabsys.com
Fri Jun 6 10:14:25 CEST 2014


 resources/imap/retrieveitemstask.cpp                        |   17 +-
 resources/imap/setupserverview_desktop.ui                   |   14 -
 resources/imap/setupserverview_mobile.ui                    |    2 
 resources/imap/tests/testretrievecollectionmetadatatask.cpp |    2 
 resources/imap/tests/testretrieveitemstask.cpp              |   89 +++++++++++-
 5 files changed, 108 insertions(+), 16 deletions(-)

New commits:
commit c111b55298d93aae71249fdf4d43700fe434bd2e
Author: Christian Mollekopf <chrigi_1 at fastmail.fm>
Date:   Thu Jun 5 15:49:20 2014 +0200

    IMAP-Resource: Fixed detecting removed messages and clearing of empty folders.
    
    The hack for local items that have not yet been uploaded doesn't work as
    it keeps us from detecting remotely removed messages.
    
    In the case of messageCount == 0 we need to ensure m_incremental is false,
    otherwise we call both itemsRetrieved and itemsRetrievedIncremental.

diff --git a/resources/imap/retrieveitemstask.cpp b/resources/imap/retrieveitemstask.cpp
index 7c49ef3..5697fe6 100644
--- a/resources/imap/retrieveitemstask.cpp
+++ b/resources/imap/retrieveitemstask.cpp
@@ -535,11 +535,18 @@ void RetrieveItemsTask::onFinalSelectDone(KJob *job)
     * * flag changes and removals can be detected by listing all messages that weren't part of the previous step
     *
     * Everything else is optimizations.
+    *
+    * TODO: Note that the local message count can be larger than the remote message count although no messages
+    * have been deleted remotely, if we locally have messages that were not yet uploaded.
+    * We cannot differentiate that from remotely removed messages, so we have to do a full flag
+    * listing in that case. This can be optimized once we support QRESYNC and therefore have a way
+    * to determine wether messages have been removed.
     */
 
     if (messageCount == 0) {
         //Shortcut:
         //If no messages are present on the server, clear local cash and finish
+        m_incremental = false;
         if (realMessageCount > 0) {
             kDebug( 5327 ) << "No messages present so we are done, deleting local messages.";
             itemsRetrieved(Akonadi::Item::List());
@@ -565,12 +572,11 @@ 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) && realMessageCount > 0) {
+    } 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);
@@ -589,18 +595,17 @@ 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);
         //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()) {
+        //WARNING: This sacrifices consistency as we will not detect flag changes until a new message enters the mailbox.
+        if (m_incremental && !serverSupportsCondstore()) {
             kDebug(5327) << "Avoiding flag sync due to missing CONDSTORE support";
             taskComplete();
             return;
diff --git a/resources/imap/tests/testretrieveitemstask.cpp b/resources/imap/tests/testretrieveitemstask.cpp
index b22a7bc..3e2bc49 100644
--- a/resources/imap/tests/testretrieveitemstask.cpp
+++ b/resources/imap/tests/testretrieveitemstask.cpp
@@ -164,6 +164,7 @@ private slots:
     collection = createCollectionChain( QLatin1String("/INBOX/Foo") );
     collection.attribute<UidValidityAttribute>(Akonadi::Entity::AddIfMissing)->setUidValidity(1149151135);
     collection.setCachePolicy( policy );
+    stats.setCount( 1 );
     collection.setStatistics( stats );
     scenario.clear();
     scenario << defaultPoolConnectionScenario()
@@ -186,6 +187,54 @@ private slots:
     QTest::newRow( "third listing, full sync, empty folder" ) << collection << scenario << callNames;
 
     collection.attribute<UidNextAttribute>( Akonadi::Collection::AddIfMissing )->setUidNext( 8 );
+    stats.setCount( 4 );
+    collection.setStatistics( stats );
+    collection.attribute<HighestModSeqAttribute>( Akonadi::Entity::AddIfMissing )->setHighestModSeq( 123456788 );
+    scenario.clear();
+    scenario << defaultPoolConnectionScenario()
+             << "C: A000003 SELECT \"INBOX/Foo\""
+             << "S: A000003 OK select done"
+             << "C: A000004 EXPUNGE"
+             << "S: A000004 OK expunge done"
+             << "C: A000005 SELECT \"INBOX/Foo\""
+             << "S: * FLAGS (\\Answered \\Flagged \\Draft \\Deleted \\Seen)"
+             << "S: * OK [ PERMANENTFLAGS (\\Answered \\Flagged \\Draft \\Deleted \\Seen) ]"
+             << "S: * 5 EXISTS"
+             << "S: * 0 RECENT"
+             << "S: * OK [ UIDVALIDITY 1149151135  ]"
+             << "S: * OK [ UIDNEXT 9  ]"
+             << "S: * OK [ HIGHESTMODSEQ 123456789 ]"
+             << "S: A000005 OK select done"
+             << "C: A000006 UID SEARCH UID 8:9"
+             << "S: * SEARCH 8 9"
+             << "S: A000006 OK search done"
+             << "C: A000007 UID FETCH 8:9 (RFC822.SIZE INTERNALDATE BODY.PEEK[] FLAGS UID)"
+             << "S: * 5 FETCH ( FLAGS (\\Seen) UID 9 INTERNALDATE \"29-Jun-2010 15:26:42 +0200\" "
+                "RFC822.SIZE 75 BODY[] {75}\r\n"
+                "From: Foo <foo at kde.org>\r\n"
+                "To: Bar <bar at kde.org>\r\n"
+                "Subject: Test Mail\r\n"
+                "\r\n"
+                "Test\r\n"
+                " )"
+             << "S: A000007 OK fetch done"
+             << "C: A000008 UID SEARCH UID 1:7"
+             << "S: * SEARCH 1 2 3 4 5 6 7"
+             << "S: A000008 OK search done"
+             << "C: A000009 UID FETCH 1:7 (FLAGS UID)"
+             << "S: * 1 FETCH"
+             << "S: * 2 FETCH"
+             << "S: * 3 FETCH"
+             << "S: * 4 FETCH"
+             << "S: A000009 OK fetch done";
+
+    callNames.clear();
+    callNames << "itemsRetrievedIncremental" << "applyCollectionChanges" << "itemsRetrievedIncremental"<< "itemsRetrievalDone";
+
+    //We know no messages have been removed, so we can do an incremental update
+    QTest::newRow( "uidnext changed, fetch new messages incrementally" ) << collection << scenario << callNames;
+
+    collection.attribute<UidNextAttribute>( Akonadi::Collection::AddIfMissing )->setUidNext( 8 );
     stats.setCount( 5 );
     collection.setStatistics( stats );
     scenario.clear();
@@ -234,8 +283,9 @@ private slots:
              << "S: A000009 OK fetch done";
 
     callNames.clear();
-    callNames << "itemsRetrievedIncremental" << "applyCollectionChanges" << "itemsRetrievedIncremental"<< "itemsRetrievalDone";
+    callNames << "itemsRetrieved" << "applyCollectionChanges" << "itemsRetrievalDone";
 
+    //A new message has been added and an old one removed, we can't do an incremental update
     QTest::newRow( "uidnext changed, fetch new messages and list flags" ) << collection << scenario << callNames;
 
 
@@ -437,6 +487,43 @@ private slots:
 
     QTest::newRow( "test batch processing" ) << collection << scenario << callNames;
 
+    collection = createCollectionChain(QLatin1String("/INBOX/Foo") );
+    collection.attribute<UidValidityAttribute>(Akonadi::Entity::AddIfMissing)->setUidValidity(1149151135);
+    collection.setCachePolicy( policy );
+    collection.attribute<UidNextAttribute>( Akonadi::Collection::AddIfMissing )->setUidNext( 9 );
+    collection.attribute<HighestModSeqAttribute>( Akonadi::Entity::AddIfMissing )->setHighestModSeq( 123456789 );
+    stats.setCount( 5 );
+    collection.setStatistics( stats );
+    scenario.clear();
+    scenario << defaultPoolConnectionScenario( QList<QByteArray>() << "CONDSTORE" )
+             << "C: A000003 SELECT \"INBOX/Foo\" (CONDSTORE)"
+             << "S: A000003 OK select done"
+             << "C: A000004 EXPUNGE"
+             << "S: A000004 OK expunge DONE"
+             << "C: A000005 SELECT \"INBOX/Foo\" (CONDSTORE)"
+             << "S: * FLAGS (\\Answered \\Flagged \\Draft \\Deleted \\Seen)"
+             << "S: * OK [ PERMANENTFLAGS (\\Answered \\Flagged \\Draft \\Deleted \\Seen) ]"
+             << "S: * 4 EXISTS"
+             << "S: * 0 RECENT"
+             << "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"
+             << "S: A000006 OK search done"
+             << "C: A000007 UID FETCH 1:4 (FLAGS UID)"
+             << "S: * 1 FETCH ( FLAGS (\\Seen) UID 1 )"
+             << "S: * 2 FETCH ( FLAGS (\\Seen) UID 2 )"
+             << "S: * 3 FETCH ( FLAGS (\\Seen) UID 3 )"
+             << "S: * 4 FETCH ( FLAGS (\\Seen) UID 4 )"
+             << "S: A000007 OK fetch done";
+    callNames.clear();
+    callNames << "itemsRetrieved" << "applyCollectionChanges" << "itemsRetrievalDone";
+
+    //fetch only changed flags
+    QTest::newRow( "remote message deleted" ) << collection << scenario << callNames;
+
   }
 
   void shouldIntrospectCollection()


commit 8914c8dd608f388eebf617affe50bea865d50cc1
Author: Christian Mollekopf <chrigi_1 at fastmail.fm>
Date:   Mon Jun 2 15:30:59 2014 +0200

    IMAP-Resource: Fixed TestRetrieveCollectionMetadataTask
    
    Adapted to to kimap change that fixed the GETMETADATA command.

diff --git a/resources/imap/tests/testretrievecollectionmetadatatask.cpp b/resources/imap/tests/testretrievecollectionmetadatatask.cpp
index c6113f8..ce0b027 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 (DEPTH infinity) \"INBOX/Foo\" (/shared)"
+             << "C: A000003 GETMETADATA \"INBOX/Foo\" (DEPTH infinity) (/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\")"


commit cc981f8e001525f7e4c4079b4a21f68bfbea27cf
Author: Dan Vrátil <dvratil at redhat.com>
Date:   Wed May 28 13:18:31 2014 +0200

    IMAP-Resource: Rename and move 'Enable Disconnected Mode' option
    
    Rename "Enable Disconnected Mode" to "Download all messages for offline use",
    which is a much better description of the feature and move it to the "General"
    tab, as this should not be hidden from users in the "Advanced" tab.
    
    REVIEW: 118363

diff --git a/resources/imap/setupserverview_desktop.ui b/resources/imap/setupserverview_desktop.ui
index eb749ee..92a35ab 100644
--- a/resources/imap/setupserverview_desktop.ui
+++ b/resources/imap/setupserverview_desktop.ui
@@ -115,6 +115,13 @@
          </property>
          <layout class="QVBoxLayout" name="verticalLayout_6">
           <item>
+           <widget class="QCheckBox" name="disconnectedModeEnabled">
+            <property name="text">
+             <string>&Download all messages for offline use</string>
+            </property>
+           </widget>
+          </item>
+          <item>
            <widget class="QCheckBox" name="enableMailCheckBox">
             <property name="text">
              <string>Enable &interval mail checking</string>
@@ -353,13 +360,6 @@
            </layout>
           </item>
           <item>
-           <widget class="QCheckBox" name="disconnectedModeEnabled">
-            <property name="text">
-             <string>Enable disconnected mode</string>
-            </property>
-           </widget>
-          </item>
-          <item>
            <widget class="QCheckBox" name="autoExpungeCheck">
             <property name="text">
              <string>Automaticall&y compact folders (expunges deleted messages)</string>
diff --git a/resources/imap/setupserverview_mobile.ui b/resources/imap/setupserverview_mobile.ui
index 135ca16..4760fec 100644
--- a/resources/imap/setupserverview_mobile.ui
+++ b/resources/imap/setupserverview_mobile.ui
@@ -308,7 +308,7 @@ p, li { white-space: pre-wrap; }
        <item>
         <widget class="QCheckBox" name="disconnectedModeEnabled">
          <property name="text">
-          <string>Enable Disconnected Mode</string>
+          <string>&Download all messages for offline use</string>
          </property>
         </widget>
        </item>




More information about the commits mailing list