summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWojtek Kosior <koszko@koszko.org>2022-09-01 18:44:48 +0200
committerWojtek Kosior <koszko@koszko.org>2022-09-28 12:54:55 +0200
commitd150d656bdab394f649a67490b146c5798361187 (patch)
tree4fef7b190cc4c5db625e06c5b0d76ca55bc3badd
parentf2b91572b163099b29c940cf6fe5814a047fdc51 (diff)
downloadhaketilo-hydrilla-d150d656bdab394f649a67490b146c5798361187.tar.gz
haketilo-hydrilla-d150d656bdab394f649a67490b146c5798361187.zip
[proxy] make it possible to enable and disable mapping versions from web UI
-rw-r--r--src/hydrilla/proxy/state.py16
-rw-r--r--src/hydrilla/proxy/state_impl/_operations/recompute_dependencies.py28
-rw-r--r--src/hydrilla/proxy/state_impl/items.py127
-rw-r--r--src/hydrilla/proxy/web_ui/items.py14
-rw-r--r--src/hydrilla/proxy/web_ui/templates/base.html.jinja18
-rw-r--r--src/hydrilla/proxy/web_ui/templates/items/item_viewversion.html.jinja34
-rw-r--r--src/hydrilla/proxy/web_ui/templates/items/library_viewversion.html.jinja16
-rw-r--r--src/hydrilla/proxy/web_ui/templates/items/package_viewversion.html.jinja64
8 files changed, 286 insertions, 31 deletions
diff --git a/src/hydrilla/proxy/state.py b/src/hydrilla/proxy/state.py
index 1246c92..f882b2d 100644
--- a/src/hydrilla/proxy/state.py
+++ b/src/hydrilla/proxy/state.py
@@ -241,6 +241,14 @@ class MappingVersionDisplayInfo(item_infos.CorrespondsToMappingDCMixin):
class MappingRef(Ref, item_infos.CorrespondsToMappingDCMixin):
"""...."""
@abstractmethod
+ def update_status(
+ self,
+ enabled: EnabledStatus,
+ frozen: t.Optional[FrozenStatus] = None
+ ) -> None:
+ ...
+
+ @abstractmethod
def get_version_display_infos(self) \
-> t.Sequence[MappingVersionDisplayInfo]:
...
@@ -262,6 +270,14 @@ class MappingVersionRef(Ref, item_infos.CorrespondsToMappingDCMixin):
...
@abstractmethod
+ def update_mapping_status(
+ self,
+ enabled: EnabledStatus,
+ frozen: t.Optional[FrozenStatus] = None
+ ) -> None:
+ ...
+
+ @abstractmethod
def get_all_version_display_infos(self) \
-> t.Sequence[MappingVersionDisplayInfo]:
...
diff --git a/src/hydrilla/proxy/state_impl/_operations/recompute_dependencies.py b/src/hydrilla/proxy/state_impl/_operations/recompute_dependencies.py
index 5403ec3..9419f91 100644
--- a/src/hydrilla/proxy/state_impl/_operations/recompute_dependencies.py
+++ b/src/hydrilla/proxy/state_impl/_operations/recompute_dependencies.py
@@ -49,21 +49,26 @@ AnyInfoVar = t.TypeVar(
def _get_infos_of_type(cursor: sqlite3.Cursor, info_type: t.Type[AnyInfoVar],) \
-> t.Mapping[int, AnyInfoVar]:
+ join_mapping_statuses = 'JOIN mapping_statuses AS ms USING (item_id)'
+ condition = "i.type = 'M' AND ms.enabled != 'D'"
+ if info_type is item_infos.ResourceInfo:
+ join_mapping_statuses = ''
+ condition = "i.type = 'R'"
+
cursor.execute(
- '''
+ f'''
SELECT
ive.item_version_id,
ive.definition,
ive.repo,
ive.repo_iteration
FROM
- item_versions_extra AS ive
- JOIN items AS i USING (item_id)
- LEFT JOIN mapping_statuses AS ms USING (item_id)
+ item_versions_extra AS ive
+ JOIN items AS i USING (item_id)
+ {join_mapping_statuses}
WHERE
- i.type = ? AND COALESCE(ms.enabled != 'D', TRUE);
- ''',
- (info_type.type.value[0].upper(),)
+ {condition};
+ '''
)
result: dict[int, AnyInfoVar] = {}
@@ -92,11 +97,14 @@ def _get_current_required_state(
cursor.execute(
'''
SELECT
- definition, repo, repo_iteration
+ ive.definition, ive.repo, ive.repo_iteration
FROM
- item_versions_extra
+ item_versions_extra AS ive
+ JOIN items AS i USING (item_id)
WHERE
- item_id NOT IN __unlocked_ids AND active = 'R';
+ i.type = 'M' AND
+ item_id NOT IN __unlocked_ids AND
+ ive.active = 'R';
''',
)
diff --git a/src/hydrilla/proxy/state_impl/items.py b/src/hydrilla/proxy/state_impl/items.py
index ddfef7c..919223b 100644
--- a/src/hydrilla/proxy/state_impl/items.py
+++ b/src/hydrilla/proxy/state_impl/items.py
@@ -48,7 +48,7 @@ def _set_installed_status(cursor: sqlite3.Cursor, id: str, new_status: str) \
(new_status, id)
)
-def _get_statuses(cursor: sqlite3.Cursor, id: str) -> t.Tuple[str, str]:
+def _get_statuses(cursor: sqlite3.Cursor, id: str) -> tuple[str, str]:
cursor.execute(
'''
SELECT
@@ -114,6 +114,105 @@ def _uninstall_version(ref: VersionRefVar) -> t.Optional[VersionRefVar]:
class ConcreteMappingRef(st.MappingRef):
state: base.HaketiloStateWithFields = dc.field(hash=False, compare=False)
+ def _get_status_data(self, cursor: sqlite3.Cursor) \
+ -> tuple[str, str, int]:
+ cursor.execute(
+ '''
+ SELECT
+ ms.enabled, ms.frozen, ms.active_version_id
+ FROM
+ mapping_statuses
+ WHERE
+ item_id = ?;
+ ''',
+ (self.id,)
+ )
+
+ rows = cursor.fetchall()
+
+ if rows == []:
+ raise st.MissingItemError()
+
+ (enabled_status, frozen_status, active_version_id), = rows
+
+ return (enabled_status, frozen_status, active_version_id)
+
+
+ def update_status(
+ self,
+ enabled: st.EnabledStatus,
+ frozen: t.Optional[st.FrozenStatus] = None,
+ version_id_to_activate: t.Optional[str] = None
+ ) -> None:
+ assert frozen is None or enabled == st.EnabledStatus.ENABLED
+ assert version_id_to_activate is None or \
+ frozen != st.FrozenStatus.NOT_FROZEN
+
+ with self.state.cursor(transaction=True) as cursor:
+ cursor.execute(
+ '''
+ SELECT
+ enabled, frozen, active_version_id
+ FROM
+ mapping_statuses
+ WHERE
+ item_id = ?;
+ ''',
+ (self.id,)
+ )
+
+ rows = cursor.fetchall()
+
+ if rows == []:
+ raise st.MissingItemError()
+
+ (old_enabled_status, old_frozen_status,
+ old_active_version_id), = rows
+
+ if enabled.value == old_enabled_status and frozen is None:
+ return
+
+ new_enabled_status = enabled.value
+
+ new_frozen_status = None if frozen is None else frozen.value
+
+ if version_id_to_activate is not None:
+ new_active_version_id = version_id_to_activate
+ elif enabled == st.EnabledStatus.ENABLED:
+ new_active_version_id = str(old_active_version_id)
+ else:
+ new_active_version_id = None
+
+ cursor.execute(
+ '''
+ UPDATE
+ mapping_statuses
+ SET
+ enabled = ?,
+ frozen = ?,
+ active_version_id = ?
+ WHERE
+ item_id = ?;
+ ''', (
+ new_enabled_status,
+ new_frozen_status,
+ new_active_version_id,
+ self.id
+ ))
+
+ if enabled == st.EnabledStatus.ENABLED:
+ if old_enabled_status == 'E' and \
+ new_active_version_id == str(old_active_version_id) and \
+ (new_frozen_status == 'E' or
+ old_frozen_status == 'N' or
+ new_frozen_status == old_frozen_status):
+ return
+ else:
+ if old_active_version_id is None:
+ return
+
+ self.state.recompute_dependencies([int(self.id)])
+
def get_version_display_infos(self) \
-> t.Sequence[st.MappingVersionDisplayInfo]:
with self.state.cursor() as cursor:
@@ -267,6 +366,32 @@ class ConcreteMappingVersionRef(st.MappingVersionRef):
def uninstall(self) -> t.Optional['ConcreteMappingVersionRef']:
return _uninstall_version(self)
+ 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)
+
+ 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:
diff --git a/src/hydrilla/proxy/web_ui/items.py b/src/hydrilla/proxy/web_ui/items.py
index 4bfae0a..01ae406 100644
--- a/src/hydrilla/proxy/web_ui/items.py
+++ b/src/hydrilla/proxy/web_ui/items.py
@@ -234,7 +234,19 @@ def alter_item_version(item_version_id: str, item_type: item_infos.ItemType) \
store = item_version_store(_app.get_haketilo_state(), item_type)
item_version_ref = store.get(item_version_id)
- if action == 'install_item_version':
+ if action == 'disable_item':
+ assert isinstance(item_version_ref, st.MappingVersionRef)
+ item_version_ref.update_mapping_status(st.EnabledStatus.DISABLED)
+ elif action == 'unenable_item':
+ assert isinstance(item_version_ref, st.MappingVersionRef)
+ item_version_ref.update_mapping_status(st.EnabledStatus.NO_MARK)
+ elif action == 'enable_item_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':
item_version_ref_after = item_version_ref.uninstall()
diff --git a/src/hydrilla/proxy/web_ui/templates/base.html.jinja b/src/hydrilla/proxy/web_ui/templates/base.html.jinja
index 8b8be4b..9520787 100644
--- a/src/hydrilla/proxy/web_ui/templates/base.html.jinja
+++ b/src/hydrilla/proxy/web_ui/templates/base.html.jinja
@@ -19,6 +19,22 @@ 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.
-#}
<!DOCTYPE html>
+
+{% macro button_row(buttons_data) %}
+ <div class="button-row">
+ {% for classes, text, action in buttons_data %}
+ {% if 'disabled-button' in classes %}
+ <button class="{{ classes|join(' ') }}">{{ text }}</button>
+ {% else %}
+ <form method="POST" class="inline-form">
+ <input name="action" value="{{ action }}" type="hidden">
+ <button class="{{ classes|join(' ') }}">{{ text }}</button>
+ </form>
+ {% endif %}
+ {% endfor %}
+ </div>
+{% endmacro %}
+
<html>
<head>
{% block head %}
@@ -88,7 +104,7 @@ in a proprietary work, I am not going to enforce this in court.
background-color: #af504c;
}
- .red-button {
+ .blue-button {
background-color: #504caf;
}
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 151a8b3..54cb3cf 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
@@ -46,6 +46,15 @@ in a proprietary work, I am not going to enforce this in court.
TODO: add more info...
{% endblock %}
+ {% if display_info.active == ActiveStatus.REQUIRED %}
+ <div>{% block item_required_msg required %}{% endblock %}</div>
+ {% elif display_info.active == ActiveStatus.AUTO %}
+ <div>{% block item_auto_activated_msg required %}{% endblock %}</div>
+ {% else %}
+ {# display_info.active == ActiveStatus.NOT_ACTIVE #}
+ <div>{% block item_not_activated_msg required %}{% endblock %}</div>
+ {% 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 %}
@@ -57,7 +66,7 @@ in a proprietary work, I am not going to enforce this in court.
set uninstall_text =
_('web_ui.items.single_version.leave_uninstalled_button')
%}
- <div>{% block item_install_failed_msg %}{% endblock %}</div>
+ <div>{% block item_install_failed_msg required %}{% endblock %}</div>
{% else %}
{% set install_text = _('web_ui.items.single_version.install_button') %}
{% set uninstall_text = _('web_ui.items.single_version.uninstall_button') %}
@@ -74,21 +83,10 @@ in a proprietary work, I am not going to enforce this in court.
{% do uninstall_but_classes.append('disabled-button') %}
{% endif %}
{% endif %}{# else/ display_info.installed == InstalledStatus.FAILED_TO_I...#}
- <div class="button-row">
- {%
- for classes, text, action in [
- (uninstall_but_classes, uninstall_text, 'uninstall_item_version'),
- (install_but_classes, install_text, 'install_item_version')
- ]
- %}
- {% if 'disabled-button' in classes %}
- <button class="{{ classes|join(' ') }}">{{ text }}</button>
- {% else %}
- <form method="POST" class="inline-form">
- <input name="action" value="{{ action }}" type="hidden">
- <button class="{{ classes|join(' ') }}">{{ text }}</button>
- </form>
- {% endif %}
- {% endfor %}
- </div>
+ {{
+ button_row([
+ (uninstall_but_classes, uninstall_text, 'uninstall_item_version'),
+ (install_but_classes, install_text, 'install_item_version')
+ ])
+ }}
{% endblock main_info %}
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 2176646..30e084d 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
@@ -19,18 +19,34 @@ 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 "items/item_viewversion.html.jinja" %}
+
{% block title %}
{{ _('web_ui.items.single_version.library.title') }}
{% endblock %}
+
{% block heading %}
{{
_('web_ui.items.single_version.library.heading.name_{}')
.format(display_info.info.long_name)
}}
{% endblock %}
+
+{% block item_required_msg %}
+ {{ _('web_ui.items.single_version.library.item_required') }}
+{% endblock %}
+
+{% block item_auto_activated_msg %}
+ {{ _('web_ui.items.single_version.library.item_auto_activated') }}
+{% endblock %}
+
+{% block item_not_activated_msg %}
+ {{ _('web_ui.items.single_version.library.item_not_activated') }}
+{% endblock %}
+
{% block item_install_failed_msg %}
{{ _('web_ui.items.single_version.library.install_failed') }}
{% endblock %}
+
{% block version_list_heading %}
{{ _('web_ui.items.single_version.library.version_list_heading') }}
{% endblock %}
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 6671747..a532b5f 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
@@ -19,18 +19,82 @@ 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 "items/item_viewversion.html.jinja" %}
+
{% block title %}
{{ _('web_ui.items.single_version.package.title') }}
{% endblock %}
+
{% block heading %}
{{
_('web_ui.items.single_version.package.heading.name_{}')
.format(display_info.info.long_name)
}}
{% endblock %}
+
+{% block item_required_msg %}
+ {{ _('web_ui.items.single_version.package.item_required') }}
+{% endblock %}
+
+{% block item_auto_activated_msg %}
+ {{ _('web_ui.items.single_version.package.item_auto_activated') }}
+{% endblock %}
+
+{% block item_not_activated_msg %}
+ {{ _('web_ui.items.single_version.package.item_not_activated') }}
+{% endblock %}
+
{% block item_install_failed_msg %}
{{ _('web_ui.items.single_version.package.install_failed') }}
{% endblock %}
+
{% block version_list_heading %}
{{ _('web_ui.items.single_version.package.version_list_heading') }}
{% endblock %}
+
+{% block main_info_bulk %}
+ TODO: add more info...
+
+ {% set enable_but_classes = ['blue-button', 'button-bordering-left'] %}
+ {%
+ set unenable_but_classes = [
+ 'green-button',
+ 'button-bordering-right',
+ 'button-bordering-left'
+ ]
+ %}
+ {% set disable_but_classes = ['red-button', 'button-bordering-right'] %}
+
+ {% 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 %}
+
+ {% if display_info.mapping_enabled == EnabledStatus.NO_MARK %}
+ {% do unenable_but_classes.append('disabled-button') %}
+ {% elif display_info.mapping_enabled == EnabledStatus.DISABLED %}
+ {% do disable_but_classes.append('disabled-button') %}
+ {% else %}
+ {% if display_info.active == ActiveStatus.REQUIRED %}
+ {% do enable_but_classes.append('disabled-button') %}
+ {% else %}
+ <div> {{ _('web_ui.items.single_version.other_version_enabled') }} </div>
+ {% endif %}
+ {% endif %}
+
+ {{
+ button_row([
+ (disable_but_classes, disable_text, 'disable_item'),
+ (unenable_but_classes, unenable_text, 'unenable_item'),
+ (enable_but_classes, enable_text, 'enable_item_version')
+ ])
+ }}
+{% endblock main_info_bulk %}