[geary/mjog/email-templates] Geary.Account: Support creating folders in the personal name space



commit 621232b6f23915e57de822819b56ffb374f9a50c
Author: Michael Gratton <mike vee net>
Date:   Wed Apr 22 19:05:47 2020 +1000

    Geary.Account: Support creating folders in the personal name space
    
    Add `create_personal_folder` method, implement it in
    ImapEngine.GenericAccount. Use this when creating required special
    folders to reduce code duplication.

 src/engine/api/geary-account.vala                  | 12 ++++
 .../imap-engine/imap-engine-generic-account.vala   | 83 +++++++++++-----------
 test/engine/api/geary-account-mock.vala            | 12 ++++
 3 files changed, 67 insertions(+), 40 deletions(-)
---
diff --git a/src/engine/api/geary-account.vala b/src/engine/api/geary-account.vala
index 0a234e28..e08f9cc0 100644
--- a/src/engine/api/geary-account.vala
+++ b/src/engine/api/geary-account.vala
@@ -406,6 +406,18 @@ public abstract class Geary.Account : BaseObject, Logging.Source {
         GLib.Cancellable? cancellable = null
     ) throws GLib.Error;
 
+    /**
+     * Creates a new folder in the root of the personal name space.
+     *
+     * If this account is backed by a remote server, calling this
+     * causes the folder to be created on the remote.
+     */
+    public abstract async Folder create_personal_folder(
+        string name,
+        Folder.SpecialUse use = NONE,
+        GLib.Cancellable? cancellable = null
+    ) throws GLib.Error;
+
     /**
      * Search the local account for emails referencing a Message-ID value
      * (which can appear in the Message-ID header itself, as well as the
diff --git a/src/engine/imap-engine/imap-engine-generic-account.vala 
b/src/engine/imap-engine/imap-engine-generic-account.vala
index bb550fb4..1bce766e 100644
--- a/src/engine/imap-engine/imap-engine-generic-account.vala
+++ b/src/engine/imap-engine/imap-engine-generic-account.vala
@@ -447,6 +447,41 @@ private abstract class Geary.ImapEngine.GenericAccount : Geary.Account {
         return folder;
     }
 
+    /** {@inheritDoc} */
+    public override async Folder create_personal_folder(
+        string name,
+        Folder.SpecialUse use = NONE,
+        GLib.Cancellable? cancellable = null
+    ) throws GLib.Error {
+        check_open();
+        var remote = yield claim_account_session(cancellable);
+        FolderPath root =
+            yield remote.get_default_personal_namespace(cancellable);
+        FolderPath path = root.get_child(name);
+        if (this.folder_map.has_key(path)) {
+            throw new EngineError.ALREADY_EXISTS(
+                "Folder already exists: %s", path.to_string()
+            );
+        }
+        yield remote.create_folder_async(path, use, cancellable);
+
+        Imap.Folder? remote_folder = yield remote.fetch_folder_async(
+            path, cancellable
+        );
+
+        ImapDB.Folder local_folder = yield this.local.clone_folder_async(
+            remote_folder, cancellable
+        );
+        add_folders(Collection.single(local_folder), false);
+        var folder = this.folder_map.get(path);
+        if (use != NONE) {
+            promote_folders(
+                Collection.single_map<Folder.SpecialUse,Folder>(use, folder)
+            );
+        }
+        return folder;
+    }
+
     private ImapDB.EmailIdentifier check_id(Geary.EmailIdentifier id) throws EngineError {
         ImapDB.EmailIdentifier? imapdb_id = id as ImapDB.EmailIdentifier;
         if (imapdb_id == null)
@@ -699,50 +734,18 @@ private abstract class Geary.ImapEngine.GenericAccount : Geary.Account {
                 );
             }
 
-            if (!this.folder_map.has_key(path)) {
+            if (this.folder_map.has_key(path)) {
+                special = this.folder_map.get(path);
+                promote_folders(
+                    Collection.single_map<Folder.SpecialUse,Folder>(use, special)
+                );
+            } else {
                 debug("Creating \"%s\" to use as special folder %s",
                       path.to_string(), use.to_string());
-
-                GLib.Error? created_err = null;
-                try {
-                    yield remote.create_folder_async(path, use, cancellable);
-                } catch (GLib.Error err) {
-                    // Hang on to the error since the folder might exist
-                    // on the remote, so try fetching it anyway.
-                    created_err = err;
-                }
-
-                Imap.Folder? remote_folder = null;
-                try {
-                    remote_folder = yield remote.fetch_folder_async(
-                        path, cancellable
-                    );
-                } catch (GLib.Error err) {
-                    // If we couldn't fetch it after also failing to
-                    // create it, it's probably due to the problem
-                    // creating it, so throw that error instead.
-                    if (created_err != null) {
-                        throw created_err;
-                    } else {
-                        throw err;
-                    }
-                }
-
-                ImapDB.Folder local_folder =
-                    yield this.local.clone_folder_async(
-                        remote_folder, cancellable
-                    );
-                add_folders(
-                    Collection.single(local_folder), created_err != null
+                special = yield create_personal_folder(
+                    path.name, use, cancellable
                 );
             }
-
-            special= this.folder_map.get(path);
-            promote_folders(
-                Collection.single_map<Folder.SpecialUse,Folder>(
-                    use, special
-                )
-            );
         }
 
         return special;
diff --git a/test/engine/api/geary-account-mock.vala b/test/engine/api/geary-account-mock.vala
index b39ad115..d2a6cae5 100644
--- a/test/engine/api/geary-account-mock.vala
+++ b/test/engine/api/geary-account-mock.vala
@@ -107,6 +107,18 @@ public class Geary.MockAccount : Account, MockObject {
         }
     }
 
+    public override async Folder create_personal_folder(
+        string name,
+        Folder.SpecialUse use = NONE,
+        GLib.Cancellable? cancellable = null
+    ) throws GLib.Error {
+        return object_call<Folder>(
+            "create_personal_folder",
+            { box_arg(name), box_arg(use), cancellable },
+            new MockFolder(null, null, null, use, null)
+        );
+    }
+
     public override EmailIdentifier to_email_identifier(GLib.Variant serialised)
         throws EngineError.BAD_PARAMETERS {
         try {


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