Spaces:
Sleeping
Sleeping
earlsab commited on
Commit ·
93c96d9
1
Parent(s): 81c4308
add more columns
Browse files
app.py
CHANGED
|
@@ -243,6 +243,65 @@ def create_html_output(job_result: Dict, resume_results: List[Dict]) -> str:
|
|
| 243 |
# Check if we have multiple resumes to display summary table
|
| 244 |
multiple_resumes = len(resume_results) > 1
|
| 245 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 246 |
# Create summary table if multiple resumes
|
| 247 |
if multiple_resumes:
|
| 248 |
html += "<h3>Match Summary</h3>"
|
|
@@ -250,6 +309,10 @@ def create_html_output(job_result: Dict, resume_results: List[Dict]) -> str:
|
|
| 250 |
html += "<tr style='background-color: #eee;'><th style='padding: 8px; text-align: left; border: 1px solid #ddd;'>Resume</th>"
|
| 251 |
html += "<th style='padding: 8px; text-align: center; border: 1px solid #ddd;'>Skills Matched</th>"
|
| 252 |
html += "<th style='padding: 8px; text-align: center; border: 1px solid #ddd;'>Match Percentage</th>"
|
|
|
|
|
|
|
|
|
|
|
|
|
| 253 |
html += "<th style='padding: 8px; text-align: center; border: 1px solid #ddd;'>Actions</th></tr>"
|
| 254 |
|
| 255 |
for i, resume_result in enumerate(resume_results, 1):
|
|
@@ -259,12 +322,35 @@ def create_html_output(job_result: Dict, resume_results: List[Dict]) -> str:
|
|
| 259 |
match_count = len(matched_skills)
|
| 260 |
match_percentage = round((match_count / job_result['total_skills'] * 100) if job_result['total_skills'] > 0 else 0, 1)
|
| 261 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 262 |
# Add row to summary table
|
| 263 |
html += f"<tr><td style='padding: 8px; border: 1px solid #ddd;'>Resume {i}</td>"
|
| 264 |
html += f"<td style='padding: 8px; text-align: center; border: 1px solid #ddd;'>{match_count}/{job_result['total_skills']}</td>"
|
| 265 |
html += f"<td style='padding: 8px; text-align: center; border: 1px solid #ddd;'>{match_percentage}%</td>"
|
|
|
|
|
|
|
|
|
|
|
|
|
| 266 |
html += f"<td style='padding: 8px; text-align: center; border: 1px solid #ddd;'>"
|
| 267 |
-
html += f"<button onclick=\"document.getElementById('resume-detail-{i}').style.display = document.getElementById('resume-detail-{i}').style.display === 'none' ? 'block' : 'none';\">Toggle Details</button>"
|
| 268 |
html += "</td></tr>"
|
| 269 |
|
| 270 |
html += "</table>"
|
|
@@ -282,6 +368,29 @@ def create_html_output(job_result: Dict, resume_results: List[Dict]) -> str:
|
|
| 282 |
match_percentage = round((match_count / job_result['total_skills'] * 100) if job_result['total_skills'] > 0 else 0, 1)
|
| 283 |
|
| 284 |
html += f"<p><strong>Skills Matched:</strong> {match_count}/{job_result['total_skills']} ({match_percentage}%)</p>"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 285 |
|
| 286 |
# Detailed resume section with visibility control
|
| 287 |
html += f"<div id='resume-detail-{i}' style='margin-bottom: 20px; padding: 10px; border: 1px solid #ddd; border-radius: 5px; display: {display_style};'>"
|
|
@@ -290,12 +399,20 @@ def create_html_output(job_result: Dict, resume_results: List[Dict]) -> str:
|
|
| 290 |
# Display all skills found in the resume
|
| 291 |
html += "<p><strong>Skills Found:</strong></p>"
|
| 292 |
html += "<div style='background-color: #f0f0f0; padding: 10px; border-radius: 5px;'>"
|
|
|
|
|
|
|
|
|
|
|
|
|
| 293 |
for skill in resume_result['skills']:
|
| 294 |
# Highlight matched skills
|
| 295 |
is_match = skill['text'].lower() in job_skills
|
| 296 |
bg_color = "#c8e6c9" if is_match else "#e0e0e0" # Green tint for matches
|
| 297 |
|
| 298 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 299 |
html += "</div>"
|
| 300 |
|
| 301 |
# Job roles section
|
|
|
|
| 243 |
# Check if we have multiple resumes to display summary table
|
| 244 |
multiple_resumes = len(resume_results) > 1
|
| 245 |
|
| 246 |
+
# Calculate leadership and collaboration counts, and total experience for each resume
|
| 247 |
+
leadership_counts = []
|
| 248 |
+
collaboration_counts = []
|
| 249 |
+
total_experiences = []
|
| 250 |
+
skill_experience_maps = []
|
| 251 |
+
|
| 252 |
+
for resume_result in resume_results:
|
| 253 |
+
# Count leadership and collaboration sentences
|
| 254 |
+
leadership_count = 0
|
| 255 |
+
collaboration_count = 0
|
| 256 |
+
|
| 257 |
+
# Calculate total experience
|
| 258 |
+
total_experience = 0
|
| 259 |
+
skill_experience = {}
|
| 260 |
+
|
| 261 |
+
if 'roles' in resume_result:
|
| 262 |
+
for role in resume_result['roles']:
|
| 263 |
+
# Count quality scores
|
| 264 |
+
if 'quality_scores' in role:
|
| 265 |
+
for score in role['quality_scores']:
|
| 266 |
+
if score['is_leadership']:
|
| 267 |
+
leadership_count += 1
|
| 268 |
+
elif score['is_collaboration']:
|
| 269 |
+
collaboration_count += 1
|
| 270 |
+
|
| 271 |
+
# Calculate experience duration
|
| 272 |
+
if 'dates' in role and role['dates']:
|
| 273 |
+
start_date = role['dates'].get('date_started', '')
|
| 274 |
+
end_date = role['dates'].get('date_ended', '')
|
| 275 |
+
|
| 276 |
+
try:
|
| 277 |
+
# Try to extract years from dates
|
| 278 |
+
start_year = int(''.join(filter(str.isdigit, start_date[-4:]))) if start_date else 0
|
| 279 |
+
end_year = int(''.join(filter(str.isdigit, end_date[-4:]))) if end_date and end_date.lower() != 'present' else time.localtime().tm_year
|
| 280 |
+
|
| 281 |
+
years_in_role = max(0, end_year - start_year)
|
| 282 |
+
total_experience += years_in_role
|
| 283 |
+
|
| 284 |
+
# Calculate experience per skill
|
| 285 |
+
for skill in role.get('skills', []):
|
| 286 |
+
skill_name = skill.get('name', '').lower()
|
| 287 |
+
if skill_name:
|
| 288 |
+
if skill_name in skill_experience:
|
| 289 |
+
skill_experience[skill_name] += years_in_role
|
| 290 |
+
else:
|
| 291 |
+
skill_experience[skill_name] = years_in_role
|
| 292 |
+
except:
|
| 293 |
+
# Skip if date parsing fails
|
| 294 |
+
pass
|
| 295 |
+
|
| 296 |
+
leadership_counts.append(leadership_count)
|
| 297 |
+
collaboration_counts.append(collaboration_count)
|
| 298 |
+
total_experiences.append(total_experience)
|
| 299 |
+
skill_experience_maps.append(skill_experience)
|
| 300 |
+
|
| 301 |
+
# Calculate averages for leadership and collaboration
|
| 302 |
+
avg_leadership = sum(leadership_counts) / len(leadership_counts) if leadership_counts else 0
|
| 303 |
+
avg_collaboration = sum(collaboration_counts) / len(collaboration_counts) if collaboration_counts else 0
|
| 304 |
+
|
| 305 |
# Create summary table if multiple resumes
|
| 306 |
if multiple_resumes:
|
| 307 |
html += "<h3>Match Summary</h3>"
|
|
|
|
| 309 |
html += "<tr style='background-color: #eee;'><th style='padding: 8px; text-align: left; border: 1px solid #ddd;'>Resume</th>"
|
| 310 |
html += "<th style='padding: 8px; text-align: center; border: 1px solid #ddd;'>Skills Matched</th>"
|
| 311 |
html += "<th style='padding: 8px; text-align: center; border: 1px solid #ddd;'>Match Percentage</th>"
|
| 312 |
+
html += "<th style='padding: 8px; text-align: center; border: 1px solid #ddd;'>Leadership</th>"
|
| 313 |
+
html += "<th style='padding: 8px; text-align: center; border: 1px solid #ddd;'>Collaboration</th>"
|
| 314 |
+
html += "<th style='padding: 8px; text-align: center; border: 1px solid #ddd;'>Years of Experience</th>"
|
| 315 |
+
html += "<th style='padding: 8px; text-align: center; border: 1px solid #ddd;'>Category</th>"
|
| 316 |
html += "<th style='padding: 8px; text-align: center; border: 1px solid #ddd;'>Actions</th></tr>"
|
| 317 |
|
| 318 |
for i, resume_result in enumerate(resume_results, 1):
|
|
|
|
| 322 |
match_count = len(matched_skills)
|
| 323 |
match_percentage = round((match_count / job_result['total_skills'] * 100) if job_result['total_skills'] > 0 else 0, 1)
|
| 324 |
|
| 325 |
+
# Get leadership and collaboration counts
|
| 326 |
+
leadership_count = leadership_counts[i-1]
|
| 327 |
+
collaboration_count = collaboration_counts[i-1]
|
| 328 |
+
|
| 329 |
+
# Get total experience and determine category
|
| 330 |
+
total_experience = total_experiences[i-1]
|
| 331 |
+
if total_experience < 3:
|
| 332 |
+
category = "Entry"
|
| 333 |
+
elif total_experience < 5:
|
| 334 |
+
category = "Intermediate"
|
| 335 |
+
else:
|
| 336 |
+
category = "Advanced"
|
| 337 |
+
|
| 338 |
+
# Add quality modifier if 50% above average
|
| 339 |
+
if leadership_count > avg_leadership * 1.5:
|
| 340 |
+
category = f"Quality {category} (Leadership)"
|
| 341 |
+
elif collaboration_count > avg_collaboration * 1.5:
|
| 342 |
+
category = f"Quality {category} (Collaboration)"
|
| 343 |
+
|
| 344 |
# Add row to summary table
|
| 345 |
html += f"<tr><td style='padding: 8px; border: 1px solid #ddd;'>Resume {i}</td>"
|
| 346 |
html += f"<td style='padding: 8px; text-align: center; border: 1px solid #ddd;'>{match_count}/{job_result['total_skills']}</td>"
|
| 347 |
html += f"<td style='padding: 8px; text-align: center; border: 1px solid #ddd;'>{match_percentage}%</td>"
|
| 348 |
+
html += f"<td style='padding: 8px; text-align: center; border: 1px solid #ddd;'>{leadership_count}</td>"
|
| 349 |
+
html += f"<td style='padding: 8px; text-align: center; border: 1px solid #ddd;'>{collaboration_count}</td>"
|
| 350 |
+
html += f"<td style='padding: 8px; text-align: center; border: 1px solid #ddd;'>{total_experience}</td>"
|
| 351 |
+
html += f"<td style='padding: 8px; text-align: center; border: 1px solid #ddd;'>{category}</td>"
|
| 352 |
html += f"<td style='padding: 8px; text-align: center; border: 1px solid #ddd;'>"
|
| 353 |
+
html += f"<button onclick=\"document.getElementById('resume-detail-{i}').style.display = document.getElementById('resume-detail-{i}').style.display === 'none' ? 'block' : 'none';\" style='background-color: #4CAF50; color: white; padding: 6px 12px; border: none; border-radius: 4px; cursor: pointer; font-size: 14px;'>Toggle Details</button>"
|
| 354 |
html += "</td></tr>"
|
| 355 |
|
| 356 |
html += "</table>"
|
|
|
|
| 368 |
match_percentage = round((match_count / job_result['total_skills'] * 100) if job_result['total_skills'] > 0 else 0, 1)
|
| 369 |
|
| 370 |
html += f"<p><strong>Skills Matched:</strong> {match_count}/{job_result['total_skills']} ({match_percentage}%)</p>"
|
| 371 |
+
|
| 372 |
+
# Show leadership and collaboration counts
|
| 373 |
+
leadership_count = leadership_counts[i-1]
|
| 374 |
+
collaboration_count = collaboration_counts[i-1]
|
| 375 |
+
total_experience = total_experiences[i-1]
|
| 376 |
+
|
| 377 |
+
if total_experience < 3:
|
| 378 |
+
category = "Entry"
|
| 379 |
+
elif total_experience < 5:
|
| 380 |
+
category = "Intermediate"
|
| 381 |
+
else:
|
| 382 |
+
category = "Advanced"
|
| 383 |
+
|
| 384 |
+
# Add quality modifier if 50% above average
|
| 385 |
+
if leadership_count > avg_leadership * 1.5:
|
| 386 |
+
category = f"Quality {category} (Leadership)"
|
| 387 |
+
elif collaboration_count > avg_collaboration * 1.5:
|
| 388 |
+
category = f"Quality {category} (Collaboration)"
|
| 389 |
+
|
| 390 |
+
html += f"<p><strong>Leadership Sentences:</strong> {leadership_count}</p>"
|
| 391 |
+
html += f"<p><strong>Collaboration Sentences:</strong> {collaboration_count}</p>"
|
| 392 |
+
html += f"<p><strong>Total Years of Experience:</strong> {total_experience}</p>"
|
| 393 |
+
html += f"<p><strong>Category:</strong> {category}</p>"
|
| 394 |
|
| 395 |
# Detailed resume section with visibility control
|
| 396 |
html += f"<div id='resume-detail-{i}' style='margin-bottom: 20px; padding: 10px; border: 1px solid #ddd; border-radius: 5px; display: {display_style};'>"
|
|
|
|
| 399 |
# Display all skills found in the resume
|
| 400 |
html += "<p><strong>Skills Found:</strong></p>"
|
| 401 |
html += "<div style='background-color: #f0f0f0; padding: 10px; border-radius: 5px;'>"
|
| 402 |
+
|
| 403 |
+
# Get skill experience map for this resume
|
| 404 |
+
skill_experience = skill_experience_maps[i-1]
|
| 405 |
+
|
| 406 |
for skill in resume_result['skills']:
|
| 407 |
# Highlight matched skills
|
| 408 |
is_match = skill['text'].lower() in job_skills
|
| 409 |
bg_color = "#c8e6c9" if is_match else "#e0e0e0" # Green tint for matches
|
| 410 |
|
| 411 |
+
# Add years of experience for this skill if available
|
| 412 |
+
skill_years = skill_experience.get(skill['text'].lower(), 0)
|
| 413 |
+
experience_text = f" ({skill_years} years)" if skill_years > 0 else ""
|
| 414 |
+
|
| 415 |
+
html += f"<span style='background-color: {bg_color}; padding: 2px 5px; margin: 2px; border-radius: 3px; display: inline-block;'>{skill['text']}{experience_text}</span>"
|
| 416 |
html += "</div>"
|
| 417 |
|
| 418 |
# Job roles section
|