OpenSlides/openslides/motions/projector.py
Tobias Hößl 453fedbc3e Initial support for line numbering and change recommendations in Projector
Read projector settings from the config
Preamble, styling fixes
Styling fixes
Show amendments inside of the motion view
Amendment view
Projector and statute paragraphs
Bugfix: Imports
2019-02-15 14:56:40 +01:00

209 lines
7.0 KiB
Python

from typing import Any, Dict
from ..users.projector import get_user_name
from ..utils.projector import (
AllData,
ProjectorElementException,
get_config,
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_state(
all_data: AllData, motion: Dict[str, Any], state_id: int
) -> Dict[str, Any]:
"""
Returns a state element from one motion.
Returns an error if the state_id does not exist for the workflow in the motion.
"""
states = all_data["motions/workflow"][motion["workflow_id"]]["states"]
for state in states:
if state["id"] == state_id:
return state
raise ProjectorElementException(
f"motion {motion['id']} can not be on the state with id {state_id}"
)
def get_amendment_merge_into_motion(all_data, motion, amendment):
"""
HINT: This implementation should be consistent to isAccepted() in ViewMotionAmendedParagraph.ts
"""
if amendment["state_id"] is None:
return 0
state = get_state(
all_data, motion, amendment["state_id"]
)
if state["merge_amendment_into_final"] == -1 or state["merge_amendment_into_final"] == 1:
return state["merge_amendment_into_final"]
if amendment["recommendation_id"] is None:
return 0
recommendation = get_state(
all_data, motion, amendment["recommendation_id"]
)
return recommendation["merge_amendment_into_final"]
def get_amendments_for_motion(motion, all_data):
amendment_data = []
for amendment_id, amendment in all_data["motions/motion"].items():
if amendment["parent_id"] == motion["id"]:
merge_amendment_into_final = get_amendment_merge_into_motion(all_data, motion, amendment)
amendment_data.append({
"id": amendment["id"],
"identifier": amendment["identifier"],
"title": amendment["title"],
"amendment_paragraphs": amendment["amendment_paragraphs"],
"merge_amendment_into_final": merge_amendment_into_final,
})
return amendment_data
def get_amendment_base_motion(amendment, all_data):
try:
motion = all_data["motions/motion"][amendment["parent_id"]]
except KeyError:
motion_id = amendment["parent_id"]
raise ProjectorElementException(f"motion with id {motion_id} does not exist")
return {
"identifier": motion["identifier"],
"title": motion["title"],
"text": motion["text"],
}
def get_amendment_base_statute(amendment, all_data):
try:
statute = all_data["motions/statute-paragraph"][amendment["statute_paragraph_id"]]
except KeyError:
statute_id = amendment["statute_paragraph_id"]
raise ProjectorElementException(f"statute with id {statute_id} does not exist")
return {
"title": statute["title"],
"text": statute["text"],
}
def motion_slide(all_data: AllData, element: Dict[str, Any]) -> Dict[str, Any]:
"""
Motion slide.
The returned dict can contain the following fields:
* identifier
* title
* text
* amendment_paragraphs
* is_child
* show_meta_box
* reason
* modified_final_version
* recommendation
* recommendation_extension
* recommender
* change_recommendations
* submitter
"""
mode = element.get("mode")
motion_id = element.get("id")
if motion_id is None:
raise ProjectorElementException("id is required for motion slide")
try:
motion = all_data["motions/motion"][motion_id]
except KeyError:
raise ProjectorElementException(f"motion with id {motion_id} does not exist")
show_meta_box = not get_config(all_data, "motions_disable_sidebox_on_projector")
line_length = get_config(all_data, "motions_line_length")
line_numbering_mode = get_config(all_data, "motions_default_line_numbering")
change_recommendation_mode = get_config(all_data, "motions_recommendation_text_mode")
motions_preamble = get_config(all_data, "motions_preamble")
if motion["statute_paragraph_id"]:
print("statute")
change_recommendations = []
amendments = []
base_motion = None
base_statute = get_amendment_base_statute(motion, all_data)
elif bool(motion["parent_id"]) and motion["amendment_paragraphs"]:
change_recommendations = []
amendments = []
base_motion = get_amendment_base_motion(motion, all_data)
base_statute = None
else:
change_recommendations = list(filter(lambda reco: reco["internal"] == False, motion["change_recommendations"]))
amendments = get_amendments_for_motion(motion, all_data)
base_motion = None
base_statute = None
return_value = {
"identifier": motion["identifier"],
"title": motion["title"],
"preamble": motions_preamble,
"text": motion["text"],
"amendment_paragraphs": motion["amendment_paragraphs"],
"base_motion": base_motion,
"base_statute": base_statute,
"is_child": bool(motion["parent_id"]),
"show_meta_box": show_meta_box,
"change_recommendations": change_recommendations,
"amendments": amendments,
"change_recommendation_mode": change_recommendation_mode,
"line_length": line_length,
"line_numbering_mode": line_numbering_mode,
}
if not get_config(all_data, "motions_disable_reason_on_projector"):
return_value["reason"] = motion["reason"]
if mode == "final":
return_value["modified_final_version"] = motion["modified_final_version"]
if show_meta_box:
if (
not get_config(all_data, "motions_disable_recommendation_on_projector")
and motion["recommendation_id"]
):
recommendation_state = get_state(
all_data, motion, motion["recommendation_id"]
)
return_value["recommendation"] = recommendation_state[
"recommendation_label"
]
if recommendation_state["show_recommendation_extension_field"]:
return_value["recommendation_extension"] = motion[
"recommendation_extension"
]
return_value["recommender"] = get_config(
all_data, "motions_recommendations_by"
)
return_value["submitter"] = [
get_user_name(all_data, submitter["user_id"])
for submitter in sorted(
motion["submitters"], key=lambda submitter: submitter["weight"]
)
]
return return_value
def motion_block_slide(all_data: AllData, element: Dict[str, Any]) -> Dict[str, Any]:
"""
Motion slide.
"""
return {"error": "TODO"}
def register_projector_slides() -> None:
register_projector_slide("motions/motion", motion_slide)
register_projector_slide("motions/motion-block", motion_block_slide)