/* Formatted output of threads */ static int do_show (void *ctx, notmuch_query_t *query, const notmuch_show_format_t *format, sprinter_t *sp, notmuch_show_params_t *params) { notmuch_threads_t *threads; notmuch_thread_t *thread; notmuch_messages_t *messages; notmuch_status_t status, res = NOTMUCH_STATUS_SUCCESS; status= notmuch_query_search_threads_st (query, &threads); if (print_status_query ("notmuch show", query, status)) return 1; sp->begin_list (sp); for ( ; notmuch_threads_valid (threads); notmuch_threads_move_to_next (threads)) { thread = notmuch_threads_get (threads); messages = notmuch_thread_get_toplevel_messages (thread); if (messages == NULL) INTERNAL_ERROR ("Thread %s has no toplevel messages.\n", notmuch_thread_get_thread_id (thread)); status = show_messages (ctx, format, sp, messages, 0, params); if (status && !res) res = status; notmuch_thread_destroy (thread); } sp->end (sp); return res != NOTMUCH_STATUS_SUCCESS; }
static int do_search_threads (search_context_t *ctx) { notmuch_thread_t *thread; notmuch_threads_t *threads; notmuch_tags_t *tags; sprinter_t *format = ctx->format; time_t date; int i; notmuch_status_t status; if (ctx->offset < 0) { unsigned count; notmuch_status_t status; status = notmuch_query_count_threads_st (ctx->query, &count); if (print_status_query ("notmuch search", ctx->query, status)) return 1; ctx->offset += count; if (ctx->offset < 0) ctx->offset = 0; } status = notmuch_query_search_threads_st (ctx->query, &threads); if (print_status_query("notmuch search", ctx->query, status)) return 1; format->begin_list (format); for (i = 0; notmuch_threads_valid (threads) && (ctx->limit < 0 || i < ctx->offset + ctx->limit); notmuch_threads_move_to_next (threads), i++) { thread = notmuch_threads_get (threads); if (i < ctx->offset) { notmuch_thread_destroy (thread); continue; } if (ctx->output == OUTPUT_THREADS) { format->set_prefix (format, "thread"); format->string (format, notmuch_thread_get_thread_id (thread)); format->separator (format); } else { /* output == OUTPUT_SUMMARY */ void *ctx_quote = talloc_new (thread); const char *authors = notmuch_thread_get_authors (thread); const char *subject = notmuch_thread_get_subject (thread); const char *thread_id = notmuch_thread_get_thread_id (thread); int matched = notmuch_thread_get_matched_messages (thread); int total = notmuch_thread_get_total_messages (thread); const char *relative_date = NULL; notmuch_bool_t first_tag = TRUE; format->begin_map (format); if (ctx->sort == NOTMUCH_SORT_OLDEST_FIRST) date = notmuch_thread_get_oldest_date (thread); else date = notmuch_thread_get_newest_date (thread); relative_date = notmuch_time_relative_date (ctx_quote, date); if (format->is_text_printer) { /* Special case for the text formatter */ printf ("thread:%s %12s [%d/%d] %s; %s (", thread_id, relative_date, matched, total, sanitize_string (ctx_quote, authors), sanitize_string (ctx_quote, subject)); } else { /* Structured Output */ format->map_key (format, "thread"); format->string (format, thread_id); format->map_key (format, "timestamp"); format->integer (format, date); format->map_key (format, "date_relative"); format->string (format, relative_date); format->map_key (format, "matched"); format->integer (format, matched); format->map_key (format, "total"); format->integer (format, total); format->map_key (format, "authors"); format->string (format, authors); format->map_key (format, "subject"); format->string (format, subject); if (notmuch_format_version >= 2) { char *matched_query, *unmatched_query; if (get_thread_query (thread, &matched_query, &unmatched_query) < 0) { fprintf (stderr, "Out of memory\n"); return 1; } format->map_key (format, "query"); format->begin_list (format); if (matched_query) format->string (format, matched_query); else format->null (format); if (unmatched_query) format->string (format, unmatched_query); else format->null (format); format->end (format); } } talloc_free (ctx_quote); format->map_key (format, "tags"); format->begin_list (format); for (tags = notmuch_thread_get_tags (thread); notmuch_tags_valid (tags); notmuch_tags_move_to_next (tags)) { const char *tag = notmuch_tags_get (tags); if (format->is_text_printer) { /* Special case for the text formatter */ if (first_tag) first_tag = FALSE; else fputc (' ', stdout); fputs (tag, stdout); } else { /* Structured Output */ format->string (format, tag); } } if (format->is_text_printer) printf (")"); format->end (format); format->end (format); format->separator (format); } notmuch_thread_destroy (thread); } format->end (format); return 0; }