- commit
- a03f441be93ea5e0cfeb4757f75cce7351393ea1
- parent
- 15a3961ec0381892095deaaf9c096a0aa7449f3f
- Author
- Tobias Bengfort <tobias.bengfort@gmx.net>
- Date
- 2014-01-18 18:00
add cli and clean up
Diffstat
| R | parser.py -> timelog_view.py | 146 | ++++++++++++++++++++++++++++++++++++++++++------------------- |
1 files changed, 101 insertions, 45 deletions
diff --git a/parser.py b/timelog_view.py
@@ -1,5 +1,22 @@1 -1 """Parse timelog files, filter the lines and output interesting data"""2 -1-1 1 #!/usr/bin/env python3 -1 2 -1 3 # Parse timelog files, filter the lines and output interesting data -1 4 # Copyright (C) 2014 Tobias Bengfort <tobias.bengfort@gmx.net> -1 5 # -1 6 # This program is free software: you can redistribute it and/or modify -1 7 # it under the terms of the GNU General Public License as published by -1 8 # the Free Software Foundation, either version 3 of the License, or -1 9 # (at your option) any later version. -1 10 # -1 11 # This program is distributed in the hope that it will be useful, -1 12 # but WITHOUT ANY WARRANTY; without even the implied warranty of -1 13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -1 14 # GNU General Public License for more details. -1 15 # -1 16 # You should have received a copy of the GNU General Public License -1 17 # along with this program. If not, see <http://www.gnu.org/licenses/>. -1 18 -1 19 import argparse 3 20 from datetime import datetime, timedelta 4 21 5 22 EMPTY_LINE = object() @@ -78,7 +95,7 @@ def timedelta2str(delta): 78 95 seconds = delta.total_seconds() 79 96 minutes, seconds = divmod(seconds, 60) 80 97 hours, minutes = divmod(minutes, 60)81 -1 return "{}:{:0=2}:{:0=2}".format(int(hours), int(minutes), int(seconds))-1 98 return "{: =3}:{:0=2}".format(int(hours), int(minutes)) 82 99 83 100 84 101 class Query: @@ -136,7 +153,7 @@ class Query: 136 153 self.before(datetime_add(start, years=offset + 1)) 137 154 138 155 def all(self):139 -1 return (self.timelog[i] for i in self.data)-1 156 return tuple(self.timelog[i] for i in self.data) 140 157 141 158 142 159 """extract information""" @@ -169,12 +186,12 @@ class Extractor: 169 186 return d 170 187 171 188172 -1 """Feiertage"""-1 189 """Holidays""" 173 190 class ExpectedHoursPer: 174 191 WORKDAYS_PER_WEEK = 5 -1 192 WORKHOURS_PER_WEEK = 35 175 193 HOLIDAYS_PER_YEAR = 9 176 194 VACATION_DAYS_PER_YEAR = 30177 -1 WORKHOURS_PER_WEEK = 35178 195 179 196 @classmethod 180 197 def day(cls): @@ -193,55 +210,94 @@ class ExpectedHoursPer: 193 210 return int(cls.day() * cls._workdays_per_year()) 194 211 195 212 @classmethod -1 213 def days(cls, n): -1 214 """interpolation between day and year""" -1 215 from math import exp -1 216 f = lambda x: 2 / (1 + exp(-x / 7) / exp(-1 / 7)) - 1 -1 217 d1 = cls.day() -1 218 d2 = cls.year() / 365 -1 219 fn = f(n) -1 220 d = (1-fn) * d1 + fn * d2 -1 221 return d * n -1 222 -1 223 @classmethod 196 224 def _workdays_per_year(cls): 197 225 return ((365 - cls.HOLIDAYS_PER_YEAR) * cls.WORKDAYS_PER_WEEK / 7 198 226 - cls.VACATION_DAYS_PER_YEAR) 199 227 200 228 201 229 """cli"""202 -1 def timelog2csv():203 -1 f = open('timelog.txt')204 -1 l = [line.strip() for line in f.readlines() if line.strip()]205 -1 ll = LazyTimelog(l)206 -1 f.close()207 -1208 -1 def day(entry):209 -1 return entry['dt'].strftime('%Y-%m-%d')210 -1211 -1 x = timedelta()212 -1 last = None213 -1 for entry in ll:214 -1 if last is not None:215 -1 if day(last) != day(entry):216 -1 print('"%s","%s"' % (day(last), int(x.total_seconds() / 3600)))217 -1 x = timedelta()218 -1219 -1 if '**' not in entry['comment']:220 -1 x += entry['dt'] - last['dt']221 -1 last = entry-1 230 #def timelog2csv(): -1 231 # f = open('timelog.txt') -1 232 # l = [line.strip() for line in f.readlines() if line.strip()] -1 233 # data = LazyTimelog(l) -1 234 # f.close() -1 235 # -1 236 # def day(entry): -1 237 # return entry['dt'].strftime('%Y-%m-%d') -1 238 # -1 239 # x = timedelta() -1 240 # last = None -1 241 # for entry in data: -1 242 # if last is not None: -1 243 # if day(last) != day(entry): -1 244 # print('"%s","%s"' % (day(last), int(x.total_seconds() / 3600))) -1 245 # x = timedelta() -1 246 # -1 247 # if '**' not in entry['comment']: -1 248 # x += entry['dt'] - last['dt'] -1 249 # last = entry 222 250 223 251 224 252 if __name__ == '__main__':225 -1 """226 -1 f = open('timelog.txt')-1 253 parser = argparse.ArgumentParser( -1 254 description='extract interesting data from timelogs') -1 255 parser.add_argument('file') -1 256 parser.add_argument('-d', '--day', nargs='?', const=0, type=int, -1 257 help="show entries from today or DAY days ago") -1 258 parser.add_argument('-w', '--week', nargs='?', const=0, type=int, -1 259 help="show entries from this week or WEEK weeks ago") -1 260 parser.add_argument('-m', '--month', nargs='?', const=0, type=int, -1 261 help="show entries from this month or MONTH months ago") -1 262 parser.add_argument('-y', '--year', nargs='?', const=0, type=int, -1 263 help="show entries from this year or YEAR years ago") -1 264 args = parser.parse_args() -1 265 -1 266 # load data from file -1 267 f = open(args.file) 227 268 l = [line.strip() for line in f.readlines() if line.strip()]228 -1 ll = LazyTimelog(l)-1 269 data = LazyTimelog(l) 229 270 f.close() 230 271231 -1 q = Query(ll)232 -1 q.month(offset=-3)233 -1234 -1 for line in q.all():235 -1 print(line)236 -1237 -1 ex = Extractor(q.all())238 -1-1 272 # filter -1 273 q = Query(data) -1 274 if args.day is not None: -1 275 q.day(offset=-args.day) -1 276 expected = ExpectedHoursPer.day() -1 277 elif args.week is not None: -1 278 q.week(offset=-args.week) -1 279 expected = ExpectedHoursPer.week() -1 280 elif args.month is not None: -1 281 q.month(offset=-args.month) -1 282 expected = ExpectedHoursPer.month() -1 283 elif args.year is not None: -1 284 q.year(offset=-args.year) -1 285 expected = ExpectedHoursPer.year() -1 286 else: -1 287 expected = ExpectedHoursPer.days( -1 288 (data[-1]['dt'] - data[0]['dt']).total_seconds() / 3600 / 24) -1 289 data = q.all() -1 290 -1 291 ex = Extractor(data) -1 292 -1 293 # output by comment 239 294 by_comment = ex.by_comment()240 -1 l = max(len(k) for k in by_comment.keys())241 -1 for comment, delta in by_comment.items():242 -1 print(comment + (l + 2 - len(comment)) * ' ' + timedelta2str(delta))243 -1 print(timedelta2str(ex.sum()))244 -1245 -1 print(ExpectedHoursPer.month())246 -1 """247 -1 timelog2csv()-1 295 if len(by_comment) > 0: -1 296 l = max(len(k) for k in by_comment.keys()) -1 297 for comment, delta in sorted(by_comment.items(), key=lambda a: a[1]): -1 298 print(comment + (l + 1 - len(comment)) * ' ' + timedelta2str(delta)) -1 299 print() -1 300 -1 301 # output total workhours -1 302 done = int(ex.sum().total_seconds() / 3600) -1 303 print("Total workhours done: %i (%i extra)" % (done, done - expected))