Attempt validation for csv
This commit is contained in:
parent
4a9ac53dd8
commit
d4e7c0833b
@ -3,7 +3,15 @@ from io import TextIOWrapper
|
|||||||
from config import item_attributes
|
from config import item_attributes
|
||||||
|
|
||||||
def get_csv_data(file):
|
def get_csv_data(file):
|
||||||
|
"""Extract and validate CSV data."""
|
||||||
csv_file = TextIOWrapper(file, encoding='utf-8')
|
csv_file = TextIOWrapper(file, encoding='utf-8')
|
||||||
|
|
||||||
|
# Check delimiter
|
||||||
|
sample = csv_file.read(1024)
|
||||||
|
csv_file.seek(0)
|
||||||
|
if '|' not in sample:
|
||||||
|
raise ValueError("CSV file must use '|' as the delimiter.")
|
||||||
|
|
||||||
reader = csv.DictReader(csv_file, delimiter='|')
|
reader = csv.DictReader(csv_file, delimiter='|')
|
||||||
|
|
||||||
# Validate CSV headers based on config
|
# Validate CSV headers based on config
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
from flask import Blueprint, request, render_template, redirect, session
|
from flask import Blueprint, request, render_template, redirect, session, flash
|
||||||
from definitions.models import Asset, db
|
from definitions.models import Asset, db
|
||||||
from functions.process_csv import get_csv_data
|
from functions.process_csv import get_csv_data
|
||||||
|
from functions.validate_values import validate_values
|
||||||
from config import item_attributes
|
from config import item_attributes
|
||||||
|
|
||||||
upload_bp = Blueprint('uploadcsv', __name__)
|
upload_bp = Blueprint('uploadcsv', __name__)
|
||||||
@ -10,26 +11,39 @@ def upload_file():
|
|||||||
if request.method == 'POST':
|
if request.method == 'POST':
|
||||||
# Check if a file was uploaded
|
# Check if a file was uploaded
|
||||||
if 'file' not in request.files:
|
if 'file' not in request.files:
|
||||||
return redirect('uploadcsv')
|
flash("No file uploaded.", "error")
|
||||||
|
return redirect(request.url)
|
||||||
|
|
||||||
file = request.files['file']
|
file = request.files['file']
|
||||||
|
|
||||||
# Check if the file is a CSV
|
# Check if the file is a CSV
|
||||||
if file.filename == '' or not file.filename.endswith('.csv'):
|
if file.filename == '' or not file.filename.endswith('.csv'):
|
||||||
return redirect('uploadcsv')
|
flash("Please upload a valid CSV file.", "error")
|
||||||
|
return redirect(request.url)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
# Extract data from the CSV file
|
# Extract and validate CSV data
|
||||||
csvdata = get_csv_data(file)
|
csvdata = get_csv_data(file)
|
||||||
|
|
||||||
# Identify the primary attribute
|
# Validate each row of data
|
||||||
primary_attrib = next(
|
errors = []
|
||||||
(attrib for attrib in item_attributes if attrib.primary),
|
for i, row in enumerate(csvdata, start=1):
|
||||||
None
|
error = validate_values(row)
|
||||||
)
|
if error:
|
||||||
|
errors.append(f"Row {i}: {error}")
|
||||||
|
|
||||||
|
if errors:
|
||||||
|
# Pass errors as a list to the template
|
||||||
|
return render_template(
|
||||||
|
'upload.html',
|
||||||
|
errors=errors
|
||||||
|
)
|
||||||
|
|
||||||
|
# Identify the primary attribute
|
||||||
|
primary_attrib = next((attrib for attrib in item_attributes if attrib.primary), None)
|
||||||
if not primary_attrib:
|
if not primary_attrib:
|
||||||
return "Primary attribute not defined in configuration."
|
flash("Primary attribute not defined in configuration.", "error")
|
||||||
|
return redirect(request.url)
|
||||||
|
|
||||||
# Separate new and existing assets
|
# Separate new and existing assets
|
||||||
new_assets = []
|
new_assets = []
|
||||||
@ -54,8 +68,8 @@ def upload_file():
|
|||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
# Handle errors during file processing
|
# Handle errors during file processing
|
||||||
print(f"Error processing CSV file: {str(e)}")
|
flash(f"Error processing CSV file: {str(e)}", "error")
|
||||||
return redirect('uploadcsv')
|
return redirect(request.url)
|
||||||
|
|
||||||
# Render the upload page for GET requests
|
# Render the upload page for GET requests
|
||||||
return render_template('upload.html')
|
return render_template('upload.html')
|
@ -9,50 +9,35 @@
|
|||||||
<body>
|
<body>
|
||||||
<h1>CSV Preview</h1>
|
<h1>CSV Preview</h1>
|
||||||
|
|
||||||
<!-- Display CSV data in a table -->
|
<!-- Render tables for new and existing assets -->
|
||||||
{% if new_assets %}
|
{% for table_name, assets, editable in [
|
||||||
<p>New assets:</p>
|
('New Assets', new_assets, true),
|
||||||
<table border="1" class="table-new-assets">
|
('Existing Assets', existing, false)
|
||||||
<thead>
|
] %}
|
||||||
<tr>
|
{% if assets %}
|
||||||
{% for attrib in item_attributes %}
|
<h2>{{ table_name }}</h2>
|
||||||
<th data-attrib="{{ attrib.attrib_name }}">{{ attrib.display_name }}</th>
|
<table border="1" class="table-new-assets">
|
||||||
{% endfor %}
|
<thead>
|
||||||
</tr>
|
<tr>
|
||||||
</thead>
|
{% for attrib in item_attributes %}
|
||||||
<tbody>
|
<th data-attrib="{{ attrib.attrib_name }}">{{ attrib.display_name }}</th>
|
||||||
{% for asset in new_assets %}
|
{% endfor %}
|
||||||
<tr>
|
</tr>
|
||||||
{% for attrib in item_attributes %}
|
</thead>
|
||||||
<td contenteditable="true">{{ asset[attrib.attrib_name] }}</td>
|
<tbody>
|
||||||
|
{% for asset in assets %}
|
||||||
|
<tr>
|
||||||
|
{% for attrib in item_attributes %}
|
||||||
|
<td {% if editable %}contenteditable="true"{% endif %}>
|
||||||
|
{{ asset[attrib.attrib_name] }}
|
||||||
|
</td>
|
||||||
|
{% endfor %}
|
||||||
|
</tr>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</tr>
|
</tbody>
|
||||||
{% endfor %}
|
</table>
|
||||||
</tbody>
|
{% endif %}
|
||||||
</table>
|
{% endfor %}
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
{% if existing %}
|
|
||||||
<p>These assets are already in the database:</p>
|
|
||||||
<table border="1" class="table-existing-assets">
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
{% for attrib in item_attributes %}
|
|
||||||
<th>{{ attrib.display_name }}</th>
|
|
||||||
{% endfor %}
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
{% for asset in existing %}
|
|
||||||
<tr>
|
|
||||||
{% for attrib in item_attributes %}
|
|
||||||
<td>{{ asset[attrib.attrib_name] }}</td>
|
|
||||||
{% endfor %}
|
|
||||||
</tr>
|
|
||||||
{% endfor %}
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
<!-- Form button to confirm and save data -->
|
<!-- Form button to confirm and save data -->
|
||||||
{% if new_assets %}
|
{% if new_assets %}
|
||||||
|
@ -7,15 +7,36 @@
|
|||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<h1>Upload CSV File</h1>
|
<h1>Upload CSV File</h1>
|
||||||
|
|
||||||
|
<!-- Display flash messages -->
|
||||||
|
{% with messages = get_flashed_messages(with_categories=true) %}
|
||||||
|
{% if messages %}
|
||||||
|
{% for category, message in messages %}
|
||||||
|
<p style="color: red;">{{ message }}</p>
|
||||||
|
{% endfor %}
|
||||||
|
{% endif %}
|
||||||
|
{% endwith %}
|
||||||
|
|
||||||
|
<!-- Display validation errors if any -->
|
||||||
|
{% if errors %}
|
||||||
|
<details style="margin-bottom: 20px;">
|
||||||
|
<summary style="color: red; font-weight: bold;">
|
||||||
|
Errors found in the CSV file (click to expand):
|
||||||
|
</summary>
|
||||||
|
<ul>
|
||||||
|
{% for error in errors %}
|
||||||
|
<li>{{ error }}</li>
|
||||||
|
{% endfor %}
|
||||||
|
</ul>
|
||||||
|
</details>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
<!-- Upload form -->
|
||||||
<form action="/uploadcsv" method="POST" enctype="multipart/form-data">
|
<form action="/uploadcsv" method="POST" enctype="multipart/form-data">
|
||||||
<label for="file">Choose a CSV file:</label>
|
<label for="file">Choose a CSV file:</label>
|
||||||
<input type="file" id="file" name="file" accept=".csv" required>
|
<input type="file" id="file" name="file" accept=".csv" required>
|
||||||
<br><br>
|
<br><br>
|
||||||
<button type="submit">Upload</button>
|
<button type="submit">Upload</button>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
{% if error %}
|
|
||||||
<p style="color: red;">{{ error }}</p>
|
|
||||||
{% endif %}
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
Loading…
Reference in New Issue
Block a user