Skip to content

Commit

Permalink
feat: modularize resume build process
Browse files Browse the repository at this point in the history
  • Loading branch information
cybardev committed Jan 20, 2024
1 parent 9b87a62 commit 433bb8c
Show file tree
Hide file tree
Showing 8 changed files with 177 additions and 145 deletions.
4 changes: 3 additions & 1 deletion .github/workflows/resume.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,9 @@ jobs:
uses: actions/checkout@v4
- name: Run resume generation script
run: |
python3 example.py
cd ./src/
python3 -m resume.builder ../example.py -o ../assets
cd ../
- name: Check for resume changes
id: check_updates
run: |
Expand Down
228 changes: 111 additions & 117 deletions example.py
Original file line number Diff line number Diff line change
@@ -1,121 +1,115 @@
#!/usr/bin/env python3
from src.resume.components import *


from src.resume import *


# TODO: edit author object as required
me: Author = Author(
name="Sheikh Saad Abdullah",
address=Address("2060 Quingate Place", "B3L 4P7"),
phone="+1 (902) 818-0048",
email="[email protected]",
website="www.cybar.dev",
social="cybardev",
skills=[
Skill(
name="Skills",
attributes=[
"Python",
"HTML",
"CSS",
"Bootstrap",
"JavaScript",
"jQuery",
"ReactJS",
"NodeJS",
"ExpressJS",
"MongoDB",
"Java",
"C/C++",
"Git",
],
),
Skill(
name="Interests",
attributes=[
"Linux",
"Open-source",
"Shell Scripting",
"Automation",
"Cloud",
"Front-end Web Development",
"Data Analytics",
],
),
],
experiences=[
Experience(
name="ReelData AI",
address="Halifax, Nova Scotia",
role="Junior Software Developer",
start="Sept 2023",
end="Dec 2023",
attributes=[
"Collaborated with a dynamic Agile team on ReelAppetite, a key product, demonstrating strong teamwork and interpersonal skills",
"Successfully integrated into a large existing codebase, showcasing adaptability and quick learning",
"Implemented features using test-driven development and containerization, contributing to the software’s robustness",
"Experienced the deployment of code to production, highlighting practical application and impact of contributions",
],
),
Experience(
name="Sensor Technology LTD (COVE)",
address="Dartmouth, Nova Scotia",
role="Research Intern",
start="May 2023",
end="Aug 2023",
attributes=[
"Configured Raspberry Pi SBCs with OpenPlotter Marine OS for the purpose of developing and testing the Acoustic Projector Control and Logging System",
"Developed Python script for generation and playback of audio files from given wavelength and duration",
"Implemented module to connect to private Signal K server and utilize its API to effectively retrieve sensor data",
"Created a script for logging data from sensors, consuming it via API calls, and storing it in an SQLite database",
],
),
],
projects=[
Project(
name="Cy | Pass - Secure Password Generator",
address="https://pypi.org/project/cybarpass",
role="Software Developer",
start="Apr 2022",
end="Apr 2023",
attributes=[
"Modularized code by splitting up project into multiple scripts and using proper object-oriented techniques to ensure separation of concerns",
"Designed and implemented simple and elegant tkinter GUI and robust CLI for convenience and ease of access",
"Packaged and published project to Python Package Index (PyPI), making it easy and convenient for users to install",
"Created companion tool [CheckPass](https://checkpass.cybar.dev) to allow users to test the security of generated passphrase",
],
),
Project(
name="Cy | Search - Search Engine Frontend",
address="https://search.cybar.dev",
role="Full-stack Developer",
start="Jan 2022",
end="Apr 2022",
attributes=[
"Designed a search engine frontend that uses NodeJS functions to request and fetch search results from a public API",
"Successfully displayed the fetched results in a clear and concise format",
"Secured the API key by encrypting it as a repository secret and using code obfuscation techniques",
"Implemented progressive web app functionality to allow users to install it as an app",
def main():
# TODO: edit author object as required
return Author(
name="Sheikh Saad Abdullah",
address=Address("2060 Quingate Place", "B3L 4P7"),
phone="+1 (902) 818-0048",
email="[email protected]",
website="www.cybar.dev",
social="cybardev",
skills=[
Skill(
name="Skills",
attributes=[
"Python",
"HTML",
"CSS",
"Bootstrap",
"JavaScript",
"jQuery",
"ReactJS",
"NodeJS",
"ExpressJS",
"MongoDB",
"Java",
"C/C++",
"Git",
],
),
Skill(
name="Interests",
attributes=[
"Linux",
"Open-source",
"Shell Scripting",
"Automation",
"Cloud",
"Front-end Web Development",
"Data Analytics",
],
),
],
experiences=[
Experience(
name="ReelData AI",
address="Halifax, Nova Scotia",
role="Junior Software Developer",
start="Sept 2023",
end="Dec 2023",
attributes=[
"Collaborated with a dynamic Agile team on ReelAppetite, a key product, demonstrating strong teamwork and interpersonal skills",
"Successfully integrated into a large existing codebase, showcasing adaptability and quick learning",
"Implemented features using test-driven development and containerization, contributing to the software’s robustness",
"Experienced the deployment of code to production, highlighting practical application and impact of contributions",
],
),
Experience(
name="Sensor Technology LTD (COVE)",
address="Dartmouth, Nova Scotia",
role="Research Intern",
start="May 2023",
end="Aug 2023",
attributes=[
"Configured Raspberry Pi SBCs with OpenPlotter Marine OS for the purpose of developing and testing the Acoustic Projector Control and Logging System",
"Developed Python script for generation and playback of audio files from given wavelength and duration",
"Implemented module to connect to private Signal K server and utilize its API to effectively retrieve sensor data",
"Created a script for logging data from sensors, consuming it via API calls, and storing it in an SQLite database",
],
),
],
projects=[
Project(
name="Cy | Pass - Secure Password Generator",
address="https://pypi.org/project/cybarpass",
role="Software Developer",
start="Apr 2022",
end="Apr 2023",
attributes=[
"Modularized code by splitting up project into multiple scripts and using proper object-oriented techniques to ensure separation of concerns",
"Designed and implemented simple and elegant tkinter GUI and robust CLI for convenience and ease of access",
"Packaged and published project to Python Package Index (PyPI), making it easy and convenient for users to install",
"Created companion tool [CheckPass](https://checkpass.cybar.dev) to allow users to test the security of generated passphrase",
],
),
Project(
name="Cy | Search - Search Engine Frontend",
address="https://search.cybar.dev",
role="Full-stack Developer",
start="Jan 2022",
end="Apr 2022",
attributes=[
"Designed a search engine frontend that uses NodeJS functions to request and fetch search results from a public API",
"Successfully displayed the fetched results in a clear and concise format",
"Secured the API key by encrypting it as a repository secret and using code obfuscation techniques",
"Implemented progressive web app functionality to allow users to install it as an app",
],
),
],
education=Education(
school="Saint Mary's University",
location="Halifax, Nova Scotia",
program="Bachelor of Science",
major="Computing Science",
start="Sep 2020",
end="Dec 2024",
courses=[
"Artificial Intelligence",
"Data Structures and Algorithms",
"Software Engineering",
"Systems Security",
],
),
],
education=Education(
school="Saint Mary's University",
location="Halifax, Nova Scotia",
program="Bachelor of Science",
major="Computing Science",
start="Sep 2020",
end="Dec 2024",
courses=[
"Artificial Intelligence",
"Data Structures and Algorithms",
"Software Engineering",
"Systems Security",
],
),
)


if __name__ == "__main__":
generate_resume(me, "./assets/")
)
10 changes: 0 additions & 10 deletions src/resume/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,3 @@

# metadata
__version__ = "1.0.0"

# import everything needed for a resume
from .components.address import Address
from .components.author import Author
from .components.education import Education
from .components.experience import Experience
from .components.project import Project
from .components.resume import Resume
from .components.skill import Skill
from .utils import generate_resume, md_to_pdf
15 changes: 0 additions & 15 deletions src/resume/__main__.py

This file was deleted.

1 change: 1 addition & 0 deletions src/resume/builder/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# __init__.py
52 changes: 52 additions & 0 deletions src/resume/builder/__main__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
#!/usr/bin/env python3

import argparse
import os
import sys

from importlib.machinery import SourceFileLoader
from importlib.util import spec_from_loader, module_from_spec

from ..components.resume import Resume
from ..utils import generate_resume


def main(args: argparse.Namespace):
full_path = os.path.abspath(args.resume)
filename = os.path.basename(full_path)
sys.path.append(os.path.dirname(full_path))

loader = SourceFileLoader(filename, full_path)
spec = spec_from_loader(filename, loader)
resume_info = module_from_spec(spec)
loader.exec_module(resume_info)

resume_obj = Resume(resume_info.main())
generate_resume(resume_obj, args.output)


def parse_args() -> argparse.Namespace:
parser = argparse.ArgumentParser(
prog="resume",
description="Generate a resume from a given python file",
allow_abbrev=False,
)
parser.add_argument(
"resume",
metavar="RESUME",
type=str,
help="path to the Python file containing the resume data",
)
parser.add_argument(
"-o",
"--output",
dest="output",
type=str,
help="path to the output directory",
default="./",
)
return parser.parse_args()


if __name__ == "__main__":
main(parse_args())
9 changes: 9 additions & 0 deletions src/resume/components/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +1,10 @@
# __init__.py

# import everything needed for a resume
from .address import Address
from .author import Author
from .education import Education
from .experience import Experience
from .project import Project
from .resume import Resume
from .skill import Skill
3 changes: 1 addition & 2 deletions src/resume/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,9 +58,8 @@ def pdf_to_png(
)


def generate_resume(author, output_dir: str) -> Resume:
def generate_resume(resume, output_dir: str):
# generate resume and output to markdown file
resume: Resume = Resume(author)
filename = (
output_dir.rstrip("/")
+ "/"
Expand Down

0 comments on commit 433bb8c

Please sign in to comment.