mirror of https://github.com/djcb/mu.git
* mu-cmd-server: add the 'contacts' command, which gives us the contacts (as
in mu-cfind)
This commit is contained in:
parent
3159d97105
commit
635e049ff7
|
@ -1,4 +1,4 @@
|
||||||
.TH MU-SERVER 1 "April 2012" "User Manuals"
|
.TH MU-SERVER 1 "June 2012" "User Manuals"
|
||||||
|
|
||||||
.SH NAME
|
.SH NAME
|
||||||
|
|
||||||
|
@ -69,7 +69,7 @@ e.g. set the subject, sender and recipient for a reply message.
|
||||||
Messages of type 'new' don't use the docid: parameter, the other ones do.
|
Messages of type 'new' don't use the docid: parameter, the other ones do.
|
||||||
|
|
||||||
.nf
|
.nf
|
||||||
-> compose <reply|forward|edit|new> [docid:<docid>]
|
-> compose type:<reply|forward|edit|new> [docid:<docid>]
|
||||||
<- (:compose <reply|forward|edit|new> :original <s-exp> :include (<list-of-attachments))
|
<- (:compose <reply|forward|edit|new> :original <s-exp> :include (<list-of-attachments))
|
||||||
.fi
|
.fi
|
||||||
|
|
||||||
|
@ -82,6 +82,18 @@ forwarding. This s-exprssion looks like:
|
||||||
.fi
|
.fi
|
||||||
|
|
||||||
|
|
||||||
|
.TP
|
||||||
|
.B contacts
|
||||||
|
|
||||||
|
Using the \fBcompose\fR command, we can retrieve an s-expression with all known
|
||||||
|
contacts (name + e-mail address). For the details, see \fBmu-cfind(1)\fR.
|
||||||
|
|
||||||
|
.nf
|
||||||
|
-> contacts [only-personal:true|false] [newer-than:<time_t>]
|
||||||
|
<- (:contacts ((:name abc :mail foo@exampl.com ...) ...)
|
||||||
|
.fi
|
||||||
|
|
||||||
|
|
||||||
.TP
|
.TP
|
||||||
.B extract
|
.B extract
|
||||||
|
|
||||||
|
|
|
@ -41,13 +41,14 @@
|
||||||
#endif /*!PATH_MAX */
|
#endif /*!PATH_MAX */
|
||||||
#endif /*PATH_MAX */
|
#endif /*PATH_MAX */
|
||||||
|
|
||||||
|
#include "mu-runtime.h"
|
||||||
#include "mu-str.h"
|
#include "mu-str.h"
|
||||||
#include "mu-cmd.h"
|
#include "mu-cmd.h"
|
||||||
#include "mu-maildir.h"
|
#include "mu-maildir.h"
|
||||||
#include "mu-query.h"
|
#include "mu-query.h"
|
||||||
#include "mu-index.h"
|
#include "mu-index.h"
|
||||||
#include "mu-msg-part.h"
|
#include "mu-msg-part.h"
|
||||||
|
#include "mu-contacts.h"
|
||||||
|
|
||||||
/* signal handling *****************************************************/
|
/* signal handling *****************************************************/
|
||||||
/*
|
/*
|
||||||
|
@ -522,6 +523,110 @@ cmd_compose (MuStore *store, MuQuery *query, GSList *args, GError **err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
struct _SexpData {
|
||||||
|
GString *gstr;
|
||||||
|
gboolean only_personal;
|
||||||
|
time_t newer_than;
|
||||||
|
};
|
||||||
|
typedef struct _SexpData SexpData;
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
each_contact_sexp (const char *email, const char *name, gboolean personal,
|
||||||
|
time_t tstamp, SexpData *sdata)
|
||||||
|
{
|
||||||
|
static const char *nil = "nil";
|
||||||
|
char *escmail, *escname;
|
||||||
|
|
||||||
|
/* only include newer-than-x contacts */
|
||||||
|
if (tstamp < sdata->newer_than)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* (maybe) only include 'personal' contacts */
|
||||||
|
if (sdata->only_personal && !personal)
|
||||||
|
return;
|
||||||
|
|
||||||
|
escmail = email ? mu_str_escape_c_literal (email, TRUE) : (char*)nil;
|
||||||
|
escname = name ? mu_str_escape_c_literal (name, TRUE) : (char*)nil;
|
||||||
|
|
||||||
|
g_string_append_printf (sdata->gstr,
|
||||||
|
"(:name %s :mail %s "
|
||||||
|
":timestamp (%u %u 0))\n",
|
||||||
|
escname, escmail,
|
||||||
|
(unsigned)(tstamp >> 16),
|
||||||
|
(unsigned)(tstamp & 0xffff));
|
||||||
|
if (escmail != nil)
|
||||||
|
g_free (escmail);
|
||||||
|
|
||||||
|
if (escname != nil)
|
||||||
|
g_free (escname);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* get all contacts as an s-expression
|
||||||
|
*
|
||||||
|
* @param self contacts object
|
||||||
|
* @param personal_only whether to restrict the list to 'personal' email addresses
|
||||||
|
*
|
||||||
|
* @return the sexp
|
||||||
|
*/
|
||||||
|
static char*
|
||||||
|
contacts_to_sexp (MuContacts *contacts,
|
||||||
|
gboolean only_personal, time_t newer_than)
|
||||||
|
{
|
||||||
|
SexpData sdata;
|
||||||
|
|
||||||
|
g_return_val_if_fail (contacts, NULL);
|
||||||
|
|
||||||
|
sdata.only_personal = only_personal;
|
||||||
|
sdata.newer_than = newer_than;
|
||||||
|
|
||||||
|
/* make a guess for the initial size */
|
||||||
|
sdata.gstr = g_string_sized_new (mu_contacts_count(contacts) * 128);
|
||||||
|
sdata.gstr = g_string_append (sdata.gstr, "(:contacts (");
|
||||||
|
mu_contacts_foreach (contacts,
|
||||||
|
(MuContactsForeachFunc)each_contact_sexp,
|
||||||
|
&sdata, NULL, NULL);
|
||||||
|
sdata.gstr = g_string_append (sdata.gstr, "))");
|
||||||
|
|
||||||
|
return g_string_free (sdata.gstr, FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static MuError
|
||||||
|
cmd_contacts (MuStore *store, MuQuery *query, GSList *args, GError **err)
|
||||||
|
{
|
||||||
|
MuContacts *contacts;
|
||||||
|
char *sexp;
|
||||||
|
gboolean only_personal;
|
||||||
|
time_t newer_than;
|
||||||
|
const char *str;
|
||||||
|
|
||||||
|
only_personal = get_bool_from_args (args, "only-personal", TRUE,
|
||||||
|
NULL);
|
||||||
|
str = get_string_from_args (args, "newer-than", TRUE, NULL);
|
||||||
|
newer_than = str ? (time_t)atoi(str) : 0;
|
||||||
|
|
||||||
|
contacts = mu_contacts_new
|
||||||
|
(mu_runtime_path (MU_RUNTIME_PATH_CONTACTS));
|
||||||
|
if (!contacts) {
|
||||||
|
print_error (MU_ERROR_INTERNAL,
|
||||||
|
"failed to open contacts cache");
|
||||||
|
return MU_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* dump the contacts cache as a giant sexp */
|
||||||
|
sexp = contacts_to_sexp (contacts, only_personal, newer_than);
|
||||||
|
print_expr ("%s", sexp);
|
||||||
|
g_free (sexp);
|
||||||
|
|
||||||
|
mu_contacts_destroy (contacts);
|
||||||
|
return MU_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static unsigned
|
static unsigned
|
||||||
print_sexps (MuMsgIter *iter, gboolean threads, unsigned maxnum)
|
print_sexps (MuMsgIter *iter, gboolean threads, unsigned maxnum)
|
||||||
{
|
{
|
||||||
|
@ -1214,6 +1319,7 @@ handle_args (MuStore *store, MuQuery *query, GSList *args, GError **err)
|
||||||
} cmd_map[] = {
|
} cmd_map[] = {
|
||||||
{ "add", cmd_add },
|
{ "add", cmd_add },
|
||||||
{ "compose", cmd_compose },
|
{ "compose", cmd_compose },
|
||||||
|
{ "contacts", cmd_contacts },
|
||||||
{ "extract", cmd_extract },
|
{ "extract", cmd_extract },
|
||||||
{ "find", cmd_find },
|
{ "find", cmd_find },
|
||||||
{ "index", cmd_index },
|
{ "index", cmd_index },
|
||||||
|
|
|
@ -424,7 +424,7 @@ with_store (store_func func, MuConfig *opts, gboolean read_only,
|
||||||
store = mu_store_new_writable
|
store = mu_store_new_writable
|
||||||
(mu_runtime_path(MU_RUNTIME_PATH_XAPIANDB),
|
(mu_runtime_path(MU_RUNTIME_PATH_XAPIANDB),
|
||||||
mu_runtime_path(MU_RUNTIME_PATH_CONTACTS),
|
mu_runtime_path(MU_RUNTIME_PATH_CONTACTS),
|
||||||
opts->rebuild, err);
|
opts->my_addresses, opts->rebuild, err);
|
||||||
if (!store)
|
if (!store)
|
||||||
return MU_G_ERROR_CODE(err);
|
return MU_G_ERROR_CODE(err);
|
||||||
else {
|
else {
|
||||||
|
|
Loading…
Reference in New Issue