Exemplo n.º 1
0
class WebUICoherenceTest(unittest.TestCase):
    def setUp(self):
        self.coherence = Coherence({
            'unittest': 'yes',
            'web-ui': 'yes',
            'serverport': '9001',
            'logmode': 'error',
        })

    @inlineCallbacks
    def test_web_ui_render_in_coherence(self):
        response = yield self.coherence.web_server.site.get(b"")
        self.assertEqual(response.value(), index_result % __version__)

    @inlineCallbacks
    def test_web_ui_get_child(self):
        req = DummyRequest(b'styles')
        res = yield self.coherence.web_server.web_root_resource.getChild(
            b'styles', req)
        self.assertIsInstance(res, static.File)

    @inlineCallbacks
    def test_web_ui_ws_callback(self):
        self.coherence.web_server.web_root_resource.ws_recived.clear()
        response = yield self.coherence.web_server.site.get(b"")
        factory = self.coherence.web_server.web_root_resource.factory
        factory.protocol.factory = factory
        factory.protocol.onMessage(factory.protocol, b'WebSocket Ready', None)
        self.assertEqual(
            self.coherence.web_server.web_root_resource.ws_recived,
            [b'WebSocket Ready'])

    @inlineCallbacks
    def test_web_ui_devices(self):
        c_dev = DummyDevice(friendly_name='CoherenceDummyDevice')
        self.coherence.add_device(c_dev)
        response = yield self.coherence.web_server.site.get(b"")
        factory = self.coherence.web_server.web_root_resource.factory
        factory.protocol.message_callback(b'WebSocket Ready', False)

        dev = DummyDevice()
        self.coherence.web_server.web_root_resource.devices.add_device(dev)
        self.assertEqual(
            self.coherence.web_server.web_root_resource.devices.detected,
            [("CoherenceDummyDevice", "CoherenceDummyDevice USN"),
             ("DummyDevice", "DummyDevice USN")])

        self.coherence.web_server.web_root_resource.devices.remove_device(
            dev.get_usn())
        self.assertEqual(
            self.coherence.web_server.web_root_resource.devices.detected,
            [("CoherenceDummyDevice", "CoherenceDummyDevice USN")])

        self.coherence.web_server.web_root_resource.devices.remove_device(
            c_dev.get_usn())

    def tearDown(self):
        self.coherence.shutdown()
Exemplo n.º 2
0
class TestCoherence(unittest.TestCase):
    def setUp(self):
        self.coherence = Coherence({'unittest': 'yes', 'logmode': 'error'})

    def tearDown(self):
        def cleaner(r):
            self.coherence.clear()
            return r

        dl = self.coherence.shutdown()
        dl.addBoth(cleaner)
        return dl

    def test_singleton(self):
        d = Deferred()

        c1 = Coherence({'unittest': 'no', 'logmode': 'error'})
        c2 = Coherence({'unittest': 'no', 'logmode': 'error'})
        c3 = Coherence({'unittest': 'no', 'logmode': 'error'})

        def shutdown(r, instance):
            return instance.shutdown()

        d.addCallback(shutdown, c1)
        d.addCallback(shutdown, c2)
        d.addCallback(shutdown, c3)

        reactor.callLater(3, d.callback, None)

        return d
Exemplo n.º 3
0
class TestCoherence(unittest.TestCase):

    def setUp(self):
        louie.reset()
        self.coherence = Coherence({'unittest':'yes','logmode':'error'})

    def tearDown(self):

        def cleaner(r):
            self.coherence.clear()
            return r

        dl = self.coherence.shutdown()
        dl.addBoth(cleaner)
        return dl

    def test_singleton(self):
        d = Deferred()

        c1 = Coherence({'unittest':'no','logmode':'error'})
        c2 = Coherence({'unittest':'no','logmode':'error'})
        c3 = Coherence({'unittest':'no','logmode':'error'})

        def shutdown(r,instance):
            return instance.shutdown()

        d.addCallback(shutdown,c1)
        d.addCallback(shutdown,c2)
        d.addCallback(shutdown,c3)

        reactor.callLater(3, d.callback, None)


        return d
Exemplo n.º 4
0
class TestCoherence(unittest.TestCase):
    def setUp(self):
        self.log_level = 'error'
        self.coherence = Coherence(
            {
                'unittest': 'yes',
                'logmode': self.log_level
            }, )

    def tearDown(self):
        def cleaner(r):
            self.coherence.clear()
            return r

        dl = self.coherence.shutdown()
        dl.addBoth(cleaner)
        return dl

    def test_singleton(self):
        d = Deferred()

        c1 = Coherence({'unittest': 'no', 'logmode': 'error'})
        c2 = Coherence({'unittest': 'no', 'logmode': 'error'})
        c3 = Coherence({'unittest': 'no', 'logmode': 'error'})

        def shutdown(r, instance):
            return instance.shutdown()

        d.addCallback(shutdown, c1)
        d.addCallback(shutdown, c2)
        d.addCallback(shutdown, c3)

        reactor.callLater(3, d.callback, None)

        return d

    def test_log_level(self):
        self.assertEqual(self.coherence.log_level, self.log_level.upper())

    def test_log_file(self):
        self.assertEqual(self.coherence.log_file, None)

        # now set a config file and test it
        fake_file = '/fake_dir/fake_file.log'
        self.coherence.config['logging'] = {'logfile': fake_file}
        self.assertEqual(self.coherence.log_file, fake_file)

    @mock.patch('coherence.base.get_ip_address')
    def test_setup_hostname(self, mock_get_ip):
        fake_ip = '192.168.1.24'
        mock_get_ip.return_value = fake_ip
        self.coherence.config['interface'] = fake_ip

        # we expect to have an real ip address assigned by the router
        self.assertNotEqual(self.coherence.hostname, '127.0.0.1')
        # proceed to set a fake ip address and test the result
        self.coherence.setup_hostname()
        self.assertEqual(self.coherence.hostname, fake_ip)
        mock_get_ip.assert_called_once_with(fake_ip)
class TestSwitchPowerClient(unittest.TestCase):

    def setUp(self):
        louie.reset()
        self.coherence = Coherence({'unittest':'yes','logmode':'error','subsystem_log':{'controlpoint':'error'},'controlpoint':'yes'})
        self.uuid = UUID()
        p = self.coherence.add_plugin('SimpleLight', name='test-light-%d'%os.getpid(),uuid=str(self.uuid))

    def tearDown(self):

        def cleaner(r):
            self.coherence.clear()
            return r

        dl = self.coherence.shutdown()
        dl.addBoth(cleaner)
        return dl

    def test_get_state(self):
        """ tries to find the activated SimpleLight backend
            and queries its state.
            The state is expected to be "off"
        """
        d = Deferred()

        def the_result(r):
            #print "the_result", r
            self.assertEqual(str(self.uuid), r.udn)

            call = r.client.switch_power.get_status()
            def got_answer(r):
                self.assertEqual(int(r['ResultStatus']), 0)
                d.callback(None)

            call.addCallback(got_answer)

        self.coherence.ctrl.add_query(DeviceQuery('uuid', str(self.uuid), the_result, timeout=10, oneshot=True))
        return d
class TestContentDirectoryServer(unittest.TestCase):
    def setUp(self):
        self.tmp_content = FilePath(self.mktemp())
        f = self.tmp_content.child('content')
        audio = f.child('audio')
        f.child('images').makedirs()
        f.child('video').makedirs()
        album = audio.child('album-1')
        album.makedirs()
        album.child('track-1.mp3').touch()
        album.child('track-2.mp3').touch()
        album = audio.child('album-2')
        album.makedirs()
        album.child('track-1.ogg').touch()
        album.child('track-2.ogg').touch()
        self.coherence = Coherence({
            'unittest': 'yes',
            'logmode': 'critical',
            'no-subsystem_log': {
                'controlpoint': 'error',
                'action': 'info',
                'soap': 'error'
            },
            'controlpoint': 'yes'
        })
        self.uuid = str(UUID())
        self.coherence.add_plugin('FSStore',
                                  name='MediaServer-%d' % os.getpid(),
                                  content=self.tmp_content.path,
                                  uuid=self.uuid,
                                  enable_inotify=False)

    def tearDown(self):
        self.tmp_content.remove()

        def cleaner(r):
            self.coherence.clear()
            return r

        dl = self.coherence.shutdown()
        dl.addBoth(cleaner)
        return dl

    def test_Browse(self):
        """ tries to find the activated FSStore backend
            and browses its root.
        """
        d = Deferred()

        @wrapped(d)
        def the_result(mediaserver):
            cdc = mediaserver.client.content_directory
            self.assertEqual(self.uuid, mediaserver.udn)
            call = cdc.browse(process_result=False)
            call.addCallback(got_first_answer, cdc)

        @wrapped(d)
        def got_first_answer(r, cdc):
            self.assertEqual(int(r['TotalMatches']), 1)
            didl = DIDLLite.DIDLElement.fromString(r['Result'])
            item = didl.getItems()[0]
            self.assertEqual(item.childCount, 3)
            call = cdc.browse(object_id=item.id, process_result=False)
            call.addCallback(got_second_answer, item.childCount)

        @wrapped(d)
        def got_second_answer(r, childcount):
            self.assertEqual(int(r['TotalMatches']), childcount)
            d.callback(None)

        self.coherence.ctrl.add_query(
            DeviceQuery('uuid',
                        self.uuid,
                        the_result,
                        timeout=10,
                        oneshot=True))
        return d

    def test_Browse_Non_Existing_Object(self):
        d = Deferred()

        @wrapped(d)
        def the_result(mediaserver):
            cdc = mediaserver.client.content_directory
            self.assertEqual(self.uuid, mediaserver.udn)
            call = cdc.browse(object_id='9999.nothing', process_result=False)
            call.addCallback(got_first_answer)

        @wrapped(d)
        def got_first_answer(r):
            self.assertIs(r, None)
            d.callback(None)

        self.coherence.ctrl.add_query(
            DeviceQuery('uuid',
                        self.uuid,
                        the_result,
                        timeout=10,
                        oneshot=True))
        return d

    def test_Browse_Metadata(self):
        """ tries to find the activated FSStore backend
            and requests metadata for ObjectID 0.
        """
        d = Deferred()

        @wrapped(d)
        def the_result(mediaserver):
            self.assertEqual(self.uuid, mediaserver.udn)
            cdc = mediaserver.client.content_directory
            call = cdc.browse(object_id='0',
                              browse_flag='BrowseMetadata',
                              process_result=False)
            call.addCallback(got_first_answer)

        @wrapped(d)
        def got_first_answer(r):
            self.assertEqual(int(r['TotalMatches']), 1)
            didl = DIDLLite.DIDLElement.fromString(r['Result'])
            item = didl.getItems()[0]
            self.assertEqual(item.title, 'root')
            d.callback(None)

        self.coherence.ctrl.add_query(
            DeviceQuery('uuid',
                        self.uuid,
                        the_result,
                        timeout=10,
                        oneshot=True))
        return d

    def test_XBOX_Browse(self):
        """ tries to find the activated FSStore backend
            and browses all audio files.
        """
        d = Deferred()

        @wrapped(d)
        def the_result(mediaserver):
            mediaserver.client.overlay_headers = {
                'user-agent': 'Xbox/Coherence emulation'
            }
            cdc = mediaserver.client.content_directory
            self.assertEqual(self.uuid, mediaserver.udn)
            call = cdc.browse(object_id='4', process_result=False)
            call.addCallback(got_first_answer)

        @wrapped(d)
        def got_first_answer(r):
            """ we expect four audio files here """
            self.assertEqual(int(r['TotalMatches']), 4)
            d.callback(None)

        d = Deferred()
        self.coherence.ctrl.add_query(
            DeviceQuery('uuid',
                        self.uuid,
                        the_result,
                        timeout=10,
                        oneshot=True))
        return d

    def test_XBOX_Browse_Metadata(self):
        """ tries to find the activated FSStore backend
            and requests metadata for ObjectID 0.
        """
        d = Deferred()

        @wrapped(d)
        def the_result(mediaserver):
            mediaserver.client.overlay_headers = {
                'user-agent': 'Xbox/Coherence emulation'
            }
            cdc = mediaserver.client.content_directory
            self.assertEqual(self.uuid, mediaserver.udn)
            call = cdc.browse(object_id='0',
                              browse_flag='BrowseMetadata',
                              process_result=False)
            call.addCallback(got_first_answer)

        @wrapped(d)
        def got_first_answer(r):
            """ we expect one item here """
            self.assertEqual(int(r['TotalMatches']), 1)
            didl = DIDLLite.DIDLElement.fromString(r['Result'])
            item = didl.getItems()[0]
            self.assertEqual(item.title, 'root')
            d.callback(None)

        self.coherence.ctrl.add_query(
            DeviceQuery('uuid',
                        self.uuid,
                        the_result,
                        timeout=10,
                        oneshot=True))
        return d

    def test_XBOX_Search(self):
        """ tries to find the activated FSStore backend
            and searches for all its audio files.
        """

        d = Deferred()

        @wrapped(d)
        def the_result(mediaserver):
            mediaserver.client.overlay_headers = {
                'user-agent': 'Xbox/Coherence emulation'
            }
            cdc = mediaserver.client.content_directory
            self.assertEqual(self.uuid, mediaserver.udn)
            call = cdc.search(container_id='4', criteria='')
            call.addCallback(got_first_answer)

        @wrapped(d)
        def got_first_answer(r):
            """ we expect four audio files here """
            self.assertEqual(len(r), 4)
            d.callback(None)

        self.coherence.ctrl.add_query(
            DeviceQuery('uuid',
                        self.uuid,
                        the_result,
                        timeout=10,
                        oneshot=True))
        return d
Exemplo n.º 7
0
class MirabeauController(object):
    coherence_started_cb = lambda: None

    def start(self):
        # TODO: select correct window class depending on platform
        main_window = MainWindow(self)
        main_window.show_all()

    def load_config(self):
        self.first_run = False
        if not os.path.exists(BASEDIR):
            os.makedirs(BASEDIR)
        if not os.path.exists(CONFIG_PATH):
            self.first_run = True

            default_account = ''
            vars = locals()
            vars["MR_UUID"] = MR_UUID
            cfg = DEFAULT_CONFIG % vars
            fd = open(CONFIG_PATH, "w")
            fd.write(cfg)
            fd.close()

        self.config = Config(CONFIG_PATH,
                             root='config',
                             element2attr_mappings={'active': 'active'})

    def reload_config(self):
        self.config.save()
        self.load_config()

    def enable_mirabeau(self):
        self.config.set("enable_mirabeau", "yes")
        self.reload_config()

    def disable_mirabeau(self):
        self.config.set("enable_mirabeau", "no")
        self.reload_config()

    def platform_media_directories(self):
        candidates = [
            "~/MyDocs/.images",
            "~/MyDocs/.sounds",
            "~/MyDocs/.videos",
            "~/MyDocs/DCIM",
            "~/MyDocs/Music",
            "~/MyDocs/Videos",
        ]
        expanded = [os.path.expanduser(c) for c in candidates]
        dirs = [c for c in expanded if os.path.isdir(c)]
        return dirs

    def enable_media_server(self, nickname=None):
        nickname = nickname or "N900"
        name_template = _("%(nickname)s Media Files")

        def generate_cfg(nickname):
            directories = self.platform_media_directories()
            name = name_template % locals()
            opts = dict(uuid=MS_UUID,
                        name=name,
                        content=",".join(directories),
                        backend="FSStore",
                        active="yes")
            return XmlDictObject(initdict=opts)

        plugins = self.config.get("plugin")
        if not plugins:
            self.config.set("plugin", generate_cfg())
        else:
            if isinstance(plugins, XmlDictObject):
                plugins = [
                    plugins,
                ]
            already_in_config = False
            for plugin in plugins:
                if plugin.get("uuid") == MS_UUID:
                    plugin.active = "yes"
                    plugin.name = name_template % locals()
                    already_in_config = True
                    break
            if not already_in_config:
                plugins.append(generate_cfg(nickname))
            self.config.set("plugin", plugins)
        self.reload_config()

    def disable_media_server(self):
        plugins = self.config.get("plugin")
        if plugins:
            if isinstance(plugins, XmlDictObject):
                plugins = [
                    plugins,
                ]
            for plugin in plugins:
                if plugin.get("uuid") == MS_UUID:
                    plugin.active = "no"
                    break
            self.config.set("plugin", plugins)
            self.reload_config()

    def media_server_enabled(self):
        plugins = self.config.get("plugin")
        if plugins:
            if isinstance(plugins, XmlDictObject):
                plugins = [
                    plugins,
                ]
            for plugin in plugins:
                if plugin.get("uuid") == MS_UUID and \
                   plugin.active == "yes":
                    return True
        return False

    def set_media_renderer_name(self, nickname=None):
        nickname = nickname or "N900"
        name_template = _("%(nickname)s Media Renderer")
        plugins = self.config.get("plugin")
        if plugins:
            if isinstance(plugins, XmlDictObject):
                plugins = [
                    plugins,
                ]
            for plugin in plugins:
                if plugin.get("uuid") == MR_UUID:
                    plugin.name = name_template % locals()
                    break
            self.config.set("plugin", plugins)
            self.reload_config()

    def start_coherence(self, restart=False):
        def start():
            if self.config.get("mirabeau").get("account"):
                self.enable_mirabeau()
            else:
                self.disable_mirabeau()
            self.coherence_instance = Coherence(self.config.config)

        if restart:
            if self.coherence_instance:
                dfr = self.stop_coherence()
                dfr.addCallback(lambda result: start())
                return dfr
            else:
                start()
        else:
            start()
        if self.coherence_instance:
            self.coherence_started_cb()

    def stop_coherence(self):
        def stopped(result):
            if self.coherence_instance:
                self.coherence_instance.clear()
                self.coherence_instance = None

        dfr = self.coherence_instance.shutdown(force=True)
        dfr.addBoth(stopped)
        return dfr

    def toggle_coherence(self):
        if self.coherence_instance:
            self.stop_coherence()
        else:
            self.start_coherence()

    def update_settings(self, chatroom, conf_server, account, account_nickname,
                        media_server_enabled):
        mirabeau_section = self.config.get("mirabeau")
        mirabeau_section.set("chatroom", chatroom)
        mirabeau_section.set("conference-server", conf_server)
        mirabeau_section.set("account", account)
        self.config.set("mirabeau", mirabeau_section)
        self.reload_config()

        nickname = account_nickname
        self.set_media_renderer_name(nickname)
        if media_server_enabled:
            self.enable_media_server(nickname=nickname)
        else:
            self.disable_media_server()
        self.start_coherence(restart=True)
class TestContentDirectoryServer(unittest.TestCase):
    def setUp(self):
        self.tmp_content = FilePath('tmp_content_coherence-%d' % os.getpid())
        f = self.tmp_content.child('content')
        audio = f.child('audio')
        f.child('images').makedirs()
        f.child('video').makedirs()
        album = audio.child('album-1')
        album.makedirs()
        album.child('track-1.mp3').touch()
        album.child('track-2.mp3').touch()
        album = audio.child('album-2')
        album.makedirs()
        album.child('track-1.ogg').touch()
        album.child('track-2.ogg').touch()
        louie.reset()
        self.coherence = Coherence({
            'unittest': 'yes',
            'logmode': 'debug',
            'subsystem_log': {
                'controlpoint': 'error',
                'action': 'error',
                'soap': 'error'
            },
            'controlpoint': 'yes'
        })
        self.uuid = UUID()
        p = self.coherence.add_plugin('FSStore',
                                      name='MediaServer-%d' % os.getpid(),
                                      content=self.tmp_content.path,
                                      uuid=str(self.uuid))

    def tearDown(self):
        self.tmp_content.remove()

        def cleaner(r):
            self.coherence.clear()
            return r

        dl = self.coherence.shutdown()
        dl.addBoth(cleaner)
        return dl

    def test_Browse(self):
        """ tries to find the activated FSStore backend
            and browses its root.
        """
        d = Deferred()

        def the_result(mediaserver):
            try:
                self.assertEqual(str(self.uuid), mediaserver.udn)
            except:
                d.errback()

            def got_second_answer(r, childcount):
                try:
                    self.assertEqual(int(r['TotalMatches']), childcount)
                    d.callback(None)
                except:
                    d.errback()

            def got_first_answer(r):
                try:
                    self.assertEqual(int(r['TotalMatches']), 1)
                except:
                    d.errback()

                didl = DIDLLite.DIDLElement.fromString(r['Result'])
                item = didl.getItems()[0]
                try:
                    self.assertEqual(item.childCount, 3)
                except:
                    d.errback()

                call = mediaserver.client.content_directory.browse(
                    object_id=item.id, process_result=False)
                call.addCallback(got_second_answer, item.childCount)
                return call

            call = mediaserver.client.content_directory.browse(
                process_result=False)
            call.addCallback(got_first_answer)

        self.coherence.ctrl.add_query(
            DeviceQuery('uuid',
                        str(self.uuid),
                        the_result,
                        timeout=10,
                        oneshot=True))
        return d

    def test_Browse_Metadata(self):
        """ tries to find the activated FSStore backend
            and requests metadata for ObjectID 0.
        """
        d = Deferred()

        def the_result(mediaserver):
            try:
                self.assertEqual(str(self.uuid), mediaserver.udn)
            except:
                d.errback()

            def got_first_answer(r):
                try:
                    self.assertEqual(int(r['TotalMatches']), 1)
                except:
                    d.errback()
                    return
                didl = DIDLLite.DIDLElement.fromString(r['Result'])
                item = didl.getItems()[0]
                try:
                    self.assertEqual(item.title, 'root')
                except:
                    d.errback()
                    return
                d.callback(None)

            call = mediaserver.client.content_directory.browse(
                object_id='0',
                browse_flag='BrowseMetadata',
                process_result=False)
            call.addCallback(got_first_answer)
            call.addErrback(lambda x: d.errback(None))

        self.coherence.ctrl.add_query(
            DeviceQuery('uuid',
                        str(self.uuid),
                        the_result,
                        timeout=10,
                        oneshot=True))
        return d

    def test_XBOX_Browse(self):
        """ tries to find the activated FSStore backend
            and browses all audio files.
        """
        d = Deferred()

        def the_result(mediaserver):
            try:
                self.assertEqual(str(self.uuid), mediaserver.udn)
            except:
                d.errback()

            def got_first_answer(r):
                """ we expect four audio files here """
                try:
                    self.assertEqual(int(r['TotalMatches']), 4)
                except:
                    d.errback()
                    return
                d.callback(None)

            def my_browse(*args, **kwargs):
                kwargs['ContainerID'] = kwargs['ObjectID']
                del kwargs['ObjectID']
                del kwargs['BrowseFlag']
                kwargs['SearchCriteria'] = ''
                return 'Search', kwargs

            #mediaserver.client.overlay_actions = {'Browse':my_browse}
            mediaserver.client.overlay_headers = {
                'user-agent': 'Xbox/Coherence emulation'
            }

            call = mediaserver.client.content_directory.browse(
                object_id='4', process_result=False)
            call.addCallback(got_first_answer)
            call.addErrback(lambda x: d.errback(None))

        self.coherence.ctrl.add_query(
            DeviceQuery('uuid',
                        str(self.uuid),
                        the_result,
                        timeout=10,
                        oneshot=True))
        return d

    def test_XBOX_Browse_Metadata(self):
        """ tries to find the activated FSStore backend
            and requests metadata for ObjectID 0.
        """
        d = Deferred()

        def the_result(mediaserver):
            try:
                self.assertEqual(str(self.uuid), mediaserver.udn)
            except:
                d.errback()

            def got_first_answer(r):
                """ we expect one item here """
                try:
                    self.assertEqual(int(r['TotalMatches']), 1)
                except:
                    d.errback()
                    return
                didl = DIDLLite.DIDLElement.fromString(r['Result'])
                item = didl.getItems()[0]
                try:
                    self.assertEqual(item.title, 'root')
                except:
                    d.errback()
                    return
                d.callback(None)

            mediaserver.client.overlay_headers = {
                'user-agent': 'Xbox/Coherence emulation'
            }

            call = mediaserver.client.content_directory.browse(
                object_id='0',
                browse_flag='BrowseMetadata',
                process_result=False)
            call.addCallback(got_first_answer)
            call.addErrback(lambda x: d.errback(None))

        self.coherence.ctrl.add_query(
            DeviceQuery('uuid',
                        str(self.uuid),
                        the_result,
                        timeout=10,
                        oneshot=True))
        return d

    def test_XBOX_Search(self):
        """ tries to find the activated FSStore backend
            and searches for all its audio files.
        """
        d = Deferred()

        def the_result(mediaserver):
            try:
                self.assertEqual(str(self.uuid), mediaserver.udn)
            except:
                d.errback()

            def got_first_answer(r):
                """ we expect four audio files here """
                try:
                    self.assertEqual(len(r), 4)
                except:
                    d.errback()
                d.callback(None)

            mediaserver.client.overlay_headers = {
                'user-agent': 'Xbox/Coherence emulation'
            }

            call = mediaserver.client.content_directory.search(
                container_id='4', criteria='')
            call.addCallback(got_first_answer)
            call.addErrback(lambda x: d.errback(None))

        self.coherence.ctrl.add_query(
            DeviceQuery('uuid',
                        str(self.uuid),
                        the_result,
                        timeout=10,
                        oneshot=True))
        return d
class TestContentDirectoryServer(unittest.TestCase):

    def setUp(self):
        self.tmp_content = FilePath('tmp_content_coherence-%d'%os.getpid())
        f = self.tmp_content.get_child()('content')
        audio = f.get_child()('audio')
        f.get_child()('images').makedirs()
        f.get_child()('video').makedirs()
        album = audio.get_child()('album-1')
        album.makedirs()
        album.get_child()('track-1.mp3').touch()
        album.get_child()('track-2.mp3').touch()
        album = audio.get_child()('album-2')
        album.makedirs()
        album.get_child()('track-1.ogg').touch()
        album.get_child()('track-2.ogg').touch()
        louie.reset()
        self.coherence = Coherence({'unittest':'yes','logmode':'debug','subsystem_log':{'controlpoint':'error',
                                                                                        'action':'error',
                                                                                        'soap':'error'},'controlpoint':'yes'})
        self.uuid = UUID()
        p = self.coherence.add_plugin('FSStore',
                                      name='MediaServer-%d'%os.getpid(),
                                      content=self.tmp_content.path,
                                      uuid=str(self.uuid))

    def tearDown(self):
        self.tmp_content.remove()

        def cleaner(r):
            self.coherence.clear()
            return r

        dl = self.coherence.shutdown()
        dl.addBoth(cleaner)
        return dl

    def test_Browse(self):
        """ tries to find the activated FSStore backend
            and browses its root.
        """
        d = Deferred()

        def the_result(mediaserver):
            try:
                self.assertEqual(str(self.uuid), mediaserver.udn)
            except:
                d.errback()

            def got_second_answer(r,childcount):
                try:
                    self.assertEqual(int(r['TotalMatches']), childcount)
                    d.callback(None)
                except:
                    d.errback()

            def got_first_answer(r):
                try:
                    self.assertEqual(int(r['TotalMatches']), 1)
                except:
                    d.errback()

                didl = DIDLLite.DIDLElement.fromString(r['Result'])
                item = didl.getItems()[0]
                try:
                    self.assertEqual(item.childCount, 3)
                except:
                    d.errback()

                call = mediaserver.client.content_directory.browse(object_id=item.id,
                                                         process_result=False)
                call.addCallback(got_second_answer,item.childCount)
                return call

            call = mediaserver.client.content_directory.browse(process_result=False)
            call.addCallback(got_first_answer)

        self.coherence.ctrl.add_query(DeviceQuery('uuid', str(self.uuid), the_result, timeout=10, oneshot=True))
        return d

    def test_Browse_Metadata(self):
        """ tries to find the activated FSStore backend
            and requests metadata for ObjectID 0.
        """
        d = Deferred()

        def the_result(mediaserver):
            try:
                self.assertEqual(str(self.uuid), mediaserver.udn)
            except:
                d.errback()

            def got_first_answer(r):
                try:
                    self.assertEqual(int(r['TotalMatches']), 1)
                except:
                    d.errback()
                    return
                didl = DIDLLite.DIDLElement.fromString(r['Result'])
                item = didl.getItems()[0]
                try:
                    self.assertEqual(item.title, 'root')
                except:
                    d.errback()
                    return
                d.callback(None)

            call = mediaserver.client.content_directory.browse(object_id='0',browse_flag='BrowseMetadata',process_result=False)
            call.addCallback(got_first_answer)
            call.addErrback(lambda x: d.errback(None))

        self.coherence.ctrl.add_query(DeviceQuery('uuid', str(self.uuid), the_result, timeout=10, oneshot=True))
        return d

    def test_XBOX_Browse(self):
        """ tries to find the activated FSStore backend
            and browses all audio files.
        """
        d = Deferred()

        def the_result(mediaserver):
            try:
                self.assertEqual(str(self.uuid), mediaserver.udn)
            except:
                d.errback()

            def got_first_answer(r):
                """ we expect four audio files here """
                try:
                    self.assertEqual(int(r['TotalMatches']), 4)
                except:
                    d.errback()
                    return
                d.callback(None)

            def my_browse(*args,**kwargs):
                kwargs['ContainerID'] = kwargs['ObjectID']
                del kwargs['ObjectID']
                del kwargs['BrowseFlag']
                kwargs['SearchCriteria'] = ''
                return 'Search',kwargs

            #mediaserver.client.overlay_actions = {'Browse':my_browse}
            mediaserver.client.overlay_headers = {'user-agent':'Xbox/Coherence emulation'}

            call = mediaserver.client.content_directory.browse(object_id='4',process_result=False)
            call.addCallback(got_first_answer)
            call.addErrback(lambda x: d.errback(None))

        self.coherence.ctrl.add_query(DeviceQuery('uuid', str(self.uuid), the_result, timeout=10, oneshot=True))
        return d

    def test_XBOX_Browse_Metadata(self):
        """ tries to find the activated FSStore backend
            and requests metadata for ObjectID 0.
        """
        d = Deferred()

        def the_result(mediaserver):
            try:
                self.assertEqual(str(self.uuid), mediaserver.udn)
            except:
                d.errback()

            def got_first_answer(r):
                """ we expect one item here """
                try:
                    self.assertEqual(int(r['TotalMatches']), 1)
                except:
                    d.errback()
                    return
                didl = DIDLLite.DIDLElement.fromString(r['Result'])
                item = didl.getItems()[0]
                try:
                    self.assertEqual(item.title, 'root')
                except:
                    d.errback()
                    return
                d.callback(None)

            mediaserver.client.overlay_headers = {'user-agent':'Xbox/Coherence emulation'}

            call = mediaserver.client.content_directory.browse(object_id='0',browse_flag='BrowseMetadata',process_result=False)
            call.addCallback(got_first_answer)
            call.addErrback(lambda x: d.errback(None))

        self.coherence.ctrl.add_query(DeviceQuery('uuid', str(self.uuid), the_result, timeout=10, oneshot=True))
        return d

    def test_XBOX_Search(self):
        """ tries to find the activated FSStore backend
            and searches for all its audio files.
        """
        d = Deferred()

        def the_result(mediaserver):
            try:
                self.assertEqual(str(self.uuid), mediaserver.udn)
            except:
                d.errback()

            def got_first_answer(r):
                """ we expect four audio files here """
                try:
                    self.assertEqual(len(r), 4)
                except:
                    d.errback()
                d.callback(None)

            mediaserver.client.overlay_headers = {'user-agent':'Xbox/Coherence emulation'}

            call = mediaserver.client.content_directory.search(container_id='4',
                                                               criteria='')
            call.addCallback(got_first_answer)
            call.addErrback(lambda x: d.errback(None))

        self.coherence.ctrl.add_query(DeviceQuery('uuid', str(self.uuid), the_result, timeout=10, oneshot=True))
        return d
Exemplo n.º 10
0
class TestDBUS(unittest.TestCase):
    if not dbus:
        skip = "Python dbus-bindings not available."
    elif gireactor is None:
        skip = "Python dbus-bindings not available, we need" \
               "a twisted.internet.gireactor.GIReactor"

    def setUp(self):
        self.coherence = Coherence({
            'unittest': 'yes',
            'logmode': 'error',
            'use_dbus': 'yes',
            'controlpoint': 'yes'
        })
        self.bus = dbus.SessionBus()
        self.coherence_service = self.bus.get_object(BUS_NAME, OBJECT_PATH)
        self.uuid = str(uuid.UUID())

    def tearDown(self):
        def cleaner(r):
            self.coherence.clear()
            if "twisted.internet.reactor" in sys.modules:
                del sys.modules["twisted.internet.reactor"]
            return r

        dl = self.coherence.shutdown()
        dl.addBoth(cleaner)
        return dl

    @get_the_gireactor
    def test_dbus_version(self):
        """ tests the version number request via dbus
        """

        d = Deferred()

        @wrapped(d)
        def handle_version_reply(version):
            self.assertEqual(version, __version__)
            d.callback(version)

        self.coherence_service.version(dbus_interface=BUS_NAME,
                                       reply_handler=handle_version_reply,
                                       error_handler=d.errback)
        return d

    @get_the_gireactor
    def test_dbus_plugin_add_and_remove(self):
        """ tests creation and removal of a backend via dbus
        """

        d = Deferred()

        @wrapped(d)
        def add_it(uuid):
            self.coherence_service.add_plugin(
                'YouTubeStore', {
                    'name': 'dbus-test-youtube-%d' % os.getpid(),
                    'uuid': uuid
                },
                dbus_interface=BUS_NAME,
                reply_handler=handle_add_plugin_reply,
                error_handler=d.errback)

        @wrapped(d)
        def handle_add_plugin_reply(uuid):
            self.assertEqual(self.uuid, uuid)
            reactor.callLater(2, remove_it, uuid)

        @wrapped(d)
        def remove_it(uuid):
            self.coherence_service.remove_plugin(
                uuid,
                dbus_interface=BUS_NAME,
                reply_handler=handle_remove_plugin_reply,
                error_handler=d.errback)

        @wrapped(d)
        def handle_remove_plugin_reply(uuid):
            self.assertEqual(self.uuid, uuid)
            d.callback(uuid)

        add_it(self.uuid)
        return d
Exemplo n.º 11
0
class ManagedControlPoint(object):
	DEVICE_TYPE_SATIP_SERVER = "SatIPServer"
	DEVICE_TYPE_DREAMBOX = "Dreambox"
	URI_BASE_DREAMBOX = "urn:dreambox-de:device"

	def __init__(self):
		self.coherence = None
		self._controlPoint = None
		self.__mediaServerClients = {}
		self.__mediaRendererClients = {}
		self.__mediaDevices = {}
		self.__devices = []
		self.onMediaServerDetected = []
		self.onMediaServerRemoved  = []
		self.onMediaRendererDetected = []
		self.onMediaRendererRemoved = []
		self.onMediaDeviceDectected = []
		self.onMediaDeviceRemoved = []
		self.onSatIpServerDetected = []
		self.onSatIpServerRemoved = []
		self.onDreamboxDetected = []
		self.onDreamboxRemoved = []
		self._session = None
		self.__deferredShutDown = None
		self._startPending = False

	def _onShutdownFinished(self, *args, **kwargs):
		self.__deferredShutDown = None
		if self._startPending:
			self.start()

	def start(self):
		def doStart(*args, **kwargs):
			if self._controlPoint:
				Log.w("already running!")
				return
			Log.i("starting now!")
			self._startPending = False
			self.coherence = Coherence({
				'logging': {
					'level' : 'warning', 
					'subsystem' : [
						{'name' : 'msearch', 'level' : 'warning'},
						{'name' : 'ssdp', 'level' : 'warning'}
					]}
				})
			self._controlPoint = ControlPoint(self.coherence, auto_client=['MediaServer','MediaRenderer'])
			self.coherence.ctrl = self._controlPoint
			self.__mediaServerClients = {}
			self.__mediaRendererClients = {}
			self.__mediaDevices = {}
			self.__devices = []
			self._controlPoint.connect(self._onMediaServerDetected, 'Coherence.UPnP.ControlPoint.MediaServer.detected')
			self._controlPoint.connect(self._onMediaServerRemoved, 'Coherence.UPnP.ControlPoint.MediaServer.removed')
			self._controlPoint.connect(self._onMediaRendererDetected, 'Coherence.UPnP.ControlPoint.MediaRenderer.detected')
			self._controlPoint.connect(self._onMediaRendererRemoved, 'Coherence.UPnP.ControlPoint.MediaRenderer.removed')
			self._controlPoint.connect(self._onMediaDeviceDectected, 'Coherence.UPnP.Device.detection_completed')
			self._controlPoint.connect(self._onMediaDeviceRemoved, 'Coherence.UPnP.RootDevice.removed')
			self.__deferredShutDown = None
			if self._session:
				self._callPlugins(reason=0)
		if self.__deferredShutDown:
			Log.w("deferring start until shutdown is finished")
			if not self._startPending:
				self._startPending = True
		else:
			doStart()

	def restart(self):
		Log.i()
		if not self.__deferredShutDown:
			self.shutdown()
		self.start()

	def setSession(self, session):
		self._session = session
		if self.coherence:
			self._callPlugins(reason=0)

	def _callPlugins(self, reason=0):
		for plugin in plugins.getPlugins(PluginDescriptor.WHERE_UPNP):
			plugin(reason, session=self._session)

	def _onMediaServerDetected(self, client, udn):
		print "[DLNA] MediaServer Detected: %s (%s)" % (client.device.get_friendly_name(), client.device.get_friendly_device_type())
		self.__mediaServerClients[udn] = client
		for fnc in self.onMediaServerDetected:
			fnc(udn, client)

	def _onMediaServerRemoved(self, udn):
		if self.__mediaServerClients.get(udn, None) != None:
			del self.__mediaServerClients[udn]
			for fnc in self.onMediaServerRemoved:
				fnc(udn)

	def _onMediaRendererDetected(self, client, udn):
		print "[DLNA] MediaRenderer detected: %s (%s, %s)" % (client.device.get_friendly_name(), client.device.get_friendly_device_type(), udn)
		self.__mediaRendererClients[udn] = client
		for fnc in self.onMediaRendererDetected:
			fnc(udn, client)

	def _onMediaRendererRemoved(self, udn):
		print "[DLNA] MediaRenderer removed: %s" % (udn)
		if self.__mediaRendererClients.get(udn, None) != None:
			del self.__mediaRendererClients[udn]
			for fnc in self.onMediaRendererRemoved:
				fnc(udn)

	def _onMediaDeviceDectected(self, device):
		if device.udn in self.__mediaDevices:
			return
		self.__mediaDevices[device.udn] = device
		device_type = device.get_friendly_device_type()
		if device_type == self.DEVICE_TYPE_SATIP_SERVER:
			Log.i("New SAT>IP Server found: %s (%s - %s)" %(device.get_friendly_name(), device.get_friendly_device_type(), device.get_satipcap()))
			for fnc in self.onSatIpServerDetected:
				fnc(device)
		elif device_type == self.DEVICE_TYPE_DREAMBOX:
			Log.i("New Dreambox found: %s (%s - %s)" %(device.get_friendly_name(), device.get_friendly_device_type(), device.get_presentation_url()))
			for fnc in self.onDreamboxDetected:
				fnc(device)
		else:
			Log.i("New Device found: %s (%s)" % (device.get_friendly_name(), device.get_friendly_device_type()))

	def _onMediaDeviceRemoved(self, usn):
		if usn in self.__mediaDevices:
			print "[DLNA] Device removed: %s" % (usn)
			device = self.__mediaDevices[usn]
			device_type = device.get_friendly_device_type()
			if device_type == self.DEVICE_TYPE_SATIP_SERVER:
				for fnc in self.onSatIpServerRemoved:
					fnc(device)
			elif device_type == self.DEVICE_TYPE_DREAMBOX:
				for fnc in self.onDreamboxRemoved:
					fnc(device)
			for fnc in self.onMediaDeviceRemoved:
				fnc(device)
			del self.__mediaDevices[usn]

	def registerRenderer(self, classDef, **kwargs):
		renderer = MediaRenderer(self.coherence, classDef, no_thread_needed=True, **kwargs)
		self.__devices.append(renderer)
		return renderer

	def registerServer(self, classDef, **kwargs):
		server = MediaServer(self.coherence, classDef, no_thread_needed=True, **kwargs)
		self.__devices.append(server)
		return server

	def registerDevice(self, instance, **kwargs):
		self.__devices.append(instance)
		return instance

	def getServerList(self):
		return self.__mediaServerClients.values()

	def getRenderingControlClientList(self):
		return self.__mediaRendererClients.values()

	def getDeviceName(self, client):
		return Item.ue(client.device.get_friendly_name())

	def getSatIPDevices(self):
		devices = []
		for device in self.__mediaDevices.itervalues():
			if device.get_friendly_device_type() == self.DEVICE_TYPE_SATIP_SERVER:
				devices.append(device)
		return devices

	def getDreamboxes(self):
		devices = []
		for device in self.__mediaDevices.itervalues():
			if device.get_friendly_device_type() == self.DEVICE_TYPE_DREAMBOX:
				devices.append(device)
		return devices

	def getDevice(self, uuid):
		for device in self.__devices:
			if device.uuid == uuid:
				return device
		return None

	def removeDevice(self, uuid):
		device = self.getDevice(uuid)
		if device:
			device.unregister()
			self.__devices.remove(device)
			return True
		return False

	def shutdown(self):
		Log.i("%s" %(self.coherence,))
		if True:
			Log.w("shutdown is broken... will continue running. please restart enigma2 instead!")
			return
		if self.coherence:
			self._callPlugins(reason=1)
			self.__mediaServerClients = {}
			self.__mediaRendererClients = {}
			self.__mediaDevices = {}
			self.__devices = []
			self.__deferredShutDown = self.coherence.shutdown(force=True)
			self.__deferredShutDown.addCallback(self._onShutdownFinished)
			self._controlPoint.disconnect(self._onMediaServerDetected, 'Coherence.UPnP.ControlPoint.MediaServer.detected')
			self._controlPoint.disconnect(self._onMediaServerRemoved, 'Coherence.UPnP.ControlPoint.MediaServer.removed')
			self._controlPoint.disconnect(self._onMediaRendererDetected, 'Coherence.UPnP.ControlPoint.MediaRenderer.detected')
			self._controlPoint.disconnect(self._onMediaRendererRemoved, 'Coherence.UPnP.ControlPoint.MediaRenderer.removed')
			self._controlPoint.disconnect(self._onMediaDeviceDectected, 'Coherence.UPnP.Device.detection_completed')
			self._controlPoint.disconnect(self._onMediaDeviceRemoved, 'Coherence.UPnP.RootDevice.removed')
			self.coherence = None
			self._controlPoint = None
Exemplo n.º 12
0
class MirabeauController(object):
    coherence_started_cb = lambda: None

    def start(self):
        # TODO: select correct window class depending on platform
        main_window = MainWindow(self)
        main_window.show_all()

    def load_config(self):
        self.first_run = False
        if not os.path.exists(BASEDIR):
            os.makedirs(BASEDIR)
        if not os.path.exists(CONFIG_PATH):
            self.first_run = True

            default_account = ''
            vars = locals()
            vars["MR_UUID"] = MR_UUID
            cfg = DEFAULT_CONFIG % vars
            fd = open(CONFIG_PATH, "w")
            fd.write(cfg)
            fd.close()

        self.config = Config(CONFIG_PATH, root='config', element2attr_mappings={'active':'active'})

    def reload_config(self):
        self.config.save()
        self.load_config()

    def enable_mirabeau(self):
        self.config.set("enable_mirabeau", "yes")
        self.reload_config()

    def disable_mirabeau(self):
        self.config.set("enable_mirabeau", "no")
        self.reload_config()

    def platform_media_directories(self):
        candidates = ["~/MyDocs/.images", "~/MyDocs/.sounds", "~/MyDocs/.videos",
                      "~/MyDocs/DCIM", "~/MyDocs/Music", "~/MyDocs/Videos",
                      ]
        expanded = [os.path.expanduser(c) for c in candidates]
        dirs = [c for c in expanded if os.path.isdir(c)]
        return dirs

    def enable_media_server(self, nickname=None):
        nickname = nickname or "N900"
        name_template = _("%(nickname)s Media Files")

        def generate_cfg(nickname):
            directories = self.platform_media_directories()
            name = name_template % locals()
            opts = dict(uuid=MS_UUID, name=name, content=",".join(directories),
                        backend="FSStore", active="yes")
            return XmlDictObject(initdict=opts)

        plugins = self.config.get("plugin")
        if not plugins:
            self.config.set("plugin", generate_cfg())
        else:
            if isinstance(plugins, XmlDictObject):
                plugins = [plugins,]
            already_in_config = False
            for plugin in plugins:
                if plugin.get("uuid") == MS_UUID:
                    plugin.active = "yes"
                    plugin.name = name_template % locals()
                    already_in_config = True
                    break
            if not already_in_config:
                plugins.append(generate_cfg(nickname))
            self.config.set("plugin", plugins)
        self.reload_config()

    def disable_media_server(self):
        plugins = self.config.get("plugin")
        if plugins:
            if isinstance(plugins, XmlDictObject):
                plugins = [plugins,]
            for plugin in plugins:
                if plugin.get("uuid") == MS_UUID:
                    plugin.active = "no"
                    break
            self.config.set("plugin", plugins)
            self.reload_config()

    def media_server_enabled(self):
        plugins = self.config.get("plugin")
        if plugins:
            if isinstance(plugins, XmlDictObject):
                plugins = [plugins,]
            for plugin in plugins:
                if plugin.get("uuid") == MS_UUID and \
                   plugin.active == "yes":
                    return True
        return False

    def set_media_renderer_name(self, nickname=None):
        nickname = nickname or "N900"
        name_template = _("%(nickname)s Media Renderer")
        plugins = self.config.get("plugin")
        if plugins:
            if isinstance(plugins, XmlDictObject):
                plugins = [plugins,]
            for plugin in plugins:
                if plugin.get("uuid") == MR_UUID:
                    plugin.name = name_template % locals()
                    break
            self.config.set("plugin", plugins)
            self.reload_config()

    def start_coherence(self, restart=False):
        def start():
            if self.config.get("mirabeau").get("account"):
                self.enable_mirabeau()
            else:
                self.disable_mirabeau()
            self.coherence_instance = Coherence(self.config.config)

        if restart:
            if self.coherence_instance:
                dfr = self.stop_coherence()
                dfr.addCallback(lambda result: start())
                return dfr
            else:
               start()
        else:
            start()
        if self.coherence_instance:
            self.coherence_started_cb()

    def stop_coherence(self):
        def stopped(result):
            if self.coherence_instance:
                self.coherence_instance.clear()
                self.coherence_instance = None

        dfr = self.coherence_instance.shutdown(force=True)
        dfr.addBoth(stopped)
        return dfr

    def toggle_coherence(self):
        if self.coherence_instance:
            self.stop_coherence()
        else:
            self.start_coherence()

    def update_settings(self, chatroom, conf_server, account, account_nickname,
                        media_server_enabled):
        mirabeau_section = self.config.get("mirabeau")
        mirabeau_section.set("chatroom", chatroom)
        mirabeau_section.set("conference-server", conf_server)
        mirabeau_section.set("account", account)
        self.config.set("mirabeau", mirabeau_section)
        self.reload_config()

        nickname = account_nickname
        self.set_media_renderer_name(nickname)
        if media_server_enabled:
            self.enable_media_server(nickname=nickname)
        else:
            self.disable_media_server()
        self.start_coherence(restart=True)
Exemplo n.º 13
0
class TestDBUS(unittest.TestCase):

    def setUp(self):
        louie.reset()
        self.coherence = Coherence({'unittest':'yes','logmode':'error','use_dbus':'yes','controlpoint':'yes'})
        self.bus = dbus.SessionBus()
        self.coherence_service = self.bus.get_object(BUS_NAME,OBJECT_PATH)
        self.uuid = UUID()

    def tearDown(self):

        def cleaner(r):
            self.coherence.clear()
            return r

        dl = self.coherence.shutdown()
        dl.addBoth(cleaner)
        return dl

    def test_dbus_version(self):
        """ tests the version number request via dbus
        """
        d = Deferred()

        def handle_version_reply(version):
            self.assertEqual(version,__version__)
            d.callback(version)

        def handle_error(err):
            d.errback(err)

        self.coherence_service.version(dbus_interface=BUS_NAME,
                                       reply_handler=handle_version_reply,
                                       error_handler=handle_error)
        return d

    def test_dbus_plugin_add_and_remove(self):
        """ tests creation and removal of a backend via dbus
        """
        d = Deferred()

        def handle_error(err):
            d.errback(err)

        def handle_add_plugin_reply(uuid):
            uuid = str(uuid)
            self.assertEqual(str(self.uuid),uuid)

            def remove_it(uuid):

                def handle_remove_plugin_reply(uuid):
                    self.assertEqual(str(self.uuid),uuid)
                    d.callback(uuid)

                self.coherence_service.remove_plugin(uuid,
                                            dbus_interface=BUS_NAME,
                                            reply_handler=handle_remove_plugin_reply,
                                            error_handler=handle_error)

            reactor.callLater(2,remove_it,uuid)

        self.coherence_service.add_plugin('SimpleLight',{'name':'dbus-test-light-%d'%os.getpid(),'uuid':str(self.uuid)},
                                          dbus_interface=BUS_NAME,
                                          reply_handler=handle_add_plugin_reply,
                                          error_handler=handle_error)
        return d
Exemplo n.º 14
0
class TestContentDirectoryServer(unittest.TestCase):

    def setUp(self):
        self.tmp_content = FilePath(self.mktemp())
        f = self.tmp_content.child('content')
        audio = f.child('audio')
        f.child('images').makedirs()
        f.child('video').makedirs()
        album = audio.child('album-1')
        album.makedirs()
        album.child('track-1.mp3').touch()
        album.child('track-2.mp3').touch()
        album = audio.child('album-2')
        album.makedirs()
        album.child('track-1.ogg').touch()
        album.child('track-2.ogg').touch()
        louie.reset()
        self.coherence = Coherence(
          {'unittest': 'yes',
           'logmode': 'critical',
           'no-subsystem_log': {'controlpoint': 'error',
                                'action': 'info',
                                'soap': 'error'},
           'controlpoint': 'yes'})
        self.uuid = str(UUID())
        self.coherence.add_plugin('FSStore',
                                  name='MediaServer-%d' % os.getpid(),
                                  content=self.tmp_content.path,
                                  uuid=self.uuid,
                                  enable_inotify=False)

    def tearDown(self):
        self.tmp_content.remove()

        def cleaner(r):
            self.coherence.clear()
            return r

        dl = self.coherence.shutdown()
        dl.addBoth(cleaner)
        return dl

    def test_Browse(self):
        """ tries to find the activated FSStore backend
            and browses its root.
        """
        d = Deferred()

        @wrapped(d)
        def the_result(mediaserver):
            cdc = mediaserver.client.content_directory
            self.assertEqual(self.uuid, mediaserver.udn)
            call = cdc.browse(process_result=False)
            call.addCallback(got_first_answer, cdc)

        @wrapped(d)
        def got_first_answer(r, cdc):
            self.assertEqual(int(r['TotalMatches']), 1)
            didl = DIDLLite.DIDLElement.fromString(r['Result'])
            item = didl.getItems()[0]
            self.assertEqual(item.childCount, 3)
            call = cdc.browse(object_id=item.id, process_result=False)
            call.addCallback(got_second_answer, item.childCount)

        @wrapped(d)
        def got_second_answer(r, childcount):
            self.assertEqual(int(r['TotalMatches']), childcount)
            d.callback(None)

        self.coherence.ctrl.add_query(
            DeviceQuery('uuid', self.uuid,
                        the_result, timeout=10, oneshot=True))
        return d

    def test_Browse_Non_Existing_Object(self):

        d = Deferred()

        @wrapped(d)
        def the_result(mediaserver):
            cdc = mediaserver.client.content_directory
            self.assertEqual(self.uuid, mediaserver.udn)
            call = cdc.browse(object_id='9999.nothing', process_result=False)
            call.addCallback(got_first_answer)

        @wrapped(d)
        def got_first_answer(r):
            self.assertIs(r, None)
            d.callback(None)

        self.coherence.ctrl.add_query(
            DeviceQuery('uuid', self.uuid, the_result,
                        timeout=10, oneshot=True))
        return d

    def test_Browse_Metadata(self):
        """ tries to find the activated FSStore backend
            and requests metadata for ObjectID 0.
        """
        d = Deferred()

        @wrapped(d)
        def the_result(mediaserver):
            self.assertEqual(self.uuid, mediaserver.udn)
            cdc = mediaserver.client.content_directory
            call = cdc.browse(object_id='0', browse_flag='BrowseMetadata',
                              process_result=False)
            call.addCallback(got_first_answer)

        @wrapped(d)
        def got_first_answer(r):
            self.assertEqual(int(r['TotalMatches']), 1)
            didl = DIDLLite.DIDLElement.fromString(r['Result'])
            item = didl.getItems()[0]
            self.assertEqual(item.title, 'root')
            d.callback(None)

        self.coherence.ctrl.add_query(
            DeviceQuery('uuid', self.uuid,
                        the_result, timeout=10, oneshot=True))
        return d

    def test_XBOX_Browse(self):
        """ tries to find the activated FSStore backend
            and browses all audio files.
        """
        d = Deferred()

        @wrapped(d)
        def the_result(mediaserver):
            mediaserver.client.overlay_headers = {'user-agent': 'Xbox/Coherence emulation'}
            cdc = mediaserver.client.content_directory
            self.assertEqual(self.uuid, mediaserver.udn)
            call = cdc.browse(object_id='4', process_result=False)
            call.addCallback(got_first_answer)

        @wrapped(d)
        def got_first_answer(r):
            """ we expect four audio files here """
            self.assertEqual(int(r['TotalMatches']), 4)
            d.callback(None)

        d = Deferred()
        self.coherence.ctrl.add_query(
            DeviceQuery('uuid', self.uuid, the_result,
                        timeout=10, oneshot=True))
        return d

    def test_XBOX_Browse_Metadata(self):
        """ tries to find the activated FSStore backend
            and requests metadata for ObjectID 0.
        """
        d = Deferred()

        @wrapped(d)
        def the_result(mediaserver):
            mediaserver.client.overlay_headers = {
                'user-agent': 'Xbox/Coherence emulation'}
            cdc = mediaserver.client.content_directory
            self.assertEqual(self.uuid, mediaserver.udn)
            call = cdc.browse(object_id='0', browse_flag='BrowseMetadata',
                              process_result=False)
            call.addCallback(got_first_answer)

        @wrapped(d)
        def got_first_answer(r):
            """ we expect one item here """
            self.assertEqual(int(r['TotalMatches']), 1)
            didl = DIDLLite.DIDLElement.fromString(r['Result'])
            item = didl.getItems()[0]
            self.assertEqual(item.title, 'root')
            d.callback(None)

        self.coherence.ctrl.add_query(
            DeviceQuery('uuid', self.uuid, the_result,
                        timeout=10, oneshot=True))
        return d

    def test_XBOX_Search(self):
        """ tries to find the activated FSStore backend
            and searches for all its audio files.
        """

        d = Deferred()

        @wrapped(d)
        def the_result(mediaserver):
            mediaserver.client.overlay_headers = {
                'user-agent': 'Xbox/Coherence emulation'}
            cdc = mediaserver.client.content_directory
            self.assertEqual(self.uuid, mediaserver.udn)
            call = cdc.search(container_id='4', criteria='')
            call.addCallback(got_first_answer)

        @wrapped(d)
        def got_first_answer(r):
            """ we expect four audio files here """
            self.assertEqual(len(r), 4)
            d.callback(None)

        self.coherence.ctrl.add_query(
            DeviceQuery('uuid', self.uuid, the_result,
                        timeout=10, oneshot=True))
        return d
Exemplo n.º 15
0
class ManagedControlPoint(object):
    DEVICE_TYPE_SATIP_SERVER = "SatIPServer"
    DEVICE_TYPE_DREAMBOX = "Dreambox"
    URI_BASE_DREAMBOX = "urn:dreambox-de:device"

    def __init__(self):
        self.coherence = None
        self._controlPoint = None
        self.__mediaServerClients = {}
        self.__mediaRendererClients = {}
        self.__mediaDevices = {}
        self.__devices = []
        self.onMediaServerDetected = []
        self.onMediaServerRemoved = []
        self.onMediaRendererDetected = []
        self.onMediaRendererRemoved = []
        self.onMediaDeviceDectected = []
        self.onMediaDeviceRemoved = []
        self.onSatIpServerDetected = []
        self.onSatIpServerRemoved = []
        self.onDreamboxDetected = []
        self.onDreamboxRemoved = []
        self._session = None
        self.__deferredShutDown = None
        self._startPending = False

    def _onShutdownFinished(self, *args, **kwargs):
        self.__deferredShutDown = None
        if self._startPending:
            self.start()

    def start(self):
        def doStart(*args, **kwargs):
            if self._controlPoint:
                Log.w("already running!")
                return
            Log.i("starting now!")
            self._startPending = False
            self.coherence = Coherence({
                'logging': {
                    'level':
                    'warning',
                    'subsystem': [{
                        'name': 'msearch',
                        'level': 'warning'
                    }, {
                        'name': 'ssdp',
                        'level': 'warning'
                    }]
                }
            })
            self._controlPoint = ControlPoint(
                self.coherence, auto_client=['MediaServer', 'MediaRenderer'])
            self.coherence.ctrl = self._controlPoint
            self.__mediaServerClients = {}
            self.__mediaRendererClients = {}
            self.__mediaDevices = {}
            self.__devices = []
            self._controlPoint.connect(
                self._onMediaServerDetected,
                'Coherence.UPnP.ControlPoint.MediaServer.detected')
            self._controlPoint.connect(
                self._onMediaServerRemoved,
                'Coherence.UPnP.ControlPoint.MediaServer.removed')
            self._controlPoint.connect(
                self._onMediaRendererDetected,
                'Coherence.UPnP.ControlPoint.MediaRenderer.detected')
            self._controlPoint.connect(
                self._onMediaRendererRemoved,
                'Coherence.UPnP.ControlPoint.MediaRenderer.removed')
            self._controlPoint.connect(
                self._onMediaDeviceDectected,
                'Coherence.UPnP.Device.detection_completed')
            self._controlPoint.connect(self._onMediaDeviceRemoved,
                                       'Coherence.UPnP.RootDevice.removed')
            self.__deferredShutDown = None
            if self._session:
                self._callPlugins(reason=0)

        if self.__deferredShutDown:
            Log.w("deferring start until shutdown is finished")
            if not self._startPending:
                self._startPending = True
        else:
            doStart()

    def restart(self):
        Log.i()
        if not self.__deferredShutDown:
            self.shutdown()
        self.start()

    def setSession(self, session):
        self._session = session
        if self.coherence:
            self._callPlugins(reason=0)

    def _callPlugins(self, reason=0):
        for plugin in plugins.getPlugins(PluginDescriptor.WHERE_UPNP):
            plugin(reason, session=self._session)

    def _onMediaServerDetected(self, client, udn):
        print "[DLNA] MediaServer Detected: %s (%s)" % (
            client.device.get_friendly_name(),
            client.device.get_friendly_device_type())
        self.__mediaServerClients[udn] = client
        for fnc in self.onMediaServerDetected:
            fnc(udn, client)

    def _onMediaServerRemoved(self, udn):
        if self.__mediaServerClients.get(udn, None) != None:
            del self.__mediaServerClients[udn]
            for fnc in self.onMediaServerRemoved:
                fnc(udn)

    def _onMediaRendererDetected(self, client, udn):
        print "[DLNA] MediaRenderer detected: %s (%s, %s)" % (
            client.device.get_friendly_name(),
            client.device.get_friendly_device_type(), udn)
        self.__mediaRendererClients[udn] = client
        for fnc in self.onMediaRendererDetected:
            fnc(udn, client)

    def _onMediaRendererRemoved(self, udn):
        print "[DLNA] MediaRenderer removed: %s" % (udn)
        if self.__mediaRendererClients.get(udn, None) != None:
            del self.__mediaRendererClients[udn]
            for fnc in self.onMediaRendererRemoved:
                fnc(udn)

    def _onMediaDeviceDectected(self, device):
        if device.udn in self.__mediaDevices:
            return
        self.__mediaDevices[device.udn] = device
        device_type = device.get_friendly_device_type()
        if device_type == self.DEVICE_TYPE_SATIP_SERVER:
            Log.i("New SAT>IP Server found: %s (%s - %s)" %
                  (device.get_friendly_name(),
                   device.get_friendly_device_type(), device.get_satipcap()))
            for fnc in self.onSatIpServerDetected:
                fnc(device)
        elif device_type == self.DEVICE_TYPE_DREAMBOX:
            Log.i(
                "New Dreambox found: %s (%s - %s)" %
                (device.get_friendly_name(), device.get_friendly_device_type(),
                 device.get_presentation_url()))
            for fnc in self.onDreamboxDetected:
                fnc(device)
        else:
            Log.i("New Device found: %s (%s)" %
                  (device.get_friendly_name(),
                   device.get_friendly_device_type()))

    def _onMediaDeviceRemoved(self, usn):
        if usn in self.__mediaDevices:
            print "[DLNA] Device removed: %s" % (usn)
            device = self.__mediaDevices[usn]
            device_type = device.get_friendly_device_type()
            if device_type == self.DEVICE_TYPE_SATIP_SERVER:
                for fnc in self.onSatIpServerRemoved:
                    fnc(device)
            elif device_type == self.DEVICE_TYPE_DREAMBOX:
                for fnc in self.onDreamboxRemoved:
                    fnc(device)
            for fnc in self.onMediaDeviceRemoved:
                fnc(device)
            del self.__mediaDevices[usn]

    def registerRenderer(self, classDef, **kwargs):
        renderer = MediaRenderer(self.coherence,
                                 classDef,
                                 no_thread_needed=True,
                                 **kwargs)
        self.__devices.append(renderer)
        return renderer

    def registerServer(self, classDef, **kwargs):
        server = MediaServer(self.coherence,
                             classDef,
                             no_thread_needed=True,
                             **kwargs)
        self.__devices.append(server)
        return server

    def registerDevice(self, instance, **kwargs):
        self.__devices.append(instance)
        return instance

    def getServerList(self):
        return self.__mediaServerClients.values()

    def getRenderingControlClientList(self):
        return self.__mediaRendererClients.values()

    def getDeviceName(self, client):
        return Item.ue(client.device.get_friendly_name())

    def getSatIPDevices(self):
        devices = []
        for device in self.__mediaDevices.itervalues():
            if device.get_friendly_device_type(
            ) == self.DEVICE_TYPE_SATIP_SERVER:
                devices.append(device)
        return devices

    def getDreamboxes(self):
        devices = []
        for device in self.__mediaDevices.itervalues():
            if device.get_friendly_device_type() == self.DEVICE_TYPE_DREAMBOX:
                devices.append(device)
        return devices

    def getDevice(self, uuid):
        for device in self.__devices:
            if device.uuid == uuid:
                return device
        return None

    def removeDevice(self, uuid):
        device = self.getDevice(uuid)
        if device:
            device.unregister()
            self.__devices.remove(device)
            return True
        return False

    def shutdown(self):
        Log.i("%s" % (self.coherence, ))
        if True:
            Log.w(
                "shutdown is broken... will continue running. please restart enigma2 instead!"
            )
            return
        if self.coherence:
            self._callPlugins(reason=1)
            self.__mediaServerClients = {}
            self.__mediaRendererClients = {}
            self.__mediaDevices = {}
            self.__devices = []
            self.__deferredShutDown = self.coherence.shutdown(force=True)
            self.__deferredShutDown.addCallback(self._onShutdownFinished)
            self._controlPoint.disconnect(
                self._onMediaServerDetected,
                'Coherence.UPnP.ControlPoint.MediaServer.detected')
            self._controlPoint.disconnect(
                self._onMediaServerRemoved,
                'Coherence.UPnP.ControlPoint.MediaServer.removed')
            self._controlPoint.disconnect(
                self._onMediaRendererDetected,
                'Coherence.UPnP.ControlPoint.MediaRenderer.detected')
            self._controlPoint.disconnect(
                self._onMediaRendererRemoved,
                'Coherence.UPnP.ControlPoint.MediaRenderer.removed')
            self._controlPoint.disconnect(
                self._onMediaDeviceDectected,
                'Coherence.UPnP.Device.detection_completed')
            self._controlPoint.disconnect(self._onMediaDeviceRemoved,
                                          'Coherence.UPnP.RootDevice.removed')
            self.coherence = None
            self._controlPoint = None
Exemplo n.º 16
0
class TestDBUS(unittest.TestCase):

    if not dbus:
        skip = "Python dbus-bindings not available."
    elif reactor.__class__.__name__ != 'Glib2Reactor':
        skip = ("This test needs a Glib2Reactor, please start trial "
                "with the '-r glib2' option.")

    def setUp(self):
        louie.reset()
        self.coherence = Coherence({'unittest': 'yes', 'logmode': 'error', 'use_dbus': 'yes', 'controlpoint': 'yes'})
        self.bus = dbus.SessionBus()
        self.coherence_service = self.bus.get_object(BUS_NAME, OBJECT_PATH)
        self.uuid = str(uuid.UUID())

    def tearDown(self):

        def cleaner(r):
            self.coherence.clear()
            return r

        dl = self.coherence.shutdown()
        dl.addBoth(cleaner)
        return dl

    def test_dbus_version(self):
        """ tests the version number request via dbus
        """

        d = Deferred()

        @wrapped(d)
        def handle_version_reply(version):
            self.assertEqual(version, __version__)
            d.callback(version)

        self.coherence_service.version(dbus_interface=BUS_NAME,
                                       reply_handler=handle_version_reply,
                                       error_handler=d.errback)
        return d

    def test_dbus_plugin_add_and_remove(self):
        """ tests creation and removal of a backend via dbus
        """

        d = Deferred()

        @wrapped(d)
        def add_it(uuid):
            self.coherence_service.add_plugin(
                'SimpleLight', {'name': 'dbus-test-light-%d' % os.getpid(), 'uuid': uuid},
                dbus_interface=BUS_NAME,
                reply_handler=handle_add_plugin_reply,
                error_handler=d.errback)

        @wrapped(d)
        def handle_add_plugin_reply(uuid):
            self.assertEqual(self.uuid, uuid)
            reactor.callLater(2, remove_it, uuid)

        @wrapped(d)
        def remove_it(uuid):
            self.coherence_service.remove_plugin(
                uuid,
                dbus_interface=BUS_NAME,
                reply_handler=handle_remove_plugin_reply,
                error_handler=d.errback)

        @wrapped(d)
        def handle_remove_plugin_reply(uuid):
            self.assertEqual(self.uuid, uuid)
            d.callback(uuid)

        add_it(self.uuid)
        return d