SHOW:
|
|
- or go back to the newest paste.
| 1 | - | import sqlite3 as sqlite, argparse |
| 1 | + | import sqlite3 as sqlite, argparse |
| 2 | - | |
| 2 | + | |
| 3 | - | class HourTracker: |
| 3 | + | class HourTracker: |
| 4 | - | class CursorInstance: |
| 4 | + | class CursorInstance: |
| 5 | - | def __init__(self, con): |
| 5 | + | def __init__(self, con): |
| 6 | - | self.cursor = con.cursor() |
| 6 | + | self.cursor = con.cursor() |
| 7 | - | self.con = con |
| 7 | + | self.con = con |
| 8 | - | def __call__(self,*a,**k):return self.cursor.execute(*a,**k) |
| 8 | + | def __call__(self,*a,**k):return self.cursor.execute(*a,**k) |
| 9 | - | def __enter__(self):return self |
| 9 | + | def __enter__(self):return self |
| 10 | - | def __exit__(self,et,ev,tb): |
| 10 | + | def __exit__(self,et,ev,tb): |
| 11 | - | self.cursor.close() |
| 11 | + | self.cursor.close() |
| 12 | - | self.con.commit() |
| 12 | + | self.con.commit() |
| 13 | - | def __init__(self): |
| 13 | + | def __init__(self): |
| 14 | - | self.connection = sqlite.connect("hours.sql") |
| 14 | + | self.connection = sqlite.connect("hours.sql")
|
| 15 | - | self.connection.row_factory = sqlite.Row |
| 15 | + | self.connection.row_factory = sqlite.Row |
| 16 | - | def cursor(self):return self.CursorInstance(self.connection) |
| 16 | + | def cursor(self):return self.CursorInstance(self.connection) |
| 17 | - | def __enter__(self): |
| 17 | + | def __enter__(self): |
| 18 | - | with self.cursor() as cursor: |
| 18 | + | with self.cursor() as cursor: |
| 19 | - | jq = """CREATE TABLE if not exists "jobs" ( |
| 19 | + | jq = """CREATE TABLE if not exists "jobs" ( |
| 20 | - | "id" INTEGER PRIMARY KEY AUTOINCREMENT, |
| 20 | + | "id" INTEGER PRIMARY KEY AUTOINCREMENT, |
| 21 | - | "name" TEXT NOT NULL |
| 21 | + | "name" TEXT NOT NULL |
| 22 | - | )""" |
| 22 | + | )""" |
| 23 | - | sq = """CREATE TABLE if not exists shifts ( |
| 23 | + | sq = """CREATE TABLE if not exists shifts ( |
| 24 | - | "job" INTEGER NOT NULL, |
| 24 | + | "job" INTEGER NOT NULL, |
| 25 | - | "minutes" TEXT NOT NULL, |
| 25 | + | "minutes" TEXT NOT NULL, |
| 26 | - | "date" DATE |
| 26 | + | "date" DATE default (date('now','localtime'))
|
| 27 | - | )""" |
| 27 | + | )""" |
| 28 | - | wq = """REATE TABLE if not exists"wages" ( |
| 28 | + | wq = """REATE TABLE if not exists"wages" ( |
| 29 | - | "job" INTEGER NOT NULL, |
| 29 | + | "job" INTEGER NOT NULL, |
| 30 | - | "wage" INTEGER NOT NULL, |
| 30 | + | "wage" INTEGER NOT NULL, |
| 31 | - | "start" DATE default (date('now','localtime')) |
| 31 | + | "start" DATE default (date('now','localtime'))
|
| 32 | - | )""" |
| 32 | + | )""" |
| 33 | - | asv = """CREATE VIEW if not exists "active_shifts" AS select |
| 33 | + | asv = """CREATE VIEW if not exists "active_shifts" AS select |
| 34 | - | sum(shifts.minutes) / 60.0 as 'hours', |
| 34 | + | sum(shifts.minutes) / 60.0 as 'hours', |
| 35 | - | shifts.job as 'job' |
| 35 | + | shifts.job as 'job' |
| 36 | - | from shifts |
| 36 | + | from shifts |
| 37 | - | where shifts.date >= date('now','start of month') |
| 37 | + | where shifts.date >= date('now','start of month')
|
| 38 | - | and shifts.date < date('now','start of month',"+1 month") |
| 38 | + | and shifts.date < date('now','start of month',"+1 month")
|
| 39 | - | group by(shifts.job) |
| 39 | + | group by(shifts.job) |
| 40 | - | """ |
| 40 | + | """ |
| 41 | - | epv = """CREATE VIEW "expected_pay" AS select |
| 41 | + | epv = """CREATE VIEW "expected_pay" AS select |
| 42 | - | (select jobs.name from jobs where jobs.id==active_shifts.job) as 'job', |
| 42 | + | (select jobs.name from jobs where jobs.id==active_shifts.job) as 'job', |
| 43 | - | active_shifts.hours as 'hours', |
| 43 | + | active_shifts.hours as 'hours', |
| 44 | - | (select wages.wage from wages where wages.job==active_shifts.job) |
| 44 | + | (select wages.wage from wages where wages.job==active_shifts.job) |
| 45 | - | * active_shifts.hours as 'expected_pay' |
| 45 | + | * active_shifts.hours as 'expected_pay' |
| 46 | - | from active_shifts |
| 46 | + | from active_shifts |
| 47 | - | """ |
| 47 | + | """ |
| 48 | - | cursor(jq) |
| 48 | + | cursor(jq) |
| 49 | - | cursor(sq) |
| 49 | + | cursor(sq) |
| 50 | - | cursor(wq) |
| 50 | + | cursor(wq) |
| 51 | - | cursor(asv) |
| 51 | + | cursor(asv) |
| 52 | - | cursor(epv) |
| 52 | + | cursor(epv) |
| 53 | - | return self |
| 53 | + | return self |
| 54 | - | def __exit__(self,et,eb,tb): |
| 54 | + | def __exit__(self,et,eb,tb): |
| 55 | - | self.connection.commit() |
| 55 | + | self.connection.commit() |
| 56 | - | def add_job(self, name, wage): |
| 56 | + | def add_job(self, name, wage): |
| 57 | - | with self.cursor() as cursor: |
| 57 | + | with self.cursor() as cursor: |
| 58 | - | cursor("insert into jobs(name) values(?)",(name,)) |
| 58 | + | cursor("insert into jobs(name) values(?)",(name,))
|
| 59 | - | cursor("insert into wages(job,wage) values(last_insert_rowid(),?)",(wage,)) |
| 59 | + | cursor("insert into wages(job,wage) values(last_insert_rowid(),?)",(wage,))
|
| 60 | - | def job_id(self, name): |
| 60 | + | def job_id(self, name): |
| 61 | - | with self.cursor() as cursor: |
| 61 | + | with self.cursor() as cursor: |
| 62 | - | q="select id from jobs where name like ?" |
| 62 | + | q="select id from jobs where name like ?" |
| 63 | - | r=[row['id']for row in cursor(q,(name,))] |
| 63 | + | r=[row['id']for row in cursor(q,(name,))] |
| 64 | - | if len(r)>1:return r |
| 64 | + | if len(r)>1:return r |
| 65 | - | return r[0] if len(r)>0 else None |
| 65 | + | return r[0] if len(r)>0 else None |
| 66 | - | def log_time(self, job, minutes): |
| 66 | + | def log_time(self, job, minutes): |
| 67 | - | with self.cursor() as cursor: |
| 67 | + | with self.cursor() as cursor: |
| 68 | - | if isinstance(job,str): |
| 68 | + | if isinstance(job,str): |
| 69 | - | jt=self.job_id(job) |
| 69 | + | jt=self.job_id(job) |
| 70 | - | if jt is None: |
| 70 | + | if jt is None: |
| 71 | - | raise RuntimeError("No such job as '{}'".format(job)) |
| 71 | + | raise RuntimeError("No such job as '{}'".format(job))
|
| 72 | - | job=jt |
| 72 | + | job=jt |
| 73 | - | q="insert into shifts(job,minutes) values(?,?)" |
| 73 | + | q="insert into shifts(job,minutes) values(?,?)" |
| 74 | - | cursor(q,(job,minutes)) |
| 74 | + | cursor(q,(job,minutes)) |
| 75 | - | def wage_report(self): |
| 75 | + | def wage_report(self): |
| 76 | - | q="select * from expected_pay" |
| 76 | + | q="select * from expected_pay" |
| 77 | - | with self.cursor() as cursor: |
| 77 | + | with self.cursor() as cursor: |
| 78 | - | for row in cursor(q): |
| 78 | + | for row in cursor(q): |
| 79 | - | yield (row['job'],row['hours'],row['expected_pay']) |
| 79 | + | yield (row['job'],row['hours'],row['expected_pay']) |
| 80 | - | |
| 80 | + | |
| 81 | - | class Main(argparse.ArgumentParser): |
| 81 | + | class Main(argparse.ArgumentParser): |
| 82 | - | def __init__(self): |
| 82 | + | def __init__(self): |
| 83 | - | d="Hour Logging" |
| 83 | + | d="Hour Logging" |
| 84 | - | super().__init__(description=d) |
| 84 | + | super().__init__(description=d) |
| 85 | - | self.tracker = None |
| 85 | + | self.tracker = None |
| 86 | - | self.add_argument('--display', dest="mode", action='store_const', |
| 86 | + | self.add_argument('--display', dest="mode", action='store_const',
|
| 87 | - | help="Displays expected payments from all jobs for this month.", |
| 87 | + | help="Displays expected payments from all jobs for this month.", |
| 88 | - | const=self.display_wages, default=self.log_minutes) |
| 88 | + | const=self.display_wages, default=self.log_minutes) |
| 89 | - | self.add_argument('--time', dest='time', action='store',type=int, default="0") |
| 89 | + | self.add_argument('--time', dest='time', action='store',type=int, default="0")
|
| 90 | - | self.add_argument('--job', dest='job', action='store', default=None) |
| 90 | + | self.add_argument('--job', dest='job', action='store', default=None)
|
| 91 | - | self.add_argument("--hire", dest='mode', action='store_const', |
| 91 | + | self.add_argument("--hire", dest='mode', action='store_const',
|
| 92 | - | const=self.get_hired, default=self.log_minutes) |
| 92 | + | const=self.get_hired, default=self.log_minutes) |
| 93 | - | self.add_argument("--wage", dest="wage", action='store', default="7.25", type=float) |
| 93 | + | self.add_argument("--wage", dest="wage", action='store', default="7.25", type=float)
|
| 94 | - | def __enter__(self): |
| 94 | + | def __enter__(self): |
| 95 | - | self.tracker = HourTracker() |
| 95 | + | self.tracker = HourTracker() |
| 96 | - | return self |
| 96 | + | return self |
| 97 | - | def __exit__(self,et,ev,tb):pass |
| 97 | + | def __exit__(self,et,ev,tb):pass |
| 98 | - | def __call__(self): |
| 98 | + | def __call__(self): |
| 99 | - | ns = self.parse_args() |
| 99 | + | ns = self.parse_args() |
| 100 | - | return ns.mode(ns) |
| 100 | + | return ns.mode(ns) |
| 101 | - | def display_wages(self,parsed): |
| 101 | + | def display_wages(self,parsed): |
| 102 | - | job = parsed.job |
| 102 | + | job = parsed.job |
| 103 | - | report = self.tracker.wage_report() |
| 103 | + | report = self.tracker.wage_report() |
| 104 | - | job = job.lower() if isinstance(job,str) else None |
| 104 | + | job = job.lower() if isinstance(job,str) else None |
| 105 | - | s = "Currently expecting {:.4n}$ from {} after {:.3n} hours." |
| 105 | + | s = "Currently expecting {:.4n}$ from {} after {:.3n} hours."
|
| 106 | - | for rjob, hours, pay in report: |
| 106 | + | for rjob, hours, pay in report: |
| 107 | - | if (job is not None and job==rjob.lower()) or job is None: |
| 107 | + | if (job is not None and job==rjob.lower()) or job is None: |
| 108 | - | print(s.format(pay, rjob, hours)) |
| 108 | + | print(s.format(pay, rjob, hours)) |
| 109 | - | def log_minutes(self, parsed): |
| 109 | + | def log_minutes(self, parsed): |
| 110 | - | job, time = parsed.job, parsed.time |
| 110 | + | job, time = parsed.job, parsed.time |
| 111 | - | if job is not None and time > 0: |
| 111 | + | if job is not None and time > 0: |
| 112 | - | self.tracker.log_time(job,time) |
| 112 | + | self.tracker.log_time(job,time) |
| 113 | - | print("Successfully logged {} minutes for {}".format(time,job)) |
| 113 | + | print("Successfully logged {} minutes for {}".format(time,job))
|
| 114 | - | def get_hired(self, parsed): |
| 114 | + | def get_hired(self, parsed): |
| 115 | - | job,wage = parsed.job,parsed.wage |
| 115 | + | job,wage = parsed.job,parsed.wage |
| 116 | - | s = "Successfully added {} to jobs index, setting wage to {:.4}$" |
| 116 | + | s = "Successfully added {} to jobs index, setting wage to {:.4}$"
|
| 117 | - | if job is not None: |
| 117 | + | if job is not None: |
| 118 | - | self.tracker.add_job(job,wage) |
| 118 | + | self.tracker.add_job(job,wage) |
| 119 | - | print(s.format(job,wage)) |
| 119 | + | print(s.format(job,wage)) |
| 120 | - | |
| 120 | + | |
| 121 | - | if __name__=="__main__": |
| 121 | + | if __name__=="__main__": |
| 122 | with Main() as prog:prog() |