load static files into memory when not in dev mode

This commit is contained in:
Izalia Mae 2024-03-15 21:15:54 -04:00
parent 8b738dd365
commit f488d661d7

View file

@ -8,9 +8,12 @@ import traceback
import typing import typing
from aiohttp import web from aiohttp import web
from aiohttp.web import StaticResource
from aiohttp_swagger import setup_swagger from aiohttp_swagger import setup_swagger
from aputils.signer import Signer from aputils.signer import Signer
from datetime import datetime, timedelta from datetime import datetime, timedelta
from mimetypes import guess_type
from pathlib import Path
from queue import Empty from queue import Empty
from threading import Event, Thread from threading import Event, Thread
@ -68,7 +71,13 @@ class Application(web.Application):
for path, view in VIEWS: for path, view in VIEWS:
self.router.add_view(path, view) self.router.add_view(path, view)
self.add_routes([web.static('/static', get_resource('frontend/static'))]) if dev:
static = StaticResource('/static', get_resource('frontend/static'))
else:
static = CachedStaticResource('/static', get_resource('frontend/static'))
self.router.register_resource(static)
setup_swagger( setup_swagger(
self, self,
@ -223,6 +232,39 @@ class Application(web.Application):
self['cache'].close() self['cache'].close()
class CachedStaticResource(StaticResource):
def __init__(self, prefix: str, path: Path):
StaticResource.__init__(self, prefix, path)
self.cache: dict[Path, bytes] = {}
for filename in path.rglob('*'):
if filename.is_dir():
continue
rel_path = str(filename.relative_to(path))
with filename.open('rb') as fd:
logging.debug('Loading static resource "%s"', rel_path)
self.cache[rel_path] = fd.read()
async def _handle(self, request: web.Request) -> web.StreamResponse:
rel_url = request.match_info['filename']
if Path(rel_url).anchor:
raise web.HTTPForbidden()
try:
return web.Response(
body = self.cache[rel_url],
content_type = guess_type(path)[0]
)
except KeyError:
raise web.HTTPNotFound()
class CacheCleanupThread(Thread): class CacheCleanupThread(Thread):
def __init__(self, app: Application): def __init__(self, app: Application):
Thread.__init__(self) Thread.__init__(self)