selenium/thesis-file
0
1import os2from flask import Flask, request, jsonify, send_from_directory, abort3from flask_cors import CORS4from ocr.ocr_reader import extract_text_from_image, extract_text_from_pdf5from web3 import Web36import tempfile7 8# Config from environment9INFURA_URL = "https://sepolia.infura.io/v3/144a5ebad90e47a7896bb110b32bf6c8"10CONTRACT_ADDRESS = "0x2ACF0d5b4d112848AfE5c0e626765cA6E7eFE160"11 12app = Flask(__name__, static_folder='../frontend', static_url_path='')13CORS(app)14 15# Initialize Web3 if INFURA_URL provided16w3 = None17contract = None18CONTRACT_ABI = [19 {20 "inputs": [21 {"internalType": "bytes32", "name": "fileHash", "type": "bytes32"},22 {"internalType": "string", "name": "studentId", "type": "string"},23 {"internalType": "string", "name": "docType", "type": "string"}24 ],25 "name": "recordRequest",26 "outputs": [],27 "stateMutability": "nonpayable",28 "type": "function"29 },30 {31 "inputs": [32 {"internalType": "bytes32", "name": "fileHash", "type": "bytes32"}33 ],34 "name": "isHashRecorded",35 "outputs": [36 {"internalType": "bool", "name": "", "type": "bool"}37 ],38 "stateMutability": "view",39 "type": "function"40 }41]42 43if INFURA_URL and CONTRACT_ADDRESS:44 try:45 w3 = Web3(Web3.HTTPProvider(INFURA_URL))46 if w3.is_connected():47 contract = w3.eth.contract(address=Web3.to_checksum_address(48 CONTRACT_ADDRESS), abi=CONTRACT_ABI)49 else:50 print(51 'Warning: Could not connect to INFURA URL. Verification will be unavailable.')52 except Exception as e:53 print('Warning initializing Web3:', str(e))54 55 56@app.route('/')57def index():58 # Serve frontend index.html59 return send_from_directory(os.path.join(app.static_folder), 'index.html')60 61 62@app.route('/api/ocr', methods=['POST'])63def api_ocr():64 # Accepts multipart/form-data file upload, returns OCR text and keccak256 file hash65 if 'document' not in request.files:66 return jsonify({'error': 'document file is required'}), 40067 68 file = request.files['document']69 filename = file.filename70 71 # --- FIX: limit file size ---72 MAX_UPLOAD_SIZE = 5 * 1024 * 1024 # 5 MB73 file.seek(0, 2) # move to end74 file_size = file.tell()75 file.seek(0) # reset pointer76 if file_size > MAX_UPLOAD_SIZE:77 return jsonify({'error': 'File too large. Max 5MB allowed.'}), 40078 # --- END FIX ---79 80 # Save to temp file81 tmp = tempfile.NamedTemporaryFile(82 delete=False, suffix=os.path.splitext(filename)[1])83 file.save(tmp.name)84 tmp.flush()85 86 text = ''87 file_hash = None88 try:89 # Run OCR (image or pdf)90 if tmp.name.lower().endswith('.pdf'):91 text = extract_text_from_pdf(tmp.name)92 else:93 text = extract_text_from_image(tmp.name)94 95 # Compute keccak256 hash of raw bytes96 with open(tmp.name, 'rb') as f:97 file_bytes = f.read()98 file_hash = Web3.keccak(file_bytes).hex() if Web3 else None99 100 except Exception as e:101 text = f'OCR error: {str(e)}'102 file_hash = None103 104 finally:105 # Cleanup temp file and free memory106 try:107 tmp.close()108 os.remove(tmp.name)109 except Exception:110 pass111 import gc112 gc.collect()113 114 return jsonify({115 'ocr_text': text,116 'file_hash': file_hash,117 'filename': filename118 })119 120 121@app.route('/api/verify', methods=['GET'])122def api_verify():123 file_hash = request.args.get('file_hash')124 if not file_hash:125 return jsonify({'error': 'file_hash query parameter required'}), 400126 if not contract:127 return jsonify({'error': 'Blockchain verification unavailable (no INFURA_URL or CONTRACT_ADDRESS)'}), 503128 try:129 # convert hex string to bytes32130 if file_hash.startswith('0x'):131 arg = bytes.fromhex(file_hash[2:])132 else:133 arg = bytes.fromhex(file_hash)134 res = contract.functions.isHashRecorded(arg).call()135 return jsonify({'recorded': bool(res)})136 except Exception as e:137 return jsonify({'error': str(e)}), 500138 139# Serve frontend static files under /static path for convenience140 141 142@app.route('/<path:path>')143def static_proxy(path):144 # send static files from frontend folder145 full = os.path.join(app.static_folder, path)146 if os.path.exists(full):147 return send_from_directory(app.static_folder, path)148 else:149 abort(404)150 151 152if __name__ == '__main__':153 app.run(host='0.0.0.0', port=int(os.getenv('PORT', 5000)), debug=True)154 