mirror of
https://github.com/ManiMatter/decluttarr.git
synced 2026-04-21 16:25:35 +02:00
Merge pull request #34 from ManiMatter/dev
Added BETA support for Readarr && removed 'Unknown Manifest' Problem (which removes ARM + x86 support) -> PRs to fix it apprecaited
This commit is contained in:
42
.github/workflows/dev.yml
vendored
42
.github/workflows/dev.yml
vendored
@@ -25,7 +25,6 @@ jobs:
|
||||
python3 -m pytest --import-mode=append tests/
|
||||
|
||||
build-dev:
|
||||
# if: github.ref == 'refs/heads/dev'
|
||||
needs: unit-tests
|
||||
runs-on: ubuntu-latest
|
||||
defaults:
|
||||
@@ -35,6 +34,12 @@ jobs:
|
||||
- name: 'Checkout GitHub Action'
|
||||
uses: actions/checkout@main
|
||||
|
||||
# - name: Set up QEMU
|
||||
# uses: docker/setup-qemu-action@v1
|
||||
|
||||
# - name: Set up Docker Buildx
|
||||
# uses: docker/setup-buildx-action@v1
|
||||
|
||||
- name: 'Login to GitHub Container Registry'
|
||||
uses: docker/login-action@v1
|
||||
with:
|
||||
@@ -42,14 +47,43 @@ jobs:
|
||||
username: ${{github.actor}}
|
||||
password: ${{secrets.GITHUB_TOKEN}}
|
||||
|
||||
- name: Store short Commit ID in env variable
|
||||
id: vars
|
||||
run: |
|
||||
calculatedSha=$(git rev-parse --short ${{ github.sha }})
|
||||
echo "SHORT_COMMIT_ID=$calculatedSha" >> $GITHUB_ENV
|
||||
|
||||
- name: "Build, Tag, and push the Docker image"
|
||||
env:
|
||||
IMAGE_NAME: ghcr.io/manimatter/decluttarr
|
||||
IMAGE_TAG: dev
|
||||
run: |
|
||||
docker build -f docker/Dockerfile -t $IMAGE_NAME:$IMAGE_TAG .
|
||||
docker push $IMAGE_NAME:$IMAGE_TAG
|
||||
|
||||
docker build \
|
||||
--progress plain \
|
||||
-t $IMAGE_NAME:$IMAGE_TAG \
|
||||
--label com.decluttarr.version=$IMAGE_TAG \
|
||||
--label com.decluttarr.commit=$SHORT_COMMIT_ID \
|
||||
--build-arg IMAGE_TAG=$IMAGE_TAG \
|
||||
--build-arg SHORT_COMMIT_ID=$SHORT_COMMIT_ID \
|
||||
-f docker/Dockerfile \
|
||||
--push .
|
||||
|
||||
# - name: "Build, Tag, and push the Docker image"
|
||||
# env:
|
||||
# IMAGE_NAME: ghcr.io/manimatter/decluttarr
|
||||
# IMAGE_TAG: dev
|
||||
# run: |
|
||||
# docker buildx build \ <<<<<<<<<<<<<<<<<<<<< creates manifest issues... don't know how to solve that
|
||||
# --platform linux/amd64,linux/arm64 \ <<<<<<<<<<<<<<<<<<<<< creates manifest issues... don't know how to solve that
|
||||
# --progress plain \
|
||||
# -t $IMAGE_NAME:$IMAGE_TAG \
|
||||
# --label com.decluttarr.version=$IMAGE_TAG \
|
||||
# --label com.decluttarr.commit=$SHORT_COMMIT_ID \
|
||||
# --build-arg IMAGE_TAG=$IMAGE_TAG \
|
||||
# --build-arg SHORT_COMMIT_ID=$SHORT_COMMIT_ID \
|
||||
# -f docker/Dockerfile \
|
||||
# --push .
|
||||
|
||||
- name: "Delete untagged versions"
|
||||
uses: actions/delete-package-versions@v4
|
||||
with:
|
||||
|
||||
40
.github/workflows/main.yml
vendored
40
.github/workflows/main.yml
vendored
@@ -18,11 +18,11 @@ jobs:
|
||||
- name: 'Checkout GitHub Action'
|
||||
uses: actions/checkout@main
|
||||
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v1
|
||||
# - name: Set up QEMU
|
||||
# uses: docker/setup-qemu-action@v1
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v1
|
||||
# - name: Set up Docker Buildx
|
||||
# uses: docker/setup-buildx-action@v1
|
||||
|
||||
- name: 'Login to GitHub Container Registry'
|
||||
uses: docker/login-action@v1
|
||||
@@ -42,17 +42,41 @@ jobs:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
WITH_V: true
|
||||
|
||||
- name: Store short Commit ID in env variable
|
||||
id: vars
|
||||
run: |
|
||||
calculatedSha=$(git rev-parse --short ${{ github.sha }})
|
||||
echo "SHORT_COMMIT_ID=$calculatedSha" >> $GITHUB_ENV
|
||||
|
||||
- name: "Build, Tag, and push the Docker image"
|
||||
env:
|
||||
IMAGE_NAME: ghcr.io/manimatter/decluttarr
|
||||
IMAGE_TAG: ${{ steps.setversion.outputs.new_tag }}
|
||||
run: |
|
||||
docker buildx build --platform linux/amd64,linux/arm64 -t $IMAGE_NAME:$IMAGE_TAG -t $IMAGE_NAME:latest -f docker/Dockerfile --push .
|
||||
docker build \
|
||||
--progress plain \
|
||||
-t $IMAGE_NAME:$IMAGE_TAG \
|
||||
-t $IMAGE_NAME:latest \
|
||||
--label com.decluttarr.version=$IMAGE_TAG \
|
||||
--label com.decluttarr.commit=$SHORT_COMMIT_ID \
|
||||
--build-arg IMAGE_TAG=$IMAGE_TAG \
|
||||
--build-arg SHORT_COMMIT_ID=$SHORT_COMMIT_ID \
|
||||
-f docker/Dockerfile \
|
||||
--push .
|
||||
|
||||
# - name: "Build, Tag, and push the Docker image"
|
||||
# env:
|
||||
# IMAGE_NAME: ghcr.io/manimatter/decluttarr
|
||||
# IMAGE_TAG: latest
|
||||
# IMAGE_TAG: ${{ steps.setversion.outputs.new_tag }}
|
||||
# run: |
|
||||
# docker buildx build --platform linux/amd64,linux/arm64 -t $IMAGE_NAME:$IMAGE_TAG -f docker/Dockerfile --push .
|
||||
|
||||
# docker buildx build \ <<<<<<<<<<<<<<<<<<<<< creates manifest issues... don't know how to solve that
|
||||
# --platform linux/amd64,linux/arm64 \ <<<<<<<<<<<<<<<<<<<<< creates manifest issues... don't know how to solve that
|
||||
# --progress plain \
|
||||
# -t $IMAGE_NAME:$IMAGE_TAG \
|
||||
# -t $IMAGE_NAME:latest \
|
||||
# --label com.decluttarr.version=$IMAGE_TAG \
|
||||
# --label com.decluttarr.commit=$SHORT_COMMIT_ID \
|
||||
# --build-arg IMAGE_TAG=$IMAGE_TAG \
|
||||
# --build-arg SHORT_COMMIT_ID=$SHORT_COMMIT_ID \
|
||||
# -f docker/Dockerfile \
|
||||
# --push .
|
||||
15
README.md
15
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
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -6,6 +6,8 @@ import configparser
|
||||
########################################################################################################################
|
||||
# Check if in Docker
|
||||
IS_IN_DOCKER = os.environ.get('IS_IN_DOCKER')
|
||||
IMAGE_TAG = os.environ.get('IMAGE_TAG', 'Local')
|
||||
SHORT_COMMIT_ID = os.environ.get('SHORT_COMMIT_ID', 'n/a')
|
||||
|
||||
########################################################################################################################
|
||||
def config_section_map(section):
|
||||
@@ -108,6 +110,11 @@ LIDARR_URL = get_config_value('LIDARR_URL',
|
||||
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 +122,15 @@ QBITTORRENT_PASSWORD = get_config_value('QBITTORRENT_PASSWORD',
|
||||
|
||||
########################################################################################################################
|
||||
########### 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
|
||||
|
||||
@@ -1,5 +1,17 @@
|
||||
#FROM python:3.9-slim-buster
|
||||
# For debugging:
|
||||
# sudo docker run --rm -it --entrypoint sh ghcr.io/manimatter/decluttarr:dev
|
||||
|
||||
FROM python:3.10.13-slim
|
||||
|
||||
# Define a build-time argument for IMAGE_TAG
|
||||
ARG IMAGE_TAG
|
||||
ARG SHORT_COMMIT_ID
|
||||
|
||||
# Set an environment variable using the build-time argument
|
||||
ENV IMAGE_TAG=$IMAGE_TAG
|
||||
ENV SHORT_COMMIT_ID=$SHORT_COMMIT_ID
|
||||
|
||||
LABEL org.opencontainers.image.source="https://github.com/ManiMatter/decluttarr"
|
||||
|
||||
ENV IS_IN_DOCKER 1
|
||||
|
||||
26
main.py
26
main.py
@@ -11,6 +11,7 @@ from src.decluttarr import queueCleaner
|
||||
import requests
|
||||
import platform
|
||||
from packaging import version
|
||||
|
||||
########### Enabling Logging
|
||||
# Set up logging
|
||||
log_level_num=logging.getLevelName(settings_dict['LOG_LEVEL'])
|
||||
@@ -49,12 +50,21 @@ 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)
|
||||
logger.info('Application Started!')
|
||||
logger.info('Decluttarr - Application Started!')
|
||||
logger.info('')
|
||||
logger.info('*** Current Settings ***')
|
||||
logger.info('Version: %s', settings_dict['IMAGE_TAG'])
|
||||
logger.info('Commit: %s', settings_dict['SHORT_COMMIT_ID'])
|
||||
logger.info('')
|
||||
logger.info('%s | Removing failed downloads', str(settings_dict['REMOVE_FAILED']))
|
||||
logger.info('%s | Removing downloads missing metadata', str(settings_dict['REMOVE_METADATA_MISSING']))
|
||||
logger.info('%s | Removing downloads missing files', str(settings_dict['REMOVE_MISSING_FILES']))
|
||||
@@ -76,6 +86,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 +128,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 +205,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,8 +214,10 @@ 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())
|
||||
|
||||
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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'])
|
||||
|
||||
|
||||
Reference in New Issue
Block a user