Skip to content

Commit 3952f3d

Browse files
authored
[EDPDEV-2479][EDPDEV-2789][EDPDEV-2598] (#481)
EDPDEV-2749 - Fix upload command for nested folders when dry-run flag is active EDPDEV-2789 - Fix subjects retrieval in GlobalSearch module EDPDEV-2598 - Enhance solvebio download command to support one file download even if --recursive flag is active
1 parent 51d9245 commit 3952f3d

3 files changed

Lines changed: 64 additions & 15 deletions

File tree

solvebio/cli/data.py

Lines changed: 62 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -195,9 +195,17 @@ def _upload_folder(
195195
# be populated
196196
all_folder_parts = sorted(all_folder_parts, key=lambda x: len(x.split("/")))
197197
for folder in all_folder_parts:
198-
print("{}Creating folder {}".format(
199-
"[Dry Run] " if dry_run else "", folder))
200-
Object.create_folder(vault, folder)
198+
if dry_run:
199+
try:
200+
f = Object.get_by_full_path(folder)
201+
if not f.is_folder:
202+
print("[Dry Run] {} is not a folder - this will cause an error on upload.".format(folder))
203+
else:
204+
print("[Dry Run] Folder {} already exists - skipping creation".format(folder))
205+
except NotFoundError:
206+
print("[Dry Run] Creating folder {}".format(folder))
207+
else:
208+
Object.create_folder(vault, folder)
201209

202210
# Create files in parallel
203211
# Signal handling allows for graceful exit upon KeyboardInterrupt
@@ -234,18 +242,32 @@ def _create_file_job(args):
234242
try:
235243
local_file_path, remote_folder_full_path, vault_path, dry_run, archive_folder, client_auth, follow_shortcuts \
236244
= args
237-
if dry_run:
238-
print("[Dry Run] Uploading {} to {}".format(
239-
local_file_path, remote_folder_full_path))
240-
return
245+
241246
# Provides the global host, token, token_type
242247
client = SolveClient(*client_auth)
243-
remote_parent = Object.get_by_full_path(
244-
remote_folder_full_path,
245-
assert_type="folder",
246-
follow_shortcuts=follow_shortcuts,
247-
client=client
248-
)
248+
249+
remote_parent = None
250+
try:
251+
remote_parent = Object.get_by_full_path(
252+
remote_folder_full_path,
253+
assert_type="folder",
254+
follow_shortcuts=follow_shortcuts,
255+
client=client
256+
)
257+
except NotFoundError as e:
258+
if not dry_run:
259+
raise e
260+
261+
if dry_run:
262+
if not _object_exists(remote_parent, local_file_path, client):
263+
print("[Dry Run] Uploading {} to {}".format(
264+
local_file_path, remote_folder_full_path))
265+
return
266+
else:
267+
print("[Dry Run] File {} already exists at {} - skipping upload".format(
268+
local_file_path, remote_folder_full_path))
269+
return
270+
249271
Object.upload_file(
250272
local_file_path,
251273
remote_parent.path,
@@ -260,6 +282,26 @@ def _create_file_job(args):
260282
except Exception as e:
261283
return e
262284

285+
def _object_exists(remote_parent, local_path, _client):
286+
if remote_parent is None:
287+
return False
288+
full_path, path_dict = Object.validate_full_path(
289+
os.path.join('{}:{}'.format(remote_parent.vault.full_path, remote_parent.path),
290+
os.path.basename(local_path)), client=_client)
291+
try:
292+
obj = Object.get_by_full_path(full_path, client=_client)
293+
if not obj.is_file:
294+
return False
295+
else:
296+
# Check if the md5sum matches
297+
local_md5 = md5sum(local_path)[0]
298+
remote_md5 = obj.get("md5")
299+
if remote_md5 and remote_md5 == local_md5:
300+
return True
301+
else:
302+
return False
303+
except NotFoundError:
304+
return False
263305

264306
def _create_template_from_file(template_file, dry_run=False):
265307
mode = "r"
@@ -752,9 +794,11 @@ def _download_recursive(
752794

753795
min_depth = min([x.depth for x in remote_objects])
754796
num_at_min_depth = len([x for x in remote_objects if x.depth == min_depth])
755-
if num_at_min_depth == 1:
797+
if num_at_min_depth == 1 and not _is_single_file(remote_objects):
798+
# when downloading from folder
756799
base_folder_depth = min_depth
757800
else:
801+
# when downloading from vault root or singular file
758802
base_folder_depth = min_depth - 1
759803

760804
downloaded_files = set()
@@ -995,6 +1039,10 @@ def _ls(full_path, recursive=False, follow_shortcuts=False):
9951039
return files
9961040

9971041

1042+
def _is_single_file(objects):
1043+
return len(objects) == 1 and objects[0].get("object_type") == "file"
1044+
1045+
9981046
def should_tag_by_object_type(args, object_):
9991047
"""Returns True if object matches object type requirements"""
10001048
valid = True

solvebio/global_search.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -202,7 +202,7 @@ def subjects(self):
202202

203203
# Executes a query to get a full API response which contains subjects list
204204
gs = self.limit(0)
205-
gs.execute(include_subjects=True)
205+
gs.execute(include_subjects=True, include_all_subjects=True)
206206

207207
return gs._response.get('subjects')
208208

solvebio/resource/object.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -370,6 +370,7 @@ def create_folder(cls, vault, full_path, tags=None, **kwargs):
370370
parent_object_id = parent.id
371371

372372
# Make the API call
373+
print("Creating folder {}".format(full_path))
373374
new_obj = Object.create(
374375
vault_id=vault.id,
375376
parent_object_id=parent_object_id,

0 commit comments

Comments
 (0)