mirror of
https://github.com/djcb/mu.git
synced 2024-06-26 07:29:17 +02:00
* mu find: add support for '--after', to only consider messages with mtime
after timestamp. This is useful for finding just-arrived messages.
This commit is contained in:
parent
c9fc49cfd6
commit
a9df392fcf
|
@ -396,6 +396,20 @@ Note: when \fBmu\fR creates a Maildir for these links, it automatically
|
||||||
inserts a \fI.noindex\fR file, to exclude the directory from \fBmu
|
inserts a \fI.noindex\fR file, to exclude the directory from \fBmu
|
||||||
index\fR.
|
index\fR.
|
||||||
|
|
||||||
|
.TP
|
||||||
|
\fB\-\-after=\fR\fI<timestamp>\fR only show messages whose message files were
|
||||||
|
last modified (\fBmtime\fR) after \fI<timestamp>\fR. \fI<timestamp>\fR is a
|
||||||
|
UNIX \fBtime_t\fR value, the number of seconds since 1970-01-01 (in UTC).
|
||||||
|
|
||||||
|
From the command line, you can use the \fBdate\fR command to get this
|
||||||
|
value. For example, only consider messages modified (or created) in the last 5
|
||||||
|
minutes, you could specify
|
||||||
|
.nf
|
||||||
|
--after=`date +%s --date='5 min ago'`
|
||||||
|
.fi
|
||||||
|
This is assuming the GNU \fBdate\fR command.
|
||||||
|
|
||||||
|
|
||||||
.TP
|
.TP
|
||||||
\fB\-\-exec\fR=\fI<command>\fR
|
\fB\-\-exec\fR=\fI<command>\fR
|
||||||
the \fB\-\-exec\fR command causes the \fIcommand\fR to be executed on each
|
the \fB\-\-exec\fR command causes the \fIcommand\fR to be executed on each
|
||||||
|
|
402
mu/mu-cmd-find.c
402
mu/mu-cmd-find.c
|
@ -40,22 +40,20 @@
|
||||||
#include "mu-bookmarks.h"
|
#include "mu-bookmarks.h"
|
||||||
#include "mu-runtime.h"
|
#include "mu-runtime.h"
|
||||||
|
|
||||||
|
|
||||||
#include "mu-util.h"
|
#include "mu-util.h"
|
||||||
#include "mu-cmd.h"
|
#include "mu-cmd.h"
|
||||||
#include "mu-threader.h"
|
#include "mu-threader.h"
|
||||||
|
|
||||||
|
static gboolean output_links (MuMsg *msg, const char* linksdir,
|
||||||
static gboolean output_links (MuMsgIter *iter, const char* linksdir,
|
|
||||||
gboolean clearlinks, GError **err);
|
gboolean clearlinks, GError **err);
|
||||||
static gboolean output_sexp (MuMsgIter *iter, gboolean threads,
|
static gboolean output_sexp (MuMsg *msg, MuMsgIter *iter, gboolean threads,
|
||||||
gboolean include_unreadable, GError **err);
|
|
||||||
static gboolean output_xml (MuMsgIter *iter,gboolean include_unreadable,
|
|
||||||
GError **err);
|
|
||||||
static gboolean output_plain (MuMsgIter *iter, const char *fields,
|
|
||||||
int summary_len, gboolean threads,
|
|
||||||
gboolean color, gboolean include_unreadable,
|
|
||||||
GError **err);
|
GError **err);
|
||||||
|
/* static gboolean output_xml (MuMsg *msg, GError **err); */
|
||||||
|
static gboolean output_plain (MuMsg *msg, MuMsgIter *iter, const char *fields,
|
||||||
|
int summary_len, gboolean threads,
|
||||||
|
gboolean color, GError **err);
|
||||||
|
|
||||||
|
static gboolean exec_cmd (MuMsg *msg, const char *cmd, GError **err);
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
print_xapian_query (MuQuery *xapian, const gchar *query, GError **err)
|
print_xapian_query (MuQuery *xapian, const gchar *query, GError **err)
|
||||||
|
@ -92,32 +90,34 @@ sort_field_from_string (const char* fieldstr, GError **err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static gboolean
|
static MuMsg*
|
||||||
output_query_results (MuMsgIter *iter, MuConfig *opts, GError **err)
|
get_message (MuMsgIter *iter, time_t after)
|
||||||
{
|
{
|
||||||
switch (opts->format) {
|
MuMsg *msg;
|
||||||
case MU_CONFIG_FORMAT_LINKS:
|
|
||||||
return output_links (iter, opts->linksdir, opts->clearlinks, err);
|
if (mu_msg_iter_is_done (iter))
|
||||||
case MU_CONFIG_FORMAT_PLAIN:
|
return NULL;
|
||||||
return output_plain (iter, opts->fields,
|
|
||||||
opts->summary ? opts->summary_len : 0,
|
msg = mu_msg_iter_get_msg_floating (iter);
|
||||||
opts->threads, !opts->nocolor,
|
if (!msg)
|
||||||
opts->include_unreadable, err);
|
return NULL; /* error */
|
||||||
case MU_CONFIG_FORMAT_XML:
|
|
||||||
return output_xml (iter, opts->include_unreadable, err);
|
if (!mu_msg_is_readable (msg)) {
|
||||||
case MU_CONFIG_FORMAT_SEXP:
|
mu_msg_iter_next (iter);
|
||||||
return output_sexp (iter, opts->threads,
|
return get_message (iter, after);
|
||||||
opts->include_unreadable, err);
|
|
||||||
default:
|
|
||||||
g_assert_not_reached ();
|
|
||||||
return FALSE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (after != 0 && after > mu_msg_get_timestamp (msg)) {
|
||||||
|
mu_msg_iter_next (iter);
|
||||||
|
return get_message (iter, after);
|
||||||
|
}
|
||||||
|
|
||||||
|
return msg;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static MuMsgIter*
|
static MuMsgIter*
|
||||||
run_query (MuQuery *xapian, const gchar *query, MuConfig *opts,
|
run_query (MuQuery *xapian, const gchar *query, MuConfig *opts, GError **err)
|
||||||
GError **err)
|
|
||||||
{
|
{
|
||||||
MuMsgIter *iter;
|
MuMsgIter *iter;
|
||||||
MuMsgFieldId sortid;
|
MuMsgFieldId sortid;
|
||||||
|
@ -135,6 +135,61 @@ run_query (MuQuery *xapian, const gchar *query, MuConfig *opts,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
output_query_results (MuMsgIter *iter, MuConfig *opts, GError **err)
|
||||||
|
{
|
||||||
|
unsigned count;
|
||||||
|
gboolean rv;
|
||||||
|
|
||||||
|
for (count = 0, rv = TRUE; !mu_msg_iter_is_done(iter);
|
||||||
|
mu_msg_iter_next (iter)) {
|
||||||
|
|
||||||
|
MuMsg *msg;
|
||||||
|
|
||||||
|
msg = get_message (iter, opts->after);
|
||||||
|
if (!msg)
|
||||||
|
break;
|
||||||
|
|
||||||
|
switch (opts->format) {
|
||||||
|
case MU_CONFIG_FORMAT_EXEC:
|
||||||
|
rv = exec_cmd (msg, opts->exec, err);
|
||||||
|
break;
|
||||||
|
case MU_CONFIG_FORMAT_LINKS:
|
||||||
|
rv = output_links (msg, opts->linksdir, opts->clearlinks, err);
|
||||||
|
break;
|
||||||
|
case MU_CONFIG_FORMAT_PLAIN:
|
||||||
|
rv = output_plain (msg, iter, opts->fields,
|
||||||
|
opts->summary ? opts->summary_len : 0,
|
||||||
|
opts->threads, !opts->nocolor, err);
|
||||||
|
break;
|
||||||
|
/* case MU_CONFIG_FORMAT_XML: */
|
||||||
|
/* rv = output_xml (msg, err); */
|
||||||
|
/* break; */
|
||||||
|
case MU_CONFIG_FORMAT_SEXP:
|
||||||
|
rv = output_sexp (msg, iter, opts->threads, err);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
g_return_val_if_reached (FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!rv)
|
||||||
|
break;
|
||||||
|
else
|
||||||
|
++count;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rv && count == 0) {
|
||||||
|
mu_util_g_set_error (err, MU_ERROR_NO_MATCHES,
|
||||||
|
"no matches for search expression");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
process_query (MuQuery *xapian, const gchar *query, MuConfig *opts, GError **err)
|
process_query (MuQuery *xapian, const gchar *query, MuConfig *opts, GError **err)
|
||||||
{
|
{
|
||||||
|
@ -153,24 +208,17 @@ process_query (MuQuery *xapian, const gchar *query, MuConfig *opts, GError **err
|
||||||
|
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
exec_cmd (const char *path, const char *cmd, GError **err)
|
exec_cmd (MuMsg *msg, const char *cmd, GError **err)
|
||||||
{
|
{
|
||||||
gint status;
|
gint status;
|
||||||
char *cmdline, *escpath;
|
char *cmdline, *escpath;
|
||||||
gboolean rv;
|
gboolean rv;
|
||||||
|
|
||||||
if (access (path, R_OK) != 0) {
|
escpath = g_strescape (mu_msg_get_path (msg), NULL);
|
||||||
g_set_error (err, MU_ERROR_DOMAIN, MU_ERROR_FILE_CANNOT_READ,
|
|
||||||
"cannot read %s: %s", path, strerror(errno));
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
escpath = g_strescape (path, NULL);
|
|
||||||
|
|
||||||
cmdline = g_strdup_printf ("%s %s", cmd, escpath);
|
cmdline = g_strdup_printf ("%s %s", cmd, escpath);
|
||||||
err = NULL;
|
|
||||||
rv = g_spawn_command_line_sync (cmdline, NULL, NULL,
|
rv = g_spawn_command_line_sync (cmdline, NULL, NULL, &status, err);
|
||||||
&status, err);
|
|
||||||
g_free (cmdline);
|
g_free (cmdline);
|
||||||
g_free (escpath);
|
g_free (escpath);
|
||||||
|
|
||||||
|
@ -178,75 +226,39 @@ exec_cmd (const char *path, const char *cmd, GError **err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static gboolean
|
|
||||||
exec_cmd_on_query (MuQuery *xapian, const gchar *query, MuConfig *opts,
|
|
||||||
GError **err)
|
|
||||||
{
|
|
||||||
MuMsgIter *iter;
|
|
||||||
gboolean rv;
|
|
||||||
size_t count;
|
|
||||||
|
|
||||||
if (!(iter = run_query (xapian, query, opts, err)))
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
for (rv = TRUE, count = 0; !mu_msg_iter_is_done (iter);
|
|
||||||
mu_msg_iter_next(iter)) {
|
|
||||||
const char *path;
|
|
||||||
MuMsg *msg;
|
|
||||||
|
|
||||||
msg = mu_msg_iter_get_msg_floating (iter);
|
|
||||||
if (!msg)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
path = mu_msg_get_path (msg);
|
|
||||||
if (!msg) {
|
|
||||||
g_warning ("cannot get path for msg");
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
rv = exec_cmd (path, opts->exec, err);
|
|
||||||
if (rv)
|
|
||||||
++count;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (count == 0) {
|
|
||||||
g_set_error (err, MU_ERROR_DOMAIN, MU_ERROR_NO_MATCHES,
|
|
||||||
"no matches for search expression");
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
mu_msg_iter_destroy (iter);
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
format_params_valid (MuConfig *opts, GError **err)
|
format_params_valid (MuConfig *opts, GError **err)
|
||||||
{
|
{
|
||||||
switch (opts->format) {
|
switch (opts->format) {
|
||||||
|
case MU_CONFIG_FORMAT_EXEC:
|
||||||
|
break;
|
||||||
case MU_CONFIG_FORMAT_PLAIN:
|
case MU_CONFIG_FORMAT_PLAIN:
|
||||||
case MU_CONFIG_FORMAT_SEXP:
|
case MU_CONFIG_FORMAT_SEXP:
|
||||||
case MU_CONFIG_FORMAT_LINKS:
|
case MU_CONFIG_FORMAT_LINKS:
|
||||||
case MU_CONFIG_FORMAT_XML:
|
case MU_CONFIG_FORMAT_XML:
|
||||||
case MU_CONFIG_FORMAT_XQUERY:
|
case MU_CONFIG_FORMAT_XQUERY:
|
||||||
|
if (opts->exec) {
|
||||||
|
mu_util_g_set_error (err, MU_ERROR_IN_PARAMETERS,
|
||||||
|
"--exec cannot be combined with --format");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
g_set_error (err, MU_ERROR_DOMAIN, MU_ERROR_IN_PARAMETERS,
|
mu_util_g_set_error (err, MU_ERROR_IN_PARAMETERS,
|
||||||
"invalid output format %s",
|
"invalid output format %s",
|
||||||
opts->formatstr ? opts->formatstr : "<none>");
|
opts->formatstr ? opts->formatstr : "<none>");
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (opts->format == MU_CONFIG_FORMAT_LINKS && !opts->linksdir) {
|
if (opts->format == MU_CONFIG_FORMAT_LINKS && !opts->linksdir) {
|
||||||
g_set_error (err, MU_ERROR_DOMAIN, MU_ERROR_IN_PARAMETERS,
|
mu_util_g_set_error (err, MU_ERROR_IN_PARAMETERS,
|
||||||
"missing --linksdir argument");
|
"missing --linksdir argument");
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (opts->linksdir && opts->format != MU_CONFIG_FORMAT_LINKS) {
|
if (opts->linksdir && opts->format != MU_CONFIG_FORMAT_LINKS) {
|
||||||
g_set_error (err, MU_ERROR_DOMAIN, MU_ERROR_IN_PARAMETERS,
|
mu_util_g_set_error (err, MU_ERROR_IN_PARAMETERS,
|
||||||
"--linksdir is only valid with --format=links");
|
"--linksdir is only valid with --format=links");
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -263,8 +275,9 @@ query_params_valid (MuConfig *opts, GError **err)
|
||||||
if (mu_util_check_dir (xpath, TRUE, FALSE))
|
if (mu_util_check_dir (xpath, TRUE, FALSE))
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
g_set_error (err, MU_ERROR_DOMAIN, MU_ERROR_FILE_CANNOT_READ,
|
mu_util_g_set_error (err, MU_ERROR_FILE_CANNOT_READ,
|
||||||
"'%s' is not a readable Xapian directory", xpath);
|
"'%s' is not a readable Xapian directory",
|
||||||
|
xpath);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -388,30 +401,6 @@ get_query_obj (MuStore *store, GError **err)
|
||||||
return mquery;
|
return mquery;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* create a linksdir if it not exist yet; if it already existed,
|
|
||||||
* remove old links if opts->clearlinks was specified */
|
|
||||||
static gboolean
|
|
||||||
create_linksdir_maybe (const char *linksdir, gboolean clearlinks)
|
|
||||||
{
|
|
||||||
GError *err;
|
|
||||||
|
|
||||||
err = NULL;
|
|
||||||
/* note, mu_maildir_mkdir simply ignores whatever part of the
|
|
||||||
* mail dir already exists */
|
|
||||||
if (!mu_maildir_mkdir (linksdir, 0700, TRUE, &err))
|
|
||||||
goto fail;
|
|
||||||
|
|
||||||
if (clearlinks && !mu_maildir_clear_links (linksdir, &err))
|
|
||||||
goto fail;
|
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
|
|
||||||
fail:
|
|
||||||
g_warning ("%s", err->message ? err->message : "unknown error");
|
|
||||||
g_clear_error (&err);
|
|
||||||
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
link_message (const char *src, const char *destdir)
|
link_message (const char *src, const char *destdir)
|
||||||
|
@ -441,43 +430,29 @@ link_message (const char *src, const char *destdir)
|
||||||
|
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
output_links (MuMsgIter *iter, const char* linksdir, gboolean clearlinks,
|
output_links (MuMsg *msg, const char *linksdir, gboolean clearlinks,
|
||||||
GError **err)
|
GError **err)
|
||||||
{
|
{
|
||||||
size_t count, errcount;
|
/* note, mu_maildir_mkdir simply ignores whatever part of the
|
||||||
MuMsgIter *myiter;
|
* mail dir already exists */
|
||||||
|
if (access (linksdir, X_OK) != 0) {
|
||||||
|
|
||||||
g_return_val_if_fail (iter, FALSE);
|
if (!mu_maildir_mkdir (linksdir, 0700, TRUE, err)) {
|
||||||
g_return_val_if_fail (linksdir, FALSE);
|
mu_util_g_set_error (err, MU_ERROR_FILE_CANNOT_MKDIR,
|
||||||
|
"error creating %s", linksdir);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
/* note: we create the linksdir even if there are no search results */
|
if (clearlinks && !mu_maildir_clear_links (linksdir, err)) {
|
||||||
if (!create_linksdir_maybe (linksdir, clearlinks))
|
mu_util_g_set_error (err, MU_ERROR_FILE,
|
||||||
return FALSE;
|
"error clearing links under %s", linksdir);
|
||||||
|
return FALSE;
|
||||||
for (myiter = iter, count = errcount = 0; !mu_msg_iter_is_done (myiter);
|
}
|
||||||
mu_msg_iter_next (myiter)) {
|
|
||||||
|
|
||||||
const char* path;
|
|
||||||
MuMsg *msg;
|
|
||||||
|
|
||||||
msg = mu_msg_iter_get_msg_floating (iter);
|
|
||||||
if (!msg)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
path = mu_msg_get_path (msg);
|
|
||||||
if (access (path, R_OK) == 0) /* only link to readable */
|
|
||||||
link_message (path, linksdir) ? ++count : ++errcount;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (errcount > 0) {
|
if (!link_message (mu_msg_get_path (msg), linksdir)) {
|
||||||
g_set_error (err, MU_ERROR_DOMAIN, MU_ERROR_FILE_CANNOT_LINK,
|
mu_util_g_set_error (err, MU_ERROR_FILE_CANNOT_LINK,
|
||||||
"error linking %u message(s)", (unsigned)errcount);
|
"error linking %s", mu_msg_get_path(msg));
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (count == 0) {
|
|
||||||
g_set_error (err, MU_ERROR_DOMAIN, MU_ERROR_NO_MATCHES,
|
|
||||||
"no matches for search expression");
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -655,51 +630,47 @@ output_plain_fields (MuMsg *msg, const char *fields,
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
output_plain (MuMsgIter *iter, const char *fields, int summary_len,
|
output_plain (MuMsg *msg, MuMsgIter *iter, const char *fields,
|
||||||
gboolean threads, gboolean color, gboolean include_unreadable, GError **err)
|
int summary_len, gboolean threads, gboolean color, GError **err)
|
||||||
{
|
{
|
||||||
MuMsgIter *myiter;
|
|
||||||
size_t count;
|
|
||||||
|
|
||||||
g_return_val_if_fail (iter, FALSE);
|
/* we reuse the color (whatever that may be)
|
||||||
g_return_val_if_fail (fields, FALSE);
|
* for message-priority for threads, too */
|
||||||
|
ansi_color_maybe (MU_MSG_FIELD_ID_PRIO, color);
|
||||||
|
if (threads)
|
||||||
|
thread_indent (iter);
|
||||||
|
|
||||||
for (myiter = iter, count = 0; !mu_msg_iter_is_done (myiter);
|
output_plain_fields (msg, fields, color, threads);
|
||||||
mu_msg_iter_next (myiter)) {
|
|
||||||
|
|
||||||
MuMsg *msg;
|
if (summary_len > 0)
|
||||||
msg = mu_msg_iter_get_msg_floating (iter); /* don't unref */
|
print_summary (msg, summary_len);
|
||||||
if (!msg)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
/* only return messages if they're actually
|
|
||||||
* readable (ie, live also outside the database) */
|
|
||||||
if (!include_unreadable && !mu_msg_is_readable (msg))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
/* we reuse the color (whatever that may be)
|
|
||||||
* for message-priority for threads, too */
|
|
||||||
ansi_color_maybe (MU_MSG_FIELD_ID_PRIO, color);
|
|
||||||
if (threads)
|
|
||||||
thread_indent (iter);
|
|
||||||
|
|
||||||
output_plain_fields (msg, fields, color, threads);
|
|
||||||
|
|
||||||
if (summary_len > 0)
|
|
||||||
print_summary (msg, summary_len);
|
|
||||||
|
|
||||||
++count;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (count == 0) {
|
|
||||||
g_set_error (err, MU_ERROR_DOMAIN, MU_ERROR_NO_MATCHES,
|
|
||||||
"no existing matches for search expression");
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
output_sexp (MuMsg *msg, MuMsgIter *iter, gboolean threads, GError **err)
|
||||||
|
{
|
||||||
|
|
||||||
|
char *sexp;
|
||||||
|
const MuMsgIterThreadInfo *ti;
|
||||||
|
|
||||||
|
ti = threads ? mu_msg_iter_get_thread_info (iter) : NULL;
|
||||||
|
sexp = mu_msg_to_sexp (msg, mu_msg_iter_get_docid (iter),
|
||||||
|
ti, TRUE, FALSE);
|
||||||
|
|
||||||
|
fputs (sexp, stdout);
|
||||||
|
g_free (sexp);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
print_attr_xml (const char* elm, const char *str)
|
print_attr_xml (const char* elm, const char *str)
|
||||||
{
|
{
|
||||||
|
@ -714,53 +685,6 @@ print_attr_xml (const char* elm, const char *str)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static gboolean
|
|
||||||
output_sexp (MuMsgIter *iter, gboolean threads,
|
|
||||||
gboolean include_unreadable, GError **err)
|
|
||||||
{
|
|
||||||
MuMsgIter *myiter;
|
|
||||||
size_t count;
|
|
||||||
|
|
||||||
g_return_val_if_fail (iter, FALSE);
|
|
||||||
|
|
||||||
for (myiter = iter, count = 0; !mu_msg_iter_is_done (myiter);
|
|
||||||
mu_msg_iter_next (myiter)) {
|
|
||||||
|
|
||||||
MuMsg *msg;
|
|
||||||
char *sexp;
|
|
||||||
const MuMsgIterThreadInfo *ti;
|
|
||||||
|
|
||||||
msg = mu_msg_iter_get_msg_floating (iter);
|
|
||||||
if (!msg)
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
/* only return messages if they're actually
|
|
||||||
* readable (ie, live also outside the database) */
|
|
||||||
if (!include_unreadable && !mu_msg_is_readable (msg))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
ti = threads ? mu_msg_iter_get_thread_info (iter) : NULL;
|
|
||||||
sexp = mu_msg_to_sexp (msg,
|
|
||||||
mu_msg_iter_get_docid (iter),
|
|
||||||
ti, TRUE, FALSE);
|
|
||||||
|
|
||||||
fputs (sexp, stdout);
|
|
||||||
g_free (sexp);
|
|
||||||
|
|
||||||
++count;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (count == 0) {
|
|
||||||
g_set_error (err, MU_ERROR_DOMAIN, MU_ERROR_NO_MATCHES,
|
|
||||||
"no existing matches for search expression");
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
output_xml_msg (MuMsg *msg)
|
output_xml_msg (MuMsg *msg)
|
||||||
{
|
{
|
||||||
|
@ -780,7 +704,7 @@ output_xml_msg (MuMsg *msg)
|
||||||
|
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
output_xml (MuMsgIter *iter, gboolean include_unreadable, GError **err)
|
output_xml (MuMsg *msg, gboolean include_unreadable, GError **err)
|
||||||
{
|
{
|
||||||
MuMsgIter *myiter;
|
MuMsgIter *myiter;
|
||||||
size_t count;
|
size_t count;
|
||||||
|
@ -817,6 +741,9 @@ output_xml (MuMsgIter *iter, gboolean include_unreadable, GError **err)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
execute_find (MuStore *store, MuConfig *opts, GError **err)
|
execute_find (MuStore *store, MuConfig *opts, GError **err)
|
||||||
{
|
{
|
||||||
|
@ -836,8 +763,6 @@ execute_find (MuStore *store, MuConfig *opts, GError **err)
|
||||||
|
|
||||||
if (opts->format == MU_CONFIG_FORMAT_XQUERY)
|
if (opts->format == MU_CONFIG_FORMAT_XQUERY)
|
||||||
rv = print_xapian_query (oracle, query_str, err);
|
rv = print_xapian_query (oracle, query_str, err);
|
||||||
else if (opts->exec)
|
|
||||||
rv = exec_cmd_on_query (oracle, query_str, opts, err);
|
|
||||||
else
|
else
|
||||||
rv = process_query (oracle, query_str, opts, err);
|
rv = process_query (oracle, query_str, opts, err);
|
||||||
|
|
||||||
|
@ -861,6 +786,9 @@ mu_cmd_find (MuStore *store, MuConfig *opts, GError **err)
|
||||||
g_return_val_if_fail (opts->cmd == MU_CONFIG_CMD_FIND,
|
g_return_val_if_fail (opts->cmd == MU_CONFIG_CMD_FIND,
|
||||||
MU_ERROR_INTERNAL);
|
MU_ERROR_INTERNAL);
|
||||||
|
|
||||||
|
if (opts->exec)
|
||||||
|
opts->format = MU_CONFIG_FORMAT_EXEC; /* pseudo format */
|
||||||
|
|
||||||
if (!query_params_valid (opts, err) || !format_params_valid(opts, err)) {
|
if (!query_params_valid (opts, err) || !format_params_valid(opts, err)) {
|
||||||
|
|
||||||
if (MU_G_ERROR_CODE(err) == MU_ERROR_IN_PARAMETERS)
|
if (MU_G_ERROR_CODE(err) == MU_ERROR_IN_PARAMETERS)
|
||||||
|
|
|
@ -229,9 +229,8 @@ config_options_group_find (void)
|
||||||
"'sexp', 'xquery')", NULL},
|
"'sexp', 'xquery')", NULL},
|
||||||
{"exec", 'e', 0, G_OPTION_ARG_STRING, &MU_CONFIG.exec,
|
{"exec", 'e', 0, G_OPTION_ARG_STRING, &MU_CONFIG.exec,
|
||||||
"execute command on each match message", NULL},
|
"execute command on each match message", NULL},
|
||||||
{"include-unreable", 0, 0, G_OPTION_ARG_NONE,
|
{"after", 0, 0, G_OPTION_ARG_INT, &MU_CONFIG.after,
|
||||||
&MU_CONFIG.include_unreadable,
|
"only show messages whose m_time > T (t_time)", NULL},
|
||||||
"don't ignore messages without a disk file (false)", NULL},
|
|
||||||
{NULL, 0, 0, 0, NULL, NULL, NULL}
|
{NULL, 0, 0, 0, NULL, NULL, NULL}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -53,7 +53,9 @@ enum _MuConfigFormat {
|
||||||
/* for find */
|
/* for find */
|
||||||
MU_CONFIG_FORMAT_LINKS, /* output as symlinks */
|
MU_CONFIG_FORMAT_LINKS, /* output as symlinks */
|
||||||
MU_CONFIG_FORMAT_XML, /* output xml */
|
MU_CONFIG_FORMAT_XML, /* output xml */
|
||||||
MU_CONFIG_FORMAT_XQUERY /* output the xapian query */
|
MU_CONFIG_FORMAT_XQUERY, /* output the xapian query */
|
||||||
|
|
||||||
|
MU_CONFIG_FORMAT_EXEC /* execute some command */
|
||||||
};
|
};
|
||||||
typedef enum _MuConfigFormat MuConfigFormat;
|
typedef enum _MuConfigFormat MuConfigFormat;
|
||||||
|
|
||||||
|
@ -129,17 +131,18 @@ struct _MuConfig {
|
||||||
char *exec; /* command to execute on the
|
char *exec; /* command to execute on the
|
||||||
* files for the matched
|
* files for the matched
|
||||||
* messages */
|
* messages */
|
||||||
gboolean include_unreadable; /* don't ignore messages
|
/* for find and cind */
|
||||||
* without a disk file */
|
time_t after; /* only show messages or
|
||||||
|
* adresses last seen after
|
||||||
|
* T */
|
||||||
|
|
||||||
/* options for view */
|
/* options for view */
|
||||||
gboolean terminator; /* add separator \f between
|
gboolean terminator; /* add separator \f between
|
||||||
* multiple messages in mu
|
* multiple messages in mu
|
||||||
* view */
|
* view */
|
||||||
/* options for cfind */
|
/* options for cfind (and 'find' --> "after") */
|
||||||
gboolean personal; /* only show 'personal' addresses */
|
gboolean personal; /* only show 'personal' addresses */
|
||||||
time_t after; /* only show addresses last
|
/* also 'after' --> see above */
|
||||||
* seen after T */
|
|
||||||
|
|
||||||
/* output to a maildir with symlinks */
|
/* output to a maildir with symlinks */
|
||||||
char *linksdir; /* maildir to output symlinks */
|
char *linksdir; /* maildir to output symlinks */
|
||||||
|
|
Loading…
Reference in New Issue
Block a user