You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
wubloader/fastest_grid.py

122 lines
3.2 KiB
Python

"""
Attempts to cut every race for a league from local segments.
Database info:
matches maps to multiple races via match_races (on match_id)
matches links to racers and cawmentator:
matches.racer_{1,2}_id
matches.cawmentator_id
races contains start time:
races.timestamp
races maps to multiple runs via race_runs
race_runs contains time for each racer
race_runs.time: centiseconds
race_runs.rank: 1 for fastest time
"""
import datetime
import logging
import os
import sys
from getpass import getpass
import argh
import mysql.connector
from common.segments import get_best_segments, cut_segments
INFO_QUERY = """
SELECT
match_info.racer_1_name as racer_1,
match_info.racer_2_name as racer_2,
match_info.cawmentator_name as cawmentator,
match_info.match_id as match_id,
match_races.race_number as race_number,
races.timestamp as start,
race_runs.time as duration
FROM match_info
JOIN match_races ON (match_info.match_id = match_races.match_id)
JOIN races ON (match_races.race_id = races.race_id)
JOIN race_runs ON (races.race_id = race_runs.race_id)
WHERE match_info.completed AND race_runs.rank = 1
"""
def ts(dt):
return dt.strftime("%FT%T")
class NoSegments(Exception):
pass
def cut_to_file(filename, base_dir, stream, start, end, variant='source'):
if os.path.exists(filename):
return
logging.info("Cutting {}".format(filename))
segments = get_best_segments(
os.path.join(base_dir, stream, variant).lower(),
start, end,
)
if None in segments:
logging.warning("Cutting {} ({} to {}) but it contains holes".format(filename, ts(start), ts(end)))
if not segments or set(segments) == {None}:
raise NoSegments("Can't cut {} ({} to {}): No segments".format(filename, ts(start), ts(end)))
with open(filename, 'w') as f:
for chunk in cut_segments(segments, start, end):
f.write(chunk)
def main(host='condor.live', user='necrobot-read', password=None, database='season_8', base_dir='.', output_dir='.', find=None):
logging.basicConfig(level=logging.INFO)
if password is None:
password = getpass("Password? ")
conn = mysql.connector.connect(
host=host, user=user, password=password, database=database,
)
if find:
find = tuple(find.split('-'))
cur = conn.cursor()
cur.execute(INFO_QUERY)
data = cur.fetchall()
data = [
[item.encode('utf-8') if isinstance(item, unicode) else item for item in row]
for row in data
]
logging.info("Got info on {} races".format(len(data)))
for racer1, racer2, cawmentator, match_id, race_number, start, duration in data:
if find and (racer1.lower(), racer2.lower()) != find:
continue
end = start + datetime.timedelta(seconds=duration/100.)
base_name = "-".join(map(str, [racer1, racer2, match_id, race_number]))
items = [(racer1, racer1), (racer2, racer2)]
if cawmentator:
items.append(("cawmentary", cawmentator))
for name, stream in items:
try:
cut_to_file(
os.path.join(output_dir, "{}-{}.ts".format(base_name, name)),
base_dir, stream, start, end,
)
except NoSegments as e:
logging.warning(e)
except Exception as e:
logging.exception("Failed to cut {}-{}.ts ({} to {})".format(
base_name, name, ts(start), ts(end),
), exc_info=True)
if __name__ == '__main__':
argh.dispatch_command(main)