Skip to content

Commit

Permalink
Merge branch 'main' into add-realization-view
Browse files Browse the repository at this point in the history
  • Loading branch information
ewuerger authored Dec 13, 2024
2 parents abf1288 + 91afc12 commit 87b1dbf
Showing 13 changed files with 416 additions and 260 deletions.
8 changes: 8 additions & 0 deletions capella2polarion/__main__.py
Original file line number Diff line number Diff line change
@@ -116,6 +116,12 @@ def print_cli_state(capella2polarion_cli: Capella2PolarionCli) -> None:
is_flag=True,
default=True,
)
@click.option(
"--generate-figure-captions",
envvar="CAPELLA2POLARION_GENERATE_FIGURE_CAPTIONS",
is_flag=True,
default=False,
)
@click.pass_context
def synchronize(
ctx: click.core.Context,
@@ -124,6 +130,7 @@ def synchronize(
type_prefix: str,
role_prefix: str,
grouped_links_custom_fields: bool,
generate_figure_captions: bool,
) -> None:
"""Synchronise model elements."""
capella_to_polarion_cli: Capella2PolarionCli = ctx.obj
@@ -160,6 +167,7 @@ def synchronize(
generate_links=True,
generate_attachments=True,
generate_grouped_links_custom_fields=grouped_links_custom_fields,
generate_figure_captions=generate_figure_captions,
)

polarion_worker.compare_and_update_work_items(converter.converter_session)
32 changes: 29 additions & 3 deletions capella2polarion/converters/element_converter.py
Original file line number Diff line number Diff line change
@@ -21,7 +21,7 @@
from capellambse import helpers as chelpers
from capellambse import model as m
from capellambse_context_diagrams import context
from lxml import etree
from lxml import etree, html

from capella2polarion import data_model
from capella2polarion.connectors import polarion_repo
@@ -75,11 +75,13 @@ def __init__(
capella_polarion_mapping: polarion_repo.PolarionDataRepository,
converter_session: data_session.ConverterSession,
generate_attachments: bool,
generate_figure_captions: bool = False,
):
self.model = model
self.capella_polarion_mapping = capella_polarion_mapping
self.converter_session = converter_session
self.generate_attachments = generate_attachments
self.generate_figure_captions = generate_figure_captions
self.jinja_envs: dict[str, jinja2.Environment] = {}

def serialize_all(self) -> list[data_model.CapellaWorkItem]:
@@ -155,6 +157,7 @@ def _draw_diagram_svg(
max_width: int,
cls: str,
render_params: dict[str, t.Any] | None = None,
caption: tuple[str, str] | None = None,
) -> tuple[str, data_model.CapellaDiagramAttachment | None]:
file_name = f"{C2P_IMAGE_PREFIX}{file_name}.svg"

@@ -172,7 +175,7 @@ def _draw_diagram_svg(

return (
polarion_html_helper.generate_image_html(
title, file_name, max_width, cls
title, file_name, max_width, cls, caption
),
attachment,
)
@@ -212,6 +215,7 @@ def __insert_diagram(
file_name: str,
render_params: dict[str, t.Any] | None = None,
max_width: int = 800,
caption: tuple[str, str] | None = None,
):
if attachment := next(
(
@@ -227,6 +231,7 @@ def __insert_diagram(
attachment.file_name,
max_width,
JINJA_RENDERED_IMG_CLS,
caption,
)

diagram_html, attachment = self._draw_diagram_svg(
@@ -312,6 +317,17 @@ def repair_images(node: etree._Element) -> None:
# We use the filename here as the ID is unknown here
# This needs to be refactored after updating attachments
node.attrib["src"] = f"workitemimg:{file_name}"
if self.generate_figure_captions:
caption = node.get(
"alt", f'Image "{file_url.stem}" of {obj.name}'
)
node.addnext(
html.fromstring(
polarion_html_helper.POLARION_CAPTION.format(
label="Figure", caption=caption
)
)
)

except FileNotFoundError:
self.converter_session[obj.uuid].errors.add(
@@ -419,7 +435,17 @@ def _diagram(
work_item_id = converter_data.work_item.id

diagram_html, attachment = self._draw_diagram_svg(
diagram, "diagram", "Diagram", 750, "diagram", render_params
diagram,
"diagram",
"Diagram",
750,
"diagram",
render_params,
(
("Figure", f"Diagram {diagram.name}")
if self.generate_figure_captions
else None
),
)

converter_data.work_item = data_model.CapellaWorkItem(
4 changes: 4 additions & 0 deletions capella2polarion/converters/model_converter.py
Original file line number Diff line number Diff line change
@@ -84,6 +84,7 @@ def generate_work_items(
generate_links: bool = False,
generate_attachments: bool = False,
generate_grouped_links_custom_fields: bool = False,
generate_figure_captions: bool = False,
) -> dict[str, data_model.CapellaWorkItem]:
"""Return a work items mapping from model elements for Polarion.
@@ -104,12 +105,15 @@ def generate_work_items(
generate_grouped_links_custom_fields
A boolean flag to control grouped links custom fields
generation.
generate_figure_captions
A boolean flag to enable the generation of figure captions
"""
serializer = element_converter.CapellaWorkItemSerializer(
self.model,
polarion_data_repo,
self.converter_session,
generate_attachments,
generate_figure_captions,
)
work_items = serializer.serialize_all()
if generate_links:
15 changes: 14 additions & 1 deletion capella2polarion/converters/polarion_html_helper.py
Original file line number Diff line number Diff line change
@@ -37,6 +37,11 @@
"params=id={pid}|layout={lid}|{custom_info}external=true"
'|project={project}"></div>'
)
POLARION_CAPTION = (
'<p class="polarion-rte-caption-paragraph">\n '
'{label} <span data-sequence="{label}" '
'class="polarion-rte-caption">#</span> {caption}\n</p>'
)
RE_DESCR_DELETED_PATTERN = re.compile(
f"&lt;deleted element ({chelpers.RE_VALID_UUID.pattern})&gt;"
)
@@ -52,14 +57,22 @@ def strike_through(string: str) -> str:


def generate_image_html(
title: str, attachment_id: str, max_width: int, cls: str
title: str,
attachment_id: str,
max_width: int,
cls: str,
caption: tuple[str, str] | None = None,
) -> str:
"""Generate an image as HTMl with the given source."""
description = (
f'<span><img title="{title}" class="{cls}" '
f'src="workitemimg:{attachment_id}" '
f'style="max-width: {max_width}px;"/></span>'
)
if caption:
description += POLARION_CAPTION.format(
label=caption[0], caption=caption[1]
)
return description


46 changes: 16 additions & 30 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -13,9 +13,7 @@ description = "Synchronise Capella models with Polarion projects"
readme = "README.md"
requires-python = ">=3.10, <3.13"
license = { text = "Apache-2.0" }
authors = [
{ name = "DB InfraGO AG" },
]
authors = [{ name = "DB InfraGO AG" }]
keywords = []
classifiers = [
"Development Status :: 1 - Planning",
@@ -29,36 +27,26 @@ classifiers = [
]
dependencies = [
"capellambse>=0.6.6,<0.7",
"capellambse_context_diagrams>=0.5.0,<0.6",
"capellambse_context_diagrams>=0.6.0,<0.7",
"click",
"PyYAML",
"polarion-rest-api-client==1.2.2",
"bidict",
"cairosvg",
"jinja2",
"pydantic"
"pydantic",
]

[project.urls]
Homepage = "https://github.com/DSD-DBS/capella2polarion"
Documentation = "https://dsd-dbs.github.io/capella2polarion"

[project.optional-dependencies]
dev = [
"python-dotenv"
]
dev = ["python-dotenv"]

docs = [
"furo",
"sphinx",
"sphinx-copybutton",
"tomli",
]
docs = ["furo", "sphinx", "sphinx-copybutton", "tomli"]

test = [
"pytest",
"pytest-cov",
]
test = ["pytest", "pytest-cov"]

[project.scripts]
capella2polarion = "capella2polarion.__main__:cli"
@@ -98,23 +86,21 @@ ignore_missing_imports = true
[tool.pydocstyle]
convention = "numpy"
add-select = [
"D212", # Multi-line docstring summary should start at the first line
"D402", # First line should not be the function’s “signature”
"D417", # Missing argument descriptions in the docstring
"D212", # Multi-line docstring summary should start at the first line
"D402", # First line should not be the function’s “signature”
"D417", # Missing argument descriptions in the docstring
]
add-ignore = [
"D201", # No blank lines allowed before function docstring # auto-formatting
"D202", # No blank lines allowed after function docstring # auto-formatting
"D203", # 1 blank line required before class docstring # auto-formatting
"D204", # 1 blank line required after class docstring # auto-formatting
"D211", # No blank lines allowed before class docstring # auto-formatting
"D213", # Multi-line docstring summary should start at the second line
"D201", # No blank lines allowed before function docstring # auto-formatting
"D202", # No blank lines allowed after function docstring # auto-formatting
"D203", # 1 blank line required before class docstring # auto-formatting
"D204", # 1 blank line required after class docstring # auto-formatting
"D211", # No blank lines allowed before class docstring # auto-formatting
"D213", # Multi-line docstring summary should start at the second line
]

[tool.pylint.master]
extension-pkg-allow-list = [
"lxml.etree",
]
extension-pkg-allow-list = ["lxml.etree"]
max-line-length = 79

[tool.pylint.messages_control]
6 changes: 3 additions & 3 deletions tests/data/model/Melody Model Test.afm
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<metadata:Metadata xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:metadata="http://www.polarsys.org/kitalpha/ad/metadata/1.0.0" id="_-kIvQKDzEeqf7Mw7EIo_Ew">
<viewpointReferences id="_-lINwKDzEeqf7Mw7EIo_Ew" vpId="org.polarsys.capella.core.viewpoint" version="5.2.0"/>
<viewpointReferences id="_4DaT8PHWEeq9N-vcO9FSUw" vpId="org.polarsys.kitalpha.vp.requirements" version="0.12.2"/>
<viewpointReferences id="_4FtaAPHWEeq9N-vcO9FSUw" vpId="org.polarsys.capella.vp.requirements" version="0.12.2"/>
<viewpointReferences id="_-lINwKDzEeqf7Mw7EIo_Ew" vpId="org.polarsys.capella.core.viewpoint" version="7.0.0"/>
<viewpointReferences id="_4DaT8PHWEeq9N-vcO9FSUw" vpId="org.polarsys.kitalpha.vp.requirements" version="0.14.0"/>
<viewpointReferences id="_4FtaAPHWEeq9N-vcO9FSUw" vpId="org.polarsys.capella.vp.requirements" version="0.14.0"/>
</metadata:Metadata>
Loading

0 comments on commit 87b1dbf

Please sign in to comment.