Exemple #1
0
 def post_config_hook(self):
     if self.user:
         bus = SessionBus()
     else:
         bus = SystemBus()
     systemd = bus.get("org.freedesktop.systemd1")
     self.systemd_unit = bus.get(".systemd1", systemd.LoadUnit(self.unit))
Exemple #2
0
    def _init_dbus(self):
        """
        Get the device id
        """
        _bus = SessionBus()

        if self.device_id is None:
            self.device_id = self._get_device_id(_bus)
            if self.device_id is None:
                return False

        try:
            self._dev = _bus.get(SERVICE_BUS,
                                 DEVICE_PATH + f"/{self.device_id}")
            try:
                self._bat = _bus.get(
                    SERVICE_BUS,
                    DEVICE_PATH + f"/{self.device_id}" + BATTERY_SUBPATH)
                self._not = _bus.get(
                    SERVICE_BUS,
                    DEVICE_PATH + f"/{self.device_id}" + NOTIFICATIONS_SUBPATH,
                )
            except Exception:
                # Fallback to the old version
                self._bat = None
                self._not = None
        except Exception:
            return False

        return True
Exemple #3
0
def main(args):
    bus = SessionBus()
    loop = GLib.MainLoop()

    def new_wallpaper():
        wg.NewWallpaper(args.type, args.subreddit, args.directory, args.output,
                        args.generate_only)

    if args.dbus:
        bus.publish('de.thm.mni.mhpp11.WallGen', WallGenDBUSService(loop))
        run(loop)
    else:
        try:
            wg = bus.get('de.thm.mni.mhpp11.WallGen')
        except GLib.Error:
            wg = WallGenDBUSService(None)
        if type(wg) != WallGenDBUSService:
            if args.monitor:
                dc = bus.get('org.gnome.Mutter.DisplayConfig')
                with wg.Closed.connect(loop.quit):
                    with dc.MonitorsChanged.connect(new_wallpaper):
                        run(loop)
            elif args.quit:
                wg.Close()
        if not args.monitor:
            new_wallpaper()
        elif type(wg) == WallGenDBUSService:
            raise Exception("Monitoring is not possible without DBus service!")
Exemple #4
0
 def post_config_hook(self):
     if self.user:
         bus = SessionBus()
     else:
         bus = SystemBus()
     systemd = bus.get("org.freedesktop.systemd1")
     self.systemd_unit = bus.get(".systemd1", systemd.LoadUnit(self.unit))
Exemple #5
0
class SystemdSession(object):
    def __init__(self):
        self.session_bus = SessionBus()
        self.systemd = self.session_bus.get('org.freedesktop.systemd1')

    def get_unit(self, name):
        unit_object = self.systemd.LoadUnit(name)
        return SystemdUnit(name, self.session_bus.get('.systemd1',
                                                      unit_object),
                           self.systemd)
Exemple #6
0
def main():
    LOG_FOLDER = sys.argv[1]
    try:
        DBUS_INTERFACE = sys.argv[2]
    except IndexError:
        DBUS_INTERFACE = 'org.gnome.ScreenSaver'
    STARTUP_TIME = datetime.now()
    logging.getLogger().setLevel(logging.INFO)

    loop = GLib.MainLoop()
    bus = SessionBus()
    try:
        dev = bus.get(DBUS_INTERFACE)
    except ValueError:
        logging.error(
            "Failed opening D-Bus interface '{}'\nexiting ...".format(
                DBUS_INTERFACE))
        sys.exit(1)

    handler = create_event_handler(LOG_FOLDER, STARTUP_TIME)

    try:
        with dev.ActiveChanged.connect(handler) as bus_ses:
            logging.info("Succesfully registered handler for D-Bus event '{}' "
                         "on interface '{}'".format('ActiveChanged',
                                                    DBUS_INTERFACE))
            loop.run()
    except AttributeError as e:
        logging.error("Failed registering handler for D-Bus event '{}' "
                      "on interface '{}' ({})\nexiting ...".format(
                          'ActiveChanged', DBUS_INTERFACE, e))
        sys.exit(1)
Exemple #7
0
    def __init__(self):
        super(GUI, self).__init__(application_id=APPLICATION_ID,
                                  flags=Gio.ApplicationFlags.FLAGS_NONE)
        self.builder = Gtk.Builder()
        self.builder.set_application(self)
        self.builder.add_from_file(GUI_GLADE_PATH)

        signals = {
            "on_volume_changed": self.on_volume_changed,
            "on_streaming_activate": self.on_streaming_activate,
            "on_streaming_refresh": self.on_streaming_refresh,
            "on_web_page_activate": self.on_web_page_activate,
            "on_web_page_refresh": self.on_web_page_refresh,
            "on_blur_radius_changed": self.on_blur_radius_changed
        }
        self.builder.connect_signals(signals)

        self.window = None
        self.local_video_icon_view = None
        self.local_video_list = None

        self.is_autostart = os.path.isfile(AUTOSTART_DESKTOP_PATH)

        bus = SessionBus()
        try:
            self.server = bus.get(DBUS_NAME)
        except GLib.Error:
            dialog = Gtk.MessageDialog(
                text="Oops!",
                message_type=Gtk.MessageType.ERROR,
                secondary_text="Couldn't connect to server",
                buttons=Gtk.ButtonsType.OK)
            dialog.run()
            dialog.destroy()
            print("Error: Couldn't connect to server")
Exemple #8
0
def notify(message):
    try:
        bus = SessionBus()
        notifier = bus.get(".Notifications")
        notifier.Notify("home.py", 0, "", "My backup", message, "", "", 10000)
    except GLib.Error:
        pass
Exemple #9
0
    def NewWallpaper(self, type, subreddit, directory, output, generate_only):
        print("Create a new Wallpaper...")
        bus = SessionBus()
        dc = bus.get('org.gnome.Mutter.DisplayConfig')

        if type == 'reddit':
            generator = reddit_generator
            option = subreddit
        else:
            generator = local_generator
            option = directory

        active_monitors = []
        for monitor in dc.GetResources()[1]:
            if monitor[6] > -1:
                active_monitors.append(monitor)
        (max_width, max_height) = get_maximum_resolution(active_monitors)
        with Image(width=max_width, height=max_height) as wallpaper:
            for monitor in active_monitors:
                image = generator.get_image(option,
                                            width=monitor[4],
                                            height=monitor[5])
                wallpaper.composite(image, left=monitor[2], top=monitor[3])
                with wallpaper.convert('png') as converted:
                    save(converted, output, generate_only)
def spotibus_connect():
    """ The DBUS INTERFACE with the Spotify Desktop client.

        You can browse it also by command line tool:
        $ mdbus2 org.mpris.MediaPlayer2.spotify /org/mpris/MediaPlayer2

        (bool)
    """
    global spotibus

    spotibus = None
    tries = 3
    while tries:
        try:
            # SessionBus will work if D-Bus has an available X11 $DISPLAY
            bus      = SessionBus()
            spotibus = bus.get( 'org.mpris.MediaPlayer2.spotify',
                                '/org/mpris/MediaPlayer2' )
            logging.info(f'spotibus OK')
            return True
        except Exception as e:
            logging.info(f'spotibus FAILED: {e}')
            tries -= 1
            sleep(.1)
    return False
Exemple #11
0
    class DbusHooks(hooks_base_class):
        def __init__(self):
            super().__init__()
            self._bus = SessionBus()
            self._bot = None
            self._log = PladderLogProxy(self._bus)

        def on_trigger(self, timestamp, network, channel, sender, text):
            retry = True
            while True:
                try:
                    if self._bot is None:
                        self._bot = self._bus.get("se.raek.PladderBot")
                    return self._bot.RunCommand(timestamp, network, channel, sender.nick, text)
                except GLib.Error as e:
                    if "org.freedesktop.DBus.Error.ServiceUnknown" in str(e):
                        if retry:
                            retry = False
                            self._bot = None
                            continue
                        else:
                            self._bot = None
                            return "Internal error: could not reach pladder-bot. Please check the log: \"journalctl --user-unit pladder-bot.service -e\""
                    else:
                        logger.error(str(e))
                        return "Internal error: " + str(e)

        def on_privmsg(self, timestamp, network, channel, sender, text):
            self._log.AddLine(timestamp, network, channel, sender.nick, text)

        def on_send_privmsg(self, timestamp, network, channel, nick, text):
            self._log.AddLine(timestamp, network, channel, nick, text)
def send_desktop_notification(title="Hello World", msg="pydbus works!"):
    """Send a notification to the desktop environment to display"""

    bus = SessionBus()
    notifications = bus.get('.Notifications')
    notifications.Notify('test', 0, 'dialog-information', title, msg, [], {},
                         5000)
Exemple #13
0
def main():
    parser = argparse.ArgumentParser()
    parser.add_argument(
        "--dbus",
        action="store_true",
        help=
        "Connect to existing pladder-bot service instead of running command directly."
    )
    parser.add_argument("--state-dir",
                        help="Directory where bot keeps its state")
    parser.add_argument(
        "-c",
        "--command",
        help="Run this command instead of reading commands from stdin.")
    args = parser.parse_args()
    if args.dbus:
        from pydbus import SessionBus  # type: ignore
        bus = SessionBus()
        bot = bus.get("se.raek.PladderBot")
        run_commands(bot, args.command)
    else:
        from pladder.bot import PladderBot, load_standard_plugins
        state_dir = args.state_dir or default_state_dir()
        with PladderBot(state_dir, None) as bot:
            load_standard_plugins(bot)
            run_commands(bot, args.command)
Exemple #14
0
def start():
    args = parse_arguments()
    config = Config()
    if not config.is_supported_desktop():
        raise Exception('Desktop environment not supported.')

    bus = SessionBus()
    loop = GLib.MainLoop()

    if args.dbus:
        bus.publish('de.thm.mni.mhpp11.WallGen', WallGenDBUSService(loop))
        run(loop)
    else:
        try:
            wg = bus.get('de.thm.mni.mhpp11.WallGen')
        except GLib.Error:
            wg = WallGenDBUSService(None)
        if type(wg) != WallGenDBUSService:
            if args.monitor:

                dc = None
                if config.is_gnome():
                    dc = bus.get('org.gnome.Mutter.DisplayConfig')
                elif config.is_kde():
                    dc = bus.get('org.kde.KScreen', object_path='/backend')
                with wg.Closed.connect(loop.quit):
                    if config.is_gnome():
                        with dc.MonitorsChanged.connect(wg.NewWallpaper):
                            run(loop)
                    elif config.is_kde():

                        class KDENewWallpaper:
                            first_call = True

                            def call(self, _):
                                if (self.first_call):
                                    wg.NewWallpaper()
                                self.first_call = not self.first_call

                        with dc.configChanged.connect(KDENewWallpaper().call):
                            run(loop)
            elif args.quit:
                wg.Close()
        elif type(wg) == WallGenDBUSService and args.monitor:
            raise Exception("Monitoring is not possible without DBus service!")
        if not args.monitor and not args.quit:
            wg.NewWallpaper()
Exemple #15
0
def _get_spotify_proxy():
    bus = SessionBus()
    try:
        proxy = bus.get('org.mpris.MediaPlayer2.spotify',
                        '/org/mpris/MediaPlayer2')
        return proxy
    except Exception:
        return None
    def trigger(self) -> None:
        """
        Sends a system notification
        """
        bus = SessionBus()
        notifications = bus.get('.Notifications')

        notifications.Notify('cwp', 0, 'dialog-information', self.title,
                             self.text, [], {}, self.mstime)
    def __init__(self):
        session_bus = SessionBus()

        self.player = session_bus.get(
            self.PLAYERCTLD_BUS,
            self.MEDIA_PLAYER_PATH,
        )

        self.was_playing = self.player.PlaybackStatus
Exemple #18
0
 def _get_session_bus(self):
     bus = SessionBus()
     try:
         proxy = bus.get('org.mpris.MediaPlayer2.spotify',
                         '/org/mpris/MediaPlayer2')
         return proxy
     except Exception as e:
         log.info('Failed to load session bus: %s', str(e))
         raise SpotifyError('Spotify is not running')
Exemple #19
0
 def __init__(self, bus_instance=None):
     if DBusNightLightManager._instance is None:
         DBusNightLightManager._instance = self
     if self.dbus_color_service is None:
         if bus_instance is None:
             bus_instance = SessionBus()
         self.dbus_color_service = bus_instance.get(
             'org.gnome.SettingsDaemon.Color', '/org/gnome/SettingsDaemon/Color')
         self.dbus_color_service.onPropertiesChanged = self.processNightLightInvocation
Exemple #20
0
def disable(settings, **kwargs):
    try:
        bus = SessionBus()
        systemd = bus.get(".systemd1")
        if systemd.DisableUnitFiles(["rammon.service"], False):
            print("Disabled rammon, it will no longer auto-start")
            sys.exit(0)
    except GError:
        pass
    print("Rammon is already disabled")
    sys.exit(1)
Exemple #21
0
    def __wait_dbus_object(self):
        bus = SessionBus()
        while True:
            try:
                os.waitpid(self.__pid, os.P_NOWAIT)
            except OSError:
                raise RuntimeError('KTimeTracker process stopped unexpectedly')

            try:
                return bus.get('org.kde.ktimetracker', '/KTimeTracker')
            except GLib.Error:
                time.sleep(0.5)
Exemple #22
0
    def info(self):
        tod_time = time.strftime("%a, %d %b %Y %H:%M:%S",
                                 time.localtime(start_time))
        message_string = ("Wheel circumference: {} meters\n"
                          "Start time: {}\n"
                          "GPIO Channel Number: {}".format(
                              wheel_circumference, tod_time, channel))

        bus_1 = SessionBus()
        notifications = bus_1.get('.Notifications')
        notifications.Notify('test', 0, 'dialog-information',
                             "Pydbus Server Information", message_string, [],
                             {}, 5000)
Exemple #23
0
    def notify(self, *args, **kwargs) -> None:
        """

        :return:
        """
        from pydbus import SessionBus

        Logger.debug(f'Application: notify({args} {kwargs})')
        bus = SessionBus()
        notifications = bus.get('.Notifications')

        notifications.Notify(NOTIFICATION_APP, self.msg_id, self.icon,
                             self.summary, self.msg, [], {}, 5000)
Exemple #24
0
def main():
    """ Entry point for this script. """
    # Get mpris2
    bus = SessionBus()
    mpris = bus.get("org.mpris.MediaPlayer2.clementine",
                    "/org/mpris/MediaPlayer2")

    if mpris is None or mpris.Metadata is None:
        sys.exit(1)

    # Get metadata
    md = mpris.Metadata
    status = mpris.PlaybackStatus.strip().lower()

    if status is None or mpris.Position is None:
        sys.exit(0)

    # Parse metadata
    statusIcons = {'paused': u'\uf04c',
                   'playing': u'\uf04b',
                   'stopped': u'\uf04d'}
    status = statusIcons[status] if status in statusIcons else '?'
    artist = md.get("xesam:artist")
    album = md.get("xesam:album")
    track = md.get("xesam:title")
    bitrate = md.get("bitrate")

    if artist is None:
        artist = "Unknown Artist"

    elif isinstance(artist, list) and artist:
        artist = artist[0]

    album = album if album is not None else "Unknown Album"
    track = track if track is not None else "Unknown Track"

    # Build result string
    icons = f'\uf025 {status} '
    result = f'{artist} - {album} - {track}'

    if bitrate is not None:
        result = f'{result} @ {bitrate} kbps'

    # Apply scroll effect based on the time and print result
    pos = mpris.Position
    posSeconds = (float(pos) / 1000000.0)
    strPos = int(posSeconds * ScrollFactor) % len(result)
    result = result[strPos:] + "    " + result[0:strPos]
    print(icons + result[:MaxCharacters])

    return 0
def main(args):

    bus = SessionBus()
    gmusic = bus.get('org.gmusicbrowser')

    pos = gmusic.GetPosition()

    if pos < 10:
        gmusic.RunCommand("PrevSong")

    else:
        gmusic.RunCommand("Rewind(20)")

    return 0
Exemple #26
0
def main():
    parser = argparse.ArgumentParser()
    parser.add_argument('param', type=int, help="Size in bytes to send to server")
    args = parser.parse_args()

    bus = SessionBus()

    server_proxy = bus.get('com.nstack.DbusTest')

    print("Sending ping - {}".format(args.param))
    output = server_proxy.Ping(bytes(args.param))
    print("Received pong - {}".format(output))

    return 0
Exemple #27
0
def execute_commands(command_list):
    """Executes the commands in the command list.

    **DANGER**

    This is VERY unsafe, as it passing the strings directly to `exec`"""
    from pydbus import SessionBus
    bus = SessionBus()
    Layout = bus.get(bus_name="org.way-cooler",
                     object_path="/org/way_cooler/Layout")
    for command in command_list:
        print("Executing command: \"{}\"".format(command))
        sleep(1)
        exec(command)
Exemple #28
0
    def info(self):
        tod_time = time.strftime("%a, %d %b %Y %H:%M:%S", 
                                 time.localtime(start_time))
        message_string = ("Wheel circumference: {} meters\n"
                          "Start time: {}\n"
                          "GPIO Channel Number: {}"
                          .format(wheel_circumference, tod_time, channel))

        bus_1 = SessionBus()
        notifications = bus_1.get('.Notifications')
        notifications.Notify('test', 0, 
                             'dialog-information', 
                             "Pydbus Server Information", 
                             message_string, 
                             [], {}, 5000)
Exemple #29
0
    def test_user_facing_interface(self):
        from pydbus import SessionBus
        import os
        import sys
        import time
        ppath = os.path.abspath(
            os.path.dirname(os.path.abspath(sys.modules[__name__].__file__)) +
            "/..")

        os.system('export PYTHONPATH="' + ppath + '";cd ' + ppath + ";" +
                  sys.executable + " -m tests.unittest_server&")
        #print(ppath)
        sb = SessionBus()
        tick = time.time() + 30
        test_server = None
        while time.time() < tick:
            try:
                test_server = sb.get('pydbus.unittest', timeout=10)
                break
            except:
                time.sleep(1)
                pass
        self.assertIsNotNone(test_server)
        r = test_server.NoArgsStringReply()
        self.assertEqual(r, 0, "Translation Inactive")
        r = test_server.AddTwo(2)
        self.assertEqual(r, 4, "Translation Inactive")

        test_server = sb.get('pydbus.unittest',
                             translation_spec=True,
                             timeout=10)
        r = test_server.NoArgsStringReply()
        self.assertEqual(r, "first string", "Translation Active")
        r = test_server.AddTwo(2)
        self.assertEqual(r, 4, "Translation Active")
        test_server.Quit()
Exemple #30
0
def set_up_dbus(hooks_base_class):
    from gi.repository import GLib
    from pydbus import SessionBus

    bus = SessionBus()
    bot = bus.get("se.raek.PladderBot")

    class DbusHooks(hooks_base_class):
        def on_trigger(self, sender, text):
            try:
                return bot.RunCommand(text)
            except GLib.Error as e:
                logger.error(str(e))
                return "Oops! Error logged."

    return DbusHooks
def hibernate():
    try:
        bus = SessionBus()
        power = bus.get('org.gnome.PowerManager', '/org/gnome/PowerManager')

        if power.CanHibernate():
            answer = input("Do you want to hibernate? [Y/n]:")
            if answer.lower() == "y":
                power.Hibernate()

        else:
            print("Cannot hibernate")

    except Exception as ex:
        print("Could not get PowerManager from DBUS")
        print(str(ex))
Exemple #32
0
def enable(**kwargs):
    os.umask(0o077)
    rammon_path = shutil.which("rammon")
    if rammon_path is None:
        print(
            "Could not find rammon in $PATH, this likely means it is installed in a virtualenv.\n"
            "Try leaving the virtualenv and installing with:\n"
            "   pip3 install --user rammon")
        sys.exit(1)
    if shutil.which("systemctl") is None:
        print(
            "Your system doesn't appear to be using systemd and is not currently supported.\n"
            "If you are interested in support for other init systems, please open an issue "
            "on Github.")
        sys.exit(1)
    rammon_unit_path = os.path.expanduser(
        "~/.local/share/systemd/user/rammon.service")
    os.makedirs(os.path.dirname(rammon_unit_path), exist_ok=True)
    if not os.path.exists(rammon_unit_path):
        print("Creating systemd unit at:\n"
              "   ~/.local/share/systemd/user/rammon.service")
        with open(rammon_unit_path, "w") as f:
            f.write(f"""[Unit]
Description=Memory usage monitor and notification daemon
[Service]
Type=simple
TimeoutStartSec=0
TimeoutStopSec=1
ExecStart={rammon_path} -d
Environment=LAUNCHED_FROM_SYSTEMD=1
Restart=on-failure
RestartSec=20

[Install]
WantedBy=default.target
""")
    bus = SessionBus()
    systemd = bus.get(".systemd1")
    if systemd.GetUnitFileState("rammon.service") == "enabled":
        print("Rammon auto-start is already enabled")
        sys.exit(1)
    if systemd.EnableUnitFiles(["rammon.service"], False, False)[0]:
        print("Rammon enable and will now start on login!")
    else:
        print("Rammon failed to be enabled and I don't know why...\n"
              "Try enabling it manually with:\n"
              "   systemctl enable --user rammon")
Exemple #33
0
    def _init_dbus(self):
        """
        Get the device id
        """
        _bus = SessionBus()

        if self.device_id is None:
            self.device_id = self._get_device_id(_bus)
            if self.device_id is None:
                return False

        try:
            self._dev = _bus.get(SERVICE_BUS, DEVICE_PATH + "/%s" % self.device_id)
        except Exception:
            return False

        return True
Exemple #34
0
		done += 1
		if done == 2:
			loop.quit()
		return "M1"

	def Method2(self):
		global done
		done += 1
		if done == 2:
			loop.quit()
		return "M2"

bus = SessionBus()

with bus.publish("net.lew21.pydbus.tests.expose_multiface", TestObject()):
	remote = bus.get("net.lew21.pydbus.tests.expose_multiface")

	def t1_func():
		print(remote.Method1())
		print(remote.Method2())

	t1 = Thread(None, t1_func)
	t1.daemon = True

	def handle_timeout():
		print("ERROR: Timeout.")
		sys.exit(1)

	GLib.timeout_add_seconds(2, handle_timeout)

	t1.start()
Exemple #35
0
#!/usr/bin/python3

import os
import sys
import datetime
import json
import subprocess
from time import sleep
from pydbus import SessionBus
from glob import glob


BUS = SessionBus()
LAYOUT = BUS.get(bus_name='org.way-cooler', object_path='/org/way_cooler/Layout')


def main():
    while True:
        layout = json.loads(LAYOUT.Debug())
        workspaces = get_workspaces(layout)
        workspaces.sort()
        active_workspace = ""
        try:
            active_workspace = LAYOUT.ActiveWorkspace()
        except Exception:
            pass
        workspaces = " ".join(workspaces)
        workspaces = format_workspaces(layout, workspaces, active_workspace)
        funcs = [workspaces + "%{c}",
                 lambda: get_time() + "%{r}",
                 my_get_temp,
    def __init__(self, bucket, loop, *args, **kargs):
        self.bucket = bucket
        self.loop = loop
        self.running = True
        self._stop = threading.Event()
        self.queue = Queue.Queue(10)

        # NOTE: enumerate req to iterate through tuple and find GVariant
        @trace
        def player_cb(*args, **kwargs):
            if SCARLETT_DEBUG:
                logger.debug("player_cb PrettyPrinter: ")
                pp = pprint.PrettyPrinter(indent=4)
                pp.pprint(args)
            for i, v in enumerate(args):
                if SCARLETT_DEBUG:
                    logger.debug("Type v: {}".format(type(v)))
                    logger.debug("Type i: {}".format(type(i)))
                if type(v) is gi.overrides.GLib.Variant:
                    if SCARLETT_DEBUG:
                        logger.debug(
                            "THIS SHOULD BE A Tuple now: {}".format(v))
                    msg, scarlett_sound = v
                    logger.warning(" msg: {}".format(msg))
                    logger.warning(
                        " scarlett_sound: {}".format(scarlett_sound))
                    # NOTE: Create something like test_gdbus_player.ScarlettPlayer('pi-listening')
                    # NOTE: test_gdbus_player.ScarlettPlayer
                    # NOTE: self.bucket.put()
                    # NOTE: ADD self.queue.put(v)

        # NOTE: enumerate req to iterate through tuple and find GVariant
        @trace
        def command_cb(*args, **kwargs):
            if SCARLETT_DEBUG:
                logger.debug("player_cb PrettyPrinter: ")
                pp = pprint.PrettyPrinter(indent=4)
                pp.pprint(args)
            for i, v in enumerate(args):
                if SCARLETT_DEBUG:
                    logger.debug("Type v: {}".format(type(v)))
                    logger.debug("Type i: {}".format(type(i)))
                if type(v) is gi.overrides.GLib.Variant:
                    if SCARLETT_DEBUG:
                        logger.debug(
                            "THIS SHOULD BE A Tuple now: {}".format(v))
                    msg, scarlett_sound, command = v
                    logger.warning(" msg: {}".format(msg))
                    logger.warning(
                        " scarlett_sound: {}".format(scarlett_sound))
                    logger.warning(" command: {}".format(command))
                    # NOTE: Create something like test_gdbus_player.ScarlettPlayer('pi-listening')
                    # NOTE: test_gdbus_player.ScarlettPlayer
                    # NOTE: self.bucket.put()
                    # NOTE: ADD self.queue.put(v)

        # with SessionBus() as bus:
        bus = SessionBus()
        ss = bus.get("org.scarlett", object_path='/org/scarlett/Listener')

        # SttFailedSignal / player_cb
        ss_failed_signal = bus.con.signal_subscribe(None,
                                                    "org.scarlett.Listener",
                                                    "SttFailedSignal",
                                                    '/org/scarlett/Listener',
                                                    None,
                                                    0,
                                                    player_cb)

        # ListenerReadySignal / player_cb
        ss_rdy_signal = bus.con.signal_subscribe(None,
                                                 "org.scarlett.Listener",
                                                 "ListenerReadySignal",
                                                 '/org/scarlett/Listener',
                                                 None,
                                                 0,
                                                 player_cb)

        # KeywordRecognizedSignal / player_cb
        ss_kw_rec_signal = bus.con.signal_subscribe(None,
                                                    "org.scarlett.Listener",
                                                    "KeywordRecognizedSignal",
                                                    '/org/scarlett/Listener',
                                                    None,
                                                    0,
                                                    player_cb)

        # CommandRecognizedSignal /command_cb
        ss_cmd_rec_signal = bus.con.signal_subscribe(None,
                                                     "org.scarlett.Listener",
                                                     "CommandRecognizedSignal",
                                                     '/org/scarlett/Listener',
                                                     None,
                                                     0,
                                                     command_cb)

        # ListenerCancelSignal / player_cb
        ss_cancel_signal = bus.con.signal_subscribe(None,
                                                    "org.scarlett.Listener",
                                                    "ListenerCancelSignal",
                                                    '/org/scarlett/Listener',
                                                    None,
                                                    0,
                                                    player_cb)

        # NOTE: print dir(ss)
        # NOTE: # Quit mainloop
        # NOTE: self.quit = ss.quit()

        # NOTE: # let listener know when we connect to it
        # NOTE: self._tasker_connected = ss.emitConnectedToListener("{}".format(
        # NOTE:
        # self._tasker_connected(ScarlettTasker().__class__.__name__)))

        logger.debug("ss PrettyPrinter: ")
        pp = pprint.PrettyPrinter(indent=4)
        pp.pprint(ss)
Exemple #37
0
	def __init__(self, id):
		self.id = id

	def HelloWorld(self, a, b):
		res = self.id + ": " + a + str(b)
		global done
		done += 1
		if done == 2:
			loop.quit()
		print(res)
		return res

bus = SessionBus()

with bus.publish("net.lew21.pydbus.Test", TestObject("Main"), ("Lol", TestObject("Lol"))):
	remoteMain = bus.get("net.lew21.pydbus.Test")
	remoteLol = bus.get("net.lew21.pydbus.Test", "Lol")

	def t1_func():
		print(remoteMain.HelloWorld("t", 1))

	def t2_func():
		print(remoteLol.HelloWorld("t", 2))

	t1 = Thread(None, t1_func)
	t2 = Thread(None, t2_func)
	t1.daemon = True
	t2.daemon = True

	def handle_timeout():
		print("ERROR: Timeout.")
Exemple #38
0
		<property name="Bar" type="s" access="write"/>
		<method name='Quit'/>
	</interface>
</node>
	'''
	def __init__(self):
		self.Foo = "foo"
		self.Foobar = "foobar"

	def Quit(self):
		loop.quit()

bus = SessionBus()

with bus.publish("net.lew21.pydbus.tests.publish_properties", TestObject()):
	remote = bus.get("net.lew21.pydbus.tests.publish_properties")
	remote_iface = remote['net.lew21.pydbus.tests.publish_properties']

	def t1_func():
		for obj in [remote, remote_iface]:
			assert(obj.Foo == "foo")
			assert(obj.Foobar == "foobar")
			obj.Foobar = "barfoo"
			assert(obj.Foobar == "barfoo")
			obj.Foobar = "foobar"
			assert(obj.Foobar == "foobar")
			obj.Bar = "rab"

		remote.Foobar = "barfoo"

		try:
    def __init__(self, *args):
        _IdleObject.__init__(self)
        context = GObject.MainContext.default()

        self.bucket = bucket = Queue.Queue()  # NOQA
        self.hello = None

        # with SessionBus() as bus:
        bus = SessionBus()
        ss = bus.get("org.scarlett", object_path='/org/scarlett/Listener')  # NOQA
        time.sleep(1)

        ss_failed_signal = bus.subscribe(sender=None,
                                         iface="org.scarlett.Listener",
                                         signal="SttFailedSignal",
                                         object="/org/scarlett/Listener",
                                         arg0=None,
                                         flags=0,
                                         signal_fired=player_cb)

        ss_rdy_signal = bus.subscribe(sender=None,
                                      iface="org.scarlett.Listener",
                                      signal="ListenerReadySignal",
                                      object="/org/scarlett/Listener",
                                      arg0=None,
                                      flags=0,
                                      signal_fired=player_cb)

        ss_kw_rec_signal = bus.subscribe(sender=None,
                                         iface="org.scarlett.Listener",
                                         signal="KeywordRecognizedSignal",
                                         object="/org/scarlett/Listener",
                                         arg0=None,
                                         flags=0,
                                         signal_fired=player_cb)

        ss_cmd_rec_signal = bus.subscribe(sender=None,
                                          iface="org.scarlett.Listener",
                                          signal="CommandRecognizedSignal",
                                          object="/org/scarlett/Listener",
                                          arg0=None,
                                          flags=0,
                                          signal_fired=command_cb)

        ss_cancel_signal = bus.subscribe(sender=None,
                                         iface="org.scarlett.Listener",
                                         signal="ListenerCancelSignal",
                                         object="/org/scarlett/Listener",
                                         arg0=None,
                                         flags=0,
                                         signal_fired=player_cb)

        pp.pprint((ss_failed_signal,
                   ss_rdy_signal,
                   ss_kw_rec_signal,
                   ss_cmd_rec_signal,
                   ss_cancel_signal))

        logger.debug("ss_failed_signal: {}".format(ss_failed_signal))
        logger.debug("ss_rdy_signal: {}".format(ss_rdy_signal))
        logger.debug("ss_kw_rec_signal: {}".format(ss_kw_rec_signal))
        logger.debug("ss_cmd_rec_signal: {}".format(ss_cmd_rec_signal))
        logger.debug("ss_cancel_signal: {}".format(ss_cancel_signal))

        ss.emitConnectedToListener('ScarlettTasker')

        loop.run()

        # THE ACTUAL THREAD BIT
        # self.manager = FooThreadManager(3)

        try:
            print("ScarlettTasker Thread Started")
        except Exception:
            ss_failed_signal.disconnect()
            ss_rdy_signal.disconnect()
            ss_kw_rec_signal.disconnect()
            ss_cmd_rec_signal.disconnect()
            ss_cancel_signal.disconnect()
            loop.quit()
            self.bucket.put(sys.exc_info())
            raise
Exemple #40
0
from pydbus import SessionBus

# TODO I'm not happy with the naming of this module. -> Find a better name
# TODO check for privileges to suspend

bus = SessionBus()
power = bus.get('org.freedesktop.UPower', '/org/freedesktop/UPower')


def suspend():
    power.Suspend()


def hibernate():
    power.Hibernate()


if __name__ == '__main__':
    suspend()

Exemple #41
0
"""https://github.com/LEW21/pydbus"""

import sys
sys.path += ['pydbus/']

from pydbus import SessionBus

bus = SessionBus()
notifications = bus.get('.Notifications')

notifications.Notify('test', 0, 'dialog-information', "Hello World!", "pydbus works :)", [], {}, 5000)
class KDEConnectNotify():
    """
    """
    # available configuration parameters
    device_id = None

    debug = None
    terminal = None
    libnotify = None
    ignore = None

    _bus = None
    _dev = None

    def __init__(self, use_terminal = True,
                 use_libnotify = True,
                 debug = False,
                 device_id = None,
                 device_name = None,
                 ignore = None):
        """
        Get the device id
        """
        self.terminal = use_terminal
        self.libnotify = use_libnotify
        self.debug = debug

        if ignore:
            self.ignore = [app.lower() for app in ignore]

        if not self.terminal:
            self._debug('hide terminal messages')

        if not self.libnotify:
            self._debug('hide notifications')

        if use_libnotify:
            Notify.init('KDEConnect Notify')

        if ignore:
            apps = ignore[0]
            for app in ignore[1:]:
                apps += ', ' + app
            self._debug('ignore ' + apps)

        self._bus = SessionBus()

        if device_id is None:
            self.device_id = self._get_device_id(device_id, device_name)
            if self.device_id is None:
                self._debug('No device id found')
                return
        else:
            self.device_id = device_id

        self._debug('Device id is %s' % self.device_id)
        try:
            self._dev = self._bus.get(SERVICE_BUS,
                                      DEVICE_PATH + '/%s' % self.device_id)
        except Exception:
            self.device_id = None
            return

    def _get_device_id(self, device_id, device_name):
        """
        Find the device id
        """
        _dbus = self._bus.get(SERVICE_BUS, PATH)
        devices = _dbus.devices()

        if device_name is None and device_id is None and len(devices) == 1:
            return devices[0]

        self._debug('Search device name \'%s\'' % device_name)
        for id in devices:
            self._dev = self._bus.get(SERVICE_BUS, DEVICE_PATH + '/%s' % id)
            if device_name == self._dev.name:
                return id

        return None

    def _debug(self, text):
        if self.debug:
            print(text)

    def _print(self, text):
        if self.terminal:
            print(text)

    def _merge(self, notifies):
        merged = []

        for notif in notifies:
            found = None
            sep = notif['text'].find('‐')
            title = notif['app_name']
            body = {
                'text': notif['text'][:sep-1],
                'desc': '<i>' + notif['text'][sep+2:] + '</i>'
            }

            for entry in merged:
                if entry['title'] == title:
                    found = entry
                    break

            if found:
                found['body'].append(body)
            else:
                merged.append({
                    'title': title,
                    'body': [body]
                })

        return merged

    def _notify(self, summary, body, category = 'dialog-information'):
        if self.libnotify:
            notify = Notify.Notification.new(summary, body, category)
            notify.show()

    def _get_device(self):
        """
        Get the device
        """
        try:
            device = {
                'name': self._dev.name,
                'isReachable': self._dev.isReachable,
                'isTrusted': self._dev.isTrusted,
            }
        except Exception:
            return None

        return device

    def _get_notification_ids(self):
        """
        Get notification ids
        """
        try:
            return self._dev.activeNotifications()
        except Exception:
            return None

    def _get_notification(self, id):
        """
        Get the notification text
        """
        try:
            _path = DEVICE_PATH + '/' + self.device_id + '/notifications/' + id
            _notify = self._bus.get(SERVICE_BUS, _path)
            notification = {
                'app_name': _notify.appName,
                'text': _notify.ticker
            }
            return notification

        except Exception:
            return None

    def show_notifications(self):
        """
        Get the current metadatas
        """
        if self.device_id is None:
            self._print('No device found')
            self._notify('KDEConnect Notify', 'No device found')
            return False

        device = self._get_device()

        if device is None:
            summary = 'KDEConnect Notify'
        else:
            summary = device['name']

        if device is None or not device['isReachable'] or not device['isTrusted']:
            self._print('Device is disconnected')
            self._notify(summary, 'Device is disconnected')
            return False

        ids = self._get_notification_ids()

        notifies = []
        for id in ids:
            notif = self._get_notification(id)

            if notif is None:
                self._print('  Couldn\'t read any notification')
                self._notify(summary, 'Couldn\'t read any notification')
                return False

            if not self.ignore or notif['app_name'].lower() not in self.ignore:
                notifies.append(notif)

        size = len(notifies)

        self._debug('%s notifications available' % size)
        self._print(summary + ':')
        if size == 0:
            self._print('  No notifications available')
            self._notify(summary, 'No notifications available')
            return True

        for notif in notifies:
            prefix = id + ' ' if self.debug else ''
            self._print('  ' + prefix + notif['app_name'] + ': ' + notif['text'])

        if not self.libnotify:
            return True

        notifies = self._merge(notifies)

        for notif in notifies:
            if len(notif['body']) == 1:
                body = notif['body'][0]
                text = body['text'] + '\n' + body['desc']
            else:
                text = ""
                for body in notif['body']:
                    text += body['text'] + ' - ' + body['desc'] + '\n'

            self._notify(notif['title'], text)

        return True
Exemple #43
0
class ScarlettListenerI(threading.Thread, _IdleObject):
    """
    Attempt to take out all Gstreamer logic and put it in a
    class ouside the dbus server.
    Cancellable thread which uses gobject signals to return information
    to the GUI.
    """

    __gsignals__ = SCARLETT_LISTENER_I_SIGNALS

    device = PS_DEVICE
    hmm = HMM_PATH
    lm = LM_PATH
    dic = DICT_PATH

    # __dr = None
    __instance = None

    MAX_FAILURES = 10

    def __init__(self, name, config_manager, *args):
        threading.Thread.__init__(self)
        _IdleObject.__init__(self)

        self.running = False
        self.finished = False
        self.ready_sem = threading.Semaphore(SEMAPHORE_NUM)
        self.queue = queue.Queue(QUEUE_SIZE)

        # Load in config object, and set default device information
        self._config_manager = config_manager
        self._graphviz_debug_dir = self._config_manager.cfg["graphviz_debug_dir"]

        self._device = self._config_manager.cfg["pocketsphinx"]["device"]
        self._hmm = self._config_manager.cfg["pocketsphinx"]["hmm"]
        self._lm = self._config_manager.cfg["pocketsphinx"]["lm"]
        self._dic = self._config_manager.cfg["pocketsphinx"]["dict"]
        self._fwdflat = bool(self._config_manager.cfg["pocketsphinx"]["fwdflat"])
        self._bestpath = bool(self._config_manager.cfg["pocketsphinx"]["bestpath"])
        self._dsratio = int(self._config_manager.cfg["pocketsphinx"]["dsratio"])
        self._maxhmmpf = int(self._config_manager.cfg["pocketsphinx"]["maxhmmpf"])
        self._bestpath = bool(self._config_manager.cfg["pocketsphinx"]["bestpath"])
        self._silprob = float(self._config_manager.cfg["pocketsphinx"]["silprob"])
        self._wip = float(self._config_manager.cfg["pocketsphinx"]["wip"])

        # dotfile setup
        self._dotfile_listener = os.path.join(
            self._graphviz_debug_dir, "generator-listener.dot"
        )
        self._pngfile_listener = os.path.join(
            self._graphviz_debug_dir, "generator-listener-pipeline.png"
        )

        # self._handler = DbusSignalHandler()

        # Get a dbus proxy and check if theres a service registered called 'org.scarlett.Listener'
        # if not, then we can skip all further processing. (The scarlett-os-mpris-dbus seems not to be running)
        # self.__dr = DBusRunner.get_instance()

        logger.info("Initializing ScarlettListenerI")

        # This wil get filled with an exception if opening fails.
        self.read_exc = None
        self.dot_exc = None

        self.cancelled = False
        self.name = name
        self.setName("{}".format(self.name))

        self.pipelines_stack = []
        self.elements_stack = []
        self.gst_bus_stack = []

        self._message = "This is the ScarlettListenerI"
        # TODO: When we're ready to unit test, config this back in!!!!!
        # self.config = scarlett_config.Config()
        self.config = None
        self.override_parse = ""
        self.failed = 0
        self.kw_found = 0
        self.debug = False
        self.create_dot = True
        self.terminate = False

        self.capsfilter_queue_overrun_handler_id = None

        self._cancel_signal_callback = None

        # source: https://github.com/ljmljz/xpra/blob/b32f748e0c29cdbfab836b3901c1e318ea142b33/src/xpra/sound/sound_pipeline.py  # NOQA
        self.bus = None
        self.bus_message_element_handler_id = None
        self.bus_message_error_handler_id = None
        self.bus_message_eos_handler_id = None
        self.bus_message_state_changed_handler_id = None
        self.pipeline = None
        self.start_time = 0
        self.state = "stopped"
        self.buffer_count = 0
        self.byte_count = 0

        self._status_ready = "  ScarlettListener is ready"
        self._status_kw_match = "  ScarlettListener caught a keyword match"
        self._status_cmd_match = "  ScarlettListener caught a command match"
        self._status_stt_failed = "  ScarlettListener hit Max STT failures"
        self._status_cmd_start = "  ScarlettListener emitting start command"
        self._status_cmd_fin = "  ScarlettListener Emitting Command run finish"
        self._status_cmd_cancel = "  ScarlettListener cancel speech Recognition"

        if self.debug:
            # NOTE: For testing puposes, mainly when in public
            # so you dont have to keep yelling scarlett in front of strangers
            self.kw_to_find = ["yo", "hello", "man", "children"]
        else:
            # NOTE: Before we start worrying about the config class, lets hardcode what we care about
            # ADD ME BACK IN WHEN WE REALLY START UNIT TESTING # self.kw_to_find = self.config.get('scarlett', 'keywords')
            self.kw_to_find = ["scarlett", "SCARLETT"]

        if self.read_exc:
            # An error occurred before the stream became ready.
            self.close(True)
            raise self.read_exc  # pylint: disable=raising-bad-type

    def scarlett_reset_listen(self):
        self.failed = 0
        self.kw_found = 0

    def on_cancel_listening(self, *args, **kwargs):
        logger.debug("Inside cancel_listening function")
        self.scarlett_reset_listen()
        logger.debug("self.failed = {}".format(self.failed))
        logger.debug("self.keyword_identified = {}".format(self.kw_found))

    def play(self):
        p = self.pipelines_stack[0]
        self.state = "active"
        self.running = True
        # GST_STATE_PAUSED is the state in which an element is ready to accept and handle data.
        # For most elements this state is the same as PLAYING. The only exception to this rule are sink elements.
        # Sink elements only accept one single buffer of data and then block.
        # At this point the pipeline is 'prerolled' and ready to render data immediately.
        p.set_state(Gst.State.PAUSED)
        # GST_STATE_PLAYING is the highest state that an element can be in.
        # For most elements this state is exactly the same as PAUSED,
        # they accept and process events and buffers with data.
        # Only sink elements need to differentiate between PAUSED and PLAYING state.
        # In PLAYING state, sink elements actually render incoming data,
        # e.g. output audio to a sound card or render video pictures to an image sink.
        ret = p.set_state(Gst.State.PLAYING)
        if ret == Gst.StateChangeReturn.FAILURE:
            logger.error("ERROR: Unable to set the pipeline to the playing state")

        # 8/8/2018 (Only enable this if we turn on debug mode)
        if os.environ.get("SCARLETT_DEBUG_MODE"):
            self.on_debug_activate()

        logger.debug("BEFORE: self.ready_sem.acquire()")
        self.ready_sem.acquire()
        logger.debug("AFTER: self.ready_sem.acquire()")
        logger.info("Press Ctrl+C to quit ...")

    def stop(self):
        p = self.pipelines_stack[0]
        self.state = "stopped"
        self.running = False
        # GST_STATE_NULL is the default state of an element.
        # In this state, it has not allocated any runtime resources,
        # it has not loaded any runtime libraries and it can obviously not handle data.
        p.set_state(Gst.State.NULL)

    def get_pocketsphinx_definition(self, override=False):
        r"""
        GST_DEBUG=2,pocketsphinx*:5 gst-launch-1.0 alsasrc device=plughw:CARD=Device,DEV=0 ! \
                                                    queue name=capsfilter_queue \
                                                          leaky=2 \
                                                          max-size-buffers=0 \
                                                          max-size-time=0 \
                                                          max-size-bytes=0 ! \
                                                    capsfilter caps='audio/x-raw,format=(string)S16LE,rate=(int)16000,channels=(int)1,layout=(string)interleaved' ! \
                                                    audioconvert ! \
                                                    audioresample ! \
                                                    pocketsphinx \
                                                    name=asr \
                                                    lm=~/dev/bossjones-github/scarlett_os/static/speech/lm/1473.lm \
                                                    dict=~/dev/bossjones-github/scarlett_os/static/speech/dict/1473.dic \
                                                    hmm=~/.virtualenvs/scarlett_os/share/pocketsphinx/model/en-us/en-us
                                                    bestpath=true ! \
                                                    tee name=tee ! \
                                                    queue name=appsink_queue \
                                                          leaky=2 \
                                                          max-size-buffers=0 \
                                                          max-size-time=0 \
                                                          max-size-bytes=0 ! \
                                                    appsink caps='audio/x-raw,format=(string)S16LE,rate=(int)16000,channels=(int)1,layout=(string)interleaved' \
                                                    drop=false max-buffers=10 sync=false \
                                                    emit-signals=true tee.
                                                    queue name=fakesink_queue \
                                                          leaky=2 \
                                                          max-size-buffers=0 \
                                                          max-size-time=0 \
                                                          max-size-bytes=0 ! \
                                                    fakesink sync=false
        """
        logger.debug("Inside get_pocketsphinx_definition")

        if override:
            _gst_launch = override
        else:
            # TODO: Add audio levels, see the following
            # SOURCE: http://stackoverflow.com/questions/5686424/detecting-blowing-on-a-microphone-with-gstreamer-or-another-library
            _gst_launch = [
                "alsasrc device=" + self.device,
                # source: https://github.com/walterbender/story/blob/master/grecord.py
                # without a buffer here, gstreamer struggles at the start of the
                # recording and then the A/V sync is bad for the whole video
                # (possibly a gstreamer/ALSA bug -- even if it gets caught up, it
                # should be able to resync without problem)
                # 'progressreport name=progressreport update-freq=1',  # NOTE: comment this in when you want performance information
                "queue name=capsfilter_queue silent=false leaky=2 max-size-buffers=0 max-size-time=0 max-size-bytes=0",
                "capsfilter name=capsfilter caps=audio/x-raw,format=S16LE,channels=1,layout=interleaved",
                "audioconvert name=audioconvert",
                "audioresample name=audioresample",
                "identity name=ident",
                "pocketsphinx name=asr",
                "tee name=tee",
                "queue name=appsink_queue silent=false leaky=2 max-size-buffers=0 max-size-time=0 max-size-bytes=0",
                #  caps=audio/x-raw,format=(string)S16LE,rate=(int)16000,channels=(int)1,layout=(string)interleaved   # NOQA
                "appsink name=appsink drop=false max-buffers=10 sync=false emit-signals=true tee.",
                "queue leaky=2 name=fakesink_queue",
                "fakesink",
            ]

        return _gst_launch

    def cancel(self):
        """
        Threads in python are not cancellable, so we implement our own
        cancellation logic
        """
        self.cancelled = True

    @abort_on_exception
    def run(self, event=None):
        # TODO: WE NEED TO USE A THREADING EVENT OR A RLOCK HERE TO WAIT TILL DBUS SERVICE IS RUNNING TO CONNECT
        # TODO: SIGNALS TO THE DBUS PROXY METHODS WE WANT TO USE
        # TODO: lock.acquire() / event / condition
        # TODO: self.connect_to_dbus()
        # TODO: self.setup_dbus_callbacks_handlers()
        self._connect_to_dbus()
        self.init_gst()
        print("Running {}".format(str(self)))
        self.play()
        self.emit("playback-status-changed")
        self.emit("playing-changed")
        # FIXME: is this needed? # self.mainloop.run()

    def _connect_to_dbus(self):
        self.bus = SessionBus()
        self.dbus_proxy = self.bus.get(
            "org.scarlett", object_path="/org/scarlett/Listener"
        )  # NOQA
        self.dbus_proxy.emitConnectedToListener("ScarlettListener")
        time.sleep(2)
        logger.info("_connect_to_dbus")
        # TODO: Add a ss_cancel_signal.disconnect() function later
        ss_cancel_signal = self.bus.subscribe(
            sender=None,
            iface="org.scarlett.Listener",
            signal="ListenerCancelSignal",
            object="/org/scarlett/Listener",
            arg0=None,
            flags=0,
            signal_fired=self.on_cancel_listening,
        )

    # NOTE: This function generates the dot file, checks that graphviz in installed and
    # then finally generates a png file, which it then displays
    def on_debug_activate(self):
        # FIXME: This needs to use dynamic paths, it's possible that we're having issues because of order of operations
        # FIXME: STATIC PATH 7/3/2018
        # dotfile = (
        #     "/home/pi/dev/bossjones-github/scarlett_os/_debug/generator-listener.dot"
        # )
        # pngfile = "/home/pi/dev/bossjones-github/scarlett_os/_debug/generator-listener-pipeline.png"  # NOQA
        dotfile = self._dotfile_listener
        pngfile = self._pngfile_listener

        if os.access(dotfile, os.F_OK):
            os.remove(dotfile)
        if os.access(pngfile, os.F_OK):
            os.remove(pngfile)

        Gst.debug_bin_to_dot_file(
            self.pipelines_stack[0], Gst.DebugGraphDetails.ALL, "generator-listener"
        )

        cmd = "/usr/bin/dot -Tpng -o {pngfile} {dotfile}".format(
            pngfile=pngfile, dotfile=dotfile
        )
        os.system(cmd)

    def result(self, final_hyp):
        """Forward result signals on the bus to the main thread."""
        logger.debug("Inside result function")
        logger.debug("final_hyp: {}".format(final_hyp))
        pp.pprint(final_hyp)
        logger.debug("kw_to_find: {}".format(self.kw_to_find))
        if final_hyp in self.kw_to_find and final_hyp != "":
            logger.debug("HYP-IS-SOMETHING: {}\n\n\n".format(final_hyp))
            self.failed = 0
            self.kw_found = 1
            self.dbus_proxy.emitKeywordRecognizedSignal()  # CHANGEME
        else:
            failed_temp = self.failed + 1
            self.failed = failed_temp
            logger.debug("self.failed = {}".format(int(self.failed)))
            # failed > 10
            if self.failed > 4:
                # reset pipline
                self.dbus_proxy.emitSttFailedSignal()  # CHANGEME
                self.scarlett_reset_listen()

    def run_cmd(self, final_hyp):
        logger.debug("Inside run_cmd function")
        logger.debug("KEYWORD IDENTIFIED BABY")
        logger.debug("self.kw_found = {}".format(int(self.kw_found)))
        if final_hyp == "CANCEL":
            self.dbus_proxy.emitListenerCancelSignal()  # CHANGEME
            self.on_cancel_listening()
        else:
            current_kw_identified = self.kw_found
            self.kw_found = current_kw_identified
            self.dbus_proxy.emitCommandRecognizedSignal(final_hyp)  # CHANGEME
            logger.info("Command = {}".format(final_hyp))
            logger.debug("AFTER run_cmd, self.kw_found = {}".format(int(self.kw_found)))

    def init_gst(self):
        logger.debug("Inside init_gst")
        self.start_time = time.time()
        pipeline = Gst.parse_launch(" ! ".join(self.get_pocketsphinx_definition()))
        logger.debug("After get_pocketsphinx_definition")
        # Add pipeline obj to stack we can pull from later
        self.pipelines_stack.append(pipeline)

        gst_bus = pipeline.get_bus()
        # gst_bus = pipeline.get_gst_bus()
        gst_bus.add_signal_watch()
        self.bus_message_element_handler_id = gst_bus.connect(
            "message::element", self._on_message
        )
        self.bus_message_eos_handler_id = gst_bus.connect(
            "message::eos", self._on_message
        )
        self.bus_message_error_handler_id = gst_bus.connect(
            "message::error", self._on_message
        )
        self.bus_message_state_changed_handler_id = gst_bus.connect(
            "message::state-changed", self._on_state_changed
        )

        # Add bus obj to stack we can pull from later
        self.gst_bus_stack.append(gst_bus)

        appsink = pipeline.get_by_name("appsink")
        appsink.set_property(
            "caps",
            Gst.Caps.from_string(
                "audio/x-raw,format=(string)S16LE,rate=(int)16000,channels=(int)1,layout=(string)interleaved"
            ),
        )

        appsink.set_property("drop", False)
        appsink.set_property("max-buffers", BUFFER_SIZE)
        appsink.set_property("sync", False)

        # The callback to receive decoded data.
        appsink.set_property("emit-signals", True)
        appsink.connect("new-sample", self._new_sample)

        self.caps_handler = appsink.get_static_pad("sink").connect(
            "notify::caps", self._notify_caps
        )

        self.elements_stack.append(appsink)

        # ************************************************************
        # get gst pipeline element pocketsphinx and set properties - BEGIN
        # ************************************************************
        pocketsphinx = pipeline.get_by_name("asr")
        # from scarlett_os.internal.debugger import dump
        # print("debug-2018-pocketsphinx - BEGIN")
        # dump(pocketsphinx.get_property('decoder'))
        # print("debug-2018-pocketsphinx - END")
        # print(pocketsphinx.list_properties())
        if self._hmm:
            pocketsphinx.set_property("hmm", self._hmm)
        if self._lm:
            pocketsphinx.set_property("lm", self._lm)
        if self._dic:
            pocketsphinx.set_property("dict", self._dic)

        if self._fwdflat:
            pocketsphinx.set_property("fwdflat", self._fwdflat)

        if self._bestpath:
            pocketsphinx.set_property("bestpath", self._bestpath)

        if self._dsratio:
            pocketsphinx.set_property("dsratio", self._dsratio)

        if self._maxhmmpf:
            pocketsphinx.set_property("maxhmmpf", self._maxhmmpf)

        if self._bestpath:
            pocketsphinx.set_property("bestpath", self._bestpath)

        # if self._silprob:
        #     pocketsphinx.set_property("silprob", self._silprob)

        # if self._wip:
        #     pocketsphinx.set_property("wip", self._wip)
        # ************************************************************
        # get gst pipeline element pocketsphinx and set properties - END
        # ************************************************************

        # NOTE: Old way of setting pocketsphinx properties. 8/5/2018
        # pocketsphinx.set_property(
        #     "fwdflat", True
        # )  # Enable Flat Lexicon Search | Default: true
        # pocketsphinx.set_property(
        #     "bestpath", True
        # )  # Enable Graph Search | Boolean. Default: true
        # pocketsphinx.set_property(
        #     "dsratio", 1
        # )  # Evaluate acoustic model every N frames |  Integer. Range: 1 - 10 Default: 1
        # pocketsphinx.set_property(
        #     "maxhmmpf", 3000
        # )  # Maximum number of HMMs searched per frame | Integer. Range: 1 - 100000 Default: 30000
        # pocketsphinx.set_property(
        #     "bestpath", True
        # )  # Enable Graph Search | Boolean. Default: true
        # pocketsphinx.set_property('maxwpf', -1)  #
        # pocketsphinx.set_property('maxwpf', 20)  # Maximum number of words
        # searched per frame | Range: 1 - 100000 Default: -1

        self.elements_stack.append(pocketsphinx)

        capsfilter_queue = pipeline.get_by_name("capsfilter_queue")
        capsfilter_queue.set_property("leaky", True)  # prefer fresh data
        capsfilter_queue.set_property("silent", False)
        capsfilter_queue.set_property("max-size-time", 0)  # 0 seconds
        capsfilter_queue.set_property("max-size-buffers", 0)
        capsfilter_queue.set_property("max-size-bytes", 0)
        self.capsfilter_queue_overrun_handler_id = capsfilter_queue.connect(
            "overrun", self._log_queue_overrun
        )

        # capsfilter_queue.connect('overrun', self._on_overrun)
        # capsfilter_queue.connect('underrun', self._on_underrun)
        # capsfilter_queue.connect('pushing', self._on_pushing)
        # capsfilter_queue.connect('running', self._on_running)

        self.elements_stack.append(capsfilter_queue)

        ident = pipeline.get_by_name("ident")
        # ident.connect('handoff', self._on_handoff)

        self.elements_stack.append(ident)

        logger.debug("After all self.elements_stack.append() calls")
        # Set up the queue for data and run the main thread.
        self.queue = queue.Queue(QUEUE_SIZE)
        self.thread = get_loop_thread()

    # NOTE: Disabled since we aren't connecting to handoff
    # def _on_handoff(self, element, buf):
    #     logger.debug('buf:')
    #     pp.pprint(buf)
    #     pp.pprint(dir(buf))
    #     logger.debug("on_handoff - %d bytes".format(len(buf))

    #     if self.signed is None:
    #         # only ever one caps struct on our buffers
    #         struct = buf.get_caps().get_structure(0)

    #         # I think these are always set too, but catch just in case
    #         try:
    #             self.signed = struct["signed"]
    #             self.depth = struct["depth"]
    #             self.rate = struct["rate"]
    #             self.channels = struct["channels"]
    #         except Exception:
    #             logger.debug('on_handoff: missing caps')
    #             pass

    # raw = str(buf)
    #
    # # print 'len(raw) =', len(raw)
    #
    # sm = 0
    # for i in range(0, len(raw)):
    #     sm += ord(raw[i])
    # # print sm
    # FIXEME: Add somthing like analyse.py
    # SOURCE: https://github.com/jcupitt/huebert/blob/master/huebert/audio.py

    def _on_state_changed(self, bus, msg):
        states = msg.parse_state_changed()
        # To state is PLAYING
        if msg.src.get_name() == "pipeline0" and states[1] == 4:
            logger.info("Inside pipeline0 on _on_state_changed")
            logger.info("State: {}".format(states[1]))
            self.ready_sem.release()
            return False
        else:
            # logger.error('NOTHING RETURNED in _on_state_changed')
            logger.info("State: {}".format(states[1]))

    def _on_overrun(self, element):
        logging.debug("on_overrun")

    def _on_underrun(self, element):
        logging.debug("on_underrun")

    def _on_running(self, element):
        logging.debug("on_running")

    def _on_pushing(self, element):
        logging.debug("on_pushing")

    def _notify_caps(self, pad, args):
        """The callback for the sinkpad's "notify::caps" signal.
        """
        # The sink has started to receive data, so the stream is ready.
        # This also is our opportunity to read information about the
        # stream.
        self.got_caps = True

        # Allow constructor to complete.
        self.ready_sem.release()

    _got_a_pad = False

    def _log_queue_overrun(self, queue):
        cbuffers = queue.get_property("current-level-buffers")
        cbytes = queue.get_property("current-level-bytes")
        ctime = queue.get_property("current-level-time")

    def _new_sample(self, sink):
        """The callback for appsink's "new-sample" signal.
        """
        if self.running:
            # New data is available from the pipeline! Dump it into our
            # queue (or possibly block if we're full).
            buf = sink.emit("pull-sample").get_buffer()
            # IMPORTANT!!!!!
            # NOTE: I think this is causing a deadlock
            self.queue.put(buf.extract_dup(0, buf.get_size()))
        # "OK = 0. Data passing was ok.""
        return Gst.FlowReturn.OK

    def _on_message(self, bus, message):
        """The callback for GstBus's "message" signal (for two kinds of
        messages).
        """
        # logger.debug("[_on_message](%s, %s)", bus, message)
        if not self.finished:
            struct = message.get_structure()

            if message.type == Gst.MessageType.EOS:
                # The file is done. Tell the consumer thread.
                self.queue.put(SENTINEL)
                if not self.got_caps:
                    logger.error(
                        "If the stream ends before _notify_caps was called, this is an invalid stream."
                    )
                    # If the stream ends before _notify_caps was called, this
                    # is an invalid file.
                    self.read_exc = NoStreamError()
                    self.ready_sem.release()
            elif struct and struct.get_name() == "pocketsphinx":
                # "final", G_TYPE_BOOLEAN, final,
                # SOURCE: https://github.com/cmusphinx/pocketsphinx/blob/1fdc9ccb637836d45d40956e745477a2bd3b470a/src/gst-plugin/gstpocketsphinx.c
                if struct["final"]:
                    logger.info("confidence: {}".format(struct["confidence"]))
                    logger.info("hypothesis: {}".format(struct["hypothesis"]))
                    if self.kw_found == 1:
                        # If keyword is set AND qualifier
                        # then perform action
                        self.run_cmd(struct["hypothesis"])
                    else:
                        # If it's the main keyword,
                        # set values wait for qualifier
                        self.result(struct["hypothesis"])
            elif message.type == Gst.MessageType.ERROR:
                gerror, debug = message.parse_error()
                pp.pprint(("gerror,debug:", gerror, debug))
                if "not-linked" in debug:
                    logger.error("not-linked")
                    self.read_exc = NoStreamError()
                elif "No such device" in debug:
                    logger.error("No such device")
                    self.read_exc = NoStreamError()
                else:
                    logger.info("FileReadError")
                    pp.pprint(
                        ("SOME FileReadError", bus, message, struct, struct.get_name())
                    )
                    self.read_exc = FileReadError(debug)
                self.ready_sem.release()

    # Cleanup.
    def close(self, force=False):
        """Close the file and clean up associated resources.

        Calling `close()` a second time has no effect.
        """
        if self.running or force:
            self.running = False
            self.finished = True

            try:
                gst_bus = self.gst_bus_stack[0]
            except Exception:
                logger.error("Failed to get gst_bus from gst_bus_stack[0]")

            if gst_bus:
                gst_bus.remove_signal_watch()
                if self.bus_message_element_handler_id:
                    gst_bus.disconnect(self.bus_message_element_handler_id)
                if self.bus_message_error_handler_id:
                    gst_bus.disconnect(self.bus_message_error_handler_id)
                if self.bus_message_eos_handler_id:
                    gst_bus.disconnect(self.bus_message_eos_handler_id)
                if self.bus_message_state_changed_handler_id:
                    gst_bus.disconnect(self.bus_message_state_changed_handler_id)

            self.bus = None
            self.pipeline = None
            self.codec = None
            self.bitrate = -1
            self.state = None

            # Unregister for signals, which we registered for above with
            # `add_signal_watch`. (Without this, GStreamer leaks file
            # descriptors.)
            logger.debug("BEFORE p = self.pipelines_stack[0]")
            p = self.pipelines_stack[0]
            p.get_bus().remove_signal_watch()
            logger.debug("AFTER p.get_bus().remove_signal_watch()")

            # Block spurious signals.
            appsink = self.elements_stack[0]
            appsink.get_static_pad("sink").disconnect(self.caps_handler)

            # Make space in the output queue to let the decoder thread
            # finish. (Otherwise, the thread blocks on its enqueue and
            # the interpreter hangs.)
            try:
                self.queue.get_nowait()
            except queue.Empty:
                pass

            # Halt the pipeline (closing file).
            self.stop()

            # Delete the pipeline object. This seems to be necessary on Python
            # 2, but not Python 3 for some reason: on 3.5, at least, the
            # pipeline gets dereferenced automatically.
            del p

    def __del__(self):
        self.close()

    def __exit__(self, exc_type, exc_val, exc_tb):
        self.close()
        return False
    def __init__(self, *args):
        _IdleObject.__init__(self)

        self.bucket = bucket = Queue.Queue()  # NOQA
        self.loop = GLib.MainLoop()
        self.hello = None

        # with SessionBus() as bus:
        bus = SessionBus()
        ss = bus.get("org.scarlett", object_path='/org/scarlett/Listener')  # NOQA

        # # SttFailedSignal / player_cb
        # ss_failed_signal = bus.con.signal_subscribe(None,  # NOQA
        #                                             "org.scarlett.Listener",
        #                                             "SttFailedSignal",
        #                                             '/org/scarlett/Listener',
        #                                             None,
        #                                             0,
        #                                             player_cb)
        ss_failed_signal = ss.SttFailedSignal.connect(player_cb)

        # # ListenerReadySignal / player_cb
        # ss_rdy_signal = bus.con.signal_subscribe(None,  # NOQA
        #                                          "org.scarlett.Listener",
        #                                          "ListenerReadySignal",
        #                                          '/org/scarlett/Listener',
        #                                          None,
        #                                          0,
        #                                          player_cb)
        ss_rdy_signal = ss.ListenerReadySignal.connect(player_cb)

        # # KeywordRecognizedSignal / player_cb
        # ss_kw_rec_signal = bus.con.signal_subscribe(None,  # NOQA
        #                                             "org.scarlett.Listener",
        #                                             "KeywordRecognizedSignal",
        #                                             '/org/scarlett/Listener',
        #                                             None,
        #                                             0,
        #                                             player_cb)
        ss_kw_rec_signal = ss.KeywordRecognizedSignal.connect(player_cb)

        # # CommandRecognizedSignal /command_cb
        # ss_cmd_rec_signal = bus.con.signal_subscribe(None,  # NOQA
        #                                              "org.scarlett.Listener",
        #                                              "CommandRecognizedSignal",
        #                                              '/org/scarlett/Listener',
        #                                              None,
        #                                              0,
        #                                              command_cb)
        ss_cmd_rec_signal = ss.CommandRecognizedSignal.connect(command_cb)

        # # ListenerCancelSignal / player_cb
        # # signal_subscribe (sender, interface_name, member, object_path, arg0, flags, callback, *user_data)
        # ss_cancel_signal = bus.con.signal_subscribe(None,  # NOQA
        #                                             "org.scarlett.Listener",
        #                                             "ListenerCancelSignal",
        #                                             '/org/scarlett/Listener',
        #                                             None,
        #                                             0,
        #                                             player_cb)
        ss_cancel_signal = ss.ListenerCancelSignal.connect(player_cb)

        ss.emitConnectedToListener('ScarlettTasker')

        # THE ACTUAL THREAD BIT
        self.manager = FooThreadManager(3)

        try:
            print "ScarlettTasker Thread Started", self
            self.loop.run()
        except Exception:
            ss_failed_signal.disconnect()
            ss_rdy_signal.disconnect()
            ss_kw_rec_signal.disconnect()
            ss_cmd_rec_signal.disconnect()
            ss_cancel_signal.disconnect()
            self.bucket.put(sys.exc_info())
            raise
Exemple #45
0
class Py3status:
    """
    """

    # available configuration parameters
    button_stop = None
    button_toggle = 1
    button_next = 4
    button_previous = 5
    format = "{previous}{toggle}{next} {state} [{artist} - ][{title}]"
    format_none = "no player running"
    icon_pause = u"▮"
    icon_play = u"▶"
    icon_stop = u"◾"
    icon_next = u"»"
    icon_previous = u"«"
    state_pause = u"▮"
    state_play = u"▶"
    state_stop = u"◾"
    player_priority = []

    def __init__(self):
        self._dbus = None
        self._data = {}
        self._kill = False
        self._mpris_players = {}
        self._mpris_names = {}
        self._mpris_name_index = {}
        self._player = None
        self._player_details = {}
        self._tries = 0

    def post_config_hook(self):
        self._dbus = SessionBus()
        self._start_listener()

    def _init_data(self):
        self._data = {
            "album": None,
            "artist": None,
            "error_occurred": False,
            "length": None,
            "player": None,
            "state": STOPPED,
            "title": None,
        }

        if self._player is None:
            return

        try:
            self._data["player"] = self._player.Identity
            playback_status = self._player.PlaybackStatus
            self._data["state"] = self._get_state(playback_status)
            metadata = self._player.Metadata
            self._update_metadata(metadata)
        except Exception:
            self._data["error_occurred"] = True

    def _get_button_state(self, control_state):
        try:
            # Workaround: The last parameter returns True for the Stop button.
            clickable = getattr(self._player, control_state["clickable"], True)
        except Exception:
            clickable = False

        state = self._data.get("state")
        if control_state["action"] == "Play" and state == PLAYING:
            clickable = False
        elif control_state["action"] == "Pause" and state in [STOPPED, PAUSED]:
            clickable = False
        elif control_state["action"] == "Stop" and state == STOPPED:
            clickable = False

        return clickable

    def _get_state(self, playback_status):
        if playback_status == "Playing":
            return PLAYING
        elif playback_status == "Paused":
            return PAUSED
        else:
            return STOPPED

    def _get_text(self):
        """
        Get the current metadata
        """
        if self._data.get("state") == PLAYING:
            color = self.py3.COLOR_PLAYING or self.py3.COLOR_GOOD
            state_symbol = self.state_play
        elif self._data.get("state") == PAUSED:
            color = self.py3.COLOR_PAUSED or self.py3.COLOR_DEGRADED
            state_symbol = self.state_pause
        else:
            color = self.py3.COLOR_STOPPED or self.py3.COLOR_BAD
            state_symbol = self.state_stop

        if self._data.get("error_occurred"):
            color = self.py3.COLOR_BAD

        try:
            ptime_ms = self._player.Position
            ptime = _get_time_str(ptime_ms)
        except Exception:
            ptime = None

        if "{time}" in self.format and self._data.get("state") == PLAYING:
            # Don't get trapped in aliasing errors!
            update = time() + 0.5
        else:
            update = self.py3.CACHE_FOREVER

        placeholders = {
            "player": self._data.get("player"),
            "state": state_symbol,
            "album": self._data.get("album"),
            "artist": self._data.get("artist"),
            "length": self._data.get("length"),
            "time": ptime,
            "title": self._data.get("title") or "No Track",
            "full_name": self._player_details.get("full_name"),  # for debugging ;p
        }

        return (placeholders, color, update)

    def _get_control_states(self):
        control_states = {
            "pause": {"action": "Pause", "clickable": "CanPause", "icon": self.icon_pause},
            "play": {"action": "Play", "clickable": "CanPlay", "icon": self.icon_play},
            "stop": {
                "action": "Stop",
                # Workaround: The MPRIS API has no CanStop function.
                "clickable": "True",
                "icon": self.icon_stop,
            },
            "next": {"action": "Next", "clickable": "CanGoNext", "icon": self.icon_next},
            "previous": {"action": "Previous", "clickable": "CanGoPrevious", "icon": self.icon_previous},
        }

        state = "pause" if self._data.get("state") == PLAYING else "play"
        control_states["toggle"] = control_states[state]

        return control_states

    def _get_response_buttons(self):
        response = {}

        for button in self._control_states.keys():
            control_state = self._control_states[button]

            if self._get_button_state(control_state):
                color = self.py3.COLOR_CONTROL_ACTIVE or self.py3.COLOR_GOOD
            else:
                color = self.py3.COLOR_CONTROL_INACTIVE or self.py3.COLOR_BAD

            response[button] = {
                "color": color,
                "full_text": control_state["icon"],
                "index": button,
                "min_width": 20,
                "align": "center",
            }

        return response

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

    def _name_owner_changed(self, *args):
        player_add = args[5][2]
        player_remove = args[5][1]
        if player_add:
            self._add_player(player_add)
        if player_remove:
            self._remove_player(player_remove)
        self._set_player()

    def _set_player(self):
        """
        Sort the current players into priority order and set self._player
        Players are ordered by working state then prefernce supplied by user
        and finally by instance if a player has more than one running.
        """
        players = []
        for name, p in self._mpris_players.items():
            # we set the priority here as we need to establish the player name
            # which might not be immediately available.
            if "_priority" not in p:
                if self.player_priority:
                    try:
                        priority = self.player_priority.index(p["name"])
                    except ValueError:
                        try:
                            priority = self.player_priority.index("*")
                        except ValueError:
                            priority = None
                else:
                    priority = 0
                if priority is not None:
                    p["_priority"] = priority
            if p.get("_priority") is not None:
                players.append((p["_state_priority"], p["_priority"], p["index"], name))
        if players:
            top_player = self._mpris_players.get(sorted(players)[0][3])
        else:
            top_player = {}

        self._player = top_player.get("_dbus_player")
        self._player_details = top_player

        self.py3.update()

    def _player_monitor(self, player_id):
        def player_on_change(*args):
            """
            Monitor a player and update its status.
            """
            data = args[1]
            status = data.get("PlaybackStatus")
            if status:
                player = self._mpris_players[player_id]
                player["status"] = status
                player["_state_priority"] = WORKING_STATES.index(status)
            self._set_player()

        return player_on_change

    def _add_player(self, player_id):
        """
        Add player to mpris_players
        """
        try:
            player = self._dbus.get(player_id, SERVICE_BUS_URL)
            if player_id.startswith(SERVICE_BUS):
                if player.Identity not in self._mpris_names:
                    self._mpris_names[player.Identity] = player_id.split(".")[-1]
                    for p in self._mpris_players.values():
                        if not p["name"] and p["identity"] in self._mpris_names:
                            p["name"] = self._mpris_names[p["identity"]]
                            p["full_name"] = u"{} {}".format(p["name"], p["index"])
                return
            status = player.PlaybackStatus
            state_priority = WORKING_STATES.index(status)
            identity = player.Identity
            if identity not in self._mpris_name_index:
                self._mpris_name_index[identity] = 0
            index = self._mpris_name_index[identity]
            self._mpris_name_index[identity] += 1
            name = self._mpris_names.get(identity)
            subscription = player.PropertiesChanged.connect(self._player_monitor(player_id))
        except:
            return

        self._mpris_players[player_id] = {
            "_dbus_player": player,
            "_id": player_id,
            "_state_priority": state_priority,
            "index": index,
            "identity": identity,
            "name": name,
            "full_name": u"{} {}".format(name, index),
            "status": status,
            "subscription": subscription,
        }
        return True

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

    def _get_players(self):
        bus = self._dbus.get("org.freedesktop.DBus")
        for player in bus.ListNames():
            if player.startswith(":") or player.startswith(SERVICE_BUS):
                if not self._add_player(player):
                    continue
        self._set_player()

    def _start_listener(self):
        self._dbus.con.signal_subscribe(
            None, "org.freedesktop.DBus", "NameOwnerChanged", None, None, 0, self._name_owner_changed
        )
        self._get_players()
        t = Thread(target=self._start_loop)
        t.daemon = True
        t.start()

    def _timeout(self):
        if self._kill:
            self._loop.quit()
            sys.exit(0)

    def _update_metadata(self, metadata):
        is_stream = False

        try:
            if len(metadata) > 0:
                url = metadata.get("xesam:url")
                is_stream = url is not None and "file://" not in url
                self._data["title"] = metadata.get("xesam:title")
                self._data["album"] = metadata.get("xesam:album")

                if metadata.get("xesam:artist") is not None:
                    self._data["artist"] = metadata.get("xesam:artist")[0]
                else:
                    # we assume here that we playing a video and these types of
                    # media we handle just like streams
                    is_stream = True

                length_ms = metadata.get("mpris:length")
                if length_ms is not None:
                    self._data["length"] = _get_time_str(length_ms)
            else:
                # use stream format if no metadata is available
                is_stream = True
        except Exception:
            self._data["error_occurred"] = True

        if is_stream and self._data.get("title"):
            # delete the file extension
            self._data["title"] = re.sub(r"\....$", "", self._data.get("title"))

    def kill(self):
        self._kill = True

    def mpris(self):
        """
        Get the current output format and return it.
        """
        current_player_id = self._player_details.get("id")
        cached_until = self.py3.CACHE_FOREVER

        if self._player is None:
            text = self.format_none
            color = self.py3.COLOR_BAD
            composite = [{"full_text": text, "color": color}]
            self._data = {}
        else:
            self._init_data()
            (text, color, cached_until) = self._get_text()
            self._control_states = self._get_control_states()
            buttons = self._get_response_buttons()
            composite = self.py3.build_composite(self.format, text, buttons)

        if self._data.get("error_occurred") or current_player_id != self._player_details.get("id"):
            # Something went wrong or the player changed during our processing
            # This is usually due to something like a player being killed
            # whilst we are checking its details
            # Retry but limit the number of attempts
            self._tries += 1
            if self._tries < 3:
                return self.mpris()
            # Max retries hit we need to output something
            composite = [{"full_text": "Something went wrong", "color": self.py3.COLOR_BAD}]
            cached_until = self.py3.time_in(1)

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

        # we are outputing so reset tries
        self._tries = 0
        return response

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

        if index not in self._control_states.keys():
            if button == self.button_toggle:
                index = "toggle"
            elif button == self.button_stop:
                index = "stop"
            elif button == self.button_next:
                index = "next"
            elif button == self.button_previous:
                index = "previous"
            else:
                return
        elif button != 1:
            return

        control_state = self._control_states[index]
        if self._player and self._get_button_state(control_state):
            getattr(self._player, self._control_states[index]["action"])()
Exemple #46
0
class Py3status:
    """
    """
    # available configuration parameters
    button_next = 4
    button_previous = 5
    button_stop = None
    button_toggle = 1
    format = '{previous}{toggle}{next} {state} [{artist} - ][{title}]'
    format_none = 'no player running'
    icon_next = u'»'
    icon_pause = u'▮'
    icon_play = u'▶'
    icon_previous = u'«'
    icon_stop = u'◾'
    player_priority = []
    state_pause = u'▮'
    state_play = u'▶'
    state_stop = u'◾'

    def __init__(self):
        self._dbus = None
        self._data = {}
        self._kill = False
        self._mpris_players = {}
        self._mpris_names = {}
        self._mpris_name_index = {}
        self._player = None
        self._player_details = {}
        self._tries = 0

    def post_config_hook(self):
        self._dbus = SessionBus()
        self._start_listener()

    def _init_data(self):
        self._data = {
            'album': None,
            'artist': None,
            'error_occurred': False,
            'length': None,
            'player': None,
            'state': STOPPED,
            'title': None
        }

        if self._player is None:
            return

        try:
            self._data['player'] = self._player.Identity
            playback_status = self._player.PlaybackStatus
            self._data['state'] = self._get_state(playback_status)
            metadata = self._player.Metadata
            self._update_metadata(metadata)
        except Exception:
            self._data['error_occurred'] = True

    def _get_button_state(self, control_state):
        try:
            # Workaround: The last parameter returns True for the Stop button.
            clickable = getattr(self._player, control_state['clickable'], True)
        except Exception:
            clickable = False

        state = self._data.get('state')
        if control_state['action'] == 'Play' and state == PLAYING:
            clickable = False
        elif control_state['action'] == 'Pause' and state in [STOPPED, PAUSED]:
            clickable = False
        elif control_state['action'] == 'Stop' and state == STOPPED:
            clickable = False

        return clickable

    def _get_state(self, playback_status):
        if playback_status == 'Playing':
            return PLAYING
        elif playback_status == 'Paused':
            return PAUSED
        else:
            return STOPPED

    def _get_text(self):
        """
        Get the current metadata
        """
        if self._data.get('state') == PLAYING:
            color = self.py3.COLOR_PLAYING or self.py3.COLOR_GOOD
            state_symbol = self.state_play
        elif self._data.get('state') == PAUSED:
            color = self.py3.COLOR_PAUSED or self.py3.COLOR_DEGRADED
            state_symbol = self.state_pause
        else:
            color = self.py3.COLOR_STOPPED or self.py3.COLOR_BAD
            state_symbol = self.state_stop

        if self._data.get('error_occurred'):
            color = self.py3.COLOR_BAD

        try:
            ptime_ms = self._player.Position
            ptime = _get_time_str(ptime_ms)
        except Exception:
            ptime = None

        if '{time}' in self.format and self._data.get('state') == PLAYING:
            # Don't get trapped in aliasing errors!
            update = time() + 0.5
        else:
            update = self.py3.CACHE_FOREVER

        placeholders = {
            'player': self._data.get('player'),
            'state': state_symbol,
            'album': self._data.get('album'),
            'artist': self._data.get('artist'),
            'length': self._data.get('length'),
            'time': ptime,
            'title': self._data.get('title') or 'No Track',
            'full_name': self._player_details.get('full_name'),  # for debugging ;p
        }

        return (placeholders, color, update)

    def _get_control_states(self):
        control_states = {
            'pause': {'action': 'Pause',
                      'clickable': 'CanPause',
                      'icon': self.icon_pause},
            'play': {'action': 'Play',
                     'clickable': 'CanPlay',
                     'icon': self.icon_play},
            'stop': {'action': 'Stop',
                     # Workaround: The MPRIS API has no CanStop function.
                     'clickable': 'True',
                     'icon': self.icon_stop},
            'next': {'action': 'Next',
                     'clickable': 'CanGoNext',
                     'icon': self.icon_next},
            'previous': {'action': 'Previous',
                         'clickable': 'CanGoPrevious',
                         'icon': self.icon_previous}
        }

        state = 'pause' if self._data.get('state') == PLAYING else 'play'
        control_states['toggle'] = control_states[state]

        return control_states

    def _get_response_buttons(self):
        response = {}

        for button in self._control_states.keys():
            control_state = self._control_states[button]

            if self._get_button_state(control_state):
                color = self.py3.COLOR_CONTROL_ACTIVE or self.py3.COLOR_GOOD
            else:
                color = self.py3.COLOR_CONTROL_INACTIVE or self.py3.COLOR_BAD

            response[button] = {
                'color': color,
                'full_text': control_state['icon'],
                'index': button,
                'min_width': 20,
                'align': 'center'
            }

        return response

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

    def _name_owner_changed(self, *args):
        player_add = args[5][2]
        player_remove = args[5][1]
        if player_add:
            self._add_player(player_add)
        if player_remove:
            self._remove_player(player_remove)
        self._set_player()

    def _set_player(self):
        """
        Sort the current players into priority order and set self._player
        Players are ordered by working state then prefernce supplied by user
        and finally by instance if a player has more than one running.
        """
        players = []
        for name, p in self._mpris_players.items():
            # we set the priority here as we need to establish the player name
            # which might not be immediately available.
            if '_priority' not in p:
                if self.player_priority:
                    try:
                        priority = self.player_priority.index(p['name'])
                    except ValueError:
                        try:
                            priority = self.player_priority.index('*')
                        except ValueError:
                            priority = None
                else:
                    priority = 0
                if priority is not None:
                    p['_priority'] = priority
            if p.get('_priority') is not None:
                players.append(
                    (p['_state_priority'], p['_priority'], p['index'], name)
                )
        if players:
            top_player = self._mpris_players.get(sorted(players)[0][3])
        else:
            top_player = {}

        self._player = top_player.get('_dbus_player')
        self._player_details = top_player

        self.py3.update()

    def _player_monitor(self, player_id):
        def player_on_change(*args):
            """
            Monitor a player and update its status.
            """
            data = args[1]
            status = data.get('PlaybackStatus')
            if status:
                player = self._mpris_players[player_id]
                player['status'] = status
                player['_state_priority'] = WORKING_STATES.index(status)
            self._set_player()
        return player_on_change

    def _add_player(self, player_id):
        """
        Add player to mpris_players
        """
        try:
            player = self._dbus.get(player_id, SERVICE_BUS_URL)
            if player_id.startswith(SERVICE_BUS):
                if player.Identity not in self._mpris_names:
                    self._mpris_names[player.Identity] = player_id.split('.')[-1]
                    for p in self._mpris_players.values():
                        if not p['name'] and p['identity'] in self._mpris_names:
                            p['name'] = self._mpris_names[p['identity']]
                            p['full_name'] = u'{} {}'.format(p['name'], p['index'])
                return
            status = player.PlaybackStatus
            state_priority = WORKING_STATES.index(status)
            identity = player.Identity
            if identity not in self._mpris_name_index:
                self._mpris_name_index[identity] = 0
            index = self._mpris_name_index[identity]
            self._mpris_name_index[identity] += 1
            name = self._mpris_names.get(identity)
            subscription = player.PropertiesChanged.connect(
                self._player_monitor(player_id)
            )
        except:
            return

        self._mpris_players[player_id] = {
            '_dbus_player': player,
            '_id': player_id,
            '_state_priority': state_priority,
            'index': index,
            'identity': identity,
            'name': name,
            'full_name': u'{} {}'.format(name, index),
            'status': status,
            'subscription': subscription,
        }
        return True

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

    def _get_players(self):
        bus = self._dbus.get('org.freedesktop.DBus')
        for player in bus.ListNames():
            if player.startswith(':') or player.startswith(SERVICE_BUS):
                if not self._add_player(player):
                    continue
        self._set_player()

    def _start_listener(self):
        self._dbus.con.signal_subscribe(
            None,
            'org.freedesktop.DBus',
            'NameOwnerChanged',
            None,
            None,
            0,
            self._name_owner_changed,
        )
        self._get_players()
        t = Thread(target=self._start_loop)
        t.daemon = True
        t.start()

    def _timeout(self):
        if self._kill:
            self._loop.quit()
            sys.exit(0)

    def _update_metadata(self, metadata):
        is_stream = False

        try:
            if len(metadata) > 0:
                url = metadata.get('xesam:url')
                is_stream = url is not None and 'file://' not in url
                self._data['title'] = metadata.get('xesam:title')
                self._data['album'] = metadata.get('xesam:album')

                if metadata.get('xesam:artist') is not None:
                    self._data['artist'] = metadata.get('xesam:artist')[0]
                else:
                    # we assume here that we playing a video and these types of
                    # media we handle just like streams
                    is_stream = True

                length_ms = metadata.get('mpris:length')
                if length_ms is not None:
                    self._data['length'] = _get_time_str(length_ms)
            else:
                # use stream format if no metadata is available
                is_stream = True
        except Exception:
            self._data['error_occurred'] = True

        if is_stream and self._data.get('title'):
            # delete the file extension
            self._data['title'] = re.sub(r'\....$', '', self._data.get('title'))

    def kill(self):
        self._kill = True

    def mpris(self):
        """
        Get the current output format and return it.
        """
        current_player_id = self._player_details.get('id')
        cached_until = self.py3.CACHE_FOREVER

        if self._player is None:
            text = self.format_none
            color = self.py3.COLOR_BAD
            composite = [{
                'full_text': text,
                'color': color,
            }]
            self._data = {}
        else:
            self._init_data()
            (text, color, cached_until) = self._get_text()
            self._control_states = self._get_control_states()
            buttons = self._get_response_buttons()
            composite = self.py3.build_composite(self.format,
                                                 text,
                                                 buttons)

        if (self._data.get('error_occurred') or
                current_player_id != self._player_details.get('id')):
            # Something went wrong or the player changed during our processing
            # This is usually due to something like a player being killed
            # whilst we are checking its details
            # Retry but limit the number of attempts
            self._tries += 1
            if self._tries < 3:
                return self.mpris()
            # Max retries hit we need to output something
            composite = [{
                'full_text': 'Something went wrong',
                'color': self.py3.COLOR_BAD,
            }]
            cached_until = self.py3.time_in(1)

        response = {
            'cached_until': cached_until,
            'color': color,
            'composite': composite
        }

        # we are outputing so reset tries
        self._tries = 0
        return response

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

        if not index:
            return

        if index not in self._control_states.keys():
            if button == self.button_toggle:
                index = 'toggle'
            elif button == self.button_stop:
                index = 'stop'
            elif button == self.button_next:
                index = 'next'
            elif button == self.button_previous:
                index = 'previous'
            else:
                return
        elif button != 1:
            return

        control_state = self._control_states[index]
        if self._player and self._get_button_state(control_state):
            getattr(self._player, self._control_states[index]['action'])()
Exemple #47
0
#!/usr/bin/env python
# -*- coding: utf-8 -*-

from flask import Flask
from flask import request
app = Flask(__name__)

from pydbus import SessionBus
bus = SessionBus()
try:
    player = bus.get("github.zhangn1985.dbplay")
except:
    from playthread import Mpvplayer
    player = Mpvplayer()
    player.start()

import json
import types

from ykdl.common import url_to_module

@app.route('/play', methods=['POST', 'GET'])
def play():
    if request.method == 'POST':
        url = request.form['url']
        try:
            islist = request.form['list']
            islist = islist == "True"
        except:
            islist = False
        m,u = url_to_module(url)
def command_cb(*args, **kwargs):
    if SCARLETT_DEBUG:
        logger.debug("command_cb PrettyPrinter: ")
        pp = pprint.PrettyPrinter(indent=4)
        pp.pprint(args)
        # MAR 13 2016
        logger.debug("command_cb kwargs")
        print_keyword_args(**kwargs)
        # (con=<DBusConnection object at 0x7f3fba21f0f0 (GDBusConnection at 0x2ede000)>,
        # sender=':1.0',
        # object='/org/scarlett/Listener',
        # iface='org.scarlett.Listener',
        # signal='CommandRecognizedSignal',
        # params=GLib.Variant('(sss)', ('  ScarlettListener caugh...ommand match', 'pi-response', 'what time is it')))

        # NOTE: THIS IS WHAT FIXED THE GENERATOR NONSENSE
        # source: https://www.python.org/dev/peps/pep-0343/
    def player_generator_func():
        for path in wavefile:
            path = os.path.abspath(os.path.expanduser(path))
            yield True
            print("for path in wavefile")
            p = generator_player.ScarlettPlayer(path, False)
            while True:
                try:
                    yield p.next()
                finally:
                    time.sleep(p.duration)
                    p.close(force=True)
                    yield False

    def run_player(function):
        gen = function()
        GObject.idle_add(lambda: next(gen, False), priority=GLib.PRIORITY_HIGH)


    def speaker_generator_func():
        for scarlett_text in tts_list:
            yield True
            print("scarlett_text in tts_list")
            _wavepath = "/home/pi/dev/bossjones-github/scarlett-dbus-poc/espeak_tmp.wav"
            s = generator_speaker.ScarlettSpeaker(text_to_speak=scarlett_text,
                                                  wavpath=_wavepath,
                                                  skip_player=True)
            p = generator_player.ScarlettPlayer(_wavepath, False)
            logger.error("Duration: p.duration: {}".format(p.duration))
            while True:
                try:
                    yield p.next()
                finally:
                    time.sleep(p.duration)
                    p.close(force=True)
                    s.close(force=True)
                    yield False

    def run_speaker(function):
        gen = function()
        GObject.idle_add(lambda: next(gen, False), priority=GLib.PRIORITY_HIGH)

    for i, v in enumerate(args):
        if SCARLETT_DEBUG:
            logger.debug("Type v: {}".format(type(v)))
            logger.debug("Type i: {}".format(type(i)))
        if isinstance(v, tuple):
            if SCARLETT_DEBUG:
                logger.debug(
                    "THIS SHOULD BE A Tuple now: {}".format(v))
            msg, scarlett_sound, command = v
            logger.warning(" msg: {}".format(msg))
            logger.warning(
                " scarlett_sound: {}".format(scarlett_sound))
            logger.warning(" command: {}".format(command))

            # 1. play sound first
            wavefile = SoundType.get_path(scarlett_sound)
            run_player_result = run_player(player_generator_func)

            # 2. Perform command
            command_run_results = generator_commands.Command.check_cmd(command_tuple=v)

            # 3. Verify it is not a command NO_OP
            if command_run_results == '__SCARLETT_NO_OP__':
                logger.error("__SCARLETT_NO_OP__")
                return False

            # 4. Scarlett Speaks
            tts_list = SpeakerType.speaker_to_array(command_run_results)
            run_speaker_result = run_speaker(speaker_generator_func)

            # 5. Emit signal to reset keyword match ( need to implement this )
            bus = SessionBus()
            ss = bus.get("org.scarlett", object_path='/org/scarlett/Listener')  # NOQA
            time.sleep(1)
            ss.emitListenerCancelSignal()
            # 6. Finished call back
        else:
            logger.debug("THIS IS NOT A GLib.Variant: {} - TYPE {}".format(v, type(v)))
class ScarlettListenerI(threading.Thread, _IdleObject):
    """
    Attempt to take out all Gstreamer logic and put it in a class ouside the dbus server.
    Cancellable thread which uses gobject signals to return information
    to the GUI.
    """
    __gsignals__ = SCARLETT_LISTENER_I_SIGNALS

    device = PS_DEVICE
    hmm = HMM_PATH
    lm = LM_PATH
    dic = DICT_PATH

    # SCARLETT_LISTENER_I_SIGNALS = {
    #     "completed": (
    #         GObject.SignalFlags.RUN_LAST, None, []),
    #     "progress": (
    #         GObject.SignalFlags.RUN_LAST, None, [
    #             GObject.TYPE_FLOAT]),  # percent complete
    #     "eos": (GObject.SignalFlags.RUN_LAST, None, ()),
    #     "error": (GObject.SignalFlags.RUN_LAST, None, (GObject.TYPE_STRING, GObject.TYPE_STRING)),
    #     "died": (GObject.SignalFlags.RUN_LAST, None, ()),
    #     "async-done": (GObject.SignalFlags.RUN_LAST, None, ()),
    #     "state-change": (GObject.SignalFlags.RUN_LAST, None, (GObject.TYPE_INT, GObject.TYPE_INT)),
    #     # FIXME: AUDIT THE RETURN TYPES
    #     "keyword-recgonized": (GObject.SignalFlags.RUN_LAST, None, (GObject.TYPE_STRING, GObject.TYPE_STRING)),
    #     "command-recgonized": (GObject.SignalFlags.RUN_LAST, None, (GObject.TYPE_STRING, GObject.TYPE_STRING)),
    #     "stt-failed": (GObject.SignalFlags.RUN_LAST, None, (GObject.TYPE_STRING, GObject.TYPE_STRING)),
    #     "listener-cancel": (GObject.SignalFlags.RUN_LAST, None, (GObject.TYPE_STRING, GObject.TYPE_STRING)),
    #     "listener-ready": (GObject.SignalFlags.RUN_LAST, None, (GObject.TYPE_STRING, GObject.TYPE_STRING)),
    #     "connected-to-server": (GObject.SignalFlags.RUN_LAST, None, (GObject.TYPE_STRING, GObject.TYPE_STRING)),
    #     "listener-message": (GObject.SignalFlags.RUN_LAST, None, (GObject.TYPE_STRING, GObject.TYPE_STRING)),
    #     'finished': (GObject.SignalFlags.RUN_LAST, None, (GObject.TYPE_PYOBJECT,)),
    #     'aborted': (GObject.SignalFlags.RUN_LAST, None, (GObject.TYPE_PYOBJECT,))
    # }

    def __init__(self, *args):
        threading.Thread.__init__(self)
        _IdleObject.__init__(self)

        # Gst.init(None)

        self.running = False
        self.finished = False
        self.ready_sem = threading.Semaphore(0)
        self.queue = queue.Queue(QUEUE_SIZE)

        # This wil get filled with an exception if opening fails.
        self.read_exc = None
        self.dot_exc = None

        self.cancelled = False
        self.name = args[0]
        self.setName("%s" % self.name)

        self.pipelines_stack = []
        self.elements_stack = []
        self.gst_bus_stack = []

        self._message = 'This is the ScarlettListenerI'
        self.config = scarlett_config.Config()
        self.override_parse = ''
        self.failed = 0
        self.kw_found = 0
        self.debug = False
        self.create_dot = True
        self.terminate = False

        self.capsfilter_queue_overrun_handler = None

        # source: https://github.com/ljmljz/xpra/blob/b32f748e0c29cdbfab836b3901c1e318ea142b33/src/xpra/sound/sound_pipeline.py  # NOQA
        self.bus = None
        self.bus_message_element_handler_id = None
        self.bus_message_error_handler_id = None
        self.bus_message_eos_handler_id = None
        self.bus_message_state_changed_handler_id = None
        self.pipeline = None
        self.start_time = 0
        self.state = "stopped"
        self.buffer_count = 0
        self.byte_count = 0

        # # Thread manager, maximum of 1 since it'll be long running
        # self.manager = FooThreadManager(1)

        self._status_ready = "  ScarlettListener is ready"
        self._status_kw_match = "  ScarlettListener caught a keyword match"
        self._status_cmd_match = "  ScarlettListener caught a command match"
        self._status_stt_failed = "  ScarlettListener hit Max STT failures"
        self._status_cmd_start = "  ScarlettListener emitting start command"
        self._status_cmd_fin = "  ScarlettListener Emitting Command run finish"
        self._status_cmd_cancel = "  ScarlettListener cancel speech Recognition"

        if self.debug:
            # NOTE: For testing puposes, mainly when in public
            # so you dont have to keep yelling scarlett in front of strangers
            self.kw_to_find = ['yo', 'hello', 'man', 'children']
        else:
            self.kw_to_find = self.config.get('scarlett', 'keywords')

        if self.read_exc:
            # An error occurred before the stream became ready.
            self.close(True)
            raise self.read_exc

    def connect_to_dbus(self):
        # self.dbus_stack.append(bus)
        # self.dbus_stack.append(path)
        # logger.debug("Inside self.dbus_stack")
        # pp.pprint(self.dbus_stack)
        pass

    def scarlett_reset_listen(self):
        self.failed = 0
        self.kw_found = 0

    def cancel_listening(self, *args, **kwargs):
        logger.debug("Inside cancel_listening function")
        self.scarlett_reset_listen()
        logger.debug("self.failed = %i" % (self.failed))
        logger.debug(
            "self.keyword_identified = %i" %
            (self.kw_found))

    def play(self):
        p = self.pipelines_stack[0]
        self.state = "active"
        self.running = True
        # GST_STATE_PAUSED is the state in which an element is ready to accept and handle data.
        # For most elements this state is the same as PLAYING. The only exception to this rule are sink elements.
        # Sink elements only accept one single buffer of data and then block.
        # At this point the pipeline is 'prerolled' and ready to render data immediately.
        p.set_state(Gst.State.PAUSED)
        # GST_STATE_PLAYING is the highest state that an element can be in.
        # For most elements this state is exactly the same as PAUSED,
        # they accept and process events and buffers with data.
        # Only sink elements need to differentiate between PAUSED and PLAYING state.
        # In PLAYING state, sink elements actually render incoming data,
        # e.g. output audio to a sound card or render video pictures to an image sink.
        ret = p.set_state(Gst.State.PLAYING)
        if ret == Gst.StateChangeReturn.FAILURE:
            logger.error("ERROR: Unable to set the pipeline to the playing state")
        self.on_debug_activate()
        logger.debug("BEFORE: self.ready_sem.acquire()")
        self.ready_sem.acquire()
        logger.debug("AFTER: self.ready_sem.acquire()")
        logger.info("Press Ctrl+C to quit ...")

    # @trace
    def stop(self):
        p = self.pipelines_stack[0]
        self.state = "stopped"
        self.running = False
        # GST_STATE_NULL is the default state of an element.
        # In this state, it has not allocated any runtime resources,
        # it has not loaded any runtime libraries and it can obviously not handle data.
        p.set_state(Gst.State.NULL)

    def get_pocketsphinx_definition(self, override=False):
        """
        GST_DEBUG=2,pocketsphinx*:5 gst-launch-1.0 alsasrc device=plughw:CARD=Device,DEV=0 ! \
                                                    queue name=capsfilter_queue \
                                                          leaky=2 \
                                                          max-size-buffers=0 \
                                                          max-size-time=0 \
                                                          max-size-bytes=0 ! \
                                                    capsfilter caps='audio/x-raw,format=(string)S16LE,rate=(int)16000,channels=(int)1,layout=(string)interleaved' ! \
                                                    audioconvert ! \
                                                    audioresample ! \
                                                    pocketsphinx \
                                                    name=asr \
                                                    lm=~/dev/bossjones-github/scarlett-dbus-poc/tests/fixtures/lm/1473.lm \
                                                    dict=~/dev/bossjones-github/scarlett-dbus-poc/tests/fixtures/dict/1473.dic \
                                                    hmm=~/.virtualenvs/scarlett-dbus-poc/share/pocketsphinx/model/en-us/en-us
                                                    bestpath=true ! \
                                                    tee name=tee ! \
                                                    queue name=appsink_queue \
                                                          leaky=2 \
                                                          max-size-buffers=0 \
                                                          max-size-time=0 \
                                                          max-size-bytes=0 ! \
                                                    appsink caps='audio/x-raw,format=(string)S16LE,rate=(int)16000,channels=(int)1,layout=(string)interleaved' \
                                                    drop=false max-buffers=10 sync=false \
                                                    emit-signals=true tee.
                                                    queue name=fakesink_queue \
                                                          leaky=2 \
                                                          max-size-buffers=0 \
                                                          max-size-time=0 \
                                                          max-size-bytes=0 ! \
                                                    fakesink sync=false
        """
        logger.debug("Inside get_pocketsphinx_definition")

        if override:
            _gst_launch = override
        else:
            _gst_launch = ['alsasrc device=' +
                           ScarlettListenerI.device,
                           # source: https://github.com/walterbender/story/blob/master/grecord.py
                           # without a buffer here, gstreamer struggles at the start of the
                           # recording and then the A/V sync is bad for the whole video
                           # (possibly a gstreamer/ALSA bug -- even if it gets caught up, it
                           # should be able to resync without problem)
                           'queue name=capsfilter_queue silent=false leaky=2 max-size-buffers=0 max-size-time=0 max-size-bytes=0',
                           'capsfilter name=capsfilter caps=audio/x-raw,format=S16LE,channels=1,layout=interleaved',
                           'audioconvert name=audioconvert',
                           'audioresample name=audioresample',
                           'identity name=ident',
                           'pocketsphinx name=asr',
                           'tee name=tee',
                           'queue name=appsink_queue silent=false leaky=2 max-size-buffers=0 max-size-time=0 max-size-bytes=0',
                           #  caps=audio/x-raw,format=(string)S16LE,rate=(int)16000,channels=(int)1,layout=(string)interleaved   # NOQA
                           'appsink name=appsink drop=false max-buffers=10 sync=false emit-signals=true tee.',
                           'queue leaky=2 name=fakesink_queue',
                           'fakesink']

        return _gst_launch

    # @trace
    def cancel(self):
        """
        Threads in python are not cancellable, so we implement our own
        cancellation logic
        """
        self.cancelled = True

    @abort_on_exception
    def run(self, event=None):
        # TODO: WE NEED TO USE A THREADING EVENT OR A RLOCK HERE TO WAIT TILL DBUS SERVICE IS RUNNING TO CONNECT
        # TODO: SIGNALS TO THE DBUS PROXY METHODS WE WANT TO USE
        # TODO: lock.acquire() / event / condition
        # TODO: self.connect_to_dbus()
        # TODO: self.setup_dbus_callbacks_handlers()
        self._connect_to_dbus()
        self.init_gst()
        print "Running %s" % str(self)
        self.play()
        self.emit('playback-status-changed')
        self.emit('playing-changed')
        # FIXME: is this needed? # self.mainloop.run()

    def _connect_to_dbus(self):
        self.bus = SessionBus()
        self.dbus_proxy = self.bus.get("org.scarlett", object_path='/org/scarlett/Listener')  # NOQA
        self.dbus_proxy.emitConnectedToListener('ScarlettListener')
        sleep(2)
        logger.info('_connect_to_dbus')
        ss_cancel_signal = self.bus.subscribe(sender=None,
                                         iface="org.scarlett.Listener",
                                         signal="ListenerCancelSignal",
                                         object="/org/scarlett/Listener",
                                         arg0=None,
                                         flags=0,
                                         signal_fired=self.cancel_listening)

    # NOTE: This function generates the dot file, checks that graphviz in installed and
    # then finally generates a png file, which it then displays
    def on_debug_activate(self):
        dotfile = "/home/pi/dev/bossjones-github/scarlett-dbus-poc/_debug/generator-listener.dot"
        pngfile = "/home/pi/dev/bossjones-github/scarlett-dbus-poc/_debug/generator-listener-pipeline.png"  # NOQA
        if os.access(dotfile, os.F_OK):
            os.remove(dotfile)
        if os.access(pngfile, os.F_OK):
            os.remove(pngfile)
        Gst.debug_bin_to_dot_file(self.pipelines_stack[0],
                                  Gst.DebugGraphDetails.ALL, "generator-listener")
        os.system('/usr/bin/dot' + " -Tpng -o " + pngfile + " " + dotfile)

    def result(self, final_hyp):
        """Forward result signals on the bus to the main thread."""
        logger.debug("Inside result function")
        logger.debug("final_hyp: {}".format(final_hyp))
        pp.pprint(final_hyp)
        logger.debug("kw_to_find: {}".format(self.kw_to_find))
        if final_hyp in self.kw_to_find and final_hyp != '':
            logger.debug(
                "HYP-IS-SOMETHING: " +
                final_hyp +
                "\n\n\n")
            self.failed = 0
            self.kw_found = 1
            self.dbus_proxy.emitKeywordRecognizedSignal()  # CHANGEME
        else:
            failed_temp = self.failed + 1
            self.failed = failed_temp
            logger.debug(
                "self.failed = %i" %
                (self.failed))
            if self.failed > 4:
                # reset pipline
                self.dbus_proxy.emitSttFailedSignal()  # CHANGEME
                self.scarlett_reset_listen()

    def run_cmd(self, final_hyp):
        logger.debug("Inside run_cmd function")
        logger.debug("KEYWORD IDENTIFIED BABY")
        logger.debug(
            "self.kw_found = %i" %
            (self.kw_found))
        if final_hyp == 'CANCEL':
            self.dbus_proxy.emitListenerCancelSignal()  # CHANGEME
            self.cancel_listening()
        else:
            current_kw_identified = self.kw_found
            self.kw_found = current_kw_identified
            self.dbus_proxy.emitCommandRecognizedSignal(final_hyp)  # CHANGEME
            logger.info(
                " Command = {}".format(final_hyp))
            logger.debug(
                "AFTER run_cmd, self.kw_found = %i" %
                (self.kw_found))

    def init_gst(self):
        logger.debug("Inside init_gst")
        self.start_time = time.time()
        pipeline = Gst.parse_launch(' ! '.join(self.get_pocketsphinx_definition()))
        logger.debug("After get_pocketsphinx_definition")
        # Add pipeline obj to stack we can pull from later
        self.pipelines_stack.append(pipeline)

        gst_bus = pipeline.get_bus()
        # gst_bus = pipeline.get_gst_bus()
        gst_bus.add_signal_watch()
        self.bus_message_element_handler_id = gst_bus.connect("message::element", self._on_message)
        self.bus_message_eos_handler_id = gst_bus.connect("message::eos", self._on_message)
        self.bus_message_error_handler_id = gst_bus.connect("message::error", self._on_message)
        self.bus_message_state_changed_handler_id = gst_bus.connect("message::state-changed", self._on_state_changed)

        # Add bus obj to stack we can pull from later
        self.gst_bus_stack.append(gst_bus)

        appsink = pipeline.get_by_name('appsink')
        appsink.set_property(
            'caps',
            Gst.Caps.from_string('audio/x-raw,format=(string)S16LE,rate=(int)16000,channels=(int)1,layout=(string)interleaved'),
        )

        appsink.set_property('drop', False)
        appsink.set_property('max-buffers', BUFFER_SIZE)
        appsink.set_property('sync', False)

        # The callback to receive decoded data.
        appsink.set_property('emit-signals', True)
        appsink.connect("new-sample", self._new_sample)

        self.caps_handler = appsink.get_static_pad("sink").connect(
            "notify::caps", self._notify_caps
        )

        self.elements_stack.append(appsink)

        # get gst pipeline element pocketsphinx and set properties
        pocketsphinx = pipeline.get_by_name('asr')
        if ScarlettListenerI.hmm:
            pocketsphinx.set_property('hmm', ScarlettListenerI.hmm)
        if ScarlettListenerI.lm:
            pocketsphinx.set_property('lm', ScarlettListenerI.lm)
        if ScarlettListenerI.dic:
            pocketsphinx.set_property('dict', ScarlettListenerI.dic)

        pocketsphinx.set_property('fwdflat', True)  # Enable Flat Lexicon Search | Default: true
        pocketsphinx.set_property('bestpath', True)  # Enable Graph Search | Boolean. Default: true
        pocketsphinx.set_property('dsratio', 1)  # Evaluate acoustic model every N frames |  Integer. Range: 1 - 10 Default: 1
        pocketsphinx.set_property('maxhmmpf', 3000)  # Maximum number of HMMs searched per frame | Integer. Range: 1 - 100000 Default: 30000
        pocketsphinx.set_property('bestpath', True)  # Enable Graph Search | Boolean. Default: true
        # pocketsphinx.set_property('maxwpf', -1)  # pocketsphinx.set_property('maxwpf', 20)  # Maximum number of words searched per frame | Range: 1 - 100000 Default: -1

        self.elements_stack.append(pocketsphinx)

        capsfilter_queue = pipeline.get_by_name('capsfilter_queue')
        capsfilter_queue.set_property('leaky', True)  # prefer fresh data
        capsfilter_queue.set_property('silent', False)
        capsfilter_queue.set_property('max-size-time', 0)  # 0 seconds
        capsfilter_queue.set_property('max-size-buffers', 0)
        capsfilter_queue.set_property('max-size-bytes', 0)
        self.capsfilter_queue_overrun_handler = capsfilter_queue.connect('overrun', self._log_queue_overrun)

        # capsfilter_queue.connect('overrun', self._on_overrun)
        # capsfilter_queue.connect('underrun', self._on_underrun)
        # capsfilter_queue.connect('pushing', self._on_pushing)
        # capsfilter_queue.connect('running', self._on_running)

        self.elements_stack.append(capsfilter_queue)

        ident = pipeline.get_by_name('ident')
        # ident.connect('handoff', self._on_handoff)

        self.elements_stack.append(ident)

        logger.debug("After all self.elements_stack.append() calls")
        # Set up the queue for data and run the main thread.
        self.queue = queue.Queue(QUEUE_SIZE)
        self.thread = get_loop_thread()

    def _on_handoff(self, element, buf):
        logger.debug('buf:')
        pp.pprint(buf)
        pp.pprint(dir(buf))
        logger.debug('on_handoff - %d bytes' % len(buf))
        # print 'buf =', buf
        # print 'dir(buf) =', dir(buf)

        if self.signed is None:
            # only ever one caps struct on our buffers
            struct = buf.get_caps().get_structure(0)

            # I think these are always set too, but catch just in case
            try:
                self.signed = struct["signed"]
                self.depth = struct["depth"]
                self.rate = struct["rate"]
                self.channels = struct["channels"]
            except:
                logger.debug('on_handoff: missing caps')
                pass

        # raw = str(buf)
        #
        # # print 'len(raw) =', len(raw)
        #
        # sm = 0
        # for i in range(0, len(raw)):
        #     sm += ord(raw[i])
        # # print sm
        # FIXEME: Add somthing like analyse.py
        # SOURCE: https://github.com/jcupitt/huebert/blob/master/huebert/audio.py

    def _on_state_changed(self, bus, msg):
        states = msg.parse_state_changed()
        # To state is PLAYING
        if msg.src.get_name() == "pipeline0" and states[1] == 4:
            logger.info('Inside pipeline0 on _on_state_changed')
            logger.info("State: {}".format(states[1]))
            self.ready_sem.release()
            return False
        else:
            # logger.error('NOTHING RETURNED in _on_state_changed')
            logger.info("State: {}".format(states[1]))

    def _on_overrun(self, element):
        logging.debug('on_overrun')

    def _on_underrun(self, element):
        logging.debug('on_underrun')

    def _on_running(self, element):
        logging.debug('on_running')

    def _on_pushing(self, element):
        logging.debug('on_pushing')

    def _notify_caps(self, pad, args):
        """The callback for the sinkpad's "notify::caps" signal.
        """
        # The sink has started to receive data, so the stream is ready.
        # This also is our opportunity to read information about the
        # stream.
        self.got_caps = True

        # Allow constructor to complete.
        self.ready_sem.release()

    _got_a_pad = False

    def _log_queue_overrun(self, queue):
        cbuffers = queue.get_property('current-level-buffers')
        cbytes = queue.get_property('current-level-bytes')
        ctime = queue.get_property('current-level-time')

    def _new_sample(self, sink):
        """The callback for appsink's "new-sample" signal.
        """
        if self.running:
            # New data is available from the pipeline! Dump it into our
            # queue (or possibly block if we're full).
            buf = sink.emit('pull-sample').get_buffer()
            self.queue.put(buf.extract_dup(0, buf.get_size()))
        return Gst.FlowReturn.OK

    def _on_message(self, bus, message):
        """The callback for GstBus's "message" signal (for two kinds of
        messages).
        """
        # logger.debug("[_on_message](%s, %s)", bus, message)
        if not self.finished:
            struct = message.get_structure()

            if message.type == Gst.MessageType.EOS:
                # The file is done. Tell the consumer thread.
                self.queue.put(SENTINEL)
                if not self.got_caps:
                    logger.error(
                        "If the stream ends before _notify_caps was called, this is an invalid stream.")
                    # If the stream ends before _notify_caps was called, this
                    # is an invalid file.
                    self.read_exc = generator_utils.NoStreamError()
                    self.ready_sem.release()
            elif struct and struct.get_name() == 'pocketsphinx':
                        if struct['final']:
                            logger.info(struct['hypothesis'])
                            if self.kw_found == 1:
                                # If keyword is set AND qualifier
                                # then perform action
                                self.run_cmd(struct['hypothesis'])
                            else:
                                # If it's the main keyword,
                                # set values wait for qualifier
                                self.result(struct['hypothesis'])
            elif message.type == Gst.MessageType.ERROR:
                gerror, debug = message.parse_error()
                pp.pprint(("gerror,debug:", gerror, debug))
                if 'not-linked' in debug:
                    logger.error('not-linked')
                    self.read_exc = generator_utils.NoStreamError()
                elif 'No such device' in debug:
                    logger.error('No such device')
                    self.read_exc = generator_utils.NoStreamError()
                else:
                    logger.info("FileReadError")
                    pp.pprint(("SOME FileReadError", bus, message, struct, struct.get_name()))
                    self.read_exc = generator_utils.FileReadError(debug)
                self.ready_sem.release()

    # Cleanup.
    def close(self, force=False):
        """Close the file and clean up associated resources.

        Calling `close()` a second time has no effect.
        """
        if self.running or force:
            self.running = False
            self.finished = True

            try:
                gst_bus = self.gst_bus_stack[0]
            except:
                logger.error("Failed to get gst_bus from gst_bus_stack[0]")
                pass

            if gst_bus:
                gst_bus.remove_signal_watch()
                if self.bus_message_element_handler_id:
                    gst_bus.disconnect(self.bus_message_element_handler_id)
                if self.bus_message_error_handler_id:
                    gst_bus.disconnect(self.bus_message_error_handler_id)
                if self.bus_message_eos_handler_id:
                    gst_bus.disconnect(self.bus_message_eos_handler_id)
                if self.bus_message_state_changed_handler_id:
                    gst_bus.disconnect(self.bus_message_state_changed_handler_id)

            self.bus = None
            self.pipeline = None
            self.codec = None
            self.bitrate = -1
            self.state = None

            # Unregister for signals, which we registered for above with
            # `add_signal_watch`. (Without this, GStreamer leaks file
            # descriptors.)
            logger.debug('BEFORE p = self.pipelines_stack[0]')
            p = self.pipelines_stack[0]
            p.get_bus().remove_signal_watch()
            logger.debug('AFTER p.get_bus().remove_signal_watch()')

            # Block spurious signals.
            appsink = self.elements_stack[0]
            appsink.get_static_pad("sink").disconnect(self.caps_handler)

            # Make space in the output queue to let the decoder thread
            # finish. (Otherwise, the thread blocks on its enqueue and
            # the interpreter hangs.)
            try:
                self.queue.get_nowait()
            except queue.Empty:
                pass

            # Halt the pipeline (closing file).
            self.stop()

            # Delete the pipeline object. This seems to be necessary on Python
            # 2, but not Python 3 for some reason: on 3.5, at least, the
            # pipeline gets dereferenced automatically.
            del p

    def __del__(self):
        self.close()

    def __exit__(self, exc_type, exc_val, exc_tb):
        self.close()
        return False
Exemple #50
0
        from scarlett_os.internal.debugger import init_debugger
        from scarlett_os.internal.debugger import set_gst_grapviz_tracing

        init_debugger()
        set_gst_grapviz_tracing()
        # Example of how to use it

    loop = GLib.MainLoop()

    recieved_signals = []

    from pydbus import SessionBus

    bus = SessionBus()
    ss = bus.get("org.scarlett", object_path="/org/scarlett/Listener")
    time.sleep(0.5)

    # taken from tasker
    ss_failed_signal = bus.subscribe(
        sender=None,
        iface="org.scarlett.Listener",
        signal="SttFailedSignal",
        object="/org/scarlett/Listener",
        arg0=None,
        flags=0,
        signal_fired=catchall_handler,
    )

    ss_rdy_signal = bus.subscribe(
        sender=None,
Exemple #51
0
#!/usr/bin/env python

# Based on http://stackoverflow.com/questions/22390064/use-dbus-to-just-send-a-message-in-python

# Python script to call the methods of the DBUS Test Server

from pydbus import SessionBus

#get the session bus
bus = SessionBus()
#get the object
the_object = bus.get("net.lew21.pydbus.ClientServerExample")

#call the methods and print the results
reply = the_object.Hello()
print(reply)

reply = the_object.EchoString("test 123")
print(reply)

the_object.Quit()
Exemple #52
0
#!/usr/bin/python

from pydbus import SessionBus

session_bus = SessionBus()
bkd_obj = session_bus.get('org.geekpur.vishal.BKD',
        '/org/geekpur/vishal/BKD')
print bkd_obj.GetBackspaceCount()
Exemple #53
0
    def __init__(self):
        Gtk.Window.__init__(self, title=TITLE)
        #self.set_default_size(150, 100)
        grid_main = Gtk.Grid()
        self.add(grid_main)

        # Modify the overall font name and size, for use with video projection.
        if PROJECTOR:  
            pangoFont = Pango.FontDescription(PROJECTOR_FONT)
            self.modify_font(pangoFont)

        # Get the session dbus
        bus = SessionBus()
        # Get the object
        try:
            self.server_1_object = bus.get(BUS)
        except GLib.Error as e:
            print("GLib.Error: {}.\nIs the server running?".format(BUS))
            #print(e)
            sys.exit("Exiting...")

        except GDBus.Error as e:
            # Doesn't seem to have GDBus.Error as an error.
            # TODO: Remove is never detected
            print("Error 2")
            print(e)
        # TODO: Check if it can hang here. If bus not registered / available? 

        # Create Frames to group different data in.
        frame_1 = Gtk.Frame(label=FRAME_1, margin=10)
        grid_main.attach(frame_1, 0, 0, 1, 1)
        frame_2 = Gtk.Frame(label=FRAME_2, margin=10)
        grid_main.attach(frame_2, 1, 0, 1, 1)
        frame_3 = Gtk.Frame(label=FRAME_3, margin=10)
        grid_main.attach(frame_3, 0, 1, 1, 2)
        frame_4 = Gtk.Frame(label=FRAME_4, margin=10)
        grid_main.attach(frame_4, 1, 1, 1, 1)
        frame_5 = Gtk.Frame(label=FRAME_4, margin=10)
        grid_main.attach(frame_5, 1, 2, 1, 1)

        # Frame_1 Grid for widgets  
        grid_frame_1 = Gtk.Grid()
        frame_1.add(grid_frame_1)
        # Frame_1 Static labels. xalign float from 0 = left to 1 = right
        f1_label_1 = Gtk.Label(F1_LABEL_1, margin=10, xalign=1)
        f1_label_2 = Gtk.Label(F1_LABEL_2, margin=10, xalign=1)
        f1_label_3 = Gtk.Label(F1_LABEL_3, margin=10, xalign=1)
        f1_label_4 = Gtk.Label(F1_LABEL_4, margin=10, xalign=1)
        f1_label_5 = Gtk.Label(F1_LABEL_5, margin=10, xalign=1)
        # Frame_1 Attach to grid
        grid_frame_1.attach(f1_label_1, 0, 0, 1, 1,)
        grid_frame_1.attach(f1_label_2, 0, 1, 1, 1,)
        grid_frame_1.attach(f1_label_3, 0, 2, 1, 1,)
        grid_frame_1.attach(f1_label_4, 0, 3, 1, 1,)
        grid_frame_1.attach(f1_label_5, 0, 4, 1, 1,)
        # Frame_1 Dynamic labels. Provide self. 
        # So they can be updated by any method.
        self.f1_label_1a = Gtk.Label("0", margin=10, xalign=1)
        self.f1_label_2a = Gtk.Label("0", margin=10, xalign=1)
        self.f1_label_3a = Gtk.Label("0", margin=10, xalign=1)
        self.f1_label_4a = Gtk.Label("0", margin=10, xalign=1)
        self.f1_label_5a = Gtk.Label("0", margin=10, xalign=1)
        # Frame_1 Attach to grid
        grid_frame_1.attach(self.f1_label_1a, 1, 0, 1, 1,)
        grid_frame_1.attach(self.f1_label_2a, 1, 1, 1, 1,)
        grid_frame_1.attach(self.f1_label_3a, 1, 2, 1, 1,)
        grid_frame_1.attach(self.f1_label_4a, 1, 3, 1, 1,)
        grid_frame_1.attach(self.f1_label_5a, 1, 4, 1, 1,)
        # Frame_1 Progress bar
        self.f1_progressbar_1 = Gtk.ProgressBar()
        grid_frame_1.attach(self.f1_progressbar_1, 2, 0, 1, 1,)
        self.f1_progressbar_1.set_fraction(0)

        # Frame_2 Grid for widgets 
        grid_frame_2 = Gtk.Grid()
        frame_2.add(grid_frame_2)
        # Frame_2 Static labels.
        f2_label_1 = Gtk.Label(F2_LABEL_1, margin=10, xalign=1)
        f2_label_2 = Gtk.Label(F2_LABEL_2, margin=10, xalign=1)
        f2_label_3 = Gtk.Label(F2_LABEL_3, margin=10, xalign=1)
        f2_label_4 = Gtk.Label(F2_LABEL_4, margin=10, xalign=1)
        f2_label_5 = Gtk.Label(F2_LABEL_5, margin=10, xalign=1)
        f2_label_6 = Gtk.Label(F2_LABEL_6, margin=10, xalign=1)
        # Frame_2 Attach to grid
        grid_frame_2.attach(f2_label_1, 0, 0, 1, 1,)
        grid_frame_2.attach(f2_label_2, 0, 1, 1, 1,)
        grid_frame_2.attach(f2_label_3, 0, 2, 1, 1,)
        grid_frame_2.attach(f2_label_4, 0, 3, 1, 1,)
        grid_frame_2.attach(f2_label_5, 0, 4, 1, 1,)
        grid_frame_2.attach(f2_label_6, 0, 5, 1, 1,)
        # Frame_2 Dynamic labels.
        self.f2_label_1a = Gtk.Label("0", margin=10, xalign=1)
        self.f2_label_2a = Gtk.Label("0", margin=10, xalign=1)
        self.f2_label_3a = Gtk.Label("0", margin=10, xalign=1)
        self.f2_label_4a = Gtk.Label("0", margin=10, xalign=1)
        self.f2_label_5a = Gtk.Label("0", margin=10, xalign=1)
        self.f2_label_6a = Gtk.Label("0", margin=10, xalign=1)
        # Frame_2 Attach to grid
        grid_frame_2.attach(self.f2_label_1a, 1, 0, 1, 1,)
        grid_frame_2.attach(self.f2_label_2a, 1, 1, 1, 1,)
        grid_frame_2.attach(self.f2_label_3a, 1, 2, 1, 1,)
        grid_frame_2.attach(self.f2_label_4a, 1, 3, 1, 1,)
        grid_frame_2.attach(self.f2_label_5a, 1, 4, 1, 1,)
        grid_frame_2.attach(self.f2_label_6a, 1, 5, 1, 1,)

        # Frame_3 Grid for widgets
        grid_frame_3 = Gtk.Grid()
        frame_3.add(grid_frame_3)
        # Frame_3 Static labels.
        f3_label_1 = Gtk.Label(F3_LABEL_1, margin=10, xalign=1)
        f3_label_2 = Gtk.Label(F3_LABEL_2, margin=10, xalign=1)
        f3_label_3 = Gtk.Label(F3_LABEL_3, margin=10, xalign=1)
        f3_label_4 = Gtk.Label(F3_LABEL_4, margin=10, xalign=1)
        # Frame_3 Attach to grid
        grid_frame_3.attach(f3_label_1, 0, 0, 1, 1,)
        grid_frame_3.attach(f3_label_2, 0, 1, 1, 1,)
        grid_frame_3.attach(f3_label_3, 0, 2, 1, 1,)
        grid_frame_3.attach(f3_label_4, 0, 3, 1, 1,)
        # Frame_3 Dynamic labels.
        self.f3_label_1a = Gtk.Label("0", margin=10, xalign=1)
        self.f3_label_2a = Gtk.Label("0", margin=10, xalign=1)
        self.f3_label_3a = Gtk.Label("0", margin=10, xalign=1)
        self.f3_label_4a = Gtk.Label("0", margin=10, xalign=1)
        # Frame_3 Attach to grid
        grid_frame_3.attach(self.f3_label_1a, 1, 0, 1, 1,)
        grid_frame_3.attach(self.f3_label_2a, 1, 1, 1, 1,)
        grid_frame_3.attach(self.f3_label_3a, 1, 2, 1, 1,)
        grid_frame_3.attach(self.f3_label_4a, 1, 3, 1, 1,)
        # Frame_3 Progress bar.
        self.f3_progressbar_1 = Gtk.ProgressBar()
        grid_frame_3.attach(self.f3_progressbar_1, 2, 0, 1, 1,)
        self.f3_progressbar_1.set_fraction(0)

        # Frame_4 Grid for widgets
        grid_frame_4 = Gtk.Grid()
        frame_4.add(grid_frame_4)
        # Frame_4 Buttons. Start/Stop/Reset buttons.
        self.f4_button_1 = Gtk.Button(label=F4_BUTTON_1, margin=10)
        self.f4_button_2 = Gtk.Button(label=F4_BUTTON_2, margin=10)
        self.f4_button_2.set_sensitive(False)
        self.f4_button_3 = Gtk.Button(label=F4_BUTTON_3, margin=10)
        self.f4_button_4 = Gtk.Button(label=F4_BUTTON_4, margin=10)
        # Frame_4 Button call-back signals
        self.f4_button_1.connect("clicked", self.cb_f4_button_1,
                                 self.f4_button_2) 
        self.f4_button_2.connect("clicked", self.cb_f4_button_2, 
                                 self.f4_button_1)
        self.f4_button_3.connect("clicked", self.cb_f4_button_3)
        self.f4_button_4.connect("clicked", self.cb_f4_button_4)
        # Frame_4 Attach to grid
        grid_frame_4.attach(self.f4_button_1, 0, 0, 1, 1, )
        grid_frame_4.attach(self.f4_button_2, 1, 0, 1, 1, )
        grid_frame_4.attach(self.f4_button_3, 2, 0, 1, 1, )
        grid_frame_4.attach(self.f4_button_4, 3, 0, 1, 1, )


        # Frame_5 Grid for widgets
        grid_frame_5 = Gtk.Grid()
        frame_5.add(grid_frame_5)
        # Frame_5 Buttons. Start/Stop/Reset buttons.
        self.f5_button_1 = Gtk.Button(label=F5_BUTTON_1, margin=10)
        self.f5_button_2 = Gtk.Button(label=F5_BUTTON_2, margin=10)
        self.f5_button_3 = Gtk.Button(label=F5_BUTTON_3, margin=10)
        self.f5_button_4 = Gtk.Button(label=F5_BUTTON_4, margin=10)
        # Frame_5 Button call-back signals
        self.f5_button_1.connect("clicked", self.cb_f5_button_1)
        self.f5_button_2.connect("clicked", self.cb_f5_button_2)
        self.f5_button_3.connect("clicked", self.cb_f5_button_3)
        self.f5_button_4.connect("clicked", self.cb_f5_button_4)
        # Frame_5 Attach to grid
        grid_frame_5.attach(self.f5_button_1, 0, 0, 1, 1, )
        grid_frame_5.attach(self.f5_button_2, 1, 0, 1, 1, )
        grid_frame_5.attach(self.f5_button_3, 2, 0, 1, 1, )
        grid_frame_5.attach(self.f5_button_4, 3, 0, 1, 1, )

        # Launch with client started...
        self.cb_f4_button_1(self.f4_button_1, self.f4_button_2)
Exemple #54
0
from __future__ import print_function
from pydbus import SessionBus
from gi.repository import GLib
import subprocess
from time import sleep

loop = GLib.MainLoop()

subprocess.Popen("gnome-music")
sleep(5)
print("Waiting for GNOME Music to start...")

b = SessionBus()
m = b.get("org.mpris.MediaPlayer2.GnomeMusic", "/org/mpris/MediaPlayer2")

m.PropertiesChanged.connect(print)

m.ActivatePlaylist(m.GetPlaylists(0, 5, "Alphabetical", 0)[0][0])

m.Play()
sleep(1)
assert(m.PlaybackStatus == "Playing")

m.Pause()
assert(m.PlaybackStatus == "Paused")

m.Play()
assert(m.PlaybackStatus == "Playing")

t = m.Metadata["xesam:title"]
		return

    if conv in chat:
        send_me = nick + "--"

        if len(reason) > 0:
            send_me += " (" + reason + ")"

        for target_conv in iter(set(chat)-set([conv])):
            purple.PurpleConvChatSend(purple.PurpleConversationGetChatData(target_conv), send_me)
            debug_print(target_conv, send_me)

# start main proc

bus = SessionBus()
purple = bus.get("im.pidgin.purple.PurpleService", "/im/pidgin/purple/PurpleObject")

print ">>> Rainbow 🌈 Bridge for Libpurple/Finch/Pidgin <<<"

for conv in purple.PurpleGetConversations():
    name = purple.PurpleConversationGetName(conv)
    if name in bridge_me:
    	chat[conv] = {
            "nick": purple.PurpleConvChatGetNick(purple.PurpleConversationGetChatData(conv)),
            "protocol": purple.PurpleAccountGetProtocolName(purple.PurpleConversationGetAccount(conv)),
            "announce": name not in dont_announce,
            }

for conv in chat.keys():
	print "<->", chat[conv]["nick"], "on", purple.PurpleConversationGetName(conv), "(" + str(conv) + ")", "using", chat[conv]["protocol"]