From 83b407cb3e39d81bcae225fe07fd04774f940d13 Mon Sep 17 00:00:00 2001 From: Izalia Mae Date: Fri, 23 Jul 2021 12:53:47 -0400 Subject: [PATCH] updates to dbus and database --- base/izzylib/misc.py | 8 +++-- dbus/izzylib/dbus/__init__.py | 60 +++++++++++++++++++++++++++-------- sql/izzylib/sql/generic.py | 9 +++++- 3 files changed, 59 insertions(+), 18 deletions(-) diff --git a/base/izzylib/misc.py b/base/izzylib/misc.py index c83a9a8..f1f1e02 100644 --- a/base/izzylib/misc.py +++ b/base/izzylib/misc.py @@ -242,10 +242,12 @@ def print_methods(object, include_underscore=False): ''' for line in dir(object): - if line.startswith('_') and include_underscore: - print(line) + if line.startswith('_'): + if include_underscore: + print(line) - print(line) + else: + print(line) def prompt(prompt, default=None, valtype=str, options=[], password=False): diff --git a/dbus/izzylib/dbus/__init__.py b/dbus/izzylib/dbus/__init__.py index 911c828..f96e8f7 100644 --- a/dbus/izzylib/dbus/__init__.py +++ b/dbus/izzylib/dbus/__init__.py @@ -4,8 +4,10 @@ from dasbus.connection import SessionMessageBus, SystemMessageBus from dasbus.error import DBusError from dasbus.identifier import DBusServiceIdentifier from dasbus.loop import EventLoop +from functools import partial from izzylib import DotDict, Path, logging from pathlib import Path as Pathlib +from xml.etree import ElementTree try: from .template import Template @@ -34,14 +36,12 @@ class DBusBase(DBusServiceIdentifier): class DBusClientBase(DBusBase): - def __init__(self, *args, methods=[], **kwargs): + def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.proxy = None - self.set_method('Introspect') - - for name in methods: - self.set_method(name) + self.methods = DotDict() + self.signals = DotDict() def __enter__(self): @@ -57,14 +57,18 @@ class DBusClientBase(DBusBase): self.proxy = self.get_proxy(self.dbuspath) try: - self.Introspect() + self.set_methods_and_signals() + return True + ## Make errors shorter and just reuse ConnectionError except DBusError as e: - if 'was not provided by any .service files' in str(e): - self.proxy = None - return + if str(e) == f'The name {self.interface_name} was not provided by any .service files': + raise ConnectionError(f'Namespace "{self.interface_name}" does not exist') from None - traceback.print_exc() + elif str(e) == f'No such object path \'{self.dbuspath}\'': + raise ConnectionError(f'Path "{self.dbuspath}" does not exist') from None + + raise e from None def disconnect(self): @@ -82,12 +86,40 @@ class DBusClientBase(DBusBase): return func(*args, **kwargs) - def set_method(self, name): - if not getattr(self, name, False): - setattr(self, name, lambda *args, **kwargs: self.cmd(name, *args, **kwargs)) + def sig_connect(self, signal, callback, *args, original_args=True, **kwargs): + if original_args: + self.signals[signal].connect(lambda *sigargs, **sigkwargs: callback(*sigargs, *args, **sigkwargs, **kwargs)) else: - logging.warning('Tried to add an existing method:', name) + self.signals[signal].connect(lambda *sigargs, **sigkargs: callback(*args, **kwargs)) + + + def set_method(self, name): + self.methods[name] = partial(self.cmd, name) + setattr(self, name, partial(self.cmd, name)) + + + def set_signal(self, name): + signal = getattr(self.proxy, name) + self.signals[name] = signal + setattr(self, name, partial(self.connect, name)) + + + def set_methods_and_signals(self, namespace=None): + for element in ElementTree.fromstring(self.cmd('Introspect')): + if element.attrib['name'] == namespace or self.interface_name: + for e in element: + name = e.attrib['name'] + + if getattr(self, name, None): + logging.verbose('Tried to add an existing method or signal:', name) + continue + + if e.tag == 'method': + self.set_method(name) + + elif e.tag == 'signal': + self.set_signal(name) class DBusServerBase(DBusBase): diff --git a/sql/izzylib/sql/generic.py b/sql/izzylib/sql/generic.py index 218c692..5df80c8 100644 --- a/sql/izzylib/sql/generic.py +++ b/sql/izzylib/sql/generic.py @@ -264,11 +264,18 @@ class SqlSession(object): row = self.execute(f'DELETE FROM {table} WHERE id={rowid}') + def drop_table(self, name): + if name not in self.table: + raise KeyError(f'Table does not exist: {name}') + + self.execute(f'DROP TABLE {table}') + + def drop_tables(self): tables = self.get_tables() for table in tables: - self.execute(f'DROP TABLE {table}') + self.drop_table(table) def get_tables(self):