2 """This is a notmuch implementation in python. It's goal is to allow running the test suite on the cnotmuch python bindings."""
3 import sys, os, re, logging
4 from cnotmuch.notmuch import Database, Query
5 PREFIX=re.compile('(\w+):(.*$)')
6 #TODO Handle variable: NOTMUCH-CONFIG
8 #-------------------------------------------------------------------------
9 HELPTEXT="""The notmuch mail system.
11 Usage: notmuch <command> [args...]
13 Where <command> and [args...] are as follows:
15 setup Interactively setup notmuch for first use.
19 Find and import new messages to the notmuch database.
21 search [options...] <search-terms> [...]
23 Search for messages matching the given search terms.
25 show <search-terms> [...]
27 Show all messages matching the search terms.
29 count <search-terms> [...]
31 Count messages matching the search terms.
33 reply [options...] <search-terms> [...]
35 Construct a reply template for a set of messages.
37 tag +<tag>|-<tag> [...] [--] <search-terms> [...]
39 Add/remove tags for all messages matching the search terms.
43 Create a plain-text dump of the tags for each message.
47 Restore the tags from the given dump file (see 'dump').
49 search-tags [<search-terms> [...] ]
51 List all tags found in the database or matching messages.
55 This message, or more detailed help for the named command.
57 Use "notmuch help <command>" for more details on each command.
58 And "notmuch help search-terms" for the common search-terms syntax.
60 #-------------------------------------------------------------------------
61 #TODO: replace the dynamic pieces
62 USAGE="""Notmuch is configured and appears to have a database. Excellent!
64 At this point you can start exploring the functionality of notmuch by
65 using commands such as:
67 notmuch search tag:inbox
69 notmuch search to:"Sebastian Spaeth"
71 notmuch search from:"Sebastian@SSpaeth.de"
73 notmuch search subject:"my favorite things"
75 See "notmuch help search" for more details.
77 You can also use "notmuch show" with any of the thread IDs resulting
78 from a search. Finally, you may want to explore using a more sophisticated
79 interface to notmuch such as the emacs interface implemented in notmuch.el
80 or any other interface described at http://notmuchmail.org
82 And don't forget to run "notmuch new" whenever new mail arrives.
84 Have fun, and may your inbox never have much mail.
86 #-------------------------------------------------------------------------
87 def quote_query_line(argv):
88 #mangle arguments wrapping terms with spaces in quotes
89 for i in xrange(0,len(argv)):
90 if argv[i].find(' ') >= 0:
91 #if we use prefix:termWithSpaces, put quotes around term
92 m = PREFIX.match(argv[i])
94 argv[i] = '%s:"%s"' % (m.group(1), m.group(2))
96 argv[i] = '"'+argv[i]+'"'
99 if __name__ == '__main__':
101 # Handle command line options
103 #-------------------------------------
104 if len(sys.argv) == 1:
106 #-------------------------------------
107 elif sys.argv[1] == 'setup':
108 """ Interactively setup notmuch for first use. """
109 print "Not implemented."
110 #-------------------------------------
111 elif sys.argv[1] == 'help':
112 if len(sys.argv) == 2: print HELPTEXT
113 else: print "Not implemented"
114 #-------------------------------------
115 elif sys.argv[1] == 'show':
117 if len(sys.argv) == 2:
118 #no further search term
121 #mangle arguments wrapping terms with spaces in quotes
122 querystr = quote_query_line(sys.argv[2:])
123 logging.debug("show "+querystr)
124 m = Query(db,querystr).search_messages()
126 print(msg.format_as_text())
127 #-------------------------------------
128 elif sys.argv[1] == 'new':
129 #TODO: handle --verbose
130 print "Not implemented."
131 #-------------------------------------
132 elif sys.argv[1] == 'count':
134 if len(sys.argv) == 2:
135 #no further search term
138 #mangle arguments wrapping terms with spaces in quotes
139 querystr = quote_query_line(sys.argv[2:])
140 logging.debug("count "+querystr)
141 print(len(Query(db,querystr).search_messages()))
142 #-------------------------------------
143 elif sys.argv[1] == 'tag':
144 #build lists of tags to be added and removed
146 while not sys.argv[2]=='--' and \
147 (sys.argv[2].startswith('+') or sys.argv[2].startswith('-')):
148 if sys.argv[2].startswith('+'):
149 #append to add list without initial +
150 add.append(sys.argv.pop(2)[1:])
152 #append to remove list without initial -
153 remove.append(sys.argv.pop(2)[1:])
155 if sys.argv[2]=='--': sys.argv.pop(2)
156 #the rest is search terms
157 querystr = quote_query_line(sys.argv[2:])
158 logging.warning("tag search-term "+querystr)
159 db = Database(mode=Database.MODE.READ_WRITE)
160 m = Query(db,querystr).search_messages()
162 #actually add and remove all tags
163 map(msg.add_tag, add)
164 map(msg.remove_tag, remove)
165 #-------------------------------------
166 elif sys.argv[1] == 'search-tags':
167 if len(sys.argv) == 2:
168 #no further search term
169 print("\n".join(Database().get_all_tags()))
171 #mangle arguments wrapping terms with spaces in quotes
172 querystr = quote_query_line(sys.argv[2:])
173 logging.debug("search-term "+querystr)
175 m = Query(db,querystr).search_messages()
176 print("\n".join([t for t in m.collect_tags()]))
177 #-------------------------------------
178 elif sys.argv[1] == 'dump':
179 #TODO: implement "dump <filename>"
182 q.set_sort(Query.SORT.MESSAGE_ID)
183 m = q.search_messages()
185 print("%s (%s)" % (msg.get_message_id(), msg.get_tags()))
186 #-------------------------------------
189 print "Error: Unknown command '%s' (see \"notmuch help\")" % sys.argv[1]
196 search [options...] <search-terms> [...]
197 show <search-terms> [...]
198 reply [options...] <search-terms> [...]