File size: 8,531 Bytes
c5462e1
9d1b3b9
 
 
 
c5462e1
8c5881f
bbd376b
 
4a38b92
6c7193e
8c5881f
 
 
9d1b3b9
 
b48a6a2
9d1b3b9
b48a6a2
9d1b3b9
 
 
 
 
bbd376b
 
6c7193e
 
 
 
 
 
 
8c5881f
4a38b92
 
6c7193e
4a38b92
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6c7193e
4a38b92
 
 
 
bbd376b
 
8c5881f
6c7193e
bbd376b
 
 
 
 
 
 
 
4a38b92
 
 
 
 
 
8c5881f
6c7193e
4a38b92
 
8c5881f
 
6c7193e
 
 
 
 
 
 
 
 
 
8c5881f
 
 
 
 
 
c5462e1
 
9d1b3b9
 
 
 
c5462e1
9d1b3b9
c5462e1
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
e0f186d
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
c5462e1
9d1b3b9
 
 
 
 
8c5881f
 
 
bbd376b
 
 
 
 
58da237
c5462e1
58da237
c5462e1
 
 
58da237
fae4149
443465b
 
 
fae4149
443465b
 
 
fae4149
443465b
 
 
 
 
 
 
 
 
 
 
c5462e1
 
 
 
 
 
 
443465b
 
 
c5462e1
443465b
c5462e1
443465b
c5462e1
 
443465b
c5462e1
 
 
fae4149
 
c5462e1
 
9d1b3b9
 
c5462e1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
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

@app.route("/", methods=["GET", "POST"])
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)