コード例 #1
0
class _OSDManager(object):
    """
    Manages OSD notifications via DBus.
    """
    def __init__(self):
        if not ENABLED:
            self._actions = {}
            return

        self._last_id = 0
        self.bus = SessionBus()

        self.notifications = None
        self.bus.watch_name(BASE_NAME + NOTIFICATION_BUS_NAME,
                            name_appeared=self._register_bus_name,
                            name_vanished=self._deregister_bus_name)
        self._register_bus_name(None)

        self._actions = {"default": lambda *args: None}

    def add_to_action(self, action, action_name, function):
        """
        Register an action to the notification deamon
        Note: you can override the default action by passing "default" the action argument.
        Note: by passing the same action argument you override it.

        Args:
           action (`str`): The action that you want to invoke.
           action_name (`str`): The human readable string that describes the action
           function (`func`): The function that you want to envoke when it is called
        """
        self._actions[action] = (action_name, function)

    def notify(self, title, body, actions, icon, replace=True):
        """
        Create new or update existing notification.

        Args:
           track (`clay.gp.Track`): The track that you want to send the notification for
           actions (`list`): A list with the actions that you want the notification to react to.
        """
        if not ENABLED:
            return

        actions_ = []
        for action in actions:
            if action not in self._actions:
                logger.error("Can't find action: {}".format(action))
                continue

            actions_.append(action)
            actions_.append(self._actions[action][0])

        self._notify(
            title,
            body,
            replace,
            actions=actions_,
            hints={"action-icons": Variant('b', 1)},  # only display icons
            icon=icon if icon is not None else 'audio-headphones')

    def _on_action(self, id_, action):
        if id_ != self._last_id:
            return

        if action in self._actions:
            self._actions[action][1]()
        else:
            self._actions.get("default")[1]()

    def _notify(self,
                summary,
                body,
                replace=True,
                actions=None,
                hints=None,
                expiration=5000,
                icon='audio-headphones'):
        """
        An implementation of Desktop Notifications Specification 1.2.
        For a detailed explanation see: https://developer.gnome.org/notification-spec/

        Does not fire if notifications were not properly set up
        Args:
           summary (`str`): A single line overview of the notification
           body (`str`): A mutli-line body of the text
           replace (`bool`): Should the notification be updated or should a new one be made
           actions (`list`): The actions a notification can perform, might be ignored. Default empty
           hints (`dict`): Extra information the server might be able to make use of
           expiration (`int`): The time until the notification automatically closes. -1 to make the
              server decide and 0 for never. Defaults to 5000.
           icon (`str`): The string to icon it displays in the notification. Defaults to headbuds.

        Returns:
           Nothing.
        """
        if self.notifications is None:
            return

        try:
            self._last_id = self.notifications.Notify(
                meta.APP_NAME, self._last_id if replace else 0, icon, summary,
                body, actions if actions is not None else list(),
                hints if hints is not None else dict(), expiration)
        except GLib.Error as exception:
            logger.error('Failed to post notification %s', exception)

    def _register_bus_name(self, name_owner):
        """
        Registers a bus for sending notifications over dbus

        Args:
            name_owner (`str`) (unused): The owner of the bus

        Returns:
            Nothing.
        """
        try:
            self.notifications = self.bus.get(NOTIFICATION_BUS_NAME)
            self.notifications.onActionInvoked = self._on_action
        except GLib.Error:
            # Bus name did not exist
            logger.error('Attempted bus name registration failed, %s',
                         NOTIFICATION_BUS_NAME)

    def _deregister_bus_name(self):
        """
        Deregisters a bus for sending notifications over dbus.
        Once run, notifications cannot be sent

        Returns:
            Nothing.
        """
        self.notifications = None
コード例 #2
0
ファイル: power.py プロジェクト: knownunown/uchroma
class PowerMonitor(metaclass=Singleton):
    """
    Watches for changes to the system's suspend state and
    screensaver, signalling devices to suspend if necessary.
    """
    def __init__(self):
        self._logger = Log.get('uchroma.power')
        self._name_watchers = []
        self._running = False
        self._sleeping = False
        self._user_active = False

        self._session_bus = SessionBus()
        self._system_bus = SystemBus()
        self._dm = UChromaDeviceManager() #singleton


    def _suspend(self, sleeping, fast):
        if self._sleeping == sleeping:
            return

        self._sleeping = sleeping
        for name, device in self._dm.devices.items():
            if sleeping:
                self._logger.info("Suspending device: %s", name)
                device.suspend(fast=fast)
            else:
                self._logger.info("Resuming device: %s", name)
                device.resume()


    def _prepare_for_sleep(self, sleeping):
        self._suspend(sleeping, True)


    def _active_changed(self, active):
        self._suspend(active, False)


    def _is_user_active(self):
        user = self._system_bus.get(LOGIN_SERVICE, "/org/freedesktop/login1/user/self")
        self._logger.info("is_user_active: %s %s", user, user.Display)
        return user is not None and user.Display[0] != ''


    def _user_changed(self, changed):
        is_active = self._is_user_active()
        if is_active != self._user_active:
            self._user_active = is_active
            self._suspend(not self._user_active, True)


    def start(self):
        """
        Connects to the PrepareForSleep signal from login1 to monitor
        system suspend, and sets up watches for known screensaver
        instances.
        """
        if self._running:
            return

        for name, path in SCREENSAVERS:
            def connect_screensaver(*args, bus_name=name, object_path=path):
                """
                Connects the callback when the service appears.
                """
                try:
                    saver = self._session_bus.get(bus_name=bus_name, object_path=object_path)
                    saver.ActiveChanged.connect(self._active_changed)
                    self._logger.info("Connected screensaver: %s:%s %s", bus_name, object_path, args)

                except Exception:
                    self._logger.warn("Could not connect to %s:%s service", bus_name, object_path)


            self._name_watchers.append(self._session_bus.watch_name( \
                    name, name_appeared=connect_screensaver))


        def connect_login1(*args):
            try:
                login1 = self._system_bus.get(LOGIN_SERVICE)
                login1.PrepareForSleep.connect(self._prepare_for_sleep)
                self._logger.info("Connected to %s %s", LOGIN_SERVICE, args)

                user = self._system_bus.get(LOGIN_SERVICE, "/org/freedesktop/login1/user/self")
                user.PropertiesChanged.connect(self._user_changed)

            except Exception:
                self._logger.warn("Could not connect to login1 service")

        self._name_watchers.append(self._system_bus.watch_name( \
                LOGIN_SERVICE, name_appeared=connect_login1))

        self._running = True


    def stop(self):
        """
        Disable the monitor
        """
        if not self._running:
            return

        for watcher in self._name_watchers:
            watcher.unwatch()

        self._name_watchers.clear()

        self._running = False
コード例 #3
0
def on_pidgin_appeared(con=None, name=None, name_owner=None):
    global purple
    purple = bus.get("im.pidgin.purple.PurpleService",
                     "/im/pidgin/purple/PurpleObject")
    purple.ReceivedImMsg.connect(on_received)
    purple.SentImMsg.connect(on_sent)


def on_pidgin_vanished(con=None, name=None):
    global purple
    purple = None


dir_filepath = getenv("HOME") + "/.moov_dir"
if not isfile(dir_filepath):
    print("Error: ~/.moov_dir file not found.\nAborting.", file=stderr)
    exit(1)
dir_file = open(dir_filepath, "r")
video_dir = dir_file.readline().strip()
if not isdir(video_dir):
    print(
        "Error: directory path specified in ~/.moov_dir is invalid.\nAborting.",
        file=stderr)
    exit(2)

bus = SessionBus()
bus.watch_name("im.pidgin.purple.PurpleService",
               name_appeared=on_pidgin_appeared,
               name_vanished=on_pidgin_vanished)
GObject.MainLoop().run()