14 KiB
14 KiB
Develop Changelog
This file tracks changes on the develop line.
changelog.md can later be used for release summaries.
2026-03-25 (20)
- Added Rated section to library sidebar: shows all non-archived books with
rating > 0, sorted by rating descending then title alphabetically; badge displays total count; navigable via#ratedURL hash
2026-03-25 (19)
- Fixed series index 0 not displaying in series slot view, grid cards, list volume column, and book detail:
- Series slot labels now show
#0for all slots when the series has at least one positively-indexed sibling (consistent label height across all cards) - Grid card and list volume column use the same cross-book heuristic (
indexedSeriesSet) to show[0]where appropriate - Book detail page queries whether any sibling in the same series has
series_index > 0(series_is_indexed) and shows[0]accordingly
- Series slot labels now show
2026-03-25 (18)
- Added autocomplete for Author, Publisher, and Series in the book edit panel: typing shows a filtered dropdown of existing values from the library; selecting a value fills the field (same dropdown styling as genres/tags)
- Status field now defaults to "Complete" when opening the edit panel for a book that has no status set yet
2026-03-25 (17)
- Fixed CBR reader showing only first page:
cbr_page_countwas missing from thecbrimport inreader.py;/api/cbr/info/was returning an error, causingpage_countto fall back to 1 and the Next button to remain disabled
2026-03-25 (16)
- Fixed CBR/CBZ reader stuck on loading: added
/api/cbr/info/{filename}endpoint returning{page_count}, and added a CBR/CBZ branch inreader.htmlthat mirrors the PDF paged reader (page images served via/library/cbr/{filename}/{page})
2026-03-25 (15)
- Added series volume 0 and letter suffix support (e.g. "21a", "21b"):
- New
series_suffix VARCHAR(10)column added tolibrarytable viamigrate_series_suffix series_indexlower bound changed from 1 to 0 throughout (index 0 = special/prequel edition)- Volume field in the book editor changed from
type="number"totype="text"— accepts "0", "1", "21a", etc. - Server parses the combined volume string into
series_index(INTEGER) +series_suffix(VARCHAR) viaparse_volume_str - File naming includes suffix:
021a - Title.epub novela:series_suffixmeta tag written to/read from EPUB OPF for persistence across rescans- Series detail view: books sorted by
(series_index, series_suffix); slot labels show "21a"; index 0 shown as slot when any sibling has index > 0 - Grid cards, list view Volume column, author/publisher sort all include suffix
- New
2026-03-25 (14)
- Added multi-select and bulk delete to
All booksList view:- Checkbox column added to the list table (List mode only; Grid mode unchanged)
- Select all / Clear all / Clear selection controls in the controls bar
Shift+clickrange selection on checkboxesDelete selectedbutton (red, disabled when nothing is selected) triggers a confirmation dialog; confirmed deletions remove files from disk and database, then reload the library
2026-03-25 (13)
- Fixed EPUB cover replacement reverting to original after upload:
GET /library/cover/{filename}for EPUBs now checks the DB cover cache first (populated on upload) before falling back to extracting from the EPUB file; the cache is also warmed on cache-miss so subsequent requests are fast.add_cover_to_epubfully rewritten: locates the OPF viaMETA-INF/container.xml, finds the existing cover image in the OPF manifest, removes it from the ZIP, and writes the new cover in the same directory — works for any EPUB directory structure (OEBPS/,EPUB/, etc.).
2026-03-25 (12)
- Fixed chapter images not loading in EPUBs that use a non-standard root directory (e.g.
EPUB/instead ofOEBPS/): image paths are now passed as full ZIP paths instead of stripping the root segment, and the image endpoint no longer hardcodes anOEBPS/prefix. Case-insensitive fallback retained for EPUBs with mismatched image folder casing.
2026-03-25 (11)
- Fixed reader progress bar jumping to 100% immediately when navigating to the second chapter in short EPUBs (2 chapters): changed progress formula denominator from
total - 1tototalso 100% is only reached after fully scrolling through the last chapter. Same fix applied to PDF page progress.
2026-03-25 (10)
- Added bookmark feature:
bookmarkstable in DB (migrate_create_bookmarks):filename,chapter_index,scroll_frac,chapter_title,note,created_at- New API endpoints:
GET/POST /library/bookmarks/{filename},PATCH/DELETE /library/bookmarks/{id},GET /api/bookmarks - Bookmark button in reader header (orange, bookmark icon): opens modal with optional note field
- Bookmark modal closes on Escape, backdrop click, or Cancel
- Reader supports
?bm_ch=N&bm_scroll=FURL params to jump directly to bookmarked position (overrides saved progress) - Library sidebar: Bookmarks section in Library nav with live count badge
- Library
#bookmarksview: card list showing cover, book title, author, chapter, note, date, Go-to and Delete buttons
2026-03-22
- Added blueprint/technical documentation structure in
docs/. - Completed router split and bootstrap structure (
main.py, routers, migrations, DB pool). - Expanded media support to EPUB/PDF/CBR/CBZ in import and scan flows.
- Expanded Home UI with:
- import dropzone for EPUB/PDF/CBR/CBZ
- search functionality
- alignment matching Library (search top-right, dropzone below)
- Updated Library import texts and drag/drop filtering for multi-format support.
- Expanded Library
Newview with:Grid/Listtoggle- column visibility filter in
List - multi-select + bulk
Remove from New - selection only in
Listmode Shift+clickrange selection on checkboxes
- Added route:
POST /library/new/mark-reviewed(bulk setneeds_review=false). - Improved library performance:
/api/libraryfast-path (no full rescan on every page load)- optional
rescan=true/include_file_info=true - SQL optimizations in
list_library_json() - additional DB indexes for scale
- Restored
/api/homefull dataset output:continue_readingshorts_unreadnovels_unreadshorts_readnovels_read
- Explicitly filtered series books out of Home sections.
- Corrected Home read ordering:
shorts_readandnovels_readnow show oldest first (ORDER BY MAX(read_at) ASC). - Restored Statistics page by returning the full
/api/statspayload required for charts, favorites, top books, and reading history. - Improved backup implementation:
- Dropbox token stored encrypted in DB
- Dropbox backup root configurable via web UI and stored encrypted in DB
- versioned snapshots + object-store deduplication in Dropbox (
library_snapshots/library_objects) - configurable snapshot retention (
snapshots to keep) via backup settings - object pruning based on retained snapshots
- scheduled backup (enable + interval in hours)
- backup runs as a background process, so page navigation does not block execution
- stale running state recovery after restart/crash (old running logs marked interrupted/error)
- dry-run support in the new flow
- Updated Docker image with
postgresql-clientforpg_dump. - Multiple test builds pushed to
gitea.oskamp.info/ivooskamp/novela:dev.
2026-03-25 (9)
- Fixed backup progress not visible immediately after clicking Run Live Backup: sidebar
loadBackupProgress()is now called directly from the backup page after a successful start - Fixed backup status timestamp showing wrong relative time (e.g. "1h ago" for a recent backup): server UTC timestamps without timezone suffix are now correctly interpreted as UTC in the browser
- Fixed backup status bar using browser-default purple link color: now uses
var(--accent)orange consistent with the rest of the UI - Added password manager ignore attributes to App Key and App Secret fields:
data-1p-ignore(1Password),data-lpignore="true"(LastPass),data-form-type="other"(1Password v8)
2026-03-25 (8)
- Added Dropbox OAuth2 refresh token support (no redirect URI needed):
- New endpoints:
POST /api/backup/oauth/prepare(generates auth URL) andPOST /api/backup/oauth/exchange(exchanges code for refresh token) _dbx()now prefers refresh token mode (app key + secret + refresh token) with automatic renewal; falls back to legacy access token for backwards compatibility- App key and secret stored encrypted in
credentialstable (dropbox_app_key,dropbox_app_secret) DELETE /api/backup/credentialsnow also cleans updropbox_app_keyanddropbox_app_secret- Backup page updated with two-step OAuth flow UI (app key/secret → auth URL → paste code)
- Settings status shows
• refresh tokenor• legacy tokenindicator
- New endpoints:
2026-03-25 (7)
- Added backup progress tracking:
GET /api/backup/progressreturns{running, done, total, phase}; sidebar shows live file count (e.g.312 / 652 · uploading) polling every 3 s while running
2026-03-25 (6)
- Fixed
GET /api/backup/healthmissingschedule_enabledandschedule_interval_hoursin response (values were read but not returned; Health card showed "disabled" even when schedule was on) - Added backup status indicator in sidebar above Rescan library button: coloured dot + status text (OK/running/failed/never), links to
/backup, auto-refreshes every 8 s while running, shows time-ago for last successful backup
2026-03-25 (5)
- One-time path migration: all 571 existing library files moved to correct format-prefixed structure (
epub/,pdf/,comics/) and all DB references updated (migrate_paths.py --execute) - Empty old publisher root directories pruned after migration
- Recovery script (
recover_decock049.py) written; confirmed file was added after last Dropbox backup so not recoverable — to be re-imported manually
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)
- Fixed CBZ extension in import:
common.make_rel_pathalways generated.cbrfor CBZ files; now acceptsextparameter;library.pypasses actual suffix so CBZ files land atcomics/{author}/{title}.cbz - Added missing
GET /download/{filename}endpoint (referenced in book.html but was 404) - TECHNICAL.md fully rewritten: added File Storage Paths section, complete endpoint lists for all routers including settings.py, corrected path documentation
2026-03-25 (2)
- Fixed PDF metadata editing (PATCH /library/book):
_sync_epub_metadatais now only called for.epubfiles; PDFs update DB only_make_rel_pathnow includes the format prefix matching import: EPUB →epub/{publisher}/{author}/…, PDF →pdf/{author}/{title}.pdf, CBR/CBZ →comics/{author}/{title}{ext}; previously files were moved outside their format directory on metadata save
- Fixed PDF reader (infinite loading screen):
reader_pagenow passesformat(epub/pdf/cbr/cbz) toreader.html- Added
GET /api/pdf/info/{filename}endpoint returning{"page_count": N} reader.htmlbranches onFORMAT: PDFs render page images from/library/pdf/{filename}?page=N, EPUB flow unchanged- PDF progress tracked per page; keyboard and button navigation work identically to EPUB
Edit EPUBbutton in Book Detail hidden for non-EPUB files
2026-03-23
- Added
All booksGrid/List toggle in Library:- same columns as
Newview (Publisher, Author, Series, Volume, Title, Has cover, Updated, Genres, Sub-genres, Tags, Status) - column visibility filter in
Listmode - no selection checkboxes or bulk actions
- view mode and column visibility persisted separately in
localStorage(novela.all.viewMode,novela.all.visibleColumns)
- same columns as
- Added 1–5 star rating for books:
- stored in the database (
rating SMALLINT DEFAULT 0) - written to EPUB OPF as
<meta name="novela:rating" content="N"/>on rating change - written to CBZ
ComicInfo.xmlas<NovelaRating>N</NovelaRating>on rating change - CBR and PDF are DB-only (file format constraints)
- rating is recovered from file metadata during rescan/DB rebuild (
upsert_bookpreserves file rating over default 0) - stars displayed under the cover (outside
.book-info) in all grid views (Library, Home) - stars in grid cards are display-only (no click) to prevent accidental taps while scrolling
- stars in Book Detail are interactive (larger, 1.1rem), clicking same star removes rating
- star color: amber (
#c8a03a) for filled,rgba(200, 160, 58, 0.25)for unfilled — consistent across Library, Home, and Book Detail
- stored in the database (
- Added text colour setting to reader hamburger menu:
- 5 warm-tone presets from bright (
#e8e2d9) to dim (#938d86) - active preset shown with accent-coloured ring
- choice persisted in
localStorage(reader-text-colour) and restored on next open
- 5 warm-tone presets from bright (
- Increased spacing between hamburger button and back link in reader header (
margin-left: 1rem) to prevent accidental taps - Removed
Cover Missingauto-tag:- tag is no longer added on import, rescan, or grabber download
ensure_cover_missing_tag()removed fromcommon.py,library.py, andgrabber.py- startup migration removes all existing
Cover Missingtags from the database
- Fixed Tags/Genres/Sub-Genres not saving in book edit panel on desktop:
,(comma) now acts as a confirmation key alongside Enter inPillInputflush()added toPillInput: any text still in the input field is auto-confirmed when Save is clicked
- Fixed tag/genre search and tag-pill navigation being broken:
renderGenreViewwas filtering onb.genres(non-existent field); now usesbookGenres(),bookSubgenres(),bookPlainTags()renderSearchResultshad the same bug; search now covers title, author, genres, sub-genres, and tags