diff --git a/config.py b/config.py
index a395425..bd7bb10 100644
--- a/config.py
+++ b/config.py
@@ -5,4 +5,7 @@
LOG_TO_FILE = True
LOG_TO_CONSOLE = True
LOG_FILE = "log/app.log"
-LOG_FORMAT = "{time:YYYY-MM-DD HH:mm:ss.SSS} | {level: <8} | {name}:{function}:{line} - {message}"
\ No newline at end of file
+LOG_FORMAT = "{time:YYYY-MM-DD HH:mm:ss.SSS} | {level: <8} | {name}:{function}:{line} - {message}"
+APPLICANT_NAME = "John Doe"
+TEX_FILE_NAME = "resume"
+TAR_FOLDER_NAME = "resume"
\ No newline at end of file
diff --git a/envs.py b/envs.py
index e757f3e..93c657c 100644
--- a/envs.py
+++ b/envs.py
@@ -8,6 +8,5 @@
GMAIL_APP_PASSWORD = getenv("GMAIL_APP_PASSWORD") # Put your gmail app password here
ADD_GDRIVE_ZAP_URL = getenv("ADD_GDRIVE_ZAP_URL") # Put zappier webhook workflow here, This webhook uploads the file to GDrive
LaTeX_COMPILER_URL_TEXT = "https://texlive2020.latexonline.cc/compile?command=pdflatex&text="
-# LaTeX_COMPILER_URL = "https://latexonline.cc/compile?command=xelatex&text="
-LaTeX_COMPILER_URL_DATA = "https://latexonline.cc/data?target=resume/resume.tex&force=true&command=pdflatex"
+LaTeX_COMPILER_URL_DATA = """https://latexonline.cc/data?target={tex_folder_path}&force=true&command=pdflatex"""
diff --git a/main.py b/main.py
index 0df78c7..1ebbd1d 100644
--- a/main.py
+++ b/main.py
@@ -7,6 +7,7 @@
from templates import john_doe_resume
from log import logger
+from config import APPLICANT_NAME
app = FastAPI()
@@ -43,11 +44,15 @@ def generate_tailored_latex_resume_save(job_description: str, resume: str = john
Gets resume and job description in plain text and saves tailored resume
"""
tailored_plain_resume = generate_tailored_plain_resume(resume, job_description, model, template)
- latex_compiler_reponse, _ = openai_wrapper.covert_plain_resume_to_latex(tailored_plain_resume, model, template)
company_name = openai_wrapper.ai_prompt(f"Give the name of the company that this job description is for. As the output just give the name, nothing else. Job description: {job_description}") # Since this is a simple task we use the cheapest ai
- with open(f'./CVs/{company_name}_cv.pdf', 'wb') as f:
+ # Make a folder for each job description to save PDF, .tex, and .tar files of tailored resume.
+ os.makedirs(f'./CVs/{company_name}',exist_ok=True)
+ latex_compiler_reponse, _ = openai_wrapper.covert_plain_resume_to_latex(company_name, tailored_plain_resume, model, template)
+ # Path to save pdf file of tailored resume
+ pdf_path = f'./CVs/{company_name}/{APPLICANT_NAME}_cv.pdf'
+ with open(pdf_path, 'wb') as f:
f.write(latex_compiler_reponse.content)
- logger.debug(f"Generated resume saved at here: ./CVs/{company_name}_cv.pdf")
- return {"success": f"Generated resume saved at here: ./CVs/{company_name}_cv.pdf",
- "path": os.path.abspath(f"./CVs/{company_name}_cv.pdf")
+ logger.debug(f"Generated resume saved at here: {pdf_path}")
+ return {"success": f"Generated resume saved at here: {pdf_path}",
+ "path": os.path.abspath(pdf_path)
}
diff --git a/openai_wrapper.py b/openai_wrapper.py
index 6afae4c..58c830c 100644
--- a/openai_wrapper.py
+++ b/openai_wrapper.py
@@ -11,6 +11,7 @@
from templates import TemplateName, Template_Details
import os
from utils import generate_tex_and_tar
+from config import TEX_FILE_NAME, TAR_FOLDER_NAME
client = OpenAI(api_key=OPEN_AI_KEY) # we recommend using python-dotenv to add OPENAI_API_KEY="My API Key" to your .env file so that your API Key is not stored in source control.
@@ -96,7 +97,7 @@ def create_tailored_plain_resume(resume: str, job_description: str, model=AIMode
logger.debug(f"The tailored CV plain text is: {tailored_resume}")
return tailored_resume
-def covert_plain_resume_to_latex(plain_resume: str, model=AIModel.gpt_4o_mini, template=TemplateName.Blue_Modern_CV):
+def covert_plain_resume_to_latex(company_name: str, plain_resume: str, model=AIModel.gpt_4o_mini, template=TemplateName.Blue_Modern_CV):
messages=[
{"role": "system", "content": "You are a helpful assistant."},
@@ -112,11 +113,10 @@ def covert_plain_resume_to_latex(plain_resume: str, model=AIModel.gpt_4o_mini, t
tailored_resume = json.loads(completion.choices[0].message.content)["tailored_resume"]
logger.debug(f"The tailored CV Latex code in iteration {i} is: {tailored_resume}")
trimed_tailored_resume = tailored_resume[tailored_resume.find(r"\documentclass"):tailored_resume.rfind(r"\end{document}")+len(r"\end{document}")] # removes possible extra things that AI adds
- file_name, folder_name = "resume", "resume"
- created_tar_file = generate_tex_and_tar(trimed_tailored_resume, f"{file_name}", f"{folder_name}")
+ created_tar_file = generate_tex_and_tar(company_name, trimed_tailored_resume, TEX_FILE_NAME, TAR_FOLDER_NAME)
with open(created_tar_file, 'rb') as tar_file:
files = {'file':(os.path.basename(created_tar_file), tar_file, "application/x-tar")}
- latex_compiler_response = requests.post(url=LaTeX_COMPILER_URL_DATA, files= files)
+ latex_compiler_response = requests.post(url=LaTeX_COMPILER_URL_DATA.format(tex_folder_path=f"{TAR_FOLDER_NAME}/{TEX_FILE_NAME}.tex"), files= files)
logger.debug(f"Request url to the LaTeX compiler is: {latex_compiler_response.url}")
if not b"error: " in latex_compiler_response.content: # there is no error in the compiled code
return latex_compiler_response, trimed_tailored_resume
diff --git a/utils.py b/utils.py
index 304bb70..1edd09b 100644
--- a/utils.py
+++ b/utils.py
@@ -2,7 +2,7 @@
import tarfile
from log import logger
-def generate_tex_and_tar(latex_content: str, file_name: str= "resume", folder_name: str="resume"):
+def generate_tex_and_tar(company_name: str, latex_content: str, file_name: str= "resume", folder_name: str="resume"):
"""
Creates a folder, generates a .tex file inside it, and compresses the folder into a .tar file.
@@ -12,11 +12,17 @@ def generate_tex_and_tar(latex_content: str, file_name: str= "resume", folder_na
folder_name (str): The name of the folder to create.
"""
try:
+ # Path of a folder for saving .tex files
+ resume_folder_path = f'./CVs/{company_name}/{folder_name}'
+
+ # Path of .tar file
+ tar_path = f'./CVs/{company_name}'
+
# Ensure the folder exists
- os.makedirs(folder_name, exist_ok=True)
+ os.makedirs(resume_folder_path, exist_ok=True)
# Full path for the .tex file
- tex_file_path = os.path.join(folder_name, file_name)
+ tex_file_path = os.path.join(resume_folder_path, file_name)
# Ensure the file name ends with .tex
if not tex_file_path.endswith(".tex"):
@@ -30,11 +36,10 @@ def generate_tex_and_tar(latex_content: str, file_name: str= "resume", folder_na
# Compress the folder into a .tar file
tar_file_name = f"{folder_name}.tar"
- with tarfile.open(tar_file_name, "w") as tar:
- tar.add(folder_name, arcname=os.path.basename(folder_name))
-
- logger.debug(f"Folder '{folder_name}' compressed into '{tar_file_name}'.")
-
- return (os.path.relpath(tar_file_name))
+ # Full path of .tar folder
+ tar_folder_path = os.path.join(tar_path, tar_file_name)
+ with tarfile.open(tar_folder_path, "w") as tar:
+ tar.add(resume_folder_path, arcname='resume')
+ return (os.path.relpath(tar_folder_path))
except Exception as e:
logger.debug(f"An error occurred: {e}")
\ No newline at end of file