Deploy folkugat web
This commit is contained in:
@@ -6,6 +6,7 @@ from fastapi.responses import HTMLResponse
|
||||
from folkugat_web.api import router
|
||||
from folkugat_web.fragments import tema, temes
|
||||
from folkugat_web.services import auth
|
||||
from folkugat_web.services import files as files_service
|
||||
from folkugat_web.services.temes import links as links_service
|
||||
from folkugat_web.services.temes import lyrics as lyrics_service
|
||||
from folkugat_web.services.temes import properties as properties_service
|
||||
@@ -46,6 +47,7 @@ def contingut(request: Request, logged_in: auth.LoggedIn, tema_id: int):
|
||||
@router.delete("/api/tema/{tema_id}")
|
||||
def delete_tema(_: auth.RequireLogin, tema_id: int):
|
||||
temes_w.delete_tema(tema_id=tema_id)
|
||||
files_service.clean_orphan_files()
|
||||
return HTMLResponse(headers={
|
||||
'HX-Redirect': '/temes'
|
||||
})
|
||||
|
||||
@@ -6,8 +6,10 @@ from fastapi.responses import HTMLResponse
|
||||
from folkugat_web.api import router
|
||||
from folkugat_web.fragments.tema import links as links_fragments
|
||||
from folkugat_web.model import temes as model
|
||||
from folkugat_web.services import auth, files
|
||||
from folkugat_web.services import auth
|
||||
from folkugat_web.services import files as files_service
|
||||
from folkugat_web.services.temes import links as links_service
|
||||
from folkugat_web.services.temes import query as temes_q
|
||||
|
||||
|
||||
@router.get("/api/tema/{tema_id}/link/{link_id}")
|
||||
@@ -30,7 +32,7 @@ async def set_link(
|
||||
upload_file: Annotated[UploadFile | None, File()] = None,
|
||||
):
|
||||
if upload_file:
|
||||
url = await files.store_file(tema_id=tema_id, upload_file=upload_file)
|
||||
url = await files_service.store_file(tema_id=tema_id, upload_file=upload_file)
|
||||
|
||||
link_type = links_service.guess_link_type(url or '')
|
||||
new_link = model.Link(
|
||||
@@ -66,6 +68,7 @@ def delete_link(
|
||||
link_id: int,
|
||||
):
|
||||
links_service.delete_link(link_id=link_id, tema_id=tema_id)
|
||||
files_service.clean_orphan_files()
|
||||
return HTMLResponse(
|
||||
headers={
|
||||
"HX-Trigger": f"reload-tema-{tema_id}-score"
|
||||
@@ -102,10 +105,14 @@ def get_score(
|
||||
logged_in: auth.LoggedIn,
|
||||
tema_id: int,
|
||||
):
|
||||
tema = temes_q.get_tema_by_id(tema_id)
|
||||
if not tema:
|
||||
raise HTTPException(status_code=404, detail="Could not find tune")
|
||||
tema = links_service.add_links_to_tema(tema)
|
||||
return links_fragments.score(
|
||||
request=request,
|
||||
logged_in=logged_in,
|
||||
tema_id=tema_id,
|
||||
tema=tema,
|
||||
)
|
||||
|
||||
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -1,5 +1,5 @@
|
||||
<div class="h-4/5 min-h-[400px] flex flex-col items-center justify-center">
|
||||
<img src="{{ url_for('static', path='img/folkugat.svg') }}"
|
||||
<img src="{{ url_for(request, 'static', path='img/folkugat.svg') }}"
|
||||
class="{% if animate %} opacity-0 animate-fade-in-one {% endif %} m-3"
|
||||
width="100"
|
||||
alt="Folkugat"/>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<!-- PDF Viewer -->
|
||||
<script type="module">
|
||||
const pdfViewer = await import("{{ url_for('static', path='js/pdf_viewer.js') }}");
|
||||
const pdfViewer = await import("{{ url_for(request, 'static', path='js/pdf_viewer.js') }}");
|
||||
const options = {
|
||||
url: '{{ pdf_url }}',
|
||||
// PDF Canvas (where the pdf will be displayed)
|
||||
@@ -24,13 +24,13 @@
|
||||
<!-- </a> -->
|
||||
<!-- </div> -->
|
||||
<div class="flex flex-row flex-nowrap items-center justify-center w-full">
|
||||
<button id="prev" class="flex-none text-xl text-beige mx-3">
|
||||
<button id="prev" class="flex-none text-xl text-beige mr-2">
|
||||
<i class="fa fa-chevron-left" aria-hidden="true"></i>
|
||||
</button>
|
||||
<canvas class="flex-auto m-2 w-1/2 max-w-3xl"
|
||||
id="the-canvas">
|
||||
</canvas>
|
||||
<button id="next" class="flex-none text-xl text-beige mx-3">
|
||||
<button id="next" class="flex-none text-xl text-beige ml-2">
|
||||
<i class="fa fa-chevron-right" aria-hidden="true"></i>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
@@ -14,15 +14,15 @@
|
||||
referrerpolicy="no-referrer" />
|
||||
|
||||
<!-- Taiwind CSS -->
|
||||
<link rel="stylesheet" href="{{ url_for('static', path='css/main.css') }}" type="text/css" />
|
||||
<link rel="stylesheet" href="{{ url_for(request, 'static', path='css/main.css') }}" type="text/css" />
|
||||
|
||||
<!-- HTMX -->
|
||||
<script src="{{ url_for('static', path='js/htmx.min.js') }}"></script>
|
||||
<script src="{{ url_for(request, 'static', path='js/htmx.min.js') }}"></script>
|
||||
|
||||
<!-- Favicon! -->
|
||||
<link rel="apple-touch-icon" sizes="180x180" href="{{ url_for('static', path='favicon/apple-touch-icon.png') }}">
|
||||
<link rel="icon" type="image/png" sizes="32x32" href="{{ url_for('static', path='favicon/favicon-32x32.png') }}">
|
||||
<link rel="icon" type="image/png" sizes="16x16" href="{{ url_for('static', path='favicon/favicon-16x16.png') }}">
|
||||
<link rel="apple-touch-icon" sizes="180x180" href="{{ url_for(request, 'static', path='favicon/apple-touch-icon.png') }}">
|
||||
<link rel="icon" type="image/png" sizes="32x32" href="{{ url_for(request, 'static', path='favicon/favicon-32x32.png') }}">
|
||||
<link rel="icon" type="image/png" sizes="16x16" href="{{ url_for(request, 'static', path='favicon/favicon-16x16.png') }}">
|
||||
<link rel="manifest" href="/site.webmanifest">
|
||||
|
||||
</head>
|
||||
|
||||
3
folkugat_web/config/api.py
Normal file
3
folkugat_web/config/api.py
Normal file
@@ -0,0 +1,3 @@
|
||||
import os
|
||||
|
||||
URL_SCHEME = os.getenv("URL_SCHEME", "http")
|
||||
@@ -1,7 +1,5 @@
|
||||
from fastapi import HTTPException, Request
|
||||
from fastapi import Request
|
||||
from folkugat_web.model import temes as model
|
||||
from folkugat_web.services.temes import query as temes_q
|
||||
from folkugat_web.services.temes.links import guess_link_type
|
||||
from folkugat_web.templates import templates
|
||||
|
||||
|
||||
@@ -73,10 +71,7 @@ def link_icon(request: Request, logged_in: bool, link: model.Link):
|
||||
)
|
||||
|
||||
|
||||
def score(request: Request, logged_in: bool, tema_id: int):
|
||||
tema = temes_q.get_tema_by_id(tema_id)
|
||||
if not tema:
|
||||
raise HTTPException(status_code=404, detail="Could not find tune")
|
||||
def score(request: Request, logged_in: bool, tema: model.Tema):
|
||||
return templates.TemplateResponse(
|
||||
"fragments/tema/score.html",
|
||||
{
|
||||
|
||||
@@ -90,4 +90,10 @@ class Tema:
|
||||
return link.link_type is LinkType.IMAGE
|
||||
|
||||
def score(self) -> Link | None:
|
||||
return next(filter(self._is_score, self.links), None)
|
||||
result = next(filter(self._is_score, self.links), None)
|
||||
return result
|
||||
|
||||
|
||||
class TemaCols(enum.Enum):
|
||||
NOM = "nom"
|
||||
COPS_TOCAT = "cops_tocat"
|
||||
|
||||
@@ -1,11 +1,15 @@
|
||||
import mimetypes
|
||||
import os
|
||||
import re
|
||||
import uuid
|
||||
from collections.abc import Iterator
|
||||
from pathlib import Path
|
||||
|
||||
import magic
|
||||
from fastapi import HTTPException, UploadFile
|
||||
from folkugat_web.config import db
|
||||
from folkugat_web.dal.sql.temes import links as links_dal
|
||||
from folkugat_web.log import logger
|
||||
|
||||
|
||||
async def get_mimetype(upload_file: UploadFile) -> str:
|
||||
@@ -56,3 +60,17 @@ async def store_file(tema_id: int, upload_file: UploadFile) -> str:
|
||||
def list_files(tema_id: str) -> list[str]:
|
||||
filedir = db.DB_FILES_DIR / str(tema_id)
|
||||
return [get_db_file_path(f) for f in filedir.iterdir()]
|
||||
|
||||
|
||||
def get_orphan_files() -> Iterator[Path]:
|
||||
alive_files = {link.url for link in links_dal.get_links()}
|
||||
return filter(
|
||||
lambda p: p.is_file() and get_db_file_path(p) not in alive_files,
|
||||
db.DB_FILES_DIR.rglob("*"),
|
||||
)
|
||||
|
||||
|
||||
def clean_orphan_files():
|
||||
for path in get_orphan_files():
|
||||
logger.info(f"Deleting the orphan file: {path}")
|
||||
os.remove(path)
|
||||
|
||||
@@ -1,27 +1,31 @@
|
||||
from typing import Optional
|
||||
|
||||
from folkugat_web.dal.sql import Connection
|
||||
from folkugat_web.dal.sql._connection import get_connection
|
||||
from folkugat_web.dal.sql.playlists import query, write
|
||||
from folkugat_web.log import logger
|
||||
from folkugat_web.model import playlists
|
||||
from folkugat_web.services.temes import links as links_service
|
||||
from folkugat_web.services.temes import query as temes_query
|
||||
|
||||
|
||||
def add_temes_to_playlist(playlist: playlists.Playlist) -> playlists.Playlist:
|
||||
for set_ in playlist.sets:
|
||||
add_temes_to_set(set_)
|
||||
_ = add_temes_to_set(set_)
|
||||
return playlist
|
||||
|
||||
|
||||
def add_temes_to_set(set_: playlists.Set) -> playlists.Set:
|
||||
for tema_in_set in set_.temes:
|
||||
add_tema_to_tema_in_set(tema_in_set)
|
||||
_ = add_tema_to_tema_in_set(tema_in_set)
|
||||
return set_
|
||||
|
||||
|
||||
def add_tema_to_tema_in_set(tema_in_set: playlists.TemaInSet) -> playlists.TemaInSet:
|
||||
if tema_in_set.tema_id is not None:
|
||||
tema_in_set.tema = temes_query.get_tema_by_id(tema_in_set.tema_id)
|
||||
if not tema_in_set.tema:
|
||||
logger.error("fCould not load tune in set: {tema_in_set}")
|
||||
else:
|
||||
_ = links_service.add_links_to_tema(tema_in_set.tema)
|
||||
return tema_in_set
|
||||
|
||||
|
||||
|
||||
@@ -84,7 +84,6 @@ def _apply_limit_offset(limit: int, offset: int) -> Callable[[Iterable[model.Tem
|
||||
|
||||
def busca_temes(query: str, hidden: bool = False, limit: int = 10, offset: int = 0) -> list[model.Tema]:
|
||||
t0 = time.time()
|
||||
|
||||
with get_connection() as con:
|
||||
result = (
|
||||
FnChain.transform(temes_q.get_tema_id_to_ngrams(con).items()) |
|
||||
|
||||
@@ -1,5 +1,20 @@
|
||||
from typing import Any
|
||||
|
||||
from fastapi import Request
|
||||
from fastapi.templating import Jinja2Templates
|
||||
|
||||
from folkugat_web.config import directories as config
|
||||
from folkugat_web.config import api as api_config
|
||||
from folkugat_web.config import directories as directories_config
|
||||
|
||||
templates = Jinja2Templates(directory=config.TEMPLATES_DIR)
|
||||
templates = Jinja2Templates(directory=directories_config.TEMPLATES_DIR)
|
||||
|
||||
|
||||
def url_for(request: Request, name: str, **path_params: Any) -> str:
|
||||
http_url = request.url_for(name, **path_params)
|
||||
if api_config.URL_SCHEME == "http":
|
||||
return str(http_url)
|
||||
# Replace 'http' with 'https'
|
||||
return str(http_url.replace(scheme=api_config.URL_SCHEME))
|
||||
|
||||
|
||||
templates.env.globals["url_for"] = url_for
|
||||
|
||||
Reference in New Issue
Block a user