@@ -11,7 +11,12 @@ __pycache__/
|
|||||||
.DS_Store
|
.DS_Store
|
||||||
|
|
||||||
# Ignore Git files
|
# Ignore Git files
|
||||||
.git
|
.git*
|
||||||
*cookies*
|
*cookies*
|
||||||
set_env.sh
|
set_env.sh
|
||||||
jellyplist.code-workspace
|
jellyplist.code-workspace
|
||||||
|
|
||||||
|
# Ignore GitHub page related files
|
||||||
|
changelogs
|
||||||
|
readme.md
|
||||||
|
screenshots
|
||||||
11
.github/workflows/main.yml
vendored
11
.github/workflows/main.yml
vendored
@@ -1,9 +1,12 @@
|
|||||||
name: Build and Release on Tag
|
name: Build and Release on Tag
|
||||||
|
|
||||||
on:
|
on:
|
||||||
push:
|
workflow_dispatch:
|
||||||
branches:
|
inputs:
|
||||||
- main
|
branch:
|
||||||
|
description: 'Branch to build the Docker image from'
|
||||||
|
required: true
|
||||||
|
default: 'main'
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build-and-publish:
|
build-and-publish:
|
||||||
@@ -73,5 +76,7 @@ jobs:
|
|||||||
name: Release ${{ env.VERSION }}
|
name: Release ${{ env.VERSION }}
|
||||||
body: |
|
body: |
|
||||||
${{ env.CHANGELOG_CONTENT }}
|
${{ env.CHANGELOG_CONTENT }}
|
||||||
|
generate_release_notes: true
|
||||||
|
|
||||||
env:
|
env:
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|||||||
@@ -113,8 +113,8 @@ def download_missing_tracks(self):
|
|||||||
app.logger.info("Starting track download job...")
|
app.logger.info("Starting track download job...")
|
||||||
|
|
||||||
with app.app_context():
|
with app.app_context():
|
||||||
spotdl_config = app.config['SPOTDL_CONFIG']
|
spotdl_config: dict = app.config['SPOTDL_CONFIG']
|
||||||
cookie_file = spotdl_config['cookie_file']
|
cookie_file = spotdl_config.get('cookie_file', None)
|
||||||
output_dir = spotdl_config['output']
|
output_dir = spotdl_config['output']
|
||||||
client_id = app.config['SPOTIFY_CLIENT_ID']
|
client_id = app.config['SPOTIFY_CLIENT_ID']
|
||||||
client_secret = app.config['SPOTIFY_CLIENT_SECRET']
|
client_secret = app.config['SPOTIFY_CLIENT_SECRET']
|
||||||
@@ -239,7 +239,7 @@ def download_missing_tracks(self):
|
|||||||
"--client-id", client_id,
|
"--client-id", client_id,
|
||||||
"--client-secret", client_secret
|
"--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")
|
app.logger.debug(f"Found {cookie_file}, using it for spotDL")
|
||||||
command.append("--cookie-file")
|
command.append("--cookie-file")
|
||||||
command.append(cookie_file)
|
command.append(cookie_file)
|
||||||
@@ -248,6 +248,7 @@ def download_missing_tracks(self):
|
|||||||
command.append("--proxy")
|
command.append("--proxy")
|
||||||
command.append(app.config['SPOTDL_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)
|
result = subprocess.run(command, capture_output=True, text=True, timeout=90)
|
||||||
if result.returncode == 0:
|
if result.returncode == 0:
|
||||||
track.downloaded = True
|
track.downloaded = True
|
||||||
|
|||||||
20
config.py
20
config.py
@@ -1,6 +1,8 @@
|
|||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
|
import app
|
||||||
|
|
||||||
class Config:
|
class Config:
|
||||||
LOG_LEVEL = os.getenv('LOG_LEVEL', 'INFO').upper()
|
LOG_LEVEL = os.getenv('LOG_LEVEL', 'INFO').upper()
|
||||||
SECRET_KEY = os.getenv('SECRET_KEY')
|
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'
|
DISPLAY_EXTENDED_AUDIO_DATA = os.getenv('DISPLAY_EXTENDED_AUDIO_DATA',"false").lower() == 'true'
|
||||||
CACHE_TYPE = 'redis'
|
CACHE_TYPE = 'redis'
|
||||||
CACHE_REDIS_PORT = 6379
|
CACHE_REDIS_PORT = 6379
|
||||||
CACHE_REDIS_HOST = 'redis'
|
CACHE_REDIS_HOST = os.getenv('CACHE_REDIS_HOST','redis')
|
||||||
CACHE_REDIS_DB = 0
|
CACHE_REDIS_DB = 0
|
||||||
CACHE_DEFAULT_TIMEOUT = 3600
|
CACHE_DEFAULT_TIMEOUT = 3600
|
||||||
REDIS_URL = os.getenv('REDIS_URL','redis://redis:6379/0')
|
REDIS_URL = os.getenv('REDIS_URL','redis://redis:6379/0')
|
||||||
@@ -39,17 +41,25 @@ class Config:
|
|||||||
ENABLE_DEEZER = os.getenv('ENABLE_DEEZER','false').lower() == 'true'
|
ENABLE_DEEZER = os.getenv('ENABLE_DEEZER','false').lower() == 'true'
|
||||||
# SpotDL specific configuration
|
# SpotDL specific configuration
|
||||||
SPOTDL_CONFIG = {
|
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
|
'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'):
|
if os.getenv('MUSIC_STORAGE_BASE_PATH'):
|
||||||
|
# Ensure MUSIC_STORAGE_BASE_PATH ends with "__jellyplist"
|
||||||
|
if not MUSIC_STORAGE_BASE_PATH.endswith("__jellyplist"):
|
||||||
|
MUSIC_STORAGE_BASE_PATH += "__jellyplist"
|
||||||
|
|
||||||
output_path = os.path.join(MUSIC_STORAGE_BASE_PATH,SPOTDL_OUTPUT_FORMAT)
|
# 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})
|
SPOTDL_CONFIG.update({'output': output_path})
|
||||||
|
|
||||||
|
if SPOTIFY_COOKIE_FILE:
|
||||||
|
SPOTDL_CONFIG.update({'cookie_file': SPOTIFY_COOKIE_FILE})
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def validate_env_vars(cls):
|
def validate_env_vars(cls):
|
||||||
required_vars = {
|
required_vars = {
|
||||||
|
|||||||
@@ -44,13 +44,13 @@ MUSIC_STORAGE_BASE_PATH = '/storage/media/music' # The base path where your musi
|
|||||||
# SPOTDL_PROXY = http://proxy:8080
|
# 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
|
# 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
|
# 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.
|
# 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
|
# LOG_LEVEL = DEBUG # Defaults to INFO
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user