#!/usr/bin/python # Author: Brian Murray # Copyright (C) 2009 Canonical, Ltd. # License: GPLv3 # # Given a package name and some criteria query Launchpad for a bug list # then check each bug against the package's bug pattern # # missing the ability to search for no tags from apport.crashdb import get_crashdb from launchpadlib.launchpad import Launchpad, EDGE_SERVICE_ROOT from launchpadlib.credentials import Credentials from launchpadlib.errors import HTTPError import apport import optparse import sys import os import tempfile def connect(use_edge=True): cachedir = os.path.expanduser('~/.launchpadlib/cache') if not os.path.exists(cachedir): os.makedirs(cachedir,0700) if use_edge: root = EDGE_SERVICE_ROOT credfile = os.path.expanduser('~/.launchpadlib/credentials') else: root = 'https://api.launchpad.net/beta/' credfile = os.path.expanduser('~/.launchpadlib/credentials-lpnet') try: credentials = Credentials() credentials.load(open(credfile)) launchpad = Launchpad(credentials, root, cachedir) except: launchpad = Launchpad.get_token_and_login(sys.argv[0], root, cachedir) credfd = tempfile.NamedTemporaryFile(dir=os.path.dirname(credfile)) launchpad.credentials.save(credfd) os.link(credfd.name, credfile) credfd.close() return launchpad lp = connect() parser = optparse.OptionParser() parser.add_option("-p", "--package", help="Filter on package", metavar="PACKAGE") parser.add_option("-s", "--status", help="Filter on status", metavar="STATUS") parser.add_option("-t", "--tags", help="Filter on tag(s)", metavar="TAGS") parser.add_option("-d", "--dupes", help="Include duplicates in search", action="store_true") parser.add_option("-q", "--quiet", help="Only print bug numbers", action="store_true") parser.add_option("-k", "--keywords", help="Search using string", metavar="keywords") (opt, args) = parser.parse_args() status_list = [] tags_list = [] ubuntu = lp.distributions['ubuntu'] valid_status = ['New', 'Incomplete', 'Invalid', "Won't Fix", 'Confirmed', 'Triaged', 'In Progress', 'Fix Committed', 'Fix Released', 'Unknown'] if not opt.status: status_list = ['New', 'Incomplete', 'Confirmed', 'Triaged', 'In Progress', 'Fix Committed' ] elif opt.status: if opt.status not in valid_status: print >> sys.stderr, ("Invalid status '%s'. Aborting") % (opt.status) sys.exit(1) else: status_list.append(opt.status) if opt.package: package = ubuntu.getSourcePackage(name='%s' % opt.package) elif not opt.package: print >> sys.stderr, ("A package is required.") sys.exit(1) if opt.tags: tags_list.append(opt.tags) elif not opt.tags: print >> sys.stderr, ("Tags are required at this point in time. Aborting") sys.exit(1) if opt.dupes: dupes = False elif not opt.dupes: dupes = True if opt.keywords: tasks = package.searchTasks(search_text=opt.keywords,status=status_list,order_by='-datecreated',tags=tags_list,omit_duplicates=dupes) else: tasks = package.searchTasks(status=status_list,order_by='-datecreated',tags=tags_list,omit_duplicates=dupes) for task in tasks: # they should be retraced first if 'need-i386-retrace' in task.bug.tags or 'need-amd64-retrace' in task.bug.tags: continue db = get_crashdb(None) try: report = db.download(task.bug.id) except AssertionError, error: print "LP: #%s: %s" % ( task.bug.id, error ) continue except Exception, error: print "LP: #%s: %s" % ( task.bug.id, error ) continue try: match = report.search_bug_patterns('.') except AssertionError, error: print "%s" % error continue if match and not opt.quiet: print 'LP: #%s: Matched bug pattern: %s' % ( task.bug.id, match ) if match and opt.quiet: print '%s' % ( task.bug.id )