otlmow-template 1.7__py3-none-any.whl → 1.10__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.
@@ -20,8 +20,6 @@ from openpyxl.worksheet.worksheet import Worksheet
20
20
  from otlmow_converter.DotnotationHelper import DotnotationHelper
21
21
  from otlmow_converter.Exceptions.UnknownExcelError import UnknownExcelError
22
22
  from otlmow_converter.OtlmowConverter import OtlmowConverter
23
- from otlmow_model.OtlmowModel.BaseClasses.BooleanField import BooleanField
24
- from otlmow_model.OtlmowModel.BaseClasses.KeuzelijstField import KeuzelijstField
25
23
  from otlmow_model.OtlmowModel.BaseClasses.OTLObject import dynamic_create_instance_from_uri, OTLObject, \
26
24
  get_attribute_by_name, dynamic_create_type_from_uri
27
25
  from otlmow_model.OtlmowModel.Helpers.GenericHelper import get_ns_and_name_from_uri
@@ -96,6 +94,11 @@ class SubsetTemplateCreator:
96
94
  add_geometry=add_geometry, filter_attributes_by_subset=filter_attributes_by_subset,
97
95
  dummy_data_rows=dummy_data_rows, model_directory=model_directory)
98
96
 
97
+ abbreviate_excel_after = False
98
+ if kwargs.get('abbreviate_excel_sheettitles') == True:
99
+ kwargs['abbreviate_excel_sheettitles'] = False
100
+ abbreviate_excel_after = True
101
+
99
102
  # write the file
100
103
  await OtlmowConverter.from_objects_to_file_async(
101
104
  file_path=template_file_path, sequence_of_objects=objects, split_per_type=split_per_type, **kwargs)
@@ -105,7 +108,8 @@ class SubsetTemplateCreator:
105
108
  if extension == '.xlsx':
106
109
  await cls.alter_excel_template_async(
107
110
  generate_choice_list=generate_choice_list, file_path=template_file_path, dummy_data_rows=dummy_data_rows,
108
- instances=objects, add_deprecated=add_deprecated, add_attribute_info=add_attribute_info)
111
+ instances=objects, add_deprecated=add_deprecated, add_attribute_info=add_attribute_info,
112
+ abbreviate_excel_sheettitles=abbreviate_excel_after)
109
113
 
110
114
  elif extension == '.csv':
111
115
  await cls.alter_csv_template_async(
@@ -151,6 +155,11 @@ class SubsetTemplateCreator:
151
155
  add_geometry=add_geometry, filter_attributes_by_subset=filter_attributes_by_subset,
152
156
  dummy_data_rows=dummy_data_rows, model_directory=model_directory)
153
157
 
158
+ abbreviate_excel_after = False
159
+ if kwargs.get('abbreviate_excel_sheettitles') == True:
160
+ kwargs['abbreviate_excel_sheettitles'] = False
161
+ abbreviate_excel_after = True
162
+
154
163
  # write the file
155
164
  OtlmowConverter.from_objects_to_file(
156
165
  file_path=template_file_path, sequence_of_objects=objects, split_per_type=split_per_type,
@@ -161,7 +170,8 @@ class SubsetTemplateCreator:
161
170
  if extension == '.xlsx':
162
171
  cls.alter_excel_template(
163
172
  generate_choice_list=generate_choice_list, file_path=template_file_path, dummy_data_rows=dummy_data_rows,
164
- instances=objects, add_deprecated=add_deprecated, add_attribute_info=add_attribute_info)
173
+ instances=objects, add_deprecated=add_deprecated, add_attribute_info=add_attribute_info,
174
+ abbreviate_excel_sheettitles=abbreviate_excel_after)
165
175
  elif extension == '.csv':
166
176
  cls.alter_csv_template(
167
177
  split_per_type=split_per_type, file_path=template_file_path, dummy_data_rows=dummy_data_rows,
@@ -340,7 +350,8 @@ class SubsetTemplateCreator:
340
350
 
341
351
  @classmethod
342
352
  def alter_excel_template(cls, instances: list, file_path: Path, add_attribute_info: bool,
343
- generate_choice_list: bool, dummy_data_rows: int, add_deprecated: bool):
353
+ generate_choice_list: bool, dummy_data_rows: int, add_deprecated: bool,
354
+ abbreviate_excel_sheettitles: bool):
344
355
  wb = load_workbook(file_path)
345
356
  wb.create_sheet('Keuzelijsten')
346
357
 
@@ -351,7 +362,8 @@ class SubsetTemplateCreator:
351
362
 
352
363
  cls.alter_excel_sheet(add_attribute_info=add_attribute_info, choice_list_dict=choice_list_dict,
353
364
  generate_choice_list=generate_choice_list, dummy_data_rows=dummy_data_rows,
354
- instances=instances, sheet=sheet, add_deprecated=add_deprecated, workbook=wb)
365
+ instances=instances, sheet=sheet, add_deprecated=add_deprecated, workbook=wb,
366
+ abbreviate_excel_sheettitle=abbreviate_excel_sheettitles)
355
367
 
356
368
  wb.save(file_path)
357
369
  wb.close()
@@ -455,7 +467,8 @@ class SubsetTemplateCreator:
455
467
 
456
468
  @classmethod
457
469
  async def alter_excel_template_async(cls, instances: list, file_path: Path, add_attribute_info: bool,
458
- generate_choice_list: bool, dummy_data_rows: int, add_deprecated: bool):
470
+ generate_choice_list: bool, dummy_data_rows: int, add_deprecated: bool,
471
+ abbreviate_excel_sheettitles: bool):
459
472
  wb = load_workbook(file_path)
460
473
  wb.create_sheet('Keuzelijsten')
461
474
 
@@ -466,7 +479,8 @@ class SubsetTemplateCreator:
466
479
 
467
480
  cls.alter_excel_sheet(add_attribute_info=add_attribute_info, choice_list_dict=choice_list_dict,
468
481
  generate_choice_list=generate_choice_list, dummy_data_rows=dummy_data_rows,
469
- instances=instances, sheet=sheet, add_deprecated=add_deprecated, workbook=wb)
482
+ instances=instances, sheet=sheet, add_deprecated=add_deprecated, workbook=wb,
483
+ abbreviate_excel_sheettitle=abbreviate_excel_sheettitles)
470
484
  await sleep(0)
471
485
 
472
486
  wb.save(file_path)
@@ -475,7 +489,7 @@ class SubsetTemplateCreator:
475
489
  @classmethod
476
490
  def alter_excel_sheet(cls, add_attribute_info: bool, choice_list_dict: dict, generate_choice_list: bool,
477
491
  instances: [OTLObject], sheet: Worksheet, add_deprecated: bool, workbook: Workbook,
478
- dummy_data_rows: int):
492
+ dummy_data_rows: int, abbreviate_excel_sheettitle: bool = True):
479
493
  type_uri = cls.get_uri_from_sheet_name(sheet.title)
480
494
  instance = next((x for x in instances if x.typeURI == type_uri), None)
481
495
  if instance is None:
@@ -487,18 +501,31 @@ class SubsetTemplateCreator:
487
501
  sheet.add_data_validation(boolean_validation)
488
502
  collected_attribute_info = []
489
503
  deprecated_attributes_row = []
504
+
490
505
  header_row = next(sheet.iter_rows(min_row=1, max_row=1))
506
+
507
+ first_data_row = 2 # first row is header, first data row is needed for later adjustments of formatting
508
+ if add_attribute_info:
509
+ first_data_row += 1
510
+ if add_deprecated and any(deprecated_attributes_row):
511
+ first_data_row += 1
512
+
513
+ max_row = 1000 # limit to 1000 as we only add validations up to row 1000
514
+ # Collect string columns to format after header processing
515
+ string_col_indices = []
516
+
491
517
  for header_cell in header_row:
492
518
  header = header_cell.value
493
- if header is None or header == '':
519
+ if not header:
494
520
  continue
495
521
 
496
522
  if header == 'typeURI':
497
523
  data_validation = DataValidation(type="list", formula1=f'"{type_uri}"', allow_blank=True)
498
524
  sheet.add_data_validation(data_validation)
499
- data_validation.add(f'{header_cell.column_letter}2:{header_cell.column_letter}1000')
525
+ data_validation.add(f'{header_cell.column_letter}{first_data_row}:{header_cell.column_letter}{max_row}')
500
526
  if add_attribute_info:
501
- collected_attribute_info.append('De URI van het object volgens https://www.w3.org/2001/XMLSchema#anyURI .')
527
+ collected_attribute_info.append(
528
+ 'De URI van het object volgens https://www.w3.org/2001/XMLSchema#anyURI .')
502
529
  if add_deprecated:
503
530
  deprecated_attributes_row.append('')
504
531
  continue
@@ -515,16 +542,23 @@ class SubsetTemplateCreator:
515
542
  deprecated_attributes_row.append('DEPRECATED' if attribute.deprecated_version else '')
516
543
 
517
544
  if generate_choice_list:
518
- if issubclass(attribute.field, BooleanField):
519
- boolean_validation.add(f'{header_cell.column_letter}2:{header_cell.column_letter}1000')
545
+ if attribute.field.native_type == bool:
546
+ boolean_validation.add(f'{header_cell.column_letter}{first_data_row}:{header_cell.column_letter}{max_row}')
520
547
  cls.color_choice_lists_green(sheet=sheet, header_cell_column=header_cell)
521
-
522
- elif issubclass(attribute.field, KeuzelijstField):
548
+ elif hasattr(attribute.field, 'options') and attribute.field.options is not None:
523
549
  cls.generate_choice_list_in_excel(
524
550
  attribute=attribute, choice_list_dict=choice_list_dict, column=header_cell.column,
525
551
  row_nr=1, sheet=sheet, workbook=workbook)
526
552
  cls.color_choice_lists_green(sheet=sheet, header_cell_column=header_cell)
527
553
 
554
+ if attribute.field.native_type == str:
555
+ string_col_indices.append(header_cell.column)
556
+
557
+ # Efficiently format all string columns in one pass
558
+ for col_idx in string_col_indices:
559
+ for row_idx in range(first_data_row, max_row + 1):
560
+ sheet.cell(row=row_idx, column=col_idx).number_format = "@"
561
+
528
562
  if dummy_data_rows == 0:
529
563
  instance_count = len([x for x in instances if x.typeURI == type_uri])
530
564
  if instance_count > 0:
@@ -538,6 +572,9 @@ class SubsetTemplateCreator:
538
572
 
539
573
  cls.set_fixed_column_width(sheet=sheet, width=25)
540
574
 
575
+ if abbreviate_excel_sheettitle:
576
+ cls.abbreviate_excel_sheettitle(sheet=sheet)
577
+
541
578
  @classmethod
542
579
  def color_choice_lists_green(cls, sheet: Worksheet, header_cell_column: Cell):
543
580
  for cell in sheet.iter_rows(min_col=header_cell_column.column, max_col=header_cell_column.column,
@@ -646,3 +683,16 @@ class SubsetTemplateCreator:
646
683
  target=doel_instance, model_directory=model_directory)
647
684
 
648
685
  otl_objects.append(relation_instance)
686
+
687
+ @classmethod
688
+ def abbreviate_excel_sheettitle(cls, sheet):
689
+ class_name = sheet.title
690
+ # abbreviates the class_name so it doesn't exceed the 31 character limit of sheet titles in excel
691
+ if '#' not in class_name:
692
+ sheet.title = class_name[:31]
693
+ return
694
+ split_name = class_name.split("#")
695
+ namespace_name = split_name[0]
696
+ subclass_name = split_name[1]
697
+ class_name = f"{namespace_name[:3]}#{subclass_name}"
698
+ sheet.title = class_name[:31]
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: otlmow_template
3
- Version: 1.7
3
+ Version: 1.10
4
4
  Author-email: David Vlaminck <david.vlaminck@mow.vlaanderen.be>, Jasper Berton <jasperberton1@telenet.be>
5
5
  License: GNU GENERAL PUBLIC LICENSE
6
6
  Version 3, 29 June 2007
@@ -684,6 +684,7 @@ Classifier: Programming Language :: Python :: 3.10
684
684
  Classifier: Programming Language :: Python :: 3.11
685
685
  Classifier: Programming Language :: Python :: 3.12
686
686
  Classifier: Programming Language :: Python :: 3.13
687
+ Classifier: Programming Language :: Python :: 3.14
687
688
  Classifier: Operating System :: OS Independent
688
689
  Classifier: Development Status :: 5 - Production/Stable
689
690
  Classifier: Environment :: Console
@@ -698,12 +699,13 @@ Requires-Python: >=3.9
698
699
  Description-Content-Type: text/markdown
699
700
  License-File: LICENSE
700
701
  Requires-Dist: otlmow-converter>=1.14
701
- Requires-Dist: otlmow-modelbuilder>=0.27
702
+ Requires-Dist: otlmow-modelbuilder>=0.37
702
703
  Provides-Extra: test
703
704
  Requires-Dist: pytest; extra == "test"
704
705
  Requires-Dist: pytest-cov; extra == "test"
705
706
  Requires-Dist: pytest-subtests; extra == "test"
706
707
  Requires-Dist: pytest-timeout; extra == "test"
708
+ Requires-Dist: pytest-asyncio; extra == "test"
707
709
  Dynamic: license-file
708
710
 
709
711
  # OTLMOW-Template
@@ -731,16 +733,18 @@ It is split into different packages to reduce compatibility issues
731
733
  - [otlmow_gui](https://github.com/davidvlaminck/OTLMOW-GUI)
732
734
 
733
735
  ## Installation and requirements
734
- Currently, you need at least Python version 3.8 to use this library.
735
-
736
- To install the OTL MOW project into your Python project, use pip to install it:
736
+ I recommend working with uv. Install this first:
737
737
  ```
738
- pip install otlmow_template
738
+ pip install uv
739
739
  ```
740
- To upgrade an existing installation use:
740
+ Then install this package by using the uv pip install command:
741
741
  ```
742
- pip install otlmow_template --upgrade
742
+ uv pip install otlmow-template
743
743
  ```
744
+ If you are a developer, use this command to install the dependencies, including those needed to run the test suite.
745
+ ```
746
+ uv pip install -r pyproject.toml --extra test
747
+ ```
744
748
 
745
749
  ## Usage
746
750
  #TODO
@@ -0,0 +1,7 @@
1
+ otlmow_template/SubsetTemplateCreator.py,sha256=t96Medun2k2zbTCCFSY4vKvIy43Hh4LnB1bYex5ONok,35500
2
+ otlmow_template/Exceptions/MissingTypeUriException.py,sha256=DSKwywmP9Bq8n7rzBoDcEPlxvC1IChx18QIHFUCTtdA,51
3
+ otlmow_template-1.10.dist-info/licenses/LICENSE,sha256=ixuiBLtpoK3iv89l7ylKkg9rs2GzF9ukPH7ynZYzK5s,35148
4
+ otlmow_template-1.10.dist-info/METADATA,sha256=PiAyWmgjyGjipqsjg0UO4MDOISBGeznaM2GmsB3jQzg,44392
5
+ otlmow_template-1.10.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
6
+ otlmow_template-1.10.dist-info/top_level.txt,sha256=zPgBoaTLG-avoOLySlwOUEtHaFyA5Vc5wJqkSeX1l6A,16
7
+ otlmow_template-1.10.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (80.9.0)
2
+ Generator: setuptools (80.10.2)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
@@ -1,7 +0,0 @@
1
- otlmow_template/SubsetTemplateCreator.py,sha256=M3CIHzj7u9N73J8F7L0xAt4l_M6g5Hjdz5puqvBfBnU,33233
2
- otlmow_template/Exceptions/MissingTypeUriException.py,sha256=DSKwywmP9Bq8n7rzBoDcEPlxvC1IChx18QIHFUCTtdA,51
3
- otlmow_template-1.7.dist-info/licenses/LICENSE,sha256=ixuiBLtpoK3iv89l7ylKkg9rs2GzF9ukPH7ynZYzK5s,35148
4
- otlmow_template-1.7.dist-info/METADATA,sha256=Stvx0Ptymrj1wVjz8Cp4yU2jqJuaFTHKRAA673O0WjY,44220
5
- otlmow_template-1.7.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
6
- otlmow_template-1.7.dist-info/top_level.txt,sha256=zPgBoaTLG-avoOLySlwOUEtHaFyA5Vc5wJqkSeX1l6A,16
7
- otlmow_template-1.7.dist-info/RECORD,,