diff --git a/mo/csv.py b/mo/csv.py index 73e6e98c9e68545fba9a4695c85e775e23eba8e1..1a5d516518b2295da7efe74d0f90b9678e234ef9 100644 --- a/mo/csv.py +++ b/mo/csv.py @@ -7,7 +7,7 @@ # - quoting pomocí uvozovek import csv -from difflib import get_close_matches +import difflib from enum import auto from dataclasses import dataclass, fields from typing import Type, List, IO, Sequence @@ -96,16 +96,10 @@ class MissingHeaderError(RuntimeError): class UnknownColumnError(RuntimeError): - def __init__(self, unknown_name: str, columns: set): - best_matches = get_close_matches(unknown_name, columns, n=1) - if not best_matches: - self.message = ( - "Neznámý sloupec '{}'. Podporovaná množina sloupců je tato: {}".format( - unknown_name, columns)) - else: - self.message = ( - "Neznámý sloupec '{}', měli jste na mysli '{}'?".format( - unknown_name, best_matches[0])) + def __init__(self, unknown_name: str, expected_name: str): + self.message = ( + "Neznámý sloupec '{}', měli jste na mysli '{}'?".format( + unknown_name, expected_name)) def write(file: IO, fmt: FileFormat, row_class: Type[Row], rows: Sequence[Row]): @@ -122,6 +116,7 @@ def write(file: IO, fmt: FileFormat, row_class: Type[Row], rows: Sequence[Row]): def read(file: IO, fmt: FileFormat, row_class: Type[Row]): reader = csv.reader(file, dialect=fmt.get_dialect(), strict=True) + warnings = [] header: List[str] = [] rows: List[Row] = [] columns = set(field.name for field in fields(row_class)) @@ -136,7 +131,11 @@ def read(file: IO, fmt: FileFormat, row_class: Type[Row]): raise MissingHeaderError() for h in header: if not h in columns: - raise UnknownColumnError(h, columns) + best_matches = difflib.get_close_matches(h, columns, n=1, cutoff=0.8) + if best_matches: + warnings.append( + "Neznámý sloupec '{}', měli jste na mysli '{}'?".format( + h, best_matches[0])) else: row = row_class() not_empty = False @@ -150,4 +149,4 @@ def read(file: IO, fmt: FileFormat, row_class: Type[Row]): if not_empty: rows.append(row) - return rows + return (rows, warnings) diff --git a/mo/imports.py b/mo/imports.py index c42df868088ab9b420c125d563a269a2a96cd9ce..8993a7f8c3511933e5926c83859903c56480adf1 100644 --- a/mo/imports.py +++ b/mo/imports.py @@ -69,6 +69,7 @@ class Import: def __init__(self): self.errors = [] + self.warnings = [] self.rr = None self.place_cache = {} self.school_place_cache = {} @@ -382,7 +383,9 @@ class Import: try: with open(path, encoding=charset) as file: try: - rows: List[mo.csv.Row] = mo.csv.read(file=file, fmt=self.fmt, row_class=self.row_class) + rows: List[mo.csv.Row] + rows, warnings = mo.csv.read(file=file, fmt=self.fmt, row_class=self.row_class) + self.warnings += warnings except MissingHeaderError: return self.error('Souboru chybí první řádek s názvy sloupců') except UnknownColumnError as e: diff --git a/mo/web/org_contest.py b/mo/web/org_contest.py index 71fce79775fc997234e8dbbe431fe4589fc31a8f..8f9e2328d93f0935d58b40701b2915b57d1118b8 100644 --- a/mo/web/org_contest.py +++ b/mo/web/org_contest.py @@ -364,6 +364,7 @@ def generic_import(round: db.Round, contest: Optional[db.Contest]): form = ImportForm() errs = [] + warnings = [] if form.validate_on_submit(): fmt = form.fmt.data imp = create_import(user=g.user, type=form.typ.data, fmt=fmt, round=round, contest=contest) @@ -383,6 +384,7 @@ def generic_import(round: db.Round, contest: Optional[db.Contest]): return redirect(url_for('org_round', id=round.round_id)) else: errs = imp.errors + warnings = imp.warnings else: flash('Vyberte si prosím soubor', 'danger') elif form.get_template.data: @@ -398,6 +400,7 @@ def generic_import(round: db.Round, contest: Optional[db.Contest]): round=round, form=form, errs=errs, + warnings=warnings ) diff --git a/mo/web/templates/org_generic_import.html b/mo/web/templates/org_generic_import.html index 3b60d4459b5c1160a6205c69bba32f9a19b73c0c..ebe4616a3b4ec546ed6704446e8efc829e73adec 100644 --- a/mo/web/templates/org_generic_import.html +++ b/mo/web/templates/org_generic_import.html @@ -9,6 +9,16 @@ Import dat do {% if contest %}soutěžní oblasti {{ contest.place.name }}{% els {% endblock %} {% block body %} +{% if warnings %} +<h3>Varování při importu</h3> + +<div class="alert alert-warning" role="alert" style="white-space: pre-line">{{ "" -}} +{% for e in warnings %} +{{ e }} +{% endfor %} +</div> +{% endif %} + {% if errs %} <h3>Chyby při importu</h3>