Example #1
0
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);
}
Example #2
0
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;
}
Example #3
0
/* 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;
}
Example #4
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));
}
Example #5
0
/* 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);
}
Example #6
0
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);
}
Example #7
0
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;
}
Example #8
0
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;
}