Add publisher to PDF and CBR/CBZ storage paths

All formats now use {publisher}/{author} consistently:
- pdf/{publisher}/{author}/{title}.pdf
- comics/{publisher}/{author}/{title}.cbr|cbz
Previously PDF and comics only had {author}, unlike EPUB.
Updated TECHNICAL.md path table accordingly.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Ivo Oskamp 2026-03-25 08:56:53 +01:00
parent f3f9d45d2b
commit 39eef0a388
4 changed files with 14 additions and 7 deletions

View File

@ -70,15 +70,17 @@ def make_rel_path(*, media_type: str, publisher: str, author: str, title: str, s
return Path("epub") / pub / auth / "Stories" / f"{ttl}.epub" return Path("epub") / pub / auth / "Stories" / f"{ttl}.epub"
if media_type == "pdf": if media_type == "pdf":
pub = clean_segment(publisher, "Unknown Publisher", 80)
auth = clean_segment(author, "Unknown Author", 80) auth = clean_segment(author, "Unknown Author", 80)
ttl = clean_segment(title, "Untitled", 140) ttl = clean_segment(title, "Untitled", 140)
return Path("pdf") / auth / f"{ttl}.pdf" return Path("pdf") / pub / auth / f"{ttl}.pdf"
# CBR / CBZ — preserve the original extension; default to .cbr # CBR / CBZ — preserve the original extension; default to .cbr
comics_ext = ext if ext in {".cbr", ".cbz"} else ".cbr" comics_ext = ext if ext in {".cbr", ".cbz"} else ".cbr"
pub = clean_segment(publisher, "Unknown Publisher", 80)
auth = clean_segment(author, "Unknown", 80) auth = clean_segment(author, "Unknown", 80)
ttl = clean_segment(title, "Untitled", 140) ttl = clean_segment(title, "Untitled", 140)
return Path("comics") / auth / f"{ttl}{comics_ext}" return Path("comics") / pub / auth / f"{ttl}{comics_ext}"
def ensure_unique_rel_path(rel_path: Path) -> Path: def ensure_unique_rel_path(rel_path: Path) -> Path:

View File

@ -417,10 +417,12 @@ def _make_rel_path(
return Path("epub") / pub / auth / "Stories" / f"{ttl}.epub" return Path("epub") / pub / auth / "Stories" / f"{ttl}.epub"
if ext == ".pdf": if ext == ".pdf":
return Path("pdf") / auth / f"{ttl}.pdf" pub = _clean_segment(publisher, "Unknown Publisher", 80)
return Path("pdf") / pub / auth / f"{ttl}.pdf"
# .cbr / .cbz # .cbr / .cbz
return Path("comics") / auth / f"{ttl}{ext}" pub = _clean_segment(publisher, "Unknown Publisher", 80)
return Path("comics") / pub / auth / f"{ttl}{ext}"
def _ensure_unique_rel_path(rel_path: Path, *, exclude: Path | None = None) -> Path: def _ensure_unique_rel_path(rel_path: Path, *, exclude: Path | None = None) -> Path:

View File

@ -27,9 +27,9 @@ All files are stored under `library/` (relative to the app working directory, ma
|--------|-------------| |--------|-------------|
| EPUB (no series) | `library/epub/{publisher}/{author}/Stories/{title}.epub` | | EPUB (no series) | `library/epub/{publisher}/{author}/Stories/{title}.epub` |
| EPUB (series) | `library/epub/{publisher}/{author}/Series/{series}/{idx:03d} - {title}.epub` | | EPUB (series) | `library/epub/{publisher}/{author}/Series/{series}/{idx:03d} - {title}.epub` |
| PDF | `library/pdf/{author}/{title}.pdf` | | PDF | `library/pdf/{publisher}/{author}/{title}.pdf` |
| CBR | `library/comics/{author}/{title}.cbr` | | CBR | `library/comics/{publisher}/{author}/{title}.cbr` |
| CBZ | `library/comics/{author}/{title}.cbz` | | CBZ | `library/comics/{publisher}/{author}/{title}.cbz` |
- Segments are sanitised: special chars stripped, max lengths applied (publisher/author 80, title 140, series 80). - Segments are sanitised: special chars stripped, max lengths applied (publisher/author 80, title 140, series 80).
- Series index is zero-padded to 3 digits (`001`, `002`, …), clamped to 1999. - Series index is zero-padded to 3 digits (`001`, `002`, …), clamped to 1999.

View File

@ -46,6 +46,9 @@ This file tracks changes on the `develop` line.
- Updated Docker image with `postgresql-client` for `pg_dump`. - Updated Docker image with `postgresql-client` for `pg_dump`.
- Multiple test builds pushed to `gitea.oskamp.info/ivooskamp/novela:dev`. - Multiple test builds pushed to `gitea.oskamp.info/ivooskamp/novela:dev`.
## 2026-03-25 (4)
- Added {publisher} directory to PDF and CBR/CBZ paths: `pdf/{publisher}/{author}/{title}.pdf`, `comics/{publisher}/{author}/{title}.cbr/cbz` — consistent with EPUB structure
## 2026-03-25 (3) ## 2026-03-25 (3)
- Fixed CBZ extension in import: `common.make_rel_path` always generated `.cbr` for CBZ files; now accepts `ext` parameter; `library.py` passes actual suffix so CBZ files land at `comics/{author}/{title}.cbz` - Fixed CBZ extension in import: `common.make_rel_path` always generated `.cbr` for CBZ files; now accepts `ext` parameter; `library.py` passes actual suffix so CBZ files land at `comics/{author}/{title}.cbz`
- Added missing `GET /download/{filename}` endpoint (referenced in book.html but was 404) - Added missing `GET /download/{filename}` endpoint (referenced in book.html but was 404)