summaryrefslogtreecommitdiffstats
path: root/ui/taxonomy_view.py
diff options
context:
space:
mode:
authorDanilo M. <danix@danix.xyz>2026-05-03 16:09:38 +0200
committerDanilo M. <danix@danix.xyz>2026-05-03 16:09:38 +0200
commit2319a6bf3c32407d387c45a522f20e23b7ba885f (patch)
tree8d7186e5487ff2c01b5069a3f4630dce2c7d1b3a /ui/taxonomy_view.py
parent365b911ba1288ccfb428602ba765750ad9d0a139 (diff)
downloadpublisher-2319a6bf3c32407d387c45a522f20e23b7ba885f.tar.gz
publisher-2319a6bf3c32407d387c45a522f20e23b7ba885f.zip
feat: propagate tag renames to articles after taxonomy save
After saving TaxonomyView, detect renamed IT/EN tags by comparing old and new it_to_en dicts, then rewrite frontmatter of affected articles. Status bar shows count of updated articles. Taxonomy save failure aborts propagation. Adds pytest-qt and four unit tests for _detect_renames. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Diffstat (limited to 'ui/taxonomy_view.py')
-rw-r--r--ui/taxonomy_view.py55
1 files changed, 53 insertions, 2 deletions
diff --git a/ui/taxonomy_view.py b/ui/taxonomy_view.py
index 6efbffd..4862833 100644
--- a/ui/taxonomy_view.py
+++ b/ui/taxonomy_view.py
@@ -9,6 +9,7 @@ from PyQt6.QtCore import Qt
from PyQt6.QtGui import QColor
from core.taxonomy import TaxonomyModel, load_taxonomy, save_taxonomy, load_categories, save_categories
from core.article_scanner import scan_articles
+from core.frontmatter import parse_frontmatter, write_frontmatter
class AddTermDialog(QDialog):
def __init__(self, parent=None):
@@ -210,9 +211,50 @@ class TaxonomyView(QWidget):
save_categories(self._categories_path, self._categories)
self._status.setText("Categorie salvate.")
+ @staticmethod
+ def _detect_renames(
+ old: dict[str, str], new: dict[str, str]
+ ) -> tuple[dict[str, str], dict[str, str]]:
+ it_renames: dict[str, str] = {}
+ en_renames: dict[str, str] = {}
+ old_en_to_it = {v: k for k, v in old.items()}
+ for new_it, new_en in new.items():
+ if new_it not in old:
+ if new_en in old_en_to_it:
+ it_renames[old_en_to_it[new_en]] = new_it
+ else:
+ if old[new_it] != new_en:
+ en_renames[old[new_it]] = new_en
+ return it_renames, en_renames
+
+ def _propagate_renames(self, it_renames: dict[str, str], en_renames: dict[str, str]) -> int:
+ if not it_renames and not en_renames:
+ return 0
+ articles = scan_articles(self._blog_root)
+ count = 0
+ for article in articles:
+ renames = it_renames if article.lang == "it" else en_renames
+ if not renames:
+ continue
+ current_tags = article.frontmatter.get("tags", [])
+ if not isinstance(current_tags, list):
+ continue
+ new_tags = [renames.get(str(t), str(t)) for t in current_tags]
+ if new_tags == [str(t) for t in current_tags]:
+ continue
+ try:
+ fm, body = parse_frontmatter(article.path)
+ fm["tags"] = new_tags
+ write_frontmatter(article.path, fm, body)
+ count += 1
+ except Exception:
+ pass
+ return count
+
def _save(self):
if not self._model:
return
+ old_it_to_en = dict(self._model.it_to_en)
updated: dict[str, str] = {}
for row in range(self._tags_table.rowCount()):
it_item = self._tags_table.item(row, 0)
@@ -223,5 +265,14 @@ class TaxonomyView(QWidget):
if it_val and en_val and en_val != "⚠ mancante":
updated[it_val] = en_val
self._model.it_to_en = updated
- save_taxonomy(self._model, self._tags_it, self._tags_en)
- self._status.setText("Salvato.")
+ try:
+ save_taxonomy(self._model, self._tags_it, self._tags_en)
+ except OSError as e:
+ QMessageBox.critical(self, "Errore", f"Impossibile salvare: {e}")
+ return
+ it_renames, en_renames = self._detect_renames(old_it_to_en, updated)
+ count = self._propagate_renames(it_renames, en_renames)
+ if count:
+ self._status.setText(f"Salvato · {count} articol{'o' if count == 1 else 'i'} aggiornati.")
+ else:
+ self._status.setText("Salvato.")