~homeworkprod/byceps

ref: 533662eefb314d54b168e5a46bc07c88b5f88be4 byceps/byceps/blueprints/admin/orga_presence/views.py -rw-r--r-- 2.4 KiB
533662ee — Jochen Kupperschmidt Use Flask v2.0's `delete`/`get`/`patch`/`post` route shortcuts 2 months ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
"""
byceps.blueprints.admin.orga_presence.views
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

:Copyright: 2006-2021 Jochen Kupperschmidt
:License: Revised BSD (see `LICENSE` file for details)
"""

from __future__ import annotations
from collections import defaultdict
from datetime import datetime
from typing import Iterable

from flask import abort

from ....services.orga_presence import service as orga_presence_service
from ....services.orga_presence.transfer.models import (
    PartyTimeSlot,
    PresenceTimeSlot,
    TimeSlot,
)
from ....services.party import service as party_service
from ....services.user.transfer.models import User
from ....util.authorization import register_permission_enum
from ....util.framework.blueprint import create_blueprint
from ....util.framework.templating import templated
from ....util.views import permission_required

from .authorization import OrgaPresencePermission


blueprint = create_blueprint('orga_presence', __name__)


register_permission_enum(OrgaPresencePermission)


@blueprint.get('/<party_id>')
@permission_required(OrgaPresencePermission.view)
@templated
def view(party_id):
    """List orga presence and task time slots for that party."""
    party = party_service.find_party(party_id)

    if party is None:
        abort(404)

    party_time_slot = PartyTimeSlot.from_party(party)
    presences = orga_presence_service.get_presences(party.id)
    tasks = orga_presence_service.get_tasks(party.id)

    presences_by_orga = _group_presences_by_orga(presences)

    time_slots = [party_time_slot] + presences + tasks
    hour_ranges = list(orga_presence_service.get_hour_ranges(time_slots))

    days_and_hour_totals = list(
        orga_presence_service.get_days_and_hour_totals(hour_ranges)
    )

    return {
        'party': party,
        'days_and_hour_totals': days_and_hour_totals,
        'hour_ranges': hour_ranges,
        'party_time_slot': party_time_slot,
        'presences_by_orga': presences_by_orga,
        'tasks': tasks,
        'is_instant_contained_in_time_slots': is_instant_contained_in_time_slots,
    }


def _group_presences_by_orga(
    presences: Iterable[PresenceTimeSlot],
) -> dict[User, set[PresenceTimeSlot]]:
    d = defaultdict(set)

    for presence in presences:
        d[presence.orga].add(presence)

    return d


def is_instant_contained_in_time_slots(
    instant: datetime, time_slots: Iterable[TimeSlot]
) -> bool:
    return any(time_slot.range.contains(instant) for time_slot in time_slots)