diff --git a/Dockerfile b/Dockerfile index 90d20fc..46a8f22 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,8 @@ FROM python:3.10 +ENV TINI_VERSION v0.19.0 +ADD https://github.com/krallin/tini/releases/download/${TINI_VERSION}/tini /tini +RUN chmod +x /tini +ENTRYPOINT ["/tini", "--"] WORKDIR /app diff --git a/docker-compose.yml b/docker-compose.yml index 4cd019a..4a10424 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -8,5 +8,16 @@ services: environment: - IWM_SERVER="http://make.fangam.es" - IWM_THUMBNAILS="https://images.make.fangam.es" - - IMGPROXY_URL="http://127.0.0.1:8080" + - IMGPROXY_URL="http://127.0.0.1:5851" - IMGPROXY_PARAMS="{\"advanced\":[\"q:50\"]}" + - 'HTTP_PROXIES={"all://make.fangam.es": "http://squid:3128"}' + imgproxy: + image: 'darthsim/imgproxy' + ports: + - 5851:8080 + squid: + image: 'ubuntu/squid' + environment: + - TZ=UTC + volumes: + - ./squid.conf:/etc/squid/squid.conf diff --git a/iwm_browser/main.py b/iwm_browser/main.py index 6a0b0a7..3c6995d 100644 --- a/iwm_browser/main.py +++ b/iwm_browser/main.py @@ -1,7 +1,7 @@ from typing import Union from fastapi.staticfiles import StaticFiles from fastapi.middleware.gzip import GZipMiddleware -from fastapi.responses import HTMLResponse, PlainTextResponse +from fastapi.responses import HTMLResponse, PlainTextResponse, RedirectResponse from fastapi import FastAPI, Form, Response from typing import Optional import urllib.parse @@ -28,7 +28,6 @@ template_env = jinja2.Environment( error_template = template_env.get_template("error.html") - template_env.globals["builtins"] = __builtins__ template_env.globals["convert_times"] = utils.convert_times template_env.globals["json_dumps"] = json.dumps @@ -46,6 +45,8 @@ utils.global_imgproxy_params = json.loads(utils.config_value("IMGPROXY_PARAMS", "advanced": ["q:50"], }''')) # Set it to None to disable the proxy params +PROXIES = utils.config_value("HTTP_PROXIES", '{}') + # Matches level code. # \S[A-Z0-9]{4}\-[A-Z0-9]{4} = With dash, no whitespace # \S[A-Z0-9]{8} = without dash, no whitespace @@ -76,6 +77,7 @@ async def root(): @app.get("/search", response_class=HTMLResponse) async def search( request: starlette.requests.Request, + response: Response, q: Union[str, None] = None, p: int = 0, sort: str = "average_rating", @@ -133,6 +135,9 @@ async def search( searchValue = q try: + headers = {} + if sort == "random": + headers["Cache-Control"] = "no-cache" rq = httpx.get( BASE_URL + "/api/v1/map", params={ @@ -146,6 +151,8 @@ async def search( **author, }, timeout=10, + proxies=PROXIES, + headers=headers ) if rq.status_code == 503: return error_template.render( @@ -174,11 +181,31 @@ async def search( QueryValues=QueryValues, ) +@app.get("/playlist/featured") +async def get_featured_list(): + try: + rq = httpx.get(BASE_URL + "/api/v1/featuredlist", timeout=10, proxies=PROXIES) + if rq.status_code == 503: + return error_template.render(reason="Server is unavailable right now") + response = rq.json() + + except httpx.ReadTimeout: + return error_template.render(reason="Server timed out") + except json.decoder.JSONDecodeError: + return error_template.render( + reason="Failed to parse server response.", details=rq.text + ) + except Exception as exc: + return error_template.render(reason="Uncaught exception", details=exc) + + + return RedirectResponse("/playlist/" + str(response["ListID"])) + @app.get("/playlist/{playlist_id}", response_class=HTMLResponse) async def showList(request: starlette.requests.Request, playlist_id: int): template = template_env.get_template("playlist.html") try: - rq = httpx.get(BASE_URL + "/api/v1/list/" + str(playlist_id), timeout=10) + rq = httpx.get(BASE_URL + "/api/v1/list/" + str(playlist_id), timeout=10, proxies=PROXIES) if rq.status_code == 503: return error_template.render(reason="Server is unavailable right now") response = rq.json() @@ -205,7 +232,7 @@ async def showLevel(level_id: int): template = template_env.get_template("levelInfo.html") try: - rq = httpx.get(BASE_URL + "/api/v1/map/" + str(level_id), timeout=10) + rq = httpx.get(BASE_URL + "/api/v1/map/" + str(level_id), timeout=10, proxies=PROXIES) if rq.status_code == 503: return error_template.render(reason="Server is unavailable right now") searchResults = rq.json() @@ -230,7 +257,7 @@ async def showUser(user_id: int): template = template_env.get_template("userInfo.html") try: - rq = httpx.get(BASE_URL + "/api/v1/user/" + str(user_id), timeout=10) + rq = httpx.get(BASE_URL + "/api/v1/user/" + str(user_id), timeout=10, proxies=PROXIES) if rq.status_code == 503: return error_template.render(reason="Server is unavailable right now") searchResults = rq.json() diff --git a/iwm_browser/templates/playlist.html b/iwm_browser/templates/playlist.html index df053b7..d1ef9d8 100644 --- a/iwm_browser/templates/playlist.html +++ b/iwm_browser/templates/playlist.html @@ -27,7 +27,7 @@