diff --git a/vdrucker.py b/vdrucker.py new file mode 100644 index 0000000..772b02e --- /dev/null +++ b/vdrucker.py @@ -0,0 +1,152 @@ +#!/usr/bin/env python3 + +import os +import tkinter as tk +import subprocess +import time +import threading +from threading import Timer +from PIL import Image + +# Verzeichnisse +PDF_DIR = "/var/spool/cups-pdf/ANONYMOUS" +OUTPUT_DIR = "/tmp/pdf_display" + +# Dateien & Skalierung +PRINTER_BG = os.path.join(os.path.dirname(__file__), "druckerbild.png") +PRINTER_SCALE = 0.6 # z. B. 0.5 = 50% der Bildschirmhöhe + +# DISPLAY-Variable setzen, falls nicht vorhanden +if "DISPLAY" not in os.environ: + os.environ["DISPLAY"] = ":0" + +os.makedirs(OUTPUT_DIR, exist_ok=True) + +# Bildschirmgröße ermitteln +def get_screen_size(): + output = subprocess.check_output("xdpyinfo | grep dimensions", shell=True).decode() + width, height = map(int, output.split()[1].split("x")) + return width, height + +# Druckerbild über gesamte Breite anzeigen +def display_printer(): + screen_width, screen_height = get_screen_size() + scaled_height = int(screen_height * PRINTER_SCALE) + + subprocess.Popen([ + "feh", "--no-fehbg", "--borderless", "--image-bg", "#000000", + "--geometry", f"{screen_width}x{scaled_height}+0+0", PRINTER_BG + ]) + +# PDF in Bild umwandeln (erste Seite) und runterskalieren +def pdf_to_image(pdf_path, breite=300): + basename = os.path.basename(pdf_path).replace(".pdf", "") + img_path = os.path.join(OUTPUT_DIR, f"{basename}.png") + subprocess.run(["pdftoppm", "-png", "-singlefile", "-f", "1", pdf_path, img_path.replace(".png", "")]) + + img = Image.open(img_path) + width, height = img.size + new_height = int((breite / width) * height) + img = img.resize((breite, new_height), Image.ANTIALIAS) + img.save(img_path) + + return img_path + +# Perspektivische Verzerrung auf das Bild anwenden +def distort_image(img_path): + output_img = img_path.replace(".png", "_distorted.png") + subprocess.run([ + "convert", img_path, + "-matte", "-virtual-pixel", "transparent", "-background", "none", + "-wave", "5x200" , output_img + ]) + return output_img + +# PDF-Bild zentriert am unteren Rand anzeigen (skaliert) +def display_image(image_path, scale=0.6): + screen_width, screen_height = get_screen_size() + + # Bildgröße auslesen + img = Image.open(image_path) + img_width, img_height = img.size + + # Neue Größe berechnen (an Bildschirmhöhe anpassen) + scaled_height = int(screen_height * scale) + scale_factor = scaled_height / img_height + scaled_width = int(img_width * scale_factor) + + # Position berechnen (zentriert, am unteren Rand) + x_offset = 0 + y_offset = screen_height - scaled_height + + # Bild mit feh anzeigen + subprocess.Popen([ + "feh", "-x", "-B", "#000000", + "--geometry", f"{screen_width}x{scaled_height}+{x_offset}+{y_offset}", + image_path + ]) + + +# PDF-Verzeichnis mit inotify überwachen +def monitor_folder(): + print(f"Überwache {PDF_DIR} auf neue PDFs...") + + # Druckerbild direkt beim Start anzeigen + display_printer() + + process = subprocess.Popen(["inotifywait", "-m", "-e", "close_write", PDF_DIR], stdout=subprocess.PIPE) + + for line in process.stdout: + parts = line.decode().strip().split() + if len(parts) == 3 and parts[2].endswith(".pdf"): + pdf_path = os.path.join(PDF_DIR, parts[2]) + print(f"Neues PDF erkannt: {pdf_path}") + + # PDF konvertieren und anzeigen + image_path = pdf_to_image(pdf_path) + distorted_path = distort_image(image_path) + display_image(distorted_path) + +# Funktion zum Herunterfahren des Rechners +def shutdown_printer(): + os.system("shutdown now") + +# Button "Drucker ausschalten" anzeigen +def show_shutdown_button(): + root = tk.Tk() + root.title("Druckersteuerung") + + # Fenstergröße und Position (unten rechts) + screen_width = root.winfo_screenwidth() + screen_height = root.winfo_screenheight() + window_width = 64 + window_height = 64 + x_position = screen_width - window_width - 10 + y_position = screen_height - window_height - 10 + root.geometry(f"{window_width}x{window_height}+{x_position}+{y_position}") + # Fenster ohne Rahmen und transparent + root.overrideredirect(True) # Entfernt den Fensterrahmen + root.attributes("-topmost", True) # Immer im Vordergrund + root.attributes("-alpha", 0.9) + root.configure(bg="black") + + # Icon laden + icon_path = os.path.join(os.path.dirname(__file__), "poweroff.png") + icon = tk.PhotoImage(file=icon_path) + + # Button mit Icon erstellen + button = tk.Button(root, image=icon, command=shutdown_printer, bg="black", width=icon.width(), height=icon.height(), borderwidth=0) + button.image = icon # Referenz speichern, damit das Bild nicht vom Garbage Collector entfernt wird + button.pack(expand=True, fill="both", padx=0, pady=0) + + # GUI starten + root.mainloop() + +def start_monitor_thread(): + # Funktion, um die Überwachung in einem separaten Thread zu starten + monitor_thread = threading.Thread(target=monitor_folder, daemon=True) + monitor_thread.start() + +if __name__ == "__main__": + start_monitor_thread() + show_shutdown_button()