def render_expression(expr: Expression_T, *args, escape_args: bool = True, **kwargs) -> str: """ Render an expression to message string. :param expr: expression to render :param escape_args: should escape arguments or not :param args: positional arguments used in str.format() :param kwargs: keyword arguments used in str.format() :return: the rendered message """ result: str if callable(expr): result = expr(*args, **kwargs) elif isinstance(expr, Sequence) and not isinstance(expr, str): result = random.choice(expr) else: result = expr if escape_args: return result.format( *[escape(s) if isinstance(s, str) else s for s in args], **{ k: escape(v) if isinstance(v, str) else v for k, v in kwargs.items() }) return result.format(*args, **kwargs)
def as_cq_el(self, message: MessageElement) -> cq_message.MessageSegment: if isinstance(message, Raw): return cq_message.MessageSegment(type_=message.type, data=message.data) elif isinstance(message, raw_message.Plain): return cq_message.MessageSegment.text(message.text) elif isinstance(message, raw_message.At): return cq_message.MessageSegment.at(message.target) elif isinstance(message, raw_message.AtAll): return cq_message.MessageSegment(type_='at', data={'qq': 'all'}) elif isinstance(message, raw_message.Face): return cq_message.MessageSegment.face(message.id) elif isinstance(message, Image) and message.file: return cq_message.MessageSegment.image(message.file) elif isinstance(message, raw_message.Image): return cq_message.MessageSegment.image(message.url) elif isinstance(message, Voice): return cq_message.MessageSegment.record(message.file) elif isinstance(message, raw_message.Voice): return cq_message.MessageSegment.record(message.url) elif isinstance(message, raw_message.App): return cq_message.MessageSegment(type_='json', data={ 'data': cq_message.escape((json.dumps( message.content))) }) elif isinstance(message, raw_message.Xml): return cq_message.MessageSegment( type_='xml', data={'data': cq_message.escape(message.content)}) else: logger.debug(f'Unknown message {message} of type {type(message)}') return cq_message.MessageSegment.text('')
async def _(session: CommandSession): # 去掉消息首尾的空白符 stripped_arg = session.current_arg QQ = session.ctx['user_id'] #await session.send("调试中") if session.is_first_run: # 该命令第一次运行(第一次进入命令会话) #await session.send("第一次运行"+stripped_arg) if stripped_arg: # 第一次运行参数不为空,意味着用户直接将城市名跟在命令名后面,作为参数传入 # 通过封装的函数获取图灵机器人的回复 reply = await call_tuling_api(session, stripped_arg) if reply: # 如果调用机器人成功,得到了回复,则转义之后发送给用户 # 转义会把消息中的某些特殊字符做转换,以避免 酷Q 将它们理解为 CQ 码 session.state['message'] = escape(reply) #await session.send(escape(reply)) else: # 先把关键词存进去 sql = "UPDATE chat SET temp='" + stripped_arg + "' WHERE QQ='" + str( QQ) + "'" sql_dml(sql) await session.pause( "[CQ:at,qq=" + str(QQ) + "]对不起,小白不知道怎么回答,我应该怎么回答呢?(要以说为开头哦,如果需要发图片的话直接回复图片即可)") # 如果调用失败,或者它返回的内容我们目前处理不了,发送无法获取图灵回复时的「表达」 else: await session.send("[CQ:at,qq=" + str(QQ) + "]有事可以直接用小白加上你想对我说的话就可与了哦,我不是小爱同学,不需要唤醒") session.finish() return if stripped_arg: # 用户没有发送有效的城市名称(而是发送了空白字符),则提示重新输入 if stripped_arg.startswith("说") or "image" in stripped_arg: sql = "SELECT temp FROM chat WHERE QQ='" + str(QQ) + "'" result = sql_dql(sql) if "image" in stripped_arg or 'bface' in stripped_arg: if 'bface' in stripped_arg: file = stripped_arg else: file = download(stripped_arg[stripped_arg.find("url=") + 4:-1]) file = "[CQ:image,file=face/" + file + "]" key = result[0][0] + "-" + file else: key = result[0][0] + "-" + stripped_arg[1:] if addreplay(key): await session.send("[CQ:at,qq=" + str(QQ) + "]小白已成功学习到该回答!") session.finish() return # # 先找关键词 # sql = "SELECT lastchat FROM chat WHERE QQ='" + str(QQ) + "'" # result = sql_dql(sql) # file = result[0][0][1:] + "-" + file else: await session.send("[CQ:at,qq=" + str(QQ) + "]已忽略该回复") session.finish() return
async def tuling(session: CommandSession): message = session.state.get('message') reply = await call_tuling_api(session, message) if reply: await session.send(escape(reply)) else: await session.send(render_expression(EXPR_DONT_UNDERSTAND))
async def tuling(session: CommandSession): # 获取可选参数,这里如果没有 message 参数,命令不会被中断,message 变量会是 None message = session.state.get('message') user = session.ctx['user_id'] if user in LIMITATION_LIST.keys(): if LIMITATION_LIST[user] > 0: LIMITATION_LIST[user] = LIMITATION_LIST[user] - 1 else: await session.send('[debug] maximun number of requests reached for %i' % user) return else: LIMITATION_LIST[user] = 20 # 通过封装的函数获取图灵机器人的回复 reply = await call_tuling_api(session, message) match = re.search(pattern=r'http[:/\.\w]*', string=reply) if match is not None: reply = reply.replace(match.group(), 'https://www.ucas.ac.cn/') # await session.send('[debug] response via Turing api]') if reply: # 如果调用图灵机器人成功,得到了回复,则转义之后发送给用户 # 转义会把消息中的某些特殊字符做转换,以避免 酷Q 将它们理解为 CQ 码 await session.send(escape(reply)) else: # 如果调用失败,或者它返回的内容我们目前处理不了,发送无法获取图灵回复时的「表达」 # 这里的 render_expression() 函数会将一个「表达」渲染成一个字符串消息 await session.send('[debug] %s' % render_expression(EXPR_DONT_UNDERSTAND))
async def get_trap(session: CommandSession): ret = await generate_trap_url(session, 'music.163.com/song/532522915') if ret: await session.send( "请保存好key,并将音乐卡片转发给想获取ip的用户【请勿自己点击】,待用户点开音乐后使用'/getip'查询结果") await session.send(f"查询key: {ret[1]}") await session.send( get_xml_segment(escape(TRAP_XML_CODE.replace('[trap_url]', ret[0]))))
async def tuling(session: CommandSession): # 获取可选参数,这里如果没有 message 参数,命令不会被中断,message 变量会是 None message = session.state.get('message') # 通过封装的函数获取图灵机器人的回复 reply = await call_tuling_api(session, message) if reply and not reply == '请求次数超限制!': # 如果调用图灵机器人成功,得到了回复,则转义之后发送给用户 # 转义会把消息中的某些特殊字符做转换,以避免 酷Q 将它们理解为 CQ 码 await session.send(escape(reply)) else: # 如果调用失败,或者它返回的内容我们目前处理不了,发送无法获取图灵回复时的「表达」 # 当图灵机器人次数上限后,调用moli机器人,若moli无法完成对话,则将expression值返回给用户 # 这里的 render_expression() 函数会将一个「表达」渲染成一个字符串消息 result = await get_reply(message) if result: await session.send(escape(result)) else: await session.send(render_expression(EXPR_DONT_UNDERSTAND))
async def chat(session: CommandSession): message = session.state.get('message') if message.strip() == '': return reply = await AI.text_request(text=message) if reply: await session.send(escape(reply), at_sender=True) else: await session.send(render_expression(EXPR_DONT_UNDERSTAND), at_sender=True)
def render_expression(expr: Expression_T, *args, escape_args: bool = True, **kwargs) -> str: """ 渲染 Expression。 参数: expr (nonebot.typing.Expression_T): 要渲染的 Expression,对于 Expression 的三种类型: `str`、`Sequence[str]`、`(*Any, **Any) -> str`,行为分别是 - `str`: 以 `*args`、`**kwargs` 为参数,使用 `str.format()` 进行格式化 - `Sequence[str]`: 随机选择其中之一,进行上面 `str` 的操作 - `(*Any, **Any) -> str`: 以 `*args`、`**kwargs` 为参数,调用该可调用对象/函数,对返回的字符串进行上面 `str` 的操作 escape_args: 是否对渲染参数进行转义 args: 渲染参数 kwargs: 渲染参数 返回: str: 渲染出的消息字符串 用法: ```python msg1 = render_expression( ['你好,{username}!', '欢迎,{username}~'], username=username ) msg2 = render_expression('你所查询的城市是{}', city) ``` """ result: str if callable(expr): result = expr(*args, **kwargs) elif isinstance(expr, Sequence) and not isinstance(expr, str): result = random.choice(expr) else: result = expr if escape_args: return result.format( *[escape(s) if isinstance(s, str) else s for s in args], **{ k: escape(v) if isinstance(v, str) else v for k, v in kwargs.items() }) return result.format(*args, **kwargs)
async def robot(session: CommandSession): # 获取可选参数,这里如果没有 message 参数,命令不会被中断,message 变量会是 None message = session.state.get('message') # 通过封装的函数获取机器人的回复 reply = await call_tuling_api(session, message) if reply: # 如果调用机器人成功,得到了回复,则转义之后发送给用户 # 转义会把消息中的某些特殊字符做转换,以避免 酷Q 将它们理解为 CQ 码 await session.send(escape(reply), at_sender=True) return reply = await call_tencent_api(session, message) if reply: await session.send(escape(reply), at_sender=True) return # 如果调用失败,或者它返回的内容我们目前处理不了,发送无法获取回复时的「表达」 # 这里的 render_expression() 函数会将一个「表达」渲染成一个字符串消息 await session.send(render_expression(EXPR_DONT_UNDERSTAND), at_sender=True)
async def image_repeat(session: CommandSession): reply = session.get('image', prompt='waiting image transmission') if 'CQ:image' in reply and re.search(r'file=(.+?)[,|&#|\]]', reply): filename = re.search(r'file=(.+?)[,|&#|\]]', reply)[1] get_image_result = await session.bot.get_image(file=filename) await session.send('[CQ:image,file=%s]' % get_image_result['url']) await session.send('[debug]\n%s' % str(get_image_result)) else: await session.send('[debug] image not received') await session.send(escape(reply)) await session.send(reply)
async def tuling(session: CommandSession): message = session.state.get('message') at_msg = '' if session.ctx['message_type'] == 'group': at_msg = '[CQ:at,qq={}] '.format(str(session.ctx['user_id'])) reply = await get_content(message.strip()) if reply: await session.send(at_msg + escape(reply)) else: await session.send(render_expression(EXPR_DONT_UNDERSTAND))
async def image_ocr(session: CommandSession): reply = session.get('image', prompt='waiting image transmission') if 'CQ:image' in reply and re.search(r'file=(.+?)[,|&#|\]]', reply): filename = re.search(r'file=(.+?)[,|&#|\]]', reply)[1] get_image_result = await session.bot.get_image(file=filename) results = client.basicGeneralUrl(url=get_image_result['url'])['words_result'] string = '' for result in results: string += result['words'] await session.send(string) else: await session.send('[debug] image not received') await session.send(escape(reply)) await session.send(reply)
async def tuling(session: CommandSession): # 获取可选参数,这里如果没有 message 参数,命令不会被中断,message 变量会是 None message = session.state.get('message') print("tuling----", message) # 通过封装的函数获取图灵机器人的回复 reply = await call_tuling_api(session, message) if reply: # 如果调用图灵机器人成功,得到了回复,则转义之后发送给用户 # 转义会把消息中的某些特殊字符做转换,以避免 酷Q 将它们理解为 CQ 码 await session.send(escape(reply)) else: # 如果调用失败,或者它返回的内容我们目前处理不了,发送无法获取图灵回复时的「表达」 # 这里的 render_expression() 函数会将一个「表达」渲染成一个字符串消息 await session.send(render_expression(EXPR_DONT_UNDERSTAND))
async def ai_chat(session: CommandSession): # 获取可选参数,这里如果没有 message 参数,message 变量会是 None message = session.state.get('message') # 通过封装的函数获取腾讯智能机器人机器人的回复 reply = await call_tencent_bot_api(session, message) if reply: # 如果调用腾讯智能机器人成功,得到了回复,则转义之后发送给用户 # 转义会把消息中的某些特殊字符做转换,避免将它们理解为 CQ 码 await session.send(escape(reply)) else: # 如果调用失败,或者它返回的内容我们目前处理不了,发送无法获取腾讯智能机器人回复时的「表达」 # 这里的 render_expression() 函数会将一个「表达」渲染成一个字符串消息 await session.send(render_expression(EXPR_DONT_UNDERSTAND))
async def tuling(session: CommandSession): # 获取可选参数,这里如果没有 message 参数,命令不会被中断,message 变量会是 None message = session.get_optional('message') # 通过封装的函数获取图灵机器人的回复 reply = await call_tuling_api(session, message) if reply: # 如果调用图灵机器人成功,得到了回复,则转义之后发送给用户 # 转义会把消息中的某些特殊字符做转换,以避免酷 Q 将它们理解为 CQ 码 await session.send(escape(reply)) else: # 如果调用失败,或者它返回的内容我们目前处理不了,发送无法获取图灵回复时的「表达」 # session.send_expr() 内部会调用 none.expression.render() # 该函数会将一个「表达」渲染成一个字符串消息 await session.send_expr(EXPR_DONT_UNDERSTAND)
async def tuling(session: CommandSession): # 获取可选参数,这里如果没有 message 参数,命令不会被中断,message 变量会是 None message = session.state.get('message') imgurl = session.state.get('imgurl') msg = session.state.get('msg') print(msg) print("*" * 40) # print(msg) print(imgurl) if imgurl: # 获取图片返回的文字 s = await call_tupian_api(session, imgurl) # 有文字返回,爬取斗图网,搜索关键字 if s: # 调用回复内容,随机获取关键字 reply = await call_tuling_api(session, s) duanyu = jieba.lcut(reply) guanzijian = random.choice(duanyu) print(guanzijian) try: reply = await call_doutu_api(str(guanzijian)) reply = str(reply).split('\'')[1] # 图片链接 if reply: await session.send(f'[CQ:image,file={reply}]') # 没图片链接 else: await session.send(message=reply) except: await session.send(render_expression(EXPR_DONT_UNDERSTAND)) # 没文字,直接返回图片 else: await session.send(message=msg) # await session.send(message) # 通过封装的函数获取图灵机器人的回复 elif message: reply = await call_tuling_api(session, message) # 如果调用图灵机器人成功,得到了回复,则转义之后发送给用户 # 转义会把消息中的某些特殊字符做转换,以避免 酷Q 将它们理解为 CQ 码 if reply: await session.send(escape(reply)) else: await session.send(render_expression(EXPR_DONT_UNDERSTAND)) # await session.send(message) else: await session.send(message=msg)
async def NLP(session: CommandSession): # 获取可选参数,这里如果没有 message 参数,命令不会被中断,message 变量会是 None message = session.state.get('message') api = get_bot().config.NLP_API if api == 'tencent': reply = await tencent_api.call_NLP_api(session, message) elif api == 'itpk': reply = await itpk_api.call_NLP_api(session, message) else: logger.warning( "Invalid NLP api type. Please config them in config.py to enable NL conversation function." ) reply = "闲聊对话功能未启用,请使用'/help'查看可用命令" if reply: # 如果调用机器人成功,得到了回复,则转义之后发送给用户 await session.send(escape(reply))
async def tuling(session: CommandSession): message = session.get('message', prompt=__(e.I_AM_READY)) ctx_id = context_id(session.ctx) if ctx_id in tuling_sessions: del tuling_sessions[ctx_id] tmp_msg = Message(message) text = tmp_msg.extract_plain_text() images = [ s.data['url'] for s in tmp_msg if s.type == 'image' and 'url' in s.data ] # call tuling api replies = await call_tuling_api(session, text, images) logger.debug(f'Got tuling\'s replies: {replies}') if replies: for reply in replies: await session.send(escape(reply)) await asyncio.sleep(0.8) else: await session.send(__(e.I_DONT_UNDERSTAND)) one_time = session.get_optional('one_time', False) if one_time: # tuling123 may opened a session, we should recognize the # situation that tuling123 want more information from the user. # for simplification, we only recognize named entities, # and since we will also check the user's input later, # here we can allow some ambiguity. ne_type = tuling_ne_type(replies, { 'LOC': ('哪里', '哪儿', re.compile(r'哪\S城市'), '位置'), 'TIME': ('什么时候', ), }) if ne_type: logger.debug(f'One time call, ' f'and there is a tuling session for {ne_type}') tuling_sessions[ctx_id] = ne_type else: session.pause()
def render(expr: Union[str, Sequence[str], Callable], *, escape_args=True, **kwargs) -> str: """ Render an expression to message string. :param expr: expression to render :param escape_args: should escape arguments or not :param kwargs: keyword arguments used in str.format() :return: the rendered message """ if isinstance(expr, Callable): expr = expr(**kwargs) elif isinstance(expr, Sequence) and not isinstance(expr, str): expr = random.choice(expr) if escape_args: for k, v in kwargs.items(): if isinstance(v, str): kwargs[k] = message.escape(v) return expr.format(**kwargs)
async def call_response(session: CommandSession, text: str, number: int) -> Optional[str]: if not text: return None # 从数据库查询 sqlHelper = bot_speakExer() # if number == 0 and 1: #取消判断 测试一下 values = sqlHelper.selectQuestion(text.lstrip()) # else: ??? # values =bot_speakExer().selectQuestionForGroup(text) logger.debug('------------------values:' + str(values)) randomresult = 0 # 如果不存在 if not values: print('数据库中无该问题' + text) # 获取可选参数,这里如果没有 message 参数,命令不会被中断,message 变量会是 None message = text get_bot().seesion # 通过封装的函数获取图灵机器人的回复 reply = await chat.call_txchat_api(session, message) if reply: # 如果调用图灵机器人成功,得到了回复,则转义之后发送给用户 # 转义会把消息中的某些特殊字符做转换,以避免 酷Q 将它们理解为 CQ 码 time.sleep(2) return escape(reply) else: # 如果调用失败,或者它返回的内容我们目前处理不了,发送无法获取图灵回复时的「表达」 # 这里的 render_expression() 函数会将一个「表达」渲染成一个字符串消息 return session.send(render_expression(EXPR_DONT_UNDERSTAND)) else: # 如果很不只有一个 if len(values) != 1: randomresult = random.randint(0, len(values)) return str(values[randomresult].answer)
async def justSpeak(session: CommandSession): # 获取可选参数,这里如果没有 message 参数,命令不会被中断,message 变量会是 None message = session.state.get('message') # 获取回复 reply = await call_response(session, str(message), 0) if reply: await session.send(reply) else: # 获取可选参数,这里如果没有 message 参数,命令不会被中断,message 变量会是 None # 通过封装的函数获取图灵机器人的回复 reply = await chat.call_txchat_api(session, message) if reply: # 如果调用图灵机器人成功,得到了回复,则转义之后发送给用户 # 转义会把消息中的某些特殊字符做转换,以避免 酷Q 将它们理解为 CQ 码 time.sleep(2) return escape(reply) else: # 如果调用失败,或者它返回的内容我们目前处理不了,发送无法获取图灵回复时的「表达」 # 这里的 render_expression() 函数会将一个「表达」渲染成一个字符串消息 return session.send(render_expression(EXPR_DONT_UNDERSTAND))