flinventory 2.2.4__tar.gz → 2.3.1__tar.gz
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-2.2.4 → flinventory-2.3.1}/PKG-INFO +1 -1
- {flinventory-2.2.4 → flinventory-2.3.1}/flinventory/__init__.py +1 -0
- {flinventory-2.2.4 → flinventory-2.3.1}/flinventory/constant.py +8 -4
- {flinventory-2.2.4 → flinventory-2.3.1}/flinventory/datacleanup.py +12 -68
- {flinventory-2.2.4 → flinventory-2.3.1}/flinventory/defaulted_data.py +3 -1
- {flinventory-2.2.4 → flinventory-2.3.1}/flinventory/generate_labels.py +62 -11
- {flinventory-2.2.4 → flinventory-2.3.1}/flinventory/inventory_io.py +59 -1
- {flinventory-2.2.4 → flinventory-2.3.1}/flinventory/sign.py +2 -1
- {flinventory-2.2.4 → flinventory-2.3.1}/pyproject.toml +4 -1
- {flinventory-2.2.4 → flinventory-2.3.1}/LICENSE +0 -0
- {flinventory-2.2.4 → flinventory-2.3.1}/README.md +0 -0
- {flinventory-2.2.4 → flinventory-2.3.1}/flinventory/__main__.py +0 -0
- {flinventory-2.2.4 → flinventory-2.3.1}/flinventory/box.py +0 -0
- {flinventory-2.2.4 → flinventory-2.3.1}/flinventory/font_location.py +0 -0
- {flinventory-2.2.4 → flinventory-2.3.1}/flinventory/labelprinter_typst.py +0 -0
- {flinventory-2.2.4 → flinventory-2.3.1}/flinventory/location.py +0 -0
- {flinventory-2.2.4 → flinventory-2.3.1}/flinventory/signprinter_latex.py +0 -0
- {flinventory-2.2.4 → flinventory-2.3.1}/flinventory/thing.py +0 -0
- {flinventory-2.2.4 → flinventory-2.3.1}/flinventory/thingtemplate_typst/dummyImage.jpg +0 -0
- {flinventory-2.2.4 → flinventory-2.3.1}/flinventory/thingtemplate_typst/label.typ +0 -0
- {flinventory-2.2.4 → flinventory-2.3.1}/flinventory/thingtemplate_typst/out/bowdenzugklemmung1.svg +0 -0
- {flinventory-2.2.4 → flinventory-2.3.1}/flinventory/thingtemplate_typst/out/things.log +0 -0
- {flinventory-2.2.4 → flinventory-2.3.1}/flinventory/thingtemplate_typst/thinglist.typ +0 -0
- {flinventory-2.2.4 → flinventory-2.3.1}/tests/__init__.py +0 -0
- {flinventory-2.2.4 → flinventory-2.3.1}/tests/test_defaulted_data.py +0 -0
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
By extracting it into a file that is not importing any other one,
|
|
5
5
|
this can be imported everywhere without circular import problem.
|
|
6
6
|
"""
|
|
7
|
+
|
|
7
8
|
import os.path
|
|
8
9
|
import pathlib
|
|
9
10
|
|
|
@@ -161,14 +162,17 @@ class Options:
|
|
|
161
162
|
|
|
162
163
|
def __init__(self, options: dict[str, Any]):
|
|
163
164
|
"""Create options from content of option file."""
|
|
164
|
-
|
|
165
|
-
if isinstance(
|
|
166
|
-
self.languages = [
|
|
167
|
-
|
|
165
|
+
languages = options.get("languages", ["de", "en"])
|
|
166
|
+
if isinstance(languages, str):
|
|
167
|
+
self.languages: list[str] = [languages]
|
|
168
|
+
elif not isinstance(languages, list) or any(
|
|
169
|
+
not isinstance(language, str) for language in languages
|
|
170
|
+
):
|
|
168
171
|
raise ValueError(
|
|
169
172
|
"Language codes must be a list of strings of "
|
|
170
173
|
"valid language codes or a single valid language code."
|
|
171
174
|
)
|
|
175
|
+
self.languages = languages
|
|
172
176
|
for language in self.languages:
|
|
173
177
|
if language not in VALID_LANGUAGES:
|
|
174
178
|
raise ValueError(
|
|
@@ -8,9 +8,9 @@ import json
|
|
|
8
8
|
import os
|
|
9
9
|
import logging
|
|
10
10
|
import string
|
|
11
|
+
from typing import Optional
|
|
11
12
|
|
|
12
13
|
import yaml
|
|
13
|
-
from typing import Optional
|
|
14
14
|
|
|
15
15
|
from . import constant, labelprinter_typst
|
|
16
16
|
from . import inventory_io
|
|
@@ -74,7 +74,7 @@ def add_arg_parsers(subparsers):
|
|
|
74
74
|
+ " are not printed next time."
|
|
75
75
|
),
|
|
76
76
|
)
|
|
77
|
-
parser_printed.set_defaults(func=
|
|
77
|
+
parser_printed.set_defaults(func=add_printed_from_args)
|
|
78
78
|
|
|
79
79
|
parser_shortcutreplacement = subparsers.add_parser(
|
|
80
80
|
"shortcut",
|
|
@@ -199,38 +199,7 @@ def set_levelname_from_args(args):
|
|
|
199
199
|
"""Set the levelname of one location schema."""
|
|
200
200
|
new_levelname = args.levelname
|
|
201
201
|
schema, inventory = get_schema_from_args(args)
|
|
202
|
-
set_levelname(
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
def set_levelname(
|
|
206
|
-
inventory: inventory_io.Inventory, schema: location.Schema, new_levelname: str
|
|
207
|
-
):
|
|
208
|
-
"""Set the levelname of one location schema.
|
|
209
|
-
|
|
210
|
-
Strip off whitespace.
|
|
211
|
-
|
|
212
|
-
Empty levelname raises ValueError if sub schemas exist.
|
|
213
|
-
Otherwise, it removes the possibility of this schema having subschemas.
|
|
214
|
-
|
|
215
|
-
Save the changes to disk.
|
|
216
|
-
|
|
217
|
-
Args:
|
|
218
|
-
inventory: inventory with schema and things (both needed)
|
|
219
|
-
schema: schema (level) to be changed
|
|
220
|
-
new_levelname: the new levelname
|
|
221
|
-
Raises:
|
|
222
|
-
ValueError: if the new levelname is empty or whitespace-only and sub schemas exist
|
|
223
|
-
"""
|
|
224
|
-
schema_name = "a default schema" if schema.is_default() else schema.name
|
|
225
|
-
new_levelname = new_levelname.strip()
|
|
226
|
-
try:
|
|
227
|
-
print(
|
|
228
|
-
f"Change level name of {schema_name} from {schema.levelname} to {new_levelname}."
|
|
229
|
-
)
|
|
230
|
-
except location.InvalidLocation:
|
|
231
|
-
print(f"Set level name of {schema_name} from nothing to {new_levelname}.")
|
|
232
|
-
schema.levelname = new_levelname
|
|
233
|
-
inventory.save()
|
|
202
|
+
inventory.set_levelname(schema, new_levelname)
|
|
234
203
|
|
|
235
204
|
|
|
236
205
|
def set_schema_name_from_args(args):
|
|
@@ -243,33 +212,7 @@ def set_schema_name_from_args(args):
|
|
|
243
212
|
ValueError: if new name is empty except for whitespace
|
|
244
213
|
"""
|
|
245
214
|
schema, inventory = get_schema_from_args(args)
|
|
246
|
-
set_schema_name(
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
def set_schema_name(
|
|
250
|
-
inventory: inventory_io.Inventory, schema: location.Schema, new_name: str
|
|
251
|
-
):
|
|
252
|
-
"""Set the name of a schema.
|
|
253
|
-
|
|
254
|
-
Fails on default schemas.
|
|
255
|
-
|
|
256
|
-
Args:
|
|
257
|
-
inventory: inventory with schema and things (both needed)
|
|
258
|
-
schema: schema (level) to be changed
|
|
259
|
-
new_name: new name of the schema. Is stripped of surrounding whitespace.
|
|
260
|
-
Raises:
|
|
261
|
-
ValueError: if new name is empty except for whitespace
|
|
262
|
-
"""
|
|
263
|
-
if schema.is_default():
|
|
264
|
-
raise ValueError(f"Cannot change name of default schema.")
|
|
265
|
-
if not new_name.strip():
|
|
266
|
-
raise ValueError(
|
|
267
|
-
f"The new name '{new_name}' is empty (or only whitespace). This is invalid."
|
|
268
|
-
)
|
|
269
|
-
new_name = new_name.strip()
|
|
270
|
-
print(f"debug: Change schema name from {schema.name} to {new_name}")
|
|
271
|
-
schema.name = new_name
|
|
272
|
-
inventory.save()
|
|
215
|
+
inventory.set_schema_name(schema, args.name)
|
|
273
216
|
|
|
274
217
|
|
|
275
218
|
def example_action(args):
|
|
@@ -337,14 +280,15 @@ def use_ids(args):
|
|
|
337
280
|
things.save()
|
|
338
281
|
|
|
339
282
|
|
|
340
|
-
def
|
|
341
|
-
"""Add to all things the attribute printed=True."""
|
|
283
|
+
def add_printed_from_args(args):
|
|
284
|
+
"""Add to all things that would be printed the attribute printed=True. Read invetory from files."""
|
|
285
|
+
add_printed(inventory_io.Inventory.from_json_files(directory=args.dataDirectory))
|
|
286
|
+
|
|
287
|
+
|
|
288
|
+
def add_printed(inventory: inventory_io.Inventory):
|
|
289
|
+
"""Add to all things that would be printed the attribute printed=True."""
|
|
342
290
|
things = (
|
|
343
|
-
labelprinter_typst.LabelPrinter()
|
|
344
|
-
.sign_things_to_be_printed(
|
|
345
|
-
inventory_io.Inventory.from_json_files(directory=args.dataDirectory)
|
|
346
|
-
)
|
|
347
|
-
.keys()
|
|
291
|
+
labelprinter_typst.LabelPrinter().sign_things_to_be_printed(inventory).keys()
|
|
348
292
|
)
|
|
349
293
|
for thing in things:
|
|
350
294
|
thing.sign["printed"] = True
|
|
@@ -22,7 +22,9 @@ from typing import Any, Iterable, Union, Iterator, cast, Callable
|
|
|
22
22
|
from . import constant
|
|
23
23
|
|
|
24
24
|
IMMUTABLE_TYPES = (str, int, float, bool, type(None))
|
|
25
|
-
Immutable = Union[
|
|
25
|
+
Immutable = Union[
|
|
26
|
+
str, int, float, bool, type(None)
|
|
27
|
+
] # *IMMUTABLE_TYPES was not accepted
|
|
26
28
|
Key = Union[str, tuple[str, str]]
|
|
27
29
|
"""Type of keys of DefaultedDict"""
|
|
28
30
|
Value = Union[Immutable, list[Immutable]]
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env python3
|
|
2
2
|
"""Create a list of things to hang in the place with all the stuff (e.g. a bike shed)."""
|
|
3
|
+
|
|
3
4
|
import importlib.resources
|
|
4
5
|
import json
|
|
5
6
|
|
|
@@ -9,11 +10,11 @@ import pathlib
|
|
|
9
10
|
import argparse
|
|
10
11
|
import os.path
|
|
11
12
|
import typst
|
|
12
|
-
from typing import cast, Union, Literal
|
|
13
|
+
from typing import cast, Union, Literal, TypeVar
|
|
13
14
|
import treelib
|
|
14
15
|
|
|
15
16
|
from .box import BoxedThing
|
|
16
|
-
from . import inventory_io, labelprinter_typst, thingtemplate_typst
|
|
17
|
+
from . import inventory_io, labelprinter_typst, thingtemplate_typst, constant
|
|
17
18
|
|
|
18
19
|
|
|
19
20
|
def add_arg_parsers(subparsers):
|
|
@@ -49,9 +50,22 @@ def add_arg_parsers(subparsers):
|
|
|
49
50
|
parser_single_label.set_defaults(func=generate_single_label_svg)
|
|
50
51
|
|
|
51
52
|
|
|
52
|
-
def get_thing_list_data(
|
|
53
|
+
def get_thing_list_data(
|
|
54
|
+
things: inventory_io.Inventory,
|
|
55
|
+
languages: list[str] | None = None,
|
|
56
|
+
alternatives: bool = True,
|
|
57
|
+
also_without_location: bool = False,
|
|
58
|
+
) -> dict[str, str]:
|
|
53
59
|
"""Get list[dict] representation of thing list.
|
|
54
60
|
|
|
61
|
+
Args:
|
|
62
|
+
things: inventory with listed things
|
|
63
|
+
languages: None for all languages, otherwise list of languages of thing names printed
|
|
64
|
+
Note that this option excludes things with missing names in some languages
|
|
65
|
+
alternatives: whether to list all alternative names.
|
|
66
|
+
Makes the list much longer but also more useful.
|
|
67
|
+
also_without_location: whether to include things that have no box.
|
|
68
|
+
This makes the list longer.
|
|
55
69
|
Returns:
|
|
56
70
|
list of dicts. Each dict has "name" and "id", most have "where",
|
|
57
71
|
many have "name_alt".
|
|
@@ -62,6 +76,18 @@ def get_thing_list_data(things: inventory_io.Inventory) -> dict[str, str]:
|
|
|
62
76
|
lines: dict[str, list[dict[str, str | None]]] = {}
|
|
63
77
|
|
|
64
78
|
def add_line(front_name: str, new_line: dict[str, str | None]):
|
|
79
|
+
"""Add a line to the lines dict.
|
|
80
|
+
|
|
81
|
+
Do not add the line if no "where" is contained in new_line and
|
|
82
|
+
also_without_location is False.
|
|
83
|
+
|
|
84
|
+
Args:
|
|
85
|
+
front_name: string to sort by: what the reader looks for
|
|
86
|
+
new_line: all data for this line on which the typst formatting
|
|
87
|
+
is building on
|
|
88
|
+
"""
|
|
89
|
+
if new_line["where"] is None and not also_without_location:
|
|
90
|
+
return
|
|
65
91
|
if "where" in new_line and not new_line["where"]:
|
|
66
92
|
del new_line["where"]
|
|
67
93
|
if front_name in lines:
|
|
@@ -69,10 +95,18 @@ def get_thing_list_data(things: inventory_io.Inventory) -> dict[str, str]:
|
|
|
69
95
|
else:
|
|
70
96
|
lines[front_name] = [new_line]
|
|
71
97
|
|
|
98
|
+
N = TypeVar("N")
|
|
99
|
+
|
|
100
|
+
def filter_language(name_dict: dict[str, N]) -> dict[str, N]:
|
|
101
|
+
"""Only include keys, values which are in languages."""
|
|
102
|
+
if languages is None:
|
|
103
|
+
return name_dict
|
|
104
|
+
return {key: value for key, value in name_dict.items() if key in languages}
|
|
105
|
+
|
|
72
106
|
for thing in things:
|
|
73
107
|
if thing.get("category", False):
|
|
74
108
|
continue
|
|
75
|
-
for name in thing.get("name", {}).values():
|
|
109
|
+
for name in filter_language(thing.get("name", {})).values():
|
|
76
110
|
add_line(
|
|
77
111
|
name,
|
|
78
112
|
{
|
|
@@ -81,7 +115,9 @@ def get_thing_list_data(things: inventory_io.Inventory) -> dict[str, str]:
|
|
|
81
115
|
"where": thing.where if thing.location else None,
|
|
82
116
|
},
|
|
83
117
|
)
|
|
84
|
-
|
|
118
|
+
if not alternatives:
|
|
119
|
+
continue
|
|
120
|
+
for lang, names_alt in filter_language(thing.get("name_alt", {})).items():
|
|
85
121
|
logging.debug("f{(lang, names_alt)=}")
|
|
86
122
|
for name_alt in names_alt:
|
|
87
123
|
add_line(
|
|
@@ -96,7 +132,7 @@ def get_thing_list_data(things: inventory_io.Inventory) -> dict[str, str]:
|
|
|
96
132
|
},
|
|
97
133
|
)
|
|
98
134
|
return {
|
|
99
|
-
"title": things.schema.name,
|
|
135
|
+
"title": str(things.schema.name),
|
|
100
136
|
"data": json.dumps(
|
|
101
137
|
[
|
|
102
138
|
line
|
|
@@ -218,11 +254,26 @@ def generate_labels(options: argparse.Namespace):
|
|
|
218
254
|
logging.info("Start creating tree view.")
|
|
219
255
|
treefile.write(get_tree(all_things))
|
|
220
256
|
|
|
221
|
-
logging.getLogger("generateLabels").info("Start creating thing
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
257
|
+
logging.getLogger("generateLabels").info("Start creating thing lists.")
|
|
258
|
+
list_path = options.output_dir / options.output_list
|
|
259
|
+
for language in [None] + all_things.options.languages:
|
|
260
|
+
for alternatives in [True, False]:
|
|
261
|
+
for without_location in [True, False]:
|
|
262
|
+
create_listpdf(
|
|
263
|
+
get_thing_list_data(
|
|
264
|
+
all_things,
|
|
265
|
+
languages=None if language is None else [language],
|
|
266
|
+
alternatives=alternatives,
|
|
267
|
+
also_without_location=without_location,
|
|
268
|
+
),
|
|
269
|
+
list_path.with_name(
|
|
270
|
+
options.output_list.stem
|
|
271
|
+
+ (f"_{language}" if language else "")
|
|
272
|
+
+ ("_onlyExisting" if not without_location else "")
|
|
273
|
+
+ ("_onlyPrimaryNames" if not alternatives else "")
|
|
274
|
+
+ options.output_list.suffix
|
|
275
|
+
),
|
|
276
|
+
)
|
|
226
277
|
|
|
227
278
|
logging.info("Start creating label pdf.")
|
|
228
279
|
labelprinter_typst.LabelPrinter().create_labels(
|
|
@@ -13,7 +13,7 @@ from typing import Callable, Sequence, Iterable, Optional, Self, Iterator, cast
|
|
|
13
13
|
|
|
14
14
|
from . import constant
|
|
15
15
|
from .box import BoxedThing
|
|
16
|
-
from .location import Schema
|
|
16
|
+
from .location import Schema, InvalidLocation
|
|
17
17
|
|
|
18
18
|
|
|
19
19
|
class Inventory(list[BoxedThing]):
|
|
@@ -238,6 +238,64 @@ class Inventory(list[BoxedThing]):
|
|
|
238
238
|
|
|
239
239
|
return supers.difference({thing})
|
|
240
240
|
|
|
241
|
+
def set_levelname(self, schema: Schema, new_levelname: str):
|
|
242
|
+
"""Set the levelname of one location schema.
|
|
243
|
+
|
|
244
|
+
Strip off whitespace.
|
|
245
|
+
|
|
246
|
+
Empty levelname raises ValueError if sub schemas exist.
|
|
247
|
+
Otherwise, it removes the possibility of this schema having subschemas.
|
|
248
|
+
|
|
249
|
+
Save the changes to disk.
|
|
250
|
+
|
|
251
|
+
This must be a method of the inventory, because all changed things must be saved afterwards
|
|
252
|
+
and the schema does not know which things are affected.
|
|
253
|
+
|
|
254
|
+
Args:
|
|
255
|
+
schema: schema (level) to be changed
|
|
256
|
+
new_levelname: the new levelname
|
|
257
|
+
Raises:
|
|
258
|
+
ValueError: if the new levelname is empty or whitespace-only and sub schemas exist
|
|
259
|
+
"""
|
|
260
|
+
schema_name = "a default schema" if schema.is_default() else schema.name
|
|
261
|
+
new_levelname = new_levelname.strip()
|
|
262
|
+
try:
|
|
263
|
+
print(
|
|
264
|
+
f"debug: Change level name of {schema_name} from {schema.levelname} to {new_levelname}."
|
|
265
|
+
)
|
|
266
|
+
except InvalidLocation:
|
|
267
|
+
print(
|
|
268
|
+
f"debug: Set level name of {schema_name} from nothing to {new_levelname}."
|
|
269
|
+
)
|
|
270
|
+
schema.levelname = new_levelname
|
|
271
|
+
self.save()
|
|
272
|
+
|
|
273
|
+
def set_schema_name(self, schema: Schema, new_name: str):
|
|
274
|
+
"""Set the name of a schema.
|
|
275
|
+
|
|
276
|
+
Fails on default schemas.
|
|
277
|
+
|
|
278
|
+
This must be a method of the inventory, because all changed things must be saved afterwards
|
|
279
|
+
and the schema does not know which things are affected.
|
|
280
|
+
|
|
281
|
+
Args:
|
|
282
|
+
inventory: inventory with schema and things (both needed)
|
|
283
|
+
schema: schema (level) to be changed
|
|
284
|
+
new_name: new name of the schema. Is stripped of surrounding whitespace.
|
|
285
|
+
Raises:
|
|
286
|
+
ValueError: if new name is empty except for whitespace
|
|
287
|
+
"""
|
|
288
|
+
if schema.is_default():
|
|
289
|
+
raise ValueError(f"Cannot change name of default schema.")
|
|
290
|
+
if not new_name.strip():
|
|
291
|
+
raise ValueError(
|
|
292
|
+
f"The new name '{new_name}' is empty (or only whitespace). This is invalid."
|
|
293
|
+
)
|
|
294
|
+
new_name = new_name.strip()
|
|
295
|
+
print(f"debug: Change schema name from {schema.name} to {new_name}")
|
|
296
|
+
schema.name = new_name
|
|
297
|
+
self.save()
|
|
298
|
+
|
|
241
299
|
|
|
242
300
|
def check_filename_types(filetypes: Sequence[str]) -> Callable[[str], pathlib.Path]:
|
|
243
301
|
"""Create function that checks for being a simple file.
|
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
#! /usr/bin/env python
|
|
2
2
|
"""Class sign that contains the info for a sign for a thing."""
|
|
3
|
+
|
|
3
4
|
import itertools
|
|
4
5
|
|
|
5
6
|
import logging
|
|
6
7
|
import os.path
|
|
7
8
|
|
|
8
9
|
import pathlib
|
|
9
|
-
import yaml
|
|
10
10
|
from typing import Optional, override
|
|
11
|
+
import yaml
|
|
11
12
|
|
|
12
13
|
from . import constant
|
|
13
14
|
from . import defaulted_data
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "flinventory"
|
|
3
|
-
version = "2.
|
|
3
|
+
version = "2.3.1"
|
|
4
4
|
description = "An inventory system for self-help repair shops"
|
|
5
5
|
authors = [
|
|
6
6
|
{ name = "flukx", email = "flinventory-flukx@612211124.xyz" },
|
|
@@ -60,3 +60,6 @@ include = [
|
|
|
60
60
|
{ path = "thingtemplate_typst" },
|
|
61
61
|
]
|
|
62
62
|
exclude = "tests"
|
|
63
|
+
|
|
64
|
+
[tool.mypy]
|
|
65
|
+
warn_unreachable = true
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{flinventory-2.2.4 → flinventory-2.3.1}/flinventory/thingtemplate_typst/out/bowdenzugklemmung1.svg
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|