mirror of https://github.com/djcb/mu.git
* add support for message-references:
- mu_msg_get_references and mu_msg_get_references_str get the list of refences ("References:" and "In-reply-to:") as a GList, resp. comma-separated list - stored in database as a value, can be shown in mu find output using 'r' (db needs rebuild) - document in mu-find manpage
This commit is contained in:
parent
efa026648b
commit
e33f927542
|
@ -1,4 +1,4 @@
|
|||
.TH MU FIND 1 "March 2011" "User Manuals"
|
||||
.TH MU FIND 1 "April 2011" "User Manuals"
|
||||
|
||||
.SH NAME
|
||||
|
||||
|
@ -273,6 +273,7 @@ search parameters; the complete list:
|
|||
s Message \fBs\fRubject
|
||||
i Message-\fBi\fRd
|
||||
m \fBm\fRaildir
|
||||
r \fBr\fReferences (message ids In-reply-to, References as comma-separated list)
|
||||
.fi
|
||||
|
||||
|
||||
|
|
|
@ -158,6 +158,13 @@ static const MuMsgField FIELD_DATA[] = {
|
|||
MU_MSG_FIELD_TYPE_TIME_T,
|
||||
"timestamp", 'x', 0,
|
||||
FLAG_GMIME
|
||||
},
|
||||
|
||||
{
|
||||
MU_MSG_FIELD_ID_REFS,
|
||||
MU_MSG_FIELD_TYPE_STRING,
|
||||
"refs", 'r', 'R',
|
||||
FLAG_GMIME | FLAG_XAPIAN_VALUE
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -41,7 +41,8 @@ enum _MuMsgFieldId {
|
|||
MU_MSG_FIELD_ID_TO,
|
||||
MU_MSG_FIELD_ID_MSGID,
|
||||
MU_MSG_FIELD_ID_TIMESTAMP,
|
||||
|
||||
MU_MSG_FIELD_ID_REFS,
|
||||
|
||||
MU_MSG_FIELD_ID_NUM,
|
||||
|
||||
/* fake fields */
|
||||
|
|
|
@ -43,6 +43,8 @@ enum _StringFields {
|
|||
MDIR_FIELD, /* the maildir */
|
||||
|
||||
FLAGS_FIELD_STR, /* message flags */
|
||||
|
||||
REFS_FIELD, /* msg references, as a comma-sep'd string */
|
||||
|
||||
FIELD_NUM
|
||||
};
|
||||
|
@ -59,6 +61,8 @@ struct _MuMsg {
|
|||
size_t _size;
|
||||
time_t _timestamp;
|
||||
MuMsgPrio _prio;
|
||||
|
||||
GSList *_refs; /* msgids of message we refer to */
|
||||
};
|
||||
|
||||
G_END_DECLS
|
||||
|
|
93
src/mu-msg.c
93
src/mu-msg.c
|
@ -80,6 +80,9 @@ mu_msg_destroy (MuMsg *msg)
|
|||
|
||||
for (i = 0; i != FIELD_NUM; ++i)
|
||||
g_free (msg->_fields[i]);
|
||||
|
||||
g_slist_foreach (msg->_refs, (GFunc)g_free, NULL);
|
||||
g_slist_free (msg->_refs);
|
||||
|
||||
g_slice_free (MuMsg, msg);
|
||||
}
|
||||
|
@ -214,7 +217,8 @@ mu_msg_new (const char* filepath, const gchar* mdir, GError **err)
|
|||
msg = g_slice_new0 (MuMsg);
|
||||
msg->_prio = MU_MSG_PRIO_NONE;
|
||||
msg->_refcount = 1;
|
||||
|
||||
msg->_refs = NULL;
|
||||
|
||||
if (!init_file_metadata(msg, filepath, mdir, err)) {
|
||||
mu_msg_unref (msg);
|
||||
return NULL;
|
||||
|
@ -814,6 +818,92 @@ mu_msg_get_summary (MuMsg *msg, size_t max_lines)
|
|||
}
|
||||
|
||||
|
||||
static GSList*
|
||||
get_msgids_from_header (MuMsg *msg, const char* header)
|
||||
{
|
||||
GSList *msgids;
|
||||
const char *str;
|
||||
|
||||
msgids = NULL;
|
||||
str = g_mime_object_get_header (GMIME_OBJECT(msg->_mime_msg),
|
||||
header);
|
||||
|
||||
/* get stuff from the 'references' header */
|
||||
if (str) {
|
||||
const GMimeReferences *cur;
|
||||
GMimeReferences *mime_refs;
|
||||
mime_refs = g_mime_references_decode (str);
|
||||
for (cur = mime_refs; cur; cur = g_mime_references_get_next(cur)) {
|
||||
const char* msgid;
|
||||
msgid = g_mime_references_get_message_id (cur);
|
||||
if (msgid)
|
||||
msgids = g_slist_prepend (msgids, g_strdup (msgid));
|
||||
}
|
||||
g_mime_references_free (mime_refs);
|
||||
}
|
||||
|
||||
return g_slist_reverse (msgids);
|
||||
}
|
||||
|
||||
const char*
|
||||
mu_msg_get_references_str (MuMsg *msg)
|
||||
{
|
||||
const GSList *refs;
|
||||
gchar *refsstr;
|
||||
|
||||
g_return_val_if_fail (msg, NULL);
|
||||
|
||||
if (msg->_fields[REFS_FIELD])
|
||||
return msg->_fields[REFS_FIELD];
|
||||
|
||||
refsstr = NULL;
|
||||
refs = mu_msg_get_references (msg);
|
||||
if (refs) {
|
||||
const GSList *cur;
|
||||
for (cur = refs; cur; cur = g_slist_next(cur)) {
|
||||
char *tmp;
|
||||
tmp = g_strdup_printf ("%s%s%s",
|
||||
refsstr ? refsstr : "",
|
||||
refsstr ? "," : "",
|
||||
g_strdup((gchar*)cur->data));
|
||||
g_free (refsstr);
|
||||
refsstr = tmp;
|
||||
}
|
||||
}
|
||||
|
||||
return msg->_fields[REFS_FIELD] = refsstr;
|
||||
}
|
||||
|
||||
|
||||
const GSList*
|
||||
mu_msg_get_references (MuMsg *msg)
|
||||
{
|
||||
GSList *refs, *inreply;
|
||||
|
||||
g_return_val_if_fail (msg, NULL);
|
||||
|
||||
if (msg->_refs)
|
||||
return msg->_refs;
|
||||
|
||||
refs = get_msgids_from_header (msg, "References");
|
||||
|
||||
/* now, add in-reply-to:, we only take the first one if there
|
||||
* are more */
|
||||
inreply = get_msgids_from_header (msg, "In-reply-to");
|
||||
if (inreply) {
|
||||
refs = g_slist_prepend (refs, g_strdup ((gchar*)inreply->data));
|
||||
g_slist_foreach (inreply, (GFunc)g_free, NULL);
|
||||
g_slist_free (inreply);
|
||||
}
|
||||
|
||||
/* put in proper order */
|
||||
msg->_refs = g_slist_reverse (refs);
|
||||
|
||||
return msg->_refs;
|
||||
}
|
||||
|
||||
|
||||
|
||||
const char*
|
||||
mu_msg_get_field_string (MuMsg *msg, MuMsgFieldId mfid)
|
||||
{
|
||||
|
@ -829,6 +919,7 @@ mu_msg_get_field_string (MuMsg *msg, MuMsgFieldId mfid)
|
|||
case MU_MSG_FIELD_ID_TO: return mu_msg_get_to (msg);
|
||||
case MU_MSG_FIELD_ID_MSGID: return mu_msg_get_msgid (msg);
|
||||
case MU_MSG_FIELD_ID_MAILDIR: return mu_msg_get_maildir (msg);
|
||||
case MU_MSG_FIELD_ID_REFS: return mu_msg_get_references_str (msg);
|
||||
default:
|
||||
g_return_val_if_reached (NULL);
|
||||
}
|
||||
|
|
22
src/mu-msg.h
22
src/mu-msg.h
|
@ -292,6 +292,28 @@ MuMsgPrio mu_msg_get_prio (MuMsg *msg);
|
|||
time_t mu_msg_get_timestamp (MuMsg *msg);
|
||||
|
||||
|
||||
/**
|
||||
* get a list of message ids this message refers to -- this is based
|
||||
* on the References: and In-reply-to: headers.
|
||||
*
|
||||
* @param msg a valid MuMsg instance
|
||||
*
|
||||
* @return a list of message id, with the most immediate parent as the
|
||||
* last element. Don't modify/free this list.
|
||||
*/
|
||||
const GSList *mu_msg_get_references (MuMsg *msg);
|
||||
|
||||
|
||||
/**
|
||||
* get the list of references as a comma-separated string
|
||||
*
|
||||
* @param msg a valid MuMsg
|
||||
*
|
||||
* @return a comma-separated string with the references or NULL if
|
||||
* there are none. Don't modify/free
|
||||
*/
|
||||
const char* mu_msg_get_references_str (MuMsg *msg);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /*__MU_MSG_H__*/
|
||||
|
|
Loading…
Reference in New Issue