flinventory 0.5.1__tar.gz → 0.6.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.
Files changed (24) hide show
  1. {flinventory-0.5.1 → flinventory-0.6.1}/PKG-INFO +1 -1
  2. {flinventory-0.5.1 → flinventory-0.6.1}/flinventory/generate_labels.py +56 -4
  3. {flinventory-0.5.1 → flinventory-0.6.1}/flinventory/location.py +2 -2
  4. {flinventory-0.5.1 → flinventory-0.6.1}/flinventory/signprinter_latex.py +167 -56
  5. {flinventory-0.5.1 → flinventory-0.6.1}/pyproject.toml +1 -1
  6. {flinventory-0.5.1 → flinventory-0.6.1}/LICENSE +0 -0
  7. {flinventory-0.5.1 → flinventory-0.6.1}/README.md +0 -0
  8. {flinventory-0.5.1 → flinventory-0.6.1}/flinventory/__init__.py +0 -0
  9. {flinventory-0.5.1 → flinventory-0.6.1}/flinventory/__main__.py +0 -0
  10. {flinventory-0.5.1 → flinventory-0.6.1}/flinventory/box.py +0 -0
  11. {flinventory-0.5.1 → flinventory-0.6.1}/flinventory/constant.py +0 -0
  12. {flinventory-0.5.1 → flinventory-0.6.1}/flinventory/datacleanup.py +0 -0
  13. {flinventory-0.5.1 → flinventory-0.6.1}/flinventory/defaulted_data.py +0 -0
  14. {flinventory-0.5.1 → flinventory-0.6.1}/flinventory/inventory_io.py +0 -0
  15. {flinventory-0.5.1 → flinventory-0.6.1}/flinventory/sign.py +0 -0
  16. {flinventory-0.5.1 → flinventory-0.6.1}/flinventory/thing.py +0 -0
  17. {flinventory-0.5.1 → flinventory-0.6.1}/flinventory/thingtemplate_latex/.gitignore +0 -0
  18. {flinventory-0.5.1 → flinventory-0.6.1}/flinventory/thingtemplate_latex/dummyImage.jpg +0 -0
  19. {flinventory-0.5.1 → flinventory-0.6.1}/flinventory/thingtemplate_latex/sign.tex +0 -0
  20. {flinventory-0.5.1 → flinventory-0.6.1}/flinventory/thingtemplate_latex/signlist-footer.tex +0 -0
  21. {flinventory-0.5.1 → flinventory-0.6.1}/flinventory/thingtemplate_latex/signlist-header.tex +0 -0
  22. {flinventory-0.5.1 → flinventory-0.6.1}/flinventory/thingtemplate_latex/signs-example.tex +0 -0
  23. {flinventory-0.5.1 → flinventory-0.6.1}/tests/__init__.py +0 -0
  24. {flinventory-0.5.1 → flinventory-0.6.1}/tests/test_defaulted_data.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: flinventory
3
- Version: 0.5.1
3
+ Version: 0.6.1
4
4
  Summary: An inventory system for self-help repair shops
5
5
  Author-Email: flukx <flinventory-flukx@612211124.xyz>
6
6
  License: GPL3
@@ -1,6 +1,7 @@
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
  import logging
4
+
4
5
  import pypandoc
5
6
 
6
7
  import argparse
@@ -70,6 +71,16 @@ def add_arg_parsers(subparsers):
70
71
 
71
72
  parser.set_defaults(func=generate_labels)
72
73
 
74
+ parser_single_sign = subparsers.add_parser(
75
+ "single_sign", description="Create a single sign as svg."
76
+ )
77
+ parser_single_sign.add_argument(
78
+ "thing_id",
79
+ help="Thing id of the thing the sign is for. "
80
+ "This is the directory name of the thing.",
81
+ )
82
+ parser_single_sign.set_defaults(func=generate_single_sign_svg)
83
+
73
84
 
74
85
  def get_markdown_list(things):
75
86
  """Get markdown representation of thing list."""
@@ -165,10 +176,7 @@ def generate_labels(options: argparse.Namespace):
165
176
  Args:
166
177
  options: command line options given
167
178
  """
168
- try:
169
- os.mkdir(options.output_dir)
170
- except FileExistsError:
171
- pass # everything fine
179
+ os.makedirs(options.output_dir, exist_ok=True)
172
180
  logging.basicConfig(
173
181
  filename=os.path.join(options.output_dir, options.logfile),
174
182
  level=logging.DEBUG,
@@ -212,3 +220,47 @@ def generate_labels(options: argparse.Namespace):
212
220
  sign_printer_latex.create_signs_pdf(all_things)
213
221
  else:
214
222
  sign_printer_latex.save_signs_latex(all_things)
223
+
224
+
225
+ def generate_single_sign_svg(options: argparse.Namespace):
226
+ """Generate sign for a single thing, given by options.thing_id.
227
+
228
+ Args:
229
+ options: command line options given
230
+ """
231
+ logging.basicConfig(
232
+ filename=os.path.join(options.output_dir, options.logfile),
233
+ level=logging.DEBUG,
234
+ filemode="w",
235
+ )
236
+ logging.info("Create thing sign")
237
+ all_things = inventory_io.Inventory.from_json_files(options.dataDirectory)
238
+ logging.info("Start creating sign svg.")
239
+ try:
240
+ thing = all_things.get_by_id(options.thing_id)
241
+ except KeyError as id_not_found:
242
+ print("key error:")
243
+ print(id_not_found)
244
+ possible_things = list(all_things.get_by_best("name", options.thing_id))
245
+ if len(possible_things) == 1:
246
+ thing = possible_things[0]
247
+ else:
248
+ error_message = (
249
+ f"No thing with the id {options.thing_id} and 0 or >1 thing "
250
+ f"with this name. Do not do anything."
251
+ )
252
+ logging.error(error_message)
253
+ print(error_message)
254
+ return
255
+ sign_printer_latex = SignPrinterLaTeX(options)
256
+ svg_path = sign_printer_latex.create_sign_svg(thing)
257
+ if svg_path:
258
+ print(
259
+ f"sign svg created for {thing.best('name', backup="?")} "
260
+ f"({options.thing_id}): find it at {svg_path}"
261
+ )
262
+ else:
263
+ print(
264
+ f"Error at creating sign for {thing.best('name', backup="?")} "
265
+ f"({options.thing_id})."
266
+ )
@@ -283,7 +283,7 @@ class Location(dict[str, Value]):
283
283
  options: global options including the seperator
284
284
  """
285
285
 
286
- EMPTY = [None, "", [], {}]
286
+ EMPTY: list[Any] = [None, "", [], {}]
287
287
  """Values that are considered empty and mean that nothing should be saved."""
288
288
 
289
289
  def __init__(
@@ -409,7 +409,7 @@ class Location(dict[str, Value]):
409
409
  Sorts by schema hierarchy.
410
410
  """
411
411
  self._levels = self.schema.get_schema_hierarchy(self)
412
- as_dict = {
412
+ as_dict: dict[str, Value] = {
413
413
  level.levelname: self._levels[index + 1].name
414
414
  for index, level in list(enumerate(self._levels))[:-1]
415
415
  }
@@ -9,7 +9,7 @@ import importlib.resources
9
9
  import os.path
10
10
  import logging
11
11
  import subprocess
12
- from typing import Union, Iterable
12
+ from typing import Union, Iterable, Optional
13
13
 
14
14
  from .box import BoxedThing
15
15
  from .sign import Sign
@@ -18,7 +18,7 @@ from . import thingtemplate_latex
18
18
 
19
19
  TEMPLATE_PACKAGE = thingtemplate_latex
20
20
  TEMPLATE_PRE = "signlist-header.tex"
21
- #importlib.resources.read_text("flinventory", "signlist-header.tex"))
21
+ # importlib.resources.read_text("flinventory", "signlist-header.tex"))
22
22
  TEMPLATE_POST = "signlist-footer.tex"
23
23
  TEMPLATE_SIGN = "sign.tex"
24
24
  DUMMY_IMAGE = "dummyImage.jpg"
@@ -59,6 +59,7 @@ MAX_WIDTH = 18 # otherwise too wide for A4 page
59
59
  MAX_HEIGHT = 28 # otherwise too long for A4 page
60
60
  # maximum height for a sign [cm]
61
61
 
62
+
62
63
  def sanitize_latex_code(latex: Union[str, int, float]):
63
64
  """Make a string insertable into LaTeX code.
64
65
 
@@ -99,6 +100,7 @@ class SignPrinterLaTeX:
99
100
  # pylint: disable-next=unbalanced-tuple-unpacking
100
101
  self.pre, self.sign, self.post = self._read_templates()
101
102
  self.output_dir = paths.output_dir
103
+ os.makedirs(self.output_dir, exist_ok=True)
102
104
  self.signs_file = paths.output_signs_latex
103
105
  self.logger = logging.getLogger(__name__)
104
106
 
@@ -113,11 +115,14 @@ class SignPrinterLaTeX:
113
115
  # todo remove function by using importlib, which gives directly the text
114
116
  file_contents = []
115
117
  for filename in [TEMPLATE_PRE, TEMPLATE_SIGN, TEMPLATE_POST]:
116
- file_contents.append(importlib.resources.read_text(TEMPLATE_PACKAGE, filename))
118
+ file_contents.append(
119
+ importlib.resources.read_text(TEMPLATE_PACKAGE, filename)
120
+ )
117
121
  return file_contents
118
122
 
119
- def controlled_length(self, sign:Sign, key: str, backup: Union[int, float],
120
- max: Union[int, float]):
123
+ def controlled_length(
124
+ self, sign: Sign, key: str, backup: Union[int, float], max: Union[int, float]
125
+ ):
121
126
  """Get the value for the key if it exists and is a number and < max, otherwise backup."""
122
127
  value = sign.get(key, backup)
123
128
  try:
@@ -126,8 +131,10 @@ class SignPrinterLaTeX:
126
131
  self.logger(f"{key} {value} is not a number. Use {backup} {UNIT} instead.")
127
132
  return backup
128
133
  if value <= 0:
129
- self.logger(f"{key} {value} is non-positive and therefore not a valid sign {key}. "
130
- f"Use {backup} {UNIT} instead.")
134
+ self.logger(
135
+ f"{key} {value} is non-positive and therefore not a valid sign {key}. "
136
+ f"Use {backup} {UNIT} instead."
137
+ )
131
138
  return backup
132
139
  if value == int(value):
133
140
  return min(int(value), max)
@@ -138,11 +145,15 @@ class SignPrinterLaTeX:
138
145
 
139
146
  In UNIT.
140
147
  """
141
- return self.controlled_length(thing.sign, key='width', backup=STANDARD_WIDTH, max=MAX_WIDTH)
148
+ return self.controlled_length(
149
+ thing.sign, key="width", backup=STANDARD_WIDTH, max=MAX_WIDTH
150
+ )
142
151
 
143
152
  def height(self, thing: BoxedThing) -> Union[int, float]:
144
153
  """Get the height of the sign of a boxed thing, using backup and max size."""
145
- return self.controlled_length(thing.sign, key='height', backup=STANDARD_HEIGHT, max=MAX_HEIGHT)
154
+ return self.controlled_length(
155
+ thing.sign, key="height", backup=STANDARD_HEIGHT, max=MAX_HEIGHT
156
+ )
146
157
 
147
158
  def if_use_landscape_template(self, thing: BoxedThing):
148
159
  """Return if we want to use the landscape template for this thing.
@@ -152,7 +163,7 @@ class SignPrinterLaTeX:
152
163
  than high.
153
164
  """
154
165
  try:
155
- return thing.sign.get('landscape')
166
+ return thing.sign.get("landscape")
156
167
  except KeyError:
157
168
  try:
158
169
  return self.width(thing) >= self.width(thing) * LANDSCAPE_MIN_RATIO
@@ -180,11 +191,11 @@ class SignPrinterLaTeX:
180
191
  width = self.width(thing)
181
192
  height = self.height(thing)
182
193
  used_width = width - height # that is approximately the part the image uses
183
- german = thing.sign.get(('name', 0), '')
184
- english = thing.sign.get(('name', 1), '')
194
+ german = thing.sign.get(("name", 0), "")
195
+ english = thing.sign.get(("name", 1), "")
185
196
  german_expected_width_at_standard = len(german) * STANDARD_LETTER_LENGTH
186
197
  german_max_by_width = (
187
- STANDARD_FONT_SIZE_GERMAN * used_width / german_expected_width_at_standard
198
+ STANDARD_FONT_SIZE_GERMAN * used_width / german_expected_width_at_standard
188
199
  )
189
200
  german_max_by_height = (
190
201
  height
@@ -193,10 +204,10 @@ class SignPrinterLaTeX:
193
204
  * GERMAN_TO_ENGLISH_SHARE
194
205
  )
195
206
  english_expected_width_at_standard = (
196
- len(english)
197
- * STANDARD_LETTER_LENGTH
198
- * STANDARD_FONTSIZE_ENGLISH
199
- / STANDARD_FONT_SIZE_GERMAN
207
+ len(english)
208
+ * STANDARD_LETTER_LENGTH
209
+ * STANDARD_FONTSIZE_ENGLISH
210
+ / STANDARD_FONT_SIZE_GERMAN
200
211
  )
201
212
  english_max_by_width = (
202
213
  STANDARD_FONTSIZE_ENGLISH * used_width / english_expected_width_at_standard
@@ -218,8 +229,8 @@ class SignPrinterLaTeX:
218
229
  """
219
230
  # use german and english as aliases for primary and secondary language
220
231
  # because it's easier to read
221
- german = thing.get(('name', 0), '')
222
- english = thing.get(('name', 1), '')
232
+ german = thing.get(("name", 0), "")
233
+ english = thing.get(("name", 1), "")
223
234
  german_words = german.replace("-", "- ").split() or [" "]
224
235
  english_words = english.replace("-", " ").split() or [" "]
225
236
  # ignore cases with more than 2 lines, should be considered by hand
@@ -257,23 +268,23 @@ class SignPrinterLaTeX:
257
268
  )
258
269
  german_expected_width_at_standard = german_length * STANDARD_LETTER_LENGTH
259
270
  german_max_by_width = (
260
- STANDARD_FONT_SIZE_GERMAN * width / german_expected_width_at_standard
271
+ STANDARD_FONT_SIZE_GERMAN * width / german_expected_width_at_standard
261
272
  )
262
273
  text_height = height * (
263
274
  1 if height < MINIMAL_HEIGHT_FOR_IMAGE else IMAGE_SHARE
264
275
  )
265
276
  german_max_by_height = (
266
- STANDARD_FONT_SIZE_GERMAN
267
- * text_height
268
- / STANDARD_LETTER_HEIGHT
269
- / (german_number_lines * GERMAN_TO_ENGLISH_SHARE + english_number_lines)
270
- * GERMAN_TO_ENGLISH_SHARE
277
+ STANDARD_FONT_SIZE_GERMAN
278
+ * text_height
279
+ / STANDARD_LETTER_HEIGHT
280
+ / (german_number_lines * GERMAN_TO_ENGLISH_SHARE + english_number_lines)
281
+ * GERMAN_TO_ENGLISH_SHARE
271
282
  )
272
283
  english_expected_width_at_standard = (
273
- english_length
274
- * STANDARD_LETTER_LENGTH
275
- * STANDARD_FONTSIZE_ENGLISH
276
- / STANDARD_FONT_SIZE_GERMAN
284
+ english_length
285
+ * STANDARD_LETTER_LENGTH
286
+ * STANDARD_FONTSIZE_ENGLISH
287
+ / STANDARD_FONT_SIZE_GERMAN
277
288
  )
278
289
  # in factor size compared to normal size
279
290
  english_max_by_width = (
@@ -324,19 +335,34 @@ class SignPrinterLaTeX:
324
335
  Returns:
325
336
  (german font size, english font size)
326
337
  """
327
- default_german_font_size, default_english_font_size = self.guess_font_size(thing)
328
- german_font_size = thing.sign.get(('fontsize', 0), default_german_font_size)
329
- english_font_size = thing.sign.get(('fontsize', 1), default_english_font_size)
338
+ default_german_font_size, default_english_font_size = self.guess_font_size(
339
+ thing
340
+ )
341
+ german_font_size = thing.sign.get(("fontsize", 0), default_german_font_size)
342
+ english_font_size = thing.sign.get(("fontsize", 1), default_english_font_size)
330
343
  logging.info(
331
344
  f"{thing.best('name')} font factor: (de) {german_font_size} (en) {english_font_size}"
332
345
  )
333
346
  return german_font_size, english_font_size
334
347
 
335
- def create_latex(self, things: Iterable[BoxedThing]):
348
+ def create_latex_single_sign(self, thing: BoxedThing) -> str:
349
+ """Create latex code (as str) that shows one sign in a minimal document."""
350
+ return "\n".join(
351
+ (
352
+ r"\documentclass{standalone}",
353
+ *(self.pre.splitlines()[2:]),
354
+ self.create_sign(thing),
355
+ self.post,
356
+ )
357
+ )
358
+
359
+ def create_latex(self, things: Iterable[BoxedThing]) -> str:
336
360
  """Create latex code (as str) that shows all signs.
337
361
 
338
362
  Arguments:
339
363
  things: list of things to be described
364
+ Return:
365
+ latex code with document with all signs that should be printed
340
366
  """
341
367
  content_latex = [self.pre]
342
368
  current_line_filled_width = 0
@@ -367,8 +393,8 @@ class SignPrinterLaTeX:
367
393
  imageheight
368
394
  location
369
395
  """
370
- german = thing.sign.get(('name', 0), '')
371
- english = thing.sign.get(('name', 1), '')
396
+ german = thing.sign.get(("name", 0), "")
397
+ english = thing.sign.get(("name", 1), "")
372
398
 
373
399
  width = self.width(thing)
374
400
  height = self.height(thing)
@@ -382,9 +408,7 @@ class SignPrinterLaTeX:
382
408
  }
383
409
 
384
410
  if not insertions["location"]: # empty string
385
- logging.warning(
386
- f"Print sign for {german} ({english}) without location."
387
- )
411
+ logging.warning(f"Print sign for {german} ({english}) without location.")
388
412
 
389
413
  # todo: make image height configurable
390
414
  if height < MINIMAL_HEIGHT_FOR_IMAGE:
@@ -397,10 +421,7 @@ class SignPrinterLaTeX:
397
421
  # at first only portrait sign, landscape sign can be implemented later
398
422
  # if self.if_use_landscape_template(thing): # would need different condition
399
423
  if image_path := thing.thing.image_path(): # not None or ""
400
- rel_path_to_image = os.path.relpath(
401
- image_path,
402
- self.output_dir
403
- )
424
+ rel_path_to_image = os.path.relpath(image_path, self.output_dir)
404
425
  insertions["imagepath"] = rel_path_to_image
405
426
  else:
406
427
  if insertions["imageheight"] > 0:
@@ -414,15 +435,18 @@ class SignPrinterLaTeX:
414
435
  except FileExistsError:
415
436
  pass
416
437
  else:
417
- dummy_image = importlib.resources.read_binary(TEMPLATE_PACKAGE, DUMMY_IMAGE)
438
+ dummy_image = importlib.resources.read_binary(
439
+ TEMPLATE_PACKAGE, DUMMY_IMAGE
440
+ )
418
441
  with image_file:
419
442
  image_file.write(dummy_image)
420
443
  font_sizes = self.get_font_size(thing)
421
444
  insertions["textscalePrimary"] = font_sizes[0] # /12
422
445
  insertions["textscaleSecondary"] = font_sizes[1] # /12
423
446
 
424
- insertions["locationShiftDown"] = thing.sign.get('location_shift_down',
425
- STANDARD_LOCATION_SHIFT_DOWN)
447
+ insertions["locationShiftDown"] = thing.sign.get(
448
+ "location_shift_down", STANDARD_LOCATION_SHIFT_DOWN
449
+ )
426
450
  return insertions
427
451
 
428
452
  def create_sign(self, thing):
@@ -444,7 +468,7 @@ class SignPrinterLaTeX:
444
468
  Arguments:
445
469
  things: list of things to visualize
446
470
  Returns:
447
- path to created file
471
+ path to created file. None in case of error.
448
472
  """
449
473
  things.sort(key=lambda t: self.height(t))
450
474
  file_signs = os.path.join(self.output_dir, self.signs_file)
@@ -456,16 +480,103 @@ class SignPrinterLaTeX:
456
480
  def create_signs_pdf(self, things: list[BoxedThing]):
457
481
  """Create a pdf and latex files with signs."""
458
482
  self.save_signs_latex(things)
459
- latex = subprocess.run(['latexmk', self.signs_file,
460
- f'-aux-directory={AUX_DIR}',
461
- "-pdf"],
462
- cwd=self.output_dir,
463
- capture_output=True,
464
- text=True) # text=True makes output a str instead of bytes
465
- with open(os.path.join(self.output_dir, AUX_DIR, 'latex_output.txt'), mode="w") as stdout_file:
483
+ latex = subprocess.run(
484
+ ["latexmk", self.signs_file, f"-aux-directory={AUX_DIR}", "-pdf"],
485
+ cwd=self.output_dir,
486
+ capture_output=True,
487
+ text=True,
488
+ ) # text=True makes output a str instead of bytes
489
+ with open(
490
+ os.path.join(self.output_dir, AUX_DIR, "latex_output.txt"), mode="w"
491
+ ) as stdout_file:
492
+ stdout_file.write(latex.stdout)
493
+ with open(
494
+ os.path.join(self.output_dir, AUX_DIR, "latex_error.txt"), mode="w"
495
+ ) as stderr_file:
496
+ stderr_file.write(latex.stderr)
497
+ if latex.returncode != 0:
498
+ print(
499
+ f"Latex finished with returncode {latex.returncode}."
500
+ f"Check in {os.path.join(self.output_dir, AUX_DIR)} for details."
501
+ )
502
+
503
+ def create_sign_svg(self, thing: BoxedThing) -> Optional[str]:
504
+ """Create a svg from a pdf with a sign for this thing.
505
+
506
+ Args:
507
+ thing: the thing which sign should be created
508
+ Returns:
509
+ path of the created svg file. None if error
510
+ """
511
+ tex = self.create_latex_single_sign(thing)
512
+ tex_hash = str(abs(hash(tex)))
513
+ file_tex = tex_hash + ".tex"
514
+ path_tex = os.path.join(self.output_dir, tex_hash + ".tex")
515
+ file_pdf = tex_hash + ".pdf"
516
+ path_pdf = os.path.join(self.output_dir, file_pdf)
517
+ file_svg = tex_hash + ".svg"
518
+ path_svg = os.path.join(self.output_dir, file_svg)
519
+ if os.path.isfile(path_tex) and os.path.isfile(path_svg):
520
+ self.logger(f"Do not regenerate {tex_hash}.")
521
+ return file_svg
522
+ with open(path_tex, mode="w") as file_tex_f:
523
+ file_tex_f.write(tex)
524
+ latex = subprocess.run(
525
+ ["latexmk", file_tex, f"-aux-directory={AUX_DIR}", "-pdf"],
526
+ cwd=self.output_dir,
527
+ capture_output=True,
528
+ text=True,
529
+ ) # text=True makes output a str instead of bytes
530
+ with open(
531
+ os.path.join(self.output_dir, AUX_DIR, f"latex_output_{tex_hash}.txt"),
532
+ mode="w",
533
+ ) as stdout_file:
466
534
  stdout_file.write(latex.stdout)
467
- with open(os.path.join(self.output_dir, AUX_DIR, 'latex_error.txt'), mode="w") as stderr_file:
535
+ with open(
536
+ os.path.join(self.output_dir, AUX_DIR, f"latex_error.{tex_hash}.txt"),
537
+ mode="w",
538
+ ) as stderr_file:
468
539
  stderr_file.write(latex.stderr)
469
540
  if latex.returncode != 0:
470
- print(f"Latex finished with returncode {latex.returncode}."
471
- f"Check in {os.path.join(self.output_dir, AUX_DIR)} for details.")
541
+ error_message = (
542
+ f"Latex for {thing.best('name', backup=tex_hash)} "
543
+ f"finished with returncode {latex.returncode}."
544
+ f"Check in {os.path.join(self.output_dir, AUX_DIR)} ({tex_hash}) for details."
545
+ )
546
+ self.logger.error(error_message)
547
+ print(error_message)
548
+ return None
549
+ svg = subprocess.run(
550
+ ["pdf2svg", path_pdf, path_svg],
551
+ capture_output=True,
552
+ text=True,
553
+ ) # text=True makes output a str instead of bytes
554
+ with open(
555
+ os.path.join(self.output_dir, AUX_DIR, f"svg_output_{tex_hash}.txt"),
556
+ mode="w",
557
+ ) as stdout_file:
558
+ stdout_file.write(svg.stdout)
559
+ with open(
560
+ os.path.join(self.output_dir, AUX_DIR, f"svg_error.{tex_hash}.txt"),
561
+ mode="w",
562
+ ) as stderr_file:
563
+ stderr_file.write(svg.stderr)
564
+ if svg.returncode != 0:
565
+ error_message = (
566
+ f"svg for {thing.best('name', backup=tex_hash)} "
567
+ f"finished with returncode {svg.returncode}."
568
+ f"Check in {os.path.join(self.output_dir, tex_hash)}* for details."
569
+ )
570
+ self.logger.error(error_message)
571
+ print(error_message)
572
+ return None
573
+ if os.path.isfile(path_svg):
574
+ return path_svg
575
+ error_message = (
576
+ f"svg for {thing.best('name', backup=tex_hash)} "
577
+ f"finished with returncode 0 but the svg was not created. "
578
+ f"Check in {os.path.join(self.output_dir, tex_hash)}* for details."
579
+ )
580
+ self.logger.error(error_message)
581
+ print(error_message)
582
+ return None
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "flinventory"
3
- version = "0.5.1"
3
+ version = "0.6.1"
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