diff --git a/thrimshim/Dockerfile b/thrimshim/Dockerfile new file mode 100644 index 0000000..93196a9 --- /dev/null +++ b/thrimshim/Dockerfile @@ -0,0 +1,14 @@ +FROM alpine:3.7 +# dependencies needed for compiling c extensions +# also busybox-extras for telnet for easier use of backdoor +RUN apk --update add py2-pip gcc python-dev musl-dev busybox-extras + +# Install common lib first as it changes less +COPY common /tmp/common +RUN pip install /tmp/common && rm -r /tmp/common + +# Install actual application +COPY thrimshim /tmp/thrimshim +RUN pip install /tmp/thrimshim && rm -r /tmp/thrimshim + +ENTRYPOINT ["python2", "-m", "thrimshim", "--base-dir", "/mnt"] diff --git a/thrimshim/setup.py b/thrimshim/setup.py new file mode 100644 index 0000000..7bd0fa1 --- /dev/null +++ b/thrimshim/setup.py @@ -0,0 +1,16 @@ +from setuptools import setup, find_packages + +setup( + name = "wubloader-thrimshim", + version = "0.0.0", + packages = find_packages(), + install_requires = [ + "argh", + "flask", + "gevent", + "psycogreen", + "psycopg2", + "python-dateutil", + "wubloader-common", + ], +) diff --git a/thrimshim/thrimshim/__init__.py b/thrimshim/thrimshim/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/thrimshim/thrimshim/__main__.py b/thrimshim/thrimshim/__main__.py new file mode 100644 index 0000000..2a8b200 --- /dev/null +++ b/thrimshim/thrimshim/__main__.py @@ -0,0 +1,15 @@ +import gevent.monkey +gevent.monkey.patch_all() + +import logging + +import argh + +from thrimshim.main import main + +LOG_FORMAT = "[%(asctime)s] %(levelname)8s %(name)s(%(module)s:%(lineno)d): %(message)s" + +level = os.environ.get('WUBLOADER_LOG_LEVEL', 'INFO').upper() +logging.basicConfig(level=level, format=LOG_FORMAT) +argh.dispatch_command(main) + diff --git a/thrimshim/thrimshim/main.py b/thrimshim/thrimshim/main.py new file mode 100644 index 0000000..deaf7f8 --- /dev/null +++ b/thrimshim/thrimshim/main.py @@ -0,0 +1,88 @@ + +import json +import logging + +import gevent +import gevent.backdoor +from gevent.pywsgi import WSGIServer +from flask import Flask, url_for, request, abort, Response + + +from common import database +from stats import stats, after_request + +app = Flask('restreamer', static_url_path='/segments') +app.after_request(after_request) + +def cors(app): + """WSGI middleware that sets CORS headers""" + HEADERS = [ + ("Access-Control-Allow-Credentials", "false"), + ("Access-Control-Allow-Headers", "*"), + ("Access-Control-Allow-Methods", "GET,POST,HEAD"), + ("Access-Control-Allow-Origin", "*"), + ("Access-Control-Max-Age", "86400"), + ] + def handle(environ, start_response): + def _start_response(status, headers, exc_info=None): + headers += HEADERS + return start_response(status, headers, exc_info) + return app(environ, _start_response) + return handle + +def get_row(ident): + result = query_database(ident) + + response = json(result) + return result + +def query_database(ident): + + select start, end, catagory, description, notes, video_title, video_description, video_start, video_end, state, error + from database where id is ident + +def set_row(data): + to_update = unjson(data) + + update_database(to_update) + +def update_database(ident, to_update): + + if state not in ['UNEDITED, EDITED, CLAIMED']: + return 'Video already published' + + insert video_title, video_description, video_start, video_end + #allow_holes, uploader_whitelist, upload_location + into database where id == indent + + set error to NULL + set uploader to NULL + + if upload_location: + set state to 'DONE' + + if publish: + set state to 'EDITED' + else: + set state to 'UNEDITED' + + + +def main(host='0.0.0.0', port=8005, connect_string='', backdoor_port=False): + + server = WSGIServer((host, port), cors(app)) + + def stop(): + logging.info("Shutting down") + server.stop() + gevent.signal(signal.SIGTERM, stop) + + PromLogCountsHandler.install() + install_stacksampler() + + if backdoor_port: + gevent.backdoor.BackdoorServer(('127.0.0.1', backdoor_port), locals=locals()).start() + + logging.info("Starting up") + server.serve_forever() + logging.info("Gracefully shut down")