From c2589581af082b44a0d9673eca869d1ed5b8dbd6 Mon Sep 17 00:00:00 2001 From: anishTP Date: Tue, 9 Jan 2024 18:46:06 +0530 Subject: [PATCH 1/5] added schedule details to update notification view --- devserver.py | 2 +- .../views/notifications/update_notification.py | 18 ++++++++++++++++-- sample.env | 4 ++-- 3 files changed, 19 insertions(+), 5 deletions(-) diff --git a/devserver.py b/devserver.py index 55800a1c0..a8ce61ecf 100755 --- a/devserver.py +++ b/devserver.py @@ -35,7 +35,7 @@ def rq_background_worker(*args: Any, **kwargs: Any) -> Any: # Only start RQ worker within the reloader environment background_rq = BackgroundWorker( rq_background_worker, - mock_transports=bool(getbool(os.environ.get('MOCK_TRANSPORTS', True))), + mock_transports=bool(getbool(os.environ.get('MOCK_TRANSPORTS', False))), ) background_rq.start() diff --git a/funnel/views/notifications/update_notification.py b/funnel/views/notifications/update_notification.py index 388bb6f46..3629c85d2 100644 --- a/funnel/views/notifications/update_notification.py +++ b/funnel/views/notifications/update_notification.py @@ -6,11 +6,12 @@ from baseframe import _, __ -from ...models import Account, NewUpdateNotification, Update +from ...models import Account, NewUpdateNotification, Update, Project from ...transports.sms import SmsPriority, SmsTemplate from ..helpers import shortlink from ..notification import RenderNotification from .mixins import TemplateVarMixin +from ..schedule import session_list_data, schedule_data class UpdateTemplate(TemplateVarMixin, SmsTemplate): @@ -33,6 +34,7 @@ class RenderNewUpdateNotification(RenderNotification): """Notify crew and participants when the project has a new update.""" update: Update + project: Project aliases = {'document': 'update'} emoji_prefix = "📰 " reason = __( @@ -62,7 +64,19 @@ def email_subject(self) -> str: ) def email_content(self) -> str: - return render_template('notifications/update_new_email.html.jinja2', view=self) + scheduled_sessions_list = session_list_data( + self.project.scheduled_sessions, with_modal_url='view' + ) + project = self.project.current_access(datasets=('primary', 'related')) + venues = [ + venue.current_access(datasets=('without_parent', 'related')) + for venue in self.project.venues + ] + schedule = schedule_data( + self.project, with_slots=False, scheduled_sessions=scheduled_sessions_list + ) + return render_template('notifications/update_new_email.html.jinja2', view=self, project=project, + venues=venues, schedule=schedule) def sms(self) -> UpdateTemplate: return UpdateTemplate( diff --git a/sample.env b/sample.env index 159905cbc..08c528399 100644 --- a/sample.env +++ b/sample.env @@ -107,9 +107,9 @@ FLASK_CACHE_REDIS_URL=redis://${REDIS_HOST}:6379/0 # --- Database configuration DB_HOST=localhost # Main app database -FLASK_SQLALCHEMY_DATABASE_URI='postgresql+psycopg:///funnel' +FLASK_SQLALCHEMY_DATABASE_URI='postgresql+psycopg:///funnel_test' # Geoname database (the use of `__` creates a dict and sets a key in the dict) -FLASK_SQLALCHEMY_BINDS__geoname='postgresql+psycopg:///geoname' +FLASK_SQLALCHEMY_BINDS__geoname='postgresql+psycopg:///geoname_testing' # --- Email configuration # SMTP mail server ('localhost' if Postfix is configured as a relay email server) From 2d0751224ee7b430a0f21e3d58fe9224017b9e08 Mon Sep 17 00:00:00 2001 From: anishTP Date: Tue, 9 Jan 2024 21:23:03 +0530 Subject: [PATCH 2/5] added schedule details to update notification view --- funnel/assets/js/schedule_view.js | 5 +++-- sample.env | 4 ++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/funnel/assets/js/schedule_view.js b/funnel/assets/js/schedule_view.js index 538b82d94..63875eecd 100644 --- a/funnel/assets/js/schedule_view.js +++ b/funnel/assets/js/schedule_view.js @@ -276,8 +276,9 @@ const Schedule = { this.config.slotInterval ); if (this.config.schedule[session.eventDay]) { - this.config.schedule[session.eventDay].sessions[session.startTime].showLabel = - true; + this.config.schedule[session.eventDay].sessions[ + session.startTime + ].showLabel = true; this.config.schedule[session.eventDay].sessions[session.startTime].rooms[ session.room_scoped_name ].talk = session; diff --git a/sample.env b/sample.env index 08c528399..159905cbc 100644 --- a/sample.env +++ b/sample.env @@ -107,9 +107,9 @@ FLASK_CACHE_REDIS_URL=redis://${REDIS_HOST}:6379/0 # --- Database configuration DB_HOST=localhost # Main app database -FLASK_SQLALCHEMY_DATABASE_URI='postgresql+psycopg:///funnel_test' +FLASK_SQLALCHEMY_DATABASE_URI='postgresql+psycopg:///funnel' # Geoname database (the use of `__` creates a dict and sets a key in the dict) -FLASK_SQLALCHEMY_BINDS__geoname='postgresql+psycopg:///geoname_testing' +FLASK_SQLALCHEMY_BINDS__geoname='postgresql+psycopg:///geoname' # --- Email configuration # SMTP mail server ('localhost' if Postfix is configured as a relay email server) From 66c3ec7cff203b61f7091667edb64cb53bb24990 Mon Sep 17 00:00:00 2001 From: anishTP Date: Thu, 11 Jan 2024 21:24:54 +0530 Subject: [PATCH 3/5] created method for retrieving schedule data with room as a dict for rendering in email template --- .../update_new_email.html.jinja2 | 28 +++++++++++++++++++ .../notifications/update_notification.py | 11 ++------ funnel/views/schedule.py | 16 ++++++++++- sample.env | 4 +-- 4 files changed, 48 insertions(+), 11 deletions(-) diff --git a/funnel/templates/notifications/update_new_email.html.jinja2 b/funnel/templates/notifications/update_new_email.html.jinja2 index b33cd1e91..4f8fd16b4 100644 --- a/funnel/templates/notifications/update_new_email.html.jinja2 +++ b/funnel/templates/notifications/update_new_email.html.jinja2 @@ -17,6 +17,34 @@ {% trans update_body=view.update.body %}{{ update_body }}{% endtrans %} + + {% for day, rooms in schedule.items() %} +
+

+ {{ day }} +

+ {% for room, slots in rooms.items() %} + + + + + + {% for slot, sessions in slots.itens() %} + {% for session in sessions %} + + + + + {% endfor %} + {% endfor %} +
Time{{ room }}
{{ session.startTime }}–{{ session.endTime }} + {% if room.talk.title %}

{{ session.title }}

{% endif %} + {% if room.talk.speaker %}

{{ session.speaker }}

{% endif %} +
+ {% endfor %} +
+ {% endfor %} +
{# Button : BEGIN #} diff --git a/funnel/views/notifications/update_notification.py b/funnel/views/notifications/update_notification.py index 3629c85d2..66a4f69cf 100644 --- a/funnel/views/notifications/update_notification.py +++ b/funnel/views/notifications/update_notification.py @@ -11,7 +11,7 @@ from ..helpers import shortlink from ..notification import RenderNotification from .mixins import TemplateVarMixin -from ..schedule import session_list_data, schedule_data +from ..schedule import upcoming_schedule_data_with_room class UpdateTemplate(TemplateVarMixin, SmsTemplate): @@ -64,19 +64,14 @@ def email_subject(self) -> str: ) def email_content(self) -> str: - scheduled_sessions_list = session_list_data( - self.project.scheduled_sessions, with_modal_url='view' - ) project = self.project.current_access(datasets=('primary', 'related')) venues = [ venue.current_access(datasets=('without_parent', 'related')) for venue in self.project.venues ] - schedule = schedule_data( - self.project, with_slots=False, scheduled_sessions=scheduled_sessions_list - ) + schedules = upcoming_schedule_data_with_room(self.project) return render_template('notifications/update_new_email.html.jinja2', view=self, project=project, - venues=venues, schedule=schedule) + venues=venues, schedules=schedules) def sms(self) -> UpdateTemplate: return UpdateTemplate( diff --git a/funnel/views/schedule.py b/funnel/views/schedule.py index cc3058801..2d3242bda 100644 --- a/funnel/views/schedule.py +++ b/funnel/views/schedule.py @@ -3,7 +3,7 @@ from __future__ import annotations from collections import defaultdict -from datetime import timedelta +from datetime import datetime, timedelta from types import SimpleNamespace from typing import TYPE_CHECKING, Any, cast @@ -114,6 +114,20 @@ def schedule_data( schedule.append(daydata) return schedule +def upcoming_schedule_data_with_room(project: Project) -> list[dict]: + schedule = schedule_data(project) + schedule_with_room = [] + for key, day in schedule: + if datetime.strptime(key,'%y-%m-%d') >= datetime.today(): + daydata_with_room: dict[str, dict[str, Any]] = defaultdict(lambda: + defaultdict(Any)) + for slots in schedule[day]: + roomdata: dict[str, Any] = defaultdict(Any) + roomdata[slots.sessions.room_scoped_name].append(slots) + daydata_with_room[day]['room'].append(roomdata) + schedule_with_room.append(daydata_with_room) + return schedule_with_room + def schedule_ical( project: Project, rsvp: Rsvp | None = None, future_only: bool = False diff --git a/sample.env b/sample.env index 159905cbc..08c528399 100644 --- a/sample.env +++ b/sample.env @@ -107,9 +107,9 @@ FLASK_CACHE_REDIS_URL=redis://${REDIS_HOST}:6379/0 # --- Database configuration DB_HOST=localhost # Main app database -FLASK_SQLALCHEMY_DATABASE_URI='postgresql+psycopg:///funnel' +FLASK_SQLALCHEMY_DATABASE_URI='postgresql+psycopg:///funnel_test' # Geoname database (the use of `__` creates a dict and sets a key in the dict) -FLASK_SQLALCHEMY_BINDS__geoname='postgresql+psycopg:///geoname' +FLASK_SQLALCHEMY_BINDS__geoname='postgresql+psycopg:///geoname_testing' # --- Email configuration # SMTP mail server ('localhost' if Postfix is configured as a relay email server) From 490f58d29d044e7f60c80e95b4dbe57cfca2e76b Mon Sep 17 00:00:00 2001 From: anishTP Date: Fri, 12 Jan 2024 18:11:54 +0530 Subject: [PATCH 4/5] code clean-up --- devserver.py | 2 +- .../notifications/layout_email.html.jinja2 | 61 +++++++++++++++ .../notifications/macros_email.html.jinja2 | 74 +++++++++++++------ .../update_new_email.html.jinja2 | 35 ++------- .../notifications/update_notification.py | 16 ++-- funnel/views/schedule.py | 12 +-- 6 files changed, 134 insertions(+), 66 deletions(-) diff --git a/devserver.py b/devserver.py index a8ce61ecf..55800a1c0 100755 --- a/devserver.py +++ b/devserver.py @@ -35,7 +35,7 @@ def rq_background_worker(*args: Any, **kwargs: Any) -> Any: # Only start RQ worker within the reloader environment background_rq = BackgroundWorker( rq_background_worker, - mock_transports=bool(getbool(os.environ.get('MOCK_TRANSPORTS', False))), + mock_transports=bool(getbool(os.environ.get('MOCK_TRANSPORTS', True))), ) background_rq.start() diff --git a/funnel/templates/notifications/layout_email.html.jinja2 b/funnel/templates/notifications/layout_email.html.jinja2 index 1c5a92003..aa0937d6d 100644 --- a/funnel/templates/notifications/layout_email.html.jinja2 +++ b/funnel/templates/notifications/layout_email.html.jinja2 @@ -323,6 +323,67 @@ font-weight: bold; text-align: center; } + + .schedule { + margin: 32px 0 !important; + } + .schedule__date { + font-size: 16px !important; + margin: 0 !important; + text-align: left; + line-height: 1.5; + padding-left: 0 !important; + } + .schedule__table { + margin: 16px 0; + background-color: #fff !important; + overflow: auto; + } + .schedule__row { + overflow: auto; + border-bottom: 1pt solid rgba(132, 146, 166, 0.3) !important; + } + .schedule__row__column--header { + outline: 1px solid rgba(132, 146, 166, 0.3) + border: none !important; + background-color: #fff; + font-size: 16px; + line-height: 1.5; + align: left; + padding: 4px 16px; + width: calc(100% - 150px); + } + .schedule__row__column--time--header { + outline: 1px solid rgba(132, 146, 166, 0.3) + border: none !important; + background-color: #fff; + width: 150px; + padding: 4px 16px; + align: left; + } + .schedule__row__column { + position: relative !important; + outline: 1px solid rgba(132, 146, 166, 0.3) + } + .schedule__row__column__content__title { + width: 100% !important; + } + .schedule__row__column__content__title__duration { + position: relative !important; + background-color: transparent !important; + font-size: 16px !important; + padding: 0 !important; + margin: 0 0 4px !important; + line-height: 1.5 !important; + } + .schedule__row__column__content__title__heading, + .schedule__row__column__content__title__speaker { + font-size: 16px !important; + font-weight: normal !important; + line-height: 1.5 !important; + margin: 0 0 4px; + color: #4d5763; + } .unsubscribe { color: #4d5763; text-decoration: underline; diff --git a/funnel/templates/notifications/macros_email.html.jinja2 b/funnel/templates/notifications/macros_email.html.jinja2 index 6245c1444..fcf24a13a 100644 --- a/funnel/templates/notifications/macros_email.html.jinja2 +++ b/funnel/templates/notifications/macros_email.html.jinja2 @@ -29,29 +29,61 @@ {%- endmacro -%} {% macro cta_button(btn_url, btn_text) %} - - -
- - - - - - + + + +{% endmacro %} + +{% macro schedule_tables(schedule) %} + + {% for day, rooms in schedule.items() %} +
- -
+
+ + + + + + +
+ +
+ +
+
+

+ {% trans %}{{ day }}{% endtrans %} +

+ {% for room, slots in rooms.items() %} + + + + + + {% for slot, sessions in slots.items() %} + {% for session in sessions %} + + + + + {% endfor %} + {% endfor %} + + {% endfor %}
{% trans %}Time{% endtrans %}{% trans %}{{ room }}{% endtrans %}
{% trans start_time=session.startTime, end_time=session.endTime %}{{ start_time }}–{{ end_time }}{% endtrans %} + {% if session.title %}

{% trans title=session.title %}{{ title }}{% endtrans %}

{% endif %} + {% if session.speaker %}

{% trans speaker=session.speaker %}{{ speaker }}{% endtrans %}

{% endif %} +
- -
- + {% endfor %} +
{% endmacro %} {% macro rsvp_footer(view, rsvp_linktext) %} diff --git a/funnel/templates/notifications/update_new_email.html.jinja2 b/funnel/templates/notifications/update_new_email.html.jinja2 index 4f8fd16b4..006ea6bad 100644 --- a/funnel/templates/notifications/update_new_email.html.jinja2 +++ b/funnel/templates/notifications/update_new_email.html.jinja2 @@ -1,5 +1,5 @@ {%- extends "notifications/layout_email.html.jinja2" -%} -{%- from "notifications/macros_email.html.jinja2" import cta_button -%} +{%- from "notifications/macros_email.html.jinja2" import cta_button, schedule_tables -%} {%- block content -%} @@ -17,35 +17,10 @@ {% trans update_body=view.update.body %}{{ update_body }}{% endtrans %} - - {% for day, rooms in schedule.items() %} -
-

- {{ day }} -

- {% for room, slots in rooms.items() %} - - - - - - {% for slot, sessions in slots.itens() %} - {% for session in sessions %} - - - - - {% endfor %} - {% endfor %} -
Time{{ room }}
{{ session.startTime }}–{{ session.endTime }} - {% if room.talk.title %}

{{ session.title }}

{% endif %} - {% if room.talk.speaker %}

{{ session.speaker }}

{% endif %} -
- {% endfor %} -
- {% endfor %} - -
+ + {# Schedule : BEGIN #} + {{ schedule_tables(schedules) }} + {# Schedule: END #} {# Button : BEGIN #} {{ cta_button(view.update.url_for(_external=true, **view.tracking_tags()), gettext("Read on the website") )}} diff --git a/funnel/views/notifications/update_notification.py b/funnel/views/notifications/update_notification.py index 66a4f69cf..376145d79 100644 --- a/funnel/views/notifications/update_notification.py +++ b/funnel/views/notifications/update_notification.py @@ -6,12 +6,12 @@ from baseframe import _, __ -from ...models import Account, NewUpdateNotification, Update, Project +from ...models import Account, NewUpdateNotification, Project, Update from ...transports.sms import SmsPriority, SmsTemplate from ..helpers import shortlink from ..notification import RenderNotification -from .mixins import TemplateVarMixin from ..schedule import upcoming_schedule_data_with_room +from .mixins import TemplateVarMixin class UpdateTemplate(TemplateVarMixin, SmsTemplate): @@ -64,14 +64,12 @@ def email_subject(self) -> str: ) def email_content(self) -> str: - project = self.project.current_access(datasets=('primary', 'related')) - venues = [ - venue.current_access(datasets=('without_parent', 'related')) - for venue in self.project.venues - ] schedules = upcoming_schedule_data_with_room(self.project) - return render_template('notifications/update_new_email.html.jinja2', view=self, project=project, - venues=venues, schedules=schedules) + return render_template( + 'notifications/update_new_email.html.jinja2', + view=self, + schedules=schedules, + ) def sms(self) -> UpdateTemplate: return UpdateTemplate( diff --git a/funnel/views/schedule.py b/funnel/views/schedule.py index 2d3242bda..14506bcf4 100644 --- a/funnel/views/schedule.py +++ b/funnel/views/schedule.py @@ -114,17 +114,19 @@ def schedule_data( schedule.append(daydata) return schedule + def upcoming_schedule_data_with_room(project: Project) -> list[dict]: schedule = schedule_data(project) schedule_with_room = [] for key, day in schedule: - if datetime.strptime(key,'%y-%m-%d') >= datetime.today(): - daydata_with_room: dict[str, dict[str, Any]] = defaultdict(lambda: - defaultdict(Any)) + if datetime.strptime(key, '%y-%m-%d') >= datetime.today(): + daydata_with_room: dict[str, dict[str, list]] = defaultdict( + lambda: defaultdict(list) + ) for slots in schedule[day]: - roomdata: dict[str, Any] = defaultdict(Any) + roomdata: dict[str, Any] = {'date': day, 'rooms': defaultdict(list)} roomdata[slots.sessions.room_scoped_name].append(slots) - daydata_with_room[day]['room'].append(roomdata) + daydata_with_room[day]['rooms'].append(roomdata) schedule_with_room.append(daydata_with_room) return schedule_with_room From 4cd5a86a59b81a659447d2415a29a42fde7d13e2 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Fri, 12 Jan 2024 12:45:13 +0000 Subject: [PATCH 5/5] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- funnel/assets/js/schedule_view.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/funnel/assets/js/schedule_view.js b/funnel/assets/js/schedule_view.js index 63875eecd..538b82d94 100644 --- a/funnel/assets/js/schedule_view.js +++ b/funnel/assets/js/schedule_view.js @@ -276,9 +276,8 @@ const Schedule = { this.config.slotInterval ); if (this.config.schedule[session.eventDay]) { - this.config.schedule[session.eventDay].sessions[ - session.startTime - ].showLabel = true; + this.config.schedule[session.eventDay].sessions[session.startTime].showLabel = + true; this.config.schedule[session.eventDay].sessions[session.startTime].rooms[ session.room_scoped_name ].talk = session;