filecache.py

Mon, 24 Jun 2019 01:06:37 +0300

author
Teemu Piippo <teemu@hecknology.net>
date
Mon, 24 Jun 2019 01:06:37 +0300
changeset 86
b25fc6f7eb70
parent 58
86014c443635
child 92
b8d72909d593
permissions
-rw-r--r--

added tests for missing license and non-CA

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()
58
86014c443635 try to fix crashing
Teemu Piippo <teemu@hecknology.net>
parents: 54
diff changeset
44 if ldraw_directories and isinstance(ldraw_directories[0], str):
86014c443635 try to fix crashing
Teemu Piippo <teemu@hecknology.net>
parents: 54
diff changeset
45 self.ldraw_directories = [
86014c443635 try to fix crashing
Teemu Piippo <teemu@hecknology.net>
parents: 54
diff changeset
46 Path(os.path.expanduser(directory))
86014c443635 try to fix crashing
Teemu Piippo <teemu@hecknology.net>
parents: 54
diff changeset
47 for directory in ldraw_directories
86014c443635 try to fix crashing
Teemu Piippo <teemu@hecknology.net>
parents: 54
diff changeset
48 ]
86014c443635 try to fix crashing
Teemu Piippo <teemu@hecknology.net>
parents: 54
diff changeset
49 else:
86014c443635 try to fix crashing
Teemu Piippo <teemu@hecknology.net>
parents: 54
diff changeset
50 from copy import copy
86014c443635 try to fix crashing
Teemu Piippo <teemu@hecknology.net>
parents: 54
diff changeset
51 self.ldraw_directories = copy(ldraw_directories)
54
0c686d10eb49 added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
52 self.reference_stack = []
0c686d10eb49 added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
53 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
54 '''
0c686d10eb49 added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
55 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
56 '''
0c686d10eb49 added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
57 self.prepare_file(filename)
0c686d10eb49 added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
58 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
59 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
60 '''
0c686d10eb49 added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
61 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
62 '''
0c686d10eb49 added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
63 self.prepare_file(filename)
0c686d10eb49 added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
64 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
65 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
66 return find_ldraw_file(
0c686d10eb49 added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
67 filename = filename,
0c686d10eb49 added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
68 libraries = self.ldraw_directories,
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 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
71 '''
0c686d10eb49 added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
72 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
73 '''
0c686d10eb49 added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
74 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
75 self._load_subfile(filename)
0c686d10eb49 added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
76 return self.cache[filename]
0c686d10eb49 added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
77 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
78 # ward against cyclical dependencies
0c686d10eb49 added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
79 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
80 raise CyclicalReferenceError(
0c686d10eb49 added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
81 ' -> '.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
82 )
0c686d10eb49 added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
83 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
84 subfile = SubfileCache.Subfile()
0c686d10eb49 added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
85 self.cache[filename] = subfile
0c686d10eb49 added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
86 try:
0c686d10eb49 added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
87 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
88 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
89 model = parse.read_ldraw(
0c686d10eb49 added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
90 file,
0c686d10eb49 added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
91 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
92 )
0c686d10eb49 added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
93 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
94 subfile.valid = False
0c686d10eb49 added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
95 subfile.problem = str(error)
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 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
98 subfile.valid = True
0c686d10eb49 added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
99 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
100 else:
0c686d10eb49 added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
101 subfile.valid = False
0c686d10eb49 added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
102 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
103 if subfile.valid:
0c686d10eb49 added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
104 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
105 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
106 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
107 # 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
108 # 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
109 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
110 if not math.isclose(
0c686d10eb49 added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
111 getattr(vertex, dimension),
0c686d10eb49 added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
112 0.0,
0c686d10eb49 added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
113 abs_tol = 1e-05,
0c686d10eb49 added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
114 ):
0c686d10eb49 added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
115 subfile.flatness.remove(dimension)
0c686d10eb49 added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
116 if not subfile.flatness:
0c686d10eb49 added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
117 break
0c686d10eb49 added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
118 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
119 # 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
120 # cyclical references
0c686d10eb49 added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
121 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
122 self.reference_stack.pop()
0c686d10eb49 added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
123
0c686d10eb49 added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
124 if __name__ == '__main__':
0c686d10eb49 added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
125 cache = SubfileCache(ldraw_directories = ["~/ldraw"])

mercurial