thrimshim seems to be working

pull/46/head
Christopher Usher 6 years ago
parent e4fc878577
commit c81d538a79

@ -2,7 +2,9 @@ import datetime
import json import json
import logging import logging
import signal import signal
import uuid
import argh
import gevent import gevent
import gevent.backdoor import gevent.backdoor
from gevent.pywsgi import WSGIServer from gevent.pywsgi import WSGIServer
@ -31,10 +33,15 @@ def cors(app):
return handle return handle
@app.route('/thrimshim/<uuid:ident>', methods=['GET', 'POST']) @app.route('/thrimshim/<ident>', methods=['GET', 'POST'])
def thrimshim(ident): def thrimshim(ident):
"""Comunicate between Thrimbletrimmer and the Wubloader database.""" """Comunicate between Thrimbletrimmer and the Wubloader database."""
ident = str(ident)
try:
uuid.UUID(ident, version=4)
except ValueError:
return 'Invalid formate for id', 400
if flask.request.method == 'POST': if flask.request.method == 'POST':
row = flask.request.json row = flask.request.json
return update_row(ident, row) return update_row(ident, row)
@ -53,7 +60,7 @@ def get_row(ident):
WHERE id = %s;""", ident) WHERE id = %s;""", ident)
row = results.fetchone() row = results.fetchone()
if row is None: if row is None:
return 'Row {} not found'.format(ident), 404 return 'Row id = {} not found'.format(ident), 404
assert row.id == ident assert row.id == ident
response = row._asdict() response = row._asdict()
response = {key:(response[key].isoformat() if isinstance(response[key], datetime.datetime) else response[key]) for key in response.keys()} response = {key:(response[key].isoformat() if isinstance(response[key], datetime.datetime) else response[key]) for key in response.keys()}
@ -62,7 +69,7 @@ def get_row(ident):
def update_row(ident, new_row): def update_row(ident, new_row):
"""Updates row of database with id == ident with the edit columns in """Updates row of database with id = ident with the edit columns in
new_row. new_row.
If a 'video_link' is provided in uodate, interperate this as a manual video If a 'video_link' is provided in uodate, interperate this as a manual video
@ -71,15 +78,17 @@ def update_row(ident, new_row):
edit_columns = ['allow_holes', 'uploader_whitelist', 'upload_location', edit_columns = ['allow_holes', 'uploader_whitelist', 'upload_location',
'video_start', 'video_end', 'video_title', 'video_description', 'video_start', 'video_end', 'video_title', 'video_description',
'video_channel', 'video_quality'] 'video_channel', 'video_quality']
state_columns = ['state', 'uploader', 'error', 'video_link']
columns = edit_columns + state_columns
#check edit columns are in new_row
row_keys = new_row.keys() row_keys = new_row.keys()
for column in edit_columns + ['state']: for column in edit_columns + ['state']:
if column not in row_keys: if column not in row_keys:
return 'Missing {} from JSON'.format(column), 400 return 'Missing field {} in JSON'.format(column), 400
state_columns = ['state', 'uploader', 'error', 'video_link']
conn = app.db_manager.get_conn() conn = app.db_manager.get_conn()
#check a row with id = ident is in the database
with database.transaction(conn): with database.transaction(conn):
results = database.query(conn, """ results = database.query(conn, """
SELECT id, state SELECT id, state
@ -93,19 +102,21 @@ def update_row(ident, new_row):
if old_row.state not in ['UNEDITED', 'EDITED', 'CLAIMED']: if old_row.state not in ['UNEDITED', 'EDITED', 'CLAIMED']:
return 'Video already published', 400 return 'Video already published', 400
# handle state columns
# handle non-empty video_link as manual uploads
# otherwise clear other state columns
if 'video_link' in new_row and new_row['video_link']: if 'video_link' in new_row and new_row['video_link']:
new_row['state'] = 'DONE' new_row['state'] = 'DONE'
new_row['upload_location'] = 'manual' new_row['upload_location'] = 'manual'
else: else:
new_row['video_link'] = None new_row['video_link'] = None
new_row['upload_location'] = None
if new_row['state'] not in ['EDITED']: if new_row['state'] not in ['EDITED']:
new_row['state'] = 'UNEDITED' new_row['state'] = 'UNEDITED'
new_row['uploader'] = None new_row['uploader'] = None
new_row['error'] = None new_row['error'] = None
columns = edit_columns + state_columns # actually update database
build_query = sql.SQL(""" build_query = sql.SQL("""
UPDATE events UPDATE events
set {} set {}
@ -119,14 +130,17 @@ def update_row(ident, new_row):
with database.transaction(conn): with database.transaction(conn):
result = database.query(conn, build_query, **kwargs) result = database.query(conn, build_query, **kwargs)
if result.rowcount != 1: if result.rowcount != 1:
raise Exception('No row with id {} to update'.format(ident)) raise Exception('Database consistancy error for id = {}'.format(ident))
logging.info('Row {} updated to state {}'.format(ident, new_row['state'])) logging.info('Row {} updated to state {}'.format(ident, new_row['state']))
return 'Row updated' return ''
@argh.arg('--host', help='Address or socket server will listen to. Default is 0.0.0.0 (everything on the local machine).')
@argh.arg('--port', help='Port server will listen on. Default is 8004.')
@argh.arg('--connection-string', help='Postgres connection string, which is either a space-separated list of key=value pairs, or a URI like: postgresql://USER:PASSWORD@HOST/DBNAME?KEY=VALUE')
@argh.arg('--backdoor-port', help='Port for gevent.backdoor access. By default disabled.')
def main(host='0.0.0.0', port=8004, connection_string='', backdoor_port=0): def main(host='0.0.0.0', port=8004, connection_string='', backdoor_port=0):
"""Thrimshim service."""
server = WSGIServer((host, port), cors(app)) server = WSGIServer((host, port), cors(app))
app.db_manager = database.DBManager(dsn=connection_string) app.db_manager = database.DBManager(dsn=connection_string)

Loading…
Cancel
Save