-
-# MAIN
-#-------------------------------------------------------------------------
-if __name__ == '__main__':
-
- # Handle command line options
- #-------------------------------------
- # No option given, print USAGE and exit
- if len(sys.argv) == 1:
- Notmuch().cmd_usage()
- #-------------------------------------
- elif sys.argv[1] == 'setup':
- """Interactively setup notmuch for first use."""
- print "Not implemented."
- #-------------------------------------
- elif sys.argv[1] == 'new':
- """Check for new and removed messages."""
- Notmuch().cmd_new()
- #-------------------------------------
- elif sys.argv[1] == 'help':
- """Print the help text"""
- Notmuch().cmd_help(sys.argv[1:])
- #-------------------------------------
- elif sys.argv[1] == 'part':
- db = Database()
- query_string = ''
- part_num=0
- first_search_term = None
- for (i, arg) in enumerate(sys.argv[1:]):
- if arg.startswith('--part='):
- part_num_str=arg.split("=")[1]
- try:
- part_num = int(part_num_str)
- except ValueError:
- # just emulating behavior
- sys.exit()
- elif not arg.startswith('--'):
- #save the position of the first sys.argv that is a search term
- first_search_term = i+1
-
- if first_search_term:
- #mangle arguments wrapping terms with spaces in quotes
- querystr = quote_query_line(sys.argv[first_search_term:])
-
- qry = Query(db,querystr)
- msgs = qry.search_messages()
- msg_list = []
- for m in msgs:
- msg_list.append(m)
-
- if len(msg_list) == 0:
- sys.exit()
- elif len(msg_list) > 1:
- raise Exception("search term did not match precisely one message")
- else:
- msg = msg_list[0]
- print(msg.get_part(part_num))
- #-------------------------------------
- elif sys.argv[1] == 'search':
- db = Database()
- query_string = ''
- sort_order="newest-first"
- first_search_term = None
- for (i, arg) in enumerate(sys.argv[1:]):
- if arg.startswith('--sort='):
- sort_order=arg.split("=")[1]
- if not sort_order in ("oldest-first", "newest-first"):
- raise Exception("unknown sort order")
- elif not arg.startswith('--'):
- #save the position of the first sys.argv that is a search term
- first_search_term = i+1
-
- if first_search_term:
- #mangle arguments wrapping terms with spaces in quotes
- querystr = quote_query_line(sys.argv[first_search_term:])
-
- qry = Query(db,querystr)
- if sort_order == "oldest-first":
- qry.set_sort(Query.SORT.OLDEST_FIRST)
- else:
- qry.set_sort(Query.SORT.NEWEST_FIRST)
- t = qry.search_threads()
-
- for thread in t:
- print(str(thread))
-
- #-------------------------------------
- elif sys.argv[1] == 'show':
- entire_thread = False
- db = Database()
- out_format="text"
- querystr=''
- first_search_term = None
-
- #ugly homegrown option parsing
- #TODO: use OptionParser
- for (i, arg) in enumerate(sys.argv[1:]):
- if arg == '--entire-thread':
- entire_thread = True
- elif arg.startswith("--format="):
- out_format = arg.split("=")[1]
- if out_format == 'json':
- #for compatibility use --entire-thread for json
- entire_thread = True
- if not out_format in ("json", "text"):
- raise Exception("unknown format")
- elif not arg.startswith('--'):
- #save the position of the first sys.argv that is a search term
- first_search_term = i+1
-
- if first_search_term:
- #mangle arguments wrapping terms with spaces in quotes
- querystr = quote_query_line(sys.argv[first_search_term:])
-
- t = Query(db,querystr).search_threads()
-
- first_toplevel=True
- if out_format.lower()=="json":
- sys.stdout.write("[")
-
- for thrd in t:
- msgs = thrd.get_toplevel_messages()
-
- if not first_toplevel:
- if out_format.lower()=="json":
- sys.stdout.write(", ")
-
- first_toplevel = False
-
- msgs.print_messages(out_format, 0, entire_thread)
-
- if out_format.lower() == "json":
- sys.stdout.write("]")
- sys.stdout.write("\n")
-
- #-------------------------------------
- elif sys.argv[1] == 'reply':
- db = Database()
- if len(sys.argv) == 2:
- #no search term. abort
- print("Error: notmuch reply requires at least one search term.")
- sys.exit()
-
- #mangle arguments wrapping terms with spaces in quotes
- querystr = quote_query_line(sys.argv[2:])
- msgs = Query(db,querystr).search_messages()
- print (Notmuch().format_reply(msgs))
-
- #-------------------------------------
- elif sys.argv[1] == 'count':
- if len(sys.argv) == 2:
- #no further search term, count all
- querystr=''
- else:
- #mangle arguments wrapping terms with spaces in quotes
- querystr = quote_query_line(sys.argv[2:])
- print(Database().create_query(querystr).count_messages())
-
- #-------------------------------------
- elif sys.argv[1] == 'tag':
- #build lists of tags to be added and removed
- add, remove = [], []
- while not sys.argv[2]=='--' and \
- (sys.argv[2].startswith('+') or sys.argv[2].startswith('-')):
- if sys.argv[2].startswith('+'):
- #append to add list without initial +
- add.append(sys.argv.pop(2)[1:])
- else:
- #append to remove list without initial -
- remove.append(sys.argv.pop(2)[1:])
- #skip eventual '--'
- if sys.argv[2]=='--': sys.argv.pop(2)
- #the rest is search terms
- querystr = quote_query_line(sys.argv[2:])
- db = Database(mode=Database.MODE.READ_WRITE)
- m = Query(db,querystr).search_messages()
- for msg in m:
- #actually add and remove all tags
- map(msg.add_tag, add)
- map(msg.remove_tag, remove)
- #-------------------------------------
- elif sys.argv[1] == 'search-tags':
- if len(sys.argv) == 2:
- #no further search term
- print("\n".join(Database().get_all_tags()))
- else:
- #mangle arguments wrapping terms with spaces in quotes
- querystr = quote_query_line(sys.argv[2:])
- db = Database()
- m = Query(db,querystr).search_messages()
- print("\n".join([t for t in m.collect_tags()]))
- #-------------------------------------
- elif sys.argv[1] == 'dump':
- #TODO: implement "dump <filename>"
- if len(sys.argv) == 2:
- f = sys.stdout
- else:
- f = open(sys.argv[2],"w")
- db = Database()
- q = Query(db,'')
- q.set_sort(Query.SORT.MESSAGE_ID)
- m = q.search_messages()
- for msg in m:
- f.write("%s (%s)\n" % (msg.get_message_id(), msg.get_tags()))
- #-------------------------------------
- elif sys.argv[1] == 'restore':
- import re
- if len(sys.argv) == 2:
- print("No filename given. Reading dump from stdin.")
- f = sys.stdin
- else:
- f = open(sys.argv[2],"r")
- #split the msg id and the tags
- MSGID_TAGS = re.compile("(\S+)\s\((.*)\)$")
- db = Database(mode=Database.MODE.READ_WRITE)
-
- #read each line of the dump file
- for line in f:
- m = MSGID_TAGS.match(line)
- if not m:
- sys.stderr.write("Warning: Ignoring invalid input line: %s" %
- line)
- continue
- # split line in components and fetch message
- msg_id = m.group(1)
- new_tags= set(m.group(2).split())
- msg = db.find_message(msg_id)
-
- if msg == None:
- sys.stderr.write(
- "Warning: Cannot apply tags to missing message: %s\n" % id)
- continue
-
- #do nothing if the old set of tags is the same as the new one
- old_tags = set(msg.get_tags())
- if old_tags == new_tags: continue
-
- #set the new tags
- msg.freeze()
- #only remove tags if the new ones are not a superset anyway
- if not (new_tags > old_tags): msg.remove_all_tags()
- for tag in new_tags: msg.add_tag(tag)
- msg.thaw()
-
- #-------------------------------------
- else:
- # unknown command
- print "Error: Unknown command '%s' (see \"notmuch help\")" % sys.argv[1]
-
-
- #TODO: implement
- """
-setup
-new
-show <search-terms> [...]
-reply [options...] <search-terms> [...]
-restore <filename>
- """