X-Git-Url: https://git.notmuchmail.org/git?p=notmuch;a=blobdiff_plain;f=notmuch-index-message.cc;h=0b1072d759c481af6a8fd3812c5bf193c99dce91;hp=852f4e16259fba6fee4d5e51918f856a4c6702b4;hb=71bd250cb6200e9a89768e34562938f7fe409d4b;hpb=7878175ed943351c39ce5cebc6f10939b2b88422 diff --git a/notmuch-index-message.cc b/notmuch-index-message.cc index 852f4e16..0b1072d7 100644 --- a/notmuch-index-message.cc +++ b/notmuch-index-message.cc @@ -17,6 +17,38 @@ * Author: Carl Worth */ +/* This indexer creates a Xapian mail index that is remarkably similar + * to that created by sup. The big difference, (and the thing that + * will keep a notmuch index from being used by sup directly), is that + * sup expects a serialized ruby data structure in the document's data + * field, but notmuch just puts the mail's filename there (trusting + * that the email client can get the data in needs from the filename). + * + * Note: One bug here is that sup actually merges together fields such + * as To, CC, Bcc etc. when finding multiple emails with the same + * message ID. To support something similar, notmuch should list + * multiple files in the data field. + * + * Other differences between sup and notmuch-index identified so far: + * + * o sup supports encrypted mime parts by prompting for a passphrase + * to decrypt the message. So far, notmuch doesn't support this, + * both because I'm lazy to code it, and I also think doing so + * would present a security leak. + * + * o sup and notmuch have different heuristics for identifying (and + * thus ignoring) signatures. For example, sup considers a line + * consisting of two hypens as a signature separator, while + * notmuch expects those two hyphens to be followed by a space + * character. + * + * o sup as been seen to split some numbers before indexing + * them. For example, the number 1754 in an email message was + * indexed by sup as separate terms 17 and 54. I couldn't find any + * explanation for this behavior and did not try to replicate it + * in notmuch. + */ + #include #include #include @@ -172,6 +204,9 @@ gen_terms_address_names (Xapian::TermGenerator term_gen, int i; InternetAddress *address; + if (addresses == NULL) + return; + for (i = 0; i < internet_address_list_length (addresses); i++) { address = internet_address_list_get_address (addresses, i); gen_terms_address_name (term_gen, address, address_type); @@ -202,6 +237,9 @@ add_terms_address_addrs (Xapian::Document doc, int i; InternetAddress *address; + if (addresses == NULL) + return; + for (i = 0; i < internet_address_list_length (addresses); i++) { address = internet_address_list_get_address (addresses, i); add_term_address_addr (doc, address, address_type); @@ -269,12 +307,23 @@ static void insert_thread_id (GHashTable *thread_ids, Xapian::Document doc) { string value_string; - const char *value; + const char *value, *id, *comma; value_string = doc.get_value (NOTMUCH_VALUE_THREAD); value = value_string.c_str(); - if (strlen (value)) - g_hash_table_insert (thread_ids, strdup (value), NULL); + if (strlen (value)) { + id = value; + while (*id) { + comma = strchr (id, ','); + if (comma == NULL) + comma = id + strlen (id); + g_hash_table_insert (thread_ids, + strndup (id, comma - id), NULL); + id = comma; + if (*id) + id++; + } + } } /* Return one or more thread_ids, (as a GPtrArray of strings), for the @@ -368,8 +417,8 @@ gen_terms_body_str (Xapian::TermGenerator term_gen, } line_end = next_line - 1; - /* Trim whitespace. */ - while (*next_line && isspace (*next_line)) + /* Get to the next non-blank line. */ + while (*next_line == '\n') next_line++; /* Skip lines that are quotes. */ @@ -401,6 +450,7 @@ gen_terms_part (Xapian::TermGenerator term_gen, GMimeStream *stream; GMimeDataWrapper *wrapper; GByteArray *byte_array; + GMimeContentDisposition *disposition; char *body; if (GMIME_IS_MULTIPART (part)) { @@ -427,15 +477,38 @@ gen_terms_part (Xapian::TermGenerator term_gen, return; } + disposition = g_mime_object_get_content_disposition (part); + if (disposition && + strcmp (disposition->disposition, GMIME_DISPOSITION_ATTACHMENT) == 0) + { + const char *filename = g_mime_part_get_filename (GMIME_PART (part)); + const char *extension; + + add_term (term_gen.get_document (), "label", "attachment"); + gen_terms (term_gen, "attachment", filename); + + if (filename) { + extension = strchr (filename, '.'); + if (extension) { + add_term (term_gen.get_document (), "attachment_extension", + extension + 1); + } + } + + return; + } + byte_array = g_byte_array_new (); stream = g_mime_stream_mem_new_with_byte_array (byte_array); g_mime_stream_mem_set_owner (GMIME_STREAM_MEM (stream), FALSE); wrapper = g_mime_part_get_content_object (GMIME_PART (part)); - g_mime_data_wrapper_write_to_stream (wrapper, stream); + if (wrapper) + g_mime_data_wrapper_write_to_stream (wrapper, stream); g_object_unref (stream); + g_byte_array_append (byte_array, (guint8 *) "\0", 1); body = (char *) g_byte_array_free (byte_array, FALSE); gen_terms_body_str (term_gen, body);