File size: 6,006 Bytes
cf8a522
92f45fe
7716c5c
8e1d297
92f45fe
 
8e1d297
 
4c77f62
8e1d297
 
92f45fe
7716c5c
 
92f45fe
 
 
 
7716c5c
 
9753cc9
92f45fe
 
9753cc9
92f45fe
 
 
50528fd
92f45fe
 
 
 
 
 
 
 
 
 
 
 
 
 
7716c5c
92f45fe
8e1d297
 
7716c5c
 
 
 
 
 
 
50528fd
 
 
 
 
7716c5c
 
 
 
50528fd
 
 
7716c5c
 
d836318
7716c5c
 
 
 
50528fd
7716c5c
 
 
 
d836318
7716c5c
 
 
50528fd
 
7716c5c
 
50528fd
7716c5c
50528fd
 
7716c5c
50528fd
 
 
 
 
 
 
 
 
 
 
 
 
 
 
7716c5c
 
 
d836318
 
 
 
 
50528fd
d836318
 
50528fd
d836318
50528fd
 
 
 
d836318
 
50528fd
 
 
 
 
 
 
 
 
 
 
d836318
 
7716c5c
 
8e1d297
6088e9d
8e1d297
6088e9d
50528fd
8e1d297
50528fd
7716c5c
50528fd
d836318
 
8e1d297
 
586dcd2
8e1d297
50528fd
7716c5c
50528fd
 
7716c5c
8e1d297
7716c5c
8e1d297
d836318
8e1d297
9753cc9
8e1d297
d836318
 
7716c5c
d836318
50528fd
 
 
 
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
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
import os
import tempfile
import re
import streamlit as st
import docx
import textract

#####################################
# Function: Extract Text from File
#####################################
def extract_text_from_file(file_obj):
    """
    Extract text from .doc and .docx files.
    Returns the extracted text or an error message if extraction fails.
    """
    filename = file_obj.name
    ext = os.path.splitext(filename)[1].lower()
    text = ""

    if ext == ".docx":
        try:
            document = docx.Document(file_obj)
            text = "\n".join([para.text for para in document.paragraphs])
        except Exception as e:
            text = f"Error processing DOCX file: {e}"
    elif ext == ".doc":
        try:
            # textract requires a filename; solve this using a temporary file.
            with tempfile.NamedTemporaryFile(delete=False, suffix=".doc") as tmp:
                tmp.write(file_obj.read())
                tmp.flush()
                tmp_filename = tmp.name
            text = textract.process(tmp_filename).decode("utf-8")
        except Exception as e:
            text = f"Error processing DOC file: {e}"
        finally:
            try:
                os.remove(tmp_filename)
            except Exception:
                pass
    else:
        text = "Unsupported file type."

    return text

#####################################
# Function: Extract Basic Resume Information
#####################################
def extract_basic_resume_info(text):
    """
    Parse the extracted text to summarize basic info:
    - Name
    - Age
    - Job Experience (years or descriptive)
    - Skills
    - Education

    Returns a dictionary with the extracted elements.
    """
    info = {
        "Name": None,
        "Age": None,
        "Job Experience": None,
        "Skills": None,
        "Education": None,
    }

    # Extract Name (e.g., "Name: John Doe")
    name_match = re.search(r"[Nn]ame[:\-]\s*([A-Za-z\s]+)", text)
    if name_match:
        info["Name"] = name_match.group(1).strip()
    else:
        # Fallback: heuristic, assume the first two or three capitalized words are the candidate name.
        potential_names = re.findall(r"\b[A-Z][a-z]+(?:\s+[A-Z][a-z]+){1,2}\b", text)
        if potential_names:
            info["Name"] = potential_names[0]

    # Extract Age (e.g., "Age: 28")
    age_match = re.search(r"[Aa]ge[:\-]\s*(\d{1,2})", text)
    if age_match:
        info["Age"] = age_match.group(1)
        
    # Extract Job Experience (e.g., "5 years of experience")
    exp_match = re.search(r"(\d+)\s+(years|yrs)\s+(?:of\s+)?experience", text, re.IGNORECASE)
    if exp_match:
        info["Job Experience"] = f"{exp_match.group(1)} {exp_match.group(2)}"
    else:
        # Attempt to capture a descriptive work experience line via a labeled section.
        exp_line = re.search(r"(Experience|Work History)[:\-]\s*(.+)", text, re.IGNORECASE)
        if exp_line:
            info["Job Experience"] = exp_line.group(2).strip()

    # Extract Skills (e.g., "Skills: Python, Java, SQL")
    # This is a simple pattern and might require refinement for your resume formats.
    skills_match = re.search(r"(Skills|Technical Skills)[:\-]\s*(.+)", text, re.IGNORECASE)
    if skills_match:
        # Cleanup skills by removing any trailing or extra characters.
        skills_str = skills_match.group(2).strip()
        info["Skills"] = skills_str.rstrip(".")
        
    # Extract Education (e.g., "Education: B.Sc in Computer Science")
    edu_match = re.search(r"Education[:\-]\s*(.+)", text, re.IGNORECASE)
    if edu_match:
        edu_str = edu_match.group(1).strip()
        info["Education"] = edu_str.rstrip(".")

    return info

#####################################
# Function: Summarize Basic Info into a Paragraph
#####################################
def summarize_basic_info(info):
    """
    Combine the extracted basic resume information into a cohesive paragraph.
    """
    parts = []

    if info.get("Name"):
        parts.append(f"Candidate {info['Name']}")
    else:
        parts.append("The candidate")
    
    if info.get("Age"):
        parts.append(f"aged {info['Age']}")
    
    if info.get("Job Experience"):
        parts.append(f"with {info['Job Experience']} of work experience")
    
    if info.get("Skills"):
        parts.append(f"skilled in {info['Skills']}")
    
    if info.get("Education"):
        parts.append(f"and educated with a background in {info['Education']}")
    
    summary_paragraph = ", ".join(parts) + "."
    return summary_paragraph

#####################################
# Main Resume Processing Logic
#####################################
def process_resume(file_obj):
    if file_obj is None:
        return None, None
    # Extract the full resume text.
    resume_text = extract_text_from_file(file_obj)
    # Extract basic info from the text.
    basic_info = extract_basic_resume_info(resume_text)
    # Create a summary paragraph from the extracted info.
    summary_paragraph = summarize_basic_info(basic_info)
    return resume_text, summary_paragraph

#####################################
# Streamlit Interface
#####################################
st.title("Resume Basic Information Summary")
st.markdown("""
Upload your resume file in **.doc** or **.docx** format. The app will extract the document's content and generate a summary paragraph
highlighting the candidate’s name, age, job experience, skills, and education.
""")

uploaded_file = st.file_uploader("Upload Resume", type=["doc", "docx"])

if st.button("Process Resume"):
    if uploaded_file is None:
        st.error("Please upload a file first.")
    else:
        with st.spinner("Processing resume..."):
            resume_text, summary_paragraph = process_resume(uploaded_file)

        st.subheader("Summary of Basic Information")
        st.markdown(summary_paragraph)

        st.subheader("Full Extracted Resume Text")
        st.text_area("", resume_text, height=300)