124543d658
- Agent studioE5 standalone en Go (console + systray) - VPN on-demand via tailscaled + tailscale up (authkey Headscale) - Resolver/serveur dans le tailnet studioe5 - Caddy on-demand TLS pour les instances - Nouveaux endpoints serveur /api/internal/send-to-node - Suppression des anciens binaires edubox-agent - Suivi dans SUIVI_VPN_ONDEMAND.md
52 lines
1.2 KiB
Python
52 lines
1.2 KiB
Python
import zlib
|
|
import struct
|
|
|
|
|
|
def png_chunk(chunk_type: bytes, data: bytes) -> bytes:
|
|
return (
|
|
struct.pack(">I", len(data))
|
|
+ chunk_type
|
|
+ data
|
|
+ struct.pack(">I", zlib.crc32(chunk_type + data) & 0xFFFFFFFF)
|
|
)
|
|
|
|
|
|
def create_png(width: int, height: int, pixels: list) -> bytes:
|
|
"""Create a PNG from a 2D list of (R, G, B) tuples."""
|
|
raw = bytearray()
|
|
for row in pixels:
|
|
raw.append(0) # no filter
|
|
for r, g, b in row:
|
|
raw.extend((r, g, b))
|
|
compressed = zlib.compress(bytes(raw), 9)
|
|
|
|
ihdr_data = struct.pack(">IIBBBBB", width, height, 8, 2, 0, 0, 0)
|
|
ihdr = png_chunk(b"IHDR", ihdr_data)
|
|
idat = png_chunk(b"IDAT", compressed)
|
|
iend = png_chunk(b"IEND", b"")
|
|
|
|
return b"\x89PNG\r\n\x1a\n" + ihdr + idat + iend
|
|
|
|
|
|
BLUE = (37, 99, 235)
|
|
WHITE = (255, 255, 255)
|
|
SIZE = 64
|
|
|
|
pixels = []
|
|
for y in range(SIZE):
|
|
row = []
|
|
for x in range(SIZE):
|
|
dx = x - SIZE // 2
|
|
dy = y - SIZE // 2
|
|
dist = (dx * dx + dy * dy) ** 0.5
|
|
if dist < SIZE * 0.25:
|
|
row.append(WHITE)
|
|
else:
|
|
row.append(BLUE)
|
|
pixels.append(row)
|
|
|
|
with open("icon.png", "wb") as f:
|
|
f.write(create_png(SIZE, SIZE, pixels))
|
|
|
|
print("Generated icon.png")
|