Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
|
@@ -12,69 +12,27 @@ from playwright.async_api import async_playwright
|
|
| 12 |
|
| 13 |
nest_asyncio.apply()
|
| 14 |
|
| 15 |
-
# --- FastAPI Setup
|
| 16 |
app = FastAPI()
|
| 17 |
@app.get("/")
|
| 18 |
def home():
|
| 19 |
return {"status": "Bot is Running on Hugging Face"}
|
| 20 |
|
| 21 |
def run_fastapi():
|
| 22 |
-
# Hugging Face डिफ़ॉल्ट रूप से पोर्ट 7860 का उपयोग करता है
|
| 23 |
port = int(os.environ.get("PORT", 7860))
|
| 24 |
uvicorn.run(app, host="0.0.0.0", port=port)
|
| 25 |
|
| 26 |
-
# ---
|
| 27 |
BOT_TOKEN = "7936101320:AAGTHSCteVyYUzPb-snNWXDn9MxQDZUXs1M"
|
| 28 |
|
| 29 |
-
# --- PDF विश्लेषण लॉजिक ---
|
| 30 |
-
def extract_student_info(pdf_path):
|
| 31 |
-
info = {"name": "Not Found", "father": "Not Found", "mother": "Not Found",
|
| 32 |
-
"email": "Not Found", "abc_id": "Not Found", "roll": "Not Found",
|
| 33 |
-
"college": "Not Found", "center": "Not Found"}
|
| 34 |
-
try:
|
| 35 |
-
doc = fitz.open(pdf_path)
|
| 36 |
-
text = "".join([page.get_text() for page in doc])
|
| 37 |
-
|
| 38 |
-
roll_match = re.search(r"Roll no is\s+([\w\d]+)", text)
|
| 39 |
-
if roll_match: info["roll"] = roll_match.group(1).strip()
|
| 40 |
-
|
| 41 |
-
name_match = re.search(r"NAME OF CANDIDATE\s*:\s*(.*)", text)
|
| 42 |
-
if name_match: info["name"] = name_match.group(1).split('\n')[0].strip()
|
| 43 |
-
|
| 44 |
-
father_match = re.search(r"FATHER'S NAME\s*:\s*(.*)", text)
|
| 45 |
-
if father_match: info["father"] = father_match.group(1).split('\n')[0].strip()
|
| 46 |
-
|
| 47 |
-
mother_match = re.search(r"MOTHER'S NAME\s*:\s*(.*)", text)
|
| 48 |
-
if mother_match: info["mother"] = mother_match.group(1).split('\n')[0].strip()
|
| 49 |
-
|
| 50 |
-
email_match = re.search(r"EMAIL ID\s*:\s*(.*)", text)
|
| 51 |
-
if email_match: info["email"] = email_match.group(1).split('\n')[0].strip()
|
| 52 |
-
|
| 53 |
-
abc_match = re.search(r"ABC ID\s*:\s*(\d+)", text)
|
| 54 |
-
if abc_match: info["abc_id"] = abc_match.group(1).strip()
|
| 55 |
-
|
| 56 |
-
college_match = re.search(r"COLLEGE NAME\s*:\s*(.*)", text)
|
| 57 |
-
if college_match: info["college"] = college_match.group(1).split('\n')[0].strip()
|
| 58 |
-
|
| 59 |
-
center_pattern = r"Exam Centre is\s*(.*?)(?=Print Date|To,|The Centre|NAME OF EXAMINATION)"
|
| 60 |
-
center_match = re.search(center_pattern, text, re.DOTALL)
|
| 61 |
-
if center_match: info["center"] = " ".join(center_match.group(1).split())
|
| 62 |
-
|
| 63 |
-
doc.close()
|
| 64 |
-
return info
|
| 65 |
-
except Exception as e:
|
| 66 |
-
print(f"Extraction Error: {e}")
|
| 67 |
-
return info
|
| 68 |
-
|
| 69 |
-
# --- डाउनलोड लॉजिक ---
|
| 70 |
async def download_jnvu_pdf(form_number):
|
| 71 |
pdf_path = f"admit_card_{form_number}.pdf"
|
| 72 |
-
|
| 73 |
-
|
| 74 |
-
|
| 75 |
-
|
| 76 |
-
|
| 77 |
-
|
| 78 |
await page.goto(url, wait_until="load", timeout=60000)
|
| 79 |
await page.fill("#txtchallanNo", str(form_number))
|
| 80 |
async with page.expect_download(timeout=30000) as download_info:
|
|
@@ -83,68 +41,66 @@ async def download_jnvu_pdf(form_number):
|
|
| 83 |
await download.save_as(pdf_path)
|
| 84 |
await browser.close()
|
| 85 |
return pdf_path
|
| 86 |
-
|
| 87 |
-
|
| 88 |
-
|
| 89 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 90 |
|
| 91 |
-
# --- टेलीग्राम हैंडलर ---
|
| 92 |
-
# --- टेलीग्राम हैंडलर (इसे वैसा ही रहने दें) ---
|
| 93 |
async def handle_message(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
| 94 |
user_input = update.message.text.strip()
|
| 95 |
-
if
|
| 96 |
-
await update.message.reply_text("
|
| 97 |
-
|
| 98 |
-
|
| 99 |
-
|
| 100 |
-
|
| 101 |
-
|
| 102 |
-
if file_path and os.path.exists(file_path):
|
| 103 |
-
data = extract_student_info(file_path)
|
| 104 |
-
caption = (f"✅ **Admit Card Found!**\n\n👤 **Name:** `{data['name']}`\n👨💼 **Father:** `{data['father']}`\n"
|
| 105 |
-
f"🎓 **College:** `{data['college']}`\n🔢 **Roll No:** `{data['roll']}`\n🏫 **Center:**\n`{data['center']}`")
|
| 106 |
-
try:
|
| 107 |
-
with open(file_path, 'rb') as doc:
|
| 108 |
-
await update.message.reply_document(document=doc, caption=caption, parse_mode='Markdown')
|
| 109 |
os.remove(file_path)
|
| 110 |
-
await
|
| 111 |
-
|
| 112 |
-
await
|
| 113 |
-
else:
|
| 114 |
-
await status_msg.edit_text("❌ एडमिट कार्ड नहीं मिला।")
|
| 115 |
|
| 116 |
-
# ---
|
| 117 |
async def main_bot():
|
| 118 |
-
|
| 119 |
-
|
| 120 |
-
|
| 121 |
-
|
| 122 |
-
bot_app.add_handler(CommandHandler("start", lambda u, c: u.message.reply_text("नमस्ते! अपना Form Number भेजें।")))
|
| 123 |
-
bot_app.add_handler(MessageHandler(filters.TEXT & (~filters.COMMAND), handle_message))
|
| 124 |
-
|
| 125 |
-
print("✅ बॉट लोड हो रहा है, नेटवर्क का इंतज़ार...")
|
| 126 |
-
|
| 127 |
while True:
|
|
|
|
| 128 |
try:
|
| 129 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 130 |
async with bot_app:
|
| 131 |
await bot_app.initialize()
|
| 132 |
await bot_app.start()
|
| 133 |
await bot_app.updater.start_polling()
|
| 134 |
-
print("
|
| 135 |
-
while
|
| 136 |
-
await asyncio.sleep(
|
| 137 |
except Exception as e:
|
| 138 |
-
print(f"❌ कनेक्शन एरर: {e}
|
| 139 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 140 |
|
| 141 |
if __name__ == "__main__":
|
| 142 |
-
# FastAPI को अलग थ्रेड में चलाएं
|
| 143 |
threading.Thread(target=run_fastapi, daemon=True).start()
|
| 144 |
-
|
| 145 |
-
# बॉट को मुख्य लूप में चलाएं
|
| 146 |
try:
|
| 147 |
asyncio.run(main_bot())
|
| 148 |
-
except
|
| 149 |
-
|
| 150 |
-
|
|
|
|
| 12 |
|
| 13 |
nest_asyncio.apply()
|
| 14 |
|
| 15 |
+
# --- FastAPI Setup ---
|
| 16 |
app = FastAPI()
|
| 17 |
@app.get("/")
|
| 18 |
def home():
|
| 19 |
return {"status": "Bot is Running on Hugging Face"}
|
| 20 |
|
| 21 |
def run_fastapi():
|
|
|
|
| 22 |
port = int(os.environ.get("PORT", 7860))
|
| 23 |
uvicorn.run(app, host="0.0.0.0", port=port)
|
| 24 |
|
| 25 |
+
# --- JNVU Logic ---
|
| 26 |
BOT_TOKEN = "7936101320:AAGTHSCteVyYUzPb-snNWXDn9MxQDZUXs1M"
|
| 27 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 28 |
async def download_jnvu_pdf(form_number):
|
| 29 |
pdf_path = f"admit_card_{form_number}.pdf"
|
| 30 |
+
try:
|
| 31 |
+
async with async_playwright() as p:
|
| 32 |
+
browser = await p.chromium.launch(headless=True, args=["--no-sandbox", "--disable-setuid-sandbox"])
|
| 33 |
+
context = await browser.new_context(accept_downloads=True)
|
| 34 |
+
page = await context.new_page()
|
| 35 |
+
url = "https://erp.jnvuiums.in/(S(biolzjtwlrcfmzwwzgs5uj5n))/Exam/Pre_Exam/Exam_ForALL_AdmitCard.aspx#"
|
| 36 |
await page.goto(url, wait_until="load", timeout=60000)
|
| 37 |
await page.fill("#txtchallanNo", str(form_number))
|
| 38 |
async with page.expect_download(timeout=30000) as download_info:
|
|
|
|
| 41 |
await download.save_as(pdf_path)
|
| 42 |
await browser.close()
|
| 43 |
return pdf_path
|
| 44 |
+
except Exception as e:
|
| 45 |
+
print(f"Download Error: {e}")
|
| 46 |
+
return None
|
| 47 |
+
|
| 48 |
+
def extract_student_info(pdf_path):
|
| 49 |
+
info = {"name": "N/A", "college": "N/A", "roll": "N/A", "center": "N/A"}
|
| 50 |
+
try:
|
| 51 |
+
doc = fitz.open(pdf_path)
|
| 52 |
+
text = "".join([page.get_text() for page in doc])
|
| 53 |
+
name_match = re.search(r"NAME OF CANDIDATE\s*:\s*(.*)", text)
|
| 54 |
+
if name_match: info["name"] = name_match.group(1).split('\n')[0].strip()
|
| 55 |
+
doc.close()
|
| 56 |
+
except: pass
|
| 57 |
+
return info
|
| 58 |
|
|
|
|
|
|
|
| 59 |
async def handle_message(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
| 60 |
user_input = update.message.text.strip()
|
| 61 |
+
if user_input.isdigit():
|
| 62 |
+
status = await update.message.reply_text("⏳ एडमिट कार्ड निकाल रहा हूँ...")
|
| 63 |
+
file_path = await download_jnvu_pdf(user_input)
|
| 64 |
+
if file_path and os.path.exists(file_path):
|
| 65 |
+
data = extract_student_info(file_path)
|
| 66 |
+
caption = f"✅ एडमिट कार्ड मिल गया!\n👤 नाम: {data['name']}"
|
| 67 |
+
await update.message.reply_document(document=open(file_path, 'rb'), caption=caption)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 68 |
os.remove(file_path)
|
| 69 |
+
await status.delete()
|
| 70 |
+
else:
|
| 71 |
+
await status.edit_text("❌ एडमिट कार्ड नहीं मिला।")
|
|
|
|
|
|
|
| 72 |
|
| 73 |
+
# --- Main Bot Function with Power-Reset ---
|
| 74 |
async def main_bot():
|
| 75 |
+
print("⏳ DNS स्टेबल होने का इंतज़ार (10s)...")
|
| 76 |
+
await asyncio.sleep(10)
|
| 77 |
+
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 78 |
while True:
|
| 79 |
+
bot_app = None
|
| 80 |
try:
|
| 81 |
+
print("🚀 टेलीग्राम से नया कनेक्शन बना रहा हूँ...")
|
| 82 |
+
bot_app = ApplicationBuilder().token(BOT_TOKEN).build()
|
| 83 |
+
bot_app.add_handler(CommandHandler("start", lambda u,c: u.message.reply_text("नमस्ते! Form No भेजें।")))
|
| 84 |
+
bot_app.add_handler(MessageHandler(filters.TEXT & (~filters.COMMAND), handle_message))
|
| 85 |
+
|
| 86 |
async with bot_app:
|
| 87 |
await bot_app.initialize()
|
| 88 |
await bot_app.start()
|
| 89 |
await bot_app.updater.start_polling()
|
| 90 |
+
print("✅ बॉट अब टेलीग्राम से जुड़ चुका है!")
|
| 91 |
+
while bot_app.updater.running:
|
| 92 |
+
await asyncio.sleep(10)
|
| 93 |
except Exception as e:
|
| 94 |
+
print(f"❌ कनेक्शन एरर: {e}")
|
| 95 |
+
if bot_app:
|
| 96 |
+
try: await bot_app.stop()
|
| 97 |
+
except: pass
|
| 98 |
+
print("🔄 15 सेकंड में रीस्टार्ट करेंगे...")
|
| 99 |
+
await asyncio.sleep(15)
|
| 100 |
|
| 101 |
if __name__ == "__main__":
|
|
|
|
| 102 |
threading.Thread(target=run_fastapi, daemon=True).start()
|
|
|
|
|
|
|
| 103 |
try:
|
| 104 |
asyncio.run(main_bot())
|
| 105 |
+
except KeyboardInterrupt:
|
| 106 |
+
pass
|
|
|