File size: 3,729 Bytes
f0ad734
 
 
 
 
d88c8fe
 
 
 
 
0c36edf
4676010
d88c8fe
 
 
 
4676010
0c36edf
4676010
 
f0ad734
4676010
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
0e5ac9b
4676010
 
 
 
 
 
 
 
 
 
d88c8fe
4676010
 
d88c8fe
 
4676010
 
 
 
 
d88c8fe
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
import gradio as gr
import pdfplumber
import spacy
import os

# Load spaCy with minimal pipelines to save memory
try:
    nlp = spacy.load("en_core_web_sm", disable=["ner", "lemmatizer"])
except Exception as e:
    raise RuntimeError(f"Failed to load spaCy model: {str(e)}")

def generate_portfolio(resume_file):
    # Check if a file was uploaded
    if resume_file is None:
        return "No file uploaded. Please upload a PDF resume."

    # Extract text from PDF
    try:
        with pdfplumber.open(resume_file) as pdf:
            text = "".join(page.extract_text() or "" for page in pdf.pages)
    except Exception as e:
        return f"Error processing PDF: {str(e)}"

    # Parse resume with spaCy
    doc = nlp(text)
    data = {
        "name": "",
        "summary": "",
        "experience": [],
        "skills": [],
        "contact": ""
    }
    for ent in doc.ents:
        if ent.label_ == "PERSON" and not data["name"]:
            data["name"] = ent.text
        elif ent.label_ == "ORG":
            data["experience"].append({"company": ent.text, "role": ""})
        elif ent.label_ == "EMAIL":
            data["contact"] = ent.text

    # Extract skills (simple keyword-based)
    skill_keywords = ["python", "javascript", "sql", "communication", "leadership"]
    data["skills"] = [token.text for token in doc if token.text.lower() in skill_keywords]
    data["summary"] = text[:200] + "..."  # Truncate for demo

    # Delete the uploaded file (privacy)
    os.remove(resume_file)

    # Generate portfolio HTML
    portfolio_html = f"""
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>{data['name']}'s Portfolio</title>
        <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
    </head>
    <body>
        <header class="bg-primary text-white text-center py-5">
            <h1>{data['name']}</h1>
            <p>Professional Portfolio</p>
        </header>
        <div class="container my-5">
            <section>
                <h2>About Me</h2>
                <p>{data['summary']}</p>
            </section>
            <section>
                <h2>Experience</h2>
                {''.join([f'<div class="card mb-3"><div class="card-body"><h5 class="card-title">{exp["company"]}</h5><p class="card-text">{exp["role"]}</p></div></div>' for exp in data['experience']])}
            </section>
            <section>
                <h2>Skills</h2>
                <ul class="list-group">
                    {''.join([f'<li class="list-group-item">{skill}</li>' for skill in data['skills']])}
                </ul>
            </section>
            <section>
                <h2>Contact</h2>
                <p>Email: {data['contact']}</p>
            </section>
        </div>
        <footer class="bg-dark text-white text-center py-3">
            <p>© 2025 {data['name']}</p>
            <p>Generated by Resume-to-Portfolio AI. Your data was processed securely and not retained.</p>
        </footer>
        <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
    </body>
    </html>
    """
    return portfolio_html

# Gradio interface (adjusted for 3.50.0 compatibility)
interface = gr.Interface(
    fn=generate_portfolio,
    inputs=gr.inputs.File(label="Upload Resume (PDF)"),
    outputs=gr.outputs.HTML(label="Your Portfolio"),
    title="Resume to Portfolio Generator",
    description="Upload your resume to generate a portfolio landing page. Your data is processed securely and not stored.",
    allow_flagging="never"
)

interface.launch()