Spaces:
Sleeping
Sleeping
| from reportlab.pdfgen import canvas | |
| from reportlab.pdfbase.ttfonts import TTFont | |
| from reportlab.pdfbase import pdfmetrics | |
| from PyPDF2 import PdfReader | |
| from PyPDF2 import PdfWriter | |
| import openai | |
| import uuid | |
| import os | |
| import gradio as gr | |
| # 確保字體文件和模板文件存在於同一目錄 | |
| pdfmetrics.registerFont(TTFont("ArialUnicode", "./Arial Unicode.ttf")) | |
| def draw_data_on_template(template_path, name, email, phone, education, experience, skills, social_media): | |
| try: | |
| temp_pdf_path = f"./{uuid.uuid4()}_temp.pdf" | |
| c = canvas.Canvas(temp_pdf_path) | |
| c.setFont("ArialUnicode", 22) | |
| c.drawString(15, 750, f"Name: {name}") | |
| c.drawString(15, 680, f"Email: {email}") | |
| c.drawString(15, 610, f"Phone: {phone}") | |
| c.drawString(15, 540, f"Education: {education}") | |
| c.drawString(15, 470, f"Work Experience: {experience}") | |
| c.drawString(15, 340, f"Skills: {skills}") | |
| c.drawString(15, 200, f"Social Media: {social_media}") | |
| c.save() | |
| # 加載模板 PDF | |
| reader = PdfReader(template_path) | |
| template_page = reader.pages[0] | |
| content_reader = PdfReader(temp_pdf_path) | |
| content_page = content_reader.pages[0] | |
| template_page.merge_page(content_page) | |
| merged_pdf_path = f"./{uuid.uuid4()}_merged.pdf" | |
| writer = PdfWriter() | |
| writer.add_page(template_page) | |
| with open(merged_pdf_path, "wb") as output_file: | |
| writer.write(output_file) | |
| os.remove(temp_pdf_path) | |
| return merged_pdf_path | |
| except Exception as e: | |
| return f"Error in Drawing Data on Template: {str(e)}" | |
| def recommend_jobs(api_key, skills): | |
| try: | |
| openai.api_key = api_key | |
| skills_list = [skill.strip() for skill in skills.split(",") if skill.strip()] | |
| if not skills_list: | |
| return "Error: No valid skills provided." | |
| prompt = f"請用正體中文回覆,根據以下技能推薦適合的職位:{', '.join(skills_list)}" | |
| response = openai.ChatCompletion.create( | |
| model="gpt-4", | |
| messages=[{"role": "user", "content": prompt}] | |
| ) | |
| if not response.choices: | |
| return "Error: OpenAI API returned no results." | |
| return response.choices[0].message['content'].strip() | |
| except Exception as e: | |
| return f"Error in Job Recommendation: {str(e)}" | |
| def validate_and_process(api_key, name, email, phone, education, experience, skills, social_media): | |
| errors = [] | |
| if not name.strip(): | |
| errors.append("Name不能為空.") | |
| if not email.strip(): | |
| errors.append("Email不能為空.") | |
| if not phone.strip(): | |
| errors.append("Phone不能為空.") | |
| if not education.strip(): | |
| errors.append("Education不能為空.") | |
| if not skills.strip(): | |
| errors.append("Skills不能為空.") | |
| if errors: | |
| return None, "\n".join(errors), "請填寫完整後重試!" | |
| template_path = "./resume_null.pdf" # 確保模板文件上傳至同一目錄 | |
| merged_pdf = draw_data_on_template(template_path, name, email, phone, education, experience, skills, social_media) | |
| if isinstance(merged_pdf, str) and merged_pdf.startswith("Error"): | |
| return None, merged_pdf, "Merging with template failed." | |
| job_recommendations = recommend_jobs(api_key, skills) | |
| if job_recommendations.startswith("Error"): | |
| return merged_pdf, "Resume generated successfully!", job_recommendations | |
| return merged_pdf, "Resume generated successfully!", job_recommendations | |
| with gr.Blocks() as demo: | |
| gr.Markdown("# 自動生成簡歷工具") | |
| api_key = gr.Textbox(label="OpenAI API Key", placeholder="請輸入您的 OpenAI API Key", type="password") | |
| name = gr.Textbox(label="Name(必填)", placeholder="例:王小明") | |
| email = gr.Textbox(label="Email(必填)", placeholder="a1234567890@example.com") | |
| phone = gr.Textbox(label="Phone(必填)", placeholder="0912345678") | |
| education = gr.Textbox(label="Education(必填)", placeholder="例:學位、主修、學校") | |
| experience = gr.Textbox(label="Work Experience", placeholder="例:實習、兼職工作") | |
| skills = gr.Textbox(label="Skills(必填)", placeholder="例:Python, Teaching, Data Analysis (多項技能用,分隔)") | |
| social_media = gr.Textbox(label="Social Media", placeholder="例:LinkedIn URL") | |
| pdf_output = gr.File(label="Download Your Resume") | |
| status = gr.Textbox(label="Status / Error", interactive=False) | |
| job_recommendations = gr.Textbox(label="Recommended Jobs", interactive=False) | |
| generate_button = gr.Button("Generate Resume & Recommend Jobs") | |
| generate_button.click( | |
| validate_and_process, | |
| inputs=[api_key, name, email, phone, education, experience, skills, social_media], | |
| outputs=[pdf_output, status, job_recommendations] | |
| ) | |
| demo.launch() | |