Skip to content

Latest commit

 

History

History
473 lines (351 loc) · 48.1 KB

File metadata and controls

473 lines (351 loc) · 48.1 KB
id rules
slug /rules
description Rules configurations and basic information about using rules.
title Rules

import CodeBlock from "@theme/CodeBlock"; import InlineTooltip from "@site/src/components/InlineTooltip";

Rules are the core of Maintainerr. They evaluate media from your configured media server based on the parameters you set. If a media item matches a rule, it is added to a collection.

Media in a collection will remain there for the number of days you specify. After that period, Maintainerr will delete the media from disk and any connected external applications. If a collections media item no longer matches a rule, it will be removed from it.

:::note Rule Handling Rule handling is a batch process that runs every 8 hours (this interval can be changed in the settings). During each run, Maintainerr checks all your rules and updates collections by adding or removing media items as needed. You can manually trigger this process with the Run Rules button on the 'Rules' page.

:::

:::info Watch History Rules Rules that depend on watch history, such as Plex.lastViewedAt, Jellyfin.lastViewedAt, and the equivalent Emby watch-state properties, treat watch-history lookup failures as an unknown value. Maintainerr does not interpret a failed lookup as "never watched".

In practice, that means there is a difference between:

  • no recorded watch history for an item
  • watch history could not be loaded at all

This distinction matters most for exists and not exists checks on watch-history-backed rules.

Practical rule behavior:

  • lastViewedAt BEFORE 90 days means the item has a real last-viewed date, and that date is older than 90 days.
  • lastViewedAt NOT_EXISTS is the correct way to match items with no recorded watch history.
  • If you want both cases, express them separately, such as lastViewedAt NOT_EXISTS OR lastViewedAt BEFORE 90 days.

This also means Maintainerr keeps these states separate on purpose:

  • watched before, with a real timestamp
  • never watched, so no timestamp exists
  • watch-history lookup failed, so the value is unknown

The watch-history getters keep these cases separate: a confirmed empty history returns no watch date, while server or history lookup failures stay unknown instead of falling back to an empty history result. That prevents outages from being misread as "never watched" and keeps NOT_EXISTS from matching the wrong items.

Last play date (including unfinished) (lastPlayedAt) is the played counterpart of Last view date. It answers with the last time an item was played at all, including a play someone stopped early, while lastViewedAt only counts a play that got far enough to be a view. It is offered for Plex, Jellyfin, Emby, Tautulli, Tracearr, and Streamystats, and it treats a failed lookup as unknown in the same way. On Plex both properties report the same date, because Plex already moves an item's last-viewed date on any playback.

:::

:::warning Plex Watchlist Rules Watchlisted by (Plex.watchlist_isListedByUsers) and Is Watchlisted (Plex.watchlist_isWatchlisted) do not only check the current Plex user. Maintainerr scans every user still returned by the Plex server account list and then tries to resolve the related Plex.tv / community usernames and UUIDs needed for watchlist lookups.

Current limitations and behavior to expect:

  • There is currently no per-user exclude option for Plex watchlist scanning.
  • If a removed Plex friend is still returned by the Plex server account list, Maintainerr can still try to scan that user.
  • Private watchlists can produce expected warnings because those watchlists are not visible to Maintainerr.
  • These rules depend on Plex cloud services such as plex.tv and community.plex.tv, not only your local Plex server.
  • Watchlisted by remains experimental and is generally more fragile than purely local metadata rules.

Troubleshooting tips:

  • Verify the affected user is still returned by the Plex server account list.
  • Verify the watchlist is public if you expect Maintainerr to see it.
  • Do not expect reauthing Plex or changing the local Plex IP to fix this specific lookup path by itself.
  • Test Media can still work while a full rule run fails with repeated Plex cloud timeouts such as ECONNABORTED. That usually points to repeated cloud lookups during the full run, not necessarily a local Plex configuration problem.

:::

Creating rules

General

General info about the rule. Some of the information specified here will be shown on the generated collection. In here you also specify how to handle the collection.

Parameter Description
Name The Rule and Collection name
Description Description of the Rule. This is also used as the Collection's description
Library Which media library to use
Media type The type of TV media the rules will apply to, either the entire show, only seasons or only episodes
Radarr server The server that Radarr specific rules and actions will be applied to
Radarr action Delete, unmonitor, or change the quality profile of movies in Radarr
Sonarr server The server that Sonarr specific rules and actions will be applied to
Sonarr action Delete, unmonitor, or change the quality profile in Sonarr. Season rules can also delete or unmonitor the parent show if it becomes empty.
Sportarr server The server that Sportarr-specific rules and actions will be applied to
Sportarr action Delete or unmonitor leagues, seasons, or events in Sportarr; whole-league rules can also change the quality profile
Media server action Delete media from your media server directly. Only applicable when no *arr server is selected.
Do nothing action No action will be taken on the media in this collection.
Active If inactive, the rule won't run
Show on library recommended Show the rule's collection on the library recommended screen
Show on home Show the rule's collection on the home screen
Add list exclusions Prevent *arr import lists from re-adding media that has been removed by Maintainerr
Tag this content Tag matching movies (Radarr) or shows (Sonarr) with a tag named after this rule group while they are in the collection, removed when they leave. Only shown for movie collections with a Radarr server selected, or whole-show collections with a Sonarr server selected.
Media deleted after days Amount of days media will live in the collection before deletion
Clean up leftover folders (BETA) When enabled, Maintainerr removes the folder the *arr leaves behind after deleting files one at a time, along with its sidecars (subtitles, .nfo, artwork). Off by default. Only shown when the selected action strands a folder. Requires the media library mounted into Maintainerr at the same path as the *arr. See Leftover folder cleanup.
Use rules Disable the rule engine, for when you want to add media to the collection manually
Force reset Seerr record Force resets the Seerr record by deleting any requests instead of relying on availability-sync. 'Enable CSRF Protection' needs to be disabled in Seerr's settings for this to work.
Custom collection Use a manually created collection. Maintainerr will never automatically add or remove this collection from your media server.
Custom collection name The name of the existing manually managed collection to use

Maintainerr only shows Force reset Seerr record for movie, show, and season rules. Episode rules always rely on Seerr's normal availability sync because Seerr tracks requests at the season level, not per episode. If an older episode rule still has this option saved, re-saving the rule clears it.

When you choose Change quality profile and search for Radarr or Sonarr, Maintainerr shows a quality profile selector for the chosen server. This action does not use Take action after days; it changes the item's quality profile immediately when the collection action runs.

The Tag this content option keeps a Radarr/Sonarr tag named after the rule group on each matching item for as long as it stays in the collection, and removes it when the item leaves. Because Sonarr tags apply to the whole series, the option is offered for movie collections (Radarr) and whole-show collections (Sonarr) only - not season or episode collections. The tag is created on the *arr instance if missing, the rule group's name is normalized to the tag character set Radarr/Sonarr accept (lowercase letters, numbers, and hyphens), and tagging is best-effort, so it never blocks a rule run. Renaming a rule group applies the new tag on the next membership change but leaves the previous tag in place until you remove it.

For Sonarr season rules, additional actions are available to also clean up the parent show when it becomes empty after season processing.

Never-downloaded later seasons do not block those parent-show cleanup actions. Maintainerr only treats a monitored season as still keeping the show active when Sonarr reports episode files for that season.

Radarr and Sonarr actions

Each *arr action affects three independent things: whether the movie or series record stays in Radarr or Sonarr, whether the media files are deleted from disk, and whether the containing folder is removed. The tables below make all three axes explicit.

Radarr movie actions

Action Radarr record Files Containing folder
Delete removed deleted deleted (Radarr removes it)
Unmonitor and delete files kept, set to unmonitored deleted (each file individually) stranded - opt-in cleanup available
Unmonitor and keep files kept, set to unmonitored kept kept
Change quality profile and search kept, profile changed kept kept

Delete calls Radarr's DELETE /movie/{id} with deleteFiles=true. Radarr removes its own record and the movie folder in one operation, so no folder is left behind.

Unmonitor and delete files calls Radarr's PUT /movie/{id} with monitored=false, then issues a separate DELETE /moviefile/{id} for each file. The Radarr record stays in the library as an unmonitored entry with no file. Because Radarr removes only the individual files and not the folder, the folder and any sidecars (subtitles, .nfo, artwork) remain on disk - that is what the optional leftover folder cleanup removes. The unmonitored record acts as a tombstone: it prevents an import-list or collection sync from re-adding the movie automatically. If Add list exclusions is enabled, an import exclusion is also added.

Unmonitor and keep files only changes the monitored flag. No files or folders are touched.

Sonarr show actions

Action Sonarr record Files Containing folder
Delete entire show removed deleted deleted (Sonarr removes it)
Unmonitor show + seasons, delete all episodes kept, set to unmonitored all episode files deleted (each individually) series folder stranded - opt-in cleanup available
Unmonitor show, delete existing episodes kept, set to unmonitored already-downloaded episode files deleted (each individually) series folder stranded - opt-in cleanup available
Unmonitor show + seasons, keep files kept, set to unmonitored kept kept
Change quality profile and search kept, profile changed kept kept

Delete entire show calls Sonarr's DELETE /series/{id} with deleteFiles=true. Sonarr removes its own record and the series folder in one operation.

Unmonitor show + seasons, delete all episodes and Unmonitor show, delete existing episodes both keep the Sonarr record but delete episode files one at a time via DELETE /episodefile/{id}. The difference is scope: the first deletes every episode file Sonarr knows about; the second deletes only the files that are currently on disk. Both strand the series folder and its sidecars - the optional leftover folder cleanup removes it.

Sonarr season actions

Action Season/show record Files Containing folder
Unmonitor and delete season season unmonitored, show kept episode files deleted (each individually) season folder stranded - opt-in cleanup available
Unmonitor and delete season + delete show if empty season unmonitored, show removed when no files remain episode files deleted (each individually) season folder stranded, series folder removed if show deleted
Unmonitor and delete existing episodes season unmonitored, show kept already-downloaded episode files deleted (each individually) season folder stranded - opt-in cleanup available
Unmonitor season and keep files season unmonitored, show kept kept kept
Unmonitor season + unmonitor show if empty season and show unmonitored, both kept kept kept

Season delete actions unmonitor the season in Sonarr and delete its episode files one at a time via DELETE /episodefile/{id}. The season folder and its sidecars are stranded because only the files are removed. The series folder is untouched unless the show itself is also deleted.

Sonarr episode actions

Action Episode/season/show record File Folder
Unmonitor and delete episode episode unmonitored, season and show kept deleted season folder unchanged (shared with other episodes)
Unmonitor and keep file episode unmonitored, season and show kept kept kept

Episode delete actions share the season folder with other episodes, so the folder is never removed by this action. No leftover folder cleanup is offered for episode rules.

Sportarr actions

Sportarr runs alongside Sonarr and Radarr; you can configure all three at once. Because Plex reports both TV and sports libraries as the same 'show' type, each collection over a show library names a single manager: pick either Sonarr or Sportarr for that collection (not both). Different collections can use different managers, so the same library can have some collections managed by Sonarr and others by Sportarr.

  • League rules can delete an entire league, unmonitor it while keeping files, or change its quality profile.
  • Season rules can unmonitor a season and delete its event files, or unmonitor it while keeping files.
  • Event rules can delete an event file, or unmonitor the event while keeping its file.

:::warning Disabling an active rule group does not empty its linked collection. Existing tracked items stay there until the rule group is re-enabled or deleted.

If you want to clear the collection first, update the rule so it matches nothing, run the rule once, and then disable it. :::

TV media type

With the Media type parameter, you specify which type of media to target in a TV library. This allows you to run rules on shows, seasons, or episodes.

For example, you might create a rule group that selects and deletes old or watched seasons of a TV show, while keeping newer seasons untouched. Alternatively, you could target watched episodes and set them to unmonitored in Sonarr.

:::note

  • Plex collections cannot contain mixed media types. Therefore, Maintainerr restricts each rule group / collection to a single media type.

  • Running rules on episodes is slower than on shows or seasons, as Maintainerr must process a larger volume of data.

:::

Custom collections

If you prefer to manage collections yourself or use a different tool, you can enable the Custom collection option. With this enabled, Maintainerr links the rule group to an existing collection instead of creating and deleting that collection on the media server itself.

This is separate from Use rules, which controls whether the rule engine fills the collection automatically, and from manually added items, which are tracked per item on the collection.

Sharing a custom collection across rule groups

Several rule groups can point at the same Custom collection name. They all link to the same collection on the media server, but each rule group keeps its own tracking row and per-card item count. The count on a rule group's collection card is the number of rows that rule group tracks, not the size of the underlying media-server collection.

On Jellyfin and Emby, that shared custom collection can also span libraries because BoxSets are server-global. A movie rule group and a show rule group can therefore link the same custom collection name there. Plex collections remain library-scoped, so cross-library custom-collection sharing is not available on Plex.

After every rule run, items present in the shared media-server collection that aren't claimed by any of the linked rule groups are imported into each linked rule group as manual rows. This keeps Maintainerr from stripping those items out. The import is not filtered by media type, so an item added to the shared collection by one rule group can show up in another linked rule group's tracked count, including rule groups whose media type doesn't match.

:::note

The per-card count therefore mixes rule-owned items with these shared manual rows. A rule group whose criteria match nothing can still display a non-zero count when it shares its custom collection name with other rule groups.

:::

To drain items from a shared custom collection, re-enable the rule group that originally added them, change its criteria so it matches nothing, and run it. As noted in the warning above, disabling an active rule group by itself does not empty its linked collection.

Adding rules

Adding a rule is done by using the Add button next to a section title. If the button is not available, it means your current rule isn't finished yet.

A rule consists of at least 4 values. If the second value contains a custom value, a custom value parameter will also pop up.

Every rule after the very first rule in a group requires an explicit AND or OR operator. The editor keeps that rule incomplete until you choose one, and the API rejects a save with Operator is required for every rule after the first. The first rule of the whole group does not have an operator.

Param Description
Operator Action to take on the previous rule or section
First value The first value to compare with
Action The comparable action to take
Second value The second value to compare with
Custom value A custom value input

Sections

A section is a group of rules. Rules inside a section combine with the previous rule in that same section by using each rule's operator. The first rule of every later section carries the section-combine operator that combines that whole section with the previous section's result. The first rule of the whole group is the only rule without an operator.

Adding new sections

The New section button, at the bottom of the form, is only available if all rules are completed.

Both sections and individual rules can be reordered by dragging their handle in the rule editor. Maintainerr evaluates rules from top to bottom, so reordering can change how your sections and chained operators behave.

Operators

There are 2 operator choices, both explained below. The choice of operator defines what happens to the result of each section or rule.

  • The Operator selector on a non-first rule works inside the current section. AND evaluates only the media that already matched earlier rules in that same section. OR evaluates all media for that rule, then unions the new matches into the section result.
  • The Section Operator selector appears on the first rule of each later section. It does not change how rules inside that section run. After the section finishes, AND intersects that whole section result with the earlier sections' result, while OR unions that whole section result into the earlier sections' result.

AND

Using this operator, the rule will run against the result of the previous rule (or section). The output of the rule will then be passed on to the next rule.

OR

Using this operator, the rule will start off with all media and add its result to the previous rule (or section) result. The output of the rule will then be passed on to the next rule.

Actions

The action defines the way the first value and second value will be compared. The available actions are dependent on the type of the first value

Action Description Types
bigger Is the first value bigger than the second value ? number
smaller Is the first value smaller than the second value ? number
contains Does the first value contain the second value? Lists will confirm the existence of an exact match within the first value list number, text
contains (partial) Does the first value contain the second value ? Lists will confirm the existence of a partial match within the first value list number, text
contains (all items) Does the first value list contain all values from the second value list? text[]
not contains Does the first value lack the second value? Lists will indicate the absence of an exact match within the first value list. number, text
not contains (partial) Does the first value lack the second value ? Lists will indicate the absence of a partial match within the first value list. number, text
not contains (all items) Does the first value list fail to contain all values from the second value list? text[]
equals Is the first value equal to the second value ? number, text, date
not equals Is the first value unequal to the second value ? number, text, date
count equals Does the number of entries in the first value list equal the second value? text[]
count not equals Does the number of entries in the first value list differ from the second value? text[]
count bigger Is the number of entries in the first value list bigger than the second value? text[]
count smaller Is the number of entries in the first value list smaller than the second value? text[]
before Does the first value occur before the second value ? date
after Does the first value occur after the second value ? date
in last Does the first value occur in the last x amount of days ? date
in next Does the first value occur in the next x amount of days ? date
exists Does the first value exist at all? Useful for matching whether Maintainerr could resolve a value before comparing it. number, text, date, boolean, text[]
not exists Does the first value not exist? Useful for missing dates, empty watch history, or values that are not available for the item. number, text, date, boolean, text[]

The difference between Contains/Contains (exact) and Contains (partial) is only apparent with list values. When comparing a text list, Contains (exact) will only return true if the second value exactly matches any value in the first value list. Contains (partial) will return true if the first value list has a value that partially matches any value in the second value list.

List Examples

{`firstValue: - user1 - user2 - user3 secondValue: - use - ser - ser3 - user - ser1 - er3`} {`firstValue: - user1 - user2 - user3 secondValue: - user1 - user2 - user3 - user5`} {`firstValue: - user1 - user2 - user3 secondValue: - friend - james - wilhelm - frank`} {`firstValue: - user1 - user2 - user3 secondValue: - user1 - user2 - user5`} {`firstValue: - user1 - user2 - user3 - user7 secondValue: - user1 - user2 - user7`} {`firstValue: - user1 - user2 - user3 secondValue: - user1 - user5 - user8`} {`firstValue: - user1 - user2 - user3 secondValue: - use - friend - 1 - 2 - 3`}

Custom values

The second value field allows some custom values. The available custom values are dependent on the type of first value.

Action Description Types
Custom days This behavior depends on the selected action. In case of in_last or in_next, this translates to 'in the last (or next) x days'. in case of before the value will be translated to the current date subtracted by the amount of custom days. In all other cases, the amount of days will be added to the current date date
Custom date Takes a specific date date
Custom number Takes a specific number number
Custom text Takes a specific text text
Custom text (list) Takes a list in JSON format ["Jef", "Frank", "Wilhelm"]

ARR disk space rules

When you use Radarr or Sonarr disk space properties, Maintainerr may also ask you to choose which ARR path to evaluate.

  • Remaining disk space and Total disk space rules can target a specific configured path instead of assuming a single global root folder.
  • The path list is populated from the selected Radarr or Sonarr server.
  • For Total disk space, Maintainerr only shows paths where the server can report an accurate total size.

Per-user watch statistics

Tautulli, Tracearr, and Streamystats each offer three properties that count one person's viewing instead of everyone's: Times viewed by user, Watch time by user (minutes), and Last view date by user.

  • Choosing one of these properties adds a User field to the rule. Type to filter the list, then pick the username the property should answer for.
  • The list holds the usernames your media server reports. If you enter a name it does not report, Maintainerr refuses to save the rule. On Plex the list comes from Plex.tv, which can spell an account differently from the server's own list.
  • If Maintainerr cannot find the saved username on a later rule run, it treats the value as unknown for that item instead of reading it as 0 or "never watched". So renaming or deleting that account stops the rule from matching, rather than making it match your whole library.
  • Watch time by user (minutes) counts every minute played, not only finished views.
  • On Tautulli and Tracearr, the view count and last view date only count plays that reach the watched percentage, including a collection's Watched percent override. Streamystats has no such setting, so its view count counts every play session.
  • Maintainerr removes the username when you upload a rule to the community list, because it names someone in your household and would match nobody on anyone else's install. Pick a user again after importing a rule like this.

Streamystats does not track watching per season, so its three properties are unavailable for seasons. The Glossary lists availability for every key.

Episode and season retention rules (Sonarr)

Long-running shows, daily series especially, can grow to thousands of episodes. Four Sonarr properties let you build a rolling window that keeps only the newest downloaded episodes or seasons of a show and cleans up the rest.

  • Episode position by air date (1 = latest) (number, episode rules only) ranks every episode within its own show by air date, counting only episodes that are currently downloaded in Sonarr. The newest downloaded episode is rank 1, the next one rank 2, and so on. Episodes Sonarr knows about but has no file for do not take up a rank, and an episode airing without being downloaded never shifts the window. Specials (season 0), unaired episodes, and episodes without a valid air date never receive a rank, so rules never match them.
  • Season position by air date (1 = latest) (number, season rules only) is the same idea one level up: it ranks every season within its show by the air date of its newest downloaded episode. Seasons without any downloaded episode take no rank slot, and specials (season 0) are excluded.
  • Series title (text) is the show's title as Sonarr knows it. Matching is case-insensitive.
  • Series ID (number) is the show's id in Sonarr. Prefer this over the title for rules that delete: the id keeps working after a rename or when titles carry a year or region suffix. The easiest way to find it is the Test media feature: add a Series ID rule, test any episode of the show, and read the value from the result.

In every case the rank is computed fresh on each rule run from what is on disk at that moment. If Sonarr is unreachable during a run, affected items are skipped rather than treated as matches, so a temporary outage never causes unexpected deletions.

Both rank properties apply their window per show. Always pair them with a Series ID (or Series title) rule as shown below - without one, the same window applies to every show in the library, which is usually not what you want.

Keep the newest N episodes of a show

A "keep the newest 5 episodes" rule group looks like this:

  • Media type Episodes, with a Sonarr action such as Unmonitor and delete episode.
  • Rule 1: Episode position by air date (1 = latest) bigger than 5
  • Rule 2 (AND): Series ID equals the show's id

Every run, all downloaded episodes of that show except the 5 newest by air date enter the collection and are handled after Take action after days. When a new episode downloads, it takes rank 1 and the oldest episode of the kept window rotates out on the next run.

Keep the newest N seasons of a show

A "keep the newest 2 seasons" rule group looks like this:

  • Media type Seasons, with a Sonarr action such as Unmonitor and delete season.
  • Rule 1: Season position by air date (1 = latest) bigger than 2
  • Rule 2 (AND): Series ID equals the show's id

Every run, all seasons that have downloaded episodes, except the 2 with the newest downloaded episodes, enter the collection and are handled after Take action after days. When a new season starts downloading it becomes rank 1, and the oldest kept season rotates out on the next run. A season whose files have all been removed drops out of the ranking entirely; it does not linger in the collection.

Daily series

Both walkthroughs work unchanged for daily series:

  • Daily shows that use one season per year rank those year-seasons like any other season.
  • Some servers store daily episodes with only an air date and no episode number. Those episodes are matched to Sonarr by broadcast date, so Episode position by air date (1 = latest) still resolves. When two episodes of a date-only show share the same broadcast day, the newer one's rank is used, which errs on the side of keeping media.
  • Airing alone never changes anything: only a new download moves the window.

Movie scoping (Radarr)

Movie title (text, case-insensitive) and Movie ID (number) are the movie equivalents of Series title and Series ID: they pin a movie rule to specific movies without going through tags or collections. The same advice applies - prefer Movie ID for destructive rules, and use Test media to read a movie's id.