* mu4e: load message by path (WIP)
This commit is contained in:
@ -969,6 +969,26 @@ set_my_addresses (MuStore *store, const char *addrstr)
|
|||||||
g_strfreev (my_addresses);
|
g_strfreev (my_addresses);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static char*
|
||||||
|
get_checked_path (const char *path)
|
||||||
|
{
|
||||||
|
char *cpath;
|
||||||
|
|
||||||
|
cpath = mu_util_dir_expand(path);
|
||||||
|
if (!cpath ||
|
||||||
|
!mu_util_check_dir (cpath, TRUE, FALSE)) {
|
||||||
|
print_error (MU_ERROR_IN_PARAMETERS,
|
||||||
|
"not a readable dir: '%s'");
|
||||||
|
g_free (cpath);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return cpath;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* 'index' (re)indexs maildir at path:<path>, and responds with (:info
|
* 'index' (re)indexs maildir at path:<path>, and responds with (:info
|
||||||
* index ... ) messages while doing so (see the code)
|
* index ... ) messages while doing so (see the code)
|
||||||
@ -977,23 +997,26 @@ static MuError
|
|||||||
cmd_index (ServerContext *ctx, GSList *args, GError **err)
|
cmd_index (ServerContext *ctx, GSList *args, GError **err)
|
||||||
{
|
{
|
||||||
MuIndex *index;
|
MuIndex *index;
|
||||||
const char *path;
|
const char *argpath;
|
||||||
|
char *path;
|
||||||
MuIndexStats stats, stats2;
|
MuIndexStats stats, stats2;
|
||||||
MuError rv;
|
MuError rv;
|
||||||
|
|
||||||
GET_STRING_OR_ERROR_RETURN (args, "path", &path, err);
|
index = NULL;
|
||||||
|
|
||||||
|
GET_STRING_OR_ERROR_RETURN (args, "path", &argpath, err);
|
||||||
|
if (!(path = get_checked_path (argpath)))
|
||||||
|
goto leave;
|
||||||
|
|
||||||
set_my_addresses (ctx->store, get_string_from_args
|
set_my_addresses (ctx->store, get_string_from_args
|
||||||
(args, "my-addresses", TRUE, NULL));
|
(args, "my-addresses", TRUE, NULL));
|
||||||
|
|
||||||
index = mu_index_new (ctx->store, err);
|
if (!(index = mu_index_new (ctx->store, err)))
|
||||||
if (!index) {
|
goto leave;
|
||||||
print_and_clear_g_error (err);
|
|
||||||
return MU_OK;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
mu_index_stats_clear (&stats);
|
mu_index_stats_clear (&stats);
|
||||||
rv = mu_index_run (index, path, FALSE, &stats, index_msg_cb, NULL, NULL);
|
rv = mu_index_run (index, argpath, FALSE, &stats,
|
||||||
|
index_msg_cb, NULL, NULL);
|
||||||
if (rv != MU_OK && rv != MU_STOP) {
|
if (rv != MU_OK && rv != MU_STOP) {
|
||||||
print_error (MU_ERROR_INTERNAL, "indexing failed");
|
print_error (MU_ERROR_INTERNAL, "indexing failed");
|
||||||
goto leave;
|
goto leave;
|
||||||
@ -1011,6 +1034,11 @@ cmd_index (ServerContext *ctx, GSList *args, GError **err)
|
|||||||
":processed %u :updated %u :cleaned-up %u)",
|
":processed %u :updated %u :cleaned-up %u)",
|
||||||
stats._processed, stats._updated, stats2._cleaned_up);
|
stats._processed, stats._updated, stats2._cleaned_up);
|
||||||
leave:
|
leave:
|
||||||
|
g_free (path);
|
||||||
|
|
||||||
|
if (err && *err)
|
||||||
|
print_and_clear_g_error (err);
|
||||||
|
|
||||||
mu_index_destroy (index);
|
mu_index_destroy (index);
|
||||||
return MU_OK;
|
return MU_OK;
|
||||||
}
|
}
|
||||||
@ -1341,8 +1369,6 @@ cmd_sent (ServerContext *ctx, GSList *args, GError **err)
|
|||||||
return MU_OK;
|
return MU_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* 'view' gets a full (including body etc.) sexp for some message,
|
/* 'view' gets a full (including body etc.) sexp for some message,
|
||||||
* identified by either docid: or msgid:; return a (:view <sexp>)
|
* identified by either docid: or msgid:; return a (:view <sexp>)
|
||||||
*/
|
*/
|
||||||
@ -1350,9 +1376,10 @@ static MuError
|
|||||||
cmd_view (ServerContext *ctx, GSList *args, GError **err)
|
cmd_view (ServerContext *ctx, GSList *args, GError **err)
|
||||||
{
|
{
|
||||||
MuMsg *msg;
|
MuMsg *msg;
|
||||||
unsigned docid;
|
const gchar *path;
|
||||||
char *sexp;
|
char *sexp;
|
||||||
MuMsgOptions opts;
|
MuMsgOptions opts;
|
||||||
|
unsigned docid;
|
||||||
|
|
||||||
opts = MU_MSG_OPTION_VERIFY;
|
opts = MU_MSG_OPTION_VERIFY;
|
||||||
if (get_bool_from_args (args, "extract-images", FALSE, NULL))
|
if (get_bool_from_args (args, "extract-images", FALSE, NULL))
|
||||||
@ -1364,13 +1391,22 @@ cmd_view (ServerContext *ctx, GSList *args, GError **err)
|
|||||||
if (get_bool_from_args (args, "extract-encrypted", FALSE, NULL))
|
if (get_bool_from_args (args, "extract-encrypted", FALSE, NULL))
|
||||||
opts |= MU_MSG_OPTION_DECRYPT;
|
opts |= MU_MSG_OPTION_DECRYPT;
|
||||||
|
|
||||||
docid = determine_docid (ctx->query, args, err);
|
/* when 'path' is specified, get the message at path */
|
||||||
if (docid == MU_STORE_INVALID_DOCID) {
|
path = get_string_from_args (args, "path", FALSE, NULL);
|
||||||
print_and_clear_g_error (err);
|
|
||||||
return MU_OK;
|
if (path) {
|
||||||
|
docid = 0;
|
||||||
|
msg = mu_msg_new_from_file (path, NULL, err);
|
||||||
|
} else {
|
||||||
|
docid = determine_docid (ctx->query, args, err);
|
||||||
|
if (docid == MU_STORE_INVALID_DOCID) {
|
||||||
|
print_and_clear_g_error (err);
|
||||||
|
return MU_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
msg = mu_store_get_msg (ctx->store, docid, err);
|
||||||
}
|
}
|
||||||
|
|
||||||
msg = mu_store_get_msg (ctx->store, docid, err);
|
|
||||||
if (!msg) {
|
if (!msg) {
|
||||||
print_and_clear_g_error (err);
|
print_and_clear_g_error (err);
|
||||||
return MU_OK;
|
return MU_OK;
|
||||||
|
|||||||
@ -110,17 +110,20 @@ data removed."
|
|||||||
;; mu4e~cookie-matcher-rx:
|
;; mu4e~cookie-matcher-rx:
|
||||||
;; (concat mu4e~cookie-pre "\\([[:xdigit:]]+\\)]" mu4e~cookie-post)
|
;; (concat mu4e~cookie-pre "\\([[:xdigit:]]+\\)]" mu4e~cookie-post)
|
||||||
(ignore-errors ;; an error would e.g. when proc is killed in the middel
|
(ignore-errors ;; an error would e.g. when proc is killed in the middel
|
||||||
(let ((b (string-match mu4e~cookie-matcher-rx mu4e~proc-buf)) (sexp-len) (objcons))
|
(let ((b (string-match mu4e~cookie-matcher-rx mu4e~proc-buf))
|
||||||
|
(sexp-len) (objcons))
|
||||||
(when b
|
(when b
|
||||||
(setq sexp-len (string-to-number (match-string 1 mu4e~proc-buf) 16))
|
(setq sexp-len (string-to-number (match-string 1 mu4e~proc-buf) 16))
|
||||||
;; does mu4e~proc-buf contain the full sexp?
|
;; does mu4e~proc-buf contain the full sexp?
|
||||||
(when (>= (length mu4e~proc-buf) (+ sexp-len (match-end 0)))
|
(when (>= (length mu4e~proc-buf) (+ sexp-len (match-end 0)))
|
||||||
;; clear-up start
|
;; clear-up start
|
||||||
(setq mu4e~proc-buf (substring mu4e~proc-buf (match-end 0)))
|
(setq mu4e~proc-buf (substring mu4e~proc-buf (match-end 0)))
|
||||||
;; note: we read the input in binary mode -- here, we take the part that
|
;; note: we read the input in binary mode -- here, we take the part
|
||||||
;; is the sexp, and convert that to utf-8, before we interpret it.
|
;; that is the sexp, and convert that to utf-8, before we interpret
|
||||||
|
;; it.
|
||||||
(setq objcons (read-from-string
|
(setq objcons (read-from-string
|
||||||
(decode-coding-string (substring mu4e~proc-buf 0 sexp-len)
|
(decode-coding-string
|
||||||
|
(substring mu4e~proc-buf 0 sexp-len)
|
||||||
'utf-8 t)))
|
'utf-8 t)))
|
||||||
(when objcons
|
(when objcons
|
||||||
(setq mu4e~proc-buf (substring mu4e~proc-buf sexp-len))
|
(setq mu4e~proc-buf (substring mu4e~proc-buf sexp-len))
|
||||||
@ -242,7 +245,8 @@ The server output is as follows:
|
|||||||
((plist-get sexp :temp)
|
((plist-get sexp :temp)
|
||||||
(funcall mu4e-temp-func
|
(funcall mu4e-temp-func
|
||||||
(plist-get sexp :temp) ;; name of the temp file
|
(plist-get sexp :temp) ;; name of the temp file
|
||||||
(plist-get sexp :what) ;; what to do with it (pipe|emacs|open-with...)
|
(plist-get sexp :what) ;; what to do with it
|
||||||
|
;; (pipe|emacs|open-with...)
|
||||||
(plist-get sexp :param)));; parameter for the action
|
(plist-get sexp :param)));; parameter for the action
|
||||||
|
|
||||||
;; get some info
|
;; get some info
|
||||||
@ -454,8 +458,8 @@ seen AFTER (the time_t value)."
|
|||||||
(or after 0)))
|
(or after 0)))
|
||||||
|
|
||||||
(defun mu4e~proc-view (docid-or-msgid &optional images decrypt)
|
(defun mu4e~proc-view (docid-or-msgid &optional images decrypt)
|
||||||
"Get one particular message based on its DOCID-OR-MSGID (keyword
|
"Get one particular message based on its
|
||||||
argument). Optionally, if IMAGES is non-nil, backend will any
|
DOCID-OR-MSGID. Optionally, if IMAGES is non-nil, backend will any
|
||||||
images attached to the message, and return them as temp files. The
|
images attached to the message, and return them as temp files. The
|
||||||
result will be delivered to the function registered as
|
result will be delivered to the function registered as
|
||||||
`mu4e-message-func'."
|
`mu4e-message-func'."
|
||||||
@ -465,5 +469,18 @@ result will be delivered to the function registered as
|
|||||||
(if images "true" "false")
|
(if images "true" "false")
|
||||||
(if decrypt "true" "false")))
|
(if decrypt "true" "false")))
|
||||||
|
|
||||||
|
(defun mu4e~proc-view-path (path &optional images decrypt)
|
||||||
|
"View message at PATH (keyword
|
||||||
|
argument). Optionally, if IMAGES is non-nil, backend will any
|
||||||
|
images attached to the message, and return them as temp files. The
|
||||||
|
result will be delivered to the function registered as
|
||||||
|
`mu4e-message-func'."
|
||||||
|
(mu4e~proc-send-command
|
||||||
|
"view path:\"%s\" extract-images:%s extract-encrypted:%s"
|
||||||
|
path
|
||||||
|
(if images "true" "false")
|
||||||
|
(if decrypt "true" "false")))
|
||||||
|
|
||||||
|
|
||||||
(provide 'mu4e-proc)
|
(provide 'mu4e-proc)
|
||||||
;; End of mu4e-proc.el
|
;; End of mu4e-proc.el
|
||||||
|
|||||||
Reference in New Issue
Block a user