Bug 111624 - Cannot create folder with disconnected IMAP
Summary: Cannot create folder with disconnected IMAP
Status: RESOLVED FIXED
Alias: None
Product: kmail
Classification: Applications
Component: general (show other bugs)
Version: unspecified
Platform: Compiled Sources Linux
: NOR normal
Target Milestone: ---
Assignee: kdepim bugs
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2005-08-28 00:55 UTC by Szombathelyi György
Modified: 2007-09-14 12:17 UTC (History)
0 users

See Also:
Latest Commit:
Version Fixed In:


Attachments
Debug log for the still existing bug. (3.84 KB, text/plain)
2005-09-05 21:42 UTC, Szombathelyi György
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Szombathelyi György 2005-08-28 00:55:14 UTC
Version:            (using KDE Devel)
Installed from:    Compiled sources
Compiler:          gcc 4.0.1 
OS:                Linux

When I try to create an IMAP folder with kmail using a disconnected IMAP account, the creation always fail after I try to sync to the server (Cyrus 2.2.10). Online IMAP works.

Here's the log from kio_imap:
kio_imap: IMAP4::mkdir - imap://gyuri@localhost:143/INBOX/kde
kio_imap: imapParser::parseURL /INBOX/kde
kio_imap: URL: box= INBOX/kde, section= , type= , uid= , validity= , info=
kio_imap: imapParse::namespaceForBox INBOX/kde
kio_imap: IMAP4::parseURL - namespace=INBOX
kio_imap: IMAP4::parseURL - delimiter=.
kio_imap: IMAP4::parseURL - box=INBOX/kde
kio_imap: IMAP4::parseURL - return 0
kio_imap: IMAP4::mkdir - create INBOX/kde
kio_imap: IMAP4::mkdir - Invalid mailbox name

When I do the same with online-imap, the debugging info:
kio_imap: IMAP4::mkdir - imap://gyuri@localhost:143/INBOX.kde/;INFO=ASKUSER
kio_imap: imapParser::parseURL /INBOX.kde/;INFO=ASKUSER
kio_imap: URL: box= INBOX.kde, section= , type= , uid= , validity= , info= ASKUSER
kio_imap: imapParse::namespaceForBox INBOX.kde
kio_imap: IMAP4::parseURL - namespace=INBOX
kio_imap: IMAP4::parseURL - delimiter=.
kio_imap: IMAP4::parseURL - box=INBOX.kde
kio_imap: IMAP4::parseURL - return 0
kio_imap: IMAP4::mkdir - create INBOX.kde
kio_imap: imapParser::parseURL /INBOX.kde/;INFO=ASKUSER
kio_imap: URL: box= INBOX.kde, section= , type= , uid= , validity= , info= ASKUSER
kio_imap: imapParse::namespaceForBox INBOX.kde
kio_imap: IMAP4::parseURL - namespace=INBOX
kio_imap: IMAP4::parseURL - delimiter=.
kio_imap: IMAP4::parseURL - box=INBOX.kde
kio_imap: IMAP4::parseURL - return 3
kio_imap: IMAP4::dispatch - command=80
kio_imap: IMAP4::dispatch - command=71


So the problem is that the folder delimiter is wrong with d-imap.
Comment 1 Carsten Burghardt 2005-08-30 22:24:00 UTC
SVN commit 455223 by burghard:

Use the correct delimiter for disconnected imap. Refactor this stuff a bit to make the creation of
imapPaths easier.
BUGS: 111624


 M  +44 -0     imapaccountbase.cpp  
 M  +14 -1     imapaccountbase.h  
 M  +1 -14     kmfolderimap.cpp  
 M  +3 -3      newfolderdialog.cpp  


--- branches/KDE/3.5/kdepim/kmail/imapaccountbase.cpp #455222:455223
@@ -1263,6 +1263,50 @@
     return map;
   }
 
+  //------------------------------------------------------------------------------
+  QString ImapAccountBase::createImapPath( const QString& parent, 
+                                           const QString& folderName )
+  {
+    QString newName = parent;
+    // strip / at the end
+    if ( newName.endsWith("/") ) {
+      newName = newName.left( newName.length() - 1 );
+    }
+    // add correct delimiter
+    QString delim = delimiterForNamespace( parent );
+    // should not happen...
+    if ( delim.isEmpty() ) {
+      delim = "/";
+    }
+    if ( !newName.endsWith( delim ) && !folderName.startsWith( delim ) ) {
+      newName = newName + delim;
+    }
+    newName = newName + folderName;
+    // add / at the end
+    if ( !newName.endsWith("/") ) {
+      newName = newName + "/";
+    }
+
+    return newName;
+  }
+
+  //------------------------------------------------------------------------------
+  QString ImapAccountBase::createImapPath( FolderStorage* parent, 
+                                           const QString& folderName )
+  {
+    QString path;
+    if ( parent->folderType() == KMFolderTypeImap ) {
+      path = static_cast<KMFolderImap*>( parent )->imapPath();
+    } else if ( parent->folderType() == KMFolderTypeCachedImap ) {
+      path = static_cast<KMFolderCachedImap*>( parent )->imapPath();
+    } else {
+      // error
+      return path;
+    }
+    
+    return createImapPath( path, folderName );
+  }
+
 } // namespace KMail
 
 #include "imapaccountbase.moc"
--- branches/KDE/3.5/kdepim/kmail/imapaccountbase.h #455222:455223
@@ -352,8 +352,21 @@
       * Returns true if the account has the given capability
       */
      bool hasCapability( const QString& capa ) {
-      return mCapabilities.contains( capa ); } 
+      return mCapabilities.contains( capa ); }
 
+     /**
+      * Create an IMAP path for a parent folder and a foldername
+      * Parent and folder are separated with the delimiter of the account
+      * The path starts and ends with '/' 
+      */
+     QString createImapPath( FolderStorage* parent, const QString& folderName );
+
+     /**
+      * Create an IMAP path for a parent imapPath and a folderName
+      */
+     QString createImapPath( const QString& parent, const QString& folderName );
+
+
   public slots:
     /**
      * Call this to get the namespaces
--- branches/KDE/3.5/kdepim/kmail/kmfolderimap.cpp #455222:455223
@@ -1622,20 +1622,7 @@
   }
   KURL url = mAccount->getUrl();
   QString parent = ( parentPath.isEmpty() ? imapPath() : parentPath );
-  if ( parent.endsWith("/") ) {
-    // strip / (which kmail uses this internally)
-    parent = parent.left( parent.length()-1 );
-  }
-  QString delim = mAccount->delimiterForFolder( this );
-  if ( delim.isEmpty() ) {
-    // better be safe
-    delim = "/";
-  }
-  if ( !parent.endsWith(delim) ) {
-    // add the correct delimiter
-    parent += delim;
-  }
-  QString path = parent + name;
+  QString path = mAccount->createImapPath( parent, name );
   if ( askUser ) {
     path += "/;INFO=ASKUSER";
   }
--- branches/KDE/3.5/kdepim/kmail/newfolderdialog.cpp #455222:455223
@@ -250,7 +250,7 @@
         if ( mNamespacesComboBox ) {
           // create folder with namespace
           parent = anAccount->addPathToNamespace( mNamespacesComboBox->currentText() );
-          imapPath = anAccount->addPathToNamespace( parent ) + fldName;
+          imapPath = anAccount->createImapPath( parent, fldName );
         }
         KMFolderImap* newStorage = static_cast<KMFolderImap*>( newFolder->storage() );
         selectedStorage->createFolder(fldName, parent); // create it on the server
@@ -267,8 +267,8 @@
       newStorage->initializeFrom( selectedStorage );
       if ( mNamespacesComboBox ) {
         // create folder with namespace
-        QString path = selectedStorage->account()->addPathToNamespace(
-            mNamespacesComboBox->currentText() ) + fldName;
+        QString path = selectedStorage->account()->createImapPath( 
+            mNamespacesComboBox->currentText(), fldName );
         newStorage->setImapPathForCreation( path );
       }
       success = true;
Comment 2 Szombathelyi György 2005-09-05 21:42:27 UTC
Created attachment 12483 [details]
Debug log for the still existing bug.

The bug still exists. Here's the log where I try to create a folder "newfolder"
on an empty dimap account. Now I receive the "file or folder does not exists:
;TYPE=LIST" error message on the sync attempt (#90144), and the delimiter still
wrong.
Comment 3 Carsten Burghardt 2005-09-06 23:27:10 UTC
SVN commit 457883 by burghard:

I did not see this part where the path for disconnected imap folders is build.
And try harder to find the correct delimiter.
CCMAIL: 111624@bugs.kde.org


 M  +2 -1      cachedimapjob.cpp  
 M  +8 -2      imapaccountbase.cpp  


--- branches/KDE/3.5/kdepim/kmail/cachedimapjob.cpp #457882:457883
@@ -528,7 +528,8 @@
   KMFolderCachedImap *folder = mFolderList.front();
   mFolderList.pop_front();
   KURL url = mAccount->getUrl();
-  QString path = mFolder->imapPath() + folder->folder()->name();
+  QString path = mAccount->createImapPath( mFolder->imapPath(), 
+      folder->folder()->name() );
   if ( !folder->imapPathForCreation().isEmpty() ) {
     // the folder knows it's namespace
     path = folder->imapPathForCreation();
--- branches/KDE/3.5/kdepim/kmail/imapaccountbase.cpp #457882:457883
@@ -762,6 +762,7 @@
   //-----------------------------------------------------------------------------
   QString ImapAccountBase::delimiterForNamespace( const QString& prefix )
   {
+    kdDebug(5006) << "delimiterForNamespace " << prefix << endl;
     // try to match exactly
     if ( mNamespaceToDelimiter.contains(prefix) ) {
       return mNamespaceToDelimiter[prefix];
@@ -772,7 +773,11 @@
     for ( namespaceDelim::ConstIterator it = mNamespaceToDelimiter.begin(); 
           it != mNamespaceToDelimiter.end(); ++it )
     {
-      if ( !it.key().isEmpty() && prefix.contains( it.key() ) ) {
+      // the namespace definition sometimes contains the delimiter
+      // make sure we also match this version
+      QString stripped = it.key().left( it.key().length() - 1 );
+      if ( !it.key().isEmpty() && 
+          ( prefix.contains( it.key() ) || prefix.contains( stripped ) ) ) {
         return it.data();
       }
     }
@@ -781,6 +786,7 @@
       return mNamespaceToDelimiter[QString::null];
     }
     // well, we tried
+    kdDebug(5006) << "delimiterForNamespace - not found" << endl;
     return QString::null;
   }
 
@@ -1273,7 +1279,7 @@
       newName = newName.left( newName.length() - 1 );
     }
     // add correct delimiter
-    QString delim = delimiterForNamespace( parent );
+    QString delim = delimiterForNamespace( newName );
     // should not happen...
     if ( delim.isEmpty() ) {
       delim = "/";
Comment 4 Szombathelyi György 2005-09-07 22:21:11 UTC
Thanks, I confirm that the bug is fixed now. Only the dreaded ";TYPE=LIST" remained, which I can always reproduce. I'll post additional info to #90144