* mu4e: load message by path (WIP)

This commit is contained in:
djcb
2012-09-20 21:34:19 +03:00
parent 1f93fecc9d
commit 0eb032e642
2 changed files with 77 additions and 24 deletions

View File

@ -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;

View File

@ -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