DockOfOurOwn/app.py

134 lines
4.0 KiB
Python
Executable File

#! /Users/arianagiroux/Documents/Coding/owncast-obs-streamer/venv/bin/python3
""" A simple flask app to provide a streamer UI for obs and owncast.
Usage:
$ ./app.py
> * Serving Flask app 'app' (lazy loading)
> * Environment: production
> WARNING: This is a development server. Do not use it in a production deployment.
> Use a production WSGI server instead.
> * Debug mode: off
> * Running on http://127.0.0.1:5000 (Press CTRL+C to quit)
> Open 127.0.0.1:5000 in your local browser
Note:
If port 5000 is already bound, use the following command to start the flask
app:
$ flask run -p INTEGER
The app will automatically fail if there is not file containing valid JSON data
located at ./resources/data.json. This json file should have the following data
structure:
{
"stream_url":"https://yourstream.url",
"user_name":"admin",
"stream_key":"your_stream_key"
}
"""
import chevron
import requests
import json
from os import path
from pprint import pprint
from flask import Flask, request, Response
# load json data, or raise exception.
if path.exists('resources/data.json'):
try:
stream_data = json.load(open('resources/data.json', 'r'))
except json.JSONDecodeError as e:
raise RuntimeError('JSON data did not pass validation.')
else:
raise RuntimeError('Could not find ./resources/data.json, required for '
'runtime!')
# initialize requests session
session = requests.Session()
session.auth = ('admin', stream_data['stream_key'])
# initialize flask app
app = Flask(__name__)
def render(data={}):
""" Template rendering function using mustache (via the pypi chevron
implementation.
:returns: A full HTML template with relevant data from the server.
"""
return chevron.render(template=open('index.mustache', 'r'), data=data)
@app.route("/api/serverstatus", methods=['GET'])
def getServerStatus():
""" Obtains useful information from the server from either /api/yp or
/api/status.
:returns: the collected data as a JSON formatted dict.
"""
response = session.get(stream_data['stream_url'] + '/api/yp')
response_data = response.json()
data = {
'name': response_data['name'],
'online': response_data['online'],
'overallMaxViewerCount': response_data['overallMaxViewerCount'],
'sessionMaxViewerCount': response_data['sessionMaxViewerCount'],
'viewerCount': response_data['viewerCount'],
'description': response_data['description'],
'tags': response_data['tags'],
'nsfw': response_data['nsfw'],
}
response = session.get(stream_data['stream_url'] + '/api/status')
response_data = response.json()
data['streamTitle'] = response_data['streamTitle']
return json.dumps(data)
@app.route("/api/update/streamtitle", methods=['POST'])
def updateStreamTitle():
""" An endpoint to allow the user to update the stream title.
:returns: the status code of the post request made to the server.
"""
response = session.post(
stream_data['stream_url'] + '/api/admin/config/streamtitle',
data=json.dumps({'value': request.get_json(force=True)})
)
return Response(status=response.status_code)
@app.route('/api/update/servertags', methods=['POST'])
def updateServerTags():
""" An endpoint to allow the user to update the stream title.
:returns: the status code of the post request made to the server.
"""
values = [i.strip() for i in request.get_json(force=True).split(',')]
response = session.post(
stream_data['stream_url'] + '/api/admin/config/tags',
data=json.dumps({
'value': values
})
)
return Response(status=response.status_code)
@app.route("/")
def index():
""" A simple initial endpoint that loads in relevant data from the server.
:returns: the rendered template (see app.render for more)
"""
return render(json.loads(getServerStatus()))
if __name__ == '__main__':
app.run()