diff --git a/api/config/live_config.json b/api/config/live_config.json index 8b335dcc36b8b2e83da3c5a631485b431345e521..e1b0508c54a50985cdace332c16f38a37b73d1fa 100644 --- a/api/config/live_config.json +++ b/api/config/live_config.json @@ -3,10 +3,11 @@ "disabled": false, "static_announcements": [ { - "is_enabled": false, + "is_enabled": true, + "visible": true, "type": "info", - "visibility": "all_pages", - "text": "Example static announcement. Other types: 'warning' and 'important'. Other visibilities: 'only_main_page' and 'all_pages_and_embed'" + "page_visibility": "all_pages", + "text": "Example static announcement. 'visible' refers to publicly visible or only for mods. Other types: 'warning' and 'important'. Other visibilities: 'only_main_page' and 'all_pages_and_embed'" } ] } \ No newline at end of file diff --git a/api/src/api/live_config.py b/api/src/api/live_config.py index b7fab120e23faed6b2acdf630fdc504c7515b6a4..19a7a7ba700d772548f85b73b474eba43379a161 100644 --- a/api/src/api/live_config.py +++ b/api/src/api/live_config.py @@ -2,6 +2,8 @@ import os import traceback from pathlib import Path +from videoag_common.objects import AnnouncementType, AnnouncementPageVisibility + import api from api.miscellaneous import * @@ -9,63 +11,58 @@ _LIVE_CONFIG_PATH_STRING = os.environ.get("VIDEOAG_API_LIVE_CONFIG", None) _LIVE_CONFIG_PATH = None if _LIVE_CONFIG_PATH_STRING is None else Path(_LIVE_CONFIG_PATH_STRING).resolve() +class LiveConfigAnnouncement(JsonDataClass): + is_enabled: bool + visible: bool + type: AnnouncementType + page_visibility: AnnouncementPageVisibility + text: str = json_field(max_length=8192) + + +class LiveConfigData(JsonDataClass): + readonly: bool + disabled: bool + static_announcements: list[LiveConfigAnnouncement] + + class LiveConfig: def __init__(self): super().__init__() - self._disabled: bool = False - self._readonly: bool = False - self._static_announcements: list[dict] = [] + self.reset() def reset(self): - self._disabled = False - self._readonly = False - self._static_announcements = [] + self._data = LiveConfigData( + readonly=False, + disabled=False, + static_announcements=[], + ) def update(self, json_config: CJsonObject): """ Raises an exception if the file has wrong format/values. In this case, nothing is updated """ - disable = json_config.get_bool("disabled", False) - readonly = json_config.get_bool("readonly", False) or disable - static_announcements = [] - unsafe_announcements = json_config.get_array("static_announcements") - if unsafe_announcements is not None: - for unsafe_announcement in unsafe_announcements: - unsafe_announcement = unsafe_announcement.as_object() - - type = unsafe_announcement.get_string("type", 100) - if type not in ["info", "warning", "important"]: - unsafe_announcement.get("type").raise_error("Unknown type") - visibility = unsafe_announcement.get_string("visibility", 100) - if visibility not in ["only_main_page", "all_pages", "all_pages_and_embed"]: - unsafe_announcement.get("visibility").raise_error("Unknown visibility") - text = unsafe_announcement.get_string("text", 8192) - - if not unsafe_announcement.get_bool("is_enabled", True): - continue - static_announcements.append({ - "type": type, - "visibility": visibility, - "text": text - }) - - # Assign to global vars only if whole file parsed successfully - self._readonly = readonly - self._disabled = disable - self._static_announcements = static_announcements + self._data = LiveConfigData.from_json(json_config) def is_disabled(self) -> bool: - return self._disabled + return self._data.disabled def is_readonly(self) -> bool: - return self._readonly + return self._data.readonly - def get_static_announcements(self) -> list[dict]: + def get_static_announcements(self, is_mod: bool) -> list[dict]: """ - Dicts contain (as in the api specification): type, visibility, text + Dicts contain (as in the api specification): type, page_visibility, text """ - return self._static_announcements + return [ + { + "type": announcement.type.to_json(), + "page_visibility": announcement.page_visibility.to_json(), + "text": announcement.text, + } + for announcement in self._data.static_announcements + if announcement.is_enabled and (is_mod or announcement.visible) + ] # Do not modify directly! Variable is imported by others diff --git a/api/src/api/routes/site.py b/api/src/api/routes/site.py index 928da6c155d260a3bc22875de6677b3d0d56eccc..0e3571df20849ca4f5249401224cff7a9acf5efe 100644 --- a/api/src/api/routes/site.py +++ b/api/src/api/routes/site.py @@ -25,7 +25,7 @@ def api_route_status(): is_mod = is_moderator() status = "available" announcements = [] - announcements.extend(api.live_config.get_static_announcements()) + announcements.extend(api.live_config.get_static_announcements(is_mod)) if api.live_config.is_disabled(): status = "unavailable" diff --git a/common_py/src/videoag_common/objects/site.py b/common_py/src/videoag_common/objects/site.py index 39d65386f87f149ac050d7be017f17bc0ead3253..09bde4a031b4934dd61b2fab3a5797a56a507f77 100644 --- a/common_py/src/videoag_common/objects/site.py +++ b/common_py/src/videoag_common/objects/site.py @@ -8,13 +8,13 @@ from videoag_common.api_object import * from .course import Course, Lecture -class AnnouncementType(Enum): +class AnnouncementType(JsonSerializableEnum): INFO = "info" WARNING = "warning" IMPORTANT = "important" -class AnnouncementPageVisibility(Enum): +class AnnouncementPageVisibility(JsonSerializableEnum): ONLY_MAIN_PAGE = "only_main_page" ALL_PAGES = "all_pages" ALL_PAGES_AND_EMBED = "all_pages_and_embed"