[Xfce4-commits] <postler:master> Support for receiving IMAP accounts via isync

Christian Dywan noreply at xfce.org
Sun Jun 13 23:04:01 CEST 2010


Updating branch refs/heads/master
         to 1131d9cc9b0f847507ef72ba8616358a98a3a7f1 (commit)
       from 82ac027ebe8847a1ae666cb2ecc426165926e49e (commit)

commit 1131d9cc9b0f847507ef72ba8616358a98a3a7f1
Author: Christian Dywan <christian at twotoasts.de>
Date:   Sat Jun 12 23:08:26 2010 +0200

    Support for receiving IMAP accounts via isync

 postler/postler-accounts.vala |  153 ++++++++++++++++++++++++++++++++++++++++-
 postler/postler-bureau.vala   |    3 +-
 2 files changed, 152 insertions(+), 4 deletions(-)

diff --git a/postler/postler-accounts.vala b/postler/postler-accounts.vala
index c560390..650d3ca 100644
--- a/postler/postler-accounts.vala
+++ b/postler/postler-accounts.vala
@@ -14,13 +14,19 @@ const string GETTEXT_PACKAGE_ACCOUNTS = Config.GETTEXT_PACKAGE;
 namespace Postler {
     public enum AccountType {
         MAILDIR,
+        IMAP,
         SEARCH
     }
 
     public class AccountInfo : GLib.Object {
         public string name;
         public AccountType type;
+        public string address;
+        public string receive;
+        public string username;
+        public string password;
         public string path;
+        public string sync;
     }
 }
 
@@ -28,9 +34,15 @@ public class Postler.Accounts : GLib.Object {
     string location;
     string config_path;
     string data_path;
+    string? certificate_file;
     GLib.KeyFile keyfile;
     GLib.List<AccountInfo> infos;
 
+    const string[] root_certificate_files = {
+        "/etc/pki/tls/certs/ca-bundle.crt",
+        "/etc/ssl/certs/ca-certificates.crt"
+    };
+
     public Accounts (string? location=null) {
         if (location != null) {
             this.location = location;
@@ -42,6 +54,14 @@ public class Postler.Accounts : GLib.Object {
         config_path = config_dir + "/" + Config.PACKAGE_NAME + "/accountrc";
         data_path = data_dir + "/" + Config.PACKAGE_NAME + "/mail/";
         /* TODO: Monitor accountrc file and emit a signal */
+
+        foreach (unowned string file in root_certificate_files) {
+            if (FileUtils.test (file, FileTest.EXISTS))
+                certificate_file = file;
+        }
+        if (certificate_file == null)
+            GLib.warning (_("Failed to find a root certificate file."));
+
         reload ();
     }
 
@@ -69,18 +89,32 @@ public class Postler.Accounts : GLib.Object {
         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 ();
+                info.name = name;
                 if (type == "maildir") {
-                    info.name = name;
                     info.type = AccountType.MAILDIR;
                     info.path = data_path + name;
                 }
+                else if (type == "imap") {
+                    info.type = AccountType.IMAP;
+                    info.path = data_path + name;
+                    if (keyfile.has_key (group, "address"))
+                        info.address = keyfile.get_string (group, "address");
+                    if (keyfile.has_key (group, "username"))
+                        info.username = keyfile.get_string (group, "username");
+                    if (keyfile.has_key (group, "password"))
+                        info.password = keyfile.get_string (group, "password");
+                    if (keyfile.has_key (group, "receive"))
+                        info.receive = keyfile.get_string (group, "receive");
+                    if (keyfile.has_key (group, "sync"))
+                        info.sync = keyfile.get_string (group, "sync");
+                }
                 else if (type == "search") {
-                    info.name = name;
                     info.type = AccountType.SEARCH;
                     info.path = "search:%s/%s".printf (
                         keyfile.get_string (group, "header"),
@@ -110,5 +144,120 @@ public class Postler.Accounts : GLib.Object {
     public unowned List<AccountInfo> get_infos () {
         return infos;
     }
+
+    string? get_tool_configuration_filename (AccountInfo info) throws GLib.FileError {
+        unowned string cache_dir = Environment.get_user_cache_dir ();
+        string cache_path = cache_dir + "/postler/mail";
+        if (DirUtils.create_with_parents (cache_path, 0700) != 0)
+            throw new GLib.FileError.FAILED (_("Cache folder couldn't be created."));
+        switch (info.type) {
+        case AccountType.IMAP:
+            return "%s/%s.mbsyncrc".printf (cache_path, info.name);
+        case AccountType.MAILDIR:
+        case AccountType.SEARCH:
+            throw new GLib.FileError.FAILED (_("This type can't receive mail."));
+        }
+        return null;
+    }
+
+    void generate_tool_configuration (AccountInfo info) throws GLib.FileError {
+        string filename = get_tool_configuration_filename (info);
+        /* FIXME: Bail out if the file exists and is younger than accountrc */
+
+        if (certificate_file == null)
+            throw new GLib.FileError.FAILED (_("No SSL certificates available"));
+
+        if (info.address != null) {
+            string[] address_parts = info.address.split ("@", 2);
+            if (address_parts[0] == null || address_parts[1] == null)
+                throw new GLib.FileError.FAILED (_("Invalid address"));
+            if (info.receive == null)
+                info.receive = "imap." + address_parts[1];
+            if (info.username == null)
+                info.username = address_parts[0];
+        }
+        if (info.receive == null)
+            throw new GLib.FileError.FAILED (_("Hostname is missing"));
+        if (info.username == null)
+            throw new GLib.FileError.FAILED (_("Username is missing"));
+        if (info.password == null)
+            throw new GLib.FileError.FAILED (_("Password is missing"));
+
+        switch (info.type) {
+        case AccountType.IMAP:
+            string mbsyncrc = """
+               Sync Pull
+               Create Slave
+               SyncState *
+
+               IMAPStore remote
+                   Host %s
+                   User %s
+                   Pass %s
+                   UseIMAPS yes
+                   CertificateFile %s
+
+               MaildirStore local
+                   Path %s/
+                   Inbox %s/INBOX
+
+               Channel local-remote
+                   Master :remote:
+                   Slave :local:
+                   Pattern *
+               """.
+               printf (
+                   info.receive,
+                   info.username,
+                   info.password,
+                   certificate_file,
+                   info.path,
+                   info.path
+                   );
+            FileUtils.set_contents (filename, mbsyncrc, -1);
+            FileUtils.chmod (filename, 0700);
+            break;
+        case AccountType.MAILDIR:
+        case AccountType.SEARCH:
+            throw new GLib.FileError.FAILED (_("This type can't receive mail."));
+        }
+    }
+
+    public void receive (AccountInfo? info=null) {
+        var infos = new GLib.List<AccountInfo> ();
+        if (info != null)
+            infos.prepend (info);
+        else {
+            foreach (var info in this.infos) {
+                if (info.type == AccountType.IMAP)
+                    infos.prepend (info);
+            }
+        }
+
+        foreach (var info in infos) {
+            try {
+            string filename = get_tool_configuration_filename (info);
+            string command;
+            if (info.type == AccountType.IMAP)
+                command = "mbsync -c %s -a --pull%s".printf (
+                    filename, info.sync == "full" ? " --push" : "");
+            else
+                continue;
+                generate_tool_configuration (info);
+                if (DirUtils.create_with_parents (info.path, 0700) != 0)
+                    throw new GLib.FileError.FAILED (_("Mail folder couldn't be created."));
+                Postler.App.execute_command (command);
+            } catch (GLib.Error error) {
+                var error_dialog = new Gtk.MessageDialog (null, 0,
+                Gtk.MessageType.ERROR, Gtk.ButtonsType.OK,
+                    _("Failed to generate configuration for type \"%s\"."),
+                    info.type.to_string ());
+                error_dialog.format_secondary_text (error.message);
+                error_dialog.response.connect ((dialog, response)
+                    => { dialog.destroy (); });
+                error_dialog.show ();
+            }
+        }
+    }
 }
 
diff --git a/postler/postler-bureau.vala b/postler/postler-bureau.vala
index 7c9ba6c..d72cd74 100644
--- a/postler/postler-bureau.vala
+++ b/postler/postler-bureau.vala
@@ -86,8 +86,7 @@ public class Postler.Bureau : Gtk.Window {
     """;
 
     void action_mail_receive () {
-        /* FIXME: Don't hardcode offlineimap */
-        Postler.App.execute_command ("offlineimap -o -u Noninteractive.Quiet");
+        accounts.receive ();
     }
 
     void action_message_new () {



More information about the Xfce4-commits mailing list