コード例 #1
0
ファイル: NH.py プロジェクト: regina-book/tfc-nacl
def nh_side_command_process():
    """
    Execute command (clear screen or exit) on NH.

    :return: [no return value]
    """

    bus = SessionBus()
    obj = bus.get_object("im.pidgin.purple.PurpleService",
                         "/im/pidgin/purple/PurpleObject")
    purple = Interface(obj, "im.pidgin.purple.PurpleInterface")
    account = purple.PurpleAccountsGetAllActive()[0]

    while True:
        if nh_side_command.empty():
            sleep(0.001)
            continue

        cmd = nh_side_command.get()

        if cmd.startswith("TFC|N|%s|U|CLEAR|" % int_version):
            contact = cmd.split('|')[5]
            new_conv = purple.PurpleConversationNew(1, account, contact)
            purple.PurpleConversationClearMessageHistory(new_conv)
            system("clear")
コード例 #2
0
ファイル: NH.py プロジェクト: regina-book/tfc-nacl
def dbus_receiver():
    """
    Start Qt loop that loads messages from Pidgin.

    :return: [no return value]
    """

    DBusQtMainLoop(set_as_default=True)
    bus = SessionBus()
    bus.add_signal_receiver(pidgin_to_rxm_queue,
                            dbus_interface="im.pidgin.purple.PurpleInterface",
                            signal_name="ReceivedImMsg")
コード例 #3
0
ファイル: vibra.py プロジェクト: proximate/proximate
class Vibra_Plugin(Plugin):
    def __init__(self):
        DBusGMainLoop(set_as_default=True)

        self.bus = SystemBus()
        self.sessionbus = SessionBus()
        try:
            self.mce = self.bus.get_object("com.nokia.mce", "/com/nokia/mce")
        except DBusException:
            warning("Nokia MCE not found. Vibra is disabled\n")
            return

        self.profiled = self.sessionbus.get_object("com.nokia.profiled", "/com/nokia/profiled")

        self.sessionbus.add_signal_receiver(
            self.profile_changed_handler,
            "profile_changed",
            "com.nokia.profiled",
            "com.nokia.profiled",
            "/com/nokia/profiled",
        )

        profile = self.profiled.get_profile(dbus_interface="com.nokia.profiled")
        self.get_vibra_enabled(profile)

        self.register_plugin(PLUGIN_TYPE_VIBRA)

    def ready(self):
        self.notification = get_plugin_by_type(PLUGIN_TYPE_NOTIFICATION)

        sendfile = get_plugin_by_type(PLUGIN_TYPE_SEND_FILE)
        sendfile.receive_cb.append(self.file_receive)

    def get_vibra_enabled(self, profile):
        self.enabled = (
            self.profiled.get_value(profile, "vibrating.alert.enabled", dbus_interface="com.nokia.profiled") == "On"
        )
        debug("Vibra enabled: %s\n" % self.enabled)

    def profile_changed_handler(self, foo, bar, profile, *args):
        self.get_vibra_enabled(profile)

    def vibrate(self):
        if self.enabled:
            self.mce.req_vibrator_pattern_activate("PatternChatAndEmail", dbus_interface="com.nokia.mce.request")

    def file_receive(self, cb, user, fname):
        self.vibrate()

    def user_appears(self, user):
        if user.get("friend"):
            self.vibrate()
コード例 #4
0
class DBusMediaKeyListener(object):
    '''Listen on DBus for media-key events.'''

    def __init__(self, callback=None):
        self._subscribers = []
        self.app = APP_NAME
        self.bus = SessionBus()
        self.bus_object = self.bus.get_object(
            'org.gnome.SettingsDaemon', '/org/gnome/SettingsDaemon/MediaKeys')
        self.bus_object.GrabMediaPlayerKeys(
            self.app, 0, dbus_interface='org.gnome.SettingsDaemon.MediaKeys')
        self.bus_object.connect_to_signal(
            'MediaPlayerKeyPressed', self._notify)
        if callback:
            self.subscribe(callback)

    def _notify(self, application, *mmkeys):
        for subscriber in self._subscribers:
            subscriber(mmkeys)

    def subscribe(self, callback):
        self._subscribers.append(callback)

    def unsubscribe(self, callback):
        self._subscribers.remove(callback)
コード例 #5
0
 def __init__(self):
     DBusGMainLoop(set_as_default=True)
     self.mem='ActiveChanged'
     self.dest='org.gnome.ScreenSaver'
     self.bus=SessionBus()
     self.loop=MainLoop()
     self.bus.add_signal_receiver(self.catch,self.mem,self.dest)
コード例 #6
0
ファイル: vibra.py プロジェクト: proximate/proximate
    def __init__(self):
        DBusGMainLoop(set_as_default=True)

        self.bus = SystemBus()
        self.sessionbus = SessionBus()
        try:
            self.mce = self.bus.get_object("com.nokia.mce", "/com/nokia/mce")
        except DBusException:
            warning("Nokia MCE not found. Vibra is disabled\n")
            return

        self.profiled = self.sessionbus.get_object("com.nokia.profiled", "/com/nokia/profiled")

        self.sessionbus.add_signal_receiver(
            self.profile_changed_handler,
            "profile_changed",
            "com.nokia.profiled",
            "com.nokia.profiled",
            "/com/nokia/profiled",
        )

        profile = self.profiled.get_profile(dbus_interface="com.nokia.profiled")
        self.get_vibra_enabled(profile)

        self.register_plugin(PLUGIN_TYPE_VIBRA)
コード例 #7
0
    def __init__(self, registry, owner):
        """Initialize the ServerPlugin instance

        :Parameters:
            `registry` : telepathy.client.ManagerRegistry
                From the PresenceService, used to find the connection
                manager details
            `owner` : buddy.GenericOwner
                The Buddy representing the owner of this XO (normally a
                buddy.ShellOwner instance)
        """
        gobject.GObject.__init__(self)

        #: The connection, a `telepathy.client.Connection`
        self._conn = None

        #: List of dbus-python SignalMatch objects representing signal match
        #: rules associated with the connection, so we don't leak the match
        #: rules when disconnected.
        self._matches = []

        #: The manager registry, a `telepathy.client.ManagerRegistry`
        self._registry = registry

        #: set of contact handles: those for whom we've emitted contacts-online
        self._online_contacts = set()

        #: The owner, a `buddy.GenericOwner`
        self._owner = owner
        #: The owner's handle on this connection
        self.self_handle = None
        #: The owner's identifier (e.g. JID) on this connection
        self.self_identifier = None

        #: The connection's status
        self._conn_status = CONNECTION_STATUS_DISCONNECTED

        #: GLib source ID indicating when we may try to reconnect
        self._backoff_id = 0

        #: length of the next reconnect timeout
        self._reconnect_timeout = self._RECONNECT_INITIAL_TIMEOUT

        #: The ``subscribe`` channel: a `telepathy.client.Channel` or None
        self._subscribe_channel = None
        #: The members of the ``subscribe`` channel
        self._subscribe_members = set()
        #: The local-pending members of the ``subscribe`` channel
        self._subscribe_local_pending = set()
        #: The remote-pending members of the ``subscribe`` channel
        self._subscribe_remote_pending = set()

        #: The ``publish`` channel: a `telepathy.client.Channel` or None
        self._publish_channel = None

        self._session_bus = SessionBus()
        self._init_connection()
コード例 #8
0
ファイル: voltisession.py プロジェクト: zerkalica/volti-lite
class VoltiSession:
    def __init__(self, app_name):
        log.Notice("running init")
        self.app_name = app_name
        self.bus = SessionBus(mainloop = DBusGMainLoop() )

    def check(self):
        log.Notice("running check")
        return self.bus.request_name(self.app_name) != bus.REQUEST_NAME_REPLY_PRIMARY_OWNER
コード例 #9
0
ファイル: keysocket.py プロジェクト: hobeone/keysocket
 def __init__(self, callback=None):
     self._subscribers = []
     self.app = APP_NAME
     self.bus = SessionBus()
     self.bus_object = self.bus.get_object("org.gnome.SettingsDaemon", "/org/gnome/SettingsDaemon/MediaKeys")
     self.bus_object.GrabMediaPlayerKeys(self.app, 0, dbus_interface="org.gnome.SettingsDaemon.MediaKeys")
     self.bus_object.connect_to_signal("MediaPlayerKeyPressed", self._notify)
     if callback:
         self.subscribe(callback)
コード例 #10
0
ファイル: systemtray.py プロジェクト: incrazyboyy/RPiTC-X
    def __init__(self, args, read_pipe):
        QApplication.__init__(self, args)

        self.menu = None
        self.read_pipe = read_pipe
        self.fmt = "80s80sI32sI80sf"
        self.fmt_size = struct.calcsize(self.fmt)
        self.timer_active = False
        self.active_icon = False
        self.user_settings = UserSettings()
        self.user_settings.load()
        self.user_settings.debug()

        self.tray_icon = QSystemTrayIcon()

        pm = load_pixmap("hp_logo", "32x32")
        self.prop_icon = QIcon(pm)

        a = load_pixmap('active', '16x16')
        painter = QPainter(pm)
        painter.drawPixmap(32, 0, a)
        painter.end()

        self.prop_active_icon = QIcon(pm)

        self.tray_icon.setIcon(self.prop_icon)

        self.session_bus = SessionBus()
        self.service = None

        for d in device.getSupportedCUPSDevices(back_end_filter=['hp', 'hpfax']):
            self.addDevice(d)

        self.tray_icon.setToolTip(self.__tr("HPLIP Status Service"))
        QObject.connect(self.tray_icon, SIGNAL("messageClicked()"), self.messageClicked)
        notifier = QSocketNotifier(self.read_pipe, QSocketNotifier.Read)
        QObject.connect(notifier, SIGNAL("activated(int)"), self.notifierActivated)
        QObject.connect(self.tray_icon, SIGNAL("activated(QSystemTrayIcon::ActivationReason)"), self.trayActivated)
        signal.signal(signal.SIGINT, signal.SIG_DFL)
        self.tray_icon.show()

        if self.user_settings.systray_visible == SYSTRAY_VISIBLE_SHOW_ALWAYS:
            self.tray_icon.setVisible(True)
        else:
            QTimer.singleShot(HIDE_INACTIVE_DELAY, self.timeoutHideWhenInactive) # show icon for awhile @ startup

        self.tray_icon.setIcon(self.prop_active_icon)
        self.active_icon = True

        if "--ignore-update-firsttime" not in args:
            self.handle_hplip_updation()

        QTimer.singleShot(SET_MENU_DELAY, self.initDone)

        self.update_timer = QTimer()
        self.update_timer.connect(self.update_timer,SIGNAL("timeout()"),self.handle_hplip_updation)
        self.update_timer.start(UPGRADE_CHECK_DELAY)
コード例 #11
0
    def run_client(self):
        bus = SessionBus()
        obj = bus.get_object(CROSS_TEST_BUS_NAME, CROSS_TEST_PATH)
        self.obj = obj

        self.run_synchronous_tests(obj)

        # Signal tests
        logger.info("Binding signal handler for Triggered")
        # FIXME: doesn't seem to work when going via the Interface method
        # FIXME: should be possible to ask the proxy object for its
        # bus name
        bus.add_signal_receiver(self.triggered_cb, 'Triggered',
                                INTERFACE_SIGNAL_TESTS,
                                CROSS_TEST_BUS_NAME,
                                path_keyword='sender_path')
        logger.info("method/signal: Triggering signal")
        self.expected.add('%s.Trigger' % INTERFACE_TESTS)
        Interface(obj, INTERFACE_TESTS).Trigger(u'/Where/Ever', dbus.UInt64(42), reply_handler=self.trigger_returned_cb, error_handler=self.trigger_error_handler)
コード例 #12
0
 def __init__(self):
     self.v=False
     self.o=False
     try:
         self.session = SessionBus.get_session()
         self.spotify = self.session.get_object("org.mpris.MediaPlayer2.spotify","/org/mpris/MediaPlayer2")
         self.p=Interface(self.spotify, 'org.freedesktop.DBus.Properties')
         self.v=True
         self.o=True
     except:
         pass   
コード例 #13
0
ファイル: NH.py プロジェクト: regina-book/tfc-nacl
def header_printer_process():
    """
    Print NH.py headers.

    :return: [no return value]
    """

    try:
        bus = SessionBus()
        obj = bus.get_object("im.pidgin.purple.PurpleService",
                             "/im/pidgin/purple/PurpleObject")
        purple = Interface(obj, "im.pidgin.purple.PurpleInterface")
        active = purple.PurpleAccountsGetAllActive()[0]
        acco_u = purple.PurpleAccountGetUsername(active)[:-1]

        print("TFC-NaCl %s | NH.py\n" % str_version)
        print("Active account: %s\n" % acco_u)

    except DBusException:
        raise CriticalError("header_printer_process", "DBusException. Ensure "
                                                      "Pidgin is running.")
コード例 #14
0
ファイル: radiotray.py プロジェクト: jmberros/dotfiles
    def run(self):
        radiotray = SessionBus().get_object("net.sourceforge.radiotray",
                                            "/net/sourceforge/radiotray")

        radio_full_name = str(radiotray.getCurrentRadio())
        matches = search("~ ([^\(]*)", radio_full_name)
        radio_short_name = matches.group(1).rstrip() if matches else radio_full_name

        cdict = {
            "radio": radio_short_name,
            "song": str(radiotray.getCurrentMetaData()),
        }

        if "not playing" in cdict["radio"]:
            full_text = ""
        else:
            full_text = self.format.format(**cdict)

        self.output = {
            "full_text": full_text,
            "color": self.color,
        }
コード例 #15
0
ファイル: audiobox.py プロジェクト: dhruvasagar/vim-audiobox
class Audiobox():
    """Audiobox class"""
    def __init__(self):
        self.bus = SessionBus()
        self.init()

    def init(self):
        self.proxy_obj = self.bus.get_object(vim.eval('g:audiobox_dbus_dest'),
                                             vim.eval('g:audiobox_dbus_path'))
        self.player = Interface(self.proxy_obj, vim.eval('g:audiobox_dbus_interface'))
        self.properties = Interface(self.proxy_obj, vim.eval('g:audiobox_dbus_properties_interface'))

    def Play(self):
        """Play current song"""
        if self.player:
            self.player.Play()

    def Pause(self):
        """Pause current song"""
        if self.player:
            self.player.Pause()

    def Next(self):
        """Play the next song"""
        if self.player:
            self.player.Next()

    def Prev(self):
        """Play the previous song"""
        if self.player:
            self.player.Previous()

    def PlayPause(self):
        """Play / Pause the current song"""
        if self.player:
            self.player.PlayPause()

    def Stop(self):
        """Stop the current song"""
        if self.player:
            self.player.Stop()

    def GetCurrentSong(self):
        """Get the title of the current song"""
        if self.properties:
            metadata = self.properties.Get(vim.eval('g:audiobox_dbus_interface'), 'Metadata')
            if len(metadata) > 0:
                vim.command("echohl String | echom \"" + ("Song: %s, Artist: %s, Album: %s"
                    % (str(metadata['xesam:title']),
                        str(metadata['xesam:artist'][0]),
                        str(metadata['xesam:album']))) + "\" | echohl None")
コード例 #16
0
ファイル: NH.py プロジェクト: regina-book/tfc-nacl
def queue_to_pidgin_process():
    """
    Send message from queue to Pidgin.

    :return: [no return value]
    """

    bus = SessionBus()
    obj = bus.get_object("im.pidgin.purple.PurpleService",
                         "/im/pidgin/purple/PurpleObject")
    purple = Interface(obj, "im.pidgin.purple.PurpleInterface")
    account = purple.PurpleAccountsGetAllActive()[0]

    while True:
        if message_to_pidgin.empty():
            sleep(0.001)
            continue

        message = message_to_pidgin.get()

        if message.startswith("TFC|N|%s|M|" % int_version):
            tfc, model, ver, pt, ct, key_id, recipient = message.split('|')
            to_pidgin = '|'.join(message.split('|')[:6])

            if output_pidgin:
                new_conv = purple.PurpleConversationNew(1, account, recipient)
                sel_conv = purple.PurpleConvIm(new_conv)
                purple.PurpleConvImSend(sel_conv, to_pidgin)

        if message.startswith("TFC|N|%s|P|" % int_version):
            tfc, model, ver, pt, pub_key, recipient = message.split('|')
            to_pidgin = '|'.join(message.split('|')[:5])

            if output_pidgin:
                new_conv = purple.PurpleConversationNew(1, account, recipient)
                sel_conv = purple.PurpleConvIm(new_conv)
                purple.PurpleConvImSend(sel_conv, to_pidgin)
コード例 #17
0
class SSTrigger:
    def __init__(self):
        DBusGMainLoop(set_as_default=True)
        self.mem='ActiveChanged'
        self.dest='org.gnome.ScreenSaver'
        self.bus=SessionBus()
        self.loop=MainLoop()
        self.bus.add_signal_receiver(self.catch,self.mem,self.dest)

    def catch(self,ssOn):
        conn = mdb.connect('localhost', 'root','mysql_password', 'working_time');
        cursor = conn.cursor()
        now = datetime.datetime.now()

        if ssOn == 1: #Screensaver turned on
            sql = "UPDATE working_time SET end='%s' WHERE date='%s' AND end='0:0'"\
                    %(now.strftime("%H:%M"),now.strftime("%Y-%m-%d"))
            #logging.info(" sql=%s "%sql)
            logging.info("end=%s" % str(now.strftime("%H:%M")))
            res = cursor.execute(sql)
            if conn.affected_rows() != 1:
                cursor.execute("SELECT * from working_time")
                if cursor.rowcount != 1: # ignore error if it is a very first record in database
                    logging.error("ERROR!!! It should be only one (the last) record with end=0:0")

        else: #Screensaver turned off
            sql = "INSERT INTO working_time (date, start, end) VALUES('%s','%s','%s')"\
                    %(now.strftime("%Y-%m-%d"),now.strftime("%H:%M"),"0:0")
            #logging.info(" sql=%s "%sql)
            res=cursor.execute(sql)
            logging.info("start=%s "%now.strftime("%H:%M"))
            os.system("xmessage -nearmouse 'If you were out then start: log_working_time.py break'")

        conn.commit()	
        cursor.close()
        conn.close()
コード例 #18
0
ファイル: posix_dbus.py プロジェクト: brianhlin/htcondor
 def __init__(self, handler, opts):
     _ISkypeAPIBase.__init__(self, opts)
     self.RegisterHandler(handler)
     self.skype_in = self.skype_out = self.dbus_name_owner_watch = None
     self.bus = opts.pop('Bus', None)
     try:
         mainloop = opts.pop('MainLoop')
         if self.bus is not None:
             raise TypeError('Bus and MainLoop cannot be used at the same time!')
     except KeyError:
         if self.bus is None:
             import dbus.mainloop.glib
             import gobject
             gobject.threads_init()
             dbus.mainloop.glib.threads_init()
             mainloop = dbus.mainloop.glib.DBusGMainLoop()
             self.mainloop = gobject.MainLoop()
     if self.bus is None:
         from dbus import SessionBus
         self.bus = SessionBus(private=True, mainloop=mainloop)
     if opts:
         raise TypeError('Unexpected parameter(s): %s' % ', '.join(opts.keys()))
コード例 #19
0
 def quit_triggered(self):
     device.Event('', '', EVENT_SYSTEMTRAY_EXIT).send_via_dbus(SessionBus())
     self.quit()
コード例 #20
0
def send_message(device_uri, event_code, bytes_written=0):
    args = [device_uri, '', event_code, prop.username, 0, '', '', bytes_written]
    msg = lowlevel.SignalMessage('/', 'com.hplip.StatusService', 'Event')
    msg.append(signature='ssisissi', *args)
    SessionBus().send_message(msg)
コード例 #21
0
ファイル: spotify.py プロジェクト: nim65s/scripts
#!/usr/bin/env python3

from argparse import ArgumentParser

from dbus import Interface, SessionBus

parser = ArgumentParser(description='wrapper DBus pour Spotify')
parser.add_argument('action', nargs=1, choices=['play', 'pause', 'playpause', 'next', 'previous'])
action = parser.parse_args().action[0]

bus = SessionBus()
proxy = bus.get_object('org.mpris.MediaPlayer2.spotify', '/org/mpris/MediaPlayer2')
interface = Interface(proxy, dbus_interface='org.mpris.MediaPlayer2.Player')

if action in ['pause', 'play']:  # Workaround spotify’s bad implementation of Play…
    interface.Pause()
if action in ['playpause', 'play']:
    interface.PlayPause()
elif action == 'next':
    interface.Next()
elif action == 'previous':
    interface.Previous()
コード例 #22
0
ファイル: systemtray.py プロジェクト: csteacherd22/hplip
class SystemTrayApp(QApplication):
    def __init__(self, args, read_pipe):
        QApplication.__init__(self, args)

        self.menu = None
        self.read_pipe = read_pipe
        self.fmt = "80s80sI32sI80sf"
        self.fmt_size = struct.calcsize(self.fmt)
        self.timer_active = False
        self.active_icon = False
        self.user_settings = UserSettings()
        self.user_settings.load()
        self.user_settings.debug()

        self.tray_icon = QSystemTrayIcon()

        pm = load_pixmap("hp_logo", "32x32")
        self.prop_icon = QIcon(pm)

        a = load_pixmap('active', '16x16')
        painter = QPainter(pm)
        painter.drawPixmap(32, 0, a)
        painter.end()

        self.prop_active_icon = QIcon(pm)

        self.tray_icon.setIcon(self.prop_icon)

        self.session_bus = SessionBus()
        self.service = None

        for d in device.getSupportedCUPSDevices(back_end_filter=['hp', 'hpfax']):
            self.addDevice(d)

        self.tray_icon.setToolTip(self.__tr("HPLIP Status Service"))
        QObject.connect(self.tray_icon, SIGNAL("messageClicked()"), self.messageClicked)
        notifier = QSocketNotifier(self.read_pipe, QSocketNotifier.Read)
        QObject.connect(notifier, SIGNAL("activated(int)"), self.notifierActivated)
        QObject.connect(self.tray_icon, SIGNAL("activated(QSystemTrayIcon::ActivationReason)"), self.trayActivated)
        signal.signal(signal.SIGINT, signal.SIG_DFL)
        self.tray_icon.show()

        if self.user_settings.systray_visible == SYSTRAY_VISIBLE_SHOW_ALWAYS:
            self.tray_icon.setVisible(True)
        else:
            QTimer.singleShot(HIDE_INACTIVE_DELAY, self.timeoutHideWhenInactive) # show icon for awhile @ startup

        self.tray_icon.setIcon(self.prop_active_icon)
        self.active_icon = True

        if "--ignore-update-firsttime" not in args:
            self.handle_hplip_updation()

        QTimer.singleShot(SET_MENU_DELAY, self.initDone)

        self.update_timer = QTimer()
        self.update_timer.connect(self.update_timer,SIGNAL("timeout()"),self.handle_hplip_updation)
        self.update_timer.start(UPGRADE_CHECK_DELAY)

        # Cleans the /var/log/hp/tmp directory
        #self.handle_hplip_clean()
        
        #self.clean_timer = QTimer()
        #self.clean_timer.connect(self.clean_timer,SIGNAL("timeout()"),self.handle_hplip_clean)
        #self.clean_timer.start(CLEAN_EXEC_DELAY)
        



    def initDone(self):
        self.tray_icon.setIcon(self.prop_icon)
        self.active_icon = False

        self.setMenu()

    def resetDevice(self):
        devices.clear()

    def addDevice(self, device_uri):
        try:
            devices[device_uri]
        except KeyError:
            devices[device_uri] = HistoryDevice(device_uri)
        else:
            devices[device_uri].needs_update = True

    def handle_hplip_clean(self):
        log.debug("handle_hplip_clean ")
        home_dir = sys_conf.get('dirs', 'home')
        cmd = 'sh %s/hplip_clean.sh'%home_dir
        os.system(cmd)
        

    def handle_hplip_updation(self):
        log.debug("handle_hplip_updation upgrade_notify =%d"%(self.user_settings.upgrade_notify))
        path = utils.which('hp-upgrade')
        if self.user_settings.upgrade_notify is False:
            log.debug("upgrade notification is disabled in systray ")
            if path:
                path = os.path.join(path, 'hp-upgrade')
                log.debug("Running hp-upgrade: %s " % (path))
                # this just updates the available version in conf file. But won't notify
                os.spawnlp(os.P_NOWAIT, path, 'hp-upgrade', '--check')
                time.sleep(5)
                try:
                    os.waitpid(0, os.WNOHANG)
                except OSError:
                   pass

            return
            
            
        current_time = time.time()
    
        if int(current_time) > self.user_settings.upgrade_pending_update_time:
            path = utils.which('hp-upgrade')
            if path:
                path = os.path.join(path, 'hp-upgrade')
                log.debug("Running hp-upgrade: %s " % (path))
                os.spawnlp(os.P_NOWAIT, path, 'hp-upgrade', '--notify')
                time.sleep(5)
            else:
                log.error("Unable to find hp-upgrade --notify on PATH.")
        else:
            log.debug("upgrade schedule time is not yet completed. schedule time =%d current time =%d " %(self.user_settings.upgrade_pending_update_time, current_time))
        
        try:
            os.waitpid(0, os.WNOHANG)
        except OSError:
            pass





    def setMenu(self):
        self.menu = QMenu()

        title = QWidgetAction(self.menu)
        #title.setDisabled(True)

        hbox = QFrame(self.menu)
        layout = QHBoxLayout(hbox)
        layout.setMargin(3)
        layout.setSpacing(5)
        pix_label = QLabel(hbox)

        layout.insertWidget(-1, pix_label, 0)

        icon_size = self.menu.style().pixelMetric(QStyle.PM_SmallIconSize)
        pix_label.setPixmap(self.prop_icon.pixmap(icon_size))

        label = QLabel(hbox)
        layout.insertWidget(-1, label, 20)
        title.setDefaultWidget(hbox)

        label.setText(self.__tr("HPLIP Status Service"))

        f = label.font()
        f.setBold(True)
        label.setFont(f)
        self.menu.insertAction(None, title)

        if devices:
            if self.service is None:
                t = 0
                while t < 3:
                    try:
                        self.service = self.session_bus.get_object('com.hplip.StatusService',
                                                                  "/com/hplip/StatusService")
                    except dbus.DBusException:
                        log.warn("Unable to connect to StatusService. Retrying...")

                    t += 1
                    time.sleep(0.5)

            if self.service is not None:
                self.menu.addSeparator()

                for d in devices:
                    devices[d].getHistory(self.service)

                    menu = DeviceMenu(devices[d].menu_text, self.menu, d, devices[d].history, devices[d].index)
                    self.menu.addMenu(menu)
                    menu.update()


        self.menu.addSeparator()
        self.menu.addAction(self.__tr("HP Device Manager..."), self.toolboxTriggered)

        self.menu.addSeparator()

        self.settings_action = self.menu.addAction(QIcon(load_pixmap('settings', '16x16')),
                                    self.__tr("Settings..."),  self.settingsTriggered)

        self.menu.addSeparator()
        self.menu.addAction(QIcon(load_pixmap('quit', '16x16')), "Quit", self.quitTriggered)
        self.tray_icon.setContextMenu(self.menu)




    def settingsTriggered(self):
        if self.menu is None:
            return

        self.sendMessage('', '', EVENT_DEVICE_STOP_POLLING)
#        sys_conf
        cur_vers = sys_conf.get('hplip', 'version')
        self.user_settings.load()
        installed_time =time.strftime("%d-%m-%Y", time.localtime(self.user_settings.upgrade_last_update_time))
        if utils.Is_HPLIP_older_version(cur_vers, self.user_settings.latest_available_version):
            if int(time.time()) < self.user_settings.upgrade_pending_update_time :
                postponed_time =time.strftime("%d-%m-%Y", time.localtime(self.user_settings.upgrade_pending_update_time))
                upgrade_msg ="HPLIP-%s version was installed on %s.\n\nNew version of HPLIP-%s is available for upgrade. HPLIP upgrade is scheduled on %s." %(cur_vers,installed_time , self.user_settings.latest_available_version, postponed_time)
            elif self.user_settings.upgrade_last_update_time:
                upgrade_msg ="HPLIP-%s version was installed on %s.\n\nNew version of HPLIP-%s is available for upgrade." %(cur_vers,installed_time , self.user_settings.latest_available_version)
            else:
                upgrade_msg ="HPLIP-%s version was installed.\n\nNew version of HPLIP-%s is available for upgrade." %(cur_vers, self.user_settings.latest_available_version)
        elif self.user_settings.upgrade_last_update_time:
            upgrade_msg ="HPLIP-%s version was installed on %s."%(cur_vers, installed_time)
        else: 
            upgrade_msg ="HPLIP-%s version was installed."%(cur_vers)
            
        
        try:
            dlg = SystraySettingsDialog(self.menu, self.user_settings.systray_visible,
                                        self.user_settings.polling, self.user_settings.polling_interval,
                                        self.user_settings.systray_messages,
                                        self.user_settings.polling_device_list,
                                        self.user_settings.upgrade_notify,
                                        self.user_settings.upgrade_pending_update_time,
                                        self.user_settings.upgrade_last_update_time,
                                        upgrade_msg)


            if dlg.exec_() == QDialog.Accepted:
                self.user_settings.systray_visible = dlg.systray_visible
                self.user_settings.systray_messages = dlg.systray_messages
                self.user_settings.upgrade_notify = dlg.upgrade_notify
        
                log.debug("HPLIP update  notification = %d"%(self.user_settings.upgrade_notify))
                self.user_settings.save()

                if self.user_settings.systray_visible == SYSTRAY_VISIBLE_SHOW_ALWAYS:
                    log.debug("Showing...")
                    self.tray_icon.setVisible(True)

                else:
                    log.debug("Waiting to hide...")
                    QTimer.singleShot(HIDE_INACTIVE_DELAY, self.timeoutHideWhenInactive)

                self.sendMessage('', '', EVENT_USER_CONFIGURATION_CHANGED)

        finally:
            self.sendMessage('', '', EVENT_DEVICE_START_POLLING)


    def timeoutHideWhenInactive(self):
        log.debug("Hiding...")
        if self.user_settings.systray_visible in (SYSTRAY_VISIBLE_HIDE_WHEN_INACTIVE, SYSTRAY_VISIBLE_HIDE_ALWAYS):
            self.tray_icon.setVisible(False)
            log.debug("Hidden")


    def updateMenu(self):
        if self.menu is None:
            return
        for a in self.menu.actions():
            try:
                a.menu().update()
            except AttributeError:
                continue



    def trayActivated(self, reason):
        if reason == QSystemTrayIcon.Context:
            self.updateMenu()


        elif reason == QSystemTrayIcon.DoubleClick:
            #print "double click"
            self.toolboxTriggered()
            pass

        elif reason == QSystemTrayIcon.Trigger:
            #print "single click"
            pass

        elif reason == QSystemTrayIcon.MiddleClick:
            #print "middle click"
            pass


    def messageClicked(self):
        #print "\nPARENT: message clicked"
        pass


    def quitTriggered(self):
        log.debug("Exiting")
        self.sendMessage('', '', EVENT_SYSTEMTRAY_EXIT)
        self.quit()
        del self.tray_icon

    def toolboxTriggered(self):
        try:
            os.waitpid(-1, os.WNOHANG)
        except OSError:
            pass

        # See if it is already running...
        ok, lock_file = utils.lock_app('hp-toolbox', True)

        if ok: # able to lock, not running...
            utils.unlock(lock_file)

            path = utils.which('hp-toolbox')
            if path:
                path = os.path.join(path, 'hp-toolbox')
            else:
                self.tray_icon.showMessage(self.__tr("HPLIP Status Service"),
                                self.__tr("Unable to locate hp-toolbox on system PATH."),
                                QSystemTrayIcon.Critical, TRAY_MESSAGE_DELAY)

                log.error("Unable to find hp-toolbox on PATH.")
                return

            #log.debug(path)
            log.debug("Running hp-toolbox: hp-toolbox")
            os.spawnlp(os.P_NOWAIT, path, 'hp-toolbox')

        else: # ...already running, raise it
            self.sendMessage('', '', EVENT_RAISE_DEVICE_MANAGER, interface='com.hplip.Toolbox')


    def sendMessage(self, device_uri, printer_name, event_code, username=prop.username,
                    job_id=0, title='', pipe_name='', interface='com.hplip.StatusService'):
        #device.Event(device_uri, printer_name, event_code, username, job_id, title).send_via_dbus(SessionBus(), interface)
        device.Event(device_uri, printer_name, event_code, username, job_id, title).send_via_dbus(self.session_bus, interface)


    def notifierActivated(self, s):
        m = ''
        while True:
            try:
                r, w, e = select.select([self.read_pipe], [], [self.read_pipe], 1.0)
            except select.error:
                log.debug("Error in select()")
                break

            if e:
                log.error("Pipe error: %s" % e)
                break

            if r:
                #m = ''.join([m, os.read(self.read_pipe, self.fmt_size)])
                m = os.read(self.read_pipe, self.fmt_size)
                while len(m) >= self.fmt_size:
                    event = device.Event(*[x.rstrip(b'\x00').decode('utf-8') if isinstance(x, bytes) else x for x in struct.unpack(self.fmt, m[:self.fmt_size])])
                    m = m[self.fmt_size:]
                    
                    if event.event_code == EVENT_CUPS_QUEUES_REMOVED or event.event_code == EVENT_CUPS_QUEUES_ADDED:
                        self.resetDevice()
                        for d in device.getSupportedCUPSDevices(back_end_filter=['hp', 'hpfax']):
                            self.addDevice(d)
                            
                        self.setMenu()

                    if event.event_code == EVENT_USER_CONFIGURATION_CHANGED:
                        log.debug("Re-reading configuration (EVENT_USER_CONFIGURATION_CHANGED)")
                        self.user_settings.load()
                        self.user_settings.debug()

                    elif event.event_code == EVENT_SYSTEMTRAY_EXIT:
                        self.quit()
                        return

                    if self.user_settings.systray_visible in \
                        (SYSTRAY_VISIBLE_SHOW_ALWAYS, SYSTRAY_VISIBLE_HIDE_WHEN_INACTIVE):
                        
                        log.debug("Showing...")
                        self.tray_icon.setVisible(True)

                        if event.event_code == EVENT_DEVICE_UPDATE_ACTIVE:
                            if not self.active_icon:
                                self.tray_icon.setIcon(self.prop_active_icon)
                                self.active_icon = True
                            continue

                        elif event.event_code == EVENT_DEVICE_UPDATE_INACTIVE:
                            if self.active_icon:
                                self.tray_icon.setIcon(self.prop_icon)
                                self.active_icon = False
                            continue

                        elif event.event_code == EVENT_DEVICE_UPDATE_BLIP:
                            if not self.active_icon:
                                self.tray_icon.setIcon(self.prop_active_icon)
                                self.active_icon = True
                                QTimer.singleShot(BLIP_DELAY, self.blipTimeout)
                            continue

                    if self.user_settings.systray_visible in (SYSTRAY_VISIBLE_HIDE_WHEN_INACTIVE, SYSTRAY_VISIBLE_HIDE_ALWAYS):
                        log.debug("Waiting to hide...")
                        QTimer.singleShot(HIDE_INACTIVE_DELAY, self.timeoutHideWhenInactive)

                    if event.event_code <= EVENT_MAX_USER_EVENT or \
                        event.event_code == EVENT_CUPS_QUEUES_REMOVED or event.event_code == EVENT_CUPS_QUEUES_ADDED:

                        if event.event_code != EVENT_CUPS_QUEUES_REMOVED:
                            self.addDevice(event.device_uri)
                            self.setMenu()

                        if self.tray_icon.supportsMessages():

                            log.debug("Tray icon message:")
                            event.debug()

                            error_state = STATUS_TO_ERROR_STATE_MAP.get(event.event_code, ERROR_STATE_CLEAR)
                            desc = device.queryString(event.event_code)

                            show_message = False
                            if self.user_settings.systray_messages == SYSTRAY_MESSAGES_SHOW_ALL: # OK, Busy
                                show_message = True

                            elif self.user_settings.systray_messages in (SYSTRAY_MESSAGES_SHOW_ERRORS_AND_WARNINGS, SYSTRAY_MESSAGES_SHOW_ERRORS_ONLY):
                                if error_state == ERROR_STATE_ERROR:
                                    show_message = True

                                elif self.user_settings.systray_messages == SYSTRAY_MESSAGES_SHOW_ERRORS_AND_WARNINGS and \
                                    error_state in (ERROR_STATE_WARNING, ERROR_STATE_LOW_SUPPLIES, ERROR_STATE_LOW_PAPER):

                                    show_message = True

                            if event.printer_name:
                                d = QString(event.printer_name)
                            else:
                                back_end, is_hp, bus, model, serial, dev_file, host, zc, port = \
                                                device.parseDeviceURI(event.device_uri)

                                if bus == 'usb':
                                    idd = serial
                                elif bus == 'net':
                                    idd = host
                                elif bus == 'par':
                                    idd = dev_file
                                else:
                                    idd = 'unknown'

                                self.model = models.normalizeModelUIName(model)

                                if back_end == 'hp':
                                    d = self.__tr("%s Printer (%s)"%(model,idd))

                                elif back_end == 'hpaio':
                                    d = self.__tr("%s Scanner (%s)"%(model,idd))

                                elif back_end == 'hpfax':
                                    d = self.__tr("%s Fax (%s)"%(model,idd))

                                else:
                                    d = self.__tr("%s (%s)"%(model,idd))

                            if show_message:
                                if have_pynotify and pynotify.init("hplip"): # Use libnotify/pynotify
                                    icon, urgency = ERROR_STATE_TO_ICON_AND_URGENCY_PYNOTIFY.get(error_state,
                                        (getPynotifyIcon('info'), pynotify.URGENCY_NORMAL))

                                    if event.job_id and event.title:
                                        msg = "%s\n%s: %s\n(%s/%s)" % (to_unicode(d), desc, event.title, event.username, event.job_id)
                                        log.debug("Notify: uri=%s desc=%s title=%s user=%s job_id=%d code=%d" %
                                                (event.device_uri, desc, event.title, event.username, event.job_id, event.event_code))
                                    else:
                                        msg = "%s\n%s (%s)" % (to_unicode(d), desc, event.event_code)
                                        log.debug("Notify: uri=%s desc=%s code=%d" % (event.device_uri, desc, event.event_code))

                                    n = pynotify.Notification("HPLIP Device Status", msg, icon)
                                    # CRID: 11833 Debian Traceback error notification exceeded
                                    n.set_hint('transient', True)
                                    n.set_urgency(urgency)

                                    if error_state == ERROR_STATE_ERROR:
                                        n.set_timeout(pynotify.EXPIRES_NEVER)
                                    else:
                                        n.set_timeout(TRAY_MESSAGE_DELAY)

                                    n.show()

                                else: # Use "standard" message bubbles
                                    icon = ERROR_STATE_TO_ICON.get(error_state, QSystemTrayIcon.Information)
                                    if event.job_id and event.title:
                                        log.debug("Bubble: uri=%s desc=%s title=%s user=%s job_id=%d code=%d" %
                                                (event.device_uri, desc, event.title, event.username, event.job_id, event.event_code))
                                        self.tray_icon.showMessage(self.__tr("HPLIP Device Status"),
                                            QString("%s\n%s: %s\n(%s/%s)"%(d,desc, event.title,event.username,event.job_id)),
                                            icon, TRAY_MESSAGE_DELAY)

                                    else:
                                        log.debug("Bubble: uri=%s desc=%s code=%d" % (event.device_uri, desc, event.event_code))
                                        self.tray_icon.showMessage(self.__tr("HPLIP Device Status"),
                                            QString("%s\n%s (%s)"%(d,desc,event.event_code)),
                                            icon, TRAY_MESSAGE_DELAY)

            else:
                break


    def blipTimeout(self):
        if self.active_icon:
            self.tray_icon.setIcon(self.prop_icon)
            self.active_icon = False



    def __tr(self, s, c=None):
        return QApplication.translate("SystemTray", s, c, QApplication.UnicodeUTF8)
コード例 #23
0
ファイル: main.py プロジェクト: daju1-ros/qt_gui_core
    def main(self, argv=None, standalone=None):
        # check if DBus is available
        try:
            import dbus
            del dbus
            self._dbus_available = True
        except ImportError:
            pass

        if argv is None:
            argv = sys.argv

        # extract --args and everything behind manually since argparse can not handle that
        arguments = argv[1:]
        args = []
        if '--args' in arguments:
            index = arguments.index('--args')
            args = arguments[index + 1:]
            arguments = arguments[0:index + 1]

        if standalone:
            arguments += ['-s', standalone]

        parser = ArgumentParser('usage: %prog [options]')
        self._add_arguments(parser)
        self._options = parser.parse_args(arguments)
        self._options.args = args

        # check option dependencies
        try:
            if self._options.args and not self._options.standalone_plugin and not self._options.command_start_plugin and not self._options.embed_plugin:
                raise RuntimeError(
                    'Option --args can only be used together with either --standalone, --command-start-plugin or --embed-plugin option'
                )

            list_options = (self._options.list_perspectives,
                            self._options.list_plugins)
            list_options_set = [
                opt for opt in list_options if opt is not False
            ]
            if len(list_options_set) > 1:
                raise RuntimeError(
                    'Only one --list-* option can be used at a time')

            command_options = (self._options.command_start_plugin,
                               self._options.command_switch_perspective)
            command_options_set = [
                opt for opt in command_options if opt is not None
            ]
            if len(command_options_set) > 0 and not self._dbus_available:
                raise RuntimeError(
                    'Without DBus support the --command-* options are not available'
                )
            if len(command_options_set) > 1:
                raise RuntimeError(
                    'Only one --command-* option can be used at a time (except --command-pid which is optional)'
                )
            if len(command_options_set
                   ) == 0 and self._options.command_pid is not None:
                raise RuntimeError(
                    'Option --command_pid can only be used together with an other --command-* option'
                )

            embed_options = (self._options.embed_plugin,
                             self._options.embed_plugin_serial,
                             self._options.embed_plugin_address)
            embed_options_set = [
                opt for opt in embed_options if opt is not None
            ]
            if len(command_options_set) > 0 and not self._dbus_available:
                raise RuntimeError(
                    'Without DBus support the --embed-* options are not available'
                )
            if len(embed_options_set) > 0 and len(embed_options_set) < len(
                    embed_options):
                raise RuntimeError(
                    'Missing option(s) - all \'--embed-*\' options must be set'
                )

            if len(embed_options_set) > 0 and self._options.clear_config:
                raise RuntimeError(
                    'Option --clear-config can only be used without any --embed-* option'
                )

            groups = (list_options_set, command_options_set, embed_options_set)
            groups_set = [opt for opt in groups if len(opt) > 0]
            if len(groups_set) > 1:
                raise RuntimeError(
                    'Options from different groups (--list, --command, --embed) can not be used together'
                )

        except RuntimeError as e:
            print(str(e))
            #parser.parse_args(['--help'])
            # calling --help will exit
            return 1

        # set implicit option dependencies
        if self._options.standalone_plugin is not None:
            self._options.lock_perspective = True

        # use qt/glib mainloop integration to get dbus mainloop working
        if self._dbus_available:
            from dbus.mainloop.glib import DBusGMainLoop
            from dbus import DBusException, Interface, SessionBus
            DBusGMainLoop(set_as_default=True)

        # create application context containing various relevant information
        from .application_context import ApplicationContext
        context = ApplicationContext()
        context.options = self._options

        # non-special applications provide various dbus interfaces
        if self._dbus_available:
            context.provide_app_dbus_interfaces = len(groups_set) == 0
            context.dbus_base_bus_name = 'org.ros.qt_gui'
            if context.provide_app_dbus_interfaces:
                context.dbus_unique_bus_name = context.dbus_base_bus_name + '.pid%d' % os.getpid(
                )

                # provide pid of application via dbus
                from .application_dbus_interface import ApplicationDBusInterface
                _dbus_server = ApplicationDBusInterface(
                    context.dbus_base_bus_name)

        # determine host bus name, either based on pid given on command line or via dbus application interface if any other instance is available
        if len(command_options_set) > 0 or len(embed_options_set) > 0:
            host_pid = None
            if self._options.command_pid is not None:
                host_pid = self._options.command_pid
            else:
                try:
                    remote_object = SessionBus().get_object(
                        context.dbus_base_bus_name, '/Application')
                except DBusException:
                    pass
                else:
                    remote_interface = Interface(
                        remote_object,
                        context.dbus_base_bus_name + '.Application')
                    host_pid = remote_interface.get_pid()
            if host_pid is not None:
                context.dbus_host_bus_name = context.dbus_base_bus_name + '.pid%d' % host_pid

        # execute command on host application instance
        if len(command_options_set) > 0:
            if self._options.command_start_plugin is not None:
                try:
                    remote_object = SessionBus().get_object(
                        context.dbus_host_bus_name, '/PluginManager')
                except DBusException:
                    (rc,
                     msg) = (1,
                             'unable to communicate with GUI instance "%s"' %
                             context.dbus_host_bus_name)
                else:
                    remote_interface = Interface(
                        remote_object,
                        context.dbus_base_bus_name + '.PluginManager')
                    (rc, msg) = remote_interface.start_plugin(
                        self._options.command_start_plugin,
                        ' '.join(self._options.args))
                if rc == 0:
                    print('qt_gui_main() started plugin "%s" in GUI "%s"' %
                          (msg, context.dbus_host_bus_name))
                else:
                    print(
                        'qt_gui_main() could not start plugin "%s" in GUI "%s": %s'
                        % (self._options.command_start_plugin,
                           context.dbus_host_bus_name, msg))
                return rc
            elif self._options.command_switch_perspective is not None:
                remote_object = SessionBus().get_object(
                    context.dbus_host_bus_name, '/PerspectiveManager')
                remote_interface = Interface(
                    remote_object,
                    context.dbus_base_bus_name + '.PerspectiveManager')
                remote_interface.switch_perspective(
                    self._options.command_switch_perspective)
                print(
                    'qt_gui_main() switched to perspective "%s" in GUI "%s"' %
                    (self._options.command_switch_perspective,
                     context.dbus_host_bus_name))
                return 0
            raise RuntimeError('Unknown command not handled')

        # choose selected or default qt binding
        setattr(sys, 'SELECT_QT_BINDING', self._options.qt_binding)
        from python_qt_binding import QT_BINDING

        from python_qt_binding.QtCore import qDebug, qInstallMsgHandler, QSettings, Qt, QtCriticalMsg, QtDebugMsg, QtFatalMsg, QTimer, QtWarningMsg
        from python_qt_binding.QtGui import QAction, QApplication, QIcon, QMenuBar

        from .about_handler import AboutHandler
        from .composite_plugin_provider import CompositePluginProvider
        from .help_provider import HelpProvider
        from .main_window import MainWindow
        from .perspective_manager import PerspectiveManager
        from .plugin_manager import PluginManager

        def message_handler(type_, msg):
            colored_output = 'TERM' in os.environ and 'ANSI_COLORS_DISABLED' not in os.environ
            cyan_color = '\033[36m' if colored_output else ''
            red_color = '\033[31m' if colored_output else ''
            reset_color = '\033[0m' if colored_output else ''
            if type_ == QtDebugMsg and self._options.verbose:
                print(msg, file=sys.stderr)
            elif type_ == QtWarningMsg:
                print(cyan_color + msg + reset_color, file=sys.stderr)
            elif type_ == QtCriticalMsg:
                print(red_color + msg + reset_color, file=sys.stderr)
            elif type_ == QtFatalMsg:
                print(red_color + msg + reset_color, file=sys.stderr)
                sys.exit(1)

        qInstallMsgHandler(message_handler)

        app = QApplication(argv)
        app.setAttribute(Qt.AA_DontShowIconsInMenus, False)

        self.__check_icon_theme_compliance()

        if len(embed_options_set) == 0:
            settings = QSettings(QSettings.IniFormat, QSettings.UserScope,
                                 'ros.org', self._settings_filename)
            if self._options.clear_config:
                settings.clear()

            main_window = MainWindow()
            main_window.setDockNestingEnabled(True)
            main_window.statusBar()

            def sigint_handler(*args):
                qDebug('\nsigint_handler()')
                main_window.close()

            signal.signal(signal.SIGINT, sigint_handler)
            # the timer enables triggering the sigint_handler
            timer = QTimer()
            timer.start(500)
            timer.timeout.connect(lambda: None)

            # create own menu bar to share one menu bar on Mac
            menu_bar = QMenuBar()
            menu_bar.setNativeMenuBar(False)
            if not self._options.lock_perspective:
                main_window.setMenuBar(menu_bar)

            file_menu = menu_bar.addMenu(menu_bar.tr('File'))
            action = QAction(file_menu.tr('Quit'), file_menu)
            action.setIcon(QIcon.fromTheme('application-exit'))
            action.triggered.connect(main_window.close)
            file_menu.addAction(action)

        else:
            app.setQuitOnLastWindowClosed(False)

            settings = None
            main_window = None
            menu_bar = None

        self._add_plugin_providers()

        # setup plugin manager
        plugin_provider = CompositePluginProvider(self.plugin_providers)
        plugin_manager = PluginManager(plugin_provider, context)

        if self._options.list_plugins:
            # output available plugins
            print('\n'.join(sorted(plugin_manager.get_plugins().values())))
            return 0

        help_provider = HelpProvider()
        plugin_manager.plugin_help_signal.connect(
            help_provider.plugin_help_request)

        # setup perspective manager
        if settings is not None:
            perspective_manager = PerspectiveManager(settings, context)

            if self._options.list_perspectives:
                # output available perspectives
                print('\n'.join(sorted(perspective_manager.perspectives)))
                return 0
        else:
            perspective_manager = None

        if main_window is not None:
            plugin_manager.set_main_window(main_window, menu_bar)

        if settings is not None and menu_bar is not None:
            perspective_menu = menu_bar.addMenu(menu_bar.tr('Perspectives'))
            perspective_manager.set_menu(perspective_menu)

        # connect various signals and slots
        if perspective_manager is not None and main_window is not None:
            # signal changed perspective to update window title
            perspective_manager.perspective_changed_signal.connect(
                main_window.perspective_changed)
            # signal new settings due to changed perspective
            perspective_manager.save_settings_signal.connect(
                main_window.save_settings)
            perspective_manager.restore_settings_signal.connect(
                main_window.restore_settings)
            perspective_manager.restore_settings_without_plugin_changes_signal.connect(
                main_window.restore_settings)

        if perspective_manager is not None and plugin_manager is not None:
            perspective_manager.save_settings_signal.connect(
                plugin_manager.save_settings)
            plugin_manager.save_settings_completed_signal.connect(
                perspective_manager.save_settings_completed)
            perspective_manager.restore_settings_signal.connect(
                plugin_manager.restore_settings)
            perspective_manager.restore_settings_without_plugin_changes_signal.connect(
                plugin_manager.restore_settings_without_plugins)

        if plugin_manager is not None and main_window is not None:
            # signal before changing plugins to save window state
            plugin_manager.plugins_about_to_change_signal.connect(
                main_window.save_setup)
            # signal changed plugins to restore window state
            plugin_manager.plugins_changed_signal.connect(
                main_window.restore_state)
            # signal save settings to store plugin setup on close
            main_window.save_settings_before_close_signal.connect(
                plugin_manager.close_application)
            # signal save and shutdown called for all plugins, trigger closing main window again
            plugin_manager.close_application_signal.connect(
                main_window.close, type=Qt.QueuedConnection)

        if main_window is not None and menu_bar is not None:
            about_handler = AboutHandler(main_window)
            help_menu = menu_bar.addMenu(menu_bar.tr('Help'))
            action = QAction(file_menu.tr('About'), help_menu)
            action.setIcon(QIcon.fromTheme('help-about'))
            action.triggered.connect(about_handler.show)
            help_menu.addAction(action)

        # set initial size - only used without saved configuration
        if main_window is not None:
            main_window.resize(600, 450)
            main_window.move(100, 100)

        # ensure that qt_gui/src is in sys.path
        src_path = os.path.realpath(
            os.path.join(os.path.dirname(__file__), '..'))
        if src_path not in sys.path:
            sys.path.append(src_path)

        # load specific plugin
        plugin = None
        plugin_serial = None
        if self._options.embed_plugin is not None:
            plugin = self._options.embed_plugin
            plugin_serial = self._options.embed_plugin_serial
        elif self._options.standalone_plugin is not None:
            plugin = self._options.standalone_plugin
            plugin_serial = 0
        if plugin is not None:
            plugins = plugin_manager.find_plugins_by_name(plugin)
            if len(plugins) == 0:
                print('qt_gui_main() found no plugin matching "%s"' % plugin)
                return 1
            elif len(plugins) > 1:
                print(
                    'qt_gui_main() found multiple plugins matching "%s"\n%s' %
                    (plugin, '\n'.join(plugins.values())))
                return 1
            plugin = plugins.keys()[0]

        qDebug('QtBindingHelper using %s' % QT_BINDING)

        plugin_manager.discover()

        self._caching_hook()

        if self._options.reload_import:
            qDebug(
                'ReloadImporter() automatically reload all subsequent imports')
            from .reload_importer import ReloadImporter
            _reload_importer = ReloadImporter()
            self._add_reload_paths(_reload_importer)
            _reload_importer.enable()

        # switch perspective
        if perspective_manager is not None:
            if not plugin:
                perspective_manager.set_perspective(self._options.perspective)
            else:
                perspective_manager.set_perspective(
                    plugin, hide_and_without_plugin_changes=True)

        # load specific plugin
        if plugin:
            plugin_manager.load_plugin(plugin, plugin_serial,
                                       self._options.args)

        if main_window is not None:
            main_window.show()

        return app.exec_()
コード例 #24
0
class TelepathyPlugin(gobject.GObject):
    __gsignals__ = {
        'contacts-online':
            # Contacts in the subscribe list have come online.
            # args:
            #   contact identification (based on key ID or JID): list of str
            #   contact handle: list of int or long
            #   contact identifier (JID): list of str or unicode
            (gobject.SIGNAL_RUN_FIRST, None, [object, object, object]),
        'contacts-offline':
            # Contacts in the subscribe list have gone offline.
            # args: iterable over contact handles
            (gobject.SIGNAL_RUN_FIRST, None, [object]),
        'status':
            # Connection status changed.
            # args: status, reason as for Telepathy StatusChanged
            (gobject.SIGNAL_RUN_FIRST, None, [int, int]),
        'activity-invitation':
            # We were invited to join an activity
            # args:
            #   activity room: Channel
            #   activity room handle: int or long
            #   inviter contact handle: int or long
            #   message: unicode
            (gobject.SIGNAL_RUN_FIRST, None, [object] * 4),
        'private-invitation':
            # We were invited to join a chat or a media call
            # args:
            #   channel object path
            (gobject.SIGNAL_RUN_FIRST, None, [object, str]),
        'want-to-connect':
            # The TelepathyPlugin wants to connect. presenceservice.py will
            # call the start() method if that's OK with its policy.
            (gobject.SIGNAL_RUN_FIRST, None, []),
    }

    _RECONNECT_INITIAL_TIMEOUT = 5000    # 5 seconds
    _RECONNECT_MAX_TIMEOUT = 300000      # 5 minutes
    _TP_CONN_MANAGER = 'gabble'
    _PROTOCOL = 'jabber'

    def __init__(self, registry, owner):
        """Initialize the ServerPlugin instance

        :Parameters:
            `registry` : telepathy.client.ManagerRegistry
                From the PresenceService, used to find the connection
                manager details
            `owner` : buddy.GenericOwner
                The Buddy representing the owner of this XO (normally a
                buddy.ShellOwner instance)
        """
        gobject.GObject.__init__(self)

        #: The connection, a `telepathy.client.Connection`
        self._conn = None

        #: List of dbus-python SignalMatch objects representing signal match
        #: rules associated with the connection, so we don't leak the match
        #: rules when disconnected.
        self._matches = []

        #: The manager registry, a `telepathy.client.ManagerRegistry`
        self._registry = registry

        #: set of contact handles: those for whom we've emitted contacts-online
        self._online_contacts = set()

        #: The owner, a `buddy.GenericOwner`
        self._owner = owner
        #: The owner's handle on this connection
        self.self_handle = None
        #: The owner's identifier (e.g. JID) on this connection
        self.self_identifier = None

        #: The connection's status
        self._conn_status = CONNECTION_STATUS_DISCONNECTED

        #: GLib source ID indicating when we may try to reconnect
        self._backoff_id = 0

        #: length of the next reconnect timeout
        self._reconnect_timeout = self._RECONNECT_INITIAL_TIMEOUT

        #: The ``subscribe`` channel: a `telepathy.client.Channel` or None
        self._subscribe_channel = None
        #: The members of the ``subscribe`` channel
        self._subscribe_members = set()
        #: The local-pending members of the ``subscribe`` channel
        self._subscribe_local_pending = set()
        #: The remote-pending members of the ``subscribe`` channel
        self._subscribe_remote_pending = set()

        #: The ``publish`` channel: a `telepathy.client.Channel` or None
        self._publish_channel = None

        self._session_bus = SessionBus()
        self._init_connection()

    @property
    def status(self):
        """Return the Telepathy connection status."""
        return self._conn_status

    def get_connection(self):
        """Retrieve our telepathy.client.Connection object"""
        return self._conn

    def suggest_room_for_activity(self, activity_id):
        """Suggest a room to use to share the given activity.
        """
        return activity_id

    def identify_contacts(self, tp_chan, handles, identifiers=None):
        raise NotImplementedError

    def _init_connection(self):
        """Set up our connection

        if there is no existing connection
            (_find_existing_connection returns None)
        produce a new connection with our protocol for our
        account.

        if there is an existing connection, reuse it by
        registering for various of events on it.
        """
        _logger.debug('%r: init connection', self)
        conn = self._find_existing_connection()
        if not conn:
            _logger.debug('%r: no existing connection', self)
            return

        m = conn[CONN_INTERFACE].connect_to_signal('StatusChanged',
           self._handle_connection_status_change)
        self._matches.append(m)
        m = conn[CONN_INTERFACE].connect_to_signal('NewChannel',
                                                   self._new_channel_cb)
        self._matches.append(m)
        self._watch_conn_name = self._session_bus.watch_name_owner(
            conn.service_name, self._watch_conn_name_cb)

        self._conn = conn

        status = self._conn.GetStatus()
        self._handle_connection_status_change(status, CONNECTION_STATUS_REASON_NONE_SPECIFIED)

    def _find_existing_connection(self):
        raise NotImplementedError

    def _watch_conn_name_cb(self, dbus_name):
        """Check if we still have a connection on the DBus session bus.

        If the connection disappears, stop the plugin.
        """
        if not dbus_name and self._conn is not None:
            _logger.warning(
                'D-Bus name %s disappeared, this probably means %s crashed',
                self._conn.service_name, self._TP_CONN_MANAGER)
            self._handle_connection_status_change(
                CONNECTION_STATUS_DISCONNECTED, 
                CONNECTION_STATUS_REASON_NONE_SPECIFIED)

    def _handle_connection_status_change(self, status, reason):
        if status == self._conn_status:
            return

        if status == CONNECTION_STATUS_CONNECTING:
            self._conn_status = status
            _logger.debug("%r: connecting...", self)
        elif status == CONNECTION_STATUS_CONNECTED:
            self._conn_status = status
            _logger.debug("%r: connected", self)
            self._connected_cb()
        elif status == CONNECTION_STATUS_DISCONNECTED:
            self._conn = None
            _logger.debug("%r: disconnected (reason %r)", self, reason)
            if reason == CONNECTION_STATUS_REASON_AUTHENTICATION_FAILED:
                # FIXME: handle connection failure; retry later?
                _logger.debug("%r: authentification failed. Give up ", self)

        self.emit('status', self._conn_status, int(reason))

    def _could_connect(self):
        # Don't allow connection unless the reconnect timeout has elapsed,
        # or this is the first attempt
        return (self._backoff_id == 0)

    def _contacts_offline(self, handles):
        """Handle contacts going offline (send message, update set)"""
        self._online_contacts -= handles
        _logger.debug('%r: Contacts now offline: %r', self, handles)
        self.emit("contacts-offline", handles)

    def _inspect_handles_one_by_one(self, handle_type, handles):
        jids = []

        for handle in handles:
            try:
                jid = self._conn[CONN_INTERFACE].InspectHandles(handle_type,
                     [handle])
            except (InvalidArgument, InvalidHandle):
                continue
            else:
                jids.append(jid[0])

        return jids

    def _handle_is_channel_specific(self, handle):
        raise NotImplementedError

    def _contacts_online(self, handles):
        """Handle contacts coming online"""
        relevant = []

        for handle in handles:
            if handle == self.self_handle:
                # ignore network events for Owner property changes since those
                # are handled locally
                pass
            elif (handle in self._subscribe_members or
                  handle in self._subscribe_local_pending or
                  handle in self._subscribe_remote_pending or
                  not self._handle_is_channel_specific(handle)):
                relevant.append(handle)
            # else it's probably a channel-specific handle - can't create a
            # Buddy object for those yet

        if not relevant:
            return

        try:
            jids = self._conn[CONN_INTERFACE].InspectHandles(
                    HANDLE_TYPE_CONTACT, relevant)
        except (InvalidArgument, InvalidHandle):
            # InspectHandles failed so discard invalid handles by trying to
            # inspect them one by one.
            # FIXME: the Contacts interface should offer a proper way to do this
            jids = self._inspect_handles_one_by_one(HANDLE_TYPE_CONTACT,
                                                    relevant)
            if not jids:
                return

        handle_to_objid = self.identify_contacts(None, relevant, jids)
        objids = []
        for handle in relevant:
            objids.append(handle_to_objid[handle])

        self._online_contacts |= frozenset(relevant)
        _logger.debug('%r: Contacts now online:', self)
        for handle, objid in izip(relevant, objids):
            _logger.debug('  %u .../%s', handle, objid)
        self.emit('contacts-online', objids, relevant, jids)

    def _subscribe_members_changed_cb(self, message, added, removed,
                                      local_pending, remote_pending,
                                      actor, reason):

        added = set(added)
        removed = set(removed)
        local_pending = set(local_pending)
        remote_pending = set(remote_pending)

        affected = added|removed
        affected |= local_pending
        affected |= remote_pending

        self._subscribe_members -= affected
        self._subscribe_members |= added
        self._subscribe_local_pending -= affected
        self._subscribe_local_pending |= local_pending
        self._subscribe_remote_pending -= affected
        self._subscribe_remote_pending |= remote_pending

    def _publish_members_changed_cb(self, message, added, removed,
            local_pending, remote_pending, actor, reason):
        pass

    def _presence_update_cb(self, presence):
        """Send update for online/offline status of presence"""

        now_online = set()
        now_offline = set(presence.iterkeys())

        for handle in presence:
            timestamp, statuses = presence[handle]
            for status, params in statuses.items():
                # FIXME: use correct logic involving the GetStatuses method
                if status in ["available", "away", "brb", "busy", "dnd", "xa"]:
                    now_online.add(handle)
                    now_offline.discard(handle)

        now_online -= self._online_contacts
        now_offline &= self._online_contacts

        if now_online:
            self._contacts_online(now_online)
        if now_offline:
            self._contacts_offline(now_offline)

    def _new_channel_cb(self, object_path, channel_type, handle_type, handle,
                        suppress_handler):
        """Handle creation of a new channel
        """
        if (handle_type == HANDLE_TYPE_ROOM and
            channel_type == CHANNEL_TYPE_TEXT):

            def ready(channel):
                # workaround for odd behaviour of nested scopes
                room_self = []

                def got_lpwi(info):
                    for invitee, actor, reason, message in info:
                        if ((invitee == room_self[0]
                             or invitee == self.self_handle)
                            and reason == CHANNEL_GROUP_CHANGE_REASON_INVITED):
                            self.emit('activity-invitation', channel, handle,
                                      actor, message)
                def got_lpwi_err(e):
                    _logger.warning('Unable to get channel members for %s:',
                                    object_path, exc_info=1)

                def got_self_handle(self_handle):
                    room_self.append(self_handle)
                    group.GetLocalPendingMembersWithInfo(
                            reply_handler=got_lpwi,
                            error_handler=got_lpwi_err)
                def got_self_handle_err(e):
                    _logger.warning('Unable to get self-handle for %s:',
                                    object_path, exc_info=1)

                group = channel[CHANNEL_INTERFACE_GROUP]
                group.GetSelfHandle(reply_handler=got_self_handle,
                                    error_handler=got_self_handle_err)

            # we throw away the channel as soon as ready() finishes
            Channel(self._conn.service_name, object_path,
                    ready_handler=ready)

        elif (handle_type == HANDLE_TYPE_CONTACT and
              channel_type in (CHANNEL_TYPE_TEXT,
                               CHANNEL_TYPE_STREAMED_MEDIA)):
            self.emit("private-invitation", object_path, channel_type)

        elif (handle_type == HANDLE_TYPE_LIST and
              channel_type == CHANNEL_TYPE_CONTACT_LIST):
            name = self._conn.InspectHandles(handle_type, [handle])[0]
            channel = Channel(self._conn.service_name, object_path)

            if name == 'publish':
                self._publish_channel_cb(channel)
            elif name == 'subscribe':
                self._subscribe_channel_cb(channel)

    def _publish_channel_cb(self, channel):
        # the group of contacts who may receive your presence
        self._publish_channel = channel
        m = channel[CHANNEL_INTERFACE_GROUP].connect_to_signal(
                'MembersChanged', self._publish_members_changed_cb)
        self._matches.append(m)

    def _subscribe_channel_cb(self, channel):
        if self._subscribe_channel is not None:
            return
        # the group of contacts for whom you wish to receive presence
        self._subscribe_channel = channel
        m = channel[CHANNEL_INTERFACE_GROUP].connect_to_signal(
                'MembersChanged', self._subscribe_members_changed_cb)
        self._matches.append(m)
        subscribe_handles, subscribe_lp, subscribe_rp = \
                channel[CHANNEL_INTERFACE_GROUP].GetAllMembers()
        self._subscribe_members = set(subscribe_handles)
        self._subscribe_local_pending = set(subscribe_lp)
        self._subscribe_remote_pending = set(subscribe_rp)

        if CONN_INTERFACE_PRESENCE in self._conn:
            # request presence for everyone we're subscribed to
            self._conn[CONN_INTERFACE_PRESENCE].RequestPresence(
                    subscribe_handles)

    def _connected_cb(self):
        """Callback on successful connection to a server
        """
        # FIXME: cope with CMs that lack some of the interfaces
        # FIXME: cope with CMs with no 'publish' or 'subscribe'

        # FIXME: retry if getting the channel times out

        interfaces = self._conn.get_valid_interfaces()

        # FIXME: this is a hack, but less harmful than the previous one -
        # the next version of telepathy-python will contain a better fix
        for iface in self._conn[CONN_INTERFACE].GetInterfaces():
            interfaces.add(iface)

        # FIXME: do this async?
        self.self_handle = self._conn[CONN_INTERFACE].GetSelfHandle()
        self.self_identifier = self._conn[CONN_INTERFACE].InspectHandles(
                HANDLE_TYPE_CONTACT, [self.self_handle])[0]

        if CONN_INTERFACE_PRESENCE in self._conn:
            # Ask to be notified about presence changes
            m = self._conn[CONN_INTERFACE_PRESENCE].connect_to_signal(
                    'PresenceUpdate', self._presence_update_cb)
            self._matches.append(m)
        else:
            _logger.warning('%s does not support Connection.Interface.'
                            'Presence', self._conn.object_path)

        properties = {
                CHANNEL + '.ChannelType': CHANNEL_TYPE_CONTACT_LIST,
                CHANNEL + '.TargetHandleType': HANDLE_TYPE_LIST,
                CHANNEL + '.TargetID': 'subscribe',
                }
        properties = dbus.Dictionary(properties, signature='sv')
        connection = self._conn[CONNECTION_INTERFACE_REQUESTS]
        is_ours, channel_path, properties = connection.EnsureChannel(properties)

        channel = Channel(self._conn.service_name, channel_path)
        self._subscribe_channel_cb(channel)
コード例 #25
0
ファイル: jsprog.py プロジェクト: ivaradi/jsprog

def makeCommandFun(clazz):
    return lambda _args: clazz


#------------------------------------------------------------------------------

if __name__ == "__main__":
    mainParser = argparse.ArgumentParser(
        prog="jsprog",
        description="Command-line interface for the JSProg daemon")

    subParsers = mainParser.add_subparsers(
        title="commands", description="the commands the program accepts")

    for clazz in [
            GetJoysticks, GetJoystickState, LoadProfile, Monitor,
            MonitorControls, Stop, GUI
    ]:
        parser = clazz.addParser(subParsers)
        parser.set_defaults(func=makeCommandFun(clazz))

    args = mainParser.parse_args(sys.argv[1:])

    #try:
    connection = SessionBus(mainloop=DBusGMainLoop())
    args.func(args).execute(connection, args)
    #except Exception, e:
    #    print str(e)
コード例 #26
0
ファイル: posix_dbus.py プロジェクト: brianhlin/htcondor
class _ISkypeAPI(_ISkypeAPIBase):
    def __init__(self, handler, opts):
        _ISkypeAPIBase.__init__(self, opts)
        self.RegisterHandler(handler)
        self.skype_in = self.skype_out = self.dbus_name_owner_watch = None
        self.bus = opts.pop('Bus', None)
        try:
            mainloop = opts.pop('MainLoop')
            if self.bus is not None:
                raise TypeError('Bus and MainLoop cannot be used at the same time!')
        except KeyError:
            if self.bus is None:
                import dbus.mainloop.glib
                import gobject
                gobject.threads_init()
                dbus.mainloop.glib.threads_init()
                mainloop = dbus.mainloop.glib.DBusGMainLoop()
                self.mainloop = gobject.MainLoop()
        if self.bus is None:
            from dbus import SessionBus
            self.bus = SessionBus(private=True, mainloop=mainloop)
        if opts:
            raise TypeError('Unexpected parameter(s): %s' % ', '.join(opts.keys()))

    def run(self):
        self.DebugPrint('thread started')
        if hasattr(self, 'mainloop'):
            self.mainloop.run()
        self.DebugPrint('thread finished')

    def Close(self):
        if hasattr(self, 'mainloop'):
            self.mainloop.quit()
        self.skype_in = self.skype_out = None
        if self.dbus_name_owner_watch is not None:
            self.bus.remove_signal_receiver(self.dbus_name_owner_watch)
        self.dbus_name_owner_watch = None
        self.DebugPrint('closed')

    def SetFriendlyName(self, FriendlyName):
        self.FriendlyName = FriendlyName
        if self.skype_out:
            self.SendCommand(ICommand(-1, 'NAME %s' % FriendlyName))

    def StartWatcher(self):
        self.dbus_name_owner_watch = self.bus.add_signal_receiver(self.dbus_name_owner_changed,
            'NameOwnerChanged',
            'org.freedesktop.DBus',
            'org.freedesktop.DBus',
            '/org/freedesktop/DBus',
            arg0='com.Skype.API')

    def __Attach_ftimeout(self):
        self.wait = False

    def Attach(self, Timeout=30000, Wait=True):
        try:
            if not self.isAlive():
                self.StartWatcher()
                self.start()
        except AssertionError:
            pass
        try:
            self.wait = True
            t = threading.Timer(Timeout / 1000.0, self.__Attach_ftimeout)
            if Wait:
                t.start()
            while self.wait:
                if not Wait:
                    self.wait = False
                try:
                    if not self.skype_out:
                        self.skype_out = self.bus.get_object('com.Skype.API', '/com/Skype')
                    if not self.skype_in:
                        self.skype_in = _SkypeNotifyCallback(self.bus, self.notify)
                except dbus.DBusException:
                    if not Wait:
                        break
                    time.sleep(1.0)
                else:
                    break
            else:
                raise ISkypeAPIError('Skype attach timeout')
        finally:
            t.cancel()
        c = ICommand(-1, 'NAME %s' % self.FriendlyName, '', True, Timeout)
        if self.skype_out:
            self.SendCommand(c)
        if c.Reply != 'OK':
            self.skype_out = None
            self.SetAttachmentStatus(apiAttachRefused)
            return
        self.SendCommand(ICommand(-1, 'PROTOCOL %s' % self.Protocol))
        self.SetAttachmentStatus(apiAttachSuccess)

    def IsRunning(self):
        try:
            self.bus.get_object('com.Skype.API', '/com/Skype')
            return True
        except dbus.DBusException:
            return False

    def Start(self, Minimized=False, Nosplash=False):
        # options are not supported as of Skype 1.4 Beta for Linux
        if not self.IsRunning():
            import os
            if os.fork() == 0: # we're child
                os.setsid()
                os.execlp('skype')

    def Shutdown(self):
        import os
        from signal import SIGINT
        fh = os.popen('ps -o %p --no-heading -C skype')
        pid = fh.readline().strip()
        fh.close()
        if pid:
            os.kill(int(pid), SIGINT)
            self.skype_in = self.skype_out = None

    def SendCommand(self, Command):
        if not self.skype_out:
            self.Attach(Command.Timeout)
        self.CommandsStackPush(Command)
        self.CallHandler('send', Command)
        com = u'#%d %s' % (Command.Id, Command.Command)
        self.DebugPrint('->', repr(com))
        if Command.Blocking:
            Command._event = event = threading.Event()
        else:
            Command._timer = timer = threading.Timer(Command.Timeout / 1000.0, self.CommandsStackPop, (Command.Id,))
        try:
            result = self.skype_out.Invoke(com)
        except dbus.DBusException, err:
            raise ISkypeAPIError(str(err))
        if result.startswith(u'#%d ' % Command.Id):
            self.notify(result)
        if Command.Blocking:
            event.wait(Command.Timeout / 1000.0)
            if not event.isSet():
                raise ISkypeAPIError('Skype command timeout')
        else:
            timer.start()
コード例 #27
0
ファイル: Globals.py プロジェクト: mystilleef/scribes
# -*- coding: utf-8 -*-
from os import environ
from os.path import join, expanduser
from dbus import SessionBus, Interface, glib
from xdg.BaseDirectory import xdg_config_home, xdg_data_home
SCRIBES_DBUS_SERVICE = "net.sourceforge.Scribes"
SCRIBES_DBUS_PATH = "/net/sourceforge/Scribes"
SCRIBES_SAVE_PROCESS_DBUS_SERVICE = "net.sourceforge.ScribesSaveProcess"
SCRIBES_SAVE_PROCESS_DBUS_PATH = "/net/sourceforge/ScribesSaveProcess"
session_bus = SessionBus()
dbus_proxy_obj = session_bus.get_object('org.freedesktop.DBus',
                                        '/org/freedesktop/DBus')
dbus_iface = Interface(dbus_proxy_obj, 'org.freedesktop.DBus')
home_folder = expanduser("~")
from tempfile import gettempdir
tmp_folder = gettempdir()
folder_ = join(home_folder, "Desktop")
from os.path import exists
desktop_folder = folder_ if exists(folder_) else home_folder
metadata_folder = config_folder = join(xdg_config_home, "scribes")
print_settings_filename = join(metadata_folder, "ScribesPrintSettings.txt")
home_plugin_folder = home_generic_plugin_folder = join(config_folder,
                                                       "GenericPlugins")
home_language_plugin_folder = join(config_folder, "LanguagePlugins")
scribes_theme_folder = join(config_folder, "styles")
storage_folder = join(config_folder, ".config")
default_home_theme_folder = join(xdg_data_home, "gtksourceview-2.0", "styles")
name = "scribes"
prefix = "/usr"
executable_path = join(prefix, "bin")
data_path = "/usr/share"
コード例 #28
0
def main():
    ap = argparse.ArgumentParser()
    ap.add_argument('--debug', action='store_true')
    ap.add_argument('--sound', dest='sound_spec', action='append', help='registers a sound for a specific filter with format <filter-name>:<file-path> or use format <file-path> for everything')
    ap.add_argument('--filter', dest='filters', action='append', choices=FILTERS.keys())
    ap.add_argument('--player', default=DEFAULT_PLAYER)
    ap.add_argument('--rate-ms', type=int, default=DEFAULT_RATE_MS)
    params = ap.parse_args()

    logging.basicConfig(
        datefmt='%H:%M:%S',
        format='%(asctime)s %(levelname)5s - %(message)s',
        level='DEBUG' if params.debug else 'INFO',
        stream=sys.stdout,
    )

    LOG.debug('build sound registry: %s', params.sound_spec)

    sounds = {'*': DEFAULT_SOUND}
    if params.sound_spec:
        for spec in params.sound_spec:
            spec = spec.strip()  # type: str
            m = PATTERN_SOUNDSPEC.match(spec)
            if m:
                key = m.group('name').lower()
                value = m.group('path')

                if key not in FILTERS:
                    ap.error('unknown filter %r in sound spec %r' % (key, spec))
                    return
            else:
                key = '*'
                value = spec

            if not os.access(value, os.R_OK):
                ap.error('audio file %r cannot be read in sound spec %r' % (value, spec))
                return

            sounds[key] = value

    LOG.debug('sound registry: %s', sounds)

    LOG.debug('check audio player')

    if not os.access(params.player, os.R_OK | os.X_OK):
        ap.error('player %r does not exist or is not executable' % (params.player,))

    LOG.debug('initialize dbus')

    DBusGMainLoop(set_as_default=True)
    bus = SessionBus()

    filter_keys = tuple(sorted(set(params.filters if params.filters else FILTERS.keys())))

    subscribe_to_messages(bus, filter_keys)
    audio_player = AudioPlayer(params.player, sounds, params.rate_ms)
    attach_message_handler(bus, audio_player, filter_keys)

    LOG.info('ONLINE')

    loop = GLib.MainLoop()
    try:
        loop.run()
    except KeyboardInterrupt:
        loop.quit()
コード例 #29
0
from dbus import SessionBus, Interface
import gobject
from dbus.mainloop.glib import DBusGMainLoop


def handler(*args, **kwargs):
    if 'RemoteVolumeMonitor' in kwargs[
            'dbus_interface'] and 'VolumeAdded' in kwargs['DriveChanged']:
        print "-" * 30
        print kwargs
        print args
        lproperties = []
        lproperties = args
        for prop in lproperties:
            print prop


DBusGMainLoop(set_as_default=True)
bus = SessionBus()

bus.add_signal_receiver(handler_function=handler,
                        interface_keyword="dbus_interface",
                        member_keyword="DriveChanged",
                        dbus_interface="org.gtk.Private.RemoteVolumeMonitor")

# Start Loop
loop = gobject.MainLoop()
loop.run()
コード例 #30
0
ファイル: client.py プロジェクト: MarvinMuuss/webradio-1
class Client(GObject):
    (STATE_INITIALIZED,
     STATE_STATIONS_LOADED,
     STATE_CHANNELS_LOADED) = range(3)

    __gtype_name__ = 'WebRadioClient'

    __gsignals__ = {
        'station-added':       (SIGNAL_RUN_LAST, TYPE_NONE, (object,)),
        'channel-added':       (SIGNAL_RUN_LAST, TYPE_NONE, (object,)),
        'state-changed':       (SIGNAL_RUN_LAST, TYPE_NONE, ()),
        'stream-tags-changed': (SIGNAL_RUN_LAST, TYPE_NONE, ()),
    }

    @staticmethod
    def decode_stream(uri, title, length):
        return Stream(uri, title, length)

    @classmethod
    def decode_channel(cls, station, uri, tags, streams):
        streams = [cls.decode_stream(*s) for s in streams]
        return Channel(station, uri, tags, streams)

    def __init__(self):
        super(Client, self).__init__()

        self.__stations = dict()
        self.__channels = dict()
        self.__stream_tags = dict()

        self.__current_channel = None
        self.__is_playing = False

        def register_channel(station, channel):
            if station:
                station.channels.append(channel)

            for stream in channel.streams:
                self.__channels[stream.uri] = channel

            self.__channels[channel.uri] = channel

        def station_added_cb(station):
            id, title, uri, channels = station
            station = Station(id, title, uri)

            for channel in channels:
                channel = self.decode_channel(station, *channel)
                register_channel(station, channel)

            self.__stations[station.id] = station
            self.emit('station-added', station)

        def channel_added_cb(station_id, channel):
            station = self.find_station(station_id)
            channel = self.decode_channel(station, *channel)
            register_channel(station, channel)
            self.emit('channel-added', channel)

        def state_changed_cb(playing, stream_uri):
            self.__stream_tags = self.__service.GetStreamTags()
            self.__current_channel = self.__channels.get(stream_uri)
            self.__is_playing = playing
            self.emit('state-changed')

        def stream_tags_changed_cb(tags):
            self.__stream_tags.update(tags)
            self.emit('stream-tags-changed')

        def name_owner_cb(new_owner):
            if not new_owner:
                # FIXME
                from gtk import main_quit
                main_quit()

        self.__bus = SessionBus()
        proxy = self.__bus.get_object(Service.name, '/')
        self.__bus.watch_name_owner(Service.name, name_owner_cb)
        self.__service = Interface(proxy, Service.interface)
        self.__service.connect_to_signal('StationAdded',      station_added_cb)
        self.__service.connect_to_signal('ChannelAdded',      channel_added_cb)
        self.__service.connect_to_signal('StateChanged',      state_changed_cb)
        self.__service.connect_to_signal('StreamTagsChanged', stream_tags_changed_cb)

        for station in self.__service.GetStations():
            station_added_cb(station)

        state_changed_cb(*self.__service.GetState())

    def wait(self, stage=STATE_CHANNELS_LOADED):
        loop = MainLoop(None, True)

        def data_ready_cb(new_stage):
            if new_stage >= stage:
                loop.quit()

        self.__service.connect_to_signal('DataReady', data_ready_cb)

        if self.__service.GetDataStage() >= stage:
            loop.quit()

        progress_id = 0

        if loop.is_running():
            if sys.stdout.isatty():
                progress = ['-\r', '\\\r', '|\r', '/\r']

                def progress_cb():
                    c = progress.pop(0)
                    sys.stdout.write(c)
                    sys.stdout.flush()
                    progress.append(c)
                    return True

                progress_id = timeout_add(250, progress_cb)
                sys.stdout.write('  loading...\r')

            loop.run()

        if progress_id:
            source_remove(progress_id)
            sys.stdout.write('\r\033[K')
            sys.stdout.flush()

    def find_channels(self, query=[]):
        result = list()

        for station_id, channel in self.__service.Find(query):
            station = self.__stations.get(station_id)
            channel = self.decode_channel(station, *channel)
            result.append(channel)

        return result

    def find_station(self, id):
        return self.__stations.get(id)
    def get_stations(self):
        return self.__stations.values()

    def get_tags(self):
        return self.__service.GetTags()

    def play(self, channel):
        self.__service.Play(channel.streams[0].uri)

    def pause(self):
        self.__service.Pause()

    def resume(self):
        self.__service.Resume()

    def quit(self):
        self.__service.Quit()

    def get_equalizer_profiles(self):
        return self.__service.ListEqualizerProfiles()
    def __get_equalizer_profile(self):
        return self.__service.GetEqualizerProfile()
    def __set_equalizer_profile(self, value):
        self.__service.SetEqualizerProfile(value)

    is_playing = property(fget=lambda self: self.__is_playing)
    current_channel = property(fget=lambda self: self.__current_channel)
    stream_tags = property(fget=lambda self: self.__stream_tags)
    equalizer_profile = property(fget=__get_equalizer_profile, fset=__set_equalizer_profile)
コード例 #31
0
    def send(self, body, title='', notify_type=NotifyType.INFO, **kwargs):
        """
        Perform DBus Notification
        """

        if not self._enabled or MAINLOOP_MAP[self.schema] is None:
            self.logger.warning("{} notifications could not be loaded.".format(
                self.schema))
            return False

        # Acquire our session
        session = SessionBus(mainloop=MAINLOOP_MAP[self.schema])

        # acquire our dbus object
        dbus_obj = session.get_object(
            NOTIFY_DBUS_INTERFACE,
            NOTIFY_DBUS_SETTING_LOCATION,
        )

        # Acquire our dbus interface
        dbus_iface = Interface(
            dbus_obj,
            dbus_interface=NOTIFY_DBUS_INTERFACE,
        )

        # image path
        icon_path = None if not self.include_image \
            else self.image_path(notify_type, extension='.ico')

        # Our meta payload
        meta_payload = {"urgency": Byte(self.urgency)}

        if not (self.x_axis is None and self.y_axis is None):
            # Set x/y access if these were set
            meta_payload['x'] = self.x_axis
            meta_payload['y'] = self.y_axis

        if NOTIFY_DBUS_IMAGE_SUPPORT and icon_path:
            try:
                # Use Pixbuf to create the proper image type
                image = GdkPixbuf.Pixbuf.new_from_file(icon_path)

                # Associate our image to our notification
                meta_payload['icon_data'] = (image.get_width(),
                                             image.get_height(),
                                             image.get_rowstride(),
                                             image.get_has_alpha(),
                                             image.get_bits_per_sample(),
                                             image.get_n_channels(),
                                             ByteArray(image.get_pixels()))

            except Exception as e:
                self.logger.warning(
                    "Could not load Gnome notification icon ({}): {}".format(
                        icon_path, e))

        try:
            # Always call throttle() before any remote execution is made
            self.throttle()

            dbus_iface.Notify(
                # Application Identifier
                self.app_id,
                # Message ID (0 = New Message)
                0,
                # Icon (str) - not used
                '',
                # Title
                str(title),
                # Body
                str(body),
                # Actions
                list(),
                # Meta
                meta_payload,
                # Message Timeout
                self.message_timeout_ms,
            )

            self.logger.info('Sent DBus notification.')

        except Exception:
            self.logger.warning('Failed to send DBus notification.')
            self.logger.exception('DBus Exception')
            return False

        return True
コード例 #32
0
ファイル: unity.py プロジェクト: sousaakira/unity7
def get_dbus_proxy_object():
    return SessionBus().get_object(UNITY_BUS_NAME, DEBUG_PATH)
コード例 #33
0

class Server(SingleTestsImpl, TestsImpl, SignalTestsImpl):
    def triggered_by_client(self, parameter1, parameter2, sender, sender_path):
        # Called when the client emits TestSignals.Trigger from any object.
        logger.info('signal/callback: Triggered by client (%s:%s): (%r,%r)',
                    sender, sender_path, parameter1, parameter2)
        tested_things.add(INTERFACE_SIGNAL_TESTS + '.Trigger')
        dbus.Interface(dbus.SessionBus().get_object(sender, sender_path),
                       INTERFACE_CALLBACK_TESTS).Response(
                           parameter1, parameter2)
        logger.info('signal/callback: Sent Response')


if __name__ == '__main__':
    bus = SessionBus()
    bus_name = BusName(CROSS_TEST_BUS_NAME, bus=bus)
    loop = gobject.MainLoop()
    obj = Server(bus_name, CROSS_TEST_PATH, loop.quit)
    objects[CROSS_TEST_PATH] = obj
    kwargs = {}
    if is_py2:
        kwargs['utf8_strings'] = True
    bus.add_signal_receiver(obj.triggered_by_client,
                            signal_name='Trigger',
                            dbus_interface=INTERFACE_SIGNAL_TESTS,
                            named_service=None,
                            path=None,
                            sender_keyword='sender',
                            path_keyword='sender_path',
                            **kwargs)
コード例 #34
0
        for s in self.__stations:
            for c in s.channels:
                for t in c.tags:
                    tags[t] = True

            tags[s.id] = True

        tags = list(tags)
        tags.sort()

        return tags

    @method(dbus_interface=interface, in_signature='', out_signature='as')
    def ListEqualizerProfiles(self):
        return self.__player.get_profile_names()

    @method(dbus_interface=interface, in_signature='', out_signature='s')
    def GetEqualizerProfile(self):
        return self.__player.profile

    @method(dbus_interface=interface, in_signature='s', out_signature='')
    def SetEqualizerProfile(self, profile_name):
        self.__player.profile = profile_name


if '__main__' == __name__:
    threads_init()
    DBusGMainLoop(set_as_default=True)
    Service(SessionBus()).run()
コード例 #35
0
    def __new__(cls, name, bus=None, allow_replacement=False , replace_existing=False, do_not_queue=False):
        """Constructor, which may either return an existing cached object
        or a new object.

        :Parameters:
            `name` : str
                The well-known name to be advertised
            `bus` : dbus.Bus
                A Bus on which this service will be advertised.

                Omitting this parameter or setting it to None has been
                deprecated since version 0.82.1. For backwards compatibility,
                if this is done, the global shared connection to the session
                bus will be used.

            `allow_replacement` : bool
                If True, other processes trying to claim the same well-known
                name will take precedence over this one.
            `replace_existing` : bool
                If True, this process can take over the well-known name
                from other processes already holding it.
            `do_not_queue` : bool
                If True, this service will not be placed in the queue of
                services waiting for the requested name if another service
                already holds it.
        """
        validate_bus_name(name, allow_well_known=True, allow_unique=False)

        # if necessary, get default bus (deprecated)
        if bus is None:
            import warnings
            warnings.warn('Omitting the "bus" parameter to '
                          'dbus.service.BusName.__init__ is deprecated',
                          DeprecationWarning, stacklevel=2)
            bus = SessionBus()

        # see if this name is already defined, return it if so
        # FIXME: accessing internals of Bus
        if name in bus._bus_names:
            return bus._bus_names[name]

        # otherwise register the name
        name_flags = (
            (allow_replacement and _dbus_bindings.NAME_FLAG_ALLOW_REPLACEMENT or 0) |
            (replace_existing and _dbus_bindings.NAME_FLAG_REPLACE_EXISTING or 0) |
            (do_not_queue and _dbus_bindings.NAME_FLAG_DO_NOT_QUEUE or 0))

        retval = bus.request_name(name, name_flags)

        # TODO: more intelligent tracking of bus name states?
        if retval == _dbus_bindings.REQUEST_NAME_REPLY_PRIMARY_OWNER:
            pass
        elif retval == _dbus_bindings.REQUEST_NAME_REPLY_IN_QUEUE:
            # queueing can happen by default, maybe we should
            # track this better or let the user know if they're
            # queued or not?
            pass
        elif retval == _dbus_bindings.REQUEST_NAME_REPLY_EXISTS:
            raise NameExistsException(name)
        elif retval == _dbus_bindings.REQUEST_NAME_REPLY_ALREADY_OWNER:
            # if this is a shared bus which is being used by someone
            # else in this process, this can happen legitimately
            pass
        else:
            raise RuntimeError('requesting bus name %s returned unexpected value %s' % (name, retval))

        # and create the object
        bus_name = object.__new__(cls)
        bus_name._bus = bus
        bus_name._name = name

        # cache instance (weak ref only)
        # FIXME: accessing Bus internals again
        bus._bus_names[name] = bus_name

        return bus_name
コード例 #36
0
ファイル: systemtray.py プロジェクト: Alberto-Beralix/Beralix
class SystemTrayApp(QApplication):
    def __init__(self, args, read_pipe):
        QApplication.__init__(self, args)

        self.menu = None
        self.read_pipe = read_pipe
        self.fmt = "80s80sI32sI80sf"
        self.fmt_size = struct.calcsize(self.fmt)
        self.timer_active = False
        self.active_icon = False
        self.user_settings = UserSettings()
        self.user_settings.load()
        self.user_settings.debug()

        self.tray_icon = QSystemTrayIcon()

        pm = load_pixmap("hp_logo", "32x32")
        self.prop_icon = QIcon(pm)

        a = load_pixmap('active', '16x16')
        painter = QPainter(pm)
        painter.drawPixmap(32, 0, a)
        painter.end()

        self.prop_active_icon = QIcon(pm)

        self.tray_icon.setIcon(self.prop_icon)

        self.session_bus = SessionBus()
        self.service = None

        for d in device.getSupportedCUPSDevices(back_end_filter=['hp', 'hpfax']):
            self.addDevice(d)

        self.tray_icon.setToolTip(self.__tr("HPLIP Status Service"))
        QObject.connect(self.tray_icon, SIGNAL("messageClicked()"), self.messageClicked)
        notifier = QSocketNotifier(self.read_pipe, QSocketNotifier.Read)
        QObject.connect(notifier, SIGNAL("activated(int)"), self.notifierActivated)
        QObject.connect(self.tray_icon, SIGNAL("activated(QSystemTrayIcon::ActivationReason)"), self.trayActivated)
        self.tray_icon.show()

        if self.user_settings.systray_visible == SYSTRAY_VISIBLE_SHOW_ALWAYS:
            self.tray_icon.setVisible(True)
        else:
            QTimer.singleShot(HIDE_INACTIVE_DELAY, self.timeoutHideWhenInactive) # show icon for awhile @ startup

        self.tray_icon.setIcon(self.prop_active_icon)
        self.active_icon = True

        QTimer.singleShot(SET_MENU_DELAY, self.initDone)


    def initDone(self):
        self.tray_icon.setIcon(self.prop_icon)
        self.active_icon = False

        self.setMenu()


    def addDevice(self, device_uri):
        try:
            devices[device_uri]
        except KeyError:
            devices[device_uri] = HistoryDevice(device_uri)
        else:
            devices[device_uri].needs_update = True



    def setMenu(self):
        self.menu = QMenu()

        title = QAction(self.menu)
        #title.setDisabled(True)
        title.setText(self.__tr("HPLIP Status Service"))
        title.setIcon(self.prop_icon)
        title.setIconVisibleInMenu(True)
        self.menu.insertAction(None, title)

        if devices:
            if self.service is None:
                t = 0
                while t < 3:
                    try:
                        self.service = self.session_bus.get_object('com.hplip.StatusService',
                                                                  "/com/hplip/StatusService")
                    except DBusException:
                        log.warn("Unable to connect to StatusService. Retrying...")

                    t += 1
                    time.sleep(0.5)

            if self.service is not None:
                self.menu.addSeparator()

                for d in devices:
                    devices[d].getHistory(self.service)

                    menu = DeviceMenu(devices[d].menu_text, self.menu, d, devices[d].history, devices[d].index)
                    self.menu.addMenu(menu)
                    menu.update()


        self.menu.addSeparator()
        self.menu.addAction(self.__tr("HP Device Manager..."), self.toolboxTriggered)

        self.menu.addSeparator()

        self.settings_action = self.menu.addAction(QIcon(load_pixmap('settings', '16x16')),
                                    self.__tr("Settings..."),  self.settingsTriggered)

        self.menu.addSeparator()
        self.menu.addAction(QIcon(load_pixmap('quit', '16x16')), "Quit", self.quitTriggered)
        self.tray_icon.setContextMenu(self.menu)




    def settingsTriggered(self):
        if self.menu is None:
            return

        self.sendMessage('', '', EVENT_DEVICE_STOP_POLLING)
        try:
            dlg = SystraySettingsDialog(self.menu, self.user_settings.systray_visible,
                                        self.user_settings.polling, self.user_settings.polling_interval,
                                        self.user_settings.systray_messages,
                                        self.user_settings.polling_device_list)

            if dlg.exec_() == QDialog.Accepted:
                self.user_settings.systray_visible = dlg.systray_visible
                self.user_settings.systray_messages = dlg.systray_messages

                self.user_settings.save()

                if self.user_settings.systray_visible == SYSTRAY_VISIBLE_SHOW_ALWAYS:
                    log.debug("Showing...")
                    self.tray_icon.setVisible(True)

                else:
                    log.debug("Waiting to hide...")
                    QTimer.singleShot(HIDE_INACTIVE_DELAY, self.timeoutHideWhenInactive)

                self.sendMessage('', '', EVENT_USER_CONFIGURATION_CHANGED)

        finally:
            self.sendMessage('', '', EVENT_DEVICE_START_POLLING)


    def timeoutHideWhenInactive(self):
        log.debug("Hiding...")
        if self.user_settings.systray_visible in (SYSTRAY_VISIBLE_HIDE_WHEN_INACTIVE, SYSTRAY_VISIBLE_HIDE_ALWAYS):
            self.tray_icon.setVisible(False)
            log.debug("Hidden")


    def updateMenu(self):
        if self.menu is None:
            return
        for a in self.menu.actions():
            try:
                a.menu().update()
            except AttributeError:
                continue



    def trayActivated(self, reason):
        if reason == QSystemTrayIcon.Context:
            self.updateMenu()


        elif reason == QSystemTrayIcon.DoubleClick:
            #print "double click"
            self.toolboxTriggered()
            pass

        elif reason == QSystemTrayIcon.Trigger:
            #print "single click"
            self.updateMenu()
            if not self.menu is None:
                self.menu.popup(QCursor.pos())
            pass

        elif reason == QSystemTrayIcon.MiddleClick:
            #print "middle click"
            pass


    def messageClicked(self):
        #print "\nPARENT: message clicked"
        pass


    def quitTriggered(self):
        log.debug("Exiting")
        self.sendMessage('', '', EVENT_SYSTEMTRAY_EXIT)
        self.quit()
        del self.tray_icon

    def toolboxTriggered(self):
        try:
            os.waitpid(-1, os.WNOHANG)
        except OSError:
            pass

        # See if it is already running...
        ok, lock_file = utils.lock_app('hp-toolbox', True)

        if ok: # able to lock, not running...
            utils.unlock(lock_file)

            path = utils.which('hp-toolbox')
            if path:
                path = os.path.join(path, 'hp-toolbox')
            else:
                self.tray_icon.showMessage(self.__tr("HPLIP Status Service"),
                                self.__tr("Unable to locate hp-toolbox on system PATH."),
                                QSystemTrayIcon.Critical, TRAY_MESSAGE_DELAY)

                log.error("Unable to find hp-toolbox on PATH.")
                return

            #log.debug(path)
            log.debug("Running hp-toolbox: hp-toolbox")
            os.spawnlp(os.P_NOWAIT, path, 'hp-toolbox')

        else: # ...already running, raise it
            self.sendMessage('', '', EVENT_RAISE_DEVICE_MANAGER, interface='com.hplip.Toolbox')


    def sendMessage(self, device_uri, printer_name, event_code, username=prop.username,
                    job_id=0, title='', pipe_name='', interface='com.hplip.StatusService'):
        #device.Event(device_uri, printer_name, event_code, username, job_id, title).send_via_dbus(SessionBus(), interface)
        device.Event(device_uri, printer_name, event_code, username, job_id, title).send_via_dbus(self.session_bus, interface)


    def notifierActivated(self, s):
        m = ''
        while True:
            try:
                r, w, e = select.select([self.read_pipe], [], [self.read_pipe], 1.0)
            except select.error:
                log.debug("Error in select()")
                break

            if e:
                log.error("Pipe error: %s" % e)
                break

            if r:
                m = ''.join([m, os.read(self.read_pipe, self.fmt_size)])
                while len(m) >= self.fmt_size:
                    event = device.Event(*struct.unpack(self.fmt, m[:self.fmt_size]))

                    m = m[self.fmt_size:]

                    if event.event_code == EVENT_USER_CONFIGURATION_CHANGED:
                        log.debug("Re-reading configuration (EVENT_USER_CONFIGURATION_CHANGED)")
                        self.user_settings.load()
                        self.user_settings.debug()

                    elif event.event_code == EVENT_SYSTEMTRAY_EXIT:
                        self.quit()
                        return

                    if self.user_settings.systray_visible in \
                        (SYSTRAY_VISIBLE_SHOW_ALWAYS, SYSTRAY_VISIBLE_HIDE_WHEN_INACTIVE):

                        log.debug("Showing...")
                        self.tray_icon.setVisible(True)

                        if event.event_code == EVENT_DEVICE_UPDATE_ACTIVE:
                            if not self.active_icon:
                                self.tray_icon.setIcon(self.prop_active_icon)
                                self.active_icon = True
                            continue

                        elif event.event_code == EVENT_DEVICE_UPDATE_INACTIVE:
                            if self.active_icon:
                                self.tray_icon.setIcon(self.prop_icon)
                                self.active_icon = False
                            continue

                        elif event.event_code == EVENT_DEVICE_UPDATE_BLIP:
                            if not self.active_icon:
                                self.tray_icon.setIcon(self.prop_active_icon)
                                self.active_icon = True
                                QTimer.singleShot(BLIP_DELAY, self.blipTimeout)
                            continue

                    if self.user_settings.systray_visible in (SYSTRAY_VISIBLE_HIDE_WHEN_INACTIVE, SYSTRAY_VISIBLE_HIDE_ALWAYS):
                        log.debug("Waiting to hide...")
                        QTimer.singleShot(HIDE_INACTIVE_DELAY, self.timeoutHideWhenInactive)

                    if event.event_code <= EVENT_MAX_USER_EVENT:
                        self.addDevice(event.device_uri)
                        self.setMenu()

                        if self.tray_icon.supportsMessages():

                            log.debug("Tray icon message:")
                            event.debug()

                            error_state = STATUS_TO_ERROR_STATE_MAP.get(event.event_code, ERROR_STATE_CLEAR)
                            desc = device.queryString(event.event_code)

                            show_message = False
                            if self.user_settings.systray_messages == SYSTRAY_MESSAGES_SHOW_ALL: # OK, Busy
                                show_message = True

                            elif self.user_settings.systray_messages in (SYSTRAY_MESSAGES_SHOW_ERRORS_AND_WARNINGS, SYSTRAY_MESSAGES_SHOW_ERRORS_ONLY):
                                if error_state == ERROR_STATE_ERROR:
                                    show_message = True

                                elif self.user_settings.systray_messages == SYSTRAY_MESSAGES_SHOW_ERRORS_AND_WARNINGS and \
                                    error_state in (ERROR_STATE_WARNING, ERROR_STATE_LOW_SUPPLIES, ERROR_STATE_LOW_PAPER):

                                    show_message = True

                            if event.printer_name:
                                d = QString(event.printer_name)
                            else:
                                back_end, is_hp, bus, model, serial, dev_file, host, zc, port = \
                                                device.parseDeviceURI(event.device_uri)

                                if bus == 'usb':
                                    idd = serial
                                elif bus == 'net':
                                    idd = host
                                elif bus == 'par':
                                    idd = dev_file
                                else:
                                    idd = 'unknown'

                                self.model = models.normalizeModelUIName(model)

                                if back_end == 'hp':
                                    d = self.__tr("%1 Printer (%2)").arg(model).arg(idd)

                                elif back_end == 'hpaio':
                                    d = self.__tr("%1 Scanner (%2)").arg(model).arg(idd)

                                elif back_end == 'hpfax':
                                    d = self.__tr("%1 Fax (%2)").arg(model).arg(idd)

                                else:
                                    d = self.__tr("%1 (%2)").arg(model).arg(idd)

                            if show_message:
                                if have_pynotify and pynotify.init("hplip"): # Use libnotify/pynotify
                                    icon, urgency = ERROR_STATE_TO_ICON_AND_URGENCY_PYNOTIFY.get(error_state,
                                        (getPynotifyIcon('info'), pynotify.URGENCY_NORMAL))

                                    if event.job_id and event.title:
                                        msg = "%s\n%s: %s\n(%s/%s)" % (unicode(d), desc, event.title, event.username, event.job_id)
                                        log.debug("Notify: uri=%s desc=%s title=%s user=%s job_id=%d code=%d" %
                                                (event.device_uri, desc, event.title, event.username, event.job_id, event.event_code))
                                    else:
                                        msg = "%s\n%s (%s)" % (unicode(d), desc, event.event_code)
                                        log.debug("Notify: uri=%s desc=%s code=%d" % (event.device_uri, desc, event.event_code))

                                    n = pynotify.Notification("HPLIP Device Status", msg, icon)
                                    n.set_urgency(urgency)

                                    if error_state == ERROR_STATE_ERROR:
                                        n.set_timeout(pynotify.EXPIRES_NEVER)
                                    else:
                                        n.set_timeout(TRAY_MESSAGE_DELAY)

                                    n.show()

                                else: # Use "standard" message bubbles
                                    icon = ERROR_STATE_TO_ICON.get(error_state, QSystemTrayIcon.Information)
                                    if event.job_id and event.title:
                                        log.debug("Bubble: uri=%s desc=%s title=%s user=%s job_id=%d code=%d" %
                                                (event.device_uri, desc, event.title, event.username, event.job_id, event.event_code))
                                        self.tray_icon.showMessage(self.__tr("HPLIP Device Status"),
                                            QString("%1\n%2: %3\n(%4/%5)").\
                                            arg(d).\
                                            arg(desc).arg(event.title).\
                                            arg(event.username).arg(event.job_id),
                                            icon, TRAY_MESSAGE_DELAY)

                                    else:
                                        log.debug("Bubble: uri=%s desc=%s code=%d" % (event.device_uri, desc, event.event_code))
                                        self.tray_icon.showMessage(self.__tr("HPLIP Device Status"),
                                            QString("%1\n%2 (%3)").arg(d).\
                                            arg(desc).arg(event.event_code),
                                            icon, TRAY_MESSAGE_DELAY)

            else:
                break


    def blipTimeout(self):
        if self.active_icon:
            self.tray_icon.setIcon(self.prop_icon)
            self.active_icon = False



    def __tr(self, s, c=None):
        return QApplication.translate("SystemTray", s, c, QApplication.UnicodeUTF8)
コード例 #37
0
class SystemdBus(object):
    def __init__(self, user=False):
        self.bus = SessionBus() if user else SystemBus()
        systemd = self.bus.get_object(SYSTEMD_BUSNAME, SYSTEMD_PATH)
        self.manager = Interface(systemd,
                                 dbus_interface=SYSTEMD_MANAGER_INTERFACE)

    def get_unit_active_state(self, unit):
        unit = self.manager.LoadUnit(unit)
        unit_object = self.bus.get_object(SYSTEMD_BUSNAME, unit)
        unit_properties = Interface(unit_object, DBUS_INTERFACE)
        return unit_properties.Get(SYSTEMD_UNIT_INTERFACE, 'ActiveState')

    def get_unit_field_state(self, unit, field):
        unit = self.manager.LoadUnit(unit)
        unit_object = self.bus.get_object(SYSTEMD_BUSNAME, unit)
        unit_properties = Interface(unit_object, DBUS_INTERFACE)
        return unit_properties.Get(SYSTEMD_UNIT_INTERFACE, field)

    def get_unit_load_state(self, unit):
        unit = self.manager.LoadUnit(unit)
        unit_object = self.bus.get_object(SYSTEMD_BUSNAME, unit)
        unit_properties = Interface(unit_object, DBUS_INTERFACE)
        return unit_properties.Get(SYSTEMD_UNIT_INTERFACE, 'LoadState')

    def reload(self):
        self.manager.Reload()

    # In [31]: manager.DisableUnitFiles(["zabbix-agent.service"], False)
    # Out[31]: dbus.Array([dbus.Struct((dbus.String(u'unlink'), dbus.String(u'/etc/systemd/system/multi-user.target.wants/zabbix-agent.service'), dbus.String(u'')), signature=None)], signature=dbus.Signature('(sss)'))

    # In [33]: manager.EnableUnitFiles(["zabbix-agent.service"], False, True)
    # Out[33]:
    # (dbus.Boolean(True),
    #  dbus.Array([dbus.Struct((dbus.String(u'symlink'), dbus.String(u'/etc/systemd/system/multi-user.target.wants/zabbix-agent.service'), dbus.String(u'/usr/lib/systemd/system/zabbix-agent.service')), signature=None)], signature=dbus.Signature('(sss)')))

    def start_unit(self, unit):
        try:
            self.manager.StartUnit(unit, 'replace')
            return True
        except exceptions.DBusException:
            return False

    def stop_unit(self, unit):
        try:
            self.manager.StopUnit(unit, 'replace')
            return True
        except exceptions.DBusException:
            return False

    def restart_unit(self, unit):
        try:
            self.manager.RestartUnit(unit, 'replace')
            return True
        except exceptions.DBusException:
            return False

    def reload_unit(self, unit):
        try:
            self.manager.ReloadUnit(unit, 'replace')
            return True
        except exceptions.DBusException:
            return False

    def reload_or_restart_unit(self, unit):
        try:
            self.manager.ReloadOrRestartUnit(unit, 'replace')
            return True
        except exceptions.DBusException:
            return False
コード例 #38
0
ファイル: client.py プロジェクト: dineshkummarc/webradio
    def __init__(self):
        super(Client, self).__init__()

        self.__stations = dict()
        self.__channels = dict()
        self.__stream_tags = dict()

        self.__current_channel = None
        self.__is_playing = False

        def register_channel(station, channel):
            if station:
                station.channels.append(channel)

            for stream in channel.streams:
                self.__channels[stream.uri] = channel

            self.__channels[channel.uri] = channel

        def station_added_cb(station):
            id, title, uri, channels = station
            station = Station(id, title, uri)

            for channel in channels:
                channel = self.decode_channel(station, *channel)
                register_channel(station, channel)

            self.__stations[station.id] = station
            self.emit('station-added', station)

        def channel_added_cb(station_id, channel):
            station = self.find_station(station_id)
            channel = self.decode_channel(station, *channel)
            register_channel(station, channel)
            self.emit('channel-added', channel)

        def state_changed_cb(playing, stream_uri):
            self.__stream_tags = self.__service.GetStreamTags()
            self.__current_channel = self.__channels.get(stream_uri)
            self.__is_playing = playing
            self.emit('state-changed')

        def stream_tags_changed_cb(tags):
            self.__stream_tags.update(tags)
            self.emit('stream-tags-changed')

        def name_owner_cb(new_owner):
            if not new_owner:
                # FIXME
                from gtk import main_quit
                main_quit()

        self.__bus = SessionBus()
        proxy = self.__bus.get_object(Service.name, '/')
        self.__bus.watch_name_owner(Service.name, name_owner_cb)
        self.__service = Interface(proxy, Service.interface)
        self.__service.connect_to_signal('StationAdded', station_added_cb)
        self.__service.connect_to_signal('ChannelAdded', channel_added_cb)
        self.__service.connect_to_signal('StateChanged', state_changed_cb)
        self.__service.connect_to_signal('StreamTagsChanged',
                                         stream_tags_changed_cb)

        for station in self.__service.GetStations():
            station_added_cb(station)

        state_changed_cb(*self.__service.GetState())
コード例 #39
0
ファイル: audiobox.py プロジェクト: dhruvasagar/vim-audiobox
 def __init__(self):
     self.bus = SessionBus()
     self.init()
コード例 #40
0
class AutoPlayer:
    def __init__(self):
        # Diccionario para evitar los dobles escaneos producto de la emisión
        # de señales repetidas. Pasa porque Rhythmbox vuelve a escanear todos
        # los dispositivos cuando levanta por primera vez.
        self._already_scanned = {}

        # Se obtiene una conexión al bus de sistema
        self._system_bus = SystemBus()

        # Se obtiene una conexión al bus de sesión
        self._session_bus = SessionBus()

        # Conectar a las señales que emite de UDisks
        self._connect_to_udisks()

    def _connect_to_udisks(self):
        # Información de D-Bus para UDisks
        udisks_bus_name = 'org.freedesktop.UDisks'
        udisks_object_path = '/org/freedesktop/UDisks'
        udisks_dbus_interface = 'org.freedesktop.UDisks'

        # Se conecta la señal 'DeviceChanged' exportada por el objeto remoto
        # al manejador local de señales '_onDeviceChanged'.
        self._system_bus.add_signal_receiver(
            self._onDeviceChanged,
            signal_name='DeviceChanged',
            dbus_interface=udisks_dbus_interface,
            bus_name=udisks_bus_name,
            path=udisks_object_path)

        # Se conecta la señal 'DeviceRemoved' exportada por el objeto remoto
        # al manejador local de señales '_onDeviceRemoved'.
        self._system_bus.add_signal_receiver(
            self._onDeviceRemoved,
            signal_name='DeviceRemoved',
            dbus_interface=udisks_dbus_interface,
            bus_name=udisks_bus_name,
            path=udisks_object_path)

    def _onDeviceChanged(self, device_object_path):
        " La señal 'DeviceChanged' es emitida cuando se cambia el estado de un"
        " dispositivo (por ejemplo, cuando se monta o desmonta). UDisks envía "
        " el camino del objeto remoto del dispositivo que cambió de estado.   "
        print u'Un dispositivo cambió: %s' % device_object_path
        mount_path = self._get_device_mount_path(device_object_path)
        # Si no está montado o ya fue escaneado, no hacer nada y retornar
        if not mount_path:
            return
        playlist = self._get_playlist(mount_path)
        # Si no hay música en el dispositivo, no hacer nada y retornar
        if not playlist:
            return
        self._play(playlist)

    def _onDeviceRemoved(self, device_object_path):
        " La señal 'DeviceRemoved' es emitida cuando un dispositivo es   "
        " desconectado por hardware de la PC. UDisks envía el camino del "
        " objeto remoto del dispositivo."
        print u'Un dispositivo fue desconectado: %s' % device_object_path
        if device_object_path in self._already_scanned:
            del self._already_scanned[device_object_path]

    def _get_device_mount_path(self, device_object_path):
        # Información necesaria para procesar los dispositivos de UDisks
        udisks_bus_name = 'org.freedesktop.UDisks'
        device_dbus_interface = 'org.freedesktop.UDisks.Device'

        # Se obtiene el objeto remoto del dispositivo insertado a través
        # de la conexión al bus de sistema del demonio UDisks.
        device_object = self._system_bus.get_object(udisks_bus_name,
                                                    device_object_path)

        # Para acceder a las propiedades de un objeto FreeDesktop.org
        # establece una interfaz estándar: 'org.freedesktop.DBus.Properties'
        device = Interface(device_object, 'org.freedesktop.DBus.Properties')

        # Con el método 'Get' de la interfaz 'org.freedesktop.DBus.Properties'
        # se obtiene el valor de una propiedad en una interfaz determinada.

        # La propiedad 'DeviceFile' devuelve el archivo de dispositivo en /dev
        # En nuestro caso no lo necesitamos, se pone a modo de enseñanza.
        dev_file = device.Get(device_dbus_interface, 'DeviceFile')

        # La propiedad 'DeviceIsMounted' devuelve si está montado
        is_mounted = device.Get(device_dbus_interface, 'DeviceIsMounted')
        print u'¿Está montado %s? : %s' % (dev_file, str(bool(is_mounted)))

        # Si el dispositivo ya fue escaneado y no está montado, significa que
        # recién se desmontó, hay que olvidarlo.
        mount_path = None
        if device_object_path in self._already_scanned:
            if not is_mounted:
                del self._already_scanned[device_object_path]
        # Si no ha sido escaneado y está montado, significa que recién se
        # ha montado y hay que escanearlo y recordarlo, se devuelve el punto
        # de montaje. En otros casos, no se hace nada y no se devuelve nada.
        elif is_mounted:
            self._already_scanned[device_object_path] = True
            # La propiedad 'DeviceMountPaths' devuelve todos los directorios
            # del sistema de archivos donde se ha montado este dispositivo.
            mount_paths = device.Get(device_dbus_interface, 'DeviceMountPaths')
            mount_path = mount_paths[0]
        return mount_path

    def _get_playlist(self, directory_path):
        print u'Buscando música en el directorio %s' % directory_path
        playlist = []
        filenames = listdir(directory_path)
        for filename in filenames:
            path = join(directory_path, filename)
            if isfile(path):
                # Se obtiene el tipo MIME, ejemplo "audio/mpeg"
                mime_type = guess_type(path)[0]
                # Lo que interesa es la primera parte del tipo MIME
                category = mime_type.split('/')[0]
                if category == 'audio':
                    # El Playlist Manager de Rhythmbox espera URIs, por tanto..
                    uri = urljoin('file:', pathname2url(path))
                    playlist.append(uri)
        return playlist

    def _get_rhythmbox_playlist_manager(self):
        # Para modificar la lista de reproducción no hay MPRIS que valga :-(
        # Información de D-Bus para el Playlist Manager de Rhythmbox
        rhythmbox_bus_name = 'org.gnome.Rhythmbox3'
        playlist_mgr_object_path = '/org/gnome/Rhythmbox3/PlaylistManager'
        playlist_mgr_dbus_interface = 'org.gnome.Rhythmbox3.PlaylistManager'

        # Se obtiene el objeto remoto de Rhythmbox desde el bus de sesión
        playlist_mgr_obj = self._session_bus.get_object(
            rhythmbox_bus_name, playlist_mgr_object_path)

        # Esperar a que levante Rhythmbox... sí, ok, ya sé que esto es una
        # mala práctica. Lo correcto sería conectar a alguna señal remota que
        # avise de que está listo el reproductor, pero mejor no complicarse :-P
        sleep(5)

        playlist_manager = Interface(playlist_mgr_obj,
                                     playlist_mgr_dbus_interface)
        return playlist_manager

    def _get_rhythmbox_player(self):
        # Para controlar el reproductor, usaremos la interfaz estándar que
        # define FreeDestkop.org, es decir MPRIS

        # Información de D-Bus para Rhythmbox usando interfaz estándar MPRIS
        rhythmbox_bus_name = 'org.mpris.MediaPlayer2.rhythmbox'
        rhythmbox_object_path = '/org/mpris/MediaPlayer2'
        rhythmbox_dbus_interface_player = 'org.mpris.MediaPlayer2.Player'
        rhythmbox_dbus_interface_playlists = 'org.mpris.MediaPlayer2.Playlists'

        # Se obtiene el objeto remoto de Rhythmbox desde el bus de sesión
        rhythmbox_object = self._session_bus.get_object(
            rhythmbox_bus_name, rhythmbox_object_path)

        # Se obtiene la interfaz Player del objeto remoto del reproductor
        rhythmbox_player = Interface(rhythmbox_object,
                                     rhythmbox_dbus_interface_player)

        # Se obtiene la interfaz Playerlists del objeto remoto del reproductor
        rhythmbox_playlists = Interface(rhythmbox_object,
                                        rhythmbox_dbus_interface_playlists)

        # Se necesita obtener la cantidad de listas de reproducción contenidas
        # en el reproductor. Eso lo devuelve la propiedad "PlaylistCount"
        playlists_properties = Interface(rhythmbox_object,
                                         'org.freedesktop.DBus.Properties')
        pl_count = playlists_properties.Get(rhythmbox_dbus_interface_playlists,
                                            'PlaylistCount')

        return rhythmbox_player, rhythmbox_playlists, pl_count

    def _play(self, playlist):
        # Obtener el Playlist Manager de Rhythmbox
        playlist_manager = self._get_rhythmbox_playlist_manager()

        # Nombre estático para la lista de reproducción,
        # se llamará siempre "Autoplayer"
        playlist_name = 'Autoplayer'
        try:
            # Borrar la lista de reproducción si ya existe
            playlist_manager.DeletePlaylist(playlist_name)
        except:
            # Si no existe levanta excepción, la ignoramos
            pass
        # Crear una lista de reproducción nueva
        playlist_manager.CreatePlaylist(playlist_name)

        # Se adiciona cada archivo de música obtenido del dispositvo
        # de almacenamiento a la nueva lista de reproducción
        for uri in playlist:
            playlist_manager.AddToPlaylist(playlist_name, uri)

        # Obtenemos el reproductor y sus listas desde la interfaz MPRIS
        (rhythmbox_player, playlists_interface,
         playlists_count) = self._get_rhythmbox_player()

        # En un mundo ideal, Rhythmbox sería buenito y ordenaría las listas de
        # reproducción por fecha de creación en orden reverso como indica el
        # API de MPRIS, pero desgraciadamente no soporta esta funcionalidad,
        # así que hay que buscar a lo bestia... :-P :-(
        playlists = playlists_interface.GetPlaylists(0, playlists_count,
                                                     'CreationDate', True)

        # Buscando nuestra lista de reproducción a lo bestia... :-P
        i = 0
        while i < playlists_count and playlists[i][1] != playlist_name:
            i += 1
        if i < playlists_count:
            playlist_id = playlists[i][0]
        else:
            print >> stderr, u'Rhythmbox no cargó la lista correctamente.'
            return

        # Si se llega aquí, es que se encontró nuestra lista de reproducción
        # Detenemos cualquier reproducción previa para evitar mareadera :-P
        rhythmbox_player.Stop()

        # Activar la lista de reproducción como lista de reproducción actual
        playlists_interface.ActivatePlaylist(playlist_id)

        # Reproducir... :-)
        rhythmbox_player.Play()
コード例 #41
0
ファイル: NotifyDBus.py プロジェクト: xuduofeng/apprise
    def notify(self, title, body, notify_type, **kwargs):
        """
        Perform DBus Notification
        """

        if not self._enabled or MAINLOOP_MAP[self.schema] is None:
            self.logger.warning(
                "{} notifications could not be loaded.".format(self.schema))
            return False

        # Acquire our session
        session = SessionBus(mainloop=MAINLOOP_MAP[self.schema])

        # acquire our dbus object
        dbus_obj = session.get_object(
            NOTIFY_DBUS_INTERFACE,
            NOTIFY_DBUS_SETTING_LOCATION,
        )

        # Acquire our dbus interface
        dbus_iface = Interface(
            dbus_obj,
            dbus_interface=NOTIFY_DBUS_INTERFACE,
        )

        # image path
        icon_path = self.image_path(notify_type, extension='.ico')

        # Our meta payload
        meta_payload = {
            "urgency": Byte(self.urgency)
        }

        if not (self.x_axis is None and self.y_axis is None):
            # Set x/y access if these were set
            meta_payload['x'] = self.x_axis
            meta_payload['y'] = self.y_axis

        if NOTIFY_DBUS_IMAGE_SUPPORT is True:
            try:
                # Use Pixbuf to create the proper image type
                image = GdkPixbuf.Pixbuf.new_from_file(icon_path)

                # Associate our image to our notification
                meta_payload['icon_data'] = (
                    image.get_width(),
                    image.get_height(),
                    image.get_rowstride(),
                    image.get_has_alpha(),
                    image.get_bits_per_sample(),
                    image.get_n_channels(),
                    ByteArray(image.get_pixels())
                )

            except Exception as e:
                self.logger.warning(
                    "Could not load Gnome notification icon ({}): {}"
                    .format(icon_path, e))

        # Limit results to just the first 10 line otherwise
        # there is just to much content to display
        body = re.split('[\r\n]+', body)
        if title:
            # Place title on first line if it exists
            body.insert(0, title)

        body = '\r\n'.join(body[0:10])

        try:
            dbus_iface.Notify(
                # Application Identifier
                self.app_id,
                # Message ID (0 = New Message)
                0,
                # Icon (str) - not used
                '',
                # Title
                str(title),
                # Body
                str(body),
                # Actions
                list(),
                # Meta
                meta_payload,
                # Message Timeout
                self.message_timeout_ms,
            )

            self.logger.info('Sent DBus notification.')

        except Exception as e:
            self.logger.warning('Failed to send DBus notification.')
            self.logger.exception('DBus Exception')
            return False

        return True
コード例 #42
0
ファイル: refreshPlasma.py プロジェクト: X4/krawall
#!/usr/bin/env python
import os, sys, datetime
from dbus import SessionBus
from PyKDE4.kdecore import KConfig, KConfigGroup
from PyKDE4.kdeui import KGlobalSettings
kGlobalSettings = KGlobalSettings.self()
# tell all KDE apps to recreate their styles to apply the setitngs
kGlobalSettings.emitChange(KGlobalSettings.StyleChanged)
kGlobalSettings.emitChange(KGlobalSettings.SettingsChanged)
kGlobalSettings.emitChange(KGlobalSettings.ToolbarStyleChanged)
kGlobalSettings.emitChange(KGlobalSettings.PaletteChanged)
kGlobalSettings.emitChange(KGlobalSettings.FontChanged)
kGlobalSettings.emitChange(KGlobalSettings.IconChanged)
kGlobalSettings.emitChange(KGlobalSettings.CursorChanged)

print 'Telling Kwin to reload its config'
os.system("dbus-send --dest=org.kde.kwin /KWin org.kde.KWin.reloadConfig")

print 'Telling plasma to reload its config'
plasma = SessionBus().get_object('org.kde.plasma-desktop','/MainApplication')
plasma.reparseConfiguration()
コード例 #43
0
def start(language, auto=True, test_depends=False,
          test_unknown=False, assume_network=False,
          max_retries=3, enable=None, disable=None):
    try:
        core =  CoreInstall(MODE_INSTALLER, INTERACTIVE_MODE)
        current_version = prop.installed_version_int
        log.debug("Currently installed version: 0x%06x" % current_version)
        core.enable = enable
        core.disable = disable

        if services.running_as_root():
            log.error("You are running the installer as root. It is highly recommended that you run the installer as")
            log.error("a regular (non-root) user. Do you still wish to continue?")

            ok, ans = tui.enter_yes_no(log.bold("Continue with installation"), 'n')
            if not ans or not ok:
                sys.exit(1)

        if auto:
            log.note("Running in automatic mode. The most common options will be selected.")

        log.info("")
        log.note("Defaults for each question are maked with a '*'. Press <enter> to accept the default.")
        core.init()
        vrs =core.get_distro_data('versions_list')
        Is_Manual_Distro = False
        distro_alternate_version=None
        if core.distro_version not in vrs and len(vrs):
            distro_alternate_version= vrs[len(vrs)-1]
            if core.is_auto_installer_support(distro_alternate_version):
                log.error("%s-%s version is not supported, so all dependencies may not be installed. However trying to install using %s-%s version packages." \
                                                   %(core.distro_name, core.distro_version, core.distro_name, distro_alternate_version))
                ok, choice = tui.enter_choice("\nPress 'y' to continue auto installation. Press 'n' to quit auto instalation(y=yes, n=no*): ",['y','n'],'n')
                if not ok or choice =='n':
                    log.info("Installation exit")
                    sys.exit()
            else:
                # Even previous distro is not supported
                Is_Manual_Distro = True
        elif not core.is_auto_installer_support():
              # This distro is not supported
            Is_Manual_Distro = True


        if Is_Manual_Distro:
            log.error("Auto installation is not supported for '%s' distro so all dependencies may not be installed. \nPlease install manually as mentioned in 'http://hplipopensource.com/hplip-web/install/manual/index.html' web-site"% core.distro_name)
            ok, choice = tui.enter_choice("\nPress 'y' to continue auto installation. Press 'n' to quit auto instalation(y=yes, n=no*): ",['y','n'],'n')
            if not ok or choice =='n':
                log.info("Installation exit")
                sys.exit()

        if not auto:
            tui.title("INSTALLATION MODE")
            log.info("Automatic mode will install the full HPLIP solution with the most common options.")
            log.info("Custom mode allows you to choose installation options to fit specific requirements.")

            #if os.getenv('DISPLAY') and utils.find_browser() is not None:
            if 0:
                ok, choice = tui.enter_choice("\nPlease choose the installation mode (a=automatic*, c=custom, w=web installer, q=quit) : ",
                    ['a', 'c', 'w'], 'a')
            else:
                ok, choice = tui.enter_choice("\nPlease choose the installation mode (a=automatic*, c=custom, q=quit) : ",
                    ['a', 'c'], 'a')

            if not ok: sys.exit(0)

            if choice == 'a':
                auto = True

            elif choice == 'w':
                from . import web_install
                log.debug("Starting web browser installer...")
                web_install.start(language)
                return

        log.info("\nInitializing. Please wait...")
        prev_hplip_version = sys_conf.get("hplip","version","0.0.0")
        pluginObj = pluginhandler.PluginHandle()
        prev_hplip_plugin_status = pluginObj.getStatus()

        if test_unknown:
            core.distro_name = 'unknown'
            core.distro = 0
            core.distro_version = 0

        #
        # HPLIP INSTALLATION
        #
        core.selected_component = 'hplip'

        #
        # INTRODUCTION
        #

        tui.title("INTRODUCTION")
        if core.selected_component == 'hplip':
            log.info("This installer will install HPLIP version %s on your computer." % core.version_public)

        log.info("Please close any running package management systems now (YaST, Adept, Synaptic, Up2date, etc).")


        # For testing, mark all dependencies missing
        if test_depends:
            for d in core.have_dependencies:
                core.have_dependencies[d] = False

        num_req_missing = core.count_num_required_missing_dependencies()
        num_opt_missing = core.count_num_optional_missing_dependencies()


        #
        # CONFIRM AND SELECT DISTRO NAME AND VERSION
        #

        tui.title("DISTRO/OS CONFIRMATION")

        if core.distro_known():
            log.info("Distro appears to be %s %s.\n" % (core.get_distro_data('display_name', '(unknown)'), core.distro_version))

        log.debug("Distro = %s Distro Name = %s Display Name= %s Version = %s Supported = %s" % \
            (core.distro, core.distro_name, core.distros[core.distro_name]['display_name'], \
            core.distro_version, core.distro_version_supported))

        distro_ok, ok = False, True
        if core.distro_known():
            ok, distro_ok = tui.enter_yes_no('Is "%s %s" your correct distro/OS and version'
                % (core.get_distro_data('display_name', '(unknown)'), core.distro_version))

        if not ok:
            sys.exit(0)

        if PY3 and core.distro_name.lower() == 'fedora' and int(core.distro_version) < 22:
             global Fedora_Py3               # Workaround due to incomplete Python3 support in Linux distros.
             Fedora_Py3 = True

        if distro_alternate_version:
            core.distro_version = distro_alternate_version

        core.distro_changed()
        if not distro_ok:
            tui.title("DISTRO/OS SELECTION")
            core.distro, core.distro_version = DISTRO_UNKNOWN, DISTRO_VER_UNKNOWN

            log.info(log.bold("\nChoose the name of the distro/OS that most closely matches your system:\n"))

            max_name = 0
            for d in core.distros_index:
                dd = core.distros[core.distros_index[d]]
                if dd['display']:
                    max_name = max(max_name, len(dd['display_name']))

            formatter = utils.TextFormatter(
                    (
                        {'width': 4},
                        {'width': max_name, 'margin': 2},
                    )
                )

            log.info(formatter.compose(("Num.", "Distro/OS Name")))
            log.info(formatter.compose(('-'*4, '-'*(max_name))))

            d_temp = {}
            x = 0
            for d in core.distros_index:
                dd = core.distros[core.distros_index[d]]

                if dd['display']:
                    d_temp[x] = d
                    log.info(formatter.compose((str(x), dd['display_name'])))
                    x += 1

            ok, y = tui.enter_range("\nEnter number 0...%d (q=quit) ?" % (x-1), 0, x-1)
            if not ok: sys.exit(0)

            core.distro = d_temp[y]
            core.distro_name = core.distros_index[core.distro]
            distro_display_name = core.distros[core.distro_name]['display_name']
            log.debug("Distro = %s Distro Name = %s Display Name= %s" %
                (core.distro, core.distro_name, distro_display_name))

            if core.distro != DISTRO_UNKNOWN:
                versions = list(core.distros[core.distro_name]['versions'].keys())
                versions.sort(key=utils.cmp_to_key(cmp))

                log.info(log.bold('\nChoose the version of "%s" that most closely matches your system:\n' % distro_display_name))
                formatter = utils.TextFormatter(
                        (
                            {'width': 4},
                            {'width': 40, 'margin': 2},
                        )
                    )

                log.info(formatter.compose(("Num.", "Distro/OS Version")))
                log.info(formatter.compose(('-'*4, '-'*40)))

                log.info(formatter.compose(("0", "Unknown or not listed")))

                x = 1
                for ver in versions:
                    ver_info = core.distros[core.distro_name]['versions'][ver]

                    if ver_info['code_name'] and ver_info['release_date']:
                        text = ver + ' ("' + ver_info['code_name'] + '", Released ' + ver_info['release_date'] + ')'

                    elif ver_info['code_name']:
                        text = ver + ' ("' + ver_info['code_name'] + '")'

                    elif ver_info['release_date']:
                        text = ver + ' (Released ' + ver_info['release_date'] + ')'

                    else:
                        text = ver

                    if not ver_info['supported']:
                        text += " [Unsupported]"

                    log.info(formatter.compose((str(x), text)))
                    x += 1

                ok, core.distro_version_int = tui.enter_range("\nEnter number 0...%d (q=quit) ?" %
                    (x-1), 0, x-1)
                if not ok: sys.exit(0)

                if core.distro_version_int == 0:
                    core.distro_version = DISTRO_VER_UNKNOWN
                    core.distro_version_supported = False
                else:
                    core.distro_version = versions[core.distro_version_int - 1]
                    core.distro_version_supported = core.get_ver_data('supported', False)

                log.debug("Distro = %s Distro Name = %s Display Name= %s Version = %s Supported = %s" % \
                    (core.distro, core.distro_name, core.distros[core.distro_name]['display_name'], \
                    core.distro_version, core.distro_version_supported))

                core.distro_changed()

                log.info("\nDistro set to: %s %s" %
                    (core.get_distro_data('display_name', '(unknown)'), core.distro_version))


#            if core.distro == DISTRO_UNKNOWN or not core.distro_version_supported:
            if core.distro == DISTRO_UNKNOWN:
                log.error("The distribution/OS that you are running is not supported. This installer\ncannot install an unsupported distribution. Please check your distribution/OS\nand re-run this installer or perform a manual installation.")
                if num_req_missing:
                    log.error("The following REQUIRED dependencies are missing and need to be installed:")

                    for d, desc, opt in core.missing_required_dependencies():
                        log.error("Missing REQUIRED dependency: %s (%s)" % (d, desc))

                for d, desc, req, opt in core.missing_optional_dependencies():
                    if req:
                        log.warning("Missing OPTIONAL dependency: %s (%s) [Required for option '%s']" % (d, desc, opt))
                    else:
                        log.warning("Missing OPTIONAL dependency: %s (%s) [Optional for option '%s']" % (d, desc, opt))

                sys.exit(1)

        #
        # SELECT OPTIONS TO INSTALL
        #

        if not auto:
            tui.title("SELECT HPLIP OPTIONS")
            log.info("You can select which HPLIP options to enable. Some options require extra dependencies.")
            log.info("")
            num_opt_missing = core.select_options(option_question_callback)

        else:
            enable_par = False
            core.selected_options['parallel'] = False

        #
        # COLLECT SUPERUSER PASSWORD
        #
        if not services.running_as_root():
            if core.passwordObj.getAuthType() == "sudo":
                tui.title("ENTER USER PASSWORD")
            else:
                tui.title("ENTER ROOT/SUPERUSER PASSWORD")

            ok = core.check_password()
            if not ok:
                log.error("3 incorrect attempts. (or) Insufficient permissions(i.e. try with sudo user).\nExiting.")
                sys.exit(1)


        # INSTALLATION NOTES
        #

        if core.is_auto_installer_support(distro_alternate_version):
            distro_notes = core.get_distro_data('notes', '').strip()
            ver_notes = core.get_ver_data('notes', '',distro_alternate_version).strip()

            if distro_notes or ver_notes:
                tui.title("INSTALLATION NOTES")

                if distro_notes:
                    log.info(distro_notes)

                if ver_notes:
                    log.info(ver_notes)

                log.info("")

                if not tui.continue_prompt("Please read the installation notes."):
                    sys.exit(0)

        sec_package_name, is_sec_installed = core.security_package_status()

        if sec_package_name:
            tui.title("SECURITY PACKAGES")
            log.info("%s is installed. " % sec_package_name)
            log.info("%s protects the application from external intrusion attempts making the application secure" % sec_package_name )
            ok, answer = tui.enter_yes_no("\nWould you like to have this installer install the hplip specific policy/profile", default_value='')
            if not ok:
                sys.exit(0)
            elif answer:
                if sec_package_name == "SELinux":
                    core.selinux_install()
                core.security_package = sec_package_name
            else:
                pass


        #
        # PRE-INSTALL COMMANDS
        #
        tui.title("RUNNING PRE-INSTALL COMMANDS")
        if core.run_pre_install(progress_callback, distro_alternate_version): # some cmds were run...
            num_req_missing = core.count_num_required_missing_dependencies()
            num_opt_missing = core.count_num_optional_missing_dependencies()
        log.info("OK")

        #
        # REQUIRED DEPENDENCIES INSTALL
        #
        package_mgr_cmd = core.get_distro_ver_data('package_mgr_cmd')
        depends_to_install = []
        depends_to_install_using_pip = []

        if num_req_missing or num_opt_missing:
            tui.title("MISSING DEPENDENCIES")
            log.info("Following dependencies are not installed. HPLIP will not work if all REQUIRED dependencies are not installed and some of the HPLIP features will not work if OPTIONAL dependencies are not installed.")

            log.info("%-20s %-20s %-20s"%( "Package-Name", "Component", "Required/Optional"))
            for d in core.dependencies:
                if (not core.have_dependencies[d]):
                    if core.dependencies[d][0]:
                        deptype = "REQUIRED"
                    else:
                        deptype = "OPTIONAL"
                        
                    log.info("%-20s %-20s %-20s" %(d, core.dependencies[d][1][0], deptype))

            ok, ans = tui.enter_yes_no("Do you want to install these missing dependencies")
            if not ok:
                sys.exit(0)  

            if not ans and num_req_missing:
                log.error("Installation can not continue because all REQUIRED dependencies are not installed.")                
                sys.exit(0)  


        if num_req_missing:
            tui.title("INSTALL MISSING REQUIRED DEPENDENCIES")
            log.notice("Installation of dependencies requires an active internet connection.")
            
            for depend, desc, option in core.missing_required_dependencies():
                log.warning("Missing REQUIRED dependency: %s (%s)" % (depend, desc))
                if Fedora_Py3:              # Workaround due to incomplete Python3 support in Linux distros.
                      continue

                ok = False
                packages, commands = core.get_dependency_data(depend,distro_alternate_version)
                log.debug("Packages: %s" % ','.join(packages))
                log.debug("Commands: %s" % ','.join(commands))

#                if core.distro_version_supported and (packages or commands):
                if package_mgr_cmd and (packages or commands):
                    if auto:
                        answer = True
                    else:
                        ok, answer = tui.enter_yes_no("\nWould you like to have this installer install the missing dependency")
                        if not ok: sys.exit(0) ### TBD: TELL CUSTOMER THAT YOU ARE QUITTING 

                    if answer:
                        ok = True
                        log.debug("Adding '%s' to list of dependencies to install. %s" % (depend,packages))
                        #Adding package which requires python(3)-pip package.
                        for pk in packages:
                            if PIP_PACKAGE_SEARCH in pk:
                                depends_to_install_using_pip.append(pk.replace(PIP_PACKAGE_SEARCH,''))
                        
                        depends_to_install.append(depend)

                else:
                    log.warn("This installer cannot install '%s' for your distro/OS and/or version." % depend)

                if not ok:
                    log.error("Installation cannot continue without this dependency. Please manually install this dependency and re-run this installer.")
                    sys.exit(0)


            if Fedora_Py3:                 # Workaround due to incomplete Python3 support in Linux distros.
                log.info("")
                log.error("'yum' tool required for package downloads is not supported for Python 3 environments by Fedora.\nHPLIP installation failed.")
                log.info("")
                log.warn(log.bold("Manually install the required dependencies to to use HPLIP with Python 3.x on Fedora. More information is available at http://hplipopensource.com/node/369"))
                log.info("")
                sys.exit(1)


        #
        # OPTIONAL dependencies
        #
        if num_opt_missing:
            tui.title("INSTALL MISSING OPTIONAL DEPENDENCIES")
            log.notice("Installation of dependencies requires an active internet connection.")

            for depend, desc, required_for_opt, opt in core.missing_optional_dependencies():

                if required_for_opt:
                    log.warning("Missing REQUIRED dependency for option '%s': %s (%s)" % (opt, depend, desc))

                else:
                    log.warning("Missing OPTIONAL dependency for option '%s': %s (%s)" % (opt, depend, desc))

                if Fedora_Py3:          # Workaround due to incomplete Python3 support in Linux distros.
                      continue

                installed = False
                packages, commands = core.get_dependency_data(depend,distro_alternate_version)
                log.debug("Packages: %s" % ','.join(packages))
                log.debug("Commands: %s" % ','.join(commands))


#                if core.distro_version_supported and (packages or commands):
                if package_mgr_cmd and (packages or commands):
                    if auto:
                        answer = True
                    else:
                        ok, answer = tui.enter_yes_no("\nWould you like to have this installer install the missing dependency")
                        if not ok: sys.exit(0)

                    if answer:
                        log.debug("Adding '%s' to list of dependencies to install. %s" % (depend,packages))
                        #Adding package which requires python(3)-pip package.
                        for pk in packages:
                            if PIP_PACKAGE_SEARCH in pk:
                                depends_to_install_using_pip.append(pk.replace(PIP_PACKAGE_SEARCH,''))

                        depends_to_install.append(depend)

                    else:
                        log.warning("Missing dependencies may affect the proper functioning of HPLIP. Please manually install this dependency after you exit this installer.")
                        log.warning("Note: Options that have REQUIRED dependencies that are missing will be turned off.")

                        if required_for_opt:
                            log.warn("Option '%s' has been turned off." % opt)
                            core.selected_options[opt] = False
                else:
                    log.warn("This installer cannot install '%s' for your distro/OS and/or version." % depend)

                    if required_for_opt:
                        log.warn("Option '%s' has been turned off." % opt)
                        core.selected_options[opt] = False

            if Fedora_Py3:                  # Workaround due to incomplete Python3 support in Linux distros.
                log.info("")
                log.warn("'yum' tool required for package downloads is not supported for Python 3 environments by Fedora.")
                log.warn("Missing dependencies may affect the proper functioning of HPLIP")
                log.info("")
                log.notice(log.bold("Manually install the above missing dependencies if required. More information is available at http://hplipopennsource.com/node/369"))
                log.info("")


        log.debug("Dependencies to install: %s  hplip_present:%s" % (depends_to_install, core.hplip_present))

#        if core.distro_version_supported and \
#            (depends_to_install or core.hplip_present) and \
#            core.selected_component == 'hplip':

        if package_mgr_cmd and \
            (depends_to_install or core.hplip_present) and \
            core.selected_component == 'hplip':
            #
            # CHECK FOR RUNNING PACKAGE MANAGER
            #
            User_exit, Is_pkg_mgr_running = core.close_package_managers()
            if User_exit:
                sys.exit(0)
#            if Is_pkg_mgr_running:
#                log.debug("Some Package manager are still running. ")

            #
            # CHECK FOR ACTIVE NETWORK CONNECTION
            #
            if not assume_network:
                tui.title("CHECKING FOR NETWORK CONNECTION")

                if not utils.check_network_connection():
                    log.error("The network appears to be unreachable. Installation may not resolve all dependencies without access to distribution repositories.")
                    ok, choice = tui.enter_choice("Do you want to continue installation without network?. Press 'y' for YES. Press 'n' for NO (y=yes*, n=no) : ",['y', 'n'], 'y')
                    if not ok or choice == 'n':
                        log.info("Please connect network and try again")
                        sys.exit(1)
                    else:
                        log.debug("Continuing installation without network")
                else:
                    log.info("Network connection present.")

            # sec_package_name, is_sec_installed = core.security_package_status()

            # if sec_package_name:
            #     tui.title("SECURITY PACKAGES")
            #     log.info("%s is installed. " % sec_package_name)
            #     log.info("%s protects the application from external intrusion attempts making the application secure" % sec_package_name )
            #     ok, answer = tui.enter_yes_no("\nWould you like to have this installer install the hplip specific policy/profile")
            #     if not ok:
            #         sys.exit(0)
            #     elif answer:
            #         core.security_package = sec_package_name
            #     else:
            #         pass

            #
            # PRE-DEPEND
            #

            tui.title("RUNNING PRE-PACKAGE COMMANDS")
            if not Fedora_Py3:                            # Workaround due to incomplete Python3 support in Linux distros.
                core.run_pre_depend(progress_callback,distro_alternate_version)
                log.info("OK")

            #
            # INSTALL PACKAGES AND RUN COMMANDS
            #

            tui.title("DEPENDENCY AND CONFLICT RESOLUTION")

            packages = []
            commands_to_run = []
            package_mgr_cmd = core.get_distro_ver_data('package_mgr_cmd')

            # HACK!
            individual_pkgs = True
            if package_mgr_cmd.startswith('xterm'):
                individual_pkgs = False

            if package_mgr_cmd:
                log.debug("Preparing to install packages and run commands...")

                for d in depends_to_install:
                    log.debug("*** Processing dependency: %s" % d)
                    pkgs, commands = core.get_dependency_data(d,distro_alternate_version)

                    if pkgs:
                        log.debug("Package(s) '%s' will be installed to satisfy dependency '%s'." %
                            (','.join(pkgs), d))

                        packages.extend(pkgs)

                    if commands:
                        log.debug("Command(s) '%s' will be run to satisfy dependency '%s'." %
                            (','.join(commands), d))

                        commands_to_run.extend(commands)

            else:
                log.error("Invalid package manager")

            log.debug("Packages: %s" % packages)
            log.debug("Commands: %s" % commands_to_run)
            log.debug("Install individual packages: %s" % individual_pkgs)

            PY_PIP = False
            if len(depends_to_install_using_pip):    # Workaround due to incomplete Python3 support in Linux distros.
                if PY3:
                    packages_to_install = 'python3-pip'
                else:
                    packages_to_install = 'python-pip'

                cmd = utils.cat(package_mgr_cmd)
                log.info("Running '%s'\nPlease wait, this may take several minutes..." % cmd)
                status, output = utils.run(cmd, core.passwordObj)
                if status != 0:
                    log.error("Package install command failed with error code %d" % status)
                    log.warn("Some HPLIP functionality might not function due to missing package(s). [%s]"%depends_to_install_using_pip)
                    if PY3:          # Workaround due to incomplete Python3 support in Linux distros.
                        log.notice(log.bold("More information is available at http://hplipopensource.com/node/369"))
                        sys.exit(1)
                else:
                    PY_PIP = True


            if package_mgr_cmd and packages:
                if individual_pkgs:
                    for packages_to_install in packages:
                        if PIP_PACKAGE_SEARCH in packages_to_install:
                           continue  #This will be installed using python(3)-pip
                           
                        # Workaround due to incomplete Python3 support in Linux distros.                        
                        xsane_var = PY3 and core.get_distro_data('display_name', '(unknown)') in ["Ubuntu", "Linux Mint"]
                        retries = 0
                        while True:
                            cmd = utils.cat(package_mgr_cmd)
                            # Workaround due to incomplete Python3 support in Linux distros.
                            if xsane_var and xsane_reg.search(cmd):
                                package_mgr_cmd_xsane = "sudo apt-get install --no-install-recommends --assume-yes $packages_to_install"
                                cmd = utils.cat(package_mgr_cmd_xsane)

                            log.debug("Package manager command: %s" % cmd)

                            log.info("Running '%s'\nPlease wait, this may take several minutes..." % cmd)
                            status, output = utils.run(cmd, core.passwordObj)

                            if status != 0:
                                retries += 1
                                if retries < (max_retries+1):
                                    log.error("Command failed. Re-try #%d..." % retries)
                                    continue

                                log.error("Package install command failed with error code %d" % status)
                                if PY3:
                                    log.notice("Some packages may not get installed on python3 due to distro incompatibilites")
                                    log.info("")
                                    log.notice("Please check for more information at http://hplipopensource.com/node/369")
                                ok, ans = tui.enter_yes_no("Would you like to retry installing the missing package(s)")

                                if not ok:
                                    sys.exit(0)

                                if ans:
                                    continue
                                else:
                                    log.warn("Some HPLIP functionality might not function due to missing package(s).")
                                    break
                            else:
                                break

                else:
                    packages_to_install = ' '.join(packages)
                    while True:
                        cmd = utils.cat(package_mgr_cmd)
                        log.debug("Package manager command: %s" % cmd)

                        log.info("Running '%s'\nPlease wait, this may take several minutes..." % cmd)
                        status, output = utils.run(cmd, core.passwordObj)

                        if status != 0:
                            log.error("Package install command failed with error code %d" % status)
                            ok, ans = tui.enter_yes_no("Would you like to retry installing the missing package(s)")

                            if not ok:
                                sys.exit(0)

                            if ans:
                                continue
                            else:
                                log.warn("Some HPLIP functionality might not function due to missing package(s).")
                                break
                        else:
                            break
            if PY_PIP:
                pip_cmd = utils.find_pip()
                if pip_cmd:
                    for d in depends_to_install_using_pip:
                        cmd = "%s  install %s"%(pip_cmd,d)
                        cmd = core.passwordObj.getAuthCmd()%cmd
                        log.info("Running '%s'\nPlease wait, this may take several minutes..." % cmd)
                        status, output = utils.run(cmd, core.passwordObj)
                        if status != 0:
                            log.error("Package install command failed with error code %d" % status)
                            log.warn("Some HPLIP functionality might not function due to missing package(s). [%s]"%d)


            if commands_to_run:
                for cmd in commands_to_run:
                    log.debug(cmd)
                    log.info("Running '%s'\nPlease wait, this may take several minutes..." % cmd)
                    status, output = utils.run(cmd, core.passwordObj)

                    if status != 0:
                        log.error("Install command failed with error code %d" % status)
                        sys.exit(1)


            #
            # HPLIP REMOVE
            #
            num_req_missing = 0
            core.check_dependencies()
            for depend, desc, opt in core.missing_required_dependencies():
                log.error("A required dependency '%s (%s)' is still missing." % (depend, desc))
                num_req_missing += 1

            if num_req_missing == 0 and core.hplip_present and core.selected_component == 'hplip' and core.distro_version_supported:
                path = utils.which('hp-uninstall')
                ok, choice = tui.enter_choice("HPLIP-%s exists, this may conflict with the new one being installed.\nDo you want to ('i'= Remove and Install*, 'q'= Quit)?    :"%(prev_hplip_version),['i','q'],'i')
                if not ok or choice=='q':
                    log.error("User Exit")
                    sys.exit(0)
                elif choice == 'i':
#                    log.info("Uninstalling existing HPLIP-%s"%prev_hplip_version)
                    sts =core.uninstall(NON_INTERACTIVE_MODE)

                    if sts is False:
                        log.warn("Failed to uninstall existing HPLIP-%s. This installation will overwrite on existing HPLIP" %prev_hplip_version)
                    else:
                        log.debug("HPLIP-%s is uninstalled successfully." %prev_hplip_version)

            #
            # POST-DEPEND
            #
            tui.title("RUNNING POST-PACKAGE COMMANDS")
            core.run_post_depend(progress_callback)
            log.info("OK")


            #
            # DEPENDENCIES RE-CHECK
            #
            tui.title("RE-CHECKING DEPENDENCIES")
            core.check_dependencies()

            num_req_missing = 0
            for depend, desc, opt in core.missing_required_dependencies():
                num_req_missing += 1
                log.error("A required dependency '%s (%s)' is still missing." % (depend, desc))

            if num_req_missing:
                if num_req_missing > 1:
                    log.error("Installation cannot continue without these dependencies.")
                else:
                    log.error("Installation cannot continue without this dependency.")

                log.error("Please manually install this dependency and re-run this installer.")
                sys.exit(1)

            for depend, desc, required_for_opt, opt in core.missing_optional_dependencies():
                if required_for_opt:
                    log.warn("An optional dependency '%s (%s)' is still missing." % (depend, desc))
                    log.warn("Option '%s' has been turned off." % opt)
                    core.selected_options[opt] = False
                else:
                    log.warn("An optional dependency '%s (%s)' is still missing." % (depend, desc))
                    log.warn("Some features may not function as expected.")


            if not num_opt_missing and not num_req_missing:
                log.info("OK")

        #
        # INSTALL LOCATION
        #

        log.debug("Install location = %s" % core.install_location)


        #
        # BUILD AND INSTALL
        #

        if not auto:
            tui.title("READY TO BUILD AND INSTALL")
            if not tui.continue_prompt("Ready to perform build and install."):
                sys.exit(0)

        tui.title("PRE-BUILD COMMANDS")
        core.run_pre_build(progress_callback, distro_alternate_version)
        log.info("OK")

        tui.title("BUILD AND INSTALL")
        os.umask(0o022)
        for cmd in core.build_cmds():
            log.info("Running '%s'\nPlease wait, this may take several minutes..." % cmd)
            status, output = utils.run(cmd , core.passwordObj)

            if status != 0:
                if 'configure' in cmd:
                    log.error("Configure failed with error: %s" % (CONFIGURE_ERRORS.get(status, CONFIGURE_ERRORS[1])))
                    log.error("output = %s"%output)

                else:
                    log.error("'%s' command failed with status code %d" % (cmd, status))

                sys.exit(0)
            else:
                log.info("Command completed successfully.")

            log.info("")

        log.info("\nBuild complete.")

        #
        # POST BUILD
        #

        tui.title("POST-BUILD COMMANDS")
        core.run_post_build(progress_callback, distro_alternate_version)
        try:
            from prnt import cups
            #This call is just to update the cups PPD cache file@ /var/cache/cups/ppds.dat. If this is not called, hp-setup picks incorrect ppd 1st time for some printers.
            cups.getSystemPPDs()
        except ImportError:
            log.error("Failed to Import Cups")

        #
        # OPEN MDNS MULTICAST PORT
        #
        user_conf = UserConfig()

        if core.selected_options['network']:
            open_mdns_port = core.get_distro_ver_data('open_mdns_port',None,distro_alternate_version)
            if open_mdns_port:
                tui.title("OPEN MDNS/BONJOUR FIREWALL PORT (MULTICAST PORT 5353)")

                paragraph = "In order to setup your printer on the network using mDNS/Bonjour, it is required that your internet firewall allows connections on port 5353. If this port is blocked by the firewall, connection to network printers using mDNS/Bonjour will not be possible."

                for p in tui.format_paragraph(paragraph):
                    log.info(p)
                log.info("")

                ok, ans = tui.enter_yes_no("Do you wish to open this port on your internet firewall")
                if not ok: sys.exit(0)

                if ans:
                    services.run_open_mdns_port(core, core.passwordObj)
                else:
                    log.warn("Skipping firewall setup. If this port is blocked on your firewall when setting up network printers, use SLP discovery and device URIs with ?ip=x.x.x.x. When using hp-setup, choose 'SLP' discovery under 'Advanced'.")


        #
        # Try to close running hp-systray (3.9.2 or later)
        #

        if current_version >= 0x030902: # 3.9.2
            try:
                from dbus import SessionBus, lowlevel
            except ImportError:
                pass
            else:
                try:
                    args = ['', '', EVENT_SYSTEMTRAY_EXIT, prop.username, 0, '', '']
                    msg = lowlevel.SignalMessage('/', 'com.hplip.StatusService', 'Event')
                    msg.append(signature='ssisiss', *args)
                    tui.title("CLOSE HP_SYSTRAY")
                    log.info("Sending close message to hp-systray (if it is currently running)...")
                    SessionBus().send_message(msg)
                    time.sleep(0.5)
                except:
                    pass

        tui.title("HPLIP UPDATE NOTIFICATION")
        ok, choice = tui.enter_choice("Do you want to check for HPLIP updates?. (y=yes*, n=no) : ",['y', 'n'], 'y')
        if not ok or choice != 'y':
            user_conf.set('upgrade', 'notify_upgrade', 'false')
        else:
            user_conf.set('upgrade', 'notify_upgrade', 'true')

        user_conf.set('upgrade','last_upgraded_time',str(int(time.time())))
        user_conf.set('upgrade','pending_upgrade_time','0')

        if prev_hplip_plugin_status != pluginhandler.PLUGIN_NOT_INSTALLED:
            tui.title("HPLIP PLUGIN UPDATE NOTIFICATION")
            ok, choice = tui.enter_choice("HPLIP Plug-in's needs to be installed/updated. Do you want to update plug-in's?. (y=yes*, n=no) : ",['y', 'n'], 'y')
            if ok and choice == 'y':
                ok, choice = tui.enter_choice("Do you want to install plug-in's in GUI mode?. (u=GUI mode*, i=Interactive mode) : ",['u', 'i'], 'u')
                if ok and choice == 'u':
                    plugin_cmd = 'hp-plugin  -u'
                elif ok and choice == 'i':
                    plugin_cmd = 'hp-plugin  -i'
                else:
                    log.info(log.bold("Please install hp plugin's manually, otherwise some functionality may break"))
                if os_utils.execute(plugin_cmd) != 0:
                    log.error("hp-plugin command failed. Please run hp-plugin manually.")
            else:
                log.info(log.bold("Please install hp plugin's manually, otherwise some functionality may break"))

        if core.selected_component == 'hplip':
            tui.title("RESTART OR RE-PLUG IS REQUIRED")
            cmd = "hp-setup"
            paragraph = """If you are installing a USB connected printer, and the printer was plugged in when you started this installer, you will need to either restart your PC or unplug and re-plug in your printer (USB cable only). If you choose to restart, run this command after restarting: %s  (Note: If you are using a parallel connection, you will have to restart your PC. If you are using network/wireless, you can ignore and continue).""" % cmd

            for p in tui.format_paragraph(paragraph):
                log.info(p)
            log.info("")

            ok, choice = tui.enter_choice("Restart or re-plug in your printer (r=restart, p=re-plug in*, i=ignore/continue, q=quit) : ",
                ['r', 'p', 'i'], 'p')

            if not ok:
                tui.title("RE-STARTING HP_SYSTRAY")
                services.run_systray()
                sys.exit(0)

            if choice == 'r':
                log.note("")
                log.note("IMPORTANT! Make sure to save all work in all open applications before restarting!")

                ok, ans = tui.enter_yes_no(log.bold("Restart now"), 'n')
                if not ok:
                    tui.title("RE-STARTING HP_SYSTRAY")
                    services.run_systray()
                    sys.exit(0)
                if ans:
                    ok = services.restart(core.passwordObj)
                    if not ok:
                        log.error("Restart failed. Please restart using the system menu.")

                tui.title("RE-STARTING HP_SYSTRAY")
                services.run_systray()
                sys.exit(0)

            elif choice == 'p': # 'p'
                if not tui.continue_prompt("Please unplug and re-plugin your printer now. "):
                    tui.title("RE-STARTING HP_SYSTRAY")
                    services.run_systray()
                    sys.exit(0)


        #
        # SETUP PRINTER
        #
        if core.selected_component == 'hplip':
            tui.title("PRINTER SETUP")

            if auto:
                install_printer = True
            else:
                ok, install_printer = tui.enter_yes_no("Would you like to setup a printer now")
                if not ok:
                    tui.title("RE-STARTING HP_SYSTRAY")
                    services.run_systray()
                    sys.exit(0)

            if install_printer:
                log.info("Please make sure your printer is connected and powered on at this time.")
                ok, choice = tui.enter_choice("Do you want to setup printer in GUI mode? (u=GUI mode*, i=Interactive mode) : ",['u', 'i'], 'u')
                if ok and choice == 'u':
                    setup_cmd = 'hp-setup  -u'
                    if os_utils.execute(setup_cmd) != 0:
                        log.error("hp-setup failed. Please run hp-setup manually.")

                elif ok and choice == 'i':
                    setup_cmd = 'hp-setup  -i'
                    log.info("Running '%s' command...."%setup_cmd)
                    if os_utils.execute(setup_cmd) != 0:
                        log.error("hp-setup failed. Please run hp-setup manually.")

        tui.title("RE-STARTING HP_SYSTRAY")
        services.run_systray()
    except KeyboardInterrupt:
        log.info("")
        log.error("Aborted.")

    sys.exit(0)
コード例 #44
0
 def __init__(self, user=False):
     self.bus = SessionBus() if user else SystemBus()
     systemd = self.bus.get_object(SYSTEMD_BUSNAME, SYSTEMD_PATH)
     self.manager = Interface(systemd,
                              dbus_interface=SYSTEMD_MANAGER_INTERFACE)
コード例 #45
0
ファイル: client.py プロジェクト: dineshkummarc/webradio
class Client(GObject):
    (STATE_INITIALIZED, STATE_STATIONS_LOADED,
     STATE_CHANNELS_LOADED) = range(3)

    __gtype_name__ = 'WebRadioClient'

    __gsignals__ = {
        'station-added': (SIGNAL_RUN_LAST, TYPE_NONE, (object, )),
        'channel-added': (SIGNAL_RUN_LAST, TYPE_NONE, (object, )),
        'state-changed': (SIGNAL_RUN_LAST, TYPE_NONE, ()),
        'stream-tags-changed': (SIGNAL_RUN_LAST, TYPE_NONE, ()),
    }

    @staticmethod
    def decode_stream(uri, title, length):
        return Stream(uri, title, length)

    @classmethod
    def decode_channel(cls, station, uri, tags, streams):
        streams = [cls.decode_stream(*s) for s in streams]
        return Channel(station, uri, tags, streams)

    def __init__(self):
        super(Client, self).__init__()

        self.__stations = dict()
        self.__channels = dict()
        self.__stream_tags = dict()

        self.__current_channel = None
        self.__is_playing = False

        def register_channel(station, channel):
            if station:
                station.channels.append(channel)

            for stream in channel.streams:
                self.__channels[stream.uri] = channel

            self.__channels[channel.uri] = channel

        def station_added_cb(station):
            id, title, uri, channels = station
            station = Station(id, title, uri)

            for channel in channels:
                channel = self.decode_channel(station, *channel)
                register_channel(station, channel)

            self.__stations[station.id] = station
            self.emit('station-added', station)

        def channel_added_cb(station_id, channel):
            station = self.find_station(station_id)
            channel = self.decode_channel(station, *channel)
            register_channel(station, channel)
            self.emit('channel-added', channel)

        def state_changed_cb(playing, stream_uri):
            self.__stream_tags = self.__service.GetStreamTags()
            self.__current_channel = self.__channels.get(stream_uri)
            self.__is_playing = playing
            self.emit('state-changed')

        def stream_tags_changed_cb(tags):
            self.__stream_tags.update(tags)
            self.emit('stream-tags-changed')

        def name_owner_cb(new_owner):
            if not new_owner:
                # FIXME
                from gtk import main_quit
                main_quit()

        self.__bus = SessionBus()
        proxy = self.__bus.get_object(Service.name, '/')
        self.__bus.watch_name_owner(Service.name, name_owner_cb)
        self.__service = Interface(proxy, Service.interface)
        self.__service.connect_to_signal('StationAdded', station_added_cb)
        self.__service.connect_to_signal('ChannelAdded', channel_added_cb)
        self.__service.connect_to_signal('StateChanged', state_changed_cb)
        self.__service.connect_to_signal('StreamTagsChanged',
                                         stream_tags_changed_cb)

        for station in self.__service.GetStations():
            station_added_cb(station)

        state_changed_cb(*self.__service.GetState())

    def wait(self, stage=STATE_CHANNELS_LOADED):
        loop = MainLoop(None, True)

        def data_ready_cb(new_stage):
            if new_stage >= stage:
                loop.quit()

        self.__service.connect_to_signal('DataReady', data_ready_cb)

        if self.__service.GetDataStage() >= stage:
            loop.quit()

        progress_id = 0

        if loop.is_running():
            if sys.stdout.isatty():
                progress = ['-\r', '\\\r', '|\r', '/\r']

                def progress_cb():
                    c = progress.pop(0)
                    sys.stdout.write(c)
                    sys.stdout.flush()
                    progress.append(c)
                    return True

                progress_id = timeout_add(250, progress_cb)
                sys.stdout.write('  loading...\r')

            loop.run()

        if progress_id:
            source_remove(progress_id)
            sys.stdout.write('\r\033[K')
            sys.stdout.flush()

    def find_channels(self, query=[]):
        result = list()

        for station_id, channel in self.__service.Find(query):
            station = self.__stations.get(station_id)
            channel = self.decode_channel(station, *channel)
            result.append(channel)

        return result

    def find_station(self, id):
        return self.__stations.get(id)

    def get_stations(self):
        return self.__stations.values()

    def get_tags(self):
        return self.__service.GetTags()

    def play(self, channel):
        self.__service.Play(channel.streams[0].uri)

    def pause(self):
        self.__service.Pause()

    def resume(self):
        self.__service.Resume()

    def quit(self):
        self.__service.Quit()

    def get_equalizer_profiles(self):
        return self.__service.ListEqualizerProfiles()

    def __get_equalizer_profile(self):
        return self.__service.GetEqualizerProfile()

    def __set_equalizer_profile(self, value):
        self.__service.SetEqualizerProfile(value)

    is_playing = property(fget=lambda self: self.__is_playing)
    current_channel = property(fget=lambda self: self.__current_channel)
    stream_tags = property(fget=lambda self: self.__stream_tags)
    equalizer_profile = property(fget=__get_equalizer_profile,
                                 fset=__set_equalizer_profile)
コード例 #46
0
ファイル: quicktile.py プロジェクト: meryt/quicktile
    XLIB_PRESENT = True  #: Indicates whether python-xlib was found
except ImportError:
    XLIB_PRESENT = False  #: Indicates whether python-xlib was found

DBUS_PRESENT = False
try:
    import dbus.service
    from dbus import SessionBus
    from dbus.exceptions import DBusException
    from dbus.mainloop.glib import DBusGMainLoop
except ImportError:
    pass
else:
    try:
        DBusGMainLoop(set_as_default=True)
        sessBus = SessionBus()
    except DBusException:
        pass
    else:
        DBUS_PRESENT = True

XDG_CONFIG_DIR = os.environ.get('XDG_CONFIG_HOME',
                                os.path.expanduser('~/.config'))

#TODO: Figure out how best to put this in the config file.
POSITIONS = {
    'left': ((0, 0, 0.5, 1), (0, 0, 1.0 / 3, 1), (0, 0, 1.0 / 3 * 2, 1)),
    'middle':
    ((0, 0, 1, 1), (1.0 / 3, 0, 1.0 / 3, 1), (1.0 / 6, 0, 1.0 / 3 * 2, 1)),
    'right': ((0.5, 0, 0.5, 1), (1.0 / 3 * 2, 0, 1.0 / 3, 1),
              (1.0 / 3, 0, 1.0 / 3 * 2, 1)),
コード例 #47
0
 def __init__(self, uid):
     bus_name = BusName('.'.join([DBUS_NS, uid]), bus=SessionBus())
     self.dbus_uid = uid
     self.dbus_path = '/vim'
     dbus.service.Object.__init__(self, bus_name, self.dbus_path)
コード例 #48
0
    XLIB_PRESENT = True  #: Indicates presence of python-xlib (runtime check)
except ImportError:
    XLIB_PRESENT = False  #: Indicates presence of python-xlib (runtime check)

DBUS_PRESENT = False  #: Indicates availability of D-Bus (runtime check)
try:
    import dbus.service
    from dbus import SessionBus
    from dbus.exceptions import DBusException
    from dbus.mainloop.glib import DBusGMainLoop
except ImportError:
    pass
else:
    try:
        DBusGMainLoop(set_as_default=True)
        sessBus = SessionBus()  #: D-Bus Session Bus for L{QuickTileApp.run}
    except DBusException:
        pass
    else:
        DBUS_PRESENT = True  #: Indicates availability of D-Bus (runtime check)

#: Location for config files (determined at runtime).
XDG_CONFIG_DIR = os.environ.get('XDG_CONFIG_HOME',
                                os.path.expanduser('~/.config'))
#{ Settings


class GravityLayout(object):
    """Helper for generating L{cycle_dimensions} presets."""
    #: Possible window alignments relative to the monitor/desktop.
    #: @todo 1.0.0: Normalize these to X11 or CSS terminology for 1.0
コード例 #49
0
ファイル: Globals.py プロジェクト: mystilleef/scribes
# -*- coding: utf-8 -*-
from os import environ
from os.path import join, expanduser
from dbus import SessionBus, Interface, glib
from xdg.BaseDirectory import xdg_config_home, xdg_data_home
SCRIBES_DBUS_SERVICE = "net.sourceforge.Scribes"
SCRIBES_DBUS_PATH = "/net/sourceforge/Scribes"
SCRIBES_SAVE_PROCESS_DBUS_SERVICE = "net.sourceforge.ScribesSaveProcess"
SCRIBES_SAVE_PROCESS_DBUS_PATH = "/net/sourceforge/ScribesSaveProcess"
session_bus = SessionBus()
dbus_proxy_obj = session_bus.get_object('org.freedesktop.DBus', '/org/freedesktop/DBus')
dbus_iface = Interface(dbus_proxy_obj, 'org.freedesktop.DBus')
home_folder = expanduser("~")
from tempfile import gettempdir
tmp_folder = gettempdir()
folder_ = join(home_folder, "Desktop")
from os.path import exists
desktop_folder = folder_ if exists(folder_) else home_folder
metadata_folder = config_folder = join(xdg_config_home, "scribes")
print_settings_filename = join(metadata_folder, "ScribesPrintSettings.txt")
home_plugin_folder = home_generic_plugin_folder = join(config_folder, "GenericPlugins")
home_language_plugin_folder = join(config_folder, "LanguagePlugins")
scribes_theme_folder = join(config_folder, "styles")
storage_folder = join(config_folder, ".config")
default_home_theme_folder = join(xdg_data_home, "gtksourceview-2.0", "styles")
name = "scribes"
prefix = "/usr"
executable_path = join(prefix, "bin")
data_path = "/usr/share"
library_path = "/usr/lib"
sysconfdir = "/usr/etc"
コード例 #50
0
class Py3status:
    """ """

    # available configuration parameters
    button_next = None
    button_next_player = None
    button_prev_player = None
    button_previous = None
    button_stop = None
    button_switch_to_top_player = None
    button_toggle = 1
    cache_timeout = 0.5
    format = "[{artist} - ][{title}] {previous} {toggle} {next}"
    format_none = "no player running"
    icon_next = "\u25b9"
    icon_pause = "\u25eb"
    icon_play = "\u25b7"
    icon_previous = "\u25c3"
    icon_stop = "\u25a1"
    max_width = None
    player_hide_non_canplay = []
    player_priority = []
    state_pause = "\u25eb"
    state_play = "\u25b7"
    state_stop = "\u25a1"

    def post_config_hook(self):
        if self.py3.is_gevent():
            raise Exception(STRING_GEVENT)
        self._name_owner_change_match = None
        self._kill = False
        self._mpris_players: dict[Player] = {}
        self._identity_cache = {}
        self._identity_index = {}
        self._priority_cache = {}
        self._player: [Player, None] = None
        self._tries = 0
        self._empty_response = {
            "album": None,
            "artist": None,
            "length": None,
            "title": None,
            "nowplaying": None,
            "time": None,
            "state": None,
            "player": None,
            # for debugging ;p
            "full_name": None,
        }

        self._states = {
            "pause": {
                "action": "Pause",
                "clickable": "CanPause",
                "icon": self.icon_pause,
                "inactive": [STATE.Stopped, STATE.Paused],
            },
            "play": {
                "action": "Play",
                "clickable": "CanPlay",
                "icon": self.icon_play,
                "inactive": [STATE.Playing],
            },
            "stop": {
                "action": "Stop",
                "clickable": "CanControl",
                "icon": self.icon_stop,
                "inactive": [STATE.Stopped],
            },
            "next": {
                "action": "Next",
                "clickable": "CanGoNext",
                "icon": self.icon_next,
            },
            "previous": {
                "action": "Previous",
                "clickable": "CanGoPrevious",
                "icon": self.icon_previous,
            },
            "toggle": {
                "action": "PlayPause",
                "clickable": "CanPause",
                # Not used, but it will be set dynamically with player state map.
                "icon": None,
            },
        }

        self._state_icon_color_map = {
            STATE.Playing: {
                "state_icon": self.state_play,
                "color": self.py3.COLOR_PLAYING or self.py3.COLOR_GOOD,
                "toggle_icon": self.state_pause,
                "cached_until": self.cache_timeout,
            },
            STATE.Paused: {
                "state_icon": self.state_pause,
                "color": self.py3.COLOR_PAUSED or self.py3.COLOR_DEGRADED,
                "toggle_icon": self.state_play,
                "cached_until": self.py3.CACHE_FOREVER,
            },
            STATE.Stopped: {
                "state_icon": self.state_stop,
                "color": self.py3.COLOR_STOPPED or self.py3.COLOR_BAD,
                "toggle_icon": self.state_play,
                "cached_until": self.py3.CACHE_FOREVER,
            },
        }

        self._color_active = self.py3.COLOR_CONTROL_ACTIVE or self.py3.COLOR_GOOD
        self._color_inactive = self.py3.COLOR_CONTROL_INACTIVE or self.py3.COLOR_BAD

        self._format_contains_metadata = False
        self._metadata_keys = ["album", "artist", "title", "nowplaying", "length"]
        for key in self._metadata_keys:
            if self.py3.format_contains(self.format, key):
                self._format_contains_metadata = True
                break

        self._format_contains_control_buttons = False
        self._used_can_properties = []
        for key, value in self._states.items():
            if self.py3.format_contains(self.format, key):
                self._format_contains_control_buttons = True
                self._used_can_properties.append(value["clickable"])

        if (
            len(self.player_hide_non_canplay)
            and "CanPlay" not in self._used_can_properties
        ):
            self._used_can_properties.append("CanPlay")

        self._format_contains_time = self.py3.format_contains(self.format, "time")
        self._button_cache_flush = None
        if 2 not in [
            self.button_next,
            self.button_next_player,
            self.button_prev_player,
            self.button_previous,
            self.button_stop,
            self.button_switch_to_top_player,
            self.button_toggle,
        ]:
            self._button_cache_flush = 2

        if self.player_priority:
            try:
                self._random_player_priority = self.player_priority.index("*")
            except ValueError:
                self._random_player_priority = False
        else:
            self._random_player_priority = 0

        # start last
        self._dbus_loop = DBusGMainLoop()
        self._dbus = SessionBus(mainloop=self._dbus_loop)
        self._start_listener()

    def _start_loop(self):
        self._loop = GLib.MainLoop()
        GLib.timeout_add(1000, self._timeout)
        try:
            self._loop.run()
        except KeyboardInterrupt:
            # This branch is only needed for the test mode
            self._kill = True

    @staticmethod
    def _is_mediaplayer_interface(player_id):
        return player_id.startswith(Interfaces.MEDIA_PLAYER)

    def _dbus_name_owner_changed(self, name, old_owner, new_owner):
        if not self._is_mediaplayer_interface(name):
            return
        if new_owner:
            self._add_player(name)
        if old_owner:
            self._remove_player(name)
        self._set_player()

    def _set_player(self, update=True):
        """
        Sort the current players into priority order and set self._player
        Players are ordered by working state, then by preference supplied by
        user and finally by instance if a player has more than one running.
        """
        players = []
        for name, player in self._mpris_players.items():
            player_priority_tuple = player.priority_tuple
            if player_priority_tuple:
                players.append(player_priority_tuple)

        new_top_player_id = None
        if players:
            new_top_player_id = sorted(players)[0][3]

        self._set_data_entry_point_by_name_key(new_top_player_id, update)

    def _player_on_change(self, interface_name, data, invalidated_properties, sender):
        """
        Monitor a player and update its status.
        """
        pass

    def _add_player(self, player_id):
        """
        Add player to mpris_players
        """
        player_id_parts_list = player_id.split(".")
        name_from_id = player_id_parts_list[3]

        identity = self._identity_cache.get(name_from_id)
        if not identity:
            dMediaPlayer = dMediaPlayer2(dbus_interface_info={"dbus_uri": player_id})
            identity = str(dMediaPlayer.Identity)
            self._identity_cache[name_from_id] = identity

        if self.player_priority:
            # Expected value: numeric / False, None is cache miss.
            priority = self._priority_cache.get(name_from_id, None)
            if priority is None:
                for i, _player in enumerate(self.player_priority):
                    if _player == name_from_id or _player == identity:
                        priority = i
                        break

                if priority is None:
                    priority = self._random_player_priority
                self._priority_cache[identity] = priority

            if not isinstance(priority, int):
                return

        else:
            priority = 0

        identity_index = self._identity_index.get(identity, 0)
        if identity_index:
            self._identity_index[identity] += 1
        else:
            self._identity_index[identity] = 1

        name_with_instance = ".".join(player_id_parts_list[3:])

        player = Player(
            self,
            player_id=player_id,
            name_from_id=name_from_id,
            name_with_instance=name_with_instance,
            name_priority=priority,
            identity=identity,
            identity_index=identity_index,
        )

        self._mpris_players[player_id] = player

    def _remove_player(self, player_id):
        """
        Remove player from mpris_players
        """
        if self._mpris_players.get(player_id):
            del self._mpris_players[player_id]

    def _get_players(self):
        for player in get_players_uri():
            try:
                # str(player) helps avoid to use dbus.Str(*) as dict key
                self._add_player(str(player))
            except DBusException:
                continue

        self._set_player()

    def _start_listener(self):
        self._get_players()

        self._name_owner_change_match = self._dbus.add_signal_receiver(
            handler_function=self._dbus_name_owner_changed,
            dbus_interface="org.freedesktop.DBus",
            signal_name="NameOwnerChanged",
        )

        # Start listening things after initiating 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 _set_data_entry_point_by_name_key(self, new_active_player_key, update=True):
        if self._player is None or new_active_player_key != self._player.id:
            self._player = self._mpris_players.get(new_active_player_key, None)
            if self._player:
                self._player.prepare_output()

        if update:
            self.py3.update()

    def kill(self):
        self._kill = True
        if self._name_owner_change_match:
            self.parent._dbus._clean_up_signal_match(self._name_owner_change_match)

    def mpris(self):
        """
        Get the current output format and return it.
        """
        if self._kill:
            raise KeyboardInterrupt

        current_player = self._player
        cached_until = self.py3.CACHE_FOREVER
        color = self.py3.COLOR_BAD

        if current_player:
            current_player_id = str(current_player.id)
            current_state_map = current_player.state_map
            data = current_player.data

            if current_player_id == self._player.id:
                if self._format_contains_time:
                    cached_until = self.py3.time_in(
                        seconds=current_state_map.get("cached_until"), sync_to=0
                    )

                placeholders = {"state": current_state_map["state_icon"]}
                color = current_state_map["color"]
                composite = self.py3.safe_format(
                    self.format,
                    dict(self._empty_response, **placeholders, **data),
                    max_width=self.max_width,
                )
            else:
                # 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
                return {
                    # Can't decide what is good time to restart 3 retry cycle
                    "cached_until": self.py3.time_in(10),
                    "color": self.py3.COLOR_BAD,
                    "composite": [
                        {
                            "full_text": "Something went wrong",
                            "color": self.py3.COLOR_BAD,
                        }
                    ],
                }

        else:
            composite = [{"full_text": self.format_none, "color": color}]

        # we are outputting so reset tries
        self._tries = 0

        response = {
            "cached_until": cached_until,
            "color": color,
            "composite": composite,
        }
        return response

    def on_click(self, event):
        """
        Handles click events
        """
        index = event["index"]
        button = event["button"]

        if not self._player:
            return

        if button == self._button_cache_flush:
            self._player.metadata = None
            self._player.state = None

        elif index not in self._states:
            if button == self.button_toggle:
                return self._player.send_mpris_action("toggle")
            elif button == self.button_stop:
                return self._player.send_mpris_action("stop")
            elif button == self.button_next:
                return self._player.send_mpris_action("next")
            elif button == self.button_previous:
                return self._player.send_mpris_action("previous")
            elif button == self.button_switch_to_top_player:
                return self._set_player(update=False)

            elif button == self.button_prev_player or button == self.button_next_player:
                switchable_players = []
                order_asc = button == self.button_next_player
                current_player_index = False
                for key, player in self._mpris_players.items():
                    if player.state == self._player.state and not player.hide:
                        if not current_player_index:
                            if player.id == self._player.id:
                                current_player_index = len(switchable_players)
                                if order_asc:
                                    continue

                        switchable_players.append(key)
                        if current_player_index:
                            if order_asc:
                                break
                            else:
                                if current_player_index != 0:
                                    break

                if len(switchable_players):
                    try:
                        if order_asc:
                            next_index = current_player_index % len(switchable_players)
                        else:
                            next_index = (current_player_index - 1) % len(
                                switchable_players
                            )

                        self._set_data_entry_point_by_name_key(
                            switchable_players[next_index], update=False
                        )

                    except KeyError:
                        pass

            else:
                return

        elif button == 1:
            self._player.send_mpris_action(index)
コード例 #51
0
    def post_config_hook(self):
        if self.py3.is_gevent():
            raise Exception(STRING_GEVENT)
        self._name_owner_change_match = None
        self._kill = False
        self._mpris_players: dict[Player] = {}
        self._identity_cache = {}
        self._identity_index = {}
        self._priority_cache = {}
        self._player: [Player, None] = None
        self._tries = 0
        self._empty_response = {
            "album": None,
            "artist": None,
            "length": None,
            "title": None,
            "nowplaying": None,
            "time": None,
            "state": None,
            "player": None,
            # for debugging ;p
            "full_name": None,
        }

        self._states = {
            "pause": {
                "action": "Pause",
                "clickable": "CanPause",
                "icon": self.icon_pause,
                "inactive": [STATE.Stopped, STATE.Paused],
            },
            "play": {
                "action": "Play",
                "clickable": "CanPlay",
                "icon": self.icon_play,
                "inactive": [STATE.Playing],
            },
            "stop": {
                "action": "Stop",
                "clickable": "CanControl",
                "icon": self.icon_stop,
                "inactive": [STATE.Stopped],
            },
            "next": {
                "action": "Next",
                "clickable": "CanGoNext",
                "icon": self.icon_next,
            },
            "previous": {
                "action": "Previous",
                "clickable": "CanGoPrevious",
                "icon": self.icon_previous,
            },
            "toggle": {
                "action": "PlayPause",
                "clickable": "CanPause",
                # Not used, but it will be set dynamically with player state map.
                "icon": None,
            },
        }

        self._state_icon_color_map = {
            STATE.Playing: {
                "state_icon": self.state_play,
                "color": self.py3.COLOR_PLAYING or self.py3.COLOR_GOOD,
                "toggle_icon": self.state_pause,
                "cached_until": self.cache_timeout,
            },
            STATE.Paused: {
                "state_icon": self.state_pause,
                "color": self.py3.COLOR_PAUSED or self.py3.COLOR_DEGRADED,
                "toggle_icon": self.state_play,
                "cached_until": self.py3.CACHE_FOREVER,
            },
            STATE.Stopped: {
                "state_icon": self.state_stop,
                "color": self.py3.COLOR_STOPPED or self.py3.COLOR_BAD,
                "toggle_icon": self.state_play,
                "cached_until": self.py3.CACHE_FOREVER,
            },
        }

        self._color_active = self.py3.COLOR_CONTROL_ACTIVE or self.py3.COLOR_GOOD
        self._color_inactive = self.py3.COLOR_CONTROL_INACTIVE or self.py3.COLOR_BAD

        self._format_contains_metadata = False
        self._metadata_keys = ["album", "artist", "title", "nowplaying", "length"]
        for key in self._metadata_keys:
            if self.py3.format_contains(self.format, key):
                self._format_contains_metadata = True
                break

        self._format_contains_control_buttons = False
        self._used_can_properties = []
        for key, value in self._states.items():
            if self.py3.format_contains(self.format, key):
                self._format_contains_control_buttons = True
                self._used_can_properties.append(value["clickable"])

        if (
            len(self.player_hide_non_canplay)
            and "CanPlay" not in self._used_can_properties
        ):
            self._used_can_properties.append("CanPlay")

        self._format_contains_time = self.py3.format_contains(self.format, "time")
        self._button_cache_flush = None
        if 2 not in [
            self.button_next,
            self.button_next_player,
            self.button_prev_player,
            self.button_previous,
            self.button_stop,
            self.button_switch_to_top_player,
            self.button_toggle,
        ]:
            self._button_cache_flush = 2

        if self.player_priority:
            try:
                self._random_player_priority = self.player_priority.index("*")
            except ValueError:
                self._random_player_priority = False
        else:
            self._random_player_priority = 0

        # start last
        self._dbus_loop = DBusGMainLoop()
        self._dbus = SessionBus(mainloop=self._dbus_loop)
        self._start_listener()
コード例 #52
0
class SystemTrayApp(QApplication):
    def __init__(self, args, read_pipe):
        QApplication.__init__(self, args)

        self.menu = None
        self.read_pipe = read_pipe
        self.fmt = "80s80sI32sI80sf"
        self.fmt_size = struct.calcsize(self.fmt)
        self.timer_active = False
        self.active_icon = False
        self.user_settings = UserSettings()
        self.user_settings.load()
        self.user_settings.debug()

        self.tray_icon = QSystemTrayIcon()

        pm = load_pixmap("hp_logo", "32x32")
        self.prop_icon = QIcon(pm)

        a = load_pixmap('active', '16x16')
        painter = QPainter(pm)
        painter.drawPixmap(32, 0, a)
        painter.end()

        self.prop_active_icon = QIcon(pm)

        self.tray_icon.setIcon(self.prop_icon)

        self.session_bus = SessionBus()
        self.service = None

        for d in device.getSupportedCUPSDevices(
                back_end_filter=['hp', 'hpfax']):
            self.addDevice(d)

        self.tray_icon.setToolTip(self.__tr("HPLIP Status Service"))
        # QObject.tray_icon.messageClicked.connect(self.messageClicked)
        self.tray_icon.messageClicked.connect(self.messageClicked)
        notifier = QSocketNotifier(self.read_pipe, QSocketNotifier.Read)
        # QObject.notifier.activated[int].connect(self.notifierActivated)
        notifier.activated[int].connect(self.notifierActivated)
        # QObject.tray_icon.activated[QSystemTrayIcon::ActivationReason].connect(self.trayActivated)
        self.tray_icon.activated["QSystemTrayIcon::ActivationReason"].connect(
            self.trayActivated)
        signal.signal(signal.SIGINT, signal.SIG_DFL)
        self.tray_icon.show()

        if self.user_settings.systray_visible == SYSTRAY_VISIBLE_SHOW_ALWAYS:
            self.tray_icon.setVisible(True)
        else:
            QTimer.singleShot(
                HIDE_INACTIVE_DELAY,
                self.timeoutHideWhenInactive)  # show icon for awhile @ startup

        self.tray_icon.setIcon(self.prop_active_icon)
        self.active_icon = True

        if "--ignore-update-firsttime" not in args:
            self.handle_hplip_updation()

        QTimer.singleShot(SET_MENU_DELAY, self.initDone)

        self.update_timer = QTimer()
        # self.update_timer.connect(self.update_timer,SIGNAL("timeout()"),self.handle_hplip_updation)
        self.update_timer.timeout.connect(self.handle_hplip_updation)
        self.update_timer.start(UPGRADE_CHECK_DELAY)

        # Cleans the /var/log/hp/tmp directory
        #self.handle_hplip_clean()

        #self.clean_timer = QTimer()
        #self.clean_timer.connect(self.clean_timer,SIGNAL("timeout()"),self.handle_hplip_clean)
        #self.clean_timer.start(CLEAN_EXEC_DELAY)

    def initDone(self):
        self.tray_icon.setIcon(self.prop_icon)
        self.active_icon = False

        self.setMenu()

    def resetDevice(self):
        devices.clear()

    def addDevice(self, device_uri):
        try:
            devices[device_uri]
        except KeyError:
            devices[device_uri] = HistoryDevice(device_uri)
        else:
            devices[device_uri].needs_update = True

    def handle_hplip_clean(self):
        log.debug("handle_hplip_clean ")
        home_dir = sys_conf.get('dirs', 'home')
        cmd = 'sh %s/hplip_clean.sh' % home_dir
        os.system(cmd)

    def handle_hplip_updation(self):
        log.debug("handle_hplip_updation upgrade_notify =%d" %
                  (self.user_settings.upgrade_notify))
        path = utils.which('hp-upgrade')
        if self.user_settings.upgrade_notify is False:
            log.debug("upgrade notification is disabled in systray ")
            if path:
                path = os.path.join(path, 'hp-upgrade')
                log.debug("Running hp-upgrade: %s " % (path))
                # this just updates the available version in conf file. But won't notify
                os.spawnlp(os.P_NOWAIT, path, 'hp-upgrade', '--check')
                time.sleep(5)
                try:
                    os.waitpid(0, os.WNOHANG)
                except OSError:
                    pass

            return

        current_time = time.time()

        if int(current_time) > self.user_settings.upgrade_pending_update_time:
            path = utils.which('hp-upgrade')
            if path:
                path = os.path.join(path, 'hp-upgrade')
                log.debug("Running hp-upgrade: %s " % (path))
                os.spawnlp(os.P_NOWAIT, path, 'hp-upgrade', '--notify')
                time.sleep(5)
            else:
                log.error("Unable to find hp-upgrade --notify on PATH.")
        else:
            log.debug(
                "upgrade schedule time is not yet completed. schedule time =%d current time =%d "
                %
                (self.user_settings.upgrade_pending_update_time, current_time))

        try:
            os.waitpid(0, os.WNOHANG)
        except OSError:
            pass

    def setMenu(self):
        self.menu = QMenu()

        title = QWidgetAction(self.menu)
        #title.setDisabled(True)

        hbox = QFrame(self.menu)
        layout = QHBoxLayout(hbox)
        # layout.setMargin(3)
        layout.setContentsMargins(3, 3, 3, 3)
        layout.setSpacing(5)
        pix_label = QLabel(hbox)

        layout.insertWidget(-1, pix_label, 0)

        icon_size = self.menu.style().pixelMetric(QStyle.PM_SmallIconSize)
        pix_label.setPixmap(self.prop_icon.pixmap(icon_size))

        label = QLabel(hbox)
        layout.insertWidget(-1, label, 20)
        title.setDefaultWidget(hbox)

        label.setText(self.__tr("HPLIP Status Service"))

        f = label.font()
        f.setBold(True)
        label.setFont(f)
        self.menu.insertAction(None, title)

        if devices:
            if self.service is None:
                t = 0
                while t < 3:
                    try:
                        self.service = self.session_bus.get_object(
                            'com.hplip.StatusService',
                            "/com/hplip/StatusService")
                    except dbus.DBusException:
                        log.warn(
                            "Unable to connect to StatusService. Retrying...")

                    t += 1
                    time.sleep(0.5)

            if self.service is not None:
                self.menu.addSeparator()

                for d in devices:
                    devices[d].getHistory(self.service)

                    menu = DeviceMenu(devices[d].menu_text, self.menu, d,
                                      devices[d].history, devices[d].index)
                    self.menu.addMenu(menu)
                    menu.update()

        self.menu.addSeparator()
        self.menu.addAction(self.__tr("HP Device Manager..."),
                            self.toolboxTriggered)

        self.menu.addSeparator()

        self.settings_action = self.menu.addAction(
            QIcon(load_pixmap('settings', '16x16')), self.__tr("Settings..."),
            self.settingsTriggered)

        self.menu.addSeparator()
        self.menu.addAction(QIcon(load_pixmap('quit', '16x16')), "Quit",
                            self.quitTriggered)
        self.tray_icon.setContextMenu(self.menu)

    def settingsTriggered(self):
        if self.menu is None:
            return

        self.sendMessage('', '', EVENT_DEVICE_STOP_POLLING)
        #        sys_conf
        cur_vers = sys_conf.get('hplip', 'version')
        self.user_settings.load()
        installed_time = time.strftime(
            "%d-%m-%Y",
            time.localtime(self.user_settings.upgrade_last_update_time))
        if utils.Is_HPLIP_older_version(
                cur_vers, self.user_settings.latest_available_version):
            if int(time.time()
                   ) < self.user_settings.upgrade_pending_update_time:
                postponed_time = time.strftime(
                    "%d-%m-%Y",
                    time.localtime(
                        self.user_settings.upgrade_pending_update_time))
                upgrade_msg = "HPLIP-%s version was installed on %s.\n\nNew version of HPLIP-%s is available for upgrade. HPLIP upgrade is scheduled on %s." % (
                    cur_vers, installed_time,
                    self.user_settings.latest_available_version,
                    postponed_time)
            elif self.user_settings.upgrade_last_update_time:
                upgrade_msg = "HPLIP-%s version was installed on %s.\n\nNew version of HPLIP-%s is available for upgrade." % (
                    cur_vers, installed_time,
                    self.user_settings.latest_available_version)
            else:
                upgrade_msg = "HPLIP-%s version was installed.\n\nNew version of HPLIP-%s is available for upgrade." % (
                    cur_vers, self.user_settings.latest_available_version)
        elif self.user_settings.upgrade_last_update_time:
            upgrade_msg = "HPLIP-%s version was installed on %s." % (
                cur_vers, installed_time)
        else:
            upgrade_msg = "HPLIP-%s version was installed." % (cur_vers)

        try:
            dlg = SystraySettingsDialog(
                self.menu, self.user_settings.systray_visible,
                self.user_settings.polling,
                self.user_settings.polling_interval,
                self.user_settings.systray_messages,
                self.user_settings.polling_device_list,
                self.user_settings.upgrade_notify,
                self.user_settings.upgrade_pending_update_time,
                self.user_settings.upgrade_last_update_time, upgrade_msg)

            if dlg.exec_() == QDialog.Accepted:
                self.user_settings.systray_visible = dlg.systray_visible
                self.user_settings.systray_messages = dlg.systray_messages
                self.user_settings.upgrade_notify = dlg.upgrade_notify

                log.debug("HPLIP update  notification = %d" %
                          (self.user_settings.upgrade_notify))
                self.user_settings.save()

                if self.user_settings.systray_visible == SYSTRAY_VISIBLE_SHOW_ALWAYS:
                    log.debug("Showing...")
                    self.tray_icon.setVisible(True)

                else:
                    log.debug("Waiting to hide...")
                    QTimer.singleShot(HIDE_INACTIVE_DELAY,
                                      self.timeoutHideWhenInactive)

                self.sendMessage('', '', EVENT_USER_CONFIGURATION_CHANGED)

        finally:
            self.sendMessage('', '', EVENT_DEVICE_START_POLLING)

    def timeoutHideWhenInactive(self):
        log.debug("Hiding...")
        if self.user_settings.systray_visible in (
                SYSTRAY_VISIBLE_HIDE_WHEN_INACTIVE,
                SYSTRAY_VISIBLE_HIDE_ALWAYS):
            self.tray_icon.setVisible(False)
            log.debug("Hidden")

    def updateMenu(self):
        if self.menu is None:
            return
        for a in self.menu.actions():
            try:
                a.menu().update()
            except AttributeError:
                continue

    def trayActivated(self, reason):
        if reason == QSystemTrayIcon.Context:
            self.updateMenu()

        elif reason == QSystemTrayIcon.DoubleClick:
            #print "double click"
            self.toolboxTriggered()
            pass

        elif reason == QSystemTrayIcon.Trigger:
            #print "single click"
            pass

        elif reason == QSystemTrayIcon.MiddleClick:
            #print "middle click"
            pass

    def messageClicked(self):
        #print "\nPARENT: message clicked"
        pass

    def quitTriggered(self):
        log.debug("Exiting")
        self.sendMessage('', '', EVENT_SYSTEMTRAY_EXIT)
        self.quit()
        del self.tray_icon

    def toolboxTriggered(self):
        try:
            os.waitpid(-1, os.WNOHANG)
        except OSError:
            pass

        # See if it is already running...
        ok, lock_file = utils.lock_app('hp-toolbox', True)

        if ok:  # able to lock, not running...
            utils.unlock(lock_file)

            path = utils.which('hp-toolbox')
            if path:
                path = os.path.join(path, 'hp-toolbox')
            else:
                self.tray_icon.showMessage(
                    self.__tr("HPLIP Status Service"),
                    self.__tr("Unable to locate hp-toolbox on system PATH."),
                    QSystemTrayIcon.Critical, TRAY_MESSAGE_DELAY)

                log.error("Unable to find hp-toolbox on PATH.")
                return

            #log.debug(path)
            log.debug("Running hp-toolbox: hp-toolbox")
            os.spawnlp(os.P_NOWAIT, path, 'hp-toolbox')

        else:  # ...already running, raise it
            self.sendMessage('',
                             '',
                             EVENT_RAISE_DEVICE_MANAGER,
                             interface='com.hplip.Toolbox')

    def sendMessage(self,
                    device_uri,
                    printer_name,
                    event_code,
                    username=prop.username,
                    job_id=0,
                    title='',
                    pipe_name='',
                    interface='com.hplip.StatusService'):
        #device.Event(device_uri, printer_name, event_code, username, job_id, title).send_via_dbus(SessionBus(), interface)
        device.Event(device_uri, printer_name, event_code, username, job_id,
                     title).send_via_dbus(self.session_bus, interface)

    def notifierActivated(self, s):
        m = ''
        while True:
            try:
                r, w, e = select.select([self.read_pipe], [], [self.read_pipe],
                                        1.0)
            except select.error:
                log.debug("Error in select()")
                break

            if e:
                log.error("Pipe error: %s" % e)
                break

            if r:
                #m = ''.join([m, os.read(self.read_pipe, self.fmt_size)])
                m = os.read(self.read_pipe, self.fmt_size)
                while len(m) >= self.fmt_size:
                    event = device.Event(*[
                        x.rstrip(b'\x00').
                        decode('utf-8') if isinstance(x, bytes) else x
                        for x in struct.unpack(self.fmt, m[:self.fmt_size])
                    ])
                    m = m[self.fmt_size:]

                    if event.event_code == EVENT_CUPS_QUEUES_REMOVED or event.event_code == EVENT_CUPS_QUEUES_ADDED:
                        self.resetDevice()
                        for d in device.getSupportedCUPSDevices(
                                back_end_filter=['hp', 'hpfax']):
                            self.addDevice(d)

                        self.setMenu()

                    if event.event_code == EVENT_USER_CONFIGURATION_CHANGED:
                        log.debug(
                            "Re-reading configuration (EVENT_USER_CONFIGURATION_CHANGED)"
                        )
                        self.user_settings.load()
                        self.user_settings.debug()

                    elif event.event_code == EVENT_SYSTEMTRAY_EXIT:
                        self.quit()
                        return

                    if self.user_settings.systray_visible in \
                        (SYSTRAY_VISIBLE_SHOW_ALWAYS, SYSTRAY_VISIBLE_HIDE_WHEN_INACTIVE):

                        log.debug("Showing...")
                        self.tray_icon.setVisible(True)

                        if event.event_code == EVENT_DEVICE_UPDATE_ACTIVE:
                            if not self.active_icon:
                                self.tray_icon.setIcon(self.prop_active_icon)
                                self.active_icon = True
                            continue

                        elif event.event_code == EVENT_DEVICE_UPDATE_INACTIVE:
                            if self.active_icon:
                                self.tray_icon.setIcon(self.prop_icon)
                                self.active_icon = False
                            continue

                        elif event.event_code == EVENT_DEVICE_UPDATE_BLIP:
                            if not self.active_icon:
                                self.tray_icon.setIcon(self.prop_active_icon)
                                self.active_icon = True
                                QTimer.singleShot(BLIP_DELAY, self.blipTimeout)
                            continue

                    if self.user_settings.systray_visible in (
                            SYSTRAY_VISIBLE_HIDE_WHEN_INACTIVE,
                            SYSTRAY_VISIBLE_HIDE_ALWAYS):
                        log.debug("Waiting to hide...")
                        QTimer.singleShot(HIDE_INACTIVE_DELAY,
                                          self.timeoutHideWhenInactive)

                    if event.event_code <= EVENT_MAX_USER_EVENT or \
                        event.event_code == EVENT_CUPS_QUEUES_REMOVED or event.event_code == EVENT_CUPS_QUEUES_ADDED:

                        if event.event_code != EVENT_CUPS_QUEUES_REMOVED:
                            self.addDevice(event.device_uri)
                            self.setMenu()

                        if self.tray_icon.supportsMessages():

                            log.debug("Tray icon message:")
                            event.debug()

                            error_state = STATUS_TO_ERROR_STATE_MAP.get(
                                event.event_code, ERROR_STATE_CLEAR)
                            desc = device.queryString(event.event_code)

                            show_message = False
                            if self.user_settings.systray_messages == SYSTRAY_MESSAGES_SHOW_ALL:  # OK, Busy
                                show_message = True

                            elif self.user_settings.systray_messages in (
                                    SYSTRAY_MESSAGES_SHOW_ERRORS_AND_WARNINGS,
                                    SYSTRAY_MESSAGES_SHOW_ERRORS_ONLY):
                                if error_state == ERROR_STATE_ERROR:
                                    show_message = True

                                elif self.user_settings.systray_messages == SYSTRAY_MESSAGES_SHOW_ERRORS_AND_WARNINGS and \
                                    error_state in (ERROR_STATE_WARNING, ERROR_STATE_LOW_SUPPLIES, ERROR_STATE_LOW_PAPER):

                                    show_message = True

                            if event.printer_name:
                                d = event.printer_name
                            else:
                                back_end, is_hp, bus, model, serial, dev_file, host, zc, port = \
                                                device.parseDeviceURI(event.device_uri)

                                if bus == 'usb':
                                    idd = serial
                                elif bus == 'net':
                                    idd = host
                                elif bus == 'par':
                                    idd = dev_file
                                else:
                                    idd = 'unknown'

                                self.model = models.normalizeModelUIName(model)

                                if back_end == 'hp':
                                    d = self.__tr("%s Printer (%s)" %
                                                  (model, idd))

                                elif back_end == 'hpaio':
                                    d = self.__tr("%s Scanner (%s)" %
                                                  (model, idd))

                                elif back_end == 'hpfax':
                                    d = self.__tr("%s Fax (%s)" % (model, idd))

                                else:
                                    d = self.__tr("%s (%s)" % (model, idd))

                            if show_message:
                                if have_pynotify and pynotify.init(
                                        "hplip"):  # Use libnotify/pynotify
                                    icon, urgency = ERROR_STATE_TO_ICON_AND_URGENCY_PYNOTIFY.get(
                                        error_state, (getPynotifyIcon('info'),
                                                      pynotify.URGENCY_NORMAL))

                                    if event.job_id and event.title:
                                        msg = "%s\n%s: %s\n(%s/%s)" % (
                                            to_unicode(d), desc, event.title,
                                            event.username, event.job_id)
                                        log.debug(
                                            "Notify: uri=%s desc=%s title=%s user=%s job_id=%d code=%d"
                                            % (event.device_uri, desc,
                                               event.title, event.username,
                                               event.job_id, event.event_code))
                                    else:
                                        msg = "%s\n%s (%s)" % (to_unicode(
                                            d), desc, event.event_code)
                                        log.debug(
                                            "Notify: uri=%s desc=%s code=%d" %
                                            (event.device_uri, desc,
                                             event.event_code))

                                    n = pynotify.Notification(
                                        "HPLIP Device Status", msg, icon)
                                    # CRID: 11833 Debian Traceback error notification exceeded
                                    n.set_hint('transient', True)
                                    n.set_urgency(urgency)

                                    if error_state == ERROR_STATE_ERROR:
                                        n.set_timeout(pynotify.EXPIRES_NEVER)
                                    else:
                                        n.set_timeout(TRAY_MESSAGE_DELAY)

                                    n.show()

                                else:  # Use "standard" message bubbles
                                    icon = ERROR_STATE_TO_ICON.get(
                                        error_state,
                                        QSystemTrayIcon.Information)
                                    if event.job_id and event.title:
                                        log.debug(
                                            "Bubble: uri=%s desc=%s title=%s user=%s job_id=%d code=%d"
                                            % (event.device_uri, desc,
                                               event.title, event.username,
                                               event.job_id, event.event_code))
                                        self.tray_icon.showMessage(
                                            self.__tr("HPLIP Device Status"),
                                            "%s\n%s: %s\n(%s/%s)" %
                                            (d, desc, event.title,
                                             event.username, event.job_id),
                                            icon, TRAY_MESSAGE_DELAY)

                                    else:
                                        log.debug(
                                            "Bubble: uri=%s desc=%s code=%d" %
                                            (event.device_uri, desc,
                                             event.event_code))
                                        self.tray_icon.showMessage(
                                            self.__tr("HPLIP Device Status"),
                                            "%s\n%s (%s)" %
                                            (d, desc, event.event_code), icon,
                                            TRAY_MESSAGE_DELAY)

            else:
                break
                # return

    def blipTimeout(self):
        if self.active_icon:
            self.tray_icon.setIcon(self.prop_icon)
            self.active_icon = False

    def __tr(self, s, c=None):
        return QApplication.translate("SystemTray", s, c)
コード例 #53
0

class Server(SingleTestsImpl, TestsImpl, SignalTestsImpl):

    def triggered_by_client(self, parameter1, parameter2, sender, sender_path):
        # Called when the client emits TestSignals.Trigger from any object.
        logger.info('signal/callback: Triggered by client (%s:%s): (%r,%r)', sender, sender_path, parameter1, parameter2)
        tested_things.add(INTERFACE_SIGNAL_TESTS + '.Trigger')
        dbus.Interface(dbus.SessionBus().get_object(sender, sender_path),
                       INTERFACE_CALLBACK_TESTS).Response(parameter1, parameter2)
        logger.info('signal/callback: Sent Response')



if __name__ == '__main__':
    bus = SessionBus()
    bus_name = BusName(CROSS_TEST_BUS_NAME, bus=bus)
    loop = gobject.MainLoop()
    obj = Server(bus_name, CROSS_TEST_PATH, loop.quit)
    objects[CROSS_TEST_PATH] = obj
    bus.add_signal_receiver(obj.triggered_by_client,
                            signal_name='Trigger',
                            dbus_interface=INTERFACE_SIGNAL_TESTS,
                            named_service=None,
                            path=None,
                            sender_keyword='sender',
                            path_keyword='sender_path',
                            utf8_strings=True)

    logger.info("running...")
    loop.run()
コード例 #54
0
    def __init__(self, args, read_pipe):
        QApplication.__init__(self, args)

        self.menu = None
        self.read_pipe = read_pipe
        self.fmt = "80s80sI32sI80sf"
        self.fmt_size = struct.calcsize(self.fmt)
        self.timer_active = False
        self.active_icon = False
        self.user_settings = UserSettings()
        self.user_settings.load()
        self.user_settings.debug()

        self.tray_icon = QSystemTrayIcon()

        pm = load_pixmap("hp_logo", "32x32")
        self.prop_icon = QIcon(pm)

        a = load_pixmap('active', '16x16')
        painter = QPainter(pm)
        painter.drawPixmap(32, 0, a)
        painter.end()

        self.prop_active_icon = QIcon(pm)

        self.tray_icon.setIcon(self.prop_icon)

        self.session_bus = SessionBus()
        self.service = None

        for d in device.getSupportedCUPSDevices(
                back_end_filter=['hp', 'hpfax']):
            self.addDevice(d)

        self.tray_icon.setToolTip(self.__tr("HPLIP Status Service"))
        # QObject.tray_icon.messageClicked.connect(self.messageClicked)
        self.tray_icon.messageClicked.connect(self.messageClicked)
        notifier = QSocketNotifier(self.read_pipe, QSocketNotifier.Read)
        # QObject.notifier.activated[int].connect(self.notifierActivated)
        notifier.activated[int].connect(self.notifierActivated)
        # QObject.tray_icon.activated[QSystemTrayIcon::ActivationReason].connect(self.trayActivated)
        self.tray_icon.activated["QSystemTrayIcon::ActivationReason"].connect(
            self.trayActivated)
        signal.signal(signal.SIGINT, signal.SIG_DFL)
        self.tray_icon.show()

        if self.user_settings.systray_visible == SYSTRAY_VISIBLE_SHOW_ALWAYS:
            self.tray_icon.setVisible(True)
        else:
            QTimer.singleShot(
                HIDE_INACTIVE_DELAY,
                self.timeoutHideWhenInactive)  # show icon for awhile @ startup

        self.tray_icon.setIcon(self.prop_active_icon)
        self.active_icon = True

        if "--ignore-update-firsttime" not in args:
            self.handle_hplip_updation()

        QTimer.singleShot(SET_MENU_DELAY, self.initDone)

        self.update_timer = QTimer()
        # self.update_timer.connect(self.update_timer,SIGNAL("timeout()"),self.handle_hplip_updation)
        self.update_timer.timeout.connect(self.handle_hplip_updation)
        self.update_timer.start(UPGRADE_CHECK_DELAY)
コード例 #55
0
ファイル: dbus_service.py プロジェクト: kovidgoyal/calibre
    def __new__(cls, name, bus=None, allow_replacement=False , replace_existing=False, do_not_queue=False):
        """Constructor, which may either return an existing cached object
        or a new object.

        :Parameters:
            `name` : str
                The well-known name to be advertised
            `bus` : dbus.Bus
                A Bus on which this service will be advertised.

                Omitting this parameter or setting it to None has been
                deprecated since version 0.82.1. For backwards compatibility,
                if this is done, the global shared connection to the session
                bus will be used.

            `allow_replacement` : bool
                If True, other processes trying to claim the same well-known
                name will take precedence over this one.
            `replace_existing` : bool
                If True, this process can take over the well-known name
                from other processes already holding it.
            `do_not_queue` : bool
                If True, this service will not be placed in the queue of
                services waiting for the requested name if another service
                already holds it.
        """
        validate_bus_name(name, allow_well_known=True, allow_unique=False)

        # if necessary, get default bus (deprecated)
        if bus is None:
            import warnings
            warnings.warn('Omitting the "bus" parameter to '
                          'dbus.service.BusName.__init__ is deprecated',
                          DeprecationWarning, stacklevel=2)
            bus = SessionBus()

        # see if this name is already defined, return it if so
        # FIXME: accessing internals of Bus
        if name in bus._bus_names:
            return bus._bus_names[name]

        # otherwise register the name
        name_flags = (
            (allow_replacement and _dbus_bindings.NAME_FLAG_ALLOW_REPLACEMENT or 0) |
            (replace_existing and _dbus_bindings.NAME_FLAG_REPLACE_EXISTING or 0) |
            (do_not_queue and _dbus_bindings.NAME_FLAG_DO_NOT_QUEUE or 0))

        retval = bus.request_name(name, name_flags)

        # TODO: more intelligent tracking of bus name states?
        if retval == _dbus_bindings.REQUEST_NAME_REPLY_PRIMARY_OWNER:
            pass
        elif retval == _dbus_bindings.REQUEST_NAME_REPLY_IN_QUEUE:
            # queueing can happen by default, maybe we should
            # track this better or let the user know if they're
            # queued or not?
            pass
        elif retval == _dbus_bindings.REQUEST_NAME_REPLY_EXISTS:
            raise NameExistsException(name)
        elif retval == _dbus_bindings.REQUEST_NAME_REPLY_ALREADY_OWNER:
            # if this is a shared bus which is being used by someone
            # else in this process, this can happen legitimately
            pass
        else:
            raise RuntimeError('requesting bus name %s returned unexpected value %s' % (name, retval))

        # and create the object
        bus_name = object.__new__(cls)
        bus_name._bus = bus
        bus_name._name = name

        # cache instance (weak ref only)
        # FIXME: accessing Bus internals again
        bus._bus_names[name] = bus_name

        return bus_name
コード例 #56
0
    def main(self,
             argv=None,
             standalone=None,
             plugin_argument_provider=None,
             plugin_manager_settings_prefix=''):
        if argv is None:
            argv = sys.argv

        # extract --args and everything behind manually since argparse can not handle that
        arguments = argv[1:]

        # extract plugin specific args when not being invoked in standalone mode programmatically
        if not standalone:
            plugin_args = []
            if '--args' in arguments:
                index = arguments.index('--args')
                plugin_args = arguments[index + 1:]
                arguments = arguments[0:index + 1]

        parser = ArgumentParser(os.path.basename(Main.main_filename),
                                add_help=False)
        self.add_arguments(parser,
                           standalone=bool(standalone),
                           plugin_argument_provider=plugin_argument_provider)
        self._options = parser.parse_args(arguments)

        if standalone:
            # rerun parsing to separate common arguments from plugin specific arguments
            parser = ArgumentParser(os.path.basename(Main.main_filename),
                                    add_help=False)
            self.add_arguments(parser, standalone=bool(standalone))
            self._options, plugin_args = parser.parse_known_args(arguments)
        self._options.multi_process = False  # not supported anymore
        self._options.plugin_args = plugin_args

        # set default values for options not available in standalone mode
        if standalone:
            self._options.freeze_layout = False
            self._options.lock_perspective = False
            self._options.hide_title = False
            self._options.perspective = None
            self._options.perspective_file = None
            self._options.standalone_plugin = standalone
            self._options.list_perspectives = False
            self._options.list_plugins = False
            self._options.command_pid = None
            self._options.command_start_plugin = None
            self._options.command_switch_perspective = None
            self._options.embed_plugin = None
            self._options.embed_plugin_serial = None
            self._options.embed_plugin_address = None

        # check option dependencies
        try:
            if self._options.plugin_args and \
                    not self._options.standalone_plugin and \
                    not self._options.command_start_plugin and \
                    not self._options.embed_plugin:
                raise RuntimeError(
                    'Option --args can only be used together with either --standalone, '
                    '--command-start-plugin or --embed-plugin option')

            if self._options.freeze_layout and not self._options.lock_perspective:
                raise RuntimeError(
                    'Option --freeze_layout can only be used together with the '
                    '--lock_perspective option')

            list_options = (self._options.list_perspectives,
                            self._options.list_plugins)
            list_options_set = [
                opt for opt in list_options if opt is not False
            ]
            if len(list_options_set) > 1:
                raise RuntimeError(
                    'Only one --list-* option can be used at a time')

            command_options = (self._options.command_start_plugin,
                               self._options.command_switch_perspective)
            command_options_set = [
                opt for opt in command_options if opt is not None
            ]
            if len(command_options_set) > 0 and not self._dbus_available:
                raise RuntimeError(
                    'Without DBus support the --command-* options are not available'
                )
            if len(command_options_set) > 1:
                raise RuntimeError(
                    'Only one --command-* option can be used at a time (except --command-pid '
                    'which is optional)')
            if len(command_options_set
                   ) == 0 and self._options.command_pid is not None:
                raise RuntimeError(
                    'Option --command_pid can only be used together with an other --command-* '
                    'option')

            embed_options = (self._options.embed_plugin,
                             self._options.embed_plugin_serial,
                             self._options.embed_plugin_address)
            embed_options_set = [
                opt for opt in embed_options if opt is not None
            ]
            if len(command_options_set) > 0 and not self._dbus_available:
                raise RuntimeError(
                    'Without DBus support the --embed-* options are not available'
                )
            if len(embed_options_set) > 0 and len(embed_options_set) < len(
                    embed_options):
                raise RuntimeError(
                    "Missing option(s) - all '--embed-*' options must be set")

            if len(embed_options_set) > 0 and self._options.clear_config:
                raise RuntimeError(
                    'Option --clear-config can only be used without any --embed-* option'
                )

            groups = (list_options_set, command_options_set, embed_options_set)
            groups_set = [opt for opt in groups if len(opt) > 0]
            if len(groups_set) > 1:
                raise RuntimeError(
                    'Options from different groups (--list, --command, --embed) can not be used '
                    'together')

            perspective_options = (self._options.perspective,
                                   self._options.perspective_file)
            perspective_options_set = [
                opt for opt in perspective_options if opt is not None
            ]
            if len(perspective_options_set) > 1:
                raise RuntimeError(
                    'Only one --perspective-* option can be used at a time')

            if self._options.perspective_file is not None and \
                    not os.path.isfile(self._options.perspective_file):
                raise RuntimeError(
                    'Option --perspective-file must reference existing file')

        except RuntimeError as e:
            print(str(e))
            # parser.parse_args(['--help'])
            # calling --help will exit
            return 1

        # set implicit option dependencies
        if self._options.standalone_plugin is not None:
            self._options.lock_perspective = True

        # create application context containing various relevant information
        from qt_gui.application_context import ApplicationContext
        context = ApplicationContext()
        context.qtgui_path = self._qtgui_path
        context.options = self._options

        if self._dbus_available:
            from dbus import DBusException, Interface, SessionBus

        # non-special applications provide various dbus interfaces
        if self._dbus_available:
            context.provide_app_dbus_interfaces = len(groups_set) == 0
            context.dbus_base_bus_name = 'org.ros.qt_gui'
            if context.provide_app_dbus_interfaces:
                context.dbus_unique_bus_name = context.dbus_base_bus_name + '.pid%d' % os.getpid(
                )

                # provide pid of application via dbus
                from qt_gui.application_dbus_interface import ApplicationDBusInterface
                _dbus_server = ApplicationDBusInterface(
                    context.dbus_base_bus_name)  # noqa: F841

        # determine host bus name, either based on pid given on command line or
        # via dbus application interface if any other instance is available
        if len(command_options_set) > 0 or len(embed_options_set) > 0:
            host_pid = None
            if self._options.command_pid is not None:
                host_pid = self._options.command_pid
            else:
                try:
                    remote_object = SessionBus().get_object(
                        context.dbus_base_bus_name, '/Application')
                except DBusException:
                    pass
                else:
                    remote_interface = Interface(
                        remote_object,
                        context.dbus_base_bus_name + '.Application')
                    host_pid = remote_interface.get_pid()
            if host_pid is not None:
                context.dbus_host_bus_name = context.dbus_base_bus_name + '.pid%d' % host_pid

        # execute command on host application instance
        if len(command_options_set) > 0:
            if self._options.command_start_plugin is not None:
                try:
                    remote_object = SessionBus().get_object(
                        context.dbus_host_bus_name, '/PluginManager')
                except DBusException:
                    (rc,
                     msg) = (1,
                             'unable to communicate with GUI instance "%s"' %
                             context.dbus_host_bus_name)
                else:
                    remote_interface = Interface(
                        remote_object,
                        context.dbus_base_bus_name + '.PluginManager')
                    (rc, msg) = remote_interface.start_plugin(
                        self._options.command_start_plugin,
                        ' '.join(self._options.plugin_args))
                if rc == 0:
                    print('qt_gui_main() started plugin "%s" in GUI "%s"' %
                          (msg, context.dbus_host_bus_name))
                else:
                    print(
                        'qt_gui_main() could not start plugin "%s" in GUI "%s": %s'
                        % (self._options.command_start_plugin,
                           context.dbus_host_bus_name, msg))
                return rc
            elif self._options.command_switch_perspective is not None:
                remote_object = SessionBus().get_object(
                    context.dbus_host_bus_name, '/PerspectiveManager')
                remote_interface = Interface(
                    remote_object,
                    context.dbus_base_bus_name + '.PerspectiveManager')
                remote_interface.switch_perspective(
                    self._options.command_switch_perspective)
                print(
                    'qt_gui_main() switched to perspective "%s" in GUI "%s"' %
                    (self._options.command_switch_perspective,
                     context.dbus_host_bus_name))
                return 0
            raise RuntimeError('Unknown command not handled')

        # choose selected or default qt binding
        setattr(sys, 'SELECT_QT_BINDING', self._options.qt_binding)
        from python_qt_binding import QT_BINDING

        from python_qt_binding.QtCore import (qDebug, qInstallMessageHandler,
                                              QSettings, Qt, QtCriticalMsg,
                                              QtDebugMsg)
        from python_qt_binding.QtCore import QtFatalMsg, QTimer, QtWarningMsg

        from python_qt_binding.QtGui import QIcon
        from python_qt_binding.QtWidgets import QAction

        from qt_gui.about_handler import AboutHandler
        from qt_gui.composite_plugin_provider import CompositePluginProvider
        from qt_gui.container_manager import ContainerManager
        from qt_gui.help_provider import HelpProvider
        from qt_gui.icon_loader import get_icon
        from qt_gui.main_window import MainWindow
        from qt_gui.minimized_dock_widgets_toolbar import MinimizedDockWidgetsToolbar
        from qt_gui.perspective_manager import PerspectiveManager
        from qt_gui.plugin_manager import PluginManager

        # TODO PySide2 segfaults when invoking this custom message handler atm
        if QT_BINDING != 'pyside':

            def message_handler(type_, context, msg):
                colored_output = 'TERM' in os.environ and 'ANSI_COLORS_DISABLED' not in os.environ
                cyan_color = '\033[36m' if colored_output else ''
                red_color = '\033[31m' if colored_output else ''
                reset_color = '\033[0m' if colored_output else ''
                if type_ == QtDebugMsg and self._options.verbose:
                    print(msg, file=sys.stderr)
                elif type_ == QtWarningMsg:
                    print(cyan_color + msg + reset_color, file=sys.stderr)
                elif type_ == QtCriticalMsg:
                    print(red_color + msg + reset_color, file=sys.stderr)
                elif type_ == QtFatalMsg:
                    print(red_color + msg + reset_color, file=sys.stderr)
                    sys.exit(1)

            qInstallMessageHandler(message_handler)

        app = self.create_application(argv)

        self._check_icon_theme_compliance()

        settings = QSettings(QSettings.IniFormat, QSettings.UserScope,
                             'ros.org', self._settings_filename)
        if len(embed_options_set) == 0:
            if self._options.clear_config:
                settings.clear()

            main_window = MainWindow()
            if self._options.on_top:
                main_window.setWindowFlags(Qt.WindowStaysOnTopHint)

            main_window.statusBar()

            def sigint_handler(*args):
                qDebug('\nsigint_handler()')
                main_window.close()

            signal.signal(signal.SIGINT, sigint_handler)
            # the timer enables triggering the sigint_handler
            timer = QTimer()
            timer.start(500)
            timer.timeout.connect(lambda: None)

            if not self._options.lock_perspective:
                menu_bar = main_window.menuBar()
                file_menu = menu_bar.addMenu(menu_bar.tr('&File'))
                action = QAction(file_menu.tr('&Quit'), file_menu)
                action.setIcon(QIcon.fromTheme('application-exit'))
                action.triggered.connect(main_window.close)
                file_menu.addAction(action)
            else:
                menu_bar = None

        else:
            app.setQuitOnLastWindowClosed(False)

            main_window = None
            menu_bar = None

        self._add_plugin_providers()

        # setup plugin manager
        plugin_provider = CompositePluginProvider(self.plugin_providers)
        plugin_manager = PluginManager(
            plugin_provider,
            settings,
            context,
            settings_prefix=plugin_manager_settings_prefix)

        if self._options.list_plugins:
            # output available plugins
            print('\n'.join(sorted(plugin_manager.get_plugins().values())))
            return 0

        help_provider = HelpProvider()
        plugin_manager.plugin_help_signal.connect(
            help_provider.plugin_help_request)

        # setup perspective manager
        if main_window is not None:
            perspective_manager = PerspectiveManager(settings, context)

            if self._options.list_perspectives:
                # output available perspectives
                print('\n'.join(sorted(perspective_manager.perspectives)))
                return 0
        else:
            perspective_manager = None

        if main_window is not None:
            container_manager = ContainerManager(main_window, plugin_manager)
            plugin_manager.set_main_window(main_window, menu_bar,
                                           container_manager)

            if not self._options.freeze_layout:
                minimized_dock_widgets_toolbar = MinimizedDockWidgetsToolbar(
                    container_manager, main_window)
                main_window.addToolBar(Qt.BottomToolBarArea,
                                       minimized_dock_widgets_toolbar)
                plugin_manager.set_minimized_dock_widgets_toolbar(
                    minimized_dock_widgets_toolbar)

        if menu_bar is not None:
            perspective_menu = menu_bar.addMenu(menu_bar.tr('P&erspectives'))
            perspective_manager.set_menu(perspective_menu)

        # connect various signals and slots
        if perspective_manager is not None and main_window is not None:
            # signal changed perspective to update window title
            perspective_manager.perspective_changed_signal.connect(
                main_window.perspective_changed)
            # signal new settings due to changed perspective
            perspective_manager.save_settings_signal.connect(
                main_window.save_settings)
            perspective_manager.restore_settings_signal.connect(
                main_window.restore_settings)
            perspective_manager.restore_settings_without_plugin_changes_signal.connect(
                main_window.restore_settings)

        if perspective_manager is not None and plugin_manager is not None:
            perspective_manager.save_settings_signal.connect(
                plugin_manager.save_settings)
            plugin_manager.save_settings_completed_signal.connect(
                perspective_manager.save_settings_completed)
            perspective_manager.restore_settings_signal.connect(
                plugin_manager.restore_settings)
            perspective_manager.restore_settings_without_plugin_changes_signal.connect(
                plugin_manager.restore_settings_without_plugins)

        if plugin_manager is not None and main_window is not None:
            # signal before changing plugins to save window state
            plugin_manager.plugins_about_to_change_signal.connect(
                main_window.save_setup)
            # signal changed plugins to restore window state
            plugin_manager.plugins_changed_signal.connect(
                main_window.restore_state)
            # signal save settings to store plugin setup on close
            main_window.save_settings_before_close_signal.connect(
                plugin_manager.close_application)
            # signal save and shutdown called for all plugins, trigger closing main window again
            plugin_manager.close_application_signal.connect(
                main_window.close, type=Qt.QueuedConnection)

        if main_window is not None and menu_bar is not None:
            about_handler = AboutHandler(context.qtgui_path, main_window)
            help_menu = menu_bar.addMenu(menu_bar.tr('&Help'))
            action = QAction(help_menu.tr('&About'), help_menu)
            action.setIcon(QIcon.fromTheme('help-about'))
            action.triggered.connect(about_handler.show)
            help_menu.addAction(action)

        # set initial size - only used without saved configuration
        if main_window is not None:
            main_window.resize(600, 450)
            main_window.move(100, 100)

        # ensure that qt_gui/src is in sys.path
        src_path = os.path.realpath(
            os.path.join(os.path.dirname(__file__), '..'))
        if src_path not in sys.path:
            sys.path.append(src_path)

        # load specific plugin
        plugin = None
        plugin_serial = None
        if self._options.embed_plugin is not None:
            plugin = self._options.embed_plugin
            plugin_serial = self._options.embed_plugin_serial
        elif self._options.standalone_plugin is not None:
            plugin = self._options.standalone_plugin
            plugin_serial = 0
        if plugin is not None:
            plugins = plugin_manager.find_plugins_by_name(plugin)
            if len(plugins) == 0:
                print('qt_gui_main() found no plugin matching "%s"' % plugin)
                print('try passing the option "--force-discover"')
                return 1
            elif len(plugins) > 1:
                print(
                    'qt_gui_main() found multiple plugins matching "%s"\n%s' %
                    (plugin, '\n'.join(plugins.values())))
                return 1
            plugin = list(plugins.keys())[0]

        qDebug('QtBindingHelper using %s' % QT_BINDING)

        plugin_manager.discover()

        if self._options.reload_import:
            qDebug(
                'ReloadImporter() automatically reload all subsequent imports')
            from qt_gui.reload_importer import ReloadImporter
            _reload_importer = ReloadImporter()
            self._add_reload_paths(_reload_importer)
            _reload_importer.enable()

        # switch perspective
        if perspective_manager is not None:
            if plugin:
                perspective_manager.set_perspective(
                    plugin, hide_and_without_plugin_changes=True)
            elif self._options.perspective_file:
                perspective_manager.import_perspective_from_file(
                    self._options.perspective_file,
                    perspective_manager.HIDDEN_PREFIX +
                    os.path.basename(self._options.perspective_file))
            else:
                perspective_manager.set_perspective(self._options.perspective)

        # load specific plugin
        if plugin:
            plugin_manager.load_plugin(plugin, plugin_serial,
                                       self._options.plugin_args)
            running = plugin_manager.is_plugin_running(plugin, plugin_serial)
            if not running:
                return 1
            if self._options.standalone_plugin:
                # use icon of standalone plugin (if available) for application
                plugin_descriptor = plugin_manager.get_plugin_descriptor(
                    plugin)
                action_attributes = plugin_descriptor.action_attributes()
                if 'icon' in action_attributes and action_attributes[
                        'icon'] is not None:
                    base_path = plugin_descriptor.attributes().get(
                        'plugin_path')
                    try:
                        icon = get_icon(
                            action_attributes['icon'],
                            action_attributes.get('icontype', None), base_path)
                    except UserWarning:
                        pass
                    else:
                        app.setWindowIcon(icon)

        if main_window is not None:
            main_window.show()
            if sys.platform == 'darwin':
                main_window.raise_()

        return app.exec_()
コード例 #57
0
 def __init__(self):
     session_bus = SessionBus()
     self.player_engine = session_bus.get_object(self.BANSHEE_OBJECT, self.PLAYER_ENGINE_NODE)
コード例 #58
0
#!/usr/bin/env python

from dbus import SessionBus, Interface

bus = SessionBus()
mpris_obj = bus.get_object('org.gnome.Rhythmbox3', '/org/mpris/MediaPlayer2')
rb_plm_obj = bus.get_object('org.gnome.Rhythmbox3',
                            '/org/gnome/Rhythmbox3/PlaylistManager')
mpris_introspectable = Interface(mpris_obj,
                                 'org.freedesktop.DBus.Introspectable')

rb_plm_introspectable = Interface(rb_plm_obj,
                                  'org.freedesktop.DBus.Introspectable')

with open('org.mpris.MediaPlayer2.rhythmbox.xml', 'w') as mpris_xml:
    print >> mpris_xml, mpris_introspectable.Introspect()

with open('org.gnome.Rhythmbox3.PlaylistManager.xml', 'w') as rb_plm_xml:
    print >> rb_plm_xml, rb_plm_introspectable.Introspect()