Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add contributions placeholder for emails #4716

Merged
merged 6 commits into from Nov 23, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGES.rst
Expand Up @@ -12,6 +12,7 @@ Improvements

- Disable title field by default in new registration forms (:issue:`4688`, :pr:`4692`)
- Add gender-neutral "Mx" title (:issue:`4688`, :pr:`4692`)
- Add contributions placeholder for emails (:pr:`4716`, thanks :user:`bpedersen2`)

Bugfixes
^^^^^^^^
Expand Down
21 changes: 21 additions & 0 deletions indico/modules/events/contributions/util.py
Expand Up @@ -31,6 +31,7 @@
from indico.modules.events.models.events import Event
from indico.modules.events.models.persons import EventPerson
from indico.modules.events.persons.util import get_event_person
from indico.modules.events.timetable.models.entries import TimetableEntry
from indico.modules.events.util import serialize_person_link, track_time_changes
from indico.util.date_time import format_human_timedelta
from indico.util.i18n import _
Expand Down Expand Up @@ -221,6 +222,26 @@ def has_contributions_with_user_as_submitter(event, user):
return _query_contributions_with_user_as_submitter(event, user).has_rows()


def get_contributions_for_person(event, person, only_speakers=False):
"""Get all contributions for an event person.

If ``only_speakers`` is true, then only contributions where the person is a
speaker are returned
"""
cl_join = db.and_(ContributionPersonLink.person_id == person.id,
ContributionPersonLink.contribution_id == Contribution.id)

if only_speakers:
cl_join &= ContributionPersonLink.is_speaker

return (Contribution.query
.with_parent(event)
.join(ContributionPersonLink, cl_join)
.outerjoin(TimetableEntry)
.order_by(TimetableEntry.start_dt, db.func.lower(Contribution.title), Contribution.friendly_id)
.all())


def serialize_contribution_for_ical(contrib):
return {
'_fossil': 'contributionMetadata',
Expand Down
3 changes: 2 additions & 1 deletion indico/modules/events/persons/__init__.py
Expand Up @@ -30,11 +30,12 @@ def _sidemenu_items(sender, event, **kwargs):
def _get_placeholders(sender, person, event, register_link=False, **kwargs):
from indico.modules.events.persons.placeholders import (FirstNamePlaceholder, LastNamePlaceholder, EmailPlaceholder,
EventTitlePlaceholder, EventLinkPlaceholder,
RegisterLinkPlaceholder)
ContributionsPlaceholder, RegisterLinkPlaceholder)
yield FirstNamePlaceholder
yield LastNamePlaceholder
yield EmailPlaceholder
yield EventTitlePlaceholder
yield EventLinkPlaceholder
yield ContributionsPlaceholder
if register_link:
yield RegisterLinkPlaceholder
33 changes: 31 additions & 2 deletions indico/modules/events/persons/placeholders.py
Expand Up @@ -10,11 +10,16 @@
from markupsafe import Markup

from indico.modules.auth.util import url_for_register
from indico.modules.events.contributions.util import get_contributions_for_person
from indico.modules.events.models.persons import EventPerson
from indico.modules.users.models.users import User
from indico.util.i18n import _
from indico.util.placeholders import Placeholder
from indico.util.placeholders import ParametrizedPlaceholder, Placeholder
from indico.web.flask.templating import get_template_module


# XXX: `person` may be either an `EventPerson` or a `User`
# XXX: `person` may be either an `EventPerson` or a `User`; the latter happens
# when emailing role members or people from peer reviewing teams)


class FirstNamePlaceholder(Placeholder):
Expand Down Expand Up @@ -63,6 +68,30 @@ def render(cls, person, event, **kwargs):
title=event.title)


class ContributionsPlaceholder(ParametrizedPlaceholder):
name = 'contributions'
param_required = False
param_restricted = True

@classmethod
def iter_param_info(cls, person, event, **kwargs):
yield None, _("The person's contributions")
yield 'speakers', _("The person's contributions where they are a speaker")

@classmethod
def render(cls, param, person, event, **kwargs):
if isinstance(person, User):
person = EventPerson.query.with_parent(event).filter_by(user_id=person.id).first()
if person is None:
return ''
tpl = get_template_module('events/persons/emails/_contributions.html')
html = tpl.render_contribution_list(
get_contributions_for_person(event, person, only_speakers=(param == 'speakers')),
event.timezone
)
return Markup(html)


class RegisterLinkPlaceholder(Placeholder):
name = 'register_link'
description = _("The link for the registration page")
Expand Down
18 changes: 18 additions & 0 deletions indico/modules/events/persons/templates/emails/_contributions.html
@@ -0,0 +1,18 @@
{% macro render_contribution_list(contributions, timezone) -%}
<ul>
{% for contribution in contributions %}
<li>
<a href="{{ url_for('contributions.display_contribution', contribution) }}">{{ contribution.title }}</a>
(
{%- if contribution.timetable_entry -%}
{{ contribution.timetable_entry.start_dt | format_datetime(format='EEEE', timezone=timezone) }}
{{ contribution.timetable_entry.start_dt | format_datetime(format='medium', timezone=timezone) }}
- {{ contribution.timetable_entry.end_dt | format_datetime(format='HH:mm', timezone=timezone) }}
{%- else -%}
Not scheduled yet
{%- endif -%}
)
</li>
{% endfor %}
</ul>
{%- endmacro %}
2 changes: 1 addition & 1 deletion indico/web/templates/placeholder_info.html
Expand Up @@ -8,7 +8,7 @@
{% for placeholder in placeholders if placeholder.advanced == advanced and placeholder is subclassof ParametrizedPlaceholder -%}
{% for param, description in placeholder.iter_param_info(**placeholder_kwargs) %}
{{ br() }}
<span style="font-style: normal;">{ {{- placeholder.name -}}{%- if param is not none -%}:{{- param -}}{%- endif -%} }</span>:
<code class="placeholder">{ {{- placeholder.name -}}{%- if param is not none -%}:{{- param -}}{%- endif -%} }</code> -
{{ description }} {% if placeholder.required %}(required){% endif %}
{% endfor %}
{% endfor %}
Expand Down