mirror of
https://github.com/calibrain/shelfmark.git
synced 2026-11-10 12:28:27 +00:00
docs: small fixes from a check of the docs against the code (#1567)
These are the leftovers from the docs check, the fixes that did not belong in the other three. Claude did the comparison and wrote the changes here too, so I would still like a human look before it merges. The one new piece of prose worth a read is `troubleshooting.md`. It was a TODO page that two other pages link to, so I filled it with only what I could confirm in the code: where the logs go, `LOG_LEVEL`, the `DEBUG=true` bundle from the bug report template, and reporting an issue. Happy to drop it back to a stub if you would rather write that one yourself. - `configuration.md`, `custom-scripts.md`, `users-and-requests.md`: Booklore is Grimmory in the UI now. The stored mode value is still `booklore`, and the custom script doc says so. The hardlink heading now matches the "Hardlink Book Torrents" and "Hardlink Audiobook Torrents" checkboxes. - `custom-scripts.md`: the email output runs scripts too (`phase=post_email`, `output.mode=email`, details under `output.details.email`). It was missing from the phase list. - `users-and-requests.md`: a delivery that fails with no retry available goes back to pending on its own, and the admin reopen action is for rejected requests. The page said an admin reopens a failed delivery. Also noted that rules cannot use Request Book. - `hardcover-sync.md`: added the missing `AUTO_DOWNLOAD_AUDIOBOOK_MIN_SIZE_PERCENT` row and a sentence in the ranking paragraph. - `api-access.md`: an admin session also reads `/api/stats`, and what the 403 says. - `installation.md`: points at the Lite, Tor and WireGuard variants. Docs only, no code touched.
This commit is contained in:
1 parent
6b775cd9e8
commit
20848a8774
7 files changed
+37
-19
No files matched your search
+1
-1
@@ -75,7 +75,7 @@ curl -s -H "Authorization: Bearer $SHELFMARK_API_KEY" https://shelfmark.example.
|
||||
|
||||
Set `SHELFMARK_API_KEY_READONLY` to a second secret for dashboards and monitors. It can read one endpoint,
|
||||
`GET /api/stats`, and nothing else. Writes and every other path return 403, and the key never gets a session.
|
||||
The admin key reaches `/api/stats` too.
|
||||
The admin key reaches `/api/stats` too, and so does a browser session signed in as an admin. A refused request gets `{"error": "This API key is read-only"}`.
|
||||
|
||||
```bash
|
||||
curl -s -H "X-Api-Key: $SHELFMARK_API_KEY_READONLY" https://shelfmark.example.com/api/stats
|
||||
|
||||
@@ -41,8 +41,8 @@ services:
|
||||
```
|
||||
|
||||
Notes:
|
||||
- Point `/books` to your library ingest folder (Calibre-Web, Booklore, Audiobookshelf, etc) for automatic import.
|
||||
- If you set Books Output Mode to Booklore (API), books are uploaded via API instead of written to `/books`. Audiobooks still use a destination folder.
|
||||
- Point `/books` to your library ingest folder (Calibre-Web, Grimmory, Audiobookshelf, etc) for automatic import.
|
||||
- If you set Output Mode to Grimmory (API), books are uploaded via API instead of written to `/books`. Audiobooks still use a destination folder.
|
||||
- Ensure `PUID`/`PGID` (or legacy `UID`/`GID`) match the owner of the host directories.
|
||||
- For non-root mode, start the container as `1000:1000`.
|
||||
- On Kubernetes, set `runAsUser: 1000`, `runAsGroup: 1000`, and `runAsNonRoot: true` together.
|
||||
@@ -97,11 +97,9 @@ longer than the sync interval.
|
||||
|
||||
## File Processing Options
|
||||
|
||||
### Transfer Method (Torrent / Usenet Only)
|
||||
### Hardlink Torrents (Torrent / Usenet Only)
|
||||
|
||||
Available methods:
|
||||
- Copy (default). Works everywhere.
|
||||
- Hardlink. Preserves seeding without duplicating files.
|
||||
Imported files are copied by default, which works everywhere. Turn on **Hardlink Book Torrents** (and **Hardlink Audiobook Torrents** for audiobooks) to hardlink instead, which preserves seeding without duplicating files.
|
||||
|
||||
Hardlink requirements and behavior:
|
||||
- Source and destination must be on the same filesystem.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Custom Scripts
|
||||
|
||||
Shelfmark can run an executable you provide after a download task completes successfully. The script runs after the selected output has finished (for example: transfer to the folder destination, or upload to Booklore).
|
||||
Shelfmark can run an executable you provide after a download task completes successfully. The script runs after the selected output has finished (for example: transfer to the folder destination, upload to Grimmory, or send by email).
|
||||
|
||||
|
||||
## Quick Start (Recommended)
|
||||
@@ -71,7 +71,8 @@ Shelfmark chooses a "best single path" for the task:
|
||||
What the target path refers to depends on the output mode:
|
||||
|
||||
- Folder output (`output.mode=folder`, `phase=post_transfer`): the final imported file or folder inside your destination.
|
||||
- Booklore output (`output.mode=booklore`, `phase=post_upload`): the local file or folder that was uploaded (the destination is remote).
|
||||
- Grimmory output (`output.mode=booklore`, `phase=post_upload`): the local file or folder that was uploaded (the destination is remote).
|
||||
- Email output (`output.mode=email`, `phase=post_email`): the file that was sent, or the folder holding the files when there were several.
|
||||
|
||||
By default, `$1` is an absolute path inside the Shelfmark container (or on your host, if you are not using Docker).
|
||||
|
||||
@@ -79,12 +80,12 @@ By default, `$1` is an absolute path inside the Shelfmark container (or on your
|
||||
|
||||
Configure in: Settings -> Advanced -> Custom Script JSON Payload
|
||||
|
||||
When enabled, Shelfmark sends a versioned JSON payload to your script via stdin (and still passes `$1`). This is the recommended way to write robust scripts, especially for multi-file imports (audiobooks) and output-specific context (like Booklore).
|
||||
When enabled, Shelfmark sends a versioned JSON payload to your script via stdin (and still passes `$1`). This is the recommended way to write robust scripts, especially for multi-file imports (audiobooks) and output-specific context (like Grimmory).
|
||||
|
||||
- The JSON payload always includes absolute paths in `paths.*`, even if you set Custom Script Path Mode to `relative` for `$1`.
|
||||
- `output.mode` tells you which output ran.
|
||||
- `output.details` is output-specific. For Booklore output, `output.details.booklore` includes connection details such as `base_url`, `library_id`, and `path_id`.
|
||||
- `phase` indicates when the script is running. Current values: `post_transfer` (folder output), `post_upload` (Booklore output).
|
||||
- `output.details` is output-specific. For Grimmory output (the mode value is still `booklore`), `output.details.booklore` includes connection details such as `base_url`, `library_id`, and `path_id`. For email output, `output.details.email` has `to`, `label`, `host`, `port`, and `security`.
|
||||
- `phase` indicates when the script is running. Current values: `post_transfer` (folder output), `post_upload` (Grimmory output), `post_email` (email output).
|
||||
- `transfer` is only included for outputs that do a local transfer (for example the folder output).
|
||||
|
||||
If JSON payload is disabled, stdin is empty (EOF). Don't `cat` stdin unless you've enabled the payload.
|
||||
@@ -171,7 +172,7 @@ This setting controls what gets passed as `$1`:
|
||||
- `absolute` (default): pass an absolute path.
|
||||
- `relative`: pass a path relative to the output's "destination root", and run the script with `$PWD` set to that root.
|
||||
|
||||
For folder output, the destination root is your configured destination folder. For Booklore output, it's the local upload folder.
|
||||
For folder output, the destination root is your configured destination folder. For Grimmory output, it's the local upload folder. For email output, it's the folder holding the files that were sent.
|
||||
|
||||
Example (folder destination is `/data/library/books`, and the imported file ended up in `Isaac Asimov/Foundation/Foundation.epub`):
|
||||
|
||||
@@ -192,4 +193,5 @@ Note: if the target is the destination folder itself, `relative` mode may pass `
|
||||
## Notes And Caveats
|
||||
|
||||
- **Hardlinks and torrents:** if you use hardlinking to keep seeding, avoid scripts that modify file contents, since hardlinked files share data with the seeding copy.
|
||||
- **Booklore output mode:** scripts run after upload. `$1` will point at the local uploaded file (or staging folder).
|
||||
- **Grimmory output mode:** scripts run after upload. `$1` will point at the local uploaded file (or staging folder).
|
||||
- **Email output mode:** scripts run after the message is sent. `$1` will point at the file that was sent (or the folder holding the files).
|
||||
@@ -35,7 +35,7 @@ AudiobookBay requires every word of a query, and its posts for one volume of a m
|
||||
|
||||
When no source yields a strict match for the request's own search title, up to three simpler titles are tried in turn, each across the sources in priority order and all within the request's search budget: the title without a subtitle after `:` or ` - `, the title without an alternate title (*The Hobbit, or There and Back Again* becomes *The Hobbit*), and the title with its numbers written as digits (*Part II* becomes *Part 2*). The first one that yields a strict match wins, and the log names it. A simpler title is matched by exactly the rules above, so a release has to name the shorter title, the right author, and no sequel, edition, derivative or pack. The subtitle is only dropped when the book's metadata says it is one (a series name is known, or the book's subtitle is what follows the separator), and never when what is left is only the series or author name: *Star Wars: Thrawn* is not searched as *Star Wars*.
|
||||
|
||||
Among matching releases from the winning source, format ranks first (`m4b` over `mp3` for audiobooks; `epub` over `azw3` over `mobi` for ebooks), then the copy other people chose — more downloads (direct-download sources report them), then more seeders — then larger size. If no source produces a confident match the request stays **pending** for manual review; nothing is guessed.
|
||||
Among matching releases from the winning source, format ranks first (`m4b` over `mp3` for audiobooks; `epub` over `azw3` over `mobi` for ebooks), then the copy other people chose — more downloads (direct-download sources report them), then more seeders — then larger size. The exception is an audiobook copy far smaller than the others for the same book, which is probably a lower-bitrate copy: it is tried after the others (see **Smallest acceptable audiobook copy** below). If no source produces a confident match the request stays **pending** for manual review; nothing is guessed.
|
||||
|
||||
A request whose book turns out to be in your library already is closed, not left pending: it is marked fulfilled with the admin note `[auto] Already in the library.`, so it stops being looked up every pass. Before this it sat in Needs Review indefinitely. **Clear Completed** clears these too.
|
||||
|
||||
@@ -78,6 +78,7 @@ The check **fails closed** here: if an enabled library cannot be read and has no
|
||||
| `AUTO_DOWNLOAD_SOURCE_PRIORITY` | Audiobook source priority | All usable sources | Drag to order; used for audiobook requests. Sources you disable here, or that are not configured, are skipped |
|
||||
| `AUTO_DOWNLOAD_EBOOK_SOURCE_PRIORITY` | Ebook source priority | All usable sources | Same, for ebook requests |
|
||||
| `AUTO_DOWNLOAD_MIN_SEEDERS` | Minimum seeders (torrents) | 1 | Torrent releases below this are ignored |
|
||||
| `AUTO_DOWNLOAD_AUDIOBOOK_MIN_SIZE_PERCENT` | Smallest acceptable audiobook copy (%) | 67 | A copy smaller than this share of the largest copy found for the same book is tried after the others, and a single m4b that small is not preferred over a fuller set of chapter files. 0 turns the check off |
|
||||
| `AUTO_DOWNLOAD_RETRY_DAYS` | Retry failed downloads after (days) | 7 | A failed or interrupted download goes back to pending after this long. 0 turns retries off |
|
||||
| `AUTO_DOWNLOAD_BACKOFF_MAX_DAYS` | Longest wait between searches for an unmatched request (days) | 3 | 0 searches every unmatched request every cycle |
|
||||
| `AUTO_DOWNLOAD_FAILURE_RETRY_MINUTES` | Try another release after a failed download (minutes) | 0 (off) | Reopens failed or given-up downloads and picks another release this long after, between sync cycles |
|
||||
|
||||
@@ -31,3 +31,4 @@ docker compose up -d
|
||||
- Universal search is the default mode for new installs
|
||||
- Direct Download is optional and must be enabled and configured before it can be used
|
||||
- Torrent and usenet setups require matching download paths between Shelfmark and your download client
|
||||
- The Lite image and the Tor and WireGuard variants have their own compose files, described under Docker Variants in the [README](../readme.md)
|
||||
+15
-1
@@ -1,3 +1,17 @@
|
||||
# Troubleshooting
|
||||
|
||||
TODO
|
||||
Start with the logs, then attach a debug bundle if you open an issue.
|
||||
|
||||
## Logs
|
||||
|
||||
Shelfmark writes its log to the container output, so `docker logs shelfmark` shows it. With `ENABLE_LOGGING` on (the default) it also writes log files under `LOG_ROOT/shelfmark/` (`/var/log/shelfmark/` by default), including `shelfmark.log` and the startup logs.
|
||||
|
||||
`LOG_LEVEL` sets how much is written (`INFO` by default). Set it to `DEBUG` to see what a search or download is doing. See the [Environment Variables](environment-variables.md) reference for both settings.
|
||||
|
||||
## Debug bundle
|
||||
|
||||
Set `DEBUG=true` on the container and restart it. A **DEBUG** button then appears in the interface. It generates a zip with logs, configuration and environment details, with sensitive values redacted. Have a look through it before you post it publicly, then attach it when you open an issue.
|
||||
|
||||
## Reporting an issue
|
||||
|
||||
Open an issue on [GitHub](https://github.com/calibrain/shelfmark/issues) and fill in the bug report template. A description of what you expected, the steps to reproduce it and the debug bundle are what make a problem findable.
|
||||
@@ -42,10 +42,10 @@ There are four categories of per-user settings:
|
||||
|
||||
Override where a user's downloads are sent. Options depend on the global output mode configuration:
|
||||
|
||||
- **Output mode** — Folder, Email (SMTP), or BookLore (API)
|
||||
- **Output mode** — Folder, Email (SMTP), or Grimmory (API)
|
||||
- **Destination** — A custom folder path for this user's ebook downloads
|
||||
- **Audiobook destination** — A custom folder path for audiobook downloads
|
||||
- **BookLore library/path** — Per-user BookLore target (when using BookLore output mode)
|
||||
- **Grimmory library/path** — Per-user Grimmory target (when using Grimmory output mode)
|
||||
- **Email recipient** — Per-user email address (when using Email output mode)
|
||||
|
||||
### Search Preferences
|
||||
@@ -101,6 +101,8 @@ The rules matrix lets you override the mode for specific source + content type c
|
||||
|
||||
For example, if the default ebook mode is "Download", a rule can restrict a specific source to "Request Release" or "Blocked", but not the other way around. If no rule matches, the content-type default applies.
|
||||
|
||||
Rules cannot use "Request Book". Sources whose browse results are already concrete releases are also treated as "Request Release" when the default mode is "Request Book", since there is no book-level request to make for them.
|
||||
|
||||
### Per-User Overrides
|
||||
|
||||
Admins can override the default ebook/audiobook modes and request rules for individual users. Per-user rules are overlaid on the global rules, not replacing them.
|
||||
@@ -111,6 +113,6 @@ Admins can override the default ebook/audiobook modes and request rules for indi
|
||||
2. Request appears in the admin request queue as **pending**
|
||||
3. Admin either **fulfils** (queues a download) or **rejects** the request
|
||||
4. For fulfilled requests, delivery state is tracked through the download pipeline
|
||||
5. If delivery fails, an admin can reopen the request to try a different release
|
||||
5. If delivery fails and the download cannot be retried, the request goes back to pending automatically so an admin can approve it again with a different release. An admin can also reopen a rejected request
|
||||
6. Users can cancel their own pending requests
|
||||
7. An admin can **reopen** a rejected request, from the Requests tab or from History. It goes back to pending with what the user originally asked for, and shows in the activity list again even if the user had dismissed it.
|
||||
Reference in new issue
Block a user