[geary/wip/721790-gmail-delete] Hook it all up the right way with Gmail's various folder types



commit eae4d68e1533f1ac21f0515841349ca8769abef4
Author: Jim Nelson <jim yorba org>
Date:   Fri Jan 9 14:39:52 2015 -0800

    Hook it all up the right way with Gmail's various folder types

 src/CMakeLists.txt                                 |    3 ++
 .../gmail/imap-engine-gmail-account.vala           |    7 +++-
 .../gmail/imap-engine-gmail-all-mail-folder.vala   |   21 +++++++++++++
 .../gmail/imap-engine-gmail-drafts-folder.vala     |   29 ++++++++++++++++++
 .../gmail/imap-engine-gmail-folder.vala            |   32 +++++++++++--------
 .../gmail/imap-engine-gmail-spam-trash-folder.vala |   23 ++++++++++++++
 6 files changed, 99 insertions(+), 16 deletions(-)
---
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 251b3b0..64fb8d6 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -193,8 +193,11 @@ engine/imap-engine/imap-engine-replay-operation.vala
 engine/imap-engine/imap-engine-replay-queue.vala
 engine/imap-engine/imap-engine-send-replay-operation.vala
 engine/imap-engine/gmail/imap-engine-gmail-account.vala
+engine/imap-engine/gmail/imap-engine-gmail-all-mail-folder.vala
+engine/imap-engine/gmail/imap-engine-gmail-drafts-folder.vala
 engine/imap-engine/gmail/imap-engine-gmail-folder.vala
 engine/imap-engine/gmail/imap-engine-gmail-search-folder.vala
+engine/imap-engine/gmail/imap-engine-gmail-spam-trash-folder.vala
 engine/imap-engine/other/imap-engine-other-account.vala
 engine/imap-engine/other/imap-engine-other-folder.vala
 engine/imap-engine/outlook/imap-engine-outlook-account.vala
diff --git a/src/engine/imap-engine/gmail/imap-engine-gmail-account.vala 
b/src/engine/imap-engine/gmail/imap-engine-gmail-account.vala
index d409efc..7e4ba31 100644
--- a/src/engine/imap-engine/gmail/imap-engine-gmail-account.vala
+++ b/src/engine/imap-engine/gmail/imap-engine-gmail-account.vala
@@ -36,13 +36,16 @@ private class Geary.ImapEngine.GmailAccount : Geary.ImapEngine.GenericAccount {
         
         switch (special_folder_type) {
             case SpecialFolderType.ALL_MAIL:
-                return new MinimalFolder(this, remote_account, local_account, local_folder,
+                return new GmailAllMailFolder(this, remote_account, local_account, local_folder,
                     special_folder_type);
             
             case SpecialFolderType.DRAFTS:
+                return new GmailDraftsFolder(this, remote_account, local_account, local_folder,
+                    special_folder_type);
+            
             case SpecialFolderType.SPAM:
             case SpecialFolderType.TRASH:
-                return new GenericFolder(this, remote_account, local_account, local_folder,
+                return new GmailSpamTrashFolder(this, remote_account, local_account, local_folder,
                     special_folder_type);
             
             default:
diff --git a/src/engine/imap-engine/gmail/imap-engine-gmail-all-mail-folder.vala 
b/src/engine/imap-engine/gmail/imap-engine-gmail-all-mail-folder.vala
new file mode 100644
index 0000000..ce46e75
--- /dev/null
+++ b/src/engine/imap-engine/gmail/imap-engine-gmail-all-mail-folder.vala
@@ -0,0 +1,21 @@
+/* Copyright 2015 Yorba Foundation
+ *
+ * This software is licensed under the GNU Lesser General Public License
+ * (version 2.1 or later).  See the COPYING file in this distribution.
+ */
+
+/**
+ * Gmail's All Mail folder supports basic operations as well as true removal of emails.
+ */
+
+private class Geary.ImapEngine.GmailAllMailFolder : MinimalFolder, FolderSupport.Remove {
+    public GmailAllMailFolder(GmailAccount account, Imap.Account remote, ImapDB.Account local,
+        ImapDB.Folder local_folder, SpecialFolderType special_folder_type) {
+        base (account, remote, local, local_folder, special_folder_type);
+    }
+    
+    public async void remove_email_async(Gee.List<Geary.EmailIdentifier> email_ids,
+        Cancellable? cancellable = null) throws Error {
+        yield GmailFolder.true_remove_email_async(this, email_ids, cancellable);
+    }
+}
diff --git a/src/engine/imap-engine/gmail/imap-engine-gmail-drafts-folder.vala 
b/src/engine/imap-engine/gmail/imap-engine-gmail-drafts-folder.vala
new file mode 100644
index 0000000..57ea1df
--- /dev/null
+++ b/src/engine/imap-engine/gmail/imap-engine-gmail-drafts-folder.vala
@@ -0,0 +1,29 @@
+/* Copyright 2015 Yorba Foundation
+ *
+ * This software is licensed under the GNU Lesser General Public License
+ * (version 2.1 or later).  See the COPYING file in this distribution.
+ */
+
+/**
+ * Gmail's Drafts folder supports basic operations as well as true removal of messages and creating
+ * new ones (IMAP APPEND).
+ */
+
+private class Geary.ImapEngine.GmailDraftsFolder : MinimalFolder, FolderSupport.Create,
+    FolderSupport.Remove {
+    public GmailDraftsFolder(GmailAccount account, Imap.Account remote, ImapDB.Account local,
+        ImapDB.Folder local_folder, SpecialFolderType special_folder_type) {
+        base (account, remote, local, local_folder, special_folder_type);
+    }
+    
+    public new async Geary.EmailIdentifier? create_email_async(
+        RFC822.Message rfc822, Geary.EmailFlags? flags, DateTime? date_received,
+        Geary.EmailIdentifier? id, Cancellable? cancellable = null) throws Error {
+        return yield base.create_email_async(rfc822, flags, date_received, id, cancellable);
+    }
+    
+    public async void remove_email_async(Gee.List<Geary.EmailIdentifier> email_ids,
+        Cancellable? cancellable = null) throws Error {
+        yield GmailFolder.true_remove_email_async(this, email_ids, cancellable);
+    }
+}
diff --git a/src/engine/imap-engine/gmail/imap-engine-gmail-folder.vala 
b/src/engine/imap-engine/gmail/imap-engine-gmail-folder.vala
index 6f73415..6520d9e 100644
--- a/src/engine/imap-engine/gmail/imap-engine-gmail-folder.vala
+++ b/src/engine/imap-engine/gmail/imap-engine-gmail-folder.vala
@@ -24,42 +24,46 @@ private class Geary.ImapEngine.GmailFolder : MinimalFolder, FolderSupport.Archiv
     
     public async void remove_email_async(Gee.List<Geary.EmailIdentifier> email_ids,
         Cancellable? cancellable = null) throws Error {
-        // Gmail offers no direct path via IMAP to delete a message from the server ... must move
-        // the message to the Trash folder, then delete it there
-        
+        yield true_remove_email_async(this, email_ids, cancellable);
+    }
+    
+    /**
+     * Truly removes an email from Gmail by moving it to the Trash and then deleting it from the
+     * Trash.
+     */
+    public static async void true_remove_email_async(MinimalFolder folder,
+        Gee.List<Geary.EmailIdentifier> email_ids, Cancellable? cancellable) throws Error {
         // Get path to Trash folder
-        Geary.Folder? trash = account.get_special_folder(SpecialFolderType.TRASH);
+        Geary.Folder? trash = folder.account.get_special_folder(SpecialFolderType.TRASH);
         if (trash == null)
-            throw new EngineError.NOT_FOUND("%s: Trash folder not found for removal", to_string());
+            throw new EngineError.NOT_FOUND("%s: Trash folder not found for removal", folder.to_string());
         
         // Copy to Trash, collect UIDs (note that copying to Trash is like a move; the copied
         // messages are removed from all labels)
-        Gee.Set<Imap.UID>? uids = yield copy_email_uids_async(email_ids, trash.path, cancellable);
+        Gee.Set<Imap.UID>? uids = yield folder.copy_email_uids_async(email_ids, trash.path, cancellable);
         if (uids == null || uids.size == 0)
             return;
         
-        debug("COPIED, %d UIDS", uids.size);
-        
         // For speed reasons, use a detched Imap.Folder object to delete moved emails; this is a
         // separate connection and is not synchronized with the database, but also avoids a full
         // folder normalization, which can be a heavyweight operation
-        Imap.Folder imap_trash = yield ((GenericAccount) account).fetch_detached_folder_async(trash.path,
-            cancellable);
-        
-        debug("FETCHED DETACHED FOLDER");
+        Imap.Folder imap_trash = yield ((GenericAccount) folder.account).fetch_detached_folder_async(
+            trash.path, cancellable);
         
         yield imap_trash.open_async(cancellable);
         try {
-            debug("REMOVING FROM TRASH");
             yield imap_trash.remove_email_async(Imap.MessageSet.uid_sparse(uids), cancellable);
-            debug("REMOVED FROM TRASH");
         } finally {
             try {
+                // don't use cancellable, need to close this connection no matter what
                 yield imap_trash.close_async(null);
             } catch (Error err) {
                 // ignored
             }
         }
+        
+        debug("%s: Successfully true-removed %d/%d emails", folder.to_string(), uids.size,
+            email_ids.size);
     }
 }
 
diff --git a/src/engine/imap-engine/gmail/imap-engine-gmail-spam-trash-folder.vala 
b/src/engine/imap-engine/gmail/imap-engine-gmail-spam-trash-folder.vala
new file mode 100644
index 0000000..8583eaf
--- /dev/null
+++ b/src/engine/imap-engine/gmail/imap-engine-gmail-spam-trash-folder.vala
@@ -0,0 +1,23 @@
+/* Copyright 2015 Yorba Foundation
+ *
+ * This software is licensed under the GNU Lesser General Public License
+ * (version 2.1 or later).  See the COPYING file in this distribution.
+ */
+
+/**
+ * Gmail's Spam and Trash folders support basic operations and removing messages with a traditional
+ * IMAP STORE/EXPUNGE operation.
+ */
+
+private class Geary.ImapEngine.GmailSpamTrashFolder : MinimalFolder, FolderSupport.Remove {
+    public GmailSpamTrashFolder(GmailAccount account, Imap.Account remote, ImapDB.Account local,
+        ImapDB.Folder local_folder, SpecialFolderType special_folder_type) {
+        base (account, remote, local, local_folder, special_folder_type);
+    }
+    
+    public async void remove_email_async(Gee.List<Geary.EmailIdentifier> email_ids,
+        Cancellable? cancellable = null) throws Error {
+        yield expunge_email_async(email_ids, cancellable);
+    }
+}
+


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