Source code for timApp.user.preferences

import re
import sre_constants
from functools import cached_property
from re import Pattern
from typing import Optional

import attr

from timApp.document.docentry import DocEntry
from timApp.item.item import Item

BookmarkEntry = dict[str, str]
BookmarkEntryList = list[BookmarkEntry]
BookmarkFolder = dict[str, BookmarkEntryList]
BookmarkCollection = list[BookmarkFolder]


[docs]@attr.s(auto_attribs=True) class Preferences: custom_css: str = "" use_document_word_list: bool = False disable_menu_hover: bool = False remember_last_sidebar_menu_tab: bool = False remember_last_sidebar_menu_state: bool = False word_list: str = "" email_exclude: str = "" language: str | None = None style_doc_ids: list[int] = attr.Factory(list) last_answer_fetch: dict[str, str] = attr.Factory(dict) auto_mark_all_read: bool = False bookmarks: BookmarkCollection | None = None max_uncollapsed_toc_items: int | None = None
[docs] @staticmethod def from_json(j: dict) -> "Preferences": j.pop("style_path", None) return Preferences(**j)
[docs] def theme_docs(self) -> list[DocEntry]: if not self.style_doc_ids: return [] ordering = {d: i for i, d in enumerate(self.style_doc_ids)} return sorted( DocEntry.query.filter(DocEntry.id.in_(self.style_doc_ids)).all(), key=lambda d: ordering[d.id], )
@cached_property def style_path(self) -> str: from timApp.user.settings.styles import generate_style style_path, style_hash = generate_style(self.theme_docs()) return f"{style_path}?{style_hash}" @cached_property def excluded_email_paths(self) -> list[Pattern[str]]: if not isinstance(self.email_exclude, str): return [] try: return [re.compile(s) for s in self.email_exclude.strip().splitlines()] except sre_constants.error: return []
[docs] def is_item_excluded_from_emails(self, d: Item) -> bool: return any(pat.search(d.path) for pat in self.excluded_email_paths)
[docs] def to_json(self, with_style: bool = False) -> dict: result = self.__dict__ if with_style: result |= {"style_path": self.style_path} return result