From: Danilo M. Date: Sun, 3 May 2026 14:20:39 +0000 (+0200) Subject: chore: update HANDOFF, TODO, and desktop entry for v1.3 X-Git-Tag: v1.3 X-Git-Url: https://git.danix.xyz/?a=commitdiff_plain;h=refs%2Fheads%2Fmaster;p=publisher.git chore: update HANDOFF, TODO, and desktop entry for v1.3 Mark tag autocomplete and rename propagation as complete in TODO. Update desktop entry Exec path and Icon to match installed location. Co-Authored-By: Claude Sonnet 4.6 --- diff --git a/HANDOFF.md b/HANDOFF.md index 1009af9..4cc7339 100644 --- a/HANDOFF.md +++ b/HANDOFF.md @@ -1,17 +1,14 @@ Who this is for: - Danilo is a developer and blogger running a bilingual (IT/EN) Hugo site at danix.xyz. He maintains a PyQt6 desktop app called my-publisher that centralizes his blog publishing workflow, and is currently extending it post-v1.0 launch. + Danilo is a developer and blogger running a bilingual (IT/EN) Hugo site at danix.xyz. He maintains a PyQt6 desktop app called my-publisher that centralizes his blog publishing workflow, and is continuing to extend it post-v1.2. What we covered: - Two features were implemented this session. First, draft article visual hints: added a draft property to the Article dataclass, amber [DRAFT] prefix in article list items, and a DRAFT badge in the article detail header. Second, article list metadata display: added four properties to Article (meta_type, meta_tags, meta_categories, meta_date), then updated the article list to show a two-line row per article with slug+badge on line 1 and type/date/tags/categories on line 2. The two-line rendering required three iterations to fix: setWordWrap failed, setTextElideMode failed, and the final working solution was a custom QStyledItemDelegate that draws both lines directly onto the canvas bypassing Qt elision entirely. The app was tagged v1.1 and pushed to origin. + Three changes were implemented this session. First, multi-token tag autocomplete was added to FrontmatterEditor: a MultiTokenCompleter subclass of QCompleter intercepts textEdited, extracts the last comma-separated token as the completion prefix, and on activation inserts the completed tag followed by ", " so the user can immediately type the next tag. Does not call setCompleter() — wires via setWidget() + signals to bypass Qt's built-in prefix detection. Second, tag rename propagation was added to TaxonomyView: _save() now snapshots the old it_to_en dict before modifying, calls _detect_renames() (static method, compares old vs new dicts to find IT and EN renames), then _propagate_renames() scans all articles via scan_articles() and rewrites frontmatter for any article whose tags include a renamed value. Status bar shows count of updated articles. Propagation only runs after save_taxonomy() succeeds. Third, a pre-existing bug was fixed in FrontmatterEditor._save(): it was passing empty string as body to write_frontmatter(), erasing all article content below the +++ delimiter. Fixed by reading body via parse_frontmatter() first. What was confirmed: - All 30 tests pass. The delegate approach (ArticleItemDelegate in ui/articles_view.py) is the correct solution for multi-line QListWidget items in PyQt6. Line 2 metadata is stored in Qt.ItemDataRole.UserRole+1 and drawn in dimmed #888 color. Draft items show amber #f59e0b. - Missing-translation items show red #ff6b6b. The blog's TOML frontmatter uses lowercase keys: type, date, tags, categories. Tag v1.1 is pushed to danix_git:publisher. + All 34 tests pass. pytest-qt added to requirements.txt for the _detect_renames unit tests. The body-erasure bug was pre-existing since v1.0 — any article saved through FrontmatterEditor before this fix lost its content. MultiTokenCompleter does not call widget.setCompleter() because that re-enables Qt's built-in single-token prefix logic. Tag rename propagation is transactional: taxonomy save failure aborts propagation entirely. v1.3 tagged and pushed. Still in progress: - Nothing was left open in this session. The remaining TODO items from TODO.md are: TaxonomyView Categories tab, MissingTranslationView Traduci button, font size spinner in SetupDialog, multi-token tag autocomplete in FrontmatterEditor, transart backend availability validation, - taxonomy tag rename propagation to articles, and Ctrl+Q keyboard shortcut. + Nothing was left open in this session. Remaining TODO items are: font size spinner in SetupDialog, and transart backend availability validation using OLLAMA_HOST. Next steps: - Pick the next TODO item to implement. Suggested order by impact: (1) Ctrl+Q keyboard shortcut — trivial, one line in main_window.py; (2) font size spinner in SetupDialog (ui/setup_dialog.py) — moderate, saves via Config.save() and re-applies with app.setFont(); (3) transart backend - availability check using OLLAMA_HOST; (4) MissingTranslationView Traduci button — wire translate_requested signal per row; (5) TaxonomyView Categories tab; (6) taxonomy tag rename propagation; (7) multi-token tag autocomplete in ui/frontmatter_editor.py. \ No newline at end of file + Two TODO items remain. Suggested order: (1) font size spinner in SetupDialog (ui/setup_dialog.py) — add QSpinBox, save via Config.save(), re-apply with app.setFont(); (2) transart backend availability check using OLLAMA_HOST — validate before translation starts or disable the translate button with a popup reminder to activate RunPod. diff --git a/TODO.md b/TODO.md index c9ce125..b3590da 100644 --- a/TODO.md +++ b/TODO.md @@ -4,9 +4,9 @@ Known gaps from initial implementation. Functional for daily use — these are e ## UI Gaps -- [ ] **TaxonomyView: Categories tab** — Tags tab exists, Categories tab missing. Mirror the Tags tab structure (IT/EN pair table, orphan detection) for `categories` frontmatter key. Files: `ui/taxonomy_view.py`, `core/taxonomy.py`. +- [✅] **TaxonomyView: Categories tab** — Tags tab exists, Categories tab missing. Mirror the Tags tab structure (IT/EN pair table, orphan detection) for `categories` frontmatter key. Files: `ui/taxonomy_view.py`, `core/taxonomy.py`. -- [ ] **MissingTranslationView: Traduci button** — `translate_requested(str)` signal declared but no button wired to it. Add a per-row "Traduci" button that emits the signal with the article slug, then handle it in `main_window.py` to open the translation view for that article. +- [✅] **MissingTranslationView: Traduci button** — `translate_requested(str)` signal declared but no button wired to it. Add a per-row "Traduci" button that emits the signal with the article slug, then handle it in `main_window.py` to open the translation view for that article. ## Settings @@ -14,7 +14,7 @@ Known gaps from initial implementation. Functional for daily use — these are e ## Autocomplete -- [ ] **FrontmatterEditor: multi-token tag autocomplete** — `QCompleter` only completes the first token in the tags field. Need a custom completer that splits on commas, completes the current token, and re-joins. Consider subclassing `QCompleter` or intercepting `textEdited` to extract the active token. File: `ui/frontmatter_editor.py`. +- [✅] **FrontmatterEditor: multi-token tag autocomplete** — `QCompleter` only completes the first token in the tags field. Need a custom completer that splits on commas, completes the current token, and re-joins. Consider subclassing `QCompleter` or intercepting `textEdited` to extract the active token. File: `ui/frontmatter_editor.py`. ## Drafts @@ -27,7 +27,7 @@ Known gaps from initial implementation. Functional for daily use — these are e ## Interface - [✅] The main articles list should display the type, tags, categories and date fields for each article in both languages. -- [ ] When modifying tags in the taxonomy view, they should be updated in the relevant articles. EG modified the english "regionale" tag to "regional", after saving it, the program should find all english articles with the old "regionale" tag and modify them to the new "regional". +- [✅] When modifying tags in the taxonomy view, they should be updated in the relevant articles. EG modified the english "regionale" tag to "regional", after saving it, the program should find all english articles with the old "regionale" tag and modify them to the new "regional". ## keyboard shortcuts -- [ ] The app should follow some standard keyboard shortcuts like Ctrl+q should quit the app. \ No newline at end of file +- [✅] The app should follow some standard keyboard shortcuts like Ctrl+q should quit the app. \ No newline at end of file diff --git a/assets/my-publisher.desktop b/assets/my-publisher.desktop index 7207323..2a5b5be 100644 --- a/assets/my-publisher.desktop +++ b/assets/my-publisher.desktop @@ -3,8 +3,8 @@ Version=1.0 Type=Application Name=my-publisher Comment=danix.xyz blog publishing workflow -Exec=python /opt/my-publisher/main.py -Icon=/opt/my-publisher/assets/blogilo.svg +Exec=python /opt/publisher/main.py +Icon=blogilo Terminal=false Categories=Office;Publishing; StartupWMClass=my-publisher