diff --git a/picard/coverart/image.py b/picard/coverart/image.py index c1e3e2ff1..24204d513 100644 --- a/picard/coverart/image.py +++ b/picard/coverart/image.py @@ -277,7 +277,7 @@ class CoverArtImage: metadata.add_unique("coverart_types", "front") for cover_type in self.types: metadata.add_unique("coverart_types", cover_type) - filename = script_to_filename(filename, metadata) + (filename, updated_metadata) = script_to_filename(filename, metadata) if not filename: filename = "cover" if not os.path.isabs(filename): diff --git a/picard/file.py b/picard/file.py index dec1de0fc..6431877bd 100644 --- a/picard/file.py +++ b/picard/file.py @@ -342,7 +342,7 @@ class File(QtCore.QObject, Item): """Save the metadata.""" raise NotImplementedError - def _script_to_filename(self, naming_format, file_metadata, settings=None): + def _script_to_filename(self, naming_format, file_metadata, file_extension, settings=None): if settings is None: settings = config.setting metadata = Metadata() @@ -351,7 +351,13 @@ class File(QtCore.QObject, Item): else: metadata.copy(self.orig_metadata) metadata.update(file_metadata) - return script_to_filename(naming_format, metadata, file=self, settings=settings) + (filename, new_metadata) = script_to_filename(naming_format, metadata, + file=self, settings=settings) + # NOTE: the script_to_filename strips the extension away + ext = new_metadata.get('~extension', file_extension) + if not ext.startswith('.'): + ext = '.' + ext + return filename + ext def _fixed_splitext(self, filename): # In case the filename is blank and only has the extension @@ -371,9 +377,7 @@ class File(QtCore.QObject, Item): # 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 + new_filename = self._script_to_filename(naming_format, metadata, ext, settings) if not settings['rename_files']: new_filename = os.path.join(os.path.dirname(new_filename), old_filename) if not settings['move_files']: diff --git a/picard/util/scripttofilename.py b/picard/util/scripttofilename.py index a9bde0276..ed9cbfa84 100644 --- a/picard/util/scripttofilename.py +++ b/picard/util/scripttofilename.py @@ -48,4 +48,4 @@ def script_to_filename(naming_format, metadata, file=None, settings=None): filename = replace_win32_incompat(filename) # remove null characters filename = filename.replace("\x00", "") - return filename + return (filename, meta) diff --git a/test/test_scripttofilename.py b/test/test_scripttofilename.py index 11ff4a24d..027707d72 100644 --- a/test/test_scripttofilename.py +++ b/test/test_scripttofilename.py @@ -32,39 +32,48 @@ class ScriptToFilenameTest(PicardTestCase): def test_plain_filename(self): metadata = Metadata() - filename = script_to_filename('AlbumArt', metadata) + (filename, new_metadata) = script_to_filename('AlbumArt', metadata) self.assertEqual('AlbumArt', filename) def test_simple_script(self): metadata = Metadata() metadata['artist'] = 'AC/DC' metadata['album'] = 'The Album' - filename = script_to_filename('%album%', metadata) + (filename, new_metadata) = script_to_filename('%album%', metadata) self.assertEqual('The Album', filename) - filename = script_to_filename('%artist%/%album%', metadata) + (filename, new_metadata) = script_to_filename('%artist%/%album%', metadata) self.assertEqual('AC_DC/The Album', filename) def test_preserve_backslash(self): metadata = Metadata() metadata['artist'] = 'AC\\/DC' - filename = script_to_filename('%artist%', metadata) + (filename, new_metadata) = script_to_filename('%artist%', metadata) self.assertEqual('AC__DC' if IS_WIN else 'AC\\_DC', filename) def test_file_metadata(self): metadata = Metadata() file = File('somepath/somefile.mp3') - self.assertEqual('', script_to_filename('$has_file()', metadata)) - self.assertEqual('1', script_to_filename('$has_file()', metadata, file=file)) + self.assertEqual('', script_to_filename('$has_file()', metadata)[0]) + self.assertEqual('1', script_to_filename('$has_file()', metadata, file=file)[0]) + + def test_update_metadata(self): + metadata = Metadata() + metadata['artist'] = 'Foo' + metadata['~extension'] = 'foo' + (filename, new_metadata) = script_to_filename('$set(_extension,bar)\n%artist%', metadata) + self.assertEqual('Foo', filename) + self.assertEqual('foo', metadata['~extension']) + self.assertEqual('bar', new_metadata['~extension']) def test_ascii_filenames(self): metadata = Metadata() metadata['artist'] = 'Die Ärzte' settings = config.setting.copy() settings['ascii_filenames'] = False - filename = script_to_filename('%artist% éöü½', metadata, settings=settings) + (filename, new_metadata) = script_to_filename('%artist% éöü½', metadata, settings=settings) self.assertEqual('Die Ärzte éöü½', filename) settings['ascii_filenames'] = True - filename = script_to_filename('%artist% éöü½', metadata, settings=settings) + (filename, new_metadata) = script_to_filename('%artist% éöü½', metadata, settings=settings) self.assertEqual('Die Arzte eou 1_2', filename) def test_windows_compatibility(self): @@ -74,10 +83,10 @@ class ScriptToFilenameTest(PicardTestCase): settings['windows_compatibility'] = False expect_orig = '\\*:?' expect_compat = '____' - filename = script_to_filename('%artist%?', metadata, settings=settings) + (filename, new_metadata) = script_to_filename('%artist%?', metadata, settings=settings) self.assertEqual(expect_compat if IS_WIN else expect_orig, filename) settings['windows_compatibility'] = True - filename = script_to_filename('%artist%?', metadata, settings=settings) + (filename, new_metadata) = script_to_filename('%artist%?', metadata, settings=settings) self.assertEqual(expect_compat, filename) @unittest.skipUnless(IS_WIN, "windows test") @@ -93,21 +102,21 @@ class ScriptToFilenameTest(PicardTestCase): metadata['artist'] = '\u2216/\\\u2215' settings = config.setting.copy() settings['ascii_filenames'] = True - filename = script_to_filename('%artist%/\u2216\\\\\u2215', metadata, settings=settings) + (filename, new_metadata) = script_to_filename('%artist%/\u2216\\\\\u2215', metadata, settings=settings) self.assertEqual('____/_\\_', filename) def test_remove_null_chars(self): metadata = Metadata() - filename = script_to_filename('a\x00b\x00', metadata) + (filename, new_metadata) = script_to_filename('a\x00b\x00', metadata) self.assertEqual('ab', filename) def test_remove_tabs_and_linebreaks_chars(self): metadata = Metadata() - filename = script_to_filename('a\tb\nc', metadata) + (filename, new_metadata) = script_to_filename('a\tb\nc', metadata) self.assertEqual('abc', filename) def test_preserve_leading_and_trailing_whitespace(self): metadata = Metadata() metadata['artist'] = 'The Artist' - filename = script_to_filename(' %artist% ', metadata) + (filename, new_metadata) = script_to_filename(' %artist% ', metadata) self.assertEqual(' The Artist ', filename)