Pubgbc9799 commited on
Commit
e180ad7
·
verified ·
1 Parent(s): bc7a5c0

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +42 -40
app.py CHANGED
@@ -5,42 +5,45 @@ import fitz # PyMuPDF
5
  from flask import Flask, request, render_template_string, send_file
6
  from playwright.async_api import async_playwright
7
 
8
- # --- Flask App Setup ---
9
  app = Flask(__name__)
10
 
11
- # --- UI (HTML/CSS) ---
12
  HTML_PAGE = """
13
  <!DOCTYPE html>
14
  <html>
15
  <head>
16
  <title>JNVU Admit Card Downloader</title>
 
17
  <style>
18
- body { font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; background-color: #f4f7f6; display: flex; justify-content: center; align-items: center; height: 100vh; margin: 0; }
19
- .container { background: white; padding: 2rem; border-radius: 10px; box-shadow: 0 4px 6px rgba(0,0,0,0.1); width: 400px; text-align: center; }
20
- h2 { color: #2c3e50; }
21
- input { width: 80%; padding: 10px; margin: 10px 0; border: 1px solid #ddd; border-radius: 5px; font-size: 16px; }
22
- button { background-color: #3498db; color: white; border: none; padding: 10px 20px; border-radius: 5px; cursor: pointer; font-size: 16px; width: 85%; }
23
- button:hover { background-color: #2980b9; }
24
- .result { margin-top: 20px; text-align: left; font-size: 14px; background: #eef2f3; padding: 10px; border-radius: 5px; }
25
- .error { color: #e74c3c; margin-top: 10px; }
 
 
 
26
  </style>
27
  </head>
28
  <body>
29
- <div class="container">
30
- <h2>JNVU Admit Card</h2>
31
  <form method="POST">
32
- <input type="text" name="form_number" placeholder="Enter Form Number" required>
33
- <button type="submit">Download PDF</button>
34
  </form>
35
- {% if error %}<p class="error">{{ error }}</p>{% endif %}
 
 
36
  {% if data %}
37
- <div class="result">
38
- <strong>Student Info Found:</strong><br>
39
- 👤 Name: {{ data.name }}<br>
40
- 🔢 Roll No: {{ data.roll }}<br>
41
- 🏫 Center: {{ data.center }}
42
- <hr>
43
- <a href="/download/{{ filename }}" style="color: #27ae60; font-weight: bold;">📥 Click here to Save PDF</a>
44
  </div>
45
  {% endif %}
46
  </div>
@@ -55,33 +58,31 @@ def extract_student_info(pdf_path):
55
  doc = fitz.open(pdf_path)
56
  text = "".join([page.get_text() for page in doc])
57
 
58
- name_match = re.search(r"NAME OF CANDIDATE\s*:\s*(.*)", text)
59
- roll_match = re.search(r"Roll no is\s+([\w\d]+)", text)
60
- center_pattern = r"Exam Centre is\s*(.*?)(?=Print Date|To,|The Centre|NAME OF EXAMINATION)"
61
- center_match = re.search(center_pattern, text, re.DOTALL)
62
 
63
- if name_match: info["name"] = name_match.group(1).split('\n')[0].strip()
64
- if roll_match: info["roll"] = roll_match.group(1).strip()
65
- if center_match: info["center"] = " ".join(center_match.group(1).split())
66
-
67
  doc.close()
68
- except Exception as e:
69
- print(f"Extraction Error: {e}")
70
  return info
71
 
72
- # --- Playwright Downloader ---
73
  async def download_jnvu_pdf(form_number):
74
  pdf_path = f"admit_card_{form_number}.pdf"
75
  async with async_playwright() as p:
76
- browser = await p.chromium.launch(headless=True, args=["--no-sandbox"])
 
77
  context = await browser.new_context(accept_downloads=True)
78
  page = await context.new_page()
79
  try:
80
  url = "https://erp.jnvuiums.in/(S(biolzjtwlrcfmzwwzgs5uj5n))/Exam/Pre_Exam/Exam_ForALL_AdmitCard.aspx#"
81
- await page.goto(url, wait_until="networkidle", timeout=30000)
82
  await page.fill("#txtchallanNo", str(form_number))
83
 
84
- async with page.expect_download(timeout=15000) as download_info:
85
  await page.click("#btnGetResult")
86
 
87
  download = await download_info.value
@@ -99,25 +100,26 @@ def index():
99
  if request.method == 'POST':
100
  form_number = request.form.get('form_number')
101
  if not form_number.isdigit():
102
- return render_template_string(HTML_PAGE, error="Invalid Form Number!")
103
 
104
- # Run async download in sync Flask
105
  file_path = asyncio.run(download_jnvu_pdf(form_number))
106
 
107
  if file_path and os.path.exists(file_path):
108
  data = extract_student_info(file_path)
109
  return render_template_string(HTML_PAGE, data=data, filename=file_path)
110
  else:
111
- return render_template_string(HTML_PAGE, error="Could not find Admit Card.")
112
 
113
  return render_template_string(HTML_PAGE)
114
 
115
  @app.route('/download/<filename>')
116
  def download_file(filename):
 
117
  if os.path.exists(filename):
118
  return send_file(filename, as_attachment=True)
119
- return "File Not Found", 404
120
 
121
  if __name__ == "__main__":
 
122
  port = int(os.environ.get("PORT", 7860))
123
  app.run(host='0.0.0.0', port=port)
 
5
  from flask import Flask, request, render_template_string, send_file
6
  from playwright.async_api import async_playwright
7
 
 
8
  app = Flask(__name__)
9
 
10
+ # --- UI Design ---
11
  HTML_PAGE = """
12
  <!DOCTYPE html>
13
  <html>
14
  <head>
15
  <title>JNVU Admit Card Downloader</title>
16
+ <meta name="viewport" content="width=device-width, initial-scale=1">
17
  <style>
18
+ body { font-family: 'Segoe UI', Arial, sans-serif; background: #f0f2f5; display: flex; justify-content: center; padding-top: 50px; }
19
+ .card { background: white; padding: 30px; border-radius: 15px; box-shadow: 0 10px 25px rgba(0,0,0,0.1); width: 100%; max-width: 450px; text-align: center; }
20
+ h2 { color: #1a73e8; margin-bottom: 20px; }
21
+ input { width: 90%; padding: 12px; margin: 10px 0; border: 2px solid #dfe1e5; border-radius: 8px; font-size: 16px; outline: none; }
22
+ input:focus { border-color: #1a73e8; }
23
+ .btn-fetch { background: #1a73e8; color: white; border: none; padding: 12px 25px; border-radius: 8px; cursor: pointer; font-size: 16px; width: 95%; font-weight: bold; }
24
+ .btn-fetch:hover { background: #1557b0; }
25
+ .result-box { margin-top: 25px; padding: 20px; background: #f8f9fa; border-radius: 10px; text-align: left; border-left: 5px solid #34a853; }
26
+ .btn-download { display: block; text-align: center; background: #34a853; color: white; padding: 12px; text-decoration: none; border-radius: 8px; margin-top: 15px; font-weight: bold; }
27
+ .error { color: #d93025; background: #fce8e6; padding: 10px; border-radius: 5px; margin-top: 10px; }
28
+ .loading { color: #5f6368; font-style: italic; margin-top: 10px; }
29
  </style>
30
  </head>
31
  <body>
32
+ <div class="card">
33
+ <h2>JNVU Admit Card Finder</h2>
34
  <form method="POST">
35
+ <input type="text" name="form_number" placeholder="Enter Form Number (e.g. 128xxx)" required>
36
+ <button type="submit" class="btn-fetch">Fetch Admit Card</button>
37
  </form>
38
+
39
+ {% if error %}<div class="error">{{ error }}</div>{% endif %}
40
+
41
  {% if data %}
42
+ <div class="result-box">
43
+ <p><strong>👤 Name:</strong> {{ data.name }}</p>
44
+ <p><strong>🔢 Roll No:</strong> {{ data.roll }}</p>
45
+ <p><strong>🏫 Center:</strong> {{ data.center }}</p>
46
+ <a href="/download/{{ filename }}" class="btn-download">📥 Download PDF Now</a>
 
 
47
  </div>
48
  {% endif %}
49
  </div>
 
58
  doc = fitz.open(pdf_path)
59
  text = "".join([page.get_text() for page in doc])
60
 
61
+ name_m = re.search(r"NAME OF CANDIDATE\s*:\s*(.*)", text)
62
+ roll_m = re.search(r"Roll no is\s+([\w\d]+)", text)
63
+ cent_m = re.search(r"Exam Centre is\s*(.*?)(?=Print Date|To,|The Centre|NAME OF EXAMINATION)", text, re.DOTALL)
 
64
 
65
+ if name_m: info["name"] = name_m.group(1).split('\n')[0].strip()
66
+ if roll_m: info["roll"] = roll_m.group(1).strip()
67
+ if cent_m: info["center"] = " ".join(cent_m.group(1).split())
 
68
  doc.close()
69
+ except Exception as e: print(f"Error: {e}")
 
70
  return info
71
 
72
+ # --- Playwright Logic ---
73
  async def download_jnvu_pdf(form_number):
74
  pdf_path = f"admit_card_{form_number}.pdf"
75
  async with async_playwright() as p:
76
+ # Docker के लिए No-Sandbox बहुत जरूरी है
77
+ browser = await p.chromium.launch(headless=True, args=["--no-sandbox", "--disable-dev-shm-usage"])
78
  context = await browser.new_context(accept_downloads=True)
79
  page = await context.new_page()
80
  try:
81
  url = "https://erp.jnvuiums.in/(S(biolzjtwlrcfmzwwzgs5uj5n))/Exam/Pre_Exam/Exam_ForALL_AdmitCard.aspx#"
82
+ await page.goto(url, wait_until="load", timeout=40000)
83
  await page.fill("#txtchallanNo", str(form_number))
84
 
85
+ async with page.expect_download(timeout=20000) as download_info:
86
  await page.click("#btnGetResult")
87
 
88
  download = await download_info.value
 
100
  if request.method == 'POST':
101
  form_number = request.form.get('form_number')
102
  if not form_number.isdigit():
103
+ return render_template_string(HTML_PAGE, error="कृपया सही फॉर्म नंबर डालें।")
104
 
 
105
  file_path = asyncio.run(download_jnvu_pdf(form_number))
106
 
107
  if file_path and os.path.exists(file_path):
108
  data = extract_student_info(file_path)
109
  return render_template_string(HTML_PAGE, data=data, filename=file_path)
110
  else:
111
+ return render_template_string(HTML_PAGE, error="एडमिट कार्ड नहीं मिला या JNVU सर्वर धीमा है।")
112
 
113
  return render_template_string(HTML_PAGE)
114
 
115
  @app.route('/download/<filename>')
116
  def download_file(filename):
117
+ # सुरक्षा के लिए चेक करें कि फाइल मौजूद है
118
  if os.path.exists(filename):
119
  return send_file(filename, as_attachment=True)
120
+ return "File missing", 404
121
 
122
  if __name__ == "__main__":
123
+ # Hugging Face PORT 7860 मांगता है
124
  port = int(os.environ.get("PORT", 7860))
125
  app.run(host='0.0.0.0', port=port)