From: Chris Fulljames Date: Sat, 12 Apr 2025 15:24:08 +0000 (-0400) Subject: Add new event page, refactor jam stuff X-Git-Url: https://littlesong.place/gitweb/?a=commitdiff_plain;h=b8445f79ac6a0ce42fef668ae98c7567e6830399;p=littlesongplace.git Add new event page, refactor jam stuff --- diff --git a/src/littlesongplace/jams.py b/src/littlesongplace/jams.py index 771340e..75a143c 100644 --- a/src/littlesongplace/jams.py +++ b/src/littlesongplace/jams.py @@ -1,3 +1,4 @@ +import functools from dataclasses import dataclass from datetime import datetime, timezone @@ -9,7 +10,20 @@ from .sanitize import sanitize_user_text bp = Blueprint("jams", __name__, url_prefix="/jams") -@bp.get("/") +def jam_owner_only(f): + @functools.wraps(f) + def _wrapper(jamid, *args, **kwargs): + row = db.query( + "SELECT * FROM jams WHERE jamid = ?", [jamid], expect_one=True) + + if row["ownerid"] != g.userid: + abort(403) # Forbidden; cannot modify other user's jam + + return f(jamid, *args, **kwargs) + return _wrapper + + +@bp.get("") def jams(): # Show a list of all jams: ongoing, upcoming, previous rows = db.query( @@ -55,6 +69,7 @@ def jam(jamid): @bp.post("//update") @auth.requires_login +@jam_owner_only def update(jamid): # Update a jam with the new form data, redirect to view page title = request.form["title"] @@ -73,6 +88,7 @@ def update(jamid): @bp.get("//delete") @auth.requires_login +@jam_owner_only def delete(jamid): # Delete a jam, redirect to the jams list row = db.query( @@ -83,35 +99,32 @@ def delete(jamid): return redirect(url_for("jams.jams")) -@bp.get("//events") -def events(jamid): - # Show a list of all events for the jam (current, upcoming, previous) - ... - - @bp.get("//events/create") @auth.requires_login -def events_create(): +@jam_owner_only +def events_create(jamid): # Create a new event and redirect to the edit form ... @bp.get("//events/") -def events_view(eventid): +def events_view(jamid, eventid): # Show the event page ... @bp.post("//events//update") @auth.requires_login -def events_update(jamid): +@jam_owner_only +def events_update(jamid, eventid): # Update an event with the new form data ... @bp.get("//events//delete") @auth.requires_login -def events_delete(jamid): +@jam_owner_only +def events_delete(jamid, eventid): # Delete an event, redirect to list of all events ... @@ -130,7 +143,24 @@ class Jam: @classmethod def from_row(cls, row): - event_rows = db.query("SELECT * FROM jam_events WHERE jamid = ?", [row["jamid"]]) + event_rows = db.query( + """ + SELECT + e.eventid, + e.jamid, + e.title, + e.threadid, + e.created, + e.startdate, + e.enddate, + e.description, + j.title as jam_title, + u.username as jam_ownername + FROM jam_events as e + INNER JOIN jams as j on e.jamid = j.jamid + INNER JOIN users as u on j.ownerid = u.userid + WHERE e.jamid = ? + """, [row["jamid"]]) events = [JamEvent.from_row(r) for r in event_rows] return cls( jamid=row["jamid"], @@ -153,6 +183,8 @@ class JamEvent: startdate: datetime enddate: datetime description: str + jam_title: str + jam_ownername: str # TODO: Comment object? comments: list @@ -168,6 +200,8 @@ class JamEvent: startdate=datetime.fromisoformat(row["startdate"]), enddate=datetime.fromisoformat(row["enddate"]), description=sanitize_user_text(row["description"] or ""), + jam_title=row["jam_title"], + jam_ownername=row["jam_ownername"], # TODO: Comment object? comments=comments, ) diff --git a/src/littlesongplace/templates/jam-event-list.html b/src/littlesongplace/templates/jam-event-list.html new file mode 100644 index 0000000..0e6a802 --- /dev/null +++ b/src/littlesongplace/templates/jam-event-list.html @@ -0,0 +1,21 @@ +{% macro jam_event_list(list_title, events) %} +{% if events %} +

{{ list_title }}

+
+ {% for event in events %} +
+ + {{ event.title }} + + - + + {{ event.jam_title }} + + + Hosted by {{ event.jam_ownername }} + +
+ {% endfor %} +
+{% endif %} +{% endmacro %} diff --git a/src/littlesongplace/templates/jam-event.html b/src/littlesongplace/templates/jam-event.html new file mode 100644 index 0000000..06c4ca1 --- /dev/null +++ b/src/littlesongplace/templates/jam-event.html @@ -0,0 +1,36 @@ +{% extends "base.html" %} + +{% block title %}{{ event.title }} - {{ jam.title }}{% endblock %} + +{% block body %} + +

{{ event.title }} - {{ jam.title }}

+ +
+ Host: + {{ jam.ownername }} +
+ Start Date: + {{ event.startdate.aslocaltime().strftime("%Y-%m-%d @ %H:%M") }} +
+ End Date: + {{ event.enddate.aslocaltime().strftime("%Y-%m-%d @ %H:%M") }} +
+ +
+{{ event.description }} +
+ +

About the Jam

+
+{{ jam.description }} +
+ +

Submissions

+ +{% include "song-list.html" %} + +

Comments

+{{ comment_thread(event.threadid, session['userid'], jam.ownerid, event.comments) }} + +{% endblock %} diff --git a/src/littlesongplace/templates/jam.html b/src/littlesongplace/templates/jam.html index 4704f54..776d7b5 100644 --- a/src/littlesongplace/templates/jam.html +++ b/src/littlesongplace/templates/jam.html @@ -7,12 +7,18 @@

{{ jam.title }}

- Jam Master: {{ jam.username }} + Host: + {{ jam.ownername }}
-

Description

+
{{ jam.description }}
+{% from "jam-event-list.html" import jam_event_list %} +{{ jam_event_list("Ongoing Events", ongoing) }} +{{ jam_event_list("Upcoming Events", upcoming) }} +{{ jam_event_list("Past Events", past) }} + {% endblock %} diff --git a/src/littlesongplace/templates/jams-main.html b/src/littlesongplace/templates/jams-main.html index 7144d4d..1bcf7c4 100644 --- a/src/littlesongplace/templates/jams-main.html +++ b/src/littlesongplace/templates/jams-main.html @@ -6,9 +6,12 @@

Jams

-{% macro jam_list(list_title, jams) %} -{% if jams %} -

{{ list_title }}

+{% from "jam-event-list.html" import jam_event_list %} +{{ jam_event_list("Ongoing Events", ongoing) }} +{{ jam_event_list("Upcoming Events", upcoming) }} +{{ jam_event_list("Recent Events", recent) }} + +

All Jams

{% for jam in jams %}
@@ -21,11 +24,5 @@
{% endfor %}
-{% endif %} -{% endmacro %} - -{{ jam_list("Ongoing Jams", ongoing) }} -{{ jam_list("Upcoming Jams", upcoming) }} -{{ jam_list("Past Jams", past) }} {% endblock %} diff --git a/test/test_jams.py b/test/test_jams.py index 7fa1d41..e415101 100644 --- a/test/test_jams.py +++ b/test/test_jams.py @@ -23,7 +23,7 @@ def test_create_jam(client, user): assert b"New Jam" in response.data def test_jams_list(client, user, jam): - response = client.get("/jams/") + response = client.get("/jams") assert response.status_code == 200 assert b"New Jam" in response.data @@ -44,9 +44,16 @@ def test_update_invalid_jam(client, user): data={"title": "Coolest Jam", "description": "pb and jam"}) assert response.status_code == 404 +def test_update_other_users_jam(client, user, jam): + create_user(client, "otheruser", login=True) + response = client.post( + f"/jams/{jam}/update", + data={"title": "Coolest Jam", "description": "pb and jam"}) + assert response.status_code == 403 + def test_delete_jam(client, user, jam): response = client.get(f"/jams/{jam}/delete", follow_redirects=True) - assert response.request.path == "/jams/" + assert response.request.path == "/jams" assert b"New Jam" not in response.data response = client.get(f"/jams/{jam}") @@ -55,3 +62,8 @@ def test_delete_jam(client, user, jam): def test_delete_invalid_jam(client, user): response = client.get("/jams/1/delete") assert response.status_code == 404 + +def test_delete_other_users_jam(client, user, jam): + create_user(client, "otheruser", login=True) + response = client.get(f"/jams/{jam}/delete") + assert response.status_code == 403