def test_windows_shortening(self): fn = make_short_filename(self.root, os.path.join("a" * 200, "b" * 200, "c" * 200 + ".ext"), win_compat=True) self.assertEqual(fn, os.path.join("a" * 116, "b" * 116, "c" * 7 + ".ext"))
def test_nonbmp_unicode_on_nix_with_windows_compat(self): char = u"\N{MUSICAL SYMBOL G CLEF}" max_len = self.max_len remaining = 259 - (3 + 10 + 1 + 200 + 1) divisor = len(char.encode(sys.getfilesystemencoding())) fn = make_short_filename(self.root, os.path.join(*[char * 100] * 2), win_compat=True) self.assertEqual(fn, os.path.join(char * (max_len // divisor), char * (remaining // 2)))
def _make_filename(self, filename, metadata, settings=config.setting): """Constructs file name based on metadata and file naming formats.""" if settings["move_files"]: new_dirname = settings["move_files_to"] if not os.path.isabs(new_dirname): new_dirname = os.path.normpath(os.path.join(os.path.dirname(filename), new_dirname)) else: new_dirname = os.path.dirname(filename) new_filename, ext = os.path.splitext(os.path.basename(filename)) if settings["rename_files"]: # expand the naming format format = settings['file_naming_format'] if len(format) > 0: new_filename = self._script_to_filename(format, metadata, settings) if not settings['move_files']: new_filename = os.path.basename(new_filename) new_filename = make_short_filename(new_dirname, new_filename, config.setting['windows_compatibility'], config.setting['windows_compatibility_drive_root']) # TODO: move following logic under util.filenaming # (and reconsider its necessity) # win32 compatibility fixes if settings['windows_compatibility'] or sys.platform == 'win32': new_filename = new_filename.replace('./', '_/').replace('.\\', '_\\') # replace . at the beginning of file and directory names new_filename = new_filename.replace('/.', '/_').replace('\\.', '\\_') if new_filename and new_filename[0] == '.': new_filename = '_' + new_filename[1:] # Fix for precomposed characters on OSX if sys.platform == "darwin": new_filename = unicodedata.normalize("NFD", unicode(new_filename)) return os.path.realpath(os.path.join(new_dirname, new_filename + ext.lower()))
def test_nonbmp_unicode_on_nix_with_windows_compat(self): char = u"\N{MUSICAL SYMBOL G CLEF}" max_len = 255 remaining = 259 - (3 + 10 + 1 + 200 + 1) divisor = len(char.encode(sys.getfilesystemencoding())) fn = make_short_filename(self.root, os.path.join(*[char * 100] * 2), win_compat=True) self.assertEqual(fn, os.path.join(self.root, char * (max_len // divisor), char * (remaining // 2)))
def _format_filename(self, new_dirname, new_filename, metadata, settings): # TODO: tests !! new_filename, ext = self._fixed_splitext(new_filename) ext = ext.lower() new_filename = new_filename + ext # expand the naming format naming_format = settings['file_naming_format'] if naming_format: new_filename = self._script_to_filename(naming_format, metadata, settings) # NOTE: the _script_to_filename strips the extension away new_filename = new_filename + ext if not settings['move_files']: new_filename = os.path.basename(new_filename) win_compat = IS_WIN or settings['windows_compatibility'] new_filename = make_short_filename(new_dirname, new_filename, win_compat) # TODO: move following logic under util.filenaming # (and reconsider its necessity) # win32 compatibility fixes if win_compat: new_filename = new_filename.replace('./', '_/').replace('.\\', '_\\') # replace . at the beginning of file and directory names # FIXME: even on non-win platforms ??? new_filename = new_filename.replace('/.', '/_').replace('\\.', '\\_') if new_filename.startswith('.'): new_filename = '_' + new_filename[1:] # Fix for precomposed characters on OSX if IS_MACOS: new_filename = unicodedata.normalize("NFD", new_filename) return new_filename
def test_windows_node_maxlength_shortening(self): max_len = 226 remaining = 259 - (3 + 10 + 1 + max_len + 1) fn = make_short_filename(self.root, os.path.join("a" * 300, "b" * 100 + ".ext"), win_compat=True) self.assertEqual( fn, os.path.join("a" * max_len, "b" * (remaining - 4) + ".ext"))
def test_windows_shortening_not_needed(self): root = self.root + "x" * 33 fn = make_short_filename(root, os.path.join(os.path.join(*["a" * 9] * 20), "b" * 10), win_compat=True) self.assertEqual(fn, os.path.join(os.path.join(*["a" * 9] * 20), "b" * 10))
def test_windows_shortening_with_ancestor_on_nix(self): root = os.path.join(self.root, "w" * 10, "x" * 10, "y" * 9, "z" * 9) fn = make_short_filename(root, os.path.join("b" * 200, "c" * 200, "d" * 200 + ".ext"), win_compat=True, relative_to=self.root) self.assertEqual(fn, os.path.join("b" * 100, "c" * 100, "d" * 7 + ".ext"))
def test_windows_shortening_with_ancestor_on_nix(self): fn = make_short_filename( os.path.join(self.root, "w" * 10, "x" * 10, "y" * 9, "z" * 9), os.path.join("b" * 200, "c" * 200, "d" * 200 + ".ext"), win_compat=True, relative_to=self.root, ) self.assertEqual( fn, os.path.join(self.root, "w" * 10, "x" * 10, "y" * 9, "z" * 9, "b" * 100, "c" * 100, "d" * 7 + ".ext") )
def test_windows_selective_shortening(self): root = self.root + "x" * (44 - 10 - 3) fn = make_short_filename( root, os.path.join(os.path.join(*["a" * 9] * 10 + ["b" * 15] * 10), "c" * 10), win_compat=True) self.assertEqual( fn, os.path.join(os.path.join(*["a" * 9] * 10 + ["b" * 9] * 10), "c" * 10))
def _make_filename(self, filename, metadata, settings=None): """Constructs file name based on metadata and file naming formats.""" if settings is None: settings = config.setting if settings["move_files"]: new_dirname = settings["move_files_to"] if not os.path.isabs(new_dirname): new_dirname = os.path.normpath( os.path.join(os.path.dirname(filename), new_dirname)) else: new_dirname = os.path.dirname(filename) new_filename = os.path.basename(filename) if settings["rename_files"]: new_filename, ext = self._fixed_splitext(new_filename) ext = ext.lower() new_filename = new_filename + ext # expand the naming format naming_format = settings['file_naming_format'] if len(naming_format) > 0: new_filename = self._script_to_filename( naming_format, metadata, settings) # NOTE: the _script_to_filename strips the extension away new_filename = new_filename + ext if not settings['move_files']: new_filename = os.path.basename(new_filename) new_filename = make_short_filename( new_dirname, new_filename, config.setting['windows_compatibility'], config.setting['windows_compatibility_drive_root']) # TODO: move following logic under util.filenaming # (and reconsider its necessity) # win32 compatibility fixes if settings['windows_compatibility'] or sys.platform == 'win32': new_filename = new_filename.replace('./', '_/').replace( '.\\', '_\\') # replace . at the beginning of file and directory names new_filename = new_filename.replace('/.', '/_').replace( '\\.', '\\_') if new_filename and new_filename[0] == '.': new_filename = '_' + new_filename[1:] # Fix for precomposed characters on OSX if sys.platform == "darwin": new_filename = unicodedata.normalize("NFD", new_filename) new_path = os.path.join(new_dirname, new_filename) try: return os.path.realpath(new_path) except FileNotFoundError: # os.path.realpath can fail if cwd doesn't exist return new_path
def _format_filename(self, new_dirname, new_filename, metadata, settings, naming_format): old_filename = new_filename new_filename, ext = self._clean_file_extension(new_filename) if naming_format: new_filename = self._script_to_filename(naming_format, metadata, ext, settings) if not new_filename: new_filename = old_filename if not settings['rename_files']: new_filename = os.path.join(os.path.dirname(new_filename), old_filename) if not settings['move_files']: new_filename = os.path.basename(new_filename) win_compat = IS_WIN or settings['windows_compatibility'] new_filename = make_short_filename(new_dirname, new_filename, win_compat) new_filename = make_save_path(new_filename, win_compat=win_compat, mac_compat=IS_MACOS) return new_filename
def _make_filename(self, filename, metadata, settings=config.setting): """Constructs file name based on metadata and file naming formats.""" if settings["move_files"]: new_dirname = settings["move_files_to"] if not os.path.isabs(new_dirname): new_dirname = os.path.normpath(os.path.join(os.path.dirname(filename), new_dirname)) else: new_dirname = os.path.dirname(filename) new_filename = os.path.basename(filename) if settings["rename_files"]: new_filename, ext = os.path.splitext(new_filename) ext = ext.lower() new_filename = new_filename + ext # expand the naming format format = settings["file_naming_format"] if len(format) > 0: new_filename = self._script_to_filename(format, metadata, settings) # NOTE: the _script_to_filename strips the extension away new_filename = new_filename + ext if not settings["move_files"]: new_filename = os.path.basename(new_filename) new_filename = make_short_filename( new_dirname, new_filename, config.setting["windows_compatibility"], config.setting["windows_compatibility_drive_root"], ) # TODO: move following logic under util.filenaming # (and reconsider its necessity) # win32 compatibility fixes if settings["windows_compatibility"] or sys.platform == "win32": new_filename = new_filename.replace("./", "_/").replace(".\\", "_\\") # replace . at the beginning of file and directory names new_filename = new_filename.replace("/.", "/_").replace("\\.", "\\_") if new_filename and new_filename[0] == ".": new_filename = "_" + new_filename[1:] # Fix for precomposed characters on OSX if sys.platform == "darwin": new_filename = unicodedata.normalize("NFD", unicode(new_filename)) return os.path.realpath(os.path.join(new_dirname, new_filename))
def test_nonbmp_unicode_on_nix(self): char = u"\N{MUSICAL SYMBOL G CLEF}" max_len = self.max_len divisor = len(char.encode(sys.getfilesystemencoding())) fn = make_short_filename(self.root, os.path.join(*[char * 100] * 2)) self.assertEqual(fn, os.path.join(*[char * (max_len // divisor)] * 2))
def test_nonbmp_unicode_on_windows(self): char = u"\N{MUSICAL SYMBOL G CLEF}" remaining = 259 - (3 + 10 + 1 + 200 + 1) fn = make_short_filename(self.root, os.path.join(*[char * 100] * 2)) self.assertEqual(fn, os.path.join(char * 100, char * (remaining // 2)))
def test_nonbmp_unicode_on_osx(self): char = u"\N{MUSICAL SYMBOL G CLEF}" max_len = self.max_len fn = make_short_filename(self.root, os.path.join(*[char * 200] * 2)) self.assertEqual(fn, os.path.join(*[char * (max_len // 2)] * 2))
def test_bmp_unicode_on_nix(self): char = u"\N{LATIN SMALL LETTER SHARP S}" max_len = self.max_len divisor = len(char.encode(sys.getfilesystemencoding())) fn = make_short_filename(self.root, os.path.join(*[char * 200] * 2)) self.assertEqual(fn, os.path.join(*[char * (max_len // divisor)] * 2))
def test_precomposed_unicode_on_osx(self): char = u"\N{LATIN SMALL LETTER A WITH BREVE}" max_len = self.max_len fn = make_short_filename(self.root, os.path.join(*[char * 200] * 2)) self.assertEqual(fn, os.path.join(*[char * (max_len // 2)] * 2))
def test_windows_shortening_not_needed(self): fn = make_short_filename( self.root + "x" * 33, os.path.join(os.path.join(*["a" * 9] * 20), "b" * 10), win_compat=True ) self.assertEqual(fn, os.path.join(self.root + "x" * 33, os.path.join(*["a" * 9] * 20), "b" * 10))
def test_bmp_unicode_on_unicode_fs(self): char = u"\N{LATIN SMALL LETTER SHARP S}" fn = make_short_filename(self.root, os.path.join(*[char * 120] * 2)) self.assertEqual(fn, os.path.join(*[char * 120] * 2))
def test_windows_node_maxlength_shortening(self): max_len = 226 remaining = 259 - (3 + 10 + 1 + max_len + 1) fn = make_short_filename(self.root, os.path.join("a" * 300, "b" * 100 + ".ext"), win_compat=True) self.assertEqual(fn, os.path.join(self.root, "a" * max_len, "b" * (remaining - 4) + ".ext"))
def test_nonbmp_unicode_on_nix(self): char = u"\N{MUSICAL SYMBOL G CLEF}" max_len = 255 divisor = len(char.encode(sys.getfilesystemencoding())) fn = make_short_filename(self.root, os.path.join(*[char * 100] * 2)) self.assertEqual(fn, os.path.join(self.root, *[char * (max_len // divisor)] * 2))
def test_precomposed_unicode_on_osx(self): char = u"\N{LATIN SMALL LETTER A WITH BREVE}" max_len = 255 fn = make_short_filename(self.root, os.path.join(*[char * 200] * 2)) self.assertEqual(fn, os.path.join(self.root, *[char * (max_len // 2)] * 2))
def test_bmp_unicode_on_nix(self): char = u"\N{LATIN SMALL LETTER SHARP S}" max_len = 255 divisor = len(char.encode(sys.getfilesystemencoding())) fn = make_short_filename(self.root, os.path.join(*[char * 200] * 2)) self.assertEqual(fn, os.path.join(self.root, *[char * (max_len // divisor)] * 2))
def test_nonbmp_unicode_on_windows(self): char = u"\N{MUSICAL SYMBOL G CLEF}" remaining = 259 - (3 + 10 + 1 + 200 + 1) fn = make_short_filename(self.root, os.path.join(*[char * 100] * 2)) self.assertEqual(fn, os.path.join(self.root, char * 100, char * (remaining // 2)))
def test_windows_path_not_too_long(self): fn = make_short_filename(self.root + "x" * 230, os.path.join("a", "b", "c"), win_compat=True) self.assertEqual(fn, os.path.join(self.root + "x" * 230, "a", "b", "c"))
def test_nonbmp_unicode_on_osx(self): char = u"\N{MUSICAL SYMBOL G CLEF}" max_len = 255 fn = make_short_filename(self.root, os.path.join(*[char * 200] * 2)) self.assertEqual(fn, os.path.join(self.root, *[char * (max_len // 2)] * 2))
def test_bmp_unicode_on_unicode_fs(self): char = u"\N{LATIN SMALL LETTER SHARP S}" fn = make_short_filename(self.root, os.path.join(*[char * 120] * 2)) self.assertEqual(fn, os.path.join(self.root, *[char * 120] * 2))
def test_whitespace(self): fn = make_short_filename(self.root, os.path.join("a1234567890 ", " b1234567890 ")) self.assertEqual(fn, os.path.join("a1234567890", "b1234567890"))
def test_whitespace(self): fn = make_short_filename(self.root, os.path.join("a1234567890 ", " b1234567890 ")) self.assertEqual(fn, os.path.join(self.root, "a1234567890", "b1234567890"))
def test_windows_selective_shortening(self): root = self.root + "x" * (44 - 10 - 3) fn = make_short_filename( root, os.path.join(os.path.join(*["a" * 9] * 10 + ["b" * 15] * 10), "c" * 10), win_compat=True ) self.assertEqual(fn, os.path.join(root, os.path.join(*["a" * 9] * 10 + ["b" * 9] * 10), "c" * 10))
def test_windows_path_not_too_long(self): root = self.root + "x" * 230 fn = make_short_filename(root, os.path.join("a", "b", "c"), win_compat=True) self.assertEqual(fn, os.path.join("a", "b", "c"))
def test_windows_shortening(self): fn = make_short_filename(self.root, os.path.join("a" * 200, "b" * 200, "c" * 200 + ".ext"), win_compat=True) self.assertEqual(fn, os.path.join(self.root, "a" * 116, "b" * 116, "c" * 7 + ".ext"))