Skip to content
Snippets Groups Projects
Commit a294a0c4 authored by Jan Prachař's avatar Jan Prachař
Browse files

import: unknown columns as warning

parent 117d5f4d
No related branches found
No related tags found
No related merge requests found
......@@ -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:
def __init__(self, unknown_name: str, expected_name: str):
self.message = (
"Neznámý sloupec '{}', měli jste na mysli '{}'?".format(
unknown_name, best_matches[0]))
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)
......@@ -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:
......
......@@ -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
)
......
......@@ -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>
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment