radar/feedutils.py

190 lines
5.8 KiB
Python
Executable File

#!/usr/bin/python
# Helpers for producing data feeds
import cgi
import datetime
import json
import random
import sys
import time
import MySQLdb
import sql
def SendPacket(packet):
packet['timestamp'] = int(time.time())
print json.dumps(packet)
sys.stdout.flush()
def GetCursor():
# Read config from a file
with open('/srv/config/summaryfeed') as f:
flags = json.loads(f.read())
db = MySQLdb.connect(user = flags['dbuser'],
db = flags['dbname'],
passwd = flags['dbpassword'],
host = flags.get('dbhost', 'localhost'))
cursor = db.cursor(MySQLdb.cursors.DictCursor)
return cursor
def SendGroups(cursor):
groups = []
cursor.execute('select * from groups;')
for row in cursor:
groups.append([row['name'], row['members'].split(' ')])
SendPacket({'type': 'groups',
'payload': groups})
def GetGroupMembers(cursor, groupname):
members = []
cursor.execute('select * from groups where name="%s";'
% groupname)
if cursor.rowcount > 0:
row = cursor.fetchone()
for member in row['members'].split(' '):
members.append(member)
return members
def ResolveGroupMembers(cursor, usersliststring, table, window_size):
showusers = []
one_day = datetime.timedelta(days=1)
start_of_window = datetime.datetime.now()
start_of_window -= one_day * window_size
for userish in usersliststring.lstrip(' ').split(' '):
if userish.startswith('g:'):
group_name = userish.split(':')[1]
if group_name == 'all':
cursor.execute('select distinct(username), max(day) from %s '
'where day > date(%s) group by username;'
%(table,
sql.FormatSqlValue('timestamp',
start_of_window)))
for row in cursor:
showusers.append(row['username'])
else:
for user in GetGroupMembers(cursor, group_name):
showusers.append(user)
else:
showusers.append(userish)
if len(showusers) == 0:
showusers = ['mikalstill']
return showusers
def SendTriagers(cursor, window_size):
SendUsers(cursor, window_size, 'bugtriagesummary')
def SendClosers(cursor, window_size):
SendUsers(cursor, window_size, 'bugclosesummary')
def SendUsers(cursor, window_size, table, project=None):
one_day = datetime.timedelta(days=1)
start_of_window = datetime.datetime.now()
start_of_window -= one_day * window_size
plike = '%'
if project:
plike = '%%%s%%' % project
all_reviewers = []
cursor.execute('select distinct(username), max(day) from %s '
'where data like "%s" and day > date(%s) group by username;'
%(table, plike,
sql.FormatSqlValue('timestamp', start_of_window)))
for row in cursor:
all_reviewers.append((row['username'], row['max(day)'].isoformat()))
SendPacket({'type': 'users-all',
'payload': all_reviewers})
def SendKeepAlive():
SendPacket({'type': 'keepalive'})
def SendDebug(message):
SendPacket({'type': 'debug',
'payload': message})
def GetInitial(eventname, showusers, project, initial_size):
cursor = GetCursor()
# Fetch the last seven days of results to start off with
last_time = 0
one_day = datetime.timedelta(days=1)
SendGroups(cursor)
SendUsers(cursor, initial_size, '%ssummary' % eventname, project=project)
SendPacket({'type': 'users-present', 'payload': showusers})
for username in showusers:
day = datetime.datetime.now()
day = datetime.datetime(day.year, day.month, day.day)
day -= one_day * (initial_size - 1)
for i in range(initial_size):
timestamp = sql.FormatSqlValue('timestamp', day)
cursor.execute('select * from %ssummary where username="%s" '
'and day=date(%s);'
%(eventname, username, timestamp))
packet = {'type': 'initial-value',
'user': username,
'day': day.isoformat()}
if cursor.rowcount > 0:
row = cursor.fetchone()
packet['payload'] = json.loads(row['data']).get(project, 0)
packet['written-at'] = row['epoch']
if row['epoch'] > last_time:
last_time = row['epoch']
else:
packet['payload'] = 0
SendPacket(packet)
day += one_day
SendPacket({'type': 'initial-value-ends'})
return last_time
def GetUpdates(eventname, showusers, project, last_time):
while True:
time.sleep(60)
# Rebuild the DB connection in case the DB went away
cursor = GetCursor()
SendKeepAlive()
SendDebug('Querying for updates after %d, server time %s'
%(last_time, datetime.datetime.now()))
for username in showusers:
ts = datetime.datetime.now()
ts -= datetime.timedelta(days=5)
cursor.execute('select * from %ssummary where username="%s" '
'and epoch > %d and day > date(%s);'
%(eventname, username, last_time,
sql.FormatSqlValue('timestamp', ts)))
for row in cursor:
SendPacket(
{'type': 'update-value',
'user': username,
'written-at': row['epoch'],
'day': row['day'].isoformat(),
'payload': json.loads(row['data']).get(project, 0)})
if row['epoch'] > last_time:
last_time = row['epoch']