Commit 722eeabe authored by Pierre Dittgen's avatar Pierre Dittgen Committed by Christophe Benz

Add badge in ui

parent 212231f9
...@@ -29,10 +29,12 @@ setup( ...@@ -29,10 +29,12 @@ setup(
'ezodf', 'ezodf',
'flask', 'flask',
'lxml', 'lxml',
'requests',
'toml',
'goodtables', 'goodtables',
'tabulator', 'tabulator',
'validata_core >= 0.2, < 0.3', 'validata_core >= 0.2.1, < 0.3',
] ]
) )
...@@ -26,6 +26,7 @@ ...@@ -26,6 +26,7 @@
{% endif %} {% endif %}
<h1 class="my-4">{{ title }}</h1> <h1 class="my-4">{{ title }}</h1>
<p>Validation effectuée {{ validation_date }}</p> <p>Validation effectuée {{ validation_date }}</p>
<p><img src="{{ badge_url }}" alt="{{ badge_msg }}" title="{{ badge_msg }}"/></p>
{% if print_mode %} {% if print_mode %}
</div> </div>
<div class="col-md-7"> <div class="col-md-7">
...@@ -182,14 +183,14 @@ ...@@ -182,14 +183,14 @@
{% block footer %} {% block footer %}
<script> <script>
$(function () { $(function() {
// Errors tooltip activate // Errors tooltip activate
$('[data-toggle="popover"]').popover({ $('[data-toggle="popover"]').popover({
html: true, html: true,
placement: 'auto', placement: "auto",
trigger: 'hover' trigger: "hover"
}); });
}) });
</script> </script>
{% endblock %} {% endblock %}
\ No newline at end of file
...@@ -5,6 +5,7 @@ import copy ...@@ -5,6 +5,7 @@ import copy
import itertools import itertools
import json import json
import logging import logging
import os
import subprocess import subprocess
import tempfile import tempfile
from datetime import datetime from datetime import datetime
...@@ -13,13 +14,15 @@ from operator import itemgetter ...@@ -13,13 +14,15 @@ from operator import itemgetter
from pathlib import Path from pathlib import Path
from urllib.parse import quote_plus from urllib.parse import quote_plus
import requests
import toml
from backports.datetime_fromisoformat import MonkeyPatch from backports.datetime_fromisoformat import MonkeyPatch
from commonmark import commonmark from commonmark import commonmark
from flask import make_response, redirect, render_template, request, url_for from flask import make_response, redirect, render_template, request, url_for
from validata_core import compute_badge, csv_helpers, messages
from validata_core.loaders import custom_loaders
import tabulator import tabulator
from validata_core import csv_helpers, messages
from validata_core.loaders import custom_loaders
from validata_ui import app from validata_ui import app
from validata_ui.ui_util import flash_error, flash_warning from validata_ui.ui_util import flash_error, flash_warning
from validata_ui.validata_util import ValidataSource from validata_ui.validata_util import ValidataSource
...@@ -30,6 +33,26 @@ MonkeyPatch.patch_fromisoformat() ...@@ -30,6 +33,26 @@ MonkeyPatch.patch_fromisoformat()
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
# Get badge configuration file url from environment variable
badge_config = None
badge_config_url = os.environ.get('BADGE_CONFIG_URL')
if badge_config_url is None:
log.warning("BADGE_CONFIG_URL environment variable is not set")
else:
req = requests.get(badge_config_url)
if not req.ok:
log.warning("Can't retrieve badge config from [%s]", badge_config_url)
else:
badge_config = toml.loads(req.text)
# Gets shields io url from environment variable
shields_io_url = os.environ.get('SHIELDS_IO_URL')
if shields_io_url is None:
shields_io_url = 'https://img.shields.io/'
elif not shields_io_url.endswith('/'):
shields_io_url += '/'
def extract_source_data(source: ValidataSource, preview_rows_nb=5): def extract_source_data(source: ValidataSource, preview_rows_nb=5):
""" Computes table preview """ """ Computes table preview """
...@@ -205,6 +228,34 @@ def create_validata_ui_report(validata_core_report, schema): ...@@ -205,6 +228,34 @@ def create_validata_ui_report(validata_core_report, schema):
return report return report
def compute_badge_message_and_color(badge):
"""Computes message and color from badge information"""
structure = badge['structure']
body = badge.get('body')
# Bad structure, stop here
if structure == 'KO':
return (
'structure invalide', 'red')
# No body error
if body == 'OK':
return ('structure invalide', 'orange') if structure == 'WARN' else ('valide', 'green')
# else compute quality ratio percent
p = (1 - badge['ratio']) * 100.0
msg = 'cellules valides : {:.1f}%'.format(p)
return (msg, 'red') if body == 'KO' else (msg, 'orange')
def get_badge_url_and_message(badge):
"""Gets badge url from badge information"""
msg, color = compute_badge_message_and_color(badge)
return ('{}static/v1.svg?label=Validata&message={}&color={}'
.format(shields_io_url, quote_plus(msg), color), msg)
def validate(schema_code, source: ValidataSource): def validate(schema_code, source: ValidataSource):
""" Validate source and display report """ """ Validate source and display report """
...@@ -224,6 +275,10 @@ def validate(schema_code, source: ValidataSource): ...@@ -224,6 +275,10 @@ def validate(schema_code, source: ValidataSource):
flash_error('Erreur : format de fichier non supporté') flash_error('Erreur : format de fichier non supporté')
return redirect(url_for('scdl_validator', val_code=schema_code)) return redirect(url_for('scdl_validator', val_code=schema_code))
# Computes badge from report and badge configuration
badge = compute_badge(validata_core_report, badge_config)
badge_url, badge_msg = get_badge_url_and_message(badge)
source_errors = [err for err in validata_core_report['tables'][0]['errors'] if err['code'] == 'source-error'] source_errors = [err for err in validata_core_report['tables'][0]['errors'] if err['code'] == 'source-error']
if source_errors: if source_errors:
err = source_errors[0] err = source_errors[0]
...@@ -247,6 +302,7 @@ def validate(schema_code, source: ValidataSource): ...@@ -247,6 +302,7 @@ def validate(schema_code, source: ValidataSource):
validation_date=report_datetime.strftime('le %d/%m/%Y à %Hh%M'), validation_date=report_datetime.strftime('le %d/%m/%Y à %Hh%M'),
source=source, source_type=source.type, source_data=source_data, source=source, source_type=source.type, source_data=source_data,
print_mode=request.args.get('print', 'false') == 'true', print_mode=request.args.get('print', 'false') == 'true',
badge_url=badge_url, badge_msg=badge_msg,
report_str=json.dumps(validata_report, sort_keys=True, indent=2), report_str=json.dumps(validata_report, sort_keys=True, indent=2),
breadcrumbs=[{'url': url_for('home'), 'title': 'Accueil'}, breadcrumbs=[{'url': url_for('home'), 'title': 'Accueil'},
{'url': url_for('scdl_validator', val_code=schema_code), {'url': url_for('scdl_validator', val_code=schema_code),
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment