Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 8 additions & 8 deletions service/src/structure_comparer/files/template.html.j2
Original file line number Diff line number Diff line change
Expand Up @@ -11,23 +11,23 @@
</head>

<body>
<h2>Mapping: {% for profile in source_profiles %}{{ profile['key'] }}{% if not loop.last %}, {% endif %}{% endfor %} in {{ target_profile['key'] }}</h2>
<h2>Mapping: {% for profile in source_profiles %}{{ profile['name'] ~ "|" ~ profile['version'] }}{% if not loop.last %}, {% endif %}{% endfor %} in {{ target_profile['name'] ~ "|" ~ target_profile['version'] }}</h2>

<div style="display: flex; justify-content: space-between;">
<div style="flex: 1;">
{% if source_profiles|length > 1 %}
<p>Source Profiles:</p>
<ul>
{% for profile in source_profiles %}
<li><a href="{{ profile['url'] }}" target="_blank">{{ profile['key'] }}</a></li>
<li><a href="{{ profile['url'] }}" target="_blank">{{ profile['name'] ~ "|" ~ profile['version'] }}</a></li>
{% endfor %}
</ul>
{% else %}
<p>Source Profile:
<a href="{{ source_profiles[0]['url'] }}" target="_blank">{{ source_profiles[0]['key'] }}</a></p>
<a href="{{ source_profiles[0]['url'] }}" target="_blank">{{ source_profiles[0]['name'] ~ "|" ~ source_profiles[0]['version'] }}</a></p>
{% endif %}

<p>Target Profile: <a href="{{ target_profile['url'] }}" target="_blank">{{ target_profile['key'] }}</a></p>
<p>Target Profile: <a href="{{ target_profile['url'] }}" target="_blank">{{ target_profile['name'] ~ "|" ~ target_profile['version'] }}</a></p>
<p>Version: {{version}}, Status: {{status}}</p>
<p>Last updated on: {{last_updated}}</p>
</div>
Expand Down Expand Up @@ -60,9 +60,9 @@
</tr>
<tr>
{% for profile in source_profiles %}
<th style="text-align: center;">{{ profile['key'] }}</th>
<th style="text-align: center;">{{ profile['name'] ~ "|" ~ profile['version'] }}</th>
{% endfor %}
<th style="text-align: center;">{{ target_profile['key'] }}</th>
<th style="text-align: center;">{{ target_profile['name'] ~ "|" ~ target_profile['version'] }}</th>
</tr>
</thead>
<tbody>
Expand All @@ -73,8 +73,8 @@
</td>
{% for profile in source_profiles + [target_profile] %}
<td style="text-align: center;">
{% if entry.profiles[profile['key']].present %}
{{ entry.profiles[profile['key']].min_cardinality }}..{{ entry.profiles[profile['key']].max_cardinality | format_cardinality }}
{% if entry.profiles[profile['key']] %}
{{ entry.profiles[profile['key']].min }}..{{ entry.profiles[profile['key']].max | format_cardinality }}
{% endif %}
</td>
{% endfor %}
Expand Down
13 changes: 13 additions & 0 deletions service/src/structure_comparer/handler/mapping.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
from ..model.mapping import MappingFieldMinimal as MappingFieldMinimalModel
from ..model.mapping import MappingFieldsOutput as MappingFieldsOutputModel
from .project import ProjectsHandler
from ..results_html import create_results_html


class MappingHandler:
Expand Down Expand Up @@ -54,6 +55,18 @@ def get_field(
raise FieldNotFound()

return field.to_model()

def get_html(
self, project_key: str, mapping_id: str, show_remarks: bool, show_warnings: bool
) -> str:
mapping = self.get(project_key, mapping_id)
mappingDict = {mapping.name: mapping}
html_output_dir = self.project_handler._get(project_key).config.html_output_dir
print(f"Mapping:{mapping.name}")

return create_results_html(
mappingDict, html_output_dir, show_remarks, show_warnings)
# return mapping

def set_field(
self,
Expand Down
52 changes: 37 additions & 15 deletions service/src/structure_comparer/results_html.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
from typing import Dict, List

from jinja2 import Environment, FileSystemLoader
from structure_comparer.helpers import split_parent_child

from .action import Action
from .data.mapping import Mapping
Expand Down Expand Up @@ -64,21 +63,41 @@ def create_results_html(
entries = {}
number_of_warnings = 0 # Initialize the warning counter

for field, entry in comp.fields.items():
fields = {field.name: field for field in comp.fields}
for entry in comp.fields: # .items():
# field, entry
field = entry.name
warnings = set() # Use a set to collect unique warnings
target_min_card = entry.profiles[comp.target.key].min_cardinality
target_max_card = entry.profiles[comp.target.key].max_cardinality
if comp.target.key not in entry.profiles:
warnings.add(
"The target profile does not contain this field, so it cannot be compared"
)
target_min_card = 0 # _cardinality
target_max_card = 0 # _cardinality
else:
target_min_card = entry.profiles[comp.target.key].min # _cardinality
target_max_card = entry.profiles[comp.target.key].max # _cardinality
if target_max_card == "*":
target_max_card = float("inf")
else:
target_max_card = int(target_max_card)

parent, _ = split_parent_child(field)
comparison_parent = comp.fields.get(parent)
match = re.search(r"[.:](?=[^.:]*$)", field)
if match:
parent = field[:match.start()]
else:
parent = field
# parent = field.rsplit(".", 1)[0]
comparison_parent = fields.get(parent)

for profile in comp.sources:
source_min_card = entry.profiles[profile.key].min_cardinality
source_max_card = entry.profiles[profile.key].max_cardinality
if profile.key in entry.profiles:
source_min_card = entry.profiles[profile.key].min # _cardinality
source_max_card = entry.profiles[profile.key].max # _cardinality
else:
source_min_card = 0
source_max_card = 0

if source_max_card == "*":
source_max_card = float("inf")
else:
Expand Down Expand Up @@ -118,7 +137,7 @@ def create_results_html(
entries[field] = {
"classification": entry.action,
"css_class": CSS_CLASS[entry.action],
"extension": entry.extension,
"extension": None, # entry.extension,
"extra": entry.other,
"profiles": entry.profiles,
"remark": entry.remark,
Expand All @@ -129,12 +148,16 @@ def create_results_html(
"css_file": STYLE_FILE_NAME,
"target_profile": {
"key": comp.target.key,
"url": comp.target.simplifier_url,
"url": comp.target.url, # simplifier_url,
"name": comp.target.name,
"version": comp.target.version
},
"source_profiles": [
{
"key": profile.key,
"url": profile.simplifier_url,
"url": profile.url, # .simplifier_url,
"name": profile.name,
"version": profile.version
}
for profile in comp.sources
],
Expand All @@ -150,14 +173,13 @@ def create_results_html(
content = template.render(**data)

# HOTFIX: prevent filenames to contain '|' but use '#' instead
source_profiles_flat = flatten_profiles(
[profile["key"].replace("|", "#") for profile in data["source_profiles"]]
)
html_file = (
results_folder
/ f"{source_profiles_flat}_to_{data['target_profile']['key'].replace("|", "#")}.html"
/ f"{comp.name.replace("|", "#").replace(" -> ", "_to_")}.html"
)
html_file.write_text(content, encoding="utf-8")

return str(html_file)


def format_links(text: str) -> str:
Expand Down
41 changes: 41 additions & 0 deletions service/src/structure_comparer/serve.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

import uvicorn
from fastapi import FastAPI, Response, UploadFile
from fastapi.responses import FileResponse
from fastapi.middleware.cors import CORSMiddleware

from .errors import (
Expand Down Expand Up @@ -798,6 +799,46 @@ async def get_mapping(
return ErrorModel.from_except(e)


@app.get(
"/project/{project_key}/mapping/{mapping_id}/results",
tags=["Mappings"],
response_model_exclude_unset=True,
response_model_exclude_none=True,
responses={404: {}},
)
async def get_mapping_results(
project_key: str, mapping_id: str, show_remarks: bool, show_warnings: bool, response: Response
) -> FileResponse: # MappingDetailsModel | ErrorModel:
"""
Get a static HTML page with the mappings
Returns a static HTML page with all mappings.
---
produces:
- text/html
responses:
200:
description: A static HTML page with the mappings
content:
text/html:
schema:
type: string
format: binary
headers:
Content-Disposition:
description: The filename of the HTML file
schema:
type: string
example: "mapping_results.html"
"""
global mapping_handler
try:
return FileResponse(mapping_handler.get_html(project_key, mapping_id, show_remarks, show_warnings), media_type="text/html")

except (ProjectNotFound, MappingNotFound) as e:
response.status_code = 404
return ErrorModel.from_except(e)


@app.get(
"/mapping/{id}/fields",
tags=["Fields"],
Expand Down