Skip to content

Commit 5f5439b

Browse files
Add ability to cancel loading the resource pack (#12)
This is useful when the user wants to close the application before the resource pack is loaded or load a new resource pack before the previous one has finished loading.
1 parent 11d3a0f commit 5f5439b

File tree

1 file changed

+38
-18
lines changed

1 file changed

+38
-18
lines changed

src/amulet/resource_pack/java/download_resources.py

Lines changed: 38 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,20 @@
44
import json
55
from urllib.request import urlopen, Request
66
import io
7-
from typing import Generator, TypeVar, Any, Optional
87
import logging
98

10-
from amulet.utils.task_manager import AbstractProgressManager, VoidProgressManager
9+
from amulet.utils.task_manager import (
10+
AbstractProgressManager,
11+
VoidProgressManager,
12+
AbstractCancelManager,
13+
VoidCancelManager,
14+
TaskCancelled,
15+
)
1116
from amulet.resource_pack import JavaResourcePack
1217

13-
T = TypeVar("T")
14-
1518
log = logging.getLogger(__name__)
1619

17-
launcher_manifest: Optional[dict] = None
20+
launcher_manifest: dict | None = None
1821
INCLUDE_SNAPSHOT = False
1922

2023

@@ -32,6 +35,7 @@ def get_launcher_manifest() -> dict:
3235

3336
def get_latest(
3437
progress_manager: AbstractProgressManager = VoidProgressManager(),
38+
cancel_manager: AbstractCancelManager = VoidCancelManager(),
3539
) -> JavaResourcePack:
3640
"""Download the latest resource pack if required.
3741
@@ -60,12 +64,14 @@ def get_latest(
6064
has_new_pack = old_version == new_version
6165

6266
if not has_new_pack:
63-
_remove_and_download(vanilla_rp_path, new_version, progress_manager)
67+
_remove_and_download(
68+
vanilla_rp_path, new_version, progress_manager, cancel_manager
69+
)
6470
return JavaResourcePack(vanilla_rp_path)
6571

6672

67-
_java_vanilla_fix: Optional[JavaResourcePack] = None
68-
_java_vanilla_latest: Optional[JavaResourcePack] = None
73+
_java_vanilla_fix: JavaResourcePack | None = None
74+
_java_vanilla_latest: JavaResourcePack | None = None
6975

7076

7177
def get_java_vanilla_fix() -> JavaResourcePack:
@@ -79,17 +85,19 @@ def get_java_vanilla_fix() -> JavaResourcePack:
7985

8086
def get_java_vanilla_latest(
8187
progress_manager: AbstractProgressManager = VoidProgressManager(),
88+
cancel_manager: AbstractCancelManager = VoidCancelManager(),
8289
) -> JavaResourcePack:
8390
global _java_vanilla_latest
8491
if _java_vanilla_latest is None:
85-
_java_vanilla_latest = get_latest(progress_manager)
92+
_java_vanilla_latest = get_latest(progress_manager, cancel_manager)
8693
return _java_vanilla_latest
8794

8895

8996
def _remove_and_download(
9097
path: str,
9198
version: str,
9299
progress_manager: AbstractProgressManager = VoidProgressManager(),
100+
cancel_manager: AbstractCancelManager = VoidCancelManager(),
93101
) -> None:
94102
# try downloading the new resources to a temporary location
95103
temp_path = os.path.join(os.path.dirname(path), "_temp_")
@@ -99,21 +107,25 @@ def _remove_and_download(
99107
elif os.path.isdir(temp_path):
100108
shutil.rmtree(temp_path, ignore_errors=True)
101109

102-
_download_resources(temp_path, version, progress_manager)
103-
if os.path.isdir(path):
104-
shutil.rmtree(path, ignore_errors=True)
105-
106-
shutil.move(temp_path, path)
110+
try:
111+
_download_resources(temp_path, version, progress_manager, cancel_manager)
112+
except:
113+
shutil.rmtree(temp_path, ignore_errors=True)
114+
else:
115+
if os.path.isdir(path):
116+
shutil.rmtree(path, ignore_errors=True)
117+
shutil.move(temp_path, path)
107118

108-
with open(os.path.join(path, "version"), "w") as f:
109-
f.write(version)
119+
with open(os.path.join(path, "version"), "w") as f:
120+
f.write(version)
110121

111122

112123
def _download_with_retry(
113124
url: str,
114125
chunk_size: int = 4096,
115126
attempts: int = 5,
116127
progress_manager: AbstractProgressManager = VoidProgressManager(),
128+
cancel_manager: AbstractCancelManager = VoidCancelManager(),
117129
) -> bytes:
118130
content_length_found = 0
119131
content = []
@@ -123,6 +135,8 @@ def _download_with_retry(
123135
with urlopen(request, timeout=20) as response:
124136
content_length = int(response.headers["content-length"].strip())
125137
while content_length_found < content_length:
138+
if cancel_manager.is_cancel_requested():
139+
raise TaskCancelled
126140
chunk = response.read(chunk_size)
127141
if not chunk:
128142
break
@@ -142,6 +156,7 @@ def _download_resources(
142156
path: str,
143157
version: str,
144158
progress_manager: AbstractProgressManager = VoidProgressManager(),
159+
cancel_manager: AbstractCancelManager = VoidCancelManager(),
145160
chunk_size: int = 4096,
146161
) -> None:
147162
log.info(f"Downloading Java resource pack for version {version}")
@@ -163,6 +178,7 @@ def _download_resources(
163178
version_client_url,
164179
chunk_size=chunk_size,
165180
progress_manager=progress_manager_child_1,
181+
cancel_manager=cancel_manager,
166182
)
167183

168184
client = zipfile.ZipFile(io.BytesIO(data))
@@ -173,6 +189,8 @@ def _download_resources(
173189
progress_manager_child_2 = progress_manager.get_child(0.5, 1.0)
174190
for path_index, fpath in enumerate(paths):
175191
if not path_index % 30:
192+
if cancel_manager.is_cancel_requested():
193+
raise TaskCancelled
176194
progress_manager_child_2.update_progress(path_index / path_count)
177195
if fpath.endswith("/"):
178196
continue
@@ -192,10 +210,12 @@ def _download_resources(
192210
if "pack.png" in client.namelist():
193211
client.extract("pack.png", path)
194212

195-
except Exception as e:
213+
except TaskCancelled:
214+
raise
215+
except Exception:
196216
log.error(
197217
f"Failed to download and extract the Java resource pack for version {version}.",
198218
exc_info=True,
199219
)
200-
raise e
220+
raise
201221
log.info(f"Finished downloading Java resource pack for version {version}")

0 commit comments

Comments
 (0)