diff --git a/lib/hidapi/hidapi.py b/lib/hidapi/hidapi.py index 324cc329eb..18464f9cd6 100644 --- a/lib/hidapi/hidapi.py +++ b/lib/hidapi/hidapi.py @@ -26,16 +26,15 @@ """ import atexit import ctypes +import logging import platform as _platform from collections import namedtuple -from logging import INFO as _INFO -from logging import getLogger from threading import Thread from time import sleep -_log = getLogger(__name__) -del getLogger +logger = logging.getLogger(__name__) + native_implementation = 'hidapi' # Device info as expected by Solaar @@ -257,14 +256,14 @@ def _match(action, device, filterfn): if len(report) == 1 + 19 and report[0] == 0x11: device['hidpp_long'] = True except HIDError as e: # noqa: F841 - if _log.isEnabledFor(_INFO): - _log.info(f"Error opening device {device['path']} ({bus_id}/{vid:04X}/{pid:04X}) for hidpp check: {e}") + if logger.isEnabledFor(logging.INFO): + logger.info(f"Error opening device {device['path']} ({bus_id}/{vid:04X}/{pid:04X}) for hidpp check: {e}") finally: if device_handle: close(device_handle) - if _log.isEnabledFor(_INFO): - _log.info( + if logger.isEnabledFor(logging.INFO): + logger.info( 'Found device BID %s VID %04X PID %04X HID++ %s %s', bus_id, vid, pid, device['hidpp_short'], device['hidpp_long'] ) diff --git a/lib/hidapi/udev.py b/lib/hidapi/udev.py index ce38531b15..aaa11698bc 100644 --- a/lib/hidapi/udev.py +++ b/lib/hidapi/udev.py @@ -25,13 +25,12 @@ """ import errno as _errno +import logging import os as _os import warnings as _warnings # the tuple object we'll expose when enumerating devices from collections import namedtuple -from logging import INFO as _INFO -from logging import getLogger from select import select as _select from time import sleep from time import time as _timestamp @@ -42,8 +41,8 @@ from pyudev import Devices as _Devices from pyudev import Monitor as _Monitor -_log = getLogger(__name__) -del getLogger +logger = logging.getLogger(__name__) + native_implementation = 'udev' fileopen = open @@ -123,7 +122,7 @@ def _match(action, device, filterfn): return except Exception as e: # if can't process report descriptor fall back to old scheme hidpp_short = hidpp_long = None - _log.warn( + logger.warning( 'Report Descriptor not processed for DEVICE %s BID %s VID %s PID %s: %s', device.device_node, bid, vid, pid, e ) @@ -147,8 +146,8 @@ def _match(action, device, filterfn): intf_device = device.find_parent('usb', 'usb_interface') usb_interface = None if intf_device is None else intf_device.attributes.asint('bInterfaceNumber') # print('*** usb interface', action, device, 'usb_interface:', intf_device, usb_interface, interface_number) - if _log.isEnabledFor(_INFO): - _log.info( + if logger.isEnabledFor(logging.INFO): + logger.info( 'Found device %s BID %s VID %s PID %s HID++ %s %s USB %s %s', device.device_node, bid, vid, pid, hidpp_short, hidpp_long, usb_interface, interface_number ) @@ -325,14 +324,14 @@ def open_path(device_path): assert device_path assert device_path.startswith('/dev/hidraw') - _log.info('OPEN PATH %s', device_path) + logger.info('OPEN PATH %s', device_path) retrycount = 0 while (retrycount < 3): retrycount += 1 try: return _os.open(device_path, _os.O_RDWR | _os.O_SYNC) except OSError as e: - _log.info('OPEN PATH FAILED %s ERROR %s %s', device_path, e.errno, e) + logger.info('OPEN PATH FAILED %s ERROR %s %s', device_path, e.errno, e) if e.errno == _errno.EACCES: sleep(0.1) else: diff --git a/lib/logitech_receiver/__init__.py b/lib/logitech_receiver/__init__.py index 9625ddb226..e31407edac 100644 --- a/lib/logitech_receiver/__init__.py +++ b/lib/logitech_receiver/__init__.py @@ -37,12 +37,11 @@ from .hidpp20 import FeatureCallError, FeatureNotSupported # noqa: F401 from .receiver import Receiver # noqa: F401 -_DEBUG = logging.DEBUG -_log = logging.getLogger(__name__) -_log.setLevel(logging.root.level) +logger = logging.getLogger(__name__) +logger.setLevel(logging.root.level) # if logging.root.level > logging.DEBUG: -# _log.addHandler(logging.NullHandler()) -# _log.propagate = 0 +# logger.addHandler(logging.NullHandler()) +# logger.propagate = 0 del logging diff --git a/lib/logitech_receiver/base.py b/lib/logitech_receiver/base.py index c9dd1c6376..0024b021ec 100644 --- a/lib/logitech_receiver/base.py +++ b/lib/logitech_receiver/base.py @@ -19,13 +19,11 @@ # Base low-level functions used by the API proper. # Unlikely to be used directly unless you're expanding the API. +import logging import threading as _threading from collections import namedtuple from contextlib import contextmanager -from logging import DEBUG as _DEBUG -from logging import INFO as _INFO -from logging import getLogger from random import getrandbits as _random_bits from struct import pack as _pack from time import time as _timestamp @@ -40,8 +38,7 @@ from .common import KwException as _KwException from .common import strhex as _strhex -_log = getLogger(__name__) -del getLogger +logger = logging.getLogger(__name__) # # @@ -184,10 +181,10 @@ def close(handle): _hid.close(handle) else: handle.close() - # _log.info("closed receiver handle %r", handle) + # logger.info("closed receiver handle %r", handle) return True except Exception: - # _log.exception("closing receiver handle %r", handle) + # logger.exception("closing receiver handle %r", handle) pass return False @@ -214,13 +211,13 @@ def write(handle, devnumber, data, long_message=False): wdata = _pack('!BB18s', HIDPP_LONG_MESSAGE_ID, devnumber, data) else: wdata = _pack('!BB5s', HIDPP_SHORT_MESSAGE_ID, devnumber, data) - if _log.isEnabledFor(_DEBUG): - _log.debug('(%s) <= w[%02X %02X %s %s]', handle, ord(wdata[:1]), devnumber, _strhex(wdata[2:4]), _strhex(wdata[4:])) + if logger.isEnabledFor(logging.DEBUG): + logger.debug('(%s) <= w[%02X %02X %s %s]', handle, ord(wdata[:1]), devnumber, _strhex(wdata[2:4]), _strhex(wdata[4:])) try: _hid.write(int(handle), wdata) except Exception as reason: - _log.error('write failed, assuming handle %r no longer available', handle) + logger.error('write failed, assuming handle %r no longer available', handle) close(handle) raise NoReceiver(reason=reason) @@ -251,7 +248,7 @@ def check_message(data): if report_lengths.get(report_id) == len(data): return True else: - _log.warn('unexpected message size: report_id %02X message %s' % (report_id, _strhex(data))) + logger.warning('unexpected message size: report_id %02X message %s' % (report_id, _strhex(data))) return False @@ -269,7 +266,7 @@ def _read(handle, timeout): timeout = int(timeout * 1000) data = _hid.read(int(handle), _MAX_READ_SIZE, timeout) except Exception as reason: - _log.warn('read failed, assuming handle %r no longer available', handle) + logger.warning('read failed, assuming handle %r no longer available', handle) close(handle) raise NoReceiver(reason=reason) @@ -277,8 +274,9 @@ def _read(handle, timeout): report_id = ord(data[:1]) devnumber = ord(data[1:2]) - if _log.isEnabledFor(_DEBUG) and (report_id != DJ_MESSAGE_ID or ord(data[2:3]) > 0x10): # ignore DJ input messages - _log.debug('(%s) => r[%02X %02X %s %s]', handle, report_id, devnumber, _strhex(data[2:4]), _strhex(data[4:])) + if logger.isEnabledFor(logging.DEBUG + ) and (report_id != DJ_MESSAGE_ID or ord(data[2:3]) > 0x10): # ignore DJ input messages + logger.debug('(%s) => r[%02X %02X %s %s]', handle, report_id, devnumber, _strhex(data[2:4]), _strhex(data[4:])) return report_id, devnumber, data[2:] @@ -299,7 +297,7 @@ def _skip_incoming(handle, ihandle, notifications_hook): # read whatever is already in the buffer, if any data = _hid.read(ihandle, _MAX_READ_SIZE, 0) except Exception as reason: - _log.error('read failed, assuming receiver %s no longer available', handle) + logger.error('read failed, assuming receiver %s no longer available', handle) close(handle) raise NoReceiver(reason=reason) @@ -363,8 +361,8 @@ def make_notification(report_id, devnumber, data): def handle_lock(handle): with request_lock: if handles_lock.get(handle) is None: - if _log.isEnabledFor(_INFO): - _log.info('New lock %s', repr(handle)) + if logger.isEnabledFor(logging.INFO): + logger.info('New lock %s', repr(handle)) handles_lock[handle] = _threading.Lock() # Serialize requests on the handle return handles_lock[handle] @@ -375,7 +373,7 @@ def acquire_timeout(lock, handle, timeout): result = lock.acquire(timeout=timeout) try: if not result: - _log.error('lock on handle %d not acquired, probably due to timeout', int(handle)) + logger.error('lock on handle %d not acquired, probably due to timeout', int(handle)) yield result finally: if result: @@ -414,8 +412,8 @@ def request(handle, devnumber, request_id, *params, no_reply=False, return_error params = b''.join(_pack('B', p) if isinstance(p, int) else p for p in params) else: params = b'' - # if _log.isEnabledFor(_DEBUG): - # _log.debug("(%s) device %d request_id {%04X} params [%s]", handle, devnumber, request_id, _strhex(params)) + # if logger.isEnabledFor(logging.DEBUG): + # logger.debug("(%s) device %d request_id {%04X} params [%s]", handle, devnumber, request_id, _strhex(params)) request_data = _pack('!H', request_id) + params ihandle = int(handle) @@ -423,7 +421,7 @@ def request(handle, devnumber, request_id, *params, no_reply=False, return_error try: _skip_incoming(handle, ihandle, notifications_hook) except NoReceiver: - _log.warn('device or receiver disconnected') + logger.warning('device or receiver disconnected') return None write(ihandle, devnumber, request_data, long_message) @@ -444,8 +442,8 @@ def request(handle, devnumber, request_id, *params, no_reply=False, return_error ]: error = ord(reply_data[3:4]) - if _log.isEnabledFor(_DEBUG): - _log.debug( + if logger.isEnabledFor(logging.DEBUG): + logger.debug( '(%s) device 0x%02X error on request {%04X}: %d = %s', handle, devnumber, request_id, error, _hidpp10.ERROR[error] ) @@ -453,7 +451,7 @@ def request(handle, devnumber, request_id, *params, no_reply=False, return_error if reply_data[:1] == b'\xFF' and reply_data[1:3] == request_data[:2]: # a HID++ 2.0 feature call returned with an error error = ord(reply_data[3:4]) - _log.error( + logger.error( '(%s) device %d error on feature request {%04X}: %d = %s', handle, devnumber, request_id, error, _hidpp20.ERROR[error] ) @@ -481,16 +479,16 @@ def request(handle, devnumber, request_id, *params, no_reply=False, return_error n = make_notification(report_id, reply_devnumber, reply_data) if n: notifications_hook(n) - # elif _log.isEnabledFor(_DEBUG): - # _log.debug("(%s) ignoring reply %02X [%s]", handle, reply_devnumber, _strhex(reply_data)) - # elif _log.isEnabledFor(_DEBUG): - # _log.debug("(%s) ignoring reply %02X [%s]", handle, reply_devnumber, _strhex(reply_data)) + # elif logger.isEnabledFor(logging.DEBUG): + # logger.debug("(%s) ignoring reply %02X [%s]", handle, reply_devnumber, _strhex(reply_data)) + # elif logger.isEnabledFor(logging.DEBUG): + # logger.debug("(%s) ignoring reply %02X [%s]", handle, reply_devnumber, _strhex(reply_data)) delta = _timestamp() - request_started - # if _log.isEnabledFor(_DEBUG): - # _log.debug("(%s) still waiting for reply, delta %f", handle, delta) + # if logger.isEnabledFor(logging.DEBUG): + # logger.debug("(%s) still waiting for reply, delta %f", handle, delta) - _log.warn( + logger.warning( 'timeout (%0.2f/%0.2f) on device %d request {%04X} params [%s]', delta, timeout, devnumber, request_id, _strhex(params) ) @@ -501,14 +499,14 @@ def ping(handle, devnumber, long_message=False): """Check if a device is connected to the receiver. :returns: The HID protocol supported by the device, as a floating point number, if the device is active. """ - if _log.isEnabledFor(_DEBUG): - _log.debug('(%s) pinging device %d', handle, devnumber) + if logger.isEnabledFor(logging.DEBUG): + logger.debug('(%s) pinging device %d', handle, devnumber) with acquire_timeout(handle_lock(handle), handle, 10.): notifications_hook = getattr(handle, 'notifications_hook', None) try: _skip_incoming(handle, int(handle), notifications_hook) except NoReceiver: - _log.warn('device or receiver disconnected') + logger.warning('device or receiver disconnected') return # randomize the SoftwareId and mark byte to be able to identify the ping @@ -537,16 +535,16 @@ def ping(handle, devnumber, long_message=False): if error == _hidpp10.ERROR.resource_error or error == _hidpp10.ERROR.connection_request_failed: return # device unreachable if error == _hidpp10.ERROR.unknown_device: # no paired device with that number - _log.error('(%s) device %d error on ping request: unknown device', handle, devnumber) + logger.error('(%s) device %d error on ping request: unknown device', handle, devnumber) raise NoSuchDevice(number=devnumber, request=request_id) if notifications_hook: n = make_notification(report_id, reply_devnumber, reply_data) if n: notifications_hook(n) - # elif _log.isEnabledFor(_DEBUG): - # _log.debug("(%s) ignoring reply %02X [%s]", handle, reply_devnumber, _strhex(reply_data)) + # elif logger.isEnabledFor(logging.DEBUG): + # logger.debug("(%s) ignoring reply %02X [%s]", handle, reply_devnumber, _strhex(reply_data)) delta = _timestamp() - request_started - _log.warn('(%s) timeout (%0.2f/%0.2f) on device %d ping', handle, delta, _PING_TIMEOUT, devnumber) + logger.warning('(%s) timeout (%0.2f/%0.2f) on device %d ping', handle, delta, _PING_TIMEOUT, devnumber) diff --git a/lib/logitech_receiver/device.py b/lib/logitech_receiver/device.py index 177e2140d2..18799f8959 100644 --- a/lib/logitech_receiver/device.py +++ b/lib/logitech_receiver/device.py @@ -17,10 +17,9 @@ ## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. import errno as _errno +import logging import threading as _threading -from logging import INFO as _INFO -from logging import getLogger from typing import Optional import hidapi as _hid @@ -33,8 +32,7 @@ from .common import strhex as _strhex from .settings_templates import check_feature_settings as _check_feature_settings -_log = getLogger(__name__) -del getLogger +logger = logging.getLogger(__name__) _R = _hidpp10.REGISTERS _IR = _hidpp10.INFO_SUBREGISTERS @@ -129,7 +127,7 @@ def __init__( elif receiver.receiver_kind == '27Mhz': # 27 Mhz receiver doesn't have pairing registers self.wpid = _hid.find_paired_node_wpid(receiver.path, number) if not self.wpid: - _log.error('Unable to get wpid from udev for device %d of %s', number, receiver) + logger.error('Unable to get wpid from udev for device %d of %s', number, receiver) raise _base.NoSuchDevice(number=number, receiver=receiver, error='Not present 27Mhz device') kind = receiver.get_kind_from_index(number) self._kind = _hidpp10.DEVICE_KIND[kind] @@ -220,8 +218,8 @@ def get_ids(self): ids = _hidpp20.get_ids(self) if ids: self._unitId, self._modelId, self._tid_map = ids - if _log.isEnabledFor(_INFO) and self._serial and self._serial != self._unitId: - _log.info('%s: unitId %s does not match serial %s', self, self._unitId, self._serial) + if logger.isEnabledFor(logging.INFO) and self._serial and self._serial != self._unitId: + logger.info('%s: unitId %s does not match serial %s', self, self._unitId, self._serial) @property def unitId(self): @@ -426,12 +424,12 @@ def enable_connection_notifications(self, enable=True): set_flag_bits = 0 ok = _hidpp10.set_notification_flags(self, set_flag_bits) if not ok: - _log.warn('%s: failed to %s device notifications', self, 'enable' if enable else 'disable') + logger.warning('%s: failed to %s device notifications', self, 'enable' if enable else 'disable') flag_bits = _hidpp10.get_notification_flags(self) flag_names = None if flag_bits is None else tuple(_hidpp10.NOTIFICATION_FLAG.flag_names(flag_bits)) - if _log.isEnabledFor(_INFO): - _log.info('%s: device notifications %s %s', self, 'enabled' if enable else 'disabled', flag_names) + if logger.isEnabledFor(logging.INFO): + logger.info('%s: device notifications %s %s', self, 'enabled' if enable else 'disabled', flag_names) return flag_bits if ok else None def add_notification_handler(self, id: str, fn): @@ -451,8 +449,8 @@ def add_notification_handler(self, id: str, fn): def remove_notification_handler(self, id: str): """Unregisters the notification handler under name `id`.""" - if id not in self._notification_handlers and _log.isEnabledFor(_INFO): - _log.info(f'Tried to remove nonexistent notification handler {id} from device {self}.') + if id not in self._notification_handlers and logger.isEnabledFor(logging.INFO): + logger.info(f'Tried to remove nonexistent notification handler {id} from device {self}.') else: del self._notification_handlers[id] @@ -544,11 +542,11 @@ def open(self, device_info): bus_id=device_info.bus_id ) except OSError as e: - _log.exception('open %s', device_info) + logger.exception('open %s', device_info) if e.errno == _errno.EACCES: raise except Exception: - _log.exception('open %s', device_info) + logger.exception('open %s', device_info) def close(self): handle, self.handle = self.handle, None diff --git a/lib/logitech_receiver/diversion.py b/lib/logitech_receiver/diversion.py index 8afaf97fd0..e31479182b 100644 --- a/lib/logitech_receiver/diversion.py +++ b/lib/logitech_receiver/diversion.py @@ -17,15 +17,13 @@ ## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. import ctypes as _ctypes +import logging import os as _os import os.path as _path import platform as _platform import sys as _sys import time as _time -from logging import DEBUG as _DEBUG -from logging import INFO as _INFO -from logging import getLogger from math import sqrt as _sqrt from struct import unpack as _unpack @@ -54,8 +52,7 @@ gi.require_version('Gdk', '3.0') # isort:skip from gi.repository import Gdk, GLib # NOQA: E402 # isort:skip -_log = getLogger(__name__) -del getLogger +logger = logging.getLogger(__name__) # # See docs/rules.md for documentation @@ -99,12 +96,12 @@ gdisplay = Gdk.Display.get_default() # can be None if Solaar is run without a full window system gkeymap = Gdk.Keymap.get_for_display(gdisplay) if gdisplay else None -if _log.isEnabledFor(_INFO): - _log.info('GDK Keymap %sset up', '' if gkeymap else 'not ') +if logger.isEnabledFor(logging.INFO): + logger.info('GDK Keymap %sset up', '' if gkeymap else 'not ') wayland = _os.getenv('WAYLAND_DISPLAY') # is this Wayland? if wayland: - _log.warn( + logger.warning( 'rules cannot access modifier keys in Wayland, ' 'accessing process only works on GNOME with Solaar Gnome extension installed' ) @@ -149,10 +146,10 @@ def x11_setup(): NET_WM_PID = xdisplay.intern_atom('_NET_WM_PID') WM_CLASS = xdisplay.intern_atom('WM_CLASS') _x11 = True # X11 available - if _log.isEnabledFor(_INFO): - _log.info('X11 library loaded and display set up') + if logger.isEnabledFor(logging.INFO): + logger.info('X11 library loaded and display set up') except Exception: - _log.warn('X11 not available - some rule capabilities inoperable', exc_info=_sys.exc_info()) + logger.warning('X11 not available - some rule capabilities inoperable', exc_info=_sys.exc_info()) _x11 = False xtest_available = False return _x11 @@ -167,7 +164,7 @@ def gnome_dbus_interface_setup(): remote_object = bus.get_object('org.gnome.Shell', '/io/github/pwr_solaar/solaar') _dbus_interface = dbus.Interface(remote_object, 'io.github.pwr_solaar.solaar') except dbus.exceptions.DBusException: - _log.warn('Solaar Gnome extension not installed - some rule capabilities inoperable', exc_info=_sys.exc_info()) + logger.warning('Solaar Gnome extension not installed - some rule capabilities inoperable', exc_info=_sys.exc_info()) _dbus_interface = False return _dbus_interface @@ -181,10 +178,10 @@ def xkb_setup(): X11Lib.XOpenDisplay.restype = _ctypes.POINTER(XkbDisplay) X11Lib.XkbGetState.argtypes = [_ctypes.POINTER(XkbDisplay), _ctypes.c_uint, _ctypes.POINTER(XkbStateRec)] Xkbdisplay = X11Lib.XOpenDisplay(None) - if _log.isEnabledFor(_INFO): - _log.info('XKB display set up') + if logger.isEnabledFor(logging.INFO): + logger.info('XKB display set up') except Exception: - _log.warn('XKB display not available - rules cannot access keyboard group', exc_info=_sys.exc_info()) + logger.warning('XKB display not available - rules cannot access keyboard group', exc_info=_sys.exc_info()) Xkbdisplay = False return Xkbdisplay @@ -224,11 +221,11 @@ def setup_uinput(): return udevice try: udevice = evdev.uinput.UInput(events=devicecap, name='solaar-keyboard') - if _log.isEnabledFor(_INFO): - _log.info('uinput device set up') + if logger.isEnabledFor(logging.INFO): + logger.info('uinput device set up') return True except Exception as e: - _log.warn('cannot create uinput device: %s', e) + logger.warning('cannot create uinput device: %s', e) if wayland: # Wayland can't use xtest so may as well set up uinput now @@ -297,12 +294,12 @@ def simulate_xtest(code, event): ) Xlib.ext.xtest.fake_input(xdisplay, event, code) xdisplay.sync() - if _log.isEnabledFor(_DEBUG): - _log.debug('xtest simulated input %s %s %s', xdisplay, event, code) + if logger.isEnabledFor(logging.DEBUG): + logger.debug('xtest simulated input %s %s %s', xdisplay, event, code) return True except Exception as e: xtest_available = False - _log.warn('xtest fake input failed: %s', e) + logger.warning('xtest fake input failed: %s', e) def simulate_uinput(what, code, arg): @@ -311,12 +308,12 @@ def simulate_uinput(what, code, arg): try: udevice.write(what, code, arg) udevice.syn() - if _log.isEnabledFor(_DEBUG): - _log.debug('uinput simulated input %s %s %s', what, code, arg) + if logger.isEnabledFor(logging.DEBUG): + logger.debug('uinput simulated input %s %s %s', what, code, arg) return True except Exception as e: udevice = None - _log.warn('uinput write failed: %s', e) + logger.warning('uinput write failed: %s', e) def simulate_key(code, event): # X11 keycode but Solaar event code @@ -324,7 +321,7 @@ def simulate_key(code, event): # X11 keycode but Solaar event code return True if simulate_uinput(evdev.ecodes.EV_KEY, code - 8, event): return True - _log.warn('no way to simulate key input') + logger.warning('no way to simulate key input') def click_xtest(button, count): @@ -366,7 +363,7 @@ def click(button, count): return True if click_uinput(button, count): return True - _log.warn('no way to simulate mouse click') + logger.warning('no way to simulate mouse click') return False @@ -387,7 +384,7 @@ def simulate_scroll(dx, dy): success = simulate_uinput(evdev.ecodes.EV_REL, evdev.ecodes.REL_WHEEL, dy) if success: return True - _log.warn('no way to simulate scrolling') + logger.warning('no way to simulate scrolling') def thumb_wheel_up(f, r, d, a): @@ -465,7 +462,7 @@ def compile(self, c): k, v = next(iter(c.items())) if k in COMPONENTS: return COMPONENTS[k](v) - _log.warn('illegal component in rule: %s', c) + logger.warning('illegal component in rule: %s', c) return Condition() @@ -480,8 +477,8 @@ def __str__(self): return 'Rule%s[%s]' % (source, ', '.join([c.__str__() for c in self.components])) def evaluate(self, feature, notification, device, status, last_result): - if _log.isEnabledFor(_DEBUG): - _log.debug('evaluate rule: %s', self) + if logger.isEnabledFor(logging.DEBUG): + logger.debug('evaluate rule: %s', self) result = True for component in self.components: result = component.evaluate(feature, notification, device, status, result) @@ -508,8 +505,8 @@ def __str__(self): return 'CONDITION' def evaluate(self, feature, notification, device, status, last_result): - if _log.isEnabledFor(_DEBUG): - _log.debug('evaluate condition: %s', self) + if logger.isEnabledFor(logging.DEBUG): + logger.debug('evaluate condition: %s', self) return False @@ -525,8 +522,8 @@ def __str__(self): return 'Not: ' + str(self.component) def evaluate(self, feature, notification, device, status, last_result): - if _log.isEnabledFor(_DEBUG): - _log.debug('evaluate condition: %s', self) + if logger.isEnabledFor(logging.DEBUG): + logger.debug('evaluate condition: %s', self) result = self.component.evaluate(feature, notification, device, status, last_result) return None if result is None else not result @@ -543,8 +540,8 @@ def __str__(self): return 'Or: [' + ', '.join(str(c) for c in self.components) + ']' def evaluate(self, feature, notification, device, status, last_result): - if _log.isEnabledFor(_DEBUG): - _log.debug('evaluate condition: %s', self) + if logger.isEnabledFor(logging.DEBUG): + logger.debug('evaluate condition: %s', self) result = False for component in self.components: result = component.evaluate(feature, notification, device, status, last_result) @@ -567,8 +564,8 @@ def __str__(self): return 'And: [' + ', '.join(str(c) for c in self.components) + ']' def evaluate(self, feature, notification, device, status, last_result): - if _log.isEnabledFor(_DEBUG): - _log.debug('evaluate condition: %s', self) + if logger.isEnabledFor(logging.DEBUG): + logger.debug('evaluate condition: %s', self) result = True for component in self.components: result = component.evaluate(feature, notification, device, status, last_result) @@ -634,21 +631,21 @@ def __init__(self, process, warn=True): self.process = process if (not wayland and not x11_setup()) or (wayland and not gnome_dbus_interface_setup()): if warn: - _log.warn( + logger.warning( 'rules can only access active process in X11 or in Wayland under GNOME with Solaar Gnome extension - %s', self ) if not isinstance(process, str): if warn: - _log.warn('rule Process argument not a string: %s', process) + logger.warning('rule Process argument not a string: %s', process) self.process = str(process) def __str__(self): return 'Process: ' + str(self.process) def evaluate(self, feature, notification, device, status, last_result): - if _log.isEnabledFor(_DEBUG): - _log.debug('evaluate condition: %s', self) + if logger.isEnabledFor(logging.DEBUG): + logger.debug('evaluate condition: %s', self) if not isinstance(self.process, str): return False focus = x11_focus_prog() if not wayland else gnome_dbus_focus_prog() @@ -665,21 +662,21 @@ def __init__(self, process, warn=True): self.process = process if (not wayland and not x11_setup()) or (wayland and not gnome_dbus_interface_setup()): if warn: - _log.warn( + logger.warning( 'rules cannot access active mouse process ' 'in X11 or in Wayland under GNOME with Solaar Extension for GNOME - %s', self ) if not isinstance(process, str): if warn: - _log.warn('rule MouseProcess argument not a string: %s', process) + logger.warning('rule MouseProcess argument not a string: %s', process) self.process = str(process) def __str__(self): return 'MouseProcess: ' + str(self.process) def evaluate(self, feature, notification, device, status, last_result): - if _log.isEnabledFor(_DEBUG): - _log.debug('evaluate condition: %s', self) + if logger.isEnabledFor(logging.DEBUG): + logger.debug('evaluate condition: %s', self) if not isinstance(self.process, str): return False pointer_focus = x11_pointer_prog() if not wayland else gnome_dbus_pointer_prog() @@ -695,7 +692,7 @@ class Feature(Condition): def __init__(self, feature, warn=True): if not (isinstance(feature, str) and feature in _F): if warn: - _log.warn('rule Feature argument not name of a feature: %s', feature) + logger.warning('rule Feature argument not name of a feature: %s', feature) self.feature = None self.feature = _F[feature] @@ -703,8 +700,8 @@ def __str__(self): return 'Feature: ' + str(self.feature) def evaluate(self, feature, notification, device, status, last_result): - if _log.isEnabledFor(_DEBUG): - _log.debug('evaluate condition: %s', self) + if logger.isEnabledFor(logging.DEBUG): + logger.debug('evaluate condition: %s', self) return feature == self.feature def data(self): @@ -716,7 +713,7 @@ class Report(Condition): def __init__(self, report, warn=True): if not (isinstance(report, int)): if warn: - _log.warn('rule Report argument not an integer: %s', report) + logger.warning('rule Report argument not an integer: %s', report) self.report = -1 else: self.report = report @@ -725,8 +722,8 @@ def __str__(self): return 'Report: ' + str(self.report) def evaluate(self, report, notification, device, status, last_result): - if _log.isEnabledFor(_DEBUG): - _log.debug('evaluate condition: %s', self) + if logger.isEnabledFor(logging.DEBUG): + logger.debug('evaluate condition: %s', self) return (notification.address >> 4) == self.report def data(self): @@ -739,7 +736,7 @@ class Setting(Condition): def __init__(self, args, warn=True): if not (isinstance(args, list) and len(args) > 2): if warn: - _log.warn('rule Setting argument not list with minimum length 3: %s', args) + logger.warning('rule Setting argument not list with minimum length 3: %s', args) self.args = [] else: self.args = args @@ -748,24 +745,24 @@ def __str__(self): return 'Setting: ' + ' '.join([str(a) for a in self.args]) def evaluate(self, report, notification, device, status, last_result): - if _log.isEnabledFor(_DEBUG): - _log.debug('evaluate condition: %s', self) + if logger.isEnabledFor(logging.DEBUG): + logger.debug('evaluate condition: %s', self) if len(self.args) < 3: return None dev = _Device.find(self.args[0]) if self.args[0] is not None else device if dev is None: - _log.warn('Setting condition: device %s is not known', self.args[0]) + logger.warning('Setting condition: device %s is not known', self.args[0]) return False setting = next((s for s in dev.settings if s.name == self.args[1]), None) if setting is None: - _log.warn('Setting condition: setting %s is not the name of a setting for %s', self.args[1], dev.name) + logger.warning('Setting condition: setting %s is not the name of a setting for %s', self.args[1], dev.name) return None # should the value argument be checked to be sure it is acceptable?? needs to be careful about boolean toggle # TODO add compare methods for more validators try: result = setting.compare(self.args[2:], setting.read()) except Exception as e: - _log.warn('Setting condition: error when checking setting %s: %s', self.args, e) + logger.warning('Setting condition: error when checking setting %s: %s', self.args, e) result = False return result @@ -794,19 +791,19 @@ def __init__(self, modifiers, warn=True): self.modifiers.append(k) else: if warn: - _log.warn('unknown rule Modifier value: %s', k) + logger.warning('unknown rule Modifier value: %s', k) def __str__(self): return 'Modifiers: ' + str(self.desired) def evaluate(self, feature, notification, device, status, last_result): - if _log.isEnabledFor(_DEBUG): - _log.debug('evaluate condition: %s', self) + if logger.isEnabledFor(logging.DEBUG): + logger.debug('evaluate condition: %s', self) if gkeymap: current = gkeymap.get_modifier_state() # get the current keyboard modifier return self.desired == (current & MODIFIER_MASK) else: - _log.warn('no keymap so cannot determine modifier keys') + logger.warning('no keymap so cannot determine modifier keys') return False def data(self): @@ -825,16 +822,16 @@ def __init__(self, args, warn=True): if not args or not isinstance(args, (list, str)): if warn: - _log.warn('rule Key arguments unknown: %s' % args) + logger.warning('rule Key arguments unknown: %s' % args) key = default_key action = default_action elif isinstance(args, str): - _log.debug('rule Key assuming action "%s" for "%s"' % (default_action, args)) + logger.debug('rule Key assuming action "%s" for "%s"' % (default_action, args)) key = args action = default_action elif isinstance(args, list): if len(args) == 1: - _log.debug('rule Key assuming action "%s" for "%s"' % (default_action, args)) + logger.debug('rule Key assuming action "%s" for "%s"' % (default_action, args)) key, action = args[0], default_action elif len(args) >= 2: key, action = args[:2] @@ -843,22 +840,22 @@ def __init__(self, args, warn=True): self.key = _CONTROL[key] else: if warn: - _log.warn('rule Key key name not name of a Logitech key: %s' % key) + logger.warning('rule Key key name not name of a Logitech key: %s' % key) self.key = default_key if isinstance(action, str) and action in (self.DOWN, self.UP): self.action = action else: if warn: - _log.warn('rule Key action unknown: %s, assuming %s' % (action, default_action)) + logger.warning('rule Key action unknown: %s, assuming %s' % (action, default_action)) self.action = default_action def __str__(self): return 'Key: %s (%s)' % ((str(self.key) if self.key else 'None'), self.action) def evaluate(self, feature, notification, device, status, last_result): - if _log.isEnabledFor(_DEBUG): - _log.debug('evaluate condition: %s', self) + if logger.isEnabledFor(logging.DEBUG): + logger.debug('evaluate condition: %s', self) return bool(self.key and self.key == (key_down if self.action == self.DOWN else key_up)) def data(self): @@ -874,7 +871,7 @@ def __init__(self, args, warn=True): if not args or not isinstance(args, str): if warn: - _log.warn('rule KeyDown arguments unknown: %s' % args) + logger.warning('rule KeyDown arguments unknown: %s' % args) key = default_key elif isinstance(args, str): key = args @@ -883,15 +880,15 @@ def __init__(self, args, warn=True): self.key = _CONTROL[key] else: if warn: - _log.warn('rule Key key name not name of a Logitech key: %s' % key) + logger.warning('rule Key key name not name of a Logitech key: %s' % key) self.key = default_key def __str__(self): return 'KeyIsDown: %s' % (str(self.key) if self.key else 'None') def evaluate(self, feature, notification, device, status, last_result): - if _log.isEnabledFor(_DEBUG): - _log.debug('evaluate condition: %s', self) + if logger.isEnabledFor(logging.DEBUG): + logger.debug('evaluate condition: %s', self) return key_is_down(self.key) def data(self): @@ -920,13 +917,13 @@ def __init__(self, test, warn=True): test = [test] if isinstance(test, list) and all(isinstance(t, int) for t in test): if warn: - _log.warn('Test rules consisting of numbers are deprecated, converting to a TestBytes condition') + logger.warning('Test rules consisting of numbers are deprecated, converting to a TestBytes condition') self.__class__ = TestBytes self.__init__(test, warn=warn) elif isinstance(test, list): if test[0] in MOUSE_GESTURE_TESTS: if warn: - _log.warn('mouse movement test %s deprecated, converting to a MouseGesture', test) + logger.warning('mouse movement test %s deprecated, converting to a MouseGesture', test) self.__class__ = MouseGesture self.__init__(MOUSE_GESTURE_TESTS[0][test], warn=warn) elif test[0] in TESTS: @@ -935,19 +932,19 @@ def __init__(self, test, warn=True): self.parameter = test[1] if len(test) > 1 else None else: if warn: - _log.warn('rule Test name not name of a test: %s', test) + logger.warning('rule Test name not name of a test: %s', test) self.test = 'False' self.function = TESTS['False'][0] else: if warn: - _log.warn('rule Test argument not valid %s', test) + logger.warning('rule Test argument not valid %s', test) def __str__(self): return 'Test: ' + str(self.test) def evaluate(self, feature, notification, device, status, last_result): - if _log.isEnabledFor(_DEBUG): - _log.debug('evaluate condition: %s', self) + if logger.isEnabledFor(logging.DEBUG): + logger.debug('evaluate condition: %s', self) return self.function(feature, notification.address, notification.data, self.parameter) def data(self): @@ -965,14 +962,14 @@ def __init__(self, test, warn=True): self.function = bit_test(*test) if len(test) == 3 else range_test(*test) else: if warn: - _log.warn('rule TestBytes argument not valid %s', test) + logger.warning('rule TestBytes argument not valid %s', test) def __str__(self): return 'TestBytes: ' + str(self.test) def evaluate(self, feature, notification, device, status, last_result): - if _log.isEnabledFor(_DEBUG): - _log.debug('evaluate condition: %s', self) + if logger.isEnabledFor(logging.DEBUG): + logger.debug('evaluate condition: %s', self) return self.function(feature, notification.address, notification.data) def data(self): @@ -991,15 +988,15 @@ def __init__(self, movements, warn=True): for x in movements: if x not in self.MOVEMENTS and x not in _CONTROL: if warn: - _log.warn('rule Mouse Gesture argument not direction or name of a Logitech key: %s', x) + logger.warning('rule Mouse Gesture argument not direction or name of a Logitech key: %s', x) self.movements = movements def __str__(self): return 'MouseGesture: ' + ' '.join(self.movements) def evaluate(self, feature, notification, device, status, last_result): - if _log.isEnabledFor(_DEBUG): - _log.debug('evaluate condition: %s', self) + if logger.isEnabledFor(logging.DEBUG): + logger.debug('evaluate condition: %s', self) if feature == _F.MOUSE_GESTURE: d = notification.data data = _unpack('!' + (int(len(d) / 2) * 'h'), d) @@ -1033,7 +1030,7 @@ class Active(Condition): def __init__(self, devID, warn=True): if not (isinstance(devID, str)): if warn: - _log.warn('rule Active argument not a string: %s', devID) + logger.warning('rule Active argument not a string: %s', devID) self.devID = '' self.devID = devID @@ -1041,8 +1038,8 @@ def __str__(self): return 'Active: ' + str(self.devID) def evaluate(self, feature, notification, device, status, last_result): - if _log.isEnabledFor(_DEBUG): - _log.debug('evaluate condition: %s', self) + if logger.isEnabledFor(logging.DEBUG): + logger.debug('evaluate condition: %s', self) dev = _Device.find(self.devID) return bool(dev and dev.ping()) @@ -1055,7 +1052,7 @@ class Device(Condition): def __init__(self, devID, warn=True): if not (isinstance(devID, str)): if warn: - _log.warn('rule Device argument not a string: %s', devID) + logger.warning('rule Device argument not a string: %s', devID) self.devID = '' self.devID = devID @@ -1063,8 +1060,8 @@ def __str__(self): return 'Device: ' + str(self.devID) def evaluate(self, feature, notification, device, status, last_result): - if _log.isEnabledFor(_DEBUG): - _log.debug('evaluate condition: %s', self) + if logger.isEnabledFor(logging.DEBUG): + logger.debug('evaluate condition: %s', self) return device.unitId == self.devID or device.serial == self.devID def data(self): @@ -1076,7 +1073,7 @@ class Host(Condition): def __init__(self, host, warn=True): if not (isinstance(host, str)): if warn: - _log.warn('rule Host Name argument not a string: %s', host) + logger.warning('rule Host Name argument not a string: %s', host) self.host = '' self.host = host @@ -1084,8 +1081,8 @@ def __str__(self): return 'Host: ' + str(self.host) def evaluate(self, feature, notification, device, status, last_result): - if _log.isEnabledFor(_DEBUG): - _log.debug('evaluate condition: %s', self) + if logger.isEnabledFor(logging.DEBUG): + logger.debug('evaluate condition: %s', self) import socket hostname = socket.getfqdn() return hostname.startswith(self.host) @@ -1109,13 +1106,13 @@ def __init__(self, args, warn=True): self.key_names, self.action = self.regularize_args(args) if not isinstance(self.key_names, list): if warn: - _log.warn('rule KeyPress keys not key names %s', self.keys_names) + logger.warning('rule KeyPress keys not key names %s', self.keys_names) self.key_symbols = [] else: self.key_symbols = [XK_KEYS.get(k, None) for k in self.key_names] if not all(self.key_symbols): if warn: - _log.warn('rule KeyPress keys not key names %s', self.key_names) + logger.warning('rule KeyPress keys not key names %s', self.key_names) self.key_symbols = [] def regularize_args(self, args): @@ -1168,7 +1165,7 @@ def keyDown(self, keysyms, modifiers): for k in keysyms: (keycode, level) = self.keysym_to_keycode(k, modifiers) if keycode is None: - _log.warn('rule KeyPress key symbol not currently available %s', self) + logger.warning('rule KeyPress key symbol not currently available %s', self) elif self.action != CLICK or self.needed(keycode, modifiers): # only check needed when clicking self.mods(level, modifiers, _KEY_PRESS) simulate_key(keycode, _KEY_PRESS) @@ -1183,15 +1180,15 @@ def keyUp(self, keysyms, modifiers): def evaluate(self, feature, notification, device, status, last_result): if gkeymap: current = gkeymap.get_modifier_state() - if _log.isEnabledFor(_INFO): - _log.info('KeyPress action: %s %s, group %s, modifiers %s', self.key_names, self.action, kbdgroup(), current) + if logger.isEnabledFor(logging.INFO): + logger.info('KeyPress action: %s %s, group %s, modifiers %s', self.key_names, self.action, kbdgroup(), current) if self.action != RELEASE: self.keyDown(self.key_symbols, current) if self.action != DEPRESS: self.keyUp(reversed(self.key_symbols), current) _time.sleep(0.01) else: - _log.warn('no keymap so cannot determine which keycode to send') + logger.warning('no keymap so cannot determine which keycode to send') return None def data(self): @@ -1215,7 +1212,7 @@ def __init__(self, amounts, warn=True): amounts = amounts[0] if not (len(amounts) == 2 and all([isinstance(a, numbers.Number) for a in amounts])): if warn: - _log.warn('rule MouseScroll argument not two numbers %s', amounts) + logger.warning('rule MouseScroll argument not two numbers %s', amounts) amounts = [0, 0] self.amounts = amounts @@ -1228,8 +1225,8 @@ def evaluate(self, feature, notification, device, status, last_result): amounts = self.amounts if isinstance(last_result, numbers.Number): amounts = [math.floor(last_result * a) for a in self.amounts] - if _log.isEnabledFor(_INFO): - _log.info('MouseScroll action: %s %s %s', self.amounts, last_result, amounts) + if logger.isEnabledFor(logging.INFO): + logger.info('MouseScroll action: %s %s %s', self.amounts, last_result, amounts) dx, dy = amounts simulate_scroll(dx, dy) _time.sleep(0.01) @@ -1249,7 +1246,7 @@ def __init__(self, args, warn=True): self.button = str(args[0]) if len(args) >= 0 else None if self.button not in buttons: if warn: - _log.warn('rule MouseClick action: button %s not known', self.button) + logger.warning('rule MouseClick action: button %s not known', self.button) self.button = None count = args[1] if len(args) >= 2 else 1 try: @@ -1258,15 +1255,15 @@ def __init__(self, args, warn=True): if count in [CLICK, DEPRESS, RELEASE]: self.count = count elif warn: - _log.warn('rule MouseClick action: argument %s should be an integer or CLICK, PRESS, or RELEASE', count) + logger.warning('rule MouseClick action: argument %s should be an integer or CLICK, PRESS, or RELEASE', count) self.count = 1 def __str__(self): return 'MouseClick: %s (%d)' % (self.button, self.count) def evaluate(self, feature, notification, device, status, last_result): - if _log.isEnabledFor(_INFO): - _log.info('MouseClick action: %d %s' % (self.count, self.button)) + if logger.isEnabledFor(logging.INFO): + logger.info('MouseClick action: %d %s' % (self.count, self.button)) if self.button and self.count: click(buttons[self.button], self.count) _time.sleep(0.01) @@ -1281,7 +1278,7 @@ class Set(Action): def __init__(self, args, warn=True): if not (isinstance(args, list) and len(args) > 2): if warn: - _log.warn('rule Set argument not list with minimum length 3: %s', args) + logger.warning('rule Set argument not list with minimum length 3: %s', args) self.args = [] else: self.args = args @@ -1295,19 +1292,19 @@ def evaluate(self, feature, notification, device, status, last_result): if len(self.args) < 3: return None - if _log.isEnabledFor(_INFO): - _log.info('Set action: %s', self.args) + if logger.isEnabledFor(logging.INFO): + logger.info('Set action: %s', self.args) dev = _Device.find(self.args[0]) if self.args[0] is not None else device if dev is None: - _log.warn('Set action: device %s is not known', self.args[0]) + logger.warning('Set action: device %s is not known', self.args[0]) return None setting = next((s for s in dev.settings if s.name == self.args[1]), None) if setting is None: - _log.warn('Set action: setting %s is not the name of a setting for %s', self.args[1], dev.name) + logger.warning('Set action: setting %s is not the name of a setting for %s', self.args[1], dev.name) return None args = setting.acceptable(self.args[2:], setting.read()) if args is None: - _log.warn('Set Action: invalid args %s for setting %s of %s', self.args[2:], self.args[1], self.args[0]) + logger.warning('Set Action: invalid args %s for setting %s of %s', self.args[2:], self.args[1], self.args[0]) return None _change_setting(dev, setting, args) return None @@ -1323,7 +1320,7 @@ def __init__(self, args, warn=True): args = [args] if not (isinstance(args, list) and all(isinstance(arg), str) for arg in args): if warn: - _log.warn('rule Execute argument not list of strings: %s', args) + logger.warning('rule Execute argument not list of strings: %s', args) self.args = [] else: self.args = args @@ -1333,8 +1330,8 @@ def __str__(self): def evaluate(self, feature, notification, device, status, last_result): import subprocess - if _log.isEnabledFor(_INFO): - _log.info('Execute action: %s', self.args) + if logger.isEnabledFor(logging.INFO): + logger.info('Execute action: %s', self.args) subprocess.Popen(self.args) return None @@ -1352,10 +1349,10 @@ def __init__(self, args, warn=True): args = [args] if not (isinstance(args, list) and len(args) >= 1): if warn: - _log.warn('rule Later argument not list with minimum length 1: %s', args) + logger.warning('rule Later argument not list with minimum length 1: %s', args) elif not (isinstance(args[0], int)) or not 0 < args[0] < 101: if warn: - _log.warn('rule Later argument delay not integer between 1 and 100: %s', args) + logger.warning('rule Later argument delay not integer between 1 and 100: %s', args) else: self.delay = args[0] self.rule = Rule(args[1:], warn=warn) @@ -1446,8 +1443,8 @@ def key_is_down(key): def evaluate_rules(feature, notification, device, status): - if _log.isEnabledFor(_DEBUG): - _log.debug('evaluating rules on %s', notification) + if logger.isEnabledFor(logging.DEBUG): + logger.debug('evaluating rules on %s', notification) rules.evaluate(feature, notification, device, status, True) @@ -1541,15 +1538,15 @@ def convert(elem): # Save only user-defined rules rules_to_save = sum((r.data()['Rule'] for r in rules.components if r.source == file_name), []) if True: # save even if there are no rules to save - if _log.isEnabledFor(_INFO): - _log.info('saving %d rule(s) to %s', len(rules_to_save), file_name) + if logger.isEnabledFor(logging.INFO): + logger.info('saving %d rule(s) to %s', len(rules_to_save), file_name) try: with open(file_name, 'w') as f: if rules_to_save: f.write('%YAML 1.3\n') # Write version manually _yaml_dump_all(convert([r['Rule'] for r in rules_to_save]), f, **dump_settings) except Exception as e: - _log.error('failed to save to %s\n%s', file_name, e) + logger.error('failed to save to %s\n%s', file_name, e) return False return True @@ -1563,13 +1560,13 @@ def _load_config_rule_file(): loaded_rules = [] for loaded_rule in _yaml_safe_load_all(config_file): rule = Rule(loaded_rule, source=_file_path) - if _log.isEnabledFor(_DEBUG): - _log.debug('load rule: %s', rule) + if logger.isEnabledFor(logging.DEBUG): + logger.debug('load rule: %s', rule) loaded_rules.append(rule) - if _log.isEnabledFor(_INFO): - _log.info('loaded %d rules from %s', len(loaded_rules), config_file.name) + if logger.isEnabledFor(logging.INFO): + logger.info('loaded %d rules from %s', len(loaded_rules), config_file.name) except Exception as e: - _log.error('failed to load from %s\n%s', _file_path, e) + logger.error('failed to load from %s\n%s', _file_path, e) rules = Rule([Rule(loaded_rules, source=_file_path), built_in_rules]) diff --git a/lib/logitech_receiver/hidpp10.py b/lib/logitech_receiver/hidpp10.py index 0818ef167e..51de5c2870 100644 --- a/lib/logitech_receiver/hidpp10.py +++ b/lib/logitech_receiver/hidpp10.py @@ -16,7 +16,7 @@ ## with this program; if not, write to the Free Software Foundation, Inc., ## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -from logging import getLogger # , DEBUG as _DEBUG +import logging from .common import BATTERY_APPROX as _BATTERY_APPROX from .common import FirmwareInfo as _FirmwareInfo @@ -26,8 +26,7 @@ from .common import strhex as _strhex from .hidpp20 import BATTERY_STATUS, FIRMWARE_KIND -_log = getLogger(__name__) -del getLogger +logger = logging.getLogger(__name__) # # Constants - most of them as defined by the official Logitech HID++ 1.0 @@ -258,7 +257,7 @@ def parse_battery_status(register, reply): elif charging_byte & 0x22 == 0x22: status_text = BATTERY_STATUS.full else: - _log.warn('could not parse 0x07 battery status: %02X (level %02X)', charging_byte, status_byte) + logger.warning('could not parse 0x07 battery status: %02X (level %02X)', charging_byte, status_byte) status_text = None if charging_byte & 0x03 and status_byte == 0: diff --git a/lib/logitech_receiver/hidpp20.py b/lib/logitech_receiver/hidpp20.py index d4c4555ad7..40f96fe176 100644 --- a/lib/logitech_receiver/hidpp20.py +++ b/lib/logitech_receiver/hidpp20.py @@ -18,13 +18,9 @@ # Logitech Unifying Receiver API. +import logging import threading as _threading -from logging import DEBUG as _DEBUG -from logging import ERROR as _ERROR -from logging import INFO as _INFO -from logging import WARNING as _WARNING -from logging import getLogger from struct import pack as _pack from struct import unpack as _unpack from typing import List @@ -43,8 +39,7 @@ from .common import int2bytes as _int2bytes from .i18n import _ -_log = getLogger(__name__) -del getLogger +logger = logging.getLogger(__name__) def hexint_presenter(dumper, data): @@ -271,7 +266,7 @@ def _check(self): if fs_index: count = self.device.request(fs_index << 8) if count is None: - _log.warn('FEATURE_SET found, but failed to read features count') + logger.warn('FEATURE_SET found, but failed to read features count') return False else: self.count = ord(count[:1]) + 1 # ROOT feature not included in count @@ -455,8 +450,8 @@ def _getCidReporting(self): mapped_data = feature_request(self._device, FEATURE.REPROG_CONTROLS_V4, 0x20, *tuple(_pack('!H', self._cid))) if mapped_data: cid, mapping_flags_1, mapped_to = _unpack('!HBH', mapped_data[:5]) - if cid != self._cid and _log.isEnabledFor(_WARNING): - _log.warn( + if cid != self._cid and logger.isEnabledFor(logging.WARNING): + logger.warn( f'REPROG_CONTROLS_V4 endpoint getCidReporting on device {self._device} replied ' + f'with a different control ID ({cid}) than requested ({self._cid}).' ) @@ -469,8 +464,8 @@ def _getCidReporting(self): else: raise FeatureCallError(msg='No reply from device.') except FeatureCallError: # if the key hasn't ever been configured then the read may fail so only produce a warning - if _log.isEnabledFor(_WARNING): - _log.warn( + if logger.isEnabledFor(logging.WARNING): + logger.warn( f'Feature Call Error in _getCidReporting on device {self._device} for cid {self._cid} - use defaults' ) # Clear flags and set mapping target to self @@ -527,8 +522,8 @@ def _setCidReporting(self, flags=None, remap=0): # TODO: to fully support version 4 of REPROG_CONTROLS_V4, append `(bfield >> 8) & 0xff` here. # But older devices might behave oddly given that byte, so we don't send it. ret = feature_request(self._device, FEATURE.REPROG_CONTROLS_V4, 0x30, *pkt) - if ret is None or _unpack('!BBBBB', ret[:5]) != pkt and _log.isEnabledFor(_DEBUG): - _log.debug(f"REPROG_CONTROLS_v4 setCidReporting on device {self._device} didn't echo request packet.") + if ret is None or _unpack('!BBBBB', ret[:5]) != pkt and logger.isEnabledFor(logging.DEBUG): + logger.debug(f"REPROG_CONTROLS_v4 setCidReporting on device {self._device} didn't echo request packet.") class PersistentRemappableAction(): @@ -608,8 +603,8 @@ def __init__(self, device, count, version): elif FEATURE.REPROG_CONTROLS_V2 in self.device.features: self.keyversion = FEATURE.REPROG_CONTROLS_V2 else: - if _log.isEnabledFor(_ERROR): - _log.error(f'Trying to read keys on device {device} which has no REPROG_CONTROLS(_VX) support.') + if logger.isEnabledFor(logging.ERROR): + logger.error(f'Trying to read keys on device {device} which has no REPROG_CONTROLS(_VX) support.') self.keyversion = None self.keys = [None] * count @@ -634,8 +629,8 @@ def _query_key(self, index: int): self.cid_to_tid[cid] = tid if group != 0: # 0 = does not belong to a group self.group_cids[special_keys.CID_GROUP[group]].append(cid) - elif _log.isEnabledFor(_WARNING): - _log.warn(f"Key with index {index} was expected to exist but device doesn't report it.") + elif logger.isEnabledFor(logging.WARNING): + logger.warn(f"Key with index {index} was expected to exist but device doesn't report it.") def _ensure_all_keys_queried(self): """The retrieval of key information is lazy, but for certain functionality @@ -697,8 +692,8 @@ def _query_key(self, index: int): cid, tid, flags = _unpack('!HHB', keydata[:5]) self.keys[index] = ReprogrammableKey(self.device, index, cid, tid, flags) self.cid_to_tid[cid] = tid - elif _log.isEnabledFor(_WARNING): - _log.warn(f"Key with index {index} was expected to exist but device doesn't report it.") + elif logger.isEnabledFor(logging.WARNING): + logger.warn(f"Key with index {index} was expected to exist but device doesn't report it.") class KeysArrayV4(KeysArrayV1): @@ -717,8 +712,8 @@ def _query_key(self, index: int): self.cid_to_tid[cid] = tid if group != 0: # 0 = does not belong to a group self.group_cids[special_keys.CID_GROUP[group]].append(cid) - elif _log.isEnabledFor(_WARNING): - _log.warn(f"Key with index {index} was expected to exist but device doesn't report it.") + elif logger.isEnabledFor(logging.WARNING): + logger.warn(f"Key with index {index} was expected to exist but device doesn't report it.") # we are only interested in the current host, so use 0xFF for the host throughout @@ -762,8 +757,8 @@ def _query_key(self, index: int): elif actionId == special_keys.ACTIONID.Empty: # purge data from empty value remapped = modifiers = 0 self.keys[index] = PersistentRemappableAction(self.device, index, key, actionId, remapped, modifiers, status) - elif _log.isEnabledFor(_WARNING): - _log.warn(f"Key with index {index} was expected to exist but device doesn't report it.") + elif logger.isEnabledFor(logging.WARNING): + logger.warn(f"Key with index {index} was expected to exist but device doesn't report it.") # Gesture Ids for feature GESTURE_2 @@ -1050,8 +1045,8 @@ def read(self): try: value = feature_request(self._device, FEATURE.GESTURE_2, 0x50, self.id, 0xFF) except FeatureCallError: # some calls produce an error (notably spec 5 multiplier on K400Plus) - if _log.isEnabledFor(_WARNING): - _log.warn(f'Feature Call Error reading Gesture Spec on device {self._device} for spec {self.id} - use None') + if logger.isEnabledFor(logging.WARNING): + logger.warn(f'Feature Call Error reading Gesture Spec on device {self._device} for spec {self.id} - use None') return None return _bytes2int(value[:self.byte_count]) @@ -1093,12 +1088,12 @@ def __init__(self, device): self.params[param.param] = param elif field_high == 0x04: if field_low != 0x00: - _log.error(f'Unimplemented GESTURE_2 grouping {field_low} {field_high} found.') + logger.error(f'Unimplemented GESTURE_2 grouping {field_low} {field_high} found.') elif field_high & 0xF0 == 0x40: spec = Spec(device, field_low, field_high) self.specs[spec.spec] = spec else: - _log.warn(f'Unimplemented GESTURE_2 field {field_low} {field_high} found.') + logger.warn(f'Unimplemented GESTURE_2 field {field_low} {field_high} found.') index += 1 def gesture(self, gesture): @@ -1581,7 +1576,7 @@ def write(self, device): try: written = 1 if OnboardProfiles.write_sector(device, 0, self.to_bytes()) else 0 except Exception as e: - _log.warn('Exception writing onboard profile control sector') + logger.warn('Exception writing onboard profile control sector') raise e for p in self.profiles.values(): try: @@ -1589,7 +1584,7 @@ def write(self, device): raise Exception(f'Sector {p.sector} not a writable sector') written += 1 if OnboardProfiles.write_sector(device, p.sector, p.to_bytes(self.size)) else 0 except Exception as e: - _log.warn(f'Exception writing onboard profile sector {p.sector}') + logger.warn(f'Exception writing onboard profile sector {p.sector}') raise e return written @@ -1639,8 +1634,8 @@ def get_firmware(device): fw_info = _FirmwareInfo(FIRMWARE_KIND.Other, '', '', None) fw.append(fw_info) - # if _log.isEnabledFor(_DEBUG): - # _log.debug("device %d firmware %s", devnumber, fw_info) + # if logger.isEnabledFor(logging.DEBUG): + # logger.debug("device %d firmware %s", devnumber, fw_info) return tuple(fw) @@ -1670,8 +1665,8 @@ def get_kind(device): kind = feature_request(device, FEATURE.DEVICE_NAME, 0x20) if kind: kind = ord(kind[:1]) - # if _log.isEnabledFor(_DEBUG): - # _log.debug("device %d type %d = %s", devnumber, kind, DEVICE_KIND[kind]) + # if logger.isEnabledFor(logging.DEBUG): + # logger.debug("device %d type %d = %s", devnumber, kind, DEVICE_KIND[kind]) return DEVICE_KIND[kind] @@ -1691,7 +1686,7 @@ def get_name(device): if fragment: name += fragment[:name_length - len(name)] else: - _log.error('failed to read whole name of %s (expected %d chars)', device, name_length) + logger.error('failed to read whole name of %s (expected %d chars)', device, name_length) return None return name.decode('utf-8') @@ -1714,7 +1709,7 @@ def get_friendly_name(device): initial_null = 0 if fragment[0] else 1 # initial null actually seen on a device name += fragment[initial_null:name_length + initial_null - len(name)] else: - _log.error('failed to read whole name of %s (expected %d chars)', device, name_length) + logger.error('failed to read whole name of %s (expected %d chars)', device, name_length) return None return name.decode('utf-8') @@ -1730,8 +1725,8 @@ def decipher_battery_status(report): discharge, next, status = _unpack('!BBB', report[:3]) discharge = None if discharge == 0 else discharge status = BATTERY_STATUS[status] - if _log.isEnabledFor(_DEBUG): - _log.debug('battery status %s%% charged, next %s%%, status %s', discharge, next, status) + if logger.isEnabledFor(logging.DEBUG): + logger.debug('battery status %s%% charged, next %s%%, status %s', discharge, next, status) return FEATURE.BATTERY_STATUS, discharge, next, status, None @@ -1744,8 +1739,8 @@ def get_battery_unified(device): def decipher_battery_unified(report): discharge, level, status, _ignore = _unpack('!BBBB', report[:4]) status = BATTERY_STATUS[status] - if _log.isEnabledFor(_DEBUG): - _log.debug('battery unified %s%% charged, level %s, charging %s', discharge, level, status) + if logger.isEnabledFor(logging.DEBUG): + logger.debug('battery unified %s%% charged, level %s, charging %s', discharge, level, status) level = ( _BATTERY_APPROX.full if level == 8 # full else _BATTERY_APPROX.good if level == 4 # good @@ -1806,8 +1801,8 @@ def decipher_battery_voltage(report): if level[0] < voltage: charge_lvl = level[1] break - if _log.isEnabledFor(_DEBUG): - _log.debug( + if logger.isEnabledFor(logging.DEBUG): + logger.debug( 'battery voltage %d mV, charging %s, status %d = %s, level %s, type %s', voltage, status, (flags & 0x03), charge_sts, charge_lvl, charge_type ) @@ -2015,8 +2010,8 @@ def get_host_names(device): def set_host_name(device, name, currentName=''): name = bytearray(name, 'utf-8') currentName = bytearray(currentName, 'utf-8') - if _log.isEnabledFor(_INFO): - _log.info('Setting host name to %s', name) + if logger.isEnabledFor(logging.INFO): + logger.info('Setting host name to %s', name) state = feature_request(device, FEATURE.HOSTS_INFO, 0x00) if state: flags, _ignore, _ignore, currentHost = _unpack('!BBBB', state[:4]) diff --git a/lib/logitech_receiver/listener.py b/lib/logitech_receiver/listener.py index 86dc7013f4..95f7732737 100644 --- a/lib/logitech_receiver/listener.py +++ b/lib/logitech_receiver/listener.py @@ -16,12 +16,9 @@ ## with this program; if not, write to the Free Software Foundation, Inc., ## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +import logging import threading as _threading -from logging import DEBUG as _DEBUG -from logging import INFO as _INFO -from logging import getLogger - from . import base as _base # from time import time as _timestamp @@ -32,8 +29,7 @@ except ImportError: from queue import Queue as _Queue -_log = getLogger(__name__) -del getLogger +logger = logging.getLogger(__name__) # # @@ -64,10 +60,10 @@ def __init__(self, listener, path, handle): def _open(self): handle = _base.open_path(self.path) if handle is None: - _log.error('%r failed to open new handle', self) + logger.error('%r failed to open new handle', self) else: - # if _log.isEnabledFor(_DEBUG): - # _log.debug("%r opened new handle %d", self, handle) + # if logger.isEnabledFor(logging.DEBUG): + # logger.debug("%r opened new handle %d", self, handle) self._local.handle = handle self._handles.append(handle) return handle @@ -76,8 +72,8 @@ def close(self): if self._local: self._local = None handles, self._handles = self._handles, [] - if _log.isEnabledFor(_DEBUG): - _log.debug('%r closing %s', self, handles) + if logger.isEnabledFor(logging.DEBUG): + logger.debug('%r closing %s', self, handles) for h in handles: _base.close(h) @@ -155,8 +151,8 @@ def run(self): self._active = True # replace the handle with a threaded one self.receiver.handle = _ThreadedHandle(self, self.receiver.path, self.receiver.handle) - if _log.isEnabledFor(_INFO): - _log.info('started with %s (%d)', self.receiver, int(self.receiver.handle)) + if logger.isEnabledFor(logging.INFO): + logger.info('started with %s (%d)', self.receiver, int(self.receiver.handle)) self.has_started() if self.receiver.isDevice: # ping (wired or BT) devices to see if they are really online @@ -168,7 +164,7 @@ def run(self): try: n = _base.read(self.receiver.handle, _EVENT_READ_TIMEOUT) except _base.NoReceiver: - _log.warning('%s disconnected', self.receiver.name) + logger.warning('%s disconnected', self.receiver.name) self.receiver.close() break if n: @@ -179,7 +175,7 @@ def run(self): try: self._notifications_callback(n) except Exception: - _log.exception('processing %s', n) + logger.exception('processing %s', n) del self._queued_notifications self.has_stopped() @@ -206,8 +202,8 @@ def _notifications_hook(self, n): # i.e. triggered by a callback handling a previous notification. assert _threading.current_thread() == self if self._active: # and _threading.current_thread() == self: - # if _log.isEnabledFor(_DEBUG): - # _log.debug("queueing unhandled %s", n) + # if logger.isEnabledFor(logging.DEBUG): + # logger.debug("queueing unhandled %s", n) if not self._queued_notifications.full(): self._queued_notifications.put(n) diff --git a/lib/logitech_receiver/notifications.py b/lib/logitech_receiver/notifications.py index eaca1a7c71..32d1105202 100644 --- a/lib/logitech_receiver/notifications.py +++ b/lib/logitech_receiver/notifications.py @@ -17,11 +17,9 @@ # Handles incoming events from the receiver/devices, updating the related # status object as appropriate. +import logging import threading as _threading -from logging import DEBUG as _DEBUG -from logging import INFO as _INFO -from logging import getLogger from struct import unpack as _unpack from . import diversion as _diversion @@ -34,8 +32,7 @@ from .status import ALERT as _ALERT from .status import KEYS as _K -_log = getLogger(__name__) -del getLogger +logger = logging.getLogger(__name__) _R = _hidpp10.REGISTERS _F = _hidpp20.FEATURE @@ -73,8 +70,8 @@ def _process_receiver_notification(receiver, status, n): if n.sub_id == 0x4A: # pairing lock notification status.lock_open = bool(n.address & 0x01) reason = (_('pairing lock is open') if status.lock_open else _('pairing lock is closed')) - if _log.isEnabledFor(_INFO): - _log.info('%s: %s', receiver, reason) + if logger.isEnabledFor(logging.INFO): + logger.info('%s: %s', receiver, reason) status[_K.ERROR] = None if status.lock_open: status.new_device = None @@ -82,7 +79,7 @@ def _process_receiver_notification(receiver, status, n): if pair_error: status[_K.ERROR] = error_string = _hidpp10.PAIRING_ERRORS[pair_error] status.new_device = None - _log.warn('pairing error %d: %s', pair_error, error_string) + logger.warning('pairing error %d: %s', pair_error, error_string) status.changed(reason=reason) return True @@ -90,8 +87,8 @@ def _process_receiver_notification(receiver, status, n): with notification_lock: status.discovering = n.address == 0x00 reason = (_('discovery lock is open') if status.discovering else _('discovery lock is closed')) - if _log.isEnabledFor(_INFO): - _log.info('%s: %s', receiver, reason) + if logger.isEnabledFor(logging.INFO): + logger.info('%s: %s', receiver, reason) status[_K.ERROR] = None if status.discovering: status.counter = status.device_address = status.device_authentication = status.device_name = None @@ -99,7 +96,7 @@ def _process_receiver_notification(receiver, status, n): discover_error = ord(n.data[:1]) if discover_error: status[_K.ERROR] = discover_string = _hidpp10.BOLT_PAIRING_ERRORS[discover_error] - _log.warn('bolt discovering error %d: %s', discover_error, discover_string) + logger.warning('bolt discovering error %d: %s', discover_error, discover_string) status.changed(reason=reason) return True @@ -124,8 +121,8 @@ def _process_receiver_notification(receiver, status, n): status.device_passkey = None status.lock_open = n.address == 0x00 reason = (_('pairing lock is open') if status.lock_open else _('pairing lock is closed')) - if _log.isEnabledFor(_INFO): - _log.info('%s: %s', receiver, reason) + if logger.isEnabledFor(logging.INFO): + logger.info('%s: %s', receiver, reason) status[_K.ERROR] = None if not status.lock_open: status.counter = status.device_address = status.device_authentication = status.device_name = None @@ -137,7 +134,7 @@ def _process_receiver_notification(receiver, status, n): if pair_error: status[_K.ERROR] = error_string = _hidpp10.BOLT_PAIRING_ERRORS[pair_error] status.new_device = None - _log.warn('pairing error %d: %s', pair_error, error_string) + logger.warning('pairing error %d: %s', pair_error, error_string) status.changed(reason=reason) return True @@ -149,7 +146,7 @@ def _process_receiver_notification(receiver, status, n): elif n.sub_id == _R.passkey_pressed_notification: # Bolt pairing return True - _log.warn('%s: unhandled notification %s', receiver, n) + logger.warning('%s: unhandled notification %s', receiver, n) # @@ -190,46 +187,46 @@ def _process_device_notification(device, status, n): # assuming 0x00 to 0x3F are feature (HID++ 2.0) notifications if not device.features: - _log.warn('%s: feature notification but features not set up: %02X %s', device, n.sub_id, n) + logger.warning('%s: feature notification but features not set up: %02X %s', device, n.sub_id, n) return False try: feature = device.features.get_feature(n.sub_id) except IndexError: - _log.warn('%s: notification from invalid feature index %02X: %s', device, n.sub_id, n) + logger.warning('%s: notification from invalid feature index %02X: %s', device, n.sub_id, n) return False return _process_feature_notification(device, status, n, feature) def _process_dj_notification(device, status, n): - if _log.isEnabledFor(_DEBUG): - _log.debug('%s (%s) DJ %s', device, device.protocol, n) + if logger.isEnabledFor(logging.DEBUG): + logger.debug('%s (%s) DJ %s', device, device.protocol, n) if n.sub_id == 0x40: # do all DJ paired notifications also show up as HID++ 1.0 notifications? - if _log.isEnabledFor(_INFO): - _log.info('%s: ignoring DJ unpaired: %s', device, n) + if logger.isEnabledFor(logging.INFO): + logger.info('%s: ignoring DJ unpaired: %s', device, n) return True if n.sub_id == 0x41: # do all DJ paired notifications also show up as HID++ 1.0 notifications? - if _log.isEnabledFor(_INFO): - _log.info('%s: ignoring DJ paired: %s', device, n) + if logger.isEnabledFor(logging.INFO): + logger.info('%s: ignoring DJ paired: %s', device, n) return True if n.sub_id == 0x42: connected = not n.address & 0x01 - if _log.isEnabledFor(_INFO): - _log.info('%s: DJ connection: %s %s', device, connected, n) + if logger.isEnabledFor(logging.INFO): + logger.info('%s: DJ connection: %s %s', device, connected, n) status.changed(active=connected, alert=_ALERT.NONE, reason=_('connected') if connected else _('disconnected')) return True - _log.warn('%s: unrecognized DJ %s', device, n) + logger.warning('%s: unrecognized DJ %s', device, n) def _process_hidpp10_custom_notification(device, status, n): - if _log.isEnabledFor(_DEBUG): - _log.debug('%s (%s) custom notification %s', device, device.protocol, n) + if logger.isEnabledFor(logging.DEBUG): + logger.debug('%s (%s) custom notification %s', device, device.protocol, n) if n.sub_id in (_R.battery_status, _R.battery_charge): # message layout: 10 ix <00> @@ -242,11 +239,11 @@ def _process_hidpp10_custom_notification(device, status, n): if n.sub_id == _R.keyboard_illumination: # message layout: 10 ix 17("address") # TODO anything we can do with this? - if _log.isEnabledFor(_INFO): - _log.info('illumination event: %s', n) + if logger.isEnabledFor(logging.INFO): + logger.info('illumination event: %s', n) return True - _log.warn('%s: unrecognized %s', device, n) + logger.warning('%s: unrecognized %s', device, n) def _process_hidpp10_notification(device, status, n): @@ -261,7 +258,7 @@ def _process_hidpp10_notification(device, status, n): del device.receiver[device.number] status.changed(active=False, alert=_ALERT.ALL, reason=_('unpaired')) else: - _log.warn('%s: disconnection with unknown type %02X: %s', device, n.address, n) + logger.warning('%s: disconnection with unknown type %02X: %s', device, n.address, n) return True # device connection (and disconnection) @@ -276,12 +273,12 @@ def _process_hidpp10_notification(device, status, n): link_established = not (flags & 0x40) link_encrypted = bool(flags & 0x20) or n.address == 0x10 # Bolt protocol always encrypted else: - _log.warn('%s: connection notification with unknown protocol %02X: %s', device.number, n.address, n) + logger.warning('%s: connection notification with unknown protocol %02X: %s', device.number, n.address, n) return True if wpid != device.wpid: - _log.warn('%s wpid mismatch, got %s', device, wpid) - if _log.isEnabledFor(_DEBUG): - _log.debug( + logger.warning('%s wpid mismatch, got %s', device, wpid) + if logger.isEnabledFor(logging.DEBUG): + logger.debug( '%s: protocol %s connection notification: software=%s, encrypted=%s, link=%s, payload=%s', device, n.address, bool(flags & 0x10), link_encrypted, link_established, bool(flags & 0x80) ) @@ -299,44 +296,44 @@ def _process_hidpp10_notification(device, status, n): # power notification if n.sub_id == 0x4B: if n.address == 0x01: - if _log.isEnabledFor(_DEBUG): - _log.debug('%s: device powered on', device) + if logger.isEnabledFor(logging.DEBUG): + logger.debug('%s: device powered on', device) reason = status.to_string() or _('powered on') status.changed(active=True, alert=_ALERT.NOTIFICATION, reason=reason) else: - _log.warn('%s: unknown %s', device, n) + logger.warning('%s: unknown %s', device, n) return True - _log.warn('%s: unrecognized %s', device, n) + logger.warning('%s: unrecognized %s', device, n) def _process_feature_notification(device, status, n, feature): - if _log.isEnabledFor(_DEBUG): - _log.debug('%s: notification for feature %s, report %s, data %s', device, feature, n.address >> 4, _strhex(n.data)) + if logger.isEnabledFor(logging.DEBUG): + logger.debug('%s: notification for feature %s, report %s, data %s', device, feature, n.address >> 4, _strhex(n.data)) if feature == _F.BATTERY_STATUS: if n.address == 0x00: _ignore, discharge_level, discharge_next_level, battery_status, voltage = _hidpp20.decipher_battery_status(n.data) status.set_battery_info(discharge_level, discharge_next_level, battery_status, voltage) elif n.address == 0x10: - if _log.isEnabledFor(_INFO): - _log.info('%s: spurious BATTERY status %s', device, n) + if logger.isEnabledFor(logging.INFO): + logger.info('%s: spurious BATTERY status %s', device, n) else: - _log.warn('%s: unknown BATTERY %s', device, n) + logger.warning('%s: unknown BATTERY %s', device, n) elif feature == _F.BATTERY_VOLTAGE: if n.address == 0x00: _ignore, level, nextl, battery_status, voltage = _hidpp20.decipher_battery_voltage(n.data) status.set_battery_info(level, nextl, battery_status, voltage) else: - _log.warn('%s: unknown VOLTAGE %s', device, n) + logger.warning('%s: unknown VOLTAGE %s', device, n) elif feature == _F.UNIFIED_BATTERY: if n.address == 0x00: _ignore, level, nextl, battery_status, voltage = _hidpp20.decipher_battery_unified(n.data) status.set_battery_info(level, nextl, battery_status, voltage) else: - _log.warn('%s: unknown UNIFIED BATTERY %s', device, n) + logger.warning('%s: unknown UNIFIED BATTERY %s', device, n) elif feature == _F.ADC_MEASUREMENT: if n.address == 0x00: @@ -347,7 +344,7 @@ def _process_feature_notification(device, status, n, feature): else: # this feature is used to signal device becoming inactive status.changed(active=False) else: - _log.warn('%s: unknown ADC MEASUREMENT %s', device, n) + logger.warning('%s: unknown ADC MEASUREMENT %s', device, n) elif feature == _F.SOLAR_DASHBOARD: if n.data[5:9] == b'GOOD': @@ -364,8 +361,8 @@ def _process_feature_notification(device, status, n, feature): status_text = _hidpp20.BATTERY_STATUS.recharging status.set_battery_info(charge, None, status_text, None) elif n.address == 0x20: - if _log.isEnabledFor(_DEBUG): - _log.debug('%s: Light Check button pressed', device) + if logger.isEnabledFor(logging.DEBUG): + logger.debug('%s: Light Check button pressed', device) status.changed(alert=_ALERT.SHOW_WINDOW) # first cancel any reporting # device.feature_request(_F.SOLAR_DASHBOARD) @@ -374,41 +371,41 @@ def _process_feature_notification(device, status, n, feature): reports_period = 2 # seconds device.feature_request(_F.SOLAR_DASHBOARD, 0x00, reports_count, reports_period) else: - _log.warn('%s: unknown SOLAR CHARGE %s', device, n) + logger.warning('%s: unknown SOLAR CHARGE %s', device, n) else: - _log.warn('%s: SOLAR CHARGE not GOOD? %s', device, n) + logger.warning('%s: SOLAR CHARGE not GOOD? %s', device, n) elif feature == _F.WIRELESS_DEVICE_STATUS: if n.address == 0x00: - if _log.isEnabledFor(_DEBUG): - _log.debug('wireless status: %s', n) + if logger.isEnabledFor(logging.DEBUG): + logger.debug('wireless status: %s', n) reason = 'powered on' if n.data[2] == 1 else None if n.data[1] == 1: # device is asking for software reconfiguration so need to change status alert = _ALERT.NONE status.changed(active=True, alert=alert, reason=reason, push=True) else: - _log.warn('%s: unknown WIRELESS %s', device, n) + logger.warning('%s: unknown WIRELESS %s', device, n) elif feature == _F.TOUCHMOUSE_RAW_POINTS: if n.address == 0x00: - if _log.isEnabledFor(_INFO): - _log.info('%s: TOUCH MOUSE points %s', device, n) + if logger.isEnabledFor(logging.INFO): + logger.info('%s: TOUCH MOUSE points %s', device, n) elif n.address == 0x10: touch = ord(n.data[:1]) button_down = bool(touch & 0x02) mouse_lifted = bool(touch & 0x01) - if _log.isEnabledFor(_INFO): - _log.info('%s: TOUCH MOUSE status: button_down=%s mouse_lifted=%s', device, button_down, mouse_lifted) + if logger.isEnabledFor(logging.INFO): + logger.info('%s: TOUCH MOUSE status: button_down=%s mouse_lifted=%s', device, button_down, mouse_lifted) else: - _log.warn('%s: unknown TOUCH MOUSE %s', device, n) + logger.warning('%s: unknown TOUCH MOUSE %s', device, n) # TODO: what are REPROG_CONTROLS_V{2,3}? elif feature == _F.REPROG_CONTROLS: if n.address == 0x00: - if _log.isEnabledFor(_INFO): - _log.info('%s: reprogrammable key: %s', device, n) + if logger.isEnabledFor(logging.INFO): + logger.info('%s: reprogrammable key: %s', device, n) else: - _log.warn('%s: unknown REPROG_CONTROLS %s', device, n) + logger.warning('%s: unknown REPROG_CONTROLS %s', device, n) elif feature == _F.BACKLIGHT2: if (n.address == 0x00): @@ -420,43 +417,43 @@ def _process_feature_notification(device, status, n, feature): elif feature == _F.REPROG_CONTROLS_V4: if n.address == 0x00: - if _log.isEnabledFor(_DEBUG): + if logger.isEnabledFor(logging.DEBUG): cid1, cid2, cid3, cid4 = _unpack('!HHHH', n.data[:8]) - _log.debug('%s: diverted controls pressed: 0x%x, 0x%x, 0x%x, 0x%x', device, cid1, cid2, cid3, cid4) + logger.debug('%s: diverted controls pressed: 0x%x, 0x%x, 0x%x, 0x%x', device, cid1, cid2, cid3, cid4) elif n.address == 0x10: - if _log.isEnabledFor(_DEBUG): + if logger.isEnabledFor(logging.DEBUG): dx, dy = _unpack('!hh', n.data[:4]) - _log.debug('%s: rawXY dx=%i dy=%i', device, dx, dy) + logger.debug('%s: rawXY dx=%i dy=%i', device, dx, dy) elif n.address == 0x20: - if _log.isEnabledFor(_DEBUG): - _log.debug('%s: received analyticsKeyEvents', device) - elif _log.isEnabledFor(_INFO): - _log.info('%s: unknown REPROG_CONTROLS_V4 %s', device, n) + if logger.isEnabledFor(logging.DEBUG): + logger.debug('%s: received analyticsKeyEvents', device) + elif logger.isEnabledFor(logging.INFO): + logger.info('%s: unknown REPROG_CONTROLS_V4 %s', device, n) elif feature == _F.HIRES_WHEEL: if (n.address == 0x00): - if _log.isEnabledFor(_INFO): + if logger.isEnabledFor(logging.INFO): flags, delta_v = _unpack('>bh', n.data[:3]) high_res = (flags & 0x10) != 0 periods = flags & 0x0f - _log.info('%s: WHEEL: res: %d periods: %d delta V:%-3d', device, high_res, periods, delta_v) + logger.info('%s: WHEEL: res: %d periods: %d delta V:%-3d', device, high_res, periods, delta_v) elif (n.address == 0x10): ratchet = n.data[0] - if _log.isEnabledFor(_INFO): - _log.info('%s: WHEEL: ratchet: %d', device, ratchet) + if logger.isEnabledFor(logging.INFO): + logger.info('%s: WHEEL: ratchet: %d', device, ratchet) if ratchet < 2: # don't process messages with unusual ratchet values from solaar.ui.config_panel import record_setting # prevent circular import setting = next((s for s in device.settings if s.name == _st.ScrollRatchet.name), None) if setting: record_setting(device, setting, [2 if ratchet else 1]) else: - if _log.isEnabledFor(_INFO): - _log.info('%s: unknown WHEEL %s', device, n) + if logger.isEnabledFor(logging.INFO): + logger.info('%s: unknown WHEEL %s', device, n) elif feature == _F.ONBOARD_PROFILES: if (n.address > 0x10): - if _log.isEnabledFor(_INFO): - _log.info('%s: unknown ONBOARD PROFILES %s', device, n) + if logger.isEnabledFor(logging.INFO): + logger.info('%s: unknown ONBOARD PROFILES %s', device, n) else: if (n.address == 0x00): resolution_index = None diff --git a/lib/logitech_receiver/receiver.py b/lib/logitech_receiver/receiver.py index 2f32747fb3..55786b0e98 100644 --- a/lib/logitech_receiver/receiver.py +++ b/lib/logitech_receiver/receiver.py @@ -17,9 +17,7 @@ ## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. import errno as _errno - -from logging import INFO as _INFO -from logging import getLogger +import logging import hidapi as _hid @@ -29,8 +27,7 @@ from .common import strhex as _strhex from .device import Device -_log = getLogger(__name__) -del getLogger +logger = logging.getLogger(__name__) _R = _hidpp10.REGISTERS _IR = _hidpp10.INFO_SUBREGISTERS @@ -56,7 +53,7 @@ def __init__(self, handle, path, product_id): self.product_id = product_id product_info = _product_information(self.product_id) if not product_info: - _log.warning('Unknown receiver type: %s', self.product_id) + logger.warning('Unknown receiver type: %s', self.product_id) product_info = {} self.receiver_kind = product_info.get('receiver_kind', 'unknown') @@ -131,13 +128,13 @@ def enable_connection_notifications(self, enable=True): set_flag_bits = 0 ok = _hidpp10.set_notification_flags(self, set_flag_bits) if ok is None: - _log.warn('%s: failed to %s receiver notifications', self, 'enable' if enable else 'disable') + logger.warning('%s: failed to %s receiver notifications', self, 'enable' if enable else 'disable') return None flag_bits = _hidpp10.get_notification_flags(self) flag_names = None if flag_bits is None else tuple(_hidpp10.NOTIFICATION_FLAG.flag_names(flag_bits)) - if _log.isEnabledFor(_INFO): - _log.info('%s: receiver notifications %s => %s', self, 'enabled' if enable else 'disabled', flag_names) + if logger.isEnabledFor(logging.INFO): + logger.info('%s: receiver notifications %s => %s', self, 'enabled' if enable else 'disabled', flag_names) return flag_bits def device_codename(self, n): @@ -172,7 +169,7 @@ def device_pairing_information(self, n): elif self.receiver_kind == '27Mz': # 27Mhz receiver, fill extracting WPID from udev path wpid = _hid.find_paired_node_wpid(self.path, n) if not wpid: - _log.error('Unable to get wpid from udev for device %d of %s', n, self) + logger.error('Unable to get wpid from udev for device %d of %s', n, self) raise _base.NoSuchDevice(number=n, receiver=self, error='Not present 27Mhz device') kind = _hidpp10.DEVICE_KIND[self.get_kind_from_index(n)] elif not self.receiver_kind == 'unifying': # unifying protocol not supported, may be an old Nano receiver @@ -219,7 +216,7 @@ def get_kind_from_index(self, index): elif index == 4: # numpad kind = 3 else: # unknown device number on 27Mhz receiver - _log.error('failed to calculate device kind for device %d of %s', index, self) + logger.error('failed to calculate device kind for device %d of %s', index, self) raise _base.NoSuchDevice(number=index, receiver=self, error='Unknown 27Mhz device number') return kind @@ -227,7 +224,7 @@ def notify_devices(self): """Scan all devices.""" if self.handle: if not self.write_register(_R.receiver_connection, 0x02): - _log.warn('%s: failed to trigger device link notifications', self) + logger.warning('%s: failed to trigger device link notifications', self) def register_new_device(self, number, notification=None): if self._devices.get(number) is not None: @@ -238,14 +235,14 @@ def register_new_device(self, number, notification=None): try: dev = Device(self, number, notification) - if _log.isEnabledFor(_INFO): - _log.info('%s: found new device %d (%s)', self, number, dev.wpid) + if logger.isEnabledFor(logging.INFO): + logger.info('%s: found new device %d (%s)', self, number, dev.wpid) self._devices[number] = dev return dev except _base.NoSuchDevice as e: - _log.warn('register new device failed for %s device %d error %s', e.receiver, e.number, e.error) + logger.warning('register new device failed for %s device %d error %s', e.receiver, e.number, e.error) - _log.warning('%s: looked for device %d, not found', self, number) + logger.warning('%s: looked for device %d, not found', self, number) self._devices[number] = None def set_lock(self, lock_closed=True, device=0, timeout=0): @@ -254,7 +251,7 @@ def set_lock(self, lock_closed=True, device=0, timeout=0): reply = self.write_register(_R.receiver_pairing, action, device, timeout) if reply: return True - _log.warn('%s: failed to %s the receiver lock', self, 'close' if lock_closed else 'open') + logger.warning('%s: failed to %s the receiver lock', self, 'close' if lock_closed else 'open') def discover(self, cancel=False, timeout=30): # Bolt device discovery assert self.receiver_kind == 'bolt' @@ -263,7 +260,7 @@ def discover(self, cancel=False, timeout=30): # Bolt device discovery reply = self.write_register(_R.bolt_device_discovery, timeout, action) if reply: return True - _log.warn('%s: failed to %s device discovery', self, 'cancel' if cancel else 'start') + logger.warning('%s: failed to %s device discovery', self, 'cancel' if cancel else 'start') def pair_device(self, pair=True, slot=0, address=b'\0\0\0\0\0\0', authentication=0x00, entropy=20): # Bolt pairing assert self.receiver_kind == 'bolt' @@ -272,7 +269,7 @@ def pair_device(self, pair=True, slot=0, address=b'\0\0\0\0\0\0', authentication reply = self.write_register(_R.bolt_pairing, action, slot, address, authentication, entropy) if reply: return True - _log.warn('%s: failed to %s device %s', self, 'pair' if pair else 'unpair', address) + logger.warning('%s: failed to %s device %s', self, 'pair' if pair else 'unpair', address) def count(self): count = self.read_register(_R.receiver_connection) @@ -338,7 +335,7 @@ def _unpair_device(self, key, force=False): dev.wpid = None if key in self._devices: del self._devices[key] - _log.warn('%s removed device %s', self, dev) + logger.warning('%s removed device %s', self, dev) else: if self.receiver_kind == 'bolt': reply = self.write_register(_R.bolt_pairing, 0x03, key) @@ -350,10 +347,10 @@ def _unpair_device(self, key, force=False): dev.wpid = None if key in self._devices: del self._devices[key] - if _log.isEnabledFor(_INFO): - _log.info('%s unpaired device %s', self, dev) + if logger.isEnabledFor(logging.INFO): + logger.info('%s unpaired device %s', self, dev) else: - _log.error('%s failed to unpair device %s', self, dev) + logger.error('%s failed to unpair device %s', self, dev) raise Exception('failed to unpair device %s: %s' % (dev.name, key)) def __len__(self): @@ -392,8 +389,8 @@ def open(self, device_info): if handle: return Receiver(handle, device_info.path, device_info.product_id) except OSError as e: - _log.exception('open %s', device_info) + logger.exception('open %s', device_info) if e.errno == _errno.EACCES: raise except Exception: - _log.exception('open %s', device_info) + logger.exception('open %s', device_info) diff --git a/lib/logitech_receiver/settings.py b/lib/logitech_receiver/settings.py index abe180c637..5bc136b389 100644 --- a/lib/logitech_receiver/settings.py +++ b/lib/logitech_receiver/settings.py @@ -16,11 +16,9 @@ ## with this program; if not, write to the Free Software Foundation, Inc., ## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +import logging import math -from logging import DEBUG as _DEBUG -from logging import WARNING as _WARNING -from logging import getLogger from struct import unpack as _unpack from time import sleep as _sleep @@ -31,8 +29,7 @@ from .common import int2bytes as _int2bytes from .i18n import _ -_log = getLogger(__name__) -del getLogger +logger = logging.getLogger(__name__) # # @@ -141,13 +138,13 @@ def validate_read(self, reply_bytes): reply_bytes = reply_bytes[self.read_skip_byte_count:] if isinstance(self.mask, int): reply_value = ord(reply_bytes[:1]) & self.mask - if _log.isEnabledFor(_DEBUG): - _log.debug('BooleanValidator: validate read %r => %02X', reply_bytes, reply_value) + if logger.isEnabledFor(logging.DEBUG): + logger.debug('BooleanValidator: validate read %r => %02X', reply_bytes, reply_value) if reply_value == self.true_value: return True if reply_value == self.false_value: return False - _log.warn( + logger.warning( 'BooleanValidator: reply %02X mismatched %02X/%02X/%02X', reply_value, self.true_value, self.false_value, self.mask ) @@ -165,7 +162,9 @@ def validate_read(self, reply_bytes): if reply_value == false_value: return False - _log.warn('BooleanValidator: reply %r mismatched %r/%r/%r', reply_bytes, self.true_value, self.false_value, self.mask) + logger.warning( + 'BooleanValidator: reply %r mismatched %r/%r/%r', reply_bytes, self.true_value, self.false_value, self.mask + ) return False def prepare_write(self, new_value, current_value=None): @@ -198,8 +197,8 @@ def prepare_write(self, new_value, current_value=None): if current_value is not None and to_write == current_value[:len(to_write)]: return None - if _log.isEnabledFor(_DEBUG): - _log.debug('BooleanValidator: prepare_write(%s, %s) => %r', new_value, current_value, to_write) + if logger.isEnabledFor(logging.DEBUG): + logger.debug('BooleanValidator: prepare_write(%s, %s) => %r', new_value, current_value, to_write) return self.write_prefix_bytes + to_write @@ -278,8 +277,8 @@ def read(self, cached=True): self._pre_read(cached) if cached and self._value is not None: - if _log.isEnabledFor(_DEBUG): - _log.debug('%s: cached value %r on %s', self.name, self._value, self._device) + if logger.isEnabledFor(logging.DEBUG): + logger.debug('%s: cached value %r on %s', self.name, self._value, self._device) return self._value if self._device.online: @@ -290,8 +289,8 @@ def read(self, cached=True): # Don't update the persister if it already has a value, # otherwise the first read might overwrite the value we wanted. self._device.persister[self.name] = self._value if self.persist else None - if _log.isEnabledFor(_DEBUG): - _log.debug('%s: read value %r on %s', self.name, self._value, self._device) + if logger.isEnabledFor(logging.DEBUG): + logger.debug('%s: read value %r on %s', self.name, self._value, self._device) return self._value def _pre_write(self, save=True): @@ -310,8 +309,8 @@ def write(self, value, save=True): assert hasattr(self, '_device') assert value is not None - if _log.isEnabledFor(_DEBUG): - _log.debug('%s: write %r to %s', self.name, value, self._device) + if logger.isEnabledFor(logging.DEBUG): + logger.debug('%s: write %r to %s', self.name, value, self._device) if self._device.online: if self._value != value: @@ -321,13 +320,13 @@ def write(self, value, save=True): if self._validator.needs_current_value: # the _validator needs the current value, possibly to merge flag values current_value = self._rw.read(self._device) - if _log.isEnabledFor(_DEBUG): - _log.debug('%s: current value %r on %s', self.name, current_value, self._device) + if logger.isEnabledFor(logging.DEBUG): + logger.debug('%s: current value %r on %s', self.name, current_value, self._device) data_bytes = self._validator.prepare_write(value, current_value) if data_bytes is not None: - if _log.isEnabledFor(_DEBUG): - _log.debug('%s: prepare write(%s) => %r', self.name, value, data_bytes) + if logger.isEnabledFor(logging.DEBUG): + logger.debug('%s: prepare write(%s) => %r', self.name, value, data_bytes) reply = self._rw.write(self._device, data_bytes) if not reply: @@ -345,15 +344,15 @@ def compare(self, args, current): def apply(self): assert hasattr(self, '_value') assert hasattr(self, '_device') - if _log.isEnabledFor(_DEBUG): - _log.debug('%s: apply (%s)', self.name, self._device) + if logger.isEnabledFor(logging.DEBUG): + logger.debug('%s: apply (%s)', self.name, self._device) value = self.read(self.persist) # Don't use persisted value if setting doesn't persist if self.persist and value is not None: # If setting doesn't persist no need to write value just read try: self.write(value, save=False) except Exception as e: - if _log.isEnabledFor(_WARNING): - _log.warn( + if logger.isEnabledFor(logging.WARNING): + logger.warning( '%s: error applying value %s so ignore it (%s): %s', self.name, self._value, self._device, repr(e) ) @@ -375,8 +374,8 @@ class Settings(Setting): def read(self, cached=True): assert hasattr(self, '_value') assert hasattr(self, '_device') - if _log.isEnabledFor(_DEBUG): - _log.debug('%s: settings read %r from %s', self.name, self._value, self._device) + if logger.isEnabledFor(logging.DEBUG): + logger.debug('%s: settings read %r from %s', self.name, self._value, self._device) self._pre_read(cached) @@ -400,8 +399,8 @@ def read_key(self, key, cached=True): assert hasattr(self, '_value') assert hasattr(self, '_device') assert key is not None - if _log.isEnabledFor(_DEBUG): - _log.debug('%s: settings read %r key %r from %s', self.name, self._value, key, self._device) + if logger.isEnabledFor(logging.DEBUG): + logger.debug('%s: settings read %r key %r from %s', self.name, self._value, key, self._device) self._pre_read(cached) if cached and self._value is not None: @@ -420,16 +419,16 @@ def write(self, map, save=True): assert hasattr(self, '_device') assert map is not None - if _log.isEnabledFor(_DEBUG): - _log.debug('%s: settings write %r to %s', self.name, map, self._device) + if logger.isEnabledFor(logging.DEBUG): + logger.debug('%s: settings write %r to %s', self.name, map, self._device) if self._device.online: self.update(map, save) for key, value in map.items(): data_bytes = self._validator.prepare_write(int(key), value) if data_bytes is not None: - if _log.isEnabledFor(_DEBUG): - _log.debug('%s: settings prepare map write(%s,%s) => %r', self.name, key, value, data_bytes) + if logger.isEnabledFor(logging.DEBUG): + logger.debug('%s: settings prepare map write(%s,%s) => %r', self.name, key, value, data_bytes) reply = self._rw.write(self._device, int(key), data_bytes) if not reply: return None @@ -445,8 +444,8 @@ def write_key_value(self, key, value, save=True): assert key is not None assert value is not None - if _log.isEnabledFor(_DEBUG): - _log.debug('%s: settings write key %r value %r to %s', self.name, key, value, self._device) + if logger.isEnabledFor(logging.DEBUG): + logger.debug('%s: settings write key %r value %r to %s', self.name, key, value, self._device) if self._device.online: if not self._value: @@ -458,8 +457,8 @@ def write_key_value(self, key, value, save=True): except ValueError: data_bytes = value = None if data_bytes is not None: - if _log.isEnabledFor(_DEBUG): - _log.debug('%s: settings prepare key value write(%s,%s) => %r', self.name, key, value, data_bytes) + if logger.isEnabledFor(logging.DEBUG): + logger.debug('%s: settings prepare key value write(%s,%s) => %r', self.name, key, value, data_bytes) reply = self._rw.write(self._device, int(key), data_bytes) if not reply: return None @@ -475,8 +474,8 @@ class LongSettings(Setting): def read(self, cached=True): assert hasattr(self, '_value') assert hasattr(self, '_device') - if _log.isEnabledFor(_DEBUG): - _log.debug('%s: settings read %r from %s', self.name, self._value, self._device) + if logger.isEnabledFor(logging.DEBUG): + logger.debug('%s: settings read %r from %s', self.name, self._value, self._device) self._pre_read(cached) @@ -502,8 +501,8 @@ def read_item(self, item, cached=True): assert hasattr(self, '_value') assert hasattr(self, '_device') assert item is not None - if _log.isEnabledFor(_DEBUG): - _log.debug('%s: settings read %r item %r from %s', self.name, self._value, item, self._device) + if logger.isEnabledFor(logging.DEBUG): + logger.debug('%s: settings read %r item %r from %s', self.name, self._value, item, self._device) self._pre_read(cached) if cached and self._value is not None: @@ -523,8 +522,8 @@ def write(self, map, save=True): assert hasattr(self, '_device') assert map is not None - if _log.isEnabledFor(_DEBUG): - _log.debug('%s: long settings write %r to %s', self.name, map, self._device) + if logger.isEnabledFor(logging.DEBUG): + logger.debug('%s: long settings write %r to %s', self.name, map, self._device) if self._device.online: self.update(map, save) for item, value in map.items(): @@ -532,8 +531,8 @@ def write(self, map, save=True): if data_bytes_list is not None: for data_bytes in data_bytes_list: if data_bytes is not None: - if _log.isEnabledFor(_DEBUG): - _log.debug('%s: settings prepare map write(%s,%s) => %r', self.name, item, value, data_bytes) + if logger.isEnabledFor(logging.DEBUG): + logger.debug('%s: settings prepare map write(%s,%s) => %r', self.name, item, value, data_bytes) reply = self._rw.write(self._device, data_bytes) if not reply: return None @@ -549,8 +548,8 @@ def write_key_value(self, item, value, save=True): assert item is not None assert value is not None - if _log.isEnabledFor(_DEBUG): - _log.debug('%s: long settings write item %r value %r to %s', self.name, item, value, self._device) + if logger.isEnabledFor(logging.DEBUG): + logger.debug('%s: long settings write item %r value %r to %s', self.name, item, value, self._device) if self._device.online: if not self._value: @@ -558,8 +557,8 @@ def write_key_value(self, item, value, save=True): data_bytes = self._validator.prepare_write_item(item, value) self.update_key_value(item, value, save) if data_bytes is not None: - if _log.isEnabledFor(_DEBUG): - _log.debug('%s: settings prepare item value write(%s,%s) => %r', self.name, item, value, data_bytes) + if logger.isEnabledFor(logging.DEBUG): + logger.debug('%s: settings prepare item value write(%s,%s) => %r', self.name, item, value, data_bytes) reply = self._rw.write(self._device, data_bytes) if not reply: return None @@ -573,8 +572,8 @@ class BitFieldSetting(Setting): def read(self, cached=True): assert hasattr(self, '_value') assert hasattr(self, '_device') - if _log.isEnabledFor(_DEBUG): - _log.debug('%s: settings read %r from %s', self.name, self._value, self._device) + if logger.isEnabledFor(logging.DEBUG): + logger.debug('%s: settings read %r from %s', self.name, self._value, self._device) self._pre_read(cached) @@ -600,8 +599,8 @@ def read_key(self, key, cached=True): assert hasattr(self, '_value') assert hasattr(self, '_device') assert key is not None - if _log.isEnabledFor(_DEBUG): - _log.debug('%s: settings read %r key %r from %s', self.name, self._value, key, self._device) + if logger.isEnabledFor(logging.DEBUG): + logger.debug('%s: settings read %r key %r from %s', self.name, self._value, key, self._device) self._pre_read(cached) @@ -624,14 +623,14 @@ def write(self, map, save=True): assert hasattr(self, '_device') assert map is not None - if _log.isEnabledFor(_DEBUG): - _log.debug('%s: bit field settings write %r to %s', self.name, map, self._device) + if logger.isEnabledFor(logging.DEBUG): + logger.debug('%s: bit field settings write %r to %s', self.name, map, self._device) if self._device.online: self.update(map, save) data_bytes = self._validator.prepare_write(self._value) if data_bytes is not None: - if _log.isEnabledFor(_DEBUG): - _log.debug('%s: settings prepare map write(%s) => %r', self.name, self._value, data_bytes) + if logger.isEnabledFor(logging.DEBUG): + logger.debug('%s: settings prepare map write(%s) => %r', self.name, self._value, data_bytes) # if prepare_write returns a list, write one item at a time seq = data_bytes if isinstance(data_bytes, list) else [data_bytes] for b in seq: @@ -650,8 +649,8 @@ def write_key_value(self, key, value, save=True): assert key is not None assert value is not None - if _log.isEnabledFor(_DEBUG): - _log.debug('%s: bit field settings write key %r value %r to %s', self.name, key, value, self._device) + if logger.isEnabledFor(logging.DEBUG): + logger.debug('%s: bit field settings write key %r value %r to %s', self.name, key, value, self._device) if self._device.online: if not self._value: @@ -661,8 +660,8 @@ def write_key_value(self, key, value, save=True): data_bytes = self._validator.prepare_write(self._value) if data_bytes is not None: - if _log.isEnabledFor(_DEBUG): - _log.debug('%s: settings prepare key value write(%s,%s) => %r', self.name, key, str(value), data_bytes) + if logger.isEnabledFor(logging.DEBUG): + logger.debug('%s: settings prepare key value write(%s,%s) => %r', self.name, key, str(value), data_bytes) # if prepare_write returns a list, write one item at a time seq = data_bytes if isinstance(data_bytes, list) else [data_bytes] for b in seq: @@ -693,8 +692,8 @@ class RangeFieldSetting(Setting): def read(self, cached=True): assert hasattr(self, '_value') assert hasattr(self, '_device') - if _log.isEnabledFor(_DEBUG): - _log.debug('%s: settings read %r from %s', self.name, self._value, self._device) + if logger.isEnabledFor(logging.DEBUG): + logger.debug('%s: settings read %r from %s', self.name, self._value, self._device) self._pre_read(cached) if cached and self._value is not None: return self._value @@ -720,26 +719,26 @@ def write(self, map, save=True): assert hasattr(self, '_value') assert hasattr(self, '_device') assert map is not None - if _log.isEnabledFor(_DEBUG): - _log.debug('%s: range field setting write %r to %s', self.name, map, self._device) + if logger.isEnabledFor(logging.DEBUG): + logger.debug('%s: range field setting write %r to %s', self.name, map, self._device) if self._device.online: self.update(map, save) data_bytes = self._validator.prepare_write(self._value) if data_bytes is not None: - if _log.isEnabledFor(_DEBUG): - _log.debug('%s: range field setting prepare map write(%s) => %r', self.name, self._value, data_bytes) + if logger.isEnabledFor(logging.DEBUG): + logger.debug('%s: range field setting prepare map write(%s) => %r', self.name, self._value, data_bytes) reply = self._rw.write(self._device, data_bytes) if not reply: return None - elif _log.isEnabledFor(_WARNING): - _log.warn('%s: range field setting no data to write', self.name) + elif logger.isEnabledFor(logging.WARNING): + logger.warning('%s: range field setting no data to write', self.name) return map def write_key_value(self, key, value, save=True): assert key is not None assert value is not None - if _log.isEnabledFor(_DEBUG): - _log.debug('%s: range field setting write key %r value %r to %s', self.name, key, value, self._device) + if logger.isEnabledFor(logging.DEBUG): + logger.debug('%s: range field setting write key %r value %r to %s', self.name, key, value, self._device) if self._device.online: if not self._value: self.read() @@ -1130,7 +1129,7 @@ def prepare_key(self, key): def prepare_write(self, key, new_value): choices = self.choices.get(key) if choices is None or (new_value not in choices and new_value != self.extra_default): - _log.error('invalid choice %r for %s', new_value, key) + logger.error('invalid choice %r for %s', new_value, key) return None new_value = new_value | self.activate return self._write_prefix_bytes + new_value.to_bytes(self._byte_count, 'big') @@ -1287,7 +1286,7 @@ def acceptable(self, args, current): return None if type(args[1]) != int or args[1] < self.min_value or args[1] > self.max_value else args def compare(self, args, current): - _log.warn('compare not implemented for packed range settings') + logger.warning('compare not implemented for packed range settings') return False @@ -1316,7 +1315,7 @@ def validate_read_item(self, reply_bytes, item): r += b'\x00' * (sub_item.length - len(value)) v = _bytes2int(r) if not (sub_item.minimum < v < sub_item.maximum): - _log.warn( + logger.warning( f'{self.__class__.__name__}: failed to validate read value for {item}.{sub_item}: ' + f'{v} not in [{sub_item.minimum}..{sub_item.maximum}]' ) @@ -1376,7 +1375,7 @@ def acceptable(self, args, current): return [int(item), {**args[1]}] def compare(self, args, current): - _log.warn('compare not implemented for multiple range settings') + logger.warning('compare not implemented for multiple range settings') return False @@ -1438,7 +1437,7 @@ def handler(device, n): # Called on notification events from the device divertSetting = next(filter(lambda s: s.name == self.divert_setting_name, device.settings), None) if divertSetting is None: - _log.warn('setting %s not found on %s', self.divert_setting_name, device.name) + logger.warning('setting %s not found on %s', self.divert_setting_name, device.name) return None self.device = device key = _bytes2int(data_bytes) @@ -1453,7 +1452,7 @@ def handler(device, n): # Called on notification events from the device self.activate_action() _status_changed(device, refresh=True) # update main window else: - _log.error('cannot enable %s on %s for key %s', self.name, device, key) + logger.error('cannot enable %s on %s for key %s', self.name, device, key) else: # Disable if self.active: self.active = False @@ -1464,8 +1463,8 @@ def handler(device, n): # Called on notification events from the device try: device.remove_notification_handler(self.name) except Exception: - if _log.isEnabledFor(_WARNING): - _log.warn('cannot disable %s on %s', self.name, device) + if logger.isEnabledFor(logging.WARNING): + logger.warning('cannot disable %s on %s', self.name, device) self.deactivate_action() return True @@ -1526,8 +1525,8 @@ def stop(self, key): # only stop if this is the active key try: self.device.remove_notification_handler(self.name) except Exception: - if _log.isEnabledFor(_WARNING): - _log.warn('cannot disable %s on %s', self.name, self.device) + if logger.isEnabledFor(logging.WARNING): + logger.warning('cannot disable %s on %s', self.name, self.device) self.deactivate_action() self.active = False diff --git a/lib/logitech_receiver/settings_templates.py b/lib/logitech_receiver/settings_templates.py index e63e7fe2db..15b65c5d62 100644 --- a/lib/logitech_receiver/settings_templates.py +++ b/lib/logitech_receiver/settings_templates.py @@ -16,10 +16,9 @@ ## with this program; if not, write to the Free Software Foundation, Inc., ## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -from logging import DEBUG as _DEBUG -from logging import INFO as _INFO +import logging + from logging import WARN as _WARN -from logging import getLogger from struct import pack as _pack from struct import unpack as _unpack from time import time as _time @@ -52,8 +51,7 @@ from .settings import Settings as _Settings from .special_keys import DISABLE as _DKEY -_log = getLogger(__name__) -del getLogger +logger = logging.getLogger(__name__) _DK = _hidpp10.DEVICE_KIND _R = _hidpp10.REGISTERS @@ -803,8 +801,8 @@ def release_action(self): from .base import _HIDPP_Notification as _HIDPP_Notification from .diversion import process_notification as _process_notification self.push_mouse_event() - if _log.isEnabledFor(_INFO): - _log.info('mouse gesture notification %s', self.data) + if logger.isEnabledFor(logging.INFO): + logger.info('mouse gesture notification %s', self.data) payload = _pack('!' + (len(self.data) * 'h'), *self.data) notification = _HIDPP_Notification(0, 0, 0, 0, payload) _process_notification(self.device, self.device.status, notification, _hidpp20.FEATURE.MOUSE_GESTURE) @@ -830,8 +828,8 @@ def key_action(self, key): self.data.append(1) self.data.append(key) self.lastEv = _time() * 1000 # _time_ns() / 1e6 - if _log.isEnabledFor(_DEBUG): - _log.debug('mouse gesture key event %d %s', key, self.data) + if logger.isEnabledFor(logging.DEBUG): + logger.debug('mouse gesture key event %d %s', key, self.data) def push_mouse_event(self): x = int(self.dx) @@ -843,8 +841,8 @@ def push_mouse_event(self): self.data.append(y) self.dx = 0. self.dy = 0. - if _log.isEnabledFor(_DEBUG): - _log.debug('mouse gesture move event %d %d %s', x, y, self.data) + if logger.isEnabledFor(logging.DEBUG): + logger.debug('mouse gesture move event %d %d %s', x, y, self.data) class DivertKeys(_Settings): @@ -982,7 +980,7 @@ def press_action(self): # switch sensitivity if speed_setting: speed_setting.write(newSpeed) else: - _log.error('cannot save sensitivity setting on %s', self.device) + logger.error('cannot save sensitivity setting on %s', self.device) from solaar.ui import status_changed as _status_changed _status_changed(self.device, refresh=True) # update main window if self.device.persister: @@ -1343,8 +1341,8 @@ def build(cls, setting_class, device): elif capabilities & 0x0023 == 0x0023: # Key, Mouse, and HScroll Codes keys = _special_keys.KEYS_KEYS_MOUSE_HSCROLL else: - if _log.isEnabledFor(_WARN): - _log.warn('%s: unimplemented Persistent Remappable capability %s', device.name, hex(capabilities)) + if logger.isEnabledFor(_WARN): + logger.warning('%s: unimplemented Persistent Remappable capability %s', device.name, hex(capabilities)) return None choices = {} for k in remap_keys: @@ -1359,8 +1357,8 @@ def validate_read(self, reply_bytes, key): reply_value = _bytes2int(reply_bytes[start:end]) & self.mask # Craft keyboard has a value that isn't valid so fudge these values if reply_value not in self.choices[key]: - if _log.isEnabledFor(_WARN): - _log.warn('unusual persistent remappable action mapping %x: use Default', reply_value) + if logger.isEnabledFor(_WARN): + logger.warning('unusual persistent remappable action mapping %x: use Default', reply_value) reply_value = _special_keys.KEYS_Default return reply_value @@ -1531,12 +1529,12 @@ def check_feature(device, sclass): return try: detected = sclass.build(device) - if _log.isEnabledFor(_DEBUG): - _log.debug('check_feature %s [%s] detected %s', sclass.name, sclass.feature, detected) + if logger.isEnabledFor(logging.DEBUG): + logger.debug('check_feature %s [%s] detected %s', sclass.name, sclass.feature, detected) return detected except Exception as e: from traceback import format_exc - _log.error('check_feature %s [%s] error %s\n%s', sclass.name, sclass.feature, e, format_exc()) + logger.error('check_feature %s [%s] error %s\n%s', sclass.name, sclass.feature, e, format_exc()) return False # differentiate from an error-free determination that the setting is not supported diff --git a/lib/logitech_receiver/status.py b/lib/logitech_receiver/status.py index 99d7343a21..60d5837f6c 100644 --- a/lib/logitech_receiver/status.py +++ b/lib/logitech_receiver/status.py @@ -16,9 +16,8 @@ ## with this program; if not, write to the Free Software Foundation, Inc., ## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -from logging import DEBUG as _DEBUG -from logging import INFO as _INFO -from logging import getLogger +import logging + from time import time as _timestamp from . import hidpp10 as _hidpp10 @@ -29,8 +28,7 @@ from .common import NamedInts as _NamedInts from .i18n import _, ngettext -_log = getLogger(__name__) -del getLogger +logger = logging.getLogger(__name__) _R = _hidpp10.REGISTERS @@ -125,8 +123,8 @@ def changed(self, alert=ALERT.NOTIFICATION, reason=None): # r = self._receiver # assert r # - # if _log.isEnabledFor(_DEBUG): - # _log.debug("polling status of %s", r) + # if logger.isEnabledFor(logging.DEBUG): + # logger.debug("polling status of %s", r) # # # make sure to read some stuff that may be read later by the UI # r.serial, r.firmware, None @@ -194,8 +192,8 @@ def __bool__(self): __nonzero__ = __bool__ def set_battery_info(self, level, nextLevel, status, voltage, timestamp=None): - if _log.isEnabledFor(_DEBUG): - _log.debug('%s: battery %s, %s', self._device, level, status) + if logger.isEnabledFor(logging.DEBUG): + logger.debug('%s: battery %s, %s', self._device, level, status) if level is None: # Some notifications may come with no battery level info, just @@ -230,7 +228,7 @@ def set_battery_info(self, level, nextLevel, status, voltage, timestamp=None): if _hidpp20.BATTERY_OK(status) and (level is None or level > _BATTERY_ATTENTION_LEVEL): self[KEYS.ERROR] = None else: - _log.warn('%s: battery %d%%, ALERT %s', self._device, level, status) + logger.warning('%s: battery %d%%, ALERT %s', self._device, level, status) if self.get(KEYS.ERROR) != status: self[KEYS.ERROR] = status # only show the notification once @@ -288,8 +286,8 @@ def changed(self, active=None, alert=ALERT.NONE, reason=None, push=False, timest if was_active is None or push or not was_active and ( not d.features or _hidpp20.FEATURE.WIRELESS_DEVICE_STATUS not in d.features ): - if _log.isEnabledFor(_INFO): - _log.info('%s pushing device settings %s', d, d.settings) + if logger.isEnabledFor(logging.INFO): + logger.info('%s pushing device settings %s', d, d.settings) _settings.apply_all_settings(d) else: @@ -314,19 +312,19 @@ def changed(self, active=None, alert=ALERT.NONE, reason=None, push=False, timest self.updated = timestamp - # if _log.isEnabledFor(_DEBUG): - # _log.debug("device %d changed: active=%s %s", d.number, self._active, dict(self)) + # if logger.isEnabledFor(logging.DEBUG): + # logger.debug("device %d changed: active=%s %s", d.number, self._active, dict(self)) self._changed_callback(d, alert, reason) # def poll(self, timestamp): # d = self._device # if not d: - # _log.error("polling status of invalid device") + # logger.error("polling status of invalid device") # return # # if self._active: - # if _log.isEnabledFor(_DEBUG): - # _log.debug("polling status of %s", d) + # if logger.isEnabledFor(logging.DEBUG): + # logger.debug("polling status of %s", d) # # # read these from the device, the UI may need them later # d.protocol, d.serial, d.firmware, d.kind, d.name, d.settings, None diff --git a/lib/solaar/cli/__init__.py b/lib/solaar/cli/__init__.py index 782067e965..2868147b0b 100644 --- a/lib/solaar/cli/__init__.py +++ b/lib/solaar/cli/__init__.py @@ -17,15 +17,12 @@ ## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. import argparse as _argparse +import logging import sys as _sys -from logging import DEBUG as _DEBUG -from logging import getLogger - from solaar import NAME -_log = getLogger(__name__) -del getLogger +logger = logging.getLogger(__name__) # # @@ -114,12 +111,12 @@ def _receivers(dev_path=None): continue try: r = Receiver.open(dev_info) - if _log.isEnabledFor(_DEBUG): - _log.debug('[%s] => %s', dev_info.path, r) + if logger.isEnabledFor(logging.DEBUG): + logger.debug('[%s] => %s', dev_info.path, r) if r: yield r except Exception as e: - _log.exception('opening ' + str(dev_info)) + logger.exception('opening ' + str(dev_info)) _sys.exit('%s: error: %s' % (NAME, str(e))) @@ -131,12 +128,12 @@ def _receivers_and_devices(dev_path=None): continue try: d = Device.open(dev_info) if dev_info.isDevice else Receiver.open(dev_info) - if _log.isEnabledFor(_DEBUG): - _log.debug('[%s] => %s', dev_info.path, d) + if logger.isEnabledFor(logging.DEBUG): + logger.debug('[%s] => %s', dev_info.path, d) if d is not None: yield d except Exception as e: - _log.exception('opening ' + str(dev_info)) + logger.exception('opening ' + str(dev_info)) _sys.exit('%s: error: %s' % (NAME, str(e))) diff --git a/lib/solaar/configuration.py b/lib/solaar/configuration.py index 18aeea1949..b011b50017 100644 --- a/lib/solaar/configuration.py +++ b/lib/solaar/configuration.py @@ -17,12 +17,10 @@ ## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. import json as _json +import logging import os as _os import os.path as _path -from logging import DEBUG as _DEBUG -from logging import INFO as _INFO -from logging import getLogger from threading import Lock as _Lock from threading import Timer as _Timer @@ -31,8 +29,7 @@ from logitech_receiver.common import NamedInt as _NamedInt from solaar import __version__ -_log = getLogger(__name__) -del getLogger +logger = logging.getLogger(__name__) _XDG_CONFIG_HOME = _os.environ.get('XDG_CONFIG_HOME') or _path.expanduser(_path.join('~', '.config')) _yaml_file_path = _path.join(_XDG_CONFIG_HOME, 'solaar', 'config.yaml') @@ -57,19 +54,19 @@ def _load(): with open(_yaml_file_path) as config_file: loaded_config = _yaml.safe_load(config_file) except Exception as e: - _log.error('failed to load from %s: %s', _yaml_file_path, e) + logger.error('failed to load from %s: %s', _yaml_file_path, e) elif _path.isfile(_json_file_path): path = _json_file_path try: with open(_json_file_path) as config_file: loaded_config = _json.load(config_file) except Exception as e: - _log.error('failed to load from %s: %s', _json_file_path, e) + logger.error('failed to load from %s: %s', _json_file_path, e) loaded_config = _convert_json(loaded_config) else: path = None - if _log.isEnabledFor(_DEBUG): - _log.debug('load => %s', loaded_config) + if logger.isEnabledFor(logging.DEBUG): + logger.debug('load => %s', loaded_config) global _config _config = _parse_config(loaded_config, path) @@ -84,8 +81,8 @@ def _parse_config(loaded_config, config_path): loaded_version = loaded_config[0] discard_derived_properties = loaded_version != current_version if discard_derived_properties: - if _log.isEnabledFor(_INFO): - _log.info( + if logger.isEnabledFor(logging.INFO): + logger.info( 'config file \'%s\' was generated by another version of solaar ' '(config: %s, current: %s). refreshing detected device capabilities', config_path, loaded_version, current_version @@ -95,7 +92,7 @@ def _parse_config(loaded_config, config_path): assert isinstance(device, dict) parsed_config.append(_device_entry_from_config_dict(device, discard_derived_properties)) except Exception as e: - _log.warning('Exception processing config file \'%s\', ignoring contents: %s', config_path, e) + logger.warning('Exception processing config file \'%s\', ignoring contents: %s', config_path, e) return parsed_config @@ -138,7 +135,7 @@ def save(defer=False): try: _os.makedirs(dirname) except Exception: - _log.error('failed to create %s', dirname) + logger.error('failed to create %s', dirname) return if not defer or not defer_saves: do_save() @@ -159,10 +156,10 @@ def do_save(): try: with open(_yaml_file_path, 'w') as config_file: _yaml.dump(_config, config_file, default_flow_style=None, width=150) - if _log.isEnabledFor(_INFO): - _log.info('saved %s to %s', _config, _yaml_file_path) + if logger.isEnabledFor(logging.INFO): + logger.info('saved %s to %s', _config, _yaml_file_path) except Exception as e: - _log.error('failed to save to %s: %s', _yaml_file_path, e) + logger.error('failed to save to %s: %s', _yaml_file_path, e) def _convert_json(json_dict): @@ -256,11 +253,11 @@ def match(wpid, serial, modelId, unitId, c): break if not entry: if not device.online and not device.serial: # don't create entry for offline devices without serial number - if _log.isEnabledFor(_INFO): - _log.info('not setting up persister for offline device %s with missing serial number', device.name) + if logger.isEnabledFor(logging.INFO): + logger.info('not setting up persister for offline device %s with missing serial number', device.name) return - if _log.isEnabledFor(_INFO): - _log.info('setting up persister for device %s', device.name) + if logger.isEnabledFor(logging.INFO): + logger.info('setting up persister for device %s', device.name) entry = _DeviceEntry() _config.append(entry) entry.update(device, modelId) diff --git a/lib/solaar/gtk.py b/lib/solaar/gtk.py index f8042365f8..514a544e91 100755 --- a/lib/solaar/gtk.py +++ b/lib/solaar/gtk.py @@ -26,15 +26,12 @@ import sys import tempfile -from logging import INFO as _INFO -from logging import WARNING as _WARNING - import solaar.cli as _cli import solaar.i18n as _i18n from solaar import NAME, __version__ -_log = logging.getLogger(__name__) +logger = logging.getLogger(__name__) # # @@ -117,8 +114,8 @@ def _parse_arguments(): logging.getLogger('').addHandler(stream_handler) if not args.action: - if _log.isEnabledFor(logging.INFO): - logging.info('version %s, language %s (%s)', __version__, _i18n.language, _i18n.encoding) + if logger.isEnabledFor(logging.INFO): + logger.info('version %s, language %s (%s)', __version__, _i18n.language, _i18n.encoding) return args @@ -130,7 +127,7 @@ def _handlesig(signl, stack): signal.signal(signal.SIGTERM, signal.SIG_DFL) if signl == int(signal.SIGINT): - if _log.isEnabledFor(_INFO): + if logger.isEnabledFor(logging.INFO): faulthandler.dump_traceback() sys.exit('%s: exit due to keyboard interrupt' % (NAME.lower())) else: @@ -157,12 +154,12 @@ def main(): signal.signal(signal.SIGTERM, _handlesig) udev_file = '42-logitech-unify-permissions.rules' - if _log.isEnabledFor(_WARNING) \ + if logger.isEnabledFor(logging.WARNING) \ and not os.path.isfile('/etc/udev/rules.d/' + udev_file) \ and not os.path.isfile('/usr/lib/udev/rules.d/' + udev_file) \ and not os.path.isfile('/usr/local/lib/udev/rules.d/' + udev_file): - _log.warning('Solaar udev file not found in expected location') - _log.warning('See https://pwr-solaar.github.io/Solaar/installation for more information') + logger.warning('Solaar udev file not found in expected location') + logger.warning('See https://pwr-solaar.github.io/Solaar/installation for more information') try: import solaar.listener as listener import solaar.ui as ui diff --git a/lib/solaar/listener.py b/lib/solaar/listener.py index 9417c88772..3ddba6d5be 100644 --- a/lib/solaar/listener.py +++ b/lib/solaar/listener.py @@ -17,13 +17,10 @@ ## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. import errno as _errno +import logging import time from collections import namedtuple -from logging import DEBUG as _DEBUG -from logging import INFO as _INFO -from logging import WARNING as _WARNING -from logging import getLogger import gi @@ -41,8 +38,7 @@ # from solaar.i18n import _ -_log = getLogger(__name__) -del getLogger +logger = logging.getLogger(__name__) _R = _hidpp10.REGISTERS _IR = _hidpp10.INFO_SUBREGISTERS @@ -87,12 +83,12 @@ def __init__(self, receiver, status_changed_callback): _status.attach_to(receiver, self._status_changed) def has_started(self): - if _log.isEnabledFor(_INFO): - _log.info('%s: notifications listener has started (%s)', self.receiver, self.receiver.handle) + if logger.isEnabledFor(logging.INFO): + logger.info('%s: notifications listener has started (%s)', self.receiver, self.receiver.handle) nfs = self.receiver.enable_connection_notifications() - if _log.isEnabledFor(_WARNING): + if logger.isEnabledFor(logging.WARNING): if not self.receiver.isDevice and not ((nfs if nfs else 0) & _hidpp10.NOTIFICATION_FLAG.wireless): - _log.warning( + logger.warning( 'Receiver on %s might not support connection notifications, GUI might not show its devices', self.receiver.path ) @@ -103,8 +99,8 @@ def has_started(self): def has_stopped(self): r, self.receiver = self.receiver, None assert r is not None - if _log.isEnabledFor(_INFO): - _log.info('%s: notifications listener has stopped', r) + if logger.isEnabledFor(logging.INFO): + logger.info('%s: notifications listener has stopped', r) # because udev is not notifying us about device removal, # make sure to clean up in _all_listeners @@ -115,7 +111,7 @@ def has_stopped(self): try: r.close() except Exception: - _log.exception('closing receiver %s' % r.path) + logger.exception('closing receiver %s' % r.path) self.status_changed_callback(r) # , _status.ALERT.NOTIFICATION) # def tick(self, timestamp): @@ -126,7 +122,7 @@ def has_stopped(self): # # if self._last_tick > 0 and timestamp - self._last_tick > _POLL_TICK * 2: # # # if we missed a couple of polls, most likely the computer went into # # # sleep, and we have to reinitialize the receiver again - # # _log.warn("%s: possible sleep detected, closing this listener", self.receiver) + # # logger.warning("%s: possible sleep detected, closing this listener", self.receiver) # # self.stop() # # return # @@ -153,25 +149,25 @@ def has_stopped(self): # if dev and dev.status is not None: # dev.status.poll(timestamp) # except Exception as e: - # _log.exception("polling", e) + # logger.exception("polling", e) def _status_changed(self, device, alert=_status.ALERT.NONE, reason=None): assert device is not None - if _log.isEnabledFor(_INFO): + if logger.isEnabledFor(logging.INFO): try: device.ping() if device.kind is None: - _log.info( + logger.info( 'status_changed %r: %s, %s (%X) %s', device, 'present' if bool(device) else 'removed', device.status, alert, reason or '' ) else: - _log.info( + logger.info( 'status_changed %r: %s %s, %s (%X) %s', device, 'paired' if bool(device) else 'unpaired', 'online' if device.online else 'offline', device.status, alert, reason or '' ) except Exception: - _log.info('status_changed for unknown device') + logger.info('status_changed for unknown device') if device.kind is None: assert device == self.receiver @@ -184,8 +180,8 @@ def _status_changed(self, device, alert=_status.ALERT.NONE, reason=None): # Device was unpaired, and isn't valid anymore. # We replace it with a ghost so that the UI has something to work # with while cleaning up. - if _log.isEnabledFor(_INFO): - _log.info('device %s was unpaired, ghosting', device) + if logger.isEnabledFor(logging.INFO): + logger.info('device %s was unpaired, ghosting', device) device = _ghost(device) self.status_changed_callback(device, alert, reason) @@ -197,8 +193,8 @@ def _status_changed(self, device, alert=_status.ALERT.NONE, reason=None): def _notifications_handler(self, n): assert self.receiver - # if _log.isEnabledFor(_DEBUG): - # _log.debug("%s: handling %s", self.receiver, n) + # if logger.isEnabledFor(logging.DEBUG): + # logger.debug("%s: handling %s", self.receiver, n) if n.devnumber == 0xFF: # a receiver notification _notifications.process(self.receiver, n) @@ -206,20 +202,20 @@ def _notifications_handler(self, n): # a notification that came in to the device listener - strange, but nothing needs to be done here if self.receiver.isDevice: - if _log.isEnabledFor(_DEBUG): - _log.debug('Notification %s via device %s being ignored.', n, self.receiver) + if logger.isEnabledFor(logging.DEBUG): + logger.debug('Notification %s via device %s being ignored.', n, self.receiver) return # DJ pairing notification - ignore - hid++ 1.0 pairing notification is all that is needed if n.sub_id == 0x41 and n.report_id == _base.DJ_MESSAGE_ID: - if _log.isEnabledFor(_INFO): - _log.info('ignoring DJ pairing notification %s', n) + if logger.isEnabledFor(logging.INFO): + logger.info('ignoring DJ pairing notification %s', n) return # a device notification if not (0 < n.devnumber <= 16): # some receivers have devices past their max # devices - if _log.isEnabledFor(_WARNING): - _log.warning('Unexpected device number (%s) in notification %s.', n.devnumber, n) + if logger.isEnabledFor(logging.WARNING): + logger.warning('Unexpected device number (%s) in notification %s.', n.devnumber, n) return already_known = n.devnumber in self.receiver @@ -255,17 +251,17 @@ def _notifications_handler(self, n): dev = self.receiver[n.devnumber] if not dev: - _log.warn('%s: received %s for invalid device %d: %r', self.receiver, n, n.devnumber, dev) + logger.warning('%s: received %s for invalid device %d: %r', self.receiver, n, n.devnumber, dev) return # Apply settings every time the device connects if n.sub_id == 0x41: - if _log.isEnabledFor(_INFO): + if logger.isEnabledFor(logging.INFO): try: dev.ping() - _log.info('connection %s for %r', n, dev) + logger.info('connection %s for %r', n, dev) except Exception: - _log.info('connection %s for unknown device, number %s', n, n.devnumber) + logger.info('connection %s for unknown device, number %s', n, n.devnumber) # If there are saved configs, bring the device's settings up-to-date. # They will be applied when the device is marked as online. configuration.attach_to(dev) @@ -275,15 +271,15 @@ def _notifications_handler(self, n): if not hasattr(dev, 'status') or dev.status is None: # notification before device status set up - don't process it - _log.warn('%s before device %s has status', n, dev) + logger.warning('%s before device %s has status', n, dev) else: _notifications.process(dev, n) if self.receiver.status.lock_open and not already_known: # this should be the first notification after a device was paired assert n.sub_id == 0x41, 'first notification was not a connection notification' - if _log.isEnabledFor(_INFO): - _log.info('%s: pairing detected new device', self.receiver) + if logger.isEnabledFor(logging.INFO): + logger.info('%s: pairing detected new device', self.receiver) self.receiver.status.new_device = dev elif dev.online is None: dev.ping() @@ -316,15 +312,15 @@ def _start(device_info): _all_listeners[device_info.path] = rl return rl - _log.warn('failed to open %s', device_info) + logger.warning('failed to open %s', device_info) def start_all(): # just in case this it called twice in a row... stop_all() - if _log.isEnabledFor(_INFO): - _log.info('starting receiver listening threads') + if logger.isEnabledFor(logging.INFO): + logger.info('starting receiver listening threads') for device_info in _base.receivers_and_devices(): _process_receiver_event('add', device_info) @@ -334,8 +330,8 @@ def stop_all(): _all_listeners.clear() if listeners: - if _log.isEnabledFor(_INFO): - _log.info('stopping receiver listening threads %s', listeners) + if logger.isEnabledFor(logging.INFO): + logger.info('stopping receiver listening threads %s', listeners) for l in listeners: l.stop() @@ -351,8 +347,8 @@ def stop_all(): # after a resume, the device may have been off # so mark its saved status to ensure that the status is pushed to the device when it comes back def ping_all(resuming=False): - if _log.isEnabledFor(_INFO): - _log.info('ping all devices%s', ' when resuming' if resuming else '') + if logger.isEnabledFor(logging.INFO): + logger.info('ping all devices%s', ' when resuming' if resuming else '') for l in _all_listeners.values(): if l.receiver.isDevice: if resuming and hasattr(l.receiver, 'status'): @@ -396,8 +392,8 @@ def _process_add(device_info, retry): try: import subprocess output = subprocess.check_output(['/usr/bin/getfacl', '-p', device_info.path], text=True) - if _log.isEnabledFor(_WARNING): - _log.warning('Missing permissions on %s\n%s.', device_info.path, output) + if logger.isEnabledFor(logging.WARNING): + logger.warning('Missing permissions on %s\n%s.', device_info.path, output) except Exception: pass if retry: @@ -416,8 +412,8 @@ def _process_receiver_event(action, device_info): assert device_info is not None assert _error_callback - if _log.isEnabledFor(_INFO): - _log.info('receiver event %s %s', action, device_info) + if logger.isEnabledFor(logging.INFO): + logger.info('receiver event %s %s', action, device_info) # whatever the action, stop any previous receivers at this path l = _all_listeners.pop(device_info.path, None) diff --git a/lib/solaar/tasks.py b/lib/solaar/tasks.py index 1bf45d29b8..333de1761c 100644 --- a/lib/solaar/tasks.py +++ b/lib/solaar/tasks.py @@ -18,12 +18,11 @@ ## with this program; if not, write to the Free Software Foundation, Inc., ## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -from logging import DEBUG as _DEBUG -from logging import getLogger +import logging + from threading import Thread as _Thread -_log = getLogger(__name__) -del getLogger +logger = logging.getLogger(__name__) try: from Queue import Queue as _Queue @@ -54,8 +53,8 @@ def stop(self): def run(self): self.alive = True - if _log.isEnabledFor(_DEBUG): - _log.debug('started') + if logger.isEnabledFor(logging.DEBUG): + logger.debug('started') while self.alive: task = self.queue.get() @@ -65,7 +64,7 @@ def run(self): try: function(*args, **kwargs) except Exception: - _log.exception('calling %s', function) + logger.exception('calling %s', function) - if _log.isEnabledFor(_DEBUG): - _log.debug('stopped') + if logger.isEnabledFor(logging.DEBUG): + logger.debug('stopped') diff --git a/lib/solaar/ui/__init__.py b/lib/solaar/ui/__init__.py index 61becfafd6..4ee05e05a0 100644 --- a/lib/solaar/ui/__init__.py +++ b/lib/solaar/ui/__init__.py @@ -16,9 +16,7 @@ ## with this program; if not, write to the Free Software Foundation, Inc., ## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -from logging import DEBUG as _DEBUG -from logging import INFO as _INFO -from logging import getLogger +import logging import yaml as _yaml @@ -29,8 +27,7 @@ from logitech_receiver.status import ALERT # NOQA: E402 # isort:skip from solaar.i18n import _ # NOQA: E402 # isort:skip -_log = getLogger(__name__) -del getLogger +logger = logging.getLogger(__name__) # # @@ -46,7 +43,7 @@ def _error_dialog(reason, object): - _log.error('error: %s %s', reason, object) + logger.error('error: %s %s', reason, object) if reason == 'permissions': title = _('Permissions error') @@ -103,8 +100,8 @@ def ui_async(function, *args, **kwargs): def _startup(app, startup_hook, use_tray, show_window): - if _log.isEnabledFor(_DEBUG): - _log.debug('startup registered=%s, remote=%s', app.get_is_registered(), app.get_is_remote()) + if logger.isEnabledFor(logging.DEBUG): + logger.debug('startup registered=%s, remote=%s', app.get_is_registered(), app.get_is_remote()) from solaar.tasks import TaskRunner as _TaskRunner global _task_runner @@ -120,8 +117,8 @@ def _startup(app, startup_hook, use_tray, show_window): def _activate(app): - if _log.isEnabledFor(_DEBUG): - _log.debug('activate') + if logger.isEnabledFor(logging.DEBUG): + logger.debug('activate') if app.get_windows(): window.popup() else: @@ -134,8 +131,8 @@ def _command_line(app, command_line): if not args: _activate(app) elif args[0] == 'config': # config call from remote instance - if _log.isEnabledFor(_INFO): - _log.info('remote command line %s', args) + if logger.isEnabledFor(logging.INFO): + logger.info('remote command line %s', args) from solaar.ui.config_panel import change_setting # prevent circular import from solaar.ui.window import find_device # prevent circular import dev = find_device(args[1]) @@ -147,8 +144,8 @@ def _command_line(app, command_line): def _shutdown(app, shutdown_hook): - if _log.isEnabledFor(_DEBUG): - _log.debug('shutdown') + if logger.isEnabledFor(logging.DEBUG): + logger.debug('shutdown') shutdown_hook() @@ -185,8 +182,8 @@ def run_loop(startup_hook, shutdown_hook, use_tray, show_window): def _status_changed(device, alert, reason, refresh=False): assert device is not None - if _log.isEnabledFor(_DEBUG): - _log.debug('status changed: %s (%s) %s', device, alert, reason) + if logger.isEnabledFor(logging.DEBUG): + logger.debug('status changed: %s (%s) %s', device, alert, reason) tray.update(device) if alert & ALERT.ATTENTION: diff --git a/lib/solaar/ui/about.py b/lib/solaar/ui/about.py index bd91adf0d4..54734e5f58 100644 --- a/lib/solaar/ui/about.py +++ b/lib/solaar/ui/about.py @@ -34,7 +34,7 @@ def _create(): about.set_program_name(NAME) about.set_version(__version__) about.set_comments(_('Manages Logitech receivers,\nkeyboards, mice, and tablets.')) - about.set_logo_icon_name(NAME.lower()) + about.setloggero_icon_name(NAME.lower()) about.set_copyright('© 2012-2023 Daniel Pavel and contributors to the Solaar project') about.set_license_type(Gtk.License.GPL_2_0) diff --git a/lib/solaar/ui/action.py b/lib/solaar/ui/action.py index 91621f236b..1a7164341d 100644 --- a/lib/solaar/ui/action.py +++ b/lib/solaar/ui/action.py @@ -22,9 +22,8 @@ from ..ui import error_dialog from . import pair_window -# from logging import getLogger -# _log = getLogger(__name__) -# del getLogger +# import logging +# logger = logging.getLogger(__name__) # # @@ -97,5 +96,5 @@ def unpair(window, device): try: del receiver[device_number] except Exception: - # _log.exception("unpairing %s", device) + # logger.exception("unpairing %s", device) error_dialog('unpair', device) diff --git a/lib/solaar/ui/config_panel.py b/lib/solaar/ui/config_panel.py index e95ac610fa..670c724d56 100644 --- a/lib/solaar/ui/config_panel.py +++ b/lib/solaar/ui/config_panel.py @@ -16,11 +16,9 @@ ## with this program; if not, write to the Free Software Foundation, Inc., ## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +import logging import traceback -from logging import DEBUG as _DEBUG -from logging import WARNING as _WARNING -from logging import getLogger from threading import Timer as _Timer from gi.repository import Gdk, GLib, Gtk @@ -30,8 +28,7 @@ from solaar.i18n import _, ngettext from solaar.ui import ui_async as _ui_async -_log = getLogger(__name__) -del getLogger +logger = logging.getLogger(__name__) # # @@ -695,8 +692,8 @@ def _create_sbox(s, device): elif s.kind == _SETTING_KIND.hetero: control = HeteroKeyControl(sbox, change) else: - if _log.isEnabledFor(_WARNING): - _log.warn('setting %s display not implemented', s.label) + if logger.isEnabledFor(logging.WARNING): + logger.warning('setting %s display not implemented', s.label) return None control.set_sensitive(False) # the first read will enable it @@ -828,8 +825,8 @@ def record_setting(device, setting, values): def _record_setting(device, setting, values): - if _log.isEnabledFor(_DEBUG): - _log.debug('on %s changing setting %s to %s', device, setting, values) + if logger.isEnabledFor(logging.DEBUG): + logger.debug('on %s changing setting %s to %s', device, setting, values) if len(values) > 1: setting.update_key_value(values[0], values[-1]) value = {values[0]: values[-1]} diff --git a/lib/solaar/ui/diversion_rules.py b/lib/solaar/ui/diversion_rules.py index 99450999f3..fc71a0ea78 100644 --- a/lib/solaar/ui/diversion_rules.py +++ b/lib/solaar/ui/diversion_rules.py @@ -15,6 +15,7 @@ ## You should have received a copy of the GNU General Public License along ## with this program; if not, write to the Free Software Foundation, Inc., ## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +import logging import string import threading @@ -22,7 +23,6 @@ from contextlib import contextmanager as contextlib_contextmanager from copy import copy from dataclasses import dataclass, field -from logging import getLogger from shlex import quote as shlex_quote from typing import Dict @@ -40,8 +40,7 @@ from logitech_receiver.special_keys import CONTROL as _CONTROL from solaar.i18n import _ -_log = getLogger(__name__) -del getLogger +logger = logging.getLogger(__name__) # # @@ -2190,7 +2189,7 @@ def _all_settings(): prev_setting = settings[s.name][0] prev_kind = prev_setting.validator_class.kind if prev_kind != s.validator_class.kind: - _log.warning( + logger.warning( 'ignoring setting {} - same name of {}, but different kind ({} != {})'.format( s.__name__, prev_setting.__name__, prev_kind, s.validator_class.kind ) diff --git a/lib/solaar/ui/icons.py b/lib/solaar/ui/icons.py index aadf76ae12..597729541b 100644 --- a/lib/solaar/ui/icons.py +++ b/lib/solaar/ui/icons.py @@ -16,15 +16,13 @@ ## with this program; if not, write to the Free Software Foundation, Inc., ## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -from logging import DEBUG as _DEBUG -from logging import getLogger +import logging import solaar.gtk as gtk from gi.repository import Gtk -_log = getLogger(__name__) -del getLogger +logger = logging.getLogger(__name__) # # @@ -47,18 +45,18 @@ def _init_icon_paths(): return _default_theme = Gtk.IconTheme.get_default() - if _log.isEnabledFor(_DEBUG): - _log.debug('icon theme paths: %s', _default_theme.get_search_path()) + if logger.isEnabledFor(logging.DEBUG): + logger.debug('icon theme paths: %s', _default_theme.get_search_path()) if gtk.battery_icons_style == 'symbolic': global TRAY_OKAY TRAY_OKAY = TRAY_INIT # use monochrome tray icon if not _default_theme.has_icon('battery-good-symbolic'): - _log.warning('failed to detect symbolic icons') + logger.warning('failed to detect symbolic icons') gtk.battery_icons_style = 'regular' if gtk.battery_icons_style == 'regular': if not _default_theme.has_icon('battery-good'): - _log.warning('failed to detect icons') + logger.warning('failed to detect icons') gtk.battery_icons_style = 'solaar' @@ -70,10 +68,10 @@ def _init_icon_paths(): def battery(level=None, charging=False): icon_name = _battery_icon_name(level, charging) if not _default_theme.has_icon(icon_name): - _log.warning('icon %s not found in current theme', icon_name) + logger.warning('icon %s not found in current theme', icon_name) return TRAY_OKAY # use Solaar icon if battery icon not available - elif _log.isEnabledFor(_DEBUG): - _log.debug('battery icon for %s:%s = %s', level, charging, icon_name) + elif logger.isEnabledFor(logging.DEBUG): + logger.debug('battery icon for %s:%s = %s', level, charging, icon_name) return icon_name @@ -172,8 +170,8 @@ def icon_file(name, size=_LARGE_SIZE): theme_icon = _default_theme.lookup_icon(name, size, 0) if theme_icon: file_name = theme_icon.get_filename() - # if _log.isEnabledFor(_DEBUG): - # _log.debug("icon %s(%d) => %s", name, size, file_name) + # if logger.isEnabledFor(logging.DEBUG): + # logger.debug("icon %s(%d) => %s", name, size, file_name) return file_name - _log.warn('icon %s(%d) not found in current theme', name, size) + logger.warning('icon %s(%d) not found in current theme', name, size) diff --git a/lib/solaar/ui/notify.py b/lib/solaar/ui/notify.py index db3e74979b..6db0e29495 100644 --- a/lib/solaar/ui/notify.py +++ b/lib/solaar/ui/notify.py @@ -37,10 +37,8 @@ available = False if available: - from logging import INFO as _INFO - from logging import getLogger - _log = getLogger(__name__) - del getLogger + import logging + logger = logging.getLogger(__name__) from solaar import NAME @@ -55,19 +53,19 @@ def init(): global available if available: if not Notify.is_initted(): - if _log.isEnabledFor(_INFO): - _log.info('starting desktop notifications') + if logger.isEnabledFor(logging.INFO): + logger.info('starting desktop notifications') try: return Notify.init(NAME) except Exception: - _log.exception('initializing desktop notifications') + logger.exception('initializing desktop notifications') available = False return available and Notify.is_initted() def uninit(): if available and Notify.is_initted(): - if _log.isEnabledFor(_INFO): - _log.info('stopping desktop notifications') + if logger.isEnabledFor(logging.INFO): + logger.info('stopping desktop notifications') _notifications.clear() Notify.uninit() @@ -96,11 +94,11 @@ def alert(reason, icon=None): n.set_hint('desktop-entry', GLib.Variant('s', NAME.lower())) try: - # if _log.isEnabledFor(_DEBUG): - # _log.debug("showing %s", n) + # if logger.isEnabledFor(logging.DEBUG): + # logger.debug("showing %s", n) n.show() except Exception: - _log.exception('showing %s', n) + logger.exception('showing %s', n) def show(dev, reason=None, icon=None, progress=None): """Show a notification with title and text. @@ -135,11 +133,11 @@ def show(dev, reason=None, icon=None, progress=None): n.set_hint('value', GLib.Variant('i', progress)) try: - # if _log.isEnabledFor(_DEBUG): - # _log.debug("showing %s", n) + # if logger.isEnabledFor(logging.DEBUG): + # logger.debug("showing %s", n) n.show() except Exception: - _log.exception('showing %s', n) + logger.exception('showing %s', n) else: init = lambda: False diff --git a/lib/solaar/ui/pair_window.py b/lib/solaar/ui/pair_window.py index 2ee4303ee3..4664a8d5de 100644 --- a/lib/solaar/ui/pair_window.py +++ b/lib/solaar/ui/pair_window.py @@ -16,8 +16,7 @@ ## with this program; if not, write to the Free Software Foundation, Inc., ## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -from logging import DEBUG as _DEBUG -from logging import getLogger +import logging from gi.repository import GLib, Gtk from logitech_receiver import hidpp10 as _hidpp10 @@ -26,8 +25,7 @@ from . import icons as _icons -_log = getLogger(__name__) -del getLogger +logger = logging.getLogger(__name__) # # @@ -71,8 +69,8 @@ def _check_lock_state(assistant, receiver, count=2): global address, kind, authentication, name, passcode if not assistant.is_drawable(): - if _log.isEnabledFor(_DEBUG): - _log.debug('assistant %s destroyed, bailing out', assistant) + if logger.isEnabledFor(logging.DEBUG): + logger.debug('assistant %s destroyed, bailing out', assistant) return False if receiver.status.get(_K.ERROR): @@ -115,8 +113,8 @@ def _check_lock_state(assistant, receiver, count=2): def _show_passcode(assistant, receiver, passkey): - if _log.isEnabledFor(_DEBUG): - _log.debug('%s show passkey: %s', receiver, passkey) + if logger.isEnabledFor(logging.DEBUG): + logger.debug('%s show passkey: %s', receiver, passkey) name = receiver.status.device_name authentication = receiver.status.device_authentication intro_text = _('%(receiver_name)s: pair new device') % {'receiver_name': receiver.name} @@ -136,8 +134,8 @@ def _show_passcode(assistant, receiver, passkey): def _prepare(assistant, page, receiver): index = assistant.get_current_page() - if _log.isEnabledFor(_DEBUG): - _log.debug('prepare %s %d %s', assistant, index, page) + if logger.isEnabledFor(logging.DEBUG): + logger.debug('prepare %s %d %s', assistant, index, page) if index == 0: if receiver.receiver_kind == 'bolt': @@ -164,8 +162,8 @@ def _prepare(assistant, page, receiver): def _finish(assistant, receiver): - if _log.isEnabledFor(_DEBUG): - _log.debug('finish %s', assistant) + if logger.isEnabledFor(logging.DEBUG): + logger.debug('finish %s', assistant) assistant.destroy() receiver.status.new_device = None if receiver.status.lock_open: @@ -180,8 +178,8 @@ def _finish(assistant, receiver): def _pairing_failed(assistant, receiver, error): - if _log.isEnabledFor(_DEBUG): - _log.debug('%s fail: %s', receiver, error) + if logger.isEnabledFor(logging.DEBUG): + logger.debug('%s fail: %s', receiver, error) assistant.commit() @@ -202,8 +200,8 @@ def _pairing_failed(assistant, receiver, error): def _pairing_succeeded(assistant, receiver, device): assert device - if _log.isEnabledFor(_DEBUG): - _log.debug('%s success: %s', receiver, device) + if logger.isEnabledFor(logging.DEBUG): + logger.debug('%s success: %s', receiver, device) page = _create_page(assistant, Gtk.AssistantPageType.SUMMARY) diff --git a/lib/solaar/ui/tray.py b/lib/solaar/ui/tray.py index 298ba28e52..5d9bf1d509 100644 --- a/lib/solaar/ui/tray.py +++ b/lib/solaar/ui/tray.py @@ -16,10 +16,9 @@ ## with this program; if not, write to the Free Software Foundation, Inc., ## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +import logging import os -from logging import DEBUG as _DEBUG -from logging import getLogger from time import time as _timestamp import solaar.gtk as gtk @@ -35,8 +34,7 @@ from .window import popup as _window_popup from .window import toggle as _window_toggle -_log = getLogger(__name__) -del getLogger +logger = logging.getLogger(__name__) # # constants @@ -95,8 +93,8 @@ def _scroll(tray_icon, event, direction=None): return _last_scroll = now - # if _log.isEnabledFor(_DEBUG): - # _log.debug("scroll direction %s", direction) + # if logger.isEnabledFor(logging.DEBUG): + # logger.debug("scroll direction %s", direction) global _picked_device candidate = None @@ -141,8 +139,8 @@ def _scroll(tray_icon, event, direction=None): _picked_device = None _picked_device = candidate or _picked_device - if _log.isEnabledFor(_DEBUG): - _log.debug('scroll: picked %s', _picked_device) + if logger.isEnabledFor(logging.DEBUG): + logger.debug('scroll: picked %s', _picked_device) _update_tray_icon() @@ -161,8 +159,8 @@ def _scroll(tray_icon, event, direction=None): # treat unavailable versions the same as unavailable packages raise ImportError - if _log.isEnabledFor(_DEBUG): - _log.debug('using %sAppIndicator3' % ('Ayatana ' if ayatana_appindicator_found else '')) + if logger.isEnabledFor(logging.DEBUG): + logger.debug('using %sAppIndicator3' % ('Ayatana ' if ayatana_appindicator_found else '')) # Defense against AppIndicator3 bug that treats files in current directory as icon files # https://bugs.launchpad.net/ubuntu/+source/libappindicator/+bug/1363277 @@ -228,8 +226,8 @@ def attention(reason=None): except ImportError: - if _log.isEnabledFor(_DEBUG): - _log.debug('using StatusIcon') + if logger.isEnabledFor(logging.DEBUG): + logger.debug('using StatusIcon') def _create(menu): icon = Gtk.StatusIcon.new_from_icon_name(_icons.TRAY_INIT) @@ -339,8 +337,8 @@ def _pick_device_with_lowest_battery(): picked = info picked_level = level or 0 - if _log.isEnabledFor(_DEBUG): - _log.debug('picked device with lowest battery: %s', picked) + if logger.isEnabledFor(logging.DEBUG): + logger.debug('picked device with lowest battery: %s', picked) return picked @@ -424,7 +422,7 @@ def _remove_receiver(receiver): def _update_menu_item(index, device): if device is None or device.status is None: - _log.warn('updating an inactive device %s, assuming disconnected', device) + logger.warning('updating an inactive device %s, assuming disconnected', device) return None menu_items = _menu.get_children() diff --git a/lib/solaar/ui/window.py b/lib/solaar/ui/window.py index 512e9ac672..cc456b7756 100644 --- a/lib/solaar/ui/window.py +++ b/lib/solaar/ui/window.py @@ -16,8 +16,7 @@ ## with this program; if not, write to the Free Software Foundation, Inc., ## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -from logging import DEBUG as _DEBUG -from logging import getLogger +import logging from gi.repository import Gdk, GLib, Gtk from gi.repository.GObject import TYPE_PYOBJECT @@ -36,8 +35,7 @@ from .about import show_window as _show_about_window from .diversion_rules import show_window as _show_diversion_window -_log = getLogger(__name__) -del getLogger +logger = logging.getLogger(__name__) # # constants @@ -387,8 +385,8 @@ def _find_selected_device_id(): def _device_selected(selection): model, item = selection.get_selected() device = model.get_value(item, _COLUMN.DEVICE) if item else None - # if _log.isEnabledFor(_DEBUG): - # _log.debug("window tree selected device %s", device) + # if logger.isEnabledFor(logging.DEBUG): + # logger.debug("window tree selected device %s", device) if device: _update_info_panel(device, full=True) else: @@ -418,8 +416,8 @@ def _receiver_row(receiver_path, receiver=None): status_icon = None row_data = (receiver_path, 0, True, receiver.name, icon_name, status_text, status_icon, receiver) assert len(row_data) == len(_TREE_SEPATATOR) - if _log.isEnabledFor(_DEBUG): - _log.debug('new receiver row %s', row_data) + if logger.isEnabledFor(logging.DEBUG): + logger.debug('new receiver row %s', row_data) item = _model.append(None, row_data) if _TREE_SEPATATOR: _model.append(None, _TREE_SEPATATOR) @@ -443,7 +441,7 @@ def _device_row(receiver_path, device_number, device=None): new_child_index = 0 while item: if _model.get_value(item, _COLUMN.PATH) != receiver_path: - _log.warn( + logger.warning( 'path for device row %s different from path for receiver %s', _model.get_value(item, _COLUMN.PATH), receiver_path ) @@ -464,8 +462,8 @@ def _device_row(receiver_path, device_number, device=None): receiver_path, device_number, bool(device.online), device.codename, icon_name, status_text, status_icon, device ) assert len(row_data) == len(_TREE_SEPATATOR) - if _log.isEnabledFor(_DEBUG): - _log.debug('new device row %s at index %d', row_data, new_child_index) + if logger.isEnabledFor(logging.DEBUG): + logger.debug('new device row %s at index %d', row_data, new_child_index) item = _model.insert(receiver_row, new_child_index, row_data) return item or None @@ -487,7 +485,7 @@ def select(receiver_path, device_number=None): selection = _tree.get_selection() selection.select_iter(item) else: - _log.warn('select(%s, %s) failed to find an item', receiver_path, device_number) + logger.warning('select(%s, %s) failed to find an item', receiver_path, device_number) def _hide(w, _ignore=None): diff --git a/lib/solaar/upower.py b/lib/solaar/upower.py index 4bede4c709..61517b4004 100644 --- a/lib/solaar/upower.py +++ b/lib/solaar/upower.py @@ -16,11 +16,9 @@ ## with this program; if not, write to the Free Software Foundation, Inc., ## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -from logging import INFO as _INFO -from logging import getLogger +import logging -_log = getLogger(__name__) -del getLogger +logger = logging.getLogger(__name__) # # As suggested here: http://stackoverflow.com/a/13548984 @@ -31,8 +29,8 @@ def _suspend(): if _suspend_callback: - if _log.isEnabledFor(_INFO): - _log.info('received suspend event') + if logger.isEnabledFor(logging.INFO): + logger.info('received suspend event') _suspend_callback() @@ -41,8 +39,8 @@ def _suspend(): def _resume(): if _resume_callback: - if _log.isEnabledFor(_INFO): - _log.info('received resume event') + if logger.isEnabledFor(logging.INFO): + logger.info('received resume event') _resume_callback() @@ -73,12 +71,12 @@ def watch(on_resume_callback=None, on_suspend_callback=None): bus.add_signal_receiver(_suspend_or_resume, 'PrepareForSleep', dbus_interface=_LOGIND_INTERFACE, bus_name=_LOGIND_BUS) - if _log.isEnabledFor(_INFO): - _log.info('connected to system dbus, watching for suspend/resume events') + if logger.isEnabledFor(logging.INFO): + logger.info('connected to system dbus, watching for suspend/resume events') except Exception: # Either: # - the dbus library is not available # - the system dbus is not running - _log.warn('failed to register suspend/resume callbacks') + logger.warning('failed to register suspend/resume callbacks') pass diff --git a/setup.py b/setup.py index d10a2cdd05..7ed4f31eb3 100755 --- a/setup.py +++ b/setup.py @@ -81,7 +81,7 @@ def _data_files(): 'PyYAML (>= 3.12)', 'python-xlib (>= 0.27)', 'psutil (>= 5.4.3)', - 'dbus-python (>=1.3.2)', + 'dbus-python', ], extras_require={ 'report-descriptor': ['hid-parser'],