mirror of
https://github.com/djcb/mu.git
synced 2024-06-29 07:51:04 +02:00
* support getting all image attachments as temp files (change in mu-msg-sexp
api)
This commit is contained in:
parent
3bbff2e9ad
commit
47e7720464
|
@ -215,8 +215,11 @@ update the database accordingly.
|
||||||
Using the \fBview\fR command, we can all information (including the body) of a
|
Using the \fBview\fR command, we can all information (including the body) of a
|
||||||
particular e-mail message.
|
particular e-mail message.
|
||||||
|
|
||||||
|
If the optional parameter \fBextract-images\fR is \fBtrue\fR, extract images
|
||||||
|
to temp files, and include links to them in the returned s-exp.
|
||||||
|
|
||||||
.nf
|
.nf
|
||||||
-> view docid:<docid>|msgid:<msgid>
|
-> view docid:<docid>|msgid:<msgid> [extract-images:true]
|
||||||
<- (:view <s-exp>)
|
<- (:view <s-exp>)
|
||||||
.fi
|
.fi
|
||||||
|
|
||||||
|
|
|
@ -743,7 +743,7 @@ output_sexp (MuMsgIter *iter, gboolean threads,
|
||||||
ti = threads ? mu_msg_iter_get_thread_info (iter) : NULL;
|
ti = threads ? mu_msg_iter_get_thread_info (iter) : NULL;
|
||||||
sexp = mu_msg_to_sexp (msg,
|
sexp = mu_msg_to_sexp (msg,
|
||||||
mu_msg_iter_get_docid (iter),
|
mu_msg_iter_get_docid (iter),
|
||||||
ti, TRUE);
|
ti, TRUE, FALSE);
|
||||||
|
|
||||||
fputs (sexp, stdout);
|
fputs (sexp, stdout);
|
||||||
g_free (sexp);
|
g_free (sexp);
|
||||||
|
|
|
@ -188,7 +188,7 @@ read_line_as_list (GError **err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const char*
|
static const char*
|
||||||
get_string_from_args (GSList *args, const char *param, gboolean optional,
|
get_string_from_args (GSList *args, const char *param, gboolean optional,
|
||||||
GError **err)
|
GError **err)
|
||||||
{
|
{
|
||||||
|
@ -215,6 +215,27 @@ get_string_from_args (GSList *args, const char *param, gboolean optional,
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
get_bool_from_args (GSList *args, const char *param, gboolean optional, GError **err)
|
||||||
|
{
|
||||||
|
const char *val;
|
||||||
|
|
||||||
|
val = get_string_from_args (args, param, optional, err);
|
||||||
|
if (err && (*err != NULL))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
if (g_strcmp0 (val, "true") == 0)
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
if (!val || g_strcmp0 (val, "false") == 0)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
mu_util_g_set_error (err, MU_ERROR_IN_PARAMETERS,
|
||||||
|
"invalid value for parameter '%s'", param);
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#define GET_STRING_OR_ERROR_RETURN(ARGS,PARAM,SP,E) \
|
#define GET_STRING_OR_ERROR_RETURN(ARGS,PARAM,SP,E) \
|
||||||
do { \
|
do { \
|
||||||
|
@ -479,7 +500,7 @@ cmd_compose (MuStore *store, MuQuery *query, GSList *args, GError **err)
|
||||||
print_and_clear_g_error (err);
|
print_and_clear_g_error (err);
|
||||||
return MU_OK;
|
return MU_OK;
|
||||||
}
|
}
|
||||||
sexp = mu_msg_to_sexp (msg, atoi(docidstr), NULL, FALSE);
|
sexp = mu_msg_to_sexp (msg, atoi(docidstr), NULL, FALSE, FALSE);
|
||||||
atts = (ctype == FORWARD) ? include_attachments (msg) : NULL;
|
atts = (ctype == FORWARD) ? include_attachments (msg) : NULL;
|
||||||
mu_msg_unref (msg);
|
mu_msg_unref (msg);
|
||||||
} else
|
} else
|
||||||
|
@ -512,7 +533,7 @@ print_sexps (MuMsgIter *iter, int maxnum)
|
||||||
char *sexp;
|
char *sexp;
|
||||||
sexp = mu_msg_to_sexp (msg, mu_msg_iter_get_docid (iter),
|
sexp = mu_msg_to_sexp (msg, mu_msg_iter_get_docid (iter),
|
||||||
mu_msg_iter_get_thread_info (iter),
|
mu_msg_iter_get_thread_info (iter),
|
||||||
TRUE);
|
TRUE, FALSE);
|
||||||
print_expr ("%s", sexp);
|
print_expr ("%s", sexp);
|
||||||
g_free (sexp);
|
g_free (sexp);
|
||||||
++u;
|
++u;
|
||||||
|
@ -846,7 +867,8 @@ do_move (MuStore *store, unsigned docid, MuMsg *msg, const char *maildir,
|
||||||
print_and_clear_g_error (err);
|
print_and_clear_g_error (err);
|
||||||
}
|
}
|
||||||
|
|
||||||
sexp = mu_msg_to_sexp (msg, docid, NULL, FALSE/*include body*/);
|
sexp = mu_msg_to_sexp (msg, docid, NULL, FALSE/*include body*/,
|
||||||
|
FALSE/*do not include images*/);
|
||||||
/* note, the :move t thing is a hint to the frontend that it
|
/* note, the :move t thing is a hint to the frontend that it
|
||||||
* could remove the particular header */
|
* could remove the particular header */
|
||||||
print_expr ("(:update %s :move %s)", sexp,
|
print_expr ("(:update %s :move %s)", sexp,
|
||||||
|
@ -1049,11 +1071,7 @@ cmd_remove (MuStore *store, MuQuery *query, GSList *args, GError **err)
|
||||||
|
|
||||||
path = get_path_from_docid (store, docid, err);
|
path = get_path_from_docid (store, docid, err);
|
||||||
if (!path) {
|
if (!path) {
|
||||||
if (err && *err)
|
|
||||||
print_and_clear_g_error (err);
|
print_and_clear_g_error (err);
|
||||||
else
|
|
||||||
print_error (MU_ERROR_IN_PARAMETERS,
|
|
||||||
"no path for docid");
|
|
||||||
return MU_OK;
|
return MU_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1114,6 +1132,13 @@ cmd_view (MuStore *store, MuQuery *query, GSList *args, GError **err)
|
||||||
MuMsg *msg;
|
MuMsg *msg;
|
||||||
unsigned docid;
|
unsigned docid;
|
||||||
char *sexp;
|
char *sexp;
|
||||||
|
gboolean extract_images;
|
||||||
|
|
||||||
|
extract_images = get_bool_from_args (args, "extract-images", FALSE, err);
|
||||||
|
if (err && *err) {
|
||||||
|
print_and_clear_g_error (err);
|
||||||
|
return MU_OK;
|
||||||
|
}
|
||||||
|
|
||||||
docid = determine_docid (query, args, err);
|
docid = determine_docid (query, args, err);
|
||||||
if (docid == MU_STORE_INVALID_DOCID) {
|
if (docid == MU_STORE_INVALID_DOCID) {
|
||||||
|
@ -1123,15 +1148,11 @@ cmd_view (MuStore *store, MuQuery *query, GSList *args, GError **err)
|
||||||
|
|
||||||
msg = mu_store_get_msg (store, docid, err);
|
msg = mu_store_get_msg (store, docid, err);
|
||||||
if (!msg) {
|
if (!msg) {
|
||||||
if (err && *err)
|
|
||||||
print_and_clear_g_error (err);
|
print_and_clear_g_error (err);
|
||||||
else
|
|
||||||
print_error (MU_ERROR_IN_PARAMETERS,
|
|
||||||
"failed to get message");
|
|
||||||
return MU_OK;
|
return MU_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
sexp = mu_msg_to_sexp (msg, docid, NULL, FALSE);
|
sexp = mu_msg_to_sexp (msg, docid, NULL, FALSE, extract_images);
|
||||||
mu_msg_unref (msg);
|
mu_msg_unref (msg);
|
||||||
|
|
||||||
print_expr ("(:view %s)\n", sexp);
|
print_expr ("(:view %s)\n", sexp);
|
||||||
|
|
|
@ -48,7 +48,7 @@ view_msg_sexp (MuMsg *msg)
|
||||||
{
|
{
|
||||||
char *sexp;
|
char *sexp;
|
||||||
|
|
||||||
sexp = mu_msg_to_sexp (msg, 0, NULL, FALSE);
|
sexp = mu_msg_to_sexp (msg, 0, NULL, FALSE, FALSE);
|
||||||
fputs (sexp, stdout);
|
fputs (sexp, stdout);
|
||||||
g_free (sexp);
|
g_free (sexp);
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
** Copyright (C) 2011 Dirk-Jan C. Binnema <djcb@djcbsoftware.nl>
|
** Copyright (C) 2011-2012 Dirk-Jan C. Binnema <djcb@djcbsoftware.nl>
|
||||||
**
|
**
|
||||||
** This program is free software; you can redistribute it and/or modify it
|
** This program is free software; you can redistribute it and/or modify it
|
||||||
** under the terms of the GNU General Public License as published by the
|
** under the terms of the GNU General Public License as published by the
|
||||||
|
@ -201,12 +201,40 @@ append_sexp_flags (GString *gstr, MuMsg *msg)
|
||||||
g_free (fdata.flagstr);
|
g_free (fdata.flagstr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static char*
|
||||||
|
get_temp_file (MuMsg *msg, unsigned index)
|
||||||
|
{
|
||||||
|
char *path;
|
||||||
|
GError *err;
|
||||||
|
|
||||||
|
err = NULL;
|
||||||
|
path = mu_msg_part_filepath_cache (msg, index);
|
||||||
|
if (!mu_msg_part_save (msg, path, index,
|
||||||
|
FALSE/*overwrite*/, TRUE/*use cache*/, &err)) {
|
||||||
|
g_warning ("failed to save mime part: %s",
|
||||||
|
err->message ? err->message : "something went wrong");
|
||||||
|
g_clear_error (&err);
|
||||||
|
g_free (path);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
struct _PartInfo {
|
||||||
|
char *parts;
|
||||||
|
gboolean want_images;
|
||||||
|
};
|
||||||
|
typedef struct _PartInfo PartInfo;
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
each_part (MuMsg *msg, MuMsgPart *part, gchar **parts)
|
each_part (MuMsg *msg, MuMsgPart *part, PartInfo *pinfo)
|
||||||
{
|
{
|
||||||
const char *fname;
|
const char *fname;
|
||||||
char *name, *tmp;
|
char *name, *tmp;
|
||||||
|
char *tmpfile;
|
||||||
|
|
||||||
fname = mu_msg_part_file_name (part);
|
fname = mu_msg_part_file_name (part);
|
||||||
if (!fname)
|
if (!fname)
|
||||||
|
@ -221,31 +249,44 @@ each_part (MuMsg *msg, MuMsgPart *part, gchar **parts)
|
||||||
part->subtype ? part->subtype : "octet-stream",
|
part->subtype ? part->subtype : "octet-stream",
|
||||||
part->index);
|
part->index);
|
||||||
|
|
||||||
|
tmpfile = NULL;
|
||||||
|
if (pinfo->want_images && g_ascii_strcasecmp (part->type, "image") == 0) {
|
||||||
|
char *tmp;
|
||||||
|
tmp = get_temp_file (msg, part->index);
|
||||||
|
if (tmp) {
|
||||||
|
tmpfile = mu_str_escape_c_literal (tmp, TRUE);
|
||||||
|
g_free (tmp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
tmp = g_strdup_printf
|
tmp = g_strdup_printf
|
||||||
("%s(:index %d :name %s :mime-type \"%s/%s\" :attachment %s :size %i)",
|
("%s(:index %d :name %s :mime-type \"%s/%s\"%s%s :attachment %s :size %i)",
|
||||||
*parts ? *parts : "", part->index, name,
|
pinfo->parts ? pinfo->parts : "", part->index, name,
|
||||||
part->type ? part->type : "application",
|
part->type ? part->type : "application",
|
||||||
part->subtype ? part->subtype : "octet-stream",
|
part->subtype ? part->subtype : "octet-stream",
|
||||||
|
tmpfile ? " :temp" : "", tmpfile ? tmpfile : "",
|
||||||
mu_msg_part_looks_like_attachment (part, TRUE) ? "t" : "nil",
|
mu_msg_part_looks_like_attachment (part, TRUE) ? "t" : "nil",
|
||||||
(int)part->size);
|
(int)part->size);
|
||||||
|
|
||||||
g_free (*parts);
|
g_free (pinfo->parts);
|
||||||
*parts = tmp;
|
pinfo->parts = tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
append_sexp_parts (GString *gstr, MuMsg *msg)
|
append_sexp_parts (GString *gstr, MuMsg *msg, gboolean want_images)
|
||||||
{
|
{
|
||||||
char *parts;
|
PartInfo pinfo;
|
||||||
|
|
||||||
|
pinfo.parts = NULL;
|
||||||
|
pinfo.want_images = want_images;
|
||||||
|
|
||||||
parts = NULL;
|
|
||||||
mu_msg_part_foreach (msg, FALSE,
|
mu_msg_part_foreach (msg, FALSE,
|
||||||
(MuMsgPartForeachFunc)each_part, &parts);
|
(MuMsgPartForeachFunc)each_part, &pinfo);
|
||||||
|
|
||||||
if (parts) {
|
if (pinfo.parts) {
|
||||||
g_string_append_printf (gstr, "\t:parts (%s)\n", parts);
|
g_string_append_printf (gstr, "\t:parts (%s)\n", pinfo.parts);
|
||||||
g_free (parts);
|
g_free (pinfo.parts);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -254,8 +295,6 @@ append_sexp_parts (GString *gstr, MuMsg *msg)
|
||||||
static void
|
static void
|
||||||
append_sexp_message_file_attr (GString *gstr, MuMsg *msg)
|
append_sexp_message_file_attr (GString *gstr, MuMsg *msg)
|
||||||
{
|
{
|
||||||
append_sexp_parts (gstr, msg);
|
|
||||||
|
|
||||||
append_sexp_attr_list (gstr, "references", mu_msg_get_references (msg));
|
append_sexp_attr_list (gstr, "references", mu_msg_get_references (msg));
|
||||||
append_sexp_attr (gstr, "in-reply-to",
|
append_sexp_attr (gstr, "in-reply-to",
|
||||||
mu_msg_get_header (msg, "In-Reply-To"));
|
mu_msg_get_header (msg, "In-Reply-To"));
|
||||||
|
@ -285,18 +324,21 @@ append_sexp_thread_info (GString *gstr, const MuMsgIterThreadInfo *ti)
|
||||||
|
|
||||||
char*
|
char*
|
||||||
mu_msg_to_sexp (MuMsg *msg, unsigned docid, const MuMsgIterThreadInfo *ti,
|
mu_msg_to_sexp (MuMsg *msg, unsigned docid, const MuMsgIterThreadInfo *ti,
|
||||||
gboolean header)
|
gboolean header_only, gboolean extract_images)
|
||||||
{
|
{
|
||||||
GString *gstr;
|
GString *gstr;
|
||||||
time_t t;
|
time_t t;
|
||||||
|
|
||||||
gstr = g_string_sized_new (header ? 1024 : 8192);
|
g_return_val_if_fail (msg, NULL);
|
||||||
|
g_return_val_if_fail (!(header_only && extract_images), NULL);
|
||||||
|
|
||||||
|
gstr = g_string_sized_new (header_only ? 1024 : 8192);
|
||||||
g_string_append (gstr, "(\n");
|
g_string_append (gstr, "(\n");
|
||||||
|
|
||||||
if (docid != 0)
|
if (docid != 0)
|
||||||
g_string_append_printf (gstr, "\t:docid %u\n", docid);
|
g_string_append_printf (gstr, "\t:docid %u\n", docid);
|
||||||
|
|
||||||
if (!header) /* force loading of file... should do this a bit
|
if (!header_only) /* force loading of file... should do this a bit
|
||||||
* more elegantly */
|
* more elegantly */
|
||||||
mu_msg_get_header (msg, "Reply-To");
|
mu_msg_get_header (msg, "Reply-To");
|
||||||
|
|
||||||
|
@ -327,8 +369,10 @@ mu_msg_to_sexp (MuMsg *msg, unsigned docid, const MuMsgIterThreadInfo *ti,
|
||||||
*
|
*
|
||||||
* file attr things can only be gotten from the file (ie., mu
|
* file attr things can only be gotten from the file (ie., mu
|
||||||
* view), not from the database (mu find). */
|
* view), not from the database (mu find). */
|
||||||
if (!header)
|
if (!header_only) {
|
||||||
append_sexp_message_file_attr (gstr, msg);
|
append_sexp_message_file_attr (gstr, msg);
|
||||||
|
append_sexp_parts (gstr, msg, extract_images);
|
||||||
|
}
|
||||||
|
|
||||||
g_string_append (gstr, ")\n");
|
g_string_append (gstr, ")\n");
|
||||||
|
|
||||||
|
|
|
@ -390,15 +390,17 @@ struct _MuMsgIterThreadInfo;
|
||||||
* @param msg a valid message
|
* @param msg a valid message
|
||||||
* @param docid the docid for this message, or 0
|
* @param docid the docid for this message, or 0
|
||||||
* @param ti thread info for the current message, or NULL
|
* @param ti thread info for the current message, or NULL
|
||||||
* @param dbonly if TRUE, only include message fields which can be
|
* @param headers if TRUE, only include message fields which can be
|
||||||
* obtained from the database (this is much faster if the MuMsg is
|
* obtained from the database (this is much faster if the MuMsg is
|
||||||
* database-backed, so no file needs to be opened)
|
* database-backed, so no file needs to be opened)
|
||||||
|
* @param extract_images if TRUE, extract image attachments as temporary
|
||||||
|
* files and include links to those in the sexp
|
||||||
*
|
*
|
||||||
* @return a string with the sexp (free with g_free) or NULL in case of error
|
* @return a string with the sexp (free with g_free) or NULL in case of error
|
||||||
*/
|
*/
|
||||||
char* mu_msg_to_sexp (MuMsg *msg, unsigned docid,
|
char* mu_msg_to_sexp (MuMsg *msg, unsigned docid,
|
||||||
const struct _MuMsgIterThreadInfo *ti,
|
const struct _MuMsgIterThreadInfo *ti,
|
||||||
gboolean dbonly);
|
gboolean headers_only, gboolean extract_images);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* move a message to another maildir; note that this does _not_ update
|
* move a message to another maildir; note that this does _not_ update
|
||||||
|
|
Loading…
Reference in New Issue
Block a user