71 lines
2.4 KiB
Python
71 lines
2.4 KiB
Python
from django.db.models.signals import post_save
|
|
from django.dispatch import receiver
|
|
from . import models
|
|
|
|
# @receiver(post_save, sender=models.Candidate)
|
|
# def parse_resume(sender, instance, created, **kwargs):
|
|
# if instance.resume and not instance.summary:
|
|
# from .utils import extract_summary_from_pdf,match_resume_with_job_description
|
|
# summary = extract_summary_from_pdf(instance.resume.path)
|
|
# if 'error' not in summary:
|
|
# instance.summary = summary
|
|
# instance.save()
|
|
|
|
# match_resume_with_job_description
|
|
|
|
import logging
|
|
logger = logging.getLogger(__name__)
|
|
import os
|
|
from .utils import extract_text_from_pdf,score_resume_with_openrouter
|
|
|
|
|
|
|
|
@receiver(post_save, sender=models.Candidate)
|
|
def score_candidate_resume(sender, instance, created, **kwargs):
|
|
# Skip if no resume or OpenRouter not configured
|
|
if instance.resume is None:
|
|
return
|
|
if kwargs.get('update_fields') is not None:
|
|
return
|
|
|
|
# Optional: Only re-score if resume changed (advanced: track file hash)
|
|
# For simplicity, we score on every save with a resume
|
|
|
|
try:
|
|
# Get absolute file path
|
|
file_path = instance.resume.path
|
|
if not os.path.exists(file_path):
|
|
logger.warning(f"Resume file not found: {file_path}")
|
|
return
|
|
|
|
resume_text = extract_text_from_pdf(file_path)
|
|
# if not resume_text:
|
|
# instance.scoring_error = "Could not extract text from resume."
|
|
# instance.save(update_fields=['scoring_error'])
|
|
# return
|
|
|
|
result = score_resume_with_openrouter(resume_text)
|
|
|
|
# Update candidate with scoring results
|
|
instance.match_score = result.get('match_score')
|
|
instance.strengths = result.get('strengths', '')
|
|
instance.weaknesses = result.get('weaknesses', '')
|
|
instance.criteria_checklist = result.get('criteria_checklist', {})
|
|
|
|
|
|
|
|
# Save only scoring-related fields to avoid recursion
|
|
instance.save(update_fields=[
|
|
'match_score', 'strengths', 'weaknesses',
|
|
'criteria_checklist'
|
|
])
|
|
|
|
logger.info(f"Successfully scored resume for candidate {instance.id}")
|
|
|
|
except Exception as e:
|
|
# error_msg = str(e)[:500] # Truncate to fit TextField
|
|
# instance.scoring_error = error_msg
|
|
# instance.save(update_fields=['scoring_error'])
|
|
logger.error(f"Failed to score resume for candidate {instance.id}: {e}")
|
|
|
|
|