diff --git a/.env.production b/.env.production index b1c4197..3c04af7 100644 --- a/.env.production +++ b/.env.production @@ -1,8 +1,8 @@ -TWITCH_ARCHIVE_IMAGE=forgejo.maddoscientisto.net/maddo/twitch-archive:latest -TWITCH_ARCHIVE_CONTAINER_NAME=twitch-archive -TWITCH_ARCHIVE_APP_ENV_FILE=./.env.production -TWITCH_ARCHIVE_ARCHIVE_BIND=./archive -TWITCH_ARCHIVE_CONFIG_BIND=./config +TWITCH_ARCHIVE_IMAGE=forgejo.maddoscientisto.net/maddo/twitchdownloader:latest +TWITCH_ARCHIVE_CONTAINER_NAME=twitchdownloader +TWITCH_ARCHIVE_APP_ENV_FILE=/mnt/storage/AppData/twitchdownloader/config/.env.production +TWITCH_ARCHIVE_ARCHIVE_BIND=/mnt/storage/AppData/twitchdownloader/archive +TWITCH_ARCHIVE_CONFIG_BIND=/mnt/storage/AppData/twitchdownloader/config TWITCH_ARCHIVE_ARGS=-u vinesauce TWITCH_ARCHIVE_HEALTHCHECK_STREAMER=vinesauce TWITCH_ARCHIVE_RCLONE_CONFIG=/app/config/rclone.conf diff --git a/docker-compose.yml b/docker-compose.yml index 68bc572..e77d6d6 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -4,8 +4,6 @@ services: container_name: ${TWITCH_ARCHIVE_CONTAINER_NAME:-twitch-archive} restart: unless-stopped init: true - env_file: - - ${TWITCH_ARCHIVE_APP_ENV_FILE:-./.env.production} environment: PYTHONUNBUFFERED: ${PYTHONUNBUFFERED:-1} TZ: ${TZ:-UTC} diff --git a/test_twitch_archive_simple.py b/test_twitch_archive_simple.py index 445e741..3d096e3 100644 --- a/test_twitch_archive_simple.py +++ b/test_twitch_archive_simple.py @@ -741,7 +741,6 @@ class TestMultiStreamerCleanupRegression(unittest.TestCase): } } } - stream_info = { 'title': 'Test', 'createdAt': '2026-04-25T09:14:01Z' @@ -753,6 +752,21 @@ class TestMultiStreamerCleanupRegression(unittest.TestCase): archiver.file_manager.delete_local_files.assert_not_called() +class TestEnvironmentLoadingRegression(unittest.TestCase): + """Regression tests for process environment startup in containers.""" + + def setUp(self): + self.module = load_twitch_archive_module() + + @patch.dict(os.environ, {'CLIENT-ID': 'portainer-client', 'CLIENT-SECRET': 'portainer-secret'}, clear=True) + @patch('dotenv.main.find_dotenv', return_value='') + @patch('dotenv.main.load_dotenv', return_value=False) + def test_load_environment_variables_accepts_process_environment_without_dotenv(self, _mock_load_dotenv, _mock_find_dotenv): + archive = self.module.TwitchArchive.__new__(self.module.TwitchArchive) + + self.module.TwitchArchive._load_environment_variables(archive) + + if __name__ == '__main__': # Run tests with verbose output print("="*70) diff --git a/twitch-archive.py b/twitch-archive.py index 707bdfe..16290db 100644 --- a/twitch-archive.py +++ b/twitch-archive.py @@ -137,7 +137,7 @@ class TwitchArchive: def _load_environment_variables(self) -> None: """ - Load environment variables from .env file. + Load environment variables from process environment or an optional .env file. Required variables: - CLIENT-ID: Twitch API client ID @@ -148,16 +148,26 @@ class TwitchArchive: - PASSWD: Email password for sending notifications (if enabled) Raises: - SystemExit: If .env file is not found + SystemExit: If required Twitch API credentials are unavailable """ + has_required_env = bool( + get_env_value('CLIENT-ID', 'CLIENT_ID') and + get_env_value('CLIENT-SECRET', 'CLIENT_SECRET') + ) + + if has_required_env: + print(f'{Fore.GREEN}✓ Twitch API credentials loaded from process environment{Style.RESET_ALL}') + return + dotenv_loaded = load_dotenv(find_dotenv()) has_required_env = bool( get_env_value('CLIENT-ID', 'CLIENT_ID') and get_env_value('CLIENT-SECRET', 'CLIENT_SECRET') ) - if not dotenv_loaded and has_required_env: - print(f'{Fore.GREEN}✓ Twitch API credentials loaded from process environment{Style.RESET_ALL}') + if has_required_env: + if dotenv_loaded: + print(f'{Fore.GREEN}✓ Twitch API credentials loaded from .env file{Style.RESET_ALL}') return if not dotenv_loaded and not has_required_env: