cleanup, rate-limit, document

This commit is contained in:
Jan Koppe 2024-01-27 12:55:09 +01:00
parent 3082f36026
commit 8bb4af2e97
Signed by: thunfisch
GPG Key ID: BE935B0735A2129B
6 changed files with 37 additions and 32 deletions

9
Dockerfile Normal file
View File

@ -0,0 +1,9 @@
FROM python:alpine
ENV WORKERS=4
RUN mkdir /app && adduser -D app
WORKDIR /app
COPY requirements.txt /app
RUN pip install -r requirements.txt
COPY app.py /app
USER app
ENTRYPOINT ["sh", "-c","exec gunicorn -w $WORKERS -b 0.0.0.0 app:app"]

9
README.md Normal file
View File

@ -0,0 +1,9 @@
# spaceapi
Stupid implementation of [SpaceAPI](https://spaceapi.io/) for [Chaos-West TV](https://chaoswest.tv/).
As we don't have a physical space, we look at the current Jitsi Lounge status, and use that as an indicator for the space being open or closed.
## WTF.
Could this have been a cronjob, writing some JSON file to disk? Yes. But we're paying for the whole CPU, so we're gonna use the whole CPU, damnit!

View File

@ -1,11 +1,21 @@
from functools import lru_cache
import json import json
import time
import urllib.request import urllib.request
from flask import Flask, jsonify from flask import Flask, jsonify
app = Flask(__name__) app = Flask(__name__)
def get_jitsi_status(): @lru_cache(maxsize=1)
def get_jitsi_status(ttl_hash : int = 0) -> bool | None:
# ttl_hash is used to cache the result for a certain amount of time.
# This is done to rate-limit the outgoing requests to the jitsi server.
# Inspired by https://stackoverflow.com/a/55900800
# The jitsi server uses mod_census to provide a JSON representation of all
# currently active rooms. We can use this to check if the lounge is currently
# occupied.
try: try:
content = urllib.request.urlopen("https://talk.chaoswest.tv/room-census").read() content = urllib.request.urlopen("https://talk.chaoswest.tv/room-census").read()
census = json.loads(content) census = json.loads(content)
@ -15,6 +25,12 @@ def get_jitsi_status():
print(e) print(e)
return None return None
def get_ttl_hash(seconds : int = 1) -> int:
# Generates a monotonically increasing "hash" as time progresses
return round(time.time() / seconds)
@app.route("/spaceapi") @app.route("/spaceapi")
def spaceapi(): def spaceapi():
result = { result = {
@ -33,7 +49,7 @@ def spaceapi():
} }
} }
status = get_jitsi_status() status = get_jitsi_status(get_ttl_hash())
if status is not None: if status is not None:
result["state"] = { result["state"] = {

View File

@ -1,24 +0,0 @@
version: '3.8'
services:
spaceapi:
image: spaceapi
build:
context: src
networks:
- ingress
- default
deploy:
labels:
- "shepherd.auto-update=true"
- "traefik.enable=true"
- "traefik.http.services.spaceapi.loadbalancer.server.port=5000"
- "traefik.http.routers.spaceapi.rule=Host(`api.montage2.de`)||Host(`api.chaoswest.tv`)"
- "traefik.http.routers.spaceapi.tls=true"
- "traefik.http.routers.spaceapi.tls.certresolver=default"
networks:
ingress:
external: true
name: traefik

View File

@ -1 +1,2 @@
Flask>=3.0.1 Flask>=3.0.1
gunicorn

View File

@ -1,6 +0,0 @@
FROM python:alpine
RUN mkdir /app
WORKDIR /app
COPY . /app
RUN pip install -r requirements.txt
ENTRYPOINT ["flask", "--app", "app", "run", "--host=0.0.0.0"]