Spaces:
Running
Running
Update app.py
Browse files
app.py
CHANGED
|
@@ -714,8 +714,7 @@ def format_ccog_card(ccog_data):
|
|
| 714 |
card = f"""
|
| 715 |
<div class='ccog-card'>
|
| 716 |
<div class='ccog-header'>
|
| 717 |
-
<h3>
|
| 718 |
-
<div class='ccog-system'>Common Classification of Occupational Groups</div>
|
| 719 |
</div>
|
| 720 |
|
| 721 |
<div class='ccog-levels'>
|
|
@@ -732,16 +731,55 @@ def format_ccog_card(ccog_data):
|
|
| 732 |
{f"<div class='level-desc'>{level['desc']}</div>" if level['desc'] else ""}
|
| 733 |
</div>
|
| 734 |
"""
|
|
|
|
|
|
|
| 735 |
|
| 736 |
-
|
| 737 |
-
|
| 738 |
-
|
| 739 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 740 |
</div>
|
| 741 |
-
|
|
|
|
| 742 |
"""
|
| 743 |
|
| 744 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 745 |
|
| 746 |
# ================= Process Analysis =================
|
| 747 |
from concurrent.futures import ThreadPoolExecutor
|
|
@@ -863,6 +901,7 @@ def process_pdf(file):
|
|
| 863 |
for i in range(1, 6) for field in ["code", "name", "desc"]}
|
| 864 |
esco_skills = None
|
| 865 |
|
|
|
|
| 866 |
formatted_esco_skills = format_skill_cards(esco_skills)
|
| 867 |
|
| 868 |
debug_message = "Processing completed successfully."
|
|
@@ -876,7 +915,8 @@ def process_pdf(file):
|
|
| 876 |
"\n".join(interview),
|
| 877 |
#joined_skills,
|
| 878 |
formatted_skills,
|
| 879 |
-
|
|
|
|
| 880 |
#esco_skills,
|
| 881 |
formatted_esco_skills,
|
| 882 |
debug_message if DEBUG else None
|
|
@@ -1325,7 +1365,7 @@ label {
|
|
| 1325 |
|
| 1326 |
/* Header section */
|
| 1327 |
.skill-header {
|
| 1328 |
-
background: #
|
| 1329 |
color: white;
|
| 1330 |
padding: 1.2rem;
|
| 1331 |
display: flex;
|
|
@@ -1450,7 +1490,6 @@ progress::-webkit-progress-value {
|
|
| 1450 |
margin: 1.5rem 0;
|
| 1451 |
}
|
| 1452 |
|
| 1453 |
-
/* Card styling */
|
| 1454 |
.ccog-card {
|
| 1455 |
background: white;
|
| 1456 |
border-radius: 10px;
|
|
@@ -1460,7 +1499,7 @@ progress::-webkit-progress-value {
|
|
| 1460 |
}
|
| 1461 |
|
| 1462 |
.ccog-header {
|
| 1463 |
-
background: #
|
| 1464 |
color: white;
|
| 1465 |
padding: 1.2rem;
|
| 1466 |
border-bottom: 2px solid rgba(255,255,255,0.1);
|
|
@@ -1478,7 +1517,6 @@ progress::-webkit-progress-value {
|
|
| 1478 |
margin-top: 0.3rem;
|
| 1479 |
}
|
| 1480 |
|
| 1481 |
-
/* Levels hierarchy */
|
| 1482 |
.ccog-levels {
|
| 1483 |
padding: 1rem;
|
| 1484 |
display: flex;
|
|
@@ -1502,6 +1540,61 @@ progress::-webkit-progress-value {
|
|
| 1502 |
opacity: 0.7;
|
| 1503 |
}
|
| 1504 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1505 |
.level-header {
|
| 1506 |
display: flex;
|
| 1507 |
justify-content: space-between;
|
|
@@ -1540,15 +1633,6 @@ progress::-webkit-progress-value {
|
|
| 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 {
|
|
@@ -1593,6 +1677,10 @@ progress::-webkit-progress-value {
|
|
| 1593 |
.ccog-level {
|
| 1594 |
padding: 0.8rem;
|
| 1595 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1596 |
|
| 1597 |
.level-name {
|
| 1598 |
font-size: 1rem;
|
|
@@ -1668,6 +1756,11 @@ progress::-webkit-progress-value {
|
|
| 1668 |
with gr.Column():
|
| 1669 |
gr.Markdown("### Expected Qualifications")
|
| 1670 |
qualification_output = gr.Textbox(label="", lines=5, interactive=False)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1671 |
|
| 1672 |
with gr.Row():
|
| 1673 |
with gr.Column():
|
|
@@ -1676,22 +1769,16 @@ progress::-webkit-progress-value {
|
|
| 1676 |
|
| 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.
|
| 1685 |
-
esco_levels_output = gr.Textbox(label="Mapped ESCO Occupation group")
|
| 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():
|
|
|
|
| 714 |
card = f"""
|
| 715 |
<div class='ccog-card'>
|
| 716 |
<div class='ccog-header'>
|
| 717 |
+
<h3>UN Common Classification of Occupational Groups</h3>
|
|
|
|
| 718 |
</div>
|
| 719 |
|
| 720 |
<div class='ccog-levels'>
|
|
|
|
| 731 |
{f"<div class='level-desc'>{level['desc']}</div>" if level['desc'] else ""}
|
| 732 |
</div>
|
| 733 |
"""
|
| 734 |
+
|
| 735 |
+
"""
|
| 736 |
|
| 737 |
+
return f"<div class='ccog-container'>{card}</div>"
|
| 738 |
+
|
| 739 |
+
# ================= Format CCOG =================
|
| 740 |
+
def format_esco_card(esco_data):
|
| 741 |
+
if not esco_data or not isinstance(esco_data, dict):
|
| 742 |
+
return "<div class='ccog-container'><p>No ESCO classification data available</p></div>"
|
| 743 |
+
|
| 744 |
+
# Extract level data
|
| 745 |
+
levels = []
|
| 746 |
+
for i in range(1, 5):
|
| 747 |
+
level_data = {
|
| 748 |
+
'code': esco_data.get(f'Level_{i}_ESCO_code'),
|
| 749 |
+
'name': esco_data.get(f'Level_{i}_ESCO_name'),
|
| 750 |
+
'desc': esco_data.get(f'Level_{i}_ESCO_desc')
|
| 751 |
+
}
|
| 752 |
+
if level_data['code'] or level_data['name']:
|
| 753 |
+
levels.append(level_data)
|
| 754 |
+
|
| 755 |
+
if not levels:
|
| 756 |
+
return "<div class='esco-container'><p>No valid ESCO classification found</p></div>"
|
| 757 |
+
|
| 758 |
+
# Build the card
|
| 759 |
+
card = f"""
|
| 760 |
+
<div class='esco-card'>
|
| 761 |
+
<div class='esco-header'>
|
| 762 |
+
<h3>ESCO Occupation Classification</h3>
|
| 763 |
</div>
|
| 764 |
+
|
| 765 |
+
<div class='esco-levels'>
|
| 766 |
"""
|
| 767 |
|
| 768 |
+
for i, level in enumerate(levels, 1):
|
| 769 |
+
card += f"""
|
| 770 |
+
<div class='esco-level {'active' if level['desc'] else 'inactive'}'>
|
| 771 |
+
<div class='level-header'>
|
| 772 |
+
<span class='level-number'>Level {i}</span>
|
| 773 |
+
<span class='level-code'>{level['code'] or 'N/A'}</span>
|
| 774 |
+
</div>
|
| 775 |
+
<div class='level-name'>{level['name'] or 'Not classified'}</div>
|
| 776 |
+
{f"<div class='level-desc'>{level['desc']}</div>" if level['desc'] else ""}
|
| 777 |
+
</div>
|
| 778 |
+
"""
|
| 779 |
+
|
| 780 |
+
"""
|
| 781 |
+
|
| 782 |
+
return f"<div class='esco-container'>{card}</div>"
|
| 783 |
|
| 784 |
# ================= Process Analysis =================
|
| 785 |
from concurrent.futures import ThreadPoolExecutor
|
|
|
|
| 901 |
for i in range(1, 6) for field in ["code", "name", "desc"]}
|
| 902 |
esco_skills = None
|
| 903 |
|
| 904 |
+
formatted_esco_levels = format_esco_card(esco_levels)
|
| 905 |
formatted_esco_skills = format_skill_cards(esco_skills)
|
| 906 |
|
| 907 |
debug_message = "Processing completed successfully."
|
|
|
|
| 915 |
"\n".join(interview),
|
| 916 |
#joined_skills,
|
| 917 |
formatted_skills,
|
| 918 |
+
# esco_levels,
|
| 919 |
+
formatted_esco_levels,
|
| 920 |
#esco_skills,
|
| 921 |
formatted_esco_skills,
|
| 922 |
debug_message if DEBUG else None
|
|
|
|
| 1365 |
|
| 1366 |
/* Header section */
|
| 1367 |
.skill-header {
|
| 1368 |
+
background: #ecf0f1;
|
| 1369 |
color: white;
|
| 1370 |
padding: 1.2rem;
|
| 1371 |
display: flex;
|
|
|
|
| 1490 |
margin: 1.5rem 0;
|
| 1491 |
}
|
| 1492 |
|
|
|
|
| 1493 |
.ccog-card {
|
| 1494 |
background: white;
|
| 1495 |
border-radius: 10px;
|
|
|
|
| 1499 |
}
|
| 1500 |
|
| 1501 |
.ccog-header {
|
| 1502 |
+
background: #ecf0f1;
|
| 1503 |
color: white;
|
| 1504 |
padding: 1.2rem;
|
| 1505 |
border-bottom: 2px solid rgba(255,255,255,0.1);
|
|
|
|
| 1517 |
margin-top: 0.3rem;
|
| 1518 |
}
|
| 1519 |
|
|
|
|
| 1520 |
.ccog-levels {
|
| 1521 |
padding: 1rem;
|
| 1522 |
display: flex;
|
|
|
|
| 1540 |
opacity: 0.7;
|
| 1541 |
}
|
| 1542 |
|
| 1543 |
+
/* ESCO card */
|
| 1544 |
+
.esco-container {
|
| 1545 |
+
margin: 1.5rem 0;
|
| 1546 |
+
}
|
| 1547 |
+
|
| 1548 |
+
.esco-card {
|
| 1549 |
+
background: white;
|
| 1550 |
+
border-radius: 10px;
|
| 1551 |
+
box-shadow: 0 4px 12px rgba(0,0,0,0.08);
|
| 1552 |
+
overflow: hidden;
|
| 1553 |
+
border: 1px solid #e0e0e0;
|
| 1554 |
+
}
|
| 1555 |
+
|
| 1556 |
+
.esco-header {
|
| 1557 |
+
background: #ecf0f1;
|
| 1558 |
+
color: white;
|
| 1559 |
+
padding: 1.2rem;
|
| 1560 |
+
border-bottom: 2px solid rgba(255,255,255,0.1);
|
| 1561 |
+
}
|
| 1562 |
+
|
| 1563 |
+
.esco-header h3 {
|
| 1564 |
+
margin: 0;
|
| 1565 |
+
font-size: 1.3rem;
|
| 1566 |
+
font-weight: 600;
|
| 1567 |
+
}
|
| 1568 |
+
|
| 1569 |
+
.esco-system {
|
| 1570 |
+
opacity: 0.9;
|
| 1571 |
+
font-size: 0.85rem;
|
| 1572 |
+
margin-top: 0.3rem;
|
| 1573 |
+
}
|
| 1574 |
+
|
| 1575 |
+
.esco-levels {
|
| 1576 |
+
padding: 1rem;
|
| 1577 |
+
display: flex;
|
| 1578 |
+
flex-direction: column;
|
| 1579 |
+
gap: 0.5rem;
|
| 1580 |
+
}
|
| 1581 |
+
|
| 1582 |
+
.esco-level {
|
| 1583 |
+
padding: 1rem;
|
| 1584 |
+
border-radius: 6px;
|
| 1585 |
+
position: relative;
|
| 1586 |
+
}
|
| 1587 |
+
|
| 1588 |
+
.esco-level.active {
|
| 1589 |
+
background: #f8fafc;
|
| 1590 |
+
border-left: 4px solid #0033A0;
|
| 1591 |
+
}
|
| 1592 |
+
|
| 1593 |
+
.esco-level.inactive {
|
| 1594 |
+
background: #f5f5f5;
|
| 1595 |
+
opacity: 0.7;
|
| 1596 |
+
}
|
| 1597 |
+
|
| 1598 |
.level-header {
|
| 1599 |
display: flex;
|
| 1600 |
justify-content: space-between;
|
|
|
|
| 1633 |
margin-top: 0.5rem;
|
| 1634 |
}
|
| 1635 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1636 |
|
| 1637 |
/* Output Markdown */
|
| 1638 |
.gr-markdown {
|
|
|
|
| 1677 |
.ccog-level {
|
| 1678 |
padding: 0.8rem;
|
| 1679 |
}
|
| 1680 |
+
|
| 1681 |
+
.esco-level {
|
| 1682 |
+
padding: 0.8rem;
|
| 1683 |
+
}
|
| 1684 |
|
| 1685 |
.level-name {
|
| 1686 |
font-size: 1rem;
|
|
|
|
| 1756 |
with gr.Column():
|
| 1757 |
gr.Markdown("### Expected Qualifications")
|
| 1758 |
qualification_output = gr.Textbox(label="", lines=5, interactive=False)
|
| 1759 |
+
|
| 1760 |
+
with gr.Row():
|
| 1761 |
+
with gr.Column():
|
| 1762 |
+
gr.Markdown("## Interview Questions")
|
| 1763 |
+
interview_output = gr.Textbox(label="Interview Questions", lines=10, interactive=False)
|
| 1764 |
|
| 1765 |
with gr.Row():
|
| 1766 |
with gr.Column():
|
|
|
|
| 1769 |
|
| 1770 |
with gr.Row():
|
| 1771 |
with gr.Column():
|
|
|
|
| 1772 |
ccoq_levels_output = gr.HTML(label="", elem_classes="ccog-container")
|
| 1773 |
|
| 1774 |
with gr.Row():
|
| 1775 |
with gr.Column():
|
| 1776 |
+
esco_levels_output = gr.HTML(label="", elem_classes="esco-container")
|
|
|
|
| 1777 |
|
| 1778 |
with gr.Row():
|
| 1779 |
with gr.Column():
|
| 1780 |
+
esco_skills_output = gr.HTML(label="Linked ESCO Skills", elem_classes="skills-container")
|
| 1781 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1782 |
|
| 1783 |
with gr.Row():
|
| 1784 |
with gr.Column():
|