Whoops, get rid of that spurious API call
[trac-attack.git] / trac-attack.py
1 #!/usr/bin/python
2 import ConfigParser
3 from optparse import OptionParser
4 import os, os.path, sys
5 import xmlrpclib
6 import textwrap
7
8 config = ConfigParser.RawConfigParser()
9 config.read(os.path.join(os.environ['HOME'], '.trac-attack.rc'))
10 default_trac = config.get('main', 'default')
11
12 options = OptionParser()
13 options.add_option('-t', '--trac', dest = "trac",
14                    help = "Which trac to connect to")
15
16 def open_rpc(trac):
17     url = config.get(trac, 'url')
18     return xmlrpclib.ServerProxy(url)
19
20 def list_tickets(tickets):
21     listing_wrapper = textwrap.TextWrapper(
22             width = 63, replace_whitespace = True, drop_whitespace = True,
23             subsequent_indent = ' ' * 17)
24
25     print "%-7s %-8s %s" % ('ID', 'priority', 'summary')
26     print '-' * 70
27     for t in tickets:
28         print "#%-6d %-8s" % (t[0], t[3]['priority']), listing_wrapper.fill(t[3]['summary'])
29
30 def show_ticket(ticket):
31     description_wrap = textwrap.TextWrapper(width = 80)
32
33     (id, time_created, time_changed, attributes) = ticket
34
35     print "Ticket #%d (%s %s)" % (id, attributes['status'], attributes['type'])
36     print attributes['summary']
37     print
38
39     fields = [
40             [('Reported by', 'reporter'), ('Owned by', 'owner')],
41             [('Priority', 'priority'), ('Milestone', 'milestone')],
42             [('Component', 'component'), ('Version', 'version')],
43             [('Keywords', 'keywords'), ('Cc', 'cc')],
44     ]
45     for row in fields:
46         print "%-39s %-39s" % tuple(map(lambda x: "%s: %s" % (x[0], attributes[x[1]]), row))
47
48     print
49     print description_wrap.fill(attributes['description'])
50     print
51
52 def editor():
53     raise NotImplementedError
54
55 def comment_on_ticket(id, comment):
56     raise NotImplementedError
57
58 def main():
59     (flags, args) = options.parse_args()
60     trac = flags.trac or default_trac
61     server = open_rpc(trac)
62     user = config.get(trac, 'user')
63     
64     if args[0] == 'ls' or args[0] == 'list':
65         if len(args) > 1:
66             try:
67                 query = config.get('queries', args[1])
68             except ConfigParser.NoOptionError:
69                 print "I couldn't find the query %s" % args[1]
70                 sys.exit(1)
71         else:
72             try:
73                 query = config.get('queries', 'default')
74             except ConfigParser.NoOptionError:
75                 query = "status!=closed&owner=$USER"
76         tickets = server.ticket.query(query)
77         multicall = xmlrpclib.MultiCall(server)
78         for t in tickets:
79             multicall.ticket.get(t)
80         list_tickets(multicall())
81     elif args[0] == 'info' or args[0] == 'show':
82         id = int(args[1])
83         ticket = server.ticket.get(id)
84         show_ticket(ticket)
85     elif args[0] == 'comment':
86         id = int(args[1])
87         comment = editor()
88         comment_on_ticket(id, comment)
89     else:
90         print "Command %s not understood" % args[0]
91
92 if __name__ == "__main__":
93     main()