-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathutils.py
More file actions
144 lines (115 loc) · 5.61 KB
/
utils.py
File metadata and controls
144 lines (115 loc) · 5.61 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
import copy
import os
from typing import Dict, Optional, Sequence
import typing
import keyring
from requests import Response
from pyicloud_ipd.asset_version import AssetVersion
from pyicloud_ipd.version_size import AssetVersionSize, VersionSize
from .exceptions import PyiCloudNoStoredPasswordAvailableException, PyiCloudServiceUnavailableException
KEYRING_SYSTEM = 'pyicloud://icloud-password'
# def get_password(username:str, interactive:bool=sys.stdout.isatty()) -> str:
# try:
# return get_password_from_keyring(username)
# except PyiCloudNoStoredPasswordAvailableException:
# if not interactive:
# raise
# return getpass.getpass(
# 'Enter iCloud password for {username}: '.format(
# username=username,
# )
# )
def password_exists_in_keyring(username:str) -> bool:
try:
return get_password_from_keyring(username) is not None
except PyiCloudNoStoredPasswordAvailableException:
return False
def get_password_from_keyring(username:str) -> Optional[str]:
result = keyring.get_password(
KEYRING_SYSTEM,
username
)
# if result is None:
# raise PyiCloudNoStoredPasswordAvailableException(
# "No pyicloud password for {username} could be found "
# "in the system keychain. Use the `--store-in-keyring` "
# "command-line option for storing a password for this "
# "username.".format(
# username=username,
# )
# )
return result
def store_password_in_keyring(username: str, password:str) -> None:
# if get_password_from_keyring(username) is not None:
# # Apple can save only into empty keyring
# return delete_password_in_keyring(username)
return keyring.set_password(
KEYRING_SYSTEM,
username,
password,
)
def delete_password_in_keyring(username:str) -> None:
return keyring.delete_password(
KEYRING_SYSTEM,
username,
)
def underscore_to_camelcase(word:str , initial_capital: bool=False) -> str:
words = [x.capitalize() or '_' for x in word.split('_')]
if not initial_capital:
words[0] = words[0].lower()
return ''.join(words)
# def filename_with_size(filename: str, size: str, original: Optional[Dict[str, Any]]) -> str:
# """Returns the filename with size, e.g. IMG1234.jpg, IMG1234-small.jpg"""
# if size == 'original' or size == 'alternative':
# # TODO what if alternative ext matches original?
# return filename
# # for adjustments we add size only if extension matches original (alternative
# if size == "adjusted" and original != None and original["filename"] != filename:
# return filename
# return (f"-{size}.").join(filename.rsplit(".", 1))
def size_to_suffix(size: VersionSize) -> str:
return f"-{size}".lower()
def add_suffix_to_filename(suffix: str, filename: str) -> str:
_n, _e = os.path.splitext(filename)
return _n + suffix + _e
def disambiguate_filenames(_versions: Dict[VersionSize, AssetVersion], _sizes:Sequence[AssetVersionSize]) -> Dict[AssetVersionSize, AssetVersion]:
_results: Dict[AssetVersionSize, AssetVersion] = {}
# add those that were requested
for _size in _sizes:
_version = _versions.get(_size)
if _version:
_results[_size] = copy.copy(_version)
# adjusted
if AssetVersionSize.ADJUSTED in _sizes:
if AssetVersionSize.ORIGINAL not in _sizes:
if AssetVersionSize.ADJUSTED not in _results:
# clone
_results[AssetVersionSize.ADJUSTED] = copy.copy(_versions[AssetVersionSize.ORIGINAL])
else:
if AssetVersionSize.ADJUSTED in _results and _results[AssetVersionSize.ORIGINAL].filename == _results[AssetVersionSize.ADJUSTED].filename:
_results[AssetVersionSize.ADJUSTED].filename = add_suffix_to_filename("-adjusted", _results[AssetVersionSize.ADJUSTED].filename)
# alternative
if AssetVersionSize.ALTERNATIVE in _sizes:
if AssetVersionSize.ORIGINAL not in _sizes and AssetVersionSize.ADJUSTED not in _results:
if AssetVersionSize.ALTERNATIVE not in _results:
# clone
_results[AssetVersionSize.ALTERNATIVE] = copy.copy(_versions[AssetVersionSize.ORIGINAL])
else:
if AssetVersionSize.ALTERNATIVE in _results:
if AssetVersionSize.ADJUSTED in _results and _results[AssetVersionSize.ADJUSTED].filename == _results[AssetVersionSize.ALTERNATIVE].filename or AssetVersionSize.ORIGINAL in _results and _results[AssetVersionSize.ORIGINAL].filename == _results[AssetVersionSize.ALTERNATIVE].filename:
_results[AssetVersionSize.ALTERNATIVE].filename = add_suffix_to_filename("-alternative", _results[AssetVersionSize.ALTERNATIVE].filename)
for _size in _sizes:
if _size not in [AssetVersionSize.ORIGINAL, AssetVersionSize.ADJUSTED, AssetVersionSize.ALTERNATIVE]:
if _size not in _results:
# ensure original is downloaded - mimic existing behavior
if AssetVersionSize.ORIGINAL not in _sizes:
_results[AssetVersionSize.ORIGINAL] = copy.copy(_versions[AssetVersionSize.ORIGINAL])
# else:
# _n, _e = os.path.splitext(_results[_size]["filename"])
# _results[_size]["filename"] = f"{_n}-{_size}{_e}"
return _results
def throw_on_503(response: Response) -> Response:
if response.status_code == 503:
raise PyiCloudServiceUnavailableException("Apple iCloud is temporary refusing to serve icloudpd")
else:
return response