|
|
import gradio as gr |
|
|
from transformers import pipeline |
|
|
import torch |
|
|
import re |
|
|
import os |
|
|
from PyPDF2 import PdfReader |
|
|
import gtts |
|
|
import tempfile |
|
|
import warnings |
|
|
import threading |
|
|
import time |
|
|
import speech_recognition as sr |
|
|
import cv2 |
|
|
import numpy as np |
|
|
import moviepy.editor as mp |
|
|
|
|
|
|
|
|
|
|
|
try: |
|
|
import moviepy.editor as mp |
|
|
except ModuleNotFoundError: |
|
|
raise ImportError("The 'moviepy' module is not installed. Please add 'moviepy' to your requirements.txt and restart your Hugging Face Space.") |
|
|
|
|
|
|
|
|
warnings.filterwarnings("ignore", category=UserWarning, module="gtts") |
|
|
|
|
|
|
|
|
nlp = pipeline("text-generation", model="distilgpt2", tokenizer="distilgpt2", device=0 if torch.cuda.is_available() else -1) |
|
|
sentiment_analyzer = pipeline("sentiment-analysis", model="distilbert-base-uncased-finetuned-sst-2-english") |
|
|
|
|
|
|
|
|
r = sr.Recognizer() |
|
|
|
|
|
|
|
|
def extract_text_from_pdf(pdf_file): |
|
|
try: |
|
|
reader = PdfReader(pdf_file.name) |
|
|
text = "" |
|
|
for page in reader.pages: |
|
|
text += page.extract_text() or "" |
|
|
return text if text else "No text found in the PDF." |
|
|
except Exception as e: |
|
|
return f"Error reading PDF: {str(e)}" |
|
|
|
|
|
|
|
|
def analyze_resume(resume_text, difficulty=1): |
|
|
generic_questions = [ |
|
|
"What’s your greatest strength?", |
|
|
"Describe a challenge you overcame.", |
|
|
"Why do you want this role?" |
|
|
] |
|
|
if not resume_text: |
|
|
return generic_questions[:difficulty] |
|
|
|
|
|
questions = [] |
|
|
skills = re.findall(r"Skills:\s*(.*?)(?:\n|$)", resume_text, re.DOTALL | re.IGNORECASE) |
|
|
|
|
|
if skills: |
|
|
first_skill = skills[0].split(',')[0].strip() |
|
|
questions.append(f"Tell me about a time you used {first_skill} in a project.") |
|
|
|
|
|
return (questions + generic_questions)[:max(1, difficulty)] |
|
|
|
|
|
|
|
|
def provide_feedback(response): |
|
|
if not response: |
|
|
return "Please provide an answer." |
|
|
sentiment = sentiment_analyzer(response)[0] |
|
|
feedback = [] |
|
|
|
|
|
if len(response.split()) < 20: |
|
|
feedback.append("Your answer is short. Please elaborate.") |
|
|
if "I don’t know" in response.lower(): |
|
|
feedback.append("Try sharing a related experience instead.") |
|
|
if sentiment["label"] == "NEGATIVE": |
|
|
feedback.append("Try to sound more positive and confident!") |
|
|
|
|
|
return " ".join(feedback) or "Great answer!" |
|
|
|
|
|
|
|
|
def analyze_code(code): |
|
|
if not code: |
|
|
return "No code provided." |
|
|
try: |
|
|
ast.parse(code) |
|
|
return "Code syntax is valid! Consider adding comments for clarity." |
|
|
except SyntaxError as e: |
|
|
return f"Code error: {str(e)}" |
|
|
|
|
|
|
|
|
def transcribe_audio(file_path): |
|
|
try: |
|
|
if file_path.endswith(".mp4"): |
|
|
video = mp.VideoFileClip(file_path) |
|
|
audio_path = tempfile.NamedTemporaryFile(suffix=".wav").name |
|
|
video.audio.write_audiofile(audio_path) |
|
|
else: |
|
|
audio_path = file_path |
|
|
|
|
|
with sr.AudioFile(audio_path) as source: |
|
|
audio = r.record(source) |
|
|
return r.recognize_google(audio) |
|
|
except Exception as e: |
|
|
return f"Error transcribing: {str(e)}" |
|
|
|
|
|
|
|
|
with gr.Blocks(title="Nancy AI - Advanced Interview Simulator") as demo: |
|
|
gr.Markdown("# 🎤 Nancy AI - Advanced Interview Simulator") |
|
|
gr.Markdown("Upload your resume and a video response to get interview questions and feedback.") |
|
|
|
|
|
question_state = gr.State(value=0) |
|
|
questions_state = gr.State(value=[]) |
|
|
responses_state = gr.State(value=[]) |
|
|
timer_state = gr.State(value=60) |
|
|
|
|
|
with gr.Row(): |
|
|
pdf_input = gr.File(label="📄 Upload PDF Resume", file_types=[".pdf"]) |
|
|
difficulty = gr.Slider(1, 5, step=1, label="🔹 Difficulty Level", value=1) |
|
|
|
|
|
with gr.Row(): |
|
|
video_input = gr.Video(label="🎥 Upload or Record Video Response", interactive=True) |
|
|
code_input = gr.Code(language="python", label="📝 Write Your Code (if applicable)") |
|
|
text_input = gr.Textbox(label="🗣️ Your Response", placeholder="Type your answer here...") |
|
|
|
|
|
with gr.Row(): |
|
|
question_output = gr.Textbox(label="❓ Current Question", interactive=False) |
|
|
feedback_output = gr.Textbox(label="💡 Feedback", interactive=False) |
|
|
timer_display = gr.Textbox(label="⏳ Time Left (seconds)", interactive=False, value="60") |
|
|
|
|
|
submit_btn = gr.Button("✅ Submit Response") |
|
|
|
|
|
|
|
|
def process_response(pdf_file, video_file, code_input, text_input, question_index, questions_state, responses_state, timer_state, difficulty): |
|
|
try: |
|
|
|
|
|
if not questions_state: |
|
|
resume_text = extract_text_from_pdf(pdf_file) if pdf_file else "" |
|
|
questions_state = analyze_resume(resume_text, difficulty) |
|
|
responses_state = [""] * len(questions_state) |
|
|
timer_state = 60 |
|
|
|
|
|
|
|
|
user_response = transcribe_audio(video_file) if video_file else text_input |
|
|
if code_input: |
|
|
user_response = code_input |
|
|
code_feedback = analyze_code(code_input) |
|
|
else: |
|
|
code_feedback = "" |
|
|
|
|
|
|
|
|
if user_response and 0 <= question_index < len(questions_state): |
|
|
responses_state[question_index] = user_response |
|
|
|
|
|
|
|
|
feedback = provide_feedback(user_response) + (f" {code_feedback}" if code_feedback else "") |
|
|
|
|
|
|
|
|
if question_index >= len(questions_state) - 1: |
|
|
return "Interview complete!", "Thank you!", questions_state, responses_state, 0, None |
|
|
|
|
|
return questions_state[question_index], feedback, questions_state, responses_state, question_index + 1, str(max(0, timer_state - 10)) |
|
|
except Exception as e: |
|
|
return f"Error: {str(e)}", "Something went wrong.", [], [], 0, "60" |
|
|
|
|
|
submit_btn.click( |
|
|
fn=process_response, |
|
|
inputs=[pdf_input, video_input, code_input, text_input, question_state, questions_state, responses_state, timer_state, difficulty], |
|
|
outputs=[question_output, feedback_output, questions_state, responses_state, question_state, timer_display] |
|
|
) |
|
|
|
|
|
demo.launch() |
|
|
|