Skip to content

Commit 52b11f7

Browse files
committed
Improved the download files implementation
1 parent a5739a6 commit 52b11f7

2 files changed

Lines changed: 63 additions & 44 deletions

File tree

src/bin/qfieldcloud-cli

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -284,7 +284,7 @@ def download_files(ctx, project_id, local_dir, filter_glob, exit_on_error):
284284

285285
log(f'Downloading project "{project_id}" files to {local_dir}…')
286286

287-
files = ctx.obj["client"].download_files(
287+
files = ctx.obj["client"].download_project(
288288
project_id, local_dir, filter_glob, exit_on_error, show_progress=True
289289
)
290290

src/qfieldcloud_sdk/sdk.py

Lines changed: 62 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -38,11 +38,6 @@ class DeleteStatus(str, Enum):
3838
FAILED = "FAILED"
3939

4040

41-
class DownloadType(str, Enum):
42-
FILES = "files"
43-
PACKAGED_FILES = "qfield-files"
44-
45-
4641
class FileTransferType(Enum):
4742
PROJECT = "project"
4843
PACKAGE = "package"
@@ -262,12 +257,12 @@ def upload_file(
262257
},
263258
)
264259

265-
def download_files(
260+
def download_project(
266261
self,
267262
project_id: str,
268263
local_dir: str,
269264
filter_glob: str = None,
270-
continue_on_error: bool = False,
265+
exit_on_error: bool = False,
271266
show_progress: bool = False,
272267
) -> List[Dict]:
273268
"""Download the specified project files into the destination dir.
@@ -280,13 +275,13 @@ def download_files(
280275

281276
files = self.list_files(project_id)
282277

283-
return self._download_files(
278+
return self.download_files(
284279
files,
285-
DownloadType.FILES,
286280
project_id,
281+
FileTransferType.PROJECT,
287282
local_dir,
288283
filter_glob,
289-
continue_on_error,
284+
exit_on_error,
290285
show_progress,
291286
)
292287

@@ -416,7 +411,7 @@ def package_download(
416411
project_id: str,
417412
local_dir: str,
418413
filter_glob: str = None,
419-
continue_on_error: bool = False,
414+
exit_on_error: bool = False,
420415
show_progress: bool = False,
421416
) -> List[Dict]:
422417
"""Download the specified project packaged files into the destination dir.
@@ -435,24 +430,24 @@ def package_download(
435430

436431
resp = self._request("GET", f"packages/{project_id}/latest/")
437432

438-
return self._download_files(
433+
return self.download_files(
439434
resp.json()["files"],
440-
DownloadType.PACKAGED_FILES,
441435
project_id,
436+
FileTransferType.PACKAGE,
442437
local_dir,
443438
filter_glob,
444-
continue_on_error,
439+
exit_on_error,
445440
show_progress,
446441
)
447442

448-
def _download_files(
443+
def download_files(
449444
self,
450445
files: List[Dict],
451-
download_type: DownloadType,
452446
project_id: str,
447+
download_type: FileTransferType,
453448
local_dir: str,
454449
filter_glob: str = None,
455-
continue_on_error: bool = False,
450+
exit_on_error: bool = False,
456451
show_progress: bool = False,
457452
) -> List[Dict]:
458453
if not filter_glob:
@@ -466,14 +461,15 @@ def _download_files(
466461
files_to_download.append(file)
467462

468463
for file in files_to_download:
469-
local_file = Path(f'{local_dir}/{file["name"]}')
470-
resp = None
464+
local_filename = Path(f'{local_dir}/{file["name"]}')
471465

472466
try:
473-
resp = self._request(
474-
"GET",
475-
f'{download_type.value}/{project_id}/{file["name"]}',
476-
stream=True,
467+
self.download_file(
468+
project_id,
469+
download_type,
470+
local_filename,
471+
file["name"],
472+
show_progress,
477473
)
478474
file["status"] = DownloadStatus.SUCCESS
479475
except QfcRequestException as err:
@@ -486,32 +482,55 @@ def _download_files(
486482
file["status"] = DownloadStatus.FAILED
487483
file["error"] = err
488484

489-
if continue_on_error:
490-
continue
491-
else:
485+
if exit_on_error:
492486
raise err
487+
else:
488+
continue
489+
490+
return files_to_download
493491

494-
if not local_file.parent.exists():
495-
local_file.parent.mkdir(parents=True)
492+
def download_file(
493+
self,
494+
project_id: str,
495+
download_type: FileTransferType,
496+
local_filename: Path,
497+
remote_filename: Path,
498+
show_progress: bool,
499+
) -> requests.Response:
500+
if download_type == FileTransferType.PROJECT:
501+
url = f"files/{project_id}/{remote_filename}"
502+
elif download_type == FileTransferType.PACKAGE:
503+
url = f"packages/{project_id}/latest/files/{remote_filename}"
504+
else:
505+
raise NotImplementedError()
496506

497-
with open(local_file, "wb") as f:
498-
download_file = f
499-
if show_progress:
500-
from tqdm import tqdm
501-
from tqdm.utils import CallbackIOWrapper
507+
resp = self._request("GET", url, stream=True)
502508

503-
content_length = int(resp.headers.get("content-length", 0))
504-
progress_bar = tqdm(
505-
total=content_length, unit_scale=True, desc=file["name"]
506-
)
507-
download_file = CallbackIOWrapper(progress_bar.update, f, "write")
509+
if not local_filename.parent.exists():
510+
local_filename.parent.mkdir(parents=True)
508511

509-
for chunk in resp.iter_content(chunk_size=8192):
510-
# filter out keep-alive new chunks
511-
if chunk:
512-
download_file.write(chunk)
512+
with open(local_filename, "wb") as f:
513+
download_file = f
514+
if show_progress:
515+
from tqdm import tqdm
516+
from tqdm.utils import CallbackIOWrapper
513517

514-
return files_to_download
518+
content_length = int(resp.headers.get("content-length", 0))
519+
progress_bar = tqdm(
520+
total=content_length,
521+
unit_scale=True,
522+
desc=remote_filename,
523+
)
524+
download_file = CallbackIOWrapper(progress_bar.update, f, "write")
525+
else:
526+
logging.info(f'Downloading file "{remote_filename}"…')
527+
528+
for chunk in resp.iter_content(chunk_size=8192):
529+
# filter out keep-alive new chunks
530+
if chunk:
531+
download_file.write(chunk)
532+
533+
return resp
515534

516535
def get_files_list(
517536
self, project_path: str, filter_glob: str

0 commit comments

Comments
 (0)