Skip to content

Commit

Permalink
Merge branch 'main' into main
Browse files Browse the repository at this point in the history
  • Loading branch information
feder-cr authored Oct 16, 2024
2 parents 98dbb5e + a11381f commit 5b55fad
Show file tree
Hide file tree
Showing 5 changed files with 31 additions and 29 deletions.
17 changes: 12 additions & 5 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -1,9 +1,16 @@
MIT License
Proprietary License for Auto Jobs Applier AIHawk

Copyright (c) 2024 feder-cr
1. Freedom to Use, Modify, and Distribute
The software may be freely used, modified, and distributed by anyone, provided that the source code remains accessible and open to the public. Any derivative work or modification may be released as open source but cannot be converted into proprietary software without prior written authorization from the original author.

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
2. Prohibition of Resale and Non-Commercial Use
The software may not be sold without explicit authorization from the original author. It is intended for non-commercial use unless specific permission for commercial use is granted.

The above copyright notice and this permission notice must be included in all copies or substantial portions of the Software.
3. Copyright
Copyright remains with the original author. Any unauthorized use will be considered a copyright infringement.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
4. Disclaimer of Warranty
This software is provided “as is,” without warranties of any kind. The author shall not be liable for any damages arising from its use.

5. Governing Law
This agreement shall be governed by the laws of Italy.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ Auto_Jobs_Applier_AIHawk steps in as a game-changing solution to these challenge

## Installation

**Confirmed succesfull runs on the following:**
**Confirmed successful runs on the following:**
- Operating Systems:
- Windows 10
- Ubuntu 22
Expand Down
4 changes: 2 additions & 2 deletions assets/resume_schema.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ personal_information:
email: {type: string, format: email}
github: {type: string, format: uri}
linkedin: {type: string, format: uri}
required: [name, surname, date_of_birth, country, city, address,zip_code, phone_prefix, phone, email]
required: [name, surname, date_of_birth, country, city, address, zip_code, phone_prefix, phone, email]

education_details:
type: array
Expand Down Expand Up @@ -130,4 +130,4 @@ work_preferences:
willing_to_complete_assessments: {type: string, enum: [Yes, No]}
willing_to_undergo_drug_tests: {type: string, enum: [Yes, No]}
willing_to_undergo_background_checks: {type: string, enum: [Yes, No]}
required: [remote_work, in_person_work, open_to_relocation, willing_to_complete_assessments, willing_to_undergo_drug_tests, willing_to_undergo_background_checks]
required: [remote_work, in_person_work, open_to_relocation, willing_to_complete_assessments, willing_to_undergo_drug_tests, willing_to_undergo_background_checks]
2 changes: 1 addition & 1 deletion data_folder/config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -47,4 +47,4 @@ job_applicants_threshold:

llm_model_type: openai
llm_model: 'gpt-4o-mini'
# llm_api_url: https://api.pawan.krd/cosmosrp/v1'
# llm_api_url: 'https://api.pawan.krd/cosmosrp/v1'
35 changes: 15 additions & 20 deletions main.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
from selenium.webdriver.chrome.service import Service as ChromeService
from webdriver_manager.chrome import ChromeDriverManager
from selenium.common.exceptions import WebDriverException
from lib_resume_builder_AIHawk import Resume,StyleManager,FacadeManager,ResumeGenerator
from lib_resume_builder_AIHawk import Resume, FacadeManager, ResumeGenerator, StyleManager
from src.utils import chrome_browser_options
from src.llm.llm_manager import GPTAnswerer
from src.aihawk_authenticator import AIHawkAuthenticator
Expand All @@ -17,8 +17,8 @@
from src.job_application_profile import JobApplicationProfile
from loguru import logger

# Suppress stderr
sys.stderr = open(os.devnull, 'w')
# Suppress stderr only during specific operations
original_stderr = sys.stderr

class ConfigError(Exception):
pass
Expand All @@ -37,8 +37,8 @@ def validate_yaml_file(yaml_path: Path) -> dict:
raise ConfigError(f"Error reading file {yaml_path}: {exc}")
except FileNotFoundError:
raise ConfigError(f"File not found: {yaml_path}")


@staticmethod
def validate_config(config_yaml_path: Path) -> dict:
parameters = ConfigValidator.validate_yaml_file(config_yaml_path)
required_keys = {
Expand Down Expand Up @@ -67,30 +67,36 @@ def validate_config(config_yaml_path: Path) -> dict:
else:
raise ConfigError(f"Invalid type for key '{key}' in config file {config_yaml_path}. Expected {expected_type}.")

# Validate experience levels, ensure they are boolean
experience_levels = ['internship', 'entry', 'associate', 'mid-senior level', 'director', 'executive']
for level in experience_levels:
if not isinstance(parameters['experienceLevel'].get(level), bool):
raise ConfigError(f"Experience level '{level}' must be a boolean in config file {config_yaml_path}")

# Validate job types, ensure they are boolean
job_types = ['full-time', 'contract', 'part-time', 'temporary', 'internship', 'other', 'volunteer']
for job_type in job_types:
if not isinstance(parameters['jobTypes'].get(job_type), bool):
raise ConfigError(f"Job type '{job_type}' must be a boolean in config file {config_yaml_path}")

# Validate date filters
date_filters = ['all time', 'month', 'week', '24 hours']
for date_filter in date_filters:
if not isinstance(parameters['date'].get(date_filter), bool):
raise ConfigError(f"Date filter '{date_filter}' must be a boolean in config file {config_yaml_path}")

# Validate positions and locations as lists of strings
if not all(isinstance(pos, str) for pos in parameters['positions']):
raise ConfigError(f"'positions' must be a list of strings in config file {config_yaml_path}")
if not all(isinstance(loc, str) for loc in parameters['locations']):
raise ConfigError(f"'locations' must be a list of strings in config file {config_yaml_path}")

# Validate distance
approved_distances = {0, 5, 10, 25, 50, 100}
if parameters['distance'] not in approved_distances:
raise ConfigError(f"Invalid distance value in config file {config_yaml_path}. Must be one of: {approved_distances}")

# Ensure blacklists are lists
for blacklist in ['companyBlacklist', 'titleBlacklist']:
if not isinstance(parameters.get(blacklist), list):
raise ConfigError(f"'{blacklist}' must be a list in config file {config_yaml_path}")
Expand All @@ -99,10 +105,8 @@ def validate_config(config_yaml_path: Path) -> dict:

return parameters



@staticmethod
def validate_secrets(secrets_yaml_path: Path) -> tuple:
def validate_secrets(secrets_yaml_path: Path) -> str:
secrets = ConfigValidator.validate_yaml_file(secrets_yaml_path)
mandatory_secrets = ['llm_api_key']

Expand All @@ -115,10 +119,6 @@ def validate_secrets(secrets_yaml_path: Path) -> tuple:
return secrets['llm_api_key']

class FileManager:
@staticmethod
def find_file(name_containing: str, with_extension: str, at_path: Path) -> Path:
return next((file for file in at_path.iterdir() if name_containing.lower() in file.name.lower() and file.suffix.lower() == with_extension.lower()), None)

@staticmethod
def validate_data_folder(app_data_folder: Path) -> tuple:
if not app_data_folder.exists() or not app_data_folder.is_dir():
Expand Down Expand Up @@ -150,7 +150,6 @@ def file_paths_to_dict(resume_file: Path | None, plain_text_resume_file: Path) -

def init_browser() -> webdriver.Chrome:
try:

options = chrome_browser_options()
service = ChromeService(ChromeDriverManager().install())
return webdriver.Chrome(service=service, options=options)
Expand All @@ -165,9 +164,9 @@ def create_and_run_bot(parameters, llm_api_key):
plain_text_resume = file.read()
resume_object = Resume(plain_text_resume)
resume_generator_manager = FacadeManager(llm_api_key, style_manager, resume_generator, resume_object, Path("data_folder/output"))
os.system('cls' if os.name == 'nt' else 'clear')

# Run the resume generator manager's functions
resume_generator_manager.choose_style()
os.system('cls' if os.name == 'nt' else 'clear')

job_application_profile_object = JobApplicationProfile(plain_text_resume)

Expand Down Expand Up @@ -211,18 +210,14 @@ def main(collect: False, resume: Path = None):
except ConfigError as ce:
logger.error(f"Configuration error: {str(ce)}")
logger.error(f"Refer to the configuration guide for troubleshooting: https://github.com/feder-cr/Auto_Jobs_Applier_AIHawk?tab=readme-ov-file#configuration {str(ce)}")

except FileNotFoundError as fnf:
logger.error(f"File not found: {str(fnf)}")
logger.error("Ensure all required files are present in the data folder.")
logger.error("Refer to the file setup guide: https://github.com/feder-cr/AIHawk_AIHawk_automatic_job_application/blob/main/readme.md#configuration")
except RuntimeError as re:

logger.error(f"Runtime error: {str(re)}")

logger.error("Refer to the configuration and troubleshooting guide: https://github.com/feder-cr/AIHawk_AIHawk_automatic_job_application/blob/main/readme.md#configuration")
except Exception as e:
logger.error(f"An unexpected error occurred: {str(e)}")
logger.error("Refer to the general troubleshooting guide: https://github.com/feder-cr/AIHawk_AIHawk_automatic_job_application/blob/main/readme.md#configuration")

if __name__ == "__main__":
main()

0 comments on commit 5b55fad

Please sign in to comment.