Revision f42f5c19
Added by koszko over 1 year ago
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
incorporate version 2 of Hydrilla JSON schemas