From a41253145138eb370946095201314ff88bfe89e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mike=20F=C3=A4hrmann?= Date: Fri, 29 Nov 2019 23:12:22 +0100 Subject: [PATCH] [postprocessor:metadata] implement 'extension-format' option closes #477 --- docs/configuration.rst | 17 +++++++++++++-- gallery_dl/postprocessor/metadata.py | 32 +++++++++++++++++++++------- test/test_postprocessor.py | 31 ++++++++++++++++++++++++++- 3 files changed, 69 insertions(+), 11 deletions(-) diff --git a/docs/configuration.rst b/docs/configuration.rst index 50d6c092..d03dd2d5 100644 --- a/docs/configuration.rst +++ b/docs/configuration.rst @@ -1474,7 +1474,20 @@ metadata.extension =========== ===== Type ``string`` Default ``"json"`` or ``"txt"`` -Description Filename extension for metadata files. +Description Filename extension for metadata files that will be appended to the + original file names. +=========== ===== + +metadata.extension-format +------------------------- +=========== ===== +Type ``string`` +Example * ``"{extension}.json"`` + * ``"json"`` +Description Custom format string to build filename extensions for metadata + files with, which will replace the original filename extensions. + + Note: `metadata.extension`_ is ignored if this option is set. =========== ===== metadata.format @@ -1482,7 +1495,7 @@ metadata.format =========== ===== Type ``string`` Example ``"tags:\n\n{tags:J\n}\n"`` -Description Custom format string to build content of metadata files. +Description Custom format string to build the content of metadata files with. Note: Only applies for ``"mode": "custom"``. =========== ===== diff --git a/gallery_dl/postprocessor/metadata.py b/gallery_dl/postprocessor/metadata.py index 0e559559..20f47a15 100644 --- a/gallery_dl/postprocessor/metadata.py +++ b/gallery_dl/postprocessor/metadata.py @@ -18,29 +18,45 @@ class MetadataPP(PostProcessor): PostProcessor.__init__(self) mode = options.get("mode", "json") - ext = "txt" - if mode == "custom": self.write = self._write_custom - self.formatter = util.Formatter(options.get("format")) + self.contentfmt = util.Formatter(options.get("format")).format_map + ext = "txt" elif mode == "tags": self.write = self._write_tags + ext = "txt" else: self.write = self._write_json self.indent = options.get("indent", 4) self.ascii = options.get("ascii", False) ext = "json" - self.extension = options.get("extension", ext) + extfmt = options.get("extension-format") + if extfmt: + self.path = self._path_format + self.extfmt = util.Formatter(extfmt).format_map + else: + self.path = self._path_append + self.extension = options.get("extension", ext) def run(self, pathfmt): - path = "{}.{}".format(pathfmt.realpath, self.extension) - with open(path, "w", encoding="utf-8") as file: + with open(self.path(pathfmt), "w", encoding="utf-8") as file: self.write(file, pathfmt.kwdict) + def _path_append(self, pathfmt): + return "{}.{}".format(pathfmt.realpath, self.extension) + + def _path_format(self, pathfmt): + kwdict = pathfmt.kwdict + ext = kwdict["extension"] + kwdict["extension"] = pathfmt.extension + kwdict["extension"] = pathfmt.prefix + self.extfmt(kwdict) + path = pathfmt.realdirectory + pathfmt.build_filename() + kwdict["extension"] = ext + return path + def _write_custom(self, file, kwdict): - output = self.formatter.format_map(kwdict) - file.write(output) + file.write(self.contentfmt(kwdict)) def _write_tags(self, file, kwdict): tags = kwdict.get("tags") or kwdict.get("tag_string") diff --git a/test/test_postprocessor.py b/test/test_postprocessor.py index 8e766ae6..17f82c94 100644 --- a/test/test_postprocessor.py +++ b/test/test_postprocessor.py @@ -156,6 +156,7 @@ class MetadataTest(BasePostprocessorTest): "_private" : "world", }) + self.assertEqual(pp.path , pp._path_append) self.assertEqual(pp.write , pp._write_json) self.assertEqual(pp.ascii , True) self.assertEqual(pp.indent , 2) @@ -228,13 +229,41 @@ class MetadataTest(BasePostprocessorTest): ) self.assertEqual(pp.write, pp._write_custom) self.assertEqual(pp.extension, "txt") - self.assertTrue(pp.formatter) + self.assertTrue(pp.contentfmt) with patch("builtins.open", mock_open()) as m: pp.prepare(self.pathfmt) pp.run(self.pathfmt) self.assertEqual(self._output(m), "bar\nNone\n") + def test_metadata_extfmt(self): + pp = self._create({ + "extension" : "ignored", + "extension-format": "json", + }) + + self.assertEqual(pp.path, pp._path_format) + + with patch("builtins.open", mock_open()) as m: + pp.prepare(self.pathfmt) + pp.run(self.pathfmt) + + path = self.pathfmt.realdirectory + "file.json" + m.assert_called_once_with(path, "w", encoding="utf-8") + + def test_metadata_extfmt_2(self): + pp = self._create({ + "extension-format": "{extension!u}-data:{category:Res/ES/}", + }) + + self.pathfmt.prefix = "2." + with patch("builtins.open", mock_open()) as m: + pp.prepare(self.pathfmt) + pp.run(self.pathfmt) + + path = self.pathfmt.realdirectory + "file.2.EXT-data:tESt" + m.assert_called_once_with(path, "w", encoding="utf-8") + @staticmethod def _output(mock): return "".join(