diff --git a/docs/configuration.rst b/docs/configuration.rst index 14ee1a7d..b49fcfd2 100644 --- a/docs/configuration.rst +++ b/docs/configuration.rst @@ -3319,6 +3319,7 @@ Description * ``"tags"``: ``tags`` separated by newlines * ``"custom"``: result of applying `metadata.content-format`_ to a file's metadata dictionary + * ``"delete"``: remove metadata entries specified in `metadata.fields`_ metadata.filename @@ -3407,6 +3408,16 @@ Description e.g. a Tweet on Twitter or a post on Patreon. +metadata.fields +--------------- +Type + ``list`` of ``strings`` +Example + ``["blocked", "watching", "status[creator][name]"]`` +Description + List of metadata field names to remove for ``"mode": "delete"``. + + metadata.content-format ----------------------- Type diff --git a/gallery_dl/postprocessor/metadata.py b/gallery_dl/postprocessor/metadata.py index 2d16db8d..61ee4527 100644 --- a/gallery_dl/postprocessor/metadata.py +++ b/gallery_dl/postprocessor/metadata.py @@ -30,6 +30,10 @@ class MetadataPP(PostProcessor): elif mode == "tags": self.write = self._write_tags ext = "txt" + elif mode == "delete": + self.run = self._run_delete + self.fields = options.get("fields") + ext = None else: self.write = self._write_json self.indent = options.get("indent", 4) @@ -114,6 +118,19 @@ class MetadataPP(PostProcessor): def _run_stdout(self, pathfmt): self.write(sys.stdout, pathfmt.kwdict) + def _run_delete(self, pathfmt): + kwdict = pathfmt.kwdict + for key in self.fields: + obj = kwdict + try: + while "[" in key: + name, _, key = key.partition("[") + obj = obj[name] + key = key.rstrip("]") + del obj[key] + except Exception: + pass + def _directory(self, pathfmt): return pathfmt.realdirectory diff --git a/test/test_postprocessor.py b/test/test_postprocessor.py index 7a216bbc..7f948490 100644 --- a/test/test_postprocessor.py +++ b/test/test_postprocessor.py @@ -339,6 +339,28 @@ class MetadataTest(BasePostprocessorTest): {"category": "test", "extension": "ext", "filename": "file"} """) + def test_metadata_delete(self): + kwdict = {"foo": 0, "bar": {"bax": 1, "bay": 2, "baz": 3}} + self._create({"mode": "delete", "fields": ["foo", "bar[baz]"]}, kwdict) + pdict = self.pathfmt.kwdict + + self.assertEqual(pdict["foo"], kwdict["foo"]) + self.assertEqual(pdict["bar"], kwdict["bar"]) + + self.assertIsNot(kwdict, pdict) + del kwdict["foo"] + del kwdict["bar"]["baz"] + + self._trigger() + self.assertNotIn("foo", pdict) + self.assertNotIn("baz", pdict["bar"]) + self.assertEqual(kwdict["bar"], pdict["bar"]) + + self._trigger() + self.assertNotIn("foo", pdict) + self.assertNotIn("baz", pdict["bar"]) + self.assertEqual(kwdict["bar"], pdict["bar"]) + @staticmethod def _output(mock): return "".join(