shravanijadhav264 commited on
Commit
5d03192
·
1 Parent(s): b039770

fix session and download report

Browse files
Files changed (3) hide show
  1. app.py +191 -84
  2. templates/index.html +1 -1
  3. templates/result.html +16 -11
app.py CHANGED
@@ -1,4 +1,4 @@
1
- from flask import Flask, render_template, request, redirect, url_for, send_file, session
2
  import os
3
 
4
  from resume_parser import extract_resume_text
@@ -10,7 +10,6 @@ from skill_extractor import extract_skills
10
  from warning_engine import detect_warnings
11
 
12
  app = Flask(__name__)
13
- app.secret_key = "secret_key_change_this"
14
  app.config["UPLOAD_FOLDER"] = "uploads"
15
 
16
 
@@ -21,9 +20,8 @@ def index():
21
 
22
 
23
  # ---------------- PROCESS RESUME ----------------
24
- @app.route('/process', methods=['POST'])
25
  def process():
26
-
27
  resume_text = request.form.get("resume_text", "").strip()
28
  uploaded_file = request.files.get("resume_file")
29
 
@@ -40,22 +38,15 @@ def process():
40
  else:
41
  return redirect(url_for("index"))
42
 
43
- # store in session (IMPORTANT FIX)
44
- session["resume"] = final_resume
45
-
46
  return render_template("upload_jd.html", resume=final_resume)
47
 
48
 
49
  # ---------------- ANALYZE ----------------
50
- @app.route('/analyze', methods=['POST'])
51
  def analyze():
52
-
53
  resume = request.form.get("resume", "").strip()
54
  jd = request.form.get("jd_text", "").strip()
55
 
56
- print("RESUME LENGTH:", len(resume))
57
- print("JD LENGTH:", len(jd))
58
-
59
  if not resume or not jd:
60
  return "Missing resume or job description", 400
61
 
@@ -69,34 +60,26 @@ def analyze():
69
 
70
  feedback = generate_feedback(resume, skill_data)
71
 
72
- # store for PDF
73
- session["match_score"] = match_score
74
- session["resume"] = resume
75
- session["jd"] = jd
76
- session["skill_data"] = skill_data
77
- session["feedback"] = feedback
78
-
79
  return render_template(
80
  "result.html",
81
  match_score=match_score,
82
  jobs=jobs,
83
  skills=skills,
84
- resume=resume[:300],
85
- jd=jd[:300],
86
  skill_data=skill_data,
87
  feedback=feedback
88
  )
89
 
90
 
91
  # ---------------- SCAM CHECKER ----------------
92
- @app.route('/scam-checker')
93
  def scam_checker():
94
  return render_template("scam_checker.html")
95
 
96
 
97
- @app.route('/analyze-scam', methods=['POST'])
98
  def analyze_scam():
99
-
100
  email = request.form.get("email", "")
101
  title = request.form.get("title", "")
102
  description = request.form.get("description", "")
@@ -104,94 +87,218 @@ def analyze_scam():
104
  score, label = predict_scam(email, title, description)
105
  warnings = detect_warnings(email, title, description)
106
 
107
- if label == "Scam":
108
- precautions = [
109
- "Do not pay money",
110
- "Do not share bank details",
111
- "Verify company website",
112
- "Check LinkedIn presence",
113
- "Be careful of urgency traps"
114
- ]
115
- elif label == "Medium Risk":
116
- precautions = [
117
- "Verify recruiter email",
118
- "Check reviews",
119
- "Avoid suspicious links"
120
- ]
121
- else:
122
- precautions = ["Still verify company authenticity"]
123
-
124
  return render_template(
125
  "scam_result.html",
126
  result=label,
127
  score=score,
128
- precautions=precautions,
129
  warnings=warnings
130
  )
131
 
132
 
133
- # ---------------- DOWNLOAD PDF REPORT ----------------
134
- @app.route('/download-report')
135
- def download_report():
 
136
 
137
- from reportlab.platypus import SimpleDocTemplate, Paragraph, Spacer
138
- from reportlab.lib.styles import getSampleStyleSheet
139
 
140
- pdf_path = os.path.join("/tmp", "report.pdf")
141
 
142
- doc = SimpleDocTemplate(pdf_path)
143
- styles = getSampleStyleSheet()
144
- elements = []
145
 
146
- match_score = session.get("match_score", 0)
147
- resume = session.get("resume", "")
148
- jd = session.get("jd", "")
149
 
150
- skill_data = session.get("skill_data", {"matched": [], "missing": []})
151
- feedback = session.get("feedback", [])
152
 
153
- elements.append(Paragraph("JobShield AI Report", styles['Title']))
154
- elements.append(Spacer(1, 20))
155
 
156
- elements.append(Paragraph(f"<b>Match Score:</b> {match_score}%", styles['BodyText']))
157
- elements.append(Spacer(1, 10))
 
 
 
 
 
158
 
159
- elements.append(Paragraph("<b>Matched Skills:</b>", styles['Heading2']))
160
- for skill in skill_data.get("matched", []):
161
- elements.append(Paragraph(f"• {skill}", styles['BodyText']))
162
 
163
- elements.append(Spacer(1, 10))
164
 
165
- elements.append(Paragraph("<b>Missing Skills:</b>", styles['Heading2']))
166
- for skill in skill_data.get("missing", []):
167
- elements.append(Paragraph(f"• {skill}", styles['BodyText']))
 
168
 
169
- elements.append(Spacer(1, 10))
170
 
171
- elements.append(Paragraph("<b>Resume Feedback:</b>", styles['Heading2']))
172
- for f in feedback:
173
- elements.append(Paragraph(f"• {f}", styles['BodyText']))
174
 
175
- elements.append(Spacer(1, 10))
 
176
 
177
- elements.append(Paragraph("<b>Resume Preview:</b>", styles['Heading2']))
178
- elements.append(Paragraph(resume[:1000], styles['BodyText']))
179
 
180
- elements.append(Spacer(1, 10))
 
 
 
181
 
182
- elements.append(Paragraph("<b>Job Description Preview:</b>", styles['Heading2']))
183
- elements.append(Paragraph(jd[:1000], styles['BodyText']))
184
 
185
- doc.build(elements)
 
186
 
187
- return send_file(pdf_path, as_attachment=True)
 
188
 
 
189
 
190
- # ---------------- RUN ----------------
191
- if __name__ == "__main__":
192
- os.makedirs(app.config['UPLOAD_FOLDER'], exist_ok=True)
193
- print("Starting JobShield AI...")
194
- app.run(host="0.0.0.0", port=7860)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
195
 
196
 
197
 
 
1
+ from flask import Flask, render_template, request, redirect, url_for, send_file
2
  import os
3
 
4
  from resume_parser import extract_resume_text
 
10
  from warning_engine import detect_warnings
11
 
12
  app = Flask(__name__)
 
13
  app.config["UPLOAD_FOLDER"] = "uploads"
14
 
15
 
 
20
 
21
 
22
  # ---------------- PROCESS RESUME ----------------
23
+ @app.route("/process", methods=["POST"])
24
  def process():
 
25
  resume_text = request.form.get("resume_text", "").strip()
26
  uploaded_file = request.files.get("resume_file")
27
 
 
38
  else:
39
  return redirect(url_for("index"))
40
 
 
 
 
41
  return render_template("upload_jd.html", resume=final_resume)
42
 
43
 
44
  # ---------------- ANALYZE ----------------
45
+ @app.route("/analyze", methods=["POST"])
46
  def analyze():
 
47
  resume = request.form.get("resume", "").strip()
48
  jd = request.form.get("jd_text", "").strip()
49
 
 
 
 
50
  if not resume or not jd:
51
  return "Missing resume or job description", 400
52
 
 
60
 
61
  feedback = generate_feedback(resume, skill_data)
62
 
 
 
 
 
 
 
 
63
  return render_template(
64
  "result.html",
65
  match_score=match_score,
66
  jobs=jobs,
67
  skills=skills,
68
+ resume=resume,
69
+ jd=jd,
70
  skill_data=skill_data,
71
  feedback=feedback
72
  )
73
 
74
 
75
  # ---------------- SCAM CHECKER ----------------
76
+ @app.route("/scam-checker")
77
  def scam_checker():
78
  return render_template("scam_checker.html")
79
 
80
 
81
+ @app.route("/analyze-scam", methods=["POST"])
82
  def analyze_scam():
 
83
  email = request.form.get("email", "")
84
  title = request.form.get("title", "")
85
  description = request.form.get("description", "")
 
87
  score, label = predict_scam(email, title, description)
88
  warnings = detect_warnings(email, title, description)
89
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
90
  return render_template(
91
  "scam_result.html",
92
  result=label,
93
  score=score,
 
94
  warnings=warnings
95
  )
96
 
97
 
98
+ # ---------------- RUN ----------------
99
+ if __name__ == "__main__":
100
+ os.makedirs(app.config["UPLOAD_FOLDER"], exist_ok=True)
101
+ app.run(host="0.0.0.0", port=7860)
102
 
 
 
103
 
 
104
 
 
 
 
105
 
 
 
 
106
 
 
 
107
 
108
+ # from flask import Flask, render_template, request, redirect, url_for, send_file, session
109
+ # import os
110
 
111
+ # from resume_parser import extract_resume_text
112
+ # from matching_engine import calculate_similarity, get_top_job_matches
113
+ # from scam_model import predict_scam
114
+ # from skill_analyzer import analyze_skill_gap
115
+ # from feedback_engine import generate_feedback
116
+ # from skill_extractor import extract_skills
117
+ # from warning_engine import detect_warnings
118
 
119
+ # app = Flask(__name__)
120
+ # app.secret_key = "secret_key_change_this"
121
+ # app.config["UPLOAD_FOLDER"] = "uploads"
122
 
 
123
 
124
+ # # ---------------- HOME ----------------
125
+ # @app.route("/")
126
+ # def index():
127
+ # return render_template("index.html")
128
 
 
129
 
130
+ # # ---------------- PROCESS RESUME ----------------
131
+ # @app.route('/process', methods=['POST'])
132
+ # def process():
133
 
134
+ # resume_text = request.form.get("resume_text", "").strip()
135
+ # uploaded_file = request.files.get("resume_file")
136
 
137
+ # final_resume = ""
 
138
 
139
+ # if uploaded_file and uploaded_file.filename != "":
140
+ # filepath = os.path.join(app.config["UPLOAD_FOLDER"], uploaded_file.filename)
141
+ # uploaded_file.save(filepath)
142
+ # final_resume = extract_resume_text(filepath)
143
 
144
+ # elif resume_text:
145
+ # final_resume = resume_text
146
 
147
+ # else:
148
+ # return redirect(url_for("index"))
149
 
150
+ # # store in session (IMPORTANT FIX)
151
+ # session["resume"] = final_resume
152
 
153
+ # return render_template("upload_jd.html", resume=final_resume)
154
 
155
+
156
+ # # ---------------- ANALYZE ----------------
157
+ # @app.route('/analyze', methods=['POST'])
158
+ # def analyze():
159
+
160
+ # resume = request.form.get("resume", "").strip()
161
+ # jd = request.form.get("jd_text", "").strip()
162
+
163
+ # print("RESUME LENGTH:", len(resume))
164
+ # print("JD LENGTH:", len(jd))
165
+
166
+ # if not resume or not jd:
167
+ # return "Missing resume or job description", 400
168
+
169
+ # match_score = calculate_similarity(resume, jd)
170
+ # jobs = get_top_job_matches(resume)
171
+ # skills = extract_skills(resume)
172
+
173
+ # skill_data = analyze_skill_gap(resume, jd)
174
+ # if not isinstance(skill_data, dict):
175
+ # skill_data = {"matched": [], "missing": [], "match_ratio": 0}
176
+
177
+ # feedback = generate_feedback(resume, skill_data)
178
+
179
+ # # store for PDF
180
+ # session["match_score"] = match_score
181
+ # session["resume"] = resume
182
+ # session["jd"] = jd
183
+ # session["skill_data"] = skill_data
184
+ # session["feedback"] = feedback
185
+
186
+ # return render_template(
187
+ # "result.html",
188
+ # match_score=match_score,
189
+ # jobs=jobs,
190
+ # skills=skills,
191
+ # resume=resume[:300],
192
+ # jd=jd[:300],
193
+ # skill_data=skill_data,
194
+ # feedback=feedback
195
+ # )
196
+
197
+
198
+ # # ---------------- SCAM CHECKER ----------------
199
+ # @app.route('/scam-checker')
200
+ # def scam_checker():
201
+ # return render_template("scam_checker.html")
202
+
203
+
204
+ # @app.route('/analyze-scam', methods=['POST'])
205
+ # def analyze_scam():
206
+
207
+ # email = request.form.get("email", "")
208
+ # title = request.form.get("title", "")
209
+ # description = request.form.get("description", "")
210
+
211
+ # score, label = predict_scam(email, title, description)
212
+ # warnings = detect_warnings(email, title, description)
213
+
214
+ # if label == "Scam":
215
+ # precautions = [
216
+ # "Do not pay money",
217
+ # "Do not share bank details",
218
+ # "Verify company website",
219
+ # "Check LinkedIn presence",
220
+ # "Be careful of urgency traps"
221
+ # ]
222
+ # elif label == "Medium Risk":
223
+ # precautions = [
224
+ # "Verify recruiter email",
225
+ # "Check reviews",
226
+ # "Avoid suspicious links"
227
+ # ]
228
+ # else:
229
+ # precautions = ["Still verify company authenticity"]
230
+
231
+ # return render_template(
232
+ # "scam_result.html",
233
+ # result=label,
234
+ # score=score,
235
+ # precautions=precautions,
236
+ # warnings=warnings
237
+ # )
238
+
239
+
240
+ # # ---------------- DOWNLOAD PDF REPORT ----------------
241
+ # @app.route('/download-report')
242
+ # def download_report():
243
+
244
+ # from reportlab.platypus import SimpleDocTemplate, Paragraph, Spacer
245
+ # from reportlab.lib.styles import getSampleStyleSheet
246
+
247
+ # pdf_path = os.path.join("/tmp", "report.pdf")
248
+
249
+ # doc = SimpleDocTemplate(pdf_path)
250
+ # styles = getSampleStyleSheet()
251
+ # elements = []
252
+
253
+ # match_score = session.get("match_score", 0)
254
+ # resume = session.get("resume", "")
255
+ # jd = session.get("jd", "")
256
+
257
+ # skill_data = session.get("skill_data", {"matched": [], "missing": []})
258
+ # feedback = session.get("feedback", [])
259
+
260
+ # elements.append(Paragraph("JobShield AI Report", styles['Title']))
261
+ # elements.append(Spacer(1, 20))
262
+
263
+ # elements.append(Paragraph(f"<b>Match Score:</b> {match_score}%", styles['BodyText']))
264
+ # elements.append(Spacer(1, 10))
265
+
266
+ # elements.append(Paragraph("<b>Matched Skills:</b>", styles['Heading2']))
267
+ # for skill in skill_data.get("matched", []):
268
+ # elements.append(Paragraph(f"• {skill}", styles['BodyText']))
269
+
270
+ # elements.append(Spacer(1, 10))
271
+
272
+ # elements.append(Paragraph("<b>Missing Skills:</b>", styles['Heading2']))
273
+ # for skill in skill_data.get("missing", []):
274
+ # elements.append(Paragraph(f"• {skill}", styles['BodyText']))
275
+
276
+ # elements.append(Spacer(1, 10))
277
+
278
+ # elements.append(Paragraph("<b>Resume Feedback:</b>", styles['Heading2']))
279
+ # for f in feedback:
280
+ # elements.append(Paragraph(f"• {f}", styles['BodyText']))
281
+
282
+ # elements.append(Spacer(1, 10))
283
+
284
+ # elements.append(Paragraph("<b>Resume Preview:</b>", styles['Heading2']))
285
+ # elements.append(Paragraph(resume[:1000], styles['BodyText']))
286
+
287
+ # elements.append(Spacer(1, 10))
288
+
289
+ # elements.append(Paragraph("<b>Job Description Preview:</b>", styles['Heading2']))
290
+ # elements.append(Paragraph(jd[:1000], styles['BodyText']))
291
+
292
+ # doc.build(elements)
293
+
294
+ # return send_file(pdf_path, as_attachment=True)
295
+
296
+
297
+ # # ---------------- RUN ----------------
298
+ # if __name__ == "__main__":
299
+ # os.makedirs(app.config['UPLOAD_FOLDER'], exist_ok=True)
300
+ # print("Starting JobShield AI...")
301
+ # app.run(host="0.0.0.0", port=7860)
302
 
303
 
304
 
templates/index.html CHANGED
@@ -141,7 +141,7 @@
141
 
142
 
143
  <footer>
144
- <p>JobShield AI © 2026 | Developed by Shravani Jadhav</p>
145
  </footer>
146
  </div>
147
  <div id="fakeJobResult" style="margin-top:20px; font-size:18px; font-weight:bold;"></div>
 
141
 
142
 
143
  <footer>
144
+ <p>JobShield AI © 2026</p>
145
  </footer>
146
  </div>
147
  <div id="fakeJobResult" style="margin-top:20px; font-size:18px; font-weight:bold;"></div>
templates/result.html CHANGED
@@ -74,15 +74,13 @@
74
  <!-- MESSAGE -->
75
  <div class="result-message">
76
 
77
- {% if match_score < 40 %}
78
- <h3 style="color:red;">
79
- <i class="fa-solid fa-award"></i>
80
- Poor Match
81
  </h3>
82
- {% elif match_score < 70 %}
83
- <h3 style="color:orange;">
84
- <i class="fa-solid fa-award"></i>
85
- Medium Match
86
  </h3>
87
  {% else %}
88
  <h3 style="color:#00bf63;">
@@ -185,14 +183,21 @@
185
 
186
  </div>
187
 
 
 
 
 
 
188
 
189
-
 
 
190
  <!-- BUTTONS -->
191
- <div class="actions">
192
  <button onclick="window.location.href='/download-report'">Download Report</button>
193
  <button onclick="window.location.href='/'">Analyze Again</button>
194
  <button onclick="window.location.href='/scam-checker'">Scam Check</button>
195
- </div>
196
 
197
  </main>
198
 
 
74
  <!-- MESSAGE -->
75
  <div class="result-message">
76
 
77
+ {% if match_score < 40 %} <h3 style="color:red;">
78
+ <i class="fa-solid fa-award"></i>
79
+ Poor Match
 
80
  </h3>
81
+ {% elif match_score < 70 %} <h3 style="color:orange;">
82
+ <i class="fa-solid fa-award"></i>
83
+ Medium Match
 
84
  </h3>
85
  {% else %}
86
  <h3 style="color:#00bf63;">
 
183
 
184
  </div>
185
 
186
+ <div class="actions">
187
+ <form action="/download-report" method="POST">
188
+ <input type="hidden" name="resume" value="{{ resume }}">
189
+ <input type="hidden" name="jd_text" value="{{ jd }}">
190
+ <input type="hidden" name="match_score" value="{{ match_score }}">
191
 
192
+ <button type="submit">Download Report</button>
193
+ </form>
194
+ </div>
195
  <!-- BUTTONS -->
196
+ <!-- <div class="actions">
197
  <button onclick="window.location.href='/download-report'">Download Report</button>
198
  <button onclick="window.location.href='/'">Analyze Again</button>
199
  <button onclick="window.location.href='/scam-checker'">Scam Check</button>
200
+ </div> -->
201
 
202
  </main>
203