[pp:metadata] add 'include' and 'exclude' options (#6058)

pull/6104/head
Mike Fährmann 1 month ago
parent 80c423a444
commit 4b94b7d477
No known key found for this signature in database
GPG Key ID: 5680CA389D365A88

@ -5692,6 +5692,30 @@ Description
After downloading all files of a `post` After downloading all files of a `post`
metadata.include
----------------
Type
``list`` of ``strings``
Example
``["id", "width", "height", "description"]``
Description
Include only the given top-level keys when writing JSON data.
Note: Missing or undefined fields will be silently ignored.
metadata.exclude
----------------
Type
``list`` of ``strings``
Example
``["blocked", "watching", "status"]``
Description
Exclude all given keys from written JSON data.
Note: Cannot be used with `metadata.include`_.
metadata.fields metadata.fields
--------------- ---------------
Type Type

@ -103,10 +103,10 @@ class MetadataPP(PostProcessor):
job.register_hooks({event: self.run for event in events}, options) job.register_hooks({event: self.run for event in events}, options)
self._init_archive(job, options, "_MD_") self._init_archive(job, options, "_MD_")
self.filter = self._make_filter(options)
self.mtime = options.get("mtime") self.mtime = options.get("mtime")
self.omode = options.get("open", omode) self.omode = options.get("open", omode)
self.encoding = options.get("encoding", "utf-8") self.encoding = options.get("encoding", "utf-8")
self.private = options.get("private", False)
self.skip = options.get("skip", False) self.skip = options.get("skip", False)
def run(self, pathfmt): def run(self, pathfmt):
@ -231,10 +231,33 @@ class MetadataPP(PostProcessor):
fp.write("\n".join(tags) + "\n") fp.write("\n".join(tags) + "\n")
def _write_json(self, fp, kwdict): def _write_json(self, fp, kwdict):
if not self.private: if self.filter:
kwdict = util.filter_dict(kwdict) kwdict = self.filter(kwdict)
fp.write(self._json_encode(kwdict) + "\n") fp.write(self._json_encode(kwdict) + "\n")
def _make_filter(self, options):
include = options.get("include")
if include:
if isinstance(include, str):
include = include.split(",")
return lambda d: {k: d[k] for k in include if k in d}
exclude = options.get("exclude")
private = options.get("private")
if exclude:
if isinstance(exclude, str):
exclude = exclude.split(",")
exclude = set(exclude)
if private:
return lambda d: {k: v for k, v in d.items()
if k not in exclude}
return lambda d: {k: v for k, v in util.filter_dict(d).items()
if k not in exclude}
if not private:
return util.filter_dict
@staticmethod @staticmethod
def _make_encoder(options, indent=None): def _make_encoder(options, indent=None):
return json.JSONEncoder( return json.JSONEncoder(

@ -585,6 +585,36 @@ class MetadataTest(BasePostprocessorTest):
self.assertTrue(not e.called) self.assertTrue(not e.called)
self.assertTrue(m.called) self.assertTrue(m.called)
def test_metadata_option_include(self):
self._create(
{"include": ["_private", "filename", "foo"], "sort": True},
{"public": "hello ワールド", "_private": "foo バー"},
)
with patch("builtins.open", mock_open()) as m:
self._trigger()
self.assertEqual(self._output(m), """{
"_private": "foo バー",
"filename": "file"
}
""")
def test_metadata_option_exclude(self):
self._create(
{"exclude": ["category", "filename", "foo"], "sort": True},
{"public": "hello ワールド", "_private": "foo バー"},
)
with patch("builtins.open", mock_open()) as m:
self._trigger()
self.assertEqual(self._output(m), """{
"extension": "ext",
"public": "hello ワールド"
}
""")
@staticmethod @staticmethod
def _output(mock): def _output(mock):
return "".join( return "".join(

Loading…
Cancel
Save