rclone-api 1.5.45__py3-none-any.whl → 1.5.46__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- rclone_api/install.py +139 -100
- {rclone_api-1.5.45.dist-info → rclone_api-1.5.46.dist-info}/METADATA +1 -1
- {rclone_api-1.5.45.dist-info → rclone_api-1.5.46.dist-info}/RECORD +7 -7
- {rclone_api-1.5.45.dist-info → rclone_api-1.5.46.dist-info}/WHEEL +0 -0
- {rclone_api-1.5.45.dist-info → rclone_api-1.5.46.dist-info}/entry_points.txt +0 -0
- {rclone_api-1.5.45.dist-info → rclone_api-1.5.46.dist-info}/licenses/LICENSE +0 -0
- {rclone_api-1.5.45.dist-info → rclone_api-1.5.46.dist-info}/top_level.txt +0 -0
rclone_api/install.py
CHANGED
@@ -1,100 +1,139 @@
|
|
1
|
-
import logging
|
2
|
-
import os
|
3
|
-
import platform
|
4
|
-
import shutil
|
5
|
-
from pathlib import Path
|
6
|
-
from tempfile import TemporaryDirectory
|
7
|
-
from warnings import warn
|
8
|
-
|
9
|
-
from download import download
|
10
|
-
|
11
|
-
URL_WINDOWS = "https://downloads.rclone.org/rclone-current-windows-amd64.zip"
|
12
|
-
URL_LINUX = "https://downloads.rclone.org/rclone-current-linux-amd64.zip"
|
13
|
-
URL_MACOS_ARM = "https://downloads.rclone.org/rclone-current-osx-arm64.zip"
|
14
|
-
URL_MACOS_X86 = "https://downloads.rclone.org/rclone-current-osx-amd64.zip"
|
15
|
-
|
16
|
-
logger = logging.getLogger(__name__)
|
17
|
-
logging.basicConfig(level=logging.DEBUG)
|
18
|
-
|
19
|
-
|
20
|
-
def rclone_download_url() -> str:
|
21
|
-
system = platform.system()
|
22
|
-
arch = platform.machine()
|
23
|
-
if system == "Windows":
|
24
|
-
assert "arm" not in arch, f"Unsupported arch: {arch}"
|
25
|
-
return URL_WINDOWS
|
26
|
-
elif system == "Linux":
|
27
|
-
assert "arm" not in arch, f"Unsupported arch: {arch}"
|
28
|
-
return URL_LINUX
|
29
|
-
elif system == "Darwin":
|
30
|
-
if "x86" in arch:
|
31
|
-
return URL_MACOS_X86
|
32
|
-
elif "arm" in arch:
|
33
|
-
return URL_MACOS_ARM
|
34
|
-
else:
|
35
|
-
raise Exception(f"Unsupported arch: {arch}")
|
36
|
-
else:
|
37
|
-
raise Exception("Unsupported system")
|
38
|
-
|
39
|
-
|
40
|
-
def _remove_signed_binary_requirements(out: Path) -> None:
|
41
|
-
if platform.system() == "Windows":
|
42
|
-
return
|
43
|
-
# mac os
|
44
|
-
if platform.system() == "Darwin":
|
45
|
-
# remove signed binary requirements
|
46
|
-
#
|
47
|
-
# xattr -d com.apple.quarantine rclone
|
48
|
-
import subprocess
|
49
|
-
|
50
|
-
subprocess.run(
|
51
|
-
["xattr", "-d", "com.apple.quarantine", str(out)],
|
52
|
-
capture_output=True,
|
53
|
-
check=False,
|
54
|
-
)
|
55
|
-
return
|
56
|
-
|
57
|
-
|
58
|
-
def _make_executable(out: Path) -> None:
|
59
|
-
if platform.system() == "Windows":
|
60
|
-
return
|
61
|
-
# linux and mac os
|
62
|
-
os.chmod(out, 0o755)
|
63
|
-
|
64
|
-
|
65
|
-
def _find_rclone_exe(start: Path) -> Path | None:
|
66
|
-
for root, dirs, files in os.walk(start):
|
67
|
-
if platform.system() == "Windows":
|
68
|
-
if "rclone.exe" in files:
|
69
|
-
return Path(root) / "rclone.exe"
|
70
|
-
else:
|
71
|
-
if "rclone" in files:
|
72
|
-
return Path(root) / "rclone"
|
73
|
-
return None
|
74
|
-
|
75
|
-
|
76
|
-
def
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
if
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
1
|
+
import logging
|
2
|
+
import os
|
3
|
+
import platform
|
4
|
+
import shutil
|
5
|
+
from pathlib import Path
|
6
|
+
from tempfile import TemporaryDirectory
|
7
|
+
from warnings import warn
|
8
|
+
|
9
|
+
from download import download
|
10
|
+
|
11
|
+
URL_WINDOWS = "https://downloads.rclone.org/rclone-current-windows-amd64.zip"
|
12
|
+
URL_LINUX = "https://downloads.rclone.org/rclone-current-linux-amd64.zip"
|
13
|
+
URL_MACOS_ARM = "https://downloads.rclone.org/rclone-current-osx-arm64.zip"
|
14
|
+
URL_MACOS_X86 = "https://downloads.rclone.org/rclone-current-osx-amd64.zip"
|
15
|
+
|
16
|
+
logger = logging.getLogger(__name__)
|
17
|
+
logging.basicConfig(level=logging.DEBUG)
|
18
|
+
|
19
|
+
|
20
|
+
def rclone_download_url() -> str:
|
21
|
+
system = platform.system()
|
22
|
+
arch = platform.machine()
|
23
|
+
if system == "Windows":
|
24
|
+
assert "arm" not in arch, f"Unsupported arch: {arch}"
|
25
|
+
return URL_WINDOWS
|
26
|
+
elif system == "Linux":
|
27
|
+
assert "arm" not in arch, f"Unsupported arch: {arch}"
|
28
|
+
return URL_LINUX
|
29
|
+
elif system == "Darwin":
|
30
|
+
if "x86" in arch:
|
31
|
+
return URL_MACOS_X86
|
32
|
+
elif "arm" in arch:
|
33
|
+
return URL_MACOS_ARM
|
34
|
+
else:
|
35
|
+
raise Exception(f"Unsupported arch: {arch}")
|
36
|
+
else:
|
37
|
+
raise Exception("Unsupported system")
|
38
|
+
|
39
|
+
|
40
|
+
def _remove_signed_binary_requirements(out: Path) -> None:
|
41
|
+
if platform.system() == "Windows":
|
42
|
+
return
|
43
|
+
# mac os
|
44
|
+
if platform.system() == "Darwin":
|
45
|
+
# remove signed binary requirements
|
46
|
+
#
|
47
|
+
# xattr -d com.apple.quarantine rclone
|
48
|
+
import subprocess
|
49
|
+
|
50
|
+
subprocess.run(
|
51
|
+
["xattr", "-d", "com.apple.quarantine", str(out)],
|
52
|
+
capture_output=True,
|
53
|
+
check=False,
|
54
|
+
)
|
55
|
+
return
|
56
|
+
|
57
|
+
|
58
|
+
def _make_executable(out: Path) -> None:
|
59
|
+
if platform.system() == "Windows":
|
60
|
+
return
|
61
|
+
# linux and mac os
|
62
|
+
os.chmod(out, 0o755)
|
63
|
+
|
64
|
+
|
65
|
+
def _find_rclone_exe(start: Path) -> Path | None:
|
66
|
+
for root, dirs, files in os.walk(start):
|
67
|
+
if platform.system() == "Windows":
|
68
|
+
if "rclone.exe" in files:
|
69
|
+
return Path(root) / "rclone.exe"
|
70
|
+
else:
|
71
|
+
if "rclone" in files:
|
72
|
+
return Path(root) / "rclone"
|
73
|
+
return None
|
74
|
+
|
75
|
+
|
76
|
+
def _move_to_standard_linux_paths(exe_path: Path) -> None:
|
77
|
+
"""Move rclone to standard paths on Linux systems and create a symlink in the original location."""
|
78
|
+
if platform.system() != "Linux":
|
79
|
+
return
|
80
|
+
|
81
|
+
try:
|
82
|
+
# Create directory in standard path if it doesn't exist
|
83
|
+
bin_path = Path("/usr/local/bin/rclone")
|
84
|
+
|
85
|
+
if os.access("/usr/local/bin", os.W_OK):
|
86
|
+
# Remove existing binary if it exists
|
87
|
+
if bin_path.exists():
|
88
|
+
if bin_path.is_symlink():
|
89
|
+
bin_path.unlink()
|
90
|
+
else:
|
91
|
+
os.remove(bin_path)
|
92
|
+
|
93
|
+
# Move the binary to standard path
|
94
|
+
shutil.move(str(exe_path), str(bin_path))
|
95
|
+
|
96
|
+
# Make it executable
|
97
|
+
os.chmod(bin_path, 0o755)
|
98
|
+
|
99
|
+
# Create a symlink in the original location
|
100
|
+
exe_path.symlink_to(bin_path)
|
101
|
+
|
102
|
+
logger.info(f"Moved rclone to {bin_path} and created symlink at {exe_path}")
|
103
|
+
else:
|
104
|
+
logger.warning(
|
105
|
+
"No write permission to /usr/local/bin, skipping move operation"
|
106
|
+
)
|
107
|
+
except Exception as e:
|
108
|
+
logger.warning(f"Failed to move rclone to standard paths: {e}")
|
109
|
+
|
110
|
+
|
111
|
+
def rclone_download(out: Path, replace=False) -> Exception | None:
|
112
|
+
if out.exists() and not replace:
|
113
|
+
return None
|
114
|
+
try:
|
115
|
+
url = rclone_download_url()
|
116
|
+
with TemporaryDirectory() as tmpdir:
|
117
|
+
tmp = Path(tmpdir)
|
118
|
+
logging.info(f"Downloading rclone from {url} to {tmp.absolute()}")
|
119
|
+
download(url, tmp, kind="zip", replace=True)
|
120
|
+
exe = _find_rclone_exe(tmp)
|
121
|
+
if exe is None:
|
122
|
+
raise FileNotFoundError("rclone executable not found")
|
123
|
+
if os.path.exists(out):
|
124
|
+
os.remove(out)
|
125
|
+
out.parent.mkdir(parents=True, exist_ok=True)
|
126
|
+
shutil.move(exe, out)
|
127
|
+
_remove_signed_binary_requirements(out)
|
128
|
+
_make_executable(out)
|
129
|
+
|
130
|
+
# Move to standard paths on Linux
|
131
|
+
_move_to_standard_linux_paths(out)
|
132
|
+
|
133
|
+
return None
|
134
|
+
except Exception as e:
|
135
|
+
import traceback
|
136
|
+
|
137
|
+
stacktrace = traceback.format_exc()
|
138
|
+
warn(f"Failed to download rclone: {e}\n{stacktrace}")
|
139
|
+
return e
|
@@ -16,7 +16,7 @@ rclone_api/filelist.py,sha256=xbiusvNgaB_b_kQOZoHMJJxn6TWGtPrWd2J042BI28o,767
|
|
16
16
|
rclone_api/fs.py,sha256=xUkoSV2R9dByKgueZ3x2GjyCn9fM7tK1ydgK1Whiph0,8933
|
17
17
|
rclone_api/group_files.py,sha256=H92xPW9lQnbNw5KbtZCl00bD6iRh9yRbCuxku4j_3dg,8036
|
18
18
|
rclone_api/http_server.py,sha256=P-LT2GqCEM9tGbyzzr-CrSOc3FyCw1qXUSQ5bY2KBHU,12113
|
19
|
-
rclone_api/install.py,sha256=
|
19
|
+
rclone_api/install.py,sha256=db7l5KoVBr84HbFxih1Sd82tUfzhOuczKfBLb_Dn3XU,4507
|
20
20
|
rclone_api/log.py,sha256=VZHM7pNSXip2ZLBKMP7M1u-rp_F7zoafFDuR8CPUoKI,1271
|
21
21
|
rclone_api/mount.py,sha256=LZqEhuKZunbWVqmsOIqkkCotaxWJpdFRS1InXveoU5E,1428
|
22
22
|
rclone_api/mount_util.py,sha256=jqhJEVTHV6c6lOOzUYb4FLMbqDMHdz7-QRcdH-IobFc,10154
|
@@ -55,9 +55,9 @@ rclone_api/s3/multipart/upload_parts_inline.py,sha256=V7syKjFyVIe4U9Ahl5XgqVTzt9
|
|
55
55
|
rclone_api/s3/multipart/upload_parts_resumable.py,sha256=6-nlMclS8jyVvMvFbQDcZOX9MY1WbCcKA_s9bwuYxnk,9793
|
56
56
|
rclone_api/s3/multipart/upload_parts_server_side_merge.py,sha256=Fp2pdrs5dONQI9LkfNolgAGj1-Z2V1SsRd0r0sreuXI,18040
|
57
57
|
rclone_api/s3/multipart/upload_state.py,sha256=f-Aq2NqtAaMUMhYitlICSNIxCKurWAl2gDEUVizLIqw,6019
|
58
|
-
rclone_api-1.5.
|
59
|
-
rclone_api-1.5.
|
60
|
-
rclone_api-1.5.
|
61
|
-
rclone_api-1.5.
|
62
|
-
rclone_api-1.5.
|
63
|
-
rclone_api-1.5.
|
58
|
+
rclone_api-1.5.46.dist-info/licenses/LICENSE,sha256=b6pOoifSXiUaz_lDS84vWlG3fr4yUKwB8fzkrH9R8bQ,1064
|
59
|
+
rclone_api-1.5.46.dist-info/METADATA,sha256=KqRtpIh195KJQ-8gY8HYZLcY4Qm1KUFVXC5XCw_av8o,37305
|
60
|
+
rclone_api-1.5.46.dist-info/WHEEL,sha256=CmyFI0kx5cdEMTLiONQRbGQwjIoR1aIYB7eCAQ4KPJ0,91
|
61
|
+
rclone_api-1.5.46.dist-info/entry_points.txt,sha256=ognh2e11HTjn73_KL5MWI67pBKS2jekBi-QTiRXySXA,316
|
62
|
+
rclone_api-1.5.46.dist-info/top_level.txt,sha256=EvZ7uuruUpe9RiUyEp25d1Keq7PWYNT0O_-mr8FCG5g,11
|
63
|
+
rclone_api-1.5.46.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|