diff --git a/functions/process_csv.py b/functions/process_csv.py index ee96241..c3155cd 100644 --- a/functions/process_csv.py +++ b/functions/process_csv.py @@ -3,7 +3,15 @@ from io import TextIOWrapper from config import item_attributes def get_csv_data(file): + """Extract and validate CSV data.""" 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='|') # Validate CSV headers based on config diff --git a/routes/upload.py b/routes/upload.py index 0598285..02c8aeb 100644 --- a/routes/upload.py +++ b/routes/upload.py @@ -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 functions.process_csv import get_csv_data +from functions.validate_values import validate_values from config import item_attributes upload_bp = Blueprint('uploadcsv', __name__) @@ -10,26 +11,39 @@ def upload_file(): if request.method == 'POST': # Check if a file was uploaded if 'file' not in request.files: - return redirect('uploadcsv') + flash("No file uploaded.", "error") + return redirect(request.url) file = request.files['file'] # Check if the file is a 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: - # Extract data from the CSV file + # Extract and validate CSV data csvdata = get_csv_data(file) - # Identify the primary attribute - primary_attrib = next( - (attrib for attrib in item_attributes if attrib.primary), - None - ) + # Validate each row of data + errors = [] + for i, row in enumerate(csvdata, start=1): + 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: - return "Primary attribute not defined in configuration." + flash("Primary attribute not defined in configuration.", "error") + return redirect(request.url) # Separate new and existing assets new_assets = [] @@ -54,8 +68,8 @@ def upload_file(): except Exception as e: # Handle errors during file processing - print(f"Error processing CSV file: {str(e)}") - return redirect('uploadcsv') + flash(f"Error processing CSV file: {str(e)}", "error") + return redirect(request.url) # Render the upload page for GET requests return render_template('upload.html') \ No newline at end of file diff --git a/templates/csv_preview.html b/templates/csv_preview.html index d73a2f0..ee8159a 100644 --- a/templates/csv_preview.html +++ b/templates/csv_preview.html @@ -9,50 +9,35 @@
New assets:
-{{ attrib.display_name }} | - {% endfor %} -||||
---|---|---|---|---|
{{ asset[attrib.attrib_name] }} | + + {% for table_name, assets, editable in [ + ('New Assets', new_assets, true), + ('Existing Assets', existing, false) + ] %} + {% if assets %} +
{{ attrib.display_name }} | + {% endfor %} +
---|
+ {{ asset[attrib.attrib_name] }} + | + {% endfor %} +
These assets are already in the database:
-{{ attrib.display_name }} | - {% endfor %} -
---|
{{ asset[attrib.attrib_name] }} | - {% endfor %} -
{{ message }}
+ {% endfor %} + {% endif %} + {% endwith %} + + + {% if errors %} +{{ error }}
- {% endif %}