54 lines
2.0 KiB
Python
54 lines
2.0 KiB
Python
|
|
import re
|
||
|
|
|
||
|
|
with open("app/modules/manual/frontend/views.py", "r") as f:
|
||
|
|
text = f.read()
|
||
|
|
|
||
|
|
# Make sure cache is imported
|
||
|
|
if "manual_cache" not in text:
|
||
|
|
text = text.replace("from app.core.database import", "from app.modules.manual.backend.cache import manual_cache\nfrom app.core.database import")
|
||
|
|
|
||
|
|
# GET /manual
|
||
|
|
list_patch = """async def manual_index(
|
||
|
|
request: Request,
|
||
|
|
module: Optional[str] = Query(default=None),
|
||
|
|
difficulty: Optional[str] = Query(default=None),
|
||
|
|
tag: Optional[str] = Query(default=None),
|
||
|
|
search: Optional[str] = Query(default=None),
|
||
|
|
):
|
||
|
|
cache_key = f"views:list:{module}:{difficulty}:{tag}:{search}"
|
||
|
|
cached = manual_cache.get(cache_key)
|
||
|
|
if cached:
|
||
|
|
# FastAPI TemplateResponse returns HTMLResponse which we can't easily cache natively
|
||
|
|
# But we can cache the context dictionary to avoid DB queries
|
||
|
|
rows, modules, unique_tags = cached
|
||
|
|
else:"""
|
||
|
|
|
||
|
|
text = re.sub(
|
||
|
|
r'async def manual_index\([^)]*\):',
|
||
|
|
list_patch,
|
||
|
|
text
|
||
|
|
)
|
||
|
|
|
||
|
|
# Need to indent the whole db fetch logic
|
||
|
|
# Then we save it to cache.
|
||
|
|
# Alternatively, I can just use a simple python caching decorator in `views.py`. Since we share the manual_cache instance, we can just clear it.
|
||
|
|
text = text.replace(' return templates.TemplateResponse(', ' manual_cache.set(cache_key, (rows, modules, unique_tags))\n return templates.TemplateResponse(')
|
||
|
|
# Indenting the execute_query part cleanly using re.sub is hard. Let's do it using Python string replacement
|
||
|
|
lines = text.split('\n')
|
||
|
|
in_else = False
|
||
|
|
new_lines = []
|
||
|
|
for line in lines:
|
||
|
|
if 'else:' in line and 'manual_index' not in line: # crude check
|
||
|
|
if 'rows, modules, unique_tags = cached' in '\n'.join(new_lines[-5:]):
|
||
|
|
in_else = True
|
||
|
|
if in_else:
|
||
|
|
if line.startswith(' return templates.TemplateResponse('):
|
||
|
|
in_else = False
|
||
|
|
else:
|
||
|
|
if line.startswith(' '):
|
||
|
|
line = ' ' + line
|
||
|
|
new_lines.append(line)
|
||
|
|
|
||
|
|
with open("app/modules/manual/frontend/views.py", "w") as f:
|
||
|
|
f.write("\n".join(new_lines))
|