From: Dustin Walde Date: Fri, 5 May 2023 22:57:15 +0000 (-0700) Subject: Add full day visualization X-Git-Url: https://git.walde.dev/?a=commitdiff_plain;h=4f74729bc1cadb2127ce67474974e239047cd89a;p=punch Add full day visualization Maps pixels to time of day, instead of only combining punched in times. --- diff --git a/src/image_generator.py b/src/image_generator.py index f034c02..1898ed4 100644 --- a/src/image_generator.py +++ b/src/image_generator.py @@ -70,17 +70,31 @@ def week(sheet: TimeSheet, start_date: datetime.date) -> Image.Image: for i in range(7): date = (datetime.datetime.combine(start_date, datetime.time(), tzinfo=tzi) + datetime.timedelta(days=i)).date() - #_day(sheet, img, date, (1+i*(IMAGE_SIZE+1), (i+1)*(IMAGE_SIZE+1)-1), (1, IMAGE_SIZE+1), TARGET_HOURS) - _day(sheet, img, date, (1+i*(IMAGE_SIZE), (i+1)*(IMAGE_SIZE)-1), (1, IMAGE_SIZE-1), TARGET_HOURS) + x_range = (1+i*(IMAGE_SIZE), (i+1)*IMAGE_SIZE-1) + y_range = (1, IMAGE_SIZE-1) + _day(sheet, img, date, x_range, y_range, TARGET_HOURS) #img = img.resize((IMAGE_SIZE*28+32,IMAGE_SIZE*4+8), Image.NEAREST) img = img.resize((IMAGE_SIZE*28,IMAGE_SIZE*4), Image.NEAREST) return img +def full_week(sheet: TimeSheet, start_date: datetime.date) -> Image.Image: + img = Image.new('RGBA', (1+13*7, 26), (0,0,0,0)) + tzi = datetime.datetime.now().astimezone().tzinfo + + for i in range(7): + date = (datetime.datetime.combine(start_date, datetime.time(), tzinfo=tzi) + datetime.timedelta(days=i)).date() + x_range = (1+i*13, (i+1)*13-1) + y_range = (1, 25) + _full_day(sheet, img, date, x_range, y_range) + + img = img.resize((img.width*4,img.height*4), Image.NEAREST) + return img + def _day(sheet: TimeSheet, image: Image.Image, date: datetime.date, x_range: Tuple[int,int], y_range: Tuple[int,int], - target_hours: int = 0, alpha: int = 255) -> datetime.timedelta: + target_hours: int = 8, alpha: int = 255) -> datetime.timedelta: dt = datetime.datetime.combine(date, datetime.time(), datetime.datetime.now().astimezone().tzinfo) de = dt + datetime.timedelta(days=1) tt = datetime.timedelta(0) @@ -114,8 +128,6 @@ def _day(sheet: TimeSheet, image: Image.Image, date: datetime.date, color = color[:3] + (alpha,) if not entry.is_complete: tt += datetime.datetime.now().astimezone() - max(entry.t_in, dt) - #for i in range(HOURS): - # image.putpixel((0,i), color) elif entry.t_in >= dt and entry.t_in <= de: time = min(entry.t_out, de) - entry.t_in # type: ignore tt += time @@ -131,6 +143,61 @@ def _day(sheet: TimeSheet, image: Image.Image, date: datetime.date, return ct*seg_time + tt +def full_day(sheet: TimeSheet, date: datetime.date) -> Image.Image: + img = Image.new('RGBA', (12, 24), (0,0,0,0)) + + _full_day(sheet, img, date, (0,12), (0,24)) + img = img.resize((48, 96), Image.NEAREST) + + return img + + +def _full_day(sheet: TimeSheet, image: Image.Image, date: datetime.date, + x_range: Tuple[int,int], y_range: Tuple[int,int]): + assert (y_range[1] - y_range[0]) % 24 == 0 + xlen = x_range[1] - x_range[0] + day_start = datetime.datetime.combine(date, datetime.time(), tzinfo=datetime.datetime.now().astimezone().tzinfo) + day_end = datetime.datetime.combine(date+datetime.timedelta(days=1), datetime.time(), tzinfo=datetime.datetime.now().astimezone().tzinfo) + + for x in range(*x_range): + for y in range(*y_range): + image.putpixel((x,y), (255,255,255,32)) + + y_size = int((y_range[1] - y_range[0]) / 24) + x_size = int(floor(y_size*3/2)) + # shrink until x divides evenly + while x_size > 1: + if xlen % x_size == 0: + break + x_size -= 1 + + for entry in sheet.entries: + if entry is None: + continue + if entry.t_in.date() > date: + continue + if entry.is_complete and entry.t_out.date() < date: # type: ignore + continue + + color = colstr(sheet.categories[entry.category].color) + + if entry.t_out is not None: + end = entry.t_out + else: + end = datetime.datetime.now().astimezone() + begin = max(day_start, entry.t_in) + end = min(day_end, end) + while begin < end: + t = begin.time() + y_pos = (24-y_size*(t.hour+1), 24-y_size*t.hour) + m = min(x_range[1]-1, floor(t.minute*xlen/60)) + x_pos = (m*x_size, (m+1)*x_size) + for x in range(*x_pos): + for y in range(*y_pos): + image.putpixel((x_range[0]+x,y_range[0]+y), color) + + begin += datetime.timedelta(minutes=60/xlen) + def _time_per_segment(segments: int) -> datetime.timedelta: seg_minutes = floor(60/segments) diff --git a/src/punch.py b/src/punch.py index 2f5174e..3a7448a 100644 --- a/src/punch.py +++ b/src/punch.py @@ -113,8 +113,10 @@ def main(args): if len(args) > 2: dt = date.fromisoformat(args[2]) else: - dt = date.today() - timedelta(days=7) - image = image_generator.week(sheet, dt) + dt = date.today() + #dt -= timedelta(days=1) + #image = image_generator.week(sheet, dt) + image = image_generator.full_week(sheet, dt) image.save("test.png") elif args[1] == 'query':