From 75670d9a90a746219871bce5669d7dc7e009e181 Mon Sep 17 00:00:00 2001 From: Benjamin Harder Date: Sun, 18 Feb 2024 22:41:32 +0100 Subject: [PATCH] BEAT TEST - Added Readarr Support (completely untested) --- .github/workflows/main.yml | 6 ------ README.md | 15 +++++++++++++++ config/config.conf-Example | 4 ++++ config/config.py | 10 ++++++++-- main.py | 19 ++++++++++++++++++- src/decluttarr.py | 5 +++++ src/remove_unmonitored.py | 4 +++- 7 files changed, 53 insertions(+), 10 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index abad074..53ce3c3 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -49,10 +49,4 @@ jobs: run: | docker buildx build --platform linux/amd64,linux/arm64 -t $IMAGE_NAME:$IMAGE_TAG -t $IMAGE_NAME:latest -f docker/Dockerfile --push . - # - name: "Build, Tag, and push the Docker image" - # env: - # IMAGE_NAME: ghcr.io/manimatter/decluttarr - # IMAGE_TAG: latest - # run: | - # docker buildx build --platform linux/amd64,linux/arm64 -t $IMAGE_NAME:$IMAGE_TAG -f docker/Dockerfile --push . diff --git a/README.md b/README.md index 009abe9..0a50bcd 100644 --- a/README.md +++ b/README.md @@ -63,6 +63,9 @@ services: # Lidarr - LIDARR_URL=http://lidarr:8686 - LIDARR_KEY=$LIDARR_API_KEY + # Readarr + - READARR_URL=http://readarr:8787 + - READARR_KEY=$READARR_API_KEY # qBittorrent - QBITTORRENT_URL=http://qbittorrent:8080 #- QBITTORRENT_USERNAME=Your name @@ -227,6 +230,18 @@ Note: The `config.conf` is disregarded when running via docker-compose.yml --- +### **-Readarr section** +- Defines readarr instance on which download queue should be decluttered + +**READARR_URL** +- URL under which the instance can be reached +- If not defined, this instance will not be monitored + +**READARR_KEY** +- Your API key for readarr + +--- + ### **qBittorrent section** - Defines settings to connect with qBittorrent diff --git a/config/config.conf-Example b/config/config.conf-Example index 5127c02..1ad6cad 100644 --- a/config/config.conf-Example +++ b/config/config.conf-Example @@ -29,6 +29,10 @@ SONARR_KEY = $SONARR_API_KEY LIDARR_URL = http://lidarr:8686 LIDARR_KEY = $LIDARR_API_KEY +[readarr] +READARR_URL = http://lidarr:8787 +READARR_KEY = $READARR_API_KEY + [qbittorrent] QBITTORRENT_URL = http://qbittorrent:8080 QBITTORRENT_USERNAME = Your name (or empty) diff --git a/config/config.py b/config/config.py index b882834..d9b016a 100644 --- a/config/config.py +++ b/config/config.py @@ -108,6 +108,11 @@ def get_config_value(key, config_section, is_mandatory, datatype, default_value LIDARR_KEY = None if LIDARR_URL == None else \ get_config_value('LIDARR_KEY', 'lidarr', True, str) +# Readarr +READARR_URL = get_config_value('READARR_URL', 'readarr', False, str) +READARR_KEY = None if READARR_URL == None else \ + get_config_value('READARR_KEY', 'readarr', True, str) + # qBittorrent QBITTORRENT_URL = get_config_value('QBITTORRENT_URL', 'qbittorrent', False, str, '') QBITTORRENT_USERNAME = get_config_value('QBITTORRENT_USERNAME', 'qbittorrent', False, str, '') @@ -115,14 +120,15 @@ def get_config_value(key, config_section, is_mandatory, datatype, default_value ######################################################################################################################## ########### Validate settings -if not (RADARR_URL or SONARR_URL or LIDARR_URL): - print(f'[ ERROR ]: No Radarr/Sonarr/Lidarr URLs specified (nothing to monitor)') +if not (RADARR_URL or SONARR_URL or LIDARR_URL or READARR_URL): + print(f'[ ERROR ]: No Radarr/Sonarr/Lidarr/Readarr URLs specified (nothing to monitor)') sys.exit(0) ########### Enrich setting variables if RADARR_URL: RADARR_URL += '/api/v3' if SONARR_URL: SONARR_URL += '/api/v3' if LIDARR_URL: LIDARR_URL += '/api/v1' +if READARR_URL: READARR_URL += '/api/v1' if QBITTORRENT_URL: QBITTORRENT_URL += '/api/v2' ########### Add Variables to Dictionary diff --git a/main.py b/main.py index 0e4be74..1f6e5ed 100644 --- a/main.py +++ b/main.py @@ -49,6 +49,12 @@ async def main(): except: settings_dict['LIDARR_NAME'] = 'Lidarr' + try: + if settings_dict['READARR_URL']: + settings_dict['READARR_NAME'] = (await rest_get(settings_dict['READARR_URL']+'/system/status', settings_dict['READARR_KEY']))['instanceName'] + except: + settings_dict['READARR_NAME'] = 'Readarr' + # Print Settings fmt = '{0.days} days {0.hours} hours {0.minutes} minutes' logger.info('#' * 50) @@ -76,6 +82,7 @@ async def main(): if settings_dict['RADARR_URL']: logger.info('%s: %s', settings_dict['RADARR_NAME'], settings_dict['RADARR_URL']) if settings_dict['SONARR_URL']: logger.info('%s: %s', settings_dict['SONARR_NAME'], settings_dict['SONARR_URL']) if settings_dict['LIDARR_URL']: logger.info('%s: %s', settings_dict['LIDARR_NAME'], settings_dict['LIDARR_URL']) + if settings_dict['READARR_URL']: logger.info('%s: %s', settings_dict['READARR_NAME'], settings_dict['READARR_URL']) if settings_dict['QBITTORRENT_URL']: logger.info('qBittorrent: %s', settings_dict['QBITTORRENT_URL']) logger.info('') @@ -117,6 +124,14 @@ async def main(): error_occured = True logger.error('-- | %s *** Error: %s ***', settings_dict['LIDARR_NAME'], error) + if settings_dict['READARR_URL']: + try: + await asyncio.get_event_loop().run_in_executor(None, lambda: requests.get(settings_dict['READARR_URL']+'/system/status', params=None, headers={'X-Api-Key': settings_dict['READARR_KEY']})) + logger.info('OK | %s', settings_dict['READARR_NAME']) + except Exception as error: + error_occured = True + logger.error('-- | %s *** Error: %s ***', settings_dict['READARR_NAME'], error) + if settings_dict['QBITTORRENT_URL']: # Checking if qbit can be reached, and checking if version is OK try: @@ -186,6 +201,7 @@ async def main(): if settings_dict['RADARR_URL']: await queueCleaner(settings_dict, 'radarr', defective_tracker, download_sizes_tracker, protectedDownloadIDs, privateDowloadIDs) if settings_dict['SONARR_URL']: await queueCleaner(settings_dict, 'sonarr', defective_tracker, download_sizes_tracker, protectedDownloadIDs, privateDowloadIDs) if settings_dict['LIDARR_URL']: await queueCleaner(settings_dict, 'lidarr', defective_tracker, download_sizes_tracker, protectedDownloadIDs, privateDowloadIDs) + if settings_dict['READARR_URL']: await queueCleaner(settings_dict, 'readarr', defective_tracker, download_sizes_tracker, protectedDownloadIDs, privateDowloadIDs) logger.verbose('') logger.verbose('Queue clean-up complete!') await asyncio.sleep(settings_dict['REMOVE_TIMER']*60) @@ -194,7 +210,8 @@ async def main(): if __name__ == '__main__': instances = {settings_dict['RADARR_URL']: {}} if settings_dict['RADARR_URL'] else {} + \ {settings_dict['SONARR_URL']: {}} if settings_dict['SONARR_URL'] else {} + \ - {settings_dict['LIDARR_URL']: {}} if settings_dict['LIDARR_URL'] else {} + {settings_dict['LIDARR_URL']: {}} if settings_dict['LIDARR_URL'] else {} + \ + {settings_dict['READARR_URL']: {}} if settings_dict['READARR_URL'] else {} defective_tracker = Defective_Tracker(instances) download_sizes_tracker = Download_Sizes_Tracker({}) asyncio.run(main()) diff --git a/src/decluttarr.py b/src/decluttarr.py index 81be668..b507cf1 100644 --- a/src/decluttarr.py +++ b/src/decluttarr.py @@ -34,6 +34,11 @@ async def queueCleaner(settings_dict, arr_type, defective_tracker, download_size API_KEY = settings_dict['LIDARR_KEY'] NAME = settings_dict['LIDARR_NAME'] full_queue_param = 'includeUnknownArtistItems' + elif arr_type == 'readarr': + BASE_URL = settings_dict['READARR_URL'] + API_KEY = settings_dict['READARR_KEY'] + NAME = settings_dict['READARR_NAME'] + full_queue_param = 'includeUnknownAuthorItems' else: logger.error('Unknown arr_type specified, exiting: %s', str(arr_type)) sys.exit() diff --git a/src/remove_unmonitored.py b/src/remove_unmonitored.py index e406951..df32831 100644 --- a/src/remove_unmonitored.py +++ b/src/remove_unmonitored.py @@ -19,7 +19,9 @@ async def remove_unmonitored(settings_dict, BASE_URL, API_KEY, NAME, deleted_dow elif arr_type == 'radarr': isMonitored = (await rest_get(f'{BASE_URL}/movie/{str(queueItem["movieId"])}', API_KEY))['monitored'] elif arr_type == 'lidarr': - isMonitored = (await rest_get(f'{BASE_URL}/album/{str(queueItem["albumId"])}', API_KEY))['monitored'] + isMonitored = (await rest_get(f'{BASE_URL}/album/{str(queueItem["albumId"])}', API_KEY))['monitored'] + elif arr_type == 'readarr': + isMonitored = (await rest_get(f'{BASE_URL}/book/{str(queueItem["bookId"])}', API_KEY))['monitored'] if isMonitored: monitoredDownloadIDs.append(queueItem['downloadId'])