Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added black as pre-commit and applied it. #150

Merged
merged 1 commit into from
Sep 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading