Attempt validation for csv

This commit is contained in:
Candifloss 2025-02-24 02:24:00 +05:30
parent 4a9ac53dd8
commit d4e7c0833b
4 changed files with 87 additions and 59 deletions

View File

@ -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

View File

@ -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')

View File

@ -9,9 +9,13 @@
<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),
('Existing Assets', existing, false)
] %}
{% if assets %}
<h2>{{ table_name }}</h2>
<table border="1" class="table-new-assets"> <table border="1" class="table-new-assets">
<thead> <thead>
<tr> <tr>
@ -21,38 +25,19 @@
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
{% for asset in new_assets %} {% for asset in assets %}
<tr> <tr>
{% for attrib in item_attributes %} {% for attrib in item_attributes %}
<td contenteditable="true">{{ asset[attrib.attrib_name] }}</td> <td {% if editable %}contenteditable="true"{% endif %}>
{{ asset[attrib.attrib_name] }}
</td>
{% endfor %} {% endfor %}
</tr> </tr>
{% endfor %} {% endfor %}
</tbody> </tbody>
</table> </table>
{% endif %} {% 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 %} {% 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 %}

View File

@ -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>