Tue, 28 May 2019 19:10:52 +0300
fix LDRAW_ORG parsing
3
1dc58f44d556
Can now write dat files, added direct color handling
Santeri Piippo
parents:
diff
changeset
|
1 | #!/usr/bin/env python3 |
8 | 2 | from sys import version_info |
3 | if version_info < (3, 4): | |
4 | raise RuntimeError('Python 3.4 or newer required') | |
5 | ||
3
1dc58f44d556
Can now write dat files, added direct color handling
Santeri Piippo
parents:
diff
changeset
|
6 | from parse import parse_ldraw_code |
8 | 7 | from colours import load_colours |
7 | 8 | from geometry import * |
8 | 9 | from pathlib import Path |
13 | 10 | import linetypes |
47
4da025d0b283
added work on header check
Teemu Piippo <teemu@hecknology.net>
parents:
38
diff
changeset
|
11 | import header |
3
1dc58f44d556
Can now write dat files, added direct color handling
Santeri Piippo
parents:
diff
changeset
|
12 | |
9
fea8e9ae6f29
Added matrix code, moved library paths to ldcheck.cfg.
Santeri Piippo
parents:
8
diff
changeset
|
13 | from os.path import realpath |
fea8e9ae6f29
Added matrix code, moved library paths to ldcheck.cfg.
Santeri Piippo
parents:
8
diff
changeset
|
14 | script_directory = Path(realpath(__file__)).parent |
fea8e9ae6f29
Added matrix code, moved library paths to ldcheck.cfg.
Santeri Piippo
parents:
8
diff
changeset
|
15 | |
fea8e9ae6f29
Added matrix code, moved library paths to ldcheck.cfg.
Santeri Piippo
parents:
8
diff
changeset
|
16 | def load_config(filename): |
fea8e9ae6f29
Added matrix code, moved library paths to ldcheck.cfg.
Santeri Piippo
parents:
8
diff
changeset
|
17 | from configobj import ConfigObj |
fea8e9ae6f29
Added matrix code, moved library paths to ldcheck.cfg.
Santeri Piippo
parents:
8
diff
changeset
|
18 | from copy import deepcopy |
fea8e9ae6f29
Added matrix code, moved library paths to ldcheck.cfg.
Santeri Piippo
parents:
8
diff
changeset
|
19 | config = ConfigObj(filename, encoding = 'UTF8') |
fea8e9ae6f29
Added matrix code, moved library paths to ldcheck.cfg.
Santeri Piippo
parents:
8
diff
changeset
|
20 | read_config = deepcopy(config) |
fea8e9ae6f29
Added matrix code, moved library paths to ldcheck.cfg.
Santeri Piippo
parents:
8
diff
changeset
|
21 | if 'libraries' not in config: |
fea8e9ae6f29
Added matrix code, moved library paths to ldcheck.cfg.
Santeri Piippo
parents:
8
diff
changeset
|
22 | config['libraries'] = ['/path/to/ldraw'] |
fea8e9ae6f29
Added matrix code, moved library paths to ldcheck.cfg.
Santeri Piippo
parents:
8
diff
changeset
|
23 | if config != read_config: |
fea8e9ae6f29
Added matrix code, moved library paths to ldcheck.cfg.
Santeri Piippo
parents:
8
diff
changeset
|
24 | config.write() |
34
7ed2e831acd4
the program now checks that all ldraw paths are reachable
Teemu Piippo <teemu@hecknology.net>
parents:
32
diff
changeset
|
25 | check_library_paths(config) |
9
fea8e9ae6f29
Added matrix code, moved library paths to ldcheck.cfg.
Santeri Piippo
parents:
8
diff
changeset
|
26 | return config |
fea8e9ae6f29
Added matrix code, moved library paths to ldcheck.cfg.
Santeri Piippo
parents:
8
diff
changeset
|
27 | |
21 | 28 | def read_ldraw(file, *, name = '', config): |
29 | model_body = [ | |
30 | parse_ldraw_code(line) | |
31 | for line in file | |
32 | ] | |
47
4da025d0b283
added work on header check
Teemu Piippo <teemu@hecknology.net>
parents:
38
diff
changeset
|
33 | headerparser = header.HeaderParser() |
4da025d0b283
added work on header check
Teemu Piippo <teemu@hecknology.net>
parents:
38
diff
changeset
|
34 | try: |
4da025d0b283
added work on header check
Teemu Piippo <teemu@hecknology.net>
parents:
38
diff
changeset
|
35 | header_parse_result = headerparser.parse(model_body) |
4da025d0b283
added work on header check
Teemu Piippo <teemu@hecknology.net>
parents:
38
diff
changeset
|
36 | header_object = header_parse_result['header'] |
4da025d0b283
added work on header check
Teemu Piippo <teemu@hecknology.net>
parents:
38
diff
changeset
|
37 | end = header_parse_result['end-index'] |
4da025d0b283
added work on header check
Teemu Piippo <teemu@hecknology.net>
parents:
38
diff
changeset
|
38 | except header.HeaderError as error: |
4da025d0b283
added work on header check
Teemu Piippo <teemu@hecknology.net>
parents:
38
diff
changeset
|
39 | header_object = header.BadHeader(error.index, error.reason) |
4da025d0b283
added work on header check
Teemu Piippo <teemu@hecknology.net>
parents:
38
diff
changeset
|
40 | end = 0 |
4da025d0b283
added work on header check
Teemu Piippo <teemu@hecknology.net>
parents:
38
diff
changeset
|
41 | model = Model( |
4da025d0b283
added work on header check
Teemu Piippo <teemu@hecknology.net>
parents:
38
diff
changeset
|
42 | header = header_object, |
4da025d0b283
added work on header check
Teemu Piippo <teemu@hecknology.net>
parents:
38
diff
changeset
|
43 | body = model_body, |
4da025d0b283
added work on header check
Teemu Piippo <teemu@hecknology.net>
parents:
38
diff
changeset
|
44 | header_size = end) |
21 | 45 | model.name = name |
46 | return model | |
3
1dc58f44d556
Can now write dat files, added direct color handling
Santeri Piippo
parents:
diff
changeset
|
47 | |
9
fea8e9ae6f29
Added matrix code, moved library paths to ldcheck.cfg.
Santeri Piippo
parents:
8
diff
changeset
|
48 | def library_paths(config): |
fea8e9ae6f29
Added matrix code, moved library paths to ldcheck.cfg.
Santeri Piippo
parents:
8
diff
changeset
|
49 | for library_path_string in config['libraries']: |
fea8e9ae6f29
Added matrix code, moved library paths to ldcheck.cfg.
Santeri Piippo
parents:
8
diff
changeset
|
50 | yield Path(library_path_string).expanduser() |
fea8e9ae6f29
Added matrix code, moved library paths to ldcheck.cfg.
Santeri Piippo
parents:
8
diff
changeset
|
51 | |
34
7ed2e831acd4
the program now checks that all ldraw paths are reachable
Teemu Piippo <teemu@hecknology.net>
parents:
32
diff
changeset
|
52 | def check_library_paths(config): |
7ed2e831acd4
the program now checks that all ldraw paths are reachable
Teemu Piippo <teemu@hecknology.net>
parents:
32
diff
changeset
|
53 | from sys import exit |
7ed2e831acd4
the program now checks that all ldraw paths are reachable
Teemu Piippo <teemu@hecknology.net>
parents:
32
diff
changeset
|
54 | problems = False |
36
2753aad79678
now checks that paths are specified
Teemu Piippo <teemu@hecknology.net>
parents:
34
diff
changeset
|
55 | have_paths = False |
34
7ed2e831acd4
the program now checks that all ldraw paths are reachable
Teemu Piippo <teemu@hecknology.net>
parents:
32
diff
changeset
|
56 | for library_path in library_paths(config): |
36
2753aad79678
now checks that paths are specified
Teemu Piippo <teemu@hecknology.net>
parents:
34
diff
changeset
|
57 | have_paths = True |
34
7ed2e831acd4
the program now checks that all ldraw paths are reachable
Teemu Piippo <teemu@hecknology.net>
parents:
32
diff
changeset
|
58 | if not library_path.exists(): |
7ed2e831acd4
the program now checks that all ldraw paths are reachable
Teemu Piippo <teemu@hecknology.net>
parents:
32
diff
changeset
|
59 | problems = True |
7ed2e831acd4
the program now checks that all ldraw paths are reachable
Teemu Piippo <teemu@hecknology.net>
parents:
32
diff
changeset
|
60 | print(str.format( |
7ed2e831acd4
the program now checks that all ldraw paths are reachable
Teemu Piippo <teemu@hecknology.net>
parents:
32
diff
changeset
|
61 | 'Library path {} does not exist', |
7ed2e831acd4
the program now checks that all ldraw paths are reachable
Teemu Piippo <teemu@hecknology.net>
parents:
32
diff
changeset
|
62 | library_path, |
7ed2e831acd4
the program now checks that all ldraw paths are reachable
Teemu Piippo <teemu@hecknology.net>
parents:
32
diff
changeset
|
63 | )) |
7ed2e831acd4
the program now checks that all ldraw paths are reachable
Teemu Piippo <teemu@hecknology.net>
parents:
32
diff
changeset
|
64 | elif not library_path.exists(): |
7ed2e831acd4
the program now checks that all ldraw paths are reachable
Teemu Piippo <teemu@hecknology.net>
parents:
32
diff
changeset
|
65 | problems = True |
7ed2e831acd4
the program now checks that all ldraw paths are reachable
Teemu Piippo <teemu@hecknology.net>
parents:
32
diff
changeset
|
66 | print(str.format( |
7ed2e831acd4
the program now checks that all ldraw paths are reachable
Teemu Piippo <teemu@hecknology.net>
parents:
32
diff
changeset
|
67 | 'Library path {} is not a directory', |
7ed2e831acd4
the program now checks that all ldraw paths are reachable
Teemu Piippo <teemu@hecknology.net>
parents:
32
diff
changeset
|
68 | library_path, |
7ed2e831acd4
the program now checks that all ldraw paths are reachable
Teemu Piippo <teemu@hecknology.net>
parents:
32
diff
changeset
|
69 | )) |
36
2753aad79678
now checks that paths are specified
Teemu Piippo <teemu@hecknology.net>
parents:
34
diff
changeset
|
70 | if not have_paths: |
2753aad79678
now checks that paths are specified
Teemu Piippo <teemu@hecknology.net>
parents:
34
diff
changeset
|
71 | print('No LDraw path specified') |
2753aad79678
now checks that paths are specified
Teemu Piippo <teemu@hecknology.net>
parents:
34
diff
changeset
|
72 | problems = True |
34
7ed2e831acd4
the program now checks that all ldraw paths are reachable
Teemu Piippo <teemu@hecknology.net>
parents:
32
diff
changeset
|
73 | if problems: |
7ed2e831acd4
the program now checks that all ldraw paths are reachable
Teemu Piippo <teemu@hecknology.net>
parents:
32
diff
changeset
|
74 | print('Please fix ldcheck.cfg') |
7ed2e831acd4
the program now checks that all ldraw paths are reachable
Teemu Piippo <teemu@hecknology.net>
parents:
32
diff
changeset
|
75 | exit(1) |
7ed2e831acd4
the program now checks that all ldraw paths are reachable
Teemu Piippo <teemu@hecknology.net>
parents:
32
diff
changeset
|
76 | |
9
fea8e9ae6f29
Added matrix code, moved library paths to ldcheck.cfg.
Santeri Piippo
parents:
8
diff
changeset
|
77 | def find_ldconfig_ldr_paths(config): |
fea8e9ae6f29
Added matrix code, moved library paths to ldcheck.cfg.
Santeri Piippo
parents:
8
diff
changeset
|
78 | for library_path in library_paths(config): |
17 | 79 | yield from [ |
80 | library_path / path | |
81 | for path in ['LDConfig.ldr', 'ldconfig.ldr'] | |
82 | if (library_path / path).is_file() | |
8 | 83 | ] |
84 | ||
13 | 85 | class Model: |
47
4da025d0b283
added work on header check
Teemu Piippo <teemu@hecknology.net>
parents:
38
diff
changeset
|
86 | def __init__(self, header, body, *, header_size = 0): |
4da025d0b283
added work on header check
Teemu Piippo <teemu@hecknology.net>
parents:
38
diff
changeset
|
87 | self.header = header |
17 | 88 | self.body = body |
47
4da025d0b283
added work on header check
Teemu Piippo <teemu@hecknology.net>
parents:
38
diff
changeset
|
89 | self.header_size = header_size |
21 | 90 | def filter_by_type(self, type): |
17 | 91 | yield from [ |
92 | element | |
93 | for element in self.body | |
21 | 94 | if isinstance(element, type) |
17 | 95 | ] |
21 | 96 | @property |
97 | def subfile_references(self): | |
98 | yield from self.filter_by_type(linetypes.SubfileReference) | |
99 | @property | |
100 | def line_segments(self): | |
101 | yield from self.filter_by_type(linetypes.LineSegment) | |
102 | @property | |
103 | def triangles(self): | |
104 | yield from self.filter_by_type(linetypes.Triangle) | |
105 | @property | |
106 | def quadrilaterals(self): | |
107 | yield from self.filter_by_type(linetypes.Quadrilateral) | |
47
4da025d0b283
added work on header check
Teemu Piippo <teemu@hecknology.net>
parents:
38
diff
changeset
|
108 | @property |
4da025d0b283
added work on header check
Teemu Piippo <teemu@hecknology.net>
parents:
38
diff
changeset
|
109 | def has_header(self): |
4da025d0b283
added work on header check
Teemu Piippo <teemu@hecknology.net>
parents:
38
diff
changeset
|
110 | return self.header and not isinstance(self.header, header.BadHeader) |
13 | 111 | |
26
7c263b864371
Added command line option to list all checks.
Santeri Piippo
parents:
21
diff
changeset
|
112 | import argparse |
7c263b864371
Added command line option to list all checks.
Santeri Piippo
parents:
21
diff
changeset
|
113 | class ListTestSuiteAction(argparse.Action): |
7c263b864371
Added command line option to list all checks.
Santeri Piippo
parents:
21
diff
changeset
|
114 | def __init__(self, option_strings, dest, nargs = None, **kwargs): |
7c263b864371
Added command line option to list all checks.
Santeri Piippo
parents:
21
diff
changeset
|
115 | super().__init__(option_strings, dest, nargs = 0, **kwargs) |
7c263b864371
Added command line option to list all checks.
Santeri Piippo
parents:
21
diff
changeset
|
116 | def __call__(self, *args, **kwargs): |
7c263b864371
Added command line option to list all checks.
Santeri Piippo
parents:
21
diff
changeset
|
117 | from testsuite import load_tests |
7c263b864371
Added command line option to list all checks.
Santeri Piippo
parents:
21
diff
changeset
|
118 | from sys import exit |
7c263b864371
Added command line option to list all checks.
Santeri Piippo
parents:
21
diff
changeset
|
119 | from re import sub |
7c263b864371
Added command line option to list all checks.
Santeri Piippo
parents:
21
diff
changeset
|
120 | test_suite = load_tests() |
7c263b864371
Added command line option to list all checks.
Santeri Piippo
parents:
21
diff
changeset
|
121 | for test_name in sorted(test_suite['tests'].keys()): |
7c263b864371
Added command line option to list all checks.
Santeri Piippo
parents:
21
diff
changeset
|
122 | test_function = test_suite['tests'][test_name] |
7c263b864371
Added command line option to list all checks.
Santeri Piippo
parents:
21
diff
changeset
|
123 | help = sub(r'\s+', ' ', test_function.__doc__ or '').strip() |
7c263b864371
Added command line option to list all checks.
Santeri Piippo
parents:
21
diff
changeset
|
124 | print(test_name + ': ' + help) |
7c263b864371
Added command line option to list all checks.
Santeri Piippo
parents:
21
diff
changeset
|
125 | exit(0) |
7c263b864371
Added command line option to list all checks.
Santeri Piippo
parents:
21
diff
changeset
|
126 | |
3
1dc58f44d556
Can now write dat files, added direct color handling
Santeri Piippo
parents:
diff
changeset
|
127 | if __name__ == '__main__': |
1dc58f44d556
Can now write dat files, added direct color handling
Santeri Piippo
parents:
diff
changeset
|
128 | from sys import argv |
26
7c263b864371
Added command line option to list all checks.
Santeri Piippo
parents:
21
diff
changeset
|
129 | parser = argparse.ArgumentParser() |
7c263b864371
Added command line option to list all checks.
Santeri Piippo
parents:
21
diff
changeset
|
130 | parser.add_argument('filename') |
7c263b864371
Added command line option to list all checks.
Santeri Piippo
parents:
21
diff
changeset
|
131 | parser.add_argument('--list', |
7c263b864371
Added command line option to list all checks.
Santeri Piippo
parents:
21
diff
changeset
|
132 | action = ListTestSuiteAction, |
7c263b864371
Added command line option to list all checks.
Santeri Piippo
parents:
21
diff
changeset
|
133 | help = 'Lists all possible checks and exit', |
7c263b864371
Added command line option to list all checks.
Santeri Piippo
parents:
21
diff
changeset
|
134 | ) |
38
66c9591b733d
added proper handling of syntax errors
Teemu Piippo <teemu@hecknology.net>
parents:
36
diff
changeset
|
135 | parser.add_argument('--dump-structure', action = 'store_true') |
66c9591b733d
added proper handling of syntax errors
Teemu Piippo <teemu@hecknology.net>
parents:
36
diff
changeset
|
136 | parser.add_argument('--rebuild', action = 'store_true') |
26
7c263b864371
Added command line option to list all checks.
Santeri Piippo
parents:
21
diff
changeset
|
137 | args = parser.parse_args() |
9
fea8e9ae6f29
Added matrix code, moved library paths to ldcheck.cfg.
Santeri Piippo
parents:
8
diff
changeset
|
138 | config = load_config('ldcheck.cfg') |
fea8e9ae6f29
Added matrix code, moved library paths to ldcheck.cfg.
Santeri Piippo
parents:
8
diff
changeset
|
139 | for ldconfig_ldr_path in find_ldconfig_ldr_paths(config): |
8 | 140 | with ldconfig_ldr_path.open() as ldconfig_ldr: |
141 | load_colours(ldconfig_ldr) | |
26
7c263b864371
Added command line option to list all checks.
Santeri Piippo
parents:
21
diff
changeset
|
142 | with open(args.filename) as file: |
18 | 143 | from os.path import basename |
26
7c263b864371
Added command line option to list all checks.
Santeri Piippo
parents:
21
diff
changeset
|
144 | model = read_ldraw( |
7c263b864371
Added command line option to list all checks.
Santeri Piippo
parents:
21
diff
changeset
|
145 | file, |
7c263b864371
Added command line option to list all checks.
Santeri Piippo
parents:
21
diff
changeset
|
146 | name = basename(args.filename), |
7c263b864371
Added command line option to list all checks.
Santeri Piippo
parents:
21
diff
changeset
|
147 | config = config, |
7c263b864371
Added command line option to list all checks.
Santeri Piippo
parents:
21
diff
changeset
|
148 | ) |
38
66c9591b733d
added proper handling of syntax errors
Teemu Piippo <teemu@hecknology.net>
parents:
36
diff
changeset
|
149 | if args.dump_structure: |
47
4da025d0b283
added work on header check
Teemu Piippo <teemu@hecknology.net>
parents:
38
diff
changeset
|
150 | print('header: ' + type(model.header).__name__) |
4da025d0b283
added work on header check
Teemu Piippo <teemu@hecknology.net>
parents:
38
diff
changeset
|
151 | for key in sorted(dir(model.header)): |
4da025d0b283
added work on header check
Teemu Piippo <teemu@hecknology.net>
parents:
38
diff
changeset
|
152 | if not key.startswith('__'): |
4da025d0b283
added work on header check
Teemu Piippo <teemu@hecknology.net>
parents:
38
diff
changeset
|
153 | print('\t' + key + ': ' + repr(getattr(model.header, key))) |
38
66c9591b733d
added proper handling of syntax errors
Teemu Piippo <teemu@hecknology.net>
parents:
36
diff
changeset
|
154 | for entry in model.body: |
66c9591b733d
added proper handling of syntax errors
Teemu Piippo <teemu@hecknology.net>
parents:
36
diff
changeset
|
155 | print(entry) |
66c9591b733d
added proper handling of syntax errors
Teemu Piippo <teemu@hecknology.net>
parents:
36
diff
changeset
|
156 | elif args.rebuild: |
66c9591b733d
added proper handling of syntax errors
Teemu Piippo <teemu@hecknology.net>
parents:
36
diff
changeset
|
157 | for entry in model.body: |
66c9591b733d
added proper handling of syntax errors
Teemu Piippo <teemu@hecknology.net>
parents:
36
diff
changeset
|
158 | print(entry.textual_representation(), end = '\r\n') |
66c9591b733d
added proper handling of syntax errors
Teemu Piippo <teemu@hecknology.net>
parents:
36
diff
changeset
|
159 | else: |
66c9591b733d
added proper handling of syntax errors
Teemu Piippo <teemu@hecknology.net>
parents:
36
diff
changeset
|
160 | from testsuite import load_tests, check_model, format_report |
66c9591b733d
added proper handling of syntax errors
Teemu Piippo <teemu@hecknology.net>
parents:
36
diff
changeset
|
161 | test_suite = load_tests() |
66c9591b733d
added proper handling of syntax errors
Teemu Piippo <teemu@hecknology.net>
parents:
36
diff
changeset
|
162 | report = check_model(model, test_suite) |
66c9591b733d
added proper handling of syntax errors
Teemu Piippo <teemu@hecknology.net>
parents:
36
diff
changeset
|
163 | print(format_report(report, model, test_suite)) |