-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Initial commit done with a working code
- Loading branch information
0 parents
commit 4312534
Showing
16 changed files
with
351 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
env | ||
.vscode | ||
output.pdf | ||
config.ini |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
MIT License | ||
|
||
Copyright (c) 2023 Mohit Ranjan | ||
|
||
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: | ||
|
||
The above copyright notice and this permission notice shall be included in all | ||
copies or substantial portions of the Software. | ||
|
||
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. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
# Resume in python (using reportlab) [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) | ||
|
||
This is an attempt to create an ATS friendly resume in python. I'm intending to maintain and enhance it as per my needs, or in case I get any feedback from the community. I'm trying to keep the code simple and easy to comprehend, and separating the data from the PDF generation logic. All the data that needs to be put in the resume is present in the ```data.json``` file | ||
|
||
## Steps to run | ||
- Make sure you have python version 3 installed | ||
- Clone this repository | ||
- Create a virtual environment by running the command ```python3 -m venv env``` | ||
- Activate the virtual environment by running the ```activate``` script for your respective operating system | ||
- Install all the required libraries by running ```pip install requirements.txt``` | ||
- Create a ```config.ini``` file as follows: | ||
|
||
``` | ||
[global] | ||
debug = false | ||
author = <Your name> | ||
email = <Your email> | ||
address = <Your address> | ||
phone = <Your phone number> | ||
``` | ||
This will set the debug configuration as false, which will generate the resume without any grid lines. If debug is set to true it will generate the resume with gridlines | ||
- Run the ```main.py``` file by executing the command ```python3 main.py```. This will generate a resume in PDF format with the name ```output.pdf``` in the project directory | ||
- To customize the information in resume, just modify the ```data.json``` file with your required information | ||
- Personal information would be picked up from the ```config.ini``` file that is present in the project root |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
{ | ||
"education": [ | ||
{ | ||
"degree": "B.Tech (Computer Engineering), CGPA: 8.36", | ||
"university": "Delhi Technological University", | ||
"location": "Delhi, India", | ||
"year": "July 2021" | ||
}, | ||
{ | ||
"degree": "AISSCE (Class XII), Percentage: 95.2%", | ||
"university": "Vanasthali Public School", | ||
"location": "Delhi, India", | ||
"year": "July 2017" | ||
}, | ||
{ | ||
"degree": "AISSE (Class X), CGPA: 10.0", | ||
"university": "Vanasthali Public School", | ||
"location": "Delhi, India", | ||
"year": "July 2015" | ||
} | ||
], | ||
"experience": [ | ||
{ | ||
"title": "Research and Development Engineer", | ||
"company": "Tejas Networks Ltd.", | ||
"location": "Gurugram, Haryana, India", | ||
"duration": "July 2021 - Present", | ||
"description": [ | ||
"Developed and implemented new features, including Circuit Emulation and QoS Enhancements, for carrier Ethernet Networks in TejNMS (Tejas Network Management System) app", | ||
"Installed and configured multiple network element simulators, providing a realistic testing environment, using Docker", | ||
"Utilized Selenium and TestNG to automate regression testing, resulting in improved efficiency and reduced testing time by 60%", | ||
"Developed test scripts and executed automated tests to verify system functionality, identify bugs, and ensure product quality", | ||
"Played a key role in migrating the existing codebase of the TejNMS from CVS to Git, enhancing version control and collaboration processes", | ||
"Currently involved in the development of a user-friendly Border Gateway Protocol (BGP) configuration UI for Layer 3 provisioning in TejNMS" | ||
] | ||
}, | ||
{ | ||
"title": "R & D Engineer Intern", | ||
"company": "Tejas Networks Ltd.", | ||
"location": "Gurugram, Haryana, India", | ||
"duration": "January 2021 - July 2021", | ||
"description": [ | ||
"Achieved enhanced code quality through in-depth analysis and optimized flow by leveraging library functions of DHTMLX, minimizing redundancy", | ||
"Significantly improved TejNMS UI by implementing modern JavaScript practices and asynchronous operations, resulting in shorter development time and highly predictable code behavior." | ||
] | ||
}, | ||
{ | ||
"title": "Front-end Developer Intern", | ||
"company": "Stepswatch", | ||
"location": "India", | ||
"duration": "March 2020 - May 2020", | ||
"description": [ | ||
"Designed and developed the Stepswatch mobile app from scratch using React Native, Redux, and Node.js", | ||
"Implemented authentication and state management using Redux and JWT (JSON Web Tokens), ensuring secure user sessions and data protection", | ||
"Integrated real-time chat functionality using socket.io, allowing users to engage in seamless and instant communication within the app" | ||
] | ||
}, | ||
{ | ||
"title": "University Student Intern", | ||
"company": "Delhi Technological University", | ||
"location": "Delhi, India", | ||
"duration": "August 2019 - March 2020", | ||
"description": [ | ||
"Designed and developed the website for Intellectual Property Rights Cell, DTU <a href=\"https://mohitr1999.github.io/iprCellWebsite/\" color=\"blue\">(Link)</a>", | ||
"Developed the website for International Summit on Quality Indices in Higher Education" | ||
] | ||
} | ||
], | ||
"skills": [ | ||
"Programming Languages: Javascript, C++, Python", | ||
"Version control systems: Git, CVS", | ||
"Frameworks and Libraries: React.js, React Native, Redux" | ||
], | ||
|
||
"projects" : [ | ||
{ | ||
"title" : "C Compiler in Javascript", | ||
"description" : "A C compiler, written purely in Javascript from scratch <a href=\"https://github.com/MohitR1999/compiler-in-javascript\" color=\"blue\">(GitHub)</a>", | ||
"link" : "<a href=\"https://github.com/MohitR1999/compiler-in-javascript\" color=\"blue\">(GitHub)</a>" | ||
}, | ||
|
||
{ | ||
"title" : "Vitarit File Pranali", | ||
"description" : "A distributed file system implemented using python and rpyc <a href=\"https://github.com/MohitR1999/vitarit-file-pranali\" color=\"blue\">(GitHub)</a>", | ||
"link" : "<a href=\"https://github.com/MohitR1999/vitarit-file-pranali\" color=\"blue\">(GitHub)</a>" | ||
}, | ||
|
||
{ | ||
"title" : "Maestro-bot", | ||
"description" : "A Discord bot, that shows you memes and pictures as you say <a href=\"https://github.com/MohitR1999/maestro-bot\" color=\"blue\">(GitHub)</a>", | ||
"link" : "<a href=\"https://github.com/MohitR1999/maestro-bot\" color=\"blue\">(GitHub)</a>" | ||
} | ||
] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,206 @@ | ||
from reportlab.pdfbase import pdfmetrics, ttfonts | ||
from reportlab.lib.pagesizes import A4 | ||
from reportlab.lib.units import inch | ||
from reportlab.lib import colors | ||
from reportlab.platypus import SimpleDocTemplate, Paragraph, Table, TableStyle | ||
from reportlab.lib.styles import ParagraphStyle | ||
from reportlab.lib.enums import TA_RIGHT | ||
import json | ||
import configparser | ||
import os | ||
|
||
PAGE_WIDTH, PAGE_HEIGHT = A4 | ||
FULL_COLUMN_WIDTH = (PAGE_WIDTH - 1 * inch) | ||
GARAMOND_REGULAR_FONT_PATH = './res/fonts/EBGaramond-Regular.ttf' | ||
GARAMOND_REGULAR = 'Garamond_Regular' | ||
|
||
GARAMOND_BOLD_FONT_PATH = './res/fonts/EBGaramond-Bold.ttf' | ||
GARAMOND_BOLD = 'Garamond_Bold' | ||
|
||
GARAMOND_SEMIBOLD_FONT_PATH = './res/fonts/EBGaramond-SemiBold.ttf' | ||
GARAMOND_SEMIBOLD = 'Garamond_Semibold' | ||
|
||
pdfmetrics.registerFont(ttfonts.TTFont(GARAMOND_REGULAR, GARAMOND_REGULAR_FONT_PATH)) | ||
pdfmetrics.registerFont(ttfonts.TTFont(GARAMOND_BOLD, GARAMOND_BOLD_FONT_PATH)) | ||
pdfmetrics.registerFont(ttfonts.TTFont(GARAMOND_SEMIBOLD, GARAMOND_SEMIBOLD_FONT_PATH)) | ||
|
||
JOB_DETAILS_PARAGRAPH_STYLE = ParagraphStyle('job_details_paragraph', leftIndent=12, fontName = GARAMOND_REGULAR, fontSize = 12, leading = 14) | ||
NAME_PARAGRAPH_STYLE = ParagraphStyle('name_paragraph', fontName = GARAMOND_SEMIBOLD, fontSize=16) | ||
CONTACT_PARAGRAPH_STYLE = ParagraphStyle('contact_paragraph', fontName = GARAMOND_REGULAR, fontSize=12) | ||
SECTION_PARAGRAPH_STYLE = ParagraphStyle('section_paragraph', fontName = GARAMOND_SEMIBOLD, fontSize=13, textTransform = 'uppercase') | ||
COMPANY_HEADING_PARAGRAPH_STYLE = ParagraphStyle('company_heading_paragraph', fontName = GARAMOND_SEMIBOLD, fontSize=13) | ||
COMPANY_TITLE_PARAGRAPH_STYLE = ParagraphStyle('company_title_paragraph', fontName = GARAMOND_REGULAR, fontSize=12) | ||
COMPANY_DURATION_PARAGRAPH_STYLE = ParagraphStyle('company_duration_paragraph', fontName = GARAMOND_SEMIBOLD, fontSize=13, alignment = TA_RIGHT) | ||
COMPANY_LOCATION_PARAGRAPH_STYLE = ParagraphStyle('company_location_paragraph', fontName = GARAMOND_REGULAR, fontSize=12, alignment = TA_RIGHT) | ||
|
||
def appendSectionTableStyle(table_styles, running_row_index): | ||
table_styles.append(('TOPPADDING', (0, running_row_index), (1, running_row_index), 5)) | ||
table_styles.append(('BOTTOMPADDING', (0, running_row_index), (1, running_row_index), 5)) | ||
table_styles.append(('LINEBELOW', (0, running_row_index), (-1, running_row_index), 1, colors.black)) | ||
|
||
|
||
def generate_resume(file_path, json_file_path): | ||
config = None | ||
debug = 'false' | ||
author = 'anonymous' | ||
email = '[email protected]' | ||
address = 'XXX' | ||
phone = '00-0000000000' | ||
|
||
if (os.path.isfile('./config.ini')): | ||
config = configparser.ConfigParser() | ||
config.read('./config.ini') | ||
# Check if debug option is present | ||
if (config.has_option('global', 'debug')): | ||
debug = config.get('global', 'debug') | ||
|
||
# Check if author is present | ||
if (config.has_option('global', 'author')): | ||
author = config.get('global', 'author') | ||
|
||
# Check if email address is present | ||
if (config.has_option('global', 'email')): | ||
email = config.get('global', 'email') | ||
|
||
# Check if address is present | ||
if (config.has_option('global', 'address')): | ||
address = config.get('global', 'address') | ||
|
||
# Check if author is present | ||
if (config.has_option('global', 'phone')): | ||
phone = config.get('global', 'phone') | ||
|
||
doc = SimpleDocTemplate(file_path, pagesize=A4, showBoundary=0, leftMargin = 0.5 * inch, rightMargin= 0.5 * inch, topMargin = 0.2 * inch, bottomMargin = 0.1 * inch, title = f"Resume of {author}", author = author) | ||
with open(json_file_path, 'r') as file: | ||
data = json.load(file) | ||
# data for the table | ||
table_data = [] | ||
table_styles = [] | ||
running_row_index = 0 | ||
|
||
# Append some basic styles to the table styles array only in debug mode | ||
if (debug == 'true'): | ||
table_styles.append(('GRID', (0, 0), (-1, -1), 0, colors.black)) | ||
|
||
table_styles.append(('ALIGN', (0, 0), (0, -1), 'LEFT')) | ||
table_styles.append(('ALIGN', (1, 0), (1, -1), 'RIGHT')) | ||
table_styles.append(('LEFTPADDING', (0, 0), (-1, -1), 0)) | ||
table_styles.append(('RIGHTPADDING', (0, 0), (-1, -1), 0)) | ||
# Add name and basic contact | ||
|
||
table_styles.append(('BOTTOMPADDING', (0, running_row_index), (1, running_row_index), 6)) | ||
table_data.append([ | ||
Paragraph(author, NAME_PARAGRAPH_STYLE) | ||
]) | ||
running_row_index += 1 | ||
|
||
table_data.append([ | ||
Paragraph(f"{email} | {phone} | {address}", CONTACT_PARAGRAPH_STYLE), | ||
]) | ||
table_styles.append(('BOTTOMPADDING', (0, running_row_index), (1, running_row_index), 1)) | ||
running_row_index += 1 | ||
|
||
# Add experience heading | ||
table_data.append( | ||
[Paragraph("Experience", SECTION_PARAGRAPH_STYLE)] | ||
) | ||
appendSectionTableStyle(table_styles, running_row_index) | ||
running_row_index += 1 | ||
|
||
|
||
# Append experience | ||
for job_experience in data['experience']: | ||
table_data.append([ | ||
Paragraph(job_experience['company'], COMPANY_HEADING_PARAGRAPH_STYLE), | ||
Paragraph(job_experience['duration'], COMPANY_DURATION_PARAGRAPH_STYLE), | ||
]) | ||
table_styles.append(('TOPPADDING', (0, running_row_index), (1, running_row_index), 5)) | ||
running_row_index += 1 | ||
|
||
table_data.append([ | ||
Paragraph(job_experience['title'], COMPANY_TITLE_PARAGRAPH_STYLE), | ||
Paragraph(job_experience['location'], COMPANY_LOCATION_PARAGRAPH_STYLE), | ||
]) | ||
table_styles.append(('TOPPADDING', (0, running_row_index), (1, running_row_index), 1)) | ||
running_row_index += 1 | ||
|
||
for line in job_experience['description']: | ||
table_data.append([ | ||
Paragraph(line, bulletText='•', style=JOB_DETAILS_PARAGRAPH_STYLE) | ||
]) | ||
table_styles.append(('TOPPADDING', (0, running_row_index), (1, running_row_index), 1)) | ||
table_styles.append(('BOTTOMPADDING', (0, running_row_index), (1, running_row_index), 0)) | ||
table_styles.append(('SPAN', (0, running_row_index), (1, running_row_index))) | ||
running_row_index += 1 | ||
|
||
# Append education heading | ||
table_data.append( | ||
[Paragraph("Education", SECTION_PARAGRAPH_STYLE)] | ||
) | ||
appendSectionTableStyle(table_styles, running_row_index) | ||
running_row_index += 1 | ||
|
||
# Append education | ||
for education in data['education']: | ||
table_data.append([ | ||
Paragraph(education['university'], COMPANY_HEADING_PARAGRAPH_STYLE), | ||
Paragraph(education['year'], COMPANY_DURATION_PARAGRAPH_STYLE), | ||
]) | ||
table_styles.append(('TOPPADDING', (0, running_row_index), (1, running_row_index), 5)) | ||
running_row_index += 1 | ||
|
||
table_data.append([ | ||
Paragraph(education['degree'], COMPANY_TITLE_PARAGRAPH_STYLE), | ||
Paragraph(education['location'], COMPANY_LOCATION_PARAGRAPH_STYLE), | ||
]) | ||
table_styles.append(('TOPPADDING', (0, running_row_index), (1, running_row_index), 1)) | ||
running_row_index += 1 | ||
|
||
# Append projects heading | ||
table_data.append( | ||
[Paragraph("Projects", SECTION_PARAGRAPH_STYLE)] | ||
) | ||
appendSectionTableStyle(table_styles, running_row_index) | ||
running_row_index += 1 | ||
|
||
for project in data['projects']: | ||
table_data.append([ | ||
Paragraph(project['description'], bulletText='•', style=COMPANY_TITLE_PARAGRAPH_STYLE), | ||
]) | ||
table_styles.append(('TOPPADDING', (0, running_row_index), (1, running_row_index), 1)) | ||
table_styles.append(('SPAN', (0, running_row_index), (1, running_row_index))) | ||
running_row_index += 1 | ||
|
||
# Append skills heading | ||
table_data.append( | ||
[Paragraph("Skills", SECTION_PARAGRAPH_STYLE)] | ||
) | ||
appendSectionTableStyle(table_styles, running_row_index) | ||
running_row_index += 1 | ||
|
||
# Append skills | ||
for skill in data['skills']: | ||
table_data.append([ | ||
Paragraph(skill, bulletText='•', style=JOB_DETAILS_PARAGRAPH_STYLE) | ||
]) | ||
table_styles.append(('TOPPADDING', (0, running_row_index), (1, running_row_index), 1)) | ||
table_styles.append(('BOTTOMPADDING', (0, running_row_index), (1, running_row_index), 0)) | ||
table_styles.append(('SPAN', (0, running_row_index), (1, running_row_index))) | ||
running_row_index += 1 | ||
|
||
table_style = TableStyle(table_styles) | ||
|
||
# Create the table and apply the style | ||
table = Table(table_data, colWidths=[FULL_COLUMN_WIDTH * 0.7, FULL_COLUMN_WIDTH * 0.3], spaceBefore=0, spaceAfter=0) | ||
table.setStyle(table_style) | ||
|
||
# Add the table to the elements list | ||
elements = [table] | ||
|
||
# Build the PDF document | ||
doc.build(elements) | ||
|
||
if __name__ == "__main__": | ||
OUTPUT_PDF_PATH = "./output.pdf" | ||
JSON_PATH = "./data.json" | ||
generate_resume(OUTPUT_PDF_PATH, JSON_PATH) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
Pillow==10.0.0 | ||
reportlab==4.0.4 |
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.