comparison scripts/getan-report.py @ 387:0fd096670ae7

Update coding style for pep8
author Björn Ricks <bjoern.ricks@intevation.de>
date Mon, 26 Jan 2015 13:09:52 +0100
parents 7a63212924c3
children 9d4a8f7da935
comparison
equal deleted inserted replaced
386:b8cd8751cba0 387:0fd096670ae7
1 #!/usr/bin/env python3 1 #!/usr/bin/env python3
2 """write a daily report accessing a database from http://hg.intevation.de/getan 1.1dev3.""" 2 """
3 write a daily report accessing a database from
4 http://hg.intevation.de/getan 1.1dev3.
5 """
3 # hastily done, written to learn the getan database format and its manipulation 6 # hastily done, written to learn the getan database format and its manipulation
4 # Free Software under GNU GPL v>=3 7 # Free Software under GNU GPL v>=3
5 # 20130109 bernhard@intevation.de 8 # 20130109 bernhard@intevation.de
6 # 20140103 bernhard@intevation.de: 9 # 20140103 bernhard@intevation.de:
7 # started from 2013/getan-writeout-timesorted.py 10 # started from 2013/getan-writeout-timesorted.py
11 # Total time output format improved. 14 # Total time output format improved.
12 # 20140120 bernhard@intevation.de: 15 # 20140120 bernhard@intevation.de:
13 # added command line options, requires argparse module now (e.g. Python>=3.2) 16 # added command line options, requires argparse module now (e.g. Python>=3.2)
14 # 20141104 bernhard@intevation.de: 17 # 20141104 bernhard@intevation.de:
15 # migration to argparse complete, added -t option 18 # migration to argparse complete, added -t option
16 # TODO: 19 # TODO:
17 # * use python v>=3.2 variants in the code where noted. 20 # * use python v>=3.2 variants in the code where noted.
18 21
19 import argparse 22 import argparse
20 import datetime 23 import datetime
21 import logging 24 import logging
22 import sqlite3 25 import sqlite3
23 import sys
24 26
25 factor = {'privat' : 0} 27 factor = {'privat': 0}
26 28
27 l = logging 29 l = logging
28 l.basicConfig(level=logging.INFO, 30 l.basicConfig(level=logging.INFO,
29 #l.basicConfig(level=logging.DEBUG, 31 # l.basicConfig(level=logging.DEBUG,
30 format='%(message)s') 32 format='%(message)s')
31 # format='%(asctime)s %(levelname)s %(message)s') 33 # format='%(asctime)s %(levelname)s %(message)s')
34
32 35
33 def hhhmm_from_timedelta(td): 36 def hhhmm_from_timedelta(td):
34 """Return a string '-HHH:MM' from the timedelta parameter. 37 """Return a string '-HHH:MM' from the timedelta parameter.
35 38
36 Accounts for way the integer division works for negative numbers: 39 Accounts for way the integer division works for negative numbers:
37 -2 // 60 == -1 40 -2 // 60 == -1
38 -2 % 60 == 58 41 -2 % 60 == 58
39 by first working on the positive number and then adding the minus 42 by first working on the positive number and then adding the minus
40 to the string. 43 to the string.
41 44
42 For python >=3.1. Successor of hhmm_from_timedelta() from 45 For python >=3.1. Successor of hhmm_from_timedelta() from
43 http://intevation.de/cgi-bin/viewcvs-misc.cgi/worklog.py/ . 46 http://intevation.de/cgi-bin/viewcvs-misc.cgi/worklog.py/ .
44 """ 47 """
45 total_minutes = abs(round(td.days*24*60 + td.seconds/60)) 48 total_minutes = abs(round(td.days * 24 * 60 + td.seconds / 60))
46 # variant for Python v>3.2: 49 # variant for Python v>3.2:
47 #total_minutes = abs(round(td/datetime.timedelta(minutes=1))) 50 # total_minutes = abs(round(td/datetime.timedelta(minutes=1)))
48 51
49 hours = total_minutes//60 52 hours = total_minutes // 60
50 minutes = total_minutes%60 53 minutes = total_minutes % 60
51 54
52 h_string = "{}".format(hours) 55 h_string = "{}".format(hours)
53 56
54 if(td.days<0): 57 if(td.days < 0):
55 h_string = "-" + h_string 58 h_string = "-" + h_string
56 59
57 return "{:>3s}:{:02d}".format(h_string, minutes) 60 return "{:>3s}:{:02d}".format(h_string, minutes)
61
58 62
59 def self_test(): 63 def self_test():
60 """Run some simple tests on hhhmm_from_timedelta(). 64 """Run some simple tests on hhhmm_from_timedelta().
61 65
62 e.g. run like 66 e.g. run like
63 python3 -c 'from getan_report_20140103 import *; self_test()' 67 python3 -c 'from getan_report_20140103 import *; self_test()'
64 """ 68 """
65 l.info(hhhmm_from_timedelta(datetime.timedelta(minutes=1))) 69 l.info(hhhmm_from_timedelta(datetime.timedelta(minutes=1)))
66 l.info(hhhmm_from_timedelta(datetime.timedelta(minutes=-2))) 70 l.info(hhhmm_from_timedelta(datetime.timedelta(minutes=-2)))
67 71
72
68 def main(): 73 def main():
69 parser = argparse.ArgumentParser(description=__doc__) 74 parser = argparse.ArgumentParser(description=__doc__)
70 parser.add_argument("-t", action='store_true', 75 parser.add_argument("-t", action='store_true',
71 help="timesorted output and default reportday to today") 76 help="timesorted output and default reportday to today")
72 parser.add_argument("dbfilename") 77 parser.add_argument("dbfilename")
73 parser.add_argument("reportday", nargs='?', 78 parser.add_argument("reportday", nargs='?',
74 help="day to report yyyy-mm-dd") 79 help="day to report yyyy-mm-dd")
75 80
76 args = parser.parse_args() 81 args = parser.parse_args()
77 l.debug(args) 82 l.debug(args)
78 83
79 if args.reportday: 84 if args.reportday:
80 report_range_start = \ 85 report_range_start = \
81 datetime.datetime.strptime(args.reportday, "%Y-%m-%d") 86 datetime.datetime.strptime(args.reportday, "%Y-%m-%d")
82 elif args.t: 87 elif args.t:
83 # start with today 00:00 88 # start with today 00:00
84 report_range_start = datetime.datetime.combine( 89 report_range_start = datetime.datetime.combine(
85 datetime.date.today(), datetime.time()) 90 datetime.date.today(), datetime.time())
86 else: 91 else:
87 # start with yesterday 00:00 92 # start with yesterday 00:00
88 report_range_start = datetime.datetime.combine( 93 report_range_start = datetime.datetime.combine(
89 datetime.date.today() - datetime.timedelta(days=1), 94 datetime.date.today() - datetime.timedelta(days=1),
90 datetime.time()) 95 datetime.time())
91 report_range_end = report_range_start + datetime.timedelta(days=1) 96 report_range_end = report_range_start + datetime.timedelta(days=1)
92 97
93
94 l.info("Opening sqlite3 database '%s'" % args.dbfilename) 98 l.info("Opening sqlite3 database '%s'" % args.dbfilename)
95 conn = sqlite3.connect(args.dbfilename, detect_types=sqlite3.PARSE_DECLTYPES|sqlite3.PARSE_COLNAMES) 99 conn = sqlite3.connect(
100 args.dbfilename,
101 detect_types=sqlite3.PARSE_DECLTYPES | sqlite3.PARSE_COLNAMES)
96 c = conn.cursor() 102 c = conn.cursor()
97 103
98 tasks = {} 104 tasks = {}
99 task_total = {} 105 task_total = {}
100 106
103 l.debug(t) 109 l.debug(t)
104 tasks[t[0]] = t[2] 110 tasks[t[0]] = t[2]
105 task_total[t[0]] = datetime.timedelta() 111 task_total[t[0]] = datetime.timedelta()
106 112
107 # from getan 1.0 20130103 113 # from getan 1.0 20130103
108 #CREATE TABLE entries ( 114 # CREATE TABLE entries (
109 # id INTEGER PRIMARY KEY AUTOINCREMENT, 115 # id INTEGER PRIMARY KEY AUTOINCREMENT,
110 # project_id INTEGER REFERENCES projects(id), 116 # project_id INTEGER REFERENCES projects(id),
111 # start_time TIMESTAMP NOT NULL, 117 # start_time TIMESTAMP NOT NULL,
112 # stop_time TIMESTAMP NOT NULL, 118 # stop_time TIMESTAMP NOT NULL,
113 # description VARCHAR(256), 119 # description VARCHAR(256),
114 # 120 #
115 # CHECK (strftime('%s', start_time) <= strftime('%s', stop_time)) 121 # CHECK (strftime('%s', start_time) <= strftime('%s', stop_time))
116 #); 122 # );
117 123
118 total_time = datetime.timedelta() 124 total_time = datetime.timedelta()
119 125
120 if args.t: 126 if args.t:
121 c.execute('select * from entries order by start_time') 127 c.execute('select * from entries order by start_time')
122 else: 128 else:
123 c.execute('select * from entries order by project_id') 129 c.execute('select * from entries order by project_id')
124 for e in c: 130 for e in c:
125 l.debug(e) 131 l.debug(e)
126 length = e[3]-e[2] 132 length = e[3] - e[2]
127 133
128 desc = tasks[e[1]] 134 desc = tasks[e[1]]
129 135
130 if e[2] >= report_range_start and e[2] < report_range_end: 136 if e[2] >= report_range_start and e[2] < report_range_end:
131 if args.t: 137 if args.t:
132 print("{2}: {3} {4}\n\t\t\t{0} {1}". 138 print("{2}: {3} {4}\n\t\t\t{0} {1}".
133 format(e[2], e[3], desc, e[4],hhhmm_from_timedelta(length))) 139 format(e[2], e[3], desc, e[4],
140 hhhmm_from_timedelta(length)))
134 else: 141 else:
135 print("{0} {2}: {3} {4}". 142 print("{0} {2}: {3} {4}".
136 format(e[2], e[3], desc, e[4],hhhmm_from_timedelta(length))) 143 format(e[2], e[3], desc, e[4],
144 hhhmm_from_timedelta(length)))
137 if desc in factor: 145 if desc in factor:
138 ##python3.1 does not allow timedelta division. 146 # python3.1 does not allow timedelta division.
139 ##TODO: Make python3.1 save or update to python3.2. 147 # TODO: Make python3.1 save or update to python3.2.
140 #l.info("applying factor %f to entry %s" % (factor[desc], e)) 148 # l.info("applying factor %f to entry %s" % (factor[desc], e))
141 #length = (length * int(factor[desc]*1000))/1000 149 # length = (length * int(factor[desc]*1000))/1000
142 #Until python3.2 we only honor a factor of zero: 150 # Until python3.2 we only honor a factor of zero:
143 if factor[desc] == 0: 151 if factor[desc] == 0:
144 length = datetime.timedelta(0) 152 length = datetime.timedelta(0)
145 l.info("not counting {}".format(e)) 153 l.info("not counting {}".format(e))
146 else: 154 else:
147 l.info("ignoring factor {}".factor[desc]) 155 l.info("ignoring factor {}".factor[desc])
This site is hosted by Intevation GmbH (Datenschutzerklärung und Impressum | Privacy Policy and Imprint)