Esempio n. 1
0
class SingleBusManager(BusManager):
    def __init__(self,
                 spotify: Spotify,
                 bus: Bus = None,
                 app_name: str = "spotpris"):
        super().__init__(spotify, app_name)
        self.registration = None
        if bus is None:
            self.bus = SessionBus()  # Use built in method to get bus singleton
            self.bus.request_name(f"org.mpris.MediaPlayer2.{app_name}")
        else:
            self.bus = bus
        self.player = None

    def _register(self, player):
        self.player = player
        self.registration = self.bus.register_object("/org/mpris/MediaPlayer2",
                                                     player, None)

    def main_loop(self):
        current_playback = self.spotify.current_playback()
        if current_playback is None:
            if self.registration is not None:
                self.registration.unregister()
                self.registration = None
        else:
            if self.registration is None:
                if self.player is None:
                    self._register(MediaPlayer2(self.spotify,
                                                current_playback))
            self.player.event_loop(current_playback)
Esempio n. 2
0
class KbDaemon:
    def __init__(self):
        # Logging
        self.logger = logging.getLogger('daemon')
        self.logger.setLevel(logging.DEBUG)

        sh = logging.StreamHandler()
        sh.setLevel(logging.DEBUG)

        self.logger.addHandler(sh)

        # DBus
        self.bus = SessionBus()

    def start(self):
        try:
            self.bus.request_name('com.qtech.openkeyboard')
            self.bus.register_object('/com/qtech/openkeyboard',
                                     DaemonInterface(), None)
        except RuntimeError:
            self.logger.exception('Failed to connect to DBus')
            exit()

        # List keyboards
        kb_info = self.find_keyboard()
        print(kb_info)

        if kb_info is not None:
            self.logger.info(f'Connecting to keyboard at {kb_info["path"]}')
            rd = RedDragon(Device(path=kb_info['path']))
            self.bus.register_object(
                f'/com/qtech/openkeyboard/{kb_info["manufacturer_string"]}',
                KeyboardInterface(rd), None)
        else:
            self.logger.info(f'Creating fake keyboard')
            fake = FakeKeyboard()
            self.bus.register_object('/com/qtech/openkeyboard/fake',
                                     KeyboardInterface(fake), None)

        # Start main loop
        GLib.MainLoop().run()

    def find_keyboard(self):
        devices = enumerate(VID, PID)

        for device in devices:
            print(device)
            if device['interface_number'] == 1:
                return device

        return None
Esempio n. 3
0
def main():
    parser = argparse.ArgumentParser(
        description="Control Spotify Connect devices using MPRIS2")
    parser.add_argument('-d',
                        '--devices',
                        nargs='+',
                        metavar="DEVICE",
                        help="Only create interfaces for the listed devices")
    parser.add_argument('-i',
                        '--ignore',
                        nargs='+',
                        metavar="DEVICE",
                        help="Ignore the listed devices")
    parser.add_argument('-a',
                        '--auto',
                        action="store_true",
                        help="Automatically control the active device")
    parser.add_argument('-l',
                        '--list',
                        nargs='?',
                        choices=["name", "id"],
                        const="name",
                        help="List available devices and exit")
    parser.add_argument(
        '-s',
        '--steal-bus',
        action="store_true",
        help="Steal the dbus bus name from spotify to prevent "
        "it from also offering an MPRIS2 interface. If --auto is used use the spotify bus name as own "
        "bus name (experimental)")
    args = parser.parse_args()

    MediaPlayer2.dbus = [
        pkg_resources.resource_string(__name__,
                                      f"mpris/{iface}.xml").decode('utf-8')
        for iface in ifaces
    ]

    loop = GLib.MainLoop()

    oauth = authenticate()
    sp = Spotify(oauth_manager=oauth)

    if args.list:
        devices = sp.devices()
        for devices in devices["devices"]:
            print(devices[args.list])
        return

    exclusive_count = 0
    for arg in [args.devices, args.ignore, args.auto]:
        if arg:
            exclusive_count += 1
    if exclusive_count >= 2:
        parser.error(
            "Only one of --devices, --ignore and --auto can be used at the same time"
        )
        return

    if args.steal_bus:
        bus = SessionBus()
        try:
            # This sets the bus name for the SessionBus singleton which is also used by SingleBusManager
            bus.request_name("org.mpris.MediaPlayer2.spotify",
                             allow_replacement=False,
                             replace=True)
        except RuntimeError:
            print(
                "Failed to steal spotify bus name. You need to start spotPRIS2 before spotify"
            )
            exit(1)

    if not args.auto:
        manager = MultiBusManager(sp, args.devices, args.ignore)
    else:
        if args.steal_bus:
            manager = SingleBusManager(sp, bus=bus)
        else:
            manager = SingleBusManager(sp)

    def timeout_handler():
        try:
            manager.main_loop()
        except Exception as e:
            print(e)
        finally:
            return True

    GLib.timeout_add_seconds(1, timeout_handler)

    try:
        loop.run()
    except KeyboardInterrupt:
        pass
Esempio n. 4
0
class TestFakeMethods():
    def __init__(self, bluetoothAudioBridge):
        self.TestResult = 0
        self.bluetoothAudioBridge = bluetoothAudioBridge
        self.bluetoothAudioBridge.DbusBluezBusName = "BluetoothAudioBridge.FakeDbusObject"
        self.bluetoothAudioBridge.DbusBluezObjectPath = "/BluetoothAudioBridge/FakeDbusObject/hci0"
        self.bluetoothAudioBridge.PollingCycle = 1
        self.fakeDbusDevices = []
        self.fakeDbusAdapter = None
        self.fakeDbusAdapterRegistration = None
        self.fakeDbusObjectManager = None
        self.fakeDbusObjectManagerRegistration = None
        self.bus = None
        self.bluetoothAudioBridge.DbusBluezOnSystemBus = False
        self.busName = None

    def callerWithOneParameterWasCalled(self):
        def methodCall(parameter):
            print("parameter " + parameter)
            #print(self.TestResult)
            self.TestResult = self.TestResult + 1

        return methodCall

    def callerWithOneParameterWasCalledAsync(self):
        async def methodCall(parameter):
            print("parameter " + parameter)
            self.TestResult = self.TestResult + 1

        return methodCall

    async def unexportAllDevices(self):
        if self.fakeDbusObjectManager:
            for name, obj in self.fakeDbusDevices:
                self.fakeDbusObjectManager.unexport(name)
            self.fakeDbusDevices = []
        #if self.fakeDbusDevice:
        #    self.fakeDbusDevice.unregister()
        #if self.fakeDbusObjectManager:
        #    self.fakeDbusObjectManager.unregister()

    async def unexportDevice(self, path):
        self.fakeDbusObjectManager.unexport(path)
        self.fakeDbusDevices.remove(path)

    async def startTestFakeDbusBluez(self):
        if not self.bus:
            self.bus = SessionBus()
        await self.unexportAllDevices()
        if self.busName:
            busName.unown()
        if self.fakeDbusAdapterRegistration:
            self.fakeDbusAdapterRegistration.unregister()
            self.fakeDbusAdapterRegistration = None
        if self.fakeDbusObjectManagerRegistration:
            self.fakeDbusObjectManagerRegistration.unregister()
            self.fakeDbusObjectManagerRegistration = None
        await asyncio.sleep(0.5)
        prefix = "/" + self.bluetoothAudioBridge.DbusBluezBusName.replace(
            ".", "/")
        self.fakeDbusObjectManager = TestFakeObjectManager(self.bus)
        self.fakeDbusAdapter = TestFakeDbusBluezAdapter(self)
        self.fakeDbusObjectManagerRegistration = self.bus.register_object(
            "/", self.fakeDbusObjectManager, None)
        self.fakeDbusAdapterRegistration = self.fakeDbusObjectManager.export(
            prefix + "/hci0", self.fakeDbusAdapter)
        self.busName = self.bus.request_name(
            self.bluetoothAudioBridge.DbusBluezBusName)

    async def exportNewDevice(self, name):
        prefix = "/" + self.bluetoothAudioBridge.DbusBluezBusName.replace(
            ".", "/")
        self.fakeDbusDevice = TestFakeDbusBluezDevice(self)
        result = (prefix + "/hci0/dev_" + name, self.fakeDbusDevice)
        self.fakeDbusObjectManager.export(result[0], result[1])
        self.fakeDbusDevices.append(result)
        return result

    async def stopTestFakeDbusBluez(self):
        await self.unexportAllDevices()
        if (self.fakeDbusObjectManagerRegistration):
            self.fakeDbusObjectManagerRegistration.unregister()
        if (self.fakeDbusAdapterRegistration):
            self.fakeDbusAdapterRegistration.unregister()
        if self.busName:
            self.busName.unown()
        self.busName = None
        self.fakeDbusDevices = []
        self.fakeDbusObject = None
        self.fakeDbusObjectManager = None
        self.fakeDbusObjectManagerRegistration = None
        self.fakeDbusAdapter = None
        self.fakeDbusAdapterRegistration = None
        self.bus = None
        await asyncio.sleep(0.5)

    async def cancelIn2Seconds(self):
        await asyncio.sleep(2)
        self.bluetoothAudioBridge.CancellationToken.set_result(True)

    async def setResultInXSecondsCancelable(self, time):
        (finished, result) = await self.bluetoothAudioBridge.awaitOrStop(
            asyncio.sleep(time))
        if finished:
            print("set Result to true")
            self.TestResult = 1