Changes in / [12:73483c3145ff:11:30241f3a03eb] in stamper
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
bin/stamps
r10 r3 1 1 #!/usr/bin/env python 2 2 3 import argparse3 import sys 4 4 from stamper import Stamper 5 6 7 def usage(name): 8 msg = """ 9 Usage: 10 11 To gather information of recorded times: %(name)s 12 13 Recorded times for a given customer: %(name)s customer 14 15 Detailed times for a given customer: %(name)s customer details 16 """ % {'name': name} 17 print(msg) 5 18 6 19 7 20 if __name__ == '__main__': 8 21 9 parser = argparse.ArgumentParser(10 description='stamps: show recorded times information')11 parser.add_argument('customer', action="store", nargs='?',12 help='Show times only for this customer')13 parser.add_argument('filter', action="store", nargs='?',14 help='Filter the times by date range')15 parser.add_argument('-v', '--verbose', action="store_true",16 help='Include detailed times information')17 18 args = parser.parse_args()19 20 22 s = Stamper() 21 23 s.load_stamps() 22 s.show_stamps(args.customer, args.filter, args.verbose) 24 25 if len(sys.argv) == 1: 26 totals = s.totals() 27 print('Total times for all customers:') 28 for t in totals: 29 print(' -> %(customer)s: %(total)s' % {'customer': t, 30 'total': totals[t]}) 31 elif len(sys.argv) == 2: 32 if sys.argv[1] in s.customers(): 33 print('Total time for %(customer)s: %(total)s' % { 34 'customer': sys.argv[1], 35 'total': s.total_by_customer(sys.argv[1]) 36 }) 37 38 elif len(sys.argv) == 3: 39 if sys.argv[1] in s.customers(): 40 print('Detailed time for %(customer)s' % { 41 'customer': sys.argv[1], 42 }) 43 details, totals = s.details_by_customer(sys.argv[1]) 44 for day in details: 45 print('------ %(day)s ------' % {'day': day}) 46 for line in details[day]: 47 print(line) 48 print(' Total: %(total)s' % {'total': totals[day]}) 49 50 else: 51 usage(sys.argv[0]) 52 sys.exit(1) -
stamper/stamper.py
r9 r0 1 1 2 2 import json 3 import re4 3 from datetime import datetime, timedelta 5 4 from os.path import expanduser, exists 6 7 5 8 6 STAMPS_FILE = expanduser('~/.workstamps.json') … … 51 49 return worktime.seconds 52 50 53 def validate_filter(self, stamp_filter):54 """55 Validate a given filter. Filters can have the following notation:56 57 - %Y-%m-%d--%Y-%m-%d: Times recorded between two dates58 59 - -%Y-%m-%d: Times recorded before a given date60 61 - +%Y-%m-%d: Times recorded after a given date62 63 - N...N[d|w|m|y]: Times recorded N...N days/weeks/months/years ago64 """65 # First try the date filters, one by one66 matches = ['%Y-%m-%d', '-%Y-%m-%d', '+%Y-%m-%d']67 for match in matches:68 try:69 if '--' in stamp_filter:70 filter_from, filter_to = stamp_filter.split('--')71 filter_from = datetime.strptime(stamp_filter, match)72 filter_to = datetime.strptime(stamp_filter, match)73 else:74 valid_filter = datetime.strptime(stamp_filter, match)75 except ValueError:76 pass77 else:78 return stamp_filter79 80 valid_filter = re.search(r'(\d+[dwmyDWMY]{1})', stamp_filter)81 if valid_filter:82 return stamp_filter83 84 # Not a valid filter85 return None86 87 51 def customers(self): 88 52 customers = [] … … 93 57 return customers 94 58 95 def totals(self, stamp_filter=None): 59 def total_by_customer(self, customer): 60 total = 0 61 for stamp in self.stamps: 62 if stamp['customer'] == customer: 63 total += self.worktime(stamp['start'], stamp['end']) 64 total = timedelta(seconds=total) 65 return str(total) 66 67 def totals(self): 96 68 totals = {} 97 for stamp in self.stamps: 98 customer = stamp['customer'] 99 if customer: 100 # c will be None for "start" stamps, having no end time 101 if customer not in totals: 102 totals[customer] = 0 103 totals[customer] += self.worktime(stamp['start'], stamp['end']) 69 for customer in self.customers(): 70 totals[customer] = self.total_by_customer(customer) 104 71 return totals 105 106 def details(self):107 details = {}108 totals = {}109 for stamp in self.stamps:110 if stamp['customer']:111 # avoid "start" stamps112 start_day = stamp['start'].split(' ')[0]113 if start_day not in details:114 details[start_day] = []115 if start_day not in totals:116 totals[start_day] = 0117 worktime = self.worktime(stamp['start'], stamp['end'])118 details[start_day].append(119 ' -> %(worktime)s %(customer)s %(action)s' % {120 'worktime': str(timedelta(seconds=worktime)),121 'customer': stamp['customer'],122 'action': stamp['action']123 })124 totals[start_day] += worktime125 for day in totals:126 totals[day] = str(timedelta(seconds=totals[day]))127 return details, totals128 72 129 73 def details_by_customer(self, customer): … … 148 92 totals[day] = str(timedelta(seconds=totals[day])) 149 93 return details, totals 150 151 def show_stamps(self, customer=None, stamp_filter=None, verbose=False):152 if stamp_filter:153 stamp_filter = self.validate_filter(stamp_filter)154 155 totals = self.totals(stamp_filter)156 157 if customer:158 total = timedelta(seconds=totals.get(customer, 0))159 print(' %(customer)s: %(total)s' % {'customer': customer,160 'total': total})161 else:162 for c in totals:163 total = timedelta(seconds=totals[c])164 print(' %(customer)s: %(total)s' % {'customer': c,165 'total': total})166 167 if verbose:168 if customer:169 details, totals = self.details_by_customer(customer)170 else:171 details, totals = self.details()172 for day in details:173 print('------ %(day)s ------' % {'day': day})174 for line in details[day]:175 print(line)176 print(' Total: %(total)s' % {'total': totals[day]})
Note:
See TracChangeset
for help on using the changeset viewer.