From 2f23c5122f1efa1363d4d2f53d8bb48f6f687c98 Mon Sep 17 00:00:00 2001 From: Robert McWilliam Date: Sat, 25 May 2024 23:32:09 +0100 Subject: [PATCH 1/4] update mapref and put in links --- apps/volunteer/data/venues/arcade.yml | 2 +- apps/volunteer/data/venues/badge_tent.yml | 2 +- apps/volunteer/data/venues/bar.yml | 2 +- apps/volunteer/data/venues/car_park.yml | 2 +- apps/volunteer/data/venues/cybar.yml | 2 +- apps/volunteer/data/venues/entrance_tent.yml | 2 +- apps/volunteer/data/venues/green_room.yml | 2 +- apps/volunteer/data/venues/info_volunteer_tent.yml | 2 +- apps/volunteer/data/venues/logistics_tent.yml | 2 +- apps/volunteer/data/venues/noc.yml | 2 +- apps/volunteer/data/venues/null_sector.yml | 2 +- apps/volunteer/data/venues/phone_tent.yml | 2 +- apps/volunteer/data/venues/shop.yml | 2 +- apps/volunteer/data/venues/stage_a.yml | 2 +- apps/volunteer/data/venues/stage_b.yml | 2 +- apps/volunteer/data/venues/stage_c.yml | 2 +- apps/volunteer/data/venues/vehicle_gate_y.yml | 2 +- apps/volunteer/data/venues/voc.yml | 2 +- apps/volunteer/data/venues/volunteer_kitchen.yml | 2 +- apps/volunteer/data/venues/youth_workshop.yml | 2 +- templates/volunteer/schedule.html | 2 +- 21 files changed, 21 insertions(+), 21 deletions(-) diff --git a/apps/volunteer/data/venues/arcade.yml b/apps/volunteer/data/venues/arcade.yml index 749589486..5647fbfe1 100644 --- a/apps/volunteer/data/venues/arcade.yml +++ b/apps/volunteer/data/venues/arcade.yml @@ -1,2 +1,2 @@ -mapref: https://map.emfcamp.org/#20.82/52.0397817/-2.3767928 +mapref: https://map.emfcamp.org/#17.03/52.041068/-2.377307/m=52.042011,-2.377318 name: Arcade diff --git a/apps/volunteer/data/venues/badge_tent.yml b/apps/volunteer/data/venues/badge_tent.yml index 6a9e3802b..361fc979b 100644 --- a/apps/volunteer/data/venues/badge_tent.yml +++ b/apps/volunteer/data/venues/badge_tent.yml @@ -1,2 +1,2 @@ -mapref: https://map.emfcamp.org/#20.24/52.0405486/-2.3781891 +mapref: https://map.emfcamp.org/#17.06/52.041602/-2.375338/m=52.042277,-2.375297 name: Badge Tent diff --git a/apps/volunteer/data/venues/bar.yml b/apps/volunteer/data/venues/bar.yml index 40ca3e32c..7a68d2a5d 100644 --- a/apps/volunteer/data/venues/bar.yml +++ b/apps/volunteer/data/venues/bar.yml @@ -1,2 +1,2 @@ -mapref: https://map.emfcamp.org/#19/52.0420157/-2.3770749 +mapref: https://map.emfcamp.org/#16.62/52.04154/-2.3771/m=52.042322,-2.377277 name: Bar diff --git a/apps/volunteer/data/venues/car_park.yml b/apps/volunteer/data/venues/car_park.yml index 217d17fec..758c27d4c 100644 --- a/apps/volunteer/data/venues/car_park.yml +++ b/apps/volunteer/data/venues/car_park.yml @@ -1,2 +1,2 @@ -mapref: https://map.emfcamp.org/#19.19/52.0389412/-2.3783488 +mapref: https://map.emfcamp.org/#16/52.038135/-2.37846/m=52.038723,-2.37851 name: Car Park diff --git a/apps/volunteer/data/venues/cybar.yml b/apps/volunteer/data/venues/cybar.yml index ed1cc82c2..ce2930e1b 100644 --- a/apps/volunteer/data/venues/cybar.yml +++ b/apps/volunteer/data/venues/cybar.yml @@ -1,2 +1,2 @@ -mapref: https://map.emfcamp.org/#19/52.0409755/-2.3786306 +mapref: https://map.emfcamp.org/#17.02/52.043133/-2.37699/m=52.0437884,-2.3770287 name: Cybar diff --git a/apps/volunteer/data/venues/entrance_tent.yml b/apps/volunteer/data/venues/entrance_tent.yml index f8170a668..a54c68e8b 100644 --- a/apps/volunteer/data/venues/entrance_tent.yml +++ b/apps/volunteer/data/venues/entrance_tent.yml @@ -1,2 +1,2 @@ -mapref: https://map.emfcamp.org/#18/52.039226/-2.378184 +mapref: https://map.emfcamp.org/#16.65/52.039551/-2.378303/m=52.0392897,-2.3783524 name: Entrance Tent diff --git a/apps/volunteer/data/venues/green_room.yml b/apps/volunteer/data/venues/green_room.yml index c283c721a..9cd57af0d 100644 --- a/apps/volunteer/data/venues/green_room.yml +++ b/apps/volunteer/data/venues/green_room.yml @@ -1,2 +1,2 @@ -mapref: https://map.emfcamp.org/#20.72/52.0414959/-2.378016 +mapref: https://map.emfcamp.org/#16.76/52.040738/-2.377879/m=52.0406657,-2.3780121 name: Green Room diff --git a/apps/volunteer/data/venues/info_volunteer_tent.yml b/apps/volunteer/data/venues/info_volunteer_tent.yml index e56bd0230..75a4a99e0 100644 --- a/apps/volunteer/data/venues/info_volunteer_tent.yml +++ b/apps/volunteer/data/venues/info_volunteer_tent.yml @@ -1,2 +1,2 @@ -mapref: https://map.emfcamp.org/#20.82/52.0397817/-2.3767928 +mapref: https://map.emfcamp.org/#16.61/52.04099/-2.376626/m=52.041813,-2.3769969 name: Info/Volunteer Tent diff --git a/apps/volunteer/data/venues/logistics_tent.yml b/apps/volunteer/data/venues/logistics_tent.yml index dc6e38bd0..50355c72d 100644 --- a/apps/volunteer/data/venues/logistics_tent.yml +++ b/apps/volunteer/data/venues/logistics_tent.yml @@ -1,2 +1,2 @@ -mapref: https://map.emfcamp.org/#20.82/52.0397817/-2.3767928 +mapref: https://map.emfcamp.org/#16.53/52.040206/-2.37686/m=52.0399083,-2.3767278 name: Logistics Tent diff --git a/apps/volunteer/data/venues/noc.yml b/apps/volunteer/data/venues/noc.yml index 3048fabee..3f25bb775 100644 --- a/apps/volunteer/data/venues/noc.yml +++ b/apps/volunteer/data/venues/noc.yml @@ -1,2 +1,2 @@ -mapref: https://map.emfcamp.org/#21.49/52.0415113/-2.3776567 +mapref: https://map.emfcamp.org/#16.95/52.039438/-2.377115/m=52.0395588,-2.3771013 name: NOC diff --git a/apps/volunteer/data/venues/null_sector.yml b/apps/volunteer/data/venues/null_sector.yml index d97ce05e9..76f97b3ab 100644 --- a/apps/volunteer/data/venues/null_sector.yml +++ b/apps/volunteer/data/venues/null_sector.yml @@ -1,2 +1,2 @@ -mapref: https://map.emfcamp.org/#19/52.0409755/-2.3786306 +mapref: https://map.emfcamp.org/#17.17/52.043132/-2.377102/m=52.0436251,-2.3770731 name: Null Sector diff --git a/apps/volunteer/data/venues/phone_tent.yml b/apps/volunteer/data/venues/phone_tent.yml index 632888613..56b800d7d 100644 --- a/apps/volunteer/data/venues/phone_tent.yml +++ b/apps/volunteer/data/venues/phone_tent.yml @@ -1,2 +1,2 @@ -mapref: https://map.emfcamp.org/#20.42/52.0399054/-2.3768637 +mapref: https://map.emfcamp.org/#16.81/52.039713/-2.376886/m=52.0399211,-2.3768469 name: Phone Team Tent diff --git a/apps/volunteer/data/venues/shop.yml b/apps/volunteer/data/venues/shop.yml index 0600e63a8..a9fdb7589 100644 --- a/apps/volunteer/data/venues/shop.yml +++ b/apps/volunteer/data/venues/shop.yml @@ -1,2 +1,2 @@ -mapref: https://map.emfcamp.org/#20.82/52.0397817/-2.3767928 +mapref: https://map.emfcamp.org/#17.24/52.041165/-2.377744/m=52.0413849,-2.3778526 name: Shop diff --git a/apps/volunteer/data/venues/stage_a.yml b/apps/volunteer/data/venues/stage_a.yml index 70c1b6f87..7a357b6d7 100644 --- a/apps/volunteer/data/venues/stage_a.yml +++ b/apps/volunteer/data/venues/stage_a.yml @@ -1,2 +1,2 @@ -mapref: https://map.emfcamp.org/#17/52.039601/-2.377759 +mapref: https://map.emfcamp.org/#16.51/52.039593/-2.378368/m=52.0399551,-2.3783369 name: Stage A diff --git a/apps/volunteer/data/venues/stage_b.yml b/apps/volunteer/data/venues/stage_b.yml index f24a0f2d1..945df7e71 100644 --- a/apps/volunteer/data/venues/stage_b.yml +++ b/apps/volunteer/data/venues/stage_b.yml @@ -1,2 +1,2 @@ -mapref: https://map.emfcamp.org/#17/52.041798/-2.376412 +mapref: https://map.emfcamp.org/#16.72/52.041168/-2.376755/m=52.041798,-2.37667 name: Stage B diff --git a/apps/volunteer/data/venues/stage_c.yml b/apps/volunteer/data/venues/stage_c.yml index 36a323764..e455a52bf 100644 --- a/apps/volunteer/data/venues/stage_c.yml +++ b/apps/volunteer/data/venues/stage_c.yml @@ -1,2 +1,2 @@ -mapref: https://map.emfcamp.org/#17/52.040482/-2.377432 +mapref: https://map.emfcamp.org/#16.84/52.040478/-2.377832/m=52.040607,-2.377842 name: Stage C diff --git a/apps/volunteer/data/venues/vehicle_gate_y.yml b/apps/volunteer/data/venues/vehicle_gate_y.yml index 7717b7465..2e980111f 100644 --- a/apps/volunteer/data/venues/vehicle_gate_y.yml +++ b/apps/volunteer/data/venues/vehicle_gate_y.yml @@ -1,2 +1,2 @@ -mapref: https://map.emfcamp.org/#21.49/52.0415113/-2.3776567 +mapref: https://map.emfcamp.org/#16.43/52.039329/-2.376927/m=52.0391181,-2.3770662 name: Vehicle Gate Y diff --git a/apps/volunteer/data/venues/voc.yml b/apps/volunteer/data/venues/voc.yml index 1f79d8fed..19b4cea29 100644 --- a/apps/volunteer/data/venues/voc.yml +++ b/apps/volunteer/data/venues/voc.yml @@ -1,2 +1,2 @@ -mapref: https://map.emfcamp.org/#20.72/52.0414959/-2.378016 +mapref: https://map.emfcamp.org/#16.91/52.04049/-2.37799/m=52.040724,-2.377994 name: VOC diff --git a/apps/volunteer/data/venues/volunteer_kitchen.yml b/apps/volunteer/data/venues/volunteer_kitchen.yml index 5503367ce..543fe473b 100644 --- a/apps/volunteer/data/venues/volunteer_kitchen.yml +++ b/apps/volunteer/data/venues/volunteer_kitchen.yml @@ -1,2 +1,2 @@ -mapref: https://map.emfcamp.org/#20.82/52.0397817/-2.3767928 +mapref: https://map.emfcamp.org/#17.05/52.041005/-2.376121/m=52.0417823,-2.3760325 name: Volunteer Kitchen diff --git a/apps/volunteer/data/venues/youth_workshop.yml b/apps/volunteer/data/venues/youth_workshop.yml index 0e606307e..e93919e00 100644 --- a/apps/volunteer/data/venues/youth_workshop.yml +++ b/apps/volunteer/data/venues/youth_workshop.yml @@ -1,2 +1,2 @@ -mapref: https://map.emfcamp.org/#19.46/52.0420979/-2.3753702 +mapref: https://map.emfcamp.org/#16.68/52.040881/-2.377577/m=52.041475,-2.377593 name: Youth Workshop diff --git a/templates/volunteer/schedule.html b/templates/volunteer/schedule.html index ad70282e6..2c641da8b 100644 --- a/templates/volunteer/schedule.html +++ b/templates/volunteer/schedule.html @@ -87,7 +87,7 @@

Pick your shifts

{{ hour }}{% if shift.end %} to {{ shift.end_time }}{% endif %} {% endif %} - {{ shift.venue.name }} + {{ shift.venue.name }} {{ shift.role.name }} {{ shift.current_count }}/{{ shift.max_needed }} From f74a987cf9984240c8d7a611181c05a7990bf8b7 Mon Sep 17 00:00:00 2001 From: Ed Kellett Date: Sun, 26 May 2024 00:08:49 +0100 Subject: [PATCH 2/4] Add an iCal feed for volunteer shifts --- apps/volunteer/schedule.py | 54 +++++++++++++++++++++++++++++-- templates/volunteer/schedule.html | 2 ++ 2 files changed, 54 insertions(+), 2 deletions(-) diff --git a/apps/volunteer/schedule.py b/apps/volunteer/schedule.py index 061aa161e..175d343e3 100644 --- a/apps/volunteer/schedule.py +++ b/apps/volunteer/schedule.py @@ -1,12 +1,16 @@ # coding=utf-8 import pendulum +from icalendar import Calendar, Event from datetime import datetime -from flask import render_template, request, redirect, url_for, flash, session +from flask import render_template, request, redirect, url_for, flash, abort, session, Response +from flask import current_app as app from collections import defaultdict from flask_login import current_user +from sqlalchemy.orm import joinedload, defer from main import db -from models.user import User +from models import event_year +from models.user import User, generate_api_token from models.volunteer.role import Role from models.volunteer.venue import VolunteerVenue @@ -14,6 +18,7 @@ from models.volunteer.volunteer import Volunteer from models import config_date +from ..schedule import event_tz from ..users import get_next_url from ..common import feature_flag from . import volunteer, v_user_required, v_admin_required @@ -78,6 +83,8 @@ def schedule(): r for r in roles if r["is_interested"] and r["requires_training"] and not r["is_trained"] ] + token = generate_api_token(app.config["SECRET_KEY"], current_user.id) + return render_template( "volunteer/schedule.html", roles=roles, @@ -85,9 +92,52 @@ def schedule(): all_shifts=by_time, active_day=active_day, untrained_roles=untrained_roles, + token=token, ) +@volunteer.route("/schedule.ical") +@volunteer.route("/schedule.ics") +@feature_flag("VOLUNTEERS_SCHEDULE") +def schedule_ical(): + code = request.args.get("token", None) + user = None + if code: + user = User.get_by_api_token(app.config.get("SECRET_KEY"), str(code)) + if not current_user.is_anonymous: + user = current_user + if not user: + abort(404) + + title = "EMF {} Volunteer Shifts for {}".format(event_year(), user.name) + + cal = Calendar() + cal.add("summary", title) + cal.add("X-WR-CALNAME", title) + cal.add("X-WR-CALDESC", title) + cal.add("version", "2.0") + + shifts = (Shift.query + .select_from(ShiftEntry) + .join(Shift.entries.and_(ShiftEntry.user == user)) + .options( + defer(Shift.current_count), # the subquery for that column breaks this query + joinedload(Shift.venue), + joinedload(Shift.role) + )).all() + + for shift in shifts: + cal_event = Event() + cal_event.add("uid", "%s-%s" % (event_year(), shift.id)) + cal_event.add("summary", "%s at %s" % (shift.role.name, shift.venue.name)) + cal_event.add("location", shift.venue.name) + cal_event.add("dtstart", event_tz.localize(shift.start)) + cal_event.add("dtend", event_tz.localize(shift.end)) + cal.add_component(cal_event) + + return Response(cal.to_ical(), mimetype="text/calendar") + + @volunteer.route("/shift/", methods=["GET"]) @feature_flag("VOLUNTEERS_SCHEDULE") @v_admin_required diff --git a/templates/volunteer/schedule.html b/templates/volunteer/schedule.html index 2c641da8b..cff1f8ee8 100644 --- a/templates/volunteer/schedule.html +++ b/templates/volunteer/schedule.html @@ -21,6 +21,8 @@

Pick your shifts

Select a day to sign up for shifts. To change which roles you're interested in, click here.

+

You can get a list of all your shifts as an iCal feed.

+ {% if untrained_roles %}
You still need training before starting a shift for the following roles: From ca219f1ac94b55292ddce6f409c242c1084075db Mon Sep 17 00:00:00 2001 From: Ed Kellett Date: Sun, 26 May 2024 01:10:18 +0100 Subject: [PATCH 3/4] Fix joining Shift+ShiftEntry, unhack volunteer schedule_ical https://docs.sqlalchemy.org/en/14/orm/mapped_sql_expr.html leads me to believe this was just a bug in the definition of current_count. --- apps/volunteer/schedule.py | 3 +-- models/volunteer/shift.py | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/apps/volunteer/schedule.py b/apps/volunteer/schedule.py index 175d343e3..039b565f8 100644 --- a/apps/volunteer/schedule.py +++ b/apps/volunteer/schedule.py @@ -6,7 +6,7 @@ from flask import current_app as app from collections import defaultdict from flask_login import current_user -from sqlalchemy.orm import joinedload, defer +from sqlalchemy.orm import joinedload from main import db from models import event_year @@ -121,7 +121,6 @@ def schedule_ical(): .select_from(ShiftEntry) .join(Shift.entries.and_(ShiftEntry.user == user)) .options( - defer(Shift.current_count), # the subquery for that column breaks this query joinedload(Shift.venue), joinedload(Shift.role) )).all() diff --git a/models/volunteer/shift.py b/models/volunteer/shift.py index 33f70e292..2325a2430 100644 --- a/models/volunteer/shift.py +++ b/models/volunteer/shift.py @@ -71,7 +71,7 @@ class Shift(BaseModel): proposal = db.relationship("Proposal", backref="shift") current_count = db.column_property( - select([func.count(ShiftEntry.shift_id)]).where(ShiftEntry.shift_id == id).scalar_subquery() # type: ignore[attr-defined] + select([func.count(ShiftEntry.shift_id)]).where(ShiftEntry.shift_id == id).correlate_except(ShiftEntry).scalar_subquery() # type: ignore[attr-defined] ) duration = db.column_property(end - start) From d6fa902bb398118ba5469e8cb808bd7e90b7e250 Mon Sep 17 00:00:00 2001 From: Ed Kellett Date: Sun, 26 May 2024 11:01:33 +0100 Subject: [PATCH 4/4] Supress type FP for Shift.current_count --- models/volunteer/shift.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/models/volunteer/shift.py b/models/volunteer/shift.py index 2325a2430..f109e8075 100644 --- a/models/volunteer/shift.py +++ b/models/volunteer/shift.py @@ -71,7 +71,7 @@ class Shift(BaseModel): proposal = db.relationship("Proposal", backref="shift") current_count = db.column_property( - select([func.count(ShiftEntry.shift_id)]).where(ShiftEntry.shift_id == id).correlate_except(ShiftEntry).scalar_subquery() # type: ignore[attr-defined] + select([func.count(ShiftEntry.shift_id)]).where(ShiftEntry.shift_id == id).correlate_except(ShiftEntry).scalar_subquery() # type: ignore[attr-defined,arg-type] ) duration = db.column_property(end - start)