Spaces:
Runtime error
Runtime error
File size: 5,833 Bytes
5348e91 f441e49 5348e91 4fb2f1b 5348e91 f441e49 5348e91 f441e49 4fb2f1b eee2bf3 4fb2f1b 5348e91 4fb2f1b 5348e91 4fb2f1b 5348e91 4fb2f1b 5348e91 f441e49 5348e91 4fb2f1b 5348e91 4fb2f1b 5348e91 4fb2f1b 5348e91 4fb2f1b 5348e91 4fb2f1b 5348e91 4fb2f1b 5348e91 4fb2f1b 5348e91 4fb2f1b |
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 |
# modules/report_generator.py
import datetime
import os
import numpy as np
import matplotlib.pyplot as plt
from reportlab.platypus import SimpleDocTemplate, Paragraph, Spacer, PageBreak, Image, Frame, PageTemplate
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
# --- THIS IS THE FIX: Import TA_LEFT ---
from reportlab.lib.enums import TA_JUSTIFY, TA_CENTER, TA_LEFT
from reportlab.lib.units import inch
from reportlab.lib import colors
from modules.llm_handler import generate_holistic_feedback, parse_scores_from_evaluation
import config
# The rest of the file remains the same...
class ReportPageTemplate(PageTemplate):
def __init__(self, id, pagesize):
frame = Frame(inch, inch, pagesize[0] - 2 * inch, pagesize[1] - 2 * inch, id='normal')
PageTemplate.__init__(self, id, [frame])
def beforeDrawPage(self, canvas, doc):
canvas.saveState()
canvas.setFont('Helvetica', 9)
canvas.setFillColor(colors.grey)
footer_text = f"Page {doc.page} | AI Interview Coach Report | Generated on {datetime.datetime.now().strftime('%Y-%m-%d')}"
canvas.drawCentredString(doc.width / 2 + inch, 0.75 * inch, footer_text)
canvas.restoreState()
def create_radar_chart(labels, scores, file_path):
num_vars = len(labels)
angles = np.linspace(0, 2 * np.pi, num_vars, endpoint=False).tolist()
scores += scores[:1]; angles += angles[:1]
fig, ax = plt.subplots(figsize=(6, 6), subplot_kw=dict(polar=True))
ax.fill(angles, scores, color='#4A90E2', alpha=0.2)
ax.plot(angles, scores, color='#4A90E2', linewidth=2, linestyle='solid')
ax.set_yticklabels([]); ax.set_xticks(angles[:-1]); ax.set_xticklabels(labels, size=12, color='grey')
ax.set_ylim(0, 10)
for angle, score in zip(angles[:-1], scores[:-1]):
ax.text(angle, score + 1.5, str(score), ha='center', va='center', size=14, color="#000000", weight='bold')
plt.title('Performance Snapshot', size=20, color='#333333', y=1.1)
os.makedirs(os.path.dirname(file_path), exist_ok=True)
plt.savefig(file_path, transparent=True, dpi=150)
plt.close(fig)
print(f"📈 Radar chart saved to {file_path}")
def generate_pdf_report(interview_data, file_path):
doc = SimpleDocTemplate(file_path, pagesize=(8.5 * inch, 11 * inch),
leftMargin=inch, rightMargin=inch, topMargin=inch, bottomMargin=inch)
doc.addPageTemplates([ReportPageTemplate('main_template', (8.5 * inch, 11 * inch))])
styles = getSampleStyleSheet()
styles.add(ParagraphStyle(name='ReportTitle', parent=styles['h1'], fontSize=28, alignment=TA_CENTER, spaceAfter=24))
styles.add(ParagraphStyle(name='ReportSubTitle', parent=styles['h2'], fontSize=16, alignment=TA_CENTER, spaceAfter=12, textColor=colors.HexColor('#555555')))
styles.add(ParagraphStyle(name='Justify', alignment=TA_JUSTIFY, spaceAfter=12, leading=14))
styles.add(ParagraphStyle(name='MainHeader', parent=styles['h1'], fontSize=22, spaceBefore=12, spaceAfter=20, alignment=TA_LEFT, textColor=colors.HexColor('#2c3e50')))
styles.add(ParagraphStyle(name='QuestionTitle', parent=styles['h2'], spaceBefore=20, spaceAfter=10, textColor=colors.HexColor('#2980b9')))
styles.add(ParagraphStyle(name='SectionTitle', parent=styles['h3'], spaceBefore=12, spaceAfter=6, textColor=colors.HexColor('#34495e')))
story = []
story.append(Paragraph("Interview Performance Report", styles['ReportTitle']))
story.append(Spacer(1, 0.5 * inch))
story.append(Paragraph(f"Prepared for: <b>{interview_data.get('name', 'N/A')}</b>", styles['ReportSubTitle']))
story.append(Spacer(1, 0.2 * inch))
story.append(Paragraph(f"Interview Type: <b>{interview_data.get('type', 'N/A')}</b>", styles['ReportSubTitle']))
story.append(Spacer(1, 0.2 * inch))
story.append(Paragraph(f"Date of Report: <b>{datetime.datetime.now().strftime('%B %d, %Y')}</b>", styles['ReportSubTitle']))
story.append(PageBreak())
story.append(Paragraph("Overall Performance Analysis", styles['MainHeader']))
full_log_text = ""
all_scores = []
skill_labels = ['Factual Accuracy', 'Relevance & Directness', 'Structure & Clarity']
for i, qa in enumerate(interview_data['q_and_a']):
full_log_text += f"Q{i+1}: {qa['question']}\nA: {qa['answer']}\n---\n"
scores = parse_scores_from_evaluation(qa['evaluation'])
all_scores.append([scores.get(label, 0) for label in skill_labels])
holistic_feedback = generate_holistic_feedback(full_log_text).replace('\n', '<br/>')
story.append(Paragraph(holistic_feedback, styles['Justify']))
story.append(Spacer(1, 0.3 * inch))
if all_scores:
avg_scores = np.mean(all_scores, axis=0).tolist()
chart_path = os.path.join(config.REPORT_FOLDER, "skill_chart.png")
if os.path.exists(chart_path): os.remove(chart_path)
create_radar_chart(skill_labels, avg_scores, chart_path)
story.append(Image(chart_path, width=4.5*inch, height=4.5*inch, hAlign='CENTER'))
story.append(PageBreak())
story.append(Paragraph("Detailed Question Analysis", styles['MainHeader']))
for i, qa in enumerate(interview_data['q_and_a']):
story.append(Paragraph(f"Question {i+1}: {qa['question']}", styles['QuestionTitle']))
story.append(Paragraph("Your Answer:", styles['SectionTitle']))
story.append(Paragraph(qa.get('answer', 'N/A'), styles['Justify']))
story.append(Paragraph("AI Evaluation:", styles['SectionTitle']))
story.append(Paragraph(qa.get('evaluation', 'N/A').replace('\n', '<br/>'), styles['Justify']))
try:
doc.build(story)
print(f"\n✅ Professional report generated successfully: {file_path}")
except Exception as e:
print(f"💥 Error generating professional PDF report: {e}") |