diff --git a/.dockerignore b/.dockerignore index 036bd21..d65d56d 100644 --- a/.dockerignore +++ b/.dockerignore @@ -11,7 +11,12 @@ __pycache__/ .DS_Store # Ignore Git files -.git +.git* *cookies* set_env.sh -jellyplist.code-workspace \ No newline at end of file +jellyplist.code-workspace + +# Ignore GitHub page related files +changelogs +readme.md +screenshots \ No newline at end of file diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 3e6ca45..713e355 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -1,9 +1,12 @@ name: Build and Release on Tag on: - push: - branches: - - main + workflow_dispatch: + inputs: + branch: + description: 'Branch to build the Docker image from' + required: true + default: 'main' jobs: build-and-publish: @@ -73,5 +76,7 @@ jobs: name: Release ${{ env.VERSION }} body: | ${{ env.CHANGELOG_CONTENT }} + generate_release_notes: true + env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/app/tasks.py b/app/tasks.py index 44b1ed6..fcfc60b 100644 --- a/app/tasks.py +++ b/app/tasks.py @@ -113,8 +113,8 @@ def download_missing_tracks(self): app.logger.info("Starting track download job...") with app.app_context(): - spotdl_config = app.config['SPOTDL_CONFIG'] - cookie_file = spotdl_config['cookie_file'] + spotdl_config: dict = app.config['SPOTDL_CONFIG'] + cookie_file = spotdl_config.get('cookie_file', None) output_dir = spotdl_config['output'] client_id = app.config['SPOTIFY_CLIENT_ID'] client_secret = app.config['SPOTIFY_CLIENT_SECRET'] @@ -239,7 +239,7 @@ def download_missing_tracks(self): "--client-id", client_id, "--client-secret", client_secret ] - if os.path.exists(cookie_file): + if cookie_file and os.path.exists(cookie_file): app.logger.debug(f"Found {cookie_file}, using it for spotDL") command.append("--cookie-file") command.append(cookie_file) @@ -247,7 +247,8 @@ def download_missing_tracks(self): app.logger.debug(f"Using proxy: {app.config['SPOTDL_PROXY']}") command.append("--proxy") command.append(app.config['SPOTDL_PROXY']) - + + app.logger.info(f"Executing the spotDL command: {' '.join(command)}") result = subprocess.run(command, capture_output=True, text=True, timeout=90) if result.returncode == 0: track.downloaded = True diff --git a/config.py b/config.py index 9950598..0edd323 100644 --- a/config.py +++ b/config.py @@ -1,6 +1,8 @@ import os import sys +import app + class Config: LOG_LEVEL = os.getenv('LOG_LEVEL', 'INFO').upper() SECRET_KEY = os.getenv('SECRET_KEY') @@ -20,7 +22,7 @@ class Config: DISPLAY_EXTENDED_AUDIO_DATA = os.getenv('DISPLAY_EXTENDED_AUDIO_DATA',"false").lower() == 'true' CACHE_TYPE = 'redis' CACHE_REDIS_PORT = 6379 - CACHE_REDIS_HOST = 'redis' + CACHE_REDIS_HOST = os.getenv('CACHE_REDIS_HOST','redis') CACHE_REDIS_DB = 0 CACHE_DEFAULT_TIMEOUT = 3600 REDIS_URL = os.getenv('REDIS_URL','redis://redis:6379/0') @@ -39,16 +41,24 @@ class Config: ENABLE_DEEZER = os.getenv('ENABLE_DEEZER','false').lower() == 'true' # SpotDL specific configuration SPOTDL_CONFIG = { - 'cookie_file': '/jellyplist/cookies.txt', - # combine the path provided in MUSIC_STORAGE_BASE_PATH with the following path __jellyplist/{track-id} to get the value for output - 'threads': 12 } + # combine the path provided in MUSIC_STORAGE_BASE_PATH with the SPOTDL_OUTPUT_FORMAT to get the value for output if os.getenv('MUSIC_STORAGE_BASE_PATH'): - - output_path = os.path.join(MUSIC_STORAGE_BASE_PATH,SPOTDL_OUTPUT_FORMAT) - + # Ensure MUSIC_STORAGE_BASE_PATH ends with "__jellyplist" + if not MUSIC_STORAGE_BASE_PATH.endswith("__jellyplist"): + MUSIC_STORAGE_BASE_PATH += "__jellyplist" + + # Ensure SPOTDL_OUTPUT_FORMAT does not start with "/" + normalized_spotdl_output_format = SPOTDL_OUTPUT_FORMAT.lstrip("/").replace(" ", "_") + + # Join the paths + output_path = os.path.join(MUSIC_STORAGE_BASE_PATH, normalized_spotdl_output_format) + SPOTDL_CONFIG.update({'output': output_path}) + + if SPOTIFY_COOKIE_FILE: + SPOTDL_CONFIG.update({'cookie_file': SPOTIFY_COOKIE_FILE}) @classmethod def validate_env_vars(cls): @@ -72,4 +82,4 @@ class Config: if missing_vars: missing = ', '.join(missing_vars) sys.stderr.write(f"Error: The following environment variables are not set: {missing}\n") - sys.exit(1) \ No newline at end of file + sys.exit(1) diff --git a/readme.md b/readme.md index 7422ab3..cb64ecf 100644 --- a/readme.md +++ b/readme.md @@ -44,13 +44,13 @@ MUSIC_STORAGE_BASE_PATH = '/storage/media/music' # The base path where your musi # SPOTDL_PROXY = http://proxy:8080 # SPOTDL_OUTPUT_FORMAT = "/{artist}/{artists} - {title}" # Supported variables: {title}, {artist},{artists}, {album}, Will be joined with to get a complete path -# SEARCH_JELLYFIN_BEFORE_DOWNLOAD = false # defaults to true, before attempting to do a download with spotDL , the song will be searched first in the local library +# SEARCH_JELLYFIN_BEFORE_DOWNLOAD = false # defaults to true, before attempting to do a download with spotDL , the song will be searched first in the local library ("true" MAY INCURE PERFORMENCE ISSUES) # START_DOWNLOAD_AFTER_PLAYLIST_ADD = true # defaults to false, If a new Playlist is added, the Download Task will be scheduled immediately # FIND_BEST_MATCH_USE_FFPROBE = true # Use ffprobe to gather quality details from a file to calculate quality score. Otherwise jellyplist will use details provided by jellyfin. defaults to false. -#REFRESH_LIBRARIES_AFTER_DOWNLOAD_TASK = true # jellyplist will trigger a music library update on your Jellyfin server, in case you dont have `Realtime Monitoring` enabled on your Jellyfin library. Defaults to false. +#REFRESH_LIBRARIES_AFTER_DOWNLOAD_TASK = true # jellyplist will trigger a music library update on your Jellyfin server, in case you dont have `Realtime Monitoring` enabled on your Jellyfin library. Defaults to false. ("true" MAY INCURE PERFORMENCE ISSUES) # LOG_LEVEL = DEBUG # Defaults to INFO