Skip to content

Commit

Permalink
Fix folder existence error in sync command
Browse files Browse the repository at this point in the history
  • Loading branch information
const-cloudinary committed Jul 15, 2024
1 parent 5be226a commit df66d23
Show file tree
Hide file tree
Showing 4 changed files with 54 additions and 14 deletions.
49 changes: 39 additions & 10 deletions cloudinary_cli/modules/sync.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import logging
import os.path
import re
from collections import Counter
from itertools import groupby
Expand Down Expand Up @@ -45,10 +46,6 @@ def sync(local_folder, cloudinary_folder, push, pull, include_hidden, concurrent
if push == pull:
raise UsageError("Please use either the '--push' OR '--pull' options")

if pull and not cld_folder_exists(cloudinary_folder):
logger.error(f"Cloudinary folder '{cloudinary_folder}' does not exist. Aborting...")
return False

sync_dir = SyncDir(local_folder, cloudinary_folder, include_hidden, concurrent_workers, force, keep_unique,
deletion_batch_size, folder_mode, optional_parameter, optional_parameter_parsed)

Expand All @@ -58,7 +55,8 @@ def sync(local_folder, cloudinary_folder, push, pull, include_hidden, concurrent
elif pull:
result = sync_dir.pull()

logger.info("Done!")
if result:
logger.info("Done!")

return result

Expand All @@ -84,12 +82,32 @@ def __init__(self, local_dir, remote_dir, include_hidden, concurrent_workers, fo

self.verbose = logger.getEffectiveLevel() < logging.INFO

self.local_files = walk_dir(path.abspath(self.local_dir), include_hidden)
logger.info(f"Found {len(self.local_files)} items in local folder '{local_dir}'")
self.local_files = {}
self.local_folder_exists = os.path.isdir(path.abspath(self.local_dir))
if not self.local_folder_exists:
logger.info(f"Local folder '{self.local_dir}' does not exist.")
else:
self.local_files = walk_dir(path.abspath(self.local_dir), include_hidden)
if len(self.local_files):
logger.info(f"Found {len(self.local_files)} items in local folder '{self.local_dir}'")
else:
logger.info(f"Local folder '{self.local_dir}' is empty.")

raw_remote_files = {}
self.cld_folder_exists = cld_folder_exists(self.remote_dir)
if not self.cld_folder_exists:
logger.info(f"Cloudinary folder '{self.user_friendly_remote_dir}' does not exist "
f"({self.folder_mode} folder mode).")
else:
raw_remote_files = query_cld_folder(self.remote_dir, self.folder_mode)
if len(raw_remote_files):
logger.info(
f"Found {len(raw_remote_files)} items in Cloudinary folder '{self.user_friendly_remote_dir}' "
f"({self.folder_mode} folder mode).")
else:
logger.info(f"Cloudinary folder '{self.user_friendly_remote_dir}' is empty. "
f"({self.folder_mode} folder mode)")

raw_remote_files = query_cld_folder(self.remote_dir, self.folder_mode)
logger.info(f"Found {len(raw_remote_files)} items in Cloudinary folder '{self.user_friendly_remote_dir}' "
f"({self.folder_mode} folder mode)")
self.remote_files = self._normalize_remote_file_names(raw_remote_files, self.local_files)
self.remote_duplicate_names = duplicate_values(self.remote_files, "normalized_path", "asset_id")
self._print_duplicate_file_names()
Expand Down Expand Up @@ -137,6 +155,11 @@ def push(self):
"""
Pushes changes from the local folder to the Cloudinary folder.
"""

if not self.local_folder_exists:
logger.error(f"Cannot push a non-existent local folder '{self.local_dir}'. Aborting...")
return False

if not self._handle_unique_remote_files():
logger.info("Aborting...")
return False
Expand Down Expand Up @@ -176,6 +199,12 @@ def pull(self):
"""
Pulls changes from the Cloudinary folder to the local folder.
"""

if not self.cld_folder_exists:
logger.error(f"Cannot pull from a non-existent Cloudinary folder '{self.user_friendly_remote_dir}' "
f"({self.folder_mode} folder mode). Aborting...")
return False

download_results = {}
download_errors = {}
if not self._handle_unique_local_files():
Expand Down
8 changes: 5 additions & 3 deletions cloudinary_cli/utils/api_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,21 +59,23 @@ def query_cld_folder(folder, folder_mode):

return files


def cld_folder_exists(folder):
folder = folder.strip('/') # omit redundant leading slash and duplicate trailing slashes in query

if not folder:
return True # root folder
return True # root folder

res = SearchFolders().expression(f"name=\"{folder}\"").execute()
res = SearchFolders().expression(f"path=\"{folder}\"").execute()

return res.get("total_count", 0) > 0


def _display_path(asset):
if asset.get("display_name") is None:
return ""

return "/".join([asset.get("asset_folder", ""), ".".join([asset["display_name"], asset["format"]])])
return "/".join([asset.get("asset_folder", ""), ".".join(filter(None, [asset["display_name"], asset.get("format", None)]))])


def _relative_display_path(asset, folder):
Expand Down
2 changes: 2 additions & 0 deletions cloudinary_cli/utils/file_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,7 @@ def normalize_file_extension(filename: str) -> str:

return ".".join([p for p in [filename, extension_alias] if p])


def populate_duplicate_name(filename, index=0):
"""
Adds index to the filename in order to avoid duplicates.
Expand All @@ -143,6 +144,7 @@ def populate_duplicate_name(filename, index=0):

return ".".join([p for p in [filename, extension[1:]] if p])


def posix_rel_path(end, start) -> str:
"""
Returns a relative path in posix style on any system.
Expand Down
9 changes: 8 additions & 1 deletion test/test_modules/test_cli_sync.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,13 @@ def test_cli_sync_push(self):
self.assertIn("Synced | 12", result.output)
self.assertIn("Done!", result.output)

def test_cli_sync_push_non_existing_folder(self):
non_existing_dir = self.LOCAL_SYNC_PULL_DIR + "non_existing"
result = self.runner.invoke(cli, ['sync', '--push', non_existing_dir, self.CLD_SYNC_DIR])

self.assertIn(f"Cannot push a non-existent local folder '{non_existing_dir}'", result.output)
self.assertIn("Aborting...", result.output)

@retry_assertion
def test_cli_sync_push_twice(self):
self._upload_sync_files(TEST_FILES_DIR)
Expand Down Expand Up @@ -92,7 +99,7 @@ def test_cli_sync_pull_non_existing_folder(self):
non_existing_dir = self.CLD_SYNC_DIR + "non_existing"
result = self.runner.invoke(cli, ['sync', '--pull', self.LOCAL_SYNC_PULL_DIR, non_existing_dir])

self.assertIn(f"error: Cloudinary folder '{non_existing_dir}' does not exist.", result.output)
self.assertIn(f"Cannot pull from a non-existent Cloudinary folder '{non_existing_dir}'", result.output)
self.assertIn("Aborting...", result.output)

@retry_assertion
Expand Down

0 comments on commit df66d23

Please sign in to comment.