From 77e8f5353cb519bd5a9e3699d10de2f90ba07c73 Mon Sep 17 00:00:00 2001 From: Zenon Mousmoulas Date: Wed, 10 Nov 2021 22:21:14 +0200 Subject: [PATCH] JSON-LD: Support top-level @graph expressing implicit default graph MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Per W3C JSON-LD v1.1 ยง4.9 (non-normative ref): When a JSON-LD document's top-level structure is a map that contains no other keys than @graph and optionally @context (properties that are not mapped to an IRI or a keyword are ignored), @graph is considered to express the otherwise implicit default graph. Support such a structure in InfoExtractor._json_ld parsing: Wrap the control flow block in a function, which is called recursively upon such a structure --- youtube_dl/extractor/common.py | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/youtube_dl/extractor/common.py b/youtube_dl/extractor/common.py index 797c35fd5..d947b9253 100644 --- a/youtube_dl/extractor/common.py +++ b/youtube_dl/extractor/common.py @@ -1296,8 +1296,16 @@ class InfoExtractor(object): }) extract_interaction_statistic(e) - for e in json_ld: - if '@context' in e: + def traverse_json_ld(json_ld, info, at_top_level=True): + for e in json_ld: + if at_top_level and '@context' not in e: + continue + if at_top_level and all(k in ('@context', '@graph') for k in e): + graph = e['@graph'] + if isinstance(graph, dict): + graph = [graph] + traverse_json_ld(graph, info, at_top_level=False) + break item_type = e.get('@type') if expected_type is not None and expected_type != item_type: continue @@ -1345,6 +1353,8 @@ class InfoExtractor(object): continue else: break + traverse_json_ld(json_ld, info) + return dict((k, v) for k, v in info.items() if v is not None) @staticmethod