"""Utils.""" import base64 import getpass import sys from typing import Optional import keyring KEYRING_SYSTEM = "pyicloud://icloud-password" def get_password(username: str, interactive=sys.stdout.isatty()) -> Optional[str]: """Get the password from a username. Returns the password if found in keyring or if interactive is True. Returns None if no password is found and interactive is False.""" result: Optional[str] = get_password_from_keyring(username) if result: return result if interactive: return getpass.getpass(f"Enter iCloud password for {username}: ") def password_exists_in_keyring(username: str) -> bool: """Return true if the password of a username exists in the keyring.""" return get_password_from_keyring(username) is not None def get_password_from_keyring(username: str) -> Optional[str]: """Get the password from a username.""" return keyring.get_password(KEYRING_SYSTEM, username) def store_password_in_keyring(username: str, password: str) -> None: """Store the password of a username.""" return keyring.set_password( KEYRING_SYSTEM, username, password, ) def delete_password_in_keyring(username: str) -> None: """Delete the password of a username.""" return keyring.delete_password( KEYRING_SYSTEM, username, ) def underscore_to_camelcase(word: str, initial_capital: bool = False) -> str: """Transform a word to camelCase.""" words: list[str] = [x.capitalize() or "_" for x in word.split("_")] if not initial_capital: words[0] = words[0].lower() return "".join(words) def camelcase_to_underscore(camel_str: str) -> str: """ Convert camelCase string to snake_case. Examples: startDate -> start_date localStartDate -> local_start_date hasAttachments -> has_attachments """ result: list[str] = [] for i, char in enumerate(camel_str): if char.isupper() and i > 0: result.append("_") result.append(char.lower()) return "".join(result) def b64url_decode(s: str) -> bytes: """Decode a base64url encoded string.""" return base64.urlsafe_b64decode(s + "=" * (-len(s) % 4)) def b64_encode(b: bytes) -> str: """Encode bytes to a base64 encoded string.""" return base64.b64encode(b).decode()