static void format_message_json (const void *ctx, notmuch_message_t *message) { notmuch_tags_t *tags; int first = 1; void *ctx_quote = talloc_new (ctx); time_t date; const char *relative_date; date = notmuch_message_get_date (message); relative_date = notmuch_time_relative_date (ctx, date); printf ("\"id\": %s, \"match\": %s, \"excluded\": %s, \"filename\": %s, \"timestamp\": %ld, \"date_relative\": \"%s\", \"tags\": [", json_quote_str (ctx_quote, notmuch_message_get_message_id (message)), notmuch_message_get_flag (message, NOTMUCH_MESSAGE_FLAG_MATCH) ? "true" : "false", notmuch_message_get_flag (message, NOTMUCH_MESSAGE_FLAG_EXCLUDED) ? "true" : "false", json_quote_str (ctx_quote, notmuch_message_get_filename (message)), date, relative_date); for (tags = notmuch_message_get_tags (message); notmuch_tags_valid (tags); notmuch_tags_move_to_next (tags)) { printf("%s%s", first ? "" : ",", json_quote_str (ctx_quote, notmuch_tags_get (tags))); first = 0; } printf("], "); talloc_free (ctx_quote); }
static notmuch_status_t show_messages (void *ctx, const notmuch_show_format_t *format, sprinter_t *sp, notmuch_messages_t *messages, int indent, notmuch_show_params_t *params) { notmuch_message_t *message; notmuch_bool_t match; notmuch_bool_t excluded; int next_indent; notmuch_status_t status, res = NOTMUCH_STATUS_SUCCESS; sp->begin_list (sp); for (; notmuch_messages_valid (messages); notmuch_messages_move_to_next (messages)) { sp->begin_list (sp); message = notmuch_messages_get (messages); match = notmuch_message_get_flag (message, NOTMUCH_MESSAGE_FLAG_MATCH); excluded = notmuch_message_get_flag (message, NOTMUCH_MESSAGE_FLAG_EXCLUDED); next_indent = indent; if ((match && (!excluded || !params->omit_excluded)) || params->entire_thread) { status = show_message (ctx, format, sp, message, indent, params); if (status && !res) res = status; next_indent = indent + 1; } else { sp->null (sp); } status = show_messages (ctx, format, sp, notmuch_message_get_replies (message), next_indent, params); if (status && !res) res = status; notmuch_message_destroy (message); sp->end (sp); } sp->end (sp); return res; }
/* Return two stable query strings that identify exactly the matched * and unmatched messages currently in thread. If there are no * matched or unmatched messages, the returned buffers will be * NULL. */ static int get_thread_query (notmuch_thread_t *thread, char **matched_out, char **unmatched_out) { notmuch_messages_t *messages; char *escaped = NULL; size_t escaped_len = 0; *matched_out = *unmatched_out = NULL; for (messages = notmuch_thread_get_messages (thread); notmuch_messages_valid (messages); notmuch_messages_move_to_next (messages)) { notmuch_message_t *message = notmuch_messages_get (messages); const char *mid = notmuch_message_get_message_id (message); /* Determine which query buffer to extend */ char **buf = notmuch_message_get_flag ( message, NOTMUCH_MESSAGE_FLAG_MATCH) ? matched_out : unmatched_out; /* Add this message's id: query. Since "id" is an exclusive * prefix, it is implicitly 'or'd together, so we only need to * join queries with a space. */ if (make_boolean_term (thread, "id", mid, &escaped, &escaped_len) < 0) return -1; if (*buf) *buf = talloc_asprintf_append_buffer (*buf, " %s", escaped); else *buf = talloc_strdup (thread, escaped); if (!*buf) return -1; } talloc_free (escaped); return 0; }
static void format_message_text (unused (const void *ctx), notmuch_message_t *message, int indent) { printf ("id:%s depth:%d match:%d filename:%s\n", notmuch_message_get_message_id (message), indent, notmuch_message_get_flag (message, NOTMUCH_MESSAGE_FLAG_MATCH), notmuch_message_get_filename (message)); }
/* Emit a sequence of key/value pairs for the metadata of message. * The caller should begin a map before calling this. */ static void format_message_sprinter (sprinter_t *sp, notmuch_message_t *message) { /* Any changes to the JSON or S-Expression format should be * reflected in the file devel/schemata. */ void *local = talloc_new (NULL); notmuch_tags_t *tags; time_t date; const char *relative_date; sp->map_key (sp, "id"); sp->string (sp, notmuch_message_get_message_id (message)); sp->map_key (sp, "match"); sp->boolean (sp, notmuch_message_get_flag (message, NOTMUCH_MESSAGE_FLAG_MATCH)); sp->map_key (sp, "excluded"); sp->boolean (sp, notmuch_message_get_flag (message, NOTMUCH_MESSAGE_FLAG_EXCLUDED)); sp->map_key (sp, "filename"); sp->string (sp, notmuch_message_get_filename (message)); sp->map_key (sp, "timestamp"); date = notmuch_message_get_date (message); sp->integer (sp, date); sp->map_key (sp, "date_relative"); relative_date = notmuch_time_relative_date (local, date); sp->string (sp, relative_date); sp->map_key (sp, "tags"); sp->begin_list (sp); for (tags = notmuch_message_get_tags (message); notmuch_tags_valid (tags); notmuch_tags_move_to_next (tags)) sp->string (sp, notmuch_tags_get (tags)); sp->end (sp); talloc_free (local); }
static void show_messages (void *ctx, const notmuch_show_format_t *format, notmuch_messages_t *messages, int indent, notmuch_show_params_t *params) { notmuch_message_t *message; notmuch_bool_t match; int first_set = 1; int next_indent; fputs (format->message_set_start, stdout); for (; notmuch_messages_valid (messages); notmuch_messages_move_to_next (messages)) { if (!first_set) fputs (format->message_set_sep, stdout); first_set = 0; fputs (format->message_set_start, stdout); message = notmuch_messages_get (messages); match = notmuch_message_get_flag (message, NOTMUCH_MESSAGE_FLAG_MATCH); next_indent = indent; if (match || params->entire_thread) { show_message (ctx, format, message, indent, params); next_indent = indent + 1; fputs (format->message_set_sep, stdout); } show_messages (ctx, format, notmuch_message_get_replies (message), next_indent, params); notmuch_message_destroy (message); fputs (format->message_set_end, stdout); } fputs (format->message_set_end, stdout); }
static notmuch_status_t show_messages (void *ctx, const notmuch_show_format_t *format, notmuch_messages_t *messages, int indent, notmuch_show_params_t *params) { notmuch_message_t *message; notmuch_bool_t match; notmuch_bool_t excluded; int first_set = 1; int next_indent; notmuch_status_t status, res = NOTMUCH_STATUS_SUCCESS; if (format->message_set_start) fputs (format->message_set_start, stdout); for (; notmuch_messages_valid (messages); notmuch_messages_move_to_next (messages)) { if (!first_set && format->message_set_sep) fputs (format->message_set_sep, stdout); first_set = 0; if (format->message_set_start) fputs (format->message_set_start, stdout); message = notmuch_messages_get (messages); match = notmuch_message_get_flag (message, NOTMUCH_MESSAGE_FLAG_MATCH); excluded = notmuch_message_get_flag (message, NOTMUCH_MESSAGE_FLAG_EXCLUDED); next_indent = indent; if ((match && (!excluded || !params->omit_excluded)) || params->entire_thread) { status = show_message (ctx, format, message, indent, params); if (status && !res) res = status; next_indent = indent + 1; if (!status && format->message_set_sep) fputs (format->message_set_sep, stdout); } status = show_messages (ctx, format, notmuch_message_get_replies (message), next_indent, params); if (status && !res) res = status; notmuch_message_destroy (message); if (format->message_set_end) fputs (format->message_set_end, stdout); } if (format->message_set_end) fputs (format->message_set_end, stdout); return res; }
static notmuch_status_t format_part_text (const void *ctx, mime_node_t *node, int indent, const notmuch_show_params_t *params) { /* The disposition and content-type metadata are associated with * the envelope for message parts */ GMimeObject *meta = node->envelope_part ? GMIME_OBJECT (node->envelope_part) : node->part; GMimeContentType *content_type = g_mime_object_get_content_type (meta); const notmuch_bool_t leaf = GMIME_IS_PART (node->part); const char *part_type; int i; if (node->envelope_file) { notmuch_message_t *message = node->envelope_file; part_type = "message"; printf ("\f%s{ id:%s depth:%d match:%d excluded:%d filename:%s\n", part_type, notmuch_message_get_message_id (message), indent, notmuch_message_get_flag (message, NOTMUCH_MESSAGE_FLAG_MATCH) ? 1 : 0, notmuch_message_get_flag (message, NOTMUCH_MESSAGE_FLAG_EXCLUDED) ? 1 : 0, notmuch_message_get_filename (message)); } else { GMimeContentDisposition *disposition = g_mime_object_get_content_disposition (meta); const char *cid = g_mime_object_get_content_id (meta); const char *filename = leaf ? g_mime_part_get_filename (GMIME_PART (node->part)) : NULL; if (disposition && strcmp (disposition->disposition, GMIME_DISPOSITION_ATTACHMENT) == 0) part_type = "attachment"; else part_type = "part"; printf ("\f%s{ ID: %d", part_type, node->part_num); if (filename) printf (", Filename: %s", filename); if (cid) printf (", Content-id: %s", cid); printf (", Content-type: %s\n", g_mime_content_type_to_string (content_type)); } if (GMIME_IS_MESSAGE (node->part)) { GMimeMessage *message = GMIME_MESSAGE (node->part); InternetAddressList *recipients; const char *recipients_string; printf ("\fheader{\n"); if (node->envelope_file) printf ("%s\n", _get_one_line_summary (ctx, node->envelope_file)); printf ("Subject: %s\n", g_mime_message_get_subject (message)); printf ("From: %s\n", g_mime_message_get_sender (message)); recipients = g_mime_message_get_recipients (message, GMIME_RECIPIENT_TYPE_TO); recipients_string = internet_address_list_to_string (recipients, 0); if (recipients_string) printf ("To: %s\n", recipients_string); recipients = g_mime_message_get_recipients (message, GMIME_RECIPIENT_TYPE_CC); recipients_string = internet_address_list_to_string (recipients, 0); if (recipients_string) printf ("Cc: %s\n", recipients_string); printf ("Date: %s\n", g_mime_message_get_date_as_string (message)); printf ("\fheader}\n"); printf ("\fbody{\n"); } if (leaf) { if (g_mime_content_type_is_type (content_type, "text", "*") && !g_mime_content_type_is_type (content_type, "text", "html")) { GMimeStream *stream_stdout = g_mime_stream_file_new (stdout); g_mime_stream_file_set_owner (GMIME_STREAM_FILE (stream_stdout), FALSE); show_text_part_content (node->part, stream_stdout, 0); g_object_unref(stream_stdout); } else { printf ("Non-text part: %s\n", g_mime_content_type_to_string (content_type)); } } for (i = 0; i < node->nchildren; i++) format_part_text (ctx, mime_node_child (node, i), indent, params); if (GMIME_IS_MESSAGE (node->part)) printf ("\fbody}\n"); printf ("\f%s}\n", part_type); return NOTMUCH_STATUS_SUCCESS; }