[PATCH] Including 'unread' tag to mails without maildir flags

2010-11-19 Thread mes...@sindominio.net
From: Ruben Pollan <mes...@sindominio.net>

Some mail fetchers, like fetchmail, leaves the email without ':2,' at the end of
the filename. Notmuch didn't detect this emails as maildir, it didn't add the
maildir flags to them.

Now it detects if a mail is in a maildir by the directory structure, and add its
maildir flags correctly.
---
 lib/message.cc |   87 +---
 1 files changed, 45 insertions(+), 42 deletions(-)

diff --git a/lib/message.cc b/lib/message.cc
index 225b7e9..996c1df 100644
--- a/lib/message.cc
+++ b/lib/message.cc
@@ -854,6 +854,47 @@ notmuch_message_remove_tag (notmuch_message_t *message, 
const char *tag)
 return NOTMUCH_STATUS_SUCCESS;
 }

+/* Is the given filename within a maildir directory?
+ *
+ * Specifically, is the final directory component of 'filename' either
+ * "cur" or "new". If so, return a pointer to that final directory
+ * component within 'filename'. If not, return NULL.
+ *
+ * A non-NULL return value is guaranteed to be a valid string pointer
+ * pointing to the characters "new/" or "cur/", (but not
+ * NUL-terminated).
+ */
+static const char *
+_filename_is_in_maildir (const char *filename)
+{
+const char *slash, *dir = NULL;
+
+/* Find the last '/' separating directory from filename. */
+slash = strrchr (filename, '/');
+if (slash == NULL)
+   return NULL;
+
+/* Jump back 4 characters to where the previous '/' will be if the
+ * directory is named "cur" or "new". */
+if (slash - filename < 4)
+   return NULL;
+
+slash -= 4;
+
+if (*slash != '/')
+   return NULL;
+
+dir = slash + 1;
+
+if (STRNCMP_LITERAL (dir, "cur/") == 0 ||
+   STRNCMP_LITERAL (dir, "new/") == 0)
+{
+   return dir;
+}
+
+return NULL;
+}
+
 notmuch_status_t
 notmuch_message_maildir_flags_to_tags (notmuch_message_t *message)
 {
@@ -871,11 +912,14 @@ notmuch_message_maildir_flags_to_tags (notmuch_message_t 
*message)
 {
filename = notmuch_filenames_get (filenames);

+   if (! _filename_is_in_maildir(filename))
+   continue;
+   seen_maildir_info = 1;
+
flags = strstr (filename, ":2,");
if (! flags)
continue;

-   seen_maildir_info = 1;
flags += 3;

combined_flags = talloc_strdup_append (combined_flags, flags);
@@ -910,47 +954,6 @@ notmuch_message_maildir_flags_to_tags (notmuch_message_t 
*message)
 return status;
 }

-/* Is the given filename within a maildir directory?
- *
- * Specifically, is the final directory component of 'filename' either
- * "cur" or "new". If so, return a pointer to that final directory
- * component within 'filename'. If not, return NULL.
- *
- * A non-NULL return value is guaranteed to be a valid string pointer
- * pointing to the characters "new/" or "cur/", (but not
- * NUL-terminated).
- */
-static const char *
-_filename_is_in_maildir (const char *filename)
-{
-const char *slash, *dir = NULL;
-
-/* Find the last '/' separating directory from filename. */
-slash = strrchr (filename, '/');
-if (slash == NULL)
-   return NULL;
-
-/* Jump back 4 characters to where the previous '/' will be if the
- * directory is named "cur" or "new". */
-if (slash - filename < 4)
-   return NULL;
-
-slash -= 4;
-
-if (*slash != '/')
-   return NULL;
-
-dir = slash + 1;
-
-if (STRNCMP_LITERAL (dir, "cur/") == 0 ||
-   STRNCMP_LITERAL (dir, "new/") == 0)
-{
-   return dir;
-}
-
-return NULL;
-}
-
 /* From the set of tags on 'message' and the flag2tag table, compute a
  * set of maildir-flag actions to be taken, (flags that should be
  * either set or cleared).
-- 
1.7.1



[notmuch] [PATCH 2/2] Added regress option to messages iterator

2009-12-08 Thread mes...@sindominio.net
From: Ruben Pollan <mes...@sindominio.net>

Added the functions notmuch_messages_regress and notmuch_messages_is_first to
notmuch library. With them is possible to iterate backwards on messages.

* notmuch_messages_regress do the opposite than notmuch_messages_advance,
  getting the messages iterator one position backwards.

* notmuch_messages_is_first return TRUE if the iterator is in the first
  message.
---
 lib/messages.c|   27 +++
 lib/notmuch-private.h |7 +++
 lib/notmuch.h |8 
 lib/query.cc  |   24 
 4 files changed, 66 insertions(+), 0 deletions(-)

diff --git a/lib/messages.c b/lib/messages.c
index 5414f87..2c28738 100644
--- a/lib/messages.c
+++ b/lib/messages.c
@@ -90,6 +90,7 @@ _notmuch_messages_create (notmuch_message_list_t *list)

 messages->is_of_list_type = TRUE;
 messages->iterator = list->head;
+messages->previous_node = NULL;

 return messages;
 }
@@ -121,6 +122,18 @@ notmuch_messages_has_more (notmuch_messages_t *messages)
 return (messages->iterator != NULL);
 }

+notmuch_bool_t
+notmuch_messages_is_first (notmuch_messages_t *messages)
+{
+if (messages == NULL)
+   return TRUE;
+
+if (! messages->is_of_list_type)
+   return _notmuch_mset_messages_is_first (messages);
+
+return (messages->previous_node == NULL);
+}
+
 notmuch_message_t *
 notmuch_messages_get (notmuch_messages_t *messages)
 {
@@ -142,10 +155,24 @@ notmuch_messages_advance (notmuch_messages_t *messages)
 if (messages->iterator == NULL)
return;

+messages->previous_node = messages->iterator;
 messages->iterator = messages->iterator->next;
 }

 void
+notmuch_messages_regress (notmuch_messages_t *messages)
+{
+if (! messages->is_of_list_type)
+   return _notmuch_mset_messages_regress (messages);
+
+if (messages->previous_node == NULL)
+   return;
+
+messages->iterator = messages->previous_node;
+messages->previous_node = messages->iterator->prev;
+}
+
+void
 notmuch_messages_destroy (notmuch_messages_t *messages)
 {
 talloc_free (messages);
diff --git a/lib/notmuch-private.h b/lib/notmuch-private.h
index 133ed0e..5852c00 100644
--- a/lib/notmuch-private.h
+++ b/lib/notmuch-private.h
@@ -299,6 +299,7 @@ typedef struct _notmuch_message_list {
  */
 struct _notmuch_messages {
 notmuch_bool_t is_of_list_type;
+notmuch_message_node_t *previous_node;
 notmuch_message_node_t *iterator;
 };

@@ -321,12 +322,18 @@ _notmuch_messages_create (notmuch_message_list_t *list);
 notmuch_bool_t
 _notmuch_mset_messages_has_more (notmuch_messages_t *messages);

+notmuch_bool_t
+_notmuch_mset_messages_is_first (notmuch_messages_t *messages);
+
 notmuch_message_t *
 _notmuch_mset_messages_get (notmuch_messages_t *messages);

 void
 _notmuch_mset_messages_advance (notmuch_messages_t *messages);

+void
+_notmuch_mset_messages_regress (notmuch_messages_t *messages);
+
 /* message.cc */

 void
diff --git a/lib/notmuch.h b/lib/notmuch.h
index 60834fb..69bd98a 100644
--- a/lib/notmuch.h
+++ b/lib/notmuch.h
@@ -604,6 +604,10 @@ notmuch_thread_destroy (notmuch_thread_t *thread);
 notmuch_bool_t
 notmuch_messages_has_more (notmuch_messages_t *messages);

+/* Is the given notmuch_messages_t object on the first message */
+notmuch_bool_t
+notmuch_messages_is_first (notmuch_messages_t *messages);
+
 /* Get the current message from 'messages' as a notmuch_message_t.
  *
  * Note: The returned message belongs to 'messages' and has a lifetime
@@ -626,6 +630,10 @@ notmuch_messages_get (notmuch_messages_t *messages);
 void
 notmuch_messages_advance (notmuch_messages_t *messages);

+/* Regress the 'messages' iterator to the previous result. */
+void
+notmuch_messages_regress (notmuch_messages_t *messages);
+
 /* Destroy a notmuch_messages_t object.
  *
  * It's not strictly necessary to call this function. All memory from
diff --git a/lib/query.cc b/lib/query.cc
index 9106b92..94a6860 100644
--- a/lib/query.cc
+++ b/lib/query.cc
@@ -35,6 +35,7 @@ typedef struct _notmuch_mset_messages {
 notmuch_messages_t base;
 notmuch_database_t *notmuch;
 Xapian::MSetIterator iterator;
+Xapian::MSetIterator iterator_begin;
 Xapian::MSetIterator iterator_end;
 } notmuch_mset_messages_t;

@@ -86,6 +87,7 @@ static int
 _notmuch_messages_destructor (notmuch_mset_messages_t *messages)
 {
 messages->iterator.~MSetIterator ();
+messages->iterator_begin.~MSetIterator ();
 messages->iterator_end.~MSetIterator ();

 return 0;
@@ -108,6 +110,7 @@ notmuch_query_search_messages (notmuch_query_t *query)
messages->base.iterator = NULL;
messages->notmuch = notmuch;
new (>iterator) Xapian::MSetIterator ();
+   new (>iterator_begin) Xapian::MSetIterator ();
new (>iterator_end) Xapian::MSetIterator ();

talloc_set_destructor (

[notmuch] [PATCH 1/2] Convert notmuch_message_list_t in a doubly linked

2009-12-08 Thread mes...@sindominio.net
From: Ruben Pollan <mes...@sindominio.net>

The messages list now have pointers to previous nodes, so it is possible to
iterate backwards.
---
 lib/messages.c|   18 +-
 lib/notmuch-private.h |3 ++-
 lib/thread.cc |4 ++--
 3 files changed, 17 insertions(+), 8 deletions(-)

diff --git a/lib/messages.c b/lib/messages.c
index aa92535..5414f87 100644
--- a/lib/messages.c
+++ b/lib/messages.c
@@ -37,20 +37,28 @@ _notmuch_message_list_create (const void *ctx)
return NULL;

 list->head = NULL;
-list->tail = >head;
+list->tail = NULL;

 return list;
 }

-/* Append 'node' (which can of course point to an arbitrarily long
- * list of nodes) to the end of 'list'.
+/* Append 'node' to the end of 'list'.
  */
 void
 _notmuch_message_list_append (notmuch_message_list_t *list,
  notmuch_message_node_t *node)
 {
-*(list->tail) = node;
-list->tail = >next;
+node->prev = list->tail;
+if (list->head)
+{
+list->tail->next = node;
+}
+else
+{
+list->head = node;
+list->tail = node;
+}
+list->tail = node;
 }

 /* Allocate a new node for 'message' and append it to the end of
diff --git a/lib/notmuch-private.h b/lib/notmuch-private.h
index 0c340a7..133ed0e 100644
--- a/lib/notmuch-private.h
+++ b/lib/notmuch-private.h
@@ -285,11 +285,12 @@ notmuch_message_file_get_header (notmuch_message_file_t 
*message,
 typedef struct _notmuch_message_node {
 notmuch_message_t *message;
 struct _notmuch_message_node *next;
+struct _notmuch_message_node *prev;
 } notmuch_message_node_t;

 typedef struct _notmuch_message_list {
 notmuch_message_node_t *head;
-notmuch_message_node_t **tail;
+notmuch_message_node_t *tail;
 } notmuch_message_list_t;

 /* There's a rumor that there's an alternate struct _notmuch_messages
diff --git a/lib/thread.cc b/lib/thread.cc
index 321937b..24dbe2c 100644
--- a/lib/thread.cc
+++ b/lib/thread.cc
@@ -169,8 +169,8 @@ _resolve_thread_relationships (unused (notmuch_thread_t 
*thread))
  (void **) ))
{
*prev = node->next;
-   if (thread->message_list->tail == >next)
-   thread->message_list->tail = prev;
+   if (thread->message_list->tail == node)
+   thread->message_list->tail = node->prev;
node->next = NULL;
_notmuch_message_add_reply (parent, node);
} else {
-- 
1.6.5.4



[notmuch] regress option to messages iterator

2009-12-08 Thread mes...@sindominio.net
Two patches for implement the regress functions on messages. With them 
notmuch_messages_t can be use as an iterator forwards and backwards.

Up to now not really useful, nothing use them. I send them mainly to review.
I'll do the same to threads and tags, so the UIs can use them.

PS: It's the first time I'm using git-send-email, I hope I do everything well.