Desacoblar playlists de sessions i afegir slow jams

This commit is contained in:
marc
2025-11-01 19:55:24 +01:00
parent 23337f8ab3
commit 2fbdbbf290
41 changed files with 705 additions and 1418 deletions

View File

@@ -60,6 +60,7 @@
lilypond-with-fonts lilypond-with-fonts
# Project tools # Project tools
sqlite sqlite
lazysql
opencode opencode
]; ];

View File

@@ -1,14 +1,15 @@
from folkugat_web.api.router import get_router from folkugat_web.api.router import get_router
from . import auth, index, sessio, sessions, tema, temes from . import auth, index, playlist, sessio, sessions, tema, temes
router = get_router() router = get_router()
router.include_router(auth.router)
router.include_router(index.router)
router.include_router(playlist.router)
router.include_router(sessio.router) router.include_router(sessio.router)
router.include_router(sessions.router) router.include_router(sessions.router)
router.include_router(tema.router) router.include_router(tema.router)
router.include_router(temes.router) router.include_router(temes.router)
router.include_router(auth.router)
router.include_router(index.router)
__all__ = ["router"] __all__ = ["router"]

View File

@@ -0,0 +1,9 @@
from folkugat_web.api.router import get_router
from . import playlist, set_page
router = get_router()
router.include_router(set_page.router)
router.include_router(playlist.router)
__all__ = ["router"]

View File

@@ -2,141 +2,139 @@ from typing import Annotated
from fastapi import Form, Request from fastapi import Form, Request
from folkugat_web.api.router import get_router from folkugat_web.api.router import get_router
from folkugat_web.fragments import live from folkugat_web.fragments import playlist
from folkugat_web.fragments.sessio import playlist
from folkugat_web.services import auth from folkugat_web.services import auth
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.post("/api/sessio/{session_id}/playlist/set") @router.post("/api/playlist/{playlist_id}/set")
def add_set( def add_set(
request: Request, request: Request,
logged_in: auth.RequireLogin, logged_in: auth.RequireLogin,
session_id: int, playlist_id: int,
): ):
return playlist.add_set( return playlist.add_set(
request=request, request=request,
session_id=session_id, playlist_id=playlist_id,
logged_in=logged_in, logged_in=logged_in,
) )
@router.get("/api/sessio/{session_id}/playlist/set/{set_id}") @router.get("/api/playlist/{playlist_id}/set/{set_id}")
def get_set( def get_set(
request: Request, request: Request,
logged_in: auth.LoggedIn, logged_in: auth.LoggedIn,
session_id: int, playlist_id: int,
set_id: int, set_id: int,
): ):
return playlist.get_set( return playlist.get_set(
request=request, request=request,
session_id=session_id, playlist_id=playlist_id,
set_id=set_id, set_id=set_id,
logged_in=logged_in, logged_in=logged_in,
) )
@router.delete("/api/sessio/{session_id}/playlist/set/{set_id}") @router.delete("/api/playlist/{playlist_id}/set/{set_id}")
def delete_set( def delete_set(
_: auth.RequireLogin, _: auth.RequireLogin,
session_id: int, playlist_id: int,
set_id: int, set_id: int,
): ):
return playlist.delete_set( return playlist.delete_set(
session_id=session_id, playlist_id=playlist_id,
set_id=set_id, set_id=set_id,
) )
@router.post("/api/sessio/{session_id}/playlist/set/{set_id}") @router.post("/api/playlist/{playlist_id}/set/{set_id}")
def add_tema( def add_tema(
request: Request, request: Request,
logged_in: auth.RequireLogin, logged_in: auth.RequireLogin,
session_id: int, playlist_id: int,
set_id: int, set_id: int,
): ):
return playlist.add_tema( return playlist.add_tema(
request=request, request=request,
session_id=session_id, playlist_id=playlist_id,
set_id=set_id, set_id=set_id,
logged_in=logged_in, logged_in=logged_in,
) )
@router.get("/api/sessio/{session_id}/playlist/set/{set_id}/tema/{entry_id}") @router.get("/api/playlist/{playlist_id}/set/{set_id}/tema/{entry_id}")
def get_tema( def get_tema(
request: Request, request: Request,
logged_in: auth.RequireLogin, logged_in: auth.RequireLogin,
session_id: int, playlist_id: int,
set_id: int, set_id: int,
entry_id: int, entry_id: int,
): ):
return playlist.get_tema( return playlist.get_tema(
request=request, request=request,
session_id=session_id, playlist_id=playlist_id,
set_id=set_id, set_id=set_id,
entry_id=entry_id, entry_id=entry_id,
logged_in=logged_in, logged_in=logged_in,
) )
@router.get("/api/sessio/{session_id}/playlist/set/{set_id}/tema/{entry_id}/editor") @router.get("/api/playlist/{playlist_id}/set/{set_id}/tema/{entry_id}/editor")
def get_tema_editor( def get_tema_editor(
request: Request, request: Request,
logged_in: auth.RequireLogin, logged_in: auth.RequireLogin,
session_id: int, playlist_id: int,
set_id: int, set_id: int,
entry_id: int, entry_id: int,
): ):
return playlist.get_tema_editor( return playlist.get_tema_editor(
request=request, request=request,
session_id=session_id, playlist_id=playlist_id,
set_id=set_id, set_id=set_id,
entry_id=entry_id, entry_id=entry_id,
logged_in=logged_in, logged_in=logged_in,
) )
@router.delete("/api/sessio/{session_id}/playlist/set/{set_id}/tema/{entry_id}") @router.delete("/api/playlist/{playlist_id}/set/{set_id}/tema/{entry_id}")
def delete_tema( def delete_tema(
_: auth.RequireLogin, _: auth.RequireLogin,
session_id: int, playlist_id: int,
set_id: int, set_id: int,
entry_id: int, entry_id: int,
): ):
return playlist.delete_tema( return playlist.delete_tema(
session_id=session_id, playlist_id=playlist_id,
set_id=set_id, set_id=set_id,
entry_id=entry_id, entry_id=entry_id,
) )
@router.get("/api/sessio/{session_id}/playlist/set/{set_id}/tema/{entry_id}/busca") @router.get("/api/playlist/{playlist_id}/set/{set_id}/tema/{entry_id}/busca")
def busca_tema( def busca_tema(
request: Request, request: Request,
_: auth.RequireLogin, _: auth.RequireLogin,
session_id: int, playlist_id: int,
set_id: int, set_id: int,
entry_id: int, entry_id: int,
query: str, query: str,
): ):
return playlist.busca_tema( return playlist.busca_tema(
request=request, request=request,
session_id=session_id, playlist_id=playlist_id,
set_id=set_id, set_id=set_id,
entry_id=entry_id, entry_id=entry_id,
query=query, query=query,
) )
@router.put("/api/sessio/{session_id}/playlist/set/{set_id}/tema/{entry_id}") @router.put("/api/playlist/{playlist_id}/set/{set_id}/tema/{entry_id}")
def set_tema( def set_tema(
request: Request, request: Request,
logged_in: auth.RequireLogin, logged_in: auth.RequireLogin,
session_id: int, playlist_id: int,
set_id: int, set_id: int,
entry_id: int, entry_id: int,
tema_id: Annotated[int, Form()], tema_id: Annotated[int, Form()],
@@ -144,36 +142,36 @@ def set_tema(
return playlist.set_tema( return playlist.set_tema(
request=request, request=request,
logged_in=logged_in, logged_in=logged_in,
session_id=session_id, playlist_id=playlist_id,
set_id=set_id, set_id=set_id,
entry_id=entry_id, entry_id=entry_id,
tema_id=tema_id, tema_id=tema_id,
) )
@router.put("/api/sessio/{session_id}/playlist/set/{set_id}/tema/{entry_id}/unknown") @router.put("/api/playlist/{playlist_id}/set/{set_id}/tema/{entry_id}/unknown")
def set_tema_unknown( def set_tema_unknown(
request: Request, request: Request,
logged_in: auth.RequireLogin, logged_in: auth.RequireLogin,
session_id: int, playlist_id: int,
set_id: int, set_id: int,
entry_id: int, entry_id: int,
): ):
return playlist.set_tema( return playlist.set_tema(
request=request, request=request,
logged_in=logged_in, logged_in=logged_in,
session_id=session_id, playlist_id=playlist_id,
set_id=set_id, set_id=set_id,
entry_id=entry_id, entry_id=entry_id,
tema_id=None, tema_id=None,
) )
@router.post("/api/sessio/{session_id}/playlist/set/{set_id}/tema/{entry_id}") @router.post("/api/playlist/{playlist_id}/set/{set_id}/tema/{entry_id}")
def set_tema_new( def set_tema_new(
request: Request, request: Request,
logged_in: auth.RequireLogin, logged_in: auth.RequireLogin,
session_id: int, playlist_id: int,
set_id: int, set_id: int,
entry_id: int, entry_id: int,
title: Annotated[str, Form()], title: Annotated[str, Form()],
@@ -182,7 +180,7 @@ def set_tema_new(
return playlist.set_tema( return playlist.set_tema(
request=request, request=request,
logged_in=logged_in, logged_in=logged_in,
session_id=session_id, playlist_id=playlist_id,
set_id=set_id, set_id=set_id,
entry_id=entry_id, entry_id=entry_id,
tema_id=new_tema.id, tema_id=new_tema.id,

View File

@@ -7,11 +7,11 @@ from folkugat_web.templates import templates
router = get_router() router = get_router()
@router.get("/sessio/{session_id}/set/{set_id}") @router.get("/playlist/{playlist_id}/set/{set_id}")
def page( def page(
request: Request, request: Request,
logged_in: auth.LoggedIn, logged_in: auth.LoggedIn,
session_id: int, playlist_id: int,
set_id: int, set_id: int,
): ):
return templates.TemplateResponse( return templates.TemplateResponse(
@@ -19,17 +19,22 @@ def page(
{ {
"request": request, "request": request,
"page_title": "Folkugat", "page_title": "Folkugat",
"content": f"/api/content/sessio/{session_id}/set/{set_id}", "content": f"/api/content/playlist/{playlist_id}/set/{set_id}",
"logged_in": logged_in, "logged_in": logged_in,
} }
) )
@router.get("/api/content/sessio/{session_id}/set/{set_id}") @router.get("/api/content/playlist/{playlist_id}/set/{set_id}")
async def contingut( async def contingut(
request: Request, request: Request,
logged_in: auth.LoggedIn, logged_in: auth.LoggedIn,
session_id: int, playlist_id: int,
set_id: int, set_id: int,
): ):
return await set_page.pagina(request, session_id, set_id, logged_in) return await set_page.pagina(
request=request,
playlist_id=playlist_id,
set_id=set_id,
logged_in=logged_in,
)

View File

@@ -1,12 +1,11 @@
from folkugat_web.api.router import get_router from folkugat_web.api.router import get_router
from . import cartell, index, live, playlist, set_page from . import cartell, index, live, notes
router = get_router() router = get_router()
router.include_router(cartell.router) router.include_router(cartell.router)
router.include_router(index.router) router.include_router(index.router)
router.include_router(live.router) router.include_router(live.router)
router.include_router(set_page.router) router.include_router(notes.router)
router.include_router(playlist.router)
__all__ = ["router"] __all__ = ["router"]

View File

@@ -0,0 +1,47 @@
import dataclasses
from typing import Annotated
from fastapi import HTTPException, Request
from fastapi.params import Form
from folkugat_web.api.router import get_router
from folkugat_web.fragments.sessio import notes
from folkugat_web.services import auth
from folkugat_web.services import sessions as sessions_service
router = get_router()
@router.get("/api/sessio/{session_id}/notes")
def get_notes(
request: Request,
logged_in: auth.LoggedIn,
session_id: int,
):
return notes.notes(request, session_id, logged_in)
@router.get("/api/sessio/{session_id}/notes/editor")
def get_notes_editor(
request: Request,
_: auth.RequireLogin,
session_id: int,
):
return notes.notes_editor(request, session_id)
@router.put("/api/sessio/{session_id}/notes")
async def set_notes(
request: Request,
logged_in: auth.RequireLogin,
session_id: int,
content: Annotated[str, Form()],
):
session = sessions_service.get_session(session_id=session_id)
if not session:
raise HTTPException(status_code=404, detail="Could not find session")
new_session = dataclasses.replace(
session,
notes=content.strip(),
)
sessions_service.set_session(new_session)
return notes.notes(request, session_id, logged_in)

File diff suppressed because one or more lines are too long

View File

@@ -1,14 +1,14 @@
<ul id="playlist-{{ session.id }}" class=""> <ul id="playlist-{{ playlist_id }}" class="">
{% for set_entry in playlist.sets %} {% for set_entry in playlist.sets %}
{% set set_id = set_entry.id %} {% set set_id = set_entry.id %}
{% include "fragments/sessio/set_entry.html" %} {% include "fragments/playlist/set_entry.html" %}
{% endfor %} {% endfor %}
</ul> </ul>
{% if logged_in %} {% if logged_in %}
<div class="flex flex-col items-center"> <div class="flex flex-col items-center">
<button class="text-beige mt-2" <button class="text-beige mt-2"
hx-post="/api/sessio/{{ session.id }}/playlist/set" hx-post="/api/playlist/{{ playlist_id }}/set"
hx-target="#playlist-{{ session.id }}" hx-target="#playlist-{{ playlist_id }}"
hx-swap="beforeend transition:true"> hx-swap="beforeend transition:true">
<i class="fa fa-plus" aria-hidden="true"></i> <i class="fa fa-plus" aria-hidden="true"></i>
Afegeix set Afegeix set

View File

@@ -0,0 +1,2 @@
{% include "fragments/menu.html" %}
{% include "fragments/playlist/set/set_page.html" %}

View File

@@ -13,14 +13,14 @@
{% for tema_in_set in set.temes %} {% for tema_in_set in set.temes %}
{% if tema_in_set.tema is not none %} {% if tema_in_set.tema is not none %}
{% set tema = tema_in_set.tema %} {% set tema = tema_in_set.tema %}
{% include "fragments/sessio/set/tema_title.html" %} {% include "fragments/playlist/set/tema_title.html" %}
{% else %} {% else %}
<h3 class="text-center text-3xl p-4"> <i>Desconegut</i> </h3> <h3 class="text-center text-3xl p-4"> <i>Desconegut</i> </h3>
{% endif %} {% endif %}
{% endfor %} {% endfor %}
<div class="mx-12"> <div class="mx-12">
<hr class="h-px mt-1 mb-3 bg-beige border-0"> <hr class="h-px mt-1 mb-3 bg-beige border-0">
{% include "fragments/sessio/set/set_score.html"%} {% include "fragments/playlist/set/set_score.html"%}
</div> </div>
{% else %} {% else %}
{% for tema_in_set in set.temes %} {% for tema_in_set in set.temes %}
@@ -31,7 +31,7 @@
{% endif %} {% endif %}
{% if tema_in_set.tema is not none %} {% if tema_in_set.tema is not none %}
{% set tema = tema_in_set.tema %} {% set tema = tema_in_set.tema %}
{% include "fragments/sessio/set/tema.html"%} {% include "fragments/playlist/set/tema.html"%}
{% else %} {% else %}
<h3 class="text-center text-3xl p-4"> <h3 class="text-center text-3xl p-4">
<i>Desconegut</i> <i>Desconegut</i>

View File

@@ -1,4 +1,4 @@
{% include "fragments/sessio/set/tema_title.html" %} {% include "fragments/playlist/set/tema_title.html" %}
<div class="mx-12 text-left"> <div class="mx-12 text-left">
{% if tema.main_score() is not none %} {% if tema.main_score() is not none %}

View File

@@ -2,12 +2,12 @@
m-4 rounded-lg bg-white m-4 rounded-lg bg-white
px-2 py-1 my-1" px-2 py-1 my-1"
id="set-entry-{{ set_id }}" id="set-entry-{{ set_id }}"
hx-get="/api/sessio/{{ session_id }}/playlist/set/{{ set_id }}" hx-get="/api/playlist/{{ playlist_id }}/set/{{ set_id }}"
hx-target="#set-entry-{{ set_id }}" hx-target="#set-entry-{{ set_id }}"
hx-swap="outerHTML" hx-swap="outerHTML"
hx-trigger="reload-set-{{ set_id }}"> hx-trigger="reload-set-{{ set_id }}">
{% if set_entry.temes | length > 1 or not set_entry.temes[0].tema %} {% if set_entry.temes | length > 1 or not set_entry.temes[0].tema %}
{% set set_url = "/sessio/%d/set/%d" | format(session_id, set_id) %} {% set set_url = "/playlist/%d/set/%d" | format(playlist_id, set_id) %}
{% else %} {% else %}
{% set set_url = "/tema/%d" | format(set_entry.temes[0].tema_id) %} {% set set_url = "/tema/%d" | format(set_entry.temes[0].tema_id) %}
{% endif %} {% endif %}
@@ -25,7 +25,7 @@
w-full max-w-[655px]"> w-full max-w-[655px]">
{% if logged_in %} {% if logged_in %}
<button class="text-beige w-full" <button class="text-beige w-full"
hx-delete="/api/sessio/{{ session_id }}/playlist/set/{{ set_id }}" hx-delete="/api/playlist/{{ playlist_id }}/set/{{ set_id }}"
hx-target="#set-entry-{{ set_id }}" hx-target="#set-entry-{{ set_id }}"
hx-swap="outerHTML"> hx-swap="outerHTML">
<i class="fa fa-times" aria-hidden="true"></i> <i class="fa fa-times" aria-hidden="true"></i>
@@ -36,15 +36,15 @@
class="flex flex-col items-start w-full"> class="flex flex-col items-start w-full">
{% for tema_entry in set_entry.temes %} {% for tema_entry in set_entry.temes %}
{% if new_entry %} {% if new_entry %}
{% include "fragments/sessio/tema_editor.html" %} {% include "fragments/playlist/tema_editor.html" %}
{% else %} {% else %}
{% include "fragments/sessio/tema_entry.html" %} {% include "fragments/playlist/tema_entry.html" %}
{% endif %} {% endif %}
{% endfor %} {% endfor %}
</ol> </ol>
{% if logged_in %} {% if logged_in %}
<button class="text-beige mt-2 w-full" <button class="text-beige mt-2 w-full"
hx-post="/api/sessio/{{ session_id }}/playlist/set/{{ set_id }}" hx-post="/api/playlist/{{ playlist_id }}/set/{{ set_id }}"
hx-target="#set-entry-{{ set_id }}-list" hx-target="#set-entry-{{ set_id }}-list"
hx-swap="beforeend transition:true"> hx-swap="beforeend transition:true">
<i class="fa fa-plus" aria-hidden="true"></i> <i class="fa fa-plus" aria-hidden="true"></i>

View File

@@ -12,13 +12,13 @@
class="border border-beige focus:outline-none class="border border-beige focus:outline-none
rounded text-center text-black rounded text-center text-black
p-1 m-1" p-1 m-1"
hx-get="/api/sessio/{{ session_id }}/playlist/set/{{ set_id }}/tema/{{ tema_entry.id }}/busca" hx-get="/api/playlist/{{ playlist_id }}/set/{{ set_id }}/tema/{{ tema_entry.id }}/busca"
hx-trigger="revealed, keyup delay:500ms changed" hx-trigger="revealed, keyup delay:500ms changed"
hx-target="#tune-entry-{{ tema_entry.id }}-search-results" hx-target="#tune-entry-{{ tema_entry.id }}-search-results"
hx-swap="outerHTML"/> hx-swap="outerHTML"/>
<button title="Descarta els canvis" <button title="Descarta els canvis"
class="text-beige mx-1" class="text-beige mx-1"
hx-get="/api/sessio/{{ session_id }}/playlist/set/{{ set_id }}/tema/{{ tema_entry.id }}" hx-get="/api/playlist/{{ playlist_id }}/set/{{ set_id }}/tema/{{ tema_entry.id }}"
hx-target="#tune-entry-{{ tema_entry.id }}" hx-target="#tune-entry-{{ tema_entry.id }}"
hx-swap="outerHTML"> hx-swap="outerHTML">
<i class="fa fa-times" aria-hidden="true"></i> <i class="fa fa-times" aria-hidden="true"></i>

View File

@@ -15,14 +15,14 @@
<div class="flex-none flex flex-row shrink-0"> <div class="flex-none flex flex-row shrink-0">
<button title="Edita el tema" <button title="Edita el tema"
class="text-beige mx-1" class="text-beige mx-1"
hx-get="/api/sessio/{{ session_id }}/playlist/set/{{ set_id }}/tema/{{ tema_entry.id }}/editor" hx-get="/api/playlist/{{ playlist_id }}/set/{{ set_id }}/tema/{{ tema_entry.id }}/editor"
hx-target="#tune-entry-{{ tema_entry.id }}" hx-target="#tune-entry-{{ tema_entry.id }}"
hx-swap="outerHTML"> hx-swap="outerHTML">
<i class="fa fa-pencil" aria-hidden="true"></i> <i class="fa fa-pencil" aria-hidden="true"></i>
</button> </button>
<button title="Esborra el tema" <button title="Esborra el tema"
class="text-beige mx-1" class="text-beige mx-1"
hx-delete="/api/sessio/{{ session_id }}/playlist/set/{{ set_id }}/tema/{{ tema_entry.id }}" hx-delete="/api/playlist/{{ playlist_id }}/set/{{ set_id }}/tema/{{ tema_entry.id }}"
hx-target="#tune-entry-{{ tema_entry.id }}" hx-target="#tune-entry-{{ tema_entry.id }}"
hx-swap="outerHTML"> hx-swap="outerHTML">
<i class="fa fa-times" aria-hidden="true"></i> <i class="fa fa-times" aria-hidden="true"></i>

View File

@@ -4,7 +4,7 @@
<li> <li>
<button class="bg-beige text-brown rounded <button class="bg-beige text-brown rounded
m-1 px-2" m-1 px-2"
hx-put="/api/sessio/{{ session_id }}/playlist/set/{{ set_id }}/tema/{{ entry_id }}" hx-put="/api/playlist/{{ playlist_id }}/set/{{ set_id }}/tema/{{ entry_id }}"
hx-vals='{"tema_id": "{{ tema.id }}"}' hx-vals='{"tema_id": "{{ tema.id }}"}'
hx-target="#tune-entry-{{ entry_id }}" hx-target="#tune-entry-{{ entry_id }}"
hx-swap="outerHTML"> hx-swap="outerHTML">
@@ -15,7 +15,7 @@
<li> <li>
<button class="border border-beige text-beige rounded <button class="border border-beige text-beige rounded
m-1 px-2" m-1 px-2"
hx-put="/api/sessio/{{ session_id }}/playlist/set/{{ set_id }}/tema/{{ entry_id }}/unknown" hx-put="/api/playlist/{{ playlist_id }}/set/{{ set_id }}/tema/{{ entry_id }}/unknown"
hx-target="#tune-entry-{{ entry_id }}" hx-target="#tune-entry-{{ entry_id }}"
hx-swap="outerHTML"> hx-swap="outerHTML">
<i class="fa fa-question" aria-hidden="true"></i> <i class="fa fa-question" aria-hidden="true"></i>
@@ -25,7 +25,7 @@
<li> <li>
<button class="border border-beige text-beige rounded <button class="border border-beige text-beige rounded
m-1 px-2" m-1 px-2"
hx-post="/api/sessio/{{ session_id }}/playlist/set/{{ set_id }}/tema/{{ entry_id }}" hx-post="/api/playlist/{{ playlist_id }}/set/{{ set_id }}/tema/{{ entry_id }}"
hx-vals='{"title": "{{ query }}"}' hx-vals='{"title": "{{ query }}"}'
hx-target="#tune-entry-{{ entry_id }}" hx-target="#tune-entry-{{ entry_id }}"
hx-swap="outerHTML"> hx-swap="outerHTML">

View File

@@ -0,0 +1,13 @@
<h4 class="py-4 text-xl text-beige">
Notes
{% if logged_in %}
<button title="Edita les notes"
class="mx-1"
hx-get="/api/sessio/{{ session_id }}/notes/editor"
hx-target="#notes"
hx-swap="innerHTML">
<i class="fa fa-pencil" aria-hidden="true"></i>
</button>
{% endif %}
</h4>
{{ notes | safe }}

View File

@@ -0,0 +1,28 @@
<h4 class="py-4 text-xl text-beige">Notes</h4>
<form id="notes-form"
class="w-full">
<h5 class="text-sm text-beige text-right">
<button title="Desa els canvis"
class="mx-1"
hx-put="/api/sessio/{{session_id}}/notes"
hx-target="#notes"
hx-swap="innerHTML">
<i class="fa fa-check" aria-hidden="true"></i>
</button>
<button title="Descarta els canvis"
class="mx-1"
hx-get="/api/sessio/{{session_id}}/notes"
hx-target="#notes"
hx-swap="innerHTML">
<i class="fa fa-times" aria-hidden="true"></i>
</button>
</h5>
<hr class="h-px mt-1 mb-3 bg-beige border-0">
<textarea name="content"
placeholder="Notes"
rows="{{ max(notes.count('\n') + 1, 5) }}"
class="border border-beige focus:outline-none
w-full text-left
rounded
bg-brown p-2 m-0">{{notes}}</textarea>
</form>

View File

@@ -31,20 +31,26 @@
{% endif %} {% endif %}
</div> </div>
{% if logged_in or session.notes %} {% if logged_in or session.notes %}
<div class="text-left"> <div id="notes"
<h4 class="py-4 text-xl text-beige">Notes</h4> class="text-left">
{% if session.notes %}{{ session.notes }}{% endif %} {% set notes = session.notes if session.notes else "" %}
{% include "fragments/sessio/notes.html" %}
</div> </div>
{% endif %} {% endif %}
{% if logged_in or False %} {% 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">Slow Jam</h4> <h4 class="py-4 text-xl text-beige mt-2">Slow Jam</h4>
{% set playlist_id = session.slowjam.id %}
{% set playlist = session.slowjam %}
{% include "fragments/playlist/playlist.html" %}
</div> </div>
{% endif %} {% endif %}
{% if logged_in or playlist.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">Temes tocats</h4>
{% include "fragments/sessio/playlist.html" %} {% set playlist_id = session.setlist.id %}
{% set playlist = session.setlist %}
{% include "fragments/playlist/playlist.html" %}
</div> </div>
{% endif %} {% endif %}
</div> </div>

View File

@@ -1,2 +0,0 @@
{% include "fragments/menu.html" %}
{% include "fragments/sessio/set/set_page.html" %}

View File

@@ -2,12 +2,13 @@ from typing import TypedDict
from folkugat_web.model import playlists as model from folkugat_web.model import playlists as model
PlaylistRowTuple = tuple[int, int, int, int | None] PlaylistRowTuple = tuple[int, str | None]
PlaylistEntryRowTuple = tuple[int, int, int, int | None]
class PlaylistRowDict(TypedDict): class PlaylistRowDict(TypedDict):
id: int | None id: int | None
session_id: int playlist_id: int
set_id: int set_id: int
tema_id: int | None tema_id: int | None
@@ -15,16 +16,16 @@ class PlaylistRowDict(TypedDict):
def playlist_entry_to_row(tema_in_set: model.PlaylistEntry) -> PlaylistRowDict: def playlist_entry_to_row(tema_in_set: model.PlaylistEntry) -> PlaylistRowDict:
return { return {
'id': tema_in_set.id, 'id': tema_in_set.id,
'session_id': tema_in_set.session_id, 'playlist_id': tema_in_set.playlist_id,
'set_id': tema_in_set.set_id, 'set_id': tema_in_set.set_id,
'tema_id': tema_in_set.tema_id, 'tema_id': tema_in_set.tema_id,
} }
def row_to_playlist_entry(row: PlaylistRowTuple) -> model.PlaylistEntry: def row_to_playlist_entry(row: PlaylistEntryRowTuple) -> model.PlaylistEntry:
return model.PlaylistEntry( return model.PlaylistEntry(
id=row[0], id=row[0],
session_id=row[1], playlist_id=row[1],
set_id=row[2], set_id=row[2],
tema_id=row[3], tema_id=row[3],
) )

View File

@@ -4,15 +4,29 @@ from folkugat_web.dal.sql import Connection, get_connection
def create_db(con: Connection | None = None): def create_db(con: Connection | None = None):
with get_connection(con) as con: with get_connection(con) as con:
create_playlists_table(con) create_playlists_table(con)
create_playlist_entries_table(con)
def create_playlists_table(con: Connection): def create_playlists_table(con: Connection):
query = """ query = """
CREATE TABLE IF NOT EXISTS playlists ( CREATE TABLE IF NOT EXISTS playlists (
id INTEGER PRIMARY KEY, id INTEGER PRIMARY KEY,
session_id INTEGER NOT NULL, name TEXT
set_id INTEGER NOT NULL, )
tema_id INTEGER """
cur = con.cursor()
_ = cur.execute(query)
def create_playlist_entries_table(con: Connection):
query = """
CREATE TABLE IF NOT EXISTS playlist_entries (
id INTEGER PRIMARY KEY,
playlist_id INTEGER NOT NULL,
set_id INTEGER NOT NULL,
tema_id INTEGER,
FOREIGN KEY (playlist_id) REFERENCES playlists(id) ON DELETE CASCADE,
FOREIGN KEY (tema_id) REFERENCES temes(id) ON DELETE CASCADE
) )
""" """
cur = con.cursor() cur = con.cursor()

View File

@@ -1,11 +1,9 @@
from collections.abc import Iterable, Iterator from collections.abc import Iterator
from typing import TypedDict from typing import TypedDict
from folkugat_web.dal.sql import Connection, get_connection from folkugat_web.dal.sql import Connection, get_connection
from folkugat_web.dal.sql.sessions import conversion as sessions_conversion from folkugat_web.dal.sql.sessions import conversion as sessions_conversion
from folkugat_web.dal.sql.temes.conversion import row_to_tema
from folkugat_web.model import playlists as model from folkugat_web.model import playlists as model
from folkugat_web.model import temes as temes_model
from folkugat_web.model.sessions import Session from folkugat_web.model.sessions import Session
from folkugat_web.utils import groupby from folkugat_web.utils import groupby
@@ -15,13 +13,13 @@ from . import conversion
class QueryData(TypedDict, total=False): class QueryData(TypedDict, total=False):
id: int id: int
set_id: int set_id: int
session_id: int playlist_id: int
def _filter_clause( def _filter_clause(
entry_id: int | None = None, entry_id: int | None = None,
set_id: int | None = None, set_id: int | None = None,
session_id: int | None = None, playlist_id: int | None = None,
) -> tuple[str, QueryData]: ) -> tuple[str, QueryData]:
filter_clauses: list[str] = [] filter_clauses: list[str] = []
query_data: QueryData = {} query_data: QueryData = {}
@@ -32,9 +30,9 @@ def _filter_clause(
if set_id is not None: if set_id is not None:
filter_clauses.append("set_id = :set_id") filter_clauses.append("set_id = :set_id")
query_data["set_id"] = set_id query_data["set_id"] = set_id
if session_id is not None: if playlist_id is not None:
filter_clauses.append("session_id = :session_id") filter_clauses.append("playlist_id = :playlist_id")
query_data["session_id"] = session_id query_data["playlist_id"] = playlist_id
return " AND ".join(filter_clauses), query_data return " AND ".join(filter_clauses), query_data
@@ -42,14 +40,14 @@ def _filter_clause(
def get_playlist_entries( def get_playlist_entries(
entry_id: int | None = None, entry_id: int | None = None,
set_id: int | None = None, set_id: int | None = None,
session_id: int | None = None, playlist_id: int | None = None,
con: Connection | None = None, con: Connection | None = None,
) -> Iterator[model.PlaylistEntry]: ) -> Iterator[model.PlaylistEntry]:
filter_clause, data = _filter_clause(entry_id=entry_id, set_id=set_id, session_id=session_id) filter_clause, data = _filter_clause(entry_id=entry_id, set_id=set_id, playlist_id=playlist_id)
query = f""" query = f"""
SELECT SELECT
id, session_id, set_id, tema_id id, playlist_id, set_id, tema_id
FROM playlists FROM playlist_entries
WHERE {filter_clause} WHERE {filter_clause}
ORDER BY id ASC ORDER BY id ASC
""" """
@@ -57,59 +55,3 @@ 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())
GetTuneSessionsRow = tuple[int, int, str, str, str, str | None, str | None, str | None, str | None, bool]
def get_tune_sessions(tema_ids: list[int], con: Connection | None = None) -> dict[int, list[Session]]:
placeholders = ", ".join(["?" for _ in tema_ids])
query = f"""
SELECT
p.tema_id, s.id, s.date, s.start_time, s.end_time, s.venue_name,
s.venue_url, s.notes, s.cartell_url, s.is_live
FROM playlists p JOIN sessions s ON p.session_id = s.id
WHERE p.tema_id IN ({placeholders})
"""
with get_connection(con) as con:
cur = con.cursor()
_ = cur.execute(query, tema_ids)
result_rows: Iterable[GetTuneSessionsRow] = cur.fetchall()
return dict(groupby(
result_rows,
key_fn=lambda row: row[0],
group_fn=lambda rows: list(sessions_conversion.row_to_session(row[1:]) for row in rows)
))
CommonlyPlayedTuneRow = tuple[int, str, str, str, str, int, int]
def get_commonly_played_tunes(
tema_id: int,
con: Connection | None = None,
) -> list[temes_model.CommonlyPlayedTema]:
query = """
SELECT
id, title, alternatives, creation_date, modification_date, hidden, count
FROM (
SELECT tema_id, count(*) count FROM playlists p JOIN (
SELECT session_id, set_id
FROM playlists
WHERE tema_id = ?
) s
ON p.session_id == s.session_id AND p.set_id == s.set_id
WHERE tema_id != ?
GROUP BY tema_id
) common JOIN temes t ON common.tema_id == t.id
"""
with get_connection(con) as con:
cur = con.cursor()
_ = cur.execute(query, [tema_id, tema_id])
result_rows: Iterable[CommonlyPlayedTuneRow] = cur.fetchall()
return [
temes_model.CommonlyPlayedTema(
tema=row_to_tema(row[:6]),
count=row[6],
) for row in result_rows
]

View File

@@ -4,27 +4,66 @@ from folkugat_web.model import playlists as model
from . import conversion from . import conversion
def insert_playlist_entry(pl_entry: model.PlaylistEntry, con: Connection | None = None) -> model.PlaylistEntry: def create_playlist(
name: str | None = None,
con: Connection | None = None,
) -> int:
query = """ query = """
INSERT INTO playlists INSERT INTO playlists
(id, session_id, set_id, tema_id) (name)
VALUES VALUES
(:id, :session_id, :set_id, :tema_id) (:name)
RETURNING *
"""
data = dict(name=name)
with get_connection(con) as con:
cur = con.cursor()
_ = cur.execute(query, data)
row: conversion.PlaylistRowTuple = cur.fetchone()
return row[0]
def delete_playlist(
playlist_id: int,
con: Connection | None = None,
) -> None:
query = """
DELETE FROM playlists
WHERE id = :id
"""
data = dict(playlist_id=playlist_id)
with get_connection(con) as con:
cur = con.cursor()
_ = cur.execute(query, data)
def insert_playlist_entry(
pl_entry: model.PlaylistEntry,
con: Connection | None = None,
) -> model.PlaylistEntry:
query = """
INSERT INTO playlist_entries
(id, playlist_id, set_id, tema_id)
VALUES
(:id, :playlist_id, :set_id, :tema_id)
RETURNING * RETURNING *
""" """
data = conversion.playlist_entry_to_row(pl_entry) data = conversion.playlist_entry_to_row(pl_entry)
with get_connection(con) as con: with get_connection(con) as con:
cur = con.cursor() cur = con.cursor()
_ = cur.execute(query, data) _ = cur.execute(query, data)
row: conversion.PlaylistRowTuple = cur.fetchone() row: conversion.PlaylistEntryRowTuple = cur.fetchone()
return conversion.row_to_playlist_entry(row) return conversion.row_to_playlist_entry(row)
def update_playlist_entry(entry: model.PlaylistEntry, con: Connection | None = None): def update_playlist_entry(
entry: model.PlaylistEntry,
con: Connection | None = None,
):
query = """ query = """
UPDATE playlists UPDATE playlist_entries
SET SET
id = :id, session_id = :session_id, set_id = :set_id, tema_id = :tema_id id = :id, playlist_id = :playlist_id, set_id = :set_id, tema_id = :tema_id
WHERE WHERE
id = :id id = :id
""" """
@@ -35,9 +74,12 @@ def update_playlist_entry(entry: model.PlaylistEntry, con: Connection | None = N
return return
def delete_playlist_entry(entry_id: int, con: Connection | None = None): def delete_playlist_entry(
entry_id: int,
con: Connection | None = None,
):
query = """ query = """
DELETE FROM playlists DELETE FROM playlist_entries
WHERE id = :id WHERE id = :id
""" """
data = dict(id=entry_id) data = dict(id=entry_id)
@@ -47,12 +89,16 @@ def delete_playlist_entry(entry_id: int, con: Connection | None = None):
return return
def delete_playlist_set(session_id: int, set_id: int, con: Connection | None = None): def delete_playlist_set(
playlist_id: int,
set_id: int,
con: Connection | None = None,
):
query = """ query = """
DELETE FROM playlists DELETE FROM playlist_entries
WHERE session_id = :session_id AND set_id = :set_id WHERE playlist_id = :playlist_id AND set_id = :set_id
""" """
data = dict(session_id=session_id, set_id=set_id) data = dict(playlist_id=playlist_id, set_id=set_id)
with get_connection(con) as con: with get_connection(con) as con:
cur = con.cursor() cur = con.cursor()
_ = cur.execute(query, data) _ = cur.execute(query, data)

View File

@@ -4,6 +4,7 @@ from folkugat_web.dal.sql import Connection, get_connection
def create_db(con: Connection | None = None): def create_db(con: Connection | None = None):
with get_connection(con) as con: with get_connection(con) as con:
create_sessions_table(con) create_sessions_table(con)
create_session_playlists_table(con)
def create_sessions_table(con: Connection): def create_sessions_table(con: Connection):
@@ -22,3 +23,18 @@ def create_sessions_table(con: Connection):
""" """
cur = con.cursor() cur = con.cursor()
_ = cur.execute(query) _ = cur.execute(query)
def create_session_playlists_table(con: Connection):
query = """
CREATE TABLE IF NOT EXISTS session_playlists (
session_id INTEGER,
playlist_type TEXT,
playlist_id INTEGER NOT NULL,
PRIMARY KEY (session_id, playlist_type),
FOREIGN KEY (session_id) REFERENCES sessions(id) ON DELETE CASCADE,
FOREIGN KEY (playlist_id) REFERENCES playlists(id) ON DELETE CASCADE
)
"""
cur = con.cursor()
_ = cur.execute(query)

View File

@@ -0,0 +1,138 @@
from folkugat_web.dal.sql import Connection, get_connection
from folkugat_web.dal.sql.temes.conversion import row_to_tema
from folkugat_web.model import sessions as sessions_model
from folkugat_web.model import temes as temes_model
from folkugat_web.model.playlists import PlaylistType
from folkugat_web.utils import groupby
from . import conversion
def get_playlist_id(
session_id: int,
playlist_type: PlaylistType,
con: Connection | None = None,
) -> int | None:
query = f"""
SELECT playlist_id
FROM session_playlists
WHERE
session_id = :session_id AND
playlist_type = :playlist_type
"""
data = dict(
session_id=session_id,
playlist_type=playlist_type.value,
)
with get_connection(con) as con:
cur = con.cursor()
_ = cur.execute(query, data)
if row := cur.fetchone():
return row[0]
return None
def insert_playlist(
session_id: int,
playlist_type: PlaylistType,
playlist_id: int,
con: Connection | None = None,
):
query = f"""
INSERT INTO session_playlists
(session_id, playlist_type, playlist_id)
VALUES
(:session_id, :playlist_type, :playlist_id)
"""
data = dict(
session_id=session_id,
playlist_type=playlist_type.value,
playlist_id=playlist_id,
)
with get_connection(con) as con:
cur = con.cursor()
_ = cur.execute(query, data)
def delete_playlist(
session_id: int,
playlist_type: PlaylistType,
con: Connection | None = None,
):
query = f"""
DELETE FROM session_playlists
WHERE
session_id = :session_id AND
playlist_type = :playlist_type
"""
data = dict(
session_id=session_id,
playlist_type=playlist_type.value,
)
with get_connection(con) as con:
cur = con.cursor()
_ = cur.execute(query, data)
GetTuneSessionsRow = tuple[int, int, str, str, str, str | None, str | None, str | None, str | None, bool]
def get_tune_sessions(
tema_ids: list[int],
con: Connection | None = None,
) -> dict[int, list[sessions_model.Session]]:
placeholders = ", ".join(["?" for _ in tema_ids])
query = f"""
SELECT
p.tema_id, s.id, s.date, s.start_time, s.end_time, s.venue_name,
s.venue_url, s.notes, s.cartell_url, s.is_live
FROM playlist_entries p
JOIN session_playlists sp ON p.playlist_id = sp.playlist_id
JOIN sessions s ON sp.session_id = s.id
WHERE
p.tema_id IN ({placeholders}) AND
sp.playlist_type = "{PlaylistType.SESSION_SETLIST.value}"
"""
with get_connection(con) as con:
cur = con.cursor()
_ = cur.execute(query, tema_ids)
result_rows: list[GetTuneSessionsRow] = cur.fetchall()
return dict(groupby(
result_rows,
key_fn=lambda row: row[0],
group_fn=lambda rows: list(conversion.row_to_session(row[1:]) for row in rows)
))
CommonlyPlayedTuneRow = tuple[int, str, str, str, str, int, int]
def get_commonly_played_tunes(
tema_id: int,
con: Connection | None = None,
) -> list[temes_model.CommonlyPlayedTema]:
query = f"""
SELECT
id, title, alternatives, creation_date, modification_date, hidden, count
FROM (
SELECT tema_id, count(*) count FROM playlist_entries p JOIN (
SELECT pe.playlist_id, pe.set_id
FROM playlist_entries pe JOIN session_playlists sp USING (playlist_id)
WHERE tema_id = :tema_id AND playlist_type = :playlist_type
) s
ON p.playlist_id == s.playlist_id AND p.set_id == s.set_id
WHERE tema_id != :tema_id
GROUP BY tema_id
) common JOIN temes t ON common.tema_id == t.id
"""
data = dict(tema_id=tema_id, playlist_type=PlaylistType.SESSION_SETLIST.value)
with get_connection(con) as con:
cur = con.cursor()
_ = cur.execute(query, data)
result_rows: list[CommonlyPlayedTuneRow] = cur.fetchall()
return [
temes_model.CommonlyPlayedTema(
tema=row_to_tema(row[:6]),
count=row[6],
) for row in result_rows
]

View File

@@ -14,7 +14,7 @@ def sessio_en_directe(request: Request):
raise RuntimeError("Got a session without id!") raise RuntimeError("Got a session without id!")
current_set = None current_set = None
if playlist := playlists_service.get_playlist(session_id=session.id): if playlist := service.get_session_setlist(session_id=session.id):
if playlist.sets: if playlist.sets:
current_set = playlists_service.add_temes_to_set(playlist.sets[-1]) current_set = playlists_service.add_temes_to_set(playlist.sets[-1])

View File

@@ -1,6 +1,5 @@
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.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
@@ -8,31 +7,35 @@ from folkugat_web.services.temes import search as search_service
from folkugat_web.templates import templates from folkugat_web.templates import templates
def add_set(request: Request, session_id: int, logged_in: bool): def add_set(
new_set = playlists_service.add_set(session_id=session_id) request: Request,
playlist_id: int,
logged_in: bool,
):
new_set = playlists_service.add_set(playlist_id=playlist_id)
return templates.TemplateResponse( return templates.TemplateResponse(
"fragments/sessio/set_entry.html", "fragments/playlist/set_entry.html",
{ {
"request": request, "request": request,
"logged_in": logged_in, "logged_in": logged_in,
"new_entry": True, "new_entry": True,
"session_id": session_id, "playlist_id": playlist_id,
"set_id": new_set.id, "set_id": new_set.id,
"set_entry": new_set, "set_entry": new_set,
} }
) )
def get_set(request: Request, session_id: int, set_id: int, logged_in: bool): def get_set(request: Request, playlist_id: int, set_id: int, logged_in: bool):
set_entry = playlists_service.get_set(session_id=session_id, set_id=set_id) set_entry = playlists_service.get_set(playlist_id=playlist_id, set_id=set_id)
if set_entry: if set_entry:
return templates.TemplateResponse( return templates.TemplateResponse(
"fragments/sessio/set_entry.html", "fragments/playlist/set_entry.html",
{ {
"request": request, "request": request,
"logged_in": logged_in, "logged_in": logged_in,
"new_entry": True, "new_entry": True,
"session_id": session_id, "playlist_id": playlist_id,
"set_id": set_id, "set_id": set_id,
"set_entry": set_entry, "set_entry": set_entry,
} }
@@ -41,59 +44,59 @@ def get_set(request: Request, session_id: int, set_id: int, logged_in: bool):
return HTMLResponse() return HTMLResponse()
def delete_set(session_id: int, set_id: int): def delete_set(playlist_id: int, set_id: int):
playlists_service.delete_set(session_id=session_id, set_id=set_id) playlists_service.delete_set(playlist_id=playlist_id, set_id=set_id)
return HTMLResponse() return HTMLResponse()
def add_tema(request: Request, session_id: int, set_id: int, logged_in: bool): def add_tema(request: Request, playlist_id: int, set_id: int, logged_in: bool):
new_tema = playlists_service.add_tema(session_id=session_id, set_id=set_id) new_tema = playlists_service.add_tema(playlist_id=playlist_id, set_id=set_id)
playlists_service.add_tema_to_tema_in_set(new_tema) new_tema = playlists_service.add_tema_to_tema_in_set(new_tema)
return templates.TemplateResponse( return templates.TemplateResponse(
"fragments/sessio/tema_editor.html", "fragments/playlist/tema_editor.html",
{ {
"request": request, "request": request,
"logged_in": logged_in, "logged_in": logged_in,
"session_id": session_id, "playlist_id": playlist_id,
"set_id": set_id, "set_id": set_id,
"tema_entry": new_tema, "tema_entry": new_tema,
} }
) )
def get_tema(request: Request, session_id: int, set_id: int, entry_id: int, logged_in: bool): def get_tema(request: Request, playlist_id: int, set_id: int, entry_id: int, logged_in: bool):
tema_entry = playlists_service.get_tema(entry_id=entry_id) tema_entry = playlists_service.get_tema(entry_id=entry_id)
playlists_service.add_tema_to_tema_in_set(tema_entry) tema_entry = playlists_service.add_tema_to_tema_in_set(tema_entry)
return templates.TemplateResponse( return templates.TemplateResponse(
"fragments/sessio/tema_entry.html", "fragments/playlist/tema_entry.html",
{ {
"request": request, "request": request,
"logged_in": logged_in, "logged_in": logged_in,
"session_id": session_id, "playlist_id": playlist_id,
"set_id": set_id, "set_id": set_id,
"tema_entry": tema_entry, "tema_entry": tema_entry,
} }
) )
def get_tema_editor(request: Request, session_id: int, set_id: int, entry_id: int, logged_in: bool): def get_tema_editor(request: Request, playlist_id: int, set_id: int, entry_id: int, logged_in: bool):
tema_entry = playlists_service.get_tema(entry_id=entry_id) tema_entry = playlists_service.get_tema(entry_id=entry_id)
playlists_service.add_tema_to_tema_in_set(tema_entry) tema_entry = playlists_service.add_tema_to_tema_in_set(tema_entry)
return templates.TemplateResponse( return templates.TemplateResponse(
"fragments/sessio/tema_editor.html", "fragments/playlist/tema_editor.html",
{ {
"request": request, "request": request,
"logged_in": logged_in, "logged_in": logged_in,
"session_id": session_id, "playlist_id": playlist_id,
"set_id": set_id, "set_id": set_id,
"tema_entry": tema_entry, "tema_entry": tema_entry,
} }
) )
def delete_tema(session_id: int, set_id: int, entry_id: int): def delete_tema(playlist_id: int, set_id: int, entry_id: int):
playlists_service.delete_tema(entry_id=entry_id) playlists_service.delete_tema(entry_id=entry_id)
if not playlists_service.get_set(session_id=session_id, set_id=set_id): if not playlists_service.get_set(playlist_id=playlist_id, set_id=set_id):
headers = { headers = {
"HX-Trigger": f"reload-set-{set_id}" "HX-Trigger": f"reload-set-{set_id}"
} }
@@ -104,7 +107,7 @@ def delete_tema(session_id: int, set_id: int, entry_id: int):
def busca_tema( def busca_tema(
request: Request, request: Request,
session_id: int, playlist_id: int,
set_id: int, set_id: int,
entry_id: int, entry_id: int,
query: str, query: str,
@@ -114,7 +117,7 @@ def busca_tema(
if not query: if not query:
# If there is no query, suggest tunes commonly played together # If there is no query, suggest tunes commonly played together
set_entry = playlists_service.get_set( set_entry = playlists_service.get_set(
session_id=session_id, playlist_id=playlist_id,
set_id=set_id, set_id=set_id,
) )
if set_entry: if set_entry:
@@ -124,7 +127,7 @@ def busca_tema(
commonly_played_tema_ids = { commonly_played_tema_ids = {
cpt.tema.id cpt.tema.id
for tema_id in tema_ids for tema_id in tema_ids
for cpt in playlists_service.get_commonly_played_temes(tema_id) for cpt in sessions_service.get_commonly_played_temes(tema_id)
if cpt.tema.id is not None if cpt.tema.id is not None
} - tema_ids } - tema_ids
suggestions = query_service.get_temes_by_ids( suggestions = query_service.get_temes_by_ids(
@@ -141,10 +144,10 @@ def busca_tema(
offset=0, offset=0,
) )
return templates.TemplateResponse( return templates.TemplateResponse(
"fragments/sessio/tema_results.html", "fragments/playlist/tema_results.html",
{ {
"request": request, "request": request,
"session_id": session_id, "playlist_id": playlist_id,
"set_id": set_id, "set_id": set_id,
"entry_id": entry_id, "entry_id": entry_id,
"results": suggestions, "results": suggestions,
@@ -153,16 +156,16 @@ def busca_tema(
) )
def set_tema(request: Request, logged_in: bool, session_id: int, set_id: int, entry_id: int, tema_id: int | None): def set_tema(request: Request, logged_in: bool, playlist_id: int, set_id: int, entry_id: int, tema_id: int | None):
playlists_service.set_tema(session_id=session_id, set_id=set_id, entry_id=entry_id, tema_id=tema_id) playlists_service.set_tema(playlist_id=playlist_id, set_id=set_id, entry_id=entry_id, tema_id=tema_id)
tema_entry = playlists_service.get_tema(entry_id=entry_id) tema_entry = playlists_service.get_tema(entry_id=entry_id)
playlists_service.add_tema_to_tema_in_set(tema_entry) tema_entry = playlists_service.add_tema_to_tema_in_set(tema_entry)
return templates.TemplateResponse( return templates.TemplateResponse(
"fragments/sessio/tema_entry.html", "fragments/playlist/tema_entry.html",
{ {
"request": request, "request": request,
"logged_in": logged_in, "logged_in": logged_in,
"session_id": session_id, "playlist_id": playlist_id,
"set_id": set_id, "set_id": set_id,
"tema_entry": tema_entry, "tema_entry": tema_entry,
} }

View File

@@ -1,10 +1,5 @@
from fastapi import Request from fastapi import Request
from fastapi.responses import HTMLResponse
from folkugat_web.model.pagines import Pages
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 search as search_service
from folkugat_web.templates import templates from folkugat_web.templates import templates

View File

@@ -0,0 +1,30 @@
from fastapi import Request
from folkugat_web.services import sessions as sessions_service
from folkugat_web.templates import templates
def notes(request: Request, session_id: int, logged_in: bool):
session = sessions_service.get_session(session_id=session_id)
return templates.TemplateResponse(
"fragments/sessio/notes.html",
{
"request": request,
"logged_in": logged_in,
"session_id": session_id,
"session": session,
"notes": session.notes if session and session.notes else "",
}
)
def notes_editor(request: Request, session_id: int):
session = sessions_service.get_session(session_id=session_id)
return templates.TemplateResponse(
"fragments/sessio/notes_editor.html",
{
"request": request,
"session_id": session_id,
"notes": session.notes if session and session.notes else "",
"max": max,
}
)

View File

@@ -9,8 +9,7 @@ def pagina(request: Request, session_id: int, logged_in: bool):
session = sessions_service.get_session(session_id=session_id) session = sessions_service.get_session(session_id=session_id)
if not session: if not session:
raise HTTPException(status_code=404, detail="Could not find session") raise HTTPException(status_code=404, detail="Could not find session")
playlist = playlists_service.get_playlist(session_id=session_id) session = sessions_service.add_playlists_to_session(session=session)
playlist = playlists_service.add_temes_to_playlist(playlist)
return templates.TemplateResponse( return templates.TemplateResponse(
"fragments/sessio/pagina.html", "fragments/sessio/pagina.html",
{ {
@@ -19,7 +18,6 @@ def pagina(request: Request, session_id: int, logged_in: bool):
"Pages": Pages, "Pages": Pages,
"session_id": session_id, "session_id": session_id,
"session": session, "session": session,
"playlist": playlist,
"date_names": sessions_service.get_date_names, "date_names": sessions_service.get_date_names,
} }
) )

View File

@@ -6,22 +6,20 @@ from folkugat_web.services import sessions as sessions_service
from folkugat_web.templates import templates from folkugat_web.templates import templates
async def pagina(request: Request, session_id: int, set_id: int, logged_in: bool): async def pagina(request: Request, playlist_id: int, set_id: int, logged_in: bool):
session = sessions_service.get_session(session_id=session_id) set_ = playlists_service.get_set(playlist_id=playlist_id, set_id=set_id)
set_ = playlists_service.get_set(session_id=session_id, set_id=set_id)
if not set_: if not set_:
raise HTTPException(status_code=404, detail="Set not found") raise HTTPException(status_code=404, detail="Set not found")
set_ = playlists_service.add_temes_to_set(set_) set_ = playlists_service.add_temes_to_set(set_)
set_ = await playlists_service.add_set_score_to_set(set_) set_ = await playlists_service.add_set_score_to_set(set_)
return templates.TemplateResponse( return templates.TemplateResponse(
"fragments/sessio/set/pagina.html", "fragments/playlist/set/pagina.html",
{ {
"request": request, "request": request,
"logged_in": logged_in, "logged_in": logged_in,
"Pages": Pages, "Pages": Pages,
"session_id": session_id,
"session": session,
"set": set_, "set": set_,
"session": None,
"date_names": sessions_service.get_date_names, "date_names": sessions_service.get_date_names,
"LinkType": LinkType, "LinkType": LinkType,
"ContentType": ContentType, "ContentType": ContentType,
@@ -33,12 +31,12 @@ async def live(request: Request, logged_in: bool):
session = sessions_service.get_live_session() session = sessions_service.get_live_session()
set_ = None set_ = None
if session and session.id: if session and session.id:
playlist = playlists_service.get_playlist(session_id=session.id) playlist = sessions_service.get_session_setlist(session_id=session.id)
if playlist.sets: if playlist and playlist.sets:
set_ = playlists_service.add_temes_to_set(playlist.sets[-1]) set_ = playlists_service.add_temes_to_set(playlist.sets[-1])
set_ = await playlists_service.add_set_score_to_set(set_) set_ = await playlists_service.add_set_score_to_set(set_)
return templates.TemplateResponse( return templates.TemplateResponse(
"fragments/sessio/set/pagina.html", "fragments/playlist/set/pagina.html",
{ {
"request": request, "request": request,
"logged_in": logged_in, "logged_in": logged_in,
@@ -56,12 +54,12 @@ async def live_set(request: Request, logged_in: bool):
session = sessions_service.get_live_session() session = sessions_service.get_live_session()
set_ = None set_ = None
if session and session.id: if session and session.id:
playlist = playlists_service.get_playlist(session_id=session.id) playlist = sessions_service.get_session_setlist(session_id=session.id)
if playlist.sets: if playlist and playlist.sets:
set_ = playlists_service.add_temes_to_set(playlist.sets[-1]) set_ = playlists_service.add_temes_to_set(playlist.sets[-1])
set_ = await playlists_service.add_set_score_to_set(set_) set_ = await playlists_service.add_set_score_to_set(set_)
return templates.TemplateResponse( return templates.TemplateResponse(
"fragments/sessio/set/set_page.html", "fragments/playlist/set/set_page.html",
{ {
"request": request, "request": request,
"logged_in": logged_in, "logged_in": logged_in,

View File

@@ -1,4 +1,5 @@
import dataclasses import dataclasses
import enum
from collections.abc import Iterator from collections.abc import Iterator
from typing import Self from typing import Self
@@ -6,10 +7,15 @@ from folkugat_web.model.temes import Tema
from folkugat_web.utils import groupby from folkugat_web.utils import groupby
class PlaylistType(enum.Enum):
SESSION_SETLIST = "session_setlist"
SESSION_SLOWJAM = "session_slowjam"
@dataclasses.dataclass @dataclasses.dataclass
class PlaylistEntry: class PlaylistEntry:
id: int | None id: int | None
session_id: int playlist_id: int
set_id: int set_id: int
tema_id: int | None tema_id: int | None
@@ -20,17 +26,21 @@ class TemaInSet:
tema_id: int | None tema_id: int | None
tema: Tema | None tema: Tema | None
def to_playlist_entry(self, session_id: int, set_id: int) -> PlaylistEntry: def to_playlist_entry(self, playlist_id: int, set_id: int) -> PlaylistEntry:
return PlaylistEntry( return PlaylistEntry(
id=self.id, id=self.id,
session_id=session_id, playlist_id=playlist_id,
set_id=set_id, set_id=set_id,
tema_id=self.tema_id, tema_id=self.tema_id,
) )
@classmethod @classmethod
def from_playlist_entry(cls, entry: PlaylistEntry) -> Self: def from_playlist_entry(cls, entry: PlaylistEntry) -> Self:
return cls(id=entry.id, tema_id=entry.tema_id, tema=None) return cls(
id=entry.id,
tema_id=entry.tema_id,
tema=None,
)
@dataclasses.dataclass @dataclasses.dataclass
@@ -45,10 +55,10 @@ class Set:
temes: list[TemaInSet] temes: list[TemaInSet]
score: SetScore | None score: SetScore | None
def to_playlist_entries(self, session_id: int) -> Iterator[PlaylistEntry]: def to_playlist_entries(self, playlist_id: int) -> Iterator[PlaylistEntry]:
for tema_in_set in self.temes: for tema_in_set in self.temes:
yield tema_in_set.to_playlist_entry( yield tema_in_set.to_playlist_entry(
session_id=session_id, playlist_id=playlist_id,
set_id=self.id, set_id=self.id,
) )
@@ -58,26 +68,29 @@ class Set:
raise ValueError("All PlaylistEntries must have the same session_id") raise ValueError("All PlaylistEntries must have the same session_id")
return cls( return cls(
id=set_id, id=set_id,
temes=[TemaInSet.from_playlist_entry(entry) for entry in sorted(entries, key=lambda e: e.id or 0)], temes=[
TemaInSet.from_playlist_entry(entry)
for entry in sorted(entries, key=lambda e: e.id or 0)
],
score=None, score=None,
) )
@dataclasses.dataclass @dataclasses.dataclass
class Playlist: class Playlist:
session_id: int id: int
sets: list[Set] sets: list[Set]
def to_playlist_entries(self) -> Iterator[PlaylistEntry]: def to_playlist_entries(self) -> Iterator[PlaylistEntry]:
for set_entry in self.sets: for set_entry in self.sets:
yield from set_entry.to_playlist_entries(session_id=self.session_id) yield from set_entry.to_playlist_entries(playlist_id=self.id)
@classmethod @classmethod
def from_playlist_entries(cls, session_id: int, entries: list[PlaylistEntry]) -> Self: def from_playlist_entries(cls, playlist_id: int, entries: list[PlaylistEntry]) -> Self:
if any(entry.session_id != session_id for entry in entries): if any(entry.playlist_id != playlist_id for entry in entries):
raise ValueError("All PlaylistEntries must have the same session_id") raise ValueError("All PlaylistEntries must have the same playlist_id")
return cls( return cls(
session_id=session_id, id=playlist_id,
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)

View File

@@ -2,6 +2,8 @@ import dataclasses
import datetime import datetime
import enum import enum
from folkugat_web.model import playlists
DEFAULT_START_TIME = datetime.time(20, 30) DEFAULT_START_TIME = datetime.time(20, 30)
DEFAULT_END_TIME = datetime.time(22, 30) DEFAULT_END_TIME = datetime.time(22, 30)
@@ -21,6 +23,8 @@ class Session:
venue: SessionVenue = dataclasses.field(default_factory=SessionVenue) venue: SessionVenue = dataclasses.field(default_factory=SessionVenue)
notes: str | None = None notes: str | None = None
cartell_url: str | None = None cartell_url: str | None = None
slowjam: playlists.Playlist | None = None
setlist: playlists.Playlist | None = None
is_live: bool = False is_live: bool = False

View File

@@ -4,13 +4,15 @@ import dataclasses
import datetime import datetime
import enum import enum
import itertools import itertools
from typing import Self from typing import TYPE_CHECKING, Self
from folkugat_web.model.lilypond.processing import RenderError from folkugat_web.model.lilypond.processing import RenderError
from folkugat_web.model.search import NGrams from folkugat_web.model.search import NGrams
from folkugat_web.model.sessions import Session
from folkugat_web.services import ngrams from folkugat_web.services import ngrams
if TYPE_CHECKING:
from folkugat_web.model.sessions import Session
class ContentType(enum.Enum): class ContentType(enum.Enum):
PARTITURA = "partitura" PARTITURA = "partitura"

View File

@@ -5,7 +5,6 @@ from folkugat_web.dal.sql._connection import get_connection
from folkugat_web.dal.sql.playlists import query, write from folkugat_web.dal.sql.playlists import query, write
from folkugat_web.log import logger from folkugat_web.log import logger
from folkugat_web.model import playlists from folkugat_web.model import playlists
from folkugat_web.model import temes as temes_model
from folkugat_web.model.lilypond import score as lilypond_model from folkugat_web.model.lilypond import score as lilypond_model
from folkugat_web.services import files as files_service from folkugat_web.services import files as files_service
from folkugat_web.services.lilypond import build as lilypond_build from folkugat_web.services.lilypond import build as lilypond_build
@@ -41,37 +40,37 @@ def add_tema_to_tema_in_set(tema_in_set: playlists.TemaInSet) -> playlists.TemaI
return tema_in_set return tema_in_set
def get_playlist(session_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( return playlists.Playlist.from_playlist_entries(
session_id=session_id, playlist_id=playlist_id,
entries=list(query.get_playlist_entries(session_id=session_id, con=con)) entries=list(query.get_playlist_entries(playlist_id=playlist_id, con=con))
) )
def add_set(session_id: int, con: Connection | None = None) -> playlists.Set: def add_set(playlist_id: int, con: Connection | None = None) -> playlists.Set:
with get_connection(con) as con: with get_connection(con) as con:
curr_playlist = get_playlist(session_id=session_id, con=con) curr_playlist = get_playlist(playlist_id=playlist_id, con=con)
new_set_id = max([set_entry.id for set_entry in curr_playlist.sets], default=0) + 1 new_set_id = max([set_entry.id for set_entry in curr_playlist.sets], default=0) + 1
new_entry = playlists.PlaylistEntry(id=None, session_id=session_id, set_id=new_set_id, tema_id=None) new_entry = playlists.PlaylistEntry(id=None, playlist_id=playlist_id, set_id=new_set_id, tema_id=None)
inserted_entry = write.insert_playlist_entry(new_entry) inserted_entry = write.insert_playlist_entry(new_entry)
return playlists.Set.from_playlist_entries(set_id=inserted_entry.set_id, entries=[inserted_entry]) return playlists.Set.from_playlist_entries(set_id=inserted_entry.set_id, entries=[inserted_entry])
def get_set(session_id: int, set_id: int, con: Connection | None = None) -> playlists.Set | None: def get_set(playlist_id: int, set_id: int, con: Connection | None = None) -> playlists.Set | None:
entries = list(query.get_playlist_entries(session_id=session_id, set_id=set_id, con=con)) entries = list(query.get_playlist_entries(playlist_id=playlist_id, set_id=set_id, con=con))
if entries: if entries:
return playlists.Set.from_playlist_entries(set_id=set_id, entries=entries) return playlists.Set.from_playlist_entries(set_id=set_id, entries=entries)
else: else:
return None return None
def delete_set(session_id: int, set_id: int, con: Connection | None = None): def delete_set(playlist_id: int, set_id: int, con: Connection | None = None):
write.delete_playlist_set(session_id=session_id, set_id=set_id, con=con) write.delete_playlist_set(playlist_id=playlist_id, set_id=set_id, con=con)
def add_tema(session_id: int, set_id: int, con: Connection | None = None) -> playlists.TemaInSet: def add_tema(playlist_id: int, set_id: int, con: Connection | None = None) -> playlists.TemaInSet:
with get_connection(con) as con: with get_connection(con) as con:
new_entry = playlists.PlaylistEntry(id=None, session_id=session_id, set_id=set_id, tema_id=None) new_entry = playlists.PlaylistEntry(id=None, playlist_id=playlist_id, set_id=set_id, tema_id=None)
inserted_entry = write.insert_playlist_entry(new_entry) inserted_entry = write.insert_playlist_entry(new_entry)
return playlists.TemaInSet.from_playlist_entry(inserted_entry) return playlists.TemaInSet.from_playlist_entry(inserted_entry)
@@ -87,10 +86,10 @@ def delete_tema(entry_id: int, con: Connection | None = None):
write.delete_playlist_entry(entry_id=entry_id, con=con) write.delete_playlist_entry(entry_id=entry_id, con=con)
def set_tema(session_id: int, set_id: int, entry_id: int, tema_id: int | None, def set_tema(playlist_id: int, set_id: int, entry_id: int, tema_id: int | None,
con: Connection | None = None): con: Connection | None = None):
with get_connection(con) as con: with get_connection(con) as con:
new_entry = playlists.PlaylistEntry(id=entry_id, session_id=session_id, set_id=set_id, tema_id=tema_id) new_entry = playlists.PlaylistEntry(id=entry_id, playlist_id=playlist_id, set_id=set_id, tema_id=tema_id)
write.update_playlist_entry(entry=new_entry, con=con) write.update_playlist_entry(entry=new_entry, con=con)
@@ -163,9 +162,3 @@ async def add_set_score_to_set(tune_set: playlists.Set) -> playlists.Set:
) )
else: else:
return tune_set return tune_set
def get_commonly_played_temes(
tema_id: int,
) -> list[temes_model.CommonlyPlayedTema]:
return query.get_commonly_played_tunes(tema_id=tema_id)

View File

@@ -1,10 +1,16 @@
import dataclasses
import datetime import datetime
from datetime import date as Date from datetime import date as Date
from folkugat_web.config import date as config from folkugat_web.config import date as config
from folkugat_web.dal.sql import Connection, get_connection
from folkugat_web.dal.sql.sessions import playlists as session_playlists
from folkugat_web.dal.sql.sessions import query, write from folkugat_web.dal.sql.sessions import query, write
from folkugat_web.model import sessions as model from folkugat_web.model import sessions as model
from folkugat_web.model import temes as temes_model
from folkugat_web.model.playlists import Playlist, PlaylistType
from folkugat_web.model.sql import Order, OrderCol, Range from folkugat_web.model.sql import Order, OrderCol, Range
from folkugat_web.services import playlists as playlists_service
def get_date_names(date: Date) -> model.DateNames: def get_date_names(date: Date) -> model.DateNames:
@@ -77,3 +83,80 @@ def stop_live_sessions():
def set_live_session(session_id: int): def set_live_session(session_id: int):
write.set_live_session(session_id=session_id) write.set_live_session(session_id=session_id)
def get_session_playlist_id(
session_id: int,
playlist_type: PlaylistType,
con: Connection | None = None,
) -> int | None:
with get_connection(con=con) as con:
return session_playlists.get_playlist_id(
session_id=session_id,
playlist_type=playlist_type,
con=con,
)
def get_session_playlist(
session_id: int,
playlist_type: PlaylistType,
con: Connection | None = None,
) -> Playlist | None:
with get_connection(con=con) as con:
playlist_id = get_session_playlist_id(
session_id=session_id,
playlist_type=playlist_type,
con=con,
)
if playlist_id is None:
return None
return playlists_service.get_playlist(
playlist_id=playlist_id,
con=con,
)
def get_session_setlist(
session_id: int,
con: Connection | None = None,
) -> Playlist | None:
return get_session_playlist(
session_id=session_id,
playlist_type=PlaylistType.SESSION_SETLIST,
con=con,
)
def get_session_slowjam(
session_id: int,
con: Connection | None = None,
) -> Playlist | None:
return get_session_playlist(
session_id=session_id,
playlist_type=PlaylistType.SESSION_SLOWJAM,
con=con,
)
def add_playlists_to_session(session: model.Session) -> model.Session:
if session.id is not None:
with get_connection() as con:
setlist = get_session_setlist(session_id=session.id, con=con)
if setlist:
setlist = playlists_service.add_temes_to_playlist(setlist)
slowjam = get_session_slowjam(session_id=session.id, con=con)
if slowjam:
slowjam = playlists_service.add_temes_to_playlist(slowjam)
session = dataclasses.replace(
session,
setlist=setlist,
slowjam=slowjam,
)
return session
def get_commonly_played_temes(
tema_id: int,
) -> list[temes_model.CommonlyPlayedTema]:
return session_playlists.get_commonly_played_tunes(tema_id=tema_id)

View File

@@ -1,6 +1,6 @@
from collections.abc import Iterable from collections.abc import Iterable
from folkugat_web.dal.sql.playlists import query as playlists_q from folkugat_web.dal.sql.sessions import playlists as session_playlists
from folkugat_web.dal.sql.temes import query as temes_q from folkugat_web.dal.sql.temes import query as temes_q
from folkugat_web.model import sessions as sessions_model from folkugat_web.model import sessions as sessions_model
from folkugat_web.model import temes as model from folkugat_web.model import temes as model
@@ -20,7 +20,7 @@ def tema_compute_stats(
) -> model.Tema: ) -> model.Tema:
if tema.id: if tema.id:
if tune_sessions_dict is None: if tune_sessions_dict is None:
tune_sessions_dict = playlists_q.get_tune_sessions(tema_ids=[tema.id]) tune_sessions_dict = session_playlists.get_tune_sessions(tema_ids=[tema.id])
if tema.id and (tune_sessions := tune_sessions_dict.get(tema.id)): if tema.id and (tune_sessions := tune_sessions_dict.get(tema.id)):
unique_tune_sessions = set(tune_sessions) unique_tune_sessions = set(tune_sessions)
tema.stats = model.Stats( tema.stats = model.Stats(
@@ -33,7 +33,7 @@ def tema_compute_stats(
def temes_compute_stats(temes: Iterable[model.Tema]) -> list[model.Tema]: def temes_compute_stats(temes: Iterable[model.Tema]) -> list[model.Tema]:
temes = list(temes) temes = list(temes)
tema_ids = [tema.id for tema in temes if tema.id is not None] tema_ids = [tema.id for tema in temes if tema.id is not None]
tune_sessions_dict = playlists_q.get_tune_sessions(tema_ids=tema_ids) tune_sessions_dict = session_playlists.get_tune_sessions(tema_ids=tema_ids)
return [tema_compute_stats(tema=tema, tune_sessions_dict=tune_sessions_dict) for tema in temes] return [tema_compute_stats(tema=tema, tune_sessions_dict=tune_sessions_dict) for tema in temes]
@@ -41,5 +41,5 @@ def tema_compute_played_with(
tema: model.Tema, tema: model.Tema,
) -> model.Tema: ) -> model.Tema:
if tema.id: if tema.id:
tema.played_with = playlists_q.get_commonly_played_tunes(tema_id=tema.id) tema.played_with = session_playlists.get_commonly_played_tunes(tema_id=tema.id)
return tema return tema

View File

@@ -0,0 +1,57 @@
from folkugat_web.dal.sql import get_connection
from folkugat_web.dal.sql.playlists import write as playlists_w
from folkugat_web.dal.sql.playlists.ddl import (create_playlist_entries_table,
create_playlists_table)
from folkugat_web.dal.sql.sessions import playlists as session_playlists
from folkugat_web.dal.sql.sessions import query as sessions_q
from folkugat_web.dal.sql.sessions.ddl import create_session_playlists_table
from folkugat_web.model.playlists import PlaylistType
with get_connection() as con:
cur = con.cursor()
drop_query = """DROP TABLE rehearse_data"""
_ = cur.execute(drop_query)
alter_query = """ALTER TABLE playlists RENAME TO playlists_old"""
_ = cur.execute(alter_query)
# Create new tables
create_playlist_entries_table(con=con)
create_playlists_table(con=con)
create_session_playlists_table(con=con)
# Create new playlists
sessions = sessions_q.get_sessions(con=con)
for session in sessions:
if session.id is None:
raise ValueError("Session without id!")
setlist_id = playlists_w.create_playlist(con=con)
session_playlists.insert_playlist(
session_id=session.id,
playlist_type=PlaylistType.SESSION_SETLIST,
playlist_id=setlist_id,
con=con,
)
slowjam_id = playlists_w.create_playlist(con=con)
session_playlists.insert_playlist(
session_id=session.id,
playlist_type=PlaylistType.SESSION_SLOWJAM,
playlist_id=slowjam_id,
con=con,
)
# Migrate
migrate_query = """
INSERT INTO playlist_entries
(id, playlist_id, set_id, tema_id)
SELECT
NULL, sp.playlist_id, pl_old.set_id, pl_old.tema_id
FROM playlists_old pl_old JOIN session_playlists sp USING (session_id)
WHERE sp.playlist_type = "session_setlist"
"""
_ = cur.execute(migrate_query)
print("DONE!")