From 5cdb4c29ea9e736ea5a52483c2e62009c4c7d27e Mon Sep 17 00:00:00 2001 From: Wojtek Kosior Date: Fri, 2 Sep 2022 13:51:25 +0200 Subject: [proxy] allow packages to be frozen and unfrozen in the web UI This commit also makes some minor changes and fixes in other parts of the web UI. --- src/hydrilla/locales/en_US/LC_MESSAGES/messages.po | 112 +++++++--- src/hydrilla/proxy/state.py | 22 +- src/hydrilla/proxy/state_impl/items.py | 230 +++++++++++---------- src/hydrilla/proxy/web_ui/items.py | 62 +++--- src/hydrilla/proxy/web_ui/root.py | 1 + .../web_ui/templates/items/item_view.html.jinja | 60 +++--- .../templates/items/item_viewversion.html.jinja | 18 +- .../templates/items/library_viewversion.html.jinja | 15 +- .../templates/items/package_viewversion.html.jinja | 119 +++++++++-- .../web_ui/templates/repos/show_single.html.jinja | 2 +- 10 files changed, 394 insertions(+), 247 deletions(-) diff --git a/src/hydrilla/locales/en_US/LC_MESSAGES/messages.po b/src/hydrilla/locales/en_US/LC_MESSAGES/messages.po index bb52222..e637de1 100644 --- a/src/hydrilla/locales/en_US/LC_MESSAGES/messages.po +++ b/src/hydrilla/locales/en_US/LC_MESSAGES/messages.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: hydrilla 2.0\n" "Report-Msgid-Bugs-To: koszko@koszko.org\n" -"POT-Creation-Date: 2022-09-01 21:22+0200\n" +"POT-Creation-Date: 2022-09-02 13:49+0200\n" "PO-Revision-Date: 2022-02-12 00:00+0000\n" "Last-Translator: Wojtek Kosior \n" "Language: en_US\n" @@ -311,29 +311,33 @@ msgstr "Available versions" msgid "web_ui.items.single_version.library.title" msgstr "Library version view" -#: src/hydrilla/proxy/web_ui/templates/items/library_viewversion.html.jinja:29 +#: src/hydrilla/proxy/web_ui/templates/items/library_viewversion.html.jinja:30 +msgid "web_ui.items.single_version.library_local.heading.name_{}" +msgstr "Local library '{}'" + +#: src/hydrilla/proxy/web_ui/templates/items/library_viewversion.html.jinja:35 msgid "web_ui.items.single_version.library.heading.name_{}" msgstr "Library '{}'" -#: src/hydrilla/proxy/web_ui/templates/items/library_viewversion.html.jinja:35 +#: src/hydrilla/proxy/web_ui/templates/items/library_viewversion.html.jinja:42 msgid "web_ui.items.single_version.library.item_required" msgstr "This library is required by an enabled mapping. It cannot be uninstalled." -#: src/hydrilla/proxy/web_ui/templates/items/library_viewversion.html.jinja:39 +#: src/hydrilla/proxy/web_ui/templates/items/library_viewversion.html.jinja:46 msgid "web_ui.items.single_version.library.item_auto_activated" msgstr "This library is used by a package which can be activated automatically." -#: src/hydrilla/proxy/web_ui/templates/items/library_viewversion.html.jinja:43 +#: src/hydrilla/proxy/web_ui/templates/items/library_viewversion.html.jinja:50 msgid "web_ui.items.single_version.library.item_not_activated" -msgstr "This library is not used by any active mapping." +msgstr "This library is not used by any active package." -#: src/hydrilla/proxy/web_ui/templates/items/library_viewversion.html.jinja:47 +#: src/hydrilla/proxy/web_ui/templates/items/library_viewversion.html.jinja:54 msgid "web_ui.items.single_version.library.install_failed" msgstr "Couldn't install this library." -#: src/hydrilla/proxy/web_ui/templates/items/library_viewversion.html.jinja:51 +#: src/hydrilla/proxy/web_ui/templates/items/library_viewversion.html.jinja:58 msgid "web_ui.items.single_version.library.version_list_heading" -msgstr "Other available versions of this library." +msgstr "Other available versions of this library" #: src/hydrilla/proxy/web_ui/templates/items/load_from_disk.html.jinja:22 msgid "web_ui.load_from_disk.title" @@ -367,49 +371,103 @@ msgstr "Available versions" msgid "web_ui.items.single_version.package.title" msgstr "Package version view" -#: src/hydrilla/proxy/web_ui/templates/items/package_viewversion.html.jinja:29 +#: src/hydrilla/proxy/web_ui/templates/items/package_viewversion.html.jinja:30 +msgid "web_ui.items.single_version.package_local.heading.name_{}" +msgstr "Local package '{}'" + +#: src/hydrilla/proxy/web_ui/templates/items/package_viewversion.html.jinja:35 msgid "web_ui.items.single_version.package.heading.name_{}" msgstr "Package '{}'" -#: src/hydrilla/proxy/web_ui/templates/items/package_viewversion.html.jinja:35 +#: src/hydrilla/proxy/web_ui/templates/items/package_viewversion.html.jinja:42 msgid "web_ui.items.single_version.package.item_required" msgstr "This package is required. It cannot be uninstalled." -#: src/hydrilla/proxy/web_ui/templates/items/package_viewversion.html.jinja:39 +#: src/hydrilla/proxy/web_ui/templates/items/package_viewversion.html.jinja:46 msgid "web_ui.items.single_version.package.item_auto_activated" msgstr "This package can be activated automatically." -#: src/hydrilla/proxy/web_ui/templates/items/package_viewversion.html.jinja:43 +#: src/hydrilla/proxy/web_ui/templates/items/package_viewversion.html.jinja:50 msgid "web_ui.items.single_version.package.item_not_activated" msgstr "This package is not active." -#: src/hydrilla/proxy/web_ui/templates/items/package_viewversion.html.jinja:47 +#: src/hydrilla/proxy/web_ui/templates/items/package_viewversion.html.jinja:54 msgid "web_ui.items.single_version.package.install_failed" msgstr "Couldn't install this package." -#: src/hydrilla/proxy/web_ui/templates/items/package_viewversion.html.jinja:51 +#: src/hydrilla/proxy/web_ui/templates/items/package_viewversion.html.jinja:58 msgid "web_ui.items.single_version.package.version_list_heading" -msgstr "Available versions" +msgstr "Other available versions of this package" -#: src/hydrilla/proxy/web_ui/templates/items/package_viewversion.html.jinja:67 +#: src/hydrilla/proxy/web_ui/templates/items/package_viewversion.html.jinja:74 msgid "web_ui.items.single_version.unenable_button" msgstr "Forget" -#: src/hydrilla/proxy/web_ui/templates/items/package_viewversion.html.jinja:68 +#: src/hydrilla/proxy/web_ui/templates/items/package_viewversion.html.jinja:75 msgid "web_ui.items.single_version.disable_button" msgstr "Disable" -#: src/hydrilla/proxy/web_ui/templates/items/package_viewversion.html.jinja:75 -msgid "web_ui.items.single_version.freeze_to_this_button" -msgstr "Pin to this version" - -#: src/hydrilla/proxy/web_ui/templates/items/package_viewversion.html.jinja:78 +#: src/hydrilla/proxy/web_ui/templates/items/package_viewversion.html.jinja:76 msgid "web_ui.items.single_version.enable_button" msgstr "Enable" -#: src/hydrilla/proxy/web_ui/templates/items/package_viewversion.html.jinja:89 -msgid "web_ui.items.single_version.other_version_enabled" -msgstr "Other available versions of this package." +#: src/hydrilla/proxy/web_ui/templates/items/package_viewversion.html.jinja:80 +msgid "web_ui.items.single_version.item_not_marked" +msgstr "This package isn't enabled." + +#: src/hydrilla/proxy/web_ui/templates/items/package_viewversion.html.jinja:83 +msgid "web_ui.items.single_version.item_disabled" +msgstr "All versions of this package have been explicitly disabled by the user." + +#: src/hydrilla/proxy/web_ui/templates/items/package_viewversion.html.jinja:87 +msgid "web_ui.items.single_version.item_enabled" +msgstr "This package has been enabled by the user." + +#: src/hydrilla/proxy/web_ui/templates/items/package_viewversion.html.jinja:109 +msgid "web_ui.items.single_version.unpin_button" +msgstr "Unpin" + +#: src/hydrilla/proxy/web_ui/templates/items/package_viewversion.html.jinja:113 +msgid "web_ui.items.single_version.not_pinned" +msgstr "This package is not pinned to any version." + +#: src/hydrilla/proxy/web_ui/templates/items/package_viewversion.html.jinja:118 +msgid "web_ui.items.single_version.pinned_repo_local" +msgstr "This package is pinned to only use locally installed versions." + +#: src/hydrilla/proxy/web_ui/templates/items/package_viewversion.html.jinja:122 +msgid "web_ui.items.single_version.pinned_repo_{}" +msgstr "This package is pinned to only use versions from repository '{}'." + +#: src/hydrilla/proxy/web_ui/templates/items/package_viewversion.html.jinja:134 +msgid "web_ui.items.single_version.pin_local_repo_button" +msgstr "Pin to local packages" + +#: src/hydrilla/proxy/web_ui/templates/items/package_viewversion.html.jinja:138 +#: src/hydrilla/proxy/web_ui/templates/items/package_viewversion.html.jinja:149 +msgid "web_ui.items.single_version.pin_repo_button" +msgstr "Pin to repository" + +#: src/hydrilla/proxy/web_ui/templates/items/package_viewversion.html.jinja:145 +msgid "web_ui.items.single_version.repin_repo_button" +msgstr "Pin to this repository" + +#: src/hydrilla/proxy/web_ui/templates/items/package_viewversion.html.jinja:154 +#: src/hydrilla/proxy/web_ui/templates/items/package_viewversion.html.jinja:164 +msgid "web_ui.items.single_version.pin_ver_button" +msgstr "Pin to this version" + +#: src/hydrilla/proxy/web_ui/templates/items/package_viewversion.html.jinja:156 +msgid "web_ui.items.single_version.pinned_ver" +msgstr "This package is pinned to this version." + +#: src/hydrilla/proxy/web_ui/templates/items/package_viewversion.html.jinja:159 +msgid "web_ui.items.single_version.repin_ver_button" +msgstr "Pin to this version" + +#: src/hydrilla/proxy/web_ui/templates/items/package_viewversion.html.jinja:161 +msgid "web_ui.items.single_version.pinned_other_ver" +msgstr "This package is pinned to a different version." #: src/hydrilla/proxy/web_ui/templates/items/packages.html.jinja:22 msgid "web_ui.packages.title" @@ -478,7 +536,7 @@ msgstr "packages: {}" #: src/hydrilla/proxy/web_ui/templates/repos/index.html.jinja:59 #: src/hydrilla/proxy/web_ui/templates/repos/show_single.html.jinja:46 msgid "web_ui.repos.local_packages_semirepo" -msgstr "Local packages" +msgstr "Local items" #: src/hydrilla/proxy/web_ui/templates/repos/show_single.html.jinja:22 msgid "web_ui.repos.single.title" diff --git a/src/hydrilla/proxy/state.py b/src/hydrilla/proxy/state.py index f882b2d..03b6291 100644 --- a/src/hydrilla/proxy/state.py +++ b/src/hydrilla/proxy/state.py @@ -226,6 +226,10 @@ class MappingDisplayInfo(item_infos.CorrespondsToMappingDCMixin): frozen: t.Optional[FrozenStatus] active_version: t.Optional['MappingVersionDisplayInfo'] +@dc.dataclass(frozen=True) +class RichMappingDisplayInfo(MappingDisplayInfo): + all_versions: t.Sequence['MappingVersionDisplayInfo'] + @dc.dataclass(frozen=True) class MappingVersionDisplayInfo(item_infos.CorrespondsToMappingDCMixin): ref: 'MappingVersionRef' @@ -234,8 +238,6 @@ class MappingVersionDisplayInfo(item_infos.CorrespondsToMappingDCMixin): active: ActiveStatus is_orphan: bool is_local: bool - mapping_enabled: EnabledStatus - mapping_frozen: t.Optional[FrozenStatus] @dc.dataclass(frozen=True, unsafe_hash=True) # type: ignore[misc] class MappingRef(Ref, item_infos.CorrespondsToMappingDCMixin): @@ -249,8 +251,7 @@ class MappingRef(Ref, item_infos.CorrespondsToMappingDCMixin): ... @abstractmethod - def get_version_display_infos(self) \ - -> t.Sequence[MappingVersionDisplayInfo]: + def get_display_info(self) -> RichMappingDisplayInfo: ... @@ -278,8 +279,7 @@ class MappingVersionRef(Ref, item_infos.CorrespondsToMappingDCMixin): ... @abstractmethod - def get_all_version_display_infos(self) \ - -> t.Sequence[MappingVersionDisplayInfo]: + def get_item_display_info(self) -> RichMappingDisplayInfo: ... class MappingVersionStore(Store[MappingVersionRef]): @@ -291,6 +291,10 @@ class ResourceDisplayInfo(item_infos.CorrespondsToResourceDCMixin): ref: 'ResourceRef' identifier: str +@dc.dataclass(frozen=True) +class RichResourceDisplayInfo(ResourceDisplayInfo): + all_versions: t.Sequence['ResourceVersionDisplayInfo'] + @dc.dataclass(frozen=True) class ResourceVersionDisplayInfo(item_infos.CorrespondsToResourceDCMixin): ref: 'ResourceVersionRef' @@ -303,8 +307,7 @@ class ResourceVersionDisplayInfo(item_infos.CorrespondsToResourceDCMixin): @dc.dataclass(frozen=True, unsafe_hash=True) # type: ignore[misc] class ResourceRef(Ref, item_infos.CorrespondsToResourceDCMixin): @abstractmethod - def get_version_display_infos(self) \ - -> t.Sequence[ResourceVersionDisplayInfo]: + def get_display_info(self) -> RichResourceDisplayInfo: ... class ResourceStore(Store[ResourceRef]): @@ -324,8 +327,7 @@ class ResourceVersionRef(Ref, item_infos.CorrespondsToResourceDCMixin): ... @abstractmethod - def get_all_version_display_infos(self) \ - -> t.Sequence[ResourceVersionDisplayInfo]: + def get_item_display_info(self) -> RichResourceDisplayInfo: ... class ResourceVersionStore(Store[ResourceVersionRef]): diff --git a/src/hydrilla/proxy/state_impl/items.py b/src/hydrilla/proxy/state_impl/items.py index 919223b..5f2f274 100644 --- a/src/hydrilla/proxy/state_impl/items.py +++ b/src/hydrilla/proxy/state_impl/items.py @@ -37,10 +37,34 @@ import sqlite3 import typing as t import dataclasses as dc +from contextlib import contextmanager + from ... import item_infos from .. import state as st from . import base + +def _get_parent_item_id(cursor: sqlite3.Cursor, version_id: str) -> str: + cursor.execute( + ''' + SELECT + item_id + FROM + item_versions + WHERE + item_version_id = ?; + ''', + (version_id,) + ) + + rows = cursor.fetchall() + if rows == []: + raise st.MissingItemError() + + (item_id,), = rows + + return str(item_id) + def _set_installed_status(cursor: sqlite3.Cursor, id: str, new_status: str) \ -> None: cursor.execute( @@ -213,41 +237,56 @@ class ConcreteMappingRef(st.MappingRef): self.state.recompute_dependencies([int(self.id)]) - def get_version_display_infos(self) \ - -> t.Sequence[st.MappingVersionDisplayInfo]: + def get_display_info(self) -> st.RichMappingDisplayInfo: with self.state.cursor() as cursor: cursor.execute( ''' SELECT - ive.item_version_id, - ive.definition, - ive.repo, - ive.repo_iteration, - ive.installed, - ive.active, - ive.is_orphan, - ive.is_local, - ms.frozen, - ms.enabled + i.identifier, + ms.enabled, ms.frozen FROM - item_versions_extra AS ive - JOIN mapping_statuses AS ms USING (item_id) + items AS i + JOIN mapping_statuses AS ms USING (item_id) WHERE - ive.item_id = ?; + item_id = ?; ''', (self.id,) ) rows = cursor.fetchall() - if rows == []: - raise st.MissingItemError() + if rows == []: + raise st.MissingItemError() - result = [] + (identifier, enabled_status, frozen_status), = rows + + cursor.execute( + ''' + SELECT + item_version_id, + definition, + repo, + repo_iteration, + installed, + active, + is_orphan, + is_local + FROM + item_versions_extra + WHERE + item_id = ?; + ''', + (self.id,) + ) + + rows = cursor.fetchall() + + version_infos = [] + + active_info: t.Optional[st.MappingVersionDisplayInfo] = None for (item_version_id, definition, repo, repo_iteration, - installed_status, active_status, is_orphan, is_local, - frozen_status, enabled_status) in rows: + installed_status, active_status, is_orphan, is_local) in rows: ref = ConcreteMappingVersionRef(str(item_version_id), self.state) item_info = item_infos.MappingInfo.load( @@ -256,19 +295,28 @@ class ConcreteMappingRef(st.MappingRef): repo_iteration ) - display_info = st.MappingVersionDisplayInfo( + version_display_info = st.MappingVersionDisplayInfo( ref = ref, info = item_info, installed = st.InstalledStatus(installed_status), active = st.ActiveStatus(active_status), is_orphan = is_orphan, - is_local = is_local, - mapping_enabled = st.EnabledStatus(enabled_status), - mapping_frozen = st.FrozenStatus.make(frozen_status) + is_local = is_local ) - result.append(display_info) - return sorted(result, key=(lambda di: di.info)) + version_infos.append(version_display_info) + + if active_status in ('R', 'A'): + active_info = version_display_info + + return st.RichMappingDisplayInfo( + ref = self, + identifier = identifier, + enabled = st.EnabledStatus(enabled_status), + frozen = st.FrozenStatus.make(frozen_status), + active_version = active_info, + all_versions = sorted(version_infos, key=(lambda vi: vi.info)) + ) @dc.dataclass(frozen=True) @@ -338,9 +386,7 @@ class ConcreteMappingStore(st.MappingStore): installed = st.InstalledStatus(installed_status), active = st.ActiveStatus(active_status), is_orphan = is_orphan, - is_local = is_local, - mapping_enabled = st.EnabledStatus(enabled_status), - mapping_frozen = st.FrozenStatus.make(frozen_status) + is_local = is_local ) display_info = st.MappingDisplayInfo( @@ -366,56 +412,27 @@ class ConcreteMappingVersionRef(st.MappingVersionRef): def uninstall(self) -> t.Optional['ConcreteMappingVersionRef']: return _uninstall_version(self) + @contextmanager + def _mapping_ref(self) -> t.Iterator[ConcreteMappingRef]: + with self.state.cursor(transaction=True) as cursor: + mapping_id = _get_parent_item_id(cursor, self.id) + yield ConcreteMappingRef(mapping_id, self.state) + def update_mapping_status( self, enabled: st.EnabledStatus, frozen: t.Optional[st.FrozenStatus] = None ) -> None: - with self.state.cursor(transaction=True) as cursor: - cursor.execute( - 'SELECT item_id FROM item_versions WHERE item_version_id = ?;', - (self.id,) - ) - - rows = cursor.fetchall() - - if rows == []: - raise st.MissingItemError() - - (mapping_id,), = rows - - mapping_ref = ConcreteMappingRef(str(mapping_id), self.state) - + with self._mapping_ref() as mapping_ref: id_to_pass: t.Optional[str] = self.id if enabled.value != 'E' or frozen is None or frozen.value == 'N': id_to_pass = None mapping_ref.update_status(enabled, frozen, id_to_pass) - def get_all_version_display_infos(self) \ - -> t.Sequence[st.MappingVersionDisplayInfo]: - with self.state.cursor() as cursor: - cursor.execute( - ''' - SELECT - item_id - FROM - item_versions - WHERE - item_version_id = ?; - ''', - (self.id,) - ) - - rows = cursor.fetchall() - if rows == []: - raise st.MissingItemError() - - (mapping_id,), = rows - - mapping_ref = ConcreteMappingRef(str(mapping_id), self.state) - - return mapping_ref.get_version_display_infos() + def get_item_display_info(self) -> st.RichMappingDisplayInfo: + with self._mapping_ref() as mapping_ref: + return mapping_ref.get_display_info() @dc.dataclass(frozen=True) @@ -430,35 +447,42 @@ class ConcreteMappingVersionStore(st.MappingVersionStore): class ConcreteResourceRef(st.ResourceRef): state: base.HaketiloStateWithFields = dc.field(hash=False, compare=False) - def get_version_display_infos(self) \ - -> t.Sequence[st.ResourceVersionDisplayInfo]: + def get_display_info(self) -> st.RichResourceDisplayInfo: with self.state.cursor() as cursor: + cursor.execute( + 'SELECT identifier FROM items WHERE item_id = ?;', + (self.id,) + ) + + rows = cursor.fetchall() + + if rows == []: + raise st.MissingItemError() + + (identifier,), = rows + cursor.execute( ''' SELECT - ive.item_version_id, - ive.definition, - ive.repo, - ive.repo_iteration, - ive.installed, - ive.active, - ive.is_orphan, - ive.is_local + item_version_id, + definition, + repo, + repo_iteration, + installed, + active, + is_orphan, + is_local FROM - item_versions_extra AS ive - JOIN items AS i USING (item_id) + item_versions_extra WHERE - i.type = 'R' AND ive.item_id = ?; + item_id = ?; ''', (self.id,) ) rows = cursor.fetchall() - if rows == []: - raise st.MissingItemError() - - result = [] + version_infos = [] for (item_version_id, definition, repo, repo_iteration, installed_status, active_status, is_orphan, is_local) in rows: @@ -478,9 +502,14 @@ class ConcreteResourceRef(st.ResourceRef): is_orphan = is_orphan, is_local = is_local ) - result.append(display_info) - return sorted(result, key=(lambda di: di.info)) + version_infos.append(display_info) + + return st.RichResourceDisplayInfo( + ref = self, + identifier = identifier, + all_versions = sorted(version_infos, key=(lambda vi: vi.info)) + ) @dc.dataclass(frozen=True) @@ -518,30 +547,11 @@ class ConcreteResourceVersionRef(st.ResourceVersionRef): def uninstall(self) -> t.Optional['ConcreteResourceVersionRef']: return _uninstall_version(self) - def get_all_version_display_infos(self) \ - -> t.Sequence[st.ResourceVersionDisplayInfo]: + def get_item_display_info(self) -> st.RichResourceDisplayInfo: with self.state.cursor() as cursor: - cursor.execute( - ''' - SELECT - item_id - FROM - item_versions - WHERE - item_version_id = ?; - ''', - (self.id,) - ) - - rows = cursor.fetchall() - if rows == []: - raise st.MissingItemError() - - (resource_id,), = rows - - resource_ref = ConcreteResourceRef(str(resource_id), self.state) - - return resource_ref.get_version_display_infos() + resource_id = _get_parent_item_id(cursor, self.id) + resource_ref = ConcreteResourceRef(resource_id, self.state) + return resource_ref.get_display_info() @dc.dataclass(frozen=True) diff --git a/src/hydrilla/proxy/web_ui/items.py b/src/hydrilla/proxy/web_ui/items.py index 01ae406..a781856 100644 --- a/src/hydrilla/proxy/web_ui/items.py +++ b/src/hydrilla/proxy/web_ui/items.py @@ -124,40 +124,11 @@ def show_item(item_id: str, item_type: item_infos.ItemType) \ -> werkzeug.Response: try: store = item_store(_app.get_haketilo_state(), item_type) - item_ref = store.get(str(item_id)) - version_display_infos = item_ref.get_version_display_infos() - - display_info: t.Union[st.MappingDisplayInfo, st.ResourceDisplayInfo] - - if isinstance(item_ref, st.ResourceRef): - display_info = st.ResourceDisplayInfo( - ref = item_ref, - identifier = version_display_infos[0].info.identifier - ) - else: - version_display_infos = t.cast( - t.Sequence[st.MappingVersionDisplayInfo], - version_display_infos - ) - - active_version: t.Optional[st.MappingVersionDisplayInfo] = None - - for info in version_display_infos: - if info.active != st.ActiveStatus.NOT_ACTIVE: - active_version = info - - display_info = st.MappingDisplayInfo( - ref = item_ref, - identifier = version_display_infos[0].info.identifier, - enabled = version_display_infos[0].mapping_enabled, - frozen = version_display_infos[0].mapping_frozen, - active_version = active_version - ) + display_info = store.get(str(item_id)).get_display_info() html = flask.render_template( f'items/{item_type.alt_name}_view.html.jinja', - display_info = display_info, - version_display_infos = version_display_infos + display_info = display_info ) return flask.make_response(html, 200) except st.MissingItemError: @@ -194,23 +165,20 @@ def show_item_version( try: store = item_version_store(_app.get_haketilo_state(), item_type) version_ref = store.get(item_version_id) - display_infos = version_ref.get_all_version_display_infos() + display_info = version_ref.get_item_display_info() - other_infos: list[ItemVersionDisplayInfo] = [] this_info: t.Optional[ItemVersionDisplayInfo] = None - for info in display_infos: + for info in display_info.all_versions: if info.ref == version_ref: this_info = info - else: - other_infos.append(info) assert this_info is not None html = flask.render_template( f'items/{item_type.alt_name}_viewversion.html.jinja', - display_info = this_info, - version_display_infos = other_infos, + display_info = display_info, + version_display_info = this_info, **errors ) return flask.make_response(html, 200) @@ -246,6 +214,24 @@ def alter_item_version(item_version_id: str, item_type: item_infos.ItemType) \ enabled = st.EnabledStatus.ENABLED, frozen = st.FrozenStatus.EXACT_VERSION, ) + elif action == 'unfreeze_item': + assert isinstance(item_version_ref, st.MappingVersionRef) + item_version_ref.update_mapping_status( + enabled = st.EnabledStatus.ENABLED, + frozen = st.FrozenStatus.NOT_FROZEN, + ) + elif action == 'freeze_to_repo': + assert isinstance(item_version_ref, st.MappingVersionRef) + item_version_ref.update_mapping_status( + enabled = st.EnabledStatus.ENABLED, + frozen = st.FrozenStatus.REPOSITORY, + ) + elif action == 'freeze_to_version': + assert isinstance(item_version_ref, st.MappingVersionRef) + item_version_ref.update_mapping_status( + enabled = st.EnabledStatus.ENABLED, + frozen = st.FrozenStatus.EXACT_VERSION, + ) elif action == 'install_item_version': item_version_ref.install() elif action == 'uninstall_item_version': diff --git a/src/hydrilla/proxy/web_ui/root.py b/src/hydrilla/proxy/web_ui/root.py index b199506..eac3be7 100644 --- a/src/hydrilla/proxy/web_ui/root.py +++ b/src/hydrilla/proxy/web_ui/root.py @@ -84,6 +84,7 @@ class WebUIAppImpl(_app.WebUIApp): self.jinja_env.globals['get_current_endpoint'] = get_current_endpoint self.jinja_env.globals['EnabledStatus'] = st.EnabledStatus + self.jinja_env.globals['FrozenStatus'] = st.FrozenStatus self.jinja_env.globals['InstalledStatus'] = st.InstalledStatus self.jinja_env.globals['ActiveStatus'] = st.ActiveStatus self.jinja_env.globals['ItemType'] = item_infos.ItemType diff --git a/src/hydrilla/proxy/web_ui/templates/items/item_view.html.jinja b/src/hydrilla/proxy/web_ui/templates/items/item_view.html.jinja index 861d5ef..1ad8df3 100644 --- a/src/hydrilla/proxy/web_ui/templates/items/item_view.html.jinja +++ b/src/hydrilla/proxy/web_ui/templates/items/item_view.html.jinja @@ -19,6 +19,15 @@ file's licenses. Although I request that you do not make use this code in a proprietary work, I am not going to enforce this in court. #} {% extends "base.html.jinja" %} + +{% macro versioned_identifier_with_repo(info) %} + {{ info.info.versioned_identifier }} + {% if not info.is_local %} + @ + {{ info.info.repo }} + {% endif %} +{% endmacro %} + {% block style %} {{ super() }} @@ -28,38 +37,37 @@ in a proprietary work, I am not going to enforce this in court. {% block main_info %}

{% block heading required %}{% endblock %}

{% endblock %} - {% if version_display_infos|length > 0 %} + {% if display_info.all_versions|length > 0 %}

{% block version_list_heading required %} {% endblock %}

- {% endif %}{# version_display_infos|length > 0 #} + {% endif %}{# display_info.all_versions|length > 0 #} {% endblock main %} diff --git a/src/hydrilla/proxy/web_ui/templates/items/item_viewversion.html.jinja b/src/hydrilla/proxy/web_ui/templates/items/item_viewversion.html.jinja index 54cb3cf..de62330 100644 --- a/src/hydrilla/proxy/web_ui/templates/items/item_viewversion.html.jinja +++ b/src/hydrilla/proxy/web_ui/templates/items/item_viewversion.html.jinja @@ -39,25 +39,25 @@ in a proprietary work, I am not going to enforce this in court. {{ super() }}
- {{ display_info.info.versioned_identifier }} + {{ versioned_identifier_with_repo(version_display_info) }}
{% block main_info_bulk %} TODO: add more info... {% endblock %} - {% if display_info.active == ActiveStatus.REQUIRED %} + {% if version_display_info.active == ActiveStatus.REQUIRED %}
{% block item_required_msg required %}{% endblock %}
- {% elif display_info.active == ActiveStatus.AUTO %} + {% elif version_display_info.active == ActiveStatus.AUTO %}
{% block item_auto_activated_msg required %}{% endblock %}
{% else %} - {# display_info.active == ActiveStatus.NOT_ACTIVE #} + {# version_display_info.active == ActiveStatus.NOT_ACTIVE #}
{% block item_not_activated_msg required %}{% endblock %}
{% endif %} {% set install_but_classes = ['green-button', 'button-bordering-left'] %} {% set uninstall_but_classes = ['green-button', 'button-bordering-right'] %} - {% if display_info.installed == InstalledStatus.FAILED_TO_INSTALL %} + {% if version_display_info.installed == InstalledStatus.FAILED_TO_INSTALL %} {% set install_text = _('web_ui.items.single_version.retry_install_button') @@ -70,19 +70,19 @@ in a proprietary work, I am not going to enforce this in court. {% else %} {% set install_text = _('web_ui.items.single_version.install_button') %} {% set uninstall_text = _('web_ui.items.single_version.uninstall_button') %} - {% if display_info.installed == InstalledStatus.INSTALLED %} + {% if version_display_info.installed == InstalledStatus.INSTALLED %} {% do install_but_classes.append('disabled-button') %} {% if uninstall_disallowed is defined or - display_info.active == ActiveStatus.REQUIRED + version_display_info.active == ActiveStatus.REQUIRED %} {% do uninstall_but_classes.append('disabled-button') %} {% endif %} {% else %} - {# display_info.installed == InstalledStatus.NOT_INSTALLED #} + {# version_display_info.installed == InstalledStatus.NOT_INSTALLED #} {% do uninstall_but_classes.append('disabled-button') %} {% endif %} - {% endif %}{# else/ display_info.installed == InstalledStatus.FAILED_TO_I...#} + {% endif %}{# else/ version_display_info.installed == InstalledStatus.FA... #} {{ button_row([ (uninstall_but_classes, uninstall_text, 'uninstall_item_version'), diff --git a/src/hydrilla/proxy/web_ui/templates/items/library_viewversion.html.jinja b/src/hydrilla/proxy/web_ui/templates/items/library_viewversion.html.jinja index 30e084d..9e0a32e 100644 --- a/src/hydrilla/proxy/web_ui/templates/items/library_viewversion.html.jinja +++ b/src/hydrilla/proxy/web_ui/templates/items/library_viewversion.html.jinja @@ -25,10 +25,17 @@ in a proprietary work, I am not going to enforce this in court. {% endblock %} {% block heading %} - {{ - _('web_ui.items.single_version.library.heading.name_{}') - .format(display_info.info.long_name) - }} + {% if version_display_info.is_local %} + {{ + _('web_ui.items.single_version.library_local.heading.name_{}') + .format(version_display_info.info.long_name) + }} + {% else %} + {{ + _('web_ui.items.single_version.library.heading.name_{}') + .format(version_display_info.info.long_name) + }} + {% endif %} {% endblock %} {% block item_required_msg %} diff --git a/src/hydrilla/proxy/web_ui/templates/items/package_viewversion.html.jinja b/src/hydrilla/proxy/web_ui/templates/items/package_viewversion.html.jinja index a532b5f..ea8b7d3 100644 --- a/src/hydrilla/proxy/web_ui/templates/items/package_viewversion.html.jinja +++ b/src/hydrilla/proxy/web_ui/templates/items/package_viewversion.html.jinja @@ -25,10 +25,17 @@ in a proprietary work, I am not going to enforce this in court. {% endblock %} {% block heading %} - {{ - _('web_ui.items.single_version.package.heading.name_{}') - .format(display_info.info.long_name) - }} + {% if version_display_info.is_local %} + {{ + _('web_ui.items.single_version.package_local.heading.name_{}') + .format(version_display_info.info.long_name) + }} + {% else %} + {{ + _('web_ui.items.single_version.package.heading.name_{}') + .format(version_display_info.info.long_name) + }} + {% endif %} {% endblock %} {% block item_required_msg %} @@ -66,28 +73,18 @@ in a proprietary work, I am not going to enforce this in court. {% set unenable_text = _('web_ui.items.single_version.unenable_button') %} {% set disable_text = _('web_ui.items.single_version.disable_button') %} - {% - if display_info.mapping_enabled == EnabledStatus.ENABLED and - display_info.active == ActiveStatus.NOT_ACTIVE - %} - {% - set enable_text = - _('web_ui.items.single_version.freeze_to_this_button') - %} - {% else %} - {% set enable_text = _('web_ui.items.single_version.enable_button') %} - {% endif %} + {% set enable_text = _('web_ui.items.single_version.enable_button') %} - {% if display_info.mapping_enabled == EnabledStatus.NO_MARK %} + {% if display_info.enabled == EnabledStatus.NO_MARK %} {% do unenable_but_classes.append('disabled-button') %} - {% elif display_info.mapping_enabled == EnabledStatus.DISABLED %} +
{{ _('web_ui.items.single_version.item_not_marked') }}
+ {% elif display_info.enabled == EnabledStatus.DISABLED %} {% do disable_but_classes.append('disabled-button') %} +
{{ _('web_ui.items.single_version.item_disabled') }}
{% else %} - {% if display_info.active == ActiveStatus.REQUIRED %} - {% do enable_but_classes.append('disabled-button') %} - {% else %} -
{{ _('web_ui.items.single_version.other_version_enabled') }}
- {% endif %} + {# display_info.enabled == EnabledStatus.ENABLED #} + {% do enable_but_classes.append('disabled-button') %} +
{{ _('web_ui.items.single_version.item_enabled') }}
{% endif %} {{ @@ -97,4 +94,82 @@ in a proprietary work, I am not going to enforce this in court. (enable_but_classes, enable_text, 'enable_item_version') ]) }} + + {% if display_info.enabled == EnabledStatus.ENABLED %} + {% set unpin_but_classes = ['green-button', 'button-bordering-right'] %} + {% + set pin_repo_but_classes = [ + 'green-button', + 'button-bordering-right', + 'button-bordering-left' + ] + %} + {% set pin_ver_but_classes = ['green-button', 'button-bordering-left'] %} + + {% set unpin_text = _('web_ui.items.single_version.unpin_button') %} + + {% if display_info.frozen == FrozenStatus.NOT_FROZEN %} + {% do unpin_but_classes.append('disabled-button') %} +
{{ _('web_ui.items.single_version.not_pinned') }}
+ {% endif %} + + {% if display_info.frozen == FrozenStatus.REPOSITORY %} + {% if display_info.active_version.is_local %} +
{{ _('web_ui.items.single_version.pinned_repo_local') }}
+ {% else %} +
+ {{ + _('web_ui.items.single_version.pinned_repo_{}') + .format(display_info.active_version.info.repo) + }} +
+ {% endif %} + {% + if display_info.active_version.info.repo == + version_display_info.info.repo + %} + {% if version_display_info.is_local %} + {% + set pin_repo_text = + _('web_ui.items.single_version.pin_local_repo_button') + %} + {% else %} + {% + set pin_repo_text = _('web_ui.items.single_version.pin_repo_button') + %} + {% endif %} + {% do pin_repo_but_classes.append('disabled-button') %} + {% else %} + {% + set pin_repo_text = + _('web_ui.items.single_version.repin_repo_button') + %} + {% endif %} + {% else %}{# display_info.frozen == FrozenStatus.REPOSITORY #} + {% set pin_repo_text = _('web_ui.items.single_version.pin_repo_button') %} + {% endif %}{# else/ display_info.frozen == FrozenStatus.REPOSITORY #} + + {% if display_info.frozen == FrozenStatus.EXACT_VERSION %} + {% if display_info.active_version.ref == version_display_info.ref %} + {% set pin_ver_text = _('web_ui.items.single_version.pin_ver_button') %} + {% do pin_ver_but_classes.append('disabled-button') %} +
{{ _('web_ui.items.single_version.pinned_ver') }}
+ {% else %} + {% + set pin_ver_text = _('web_ui.items.single_version.repin_ver_button') + %} +
{{ _('web_ui.items.single_version.pinned_other_ver') }}
+ {% endif %} + {% else %} + {% set pin_ver_text = _('web_ui.items.single_version.pin_ver_button') %} + {% endif %}{# else/ display_info.frozen == FrozenStatus.EXACT_VERSION #} + + {{ + button_row([ + (unpin_but_classes, unpin_text, 'unfreeze_item'), + (pin_repo_but_classes, pin_repo_text, 'freeze_to_repo'), + (pin_ver_but_classes, pin_ver_text, 'freeze_to_version') + ]) + }} + {% endif %}{# display_info.enabled == EnabledStatus.ENABLED #} {% endblock main_info_bulk %} diff --git a/src/hydrilla/proxy/web_ui/templates/repos/show_single.html.jinja b/src/hydrilla/proxy/web_ui/templates/repos/show_single.html.jinja index ce1cef2..604b38c 100644 --- a/src/hydrilla/proxy/web_ui/templates/repos/show_single.html.jinja +++ b/src/hydrilla/proxy/web_ui/templates/repos/show_single.html.jinja @@ -80,7 +80,7 @@ in a proprietary work, I am not going to enforce this in court. -