From e255c2f353ad16d3ed0460dabe84a11b119902da Mon Sep 17 00:00:00 2001 From: Wojtek Kosior Date: Tue, 23 Aug 2022 13:34:30 +0200 Subject: make it possible to change repo's name and URL using web UI --- src/hydrilla/proxy/state_impl/repos.py | 72 +++++++++++++++++++++++----------- 1 file changed, 50 insertions(+), 22 deletions(-) (limited to 'src/hydrilla/proxy/state_impl') diff --git a/src/hydrilla/proxy/state_impl/repos.py b/src/hydrilla/proxy/state_impl/repos.py index ae3b70c..2670ae9 100644 --- a/src/hydrilla/proxy/state_impl/repos.py +++ b/src/hydrilla/proxy/state_impl/repos.py @@ -54,6 +54,28 @@ from . import base from . import _operations +repo_name_regex = re.compile(r''' +^ +(?: + []a-zA-Z0-9()<>^&$.!,?@#|;:%"'*{}[/_=+-]+ # allowed non-whitespace characters + + (?: # optional additional words separated by single spaces + [ ] + []a-zA-Z0-9()<>^&$.!,?@#|;:%"'*{}[/_=+-]+ + )* +) +$ +''', re.VERBOSE) + +def sanitize_repo_name(name: str) -> str: + name = name.strip() + + if repo_name_regex.match(name) is None: + raise st.RepoNameInvalid() + + return name + + def sanitize_repo_url(url: str) -> str: try: parsed = urlparse(url) @@ -220,20 +242,39 @@ class ConcreteRepoRef(st.RepoRef): url: t.Optional[str] = None ) -> None: if name is not None: - raise NotImplementedError() + if name.isspace(): + raise st.RepoNameInvalid() - if url is None: - return + name = sanitize_repo_name(name) - url = sanitize_repo_url(url) + if url is not None: + if url.isspace(): + raise st.RepoUrlInvalid() + + url = sanitize_repo_url(url) + + if name is None and url is None: + return with self.state.cursor(transaction=True) as cursor: ensure_repo_not_deleted(cursor, self.id) - cursor.execute( - 'UPDATE repos SET url = ? WHERE repo_id = ?;', - (url, self.id) - ) + if url is not None: + cursor.execute( + 'UPDATE repos SET url = ? WHERE repo_id = ?;', + (url, self.id) + ) + + if name is not None: + try: + cursor.execute( + 'UPDATE repos SET name = ? WHERE repo_id = ?;', + (name, self.id) + ) + except sqlite3.IntegrityError: + raise st.RepoNameTaken() + + self.state.recompute_dependencies() def refresh(self) -> st.RepoIterationRef: with self.state.cursor(transaction=True) as cursor: @@ -256,7 +297,7 @@ class ConcreteRepoRef(st.RepoRef): RemoteFileResolver(repo_url) ) - self.state.recompute_dependencies() + self.state.rebuild_structures() cursor.execute( ''' @@ -297,19 +338,6 @@ class ConcreteRepoRef(st.RepoRef): return make_repo_display_info(self, *row) -repo_name_regex = re.compile(r''' -^ -(?: - []a-zA-Z0-9()<>^&$.!,?@#|;:%"'*{}[/_=+-]+ # allowed non-whitespace characters - - (?: # optional additional words separated by single spaces - [ ] - []a-zA-Z0-9()<>^&$.!,?@#|;:%"'*{}[/_=+-]+ - )* -) -$ -''', re.VERBOSE) - @dc.dataclass(frozen=True) class ConcreteRepoStore(st.RepoStore): state: base.HaketiloStateWithFields -- cgit v1.2.3