Skip to content

Commit

Permalink
update to pyicloud-1.0.0 to support 2fa verification
Browse files Browse the repository at this point in the history
  • Loading branch information
chenwenlong02 committed Jan 17, 2023
1 parent d1644ad commit dd9313c
Show file tree
Hide file tree
Showing 4 changed files with 35 additions and 29 deletions.
38 changes: 30 additions & 8 deletions icloudpd/authentication.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@

import sys
import click
import pyicloud_ipd
import pyicloud
from pyicloud.exceptions import PyiCloudNoStoredPasswordAvailableException
from icloudpd.logger import setup_logger


Expand All @@ -26,28 +27,49 @@ def authenticate(
try:
# If password not provided on command line variable will be set to None
# and PyiCloud will attempt to retrieve from it's keyring
icloud = pyicloud_ipd.PyiCloudService(
icloud = pyicloud.PyiCloudService(
username, password,
cookie_directory=cookie_directory,
client_id=client_id)
except pyicloud_ipd.exceptions.NoStoredPasswordAvailable:
except PyiCloudNoStoredPasswordAvailableException:
# Prompt for password if not stored in PyiCloud's keyring
password = click.prompt("iCloud Password", hide_input=True)
icloud = pyicloud_ipd.PyiCloudService(
icloud = pyicloud.PyiCloudService(
username, password,
cookie_directory=cookie_directory,
client_id=client_id)

if icloud.requires_2sa:
if icloud.requires_2fa:
if raise_error_on_2sa:
raise TwoStepAuthRequiredError(
"Two-factor authentication is required!"
)
logger.info("Two-factor authentication is required!")
request_2fa(icloud, logger)
elif icloud.requires_2sa:
if raise_error_on_2sa:
raise TwoStepAuthRequiredError(
"Two-step/two-factor authentication is required!"
"Two-step authentication is required!"
)
logger.info("Two-step/two-factor authentication is required!")
logger.info("Two-step authentication is required!")
request_2sa(icloud, logger)
return icloud


def request_2fa(icloud, logger):
"""Request two-factor authentication."""
code = click.prompt("Please enter two-factor authentication code")
if not icloud.validate_2fa_code(code):
logger.error("Failed to verify two-factor authentication code")
sys.exit(1)
logger.info(
"Great, you're all set up. The script can now be run without "
"user interaction until 2FA expires.\n"
"You can set up email notifications for when "
"the two-factor authentication expires.\n"
"(Use --help to view information about SMTP options.)"
)


def request_2sa(icloud, logger):
"""Request two-step authentication. Prompts for SMS or device"""
devices = icloud.trusted_devices
Expand Down
16 changes: 2 additions & 14 deletions icloudpd/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
from tqdm import tqdm
from tzlocal import get_localzone

from pyicloud_ipd.exceptions import PyiCloudAPIResponseError
from pyicloud.exceptions import PyiCloudAPIResponseException

from icloudpd.logger import setup_logger
from icloudpd.authentication import authenticate, TwoStepAuthRequiredError
Expand Down Expand Up @@ -279,7 +279,7 @@ def main(
# case exit.
try:
photos = icloud.photos.albums[album]
except PyiCloudAPIResponseError as err:
except PyiCloudAPIResponseException as err:
# For later: come up with a nicer message to the user. For now take the
# exception text
print(err)
Expand Down Expand Up @@ -364,18 +364,6 @@ def photos_exception_handler(ex, retries):
logger.set_tqdm(photos_enumerator)

def download_photo(counter, photo):
"""internal function for actually downloading the photos"""
if skip_videos and photo.item_type != "image":
logger.set_tqdm_description(
"Skipping %s, only downloading photos." % photo.filename
)
return
if photo.item_type != "image" and photo.item_type != "movie":
logger.set_tqdm_description(
"Skipping %s, only downloading photos and videos. "
"(Item type was: %s)" % (photo.filename, photo.item_type)
)
return
try:
created_date = photo.created.astimezone(get_localzone())
except (ValueError, OSError):
Expand Down
4 changes: 2 additions & 2 deletions icloudpd/download.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import logging
from tzlocal import get_localzone
from requests.exceptions import ConnectionError # pylint: disable=redefined-builtin
from pyicloud_ipd.exceptions import PyiCloudAPIResponseError
from pyicloud.exceptions import PyiCloudAPIResponseException
from icloudpd.logger import setup_logger

# Import the constants object so that we can mock WAIT_SECONDS in tests
Expand Down Expand Up @@ -65,7 +65,7 @@ def download_media(icloud, photo, download_path, size):
)
break

except (ConnectionError, socket.timeout, PyiCloudAPIResponseError) as ex:
except (ConnectionError, socket.timeout, PyiCloudAPIResponseException) as ex:
if "Invalid global session" in str(ex):
logger.tqdm_write(
"Session error, re-authenticating...",
Expand Down
6 changes: 1 addition & 5 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,3 @@
pyicloud_ipd==0.10.1
schema==0.7.4
click==6.7
python_dateutil==2.8.2
pyicloud==1.0.0
requests>=2.20.0
tqdm==4.62.0
piexif==1.1.3

0 comments on commit dd9313c

Please sign in to comment.