Compare commits
2 commits
9de7d20a18
...
30beb7cdaa
Author | SHA1 | Date | |
---|---|---|---|
30beb7cdaa | |||
303fd8b594 |
8 changed files with 179 additions and 8 deletions
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
@ -71,11 +72,17 @@ async def combineCSSResources(resources: str, response: Response):
|
|||
async def root():
|
||||
template = template_env.get_template("home.html")
|
||||
return template.render()
|
||||
@app.get("/about", response_class=HTMLResponse)
|
||||
async def root():
|
||||
template = template_env.get_template("about.html")
|
||||
return template.render()
|
||||
|
||||
|
||||
|
||||
@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 +140,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 +156,8 @@ async def search(
|
|||
**author,
|
||||
},
|
||||
timeout=10,
|
||||
proxies=PROXIES,
|
||||
headers=headers
|
||||
)
|
||||
if rq.status_code == 503:
|
||||
return error_template.render(
|
||||
|
@ -174,11 +186,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 +237,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 +262,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()
|
||||
|
|
|
@ -42,6 +42,19 @@
|
|||
font-size: larger;
|
||||
}
|
||||
|
||||
footer {
|
||||
display: flex;
|
||||
justify-content: space-evenly;
|
||||
padding: 0.5rem;
|
||||
font-size: small;
|
||||
}
|
||||
|
||||
footer > a {
|
||||
margin: 0em 1em;
|
||||
}
|
||||
|
||||
|
||||
.About {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
text-align: center;
|
||||
}
|
||||
|
|
22
iwm_browser/templates/about.html
Normal file
22
iwm_browser/templates/about.html
Normal file
|
@ -0,0 +1,22 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>IWM Browser</title>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<link rel="stylesheet" href="{{ combineCSS(
|
||||
'/static/index.css',
|
||||
'/static/main.css',
|
||||
'/static/homepage.css',
|
||||
) }}">
|
||||
</head>
|
||||
<body>
|
||||
<div class="Home About">
|
||||
<div class="contentBox_">
|
||||
<h1>You're on IWM Browser, </h1>
|
||||
<h2>a service for displaying <a href="https://iwannamakergame.com">I Wanna Maker</a> online levels in your browser.</h2>
|
||||
<p>You can find the source code <a href="https://git.magmaus3.eu.org/magmaus3/iwm_browser">here</a>.</p>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
|
@ -58,6 +58,7 @@
|
|||
<div class="tileBox"><a href="/search?q=&sort=created_at&dir=desc&date=-1&type=Recent">Recent ❓</a></div>
|
||||
<div class="tileBox"><a href="/search">Search 🔍</a></div>
|
||||
</div>
|
||||
<footer><a href="/about">About</a><a href="https://git.magmaus3.eu.org/magmaus3/iwm_browser">Source Code</a></footer>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
|
|
|
@ -27,7 +27,7 @@
|
|||
<div class="Search">
|
||||
<div class="contentBox_">
|
||||
<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>
|
||||
<p>ID: {{ response.ID }}</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