Skip to content
Snippets Groups Projects
Commit 97eb334e authored by Roang's avatar Roang
Browse files

Merge branch 'feature/filter_recorded' into 'develop'

plainui: add filter option to filter recorded/not_recorded events

See merge request !944
parents 90f65bfc 020eec97
Branches
Tags 4.8.2
No related merge requests found
......@@ -92,7 +92,7 @@ def str2bool(s, allow_null: bool = False):
s = s.strip().lower()
if allow_null and s in ['-', 'none', 'null', 'unknown', '?']:
if allow_null and s in ['', '-', 'none', 'null', 'unknown', '?']:
return None
if s in ['true', 'on', '1', 't', 'y', 'yes', 'j', 'ja', '', '']:
......
......@@ -58,9 +58,10 @@
{% if assembly %}<input type="hidden" name="assembly" value="{{assembly.slug}}">{% endif %}
{% if track %}<input type="hidden" name="track" value="{{track.slug}}">{% endif %}
{% if my_fahrplan %}<input type="hidden" name="my" value="y">{% endif %}
{% if is_recorded is not none %}<input type="hidden" name="rec" value="{{'y' if is_recorded else 'n'}}">{% endif %}
<div class="d-flex gap-3 flex-column flex-md-row align-items-start hub-fahrplan__title mb-2">
<div class="me-md-4 fw-bold">{{ _("fahrplan.title") }}</div>
<div>
<button
type="submit"
......@@ -97,6 +98,10 @@
{{ filter_button('d' ~ (n if n != day else ''), n == day, _("Day %(n)s", n=n + 1)) }}
{%- endfor %}
<div class="hub-tag-divider"></div>
{{ filter_button("ry" if is_recorded is not true else "r", is_recorded is true, _("recorded only")) }}
{{ filter_button("rn" if is_recorded is not false else "r", is_recorded is false, _("not recorded only")) }}
</div>
<div class="hub-tags">
......
......@@ -14,6 +14,7 @@ from core.models import (
ConferenceTrack,
Event,
)
from core.utils import str2bool
from plainui.views.utils import ConferenceRequiredMixin, event_filter, organize_events_for_calendar, session_get_favorite_events
......@@ -54,6 +55,7 @@ class FahrplanView(ConferenceRequiredMixin, TemplateView):
show_assembly_filters = self.request.GET.get('show_assembly_filters') == 'y'
show_track_filters = self.request.GET.get('show_track_filters') == 'y'
my_fahrplan = self.request.GET.get('my') == 'y'
is_recorded = str2bool(self.request.GET.get('rec', ''), allow_null=True)
to_set = self.request.GET.get('set', None)
if to_set:
......@@ -79,6 +81,14 @@ class FahrplanView(ConferenceRequiredMixin, TemplateView):
mode = to_set[1:]
elif to_set[0] == 't':
track = to_set[1:]
elif to_set[0] == 'r':
match to_set[1:]:
case '1' | 'y':
is_recorded = True
case '0' | 'n':
is_recorded = False
case _:
is_recorded = None
context['show_day_filters'] = show_day_filters
context['show_assembly_filters'] = show_assembly_filters
......@@ -130,6 +140,8 @@ class FahrplanView(ConferenceRequiredMixin, TemplateView):
track = tracks.get(slug=track) if track else None
context['track'] = track
context['is_recorded'] = is_recorded
events = event_filter(
self.request.user,
self.conf,
......@@ -139,6 +151,7 @@ class FahrplanView(ConferenceRequiredMixin, TemplateView):
track=track,
calendar_mode=mode == 'calendar',
public_fahrplan=public_fahrplan,
is_recorded=is_recorded,
**self.filter_opts,
)
......
......@@ -185,6 +185,7 @@ def event_filter(
upcoming=False,
calendar_mode=True,
public_fahrplan=None,
is_recorded: Optional[bool] = None,
):
min_date, max_date = conf.start, conf.end
if min_date is None or max_date is None:
......@@ -215,9 +216,47 @@ def event_filter(
if calendar_mode:
events = events.filter(room__isnull=False)
res = events.filter(schedule_duration__isnull=False, **filters).order_by('schedule_start', 'schedule_end')
# filter on the requested recording state
if is_recorded is True:
# don't include all events explicitly labeled "don't record"
res = res.exclude(recording=Event.Recording.NO)
res = res.filter(
# ... all events of unknown state in rooms with "record by default"
Q(recording=Event.Recording.UNKNOWN, room__isnull=False, room__recording_state__in=[Room.RecordingState.RECORD_BY_DEFAULT])
# ... all events with state "yes, record" which either ...
| (
Q(recording=Event.Recording.YES)
& (
# don't have a room
Q(room__isnull=True)
# have a room which does allow recording
| Q(room__isnull=False, room__recording_state__in=[Room.RecordingState.NOT_RECORDED_BY_DEFAULT, Room.RecordingState.RECORD_BY_DEFAULT])
)
)
)
elif is_recorded is False:
# kick all events which don't have a room and don't explicitly specify not to be recorded
res = res.exclude(room__isnull=True, recording__in=[Event.Recording.UNKNOWN, Event.Recording.YES])
# kick all events which ...
res = res.exclude(
# shall explicitly be recorded and ...
recording=Event.Recording.YES,
# have a room which permits recording (if an event may not be recorded because of this we can't filter it even though it requests to be recorded)
room__isnull=False,
room__recording_state__in=[Room.RecordingState.RECORD_BY_DEFAULT, Room.RecordingState.NOT_RECORDED_BY_DEFAULT],
)
# kick all events which default to their room's setting which would allow recording
res = res.exclude(recording=Event.Recording.UNKNOWN, room__isnull=False, room__recording_state__in=[Room.RecordingState.RECORD_BY_DEFAULT])
res = res.annotate(track_name=F('track__name'))
speakers = EventParticipant.objects.filter(is_public=True, role=EventParticipant.Role.SPEAKER).order_by('participant__username')
speakers = speakers.annotate(speaker_name=F('participant__username'))
return res.prefetch_related(
Prefetch('participants', queryset=speakers, to_attr='speakers'),
Prefetch('tags', to_attr='prefetched_tags', queryset=TagItem.objects.select_related('tag').filter(tag__is_public=True)),
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment