bcf-api-xml 0.4.15__tar.gz → 0.4.16__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.
- {bcf_api_xml-0.4.15 → bcf_api_xml-0.4.16}/PKG-INFO +4 -1
- {bcf_api_xml-0.4.15 → bcf_api_xml-0.4.16}/README.md +2 -0
- {bcf_api_xml-0.4.15 → bcf_api_xml-0.4.16}/bcf_api_xml/__init__.py +2 -2
- {bcf_api_xml-0.4.15 → bcf_api_xml-0.4.16}/bcf_api_xml/export/excel.py +69 -32
- {bcf_api_xml-0.4.15 → bcf_api_xml-0.4.16}/pyproject.toml +1 -1
- {bcf_api_xml-0.4.15 → bcf_api_xml-0.4.16}/bcf_api_xml/Schemas/bcf.version +0 -0
- {bcf_api_xml-0.4.15 → bcf_api_xml-0.4.16}/bcf_api_xml/Schemas/markup.xsd +0 -0
- {bcf_api_xml-0.4.15 → bcf_api_xml-0.4.16}/bcf_api_xml/Schemas/project.xsd +0 -0
- {bcf_api_xml-0.4.15 → bcf_api_xml-0.4.16}/bcf_api_xml/Schemas/version.xsd +0 -0
- {bcf_api_xml-0.4.15 → bcf_api_xml-0.4.16}/bcf_api_xml/Schemas/visinfo.xsd +0 -0
- {bcf_api_xml-0.4.15 → bcf_api_xml-0.4.16}/bcf_api_xml/errors.py +0 -0
- {bcf_api_xml-0.4.15 → bcf_api_xml-0.4.16}/bcf_api_xml/export/__init__.py +0 -0
- {bcf_api_xml-0.4.15 → bcf_api_xml-0.4.16}/bcf_api_xml/export/zip.py +0 -0
- {bcf_api_xml-0.4.15 → bcf_api_xml-0.4.16}/bcf_api_xml/import_zip.py +0 -0
- {bcf_api_xml-0.4.15 → bcf_api_xml-0.4.16}/bcf_api_xml/models/ClippingPlane.py +0 -0
- {bcf_api_xml-0.4.15 → bcf_api_xml-0.4.16}/bcf_api_xml/models/Color.py +0 -0
- {bcf_api_xml-0.4.15 → bcf_api_xml-0.4.16}/bcf_api_xml/models/Comment.py +0 -0
- {bcf_api_xml-0.4.15 → bcf_api_xml-0.4.16}/bcf_api_xml/models/Component.py +0 -0
- {bcf_api_xml-0.4.15 → bcf_api_xml-0.4.16}/bcf_api_xml/models/Line.py +0 -0
- {bcf_api_xml-0.4.15 → bcf_api_xml-0.4.16}/bcf_api_xml/models/OrthogonalCamera.py +0 -0
- {bcf_api_xml-0.4.15 → bcf_api_xml-0.4.16}/bcf_api_xml/models/PerspectiveCamera.py +0 -0
- {bcf_api_xml-0.4.15 → bcf_api_xml-0.4.16}/bcf_api_xml/models/Topic.py +0 -0
- {bcf_api_xml-0.4.15 → bcf_api_xml-0.4.16}/bcf_api_xml/models/ViewSetupHints.py +0 -0
- {bcf_api_xml-0.4.15 → bcf_api_xml-0.4.16}/bcf_api_xml/models/Viewpoint.py +0 -0
- {bcf_api_xml-0.4.15 → bcf_api_xml-0.4.16}/bcf_api_xml/models/Visibility.py +0 -0
- {bcf_api_xml-0.4.15 → bcf_api_xml-0.4.16}/bcf_api_xml/models/VisualizationInfo.py +0 -0
- {bcf_api_xml-0.4.15 → bcf_api_xml-0.4.16}/bcf_api_xml/models/XYZ.py +0 -0
- {bcf_api_xml-0.4.15 → bcf_api_xml-0.4.16}/bcf_api_xml/models/__init__.py +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: bcf-api-xml
|
3
|
-
Version: 0.4.
|
3
|
+
Version: 0.4.16
|
4
4
|
Summary: Convert BCF-API to BCF-XML
|
5
5
|
Home-page: https://github.com/bimdata/BCF-API-XML-translator
|
6
6
|
License: MIT
|
@@ -12,6 +12,7 @@ Classifier: Programming Language :: Python :: 3
|
|
12
12
|
Classifier: Programming Language :: Python :: 3.10
|
13
13
|
Classifier: Programming Language :: Python :: 3.11
|
14
14
|
Classifier: Programming Language :: Python :: 3.12
|
15
|
+
Classifier: Programming Language :: Python :: 3.13
|
15
16
|
Requires-Dist: generateDS (>=2.35.13,<3.0.0)
|
16
17
|
Requires-Dist: lxml (>=5.3.1,<6.0.0)
|
17
18
|
Requires-Dist: pillow (>=11.1.0,<12.0.0)
|
@@ -49,6 +50,8 @@ pre-commit install
|
|
49
50
|
```
|
50
51
|
|
51
52
|
# Publish new version
|
53
|
+
Update version number in `pyproject.toml` and `bcf_api_xml/__init__.py` then
|
54
|
+
|
52
55
|
```bash
|
53
56
|
poetry publish --build --username= --password=
|
54
57
|
```
|
@@ -1,7 +1,7 @@
|
|
1
1
|
from bcf_api_xml.errors import InvalidBCF # noqa: F401
|
2
2
|
from bcf_api_xml.errors import UnsupportedBCFVersion # noqa: F401
|
3
|
-
from bcf_api_xml.export import to_zip # noqa: F401
|
4
3
|
from bcf_api_xml.export import to_xlsx # noqa: F401
|
4
|
+
from bcf_api_xml.export import to_zip # noqa: F401
|
5
5
|
from bcf_api_xml.import_zip import to_json # noqa: F401
|
6
6
|
|
7
|
-
__version__ = "0.4.
|
7
|
+
__version__ = "0.4.16"
|
@@ -1,5 +1,6 @@
|
|
1
1
|
import base64
|
2
2
|
import io
|
3
|
+
import string
|
3
4
|
from datetime import datetime
|
4
5
|
|
5
6
|
import requests
|
@@ -8,6 +9,10 @@ from dateutil import parser
|
|
8
9
|
from PIL import Image
|
9
10
|
|
10
11
|
|
12
|
+
def col_to_letter(index):
|
13
|
+
return string.ascii_uppercase[index]
|
14
|
+
|
15
|
+
|
11
16
|
HEADER_TRANSLATIONS = {
|
12
17
|
"en": {
|
13
18
|
"index": "Index",
|
@@ -15,14 +20,15 @@ HEADER_TRANSLATIONS = {
|
|
15
20
|
"author": "Author",
|
16
21
|
"assigned_to": "Assigned to",
|
17
22
|
"title": "Title",
|
18
|
-
"description": "Description
|
23
|
+
"description": "Description",
|
19
24
|
"due_date": "Due date",
|
25
|
+
"stage": "Stage",
|
20
26
|
"status": "Status",
|
21
27
|
"priority": "Priority",
|
22
|
-
"tags": "
|
28
|
+
"tags": "Labels",
|
23
29
|
"comments": "Comments",
|
24
30
|
"viewpoint": "Image",
|
25
|
-
"models": "
|
31
|
+
"models": "Models",
|
26
32
|
"space": "Organisation",
|
27
33
|
"project": "Project",
|
28
34
|
},
|
@@ -32,14 +38,15 @@ HEADER_TRANSLATIONS = {
|
|
32
38
|
"author": "Auteur",
|
33
39
|
"assigned_to": "Assigné à",
|
34
40
|
"title": "Titre",
|
35
|
-
"description": "Description
|
41
|
+
"description": "Description",
|
36
42
|
"due_date": "Date d'échéance",
|
43
|
+
"stage": "Phase",
|
37
44
|
"status": "Statut",
|
38
45
|
"priority": "Priorité",
|
39
46
|
"tags": "Tags",
|
40
|
-
"comments": "
|
47
|
+
"comments": "Commentaires",
|
41
48
|
"viewpoint": "Image",
|
42
|
-
"models": "
|
49
|
+
"models": "Maquettes",
|
43
50
|
"space": "Organisation",
|
44
51
|
"project": "Project",
|
45
52
|
},
|
@@ -53,14 +60,27 @@ TITLE_COL_INDEX = 4
|
|
53
60
|
VIEWPOINT_COL_INDEX = 5
|
54
61
|
DESCRIPTION_COL_INDEX = 6
|
55
62
|
DUE_DATE_COL_INDEX = 7
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
63
|
+
STAGE_COL_INDEX = 8
|
64
|
+
STATUS_COL_INDEX = 9
|
65
|
+
PRIORITY_COL_INDEX = 10
|
66
|
+
LABELS_COL_INDEX = 11
|
67
|
+
COMMENTS_COL_INDEX = 12
|
68
|
+
MODELS_COL_INDEX = 13
|
69
|
+
|
70
|
+
LAST_USED_COL_INDEX = MODELS_COL_INDEX
|
71
|
+
LAST_USED_COL_LETTER = col_to_letter(LAST_USED_COL_INDEX)
|
60
72
|
|
61
73
|
|
62
74
|
def to_xlsx(
|
63
|
-
space,
|
75
|
+
space,
|
76
|
+
project,
|
77
|
+
models,
|
78
|
+
topics,
|
79
|
+
comments,
|
80
|
+
viewpoints,
|
81
|
+
company_logo_content,
|
82
|
+
lang="en",
|
83
|
+
sheetname=None,
|
64
84
|
):
|
65
85
|
"""
|
66
86
|
topics: list of topics (dict parsed from BCF-API json)
|
@@ -69,7 +89,10 @@ def to_xlsx(
|
|
69
89
|
"""
|
70
90
|
xls_file = io.BytesIO()
|
71
91
|
with xlsxwriter.Workbook(xls_file, options={"remove_timezone": True}) as workbook:
|
72
|
-
|
92
|
+
if sheetname:
|
93
|
+
worksheet = workbook.add_worksheet(sheetname)
|
94
|
+
else:
|
95
|
+
worksheet = workbook.add_worksheet()
|
73
96
|
|
74
97
|
# Set default height for tables
|
75
98
|
DEFAULT_CELL_HEIGHT = 220
|
@@ -86,22 +109,30 @@ def to_xlsx(
|
|
86
109
|
|
87
110
|
# Set image cell width
|
88
111
|
IMAGE_COLUMN_WIDTH = 220
|
89
|
-
worksheet.set_column_pixels(
|
112
|
+
worksheet.set_column_pixels(
|
113
|
+
VIEWPOINT_COL_INDEX, VIEWPOINT_COL_INDEX, IMAGE_COLUMN_WIDTH
|
114
|
+
)
|
90
115
|
|
91
116
|
header_fmt = workbook.add_format(
|
92
|
-
{
|
117
|
+
{
|
118
|
+
"valign": "vcenter",
|
119
|
+
"align": "center",
|
120
|
+
"bold": True,
|
121
|
+
"bg_color": "#C0C0C0",
|
122
|
+
"border": 1,
|
123
|
+
}
|
93
124
|
)
|
94
125
|
base_fmt = workbook.add_format({"valign": "top", "border": 1})
|
95
126
|
if lang == "fr":
|
96
127
|
date_fmt = workbook.add_format(
|
97
|
-
{"valign": "top", "num_format": "dd/mm/yyyy", "border": 1}
|
128
|
+
{"align": "left", "valign": "top", "num_format": "dd/mm/yyyy", "border": 1}
|
98
129
|
)
|
99
130
|
else:
|
100
131
|
date_fmt = workbook.add_format(
|
101
|
-
{"valign": "top", "num_format": "yyyy-mm-dd", "border": 1}
|
132
|
+
{"align": "left", "valign": "top", "num_format": "yyyy-mm-dd", "border": 1}
|
102
133
|
)
|
103
134
|
|
104
|
-
|
135
|
+
text_wrap_fmt = workbook.add_format({"valign": "top", "text_wrap": True, "border": 1})
|
105
136
|
header_fmt2 = workbook.add_format({"border": 1})
|
106
137
|
base_fm_align = workbook.add_format({"align": "center", "valign": "top"})
|
107
138
|
|
@@ -152,31 +183,29 @@ def to_xlsx(
|
|
152
183
|
},
|
153
184
|
)
|
154
185
|
|
155
|
-
worksheet.merge_range("D1:
|
186
|
+
worksheet.merge_range(f"D1:{LAST_USED_COL_LETTER}1", "", merge_format_gray)
|
156
187
|
row += 1
|
157
188
|
worksheet.set_row(row, 20)
|
158
|
-
worksheet.merge_range("A2:
|
189
|
+
worksheet.merge_range(f"A2:{LAST_USED_COL_LETTER}2", "", merge_format_default)
|
159
190
|
row += 1
|
160
191
|
worksheet.set_row_pixels(row, ROW_HEIGHT)
|
161
192
|
worksheet.merge_range("A3:B3", "", merge_format_default)
|
162
193
|
worksheet.write(row, 0, headers["project"], header_fmt)
|
163
|
-
worksheet.merge_range("C3:
|
194
|
+
worksheet.merge_range(f"C3:{LAST_USED_COL_LETTER}3", "", merge_format_default)
|
164
195
|
worksheet.write(row, 2, project["name"], header_fmt2)
|
165
196
|
|
166
|
-
# TODO: add spreadsheet metadata for models
|
167
|
-
|
168
197
|
row += 1
|
169
198
|
worksheet.set_row_pixels(row, ROW_HEIGHT)
|
170
199
|
worksheet.merge_range("A4:B4", "", merge_format_default)
|
171
200
|
worksheet.write(row, 0, headers["space"], header_fmt)
|
172
|
-
worksheet.merge_range("C4:
|
201
|
+
worksheet.merge_range(f"C4:{LAST_USED_COL_LETTER}4", "", merge_format_default)
|
173
202
|
worksheet.write(row, 2, space["name"], header_fmt2)
|
174
203
|
|
175
204
|
row += 1
|
176
205
|
worksheet.set_row_pixels(row, ROW_HEIGHT)
|
177
206
|
worksheet.merge_range("A5:B5", "", merge_format_default)
|
178
207
|
worksheet.write(row, 0, "Date", header_fmt)
|
179
|
-
worksheet.merge_range("C5:
|
208
|
+
worksheet.merge_range(f"C5:{LAST_USED_COL_LETTER}5", "", merge_format_default)
|
180
209
|
if lang == "fr":
|
181
210
|
current_time = datetime.now().strftime("%d/%m/%Y, %H:%M:%S")
|
182
211
|
else:
|
@@ -185,7 +214,7 @@ def to_xlsx(
|
|
185
214
|
|
186
215
|
row += 1
|
187
216
|
worksheet.set_row(row, 20)
|
188
|
-
worksheet.merge_range("A6:
|
217
|
+
worksheet.merge_range(f"A6:{LAST_USED_COL_LETTER}6", "", merge_format_default)
|
189
218
|
row += 1
|
190
219
|
|
191
220
|
# Set topic row height
|
@@ -194,18 +223,21 @@ def to_xlsx(
|
|
194
223
|
# Create table header
|
195
224
|
worksheet.write(row, INDEX_COL_INDEX, headers["index"], header_fmt)
|
196
225
|
worksheet.write(row, CREATION_DATE_COL_INDEX, headers["creation_date"], header_fmt)
|
226
|
+
worksheet.set_column_pixels(CREATION_DATE_COL_INDEX, CREATION_DATE_COL_INDEX, 100)
|
197
227
|
worksheet.write(row, AUTHOR_COL_INDEX, headers["author"], header_fmt)
|
198
228
|
worksheet.write(row, ASSIGNED_TO_COL_INDEX, headers["assigned_to"], header_fmt)
|
199
229
|
worksheet.write(row, TITLE_COL_INDEX, headers["title"], header_fmt)
|
200
230
|
worksheet.write(row, VIEWPOINT_COL_INDEX, headers["viewpoint"], header_fmt)
|
201
231
|
worksheet.write(row, DESCRIPTION_COL_INDEX, headers["description"], header_fmt)
|
202
232
|
worksheet.write(row, DUE_DATE_COL_INDEX, headers["due_date"], header_fmt)
|
233
|
+
worksheet.write(row, STAGE_COL_INDEX, headers["stage"], header_fmt)
|
203
234
|
worksheet.write(row, STATUS_COL_INDEX, headers["status"], header_fmt)
|
204
235
|
worksheet.write(row, PRIORITY_COL_INDEX, headers["priority"], header_fmt)
|
205
|
-
worksheet.write(row,
|
236
|
+
worksheet.write(row, LABELS_COL_INDEX, headers["tags"], header_fmt)
|
206
237
|
worksheet.write(row, COMMENTS_COL_INDEX, headers["comments"], header_fmt)
|
207
|
-
worksheet.set_column_pixels(
|
208
|
-
worksheet.set_column_pixels(
|
238
|
+
worksheet.set_column_pixels(LABELS_COL_INDEX, LABELS_COL_INDEX, 100)
|
239
|
+
worksheet.set_column_pixels(COMMENTS_COL_INDEX, COMMENTS_COL_INDEX, 200)
|
240
|
+
worksheet.write(row, MODELS_COL_INDEX, headers["models"], header_fmt)
|
209
241
|
row += 1
|
210
242
|
|
211
243
|
# Sort topic by index
|
@@ -232,12 +264,13 @@ def to_xlsx(
|
|
232
264
|
worksheet.write_datetime(row, DUE_DATE_COL_INDEX, due_date, date_fmt)
|
233
265
|
else:
|
234
266
|
worksheet.write(row, DUE_DATE_COL_INDEX, "", base_fmt)
|
267
|
+
worksheet.write(row, STAGE_COL_INDEX, topic.get("stage"), base_fmt)
|
235
268
|
worksheet.write(row, STATUS_COL_INDEX, topic.get("topic_status"), base_fmt)
|
236
269
|
worksheet.write(row, PRIORITY_COL_INDEX, topic.get("priority"), base_fmt)
|
237
270
|
|
238
|
-
|
271
|
+
concatenated_labels = ", ".join(topic.get("labels", []))
|
239
272
|
|
240
|
-
worksheet.write(row,
|
273
|
+
worksheet.write(row, LABELS_COL_INDEX, concatenated_labels, base_fmt)
|
241
274
|
|
242
275
|
concatenated_comments = ""
|
243
276
|
|
@@ -250,7 +283,11 @@ def to_xlsx(
|
|
250
283
|
concatenated_comments += (
|
251
284
|
f"[{comment_date}] {comment['author']}: {comment['comment']}\n"
|
252
285
|
)
|
253
|
-
worksheet.write(row, COMMENTS_COL_INDEX, concatenated_comments,
|
286
|
+
worksheet.write(row, COMMENTS_COL_INDEX, concatenated_comments, text_wrap_fmt)
|
287
|
+
|
288
|
+
concatenated_models = "\n".join(topic.get("models", []))
|
289
|
+
|
290
|
+
worksheet.write(row, MODELS_COL_INDEX, concatenated_models, text_wrap_fmt)
|
254
291
|
|
255
292
|
if len(topic_viewpoints):
|
256
293
|
viewpoint = topic_viewpoints[0]
|
@@ -287,7 +324,7 @@ def to_xlsx(
|
|
287
324
|
worksheet.write(row, VIEWPOINT_COL_INDEX, "", base_fmt)
|
288
325
|
|
289
326
|
row += 1
|
290
|
-
|
327
|
+
|
291
328
|
worksheet.set_default_row(hide_unused_rows=True)
|
292
329
|
|
293
330
|
worksheet.autofit()
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|