Automatically take first found start in reviews, but warn user if we do

The vast majority of the time, this is just because of an early 1-1 trapdoor.
But we should double-check.
condor-scripts
Mike Lang 3 years ago
parent b8c86eac52
commit a6fffa6a72

@ -369,12 +369,12 @@ def review_race(match_id, race_number):
"""
if app.condor_db is None:
return "Reviews are disabled", 501
start_range = map(float, request.args.get('start_range', '0,5').split(','))
start_range = map(float, request.args.get('start_range', '0,10').split(','))
finish_range = map(float, request.args.get('finish_range', '-5,10').split(','))
racer1_start = float(request.args['racer1_start']) if 'racer1_start' in request.args else None
racer2_start = float(request.args['racer2_start']) if 'racer2_start' in request.args else None
try:
review_path = review(
review_path, suspect_starts = review(
match_id, race_number, app.static_folder, app.condor_db, start_range, finish_range,
racer1_start, racer2_start,
)
@ -394,6 +394,24 @@ def review_race(match_id, race_number):
relative_path = os.path.relpath(review_path, app.static_folder)
review_url = os.path.join(app.static_url_path, relative_path)
if suspect_starts:
# warn and link via html
return "\n".join([
"<html>",
"<body>",
"Review succeeded, but start times are uncertain. Please check start videos:</br>",
"\n".join('<a href="{}">{}</a></br>'.format(
os.path.join(app.static_url_path, os.path.relpath(e.path, app.static_folder)),
e,
) for e in suspect_starts),
"If all is well, the review is available",
'<a href="{}">HERE</a>'.format(review_url),
"</body>",
"</html>",
])
else:
# happy path, redirect
response = redirect(review_url)
response.autocorrect_location_header = False
return response

@ -7,6 +7,7 @@ import subprocess
from hashlib import sha256
from urlparse import urlparse
from uuid import uuid4
from base64 import b64encode
import mysql.connector
@ -82,7 +83,7 @@ def conn_from_url(url):
def review(
match_id, race_number, base_dir, db_url, start_range=(0, 5), finish_range=(-5, 10),
match_id, race_number, base_dir, db_url, start_range=(0, 10), finish_range=(-5, 10),
racer1_start=None, racer2_start=None,
):
logger = logging.getLogger("review").getChild("{}-{}".format(match_id, race_number))
@ -120,7 +121,7 @@ def review(
# cache hash encapsulates all input args
cache_hash = sha256(str((match_id, race_number, start_range, finish_range, racer1_start, racer2_start)))
cache_str = cache_hash.digest().encode('base64')[:12]
cache_str = b64encode(cache_hash.digest(), "-_")[:12]
output_name = "{}-{}-{}-{}".format(match_id, racer1, racer2, race_number)
output_dir = os.path.join(base_dir, "reviews", output_name)
@ -130,9 +131,10 @@ def review(
result_path = os.path.join(output_dir, result_name)
if os.path.exists(result_path):
logger.info("Result already exists for {}, reusing".format(result_path))
return result_path
return result_path, []
finish_paths = []
suspect_starts = []
for racer_index, (racer, time_offset) in enumerate(((racer1, racer1_start), (racer2, racer2_start))):
nonce = str(uuid4())
@ -159,16 +161,19 @@ def review(
line for line in re.split('[\r\n]', err.strip())
if line.startswith('[blackdetect @ ')
]
if len(lines) == 1:
line, = lines
black_end = line.split(' ')[4]
assert black_end.startswith('black_end:')
time_offset = float(black_end.split(':')[1])
else:
if len(lines) != 1:
found = len(lines)
logger.warning("Unable to detect start (expected 1 black interval, but found {}), re-cutting with timestamps".format(found))
cut_to_file(logger, start_path, base_dir, racer, start_start, start_end, frame_counter=True)
raise CantFindStart(racer, racer_number, found, start_path)
error = CantFindStart(racer, racer_number, found, start_path)
if not lines:
raise error
# try to continue by picking first
suspect_starts.append(error)
line = lines[0]
black_end = line.split(' ')[4]
assert black_end.startswith('black_end:')
time_offset = float(black_end.split(':')[1])
time_offset = datetime.timedelta(seconds=time_offset - start_range[0])
# start each racer's finish video at TIME_OFFSET later, so they are the same
@ -193,6 +198,10 @@ def review(
logger.info("Cutting final result")
subprocess.check_call(args)
# atomic rename so that if result_path exists at all, we know it is complete and correct
# don't do this if we have a suspect start though, as the cached result wouldn't know.
if suspect_starts:
result_path = temp_path
else:
os.rename(temp_path, result_path)
logger.info("Review done")
return result_path
logger.info("Review done, suspect starts = {}".format(len(suspect_starts)))
return result_path, suspect_starts

Loading…
Cancel
Save