* <many> add support for searching attachment mime-types
- updated manpages - some cleanups Note, requires a --rebuild
This commit is contained in:
2
NEWS
2
NEWS
@ -3,6 +3,8 @@
|
|||||||
** Release 0.9.8 <>
|
** Release 0.9.8 <>
|
||||||
|
|
||||||
- '--descending' has been renamed into '--reverse'
|
- '--descending' has been renamed into '--reverse'
|
||||||
|
- search for attachment MIME-type using 'attmime:' or 'y:'
|
||||||
|
- experimental emacs-based mail client
|
||||||
|
|
||||||
* Release 0.9.7 <>
|
* Release 0.9.7 <>
|
||||||
|
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
.TH MU-EASY 1 "August 2011" "User Manuals"
|
.TH MU-EASY 1 "November 2011" "User Manuals"
|
||||||
|
|
||||||
.SH NAME
|
.SH NAME
|
||||||
|
|
||||||
@ -159,7 +159,7 @@ Get all messages received today:
|
|||||||
\fB$ mu find date:today..now\fR
|
\fB$ mu find date:today..now\fR
|
||||||
.fi
|
.fi
|
||||||
|
|
||||||
Get all message we got in the last two weeks about emacs:
|
Get all messages we got in the last two weeks about emacs:
|
||||||
.nf
|
.nf
|
||||||
\fB$ mu find date:2w..now emacs\fR
|
\fB$ mu find date:2w..now emacs\fR
|
||||||
.fi
|
.fi
|
||||||
@ -182,6 +182,25 @@ filename, for example:
|
|||||||
.fi
|
.fi
|
||||||
will get you all message with an attachment starting with 'pic'.
|
will get you all message with an attachment starting with 'pic'.
|
||||||
|
|
||||||
|
If you want to find attachments with a certain MIME-type, you can use the
|
||||||
|
following:
|
||||||
|
|
||||||
|
Get all messages with PDF attachments:
|
||||||
|
.nf
|
||||||
|
\fB$ mu find attmime:application/pdf\fR
|
||||||
|
.fi
|
||||||
|
|
||||||
|
or even:
|
||||||
|
|
||||||
|
Get all messages with image attachments:
|
||||||
|
.nf
|
||||||
|
\fB$ mu find 'attmime:image/*'\fR
|
||||||
|
.fi
|
||||||
|
|
||||||
|
Note that (1) the '*' wildcard can only be used as the rightmost thing in a
|
||||||
|
search query, and (2) that you need to quote the search term, because
|
||||||
|
otherwise your shell will interpret the '*' (expanding it to all files in the
|
||||||
|
current directory -- probably not what you want).
|
||||||
|
|
||||||
.SH DISPLAYING MESSAGES
|
.SH DISPLAYING MESSAGES
|
||||||
|
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
.TH MU FIND 1 "July 2011" "User Manuals"
|
.TH MU FIND 1 "November 2011" "User Manuals"
|
||||||
|
|
||||||
.SH NAME
|
.SH NAME
|
||||||
|
|
||||||
@ -123,6 +123,7 @@ search fields and their abbreviations:
|
|||||||
date,d Date-Range
|
date,d Date-Range
|
||||||
size,z Message size
|
size,z Message size
|
||||||
attach,a Attachment filename
|
attach,a Attachment filename
|
||||||
|
attmime,y Attachment MIME-type
|
||||||
tag,x Tag for the message (contents of the \fIX-Label\fR field)
|
tag,x Tag for the message (contents of the \fIX-Label\fR field)
|
||||||
.fi
|
.fi
|
||||||
|
|
||||||
@ -474,6 +475,23 @@ Find all unread messages with attachments:
|
|||||||
.fi
|
.fi
|
||||||
|
|
||||||
|
|
||||||
|
Find all messages with PDF-attachments:
|
||||||
|
|
||||||
|
.nf
|
||||||
|
$ mu find attmime:application/pdf
|
||||||
|
.fi
|
||||||
|
|
||||||
|
Find all messages with attached images:
|
||||||
|
|
||||||
|
.nf
|
||||||
|
$ mu find 'attmime:image/*'
|
||||||
|
.fi
|
||||||
|
|
||||||
|
Note[1]: the argument needs to be quoted, or the shell will interpret the '*'
|
||||||
|
Note[2]: the '*' wild card can only be used as the last (rightmost) part of a
|
||||||
|
search term.
|
||||||
|
|
||||||
|
|
||||||
.SS Integrating mu find with mail clients
|
.SS Integrating mu find with mail clients
|
||||||
|
|
||||||
.TP
|
.TP
|
||||||
|
|||||||
@ -34,24 +34,31 @@ enum _FieldFlags {
|
|||||||
FLAG_GMIME = 1 << 0, /* field retrieved through
|
FLAG_GMIME = 1 << 0, /* field retrieved through
|
||||||
* gmime */
|
* gmime */
|
||||||
FLAG_XAPIAN_INDEX = 1 << 1, /* field is indexed in
|
FLAG_XAPIAN_INDEX = 1 << 1, /* field is indexed in
|
||||||
* xapian */
|
* xapian (i.e., the text
|
||||||
|
* is processed */
|
||||||
FLAG_XAPIAN_TERM = 1 << 2, /* field stored as term in
|
FLAG_XAPIAN_TERM = 1 << 2, /* field stored as term in
|
||||||
* xapian */
|
* xapian (so it can be searched) */
|
||||||
FLAG_XAPIAN_VALUE = 1 << 3, /* field stored as value in
|
FLAG_XAPIAN_VALUE = 1 << 3, /* field stored as value in
|
||||||
* xapian */
|
* xapian (so the literal
|
||||||
|
* value can be
|
||||||
|
* retrieved) */
|
||||||
FLAG_XAPIAN_CONTACT = 1 << 4, /* field contains one or more
|
FLAG_XAPIAN_CONTACT = 1 << 4, /* field contains one or more
|
||||||
* e-mail-addresses */
|
* e-mail-addresses */
|
||||||
FLAG_XAPIAN_ESCAPE = 1 << 5, /* field needs escaping for
|
FLAG_XAPIAN_ESCAPE = 1 << 5, /* field needs escaping for
|
||||||
* xapian */
|
* xapian (so the xapian
|
||||||
|
* query does not get
|
||||||
|
* confused) */
|
||||||
FLAG_XAPIAN_BOOLEAN = 1 << 6, /* use 'add_boolean_prefix'
|
FLAG_XAPIAN_BOOLEAN = 1 << 6, /* use 'add_boolean_prefix'
|
||||||
* for Xapian queries */
|
* for Xapian queries */
|
||||||
FLAG_XAPIAN_PREFIX_ONLY = 1 << 7, /* whether this fields
|
FLAG_XAPIAN_PREFIX_ONLY = 1 << 7, /* whether this fields
|
||||||
* matches only when the
|
* matches only when the
|
||||||
* prefix is explicitly
|
* prefix is explicitly
|
||||||
* included */
|
* included in the search
|
||||||
|
* query -- e.g., the text
|
||||||
|
* body */
|
||||||
FLAG_NORMALIZE = 1 << 8, /* field needs flattening for
|
FLAG_NORMALIZE = 1 << 8, /* field needs flattening for
|
||||||
* case/accents */
|
* case/accents */
|
||||||
FLAG_DONT_CACHE = 1 << 9 /* don't cache this field in
|
FLAG_DONT_CACHE = 1 << 9, /* don't cache this field in
|
||||||
* the MuMsg cache */
|
* the MuMsg cache */
|
||||||
};
|
};
|
||||||
typedef enum _FieldFlags FieldFlags;
|
typedef enum _FieldFlags FieldFlags;
|
||||||
@ -81,8 +88,14 @@ static const MuMsgField FIELD_DATA[] = {
|
|||||||
MU_MSG_FIELD_ID_ATTACH,
|
MU_MSG_FIELD_ID_ATTACH,
|
||||||
MU_MSG_FIELD_TYPE_STRING,
|
MU_MSG_FIELD_TYPE_STRING,
|
||||||
"attach" , 'a', 'A',
|
"attach" , 'a', 'A',
|
||||||
FLAG_GMIME | FLAG_XAPIAN_TERM | FLAG_NORMALIZE |
|
FLAG_GMIME | FLAG_XAPIAN_TERM | FLAG_NORMALIZE | FLAG_DONT_CACHE
|
||||||
FLAG_DONT_CACHE
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
MU_MSG_FIELD_ID_ATTACH_MIME_TYPE,
|
||||||
|
MU_MSG_FIELD_TYPE_STRING,
|
||||||
|
"attmime" , 'y', 'Y',
|
||||||
|
FLAG_XAPIAN_TERM | FLAG_XAPIAN_ESCAPE
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
@ -213,6 +226,13 @@ static const MuMsgField FIELD_DATA[] = {
|
|||||||
"tag", 'x', 'X',
|
"tag", 'x', 'X',
|
||||||
FLAG_GMIME | FLAG_XAPIAN_TERM | FLAG_XAPIAN_PREFIX_ONLY |
|
FLAG_GMIME | FLAG_XAPIAN_TERM | FLAG_XAPIAN_PREFIX_ONLY |
|
||||||
FLAG_NORMALIZE | FLAG_XAPIAN_ESCAPE
|
FLAG_NORMALIZE | FLAG_XAPIAN_ESCAPE
|
||||||
|
},
|
||||||
|
|
||||||
|
{ /* special, internal field, to get a unique key */
|
||||||
|
MU_MSG_FIELD_ID_UID,
|
||||||
|
MU_MSG_FIELD_TYPE_STRING,
|
||||||
|
"uid", 0, 'U',
|
||||||
|
FLAG_XAPIAN_TERM
|
||||||
}
|
}
|
||||||
|
|
||||||
/* note, mu-store also use the 'Q' internal prefix for its uids */
|
/* note, mu-store also use the 'Q' internal prefix for its uids */
|
||||||
|
|||||||
@ -30,6 +30,8 @@ enum _MuMsgFieldId {
|
|||||||
|
|
||||||
/* first all the string-based ones */
|
/* first all the string-based ones */
|
||||||
MU_MSG_FIELD_ID_ATTACH = 0,
|
MU_MSG_FIELD_ID_ATTACH = 0,
|
||||||
|
MU_MSG_FIELD_ID_ATTACH_MIME_TYPE, /* mime-type */
|
||||||
|
|
||||||
MU_MSG_FIELD_ID_BCC,
|
MU_MSG_FIELD_ID_BCC,
|
||||||
MU_MSG_FIELD_ID_BODY_HTML,
|
MU_MSG_FIELD_ID_BODY_HTML,
|
||||||
MU_MSG_FIELD_ID_BODY_TEXT,
|
MU_MSG_FIELD_ID_BODY_TEXT,
|
||||||
@ -40,6 +42,9 @@ enum _MuMsgFieldId {
|
|||||||
MU_MSG_FIELD_ID_PATH,
|
MU_MSG_FIELD_ID_PATH,
|
||||||
MU_MSG_FIELD_ID_SUBJECT,
|
MU_MSG_FIELD_ID_SUBJECT,
|
||||||
MU_MSG_FIELD_ID_TO,
|
MU_MSG_FIELD_ID_TO,
|
||||||
|
|
||||||
|
MU_MSG_FIELD_ID_UID, /* special, generated from path */
|
||||||
|
|
||||||
/* MU_MSG_STRING_FIELD_ID_NUM, see below */
|
/* MU_MSG_STRING_FIELD_ID_NUM, see below */
|
||||||
|
|
||||||
/* string list items... */
|
/* string list items... */
|
||||||
@ -59,7 +64,7 @@ typedef guint8 MuMsgFieldId;
|
|||||||
|
|
||||||
/* some specials... */
|
/* some specials... */
|
||||||
static const MuMsgFieldId MU_MSG_FIELD_ID_NONE = (MuMsgFieldId)-1;
|
static const MuMsgFieldId MU_MSG_FIELD_ID_NONE = (MuMsgFieldId)-1;
|
||||||
#define MU_MSG_STRING_FIELD_ID_NUM (MU_MSG_FIELD_ID_TO + 1)
|
#define MU_MSG_STRING_FIELD_ID_NUM (MU_MSG_FIELD_ID_UID + 1)
|
||||||
|
|
||||||
#define mu_msg_field_id_is_valid(MFID) \
|
#define mu_msg_field_id_is_valid(MFID) \
|
||||||
((MFID) < MU_MSG_FIELD_ID_NUM)
|
((MFID) < MU_MSG_FIELD_ID_NUM)
|
||||||
|
|||||||
@ -225,9 +225,4 @@ private:
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/* Xapian DB prefix for the UID value */
|
|
||||||
#define MU_STORE_UID_PREFIX "Q"
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif /*__MU_STORE_PRIV_HH__*/
|
#endif /*__MU_STORE_PRIV_HH__*/
|
||||||
|
|||||||
@ -50,6 +50,8 @@ _MuStore::get_uid_term (const char* path)
|
|||||||
unsigned djbhash, bkdrhash, bkdrseed;
|
unsigned djbhash, bkdrhash, bkdrseed;
|
||||||
unsigned u;
|
unsigned u;
|
||||||
static char hex[18];
|
static char hex[18];
|
||||||
|
static const char uid_prefix =
|
||||||
|
mu_msg_field_xapian_prefix(MU_MSG_FIELD_ID_UID);
|
||||||
|
|
||||||
djbhash = 5381;
|
djbhash = 5381;
|
||||||
bkdrhash = 0;
|
bkdrhash = 0;
|
||||||
@ -60,9 +62,8 @@ _MuStore::get_uid_term (const char* path)
|
|||||||
bkdrhash = bkdrhash * bkdrseed + path[u];
|
bkdrhash = bkdrhash * bkdrseed + path[u];
|
||||||
}
|
}
|
||||||
|
|
||||||
snprintf (hex, sizeof(hex),
|
snprintf (hex, sizeof(hex), "%c%08x%08x",
|
||||||
MU_STORE_UID_PREFIX "%08x%08x",
|
uid_prefix, djbhash, bkdrhash);
|
||||||
djbhash, bkdrhash);
|
|
||||||
|
|
||||||
return hex;
|
return hex;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -405,19 +405,32 @@ struct PartData {
|
|||||||
static void
|
static void
|
||||||
each_part (MuMsg *msg, MuMsgPart *part, PartData *pdata)
|
each_part (MuMsg *msg, MuMsgPart *part, PartData *pdata)
|
||||||
{
|
{
|
||||||
|
static const std::string
|
||||||
|
att (prefix(MU_MSG_FIELD_ID_ATTACH)),
|
||||||
|
mime (prefix(MU_MSG_FIELD_ID_ATTACH_MIME_TYPE));
|
||||||
|
|
||||||
if (mu_msg_part_looks_like_attachment (part, TRUE) &&
|
if (mu_msg_part_looks_like_attachment (part, TRUE) &&
|
||||||
(part->file_name)) {
|
(part->file_name)) {
|
||||||
|
|
||||||
char val[MuStore::MAX_TERM_LENGTH + 1];
|
char val[MuStore::MAX_TERM_LENGTH + 1];
|
||||||
strncpy (val, part->file_name, sizeof(val));
|
strncpy (val, part->file_name, sizeof(val));
|
||||||
|
|
||||||
/* now, let's create a terms... */
|
/* now, let's create a term... */
|
||||||
mu_str_normalize_in_place (val, TRUE);
|
mu_str_normalize_in_place (val, TRUE);
|
||||||
mu_str_ascii_xapian_escape_in_place (val);
|
mu_str_ascii_xapian_escape_in_place (val);
|
||||||
|
|
||||||
pdata->_doc.add_term
|
pdata->_doc.add_term
|
||||||
(prefix(pdata->_mfid) +
|
(att + std::string(val, 0, MuStore::MAX_TERM_LENGTH));
|
||||||
std::string(val, 0, MuStore::MAX_TERM_LENGTH));
|
|
||||||
|
/* save the mime type */
|
||||||
|
if (part->type) {
|
||||||
|
gchar *str;
|
||||||
|
str = g_strdup_printf ("%s/%s", part->type, part->subtype);
|
||||||
|
pdata->_doc.add_term
|
||||||
|
(mime + std::string(str, 0, MuStore::MAX_TERM_LENGTH));
|
||||||
|
g_free (str);
|
||||||
|
} else
|
||||||
|
pdata->_doc.add_term (mime + "application/octet-stream");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -482,9 +495,12 @@ add_terms_values (MuMsgFieldId mfid, MsgDoc* msgdoc)
|
|||||||
case MU_MSG_FIELD_ID_BODY_TEXT:
|
case MU_MSG_FIELD_ID_BODY_TEXT:
|
||||||
add_terms_values_body (*msgdoc->_doc, msgdoc->_msg, mfid);
|
add_terms_values_body (*msgdoc->_doc, msgdoc->_msg, mfid);
|
||||||
break;
|
break;
|
||||||
case MU_MSG_FIELD_ID_ATTACH:
|
case MU_MSG_FIELD_ID_ATTACH: /* also takes care of MU_MSG_FIELD_ID_ATTACH_MIME */
|
||||||
add_terms_values_attach (*msgdoc->_doc, msgdoc->_msg, mfid);
|
add_terms_values_attach (*msgdoc->_doc, msgdoc->_msg, mfid);
|
||||||
break;
|
break;
|
||||||
|
case MU_MSG_FIELD_ID_ATTACH_MIME_TYPE:
|
||||||
|
case MU_MSG_FIELD_ID_UID:
|
||||||
|
break; /* already taken care of elsewhere */
|
||||||
default:
|
default:
|
||||||
if (mu_msg_field_is_numeric (mfid))
|
if (mu_msg_field_is_numeric (mfid))
|
||||||
add_terms_values_number (*msgdoc->_doc, msgdoc->_msg,
|
add_terms_values_number (*msgdoc->_doc, msgdoc->_msg,
|
||||||
|
|||||||
Reference in New Issue
Block a user