From db97a4b70e0984ac1595078a8bbf75423b47e026 Mon Sep 17 00:00:00 2001 From: Collin Heist Date: Wed, 4 Sep 2024 09:39:44 -0600 Subject: [PATCH] [22] Implement global Fonts setting in Card creation/API --- app/internal/cards.py | 25 ++++++++++++++++++++++--- app/models/preferences.py | 3 ++- app/routers/fonts.py | 11 +++++++++++ app/routers/settings.py | 8 ++++++-- app/schemas/preferences.py | 6 ++++-- modules/ref/version_webui | 2 +- 6 files changed, 46 insertions(+), 9 deletions(-) diff --git a/app/internal/cards.py b/app/internal/cards.py index 9058c7dce..7e65df696 100755 --- a/app/internal/cards.py +++ b/app/internal/cards.py @@ -8,8 +8,9 @@ from sqlalchemy import and_, or_ from sqlalchemy.exc import OperationalError, PendingRollbackError from sqlalchemy.orm import Query, Session +from sqlalchemy.orm.session import object_session -from app.database.query import get_interface +from app.database.query import get_font, get_interface from app.dependencies import get_database, get_preferences from app.internal.availability import get_remote_card_hash from app.internal.episodes import refresh_episode_data @@ -434,11 +435,13 @@ def resolve_card_settings( MissingSourceImage: The required Source Image is missing. """ - # Get effective Template for this Series and Episode + # Get effective Template(s) for this Series and Episode + preferences = get_preferences() series = episode.series global_template, series_template, episode_template =get_effective_templates( series, episode, library ) + global_template_dict, series_template_dict, episode_template_dict = {},{},{} if global_template is not None: global_template_dict = global_template.card_properties @@ -447,6 +450,16 @@ def resolve_card_settings( if episode_template is not None: episode_template_dict = episode_template.card_properties + # Determine the card type + card_type: str = TieredSettings.resolve_singular_setting( + preferences.default_card_type, + global_template_dict.get('card_type'), + series_template_dict.get('card_type'), + series.card_type, + episode_template_dict.get('card_type'), + episode.card_type, + ) + # Get effective Font for this Series and Episode global_font_dict, series_font_dict, episode_font_dict = {}, {}, {} if episode.font: @@ -459,9 +472,13 @@ def resolve_card_settings( series_font_dict = series_template.font.card_properties elif global_template and global_template.font: global_font_dict = global_template.font.card_properties + elif preferences.default_fonts.get(card_type) is not None: + global_font_dict = get_font( + object_session(episode), + preferences.default_fonts[card_type], + ).card_properties # Resolve all settings from global -> Episode - preferences = get_preferences() card_settings = TieredSettings.new_settings( {'hide_season_text': False, 'hide_episode_text': False}, DefaultFont, @@ -704,6 +721,8 @@ def create_episode_card( Raises: HTTPException: If the card settings are invalid and `raise_exc` is True. + InvalidCardSettings: If the card settings are invalid and + `raise_exc` is True. """ # Resolve Card settings diff --git a/app/models/preferences.py b/app/models/preferences.py index 39329a89d..9b3fbf3ec 100755 --- a/app/models/preferences.py +++ b/app/models/preferences.py @@ -79,7 +79,7 @@ class Preferences: 'current_version', 'available_version', 'blacklisted_blueprints', 'advanced_scheduling', 'require_auth', 'task_crontabs', 'simplified_data_table', 'home_page_size', 'episode_data_page_size', - 'stylize_unmonitored_posters', 'sources_as_table', + 'stylize_unmonitored_posters', 'sources_as_table', 'default_fonts', 'card_type_directory', 'local_card_types', 'imported_blueprints', 'colorblind_mode', 'library_unique_cards', 'invalid_connections', 'home_page_table_view', 'reduced_animations', 'currently_running_sync', @@ -211,6 +211,7 @@ def __initialize_defaults(self) -> None: self.default_watched_style = 'unique' self.default_unwatched_style = 'unique' self.default_templates: list[int] = [] + self.default_fonts: dict[str, int] = {} self.global_extras: dict[str, dict[str, str]] = {} self.currently_running_sync: Optional[int] = None diff --git a/app/routers/fonts.py b/app/routers/fonts.py index fcf7283d1..91a716736 100755 --- a/app/routers/fonts.py +++ b/app/routers/fonts.py @@ -205,6 +205,7 @@ def delete_font( request: Request, font_id: int, db: Session = Depends(get_database), + preferences: Preferences = Depends(get_preferences), ) -> None: """ Delete the Font with the given ID. This also deletes the font's @@ -219,6 +220,15 @@ def delete_font( # Get specified Font, raise 404 if DNE font = get_font(db, font_id, raise_exc=True) + # Delete from global setting if indicated + if font_id in preferences.default_fonts.values(): + preferences.default_fonts = { + card_type: id_ + for card_type, id_ in preferences.default_fonts.items() + if id_ != font_id + } + log.debug(f'{preferences.default_fonts = }') + # If Font file is specified (and exists), delete if (font_file := font.file) is not None: try: @@ -233,6 +243,7 @@ def delete_font( db.delete(font) db.commit() + preferences.commit() @font_router.get('/{font_id}/analysis') diff --git a/app/routers/settings.py b/app/routers/settings.py index 9d27d08de..a6bf50500 100755 --- a/app/routers/settings.py +++ b/app/routers/settings.py @@ -3,7 +3,7 @@ from fastapi import APIRouter, Body, Depends, Request from sqlalchemy.orm import Session -from app.database.query import get_template +from app.database.query import get_font, get_template from app.dependencies import get_database, get_preferences from app.internal.auth import get_current_user from app.internal.backup import list_available_backups @@ -60,7 +60,11 @@ def update_global_settings( - update_preferences: UpdatePreferences containing fields to update. """ - # Verify all specified Templates exist + # Verify any specified Fonts/Templates exist + if (hasattr(update_preferences, 'default_fonts') + and update_preferences.default_fonts != UNSPECIFIED): + for font_id in update_preferences.default_fonts.values(): + get_font(db, font_id, raise_exc=True) if (hasattr(update_preferences, 'default_templates') and update_preferences.default_templates != UNSPECIFIED): for template_id in update_preferences.default_templates: diff --git a/app/schemas/preferences.py b/app/schemas/preferences.py index 3cf846465..5a347297d 100755 --- a/app/schemas/preferences.py +++ b/app/schemas/preferences.py @@ -10,7 +10,7 @@ PositiveInt, conint, constr, - validator + validator, ) from app.schemas.base import ( @@ -18,7 +18,7 @@ ImageSource, InterfaceType, UpdateBase, - UNSPECIFIED + UNSPECIFIED, ) from modules.FormatString import FormatString @@ -99,6 +99,7 @@ class UpdatePreferences(UpdateBase): default_watched_style: Style = UNSPECIFIED default_unwatched_style: Style = UNSPECIFIED default_templates: list[int] = UNSPECIFIED + default_fonts: dict[str, int] = UNSPECIFIED global_extras: dict[str, dict[str, str]] = UNSPECIFIED home_page_size: PositiveInt = UNSPECIFIED episode_data_page_size: PositiveInt = UNSPECIFIED @@ -180,6 +181,7 @@ class Preferences(Base): default_watched_style: Style default_unwatched_style: Style default_templates: list[int] + default_fonts: dict[str, int] global_extras: dict[str, dict[str, str]] home_page_size: PositiveInt episode_data_page_size: PositiveInt diff --git a/modules/ref/version_webui b/modules/ref/version_webui index adfd8b2a4..b3d5affe1 100755 --- a/modules/ref/version_webui +++ b/modules/ref/version_webui @@ -1 +1 @@ -v2.0-alpha.12.0-webui21 \ No newline at end of file +v2.0-alpha.12.0-webui22 \ No newline at end of file