def __broadcast_message(self, msg: ReliableMessage) -> Optional[Content]: """ Deliver message to everyone@everywhere, including all neighbours """ self.debug('broadcasting message from: %s' % msg.sender) if self.__traced(msg=msg, station=self.station): self.error('ignore traced msg: %s in %s' % (self.station, msg.get('traces'))) return None session_server = self.session_server # push to all neighbors connected th current station neighbors = self.__neighbors.copy() sent_neighbors = [] success = 0 for sid in neighbors: if sid == self.station: continue sessions = session_server.active_sessions(identifier=sid) if len(sessions) == 0: self.warning('remote station (%s) not connected, try later.' % sid) continue if self.__push_message(msg=msg, receiver=sid, sessions=sessions): sent_neighbors.append(sid) success += 1 # push to the bridge (octopus) of current station sid = self.station sessions = session_server.active_sessions(identifier=sid) if len(sessions) > 0: # tell the bridge ignore this neighbor stations sent_neighbors.append(sid) msg['sent_neighbors'] = ID.revert(sent_neighbors) self.__push_message(msg=msg, receiver=sid, sessions=sessions) # FIXME: what about the failures # response text = 'Message broadcast to %d/%d stations' % (success, len(neighbors)) res = TextContent(text=text) res.group = msg.group return res
def execute(self, cmd: Command, msg: ReliableMessage) -> Optional[Content]: assert isinstance(cmd, QueryCommand), 'group command error: %s' % cmd facebook = self.facebook from ..facebook import Facebook assert isinstance(facebook, Facebook), 'entity delegate error: %s' % facebook # 0. check group group = cmd.group owner = facebook.owner(identifier=group) members = facebook.members(identifier=group) if owner is None or members is None or len(members) == 0: text = 'Sorry, members not found in group: %s' % group res = TextContent(text=text) res.group = group return res # 1. check permission sender = msg.sender if sender not in members: # not a member? check assistants assistants = facebook.assistants(identifier=group) if assistants is None or sender not in assistants: text = '%s is not a member/assistant of group %s, cannot query.' % ( sender, group) raise AssertionError(text) # 2. respond user = facebook.current_user assert user is not None, 'current user not set' if user.identifier == owner: return GroupCommand.reset(group=group, members=members) else: return GroupCommand.invite(group=group, members=members)
def execute(self, cmd: Command, msg: ReliableMessage) -> Optional[Content]: text = 'Command (name: %s) not support yet!' % cmd.command res = TextContent(text=text) # check group message group = cmd.group if group is not None: res.group = group return res
def process(self, content: Content, msg: ReliableMessage) -> Optional[Content]: text = 'Content (type: %s) not support yet!' % content.type res = TextContent(text=text) # check group message group = content.group if group is not None: res.group = group return res
def query(self, content: Content, sender: ID) -> TextContent: if isinstance(content, TextContent): # text dialog question = content.text answer = self.ask(question=question, sender=sender) if answer is not None: response = TextContent(text=answer) group = content.group if group is not None: response.group = group return response elif isinstance(content, AudioContent): # TODO: Automatic Speech Recognition pass
def __welcome(self, freshmen: List[ID]) -> TextContent: names = [self.facebook.name(item) for item in freshmen] count = len(names) if count == 1: string = names[0] msg = 'Welcome new member~ %s.' % string elif count > 1: string = ', '.join(names) msg = 'Welcome new members~ %s.' % string else: # should not be here msg = 'Welcome!' text = TextContent(text=msg) text.group = self.__group.identifier return text
def __check_blocked(self, envelope: Envelope) -> Optional[Content]: sender = envelope.sender receiver = envelope.receiver group = envelope.group # check block-list if self.database.is_blocked(sender=sender, receiver=receiver, group=group): nickname = self.facebook.name(identifier=receiver) if group is None: text = 'Message is blocked by %s' % nickname else: grp_name = self.facebook.name(identifier=group) text = 'Message is blocked by %s in group %s' % (nickname, grp_name) # response res = TextContent(text=text) res.group = group return res
def arrival(self, msg: ReliableMessage) -> Optional[ReliableMessage]: # check message delegate if msg.delegate is None: msg.delegate = self sid = g_station.identifier if self.__traced(msg=msg, station=g_station): self.debug( 'current station %s in traces list, ignore this message: %s' % (sid, msg)) return None if not self.__deliver_message(msg=msg, neighbor=sid): self.error('failed to send income message: %s' % msg) return None if g_released: # FIXME: how to let the client knows where the message reached return None # response sender = msg.sender text = 'Message reached station: %s' % g_station self.debug('income: %s, %s | %s | %s' % (text, msg['signature'][:8], sender.name, msg.receiver)) res = TextContent(text=text) res.group = msg.group return self.__pack_message(content=res, receiver=sender)
def departure(self, msg: ReliableMessage) -> Optional[ReliableMessage]: receiver = msg.receiver if receiver == g_station.identifier: self.debug('msg for %s will be stopped here' % receiver) return None sent_neighbors = msg.get('sent_neighbors') if sent_neighbors is None: sent_neighbors = [] else: msg.pop('sent_neighbors') neighbors = self.__neighbors.copy() success = 0 for sid in neighbors: if sid in sent_neighbors: self.debug('station %s in sent list, ignore this neighbor' % sid) continue if self.__deliver_message(msg=msg, neighbor=sid): success += 1 # FIXME: what about the failures if g_released: # FIXME: how to let the client knows where the message reached return None # response sender = msg.sender meta = g_messenger.facebook.meta(identifier=sender) if meta is None: # waiting for meta return None text = 'Message broadcast to %d/%d stations' % (success, len(neighbors)) self.debug('outgo: %s, %s | %s | %s' % (text, msg['signature'][:8], sender.name, msg.receiver)) res = TextContent(text=text) res.group = msg.group return self.__pack_message(content=res, receiver=sender)