OpenSlides/openslides/agenda/projector.py
FinnStutzenstein 965d23be50 more work on projector, countdowns, clos
- splitted clos-slide and clos-overlay.
- Synchronize to server, more little changes
2019-01-29 16:10:21 +01:00

112 lines
3.5 KiB
Python

from collections import defaultdict
from typing import Any, Dict, List, Tuple
from ..utils.projector import (
AllData,
ProjectorElementException,
register_projector_slide,
)
# Important: All functions have to be prune. This means, that thay can only
# access the data, that they get as argument and do not have any
# side effects. They are called from an async context. So they have
# to be fast!
def get_tree(
all_data: AllData, parent_id: int = 0
) -> List[Tuple[int, List[Tuple[int, List[Any]]]]]:
"""
Build the item tree from all_data.
Only build the tree from elements unterneath parent_id.
Returns a list of two element tuples where the first element is the item title
and the second a List with children as two element tuples.
"""
# Build a dict from an item_id to all its children
children: Dict[int, List[int]] = defaultdict(list)
for item in sorted(
all_data["agenda/item"].values(), key=lambda item: item["weight"]
):
if item["type"] == 1: # only normal items
children[item["parent_id"] or 0].append(item["id"])
def get_children(
item_ids: List[int]
) -> List[Tuple[int, List[Tuple[int, List[Any]]]]]:
return [
(all_data["agenda/item"][item_id]["title"], get_children(children[item_id]))
for item_id in item_ids
]
return get_children(children[parent_id])
def items_slide(all_data: AllData, element: Dict[str, Any]) -> Dict[str, Any]:
"""
Item list slide.
Returns all root items or all children of an item.
"""
root_item_id = element.get("id") or None
show_tree = element.get("tree") or False
if show_tree:
agenda_items = get_tree(all_data, root_item_id or 0)
else:
agenda_items = []
for item in sorted(
all_data["agenda/item"].values(), key=lambda item: item["weight"]
):
if item["parent_id"] == root_item_id and item["type"] == 1:
agenda_items.append(item["title"])
return {"items": agenda_items}
def list_of_speakers_slide(
all_data: AllData, element: Dict[str, Any]
) -> Dict[str, Any]:
"""
List of speakers slide.
Returns all usernames, that are on the list of speaker of a slide.
"""
item_id = element.get("id") or 0 # item_id 0 means current_list_of_speakers
# TODO: handle item_id == 0
try:
item = all_data["agenda/item"][item_id]
except KeyError:
raise ProjectorElementException(f"Item {item_id} does not exist")
user_ids = []
for speaker in item["speakers"]:
user_ids.append(speaker["user"])
return {"user_ids": user_ids}
def current_list_of_speakers_slide(
all_data: AllData, element: Dict[str, Any]
) -> Dict[str, Any]:
"""
TODO
Note: This data is for all projectors showing this slide, so we cannot give projector-
specific data. The work-around is to make a dict with projector-ids as keys and the
data-per-projector as values. This is not a security concern, because if a person can
see one projector, he is able to see all others, too. Maybe a bit more data..
"""
return {"error": "TODO"}
def register_projector_slides() -> None:
register_projector_slide("agenda/item-list", items_slide)
register_projector_slide("agenda/list-of-speakers", list_of_speakers_slide)
register_projector_slide("agenda/current-list-of-speakers", current_list_of_speakers_slide)
register_projector_element("agenda/current-list-of-speakers-overlay", current_list_of_speakers_slide)