def scan()

in src/plugins/scanners/github-issues.py [0:0]


def scan(KibbleBit, source, firstAttempt = True):
    auth=None
    people = {}
    if 'creds' in source:
        KibbleBit.pprint("Using auth for repo %s" % source['sourceURL'])
        creds = source['creds']
        if creds and 'username' in creds:
            auth = (creds['username'], creds['password'])
    TL = plugins.utils.github.get_tokens_left(auth=auth)
    KibbleBit.pprint("Scanning for GitHub issues (%u tokens left on GitHub)" % TL)
    # Have we scanned before? If so, only do a 3 month scan here.
    doneBefore = False
    if source.get('steps') and source['steps'].get('issues'):
        doneBefore = True
    source['steps']['issues'] = {
            'time': time.time(),
            'status': 'Issue scan started at ' + time.strftime("%a, %d %b %Y %H:%M:%S +0000", time.gmtime()),
            'running': True,
            'good': True,
        }
    KibbleBit.updateSource(source)
    try:
        if doneBefore:
            since = time.strftime("%Y-%m-%dT%H:%M:%SZ", time.gmtime(time.time() - (3*30*86400)))
            KibbleBit.pprint("Fetching changes since %s" % since)
            issues = plugins.utils.github.get_all(source, plugins.utils.github.issues,
                                   params={'filter': 'all', 'state':'all', 'since': since},
                                   auth=auth)
        else:
            issues = plugins.utils.github.get_all(source, plugins.utils.github.issues,
                                   params={'filter': 'all', 'state':'all'},
                                   auth=auth)
        KibbleBit.pprint("Fetched %s issues for %s" %(str(len(issues)), source['sourceURL']))

        for issue in issues:

            if not issue['user']['login'] in people:
                person = make_person(source, issue, plugins.utils.github.user(issue['user']['url'],
                                                          auth=auth))
                people[issue['user']['login']] = person
                update_person(KibbleBit, person)

            if 'closed_by' in issue and not issue['closed_by']['login'] in people:
                closer = make_person(source, issue, plugins.utils.github.user(issue['closed_by']['url'],
                                                          auth=auth))
                people[issue['closed_by']['login']] = closer
                update_person(KibbleBit, closer)

            doc = make_issue(source, issue, people)
            dhash = doc['id']
            stored_change = None
            if KibbleBit.exists('issue', dhash):
                es_doc = KibbleBit.get('issue', dhash)
                if not status_changed(es_doc, doc):
                    #KibbleBit.pprint("change %s seen already and status unchanged. Skipping." % issue['id'])
                    continue

            update_issue(KibbleBit, doc)
        
        source['steps']['issues'] = {
            'time': time.time(),
            'status': 'Issue scan completed at ' + time.strftime("%a, %d %b %Y %H:%M:%S +0000", time.gmtime()),
            'running': False,
            'good': True,
        }
        KibbleBit.updateSource(source)

    except requests.HTTPError as e:
        # If we errored out because of rate limiting, retry later, otherwise bail
        if firstAttempt:
            sleeps = 0
            if plugins.utils.github.get_tokens_left(auth=auth) < 10:
                KibbleBit.pprint("Hit rate limits, trying to sleep it off!")
                while plugins.utils.github.get_tokens_left(auth=auth) < 10:
                    sleeps += 1
                    if sleeps > 24:
                        KibbleBit.pprint("Slept for too long without finding a reset rate limit, giving up!")
                        break
                    time.sleep(300) # Sleep 5 min, then check again..
                # If we have tokens, try one more time...
                if plugins.utils.github.get_tokens_left(auth=auth) > 10:
                    scan(KibbleBit, source, False) # If this one fails, bail completely
                    return
            
            
        KibbleBit.pprint("HTTP Error, rate limit exceeded?")
        source['steps']['issues'] = {
            'time': time.time(),
            'status': 'Issue scan failed at ' + time.strftime("%a, %d %b %Y %H:%M:%S +0000", time.gmtime()) + ": " + e.response.text,
            'running': False,
            'good': False,
        }
        KibbleBit.updateSource(source)