CoolFace
Apppublic

selenium/thesis-file

sourceHugging Faceupdated 11mo agoView on Hugging Face
0likes
app.py154 linesDownload Raw Back to backend
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