From 1c4ff4eafb0dd9cb1463b6e8352747377b1bcbed Mon Sep 17 00:00:00 2001 From: arianagiroux Date: Tue, 19 Jul 2022 15:00:13 -0600 Subject: [PATCH 01/26] Updates .gitignore to ignore data files --- .gitignore | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index c03ba5e..2c65419 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,6 @@ /bower_components/ -/node_modules/ \ No newline at end of file +/node_modules/ +resources/data.* +venv +*.sw* +.ropeproject From 3a67e98b71948403955d62c04a240c37263b140e Mon Sep 17 00:00:00 2001 From: arianagiroux Date: Wed, 20 Jul 2022 23:42:38 -0600 Subject: [PATCH 02/26] Initial functionality for python --- index.html | 11 +++++++---- runner.py | 14 ++++++++++++++ 2 files changed, 21 insertions(+), 4 deletions(-) create mode 100644 runner.py diff --git a/index.html b/index.html index f9f6b80..5f3aae0 100644 --- a/index.html +++ b/index.html @@ -12,10 +12,13 @@ -
-
-
- +
+
+
+

{{stream-title}}

+
+
+
diff --git a/runner.py b/runner.py new file mode 100644 index 0000000..ae70d92 --- /dev/null +++ b/runner.py @@ -0,0 +1,14 @@ +#! /Users/arianagiroux/Documents/Coding/owncast-obs-streamer/venv/bin/python3 + +import chevron + + +def render(data={}): + return chevron.render(template=open('index.html', 'r'), data=data) + + +data_constructor = { + 'stream-title': 'a big test' +} + +print(render(data_constructor)) From 8b823a6386f58306bd6df9f6e6a2c2420e6e6670 Mon Sep 17 00:00:00 2001 From: arianagiroux Date: Thu, 21 Jul 2022 17:20:49 -0600 Subject: [PATCH 03/26] Adds barebones API skeleton using requests --- runner.py | 27 +++++++++++++++++++++++---- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/runner.py b/runner.py index ae70d92..2b3da3e 100644 --- a/runner.py +++ b/runner.py @@ -1,14 +1,33 @@ #! /Users/arianagiroux/Documents/Coding/owncast-obs-streamer/venv/bin/python3 import chevron +import requests +import json +from pprint import pprint + +stream_data = json.load(open('resources/data.json', 'r')) def render(data={}): return chevron.render(template=open('index.html', 'r'), data=data) -data_constructor = { - 'stream-title': 'a big test' -} +def getStatus(): + response = requests.get(stream_data['stream_url'] + '/api/yp') + response_data = response.json() + return { + 'name': response_data['name'], + 'online': response_data['online'], + 'overallMaxViewerCount': response_data['overallMaxViewerCount'], + 'sessionMaxViewerCount': response_data['sessionMaxViewerCount'], + 'streamTitle': response_data['streamTitle'], + 'viewerCount': response_data['viewerCount'], + 'description': response_data['description'], + } -print(render(data_constructor)) + +def updateStreamTitle(): + pass + + +print(render(getStatus())) From 462b1469c4d943b4463aed3250b06f43b67532fb Mon Sep 17 00:00:00 2001 From: arianagiroux Date: Thu, 21 Jul 2022 17:21:05 -0600 Subject: [PATCH 04/26] Adds UI elements to represent full API data --- index.html | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/index.html b/index.html index 5f3aae0..2d63f85 100644 --- a/index.html +++ b/index.html @@ -3,9 +3,9 @@ - Example Title + {{name}} - + @@ -15,7 +15,12 @@
-

{{stream-title}}

+

{{streamTitle}}

+

Stream online? {{online}}

+
+

Current Viewers: {{viewerCount}}

+

Session Max Viewers: {{sessionMaxViewerCount}}

+

Overall Max Viewers: {{overallMaxViewerCount}}

From 5632957041b61b995cbd2046c8b1ad34c399857b Mon Sep 17 00:00:00 2001 From: arianagiroux Date: Fri, 22 Jul 2022 12:23:24 -0600 Subject: [PATCH 05/26] More updates to the .gitignore for python --- .gitignore | 1 + runner.py => app.py | 0 2 files changed, 1 insertion(+) rename runner.py => app.py (100%) diff --git a/.gitignore b/.gitignore index 2c65419..be7fdfa 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,4 @@ resources/data.* venv *.sw* .ropeproject +__pycache__ diff --git a/runner.py b/app.py similarity index 100% rename from runner.py rename to app.py From 15030d01c8fd9465a4c8681e99d0731211eb951b Mon Sep 17 00:00:00 2001 From: arianagiroux Date: Fri, 22 Jul 2022 17:14:19 -0600 Subject: [PATCH 06/26] Implemented full api via flask - moves runner.py to app.py - implements flask api routing & interface for app.py - updates the various ui elements to reflect full data load --- app.py | 53 +++++++++++++++++++++++++++++++++++++++++++++++------ index.html | 14 ++++++++------ 2 files changed, 55 insertions(+), 12 deletions(-) diff --git a/app.py b/app.py index 2b3da3e..9072f31 100644 --- a/app.py +++ b/app.py @@ -4,18 +4,24 @@ import chevron import requests import json from pprint import pprint +from flask import Flask, request stream_data = json.load(open('resources/data.json', 'r')) +session = requests.Session() +session.auth = ('admin', stream_data['stream_key']) + +app = Flask(__name__) def render(data={}): return chevron.render(template=open('index.html', 'r'), data=data) -def getStatus(): - response = requests.get(stream_data['stream_url'] + '/api/yp') +@app.route("/api/serverstatus", methods=['GET']) +def getServerStatus(): + response = session.get(stream_data['stream_url'] + '/api/yp') response_data = response.json() - return { + return json.dumps({ 'name': response_data['name'], 'online': response_data['online'], 'overallMaxViewerCount': response_data['overallMaxViewerCount'], @@ -23,11 +29,46 @@ def getStatus(): 'streamTitle': response_data['streamTitle'], 'viewerCount': response_data['viewerCount'], 'description': response_data['description'], - } + 'tags': response_data['tags'], + 'nsfw': response_data['nsfw'], + }) +@app.route("/api/update/streamtitle", methods=['POST']) def updateStreamTitle(): - pass + response = session.post( + stream_data['stream_url'] + '/api/admin/config/streamtitle', + data=json.dumps({'value': request.json()}) + ) + print(response.json()) + return response.status_code -print(render(getStatus())) +@app.route('/api/update/servertags', methods=['POST']) +def updateServerTags(tags_list: list): + response = session.post( + stream_data['stream_url'] + '/api/admin/config/tags', + data=json.dumps({ + 'value': tags_list + }) + ) + return response.status_code, json.loads(response.text) + + +@app.route('/api/update/nsfw', methods=['POST']) +def updateServerNSFW(boolean: bool): + response = session.post( + stream_data['stream_url'] + '/api/admin/config/nsfw', + data=json.dumps({ + 'value': boolean + }) + ) + return response.status_code, json.loads(response.text) + + +@app.route("/") +def index(): + return render(json.loads(getServerStatus())) + + +print(getServerStatus()[1]) diff --git a/index.html b/index.html index 2d63f85..4df98ed 100644 --- a/index.html +++ b/index.html @@ -3,7 +3,7 @@ - {{name}} + {{name}} @@ -15,12 +15,14 @@
-

{{streamTitle}}

-

Stream online? {{online}}

+

{{streamTitle}}

+

Stream online? {{online}}


-

Current Viewers: {{viewerCount}}

-

Session Max Viewers: {{sessionMaxViewerCount}}

-

Overall Max Viewers: {{overallMaxViewerCount}}

+

Current Viewers: {{viewerCount}}

+

Session Max Viewers: {{sessionMaxViewerCount}}

+

Overall Max Viewers: {{overallMaxViewerCount}}

+
+

Current tags:

From 823abb4395378318961e627c6aa2368935c1cef4 Mon Sep 17 00:00:00 2001 From: arianagiroux Date: Fri, 22 Jul 2022 17:15:56 -0600 Subject: [PATCH 07/26] Adds initial client-side api interface --- index.html | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/index.html b/index.html index 4df98ed..cf5908c 100644 --- a/index.html +++ b/index.html @@ -28,4 +28,36 @@ + + From f9a78d9d1074413ac3efca8dfa7e39eb1d595b70 Mon Sep 17 00:00:00 2001 From: arianagiroux Date: Fri, 22 Jul 2022 17:17:50 -0600 Subject: [PATCH 08/26] Moves client side javascript to a new file - creates new file, resources/script.js - removes javascript from index.html --- index.html | 32 +------------------------------- resources/script.js | 27 +++++++++++++++++++++++++++ 2 files changed, 28 insertions(+), 31 deletions(-) create mode 100644 resources/script.js diff --git a/index.html b/index.html index cf5908c..7dd9b53 100644 --- a/index.html +++ b/index.html @@ -28,36 +28,6 @@ - + diff --git a/resources/script.js b/resources/script.js new file mode 100644 index 0000000..5291319 --- /dev/null +++ b/resources/script.js @@ -0,0 +1,27 @@ +async function getEndpoint(url = '') { + const response = await fetch(url, {method:'GET'}); + const data = await response.json(); + return data; +} + +async function uiUpdate() { + window.setInterval(async () => { + data = await getEndpoint('http://127.0.0.1:5000/api/serverstatus'); + document.getElementById("streamTitle").innerHTML = data.streamTitle + document.getElementById("currentViewers").innerHTML = data.viewerCount + document.getElementById("sessionMaxViewerCount").innerHTML = data.sessionMaxViewerCount + document.getElementById("overallMaxViewerCount").innerHTML = data.overallMaxViewerCount + document.getElementById("tags").innerHTML = data.tags + }, 1000) +} + +async function updateStreamTitle() { + response = await fetch('http://127.0.0.1:5000/api/update/streamtitle', + { + method:'POST', + data:JSON.stringify('a big test') + } + ); + const data = await response.json() + return data +} From f2fb50e025e6db93722fac468776d7e0dceafa83 Mon Sep 17 00:00:00 2001 From: arianagiroux Date: Sun, 24 Jul 2022 14:10:00 -0600 Subject: [PATCH 09/26] Moved files to more reflective of webapp structure --- index.html => index.mustache | 0 {resources => static}/script.js | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename index.html => index.mustache (100%) rename {resources => static}/script.js (100%) diff --git a/index.html b/index.mustache similarity index 100% rename from index.html rename to index.mustache diff --git a/resources/script.js b/static/script.js similarity index 100% rename from resources/script.js rename to static/script.js From 97bc440ea0e2872685defac14a5b97ea286189b6 Mon Sep 17 00:00:00 2001 From: arianagiroux Date: Sun, 24 Jul 2022 14:12:23 -0600 Subject: [PATCH 10/26] Adds a few minor changes to index.mustache - adds {{tags}} where necessary - changes where the file loads the javascript code from --- index.mustache | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/index.mustache b/index.mustache index 7dd9b53..0603d00 100644 --- a/index.mustache +++ b/index.mustache @@ -22,12 +22,12 @@

Session Max Viewers: {{sessionMaxViewerCount}}

Overall Max Viewers: {{overallMaxViewerCount}}


-

Current tags:

+

Current tags: {{tags}}

- + From 90677ec4e39da8d8635f17b922b961ebe46758e3 Mon Sep 17 00:00:00 2001 From: arianagiroux Date: Sun, 24 Jul 2022 14:14:10 -0600 Subject: [PATCH 11/26] Adds a main function static/script.js --- static/script.js | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/static/script.js b/static/script.js index 5291319..9723121 100644 --- a/static/script.js +++ b/static/script.js @@ -25,3 +25,10 @@ async function updateStreamTitle() { const data = await response.json() return data } + +async function Main() { + // console.log(await updateStreamTitle()) + // console.log(await uiUpdate()) +} + +Main() From 8589457c0708f9e00440f85ded5e49e87e77f88c Mon Sep 17 00:00:00 2001 From: arianagiroux Date: Sun, 24 Jul 2022 14:14:43 -0600 Subject: [PATCH 12/26] Adds .undodir to gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index be7fdfa..072980d 100644 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,4 @@ venv *.sw* .ropeproject __pycache__ +.undodir From e4fe12befeec52d5c4664c8462a136c2f356dc9c Mon Sep 17 00:00:00 2001 From: arianagiroux Date: Sun, 24 Jul 2022 14:32:33 -0600 Subject: [PATCH 13/26] Added basic usage documentation to app.py --- app.py | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/app.py b/app.py index 9072f31..eabbb00 100644 --- a/app.py +++ b/app.py @@ -1,4 +1,33 @@ #! /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 From 517c1b071d625658aca1a61462c8c48d55b26127 Mon Sep 17 00:00:00 2001 From: arianagiroux Date: Sun, 24 Jul 2022 14:33:09 -0600 Subject: [PATCH 14/26] Added a more sophisticated json loading interface - this should provide more verbose output in the case that the json file either doesn't exist or isn't formatted correctly --- app.py | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/app.py b/app.py index eabbb00..5e51b4f 100644 --- a/app.py +++ b/app.py @@ -32,10 +32,21 @@ structure: import chevron import requests import json +from os import path from pprint import pprint from flask import Flask, request -stream_data = json.load(open('resources/data.json', 'r')) +# 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']) From 224c724cc0094ebc84a8f4fc4170549306d32e0f Mon Sep 17 00:00:00 2001 From: arianagiroux Date: Sun, 24 Jul 2022 14:34:08 -0600 Subject: [PATCH 15/26] Added more sophisticated flask usage to app.py - enables the user to simply execute the file to run the flask app --- app.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) mode change 100644 => 100755 app.py diff --git a/app.py b/app.py old mode 100644 new mode 100755 index 5e51b4f..c2894b5 --- a/app.py +++ b/app.py @@ -50,6 +50,7 @@ else: session = requests.Session() session.auth = ('admin', stream_data['stream_key']) +# initialize flask app app = Flask(__name__) @@ -111,4 +112,5 @@ def index(): return render(json.loads(getServerStatus())) -print(getServerStatus()[1]) +if __name__ == '__main__': + app.run() From b7fcfe2b4a1b53e2fb13f25008a6594ddd5d4aef Mon Sep 17 00:00:00 2001 From: arianagiroux Date: Sun, 24 Jul 2022 14:38:24 -0600 Subject: [PATCH 16/26] FIX: fixes path to template to reflect f2fb50e --- app.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app.py b/app.py index c2894b5..37c2148 100755 --- a/app.py +++ b/app.py @@ -55,7 +55,7 @@ app = Flask(__name__) def render(data={}): - return chevron.render(template=open('index.html', 'r'), data=data) + return chevron.render(template=open('index.mustache', 'r'), data=data) @app.route("/api/serverstatus", methods=['GET']) From c8fe79414492eea388b3530ae77218784e893040 Mon Sep 17 00:00:00 2001 From: arianagiroux Date: Sun, 24 Jul 2022 16:56:48 -0600 Subject: [PATCH 17/26] Fixes post endpoint for updating stream title - adds python import, flask.Request - ensures flask endpoint /api/update/streamtitle returns valid status code response. - updates static/script.js "updateStreamTitle" to accept variable input --- app.py | 7 +++---- static/script.js | 10 ++++------ 2 files changed, 7 insertions(+), 10 deletions(-) diff --git a/app.py b/app.py index 37c2148..80e7555 100755 --- a/app.py +++ b/app.py @@ -34,7 +34,7 @@ import requests import json from os import path from pprint import pprint -from flask import Flask, request +from flask import Flask, request, Response # load json data, or raise exception. if path.exists('resources/data.json'): @@ -79,10 +79,9 @@ def getServerStatus(): def updateStreamTitle(): response = session.post( stream_data['stream_url'] + '/api/admin/config/streamtitle', - data=json.dumps({'value': request.json()}) + data=json.dumps({'value': request.get_json(force=True)}) ) - print(response.json()) - return response.status_code + return Response(status=response.status_code) @app.route('/api/update/servertags', methods=['POST']) diff --git a/static/script.js b/static/script.js index 9723121..d9e4f3f 100644 --- a/static/script.js +++ b/static/script.js @@ -15,20 +15,18 @@ async function uiUpdate() { }, 1000) } -async function updateStreamTitle() { +async function updateStreamTitle(value) { response = await fetch('http://127.0.0.1:5000/api/update/streamtitle', { method:'POST', - data:JSON.stringify('a big test') + body:JSON.stringify(value) } ); - const data = await response.json() - return data + await uiUpdate() } async function Main() { - // console.log(await updateStreamTitle()) - // console.log(await uiUpdate()) + await uiUpdate() } Main() From 6799e2513b65b4964df60288b84f502aa33158b6 Mon Sep 17 00:00:00 2001 From: arianagiroux Date: Sun, 24 Jul 2022 17:01:05 -0600 Subject: [PATCH 18/26] Pretifies index.mustache with bootstrap 5 - updates visual layout to be more readable - adds basic functionality for javascript callback functions to update various useful elements through api - note, these updates are currently implemented through a bootstrap modal - note, these updates are currently commented out through mustache. - adds a vim modeline to enable manual folding --- index.mustache | 93 ++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 83 insertions(+), 10 deletions(-) diff --git a/index.mustache b/index.mustache index 0603d00..b9b8347 100644 --- a/index.mustache +++ b/index.mustache @@ -9,25 +9,98 @@ +
-

{{streamTitle}}

-

Stream online? {{online}}

-
-

Current Viewers: {{viewerCount}}

-

Session Max Viewers: {{sessionMaxViewerCount}}

-

Overall Max Viewers: {{overallMaxViewerCount}}

-
-

Current tags: {{tags}}

+
+
+
+
+

Stream Title: {{streamTitle}}

+
+
+

Stream online? {{online}}

+
+
+
+
+
+

Current Viewers: {{viewerCount}}

+
+
+

Session Max Viewers: {{sessionMaxViewerCount}}

+
+
+

Overall Max Viewers: {{overallMaxViewerCount}}

+
+
+
+
+
+

Current tags:

+

{{tags}}

+
+
+
+
+ + {{! +
+
+ + {{!}} +
+
+
+
+ + - - + From 8cb521f53a64741b8b8e66132c1982d9f07dc4cb Mon Sep 17 00:00:00 2001 From: arianagiroux Date: Sun, 24 Jul 2022 17:03:23 -0600 Subject: [PATCH 19/26] Adds a requirements.txt file for pip --- requirements.txt | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 requirements.txt diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..765d233 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,3 @@ +chevron==0.14.0 +Flask==2.1.3 +requests==2.28.1 From 44b51e531a791c8c0e928b5c907e44df9f0963ad Mon Sep 17 00:00:00 2001 From: arianagiroux Date: Thu, 4 Aug 2022 17:29:12 -0600 Subject: [PATCH 20/26] Adds id tags for html template - allows for easier navigation when template is folded, and easier navigation for css styling --- index.mustache | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/index.mustache b/index.mustache index b9b8347..72eeb87 100644 --- a/index.mustache +++ b/index.mustache @@ -18,7 +18,7 @@
-
+

Stream Title: {{streamTitle}}

@@ -27,7 +27,7 @@

-
+

Current Viewers: {{viewerCount}}

@@ -39,16 +39,16 @@

-
+

Current tags:

{{tags}}

-
+
- {{!
- {{!
From 13f8648fb7b984e302c5c03b85ecd8760662f0f7 Mon Sep 17 00:00:00 2001 From: arianagiroux Date: Thu, 4 Aug 2022 17:30:27 -0600 Subject: [PATCH 21/26] Fixes small workflow changes with update modals - prevents form elements from refreshing the page or submitting requests - ensures that the submit buttons for modals will close the modal, insead of just spawning a page refresh --- index.mustache | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/index.mustache b/index.mustache index 72eeb87..4c1d19e 100644 --- a/index.mustache +++ b/index.mustache @@ -56,13 +56,13 @@
@@ -78,14 +78,14 @@ From dbbf1b757cee257bbfaefc67021e600ea3e4779f Mon Sep 17 00:00:00 2001 From: arianagiroux Date: Thu, 4 Aug 2022 17:31:38 -0600 Subject: [PATCH 22/26] Adds a vim modeline update to index.mustache - ensures that vim doesnt wrap long lines, for readability --- index.mustache | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/index.mustache b/index.mustache index 4c1d19e..03ebae8 100644 --- a/index.mustache +++ b/index.mustache @@ -101,6 +101,6 @@ - From 2306bbc2e77ad794e44710b688a6e8461ede0231 Mon Sep 17 00:00:00 2001 From: arianagiroux Date: Thu, 4 Aug 2022 17:33:59 -0600 Subject: [PATCH 23/26] Updates get_status endpoint for compatibility - get_status endpoint now actually accesses two different endpoints from the owncast server api, as some of the endpoints have changed since development began - adds various documentation to app.py --- app.py | 30 +++++++++++++++++++++++++++--- 1 file changed, 27 insertions(+), 3 deletions(-) diff --git a/app.py b/app.py index 80e7555..4d3de8c 100755 --- a/app.py +++ b/app.py @@ -55,28 +55,48 @@ 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() - return json.dumps({ + data = { 'name': response_data['name'], 'online': response_data['online'], 'overallMaxViewerCount': response_data['overallMaxViewerCount'], 'sessionMaxViewerCount': response_data['sessionMaxViewerCount'], - 'streamTitle': response_data['streamTitle'], '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)}) @@ -108,6 +128,10 @@ def updateServerNSFW(boolean: bool): @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())) From 08287a9758184f5cf456456c5d84e44631f4e065 Mon Sep 17 00:00:00 2001 From: arianagiroux Date: Thu, 4 Aug 2022 17:36:01 -0600 Subject: [PATCH 24/26] Simplified javascript function for updating UI - breaks uiUpdate() into two functions - uiUpdateOnce(), which contains the bulk of the UI updating code - continuousUiUpdate(), which runs the aforementioned function once every second. - updates updateStreamTitle() to conform to this new change - removes call to Main(), replacing it with a call to the new continuousUiUpdate() --- static/script.js | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/static/script.js b/static/script.js index d9e4f3f..ec6c773 100644 --- a/static/script.js +++ b/static/script.js @@ -4,29 +4,35 @@ async function getEndpoint(url = '') { return data; } -async function uiUpdate() { +async function uiUpdateOnce() { + var data = await getEndpoint('http://127.0.0.1:5000/api/serverstatus'); + document.getElementById("streamTitle").innerHTML = data.streamTitle; + document.getElementById("currentViewers").innerHTML = data.viewerCount; + document.getElementById("sessionMaxViewerCount").innerHTML = data.sessionMaxViewerCount; + document.getElementById("overallMaxViewerCount").innerHTML = data.overallMaxViewerCount; + document.getElementById("tags").innerHTML = data.tags; +} + +async function continuousUiUpdate() { window.setInterval(async () => { - data = await getEndpoint('http://127.0.0.1:5000/api/serverstatus'); - document.getElementById("streamTitle").innerHTML = data.streamTitle - document.getElementById("currentViewers").innerHTML = data.viewerCount - document.getElementById("sessionMaxViewerCount").innerHTML = data.sessionMaxViewerCount - document.getElementById("overallMaxViewerCount").innerHTML = data.overallMaxViewerCount - document.getElementById("tags").innerHTML = data.tags - }, 1000) + uiUpdateOnce(); + }, 1000); } async function updateStreamTitle(value) { + // this function simply passes data along to the python script, and allows + // python to handle data processing response = await fetch('http://127.0.0.1:5000/api/update/streamtitle', { method:'POST', body:JSON.stringify(value) } ); - await uiUpdate() + await uiUpdateOnce(); } async function Main() { await uiUpdate() } -Main() +continuousUiUpdate() From ea96df1774caede359111a98a2c2fc559fd39334 Mon Sep 17 00:00:00 2001 From: arianagiroux Date: Thu, 4 Aug 2022 17:40:31 -0600 Subject: [PATCH 25/26] Implements function to pass tags updates to python - also removes main function from javascript file --- static/script.js | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/static/script.js b/static/script.js index ec6c773..c5c5a60 100644 --- a/static/script.js +++ b/static/script.js @@ -31,8 +31,16 @@ async function updateStreamTitle(value) { await uiUpdateOnce(); } -async function Main() { - await uiUpdate() +async function updateTags(value) { + // this function simply passes data along to the python script, and allows + // python to handle data processing + response = await fetch('http://127.0.0.1:5000/api/update/servertags', + { + method:'POST', + body:JSON.stringify(value) + } + ); + await uiUpdateOnce(); } continuousUiUpdate() From 03f2f966d7708f3abcffd80a1958fc5f4df9d7e9 Mon Sep 17 00:00:00 2001 From: arianagiroux Date: Thu, 4 Aug 2022 17:41:40 -0600 Subject: [PATCH 26/26] Updates python to update tags on owncast server - removes the nsfw tag function - adds functionality to the tags update endpoint to process raw data from client --- app.py | 22 ++++++++-------------- 1 file changed, 8 insertions(+), 14 deletions(-) diff --git a/app.py b/app.py index 4d3de8c..1b3c2f5 100755 --- a/app.py +++ b/app.py @@ -105,25 +105,19 @@ def updateStreamTitle(): @app.route('/api/update/servertags', methods=['POST']) -def updateServerTags(tags_list: list): +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': tags_list + 'value': values }) ) - return response.status_code, json.loads(response.text) - - -@app.route('/api/update/nsfw', methods=['POST']) -def updateServerNSFW(boolean: bool): - response = session.post( - stream_data['stream_url'] + '/api/admin/config/nsfw', - data=json.dumps({ - 'value': boolean - }) - ) - return response.status_code, json.loads(response.text) + return Response(status=response.status_code) @app.route("/")