def Metadata(self) -> Metadata: # prefer adapter's metadata to building our own metadata: DbusMetadata = self._dbus_metadata() if metadata: return metadata # build metadata if no metadata supplied by adapter self.log_trace(f"Building {self.INTERFACE}.Metadata") track = self.adapter.get_current_track() stream_title = self.adapter.get_stream_title() if track is None: return DEFAULT_METADATA track_id = track.track_id res = {"mpris:trackid": Variant("o", track_id)} if track.length: res["mpris:length"] = Variant("x", track.length) if track.uri: res["xesam:url"] = Variant("s", track.uri) if stream_title or track.name: res["xesam:title"] = Variant("s", stream_title or track.name) if track.artists: artists = list(track.artists) artists.sort(key=lambda a: a.name or "") res["xesam:artist"] = Variant("as", [a.name for a in artists if a.name]) if track.album and track.album.name: res["xesam:album"] = Variant("s", track.album.name) if track.album and track.album.artists: artists = list(track.album.artists) artists.sort(key=lambda a: a.name or "") res["xesam:albumArtist"] = Variant( "as", [a.name for a in artists if a.name] ) art_url = self._get_art_url(track) if art_url: res["mpris:artUrl"] = Variant("s", art_url) if track.disc_no: res["xesam:discNumber"] = Variant("i", track.disc_no) if track.track_no: res["xesam:trackNumber"] = Variant("i", track.track_no) return res
def get_variant(type_hint, value): """Return a variant data type. The type of a variant is specified with a type hint. Example: .. code-block:: python v1 = get_variant(Bool, True) v2 = get_variant(List[Int], [1,2,3]) :param type_hint: a type hint or a type string :param value: a value of the variant :return: an instance of Variant """ if type(type_hint) == str: type_string = type_hint else: type_string = get_dbus_type(type_hint) if value is None: raise TypeError("Invalid DBus value 'None'.") return Variant(type_string, value)
def do_activate(self): self.shell = self.object self.__action = Gio.SimpleAction(name='open') self.__action.connect('activate', self.apply_command) app = Gio.Application.get_default() app.add_action(self.__action) # Receive fourth submenu menu = self.shell.props.application.get_menubar() assert menu.get_n_items() > 3, 'But I need fourth submenu' it = menu.iterate_item_links(3) it.next() self.menu = it.get_value() item = Gio.MenuItem() if locale.getlocale()[0] == 'ru_RU': item.set_label("Открыть...") else: item.set_label(_("Open...")) item.set_detailed_action('app.open') item.set_attribute_value('accel', Variant('s', '<Ctrl>L')) self.menu.append_item(item) app.add_plugin_menu_item('edit', 'open', item) app.add_plugin_menu_item('browser-popup', 'open', item) app.add_plugin_menu_item('playlist-popup', 'open', item) app.add_plugin_menu_item('queue-popup', 'open', item)
def get_source_data(self): if self.source: views = self.source.get_property_views() browser_values_list = [] for view in views: browser_values_list.append(view.get_selection()) self.browser_values_list = Variant('aas', browser_values_list) self.settings.set_value(KEY_BROWSER_VALUES, self.browser_values_list)
def __call__( self, instance, call_done_cb, call_error_cb, user_data, *args, **kwargs ): argdiff = len(args) - len(self._inargs) if argdiff != 0: dbg_args = { "instance": instance, "call_done_cb": call_done_cb, "call_error_cb": call_error_cb, "user_data": user_data, "args": args, "kwargs": kwargs, } if argdiff < 0: raise TypeError( self.__qualname__ + " missing {} required positional argument(s), expected: {}, given: {}".format( -argdiff, len(self._inargs), dbg_args ) ) elif argdiff > 0: raise TypeError( self.__qualname__ + " takes {} positional argument(s) but {} was/were given: {}".format( len(self._inargs), len(args), dbg_args ) ) timeout = kwargs.get("timeout", None) def done_cb(obj, res, data): try: ret = obj.call_finish(res) if call_done_cb: call_done_cb(instance, ret, data) except Exception as e: if call_error_cb: call_error_cb(instance, e, data) ret = instance._bus.con.call( instance._bus_name, instance._path, self._iface_name, self.__name__[0 : -len("Async")], Variant(self._sinargs, args), VariantType.new(self._soutargs), 0, timeout_to_glib(timeout), None, done_cb, user_data, ) return ret
def Metadata(self): self.log_trace("Getting %s.Metadata", self.INTERFACE) current_tl_track = self.core.playback.get_current_tl_track().get() stream_title = self.core.playback.get_stream_title().get() if current_tl_track is None: return {} else: (tlid, track) = current_tl_track track_id = get_track_id(tlid) res = {"mpris:trackid": Variant("o", track_id)} if track.length: res["mpris:length"] = Variant("x", track.length * 1000) if track.uri: res["xesam:url"] = Variant("s", track.uri) if stream_title or track.name: res["xesam:title"] = Variant("s", stream_title or track.name) if track.artists: artists = list(track.artists) artists.sort(key=lambda a: a.name or "") res["xesam:artist"] = Variant( "as", [a.name for a in artists if a.name]) if track.album and track.album.name: res["xesam:album"] = Variant("s", track.album.name) if track.album and track.album.artists: artists = list(track.album.artists) artists.sort(key=lambda a: a.name or "") res["xesam:albumArtist"] = Variant( "as", [a.name for a in artists if a.name]) art_url = self._get_art_url(track) if art_url: res["mpris:artUrl"] = Variant("s", art_url) if track.disc_no: res["xesam:discNumber"] = Variant("i", track.disc_no) if track.track_no: res["xesam:trackNumber"] = Variant("i", track.track_no) return res
def do_deactivate(self): self.first_run = True self.settings.set_string('playlist', self.playlist) self.settings.set_string('source', self.source_name) if self.location: self.settings.set_string(KEY_LOCATION, self.location) self.settings.set_uint(KEY_PLAYBACK_TIME, self.playback_time) self.settings.set_boolean(KEY_PLAY_STATE, self.play_state) if self.source: views = self.source.get_property_views() browser_values_list = [] for view in views: browser_values_list.append(view.get_selection()) self.browser_values_list = Variant('aas', browser_values_list) self.settings.set_value(KEY_BROWSER_VALUES, self.browser_values_list)
def save_rhythm(self, pb_time=None): """ This actually saves info into gsettings :param pb_time: :return: """ if self.location: pb_time = pb_time is None and self.playback_time or pb_time is None self.settings.set_uint(KEY_PLAYBACK_TIME, pb_time) self.settings.set_string(KEY_LOCATION, self.location) #logger.debug("last location %s" % self.location) self.settings.set_boolean(KEY_PLAY_STATE, self.play_state) if self.source: views = self.source.get_property_views() browser_values_list = [] for view in views: browser_values_list.append(view.get_selection()) self.browser_values_list = Variant('aas', browser_values_list) self.settings.set_value(KEY_BROWSER_VALUES, self.browser_values_list)
def get_variant(type_hint, value): """Return a variant data type. The type of a variant is specified with a type hint. Example: v1 = get_variant(Bool, True) v2 = get_variant(List[Int], [1,2,3]) :param type_hint: a type hint or a type string :param value: a value of the variant :return: an instance of Variant """ if type(type_hint) == str: type_string = type_hint else: type_string = get_dbus_type(type_hint) return Variant(type_string, value)
async def on_workspace_focus(i3, event): """Show the appfinder when an empty workspace receives focus""" # Close any open appfinder window await i3.command('[class="Xfce4-appfinder"] kill') # Do nothing if this workspace isn't empty if event.current.focus: return if event.current.num in WORKSPACE_CATEGORIES: # Switch appfinder category to the one configured for this workspace category = Variant("s", WORKSPACE_CATEGORIES[event.current.num]) xfconf.SetProperty("xfce4-appfinder", "/last/category", category) try: # Open a new appfinder window in the new category bus.get("org.xfce.Appfinder").OpenWindow(True, 'such_fast') except: # The xfce4-appfinder service isn't running. Start it up. await i3.command("exec --no-startup-id xfce4-appfinder")
def on_language_changed(self, spellchecker, language): action, go = self.get_action_owner() if go: action_target = Variant("s", language) go.activate_action(action, action_target)
def create_stateful_action(self, name, _type, default_value, method): action = SimpleAction.new_stateful(name, VariantType.new(_type), Variant(_type, default_value)) action.connect("change-state", method) self.add_action(action)
def dbus_prepare(obj, variant: bool = False, camel_keys: bool = False) -> tuple: """ Recursively walks obj and builds a D-Bus signature by inspecting types. Variant types are created as necessary, and the returned obj may have changed. :param obj: An arbitrary primitive or container type :param variant: Force wrapping contained objects with variants :param camel_keys: Convert dict keys to CamelCase """ sig = '' use_variant = variant try: if isinstance(obj, Variant): sig = 'v' elif isinstance(obj, bool): sig = 'b' elif isinstance(obj, str): sig = 's' elif isinstance(obj, int): if obj < pow(2, 16): sig = 'n' elif obj < pow(2, 32): sig = 'i' else: sig = 'x' elif isinstance(obj, float): sig = 'd' elif isinstance(obj, Color): sig = 's' obj = obj.html elif isinstance(obj, TraitType): obj, sig = dbus_prepare(trait_as_dict(obj), variant=True) elif isinstance(obj, HasTraits): obj, sig = dbus_prepare(class_traits_as_dict(obj), variant=True) elif hasattr(obj, '_asdict') and hasattr(obj, '_field_types'): # typing.NamedTuple obj, sig = dbus_prepare(obj._asdict(), variant=True) elif isinstance(obj, type) and issubclass(obj, enum.Enum): # top level enum, tuple of string keys obj = tuple(obj.__members__.keys()) sig = '(%s)' % ('s' * len(obj)) elif isinstance(obj, enum.Enum): obj = obj.name sig = 's' elif isinstance(obj, np.ndarray): dtype = obj.dtype.kind if dtype == 'f': dtype = 'd' sig = 'a' * obj.ndim + dtype obj = obj.tolist() elif isinstance(obj, tuple): tmp = [] sig = '(' for item in obj: if item is None and use_variant: continue # struct of all items r_obj, r_sig = dbus_prepare(item) if r_obj is None: continue sig += r_sig tmp.append(r_obj) if len(tmp) > 0: sig += ')' obj = tuple(tmp) else: sig = '' obj = None elif isinstance(obj, list): tmp = [] sig = 'a' is_variant = use_variant or _check_variance(obj) for item in obj: if item is None and is_variant: continue r_obj, r_sig = dbus_prepare(item, variant=is_variant) if r_obj is None: continue tmp.append(r_obj) if is_variant: sig += 'v' else: sig += dbus_prepare(tmp[0])[1] obj = tmp elif isinstance(obj, (dict, frozendict)): if isinstance(obj, frozendict): tmp = {} else: tmp = obj.__class__() sig = 'a{s' vals = [x for x in obj.values() if x is not None] is_variant = use_variant or _check_variance(vals) for k, v in obj.items(): if v is None: continue r_obj, r_sig = dbus_prepare(v) if r_obj is None: continue if camel_keys: k = snake_to_camel(k) if is_variant: tmp[k] = Variant(r_sig, r_obj) else: tmp[k] = r_obj if is_variant: sig += 'v' else: sig += dbus_prepare(vals[0])[1] obj = tmp sig += '}' elif isinstance(obj, type): obj = obj.__name__ sig = 's' except Exception as err: logger.exception('obj: %s sig: %s variant: %s', obj, sig, variant, exc_info=err) raise return obj, sig
def test_python_to_dbus_translations(self): from pydbus.translator import PydbusCPythonTranslator c = PydbusCPythonTranslator(True, 'pydbus.unittest', unit_test_dictname='pydbus_python_to_dbus') argspec = c.translate('who.knows.what', 'testkey', (1, 4, 100, 'never see it', 'no changes'), 0, False, 'uui', None, None) self.assertEqual(argspec[0], 1) self.assertEqual(argspec[1], 4) self.assertEqual(argspec[3], 'never see it') argspec = c.translate('pydbus.unittest', 'leave_me_alone', (1, 4, 100, 100000), 0, False, 'uui', None, None) self.assertEqual(argspec[0], 1) self.assertEqual(argspec[1], 4) argspec = c.translate( 'pydbus.unittest', 'testkey', ('value_should_be_one', 'Test Case Matching on 4', 'value should be thirty', (1, 2, 3, "won't see me"), 'no changes', ('bit 1 off', 'bit 2 on', 'bit 0 on'), { 'bit 1 off': True, 'bit 2 on': True, 'bit 0 on': True }), 0, False, 'uiussii', None, None) self.assertEqual(argspec[0], 1) self.assertEqual(argspec[1], 4) self.assertEqual(argspec[2], 30) self.assertEqual(argspec[3], 'forced replacement item') self.assertEqual(argspec[4], 'no changes') self.assertEqual(argspec[5], 5) self.assertEqual(argspec[6], 5) argspec = c.translate( 'pydbus.unittest', 'fromDbusNamedBitFormats', ( ('bit 0 on', 'bit 2 off'), ('bit 2 off', ['zero_to_sixteen', 9 ], 'left two of nibble2 is one'), 100, # oass ints along as they come 'never see it', 'no changes'), 0, False, 'uuiss', None, None) self.assertEqual(argspec[0], 1) self.assertEqual(argspec[1], 0x910) self.assertEqual(argspec[2], 100) self.assertRaises(ValueError, c.translate, 'pydbus.unittest', 'singletest', ('should fail', 6), 0, False, 'uui', None, None) argspec = c.translate('pydbus.unittest', 'singletest', 'bit 0 ON', 0, False, 'u', None, None) self.assertTrue(argspec, 1) argspec = c.translate( 'pydbus.unittest', 'prettydicttest', { 'the first three bits if not the fourth': 5, 'solo True, seldom seen': True }, 0, False, 'i', None, None) # print(str(argspec)) self.assertEqual(argspec[0], 5 + 16) self.assertTrue(len(argspec) == 1) argspec = c.translate('pydbus.unittest', 'prettylisttest', (( 'solo True, seldom seen', ('the first three bits if not the fifth', 3), ), ), 0, False, 'i', None, None) # print(str(argspec)) self.assertEqual(argspec[0], 0x13) argspec = c.translate('pydbus.unittest', 'simplematchfunction', ("The answer should be five", ), 0, False, 'i', None, None) # print(str(argspec)) self.assertTrue(argspec[0] == 5) argspec = c.translate('pydbus.unittest', 'allargsin1matchfunction', ("The answer should be seven", "Hi Mom"), 0, False, 'i', None, None) # print(str(argspec)) self.assertTrue(argspec[0] == 7) argspec = c.translate('pydbus.unittest', 'pytodbusvariants', (('label for 0', 1, 2, 'two', 'strings'), ['some', 'more', 'strings']), 0, False, 'vv', None, None) self.assertEqual(argspec[0], Variant('(iiiss)', (0, 1, 2, 'two', 'strings'))) self.assertEqual(argspec[1], Variant('as', ['some', 'more', 'strings'])) argspec = c.translate('pydbus.unittest', 'pytodbusvariants2', ( ('label for 0', 1, 2, 'two', 'strings'), ['label for 10', 'who', 'knows'], ('label for 10', 'who', 'knows'), ), 0, False, 'vvv', None, None) self.assertEqual(argspec[0], Variant('(iiiss)', (0, 1, 2, 'two', 'strings'))) self.assertEqual(argspec[1], Variant('ai', [10, -101, -101])) self.assertEqual(argspec[2], Variant( '(iss)', (10, 'who', 'knows'), )) self.assertTrue(len(argspec) == 3) argspec = c.translate('pydbus.unittest', 'dictionary_test', ({ 0: 'label for 1', 1: 10 }, { 0: 'label for 1', 20: 'label for 20', 99: 99, 42: "who knows", 100: "label for 1" }), 0, False, 'a{ii}a{ii}', None, None) self.assertEqual(argspec, ({ 0: 1, 1: 10 }, { 0: 1, 20: 20, 99: 99, 42: -101, 100: -101 })) argspec = c.translate('pydbus.unittest', 'dictionary_keys', ( { 'label for 1': 'is 1', 2: 'is 2' }, { 'label for 1': 'is 1', 2: 'is 2' }, ), 0, False, 'a{is}a{ii}', None, None) # print(str(argspec)) self.assertEqual(argspec[0], {1: 'is 1', 2: 'is 2'}) self.assertEqual(argspec[1], {1: 1, 2: 2}) t = BlankObject() t.arg0 = 'zero' t.arg1 = 'one' t.arg2 = 2 argspec = c.translate('pydbus.unittest', 'named_arguments', t, 0, False, 'ssi', None, None) self.assertEqual(argspec, ('zero', 'one', 2)) d = {'arg0': 'zero', 'arg1': 'one', 'arg2': 2} argspec = c.translate('pydbus.unittest', 'named_arguments2', d, 0, False, 'ssi', None, None) self.assertEqual(argspec, ('zero', 'one', 2))
def __init__(self, user_preferences): super(Preferences, self).__init__(border_width=20) vbox = Gtk.Box.new(Gtk.Orientation.VERTICAL, 0) self.add(vbox) self.vert_btn = Gtk.RadioButton(label="Vertical preview", action_name="win.change-preview", action_target=Variant( 'q', Gtk.Orientation.VERTICAL)) if user_preferences.preview == Gtk.Orientation.VERTICAL: self.vert_btn.set_active(True) vbox.pack_start(self.vert_btn, True, True, 0) self.hori_btn = Gtk.RadioButton(group=self.vert_btn, label="Horizontal preview", action_name="win.change-preview", action_target=Variant( 'q', Gtk.Orientation.HORIZONTAL)) if user_preferences.preview == Gtk.Orientation.HORIZONTAL: self.hori_btn.set_active(True) vbox.pack_start(self.hori_btn, True, True, 0) self.auto_scroll_btn = Gtk.CheckButton( label='Auto scroll', action_name="win.auto-scroll-toggle", action_target=Variant('b', True)) self.auto_scroll_btn.set_active(user_preferences.auto_scroll) vbox.pack_start(self.auto_scroll_btn, True, True, 0) vbox.pack_start(Gtk.Separator(orientation=Gtk.Orientation.HORIZONTAL), True, True, 0) group = None for key, val in sorted(PARSERS.items()): enabled = val['class'] is not None item = Gtk.RadioButton( label=val['title'], group=group, sensitive=enabled, action_name=("win.change-parser" if enabled else None), action_target=Variant('s', key)) if user_preferences.parser == key: item.set_active(True) item.parser = key if group is None: group = item vbox.pack_start(item, True, True, 0) self.parser_group = group.get_group() vbox.pack_start(Gtk.Separator(orientation=Gtk.Orientation.HORIZONTAL), True, True, 0) group = None for key, val in sorted(WRITERS.items()): enabled = val['class'] is not None item = Gtk.RadioButton( label=val['title'], group=group, sensitive=enabled, action_name=("win.change-writer" if enabled else None), action_target=Variant('s', key)) if user_preferences.writer == key: item.set_active(True) item.writer = key if group is None: group = item vbox.pack_start(item, True, True, 0) self.writer_group = group.get_group() vbox.pack_start(Gtk.Separator(orientation=Gtk.Orientation.HORIZONTAL), True, True, 0) self.custom_btn = Gtk.CheckButton( label='Custom style', action_name="win.custom-style-toggle", action_target=Variant('b', True)) self.custom_btn.set_active(user_preferences.custom_style) self.custom_btn.connect("toggled", self.on_custom_style_toggle) vbox.pack_start(self.custom_btn, True, True, 0) self.style_btn = ActionableFileChooserButton( sensitive=user_preferences.custom_style, action_name="win.change-style") vbox.pack_start(self.style_btn, True, True, 0) vbox.show_all()
def do_file_set(self): self.action_target = Variant("s", self.get_filename() or '') action, go = self.get_action_owner() if go: go.activate_action(action, self.action_target)
def get_dbus_metadata(metadata: Metadata) -> DbusMetadata: return { key: Variant(METADATA_TYPES[key], val) for key, val in metadata.items() if is_valid_metadata(key, val) }
WORKSPACE_CATEGORIES = { 1: "Accesssories", 2: "Chromium Apps", 3: "Office", 4: "Bookmarks", 5: "Development", 6: "Games", 7: "Internet", 8: "Settings", 9: "System", } # Tweak xfce4-appfinder over D-Bus bus = SessionBus() xfconf = bus.get("org.xfce.Xfconf") xfconf.SetProperty("xfce4-appfinder", "/enable-service", Variant("b", True)) xfconf.SetProperty("xfce4-appfinder", "/single-window", Variant("b", True)) async def on_workspace_focus(i3, event): """Show the appfinder when an empty workspace receives focus""" # Close any open appfinder window await i3.command('[class="Xfce4-appfinder"] kill') # Do nothing if this workspace isn't empty if event.current.focus: return if event.current.num in WORKSPACE_CATEGORIES: # Switch appfinder category to the one configured for this workspace