Skip to content

Commit

Permalink
Override config path via environment variable
Browse files Browse the repository at this point in the history
  • Loading branch information
mandarons committed Oct 13, 2023
1 parent 4ce0f23 commit c696481
Show file tree
Hide file tree
Showing 6 changed files with 96 additions and 2 deletions.
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,13 @@ services:
- PUID=<insert the output of `id -u $user`>
- GUID=<insert the output of `id -g $user`>
env_file:
- .env.icloud #should contain ENV_ICLOUD_PASSWORD=<password>
- .env.icloud #should contain ENV_ICLOUD_PASSWORD=<password>, ENV_CONFIG_FILE_PATH=<absolute path in container to config.yaml>
container_name: icloud
restart: unless-stopped
volumes:
- /etc/timezone:/etc/timezone:ro
- /etc/localtime:/etc/localtime:ro
# To override /app/config.yaml path in container, specify environment variable ENV_CONFIG_FILE_PATH=<absolute path in container to config.yaml>
- ${PWD}/icloud/config.yaml:/app/config.yaml
- ${PWD}/icloud/data:/app/icloud
- ${PWD}/session_data:/app/session_data
Expand Down
1 change: 1 addition & 0 deletions src/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
DEFAULT_SYNC_INTERVAL_SEC = 1800 # 30 minutes
DEFAULT_CONFIG_FILE_NAME = "config.yaml"
ENV_ICLOUD_PASSWORD_KEY = "ENV_ICLOUD_PASSWORD"
ENV_CONFIG_FILE_PATH_KEY = "ENV_CONFIG_FILE_PATH"
DEFAULT_LOGGER_LEVEL = "info"
DEFAULT_LOG_FILE_NAME = "icloud.log"
DEFAULT_CONFIG_FILE_PATH = os.path.join(
Expand Down
8 changes: 7 additions & 1 deletion src/sync.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@
from icloudpy import ICloudPyService, exceptions, utils

from src import (
DEFAULT_CONFIG_FILE_PATH,
DEFAULT_COOKIE_DIRECTORY,
ENV_CONFIG_FILE_PATH_KEY,
ENV_ICLOUD_PASSWORD_KEY,
LOGGER,
config_parser,
Expand Down Expand Up @@ -52,7 +54,11 @@ def sync():
photos_sync_interval = 0
sleep_for = 10
while True:
config = read_config()
config = read_config(
config_path=os.environ.get(
ENV_CONFIG_FILE_PATH_KEY, DEFAULT_CONFIG_FILE_PATH
)
)
alive(config=config)
username = config_parser.get_username(config=config)
if username:
Expand Down
1 change: 1 addition & 0 deletions tests/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

DATA_DIR = os.path.join(os.path.dirname(__file__), "data")
CONFIG_PATH = os.path.join(DATA_DIR, "test_config.yaml")
ENV_CONFIG_PATH = os.path.join(DATA_DIR, "test_config_env.yaml")
TEMP_DIR = os.path.join(os.path.dirname(__file__), "temp")
DRIVE_DIR = os.path.join(TEMP_DIR, "icloud", "drive")
PHOTOS_DIR = os.path.join(TEMP_DIR, "icloud", "photos")
Expand Down
68 changes: 68 additions & 0 deletions tests/data/test_config_env.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
app:
logger:
# level - debug, info (default), warning or error
level: debug
# log filename icloud.log (default)
filename: config_loaded_using_env_config_path.log
credentials:
# iCloud drive username
username: [email protected]
# Retry failed login (with/without 2FA) every 10 minutes
retry_login_interval: 600
# Drive destination
root: "./icloud"
smtp:
# If you want to recieve email notifications about expired/missing 2FA credentials then uncomment
# email: [email protected]
# Uncomment this if your SMTP username is different than your sender address (for services like AWS SES)
# username: ""
# default to is same as email above
# to: [email protected]
# password:
# host: smtp.test.com
# port: 587
# If your email provider doesn't handle TLS
# no_tls: true
# valid values are - global (default - uses .com) or china (uses .com.cn)
region: global

drive:
destination: "./drive"
remove_obsolete: true
sync_interval: -1
ignore:
- "*.psd"
- .git/
filters:
# File filters to be included in syncing iCloud drive content
folders:
- dir1/dir2/dir3
- Keynote
- icloudpy
- Obsidian
file_extensions:
# File extensions to be included
- pdf
- png
- jpg
- jpeg
- md
- band
- xmcf
photos:
destination: photos
remove_obsolete: false
sync_interval: -1
all_albums: false # Optional, default false. If true preserve album structure. If same photo is in multpile albums creates duplicates on filesystem
# folder_format: "%Y/%m" # optional, if set put photos in subfolders according to format. Format cheatsheet - https://strftime.org
filters:
# if all_albums is false - albums list is used as filter-in, if all_albums is true - albums list is used as filter-out
# if albums list is empty and all_albums is false download all photos to "all" folder. if empty and all_albums is true download all folders
albums:
- "album 2"
- album-1
file_sizes:
# Valid values are [original, medium or thumb]
- original
- medium
- thumb
17 changes: 17 additions & 0 deletions tests/test_config_parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
DEFAULT_RETRY_LOGIN_INTERVAL_SEC,
DEFAULT_ROOT_DESTINATION,
DEFAULT_SYNC_INTERVAL_SEC,
ENV_CONFIG_FILE_PATH_KEY,
config_parser,
read_config,
)
Expand All @@ -20,10 +21,26 @@
class TestConfigParser(unittest.TestCase):
"""Tests for config parser."""

def tearDown(self):
"""Clean up."""
if ENV_CONFIG_FILE_PATH_KEY in os.environ:
os.environ.pop(ENV_CONFIG_FILE_PATH_KEY)

def test_read_config_default_config_path(self):
"""Test for Default config path."""
self.assertIsNotNone(read_config(config_path=tests.CONFIG_PATH))

def test_read_config_env_config_path(self):
"""Test for ENV_CONFIG_FILE_PATH."""
os.environ[ENV_CONFIG_FILE_PATH_KEY] = tests.ENV_CONFIG_PATH
config = read_config(
config_path=os.environ.get(ENV_CONFIG_FILE_PATH_KEY, tests.CONFIG_PATH)
)
self.assertEqual(
config["app"]["logger"]["filename"],
"config_loaded_using_env_config_path.log",
)

def test_read_config_overridden_config_path(self):
"""Test for Overridden config path."""
self.assertIsNotNone(read_config(config_path=tests.CONFIG_PATH))
Expand Down

0 comments on commit c696481

Please sign in to comment.