kaauh_ats/recruitment/signals.py
2025-10-05 19:29:53 +03:00

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}")