Duino commited on
Commit
d27647c
·
1 Parent(s): da7aa6c

requirements.txt

Browse files

pdfminer3
pyresparser
streamlit
pandas
pafy
plotly
pymysql
streamlit-tags
Pillow
youtube-dl
nltk
pdfminer3
spacy==2.3.5

Files changed (1) hide show
  1. app.py +437 -0
app.py ADDED
@@ -0,0 +1,437 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ import nltk
3
+ import spacy
4
+ import pandas as pd
5
+ import base64, random
6
+ import time, datetime
7
+ from pyresparser import ResumeParser
8
+ from pdfminer3.layout import LAParams, LTTextBox
9
+ from pdfminer3.pdfpage import PDFPage
10
+ from pdfminer3.pdfinterp import PDFResourceManager
11
+ from pdfminer3.pdfinterp import PDFPageInterpreter
12
+ from pdfminer3.converter import TextConverter
13
+ import io, random
14
+ from streamlit_tags import st_tags
15
+ from PIL import Image
16
+ import pymysql
17
+ from Courses import ds_course, web_course, android_course, ios_course, uiux_course, resume_videos, interview_videos
18
+ import pafy
19
+ import plotly.express as px
20
+ import youtube_dl
21
+
22
+ nltk.download('punkt')
23
+ nltk.download('stopwords')
24
+ spacy.load("en_core_web_trf")
25
+
26
+
27
+ def fetch_yt_video(link):
28
+ video = pafy.new(link)
29
+ return video.title
30
+
31
+
32
+ def get_table_download_link(df, filename, text):
33
+ """Generates a link allowing the data in a given panda dataframe to be downloaded
34
+ in: dataframe
35
+ out: href string
36
+ """
37
+ csv = df.to_csv(index=False)
38
+ b64 = base64.b64encode(csv.encode()).decode() # some strings <-> bytes conversions necessary here
39
+ # href = f'<a href="data:file/csv;base64,{b64}">Download Report</a>'
40
+ href = f'<a href="data:file/csv;base64,{b64}" download="{filename}">{text}</a>'
41
+ return href
42
+
43
+
44
+ def pdf_reader(file):
45
+ resource_manager = PDFResourceManager()
46
+ fake_file_handle = io.StringIO()
47
+ converter = TextConverter(resource_manager, fake_file_handle, laparams=LAParams())
48
+ page_interpreter = PDFPageInterpreter(resource_manager, converter)
49
+ with open(file, 'rb') as fh:
50
+ for page in PDFPage.get_pages(fh,
51
+ caching=True,
52
+ check_extractable=True):
53
+ page_interpreter.process_page(page)
54
+ print(page)
55
+ text = fake_file_handle.getvalue()
56
+
57
+ # close open handles
58
+ converter.close()
59
+ fake_file_handle.close()
60
+ return text
61
+
62
+
63
+ def show_pdf(file_path):
64
+ with open(file_path, "rb") as f:
65
+ base64_pdf = base64.b64encode(f.read()).decode('utf-8')
66
+ # pdf_display = f'<embed src="data:application/pdf;base64,{base64_pdf}" width="700" height="1000" type="application/pdf">'
67
+ pdf_display = F'<iframe src="data:application/pdf;base64,{base64_pdf}" width="700" height="1000" type="application/pdf"></iframe>'
68
+ st.markdown(pdf_display, unsafe_allow_html=True)
69
+
70
+
71
+ def course_recommender(course_list):
72
+ st.subheader("**Courses & Certificates🎓 Recommendations**")
73
+ c = 0
74
+ rec_course = []
75
+ no_of_reco = st.slider('Choose Number of Course Recommendations:', 1, 10, 4)
76
+ random.shuffle(course_list)
77
+ for c_name, c_link in course_list:
78
+ c += 1
79
+ st.markdown(f"({c}) [{c_name}]({c_link})")
80
+ rec_course.append(c_name)
81
+ if c == no_of_reco:
82
+ break
83
+ return rec_course
84
+
85
+
86
+ # connection = pymysql.connect(host='localhost', user='root', password='')
87
+ # # cursor = connection.# cursor()
88
+
89
+
90
+ def insert_data(name, email, res_score, timestamp, no_of_pages, reco_field, cand_level, skills, recommended_skills,
91
+ courses):
92
+ DB_table_name = 'user_data'
93
+ insert_sql = "insert into " + DB_table_name + """
94
+ values (0,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s)"""
95
+ rec_values = (
96
+ name, email, str(res_score), timestamp, str(no_of_pages), reco_field, cand_level, skills, recommended_skills,
97
+ courses)
98
+ # cursor.execute(insert_sql, rec_values)
99
+ connection.commit()
100
+
101
+
102
+ st.set_page_config(
103
+ page_title="Smart CV Analyzer",
104
+ # page_icon='./Logo/SRA_Logo.ico',
105
+ )
106
+
107
+
108
+ def run():
109
+ st.title("Smart Resume Analyser")
110
+ st.sidebar.markdown("# Choose User")
111
+ activities = ["Normal User", "Admin"]
112
+ choice = st.sidebar.selectbox("Choose among the given options:", activities)
113
+ # link = '[©Developed by Spidy20](http://github.com/spidy20)'
114
+ # st.sidebar.markdown(link, unsafe_allow_html=True)
115
+ img = Image.open('./Logo/SRA_Logo.jpg')
116
+ img = img.resize((250, 250))
117
+ st.image(img)
118
+
119
+ # Create the DB
120
+ db_sql = """CREATE DATABASE IF NOT EXISTS SRA;"""
121
+ # # cursor.execute(db_sql)
122
+ # connection.select_db("sra")
123
+
124
+ # Create table
125
+ DB_table_name = 'user_data'
126
+ table_sql = "CREATE TABLE IF NOT EXISTS " + DB_table_name + """
127
+ (ID INT NOT NULL AUTO_INCREMENT,
128
+ Name varchar(100) NOT NULL,
129
+ Email_ID VARCHAR(50) NOT NULL,
130
+ resume_score VARCHAR(8) NOT NULL,
131
+ Timestamp VARCHAR(50) NOT NULL,
132
+ Page_no VARCHAR(5) NOT NULL,
133
+ Predicted_Field VARCHAR(25) NOT NULL,
134
+ User_level VARCHAR(30) NOT NULL,
135
+ Actual_skills VARCHAR(300) NOT NULL,
136
+ Recommended_skills VARCHAR(300) NOT NULL,
137
+ Recommended_courses VARCHAR(600) NOT NULL,
138
+ PRIMARY KEY (ID));
139
+ """
140
+ # cursor.execute(table_sql)
141
+ if choice == 'Normal User':
142
+ # st.markdown('''<h4 style='text-align: left; color: #d73b5c;'>* Upload your resume, and get smart recommendation based on it."</h4>''',
143
+ # unsafe_allow_html=True)
144
+ pdf_file = st.file_uploader("Choose your Resume", type=["pdf"])
145
+ if pdf_file is not None:
146
+ # with st.spinner('Uploading your Resume....'):
147
+ # time.sleep(4)
148
+ save_image_path = './Uploaded_Resumes/' + pdf_file.name
149
+ with open(save_image_path, "wb") as f:
150
+ f.write(pdf_file.getbuffer())
151
+ show_pdf(save_image_path)
152
+ resume_data = ResumeParser(save_image_path).get_extracted_data()
153
+ if resume_data:
154
+ ## Get the whole resume data
155
+ resume_text = pdf_reader(save_image_path)
156
+
157
+ st.header("**Resume Analysis**")
158
+ st.success("Hello " + resume_data['name'])
159
+ st.subheader("**Your Basic info**")
160
+ try:
161
+ st.text('Name: ' + resume_data['name'])
162
+ st.text('Email: ' + resume_data['email'])
163
+ st.text('Contact: ' + resume_data['mobile_number'])
164
+ st.text('Resume pages: ' + str(resume_data['no_of_pages']))
165
+ except:
166
+ pass
167
+ cand_level = ''
168
+ if resume_data['no_of_pages'] == 1:
169
+ cand_level = "Fresher"
170
+ st.markdown('''<h4 style='text-align: left; color: #d73b5c;'>You are looking Fresher.</h4>''',
171
+ unsafe_allow_html=True)
172
+ elif resume_data['no_of_pages'] == 2:
173
+ cand_level = "Intermediate"
174
+ st.markdown('''<h4 style='text-align: left; color: #1ed760;'>You are at intermediate level!</h4>''',
175
+ unsafe_allow_html=True)
176
+ elif resume_data['no_of_pages'] >= 3:
177
+ cand_level = "Experienced"
178
+ st.markdown('''<h4 style='text-align: left; color: #fba171;'>You are at experience level!''',
179
+ unsafe_allow_html=True)
180
+
181
+ st.subheader("**Skills Recommendation💡**")
182
+ ## Skill shows
183
+ keywords = st_tags(label='### Skills that you have',
184
+ text='See our skills recommendation',
185
+ value=resume_data['skills'], key='1')
186
+
187
+ ## recommendation
188
+ ds_keyword = ['tensorflow', 'keras', 'pytorch', 'machine learning', 'deep Learning', 'flask',
189
+ 'streamlit']
190
+ web_keyword = ['react', 'django', 'node jS', 'react js', 'php', 'laravel', 'magento', 'wordpress',
191
+ 'javascript', 'angular js', 'c#', 'flask']
192
+ android_keyword = ['android', 'android development', 'flutter', 'kotlin', 'xml', 'kivy']
193
+ ios_keyword = ['ios', 'ios development', 'swift', 'cocoa', 'cocoa touch', 'xcode']
194
+ uiux_keyword = ['ux', 'adobe xd', 'figma', 'zeplin', 'balsamiq', 'ui', 'prototyping', 'wireframes',
195
+ 'storyframes', 'adobe photoshop', 'photoshop', 'editing', 'adobe illustrator',
196
+ 'illustrator', 'adobe after effects', 'after effects', 'adobe premier pro',
197
+ 'premier pro', 'adobe indesign', 'indesign', 'wireframe', 'solid', 'grasp',
198
+ 'user research', 'user experience']
199
+
200
+ recommended_skills = []
201
+ reco_field = ''
202
+ rec_course = ''
203
+ ## Courses recommendation
204
+ for i in resume_data['skills']:
205
+ ## Data science recommendation
206
+ if i.lower() in ds_keyword:
207
+ print(i.lower())
208
+ reco_field = 'Data Science'
209
+ st.success("** Our analysis says you are looking for Data Science Jobs.**")
210
+ recommended_skills = ['Data Visualization', 'Predictive Analysis', 'Statistical Modeling',
211
+ 'Data Mining', 'Clustering & Classification', 'Data Analytics',
212
+ 'Quantitative Analysis', 'Web Scraping', 'ML Algorithms', 'Keras',
213
+ 'Pytorch', 'Probability', 'Scikit-learn', 'Tensorflow', "Flask",
214
+ 'Streamlit']
215
+ recommended_keywords = st_tags(label='### Recommended skills for you.',
216
+ text='Recommended skills generated from System',
217
+ value=recommended_skills, key='2')
218
+ st.markdown(
219
+ '''<h4 style='text-align: left; color: #1ed760;'>Adding this skills to resume will boost🚀 the chances of getting a Job💼</h4>''',
220
+ unsafe_allow_html=True)
221
+ rec_course = course_recommender(ds_course)
222
+ break
223
+
224
+ ## Web development recommendation
225
+ elif i.lower() in web_keyword:
226
+ print(i.lower())
227
+ reco_field = 'Web Development'
228
+ st.success("** Our analysis says you are looking for Web Development Jobs **")
229
+ recommended_skills = ['React', 'Django', 'Node JS', 'React JS', 'php', 'laravel', 'Magento',
230
+ 'wordpress', 'Javascript', 'Angular JS', 'c#', 'Flask', 'SDK']
231
+ recommended_keywords = st_tags(label='### Recommended skills for you.',
232
+ text='Recommended skills generated from System',
233
+ value=recommended_skills, key='3')
234
+ st.markdown(
235
+ '''<h4 style='text-align: left; color: #1ed760;'>Adding this skills to resume will boost🚀 the chances of getting a Job💼</h4>''',
236
+ unsafe_allow_html=True)
237
+ rec_course = course_recommender(web_course)
238
+ break
239
+
240
+ ## Android App Development
241
+ elif i.lower() in android_keyword:
242
+ print(i.lower())
243
+ reco_field = 'Android Development'
244
+ st.success("** Our analysis says you are looking for Android App Development Jobs **")
245
+ recommended_skills = ['Android', 'Android development', 'Flutter', 'Kotlin', 'XML', 'Java',
246
+ 'Kivy', 'GIT', 'SDK', 'SQLite']
247
+ recommended_keywords = st_tags(label='### Recommended skills for you.',
248
+ text='Recommended skills generated from System',
249
+ value=recommended_skills, key='4')
250
+ st.markdown(
251
+ '''<h4 style='text-align: left; color: #1ed760;'>Adding this skills to resume will boost🚀 the chances of getting a Job💼</h4>''',
252
+ unsafe_allow_html=True)
253
+ rec_course = course_recommender(android_course)
254
+ break
255
+
256
+ ## IOS App Development
257
+ elif i.lower() in ios_keyword:
258
+ print(i.lower())
259
+ reco_field = 'IOS Development'
260
+ st.success("** Our analysis says you are looking for IOS App Development Jobs **")
261
+ recommended_skills = ['IOS', 'IOS Development', 'Swift', 'Cocoa', 'Cocoa Touch', 'Xcode',
262
+ 'Objective-C', 'SQLite', 'Plist', 'StoreKit', "UI-Kit", 'AV Foundation',
263
+ 'Auto-Layout']
264
+ recommended_keywords = st_tags(label='### Recommended skills for you.',
265
+ text='Recommended skills generated from System',
266
+ value=recommended_skills, key='5')
267
+ st.markdown(
268
+ '''<h4 style='text-align: left; color: #1ed760;'>Adding this skills to resume will boost🚀 the chances of getting a Job💼</h4>''',
269
+ unsafe_allow_html=True)
270
+ rec_course = course_recommender(ios_course)
271
+ break
272
+
273
+ ## Ui-UX Recommendation
274
+ elif i.lower() in uiux_keyword:
275
+ print(i.lower())
276
+ reco_field = 'UI-UX Development'
277
+ st.success("** Our analysis says you are looking for UI-UX Development Jobs **")
278
+ recommended_skills = ['UI', 'User Experience', 'Adobe XD', 'Figma', 'Zeplin', 'Balsamiq',
279
+ 'Prototyping', 'Wireframes', 'Storyframes', 'Adobe Photoshop', 'Editing',
280
+ 'Illustrator', 'After Effects', 'Premier Pro', 'Indesign', 'Wireframe',
281
+ 'Solid', 'Grasp', 'User Research']
282
+ recommended_keywords = st_tags(label='### Recommended skills for you.',
283
+ text='Recommended skills generated from System',
284
+ value=recommended_skills, key='6')
285
+ st.markdown(
286
+ '''<h4 style='text-align: left; color: #1ed760;'>Adding this skills to resume will boost🚀 the chances of getting a Job💼</h4>''',
287
+ unsafe_allow_html=True)
288
+ rec_course = course_recommender(uiux_course)
289
+ break
290
+
291
+ #
292
+ ## Insert into table
293
+ ts = time.time()
294
+ cur_date = datetime.datetime.fromtimestamp(ts).strftime('%Y-%m-%d')
295
+ cur_time = datetime.datetime.fromtimestamp(ts).strftime('%H:%M:%S')
296
+ timestamp = str(cur_date + '_' + cur_time)
297
+
298
+ ### Resume writing recommendation
299
+ st.subheader("**Resume Tips & Ideas💡**")
300
+ resume_score = 0
301
+ if 'Objective' in resume_text:
302
+ resume_score = resume_score + 20
303
+ st.markdown(
304
+ '''<h4 style='text-align: left; color: #1ed760;'>[+] Awesome! You have added Objective</h4>''',
305
+ unsafe_allow_html=True)
306
+ else:
307
+ st.markdown(
308
+ '''<h4 style='text-align: left; color: #fabc10;'>[-] According to our recommendation please add your career objective, it will give your career intension to the Recruiters.</h4>''',
309
+ unsafe_allow_html=True)
310
+
311
+ if 'Declaration' in resume_text:
312
+ resume_score = resume_score + 20
313
+ st.markdown(
314
+ '''<h4 style='text-align: left; color: #1ed760;'>[+] Awesome! You have added Delcaration✍/h4>''',
315
+ unsafe_allow_html=True)
316
+ else:
317
+ st.markdown(
318
+ '''<h4 style='text-align: left; color: #fabc10;'>[-] According to our recommendation please add Declaration✍. It will give the assurance that everything written on your resume is true and fully acknowledged by you</h4>''',
319
+ unsafe_allow_html=True)
320
+
321
+ if 'Hobbies' or 'Interests' in resume_text:
322
+ resume_score = resume_score + 20
323
+ st.markdown(
324
+ '''<h4 style='text-align: left; color: #1ed760;'>[+] Awesome! You have added your Hobbies⚽</h4>''',
325
+ unsafe_allow_html=True)
326
+ else:
327
+ st.markdown(
328
+ '''<h4 style='text-align: left; color: #fabc10;'>[-] According to our recommendation please add Hobbies⚽. It will show your persnality to the Recruiters and give the assurance that you are fit for this role or not.</h4>''',
329
+ unsafe_allow_html=True)
330
+
331
+ if 'Achievements' in resume_text:
332
+ resume_score = resume_score + 20
333
+ st.markdown(
334
+ '''<h4 style='text-align: left; color: #1ed760;'>[+] Awesome! You have added your Achievements🏅 </h4>''',
335
+ unsafe_allow_html=True)
336
+ else:
337
+ st.markdown(
338
+ '''<h4 style='text-align: left; color: #fabc10;'>[-] According to our recommendation please add Achievements🏅. It will show that you are capable for the required position.</h4>''',
339
+ unsafe_allow_html=True)
340
+
341
+ if 'Projects' in resume_text:
342
+ resume_score = resume_score + 20
343
+ st.markdown(
344
+ '''<h4 style='text-align: left; color: #1ed760;'>[+] Awesome! You have added your Projects👨‍💻 </h4>''',
345
+ unsafe_allow_html=True)
346
+ else:
347
+ st.markdown(
348
+ '''<h4 style='text-align: left; color: #fabc10;'>[-] According to our recommendation please add Projects👨‍💻. It will show that you have done work related the required position or not.</h4>''',
349
+ unsafe_allow_html=True)
350
+
351
+ st.subheader("**Resume Score📝**")
352
+ st.markdown(
353
+ """
354
+ <style>
355
+ .stProgress > div > div > div > div {
356
+ background-color: #d73b5c;
357
+ }
358
+ </style>""",
359
+ unsafe_allow_html=True,
360
+ )
361
+ my_bar = st.progress(0)
362
+ score = 0
363
+ for percent_complete in range(resume_score):
364
+ score += 1
365
+ time.sleep(0.1)
366
+ my_bar.progress(percent_complete + 1)
367
+ st.success('** Your Resume Writing Score: ' + str(score) + '**')
368
+ st.warning(
369
+ "** Note: This score is calculated based on the content that you have added in your Resume. **")
370
+ st.balloons()
371
+
372
+ insert_data(resume_data['name'], resume_data['email'], str(resume_score), timestamp,
373
+ str(resume_data['no_of_pages']), reco_field, cand_level, str(resume_data['skills']),
374
+ str(recommended_skills), str(rec_course))
375
+
376
+ ## Resume writing video
377
+ st.header("**Bonus Video for Resume Writing Tips💡**")
378
+ resume_vid = random.choice(resume_videos)
379
+ res_vid_title = fetch_yt_video(resume_vid)
380
+ st.subheader("✅ **" + res_vid_title + "**")
381
+ st.video(resume_vid)
382
+
383
+ ## Interview Preparation Video
384
+ st.header("**Bonus Video for Interview👨‍💼 Tips💡**")
385
+ interview_vid = random.choice(interview_videos)
386
+ int_vid_title = fetch_yt_video(interview_vid)
387
+ st.subheader("✅ **" + int_vid_title + "**")
388
+ st.video(interview_vid)
389
+
390
+ connection.commit()
391
+ else:
392
+ st.error('Something went wrong..')
393
+ else:
394
+ ## Admin Side
395
+ st.success('Welcome to Admin Side')
396
+ # st.sidebar.subheader('**ID / Password Required!**')
397
+
398
+ ad_user = st.text_input("Username")
399
+ ad_password = st.text_input("Password", type='password')
400
+ if st.button('Login'):
401
+ if ad_user == 'machine_learning_hub' and ad_password == 'mlhub123':
402
+ st.success("Welcome Kushal")
403
+ # Display Data
404
+ # cursor.execute('''SELECT*FROM user_data''')
405
+ ## data = # cursor.fetchall()
406
+ st.header("**User's👨‍💻 Data**")
407
+ df = pd.DataFrame(data, columns=['ID', 'Name', 'Email', 'Resume Score', 'Timestamp', 'Total Page',
408
+ 'Predicted Field', 'User Level', 'Actual Skills', 'Recommended Skills',
409
+ 'Recommended Course'])
410
+ st.dataframe(df)
411
+ st.markdown(get_table_download_link(df, 'User_Data.csv', 'Download Report'), unsafe_allow_html=True)
412
+ ## Admin Side Data
413
+ query = 'select * from user_data;'
414
+ plot_data = pd.read_sql(query, connection)
415
+
416
+ ## Pie chart for predicted field recommendations
417
+ labels = plot_data.Predicted_Field.unique()
418
+ print(labels)
419
+ values = plot_data.Predicted_Field.value_counts()
420
+ print(values)
421
+ st.subheader("📈 **Pie-Chart for Predicted Field Recommendations**")
422
+ fig = px.pie(df, values=values, names=labels, title='Predicted Field according to the Skills')
423
+ st.plotly_chart(fig)
424
+
425
+ ### Pie chart for User's👨‍💻 Experienced Level
426
+ labels = plot_data.User_level.unique()
427
+ values = plot_data.User_level.value_counts()
428
+ st.subheader("📈 ** Pie-Chart for User's👨‍💻 Experienced Level**")
429
+ fig = px.pie(df, values=values, names=labels, title="Pie-Chart📈 for User's👨‍💻 Experienced Level")
430
+ st.plotly_chart(fig)
431
+
432
+
433
+ else:
434
+ st.error("Wrong ID & Password Provided")
435
+
436
+
437
+ run()