otlmow-template 0.2__tar.gz → 0.4__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.
@@ -1,7 +1,7 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: otlmow_template
3
- Version: 0.2
4
- Author-email: David Vlaminck <david.vlaminck@mow.vlaanderen.be>
3
+ Version: 0.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
7
7
 
@@ -679,19 +679,49 @@ License: GNU GENERAL PUBLIC LICENSE
679
679
  Project-URL: Homepage, https://github.com/davidvlaminck/OTLMOW-Template
680
680
  Project-URL: Bug Tracker, https://github.com/davidvlaminck/OTLMOW-Template/issues
681
681
  Classifier: Programming Language :: Python :: 3
682
+ Classifier: Programming Language :: Python :: 3.8
683
+ Classifier: Programming Language :: Python :: 3.9
684
+ Classifier: Programming Language :: Python :: 3.10
685
+ Classifier: Programming Language :: Python :: 3.11
682
686
  Classifier: Operating System :: OS Independent
687
+ Classifier: Development Status :: 5 - Production/Stable
688
+ Classifier: Environment :: Console
689
+ Classifier: Intended Audience :: Developers
690
+ Classifier: Intended Audience :: Information Technology
691
+ Classifier: License :: OSI Approved :: GNU General Public License v3 (GPLv3)
692
+ Classifier: Natural Language :: Dutch
693
+ Classifier: Topic :: Software Development
694
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
695
+ Classifier: Topic :: Software Development :: Quality Assurance
683
696
  Requires-Python: >=3.8
684
697
  Description-Content-Type: text/markdown
685
698
  License-File: LICENSE
699
+ Requires-Dist: otlmow-converter>=0.14
700
+ Requires-Dist: otlmow-modelbuilder>=0.11
686
701
 
687
702
  # OTLMOW-Template
703
+ [![PyPI](https://img.shields.io/pypi/v/otlmow-template?label=latest%20release)](https://pypi.org/project/otlmow-template/)
704
+ [![otlmow-template-downloads](https://img.shields.io/pypi/dm/otlmow-template)](https://pypi.org/project/otlmow-template/)
705
+ [![Unittests](https://github.com/davidvlaminck/otlmow-template/actions/workflows/unittest.yml/badge.svg)](https://github.com/davidvlaminck/otlmow-template/actions/workflows/unittest.yml)
706
+ ![PyPI - Python Version](https://img.shields.io/pypi/pyversions/otlmow-template)
707
+ [![GitHub issues](https://img.shields.io/github/issues/davidvlaminck/otlmow-template)](https://github.com/davidvlaminck/otlmow-template/issues)
708
+ [![coverage](https://github.com/davidvlaminck/otlmow-template/blob/master/UnitTests/coverage.svg)](https://htmlpreview.github.io/?https://github.com/davidvlaminck/otlmow-template/blob/master/UnitTests/htmlcov/index.html)
709
+
710
+
711
+ ## Summary
712
+ The main use case of otlmow-template is to provide templates for the users, depending on a given subset.
713
+
688
714
  ## OTLMOW Project
689
715
  This project aims to implement the Flemish data standard OTL (https://wegenenverkeer.data.vlaanderen.be/) in Python.
690
716
  It is split into different packages to reduce compatibility issues
691
- - otlmow_model
692
- - otlmow_modelbuilder
693
- - otlmow_converter
694
- - otlmow_template (you are currently looking at this package)
717
+ - [otlmow_model](https://github.com/davidvlaminck/OTLMOW-Model)
718
+ - [otlmow_modelbuilder](https://github.com/davidvlaminck/OTLMOW-ModelBuilder)
719
+ - [otlmow_converter](https://github.com/davidvlaminck/OTLMOW-Converter)
720
+ - [otlmow_template](https://github.com/davidvlaminck/OTLMOW-Template) (you are currently looking at this package)
721
+ - [otlmow_postenmapping](https://github.com/davidvlaminck/OTLMOW-PostenMapping)
722
+ - [otlmow_davie](https://github.com/davidvlaminck/OTLMOW-DAVIE)
723
+ - [otlmow_visuals](https://github.com/davidvlaminck/OTLMOW-Visuals)
724
+ - [otlmow_gui](https://github.com/davidvlaminck/OTLMOW-GUI)
695
725
 
696
726
  ## Installation and requirements
697
727
  Currently, you need at least Python version 3.8 to use this library.
@@ -0,0 +1,38 @@
1
+ # OTLMOW-Template
2
+ [![PyPI](https://img.shields.io/pypi/v/otlmow-template?label=latest%20release)](https://pypi.org/project/otlmow-template/)
3
+ [![otlmow-template-downloads](https://img.shields.io/pypi/dm/otlmow-template)](https://pypi.org/project/otlmow-template/)
4
+ [![Unittests](https://github.com/davidvlaminck/otlmow-template/actions/workflows/unittest.yml/badge.svg)](https://github.com/davidvlaminck/otlmow-template/actions/workflows/unittest.yml)
5
+ ![PyPI - Python Version](https://img.shields.io/pypi/pyversions/otlmow-template)
6
+ [![GitHub issues](https://img.shields.io/github/issues/davidvlaminck/otlmow-template)](https://github.com/davidvlaminck/otlmow-template/issues)
7
+ [![coverage](https://github.com/davidvlaminck/otlmow-template/blob/master/UnitTests/coverage.svg)](https://htmlpreview.github.io/?https://github.com/davidvlaminck/otlmow-template/blob/master/UnitTests/htmlcov/index.html)
8
+
9
+
10
+ ## Summary
11
+ The main use case of otlmow-template is to provide templates for the users, depending on a given subset.
12
+
13
+ ## OTLMOW Project
14
+ This project aims to implement the Flemish data standard OTL (https://wegenenverkeer.data.vlaanderen.be/) in Python.
15
+ It is split into different packages to reduce compatibility issues
16
+ - [otlmow_model](https://github.com/davidvlaminck/OTLMOW-Model)
17
+ - [otlmow_modelbuilder](https://github.com/davidvlaminck/OTLMOW-ModelBuilder)
18
+ - [otlmow_converter](https://github.com/davidvlaminck/OTLMOW-Converter)
19
+ - [otlmow_template](https://github.com/davidvlaminck/OTLMOW-Template) (you are currently looking at this package)
20
+ - [otlmow_postenmapping](https://github.com/davidvlaminck/OTLMOW-PostenMapping)
21
+ - [otlmow_davie](https://github.com/davidvlaminck/OTLMOW-DAVIE)
22
+ - [otlmow_visuals](https://github.com/davidvlaminck/OTLMOW-Visuals)
23
+ - [otlmow_gui](https://github.com/davidvlaminck/OTLMOW-GUI)
24
+
25
+ ## Installation and requirements
26
+ Currently, you need at least Python version 3.8 to use this library.
27
+
28
+ To install the OTL MOW project into your Python project, use pip to install it:
29
+ ```
30
+ pip install otlmow_template
31
+ ```
32
+ To upgrade an existing installation use:
33
+ ```
34
+ pip install otlmow_template --upgrade
35
+ ```
36
+
37
+ ## Usage
38
+ #TODO
@@ -0,0 +1,155 @@
1
+ import csv
2
+ import ntpath
3
+ import os
4
+ import tempfile
5
+ from pathlib import Path
6
+ from typing import List, Sequence, Optional
7
+
8
+ from otlmow_converter.DotnotationHelper import DotnotationHelper
9
+ from otlmow_converter.OtlmowConverter import OtlmowConverter
10
+
11
+
12
+ class CsvTemplateCreator:
13
+
14
+ @classmethod
15
+ def determine_multiplicity_csv(cls, path_to_template_file_and_extension: Path, path_to_subset: Path,
16
+ temporary_path: Path, **kwargs):
17
+ path_is_split = kwargs.get('split_per_type', True)
18
+ if path_is_split is False:
19
+ cls.alter_csv_template(path_to_template_file_and_extension=path_to_template_file_and_extension,
20
+ temporary_path=temporary_path, path_to_subset=path_to_subset, **kwargs)
21
+ else:
22
+ cls.multiple_csv_template(path_to_template_file_and_extension=path_to_template_file_and_extension,
23
+ path_to_subset=path_to_subset, **kwargs)
24
+ file_location = os.path.dirname(temporary_path)
25
+ [f.unlink() for f in Path(file_location).glob("*") if f.is_file()]
26
+
27
+ @classmethod
28
+ def multiple_csv_template(cls, path_to_template_file_and_extension, path_to_subset, **kwargs):
29
+ file_location = os.path.dirname(path_to_template_file_and_extension)
30
+ tempdir = Path(tempfile.gettempdir()) / 'temp-otlmow'
31
+ file_name = ntpath.basename(path_to_template_file_and_extension)
32
+ split_file_name = file_name.split('.')
33
+ things_in_there = os.listdir(tempdir)
34
+ csv_templates = [x for x in things_in_there if x.startswith(split_file_name[0] + '_')]
35
+ for file in csv_templates:
36
+ test_template_loc = Path(os.path.dirname(path_to_template_file_and_extension)) / file
37
+ temp_loc = Path(tempdir) / file
38
+ cls.alter_csv_template(path_to_template_file_and_extension=test_template_loc, temporary_path=temp_loc,
39
+ path_to_subset=path_to_subset, **kwargs)
40
+
41
+ @classmethod
42
+ def alter_csv_template(cls, path_to_template_file_and_extension, path_to_subset, temporary_path,
43
+ **kwargs):
44
+ converter = OtlmowConverter()
45
+ instantiated_attributes = converter.create_assets_from_file(filepath=temporary_path,
46
+ path_to_subset=path_to_subset)
47
+ header = []
48
+ data = []
49
+ delimiter = ';'
50
+ add_geo_artefact = kwargs.get('add_geo_artefact', False)
51
+ add_attribute_info = kwargs.get('add_attribute_info', False)
52
+ highlight_deprecated_attributes = kwargs.get('highlight_deprecated_attributes', False)
53
+ amount_of_examples = kwargs.get('amount_of_examples', 0)
54
+ quote_char = '"'
55
+ with open(temporary_path, 'r+', encoding='utf-8') as csvfile:
56
+ new_file = open(path_to_template_file_and_extension, 'w', encoding='utf-8')
57
+ reader = csv.reader(csvfile, delimiter=delimiter, quotechar=quote_char)
58
+ for row_nr, row in enumerate(reader):
59
+ if row_nr == 0:
60
+ header = row
61
+ else:
62
+ data.append(row)
63
+ if add_geo_artefact is False:
64
+ [header, data] = cls.remove_geo_artefact_csv(header=header, data=data)
65
+ if add_attribute_info:
66
+ info = cls.add_attribute_info_csv(header=header, data=data,
67
+ instantiated_objects=instantiated_attributes)
68
+ new_file.write(delimiter.join(info) + '\n')
69
+ data = cls.remove_mock_data_csv(data=data, rows_of_examples=amount_of_examples)
70
+ if highlight_deprecated_attributes:
71
+ header = cls.highlight_deprecated_attributes_csv(header=header, data=data,
72
+ instantiated_attributes=instantiated_attributes)
73
+ new_file.write(delimiter.join(header) + '\n')
74
+ for d in data:
75
+ new_file.write(delimiter.join(d) + '\n')
76
+ new_file.close()
77
+
78
+ @classmethod
79
+ def add_attribute_info_csv(cls, header: List[str], data: List[List[str]], instantiated_objects: List) -> List[str]:
80
+ info_data = []
81
+ info_data.extend(header)
82
+
83
+ dotnotation_module = DotnotationHelper()
84
+
85
+ uri_index = cls.get_type_uri_index_in_row(header)
86
+ found_uris = set(d[uri_index] for d in data)
87
+
88
+ for uri in found_uris:
89
+ single_object = next(x for x in instantiated_objects if x.typeURI == uri)
90
+ for index, dotnototation_title in enumerate(info_data):
91
+ if dotnototation_title == 'typeURI':
92
+ info_data[index] = 'De URI van het object volgens https://www.w3.org/2001/XMLSchema#anyURI .'
93
+ else:
94
+ dotnotation_attribute = dotnotation_module.get_attribute_by_dotnotation(
95
+ single_object, dotnototation_title)
96
+ info_data[index] = dotnotation_attribute.definition
97
+ return info_data
98
+
99
+ @classmethod
100
+ def remove_mock_data_csv(cls, data, rows_of_examples):
101
+ if rows_of_examples == 0:
102
+ data = []
103
+ return data
104
+
105
+ @classmethod
106
+ def highlight_deprecated_attributes_csv(cls, header, data, instantiated_attributes):
107
+ found_uri = []
108
+ dotnotation_module = DotnotationHelper()
109
+ uri_index = cls.get_type_uri_index_in_row(header)
110
+ for d in data:
111
+ if d[uri_index] not in found_uri:
112
+ found_uri.append(d[uri_index])
113
+ for uri in found_uri:
114
+ single_object = next(x for x in instantiated_attributes if x.typeURI == uri)
115
+ for dotnototation_title in header:
116
+ if dotnototation_title == 'typeURI':
117
+ continue
118
+ else:
119
+ index = header.index(dotnototation_title)
120
+ value = header[index]
121
+ try:
122
+ is_deprecated = False
123
+ if dotnototation_title.count('.') == 1:
124
+ dot_split = dotnototation_title.split('.')
125
+ attribute = dotnotation_module.get_attribute_by_dotnotation(single_object,
126
+ dot_split[0])
127
+
128
+ if len(attribute.deprecated_version) > 0:
129
+ is_deprecated = True
130
+ dotnotation_attribute = dotnotation_module.get_attribute_by_dotnotation(single_object,
131
+ dotnototation_title)
132
+ if len(dotnotation_attribute.deprecated_version) > 0:
133
+ is_deprecated = True
134
+ except AttributeError:
135
+ continue
136
+ if is_deprecated:
137
+ header[index] = "[DEPRECATED] " + value
138
+ return header
139
+
140
+ @classmethod
141
+ def get_type_uri_index_in_row(cls, header: Sequence[str]) -> Optional[int]:
142
+ try:
143
+ return header.index('typeURI')
144
+ except ValueError:
145
+ return None
146
+
147
+ @classmethod
148
+ def remove_geo_artefact_csv(cls, header, data):
149
+ if 'geometry' in header:
150
+ deletion_index = header.index('geometry')
151
+ header.remove('geometry')
152
+ for d in data:
153
+ d.pop(deletion_index)
154
+ return [header, data]
155
+
@@ -0,0 +1,199 @@
1
+ import os
2
+ from pathlib import Path
3
+ from typing import List
4
+
5
+ from openpyxl.reader.excel import load_workbook
6
+ from openpyxl.styles import PatternFill
7
+ from openpyxl.utils import get_column_letter
8
+ from openpyxl.worksheet.datavalidation import DataValidation
9
+ from openpyxl.worksheet.dimensions import DimensionHolder, ColumnDimension
10
+ from otlmow_converter.DotnotationHelper import DotnotationHelper
11
+ from otlmow_model.OtlmowModel.BaseClasses.BooleanField import BooleanField
12
+ from otlmow_model.OtlmowModel.BaseClasses.KeuzelijstField import KeuzelijstField
13
+
14
+
15
+ class ExcelTemplateCreator:
16
+
17
+ @classmethod
18
+ def alter_excel_template(cls, path_to_template_file_and_extension: Path, instantiated_attributes: List,
19
+ temporary_path: Path, **kwargs):
20
+ generate_choice_list = kwargs.get('generate_choice_list', False)
21
+ add_geo_artefact = kwargs.get('add_geo_artefact', False)
22
+ add_attribute_info = kwargs.get('add_attribute_info', False)
23
+ highlight_deprecated_attributes = kwargs.get('highlight_deprecated_attributes', False)
24
+ amount_of_examples = kwargs.get('amount_of_examples', 0)
25
+ wb = load_workbook(temporary_path)
26
+ wb.create_sheet('Keuzelijsten')
27
+ # Volgorde is belangrijk! Eerst rijen verwijderen indien nodig dan choice list toevoegen,
28
+ # staat namelijk vast op de kolom en niet het attribuut in die kolom
29
+ if add_geo_artefact is False:
30
+ cls.remove_geo_artefact_excel(workbook=wb)
31
+ if generate_choice_list:
32
+ cls.add_choice_list_excel(workbook=wb, instantiated_attributes=instantiated_attributes)
33
+ cls.add_mock_data_excel(workbook=wb, rows_of_examples=amount_of_examples)
34
+ if highlight_deprecated_attributes:
35
+ cls.check_for_deprecated_attributes_excel(workbook=wb, instantiated_attributes=instantiated_attributes)
36
+ if add_attribute_info:
37
+ cls.add_attribute_info_excel(workbook=wb, instantiated_attributes=instantiated_attributes)
38
+ cls.design_workbook_excel(workbook=wb)
39
+ wb.save(path_to_template_file_and_extension)
40
+ file_location = os.path.dirname(temporary_path)
41
+ [f.unlink() for f in Path(file_location).glob("*") if f.is_file()]
42
+
43
+ @classmethod
44
+ def add_attribute_info_excel(cls, workbook, instantiated_attributes: List):
45
+ dotnotation_module = DotnotationHelper()
46
+ for sheet in workbook:
47
+ if sheet == workbook['Keuzelijsten']:
48
+ break
49
+ filter_uri = cls.find_uri_in_sheet(sheet)
50
+ single_attribute = next(x for x in instantiated_attributes if x.typeURI == filter_uri)
51
+ sheet.insert_rows(1)
52
+ for rows in sheet.iter_rows(min_row=2, max_row=2, min_col=1):
53
+ for cell in rows:
54
+ if cell.value == 'typeURI':
55
+ value = 'De URI van het object volgens https://www.w3.org/2001/XMLSchema#anyURI .'
56
+ elif cell.value.find('[DEPRECATED]') != -1:
57
+ strip = cell.value.split(' ')
58
+ dotnotation_attribute = dotnotation_module.get_attribute_by_dotnotation(single_attribute,
59
+ strip[1])
60
+ value = dotnotation_attribute.definition
61
+ else:
62
+ dotnotation_attribute = dotnotation_module.get_attribute_by_dotnotation(single_attribute,
63
+ cell.value)
64
+ value = dotnotation_attribute.definition
65
+
66
+ sheet.cell(row=1, column=cell.column, value=value)
67
+ sheet.cell(row=1, column=cell.column).fill = PatternFill(start_color="808080", end_color="808080",
68
+ fill_type="solid")
69
+
70
+ @classmethod
71
+ def check_for_deprecated_attributes_excel(cls, workbook, instantiated_attributes: List):
72
+ dotnotation_module = DotnotationHelper()
73
+ for sheet in workbook:
74
+ if sheet == workbook['Keuzelijsten']:
75
+ break
76
+ filter_uri = cls.find_uri_in_sheet(sheet)
77
+ single_attribute = next(x for x in instantiated_attributes if x.typeURI == filter_uri)
78
+ for rows in sheet.iter_rows(min_row=1, max_row=1, min_col=2):
79
+ for cell in rows:
80
+ is_deprecated = False
81
+ if cell.value.count('.') == 1:
82
+ dot_split = cell.value.split('.')
83
+ attribute = dotnotation_module.get_attribute_by_dotnotation(single_attribute,
84
+ dot_split[0])
85
+
86
+ if len(attribute.deprecated_version) > 0:
87
+ is_deprecated = True
88
+ dotnotation_attribute = dotnotation_module.get_attribute_by_dotnotation(single_attribute,
89
+ cell.value)
90
+ if len(dotnotation_attribute.deprecated_version) > 0:
91
+ is_deprecated = True
92
+
93
+ if is_deprecated:
94
+ cell.value = '[DEPRECATED] ' + cell.value
95
+
96
+ @classmethod
97
+ def find_uri_in_sheet(cls, sheet):
98
+ filter_uri = None
99
+ for row in sheet.iter_rows(min_row=1, max_row=1):
100
+ for cell in row:
101
+ if cell.value == 'typeURI':
102
+ row_index = cell.row
103
+ column_index = cell.column
104
+ filter_uri = sheet.cell(row=row_index + 1, column=column_index).value
105
+ return filter_uri
106
+
107
+ @classmethod
108
+ def remove_geo_artefact_excel(cls, workbook):
109
+ for sheet in workbook:
110
+ for row in sheet.iter_rows(min_row=1, max_row=1):
111
+ for cell in row:
112
+ if cell.value == 'geometry':
113
+ sheet.delete_cols(cell.column)
114
+
115
+ @classmethod
116
+ def add_choice_list_excel(cls, workbook, instantiated_attributes: List):
117
+ choice_list_dict = {}
118
+ dotnotation_module = DotnotationHelper()
119
+ for sheet in workbook:
120
+ if sheet == workbook['Keuzelijsten']:
121
+ break
122
+ filter_uri = cls.find_uri_in_sheet(sheet)
123
+ single_attribute = next(x for x in instantiated_attributes if x.typeURI == filter_uri)
124
+ for rows in sheet.iter_rows(min_row=1, max_row=1, min_col=2):
125
+ for cell in rows:
126
+ if cell.value.find('[DEPRECATED]') != -1:
127
+ strip = cell.value.split(' ')
128
+ dotnotation_attribute = dotnotation_module.get_attribute_by_dotnotation(single_attribute,
129
+ strip[1])
130
+ else:
131
+ dotnotation_attribute = dotnotation_module.get_attribute_by_dotnotation(single_attribute,
132
+ cell.value)
133
+
134
+ if issubclass(dotnotation_attribute.field, KeuzelijstField):
135
+ name = dotnotation_attribute.field.naam
136
+ valid_options = [v.invulwaarde for k, v in dotnotation_attribute.field.options.items()
137
+ if v.status != 'verwijderd']
138
+ column = cls.return_column_letter_of_choice_list(name=name, choice_list_dict=choice_list_dict,
139
+ options=valid_options, workbook=workbook)
140
+ option_list = []
141
+ for option in valid_options:
142
+ option_list.append(option)
143
+ start_range = f"${column}$2"
144
+ end_range = f"${column}${len(valid_options) + 1}"
145
+ data_val = DataValidation(type="list", formula1=f"Keuzelijsten!{start_range}:{end_range}",
146
+ allowBlank=True)
147
+ sheet.add_data_validation(data_val)
148
+ data_val.add(f'{get_column_letter(cell.column)}2:{get_column_letter(cell.column)}1000')
149
+ if issubclass(dotnotation_attribute.field, BooleanField):
150
+ data_validation = DataValidation(type="list", formula1='"TRUE,FALSE,-"', allow_blank=True)
151
+ column = cell.column
152
+ sheet.add_data_validation(data_validation)
153
+ data_validation.add(f'{get_column_letter(column)}2:{get_column_letter(column)}1000')
154
+ sheet.add_data_validation(data_validation)
155
+
156
+ @classmethod
157
+ def add_mock_data_excel(cls, workbook, rows_of_examples: int):
158
+ for sheet in workbook:
159
+ if sheet == workbook["Keuzelijsten"]:
160
+ break
161
+ if rows_of_examples == 0:
162
+ for rows in sheet.iter_rows(min_row=2, max_row=2):
163
+ for cell in rows:
164
+ cell.value = ''
165
+
166
+ @classmethod
167
+ def return_column_letter_of_choice_list(cls, name, choice_list_dict, options, workbook):
168
+ if name in choice_list_dict:
169
+ column = choice_list_dict[name]
170
+ else:
171
+ choice_list_dict = cls.add_choice_list_to_sheet(workbook=workbook, name=name,
172
+ options=options,
173
+ choice_list_dict=choice_list_dict)
174
+ column = choice_list_dict[name]
175
+ return column
176
+
177
+ @classmethod
178
+ def add_choice_list_to_sheet(cls, workbook, name, options, choice_list_dict):
179
+ active_sheet = workbook['Keuzelijsten']
180
+ row_nr = 2
181
+ for rows in active_sheet.iter_rows(min_row=1, max_row=1, min_col=1, max_col=700):
182
+ for cell in rows:
183
+ if cell.value is None:
184
+ cell.value = name
185
+ column_nr = cell.column
186
+ for option in options:
187
+ active_sheet.cell(row=row_nr, column=column_nr, value=option)
188
+ row_nr += 1
189
+ choice_list_dict[name] = get_column_letter(column_nr)
190
+ break
191
+ return choice_list_dict
192
+
193
+ @classmethod
194
+ def design_workbook_excel(cls, workbook):
195
+ for sheet in workbook:
196
+ dim_holder = DimensionHolder(worksheet=sheet)
197
+ for col in range(sheet.min_column, sheet.max_column + 1):
198
+ dim_holder[get_column_letter(col)] = ColumnDimension(sheet, min=col, max=col, width=20)
199
+ sheet.column_dimensions = dim_holder
@@ -0,0 +1,2 @@
1
+ class MissingTypeUriException(Exception):
2
+ pass
@@ -0,0 +1,465 @@
1
+ import ntpath
2
+ import os
3
+ import csv
4
+ import site
5
+ import tempfile
6
+ from pathlib import Path
7
+ from typing import List
8
+ from openpyxl.reader.excel import load_workbook
9
+ from openpyxl.styles import PatternFill
10
+ from openpyxl.utils import get_column_letter
11
+ from openpyxl.worksheet.datavalidation import DataValidation
12
+ from openpyxl.worksheet.dimensions import DimensionHolder, ColumnDimension
13
+ from otlmow_converter.DotnotationHelper import DotnotationHelper
14
+ from otlmow_converter.OtlmowConverter import OtlmowConverter
15
+ from otlmow_model.OtlmowModel.BaseClasses.BooleanField import BooleanField
16
+ from otlmow_model.OtlmowModel.BaseClasses.KeuzelijstField import KeuzelijstField
17
+ from otlmow_model.OtlmowModel.BaseClasses.OTLObject import dynamic_create_instance_from_uri
18
+ from otlmow_modelbuilder.OSLOCollector import OSLOCollector
19
+
20
+ ROOT_DIR = os.path.abspath(os.path.join(os.path.dirname(__file__), '..'))
21
+
22
+ enumeration_validation_rules = {
23
+ "valid_uri_and_types": {},
24
+ "valid_regexes": [
25
+ "^https://wegenenverkeer.data.vlaanderen.be/ns/.+"]
26
+ }
27
+
28
+
29
+ class SubsetTemplateCreator:
30
+ def __init__(self):
31
+ pass
32
+
33
+ @staticmethod
34
+ def _load_collector_from_subset_path(path_to_subset: Path) -> OSLOCollector:
35
+ collector = OSLOCollector(path_to_subset)
36
+ collector.collect_all(include_abstract=True)
37
+ return collector
38
+
39
+ def generate_template_from_subset(self, path_to_subset: Path, path_to_template_file_and_extension: Path,
40
+ **kwargs):
41
+ tempdir = Path(tempfile.gettempdir()) / 'temp-otlmow'
42
+ if not tempdir.exists():
43
+ os.makedirs(tempdir)
44
+ test = ntpath.basename(path_to_template_file_and_extension)
45
+ temporary_path = Path(tempdir) / test
46
+ instantiated_attributes = self.generate_basic_template(path_to_subset=path_to_subset,
47
+ temporary_path=temporary_path,
48
+ path_to_template_file_and_extension=path_to_template_file_and_extension,
49
+ **kwargs)
50
+ extension = os.path.splitext(path_to_template_file_and_extension)[-1].lower()
51
+ if extension == '.xlsx':
52
+ self.alter_excel_template(path_to_template_file_and_extension=path_to_template_file_and_extension,
53
+ temporary_path=temporary_path,
54
+ path_to_subset=path_to_subset, instantiated_attributes=instantiated_attributes,
55
+ **kwargs)
56
+ elif extension == '.csv':
57
+ self.determine_multiplicity_csv(path_to_template_file_and_extension=path_to_template_file_and_extension,
58
+ path_to_subset=path_to_subset,
59
+ instantiated_attributes=instantiated_attributes,
60
+ temporary_path=temporary_path,
61
+ **kwargs)
62
+
63
+ def generate_basic_template(self, path_to_subset: Path, path_to_template_file_and_extension: Path,
64
+ temporary_path: Path, **kwargs):
65
+ collector = self._load_collector_from_subset_path(path_to_subset=path_to_subset)
66
+ otl_objects = []
67
+ amount_of_examples = kwargs.get('amount_of_examples', 0)
68
+
69
+ for class_object in list(filter(lambda cl: cl.abstract == 0, collector.classes)):
70
+ model_directory = None
71
+ if kwargs is not None:
72
+ model_directory = kwargs.get('model_directory', None)
73
+ if amount_of_examples != 0:
74
+ for i in range(amount_of_examples):
75
+ instance = dynamic_create_instance_from_uri(class_object.objectUri, model_directory=model_directory)
76
+ if instance is None:
77
+ continue
78
+ instance.fill_with_dummy_data()
79
+ otl_objects.append(instance)
80
+ else:
81
+ instance = dynamic_create_instance_from_uri(class_object.objectUri, model_directory=model_directory)
82
+ if instance is None:
83
+ continue
84
+ instance.fill_with_dummy_data()
85
+ otl_objects.append(instance)
86
+
87
+ # TODO: check if this is needed, as the above line should cover this
88
+ attributen = collector.find_attributes_by_class(class_object)
89
+ for attribute_object in attributen:
90
+ attr = getattr(instance, '_' + attribute_object.name)
91
+ attr.fill_with_dummy_data()
92
+ converter = OtlmowConverter()
93
+ converter.from_objects_to_file(file_path=temporary_path,
94
+ sequence_of_objects=otl_objects, **kwargs)
95
+ path_is_split = kwargs.get('split_per_type', True)
96
+ extension = os.path.splitext(path_to_template_file_and_extension)[-1].lower()
97
+ instantiated_attributes = []
98
+ if path_is_split is False or extension == '.xlsx':
99
+ instantiated_attributes = converter.from_file_to_objects(file_path=temporary_path,
100
+ path_to_subset=path_to_subset)
101
+ return instantiated_attributes
102
+
103
+ @classmethod
104
+ def alter_excel_template(cls, path_to_template_file_and_extension: Path, path_to_subset: Path,
105
+ instantiated_attributes: List, temporary_path, **kwargs):
106
+ generate_choice_list = kwargs.get('generate_choice_list', False)
107
+ add_geo_artefact = kwargs.get('add_geo_artefact', False)
108
+ add_attribute_info = kwargs.get('add_attribute_info', False)
109
+ highlight_deprecated_attributes = kwargs.get('highlight_deprecated_attributes', False)
110
+ amount_of_examples = kwargs.get('amount_of_examples', 0)
111
+ wb = load_workbook(temporary_path)
112
+ wb.create_sheet('Keuzelijsten')
113
+ # Volgorde is belangrijk! Eerst rijen verwijderen indien nodig dan choice list toevoegen,
114
+ # staat namelijk vast op de kolom en niet het attribuut in die kolom
115
+ if add_geo_artefact is False:
116
+ cls.remove_geo_artefact_excel(workbook=wb)
117
+ if generate_choice_list:
118
+ cls.add_choice_list_excel(workbook=wb, instantiated_attributes=instantiated_attributes,
119
+ path_to_subset=path_to_subset)
120
+ cls.add_mock_data_excel(workbook=wb, rows_of_examples=amount_of_examples)
121
+ if highlight_deprecated_attributes:
122
+ cls.check_for_deprecated_attributes(workbook=wb, instantiated_attributes=instantiated_attributes)
123
+ if add_attribute_info:
124
+ cls.add_attribute_info_excel(workbook=wb, instantiated_attributes=instantiated_attributes)
125
+ cls.design_workbook_excel(workbook=wb)
126
+ wb.save(path_to_template_file_and_extension)
127
+ file_location = os.path.dirname(temporary_path)
128
+ [f.unlink() for f in Path(file_location).glob("*") if f.is_file()]
129
+
130
+ def determine_multiplicity_csv(self, path_to_template_file_and_extension: Path, path_to_subset: Path,
131
+ instantiated_attributes: List, temporary_path: Path, **kwargs):
132
+ path_is_split = kwargs.get('split_per_type', True)
133
+ if path_is_split is False:
134
+ self.alter_csv_template(path_to_template_file_and_extension=path_to_template_file_and_extension,
135
+ temporary_path=temporary_path, path_to_subset=path_to_subset, **kwargs)
136
+ else:
137
+ self.multiple_csv_template(path_to_template_file_and_extension=path_to_template_file_and_extension,
138
+ temporary_path=temporary_path,
139
+ path_to_subset=path_to_subset, instantiated_attributes=instantiated_attributes,
140
+ **kwargs)
141
+ file_location = os.path.dirname(temporary_path)
142
+ [f.unlink() for f in Path(file_location).glob("*") if f.is_file()]
143
+
144
+ @classmethod
145
+ def filters_assets_by_subset(cls, path_to_subset: Path, list_of_otl_objectUri: [str] = None):
146
+ if list_of_otl_objectUri is None:
147
+ list_of_otl_objectUri = []
148
+
149
+ collector = cls._load_collector_from_subset_path(path_to_subset=path_to_subset)
150
+ if list_of_otl_objectUri == []:
151
+ return [x for x in collector.classes]
152
+ return [x for x in collector.classes if x.objectUri in list_of_otl_objectUri]
153
+
154
+ @staticmethod
155
+ def _try_getting_settings_of_converter() -> Path:
156
+ converter_path = Path(site.getsitepackages()[0]) / 'otlmow_converter'
157
+ return converter_path / 'settings_otlmow_converter.json'
158
+
159
+ @classmethod
160
+ def design_workbook_excel(cls, workbook):
161
+ for sheet in workbook:
162
+ dim_holder = DimensionHolder(worksheet=sheet)
163
+ for col in range(sheet.min_column, sheet.max_column + 1):
164
+ dim_holder[get_column_letter(col)] = ColumnDimension(sheet, min=col, max=col, width=20)
165
+ sheet.column_dimensions = dim_holder
166
+
167
+ @classmethod
168
+ def add_attribute_info_excel(cls, workbook, instantiated_attributes: List):
169
+ dotnotation_module = DotnotationHelper()
170
+ for sheet in workbook:
171
+ if sheet == workbook['Keuzelijsten']:
172
+ break
173
+ filter_uri = SubsetTemplateCreator.find_uri_in_sheet(sheet)
174
+ single_attribute = next(x for x in instantiated_attributes if x.typeURI == filter_uri)
175
+ sheet.insert_rows(1)
176
+ for rows in sheet.iter_rows(min_row=2, max_row=2, min_col=1):
177
+ for cell in rows:
178
+ if cell.value == 'typeURI':
179
+ value = 'De URI van het object volgens https://www.w3.org/2001/XMLSchema#anyURI .'
180
+ elif cell.value.find('[DEPRECATED]') != -1:
181
+ strip = cell.value.split(' ')
182
+ dotnotation_attribute = dotnotation_module.get_attribute_by_dotnotation(single_attribute,
183
+ strip[1])
184
+ value = dotnotation_attribute.definition
185
+ else:
186
+ dotnotation_attribute = dotnotation_module.get_attribute_by_dotnotation(single_attribute,
187
+ cell.value)
188
+ value = dotnotation_attribute.definition
189
+
190
+ sheet.cell(row=1, column=cell.column, value=value)
191
+ sheet.cell(row=1, column=cell.column).fill = PatternFill(start_color="808080", end_color="808080",
192
+ fill_type="solid")
193
+
194
+ @classmethod
195
+ def check_for_deprecated_attributes(cls, workbook, instantiated_attributes: List):
196
+ dotnotation_module = DotnotationHelper()
197
+ for sheet in workbook:
198
+ if sheet == workbook['Keuzelijsten']:
199
+ break
200
+ filter_uri = SubsetTemplateCreator.find_uri_in_sheet(sheet)
201
+ single_attribute = next(x for x in instantiated_attributes if x.typeURI == filter_uri)
202
+ for rows in sheet.iter_rows(min_row=1, max_row=1, min_col=2):
203
+ for cell in rows:
204
+ is_deprecated = False
205
+ if cell.value.count('.') == 1:
206
+ dot_split = cell.value.split('.')
207
+ attribute = dotnotation_module.get_attribute_by_dotnotation(single_attribute,
208
+ dot_split[0])
209
+
210
+ if len(attribute.deprecated_version) > 0:
211
+ is_deprecated = True
212
+ dotnotation_attribute = dotnotation_module.get_attribute_by_dotnotation(single_attribute,
213
+ cell.value)
214
+ if len(dotnotation_attribute.deprecated_version) > 0:
215
+ is_deprecated = True
216
+
217
+ if is_deprecated:
218
+ cell.value = '[DEPRECATED] ' + cell.value
219
+
220
+ @classmethod
221
+ def find_uri_in_sheet(cls, sheet):
222
+ filter_uri = None
223
+ for row in sheet.iter_rows(min_row=1, max_row=1):
224
+ for cell in row:
225
+ if cell.value == 'typeURI':
226
+ row_index = cell.row
227
+ column_index = cell.column
228
+ filter_uri = sheet.cell(row=row_index + 1, column=column_index).value
229
+ return filter_uri
230
+
231
+ @classmethod
232
+ def remove_geo_artefact_excel(cls, workbook):
233
+ for sheet in workbook:
234
+ for row in sheet.iter_rows(min_row=1, max_row=1):
235
+ for cell in row:
236
+ if cell.value == 'geometry':
237
+ sheet.delete_cols(cell.column)
238
+
239
+ @classmethod
240
+ def add_choice_list_excel(cls, workbook, instantiated_attributes: List, path_to_subset: Path):
241
+ choice_list_dict = {}
242
+ dotnotation_module = DotnotationHelper()
243
+ for sheet in workbook:
244
+ if sheet == workbook['Keuzelijsten']:
245
+ break
246
+ filter_uri = SubsetTemplateCreator.find_uri_in_sheet(sheet)
247
+ single_attribute = next(x for x in instantiated_attributes if x.typeURI == filter_uri)
248
+ for rows in sheet.iter_rows(min_row=1, max_row=1, min_col=2):
249
+ for cell in rows:
250
+ if cell.value.find('[DEPRECATED]') != -1:
251
+ strip = cell.value.split(' ')
252
+ dotnotation_attribute = dotnotation_module.get_attribute_by_dotnotation(single_attribute,
253
+ strip[1])
254
+ else:
255
+ dotnotation_attribute = dotnotation_module.get_attribute_by_dotnotation(single_attribute,
256
+ cell.value)
257
+
258
+ if issubclass(dotnotation_attribute.field, KeuzelijstField):
259
+ name = dotnotation_attribute.field.naam
260
+ valid_options = [v.invulwaarde for k, v in dotnotation_attribute.field.options.items()
261
+ if v.status != 'verwijderd']
262
+ if dotnotation_attribute.field.naam in choice_list_dict:
263
+ column = choice_list_dict[dotnotation_attribute.field.naam]
264
+ else:
265
+ choice_list_dict = cls.add_choice_list_to_sheet(workbook=workbook, name=name,
266
+ options=valid_options,
267
+ choice_list_dict=choice_list_dict)
268
+ column = choice_list_dict[dotnotation_attribute.field.naam]
269
+ print(column)
270
+ option_list = []
271
+ for option in valid_options:
272
+ option_list.append(option)
273
+ start_range = f"${column}$2"
274
+ end_range = f"${column}${len(valid_options) + 1}"
275
+ data_val = DataValidation(type="list", formula1=f"Keuzelijsten!{start_range}:{end_range}",
276
+ allowBlank=True)
277
+ sheet.add_data_validation(data_val)
278
+ data_val.add(f'{get_column_letter(cell.column)}2:{get_column_letter(cell.column)}1000')
279
+ if issubclass(dotnotation_attribute.field, BooleanField):
280
+ data_validation = DataValidation(type="list", formula1='"TRUE,FALSE,-"', allow_blank=True)
281
+ column = cell.column
282
+ sheet.add_data_validation(data_validation)
283
+ data_validation.add(f'{get_column_letter(column)}2:{get_column_letter(column)}1000')
284
+ sheet.add_data_validation(data_validation)
285
+
286
+ @classmethod
287
+ def add_mock_data_excel(cls, workbook, rows_of_examples: int):
288
+ for sheet in workbook:
289
+ if sheet == workbook["Keuzelijsten"]:
290
+ break
291
+ if rows_of_examples == 0:
292
+ for rows in sheet.iter_rows(min_row=2, max_row=2):
293
+ for cell in rows:
294
+ cell.value = ''
295
+
296
+ @classmethod
297
+ def remove_geo_artefact_csv(cls, header, data):
298
+ if 'geometry' in header:
299
+ deletion_index = header.index('geometry')
300
+ header.remove('geometry')
301
+ for d in data:
302
+ d.pop(deletion_index)
303
+ return [header, data]
304
+
305
+ @classmethod
306
+ def multiple_csv_template(cls, path_to_template_file_and_extension, path_to_subset, temporary_path,
307
+ instantiated_attributes, **kwargs):
308
+ file_location = os.path.dirname(path_to_template_file_and_extension)
309
+ tempdir = Path(tempfile.gettempdir()) / 'temp-otlmow'
310
+ print(file_location)
311
+ file_name = ntpath.basename(path_to_template_file_and_extension)
312
+ split_file_name = file_name.split('.')
313
+ things_in_there = os.listdir(tempdir)
314
+ csv_templates = [x for x in things_in_there if x.startswith(split_file_name[0] + '_')]
315
+ print(csv_templates)
316
+ for file in csv_templates:
317
+ test_template_loc = Path(os.path.dirname(path_to_template_file_and_extension)) / file
318
+ temp_loc = Path(tempdir) / file
319
+ cls.alter_csv_template(path_to_template_file_and_extension=test_template_loc, temporary_path=temp_loc,
320
+ path_to_subset=path_to_subset, **kwargs)
321
+
322
+ @classmethod
323
+ def alter_csv_template(cls, path_to_template_file_and_extension, path_to_subset, temporary_path,
324
+ **kwargs):
325
+ converter = OtlmowConverter()
326
+ instantiated_attributes = converter.from_file_to_objects(file_path=temporary_path,
327
+ path_to_subset=path_to_subset)
328
+ header = []
329
+ data = []
330
+ delimiter = ';'
331
+ add_geo_artefact = kwargs.get('add_geo_artefact', False)
332
+ add_attribute_info = kwargs.get('add_attribute_info', False)
333
+ highlight_deprecated_attributes = kwargs.get('highlight_deprecated_attributes', False)
334
+ amount_of_examples = kwargs.get('amount_of_examples', 0)
335
+ quote_char = '"'
336
+ with open(temporary_path, 'r+', encoding='utf-8') as csvfile:
337
+ new_file = open(path_to_template_file_and_extension, 'w', encoding='utf-8')
338
+ reader = csv.reader(csvfile, delimiter=delimiter, quotechar=quote_char)
339
+ for row_nr, row in enumerate(reader):
340
+ if row_nr == 0:
341
+ header = row
342
+ else:
343
+ data.append(row)
344
+ if add_geo_artefact is False:
345
+ [header, data] = cls.remove_geo_artefact_csv(header=header, data=data)
346
+ if add_attribute_info:
347
+ [info, header] = cls.add_attribute_info_csv(header=header, data=data,
348
+ instantiated_attributes=instantiated_attributes)
349
+ new_file.write(delimiter.join(info) + '\n')
350
+ data = cls.add_mock_data_csv(header=header, data=data, rows_of_examples=amount_of_examples)
351
+ if highlight_deprecated_attributes:
352
+ header = cls.highlight_deprecated_attributes_csv(header=header, data=data,
353
+ instantiated_attributes=instantiated_attributes)
354
+ new_file.write(delimiter.join(header) + '\n')
355
+ for d in data:
356
+ new_file.write(delimiter.join(d) + '\n')
357
+ new_file.close()
358
+
359
+ @classmethod
360
+ def add_attribute_info_csv(cls, header, data, instantiated_attributes):
361
+ info_data = []
362
+ info_data.extend(header)
363
+ found_uri = []
364
+ dotnotation_module = DotnotationHelper()
365
+ uri_index = cls.find_uri_in_csv(header)
366
+ for d in data:
367
+ if d[uri_index] not in found_uri:
368
+ found_uri.append(d[uri_index])
369
+ for uri in found_uri:
370
+ single_object = next(x for x in instantiated_attributes if x.typeURI == uri)
371
+ for dotnototation_title in info_data:
372
+ if dotnototation_title == 'typeURI':
373
+ index = info_data.index(dotnototation_title)
374
+ info_data[index] = 'De URI van het object volgens https://www.w3.org/2001/XMLSchema#anyURI .'
375
+ else:
376
+ index = info_data.index(dotnototation_title)
377
+ try:
378
+ dotnotation_attribute = dotnotation_module.get_attribute_by_dotnotation(
379
+ single_object, dotnototation_title)
380
+ except AttributeError as e:
381
+ continue
382
+ info_data[index] = dotnotation_attribute.definition
383
+ return [info_data, header]
384
+
385
+ @classmethod
386
+ def add_mock_data_csv(cls, header, data, rows_of_examples):
387
+ if rows_of_examples == 0:
388
+ data = []
389
+ return data
390
+
391
+ @classmethod
392
+ def highlight_deprecated_attributes_csv(cls, header, data, instantiated_attributes):
393
+ found_uri = []
394
+ dotnotation_module = DotnotationHelper()
395
+ uri_index = cls.find_uri_in_csv(header)
396
+ for d in data:
397
+ if d[uri_index] not in found_uri:
398
+ found_uri.append(d[uri_index])
399
+ for uri in found_uri:
400
+ single_object = next(x for x in instantiated_attributes if x.typeURI == uri)
401
+ for dotnototation_title in header:
402
+ if dotnototation_title == 'typeURI':
403
+ continue
404
+ else:
405
+ index = header.index(dotnototation_title)
406
+ value = header[index]
407
+ try:
408
+ is_deprecated = False
409
+ if dotnototation_title.count('.') == 1:
410
+ dot_split = dotnototation_title.split('.')
411
+ attribute = dotnotation_module.get_attribute_by_dotnotation(single_object,
412
+ dot_split[0])
413
+
414
+ if len(attribute.deprecated_version) > 0:
415
+ is_deprecated = True
416
+ dotnotation_attribute = dotnotation_module.get_attribute_by_dotnotation(single_object,
417
+ dotnototation_title)
418
+ if len(dotnotation_attribute.deprecated_version) > 0:
419
+ is_deprecated = True
420
+ except AttributeError:
421
+ continue
422
+ if is_deprecated:
423
+ header[index] = "[DEPRECATED] " + value
424
+ return header
425
+
426
+ @classmethod
427
+ def find_uri_in_csv(cls, header):
428
+ filter_uri = None
429
+ if 'typeURI' in header:
430
+ filter_uri = header.index('typeURI')
431
+ return filter_uri
432
+
433
+ @classmethod
434
+ def add_choice_list_to_sheet(cls, workbook, name, options, choice_list_dict):
435
+ active_sheet = workbook['Keuzelijsten']
436
+ print(options)
437
+ row_nr = 2
438
+ for rows in active_sheet.iter_rows(min_row=1, max_row=1, min_col=1, max_col=700):
439
+ for cell in rows:
440
+ if cell.value is None:
441
+ cell.value = name
442
+ column_nr = cell.column
443
+ for option in options:
444
+ print(option)
445
+ active_sheet.cell(row=row_nr, column=column_nr, value=option)
446
+ row_nr += 1
447
+ print(row_nr)
448
+ choice_list_dict[name] = get_column_letter(column_nr)
449
+ break
450
+ return choice_list_dict
451
+
452
+
453
+ if __name__ == '__main__':
454
+ subset_tool = SubsetTemplateCreator()
455
+ subset_location = Path(ROOT_DIR) / 'UnitTests' / 'Subset' / 'Flitspaal_noAgent3.0.db'
456
+ # directory = Path(ROOT_DIR) / 'UnitTests' / 'TestClasses'
457
+ # Slash op het einde toevoegen verandert weinig of niks aan het resultaat
458
+ # directory = os.path.join(directory, '')
459
+ xls_location = Path(ROOT_DIR) / 'UnitTests' / 'Subset' / 'testFileStorage' / 'template_file.csv'
460
+ subset_tool.generate_template_from_subset(path_to_subset=subset_location,
461
+ path_to_template_file_and_extension=xls_location, add_attribute_info=True,
462
+ highlight_deprecated_attributes=True,
463
+ amount_of_examples=5,
464
+ generate_choice_list=True,
465
+ split_per_type=False)
File without changes
@@ -1,7 +1,7 @@
1
1
  Metadata-Version: 2.1
2
- Name: otlmow-template
3
- Version: 0.2
4
- Author-email: David Vlaminck <david.vlaminck@mow.vlaanderen.be>
2
+ Name: otlmow_template
3
+ Version: 0.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
7
7
 
@@ -679,19 +679,49 @@ License: GNU GENERAL PUBLIC LICENSE
679
679
  Project-URL: Homepage, https://github.com/davidvlaminck/OTLMOW-Template
680
680
  Project-URL: Bug Tracker, https://github.com/davidvlaminck/OTLMOW-Template/issues
681
681
  Classifier: Programming Language :: Python :: 3
682
+ Classifier: Programming Language :: Python :: 3.8
683
+ Classifier: Programming Language :: Python :: 3.9
684
+ Classifier: Programming Language :: Python :: 3.10
685
+ Classifier: Programming Language :: Python :: 3.11
682
686
  Classifier: Operating System :: OS Independent
687
+ Classifier: Development Status :: 5 - Production/Stable
688
+ Classifier: Environment :: Console
689
+ Classifier: Intended Audience :: Developers
690
+ Classifier: Intended Audience :: Information Technology
691
+ Classifier: License :: OSI Approved :: GNU General Public License v3 (GPLv3)
692
+ Classifier: Natural Language :: Dutch
693
+ Classifier: Topic :: Software Development
694
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
695
+ Classifier: Topic :: Software Development :: Quality Assurance
683
696
  Requires-Python: >=3.8
684
697
  Description-Content-Type: text/markdown
685
698
  License-File: LICENSE
699
+ Requires-Dist: otlmow-converter>=0.14
700
+ Requires-Dist: otlmow-modelbuilder>=0.11
686
701
 
687
702
  # OTLMOW-Template
703
+ [![PyPI](https://img.shields.io/pypi/v/otlmow-template?label=latest%20release)](https://pypi.org/project/otlmow-template/)
704
+ [![otlmow-template-downloads](https://img.shields.io/pypi/dm/otlmow-template)](https://pypi.org/project/otlmow-template/)
705
+ [![Unittests](https://github.com/davidvlaminck/otlmow-template/actions/workflows/unittest.yml/badge.svg)](https://github.com/davidvlaminck/otlmow-template/actions/workflows/unittest.yml)
706
+ ![PyPI - Python Version](https://img.shields.io/pypi/pyversions/otlmow-template)
707
+ [![GitHub issues](https://img.shields.io/github/issues/davidvlaminck/otlmow-template)](https://github.com/davidvlaminck/otlmow-template/issues)
708
+ [![coverage](https://github.com/davidvlaminck/otlmow-template/blob/master/UnitTests/coverage.svg)](https://htmlpreview.github.io/?https://github.com/davidvlaminck/otlmow-template/blob/master/UnitTests/htmlcov/index.html)
709
+
710
+
711
+ ## Summary
712
+ The main use case of otlmow-template is to provide templates for the users, depending on a given subset.
713
+
688
714
  ## OTLMOW Project
689
715
  This project aims to implement the Flemish data standard OTL (https://wegenenverkeer.data.vlaanderen.be/) in Python.
690
716
  It is split into different packages to reduce compatibility issues
691
- - otlmow_model
692
- - otlmow_modelbuilder
693
- - otlmow_converter
694
- - otlmow_template (you are currently looking at this package)
717
+ - [otlmow_model](https://github.com/davidvlaminck/OTLMOW-Model)
718
+ - [otlmow_modelbuilder](https://github.com/davidvlaminck/OTLMOW-ModelBuilder)
719
+ - [otlmow_converter](https://github.com/davidvlaminck/OTLMOW-Converter)
720
+ - [otlmow_template](https://github.com/davidvlaminck/OTLMOW-Template) (you are currently looking at this package)
721
+ - [otlmow_postenmapping](https://github.com/davidvlaminck/OTLMOW-PostenMapping)
722
+ - [otlmow_davie](https://github.com/davidvlaminck/OTLMOW-DAVIE)
723
+ - [otlmow_visuals](https://github.com/davidvlaminck/OTLMOW-Visuals)
724
+ - [otlmow_gui](https://github.com/davidvlaminck/OTLMOW-GUI)
695
725
 
696
726
  ## Installation and requirements
697
727
  Currently, you need at least Python version 3.8 to use this library.
@@ -1,9 +1,13 @@
1
1
  LICENSE
2
2
  README.md
3
3
  pyproject.toml
4
+ otlmow_template/CsvTemplateCreator.py
5
+ otlmow_template/ExcelTemplateCreator.py
4
6
  otlmow_template/SubsetTemplateCreator.py
7
+ otlmow_template/__init__.py
5
8
  otlmow_template.egg-info/PKG-INFO
6
9
  otlmow_template.egg-info/SOURCES.txt
7
10
  otlmow_template.egg-info/dependency_links.txt
8
11
  otlmow_template.egg-info/requires.txt
9
- otlmow_template.egg-info/top_level.txt
12
+ otlmow_template.egg-info/top_level.txt
13
+ otlmow_template/Exceptions/MissingTypeUriException.py
@@ -0,0 +1,2 @@
1
+ otlmow-converter>=0.14
2
+ otlmow-modelbuilder>=0.11
@@ -0,0 +1,40 @@
1
+ [build-system]
2
+ requires = ["setuptools", "wheel"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "otlmow_template"
7
+ version = "0.4"
8
+ authors = [{name = "David Vlaminck", email = "david.vlaminck@mow.vlaanderen.be"},
9
+ {name = "Jasper Berton", email = "jasperberton1@telenet.be"}]
10
+ readme = "README.md"
11
+ license = {file = "LICENSE"}
12
+ classifiers = [
13
+ "Programming Language :: Python :: 3",
14
+ "Programming Language :: Python :: 3.8",
15
+ "Programming Language :: Python :: 3.9",
16
+ "Programming Language :: Python :: 3.10",
17
+ "Programming Language :: Python :: 3.11",
18
+ "Operating System :: OS Independent",
19
+ "Development Status :: 5 - Production/Stable",
20
+ "Environment :: Console",
21
+ "Intended Audience :: Developers",
22
+ "Intended Audience :: Information Technology",
23
+ "License :: OSI Approved :: GNU General Public License v3 (GPLv3)",
24
+ "Natural Language :: Dutch",
25
+ "Topic :: Software Development",
26
+ "Topic :: Software Development :: Libraries :: Python Modules",
27
+ "Topic :: Software Development :: Quality Assurance",
28
+ ]
29
+ requires-python = ">=3.8"
30
+ dependencies = [
31
+ 'otlmow-converter >= 0.14',
32
+ 'otlmow-modelbuilder >= 0.11',
33
+ ]
34
+
35
+ [tool.setuptools.packages.find]
36
+ include = ["otlmow_template*"]
37
+
38
+ [project.urls]
39
+ "Homepage" = "https://github.com/davidvlaminck/OTLMOW-Template"
40
+ "Bug Tracker" = "https://github.com/davidvlaminck/OTLMOW-Template/issues"
@@ -1,23 +0,0 @@
1
- # OTLMOW-Template
2
- ## OTLMOW Project
3
- This project aims to implement the Flemish data standard OTL (https://wegenenverkeer.data.vlaanderen.be/) in Python.
4
- It is split into different packages to reduce compatibility issues
5
- - otlmow_model
6
- - otlmow_modelbuilder
7
- - otlmow_converter
8
- - otlmow_template (you are currently looking at this package)
9
-
10
- ## Installation and requirements
11
- Currently, you need at least Python version 3.8 to use this library.
12
-
13
- To install the OTL MOW project into your Python project, use pip to install it:
14
- ```
15
- pip install otlmow_template
16
- ```
17
- To upgrade an existing installation use:
18
- ```
19
- pip install otlmow_template --upgrade
20
- ```
21
-
22
- ## Usage
23
- #TODO
@@ -1,79 +0,0 @@
1
- import json
2
- import os
3
- import site
4
- from os.path import abspath
5
- from pathlib import Path
6
- from typing import List
7
-
8
- from otlmow_converter.AssetFactory import AssetFactory
9
- from otlmow_converter.FileExporter import FileExporter
10
- from otlmow_modelbuilder.OSLOInMemoryCreator import OSLOInMemoryCreator
11
- from otlmow_modelbuilder.SQLDataClasses.OSLOCollector import OSLOCollector
12
- from otlmow_modelbuilder.SQLDbReader import SQLDbReader
13
-
14
-
15
- class SubsetTemplateCreator:
16
- def __init__(self, settings_path: Path = None):
17
- if settings_path is None:
18
- settings_path = self._try_getting_settings_of_converter()
19
- if settings_path is None:
20
- raise FileNotFoundError(
21
- "Instantiating this class requires a settings file. Please give a valid path to a settings file")
22
- self.settings: dict = {}
23
- self._load_settings(settings_path)
24
-
25
- def _load_settings(self, settings_path):
26
- if settings_path == '':
27
- current_file_path = Path(__file__)
28
- directory = current_file_path.parents[0]
29
- settings_path = abspath(f'{directory}\\settings_sample.json')
30
-
31
- if not os.path.isfile(settings_path):
32
- raise FileNotFoundError(settings_path + " is not a valid path. File does not exist.")
33
-
34
- try:
35
- with open(settings_path) as settings_file:
36
- self.settings = json.load(settings_file)
37
- except OSError:
38
- raise ImportError(f'Could not open the settings file at {settings_file}')
39
-
40
- @staticmethod
41
- def _load_collector_from_subset_path(path_to_subset: Path) -> OSLOCollector:
42
- sql_reader = SQLDbReader(path_to_subset)
43
- oslo_creator = OSLOInMemoryCreator(sql_reader)
44
- collector = OSLOCollector(oslo_creator)
45
- collector.collect(include_abstract=True)
46
- return collector
47
-
48
- def generate_template_from_subset(self, path_to_subset: Path, path_to_template_file_and_extension: Path,
49
- **kwargs):
50
- collector = self._load_collector_from_subset_path(path_to_subset=path_to_subset)
51
- otl_objects = []
52
-
53
- for class_object in list(filter(lambda cl: cl.abstract == 0, collector.classes)):
54
- class_directory = None
55
- if kwargs is not None and 'class_directory' in kwargs:
56
- class_directory = kwargs['class_directory']
57
- instance = AssetFactory.dynamic_create_instance_from_uri(class_object.objectUri, directory=class_directory)
58
- if instance is None:
59
- continue
60
- instance._assetId.fill_with_dummy_data()
61
- otl_objects.append(instance)
62
-
63
- attributen = collector.find_attributes_by_class(class_object)
64
- for attribute_object in attributen:
65
- attr = getattr(instance, '_' + attribute_object.name)
66
- attr.fill_with_dummy_data()
67
-
68
- exporter = FileExporter(settings=self.settings)
69
- exporter.create_file_from_assets(filepath=path_to_template_file_and_extension,
70
- list_of_objects=otl_objects, **kwargs)
71
-
72
- @classmethod
73
- def filters_assets_by_subset(cls, path_to_subset: Path, list_of_otl_objects: List):
74
- raise NotImplementedError
75
-
76
- @staticmethod
77
- def _try_getting_settings_of_converter() -> Path:
78
- converter_path = Path(site.getsitepackages()[0]) / 'otlmow_converter'
79
- return converter_path / 'settings_otlmow_converter.json'
@@ -1,2 +0,0 @@
1
- otlmow_converter>=0.5
2
- otlmow_modelbuilder>=0.3
@@ -1,26 +0,0 @@
1
- [build-system]
2
- requires = ["setuptools", "wheel"]
3
- build-backend = "setuptools.build_meta"
4
-
5
- [project]
6
- name = "otlmow_template"
7
- version = "0.2"
8
- authors = [{name = "David Vlaminck", email = "david.vlaminck@mow.vlaanderen.be"}]
9
- readme = "README.md"
10
- license = {file = "LICENSE"}
11
- classifiers = [
12
- "Programming Language :: Python :: 3",
13
- "Operating System :: OS Independent"
14
- ]
15
- requires-python = ">=3.8"
16
- dependencies = [
17
- 'otlmow_converter >= 0.5',
18
- 'otlmow_modelbuilder >= 0.3',
19
- ]
20
-
21
- [tool.setuptools.packages.find]
22
- include = ["otlmow_template*"]
23
-
24
- [project.urls]
25
- "Homepage" = "https://github.com/davidvlaminck/OTLMOW-Template"
26
- "Bug Tracker" = "https://github.com/davidvlaminck/OTLMOW-Template/issues"
File without changes
File without changes