[Xfce4-commits] <postler:master> Implement sending plain text messages with msmtp

Christian Dywan noreply at xfce.org
Sat Jun 19 06:50:05 CEST 2010


Updating branch refs/heads/master
         to 2e2d1b47c997f11e3c0cad37ca4ed26fd5adacd6 (commit)
       from 985c0f460c988cd4a054c37472637b8f5f83ebe8 (commit)

commit 2e2d1b47c997f11e3c0cad37ca4ed26fd5adacd6
Author: Christian Dywan <christian at twotoasts.de>
Date:   Fri Jun 18 22:11:47 2010 +0200

    Implement sending plain text messages with msmtp

 postler/postler-accounts.vala |   68 +++++++++++++++++++++++++++++++++++-----
 postler/postler-app.vala      |    7 ++++
 postler/postler-composer.vala |   38 ++++++++++++++++++++++-
 postler/postler-content.vala  |    6 +---
 4 files changed, 104 insertions(+), 15 deletions(-)

diff --git a/postler/postler-accounts.vala b/postler/postler-accounts.vala
index 6e9d19a..2ce38e8 100644
--- a/postler/postler-accounts.vala
+++ b/postler/postler-accounts.vala
@@ -23,6 +23,7 @@ namespace Postler {
         public AccountType type;
         public string address;
         public string receive;
+        public string send;
         public string username;
         public string password;
         public string prefix;
@@ -169,11 +170,15 @@ public class Postler.Accounts : GLib.Object {
         /* TODO: Update accountrc file */
     }
 
-    string? get_tool_configuration_filename (AccountInfo info) throws GLib.FileError {
+    string? get_tool_configuration_filename (string? send, 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."));
+
+        if (send != null)
+            return "%s/%s.msmtprc".printf (cache_path, info.name);
+
         switch (info.type) {
         case AccountType.IMAP:
             return "%s/%s.mbsyncrc".printf (cache_path, info.name);
@@ -184,8 +189,8 @@ public class Postler.Accounts : GLib.Object {
         return null;
     }
 
-    void generate_tool_configuration (AccountInfo info) throws GLib.FileError {
-        string filename = get_tool_configuration_filename (info);
+    void generate_tool_configuration (string? send, AccountInfo info) throws GLib.FileError {
+        string filename = get_tool_configuration_filename (send, info);
         /* FIXME: Bail out if the file exists and is younger than accountrc */
 
         if (certificate_file == null)
@@ -195,12 +200,17 @@ public class Postler.Accounts : GLib.Object {
             string[] address_parts = info.address.split_set ("@,", 3);
             if (address_parts[0] == null || address_parts[1] == null)
                 throw new GLib.FileError.FAILED (_("Invalid address"));
-            if (info.receive == null)
+            if (send == null && info.receive == null)
                 info.receive = "imap." + address_parts[1];
+            if (send != null && info.send == null)
+                info.send = "smtp." + address_parts[1];
             if (info.username == null)
                 info.username = address_parts[0];
         }
-        if (info.receive == null)
+
+        if (send == null && info.receive == null)
+            throw new GLib.FileError.FAILED (_("Hostname is missing"));
+        if (send != null && info.send == null)
             throw new GLib.FileError.FAILED (_("Hostname is missing"));
         if (info.username == null)
             throw new GLib.FileError.FAILED (_("Username is missing"));
@@ -210,6 +220,35 @@ public class Postler.Accounts : GLib.Object {
         if (certificate != null && !Path.is_absolute (certificate))
             certificate = info.path + "/" + certificate;
 
+        if (send != null) {
+            string msmtprc = """
+                defaults
+                auth on
+                tls on
+                tls_trust_file %s
+                tls_trust_file %s
+                auto_from on
+                maildomain localhost
+                account postler
+                host %s
+                from %s
+                user %s
+                password %s
+                account default : postler
+                """.
+                printf (
+                    certificate_file,
+                    certificate != null ? certificate : certificate_file,
+                    info.send,
+                    info.address.split (",")[0],
+                    info.username,
+                    info.password
+                    );
+            FileUtils.set_contents (filename, msmtprc, -1);
+            FileUtils.chmod (filename, 0600);
+            return;
+        }
+
         switch (info.type) {
         case AccountType.IMAP:
             string mbsyncrc = """
@@ -259,7 +298,7 @@ public class Postler.Accounts : GLib.Object {
         }
     }
 
-    public void receive (AccountInfo? info=null) {
+    public void send_or_receive (string? send, AccountInfo? info=null) {
         var infos = new GLib.List<AccountInfo> ();
         if (info != null)
             infos.prepend (info);
@@ -272,14 +311,17 @@ public class Postler.Accounts : GLib.Object {
 
         foreach (var info in infos) {
             try {
-            string filename = get_tool_configuration_filename (info);
+            string filename = get_tool_configuration_filename (send, info);
             string command;
-            if (info.type == AccountType.IMAP)
+            if (send != null)
+                command = "%s -c 'cat %s | msmtp -C %s -t'".printf (
+                    Environment.get_variable ("SHELL"), send, filename);
+            else if (info.type == AccountType.IMAP)
                 command = "mbsync -c %s --pull%s mirror".printf (
                     filename, info.sync == "full" ? " --push" : "");
             else
                 continue;
-                generate_tool_configuration (info);
+                generate_tool_configuration (send, 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);
@@ -295,5 +337,13 @@ public class Postler.Accounts : GLib.Object {
             }
         }
     }
+
+    public void receive (AccountInfo? info=null) {
+        send_or_receive (null, info);
+    }
+
+    public void send (AccountInfo? info=null, string filename) {
+        send_or_receive (filename, info);
+    }
 }
 
diff --git a/postler/postler-app.vala b/postler/postler-app.vala
index 2373c1d..99e32eb 100644
--- a/postler/postler-app.vala
+++ b/postler/postler-app.vala
@@ -84,6 +84,13 @@ public class Postler.App : Unique.App {
         factory.add_default ();
     }
 
+    public static string get_user_agent () {
+        /* FIXME: Define the user agent properly */
+        return "%s/%s (X11; Linux; U; %s) WebKit/531.2+".
+            printf (Config.PACKAGE_NAME, Config.PACKAGE_VERSION,
+                    Pango.Language.get_default ().to_string ());
+    }
+
     public static bool show_uri (Gdk.Screen screen, string uri) {
         string real_uri = uri;
         if (!("://" in uri))
diff --git a/postler/postler-composer.vala b/postler/postler-composer.vala
index 584f45b..df337c3 100644
--- a/postler/postler-composer.vala
+++ b/postler/postler-composer.vala
@@ -65,7 +65,43 @@ public class Postler.Composer : Gtk.Window {
     """;
 
     void action_mail_send () {
-        /* TODO */
+        string from = combo_from.get_active_text ();
+        foreach (var info in accounts.get_infos ()) {
+            if (info.address != null && from in info.address) {
+                if (DirUtils.create_with_parents (info.path + "/Sent", 0700) != 0) {
+                    GLib.critical (_("Folder for sent messages couldn't be created."));
+                    return;
+                }
+                var now = new Soup.Date.from_now (0);
+                /* TODO: Generate a valid Maildir filename and save to 'cur' */
+                /* TODO: Handle failure to send */
+                string filename = info.path + "/Sent/"
+                    + now.to_string (Soup.DateFormat.ISO8601_COMPACT)
+                    + Random.next_int ().to_string ();
+                string copy = entry_copy.text;
+                string header = ("From: %s\nTo: %s\n%s%s"
+                    + "Content-Type: text/plain; charset=UTF-8\n"
+                    + "Subject: %s\nDate: %s\nX-Mailer: %s\n\n").printf (
+                        from,
+                        entry_to.text,
+                        copy != "" ? "CC: " : "", copy != "" ? copy + "\n" : "",
+                        entry_subject.text,
+                        now.to_string (Soup.DateFormat.RFC2822),
+                        Postler.App.get_user_agent ()
+                    );
+                content.select_all ();
+                content.copy_clipboard ();
+                var clipboard = content.get_clipboard (Gdk.SELECTION_CLIPBOARD);
+                string body = clipboard.wait_for_text ();
+                try {
+                    FileUtils.set_contents (filename, header + body, -1);
+                    FileUtils.chmod (filename, 0700);
+                    accounts.send (info, filename);
+                } catch (GLib.Error error) {
+                    GLib.critical (_("Failed to send message: %s"), error.message);
+                }
+            }
+        }
     }
 
     void action_preferences () {
diff --git a/postler/postler-content.vala b/postler/postler-content.vala
index 4e95806..a2073a8 100644
--- a/postler/postler-content.vala
+++ b/postler/postler-content.vala
@@ -82,11 +82,7 @@ public class Postler.Content : WebKit.WebView {
     public Content () {
         settings.set ("enable-scripts", false, "enable-plugins", false, null);
         if (settings.get_class ().find_property ("user-agent") != null) {
-            /* FIXME: Define the user agent properly */
-            string user_agent = "%s/%s (X11; Linux; U; %s) WebKit/531.2+".
-                printf (Config.PACKAGE_NAME, Config.PACKAGE_VERSION,
-                        Pango.Language.get_default ().to_string ());
-            settings.set ("user-agent", user_agent, null);
+            settings.set ("user-agent", Postler.App.get_user_agent (), null);
         }
         if (settings.get_class ().find_property ("enable-private-browsing") != null) {
             settings.set ("enable-private-browsing", true, null);



More information about the Xfce4-commits mailing list