def commit_main(args): # commits are NOT handled by argparse. `args` are passed to this function # as they are from sys.argv. u = User() invid = u.active_invoice_rowid if invid == 0: fprintf( "GITIME ERROR: You do not have an active invoice set. " "You won't be able to record your hours without one. " "Create an invoice with the command: `gitime invoice -n <invoice " "name>` first. Your commit has NOT been made.", file=sys.stderr) sys.exit() inv = Invoice(invid) raw_hours = parse_hours_flag(args) if raw_hours is not False: hours = round(raw_hours / inv.rounding) * inv.rounding else: hours = u.time_tracked(inv) if hours <= 0: fprintf( "GITIME ERROR: You didn't specify a number of hours, and the " "timer hasn't recorded anything. Run this command with the " "`--hours <hour count>` flag, or use the timer to track your " "time. Your commit has NOT been made."), file=sys.stderr) sys.exit() u.reset_timer() message = parse_commit_message(args) if not message: fprintf("GITIME ERROR: Could not find a message in your commit.", file=sys.stderr) sys.exit()
def timer_main(args): u = User() if not args.force: if u.active_invoice_rowid == 0: fprintf( "WARNING: You do not have an active invoice set. " "You won't be able to record your hours without one. " "Create an invoice with the command: `gitime invoice -n " "<invoice name>` first, or suppress this warning by running " "the timer with the --force flag.", file=sys.stderr) sys.exit() if args.action == 'start': u.start_timer() fprintf('Timer started at %s' %str(datetime.now())) elif args.action == 'pause': u.pause_timer() fprintf('Timer paused at %s' %str(datetime.now())) elif args.action == 'reset': u.reset_timer() elif args.action == 'status': inv = Invoice(u.active_invoice_rowid) if u.timer_running: status = 'has been running since %s.' %str( datetime.fromtimestamp(u.timer_start)) else: status = 'is not running.' fprintf('The timer %s' %status) fprintf('Total hours tracked: %.2f' %(u.time_tracked(inv)))
def settings_main(args): u = User() if hasattr(args, 'rate'): u.set_rate(args.rate) fprintf("The rate of $%s per hour will be applied to all new invoices." %args.rate) if hasattr(args, 'round'): u.set_rounding(args.round) fprintf("Hours will be rounded to the nearest %s on all new invoices" %args.round) if args.list: fprintf(textwrap.dedent("""\ Your default values for all invoices created in the future: Hourly Rate: $%.2f Round hours to the nearest %g""" %(u.rate, u.rounding)))
def __init__(self, unique, new=False, rate=None, rounding=None, userid=1): """ Invoices can be instantiated from a rowid or a name. If the name isn't already in the database a new one will be created if `new` is true. Otherwise the program halts. If instantiated from a rowid, using a rowid that does not exist will throw an exception. `rate` and `rounding` args unnecessary if querying by rowid. `rate` and `rounding` default to user values. """ self.user = User(userid) meta = db.query_invoice(unique) if meta: if new: print("An invoice with the name %s already exists. You can't " "make a new one with that name." %unique, file=sys.stderr) sys.exit() self.name = meta[0] self.rate = meta[1] self.rounding = meta[2] self.rowid = meta[3] if len(meta) == 4 else unique else: # this will only happen if `unique` is a name # if `unique` is a rowid, an exception is raised # on the query. if not new: raise InvoiceNotFound self.name = unique if rate is None and self.user.rate == 0: fprintf("WARNING: Your default hourly rate is set to zero. This" " means that no earnings will be recorded. You can set your" " default rate with `gitime set -r <rate>` or set the rate " "for this invoice with `gitime invoice <invoice name> -r " "<rate>`.") self.rate = rate if rate is not None else self.user.rate self.rounding = (rounding if rounding is not None else self.user.rounding) self.rowid = db.insert_invoice(self.name, self.rate, self.rounding)
class Invoice(object): def __init__(self, unique, new=False, rate=None, rounding=None, userid=1): """ Invoices can be instantiated from a rowid or a name. If the name isn't already in the database a new one will be created if `new` is true. Otherwise the program halts. If instantiated from a rowid, using a rowid that does not exist will throw an exception. `rate` and `rounding` args unnecessary if querying by rowid. `rate` and `rounding` default to user values. """ self.user = User(userid) meta = db.query_invoice(unique) if meta: if new: print("An invoice with the name %s already exists. You can't " "make a new one with that name." %unique, file=sys.stderr) sys.exit() self.name = meta[0] self.rate = meta[1] self.rounding = meta[2] self.rowid = meta[3] if len(meta) == 4 else unique else: # this will only happen if `unique` is a name # if `unique` is a rowid, an exception is raised # on the query. if not new: raise InvoiceNotFound self.name = unique if rate is None and self.user.rate == 0: fprintf("WARNING: Your default hourly rate is set to zero. This" " means that no earnings will be recorded. You can set your" " default rate with `gitime set -r <rate>` or set the rate " "for this invoice with `gitime invoice <invoice name> -r " "<rate>`.") self.rate = rate if rate is not None else self.user.rate self.rounding = (rounding if rounding is not None else self.user.rounding) self.rowid = db.insert_invoice(self.name, self.rate, self.rounding) def set_active(self): self.user.set_active_invoice(self.rowid) def set_rate(self, r): try: r = float(r) except ValueError: fprintf('Rates must be provided in the form of a number.', file=sys.stderr) sys.exit() self.rate = r db.update(lambda c: c.execute(""" UPDATE invoice SET rate=? WHERE rowid=? """, (self.rate, self.rowid))) def set_rounding(self, r): try: r = float(r) except ValueError: fprintf( 'Rounding numbers must be provided in the form of a number.', file=sys.stderr) sys.exit() self.rounding = r db.update(lambda c: c.execute(""" UPDATE invoice SET rounding=? WHERE rowid=? """, (self.rounding, self.rowid))) def get_commit_meta(self): return db.query_invoice_commit_meta(self.rowid) def total_hours(self): commits = self.get_commit_meta() return sum(commit[2] for commit in commits) def total_earnings(self): return self.total_hours() * self.rate