* mu-mv: optionally, let it update the database (--updatedb) and print the

target file on stdout (--printtarget)
This commit is contained in:
Dirk-Jan C. Binnema 2011-08-02 21:27:32 +03:00
parent 92e95cf94d
commit bdf1237c34
7 changed files with 182 additions and 30 deletions

View File

@ -6,7 +6,7 @@ mu mv\- move a message file to a Maildir
.SH SYNOPSIS
.B mu mv <source-path> <target-maildir>
.B mu mv [--flags=<flags>] [--updatedb] [--printtarget] <source-path> <target-maildir>
.SH DESCRIPTION
@ -29,6 +29,29 @@ Note, unlike the UNIX \fImv\fR command, \fImu mv\fR takes precisely two
parameters. It's recommended not to use wildcards on the shell, the result may
be unexpected.
.SH OPTIONS
.TP
\fB\-\-flags\fR=\fI<flags>\fR
using the this option, you can change the file flags of the target file. If
you change the 'N' (new) flag, this will also change the exact target
directory ('new' vs 'cur').
The flags is a sequence of characters from the set D (draft), F (flagged) ,N
(new), P (passed), R (replied), S (seen) and T (trashed). Note, the
flags-parameter is case-sensitive.
.TP
\fB\-\-updatedb\fR
update the Xapian database after the move. You can use the general
\fB\-\-muhome=\fR option to specify the database if it does not live at the
default place.
.TP
\fB\-\-printtarget\fR
return the target path on standard output upon succesful completion of the
move (with or without a succesful database update)
.SH EXAMPLE
To move a message \fI/home/jimbo/Maildir/scuba/cur/123123123:2,S\fR to
@ -50,14 +73,37 @@ could do:
Obviously, you could also simply use \fBrm\fR in this case.
To mark a message as no longer new and 'Seen', and update the database
afterwards, you could do:
.nf
mu --flags=S mv /home/roger/Maildir/inbox/new/123123123:2, /home/roger/Maildir/inbox/
.fi
.SH LIMITATIONS
Both source-path and target-directory must be on the same disk partition,
except when the target-directory is \fI/dev/null\fR.
.SH OPTIONS
\fBmu mv\fR takes no options.
.SH RETURN VALUE
\fBmu mv\fR returns 0 upon success; in general, the following error codes are
returned:
.nf
| code | meaning |
|------+-----------------------------------|
| 0 | ok |
| 1 | general error |
| 4 | database is corrupted |
| 5 | some other database update error |
.fi
Note that if you get a database error rather than a general error, this means
that moving the file succeeded, but that the database update afterwards failed.
.SH BUGS

View File

@ -38,6 +38,7 @@
#include "mu-contacts.h"
#include "mu-runtime.h"
#include "mu-msg-flags.h"
#include "mu-store.h"
#define VIEW_TERMINATOR '\f' /* form-feed */
@ -301,6 +302,52 @@ mv_check_params (MuConfig *opts, MuMsgFlags *flags)
}
static gboolean
update_db_after_mv (MuConfig *opts, const char *src, const char* target)
{
MuStore *store;
GError *err;
gboolean rv1, rv2;
err = NULL;
store = mu_store_new (mu_runtime_path(MU_RUNTIME_PATH_XAPIANDB),
mu_runtime_path(MU_RUNTIME_PATH_CONTACTS), &err);
if (!store) {
if (err) {
g_warning ("store error: %s", err->message);
g_error_free (err);
} else
g_warning ("failed to create store object");
return FALSE;
}
if (!(rv1 = mu_store_remove (store, src)))
g_warning ("failed to remove message from store");
if (!(rv2 = mu_store_store_path (store, target)))
g_warning ("failed to store target message");
mu_store_destroy (store);
return rv1 && rv2;
}
static MuExitCode
mv_remove (const char *path, MuConfig *opts)
{
if (unlink (path) != 0) {
g_warning ("unlink failed: %s", strerror (errno));
return MU_EXITCODE_ERROR;
}
if (!opts->updatedb || update_db_after_mv (opts, path, NULL))
return MU_EXITCODE_OK;
else
return MU_EXITCODE_DB_UPDATE_ERROR;
}
MuExitCode
mu_cmd_mv (MuConfig *opts)
@ -308,21 +355,17 @@ mu_cmd_mv (MuConfig *opts)
GError *err;
gchar *fullpath;
MuMsgFlags flags;
MuExitCode rv;
if (!mv_check_params (opts, &flags))
return MU_EXITCODE_ERROR;
err = NULL;
/* special case: /dev/null */
if (g_strcmp0 (opts->params[2], "/dev/null") == 0) {
if (unlink (opts->params[1]) != 0) {
g_warning ("unlink failed: %s", strerror (errno));
return MU_EXITCODE_ERROR;
} else
return MU_EXITCODE_OK;
}
if (g_strcmp0 (opts->params[2], "/dev/null") == 0)
return mv_remove (opts->params[1], opts);
fullpath = mu_msg_file_move_to_maildir (opts->params[1], opts->params[2],
flags, &err);
if (!fullpath) {
@ -330,8 +373,19 @@ mu_cmd_mv (MuConfig *opts)
g_warning ("move failed: %s", err->message);
g_error_free (err);
}
return MU_EXITCODE_ERROR;
}
return MU_EXITCODE_ERROR;
} else if (opts->printtarget) /* if the move worked, print the */
g_print ("%s\n", fullpath); /* target (if user set
* --printtarget) */
/* now, when --updatedb db was given, try to update it */
if (!opts->updatedb || update_db_after_mv (opts, opts->params[1], fullpath))
rv = MU_EXITCODE_OK;
else
rv = MU_EXITCODE_DB_UPDATE_ERROR;
return MU_EXITCODE_OK;
g_free (fullpath);
return rv;
}

View File

@ -319,6 +319,11 @@ config_options_group_mv (MuConfig *opts)
GOptionEntry entries[] = {
{"flags", 0, 0, G_OPTION_ARG_STRING, &opts->flagstr,
"flags to set for the target (DFNPRST)", NULL},
{"updatedb", 0, 0, G_OPTION_ARG_NONE, &opts->updatedb,
"whether to update the database after the move", NULL},
{"printtarget", 0, 0, G_OPTION_ARG_NONE, &opts->updatedb,
"whether to print the target path upon succesful completion",
NULL},
{NULL, 0, 0, 0, NULL, NULL, NULL}
};

View File

@ -126,6 +126,11 @@ struct _MuConfig {
/* options for mv */
char *flagstr; /* message flags to set for
* the target */
gboolean updatedb; /* should the database be updated after
* moving? */
gboolean printtarget; /* should be print the
* target file path on
* stdout */
/* options for view */
gboolean terminator; /* add separator \f between

View File

@ -622,11 +622,11 @@ get_message_uid (MuMsg *msg)
return get_message_uid (mu_msg_get_path(msg));
}
MuResult
gboolean
mu_store_store (MuStore *store, MuMsg *msg, gboolean replace)
{
g_return_val_if_fail (store, MU_ERROR);
g_return_val_if_fail (msg, MU_ERROR);
g_return_val_if_fail (store, FALSE);
g_return_val_if_fail (msg, FALSE);
try {
Xapian::Document newdoc;
@ -654,21 +654,52 @@ mu_store_store (MuStore *store, MuMsg *msg, gboolean replace)
id = store->_db.replace_document (uid, newdoc);
else
id = store->_db.add_document (newdoc);
/* DEBUG */
//g_print ("\n[%s]\n", newdoc.serialise().c_str());
++store->_processed;
commit_trx_if (store,
store->_processed % store->_trx_size == 0);
return MU_OK;
return TRUE;
} MU_XAPIAN_CATCH_BLOCK;
rollback_trx_if (store, store->_in_transaction);
return MU_ERROR;
return FALSE;
}
gboolean
mu_store_store_path (MuStore *store, const char *path)
{
MuMsg *msg;
GError *err;
gboolean rv;
g_return_val_if_fail (store, FALSE);
g_return_val_if_fail (path, FALSE);
err = NULL;
msg = mu_msg_new_from_file (path, NULL, &err);
if (!msg) {
if (err) {
g_warning ("failed to create message %s to store: %s",
path, err->message);
g_error_free (err);
} else
g_warning ("failed to create message %s to store", path);
return FALSE;
}
rv = mu_store_store (store, msg, TRUE);
if (!rv)
g_warning ("failed to store %s", path);
mu_msg_unref (msg);
return rv;
}

View File

@ -109,9 +109,19 @@ void mu_store_flush (MuStore *store);
*
* @return TRUE if it succeeded, FALSE otherwise
*/
MuResult mu_store_store (MuStore *store, MuMsg *msg, gboolean replace);
gboolean mu_store_store (MuStore *store, MuMsg *msg, gboolean replace);
/**
* store an email message in the XapianStore; similar to mu_store_store, but instead takes a path as parameter instead of a MuMsg*
*
* @param store a valid store
* @param path full filesystem path to a valid message
*
* @return TRUE if it succeeded, FALSE otherwise
*/
gboolean mu_store_store_path (MuStore *store, const char *path);
/**
* remove a message from the database
*

View File

@ -399,11 +399,12 @@ enum _MuResult {
typedef enum _MuResult MuResult;
enum _MuExitCode {
MU_EXITCODE_OK = 0,
MU_EXITCODE_ERROR = 1,
MU_EXITCODE_NO_MATCHES = 2,
MU_EXITCODE_DB_LOCKED = 3,
MU_EXITCODE_DB_CORRUPTED = 4
MU_EXITCODE_OK = 0,
MU_EXITCODE_ERROR = 1,
MU_EXITCODE_NO_MATCHES = 2,
MU_EXITCODE_DB_LOCKED = 3,
MU_EXITCODE_DB_CORRUPTED = 4,
MU_EXITCODE_DB_UPDATE_ERROR = 5
};
typedef enum _MuExitCode MuExitCode;
@ -411,7 +412,7 @@ enum _MuError {
MU_ERROR_XAPIAN, /* general xapian related error */
MU_ERROR_XAPIAN_CANNOT_GET_WRITELOCK, /* can't get write lock */
MU_ERROR_XAPIAN_CORRUPTION, /* database corruption */
MU_ERROR_XAPIAN_DIR, /* xapian dir is not accessible */
MU_ERROR_XAPIAN_DIR, /* xapian dir is not accessible */
MU_ERROR_XAPIAN_NOT_UPTODATE, /* database version is not uptodate */
MU_ERROR_XAPIAN_MISSING_DATA, /* missing data for a document */
MU_ERROR_QUERY, /* (parsing) error in the query */