From 37c99cc066f7de0fe70005162a3ddf4eaba5de8e Mon Sep 17 00:00:00 2001 From: James Addison Date: Sat, 15 Jun 2024 20:57:23 +0100 Subject: [PATCH] [video recordings] Send email notifications to speakers when recordings are published. --- apps/api/schedule.py | 19 +++++++++++++++++++ apps/cfp_review/base.py | 7 +++++++ models/cfp.py | 4 ++++ .../emails/video-recording-published.txt | 10 ++++++++++ 4 files changed, 40 insertions(+) create mode 100644 templates/emails/video-recording-published.txt diff --git a/apps/api/schedule.py b/apps/api/schedule.py index f775d8d72..1a0d637f9 100644 --- a/apps/api/schedule.py +++ b/apps/api/schedule.py @@ -6,6 +6,8 @@ from flask_restful import Resource, abort from . import api +from apps.cfp_review.base import send_email_for_proposal +from apps.common.email import from_email from main import db from models.cfp import Proposal from models.ical import CalendarEvent @@ -41,6 +43,10 @@ def patch(self, proposal_id): if not payload: abort(400) + if proposal.video_recording_lost: + # Prevent updates to video recordings already flagged as lost + abort(400) + ALLOWED_ATTRIBUTES = { "youtube_url", "thumbnail_url", @@ -50,13 +56,26 @@ def patch(self, proposal_id): if set(payload.keys()) - ALLOWED_ATTRIBUTES: abort(400) + if "video_recording_lost" in payload and len(payload) > 1: + # Flagging a recording lost is mutually exclusive with other edits + abort(400) + + was_published = proposal.is_video_published for attribute in ALLOWED_ATTRIBUTES: if attribute in payload: setattr(proposal, attribute, payload[attribute] or "") + is_published = proposal.is_video_published db.session.add(proposal) db.session.commit() + if was_published is False and is_published is True: + send_email_for_proposal( + proposal, + reason="video-recording-published", + from_address=from_email("SPEAKERS_EMAIL"), + ) + return { "id": proposal.id, "slug": proposal.slug, diff --git a/apps/cfp_review/base.py b/apps/cfp_review/base.py index b34c2f9aa..b2f7942ec 100644 --- a/apps/cfp_review/base.py +++ b/apps/cfp_review/base.py @@ -325,6 +325,13 @@ def send_email_for_proposal(proposal, reason="still-considered", from_address=No ) template = "emails/cfp-slot-moved.txt" + elif reason == "video-recording-published": + subject = "Your EMF %s video recording has been published ('%s')" % ( + proposal.human_type, + proposal.title, + ) + template = "emails/video-recording-published.txt" + else: raise Exception("Unknown cfp proposal email type %s" % reason) diff --git a/models/cfp.py b/models/cfp.py index abd92ec15..bf1a8e4e5 100644 --- a/models/cfp.py +++ b/models/cfp.py @@ -441,6 +441,10 @@ class Proposal(BaseModel): thumbnail_url = db.Column(db.String) video_recording_lost = db.Column(db.Boolean, default=False) + @property + def is_video_published(self) -> bool: + return any([self.c3voc_url, self.youtube_url]) + type_might_require_ticket = False tickets = db.relationship("EventTicket", backref="proposal") diff --git a/templates/emails/video-recording-published.txt b/templates/emails/video-recording-published.txt new file mode 100644 index 000000000..859e27efe --- /dev/null +++ b/templates/emails/video-recording-published.txt @@ -0,0 +1,10 @@ +{% extends "emails/base.txt" %} +{% block body %} +Hi {{ proposal.user.name }}, + +The video recording for your EMF {{ proposal.human_type }} '{{ proposal.title }}' has been edited and published. + +The video and direct links to it can be found at: https://www.emfcamp.org/schedule/{{ event_year }}/{{ proposal.id }} + +Thank you again for participating in EMF {{ event_year }}! +{% endblock %}