[27284] in Source-Commits
scripts commit: Add a script to control Trac via XMLRPC
daemon@ATHENA.MIT.EDU (Jonathan D Reed)
Thu Sep 19 10:52:23 2013
Date: Thu, 19 Sep 2013 10:52:13 -0400
From: Jonathan D Reed <jdreed@MIT.EDU>
Message-Id: <201309191452.r8JEqDCV019715@drugstore.mit.edu>
To: source-commits@MIT.EDU
https://github.com/mit-athena/scripts/commit/f8f0a534218fb4d037060b7ece63abba398a9b94
commit f8f0a534218fb4d037060b7ece63abba398a9b94
Author: Jonathan Reed <jdreed@mit.edu>
Date: Fri Sep 6 14:46:54 2013 -0400
Add a script to control Trac via XMLRPC
A simple XMLRPC client that will allow common operations, such as
marking a ticket as committed, uploaded, etc. Designed to be called
from VCS hooks or daupload and friends
trac-remote.py | 101 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 101 insertions(+), 0 deletions(-)
diff --git a/trac-remote.py b/trac-remote.py
new file mode 100755
index 0000000..9c8c8d9
--- /dev/null
+++ b/trac-remote.py
@@ -0,0 +1,101 @@
+#!/usr/bin/python
+
+import sys, os
+import xmlrpclib
+import logging
+from optparse import OptionParser
+
+LOGGER_NAME="trac-remote"
+DEFAULT_CREDENTIALS=os.getenv('HOME', '~') + "/.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)
+
+
+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)