def filter(self, limit=None, to=None, category=None): """ Returns the events that match the filters Args: limit (int, optional): the max length of the events to return (Default value = None) to (str, optional): only events that have been sent or received by 'to' (Default value = None) category (str, optional): only events belonging to the category (Default value = None) Returns: list: a list of filtered events """ if category and not to: msg_slice = itertools.islice( (x for x in self.store if x[2] == category), limit) elif to and not category: to = JID.fromstr(to) msg_slice = itertools.islice( (x for x in self.store if _agent_in_msg(to, x[1])), limit) elif to and category: to = JID.fromstr(to) msg_slice = itertools.islice( (x for x in self.store if _agent_in_msg(to, x[1]) and x[2] == category), limit) else: msg_slice = self.all(limit=limit) return msg_slice return list(msg_slice)[::-1]
async def subscribe( self, target_jid: str, target_node: Optional[str] = None, subscription_jid: Optional[str] = None, config=None, ): """ Subscribe to a node. Args: target_jid (str): Address of the PubSub service. target_node (str): Name of the PubSub node to subscribe to. subscription_jid (str): The address to subscribe to the service. config (Data): Optional configuration of the subscription """ target_jid = JID.fromstr(target_jid) subscription_jid = (JID.fromstr(subscription_jid) if subscription_jid is not None else None) return await self.pubsub.subscribe( target_jid, target_node, subscription_jid=subscription_jid, config=config, )
def filter(self, limit=None, to=None, category=None): if category and not to: msg_slice = itertools.islice((x for x in self.store if x[2] == category), limit) elif to and not category: to = JID.fromstr(to) msg_slice = itertools.islice((x for x in self.store if _agent_in_msg(to, x[1])), limit) elif to and category: to = JID.fromstr(to) msg_slice = itertools.islice((x for x in self.store if _agent_in_msg(to, x[1]) and x[2] == category), limit) else: msg_slice = self.all(limit=limit) return msg_slice return list(msg_slice)[::-1]
async def publish( self, target_jid: str, target_node: str, payload: str, item_id: Optional[str] = None, ): """ Publish an item to a node. Args: target_jid (str): Address of the PubSub service. target_node (str): Name of the PubSub node to publish to. payload (str): Payload to publish. item_id (str or None): Item ID to use for the item. """ target_jid = JID.fromstr(target_jid) payload_node = Payload() payload_node.data = payload return await self.pubsub.publish(target_jid, target_node, payload_node, id_=item_id)
async def test_unsubscribe_agent(test_client): agent = MockedPresenceAgentFactory() future = agent.start(auto_register=False) future.result() agent.client.enqueue = Mock() agent.web.setup_routes() client = await test_client(agent.web.app) jid = "friend@server" jid_ = JID.fromstr(jid) item = Item(jid=jid_) agent.presence.roster._update_entry(item) response = await client.get(f"/spade/agent/{jid}/unsubscribe/") assert str(response.url.relative()) == f"/spade/agent/{jid}/" assert agent.client.enqueue.mock_calls arg = agent.client.enqueue.call_args[0][0] assert arg.to == jid_.bare() assert arg.type_ == PresenceType.UNSUBSCRIBE agent.stop().result()
async def test_send_agent(test_client): agent = MockedPresenceAgentFactory() future = agent.start(auto_register=False) future.result() agent.stream = MagicMock() agent.stream.send = CoroutineMock() agent.web.setup_routes() client = await test_client(agent.web.app) jid = "friend@server" item = Item(jid=JID.fromstr(jid)) agent.presence.roster._update_entry(item) msg = "Hello World" response = await client.post(f"/spade/agent/{jid}/send/", data={"message": msg}) assert str(response.url.relative()) == f"/spade/agent/{jid}/" sent = agent.traces.all()[0] assert sent[1].sent assert sent[1].body == "Hello World" agent.stop().result()
def is_address_in_list(address: aioxmpp.JID, addresslist: typing.Collection[aioxmpp.JID]) -> bool: if address in addresslist: return True if address.localpart and address.replace(localpart=None) in addresslist: return True return False
async def test_send_agent(test_client): agent = make_presence_connected_agent() future = agent.start(auto_register=False) future.result() agent.stream = MagicMock() agent.stream.send = CoroutineMock() agent.web.setup_routes() client = await test_client(agent.web.app) jid = "friend@server" item = Item(jid=JID.fromstr(jid)) agent.presence.roster._update_entry(item) msg = "Hello World" response = await client.post(f"/spade/agent/{jid}/send/", data={"message": msg}) assert str(response.url.relative()) == f"/spade/agent/{jid}/" sent = agent.traces.all()[0] assert sent[1].sent assert sent[1].body == "Hello World" agent.stop()
async def test_unsubscribe_agent(test_client): agent = make_presence_connected_agent() future = agent.start(auto_register=False) future.result() agent.client.enqueue = Mock() agent.web.setup_routes() client = await test_client(agent.web.app) jid = "friend@server" jid_ = JID.fromstr(jid) item = Item(jid=jid_) agent.presence.roster._update_entry(item) response = await client.get(f"/spade/agent/{jid}/unsubscribe/") assert str(response.url.relative()) == f"/spade/agent/{jid}/" assert agent.client.enqueue.mock_calls arg = agent.client.enqueue.call_args[0][0] assert arg.to == jid_.bare() assert arg.type_ == PresenceType.UNSUBSCRIBE agent.stop()
async def get_agent(self, request): agent_jid = request.match_info['agentjid'] agent_messages = [(self.timeago(m[0]), m[1]) for m in self.agent.traces.filter(to=agent_jid)] c = self.agent.presence.get_contact(JID.fromstr(agent_jid)) contact = { "show": str(c["presence"].show).split(".")[1] if "presence" in c.keys() else None } return {"amessages": agent_messages, "ajid": agent_jid, "contact": contact}
def test_get_invalid_jid_contact(): agent = make_presence_connected_agent() future = agent.start(auto_register=False) future.result() with pytest.raises(ContactNotFound): agent.presence.get_contact(JID.fromstr("invalid@contact"))
def test_get_invalid_jid_contact(): agent = MockedPresenceAgentFactory() future = agent.start(auto_register=False) future.result() with pytest.raises(ContactNotFound): agent.presence.get_contact(JID.fromstr("invalid@contact"))
def on_chatwith_room(self, data): roomJID = '{}@{}'.format(data['roomName'], Config._mucService) Log.info("发起会话", roomJID) if roomJID not in self._ConversationList: #一定要有昵称才可以进入聊天室 room, futrue = self.muc_service.join(JID.fromstr(roomJID), str(self.core.jid)) self._ConversationList[roomJID] = room Log.info("进入房间", roomJID)
def setup(self): self.web.start(templates_path="examples") template1 = Template(sender="agent0@fake_server") template2 = Template(sender="agent1@fake_server") template3 = Template(sender="agent2@fake_server") template4 = Template(sender="agent3@fake_server") # Create some dummy behaviours dummybehav = self.DummyBehav() self.add_behaviour(dummybehav, template=template1) periodbehav = self.DummyPeriodBehav(period=12.7) self.add_behaviour(periodbehav, template=template2) timeoutbehav = self.DummyTimeoutBehav(start_at=datetime.datetime.now()) self.add_behaviour(timeoutbehav, template=template3) fsm_behav = self.DummyFSMBehav() self.add_behaviour(fsm_behav, template=template4) behavs = [dummybehav, periodbehav, timeoutbehav, fsm_behav] # Create some fake contacts self.add_fake_contact("agent0@fake_server", PresenceType.AVAILABLE) self.add_fake_contact("agent1@fake_server", PresenceType.AVAILABLE, show=PresenceShow.AWAY) self.add_fake_contact( "agent2@fake_server", PresenceType.AVAILABLE, show=PresenceShow.DO_NOT_DISTURB, ) self.add_fake_contact("agent3@fake_server", PresenceType.UNAVAILABLE) self.add_fake_contact("agent4@fake_server", PresenceType.AVAILABLE, show=PresenceShow.CHAT) self.add_fake_contact("agent5@fake_server", PresenceType.UNAVAILABLE) # Send and Receive some fake messages self.traces.reset() for i in range(20): number = random.randint(0, 3) from_ = JID.fromstr("agent{}@fake_server".format(number)) msg = aioxmpp.Message(from_=from_, to=self.jid, type_=MessageType.CHAT) msg.body[None] = "Hello from {}! This is a long message.".format( from_.localpart) msg = Message.from_node(msg) msg.metadata = { "performative": "inform", "acl-representation": "xml" } msg = msg.prepare() self._message_received(msg=msg) msg = Message(sender=str(self.jid), to=str(from_), body="This is my answer.") msg.sent = True self.traces.append(msg, category=str(behavs[number]))
async def purge(self, target_jid: str, target_node: Optional[str]): """ Delete all items from a node. Args: target_jid (str): JID of the PubSub service target_node (str): Name of the PubSub node """ target_jid = JID.fromstr(target_jid) return await self.pubsub.purge(target_jid, target_node)
async def get_items(self, target_jid: str, target_node: Optional[str]): """ Request all items at a service or collection node. Args: target_jid (str): Addressof the PubSub service. target_node (str): Name of the PubSub node. """ target_jid = JID.fromstr(target_jid) request = await self.pubsub.get_items(target_jid, node=target_node) return [item.registered_payload for item in request.payload.items]
async def notify(self, target_jid: str, target_node: str): """ Notify all subscribers of a node without publishing an item. “Publish” to the node at jid without any item. This merely fans out a notification. Args: target_jid (str): Address of the PubSub service. target_node (str): Name of the PubSub node to send a notify from. """ target_jid = JID.fromstr(target_jid) return await self.pubsub.notify(target_jid, target_node)
def add_fake_contact(self, jid, presence, show=None): jid = JID.fromstr(jid) item = Item(jid=jid) item.approved = True self.presence.roster._update_entry(item) if show: stanza = Presence(from_=jid, type_=presence, show=show) else: stanza = Presence(from_=jid, type_=presence) self.presence.presenceclient.handle_presence(stanza)
async def get_nodes(self, target_jid: str, target_node: Optional[str] = None): """ Request all nodes at a service or collection node. Args: target_jid (str): Address of the PubSub service. target_node (str or None): Name of the collection node to query """ target_jid = JID.fromstr(target_jid) return await self.pubsub.get_nodes(target_jid, target_node)
async def create(self, target_jid: str, target_node: Optional[str] = None): """ Create a new node at a service. Args: target_jid (str): Address of the PubSub service. target_node (str or None): Name of the PubSub node to create """ target_jid = JID.fromstr(target_jid) return await self.pubsub.create(target_jid, target_node)
async def get_node_subscriptions( self, target_jid: str, target_node: Optional[str]) -> List[str]: """ Return the subscriptions of other jids with a node. Args: target_jid (str): Address of the PubSub service. target_node (str): Name of the node to query """ target_jid = JID.fromstr(target_jid) result = await self.pubsub.get_node_subscriptions( target_jid, target_node) return [str(x.jid) for x in result.payload.subscriptions]
async def getFriendList(self): _user = Users('http://{}:{}'.format(Config._host, Config._restPort), Config._restPort_secret) try: ''' friendList的数据格式: {'rosterItem': [{'jid': '[email protected]', 'nickname': 'chinsing00', 'subscriptionType': 3, 'groups': ['Friends']},{...}]} ''' friend_List = _user.get_user_roster( self.core.jid.localpart) #只需要用户名就行,不需要加域名 del _user #清除user,避免服务器生成过多的连接导致服务器连接池溢出 metadata = await self.avatar_server.get_avatar_metadata( self.core.jid) if metadata: picture = await asyncio.ensure_future( metadata[0].get_image_bytes()) picPath = os.path.join( app.getAvatarRootPath(self.core.jid.localpart), '{}.jpg'.format(str(self.core.jid))) if not os.path.exists(picPath): FileUtils.savaToPng(picPath, picture) usericon = QPixmap.fromImage(QImage(picPath)) if os.path.exists( picPath) else QPixmap(":src\images\CustomerService.png") self.mWin.avatar.setBaseSize(QSize(40, 40)) temp = utils.PixmapToRound(self.mWin.avatar, usericon) self.mWin.avatar.setScaledContents(True) self.mWin.avatar.setPixmap(temp) for friend in friend_List['rosterItem']: # task执行后返回 <AbstractAvatarDescriptor> 对象 task = await get_event_loop().create_task( self.avatar_server.get_avatar_metadata(JID.fromstr( friend['jid']), require_fresh=True, disable_pep=False)) #得到<AbstractAvatarDescriptor> 对象后进行头像保存本地及加载好友列表 avatar_path = None if task: bin_data = await ensure_future( task[0].get_image_bytes() ) # get_image_bytes()为协程,result[0]为最新的图片 avatar_path = os.path.join( app.getAvatarRootPath(self.core.jid.localpart), '{}.jpg'.format(friend['jid'])) FileUtils.savaToPng(avatar_path, bin_data) friend['avatar_path'] = avatar_path self.mWin.loadData(friend) except InvalidResponseException: Log.info("RestAPi", "获取好友列表失败")
async def unsubscribe( self, target_jid: str, target_node: Optional[str] = None, subscription_jid: Optional[str] = None, subid=None, ): """ Unsubscribe from a node. Args: target_jid (str): Address of the PubSub service. target_node (str): Name of the PubSub node to unsubscribe from. subscription_jid (str): The address to subscribe from the service. subid (str): Unique ID of the subscription to remove. """ target_jid = JID.fromstr(target_jid) subscription_jid = (JID.fromstr(subscription_jid) if subscription_jid is not None else None) return await self.pubsub.unsubscribe( target_jid, target_node, subscription_jid=subscription_jid, subid=subid)
async def getMembersAvatar(self, memberList): rootPath = os.path.join(app.getAvatarRootPath(self.core.jid.localpart), self.room_jid) if not os.path.exists(rootPath): os.mkdir(rootPath) self.room_path = rootPath for member in memberList: metadata = await asyncio.ensure_future( self._muc_avatarService.get_avatar_metadata( JID.fromstr(member))) if metadata: picture = await asyncio.ensure_future( metadata[0].get_image_bytes()) picPath = os.path.join(rootPath, '{}.jpg'.format(member)) FileUtils.savaToPng(picPath, picture) self.loadMember(memberList)
async def delete( self, target_jid: str, target_node: Optional[str], redirect_uri: Optional[str] = None, ): """ Delete an existing node. Args: target_jid (str): Address of the PubSub service. target_node (str or None): Name of the PubSub node to delete. redirect_uri (str or None): A URI to send to subscribers to indicate a replacement for the deleted node.""" target_jid = JID.fromstr(target_jid) return await self.pubsub.delete(target_jid, target_node, redirect_uri=redirect_uri)
def get_contact(self, jid: aioxmpp.JID) -> Dict: """ Returns a contact Args: jid (aioxmpp.JID): jid of the contact Returns: dict: the roster of contacts """ try: return self.get_contacts()[jid.bare()] except KeyError: raise ContactNotFound except AttributeError: raise AttributeError("jid must be an aioxmpp.JID object")
async def test_get_agent(test_client, loop): agent = Agent("jid@server", "password") agent.web.setup_routes() client = await test_client(agent.web.app) jid = "friend@server" item = Item(jid=JID.fromstr(jid)) agent.presence.roster._update_entry(item) response = await client.get(f"/spade/agent/{jid}/") response = await response.text() sel = Selector(text=response) assert sel.css("section.content-header > h1::text").get().strip() == jid agent.stop()
async def retract(self, target_jid: str, target_node: str, item_id: str, notify=False): """ Retract a previously published item from a node. Args: target_jid (str): Address of the PubSub service. target_node (str): Name of the PubSub node to send a notify from. item_id (str): The ID of the item to retract. notify (bool): Flag indicating whether subscribers shall be notified about the retraction. """ target_jid = JID.fromstr(target_jid) return await self.pubsub.retract(target_jid, target_node, item_id, notify=notify)
async def test_get_agent(test_client): agent = MockedPresenceAgentFactory(jid="jid@server", password="******") future = agent.start(auto_register=False) future.result() agent.web.setup_routes() client = await test_client(agent.web.app) jid = "friend@server" item = Item(jid=JID.fromstr(jid)) agent.presence.roster._update_entry(item) response = await client.get(f"/spade/agent/{jid}/") response = await response.text() sel = Selector(text=response) assert sel.css("section.content-header > h1::text").get().strip() == jid agent.stop().result()
async def test_get_agent(test_client): agent = make_presence_connected_agent("jid@server", "password") future = agent.start(auto_register=False) future.result() agent.web.setup_routes() client = await test_client(agent.web.app) jid = "friend@server" item = Item(jid=JID.fromstr(jid)) agent.presence.roster._update_entry(item) response = await client.get(f"/spade/agent/{jid}/") response = await response.text() sel = Selector(text=response) assert sel.css("section.content-header > h1::text").get().strip() == jid agent.stop()
def setup(self): self.web.start(templates_path="examples") template1 = Template(sender="agent0@fake_server") template2 = Template(sender="agent1@fake_server") template3 = Template(sender="agent2@fake_server") template4 = Template(sender="agent3@fake_server") # Create some dummy behaviours dummybehav = self.DummyBehav() self.add_behaviour(dummybehav, template=template1) periodbehav = self.DummyPeriodBehav(period=12.7) self.add_behaviour(periodbehav, template=template2) timeoutbehav = self.DummyTimeoutBehav(start_at=datetime.datetime.now()) self.add_behaviour(timeoutbehav, template=template3) fsm_behav = self.DummyFSMBehav() self.add_behaviour(fsm_behav, template=template4) behavs = [dummybehav, periodbehav, timeoutbehav, fsm_behav] # Create some fake contacts self.add_fake_contact("agent0@fake_server", PresenceType.AVAILABLE) self.add_fake_contact("agent1@fake_server", PresenceType.AVAILABLE, show=PresenceShow.AWAY) self.add_fake_contact("agent2@fake_server", PresenceType.AVAILABLE, show=PresenceShow.DO_NOT_DISTURB) self.add_fake_contact("agent3@fake_server", PresenceType.UNAVAILABLE) self.add_fake_contact("agent4@fake_server", PresenceType.AVAILABLE, show=PresenceShow.CHAT) self.add_fake_contact("agent5@fake_server", PresenceType.UNAVAILABLE) # Send and Receive some fake messages self.traces.reset() for i in range(20): number = random.randint(0, 3) from_ = JID.fromstr("agent{}@fake_server".format(number)) msg = aioxmpp.Message(from_=from_, to=self.jid, type_=MessageType.CHAT) msg.body[None] = "Hello from {}! This is a long message.".format(from_.localpart) msg = Message.from_node(msg) msg.metadata = {"performative": "inform", "acl-representation": "xml"} msg = msg.prepare() self._message_received(msg=msg) msg = Message(sender=str(self.jid), to=str(from_), body="This is my answer.") msg.sent = True self.traces.append(msg, category=str(behavs[number]))
async def test_send_agent(test_client, loop): agent = make_connected_agent() agent.stream.send = CoroutineMock() agent.start() agent.web.setup_routes() client = await test_client(agent.web.app) jid = "friend@server" item = Item(jid=JID.fromstr(jid)) agent.presence.roster._update_entry(item) msg = "Hello World" response = await client.post(f"/agent/{jid}/send/", data={"message": msg}) assert str(response.url.relative()) == f"/agent/{jid}/" sent = agent.traces.all()[0] assert sent[1].sent assert sent[1].body == "Hello World" agent.stop()
async def test_unsubscribe_agent(test_client, loop): agent = make_connected_agent() agent.aiothread.client.enqueue = Mock() agent.start() agent.web.setup_routes() client = await test_client(agent.web.app) jid = "friend@server" jid_ = JID.fromstr(jid) item = Item(jid=jid_) agent.presence.roster._update_entry(item) response = await client.get(f"/agent/{jid}/unsubscribe/") assert str(response.url.relative()) == f"/agent/{jid}/" assert agent.aiothread.client.enqueue.mock_calls arg = agent.aiothread.client.enqueue.call_args[0][0] assert arg.to == jid_.bare() assert arg.type_ == PresenceType.UNSUBSCRIBE agent.stop()
def jid(): return JID.fromstr("friend@localhost/home")