flinventory 0.6.10__tar.gz → 0.6.12__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-0.6.10 → flinventory-0.6.12}/PKG-INFO +1 -1
- {flinventory-0.6.10 → flinventory-0.6.12}/flinventory/signprinter_latex.py +90 -35
- {flinventory-0.6.10 → flinventory-0.6.12}/pyproject.toml +1 -1
- {flinventory-0.6.10 → flinventory-0.6.12}/LICENSE +0 -0
- {flinventory-0.6.10 → flinventory-0.6.12}/README.md +0 -0
- {flinventory-0.6.10 → flinventory-0.6.12}/flinventory/__init__.py +0 -0
- {flinventory-0.6.10 → flinventory-0.6.12}/flinventory/__main__.py +0 -0
- {flinventory-0.6.10 → flinventory-0.6.12}/flinventory/box.py +0 -0
- {flinventory-0.6.10 → flinventory-0.6.12}/flinventory/constant.py +0 -0
- {flinventory-0.6.10 → flinventory-0.6.12}/flinventory/datacleanup.py +0 -0
- {flinventory-0.6.10 → flinventory-0.6.12}/flinventory/defaulted_data.py +0 -0
- {flinventory-0.6.10 → flinventory-0.6.12}/flinventory/generate_labels.py +0 -0
- {flinventory-0.6.10 → flinventory-0.6.12}/flinventory/inventory_io.py +0 -0
- {flinventory-0.6.10 → flinventory-0.6.12}/flinventory/location.py +0 -0
- {flinventory-0.6.10 → flinventory-0.6.12}/flinventory/sign.py +0 -0
- {flinventory-0.6.10 → flinventory-0.6.12}/flinventory/thing.py +0 -0
- {flinventory-0.6.10 → flinventory-0.6.12}/flinventory/thingtemplate_latex/.gitignore +0 -0
- {flinventory-0.6.10 → flinventory-0.6.12}/flinventory/thingtemplate_latex/dummyImage.jpg +0 -0
- {flinventory-0.6.10 → flinventory-0.6.12}/flinventory/thingtemplate_latex/sign.tex +0 -0
- {flinventory-0.6.10 → flinventory-0.6.12}/flinventory/thingtemplate_latex/signlist-footer.tex +0 -0
- {flinventory-0.6.10 → flinventory-0.6.12}/flinventory/thingtemplate_latex/signlist-header.tex +0 -0
- {flinventory-0.6.10 → flinventory-0.6.12}/flinventory/thingtemplate_latex/signs-example.tex +0 -0
- {flinventory-0.6.10 → flinventory-0.6.12}/tests/__init__.py +0 -0
- {flinventory-0.6.10 → flinventory-0.6.12}/tests/test_defaulted_data.py +0 -0
@@ -5,11 +5,12 @@ Todo:
|
|
5
5
|
rename font size to text scale. Because it is used to scale instead of setting
|
6
6
|
a font size. So the 'normal' is not 12 (pt) but 1.
|
7
7
|
"""
|
8
|
+
import argparse
|
8
9
|
import importlib.resources
|
9
10
|
import os.path
|
10
11
|
import logging
|
11
12
|
import subprocess
|
12
|
-
from typing import Union, Iterable, Optional
|
13
|
+
from typing import Union, Iterable, Optional, cast
|
13
14
|
|
14
15
|
from .box import BoxedThing
|
15
16
|
from .sign import Sign
|
@@ -89,12 +90,32 @@ def sanitize_latex_code(latex: Union[str, int, float]):
|
|
89
90
|
(">", "\\textgreater{}"),
|
90
91
|
("|", "\\textbar{}"),
|
91
92
|
]:
|
92
|
-
latex = latex.replace(orig, new)
|
93
|
+
latex = cast(str, latex).replace(orig, new)
|
93
94
|
except AttributeError:
|
94
95
|
pass
|
95
96
|
return latex
|
96
97
|
|
97
98
|
|
99
|
+
class LaTeXError(Exception):
|
100
|
+
"""Exception saying that LaTeX exited non-gracefully."""
|
101
|
+
|
102
|
+
def __init__(
|
103
|
+
self, message: str, call: list[str], input_file: str, return_code: int
|
104
|
+
):
|
105
|
+
"""Create LaTeXError.
|
106
|
+
|
107
|
+
Args:
|
108
|
+
message: general message as for every exception
|
109
|
+
call: LaTeX call sent to the console
|
110
|
+
input_file: tex file processed (probably included in call)
|
111
|
+
return_code: Return call of the LaTeX command, non-zero
|
112
|
+
"""
|
113
|
+
super().__init__(message)
|
114
|
+
self.call = call
|
115
|
+
self.input_file = input_file
|
116
|
+
self.return_code = return_code
|
117
|
+
|
118
|
+
|
98
119
|
class SignPrinterLaTeX:
|
99
120
|
# pylint: disable=too-many-instance-attributes
|
100
121
|
"""Class encapsulating algorithm for creating printable signs from thing list.
|
@@ -129,7 +150,11 @@ class SignPrinterLaTeX:
|
|
129
150
|
return file_contents
|
130
151
|
|
131
152
|
def controlled_length(
|
132
|
-
self,
|
153
|
+
self,
|
154
|
+
sign: Sign,
|
155
|
+
key: str,
|
156
|
+
backup: Union[int, float],
|
157
|
+
maximum: Union[int, float],
|
133
158
|
):
|
134
159
|
"""Get the value for the key if it exists and is a number and < max, otherwise backup."""
|
135
160
|
value = sign.get(key, backup)
|
@@ -147,8 +172,8 @@ class SignPrinterLaTeX:
|
|
147
172
|
)
|
148
173
|
return backup
|
149
174
|
if value == int(value):
|
150
|
-
return min(int(value),
|
151
|
-
return min(value,
|
175
|
+
return min(int(value), maximum)
|
176
|
+
return min(value, maximum)
|
152
177
|
|
153
178
|
def width(self, thing: BoxedThing) -> Union[int, float]:
|
154
179
|
"""Get the width of a sign, using backup and max size.
|
@@ -156,13 +181,13 @@ class SignPrinterLaTeX:
|
|
156
181
|
In UNIT.
|
157
182
|
"""
|
158
183
|
return self.controlled_length(
|
159
|
-
thing.sign, key="width", backup=STANDARD_WIDTH,
|
184
|
+
thing.sign, key="width", backup=STANDARD_WIDTH, maximum=MAX_WIDTH
|
160
185
|
)
|
161
186
|
|
162
187
|
def height(self, thing: BoxedThing) -> Union[int, float]:
|
163
188
|
"""Get the height of the sign of a boxed thing, using backup and max size."""
|
164
189
|
return self.controlled_length(
|
165
|
-
thing.sign, key="height", backup=STANDARD_HEIGHT,
|
190
|
+
thing.sign, key="height", backup=STANDARD_HEIGHT, maximum=MAX_HEIGHT
|
166
191
|
)
|
167
192
|
|
168
193
|
def image_height_vspace(
|
@@ -178,20 +203,19 @@ class SignPrinterLaTeX:
|
|
178
203
|
if sign_height < MINIMAL_HEIGHT_FOR_IMAGE:
|
179
204
|
return (
|
180
205
|
self.controlled_length(
|
181
|
-
thing.sign, key="imageheight", backup=0,
|
206
|
+
thing.sign, key="imageheight", backup=0, maximum=sign_height
|
182
207
|
),
|
183
208
|
r"-1.5\baselineskip",
|
184
209
|
)
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
)
|
210
|
+
return (
|
211
|
+
self.controlled_length(
|
212
|
+
thing.sign,
|
213
|
+
key="imageheight",
|
214
|
+
backup=sign_height * IMAGE_SHARE,
|
215
|
+
maximum=sign_height,
|
216
|
+
),
|
217
|
+
"1pt",
|
218
|
+
)
|
195
219
|
|
196
220
|
def if_use_landscape_template(self, thing: BoxedThing):
|
197
221
|
"""Return if we want to use the landscape template for this thing.
|
@@ -221,7 +245,6 @@ class SignPrinterLaTeX:
|
|
221
245
|
# return self.guess_font_size_landscape(thing)
|
222
246
|
return self.guess_font_size_portrait(thing)
|
223
247
|
|
224
|
-
@staticmethod
|
225
248
|
def guess_font_size_landscape(thing):
|
226
249
|
"""Guess good font sizes for the landscape template."""
|
227
250
|
assert False, "landscape latex signs are not supperted"
|
@@ -272,7 +295,12 @@ class SignPrinterLaTeX:
|
|
272
295
|
german_words = german.replace("-", "- ").split() or [" "]
|
273
296
|
english_words = english.replace("-", " ").split() or [" "]
|
274
297
|
# ignore cases with more than 2 lines, should be considered by hand
|
275
|
-
max_font_sizes
|
298
|
+
max_font_sizes: list[list[int | float]] = [
|
299
|
+
[0, 0, 0],
|
300
|
+
[0, 0, 0],
|
301
|
+
[0, 0, 0],
|
302
|
+
[0, 0, 0],
|
303
|
+
]
|
276
304
|
# there are 4 line number cases, see below in for loop
|
277
305
|
GERMAN_INDEX = 0 # pylint: disable=invalid-name
|
278
306
|
ENGLISH_INDEX = 1 # pylint: disable=invalid-name
|
@@ -411,7 +439,7 @@ class SignPrinterLaTeX:
|
|
411
439
|
content_latex.append(
|
412
440
|
""
|
413
441
|
) # empty line in code makes new line (= row) in pdf
|
414
|
-
current_line_filled_width = 0
|
442
|
+
current_line_filled_width = 0.0
|
415
443
|
content_latex.append(self.create_sign(thing))
|
416
444
|
current_line_filled_width += self.width(thing)
|
417
445
|
content_latex.append(self.post)
|
@@ -502,9 +530,9 @@ class SignPrinterLaTeX:
|
|
502
530
|
Arguments:
|
503
531
|
things: list of things to visualize
|
504
532
|
Returns:
|
505
|
-
path to created file.
|
533
|
+
path to created file.
|
506
534
|
"""
|
507
|
-
things.sort(key=
|
535
|
+
things.sort(key=self.height)
|
508
536
|
file_signs = os.path.join(self.output_dir, self.signs_file)
|
509
537
|
print(f"Print LaTeX file to {file_signs}.")
|
510
538
|
with open(file_signs, mode="w", encoding="UTF-8") as latex_file:
|
@@ -516,16 +544,28 @@ class SignPrinterLaTeX:
|
|
516
544
|
|
517
545
|
Raises:
|
518
546
|
ProgramMissingError: if no latexmk is available
|
547
|
+
LaTeXError: if LaTeX exited with non-zero return code
|
548
|
+
Returns:
|
549
|
+
path to created pdf file
|
519
550
|
"""
|
520
551
|
self.save_signs_latex(things)
|
552
|
+
latex: (
|
553
|
+
subprocess.CalledProcessError
|
554
|
+
| subprocess.CompletedProcess
|
555
|
+
| argparse.Namespace
|
556
|
+
)
|
521
557
|
try:
|
522
558
|
latex = subprocess.run(
|
523
559
|
LATEXMK_OPTIONS + [self.signs_file],
|
524
560
|
cwd=self.output_dir,
|
525
561
|
capture_output=True,
|
526
562
|
text=True,
|
563
|
+
check=True,
|
527
564
|
) # text=True makes output a str instead of bytes
|
528
565
|
except FileNotFoundError as program_missing:
|
566
|
+
latex = argparse.Namespace(
|
567
|
+
stdout="No LaTeX output.", stderr="LaTeX not found."
|
568
|
+
)
|
529
569
|
if program_missing.filename == LATEXMK_OPTIONS[0]:
|
530
570
|
raise constant.MissingProgramError(
|
531
571
|
LATEXMK_OPTIONS[0],
|
@@ -533,21 +573,36 @@ class SignPrinterLaTeX:
|
|
533
573
|
f"Program {LATEXMK_OPTIONS[0]} missing.",
|
534
574
|
program_missing.filename,
|
535
575
|
) from program_missing
|
536
|
-
|
537
|
-
|
538
|
-
|
539
|
-
|
540
|
-
) as stdout_file:
|
541
|
-
stdout_file.write(latex.stdout)
|
542
|
-
with open(
|
543
|
-
os.path.join(self.output_dir, AUX_DIR, "latex_error.txt"), mode="w"
|
544
|
-
) as stderr_file:
|
545
|
-
stderr_file.write(latex.stderr)
|
546
|
-
if latex.returncode != 0:
|
547
|
-
print(
|
576
|
+
raise program_missing
|
577
|
+
except subprocess.CalledProcessError as latex_error:
|
578
|
+
latex = latex_error # includes output, stderr
|
579
|
+
message = (
|
548
580
|
f"Latex finished with returncode {latex.returncode}."
|
549
581
|
f"Check in {os.path.join(self.output_dir, AUX_DIR)} for details."
|
550
582
|
)
|
583
|
+
print(message)
|
584
|
+
raise LaTeXError(
|
585
|
+
message,
|
586
|
+
call=latex_error.cmd,
|
587
|
+
input_file=self.signs_file,
|
588
|
+
return_code=latex_error.returncode,
|
589
|
+
) from latex_error
|
590
|
+
finally:
|
591
|
+
with open(
|
592
|
+
os.path.join(self.output_dir, AUX_DIR, "latex_output.txt"),
|
593
|
+
mode="w",
|
594
|
+
encoding="utf-8",
|
595
|
+
) as stdout_file:
|
596
|
+
stdout_file.write(latex.stdout)
|
597
|
+
with open(
|
598
|
+
os.path.join(self.output_dir, AUX_DIR, "latex_error.txt"),
|
599
|
+
mode="w",
|
600
|
+
encoding="utf-8",
|
601
|
+
) as stderr_file:
|
602
|
+
stderr_file.write(latex.stderr)
|
603
|
+
pdf_file = os.path.splitext(self.signs_file)[0] + ".pdf"
|
604
|
+
assert os.path.isfile(pdf_file)
|
605
|
+
return pdf_file
|
551
606
|
|
552
607
|
def create_sign_svg(self, thing: BoxedThing) -> Optional[str]:
|
553
608
|
"""Create a svg from a pdf with a sign for this thing.
|
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
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{flinventory-0.6.10 → flinventory-0.6.12}/flinventory/thingtemplate_latex/signlist-footer.tex
RENAMED
File without changes
|
{flinventory-0.6.10 → flinventory-0.6.12}/flinventory/thingtemplate_latex/signlist-header.tex
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|