-
Notifications
You must be signed in to change notification settings - Fork 2
/
convert.py
127 lines (107 loc) · 3.66 KB
/
convert.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
#!/usr/bin/python
import json
import re
import sys
import ruamel.yaml as yaml
def get_yaml_data():
raw_data = None
with open('./data/all.yaml', 'r', encoding='utf-8') as ymldata:
raw_data = yaml.safe_load(ymldata)
return raw_data
mandatory_keys = [
'name', 'type', 'level', 'description', 'traits', 'cast'
]
type_checks = {
'casting': list,
'level': int,
'heightened': dict,
'traits': list,
}
def to_id(name):
return re.sub(r'[^A-Za-z]', '-', name).lower()
def validate(data):
errors = []
key_re = re.compile(r'^[a-z]+(-+[a-z]+)*-?$')
for k, v in data.items():
if not key_re.match(k):
errors.append('Invalid key name: {}'.format(k))
continue
if not isinstance(v, dict):
errors.append(
'Invalid type for "{k}": {vtype} (should be mapping)'.format(
k=k,
vtype=type(v)
)
)
continue
for key in mandatory_keys:
if key not in v:
errors.append(
'Missing "{key}" key in {spellid}'.format(
key=key, spellid=k
)
)
if 'cleric' in v.get('traits', []) and 'domain' not in v:
errors.append(
'Missing domain for cleric focus spell "{name}"'.format(
name=v['name']
)
)
for name, sub in (v['description'].get('subsections') or {}).items():
if not isinstance(sub, dict):
errors.append(
'Invalid subsection "{sub}" is not a dictionary.'.format(
sub=name
)
)
continue
if sorted(sub.keys()) != ['content', 'type']:
errors.append(
'Invalid subsection "{sub}" format in {k}:'
' Needs exactly "type" and "content"'.format(
k=k,
sub=name
)
)
if sub.get('type') not in ('list', 'dl', 'table'):
errors.append(
'Invalid subsection type in "{k}: {sub}": {type}'.format(
k=k, sub=name, type=sub.get('type'),
)
)
if 'subsection.{name}'.format(name=name) not in \
v['description']['main']:
errors.append(
'Subsection "{sub}" is declared in {k} but never used in '
'main'.format(k=k, sub=name)
)
if to_id(v['name']) != k:
errors.append(
'Spell ID {id} does not match spell name {name}'.format(
id=k, name=v['name']
)
)
for key, expect_type in type_checks.items():
if key in v and not isinstance(v[key], expect_type):
errors.append(
'Invalid type for "{key}" in {spellid}: {ktype}'
' (should be {expect_type})'.format(
key=key, spellid=k, ktype=type(v[key]),
expect_type=expect_type
)
)
return errors
def save_json(data, destination):
with open(destination, 'w') as jsonf:
json.dump(data, jsonf)
def main():
data = get_yaml_data()
validation_errs = validate(data)
if validation_errs:
for err in validation_errs:
print(err)
sys.exit(1)
print('File validation complete, writing output file')
save_json(data, sys.argv[1])
if __name__ == '__main__':
main()