From 9b33d97a11ede87bd4c98f1943a6b45227d4b1c2 Mon Sep 17 00:00:00 2001 From: Saimon Tsegai <85457358+49Simon@users.noreply.github.com> Date: Tue, 19 Nov 2024 03:20:40 -0500 Subject: [PATCH 1/2] fix: prevent failed applications from saved in success.json --- src/ai_hawk/job_manager.py | 10 ++++++---- src/ai_hawk/linkedIn_easy_applier.py | 11 +++++++---- 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/src/ai_hawk/job_manager.py b/src/ai_hawk/job_manager.py index a9be82a4..98ecec95 100644 --- a/src/ai_hawk/job_manager.py +++ b/src/ai_hawk/job_manager.py @@ -4,7 +4,6 @@ import time from itertools import product from pathlib import Path -from turtle import color from inputimeout import inputimeout, TimeoutOccurred from selenium.common.exceptions import NoSuchElementException @@ -388,9 +387,12 @@ def apply_jobs(self): continue try: if job.apply_method not in {"Continue", "Applied", "Apply"}: - self.easy_applier_component.job_apply(job) - self.write_to_file(job, "success") - logger.debug(f"Applied to job: {job.title} at {job.company}") + if self.easy_applier_component.job_apply(job): + self.write_to_file(job, "success") + logger.debug(f"Applied to job: {job.title} at {job.company}") + else: + self.write_to_file(job, "failed", "LLM scored your profile and found the role unsuitable for you.") + logger.debug(f"Failed to apply for {job.title} at {job.company}") except Exception as e: logger.error(f"Failed to apply for {job.title} at {job.company}: {e}",exc_info=True) self.write_to_file(job, "failed", f"Application error: {str(e)}") diff --git a/src/ai_hawk/linkedIn_easy_applier.py b/src/ai_hawk/linkedIn_easy_applier.py index f0fea7ab..394cc55b 100644 --- a/src/ai_hawk/linkedIn_easy_applier.py +++ b/src/ai_hawk/linkedIn_easy_applier.py @@ -107,13 +107,15 @@ def apply_to_job(self, job: Job) -> None: """ logger.debug(f"Applying to job: {job}") try: - self.job_apply(job) - logger.info(f"Successfully applied to job: {job.title}") + if self.job_apply(job): + logger.info(f"Successfully applied to job: {job.title}") + else: + logger.info(f"Failed to apply to job: {job.title}") except Exception as e: logger.error(f"Failed to apply to job: {job.title}, error: {str(e)}") raise e - def job_apply(self, job: Job): + def job_apply(self, job: Job) -> bool: logger.debug(f"Starting job application for job: {job}") job_context = JobContext() job_context.job = job @@ -157,7 +159,7 @@ def job_apply(self, job: Job): # Todo: add this job to skip list with it's reason if not self.gpt_answerer.is_job_suitable(): - return + return False logger.debug("Attempting to click 'Easy Apply' button") actions = ActionChains(self.driver) @@ -168,6 +170,7 @@ def job_apply(self, job: Job): self._fill_application_form(job_context) logger.debug(f"Job application process completed successfully for job: {job}") + return True except Exception as e: tb_str = traceback.format_exc() From 6ad0119b3ab677fe62f3a143198e1aa4088b6f2a Mon Sep 17 00:00:00 2001 From: Saimon Tsegai <85457358+49Simon@users.noreply.github.com> Date: Mon, 25 Nov 2024 00:03:13 -0500 Subject: [PATCH 2/2] chore: changed logic control to use try/except blocks as requested --- src/ai_hawk/job_manager.py | 15 ++++++++------- src/ai_hawk/linkedIn_easy_applier.py | 12 +++++------- src/custom_exception.py | 4 ++++ 3 files changed, 17 insertions(+), 14 deletions(-) create mode 100644 src/custom_exception.py diff --git a/src/ai_hawk/job_manager.py b/src/ai_hawk/job_manager.py index 8d3c9776..c9a93eb6 100644 --- a/src/ai_hawk/job_manager.py +++ b/src/ai_hawk/job_manager.py @@ -4,7 +4,6 @@ import time from itertools import product from pathlib import Path -from turtle import color from datetime import datetime from inputimeout import inputimeout, TimeoutOccurred @@ -14,6 +13,7 @@ from ai_hawk.linkedIn_easy_applier import AIHawkEasyApplier from config import JOB_MAX_APPLICATIONS, JOB_MIN_APPLICATIONS, MINIMUM_WAIT_TIME_IN_SECONDS +from src.custom_exception import JobNotSuitableException from src.job import Job from src.logging import logger @@ -409,12 +409,13 @@ def apply_jobs(self): try: if job.apply_method not in {"Continue", "Applied", "Apply"}: - if self.easy_applier_component.job_apply(job): - self.write_to_file(job, "success") - logger.debug(f"Applied to job: {job.title} at {job.company}") - else: - self.write_to_file(job, "failed", "LLM scored your profile and found the role unsuitable for you.") - logger.debug(f"Failed to apply for {job.title} at {job.company}") + self.easy_applier_component.job_apply(job) + self.write_to_file(job, "success") + logger.debug(f"Applied to job: {job.title} at {job.company}") + except JobNotSuitableException as e: + logger.debug(f"Job not suitable for application: {job.title} at {job.company}") + self.write_to_file(job, "skipped", str(e)) + continue except Exception as e: logger.error(f"Failed to apply for {job.title} at {job.company}: {e}",exc_info=True) self.write_to_file(job, "failed", f"Application error: {str(e)}") diff --git a/src/ai_hawk/linkedIn_easy_applier.py b/src/ai_hawk/linkedIn_easy_applier.py index 394cc55b..7f980106 100644 --- a/src/ai_hawk/linkedIn_easy_applier.py +++ b/src/ai_hawk/linkedIn_easy_applier.py @@ -22,6 +22,7 @@ from jobContext import JobContext from job_application import JobApplication from job_application_saver import ApplicationSaver +from src.custom_exception import JobNotSuitableException import src.utils as utils from src.logging import logger from src.job import Job @@ -107,15 +108,13 @@ def apply_to_job(self, job: Job) -> None: """ logger.debug(f"Applying to job: {job}") try: - if self.job_apply(job): - logger.info(f"Successfully applied to job: {job.title}") - else: - logger.info(f"Failed to apply to job: {job.title}") + self.job_apply(job) + logger.info(f"Successfully applied to job: {job.title}") except Exception as e: logger.error(f"Failed to apply to job: {job.title}, error: {str(e)}") raise e - def job_apply(self, job: Job) -> bool: + def job_apply(self, job: Job): logger.debug(f"Starting job application for job: {job}") job_context = JobContext() job_context.job = job @@ -159,7 +158,7 @@ def job_apply(self, job: Job) -> bool: # Todo: add this job to skip list with it's reason if not self.gpt_answerer.is_job_suitable(): - return False + raise JobNotSuitableException("LLM score determined this job is not suitable for you") logger.debug("Attempting to click 'Easy Apply' button") actions = ActionChains(self.driver) @@ -170,7 +169,6 @@ def job_apply(self, job: Job) -> bool: self._fill_application_form(job_context) logger.debug(f"Job application process completed successfully for job: {job}") - return True except Exception as e: tb_str = traceback.format_exc() diff --git a/src/custom_exception.py b/src/custom_exception.py new file mode 100644 index 00000000..aa9a147d --- /dev/null +++ b/src/custom_exception.py @@ -0,0 +1,4 @@ +class JobNotSuitableException(Exception): + def __init__(self, message): + self.message = message + super().__init__(self.message)