diff --git a/gimme_iphotos/__init__.py b/gimme_iphotos/__init__.py index c15d9a3..3eb4014 100644 --- a/gimme_iphotos/__init__.py +++ b/gimme_iphotos/__init__.py @@ -46,6 +46,13 @@ def get_cli_args() -> argparse.Namespace: "--password", help="iCloud password. Can be specified interactively if not set.", ) + parser.add_argument( + "--cookie-directory", + dest="cookie_directory", + help="Directory to store cookie files.\n" + + "Cookies can be used to avoid authentication step for subsequent runs.\n" + + "If not set, cookies are stored in a temporary directory and usually deleted between restarts.", + ) parser.add_argument( "-d", "--destination", diff --git a/gimme_iphotos/downloader.py b/gimme_iphotos/downloader.py index ded4324..29c4713 100644 --- a/gimme_iphotos/downloader.py +++ b/gimme_iphotos/downloader.py @@ -22,6 +22,7 @@ class DownloaderApp: DEFAULTS = { "username": None, "password": None, + "cookie_directory": None, "destination": None, "overwrite": False, "remove": False, @@ -119,9 +120,15 @@ def connect_to_icloud( ) -> PyiCloudService: self.logger.info("Connecting to iCloud…") if config["password"] == "": - api = PyiCloudService(config["username"]) + api = PyiCloudService( + config["username"], cookie_directory=config["cookie_directory"] + ) else: - api = PyiCloudService(config["username"], config["password"]) + api = PyiCloudService( + config["username"], + password=config["password"], + cookie_directory=config["cookie_directory"], + ) if api.requires_2sa: print("Two-step authentication required.") @@ -193,8 +200,8 @@ def download_photos( # FIXME Cancelling doesn't work well with ThreadPoolExecutor. I didn't find a way to cancel tasks if they're # already running. Maybe it makes sense using lower level of threading API. with ThreadPoolExecutor(max_workers=parallel) as executor: + downloads = [] try: - downloads = [] for photo in collection: total_count += 1 filename = self.name_photo(photo, icloud_photos, destination)