Example #1
0
async def sched_list(session: CommandSession):
    job_id_prefix = scheduler.make_job_id(PLUGIN_NAME, context_id(session.ctx))
    jobs = await scheduler.get_jobs(
        scheduler.make_job_id(PLUGIN_NAME, context_id(session.ctx)))
    if not jobs:
        await session.send(f'你还没有添加过计划任务')
        return

    for job in jobs:
        await session.send(format_job(job.id[len(job_id_prefix):], job))
        await asyncio.sleep(0.8)
    await session.send_expr(f'以上是所有的 {len(jobs)} 个计划任务')
Example #2
0
async def _(session: CommandSession):
    count = await note_count(context_id(session.ctx))
    if count == 0:
        await session.send_expr(expr.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_expr(expr.LIST_COMPLETE, count=count)
Example #3
0
async def note_add(session: CommandSession):
    content = session.get('content', prompt_expr=expr.ADD_WHAT_CONTENT)
    new_note = await Note.create(content=content,
                                 context_id=context_id(session.ctx))
    await session.send_expr(expr.ADD_SUCCESS,
                            id=new_note.id,
                            content=new_note.content)
Example #4
0
async def _(session: NLPSession):
    confidence = None  # by default we don't return result

    if session.ctx['to_me']:
        # if the user is talking to us, we may consider reply to him/her
        confidence = 60.0

    ctx_id = context_id(session.ctx)
    if ctx_id in tuling_sessions:
        ne_type = tuling_sessions[ctx_id]
        lex_result = await nlp.lexer(session.msg_text)
        # we only mind the first paragraph
        words = lex_result[0] if lex_result else []
        for w in words:
            if ne_type == w['ne']:
                # if there is a tuling session existing,
                # and the user's input is exactly what tuling wants,
                # we are sure that the user is replying tuling
                confidence = 100.0 - len(words) * 5.0
                break

    if confidence:
        return NLPResult(confidence, 'tuling', {
            'message': session.msg,
            'one_time': True
        })
Example #5
0
async def call_tuling_api(
        session: BaseSession,
        text: Optional[str],
        image: Optional[Union[List[str], str]]) -> List[str]:
    url = 'http://openapi.tuling123.com/openapi/api/v2'
    payload = {
        'reqType': 0,
        'perception': {},
        'userInfo': {
            'apiKey': session.bot.config.TULING123_API_KEY,
            'userId': context_id(session.ctx, use_hash=True)
        }
    }

    group_unique_id = context_id(session.ctx, mode='group', use_hash=True)
    if group_unique_id:
        payload['userInfo']['groupId'] = group_unique_id

    if image and not isinstance(image, str):
        image = image[0]

    if text:
        payload['perception']['inputText'] = {'text': text}
        payload['reqType'] = 0
    elif image:
        payload['perception']['inputImage'] = {'url': image}
        payload['reqType'] = 1
    else:
        return []

    try:
        resp = await requests.post(url, json=payload)
        if resp.ok:
            resp_payload = await resp.json()
            if resp_payload.get('results'):
                return_list = []
                for result in resp_payload['results']:
                    res_type = result.get('resultType')
                    if res_type in ('text', 'url'):
                        return_list.append(result['values'][res_type])
                return return_list
        return []
    except (requests.RequestException, json.JSONDecodeError, KeyError):
        return []
Example #6
0
async def call_tuling_api(session: CommandSession, text: str) -> Optional[str]:
    # 调用图灵机器人的 API 获取回复

    if not text:
        return None

    url = 'http://openapi.tuling123.com/openapi/api/v2'

    # 构造请求数据
    payload = {
        'reqType': 0,
        'perception': {
            'inputText': {
                'text': text
            }
        },
        'userInfo': {
            'apiKey': session.bot.config.TULING_API_KEY,
            'userId': context_id(session.ctx, use_hash=True)
        }
    }

    group_unique_id = context_id(session.ctx, mode='group', use_hash=True)
    if group_unique_id:
        payload['userInfo']['groupId'] = group_unique_id

    try:
        # 使用 aiohttp 库发送最终的请求
        async with aiohttp.ClientSession() as sess:
            async with sess.post(url, json=payload) as response:
                if response.status != 200:
                    # 如果 HTTP 响应状态码不是 200,说明调用失败
                    return None

                resp_payload = json.loads(await response.text())
                if resp_payload['results']:
                    for result in resp_payload['results']:
                        if result['resultType'] == 'text':
                            # 返回文本类型的回复
                            return result['values']['text']
    except (aiohttp.ClientError, json.JSONDecodeError, KeyError):
        # 抛出上面任何异常,说明调用失败
        return None
Example #7
0
async def _(session: NLPSession):
    data = {
        'timestamp': [session.ctx['time']],
        'ctx_id': [context_id(session.ctx)],
        'self_id': [session.ctx['self_id']],
        'message': [str(session.ctx['message'])]
    }
    # we don't want to block the processing of message,
    # so just make sure it will append in the future
    asyncio.ensure_future(append_message(data))
Example #8
0
async def call_tuling_api(session: CommandSession, text: str) -> Optional[str]:
    # 调用图灵机器人的 API 获取回复

    if not text:
        return None

    url = 'http://openapi.tuling123.com/openapi/api/v2'

    # 构造请求数据
    payload = {
        'reqType': 0,
        'perception': {
            'inputText': {
                'text': text
            }
        },
        'userInfo': {
            'apiKey': session.bot.config.TULING_API_KEY,
            'userId': context_id(session.ctx, use_hash=True)
        }
    }

    group_unique_id = context_id(session.ctx, mode='group', use_hash=True)
    if group_unique_id:
        payload['userInfo']['groupId'] = group_unique_id

    try:
        # 使用 aiohttp 库发送最终的请求
        async with aiohttp.ClientSession() as sess:
            async with sess.post(url, json=payload) as response:
                if response.status != 200:
                    # 如果 HTTP 响应状态码不是 200,说明调用失败
                    return None

                resp_payload = json.loads(await response.text())
                if resp_payload['results']:
                    for result in resp_payload['results']:
                        if result['resultType'] == 'text':
                            # 返回文本类型的回复
                            return result['values']['text']
    except (aiohttp.ClientError, json.JSONDecodeError, KeyError):
        # 抛出上面任何异常,说明调用失败
        return None
Example #9
0
async def sched_remove(session: CommandSession):
    parser = ArgumentParser()
    parser.add_argument('name')
    args = await parse_args(session,
                            parser,
                            argv=session.get_optional('argv'),
                            help_msg=sched_remove_help)
    ok = await scheduler.remove_job(
        scheduler.make_job_id(PLUGIN_NAME, context_id(session.ctx), args.name))
    if ok:
        await session.send(f'成功删除计划任务 {args.name}')
    else:
        await session.send(f'没有找到计划任务 {args.name},请检查你的输入是否正确')
Example #10
0
async def sched_get(session: CommandSession):
    parser = ArgumentParser()
    parser.add_argument('name')
    args = await parse_args(session,
                            parser,
                            argv=session.get_optional('argv'),
                            help_msg=sched_get_help)
    job = await scheduler.get_job(
        scheduler.make_job_id(PLUGIN_NAME, context_id(session.ctx), args.name))
    if not job:
        await session.send(f'没有找到计划任务 {args.name},请检查你的输入是否正确')
        return

    await session.send('找到计划任务如下')
    await session.send(format_job(args.name, job))
Example #11
0
async def note_remove(session: CommandSession):
    ctx_id = context_id(session.ctx)
    count = await note_count(ctx_id)
    if count == 0:
        await session.send_expr(expr.LIST_EMPTY)
        return

    id_ = session.get('id', prompt_expr=expr.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_expr(expr.DEL_ID_NOT_EXISTS, id=id_)
    else:
        await note_.delete()
        await session.send_expr(expr.DEL_SUCCESS,
                                id=id_,
                                content=note_.content)
Example #12
0
async def tuling(session: CommandSession):
    message = session.get('message', prompt_expr=expr.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_expr(expr.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()
Example #13
0
async def sched_add(session: CommandSession):
    parser = ArgumentParser()
    parser.add_argument('-S', '--second')
    parser.add_argument('-M', '--minute')
    parser.add_argument('-H', '--hour')
    parser.add_argument('-d', '--day')
    parser.add_argument('-m', '--month')
    parser.add_argument('-w', '--day-of-week')
    parser.add_argument('-f', '--force', action='store_true', default=False)
    parser.add_argument('-v', '--verbose', action='store_true', default=False)
    parser.add_argument('--name', required=True)
    parser.add_argument('commands', nargs='+')

    args = await parse_args(session,
                            parser,
                            argv=session.get_optional('argv'),
                            help_msg=sched_add_help)

    if not re.match(r'[_a-zA-Z][_a-zA-Z0-9]*', args.name):
        await session.send('计划任务名必须仅包含字母、数字、下划线,且以字母或下划线开头')
        return

    parsed_commands: List[ScheduledCommand] = []
    invalid_commands: List[str] = []

    if args.verbose:
        parsed_commands.append(
            ScheduledCommand(('echo', ), f'开始执行计划任务 {args.name}……'))

    for cmd_str in args.commands:
        cmd, current_arg = parse_command(session.bot, cmd_str)
        if cmd:
            tmp_session = CommandSession(session.bot,
                                         session.ctx,
                                         cmd,
                                         current_arg=current_arg)
            if await cmd.run(tmp_session, dry=True):
                parsed_commands.append(ScheduledCommand(cmd.name, current_arg))
                continue
        invalid_commands.append(cmd_str)
    if invalid_commands:
        invalid_commands_joined = '\n'.join(
            [f'- {c}' for c in invalid_commands])
        await session.send(f'计划任务添加失败,'
                           f'因为下面的 {len(invalid_commands)} 个命令无法被运行'
                           f'(命令不存在或权限不够):\n'
                           f'{invalid_commands_joined}')
        return

    trigger_args = {
        k: v
        for k, v in args.__dict__.items()
        if k in {'second', 'minute', 'hour', 'day', 'month', 'day_of_week'}
    }
    try:
        job = await scheduler.add_scheduled_commands(
            parsed_commands,
            job_id=scheduler.make_job_id(PLUGIN_NAME, context_id(session.ctx),
                                         args.name),
            ctx=session.ctx,
            trigger='cron',
            **trigger_args,
            replace_existing=args.force)
    except scheduler.JobIdConflictError:
        # a job with same name exists
        await session.send(f'计划任务 {args.name} 已存在,' f'若要覆盖请使用 --force 参数')
        return

    await session.send(f'计划任务 {args.name} 添加成功')
    await session.send(format_job(args.name, job))