[pp:metadata] add 'include' and 'exclude' options (#6058)
This commit is contained in:
@@ -5692,6 +5692,30 @@ Description
|
||||
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
|
||||
---------------
|
||||
Type
|
||||
|
||||
@@ -103,10 +103,10 @@ class MetadataPP(PostProcessor):
|
||||
job.register_hooks({event: self.run for event in events}, options)
|
||||
|
||||
self._init_archive(job, options, "_MD_")
|
||||
self.filter = self._make_filter(options)
|
||||
self.mtime = options.get("mtime")
|
||||
self.omode = options.get("open", omode)
|
||||
self.encoding = options.get("encoding", "utf-8")
|
||||
self.private = options.get("private", False)
|
||||
self.skip = options.get("skip", False)
|
||||
|
||||
def run(self, pathfmt):
|
||||
@@ -231,10 +231,33 @@ class MetadataPP(PostProcessor):
|
||||
fp.write("\n".join(tags) + "\n")
|
||||
|
||||
def _write_json(self, fp, kwdict):
|
||||
if not self.private:
|
||||
kwdict = util.filter_dict(kwdict)
|
||||
if self.filter:
|
||||
kwdict = self.filter(kwdict)
|
||||
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
|
||||
def _make_encoder(options, indent=None):
|
||||
return json.JSONEncoder(
|
||||
|
||||
@@ -585,6 +585,36 @@ class MetadataTest(BasePostprocessorTest):
|
||||
self.assertTrue(not e.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
|
||||
def _output(mock):
|
||||
return "".join(
|
||||
|
||||
Reference in New Issue
Block a user