#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
# PR Tracker Bot tracks pull requests sent to a mailing list (via its
# public-inbox v2 git repository), and notifies senders when their pull
# requests get merged.
#
# It runs from a cronjob, but can be also run from post-update hooks with 
# extra wrappers. For more details, consult:
#
# https://korg.wiki.kernel.org/userdoc/prtracker
#

__author__ = 'Konstantin Ryabitsev <konstantin@linuxfoundation.org>'

import os
import sys
import argparse
import email
import email.message
import email.utils
import smtplib
import time
import subprocess
import sqlite3
import logging
import pathlib
import re

from fcntl import lockf, LOCK_EX, LOCK_NB
from string import Template

DB_VERSION = 2

# Case doesn't matter
PULL_SUBJECT_RE = [
    re.compile(r'^\S*:?\s*\[GIT', re.IGNORECASE),
    re.compile(r'^\S*:?\s*\[PULL', re.IGNORECASE),
    re.compile(r'^\S*:?\s*\[PLEASE PULL', re.IGNORECASE),
]

# I like these
PULL_BODY_WITH_COMMIT_ID_RE = [
    re.compile(r'^\s*for you to fetch changes up to ([0-9a-f]{5,40}):', re.MULTILINE | re.IGNORECASE),
]

# I don't like these
PULL_BODY_REMOTE_REF_RE = [
    re.compile(r'^\s*([\w+-]+(?:://|@)[\w/.@:~-]+)[\s\\]+([\w/._-]+)\s*$', re.MULTILINE | re.IGNORECASE),
    re.compile(r'^\s*([\w+-]+(?:://|@)[\w/.@~-]+)\s*$', re.MULTILINE | re.IGNORECASE),
]

logger = logging.getLogger('prtracker')


def db_migrate_1_to_2(projpath):
    pirepo, maxshard = get_pirepo_dir(projpath, None)
    old_dbpath = os.path.join(projpath, '{0}.git'.format(maxshard), 'prs.db')
    dbconn_old = sqlite3.connect(old_dbpath, sqlite3.PARSE_DECLTYPES | sqlite3.PARSE_COLNAMES)
    c_old = dbconn_old.cursor()
    # Get all values from old db
    pr_rows = c_old.execute('SELECT * FROM prs').fetchall()
    h_rows = c_old.execute('SELECT * FROM heads').fetchall()
    dbconn_old.close()

    dbpath = os.path.join(projpath, 'prtracker.db')
    dbconn = sqlite3.connect(dbpath, sqlite3.PARSE_DECLTYPES | sqlite3.PARSE_COLNAMES)
    c = dbconn.cursor()
    db_init_pr_sqlite_db(c)

    for row in pr_rows:
        c.execute('INSERT INTO prs VALUES(?,?,?,?,?,?)', [maxshard]+list(row))

    for row in h_rows:
        c.execute('INSERT INTO heads VALUES(?,?,?)', [maxshard] + list(row))

    dbconn.commit()
    dbconn.close()


def db_save_meta(c):
    c.execute('DELETE FROM meta')
    c.execute('''INSERT INTO meta VALUES(?)''', (DB_VERSION,))


def db_save_repo_heads(c, heads, shard=None):
    if shard is None:
        c.execute('DELETE FROM heads')
        for refname, commit_id in heads:
            c.execute('''INSERT INTO heads VALUES(?,?)''', (refname, commit_id))
        return

    c.execute('DELETE FROM heads WHERE pi_shard=?', (shard,))
    for refname, commit_id in heads:
        c.execute('''INSERT INTO heads VALUES(?,?,?)''', (shard, refname, commit_id))


def db_get_repo_heads(c, shard=None):
    if shard is None:
        return c.execute('SELECT refname, commit_id FROM heads').fetchall()
    return c.execute('SELECT refname, commit_id FROM heads WHERE pi_shard=?',
                     (shard,)).fetchall()


def db_init_common_sqlite_db(c):
    c.execute('''
        CREATE TABLE meta (
            version INTEGER
        )''')
    db_save_meta(c)


def db_init_pr_sqlite_db(c):
    logger.info('Initializing new sqlite3 db with metadata version %s', DB_VERSION)
    db_init_common_sqlite_db(c)
    c.execute('''
        CREATE TABLE heads (
            pi_shard INTEGER,
            refname TEXT,
            commit_id TEXT
        )''')
    c.execute('''
        CREATE TABLE prs (
            pi_shard INTEGER,
            msg_commit_id TEXT UNIQUE,
            msg_id TEXT UNIQUE,
            subject TEXT,
            pr_commit_id TEXT,
            received DATE
        )''')


def db_init_thanks_sqlite_db(c):
    logger.info('Initializing new sqlite3 db with metadata version %s', DB_VERSION)
    db_init_common_sqlite_db(c)
    c.execute('''
        CREATE TABLE heads (
            refname TEXT,
            commit_id TEXT
        )''')
    c.execute('''
        CREATE TABLE thanks (
            pr_commit_id TEXT, --- pi.prs.pr_commit_id
            refname TEXT,
            sent_msgid TEXT,
            sent DATE
        )''')


def git_get_command_lines(gitdir, args):
    out = git_run_command(gitdir, args)
    lines = list()
    if out:
        for line in out.split('\n'):
            if line == '':
                continue
            lines.append(line)

    return lines


def git_run_command(gitdir, args, logstderr=False):
    fullargs = ['git', '--no-pager']
    if gitdir:
        fullargs += ['--git-dir', gitdir]
    fullargs += args

    logger.debug('Running %s' % ' '.join(fullargs))

    (output, error) = subprocess.Popen(fullargs, stdout=subprocess.PIPE, stderr=subprocess.PIPE).communicate()
    output = output.strip().decode('utf-8', errors='replace')

    if logstderr and len(error.strip()):
        logger.debug('Stderr: %s', error.decode('utf-8', errors='replace'))

    return output


def git_get_repo_heads(gitdir):
    refs = list()
    lines = git_get_command_lines(gitdir, ['show-ref', '--heads'])
    if lines is not None:
        for line in lines:
            (commit_id, refname) = line.split()
            refs.append((refname, commit_id))
    return refs


def git_get_message_from_pi(projpath, shard, commit_id):
    pirepo = os.path.join(projpath, '{0}.git'.format(shard))
    full_email = git_run_command(pirepo, ['show', '%s:m' % commit_id])
    if not len(full_email):
        return None

    msg = email.message_from_string(full_email)
    return msg


def git_get_commit_id_from_repo_ref(repo, ref):
    # We only handle git and http/s URLs
    if not (repo.find('git://') == 0 or repo.find('http://') == 0 or repo.find('https://') == 0):
        logger.debug('%s uses unsupported protocol', repo)
        return None

    logger.debug('getting commit-id from: %s %s', repo, ref)
    # Drop the leading "refs/", if any
    ref = re.sub(r'^refs/', '', ref)
    # Is it a full ref name or a shortname?
    if ref.find('heads/') < 0 and ref.find('tags/') < 0:
        # Try grabbing it as a head first
        lines = git_get_command_lines(None, ['ls-remote', repo, 'refs/heads/%s' % ref])
        if not lines:
            # try it as a tag, then
            lines = git_get_command_lines(None, ['ls-remote', repo, 'refs/tags/%s^{}' % ref])

    elif ref.find('tags/') == 0:
        lines = git_get_command_lines(None, ['ls-remote', repo, 'refs/%s^{}' % ref])

    else:
        # Grab it as a head and hope for the best
        lines = git_get_command_lines(None, ['ls-remote', repo, 'refs/%s' % ref])

    if not lines:
        # Oh well, we tried
        logger.debug('did not find commit-id, ignoring pull request')
        return None

    commit_id = lines[0].split()[0]
    logger.debug('success, commit-id: %s', commit_id)
    return commit_id


def get_remote_ref_from_body(body):
    repo = None
    ref = None
    for reporef_re in PULL_BODY_REMOTE_REF_RE:
        matches = reporef_re.search(body)
        if matches:
            chunks = matches.groups()
            if len(chunks) > 1:
                (repo, ref) = chunks
            else:
                repo = chunks[0]
                ref = 'refs/heads/master'
            break
    return repo, ref


def record_pr_data(shard, msg_commit_id, msg, c):
    body = get_plain_part(msg)
    if body is None:
        return False

    pr_commit_id = None
    for cid_re in PULL_BODY_WITH_COMMIT_ID_RE:
        matches = cid_re.search(body)
        if matches:
            pr_commit_id = matches.groups()[0]
            break

    if pr_commit_id is None:
        repo, ref = get_remote_ref_from_body(body)
        if repo is not None:
            pr_commit_id = git_get_commit_id_from_repo_ref(repo, ref)

    if pr_commit_id is None:
        return False

    logger.debug('pr_commit_id=%s', pr_commit_id)
    msg_id = msg['Message-Id']
    received = time.strftime('%Y-%m-%dT%H:%M:%S%z')

    rechdr = msg.get('Received')
    if rechdr:
        received = time.strftime('%Y-%m-%dT%H:%M:%S%z',
                                 email.utils.parsedate(rechdr.split(';')[-1].strip()))
    else:
        # Do we have a date?
        datehdr = msg.get('Date')
        if datehdr:
            received = time.strftime('%Y-%m-%dT%H:%M:%S%z', email.utils.parsedate(datehdr))

    logger.debug('received=%s', received)
    subject = msg['Subject'].replace('\n', ' ')
    logger.debug('Found a new PR: %s', subject)
    logger.debug('     commit_id: %s', pr_commit_id)
    try:
        c.execute('INSERT INTO prs VALUES(?, ?, ?, ?, ?, ?)',
                  (shard, msg_commit_id, msg_id, subject, pr_commit_id, received))
        return True
    except sqlite3.IntegrityError:
        logger.debug('Got integrity-error for %s', msg_id)

    return False


def git_get_new_revs(gitdir, db_heads, git_heads):
    newrevs = dict()
    for db_refrow in list(db_heads):
        if db_refrow in git_heads:
            logger.debug('No changes in %s', db_refrow[0])
            continue

        (refname, db_commit_id) = db_refrow
        # Find a matching one in git
        git_commit_id = None
        for git_refrow in git_heads:
            if git_refrow[0] == refname:
                git_commit_id = git_refrow[1]
                break
        if git_commit_id is None:
            # Looks like this head is gone from git
            db_heads.remove(db_refrow)
            continue

        if db_commit_id == git_commit_id:
            # No changes in this head
            continue

        if len(db_commit_id):
            rev_range = '%s..%s' % (db_commit_id, git_commit_id)
        else:
            rev_range = git_commit_id

        lines = git_get_command_lines(gitdir, ['rev-list', '--pretty=oneline',
                                               '--reverse', rev_range, refname])
        if not lines:
            continue

        newrevs[refname] = list()

        for line in lines:
            (commit_id, logmsg) = line.split(' ', 1)
            logger.debug('commit_id=%s, subject=%s', commit_id, logmsg)
            newrevs[refname].append((commit_id, logmsg))

    return newrevs


def git_get_merge_id(repo, commit_id):
    # get merge commit id
    args = ['rev-list', '%s..' % commit_id, '--ancestry-path']
    lines = git_get_command_lines(repo, args)
    return lines[-1]


def get_pirepo_dir(projpath, topdir):
    if topdir:
        projpath = os.path.join(topdir, projpath)

    projpath = projpath.rstrip('/')

    # drop the #.git if we find it
    if projpath[-4:] == '.git':
        projpath = os.path.dirname(projpath)

    subs = os.listdir(projpath)
    at = 0
    while True:
        if '{0}.git'.format(at+1) not in subs:
            return projpath, at
        at += 1


def parse_pull_requests(pirepo, topdir, dryrun):
    projpath, maxshard = get_pirepo_dir(pirepo, topdir)
    pirepo = os.path.join(projpath, '{0}.git'.format(maxshard))
    logger.debug('pirepo=%s', pirepo)
    git_heads = git_get_repo_heads(pirepo)
    if not git_heads:
        logger.critical('Could not get the latest ref in %s', pirepo)
        sys.exit(1)

    try:
        lockfh = open(os.path.join(projpath, 'prtracker.lock'), 'w')
        lockf(lockfh, LOCK_EX | LOCK_NB)
    except IOError:
        logger.debug('Could not obtain an exclusive lock, assuming another process is running.')
        return

    # Do we have a prtracker.db there yet?
    dbpath = os.path.join(projpath, 'prtracker.db')
    db_exists = os.path.isfile(dbpath)
    if not db_exists:
        # Do we have a prs.db in the latest shard (metadata 1.0)
        old_dbpath = os.path.join(pirepo, 'prs.db')
        if os.path.exists(old_dbpath):
            db_migrate_1_to_2(projpath)
            db_exists = True

    dbconn = sqlite3.connect(dbpath, sqlite3.PARSE_DECLTYPES | sqlite3.PARSE_COLNAMES)
    c = dbconn.cursor()

    if not db_exists:
        # initialize it once we get the latest ref
        db_init_pr_sqlite_db(c)
        db_save_repo_heads(c, git_heads, maxshard)
        # Exit early
        dbconn.commit()
        return

    db_heads = db_get_repo_heads(c, maxshard)
    if not len(db_heads) and maxshard == 0:
        logger.info('Not sure what happened, but I did not find any db heads and maxshard=0')
        return

    if not len(db_heads):
        # This should only happen when we have rolled over
        # between shards, so we need to first finish the
        # old shard and then prep next run from starting from
        # the new shard
        # Prep the next run with the new shard. We use empty
        # space so that rev-list formulates a ..foo rev-list
        # that returns the revs from the beginning of history
        logger.info('Preparing for shard roll-over to %s.git', maxshard)
        db_save_repo_heads(c, (('refs/heads/master', ''),), maxshard)
        if not dryrun:
            dbconn.commit()
        # Now let's finish with the previous shard
        maxshard -= 1
        # Refresh these
        pirepo = os.path.join(projpath, '{0}.git'.format(maxshard))
        logger.info('Finishing previous shard %s', pirepo)
        db_heads = db_get_repo_heads(c, maxshard)
        git_heads = git_get_repo_heads(pirepo)

    newrevs = git_get_new_revs(pirepo, db_heads, git_heads)
    if not newrevs:
        logger.info('No new revs since last run.')
        return

    # We are only interested in refs/heads/master for public-inbox
    msgrevs = newrevs['refs/heads/master']
    logger.info('Found %s new messages since last run', len(msgrevs))
    new_prs = 0
    for commit_id, subject in msgrevs:
        for subject_re in PULL_SUBJECT_RE:
            if subject_re.match(subject):
                logger.debug('potential match: "%s"', subject)
                msg = git_get_message_from_pi(projpath, maxshard, commit_id)
                if msg is not None and record_pr_data(maxshard, commit_id, msg, c):
                    new_prs += 1
                    logger.info('Started tracking: %s', subject)

    if not new_prs:
        logger.info('No new PRs found.')

    db_save_repo_heads(c, git_heads, maxshard)

    if not dryrun:
        dbconn.commit()


def get_config_from_cfgfile(repo, pitopdir, cmdconfig, cfgfile=None):
    from configparser import ConfigParser
    config = dict()
    if cmdconfig:
        for entry in cmdconfig:
            key, value = entry.split('=', 1)
            config[key] = value
    if not cfgfile:
        cfgfile = os.path.join(repo, 'thanks.conf')
    if not os.path.exists(cfgfile):
        logger.critical('Could not find cfgfile %s', cfgfile)
        sys.exit(1)
    cfg = ConfigParser()
    cfg.read(cfgfile)
    for key, value in cfg.items('main'):
        if key not in config:
            config[key] = value

    globpatts = [x.strip() for x in config.get('pirepos', '*').split('\n')]

    # Find all prtracker.db files in pitopdir
    tp = pathlib.Path(pitopdir)
    pirepos = set()
    for subp in tp.glob('**/prtracker.db'):
        for globpatt in globpatts:
            if subp.match(globpatt):
                pirepos.add(subp.parent.resolve().as_posix())

    return pirepos, config


def get_all_thanked_prs(c, cutoffdays=30):
    rows = c.execute('''
                     SELECT pr_commit_id
                       FROM thanks
                      WHERE sent > datetime('now', ?)
                     ''', ('-%d day' % cutoffdays,)).fetchall()
    sent_prs = set()
    for row in rows:
        sent_prs.update((row[0],))

    return sent_prs


def get_all_prs(projpath, cutoffdays=30):
    dbpath = os.path.join(projpath, 'prtracker.db')
    if not os.path.isfile(dbpath):
        # The DB does not exist, and we don't create it
        # from this location.
        logger.info('No PRs database found, assuming it did not run yet.')
        return list()

    prdbconn = sqlite3.connect(dbpath, sqlite3.PARSE_DECLTYPES | sqlite3.PARSE_COLNAMES)
    prc = prdbconn.cursor()
    rows = prc.execute('''
                       SELECT pi_shard, pr_commit_id, msg_commit_id
                         FROM prs 
                        WHERE received >= datetime('now', ?)
                       ''', ('-%d day' % cutoffdays,)).fetchall()
    return rows


def get_plain_part(msg):
    # walk until we find the first text/plain part
    body = None
    for part in msg.walk():
        if part.get_content_type().find('text/plain') < 0:
            continue
        body = part.get_payload(decode=True)
        if body is None:
            continue

        # We don't have to bother with charsets, because
        # we are looking for content that's guaranteed to be
        # in us-ascii.
        body = body.decode('utf-8', errors='replace')
        # Look for evidence of a git pull request in this body
        (repo, ref) = get_remote_ref_from_body(body)
        if repo is None:
            body = None
            continue
        logger.debug('Found a part with (%s, %s)', repo, ref)
        break

    return body


def get_unprocessed_prs(c, prs, cutoffdays=30):
    sent_prs = get_all_thanked_prs(c, cutoffdays)
    new_prs = list()
    for row in prs:
        if row[1] not in sent_prs:
            new_prs.append(row)
    return new_prs


def to_or_cc_contains(tocc, addrs):
    for addr in addrs.split(','):
        if addr.strip() in tocc:
            return True

    return False


def format_addrs(pairs):
    return ', '.join([email.utils.formataddr(pair) for pair in pairs])


def thank_for_pr(c, repo, refname, commit_id, projpath, pi_shard, msg_commit_id, config, dryrun, nomail):
    # Make sure we haven't thanked for it already
    c.execute('SELECT sent_msgid FROM thanks WHERE pr_commit_id=? AND refname=?',
              (commit_id, refname))
    rows = c.fetchall()
    if rows:
        logger.debug('Already thanked for this PR, skipping')
        return None

    orig = git_get_message_from_pi(projpath, pi_shard, msg_commit_id)
    if orig is None:
        return None

    origbody = get_plain_part(orig)
    if origbody is None:
        return None

    if 'notifinbody' in config:
        # Don't send anything if we find a certain string in the body
        # e.g. 'pr-tracker-no-ack'
        if origbody.find(config['notifinbody']) >= 0:
            logger.debug('Body contains notifinbody string')
            logger.debug('Skipping this Pull Request')
            return None

    if 'onlyifinbody' in config:
        # Only send follow-up if we find a specific string in the body
        # e.g. 'pr-tracker-ack'
        if origbody.find(config['onlyifinbody']) < 0:
            logger.debug('Body does not contain onlyifinbody string')
            logger.debug('Skipping this Pull Request')
            return None

    allfrom = email.utils.getaddresses(orig.get_all('from', []))
    allto = email.utils.getaddresses(orig.get_all('to', []))
    allcc = email.utils.getaddresses(orig.get_all('cc', []))

    targets = [chunk[1] for chunk in allfrom+allto+allcc]

    if 'onlyifto' in config:
        # Don't send anything unless the required email is in to or cc
        if not to_or_cc_contains(targets, config['onlyifto']):
            logger.debug('To or CC do not contain: %s', config['onlyifto'])
            logger.debug('Skipping this Pull Request')
            return None

    if 'notifto' in config:
        # Don't send anything if we find a specific address in to or cc
        if to_or_cc_contains(targets, config['notifto']):
            logger.debug('To or CC contains: %s', config['notifto'])
            logger.debug('Skipping this Pull Request')
            return None

    reqdate = orig.get('Date')
    if not reqdate:
        rechdr = orig.get('Received')
        reqdate = time.strftime('%Y-%m-%d at %H:%M:%S',
                                email.utils.parsedate(rechdr.split(';')[-1].strip()))

    msgvalues = dict()

    merge_id = git_get_merge_id(repo, commit_id)

    msgvalues['refname'] = refname
    msgvalues['shortrefname'] = refname.rsplit('/', 1)[-1]
    msgvalues['commit_id'] = merge_id
    msgvalues['merge_id'] = merge_id
    msgvalues['origsubject'] = orig['Subject']

    remoterepo, remoteref = get_remote_ref_from_body(origbody)
    msgvalues['remoteref'] = '(unable to parse the git remote)'
    if remoterepo is not None:
        msgvalues['remoteref'] = '%s %s' % (remoterepo, remoteref)

    msgvalues['reqdate'] = reqdate
    msgvalues['treename'] = ''
    if 'treename' in config:
        msgvalues['treename'] = config['treename']
    msgvalues['br'] = '\n'
    msgvalues['brbr'] = '\n\n'

    msg = email.message.Message()
    msg['Subject'] = Template(config['msgsubject']).safe_substitute(msgvalues)
    msg['From'] = config['from']
    # Set threading bits
    msg['In-Reply-To'] = orig['Message-Id']
    if orig.get('References', ''):
        msg['References'] = orig['References'] + ' ' + orig['Message-Id']
    else:
        msg['References'] = orig['Message-Id']

    msg['X-PR-Tracked-List-Id'] = orig.get('List-Id', '')
    msg['X-PR-Tracked-Message-Id'] = orig['Message-Id']
    msg['X-PR-Tracked-Remote'] = msgvalues['remoteref']
    msg['X-PR-Tracked-Commit-Id'] = commit_id
    msg['X-PR-Merge-Tree'] = msgvalues['treename']
    msg['X-PR-Merge-Refname'] = refname
    msg['X-PR-Merge-Commit-Id'] = merge_id

    msg['Message-Id'] = email.utils.make_msgid('pr-tracker-bot', domain='kernel.org')
    msg['Date'] = email.utils.formatdate(localtime=True)

    # Set to and cc
    if 'onlyto' in config:
        msg['To'] = config['onlyto']
        # Override targets
        targets = [config['onlyto']]
    else:
        msg['To'] = format_addrs(allfrom)
        msg['Cc'] = format_addrs(allto+allcc)

    if 'alwayscc' in config:
        if msg.get('cc', ''):
            msg['Cc'] = msg.get('cc', '') + ', %s' % config['alwayscc']
        else:
            msg['Cc'] = config['alwayscc']

        if config['alwayscc'] not in targets:
            targets.append(config['alwayscc'])

    if 'alwaysbcc' in config:
        if config['alwaysbcc'] not in targets:
            targets.append(config['alwaysbcc'])

    msg.set_payload(Template(config['msgbody']).safe_substitute(msgvalues))

    logger.debug('Message follows')
    logger.debug(msg.as_string())
    if not nomail:
        logger.info('Mailing thanks for: %s', orig['Subject'])
        smtp = smtplib.SMTP(config['mailhost'])
        smtp.sendmail(msg['From'], targets, msg.as_string())
        smtp.close()
    else:
        logger.info('Would have sent the following:')
        logger.info('------------------------------')
        logger.info(msg.as_string())
        logger.info('------------------------------')

    if not dryrun:
        try:
            c.execute('INSERT INTO thanks VALUES(?, ?, ?, ?)',
                      (commit_id, refname, msg['Message-Id'],
                       time.strftime('%Y-%m-%dT%H:%M:%S%z', time.gmtime())))
        except sqlite3.IntegrityError:
            logger.debug('Got integrity-error for %s/%s', refname, commit_id)

    return msg['Message-Id']


def send_thanks(repo, pitopdir, cfgfile, cmdconfig, nomail, dryrun):
    if dryrun:
        nomail = True

    git_heads = git_get_repo_heads(repo)
    if not git_heads:
        logger.critical('Could not get the latest ref in %s', repo)
        sys.exit(1)

    try:
        with open(os.path.join(repo, '.prtracker.lock'), 'w') as lockfh:
            lockf(lockfh, LOCK_EX | LOCK_NB)
    except IOError:
        logger.debug('Could not obtain an exclusive lock, assuming another process is running.')
        return

    # Do we have a thanks.db there yet?
    dbpath = os.path.join(repo, 'thanks.db')
    db_exists = os.path.isfile(dbpath)
    dbconn = sqlite3.connect(dbpath, sqlite3.PARSE_DECLTYPES | sqlite3.PARSE_COLNAMES)
    c = dbconn.cursor()

    if not db_exists:
        db_init_thanks_sqlite_db(c)
        db_save_repo_heads(c, git_heads)
        # Exit early
        dbconn.commit()
        return

    pirepos, settings = get_config_from_cfgfile(repo, pitopdir, cmdconfig, cfgfile=cfgfile)
    logger.debug('config follows')
    logger.debug(settings)

    tycount = 0
    for pirepo in pirepos:
        projpath, maxshard = get_pirepo_dir(pirepo, None)
        logger.info('Grabbing PR commits from %s', projpath)

        cutoffdays = 30
        try:
            cutoffdays = int(settings['cutoffdays'])
        except (IndexError, ValueError):
            pass

        prs = get_all_prs(projpath, cutoffdays=cutoffdays)
        logger.debug('Found %s PRs in %s', len(prs), projpath)
        un_prs = get_unprocessed_prs(c, prs, cutoffdays=cutoffdays)
        logger.debug('Of them, %s not already thanked for', len(un_prs))
        for pi_shard, pr_commit_id, msg_commit_id in un_prs:
            logger.debug('Checking %s', pr_commit_id)
            # Is this pr_commit_id in the repo?
            lines = git_get_command_lines(repo, ['branch', '--contains', pr_commit_id])
            if len(lines):
                refname = 'refs/heads/%s' % lines[0].split()[-1]
                logger.debug('Found %s in %s', pr_commit_id, refname)
                sent_msgid = thank_for_pr(c, repo, refname, pr_commit_id, projpath, pi_shard,
                                          msg_commit_id, settings, dryrun, nomail)
                if sent_msgid and not dryrun:
                    tycount += 1
                    dbconn.commit()

    if not dryrun:
        db_save_repo_heads(c, git_heads)
        dbconn.commit()

    if tycount:
        logger.info('Sent %s thank-you notes.', tycount)
    else:
        logger.info('No new thank-yous to send.')


if __name__ == '__main__':
    parser = argparse.ArgumentParser()
    parser.add_argument('-p', '--parse-requests', dest='pirepo', default=None,
                        help='Check the Public Inbox ML repository for any new pull requests.')
    parser.add_argument('-m', '--mail-thankyous', dest='tyrepo', default=None,
                        help='Check the repository and thank for any matching pulled PRs.')
    parser.add_argument('-t', '--pirepos-topdir', dest='topdir', default=None,
                        help='Toplevel path where all public-inbox repos are (optional)')
    parser.add_argument('-o', '--override-config', dest='config', nargs='+', default=list(),
                        help='Override config entries in the cfgfile (used with -m)')
    parser.add_argument('-c', '--cfgfile', default=None,
                        help='Config file to use instead of thanks.conf in the repo (used with -m)')
    parser.add_argument('-l', '--logfile', default=None,
                        help='Log file for messages during quiet operation')
    parser.add_argument('-d', '--dry-run', dest='dryrun', action='store_true', default=False,
                        help='Do not mail or store anything, just do a dry run.')
    parser.add_argument('-b', '--debug', dest='debug', action='store_true', default=False,
                        help='Add debug information to the log file, if specified.')
    parser.add_argument('-n', '--no-mail', dest='nomail', action='store_true', default=False,
                        help='Do not mail anything, but store database entries.')
    parser.add_argument('-q', '--quiet', action='store_true', default=False,
                        help='Only output errors to the stdout')
    parser.add_argument('-v', '--verbose', action='store_true', default=False,
                        help='Output extra debugging information')

    cmdargs = parser.parse_args()

    logger.setLevel(logging.DEBUG)

    if cmdargs.logfile:
        ch = logging.FileHandler(cmdargs.logfile)
        formatter = logging.Formatter('[%(asctime)s] %(message)s')
        ch.setFormatter(formatter)

        if cmdargs.debug:
            ch.setLevel(logging.DEBUG)
        else:
            ch.setLevel(logging.INFO)
        logger.addHandler(ch)

    ch = logging.StreamHandler()
    formatter = logging.Formatter('%(message)s')
    ch.setFormatter(formatter)

    if cmdargs.quiet:
        ch.setLevel(logging.CRITICAL)
    elif cmdargs.verbose:
        ch.setLevel(logging.DEBUG)
    else:
        ch.setLevel(logging.INFO)

    logger.addHandler(ch)

    if cmdargs.pirepo is not None:
        parse_pull_requests(cmdargs.pirepo, cmdargs.topdir, cmdargs.dryrun)

    if cmdargs.tyrepo is not None:
        send_thanks(cmdargs.tyrepo, cmdargs.topdir, cmdargs.cfgfile, cmdargs.config, cmdargs.nomail, cmdargs.dryrun)
