def post_config_hook(self): if self.user: bus = SessionBus() else: bus = SystemBus() systemd = bus.get("org.freedesktop.systemd1") self.systemd_unit = bus.get(".systemd1", systemd.LoadUnit(self.unit))
def info(self): tod_time = time.strftime("%a, %d %b %Y %H:%M:%S", time.localtime(start_time)) message_string = ("Wheel circumference: {} meters\n" "Start time: {}\n" "GPIO Channel Number: {}" .format(wheel_circumference, tod_time, channel)) bus_1 = SessionBus() notifications = bus_1.get('.Notifications') notifications.Notify('test', 0, 'dialog-information', "Pydbus Server Information", message_string, [], {}, 5000)
def bus(): from pydbus import SessionBus bus = SessionBus() time.sleep(.5) print("\n[initalize] pydbus.SessionBus ...") bus.own_name(name="org.scarlett") # bus.dbus time.sleep(.5) yield bus print("\n[teardown] pydbus.SessionBus ...") # del bus._dbus print("ran: del bus._dbus") del bus print("ran: del bus")
def _init_dbus(self): """ Get the device id """ _bus = SessionBus() if self.device_id is None: self.device_id = self._get_device_id(_bus) if self.device_id is None: return False try: self._dev = _bus.get(SERVICE_BUS, DEVICE_PATH + "/%s" % self.device_id) except Exception: return False return True
def post_config_hook(self): if self.py3.is_gevent(): raise Exception(STRING_GEVENT) self._dbus = None self._data = {} self._control_states = {} self._kill = False self._mpris_players = {} self._mpris_names = {} self._mpris_name_index = {} self._player = None self._player_details = {} self._tries = 0 # start last self._dbus = SessionBus() self._start_listener() self._states = { "pause": { "action": "Pause", "clickable": "CanPause", "icon": self.icon_pause, }, "play": { "action": "Play", "clickable": "CanPlay", "icon": self.icon_play }, "stop": { "action": "Stop", "clickable": "True", # The MPRIS API lacks 'CanStop' function. "icon": self.icon_stop, }, "next": { "action": "Next", "clickable": "CanGoNext", "icon": self.icon_next, }, "previous": { "action": "Previous", "clickable": "CanGoPrevious", "icon": self.icon_previous, }, }
def main(): parser = argparse.ArgumentParser(description="test service client") sub = parser.add_subparsers(title='subcommands', dest='subcommand') echo_parser = sub.add_parser("echo", help="echo a string") echo_parser.add_argument("str", help="String to be echoed") echo_parser.set_defaults(func=echo) wait_parser = sub.add_parser("wait", help="simulate a long running command") wait_parser.add_argument("timeout", type=int, help="Amount of time to wait.") wait_parser.set_defaults(func=wait) variant_parser = sub.add_parser("variant", help="returns a variant response") variant_parser.add_argument("--double", "-d", action='store_true') variant_parser.set_defaults(func=variant) send_signal_parser = sub.add_parser("signal", help="send a signal") send_signal_parser.add_argument("name", help="Signal name", choices=["S1", "S2"]) send_signal_parser.add_argument("value", help="Signal value") send_signal_parser.set_defaults(func=send_signal) listen_parser = sub.add_parser("listen", help="wait for a signal") listen_parser.add_argument("--name", "-n", help="Signal name") listen_parser.add_argument("--value", "-v", help="Signal value") listen_parser.set_defaults(func=listen_signal) config_parser = sub.add_parser("config", help="configures properties") config_parser.add_argument('args', nargs='*') config_parser.set_defaults(func=config) args = parser.parse_args() bus = SessionBus() service = bus.get(ENDPOINT, SERVICE_PATH) args.func(service, args)
def wakeup_response(): # Make threading safe lock = threading.Lock() lock.acquire() VoiceAssistant.assistant_is_busy = True dbus_client = None try: client_bus = SessionBus() dbus_client = client_bus.get("org.LinuxAssistantClient") except: print("[log] Can't connect to the client") VoiceAssistant.say(VoiceAssistant.greeter(), client=dbus_client) voice_cmd = None try: voice_cmd = VoiceAssistant.recognize(client=dbus_client) except sr.UnknownValueError: print("[log] Голос не распознан!") except sr.RequestError as e: print("[log] Неизвестная ошибка, проверьте интернет!") if voice_cmd is not None: print("[log] Распознано: " + voice_cmd) voice_cmd = voice_cmd.lower() for word in opts['alias']: voice_cmd = voice_cmd.replace(word, '').strip() for word in opts['tbr']: voice_cmd = voice_cmd.replace(word, '').strip() cmd = VoiceAssistant.identify_command(voice_cmd) VoiceAssistant.execute_command(cmd, dbus_client=dbus_client) lock.release() VoiceAssistant.assistant_is_busy = False
def __init__(self, config, client): super().__init__() self.config = config bus = SessionBus() self.bot = RetryProxy(bus, "se.raek.PladderBot") self.log = RetryProxy(bus, "se.raek.PladderLog") self.connector = PladderConnector(bus, config, client) self.running = False self.exe = None self.loop = None self.loop_future = None
def __init__(self): super().__init__(enable_signal_handler=True) bus = SessionBus() register_screensaver(bus, callback=self.event_handler) self.add(AcpiEventListener(callback=self.event_handler)) self.add(GLibMainLoop()) self.spotify = SpotifyDBus(bus) self.notify = NotifyDBus(bus, callback=self.event_handler) self.scheduler = EventScheduler() self.add(self.scheduler) self.was_playing = False
def __attrs_post_init__(self): self.bus = SessionBus() self.pan_bus = self.bus.get("org.pantalaimon1") self.ctl = self.pan_bus["org.pantalaimon1.control"] self.devices = self.pan_bus["org.pantalaimon1.devices"] self.own_message_ids = [] self.ctl.Response.connect(self.show_response) self.ctl.UnverifiedDevices.connect(self.unverified_devices) self.completer = PanCompleter(self.commands, self.ctl, self.devices) self.devices.VerificationInvite.connect(self.show_sas_invite) self.devices.VerificationString.connect(self.show_sas) self.devices.VerificationDone.connect(self.sas_done) self.devices.KeyRequest.connect(self.show_key_request) self.devices.KeyRequestCancel.connect(self.show_key_request_cancel)
class KbDaemon: def __init__(self): # Logging self.logger = logging.getLogger('daemon') self.logger.setLevel(logging.DEBUG) sh = logging.StreamHandler() sh.setLevel(logging.DEBUG) self.logger.addHandler(sh) # DBus self.bus = SessionBus() def start(self): try: self.bus.request_name('com.qtech.openkeyboard') self.bus.register_object('/com/qtech/openkeyboard', DaemonInterface(), None) except RuntimeError: self.logger.exception('Failed to connect to DBus') exit() # List keyboards kb_info = self.find_keyboard() print(kb_info) if kb_info is not None: self.logger.info(f'Connecting to keyboard at {kb_info["path"]}') rd = RedDragon(Device(path=kb_info['path'])) self.bus.register_object( f'/com/qtech/openkeyboard/{kb_info["manufacturer_string"]}', KeyboardInterface(rd), None) else: self.logger.info(f'Creating fake keyboard') fake = FakeKeyboard() self.bus.register_object('/com/qtech/openkeyboard/fake', KeyboardInterface(fake), None) # Start main loop GLib.MainLoop().run() def find_keyboard(self): devices = enumerate(VID, PID) for device in devices: print(device) if device['interface_number'] == 1: return device return None
def post_config_hook(self): self._dbus = None self._data = {} self._control_states = {} self._kill = False self._mpris_players = {} self._mpris_names = {} self._mpris_name_index = {} self._player = None self._player_details = {} self._tries = 0 # start last self._dbus = SessionBus() self._start_listener() self._states = { 'pause': { 'action': 'Pause', 'clickable': 'CanPause', 'icon': self.icon_pause }, 'play': { 'action': 'Play', 'clickable': 'CanPlay', 'icon': self.icon_play }, 'stop': { 'action': 'Stop', 'clickable': 'True', # The MPRIS API lacks 'CanStop' function. 'icon': self.icon_stop }, 'next': { 'action': 'Next', 'clickable': 'CanGoNext', 'icon': self.icon_next }, 'previous': { 'action': 'Previous', 'clickable': 'CanGoPrevious', 'icon': self.icon_previous } }
class DBusThread(Thread): def __init__(self, c, dbus_mm): super().__init__(name='DBus', daemon=True) self._c = c self._loop = GLib.MainLoop() self._bus = SessionBus() self._dbus_mm = dbus_mm self._dbus_mm.loop = self._loop self._dbus_mm.bus = self._bus def run(self): pub = {} # for t, module in self._mm.modules.items(): # try: # pub[t] = self._bus.publish(module.name, (module)) # except (GLib.Error, TypeError) as e: # logger.error(f'error publishing {t} because {e}') # logger.error('dbus string is likely empty or doesn\'t exist, this can be safely ignored') self._bus.publish(self._c['DBus']['prefix'], self._dbus_mm) self._loop.run()
def start(self): # Load requested plugins self.plugins = [ importlib.import_module('plugins.' + plugin).__plugin__(self) for plugin in self.args.plugins ] # Start listening for messages if self.args.bus == 'session' or self.args.bus is None: bus = SessionBus() elif self.args.bus == 'system': bus = SystemBus() else: bus = connect(self.args.bus) self.signal = bus.get('org.asamk.Signal') self.signal.onMessageReceived = self.receive loop = GLib.MainLoop() loop.run()
def main(args): bus = SessionBus() loop = GLib.MainLoop() def new_wallpaper(): wg.NewWallpaper(args.type, args.subreddit, args.directory, args.output, args.generate_only) if args.dbus: bus.publish('de.thm.mni.mhpp11.WallGen', WallGenDBUSService(loop)) run(loop) else: try: wg = bus.get('de.thm.mni.mhpp11.WallGen') except GLib.Error: wg = WallGenDBUSService(None) if type(wg) != WallGenDBUSService: if args.monitor: dc = bus.get('org.gnome.Mutter.DisplayConfig') with wg.Closed.connect(loop.quit): with dc.MonitorsChanged.connect(new_wallpaper): run(loop) elif args.quit: wg.Close() if not args.monitor: new_wallpaper() elif type(wg) == WallGenDBUSService: raise Exception("Monitoring is not possible without DBus service!")
def __enter__(self): # SIGTERMs should also lead to __exit__() being called. Note that # SIGINTs/KeyboardInterrupts are already handled by GLib.MainLoop signal.signal(signal.SIGTERM, self._sigterm_handler) if self._config['bus'] == 'session' or self._config['bus'] is None: self._bus = SessionBus() elif self.args.bus == 'system': self._bus = SystemBus() else: self._bus = connect(self._config['bus']) if self._mocker: self._signal = self._bus.get('org.signalbot.signalclidbusmock') else: self._signal = self._bus.get('org.asamk.Signal') self._signal.onMessageReceived = self._triagemessage # Actively discourage chdir in plugins, see _triagemessage self._fakecwd = TemporaryDirectory() Path(self._fakecwd.name).chmod(S_IEXEC) chdir(self._fakecwd.name) try: self._plugin_routers = {} self._chats = Chats(bot=self) for plugin in self._config['plugins']: self._init_plugin(plugin) for plugin in self._config['testing_plugins']: self._init_plugin(plugin, test=True) self._loop = GLib.MainLoop() self._thread = Thread(daemon=True, target=self._loop.run) self._thread.start() if self._config['startup_notification']: for master in self._config['master']: master_chat_id = Chats.get_id_from_sender_and_group_id( master) master_chat = self._chats.get(master_chat_id, store=True) self.send_success('Always at your service!', [], master_chat) except Exception as e: # Try not to leave empty temporary directories behind when e.g. a # plugin fails to load Path(self._fakecwd.name).chmod(S_IREAD) self._fakecwd.cleanup() raise e return self
def cli(): ARGS = sys.argv[1:] bus = SessionBus() rofi_bus = bus.get('pro.wizardsoftheweb.pyrofibus') if ARGS and ARGS[0]: rofi_bus.ActivateWindow(int(ARGS[0].split(' ')[-1])) exit(0) window_ids = rofi_bus.GetWindowList() desktops = get_desktop_names().reply() items = [] max_desktop = 0 max_class = 0 max_name = 0 for window_id in window_ids: new_item = [ desktops[get_wm_desktop(window_id).reply()], get_property( window_id, 'WM_CLASS').reply().value.to_string().split('\x00')[1], get_wm_name(window_id).reply().encode('utf-8'), window_id, ] max_desktop = len( new_item[0]) if len(new_item[0]) > max_desktop else max_desktop max_class = len( new_item[1]) if len(new_item[1]) > max_class else max_class max_name = len( new_item[2]) if len(new_item[2]) > max_name else max_name items.append(new_item) items.append(items.pop(0)) for item in items: print("{:{max_desktop}} {:{max_class}} {:{max_name}} {}".format( *item, max_desktop=max_desktop + 2, max_class=max_class + 2, max_name=max_name))
class SpotifyDBus: def __init__(self): self.proxy = SessionBus().get('org.mpris.MediaPlayer2.spotify', '/org/mpris/MediaPlayer2') def get_metadata(self): return {k.split(':')[1]: v for k, v in self.proxy.Metadata.items()} def toggle_play(self): self.proxy.PlayPause() def is_paused(self): return self.proxy.PlaybackStatus == "Paused"
def __init__(self): super().__init__() state_home = os.environ.get( "XDG_CONFIG_HOME", os.path.join(os.environ["HOME"], ".config")) state_dir = os.path.join(state_home, "pladder-web") os.makedirs(state_dir, exist_ok=True) db_file_path = os.path.join(state_dir, "tokens.db") self.db = self.enter_context(TokenDb(db_file_path)) bus = SessionBus() self.dbus_connector = PladderConnector(self.db, bus) self.dbus_web_api = PladderWebApi(self.db, bus) self.bot = RetryProxy(bus, "se.raek.PladderBot") self.enter_context(dbus_loop())
def _connect_to_dbus(self): self.bus = SessionBus() self.dbus_proxy = self.bus.get("org.scarlett", object_path='/org/scarlett/Listener') # NOQA self.dbus_proxy.emitConnectedToListener('ScarlettListener') sleep(2) logger.info('_connect_to_dbus') ss_cancel_signal = self.bus.subscribe(sender=None, iface="org.scarlett.Listener", signal="ListenerCancelSignal", object="/org/scarlett/Listener", arg0=None, flags=0, signal_fired=self.cancel_listening)
def main(): loop = GLib.MainLoop() def signalHandler(sig, frame): loop.quit() signal.signal(signal.SIGCHLD, signalHandler) signal.signal(signal.SIGINT, signalHandler) signal.signal(signal.SIGTERM, signalHandler) bus = SessionBus() spotify = None while spotify == None: try: spotify = bus.get(DBUS_CLIENT, OBJECT_PATH) player = spotify[PLAYER_IFACE] try: metadata = player.Metadata playbackStatus = player.PlaybackStatus printUpdate(metadata, playbackStatus) except Exception: output = { "text": "Playback is stopped", "class": "custom-spotify", "alt": "Spotify", } sys.stdout.write(json.dumps(output) + "\n") sys.stdout.flush() spotify.PropertiesChanged.connect(lambda _s, _a, _as: printUpdate( _a["Metadata"], _a["PlaybackStatus"])) except Exception: # Spotify isn't running, keep the loop running sleep(1) loop.run()
def __init__(self, signals: Optional[Iterable[dict]] = None, service_name: Optional[str] = _default_service_name, service_path: Optional[str] = _default_service_path, **kwargs): """ :param signals: Specify this if you want to subscribe to specific DBus signals. Structure: .. schema:: dbus.DbusSignalSchema(many=True) For example, to subscribe to all the messages on the session bus: .. code-block:: yaml dbus: signals: - bus: session :param service_name: Name of the D-Bus service where Platypush will listen for new messages (requests and events). Set to null if you want to disable message execution over D-Bus for Platypush (default: ``org.platypush.Bus``). :param service_path: The path of the D-Bus message listener. Set to null if you want to disable message execution over D-Bus for Platypush (default: ``/``). """ super().__init__(**kwargs) self._system_bus = SystemBus() self._session_bus = SessionBus() self._loop = None self._signals = DbusSignalSchema().load(signals or [], many=True) self._signal_handlers = [ self._get_signal_handler(**signal) for signal in self._signals ] self.service_name = service_name self.service_path = service_path
def main(): # parser = argparse.ArgumentParser() # setup the main loop loop = GLib.MainLoop() # publish on dbus and start main loop try: with SessionBus().publish(TestObject.name, TestObject()): print("Server running on {}".format( os.environ['DBUS_SESSION_BUS_ADDRESS'])) loop.run() except KeyboardInterrupt: loop.quit() return 0
def observe(self, config, watch_dirs): self.msg.info(self.name, "Using MPRIS.") self.re_players = re.compile(config['tracker_process']) self.filenames = {} self.statuses = {} self.view_offsets = {} self.timing = False self.active_player = None self.session = SessionBus() self.bus = self.session.get('.DBus') # Look for already running players and conect them for name in self.bus.ListNames(): if name.startswith(MPRISTracker.mpris_base): self._connect(name) # Connect signal for any new players that could appear self.bus.NameOwnerChanged.connect(self._new_name) # Run GLib loop loop = GLib.MainLoop() loop.run()
async def startTestFakeDbusBluez(self): if not self.bus: self.bus = SessionBus() await self.unexportAllDevices() if self.busName: busName.unown() if self.fakeDbusAdapterRegistration: self.fakeDbusAdapterRegistration.unregister() self.fakeDbusAdapterRegistration = None if self.fakeDbusObjectManagerRegistration: self.fakeDbusObjectManagerRegistration.unregister() self.fakeDbusObjectManagerRegistration = None await asyncio.sleep(0.5) prefix = "/" + self.bluetoothAudioBridge.DbusBluezBusName.replace( ".", "/") self.fakeDbusObjectManager = TestFakeObjectManager(self.bus) self.fakeDbusAdapter = TestFakeDbusBluezAdapter(self) self.fakeDbusObjectManagerRegistration = self.bus.register_object( "/", self.fakeDbusObjectManager, None) self.fakeDbusAdapterRegistration = self.fakeDbusObjectManager.export( prefix + "/hci0", self.fakeDbusAdapter) self.busName = self.bus.request_name( self.bluetoothAudioBridge.DbusBluezBusName)
def get_bus(request, get_environment, create_session_bus): """ Provide the session bus instance. Adapted from: https://github.com/martinpitt/python-dbusmock/blob/master/dbusmock/testcase.py#L137 # noqa """ # Fixture finalization / executing teardown code pytest # supports execution of fixture specific finalization code # when the fixture goes out of scope. # By using a yield statement instead of return, # all the code after the yield # statement serves as the teardown code.: # if os.environ.get('DBUS_SESSION_BUS_ADDRESS'): if get_environment["DBUS_SESSION_BUS_ADDRESS"]: print("[get_bus] inside if environment['DBUS_SESSION_BUS_ADDRESS']") bus = connect(get_environment["DBUS_SESSION_BUS_ADDRESS"]) # yield bus # print("teardown new session bus") # return dbus.bus.BusConnection(os.environ['DBUS_SESSION_BUS_ADDRESS']) else: print("\n[get_bus] default SessionBus") bus = SessionBus() def teardown(): """ As historical note, another way to write teardown code is by accepting a request object into your fixture function and can call its request.addfinalizer one or multiple times: """ # NOTE: # SessionBus() and SystemBus() are not closed automatically, so this should work # source: https://github.com/xZise/pydbus/blob/addf3913368cdc7225039525f3e53ab62b2a0f70/pydbus/bus.py#L31 # NOTE: bus.dbus = @property from pydbus bus object. # NOTE: When you try to grab the property and it doesn't exist, # NOTE: it assigns a dbus connection again via: self._dbus = self.get(".DBus")[""] # NOTE: That's why we delete it each time # print("running: bus.con.close()") # bus.con.close() print("running: del bus._dbus") del bus._dbus # The finalizer is called after all of the tests that use the fixture. # If you’ve used parameterized fixtures, # the finalizer is called between instances of the parameterized fixture changes. request.addfinalizer(teardown) bus.dbus return bus
def test_user_facing_interface(self): from pydbus import SessionBus import os import sys import time ppath = os.path.abspath( os.path.dirname(os.path.abspath(sys.modules[__name__].__file__)) + "/..") os.system('export PYTHONPATH="' + ppath + '";cd ' + ppath + ";" + sys.executable + " -m tests.unittest_server&") #print(ppath) sb = SessionBus() tick = time.time() + 30 test_server = None while time.time() < tick: try: test_server = sb.get('pydbus.unittest', timeout=10) break except: time.sleep(1) pass self.assertIsNotNone(test_server) r = test_server.NoArgsStringReply() self.assertEqual(r, 0, "Translation Inactive") r = test_server.AddTwo(2) self.assertEqual(r, 4, "Translation Inactive") test_server = sb.get('pydbus.unittest', translation_spec=True, timeout=10) r = test_server.NoArgsStringReply() self.assertEqual(r, "first string", "Translation Active") r = test_server.AddTwo(2) self.assertEqual(r, 4, "Translation Active") test_server.Quit()
def __init__(self, npn): self._players = {} bus = SessionBus() self._dbus = bus.get('org.freedesktop.DBus', '/org/freedesktop/DBus') def handler(name, old_owner, new_owner): if name.startswith(BUS_NAME_PREFIX): if old_owner: assert old_owner in self._players.keys() self._players[old_owner].close() del self._players[old_owner] if new_owner: assert new_owner not in self._players.keys() self._players[new_owner] = PlayerObserver( npn, bus, new_owner) logger.info('Subscribing to «org.freedesktop.DBus.NameOwnerChanged»…') self._handle = self._dbus.NameOwnerChanged.connect(handler) # This is a bit of a race. for name in self._dbus.ListNames(): if name.startswith(BUS_NAME_PREFIX): owner = self._dbus.GetNameOwner(name) self._players[owner] = PlayerObserver(npn, bus, owner)
def set_up_dbus(hooks_base_class): from gi.repository import GLib from pydbus import SessionBus bus = SessionBus() bot = bus.get("se.raek.PladderBot") log = PladderLogProxy(bus) class DbusHooks(hooks_base_class): def on_trigger(self, timestamp, network, channel, sender, text): try: return bot.RunCommand(timestamp, network, channel, sender.nick, text) except GLib.Error as e: logger.error(str(e)) return "Oops! Error logged." def on_privmsg(self, timestamp, network, channel, sender, text): log.AddLine(timestamp, network, channel, sender.nick, text) def on_send_privmsg(self, timestamp, network, channel, nick, text): log.AddLine(timestamp, network, channel, nick, text) return DbusHooks
def __init__(self, use_terminal = True, use_libnotify = True, debug = False, device_id = None, device_name = None, ignore = None): """ Get the device id """ self.terminal = use_terminal self.libnotify = use_libnotify self.debug = debug if ignore: self.ignore = [app.lower() for app in ignore] if not self.terminal: self._debug('hide terminal messages') if not self.libnotify: self._debug('hide notifications') if use_libnotify: Notify.init('KDEConnect Notify') if ignore: apps = ignore[0] for app in ignore[1:]: apps += ', ' + app self._debug('ignore ' + apps) self._bus = SessionBus() if device_id is None: self.device_id = self._get_device_id(device_id, device_name) if self.device_id is None: self._debug('No device id found') return else: self.device_id = device_id self._debug('Device id is %s' % self.device_id) try: self._dev = self._bus.get(SERVICE_BUS, DEVICE_PATH + '/%s' % self.device_id) except Exception: self.device_id = None return
def NewWallpaper(self, _=None): builder = None print("Create a new Wallpaper...") bus = SessionBus() if self.config.type == 'reddit': generator = RedditGenerator(self.config.subreddit) else: generator = LocalGenerator(self.config.directory) if self.config.is_gnome(): builder = GnomeWallpaperBuilder(bus, self.config) elif self.config.is_kde(): builder = KDEWallpaperBuilder(bus, self.config) builder.build(generator)
class GnomeBrightnessSetter(BrightnessSetter): def __init__(self, output_names: list[str] = []): super().__init__(output_names) from pydbus import SessionBus self.bus = SessionBus() self.serial = None self.display_conf = self.bus.get('org.gnome.Mutter.DisplayConfig') self.init_configuration() def init_configuration(self): res = self.display_conf.GetResources() if res[0] == self.serial: return self.serial = res[0] for crtc in self.crtcs.values(): crtc['id'] = None for output in res[2]: crtc_id = output[2] name = output[4] if name in self.crtcs: crtc = self.crtcs[name] crtc['id'] = crtc_id if crtc['original_gamma'] is None: gamma = self.display_conf.GetCrtcGamma( self.serial, crtc_id) crtc['original_gamma'] = gamma def set_brightness(self, brightness: Optional[float]): self.init_configuration() for name, crtc in self.crtcs.items(): if crtc['id'] is None: continue gamma = self.generate_gamma_table(name, brightness) try: self.display_conf.SetCrtcGamma(self.serial, crtc['id'], gamma[0], gamma[1], gamma[2]) except Exception as e: print(f'could not set gamma for {crtc["id"]}: {e}') continue
def _connect_to_dbus(self): self.bus = SessionBus() self.dbus_proxy = self.bus.get( "org.scarlett", object_path="/org/scarlett/Listener" ) # NOQA self.dbus_proxy.emitConnectedToListener("ScarlettListener") time.sleep(2) logger.info("_connect_to_dbus") # TODO: Add a ss_cancel_signal.disconnect() function later ss_cancel_signal = self.bus.subscribe( sender=None, iface="org.scarlett.Listener", signal="ListenerCancelSignal", object="/org/scarlett/Listener", arg0=None, flags=0, signal_fired=self.on_cancel_listening, )
def start(): args = parse_arguments() config = Config() if not config.is_supported_desktop(): raise Exception('Desktop environment not supported.') bus = SessionBus() loop = GLib.MainLoop() if args.dbus: bus.publish('de.thm.mni.mhpp11.WallGen', WallGenDBUSService(loop)) run(loop) else: try: wg = bus.get('de.thm.mni.mhpp11.WallGen') except GLib.Error: wg = WallGenDBUSService(None) if type(wg) != WallGenDBUSService: if args.monitor: dc = None if config.is_gnome(): dc = bus.get('org.gnome.Mutter.DisplayConfig') elif config.is_kde(): dc = bus.get('org.kde.KScreen', object_path='/backend') with wg.Closed.connect(loop.quit): if config.is_gnome(): with dc.MonitorsChanged.connect(wg.NewWallpaper): run(loop) elif config.is_kde(): class KDENewWallpaper: first_call = True def call(self, _): if (self.first_call): wg.NewWallpaper() self.first_call = not self.first_call with dc.configChanged.connect(KDENewWallpaper().call): run(loop) elif args.quit: wg.Close() elif type(wg) == WallGenDBUSService and args.monitor: raise Exception("Monitoring is not possible without DBus service!") if not args.monitor and not args.quit: wg.NewWallpaper()
def post_config_hook(self): if self.py3.is_gevent(): raise Exception(STRING_GEVENT) self._dbus = None self._data = {} self._control_states = {} self._kill = False self._mpris_players = {} self._mpris_names = {} self._mpris_name_index = {} self._player = None self._player_details = {} self._tries = 0 # start last self._dbus = SessionBus() self._start_listener() self._states = { "pause": { "action": "Pause", "clickable": "CanPause", "icon": self.icon_pause, }, "play": {"action": "Play", "clickable": "CanPlay", "icon": self.icon_play}, "stop": { "action": "Stop", "clickable": "True", # The MPRIS API lacks 'CanStop' function. "icon": self.icon_stop, }, "next": { "action": "Next", "clickable": "CanGoNext", "icon": self.icon_next, }, "previous": { "action": "Previous", "clickable": "CanGoPrevious", "icon": self.icon_previous, }, }
class Py3status: """ """ # available configuration parameters button_stop = None button_toggle = 1 button_next = 4 button_previous = 5 format = "{previous}{toggle}{next} {state} [{artist} - ][{title}]" format_none = "no player running" icon_pause = u"▮" icon_play = u"▶" icon_stop = u"◾" icon_next = u"»" icon_previous = u"«" state_pause = u"▮" state_play = u"▶" state_stop = u"◾" player_priority = [] def __init__(self): self._dbus = None self._data = {} self._kill = False self._mpris_players = {} self._mpris_names = {} self._mpris_name_index = {} self._player = None self._player_details = {} self._tries = 0 def post_config_hook(self): self._dbus = SessionBus() self._start_listener() def _init_data(self): self._data = { "album": None, "artist": None, "error_occurred": False, "length": None, "player": None, "state": STOPPED, "title": None, } if self._player is None: return try: self._data["player"] = self._player.Identity playback_status = self._player.PlaybackStatus self._data["state"] = self._get_state(playback_status) metadata = self._player.Metadata self._update_metadata(metadata) except Exception: self._data["error_occurred"] = True def _get_button_state(self, control_state): try: # Workaround: The last parameter returns True for the Stop button. clickable = getattr(self._player, control_state["clickable"], True) except Exception: clickable = False state = self._data.get("state") if control_state["action"] == "Play" and state == PLAYING: clickable = False elif control_state["action"] == "Pause" and state in [STOPPED, PAUSED]: clickable = False elif control_state["action"] == "Stop" and state == STOPPED: clickable = False return clickable def _get_state(self, playback_status): if playback_status == "Playing": return PLAYING elif playback_status == "Paused": return PAUSED else: return STOPPED def _get_text(self): """ Get the current metadata """ if self._data.get("state") == PLAYING: color = self.py3.COLOR_PLAYING or self.py3.COLOR_GOOD state_symbol = self.state_play elif self._data.get("state") == PAUSED: color = self.py3.COLOR_PAUSED or self.py3.COLOR_DEGRADED state_symbol = self.state_pause else: color = self.py3.COLOR_STOPPED or self.py3.COLOR_BAD state_symbol = self.state_stop if self._data.get("error_occurred"): color = self.py3.COLOR_BAD try: ptime_ms = self._player.Position ptime = _get_time_str(ptime_ms) except Exception: ptime = None if "{time}" in self.format and self._data.get("state") == PLAYING: # Don't get trapped in aliasing errors! update = time() + 0.5 else: update = self.py3.CACHE_FOREVER placeholders = { "player": self._data.get("player"), "state": state_symbol, "album": self._data.get("album"), "artist": self._data.get("artist"), "length": self._data.get("length"), "time": ptime, "title": self._data.get("title") or "No Track", "full_name": self._player_details.get("full_name"), # for debugging ;p } return (placeholders, color, update) def _get_control_states(self): control_states = { "pause": {"action": "Pause", "clickable": "CanPause", "icon": self.icon_pause}, "play": {"action": "Play", "clickable": "CanPlay", "icon": self.icon_play}, "stop": { "action": "Stop", # Workaround: The MPRIS API has no CanStop function. "clickable": "True", "icon": self.icon_stop, }, "next": {"action": "Next", "clickable": "CanGoNext", "icon": self.icon_next}, "previous": {"action": "Previous", "clickable": "CanGoPrevious", "icon": self.icon_previous}, } state = "pause" if self._data.get("state") == PLAYING else "play" control_states["toggle"] = control_states[state] return control_states def _get_response_buttons(self): response = {} for button in self._control_states.keys(): control_state = self._control_states[button] if self._get_button_state(control_state): color = self.py3.COLOR_CONTROL_ACTIVE or self.py3.COLOR_GOOD else: color = self.py3.COLOR_CONTROL_INACTIVE or self.py3.COLOR_BAD response[button] = { "color": color, "full_text": control_state["icon"], "index": button, "min_width": 20, "align": "center", } return response def _start_loop(self): self._loop = GObject.MainLoop() GObject.timeout_add(1000, self._timeout) try: self._loop.run() except KeyboardInterrupt: # This branch is only needed for the test mode self._kill = True def _name_owner_changed(self, *args): player_add = args[5][2] player_remove = args[5][1] if player_add: self._add_player(player_add) if player_remove: self._remove_player(player_remove) self._set_player() def _set_player(self): """ Sort the current players into priority order and set self._player Players are ordered by working state then prefernce supplied by user and finally by instance if a player has more than one running. """ players = [] for name, p in self._mpris_players.items(): # we set the priority here as we need to establish the player name # which might not be immediately available. if "_priority" not in p: if self.player_priority: try: priority = self.player_priority.index(p["name"]) except ValueError: try: priority = self.player_priority.index("*") except ValueError: priority = None else: priority = 0 if priority is not None: p["_priority"] = priority if p.get("_priority") is not None: players.append((p["_state_priority"], p["_priority"], p["index"], name)) if players: top_player = self._mpris_players.get(sorted(players)[0][3]) else: top_player = {} self._player = top_player.get("_dbus_player") self._player_details = top_player self.py3.update() def _player_monitor(self, player_id): def player_on_change(*args): """ Monitor a player and update its status. """ data = args[1] status = data.get("PlaybackStatus") if status: player = self._mpris_players[player_id] player["status"] = status player["_state_priority"] = WORKING_STATES.index(status) self._set_player() return player_on_change def _add_player(self, player_id): """ Add player to mpris_players """ try: player = self._dbus.get(player_id, SERVICE_BUS_URL) if player_id.startswith(SERVICE_BUS): if player.Identity not in self._mpris_names: self._mpris_names[player.Identity] = player_id.split(".")[-1] for p in self._mpris_players.values(): if not p["name"] and p["identity"] in self._mpris_names: p["name"] = self._mpris_names[p["identity"]] p["full_name"] = u"{} {}".format(p["name"], p["index"]) return status = player.PlaybackStatus state_priority = WORKING_STATES.index(status) identity = player.Identity if identity not in self._mpris_name_index: self._mpris_name_index[identity] = 0 index = self._mpris_name_index[identity] self._mpris_name_index[identity] += 1 name = self._mpris_names.get(identity) subscription = player.PropertiesChanged.connect(self._player_monitor(player_id)) except: return self._mpris_players[player_id] = { "_dbus_player": player, "_id": player_id, "_state_priority": state_priority, "index": index, "identity": identity, "name": name, "full_name": u"{} {}".format(name, index), "status": status, "subscription": subscription, } return True def _remove_player(self, player_id): """ Remove player from mpris_players """ player = self._mpris_players.get(player_id) if player: if player.get("subscription"): player["subscription"].disconnect() del self._mpris_players[player_id] def _get_players(self): bus = self._dbus.get("org.freedesktop.DBus") for player in bus.ListNames(): if player.startswith(":") or player.startswith(SERVICE_BUS): if not self._add_player(player): continue self._set_player() def _start_listener(self): self._dbus.con.signal_subscribe( None, "org.freedesktop.DBus", "NameOwnerChanged", None, None, 0, self._name_owner_changed ) self._get_players() t = Thread(target=self._start_loop) t.daemon = True t.start() def _timeout(self): if self._kill: self._loop.quit() sys.exit(0) def _update_metadata(self, metadata): is_stream = False try: if len(metadata) > 0: url = metadata.get("xesam:url") is_stream = url is not None and "file://" not in url self._data["title"] = metadata.get("xesam:title") self._data["album"] = metadata.get("xesam:album") if metadata.get("xesam:artist") is not None: self._data["artist"] = metadata.get("xesam:artist")[0] else: # we assume here that we playing a video and these types of # media we handle just like streams is_stream = True length_ms = metadata.get("mpris:length") if length_ms is not None: self._data["length"] = _get_time_str(length_ms) else: # use stream format if no metadata is available is_stream = True except Exception: self._data["error_occurred"] = True if is_stream and self._data.get("title"): # delete the file extension self._data["title"] = re.sub(r"\....$", "", self._data.get("title")) def kill(self): self._kill = True def mpris(self): """ Get the current output format and return it. """ current_player_id = self._player_details.get("id") cached_until = self.py3.CACHE_FOREVER if self._player is None: text = self.format_none color = self.py3.COLOR_BAD composite = [{"full_text": text, "color": color}] self._data = {} else: self._init_data() (text, color, cached_until) = self._get_text() self._control_states = self._get_control_states() buttons = self._get_response_buttons() composite = self.py3.build_composite(self.format, text, buttons) if self._data.get("error_occurred") or current_player_id != self._player_details.get("id"): # Something went wrong or the player changed during our processing # This is usually due to something like a player being killed # whilst we are checking its details # Retry but limit the number of attempts self._tries += 1 if self._tries < 3: return self.mpris() # Max retries hit we need to output something composite = [{"full_text": "Something went wrong", "color": self.py3.COLOR_BAD}] cached_until = self.py3.time_in(1) response = {"cached_until": cached_until, "color": color, "composite": composite} # we are outputing so reset tries self._tries = 0 return response def on_click(self, event): """ Handles click events """ index = event["index"] button = event["button"] if index not in self._control_states.keys(): if button == self.button_toggle: index = "toggle" elif button == self.button_stop: index = "stop" elif button == self.button_next: index = "next" elif button == self.button_previous: index = "previous" else: return elif button != 1: return control_state = self._control_states[index] if self._player and self._get_button_state(control_state): getattr(self._player, self._control_states[index]["action"])()
self._who = "human" self._state = "good" def hello(self): return "Hello %s!" % self._who def quit(self): loop.quit() def whatsup(self): return "@!#$*&@!, %s!" % self._who @property def State(self): return self._state @property def Who(self): return self._who @Who.setter def Who(self, value): self._who = value self.PropertiesChanged("org.me.test1", {"Who": self._who}, []) PropertiesChanged = signal() bus = SessionBus() bus.publish("org.me.test", MyDBUSService()) loop.run()
# set values wait for qualifier self.result(struct['hypothesis']) except KeyboardInterrupt: pipeline.send_event(Gst.Event.new_eos()) # Free resources pipeline.set_state(Gst.State.NULL) print "ScarlettListener stopped" if __name__ == '__main__': global logger logger = setup_logger() from pydbus import SessionBus bus = SessionBus() bus.own_name(name='org.scarlett') sl = ScarlettListener(bus=bus.con, path='/org/scarlett/Listener') LANGUAGE_VERSION = 1473 HOMEDIR = "/home/pi" LANGUAGE_FILE_HOME = "{}/dev/bossjones-github/scarlett-dbus-poc/tests/fixtures/lm".format( HOMEDIR) DICT_FILE_HOME = "{}/dev/bossjones-github/scarlett-dbus-poc/tests/fixtures/dict".format( HOMEDIR) LM_PATH = "{}/{}.lm".format(LANGUAGE_FILE_HOME, LANGUAGE_VERSION) DICT_PATH = "{}/{}.dic".format(DICT_FILE_HOME, LANGUAGE_VERSION) HMM_PATH = "{}/.virtualenvs/scarlett-dbus-poc/share/pocketsphinx/model/en-us/en-us".format( HOMEDIR) bestpath = 0 PS_DEVICE = 'plughw:CARD=Device,DEV=0'
def __init__(self, *args): _IdleObject.__init__(self) context = GObject.MainContext.default() self.bucket = bucket = Queue.Queue() # NOQA self.hello = None # with SessionBus() as bus: bus = SessionBus() ss = bus.get("org.scarlett", object_path='/org/scarlett/Listener') # NOQA time.sleep(1) ss_failed_signal = bus.subscribe(sender=None, iface="org.scarlett.Listener", signal="SttFailedSignal", object="/org/scarlett/Listener", arg0=None, flags=0, signal_fired=player_cb) ss_rdy_signal = bus.subscribe(sender=None, iface="org.scarlett.Listener", signal="ListenerReadySignal", object="/org/scarlett/Listener", arg0=None, flags=0, signal_fired=player_cb) ss_kw_rec_signal = bus.subscribe(sender=None, iface="org.scarlett.Listener", signal="KeywordRecognizedSignal", object="/org/scarlett/Listener", arg0=None, flags=0, signal_fired=player_cb) ss_cmd_rec_signal = bus.subscribe(sender=None, iface="org.scarlett.Listener", signal="CommandRecognizedSignal", object="/org/scarlett/Listener", arg0=None, flags=0, signal_fired=command_cb) ss_cancel_signal = bus.subscribe(sender=None, iface="org.scarlett.Listener", signal="ListenerCancelSignal", object="/org/scarlett/Listener", arg0=None, flags=0, signal_fired=player_cb) pp.pprint((ss_failed_signal, ss_rdy_signal, ss_kw_rec_signal, ss_cmd_rec_signal, ss_cancel_signal)) logger.debug("ss_failed_signal: {}".format(ss_failed_signal)) logger.debug("ss_rdy_signal: {}".format(ss_rdy_signal)) logger.debug("ss_kw_rec_signal: {}".format(ss_kw_rec_signal)) logger.debug("ss_cmd_rec_signal: {}".format(ss_cmd_rec_signal)) logger.debug("ss_cancel_signal: {}".format(ss_cancel_signal)) ss.emitConnectedToListener('ScarlettTasker') loop.run() # THE ACTUAL THREAD BIT # self.manager = FooThreadManager(3) try: print("ScarlettTasker Thread Started") except Exception: ss_failed_signal.disconnect() ss_rdy_signal.disconnect() ss_kw_rec_signal.disconnect() ss_cmd_rec_signal.disconnect() ss_cancel_signal.disconnect() loop.quit() self.bucket.put(sys.exc_info()) raise
from pydbus import SessionBus # TODO I'm not happy with the naming of this module. -> Find a better name # TODO check for privileges to suspend bus = SessionBus() power = bus.get('org.freedesktop.UPower', '/org/freedesktop/UPower') def suspend(): power.Suspend() def hibernate(): power.Hibernate() if __name__ == '__main__': suspend()
<interface name='net.lew21.pydbus.tests.publish_properties'> <property name="Foobar" type="s" access="readwrite"/> <property name="Foo" type="s" access="read"/> <property name="Bar" type="s" access="write"/> <method name='Quit'/> </interface> </node> ''' def __init__(self): self.Foo = "foo" self.Foobar = "foobar" def Quit(self): loop.quit() bus = SessionBus() with bus.publish("net.lew21.pydbus.tests.publish_properties", TestObject()): remote = bus.get("net.lew21.pydbus.tests.publish_properties") remote_iface = remote['net.lew21.pydbus.tests.publish_properties'] def t1_func(): for obj in [remote, remote_iface]: assert(obj.Foo == "foo") assert(obj.Foobar == "foobar") obj.Foobar = "barfoo" assert(obj.Foobar == "barfoo") obj.Foobar = "foobar" assert(obj.Foobar == "foobar") obj.Bar = "rab"
class Py3status: """ """ # available configuration parameters button_next = 4 button_previous = 5 button_stop = None button_toggle = 1 format = '{previous}{toggle}{next} {state} [{artist} - ][{title}]' format_none = 'no player running' icon_next = u'»' icon_pause = u'▮' icon_play = u'▶' icon_previous = u'«' icon_stop = u'◾' player_priority = [] state_pause = u'▮' state_play = u'▶' state_stop = u'◾' def __init__(self): self._dbus = None self._data = {} self._kill = False self._mpris_players = {} self._mpris_names = {} self._mpris_name_index = {} self._player = None self._player_details = {} self._tries = 0 def post_config_hook(self): self._dbus = SessionBus() self._start_listener() def _init_data(self): self._data = { 'album': None, 'artist': None, 'error_occurred': False, 'length': None, 'player': None, 'state': STOPPED, 'title': None } if self._player is None: return try: self._data['player'] = self._player.Identity playback_status = self._player.PlaybackStatus self._data['state'] = self._get_state(playback_status) metadata = self._player.Metadata self._update_metadata(metadata) except Exception: self._data['error_occurred'] = True def _get_button_state(self, control_state): try: # Workaround: The last parameter returns True for the Stop button. clickable = getattr(self._player, control_state['clickable'], True) except Exception: clickable = False state = self._data.get('state') if control_state['action'] == 'Play' and state == PLAYING: clickable = False elif control_state['action'] == 'Pause' and state in [STOPPED, PAUSED]: clickable = False elif control_state['action'] == 'Stop' and state == STOPPED: clickable = False return clickable def _get_state(self, playback_status): if playback_status == 'Playing': return PLAYING elif playback_status == 'Paused': return PAUSED else: return STOPPED def _get_text(self): """ Get the current metadata """ if self._data.get('state') == PLAYING: color = self.py3.COLOR_PLAYING or self.py3.COLOR_GOOD state_symbol = self.state_play elif self._data.get('state') == PAUSED: color = self.py3.COLOR_PAUSED or self.py3.COLOR_DEGRADED state_symbol = self.state_pause else: color = self.py3.COLOR_STOPPED or self.py3.COLOR_BAD state_symbol = self.state_stop if self._data.get('error_occurred'): color = self.py3.COLOR_BAD try: ptime_ms = self._player.Position ptime = _get_time_str(ptime_ms) except Exception: ptime = None if '{time}' in self.format and self._data.get('state') == PLAYING: # Don't get trapped in aliasing errors! update = time() + 0.5 else: update = self.py3.CACHE_FOREVER placeholders = { 'player': self._data.get('player'), 'state': state_symbol, 'album': self._data.get('album'), 'artist': self._data.get('artist'), 'length': self._data.get('length'), 'time': ptime, 'title': self._data.get('title') or 'No Track', 'full_name': self._player_details.get('full_name'), # for debugging ;p } return (placeholders, color, update) def _get_control_states(self): control_states = { 'pause': {'action': 'Pause', 'clickable': 'CanPause', 'icon': self.icon_pause}, 'play': {'action': 'Play', 'clickable': 'CanPlay', 'icon': self.icon_play}, 'stop': {'action': 'Stop', # Workaround: The MPRIS API has no CanStop function. 'clickable': 'True', 'icon': self.icon_stop}, 'next': {'action': 'Next', 'clickable': 'CanGoNext', 'icon': self.icon_next}, 'previous': {'action': 'Previous', 'clickable': 'CanGoPrevious', 'icon': self.icon_previous} } state = 'pause' if self._data.get('state') == PLAYING else 'play' control_states['toggle'] = control_states[state] return control_states def _get_response_buttons(self): response = {} for button in self._control_states.keys(): control_state = self._control_states[button] if self._get_button_state(control_state): color = self.py3.COLOR_CONTROL_ACTIVE or self.py3.COLOR_GOOD else: color = self.py3.COLOR_CONTROL_INACTIVE or self.py3.COLOR_BAD response[button] = { 'color': color, 'full_text': control_state['icon'], 'index': button, 'min_width': 20, 'align': 'center' } return response def _start_loop(self): self._loop = GObject.MainLoop() GObject.timeout_add(1000, self._timeout) try: self._loop.run() except KeyboardInterrupt: # This branch is only needed for the test mode self._kill = True def _name_owner_changed(self, *args): player_add = args[5][2] player_remove = args[5][1] if player_add: self._add_player(player_add) if player_remove: self._remove_player(player_remove) self._set_player() def _set_player(self): """ Sort the current players into priority order and set self._player Players are ordered by working state then prefernce supplied by user and finally by instance if a player has more than one running. """ players = [] for name, p in self._mpris_players.items(): # we set the priority here as we need to establish the player name # which might not be immediately available. if '_priority' not in p: if self.player_priority: try: priority = self.player_priority.index(p['name']) except ValueError: try: priority = self.player_priority.index('*') except ValueError: priority = None else: priority = 0 if priority is not None: p['_priority'] = priority if p.get('_priority') is not None: players.append( (p['_state_priority'], p['_priority'], p['index'], name) ) if players: top_player = self._mpris_players.get(sorted(players)[0][3]) else: top_player = {} self._player = top_player.get('_dbus_player') self._player_details = top_player self.py3.update() def _player_monitor(self, player_id): def player_on_change(*args): """ Monitor a player and update its status. """ data = args[1] status = data.get('PlaybackStatus') if status: player = self._mpris_players[player_id] player['status'] = status player['_state_priority'] = WORKING_STATES.index(status) self._set_player() return player_on_change def _add_player(self, player_id): """ Add player to mpris_players """ try: player = self._dbus.get(player_id, SERVICE_BUS_URL) if player_id.startswith(SERVICE_BUS): if player.Identity not in self._mpris_names: self._mpris_names[player.Identity] = player_id.split('.')[-1] for p in self._mpris_players.values(): if not p['name'] and p['identity'] in self._mpris_names: p['name'] = self._mpris_names[p['identity']] p['full_name'] = u'{} {}'.format(p['name'], p['index']) return status = player.PlaybackStatus state_priority = WORKING_STATES.index(status) identity = player.Identity if identity not in self._mpris_name_index: self._mpris_name_index[identity] = 0 index = self._mpris_name_index[identity] self._mpris_name_index[identity] += 1 name = self._mpris_names.get(identity) subscription = player.PropertiesChanged.connect( self._player_monitor(player_id) ) except: return self._mpris_players[player_id] = { '_dbus_player': player, '_id': player_id, '_state_priority': state_priority, 'index': index, 'identity': identity, 'name': name, 'full_name': u'{} {}'.format(name, index), 'status': status, 'subscription': subscription, } return True def _remove_player(self, player_id): """ Remove player from mpris_players """ player = self._mpris_players.get(player_id) if player: if player.get('subscription'): player['subscription'].disconnect() del self._mpris_players[player_id] def _get_players(self): bus = self._dbus.get('org.freedesktop.DBus') for player in bus.ListNames(): if player.startswith(':') or player.startswith(SERVICE_BUS): if not self._add_player(player): continue self._set_player() def _start_listener(self): self._dbus.con.signal_subscribe( None, 'org.freedesktop.DBus', 'NameOwnerChanged', None, None, 0, self._name_owner_changed, ) self._get_players() t = Thread(target=self._start_loop) t.daemon = True t.start() def _timeout(self): if self._kill: self._loop.quit() sys.exit(0) def _update_metadata(self, metadata): is_stream = False try: if len(metadata) > 0: url = metadata.get('xesam:url') is_stream = url is not None and 'file://' not in url self._data['title'] = metadata.get('xesam:title') self._data['album'] = metadata.get('xesam:album') if metadata.get('xesam:artist') is not None: self._data['artist'] = metadata.get('xesam:artist')[0] else: # we assume here that we playing a video and these types of # media we handle just like streams is_stream = True length_ms = metadata.get('mpris:length') if length_ms is not None: self._data['length'] = _get_time_str(length_ms) else: # use stream format if no metadata is available is_stream = True except Exception: self._data['error_occurred'] = True if is_stream and self._data.get('title'): # delete the file extension self._data['title'] = re.sub(r'\....$', '', self._data.get('title')) def kill(self): self._kill = True def mpris(self): """ Get the current output format and return it. """ current_player_id = self._player_details.get('id') cached_until = self.py3.CACHE_FOREVER if self._player is None: text = self.format_none color = self.py3.COLOR_BAD composite = [{ 'full_text': text, 'color': color, }] self._data = {} else: self._init_data() (text, color, cached_until) = self._get_text() self._control_states = self._get_control_states() buttons = self._get_response_buttons() composite = self.py3.build_composite(self.format, text, buttons) if (self._data.get('error_occurred') or current_player_id != self._player_details.get('id')): # Something went wrong or the player changed during our processing # This is usually due to something like a player being killed # whilst we are checking its details # Retry but limit the number of attempts self._tries += 1 if self._tries < 3: return self.mpris() # Max retries hit we need to output something composite = [{ 'full_text': 'Something went wrong', 'color': self.py3.COLOR_BAD, }] cached_until = self.py3.time_in(1) response = { 'cached_until': cached_until, 'color': color, 'composite': composite } # we are outputing so reset tries self._tries = 0 return response def on_click(self, event): """ Handles click events """ index = event['index'] button = event['button'] if not index: return if index not in self._control_states.keys(): if button == self.button_toggle: index = 'toggle' elif button == self.button_stop: index = 'stop' elif button == self.button_next: index = 'next' elif button == self.button_previous: index = 'previous' else: return elif button != 1: return control_state = self._control_states[index] if self._player and self._get_button_state(control_state): getattr(self._player, self._control_states[index]['action'])()
#!/usr/bin/python3 import os import sys import datetime import json import subprocess from time import sleep from pydbus import SessionBus from glob import glob BUS = SessionBus() LAYOUT = BUS.get(bus_name='org.way-cooler', object_path='/org/way_cooler/Layout') def main(): while True: layout = json.loads(LAYOUT.Debug()) workspaces = get_workspaces(layout) workspaces.sort() active_workspace = "" try: active_workspace = LAYOUT.ActiveWorkspace() except Exception: pass workspaces = " ".join(workspaces) workspaces = format_workspaces(layout, workspaces, active_workspace) funcs = [workspaces + "%{c}", lambda: get_time() + "%{r}", my_get_temp,
''' def Method1(self): global done done += 1 if done == 2: loop.quit() return "M1" def Method2(self): global done done += 1 if done == 2: loop.quit() return "M2" bus = SessionBus() with bus.publish("net.lew21.pydbus.tests.expose_multiface", TestObject()): remote = bus.get("net.lew21.pydbus.tests.expose_multiface") def t1_func(): print(remote.Method1()) print(remote.Method2()) t1 = Thread(None, t1_func) t1.daemon = True def handle_timeout(): print("ERROR: Timeout.") sys.exit(1)
class ScarlettListenerI(threading.Thread, _IdleObject): """ Attempt to take out all Gstreamer logic and put it in a class ouside the dbus server. Cancellable thread which uses gobject signals to return information to the GUI. """ __gsignals__ = SCARLETT_LISTENER_I_SIGNALS device = PS_DEVICE hmm = HMM_PATH lm = LM_PATH dic = DICT_PATH # __dr = None __instance = None MAX_FAILURES = 10 def __init__(self, name, config_manager, *args): threading.Thread.__init__(self) _IdleObject.__init__(self) self.running = False self.finished = False self.ready_sem = threading.Semaphore(SEMAPHORE_NUM) self.queue = queue.Queue(QUEUE_SIZE) # Load in config object, and set default device information self._config_manager = config_manager self._graphviz_debug_dir = self._config_manager.cfg["graphviz_debug_dir"] self._device = self._config_manager.cfg["pocketsphinx"]["device"] self._hmm = self._config_manager.cfg["pocketsphinx"]["hmm"] self._lm = self._config_manager.cfg["pocketsphinx"]["lm"] self._dic = self._config_manager.cfg["pocketsphinx"]["dict"] self._fwdflat = bool(self._config_manager.cfg["pocketsphinx"]["fwdflat"]) self._bestpath = bool(self._config_manager.cfg["pocketsphinx"]["bestpath"]) self._dsratio = int(self._config_manager.cfg["pocketsphinx"]["dsratio"]) self._maxhmmpf = int(self._config_manager.cfg["pocketsphinx"]["maxhmmpf"]) self._bestpath = bool(self._config_manager.cfg["pocketsphinx"]["bestpath"]) self._silprob = float(self._config_manager.cfg["pocketsphinx"]["silprob"]) self._wip = float(self._config_manager.cfg["pocketsphinx"]["wip"]) # dotfile setup self._dotfile_listener = os.path.join( self._graphviz_debug_dir, "generator-listener.dot" ) self._pngfile_listener = os.path.join( self._graphviz_debug_dir, "generator-listener-pipeline.png" ) # self._handler = DbusSignalHandler() # Get a dbus proxy and check if theres a service registered called 'org.scarlett.Listener' # if not, then we can skip all further processing. (The scarlett-os-mpris-dbus seems not to be running) # self.__dr = DBusRunner.get_instance() logger.info("Initializing ScarlettListenerI") # This wil get filled with an exception if opening fails. self.read_exc = None self.dot_exc = None self.cancelled = False self.name = name self.setName("{}".format(self.name)) self.pipelines_stack = [] self.elements_stack = [] self.gst_bus_stack = [] self._message = "This is the ScarlettListenerI" # TODO: When we're ready to unit test, config this back in!!!!! # self.config = scarlett_config.Config() self.config = None self.override_parse = "" self.failed = 0 self.kw_found = 0 self.debug = False self.create_dot = True self.terminate = False self.capsfilter_queue_overrun_handler_id = None self._cancel_signal_callback = None # source: https://github.com/ljmljz/xpra/blob/b32f748e0c29cdbfab836b3901c1e318ea142b33/src/xpra/sound/sound_pipeline.py # NOQA self.bus = None self.bus_message_element_handler_id = None self.bus_message_error_handler_id = None self.bus_message_eos_handler_id = None self.bus_message_state_changed_handler_id = None self.pipeline = None self.start_time = 0 self.state = "stopped" self.buffer_count = 0 self.byte_count = 0 self._status_ready = " ScarlettListener is ready" self._status_kw_match = " ScarlettListener caught a keyword match" self._status_cmd_match = " ScarlettListener caught a command match" self._status_stt_failed = " ScarlettListener hit Max STT failures" self._status_cmd_start = " ScarlettListener emitting start command" self._status_cmd_fin = " ScarlettListener Emitting Command run finish" self._status_cmd_cancel = " ScarlettListener cancel speech Recognition" if self.debug: # NOTE: For testing puposes, mainly when in public # so you dont have to keep yelling scarlett in front of strangers self.kw_to_find = ["yo", "hello", "man", "children"] else: # NOTE: Before we start worrying about the config class, lets hardcode what we care about # ADD ME BACK IN WHEN WE REALLY START UNIT TESTING # self.kw_to_find = self.config.get('scarlett', 'keywords') self.kw_to_find = ["scarlett", "SCARLETT"] if self.read_exc: # An error occurred before the stream became ready. self.close(True) raise self.read_exc # pylint: disable=raising-bad-type def scarlett_reset_listen(self): self.failed = 0 self.kw_found = 0 def on_cancel_listening(self, *args, **kwargs): logger.debug("Inside cancel_listening function") self.scarlett_reset_listen() logger.debug("self.failed = {}".format(self.failed)) logger.debug("self.keyword_identified = {}".format(self.kw_found)) def play(self): p = self.pipelines_stack[0] self.state = "active" self.running = True # GST_STATE_PAUSED is the state in which an element is ready to accept and handle data. # For most elements this state is the same as PLAYING. The only exception to this rule are sink elements. # Sink elements only accept one single buffer of data and then block. # At this point the pipeline is 'prerolled' and ready to render data immediately. p.set_state(Gst.State.PAUSED) # GST_STATE_PLAYING is the highest state that an element can be in. # For most elements this state is exactly the same as PAUSED, # they accept and process events and buffers with data. # Only sink elements need to differentiate between PAUSED and PLAYING state. # In PLAYING state, sink elements actually render incoming data, # e.g. output audio to a sound card or render video pictures to an image sink. ret = p.set_state(Gst.State.PLAYING) if ret == Gst.StateChangeReturn.FAILURE: logger.error("ERROR: Unable to set the pipeline to the playing state") # 8/8/2018 (Only enable this if we turn on debug mode) if os.environ.get("SCARLETT_DEBUG_MODE"): self.on_debug_activate() logger.debug("BEFORE: self.ready_sem.acquire()") self.ready_sem.acquire() logger.debug("AFTER: self.ready_sem.acquire()") logger.info("Press Ctrl+C to quit ...") def stop(self): p = self.pipelines_stack[0] self.state = "stopped" self.running = False # GST_STATE_NULL is the default state of an element. # In this state, it has not allocated any runtime resources, # it has not loaded any runtime libraries and it can obviously not handle data. p.set_state(Gst.State.NULL) def get_pocketsphinx_definition(self, override=False): r""" GST_DEBUG=2,pocketsphinx*:5 gst-launch-1.0 alsasrc device=plughw:CARD=Device,DEV=0 ! \ queue name=capsfilter_queue \ leaky=2 \ max-size-buffers=0 \ max-size-time=0 \ max-size-bytes=0 ! \ capsfilter caps='audio/x-raw,format=(string)S16LE,rate=(int)16000,channels=(int)1,layout=(string)interleaved' ! \ audioconvert ! \ audioresample ! \ pocketsphinx \ name=asr \ lm=~/dev/bossjones-github/scarlett_os/static/speech/lm/1473.lm \ dict=~/dev/bossjones-github/scarlett_os/static/speech/dict/1473.dic \ hmm=~/.virtualenvs/scarlett_os/share/pocketsphinx/model/en-us/en-us bestpath=true ! \ tee name=tee ! \ queue name=appsink_queue \ leaky=2 \ max-size-buffers=0 \ max-size-time=0 \ max-size-bytes=0 ! \ appsink caps='audio/x-raw,format=(string)S16LE,rate=(int)16000,channels=(int)1,layout=(string)interleaved' \ drop=false max-buffers=10 sync=false \ emit-signals=true tee. queue name=fakesink_queue \ leaky=2 \ max-size-buffers=0 \ max-size-time=0 \ max-size-bytes=0 ! \ fakesink sync=false """ logger.debug("Inside get_pocketsphinx_definition") if override: _gst_launch = override else: # TODO: Add audio levels, see the following # SOURCE: http://stackoverflow.com/questions/5686424/detecting-blowing-on-a-microphone-with-gstreamer-or-another-library _gst_launch = [ "alsasrc device=" + self.device, # source: https://github.com/walterbender/story/blob/master/grecord.py # without a buffer here, gstreamer struggles at the start of the # recording and then the A/V sync is bad for the whole video # (possibly a gstreamer/ALSA bug -- even if it gets caught up, it # should be able to resync without problem) # 'progressreport name=progressreport update-freq=1', # NOTE: comment this in when you want performance information "queue name=capsfilter_queue silent=false leaky=2 max-size-buffers=0 max-size-time=0 max-size-bytes=0", "capsfilter name=capsfilter caps=audio/x-raw,format=S16LE,channels=1,layout=interleaved", "audioconvert name=audioconvert", "audioresample name=audioresample", "identity name=ident", "pocketsphinx name=asr", "tee name=tee", "queue name=appsink_queue silent=false leaky=2 max-size-buffers=0 max-size-time=0 max-size-bytes=0", # caps=audio/x-raw,format=(string)S16LE,rate=(int)16000,channels=(int)1,layout=(string)interleaved # NOQA "appsink name=appsink drop=false max-buffers=10 sync=false emit-signals=true tee.", "queue leaky=2 name=fakesink_queue", "fakesink", ] return _gst_launch def cancel(self): """ Threads in python are not cancellable, so we implement our own cancellation logic """ self.cancelled = True @abort_on_exception def run(self, event=None): # TODO: WE NEED TO USE A THREADING EVENT OR A RLOCK HERE TO WAIT TILL DBUS SERVICE IS RUNNING TO CONNECT # TODO: SIGNALS TO THE DBUS PROXY METHODS WE WANT TO USE # TODO: lock.acquire() / event / condition # TODO: self.connect_to_dbus() # TODO: self.setup_dbus_callbacks_handlers() self._connect_to_dbus() self.init_gst() print("Running {}".format(str(self))) self.play() self.emit("playback-status-changed") self.emit("playing-changed") # FIXME: is this needed? # self.mainloop.run() def _connect_to_dbus(self): self.bus = SessionBus() self.dbus_proxy = self.bus.get( "org.scarlett", object_path="/org/scarlett/Listener" ) # NOQA self.dbus_proxy.emitConnectedToListener("ScarlettListener") time.sleep(2) logger.info("_connect_to_dbus") # TODO: Add a ss_cancel_signal.disconnect() function later ss_cancel_signal = self.bus.subscribe( sender=None, iface="org.scarlett.Listener", signal="ListenerCancelSignal", object="/org/scarlett/Listener", arg0=None, flags=0, signal_fired=self.on_cancel_listening, ) # NOTE: This function generates the dot file, checks that graphviz in installed and # then finally generates a png file, which it then displays def on_debug_activate(self): # FIXME: This needs to use dynamic paths, it's possible that we're having issues because of order of operations # FIXME: STATIC PATH 7/3/2018 # dotfile = ( # "/home/pi/dev/bossjones-github/scarlett_os/_debug/generator-listener.dot" # ) # pngfile = "/home/pi/dev/bossjones-github/scarlett_os/_debug/generator-listener-pipeline.png" # NOQA dotfile = self._dotfile_listener pngfile = self._pngfile_listener if os.access(dotfile, os.F_OK): os.remove(dotfile) if os.access(pngfile, os.F_OK): os.remove(pngfile) Gst.debug_bin_to_dot_file( self.pipelines_stack[0], Gst.DebugGraphDetails.ALL, "generator-listener" ) cmd = "/usr/bin/dot -Tpng -o {pngfile} {dotfile}".format( pngfile=pngfile, dotfile=dotfile ) os.system(cmd) def result(self, final_hyp): """Forward result signals on the bus to the main thread.""" logger.debug("Inside result function") logger.debug("final_hyp: {}".format(final_hyp)) pp.pprint(final_hyp) logger.debug("kw_to_find: {}".format(self.kw_to_find)) if final_hyp in self.kw_to_find and final_hyp != "": logger.debug("HYP-IS-SOMETHING: {}\n\n\n".format(final_hyp)) self.failed = 0 self.kw_found = 1 self.dbus_proxy.emitKeywordRecognizedSignal() # CHANGEME else: failed_temp = self.failed + 1 self.failed = failed_temp logger.debug("self.failed = {}".format(int(self.failed))) # failed > 10 if self.failed > 4: # reset pipline self.dbus_proxy.emitSttFailedSignal() # CHANGEME self.scarlett_reset_listen() def run_cmd(self, final_hyp): logger.debug("Inside run_cmd function") logger.debug("KEYWORD IDENTIFIED BABY") logger.debug("self.kw_found = {}".format(int(self.kw_found))) if final_hyp == "CANCEL": self.dbus_proxy.emitListenerCancelSignal() # CHANGEME self.on_cancel_listening() else: current_kw_identified = self.kw_found self.kw_found = current_kw_identified self.dbus_proxy.emitCommandRecognizedSignal(final_hyp) # CHANGEME logger.info("Command = {}".format(final_hyp)) logger.debug("AFTER run_cmd, self.kw_found = {}".format(int(self.kw_found))) def init_gst(self): logger.debug("Inside init_gst") self.start_time = time.time() pipeline = Gst.parse_launch(" ! ".join(self.get_pocketsphinx_definition())) logger.debug("After get_pocketsphinx_definition") # Add pipeline obj to stack we can pull from later self.pipelines_stack.append(pipeline) gst_bus = pipeline.get_bus() # gst_bus = pipeline.get_gst_bus() gst_bus.add_signal_watch() self.bus_message_element_handler_id = gst_bus.connect( "message::element", self._on_message ) self.bus_message_eos_handler_id = gst_bus.connect( "message::eos", self._on_message ) self.bus_message_error_handler_id = gst_bus.connect( "message::error", self._on_message ) self.bus_message_state_changed_handler_id = gst_bus.connect( "message::state-changed", self._on_state_changed ) # Add bus obj to stack we can pull from later self.gst_bus_stack.append(gst_bus) appsink = pipeline.get_by_name("appsink") appsink.set_property( "caps", Gst.Caps.from_string( "audio/x-raw,format=(string)S16LE,rate=(int)16000,channels=(int)1,layout=(string)interleaved" ), ) appsink.set_property("drop", False) appsink.set_property("max-buffers", BUFFER_SIZE) appsink.set_property("sync", False) # The callback to receive decoded data. appsink.set_property("emit-signals", True) appsink.connect("new-sample", self._new_sample) self.caps_handler = appsink.get_static_pad("sink").connect( "notify::caps", self._notify_caps ) self.elements_stack.append(appsink) # ************************************************************ # get gst pipeline element pocketsphinx and set properties - BEGIN # ************************************************************ pocketsphinx = pipeline.get_by_name("asr") # from scarlett_os.internal.debugger import dump # print("debug-2018-pocketsphinx - BEGIN") # dump(pocketsphinx.get_property('decoder')) # print("debug-2018-pocketsphinx - END") # print(pocketsphinx.list_properties()) if self._hmm: pocketsphinx.set_property("hmm", self._hmm) if self._lm: pocketsphinx.set_property("lm", self._lm) if self._dic: pocketsphinx.set_property("dict", self._dic) if self._fwdflat: pocketsphinx.set_property("fwdflat", self._fwdflat) if self._bestpath: pocketsphinx.set_property("bestpath", self._bestpath) if self._dsratio: pocketsphinx.set_property("dsratio", self._dsratio) if self._maxhmmpf: pocketsphinx.set_property("maxhmmpf", self._maxhmmpf) if self._bestpath: pocketsphinx.set_property("bestpath", self._bestpath) # if self._silprob: # pocketsphinx.set_property("silprob", self._silprob) # if self._wip: # pocketsphinx.set_property("wip", self._wip) # ************************************************************ # get gst pipeline element pocketsphinx and set properties - END # ************************************************************ # NOTE: Old way of setting pocketsphinx properties. 8/5/2018 # pocketsphinx.set_property( # "fwdflat", True # ) # Enable Flat Lexicon Search | Default: true # pocketsphinx.set_property( # "bestpath", True # ) # Enable Graph Search | Boolean. Default: true # pocketsphinx.set_property( # "dsratio", 1 # ) # Evaluate acoustic model every N frames | Integer. Range: 1 - 10 Default: 1 # pocketsphinx.set_property( # "maxhmmpf", 3000 # ) # Maximum number of HMMs searched per frame | Integer. Range: 1 - 100000 Default: 30000 # pocketsphinx.set_property( # "bestpath", True # ) # Enable Graph Search | Boolean. Default: true # pocketsphinx.set_property('maxwpf', -1) # # pocketsphinx.set_property('maxwpf', 20) # Maximum number of words # searched per frame | Range: 1 - 100000 Default: -1 self.elements_stack.append(pocketsphinx) capsfilter_queue = pipeline.get_by_name("capsfilter_queue") capsfilter_queue.set_property("leaky", True) # prefer fresh data capsfilter_queue.set_property("silent", False) capsfilter_queue.set_property("max-size-time", 0) # 0 seconds capsfilter_queue.set_property("max-size-buffers", 0) capsfilter_queue.set_property("max-size-bytes", 0) self.capsfilter_queue_overrun_handler_id = capsfilter_queue.connect( "overrun", self._log_queue_overrun ) # capsfilter_queue.connect('overrun', self._on_overrun) # capsfilter_queue.connect('underrun', self._on_underrun) # capsfilter_queue.connect('pushing', self._on_pushing) # capsfilter_queue.connect('running', self._on_running) self.elements_stack.append(capsfilter_queue) ident = pipeline.get_by_name("ident") # ident.connect('handoff', self._on_handoff) self.elements_stack.append(ident) logger.debug("After all self.elements_stack.append() calls") # Set up the queue for data and run the main thread. self.queue = queue.Queue(QUEUE_SIZE) self.thread = get_loop_thread() # NOTE: Disabled since we aren't connecting to handoff # def _on_handoff(self, element, buf): # logger.debug('buf:') # pp.pprint(buf) # pp.pprint(dir(buf)) # logger.debug("on_handoff - %d bytes".format(len(buf)) # if self.signed is None: # # only ever one caps struct on our buffers # struct = buf.get_caps().get_structure(0) # # I think these are always set too, but catch just in case # try: # self.signed = struct["signed"] # self.depth = struct["depth"] # self.rate = struct["rate"] # self.channels = struct["channels"] # except Exception: # logger.debug('on_handoff: missing caps') # pass # raw = str(buf) # # # print 'len(raw) =', len(raw) # # sm = 0 # for i in range(0, len(raw)): # sm += ord(raw[i]) # # print sm # FIXEME: Add somthing like analyse.py # SOURCE: https://github.com/jcupitt/huebert/blob/master/huebert/audio.py def _on_state_changed(self, bus, msg): states = msg.parse_state_changed() # To state is PLAYING if msg.src.get_name() == "pipeline0" and states[1] == 4: logger.info("Inside pipeline0 on _on_state_changed") logger.info("State: {}".format(states[1])) self.ready_sem.release() return False else: # logger.error('NOTHING RETURNED in _on_state_changed') logger.info("State: {}".format(states[1])) def _on_overrun(self, element): logging.debug("on_overrun") def _on_underrun(self, element): logging.debug("on_underrun") def _on_running(self, element): logging.debug("on_running") def _on_pushing(self, element): logging.debug("on_pushing") def _notify_caps(self, pad, args): """The callback for the sinkpad's "notify::caps" signal. """ # The sink has started to receive data, so the stream is ready. # This also is our opportunity to read information about the # stream. self.got_caps = True # Allow constructor to complete. self.ready_sem.release() _got_a_pad = False def _log_queue_overrun(self, queue): cbuffers = queue.get_property("current-level-buffers") cbytes = queue.get_property("current-level-bytes") ctime = queue.get_property("current-level-time") def _new_sample(self, sink): """The callback for appsink's "new-sample" signal. """ if self.running: # New data is available from the pipeline! Dump it into our # queue (or possibly block if we're full). buf = sink.emit("pull-sample").get_buffer() # IMPORTANT!!!!! # NOTE: I think this is causing a deadlock self.queue.put(buf.extract_dup(0, buf.get_size())) # "OK = 0. Data passing was ok."" return Gst.FlowReturn.OK def _on_message(self, bus, message): """The callback for GstBus's "message" signal (for two kinds of messages). """ # logger.debug("[_on_message](%s, %s)", bus, message) if not self.finished: struct = message.get_structure() if message.type == Gst.MessageType.EOS: # The file is done. Tell the consumer thread. self.queue.put(SENTINEL) if not self.got_caps: logger.error( "If the stream ends before _notify_caps was called, this is an invalid stream." ) # If the stream ends before _notify_caps was called, this # is an invalid file. self.read_exc = NoStreamError() self.ready_sem.release() elif struct and struct.get_name() == "pocketsphinx": # "final", G_TYPE_BOOLEAN, final, # SOURCE: https://github.com/cmusphinx/pocketsphinx/blob/1fdc9ccb637836d45d40956e745477a2bd3b470a/src/gst-plugin/gstpocketsphinx.c if struct["final"]: logger.info("confidence: {}".format(struct["confidence"])) logger.info("hypothesis: {}".format(struct["hypothesis"])) if self.kw_found == 1: # If keyword is set AND qualifier # then perform action self.run_cmd(struct["hypothesis"]) else: # If it's the main keyword, # set values wait for qualifier self.result(struct["hypothesis"]) elif message.type == Gst.MessageType.ERROR: gerror, debug = message.parse_error() pp.pprint(("gerror,debug:", gerror, debug)) if "not-linked" in debug: logger.error("not-linked") self.read_exc = NoStreamError() elif "No such device" in debug: logger.error("No such device") self.read_exc = NoStreamError() else: logger.info("FileReadError") pp.pprint( ("SOME FileReadError", bus, message, struct, struct.get_name()) ) self.read_exc = FileReadError(debug) self.ready_sem.release() # Cleanup. def close(self, force=False): """Close the file and clean up associated resources. Calling `close()` a second time has no effect. """ if self.running or force: self.running = False self.finished = True try: gst_bus = self.gst_bus_stack[0] except Exception: logger.error("Failed to get gst_bus from gst_bus_stack[0]") if gst_bus: gst_bus.remove_signal_watch() if self.bus_message_element_handler_id: gst_bus.disconnect(self.bus_message_element_handler_id) if self.bus_message_error_handler_id: gst_bus.disconnect(self.bus_message_error_handler_id) if self.bus_message_eos_handler_id: gst_bus.disconnect(self.bus_message_eos_handler_id) if self.bus_message_state_changed_handler_id: gst_bus.disconnect(self.bus_message_state_changed_handler_id) self.bus = None self.pipeline = None self.codec = None self.bitrate = -1 self.state = None # Unregister for signals, which we registered for above with # `add_signal_watch`. (Without this, GStreamer leaks file # descriptors.) logger.debug("BEFORE p = self.pipelines_stack[0]") p = self.pipelines_stack[0] p.get_bus().remove_signal_watch() logger.debug("AFTER p.get_bus().remove_signal_watch()") # Block spurious signals. appsink = self.elements_stack[0] appsink.get_static_pad("sink").disconnect(self.caps_handler) # Make space in the output queue to let the decoder thread # finish. (Otherwise, the thread blocks on its enqueue and # the interpreter hangs.) try: self.queue.get_nowait() except queue.Empty: pass # Halt the pipeline (closing file). self.stop() # Delete the pipeline object. This seems to be necessary on Python # 2, but not Python 3 for some reason: on 3.5, at least, the # pipeline gets dereferenced automatically. del p def __del__(self): self.close() def __exit__(self, exc_type, exc_val, exc_tb): self.close() return False
def __init__(self, bucket, loop, *args, **kargs): self.bucket = bucket self.loop = loop self.running = True self._stop = threading.Event() self.queue = Queue.Queue(10) # NOTE: enumerate req to iterate through tuple and find GVariant @trace def player_cb(*args, **kwargs): if SCARLETT_DEBUG: logger.debug("player_cb PrettyPrinter: ") pp = pprint.PrettyPrinter(indent=4) pp.pprint(args) for i, v in enumerate(args): if SCARLETT_DEBUG: logger.debug("Type v: {}".format(type(v))) logger.debug("Type i: {}".format(type(i))) if type(v) is gi.overrides.GLib.Variant: if SCARLETT_DEBUG: logger.debug( "THIS SHOULD BE A Tuple now: {}".format(v)) msg, scarlett_sound = v logger.warning(" msg: {}".format(msg)) logger.warning( " scarlett_sound: {}".format(scarlett_sound)) # NOTE: Create something like test_gdbus_player.ScarlettPlayer('pi-listening') # NOTE: test_gdbus_player.ScarlettPlayer # NOTE: self.bucket.put() # NOTE: ADD self.queue.put(v) # NOTE: enumerate req to iterate through tuple and find GVariant @trace def command_cb(*args, **kwargs): if SCARLETT_DEBUG: logger.debug("player_cb PrettyPrinter: ") pp = pprint.PrettyPrinter(indent=4) pp.pprint(args) for i, v in enumerate(args): if SCARLETT_DEBUG: logger.debug("Type v: {}".format(type(v))) logger.debug("Type i: {}".format(type(i))) if type(v) is gi.overrides.GLib.Variant: if SCARLETT_DEBUG: logger.debug( "THIS SHOULD BE A Tuple now: {}".format(v)) msg, scarlett_sound, command = v logger.warning(" msg: {}".format(msg)) logger.warning( " scarlett_sound: {}".format(scarlett_sound)) logger.warning(" command: {}".format(command)) # NOTE: Create something like test_gdbus_player.ScarlettPlayer('pi-listening') # NOTE: test_gdbus_player.ScarlettPlayer # NOTE: self.bucket.put() # NOTE: ADD self.queue.put(v) # with SessionBus() as bus: bus = SessionBus() ss = bus.get("org.scarlett", object_path='/org/scarlett/Listener') # SttFailedSignal / player_cb ss_failed_signal = bus.con.signal_subscribe(None, "org.scarlett.Listener", "SttFailedSignal", '/org/scarlett/Listener', None, 0, player_cb) # ListenerReadySignal / player_cb ss_rdy_signal = bus.con.signal_subscribe(None, "org.scarlett.Listener", "ListenerReadySignal", '/org/scarlett/Listener', None, 0, player_cb) # KeywordRecognizedSignal / player_cb ss_kw_rec_signal = bus.con.signal_subscribe(None, "org.scarlett.Listener", "KeywordRecognizedSignal", '/org/scarlett/Listener', None, 0, player_cb) # CommandRecognizedSignal /command_cb ss_cmd_rec_signal = bus.con.signal_subscribe(None, "org.scarlett.Listener", "CommandRecognizedSignal", '/org/scarlett/Listener', None, 0, command_cb) # ListenerCancelSignal / player_cb ss_cancel_signal = bus.con.signal_subscribe(None, "org.scarlett.Listener", "ListenerCancelSignal", '/org/scarlett/Listener', None, 0, player_cb) # NOTE: print dir(ss) # NOTE: # Quit mainloop # NOTE: self.quit = ss.quit() # NOTE: # let listener know when we connect to it # NOTE: self._tasker_connected = ss.emitConnectedToListener("{}".format( # NOTE: # self._tasker_connected(ScarlettTasker().__class__.__name__))) logger.debug("ss PrettyPrinter: ") pp = pprint.PrettyPrinter(indent=4) pp.pprint(ss)
if not chat[conv]["announce"]: return if conv in chat: send_me = nick + "--" if len(reason) > 0: send_me += " (" + reason + ")" for target_conv in iter(set(chat)-set([conv])): purple.PurpleConvChatSend(purple.PurpleConversationGetChatData(target_conv), send_me) debug_print(target_conv, send_me) # start main proc bus = SessionBus() purple = bus.get("im.pidgin.purple.PurpleService", "/im/pidgin/purple/PurpleObject") print ">>> Rainbow 🌈 Bridge for Libpurple/Finch/Pidgin <<<" for conv in purple.PurpleGetConversations(): name = purple.PurpleConversationGetName(conv) if name in bridge_me: chat[conv] = { "nick": purple.PurpleConvChatGetNick(purple.PurpleConversationGetChatData(conv)), "protocol": purple.PurpleAccountGetProtocolName(purple.PurpleConversationGetAccount(conv)), "announce": name not in dont_announce, } for conv in chat.keys(): print "<->", chat[conv]["nick"], "on", purple.PurpleConversationGetName(conv), "(" + str(conv) + ")", "using", chat[conv]["protocol"]
#!/usr/bin/env python # -*- coding: utf-8 -*- from flask import Flask from flask import request app = Flask(__name__) from pydbus import SessionBus bus = SessionBus() try: player = bus.get("github.zhangn1985.dbplay") except: from playthread import Mpvplayer player = Mpvplayer() player.start() import json import types from ykdl.common import url_to_module @app.route('/play', methods=['POST', 'GET']) def play(): if request.method == 'POST': url = request.form['url'] try: islist = request.form['list'] islist = islist == "True" except: islist = False m,u = url_to_module(url)
from __future__ import print_function from pydbus import SessionBus from gi.repository import GLib import subprocess from time import sleep loop = GLib.MainLoop() subprocess.Popen("gnome-music") sleep(5) print("Waiting for GNOME Music to start...") b = SessionBus() m = b.get("org.mpris.MediaPlayer2.GnomeMusic", "/org/mpris/MediaPlayer2") m.PropertiesChanged.connect(print) m.ActivatePlaylist(m.GetPlaylists(0, 5, "Alphabetical", 0)[0][0]) m.Play() sleep(1) assert(m.PlaybackStatus == "Playing") m.Pause() assert(m.PlaybackStatus == "Paused") m.Play() assert(m.PlaybackStatus == "Playing") t = m.Metadata["xesam:title"]
def post_config_hook(self): self._dbus = SessionBus() self._start_listener()
def __init__(self, *args): _IdleObject.__init__(self) self.bucket = bucket = Queue.Queue() # NOQA self.loop = GLib.MainLoop() self.hello = None # with SessionBus() as bus: bus = SessionBus() ss = bus.get("org.scarlett", object_path='/org/scarlett/Listener') # NOQA # # SttFailedSignal / player_cb # ss_failed_signal = bus.con.signal_subscribe(None, # NOQA # "org.scarlett.Listener", # "SttFailedSignal", # '/org/scarlett/Listener', # None, # 0, # player_cb) ss_failed_signal = ss.SttFailedSignal.connect(player_cb) # # ListenerReadySignal / player_cb # ss_rdy_signal = bus.con.signal_subscribe(None, # NOQA # "org.scarlett.Listener", # "ListenerReadySignal", # '/org/scarlett/Listener', # None, # 0, # player_cb) ss_rdy_signal = ss.ListenerReadySignal.connect(player_cb) # # KeywordRecognizedSignal / player_cb # ss_kw_rec_signal = bus.con.signal_subscribe(None, # NOQA # "org.scarlett.Listener", # "KeywordRecognizedSignal", # '/org/scarlett/Listener', # None, # 0, # player_cb) ss_kw_rec_signal = ss.KeywordRecognizedSignal.connect(player_cb) # # CommandRecognizedSignal /command_cb # ss_cmd_rec_signal = bus.con.signal_subscribe(None, # NOQA # "org.scarlett.Listener", # "CommandRecognizedSignal", # '/org/scarlett/Listener', # None, # 0, # command_cb) ss_cmd_rec_signal = ss.CommandRecognizedSignal.connect(command_cb) # # ListenerCancelSignal / player_cb # # signal_subscribe (sender, interface_name, member, object_path, arg0, flags, callback, *user_data) # ss_cancel_signal = bus.con.signal_subscribe(None, # NOQA # "org.scarlett.Listener", # "ListenerCancelSignal", # '/org/scarlett/Listener', # None, # 0, # player_cb) ss_cancel_signal = ss.ListenerCancelSignal.connect(player_cb) ss.emitConnectedToListener('ScarlettTasker') # THE ACTUAL THREAD BIT self.manager = FooThreadManager(3) try: print "ScarlettTasker Thread Started", self self.loop.run() except Exception: ss_failed_signal.disconnect() ss_rdy_signal.disconnect() ss_kw_rec_signal.disconnect() ss_cmd_rec_signal.disconnect() ss_cancel_signal.disconnect() self.bucket.put(sys.exc_info()) raise
if type(result) is list: result = tuple(result) elif not type(result) is tuple: result = (result,) invocation.return_value(GLib.Variant(self.method_outargs[method_name], result)) class Foo(Server): ''' <node> <interface name='net.lvht.Foo1'> <method name='HelloWorld'> <arg type='s' name='a' direction='in'/> <arg type='i' name='b' direction='in'/> <arg type='s' name='response' direction='out'/> </method> </interface> </node> ''' def HelloWorld(self, a, b): return a + str(b) if __name__ == '__main__': from pydbus import SessionBus bus = SessionBus() bus.own_name(name = 'net.lvht') foo = Foo(bus=bus.con, path='/net/lvht/Foo') foo.run()
def command_cb(*args, **kwargs): if SCARLETT_DEBUG: logger.debug("command_cb PrettyPrinter: ") pp = pprint.PrettyPrinter(indent=4) pp.pprint(args) # MAR 13 2016 logger.debug("command_cb kwargs") print_keyword_args(**kwargs) # (con=<DBusConnection object at 0x7f3fba21f0f0 (GDBusConnection at 0x2ede000)>, # sender=':1.0', # object='/org/scarlett/Listener', # iface='org.scarlett.Listener', # signal='CommandRecognizedSignal', # params=GLib.Variant('(sss)', (' ScarlettListener caugh...ommand match', 'pi-response', 'what time is it'))) # NOTE: THIS IS WHAT FIXED THE GENERATOR NONSENSE # source: https://www.python.org/dev/peps/pep-0343/ def player_generator_func(): for path in wavefile: path = os.path.abspath(os.path.expanduser(path)) yield True print("for path in wavefile") p = generator_player.ScarlettPlayer(path, False) while True: try: yield p.next() finally: time.sleep(p.duration) p.close(force=True) yield False def run_player(function): gen = function() GObject.idle_add(lambda: next(gen, False), priority=GLib.PRIORITY_HIGH) def speaker_generator_func(): for scarlett_text in tts_list: yield True print("scarlett_text in tts_list") _wavepath = "/home/pi/dev/bossjones-github/scarlett-dbus-poc/espeak_tmp.wav" s = generator_speaker.ScarlettSpeaker(text_to_speak=scarlett_text, wavpath=_wavepath, skip_player=True) p = generator_player.ScarlettPlayer(_wavepath, False) logger.error("Duration: p.duration: {}".format(p.duration)) while True: try: yield p.next() finally: time.sleep(p.duration) p.close(force=True) s.close(force=True) yield False def run_speaker(function): gen = function() GObject.idle_add(lambda: next(gen, False), priority=GLib.PRIORITY_HIGH) for i, v in enumerate(args): if SCARLETT_DEBUG: logger.debug("Type v: {}".format(type(v))) logger.debug("Type i: {}".format(type(i))) if isinstance(v, tuple): if SCARLETT_DEBUG: logger.debug( "THIS SHOULD BE A Tuple now: {}".format(v)) msg, scarlett_sound, command = v logger.warning(" msg: {}".format(msg)) logger.warning( " scarlett_sound: {}".format(scarlett_sound)) logger.warning(" command: {}".format(command)) # 1. play sound first wavefile = SoundType.get_path(scarlett_sound) run_player_result = run_player(player_generator_func) # 2. Perform command command_run_results = generator_commands.Command.check_cmd(command_tuple=v) # 3. Verify it is not a command NO_OP if command_run_results == '__SCARLETT_NO_OP__': logger.error("__SCARLETT_NO_OP__") return False # 4. Scarlett Speaks tts_list = SpeakerType.speaker_to_array(command_run_results) run_speaker_result = run_speaker(speaker_generator_func) # 5. Emit signal to reset keyword match ( need to implement this ) bus = SessionBus() ss = bus.get("org.scarlett", object_path='/org/scarlett/Listener') # NOQA time.sleep(1) ss.emitListenerCancelSignal() # 6. Finished call back else: logger.debug("THIS IS NOT A GLib.Variant: {} - TYPE {}".format(v, type(v)))
class PanCtl: bus = attr.ib(init=False) pan_bus = attr.ib(init=False) ctl = attr.ib(init=False) devices = attr.ib(init=False) completer = attr.ib(init=False) own_message_ids = attr.ib(init=False) command_help = { "help": "Display help about commands.", "list-servers": ( "List the configured homeservers and pan users on each homeserver." ), "list-devices": ( "List the devices of a user that are known to the " "pan-user." ), "start-verification": ( "Start an interactive key verification between " "the given pan-user and user." ), "accept-verification": ( "Accept an interactive key verification that " "the given user has started with our given " "pan-user." ), "cancel-verification": ( "Cancel an interactive key verification " "between the given pan-user and user." ), "confirm-verification": ( "Confirm that the short authentication " "string of the interactive key verification " "with the given pan-user and user is " "matching." ), "verify-device": ("Manually mark the given device as verified."), "unverify-device": ( "Mark a previously verified device of the given user as unverified." ), "blacklist-device": ( "Manually mark the given device of the given user as blacklisted." ), "unblacklist-device": ( "Mark a previously blacklisted device of the " "given user as unblacklisted." ), "send-anyways": ( "Send a room message despite having unverified " "devices in the room and mark the devices as " "ignored." ), "cancel-sending": ( "Cancel the send of a room message in a room that " "contains unverified devices" ), "import-keys": ( "Import end-to-end encryption keys from the given " "file for the given pan-user." ), "export-keys": ( "Export end-to-end encryption keys to the given file " "for the given pan-user." ), "continue-keyshare": ( "Export end-to-end encryption keys to the given file " "for the given pan-user." ), "cancel-keyshare": ( "Export end-to-end encryption keys to the given file " "for the given pan-user." ), } commands = list(command_help.keys()) def __attrs_post_init__(self): self.bus = SessionBus() self.pan_bus = self.bus.get("org.pantalaimon1") self.ctl = self.pan_bus["org.pantalaimon1.control"] self.devices = self.pan_bus["org.pantalaimon1.devices"] self.own_message_ids = [] self.ctl.Response.connect(self.show_response) self.ctl.UnverifiedDevices.connect(self.unverified_devices) self.completer = PanCompleter(self.commands, self.ctl, self.devices) self.devices.VerificationInvite.connect(self.show_sas_invite) self.devices.VerificationString.connect(self.show_sas) self.devices.VerificationDone.connect(self.sas_done) self.devices.KeyRequest.connect(self.show_key_request) self.devices.KeyRequestCancel.connect(self.show_key_request_cancel) def show_help(self, command): print(self.command_help[command]) def unverified_devices(self, pan_user, room_id, display_name): self.completer.rooms[pan_user].add(room_id) print( f"Error sending message for user {pan_user}, " f"there are unverified devices in the room {display_name} " f"({room_id}).\nUse the send-anyways or cancel-sending commands " f"to ignore the devices or cancel the sending." ) def show_response(self, response_id, pan_user, message): if response_id not in self.own_message_ids: return self.own_message_ids.remove(response_id) print(message["message"]) def show_key_request(self, pan_user, user_id, device_id, request_id): print( f"{user_id} has requested room keys from our pan " f"user {pan_user}, but the requesting device " f"{device_id} is unverified\n" f"After verifying the device accept the key share request with " f"the continue-keyshare, alternatively cancel the " f"request with the cancel-keyshare command." ) def show_key_request_cancel(self, pan_user, user_id, device_id, request_id): print( f"{user_id} via {device_id} has " f"canceled the room key request from our pan user " f"{pan_user}." ) def sas_done(self, pan_user, user_id, device_id, _): print( f"Device {device_id} of user {user_id}" f" succesfully verified for pan user {pan_user}." ) def show_sas_invite(self, pan_user, user_id, device_id, _): print( f"{user_id} has started an interactive device " f"verification for his device {device_id} with pan user " f"{pan_user}\n" f"Accept the invitation with the accept-verification command." ) # The emoji printing logic was taken from weechat-matrix and was written by # dkasak. def show_sas(self, pan_user, user_id, device_id, _, emoji): emojis = [x[0] for x in emoji] descriptions = [x[1] for x in emoji] centered_width = 12 def center_emoji(emoji, width): # Assume each emoji has width 2 emoji_width = 2 # These are emojis that need VARIATION-SELECTOR-16 (U+FE0F) so # that they are rendered with coloured glyphs. For these, we # need to add an extra space after them so that they are # rendered properly in weechat. variation_selector_emojis = ["☁️", "❤️", "☂️", "✏️", "✂️", "☎️", "✈️"] if emoji in variation_selector_emojis: emoji += " " # This is a trick to account for the fact that emojis are wider # than other monospace characters. placeholder = "." * emoji_width return placeholder.center(width).replace(placeholder, emoji) emoji_str = "".join(center_emoji(e, centered_width) for e in emojis) desc = "".join(d.center(centered_width) for d in descriptions) short_string = "\n".join([emoji_str, desc]) print( f"Short authentication string for pan " f"user {pan_user} from {user_id} via " f"{device_id}:\n{short_string}" ) def list_servers(self): """List the daemons users.""" servers = self.ctl.ListServers() print("pantalaimon servers:") for server, server_users in servers.items(): server_c = get_color(server) print_formatted_text(HTML(f" - Name: <{server_c}>{server}</{server_c}>")) user_list = [] for user, device in server_users: user_c = get_color(user) device_c = get_color(device) user_list.append( f" - <{user_c}>{user}</{user_c}> " f"<{device_c}>{device}</{device_c}>" ) if user_list: print(f" - Pan users:") user_string = "\n".join(user_list) print_formatted_text(HTML(user_string)) def list_devices(self, args): devices = self.devices.ListUserDevices(args.pan_user, args.user_id) print_formatted_text(HTML(f"Devices for user <b>{args.user_id}</b>:")) for device in devices: if device["trust_state"] == "verified": trust_state = f"<ansigreen>Verified</ansigreen>" elif device["trust_state"] == "blacklisted": trust_state = f"<ansired>Blacklisted</ansired>" elif device["trust_state"] == "ignored": trust_state = f"Ignored" else: trust_state = "Unset" key = partition_key(device["ed25519"]) color = get_color(device["device_id"]) print_formatted_text( HTML( f" - Display name: " f"{device['device_display_name']}\n" f" - Device id: " f"<{color}>{device['device_id']}</{color}>\n" f" - Device key: " f"<ansiyellow>{key}</ansiyellow>\n" f" - Trust state: " f"{trust_state}" ) ) async def loop(self): """Event loop for panctl.""" promptsession = PromptSession("panctl> ", completer=self.completer) while True: with patch_stdout(): try: result = await promptsession.prompt(async_=True) except EOFError: break if not result: continue parser = PanctlParser(self.commands) try: args = parser.parse_args(result.split()) except ParseError: continue command = args.subcommand if command == "list-servers": self.list_servers() if command == "help": self.show_help(args.command) elif command == "import-keys": self.own_message_ids.append( self.ctl.ImportKeys(args.pan_user, args.path, args.passphrase) ) elif command == "export-keys": self.own_message_ids.append( self.ctl.ExportKeys(args.pan_user, args.path, args.passphrase) ) elif command == "send-anyways": self.own_message_ids.append( self.ctl.SendAnyways(args.pan_user, args.room_id) ) elif command == "cancel-sending": self.own_message_ids.append( self.ctl.CancelSending(args.pan_user, args.room_id) ) elif command == "list-devices": self.list_devices(args) elif command == "verify-device": self.own_message_ids.append( self.devices.Verify(args.pan_user, args.user_id, args.device_id) ) elif command == "unverify-device": self.own_message_ids.append( self.devices.Unverify(args.pan_user, args.user_id, args.device_id) ) elif command == "blacklist-device": self.own_message_ids.append( self.devices.Blacklist(args.pan_user, args.user_id, args.device_id) ) elif command == "unblacklist-device": self.own_message_ids.append( self.devices.Unblacklist( args.pan_user, args.user_id, args.device_id ) ) elif command == "start-verification": self.own_message_ids.append( self.devices.StartKeyVerification( args.pan_user, args.user_id, args.device_id ) ) elif command == "cancel-verification": self.own_message_ids.append( self.devices.CancelKeyVerification( args.pan_user, args.user_id, args.device_id ) ) elif command == "accept-verification": self.own_message_ids.append( self.devices.AcceptKeyVerification( args.pan_user, args.user_id, args.device_id ) ) elif command == "confirm-verification": self.own_message_ids.append( self.devices.ConfirmKeyVerification( args.pan_user, args.user_id, args.device_id ) ) elif command == "continue-keyshare": self.own_message_ids.append( self.devices.ContinueKeyShare( args.pan_user, args.user_id, args.device_id ) ) elif command == "cancel-keyshare": self.own_message_ids.append( self.devices.CancelKeyShare( args.pan_user, args.user_id, args.device_id ) )
from playthread import Mpvplayer loop = GLib.MainLoop() player = Mpvplayer() player.start() class DBUSPlayerService(object): """ <node> <interface name='github.zhangn1985.dbplay'> <method name='play'> <arg type='s' name='playinfo' direction='in'/> </method> <method name='stop'/> <method name='exit'/> </interface> </node> """ def play(self, playinfo): player.play(playinfo) def stop(self): player.stop() def exit(self): player.exit() loop.quit() bus = SessionBus() bus.publish("github.zhangn1985.dbplay", DBUSPlayerService()) loop.run()
def Progress(self, value): self._progress = value self.PropertiesChanged(Installer.interface, {'Progress': self.Progress}, []) @property def LastError(self): return self._last_error @LastError.setter def LastError(self, value): self._last_error = value self.PropertiesChanged(Installer.interface, {'LastError': self.LastError}, []) if __name__ == '__main__': import argparse from pydbus import SessionBus parser = argparse.ArgumentParser() parser.add_argument('bundle', help='Expected RAUC bundle') parser.add_argument('--completed-code', type=int, default=0, help='Code to emit as D-Bus Completed signal') args = parser.parse_args() loop = GLib.MainLoop() bus = SessionBus() installer = Installer(args.bundle, args.completed_code) with bus.publish('de.pengutronix.rauc', ('/', installer)): print('Interface published') loop.run()
#!/usr/bin/env python # Based on http://stackoverflow.com/questions/22390064/use-dbus-to-just-send-a-message-in-python # Python script to call the methods of the DBUS Test Server from pydbus import SessionBus #get the session bus bus = SessionBus() #get the object the_object = bus.get("net.lew21.pydbus.ClientServerExample") #call the methods and print the results reply = the_object.Hello() print(reply) reply = the_object.EchoString("test 123") print(reply) the_object.Quit()
from pydbus import SessionBus bus = SessionBus() sm = bus.get("com.HACGI.convergence", "/com/HACGI/convergence/ServiceManager") def cb_signal_sm_service_changed(s_type, service_bus_name, service_obj_path, change_type, new_type): if change_type == "register": print(s_type, service_bus_name, service_obj_path, change_type, new_type) service_type = bus.get(service_bus_name, service_obj_path) print(service_type.ServiceName) print(service_type.getAllMethodNamesFromInterface("range_selector")) print(service_type.getAllMethodNamesFromInterface("switch_interface")) import json arg_obj = {'args': (), 'kwargs': {}} arg_json = json.dumps(arg_obj) service_type.CallControlInterface('switch_interface', "on", arg_json) sm.ServicesChanged.connect(cb_signal_sm_service_changed) from gi.repository import GLib loop = GLib.MainLoop() loop.run()
""" <node> <interface name='net.lew21.pydbus.ClientServerExample'> <method name='Hello'> <arg type='s' name='response' direction='out'/> </method> <method name='EchoString'> <arg type='s' name='a' direction='in'/> <arg type='s' name='response' direction='out'/> </method> <method name='Quit'/> </interface> </node> """ def Hello(self): """returns the string 'Hello, World!'""" return "Hello, World!" def EchoString(self, s): """returns whatever is passed to it""" return s def Quit(self): """removes this object from the DBUS connection and exits""" loop.quit() bus = SessionBus() bus.publish("net.lew21.pydbus.ClientServerExample", MyDBUSService()) loop.run()