Odoo18-Base/addons/hw_drivers/iot_handlers/interfaces/PrinterInterface_L.py
2025-03-10 11:12:23 +07:00

70 lines
2.9 KiB
Python

# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from cups import Connection as cups_connection
from re import sub
from threading import Lock
from odoo.addons.hw_drivers.interface import Interface
conn = cups_connection()
PPDs = conn.getPPDs()
cups_lock = Lock() # We can only make one call to Cups at a time
class PrinterInterface(Interface):
_loop_delay = 120
connection_type = 'printer'
printer_devices = {}
def get_devices(self):
discovered_devices = {}
with cups_lock:
printers = conn.getPrinters()
devices = conn.getDevices()
for printer_name, printer in printers.items():
path = printer.get('device-uri', False)
if printer_name != self.get_identifier(path):
printer.update({'supported': True}) # these printers are automatically supported
device_class = 'network'
if 'usb' in printer.get('device-uri'):
device_class = 'direct'
printer.update({'device-class': device_class})
printer.update({'device-make-and-model': printer_name}) # give name setted in Cups
printer.update({'device-id': ''})
devices.update({printer_name: printer})
for path, device in devices.items():
identifier = self.get_identifier(path)
device.update({'identifier': identifier})
device.update({'url': path})
device.update({'disconnect_counter': 0})
discovered_devices.update({identifier: device})
self.printer_devices.update(discovered_devices)
# Deal with devices which are on the list but were not found during this call of "get_devices"
# If they aren't detected 3 times consecutively, remove them from the list of available devices
for device in list(self.printer_devices):
if not discovered_devices.get(device):
disconnect_counter = self.printer_devices.get(device).get('disconnect_counter')
if disconnect_counter >= 2:
self.printer_devices.pop(device, None)
else:
self.printer_devices[device].update({'disconnect_counter': disconnect_counter + 1})
return dict(self.printer_devices)
def get_identifier(self, path):
"""
Necessary because the path is not always a valid Cups identifier,
as it may contain characters typically found in URLs or paths.
- Removes characters: ':', '/', '.', '\', and space.
- Removes the exact strings: "uuid=" and "serial=".
Example 1:
Input: "ipp://printers/printer1:1234/abcd"
Output: "ippprintersprinter11234abcd"
Example 2:
Input: "uuid=1234-5678-90ab-cdef"
Output: "1234-5678-90ab-cdef
"""
return sub(r'[:\/\.\\ ]|(uuid=)|(serial=)', '', path)