-
Notifications
You must be signed in to change notification settings - Fork 6
/
Copy pathtrac-remote.py
executable file
·108 lines (95 loc) · 3.87 KB
/
trac-remote.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
#!/usr/bin/python
import sys, os
import xmlrpclib
import logging
from optparse import OptionParser
LOGGER_NAME="trac-remote"
DEFAULT_CREDENTIALS=os.path.expanduser('~/.trac-credentials')
DEFAULT_SERVER="athena10.mit.edu"
DEFAULT_RPC_PATH="/trac/login/rpc"
logger = logging.getLogger(LOGGER_NAME)
class Trac:
use_SSL = True
valid_repos = ("-development", "-proposed", "production")
def __init__(self, credentials):
scheme = "http"
if self.use_SSL:
scheme="https"
self._uri = "%s://%s:%s@%s%s" % (scheme,
credentials[0],
credentials[1],
DEFAULT_SERVER,
DEFAULT_RPC_PATH)
logger.debug("URI: %s", self._uri)
self._server = xmlrpclib.ServerProxy(self._uri)
def _update(self, ticket_id, comment, fields, notify=True, author=""):
# Setting author requires TICKET_ADMIN or higher for the XML
# RPC user, otherwise it will be ignored and the username of the
# XML RPC user will be substituted
try:
response = self._server.ticket.get(ticket_id)
# Returns [id, time_created, time_changed, attributes]
fields["_ts"] = response[3]["_ts"]
if "action" not in fields or (fields["action"] == response[3]["status"]):
fields["action"] = "leave"
self._server.ticket.update(ticket_id, comment, fields, notify, author)
except xmlrpclib.Fault, e:
print >>sys.stderr, e.message
sys.exit(1)
def upload_to_development(self, ticket_id, version):
self._update(ticket_id, "Uploaded to -development",
{"fix_version": version,
"action": "development"})
def upload_to_proposed(self, ticket_id, version):
self._update(ticket_id, "Uploaded to -proposed",
{"fix_version": version,
"action": "proposed"})
def upload_to_production(self, ticket_id, version):
self._update(ticket_id, "Uploaded to production",
{"fix_version": version,
"action": "resolve",
"action_resolve_resolve_resolution": "fixed"})
def commit_to_master(self, ticket_id, comment, author):
self._update(ticket_id, comment,
{"action": "committed"}, True, author)
def test(self):
try:
response = self._server.system.getAPIVersion()
print "API Version: ", response
except xmlrpclib.Fault, e:
print >>sys.stderr, e.message
sys.exit(1)
if __name__ == '__main__':
parser = OptionParser()
parser.set_defaults(debug=False)
parser.add_option("--debug", action="store_true", dest="debug")
parser.add_option("--credentials", action="store", type="string",
default=DEFAULT_CREDENTIALS, dest="credentials")
(options, args) = parser.parse_args()
logging.basicConfig(level=logging.WARN, format='%(asctime)s %(levelname)s:%(name)s:%(message)s')
if options.debug:
logger.setLevel(logging.DEBUG)
if len(args) < 1:
print >>sys.stderr, "Syntax Error"
sys.exit(1)
try:
f = open(options.credentials, "r")
creds = f.readline().rstrip().split(':', 1)
f.close()
except IOError, e:
print >>sys.stderr, "Error reading credentials file:", e
sys.exit(1)
if len(creds) != 2:
print >>sys.stderr, "Malformatted credentials file."
sys.exit(1)
t = Trac(creds)
cmd = args.pop(0)
try:
getattr(t, cmd)(*args)
except AttributeError:
print >>sys.stderr, "Invalid command: " + cmd
sys.exit(1)
except TypeError, e:
print >>sys.stderr, "Syntax Error: " + e.message
sys.exit(1)
sys.exit(0)