def scan()

in src/plugins/scanners/bugzilla.py [0:0]


def scan(KibbleBit, source):
    path = source['sourceID']
    url = source['sourceURL']
    
    source['steps']['issues'] = {
        'time': time.time(),
        'status': 'Parsing BugZilla changes...',
        'running': True,
        'good': True
    }
    KibbleBit.updateSource(source)
    
    bz = re.match(r"(https?://\S+?)(/jsonrpc\.cgi)?[\s:?]+(.+)", url)
    if bz:
        if source['creds'] and 'username' in source['creds'] and source['creds']['username'] and len(source['creds']['username']) > 0:
            creds = "%s:%s" % (source['creds']['username'], source['creds']['password'])
        badOnes = 0
        pendingTickets = []
        openTickets = []

        # Get base URL, list and domain to parse
        dom = bz.group(1)
        dom = re.sub(r"/+$", "", dom)
        u = "%s/jsonrpc.cgi" % dom
        instance = bz.group(3)
        lastTicket = 0
        
        params = {
            'product':  [instance],
            'status': ["RESOLVED", "CLOSED", "NEW","UNCOMFIRMED","ASSIGNED","REOPENED","VERIFIED"], 
            'include_fields': ['id', 'creation_time', 'status', 'summary', 'creator'],
            'limit': 10000,
            'offset': 1
            }
        # If * is requested, just omit the product name
        if instance == '*':
            params = {
                'status': ["RESOLVED", "CLOSED", "NEW","UNCOMFIRMED","ASSIGNED","REOPENED","VERIFIED"], 
                'include_fields': ['id', 'creation_time', 'status', 'summary', 'creator'],
                'limit': 10000,
                'offset': 1
                }
        
        ticketsURL = "%s?method=Bug.search&params=[%s]" % (u, urllib.parse.quote(json.dumps(params)))

        while True:
            try:
                js = plugins.utils.jsonapi.get(ticketsURL, auth = creds)
            except:
                KibbleBit.pprint("Couldn't fetch more tickets, bailing")
                break
            
            if len(js['result']['bugs']) > 0:
                KibbleBit.pprint("%s: Found %u tickets..." % (source['sourceURL'], ((params.get('offset', 1)-1) + len(js['result']['bugs']))))
                for bug in js['result']['bugs']:
                    pendingTickets.append(bug)
                    if not bug['status'] in ['RESOLVED', 'CLOSED']:
                        openTickets.append(bug['id'])
                params['offset'] += 10000
                ticketsURL = "%s?method=Bug.search&params=[%s]" % (u, urllib.parse.quote(json.dumps(params)))
            else:
                KibbleBit.pprint("No more tickets left to scan")
                break
            
        KibbleBit.pprint("Found %u open tickets, %u closed." % (len(openTickets), len(pendingTickets) - len(openTickets)))

        badOnes = 0
        block = Lock()
        threads = []
        for i in range(0,4):
            t = bzThread(KibbleBit, source, block, pendingTickets, openTickets, u, dom)
            threads.append(t)
            t.start()
        
        for t in threads:
            t.join()
        

        source['steps']['issues'] = {
            'time': time.time(),
            'status': 'Issue tracker (BugZilla) successfully scanned at ' + time.strftime("%Y/%m/%d %H:%M:%S", time.gmtime(time.time())),
            'running': False,
            'good': True
        }
        KibbleBit.updateSource(source)