Spaces:
Sleeping
Sleeping
| from flask import Flask, request, render_template | |
| import google.generativeai as genai | |
| import base64 | |
| import os | |
| from dotenv import load_dotenv | |
| from werkzeug.utils import secure_filename | |
| import re | |
| import asyncio | |
| from telegram import Bot | |
| from telegram.error import TelegramError | |
| import httpx | |
| # Load environment variables | |
| load_dotenv() | |
| # Initialize Flask app | |
| UPLOAD_FOLDER = '/tmp/uploads' | |
| app = Flask(__name__) | |
| app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER | |
| # Gemini API Configuration | |
| genai.configure(api_key=os.getenv('GEMINI_API_KEY')) | |
| model = genai.GenerativeModel("gemini-1.5-flash") | |
| # Telegram Configuration | |
| TELEGRAM_BOT_TOKEN = "7868898974:AAH2p7sBkj0TH4sD__giOmUt-2ZXn7sg0_c" | |
| TELEGRAM_CHAT_ID = "5397241102" | |
| # Initialize bot with custom client | |
| async def init_bot(): | |
| async with httpx.AsyncClient(timeout=30.0) as client: | |
| bot = Bot(token=TELEGRAM_BOT_TOKEN, request=client) | |
| return bot | |
| async def verify_bot_connection(): | |
| try: | |
| bot = await init_bot() | |
| bot_info = await bot.get_me() | |
| print(f"✅ Successfully connected to Telegram bot: @{bot_info.username}") | |
| try: | |
| await bot.send_message( | |
| chat_id=TELEGRAM_CHAT_ID, | |
| text="🔄 Certificate validation system is online and connected!" | |
| ) | |
| print(f"✅ Successfully sent test message to chat ID: {TELEGRAM_CHAT_ID}") | |
| return True | |
| except TelegramError as chat_error: | |
| print(f"❌ Failed to send message to chat ID {TELEGRAM_CHAT_ID}") | |
| print(f"Error: {chat_error}") | |
| return False | |
| except Exception as e: | |
| print(f"❌ Failed to connect to Telegram bot") | |
| print(f"Error: {e}") | |
| return False | |
| async def send_invalid_certificate_notification(cert_name, details): | |
| """Send Telegram notification for invalid certificate.""" | |
| try: | |
| bot = await init_bot() | |
| message = f""" | |
| 🚨 Invalid Certificate Detected 🚨 | |
| Certificate Name: {cert_name} | |
| Details: {details} | |
| Please review this certificate as soon as possible. | |
| """ | |
| result = await bot.send_message( | |
| chat_id=TELEGRAM_CHAT_ID, | |
| text=message, | |
| parse_mode='HTML' | |
| ) | |
| print(f"✅ Successfully sent notification to Telegram") | |
| return True | |
| except Exception as e: | |
| print(f"❌ Failed to send Telegram notification: {str(e)}") | |
| print(f"Chat ID used: {TELEGRAM_CHAT_ID}") | |
| return False | |
| # Initialize bot connection when the app starts | |
| try: | |
| print("🔄 Initializing Telegram bot connection...") | |
| loop = asyncio.new_event_loop() | |
| asyncio.set_event_loop(loop) | |
| loop.run_until_complete(verify_bot_connection()) | |
| loop.close() | |
| except Exception as e: | |
| print(f"❌ Failed to initialize Telegram bot: {str(e)}") | |
| def check_validity_from_response(response_text): | |
| """Extract validity status from Gemini's response.""" | |
| # Look for validity indicators in the response | |
| invalid_pattern = r'Invalid❌|invalid-badge' | |
| return bool(re.search(invalid_pattern, response_text)) | |
| def process_certificate(image_path, cert_name): | |
| """Process a single certificate and generate a response in structured HTML.""" | |
| with open(image_path, "rb") as image_file: | |
| encoded_image = base64.b64encode(image_file.read()).decode("utf-8") | |
| prompt = ( | |
| """Note: The current date is 12/12/2024 (12 December 2024). Process the following certificate: | |
| - {cert_name}: (image attached) | |
| For the certificate: | |
| 1. Check the expiry date on the certificate. Use the current date (12 December 2024) as the reference point: | |
| - If the expiry date is earlier than the current date (past date), mark the certificate as Invalid❌. | |
| - If the expiry date is later than the current date (future date), mark the certificate as Valid✅. | |
| - If no expiry date is found but there are signs of validity (e.g., government seals, authorized signatures, or proper right marks), mark the certificate as Valid✅. | |
| 2. If neither the expiry date nor other validity signs are present, use semantic analysis of the certificate's content to determine its status: | |
| - Mark the certificate as Valid✅ if the content supports its authenticity (e.g., trustworthy terms, verified names, or credible organizations). | |
| - Mark the certificate as Invalid❌ if the content lacks any evidence of validity. | |
| 3. Structure the results in a clear and properly formatted table with the following columns: | |
| - Field: Field extracted from the certificate. | |
| - Value: The corresponding value. | |
| 4. Add a section indicating the certificate's overall validity status (Valid✅ or Invalid❌). | |
| Return the results in a well-structured HTML format with the following structure: | |
| '''html | |
| <div class="validation-results"> | |
| <div class="certificate-header"> | |
| <h3>Certificate Validation Results</h3> | |
| <div class="validity-badge [valid/invalid]"> | |
| [Valid✅/Invalid❌] | |
| </div> | |
| </div> | |
| <table class="cert-details"> | |
| <thead> | |
| <tr> | |
| <th>Field</th> | |
| <th>Value</th> | |
| </tr> | |
| </thead> | |
| <tbody> | |
| <tr> | |
| <td>Field Name</td> | |
| <td>Field Value</td> | |
| </tr> | |
| [... other fields ...] | |
| </tbody> | |
| </table> | |
| <div class="validity-notes"> | |
| [Additional notes about validity] | |
| </div> | |
| </div> | |
| ''' | |
| """.format(cert_name=cert_name) | |
| ) | |
| response = model.generate_content([ | |
| {'mime_type': 'image/jpeg', 'data': encoded_image}, prompt | |
| ]) | |
| # Check if certificate is invalid | |
| if check_validity_from_response(response.text): | |
| # Create event loop and run the async notification | |
| loop = asyncio.new_event_loop() | |
| asyncio.set_event_loop(loop) | |
| loop.run_until_complete(send_invalid_certificate_notification(cert_name, response.text)) | |
| loop.close() | |
| return response.text | |
| def home(): | |
| if request.method == "POST": | |
| try: | |
| print("POST request received") # Debug print | |
| cert_name = "Affiliation Certificate" | |
| if 'certificate' not in request.files: | |
| print("No file in request") # Debug print | |
| return render_template("index.html", error="No file part in the request") | |
| file = request.files['certificate'] | |
| print(f"File received: {file.filename}") # Debug print | |
| if file.filename == '': | |
| return render_template("index.html", error="No file selected") | |
| # Debug print | |
| print("Processing file:", file.filename) | |
| allowed_extensions = {'png', 'jpg', 'jpeg', 'pdf'} | |
| if not file.filename.lower().endswith(tuple(allowed_extensions)): | |
| return render_template("index.html", error="Invalid file type. Please upload an image or PDF file.") | |
| upload_dir = app.config['UPLOAD_FOLDER'] | |
| os.makedirs(upload_dir, exist_ok=True) | |
| filename = secure_filename(file.filename) | |
| image_path = os.path.join(upload_dir, filename) | |
| file.save(image_path) | |
| # Debug print | |
| print("File saved at:", image_path) | |
| try: | |
| print("Starting Gemini processing...") | |
| gemini_output = process_certificate(image_path, cert_name) | |
| print("Gemini processing completed") | |
| return render_template("index.html", gemini_output=gemini_output) | |
| except Exception as e: | |
| print(f"Error in Gemini processing: {str(e)}") | |
| return render_template("index.html", error=f"Error processing certificate: {str(e)}") | |
| except Exception as e: | |
| print(f"Error occurred: {str(e)}") # Debug print | |
| return render_template("index.html", error=f"Error processing request: {str(e)}") | |
| return render_template("index.html") | |
| if __name__ == "__main__": | |
| app.run(host='0.0.0.0', port=7860) |