async def weather(session: CommandSession): location = session.get('location', prompt=__(e.WHERE)) # time = session.get_optional('time') if location.province and not location.city and not location.district: # there is no city or district, ask the user for more info! session.get('location_more', prompt=__(e.WHERE_IN_PROVINCE, province=location.province)) final_loc = location.heweather_format() await session.send(f'位置:{final_loc}')
async def _(session: CommandSession): count = await note_count(context_id(session.ctx)) if count == 0: await session.send(__(e.LIST_EMPTY)) return all_notes = await Note.query.where( Note.context_id == context_id(session.ctx)).gino.all() for n in all_notes: await session.send(f'ID:{n.id}\r\n内容:{n.content}') await asyncio.sleep(0.8) await session.send(__(e.LIST_COMPLETE, count=count))
async def note_remove(session: CommandSession): ctx_id = context_id(session.ctx) count = await note_count(ctx_id) if count == 0: await session.send(__(e.LIST_EMPTY)) return id_ = session.get('id', prompt=__(e.DEL_WHICH_ID)) note_ = await Note.query.where((Note.context_id == ctx_id) & (Note.id == id_)).gino.first() if note_ is None: await session.send(__(e.DEL_ID_NOT_EXISTS, id=id_)) else: await note_.delete() await session.send(__(e.DEL_SUCCESS, id=id_, content=note_.content))
async def _(session: CommandSession): if session.current_key == 'message': text = session.current_arg_text.strip() if ('拜拜' in text or '再见' in text) and len(text) <= 4: session.finish(__(e.BYE_BYE)) return session.args[session.current_key] = session.current_arg
async def _(session: CommandSession): text = session.current_arg_text.strip() if session.is_first_run and text: # first run, and there is an argument, we take it as the id session.current_key = 'id' if session.current_key == 'id': id_ = None try: # try parse the text message as an id id_ = int(text) except ValueError: # it's not directly a number if not session.is_first_run: # we are in and interactive session, do nlp # user may want to ask for all notes, check it match_score = await nlp.sentence_similarity( session.current_arg_text.strip(), '现在有哪些呢?') if match_score > 0.70: # we think it matches await session.send(__(e.QUERYING_ALL)) # sleep to make conversation natural :) await asyncio.sleep(1) await call_command(session.bot, session.ctx, ('note', 'list'), check_perm=False, disable_interaction=True) # pause the session and wait for further interaction await session.pause() return # user may also put the id in a natural sentence, check it m = re.search(r'\d+', text) if m: possible_id = int(m.group(0)) match_score = await nlp.sentence_similarity( session.current_arg_text.strip(), f'删掉笔记{possible_id}') if match_score > 0.70: # we think it matches id_ = possible_id if id_ is not None: session.args['id'] = id_ else: session.pause(__(e.DEL_CANNOT_RECOGNIZE_ID))
async def _(session: NLPSession): if not session.msg: # empty message body nicks = list(session.bot.config.NICKNAME) if nicks: nick = nicks[0] else: nick = None await session.send(__(EXPR_ACK, nick=nick))
async def _(session: NoticeSession): if session.ctx['group_id'] not in (230697355, 519698575, 865640538): return try: info = await session.bot.get_group_member_info(**session.ctx, no_cache=True) name = info['card'] or info['nickname'] or '新成员' await session.send(__(GROUP_GREETING, name=name, **session.ctx)) except CQHttpError: pass
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()
async def lunch(session: CommandSession): where = ['去一食堂', '去二食堂', '吃日夜', '点外卖', '出去吃'] kind = ['面条', '饭', '炒饭', '早点', '砂锅'] next1 = session.get_optional('next1') next2 = session.get_optional('next2') if next1 is None: # 先随机一个去处,问可不可以 await session.send(__(EXPR_WAIT)) await asyncio.sleep(1) session.get('next1', prompt=random.choice(where) + '吧,' + __(EXPR_HOW)) if next2 is None and check_confirmation(next1) is not True: # 去处被否决 session.finish(__(EXPR_CANCEL)) # 去处 OK if next2 is None: session.get('next2', prompt=__(EXPR_REQU)) if check_confirmation(next2) is not True: session.finish(__(EXPR_CANCEL)) await asyncio.sleep(0.8) await session.send('经奶茶精选,今天' + random.choice(kind) + '与你更配哦🤔') await asyncio.sleep(0.3) await session.send(__(EXPR_EMOJI))
async def handle_cancellation(session: CommandSession) -> None: """ Handle cancellation instructions. If the current arg text is a cancellation instruction, the command session will be made finished, so that the command will no long be run. This function is present for manually calling through the process of a command's args parser, which means the args parser can do something before handle cancellation. On contrary, @allow_cancellation decorator will handle cancellation at the very beginning of the args parser. :param session: command session to handle """ if session.is_first_run: return # we are in an interactive session, waiting for user's input # handle possible cancellation # use current_arg_text, we don't mind losing rich text parts of message text = session.current_arg_text.strip() small_sentences = re.split(r'\W+', text) logger.debug(f'Split small sentences: {small_sentences}') should_cancel = False new_ctx_message = None for i, sentence in enumerate(filter(lambda x: x.strip(), small_sentences)): if await is_cancellation(sentence): logger.debug(f'Sentence "{sentence}" is a cancellation, continue') should_cancel = True continue # this small sentence is not a cancellation, we split before this new_ctx_message = ','.join(small_sentences[i:]).strip() break if should_cancel: if not new_ctx_message: session.finish(__(session.bot.config.SESSION_CANCEL_EXPRESSION)) else: session.switch(new_ctx_message)
async def weather(session: CommandSession): city = session.get('city', prompt=__(e.WHICH_CITY)) await session.send(__(e.REPORT, city=city))
async def note_add(session: CommandSession): content = session.get('content', prompt=__(e.ADD_WHAT_CONTENT)) new_note = await Note.create(content=content, context_id=context_id(session.ctx)) await session.send( __(e.ADD_SUCCESS, id=new_note.id, content=new_note.content))