quotes_display/quotes.py

80 lines
2.2 KiB
Python

from rich.align import Align
from rich.console import Console
from rich.layout import Layout
from rich.live import Live
from rich.padding import Padding
from rich.text import Text
import json
import random
import requests
import signal
import time
from denylist import get_deny_list
denylist = get_deny_list()
class Usr1Interrupt(Exception):
def __init__(self, message):
super().__init__(message)
def handle_sigusr1(sig, frame):
raise Usr1Interrupt("")
signal.signal(signal.SIGUSR1, handle_sigusr1)
def refresh_quotes():
res = None
try:
# Fetch quotes
res = requests.get('https://mattermore.zeus.gent/quotes.json').json()
assert len(res) > 150
res = res[-150:]
except:
pass
if res is None:
# Fallback: load last quotes
try:
with open('last_quotes.json') as f:
res = json.load(f)
except:
assert False, "Failed to fetch quotes, and failed to load fallback json"
else:
try:
# Fetched successfully
# Save to disk for the fallback
with open('last_quotes.json', 'w') as f:
json.dump(res, f)
except:
pass
# Only keep non-denied quotes
res = [q for q in res if not any(denied in q['quote'] for denied in denylist)]
return res
def render_quote(quote):
for i in range(len(quote['quote'])):
l = Layout()
l.split_column(
Layout(f"Mattermost: ~{quote['channel']}", size=1),
Layout(Align.center(Padding(quote['quote'][:i+1], (0, 4)), vertical="middle")),
Layout(quote['created_at'][:10], size=1)
)
yield l
with Live(
renderable=Layout(Align.center(Text("Yeet"), vertical="middle")),
console=Console(highlighter=None),
refresh_per_second=30
) as live:
first_it = True
while True:
try:
quotes = refresh_quotes()
for _ in range(500):
for q in render_quote(random.choice(quotes) if not first_it else quotes[-1]):
live.update(q)
time.sleep(0.05)
time.sleep(30)
first_it = False
except Usr1Interrupt:
first_it = True
pass