[geary/wip/768422-namespace-support] Use default personal namespace when creating special folders. Bug 726866.



commit bcca3f0332d460a3716841ddcb5c95b6478270ca
Author: Michael James Gratton <mike vee net>
Date:   Fri Nov 3 13:48:36 2017 +1100

    Use default personal namespace when creating special folders. Bug 726866.
    
    * src/engine/imap/api/imap-account.vala (Account): Add
      get_default_personal_namespace() method to return a folder at the root
      of the default personal namespace.
    
    * src/engine/imap/transport/imap-client-session.vala (ClientSession):
      Make inbox and namespace attrs into RO internal properties so Account
      can access them.
    
    * src/engine/imap-engine/imap-engine-generic-account.vala
      (Account::ensure_special_folder_async): Get the default namespace
      folder and use that when checking for matching folders, rather than
      trying to guess just at the root then INBOX. If not found, assume the
      folder should be a child of the root.

 .../imap-engine/imap-engine-generic-account.vala   |   26 +++-----------
 src/engine/imap/api/imap-account.vala              |   20 +++++++++++
 src/engine/imap/transport/imap-client-session.vala |   34 +++++++++++++-------
 3 files changed, 48 insertions(+), 32 deletions(-)
---
diff --git a/src/engine/imap-engine/imap-engine-generic-account.vala 
b/src/engine/imap-engine/imap-engine-generic-account.vala
index fb381d0..3403a75 100644
--- a/src/engine/imap-engine/imap-engine-generic-account.vala
+++ b/src/engine/imap-engine/imap-engine-generic-account.vala
@@ -690,9 +690,10 @@ private abstract class Geary.ImapEngine.GenericAccount : Geary.Account {
             // This is the first time we're turning a non-special folder into a special one.
             // After we do this, we'll record which one we picked in the account info.
 
+            Geary.FolderPath root = yield remote.get_default_personal_namespace(cancellable);
             Gee.List<string> search_names = special_search_names.get(special);
             foreach (string search_name in search_names) {
-                Geary.FolderPath search_path = new Imap.FolderRoot(search_name);
+                Geary.FolderPath search_path = root.get_child(search_name);
                 foreach (Geary.FolderPath test_path in folder_map.keys) {
                     if (test_path.compare_normalized_ci(search_path) == 0) {
                         path = search_path;
@@ -702,31 +703,16 @@ private abstract class Geary.ImapEngine.GenericAccount : Geary.Account {
                 if (path != null)
                     break;
             }
-            if (path == null) {
-                foreach (string search_name in search_names) {
-                    Geary.FolderPath search_path = new Imap.FolderRoot(
-                        Imap.MailboxSpecifier.CANONICAL_INBOX_NAME).get_child(search_name);
-                    foreach (Geary.FolderPath test_path in folder_map.keys) {
-                        if (test_path.compare_normalized_ci(search_path) == 0) {
-                            path = search_path;
-                            break;
-                        }
-                    }
-                    if (path != null)
-                        break;
-                }
-            }
-            
+
             if (path == null)
-                path = new Imap.FolderRoot(search_names[0]);
-            
+                path = root.get_child(search_names[0]);
+
             information.set_special_folder_path(special, path);
             yield information.store_async(cancellable);
         }
-        
+
         if (path in folder_map.keys) {
             debug("Promoting %s to special folder %s", path.to_string(), special.to_string());
-            
             minimal_folder = folder_map.get(path);
         } else {
             debug("Creating %s to use as special folder %s", path.to_string(), special.to_string());
diff --git a/src/engine/imap/api/imap-account.vala b/src/engine/imap/api/imap-account.vala
index ef115ec..f09ebf0 100644
--- a/src/engine/imap/api/imap-account.vala
+++ b/src/engine/imap/api/imap-account.vala
@@ -77,6 +77,26 @@ private class Geary.Imap.Account : BaseObject {
         is_open = false;
     }
 
+    /**
+     * Returns the root path for the default personal namespace.
+     */
+    public async FolderPath get_default_personal_namespace(Cancellable? cancellable)
+    throws Error {
+        ClientSession session = yield claim_session_async(cancellable);
+        if (session.personal_namespaces.is_empty) {
+            throw new ImapError.INVALID("No personal namespace found");
+        }
+
+        Namespace ns = session.personal_namespaces[0];
+        string prefix = ns.prefix;
+        string? delim = ns.delim;
+        if (delim != null && prefix.has_suffix(delim)) {
+            prefix = prefix.substring(0, prefix.length - delim.length);
+        }
+
+        return new FolderRoot(prefix);
+    }
+
     public async bool folder_exists_async(FolderPath path, Cancellable? cancellable)
     throws Error {
         ClientSession session = yield claim_session_async(cancellable);
diff --git a/src/engine/imap/transport/imap-client-session.vala 
b/src/engine/imap/transport/imap-client-session.vala
index c3a7110..03721ff 100644
--- a/src/engine/imap/transport/imap-client-session.vala
+++ b/src/engine/imap/transport/imap-client-session.vala
@@ -195,7 +195,28 @@ public class Geary.Imap.ClientSession : BaseObject {
      * (specifically for IDLE support).
      */
     public Capabilities capabilities { get; private set; default = new Capabilities(0); }
-    
+
+    // While the following inbox and namespace data should be server
+    // specific, there is a small chance they will differ between
+    // connections if the connections connect to different servers in
+    // a cluster, or if configuration changes between connections. We
+    // do assume however that once connected, this information will
+    // remain the same. This information becomes current only after
+    // initiate_session_async() has successfully completed.
+
+    /** Records the actual name and delimiter used for the inbox */
+    internal MailboxInformation? inbox = null;
+
+    /** The locations personal mailboxes on this  connection. */
+    internal Gee.List<Namespace> personal_namespaces = new Gee.ArrayList<Namespace>();
+
+    /** The locations of other user's mailboxes on this connection. */
+    internal Gee.List<Namespace> user_namespaces = new Gee.ArrayList<Namespace>();
+
+    /** The locations of shared mailboxes on this connection. */
+    internal Gee.List<Namespace> shared_namespaces = new Gee.ArrayList<Namespace>();
+
+
     private Endpoint imap_endpoint;
     private Geary.State.Machine fsm;
     private ClientConnection? cx = null;
@@ -215,17 +236,6 @@ public class Geary.Imap.ClientSession : BaseObject {
     private Nonblocking.Semaphore? connect_waiter = null;
     private Error? connect_err = null;
 
-    // While the following should be server specific, there is a small
-    // chance they will differ between connections if the connections
-    // connect to different servers in a cluster, or if configuration
-    // changes between connections. We do assume however that once
-    // connected, this information will remain the same. This
-    // information becomes current only after initiate_session_async()
-    // has successfully completed.
-    private MailboxInformation? inbox = null;
-    private Gee.List<Namespace> personal_namespaces = new Gee.ArrayList<Namespace>();
-    private Gee.List<Namespace> user_namespaces = new Gee.ArrayList<Namespace>();
-    private Gee.List<Namespace> shared_namespaces = new Gee.ArrayList<Namespace>();
     private Gee.Map<string,Namespace> namespaces = new Gee.HashMap<string,Namespace>();
 
 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]