def get_variant(value: GLib.Variant) -> GLib.Variant: # Some of the metric events (e.g UptimeEvent) have payload wrapped multiple times in variants, # but others don't while value.get_type_string() == 'v': value = value.get_variant() return value
def new_aggregate_event(request: Request, event_variant: GLib.Variant, dbsession: DbSession) -> Optional[AggregateEvent]: event_id = str(UUID(bytes=get_bytes(event_variant.get_child_value(1)))) if event_id in IGNORED_EVENTS: return None user_id = event_variant.get_child_value(0).get_uint32() count = event_variant.get_child_value(2).get_int64() event_relative_timestamp = event_variant.get_child_value(3).get_int64() payload = event_variant.get_child_value(4) event_date = get_event_datetime(request.absolute_timestamp, request.relative_timestamp, event_relative_timestamp) # We don't have any aggregate event yet, therefore it can only be unknown # Mypy complains here, even though this should be fine: # https://github.com/dropbox/sqlalchemy-stubs/issues/97 event = UnknownAggregateEvent( request=request, user_id=user_id, # type: ignore occured_at=event_date, count=count, event_id=event_id, payload=payload) dbsession.add(event) return event
def new_singular_event(request: Request, event_variant: GLib.Variant, dbsession: DbSession) -> Optional[SingularEvent]: event_id = str(UUID(bytes=get_bytes(event_variant.get_child_value(1)))) if event_id in IGNORED_EVENTS: return None user_id = event_variant.get_child_value(0).get_uint32() event_relative_timestamp = event_variant.get_child_value(2).get_int64() payload = event_variant.get_child_value(3) event_date = get_event_datetime(request.absolute_timestamp, request.relative_timestamp, event_relative_timestamp) try: event_model = SINGULAR_EVENT_MODELS[event_id] except KeyError: # Mypy complains here, even though this should be fine: # https://github.com/dropbox/sqlalchemy-stubs/issues/97 event = UnknownSingularEvent( request=request, user_id=user_id, # type: ignore occured_at=event_date, event_id=event_id, payload=payload) dbsession.add(event) return event try: # Mypy complains here, even though this should be fine: # https://github.com/dropbox/sqlalchemy-stubs/issues/97 event = event_model( request=request, user_id=user_id, # type: ignore occured_at=event_date, payload=payload) except Exception as e: if isinstance(e, EmptyPayloadError ) and event_id in IGNORED_EMPTY_PAYLOAD_ERRORS: return None log.exception('An error occured while processing the event:') # Mypy complains here, even though this should be fine: # https://github.com/dropbox/sqlalchemy-stubs/issues/97 event = InvalidSingularEvent( request=request, user_id=user_id, # type: ignore occured_at=event_date, event_id=event_id, payload=payload, error=str(e)) dbsession.add(event) return event
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 _parse_payload(self, maybe_payload: GLib.Variant) -> Dict[str, Any]: payload = maybe_payload.get_maybe() if self.__payload_type__ is None: if payload is not None: log.error('Metric event %s takes no payload, but got %s', self.__event_uuid__, payload) return {} if payload is None: raise EmptyPayloadError( f'Metric event {self.__event_uuid__} needs a ' f'{self.__payload_type__} payload, but got none') payload = get_variant(payload) payload_type = payload.get_type_string() if payload_type != self.__payload_type__: raise WrongPayloadError( f'Metric event {self.__event_uuid__} needs a ' f'{self.__payload_type__} payload, but got ' f'{payload} ({payload_type})') return self._get_fields_from_payload(payload)
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_g_properties_changed(self, changed_properties: GLib.Variant, _invalidated_properties: List[str]) -> None: changed = changed_properties.unpack() object_path = self.get_object_path() logging.debug("%s %s" % (object_path, changed)) for key, value in changed.items(): self.emit("property-changed", key, value, object_path)
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 on_close_view(self, _action: Gio.SimpleAction, view_name: GLib.Variant) -> None: try: self.view_manager.close(view_name.get_string()) except ValueError: # Tried to remove last view pass
def _handle_method_call(self, _connection: Gio.DBusConnection, sender: str, _path: str, interface_name: str, method_name: str, parameters: GLib.Variant, invocation: Gio.DBusMethodInvocation) -> None: try: try: _arguments, result_signatures, method, options = self._methods[ method_name] except KeyError: logging.warning(f"Unhandled method: {method_name}") invocation.return_error_literal( Gio.dbus_error_quark(), Gio.DBusError.UNKNOWN_METHOD, f"No such method on interface: {interface_name}.{method_name}" ) def ok(*result: Any) -> None: invocation.return_value( self._prepare_arguments( result_signatures, result[0] if len(result_signatures) > 1 else result)) args = parameters.unpack() if "sender" in options: args += (sender, ) if "async" in options: method(*(args + (ok, lambda exception: self._return_dbus_error( invocation, exception)))) else: ok(method(*args)) except Exception as e: self._return_dbus_error(invocation, e)
def on_active_changed(self, connection: Gio.DBusConnection, sender_name: str, object_path: str, interface_name: str, signal_name: str, parameters: GLib.Variant): activated = parameters.unpack()[0] self.on_screen_was_locked( ) if activated else self.on_screen_was_unlocked()
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 do_g_properties_changed(self, changed_properties: GLib.Variant, _invalidated_properties: List[str]) -> None: for name, value in changed_properties.unpack().items(): logging.debug("%s %s %s" % (self.get_object_path(), name, value)) if name == 'Transferred': self.emit('progress', value) elif name == 'Status': if value == 'complete': self.emit('completed') elif value == 'error': self.emit('error')
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 on_signal( _connection: Gio.DBusConnection, _sender_name: str, object_path: str, _interface_name: str, _signal_name: str, param: GLib.Variant, ) -> None: iface_name, changed, invalidated = param.unpack() if iface_name == self.__interface_name: self._on_properties_changed(object_path, changed, invalidated)
def on_menu_auto(self, action: Gio.Action, state: GLib.Variant) -> None: """ Manage automatic toggle menu. :param action: The action calling the function. :param state: The new state. """ action.set_state(state) view = self.__get_active_view() if view is not None and not view.is_readonly(): view.set_auto_analyze(state.get_boolean())
def on_selection_action(self, variant: GLib.Variant) -> None: self.unlocked_database.start_database_lock_timer() selection_type = variant.get_string() page = self.unlocked_database.get_current_page() list_box = page.list_box for row in list_box: if selection_type == "all": row.selection_checkbox.set_active(True) else: row.selection_checkbox.set_active(False)
def _parse_payload(self, maybe_payload: GLib.Variant) -> Dict[str, Any]: # Workaround an issue in GLib < 2.62 # https://gitlab.gnome.org/GNOME/glib/issues/1865 as_bytes = maybe_payload.get_data_as_bytes() if as_bytes is None: # pragma: no cover payload_data = b'' else: payload_data = as_bytes.get_data() return {'payload_data': payload_data}
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 _on_buffer_style_changed(self, buffer, changed_styles): """Synchronize actions as the format changes at the buffer's cursor.""" if not self.uimanager: return # never initialized a toolbar, not editable types = [StyledTextTagType.ITALIC, StyledTextTagType.BOLD, StyledTextTagType.UNDERLINE] self._internal_style_change = True for style, style_value in changed_styles.items(): if style in types: action = self.uimanager.get_action( self.action_group, StyledTextTagType(style).xml_str().upper()) action.change_state(Variant.new_boolean(style_value)) elif (style == StyledTextTagType.FONTFACE): self.fontface.set_text(style_value) elif style == StyledTextTagType.FONTSIZE: self.fontsize.set_text(str(style_value)) self._internal_style_change = False
def __inner(qtile): symbol = 'A' if vlu > 0 else 'U' subprocess.Popen(f"light -{symbol} {abs(vlu)}", shell=True, text=True) if not FAILED_NOTIFY: cur_bright = float( subprocess.Popen('light', shell=True, text=True, stdout=subprocess.PIPE).communicate()[0][:-1]) icon = 'display-brightness-off' if cur_bright >= 70: icon = 'display-brightness-high' elif cur_bright >= 40: icon = 'display-brightness-medium' elif cur_bright > 0: icon = 'display-brightness-low' notification.update('Brightness Changed', '', icon) notification.set_hint('value', gi_variant.new_int32(cur_bright)) notification.show()
def _on_action_create_row(self, action: Gio.Action, param: GLib.Variant, arg): where = param.get_string() model, refs = self._get_selected_refs() selected_iter = model.get_iter(refs[0].get_path()) if where == 'first-child': row = ('', model.get_page(selected_iter)) it = model.prepend(selected_iter, row) elif where == 'last-child': row = ('', model.get_last_chapter_page(selected_iter)) it = model.append(selected_iter, row) elif where == 'previous-sibling': row = ('', model.get_page(selected_iter)) it = model.insert_before(None, selected_iter, row) elif where == 'next-sibling': row = ('', model.get_last_chapter_page(selected_iter)) it = model.insert_after(None, selected_iter, row) else: raise ValueError(where) self.start_editing(it)
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 __inner(qtile): sign = '+' if vol > 0 else '-' subprocess.Popen( f"pactl set-sink-volume @DEFAULT_SINK@ {sign}{abs(vol)}%", shell=True, text=True) if not FAILED_NOTIFY: cur_vol = int( subprocess.Popen('pamixer --get-volume', shell=True, text=True, stdout=subprocess.PIPE).communicate()[0][:-1]) icon = 'audio-volume-muted' if cur_vol >= 70: icon = 'audio-volume-high' elif cur_vol >= 40: icon = 'audio-volume-medium' elif cur_vol > 0: icon = 'audio-volume-low' notification.update('Volume Changed', '', icon) notification.set_hint('value', gi_variant.new_int32(cur_vol)) notification.show()
def do_g_signal(self, _sender_name: str, signal_name: str, params: GLib.Variant) -> None: notif_id, signal_val = params.unpack() if notif_id != self._return_id: return logging.info(signal_val) if signal_name == 'NotificationClosed': if signal_val == 1: logging.debug('The notification expired.') elif signal_val == 2: logging.debug('The notification was dismissed by the user.') elif signal_val == 3: logging.debug( 'The notification was closed by a call to CloseNotification.' ) elif signal_val == 4: logging.debug('Undefined/reserved reasons.') elif signal_name == 'ActionInvoked': if signal_val in self._callbacks: self._callbacks[signal_val](signal_val)
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 _get_fields_from_payload(payload: GLib.Variant) -> Dict[str, Any]: return { 'the_int': payload.get_child_value(0).get_int32(), 'the_str': payload.get_child_value(1).get_string(), }