diff options
author | Wojtek Kosior <koszko@koszko.org> | 2022-08-18 13:40:16 +0200 |
---|---|---|
committer | Wojtek Kosior <koszko@koszko.org> | 2022-09-28 12:54:22 +0200 |
commit | 2579081df2a568192887d776a6965af323b7c4ee (patch) | |
tree | 12491e0ee11568a09891f4d261e9cba60e8a8d52 /src/hydrilla/proxy/state_impl | |
parent | c242a5833d41fdcee6e2b35cff7af8d445b44946 (diff) | |
download | haketilo-hydrilla-2579081df2a568192887d776a6965af323b7c4ee.tar.gz haketilo-hydrilla-2579081df2a568192887d776a6965af323b7c4ee.zip |
make it possible to list all repositories in the web UI
Diffstat (limited to 'src/hydrilla/proxy/state_impl')
-rw-r--r-- | src/hydrilla/proxy/state_impl/concrete_state.py | 22 | ||||
-rw-r--r-- | src/hydrilla/proxy/state_impl/mappings.py | 2 | ||||
-rw-r--r-- | src/hydrilla/proxy/state_impl/repos.py | 151 |
3 files changed, 155 insertions, 20 deletions
diff --git a/src/hydrilla/proxy/state_impl/concrete_state.py b/src/hydrilla/proxy/state_impl/concrete_state.py index b2b1033..46e7827 100644 --- a/src/hydrilla/proxy/state_impl/concrete_state.py +++ b/src/hydrilla/proxy/state_impl/concrete_state.py @@ -52,28 +52,12 @@ from .. import state as st from .. import policies from . import base from . import mappings +from . import repos from .load_packages import load_packages here = Path(__file__).resolve().parent -@dc.dataclass(frozen=True, unsafe_hash=True) # type: ignore[misc] -class ConcreteRepoRef(st.RepoRef): - def remove(self, state: st.HaketiloState) -> None: - raise NotImplementedError() - - def update( - self, - state: st.HaketiloState, - *, - name: t.Optional[str] = None, - url: t.Optional[str] = None - ) -> ConcreteRepoRef: - raise NotImplementedError() - - def refresh(self, state: st.HaketiloState) -> ConcreteRepoIterationRef: - raise NotImplementedError() - @dc.dataclass(frozen=True, unsafe_hash=True) class ConcreteRepoIterationRef(st.RepoIterationRef): @@ -440,8 +424,8 @@ class ConcreteHaketiloState(base.HaketiloStateWithFields): self.policy_tree = new_policy_tree self.payloads_data = new_payloads_data - def get_repo(self, repo_id: str) -> st.RepoRef: - return ConcreteRepoRef(repo_id) + def repo_store(self) -> st.RepoStore: + return repos.ConcreteRepoStore(self) def get_repo_iteration(self, repo_iteration_id: str) -> st.RepoIterationRef: return ConcreteRepoIterationRef(repo_iteration_id) diff --git a/src/hydrilla/proxy/state_impl/mappings.py b/src/hydrilla/proxy/state_impl/mappings.py index 5e31814..3668784 100644 --- a/src/hydrilla/proxy/state_impl/mappings.py +++ b/src/hydrilla/proxy/state_impl/mappings.py @@ -130,4 +130,4 @@ class ConcreteMappingVersionStore(st.MappingVersionStore): info = st.MappingDisplayInfo(ref, item_info, status, is_orphan) result.append(info) - return result + return sorted(result, key=(lambda di: di.info)) diff --git a/src/hydrilla/proxy/state_impl/repos.py b/src/hydrilla/proxy/state_impl/repos.py new file mode 100644 index 0000000..be11a88 --- /dev/null +++ b/src/hydrilla/proxy/state_impl/repos.py @@ -0,0 +1,151 @@ +# SPDX-License-Identifier: GPL-3.0-or-later + +# Haketilo proxy data and configuration (RepoRef and RepoStore subtypes). +# +# This file is part of Hydrilla&Haketilo. +# +# Copyright (C) 2022 Wojtek Kosior +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <https://www.gnu.org/licenses/>. +# +# +# I, Wojtek Kosior, thereby promise not to sue for violation of this +# file's license. Although I request that you do not make use this code +# in a proprietary program, I am not going to enforce this in court. + +""" +This module provides an interface to interact with repositories configured +inside Haketilo. +""" + +# Enable using with Python 3.7. +from __future__ import annotations + +import typing as t +import dataclasses as dc + +from datetime import datetime + +from .. import state as st +from . import base + +def make_repo_display_info( + ref: st.RepoRef, + name: str, + url: t.Optional[str], + deleted: t.Optional[bool], + last_refreshed: t.Optional[int], + resource_count: int, + mapping_count: int +) -> st.RepoDisplayInfo: + last_refreshed_converted: t.Optional[datetime] = None + if last_refreshed is not None: + last_refreshed_converted = datetime.fromtimestamp(last_refreshed) + + return st.RepoDisplayInfo( + ref = ref, + name = name, + url = url, + deleted = deleted, + last_refreshed = last_refreshed_converted, + resource_count = resource_count, + mapping_count = mapping_count + ) + + +@dc.dataclass(frozen=True, unsafe_hash=True) +class ConcreteRepoRef(st.RepoRef): + """....""" + state: base.HaketiloStateWithFields = dc.field(hash=False, compare=False) + + def remove(self) -> None: + raise NotImplementedError() + + def update( + self, + *, + name: t.Optional[str] = None, + url: t.Optional[str] = None + ) -> st.RepoRef: + raise NotImplementedError() + + def refresh(self) -> st.RepoIterationRef: + raise NotImplementedError() + + def get_display_info(self) -> st.RepoDisplayInfo: + with self.state.cursor() as cursor: + cursor.execute( + ''' + SELECT + name, url, deleted, last_refreshed, + resource_count, mapping_count + FROM + repo_display_infos + WHERE + repo_id = ?; + ''', + (self.id,) + ) + + rows = cursor.fetchall() + + if rows == []: + raise st.MissingItemError() + + row, = rows + + return make_repo_display_info(self, *row) + + +@dc.dataclass(frozen=True) +class ConcreteRepoStore(st.RepoStore): + state: base.HaketiloStateWithFields + + def get(self, id: str) -> st.RepoRef: + return ConcreteRepoRef(id, self.state) + + def get_display_infos(self, include_deleted: bool = False) \ + -> t.Iterable[st.RepoDisplayInfo]: + with self.state.cursor() as cursor: + condition: str = 'TRUE' + if include_deleted: + condition = 'COALESCE(deleted = FALSE, TRUE)' + + cursor.execute( + f''' + SELECT + repo_id, name, url, deleted, last_refreshed, + resource_count, mapping_count + FROM + repo_display_infos + WHERE + {condition} + ORDER BY + repo_id != 1, name; + ''' + ) + + all_rows = cursor.fetchall() + + assert len(all_rows) > 0 and all_rows[0][0] == 1 + + result = [] + for row in all_rows: + repo_id, *rest = row + + ref = ConcreteRepoRef(str(repo_id), self.state) + + result.append(make_repo_display_info(ref, *rest)) + + return result |