filecache.py

Thu, 26 Aug 2021 19:37:00 +0300

author
Teemu Piippo <teemu@hecknology.net>
date
Thu, 26 Aug 2021 19:37:00 +0300
changeset 148
8f621aa4cfd7
parent 145
fde18c4d6784
permissions
-rw-r--r--

Update license year

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
92
b8d72909d593 improved the mirrored stud check to catch cases where a subfile that contains studs is mirrored
Teemu Piippo <teemu@hecknology.net>
parents: 58
diff changeset
28 def is_logo_stud_name(name):
b8d72909d593 improved the mirrored stud check to catch cases where a subfile that contains studs is mirrored
Teemu Piippo <teemu@hecknology.net>
parents: 58
diff changeset
29 return name in ['stud.dat', 'stud3.dat']
b8d72909d593 improved the mirrored stud check to catch cases where a subfile that contains studs is mirrored
Teemu Piippo <teemu@hecknology.net>
parents: 58
diff changeset
30
54
0c686d10eb49 added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
31 class CyclicalReferenceError(Exception):
0c686d10eb49 added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
32 pass
0c686d10eb49 added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
33
0c686d10eb49 added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
34 class SubfileCache:
0c686d10eb49 added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
35 class Subfile:
0c686d10eb49 added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
36 def __init__(self):
0c686d10eb49 added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
37 self.valid = None
0c686d10eb49 added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
38 self.flatness = None
0c686d10eb49 added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
39 self.description = None
0c686d10eb49 added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
40 self.problem = None
92
b8d72909d593 improved the mirrored stud check to catch cases where a subfile that contains studs is mirrored
Teemu Piippo <teemu@hecknology.net>
parents: 58
diff changeset
41 self.has_studs = None # Whether or not it contains studs
54
0c686d10eb49 added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
42 self.vertices = set()
145
fde18c4d6784 refactoring: moved context-dependant data to new class LDrawContext. ldcheck no longer writes the config file, and looks for it in sensible locations like ~/.config and /etc. LDraw libraries can now be specified on the command line.
Teemu Piippo <teemu@hecknology.net>
parents: 95
diff changeset
43 def __init__(self, context):
54
0c686d10eb49 added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
44 '''
0c686d10eb49 added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
45 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
46 '''
0c686d10eb49 added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
47 self.cache = dict()
145
fde18c4d6784 refactoring: moved context-dependant data to new class LDrawContext. ldcheck no longer writes the config file, and looks for it in sensible locations like ~/.config and /etc. LDraw libraries can now be specified on the command line.
Teemu Piippo <teemu@hecknology.net>
parents: 95
diff changeset
48 self.context = context
54
0c686d10eb49 added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
49 self.reference_stack = []
0c686d10eb49 added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
50 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
51 '''
0c686d10eb49 added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
52 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
53 '''
0c686d10eb49 added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
54 self.prepare_file(filename)
0c686d10eb49 added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
55 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
56 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
57 '''
0c686d10eb49 added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
58 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
59 '''
0c686d10eb49 added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
60 self.prepare_file(filename)
0c686d10eb49 added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
61 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
62 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
63 return find_ldraw_file(
0c686d10eb49 added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
64 filename = filename,
145
fde18c4d6784 refactoring: moved context-dependant data to new class LDrawContext. ldcheck no longer writes the config file, and looks for it in sensible locations like ~/.config and /etc. LDraw libraries can now be specified on the command line.
Teemu Piippo <teemu@hecknology.net>
parents: 95
diff changeset
65 libraries = self.context.libraries,
54
0c686d10eb49 added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
66 )
0c686d10eb49 added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
67 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
68 '''
0c686d10eb49 added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
69 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
70 '''
0c686d10eb49 added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
71 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
72 self._load_subfile(filename)
0c686d10eb49 added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
73 return self.cache[filename]
0c686d10eb49 added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
74 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
75 # ward against cyclical dependencies
0c686d10eb49 added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
76 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
77 raise CyclicalReferenceError(
0c686d10eb49 added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
78 ' -> '.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
79 )
0c686d10eb49 added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
80 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
81 subfile = SubfileCache.Subfile()
0c686d10eb49 added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
82 self.cache[filename] = subfile
0c686d10eb49 added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
83 try:
0c686d10eb49 added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
84 path = self.find_file(filename)
94
109fb7cf658f added a check for non-DOS line endings
Teemu Piippo <teemu@hecknology.net>
parents: 92
diff changeset
85 with path.open('rb') as file:
145
fde18c4d6784 refactoring: moved context-dependant data to new class LDrawContext. ldcheck no longer writes the config file, and looks for it in sensible locations like ~/.config and /etc. LDraw libraries can now be specified on the command line.
Teemu Piippo <teemu@hecknology.net>
parents: 95
diff changeset
86 model = parse.read_ldraw(file, context = self.context)
54
0c686d10eb49 added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
87 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
88 subfile.valid = False
0c686d10eb49 added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
89 subfile.problem = str(error)
0c686d10eb49 added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
90 else:
0c686d10eb49 added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
91 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
92 subfile.valid = True
0c686d10eb49 added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
93 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
94 else:
0c686d10eb49 added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
95 subfile.valid = False
0c686d10eb49 added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
96 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
97 if subfile.valid:
95
a3536e51f6bc fixed the cyclical dependency handling
Teemu Piippo <teemu@hecknology.net>
parents: 94
diff changeset
98 subfile.vertices = set(parse.model_vertices(model, file_cache = self))
54
0c686d10eb49 added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
99 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
100 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
101 # 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
102 # 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
103 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
104 if not math.isclose(
0c686d10eb49 added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
105 getattr(vertex, dimension),
0c686d10eb49 added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
106 0.0,
0c686d10eb49 added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
107 abs_tol = 1e-05,
0c686d10eb49 added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
108 ):
0c686d10eb49 added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
109 subfile.flatness.remove(dimension)
0c686d10eb49 added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
110 if not subfile.flatness:
0c686d10eb49 added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
111 break
0c686d10eb49 added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
112 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
113 # Go through all the subfile references so that we catch any
92
b8d72909d593 improved the mirrored stud check to catch cases where a subfile that contains studs is mirrored
Teemu Piippo <teemu@hecknology.net>
parents: 58
diff changeset
114 # cyclical references and to get studs
54
0c686d10eb49 added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
115 self.prepare_file(subfile_reference.subfile_path)
92
b8d72909d593 improved the mirrored stud check to catch cases where a subfile that contains studs is mirrored
Teemu Piippo <teemu@hecknology.net>
parents: 58
diff changeset
116 subfile.has_studs = any(
b8d72909d593 improved the mirrored stud check to catch cases where a subfile that contains studs is mirrored
Teemu Piippo <teemu@hecknology.net>
parents: 58
diff changeset
117 self.cache[subfile_reference.subfile_path].has_studs
b8d72909d593 improved the mirrored stud check to catch cases where a subfile that contains studs is mirrored
Teemu Piippo <teemu@hecknology.net>
parents: 58
diff changeset
118 or is_logo_stud_name(subfile_reference.subfile_path)
b8d72909d593 improved the mirrored stud check to catch cases where a subfile that contains studs is mirrored
Teemu Piippo <teemu@hecknology.net>
parents: 58
diff changeset
119 for subfile_reference in model.subfile_references
b8d72909d593 improved the mirrored stud check to catch cases where a subfile that contains studs is mirrored
Teemu Piippo <teemu@hecknology.net>
parents: 58
diff changeset
120 )
54
0c686d10eb49 added tests for moved-to files and scaling in flat dimensions
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
121 self.reference_stack.pop()

mercurial