diff options
Diffstat (limited to 'CLAUDE.md')
| -rw-r--r-- | CLAUDE.md | 73 |
1 files changed, 73 insertions, 0 deletions
diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..952aac6 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,73 @@ +# CLAUDE.md + +This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. + +## What This Is + +PyQt6 desktop GUI for Linux that centralizes the danix.xyz Hugo blog publishing workflow. Centralizes: article management, translations (IT↔EN via RunPod), git operations, hugo server, media uploads, and taxonomy management. + +Blog repo: `/home/danix/Programming/GIT/danix.xyz-hacker-theme` +Translation script: `/home/danix/bin/transart.py` (TranslateGemma 27b on RunPod) +Config file: `~/.config/my-publisher/config.toml` + +## Commands + +```bash +# Run app +python main.py + +# Run all tests +pytest tests/ -v + +# Run single test file +pytest tests/test_config.py -v + +# Run single test +pytest tests/test_config.py::test_config_round_trips -v + +# Install deps +pip install -r requirements.txt +``` + +## Architecture + +Single Python process. Three layers: + +**`core/`** — UI-agnostic business logic: +- `config.py` — load/save `~/.config/my-publisher/config.toml` via tomlkit +- `models.py` — `Article` dataclass + `ARTICLE_TYPES = ["Life", "Photo", "Link", "Quote", "Tech"]` +- `article_scanner.py` — scans `content/it/` and `content/en/`, builds `list[Article]`, detects translation pairs by matching slugs across languages +- `frontmatter.py` — parse/write Hugo TOML frontmatter (delimited by `+++`, not YAML `---`) +- `taxonomy.py` — load/save `docs/tags-it.txt` + `docs/tags-en.txt` (line-aligned pairs) + +**`workers/`** — async operations via Qt signals: +- `git_worker.py` — `QThread` for pull, push master/production, `git rm`, restore deleted +- `hugo_worker.py` — `QProcess` for `hugo server -D`, streams stdout line by line +- `translation_worker.py` — `QProcess` for `transart.py`, streams stdout for progress display + +Workers emit `output(str)`, `error(str)`, `finished(bool)` signals. UI connects to these — never blocks the main thread. + +**`ui/`** — PyQt6 widgets: +- `main_window.py` — `QMainWindow` with sidebar + `QStackedWidget`. Sidebar has groups: CONTENUTO / WORKFLOW / DEPLOY. Uses `QFileSystemWatcher` on `content/it/` and `content/en/` to auto-refresh on external changes (e.g. Typora edits). +- Each sidebar section maps to a widget in the stack. + +## Key Conventions + +**Hugo frontmatter is TOML, not YAML.** Delimited by `+++`. Always use `tomlkit` (not `tomllib`) to preserve key ordering and comments when writing back. + +**Translation pairs are matched by slug.** An IT article at `content/it/articles/my-post/index.md` and EN at `content/en/articles/my-post/index.md` share slug `my-post`. `article_scanner.py` builds the pairing. + +**Git branches:** `master` = staging (hugo server testing), `production` = live deploy (post-receive hook on server). + +**Media path convention:** Files upload to `static/uppies/YYYY/MM/filename`. Web path served as `/uppies/YYYY/MM/filename`. + +**Tests are UI-free.** `core/` and `workers/` are tested with pytest + tmp_path fixtures. Qt UI components are not unit-tested — verify manually by running the app. + +**Config path override in tests:** Pass `path` explicitly to `Config.load(path)` / `Config.save(path)` rather than monkeypatching the module-level constant. + +## Spec and Plan + +Full design spec: `docs/superpowers/specs/2026-05-01-my-publisher-design.md` +Implementation plan (20 tasks): `docs/superpowers/plans/2026-05-01-my-publisher.md` + +Implementation is in progress — tasks 1–4 complete (scaffold, config, models, frontmatter parser). Tasks 5–20 pending. |
