import io import random from datetime import datetime from pathlib import Path import pygame from pygame import Surface from pygame.time import Clock from qrcode.main import QRCode DEBUG: bool = False WIDTH: int = 800 HEIGHT: int = 480 BORDER: int = 10 PHOTO_WIDTH = 2592 PHOTO_HEIGHT = 1944 SHOOTING_COUNT: int = 2 SHOOTING_INTERVAL: float = 0 if DEBUG else 1.75 COUNTDOWN_COUNT: int = 1 if DEBUG else 1 CHOICE_BORDER: int = 5 THUMB_WIDTH: int = (WIDTH - (SHOOTING_COUNT + 1) * BORDER) // SHOOTING_COUNT THUMB_HEIGHT: int = int(THUMB_WIDTH / 1.6) WHITE = (255, 255, 255) BLACK = (0, 0, 0) pygame.init() screen: Surface = pygame.display.set_mode((WIDTH, HEIGHT)) SCREEN_RECT = screen.get_rect() clock: Clock = pygame.time.Clock() def qr_create(content: str): global FOTOBOX_QR_SURFACE qr = QRCode(border=1) qr.add_data(content) qr.make(fit=True) qr_img = qr.make_image() qr_img_buffer = io.BytesIO() qr_img.save(qr_img_buffer) qr_img_buffer.seek(0) return pygame.image.load(qr_img_buffer) HTTPS = True DOMAIN = "fotobox.online" # HTTPS = False # DOMAIN = "localhost:8080" FONT_TITLE = pygame.font.SysFont(None, 70) FOTOBOX_TITLE_SURFACE = FONT_TITLE.render("Berühren um Fotos zu schießen", True, (255, 255, 255)) FOTOBOX_TITLE_RECT = FOTOBOX_TITLE_SURFACE.get_rect(centerx=SCREEN_RECT.centerx, top=BORDER) FONT_URL = pygame.font.SysFont(None, 60) FONT_COUNTDOWN = pygame.font.SysFont(None, 500) FOTOBOX_COUNTDOWN3_SURFACE = FONT_COUNTDOWN.render("3", True, (255, 255, 255)) FOTOBOX_COUNTDOWN3_RECT = FOTOBOX_COUNTDOWN3_SURFACE.get_rect(center=SCREEN_RECT.center) FOTOBOX_COUNTDOWN2_SURFACE = FONT_COUNTDOWN.render("2", True, (255, 255, 255)) FOTOBOX_COUNTDOWN2_RECT = FOTOBOX_COUNTDOWN2_SURFACE.get_rect(center=SCREEN_RECT.center) FOTOBOX_COUNTDOWN1_SURFACE = FONT_COUNTDOWN.render("1", True, (255, 255, 255)) FOTOBOX_COUNTDOWN1_RECT = FOTOBOX_COUNTDOWN1_SURFACE.get_rect(center=SCREEN_RECT.center) FONT_LOADING = pygame.font.SysFont(None, 200) LOADING_SURFACE = FONT_LOADING.render("Laden...", True, (255, 255, 255)) LOADING_RECT = LOADING_SURFACE.get_rect(center=SCREEN_RECT.center) FONT_CHOOSE = pygame.font.SysFont(None, 100) CHOOSE_SURFACE = FONT_CHOOSE.render("Bitte wählen", True, (255, 255, 255)) CHOOSE_RECT = CHOOSE_SURFACE.get_rect(centerx=SCREEN_RECT.centerx, top=BORDER) FONT_CANCEL = pygame.font.SysFont(None, 60) CANCEL_SURFACE = FONT_CANCEL.render("Abbruch", True, (255, 0, 0)) CANCEL_RECT = CANCEL_SURFACE.get_rect(left=BORDER, bottom=HEIGHT - BORDER) FONT_SAVE = pygame.font.SysFont(None, 60) SAVE_SURFACE = FONT_SAVE.render("Speichern", True, (0, 255, 0)) SAVE_RECT = SAVE_SURFACE.get_rect(right=WIDTH - BORDER, bottom=HEIGHT - BORDER) FONT_PRINT = pygame.font.SysFont(None, 60) PRINT_SURFACE = FONT_PRINT.render("Code drucken", True, (128, 128, 255)) PRINT_RECT = PRINT_SURFACE.get_rect(left=BORDER, bottom=HEIGHT - BORDER) FONT_DONE = pygame.font.SysFont(None, 60) DONE_SURFACE = FONT_DONE.render("Fertig", True, (0, 255, 0)) DONE_RECT = DONE_SURFACE.get_rect(right=WIDTH - BORDER, bottom=HEIGHT - BORDER) def pil_image_to_surface(pil_image): mode = pil_image.mode size = pil_image.size data = pil_image.tobytes() return pygame.image.fromstring(data, size, mode).convert_alpha() if 'A' in mode else pygame.image.fromstring(data, size, mode).convert() def read(path: str) -> str: with open(path, "r") as file: return file.read().strip() def read_or_else(path: str, fallback: str) -> str: try: return read(path) except FileNotFoundError: return fallback def write(path: str, value: str) -> None: Path(path).parent.mkdir(parents=True, exist_ok=True) with open(path, "w") as file: file.write(value) def file_increase(path: str) -> int: last = int(read_or_else(path, "0")) current = last + 1 write(path, str(current)) return current def iso(d: datetime): return d.strftime("%Y-%m-%dT%H:%M:%S%z") def now(): return datetime.now().astimezone() def generate_code(groups: int): return '-'.join(''.join(random.choices('23456789abcdefghjkmnpqrstuvwxyz', k=4)) for _ in range(groups))