timelog

GTimeLog compatible command line tools
git clone https://git.ce9e.org/timelog.git

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   188 
  172    -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 = 30
  177    -1 	WORKHOURS_PER_WEEK = 35
  178   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    -1 
  208    -1 	def day(entry):
  209    -1 		return entry['dt'].strftime('%Y-%m-%d')
  210    -1 
  211    -1 	x = timedelta()
  212    -1 	last = None
  213    -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    -1 
  219    -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   271 
  231    -1 	q = Query(ll)
  232    -1 	q.month(offset=-3)
  233    -1 
  234    -1 	for line in q.all():
  235    -1 		print(line)
  236    -1 
  237    -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    -1 
  245    -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))