/tools/mantisctl/mantisctl.py |
---|
File deleted |
Property changes: |
Deleted: svn:mergeinfo |
## -0,0 +0,0 ## |
Index: mantis.py |
=================================================================== |
--- mantis.py (nonexistent) |
+++ mantis.py (revision 12492) |
@@ -0,0 +1,331 @@ |
+#!/usr/bin/env python |
+"""This script allows command line bug report submission to a Mantis |
+bug tracking system (http://www.mantisbt.org/).""" |
+### |
+# Copyright (c) 2008, Oleksandr Moskalenko |
+# All rights reserved. |
+# |
+# This program is free software: you can redistribute it and/or modify |
+# it under the terms of the GNU General Public License as published by |
+# the Free Software Foundation, either version 3 of the License, or |
+# (at your option) any later version. |
+# |
+# This program is distributed in the hope that it will be useful, |
+# but WITHOUT ANY WARRANTY; without even the implied warranty of |
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
+# GNU General Public License for more details. |
+# |
+# You should have received a copy of the GNU General Public License |
+# along with this program. If not, see <http://www.gnu.org/licenses/>. |
+### |
+ |
+import re, sys |
+import mechanize |
+import logging |
+from mechanize import Browser |
+from mechanize import CookieJar |
+from mechanize import LWPCookieJar |
+ |
+############################################################################## |
+# CONFIGURATION |
+############################################################################## |
+# USER CONFIGURATION - edit for your site. |
+#username = "xxxxxxxx" |
+#password = "xxxxxxxx" |
+baseurl = "http://bugs.scribus.net/main_page.php" |
+title = "Mantis Issue Tracker for Scribus" |
+filename = "mantisctl.cookies" |
+handlers = { '' : 0, 'ale' : 20, 'alexandre' : 362, 'avox' : 569, 'cbradney' : 2, |
+ 'christoph_s' : 387, 'deejay1' : 12, 'fschmid' : 3, 'h_a_j_s' : 525, |
+ 'Herm' : 1552, 'jghali' : 649, 'jo-hannes' : 114, 'ltning' : 651, |
+ 'malex' : 73, 'mhanski' : 72, 'nimda' : 6, 'pierremarchand' : 1260, |
+ 'plinnell' : 4, 'psmedley' : 1408, 'rajeev_jsv' : 665, 'ringerc' : 212, |
+ 'sjc' : 28, 'subik' : 8, 'Tsoots' : 22 } |
+############################################################################## |
+# SYSTEM CONFIGURATION - you do not usually need to edit this. |
+severities = { 'feature' : '10', 'trivial': '20', 'text' : '30', 'tweak' : '40', 'minor' |
+: '50', 'major' : '60', 'crash' : '70', 'block' : '80'} |
+############################################################################## |
+ |
+class Mantisctl: |
+ """This class handles Mantis Bug Tracking system data retrieval, bug |
+ report submission, and control tasks.""" |
+ def __init__(self): |
+ self.br = Browser() |
+ self.br.set_handle_redirect(True) |
+ self.br.set_handle_refresh(True, honor_time=False) |
+ self.br.set_handle_referer(True) |
+ (self.opts, self.args) = self._getopts() |
+ assert self._checkbts() |
+ |
+ def _checkbts(self): |
+ """ Checks if the URL for the front page could be opened.""" |
+ try: |
+ self.br.open(self.baseurl) |
+ if self.br.title() == self.title: |
+ return True |
+ else: |
+ print "Main page does not correspond to the configuration." |
+ sys.exit(1) |
+ except: |
+ print "Cannot open the chosen Mantis Bug Tracker main page." |
+ sys.exit(1) |
+ |
+ def _usage(self): |
+ print 50*"#" |
+ print """\n |
+Usage: mantisctl.py [Options], version = mantisctl.py 0.1 |
+ |
+Options: |
+ --version show program's version number and exit |
+ -h, --help show this help message and exit |
+ -T, --test Test the script |
+ -L, --list List the Mantis options |
+ -r, --report Report a new bug |
+ -u USERNAME, --username=USERNAME |
+ User name [optional if you set it in the script |
+ itself]. [default: None] |
+ -w PASSWORD, --password=PASSWORD |
+ User password [optional if you set it in the script |
+ itself]. [default: None] |
+ -a ASSIGNTO, --assignto=ASSIGNTO |
+ Assign to [optional] |
+ -c CATEGORY, --category=CATEGORY |
+ Bug category <mandatory> |
+ -y SEVERITY, --severity=SEVERITY |
+ Bug severity <mandatory> |
+ -s SUMMARY, --summary=SUMMARY |
+ Bug summary <mandatory> |
+ -d DESCRIPTION, --desc=DESCRIPTION |
+ Bug description [optional] |
+ -p PVERSION, --product=PVERSION |
+ Product version <mandatory> |
+ -t TVERSION, --target=TVERSION |
+ Target version [optional] |
+ """ |
+ sys.exit(1) |
+ |
+ def _getopts(self): |
+ from optparse import OptionParser |
+ """This procedure parses options and arguments passed to the program and |
+ stores them in a dictionary (opts) and a list (args)""" |
+ try: |
+ self.title = title |
+ except: |
+ sys.exit("You must set the title of the base Mantis BTS page in the configuration section of this script.") |
+ try: |
+ self.baseurl = baseurl |
+ except: |
+ sys.exit("You must set base URL for Mantis BTS in the configuration section of this script.") |
+ try: |
+ self.username = username |
+ except: |
+ self.username = "None" |
+ try: |
+ self.password = password |
+ except: |
+ self.password = "None" |
+ usage = "%prog [Options], version = %prog 0.1" |
+ op = OptionParser(usage=usage, version='%prog 0.1') |
+ op.add_option("-T", "--test", action="store_true", dest="test", default=False, help="Test the script") |
+ op.add_option("-L", "--list", action="store_true", dest="list", default=False, help="List the Mantis options") |
+ op.add_option("-r", "--report", action="store_true", dest="report", default=False, help="Report a new bug") |
+ op.add_option("-u", "--username", dest="username", default=self.username, help="User name [optional if you set it in the script itself]. [default: %default]") |
+ op.add_option("-w", "--password", dest="password", default=self.password, help="User password [optional if you set it in the script itself]. [default: %default]") |
+ op.add_option("-a", "--assignto", dest="assignto", help="Assign to [optional]") |
+ op.add_option("-c", "--category", dest="category", help="Bug category <mandatory>") |
+ op.add_option("-y", "--severity", dest="severity", help="Bug severity <mandatory>") |
+ op.add_option("-s", "--summary", dest="summary", help="Bug summary <mandatory>") |
+ op.add_option("-d", "--desc", dest="description", help="Bug description [optional]") |
+ op.add_option("-p", "--product", dest="pversion", help="Product version <mandatory>") |
+ op.add_option("-t", "--target", dest="tversion", help="Target version [optional]") |
+ try: |
+ (opts, args) = op.parse_args() |
+ except: |
+ self._usage() |
+ return (opts, args) |
+ |
+ def _printcookies(self): |
+ for i in self.cj: |
+ print i |
+ |
+ def _setupcookies(self): |
+ policy = mechanize.DefaultCookiePolicy(rfc2965=True) |
+ cj = LWPCookieJar(policy=policy) |
+ self.br.set_cookiejar(cj) |
+ self.cj = cj |
+ |
+ def _savecookies(self, filename): |
+ self.cj.save(filename, ignore_discard = True, ignore_expires = True) |
+ |
+ def _loadcookies(self, filename): |
+ self.cj.load(filename, ignore_discard = True, ignore_expires = True) |
+ |
+ def _dologin(self): |
+ self.loginlink = self.br.links(text_regex=re.compile("Login")).next() |
+ self.br.follow_link(self.loginlink) |
+ self.br.select_form(name="login_form") |
+ self.br.form["username"] = self.opts.username |
+ self.br.form["password"] = self.opts.password |
+ self.br.submit() |
+ |
+ def _login(self): |
+ self.filename = filename |
+ try: |
+ self._loadcookies(self.filename) |
+ if not self.cj.as_lwp_str(): |
+ self._dologin() |
+ except IOError: |
+ self._dologin() |
+ self.cj.save(self.filename) |
+ |
+ def _getmantisopts(self): |
+ self.handlers = handlers |
+ self.severities = severities |
+ self.category_control = self.br.form.find_control("category") |
+ self.category_list = [] |
+ for i in self.category_control.items: |
+ self.category_list.append(i.name) |
+ self.severity_control = self.br.form.find_control("severity") |
+ self.severity_list = [] |
+ for i in self.severity_control.items: |
+ self.severity_list.append(i.name) |
+ self.handler_control = self.br.form.find_control("handler_id") |
+ self.handler_list = [] |
+ for i in self.handler_control.items: |
+ self.handler_list.append(int(i.name)) |
+ self.pversion_control = self.br.form.find_control("product_version") |
+ self.pversion_list = [] |
+ for i in self.pversion_control.items: |
+ self.pversion_list.append(i.name) |
+ self.tversion_control = self.br.form.find_control("target_version") |
+ self.tversion_list = [] |
+ for i in self.tversion_control.items: |
+ self.tversion_list.append(i.name) |
+ |
+ def _checkopts(self): |
+ if not self.opts.summary: |
+ sys.exit("You must provide a bug summary!") |
+ if not self.opts.description: |
+ self.opts.description = self.opts.summary |
+ elif len(self.opts.description.strip()) < 1: |
+ self.opts.description = self.opts.summary |
+ for i in self.handler_list: |
+ if i not in self.handlers.values(): |
+ sys.exit("Developer list at the top of this script is not complete.") |
+ if self.opts.assignto and len(self.opts.assignto) > 0: |
+ if self.opts.assignto not in self.handlers.keys(): |
+ print "You must specify a developer to assign bug to from the following list: \n", self.handlers.keys() |
+ sys.exit(1) |
+ else: |
+ self.handler = str(self.handlers[self.opts.assignto]) |
+ else: |
+ self.handler = '0' |
+ if not self.opts.category: |
+ print "You must specify a category from the following list: \n", self.category_list |
+ sys.exit(1) |
+ else: |
+ if self.opts.category in self.category_list: |
+ pass |
+ else: |
+ print "Your category is not in the list: \n", self.category_list |
+ sys.exit(1) |
+ for i in self.severity_list: |
+ if i not in self.severities.values(): |
+ sys.exit("Severity list at the top of this script is not complete.") |
+ if not self.opts.severity: |
+ print "You must specify a severity from the following list: \n", self.severities.keys() |
+ sys.exit(1) |
+ else: |
+ if self.opts.severity in self.severities.keys(): |
+ self.severity = self.severities[self.opts.severity] |
+ else: |
+ print "Your severity is not in the list: \n", self.severities.keys() |
+ sys.exit(1) |
+ if not self.opts.pversion: |
+ print "You must specify a product version from the following list: \n", self.pversion_list |
+ sys.exit(1) |
+ else: |
+ if self.opts.pversion in self.pversion_list: |
+ pass |
+ else: |
+ print "Your product version is not in the list: \n", self.pversion_list |
+ sys.exit(1) |
+ if self.opts.tversion: |
+ if self.opts.tversion in self.tversion_list: |
+ pass |
+ else: |
+ print "Your target version is not in the list: \n", self.tversion_list |
+ sys.exit(1) |
+ |
+ def _setupreportform(self): |
+ self._getmantisopts() |
+ if self.opts.list: |
+ print "Severities: \n", "\t", self.severities.keys(), "\n" |
+ print "Categories: \n", "\t", self.category_list, "\n" |
+ print "Developers: \n", "\t", self.handlers.keys(), "\n" |
+ print "Product Versions: \n", "\t", self.pversion_list, "\n" |
+ sys.exit(0) |
+ self._checkopts() |
+ self.br.form["category"] = [self.opts.category] |
+ self.br.form["severity"] = [self.severity] |
+ self.br.form["handler_id"] = [self.handler] |
+ self.br.form["product_version"] = [self.opts.pversion] |
+ if self.opts.tversion: |
+ self.br.form["target_version"] = [self.opts.tversion] |
+ self.br.form["summary"] = self.opts.summary |
+ self.br.form["description"] = self.opts.description |
+ |
+ def reportbug(self): |
+ reportlink = self.br.links(text_regex=re.compile("Report Issue")).next() |
+ self.br.follow_link(reportlink) |
+ self.br.select_form(name="report_bug_form") |
+ self._setupreportform() |
+ |
+ def doreportbug(self): |
+ self.reportbug() |
+ try: |
+ self.br.submit() |
+ except: |
+ pass |
+ self.br.close() |
+ print "\nBug report submission appears to be successful! The following data have been submitted:\n" |
+ print "\tCategory: \t\t%s" % self.opts.category |
+ print "\tSeverity: \t\t%s" % self.opts.severity |
+ print "\tAssigned To: \t\t%s" % self.opts.assignto |
+ print "\tProduct Version: \t%s" % self.opts.pversion |
+ print "\tTarget Version: \t%s" % self.opts.tversion |
+ print "\tSummary: \t\t%s" % self.opts.summary |
+ print "\tDescription: \t\t%s" % self.opts.description |
+ sys.exit(0) |
+ |
+ def _checkcredentials(self): |
+ if self.opts.username == 'None': |
+ print "\nUsername is not specified either in the script configuration or on the command line." |
+ self._usage() |
+ if self.opts.password == 'None': |
+ print "\nPassword is not specified either in the script or on the command line." |
+ self._usage() |
+ |
+ def dorun(self): |
+ self._checkcredentials() |
+ self._setupcookies() |
+ self._login() |
+ if self.opts.list: |
+ print "Listing the Mantis options...\n" |
+ self.reportbug() |
+ if self.opts.test: |
+ print "Testing the script...", |
+ self.reportbug() |
+ print "everything seems to be fine." |
+ sys.exit(0) |
+ if self.opts.report: |
+ self.doreportbug() |
+ |
+if __name__=='__main__': |
+ if len(sys.argv) == 1: |
+ sys.argv.append("--help") |
+ else: |
+ browser = Mantisctl() |
+ browser.dorun() |
+# vim:set shiftwidth=4 tabstop=4 expandtab textwidth=79: |