Sign inSign up

tommythebeast/arrstalledhandler

By tommythebeast

•Updated over 1 year ago

ArrStalledHandler is a Python script to manage stalled downloads in Radarr and Sonarr.

Image
Integration & delivery
0

50K+

tommythebeast/arrstalledhandler repository overview

⁠ArrStalledHandler

ArrStalledHandler is a Python-based script designed to handle stalled downloads in Radarr⁠, Sonarr⁠, Lidarr⁠ and Readarr⁠ by taking actions such as removing, blocklisting, or blocklisting and re-searching for the affected items. It supports configuration through a .env file, logging for visibility, and is deployable via Docker for ease of use.

This repository is licensed under the GNU General Public License v3.0 (GPLv3)⁠.

Created by Tommy Vange Rød⁠. You can see the full list of credits here⁠.

This project is available on GitHub⁠, Docker Hub⁠ and the Unraid Community App store⁠.

Publish Docker image Check docker build


⁠Features

  • Automatic Handling of Stalled Downloads:
    • Detect stalled downloads based on error messages from Radarr/Sonarr/Lidarr/Readarr queues.
    • Detect download stuck on "Downloading Metadata" in qBittorrent and treat them as stalled.
    • Perform configurable actions such as:
      • Remove the stalled download.
      • Blocklist the stalled download.
      • Blocklist and re-trigger a search for the movie or episodes.
  • Database Tracking:
    • Tracks stalled downloads in a SQLite database to ensure actions are only taken after a specified timeout period.
  • Logging:
    • Verbose and informative logging controlled via configuration.
  • Docker Support:
    • Easily deployable with Docker and customizable run intervals.

⁠Configuration

The script is fully configurable using environment variables specified in a .env file. Below is a description of each configuration option:

⁠.env Variables
VariableDescriptionDefault Value
RADARR_URLThe base URL for Radarr's API. Example: http://localhost:7878,http://otherhost:7878.None (required)
RADARR_API_KEYThe API key for Radarr (found in Radarr settings).None (required)
SONARR_URLThe base URL for Sonarr's API. Example: http://localhost:8989,http://otherhost:8989.None (required)
SONARR_API_KEYThe API key for Sonarr (found in Sonarr settings).None (required)
LIDARR_URLThe base URL for Lidarr's API. Example: http://localhost:8686,http://otherhost:8686.None (required)
LIDARR_API_KEYThe API key for Lidarr (found in Radarr settings).None (required)
READARR_URLThe base URL for Readarr's API. Example: http://localhost:8787,http://otherhost:8787.None (required)
READARR_API_KEYThe API key for Readarr (found in Sonarr settings).None (required)
STALLED_TIMEOUTTime (in seconds) a download must remain stalled before actions are taken.3600 (1 hour)
STALLED_ACTIONAction to perform on stalled downloads: REMOVE, BLOCKLIST, or BLOCKLIST_AND_SEARCH.BLOCKLIST_AND_SEARCH
VERBOSEEnable verbose logging for debugging (true or false).false
RUN_INTERVALTime (in seconds) between script executions when running in Docker.300 (5 minutes)
COUNT_DOWNLOADING_METADATA_AS_STALLEDWeather the script should count downloads with the status of "Downloading Metadata" as stalled.false

To disable Radarr or Sonarr; leave the URL empty in the environment. If the service does not have a URL, then it is skipped. Multple services are allowed by using comma seperated values.


⁠How It Works

⁠Script Workflow
  1. Initialization:

    • The script initializes a SQLite database (stalled_downloads.db) to track stalled downloads.
    • It fetches the current queue from Radarr and Sonarr APIs.
  2. Detect Stalled Downloads:

    • The script identifies stalled downloads based on the error message: "The download is stalled with no connections".
    • [Optional] The script treats downloads with the error message "qBittorrent is downloading metadata" as stalled.
  3. Timeout Check:

    • Downloads are only handled if they have been stalled longer than the configured STALLED_TIMEOUT.
  4. Perform Configured Action:

    • Based on the STALLED_ACTION setting:
      • REMOVE: Removes the stalled download.
      • BLOCKLIST: Removes and blocklists the stalled download.
      • BLOCKLIST_AND_SEARCH: Removes, blocklists, and re-triggers a search for the movie or episodes.
  5. Logging:

    • Logs detailed information about each action for visibility.
  6. Repeat:

    • When running in Docker, the script waits for the RUN_INTERVAL duration and repeats the process.

⁠Deployment

⁠Unraid Deployment

Picture of application in the Unraid Community App store

  1. Install the Community Apps extension as documented in this guide⁠.
  2. Go to the Apps-section in your Unraid web-ui.
  3. Search for ArrStalledHandler.
  4. Click Install on the application.
  5. Fill out the variables according to the Configuration⁠.
  6. Click Apply.

Now the container should automatically start up and start handling your stalled downloads.

⁠Docker Deployment (Docker Hub⁠)

Docker compose

More info at Docker Docs⁠.

services:
  arr-stalled-handler:
    image: tommythebeast/arrstalledhandler:latest
    container_name: ArrStalledHandler
    restart: unless-stopped
    environment:
      RADARR_URL: "http://localhost:7878,http://otherhost:7878"
      RADARR_API_KEY: "your_radarr_api_key,your_2nd_radarr_api_key"
      SONARR_URL: "http://localhost:8989,http://otherhost:8989"
      SONARR_API_KEY: "your_sonarr_api_key,your_2nd_sonarr_api_key"
      LIDARR_URL: "http://localhost:8686,http://otherhost:8686"
      LIDARR_API_KEY: "your_lidarr_api_key,your_2nd_lidarr_api_key"
      READARR_URL: "http://localhost:8787,http://otherhost:8787"
      READARR_API_KEY: "your_readarr_api_key,our_2nd_readarr_api_key"
      STALLED_TIMEOUT: "3600"
      STALLED_ACTION: "BLOCKLIST_AND_SEARCH"
      VERBOSE: "false"
      RUN_INTERVAL: "300"
      COUNT_DOWNLOADING_METADATA_AS_STALLED: "false"

Docker CLI

More info at Docker Docs⁠.

Multi-line:

docker run -d \
  --name=ArrStalledHandler \
  -e RADARR_URL=http://localhost:7878,http://otherhost:7878 \
  -e RADARR_API_KEY=your_radarr_api_key,your_2nd_radarr_api_key \
  -e SONARR_URL=http://localhost:8989,http://otherhost:8989 \
  -e SONARR_API_KEY=your_sonarr_api_key,your_2nd_sonarr_api_key \
  -e LIDARR_URL=http://localhost:8686,http://otherhost:8686 \
  -e LIDARR_API_KEY=your_lidarr_api_key,your_2nd_lidarr_api_key \
  -e READARR_URL=http://localhost:8787,http://otherhost:8787 \
  -e READARR_API_KEY=your_readarr_api_key,our_2nd_readarr_api_key \
  -e STALLED_TIMEOUT=3600 \
  -e STALLED_ACTION=BLOCKLIST_AND_SEARCH \
  -e VERBOSE=false \
  -e RUN_INTERVAL=300 \
  -e COUNT_DOWNLOADING_METADATA_AS_STALLED=false \
  --restart unless-stopped \
  tommythebeast/arrstalledhandler:latest

One line:

docker run -d --name=ArrStalledHandler -e RADARR_URL=http://localhost:7878,http://otherhost:7878 -e RADARR_API_KEY=your_radarr_api_key,your_2nd_radarr_api_key -e SONARR_URL=http://localhost:8989,http://otherhost:8989 -e SONARR_API_KEY=your_sonarr_api_key,your_2nd_sonarr_api_key -e LIDARR_URL=http://localhost:8686,http://otherhost:8686  -e LIDARR_API_KEY=your_lidarr_api_key,your_2nd_lidarr_api_key -e READARR_URL=http://localhost:8787,http://otherhost:8787 -e READARR_API_KEY=your_readarr_api_key,our_2nd_readarr_api_key -e STALLED_TIMEOUT=3600 -e STALLED_ACTION=BLOCKLIST_AND_SEARCH -e VERBOSE=false -e RUN_INTERVAL=300 -e COUNT_DOWNLOADING_METADATA_AS_STALLED=false --restart unless-stopped tommythebeast/arrstalledhandler:latest
⁠Docker Deployment (Manual)
  1. Clone the Repository:

    git clone https://github.com/your-username/ArrStalledHandler.git
    cd ArrStalledHandler
    
  2. Configure Environment:

    Create a .env file and populate it with the required variables:

    RADARR_URL=http://localhost:7878,http://otherhost:7878
    RADARR_API_KEY=aaaabbbbcccc111122223333,xxxxyyyyzzzz777788889999
    SONARR_URL=http://localhost:8989,http://otherhost:8989
    SONARR_API_KEY=aaaabbbbcccc111122223333,xxxxyyyyzzzz777788889999
    LIDARR_URL=http://localhost:8686,http://otherhost:8686
    LIDARR_API_KEY=aaaabbbbcccc111122223333,xxxxyyyyzzzz777788889999
    READARR_URL=http://localhost:8787,http://otherhost:8787
    READARR_API_KEY=aaaabbbbcccc111122223333,xxxxyyyyzzzz777788889999
    STALLED_TIMEOUT=3600
    STALLED_ACTION=BLOCKLIST_AND_SEARCH
    VERBOSE=false
    RUN_INTERVAL=300
    COUNT_DOWNLOADING_METADATA_AS_STALLED=false
    
  3. Build the Docker Image:

    docker-compose build .
    
  4. Run the Docker Container:

    docker-compose up -d
    
⁠Local Installation

Requires Python 3.13

  1. Clone the Repository:

    git clone https://github.com/your-username/ArrStalledHandler.git
    cd ArrStalledHandler
    
  2. Install Dependencies:

    pip install -r requirements.txt
    
  3. Configure Environment:

    Create a .env file and populate it with the required variables:

    RADARR_URL=http://localhost:7878,http://otherhost:7878
    RADARR_API_KEY=aaaabbbbcccc111122223333,xxxxyyyyzzzz777788889999
    SONARR_URL=http://localhost:8989,http://otherhost:8989
    SONARR_API_KEY=aaaabbbbcccc111122223333,xxxxyyyyzzzz777788889999
    LIDARR_URL=http://localhost:8686,http://otherhost:8686
    LIDARR_API_KEY=aaaabbbbcccc111122223333,xxxxyyyyzzzz777788889999
    READARR_URL=http://localhost:8787,http://otherhost:8787
    READARR_API_KEY=aaaabbbbcccc111122223333,xxxxyyyyzzzz777788889999
    STALLED_TIMEOUT=3600
    STALLED_ACTION=BLOCKLIST_AND_SEARCH
    VERBOSE=false
    RUN_INTERVAL=300
    COUNT_DOWNLOADING_METADATA_AS_STALLED=false
    
  4. Run the Script:

    python main.py
    

⁠Logging

  • Logs are written to the console and are controlled by the VERBOSE environment variable.
  • If VERBOSE is set to true, debug-level logs are enabled.

Example log output:

INFO: Checking stalled downloads in Radarr...
INFO: Handling Download ID 1462067687 in Radarr (elapsed time: 400 seconds).
INFO: Triggering search for Movie ID 770 in Radarr using Command API...
INFO: Script execution completed. Sleeping for 300 seconds...

⁠Troubleshooting

  1. Script Not Executing Actions:
    • Check if STALLED_TIMEOUT is too high.
    • Verify the stalled downloads are correctly detected via Radarr/Sonarr queues.

⁠Credits

⁠Author

You can find more of my work on my GitHub profile⁠ or connect with me on LinkedIn⁠.

⁠Contributors

Huge thanks to everyone who dedicates their valuable time to improving, perfecting, and supporting this project!


⁠GNU General Public License v3.0 (GPLv3)

The GNU General Public License v3.0 (GPLv3) is a free, copyleft license for software and other creative works. It ensures your freedom to share, modify, and distribute all versions of a program, keeping it free software for everyone.

Full license can be read here⁠ or at gnu.org⁠.

⁠Key Points:

  1. Freedom to Share and Change:

    • You can distribute copies of GPLv3-licensed software.
    • Access the source code.
    • Modify the software.
    • Create new free programs using parts of it.
  2. Responsibilities:

    • If you distribute GPLv3 software, pass on the same freedoms to recipients.
    • Provide the source code.
    • Make recipients aware of their rights.
  3. No Warranty:

    • No warranty for this free software.
    • Developers protect your rights through copyright and this license.
  4. Marking Modifications:

    • Clearly mark modified versions to avoid attributing problems to previous authors.

Tag summary

Content type

Image

Digest

sha256:dac7879f6…

Size

48.6 MB

Last updated

over 1 year ago

docker pull tommythebeast/arrstalledhandler