Exemplo n.º 1
0
async def handle_admin_mail_bind(bot: Bot, event: GroupMessageEvent,
                                 state: T_State):
    mailbox_list = state['mailbox_list']
    email_address = state['email_address']

    if email_address not in mailbox_list:
        logger.warning(
            f'Group:{event.group_id}/User:{event.user_id} 绑定邮箱: {email_address} 失败, 不在可绑定邮箱中的邮箱'
        )
        await admin_mail_bind.finish('该邮箱不在可绑定邮箱中!')

    group_id = event.group_id
    res = DBGroup(group_id=group_id).mailbox_add(mailbox=DBEmailBox(
        address=email_address))

    if res.success():
        logger.info(
            f'Group:{event.group_id}/User:{event.user_id} 绑定邮箱: {email_address} 成功'
        )
        await admin_mail_bind.finish('Success! 绑定成功')
    else:
        logger.error(
            f'Group:{event.group_id}/User:{event.user_id} 绑定邮箱: {email_address} 失败, error: {res.info}'
        )
        await admin_mail_bind.finish('绑定邮箱失败QAQ, 请检联系管理员处理')
Exemplo n.º 2
0
 async def get_result(__url: str, paras: dict) -> dict:
     timeout_count = 0
     while timeout_count < 3:
         try:
             timeout = aiohttp.ClientTimeout(total=10)
             async with aiohttp.ClientSession(timeout=timeout) as __session:
                 headers = {
                     'user-agent':
                     'Mozilla/5.0 (Windows NT 10.0; Win64; x64) '
                     'AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36'
                 }
                 async with __session.get(url=__url,
                                          params=paras,
                                          headers=headers,
                                          timeout=timeout) as resp:
                     json = await resp.json()
             return json
         except Exception as e:
             error_info = f'{repr(e)} Occurred in get_result trying {timeout_count + 1} using paras: {paras}'
             logger.info(error_info)
         finally:
             timeout_count += 1
     else:
         error_info = f'Failed too many times in get_result using paras: {paras}'
         logger.warning(error_info)
         return {'header': {'status': 1}, 'results': []}
Exemplo n.º 3
0
 async def fetch_new_post(
         self, _: Target,
         users: list[User]) -> list[tuple[User, list[Post]]]:
     try:
         config = Config()
         post_list = await self.get_sub_list()
         new_posts = await self.filter_common(post_list)
         res: list[tuple[User, list[Post]]] = []
         if not new_posts:
             return []
         else:
             for post in new_posts:
                 logger.info('fetch new post from {}: {}'.format(
                     self.platform_name, self.get_id(post)))
         for user in users:
             required_tags = config.get_sub_tags(
                 self.platform_name, 'default', user.user_type,
                 user.user) if self.enable_tag else []
             cats = config.get_sub_category(self.platform_name, 'default',
                                            user.user_type, user.user)
             user_raw_post = await self.filter_user_custom(
                 new_posts, cats, required_tags)
             user_post: list[Post] = []
             for raw_post in user_raw_post:
                 user_post.append(await self._parse_with_cache(raw_post))
             res.append((user, user_post))
         self.cache = {}
         return res
     except httpx.RequestError as err:
         logger.warning("network connection error: {}, url: {}".format(
             type(err), err.request.url))
         return []
Exemplo n.º 4
0
 async def get_ascii2d_redirects(_url: str) -> dict:
     timeout_count = 0
     while timeout_count < 3:
         try:
             timeout = aiohttp.ClientTimeout(total=10)
             async with aiohttp.ClientSession(timeout=timeout) as __session:
                 headers = {
                     'user-agent':
                     'Mozilla/5.0 (Windows NT 10.0; Win64; x64) '
                     'AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36',
                     'accept-language': 'zh-CN,zh;q=0.9'
                 }
                 async with __session.get(url=_url,
                                          headers=headers,
                                          timeout=timeout,
                                          allow_redirects=False) as resp:
                     res_headers = resp.headers
                     res_dict = {'error': False, 'body': dict(res_headers)}
             return res_dict
         except Exception as e:
             error_info = f'{repr(e)} Occurred in get_ascii2d_redirects trying {timeout_count + 1} using url: {_url}'
             logger.info(error_info)
         finally:
             timeout_count += 1
     else:
         error_info = f'Failed too many times in get_result using url: {_url}'
         logger.warning(error_info)
         return {'error': True, 'body': None}
Exemplo n.º 5
0
 async def get_ascii2d_result(__url: str) -> str:
     timeout_count = 0
     while timeout_count < 3:
         try:
             timeout = aiohttp.ClientTimeout(total=10)
             async with aiohttp.ClientSession(timeout=timeout) as __session:
                 headers = {
                     'user-agent':
                     'Mozilla/5.0 (Windows NT 10.0; Win64; x64) '
                     'AppleWebKit/537.36 (KHTML, like Gecko) '
                     'Chrome/83.0.4103.116 Safari/537.36',
                     'accept-language':
                     'zh-CN,zh;q=0.9'
                 }
                 async with __session.get(url=__url,
                                          headers=headers,
                                          timeout=timeout) as resp:
                     res_headers = await resp.text()
             return res_headers
         except Exception as e:
             error_info = f'{repr(e)} Occurred in get_ascii2d_result trying {timeout_count + 1} using url: {__url}'
             logger.info(error_info)
         finally:
             timeout_count += 1
     else:
         error_info = f'Failed too many times in get_result using url: {__url}'
         logger.warning(error_info)
         return ''
Exemplo n.º 6
0
async def handle_announce(bot: Bot, event: Event, state: T_State):
    group = state['group']
    msg = state['announce_text']
    if group == 'all':
        t = DBTable(table_name='Group')
        for item in t.list_col('group_id').result:
            group_id = item[0]
            await bot.call_api(api='send_group_msg', group_id=group_id, message=msg)
    elif group == 'notice':
        t = DBTable(table_name='Group')
        for item in t.list_col_with_condition('group_id', 'notice_permissions', 1).result:
            group_id = item[0]
            await bot.call_api(api='send_group_msg', group_id=group_id, message=msg)
    elif group == 'command':
        t = DBTable(table_name='Group')
        for item in t.list_col_with_condition('group_id', 'command_permissions', 1).result:
            group_id = item[0]
            await bot.call_api(api='send_group_msg', group_id=group_id, message=msg)
    elif re.match(r'^\d+$', group):
        group_id = int(group)
        await bot.call_api(api='send_group_msg', group_id=group_id, message=msg)
    else:
        logger.warning(f'公告未发送, 不合规的群组类型或群号: {group}')
        await announce.finish('不合规的群组类型或群号')
    logger.warning(f'公告已成功发送群组: {group}')
    await announce.finish('公告发送完成')
Exemplo n.º 7
0
 async def get_image(pic_url: str):
     timeout_count = 0
     while timeout_count < 3:
         try:
             timeout = aiohttp.ClientTimeout(total=10)
             async with aiohttp.ClientSession(timeout=timeout) as session:
                 headers = {
                     'user-agent':
                     'Mozilla/5.0 (Windows NT 10.0; Win64; x64) '
                     'AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36'
                 }
                 async with session.get(url=pic_url,
                                        headers=headers,
                                        timeout=timeout) as resp:
                     _res = await resp.read()
             return _res
         except Exception as _e:
             error_info = f'{repr(_e)} Occurred in get_image trying {timeout_count + 1} using paras: {pic_url}'
             logger.info(error_info)
         finally:
             timeout_count += 1
     else:
         error_info = f'Failed too many times in get_image using paras: {pic_url}'
         logger.warning(error_info)
         return None
Exemplo n.º 8
0
async def delete_msg(msg_ids: list):
    bot = nonebot.get_bot()
    for msg_id in msg_ids:
        try:
            await bot.call_action("delete_msg", message_id=msg_id["message_id"])
        except Exception as e:
            logger.warning("下载进度消息撤回失败!", e)
Exemplo n.º 9
0
async def handle_admin_mail_add(bot: Bot, event: MessageEvent, state: T_State):
    address = state['address']
    server_host = state['server_host']
    password = state['password']

    check_result = await check_mailbox(address=address,
                                       server_host=server_host,
                                       password=password)
    if not check_result.success():
        logger.warning(
            f'{event.user_id} 添加邮箱: {address} 失败, 邮箱验证不通过, error: {check_result.info}'
        )
        await admin_mail_add.finish('验证邮箱失败了QAQ, 请检查邮箱信息或稍后再试')

    # 对密码加密保存
    password = encrypt_password(plaintext=password)
    add_result = DBEmailBox(address=address).add(server_host=server_host,
                                                 password=password)

    if add_result.success():
        logger.info(f'{event.user_id} 添加邮箱: {address} 成功')
        await admin_mail_add.finish('Success! 邮箱添加成功')
    else:
        logger.error(
            f'{event.user_id} 添加邮箱: {address} 失败, 数据库写入失败, error: {add_result.info}'
        )
        await admin_mail_add.finish('邮箱添加失败QAQ, 请检联系管理员处理')
Exemplo n.º 10
0
async def handle_moepic(bot: Bot, event: GroupMessageEvent, state: T_State):
    tags = state['tags']
    if tags:
        _res_list = list()
        for tag in tags:
            _res = DBPixivillust.list_illust(nsfw_tag=0, keyword=tag)
            if _res.success():
                _pids = set(_res.result)
                _res_list.append(_pids)
        if len(_res_list) > 1:
            # 处理tag交集, 同时满足所有tag
            for item in _res_list[1:]:
                _res_list[0].intersection_update(item)
            pid_list = _res_list[0]
        elif len(_res_list) == 1:
            pid_list = _res_list[0]
        else:
            pid_list = _res_list
    else:
        # 没有tag则随机获取
        pid_list = DBPixivillust.rand_illust(num=3, nsfw_tag=0)

    if not pid_list:
        logger.info(
            f"Group: {event.group_id}, User: {event.user_id} 没有找到他/她想要的萌图")
        await moepic.finish('找不到萌图QAQ')
    elif len(pid_list) > 3:
        pid_list = random.sample(pid_list, k=3)

    await moepic.send('稍等, 正在下载图片~')
    # 处理article中图片内容
    tasks = []
    for pid in pid_list:
        tasks.append(fetch_illust_b64(pid=pid))
    p_res = await asyncio.gather(*tasks)
    fault_count = 0
    for image_res in p_res:
        try:
            if not image_res.success():
                fault_count += 1
                logger.warning(f'图片下载失败, error: {image_res.info}')
                continue
            else:
                img_seg = MessageSegment.image(image_res.result)
            # 发送图片
            await moepic.send(img_seg)
        except Exception as e:
            logger.warning(
                f"图片发送失败, group: {event.group_id}. error: {repr(e)}")
            continue

    if fault_count == len(pid_list):
        logger.info(
            f"Group: {event.group_id}, User: {event.user_id} 没能看到他/她想要的萌图")
        await moepic.finish('似乎出现了网络问题, 所有的图片都下载失败了QAQ')
    else:
        logger.info(
            f"Group: {event.group_id}, User: {event.user_id} 找到了他/她想要的萌图")
Exemplo n.º 11
0
async def handle_draw(bot: Bot, event: GroupMessageEvent, state: T_State):
    image_url = state['image_url']
    if not re.match(r'^(\[CQ:image,file=[abcdef\d]{32}\.image,url=.+])',
                    image_url):
        await search_image.reject('你发送的似乎不是图片呢, 请重新发送, 取消命令请发送【取消】:')

    # 提取图片url
    image_url = re.sub(r'^(\[CQ:image,file=[abcdef\d]{32}\.image,url=)', '',
                       image_url)
    image_url = re.sub(r'(])$', '', image_url)

    try:
        await search_image.send('获取识别结果中, 请稍后~')
        identify_result = await get_identify_result(url=image_url)
        # saucenao 没有结果时再使用 ascii2d 进行搜索
        if not identify_result:
            identify_ascii2d_result = await get_ascii2d_identify_result(
                url=image_url)
            # 合并搜索结果
            identify_result.extend(identify_ascii2d_result)
        if identify_result:
            for item in identify_result:
                try:
                    if type(item['ext_urls']) == list:
                        ext_urls = ''
                        for urls in item['ext_urls']:
                            ext_urls += f'{urls}\n'
                        ext_urls = ext_urls.strip()
                    else:
                        ext_urls = item['ext_urls']
                        ext_urls = ext_urls.strip()
                    img_b64 = await pic_2_base64(item['thumbnail'])
                    if not img_b64.success():
                        msg = f"识别结果: {item['index_name']}\n\n相似度: {item['similarity']}\n资源链接: {ext_urls}"
                        await search_image.send(msg)
                    else:
                        img_seg = MessageSegment.image(img_b64.result)
                        msg = f"识别结果: {item['index_name']}\n\n相似度: {item['similarity']}\n资源链接: {ext_urls}\n{img_seg}"
                        await search_image.send(Message(msg))
                except Exception as e:
                    logger.warning(f'处理和发送识别结果时发生了错误: {repr(e)}')
                    continue
            logger.info(f"Group: {event.group_id}, user: {event.user_id} "
                        f"使用searchimage成功搜索了一张图片")
            return
        else:
            await search_image.send('没有找到相似度足够高的图片QAQ')
            logger.info(f"Group: {event.group_id}, user: {event.user_id} "
                        f"使用了searchimage, 但没有找到相似的图片")
            return
    except Exception as e:
        await search_image.send('识图失败, 发生了意外的错误QAQ')
        logger.error(f"Group: {event.group_id}, user: {event.user_id}  "
                     f"使用命令searchimage时发生了错误: {repr(e)}")
        return
Exemplo n.º 12
0
async def group_upgrade(bot: Bot, event: GroupMessageEvent, state: T_State) -> Result:
    group_id = event.group_id
    # 调用api获取群信息
    group_info = await bot.call_api(api='get_group_info', group_id=group_id)
    group_name = group_info['group_name']
    group = DBGroup(group_id=group_id)

    # 添加并初始化群信息
    _result = group.add(name=group_name)
    if not _result.success():
        return Result(True, _result.info, -1)

    # 更新用户
    group_member_list = await bot.call_api(api='get_group_member_list', group_id=group_id)
    failed_user = []

    # 首先清除数据库中退群成员
    exist_member_list = []
    for user_info in group_member_list:
        user_qq = user_info['user_id']
        exist_member_list.append(int(user_qq))

    db_member_list = []
    for user_id, nickname in group.member_list().result:
        db_member_list.append(user_id)
    del_member_list = list(set(db_member_list).difference(set(exist_member_list)))

    for user_id in del_member_list:
        group.member_del(user=DBUser(user_id=user_id))

    # 更新群成员
    for user_info in group_member_list:
        # 用户信息
        user_qq = user_info['user_id']
        user_nickname = user_info['nickname']
        user_group_nickmane = user_info['card']
        if not user_group_nickmane:
            user_group_nickmane = user_nickname

        _user = DBUser(user_id=user_qq)
        _result = _user.add(nickname=user_nickname)
        if not _result.success():
            failed_user.append(_user.qq)
            logger.warning(f'User: {user_qq}, {_result.info}')
            continue

        _result = group.member_add(user=_user, user_group_nickname=user_group_nickmane)
        if not _result.success():
            failed_user.append(_user.qq)
            logger.warning(f'User: {user_qq}, {_result.info}')

    group.init_member_status()

    return Result(False, f'Success with ignore user: {failed_user}', 0)
Exemplo n.º 13
0
 def update(self):
     importlib.reload(_pcr_data)
     self._roster.clear()
     for idx, names in _pcr_data.CHARA_NAME.items():
         for n in names:
             n = util.normalize_str(n)
             if n not in self._roster:
                 self._roster[n] = idx
             else:
                 logger.warning(
                     f'priconne.chara.Roster: 出现重名{n}于id{idx}与id{self._roster[n]}'
                 )
     self._all_name_list = self._roster.keys()
Exemplo n.º 14
0
async def refresh_group_info():
    from nonebot import get_bots

    for bot_id, bot in get_bots().items():
        group_list = await bot.call_api('get_group_list')
        for group in group_list:
            group_id = group.get('group_id')
            # 调用api获取群信息
            group_info = await bot.call_api(api='get_group_info', group_id=group_id)
            group_name = group_info['group_name']
            group = DBGroup(group_id=group_id)

            # 添加并初始化群信息
            group.add(name=group_name)

            # 更新用户
            group_member_list = await bot.call_api(api='get_group_member_list', group_id=group_id)

            # 首先清除数据库中退群成员
            exist_member_list = []
            for user_info in group_member_list:
                user_qq = user_info['user_id']
                exist_member_list.append(int(user_qq))

            db_member_list = []
            for user_id, nickname in group.member_list().result:
                db_member_list.append(user_id)
            del_member_list = list(set(db_member_list).difference(set(exist_member_list)))

            for user_id in del_member_list:
                group.member_del(user=DBUser(user_id=user_id))

            # 更新群成员
            for user_info in group_member_list:
                # 用户信息
                user_qq = user_info['user_id']
                user_nickname = user_info['nickname']
                user_group_nickmane = user_info['card']
                if not user_group_nickmane:
                    user_group_nickmane = user_nickname
                _user = DBUser(user_id=user_qq)
                _result = _user.add(nickname=user_nickname)
                if not _result.success():
                    logger.warning(f'Refresh group info, User: {user_qq}, {_result.info}')
                    continue
                _result = group.member_add(user=_user, user_group_nickname=user_group_nickmane)
                if not _result.success():
                    logger.warning(f'Refresh group info, User: {user_qq}, {_result.info}')

            group.init_member_status()
            logger.info(f'Refresh group info completed, Bot: {bot_id}, Group: {group_id}')
Exemplo n.º 15
0
async def group_init(bot: Bot, event: GroupMessageEvent, state: T_State) -> Result:
    group_id = event.group_id
    # 调用api获取群信息
    group_info = await bot.call_api(api='get_group_info', group_id=group_id)
    group_name = group_info['group_name']
    group = DBGroup(group_id=group_id)

    # 添加并初始化群信息
    _result = group.add(name=group_name)
    if not _result.success():
        return Result(True, _result.info, -1)

    _result = group.permission_set(notice=1, command=1, level=10)
    if not _result.success():
        return Result(True, _result.info, -1)

    _result = group.member_clear()
    if not _result.success():
        return Result(True, _result.info, -1)

    # 添加用户
    group_member_list = await bot.call_api(api='get_group_member_list', group_id=group_id)
    failed_user = []
    for user_info in group_member_list:
        # 用户信息
        user_qq = user_info['user_id']
        user_nickname = user_info['nickname']
        user_group_nickmane = user_info['card']
        if not user_group_nickmane:
            user_group_nickmane = user_nickname

        _user = DBUser(user_id=user_qq)
        _result = _user.add(nickname=user_nickname)
        if not _result.success():
            failed_user.append(_user.qq)
            logger.warning(f'User: {user_qq}, {_result.info}')
            continue

        _result = group.member_add(user=_user, user_group_nickname=user_group_nickmane)
        if not _result.success():
            failed_user.append(_user.qq)
            logger.warning(f'User: {user_qq}, {_result.info}')

    group.init_member_status()

    return Result(False, f'Success with ignore user: {failed_user}', 0)
Exemplo n.º 16
0
async def check_down_status(hash_str: str, group_ids: list, name: str):
    qb = await get_qb_client()
    if not qb:
        return
    info = qb.get_torrent(hash_str)
    files = qb.get_torrent_files(hash_str)
    bot = nonebot.get_bot()
    if info["total_downloaded"] - info["total_size"] >= 0.000000:
        all_time = (datetime.datetime.now() - down_info[hash_str]["start_time"]).seconds
        await send_msg(f"👏 {name}\nHash: {hash_str} \n下载完成!耗时:{all_time} s")
        down_info[hash_str]["status"] = DOWN_STATUS_UPLOADING
        for group_id in group_ids:
            for tmp in files:
                # 异常包起来防止超时报错导致后续不执行
                try:
                    if config.qb_down_path and len(config.qb_down_path) > 0:
                        path = config.qb_down_path + tmp["name"]
                    else:
                        path = info["save_path"] + tmp["name"]
                    await send_msg(f"{name}\nHash: {hash_str} \n开始上传到群:{group_id}")
                    try:
                        await bot.call_action(
                        action="upload_group_file",
                            group_id=group_id,
                            file=path,
                            name=tmp["name"],
                        )
                    except Exception as e:
                        await send_msg(
                            f"{name}\nHash: {hash_str} \n上传到群:{group_id}失败!请手动上传!"
                        )
                        logger.error(e)
                except TimeoutError as e:
                    logger.warning(e)
        scheduler.remove_job(hash_str)
        down_info[hash_str]["status"] = DOWN_STATUS_UPLOAD_OK
    else:
        await delete_msg(down_info[hash_str]["downing_tips_msg_id"])
        msg_id = await send_msg(
            f"{name}\n"
            f"Hash: {hash_str} \n"
            f"下载了 {round(info['total_downloaded'] / info['total_size'] * 100, 2)}%\n"
            f"平均下载速度:{round(info['dl_speed_avg'] / 1024, 2)} KB/s"
        )
        down_info[hash_str]["downing_tips_msg_id"] = msg_id
Exemplo n.º 17
0
async def get_identify_result(img_url: str) -> Result:
    payload = {'url': img_url}
    result_json = await fetch_json(url=API_URL, paras=payload)
    if not result_json.success():
        return result_json

    _res = result_json.result
    if not _res.get('docs'):
        return Result(error=True, info='no result found', result=[])

    _result = []
    for item in _res.get('docs'):
        try:
            if item.get('similarity') < 0.80:
                continue
            _result.append({
                'raw_at':
                item.get('at'),
                'at':
                str(datetime.timedelta(seconds=item.get('at'))),
                'anilist_id':
                item.get('anilist_id'),
                'anime':
                item.get('anime'),
                'episode':
                item.get('episode'),
                'tokenthumb':
                item.get('tokenthumb'),
                'filename':
                item.get('filename'),
                'similarity':
                item.get('similarity'),
                'title_native':
                item.get('title_native'),
                'title_chinese':
                item.get('title_chinese'),
                'is_adult':
                item.get('is_adult'),
            })
        except Exception as e:
            logger.warning(f'result parse failed: {repr(e)}, raw_json: {item}')
            continue

    return Result(error=False, info='Success', result=_result)
Exemplo n.º 18
0
async def fetch_and_send(target_type: str):
    config = Config()
    target = config.get_next_target(target_type)
    if not target:
        return
    logger.debug('try to fecth new posts from {}, target: {}'.format(
        target_type, target))
    send_list = config.target_user_cache[target_type][target]
    bot_list = list(nonebot.get_bots().values())
    bot = bot_list[0] if bot_list else None
    to_send = await platform_manager[target_type].fetch_new_post(
        target, send_list)
    for user, send_list in to_send:
        for send_post in send_list:
            logger.debug('send to {}: {}'.format(user, send_post))
            if not bot:
                logger.warning('no bot connected')
            else:
                send_msgs(bot, user.user, user.user_type, await
                          send_post.generate_messages())
Exemplo n.º 19
0
async def do_send_msgs():
    global LAST_SEND_TIME
    if time.time() - LAST_SEND_TIME < 1.4:
        return
    if QUEUE:
        bot, user, user_type, msg, retry_time = QUEUE.pop(0)
        try:
            if user_type == 'group':
                await bot.call_api('send_group_msg',
                                   group_id=user,
                                   message=msg)
            elif user_type == 'private':
                await bot.call_api('send_private_msg',
                                   user_id=user,
                                   message=msg)
        except:
            if retry_time > 0:
                QUEUE.insert(0, (bot, user, user_type, msg, retry_time - 1))
            else:
                logger.warning('send msg err {}'.format(msg))
        LAST_SEND_TIME = time.time()
Exemplo n.º 20
0
def get_image(game_name: str, item_name: str) -> Image.Image:
    """获取图像,从本地或网络"""
    # 本地是否存在资源
    try:
        return R.img(f'gacha/{game_name}/{item_name}.png').open().convert(
            "RGBA")
    except FileNotFoundError:
        logger.warning(f'没有在本地找到"{item_name}",将试图从网络获取。')

    # 检查本地是否存在对应文件夹
    game_dir = os.path.join(RES_DIR, game_name)
    if not os.path.exists(game_dir):
        os.makedirs(game_dir)

    # 从卡片信息找到图像url
    url = [i for i in CONFIG['game_name']['cards'] if i.name == item_name]
    if not url:
        raise ValueError(f'找不到{item_name}')
    url = url[0]

    # 保存到本地
    save_path = os.path.join(game_dir, f'{item_name}.png')
    download_icon(url, save_path)
    return Image.open(save_path).convert("RGBA")
Exemplo n.º 21
0
async def handle_nhentai(bot: Bot, event: GroupMessageEvent, state: T_State):
    sub_command = state["sub_command"]
    sub_arg = state["sub_arg"]
    if sub_command not in ['search', 'download']:
        await nhentai.finish('没有这个命令哦QAQ')

    if sub_command == 'search':
        _res = await nh_search(tag=sub_arg)
        if _res.success():
            nh_list = list(_res.result.get('body'))
            msg = ''
            for item in nh_list:
                _id = item.get('id')
                title = item.get('title')
                msg += f'\nID: {_id} / {title}\n'
            logger.info(f"Group: {event.group_id}, User: {event.user_id} 搜索成功")
            await nhentai.finish(f"已为你找到了如下结果: \n{msg}\n{'='*8}\n可通过id下载")
        else:
            logger.warning(f"Group: {event.group_id}, User: {event.user_id} 搜索失败, error info: {_res.info}")
            await nhentai.finish('搜索失败QAQ, 请稍后再试')
    elif sub_command == 'download':
        if not re.match(r'^\d+$', sub_arg):
            logger.warning(f"Group: {event.group_id}, User: {event.user_id} 搜索失败, id错误")
            await nhentai.finish('失败了QAQ, id应为纯数字')
        else:
            await nhentai.send('正在下载资源, 请稍后~')
            _res = await nh_download(_id=sub_arg)
            if not _res.success():
                logger.warning(f"Group: {event.group_id}, User: {event.user_id} 下载失败, error info: {_res.info}")
                await nhentai.finish('下载失败QAQ, 请稍后再试')
            else:
                password = _res.result.get('password')
                file = _res.result.get('file')
                file_abs = os.path.abspath(file)
                await bot.call_api(api='upload_group_file',
                                   group_id=event.group_id, file=file_abs, name=f'{sub_arg}.7z')
                logger.info(f"Group: {event.group_id}, User: {event.user_id} 下载成功")
                await nhentai.finish(f'成功, 解压密码: {password}')
    else:
        pass
Exemplo n.º 22
0
sv = Service('pcr_gacha')
jewel_limit = DailyNumberLimiter(6000)
tenjo_limit = DailyNumberLimiter(10)

JEWEL_EXCEED_NOTICE = f'您今天已经抽过{jewel_limit.max}钻了,欢迎明早5点后再来!'
TENJO_EXCEED_NOTICE = f'您今天已经抽过{tenjo_limit.max}张天井券了,欢迎明早5点后再来!'
POOL = ('MIX', 'JP', 'TW', 'BL')
DEFAULT_POOL = POOL[0]

_pool_config_file = os.path.expanduser('~/.hoshino/group_pool_config.json')
_group_pool = {}
try:
    with open(_pool_config_file, encoding='utf8') as f:
        _group_pool = json.load(f)
except FileNotFoundError as e:
    logger.warning(
        'group_pool_config.json not found, will create when needed.')
_group_pool = defaultdict(lambda: DEFAULT_POOL, _group_pool)


def dump_pool_config():
    with open(_pool_config_file, 'w', encoding='utf8') as f:
        json.dump(_group_pool, f, ensure_ascii=False)


gacha_10_aliases = ('抽十连', '十连', '十连!', '十连抽', '来个十连', '来发十连', '来次十连', '抽个十连', '抽发十连', '抽次十连', '十连扭蛋', '扭蛋十连',
                    '10连', '10连!', '10连抽', '来个10连', '来发10连', '来次10连', '抽个10连', '抽发10连', '抽次10连', '10连扭蛋', '扭蛋10连',
                    '十連', '十連!', '十連抽', '來個十連', '來發十連', '來次十連', '抽個十連', '抽發十連', '抽次十連', '十連轉蛋', '轉蛋十連',
                    '10連', '10連!', '10連抽', '來個10連', '來發10連', '來次10連', '抽個10連', '抽發10連', '抽次10連', '10連轉蛋', '轉蛋10連')
gacha_1_aliases = ('单抽', '单抽!', '来发单抽', '来个单抽', '来次单抽', '扭蛋单抽', '单抽扭蛋',
                   '單抽', '單抽!', '來發單抽', '來個單抽', '來次單抽', '轉蛋單抽', '單抽轉蛋')
gacha_300_aliases = ('抽一井', '来一井', '来发井', '抽发井',
Exemplo n.º 23
0
    async def check_dynamic(dy_uid):
        # 获取动态并返回动态类型及内容
        try:
            _res = await get_user_dynamic_history(dy_uid=dy_uid)
            if not _res.success():
                logger.error(f'bilibili_dynamic_monitor: 获取动态失败, uid: {dy_uid}, error: {_res.info}')
                return
        except Exception as _e:
            logger.error(f'bilibili_dynamic_monitor: 获取动态失败, uid: {dy_uid}, error: {repr(_e)}')
            return

        dynamic_info = dict(_res.result)

        # 用户所有的动态id
        _res = get_user_dynamic(user_id=dy_uid)
        if not _res.success():
            logger.error(f'bilibili_dynamic_monitor: 获取用户已有动态失败, uid: {dy_uid}, error: {_res.info}')
            return
        user_dy_id_list = list(_res.result)

        sub = DBSubscription(sub_type=2, sub_id=dy_uid)

        # 获取订阅了该直播间的所有群
        sub_group = sub.sub_group_list().result
        # 需通知的群
        notice_group = list(set(all_noitce_groups) & set(sub_group))

        for num in range(len(dynamic_info)):
            try:
                # 如果有新的动态
                if dynamic_info[num]['id'] not in user_dy_id_list:
                    logger.info(f"用户: {dy_uid}/{dynamic_info[num]['name']} 新动态: {dynamic_info[num]['id']}")
                    # 转发的动态
                    if dynamic_info[num]['type'] == 1:
                        # 获取原动态信息
                        origin_dynamic_id = dynamic_info[num]['origin']
                        _dy_res = await get_dynamic_info(dynamic_id=origin_dynamic_id)
                        if not _dy_res.success():
                            msg = '{}转发了{}的动态!\n\n“{}”\n{}\n{}\n@{}: {}'.format(
                                dynamic_info[num]['name'], 'Unknown',
                                dynamic_info[num]['content'], dynamic_info[num]['url'], '=' * 16,
                                'Unknown', '获取原动态失败'
                            )
                        else:
                            origin_dynamic_info = _dy_res.result
                            # 原动态type=2, 带图片
                            if origin_dynamic_info['type'] == 2:
                                # 处理图片序列
                                pic_segs = ''
                                for pic_url in origin_dynamic_info['origin_pics']:
                                    _res = await pic_2_base64(pic_url)
                                    pic_b64 = _res.result
                                    pic_segs += f'{MessageSegment.image(pic_b64)}\n'
                                msg = '{}转发了{}的动态!\n\n“{}”\n{}\n{}\n@{}: {}\n{}'.format(
                                    dynamic_info[num]['name'], origin_dynamic_info['name'],
                                    dynamic_info[num]['content'], dynamic_info[num]['url'], '=' * 16,
                                    origin_dynamic_info['name'], origin_dynamic_info['content'],
                                    pic_segs
                                )
                            # 原动态为其他类型, 无图
                            else:
                                msg = '{}转发了{}的动态!\n\n“{}”\n{}\n{}\n@{}: {}'.format(
                                    dynamic_info[num]['name'], origin_dynamic_info['name'],
                                    dynamic_info[num]['content'], dynamic_info[num]['url'], '=' * 16,
                                    origin_dynamic_info['name'], origin_dynamic_info['content']
                                )
                        for group_id in notice_group:
                            for _bot in bots:
                                try:
                                    await _bot.call_api(api='send_group_msg', group_id=group_id, message=msg)
                                    logger.info(f"向群组: {group_id} 发送新动态通知: {dynamic_info[num]['id']}")
                                except Exception as _e:
                                    logger.warning(f"向群组: {group_id} 发送新动态通知: {dynamic_info[num]['id']} 失败, "
                                                   f"error: {repr(_e)}")
                                    continue
                    # 原创的动态(有图片)
                    elif dynamic_info[num]['type'] == 2:
                        # 处理图片序列
                        pic_segs = ''
                        for pic_url in dynamic_info[num]['pic_urls']:
                            _res = await pic_2_base64(pic_url)
                            pic_b64 = _res.result
                            pic_segs += f'{MessageSegment.image(pic_b64)}\n'
                        msg = '{}发布了新动态!\n\n“{}”\n{}\n{}'.format(
                            dynamic_info[num]['name'], dynamic_info[num]['content'],
                            dynamic_info[num]['url'], pic_segs)
                        for group_id in notice_group:
                            for _bot in bots:
                                try:
                                    await _bot.call_api(api='send_group_msg', group_id=group_id, message=msg)
                                    logger.info(f"向群组: {group_id} 发送新动态通知: {dynamic_info[num]['id']}")
                                except Exception as _e:
                                    logger.warning(f"向群组: {group_id} 发送新动态通知: {dynamic_info[num]['id']} 失败, "
                                                   f"error: {repr(_e)}")
                                    continue
                    # 原创的动态(无图片)
                    elif dynamic_info[num]['type'] == 4:
                        msg = '{}发布了新动态!\n\n“{}”\n{}'.format(
                            dynamic_info[num]['name'], dynamic_info[num]['content'], dynamic_info[num]['url'])
                        for group_id in notice_group:
                            for _bot in bots:
                                try:
                                    await _bot.call_api(api='send_group_msg', group_id=group_id, message=msg)
                                    logger.info(f"向群组: {group_id} 发送新动态通知: {dynamic_info[num]['id']}")
                                except Exception as _e:
                                    logger.warning(f"向群组: {group_id} 发送新动态通知: {dynamic_info[num]['id']} 失败, "
                                                   f"error: {repr(_e)}")
                                    continue
                    # 视频
                    elif dynamic_info[num]['type'] == 8:
                        msg = '{}发布了新的视频!\n\n《{}》\n“{}”\n{}'.format(
                            dynamic_info[num]['name'], dynamic_info[num]['origin'],
                            dynamic_info[num]['content'], dynamic_info[num]['url'])
                        for group_id in notice_group:
                            for _bot in bots:
                                try:
                                    await _bot.call_api(api='send_group_msg', group_id=group_id, message=msg)
                                    logger.info(f"向群组: {group_id} 发送新动态通知: {dynamic_info[num]['id']}")
                                except Exception as _e:
                                    logger.warning(f"向群组: {group_id} 发送新动态通知: {dynamic_info[num]['id']} 失败, "
                                                   f"error: {repr(_e)}")
                                    continue
                    # 小视频
                    elif dynamic_info[num]['type'] == 16:
                        msg = '{}发布了新的小视频动态!\n\n“{}”\n{}'.format(
                            dynamic_info[num]['name'], dynamic_info[num]['content'], dynamic_info[num]['url'])
                        for group_id in notice_group:
                            for _bot in bots:
                                try:
                                    await _bot.call_api(api='send_group_msg', group_id=group_id, message=msg)
                                    logger.info(f"向群组: {group_id} 发送新动态通知: {dynamic_info[num]['id']}")
                                except Exception as _e:
                                    logger.warning(f"向群组: {group_id} 发送新动态通知: {dynamic_info[num]['id']} 失败, "
                                                   f"error: {repr(_e)}")
                                    continue
                    # 番剧
                    elif dynamic_info[num]['type'] in [32, 512]:
                        msg = '{}发布了新的番剧!\n\n《{}》\n{}'.format(
                            dynamic_info[num]['name'], dynamic_info[num]['origin'], dynamic_info[num]['url'])
                        for group_id in notice_group:
                            for _bot in bots:
                                try:
                                    await _bot.call_api(api='send_group_msg', group_id=group_id, message=msg)
                                    logger.info(f"向群组: {group_id} 发送新动态通知: {dynamic_info[num]['id']}")
                                except Exception as _e:
                                    logger.warning(f"向群组: {group_id} 发送新动态通知: {dynamic_info[num]['id']} 失败, "
                                                   f"error: {repr(_e)}")
                                    continue
                    # 文章
                    elif dynamic_info[num]['type'] == 64:
                        msg = '{}发布了新的文章!\n\n《{}》\n“{}”\n{}'.format(
                            dynamic_info[num]['name'], dynamic_info[num]['origin'],
                            dynamic_info[num]['content'], dynamic_info[num]['url'])
                        for group_id in notice_group:
                            for _bot in bots:
                                try:
                                    await _bot.call_api(api='send_group_msg', group_id=group_id, message=msg)
                                    logger.info(f"向群组: {group_id} 发送新动态通知: {dynamic_info[num]['id']}")
                                except Exception as _e:
                                    logger.warning(f"向群组: {group_id} 发送新动态通知: {dynamic_info[num]['id']} 失败, "
                                                   f"error: {repr(_e)}")
                                    continue
                    # 音频
                    elif dynamic_info[num]['type'] == 256:
                        msg = '{}发布了新的音乐!\n\n《{}》\n“{}”\n{}'.format(
                            dynamic_info[num]['name'], dynamic_info[num]['origin'],
                            dynamic_info[num]['content'], dynamic_info[num]['url'])
                        for group_id in notice_group:
                            for _bot in bots:
                                try:
                                    await _bot.call_api(api='send_group_msg', group_id=group_id, message=msg)
                                    logger.info(f"向群组: {group_id} 发送新动态通知: {dynamic_info[num]['id']}")
                                except Exception as _e:
                                    logger.warning(f"向群组: {group_id} 发送新动态通知: {dynamic_info[num]['id']} 失败, "
                                                   f"error: {repr(_e)}")
                                    continue
                    # B站活动相关
                    elif dynamic_info[num]['type'] == 2048:
                        msg = '{}发布了一条活动相关动态!\n\n【{}】\n“{}”\n{}'.format(
                            dynamic_info[num]['name'], dynamic_info[num]['origin'],
                            dynamic_info[num]['content'], dynamic_info[num]['url'])
                        for group_id in notice_group:
                            for _bot in bots:
                                try:
                                    await _bot.call_api(api='send_group_msg', group_id=group_id, message=msg)
                                    logger.info(f"向群组: {group_id} 发送新动态通知: {dynamic_info[num]['id']}")
                                except Exception as _e:
                                    logger.warning(f"向群组: {group_id} 发送新动态通知: {dynamic_info[num]['id']} 失败, "
                                                   f"error: {repr(_e)}")
                                    continue
                    elif dynamic_info[num]['type'] == -1:
                        logger.warning(f"未知的动态类型: {dynamic_info[num]['id']}")
                    # 更新动态内容到数据库
                    dy_id = dynamic_info[num]['id']
                    dy_type = dynamic_info[num]['type']
                    content = dynamic_info[num]['content']
                    # 向数据库中写入动态信息
                    dynamic = DBDynamic(uid=dy_uid, dynamic_id=dy_id)
                    _res = dynamic.add(dynamic_type=dy_type, content=content)
                    if _res.success():
                        logger.info(f"向数据库写入动态信息: {dynamic_info[num]['id']} 成功")
                    else:
                        logger.error(f"向数据库写入动态信息: {dynamic_info[num]['id']} 失败")
            except Exception as _e:
                logger.error(f'bilibili_dynamic_monitor: 解析新动态: {dy_uid} 的时发生了错误, error info: {repr(_e)}')
Exemplo n.º 24
0
async def handle_pixiv(bot: Bot, event: GroupMessageEvent, state: T_State):
    mode = state['mode']
    if mode == '日榜':
        await pixiv.send('稍等, 正在下载资源~')
        payload = {'key': API_KEY, 'num': 3, 'mode': 'daily'}
        _res = await fetch_json(url=RANK_API_URL, paras=payload)
        rank_data = _res.result
        if _res.success() and not rank_data.get('error'):
            error_count = 0
            for pid in rank_data.get('body'):
                logger.debug(f'获取Pixiv资源: {pid}.')
                # 获取illust
                _res = await fetch_image(pid=pid)
                if _res.success():
                    msg = _res.result.get('msg')
                    img_seg = MessageSegment.image(_res.result.get('b64'))
                    # 发送图片和图片信息
                    await pixiv.send(Message(img_seg).append(msg))
                else:
                    logger.warning(
                        f"User: {event.user_id} 获取Pixiv资源失败, 网络超时或 {pid} 不存在")
                    error_count += 1
            else:
                if error_count == len(rank_data.get('body')):
                    await pixiv.finish('加载失败, 网络超时QAQ')
        else:
            logger.warning(f"User: {event.user_id} 获取Pixiv Rank失败, 网络超时")
            await pixiv.finish('加载失败, 网络超时QAQ')
    elif mode == '周榜':
        await pixiv.send('稍等, 正在下载资源~')
        payload = {'key': API_KEY, 'num': 3, 'mode': 'weekly'}
        _res = await fetch_json(url=RANK_API_URL, paras=payload)
        rank_data = _res.result
        if _res.success() and not rank_data.get('error'):
            error_count = 0
            for pid in rank_data.get('body'):
                logger.debug(f'获取Pixiv资源: {pid}.')
                # 获取illust
                _res = await fetch_image(pid=pid)
                if _res.success():
                    msg = _res.result.get('msg')
                    img_seg = MessageSegment.image(_res.result.get('b64'))
                    # 发送图片和图片信息
                    await pixiv.send(Message(img_seg).append(msg))
                else:
                    logger.warning(
                        f"User: {event.user_id} 获取Pixiv资源失败, 网络超时或 {pid} 不存在")
                    error_count += 1
            else:
                if error_count == len(rank_data.get('body')):
                    await pixiv.finish('加载失败, 网络超时QAQ')
        else:
            logger.warning(f"User: {event.user_id} 获取Pixiv Rank失败, 网络超时")
            await pixiv.finish('加载失败, 网络超时QAQ')
    elif mode == '月榜':
        await pixiv.send('稍等, 正在下载资源~')
        payload = {'key': API_KEY, 'num': 3, 'mode': 'monthly'}
        _res = await fetch_json(url=RANK_API_URL, paras=payload)
        rank_data = _res.result
        if _res.success() and not rank_data.get('error'):
            error_count = 0
            for pid in rank_data.get('body'):
                logger.debug(f'获取Pixiv资源: {pid}.')
                # 获取illust
                _res = await fetch_image(pid=pid)
                if _res.success():
                    msg = _res.result.get('msg')
                    img_seg = MessageSegment.image(_res.result.get('b64'))
                    # 发送图片和图片信息
                    await pixiv.send(Message(img_seg).append(msg))
                else:
                    logger.warning(
                        f"User: {event.user_id} 获取Pixiv资源失败, 网络超时或 {pid} 不存在")
                    error_count += 1
            else:
                if error_count == len(rank_data.get('body')):
                    await pixiv.finish('加载失败, 网络超时QAQ')
        else:
            logger.warning(f"User: {event.user_id} 获取Pixiv Rank失败, 网络超时")
            await pixiv.send('加载失败, 网络超时QAQ')
    elif re.match(r'^\d+$', mode):
        pid = mode
        logger.debug(f'获取Pixiv资源: {pid}.')
        await pixiv.send('稍等, 正在下载图片~')
        # 获取illust
        _res = await fetch_image(pid=pid)
        if _res.success():
            msg = _res.result.get('msg')
            img_seg = MessageSegment.image(_res.result.get('b64'))
            # 发送图片和图片信息
            await pixiv.send(Message(img_seg).append(msg))
        else:
            logger.warning(
                f"User: {event.user_id} 获取Pixiv资源失败, 网络超时或 {pid} 不存在")
            await pixiv.send('加载失败, 网络超时或没有这张图QAQ')
    else:
        await pixiv.reject(
            '你输入的命令好像不对呢……请输入"月榜"、"周榜"、"日榜"或者PixivID, 取消命令请发送【取消】:')
Exemplo n.º 25
0
async def get_ascii2d_identify_result(url: str) -> list:
    async def get_ascii2d_redirects(_url: str) -> dict:
        timeout_count = 0
        while timeout_count < 3:
            try:
                timeout = aiohttp.ClientTimeout(total=10)
                async with aiohttp.ClientSession(timeout=timeout) as __session:
                    headers = {
                        'user-agent':
                        'Mozilla/5.0 (Windows NT 10.0; Win64; x64) '
                        'AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36',
                        'accept-language': 'zh-CN,zh;q=0.9'
                    }
                    async with __session.get(url=_url,
                                             headers=headers,
                                             timeout=timeout,
                                             allow_redirects=False) as resp:
                        res_headers = resp.headers
                        res_dict = {'error': False, 'body': dict(res_headers)}
                return res_dict
            except Exception as e:
                error_info = f'{repr(e)} Occurred in get_ascii2d_redirects trying {timeout_count + 1} using url: {_url}'
                logger.info(error_info)
            finally:
                timeout_count += 1
        else:
            error_info = f'Failed too many times in get_result using url: {_url}'
            logger.warning(error_info)
            return {'error': True, 'body': None}

    async def get_ascii2d_result(__url: str) -> str:
        timeout_count = 0
        while timeout_count < 3:
            try:
                timeout = aiohttp.ClientTimeout(total=10)
                async with aiohttp.ClientSession(timeout=timeout) as __session:
                    headers = {
                        'user-agent':
                        'Mozilla/5.0 (Windows NT 10.0; Win64; x64) '
                        'AppleWebKit/537.36 (KHTML, like Gecko) '
                        'Chrome/83.0.4103.116 Safari/537.36',
                        'accept-language':
                        'zh-CN,zh;q=0.9'
                    }
                    async with __session.get(url=__url,
                                             headers=headers,
                                             timeout=timeout) as resp:
                        res_headers = await resp.text()
                return res_headers
            except Exception as e:
                error_info = f'{repr(e)} Occurred in get_ascii2d_result trying {timeout_count + 1} using url: {__url}'
                logger.info(error_info)
            finally:
                timeout_count += 1
        else:
            error_info = f'Failed too many times in get_result using url: {__url}'
            logger.warning(error_info)
            return ''

    search_url = f'{API_URL_ASCII2D}{url}'
    __result_json = await get_ascii2d_redirects(_url=search_url)
    if not __result_json['error']:
        ascii2d_color_url = __result_json['body']['Location']
        ascii2d_bovw_url = re.sub(r'https://ascii2d\.net/search/color/',
                                  r'https://ascii2d.net/search/bovw/',
                                  ascii2d_color_url)
    else:
        logger.error(
            f'get_ascii2d_identify_result failed: 获取识别结果url发生错误, 错误信息详见日志.')
        return []

    color_res = await get_ascii2d_result(ascii2d_color_url)
    bovw_res = await get_ascii2d_result(ascii2d_bovw_url)

    pre_bs_list = []
    if color_res:
        pre_bs_list.append(color_res)
    if bovw_res:
        pre_bs_list.append(bovw_res)
    if not pre_bs_list:
        logger.error(f'get_ascii2d_identify_result ERROR: 获取识别结果异常, 错误信息详见日志.')
        return []

    __result = []

    for result in pre_bs_list:
        try:
            gallery_soup = BeautifulSoup(result, 'lxml')
            # 模式
            search_mode = gallery_soup.find('h5', {
                'class': 'p-t-1 text-xs-center'
            }).get_text(strip=True)
            # 每一个搜索结果
            row = gallery_soup.find_all('div', {'class': 'row item-box'})
        except Exception as page_err:
            logger.warning(
                f'get_ascii2d_identify_result failed: {repr(page_err)}, 解析结果页时发生错误.'
            )
            continue
        # ascii2d搜索偏差过大,pixiv及twitter结果只取第一个
        pixiv_count = 0
        twitter_count = 0
        for row_item in row:
            # 对每个搜索结果进行解析
            try:
                detail = row_item.find('div',
                                       {'class': 'detail-box gray-link'})
                is_null = detail.get_text(strip=True)
                if not is_null:
                    continue
                # 来源部分,ascii2d网页css调整大概率导致此处解析失败,调试重点关注
                source_type = detail.find('h6').find('small').get_text(
                    strip=True)
                if source_type == 'pixiv':
                    if pixiv_count > 0:
                        break
                    else:
                        pixiv_count += 1
                elif source_type == 'twitter':
                    if twitter_count > 0:
                        break
                    else:
                        twitter_count += 1
                else:
                    continue
                source = detail.find('h6').get_text('/', strip=True)
                source_url = detail.find('h6').find('a', {
                    'title': None,
                    'style': None
                }).get('href')
                # 预览图部分,ascii2d网页css调整大概率导致此处解析失败,调试重点关注
                preview_img_url = row_item. \
                    find('div', {'class': 'col-xs-12 col-sm-12 col-md-4 col-xl-4 text-xs-center image-box'}). \
                    find('img').get('src')
                __result.append({
                    'similarity': 'null',
                    'thumbnail': f'https://ascii2d.net{preview_img_url}',
                    'index_name': f'ascii2d - {search_mode} - {source}',
                    'ext_urls': source_url
                })
            except Exception as row_err:
                logger.warning(
                    f'get_ascii2d_identify_result ERROR: {repr(row_err)}, 解搜索结果条目时发生错误.'
                )
                continue
    return __result
Exemplo n.º 26
0
async def pixivision_monitor():
    logger.debug(f"pixivision_monitor: checking started")

    # 获取当前bot列表
    bots = []
    for bot_id, bot in get_bots().items():
        bots.append(bot)

    # 获取所有有通知权限的群组
    all_noitce_groups = []
    t = DBTable(table_name='Group')
    for item in t.list_col_with_condition('group_id', 'notice_permissions',
                                          1).result:
        all_noitce_groups.append(int(item[0]))

    # 初始化tag黑名单
    block_tag_id = []
    block_tag_name = []
    for block_tag in TAG_BLOCK_LIST:
        block_tag_id.append(block_tag.get('id'))
        block_tag_name.append(block_tag.get('name'))

    # 提取数据库中已有article的id列表
    exist_article = []
    t = DBTable(table_name='Pixivision')
    for item in t.list_col('aid').result:
        exist_article.append(int(item[0]))

    # 获取最新一页pixivision的article
    new_article = []
    _res = await get_pixivsion_article()
    if _res.success() and not _res.result.get('error'):
        try:
            pixivsion_article = dict(_res.result)
            for article in pixivsion_article['body']['illustration']:
                article_tags_id = []
                article_tags_name = []
                for tag in article['tags']:
                    article_tags_id.append(int(tag['tag_id']))
                    article_tags_name.append(str(tag['tag_name']))
                # 跳过黑名单tag的article
                if list(set(article_tags_id) & set(block_tag_id)) or list(
                        set(article_tags_name) & set(block_tag_name)):
                    continue
                # 获取新的article内容
                if int(article['id']) not in exist_article:
                    logger.info(
                        f"pixivision_monitor: 检查到新的Pixivision article: {article['id']}"
                    )
                    new_article.append({
                        'aid': int(article['id']),
                        'tags': article_tags_name
                    })
        except Exception as e:
            logger.error(
                f'pixivision_monitor: an error occured in checking pixivision: {repr(e)}'
            )
            return
    else:
        logger.error(
            f'pixivision_monitor: checking pixivision timeout or other error: {_res.info}'
        )
        return

    if not new_article:
        logger.info(f'pixivision_monitor: checking completed, 没有新的article')
        return

    sub = DBSubscription(sub_type=8, sub_id=-1)
    # 获取订阅了该直播间的所有群
    sub_group = sub.sub_group_list().result
    # 需通知的群
    notice_group = list(set(all_noitce_groups) & set(sub_group))

    # 处理新的aritcle
    for article in new_article:
        aid = int(article['aid'])
        tags = list(article['tags'])
        a_res = await pixivsion_article_parse(aid=aid, tags=tags)
        if a_res.success():
            if not notice_group:
                continue
            article_data = a_res.result
            msg = f"新的Pixivision特辑!\n\n" \
                  f"《{article_data['title']}》\n\n{article_data['description']}\n{article_data['url']}"
            for group_id in notice_group:
                for _bot in bots:
                    try:
                        await _bot.call_api(api='send_group_msg',
                                            group_id=group_id,
                                            message=msg)
                    except Exception as e:
                        logger.warning(
                            f"向群组: {group_id} 发送article简介信息失败, error: {repr(e)}"
                        )
                        continue
            # 处理article中图片内容
            tasks = []
            for pid in article_data['illusts_list']:
                tasks.append(fetch_image_b64(pid=pid))
            p_res = await asyncio.gather(*tasks)
            image_error = 0
            for image_res in p_res:
                if not image_res.success():
                    image_error += 1
                    continue
                else:
                    img_seg = MessageSegment.image(image_res.result)
                # 发送图片
                for group_id in notice_group:
                    for _bot in bots:
                        try:
                            await _bot.call_api(api='send_group_msg',
                                                group_id=group_id,
                                                message=img_seg)
                        except Exception as e:
                            logger.warning(
                                f"向群组: {group_id} 发送图片内容失败, error: {repr(e)}")
                            continue
            logger.info(f"article: {aid} 图片已发送完成, 失败: {image_error}")
        else:
            logger.error(f"article: {aid} 信息解析失败, info: {a_res.info}")
    logger.info(
        f'pixivision_monitor: checking completed, 已处理新的article: {repr(new_article)}'
    )
Exemplo n.º 27
0
    async def check_live(room_id: int):
        # 获取直播间信息
        _res = await get_live_info(room_id=room_id)
        if not _res.success():
            logger.error(
                f'bilibili_live_monitor: 获取直播间信息失败, room_id: {room_id}, error: {_res.info}'
            )
            return
        live_info = _res.result

        sub = DBSubscription(sub_type=1, sub_id=room_id)

        # 获取订阅了该直播间的所有群
        sub_group = sub.sub_group_list().result
        # 需通知的群
        notice_group = list(set(all_noitce_groups) & set(sub_group))

        up_name = live_up_name[room_id]

        # 检查是否是已开播状态, 若已开播则监测直播间标题变动
        # 为避免开播时同时出现标题变更通知和开播通知, 在检测到直播状态变化时更新标题, 且仅在直播状态为直播中时发送标题变更通知
        if live_info['status'] != live_status[room_id]\
                and live_info['status'] == 1\
                and live_info['title'] != live_title[room_id]:
            # 更新标题
            live_title[room_id] = live_info['title']
            logger.info(
                f"直播间: {room_id}/{up_name} 标题变更为: {live_info['title']}")
        elif live_info[
                'status'] == 1 and live_info['title'] != live_title[room_id]:
            # 通知有通知权限且订阅了该直播间的群
            cover_pic = await pic_2_base64(url=live_info.get('cover_img'))
            if cover_pic.success():
                msg = f"{up_name}的直播间换标题啦!\n\n【{live_info['title']}】\n{MessageSegment.image(cover_pic.result)}"
            else:
                # msg = f"{up_name}的直播间换标题啦!\n\n【{live_info['title']}】\n{live_info['url']}"
                msg = f"{up_name}的直播间换标题啦!\n\n【{live_info['title']}】"
            for group_id in notice_group:
                for _bot in bots:
                    try:
                        await _bot.call_api(api='send_group_msg',
                                            group_id=group_id,
                                            message=msg)
                        logger.info(f"向群组: {group_id} 发送直播间: {room_id} 标题变更通知")
                    except Exception as _e:
                        logger.warning(
                            f"向群组: {group_id} 发送直播间: {room_id} 标题变更通知失败, error: {repr(_e)}"
                        )
                        continue
            live_title[room_id] = live_info['title']
            logger.info(
                f"直播间: {room_id}/{up_name} 标题变更为: {live_info['title']}")

        # 检测开播/下播
        # 检查直播间状态与原状态是否一致
        if live_info['status'] != live_status[room_id]:
            try:
                # 现在状态为未开播
                if live_info['status'] == 0:
                    live_start_info = f"LiveEnd! Room: {room_id}/{up_name}"
                    new_event = DBHistory(time=int(time.time()),
                                          self_id=-1,
                                          post_type='bilibili',
                                          detail_type='live')
                    new_event.add(sub_type='live_end',
                                  user_id=room_id,
                                  user_name=up_name,
                                  raw_data=repr(live_info),
                                  msg_data=live_start_info)

                    msg = f'{up_name}下播了'
                    # 通知有通知权限且订阅了该直播间的群
                    for group_id in notice_group:
                        for _bot in bots:
                            try:
                                await _bot.call_api(api='send_group_msg',
                                                    group_id=group_id,
                                                    message=msg)
                                logger.info(
                                    f"向群组: {group_id} 发送直播间: {room_id} 下播通知")
                            except Exception as _e:
                                logger.warning(
                                    f"向群组: {group_id} 发送直播间: {room_id} 下播通知失败, error: {repr(_e)}"
                                )
                                continue
                    # 更新直播间状态
                    live_status[room_id] = live_info['status']
                    logger.info(f"直播间: {room_id}/{up_name} 下播了")
                # 现在状态为直播中
                elif live_info['status'] == 1:
                    # 记录准确开播信息
                    live_start_info = f"LiveStart! Room: {room_id}/{up_name}, Title: {live_info['title']}, " \
                                      f"TrueTime: {live_info['time']}"
                    new_event = DBHistory(time=int(time.time()),
                                          self_id=-1,
                                          post_type='bilibili',
                                          detail_type='live')
                    new_event.add(sub_type='live_start',
                                  user_id=room_id,
                                  user_name=up_name,
                                  raw_data=repr(live_info),
                                  msg_data=live_start_info)

                    cover_pic = await pic_2_base64(
                        url=live_info.get('cover_img'))
                    if cover_pic.success():
                        msg = f"{live_info['time']}\n{up_name}开播啦!\n\n【{live_info['title']}】" \
                              f"\n{MessageSegment.image(cover_pic.result)}"
                    else:
                        # msg = f"{live_info['time']}\n{up_name}开播啦!\n\n【{live_info['title']}】\n{live_info['url']}"
                        msg = f"{live_info['time']}\n{up_name}开播啦!\n\n【{live_info['title']}】"
                    for group_id in notice_group:
                        for _bot in bots:
                            try:
                                await _bot.call_api(api='send_group_msg',
                                                    group_id=group_id,
                                                    message=msg)
                                logger.info(
                                    f"向群组: {group_id} 发送直播间: {room_id} 开播通知")
                            except Exception as _e:
                                logger.warning(
                                    f"向群组: {group_id} 发送直播间: {room_id} 开播通知失败, error: {repr(_e)}"
                                )
                                continue
                    live_status[room_id] = live_info['status']
                    logger.info(f"直播间: {room_id}/{up_name} 开播了")
                # 现在状态为未开播(轮播中)
                elif live_info['status'] == 2:
                    live_start_info = f"LiveEnd! Room: {room_id}/{up_name}"
                    new_event = DBHistory(time=int(time.time()),
                                          self_id=-1,
                                          post_type='bilibili',
                                          detail_type='live')
                    new_event.add(sub_type='live_end_with_playlist',
                                  user_id=room_id,
                                  user_name=up_name,
                                  raw_data=repr(live_info),
                                  msg_data=live_start_info)

                    msg = f'{up_name}下播了(轮播中)'
                    for group_id in notice_group:
                        for _bot in bots:
                            try:
                                await _bot.call_api(api='send_group_msg',
                                                    group_id=group_id,
                                                    message=msg)
                                logger.info(
                                    f"向群组: {group_id} 发送直播间: {room_id} 下播通知")
                            except Exception as _e:
                                logger.warning(
                                    f"向群组: {group_id} 发送直播间: {room_id} 下播通知失败, error: {repr(_e)}"
                                )
                                continue
                    live_status[room_id] = live_info['status']
                    logger.info(f"直播间: {room_id}/{up_name} 下播了(轮播中)")
            except Exception as _e:
                logger.warning(
                    f'试图向群组发送直播间: {room_id}/{up_name} 的直播通知时发生了错误: {repr(_e)}')