Featured list endpoint, squid proxy caching etc.
This commit is contained in:
parent
9de7d20a18
commit
303fd8b594
5 changed files with 137 additions and 7 deletions
|
@ -1,4 +1,8 @@
|
||||||
FROM python:3.10
|
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
|
WORKDIR /app
|
||||||
|
|
||||||
|
|
|
@ -8,5 +8,16 @@ services:
|
||||||
environment:
|
environment:
|
||||||
- IWM_SERVER="http://make.fangam.es"
|
- IWM_SERVER="http://make.fangam.es"
|
||||||
- IWM_THUMBNAILS="https://images.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\"]}"
|
- 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
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
from typing import Union
|
from typing import Union
|
||||||
from fastapi.staticfiles import StaticFiles
|
from fastapi.staticfiles import StaticFiles
|
||||||
from fastapi.middleware.gzip import GZipMiddleware
|
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 fastapi import FastAPI, Form, Response
|
||||||
from typing import Optional
|
from typing import Optional
|
||||||
import urllib.parse
|
import urllib.parse
|
||||||
|
@ -28,7 +28,6 @@ template_env = jinja2.Environment(
|
||||||
|
|
||||||
error_template = template_env.get_template("error.html")
|
error_template = template_env.get_template("error.html")
|
||||||
|
|
||||||
|
|
||||||
template_env.globals["builtins"] = __builtins__
|
template_env.globals["builtins"] = __builtins__
|
||||||
template_env.globals["convert_times"] = utils.convert_times
|
template_env.globals["convert_times"] = utils.convert_times
|
||||||
template_env.globals["json_dumps"] = json.dumps
|
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"],
|
"advanced": ["q:50"],
|
||||||
}''')) # Set it to None to disable the proxy params
|
}''')) # Set it to None to disable the proxy params
|
||||||
|
|
||||||
|
PROXIES = utils.config_value("HTTP_PROXIES", '{}')
|
||||||
|
|
||||||
# Matches level code.
|
# Matches level code.
|
||||||
# \S[A-Z0-9]{4}\-[A-Z0-9]{4} = With dash, no whitespace
|
# \S[A-Z0-9]{4}\-[A-Z0-9]{4} = With dash, no whitespace
|
||||||
# \S[A-Z0-9]{8} = without 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)
|
@app.get("/search", response_class=HTMLResponse)
|
||||||
async def search(
|
async def search(
|
||||||
request: starlette.requests.Request,
|
request: starlette.requests.Request,
|
||||||
|
response: Response,
|
||||||
q: Union[str, None] = None,
|
q: Union[str, None] = None,
|
||||||
p: int = 0,
|
p: int = 0,
|
||||||
sort: str = "average_rating",
|
sort: str = "average_rating",
|
||||||
|
@ -133,6 +135,9 @@ async def search(
|
||||||
|
|
||||||
searchValue = q
|
searchValue = q
|
||||||
try:
|
try:
|
||||||
|
headers = {}
|
||||||
|
if sort == "random":
|
||||||
|
headers["Cache-Control"] = "no-cache"
|
||||||
rq = httpx.get(
|
rq = httpx.get(
|
||||||
BASE_URL + "/api/v1/map",
|
BASE_URL + "/api/v1/map",
|
||||||
params={
|
params={
|
||||||
|
@ -146,6 +151,8 @@ async def search(
|
||||||
**author,
|
**author,
|
||||||
},
|
},
|
||||||
timeout=10,
|
timeout=10,
|
||||||
|
proxies=PROXIES,
|
||||||
|
headers=headers
|
||||||
)
|
)
|
||||||
if rq.status_code == 503:
|
if rq.status_code == 503:
|
||||||
return error_template.render(
|
return error_template.render(
|
||||||
|
@ -174,11 +181,31 @@ async def search(
|
||||||
QueryValues=QueryValues,
|
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)
|
@app.get("/playlist/{playlist_id}", response_class=HTMLResponse)
|
||||||
async def showList(request: starlette.requests.Request, playlist_id: int):
|
async def showList(request: starlette.requests.Request, playlist_id: int):
|
||||||
template = template_env.get_template("playlist.html")
|
template = template_env.get_template("playlist.html")
|
||||||
try:
|
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:
|
if rq.status_code == 503:
|
||||||
return error_template.render(reason="Server is unavailable right now")
|
return error_template.render(reason="Server is unavailable right now")
|
||||||
response = rq.json()
|
response = rq.json()
|
||||||
|
@ -205,7 +232,7 @@ async def showLevel(level_id: int):
|
||||||
template = template_env.get_template("levelInfo.html")
|
template = template_env.get_template("levelInfo.html")
|
||||||
|
|
||||||
try:
|
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:
|
if rq.status_code == 503:
|
||||||
return error_template.render(reason="Server is unavailable right now")
|
return error_template.render(reason="Server is unavailable right now")
|
||||||
searchResults = rq.json()
|
searchResults = rq.json()
|
||||||
|
@ -230,7 +257,7 @@ async def showUser(user_id: int):
|
||||||
template = template_env.get_template("userInfo.html")
|
template = template_env.get_template("userInfo.html")
|
||||||
|
|
||||||
try:
|
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:
|
if rq.status_code == 503:
|
||||||
return error_template.render(reason="Server is unavailable right now")
|
return error_template.render(reason="Server is unavailable right now")
|
||||||
searchResults = rq.json()
|
searchResults = rq.json()
|
||||||
|
|
|
@ -27,7 +27,7 @@
|
||||||
<div class="Search">
|
<div class="Search">
|
||||||
<div class="contentBox_">
|
<div class="contentBox_">
|
||||||
<div class="playlist-details">
|
<div class="playlist-details">
|
||||||
<h1>{{ QueryValues.name if QueryValues.name}}{{ "Playlist" if not QueryValues.name}} </h1>
|
<h1>{{ response.Name }} </h1>
|
||||||
<h2>by <a href="/user/{{ response.CreatorID }}">{{ response.CreatorName }}</a></h2>
|
<h2>by <a href="/user/{{ response.CreatorID }}">{{ response.CreatorName }}</a></h2>
|
||||||
<p>ID: {{ response.ID }}</p>
|
<p>ID: {{ response.ID }}</p>
|
||||||
<p>Maps: {{ response.MapCount }}</p>
|
<p>Maps: {{ response.MapCount }}</p>
|
||||||
|
|
88
squid.conf
Normal file
88
squid.conf
Normal file
|
@ -0,0 +1,88 @@
|
||||||
|
#
|
||||||
|
# Recommended minimum configuration:
|
||||||
|
#
|
||||||
|
|
||||||
|
# Example rule allowing access from your local networks.
|
||||||
|
# Adapt to list your (internal) IP networks from where browsing
|
||||||
|
# should be allowed
|
||||||
|
acl localnet src 0.0.0.1-0.255.255.255 # RFC 1122 "this" network (LAN)
|
||||||
|
acl localnet src 10.0.0.0/8 # RFC 1918 local private network (LAN)
|
||||||
|
acl localnet src 100.64.0.0/10 # RFC 6598 shared address space (CGN)
|
||||||
|
acl localnet src 169.254.0.0/16 # RFC 3927 link-local (directly plugged) machines
|
||||||
|
acl localnet src 172.16.0.0/12 # RFC 1918 local private network (LAN)
|
||||||
|
acl localnet src 192.168.0.0/16 # RFC 1918 local private network (LAN)
|
||||||
|
acl localnet src fc00::/7 # RFC 4193 local private network range
|
||||||
|
acl localnet src fe80::/10 # RFC 4291 link-local (directly plugged) machines
|
||||||
|
|
||||||
|
acl SSL_ports port 443
|
||||||
|
acl Safe_ports port 80 # http
|
||||||
|
# acl Safe_ports port 21 # ftp
|
||||||
|
acl Safe_ports port 443 # https
|
||||||
|
# acl Safe_ports port 70 # gopher
|
||||||
|
# acl Safe_ports port 210 # wais
|
||||||
|
# acl Safe_ports port 1025-65535 # unregistered ports
|
||||||
|
# acl Safe_ports port 280 # http-mgmt
|
||||||
|
# acl Safe_ports port 488 # gss-http
|
||||||
|
# acl Safe_ports port 591 # filemaker
|
||||||
|
# acl Safe_ports port 777 # multiling http
|
||||||
|
|
||||||
|
#
|
||||||
|
# Recommended minimum Access Permission configuration:
|
||||||
|
#
|
||||||
|
# Deny requests to certain unsafe ports
|
||||||
|
http_access deny !Safe_ports
|
||||||
|
|
||||||
|
# Deny CONNECT to other than secure SSL ports
|
||||||
|
http_access deny CONNECT !SSL_ports
|
||||||
|
|
||||||
|
# Only allow cachemgr access from localhost
|
||||||
|
http_access allow localhost manager
|
||||||
|
http_access deny manager
|
||||||
|
|
||||||
|
# This default configuration only allows localhost requests because a more
|
||||||
|
# permissive Squid installation could introduce new attack vectors into the
|
||||||
|
# network by proxying external TCP connections to unprotected services.
|
||||||
|
http_access allow localhost
|
||||||
|
|
||||||
|
# The two deny rules below are unnecessary in this default configuration
|
||||||
|
# because they are followed by a "deny all" rule. However, they may become
|
||||||
|
# critically important when you start allowing external requests below them.
|
||||||
|
|
||||||
|
# Protect web applications running on the same server as Squid. They often
|
||||||
|
# assume that only local users can access them at "localhost" ports.
|
||||||
|
http_access deny to_localhost
|
||||||
|
|
||||||
|
# Protect cloud servers that provide local users with sensitive info about
|
||||||
|
# their server via certain well-known link-local (a.k.a. APIPA) addresses.
|
||||||
|
# http_access deny to_linklocal
|
||||||
|
|
||||||
|
#
|
||||||
|
# INSERT YOUR OWN RULE(S) HERE TO ALLOW ACCESS FROM YOUR CLIENTS
|
||||||
|
#
|
||||||
|
|
||||||
|
http_access allow localnet
|
||||||
|
|
||||||
|
# For example, to allow access from your local networks, you may uncomment the
|
||||||
|
# following rule (and/or add rules that match your definition of "local"):
|
||||||
|
# http_access allow localnet
|
||||||
|
|
||||||
|
# And finally deny all other access to this proxy
|
||||||
|
http_access deny all
|
||||||
|
|
||||||
|
# Squid normally listens to port 3128
|
||||||
|
http_port 3128
|
||||||
|
|
||||||
|
# Uncomment and adjust the following to add a disk cache directory.
|
||||||
|
#cache_dir ufs /var/cache/squid 100 16 256
|
||||||
|
|
||||||
|
# Leave coredumps in the first cache dir
|
||||||
|
coredump_dir /var/cache/squid
|
||||||
|
|
||||||
|
max_filedescriptors 16384
|
||||||
|
#
|
||||||
|
# Add any of your own refresh_pattern entries above these.
|
||||||
|
#
|
||||||
|
refresh_pattern ^ftp: 1440 20% 10080
|
||||||
|
refresh_pattern ^gopher: 1440 0% 1440
|
||||||
|
refresh_pattern -i (\?) 1 0% 10
|
||||||
|
refresh_pattern . 0 20% 4320
|
Loading…
Reference in a new issue