Spaces:
Running
Running
Update app.py
Browse files
app.py
CHANGED
|
@@ -691,6 +691,57 @@ def get_progress_value(level):
|
|
| 691 |
level_map = {"basic": 1, "intermediate": 2, "advanced": 3}
|
| 692 |
return str(level_map.get(level.lower(), 1))
|
| 693 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 694 |
|
| 695 |
# ================= Process Analysis =================
|
| 696 |
from concurrent.futures import ThreadPoolExecutor
|
|
@@ -797,7 +848,8 @@ def process_pdf(file):
|
|
| 797 |
# Prepare the results for each output component
|
| 798 |
ccoq_levels = {f"Level_{i}_CCOG_{field}": occ_group.get(f"Level_{i}_CCOG_{field}")
|
| 799 |
for i in range(1, 5) for field in ["code", "name", "desc"]}
|
| 800 |
-
|
|
|
|
| 801 |
if has_esco:
|
| 802 |
esco_levels = {f"Level_{i}_ESCO_{field}": esco_occ.get(f"Level_{i}_ESCO_{field}")
|
| 803 |
for i in range(1, 6) for field in ["code", "name", "desc"]}
|
|
@@ -819,7 +871,8 @@ def process_pdf(file):
|
|
| 819 |
responsibilities,
|
| 820 |
job_family,
|
| 821 |
"\n".join(qualification),
|
| 822 |
-
ccoq_levels,
|
|
|
|
| 823 |
"\n".join(interview),
|
| 824 |
#joined_skills,
|
| 825 |
formatted_skills,
|
|
@@ -1392,6 +1445,110 @@ progress::-webkit-progress-value {
|
|
| 1392 |
min-width: 80px;
|
| 1393 |
text-align: right;
|
| 1394 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1395 |
|
| 1396 |
/* Output Markdown */
|
| 1397 |
.gr-markdown {
|
|
@@ -1432,6 +1589,14 @@ progress::-webkit-progress-value {
|
|
| 1432 |
align-items: flex-start;
|
| 1433 |
gap: 0.5rem;
|
| 1434 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1435 |
}
|
| 1436 |
""",
|
| 1437 |
head='''
|
|
@@ -1497,11 +1662,7 @@ progress::-webkit-progress-value {
|
|
| 1497 |
with gr.Row():
|
| 1498 |
with gr.Column():
|
| 1499 |
gr.Markdown("### Mapped Skills")
|
| 1500 |
-
skills_output = gr.HTML(
|
| 1501 |
-
value="",
|
| 1502 |
-
label="",
|
| 1503 |
-
elem_classes=["skills-container"]
|
| 1504 |
-
)
|
| 1505 |
|
| 1506 |
with gr.Row():
|
| 1507 |
with gr.Column():
|
|
@@ -1516,11 +1677,8 @@ progress::-webkit-progress-value {
|
|
| 1516 |
with gr.Row():
|
| 1517 |
with gr.Column():
|
| 1518 |
gr.Markdown("### United Nations Occupation Common Classification")
|
| 1519 |
-
ccoq_levels_output = gr.
|
| 1520 |
|
| 1521 |
-
|
| 1522 |
-
|
| 1523 |
-
|
| 1524 |
with gr.Row():
|
| 1525 |
with gr.Column():
|
| 1526 |
gr.Markdown("### ESCO Mapping")
|
|
@@ -1528,21 +1686,13 @@ progress::-webkit-progress-value {
|
|
| 1528 |
|
| 1529 |
with gr.Row():
|
| 1530 |
with gr.Column():
|
| 1531 |
-
esco_skills_output = (
|
| 1532 |
-
value="",
|
| 1533 |
-
label="",
|
| 1534 |
-
elem_classes=["skills-container"]
|
| 1535 |
-
)
|
| 1536 |
-
|
| 1537 |
-
|
| 1538 |
|
| 1539 |
with gr.Row():
|
| 1540 |
with gr.Column():
|
| 1541 |
gr.Markdown("## Interview Questions")
|
| 1542 |
interview_output = gr.Textbox(label="Interview Questions", lines=10, interactive=False)
|
| 1543 |
|
| 1544 |
-
|
| 1545 |
-
|
| 1546 |
with gr.Row():
|
| 1547 |
with gr.Column():
|
| 1548 |
download_btn = gr.Button(
|
|
|
|
| 691 |
level_map = {"basic": 1, "intermediate": 2, "advanced": 3}
|
| 692 |
return str(level_map.get(level.lower(), 1))
|
| 693 |
|
| 694 |
+
# ================= Format CCOG =================
|
| 695 |
+
def format_ccog_card(ccog_data):
|
| 696 |
+
if not ccog_data or not isinstance(ccog_data, dict):
|
| 697 |
+
return "<div class='ccog-container'><p>No CCOG classification data available</p></div>"
|
| 698 |
+
|
| 699 |
+
# Extract level data
|
| 700 |
+
levels = []
|
| 701 |
+
for i in range(1, 5):
|
| 702 |
+
level_data = {
|
| 703 |
+
'code': ccog_data.get(f'Level_{i}_CCOG_code'),
|
| 704 |
+
'name': ccog_data.get(f'Level_{i}_CCOG_name'),
|
| 705 |
+
'desc': ccog_data.get(f'Level_{i}_CCOG_desc')
|
| 706 |
+
}
|
| 707 |
+
if level_data['code'] or level_data['name']:
|
| 708 |
+
levels.append(level_data)
|
| 709 |
+
|
| 710 |
+
if not levels:
|
| 711 |
+
return "<div class='ccog-container'><p>No valid CCOG classification found</p></div>"
|
| 712 |
+
|
| 713 |
+
# Build the card
|
| 714 |
+
card = f"""
|
| 715 |
+
<div class='ccog-card'>
|
| 716 |
+
<div class='ccog-header'>
|
| 717 |
+
<h3>CCOG Classification</h3>
|
| 718 |
+
<div class='ccog-system'>Common Classification of Occupational Groups</div>
|
| 719 |
+
</div>
|
| 720 |
+
|
| 721 |
+
<div class='ccog-levels'>
|
| 722 |
+
"""
|
| 723 |
+
|
| 724 |
+
for i, level in enumerate(levels, 1):
|
| 725 |
+
card += f"""
|
| 726 |
+
<div class='ccog-level {'active' if level['desc'] else 'inactive'}'>
|
| 727 |
+
<div class='level-header'>
|
| 728 |
+
<span class='level-number'>Level {i}</span>
|
| 729 |
+
<span class='level-code'>{level['code'] or 'N/A'}</span>
|
| 730 |
+
</div>
|
| 731 |
+
<div class='level-name'>{level['name'] or 'Not classified'}</div>
|
| 732 |
+
{f"<div class='level-desc'>{level['desc']}</div>" if level['desc'] else ""}
|
| 733 |
+
</div>
|
| 734 |
+
"""
|
| 735 |
+
|
| 736 |
+
card += """
|
| 737 |
+
</div>
|
| 738 |
+
<div class='ccog-footer'>
|
| 739 |
+
International Organization for Migration Standard Classification
|
| 740 |
+
</div>
|
| 741 |
+
</div>
|
| 742 |
+
"""
|
| 743 |
+
|
| 744 |
+
return f"<div class='ccog-container'>{card}</div>"
|
| 745 |
|
| 746 |
# ================= Process Analysis =================
|
| 747 |
from concurrent.futures import ThreadPoolExecutor
|
|
|
|
| 848 |
# Prepare the results for each output component
|
| 849 |
ccoq_levels = {f"Level_{i}_CCOG_{field}": occ_group.get(f"Level_{i}_CCOG_{field}")
|
| 850 |
for i in range(1, 5) for field in ["code", "name", "desc"]}
|
| 851 |
+
formatted_ccog = format_ccog_card(ccoq_levels)
|
| 852 |
+
|
| 853 |
if has_esco:
|
| 854 |
esco_levels = {f"Level_{i}_ESCO_{field}": esco_occ.get(f"Level_{i}_ESCO_{field}")
|
| 855 |
for i in range(1, 6) for field in ["code", "name", "desc"]}
|
|
|
|
| 871 |
responsibilities,
|
| 872 |
job_family,
|
| 873 |
"\n".join(qualification),
|
| 874 |
+
#ccoq_levels,
|
| 875 |
+
formatted_ccog,
|
| 876 |
"\n".join(interview),
|
| 877 |
#joined_skills,
|
| 878 |
formatted_skills,
|
|
|
|
| 1445 |
min-width: 80px;
|
| 1446 |
text-align: right;
|
| 1447 |
}
|
| 1448 |
+
/* CCOG card */
|
| 1449 |
+
.ccog-container {
|
| 1450 |
+
margin: 1.5rem 0;
|
| 1451 |
+
}
|
| 1452 |
+
|
| 1453 |
+
/* Card styling */
|
| 1454 |
+
.ccog-card {
|
| 1455 |
+
background: white;
|
| 1456 |
+
border-radius: 10px;
|
| 1457 |
+
box-shadow: 0 4px 12px rgba(0,0,0,0.08);
|
| 1458 |
+
overflow: hidden;
|
| 1459 |
+
border: 1px solid #e0e0e0;
|
| 1460 |
+
}
|
| 1461 |
+
|
| 1462 |
+
.ccog-header {
|
| 1463 |
+
background: #0033A0;
|
| 1464 |
+
color: white;
|
| 1465 |
+
padding: 1.2rem;
|
| 1466 |
+
border-bottom: 2px solid rgba(255,255,255,0.1);
|
| 1467 |
+
}
|
| 1468 |
+
|
| 1469 |
+
.ccog-header h3 {
|
| 1470 |
+
margin: 0;
|
| 1471 |
+
font-size: 1.3rem;
|
| 1472 |
+
font-weight: 600;
|
| 1473 |
+
}
|
| 1474 |
+
|
| 1475 |
+
.ccog-system {
|
| 1476 |
+
opacity: 0.9;
|
| 1477 |
+
font-size: 0.85rem;
|
| 1478 |
+
margin-top: 0.3rem;
|
| 1479 |
+
}
|
| 1480 |
+
|
| 1481 |
+
/* Levels hierarchy */
|
| 1482 |
+
.ccog-levels {
|
| 1483 |
+
padding: 1rem;
|
| 1484 |
+
display: flex;
|
| 1485 |
+
flex-direction: column;
|
| 1486 |
+
gap: 0.5rem;
|
| 1487 |
+
}
|
| 1488 |
+
|
| 1489 |
+
.ccog-level {
|
| 1490 |
+
padding: 1rem;
|
| 1491 |
+
border-radius: 6px;
|
| 1492 |
+
position: relative;
|
| 1493 |
+
}
|
| 1494 |
+
|
| 1495 |
+
.ccog-level.active {
|
| 1496 |
+
background: #f8fafc;
|
| 1497 |
+
border-left: 4px solid #0033A0;
|
| 1498 |
+
}
|
| 1499 |
+
|
| 1500 |
+
.ccog-level.inactive {
|
| 1501 |
+
background: #f5f5f5;
|
| 1502 |
+
opacity: 0.7;
|
| 1503 |
+
}
|
| 1504 |
+
|
| 1505 |
+
.level-header {
|
| 1506 |
+
display: flex;
|
| 1507 |
+
justify-content: space-between;
|
| 1508 |
+
margin-bottom: 0.5rem;
|
| 1509 |
+
align-items: center;
|
| 1510 |
+
}
|
| 1511 |
+
|
| 1512 |
+
.level-number {
|
| 1513 |
+
font-weight: 600;
|
| 1514 |
+
color: #0033A0;
|
| 1515 |
+
font-size: 0.9rem;
|
| 1516 |
+
}
|
| 1517 |
+
|
| 1518 |
+
.level-code {
|
| 1519 |
+
background: rgba(0,51,160,0.1);
|
| 1520 |
+
color: #0033A0;
|
| 1521 |
+
padding: 0.2rem 0.5rem;
|
| 1522 |
+
border-radius: 4px;
|
| 1523 |
+
font-size: 0.8rem;
|
| 1524 |
+
font-family: monospace;
|
| 1525 |
+
}
|
| 1526 |
+
|
| 1527 |
+
.level-name {
|
| 1528 |
+
font-weight: 500;
|
| 1529 |
+
font-size: 1.05rem;
|
| 1530 |
+
margin-bottom: 0.5rem;
|
| 1531 |
+
color: #333;
|
| 1532 |
+
}
|
| 1533 |
+
|
| 1534 |
+
.level-desc {
|
| 1535 |
+
font-size: 0.9rem;
|
| 1536 |
+
color: #555;
|
| 1537 |
+
line-height: 1.5;
|
| 1538 |
+
padding-top: 0.5rem;
|
| 1539 |
+
border-top: 1px dashed #e0e0e0;
|
| 1540 |
+
margin-top: 0.5rem;
|
| 1541 |
+
}
|
| 1542 |
+
|
| 1543 |
+
|
| 1544 |
+
.ccog-footer {
|
| 1545 |
+
padding: 0.8rem 1.2rem;
|
| 1546 |
+
background: #f5f7fa;
|
| 1547 |
+
color: #666;
|
| 1548 |
+
font-size: 0.8rem;
|
| 1549 |
+
text-align: center;
|
| 1550 |
+
border-top: 1px solid #eee;
|
| 1551 |
+
}
|
| 1552 |
|
| 1553 |
/* Output Markdown */
|
| 1554 |
.gr-markdown {
|
|
|
|
| 1589 |
align-items: flex-start;
|
| 1590 |
gap: 0.5rem;
|
| 1591 |
}
|
| 1592 |
+
|
| 1593 |
+
.ccog-level {
|
| 1594 |
+
padding: 0.8rem;
|
| 1595 |
+
}
|
| 1596 |
+
|
| 1597 |
+
.level-name {
|
| 1598 |
+
font-size: 1rem;
|
| 1599 |
+
}
|
| 1600 |
}
|
| 1601 |
""",
|
| 1602 |
head='''
|
|
|
|
| 1662 |
with gr.Row():
|
| 1663 |
with gr.Column():
|
| 1664 |
gr.Markdown("### Mapped Skills")
|
| 1665 |
+
skills_output = gr.HTML(label="", elem_classes="skills-container")
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1666 |
|
| 1667 |
with gr.Row():
|
| 1668 |
with gr.Column():
|
|
|
|
| 1677 |
with gr.Row():
|
| 1678 |
with gr.Column():
|
| 1679 |
gr.Markdown("### United Nations Occupation Common Classification")
|
| 1680 |
+
ccoq_levels_output = gr.HTML(label="", elem_classes="ccog-container")
|
| 1681 |
|
|
|
|
|
|
|
|
|
|
| 1682 |
with gr.Row():
|
| 1683 |
with gr.Column():
|
| 1684 |
gr.Markdown("### ESCO Mapping")
|
|
|
|
| 1686 |
|
| 1687 |
with gr.Row():
|
| 1688 |
with gr.Column():
|
| 1689 |
+
esco_skills_output = gr.HTML(label="", elem_classes="skills-container")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1690 |
|
| 1691 |
with gr.Row():
|
| 1692 |
with gr.Column():
|
| 1693 |
gr.Markdown("## Interview Questions")
|
| 1694 |
interview_output = gr.Textbox(label="Interview Questions", lines=10, interactive=False)
|
| 1695 |
|
|
|
|
|
|
|
| 1696 |
with gr.Row():
|
| 1697 |
with gr.Column():
|
| 1698 |
download_btn = gr.Button(
|