def main(): logging.basicConfig(level=logging.ERROR) parser = argparse.ArgumentParser( description='Extract skills from vacancy text') parser.add_argument('vacancy_file', type=str, help='vacancy text file') args = parser.parse_args() assert os.path.exists(args.vacancy_file), 'File with text does not exist' skill_db = skills_db.SkillsDB() script_dir = os.path.dirname(os.path.realpath(__file__)) skill_db.load(os.path.join(script_dir, os.pardir, 'database')) vacancy_text = get_text(args.vacancy_file) matched_skills = [] for skill in skill_db.skills: for syn in skill.get_synonims(): if text_contains(vacancy_text, syn): logging.debug('Matched %s by "%s"' % (skill, syn)) matched_skills += [skill] break print('\n'.join((str(x.name) for x in matched_skills)))
def test_unconnected_nodes(self): db_obj = skills_db.SkillsDB() self.assertEqual(db_obj.graph.number_of_nodes(), 1) # Only matcher for skill in ['C++', 'C#', 'C']: db_obj.create_skill(skill) self.assertEqual(db_obj.graph.number_of_nodes(), 4)
def main(): logging.basicConfig(level=logging.INFO) skill_db = skills_db.SkillsDB() script_dir = os.path.dirname(os.path.realpath(__file__)) skill_db.load(os.path.join(script_dir, os.pardir, 'database')) plt.figure(figsize=(20, 20)) res = nx.draw_networkx(skill_db.graph) plt.savefig("skills.pdf")
def main(): logging.basicConfig(level=logging.INFO) parser = argparse.ArgumentParser(description='Compile CV into PDF file.') parser.add_argument('--input_dir', type=str, default='/input', help='input profile directory') parser.add_argument('--paper_size', type=str, default='a4', choices=['a4', 'a5'], help='Paper size') add_bool_arg(parser, 'watermark', True) args = parser.parse_args() # Check necessary paths exist assert os.path.exists( args.input_dir), 'Input directory "%s" does not exist' % args.input_dir out_dir = os.path.abspath(os.path.join('..', 'out')) assert os.path.exists( out_dir), 'Output directory "%s" does not exist' % out_dir # Load input data skill_db = skills_db.SkillsDB() skill_db.load(os.path.join('..', 'database')) profile = EmployeeProfile(skill_db) profile.load(args.input_dir) profile.compress() with tempfile.TemporaryDirectory() as tmp_dir: tmp_dir = os.path.join('..', 'tmp') # Generate watermark qr_code qr_path = os.path.join(tmp_dir, 'watermark.svg') print_qr_code(qr_path) # Generate tex files rc_dirs = [ os.path.join('..', 'resources'), os.path.join(args.input_dir), tmp_dir ] # tex_printer = TexClassicPrinter(tmp_dir, rc_dirs) tex_printer = TexCardsPrinter(tmp_dir, rc_dirs) tex_printer.paperSize = args.paper_size tex_printer.enableWatermark = args.watermark tex_printer.print_to(profile, 'main.tex') # Copy static resources for file in glob.glob(r'../resources/styles/*.*') + glob.glob( r'../resources/fonts/*.*'): shutil.copy(file, tmp_dir) # Compile PDF call_system('cd %s && xelatex %s main.tex %s' % (tmp_dir, ' '.join(LATEX_PARAMS), LATEX_OUTPUT)) # Move result to output shutil.copy( os.path.join(tmp_dir, 'main.pdf'), os.path.join(out_dir, '%s_CV.pdf' % to_file_name(profile.personal['name']))) with LetterPrinter(tmp_dir, rc_dirs, 'cover_letter.tex') as printer: printer.print(profile) call_system('cd %s && xelatex %s cover_letter.tex %s' % (tmp_dir, ' '.join(LATEX_PARAMS), LATEX_OUTPUT)) shutil.copy( os.path.join(tmp_dir, 'cover_letter.pdf'), os.path.join( out_dir, '%s_letter.pdf' % to_file_name(profile.personal['name'])))
def main(): logging.basicConfig(level=logging.INFO) parser = argparse.ArgumentParser( description='Compile CV projection for given vacancy') parser.add_argument('input_dir', type=str, default='../sample_input', help='input profile directory') parser.add_argument('skills', type=str, help='skills text file') args = parser.parse_args() skill_db = skills_db.SkillsDB() script_dir = os.path.dirname(os.path.realpath(__file__)) skill_db.load(os.path.join(script_dir, os.pardir, 'database')) profile = EmployeeProfile(skill_db) profile.load(args.input_dir) matched_skills = [ skill_db.find_skill(x) for x in get_text(args.skills).strip().split('\n') ] logging.info('Matching with skills: %s' % matched_skills) for skill in matched_skills: skill_db.connect_to_matcher(skill) vacancy_skill_count = len(matched_skills) # Compute skill relevance logging.info('Skill Relevances:') skill_relevance = {} for skill_rec in profile.skillRecords: skill_ref = skill_rec.skill # print('%s' % skill_ref) relevance = skill_db.get_relevance(skill_ref) skill_relevance[skill_ref] = relevance skill_rec.relevance = relevance if relevance: logging.info('::: %s: %f' % (skill_ref.name, relevance)) # Compute tasks and project relevances for project in profile.projects: logging.info('Checking tasks for "%s" project:' % project.name) for task in project.tasks: task_assesment = task_relevance(task, skill_relevance, skill_db, vacancy_skill_count) task.relevance = task_assesment logging.info('::: %s -> %f' % (task, task.relevance)) proj_assesment = project_relevance(project) project.relevance = proj_assesment # Compute employments relevances logging.info('Employments relevance:') for employment in profile.employments: employment.relevance = employment_relevance(employment) logging.info('::: %s -> %f' % (employment.name, employment.relevance)) # Serialize to different folder cprsr = Compressor() relevant_profile = cprsr.create_relevant_projection(profile, 0.07) logging.info('Project relevance:') for prj in relevant_profile.projects: logging.info('===Relevance for %s: %f' % (prj, prj.relevance)) relevant_profile.save_to('profile.analysed')