https://github.com/hollanbm/renamarr
automatically scans and renames files using the sonarr/radarr API
https://github.com/hollanbm/renamarr
radarr radarr-api radarr-companion sonarr sonarr-api sonarr-companion
Last synced: 17 days ago
JSON representation
automatically scans and renames files using the sonarr/radarr API
- Host: GitHub
- URL: https://github.com/hollanbm/renamarr
- Owner: hollanbm
- License: mit
- Created: 2024-04-25T03:38:13.000Z (about 2 years ago)
- Default Branch: main
- Last Pushed: 2026-04-18T20:40:08.000Z (25 days ago)
- Last Synced: 2026-04-18T21:27:59.501Z (25 days ago)
- Topics: radarr, radarr-api, radarr-companion, sonarr, sonarr-api, sonarr-companion
- Language: Python
- Homepage:
- Size: 491 KB
- Stars: 61
- Watchers: 4
- Forks: 3
- Open Issues: 4
-
Metadata Files:
- Readme: README.md
- License: LICENSE
- Agents: AGENTS.md
Awesome Lists containing this project
README
# Renamarr
[](https://codecov.io/gh/hollanbm/renamarr)
## Quick Start
### docker
1. Copy/Rename [config.yml.example](example/config.yml.example) to `config.yml`
2. Update `config.yml` as needed.
- See [Configuration](#configuration) for further explanation
3. Bring up app using provided [docker-compose.yml](example/docker-compose.yml)
#### Troubleshooting
Image tags ending in `-dev` can be used for troubleshooting purposes, but are not intended for normal usage. Pre-release images are tagged with their specific release version and do not change or overwrite the `latest` or `latest-dev` tags.
## How it works
### Renamarr
This job uses the [Sonarr API](https://sonarr.tv/docs/api/)/[Radarr API](https://radarr.video/docs/api/) to do the following
- Iterate over all items (Movies or Series)
- Checks if any items need to be renamed
- Radarr [get_api_v3_rename](https://radarr.video/docs/api/#/RenameMovie/get_api_v3_rename)
- Sonarr [get_api_v3_rename](https://sonarr.tv/docs/api/#/RenameEpisode/get_api_v3_rename)
- Triggers a rename on any item that need be renamed
- Series renames are batched up, for one rename call per series
- Movie renames are initiated per movie.
- Example, 1 movie, 2 files. There will be 2 rename API calls
#### Analyze Files
This config option is useful if you have audio/video codec information as part of your mediaformat, and you are transcoding files after import. This will initiate a rescan of the files in your library, so that the mediainfo will be updated. Then renamarr will come through and detect changes, and rename the files
#### Rename Folders (Sonarr Only)
This config option will rename series folders, when they no longer match your configured MediaFormat
- uses [/api/v3/series/{id}/folder](https://sonarr.tv/docs/api/#/SeriesFolder/get_api_v3_series__id__folder) endpoint to determine if the series folder requires an update
- uses [/api/v3/series/editor](https://sonarr.tv/docs/api/#v3/tag/serieseditor/PUT/api/v3/series/editor) endpoint to update series rootFolderPath to it's current value
- moving the folder in place
- Series are processed in bulk at the end of the run, **per root folder**
### Series Scanner (Sonarr Only)
This job uses the [Sonarr API](https://sonarr.tv/docs/api/) to do the following
- Iterate over continuing [series](https://sonarr.tv/docs/api/#/Series/get_api_v3_series)
- If a series has an episode airing within `config.sonarr[].series_scanner.hours_before_air`
- default value of 4, max value of 12
- OR
- An episode that has aired previously
- With a title of TBA (excluding specials)
- will trigger a series refresh, to hopefully pull new info from The TVDB
This should prevent too many API calls to the TVDB, refreshing individual series, hourly
### Usage
The application runs immediately on startup, and then continue to schedule jobs every hour (+- 5 minutes) after the first execution.
Logs are always written to stdout.
### File Logging
Set `sonarr[].renamarr.log_to_file` or `radarr[].renamarr.log_to_file` to `true` to enable per-instance log files. If the target log path is not writable, renamarr logs a warning to stdout and continues running without logging to file.
When enabled, logs for that instance are written under `/logs` using one of these paths:
- `sonarr/.log`
- `radarr/.log`
_Don't forget to mount /logs outside the container to persist log files_
_To avoid permission issues when creating log files, set the user option in docker-compose to match the desired runtime UID/GID._
#### Logging Configuration and Defaults
| Environment Variable | Description | Default |
| -------------------- | --------------------------------------------------------- | -------- |
| `LOG_LEVEL` | Log level passed to Loguru for stdout and file sinks. | `INFO` |
| `LOG_ROTATION` | Rotation schedule passed to Loguru for file log rotation. | `00:00` |
| `LOG_RETENTION` | Retention period passed to Loguru for rotated log files. | `7 days` |
_For more details on `LOG_RETENTION` or `LOG_ROTATION` values, see the [official documentation](https://loguru.readthedocs.io/en/stable/overview.html#easier-file-logging-with-rotation-retention-compression)_
### Configuration
| Name | Type | Required | Default Value | Description |
| ------------------------------------------ | ------- | -------- | ------------- | ------------------------------------------------------------------------------------------------------------------------------------------------ |
| `sonarr` | Array | Yes | [] | One or more sonarr instances |
| `sonarr[].name` | string | Yes | N/A | user friendly instance name, used in log messages |
| `sonarr[].url` | string | Yes | N/A | url for sonarr instance |
| `sonarr[].api_key` | string | Yes | N/A | api_key for sonarr instance |
| `sonarr[].series_scanner.enabled` | boolean | No | False | enables/disables series_scanner functionality |
| `sonarr[].series_scanner.hourly_job` | boolean | No | False | disables hourly job. App will exit after first execution |
| `sonarr[].series_scanner.hours_before_air` | integer | No | 4 | The number of hours before an episode has aired, to trigger a rescan when title is TBA |
| `sonarr[].renamarr.enabled` | boolean | No | False | enables/disables renamarr functionality |
| `sonarr[].renamarr.hourly_job` | boolean | No | False | disables hourly job. App will exit after first execution |
| `sonarr[].renamarr.analyze_files` | boolean | No | False | This will initiate a rescan of the files in your library. This is helpful if you are transcoding files, and the audio/video codecs have changed. |
| `sonarr[].renamarr.rename_folders` | boolean | No | False | This will rename series folders when the current series folder no longer matches your MediaFormat |
| `sonarr[].renamarr.log_to_file` | boolean | No | False | writes logs for this Sonarr instance to `/logs/sonarr/.log` with daily rotation |
| `radarr[].renamarr.enabled` | boolean | No | False | enables/disables renamarr functionality |
| `radarr[].renamarr.hourly_job` | boolean | No | False | disables hourly job. App will exit after first execution |
| `radarr[].renamarr.analyze_files` | boolean | No | False | This will initiate a rescan of the files in your library. This is helpful if you are transcoding files, and the audio/video codecs have changed. |
| `radarr[].renamarr.log_to_file` | boolean | No | False | writes logs for this Radarr instance to `/logs/radarr/.log` with daily rotation |
### Local Development
See [Local Development](docs/local-development.md) for local development requirements, environment details, and startup commands.
Dependency audits are run with `uv audit --frozen --preview-features audit`.