From 9b02b05774189b3d6bdd703679e2adad1c5f4094 Mon Sep 17 00:00:00 2001 From: Umair Jibran Date: Wed, 16 Oct 2024 00:26:33 +0500 Subject: [PATCH 1/4] add support for saving config --- addon/src/configure.html | 56 ++++++++++++++++++++++++++++++++++++++++ addon/src/configure.js | 19 ++++++++++++++ 2 files changed, 75 insertions(+) create mode 100644 addon/src/configure.html create mode 100644 addon/src/configure.js diff --git a/addon/src/configure.html b/addon/src/configure.html new file mode 100644 index 0000000..1353031 --- /dev/null +++ b/addon/src/configure.html @@ -0,0 +1,56 @@ + + + + + + Configure - Waltzes + + + + + +
+

Configure Waltzes for yourself!

+ +
+ + e.g. http://localhost:5000 (default) + +
+
+ + +
+ +
+ + + + diff --git a/addon/src/configure.js b/addon/src/configure.js new file mode 100644 index 0000000..7021b76 --- /dev/null +++ b/addon/src/configure.js @@ -0,0 +1,19 @@ +const saveButton = document.getElementById("save"); + +saveButton.addEventListener("click", async function () { + const host = document.getElementById("host").value; + const openAiKey = document.getElementById("openAiKey").value; + localStorage.setItem("host", host); + localStorage.setItem("openAiKey", openAiKey); + location.reload(); +}); + +const host = localStorage.getItem("host"); +if (host) { + document.getElementById("host").value = host; +} + +const openAiKey = localStorage.getItem("openAiKey"); +if (openAiKey) { + document.getElementById("openAiKey").value = openAiKey; +} From 7b6d5c60210e1330543c7373392cdf2e55b3d70f Mon Sep 17 00:00:00 2001 From: Umair Jibran Date: Wed, 16 Oct 2024 00:26:47 +0500 Subject: [PATCH 2/4] use config provided by the user --- addon/src/main.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/addon/src/main.js b/addon/src/main.js index b004c31..f409b09 100644 --- a/addon/src/main.js +++ b/addon/src/main.js @@ -56,8 +56,8 @@ function showCoverLetter(coverLetter) { generateCLButton.addEventListener("click", async function () { const loader = document.getElementById("loader"); const currentTab = await getCurrentTab(); - // TODO: Fetch base url from local storage (dynamic url based on user's input) - const baseUrl = "http:/localhost:5000/job-details"; + const savedHost = localStorage.getItem("host") || "http://localhost:5000"; + const baseUrl = [savedHost, "job-details"].join("/"); let jobBoard = ""; if (currentTab.url.includes("greenhouse")) jobBoard = "greenhouse"; From 0ea72dc9a3f6e74a65e65c1790d5f0f34aff625e Mon Sep 17 00:00:00 2001 From: Umair Jibran Date: Wed, 16 Oct 2024 00:35:14 +0500 Subject: [PATCH 3/4] handle incoming API key from extension --- addon/src/main.js | 4 +++- python/app.py | 3 ++- python/services/openai.py | 7 +++++-- 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/addon/src/main.js b/addon/src/main.js index f409b09..1965495 100644 --- a/addon/src/main.js +++ b/addon/src/main.js @@ -65,7 +65,9 @@ generateCLButton.addEventListener("click", async function () { notSupported(currentTab.title, currentTab.url); return; } - const url = `${baseUrl}/${jobBoard}?url=${currentTab.url}`; + const openAiKey = localStorage.getItem("openAiKey"); + let url = `${baseUrl}/${jobBoard}?url=${currentTab.url}`; + if (openAiKey) url += `&openAiKey=${openAiKey}`; generateCLButton.disabled = true; loader.hidden = false; diff --git a/python/app.py b/python/app.py index 6087e30..e849cc5 100644 --- a/python/app.py +++ b/python/app.py @@ -24,6 +24,7 @@ def test(): @app.route("/job-details/", methods=["GET"]) def get_job_details(job_board): job_url = request.args.get("url") + openai_api_key = request.args.get("openAiKey") job_details = "" if job_url is None: @@ -35,7 +36,7 @@ def get_job_details(job_board): resume_vectors, resume_segments = vectorize_resume() best_match_section = get_best_match_from_resume(job_details, resume_vectors, resume_segments) - response = generate_cover_letter(job_details, best_match_section) + response = generate_cover_letter(job_details, best_match_section, openai_api_key) return {"coverLetter": response, "bestMatchSection": best_match_section} diff --git a/python/services/openai.py b/python/services/openai.py index 10ed51e..d4c8e5a 100644 --- a/python/services/openai.py +++ b/python/services/openai.py @@ -1,10 +1,13 @@ import os from openai import OpenAI -client = OpenAI(api_key=os.environ.get("OPENAI_API_KEY")) -def generate_cover_letter(raw_job_details, best_match_section): +def generate_cover_letter(raw_job_details, best_match_section,api_key): + if api_key is None: + api_key = os.environ.get("OPENAI_API_KEY") + print("OPEN AI KEY => ", api_key) + client = OpenAI(api_key=api_key) prompt = f""" Generate a compelling cover letter based on the provided resume and job details. Analyze the resume to identify relevant work experience, skills, and achievements that align with the job requirements. Use this information to craft a brief, enthusiastic letter that showcases the candidate's qualifications and passion for the role. From 2eb209a8fa883bb78b2d98d722fd02b537a22543 Mon Sep 17 00:00:00 2001 From: Umair Jibran Date: Wed, 16 Oct 2024 00:38:09 +0500 Subject: [PATCH 4/4] Update README.md --- README.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/README.md b/README.md index 0755c9d..a98653a 100644 --- a/README.md +++ b/README.md @@ -39,6 +39,12 @@ Waltzes is a project designed to generate personalized cover letters based on jo 1. Open Firefox and navigate to `about:debugging#/runtime/this-firefox`. 2. Click "Load Temporary Add-on" and select any file in the `addon` directory. +3. Configure the extension: + - Copy the extension ID (e.g., `6546988c-c591-4bce-8e38-357819650252`). + - Go to the following url `moz-extension://{YOUR_TEMPORARY_EXTENSION_ID}/src/configure.html` + - Provide your OpenAI API key and the Flask server URL. + - Click "Save". + ### Flask Server Setup 1. Navigate to the `python` directory: