mirror of
https://git.notmuchmail.org/git/notmuch
synced 2024-11-22 02:48:08 +01:00
Add notmuch_thread_get_tags
And augment "notmuch search" to print tag values as well as thread ID values. This tool is almost usable now.
This commit is contained in:
parent
ef3ab5781a
commit
94f01d9de9
5 changed files with 128 additions and 24 deletions
|
@ -144,6 +144,9 @@ _notmuch_thread_create (const void *talloc_owner,
|
||||||
notmuch_database_t *notmuch,
|
notmuch_database_t *notmuch,
|
||||||
const char *thread_id);
|
const char *thread_id);
|
||||||
|
|
||||||
|
void
|
||||||
|
_notmuch_thread_add_tag (notmuch_thread_t *thread, const char *tag);
|
||||||
|
|
||||||
/* message.cc */
|
/* message.cc */
|
||||||
|
|
||||||
notmuch_message_t *
|
notmuch_message_t *
|
||||||
|
|
17
notmuch.c
17
notmuch.c
|
@ -610,6 +610,7 @@ search_command (int argc, char *argv[])
|
||||||
notmuch_query_t *query;
|
notmuch_query_t *query;
|
||||||
notmuch_thread_results_t *results;
|
notmuch_thread_results_t *results;
|
||||||
notmuch_thread_t *thread;
|
notmuch_thread_t *thread;
|
||||||
|
notmuch_tags_t *tags;
|
||||||
char *query_str;
|
char *query_str;
|
||||||
int i;
|
int i;
|
||||||
notmuch_status_t ret = NOTMUCH_STATUS_SUCCESS;
|
notmuch_status_t ret = NOTMUCH_STATUS_SUCCESS;
|
||||||
|
@ -641,9 +642,23 @@ search_command (int argc, char *argv[])
|
||||||
notmuch_thread_results_has_more (results);
|
notmuch_thread_results_has_more (results);
|
||||||
notmuch_thread_results_advance (results))
|
notmuch_thread_results_advance (results))
|
||||||
{
|
{
|
||||||
|
int first = 1;
|
||||||
|
|
||||||
thread = notmuch_thread_results_get (results);
|
thread = notmuch_thread_results_get (results);
|
||||||
|
|
||||||
printf ("%s\n", notmuch_thread_get_thread_id (thread));
|
printf ("%s (", notmuch_thread_get_thread_id (thread));
|
||||||
|
|
||||||
|
for (tags = notmuch_thread_get_tags (thread);
|
||||||
|
notmuch_tags_has_more (tags);
|
||||||
|
notmuch_tags_advance (tags))
|
||||||
|
{
|
||||||
|
if (! first)
|
||||||
|
printf (" ");
|
||||||
|
printf ("%s", notmuch_tags_get (tags));
|
||||||
|
first = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf (")\n");
|
||||||
|
|
||||||
notmuch_thread_destroy (thread);
|
notmuch_thread_destroy (thread);
|
||||||
}
|
}
|
||||||
|
|
39
notmuch.h
39
notmuch.h
|
@ -458,6 +458,45 @@ notmuch_thread_results_destroy (notmuch_thread_results_t *results);
|
||||||
const char *
|
const char *
|
||||||
notmuch_thread_get_thread_id (notmuch_thread_t *thread);
|
notmuch_thread_get_thread_id (notmuch_thread_t *thread);
|
||||||
|
|
||||||
|
/* Get the tags for 'thread', returning a notmuch_tags_t object which
|
||||||
|
* can be used to iterate over all tags.
|
||||||
|
*
|
||||||
|
* Note: In the Notmuch database, tags are stored on individual
|
||||||
|
* messages, not on threads. So the tags returned here will be all
|
||||||
|
* tags of the messages which matched the search and which belong to
|
||||||
|
* this thread.
|
||||||
|
*
|
||||||
|
* The tags object is owned by the thread and as such, will only be
|
||||||
|
* valid for as long as the thread is valid, (for example, until
|
||||||
|
* notmuch_thread_destroy or until the query from which it derived is
|
||||||
|
* destroyed).
|
||||||
|
*
|
||||||
|
* Typical usage might be:
|
||||||
|
*
|
||||||
|
* notmuch_thread_t *thread;
|
||||||
|
* notmuch_tags_t *tags;
|
||||||
|
* const char *tag;
|
||||||
|
*
|
||||||
|
* thread = notmuch_thread_results_get (thread_results);
|
||||||
|
*
|
||||||
|
* for (tags = notmuch_thread_get_tags (thread);
|
||||||
|
* notmuch_tags_has_more (tags);
|
||||||
|
* notmuch_result_advance (tags))
|
||||||
|
* {
|
||||||
|
* tag = notmuch_tags_get (tags);
|
||||||
|
* ....
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* notmuch_thread_destroy (thread);
|
||||||
|
*
|
||||||
|
* Note that there's no explicit destructor needed for the
|
||||||
|
* notmuch_tags_t object. (For consistency, we do provide a
|
||||||
|
* notmuch_tags_destroy function, but there's no good reason to call
|
||||||
|
* it if the message is about to be destroyed).
|
||||||
|
*/
|
||||||
|
notmuch_tags_t *
|
||||||
|
notmuch_thread_get_tags (notmuch_thread_t *thread);
|
||||||
|
|
||||||
/* Destroy a notmuch_thread_t object. */
|
/* Destroy a notmuch_thread_t object. */
|
||||||
void
|
void
|
||||||
notmuch_thread_destroy (notmuch_thread_t *thread);
|
notmuch_thread_destroy (notmuch_thread_t *thread);
|
||||||
|
|
50
query.cc
50
query.cc
|
@ -39,7 +39,7 @@ struct _notmuch_message_results {
|
||||||
|
|
||||||
struct _notmuch_thread_results {
|
struct _notmuch_thread_results {
|
||||||
notmuch_database_t *notmuch;
|
notmuch_database_t *notmuch;
|
||||||
GPtrArray *thread_ids;
|
GPtrArray *threads;
|
||||||
unsigned int index;
|
unsigned int index;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -165,7 +165,7 @@ notmuch_query_search_messages (notmuch_query_t *query)
|
||||||
static int
|
static int
|
||||||
_notmuch_thread_results_destructor (notmuch_thread_results_t *results)
|
_notmuch_thread_results_destructor (notmuch_thread_results_t *results)
|
||||||
{
|
{
|
||||||
g_ptr_array_free (results->thread_ids, TRUE);
|
g_ptr_array_free (results->threads, TRUE);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -174,9 +174,12 @@ notmuch_thread_results_t *
|
||||||
notmuch_query_search_threads (notmuch_query_t *query)
|
notmuch_query_search_threads (notmuch_query_t *query)
|
||||||
{
|
{
|
||||||
notmuch_thread_results_t *thread_results;
|
notmuch_thread_results_t *thread_results;
|
||||||
|
notmuch_thread_t *thread;
|
||||||
|
const char *thread_id;
|
||||||
notmuch_message_results_t *message_results;
|
notmuch_message_results_t *message_results;
|
||||||
notmuch_message_t *message;
|
notmuch_message_t *message;
|
||||||
const char *thread_id;
|
notmuch_tags_t *tags;
|
||||||
|
const char *tag;
|
||||||
GHashTable *seen;
|
GHashTable *seen;
|
||||||
|
|
||||||
thread_results = talloc (query, notmuch_thread_results_t);
|
thread_results = talloc (query, notmuch_thread_results_t);
|
||||||
|
@ -184,7 +187,7 @@ notmuch_query_search_threads (notmuch_query_t *query)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
thread_results->notmuch = query->notmuch;
|
thread_results->notmuch = query->notmuch;
|
||||||
thread_results->thread_ids = g_ptr_array_new ();
|
thread_results->threads = g_ptr_array_new ();
|
||||||
thread_results->index = 0;
|
thread_results->index = 0;
|
||||||
|
|
||||||
talloc_set_destructor (thread_results, _notmuch_thread_results_destructor);
|
talloc_set_destructor (thread_results, _notmuch_thread_results_destructor);
|
||||||
|
@ -197,18 +200,28 @@ notmuch_query_search_threads (notmuch_query_t *query)
|
||||||
notmuch_message_results_advance (message_results))
|
notmuch_message_results_advance (message_results))
|
||||||
{
|
{
|
||||||
message = notmuch_message_results_get (message_results);
|
message = notmuch_message_results_get (message_results);
|
||||||
|
|
||||||
thread_id = notmuch_message_get_thread_id (message);
|
thread_id = notmuch_message_get_thread_id (message);
|
||||||
|
|
||||||
if (g_hash_table_lookup_extended (seen,
|
if (! g_hash_table_lookup_extended (seen,
|
||||||
thread_id, NULL, NULL))
|
thread_id, NULL,
|
||||||
|
(void **) &thread))
|
||||||
{
|
{
|
||||||
continue;
|
thread = _notmuch_thread_create (query, query->notmuch,
|
||||||
|
thread_id);
|
||||||
|
|
||||||
|
g_hash_table_insert (seen, xstrdup (thread_id), thread);
|
||||||
|
|
||||||
|
g_ptr_array_add (thread_results->threads, thread);
|
||||||
}
|
}
|
||||||
|
|
||||||
g_hash_table_insert (seen, xstrdup (thread_id), NULL);
|
for (tags = notmuch_message_get_tags (message);
|
||||||
|
notmuch_tags_has_more (tags);
|
||||||
g_ptr_array_add (thread_results->thread_ids,
|
notmuch_tags_advance (tags))
|
||||||
talloc_strdup (thread_results, thread_id));
|
{
|
||||||
|
tag = notmuch_tags_get (tags);
|
||||||
|
_notmuch_thread_add_tag (thread, tag);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
g_hash_table_unref (seen);
|
g_hash_table_unref (seen);
|
||||||
|
@ -268,26 +281,17 @@ notmuch_message_results_destroy (notmuch_message_results_t *results)
|
||||||
notmuch_bool_t
|
notmuch_bool_t
|
||||||
notmuch_thread_results_has_more (notmuch_thread_results_t *results)
|
notmuch_thread_results_has_more (notmuch_thread_results_t *results)
|
||||||
{
|
{
|
||||||
return (results->index < results->thread_ids->len);
|
return (results->index < results->threads->len);
|
||||||
}
|
}
|
||||||
|
|
||||||
notmuch_thread_t *
|
notmuch_thread_t *
|
||||||
notmuch_thread_results_get (notmuch_thread_results_t *results)
|
notmuch_thread_results_get (notmuch_thread_results_t *results)
|
||||||
{
|
{
|
||||||
notmuch_thread_t *thread;
|
|
||||||
const char *thread_id;
|
|
||||||
|
|
||||||
if (! notmuch_thread_results_has_more (results))
|
if (! notmuch_thread_results_has_more (results))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
thread_id = (const char *) g_ptr_array_index (results->thread_ids,
|
return (notmuch_thread_t *) g_ptr_array_index (results->threads,
|
||||||
results->index);
|
results->index);
|
||||||
|
|
||||||
thread = _notmuch_thread_create (results,
|
|
||||||
results->notmuch,
|
|
||||||
thread_id);
|
|
||||||
|
|
||||||
return thread;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
43
thread.cc
43
thread.cc
|
@ -23,11 +23,22 @@
|
||||||
|
|
||||||
#include <xapian.h>
|
#include <xapian.h>
|
||||||
|
|
||||||
|
#include <glib.h> /* GHashTable */
|
||||||
|
|
||||||
struct _notmuch_thread {
|
struct _notmuch_thread {
|
||||||
notmuch_database_t *notmuch;
|
notmuch_database_t *notmuch;
|
||||||
char *thread_id;
|
char *thread_id;
|
||||||
|
GHashTable *tags;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static int
|
||||||
|
_notmuch_thread_destructor (notmuch_thread_t *thread)
|
||||||
|
{
|
||||||
|
g_hash_table_unref (thread->tags);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* Create a new notmuch_thread_t object for an existing document in
|
/* Create a new notmuch_thread_t object for an existing document in
|
||||||
* the database.
|
* the database.
|
||||||
*
|
*
|
||||||
|
@ -54,8 +65,12 @@ _notmuch_thread_create (const void *talloc_owner,
|
||||||
if (unlikely (thread == NULL))
|
if (unlikely (thread == NULL))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
talloc_set_destructor (thread, _notmuch_thread_destructor);
|
||||||
|
|
||||||
thread->notmuch = notmuch;
|
thread->notmuch = notmuch;
|
||||||
thread->thread_id = talloc_strdup (thread, thread_id);
|
thread->thread_id = talloc_strdup (thread, thread_id);
|
||||||
|
thread->tags = g_hash_table_new_full (g_str_hash, g_str_equal,
|
||||||
|
free, NULL);
|
||||||
|
|
||||||
return thread;
|
return thread;
|
||||||
}
|
}
|
||||||
|
@ -66,6 +81,34 @@ notmuch_thread_get_thread_id (notmuch_thread_t *thread)
|
||||||
return thread->thread_id;
|
return thread->thread_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
_notmuch_thread_add_tag (notmuch_thread_t *thread, const char *tag)
|
||||||
|
{
|
||||||
|
g_hash_table_insert (thread->tags, xstrdup (tag), NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
notmuch_tags_t *
|
||||||
|
notmuch_thread_get_tags (notmuch_thread_t *thread)
|
||||||
|
{
|
||||||
|
notmuch_tags_t *tags;
|
||||||
|
GList *keys, *l;
|
||||||
|
|
||||||
|
tags = _notmuch_tags_create (thread);
|
||||||
|
if (unlikely (tags == NULL))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
keys = g_hash_table_get_keys (thread->tags);
|
||||||
|
|
||||||
|
for (l = keys; l; l = l->next)
|
||||||
|
_notmuch_tags_add_tag (tags, (char *) l->data);
|
||||||
|
|
||||||
|
g_list_free (keys);
|
||||||
|
|
||||||
|
_notmuch_tags_prepare_iterator (tags);
|
||||||
|
|
||||||
|
return tags;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
notmuch_thread_destroy (notmuch_thread_t *thread)
|
notmuch_thread_destroy (notmuch_thread_t *thread)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue