Skip to content

Commit db18058

Browse files
committed
v1.1 release
1 parent 76a3912 commit db18058

10 files changed

+168
-6
lines changed

.github/ISSUE_TEMPLATE/bug_report.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,6 @@ labels: bug
66

77
**Please describe the bug:** (eg. the stop button on the webcast config page shuts down the pi instead)
88

9-
**Expected Behavior(if applicable):** (eg. it shuts down instead)
9+
**Expected Behavior(if applicable):** (eg. stop the stream)
1010

11-
**Current Behavior(if applicable):** (eg. it should stop the broadcast)
11+
**Current Behavior(if applicable):** (eg. shuts down the pi)

code/services/webcast-api.service

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
[Unit]
2+
Description=API for the Webcast Pi Manager
3+
Wants=network.target
4+
5+
[Service]
6+
ExecStartPre=/bin/sleep 3
7+
ExecStart=/etc/webcast/api/app.py
8+
Restart=always
9+
10+
[Install]
11+
WantedBy=multi-user.target

code/services/webcast-monitor.service

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
[Unit]
2+
Description=Auto-Start on Broadcast Change
3+
4+
[Service]
5+
ExecStart=/etc/webcast/webcast-monitor.py
6+
WorkingDirectory=/etc/webcast
7+
KillMode=process
8+
9+
[Install]
10+
WantedBy=default.target

code/services/webcast-monitor.timer

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
[Unit]
2+
Description=Check for changed webcast
3+
4+
[Timer]
5+
OnStartupSec=1s
6+
OnUnitActiveSec=5m
7+
8+
[Install]
9+
WantedBy=timers.target
File renamed without changes.
File renamed without changes.

code/webcast/api/app.py

+98
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
#!/usr/bin/python3
2+
3+
from flask import Flask, abort, Response, request
4+
app = Flask(__name__)
5+
6+
import os
7+
import json
8+
import pam
9+
10+
from functools import wraps
11+
def auth(f):
12+
@wraps(f)
13+
def pred(*args, **kwargs):
14+
if request.authorization:
15+
if pam.authenticate(request.authorization.username, request.authorization.password):
16+
return f(*args, **kwargs)
17+
return abort(401)
18+
return pred
19+
20+
def pi_stopped(f):
21+
@wraps(f)
22+
def pred(*args, **kwargs):
23+
if request.method == "POST":
24+
# if len(os.popen('ps -e | grep ffmpeg').read()) > 0:
25+
import random
26+
if random.randint(0,2) == 1:
27+
return abort(404)
28+
return f(*args, **kwargs)
29+
return pred
30+
31+
@app.route('/auth')
32+
@auth
33+
def authenticate():
34+
return {}
35+
36+
import psutil
37+
import time
38+
@app.route('/pi/stats')
39+
@auth
40+
def pi_stats():
41+
net = psutil.net_io_counters()
42+
return {'timestamp': time.time(), 'cpu': psutil.cpu_percent(), 'memory': psutil.virtual_memory().percent, 'net_sent': net.bytes_sent, 'net_recv': net.bytes_recv}
43+
44+
45+
@app.route('/webcast/stop')
46+
@auth
47+
def webcast_stop():
48+
os.system('sudo pkill ffmpeg')
49+
os.system('sudo systemctl stop webcast.timer')
50+
output = os.popen('sudo systemctl status webcast.service').read()
51+
return {'response': output}
52+
53+
@app.route('/webcast/start')
54+
@auth
55+
def webcast_start():
56+
os.system('sudo systemctl start webcast.timer')
57+
output = os.popen('sudo systemctl status webcast.service').read()
58+
return {'response': output}
59+
60+
61+
@app.route('/webcast/restart')
62+
@auth
63+
def webcast_restart():
64+
os.system('sudo pkill ffmpeg')
65+
os.system('sudo systemctl restart webcast.service')
66+
output = os.popen('sudo systemctl status webcast.service').read()
67+
return {'response': output}
68+
69+
@app.route('/webcast/status')
70+
@auth
71+
def webcast_status():
72+
output = os.popen('sudo systemctl status webcast.service').read()
73+
return {'response': output}
74+
75+
76+
@app.route('/webcast/settings', methods=['GET', 'POST'])
77+
@auth
78+
@pi_stopped
79+
def webcast_settings():
80+
with open('/etc/webcast/webcast.conf') as f:
81+
conf = json.load(f)
82+
83+
if request.method == 'GET':
84+
return conf
85+
elif request.method == 'POST':
86+
req_json = request.get_json()
87+
88+
for key, val in req_json.items():
89+
if key in conf.keys():
90+
conf[key] = val
91+
else:
92+
return abort(400)
93+
with open('/etc/webcast/webcast.conf', 'w') as f:
94+
json.dump(conf, f)
95+
return conf
96+
97+
if __name__ == "__main__":
98+
app.run(host="0.0.0.0", port=5000)

code/webcast/webcast-monitor.py

+31
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
#!/usr/bin/python3
2+
3+
import json
4+
from os import path, system
5+
import requests
6+
7+
try:
8+
with open('/etc/webcast/webcast.key') as f:
9+
old_key = f.read()
10+
except FileNotFoundError:
11+
old_key = ''
12+
13+
if not path.isfile('/etc/webcast/webcast.conf'):
14+
exit(1)
15+
16+
with open('/etc/webcast/webcast.conf') as f:
17+
config = json.load(f)
18+
19+
if config.get('auto', 'false') != 'true':
20+
exit(1)
21+
22+
url = config.get('url')
23+
xml = requests.get(url).text
24+
25+
_, key = xml.split('<stream>')
26+
key, _ = key.split('</stream>')
27+
28+
if key != old_key:
29+
system(f'echo {key} > /etc/webcast/webcast.key')
30+
system('sudo systemctl start webcast.timer')
31+

code/webcast/webcast.key

Whitespace-only changes.

setup.sh

+7-4
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
11
#!/bin/bash
2-
sudo cp code/webcast.* /etc/systemd/system
2+
sudo cp code/services/* /etc/systemd/system
33
sudo cp -r code/webcast /etc
44
sudo chown -R webcast:webcast /etc/webcast
5-
chmod 664 /etc/webcast/webcast.conf
6-
chmod 775 /etc/webcast/webcast.py
5+
chmod 644 /etc/webcast/webcast.conf /etc/webcast/webcast.key
6+
chmod 775 /etc/webcast/webcast.py /etc/webcast/webcast-monitor.py
7+
chmod 775 -R /etc/webcast/api
78
sudo cp -r code/webcastconfig /usr/share/cockpit
89
sudo systemctl daemon-reload
9-
sudo systemctl enable webcast.timer
10+
sudo systemctl enable --now webcast.timer
11+
sudo systemctl enable --now webcast-api.service
12+
sudo systemctl enable --now webcast-monitor.service

0 commit comments

Comments
 (0)