filecache.py

Sat, 01 Jun 2019 10:47:27 +0300

author
Teemu Piippo <teemu@hecknology.net>
date
Sat, 01 Jun 2019 10:47:27 +0300
changeset 55
388df1fa18a2
parent 54
0c686d10eb49
child 58
86014c443635
permissions
-rw-r--r--

fixed handling of invalid subfiles

54
0c686d10eb49 added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
1 import datetime
0c686d10eb49 added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
2 import parse
0c686d10eb49 added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
3 import os
0c686d10eb49 added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
4 from pathlib import Path
0c686d10eb49 added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
5 import linetypes
0c686d10eb49 added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
6 import math
0c686d10eb49 added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
7
0c686d10eb49 added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
8 def find_ldraw_file(filename, libraries):
0c686d10eb49 added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
9 '''
0c686d10eb49 added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
10 Searches the LDraw libraries for the specified file.
0c686d10eb49 added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
11 `libraries` must be an iterable of LDraw library root paths.
0c686d10eb49 added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
12 '''
0c686d10eb49 added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
13 if os.path.sep != "\\":
0c686d10eb49 added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
14 filename = filename.replace("\\", os.path.sep)
0c686d10eb49 added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
15 for library in libraries:
0c686d10eb49 added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
16 for path in [
0c686d10eb49 added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
17 Path(library) / filename,
0c686d10eb49 added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
18 Path(library) / "parts" / filename,
0c686d10eb49 added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
19 Path(library) / "p" / filename,
0c686d10eb49 added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
20 ]:
0c686d10eb49 added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
21 if path.exists():
0c686d10eb49 added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
22 return path
0c686d10eb49 added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
23 raise FileNotFoundError(str.format(
0c686d10eb49 added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
24 '"{}" not found in the LDraw libraries',
0c686d10eb49 added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
25 filename,
0c686d10eb49 added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
26 ))
0c686d10eb49 added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
27
0c686d10eb49 added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
28 class CyclicalReferenceError(Exception):
0c686d10eb49 added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
29 pass
0c686d10eb49 added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
30
0c686d10eb49 added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
31 class SubfileCache:
0c686d10eb49 added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
32 class Subfile:
0c686d10eb49 added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
33 def __init__(self):
0c686d10eb49 added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
34 self.valid = None
0c686d10eb49 added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
35 self.flatness = None
0c686d10eb49 added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
36 self.description = None
0c686d10eb49 added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
37 self.problem = None
0c686d10eb49 added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
38 self.vertices = set()
0c686d10eb49 added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
39 def __init__(self, ldraw_directories):
0c686d10eb49 added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
40 '''
0c686d10eb49 added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
41 Initializes a new subfile cache
0c686d10eb49 added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
42 '''
0c686d10eb49 added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
43 self.cache = dict()
0c686d10eb49 added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
44 self.ldraw_directories = [
0c686d10eb49 added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
45 Path(os.path.expanduser(directory))
0c686d10eb49 added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
46 for directory in ldraw_directories
0c686d10eb49 added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
47 ]
0c686d10eb49 added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
48 self.reference_stack = []
0c686d10eb49 added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
49 def flatness_of(self, filename):
0c686d10eb49 added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
50 '''
0c686d10eb49 added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
51 Returns the set of all directiones the specified file is flat in.
0c686d10eb49 added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
52 '''
0c686d10eb49 added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
53 self.prepare_file(filename)
0c686d10eb49 added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
54 return self.cache[filename].flatness
0c686d10eb49 added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
55 def description_of(self, filename):
0c686d10eb49 added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
56 '''
0c686d10eb49 added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
57 Returns the description of the specified file
0c686d10eb49 added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
58 '''
0c686d10eb49 added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
59 self.prepare_file(filename)
0c686d10eb49 added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
60 return self.cache[filename].description
0c686d10eb49 added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
61 def find_file(self, filename):
0c686d10eb49 added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
62 return find_ldraw_file(
0c686d10eb49 added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
63 filename = filename,
0c686d10eb49 added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
64 libraries = self.ldraw_directories,
0c686d10eb49 added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
65 )
0c686d10eb49 added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
66 def prepare_file(self, filename):
0c686d10eb49 added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
67 '''
0c686d10eb49 added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
68 Loads the file if not loaded yet.
0c686d10eb49 added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
69 '''
0c686d10eb49 added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
70 if filename not in self.cache:
0c686d10eb49 added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
71 self._load_subfile(filename)
0c686d10eb49 added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
72 return self.cache[filename]
0c686d10eb49 added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
73 def _load_subfile(self, filename):
0c686d10eb49 added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
74 # ward against cyclical dependencies
0c686d10eb49 added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
75 if filename in self.reference_stack:
0c686d10eb49 added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
76 raise CyclicalReferenceError(
0c686d10eb49 added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
77 ' -> '.join(self.reference_stack + [filename]),
0c686d10eb49 added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
78 )
0c686d10eb49 added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
79 self.reference_stack.append(filename)
0c686d10eb49 added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
80 subfile = SubfileCache.Subfile()
0c686d10eb49 added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
81 self.cache[filename] = subfile
0c686d10eb49 added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
82 try:
0c686d10eb49 added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
83 path = self.find_file(filename)
0c686d10eb49 added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
84 with path.open() as file:
0c686d10eb49 added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
85 model = parse.read_ldraw(
0c686d10eb49 added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
86 file,
0c686d10eb49 added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
87 ldraw_directories = self.ldraw_directories,
0c686d10eb49 added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
88 )
0c686d10eb49 added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
89 except (FileNotFoundError, IOError, PermissionError) as error:
0c686d10eb49 added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
90 subfile.valid = False
0c686d10eb49 added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
91 subfile.problem = str(error)
0c686d10eb49 added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
92 else:
0c686d10eb49 added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
93 if isinstance(model.body[0], linetypes.MetaCommand):
0c686d10eb49 added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
94 subfile.valid = True
0c686d10eb49 added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
95 subfile.description = model.body[0].text
0c686d10eb49 added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
96 else:
0c686d10eb49 added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
97 subfile.valid = False
0c686d10eb49 added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
98 subfile.problem = 'Description not found'
0c686d10eb49 added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
99 if subfile.valid:
0c686d10eb49 added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
100 subfile.vertices = set(parse.model_vertices(model))
0c686d10eb49 added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
101 subfile.flatness = {'x', 'y', 'z'}
0c686d10eb49 added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
102 for vertex in subfile.vertices:
0c686d10eb49 added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
103 # Use list(subfile.flatness) for iteration because the
0c686d10eb49 added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
104 # actual set may be modified during the loop
0c686d10eb49 added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
105 for dimension in list(subfile.flatness):
0c686d10eb49 added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
106 if not math.isclose(
0c686d10eb49 added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
107 getattr(vertex, dimension),
0c686d10eb49 added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
108 0.0,
0c686d10eb49 added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
109 abs_tol = 1e-05,
0c686d10eb49 added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
110 ):
0c686d10eb49 added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
111 subfile.flatness.remove(dimension)
0c686d10eb49 added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
112 if not subfile.flatness:
0c686d10eb49 added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
113 break
0c686d10eb49 added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
114 for subfile_reference in model.subfile_references:
0c686d10eb49 added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
115 # Go through all the subfile references so that we catch any
0c686d10eb49 added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
116 # cyclical references
0c686d10eb49 added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
117 self.prepare_file(subfile_reference.subfile_path)
0c686d10eb49 added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
118 self.reference_stack.pop()
0c686d10eb49 added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
119
0c686d10eb49 added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
120 if __name__ == '__main__':
0c686d10eb49 added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
121 cache = SubfileCache(ldraw_directories = ["~/ldraw"])

mercurial