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.
Files changed (24) hide show
  1. {flinventory-0.6.10 → flinventory-0.6.12}/PKG-INFO +1 -1
  2. {flinventory-0.6.10 → flinventory-0.6.12}/flinventory/signprinter_latex.py +90 -35
  3. {flinventory-0.6.10 → flinventory-0.6.12}/pyproject.toml +1 -1
  4. {flinventory-0.6.10 → flinventory-0.6.12}/LICENSE +0 -0
  5. {flinventory-0.6.10 → flinventory-0.6.12}/README.md +0 -0
  6. {flinventory-0.6.10 → flinventory-0.6.12}/flinventory/__init__.py +0 -0
  7. {flinventory-0.6.10 → flinventory-0.6.12}/flinventory/__main__.py +0 -0
  8. {flinventory-0.6.10 → flinventory-0.6.12}/flinventory/box.py +0 -0
  9. {flinventory-0.6.10 → flinventory-0.6.12}/flinventory/constant.py +0 -0
  10. {flinventory-0.6.10 → flinventory-0.6.12}/flinventory/datacleanup.py +0 -0
  11. {flinventory-0.6.10 → flinventory-0.6.12}/flinventory/defaulted_data.py +0 -0
  12. {flinventory-0.6.10 → flinventory-0.6.12}/flinventory/generate_labels.py +0 -0
  13. {flinventory-0.6.10 → flinventory-0.6.12}/flinventory/inventory_io.py +0 -0
  14. {flinventory-0.6.10 → flinventory-0.6.12}/flinventory/location.py +0 -0
  15. {flinventory-0.6.10 → flinventory-0.6.12}/flinventory/sign.py +0 -0
  16. {flinventory-0.6.10 → flinventory-0.6.12}/flinventory/thing.py +0 -0
  17. {flinventory-0.6.10 → flinventory-0.6.12}/flinventory/thingtemplate_latex/.gitignore +0 -0
  18. {flinventory-0.6.10 → flinventory-0.6.12}/flinventory/thingtemplate_latex/dummyImage.jpg +0 -0
  19. {flinventory-0.6.10 → flinventory-0.6.12}/flinventory/thingtemplate_latex/sign.tex +0 -0
  20. {flinventory-0.6.10 → flinventory-0.6.12}/flinventory/thingtemplate_latex/signlist-footer.tex +0 -0
  21. {flinventory-0.6.10 → flinventory-0.6.12}/flinventory/thingtemplate_latex/signlist-header.tex +0 -0
  22. {flinventory-0.6.10 → flinventory-0.6.12}/flinventory/thingtemplate_latex/signs-example.tex +0 -0
  23. {flinventory-0.6.10 → flinventory-0.6.12}/tests/__init__.py +0 -0
  24. {flinventory-0.6.10 → flinventory-0.6.12}/tests/test_defaulted_data.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: flinventory
3
- Version: 0.6.10
3
+ Version: 0.6.12
4
4
  Summary: An inventory system for self-help repair shops
5
5
  Author-Email: flukx <flinventory-flukx@612211124.xyz>
6
6
  License: GPL3
@@ -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, sign: Sign, key: str, backup: Union[int, float], max: Union[int, float]
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), max)
151
- return min(value, max)
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, max=MAX_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, max=MAX_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, max=sign_height
206
+ thing.sign, key="imageheight", backup=0, maximum=sign_height
182
207
  ),
183
208
  r"-1.5\baselineskip",
184
209
  )
185
- else:
186
- return (
187
- self.controlled_length(
188
- thing.sign,
189
- key="imageheight",
190
- backup=sign_height * IMAGE_SHARE,
191
- max=sign_height,
192
- ),
193
- "1pt",
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 = [[0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0]]
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. None in case of error.
533
+ path to created file.
506
534
  """
507
- things.sort(key=lambda t: self.height(t))
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
- else:
537
- raise program_missing
538
- with open(
539
- os.path.join(self.output_dir, AUX_DIR, "latex_output.txt"), mode="w"
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.
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "flinventory"
3
- version = "0.6.10"
3
+ version = "0.6.12"
4
4
  description = "An inventory system for self-help repair shops"
5
5
  authors = [
6
6
  { name = "flukx", email = "flinventory-flukx@612211124.xyz" },
File without changes
File without changes