Skip to content

Commit

Permalink
Fix sync file extension normalization
Browse files Browse the repository at this point in the history
  • Loading branch information
const-cloudinary committed Jul 4, 2021
1 parent 46a38b3 commit 63042d0
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 4 deletions.
5 changes: 3 additions & 2 deletions cloudinary_cli/modules/sync.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@
from cloudinary import api

from cloudinary_cli.utils.api_utils import query_cld_folder, upload_file, download_file
from cloudinary_cli.utils.file_utils import walk_dir, delete_empty_dirs, get_destination_folder
from cloudinary_cli.utils.file_utils import walk_dir, delete_empty_dirs, get_destination_folder, \
normalize_file_extension
from cloudinary_cli.utils.json_utils import print_json, read_json_from_file, write_json_to_file
from cloudinary_cli.utils.utils import logger, run_tasks_concurrently, get_user_action, invert_dict

Expand Down Expand Up @@ -149,7 +150,7 @@ def push(self):
def save_sync_meta_file(self, upload_results):
diverse_filenames = {}
for local_path, remote_path in upload_results.items():
local = path.relpath(local_path, self.local_dir)
local = normalize_file_extension(path.relpath(local_path, self.local_dir))
remote = path.relpath(remote_path, self.remote_dir)
if local != remote:
diverse_filenames[local] = remote
Expand Down
47 changes: 46 additions & 1 deletion cloudinary_cli/utils/file_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,37 @@
from cloudinary_cli.defaults import logger
from cloudinary_cli.utils.utils import etag

FORMAT_ALIASES = {
'jpeg': 'jpg',
'jpe': 'jpg',
'tif': 'tiff',
'ps': 'eps',
'ept': 'eps',
'eps3': 'eps',
'j2k': 'jpc',
'jxr': 'wdp',
'hdp': 'wdp',
'm4v': 'mp4',
'h264': 'mp4',
'asf': 'wmv',
'm2v': 'mpeg',
'm2t': 'ts',
'm2ts': 'ts',
'aif': 'aiff',
'aifc': 'aiff',
'mka': 'webm',
'webmda': 'webm',
'webmdv': 'webm',
'mp4dv': 'mp4',
'mp4da': 'mp4',
'opus': 'ogg',
'bmp2': 'bmp',
'bmp3': 'bmp',
'mpg/3': 'mp3',
'heif': 'heic',
'mid': 'midi'
}


def walk_dir(root_dir, include_hidden=False):
all_files = {}
Expand All @@ -18,7 +49,8 @@ def walk_dir(root_dir, include_hidden=False):
for file in files:
full_path = path.join(root, file)
relative_file_path = "/".join(p for p in [relative_path, file] if p)
all_files[relative_file_path] = {
normalized_relative_file_path = normalize_file_extension(relative_file_path)
all_files[normalized_relative_file_path] = {
"path": full_path,
"etag": etag(full_path)
}
Expand Down Expand Up @@ -82,3 +114,16 @@ def get_destination_folder(cloudinary_folder: str, file_path: str, parent: str =

return "/".join([cloudinary_folder, *folder_path]).strip("/")


def normalize_file_extension(filename: str) -> str:
"""
Normalizes file extension. Makes it lower case and removes aliases.
:param filename: The input file name.
:return: File name with normalized extension.
"""
filename, extension = os.path.splitext(filename)
extension = extension[1:].lower()
extension_alias = FORMAT_ALIASES.get(extension, extension)

return ".".join([p for p in [filename, extension_alias] if p])
12 changes: 11 additions & 1 deletion test/test_file_utils.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import unittest

from cloudinary_cli.utils.file_utils import get_destination_folder, walk_dir
from cloudinary_cli.utils.file_utils import get_destination_folder, walk_dir, normalize_file_extension


class FileUtilsTest(unittest.TestCase):
Expand All @@ -21,3 +21,13 @@ def test_walk_dir(self):

self.assertEqual(1, len(walk_dir(test_dir, include_hidden=False)))
self.assertEqual(4, len(walk_dir(test_dir, include_hidden=True)))

def test_normalize_file_extension(self):
for value, expected in {
"sample.jpg": "sample.jpg",
"sample": "sample",
"sample.JPG": "sample.jpg",
"sample.JPE": "sample.jpg",
"SAMPLE.JPEG": "SAMPLE.jpg",
}.items():
self.assertEqual(expected, normalize_file_extension(value))

0 comments on commit 63042d0

Please sign in to comment.