Ejemplo n.º 1
0
def UpdateTrackingTables(eventname, b, projectname, timestamp, user):
    subcursor = feedutils.GetCursor()
    subcursor.execute(
        'insert ignore into bug%s%s '
        '(id, component, timestamp, '
        'username) '
        'values(%s, "%s", %s, "%s");' %
        (eventname, VERSION, b.bug.id, projectname, timestamp, user))

    summary = {'__total__': 0}
    subcursor.execute('select * from bug%s%s where '
                      'username = "******" and date(timestamp) = %s '
                      'order by timestamp asc;' %
                      (eventname, VERSION, user, timestamp))
    for triage in subcursor:
        summary.setdefault(triage['component'], 0)
        summary[triage['component']] += 1
        summary['__total__'] += 1

    subcursor.execute('delete from bug%ssummary%s where '
                      'username="******" and day=date(%s);' %
                      (eventname, VERSION, user, timestamp))
    subcursor.execute('insert into bug%ssummary%s'
                      '(day, username, data, epoch) '
                      'values (date(%s), "%s", \'%s\', %d);' %
                      (eventname, VERSION, timestamp, user,
                       json.dumps(summary), int(time.time())))
    subcursor.execute('commit;')
def FindDuplicates():
    global DUPLICATES

    cursor = feedutils.GetCursor()
    cursor.execute('select * from bugs where duplicateof is not null;')
    for row in cursor:
        DUPLICATES[row['id']] = row['duplicateof']
Ejemplo n.º 3
0
def Execute(last_change, cmd_name, cmd, arg, cleanup=False):
    actual_cmd = cmd % arg
    print 'Executing: %s' % actual_cmd

    cursor = feedutils.GetCursor()
    try:
        cursor.execute('create table commands_%s (arg varchar(500), '
                       'timestamp datetime, epoch int, result longtext, '
                       'primary key(arg, timestamp), index(timestamp), '
                       'index(epoch)) '
                       'engine=innodb;' % cmd_name)
    except:
        pass

    cursor.execute('delete from commands_%s where arg="%s" and epoch < %s;' %
                   (cmd_name, arg, last_change))
    print ' ... Cleaned up %d old cache entries' % cursor.rowcount
    cursor.execute('commit;')

    cursor.execute('select timestamp, epoch, result from commands_%s '
                   'where arg="%s" order by timestamp desc limit 1;' %
                   (cmd_name, arg))
    if cursor.rowcount > 0:
        row = cursor.fetchone()
        if row['epoch'] > last_change:
            print ' ... Using cached result'
            return base64.decodestring(row['result']).split('\n')

    p = subprocess.Popen(actual_cmd,
                         shell=True,
                         stdout=subprocess.PIPE,
                         stderr=subprocess.PIPE)
    out = p.stdout.read()
    print ' ... Got %d bytes' % len(out)

    cursor.execute('insert into commands_%s (arg, timestamp, epoch, result) '
                   'values ("%s", now(), %d, "%s");' %
                   (cmd_name, arg, int(time.time()), base64.encodestring(out)))
    cursor.execute('commit;')

    if cleanup:
        too_old = datetime.datetime.now()
        too_old -= datetime.timedelta(days=14)

        cursor.execute('delete from commands_%s where timestamp < %s;' %
                       (cmd_name, sql.FormatSqlValue('timestamp', too_old)))
        cursor.execute('commit;')

    return out.split('\n')
def RebuildSummary():
    users_cursor = feedutils.GetCursor()
    dates_cursor = feedutils.GetCursor()
    close_cursor = feedutils.GetCursor()

    users_cursor.execute('select distinct(username) from bugclose;')
    for user_row in users_cursor:
        print user_row['username']
        dates_cursor.execute('select distinct(date(timestamp)) '
                             'from bugclose where username = "******";' %
                             user_row['username'])
        for date_row in dates_cursor:
            print '  %s' % date_row['(date(timestamp))']
            timestamp = sql.FormatSqlValue('timestamp',
                                           date_row['(date(timestamp))'])
            summary = {'__total__': 0}

            close_cursor.execute('select * from bugclose where '
                                 'username = "******" and date(timestamp) = %s '
                                 'order by timestamp asc;' %
                                 (user_row['username'], timestamp))
            for close in close_cursor:
                summary.setdefault(close['component'], 0)
                summary[close['component']] += 1
                summary['__total__'] += 1

            epoch = time.mktime(close['timestamp'].timetuple())
            close_cursor.execute('delete from bugclosesummary where '
                                 'username="******" and day=date(%s);' %
                                 (user_row['username'], timestamp))
            close_cursor.execute(
                'insert into bugclosesummary'
                '(day, username, data, epoch) '
                'values (date(%s), "%s", \'%s\', %d);' %
                (timestamp, user_row['username'], json.dumps(summary), epoch))
            close_cursor.execute('commit;')
import datetime
import json
import random
import sys
import time
import MySQLdb

import feedutils
import sql

if __name__ == '__main__':
    print 'Content-Type: text/plain\r'
    print '\r'
    sys.stdout.flush()

    cursor = feedutils.GetCursor()

    showusers = ['mikalstill']
    form = cgi.FieldStorage()
    if form.has_key('reviewers'):
        showusers = feedutils.ResolveGroupMembers(cursor,
                                                  form['reviewers'].value)

    # Fetch the last seven days of results to start off with
    initial_size = 30
    one_day = datetime.timedelta(days=1)
    last_timestamp = datetime.datetime(1970, 1, 1)

    feedutils.SendGroups(cursor)
    feedutils.SendReviewers(cursor, '__total__', initial_size)
    feedutils.SendPacket({'type': 'users-present', 'payload': showusers})
Ejemplo n.º 6
0
def ScrapeProject(projectname, days):
    launchpad = Launchpad.login_with('openstack-lp-scripts', 'production',
                                     CACHEDIR)
    proj = launchpad.projects[projectname]
    cursor = feedutils.GetCursor()
    subcursor = feedutils.GetCursor()

    now = datetime.datetime.now()
    since = datetime.datetime(now.year, now.month, now.day)
    since -= datetime.timedelta(days=days)

    bugs = proj.searchTasks(modified_since=since,
                            status=[
                                "New", "Incomplete", "Invalid", "Won't Fix",
                                "Confirmed", "Triaged", "In Progress",
                                "Fix Committed", "Fix Released"
                            ])
    for b in bugs:
        if ONLY and b.bug.id not in ONLY:
            continue

        status_toucher = None
        importance_toucher = None
        triage_timestamp = None

        print '\n%s' % b.title
        print 'Reported by: %s' % b.bug.owner.name
        if WRITE:
            cursor.execute(
                'insert ignore into bugs%s '
                '(id, title, reporter, timestamp, component) '
                'values(%s, %s, "%s", %s, "%s");' %
                (VERSION, b.bug.id, sql.FormatSqlValue(
                    'title', b.bug.title), b.bug.owner.name,
                 sql.FormatSqlValue('timestamp',
                                    b.bug.date_created), projectname))
            cursor.execute('commit;')

            for dup in getattr(b.bug, 'duplicates', []):
                print 'Duplicate: %s' % dup.id
                cursor.execute(
                    'update bugs%s set duplicateof=%s where id=%s;' %
                    (VERSION, b.bug.id, dup.id))
                cursor.execute('commit;')

        for bugtask in b.bug.bug_tasks:
            print('  Targetted to %s on %s by %s' %
                  (bugtask.bug_target_name, bugtask.date_created,
                   bugtask.owner.name))

            if WRITE:
                timestamp = sql.FormatSqlValue('timestamp',
                                               bugtask.date_created)
                cursor.execute(
                    'insert ignore into bugevents%s '
                    '(id, component, timestamp, username, '
                    'field, pre, post) '
                    'values(%s, "%s", %s, "%s", "targetted", NULL, '
                    '"%s");' %
                    (VERSION, b.bug.id, bugtask.bug_target_name, timestamp,
                     bugtask.owner.name, bugtask.bug_target_name))
                cursor.execute(
                    'insert ignore into bugevents%s '
                    '(id, component, timestamp, username, '
                    'field, pre, post) '
                    'values(%s, "%s", %s, "%s", "importance", "-", '
                    '"%s");' %
                    (VERSION, b.bug.id, bugtask.bug_target_name, timestamp,
                     bugtask.owner.name, bugtask.importance))
                cursor.execute('insert ignore into bugevents%s '
                               '(id, component, timestamp, username, '
                               'field, pre, post) '
                               'values(%s, "%s", %s, "%s", "status", "-", '
                               '"%s");' %
                               (VERSION, b.bug.id, bugtask.bug_target_name,
                                timestamp, bugtask.owner.name, bugtask.status))
                cursor.execute('commit;')

            if bugtask.assignee:
                time_diff = bugtask.date_assigned - bugtask.date_created
                if time_diff.seconds < 60:
                    print(
                        '  *** special case: bug assigned to %s on task '
                        'creation ***' % bugtask.assignee)
                    if WRITE:
                        timestamp = sql.FormatSqlValue('timestamp',
                                                       bugtask.date_assigned)
                        cursor.execute(
                            'insert ignore into bugevents%s '
                            '(id, component, timestamp, username, '
                            'field, pre, post) '
                            'values(%s, "%s", %s, "%s", "assignee", "-", '
                            '"%s");' %
                            (VERSION, b.bug.id, bugtask.bug_target_name,
                             timestamp, bugtask.owner.name,
                             bugtask.assignee.name))
                        cursor.execute('commit;')

        for activity in b.bug.activity:
            if activity.whatchanged.startswith('%s: ' % projectname):
                timestamp = sql.FormatSqlValue('timestamp',
                                               activity.datechanged)
                oldvalue = activity.oldvalue
                newvalue = activity.newvalue

                try:
                    m = PERSON_RE.match(oldvalue)
                    if m:
                        oldvalue = m.group(1)
                except:
                    pass

                try:
                    m = PERSON_RE.match(newvalue)
                    if m:
                        newvalue = m.group(1)
                except:
                    pass

                print('  %s :: %s -> %s :: %s on %s' %
                      (activity.whatchanged, oldvalue, newvalue,
                       activity.person.name, activity.datechanged))

                if WRITE:
                    cursor.execute('insert ignore into bugevents%s '
                                   '(id, component, timestamp, username, '
                                   'field, pre, post) '
                                   'values(%s, "%s", %s, "%s", "%s", "%s", '
                                   '"%s");' %
                                   (VERSION, b.bug.id, projectname, timestamp,
                                    activity.person.name,
                                    activity.whatchanged.split(': ')[1],
                                    oldvalue, newvalue))
                    cursor.execute('commit;')

                # We define a triage as changing the status from New, and
                # changing the importance from Undecided. You must do both
                # to earn a cookie.
                if (activity.whatchanged.endswith(' status')
                        and (activity.oldvalue in ['New', 'Incomplete'])
                        and (activity.newvalue in ['Confirmed', 'Triaged'])):
                    status_toucher = activity.person.name
                    if (not triage_timestamp
                            or activity.datechanged > triage_timestamp):
                        triage_timestamp = activity.datechanged

                if (activity.whatchanged.endswith(' importance')
                        and (activity.oldvalue == 'Undecided')):
                    importance_toucher = activity.person.name
                    if (not triage_timestamp
                            or activity.datechanged > triage_timestamp):
                        triage_timestamp = activity.datechanged

                # Marking a bug as invalid is a special super cookie!
                if (activity.whatchanged.endswith(' status')
                        and (activity.newvalue in ['Invalid', 'Opinion'])):
                    status_toucher = activity.person.name
                    importance_toucher = activity.person.name
                    triage_timestamp = activity.datechanged

                # Code review sent for a bug
                if (activity.whatchanged.endswith(' status')
                        and (activity.newvalue in ['In Progress'])):
                    # Find out who the bug was assigned to
                    cursor.execute('select * from bugevents%s where '
                                   'id=%s and component="%s" and '
                                   'field="assignee" and '
                                   'timestamp < %s '
                                   'order by timestamp desc limit 1;' %
                                   (VERSION, b.bug.id, projectname, timestamp))

                    for row in cursor:
                        user = row['post']
                        if WRITE:
                            UpdateTrackingTables('progress', b, projectname,
                                                 timestamp, user)
                            subcursor.execute('commit;')

                # A bug was marked as fixed
                if (activity.whatchanged.endswith(' status')
                        and (activity.newvalue in ['Fix Committed'])):
                    # Find out who the bug was assigned to
                    cursor.execute('select * from bugevents%s where '
                                   'id=%s and component="%s" and '
                                   'field="assignee" and '
                                   'timestamp < %s '
                                   'order by timestamp desc limit 1;' %
                                   (VERSION, b.bug.id, projectname, timestamp))

                    for row in cursor:
                        user = row['post']
                        if WRITE:
                            subcursor.execute(
                                'update bugs%s set '
                                'closedby="%s" where id=%s '
                                'and component="%s";' %
                                (VERSION, user, b.bug.id, projectname))
                            subcursor.execute('commit;')
                            print '  *** %s closed this bug ***' % user

                            UpdateTrackingTables('close', b, projectname,
                                                 timestamp, user)
                            subcursor.execute('commit;')

                # A bug was unfixed
                if (activity.whatchanged.endswith(' status')
                        and (activity.oldvalue in ['Fix Committed'])
                        and (not activity.newvalue in ['Fix Released'])):
                    if WRITE:
                        cursor.execute('update bugs%s set closedby = null '
                                       'where id=%s and component="%s";' %
                                       (VERSION, b.bug.id, projectname))
                        cursor.execute('commit;')
                    print '  *** This bug was unclosed ***'

        if (status_toucher and importance_toucher
                and (status_toucher == importance_toucher)):
            print '  *** %s triaged this bug ***' % status_toucher
            timestamp = sql.FormatSqlValue('timestamp', triage_timestamp)

            if WRITE:
                UpdateTrackingTables('triage', b, projectname, timestamp,
                                     status_toucher)
Ejemplo n.º 7
0
def Reviews(component):
    cursor = feedutils.GetCursor()
    for l in dbcachingexecute.Execute(time.time() - 60,
                                      'gerrit_query_approvals_json',
                                      ('ssh -i ~/.ssh/id_gerrit '
                                       'review.openstack.org gerrit query '
                                       'project:%s '
                                       '--all-approvals --patch-sets '
                                       '--format JSON'),
                                      component,
                                      cleanup=True):

        try:
            d = json.loads(l)
        except:
            continue

        if d.has_key('id'):
            b64 = base64.encodestring(l)
            checksum = hashlib.sha1(l).hexdigest()
            last_updated = datetime.datetime.fromtimestamp(d['lastUpdated'])
            timestamp = sql.FormatSqlValue('timestamp', last_updated)
            insert = (
                'insert ignore into changes (changeid, timestamp, parsed, '
                'checksum) values ("%s", %s, "%s", "%s");' %
                (d['id'], timestamp, b64, checksum))
            cursor.execute(insert)
            if cursor.rowcount == 0:
                cursor.execute('select * from changes where changeid="%s";' %
                               d['id'])
                stored_checksum = cursor.fetchone()['checksum']
                if checksum != stored_checksum:
                    cursor.execute('delete from changes where changeid="%s";' %
                                   d['id'])
                    cursor.execute(insert)
            cursor.execute('commit;')

        for ps in d.get('patchSets', {}):
            patchset = ps.get('number')

            for review in ps.get('approvals', []):
                # Deliberately leave the timezone alone here so its consistant
                # with reports others generate.
                updated_at = datetime.datetime.fromtimestamp(
                    review['grantedOn'])
                username = review['by'].get('username', 'unknown')

                if username in ['jenkins', 'smokestack']:
                    continue

                timestamp = sql.FormatSqlValue('timestamp', updated_at)
                score = review.get('value', 0)
                cursor.execute(
                    'insert ignore into reviews '
                    '(changeid, username, timestamp, day, component, '
                    'patchset, score) '
                    'values ("%s", "%s", %s, date(%s), "%s", %s, %s);' %
                    (d['id'], username, timestamp, timestamp, component,
                     patchset, score))
                if cursor.rowcount > 0:
                    # This is a new review, we assume we're the only writer
                    print 'New review from %s' % username
                    cursor.execute('select * from reviewsummary where '
                                   'username="******" and day=date(%s);' %
                                   (username, timestamp))
                    if cursor.rowcount > 0:
                        row = cursor.fetchone()
                        summary = json.loads(row['data'])
                    else:
                        summary = {}

                    summary.setdefault(component, 0)
                    summary.setdefault('__total__', 0)
                    summary[component] += 1
                    summary['__total__'] += 1

                    cursor.execute('delete from reviewsummary where '
                                   'username="******" and day=date(%s);' %
                                   (username, timestamp))
                    cursor.execute('insert into reviewsummary'
                                   '(day, username, data, epoch) '
                                   'values (date(%s), "%s", \'%s\', %d);' %
                                   (timestamp, username, json.dumps(summary),
                                    int(time.time())))

                cursor.execute('commit;')
def RebuildStates():
    global DUPLICATES

    cursor = feedutils.GetCursor()

    cursor.execute('select distinct(id) from bugevents;')
    bugids = []
    for row in cursor:
        bugids.append(row['id'])

    cursor.execute('select distinct(component) from bugevents;')
    components = []
    for row in cursor:
        components.append(row['component'])    

    for id in bugids:
        if id in DUPLICATES:
            continue

        for component in components:
            opened = None
            importance = 'Undecided'
            status = 'Unknown'

            cursor.execute('select * from bugevents where '
                           'id=%s and component="%s";'
                           %(id, component))
            for row in cursor:
                # Opened, reopened
                if row['field'] == 'targetted':
                    if not status in CLOSED_STATES:
                        opened = row['timestamp']
                elif row['field'] == 'status' and row['pre'] in CLOSED_STATES and not row['post'] in CLOSED_STATES:
                    opened = row['timestamp']

                # Closed
                elif row['field'] == 'status' and row['post'] in CLOSED_STATES:
                    EmitState(id, component, importance, opened, row['timestamp'])
                    opened = None
                    status = row['post']
                elif row['field'] == 'status':
                   status = row['post']

                # Changed importance
                elif row['field'] == 'importance':
                    if not status in CLOSED_STATES:
                        EmitState(id, component, importance, opened, row['timestamp'])
                        opened = row['timestamp']
                    importance = row['post']

                # Don't care
                elif row['field'] == 'assignee':
                    pass
                elif row['field'] == 'milestone':
                    pass

                # Unknown row!
                else:
                    print row

            if opened:
                EmitState(id, component, importance, opened, datetime.datetime.now())