Compare commits

...

8 Commits

Author SHA1 Message Date
Ariana Giroux 8cf956c2f0 Merge branch 'python-rewrite'
- rewrites the software to use a python and flask based local webserver,
  for initial simplicity.
2022-08-04 17:43:48 -06:00
Ariana Giroux 03f2f966d7 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
2022-08-04 17:41:40 -06:00
Ariana Giroux ea96df1774 Implements function to pass tags updates to python
- also removes main function from javascript file
2022-08-04 17:40:31 -06:00
Ariana Giroux 08287a9758 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()
2022-08-04 17:40:04 -06:00
Ariana Giroux 2306bbc2e7 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
2022-08-04 17:33:59 -06:00
Ariana Giroux 90746d58b2 Updates .gitignore 2022-07-21 14:59:43 -06:00
Ariana Giroux 8f27f8d216 Cleans up the visual design of the web-page. 2022-07-19 14:56:41 -06:00
Ariana Giroux 658c676be8 Initial api access functionality 2022-06-26 19:15:59 -06:00
3 changed files with 117 additions and 29 deletions

52
app.py
View File

@ -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)})
@ -85,29 +105,27 @@ 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("/")
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()))

56
resources/script.js Normal file
View File

@ -0,0 +1,56 @@
const headers = new Headers();
// note, userName and streamKey are both derived in a file called data.js
headers.append('Authorization', 'Basic ' + btoa(userName + ":" + streamKey));
async function getEndpoint(url = '') {
const response = await fetch(url, {method:'GET', headers: headers})
const data = await response.json()
return data
}
async function postEndpoint(url = '', data = {}) {
const response = await fetch(url, {
method: 'POST',
body: JSON.stringify(data), // serialized data
headers: headers // authentication header
})
return response
}
async function getStatus() {
return getEndpoint(api_url + 'admin/status')
}
async function updateElements(data) {
var {online, viewerCount, sessionPeakViewerCount} = data
updateViewers(viewerCount);
updateOnline(online);
updateSessionPeak(sessionPeakViewerCount);
}
async function updateOnline(online) {
document.getElementById('online').innerHTML = online
}
async function updateViewers(viewers) {
document.getElementById('currentViewers').innerHTML = viewers
}
async function updateSessionPeak(viewers) {
document.getElementById('sessionPeak').innerHTML = viewers
}
async function Main() {
// update visual elements using data from 'api/admin/status'
// updateElements(await getStatus())
const response = await fetch(api_url + 'yp', {mode:'no-cors'})
const data = await response.json()
// update the broadcast title
// postEndpoint(``
// api_url + 'admin/config/streamtitle',
// {value: "testing" + Math.floor(Math.random() * 1000)}
// ).then(response => response.status)
// .then(data => console.log(data))
}
// Main()

View File

@ -4,29 +4,43 @@ 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()
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();
}
Main()
continuousUiUpdate()