diff --git a/docs/authentication.md b/docs/authentication.md index a0da9d563..b70528919 100644 --- a/docs/authentication.md +++ b/docs/authentication.md @@ -17,7 +17,7 @@ If you want to send notification emails using your Gmail account, and you have e ```{versionadded} 1.21.0 ``` -There are two ways to provide MFA code to `icloudpd`: +There are two ways to provide an MFA code to `icloudpd`: - Using console - Using web interface @@ -28,7 +28,7 @@ Other options: *webui* ## Access from Mainland China -Access to iCloud.com is blocked from mainland China. `icloudpd` can be used with [`--domain cn`](domain-parameter) parameter to support downloading iCloud Photos from mainland China, however, people reported mixed results with that parameter. +Access to iCloud.com is blocked from mainland China. `icloudpd` can be used with the [`--domain cn`](domain-parameter) parameter to support downloading iCloud Photos from mainland China; however, people have reported mixed results with that parameter. ## FIDO @@ -40,7 +40,7 @@ Advanced Data Protection (ADP) for iCloud accounts is not supported because `icl ## Occasional Errors -Some authentication errors may be resolved by clearing `.pyicloud` subfolder in the user's home directory. [Example](https://github.com/icloud-photos-downloader/icloud_photos_downloader/issues/772#issuecomment-1950963522) +Some authentication errors may be resolved by clearing the `.pyicloud` subfolder in the user's home directory. [Example](https://github.com/icloud-photos-downloader/icloud_photos_downloader/issues/772#issuecomment-1950963522) (password-providers)= ## Password Providers @@ -51,16 +51,16 @@ Some authentication errors may be resolved by clearing `.pyicloud` subfolder in WebUI support ``` -Passwords for iCloud access can be supplied by user in four ways: +Passwords for iCloud access can be supplied by the user in four ways: - Using [`--password`](password-parameter) command line parameter - Using keyring - Using console - Using web interface -It is possible to specify which of these three ways `icloudpd` should use, by specifying them with [`--password-provider`](password-provider-parameter) parameter. More than one can be specified and the order -of providers matches the order then will be checked for password. E.g. `--password-provider keyring --password-provider console` means that `icloudpd` will check password in keyring first and then, if no password found, ask for password in the console. +It is possible to specify which of these four ways `icloudpd` should use, by specifying them with the [`--password-provider`](password-provider-parameter) parameter. More than one can be specified and the order +of providers matches the order they will be checked for a password. E.g., `--password-provider keyring --password-provider console` means that `icloudpd` will check the password in the keyring first and then, if no password is found, ask for a password in the console. -Keyring password provider, if specified, saves valid password back into keyring. +The keyring password provider, if specified, saves the valid password back into the keyring. Console and Web UI are not compatible with each other. Console or WebUI providers, if specified, must be last in the list of providers because they cannot be skipped. @@ -90,7 +90,7 @@ Use `icloud`, not `icloudpd` (multiple-accounts-and-configs)= ## Using Multiple Accounts and Config -`icloudpd` can process iCloud collections for multiple accounts or use multiple configs for one account. This is achived by specifying `--username` parameter multiples times: any options specified after `--username` will be applied to mentioned user only. Parameters specified before first `--username` work as defaults for all other user configs. Global app-wide settings can be specified anywhere. +`icloudpd` can process iCloud collections for multiple accounts or use multiple configs for one account. This is achieved by specifying the `--username` parameter multiple times: any options specified after `--username` will be applied to the mentioned user only. Parameters specified before the first `--username` work as defaults for all other user configs. Global app-wide settings can be specified anywhere. ### Example: using two user accounts @@ -100,10 +100,10 @@ $ icloudpd --use-os-locale --cookie-directory ./cookies --username alice@apple.c Explanation -- `--use-os-locale` is global parameter and can be used anywhere -- `--cookie-directory` is a default for both users; it is okay to use same folder since session and coockies are stored in files based on user name, so they would not collide -- `--directory ./alice` is specifying that all photos for Alice will be downloaded into ./alice folder -- `--directory ./bob` is specifying that all photos for Alice will be downloaded into ./alice folder +- `--use-os-locale` is a global parameter and can be used anywhere +- `--cookie-directory` is a default for both users; it is okay to use the same folder since sessions and cookies are stored in files based on the user name, so they would not collide +- `--directory ./alice` specifies that all photos for Alice will be downloaded into the ./alice folder +- `--directory ./bob` specifies that all photos for Bob will be downloaded into the ./bob folder ### Example: using two configs for one account @@ -114,9 +114,9 @@ $ icloudpd --cookie-directory ./cookies --username alice@apple.com --directory . Explanation - `--cookie-directory` is a default for both configs -- `--directory ./photos --skip-videos` is specifying that all photos for Alice will be downloaded into ./photos folder -- `--directory ./videos --skip-photos` is specifying that all videos for Alice will be downloaded into ./videos folder -- `--use-os-locale` is global parameter and can be used anywhere +- `--directory ./photos --skip-videos` specifies that all photos for Alice will be downloaded into the ./photos folder +- `--directory ./videos --skip-photos` specifies that all videos for Alice will be downloaded into the ./videos folder +- `--use-os-locale` is a global parameter and can be used anywhere ```{versionadded} 1.32.0 ``` diff --git a/docs/install.md b/docs/install.md index 371a40dc5..df75b97b2 100644 --- a/docs/install.md +++ b/docs/install.md @@ -7,8 +7,8 @@ There are three ways to run `icloudpd`: icloudpd --username your@email.address --directory photos --watch-with-interval 3600 ``` -1. Use package manager to install, update, and, in some cases, run ([Docker](#docker), [PyPI](#pypi), [AUR](#aur), [npm](#npm)) -1. Build and run from the source +1. Use a package manager to install, update, and, in some cases, run ([Docker](#docker), [PyPI](#pypi), [AUR](#aur), [npm](#npm)) +1. Build and run from source (docker)= ## Docker @@ -17,9 +17,9 @@ There are three ways to run `icloudpd`: docker run -it --rm --name icloudpd -v $(pwd)/Photos:/data -e TZ=America/Los_Angeles icloudpd/icloudpd:latest icloudpd --directory /data --username my@email.address --watch-with-interval 3600 ``` -Image asset date will be converted to specified TZ and then used for creating folders (see [`--folder-structure`](folder-structure-parameter) parameter) +The image asset date will be converted to the specified TZ and then used for creating folders (see the [`--folder-structure`](folder-structure-parameter) parameter). -Synchronization logic can be adjusted with command-line parameters. Run the following to get full list: +The synchronization logic can be adjusted with command-line parameters. Run the following to get the full list: ``` sh docker run -it --rm icloudpd/icloudpd:latest icloudpd --help ``` @@ -40,7 +40,7 @@ Getting Docker: - On Linux, Docker engine and client can be installed using platform package managers, e.g. [Installing on Ubuntu](https://www.digitalocean.com/community/tutorials/how-to-install-and-use-docker-on-ubuntu-20-04) -- Appliance (e.g. NAS) will have their own way to install Docker engines and running containers - see manufacturer's instructions. +- Appliances (e.g., NAS) will have their own way to install Docker engines and run containers - see the manufacturer's instructions. ``` (pypi)= @@ -65,7 +65,7 @@ on Windows: pip install icloudpd --user ``` -Plus add `C:\Users\\AppData\Roaming\Python\Python\Scripts` to PATH. The exact path will be given at the end of `icloudpd` installation. +Also add `C:\Users\\AppData\Roaming\Python\Python\Scripts` to PATH. The exact path will be given at the end of the `icloudpd` installation. ```` ```{note} @@ -88,7 +88,7 @@ cd icloudpd-bin makepkg -sirc ``` -With the use of the AUR helper e.g. [yay](https://github.com/Jguer/yay) the installation process would look like this: +With the use of an AUR helper, e.g., [yay](https://github.com/Jguer/yay), the installation process would look like this: ``` sh yay -S icloudpd-bin @@ -103,17 +103,17 @@ npx --yes icloudpd --directory /data --username my@email.address --watch-with-in ## macOS binary -`icloudpd` is available as Intel 64bit binary for macOS, but works on ARM macs too (M1, M2, M3). +`icloudpd` is available as an Intel 64-bit binary for macOS, but works on ARM Macs too (M1, M2, M3). -Here are the steps to make it working: -- download binary from GitHub [Releases](https://github.com/icloud-photos-downloader/icloud_photos_downloader/releases) into desired local folder -- add executable flag by running `chmod +x icloudpd-1.32.0-macos-amd64` -- start it from the terminal: `icloudpd-1.32.0-macos-amd64` -- Apple will tell you that it cannot check for malicious software and refuse to run the app; click "Ok" -- Open "System Settings"/"Privacy & Security" and find `icloudpd-1.32.0-macos-amd64` as blocked app; Click "Allow" +Here are the steps to make it work: +- Download the binary from GitHub [Releases](https://github.com/icloud-photos-downloader/icloud_photos_downloader/releases) into the desired local folder +- Add the executable flag by running `chmod +x icloudpd-1.32.0-macos-amd64` +- Start it from the terminal: `icloudpd-1.32.0-macos-amd64` +- Apple will tell you that it cannot check for malicious software and refuse to run the app; click "OK" +- Open "System Settings"/"Privacy & Security" and find `icloudpd-1.32.0-macos-amd64` as a blocked app; click "Allow" - Start `icloudpd-1.32.0-macos-amd64` from the terminal again - Apple will show another warning; click "Open" -- After that you can run `icloudpd-1.32.0-macos-amd64 --help` or any other supported command/option +- After that, you can run `icloudpd-1.32.0-macos-amd64 --help` or any other supported command/option ## Error on the First Run diff --git a/docs/mode.md b/docs/mode.md index fc7ae7085..669a866d3 100644 --- a/docs/mode.md +++ b/docs/mode.md @@ -7,16 +7,16 @@ Added `--delete-after-download` parameter `icloudpd` works in one of three modes of operation: Copy -: Download assets from iCloud that are are not in the local storage +: Download assets from iCloud that are not in the local storage This is the default mode Sync -: Download assets from iCloud that are are not in the local storage (same as Copy). In addition, delete local files that were removed in iCloud (moved into "Recently Deleted" album) +: Download assets from iCloud that are not in the local storage (same as Copy). In addition, delete local files that were removed in iCloud (moved into the "Recently Deleted" album) This mode is selected with [`--auto-delete`](auto-delete-parameter) parameter Move -: Download assets from iCloud that are are not in the local storage (same as Copy). Then delete assets in iCloud that are in local storage, optionally leaving recent ones in iCloud +: Download assets from iCloud that are not in the local storage (same as Copy). Then delete assets in iCloud that are in local storage, optionally leaving recent ones in iCloud This mode is selected with [`--keep-icloud-recent-days`](keep-icloud-recent-days-parameter) parameter diff --git a/docs/naming.md b/docs/naming.md index 06d59e8e3..1f6074206 100644 --- a/docs/naming.md +++ b/docs/naming.md @@ -41,9 +41,9 @@ LC_ALL=ru_RU.UTF.8 icloudpd --use-os-locale --version `--file-match-policy` parameter added and `name-id7` policy implemented ``` -In large iCloud collections it is possible to have name collisions. To avoid collisions if files need to be downloaded into the same folder, use [`--file-match-policy`](file-match-policy-parameter) parameter: -- add unique invariant asset identification suffix to the name (e.g. **"IMG_1234_QAZXSW.JPG"**) with `--file-match-policy name-id7` -- de-duplicate by adding file size as a suffix (e.g. **"IMG_1234-67890.JPG"** for second asset); `--file-match-policy name-size-dedup-with-suffix` - it is default +In large iCloud collections, it is possible to have name collisions. To avoid collisions if files need to be downloaded into the same folder, use the [`--file-match-policy`](file-match-policy-parameter) parameter: +- add a unique invariant asset identification suffix to the name (e.g., **"IMG_1234_QAZXSW.JPG"**) with `--file-match-policy name-id7` +- de-duplicate by adding file size as a suffix (e.g., **"IMG_1234-67890.JPG"** for the second asset); `--file-match-policy name-size-dedup-with-suffix` - this is the default ## Live Photos @@ -51,10 +51,10 @@ In large iCloud collections it is possible to have name collisions. To avoid col `--live-photo-mov-filename-policy` parameter added and `original` policy implemented ``` -Live Photo assets have two components: still image and short video. `icloudpd` can download both and allows customizing file name of the video portion with [`--live-photo-mov-filename-policy`](live-photo-mov-filename-policy-parameter) parameter: +Live Photo assets have two components: a still image and a short video. `icloudpd` can download both and allows customizing the file name of the video portion with the [`--live-photo-mov-filename-policy`](live-photo-mov-filename-policy-parameter) parameter: -- Use video file name the same as still image with `original` policy; use `--file-match-policy name-id7` to avoid clashes of video file with other videos. -- Use suffix from the still image with `suffix` policy: **"IMG_1234_HEVC.MOV"** for **"IMG_1234.HEIC"** still. This is default and works for HEIC still images only +- Use the same video file name as the still image with the `original` policy; use `--file-match-policy name-id7` to avoid clashes of the video file with other videos. +- Use a suffix from the still image with the `suffix` policy: **"IMG_1234_HEVC.MOV"** for **"IMG_1234.HEIC"** still image. This is the default and works for HEIC still images only ## Unicode diff --git a/docs/nas.md b/docs/nas.md index f5a3f3931..9b9597072 100644 --- a/docs/nas.md +++ b/docs/nas.md @@ -4,7 +4,7 @@ The following are example setups for NAS. ## TrueNAS -Use [`Install Custom App` button](https://www.truenas.com/docs/scale/23.10/scaletutorials/apps/usingcustomapp/) to set up `icloudpd`: +Use the [`Install Custom App` button](https://www.truenas.com/docs/scale/23.10/scaletutorials/apps/usingcustomapp/) to set up `icloudpd`: | Field | Value | Note | |-------|-------|------| Application Name | `icloudpd` | @@ -22,15 +22,15 @@ Portal Configuration/Protocol to Portal | `HTTP Protocol` | Portal Configuration/Use Node IP for Portal IP/Domain | checked | Portal Configuration/Port | `9090` | Same as "Port Forwarding/Host Port" above -Once the app has started, connect to the [WebUI](webui) to enter password and MFA code one of two ways: -- Using browser from your PC to 9090 port of your NAS -- Clicking on `icloudpd` button in Detail/Application Info section of TrueNAS portal +Once the app has started, connect to the [WebUI](webui) to enter the password and MFA code in one of two ways: +- Using a browser from your PC to port 9090 of your NAS +- Clicking on the `icloudpd` button in the Detail/Application Info section of the TrueNAS portal ## Running on Synology NAS -The error `Failed to execv() /tmp/staticx-kJmNbp` has a workaround by (from an SSH terminal in my case) running `sudo mount /tmp -o remount,exec`. [#788](https://github.com/icloud-photos-downloader/icloud_photos_downloader/issues/788) +The error `Failed to execv() /tmp/staticx-kJmNbp` has a workaround by running `sudo mount /tmp -o remount,exec` (from an SSH terminal). [#788](https://github.com/icloud-photos-downloader/icloud_photos_downloader/issues/788) -CPU/Arch [used by Synology](https://kb.synology.com/en-me/DSM/tutorial/What_kind_of_CPU_does_my_NAS_have) other than amd64 (after x12): +CPU/Arch [used by Synology](https://kb.synology.com/en-me/DSM/tutorial/What_kind_of_CPU_does_my_NAS_have) other than amd64 (from x12 onwards): | Models | CPU | Arch | |-------|-------|------| DS124, DS423, DS223j, DS223 | Realtek RTD1619B | arm64 | @@ -53,6 +53,6 @@ DS414j | Mindspeed Comcerto C200 | arm32v7 DS413, DS213+ | Freescale P1022 | power (Unsupported) | DS413j, DS213, DS213air | Marvell Kirkwood 88F6282 | arm32v5 (Unsupported) | -Non x86 64bit models from x12 and before are not supported +Non-x86 64-bit models from x12 and earlier are not supported. -[Additional info on Marvel](https://www.kernel.org/doc/html/v6.1/arm/marvell.html) +[Additional info on Marvell](https://www.kernel.org/doc/html/v6.1/arm/marvell.html) diff --git a/docs/raw.md b/docs/raw.md index e360873e7..b32c8ca67 100644 --- a/docs/raw.md +++ b/docs/raw.md @@ -3,15 +3,15 @@ ## Apple ProRAW/ProRes Apple supports shooting stills and videos in [DNG](https://en.wikipedia.org/wiki/Digital_Negative) format and -they can be downloaded by `icloudpd` as any other supported format. +they can be downloaded by `icloudpd` like any other supported format. ## Imported RAW images ```{versionadded} 1.19.0 ``` -RAW images from third party cameras can be imported into Apple Photos or uploaded to iCloud.com. -These type of assets can also be downloaded by `icloudpd`. The following formats are recognized: +RAW images from third-party cameras can be imported into Apple Photos or uploaded to iCloud.com. +These types of assets can also be downloaded by `icloudpd`. The following formats are recognized: - Adobe DNG - same as Apple ProRAW - Canon CR2, CR3, and CRW @@ -29,13 +29,13 @@ These type of assets can also be downloaded by `icloudpd`. The following formats iCloud supports images with two representations. `icloudpd` can download one or both representations. -One representation will be `original` [size](size) and another `alternative`. +One representation will be the `original` [size](size) and the other `alternative`. -As of June 2024, icloud.com always shows assets with two representations as RAW+JPEG. Photo app on Mac +As of June 2024, icloud.com always shows assets with two representations as RAW+JPEG. The Photos app on Mac allows choosing which representation to treat as original, but it is not clear what that setting changes. -`icloudpd` disambiguates the behavior with [`--align-raw`](align-raw-parameter) parameter: +`icloudpd` disambiguates the behavior with the [`--align-raw`](align-raw-parameter) parameter: -- *original* always treat RAW as original [size](size) -- *alternative* always treat RAW as alternative [size](size) -- *as-is* treat RAW as it is in iCloud data +- *original* always treats RAW as the original [size](size) +- *alternative* always treats RAW as the alternative [size](size) +- *as-is* treats RAW as it is in iCloud data diff --git a/docs/reference.md b/docs/reference.md index 6b7fafa50..681e71736 100644 --- a/docs/reference.md +++ b/docs/reference.md @@ -1,14 +1,14 @@ # Reference -This is a list of all options available for command line interface (CLI) of the `icloudpd` +This is a list of all options available for the command line interface (CLI) of `icloudpd` (until-found-parameter)= `--until-found X` : Checks assets, from most recently added to the oldest, for their local copies. - Downloads if not present locally. Whole process stops once X number of subsequent checks result in a local file matching remote. + Downloads if not present locally. The whole process stops once X number of subsequent checks result in a local file matching the remote. - This option is a useful optimization for incremental updates: only small portion (X) of the existing local storage will be rechecked for existence, saving on local IO. However, the process will not "fill the gaps" in local storage if any exist (and will not identify them). + This option is a useful optimization for incremental updates: only a small portion (X) of the existing local storage will be rechecked for existence, saving on local I/O. However, the process will not "fill the gaps" in local storage if any exist (and will not identify them). ```{note} Assets are checked by the date they were added to iCloud, not by the date they were taken/created. @@ -20,7 +20,7 @@ This is a list of all options available for command line interface (CLI) of the : Checks X most recently added assets for their local copies. Downloads if not present locally. - This option is mostly useful while testing and experimenting with parameters to limit the volume of downloads + This option is mostly useful while testing and experimenting with parameters to limit the volume of downloads. ```{note} Assets are checked by the date they were added to iCloud, not by the date they were taken/created. @@ -29,7 +29,7 @@ This is a list of all options available for command line interface (CLI) of the (album-parameter)= `--album X` -: Specifies what Album(s) to download. +: Specifies which album(s) to download. When not specified, the whole asset collection is considered. @@ -40,116 +40,142 @@ This is a list of all options available for command line interface (CLI) of the (list-albums-parameter)= `--list-albums` -: Lists all available albums +: Lists all available albums. (library-parameter)= `--library X` -: Specifies what Libarary to use. +: Specifies which library to use. Default: "Personal Library". ```{note} - Only one library can be used by `icloudpd` + Only one library can be used by `icloudpd`. ``` + ```{versionadded} 1.16.0 + Shared library support added for iOS 16 shared libraries + ``` + (list-libraries-parameter)= `--list-libraries` -: Lists all libraries available for account +: Lists all libraries available for the account. + + ```{versionadded} 1.16.0 + Shared library support added for iOS 16 shared libraries + ``` (watch-with-interval-parameter)= `--watch-with-interval X` -: Runs `icloudpd` forever, periodically re-checking iCloud for changes ("watch"). Interval is specified in seconds, e.g. 3600 will be 1hr interval. +: Runs `icloudpd` forever, periodically re-checking iCloud for changes ("watch"). The interval is specified in seconds, e.g. 3600 will be a 1-hour interval. - Too short interval may trigger throttling on Apple side, although no evidence has been reported. + Too short an interval may trigger throttling on Apple's side, although no evidence has been reported. + + ```{versionadded} 1.10.0 + ``` (version-parameter)= `--version` -: Reports current version and commit hash & date that version was build from. +: Reports the current version and commit hash & date that the version was built from. ```{note} - If `--use-os-locale` was specified before `--version`, then date is formatted according to OS locale. + If `--use-os-locale` was specified before `--version`, then the date is formatted according to the OS locale. ``` (use-os-locale-parameter)= `--use-os-locale` -: Instructs `icloudpd` to use OS locale. If not specified (and by default), US English is used. +: Instructs `icloudpd` to use the OS locale. If not specified (and by default), US English is used. + + ```{versionadded} 1.22.0 + ``` ```{seealso} - [File Naming](naming) section discusses affected behavior + The [File Naming](naming) section discusses the affected behavior ``` (dry-run-parameter)= `--dry-run` -: If specified, no changes to local storage or iCloud remote storage is made. +: If specified, no changes to local storage or iCloud remote storage are made. + + Authentication will be performed and remote files will be checked against local storage. Any differences will be reported instead of performing downloads. - Authentication will be performed and remote files will be checked against local storage. Any difference will be reported instead of performing download. + This parameter is useful for experimenting with new parameters. - This parameter is useful for experimenting with new parameters + ```{versionadded} 1.15.0 + ``` (domain-parameter)= `--domain X` -: Access to Apple servers is blocked from mainland China. As an alternative, iCloud service is available on internal .cn domain, which can be specified for `icloudpd` to work from mainland China. +: Access to Apple servers is blocked from mainland China. As an alternative, the iCloud service is available on an internal .cn domain, which can be specified for `icloudpd` to work from mainland China. Default is ".com". ".cn" is the only other option available. + ```{versionadded} 1.9.0 + ``` + (password-parameter)= `--password X` -: Specifies iCloud password to use for authentication +: Specifies the iCloud password to use for authentication. ```{note} - Supplying credentials through command line parameters is considered not a good practice since they can be logged and/or otherwise exposed. Consider using other [password providers](password-providers). + Supplying credentials through command line parameters is not considered a good practice since they can be logged and/or otherwise exposed. Consider using other [password providers](password-providers). ``` (directory-parameter)= `--directory X` -: Specifies root folder where [folder structure](folder-structure-parameter) will start and files will be downloaded. +: Specifies the root folder where the [folder structure](folder-structure-parameter) will start and files will be downloaded. (file-match-policy-parameter)= `--file-match-policy X` -: Specifies an algorithm (policy) to match remote to local files. +: Specifies an algorithm (policy) to match remote files to local files. + + ```{versionadded} 1.20.0 + ``` ```{seealso} - Discussion on [File Naming and Deduplication](naming) + Discussion of [File Naming and Deduplication](naming) ``` (username-parameter)= `--username X` -: Specifies AppleID (email address) used for authenticating to iCloud. May be used multiple times to introduce different configurations and/or accounts. See [Using Multiple Accounts and Config](multiple-accounts-and-configs) +: Specifies the AppleID (email address) used for authenticating to iCloud. May be used multiple times to introduce different configurations and/or accounts. See [Using Multiple Accounts and Config](multiple-accounts-and-configs). (auth-only-parameter)= `--auth-only` -: Performs authentication, persists auth results (tokens/cookies), and exists without processing assets +: Performs authentication, persists authentication results (tokens/cookies), and exits without processing assets. + + ```{versionadded} 1.17.0 + ``` (cookie-directory-parameter)= `--cookie-directory X` -: Customizes folder used for persisting authentication results (cookies/tokens). If not specified, `~/.pyicloud` is used. +: Customizes the folder used for persisting authentication results (cookies/tokens). If not specified, `~/.pyicloud` is used. (size-parameter)= `--size X` -: Customizes size of the asset to download. +: Customizes the size of the asset to download. ```{seealso} - Details on [Assets sizes](size) + Details on [Asset sizes](size) ``` (force-size-parameter)= `--force-size` -: If specified, only requested size will be downloaded. Otherwise, `original` size will be downloaded instead of missing size. +: If specified, only the requested size will be downloaded. Otherwise, the `original` size will be downloaded instead of the missing size. ```{seealso} [`--size` parameter](size-parameter) @@ -158,12 +184,12 @@ This is a list of all options available for command line interface (CLI) of the (live-photo-size-parameter)= `--live-photo-size X` -: Customizes size of the live photo assets to download. +: Customizes the size of the live photo assets to download. (skip-videos-parameter)= `--skip-videos` -: If specified, video assets will not be processed +: If specified, video assets will not be processed. (skip-photos-parameter)= `--skip-photos` @@ -172,17 +198,17 @@ This is a list of all options available for command line interface (CLI) of the ``` -: If specified, photos assets will not be processed +: If specified, photo assets will not be processed. (skip-live-photos-parameter)= `--skip-live-photos` -: If specified, live photo assets will not be processed +: If specified, live photo assets will not be processed. (auto-delete-parameter)= `--auto-delete` -: If specified, assets deleted in iCloud (actually moved to Recently Deleted album), will also be deleted locally. +: If specified, assets deleted in iCloud (actually moved to the Recently Deleted album) will also be deleted locally. ```{seealso} [Modes of operation](mode) @@ -191,13 +217,13 @@ This is a list of all options available for command line interface (CLI) of the (delete-after-download-parameter)= `--delete-after-download` -: If specified, assets downloaded locally will be deleted in iCloud (actually moved to Recently Deleted album). Deprecated, use [`--keep-icloud-recent-days`](keep-icloud-recent-days-parameter) instead +: If specified, assets downloaded locally will be deleted in iCloud (actually moved to the Recently Deleted album). Deprecated, use [`--keep-icloud-recent-days`](keep-icloud-recent-days-parameter) instead. ```{note} - If remote assets were not downloaded, e.g. because they were already in local storage, they will NOT be deleted in iCloud. + If remote assets were not downloaded, e.g., because they were already in local storage, they will NOT be deleted in iCloud. ``` - ```{versionadded} 1.21.0 + ```{versionadded} 1.8.0 ``` ```{deprecated} 1.26.0 @@ -206,13 +232,13 @@ This is a list of all options available for command line interface (CLI) of the (keep-icloud-recent-days-parameter)= `--keep-icloud-recent-days X` -: Deletes assets in iCloud after they were downloaded or confirmed present locally, except the ones taken within the specified number of days. If set to 0, all photos will be deleted from iCloud. +: Deletes assets in iCloud after they were downloaded or confirmed to be present locally, except for the ones taken within the specified number of days. If set to 0, all photos will be deleted from iCloud. -: If any filters are used, e.g. [`--skip-videos`](skip-videos-parameter), then assets excluded from processing by filters are not subject to deletion from iCloud. For example, running icloudpd with [`--skip-videos`](skip-videos-parameter) on a huge iCloud collection of videos will download and delete nothing. +: If any filters are used, e.g., [`--skip-videos`](skip-videos-parameter), then assets excluded from processing by filters are not subject to deletion from iCloud. For example, running icloudpd with [`--skip-videos`](skip-videos-parameter) on a huge iCloud collection of videos will download and delete nothing. -: Timestamp when the assets was taken (aka "created date") as reported by iCloud is used for calculating age of the asset. For example, asset taken in 2000, but added to iCloud in 2024, will be 25 years old in 2025. Same timestamp is used for the folder structure in the current system. +: The timestamp when the asset was taken (aka "created date") as reported by iCloud is used for calculating the age of the asset. For example, an asset taken in 2000, but added to iCloud in 2024, will be 25 years old in 2025. The same timestamp is used for the folder structure in the current system. -: If parameter is not specified, then nothing is deleted from iCloud. +: If the parameter is not specified, then nothing is deleted from iCloud. ```{versionadded} 1.26.0 ``` @@ -226,7 +252,7 @@ This is a list of all options available for command line interface (CLI) of the (only-print-filenames-parameter)= `--only-print-filenames` -: If specified, no downloading will occur, but only file paths printed in the output (no other info goes into output either). +: If specified, no downloading will occur, but only file paths will be printed in the output (no other info goes into the output either). ```{seealso} [`--dry-run` parameter](dry-run-parameter) @@ -234,102 +260,117 @@ This is a list of all options available for command line interface (CLI) of the (folder-structure-parameter)= `--folder-structure X` -: Specifies sub folder naming scheme. +: Specifies the subfolder naming scheme. ```{seealso} - Details in [Folder structure](folder-structure) section. + Details in the [Folder structure](folder-structure) section. ``` (set-exif-datetime-parameter)= `--set-exif-datetime` -: If specified, EXIF data for the image will be updated with date/time of the assets take/created. Only if EXIF does not exist already in the asset. +: If specified, EXIF data for the image will be updated with the date/time the asset was taken/created. Only if EXIF does not already exist in the asset. (no-progress-bar-parameter)= `--no-progress-bar` -: If specified, progress bar is suppressed. Valuable when streaming output to file +: If specified, the progress bar is suppressed. This is valuable when streaming output to a file. (keep-unicode-in-filenames-parameter)= `--keep-unicode-in-filenames` -: If specified, unicode chars will be preserved in filenames. Otherwise they are removed (default). +: If specified, Unicode characters will be preserved in filenames. Otherwise they are removed (default). + + ```{versionadded} 1.18.0 + ``` (live-photo-mov-filename-policy-parameter)= `--live-photo-mov-filename-policy X` -: Customizes naming of the video portion of the live photos. +: Customizes the naming of the video portion of live photos. + + ```{versionadded} 1.18.0 + ``` ```{seealso} - Details in [Live Photo](naming) section. + Details in the [Live Photo](naming) section. ``` (align-raw-parameter)= `--align-raw X` -: Customizes treating of the RAW+JPEG assets. +: Customizes the treatment of RAW+JPEG assets. + + ```{versionadded} 1.19.0 + ``` ```{seealso} - Details in [RAW+JPEG](raw) section. + Details in the [RAW+JPEG](raw) section. ``` (password-provider-parameter)= `--password-provider X` -: Customizes intake of the password for iCloud authentication. +: Customizes the intake of the password for iCloud authentication. + + ```{versionadded} 1.20.0 + ``` ```{seealso} - Details in [Password providers](password-providers) section. + Details in the [Password providers](password-providers) section. ``` (mfa-provider-parameter)= `--mfa-provider X` -: Customizes intake of the multi-factor authentication (MFA) code for iCloud authentication. +: Customizes the intake of the multi-factor authentication (MFA) code for iCloud authentication. ```{seealso} - Details in [MFA providers](authentication) section. + Details in the [MFA providers](authentication) section. ``` (xmp-sidecar-parameter)= `--xmp-sidecar` -: Export additional data as XMP sidecar files (default: don't export) +: Exports additional data as XMP sidecar files (default: don't export). + + ```{versionadded} 1.25.0 + ``` (smtp-parameter)= `--smtp-username X`, `--smtp-password X`, `--smtp-host X`, `--smtp-port X`, `--smtp-no-tls` -: Settings for SMTP notification for expired/needed authentication. +: Settings for SMTP notifications for expired/needed authentication. (notification-email-parameter)= `--notification-email X`, `--notification-email-from X` -: Settings for email notification addressing +: Settings for email notification addressing. (notification-script-parameter)= `--notification-script X` -: Script to be executed for notification on expired MFA +: Script to be executed for notifications on expired MFA. (skip-created-before-parameter)= `--skip-created-before` -: Does not process assets created before specified timestamp. Timestamp is in ISO format, e.g 2025-06-01, or as interval from now, e.g. 5d. If timezone is not specified for ISO format, then local timezone is used. +: Does not process assets created before the specified timestamp. The timestamp is in ISO format, e.g., 2025-06-01, or as an interval backwards from the current date, e.g., 5d (5 days ago). If the timezone is not specified for ISO format, then the local timezone is used. ```{versionadded} 1.28.0 ``` ```{note} - The date is when the asset was created, not added to the iCloud. + The date is when the asset was created, not when it was added to iCloud. ``` (skip-created-after-parameter)= `--skip-created-after` -: Does not process assets created after specified timestamp. Timestamp is in ISO format, e.g 2025-06-01, or as interval from now, e.g. 5d. If timezone is not specified for ISO format, then local timezone is used. +: Does not process assets created after the specified timestamp. The timestamp is in ISO format, e.g., 2025-06-01, or as an interval backwards from the current date, e.g., 5d (5 days ago). If the timezone is not specified for ISO format, then the local timezone is used. ```{versionadded} 1.29.0 ``` ```{note} - The date is when the asset was created, not added to the iCloud. + The date is when the asset was created, not when it was added to iCloud. ``` diff --git a/docs/size.md b/docs/size.md index fe56e6f0f..16e9b4d0f 100644 --- a/docs/size.md +++ b/docs/size.md @@ -11,11 +11,11 @@ Each asset in iCloud may have multiple sizes available for downloading: - medium - thumb -Size can be selected with `--size` parameter and multiple specifications are accepted (e.g. `--size original --size medium`). Default is `original`. +Size can be selected with the `--size` parameter and multiple specifications are accepted (e.g., `--size original --size medium`). The default is `original`. -If size parameter is specified, but it is not available for the asset in iCloud, then `original` is downloaded, unless `--force-size` is specified. +If the size parameter is specified, but it is not available for the asset in iCloud, then `original` is downloaded, unless `--force-size` is specified. -Assets for sizes other than original will have suffix added to their name, e.g. `IMG-1234-medium.JPG`. +Assets for sizes other than original will have a suffix added to their name, e.g., `IMG-1234-medium.JPG`. ## Special Sizes @@ -23,8 +23,8 @@ Assets for sizes other than original will have suffix added to their name, e.g. ``` Image edits are represented as a special size `adjusted`. Two common use cases related to edits: -- Download edited version or original if it was not edited: use `--size adjusted` parameter -- Download edit and original: use `--size adjusted --size original` parameters. Edits will have `-adjusted` suffix added if file extension is the same as original. +- Download the edited version or original if it was not edited: use the `--size adjusted` parameter +- Download edit and original: use the `--size adjusted --size original` parameters. Edits will have a `-adjusted` suffix added if the file extension is the same as the original. ```{note} Portraits are represented in iCloud as edits. diff --git a/docs/webui.md b/docs/webui.md index 323d968cd..dc32b48f5 100644 --- a/docs/webui.md +++ b/docs/webui.md @@ -3,4 +3,4 @@ ```{versionadded} 1.21.0 ``` -`icloudpd` can start internal web server on port 8080 and accept input (password and MFA code) from there instead of console. Web server is started only if `webui` selected for [MFA provider and/or Password Provider](authentication) +`icloudpd` can start an internal web server on port 8080 and accept input (password and MFA code) from there instead of the console. The web server is started only if `webui` is selected for [MFA provider and/or Password Provider](authentication). diff --git a/src/icloudpd/cli.py b/src/icloudpd/cli.py index 7f7733df8..280694534 100644 --- a/src/icloudpd/cli.py +++ b/src/icloudpd/cli.py @@ -39,10 +39,10 @@ def add_options_for_user(parser: argparse.ArgumentParser) -> argparse.ArgumentPa "-d", "--directory", metavar="DIRECTORY", - help="Local directory that should be used for download", + help="Local directory to use for downloads", ) cloned.add_argument( - "--auth-only", action="store_true", help="Create/Update cookie and session tokens only." + "--auth-only", action="store_true", help="Create/update cookie and session tokens only." ) cloned.add_argument( "--cookie-directory", @@ -51,7 +51,7 @@ def add_options_for_user(parser: argparse.ArgumentParser) -> argparse.ArgumentPa ) cloned.add_argument( "--size", - help="Image size to download. `medium` and `thumb` will always be added as suffixes to filenames, `adjusted` and `alternative` only if conflicting, `original` - never. If `adjusted` or `alternative` specified and is missing, then `original` is used. Default: %(default)s", + help="Image size to download. `medium` and `thumb` will always be added as suffixes to filenames, `adjusted` and `alternative` only if conflicting, `original` never. If `adjusted` or `alternative` is specified and missing, then `original` is used. Default: %(default)s", choices=["original", "medium", "thumb", "adjusted", "alternative"], default=None, action="append", @@ -74,7 +74,7 @@ def add_options_for_user(parser: argparse.ArgumentParser) -> argparse.ArgumentPa ) cloned.add_argument( "--until-found", - help="Download most recently added photos until we find x number of " + help="Download the most recently added photos until we find X number of " "previously downloaded consecutive photos (default: download all photos)", type=int, default=None, @@ -82,7 +82,7 @@ def add_options_for_user(parser: argparse.ArgumentParser) -> argparse.ArgumentPa cloned.add_argument( "-a", "--album", - help="Album(s) to download or whole collection if not specified", + help="Album(s) to download, or the whole collection if not specified", action="append", default=[], dest="albums", @@ -90,7 +90,7 @@ def add_options_for_user(parser: argparse.ArgumentParser) -> argparse.ArgumentPa cloned.add_argument( "-l", "--list-albums", - help="Lists the available albums", + help="List the available albums", action="store_true", ) cloned.add_argument( @@ -100,17 +100,17 @@ def add_options_for_user(parser: argparse.ArgumentParser) -> argparse.ArgumentPa ) cloned.add_argument( "--list-libraries", - help="Lists the available libraries", + help="List the available libraries", action="store_true", ) cloned.add_argument( "--skip-videos", - help="Don't download any videos (default: Download all photos and videos)", + help="Don't download any videos (default: download all photos and videos)", action="store_true", ) cloned.add_argument( "--skip-live-photos", - help="Don't download any live photos (default: Download live photos)", + help="Don't download any live photos (default: download live photos)", action="store_true", ) cloned.add_argument( @@ -120,40 +120,40 @@ def add_options_for_user(parser: argparse.ArgumentParser) -> argparse.ArgumentPa ) cloned.add_argument( "--force-size", - help="Only download the requested size (`adjusted` and `alternate` will not be forced). Default: download original if size is not available", + help="Only download the requested size (`adjusted` and `alternative` will not be forced). Default: download original if size is not available", action="store_true", ) cloned.add_argument( "--auto-delete", - help='Scans the "Recently Deleted" folder and deletes any files found in there. ' + help='Scan the "Recently Deleted" folder and delete any files found there. ' + "(If you restore the photo in iCloud, it will be downloaded again.)", action="store_true", ) cloned.add_argument( "--folder-structure", - help="Folder structure. If set to `none` all photos will just be placed into the download directory. Default: %(default)s", + help="Folder structure. If set to `none`, all photos will be placed into the download directory. Default: %(default)s", default="{:%Y/%m/%d}", type=validate_folder_structure, ) cloned.add_argument( "--set-exif-datetime", - help="Write the DateTimeOriginal exif tag from file creation date, if it doesn't exist.", + help="Write the DateTimeOriginal EXIF tag from file creation date, if it doesn't exist.", action="store_true", ) cloned.add_argument( "--smtp-username", - help="SMTP username, for sending email notifications when two-step authentication expires.", + help="SMTP username for sending email notifications when two-step authentication expires.", default=None, ) cloned.add_argument( "--smtp-password", - help="SMTP password, for sending email notifications when two-step authentication expires.", + help="SMTP password for sending email notifications when two-step authentication expires.", default=None, ) cloned.add_argument( "--smtp-host", - help="SMTP server host for notification", + help="SMTP server host for notifications", default="smtp.gmail.com", ) cloned.add_argument( @@ -164,7 +164,7 @@ def add_options_for_user(parser: argparse.ArgumentParser) -> argparse.ArgumentPa ) cloned.add_argument( "--smtp-no-tls", - help="Pass this flag to disable TLS for SMTP (TLS is required for Gmail)", + help="Disable TLS for SMTP (TLS is required for Gmail)", action="store_true", ) cloned.add_argument( @@ -184,7 +184,7 @@ def add_options_for_user(parser: argparse.ArgumentParser) -> argparse.ArgumentPa cloned.add_argument( "--notification-script", type=pathlib.Path, - help="Path to the external script to run when two factor authentication expires.", + help="Path to external script to run when two-factor authentication expires.", default=None, ) deprecated_kwargs: dict[str, Any] = {} @@ -194,67 +194,67 @@ def add_options_for_user(parser: argparse.ArgumentParser) -> argparse.ArgumentPa pass cloned.add_argument( "--delete-after-download", - help="Delete the photo/video after download it." - + ' The deleted items will be appear in the "Recently Deleted".' - + " Therefore, should not combine with --auto-delete option.", + help="Delete the photo/video after downloading it." + + ' The deleted items will appear in "Recently Deleted".' + + " Therefore, should not be combined with --auto-delete option.", action="store_true", **deprecated_kwargs, ) cloned.add_argument( "--keep-icloud-recent-days", - help="Keep photos newer than this many days in iCloud. Deletes the rest. " + help="Keep photos newer than this many days in iCloud. Delete the rest. " + "If set to 0, all photos will be deleted from iCloud.", type=int, default=None, ) cloned.add_argument( "--dry-run", - help="Do not modify local system or iCloud", + help="Do not modify the local system or iCloud", action="store_true", default=False, ) cloned.add_argument( "--keep-unicode-in-filenames", - help="Keep unicode chars in file names or remove non all ascii chars", + help="Keep Unicode characters in filenames, or remove all non-ASCII characters", action="store_true", default=False, ) cloned.add_argument( "--live-photo-mov-filename-policy", - help="How to produce filenames for video portion of live photos: `suffix` will add _HEVC suffix and `original` will keep filename as it is. Default: %(default)s", + help="How to produce filenames for the video portion of live photos: `suffix` will add _HEVC suffix and `original` will keep the filename as is. Default: %(default)s", choices=["suffix", "original"], default="suffix", type=lower, ) cloned.add_argument( "--align-raw", - help="For photo assets with raw and jpeg, treat raw always in the specified size: `original` (raw+jpeg), `alternative` (jpeg+raw), or unchanged (as-is). It matters when choosing sizes to download. Default: %(default)s", + help="For photo assets with RAW and JPEG, always treat RAW in the specified size: `original` (RAW+JPEG), `alternative` (JPEG+RAW), or unchanged (as-is). This matters when choosing sizes to download. Default: %(default)s", choices=["as-is", "original", "alternative"], default="as-is", type=lower, ) cloned.add_argument( "--file-match-policy", - help="Policy to identify existing files and de-duplicate. `name-size-dedup-with-suffix` appends file size to deduplicate. `name-id7` adds asset id from iCloud to all file names and does not de-duplicate. Default: %(default)s", + help="Policy to identify existing files and de-duplicate. `name-size-dedup-with-suffix` appends file size to de-duplicate. `name-id7` adds asset ID from iCloud to all filenames and does not de-duplicate. Default: %(default)s", choices=["name-size-dedup-with-suffix", "name-id7"], default="name-size-dedup-with-suffix", type=lower, ) cloned.add_argument( "--skip-created-before", - help="Do not process assets created before specified timestamp in ISO format (2025-01-02) or interval from now (20d)", + help="Do not process assets created before the specified timestamp in ISO format (2025-01-02) or interval backwards from now (20d = 20 days ago)", default=None, type=parse_timestamp_or_timedelta_tz_error, ) cloned.add_argument( "--skip-created-after", - help="Do not process assets created after specified timestamp in ISO format (2025-01-02) or interval from now (20d)", + help="Do not process assets created after the specified timestamp in ISO format (2025-01-02) or interval backwards from now (20d = 20 days ago)", default=None, type=parse_timestamp_or_timedelta_tz_error, ) cloned.add_argument( "--skip-photos", - help="Don't download any photos (default: Download all photos and videos)", + help="Don't download any photos (default: download all photos and videos)", action="store_true", ) return cloned @@ -265,7 +265,7 @@ def add_user_option(parser: argparse.ArgumentParser) -> argparse.ArgumentParser: cloned.add_argument( "-u", "--username", - help="AppleID email address. Starts new configuration group.", + help="Apple ID email address. Starts a new configuration group.", type=lower, ) cloned.add_argument( @@ -284,23 +284,23 @@ def parse_mfa_provider(provider: str) -> MFAProvider: elif provider.lower() == "webui": return MFAProvider.WEBUI else: - raise ValueError(f"Only `console` and `webui` are supported, but `{provider}` was supplied") + raise ValueError(f"Only `console` and `webui` are supported, but `{provider}` was provided") def add_global_options(parser: argparse.ArgumentParser) -> argparse.ArgumentParser: cloned = copy.deepcopy(parser) group = cloned.add_mutually_exclusive_group() - group.add_argument("--help", "-h", action="store_true", help="Show this info") + group.add_argument("--help", "-h", action="store_true", help="Show this information") group.add_argument( - "--version", help="Show the version, commit hash and timestamp", action="store_true" + "--version", help="Show the version, commit hash, and timestamp", action="store_true" ) cloned.add_argument( - "--use-os-locale", help="Use locale of the host OS to format dates", action="store_true" + "--use-os-locale", help="Use the locale of the host OS to format dates", action="store_true" ) cloned.add_argument( "--only-print-filenames", - help="Only prints the filenames of all files that will be downloaded " - "(not including files that are already downloaded.)" + help="Only print the filenames of all files that will be downloaded " + "(not including files that are already downloaded). " + "(Does not download or delete any files.)", action="store_true", ) @@ -313,8 +313,8 @@ def add_global_options(parser: argparse.ArgumentParser) -> argparse.ArgumentPars ) cloned.add_argument( "--no-progress-bar", - help="Disables the one-line progress bar and prints log messages on separate lines " - "(Progress bar is disabled by default if there is no tty attached)", + help="Disable the one-line progress bar and print log messages on separate lines " + "(progress bar is disabled by default if there is no TTY attached)", action="store_true", ) deprecated_kwargs: dict[str, Any] = {} @@ -324,27 +324,27 @@ def add_global_options(parser: argparse.ArgumentParser) -> argparse.ArgumentPars pass cloned.add_argument( "--threads-num", - help="Number of cpu threads - deprecated & always 1. To be removed in future version", + help="Number of CPU threads - deprecated & always 1. To be removed in a future version", type=int, default=1, **deprecated_kwargs, ) cloned.add_argument( "--domain", - help="What iCloud root domain to use. Use 'cn' for mainland China. Default: %(default)s", + help="Which iCloud root domain to use. Use 'cn' for mainland China. Default: %(default)s", choices=["com", "cn"], default="com", ) cloned.add_argument( "--watch-with-interval", - help="Run downloading in a infinite cycle, waiting specified seconds between runs", + help="Run downloading in an infinite cycle, waiting the specified seconds between runs", type=int, default=None, ) cloned.add_argument( "--password-provider", dest="password_providers", - help="Specifies passwords provider to check in the given order. Default: [`parameter`, `keyring`, `console`]", + help="Specify password providers to check in the given order. Default: [`parameter`, `keyring`, `console`]", choices=["console", "keyring", "parameter", "webui"], default=None, action="append", @@ -352,7 +352,7 @@ def add_global_options(parser: argparse.ArgumentParser) -> argparse.ArgumentPars ) cloned.add_argument( "--mfa-provider", - help="Specified where to get MFA code from", + help="Specify where to get the MFA code from", choices=["console", "webui"], default="console", type=lower, @@ -374,7 +374,7 @@ def log_level(inp: str) -> LogLevel: def parse_timestamp_or_timedelta_tz_error( formatted: str, ) -> datetime.datetime | datetime.timedelta | None: - """Converts ISO dates to datetime with tz and interval in days to timeinterval. Raises exception in case of the error""" + """Convert ISO dates to datetime with tz and interval in days to time interval. Raise exception in case of error.""" if formatted is None: return None result = parse_timestamp_or_timedelta(formatted) @@ -416,10 +416,10 @@ def format_help() -> str: global_help, [ "", - "COMMON options. If specified before first username, then used as default for settings for all users.", + "COMMON options. If specified before the first username, then used as defaults for settings for all users.", ], default_help, - ["", "USER options. Can be specified for setting user config only."], + ["", "USER options. Can be specified for setting user configuration only."], user_help, ] ) @@ -554,7 +554,7 @@ def cli() -> int: # check param compatibility if [user_ns for user_ns in user_nses if user_ns.skip_videos and user_ns.skip_photos]: print( - "Only one of --skip-videos and --skip-photos can be used at a time for each config" + "Only one of --skip-videos and --skip-photos can be used at a time for each configuration" ) return 2 @@ -568,7 +568,7 @@ def cli() -> int: and not user_ns.auth_only ]: print( - "--auth-only, --directory, --list-libraries or --list-albums are required for each config" + "--auth-only, --directory, --list-libraries, or --list-albums are required for each configuration" ) return 2 @@ -577,7 +577,9 @@ def cli() -> int: for user_ns in user_nses if user_ns.auto_delete and user_ns.delete_after_download ]: - print("--auto-delete and --delete-after-download are mutually exclusive per config") + print( + "--auto-delete and --delete-after-download are mutually exclusive per configuration" + ) return 2 elif [ @@ -586,7 +588,7 @@ def cli() -> int: if user_ns.keep_icloud_recent_days and user_ns.delete_after_download ]: print( - "--keep-icloud-recent-days and --delete-after-download should not be used together in one config" + "--keep-icloud-recent-days and --delete-after-download should not be used together in one configuration" ) return 2 diff --git a/tests/test_cli.py b/tests/test_cli.py index 3d0af60b8..7bc6996b1 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -40,10 +40,10 @@ def test_cli_help(self) -> None: ) self.assertIn("GLOBAL options. Applied for all user settings.", result) self.assertIn( - "COMMON options. If specified before first username, then used as default for settings for all users.", + "COMMON options. If specified before the first username, then used as defaults for settings for all users.", result, ) - self.assertIn("USER options. Can be specified for setting user config only.", result) + self.assertIn("USER options. Can be specified for setting user configuration only.", result) # Test that all major options are present self.assertIn("--help, -h", result) @@ -58,16 +58,16 @@ def test_cli_help(self) -> None: self.assertIn("--dry-run", result) # Test that option descriptions are present - self.assertIn("Show this info", result) - self.assertIn("Show the version, commit hash and timestamp", result) - self.assertIn("AppleID email address. Starts new configuration group.", result) + self.assertIn("Show this information", result) + self.assertIn("Show the version, commit hash, and timestamp", result) + self.assertIn("Apple ID email address. Starts a new configuration", result) # Directory option exists with proper help text (format varies by Python version) self.assertTrue( "-d, --directory DIRECTORY" in result or "-d DIRECTORY, --directory DIRECTORY" in result, "Expected directory option format not found in help text", ) - self.assertIn("Local directory that should be used for download", result) + self.assertIn("Local directory to use for downloads", result) def test_cli_parser(self) -> None: self.assertEqual.__self__.maxDiff = None # type: ignore[attr-defined]