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: |