def test_resume_basic_user_info_extraction(self): first_name, last_name, phone_number, email = get_basics(settings.TESTDATA_DIRS + 'resume_extraction/ideal_resume_data.txt') first_name_2, last_name_2, phone_number_2, email_2 = get_basics(settings.TESTDATA_DIRS + 'resume_extraction/resume_without_name.txt') first_name_3, last_name_3, phone_number_3, email_3 = get_basics(settings.TESTDATA_DIRS + 'resume_extraction/resume_without_email.txt') first_name_4, last_name_4, phone_number_4, email_4 = get_basics(settings.TESTDATA_DIRS + 'resume_extraction/resume_with_11_digit_phone_number.txt') first_name_5, last_name_5, phone_number_5, email_5 = get_basics(settings.TESTDATA_DIRS + 'resume_extraction/resume_with_wrong_email.txt') self.assertNotEqual(email_5, '*****@*****.**') self.assertNotEqual(email_5, '*****@*****.**') self.assertEqual(email_5, '') self.assertIn(first_name_4, 'anubhav') self.assertIn(last_name_4, 'singh') self.assertNotEqual(phone_number_4, '+916976318701') self.assertIn(email_4, '*****@*****.**') self.assertEqual(first_name_3, 'anubhav') self.assertEqual(last_name_3, 'singh') self.assertEqual(phone_number_3, '+917697631870') self.assertEqual(email_3, '') self.assertEqual(first_name, 'anubhav') self.assertEqual(last_name, 'singh') self.assertEqual(phone_number, '+917697631870') self.assertEqual(email, '*****@*****.**') self.assertEqual(first_name_2, '') self.assertEqual(last_name_2, '') self.assertEqual(phone_number_2, '+917697631870') self.assertEqual(email_2, '*****@*****.**')
def post(self, request, *args, **kwargs): form = UploadResumeForm(request.POST, request.FILES) if not form.is_valid(): return Response(form.errors) f = request.FILES.get('file', None) if not f: return Response( {'message': 'Cannot proceed further. File is missing.'}, status=status.HTTP_400_BAD_REQUEST) # Basic file storage on a local filesystem. fs = FileSystemStorage() # Save file. filename = fs.save("temp+" + f.name.lower(), f) # Absolute path to the directory that will hold the files. path = fs.location + '/' + filename # Get basic resume details. first_name, last_name, phone_number, email = get_basics(path) # Delete file as it was temporary. fs.delete(filename) return Response( { 'email': email, 'last_name': last_name, 'first_name': first_name, 'phone_number': phone_number, 'status': 'Successfully parsed.' }, status=status.HTTP_200_OK)
def test_get_basics(self): first_name, last_name, phone_number, email = get_basics(settings.TESTDATA_DIRS + 'view_tests/nda.pdf') self.assertEqual(first_name, 'anubhav') self.assertEqual(phone_number, '+917697631870') self.assertEqual(email, '*****@*****.**') self.assertEqual(last_name, 'singh')
def test_website_score(self): urls = get_urls(self.test_website_score) category_urls = url_categories(urls) # self.assertEqual('http://imgur.com/', category_urls['others'][0]) url_response = get_url_response(category_urls) resume = Resume.objects.create(parse_status=0) for item in url_response: resume_urls = Url.objects.filter(url=item['name']) if resume_urls.exists(): resume_url = resume_urls[0] resume_url.category = item['type'] resume_url.save() else: resume_url = Url.objects.create(url=item['name'], category=item['type']) resume.urls.add(resume_url) first_name, last_name, phone_number, email = get_basics( settings.TESTDATA_DIRS + 'score_calculation/test_website_score.txt') self.assertEqual(email, '*****@*****.**') apply_website_score = mock.Mock(return_value=(None, None, None)) (website_activity_score, website_reputation_score, website_contribution_score) = apply_website_score( category_urls, resume, email) self.assertEqual(website_activity_score, None) self.assertEqual(website_contribution_score, None) self.assertEqual(website_reputation_score, None)
def post(self, request, *args, **kwargs): form = UploadResumeForm(request.POST, request.FILES) if form.is_valid(): get_file = request.FILES['file'] file_name = get_file.name.lower() name, ext = os.path.splitext(file_name) uploaded_file_name = default_storage.save( "%s" % uuid4() + ext, ContentFile(get_file.read())) path = default_storage.open(uploaded_file_name).name first_name, last_name, phone_number, email = get_basics(path) return Response( { 'status': 'Successfully Parsed', 'first_name': first_name, 'last_name': last_name, 'phone_number': phone_number, 'email': email }, status=status.HTTP_200_OK) return JsonResponse(form.errors)
def test_itunes_store_score(self): urls = get_urls(self.test_itunes_score) category_urls = url_categories(urls) url_response = get_url_response(category_urls) self.assertIn( 'https://itunes.apple.com/in/app/whatsapp-messenger/id310633997?mt=8', category_urls['apps']) first_name, last_name, email, phone_number = get_basics( settings.TESTDATA_DIRS + 'score_calculation/test_itunes_score.txt') self.assertEqual(first_name, 'anubhav') resume = Resume.objects.create(parse_status=0) for item in url_response: resume_urls = Url.objects.filter(url=item['name']) if resume_urls.exists(): resume_url = resume_urls[0] resume_url.category = item['type'] resume_url.save() else: resume_url = Url.objects.create(url=item['name'], category=item['type']) resume.urls.add(resume_url) calculate_average_mobile_contrib_score = mock.Mock(return_value=(.3, .7, .05)) apply_itunes_score(category_urls, first_name, resume) avg_mobile_apps_activity_score, avg_mobile_apps_reputation_score, avg_mobile_apps_contribution_score = calculate_average_mobile_contrib_score( resume) self.assertEqual(avg_mobile_apps_contribution_score, .05) self.assertEqual(avg_mobile_apps_reputation_score, .7) self.assertEqual(avg_mobile_apps_activity_score, .3)
def parse_resume(path, text, resume_id, skills, file_name, hash_value, callback_client=False): content_list = text.lower().split() # Get resume instance. resume_details = Resume.objects.get(id=resume_id) # Categorising urls categories_url = url_categories(get_urls(text)) # Getting custom url response using get_url_response url_response = get_url_response(categories_url) # Get basic details. first_name, last_name, phone_number, email = get_basics(path) # Consider basic details only if resume_details for the same is non-nil. if resume_details.email: email = resume_details.email if resume_details.first_name: first_name = resume_details.first_name if resume_details.last_name: last_name = resume_details.last_name if resume_details.phone_number: phone_number = resume_details.phone_number # Url Instance for item in url_response: resume_urls = Url.objects.filter(url=item['name']) if resume_urls.exists(): resume_url = resume_urls[0] resume_url.category = item['type'] resume_url.save() else: resume_url = Url.objects.create(url=item['name'], category=item['type']) resume_details.urls.add(resume_url) # Skills Matching Score (skill_match_score, skills_matched, skills_not_matched) = get_skill_matching_score(skills, text) # Definition of scores github_contribution_score = 0 github_activity_score = 0 github_reputation_score = 0 bit_bucket_contribution_score = 0 bit_bucket_activity_score = 0 bit_bucket_reputation_score = 0 stackoverflow_contribution_score = 0 stackoverflow_reputation_score = 0 stackoverflow_activity_score = 0 # StackOverflow Score stackoverflow_user_id = get_stackoverflow_userid(text) if stackoverflow_user_id: (stackoverflow_activity_score, stackoverflow_reputation_score, stackoverflow_contribution_score) = apply_stackoverflow_score( stackoverflow_user_id, resume_details) # GitHub Score github_username = get_github_username(text) if github_username: (github_activity_score, github_reputation_score, github_contribution_score) = apply_github_score( github_username, resume_details) # Blog score apply_blog_score(categories_url, resume_details) # BitBucket Score contribution_urls = categories_url['contributions'] bit_bucket_url = get_bit_bucket_url(contribution_urls) if bit_bucket_url == 'No Url Found' or bit_bucket_url is None: pass else: bit_bucket_user_name = get_bitbucket_username(bit_bucket_url) (bit_bucket_activity_score, bit_bucket_reputation_score, bit_bucket_contribution_score) = apply_bitbucket_score( bit_bucket_user_name, resume_details) # MobileApp Database saving and score calculations # Play Store - Total Score apply_play_store_app_score(categories_url, resume_details) # ITunes - Total Score apply_itunes_score(categories_url, first_name, resume_details) # Website Score (website_activity_score, website_reputation_score, website_contribution_score) = apply_website_score(categories_url, resume_details, email) save_resume_skills(resume_details, skills_matched, skills_not_matched) # Work Experience features = FeatureExtraction() work_experience = features.get_work_experience(text) # Blog (average_blog_activity_score, average_blog_reputation_score, average_blog_contribution_score) = calculate_blog_scores(resume_details) # Website (average_website_activity_score, average_website_reputation_score, average_website_contribution_score ) = calculate_website_scores(resume_details) # average mobile contribution score (average_mobile_app_activity_score, average_mobile_app_reputation_score, average_mobile_app_contribution_score ) = calculate_average_mobile_contrib_score(resume_details) # Activity Scores blog_activity_score = average_blog_activity_score website_activity_score = average_website_activity_score mobile_app_activity_score = average_mobile_app_activity_score # Contributions Scores blog_contribution_score = average_blog_contribution_score website_contribution_score = average_website_contribution_score mobile_app_contribution_score = average_mobile_app_contribution_score # Reputation Scores blog_reputation_score = average_blog_reputation_score website_reputation_score = average_website_reputation_score mobile_app_reputation_score = average_mobile_app_reputation_score # Total Contribution Score coding_total_contribution_score = (github_contribution_score + bit_bucket_contribution_score + stackoverflow_contribution_score + mobile_app_contribution_score) social_total_contribution_score = (blog_contribution_score + website_contribution_score) # Total Activity score coding_total_activity_score = (github_activity_score + stackoverflow_activity_score + bit_bucket_activity_score + mobile_app_activity_score) social_total_activity_score = blog_activity_score + website_activity_score # Total Reputation Score coding_total_reputation_score = (github_reputation_score + stackoverflow_reputation_score + bit_bucket_reputation_score + mobile_app_reputation_score) social_total_reputation_score = (blog_reputation_score + website_reputation_score) # Total Coding score 2.5 out of 5 total_coding_score = (coding_total_contribution_score + coding_total_reputation_score + coding_total_activity_score) # Total Social Score 1.5 out 5 total_social_score = (social_total_contribution_score + social_total_activity_score + social_total_reputation_score) # Total Skill Matching Score 1 out 5 total_skill_score = skill_match_score # Saving to Scores Model # saving total contribution score coding_score_instance = Score.objects.create(type=Score.TYPES.coding, score=total_coding_score) resume_details.scores.add(coding_score_instance) social_score_instance = Score.objects.create(type=Score.TYPES.social, score=total_social_score) resume_details.scores.add(social_score_instance) skill_score_instance = Score.objects.create( type=Score.TYPES.skill_matching, score=total_skill_score) resume_details.scores.add(skill_score_instance) total_ranking = total_coding_score + total_social_score + total_skill_score # Extracting Location, Company and Institution Names extract_features = ExtractFeatures() locations = extract_features.get_location(text) companies = extract_features.get_company_names(text) institutions = extract_features.get_institution_names(text) for location in locations: location_instance, created = Location.objects.get_or_create( name=location) resume_details.locations.add(location_instance) for company in companies: company_instance, created = Company.objects.get_or_create(name=company) resume_details.companies.add(company_instance) for institution in institutions: institution_instance, created = Institution.objects.get_or_create( name=institution) resume_details.institutions.add(institution_instance) # Extract skills from provided text. # NOTE: As per now we're getting top 1000 tags from SO to extract skills. # With those skills we're getting intersection with list of content text. # Need to find better solution to do so [Bloom filter, et cetera] import re content_list = map(lambda x: re.sub('[^0-9a-zA-Z\.]+', '', x), content_list) # print(content_list) # content_list = map(lambda x: x.replace(',', ''), content_list) matched_skills = list(skillset.intersection(content_list)) for skill in matched_skills: skill_instance, created = Skill.objects.get_or_create(name=skill) rskills = ResumeSkills(resume=resume_details, skill=skill_instance) rskills.save() # Resume file_name = check_file_name_length(file_name) resume_details.first_name = first_name resume_details.last_name = last_name resume_details.phone_number = phone_number resume_details.parse_status = Resume.STATUS.processed resume_details.file_name = file_name resume_details.content_hash = hash_value resume_details.content = text resume_details.email = email resume_details.resume_location = path resume_details.experience = work_experience resume_details.total_score = total_ranking resume_details.save() if callback_client: resp = callback_internal_client(resume_details) if resp.status_code != requests.codes.ok: print( "ERROR: Unable to callback to internal client for resume: %s". format(str(resume_id))) return "Resume Processed"