ShutterStack commited on
Commit
b069a06
·
verified ·
1 Parent(s): 5d10236

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +108 -130
app.py CHANGED
@@ -11,60 +11,29 @@ import numpy as np
11
  import json
12
  import sqlite3
13
 
14
- # Ensure directories exist and are absolute
15
- BASE_DIR = os.path.dirname(os.path.abspath(__file__))
16
- UPLOAD_FOLDER = os.path.join(BASE_DIR, 'uploads')
17
- RESULTS_FOLDER = os.path.join(BASE_DIR, 'results')
18
- os.makedirs(UPLOAD_FOLDER, exist_ok=True)
19
- os.makedirs(RESULTS_FOLDER, exist_ok=True)
20
-
21
- # Model and data paths - Hugging Face assumes these are in the root directory
22
- MODEL_CLASSIFICATION_PATH = "models/classification.pt"
23
- MODEL_DETECTION_PATH = "models/detection.pt"
24
-
25
- # Load YOLOv8 models
26
- try:
27
- classifier = YOLO(MODEL_CLASSIFICATION_PATH)
28
- detector = YOLO(MODEL_DETECTION_PATH)
29
- except Exception as e:
30
- print(f"Model loading error: {e}")
31
- classifier = None
32
- detector = None
33
-
34
- # Initialize EasyOCR
35
- try:
36
- reader = Reader(['en'])
37
- except Exception as e:
38
- print(f"EasyOCR initialization error: {e}")
39
- reader = None
40
-
41
  app = Flask(__name__)
42
- app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER
43
- app.config['RESULTS_FOLDER'] = RESULTS_FOLDER
44
-
45
- def safe_process_image(image_path):
46
- """Safe image processing with extensive error handling"""
47
- try:
48
- if not classifier or not detector or not reader:
49
- raise ValueError("Models not properly initialized")
50
-
51
- classification_result = classifier.predict(image_path)[0]
52
- if classification_result.probs.numpy().top1 == 0:
53
- fields = detector(image_path)
54
- image = cv2.imread(image_path)
55
- extracted_data = {}
56
-
57
- for field in fields[0].boxes.data.tolist():
58
- x1, y1, x2, y2, confidence, class_id = map(int, field[:6])
59
- field_class = detector.names[class_id]
60
- cropped_roi = image[y1:y2, x1:x2]
61
- gray_roi = cv2.cvtColor(cropped_roi, cv2.COLOR_BGR2GRAY)
62
- text = reader.readtext(gray_roi, detail=0)
63
- extracted_data[field_class] = ' '.join(text)
64
-
65
- return extracted_data
66
- except Exception as e:
67
- print(f"Image processing error: {e}")
68
  return None
69
 
70
  # Helper Functions
@@ -249,6 +218,43 @@ def create_visualizations(comparison_results):
249
 
250
  return visualization_data
251
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
252
 
253
  @app.route('/download', methods=['GET'])
254
  def download_results():
@@ -271,87 +277,59 @@ def about():
271
  def contact():
272
  return render_template('contact.html')
273
 
274
- @app.route('/', methods=['GET', 'POST'])
275
  def upload_files():
276
- if request.method == 'POST':
277
- # Check if the post request has the files
278
- if 'zipfile' not in request.files or 'excelfile' not in request.files:
279
- return jsonify({"error": "Both zipfile and excelfile are required."}), 400
280
-
281
  zip_file = request.files['zipfile']
282
  excel_file = request.files['excelfile']
283
 
284
- # Validate file types
285
- if not zip_file.filename.endswith('.zip') or not excel_file.filename.endswith('.xlsx'):
286
- return jsonify({"error": "Invalid file formats. Need .zip and .xlsx files."}), 400
287
-
288
- try:
289
- # Save files temporarily (Hugging Face Spaces has a temporary file system)
290
- zip_path = zip_file.filename
291
- excel_path = excel_file.filename
292
- zip_file.save(zip_path)
293
- excel_file.save(excel_path)
294
-
295
- # Extract zip
296
- with zipfile.ZipFile(zip_path, 'r') as zip_ref:
297
- zip_ref.extractall('.')
298
-
299
- # Process images
300
- image_paths = [f for f in os.listdir('.') if f.lower().endswith(('.jpg', '.jpeg', '.png'))]
301
- processed_results = {}
302
- for image_path in image_paths:
303
- try:
304
- file_name = os.path.basename(image_path)
305
- key = file_name.split('.')[0][:3]
306
- if key not in processed_results:
307
- extracted_data = process_image(image_path) # Assuming process_image is defined
308
- if extracted_data:
309
- processed_results[key] = extracted_data
310
- except Exception as e:
311
- print(f"Error processing image {image_path}: {str(e)}")
312
-
313
- # Process Excel
314
- df = pd.read_excel(excel_path)
315
- df = df.astype(str)
316
- comparison_results = compare_data(df, processed_results) # Assuming compare_data is defined
317
- comparison_results['Accepted/Rejected'] = np.where(
318
- comparison_results['Final Remarks'] == 'All matched',
319
- 'Accepted',
320
- 'Rejected'
321
- )
322
-
323
- # Prepare for download - adjust path if needed
324
- results_df = pd.DataFrame(comparison_results)
325
- results_file_path = 'results.xlsx'
326
- results_df.to_excel(results_file_path, index=False)
327
-
328
- visualization_data = create_visualizations(comparison_results) # Assuming create_visualizations is defined
329
-
330
- # For now, return results as JSON, consider a download link for the Excel
331
- return jsonify({
332
- "message": "Files processed successfully!",
333
- "results": comparison_results[
334
- ['SrNo', 'Document Type', 'Accepted/Rejected', 'Final Remarks']
335
- ].to_dict(orient='records'),
336
- "visualization_data": visualization_data
337
- })
338
-
339
- except Exception as e:
340
- return jsonify({"error": f"Processing error: {str(e)}"}), 500
341
-
342
- finally:
343
- # Clean up temporary files
344
- if os.path.exists(zip_path):
345
- os.remove(zip_path)
346
- if os.path.exists(excel_path):
347
- os.remove(excel_path)
348
- for image_path in image_paths:
349
- if os.path.exists(image_path):
350
- os.remove(image_path)
351
-
352
- else: # GET request
353
- return render_template("services.html")
354
 
355
  if __name__ == '__main__':
356
- # Configure HTTPS with self-signed certificate
357
  app.run(debug=True, host="0.0.0.0", port=int(os.environ.get("PORT", 7680)))
 
11
  import json
12
  import sqlite3
13
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
14
  app = Flask(__name__)
15
+ app.config['UPLOAD_FOLDER'] = 'uploads/'
16
+ app.config['ALLOWED_EXTENSIONS'] = {'zip', 'xlsx'}
17
+ app.config['RESULTS_FOLDER'] = 'results/'
18
+ app.config['DATABASE'] = 'results_ack.db'
19
+
20
+ classifier = YOLO("./models/classification.pt")
21
+ detector = YOLO("./models/detection.pt")
22
+ reader = Reader(['en'])
23
+
24
+ def process_image(image_path):
25
+ if classifier.predict(image_path)[0].probs.numpy().top1 == 0:
26
+ fields = detector(image_path)
27
+ image = cv2.imread(image_path)
28
+ extracted_data = {}
29
+ for field in fields[0].boxes.data.tolist():
30
+ x1, y1, x2, y2, confidence, class_id = map(int, field[:6])
31
+ field_class = detector.names[class_id]
32
+ cropped_roi = image[y1:y2, x1:x2]
33
+ gray_roi = cv2.cvtColor(cropped_roi, cv2.COLOR_BGR2GRAY)
34
+ text = reader.readtext(gray_roi, detail=0)
35
+ extracted_data[field_class] = ' '.join(text)
36
+ return extracted_data
 
 
 
 
37
  return None
38
 
39
  # Helper Functions
 
218
 
219
  return visualization_data
220
 
221
+ def create_database_and_table():
222
+ """Creates the database and table if they don't exist."""
223
+ conn = sqlite3.connect(app.config['DATABASE'])
224
+ cursor = conn.cursor()
225
+
226
+ cursor.execute('''
227
+ CREATE TABLE IF NOT EXISTS results (
228
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
229
+ SrNo TEXT,
230
+ DocumentType TEXT,
231
+ AcceptedRejected TEXT,
232
+ FinalRemarks TEXT
233
+ )
234
+ ''')
235
+ conn.commit()
236
+ conn.close()
237
+
238
+ def save_results_to_database(results):
239
+ """Saves the provided results to the SQLite database."""
240
+ conn = sqlite3.connect(app.config['DATABASE'])
241
+ cursor = conn.cursor()
242
+
243
+ for result in results:
244
+ cursor.execute('''
245
+ INSERT INTO results (SrNo, DocumentType, AcceptedRejected, FinalRemarks)
246
+ VALUES (?, ?, ?, ?)
247
+ ''', (
248
+ result.get('SrNo', ''),
249
+ result.get('Document Type', ''),
250
+ result.get('Accepted/Rejected', ''),
251
+ result.get('Final Remarks', '')
252
+ ))
253
+
254
+ conn.commit()
255
+ conn.close()
256
+
257
+
258
 
259
  @app.route('/download', methods=['GET'])
260
  def download_results():
 
277
  def contact():
278
  return render_template('contact.html')
279
 
280
+ @app.route('/upload', methods=['POST'])
281
  def upload_files():
282
+ if 'zipfile' in request.files and 'excelfile' in request.files:
 
 
 
 
283
  zip_file = request.files['zipfile']
284
  excel_file = request.files['excelfile']
285
 
286
+ # Save files
287
+ zip_path = os.path.join(app.config['UPLOAD_FOLDER'], zip_file.filename)
288
+ excel_path = os.path.join(app.config['UPLOAD_FOLDER'], excel_file.filename)
289
+ zip_file.save(zip_path)
290
+ excel_file.save(excel_path)
291
+
292
+ # Unzip and process images
293
+ with zipfile.ZipFile(zip_path, 'r') as zip_ref:
294
+ zip_ref.extractall(app.config['UPLOAD_FOLDER'])
295
+
296
+ image_paths = [os.path.join(app.config['UPLOAD_FOLDER'], f) for f in os.listdir(app.config['UPLOAD_FOLDER']) if f.endswith(('.jpg', '.png'))]
297
+ processed_results = {}
298
+
299
+ for image_path in image_paths:
300
+ file_name = os.path.basename(image_path)
301
+ key = file_name.split('.')[0][:3]
302
+ if key not in processed_results: # Check if key already exists
303
+ extracted_data = process_image(image_path)
304
+ if extracted_data:
305
+ processed_results[key] = extracted_data
306
+
307
+ # Read Excel and compare data
308
+ df = pd.read_excel(excel_path)
309
+ df = df.astype('str')
310
+ comparison_results = compare_data(df, processed_results)
311
+ comparison_results['Accepted/Rejected'] = np.where(comparison_results['Final Remarks'] == 'All matched', 'Accepted', 'Rejected')
312
+
313
+ # Save results to a new Excel file
314
+ results_df = pd.DataFrame(comparison_results)
315
+ os.makedirs(app.config['RESULTS_FOLDER'], exist_ok=True)
316
+ results_file_path = os.path.join(app.config['RESULTS_FOLDER'], 'results.xlsx')
317
+ results_df.to_excel(results_file_path, index=False)
318
+
319
+ visualization_data = create_visualizations(comparison_results)
320
+
321
+ create_database_and_table() # Ensure database and table exist
322
+ save_results_to_database(comparison_results[
323
+ ['SrNo', 'Document Type', 'Accepted/Rejected', 'Final Remarks']
324
+ ].to_dict(orient='records'))
325
+
326
+ return jsonify({"message": "Files processed successfully!",
327
+ "results": comparison_results[
328
+ ['SrNo', 'Document Type', 'Accepted/Rejected', 'Final Remarks']
329
+ ].to_dict(orient='records'),
330
+ "visualization_data": visualization_data})
331
+
332
+ return jsonify({"error": "Both files are required."}), 400
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
333
 
334
  if __name__ == '__main__':
 
335
  app.run(debug=True, host="0.0.0.0", port=int(os.environ.get("PORT", 7680)))