- version : 0.7

- description : adding download template option and move (template.csv -> templates/template.csv).
هذا الالتزام موجود في:
2025-06-11 18:19:44 +03:00
الأصل 6840e565a4
التزام c5d5c1408c
3 ملفات معدلة مع 41 إضافات و27 حذوفات

17
app.py
عرض الملف

@@ -2,7 +2,7 @@ import sqlite3
import csv import csv
import io import io
import re import re
from flask import Flask, render_template, request, redirect, url_for, flash from flask import Flask, render_template, request, redirect, url_for, flash, send_from_directory
# --- App Setup --- # --- App Setup ---
app = Flask(__name__) app = Flask(__name__)
@@ -50,8 +50,8 @@ def validate_phone(phone):
def validate_student_data(form_data, is_csv=False): def validate_student_data(form_data, is_csv=False):
errors = [] errors = []
required_fields = ['student_name', 'age', 'parent_name', required_fields = ['student_name', 'age', 'parent_name',
'parent_phone_1', 'grade', 'school_name', 'parent_phone_1', 'grade', 'school_name',
'address', 'memorizing'] 'address', 'memorizing']
# Check required fields # Check required fields
for field in required_fields: for field in required_fields:
@@ -197,7 +197,7 @@ def import_csv():
student_data['address'], student_data['address'],
student_data['memorizing'] student_data['memorizing']
)) ))
# Process validation results # Process validation results
if row_errors: if row_errors:
flash(f'تم العثور على أخطاء في {len(row_errors)} سطراً', 'warning') flash(f'تم العثور على أخطاء في {len(row_errors)} سطراً', 'warning')
@@ -228,5 +228,12 @@ def import_csv():
return redirect(url_for('index')) return redirect(url_for('index'))
# New route to download the CSV template
@app.route('/download_csv_template')
def download_csv_template():
# The directory where the template.csv is located (your templates folder)
# The second argument is the filename to be sent
return send_from_directory(app.template_folder, 'template.csv', as_attachment=True)
if __name__ == '__main__': if __name__ == '__main__':
app.run(debug=True) app.run(debug=True)

عرض الملف

@@ -62,33 +62,40 @@
</div> </div>
<div class="bg-white p-6 rounded-xl shadow-lg mb-8"> <div class="bg-white p-6 rounded-xl shadow-lg mb-8">
<h2 class="text-2xl font-semibold mb-4 text-gray-800 border-b pb-4">استيراد من ملف CSV</h2> <h2 class="text-2xl font-semibold mb-4 text-gray-800 border-b pb-4">استيراد من ملف CSV</h2>
<div class="bg-yellow-50 border border-yellow-200 text-yellow-800 text-sm p-4 rounded-lg mt-4"> <div class="bg-yellow-50 border border-yellow-200 text-yellow-800 text-sm p-4 rounded-lg mt-4">
<p class="font-bold">هام: تنسيق ملف CSV</p> <p class="font-bold">هام: تنسيق ملف CSV</p>
<p>يجب أن يكون الملف بصيغة CSV ومرمّزاً بترميز UTF-8.</p> <p>يجب أن يكون الملف بصيغة CSV ومرمّزاً بترميز UTF-8.</p>
<p>يجب **ألا يحتوي** الملف على صف للعناوين، ويجب أن تكون الأعمدة بالترتيب الدقيق التالي:</p> <p>يجب **ألا يحتوي** الملف على صف للعناوين، ويجب أن تكون الأعمدة بالترتيب الدقيق التالي:</p>
<p class="mt-2" style="direction: ltr; text-align: right;"> <p class="mt-2" style="direction: ltr; text-align: right;">
<code class="text-xs font-mono">اسم الطالب, العمر, اسم ولي الأمر, هاتف ولي الأمر 1, هاتف ولي الأمر 2, هاتف الطالب, الصف, اسم المدرسة, العنوان, المحفوظات</code> <code class="text-xs font-mono">اسم الطالب, العمر, اسم ولي الأمر, هاتف ولي الأمر 1, هاتف ولي الأمر 2, هاتف الطالب, الصف, اسم المدرسة, العنوان, المحفوظات</code>
</p> </p>
<p>إذا كانت الحقول الاختيارية (هاتف ولي الأمر 2، هاتف الطالب) فارغة، اتركها كذلك.</p> <p>إذا كانت الحقول الاختيارية (هاتف ولي الأمر 2، هاتف الطالب) فارغة، اتركها كذلك.</p>
</div> {# Added link to download CSV template #}
<div class="mt-6 text-left"> <p class="mt-3">
<form id="import-form" action="{{ url_for('import_csv') }}" method="POST" enctype="multipart/form-data"> <a href="{{ url_for('download_csv_template') }}" class="text-blue-600 hover:underline font-semibold" download>
<input type="file" name="file" id="csv-file-input" class="hidden" required accept=".csv"> تنزيل قالب CSV
</a>
</p>
</div>
<div class="mt-6 text-left">
<form id="import-form" action="{{ url_for('import_csv') }}" method="POST" enctype="multipart/form-data">
<input type="file" name="file" id="csv-file-input" class="hidden" required accept=".csv">
<button type="button" id="choose-file-button" class="px-6 py-2 bg-green-600 text-white font-semibold rounded-lg shadow-md hover:bg-green-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-green-500 transition-all"> <button type="button" id="choose-file-button" class="px-6 py-2 bg-green-600 text-white font-semibold rounded-lg shadow-md hover:bg-green-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-green-500 transition-all">
اختر ملف اختر ملف
</button> </button>
<span id="file-name-display" class="hidden ml-4 text-gray-700"></span> <span id="file-name-display" class="hidden ml-4 text-gray-700"></span>
<button type="submit" id="submit-import-button" class="hidden px-6 py-2 bg-blue-600 text-white font-semibold rounded-lg shadow-md hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 transition-all"> <button type="submit" id="submit-import-button" class="hidden px-6 py-2 bg-blue-600 text-white font-semibold rounded-lg shadow-md hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 transition-all">
تأكيد ورفع الملف تأكيد ورفع الملف
</button> </button>
</form> </form>
</div> </div>
</div> </div>
<div class="bg-white p-6 rounded-xl shadow-lg"> <div class="bg-white p-6 rounded-xl shadow-lg">
<div class="flex justify-between items-center mb-4 pb-4 border-b"> <div class="flex justify-between items-center mb-4 pb-4 border-b">
<h2 class="text-2xl font-semibold text-gray-800">الطلاب المسجلون</h2> <h2 class="text-2xl font-semibold text-gray-800">الطلاب المسجلون</h2>

عرض الملف

لا يمكن عرض هذا الملف لأنه يحتوي على عدد خاطئ من الحقول في السطر 5.