Live viewer now takes a screenshot once as second

This commit is contained in:
Casey 2024-07-04 15:14:24 +03:00
parent f378f15c6c
commit ebe6fab9c6
Signed by: hkc
GPG Key ID: F0F6CFE11CDB0960
4 changed files with 26 additions and 3 deletions

1
.gitignore vendored
View File

@ -12,3 +12,4 @@ logs.txt
rgb111-full.png
state-new.json
settings.json
screenshots/

BIN
astley.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

@ -59,6 +59,7 @@ class AsyncBotManager:
bits_on, bits_off, timestamp = data
if timestamp < self._last_update:
print("SKIPPING UPDATES: TOO OLD")
self._last_update: int = data["timestamp"]
for ndx in bits_on:
y, x = divmod(ndx, 1000)
self.canvas.putpixel((x, y), 255)
@ -107,7 +108,7 @@ async def amain():
mgr.font = ImageFont.truetype(settings["font"], 8)
for elem in settings["elements"]:
if elem["type"] == "text":
mgr.put_text(elem["text"], elem["x"], elem["y"])
mgr.put_text(elem["x"], elem["y"], elem["text"])
elif elem["type"] == "image":
with Image.open(elem["path"]).convert("LA") as im:
mgr.put_image(elem["x"], elem["y"], im)

View File

@ -4,10 +4,12 @@ from PIL import Image, ImageTk
from socketio import SimpleClient, exceptions
from threading import Thread
from requests import get
from datetime import datetime
COLORS = [(0x33, 0x33, 0x66), (0x96, 0x96, 0xe0)]
COLORS_UNPACKED = COLORS[0] + ((0, 0, 0) * 254) + COLORS[1]
SCREENSHOTS_TMPL = "./screenshots/%Y%m%d_%H%M%S.png"
class App(tk.Tk):
def __init__(self, url: str = "https://onemillioncheckboxes.com") -> None:
@ -22,6 +24,8 @@ class App(tk.Tk):
self._canvas.pack()
self.config(width=1000, height=1000, borderwidth=0, highlightthickness=0)
self._last_update = 0
self._running = False
self._image = Image.new("RGB", (1000, 1000), COLORS[0])
@ -38,15 +42,25 @@ class App(tk.Tk):
x, y = event.x, event.y
self.sio.emit("toggle_bit", { "index": x + y * 1000 })
def _save_image(self):
ts = datetime.fromtimestamp(self._last_update / 1000)
path = ts.strftime(SCREENSHOTS_TMPL)
print("SAVED", path)
self._image.save(path)
self.after(1000, self._save_image)
def _on_key_down(self, event: tk.Event):
# <KeyPress event state=Control keysym=r keycode=27 char='\x12' x=538 y=556>
if event.keysym == "r":
print("FULL REFRESH")
with get(f"{self.url}/api/initial-state") as req:
buffer = b64decode(req.json()["full_state"].encode() + b"=")
data = req.json()
buffer = b64decode(data["full_state"].encode() + b"=")
img = Image.frombytes("1", (1000, 1000), buffer).convert("P")
img.putpalette(COLORS_UNPACKED)
self._image.paste(img.convert("RGB"))
self._last_update = data["timestamp"]
print("FULL REFRESH DONE")
def _reader(self):
@ -59,6 +73,10 @@ class App(tk.Tk):
if name == "batched_bit_toggles":
bits_on, bits_off, timestamp = data
if timestamp < self._last_update:
print("SKIP partial updates: too old")
continue
self._last_update = timestamp
for ndx in bits_on:
y, x = divmod(ndx, 1000)
self._image.putpixel((x, y), COLORS[1])
@ -92,7 +110,9 @@ class App(tk.Tk):
self.sio.connect(f"{self.url}/socket.io")
with get(f"{self.url}/api/initial-state") as req:
buffer = b64decode(req.json()["full_state"].encode() + b"=")
data = req.json()
buffer = b64decode(data["full_state"].encode() + b"=")
self._last_update = data["timestamp"]
img = Image.frombytes("1", (1000, 1000), buffer).convert("P")
img.putpalette(COLORS_UNPACKED)
self._image.paste(img.convert("RGB"))
@ -104,6 +124,7 @@ class App(tk.Tk):
self._reader_thr.start()
self.protocol("WM_DELETE_WINDOW", self._close)
self.after(1000, self._save_image)
self.mainloop()
if __name__ == "__main__":