1 /* notmuch - Not much of an email program, (just index and search)
3 * Copyright © 2009 Carl Worth
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see http://www.gnu.org/licenses/ .
18 * Author: Carl Worth <cworth@cworth.org>
21 #include "notmuch-client.h"
23 /* If the user asks for more than this number of threads, then break
24 the results down into chunks so that results start appearing
25 quickly rather than the user having to wait until all results are
26 available before anything appears.
28 Since each subsequent chunk ends up having to re-do threading work
29 done by all previous chunks, we double the chunk size repeatedly
30 until all desired results have been returned.
32 #define NOTMUCH_SEARCH_INITIAL_CHUNK_SIZE 100
34 /* Do the actual search for a chunk of threads and display the results,
35 (returning the number of threads found in this chunk). */
37 do_search_threads (const void *ctx,
38 notmuch_query_t *query,
40 int first, int max_threads)
42 notmuch_thread_t *thread;
43 notmuch_threads_t *threads;
46 const char *relative_date;
49 for (threads = notmuch_query_search_threads (query, first, max_threads);
50 notmuch_threads_has_more (threads);
51 notmuch_threads_advance (threads))
55 thread = notmuch_threads_get (threads);
58 if (sort == NOTMUCH_SORT_OLDEST_FIRST)
59 date = notmuch_thread_get_oldest_date (thread);
61 date = notmuch_thread_get_newest_date (thread);
63 relative_date = notmuch_time_relative_date (ctx, date);
65 printf ("thread:%s %12s [%d/%d] %s; %s",
66 notmuch_thread_get_thread_id (thread),
68 notmuch_thread_get_matched_messages (thread),
69 notmuch_thread_get_total_messages (thread),
70 notmuch_thread_get_authors (thread),
71 notmuch_thread_get_subject (thread));
74 for (tags = notmuch_thread_get_tags (thread);
75 notmuch_tags_has_more (tags);
76 notmuch_tags_advance (tags))
80 printf ("%s", notmuch_tags_get (tags));
85 notmuch_thread_destroy (thread);
92 notmuch_search_command (void *ctx, int argc, char *argv[])
94 notmuch_config_t *config;
95 notmuch_database_t *notmuch;
96 notmuch_query_t *query;
98 int i, first = 0, max_threads = -1;
100 notmuch_sort_t sort = NOTMUCH_SORT_NEWEST_FIRST;
102 int threads_in_chunk;
104 for (i = 0; i < argc && argv[i][0] == '-'; i++) {
105 if (strcmp (argv[i], "--") == 0) {
109 if (STRNCMP_LITERAL (argv[i], "--first=") == 0) {
110 opt = argv[i] + sizeof ("--first=") - 1;
111 first = strtoul (opt, &end, 10);
112 if (*opt == '\0' || *end != '\0') {
113 fprintf (stderr, "Invalid value for --first: %s\n", opt);
116 } else if (STRNCMP_LITERAL (argv[i], "--max-threads=") == 0) {
117 opt = argv[i] + sizeof ("--max-threads=") - 1;
118 max_threads = strtoul (opt, &end, 10);
119 if (*opt == '\0' || *end != '\0') {
120 fprintf (stderr, "Invalid value for --max-threads: %s\n", opt);
123 } else if (STRNCMP_LITERAL (argv[i], "--sort=") == 0) {
124 opt = argv[i] + sizeof ("--sort=") - 1;
125 if (strcmp (opt, "oldest-first") == 0) {
126 sort = NOTMUCH_SORT_OLDEST_FIRST;
127 } else if (strcmp (opt, "newest-first") == 0) {
128 sort = NOTMUCH_SORT_NEWEST_FIRST;
130 fprintf (stderr, "Invalid value for --sort: %s\n", opt);
134 fprintf (stderr, "Unrecognized option: %s\n", argv[i]);
142 config = notmuch_config_open (ctx, NULL, NULL);
146 notmuch = notmuch_database_open (notmuch_config_get_database_path (config),
147 NOTMUCH_DATABASE_MODE_READ_ONLY);
151 query_str = query_string_from_args (ctx, argc, argv);
152 if (query_str == NULL) {
153 fprintf (stderr, "Out of memory.\n");
156 if (*query_str == '\0') {
157 fprintf (stderr, "Error: notmuch search requires at least one search term.\n");
161 query = notmuch_query_create (notmuch, query_str);
163 fprintf (stderr, "Out of memory\n");
167 notmuch_query_set_sort (query, sort);
169 /* If we receive a max-threads option, then the user is
170 responsible for any chunking and we return all results at
173 chunk_size = NOTMUCH_SEARCH_INITIAL_CHUNK_SIZE;
175 chunk_size = max_threads;
178 threads_in_chunk = do_search_threads (ctx, query, sort,
180 if (chunk_size == max_threads)
187 } while (threads_in_chunk);
189 notmuch_query_destroy (query);
190 notmuch_database_close (notmuch);