* add 'mu add' and 'mu remove' commands for adding, removing messages from the database

This commit is contained in:
Dirk-Jan C. Binnema
2011-08-03 23:00:48 +03:00
parent ef086db2a7
commit 82be4974b7
6 changed files with 243 additions and 71 deletions

48
man/mu-add.1 Normal file
View File

@ -0,0 +1,48 @@
.TH MU ADD 1 "August 2011" "User Manuals"
.SH NAME
mu add\- add one or more messages to the database
.SH SYNOPSIS
.B mu add <file> [<files>]
.SH DESCRIPTION
\fBmu add\fR adds specific files to the database. Each of the files must be
specified with an absolute path.
.SH OPTIONS
\fBmu add\fR does not have its own options, but the general options for
determining the location of the database (\fI--muhome\fR) are available. See
\fBmu-index(1)\fR for more information.
.SH RETURN VALUE
\fBmu add\fR returns 0 upon success; in general, the following error codes are
returned:
.nf
| code | meaning |
|------+-----------------------------------|
| 0 | ok |
| 1 | general error |
| 5 | some database update error |
.fi
.SH BUGS
Please report bugs if you find them:
.BR http://code.google.com/p/mu0/issues/list
.SH AUTHOR
Dirk-Jan C. Binnema <djcb@djcbsoftware.nl>
.SH "SEE ALSO"
.BR mu(1)
.BR mu-index(1)
.BR mu-remove(1)

48
man/mu-remove.1 Normal file
View File

@ -0,0 +1,48 @@
.TH MU REMOVE 1 "August 2011" "User Manuals"
.SH NAME
mu remove\- remove one or more messages to the database
.SH SYNOPSIS
.B mu remove <file> [<files>]
.SH DESCRIPTION
\fBmu remove\fR removes specific messages from the database, each of them
specified by their filename. The files do not have to exist (anymore).
.SH OPTIONS
\fBmu remove\fR does not have its own options, but the general options for
determining the location of the database (\fI--muhome\fR) are available. See
\fBmu-index(1)\fR for more information.
.SH RETURN VALUE
\fBmu remove\fR returns 0 upon success; in general, the following error codes are
returned:
.nf
| code | meaning |
|------+-----------------------------------|
| 0 | ok |
| 1 | general error |
| 5 | some database update error |
.fi
.SH BUGS
Please report bugs if you find them:
.BR http://code.google.com/p/mu0/issues/list
.SH AUTHOR
Dirk-Jan C. Binnema <djcb@djcbsoftware.nl>
.SH "SEE ALSO"
.BR mu(1)
.BR mu-index(1)
.BR mu-add(1)

View File

@ -204,7 +204,6 @@ view_params_valid (MuConfig *opts)
return FALSE;
}
switch (opts->format) {
case MU_CONFIG_FORMAT_PLAIN:
case MU_CONFIG_FORMAT_SEXP:
@ -302,70 +301,26 @@ 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)
{
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)
return mv_remove (opts->params[1], opts);
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;
}
err = NULL;
fullpath = mu_msg_file_move_to_maildir (opts->params[1], opts->params[2],
flags, &err);
if (!fullpath) {
@ -379,13 +334,114 @@ mu_cmd_mv (MuConfig *opts)
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;
g_free (fullpath);
return rv;
return MU_EXITCODE_OK;
}
static gboolean
check_file_okay (const char *path, gboolean cmd_add)
{
if (!g_path_is_absolute (path)) {
g_warning ("path is not absolute: %s", path);
return FALSE;
}
if (cmd_add && access (path, R_OK) != 0) {
g_warning ("path is not readable: %s: %s",
path, strerror (errno));
return FALSE;
}
return TRUE;
}
static MuExitCode
add_or_remove (MuConfig *opts, gboolean cmd_add)
{
MuStore *store;
GError *err;
gboolean allok;
int i;
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 MU_EXITCODE_ERROR;
}
for (i = 1, allok = TRUE; opts->params[i]; ++i) {
const char* src;
src = opts->params[i];
if (!check_file_okay (src, cmd_add)) {
allok = FALSE;
continue;
}
if (cmd_add) {
if (!mu_store_store_path (store, src)) {
allok = FALSE;
g_warning ("failed to store %s", src);
}
} else { /* remove */
if (!mu_store_remove_path (store, src)) {
allok = FALSE;
g_warning ("failed to remove %s", src);
}
}
}
mu_store_destroy (store);
return allok ? MU_EXITCODE_OK : MU_EXITCODE_DB_UPDATE_ERROR;
}
MuExitCode
mu_cmd_add (MuConfig *opts)
{
g_return_val_if_fail (opts, MU_EXITCODE_ERROR);
g_return_val_if_fail (opts->cmd == MU_CONFIG_CMD_ADD,
MU_EXITCODE_ERROR);
/* note: params[0] will be 'add' */
if (!opts->params[0] || !opts->params[1]) {
g_warning ("usage: mu add <file> [<files>]");
return MU_EXITCODE_ERROR;
}
return add_or_remove (opts, TRUE);
}
MuExitCode
mu_cmd_remove (MuConfig *opts)
{
g_return_val_if_fail (opts, MU_EXITCODE_ERROR);
g_return_val_if_fail (opts->cmd == MU_CONFIG_CMD_REMOVE,
MU_EXITCODE_ERROR);
/* note: params[0] will be 'add' */
if (!opts->params[0] || !opts->params[1]) {
g_warning ("usage: mu remove <file> [<files>]");
return MU_EXITCODE_ERROR;
}
return add_or_remove (opts, TRUE);
}

View File

@ -118,6 +118,26 @@ MuExitCode mu_cmd_mv (MuConfig *opts);
MuExitCode mu_cmd_cfind (MuConfig *opts);
/**
* execute the add command
*
* @param opts configuration options
*
* @return MU_EXITCODE_OK (0) if the command succeeds,
* MU_EXITCODE_ERROR otherwise
*/
MuExitCode mu_cmd_add (MuConfig *opts);
/**
* execute the remove command
*
* @param opts configuration options
*
* @return MU_EXITCODE_OK (0) if the command succeeds,
* MU_EXITCODE_ERROR otherwise
*/
MuExitCode mu_cmd_remove (MuConfig *opts);
G_END_DECLS
#endif /*__MU_CMD_H__*/

View File

@ -47,7 +47,6 @@ get_output_format (const char *formatstr)
{"csv", MU_CONFIG_FORMAT_CSV},
{"org-contact", MU_CONFIG_FORMAT_ORG_CONTACT},
{"bbdb", MU_CONFIG_FORMAT_BBDB},
{"json", MU_CONFIG_FORMAT_JSON,},
{"links", MU_CONFIG_FORMAT_LINKS},
{"plain", MU_CONFIG_FORMAT_PLAIN},
{"sexp", MU_CONFIG_FORMAT_SEXP},
@ -216,9 +215,12 @@ config_options_group_find (MuConfig *opts)
"clear old links before filling a linksdir (false)", NULL},
{"format", 'o', 0, G_OPTION_ARG_STRING, &opts->formatstr,
"output format ('plain'(*), 'links', 'xml',"
"'json', 'sexp', 'xquery')", NULL},
"'sexp', 'xquery')", NULL},
{"exec", 'e', 0, G_OPTION_ARG_STRING, &opts->exec,
"execute command on each match message", NULL},
{"include-unreable", 0, 0, G_OPTION_ARG_NONE,
&opts->include_unreadable,
"don't ignore messages without a disk file (false)", NULL},
{NULL, 0, 0, 0, NULL, NULL, NULL}
};
@ -319,9 +321,7 @@ 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,
{"printtarget", 0, 0, G_OPTION_ARG_NONE, &opts->printtarget,
"whether to print the target path upon succesful completion",
NULL},
{NULL, 0, 0, 0, NULL, NULL, NULL}

View File

@ -48,12 +48,11 @@ enum _MuConfigFormat {
MU_CONFIG_FORMAT_BBDB, /* BBDB */
/* for find, view */
MU_CONFIG_FORMAT_SEXP, /* output sexps */
MU_CONFIG_FORMAT_SEXP, /* output sexps (emacs) */
/* for find */
MU_CONFIG_FORMAT_LINKS, /* output as symlinks */
MU_CONFIG_FORMAT_XML, /* output xml */
MU_CONFIG_FORMAT_JSON, /* output json */
MU_CONFIG_FORMAT_XQUERY, /* output the xapian query */
};
typedef enum _MuConfigFormat MuConfigFormat;
@ -70,6 +69,8 @@ enum _MuConfigCmd {
MU_CONFIG_CMD_EXTRACT,
MU_CONFIG_CMD_CFIND,
MU_CONFIG_CMD_MV,
MU_CONFIG_CMD_ADD,
MU_CONFIG_CMD_REMOVE,
MU_CONFIG_CMD_NONE,
};
@ -122,12 +123,11 @@ struct _MuConfig {
char *exec; /* command to execute on the
* files for the matched
* messages */
gboolean include_unreadable; /* don't ignore messages
* without a disk file */
/* 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 */