#!/usr/bin/python # -*- coding: utf-8 -*- # # Copyright (C) 2007 Canonical Ltd. # # Modified by Iain Lane , taking some code written by # Daniel Hahler # # python-launchpadlib support was added by Markus Korn . # # ################################################################## # # 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; version 3. # # 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. # # See file /usr/share/common-licenses/GPL-3 for more details. # # ################################################################## import optparse import os import sys import email from ubuntutools.config import UDTConfig from ubuntutools.lp.libsupport import (get_launchpad, translate_api_web, translate_web_api) def read_config(): instructions_file = open("instructions") instructions = email.message_from_file(instructions_file) instructions_file.close() instr = dict() for field in "subject", "assignee", "subscribers", "tags", "text", \ "buglist-url", "status": instr[field] = instructions.get(field) return instr def read_list(): pack_list = set() listfile = open("list") for line in listfile.readlines(): if line.strip()!="": pack_list.add(line.strip("\n")) listfile.close() return pack_list def check_configfiles(): result = True bin_path = os.path.dirname(os.path.abspath(__file__)) if bin_path == "/usr/bin": example_dir = "/usr/share/doc/ubuntu-dev-tools/examples" else: example_dir = "%s/examples" % bin_path if not os.path.exists("instructions"): os.system("cp %s/massfile.instructions instructions" % example_dir) print >> sys.stderr, \ "No 'instructions' file found. Copied template from %s." % \ example_dir result = False if not os.path.exists("list"): os.system("cp %s/massfile.list list" % example_dir) print >> sys.stderr, \ "No 'list' file found. Copied template from %s." % example_dir result = False return result def file_bug(config, launchpad): try: summary = config["subject"].replace("$pack", config["sourcepackage"]) description = config["text"].replace("$pack", config["sourcepackage"]) product_url = "%subuntu/+source/%s" % \ (launchpad._root_uri, config["sourcepackage"]) tags = filter(None, map(lambda t: t.strip("\n").strip(), config["tags"].split(","))) bug = launchpad.bugs.createBug(description=description, title=summary, target=product_url, tags=tags) print "Successfully filed bug %i: %s" % \ (bug.id, translate_api_web(bug.self_link)) subscribers = filter(None, map(lambda t: t.strip("\n").strip(), config["subscribers"].split(","))) for sub in subscribers: subscribe_url = "%s~%s" % (launchpad._root_uri, sub) bug.subscribe(person=subscribe_url) #newly created bugreports have one task task = bug.bug_tasks[0] if config["status"]: status = config["status"].capitalize() else: status = "Confirmed" task.status = status assignee = config["assignee"] if assignee: assignee_url = "%s~%s" % (launchpad._root_uri, assignee) task.assignee = assignee_url task.lp_save() except: print >> sys.stderr, "Bug for '%s' was not filed." % \ config["sourcepackage"] def read_buglist(url, launchpad): if not url: return set() if len(url.split("?", 1)) == 2: # search options not supported, because there is no mapping # web ui options <-> API options print >> sys.stderr, "Options in url are not supported, url: %s" % url sys.exit(1) packages = set() api_url = translate_web_api(url, launchpad) # workaround LP #303414 # if this is fixed it should simply be: buglist = launchpad.load(api_url) api_url = api_url.split("?", 1)[0] project = launchpad.load(api_url) buglist = project.searchTasks() for bug in buglist: packages.add(bug.bug_target_name) return packages def main(): p = optparse.OptionParser(description= 'Files bugs against multiple packages in Ubuntu. ' 'Reads the bug from "instructions" and files them against ' 'packages listed in "list". ' "If these files aren't preset they are created.") p.add_option('-l', '--lpinstance', metavar='INSTANCE', dest='lpinstance', default=None, help='Launchpad instance to connect to (default: production)') p.add_option('--no-conf', dest='no_conf', default=False, action='store_true', help="Don't read config files or environment variables") options, args = p.parse_args() udtconfig = UDTConfig(options.no_conf) if options.lpinstance is None: options.lpinstance = udtconfig.get_value('LPINSTANCE') if not check_configfiles(): sys.exit(1) launchpad = get_launchpad('ubuntu-dev-tools', server=options.lpinstance) config = read_config() pack_list = read_list() buglist = read_buglist(config["buglist-url"], launchpad) for pack in pack_list: if pack not in buglist: config["sourcepackage"] = pack file_bug(config, launchpad) if __name__ == '__main__': main()