initial commit
This commit is contained in:
commit
f60db11733
10 files changed
+856
No files matched your search
@@ -0,0 +1,98 @@
|
||||
# Standard Imports
|
||||
import re
|
||||
import sys
|
||||
import html
|
||||
import time
|
||||
import json
|
||||
from datetime import datetime
|
||||
from zoneinfo import ZoneInfo
|
||||
|
||||
# Package Imports
|
||||
import websocket
|
||||
|
||||
# Local Imports
|
||||
from helpers.clips import generate_and_post_clip
|
||||
|
||||
|
||||
def owncast_on_message(ws, message):
|
||||
"""
|
||||
Handles incoming messages from websocket, filters for commands, and dispatches.
|
||||
|
||||
Args:
|
||||
ws: The websocket object calling this handler.
|
||||
message: The message received by the websocket.
|
||||
|
||||
Returns:
|
||||
None
|
||||
"""
|
||||
|
||||
try:
|
||||
data = json.loads(message)
|
||||
if 'type' in data and data['type'] == 'CHAT':
|
||||
# TODO: add anti-spam and authentication checks
|
||||
current_time = datetime.now(ZoneInfo("America/Chicago"))
|
||||
chat_message = html.unescape(
|
||||
re.sub('<.*?>', '', data['body'])).strip()
|
||||
if chat_message == '!clip' or chat_message.startswith('!clip '):
|
||||
if len(chat_message) == 5:
|
||||
clip_title = f'Clip by {data["user"]["displayName"]} on {current_time.strftime("%Y-%m-%d %H:%M:%S")}'
|
||||
generate_and_post_clip(
|
||||
data['user']['displayName'], clip_title, current_time)
|
||||
elif len(chat_message) > 5 and len(chat_message) < 126:
|
||||
generate_and_post_clip(
|
||||
data['user']['displayName'], chat_message[6:], current_time)
|
||||
else:
|
||||
# TODO: report this error back to the chat
|
||||
return
|
||||
except json.JSONDecodeError as e:
|
||||
print(f'Failed to decode incoming owncast websocket message.', file=sys.stderr)
|
||||
|
||||
|
||||
def owncast_on_error(ws, error):
|
||||
print(f'[WS-ERR] {error}', file=sys.stderr)
|
||||
|
||||
|
||||
def owncast_on_close(ws, code, message):
|
||||
print(f'Owncast websocket closed (code: {code}): {message}')
|
||||
|
||||
|
||||
def owncast_on_open(ws):
|
||||
print('Owncast websocket opened successfully.')
|
||||
|
||||
|
||||
def owncast_connect(url: str, retries: int, initial_backoff: float):
|
||||
"""
|
||||
Attempts to connect to the Owncast websocket and auto-reconnect with backoff
|
||||
|
||||
Args:
|
||||
url (str): The websocket service url to connect to.
|
||||
retries (int): The maximum number of reconnect attemps before failing.
|
||||
initial_backoff (float): The base amount of reconnection backoff time in seconds
|
||||
|
||||
Returns:
|
||||
None
|
||||
"""
|
||||
|
||||
attempt = 0
|
||||
backoff = initial_backoff
|
||||
|
||||
while attempt < retries:
|
||||
ws = websocket.WebSocketApp(url,
|
||||
on_open=owncast_on_open,
|
||||
on_message=owncast_on_message,
|
||||
on_error=owncast_on_error,
|
||||
on_close=owncast_on_close
|
||||
)
|
||||
|
||||
try:
|
||||
ws.run_forever()
|
||||
except KeyboardInterrupt:
|
||||
print('\nInterrupted by user. Exiting.')
|
||||
sys.exit(0)
|
||||
|
||||
attempt += 1
|
||||
if attempt < retries:
|
||||
print(f'Reconnecting in {backoff:.1f}s ({attempt} of {retries})')
|
||||
time.sleep(backoff)
|
||||
backoff *= 2
|
||||
print(f'Max reconnect attempts reached. Exiting.')
|
||||
Reference in new issue
Block a user