From 8c9c2efeee7026206be89e4180b488498de30183 Mon Sep 17 00:00:00 2001 From: Samuel Olwe Date: Fri, 20 Jun 2025 10:40:16 +0300 Subject: [PATCH 1/5] feat: dont delete pages with jira tasks --- webapp/site_repository.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/webapp/site_repository.py b/webapp/site_repository.py index bb93f106..3354c750 100644 --- a/webapp/site_repository.py +++ b/webapp/site_repository.py @@ -362,7 +362,12 @@ def __remove_webpages_to_delete__(self, db, tree): for row in webpages_to_delete: page_to_delete = row[0] - if page_to_delete.name not in webpages: + # Delete pages which aren't in the tree, but don't delete pages + # which have associated Jira tasks + if ( + page_to_delete.name not in webpages + and len(page_to_delete.jira_tasks) == 0 + ): db.session.execute( delete(Webpage).where(Webpage.id == page_to_delete.id), ) From 4a98427371a2580cc313e4bf3852de22a3235f0c Mon Sep 17 00:00:00 2001 From: Samuel Olwe Date: Fri, 20 Jun 2025 17:09:22 +0300 Subject: [PATCH 2/5] feat: don't delete pages, sort from tree instead --- webapp/site_repository.py | 78 +++++++++++++++------------------------ 1 file changed, 30 insertions(+), 48 deletions(-) diff --git a/webapp/site_repository.py b/webapp/site_repository.py index 3354c750..973a84dc 100644 --- a/webapp/site_repository.py +++ b/webapp/site_repository.py @@ -8,7 +8,7 @@ from flask import Flask from flask_sqlalchemy import SQLAlchemy -from sqlalchemy import delete, select +from sqlalchemy import select from webapp.helper import ( convert_webpage_to_dict, @@ -245,31 +245,37 @@ def get_tree_from_db(self): """Get the tree from the database. If the tree is incomplete, reload from the repository. """ - webpages = ( - self.db.session.execute( - select(Webpage).where( - Webpage.project_id == get_project_id(self.repository_uri), - ), - ) - .scalars() - .all() - ) - # build tree from repository in case DB table is empty - # TODO: Revert this line to `if not webpages ...` - # before merging this PR - # This is only for QA - if True or not webpages or self._has_incomplete_pages(webpages): - tree = self.get_new_tree() - # otherwise, build tree from DB - else: - tree = get_tree_struct(db.session, webpages) - # If the tree is empty, load from the repository - if not tree.get("children") and not tree.get("parent_id"): - self.logger.info( - f"Reloading incomplete tree root {self.repository_uri}.", + if project_id := get_project_id(self.repository_uri): + webpages = ( + self.db.session.execute( + select(Webpage) + .where( + Webpage.project_id + == project_id + & (Webpage.status != WebpageStatus.TO_DELETE), + ) + .where(), ) + .scalars() + .all() + ) + # build tree from repository in case DB table is empty + if not webpages or self._has_incomplete_pages(webpages): tree = self.get_new_tree() - return tree + # otherwise, build tree from DB + else: + tree = get_tree_struct(db.session, webpages) + # If the tree is empty, load from the repository + if not tree or ( + tree.get("children") and not tree.get("parent_id") + ): + self.logger.info( + f"Reloading incomplete tree root {self.repository_uri}.", + ) + tree = self.get_new_tree() + return tree + # Raise an error if the project does not exist. + raise SiteRepositoryError("Invalid project_id. Unable to load tree.") def get_tree(self, no_cache: bool = False): """Get the tree from the cache or load a new tree to cache and db.""" @@ -351,27 +357,6 @@ def __create_webpages_for_children__( webpage_dict["id"], ) - def __remove_webpages_to_delete__(self, db, tree): - # convert tree of pages from repository to list - webpages = [] - self.add_pages_to_list(tree, webpages) - - webpages_to_delete = db.session.execute( - select(Webpage).where(Webpage.status == WebpageStatus.TO_DELETE), - ) - - for row in webpages_to_delete: - page_to_delete = row[0] - # Delete pages which aren't in the tree, but don't delete pages - # which have associated Jira tasks - if ( - page_to_delete.name not in webpages - and len(page_to_delete.jira_tasks) == 0 - ): - db.session.execute( - delete(Webpage).where(Webpage.id == page_to_delete.id), - ) - def create_webpages_for_tree(self, db: SQLAlchemy, tree: Tree): """Create webpages for each node in the tree.""" self.logger.info(f"Existing tree {tree}") @@ -401,9 +386,6 @@ def create_webpages_for_tree(self, db: SQLAlchemy, tree: Tree): webpage_dict["id"], ) - # Remove pages that don't exist in the repository anymore - self.__remove_webpages_to_delete__(db, tree) - self.logger.info(f"Existing dict {webpage_dict}") db.session.commit() From d88cc9718eb3fedd8d1b40f697c5569165ef5142 Mon Sep 17 00:00:00 2001 From: Samuel Olwe Date: Fri, 20 Jun 2025 18:26:31 +0300 Subject: [PATCH 3/5] chore: lint --- webapp/site_repository.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/webapp/site_repository.py b/webapp/site_repository.py index 973a84dc..43050208 100644 --- a/webapp/site_repository.py +++ b/webapp/site_repository.py @@ -269,8 +269,12 @@ def get_tree_from_db(self): if not tree or ( tree.get("children") and not tree.get("parent_id") ): + msg = ( + "Reloading incomplete tree root " + f"{self.repository_uri}." + ) self.logger.info( - f"Reloading incomplete tree root {self.repository_uri}.", + msg, ) tree = self.get_new_tree() return tree From c9b422c825fc04e2d9a635b5e74243b6673346fc Mon Sep 17 00:00:00 2001 From: Samuel Olwe Date: Tue, 24 Jun 2025 10:39:00 +0300 Subject: [PATCH 4/5] feat: removed redundant clause --- webapp/site_repository.py | 1 - 1 file changed, 1 deletion(-) diff --git a/webapp/site_repository.py b/webapp/site_repository.py index 43050208..ed10b9bd 100644 --- a/webapp/site_repository.py +++ b/webapp/site_repository.py @@ -254,7 +254,6 @@ def get_tree_from_db(self): == project_id & (Webpage.status != WebpageStatus.TO_DELETE), ) - .where(), ) .scalars() .all() From 0f897c98186d287c9d58ffc9c4f61c407de95e2c Mon Sep 17 00:00:00 2001 From: Samuel Olwe Date: Tue, 24 Jun 2025 11:14:11 +0300 Subject: [PATCH 5/5] feat: separated clauses --- webapp/helper.py | 11 +++++++++++ webapp/site_repository.py | 9 ++++----- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/webapp/helper.py b/webapp/helper.py index 8544dc17..c5160228 100644 --- a/webapp/helper.py +++ b/webapp/helper.py @@ -85,6 +85,17 @@ def get_project_id(project_name): return project.id if project else None +def get_or_create_project_id(project_name): + project = Project.query.filter_by(name=project_name).first() + if not project: + project, _ = get_or_create( + db.session, + Project, + name=project_name, + ) + return project.id if project else None + + def get_webpage_id(name, project_id): webpage = Webpage.query.filter_by(name=name, project_id=project_id).first() return webpage.id if webpage else None diff --git a/webapp/site_repository.py b/webapp/site_repository.py index ed10b9bd..7b9ff60a 100644 --- a/webapp/site_repository.py +++ b/webapp/site_repository.py @@ -12,7 +12,7 @@ from webapp.helper import ( convert_webpage_to_dict, - get_project_id, + get_or_create_project_id, get_tree_struct, ) from webapp.models import ( @@ -245,15 +245,14 @@ def get_tree_from_db(self): """Get the tree from the database. If the tree is incomplete, reload from the repository. """ - if project_id := get_project_id(self.repository_uri): + if project_id := get_or_create_project_id(self.repository_uri): webpages = ( self.db.session.execute( select(Webpage) .where( - Webpage.project_id - == project_id - & (Webpage.status != WebpageStatus.TO_DELETE), + Webpage.project_id == project_id, ) + .where(Webpage.status != WebpageStatus.TO_DELETE), ) .scalars() .all()