From 4105f15ca0ad8f798acf3d72dbbf36debf1cc2c3 Mon Sep 17 00:00:00 2001 From: "Dirk-Jan C. Binnema" Date: Tue, 20 Sep 2011 00:21:37 +0300 Subject: [PATCH] * mu-cmd-server, m-msg-part.c: add support opening, extracting attachments --- src/mu-cmd-server.c | 105 ++++++++++++++++++++++++++++++++++++++++---- src/mu-msg-part.c | 56 ++++++++++++++++++----- 2 files changed, 141 insertions(+), 20 deletions(-) diff --git a/src/mu-cmd-server.c b/src/mu-cmd-server.c index 3d755fe8..2e015816 100644 --- a/src/mu-cmd-server.c +++ b/src/mu-cmd-server.c @@ -48,6 +48,7 @@ #include "mu-maildir.h" #include "mu-query.h" #include "mu-index.h" +#include "mu-msg-part.h" /* we include \376 (0xfe) and \377, (0xff) because it cannot occur as @@ -125,8 +126,10 @@ enum _Cmd { CMD_INDEX, CMD_MKDIR, CMD_MOVE, + CMD_OPEN, CMD_QUIT, CMD_REMOVE, + CMD_SAVE, CMD_VERSION, CMD_VIEW, @@ -150,8 +153,10 @@ cmd_from_string (const char *str) { CMD_INDEX, "index"}, { CMD_MKDIR, "mkdir"}, { CMD_MOVE, "move"}, + { CMD_OPEN, "open" }, { CMD_QUIT, "quit"}, { CMD_REMOVE, "remove" }, + { CMD_SAVE, "save"}, { CMD_VERSION, "version"}, { CMD_VIEW, "view"} }; @@ -420,10 +425,7 @@ cmd_move (MuStore *store, GSList *lst, GError **err) (NULL, MU_ERROR_IN_PARAMETERS, "usage: move []"); - - return move_or_flag (store, lst, TRUE, err); - } static MuError @@ -477,6 +479,90 @@ cmd_remove (MuStore *store, GSList *lst, GError **err) + +static MuError +save_or_open (MuStore *store, GSList *args, gboolean is_save, GError **err) +{ + MuMsg *msg; + unsigned docid, partindex; + char* targetpath; + gboolean rv; + + docid = get_docid ((const char*)args->data); + msg = mu_store_get_msg (store, docid, err); + if (!msg) + return server_error (err, MU_ERROR, "failed to get message"); + + partindex = atoi((const char*)g_slist_nth (args, 1)->data); + + if (is_save) + targetpath = g_strdup ((const char*)g_slist_nth (args, 2)->data); + else + targetpath = mu_msg_part_filepath_cache (msg, partindex); + + if (!targetpath) { + mu_msg_unref (msg); + return server_error (err, MU_ERROR_FILE, + "failed to determine target path"); + } + + rv = mu_msg_part_save (msg, targetpath, partindex, + is_save ? TRUE : FALSE, + is_save ? FALSE : TRUE, err); + mu_msg_unref (msg); + + if (rv && !is_save) + mu_util_play (targetpath, TRUE, FALSE); + + if (rv) { + gchar *info, *path; + path = mu_str_escape_c_literal (targetpath, FALSE); + info = g_strdup_printf ("(:info %s :message \"%s %s\")", + is_save ? "save" : "open", + is_save ? "Saved" : "Opened", + path); + send_expr (info); + g_free (path); + g_free (info); + } + + g_free (targetpath); + + if (!rv) + return server_error (err, MU_ERROR_FILE, + "failed to save attachment"); + + return MU_OK; +} + + + +static MuError +cmd_save (MuStore *store, GSList *args, GError **err) +{ + if (!check_param_num (args, 3, 3)) + return server_error + (NULL, MU_ERROR_IN_PARAMETERS, + "save "); + + return save_or_open (store, args, TRUE, err); +} + + +static MuError +cmd_open (MuStore *store, GSList *args, GError **err) +{ + + if (!check_param_num (args, 2, 2)) + return server_error + (NULL, MU_ERROR_IN_PARAMETERS, + "open "); + + return save_or_open (store, args, FALSE, err); +} + + + static MuError cmd_view (MuStore *store, GSList *args, GError **err) { @@ -571,16 +657,17 @@ static MuError cmd_add (MuStore *store, GSList *lst, GError **err) { unsigned docid; - const char *path; + const char *path, *maildir; gchar *str, *escpath; - if (!check_param_num (lst, 1, 1)) + if (!check_param_num (lst, 2, 2)) return server_error (NULL, MU_ERROR_IN_PARAMETERS, - "usage: add "); + "usage: add "); - path = (const char*)lst->data; + path = (const char*)lst->data; + maildir = (const char*)g_slist_nth (lst, 1)->data; - docid = mu_store_add_path (store, path, err); + docid = mu_store_add_path (store, path, maildir, err); if (docid == MU_STORE_INVALID_DOCID) return server_error (err, MU_ERROR_XAPIAN, "failed to add path"); @@ -670,8 +757,10 @@ handle_command (Cmd cmd, MuStore *store, MuQuery *query, GSList *args, case CMD_INDEX: rv = cmd_index (store, args, err); break; case CMD_MKDIR: rv = cmd_mkdir (args, err); break; case CMD_MOVE: rv = cmd_move (store, args, err); break; + case CMD_OPEN: rv = cmd_open (store, args, err); break; case CMD_QUIT: rv = cmd_quit (args, err); break; case CMD_REMOVE: rv = cmd_remove (store, args, err); break; + case CMD_SAVE: rv = cmd_save (store, args, err); break; case CMD_VERSION: rv = cmd_version (args, err); break; case CMD_VIEW: rv = cmd_view (store, args, err); break; diff --git a/src/mu-msg-part.c b/src/mu-msg-part.c index 7d80ef50..7c706283 100644 --- a/src/mu-msg-part.c +++ b/src/mu-msg-part.c @@ -95,6 +95,33 @@ part_foreach_cb (GMimeObject *parent, GMimeObject *part, PartData *pdata) pdata->_func(pdata->_msg, &pi, pdata->_user_data); } +static gboolean +load_msg_file_maybe (MuMsg *msg) +{ + GError *err; + + if (msg->_file) + return TRUE; + + err = NULL; + msg->_file = mu_msg_file_new (mu_msg_get_path(msg), NULL, + &err); + if (!msg->_file) { + MU_HANDLE_G_ERROR(err); /* will free it */ + return FALSE; + } + + if (!msg->_file->_mime_msg) { + mu_msg_file_destroy (msg->_file); + msg->_file = NULL; + g_warning ("failed to create mime-msg"); + return FALSE; + } + + return TRUE; +} + + void mu_msg_part_foreach (MuMsg *msg, MuMsgPartForeachFunc func, gpointer user_data) @@ -103,18 +130,8 @@ mu_msg_part_foreach (MuMsg *msg, MuMsgPartForeachFunc func, g_return_if_fail (msg); - /* if we don't have a file yet, we need to open it now... */ - if (!msg->_file) { - GError *err; - err = NULL; - msg->_file = mu_msg_file_new (mu_msg_get_path(msg), NULL, - &err); - if (!msg->_file) { - MU_HANDLE_G_ERROR(err); /* will free it */ - return; - } - } - g_return_if_fail (GMIME_IS_OBJECT(msg->_file->_mime_msg)); + if (!load_msg_file_maybe (msg)) + return; pdata._msg = msg; pdata._idx = 0; @@ -203,6 +220,9 @@ mu_msg_part_filepath (MuMsg *msg, const char* targetdir, guint partidx) char *fname, *filepath; GMimeObject* part; + if (!load_msg_file_maybe (msg)) + return NULL; + part = find_part (msg, partidx); if (!part) { g_warning ("%s: cannot find part %u", __FUNCTION__, partidx); @@ -235,6 +255,9 @@ mu_msg_part_filepath_cache (MuMsg *msg, guint partid) g_return_val_if_fail (msg, NULL); + if (!load_msg_file_maybe (msg)) + return NULL; + path = mu_msg_get_path (msg); if (!path) return NULL; @@ -270,6 +293,9 @@ mu_msg_part_save (MuMsg *msg, const char *fullpath, guint partidx, g_return_val_if_fail (fullpath, FALSE); g_return_val_if_fail (!overwrite||!use_cached, FALSE); + if (!load_msg_file_maybe (msg)) + return FALSE; + part = find_part (msg, partidx); if (!GMIME_IS_PART(part)) { g_set_error (err, 0, MU_ERROR_GMIME, @@ -338,6 +364,9 @@ mu_msg_part_find_cid (MuMsg *msg, const char* sought_cid) g_return_val_if_fail (msg, -1); g_return_val_if_fail (sought_cid, -1); + if (!load_msg_file_maybe (msg)) + return -1; + cid = g_str_has_prefix (sought_cid, "cid:") ? sought_cid + 4 : sought_cid; @@ -382,6 +411,9 @@ mu_msg_part_find_files (MuMsg *msg, const GRegex *pattern) g_return_val_if_fail (msg, NULL); g_return_val_if_fail (pattern, NULL); + if (!load_msg_file_maybe (msg)) + return NULL; + mdata._lst = NULL; mdata._rx = pattern; mdata._idx = 0;