Pàgines llista de reproducció
This commit is contained in:
@@ -1,14 +1,76 @@
|
|||||||
from typing import Annotated
|
from typing import Annotated
|
||||||
|
|
||||||
from fastapi import Form, Request
|
from fastapi import Form, HTTPException, Request
|
||||||
from folkugat_web.api.router import get_router
|
from folkugat_web.api.router import get_router
|
||||||
from folkugat_web.fragments import playlist
|
from folkugat_web.fragments import playlist
|
||||||
from folkugat_web.services import auth
|
from folkugat_web.services import auth
|
||||||
|
from folkugat_web.services import playlists as playlists_service
|
||||||
from folkugat_web.services.temes import write as temes_service
|
from folkugat_web.services.temes import write as temes_service
|
||||||
|
from folkugat_web.templates import templates
|
||||||
|
|
||||||
router = get_router()
|
router = get_router()
|
||||||
|
|
||||||
|
|
||||||
|
@router.get("/playlist/{playlist_id}")
|
||||||
|
def page(
|
||||||
|
request: Request,
|
||||||
|
logged_in: auth.LoggedIn,
|
||||||
|
playlist_id: int,
|
||||||
|
):
|
||||||
|
playlist = playlists_service.get_playlist(playlist_id=playlist_id)
|
||||||
|
if not playlist:
|
||||||
|
raise HTTPException(status_code=404, detail="Could not find playlist")
|
||||||
|
return templates.TemplateResponse(
|
||||||
|
"index.html",
|
||||||
|
{
|
||||||
|
"request": request,
|
||||||
|
"page_title": "Folkugat - Setlist",
|
||||||
|
"page_description": playlist.name or "Llista de temes",
|
||||||
|
"page_card": None,
|
||||||
|
"content": f"/api/content/playlist/{playlist_id}",
|
||||||
|
"logged_in": logged_in,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@router.get("/api/content/playlist/{playlist_id}")
|
||||||
|
def contingut(
|
||||||
|
request: Request,
|
||||||
|
logged_in: auth.LoggedIn,
|
||||||
|
playlist_id: int,
|
||||||
|
):
|
||||||
|
return playlist.pagina(request, playlist_id, logged_in)
|
||||||
|
|
||||||
|
|
||||||
|
@router.get("/api/playlist/{playlist_id}/name")
|
||||||
|
def get_name(
|
||||||
|
request: Request,
|
||||||
|
logged_in: auth.LoggedIn,
|
||||||
|
playlist_id: int,
|
||||||
|
):
|
||||||
|
return playlist.name(request=request, playlist_id=playlist_id, logged_in=logged_in)
|
||||||
|
|
||||||
|
|
||||||
|
@router.get("/api/playlist/{playlist_id}/editor/name")
|
||||||
|
def name_editor(
|
||||||
|
request: Request,
|
||||||
|
logged_in: auth.RequireLogin,
|
||||||
|
playlist_id: int,
|
||||||
|
):
|
||||||
|
return playlist.name_editor(request=request, playlist_id=playlist_id, logged_in=logged_in)
|
||||||
|
|
||||||
|
|
||||||
|
@router.put("/api/playlist/{playlist_id}/name")
|
||||||
|
def set_name(
|
||||||
|
request: Request,
|
||||||
|
logged_in: auth.RequireLogin,
|
||||||
|
playlist_id: int,
|
||||||
|
name: Annotated[str, Form()],
|
||||||
|
):
|
||||||
|
_ = playlists_service.update_name(playlist_id=playlist_id, name=name)
|
||||||
|
return playlist.name(request=request, playlist_id=playlist_id, logged_in=logged_in)
|
||||||
|
|
||||||
|
|
||||||
@router.post("/api/playlist/{playlist_id}/set")
|
@router.post("/api/playlist/{playlist_id}/set")
|
||||||
def add_set(
|
def add_set(
|
||||||
request: Request,
|
request: Request,
|
||||||
|
|||||||
@@ -0,0 +1,26 @@
|
|||||||
|
<div class="flex flex-row flex-wrap justify-center"
|
||||||
|
id="playlist-name">
|
||||||
|
<form>
|
||||||
|
<input name="name"
|
||||||
|
placeholder="Nom de la playlist"
|
||||||
|
value="{{ playlist.name if playlist.name else '' }}"
|
||||||
|
class="border border-beige focus:outline-none
|
||||||
|
rounded text-3xl
|
||||||
|
bg-brown p-2 m-0"
|
||||||
|
/>
|
||||||
|
<button title="Desa"
|
||||||
|
class="text-beige text-3xl mx-1"
|
||||||
|
hx-put="/api/playlist/{{ playlist.id }}/name"
|
||||||
|
hx-target="#playlist-name"
|
||||||
|
hx-swap="outerHTML">
|
||||||
|
<i class="fa fa-check" aria-hidden="true"></i>
|
||||||
|
</button>
|
||||||
|
<button title="Descarta"
|
||||||
|
class="text-beige text-3xl mx-1"
|
||||||
|
hx-get="/api/playlist/{{ playlist.id }}/name"
|
||||||
|
hx-target="#playlist-name"
|
||||||
|
hx-swap="outerHTML">
|
||||||
|
<i class="fa fa-times" aria-hidden="true"></i>
|
||||||
|
</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
19
folkugat_web/assets/templates/fragments/playlist/name.html
Normal file
19
folkugat_web/assets/templates/fragments/playlist/name.html
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
<div class="flex flex-row flex-wrap justify-center"
|
||||||
|
id="playlist-name">
|
||||||
|
<h3 class="text-3xl text-center p-4">
|
||||||
|
{% if playlist.name %}
|
||||||
|
{{ playlist.name }}
|
||||||
|
{% else %}
|
||||||
|
Llista de temes
|
||||||
|
{% endif %}
|
||||||
|
</h3>
|
||||||
|
{% if logged_in %}
|
||||||
|
<button title="Canvia el nom"
|
||||||
|
class="text-beige text-2xl mx-2"
|
||||||
|
hx-get="/api/playlist/{{ playlist.id }}/editor/name"
|
||||||
|
hx-target="#playlist-name"
|
||||||
|
hx-swap="outerHTML">
|
||||||
|
<i class="fa fa-pencil" aria-hidden="true"></i>
|
||||||
|
</button>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
13
folkugat_web/assets/templates/fragments/playlist/pagina.html
Normal file
13
folkugat_web/assets/templates/fragments/playlist/pagina.html
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
{% include "fragments/menu.html" %}
|
||||||
|
<div class="flex justify-center">
|
||||||
|
<div class="m-12 grow max-w-4xl">
|
||||||
|
<div id="playlist-name">
|
||||||
|
{% include "fragments/playlist/name.html" %}
|
||||||
|
</div>
|
||||||
|
<div class="text-left">
|
||||||
|
{% set playlist_id = playlist.id %}
|
||||||
|
{% set playlist = playlist %}
|
||||||
|
{% include "fragments/playlist/playlist.html" %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
@@ -39,7 +39,11 @@
|
|||||||
{% endif %}
|
{% endif %}
|
||||||
{% if logged_in or (session.slowjam and session.slowjam.sets) %}
|
{% if logged_in or (session.slowjam and session.slowjam.sets) %}
|
||||||
<div class="text-left">
|
<div class="text-left">
|
||||||
<h4 class="py-4 text-xl text-beige mt-2">Slow Jam</h4>
|
<h4 class="py-4 text-xl text-beige mt-2">
|
||||||
|
<a href="/playlist/{{ session.slowjam.id }}" class="text-beige">
|
||||||
|
Slow Jam
|
||||||
|
</a>
|
||||||
|
</h4>
|
||||||
{% set playlist_id = session.slowjam.id %}
|
{% set playlist_id = session.slowjam.id %}
|
||||||
{% set playlist = session.slowjam %}
|
{% set playlist = session.slowjam %}
|
||||||
{% include "fragments/playlist/playlist.html" %}
|
{% include "fragments/playlist/playlist.html" %}
|
||||||
@@ -47,7 +51,11 @@
|
|||||||
{% endif %}
|
{% endif %}
|
||||||
{% if logged_in or (session.setlist and session.setlist.sets) %}
|
{% if logged_in or (session.setlist and session.setlist.sets) %}
|
||||||
<div class="text-left">
|
<div class="text-left">
|
||||||
<h4 class="py-4 text-xl text-beige mt-2">Temes tocats</h4>
|
<h4 class="py-4 text-xl text-beige mt-2">
|
||||||
|
<a href="/playlist/{{ session.setlist.id }}" class="text-beige">
|
||||||
|
Temes tocats
|
||||||
|
</a>
|
||||||
|
</h4>
|
||||||
{% set playlist_id = session.setlist.id %}
|
{% set playlist_id = session.setlist.id %}
|
||||||
{% set playlist = session.setlist %}
|
{% set playlist = session.setlist %}
|
||||||
{% include "fragments/playlist/playlist.html" %}
|
{% include "fragments/playlist/playlist.html" %}
|
||||||
|
|||||||
@@ -55,3 +55,17 @@ def get_playlist_entries(
|
|||||||
cur = con.cursor()
|
cur = con.cursor()
|
||||||
_ = cur.execute(query, data)
|
_ = cur.execute(query, data)
|
||||||
return map(conversion.row_to_playlist_entry, cur.fetchall())
|
return map(conversion.row_to_playlist_entry, cur.fetchall())
|
||||||
|
|
||||||
|
|
||||||
|
def get_playlist_name(playlist_id: int, con: Connection | None = None) -> str | None:
|
||||||
|
query = """
|
||||||
|
SELECT name
|
||||||
|
FROM playlists
|
||||||
|
WHERE id = :playlist_id
|
||||||
|
"""
|
||||||
|
data = dict(playlist_id=playlist_id)
|
||||||
|
with get_connection(con) as con:
|
||||||
|
cur = con.cursor()
|
||||||
|
_ = cur.execute(query, data)
|
||||||
|
row = cur.fetchone()
|
||||||
|
return row[0] if row else None
|
||||||
|
|||||||
@@ -103,3 +103,20 @@ def delete_playlist_set(
|
|||||||
cur = con.cursor()
|
cur = con.cursor()
|
||||||
_ = cur.execute(query, data)
|
_ = cur.execute(query, data)
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
||||||
|
def update_playlist_name(
|
||||||
|
playlist_id: int,
|
||||||
|
name: str | None,
|
||||||
|
con: Connection | None = None,
|
||||||
|
):
|
||||||
|
query = """
|
||||||
|
UPDATE playlists SET
|
||||||
|
name = :name
|
||||||
|
WHERE id = :id
|
||||||
|
"""
|
||||||
|
data = dict(id=playlist_id, name=name)
|
||||||
|
with get_connection(con) as con:
|
||||||
|
cur = con.cursor()
|
||||||
|
_ = cur.execute(query, data)
|
||||||
|
return
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
from fastapi import Request
|
from fastapi import Request
|
||||||
from fastapi.responses import HTMLResponse
|
from fastapi.responses import HTMLResponse
|
||||||
|
from folkugat_web.model.pagines import Pages
|
||||||
|
from folkugat_web.model.playlists import PlaylistType
|
||||||
from folkugat_web.services import playlists as playlists_service
|
from folkugat_web.services import playlists as playlists_service
|
||||||
from folkugat_web.services import sessions as sessions_service
|
from folkugat_web.services import sessions as sessions_service
|
||||||
from folkugat_web.services.temes import query as query_service
|
from folkugat_web.services.temes import query as query_service
|
||||||
@@ -170,3 +172,54 @@ def set_tema(request: Request, logged_in: bool, playlist_id: int, set_id: int, e
|
|||||||
"tema_entry": tema_entry,
|
"tema_entry": tema_entry,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def pagina(request: Request, playlist_id: int, logged_in: bool):
|
||||||
|
playlist = playlists_service.get_playlist(playlist_id=playlist_id)
|
||||||
|
if not playlist:
|
||||||
|
from fastapi import HTTPException
|
||||||
|
raise HTTPException(status_code=404, detail="Could not find playlist")
|
||||||
|
playlist = playlists_service.add_temes_to_playlist(playlist)
|
||||||
|
return templates.TemplateResponse(
|
||||||
|
"fragments/playlist/pagina.html",
|
||||||
|
{
|
||||||
|
"request": request,
|
||||||
|
"logged_in": logged_in,
|
||||||
|
"playlist_id": playlist_id,
|
||||||
|
"playlist": playlist,
|
||||||
|
"Pages": Pages,
|
||||||
|
"PlaylistType": PlaylistType
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def name(request: Request, playlist_id: int, logged_in: bool):
|
||||||
|
playlist = playlists_service.get_playlist(playlist_id=playlist_id)
|
||||||
|
if not playlist:
|
||||||
|
from fastapi import HTTPException
|
||||||
|
raise HTTPException(status_code=404, detail="Could not find playlist")
|
||||||
|
return templates.TemplateResponse(
|
||||||
|
"fragments/playlist/name.html",
|
||||||
|
{
|
||||||
|
"request": request,
|
||||||
|
"logged_in": logged_in,
|
||||||
|
"playlist_id": playlist_id,
|
||||||
|
"playlist": playlist,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def name_editor(request: Request, playlist_id: int, logged_in: bool):
|
||||||
|
playlist = playlists_service.get_playlist(playlist_id=playlist_id)
|
||||||
|
if not playlist:
|
||||||
|
from fastapi import HTTPException
|
||||||
|
raise HTTPException(status_code=404, detail="Could not find playlist")
|
||||||
|
return templates.TemplateResponse(
|
||||||
|
"fragments/playlist/editor/name.html",
|
||||||
|
{
|
||||||
|
"request": request,
|
||||||
|
"logged_in": logged_in,
|
||||||
|
"playlist_id": playlist_id,
|
||||||
|
"playlist": playlist,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|||||||
@@ -79,6 +79,7 @@ class Set:
|
|||||||
@dataclasses.dataclass
|
@dataclasses.dataclass
|
||||||
class Playlist:
|
class Playlist:
|
||||||
id: int
|
id: int
|
||||||
|
name: str | None
|
||||||
sets: list[Set]
|
sets: list[Set]
|
||||||
|
|
||||||
def to_playlist_entries(self) -> Iterator[PlaylistEntry]:
|
def to_playlist_entries(self) -> Iterator[PlaylistEntry]:
|
||||||
@@ -86,11 +87,12 @@ class Playlist:
|
|||||||
yield from set_entry.to_playlist_entries(playlist_id=self.id)
|
yield from set_entry.to_playlist_entries(playlist_id=self.id)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def from_playlist_entries(cls, playlist_id: int, entries: list[PlaylistEntry]) -> Self:
|
def from_playlist_entries(cls, playlist_id: int, name: str | None, entries: list[PlaylistEntry]) -> Self:
|
||||||
if any(entry.playlist_id != playlist_id for entry in entries):
|
if any(entry.playlist_id != playlist_id for entry in entries):
|
||||||
raise ValueError("All PlaylistEntries must have the same playlist_id")
|
raise ValueError("All PlaylistEntries must have the same playlist_id")
|
||||||
return cls(
|
return cls(
|
||||||
id=playlist_id,
|
id=playlist_id,
|
||||||
|
name=name,
|
||||||
sets=[
|
sets=[
|
||||||
Set.from_playlist_entries(set_id, set_entries)
|
Set.from_playlist_entries(set_id, set_entries)
|
||||||
for set_id, set_entries in groupby(entries, key_fn=lambda e: e.set_id, group_fn=list)
|
for set_id, set_entries in groupby(entries, key_fn=lambda e: e.set_id, group_fn=list)
|
||||||
|
|||||||
@@ -41,10 +41,18 @@ def add_tema_to_tema_in_set(tema_in_set: playlists.TemaInSet) -> playlists.TemaI
|
|||||||
|
|
||||||
|
|
||||||
def get_playlist(playlist_id: int, con: Connection | None = None) -> playlists.Playlist:
|
def get_playlist(playlist_id: int, con: Connection | None = None) -> playlists.Playlist:
|
||||||
return playlists.Playlist.from_playlist_entries(
|
with get_connection(con) as playlist_con:
|
||||||
playlist_id=playlist_id,
|
playlist_name = query.get_playlist_name(playlist_id=playlist_id, con=playlist_con)
|
||||||
entries=list(query.get_playlist_entries(playlist_id=playlist_id, con=con))
|
return playlists.Playlist.from_playlist_entries(
|
||||||
)
|
playlist_id=playlist_id,
|
||||||
|
name=playlist_name,
|
||||||
|
entries=list(query.get_playlist_entries(playlist_id=playlist_id, con=playlist_con))
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def update_name(playlist_id: int, name: str | None) -> playlists.Playlist:
|
||||||
|
write.update_playlist_name(playlist_id=playlist_id, name=name)
|
||||||
|
return get_playlist(playlist_id=playlist_id)
|
||||||
|
|
||||||
|
|
||||||
def add_set(playlist_id: int, con: Connection | None = None) -> playlists.Set:
|
def add_set(playlist_id: int, con: Connection | None = None) -> playlists.Set:
|
||||||
|
|||||||
@@ -75,6 +75,7 @@ def insert_session(session: model.Session):
|
|||||||
|
|
||||||
def set_session(session: model.Session):
|
def set_session(session: model.Session):
|
||||||
write.update_session(session)
|
write.update_session(session)
|
||||||
|
_update_session_playlist_names(session)
|
||||||
|
|
||||||
|
|
||||||
def delete_session(session_id: int):
|
def delete_session(session_id: int):
|
||||||
@@ -167,24 +168,72 @@ def get_commonly_played_temes(
|
|||||||
return session_playlists.get_commonly_played_tunes(tema_id=tema_id)
|
return session_playlists.get_commonly_played_tunes(tema_id=tema_id)
|
||||||
|
|
||||||
|
|
||||||
|
def _get_playlist_names(session: model.Session) -> tuple[str, str]:
|
||||||
|
date_names = get_date_names(session.date)
|
||||||
|
|
||||||
|
setlist_name = f"Sessió del {date_names.day} {date_names.month_name} de {date_names.year}"
|
||||||
|
slowjam_name = f"Slow Jam del {date_names.day} {date_names.month_name} de {date_names.year}"
|
||||||
|
|
||||||
|
return setlist_name, slowjam_name
|
||||||
|
|
||||||
|
|
||||||
def _create_session_playlists(session_id: int):
|
def _create_session_playlists(session_id: int):
|
||||||
|
session = get_session(session_id=session_id)
|
||||||
|
if not session:
|
||||||
|
return
|
||||||
|
|
||||||
|
setlist_name, slowjam_name = _get_playlist_names(session=session)
|
||||||
|
|
||||||
|
setlist_playlist_id = playlists_write.create_playlist(name=setlist_name, con=None)
|
||||||
|
slowjam_playlist_id = playlists_write.create_playlist(name=slowjam_name, con=None)
|
||||||
|
|
||||||
with get_connection() as con:
|
with get_connection() as con:
|
||||||
setlist_playlist_id = playlists_write.create_playlist(con=con)
|
|
||||||
slowjam_playlist_id = playlists_write.create_playlist(con=con)
|
|
||||||
session_playlists.insert_playlist(
|
session_playlists.insert_playlist(
|
||||||
session_id=session_id,
|
session_id=session_id,
|
||||||
playlist_type=PlaylistType.SESSION_SETLIST,
|
playlist_type=PlaylistType.SESSION_SETLIST,
|
||||||
playlist_id=setlist_playlist_id,
|
playlist_id=setlist_playlist_id,
|
||||||
con=con,
|
con=con
|
||||||
)
|
)
|
||||||
session_playlists.insert_playlist(
|
session_playlists.insert_playlist(
|
||||||
session_id=session_id,
|
session_id=session_id,
|
||||||
playlist_type=PlaylistType.SESSION_SLOWJAM,
|
playlist_type=PlaylistType.SESSION_SLOWJAM,
|
||||||
playlist_id=slowjam_playlist_id,
|
playlist_id=slowjam_playlist_id,
|
||||||
con=con,
|
con=con
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def _update_session_playlist_names(session: model.Session):
|
||||||
|
if session.id is None:
|
||||||
|
return
|
||||||
|
|
||||||
|
setlist_name, slowjam_name = _get_playlist_names(session=session)
|
||||||
|
|
||||||
|
with get_connection() as con:
|
||||||
|
setlist_playlist_id = session_playlists.get_playlist_id(
|
||||||
|
session_id=session.id,
|
||||||
|
playlist_type=PlaylistType.SESSION_SETLIST,
|
||||||
|
con=con
|
||||||
|
)
|
||||||
|
slowjam_playlist_id = session_playlists.get_playlist_id(
|
||||||
|
session_id=session.id,
|
||||||
|
playlist_type=PlaylistType.SESSION_SLOWJAM,
|
||||||
|
con=con
|
||||||
|
)
|
||||||
|
|
||||||
|
if setlist_playlist_id is not None:
|
||||||
|
playlists_write.update_playlist_name(
|
||||||
|
playlist_id=setlist_playlist_id,
|
||||||
|
name=setlist_name,
|
||||||
|
con=con
|
||||||
|
)
|
||||||
|
if slowjam_playlist_id is not None:
|
||||||
|
playlists_write.update_playlist_name(
|
||||||
|
playlist_id=slowjam_playlist_id,
|
||||||
|
name=slowjam_name,
|
||||||
|
con=con
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def _delete_session_playlists(session_id: int):
|
def _delete_session_playlists(session_id: int):
|
||||||
with get_connection() as con:
|
with get_connection() as con:
|
||||||
setlist_playlist_id = session_playlists.get_playlist_id(
|
setlist_playlist_id = session_playlists.get_playlist_id(
|
||||||
@@ -199,22 +248,22 @@ def _delete_session_playlists(session_id: int):
|
|||||||
)
|
)
|
||||||
|
|
||||||
if setlist_playlist_id is not None:
|
if setlist_playlist_id is not None:
|
||||||
|
session_playlists.delete_playlist(
|
||||||
|
session_id=session_id,
|
||||||
|
playlist_type=PlaylistType.SESSION_SETLIST,
|
||||||
|
con=con,
|
||||||
|
)
|
||||||
playlists_write.delete_playlist(
|
playlists_write.delete_playlist(
|
||||||
playlist_id=setlist_playlist_id,
|
playlist_id=setlist_playlist_id,
|
||||||
con=con,
|
con=con,
|
||||||
)
|
)
|
||||||
|
if slowjam_playlist_id is not None:
|
||||||
session_playlists.delete_playlist(
|
session_playlists.delete_playlist(
|
||||||
session_id=session_id,
|
session_id=session_id,
|
||||||
playlist_type=PlaylistType.SESSION_SETLIST,
|
playlist_type=PlaylistType.SESSION_SLOWJAM,
|
||||||
con=con
|
con=con,
|
||||||
)
|
)
|
||||||
if slowjam_playlist_id is not None:
|
|
||||||
playlists_write.delete_playlist(
|
playlists_write.delete_playlist(
|
||||||
playlist_id=slowjam_playlist_id,
|
playlist_id=slowjam_playlist_id,
|
||||||
con=con,
|
con=con,
|
||||||
)
|
)
|
||||||
session_playlists.delete_playlist(
|
|
||||||
session_id=session_id,
|
|
||||||
playlist_type=PlaylistType.SESSION_SLOWJAM,
|
|
||||||
con=con
|
|
||||||
)
|
|
||||||
|
|||||||
Reference in New Issue
Block a user