import os from datetime import datetime try: import markdown MARKDOWN_AVAILABLE = True except ImportError: MARKDOWN_AVAILABLE = False # MBTI Type descriptions based on 16personalities.com MBTI_DESCRIPTIONS = { # Analysts (NT) "INTJ": { "name": "Architect", "description": "Imaginative and strategic thinkers, with a plan for everything.", "strengths": ["Strategic thinking", "Independent", "Decisive", "Hard-working", "Open-minded"], "weaknesses": ["Arrogant", "Judgmental", "Overly analytical", "Loathe highly structured environments", "Clueless in romance"], "careers": ["Scientist", "Engineer", "Professor", "Lawyer", "Systems Analyst"] }, "INTP": { "name": "Thinker", "description": "Innovative inventors with an unquenchable thirst for knowledge.", "strengths": ["Analytical", "Original", "Open-minded", "Curious", "Objective"], "weaknesses": ["Disconnected", "Insensitive", "Dissatisfied", "Impatient", "Perfectionist"], "careers": ["Researcher", "Philosopher", "Architect", "Professor", "Mathematician"] }, "ENTJ": { "name": "Commander", "description": "Bold, imaginative and strong-willed leaders, always finding a way – or making one.", "strengths": ["Efficient", "Energetic", "Self-confident", "Strong-willed", "Strategic thinkers"], "weaknesses": ["Stubborn", "Impatient", "Arrogant", "Poor handling of emotions", "Cold and ruthless"], "careers": ["CEO", "Manager", "Entrepreneur", "Judge", "Business Analyst"] }, "ENTP": { "name": "Debater", "description": "Smart and curious thinkers who cannot resist an intellectual challenge.", "strengths": ["Knowledgeable", "Quick thinkers", "Original", "Excellent brainstormers", "Charismatic"], "weaknesses": ["Argumentative", "Insensitive", "Intolerant", "Find it difficult to focus", "Dislike practical matters"], "careers": ["Inventor", "Journalist", "Psychologist", "Photographer", "Consultant"] }, # Diplomats (NF) "INFJ": { "name": "Advocate", "description": "Quiet and mystical, yet very inspiring and tireless idealists.", "strengths": ["Creative", "Insightful", "Inspiring", "Convincing", "Decisive"], "weaknesses": ["Sensitive", "Extremely private", "Perfectionist", "Always need a cause", "Can burn out easily"], "careers": ["Counselor", "Writer", "Psychologist", "Teacher", "Social Worker"] }, "INFP": { "name": "Mediator", "description": "Poetic, kind and altruistic people, always eager to help a good cause.", "strengths": ["Idealistic", "Loyal", "Adaptable", "Curious", "Passionate"], "weaknesses": ["Too idealistic", "Too altruistic", "Impractical", "Dislike dealing with data", "Take things personally"], "careers": ["Writer", "Artist", "Therapist", "Librarian", "Human Resources"] }, "ENFJ": { "name": "Protagonist", "description": "Charismatic and inspiring leaders, able to mesmerize their listeners.", "strengths": ["Tolerant", "Reliable", "Charismatic", "Altruistic", "Natural leaders"], "weaknesses": ["Overly idealistic", "Too selfless", "Too sensitive", "Fluctuating self-esteem", "Struggle to make tough decisions"], "careers": ["Teacher", "Coach", "Politician", "Sales Manager", "Event Coordinator"] }, "ENFP": { "name": "Campaigner", "description": "Enthusiastic, creative and sociable free spirits, who can always find a reason to smile.", "strengths": ["Enthusiastic", "Creative", "Sociable", "Energetic", "Independent"], "weaknesses": ["Poor practical skills", "Find it difficult to focus", "Overthink things", "Get stressed easily", "Highly emotional"], "careers": ["Marketing", "Actor", "Musician", "Social Worker", "Entrepreneur"] }, # Sentinels (SJ) "ISTJ": { "name": "Logistician", "description": "Practical and fact-minded, reliable and responsible.", "strengths": ["Honest", "Direct", "Strong-willed", "Dutiful", "Very responsible"], "weaknesses": ["Stubborn", "Insensitive", "Always by the book", "Judgmental", "Often unreasonably blame themselves"], "careers": ["Accountant", "Administrator", "Military Officer", "Lawyer", "Judge"] }, "ISFJ": { "name": "Protector", "description": "Warm-hearted and dedicated, always ready to protect their loved ones.", "strengths": ["Supportive", "Reliable", "Patient", "Imaginative", "Observant"], "weaknesses": ["Humble", "Shy", "Take things too personally", "Repress their feelings", "Overload themselves"], "careers": ["Nurse", "Teacher", "Social Worker", "Counselor", "Office Manager"] }, "ESTJ": { "name": "Executive", "description": "Excellent administrators, unsurpassed at managing things – or people.", "strengths": ["Dedicated", "Strong-willed", "Direct", "Honest", "Loyal"], "weaknesses": ["Inflexible", "Stubborn", "Uncomfortable with unconventional situations", "Judgmental", "Too focused on social status"], "careers": ["Manager", "Administrator", "Judge", "Teacher", "Military Officer"] }, "ESFJ": { "name": "Consul", "description": "Extraordinarily caring, social and popular people, always eager to help.", "strengths": ["Strong practical skills", "Dutiful", "Very loyal", "Sensitive", "Warm"], "weaknesses": ["Worried about their social status", "Inflexible", "Reluctant to innovate", "Vulnerable to criticism", "Often too needy"], "careers": ["Teacher", "Nurse", "Social Worker", "Counselor", "Office Manager"] }, # Explorers (SP) "ISTP": { "name": "Virtuoso", "description": "Bold and practical experimenters, masters of all kinds of tools.", "strengths": ["Optimistic", "Energetic", "Creative", "Practical", "Spontaneous"], "weaknesses": ["Stubborn", "Insensitive", "Private", "Reserved", "Easily bored"], "careers": ["Mechanic", "Engineer", "Pilot", "Paramedic", "Data Analyst"] }, "ISFP": { "name": "Adventurer", "description": "Flexible and charming artists, always ready to explore new possibilities.", "strengths": ["Charming", "Sensitive to others", "Imaginative", "Passionate", "Curious"], "weaknesses": ["Fiercely independent", "Unpredictable", "Easily stressed", "Overly competitive", "Fluctuating self-esteem"], "careers": ["Artist", "Musician", "Designer", "Photographer", "Chef"] }, "ESTP": { "name": "Entrepreneur", "description": "Smart, energetic and very perceptive people, who truly enjoy living on the edge.", "strengths": ["Tolerant", "Energetic", "Very perceptive", "Excellent people skills", "Direct"], "weaknesses": ["Impatient", "Risk-prone", "Unstructured", "May miss the bigger picture", "Defiant"], "careers": ["Sales Representative", "Paramedic", "Entrepreneur", "Actor", "Real Estate Agent"] }, "ESFP": { "name": "Entertainer", "description": "Spontaneous, energetic and enthusiastic people – life is never boring around them.", "strengths": ["Bold", "Original", "Aesthetics and showcase", "Practical", "Observant"], "weaknesses": ["Sensitive", "Conflict-averse", "Easily bored", "Poor long-term planners", "Unfocused"], "careers": ["Actor", "Artist", "Photographer", "Designer", "Event Planner"] } } def markdown_to_html(markdown_text): """Convert markdown to HTML""" if not markdown_text: return "" if MARKDOWN_AVAILABLE: return markdown.markdown(markdown_text) else: # Fallback: just replace line breaks return markdown_text.replace('\n', '
') def generate_responses_html(responses_data): """Generate HTML for question responses""" if not responses_data: return "

No response data available.

" html = "" html += "" for resp in responses_data: html += f"" html += f"" html += f"" html += f"" html += "" html += "
QuestionDimensionResponse
Q{resp['id']}: {resp['text']}{resp['dimension']}{resp['response']}
" return html def generate_report(mbti_type, analysis, format="html"): """Generate MBTI report in HTML or PDF format""" # Get type info type_info = MBTI_DESCRIPTIONS.get(mbti_type, { "name": "Unknown Type", "description": "Type description not available.", "strengths": ["To be determined"], "weaknesses": ["To be determined"], "careers": ["Various options"] }) # Generate HTML content html_content = f""" MBTI Report - {mbti_type}

Your Personality Type mbti-pocketflow

{mbti_type} - {type_info['name']}

{type_info['description']}

Question Responses

{generate_responses_html(analysis.get('responses_data', []))}

Strengths

Areas for Growth

Career Suggestions

Analysis Details

Traditional Scoring

Scores: {analysis.get('traditional_scores', 'Not available')}

AI Analysis

{markdown_to_html(analysis.get('llm_analysis', 'AI analysis not performed.'))}

Report generated on {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}

""" # Save report to temp directory for HF Spaces compatibility import tempfile timestamp = datetime.now().strftime('%Y%m%d_%H%M%S') filename = f"mbti_report_{mbti_type}_{timestamp}.html" temp_dir = tempfile.gettempdir() full_path = os.path.join(temp_dir, filename) with open(full_path, 'w', encoding='utf-8') as f: f.write(html_content) return full_path if __name__ == "__main__": # Test report generation test_analysis = { 'traditional_scores': {'E_score': 0.6, 'I_score': 0.4}, 'llm_analysis': 'This person shows strong analytical thinking patterns.' } report_path = generate_report("INTJ", test_analysis) print(f"Report generated: {report_path}")