Return-Path: X-Original-To: notmuch@notmuchmail.org Delivered-To: notmuch@notmuchmail.org Received: from localhost (localhost [127.0.0.1]) by olra.theworths.org (Postfix) with ESMTP id 11F1E431FB6 for ; Sun, 9 Jan 2011 23:35:47 -0800 (PST) X-Virus-Scanned: Debian amavisd-new at olra.theworths.org X-Spam-Flag: NO X-Spam-Score: 0 X-Spam-Level: X-Spam-Status: No, score=0 tagged_above=-999 required=5 tests=[RCVD_IN_DNSWL_NONE=-0.0001] autolearn=disabled Received: from olra.theworths.org ([127.0.0.1]) by localhost (olra.theworths.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id qWS-+TegsXGd for ; Sun, 9 Jan 2011 23:35:43 -0800 (PST) X-Greylist: delayed 3699 seconds by postgrey-1.32 at olra; Sun, 09 Jan 2011 23:35:42 PST Received: from smtprelay02.ispgateway.de (smtprelay02.ispgateway.de [80.67.18.14]) by olra.theworths.org (Postfix) with ESMTP id 99719431FB5 for ; Sun, 9 Jan 2011 23:35:42 -0800 (PST) Received: from [87.180.81.26] (helo=stokes.schwinge.homeip.net) by smtprelay02.ispgateway.de with esmtpa (Exim 4.68) (envelope-from ) id 1Pc0nY-0006F7-PV for notmuch@notmuchmail.org; Sun, 09 Jan 2011 20:19:29 +0100 Received: (qmail 23501 invoked from network); 9 Jan 2011 19:19:20 -0000 Received: from kepler.schwinge.homeip.net (192.168.111.7) by stokes.schwinge.homeip.net with QMQP; 9 Jan 2011 19:19:20 -0000 Received: (nullmailer pid 27483 invoked by uid 1000); Sun, 09 Jan 2011 19:19:19 -0000 From: Thomas Schwinge To: notmuch@notmuchmail.org Subject: Hallo!, and hooray!, and some first work, too User-Agent: Notmuch/0.5-33-g665f77b (http://notmuchmail.org) Emacs/23.2.1 (i486-pc-linux-gnu) Date: Sun, 09 Jan 2011 20:19:15 +0100 Message-ID: <87tyhhvqa4.fsf@kepler.schwinge.homeip.net> MIME-Version: 1.0 Content-Type: multipart/signed; boundary="=-=-="; micalg=pgp-sha1; protocol="application/pgp-signature" X-Df-Sender: thomas@schwinge.name X-BeenThere: notmuch@notmuchmail.org X-Mailman-Version: 2.1.13 Precedence: list List-Id: "Use and development of the notmuch mail system." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 10 Jan 2011 07:35:47 -0000 --=-=-= Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable Hallo! After having read about it in ..., in ..., (don't know anymore), and then again over at LWN, I have had the plan to try (or rather: directly switch to) notmuch like half a year ago, or longer. I eventually was brave enough to begin that process in the last days of 2010. I'm still with you, as you can see. Hooray! :-) As I said on IRC already: there are, of course, still some rough edges, but what else should I expect from such a young project. I'm currently using getmail, then maildrop which invokes notmuch-deliver for getting my emails into both maildir storage, and making them known to notmuch. In that process I can apply tags at will (based on List-Id: / Mailing-List: headers, mostly, but also for possibly-spam, and so on), and then use a script that operates on these to further massage them. Thus, I don't really have a need for ``notmuch new'' anymore, and notmuch-deliver is sort of an atomic / integrated ``put into maildir and add tags'' tool for me. I will post more details on my setup (or rather: directly put it into the wiki), as soon as all this settles down some more. I have not yet switched all my email channels to notmuch, but will do so soon, I think. Likewise, there are some topics I'd like to discuss. I'll also begin to plow through notmuch's mailing list archive, and will gladly accept id:xxx pointers that answer / discuss the questions I'll be sending. I poked at notmuch-deliver's code two weeks ago already (Ali, beware, there'll be some few further patches coming), and in the last hours, I finally had a look at notmuch.h and some of the source code. Here is a diff containing some comments, or to-do items. Not all are fully fledged (I have neither been using talloc, nor Xapian before), but perhaps someone nevertheless feels like commenting on them. In general I can say, that the notmuch code makes a solid impression. :-) diff --git a/emacs/notmuch-maildir-fcc.el b/emacs/notmuch-maildir-fcc.el index 3f1c124..0d7017c 100644 =2D-- a/emacs/notmuch-maildir-fcc.el +++ b/emacs/notmuch-maildir-fcc.el @@ -16,6 +16,14 @@ ;; To use this as the fcc handler for message-mode, ;; customize the notmuch-fcc-dirs variable =20 +;; TODO. A bunch of maildir code is not specific to fcc handling and shou= ld be +;; factored out. + +;; TODO. In fact, apart from using notmuch-database-path (which should +;; probably be message-directory instead, anyways?), this whole unit is not +;; specific to notmuch, and should perhaps be integrated into Emacs' +;; message.el -- or is there even anything in Gnus that can directly be us= ed? + (eval-when-compile (require 'cl)) (require 'message) =20 @@ -73,7 +81,7 @@ yet when sending a mail." (defun notmuch-fcc-header-setup () "Add an Fcc header to the current message buffer. =20 =2DCan be added to `message-send-hook' and will set the Fcc header +Is by default added to `message-header-setup-hook' and will set the Fcc he= ader based on the values of `notmuch-fcc-dirs'. An existing Fcc header will NOT be removed or replaced." =20 @@ -163,7 +171,7 @@ will NOT be removed or replaced." (make-directory (concat path "/new/") t) (make-directory (concat path "/tmp/") t)) ((file-regular-p path) =2D (error "%s is a file. Can't creat maildir." path)) + (error "%s is a file. Can't create maildir." path)) (t (error "I don't know how to create a maildir here")))) =20 @@ -173,6 +181,8 @@ if successful, nil if not." (let ((msg-id (notmuch-maildir-fcc-make-uniq-maildir-id))) (while (file-exists-p (concat destdir "/tmp/" msg-id)) (setq msg-id (notmuch-maildir-fcc-make-uniq-maildir-id))) +;; TODO. Race. Should instead (try to) open (create) the file exclusivel= y, +;; until that succeeds. (cond ((notmuch-maildir-fcc-dir-is-maildir-p destdir) (write-file (concat destdir "/tmp/" msg-id)) msg-id) diff --git a/lib/database.cc b/lib/database.cc index 7a00917..b08c429 100644 =2D-- a/lib/database.cc +++ b/lib/database.cc @@ -551,7 +551,10 @@ notmuch_database_create (const char *path) =20 notmuch =3D notmuch_database_open (path, NOTMUCH_DATABASE_MODE_READ_WRITE); + /* XXX: should check 'notmuch'. */ + notmuch_database_upgrade (notmuch, NULL, NULL); + /* XXX: should check return value. */ =20 DONE: if (notmuch_path) @@ -760,18 +763,6 @@ handle_sigalrm (unused (int signal)) do_progress_notify =3D 1; } =20 =2D/* Upgrade the current database. =2D * =2D * After opening a database in read-write mode, the client should =2D * check if an upgrade is needed (notmuch_database_needs_upgrade) and =2D * if so, upgrade with this function before making any modifications. =2D * =2D * The optional progress_notify callback can be used by the caller to =2D * provide progress indication to the user. If non-NULL it will be =2D * called periodically with 'count' as the number of messages upgraded =2D * so far and 'total' the overall number of messages that will be =2D * converted. =2D */ notmuch_status_t notmuch_database_upgrade (notmuch_database_t *notmuch, void (*progress_notify) (void *closure, @@ -1012,6 +1003,7 @@ _notmuch_database_get_directory_db_path (const char *= path) * is an empty string, then both directory and basename will be * returned as NULL. */ +/* XXX: isn't there a standard libc function that can be used? */ notmuch_status_t _notmuch_database_split_path (void *ctx, const char *path, @@ -1141,6 +1133,7 @@ _notmuch_database_filename_to_direntry (void *ctx, return status; =20 *direntry =3D talloc_asprintf (ctx, "%u:%s", directory_id, basename); + /* XXX: *direntry !=3D NULL? */ =20 return NOTMUCH_STATUS_SUCCESS; } @@ -1168,6 +1161,9 @@ _notmuch_database_relative_path (notmuch_database_t *= notmuch, while (*relative =3D=3D '/' && *(relative+1) =3D=3D '/') relative++; =20 + /* XXX: canonicalize paths (symlinks, `x/./y, `x/../y') before + comparing? */ + if (strncmp (relative, db_path, db_path_len) =3D=3D 0) { relative +=3D db_path_len; @@ -1601,6 +1597,8 @@ notmuch_database_add_message (notmuch_database_t *not= much, =20 /* If a message ID is too long, substitute its sha1 instead. */ if (message_id && strlen (message_id) > NOTMUCH_MESSAGE_ID_MAX) { + /* XXX: How to distinguish this one later on (or don't we ha= ve + to?) from the message-id (possibly) generated below? */ char *compressed =3D _message_id_compressed (message_file, message_id); talloc_free (message_id); @@ -1619,6 +1617,8 @@ notmuch_database_add_message (notmuch_database_t *not= much, goto DONE; } =20 + /* XXX: How to distinguish this one later on (or don't we have= to?) + from the message-id (possibly) generated above? */ message_id =3D talloc_asprintf (message_file, "notmuch-sha1-%s", sha1); free (sha1); @@ -1641,6 +1641,7 @@ notmuch_database_add_message (notmuch_database_t *not= much, } =20 _notmuch_message_add_filename (message, filename); + /* XXX: check return value. */ =20 /* Is this a newly created message object? */ if (private_status =3D=3D NOTMUCH_PRIVATE_STATUS_NO_DOCUMENT_FOUND) { @@ -1655,6 +1656,7 @@ notmuch_database_add_message (notmuch_database_t *not= much, _notmuch_message_set_date (message, date); =20 _notmuch_message_index_file (message, filename); + /* XXX: check return value. */ } else { ret =3D NOTMUCH_STATUS_DUPLICATE_MESSAGE_ID; } @@ -1735,11 +1737,15 @@ notmuch_database_remove_message (notmuch_database_t= *notmuch, status =3D NOTMUCH_STATUS_DUPLICATE_MESSAGE_ID; } } +=20=20=20=20=20=20=20=20 + /* XXX: talloc_free (term); */ } catch (const Xapian::Error &error) { fprintf (stderr, "Error: A Xapian exception occurred removing message: %s= \n", error.get_msg().c_str()); notmuch->exception_reported =3D TRUE; status =3D NOTMUCH_STATUS_XAPIAN_EXCEPTION; + + /* XXX: (conditionally) talloc_free (term); */ } =20 talloc_free (local); diff --git a/lib/directory.cc b/lib/directory.cc index 946be4f..925b1da 100644 =2D-- a/lib/directory.cc +++ b/lib/directory.cc @@ -140,6 +140,7 @@ _notmuch_directory_create (notmuch_database_t *notmuch, char *term =3D talloc_asprintf (local, "%s%s", _find_prefix ("directory"), db_path); directory->doc.add_term (term, 0); + /* XXX?: talloc_free (term); */ =20 directory->doc.set_data (path); =20 @@ -152,6 +153,7 @@ _notmuch_directory_create (notmuch_database_t *notmuch, _find_prefix ("directory-direntry"), parent_id, basename); directory->doc.add_term (term, 0); + /* XXX?: talloc_free (term); */ } =20 directory->doc.add_value (NOTMUCH_VALUE_TIMESTAMP, diff --git a/lib/message.cc b/lib/message.cc index adcd07d..cf4e36a 100644 =2D-- a/lib/message.cc +++ b/lib/message.cc @@ -187,13 +187,14 @@ _notmuch_message_create (const void *talloc_owner, * There is already a document with message ID 'message_id' in the * database. The returned message can be used to query/modify the * document. + * * NOTMUCH_PRIVATE_STATUS_NO_DOCUMENT_FOUND: * * No document with 'message_id' exists in the database. The * returned message contains a newly created document (not yet * added to the database) and a document ID that is known not to * exist in the database. The caller can modify the message, and a =2D * call to _notmuch_message_sync will add * the document to the + * call to _notmuch_message_sync will add the document to the * database. * * If an error occurs, this function will return NULL and *status @@ -449,8 +450,10 @@ _notmuch_message_add_filename (notmuch_message_t *mess= age, status =3D _notmuch_database_filename_to_direntry (local, message->notmuch, filename, &direntry); =2D if (status) + if (status) { + /* XXX: talloc_free (local); */ return status; + } =20 _notmuch_message_add_term (message, "file-direntry", direntry); =20 @@ -717,6 +720,7 @@ _notmuch_message_close (notmuch_message_t *message) * * This change will not be reflected in the database until the next * call to _notmuch_message_sync. */ +/* XXX: basically nowehere this function's return value is checked. */ notmuch_private_status_t _notmuch_message_add_term (notmuch_message_t *message, const char *prefix_name, @@ -730,9 +734,12 @@ _notmuch_message_add_term (notmuch_message_t *message, =20 term =3D talloc_asprintf (message, "%s%s", _find_prefix (prefix_name), value); + /* XXX: term !=3D NULL? */ =20 =2D if (strlen (term) > NOTMUCH_TERM_MAX) + if (strlen (term) > NOTMUCH_TERM_MAX) { + /* XXX: talloc_free (term); */ return NOTMUCH_PRIVATE_STATUS_TERM_TOO_LONG; + } =20 message->doc.add_term (term, 0); =20 @@ -820,6 +827,7 @@ notmuch_message_add_tag (notmuch_message_t *message, co= nst char *tag) if (strlen (tag) > NOTMUCH_TAG_MAX) return NOTMUCH_STATUS_TAG_TOO_LONG; =20 + /* XXX: what if tag is already present -- added again? */ private_status =3D _notmuch_message_add_term (message, "tag", tag); if (private_status) { INTERNAL_ERROR ("_notmuch_message_add_term return unexpected value: %d\n", diff --git a/lib/notmuch.h b/lib/notmuch.h index e508309..ffc7f8f 100644 =2D-- a/lib/notmuch.h +++ b/lib/notmuch.h @@ -810,6 +810,7 @@ notmuch_message_set_flag (notmuch_message_t *message, * For the original textual representation of the Date header from the * message call notmuch_message_get_header() with a header value of * "date". */ +/* XXX: what if Date: was missing? */ time_t notmuch_message_get_date (notmuch_message_t *message); =20 @@ -866,6 +867,8 @@ notmuch_message_get_tags (notmuch_message_t *message); =20 /* Add a tag to the given message. * + * XXX: which are valid characters for a tag? + * * Return value: * * NOTMUCH_STATUS_SUCCESS: Tag successfully added to message @@ -1112,7 +1115,7 @@ notmuch_tags_destroy (notmuch_tags_t *tags); * * o Read the mtime of a directory from the filesystem * =2D * o Call add_message for all mail files in the directory + * o Call notmuch_database_add_message for all mail files in the directo= ry * * o Call notmuch_directory_set_mtime with the mtime read from the * filesystem. @@ -1157,7 +1160,7 @@ notmuch_directory_get_mtime (notmuch_directory_t *dir= ectory); notmuch_filenames_t * notmuch_directory_get_child_files (notmuch_directory_t *directory); =20 =2D/* Get a notmuch_filenams_t iterator listing all the filenames of +/* Get a notmuch_filenames_t iterator listing all the filenames of * sub-directories in the database within the given directory. * * The returned filenames will be the basename-entries only (not diff --git a/notmuch-new.c b/notmuch-new.c index cdf8513..74a09bf 100644 =2D-- a/notmuch-new.c +++ b/notmuch-new.c @@ -784,6 +784,7 @@ notmuch_new_command (void *ctx, int argc, char *argv[]) gettimeofday (&add_files_state.tv_start, NULL); notmuch_database_upgrade (notmuch, upgrade_print_progress, &add_files_state); + /* XXX: should check return value. */ printf ("Your notmuch database has now been upgraded to database form= at version %u.\n", notmuch_database_get_version (notmuch)); } diff --git a/notmuch-restore.c b/notmuch-restore.c index f095f64..2c607c3 100644 =2D-- a/notmuch-restore.c +++ b/notmuch-restore.c @@ -115,7 +115,10 @@ notmuch_restore_command (unused (void *ctx), int argc,= char *argv[]) } =20 notmuch_message_freeze (message); + /* XXX: check return value. */ + notmuch_message_remove_all_tags (message); + /* XXX: check return value. */ =20 next =3D file_tags; while (next) { @@ -133,6 +136,7 @@ notmuch_restore_command (unused (void *ctx), int argc, = char *argv[]) } =20 notmuch_message_thaw (message); + /* XXX: check return value. */ =20 if (synchronize_flags) notmuch_message_tags_to_maildir_flags (message); diff --git a/notmuch-tag.c b/notmuch-tag.c index 60e21e0..3b7a00c 100644 =2D-- a/notmuch-tag.c +++ b/notmuch-tag.c @@ -120,6 +120,7 @@ notmuch_tag_command (void *ctx, unused (int argc), unus= ed (char *argv[])) message =3D notmuch_messages_get (messages); =20 notmuch_message_freeze (message); + /* XXX: check return value. */ =20 for (i =3D 0; i < remove_tags_count; i++) notmuch_message_remove_tag (message, @@ -129,6 +130,7 @@ notmuch_tag_command (void *ctx, unused (int argc), unus= ed (char *argv[])) notmuch_message_add_tag (message, argv[add_tags[i]] + 1); =20 notmuch_message_thaw (message); + /* XXX: check return value. */ =20 if (synchronize_flags) notmuch_message_tags_to_maildir_flags (message); Gr=C3=BC=C3=9Fe, Thomas --=-=-= Content-Type: application/pgp-signature -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.10 (GNU/Linux) iEYEARECAAYFAk0qCjMACgkQFaWaPJ2HwAoDHACfXoIIZMdiDTC88w7Mu78Ks/r6 1rcAnA/LXMFwJOFF5bNSY9NzmM5OMZ+X =qHIc -----END PGP SIGNATURE----- --=-=-=--