diff --git a/gpt.py b/gpt.py index 515a82f..368572c 100644 --- a/gpt.py +++ b/gpt.py @@ -267,9 +267,6 @@ class GPTAnswerer: Provide only the exact name of the section from the list above with no additional text. """ - - - prompt = ChatPromptTemplate.from_template(section_prompt) chain = prompt | self.llm_cheap | StrOutputParser() output = chain.invoke({"question": question}) diff --git a/linkedIn_easy_applier.py b/linkedIn_easy_applier.py index 2160f6a..759e506 100644 --- a/linkedIn_easy_applier.py +++ b/linkedIn_easy_applier.py @@ -191,7 +191,9 @@ class LinkedInEasyApplier: def _fill_additional_questions(self) -> None: form_sections = self.driver.find_elements(By.CLASS_NAME, 'jobs-easy-apply-form-section__grouping') for section in form_sections: + outer_html = section.get_attribute('outerHTML') self._process_form_section(section) + def _process_form_section(self, section: WebElement) -> None: if self._handle_terms_of_service(section): @@ -243,15 +245,18 @@ class LinkedInEasyApplier: return False def _find_and_handle_dropdown_question(self, section: WebElement) -> bool: - dropdowns = section.find_elements(By.CLASS_NAME, 'fb-dropdown__select') - if dropdowns: - dropdown = dropdowns[0] - question_text = section.text.lower() - select = Select(dropdown) - answer = self.gpt_answerer.answer_question_from_options(question_text, [option.text.lower() for option in select.options]) - self._select_dropdown_option(select, answer) - return True - return False + try: + question = section.find_element(By.CLASS_NAME, 'jobs-easy-apply-form-element') + question_text = question.find_element(By.TAG_NAME, 'label').text.lower() + dropdown = question.find_element(By.TAG_NAME, 'select') + if dropdown: + select = Select(dropdown) + options = [option.text for option in select.options] + answer = self.gpt_answerer.answer_question_from_options(question_text, options) + self._select_dropdown_option(dropdown, answer) + return True + except Exception: + return False def _is_numeric_field(self, field: WebElement) -> bool: field_type = field.get_attribute('type').lower() @@ -270,8 +275,6 @@ class LinkedInEasyApplier: radio.click() break - def _select_dropdown_option(self, select: Select, answer: str) -> None: - for option in select.options: - if option.text.lower() == answer.lower(): - select.select_by_visible_text(option.text) - break + def _select_dropdown_option(self, element: WebElement, text: str) -> None: + select = Select(element) + select.select_by_visible_text(text) diff --git a/linkedIn_job_manager.py b/linkedIn_job_manager.py index b25bae0..2a0bee9 100644 --- a/linkedIn_job_manager.py +++ b/linkedIn_job_manager.py @@ -153,8 +153,8 @@ class LinkedInJobManager: "pdf_path": job.pdf_path } file_path = self.output_file_directory / f"{file_name}.json" - file_path = file_path.as_posix() if not file_path.exists(): + job.pdf_path = file_path.as_posix() with open(file_path, 'w', encoding='utf-8') as f: json.dump([data], f, indent=4) else: diff --git a/main.py b/main.py index 0253c97..38d99a1 100644 --- a/main.py +++ b/main.py @@ -149,6 +149,12 @@ def init_browser() -> webdriver.Chrome: def create_and_run_bot(email: str, password: str, parameters: dict, openai_api_key: str): try: + + style_manager = StyleManager() + resume_generator = ResumeGenerator() + resume_generator_manager = FacadeManager(openai_api_key, style_manager, resume_generator, resume_object, Path("data_folder/output")) + + browser = init_browser() login_component = LinkedInAuthenticator(browser) @@ -161,13 +167,7 @@ def create_and_run_bot(email: str, password: str, parameters: dict, openai_api_k resume_object = Resume(plain_text_resume) job_application_profile_object = JobApplicationProfile(plain_text_resume) - style_manager = StyleManager() - resume_generator = ResumeGenerator() - resume_generator_manager = FacadeManager(openai_api_key, style_manager, resume_generator, resume_object, Path("data_folder/output")) - - os.system('cls' if os.name == 'nt' else 'clear') - resume_generator_manager.choose_style() - + bot = LinkedInBotFacade(login_component, apply_component) bot.set_secrets(email, password) bot.set_job_application_profile_and_resume(job_application_profile_object, resume_object)