From 1eb211db0aa91286f5e6f63a5a847518651c8ac8 Mon Sep 17 00:00:00 2001 From: Oliverpool Date: Tue, 12 Jan 2016 23:30:47 +0100 Subject: [PATCH] Check the schema before generating ContentList --- patacrep/content/__init__.py | 44 ++++++++++++++++++++++++++++++--- patacrep/content/cwd.py | 7 ++++++ patacrep/content/include.py | 8 ++++++ patacrep/content/section.py | 10 ++++++++ patacrep/content/song.py | 3 +++ patacrep/content/songsection.py | 3 +++ patacrep/content/sorted.py | 15 +++++++++++ patacrep/content/tex.py | 7 ++++++ patacrep/utils.py | 2 +- 9 files changed, 95 insertions(+), 4 deletions(-) diff --git a/patacrep/content/__init__.py b/patacrep/content/__init__.py index 83110c20..97e2d2a9 100755 --- a/patacrep/content/__init__.py +++ b/patacrep/content/__init__.py @@ -72,9 +72,10 @@ import re import sys import jinja2 +import yaml -from patacrep import files -from patacrep.errors import SharedError +from patacrep import files, utils +from patacrep.errors import SBFileError, SharedError LOGGER = logging.getLogger(__name__) EOL = '\n' @@ -228,6 +229,38 @@ def render(context, content): return rendered +def build_plugin_schema(plugins): + """Builds the Rx schema for the ContentItem""" + plugin_schemas = {} + for keyword, parser in plugins.items(): + subschema = getattr(parser, 'rxschema', '//any') + plugin_schemas[keyword] = yaml.load(subschema) + plugin_schema = [{ + 'type': '//rec', + 'optional': plugin_schemas, + }] + song_schema = { + 'type': '//str', + } + plugin_schema.append(song_schema) + return { + 'type': '//any', + 'of': plugin_schema, + } + +def validate_content(content, plugins): + """Validate the content against the Rx content schema""" + plugin_schema = build_plugin_schema(plugins) + content_schema = { + 'type': '//any', + 'of': [ + plugin_schema, + {'type': '//arr', 'contents':plugin_schema}, + #{'type': '//nil'}, + ] + } + utils.validate_yaml_schema(content, content_schema) + def process_content(content, config=None): """Process content, and return a list of ContentItem() objects. @@ -242,7 +275,12 @@ def process_content(content, config=None): contentlist = ContentList() plugins = config.get('_content_plugins', {}) if not content: - content = [{'song': None}] + content = [{'song': ""}] + try: + validate_content(content, plugins) + except SBFileError as error: + contentlist.append_error(ContentError("Invalid content", str(error))) + return contentlist for elem in content: if isinstance(elem, str): elem = {'song': [elem]} diff --git a/patacrep/content/cwd.py b/patacrep/content/cwd.py index bf7a7931..9a1f2352 100755 --- a/patacrep/content/cwd.py +++ b/patacrep/content/cwd.py @@ -33,4 +33,11 @@ def parse(keyword, config, argument): config['_songdir'] = old_songdir return processed_content +parse.rxschema = """ +type: //rec +required: + path: //str + content: //any +""" + CONTENT_PLUGINS = {'cwd': parse} diff --git a/patacrep/content/include.py b/patacrep/content/include.py index 9f27c992..03e9bd3b 100644 --- a/patacrep/content/include.py +++ b/patacrep/content/include.py @@ -69,4 +69,12 @@ def parse(keyword, config, argument): return new_contentlist +parse.rxschema = """ +type: //any +of: + - type: //str + - type: //arr + contents: //str +""" + CONTENT_PLUGINS = {'include': parse} diff --git a/patacrep/content/section.py b/patacrep/content/section.py index 473f6e92..5adf72ed 100755 --- a/patacrep/content/section.py +++ b/patacrep/content/section.py @@ -47,6 +47,16 @@ def parse(keyword, argument, config): argument = {'name': argument} return ContentList([Section(keyword, **argument)]) +parse.rxschema = """ +type: //any +of: + - type: //str + - type: //rec + required: + name: //str + optional: + short: //str +""" CONTENT_PLUGINS = dict([ (word, parse) diff --git a/patacrep/content/song.py b/patacrep/content/song.py index 869f87f6..020690d1 100755 --- a/patacrep/content/song.py +++ b/patacrep/content/song.py @@ -121,6 +121,9 @@ def parse(keyword, argument, config): )) return sorted(songlist) +parse.rxschema = """ +type: //str +""" CONTENT_PLUGINS = {'song': parse} diff --git a/patacrep/content/songsection.py b/patacrep/content/songsection.py index a004d393..a6ccb013 100755 --- a/patacrep/content/songsection.py +++ b/patacrep/content/songsection.py @@ -30,6 +30,9 @@ def parse(keyword, argument, config): """ return ContentList([SongSection(keyword, argument)]) +parse.rxschema = """ +//str +""" CONTENT_PLUGINS = dict([ (keyword, parse) diff --git a/patacrep/content/sorted.py b/patacrep/content/sorted.py index cd2fee1b..32ef89af 100755 --- a/patacrep/content/sorted.py +++ b/patacrep/content/sorted.py @@ -94,4 +94,19 @@ def parse(keyword, config, argument): ))]) return sorted(songlist, key=key_generator(sort)) +parse.rxschema = """ +type: //any +of: + - type: //nil + - type: //rec + optional: + key: + type: //any + of: + - //str + - type: //arr + contents: //str + content: //any +""" + CONTENT_PLUGINS = {'sorted': parse} diff --git a/patacrep/content/tex.py b/patacrep/content/tex.py index 73221c1b..3e0bf2e9 100755 --- a/patacrep/content/tex.py +++ b/patacrep/content/tex.py @@ -62,5 +62,12 @@ def parse(keyword, argument, config): return filelist +parse.rxschema = """ +type: //any +of: + - type: //arr + contents: //str + - type: //str +""" CONTENT_PLUGINS = {'tex': parse} diff --git a/patacrep/utils.py b/patacrep/utils.py index 7ddd0eca..ac13b4d5 100644 --- a/patacrep/utils.py +++ b/patacrep/utils.py @@ -86,7 +86,7 @@ def validate_yaml_schema(data, schema): rx_checker = Rx.Factory({"register_core_types": True}) schema = rx_checker.make_schema(schema) - if not isinstance(data, dict): + if isinstance(data, DictOfDict): data = dict(data) try: