-
Notifications
You must be signed in to change notification settings - Fork 4
/
validate.py
executable file
·226 lines (165 loc) · 6.4 KB
/
validate.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
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
#!/usr/bin/env python
import os
import re
import json
import requests
import markdown
import PIL.Image
def error(message):
print('-' * 50)
print('ERROR')
print(message)
print('-' * 50)
raise(message)
def get_material_icon_names():
ret = []
target_url = 'https://raw.githubusercontent.com/google/material-design-icons/master/update/current_versions.json'
response = requests.get(target_url)
data = response.text
icons_raw = json.loads(data)
for i in icons_raw:
icon_name = i.split('::')[1]
ret.append(icon_name)
return ret
def validate_mapping(mapping):
left = mapping['left']
top = mapping['top']
width = mapping['width']
height = mapping['height']
pattern = r"^\d+\.?\d*\%$"
pat = re.compile(pattern)
if not re.fullmatch(pat, left):
error("left coordinates are invalid: " + left)
if not re.fullmatch(pat, top):
error("top coordinates are invalid: " + top)
if not re.fullmatch(pat, width):
error("top coordinates are invalid: " + width)
if not re.fullmatch(pat, height):
error("top coordinates are invalid: " + height)
def validate_transition(transition, known_statuses, output_dir, working_dir, default_image):
_from = transition["from"]
_to = transition["to"]
_id = transition["id"]
_name = transition["name"]
_readme = _id + '.md'
_image = _id + '.png'
if _from not in ['New', 'Deleted']:
if _from not in known_statuses:
error('unnknown from status used in transtion: ' + _from )
if _to not in ['New', 'Deleted']:
if _to not in known_statuses:
error('unnknown to status used in transtion: ' + _to )
# validate that transition readme file exists
if not os.path.exists( os.path.join(working_dir, _readme) ):
error('Readme file not found for the transition: ' + _from + ' - ' + _to )
# render markdown html
from_markdown = os.path.join(working_dir, _readme)
to_html = os.path.join(output_dir, os.path.splitext(_readme)[0] + '.html')
markdown.markdownFromFile(
input=from_markdown,
output=to_html,
encoding='utf8',
)
# make sure all images within the object have the same size
transition_image = PIL.Image.open( os.path.join(working_dir, _image) )
img_width, img_height = transition_image.size
if transition_image.size != default_image.size:
error('Different image sizes wihin the same object')
validate_mapping(transition['mapping'])
def validate_status(status, output_dir, working_dir, default_image):
# validate that status readme file exists
status_readme_file = status['id'] + '.md'
if not os.path.exists( os.path.join(working_dir, status_readme_file) ):
error('Status readme file not found: ' + status_readme_file )
# render markdown html
from_markdown = os.path.join(working_dir, status_readme_file)
to_html = os.path.join(output_dir, os.path.splitext(status_readme_file)[0] + '.html')
markdown.markdownFromFile(
input=from_markdown,
output=to_html,
encoding='utf8',
)
# validate that image exists
image = status['id'] + '.png'
if not os.path.exists( os.path.join(working_dir, image) ):
error('image not found: ' + image)
# make sure all images within the object have the same size
status_image = PIL.Image.open( os.path.join(working_dir, image) )
img_width, img_height = status_image.size
if status_image.size != default_image.size:
print( 'status image validation failed: ' + status['name'] )
print( 'status_image.size = ' + str(status_image.size) )
print( 'default_image.size = ' + str(default_image.size) )
error('Different image sizes wihin the same object')
validate_mapping(status['mapping'])
def validate_object(obj_file):
working_dir = os.path.split(obj_file)[0]
print(' ' * 8 + working_dir)
with open(obj_file) as f:
object = json.load(f)
# validate and render object readme
object_readme_file = 'object.md'
if not os.path.exists( os.path.join(working_dir, object_readme_file) ):
error('Object readme file not found')
with open(os.path.join(working_dir, object_readme_file), 'r') as m:
description_html = markdown.markdown(m.read())
# reading default image
default_image_file = object['image']
default_image = PIL.Image.open( os.path.join(working_dir, default_image_file) )
output_dir = os.path.join(working_dir, 'output')
if not os.path.exists(output_dir):
os.makedirs(output_dir)
known_statuses = []
# validate each status
for status in object['statuses']:
known_statuses.append(status['name'])
validate_status(status, output_dir, working_dir, default_image)
# validate each transition
for transition in object['transitions']:
validate_transition(transition, known_statuses, output_dir, working_dir, default_image)
def validate_no_orphant_folders(modules):
print('checking orphanted folders...')
object_folders = []
for m in modules:
if not 'objects' in modules[m]:
continue
for o in modules[m]['objects']:
folder = os.path.split(o)[0]
object_folders.append(folder)
ignored_folders = [ '.env', '.git', '.github' ]
directory_contents = os.listdir('.')
for item in directory_contents:
if not os.path.isdir(item):
continue
if item in ignored_folders:
continue
if item not in object_folders:
error('orphant folder detected: ' + item)
def main():
icons = get_material_icon_names()
print('validating modules...')
with open('./modules.json') as f:
data = json.load(f)
counter = 1
modules = data["modules"]
validate_no_orphant_folders(modules)
for module_name in modules:
m = modules[module_name]
print('{counter}. {name}'.format(
counter=counter,
name=module_name
))
print(' icons ...', end='')
icon = m['icon']
if not icon in icons:
error('Unknown icon: ' + icon)
print(' ok')
print(' objects ...', end='')
if 'objects' in m:
print(' ')
for o in m['objects']:
validate_object(o)
else:
print(' -')
counter += 1
main()