diff --git a/app/main.py b/app/main.py index 580bc76..3ba5ae4 100644 --- a/app/main.py +++ b/app/main.py @@ -74,21 +74,22 @@ class Config: if not self.URL_PREFIX.endswith('/'): self.URL_PREFIX += '/' - success,_ = self.load_ytdl_options(True) + success,_ = self.load_ytdl_options() if not success: sys.exit(1) - def load_ytdl_options(self, is_init=False) -> tuple[bool, str]: - msg = '' - if not self.load_ytdl_options_env(is_init): + def load_ytdl_options(self) -> tuple[bool, str]: + try: + self.YTDL_OPTIONS = json.loads(os.environ.get('YTDL_OPTIONS', '{}')) + assert isinstance(self.YTDL_OPTIONS, dict) + except (json.decoder.JSONDecodeError, AssertionError): msg = 'Environment variable YTDL_OPTIONS is invalid' + log.error(msg) return (False, msg) - + if not self.YTDL_OPTIONS_FILE: - msg='YTDL_OPTIONS_FILE is not set' - if not is_init: - log.error(msg) - return (is_init, msg) + return (True, '') + log.info(f'Loading yt-dlp custom options from "{self.YTDL_OPTIONS_FILE}"') if not os.path.exists(self.YTDL_OPTIONS_FILE): msg = f'File "{self.YTDL_OPTIONS_FILE}" not found' @@ -104,21 +105,7 @@ class Config: return (False, msg) self.YTDL_OPTIONS.update(opts) - return (True, msg) - - def load_ytdl_options_env(self, is_init=False) -> tuple[bool, str]: - k = 'YTDL_OPTIONS' - if not is_init: - - setattr(self, k, os.environ.get(k, '{}')) - print(os.environ.get(k, '{}')) - try: - self.YTDL_OPTIONS = json.loads(self.YTDL_OPTIONS) - assert isinstance(self.YTDL_OPTIONS, dict) - except (json.decoder.JSONDecodeError, AssertionError): - log.error('YTDL_OPTIONS is invalid') - return False - return True + return (True, '') config = Config() @@ -161,15 +148,40 @@ app.on_startup.append(lambda app: dqueue.initialize()) class FileOpsFilter(DefaultFilter): def __call__(self, change_type: int, path: str) -> bool: - return (os.path.samefile(path, config.YTDL_OPTIONS_FILE) and - change_type in (Change.modified,Change.added)) + # Check if this path matches our YTDL_OPTIONS_FILE + if path != config.YTDL_OPTIONS_FILE: + return False + + # For existing files, use samefile comparison to handle symlinks correctly + if os.path.exists(config.YTDL_OPTIONS_FILE): + try: + if not os.path.samefile(path, config.YTDL_OPTIONS_FILE): + return False + except (OSError, IOError): + # If samefile fails, fall back to string comparison + if path != config.YTDL_OPTIONS_FILE: + return False + + # Accept all change types for our file: modified, added, deleted + return change_type in (Change.modified, Change.added, Change.deleted) + def get_options_update_time(success=True, msg=''): result = { 'success': success, 'msg': msg, - 'update_time': os.path.getmtime(config.YTDL_OPTIONS_FILE) + 'update_time': None } + + # Only try to get file modification time if YTDL_OPTIONS_FILE is set and file exists + if config.YTDL_OPTIONS_FILE and os.path.exists(config.YTDL_OPTIONS_FILE): + try: + result['update_time'] = os.path.getmtime(config.YTDL_OPTIONS_FILE) + except (OSError, IOError) as e: + log.warning(f"Could not get modification time for {config.YTDL_OPTIONS_FILE}: {e}") + result['update_time'] = None + return result + async def watch_files(): path_to_watch = Path(config.YTDL_OPTIONS_FILE).resolve() async def _watch_files():