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()
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
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
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
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
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
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
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 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
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
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
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