[Xfce4-commits] <postler:master> Implement PostlerAccounts for account handling

Christian Dywan noreply at xfce.org
Fri Jun 11 23:36:01 CEST 2010


Updating branch refs/heads/master
         to 0de7876637097283947fb5bfd8f6cd74de5161ea (commit)
       from b6f23fb36d6fa7ddcabbf015ccd2b9f204f32cee (commit)

commit 0de7876637097283947fb5bfd8f6cd74de5161ea
Author: Christian Dywan <christian at twotoasts.de>
Date:   Thu Jun 10 21:54:24 2010 +0200

    Implement PostlerAccounts for account handling
    
    If ~/Mail or a folder at the path MAILDIR exists, it is assumed
    as the local folder.
    
    Other accounts must be defined in ~/.config/postler/accountrc.
    
    Search is a type of account now.

 postler/postler-accounts.vala |  114 +++++++++++++++++++++++++++++++++++++++++
 postler/postler-bureau.vala   |    6 ++-
 postler/postler-folders.vala  |   61 ++++++++++-----------
 postler/postler-messages.vala |   27 +++++-----
 4 files changed, 161 insertions(+), 47 deletions(-)

diff --git a/postler/postler-accounts.vala b/postler/postler-accounts.vala
new file mode 100644
index 0000000..c560390
--- /dev/null
+++ b/postler/postler-accounts.vala
@@ -0,0 +1,114 @@
+/*
+ Copyright (C) 2010 Christian Dywan <christian at twotoasts.de>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ See the file COPYING for the full license text.
+*/
+
+const string GETTEXT_PACKAGE_ACCOUNTS = Config.GETTEXT_PACKAGE;
+
+namespace Postler {
+    public enum AccountType {
+        MAILDIR,
+        SEARCH
+    }
+
+    public class AccountInfo : GLib.Object {
+        public string name;
+        public AccountType type;
+        public string path;
+    }
+}
+
+public class Postler.Accounts : GLib.Object {
+    string location;
+    string config_path;
+    string data_path;
+    GLib.KeyFile keyfile;
+    GLib.List<AccountInfo> infos;
+
+    public Accounts (string? location=null) {
+        if (location != null) {
+            this.location = location;
+            reload ();
+            return;
+        }
+        unowned string config_dir = Environment.get_user_config_dir ();
+        unowned string data_dir = Environment.get_user_data_dir ();
+        config_path = config_dir + "/" + Config.PACKAGE_NAME + "/accountrc";
+        data_path = data_dir + "/" + Config.PACKAGE_NAME + "/mail/";
+        /* TODO: Monitor accountrc file and emit a signal */
+        reload ();
+    }
+
+    void reload () {
+        infos = new GLib.List<AccountInfo> ();
+        var info = new AccountInfo ();
+        unowned string toplevel = Environment.get_variable ("MAILDIR");
+        if (toplevel != null && toplevel != "")
+            info.path = toplevel;
+        else {
+            string local_mail = Environment.get_home_dir () + "/Mail";
+            if (FileUtils.test (local_mail, FileTest.IS_DIR))
+                info.path = local_mail;
+        }
+        if (info.path != null) {
+            info.name = _("Local");
+            info.type = AccountType.MAILDIR;
+            infos.prepend (info);
+        }
+
+        keyfile = new GLib.KeyFile ();
+        try {
+            keyfile.load_from_file (config_path, 0);
+        }
+        catch (GLib.Error error) {
+            GLib.debug ("Failed to load \"%s\": %s", config_path, error.message);
+        }
+        foreach (string group in keyfile.get_groups ()) {
+            try {
+                string name = keyfile.get_string (group, "name");
+                string type = keyfile.get_string (group, "type");
+                info = new AccountInfo ();
+                if (type == "maildir") {
+                    info.name = name;
+                    info.type = AccountType.MAILDIR;
+                    info.path = data_path + name;
+                }
+                else if (type == "search") {
+                    info.name = name;
+                    info.type = AccountType.SEARCH;
+                    info.path = "search:%s/%s".printf (
+                        keyfile.get_string (group, "header"),
+                        keyfile.get_string (group, "filter"));
+                }
+                else
+                    throw new GLib.FileError.FAILED (
+                        _("Invalid type \"%s\"").printf (type));
+                infos.prepend (info);
+            } catch (GLib.Error error) {
+                GLib.critical (_("Failed to parse account in \"%s\": %s"),
+                                 location, error.message);
+            }
+        }
+        infos.reverse ();
+    }
+
+    public string[] get_folders () {
+        string[] folders = {};
+        foreach (unowned AccountInfo info in infos) {
+            if (info.type != AccountType.SEARCH)
+                folders += info.path;
+        }
+        return folders;
+    }
+
+    public unowned List<AccountInfo> get_infos () {
+        return infos;
+    }
+}
+
diff --git a/postler/postler-bureau.vala b/postler/postler-bureau.vala
index a24c6ad..7c9ba6c 100644
--- a/postler/postler-bureau.vala
+++ b/postler/postler-bureau.vala
@@ -12,6 +12,8 @@
 const string GETTEXT_PACKAGE_BUREAU = Config.GETTEXT_PACKAGE;
 
 public class Postler.Bureau : Gtk.Window {
+    Accounts accounts = new Accounts ();
+
     Gtk.UIManager ui;
     Gtk.ActionGroup actions;
 
@@ -302,7 +304,7 @@ public class Postler.Bureau : Gtk.Window {
         toolitem.show_all ();
         shelf.pack_start (toolbar, false, false, 0);
         var hpaned = new Gtk.HPaned ();
-        folders = new Postler.Folders ();
+        folders = new Postler.Folders (accounts);
         var scrolled = new Postler.ScrolledWindow (folders);
         hpaned.pack1 (scrolled, false, true);
         shelf.pack_start (hpaned, true, true, 0);
@@ -315,7 +317,7 @@ public class Postler.Bureau : Gtk.Window {
         actions.get_action ("SearchSender").is_important = true;
         actions.get_action ("SearchRecipient").is_important = true;
         messages_box.pack_start (search_options, false, false, 0);
-        messages = new Postler.Messages ();
+        messages = new Postler.Messages (accounts);
         messages.notify["selected-location"].connect ((object, pspec) => {
             Postler.Messages messages = object as Postler.Messages;
             bool state = messages.selected_location != null;
diff --git a/postler/postler-folders.vala b/postler/postler-folders.vala
index ff5f3f3..59fa6fa 100644
--- a/postler/postler-folders.vala
+++ b/postler/postler-folders.vala
@@ -18,6 +18,7 @@ struct Postler.MailFolder {
 }
 
 public class Postler.Folders : Gtk.TreeView {
+    Accounts accounts;
     Gtk.TreeStore store;
     string last_location;
     FileMonitor[] unread_monitors = {};
@@ -42,7 +43,8 @@ public class Postler.Folders : Gtk.TreeView {
         LOCATION
     }
 
-    public Folders () {
+    public Folders (Accounts accounts) {
+        this.accounts = accounts;
         store = new Gtk.TreeStore (3,
             typeof (string), typeof (string), typeof (string));
         set_model (store);
@@ -81,55 +83,49 @@ public class Postler.Folders : Gtk.TreeView {
     bool populate () {
         unread_monitors = {};
         unread_monitors_count = 0;
-        string toplevel = Environment.get_variable ("MAILDIR");
-        if (toplevel == null || toplevel == "")
-            toplevel = Environment.get_home_dir () + "/Mail";
         /* TODO: Monitor folders for changes */
-        try {
-            /* FIXME: Scan for toplevel, then sublevel */
-            var account_dir = File.new_for_path (toplevel);
-            var account_enumerator = account_dir.enumerate_children (
-                FILE_ATTRIBUTE_STANDARD_NAME + "," +
-                FILE_ATTRIBUTE_STANDARD_TYPE, 0, null);
-            GLib.FileInfo info;
-            while ((info = account_enumerator.next_file (null)) != null) {
-                string account_name = info.get_name ();
-                string location = toplevel + "/" + account_name;
-
-                if (info.get_file_type () == FileType.REGULAR) {
-                    store.insert_with_values (null, null, -1,
-                        Columns.ICON, STOCK_FOLDER_SAVED_SEARCH,
-                        Columns.NAME, info.get_name (),
-                        Columns.LOCATION, location, -1);
-                    continue;
-                }
+        unowned GLib.List<AccountInfo> infos = accounts.get_infos ();
+        /* foreach (unowned AccountInfo account_info in infos) { */
+        for (unowned GLib.List<AccountInfo> info_iter = infos;
+            info_iter != null; info_iter = info_iter.next) {
+            AccountInfo account_info = info_iter.data;
+
+            if (account_info.type == AccountType.SEARCH) {
+                store.insert_with_values (null, null, -1,
+                    Columns.ICON, STOCK_FOLDER_SAVED_SEARCH,
+                    Columns.NAME, account_info.name,
+                    Columns.LOCATION, account_info.path, -1);
+                continue;
+            }
 
+            try {
                 Gtk.TreeIter account_iter;
                 store.insert_with_values (out account_iter, null, -1,
                     Columns.ICON, Gtk.STOCK_DIRECTORY,
-                    Columns.NAME, info.get_name (),
+                    Columns.NAME, account_info.name,
                     Columns.LOCATION, null, -1);
-                var folder_dir = account_dir.resolve_relative_path (account_name);
+                var folder_dir = File.new_for_path (account_info.path);
                 var folder_enumerator = folder_dir.enumerate_children (
                     FILE_ATTRIBUTE_STANDARD_NAME, 0, null);
+                FileInfo info;
                 while ((info = folder_enumerator.next_file (null)) != null) {
                     Gtk.TreeIter folder_iter;
                     string name = info.get_name ();
                     if (name == "INBOX") {
                         var msg_dir = folder_dir.resolve_relative_path (
-                            location + "/" + name + "/new");
+                            account_info.path + "/" + name + "/new");
                         unread_monitors += msg_dir.monitor_directory (0, null);
                         unread_monitors_count++;
                         string path = store.get_string_from_iter (account_iter);
                         unread_monitors[unread_monitors_count - 1].changed.connect (
                             (monitor, file, other, event) => {
-                            unread_monitor_changed (msg_dir, path, account_name);
+                            unread_monitor_changed (msg_dir, path, account_info.name);
                         });
-                        unread_monitor_changed (msg_dir, path, account_name);
+                        unread_monitor_changed (msg_dir, path, account_info.name);
 
                         store.set (account_iter,
                             Columns.ICON, STOCK_INBOX,
-                            Columns.LOCATION, location + "/" + name,
+                            Columns.LOCATION, account_info.path + "/" + name,
                             -1);
                         continue;
                     }
@@ -148,7 +144,7 @@ public class Postler.Folders : Gtk.TreeView {
                     store.insert_with_values (out folder_iter, account_iter, -1,
                         Columns.ICON, stock_id,
                         Columns.NAME, localized_name ?? name,
-                        Columns.LOCATION, location + "/" + name, -1);
+                        Columns.LOCATION, account_info.path + "/" + name, -1);
                     var status_dir = folder_dir.resolve_relative_path (name);
                     var new_dir = status_dir.resolve_relative_path ("new");
                     if (!new_dir.query_exists (null))
@@ -156,9 +152,10 @@ public class Postler.Folders : Gtk.TreeView {
                 }
                 expand_row (store.get_path (account_iter), true);
             }
-        } catch (GLib.Error error) {
-            GLib.critical (_("Failed to read folder \"%s\": %s"),
-                toplevel, error.message);
+            catch (GLib.Error error) {
+                GLib.critical (_("Failed to read folder \"%s\": %s"),
+                    account_info.path, error.message);
+            }
         }
         return false;
     }
diff --git a/postler/postler-messages.vala b/postler/postler-messages.vala
index 5a97655..39c60c5 100644
--- a/postler/postler-messages.vala
+++ b/postler/postler-messages.vala
@@ -12,6 +12,7 @@
 const string GETTEXT_PACKAGE_MESSAGES = Config.GETTEXT_PACKAGE;
 
 public class Postler.Messages : Gtk.TreeView {
+    Accounts accounts;
     Gtk.TreeStore store;
     Gtk.TreeModelSort sort;
 
@@ -162,7 +163,8 @@ public class Postler.Messages : Gtk.TreeView {
         }
     }
 
-    public Messages () {
+    public Messages (Accounts accounts) {
+        this.accounts = accounts;
         store = new Gtk.TreeStore (9, typeof (string), typeof (string),
             typeof (string), typeof (string), typeof (int), typeof (string),
             typeof (int64), typeof (string), typeof (ulong));
@@ -383,18 +385,17 @@ public class Postler.Messages : Gtk.TreeView {
             string[] filters = {};
             string[] folders = {};
 
-            try {
-                var keyfile = new KeyFile ();
-                keyfile.load_from_file (location, 0);
-                headers += keyfile.get_string ("search", "header");
-                filters += keyfile.get_string ("search", "filter").down ();
-                string search_account = keyfile.get_string ("search", "account");
-                string toplevel = Environment.get_variable ("MAILDIR");
-                if (toplevel == null || toplevel == "")
-                    toplevel = Environment.get_home_dir () + "/Mail";
-                folders += toplevel + "/" + search_account + "/INBOX/cur";
-                folders += toplevel + "/" + search_account + "/INBOX/new";
-            } catch (GLib.KeyFileError keyfile_error) {
+            if (location.has_prefix ("search:")) {
+                string query = location.substring (7);
+                string[] parts = query.split ("/", 2);
+                return_val_if_fail (parts[0] != null && parts[1] != null, false);
+                headers += parts[0];
+                filters += parts[1].down ();
+                foreach (var folder in accounts.get_folders ()) {
+                    folders += folder + "/INBOX/new";
+                    folders += folder + "/INBOX/cur";
+                }
+            } else {
                 folders += location + "/cur";
                 folders += location + "/new";
             }



More information about the Xfce4-commits mailing list