Improved printer detection in GUI

This commit is contained in:
Ircama 2024-07-27 04:01:38 +02:00
parent 1ed4e93553
commit b0709705d4
3 changed files with 70 additions and 11 deletions

View file

@ -78,7 +78,7 @@ class EpsonPrinter:
"same-as": "XP-315" "same-as": "XP-315"
}, },
"Stylus Photo PX730WD": { "Stylus Photo PX730WD": {
"alias": ["Epson Artisan 730"], "alias": ["Stylus Photo PX730", "Artisan 730"],
"read_key": [0x8, 0x77], "read_key": [0x8, 0x77],
"write_key": b'Cattleya', "write_key": b'Cattleya',
"main_waste": {"oids": [0xe, 0xf], "divider": 81.82}, "main_waste": {"oids": [0xe, 0xf], "divider": 81.82},
@ -525,7 +525,7 @@ class EpsonPrinter:
range(0x120, 0x12a), range(0x727, 0x72c), range(0x7f4, 0x7fe) range(0x120, 0x12a), range(0x727, 0x72c), range(0x7f4, 0x7fe)
), ),
}, },
"Artisan-800": { "Artisan 800": {
"read_key": [0x53, 0x09], "read_key": [0x53, 0x09],
# uncompleted # uncompleted
}, },

View file

@ -52,12 +52,19 @@ class PrinterScanner:
else: else:
return {"ip": ip, "hostname": hostname, "name": "Unknown"} return {"ip": ip, "hostname": hostname, "name": "Unknown"}
return None return None
def get_all_printers(self):
def get_all_printers(self, ip_addr=""):
if ip_addr:
result = self.scan_ip(ip_addr)
if result:
return [result]
local_device_ip_list = socket.gethostbyname_ex(socket.gethostname())[2] local_device_ip_list = socket.gethostbyname_ex(socket.gethostname())[2]
printers = []
for local_device_ip in local_device_ip_list: for local_device_ip in local_device_ip_list:
if ip_addr and not local_device_ip.startswith(ip_addr):
continue
base_ip = local_device_ip[:local_device_ip.rfind('.') + 1] base_ip = local_device_ip[:local_device_ip.rfind('.') + 1]
ips=[f"{base_ip}{i}" for i in range(1, 255)] ips=[f"{base_ip}{i}" for i in range(1, 255)]
printers = []
threads = [] threads = []
def worker(ip): def worker(ip):
@ -77,5 +84,9 @@ class PrinterScanner:
if __name__ == "__main__": if __name__ == "__main__":
import sys
ip = ""
if len(sys.argv) > 1:
ip = sys.argv[1]
scanner = PrinterScanner() scanner = PrinterScanner()
print(scanner.get_all_printers()) print(scanner.get_all_printers(ip))

58
ui.py
View file

@ -3,6 +3,7 @@ from tkinter import ttk, Menu
from tkinter.scrolledtext import ScrolledText from tkinter.scrolledtext import ScrolledText
import threading import threading
import ipaddress import ipaddress
import re
from find_printers import PrinterScanner from find_printers import PrinterScanner
from epson_print_conf import EpsonPrinter from epson_print_conf import EpsonPrinter
import tkinter.font as tkfont import tkinter.font as tkfont
@ -13,6 +14,7 @@ class EpsonPrinterUI(tk.Tk):
super().__init__() super().__init__()
self.title("Epson Printer Configuration") self.title("Epson Printer Configuration")
self.geometry("450x400") self.geometry("450x400")
self.printer_scanner=PrinterScanner()
# configure the main window to be resizable # configure the main window to be resizable
self.columnconfigure(0, weight=1) self.columnconfigure(0, weight=1)
@ -32,7 +34,7 @@ class EpsonPrinterUI(tk.Tk):
self.model_var = tk.StringVar() self.model_var = tk.StringVar()
ttk.Label(model_frame, text="Select Printer Model:").grid(row=0, column=0, sticky=tk.W, padx=5) ttk.Label(model_frame, text="Select Printer Model:").grid(row=0, column=0, sticky=tk.W, padx=5)
self.model_dropdown = ttk.Combobox(model_frame, textvariable=self.model_var) self.model_dropdown = ttk.Combobox(model_frame, textvariable=self.model_var)
self.model_dropdown['values'] = sorted(list(EpsonPrinter.PRINTER_CONFIG.keys())) self.model_dropdown['values'] = sorted(EpsonPrinter().valid_printers)
self.model_dropdown.grid(row=0, column=1, pady=5, padx=5, sticky=(tk.W, tk.E)) self.model_dropdown.grid(row=0, column=1, pady=5, padx=5, sticky=(tk.W, tk.E))
# IP address entry # IP address entry
@ -160,12 +162,20 @@ class EpsonPrinterUI(tk.Tk):
def detect_printers(self): def detect_printers(self):
self.show_status_text_view() self.show_status_text_view()
printer_scanner=PrinterScanner()
try: try:
printers = printer_scanner.get_all_printers() printers = self.printer_scanner.get_all_printers(self.ip_var.get().strip())
if len(printers) > 0: if len(printers) > 0:
for printer in printers: if len(printers) == 1:
self.status_text.insert(tk.END, f"[INFO] {printer['name']} found at {printer['ip']} (hostname: {printer['hostname']})\n") self.status_text.insert(tk.END, f"[INFO] Found printer '{printers[0]['name']}' at {printers[0]['ip']} (hostname: {printers[0]['hostname']})\n")
self.ip_var.set(printers[0]['ip'])
for model in self.get_printer_models(printers[0]['name']):
if model in EpsonPrinter().valid_printers:
self.model_var.set(model)
break
else:
self.status_text.insert(tk.END, f"[INFO] Found {len(printers)} printers:\n")
for printer in printers:
self.status_text.insert(tk.END, f"[INFO] {printer['name']} found at {printer['ip']} (hostname: {printer['hostname']})\n")
else: else:
self.status_text.insert(tk.END, "[WARN] No printers found.\n") self.status_text.insert(tk.END, "[WARN] No printers found.\n")
except Exception as e: except Exception as e:
@ -248,6 +258,44 @@ class EpsonPrinterUI(tk.Tk):
self.clipboard_clear() self.clipboard_clear()
self.clipboard_append(item_text) self.clipboard_append(item_text)
def get_printer_models(self, input_string):
# Tokenize the string
tokens = re.split(' |/', input_string)
if not len(tokens):
return []
# Define the words to remove (uppercase, then case insensitive)
remove_tokens = {"EPSON", "SERIES"}
# Process tokens
processed_tokens = []
non_numeric_part = ""
pre_model = ""
for token in tokens:
upper_token = token.upper()
# Remove tokens that match remove_tokens
if any(word == upper_token for word in remove_tokens):
continue
if not any(char.isdigit() for char in token): # no alphanum inside
pre_model = pre_model + token + " "
continue
# Identify the non-numeric part of the first token
if not token.isnumeric() and not non_numeric_part:
non_numeric_part = ''.join(c for c in token if not c.isdigit())
# if token is numeric, prepend the non-numeric part
if token.isnumeric():
processed_tokens.append(f"{pre_model}{non_numeric_part}{token}")
else:
processed_tokens.append(f"{pre_model}{token}")
if not processed_tokens and pre_model:
processed_tokens.append(pre_model.strip())
return processed_tokens
if __name__ == "__main__": if __name__ == "__main__":
app = EpsonPrinterUI() app = EpsonPrinterUI()
app.mainloop() app.mainloop()