Commit Graph
1150 Commits
Author SHA1 Message Date
github-actions[bot] 9992a2bff0 chore: bump Cargo.toml to 0.8.1
Check / stable / fmt (push) Failing after 24s
Check / beta / clippy (push) Failing after 1m10s
Check / stable / clippy (push) Failing after 1m10s
Check / nightly / doc (push) Successful in 1m1s
Check / 1.95.0 / check (push) Successful in 1m8s
Check / dockerfile / msrv (push) Successful in 5s
Test Suite / ubuntu / beta (push) Successful in 2m15s
Test Suite / ubuntu / stable (push) Successful in 2m16s
Test Suite / ubuntu / stable / coverage (push) Failing after 1m55s
Test Suite / macos-latest / stable (push) Canceled after 0s
Test Suite / windows-latest / stable (push) Canceled after 0s
2026-10-12 17:31:42 +00:00
github-actions[bot] c5ac78a310 bump: version 0.8.0 → 0.8.1 [skip ci] 2026-10-12 17:31:40 +00:00
Dark-Alex-17 0f230a1a4f fix: never panic when the log directory is unwritable; disable file logging instead [#67]
Check / stable / fmt (push) Failing after 26s
Check / beta / clippy (push) Failing after 1m10s
Check / stable / clippy (push) Failing after 1m10s
Check / nightly / doc (push) Successful in 1m0s
Check / 1.95.0 / check (push) Successful in 1m7s
Check / dockerfile / msrv (push) Successful in 5s
Test Suite / ubuntu / beta (push) Successful in 2m15s
Test Suite / ubuntu / stable (push) Successful in 2m14s
Test Suite / ubuntu / stable / coverage (push) Failing after 1m57s
Test Suite / macos-latest / stable (push) Canceled after 0s
Test Suite / windows-latest / stable (push) Canceled after 0s
2026-10-12 11:16:11 -06:00
Dark-Alex-17 f6071f73b5 Merge branch 'main' of github.com:Dark-Alex-17/managarr
Check / stable / fmt (push) Failing after 25s
Check / beta / clippy (push) Failing after 1m15s
Check / stable / clippy (push) Failing after 1m11s
Check / nightly / doc (push) Successful in 1m3s
Check / 1.95.0 / check (push) Successful in 1m10s
Check / dockerfile / msrv (push) Successful in 5s
Test Suite / ubuntu / beta (push) Successful in 2m16s
Test Suite / ubuntu / stable (push) Successful in 2m17s
Test Suite / ubuntu / stable / coverage (push) Failing after 2m0s
Test Suite / macos-latest / stable (push) Canceled after 0s
Test Suite / windows-latest / stable (push) Canceled after 0s
2026-10-01 14:45:21 -06:00
Dark-Alex-17 11524bb232 feat: all CLI-based errors now come out in the same JSON format to further improve scripting and LLM integration
Check / stable / fmt (push) Failing after 25s
Check / beta / clippy (push) Failing after 1m15s
Check / stable / clippy (push) Failing after 1m12s
Check / nightly / doc (push) Successful in 1m2s
Check / 1.95.0 / check (push) Successful in 1m8s
Check / dockerfile / msrv (push) Successful in 5s
Test Suite / ubuntu / beta (push) Successful in 2m21s
Test Suite / ubuntu / stable (push) Successful in 2m20s
Test Suite / ubuntu / stable / coverage (push) Failing after 1m59s
Test Suite / macos-latest / stable (push) Canceled after 0s
Test Suite / windows-latest / stable (push) Canceled after 0s
2026-09-30 22:02:46 -06:00
github-actions[bot] 72ace0f2d5 chore: bump Cargo.toml to 0.8.0 2026-09-30 17:57:08 +00:00
github-actions[bot] 9375e04ebf bump: version 0.7.3 → 0.8.0 [skip ci] 2026-09-30 17:57:06 +00:00
Dark-Alex-17 7a79e1c05e ci: Added a dockerfile check to ensure the dockerfile MSRV matches Cargo.toml
Check / stable / fmt (push) Failing after 32s
Check / beta / clippy (push) Failing after 1m20s
Check / stable / clippy (push) Failing after 1m19s
Check / nightly / doc (push) Successful in 1m4s
Check / 1.95.0 / check (push) Successful in 1m8s
Check / dockerfile / msrv (push) Successful in 5s
Test Suite / ubuntu / beta (push) Successful in 2m24s
Test Suite / ubuntu / stable (push) Successful in 2m28s
Test Suite / ubuntu / stable / coverage (push) Failing after 2m22s
Test Suite / macos-latest / stable (push) Canceled after 0s
Test Suite / windows-latest / stable (push) Canceled after 0s
2026-09-30 11:40:46 -06:00
Alex Clarke 06e504732d Merge pull request #65 from Dark-Alex-17/readarr-support
Readarr support
2026-09-30 10:41:44 -06:00
Dark-Alex-17 003f80098a docs: Updated the pull request template 2026-09-30 00:11:56 -06:00
Dark-Alex-17 ad8a6743ab docs: Added documentation on how to configure Chaptarr in Managarr 2026-09-30 00:03:29 -06:00
Dark-Alex-17 c61404dc71 docs: Updated the contribution guidelines and PR template to sound more like AI is allowed but only when disclosed 2026-09-29 23:46:40 -06:00
Dark-Alex-17 a5b95c165a fix(readarr): send an empty images list when adding an author 2026-09-29 23:36:11 -06:00
Dark-Alex-17 8ec4ec018b fix(readarr): accept release searches wrapped in a filter summary envelope 2026-09-29 23:30:30 -06:00
Dark-Alex-17 642a5c0a87 fix(readarr): tolerate book payloads that omit the grabbed flag 2026-09-29 23:25:19 -06:00
Dark-Alex-17 9128e68d0a test(readarr): cover the CLI handler dispatch to each subcommand handler 2026-09-29 16:52:53 -06:00
Dark-Alex-17 ddc18ae21a docs: Updated the README to mention that Readarr has been sunset but Managarr is compatible with any APIs that are compatible with Readarr v1 2026-09-29 15:54:47 -06:00
Dark-Alex-17 4b8b9cde57 docs: Updated README with screenshots of Readarr 2026-09-29 14:24:00 -06:00
Dark-Alex-17 238348f6ec fix(radarr): render the movie overview one size down so the collection details stay visible behind it 2026-09-29 13:49:28 -06:00
Dark-Alex-17 37f697d1b4 docs: reformatted tables in README 2026-09-29 13:47:04 -06:00
Dark-Alex-17 a70019b88f Merge remote-tracking branch 'origin/main' into readarr-support
# Conflicts:
#	src/utils_tests.rs
2026-09-29 12:46:54 -06:00
Alex Clarke fa02b70bf0 Merge pull request #64 from solareon/fix/servarr_name
fix: passes servarr-name global switch to both the tui and cli
2026-09-29 10:54:20 -06:00
Solareon 76f9f4da9a test: remove disable-spinner to improve test coverage 2026-09-29 11:05:37 +02:00
Solareon 49be500b8c style: cargo fmt and nested if fix 2026-09-29 10:44:39 +02:00
Solareon 78918b6d88 test: ensure no servarr-name select first configured instance 2026-09-29 10:40:11 +02:00
Solareon 9b98e53b55 test: servarr-name with whitespace is trimmed properly 2026-09-29 10:31:01 +02:00
Solareon b799fe3865 test: unknown servarr-name fails properly 2026-09-29 10:21:00 +02:00
Solareon 0e869e1e98 test: ensure duplicate servarr names select correct instance 2026-09-29 10:05:37 +02:00
Solareon 196bc55f35 test: validate selected servarr-name type mismatch 2026-09-29 10:00:24 +02:00
Solareon e29bd67a3e test: happy path test for servarr-name 2026-09-29 08:55:04 +02:00
Dark-Alex-17 424ed62229 chore: update dependencies ahead of release 2026-09-28 16:02:28 -06:00
Dark-Alex-17 ab7542651b chore: bump GitHub Actions to Node 24 runtimes 2026-09-28 15:53:26 -06:00
Dark-Alex-17 a222f40616 fmt: addressed linter complaints 2026-09-28 14:49:53 -06:00
solareon 699e929ed2 fix(app/mod): use correct api for tab when starting on non default tab
Further testing of the servarr_name switch revealed an issue where selecting a server that didn't match the first tab caused the wrong api to be used. Now when a non-default tab is selected the correct api is used
2026-09-25 07:44:51 -04:00
solareon 5279d37ea2 fix: passes servarr-name global switch to both the tui and cli
servarr-name global switch was documented but not fully implemented in commit fd6fcfc. this commit fully implements the feature
2026-09-25 07:30:01 -04:00
Dark-Alex-17 a4b8a23424 docs: list the Readarr features in the README 2026-09-19 13:57:49 -06:00
Dark-Alex-17 f2ee1e71f6 feat: show sizes under a gigabyte in megabytes
Every size cell converted bytes to gigabytes and formatted the float in
place, so anything below a gigabyte rendered as 0.00 GB. Books and
tracks are almost always that small, which made the Size columns in
Readarr and Lidarr useless.

Replace convert_to_gb and convert_f64_to_gb with one format_size helper
that renders gigabytes at or above 1 GiB and megabytes below it, at the
precision each site already used. Every render site across the four
servarr trees now calls it, including the two movie and episode detail
strings built on the network side. Values at or above a gigabyte render
byte for byte as before.

Give the Readarr book statistics and book file fixtures and the Lidarr
album statistics fixture realistic sub-gigabyte sizes so the megabyte
path is pinned by the committed snapshots.
2026-09-18 21:44:22 -06:00
Dark-Alex-17 bdeaf6ae35 test: prove the track, episode and movie row styles reach the rendered buffer
The row-style decorators were unit-tested as pure functions and the populated test apps do carry a downloading queue entry, but text snapshots discard colour, so nothing proved the draw functions actually call the decorator with the live downloads list. Passing an empty slice instead left every test green.

Render the lidarr tracks table, the sonarr episodes table and the radarr movies table into a Buffer and assert the probe row's foreground: downloading_style with the queue populated, missing_style once the queue is emptied. The probe is the second row so the selection highlight never masks its style.
2026-09-17 18:44:34 -06:00
Dark-Alex-17 35ed3f359d refactor: share one DownloadStatus enum across the servarr models
DownloadStatus was declared four times, byte for byte identically, in
radarr_models, sonarr_models, lidarr_models, and readarr_models: the same
variants, the same derive list, and the same serde, strum, and display_style
attributes. Every servarr's queue endpoint reports the same status
vocabulary, so there is nothing servarr specific about the type.

Move it into servarr_models, preserving that file's alphabetical ordering
(between DiskSpace and IndexerSettings), and drop the four copies. The
DownloadRecord types keep their per-servarr shapes and now reference the
shared enum.

The two enum tests, test_download_status_display and
test_download_status_to_display_str, were likewise duplicated in the four
per-servarr model test files. Keep one copy of each in servarr_models_tests
alongside the other shared enum display tests and delete the rest. The
per-servarr DownloadRecord fallback deserialization tests stay where they
are since they exercise each servarr's own record type.

Behavior is unchanged. Every remaining edit is an import path update.
2026-09-17 18:32:51 -06:00
Dark-Alex-17 040935178a test(sonarr): give the download record and episode fixtures distinct ids
The shared download record held id and episode id both equal to 1, and
the shared episode held id and episode file id both equal to 1, so
reading the wrong one of those fields could not fail any test that uses
them. Move the download record to id 9 and the episode to id 11, keeping
the download record's episode id equal to the episode's id so the
downloading episode still matches, and move the episode file to id 7
together with the episode's episode file id so the season view still
finds its quality and size. Series id, season number, and episode number
stay at 1. The handler tree keeps its own copy of these fixtures; update
it identically, along with the JSON twins in the network tests and the
seven handler assertions that named the old ids. The two get episodes
tests that asserted the sorted table now spell out the sorted order,
since the fixture episode no longer sorts first by id.
2026-09-17 18:22:31 -06:00
Dark-Alex-17 4f78a5940f test(lidarr): give the track and history fixtures distinct ids
The shared track held id, artist id, track file id, and album id all
equal to 1, and the shared history item held id, album id, artist id,
and track id all equal to 1, so reading the wrong one of those fields
could not fail any test that uses them. Move the track to id 5, artist
id 3, and track file id 7 (with the shared track file moved to id 7 so
the album view still finds its quality and audio info), and move the
history item to id 13, artist id 3, and track id 5. Both album ids stay
at 1 so the fully populated album view still shows its track as
downloading. Update the seven assertions that named the old ids.
2026-09-17 18:16:17 -06:00
Dark-Alex-17 9822597b56 fix(radarr): model the movie status as an enum
Movie.status and AddMovieSearchResult.status were bare Strings compared
against the literal "released" in the row-style decorator and in the
movie details style function. They now carry a MovieStatus enum with the
five values Radarr actually sends (tba, announced, inCinemas, released,
deleted), shaped like MinimumAvailability and DownloadStatus, and guarded
with from_json_or_default so an unrecognised status degrades to Tba
instead of failing the whole fetch.

Radarr never sends "Downloaded" as a movie status; its web UI derives
that label from released plus hasFile. Every fixture that carried
"Downloaded" now holds released, the value it was standing in for, so
none of them degrade to the default through the guard.

The status is never rendered as text in the Radarr tree, so no snapshot
changes; the CLI JSON output is unchanged since the enum serializes to
the same camelCase strings. The style_from_download_status tests now
exercise the unreleased arm, which previously had no case, in place of a
duplicated unmonitored-missing row.
2026-09-17 18:06:37 -06:00
Dark-Alex-17 c42a46c7ca fix: page up and down stop at the table edges instead of wrapping
A page is 20 rows and the index wrapped modulo one less than the row
count, so the last row was unreachable by paging, 21-row and 5-row tables
did nothing on page down from the first row, and 4-row tables cycled
0, 2, 1 and never reached row 3. Page down now clamps to the last row and
page up clamps to the first.

With no division left, a single-row table is safe, so the early return
only guards the empty table again, matching scroll_to_top and
scroll_to_bottom.
2026-09-17 17:38:37 -06:00
Dark-Alex-17 1d936c5cb5 fix(radarr): serialize the credit type under the same key it is read from
Radarr sends and accepts the credit type as "type" in both directions,
but the field was only renamed for deserialization, so serializing a
Credit emitted "creditType" and a to_value round trip could not be read
back. Credit is only deserialized in production, so this affects tests
and any future serialization of the record, not the live API traffic.
2026-09-17 15:49:12 -06:00
Dark-Alex-17 7b6d595397 fix(radarr): model the download status as a DownloadStatus enum
Radarr was the only tree still holding DownloadRecord.status as a bare
String and comparing it against literals. It now carries its own
DownloadStatus enum, shaped exactly like the Sonarr, Lidarr and Readarr
copies, and is guarded with from_json_or_default so an unrecognised
status degrades to Unknown instead of failing the whole queue fetch.

The row-style decorator and get_movie_status compare against the enum
variants. The status cell is never rendered in the Radarr tree, so no
snapshot changes; the CLI JSON output is unchanged for every real value
since the enum serializes to the same camelCase strings.
2026-09-17 15:46:49 -06:00
Dark-Alex-17 25da032f02 test(lidarr): give the download record fixture distinct album and artist ids
The shared download record held id, album id, and artist id all equal to
1, so reading the wrong one of the three could not fail any test that
uses the fixture. Move artist id to 3 and id to 9, keeping album id at 1
so the fully populated album view still shows its track as downloading,
and update the three handler assertions that named the old id.
2026-09-17 15:36:27 -06:00
Dark-Alex-17 e9c323c4e8 test(sonarr): cover the episode row style branches
decorate_with_row_style had no unit tests, so every one of its seven
return sites could be swapped for another style without a failure. Add
one test per branch, including the ordering cases where the download
match precedes the monitored guard and the monitored guard precedes the
air date check, using a local download fixture with distinct episode,
other-episode, and download ids.
2026-09-17 15:30:16 -06:00
Dark-Alex-17 289abbd8eb test(readarr): populate the book fixture with statistics
The shared Book fixture left statistics as None, so every author details
snapshot rendered the missing-statistics N/A cells and the populated
branch of the Files and Size columns was only exercised by one test.
Give the fixture distinct, non-default counts and a size that formats to
a value different from the dedicated statistics test.
2026-09-17 15:19:16 -06:00
Dark-Alex-17 a68de41025 fix: fall back to the default when a servarr returns an unknown enum value
A Servarr build can emit an enum value this app has no name for, either
as a string it does not recognise or as a bare integer for a value the
build itself cannot name. Until now any such value in a response failed
the whole payload, so one unexpected artist status, download status,
task name, series type, minimum availability, credit type, or security
setting emptied the entire view with "Failed to parse response!".

Every enum-typed field on a struct the app only ever deserializes and
displays now uses from_json_or_default, so an unrecognised value
degrades to that enum's default and the rest of the record is kept.
Known values still map exactly as before and serialization is untouched.

Fields on request bodies (Add*Body, Add*Options, Edit*Params, the root
folder bodies) are deliberately left alone: those structs are only ever
serialized, so the attribute would be meaningless there. No candidate
struct is round-tripped: every edit and toggle in the app re-fetches
the raw JSON value and patches it by key, so the fallback can never be
written back to a server as a real setting.

The one Option field, the security config's authentication_required,
also carries serde(default), because deserialize_with on an Option turns
a missing key into a hard error. An unknown value there yields None.

Verified by mutation. Removing the attribute from one field per tree
fails exactly that field's test and nothing else. Dropping default from
the Option field fails only the missing-key test with "missing field
authenticationRequired"; dropping deserialize_with from it fails only
the unknown-value test. All 21 new fallback tests fail against the
unguarded code with "invalid type: integer 2, expected string or map".
2026-09-17 15:08:52 -06:00
Dark-Alex-17 9d0973352f feat(lidarr): highlight tracks whose album is downloading or awaiting import
Lidarr queues whole albums rather than individual tracks, so a track row
is styled from the queue entry whose albumId matches the track's albumId,
mirroring the Sonarr episode row logic. Tracks that already have a file
keep the downloaded style regardless of the queue.
2026-09-17 14:50:27 -06:00