Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
79 changes: 79 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,85 @@

Releases of this fork. Images: `ghcr.io/mikaeltarquin/shelfmark:<version>` and `:latest`.

## v1.2.0

### Added

**A Sonarr/Radarr-style layout**
- **Left navigation and a search bar that's always there**: Search, Library, Activity
(Queued, Downloads, Requests, History), Wanted, Settings and System, each a page with
its own address. The open section lists its pages, with counts. On a phone it's a menu.
- **Tables for Activity, Wanted and the Library**, with sortable columns.
- **Settings is a page**, its tabs grouped into sections (Indexers, Download Clients with
Torrent and Usenet tabs, Libraries, Notifications…). **System** has the version,
health and support links.
- **A theme button** in the top bar: Light, Dark or Auto.
- Links, images and install commands point at this fork.

**The download queue**
- **Activity → Queued is everything waiting, in order**: **Up next** (downloads waiting
to start, such as a MyAnonamouse torrent waiting for an unsatisfied slot) and then
**Waiting for room** (saved picks), numbered in the order they go. Drag a row, or use
its arrows, to reorder either list.
- **Each saved pick shows** its releases (one per line, with the narrator and a link to
the release on MyAnonamouse), what it's **Waiting for**, when it was **Last checked**
and a countdown to the **Next check**.
- **Each release goes on its own**: a freeleech torrent or a small ebook downloads as soon
as there's room, instead of waiting for a big audiobook picked with it. An ebook that
goes first is still filed with its audiobooks.
- **Wanted** (formerly Later) has **Choose releases** on each book; once you pick, the book
moves to the queue.
- **Titles and covers on Queued and Wanted open the book's details.**

**Activity**
- **Finished downloads go straight to History**, and History is kept (it can't be
cleared). Clear Completed is gone.
- **Narrators** are listed under the author in Queued, Downloads and History, so two
recordings of a book can be told apart.
- **Open in your library from History** (Audiobookshelf or Calibre-Web), with or
without login.
- **Calmer badges**: counts beside Activity and its pages are soft tints, not red, and
queued downloads count on Queued, not twice.

**MyAnonamouse**
- **Next slot countdown** in the MyAnonamouse button.
- **The ratio shows two decimals**, worked out from the exact bytes uploaded and
downloaded.

**Library**
- Books in several series are listed under each of them (*Rhythm of War* in both The
Cosmere and The Stormlight Archive).
- **My Account → Library** sets the tab the Library opens on and each tab's sort.
- Box sets, omnibuses and collections are left out of missing books (My Account can show
them), and so are missing books numbered like one you already hold in the series.
- Narrator badges name the first narrator and a count ("Andrew Scott +9").

### Changed
- **Show Downloads When Queued** is off by default and only applies to downloads you
start. Background changes to the queue never move you to another page.
- Downloads waiting for an unsatisfied slot are checked every 2 minutes (was 5).

### Fixed
- **"Download failed: OSError"**: an audiobook with a large cast made a narrator folder
name too long for the filesystem. Names are now kept to 240 bytes, ending a long
narrator list with "et al.", and errors say what went wrong ("File name too long").
- **Non-freeleech audiobooks downloaded automatically below Keep Ratio At Least**: the
"barely moves the ratio" exception let through anything that lowered it by less than
0.01, which on a large account is a 500 MB audiobook. It now covers only ebook-sized
downloads (100 MB or less).
- **Automatic downloads stopped short of the unsatisfied limit** (stalling at 132/150
with 5 slots kept free): recent snatches were counted again after MAM's own count
already included them.
- **Retrying a MyAnonamouse download that was already in the torrent client** waited for
an unsatisfied slot it didn't need.
- **Expired indexer links** are re-found more often: the refresh searches the way the
book search did, then by title and author, so short titles like *Eric* are found.

### Upgrading
Activity's Later tab is now **Wanted** in the navigation; update bookmarks to the old
pages. Folders an earlier version left half-made after an "OSError" failure aren't cleaned
up; delete them and retry the download.

## v1.1.0

### Added
Expand Down
2 changes: 2 additions & 0 deletions docs/audiobookshelf.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ Audiobook templates can use `{Narrator}`. Narrators come from [MyAnonamouse Enri

Several narrators are joined with **Narrator Separator** (`NARRATOR_SEPARATOR`): `&` (default) gives `Narrator Two & Narrator Three`, `,` gives `Narrator Two, Narrator Three`.

Folder and file names are kept to 240 bytes, under the 255-byte limit of most filesystems. A full-cast recording with a dozen narrators would go over it, so its list is cut after the last whole name that fits and ends with `et al.` (`Book Title {Martin Jarvis & Peter Serafinowicz & … et al.}`). Any other value that's too long (a very long title, say) is cut at a word.

Braces nested inside a template block are kept as text, so `{{Narrator}}` renders `{Narrator One}` and disappears entirely when there is no narrator (the space before it is trimmed too). The recommended audiobook **Path Template** is:

```
Expand Down
36 changes: 34 additions & 2 deletions docs/environment-variables.md
Original file line number Diff line number Diff line change
Expand Up @@ -536,7 +536,7 @@ Audiobooks only. AudiobookBay lists it for most releases. In Prowlarr results it
| `EBOOKS_WITH_AUDIOBOOKS` | Audiobookshelf shows an ebook and an audiobook as one item when they share a folder. Also place each downloaded ebook in the folder of every audiobook of the same book (one per narrator), and copy an existing ebook into a newly downloaded audiobook's folder. Ebooks with no audiobook yet go to the audiobook path without a narrator and move in when the first audiobook arrives. Uses the audiobook Path Template, so include {Narrator} to keep narrations apart. | boolean | `false` |
| `WRITE_AUDIOBOOKSHELF_OPF` | Save a metadata.opf with Shelfmark's title, authors, narrators, year and series into each audiobook folder (and the ebooks kept with them) before the files arrive. Audiobookshelf prefers it over the release's own tags, so every book of a series imports with the same series name and number. Edits made in Audiobookshelf still take precedence. Folders that already have an .opf are left alone. | boolean | `false` |
| `HARDLINK_TORRENTS_AUDIOBOOK` | Create hardlinks instead of copying. Preserves seeding but archives won't be extracted. Don't use if destination is a library ingest folder. | boolean | `true` |
| `AUTO_OPEN_DOWNLOADS_SIDEBAR` | Go to Activity > Downloads when a new download is queued. | boolean | `false` |
| `AUTO_OPEN_DOWNLOADS_SIDEBAR` | When you start a download, go to the Activity page that lists it (Queued or Downloads). Downloads queued in the background never move the page. | boolean | `false` |
| `DOWNLOAD_TO_BROWSER_CONTENT_TYPES` | Automatically download completed files to your browser for the selected content types. | string (comma-separated) | _empty list_ |
| `MAX_CONCURRENT_DOWNLOADS` | Maximum number of simultaneous downloads. | number | `3` |
| `STATUS_TIMEOUT` | How long to keep completed/failed downloads in the queue display. | number | `3600` |
Expand Down Expand Up @@ -852,7 +852,7 @@ Create hardlinks instead of copying. Preserves seeding but archives won't be ext

**Show Downloads When Queued**

Go to Activity > Downloads when a new download is queued.
When you start a download, go to the Activity page that lists it (Queued or Downloads). Downloads queued in the background never move the page.

- **Type:** boolean
- **Default:** `false`
Expand Down Expand Up @@ -1357,6 +1357,9 @@ How long to cache individual book details. Default: 600 (10 minutes). Max: 60480
| `MAM_BLOCK_ON_LOW_BUFFER` | Before queueing MyAnonamouse torrents, check that they fit in the account's buffer (uploaded minus downloaded), counting Shelfmark's MAM downloads that are still active. If not, admins are offered upload credit to buy first; other users are asked to contact an admin. Freeleech torrents don't count. If MAM can't be reached, downloads go ahead. | boolean | `true` |
| `MAM_BLOCK_ON_UNSAT_LIMIT` | MyAnonamouse limits how many torrents can be unsatisfied (not yet seeded 72 hours) at once, by user class. Before queueing MAM torrents (freeleech too), check that they, plus Shelfmark's MAM downloads not yet started, leave the slots below free. Buying upload credit doesn't help here; wait for torrents to finish seeding. | boolean | `true` |
| `MAM_UNSAT_RESERVE_SLOTS` | Hold back downloads that would leave fewer free unsatisfied slots than this. | number | `5` |
| `SAVED_AUTO_GET_ENABLED` | Turn off to pause every automatic download; items stay marked. | boolean | `true` |
| `SAVED_AUTO_GET_TARGET_RATIO` | Non-freeleech downloads that would take the ratio below this wait, unless they're ebook-sized (100 MB or less) and lower it by less than 0.01. 0 turns the ratio check off. | number | `2.0` |
| `SAVED_AUTO_GET_INTERVAL_MINUTES` | How often to check the marked items. At least 5. | number | `10` |
| `MAM_AUTOBUY_RATIO_ENABLED` | Buy once per check while the ratio is below the threshold. | boolean | `false` |
| `MAM_AUTOBUY_RATIO_THRESHOLD` | Buy when the ratio is below this. 2.0 is MAM's minimum for renewing VIP; 1.0 is the site minimum. | number | `2.0` |
| `MAM_AUTOBUY_RATIO_AMOUNT` | How much to buy each time, in multiples of 50 GB. | number | `50` |
Expand Down Expand Up @@ -1484,6 +1487,35 @@ Hold back downloads that would leave fewer free unsatisfied slots than this.
- **Default:** `5`
- **Constraints:** min: 0

#### `SAVED_AUTO_GET_ENABLED`

**Get Saved Books Automatically**

Turn off to pause every automatic download; items stay marked.

- **Type:** boolean
- **Default:** `true`

#### `SAVED_AUTO_GET_TARGET_RATIO`

**Keep Ratio At Least**

Non-freeleech downloads that would take the ratio below this wait, unless they're ebook-sized (100 MB or less) and lower it by less than 0.01. 0 turns the ratio check off.

- **Type:** number
- **Default:** `2.0`
- **Constraints:** min: 0

#### `SAVED_AUTO_GET_INTERVAL_MINUTES`

**Check Every (Minutes)**

How often to check the marked items. At least 5.

- **Type:** number
- **Default:** `10`
- **Constraints:** min: 5

#### `MAM_AUTOBUY_RATIO_ENABLED`

**Buy When Ratio Is Low**
Expand Down
6 changes: 3 additions & 3 deletions docs/library-check.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ so its items are re-read at most every ten minutes.

## Browsing the library

With a library connected, admins get a **Library** button in the header. It shows every
With a library connected, admins get **Library** in the left navigation. It shows every
book in the connected libraries as a cover grid, with a filter (title, author, series or
narrator), a format filter (ebook, audiobook, or both) and sorting by title, author or
recently added. A book held by both libraries, say the ebook in Calibre and the audiobook
Expand All @@ -70,7 +70,7 @@ series name anywhere opens its page, and each page has its own address

Books you own work like search results: hover a card for **details** and the
**Hardcover lists** button, and **+ Get** underneath finds releases, in the format picked
in the header (or both, in combined mode). Use it to get the format you're missing, a
in the search bar (or both, in combined mode). Use it to get the format you're missing, a
better copy, or another narrator's version; releases whose narrator you already own are
marked. The card looks the book up with the metadata provider the first time it's
hovered (by ISBN, else title and author), and the answer is remembered.
Expand All @@ -79,7 +79,7 @@ Below the books you own, author and series pages list what is **Not in your libr
the books the metadata provider knows for that author or series, minus the ones you have.
Pick **Any format**, **Ebook** or **Audiobook**: under Audiobook, a book you own only as
an ebook still shows (with a "Have ebook" badge). Picking Ebook or Audiobook also switches
the header's content type, so **Get** on a missing book finds releases in that format;
the search bar's content type, so **Get** on a missing book finds releases in that format;
it opens the usual release (or request) flow. Series need a provider that can list a
series (Hardcover); with Hardcover an author is looked up by their Hardcover id, so the
list is their own books. Up to 200 books are listed per author or series.
Expand Down
13 changes: 7 additions & 6 deletions docs/myanonamouse-enrichment.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,10 +45,11 @@ After a failed request (a 403, a timeout, an unexpected reply), Shelfmark waits

## Account panel

With a MAM session ID set, admins get a **MyAnonamouse** button in the header, between
Library and Activity. It shows the account's ratio and unsatisfied count at a glance (amber
or red as they near their limits, refreshed every 5 minutes), and opens a panel with links
to your MAM profile and the MAM store. The panel shows:
With a MAM session ID set, admins get a **MyAnonamouse** button in the top bar. It shows the account's ratio (to two
decimals, worked out from the exact bytes uploaded and downloaded rather than MAM's rounded
figures) and unsatisfied count at a glance (amber or red as they near their limits,
refreshed every 5 minutes), plus a countdown to the next unsatisfied slot freeing up, and
opens a panel with links to your MAM profile and the MAM store. The panel shows:

- **Account:** ratio, buffer (uploaded − downloaded), bonus points, uploaded, downloaded, class, VIP expiry and unsatisfied torrents against your class's limit (amber at 90%, red at the limit), from MAM's `jsonLoad.php?snatch_summary`. Refreshed at most once a minute unless you press **Refresh**.
- **Points / hour:** MAM's API has no earning rate, so Shelfmark estimates it from its own readings of your balance (taken hourly, kept for two days) over the last 24 hours. Points Shelfmark spent on upload credit are added back; a period where points dropped for another reason (spending on MAM's site) or hit MAM's 99,999 cap is left out. It shows once a few hours of readings exist.
Expand Down Expand Up @@ -87,11 +88,11 @@ Under **Settings > Prowlarr > Upload Credit Auto-Buy**, Shelfmark can spend bonu

MyAnonamouse limits how many torrents can be unsatisfied (not yet seeded 72 hours) at once, by class. With **Hold Back Downloads at the Unsatisfied Limit** (`MAM_BLOCK_ON_UNSAT_LIMIT`, on by default), MAM torrents are held back when they, plus Shelfmark's MAM downloads not yet handed to the torrent client, would leave fewer free slots than **Unsatisfied Slots to Keep Free** (`MAM_UNSAT_RESERVE_SLOTS`, 5). Every MAM torrent counts, freeleech too. Upload credit can't fix this, so none is offered: wait for torrents to finish seeding or pick fewer. The projected-ratio line also shows `unsatisfied 94 → 98 / 100`, red when the picks would be held back.

A MAM download that's short only of unsatisfied slots doesn't have to be held back or fail. The hold-back prompt offers **Queue and wait for a slot**. A queued MAM download whose turn comes while the account is full, counting the slots kept free (or whose grab MAM refuses while at the limit), goes back to the queue as **Waiting for an unsatisfied slot on MyAnonamouse**. Waiting downloads are released, longest waiting first, once a slot is free (checked every 5 minutes). Shelfmark's own snatches since shortly before the account was read count too, since MAM's figure lags. Cancel it from Activity to drop it. Waiting downloads don't survive a restart; they show as interrupted, with Retry.
A MAM download that's short only of unsatisfied slots doesn't have to be held back or fail. The hold-back prompt offers **Queue and wait for a slot**. A queued MAM download whose turn comes while the account is full, counting the slots kept free (or whose grab MAM refuses while at the limit), goes back to the queue as **Waiting for an unsatisfied slot on MyAnonamouse**. Waiting downloads are released, longest waiting first, once a slot is free (checked every 2 minutes), in their order on **Activity → Queued**. A torrent already in your torrent client (a retry after it was handed over) doesn't wait for a slot: it already has one. Shelfmark's own snatches that MAM's count doesn't show yet count too, since MAM's figure lags; once MAM's count has caught up they aren't counted a second time. Cancel it from Activity to drop it. Waiting downloads don't survive a restart; they show as interrupted, with Retry.

### When slots free up

The account panel (and the header button's tooltip) also estimates when unsatisfied
The account panel (and the top-bar button and its tooltip) also estimates when unsatisfied
torrents free their slots: `Next slot in 2:05 · 3 slots in the next 6 hours`. MAM's API
only reports how many torrents are unsatisfied, so the timing comes from your torrent
client: each MyAnonamouse torrent it is seeding that hasn't reached 72 hours frees a slot
Expand Down
Loading
Loading