diff options
Diffstat (limited to 'day9/task5_vue/backend/views.py')
| -rw-r--r-- | day9/task5_vue/backend/views.py | 67 |
1 files changed, 46 insertions, 21 deletions
diff --git a/day9/task5_vue/backend/views.py b/day9/task5_vue/backend/views.py index 5c39322..8fb3a36 100644 --- a/day9/task5_vue/backend/views.py +++ b/day9/task5_vue/backend/views.py @@ -5,7 +5,10 @@ from backend.core.response_types import ErrorResponse, TextFileResponse, ImageRe from backend.database.database import get_wrapper_for from backend.database.validators import ValidationError +from backend.logger import Logger + import csv +import io def return_static(query, *args): @@ -28,36 +31,58 @@ def return_static(query, *args): def upload_file(query, *args): - base_html = '<a href="/">Return to main page</a><br>%s' - try: data = query['files'][0]['data'].decode('utf-8') except (UnicodeDecodeError, KeyError, IndexError): - return ErrorResponse(500, base_html % '<h1>Error while reading file</h1>') + return ErrorResponse(500, 'Error while reading file') wrapper = get_wrapper_for('mysql') - - permitted_headers = wrapper.get_column_names() - - try: - data = list(csv.reader(data.strip().splitlines(), delimiter=';', quotechar='"')) - if len(data[0]) != len(permitted_headers) or set(data[0]) != set(permitted_headers): - return ErrorResponse(500, base_html % '<h1>File format error</h1>') - except IndexError: - return ErrorResponse(500, base_html % '<h1>File format error</h1>') - wrapper.clear_table('table_task1') - scheme = wrapper.schemes['table_task1'] - for row in data[1:]: - insert_values = dict(zip(data[0], row)) - validation_results = scheme.validate(insert_values) + + result = parse_csv(data, scheme) + if result is None: + return ErrorResponse(500, 'Wrong file format') + + for index, row in enumerate(result): + Logger.get_logger().debug(f'Validating') + validation_results = scheme.validate(row) if not validation_results['error']: - wrapper.insert_one('table_task1', insert_values) + Logger.get_logger().debug(f'No errors') + wrapper.insert_one('table_task1', row) else: - return ErrorResponse(500) - - return HtmlResponse(base_html % '<h1>File uploaded</h1>') + Logger.get_logger().debug(f'Error {validation_results}') + return ErrorResponse(500, f'Validation error\n{validation_results}') + + return HtmlResponse('File uploaded') + + +def parse_csv(data, scheme): + reader = csv.DictReader(io.StringIO(data), delimiter=';') + + if set(reader.fieldnames) != set(scheme.fields.keys()): + return None + + result = [] + for row in reader: + insert_row = {} + for field_name, value in row.items(): + if scheme.fields[field_name].nullable and value == 'NULL': + insert_row[field_name] = None + else: + data_type = scheme.fields[field_name].data_type + + try: + new_value = data_type(value) + except ValueError: + Logger.get_logger().debug(f'Unable to cast `{value}` to {data_type}') + insert_row[field_name] = value + else: + insert_row[field_name] = new_value + + result.append(insert_row) + + return result def validate(query, *args): |