Project

General

Profile

« Previous | Next » 

Revision f42f5c19

Added by koszko over 1 year ago

incorporate version 2 of Hydrilla JSON schemas

View differences:

src/hydrilla/util/_util.py
39 39

  
40 40
here = Path(__file__).resolve().parent
41 41

  
42
class UnknownSchemaError(Exception):
43
    """
44
    Exception used to record problems with JSON documents for which not even
45
    the appropriate validation schema could be determined.
46
    """
47
    pass
48

  
42 49
_strip_comment_re = re.compile(r'''
43 50
^ # match from the beginning of each line
44 51
( # catch the part before '//' comment
......
111 118
    return '.'.join([str(n) for n in ver]) + ('' if rev is None else f'-{rev}')
112 119

  
113 120
schemas = {}
114
for path in (here.parent / 'schemas').glob('*-1.0.1.schema.json'):
115
    schema = json.loads(path.read_text())
116
    schemas[schema['$id']] = schema
121
for series_dir in (here.parent / 'schemas').glob('*.x'):
122
    for path in series_dir.glob("*.schema.json"):
123
        schema = json.loads(path.read_text())
124
        schemas[schema['$id']] = schema
117 125

  
118 126
common_schema_filename = 'common_definitions-1.schema.json'
119 127
common_schema_path = here.parent / "schemas" / common_schema_filename
120 128

  
121
resolver = RefResolver(
122
    base_uri=f'file://{str(common_schema_path)}',
123
    referrer=f'https://hydrilla.koszko.org/{common_schema_filename}',
124
    store=schemas
125
)
129
def validator_for(schema: Union[str, dict]) -> Draft7Validator:
130
    """
131
    Prepare a validator for the provided schema.
126 132

  
127
def validator_for(schema_filename: str) -> Draft7Validator:
133
    Other schemas under '../schemas' can be referenced.
128 134
    """
129
    Prepare a validator for one of the schemas in '../schemas'.
135
    if isinstance(schema, str):
136
        schema = schemas[f'https://hydrilla.koszko.org/schemas/{schema}']
137

  
138
    resolver = RefResolver(
139
        base_uri=schema['$id'],
140
        referrer=schema,
141
        handlers={'https': lambda uri: schemas[uri]}
142
    )
143

  
144
    return Draft7Validator(schema, resolver=resolver)
145

  
146
_major_version_re = re.compile(r'''
147
-
148
(?P<major>[1-9][0-9]*)
149
(?: # this repeated group matches the remaining version numbers
150
  \.
151
  (?:[1-9][0-9]*|0)
152
)*
153
\.schema\.json
154
$
155
''', re.VERBOSE)
156

  
157
def load_instance_from_file(path: Path) -> tuple[dict, Optional[int]]:
158
    """
159
    Open a file and load its contents as a JSON document (with additional
160
    '//' comments support). Then parse its "$schema" property (if present)
161
    and return a tuple of the document instance and the major number of
162
    schema version.
130 163

  
131
    This function is not thread-safe.
164
    If no schema version number can be extracted, None is used instead.
132 165
    """
133
    return Draft7Validator(resolver.resolve(schema_filename)[1],
134
                           resolver=resolver)
166
    instance = json.loads(strip_json_comments(path.read_text()))
167
    major = None
168

  
169
    if type(instance) is dict and type(instance.get('$schema')) is str:
170
        match = _major_version_re.search(instance.get('$schema'))
171
        major = match and int(match.group('major'))
172

  
173
    return instance, major
135 174

  
136 175
def translation(localedir: Union[Path, str], lang: Optional[str]=None) \
137 176
    -> gettext.GNUTranslations:

Also available in: Unified diff