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