def send_location_msg(self): slave = coordinator.slaves['tests.mocks.slave'] alice = slave.get_chat('alice') msg = EFBMsg() msg.deliver_to = slave msg.chat = alice msg.author = EFBChat(self).self() msg.type = MsgType.Location msg.text = "I'm not here." msg.attributes = EFBMsgLocationAttribute(latitude=0.1, longitude=1.0) return coordinator.send_message(msg)
def build_efb_chat_as_anonymous_user(self, context): efb_chat = EFBChat(self.channel) anonymous_data = context['anonymous'] efb_chat.chat_uid = 'anonymous' + '_' + anonymous_data['flag'] efb_chat.chat_name = '[Anonymous] ' + anonymous_data['name'] efb_chat.chat_type = ChatType.User efb_chat.is_chat = False efb_chat.vendor_specific = { 'is_anonymous': True, 'anonymous_id': anonymous_data['id'] } efb_chat.group = self.build_efb_chat_as_group(context) return efb_chat
def send_link_msg(self): slave = next(iter(coordinator.slaves.values())) alice = slave.get_chat('alice') msg = EFBMsg() msg.deliver_to = slave msg.chat = alice msg.author = EFBChat(self).self() msg.type = MsgType.Link msg.text = "Check it out." msg.attributes = EFBMsgLinkAttribute(title="Example", url="https://example.com") return coordinator.send_message(msg)
def test_copy(self): channel = MockMasterChannel() chat = EFBChat(channel) chat.chat_uid = "00001" chat.chat_name = "Chat" chat.chat_alias = "chaT" chat.chat_type = ChatType.User copy = chat.copy() assert chat == copy assert chat is not copy
def test_copy(self): channel = MockMasterChannel() chat = EFBChat(channel) chat.chat_uid = "00001" chat.chat_name = "Chat" chat.chat_alias = "chaT" chat.chat_type = ChatType.User copy = chat.copy() self.assertEqual(chat, copy) self.assertIsNot(chat, copy)
def build_efb_chat_as_group(self, context): efb_chat = EFBChat(self.channel) efb_chat.chat_type = ChatType.Group is_discuss = False if context['message_type'] == 'group' else True chat_uid = context['discuss_id'] if is_discuss else context['group_id'] if not is_discuss: efb_chat.chat_uid = 'group' + '_' + str(chat_uid) i = self.channel.QQClient.get_group_info(chat_uid) if i is not None: efb_chat.chat_name = i[ 'group_name'] if 'group_name' not in context else context[ 'group_name'] else: efb_chat.chat_name = chat_uid efb_chat.vendor_specific = {'is_discuss': False} # todo Add user to efb_chat.member else: efb_chat.chat_uid = 'discuss' + '_' + str(chat_uid) efb_chat.chat_name = 'Discuss Group' + '_' + str(chat_uid) # todo Find a way to distinguish from different discuss group efb_chat.vendor_specific = {'is_discuss': True} return efb_chat
def build_efb_chat_as_user(self, context, is_chat): efb_chat = EFBChat(self.channel) uid = context['user_id'] efb_chat.chat_uid = 'private' + '_' + str(uid) chat_name = '' if 'nickname' not in context: i: dict = self.channel.QQClient.get_stranger_info(uid) chat_name = i['nickname'] else: chat_name = context['nickname'] efb_chat.chat_name = chat_name efb_chat.chat_alias = None if 'alias' not in context else context[ 'alias'] efb_chat.chat_type = ChatType.User efb_chat.is_chat = is_chat efb_chat.vendor_specific = {'is_anonymous': False} if not is_chat and context['message_type'] != 'private': efb_chat.group = self.build_efb_chat_as_group(context) return efb_chat
def wechat_text_msg(self, msg: wxpy.Message) -> EFBMsg: if msg.chat.user_name == "newsapp" and msg.text.startswith("<mmreader>"): return self.wechat_newsapp_msg(msg) if msg.text.startswith("http://weixin.qq.com/cgi-bin/redirectforward?args="): return self.wechat_location_msg(msg) efb_msg = EFBMsg() efb_msg.text = ews_utils.wechat_string_unescape(msg.text) efb_msg.type = MsgType.Text if msg.is_at: found = False for i in re.finditer("@([^@]*)(?=\u2005|$)", msg.text): if i.groups()[0] in (self.bot.self.name, msg.chat.self.display_name): found = True efb_msg.substitutions = EFBMsgSubstitutions({ i.span(): EFBChat(self.channel).self() }) if not found: append = "@" + self.bot.self.name efb_msg.substitutions = EFBMsgSubstitutions({ (len(msg.text) + 1, len(msg.text) + 1 + len(append)): EFBChat(self.channel).self() }) efb_msg.text += " " + append return efb_msg
def exit_callback(self): # Don't send prompt if there's nowhere to send. if not getattr(coordinator, 'master', default=None): raise Exception( self. _("Web WeChat logged your account out before master channel is ready." )) self.logger.debug('Calling exit callback...') if self._stop_polling_event.is_set(): return msg = EFBMsg() chat = EFBChat(self).system() chat.chat_type = ChatType.System chat.chat_name = self._("EWS User Auth") msg.chat = msg.author = chat msg.deliver_to = coordinator.master msg.text = self._( "WeChat server has logged you out. Please log in again when you are ready." ) msg.uid = "__reauth__.%s" % int(time.time()) msg.type = MsgType.Text on_log_out = self.flag("on_log_out") on_log_out = on_log_out if on_log_out in ("command", "idle", "reauth") else "command" if on_log_out == "command": msg.type = MsgType.Text msg.commands = EFBMsgCommands([ EFBMsgCommand(name=self._("Log in again"), callable_name="reauth", kwargs={"command": True}) ]) elif on_log_out == "reauth": if self.flag("qr_reload") == "console_qr_code": msg.text += "\n" + self._("Please check your log to continue.") self.reauth() coordinator.send_message(msg)
def wechat_system_msg(self, msg: wxpy.Message) -> Optional[EFBMsg]: if msg.recalled_message_id: efb_msg = EFBMsg() efb_msg.chat = self.channel.chats.wxpy_chat_to_efb_chat(msg.chat) efb_msg.author = self.channel.chats.wxpy_chat_to_efb_chat(msg.sender) efb_msg.uid = str(msg.recalled_message_id) coordinator.send_status(EFBMessageRemoval(source_channel=self.channel, destination_channel=coordinator.master, message=efb_msg)) return None efb_msg = EFBMsg() efb_msg.text = msg.text efb_msg.type = MsgType.Text efb_msg.author = EFBChat(self.channel).system() return efb_msg
def test_pickle(slave_channel): chat = EFBChat(slave_channel) chat.chat_uid = "00001" chat.chat_name = "Chat" chat.chat_alias = "chaT" chat.chat_type = ChatType.User chat_dup = pickle.loads(pickle.dumps(chat)) for attr in ("module_name", "module_id", "channel_emoji", "chat_name", "chat_type", "chat_alias", "chat_uid", "is_chat"): assert getattr(chat, attr) == getattr(chat_dup, attr)
def get_chat_from_db(self, channel_id: str, chat_id: str) -> Optional[EFBChat]: d = self.db.get_slave_chat_info(slave_channel_id=channel_id, slave_chat_uid=chat_id) if d: chat = EFBChat(coordinator.slaves[channel_id]) chat.chat_name = d.slave_chat_name chat.chat_alias = d.slave_chat_alias chat.chat_uid = d.slave_chat_uid chat.chat_type = ChatType(d.slave_chat_type) return chat else: chat = coordinator.slaves[channel_id].get_chat(chat_id) if chat: self._db_update_slave_chats_cache([chat]) return chat
def get_chat_from_db(self, channel_id: ModuleID, chat_id: ChatID) -> Optional[EFBChat]: if channel_id not in coordinator.slaves: return None d = self.db.get_slave_chat_info(slave_channel_id=channel_id, slave_chat_uid=chat_id) if d: chat = EFBChat(coordinator.slaves[channel_id]) chat.chat_name = d.slave_chat_name chat.chat_alias = d.slave_chat_alias chat.chat_uid = d.slave_chat_uid chat.chat_type = ChatType(d.slave_chat_type) return chat else: try: chat = coordinator.slaves[channel_id].get_chat(chat_id) if chat: self._db_update_slave_chats_cache([chat]) return chat return None except EFBChatNotFound: return None
def __init__(self): alice = EFBChat(self) alice.chat_name = "Alice" alice.chat_uid = "alice" alice.chat_type = ChatType.User bob = EFBChat(self) bob.chat_name = "Bob" bob.chat_alias = "Little bobby" bob.chat_uid = "bob" bob.chat_type = ChatType.User carol = EFBChat(self) carol.chat_name = "Carol" carol.chat_uid = "carol" carol.chat_type = ChatType.User dave = EFBChat(self) dave.chat_name = "デブ" # Nah, that's a joke dave.chat_uid = "dave" dave.chat_type = ChatType.User wonderland = EFBChat(self) wonderland.chat_name = "Wonderland" wonderland.chat_uid = "wonderland001" wonderland.chat_type = ChatType.Group wonderland.members = [bob.copy(), carol.copy(), dave.copy()] for i in wonderland.members: i.group = wonderland i.is_chat = False self.chats: List[EFBChat] = [alice, bob, wonderland]
def test_generate_with_channel(slave_channel): chat = EFBChat(slave_channel) assert chat.module_id == slave_channel.channel_id assert chat.module_name == slave_channel.channel_name assert chat.channel_emoji == slave_channel.channel_emoji
def test_verify_missing_uid(slave_channel): chat = EFBChat(slave_channel) chat.chat_name = "Chat" chat.chat_type = ChatType.User with pytest.raises(ValueError): chat.verify()
def test_normal_chat(): chat = EFBChat() assert not chat.is_self assert not chat.is_system
def test_is_self(): chat = EFBChat().self() assert chat.is_self
def test_is_system(): chat = EFBChat().system() assert chat.is_system
def test_generate_with_middleware(middleware): chat = EFBChat(middleware=middleware) assert chat.module_id == middleware.middleware_id assert chat.module_name == middleware.middleware_name
def test_generate_with_channel(self): channel = MockMasterChannel() chat = EFBChat(channel) self.assertEqual(chat.channel_id, channel.channel_id) self.assertEqual(chat.channel_name, channel.channel_name) self.assertEqual(chat.channel_emoji, channel.channel_emoji)
def process_telegram_message(self, bot: telegram.Bot, update: telegram.Update, channel_id: Optional[str] = None, chat_id: Optional[str] = None, target_msg: Optional[str] = None): """ Process messages came from Telegram. Args: bot: Telegram bot update: Telegram message update channel_id: Slave channel ID if specified chat_id: Slave chat ID if specified target_msg: Target slave message if specified Returns: """ target: Optional[str] = None target_channel: Optional[str] = None target_log: Optional['MsgLog'] = None # Message ID for logging message_id = utils.message_id_to_str(update=update) multi_slaves: bool = False destination: Optional[str] = None slave_msg: Optional[EFBMsg] = None message: telegram.Message = update.effective_message edited = bool(update.edited_message or update.edited_channel_post) self.logger.debug('[%s] Message is edited: %s, %s', message_id, edited, message.edit_date) private_chat = update.effective_chat.type == telegram.Chat.PRIVATE if not private_chat: # from group linked_chats = self.db.get_chat_assoc( master_uid=utils.chat_id_to_str(self.channel_id, update.effective_chat.id)) if len(linked_chats) == 1: destination = linked_chats[0] elif len(linked_chats) > 1: multi_slaves = True reply_to = bool(getattr(message, "reply_to_message", None)) # Process predefined target (slave) chat. if channel_id and chat_id: destination = utils.chat_id_to_str(channel_id, chat_id) if target_msg: target_log = self.db.get_msg_log(master_msg_id=target_msg) if target_log: target = target_log.slave_origin_uid target_channel, target_uid = utils.chat_id_str_to_id( target) else: self.logger.info( "[%s], Predefined chat %d.%d with target msg") return self.bot.reply_error( update, self._("Message is not found in database. " "Please try with another message. (UC07)")) elif private_chat: if reply_to: dest_msg = self.db.get_msg_log( master_msg_id=utils.message_id_to_str( message.reply_to_message.chat.id, message.reply_to_message.message_id)) if dest_msg: destination = dest_msg.slave_origin_uid else: return self.bot.reply_error( update, self._("Message is not found in database. " "Please try with another one. (UC03)")) else: return self.bot.reply_error( update, self._("Please reply to an incoming message. (UC04)")) else: # group chat if multi_slaves: if reply_to: dest_msg = self.db.get_msg_log( master_msg_id=utils.message_id_to_str( message.reply_to_message.chat.id, message.reply_to_message.message_id)) if dest_msg: destination = dest_msg.slave_origin_uid else: return self.bot.reply_error( update, self._("Message is not found in database. " "Please try with another one. (UC05)")) else: return self.bot.reply_error( update, self. _("This group is linked to multiple remote chats. " "Please reply to an incoming message. " "To unlink all remote chats, please send /unlink_all . (UC06)" )) elif destination: if reply_to: target_log = \ self.db.get_msg_log(master_msg_id=utils.message_id_to_str( message.reply_to_message.chat.id, message.reply_to_message.message_id)) if target_log: target = target_log.slave_origin_uid target_channel, target_uid = utils.chat_id_str_to_id( target) else: return self.bot.reply_error( update, self._("Message is not found in database. " "Please try with another message. (UC07)")) else: return self.bot.reply_error( update, self._("This group is not linked to any chat. (UC06)")) self.logger.debug( "[%s] Telegram received. From private chat: %s; Group has multiple linked chats: %s; " "Message replied to another message: %s", message_id, private_chat, multi_slaves, reply_to) self.logger.debug("[%s] Destination chat = %s", message_id, destination) channel, uid = utils.chat_id_str_to_id(destination) if channel not in coordinator.slaves: return self.bot.reply_error( update, self._("Internal error: Channel \"{0}\" not found.").format( channel)) m = EFBMsg() try: m.uid = message_id mtype = get_msg_type(message) # Chat and author related stuff m.author = EFBChat(self.channel).self() m.chat = EFBChat(coordinator.slaves[channel]) m.chat.chat_uid = uid chat_info = self.db.get_slave_chat_info(channel, uid) if chat_info: m.chat.chat_name = chat_info.slave_chat_name m.chat.chat_alias = chat_info.slave_chat_alias m.chat.chat_type = ChatType(chat_info.slave_chat_type) m.deliver_to = coordinator.slaves[channel] if target and target_channel == channel: trgt_msg = EFBMsg() trgt_msg.type = MsgType.Text trgt_msg.text = target_log.text trgt_msg.uid = target_log.slave_message_id trgt_msg.chat = EFBChat(coordinator.slaves[target_channel]) trgt_msg.chat.chat_name = target_log.slave_origin_display_name trgt_msg.chat.chat_alias = target_log.slave_origin_display_name trgt_msg.chat.chat_uid = utils.chat_id_str_to_id( target_log.slave_origin_uid)[1] if target_log.slave_member_uid: trgt_msg.author = EFBChat( coordinator.slaves[target_channel]) trgt_msg.author.chat_name = target_log.slave_member_display_name trgt_msg.author.chat_alias = target_log.slave_member_display_name trgt_msg.author.chat_uid = target_log.slave_member_uid elif target_log.sent_to == 'master': trgt_msg.author = trgt_msg.chat else: trgt_msg.author = EFBChat(self.channel).self() m.target = trgt_msg self.logger.debug( "[%s] This message replies to another message of the same channel.\n" "Chat ID: %s; Message ID: %s.", message_id, trgt_msg.chat.chat_uid, trgt_msg.uid) # Type specific stuff self.logger.debug("[%s] Message type from Telegram: %s", message_id, mtype) if self.TYPE_DICT.get(mtype, None): m.type = self.TYPE_DICT[mtype] self.logger.debug("[%s] EFB message type: %s", message_id, mtype) else: self.logger.info( "[%s] Message type %s is not supported by ETM", message_id, mtype) raise EFBMessageTypeNotSupported( "Message type %s is not supported by ETM" % mtype) if m.type not in coordinator.slaves[ channel].supported_message_types: self.logger.info( "[%s] Message type %s is not supported by channel %s", message_id, m.type.name, channel) raise EFBMessageTypeNotSupported( "Message type %s is not supported by channel %s" % (m.type, coordinator.slaves[channel].channel_name)) # Parse message text and caption to markdown msg_md_text = message.text and message.text_markdown if msg_md_text and msg_md_text == escape_markdown(message.text): msg_md_text = message.text msg_md_text = msg_md_text or "" msg_md_caption = message.caption and message.caption_markdown if msg_md_caption and msg_md_caption == escape_markdown( message.caption): msg_md_caption = message.caption msg_md_caption = msg_md_caption or "" # Flag for edited message if edited: m.edit = True text = msg_md_text or msg_md_caption msg_log = self.db.get_msg_log( master_msg_id=utils.message_id_to_str(update=update)) if not msg_log or msg_log == self.FAIL_FLAG: raise EFBMessageNotFound() m.uid = msg_log.slave_message_id if text.startswith(self.DELETE_FLAG): coordinator.send_status( EFBMessageRemoval( source_channel=self.channel, destination_channel=coordinator.slaves[channel], message=m)) self.db.delete_msg_log( master_msg_id=utils.message_id_to_str(update=update)) m = None return self.logger.debug('[%s] Message is edited (%s)', m.uid, m.edit) # Enclose message as an EFBMsg object by message type. if mtype == TGMsgType.Text: m.text = msg_md_text elif mtype == TGMsgType.Photo: m.text = msg_md_caption m.file, m.mime, m.filename, m.path = self._download_file( message.photo[-1]) elif mtype == TGMsgType.Sticker: # Convert WebP to the more common PNG m.text = "" m.file, m.mime, m.filename, m.path = self._download_file( message.sticker, 'image/webp') self.logger.debug( "[%s] Trying to convert WebP sticker (%s) to PNG.", message_id, m.path) f = tempfile.NamedTemporaryFile(suffix=".png") Image.open(m.file).convert("RGBA").save(f, 'png') m.file.close() m.file, m.mime, m.filename, m.path = f, 'image/png', os.path.basename( f.name), f.name self.logger.debug( "[%s] WebP sticker is converted to PNG (%s).", message_id, f.name) elif mtype == TGMsgType.Animation: m.text = "" self.logger.debug( "[%s] Telegram message is a \"Telegram GIF\".", message_id) m.filename = getattr(message.document, "file_name", None) or None m.file, m.mime, m.filename, m.path = self._download_gif( message.document, channel) m.mime = message.document.mime_type or m.mime elif mtype == TGMsgType.Document: m.text = msg_md_caption self.logger.debug("[%s] Telegram message type is document.", message_id) m.filename = getattr(message.document, "file_name", None) or None m.file, m.mime, filename, m.path = self._download_file( message.document, message.document.mime_type) m.filename = m.filename or filename m.mime = message.document.mime_type or m.mime elif mtype == TGMsgType.Video: m.text = msg_md_caption m.file, m.mime, m.filename, m.path = self._download_file( message.video, message.video.mime_type) elif mtype == TGMsgType.Audio: m.text = "%s - %s\n%s" % (message.audio.title, message.audio.performer, msg_md_caption) m.file, m.mime, m.filename, m.path = self._download_file( message.audio, message.audio.mime_type) elif mtype == TGMsgType.Voice: m.text = msg_md_caption m.file, m.mime, m.filename, m.path = self._download_file( message.voice, message.voice.mime_type) elif mtype == TGMsgType.Location: # TRANSLATORS: Message body text for location messages. m.text = self._("Location") m.attributes = EFBMsgLocationAttribute( message.location.latitude, message.location.longitude) elif mtype == TGMsgType.Venue: m.text = message.location.title + "\n" + message.location.adderss m.attributes = EFBMsgLocationAttribute( message.venue.location.latitude, message.venue.location.longitude) elif mtype == TGMsgType.Contact: contact: telegram.Contact = message.contact m.text = self._( "Shared a contact: {first_name} {last_name}\n{phone_number}" ).format(first_name=contact.first_name, last_name=contact.last_name, phone_number=contact.phone_number) else: raise EFBMessageTypeNotSupported( self._("Message type {0} is not supported.").format(mtype)) # return self.bot.reply_error(update, "Message type not supported. (MN02)") slave_msg = coordinator.send_message(m) except EFBChatNotFound as e: self.bot.reply_error(update, e.args[0] or self._("Chat is not found.")) except EFBMessageTypeNotSupported as e: self.bot.reply_error( update, e.args[0] or self._("Message type is not supported.")) except EFBOperationNotSupported as e: self.bot.reply_error( update, self._("Message editing is not supported.\n\n{!s}".format(e))) except Exception as e: self.bot.reply_error( update, self._("Message is not sent.\n\n{!r}".format(e))) finally: if m: msg_log_d = { "master_msg_id": utils.message_id_to_str(update=update), "text": m.text or "Sent a %s" % m.type, "slave_origin_uid": utils.chat_id_to_str(chat=m.chat), "slave_origin_display_name": "__chat__", "msg_type": m.type, "sent_to": "slave", "slave_message_id": None if m.edit else "%s.%s" % (self.FAIL_FLAG, int(time.time())), # Overwritten later if slave message ID exists "update": m.edit } # Store media related information to local database for tg_media_type in ('audio', 'animation', 'document', 'video', 'voice', 'video_note'): attachment = getattr(message, tg_media_type, None) if attachment: msg_log_d.update(media_type=tg_media_type, file_id=attachment.file_id, mime=attachment.mime_type) break if not msg_log_d.get('media_type', None): if getattr(message, 'sticker', None): msg_log_d.update(media_type='sticker', file_id=message.sticker.file_id, mime='image/webp') elif getattr(message, 'photo', None): attachment = message.photo[-1] msg_log_d.update(media_type=tg_media_type, file_id=attachment.file_id, mime='image/jpeg') if slave_msg: msg_log_d['slave_message_id'] = slave_msg.uid self.db.add_msg_log(**msg_log_d) if m.file: m.file.close()
def handle_msg(context): self.logger.debug(repr(context)) msg_element = context['message'] main_text: str = '' messages = [] qq_uid = context['user_id'] at_list = {} for i in range(len(msg_element)): msg_type = msg_element[i]['type'] msg_data = msg_element[i]['data'] if msg_type == 'text': main_text += msg_data['text'] elif msg_type == 'face': qq_face = int(msg_data['id']) if qq_face in qq_emoji_list: main_text += qq_emoji_list[qq_face] else: main_text += '\u2753' # ❓ elif msg_type == 'sface': main_text += '\u2753' # ❓ elif msg_type == 'at': # todo Recheck if bug exists g_id = context['group_id'] my_uid = self.get_qq_uid() self.logger.debug('My QQ uid: %s\n' 'QQ mentioned: %s\n', my_uid, msg_data['qq']) group_card = '' if str(msg_data['qq']) == 'all': group_card = 'all' else: member_info = self.coolq_api_query('get_group_member_info', group_id=g_id, user_id=msg_data['qq']) group_card = member_info['card'] if member_info['card'] != '' else member_info['nickname'] self.logger.debug('Group card: {}'.format(group_card)) substitution_begin = 0 substitution_end = 0 if main_text == '': substitution_begin = len(main_text) substitution_end = len(main_text) + len(group_card) + 1 main_text += '@{} '.format(group_card) else: substitution_begin = len(main_text) + 1 substitution_end = len(main_text) + len(group_card) + 2 main_text += ' @{} '.format(group_card) if str(my_uid) == str(msg_data['qq']) or str(msg_data['qq']) == 'all': at_list[(substitution_begin, substitution_end)] = EFBChat(self.channel).self() else: messages.extend(self.call_msg_decorator(msg_type, msg_data)) if main_text != "": messages.append(self.msg_decorator.qq_text_simple_wrapper(main_text, at_list)) uid: str = str(uuid.uuid4()) coolq_msg_id = context['message_id'] for i in range(len(messages)): if not isinstance(messages[i], EFBMsg): continue efb_msg = messages[i] efb_msg.uid = uid + '_' + str(coolq_msg_id) + '_' + str(i) # if qq_uid != '80000000': if 'anonymous' not in context or context['anonymous'] is None: remark = self.get_friend_remark(qq_uid) if context['message_type'] == 'group': if context['sub_type'] == 'notice': context['event_description'] = self._("System Notification") efb_msg.author = self.chat_manager.build_efb_chat_as_system_user(context) else: if remark is not None: context['nickname'] = remark g_id = context['group_id'] member_info = self.coolq_api_query('get_group_member_info', group_id=g_id, user_id=qq_uid) if member_info is not None: context['alias'] = member_info['card'] efb_msg.author: EFBChat = self.chat_manager.build_efb_chat_as_user(context, False) else: if context['message_type'] == 'private' or context['message_type'] == 'discuss': context['alias'] = remark efb_msg.author: EFBChat = self.chat_manager.build_efb_chat_as_user(context, False) else: # anonymous user in group efb_msg.author: EFBChat = self.chat_manager.build_efb_chat_as_anonymous_user(context) if context['message_type'] == 'private': efb_msg.chat: EFBChat = self.chat_manager.build_efb_chat_as_user(context, True) else: efb_msg.chat: EFBChat = self.chat_manager.build_efb_chat_as_group(context) # Append discuss group into group list if context['message_type'] == 'discuss' and efb_msg.chat not in self.discuss_list: self.discuss_list.append(efb_msg.chat) efb_msg.deliver_to = coordinator.master def send_message_wrapper(*args, **kwargs): threading.Thread(target=async_send_messages_to_master, args=args, kwargs=kwargs).start() send_message_wrapper(efb_msg)
def wxpy_chat_to_efb_chat(self, chat: wxpy.Chat, recursive=True) -> EFBChat: # self.logger.debug("Converting WXPY chat %r, %sin recursive mode", chat, '' if recursive else 'not ') # self.logger.debug("WXPY chat with ID: %s, name: %s, alias: %s;", chat.puid, chat.nick_name, chat.alias) if chat is None: return self.MISSING_USER if chat.puid in self.efb_chat_objs: return self.efb_chat_objs[chat.puid] efb_chat = EFBChat(self.channel) efb_chat.chat_uid = chat.puid or "__invalid__" efb_chat.chat_name = ews_utils.wechat_string_unescape(chat.nick_name) efb_chat.chat_alias = None efb_chat.chat_type = ChatType.System efb_chat.vendor_specific = {'is_mp': False} if isinstance(chat, wxpy.Member): efb_chat.chat_type = ChatType.User efb_chat.is_chat = False efb_chat.chat_alias = chat.name # self.logger.debug("[WXPY: %s] Display name: %s;", chat.puid, chat.display_name) if recursive: efb_chat.group = self.wxpy_chat_to_efb_chat(chat.group, False) elif isinstance(chat, wxpy.Group): efb_chat.chat_type = ChatType.Group for i in chat.members: efb_chat.members.append(self.wxpy_chat_to_efb_chat(i, False)) efb_chat.members[-1].group = efb_chat elif isinstance(chat, wxpy.MP): efb_chat.chat_type = ChatType.User efb_chat.vendor_specific['is_mp'] = True elif isinstance(chat, wxpy.User): efb_chat.chat_type = ChatType.User efb_chat.chat_alias = chat.remark_name or efb_chat.chat_alias # self.logger.debug("[WXPY: %s] Remark name: %s;", chat.puid, chat.remark_name) if chat == chat.bot.self: efb_chat.self() efb_chat.chat_alias = efb_chat.chat_alias and ews_utils.wechat_string_unescape( efb_chat.chat_alias) efb_chat.vendor_specific.update(self.generate_vendor_specific(chat)) if efb_chat.vendor_specific.get('is_muted', False): efb_chat.notification = EFBChatNotificationState.MENTIONS # self.logger.debug('WXPY chat %s converted to EFBChat %s', chat.puid, efb_chat) if chat.puid: self.efb_chat_objs[chat.puid] = efb_chat return efb_chat
def setUp(self): self.channel = MockMasterChannel() self.chat = EFBChat(self.channel) self.chat.chat_name = "Chat 0" self.chat.chat_uid = "0" self.chat.chat_type = ChatType.User
def test_normal_chat(self): chat = EFBChat() self.assertFalse(chat.is_self) self.assertFalse(chat.is_system)
def test_is_self(self): chat = EFBChat().self() self.assertTrue(chat.is_self)
def test_is_system(self): chat = EFBChat().system() self.assertTrue(chat.is_system)
def patch_chat_1(slave_channel): mocked_chat = EFBChat(slave_channel).self() mocked_chat.verify = mock.Mock() return mocked_chat
def wxpy_chat_to_efb_chat(self, chat: wxpy.Chat, recursive=True) -> Optional[EFBChat]: self.logger.debug("Converting WXPY chat %r, %sin recursive mode", chat, '' if recursive else 'not ') self.logger.debug("WXPY chat with ID: %s, name: %s, alias: %s;", chat.puid, chat.nick_name, chat.alias) if chat is None: return self.MISSING_USER efb_chat = EFBChat(self.channel) efb_chat.chat_uid = chat.puid or "__invalid__" efb_chat.chat_name = ews_utils.wechat_string_unescape(chat.nick_name) efb_chat.chat_alias = None efb_chat.chat_type = ChatType.System efb_chat.vendor_specific = {'is_mp': False, 'wxpy_object': chat} if isinstance(chat, wxpy.Member): efb_chat.chat_type = ChatType.User efb_chat.is_chat = False efb_chat.chat_alias = chat.display_name or efb_chat.chat_alias self.logger.debug("[WXPY: %s] Display name: %s;", chat.puid, chat.display_name) if recursive: efb_chat.group = self.wxpy_chat_to_efb_chat(chat.group, False) elif isinstance(chat, wxpy.Group): efb_chat.chat_type = ChatType.Group for i in chat.members: efb_chat.members.append(self.wxpy_chat_to_efb_chat(i, False)) efb_chat.members[-1].group = efb_chat elif isinstance(chat, wxpy.MP): efb_chat.chat_type = ChatType.User efb_chat.vendor_specific['is_mp'] = True elif isinstance(chat, wxpy.User): efb_chat.chat_type = ChatType.User efb_chat.chat_alias = chat.remark_name or efb_chat.chat_alias self.logger.debug("[WXPY: %s] Remark name: %s;", chat.puid, chat.remark_name) if chat == chat.bot.self: efb_chat.self() efb_chat.chat_alias = efb_chat.chat_alias and ews_utils.wechat_string_unescape(efb_chat.chat_alias) self.logger.debug('WXPY chat %s converted to EFBChat %s', chat.puid, efb_chat) return efb_chat