]> git.walde.dev - punch/commitdiff
Add full day visualization
authorDustin Walde <redacted>
Fri, 5 May 2023 22:57:15 +0000 (15:57 -0700)
committerDustin Walde <redacted>
Fri, 5 May 2023 22:57:15 +0000 (15:57 -0700)
Maps pixels to time of day, instead of only combining punched in times.

src/image_generator.py
src/punch.py

index f034c024d3bba16215cce353f25d0a07f825ad3b..1898ed4c91d9a63870fa16a6b809f62935448388 100644 (file)
@@ -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)
index 2f5174ee74887b8caec58a8ba471fdd934da819d..3a7448a942dac6b217b1e5bd30a2adb015ac2f65 100644 (file)
@@ -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':