initial
This commit is contained in:
		
							parent
							
								
									47eb95e12c
								
							
						
					
					
						commit
						5a809b5607
					
				
					 1 changed files with 152 additions and 0 deletions
				
			
		
							
								
								
									
										152
									
								
								vdrucker.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										152
									
								
								vdrucker.py
									
										
									
									
									
										Normal file
									
								
							|  | @ -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() | ||||
		Loading…
	
	Add table
		
		Reference in a new issue