Skip to content

Commit

Permalink
Added black as pre-commit and applied it.
Browse files Browse the repository at this point in the history
  • Loading branch information
ManiMatter committed Sep 8, 2024
1 parent 8e24448 commit 7f33dd8
Show file tree
Hide file tree
Showing 30 changed files with 1,903 additions and 770 deletions.
1 change: 0 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
__pycache__/
.pytest_cache/
.vscode/
config/config.conf
ToDo
snip*.py
Expand Down
11 changes: 11 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
repos:
- repo: local
hooks:
- id: black
name: black
entry: venv/bin/black
language: system
types: [python]



4 changes: 4 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"editor.formatOnSave": true,
"editor.defaultFormatter": "ms-python.black-formatter"
}
166 changes: 106 additions & 60 deletions config/definitions.py
Original file line number Diff line number Diff line change
@@ -1,86 +1,132 @@
#!/usr/bin/env python
from config.parser import get_config_value
from config.env_vars import *

# Define data types and default values for settingsDict variables
# General
LOG_LEVEL = get_config_value('LOG_LEVEL', 'general', False, str, 'INFO')
TEST_RUN = get_config_value('TEST_RUN', 'general', False, bool, False)
SSL_VERIFICATION = get_config_value('SSL_VERIFICATION', 'general', False, bool, True)
# General
LOG_LEVEL = get_config_value("LOG_LEVEL", "general", False, str, "INFO")
TEST_RUN = get_config_value("TEST_RUN", "general", False, bool, False)
SSL_VERIFICATION = get_config_value("SSL_VERIFICATION", "general", False, bool, True)

# Features
REMOVE_TIMER = get_config_value('REMOVE_TIMER', 'features', False, float, 10)
REMOVE_FAILED = get_config_value('REMOVE_FAILED', 'features', False, bool, False)
REMOVE_FAILED_IMPORTS = get_config_value('REMOVE_FAILED_IMPORTS' , 'features', False, bool, False)
REMOVE_METADATA_MISSING = get_config_value('REMOVE_METADATA_MISSING', 'features', False, bool, False)
REMOVE_MISSING_FILES = get_config_value('REMOVE_MISSING_FILES' , 'features', False, bool, False)
REMOVE_NO_FORMAT_UPGRADE = get_config_value('REMOVE_NO_FORMAT_UPGRADE' , 'features', False, bool, False) # OUTDATED - WILL RETURN WARNING
REMOVE_ORPHANS = get_config_value('REMOVE_ORPHANS' , 'features', False, bool, False)
REMOVE_SLOW = get_config_value('REMOVE_SLOW' , 'features', False, bool, False)
REMOVE_STALLED = get_config_value('REMOVE_STALLED', 'features', False, bool, False)
REMOVE_UNMONITORED = get_config_value('REMOVE_UNMONITORED', 'features', False, bool, False)
CANCEL_UNAVAILABLE_FILES = get_config_value('CANCEL_UNAVAILABLE_FILES', 'features', False, bool, False)
MIN_DOWNLOAD_SPEED = get_config_value('MIN_DOWNLOAD_SPEED', 'features', False, int, 0)
PERMITTED_ATTEMPTS = get_config_value('PERMITTED_ATTEMPTS', 'features', False, int, 3)
NO_STALLED_REMOVAL_QBIT_TAG = get_config_value('NO_STALLED_REMOVAL_QBIT_TAG', 'features', False, str, 'Don\'t Kill')
IGNORE_PRIVATE_TRACKERS = get_config_value('IGNORE_PRIVATE_TRACKERS', 'features', False, bool, True)
FAILED_IMPORT_MESSAGE_PATTERNS = get_config_value('FAILED_IMPORT_MESSAGE_PATTERNS','features', False, list, [])
# Features
REMOVE_TIMER = get_config_value("REMOVE_TIMER", "features", False, float, 10)
REMOVE_FAILED = get_config_value("REMOVE_FAILED", "features", False, bool, False)
REMOVE_FAILED_IMPORTS = get_config_value(
"REMOVE_FAILED_IMPORTS", "features", False, bool, False
)
REMOVE_METADATA_MISSING = get_config_value(
"REMOVE_METADATA_MISSING", "features", False, bool, False
)
REMOVE_MISSING_FILES = get_config_value(
"REMOVE_MISSING_FILES", "features", False, bool, False
)
REMOVE_NO_FORMAT_UPGRADE = get_config_value(
"REMOVE_NO_FORMAT_UPGRADE", "features", False, bool, False
) # OUTDATED - WILL RETURN WARNING
REMOVE_ORPHANS = get_config_value("REMOVE_ORPHANS", "features", False, bool, False)
REMOVE_SLOW = get_config_value("REMOVE_SLOW", "features", False, bool, False)
REMOVE_STALLED = get_config_value("REMOVE_STALLED", "features", False, bool, False)
REMOVE_UNMONITORED = get_config_value(
"REMOVE_UNMONITORED", "features", False, bool, False
)
CANCEL_UNAVAILABLE_FILES = get_config_value(
"CANCEL_UNAVAILABLE_FILES", "features", False, bool, False
)
MIN_DOWNLOAD_SPEED = get_config_value("MIN_DOWNLOAD_SPEED", "features", False, int, 0)
PERMITTED_ATTEMPTS = get_config_value("PERMITTED_ATTEMPTS", "features", False, int, 3)
NO_STALLED_REMOVAL_QBIT_TAG = get_config_value(
"NO_STALLED_REMOVAL_QBIT_TAG", "features", False, str, "Don't Kill"
)
IGNORE_PRIVATE_TRACKERS = get_config_value(
"IGNORE_PRIVATE_TRACKERS", "features", False, bool, True
)
FAILED_IMPORT_MESSAGE_PATTERNS = get_config_value(
"FAILED_IMPORT_MESSAGE_PATTERNS", "features", False, list, []
)

# Radarr
RADARR_URL = get_config_value('RADARR_URL', 'radarr', False, str)
RADARR_KEY = None if RADARR_URL == None else \
get_config_value('RADARR_KEY', 'radarr', True, str)
RADARR_URL = get_config_value("RADARR_URL", "radarr", False, str)
RADARR_KEY = (
None if RADARR_URL == None else get_config_value("RADARR_KEY", "radarr", True, str)
)

# Sonarr
SONARR_URL = get_config_value('SONARR_URL', 'sonarr', False, str)
SONARR_KEY = None if SONARR_URL == None else \
get_config_value('SONARR_KEY', 'sonarr', True, str)
# Sonarr
SONARR_URL = get_config_value("SONARR_URL", "sonarr", False, str)
SONARR_KEY = (
None if SONARR_URL == None else get_config_value("SONARR_KEY", "sonarr", True, str)
)

# Lidarr
LIDARR_URL = get_config_value('LIDARR_URL', 'lidarr', False, str)
LIDARR_KEY = None if LIDARR_URL == None else \
get_config_value('LIDARR_KEY', 'lidarr', True, str)
# Lidarr
LIDARR_URL = get_config_value("LIDARR_URL", "lidarr", False, str)
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)
# 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)
)

# Whisparr
WHISPARR_URL = get_config_value('WHISPARR_URL', 'whisparr', False, str)
WHISPARR_KEY = None if WHISPARR_URL == None else \
get_config_value('WHISPARR_KEY', 'whisparr', True, str)
# Whisparr
WHISPARR_URL = get_config_value("WHISPARR_URL", "whisparr", False, str)
WHISPARR_KEY = (
None
if WHISPARR_URL == None
else get_config_value("WHISPARR_KEY", "whisparr", True, str)
)

# qBittorrent
QBITTORRENT_URL = get_config_value('QBITTORRENT_URL', 'qbittorrent', False, str, '')
QBITTORRENT_USERNAME = get_config_value('QBITTORRENT_USERNAME', 'qbittorrent', False, str, '')
QBITTORRENT_PASSWORD = get_config_value('QBITTORRENT_PASSWORD', 'qbittorrent', False, str, '')
# qBittorrent
QBITTORRENT_URL = get_config_value("QBITTORRENT_URL", "qbittorrent", False, str, "")
QBITTORRENT_USERNAME = get_config_value(
"QBITTORRENT_USERNAME", "qbittorrent", False, str, ""
)
QBITTORRENT_PASSWORD = get_config_value(
"QBITTORRENT_PASSWORD", "qbittorrent", False, str, ""
)

########################################################################################################################
########### Validate settings
if not (IS_IN_PYTEST or RADARR_URL or SONARR_URL or LIDARR_URL or READARR_URL or WHISPARR_URL):
print(f'[ ERROR ]: No Radarr/Sonarr/Lidarr/Readarr/Whisparr URLs specified (nothing to monitor)')
if not (
IS_IN_PYTEST
or RADARR_URL
or SONARR_URL
or LIDARR_URL
or READARR_URL
or WHISPARR_URL
):
print(
f"[ ERROR ]: No Radarr/Sonarr/Lidarr/Readarr/Whisparr URLs specified (nothing to monitor)"
)
exit()

########### Enrich setting variables
if RADARR_URL: RADARR_URL = RADARR_URL.rstrip('/') + '/api/v3'
if SONARR_URL: SONARR_URL = SONARR_URL.rstrip('/') + '/api/v3'
if LIDARR_URL: LIDARR_URL = LIDARR_URL.rstrip('/') + '/api/v1'
if READARR_URL: READARR_URL = READARR_URL.rstrip('/') + '/api/v1'
if WHISPARR_URL: WHISPARR_URL = WHISPARR_URL.rstrip('/') + '/api/v3'
if QBITTORRENT_URL: QBITTORRENT_URL = QBITTORRENT_URL.rstrip('/') + '/api/v2'
if RADARR_URL:
RADARR_URL = RADARR_URL.rstrip("/") + "/api/v3"
if SONARR_URL:
SONARR_URL = SONARR_URL.rstrip("/") + "/api/v3"
if LIDARR_URL:
LIDARR_URL = LIDARR_URL.rstrip("/") + "/api/v1"
if READARR_URL:
READARR_URL = READARR_URL.rstrip("/") + "/api/v1"
if WHISPARR_URL:
WHISPARR_URL = WHISPARR_URL.rstrip("/") + "/api/v3"
if QBITTORRENT_URL:
QBITTORRENT_URL = QBITTORRENT_URL.rstrip("/") + "/api/v2"

RADARR_MIN_VERSION = '5.3.6.8608'
SONARR_MIN_VERSION = '4.0.1.1131'
LIDARR_MIN_VERSION = None
READARR_MIN_VERSION = None
WHISPARR_MIN_VERSION = '2.0.0.548'
QBITTORRENT_MIN_VERSION = '4.3.0'
RADARR_MIN_VERSION = "5.3.6.8608"
SONARR_MIN_VERSION = "4.0.1.1131"
LIDARR_MIN_VERSION = None
READARR_MIN_VERSION = None
WHISPARR_MIN_VERSION = "2.0.0.548"
QBITTORRENT_MIN_VERSION = "4.3.0"

SUPPORTED_ARR_APPS = ['RADARR', 'SONARR', 'LIDARR', 'READARR', 'WHISPARR']
SUPPORTED_ARR_APPS = ["RADARR", "SONARR", "LIDARR", "READARR", "WHISPARR"]

########### Add Variables to Dictionary
settingsDict = {}
for var_name in dir():
if var_name.isupper():
settingsDict[var_name] = locals()[var_name]

9 changes: 5 additions & 4 deletions config/env_vars.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import os
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')
IS_IN_PYTEST = os.environ.get('IS_IN_PYTEST')

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")
IS_IN_PYTEST = os.environ.get("IS_IN_PYTEST")
44 changes: 26 additions & 18 deletions config/parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,18 @@
from config.env_vars import *

# Configures how to parse configuration file
config_file_name = 'config.conf'
config_file_full_path = os.path.join(os.path.abspath(os.path.dirname(__file__)), config_file_name)
config_file_name = "config.conf"
config_file_full_path = os.path.join(
os.path.abspath(os.path.dirname(__file__)), config_file_name
)
sys.tracebacklimit = 0 # dont show stack traces in prod mode
config = configparser.ConfigParser()
config.optionxform = str # maintain capitalization of config keys
config.optionxform = str # maintain capitalization of config keys
config.read(config_file_full_path)


def config_section_map(section):
'Load the config file into a dictionary'
"Load the config file into a dictionary"
dict1 = {}
options = config.options(section)
for option in options:
Expand All @@ -26,19 +28,21 @@ def config_section_map(section):
dict1[option] = None
return dict1


def cast(value, type_):
return type_(value)

def get_config_value(key, config_section, is_mandatory, datatype, default_value = None):
'Return for each key the corresponding value from the Docker Environment or the Config File'

def get_config_value(key, config_section, is_mandatory, datatype, default_value=None):
"Return for each key the corresponding value from the Docker Environment or the Config File"
if IS_IN_DOCKER:
config_value = os.environ.get(key)
if config_value is not None:
if config_value is not None:
# print(f'The value retrieved for [{config_section}]: {key} is "{config_value}"')
config_value = config_value
# return config_value
elif is_mandatory:
print(f'[ ERROR ]: Variable not specified in Docker environment: {key}' )
print(f"[ ERROR ]: Variable not specified in Docker environment: {key}")
sys.exit(0)
else:
# return default_value
Expand All @@ -52,13 +56,15 @@ def get_config_value(key, config_section, is_mandatory, datatype, default_value
config_value = None
if config_value is not None:
# print(f'The value retrieved for [{config_section}]: {key} is "{config_value}"')
config_value = config_value
config_value = config_value
# return config_value
elif is_mandatory:
print(f'[ ERROR ]: Mandatory variable not specified in config file, section [{config_section}]: {key} (data type: {datatype.__name__})')
print(
f"[ ERROR ]: Mandatory variable not specified in config file, section [{config_section}]: {key} (data type: {datatype.__name__})"
)
sys.exit(0)
else:
# return default_value
# return default_value
# print(f'The default value used for [{config_section}]: {key} is "{default_value}" (data type: {type(default_value).__name__})')
config_value = default_value

Expand All @@ -67,14 +73,16 @@ def get_config_value(key, config_section, is_mandatory, datatype, default_value
if datatype == bool:
config_value = eval(str(config_value).capitalize())
elif datatype == list:
if type(config_value) != list: # Default value is already a list, doesn't need to be pushed through json.loads
if (
type(config_value) != list
): # Default value is already a list, doesn't need to be pushed through json.loads
config_value = json.loads(config_value)
elif config_value is not None:
elif config_value is not None:
config_value = cast(config_value, datatype)
except Exception as e:
print(f'[ ERROR ]: The value retrieved for [{config_section}]: {key} is "{config_value}" and cannot be converted to data type {datatype}')
except Exception as e:
print(
f'[ ERROR ]: The value retrieved for [{config_section}]: {key} is "{config_value}" and cannot be converted to data type {datatype}'
)
print(e)
sys.exit(0)
return config_value


return config_value
3 changes: 3 additions & 0 deletions docker/requirements.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
# python3 -m pip install -r docker/requirements.txt
requests==2.32.3
asyncio==3.4.3
python-dateutil==2.8.2
verboselogs==1.7
pytest==8.0.1
pytest-asyncio==0.23.5
pre-commit==3.8.0
black==24.8.0
Loading

0 comments on commit 7f33dd8

Please sign in to comment.