Skip to content

Commit

Permalink
Fixes issue 9, csv.DictReader
Browse files Browse the repository at this point in the history
  • Loading branch information
LeamHall committed Dec 14, 2023
1 parent 91c8aca commit e124926
Show file tree
Hide file tree
Showing 5 changed files with 217 additions and 156 deletions.
19 changes: 19 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Makefile

SHELL = /usr/bin/bash

.PHONY:test
test:
python -m unittest

clean:
find . -type f -name "*.pyc" -exec rm {} \;
find . -type f -name "*.swp" -exec rm {} \;

all: clean test
coverage run -m unittest
coverage report -m
python -m black -l79 .
-flake8 --ignore E251,E266,W391


7 changes: 1 addition & 6 deletions data/jobs.txt
Original file line number Diff line number Diff line change
@@ -1,8 +1,3 @@
# data/jobs.txt



first_contact;last_contact;poc_name;company;notes;active;url;title
20230123;20230201;Fred Smythe; Some Great Place, LLC; linux, ansible, python; y; https://example.com/r12345; Senior Automation Engineer

20230101; 20230101; Jason Jayson; Can't read resume, Inc; Windows server, powershell; n; https://whocares.com; Winderz admin

5 changes: 1 addition & 4 deletions data/pocs.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,4 @@
# data/pocs.txt
name;phone;email;first_contact;last_contact
Fred Smythe; 555.555.1212; fred@example.com; Example, Inc ; 20230123; 20202102
Jayne Johnson; 123.456.7890; jj@otherexample.com; Other Recruiter, LLC; 20221212; 20221212


Jason Jayson; br-549; jay@whocares.com; Whocares, Inc; 20230101; 20230101

195 changes: 119 additions & 76 deletions job_seeker.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,25 +6,42 @@
# desc: Track data on job applications

import argparse
import csv
from datetime import datetime as dt
import os.path
import sys


class Job:
""" Stores the job req data """
def __init__(self, job_data = {}):
self.title = job_data.get("title", None)
self.active = job_data.get("active", "y")
self.notes = job_data.get("notes", None)
self.company = job_data.get("company", None)
self.url = job_data.get("url", None)
self.poc_name = job_data.get("poc_name", None)
self.last_contact = job_data.get("last_contact", convert_date(dt.now()))
self.first_contact = job_data.get("first_contact", convert_date(dt.now()))
"""Stores the job req data"""

def __init__(self, job_data={}):
self.title = job_data.get("title", "")
self.active = job_data.get("active", "y")
self.notes = job_data.get("notes", "")
self.company = job_data.get("company", "")
self.url = job_data.get("url", "")
self.poc_name = job_data.get("poc_name", "")
self.last_contact = job_data.get(
"last_contact", convert_date(dt.now())
)
self.first_contact = job_data.get(
"first_contact", convert_date(dt.now())
)
self.searchables = [
self.title.lower(),
self.notes.lower(),
self.company.lower(),
self.url.lower(),
self.poc_name.lower(),
]

def __str__(self):
return "{}\nActive: {} Notes: {}\n{}, {}\n{} \nLast chat: {}, First chat: {}".format(
if self.active == "y":
self.active = "Yes"
else:
self.active = "No"
return "Title: {}\nActive: {}\nNotes: {}\nCompany: {} ({})\nPOC: {} \nLast contact: {}\nFirst contact: {}".format(
self.title,
self.active,
self.notes,
Expand All @@ -35,123 +52,149 @@ def __str__(self):
self.first_contact,
)


def job_builder(line):
_list = string_to_list(line)
data = {
"last_contact": _list[0],
"first_contact": _list[1],
"poc_name": _list[2],
"company": _list[3],
"notes": _list[4],
"active": _list[5],
"url": _list[6],
"title": _list[7],
"last_contact": _list[0],
"first_contact": _list[1],
"poc_name": _list[2],
"company": _list[3],
"notes": _list[4],
"active": _list[5],
"url": _list[6],
"title": _list[7],
}
return Job(data)
return Job(data)


class POC():
""" Stores the contact info for each Point of Contact """
def __init__(self, data = {}):
self.name = data.get('name', None)
self.company = data.get('company', None)
self.phone = data.get('phone', None)
self.email = data.get('email', None)
self.first_contact = data.get("first_contact", convert_date(dt.now()))
self.last_contact = data.get('last_contact', convert_date(dt.now()))
class POC:
"""Stores the contact info for each Point of Contact"""

def __init__(self, data={}):
self.name = data.get("name", "")
self.company = data.get("company", "")
self.phone = data.get("phone", "")
self.email = data.get("email", "")
self.first_contact = data.get("first_contact", convert_date(dt.now()))
self.last_contact = data.get("last_contact", convert_date(dt.now()))
self.searchables = [
self.name.lower(),
self.company.lower(),
self.email.lower(),
]

def __str__(self):
""" Returns a formatted string with the POC info """
"""Returns a formatted string with the POC info"""
return "{}, ({}) {} [{}]\nFirst Contact: {}, Last Contact: {}".format(
self.name,
self.name,
self.phone,
self.email,
self.company,
self.first_contact,
self.last_contact)
self.last_contact,
)


def poc_builder(line):
_list = string_to_list(line)
data = {
"name": _list[0],
"phone": _list[1],
"email": _list[2],
"company": _list[3],
"first_contact": _list[4],
"last_contact": _list[5],
}
"name": _list[0],
"phone": _list[1],
"email": _list[2],
"company": _list[3],
"first_contact": _list[4],
"last_contact": _list[5],
}
return POC(data)



def convert_date(date):
""" Takes a datetime.datetime object and returns a YYYMMDD string """
"""Takes a datetime.datetime object and returns a YYYMMDD string"""
return "{}{:0>2}{:0>2}".format(date.year, date.month, date.day)


def list_from_file(filename):
""" Takes a file, removes comments/empty lines, returns a list of each line """
"""Takes a file, removes comments/empty lines, returns a list of each line"""
lines = []
with open(filename, 'r') as f:
with open(filename, "r") as f:
for line in f:
line = line.strip()
if len(line) > 5 and not line.startswith("#"):
lines.append(line)
return lines


def parse_list(_list, _list_type, search):
""" Takes a list, and the element type, and prints any that match search """
items = []
"""Takes a list, and the element type, and prints any that match search"""
items = []
for element in _list:
if search.lower() in element.lower():
if _list_type == "poc":
items.append(poc_builder(element))
if _list_type == "job":
items.append(job_builder(element))
return items

def string_to_list(data, sep = ';'):
""" Takes a sep separated string and converts it to a list """
return [ e.strip() for e in data.split(sep) ]



def string_to_list(data, sep=";"):
"""Takes a sep separated string and converts it to a list"""
return [e.strip() for e in data.split(sep)]


def items_from_file(filename, klass):
"""Takes a filename, and returns objects based on that file."""
with open(filename, "r") as f:
reader = csv.DictReader(f, delimiter=";")
result = [klass(row) for row in reader]

return result


def search_items(search_term, *lists):
"""
Searches the values of each item in a list of objects.
Returns a list of objects with the search_term.
"""
results = []
for _list in lists:
for item in _list:
for searchable in item.searchables:
if search_term.lower() in searchable:
results.append(item)
break
return results


if __name__ == "__main__":
datadir = "data"
job_file = "jobs.txt"
poc_file = "pocs.txt"

datadir = "data"
job_file = "jobs.txt"
poc_file = "pocs.txt"
try:
poc_list = list_from_file(os.path.join(datadir, poc_file))
job_list = list_from_file(os.path.join(datadir, job_file))
poc_list = items_from_file(os.path.join(datadir, poc_file), POC)
job_list = items_from_file(os.path.join(datadir, job_file), Job)
except:
print("Can't find the data files")
sys.exit(1)

parser = argparse.ArgumentParser()
parser.add_argument(
"-a", "--add",
help = "add data, requires -r or -p",
action = "store_true")
parser.add_argument(
"-j", "--job",
help = "use the Job info",
action = "store_true")
"-a", "--add", help="add data, requires -r or -p", action="store_true"
)
parser.add_argument(
"-p", "--poc",
help = "use the POC info",
action = "store_true")
"-j", "--job", help="use the Job info", action="store_true"
)
parser.add_argument(
"-s", "--search",
help = "SEARCH for",
default = "")
"-p", "--poc", help="use the POC info", action="store_true"
)
parser.add_argument("-s", "--search", help="SEARCH for", default="")
args = parser.parse_args()

if args.add:
print("I am to add")

if args.job:
for job in parse_list(job_list, "job", args.search):
print(job, "\n")
elif args.poc:
for poc in parse_list(poc_list, "poc", args.search):
print(poc, "\n")


if args.search:
results = search_items(args.search, job_list, poc_list)
for result in results:
print(result, "\n")
Loading

0 comments on commit e124926

Please sign in to comment.