def test_init(self): expected_channels = { "channel1": Channel("channel1"), "channel2": Channel("channel2") } dispatcher = Dispatcher(expected_channels) self.assertEqual(dispatcher.channels, expected_channels)
def play(item_to_play): channel_data = fetch_channel_data(fetch_local_channel_data, fetch_remote_channel_data) xml_data = ET.fromstring(channel_data) try: channel_data = xml_data.find(".//channel[@id='" + item_to_play + "']") channel = Channel(handle, tempdir, channel_data, quality_priority(), format_priority()) except: for element in xml_data.findall(".//channel"): channel = Channel(handle, tempdir, element, quality_priority(), format_priority()) if channel.getid() == item_to_play: break list_item = ListItem(channel.get_simple_element('title'), channel.get_simple_element('description'), channel.get_content_url()) list_item.setArt({ "icon": channel.geticon(), "thumb": channel.getthumbnail(), "fanart": xbmcvfs.translatePath("special://home/addons/%s/fanart.jpg" % __addonid__) }) xbmcplugin.setResolvedUrl(handle, True, list_item)
def test_add_client(self): # It adds the client and assigns a uuid address test_client = Client(websockets.protocol.WebSocketCommonProtocol()) channel = Channel("test-channel") channel.add_client(test_client) self.assertTrue(len(channel.clients) == 1) client = channel.clients.pop() self.assertEqual(client, test_client)
def build_directory(): channel_data = fetch_channel_data(fetch_cached_channel_data, fetch_remote_channel_data, fetch_local_channel_data) xml_data = ET.fromstring(channel_data) stations = xml_data.findall(".//channel") for station in stations: channel = Channel(handle, tempdir, station) li = xbmcgui.ListItem(channel.get_simple_element('title'), channel.get_simple_element('description'), channel.geticon(), channel.getthumbnail(), plugin_url + channel.getid()) li.setArt({ "fanart": xbmc.translatePath("special://home/addons/%s/fanart.jpg" % __addonid__) }) li.setProperty("IsPlayable", "true") for element, info in [('listeners', 'listeners'), ('genre', 'genre'), ('dj', 'artist'), ('description', 'comment'), ('title', 'title')]: value = channel.get_simple_element(element) li.setInfo("Music", {info: value}) xbmcplugin.addDirectoryItem(handle=handle, url=plugin_url + channel.getid(), listitem=li, totalItems=len(stations)) xbmcplugin.addSortMethod(handle, SORT_METHOD_UNSORTED) xbmcplugin.addSortMethod(handle, SORT_METHOD_LISTENERS) xbmcplugin.addSortMethod(handle, SORT_METHOD_GENRE)
def on_start(cmd: pcmd.Command, args: List[str]) -> None: """Callback for `start` - starts the channel""" global ch if ch.is_alive(): utils.printwrn('Already running ... ') return ch = Channel(ch.transf, ch.ist, ch.ost) try: ch.start() except IOError as e: utils.printerr(e)
def build_directory(): channel_data = fetch_channel_data(fetch_cached_channel_data, fetch_remote_channel_data, fetch_local_channel_data) xml_data = ET.fromstring(channel_data) stations = xml_data.findall(".//channel") for station in stations: channel = Channel(handle, tempdir, station) li = xbmcgui.ListItem( channel.get_simple_element('title'), channel.get_simple_element('description'), channel.geticon(), channel.getthumbnail(), plugin_url + channel.getid()) li.setArt({"fanart": xbmc.translatePath("special://home/addons/%s/fanart.jpg" % __addonid__)}) li.setProperty("IsPlayable", "true") for element, info in [('listeners', 'listeners'), ('genre', 'genre'), ('dj', 'artist'), ('description', 'comment'), ('title', 'title')]: value = channel.get_simple_element(element) li.setInfo("Music", {info: value}) xbmcplugin.addDirectoryItem( handle=handle, url=plugin_url + channel.getid(), listitem=li, totalItems=len(stations)) xbmcplugin.addSortMethod(handle, SORT_METHOD_UNSORTED) xbmcplugin.addSortMethod(handle, SORT_METHOD_LISTENERS) xbmcplugin.addSortMethod(handle, SORT_METHOD_GENRE)
def setUp(self): self.target_channel = Channel("target_channel") self.target_channel.broadcast = unittest.mock.AsyncMock() self.target_channel.send = unittest.mock.AsyncMock() self.another_channel = Channel("another_channel") self.channels = { self.target_channel.id: self.target_channel, self.another_channel.id: self.another_channel } self.sender_mock_socket = MockAsyncIterator(iter([])) self.sender = Client(self.sender_mock_socket) self.receiver_mock_socket = MockAsyncIterator(iter([])) self.receiver = Client(self.receiver_mock_socket) self.sample_message = Message(self.sender.address, self.receiver.address, self.target_channel.id, "")
def parse_channels(self): """Creates an array of Channel objects from the project""" channels = [] for channel in self._project_dict["channels"]: channels.append( Channel(channel, self._is_sixteen_bit, self._ignore_list)) return channels
def test_send(self, SenderMockWebSocket, ReceiverMockWebSocket): # Set up some clients sender = Client(SenderMockWebSocket) receiver = Client(ReceiverMockWebSocket) channel = Channel("test_channel") channel.add_client(sender) channel.add_client(receiver) self.assertTrue(len(channel.clients) == 2) # It sends a message to receiver sample_message = Message( receiver_guid = receiver.address, type = "announce", data = "data" ) asyncio.get_event_loop().run_until_complete( channel.send(sender, sample_message) ) # It called send ReceiverMockWebSocket.send.assert_called() # It sent the right message sent_message = Message.from_json(ReceiverMockWebSocket.send.call_args[0][0]) sent_data = sent_message.data sent_type = sent_message.type self.assertEqual(sent_data, sample_message.data) self.assertEqual(sent_type, sample_message.type) # It set the "sender_guid" sent_from = sent_message.sender_guid self.assertEqual(sent_from, sender.address)
async def send_sounds(ws: websockets.server.WebSocketServerProtocol, ch: Channel): """ Regularly sends the currently running sounds. """ while True: try: await ws.send( json.dumps(list(map(lambda s: s.toJSON(), ch.get_sounds())))) except websockets.exceptions.ConnectionClosed: return await asyncio.sleep(0.1)
def test_remove_client(self): # It removes the client remaining_client = Client(websockets.protocol.WebSocketCommonProtocol(host="1")) removed_client = Client(websockets.protocol.WebSocketCommonProtocol(host="2")) channel = Channel("test-channel") channel.add_client(remaining_client) channel.add_client(removed_client) self.assertTrue(len(channel.clients) == 2) # It removes a client channel.remove_client(removed_client) self.assertTrue(len(channel.clients) == 1) # It removes the right client actual_remaining_client = channel.clients.pop() self.assertEqual(remaining_client, actual_remaining_client)
def on_start(cmd: pcmd.Command, args: List[str], json: bool) -> None: """Callback for `start` - starts the channel""" global ch if ch.is_alive(): if not json: utils.printwrn('Already running ... ') else: print(JSON.dumps({ 'error': 'Already running ... ', })) return ch = Channel(ch.transf, ch.ist, ch.ost) server.ch = ch try: ch.start() if json: print(JSON.dumps({})) except IOError as e: if not json: utils.printerr(e) else: print(JSON.dumps({ 'error': str(e), }))
def play(item_to_play): channel_data = fetch_channel_data(fetch_local_channel_data, fetch_remote_channel_data) xml_data = ET.fromstring(channel_data) try: channel_data = xml_data.find(".//channel[@id='" + item_to_play + "']") channel = Channel(handle, tempdir, channel_data, quality_priority(), format_priority()) except: for element in xml_data.findall(".//channel"): channel = Channel(handle, tempdir, element, quality_priority(), format_priority()) if channel.getid() == item_to_play: break list_item = ListItem(channel.get_simple_element('title'), channel.get_simple_element('description'), channel.geticon(), channel.getthumbnail(), channel.get_content_url()) list_item.setArt({"fanart": xbmc.translatePath("special://home/addons/%s/fanart.jpg" % __addonid__)}) xbmcplugin.setResolvedUrl(handle, True, list_item)
async def handle_connection(self, websocket: iter, path: str): client = Client(websocket) print("New client: " + client.address, flush=True) channel = None try: async for json_message in websocket: message = Message.from_json(json_message) if message.type == "create_channel": new_channel = Channel(message.data["name"]) self.channels[new_channel.id] = new_channel ack = Message(type="ack", data={"channel_id": new_channel.id}) await websocket.send(ack.to_json()) continue channel_id = message.channel_id if channel_id in self.channels.keys(): channel = self.channels[channel_id] else: message = Message(type="error") await websocket.send(message.to_json()) await websocket.close() break if (message.type in ["announce"]): channel.add_client(client) await channel.broadcast(client, message) elif (message.type in ["offer", "answer", "ice"]): await channel.send(client, message) elif (message.type in ["name"]): await channel.broadcast(client, message) finally: if channel: channel.remove_client(client) # broadcast the departure message = Message(type="hangup") await channel.broadcast(client, message) print("Client " + client.address + " left", flush=True)
def test_init(self): # It sets the channel name and assigned a uuid sample_name = "test-name" channel = Channel(sample_name) self.assertEqual(channel.name, sample_name) self.assertTrue(uuid.UUID(channel.id) != "")
from lib import params, utils, server from lib.sound import Sound from lib.device import Device from lib.channel import Channel from lib.interpreter import Interpreter from lib.filters.filter import Filter from lib.server import db from lib.server.models.user import User """The basic prompt for the figaro shell""" BPROMPT: str = cr.Fore.LIGHTBLUE_EX + 'figaro' + cr.Fore.LIGHTBLACK_EX + '$ ' + cr.Fore.RESET """The shell itself""" sh: pash.shell.Shell = pash.shell.Shell(prompt=BPROMPT) """The main PyAudio object""" pa: pyaudio.PyAudio = pyaudio.PyAudio() """The main audio channel""" ch: Channel = Channel() """A list of all running interpreters""" interpreters: List[Interpreter] = [] def on_exit(cmd: pcmd.Command, args: List[str]) -> None: """Callback for `exit` - quits the shell""" if ch.is_alive(): ch.kill() ch.kill_all() pa.terminate() sh.exit() def on_show_devices(cmd: pcmd.Command, args: List[str], json: bool) -> None: """Callback for `show devices` - lists all audio devices"""
class DispatcherTests(unittest.TestCase): def setUp(self): self.target_channel = Channel("target_channel") self.target_channel.broadcast = unittest.mock.AsyncMock() self.target_channel.send = unittest.mock.AsyncMock() self.another_channel = Channel("another_channel") self.channels = { self.target_channel.id: self.target_channel, self.another_channel.id: self.another_channel } self.sender_mock_socket = MockAsyncIterator(iter([])) self.sender = Client(self.sender_mock_socket) self.receiver_mock_socket = MockAsyncIterator(iter([])) self.receiver = Client(self.receiver_mock_socket) self.sample_message = Message(self.sender.address, self.receiver.address, self.target_channel.id, "") def test_init(self): expected_channels = { "channel1": Channel("channel1"), "channel2": Channel("channel2") } dispatcher = Dispatcher(expected_channels) self.assertEqual(dispatcher.channels, expected_channels) def test_create_channel(self): message = self.sample_message message.type = "create_channel" message.receiver_guid = "" message.data = {"name": "new_channel"} # Mock the webocket methods self.sender_mock_socket.send = unittest.mock.AsyncMock() dispatcher = Dispatcher({}) self.mock_receive_message(message, dispatcher) # It adds a new channel found = False new_channel = "" for channel in dispatcher.channels.values(): found = channel.name == "new_channel" if found: new_channel = channel break self.assertTrue(found) # It sends an 'ack' with the channel id self.sender_mock_socket.send.assert_called() sent_message = Message.from_json( self.sender_mock_socket.send.call_args_list[0][0][0]) self.assertEqual(sent_message.type, "ack") self.assertEqual(sent_message.data["channel_id"], new_channel.id) def test_client_disconnect(self): message = self.sample_message message.type = "ignored" message.channel_id = self.target_channel.id dispatcher = Dispatcher(self.channels) self.mock_receive_message(message, dispatcher) # It broadcasts a hangup self.target_channel.broadcast.assert_called() sent_message = self.target_channel.broadcast.call_args_list[0][0][1] self.assertEqual(sent_message.type, "hangup") # It removes the client from the channel self.assertEqual(len(self.target_channel.clients), 0) def test_message_with_missing_channel(self): # When channel_id is missing message = self.sample_message message.type = "anything_but_create_channel" message.channel_id = "non_existent" message.receiver_guid = "" # Mock the webocket methods self.sender_mock_socket.close = unittest.mock.AsyncMock() self.sender_mock_socket.send = unittest.mock.AsyncMock() # Receive the test message dispatcher = Dispatcher(self.channels) self.mock_receive_message(message, dispatcher) # It sends an error to the sender self.sender_mock_socket.send.assert_called() sent_message = Message.from_json( self.sender_mock_socket.send.call_args_list[0][0][0]) self.assertEqual(sent_message.type, "error") # It disconnects self.sender_mock_socket.close.assert_called() def test_announce_message(self): # When an "announce" is received message = self.sample_message message.type = "announce" message.receiver_guid = "" # It broadcasts it to the channel self.it_broadcasts(message) # It adds the sender to the channel matching_clients = list(client for client in list(self.target_channel.clients) if client.websocket == self.sender.websocket) self.assertEqual(len(matching_clients), 1) def test_name_message(self): message = self.sample_message message.type = "name" message.receiver_guid = "" # It broadcasts it to the channel self.it_broadcasts(message) def test_offer_message(self): message = self.sample_message message.type = "offer" self.it_sends(message) def test_answer_message(self): message = self.sample_message message.type = "answer" self.it_sends(message) def test_ice_message(self): message = self.sample_message message.type = "ice" self.it_sends(message) def it_broadcasts(self, message): self.target_channel.remove_client = unittest.mock.Mock() self.sender_mock_socket.iterable = iter([message.to_json()]) dispatcher = Dispatcher(self.channels) asyncio.get_event_loop().run_until_complete( dispatcher.handle_connection(self.sender_mock_socket, "/")) # It broadcasts it to the channel self.target_channel.broadcast.assert_called() broadcast_args = self.target_channel.broadcast.call_args_list[0] self.assertEqual(self.sender.websocket, broadcast_args[0][0].websocket) self.assertEqual(vars(message), vars(broadcast_args[0][1])) def it_sends(self, message): self.target_channel.remove_client = unittest.mock.Mock() self.sender_mock_socket.iterable = iter([message.to_json()]) self.target_channel.add_client(self.sender) dispatcher = Dispatcher(self.channels) asyncio.get_event_loop().run_until_complete( dispatcher.handle_connection(self.sender_mock_socket, "/")) # It sends the message self.target_channel.send.assert_called() send_args = self.target_channel.send.call_args_list[0] self.assertEqual(self.sender.websocket, send_args[0][0].websocket) self.assertEqual(vars(message), vars(send_args[0][1])) def mock_receive_message(self, message, dispatcher): self.target_channel.remove_client = unittest.mock.Mock() self.sender_mock_socket.iterable = iter([message.to_json()]) asyncio.get_event_loop().run_until_complete( dispatcher.handle_connection(self.sender_mock_socket, "/"))