flinventory 0.3.2__py3-none-any.whl → 0.4.2__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- flinventory/inventory_io.py +68 -4
- flinventory/thing.py +1 -1
- {flinventory-0.3.2.dist-info → flinventory-0.4.2.dist-info}/METADATA +2 -2
- {flinventory-0.3.2.dist-info → flinventory-0.4.2.dist-info}/RECORD +7 -7
- {flinventory-0.3.2.dist-info → flinventory-0.4.2.dist-info}/WHEEL +1 -1
- {flinventory-0.3.2.dist-info → flinventory-0.4.2.dist-info}/entry_points.txt +0 -0
- {flinventory-0.3.2.dist-info → flinventory-0.4.2.dist-info}/licenses/LICENSE +0 -0
flinventory/inventory_io.py
CHANGED
@@ -8,7 +8,7 @@ import random
|
|
8
8
|
import argparse
|
9
9
|
import logging
|
10
10
|
import os
|
11
|
-
from typing import Callable, Sequence, Iterable, Optional, Self,
|
11
|
+
from typing import Callable, Sequence, Iterable, Optional, Self, Iterator, cast
|
12
12
|
|
13
13
|
from . import constant
|
14
14
|
from .box import BoxedThing
|
@@ -120,7 +120,6 @@ class Inventory(list[BoxedThing]):
|
|
120
120
|
Saving schema would be possible with schema.json attribute.
|
121
121
|
todo: maybe save options
|
122
122
|
"""
|
123
|
-
logger = logging.getLogger("save_things")
|
124
123
|
for thing in self:
|
125
124
|
thing.save()
|
126
125
|
|
@@ -148,7 +147,7 @@ class Inventory(list[BoxedThing]):
|
|
148
147
|
return thing
|
149
148
|
raise KeyError(thing_id)
|
150
149
|
|
151
|
-
def get_by_key(self, key, value) ->
|
150
|
+
def get_by_key(self, key, value) -> Iterable[BoxedThing]:
|
152
151
|
"""Return all boxed things that have this value for this key.
|
153
152
|
|
154
153
|
For example useful for looking up thing by name: get_by_key(('name', 0), 'Nice thing')
|
@@ -174,6 +173,71 @@ class Inventory(list[BoxedThing]):
|
|
174
173
|
"""
|
175
174
|
return (box for box in self if box.thing.best(key, backup=None) == value)
|
176
175
|
|
176
|
+
def direct_ancestors(self, thing: BoxedThing, key: str) -> set[BoxedThing]:
|
177
|
+
"""Convert key (assuming list of ids) into set of things.
|
178
|
+
|
179
|
+
Intended for key = subclass_of and part_of.
|
180
|
+
"""
|
181
|
+
generalisations = set()
|
182
|
+
for thing_id in cast(tuple, thing.get(key, tuple())):
|
183
|
+
try:
|
184
|
+
generalisations.add(self.get_by_id(thing_id))
|
185
|
+
except KeyError:
|
186
|
+
logging.getLogger("inventory.direct_generalisations").warning(
|
187
|
+
f"id {thing_id} in {self.get_id(thing)} ({thing.best('name', backup="?")}) "
|
188
|
+
"subclass_of is not a valid id. Ignore it."
|
189
|
+
)
|
190
|
+
return generalisations
|
191
|
+
|
192
|
+
def ancestors(self, thing: BoxedThing, key: str) -> set[BoxedThing]:
|
193
|
+
"""Get all direct and indirect key of elements as things.
|
194
|
+
|
195
|
+
Intended for key = subclass_of and part_of.
|
196
|
+
"""
|
197
|
+
generalisations = set()
|
198
|
+
unchecked = {thing}
|
199
|
+
while unchecked:
|
200
|
+
current = unchecked.pop()
|
201
|
+
generalisations.add(current)
|
202
|
+
unchecked.update(self.direct_ancestors(current, key))
|
203
|
+
# to avoid checking something again, avoiding infinite loops:
|
204
|
+
unchecked.difference_update(generalisations)
|
205
|
+
return generalisations.difference({thing})
|
206
|
+
|
207
|
+
def super_things(self, thing: BoxedThing) -> set[BoxedThing]:
|
208
|
+
"""Get all things this thing is a part of. Directly or indirectly.
|
209
|
+
|
210
|
+
That is: a part_of b & b part_of c ⇒ a part_of c
|
211
|
+
and a subclass_of b not⇒ a part_of b but
|
212
|
+
a subclass_of b & b part_of c ⇒ a part_of c
|
213
|
+
|
214
|
+
Infinite loops must be avoided, so simple recursive call might be problematic.
|
215
|
+
|
216
|
+
Not implemented but maybe necessary: caching result in the thing.
|
217
|
+
Cache must be invalidated whenever part_of or subclass_of of any
|
218
|
+
included thing changes. Difficult. Better would be cache on the
|
219
|
+
direct level.
|
220
|
+
"""
|
221
|
+
supers = set()
|
222
|
+
unchecked = {thing}
|
223
|
+
generalisations = {thing} # only saved to avoid recursion loop
|
224
|
+
unchecked_generalisations = set()
|
225
|
+
while unchecked or unchecked_generalisations:
|
226
|
+
if unchecked:
|
227
|
+
current = unchecked.pop()
|
228
|
+
supers.add(current)
|
229
|
+
else:
|
230
|
+
current = unchecked_generalisations.pop()
|
231
|
+
generalisations.add(current)
|
232
|
+
unchecked.update(self.direct_ancestors(current, "part_of"))
|
233
|
+
unchecked_generalisations.update(
|
234
|
+
self.direct_ancestors(current, "subclass_of")
|
235
|
+
)
|
236
|
+
unchecked.difference_update(supers)
|
237
|
+
unchecked_generalisations.difference_update(generalisations)
|
238
|
+
|
239
|
+
return supers.difference({thing})
|
240
|
+
|
177
241
|
|
178
242
|
def check_filename_types(filetypes: Sequence[str]) -> Callable[[str], str]:
|
179
243
|
"""Create function that checks for being a simple file.
|
@@ -267,7 +331,7 @@ def add_file_args(parser: argparse.ArgumentParser) -> None:
|
|
267
331
|
"--logfile",
|
268
332
|
"-lf",
|
269
333
|
default="things.log",
|
270
|
-
help=
|
334
|
+
help="Where to write the log file. Relative to the out directory.",
|
271
335
|
type=check_filename_types([".log"]),
|
272
336
|
)
|
273
337
|
|
flinventory/thing.py
CHANGED
@@ -39,7 +39,7 @@ class Thing(defaulted_data.DefaultedDict):
|
|
39
39
|
default=default,
|
40
40
|
non_defaulted=tuple(),
|
41
41
|
translated=("name", "name_alt", "description"),
|
42
|
-
lists=("name_alt", "part_of"),
|
42
|
+
lists=("name_alt", "part_of", "subclass_of"),
|
43
43
|
default_order=("name", "name_alt", "part_of", "category", "url"),
|
44
44
|
options=options,
|
45
45
|
)
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: flinventory
|
3
|
-
Version: 0.
|
3
|
+
Version: 0.4.2
|
4
4
|
Summary: An inventory system for self-help repair shops
|
5
5
|
Author-Email: flukx <flinventory-flukx@612211124.xyz>
|
6
6
|
License: GPL3
|
@@ -43,7 +43,7 @@ There this inventory should help.
|
|
43
43
|
3. Each thing can be found by one of its names alphabetically, by several categories, by English or German name, by looking at pictures in the storage. Not a single categorization to be limited to.
|
44
44
|
|
45
45
|
## Data
|
46
|
-
For example data see the directory `sample-data` or [the data repository](https://flugit.hilsky.de/flukx/things-data)
|
46
|
+
For example data see the directory `sample-data` or [branch Rad i.O. in the data repository](https://codeberg.org/flukx/flings/src/branch/rad-i-o) or the [private data repository](https://flugit.hilsky.de/flukx/things-data) if you have access.
|
47
47
|
The data format is a specific directory structure with specific file names:
|
48
48
|
- `schema.yaml`: describes how locations in this workshop are defined. See `sample_data` for details.
|
49
49
|
- `preferences.yaml`: general options for this data. See `sample_data` for details.
|
@@ -1,7 +1,7 @@
|
|
1
|
-
flinventory-0.
|
2
|
-
flinventory-0.
|
3
|
-
flinventory-0.
|
4
|
-
flinventory-0.
|
1
|
+
flinventory-0.4.2.dist-info/METADATA,sha256=ZQjK-O4pZu_8nTuBLmDKJ0iSepizKaVkxaGIRP-cTnc,4542
|
2
|
+
flinventory-0.4.2.dist-info/WHEEL,sha256=tSfRZzRHthuv7vxpI4aehrdN9scLjk-dCJkPLzkHxGg,90
|
3
|
+
flinventory-0.4.2.dist-info/entry_points.txt,sha256=6OYgBcLyFCUgeqLgnvMyOJxPCWzgy7se4rLPKtNonMs,34
|
4
|
+
flinventory-0.4.2.dist-info/licenses/LICENSE,sha256=9c-AWlAEeFMmn1aODEfabsw2he-SpQeykurYw-KqSdw,34478
|
5
5
|
flinventory/__init__.py,sha256=0HTGxw9J-2KnbxQbzX6HH-Pztkp0BEjiHANhndfbtYM,270
|
6
6
|
flinventory/__main__.py,sha256=YI3dGiBr1i56JpGommQTWYjgfCmhr2JT1pQUdf0lf1w,1228
|
7
7
|
flinventory/box.py,sha256=rk7yrAjVdxcrpvmTMt3jkMVOAoQNJfqoSig9U2S3yJ0,10480
|
@@ -9,15 +9,15 @@ flinventory/constant.py,sha256=pPNCwScLon_MOKL9_jjD_sxqB7Q2WW6rZqtrBl7SyWk,10283
|
|
9
9
|
flinventory/datacleanup.py,sha256=_CImmWJhq5uKz21jJQUqKYoQfbHEYA0000RyPRt5BI0,11363
|
10
10
|
flinventory/defaulted_data.py,sha256=KAy6V2KLcifLg7zHBFnx_eFLp31sCWih1Btp6cE0bQc,21585
|
11
11
|
flinventory/generate_labels.py,sha256=wB9ibokHOcab599qZhi5uTzfy3DTo3wT4DJP9qLMzXs,6642
|
12
|
-
flinventory/inventory_io.py,sha256=
|
12
|
+
flinventory/inventory_io.py,sha256=OWThcf9nzeZNqvNpzQiBhESQAnVXC7hUA8DEVzq-w-Y,12561
|
13
13
|
flinventory/location.py,sha256=eaZ8tF8HdzH17IBDl3_p_MsnSw5-H1GfbvkTe3dPFGk,16593
|
14
14
|
flinventory/sign.py,sha256=8G7fsne3Nsf8zZKKTUl40uWMNsWIv7FYV2KcqBR2MQI,5515
|
15
15
|
flinventory/signprinter_latex.py,sha256=Ytf1T_ADedj_Wkqe8bWyN23-TwFaKE7zFpeoYxn5NzM,19105
|
16
|
-
flinventory/thing.py,sha256=
|
16
|
+
flinventory/thing.py,sha256=86fXj3RwTbkCdVVWrbyO-VEW_e5lKJlV8PPt1Xf8ejY,5079
|
17
17
|
flinventory/thingtemplate_latex/.gitignore,sha256=DTF250Ttj8O2lxrQBwMNrQ73rWPvdwCytipfZSLFtlU,51
|
18
18
|
flinventory/thingtemplate_latex/dummyImage.jpg,sha256=bIBH5Lrxlr5qJ42nP1cpJXPRNGLOwyEuzwXFSvNwTSk,147857
|
19
19
|
flinventory/thingtemplate_latex/sign.tex,sha256=cVlOjImuS97Gf19MGW27HiP6Uw8JNnobXym6NlY-qSI,787
|
20
20
|
flinventory/thingtemplate_latex/signlist-footer.tex,sha256=LcZw5__h8SqgMmYxs5oLbXLaFTQlx_X5rtYnpxwUh9Y,14
|
21
21
|
flinventory/thingtemplate_latex/signlist-header.tex,sha256=F1J4aSPq6QO_Ved4Zn7-rytP1vDkdWTqjjtGJpe_FDg,297
|
22
22
|
flinventory/thingtemplate_latex/signs-example.tex,sha256=J6eCcPhP0Xklgn8xnSenDOvjzmc_NGmakWU4RGbeUtM,3090
|
23
|
-
flinventory-0.
|
23
|
+
flinventory-0.4.2.dist-info/RECORD,,
|
File without changes
|
File without changes
|