[geary/wip/768422-namespace-support: 2/6] Add initial NAMESPACE command, response and console support.



commit 53dd5a5f69a925db3feb2c5e3ed06474a7fc2889
Author: Michael James Gratton <mike vee net>
Date:   Thu Jul 7 01:32:05 2016 +1000

    Add initial NAMESPACE command, response and console support.
    
    Bug 768422

 po/POTFILES.in                                     |    3 +
 src/CMakeLists.txt                                 |    3 +
 src/console/main.vala                              |   25 ++++++-
 .../imap/command/imap-namespace-command.vala       |   24 ++++++
 src/engine/imap/message/imap-namespace.vala        |   29 +++++++
 src/engine/imap/response/imap-capabilities.vala    |    3 +-
 .../imap/response/imap-namespace-response.vala     |   83 ++++++++++++++++++++
 .../imap/response/imap-server-data-type.vala       |   14 +++-
 src/engine/imap/response/imap-server-data.vala     |   14 +++-
 9 files changed, 192 insertions(+), 6 deletions(-)
---
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 271ab79..eb636b7 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -191,6 +191,7 @@ src/engine/imap/command/imap-list-return-parameter.vala
 src/engine/imap/command/imap-login-command.vala
 src/engine/imap/command/imap-logout-command.vala
 src/engine/imap/command/imap-message-set.vala
+src/engine/imap/command/imap-namespace-command.vala
 src/engine/imap/command/imap-noop-command.vala
 src/engine/imap/command/imap-search-command.vala
 src/engine/imap/command/imap-search-criteria.vala
@@ -275,6 +276,7 @@ src/engine/imap/message/imap-mailbox-specifier.vala
 src/engine/imap/message/imap-message-data.vala
 src/engine/imap/message/imap-message-flag.vala
 src/engine/imap/message/imap-message-flags.vala
+src/engine/imap/message/imap-namespace.vala
 src/engine/imap/message/imap-sequence-number.vala
 src/engine/imap/message/imap-status-data-type.vala
 src/engine/imap/message/imap-tag.vala
@@ -297,6 +299,7 @@ src/engine/imap/response/imap-fetched-data.vala
 src/engine/imap/response/imap-mailbox-attribute.vala
 src/engine/imap/response/imap-mailbox-attributes.vala
 src/engine/imap/response/imap-mailbox-information.vala
+src/engine/imap/response/imap-namespace-response.vala
 src/engine/imap/response/imap-response-code-type.vala
 src/engine/imap/response/imap-response-code.vala
 src/engine/imap/response/imap-server-data-type.vala
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 218f525..ca97d35 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -108,6 +108,7 @@ engine/imap/command/imap-list-return-parameter.vala
 engine/imap/command/imap-login-command.vala
 engine/imap/command/imap-logout-command.vala
 engine/imap/command/imap-message-set.vala
+engine/imap/command/imap-namespace-command.vala
 engine/imap/command/imap-noop-command.vala
 engine/imap/command/imap-search-command.vala
 engine/imap/command/imap-search-criteria.vala
@@ -128,6 +129,7 @@ engine/imap/message/imap-mailbox-parameter.vala
 engine/imap/message/imap-message-data.vala
 engine/imap/message/imap-message-flag.vala
 engine/imap/message/imap-message-flags.vala
+engine/imap/message/imap-namespace.vala
 engine/imap/message/imap-sequence-number.vala
 engine/imap/message/imap-status-data-type.vala
 engine/imap/message/imap-tag.vala
@@ -150,6 +152,7 @@ engine/imap/response/imap-fetched-data.vala
 engine/imap/response/imap-mailbox-attribute.vala
 engine/imap/response/imap-mailbox-attributes.vala
 engine/imap/response/imap-mailbox-information.vala
+engine/imap/response/imap-namespace-response.vala
 engine/imap/response/imap-response-code.vala
 engine/imap/response/imap-response-code-type.vala
 engine/imap/response/imap-server-data.vala
diff --git a/src/console/main.vala b/src/console/main.vala
index 1523d66..179dfd4 100644
--- a/src/console/main.vala
+++ b/src/console/main.vala
@@ -88,6 +88,7 @@ class ImapConsole : Gtk.Window {
         "logout",
         "id",
         "bye",
+        "namespace",
         "list",
         "xlist",
         "examine",
@@ -166,7 +167,11 @@ class ImapConsole : Gtk.Window {
                     case "id":
                         id(cmd, args);
                     break;
-                    
+
+                    case "namespace":
+                        namespace(cmd, args);
+                    break;
+
                     case "list":
                     case "xlist":
                         list(cmd, args);
@@ -433,7 +438,23 @@ class ImapConsole : Gtk.Window {
             exception(err);
         }
     }
-    
+
+    private void namespace(string cmd, string[] args) throws Error {
+        check_connected(cmd, args, 0, null);
+
+        status("Retrieving NAMESPACE...");
+        cx.send_async.begin(new Geary.Imap.NamespaceCommand(), null, on_namespace);
+    }
+
+    private void on_namespace(Object? source, AsyncResult result) {
+        try {
+            cx.send_async.end(result);
+            status("Retrieved NAMESPACE");
+        } catch (Error err) {
+            exception(err);
+        }
+    }
+
     private void list(string cmd, string[] args) throws Error {
         check_connected(cmd, args, 2, "<reference> <mailbox>");
         
diff --git a/src/engine/imap/command/imap-namespace-command.vala 
b/src/engine/imap/command/imap-namespace-command.vala
new file mode 100644
index 0000000..2402d46
--- /dev/null
+++ b/src/engine/imap/command/imap-namespace-command.vala
@@ -0,0 +1,24 @@
+/*
+ * Copyright 2016 Michael Gratton <mike vee net>
+ *
+ * This software is licensed under the GNU Lesser General Public License
+ * (version 2.1 or later). See the COPYING file in this distribution.
+ */
+
+/**
+ * The RFC 2342 NAMESPACE command.
+ *
+ * Determines the mailbox name prefix and hierarchy delimiter for the
+ * personal, other user's and public namespaces.
+ *
+ * @see [[https://tools.ietf.org/html/rfc2342]]
+ */
+public class Geary.Imap.NamespaceCommand : Command {
+
+    public const string NAME = "NAMESPACE";
+
+    public NamespaceCommand() {
+        base(NAME);
+    }
+
+}
diff --git a/src/engine/imap/message/imap-namespace.vala b/src/engine/imap/message/imap-namespace.vala
new file mode 100644
index 0000000..060ab2c
--- /dev/null
+++ b/src/engine/imap/message/imap-namespace.vala
@@ -0,0 +1,29 @@
+/*
+ * Copyright 2016 Michael Gratton <mike vee net>
+ *
+ * This software is licensed under the GNU Lesser General Public License
+ * (version 2.1 or later). See the COPYING file in this distribution.
+ */
+
+/**
+ * Namespace component in a response for a NAMESPACE command.
+ *
+ * @see Geary.Imap.NamespaceCommand
+ */
+public class Geary.Imap.Namespace : BaseObject {
+
+
+    public string prefix { get; private set; }
+    public string? delim { get; private set; }
+
+
+    public Namespace(string prefix, string? delim) {
+        this.prefix = prefix;
+        this.delim = delim;
+    }
+
+    public string to_string() {
+        return "(%s,%s)".printf(this.prefix, this.delim ?? "NIL");
+    }
+
+}
diff --git a/src/engine/imap/response/imap-capabilities.vala b/src/engine/imap/response/imap-capabilities.vala
index 3d3eef8..67a3dfb 100644
--- a/src/engine/imap/response/imap-capabilities.vala
+++ b/src/engine/imap/response/imap-capabilities.vala
@@ -12,7 +12,8 @@ public class Geary.Imap.Capabilities : Geary.GenericCapabilities {
     public const string DEFLATE_SETTING = "DEFLATE";
     public const string UIDPLUS = "UIDPLUS";
     public const string SPECIAL_USE = "SPECIAL-USE";
-    
+    public const string NAMESPACE = "NAMESPACE";
+
     public const string NAME_SEPARATOR = "=";
     public const string? VALUE_SEPARATOR = null;
     
diff --git a/src/engine/imap/response/imap-namespace-response.vala 
b/src/engine/imap/response/imap-namespace-response.vala
new file mode 100644
index 0000000..c6abb9d
--- /dev/null
+++ b/src/engine/imap/response/imap-namespace-response.vala
@@ -0,0 +1,83 @@
+/*
+ * Copyright 2016 Michael Gratton <mike vee net>
+ *
+ * This software is licensed under the GNU Lesser General Public License
+ * (version 2.1 or later). See the COPYING file in this distribution.
+ */
+
+/**
+ * Response for a NAMESPACE command.
+ *
+ * @see Geary.Imap.NamespaceCommand
+ */
+public class Geary.Imap.NamespaceResponse : BaseObject {
+
+
+    public Namespace[]? personal { get; private set; default = null; }
+    public Namespace[]? user { get; private set; default = null; }
+    public Namespace[]? shared { get; private set; default = null; }
+
+
+    /**
+     * Decodes {@link ServerData} into a NamespaceResponse representation.
+     *
+     * The ServerData must be the response to a NAMESPACE command.
+     *
+     * @see ServerData.get_list
+     */
+    public static NamespaceResponse decode(ServerData server_data) throws ImapError {
+        StringParameter cmd = server_data.get_as_string(1);
+        if (!cmd.equals_ci(NamespaceCommand.NAME))
+            throw new ImapError.PARSE_ERROR(
+                "Not NAMESPACE data: %s", server_data.to_string()
+            );
+
+        if (server_data.size <= 2) {
+            throw new ImapError.PARSE_ERROR(
+                "No NAMESPACEs privided: %s", server_data.to_string()
+            );
+        }
+
+        ListParameter? personal = server_data.get_as_nullable_list(2);
+        ListParameter? user = null;
+        if (server_data.size >= 4) {
+            user = server_data.get_as_nullable_list(3);
+        }
+        ListParameter? shared = null;
+        if (server_data.size >= 5) {
+            shared = server_data.get_as_nullable_list(4);
+        }
+
+        return new NamespaceResponse(
+            parse_namespaces(personal),
+            user != null ? parse_namespaces(user) : null,
+            shared != null ? parse_namespaces(shared) : null
+        );
+    }
+
+    private static Namespace[]? parse_namespaces(ListParameter? list) throws ImapError {
+        Namespace[] nss = new Namespace[list.size];
+        for (int i = 0; i < list.size; i++) {
+            nss[i] = parse_namespace(list.get_as_list(i));
+        }
+        return nss;
+    }
+
+    private static Namespace? parse_namespace(ListParameter? list) throws ImapError {
+        Namespace? ns = null;
+        if (list != null && list.size >= 1) {
+            ns = new Namespace(
+                list.get_as_string(0).ascii,
+                list.get_as_nullable_string(1).nullable_ascii
+            );
+        }
+        return ns;
+    }
+
+    public NamespaceResponse(Namespace[]? personal, Namespace[]? user, Namespace[]? shared) {
+        this.personal = personal;
+        this.user = user;
+        this.shared = shared;
+    }
+
+}
diff --git a/src/engine/imap/response/imap-server-data-type.vala 
b/src/engine/imap/response/imap-server-data-type.vala
index f2ff5f5..f7246f7 100644
--- a/src/engine/imap/response/imap-server-data-type.vala
+++ b/src/engine/imap/response/imap-server-data-type.vala
@@ -18,6 +18,7 @@ public enum Geary.Imap.ServerDataType {
     FLAGS,
     LIST,
     LSUB,
+    NAMESPACE,
     RECENT,
     SEARCH,
     STATUS,
@@ -45,7 +46,10 @@ public enum Geary.Imap.ServerDataType {
             
             case LSUB:
                 return "lsub";
-            
+
+            case NAMESPACE:
+                return "namespace";
+
             case RECENT:
                 return "recent";
             
@@ -91,7 +95,10 @@ public enum Geary.Imap.ServerDataType {
             
             case "lsub":
                 return LSUB;
-            
+
+            case "namespace":
+                return NAMESPACE;
+
             case "recent":
                 return RECENT;
             
@@ -137,6 +144,9 @@ public enum Geary.Imap.ServerDataType {
                 case "lsub":
                     return LSUB;
                 
+                case "namespace":
+                    return NAMESPACE;
+                
                 case "search":
                     return SEARCH;
                 
diff --git a/src/engine/imap/response/imap-server-data.vala b/src/engine/imap/response/imap-server-data.vala
index 7c1e2c3..e2e91aa 100644
--- a/src/engine/imap/response/imap-server-data.vala
+++ b/src/engine/imap/response/imap-server-data.vala
@@ -129,7 +129,19 @@ public class Geary.Imap.ServerData : ServerResponse {
         
         return MailboxInformation.decode(this, true);
     }
-    
+
+    /**
+     * Parses the {@link ServerData} into {@link MailboxInformation}, if possible.
+     *
+     * @throws ImapError.INVALID if not a NAMESPACE response.
+     */
+    public NamespaceResponse get_namespace() throws ImapError {
+        if (server_data_type != ServerDataType.NAMESPACE)
+            throw new ImapError.INVALID("Not NAMESPACE data: %s", to_string());
+
+        return NamespaceResponse.decode(this);
+    }
+
     /**
      * Parses the {@link ServerData} into a {@link ServerDataType.RECENT} value, if possible.
      *


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