Exemple #1
0
 async def get_screenshot(self, retry=3):
     browser = await launch(args=['--no-sandbox'])
     page = await browser.newPage()
     for i in range(retry + 1):
         try:
             await page.goto(self.url, waitUntil="networkidle0", timeout=10000)
             await page.setViewport(viewport={'width': 2560, 'height': 1080})
             card = await page.querySelector(".card")
             clip = await card.boundingBox()
             bar = await page.querySelector(".text-bar")
             bar_bound = await bar.boundingBox()
             clip['height'] = bar_bound['y'] - clip['y']
             self.img = "base64://" +\
                 await page.screenshot(clip=clip, encoding='base64')
             break
         except TimeoutError as e:
             logger.error(f"截图失败(连接超时) 已重试({i}/{retry})")
         except BadStatusLine as e:
             logger.error(f"截图失败(连接错误) 已重试({i}/{retry})")
         except Exception as e:
             logger.error("截图失败(未知错误),以下为错误日志")
             logger.error(traceback(e))
             await browser.close()
             raise
         finally:
             if i == retry:
                 try:
                     getattr(self, 'img')
                 except AttributeError:
                     logger.error("已达到重试上限,将在下个轮询中重新尝试")
                     await browser.close()
                     raise
         await asyncio.sleep(0.1)
     await browser.close()
Exemple #2
0
async def show_id_battle(bot: Bot, event: Event, state: dict):
    """Handle the id_battle command."""
    try:
        uids = map(int, str(event.message).split())
        uid1 = next(uids)
        uid2 = next(uids)
    except Exception:
        await bot.send(event=event, message=exclaim_msg('', '3', False, 1))
        return

    try:
        uid1_info = await get_user_info(uid1)
        uid2_info = await get_user_info(uid2)
    except Exception:
        logger.error(traceback.format_exc())
        await bot.send(event=event, message='用户信息获取失败~')
        return

    battle_message = '[%d] vs [%d]\n' % (uid1, uid2)

    for v in ['beg', 'int', 'exp', 'total']:
        tdiff = uid1_info[f'record_{v}'][0] - uid2_info[f'record_{v}'][0]
        bdiff = uid1_info[f'record_{v}'][1] - uid2_info[f'record_{v}'][1]
        result = f'{v}: %+.3f | %+.3f' % (tdiff, bdiff)
        battle_message += (result + '\n')

    await bot.send(event=event, message=battle_message.strip())
Exemple #3
0
async def subscriber_update(bot: Bot, event: Event, state: dict):
    """Handle the subscribe command."""
    universal_id = str(event.self_id) + str(event.group_id)
    subscribed_list = load(universal_id, 'subscribed_list')
    if not subscribed_list:
        subscribed_list = {}
        save(universal_id, 'subscribed_list', subscribed_list)

    operation = {
        '+': lambda x: subscribed_list.setdefault(x, False),
        '-': lambda x: subscribed_list.pop(x),
    }

    arg = str(event.message).strip()
    try:
        operator = arg[0]
        if operator == 'o':
            await bot.send(event=event,
                           message='当前订阅用户B站UID名单: %s' %
                           ', '.join(subscribed_list.keys()))
            return
        operand = str(int(arg[1:].strip()))
        operation[operator](operand)  # add or remove the word
        save(universal_id, 'subscribed_list', subscribed_list)
        await bot.send(event=event, message='订阅用户信息更新成功~')
    except Exception:
        logger.error(traceback.format_exc())
        await bot.send(event=event, message='订阅用户信息更新失败,请检查日志文件~')
def my_trigger_cron(rss: rss_class.Rss):
    # 解析参数
    tmp_list = rss.time.split("_")
    times_list = ["*/5", "*", "*", "*", "*"]
    for index, value in enumerate(tmp_list):
        if value:
            times_list[index] = value
    try:
        # 制作一个触发器
        trigger = CronTrigger(
            minute=times_list[0],
            hour=times_list[1],
            day=times_list[2],
            month=times_list[3],
            day_of_week=times_list[4],
            timezone="Asia/Shanghai",
        )
    except Exception as e:
        logger.error(f"创建定时器错误!cron:{times_list} E:{e}")
        return

    # 添加任务
    scheduler.add_job(
        func=check_update,  # 要添加任务的函数,不要带参数
        trigger=trigger,  # 触发器
        args=(rss,),  # 函数的参数列表,注意:只有一个值时,不能省略末尾的逗号
        id=rss.name,
        misfire_grace_time=30,  # 允许的误差时间,建议不要省略
        max_instances=1,  # 最大并发
        default=ThreadPoolExecutor(64),  # 最大线程
        processpool=ProcessPoolExecutor(8),  # 最大进程
        coalesce=True,  # 积攒的任务是否只跑一次,是否合并所有错过的Job
    )
    logger.info(f"定时任务 {rss.name} 添加成功")
Exemple #5
0
async def _run_matcher(Matcher: Type[Matcher], bot: Bot, event: Event,
                       state: dict) -> Union[None, NoReturn]:
    if Matcher.expire_time and datetime.now() > Matcher.expire_time:
        raise _ExceptionContainer([ExpiredException])

    try:
        if not await Matcher.check_perm(
                bot, event) or not await Matcher.check_rule(bot, event, state):
            return
    except Exception as e:
        logger.error(f"Rule check failed for matcher {Matcher}. Ignored.")
        logger.exception(e)
        return

    # TODO: log matcher
    logger.info(f"Event will be handled by {Matcher}")

    matcher = Matcher()
    # TODO: BeforeMatcherRun
    try:
        logger.debug(f"Running matcher {matcher}")
        await matcher.run(bot, event, state)
    except Exception as e:
        logger.error(f"Running matcher {matcher} failed.")
        logger.exception(e)

    exceptions = []
    if Matcher.temp:
        exceptions.append(ExpiredException)
    if Matcher.block:
        exceptions.append(StopPropagation)
    if exceptions:
        raise _ExceptionContainer(exceptions)
Exemple #6
0
async def start_game(bot: Bot,
                     universal_id: str,
                     addscore: bool = True,
                     enforce_random: bool = False):
    """Start the calc42 game."""
    group_id = int(universal_id[len(str(bot.self_id)):])
    init(universal_id)

    if status(universal_id):
        return  # stop the process if the game has started

    problem = start(universal_id, addscore, enforce_random)
    message = print_current_problem(problem)
    deadline = get_deadline(problem['total'])

    try:
        manager.add_scheduler(bot, universal_id, finish_game, deadline)
        manager.add_scheduler(bot, universal_id, timeout_reminder,
                              deadline - hint_timeout)
        await bot.send_group_msg(group_id=group_id, message=message)
    except Exception:
        logger.error(traceback.format_exc())
        manager.remove_schedulers(universal_id)
        manager.reset_invoker(universal_id)
        stop(universal_id)  # stop the app instantly
Exemple #7
0
    def _get_group_uncached(self, name: Union[str, int], referer: Optional["PermissionGroup"], required: bool
                            ) -> Tuple["PermissionGroup", bool]:
        group_desc = self.config.get(name)
        if group_desc is None:
            if required:
                if referer:
                    logger.error('Permission group {}:{} not found (required from {}:{})',
                                 self.name, name, referer.namespace.name, referer.name)
                else:
                    logger.error('Permission group {}:{} not found', self.name, name)
            return NullPermissionGroup(), False

        try:
            desc = parse_obj_as(GroupDesc, group_desc)
        except ValueError:
            logger.exception('Failed to parse {}:{} ({})', self.name, name, self.path)
            return NullPermissionGroup(), False

        # 注入插件预设
        if self.name == 'global' and name in default_groups:
            for pn in plugin_namespaces:
                if name in pn.config:
                    desc.inherits.append(f'{pn.name}:{name}')

        self.groups[name] = group = PermissionGroup(self, name)
        group.populate(desc, referer)
        return group, True
Exemple #8
0
async def get_City_Weather(city: str):
    # global city_id
    city_info = await get_Location(city)
    logger.debug(city_info)
    if city_info["code"] == "200":
        city_id = city_info["location"][0]["id"]
        city_name = city_info["location"][0]["name"]

        # 3天天气
        daily_info = await get_WeatherInfo("3d", city_id)
        daily = daily_info["daily"]
        day1 = daily[0]
        day2 = daily[1]
        day3 = daily[2]

        # 实时天气
        now_info = await get_WeatherInfo("now", city_id)
        now = now_info["now"]

        # 天气预警信息
        warning = await get_WeatherWarning(city_id)

        return {
            "city": city_name,
            "now": now,
            "day1": day1,
            "day2": day2,
            "day3": day3,
            "warning": warning,
        }
    else:
        logger.error(
            f"错误: {city_info['code']} 请参考 https://dev.qweather.com/docs/start/status-code/ "
        )
        return int(city_info["code"])
Exemple #9
0
async def create_schema():
    await db.setBind()
    try:
        async with db.pool.acquire() as conn:
            await conn.execute("""create table jrrp(
                qid bigint primary key,
                dt date,
                rand int
            )""")
            await conn.execute("""create table rss(
                id varchar(20) primary key,
                dt varchar(50),
            )""")
            await conn.execute("""create table subs(
                qid bigint,
                dt varchar(50),
                rss varchar(20) references rss (id) on update cascade on delete cascade
                primary key (qid,rss)
            )""")
            await conn.execute("""create table notebook(
                qid bigint,
                item varchar(200),
                ind int,
                primary key (qid,item));""")
            await conn.execute("""create index on subs(rss)""")
    except:
        logger.error("操作失败,可能是数据库配置不正确!")
        exit(1)
Exemple #10
0
async def download_image(url: str, proxy: bool = False):
    url = await handle_img_url(url)
    try:
        return await download_image_detail(url=url, proxy=proxy)
    except Exception as e:
        logger.error(f"图片[{url}]下载失败!已达最大重试次数!{e}")
        return None
Exemple #11
0
async def send_msg(rss: rss_class.Rss, msg: str, item: dict) -> bool:
    bot = nonebot.get_bot()
    flag = False
    if not msg:
        return False
    if rss.user_id:
        for user_id in rss.user_id:
            try:
                await bot.send_msg(message_type="private",
                                   user_id=user_id,
                                   message=str(msg))
                flag = True
            except Exception as e:
                logger.error(f'发送QQ号[{user_id}]错误! E: {e}')

    if rss.group_id:
        for group_id in rss.group_id:
            try:
                await bot.send_msg(message_type="group",
                                   group_id=group_id,
                                   message=str(msg))
                flag = True
            except Exception as e:
                logger.error(f'发送QQ号[{user_id}]错误! E: {e}')
    return flag
Exemple #12
0
async def resize_gif(url: str, proxy: bool, resize_ratio: int = 2) -> BytesIO:
    try:
        async with httpx.AsyncClient(proxies=get_proxy(proxy)) as client:
            response = await client.post(
                url="https://s3.ezgif.com/resize",
                data={"new-image-url": url},
                timeout=None,
            )
            d = Pq(response.text)
            next_url = d("form").attr("action")
            file = d("form > input[type=hidden]:nth-child(1)").attr("value")
            token = d("form > input[type=hidden]:nth-child(2)").attr("value")
            old_width = d("form > input[type=hidden]:nth-child(3)").attr(
                "value")
            old_height = d("form > input[type=hidden]:nth-child(4)").attr(
                "value")
            data = {
                "file": file,
                "token": token,
                "old_width": old_width,
                "old_height": old_height,
                "width": str(int(old_width) // resize_ratio),
                "method": "gifsicle",
                "ar": "force",
            }
            async with httpx.AsyncClient(
                    proxies=get_proxy(proxy)) as fork_client:
                response = await fork_client.post(url=next_url + "?ajax=true",
                                                  data=data,
                                                  timeout=None)
                d = Pq(response.text)
                output_img_url = "https:" + d("img:nth-child(1)").attr("src")
                return await download_image(output_img_url)
    except Exception as e:
        logger.error(f"GIF 图片[{url}]压缩失败,将重试 \n {e}")
Exemple #13
0
async def recent_handler(bot: Bot, state: T_State) -> Any:
    cmd = state['cmd']
    current_user: schema.User = state['current_user']
    if cmd in config.CMDA_RECENT:
        if not current_user.code:
            raise ValueError
        api = ArcApiPlus(current_user.code)
        query_start_time = time()
        try:
            userinfo = await api.userinfo(with_recent=True)
        except HTTPException as e:
            logger.error(e.detail)
            await arc.finish('服务器连接失败', at_sender=True)
            return
        except Exception as e:
            logger.error(str(e))
            await arc.finish('查询失败~', at_sender=True)
            return
        query_end_time = time()
        if current_user.recent_type == 'text':
            userinfo_msg = ArcMessage.text(userinfo)
            send_msg = userinfo_msg + f"\n查询耗时: {query_end_time - query_start_time:.2f}s"
            await arc.finish('Recent 查询结果\n' + send_msg, at_sender=True)
            return
        else:
            await arc.finish('this_is_recent.jpg')
            return
Exemple #14
0
async def update_pool(force=False) -> int:
    '''
    从远程拉取卡池覆盖本地的卡池
    1, 备份原卡池到backup.json
    2, 从远程卡池获取数据, 修改本地卡池数据
    3, 从远程卡池获取版本号, 覆盖到本地
    指定force为true, 则不会比较本地版本号是否最新
    '''
    if PCRDATA_UPDATA:
        await update_pcrdata()
    # 获取远程卡池
    online_pool = await get_online_pool()
    if type(online_pool) == int:
        logger.error(f'获取在线卡池时发生错误{online_pool}')
        return online_pool

    # 获取远程版本号
    online_ver = await get_online_ver()
    if online_ver < 1000:
        logger.error(f'获取在线卡池版本时发生错误{online_ver}')
        return online_ver

    # 比较本地版本号
    local_ver = get_local_ver()
    if force:
        # 指定强制更新
        local_ver = 0
    if online_ver <= local_ver:
        return 0
    # 修改本地卡池
    update_local_pool(online_pool)
    # 覆盖本地版本号
    update_local_ver(online_ver)
    return online_ver
Exemple #15
0
 async def get_screenshot(self):
     if path.isfile(self.img_path):
         return
     browser = await launch(args=['--no-sandbox'])
     page = await browser.newPage()
     for _ in range(3):
         try:
             await page.goto(self.url, waitUntil="networkidle0")
             # await page.waitForNavigation()
             # await page.waitFor(1000)
             await page.setViewport(viewport={
                 'width': 1920,
                 'height': 1080
             })
             # card = await page.waitForSelector(".card")
             card = await page.querySelector(".card")
             clip = await card.boundingBox()
             bar = await page.querySelector(".text-bar")
             bar_bound = await bar.boundingBox()
             clip['height'] = bar_bound['y'] - clip['y']
             await page.screenshot({'path': self.img_path, 'clip': clip})
             break
         except:
             logger.error(traceback.format_exc())
             await asyncio.sleep(0.1)
     await page.close()
     await browser.close()
Exemple #16
0
async def _real_run_command(session: CommandSession,
                            ctx_id: str,
                            disable_interaction: bool = False,
                            **kwargs) -> Optional[bool]:
    if not disable_interaction:
        # override session only when interaction is not disabled
        _sessions[ctx_id] = session
    try:
        logger.debug(f'Running command {session.cmd.name}')
        session.running = True
        future = asyncio.ensure_future(session.cmd.run(session, **kwargs))
        timeout_opt = session.run_timeout
        timeout = timeout_opt.total_seconds() if timeout_opt else None

        try:
            await asyncio.wait_for(future, timeout)
            handled = future.result()
        except asyncio.TimeoutError:
            handled = True
        except CommandInterrupt:
            raise
        except Exception as e:
            logger.error(f'An exception occurred while '
                         f'running command {session.cmd.name}:')
            logger.exception(e)
            handled = True
        raise _FinishException(handled)
    except _PauseException:
        session.running = False
        if disable_interaction:
            # if the command needs further interaction, we view it as failed
            return False
        logger.debug(f'Further interaction needed for '
                     f'command {session.cmd.name}')
        # return True because this step of the session is successful
        return True
    except _YieldException:
        return True
        # return True because this step of the session is successful
    except (_FinishException, SwitchException) as e:
        session.running = False
        logger.debug(f'Session of command {session.cmd.name} finished')
        if not disable_interaction and ctx_id in _sessions:
            # the command is finished, remove the session,
            # but if interaction is disabled during this command call,
            # we leave the _sessions untouched.
            del _sessions[ctx_id]

        if isinstance(e, _FinishException):
            return e.result
        elif isinstance(e, SwitchException):
            # we are guaranteed that the session is not first run here,
            # which means interaction is definitely enabled,
            # so we can safely touch _sessions here.
            if ctx_id in _sessions:
                # make sure there is no session waiting
                del _sessions[ctx_id]
            logger.debug(f'Session of command {session.cmd.name} switching, '
                         f'new message: {e.new_message}')
            raise e  # this is intended to be propagated to handle_message()
Exemple #17
0
def ensure_user_sync(user_name, group_name="damebot", extra_group=tuple()):
    logger.debug(
        f"ensuring user {user_name} and group {group_name} {extra_group} exists."
    )
    uid_extra = f" -u {uid_map[user_name]}" if user_name in uid_map else ""
    group_exist = ensure_group_sync(group_name)
    extra_group_values = [ensure_group_sync(group) for group in extra_group]
    extra_group_exists = all(extra_group_values)
    group_all_exists = group_exist and extra_group_exists
    cmd = f"useradd -r {user_name}{uid_extra} -Ng {group_name}"
    code, out, err = execute_shell_sync(cmd)
    success = group_all_exists and (code == 0 or code == 9)
    for group in extra_group:
        cmd_usermod = f"usermod {user_name} -aG {group}"
        code, out, err = execute_shell_sync(cmd_usermod)
        success = success and (code == 0 or code == 9)
    if not success:
        logger.error(f"useradd failed. ")
    else:
        logger.debug(f"useradd succeed.")
        uid_map[user_name] = pwd.getpwnam(user_name).pw_uid
        uid_map.sync()
        gid_reverse = {v: k for k, v in gid_map.items()}
        main_group_name = gid_reverse[pwd.getpwnam(user_name).pw_gid]
        logger.debug(f"group {main_group_name} for {user_name}")
        user_main_group[user_name] = main_group_name
        groups = [g.gr_name for g in grp.getgrall() if user_name in g.gr_mem]
        logger.debug(f"groups {groups} for {user_name}")
        if main_group_name in groups:
            groups.remove(main_group_name)
        user_extra_group[user_name] = groups
        user_main_group.sync()
        user_extra_group.sync()
    return success
Exemple #18
0
async def _(bot_id: str, group_id: str):
    """Scheduled group member information update."""
    bot = nonebot.get_bots()[bot_id]
    try:
        await update_group_members(bot, group_id)
    except Exception:
        logger.error(traceback.format_exc())
Exemple #19
0
    def get_group(self, name: Union[str, int], referer: Optional["PermissionGroup"], required: bool
                  ) -> Tuple["PermissionGroup", bool]:
        """
        获取本名称空间下的权限组。

        :param name: 组名。
        :param referer: 引用者。
        :param required: 权限组不存在时是否报错。
        :return:
            [0] 权限组,若失败则返回一个空组。 <br>
            [1] 是否成功。
        """
        group = self.groups.get(name)
        if group is not None:
            if not group.referer:
                return group, group.namespace is not None

            cycle = [f'{self.name}:{name}']
            it = referer
            while it and not (it.name == name and it.namespace is self):
                cycle.append(f'{it.namespace.name}:{it.name}')
                it = it.referer
            cycle.append(f'{self.name}:{name}')
            logger.error('Inheritance cycle detected: {}', ' -> '.join(reversed(cycle)))
            return NullPermissionGroup(), False

        group, found = self._get_group_uncached(name, referer, required)
        self.groups[name] = group
        return group, found
Exemple #20
0
async def get_anime_list(year: int,
                         month: int) -> Optional[List[Dict[str, Any]]]:
    payload = {
        'season_version': -1,
        'area': -1,
        'is_finish': -1,
        'copyright': -1,
        'season_status': -1,
        'season_month': month,
        'pub_date': year,
        'style_id': -1,
        'order': 3,
        'st': 1,
        'sort': 0,
        'page': 1,
        'season_type': 1,
        'pagesize': 20
    }
    async with httpx.AsyncClient(headers=HEADER) as client:
        try:
            response = await client.get(INDEX_API_URL, params=payload)
            response.raise_for_status()
            data = response.json()
            if data.get('code') != 0:
                return None
            return data['result']['data']
        except (httpx.HTTPError, KeyError) as e:
            logger.error(e)
            return None
Exemple #21
0
async def wakuang_handle(bot: Bot, event: Event, state: dict):
    msg = str(event.message).strip()
    try:
        state['rank'] = int(msg)
    except Exception as e:
        logger.error(e)
        await sv_wakuang.finish()
Exemple #22
0
    async def refresh_calendar(self) -> None:
        """获取最新的日程表"""
        if self._timeline:
            # 最近四小时内才更新的不用再次更新
            if self._timeline_update_time > datetime.now() - timedelta(hours=4):
                return
        try:
            async with httpx.AsyncClient() as client:
                r = await client.get(self._url)
                rjson = r.json()

                # 清除以前的时间线
                self._timeline.clear()
                for event in rjson:
                    start_time = datetime.strptime(
                        event["start_time"], "%Y/%m/%d %H:%M:%S"
                    )
                    end_time = datetime.strptime(event["end_time"], "%Y/%m/%d %H:%M:%S")
                    name = event["name"]
                    self.add_event(start_time, end_time, name)

                self._timeline_update_time = datetime.now()
                logger.info("公主连结Re:Dive 日程表刷新成功")
        except (httpx.HTTPError, KeyError) as e:
            logger.error(f"获取日程表出错,{e}")
            # 抛出上面任何异常,说明调用失败
            return
Exemple #23
0
def checkUpdate(new, old) -> list:
    try:
        a = new.entries
    except Exception as e:
        logger.error('拉取RSS失败,可能是网络开了小差 E:' + str(e))
        print(new)
        return []
    b = old['entries']

    c = []
    # 防止 rss 超过设置的缓存条数
    if len(a) >= config.LIMT:
        LIMT = len(a) + config.LIMT
    else:
        LIMT = config.LIMT

    for i in a:
        count = 0
        # print(i['link'])
        for j in b:
            if i['id'] == j['id']:
                count = 1
        if count == 0:
            c.insert(0, i)
    for i in c:
        count = 0
        # print(i['link'])
        for j in b:
            if i['id'] == j['id']:
                count = 1
        if count == 1:
            c.remove(i)
    return c
Exemple #24
0
async def getRSS(rss):  # 链接,订阅名
    d = ""
    try:
        r = requests.get(rss.geturl(), timeout=30)
        d = feedparser.parse(r.content)
    except:
        logger.error("抓取订阅 {} 的 RSS 失败".format(rss.url))

    # 检查是否存在rss记录
    if os.path.isfile(file_path + (rss.url + '.json')):
        change = checkUpdate(d, readRss(rss.url))  # 检查更新
        if len(change) > 0:
            writeRss(rss.url, d)  # 写入文件
            msg_list = []
            for item in change:
                msg = '【' + d.feed.title + '】更新了!\n----------------------\n'
                # 处理item['summary']只有图片的情况
                text = re.sub('<video.+?><\/video>|<img.+?>', '',
                              item['summary'])
                text = re.sub('<br>', '', text)
                msg = msg + '标题:' + item['title'] + '\n'
                temp = await checkstr(item['summary'])
                if temp:
                    msg = msg + '内容:' + temp + '\n'

                str_link = re.sub('member_illust.php\?mode=medium&illust_id=',
                                  'i/', item['link'])
                msg = msg + '原链接:' + str_link + '\n'
                msg_list.append(msg)
            return msg_list
    else:
        writeRss(rss.url, d)
        return []
Exemple #25
0
async def b30_handler(bot: Bot, state: T_State) -> Any:
    cmd = state['cmd']
    current_user: schema.User = state['current_user']
    if cmd in config.CMDA_B30:
        if not current_user.code:
            raise ValueError
        api = ArcApiPlus(current_user.code)
        query_start_time = time()
        try:
            userbest30 = await api.userbest30()
        except HTTPException as e:
            logger.error(e.detail)
            await arc.finish('服务器连接失败', at_sender=True)
            return
        except Exception as e:
            logger.error(str(e))
            await arc.finish('查询失败~', at_sender=True)
            return
        query_end_time = time()
        if current_user.b30_type == 'text':
            userbest30_msg = ArcMessage.text(userbest30)
        else:
            userbest30_msg = ArcMessage.image(userbest30, theme_name=current_user.b30_type)
        send_msg = userbest30_msg + f"\n查询耗时: {query_end_time - query_start_time:.2f}s"
        await arc.finish('B30 查询结果\n' + send_msg, at_sender=True)
        return
Exemple #26
0
async def commit():
    """Commit to the database, saving the file on disk from memory."""
    logger.info('Saving the database to disk ...')

    database_backup = os.path.join(database_backup_directory,
                                   '%d.bak' % int(time.time() * 1000000))
    shutil.copyfile(database_location, database_backup)

    backups = os.listdir(database_backup_directory)
    removes = (0 < database_backup_max_storage <
               len(backups)) * (len(backups) - database_backup_max_storage)
    for i in range(removes):
        os.remove(os.path.join(database_backup_directory,
                               backups[i]))  # remove the redundant files

    try:
        with gzip.open(database_location,
                       'wb',
                       compresslevel=database_compress_level) as tf:
            tf.write(json.dumps(database, sort_keys=True).encode())
        return True
    except Exception:
        logger.error('Failed to save the database ...')
        logger.error(traceback.format_exc())
        return False
Exemple #27
0
async def show_my_info(bot: Bot, event: Event, state: dict):
    """Handle the id_me command."""
    universal_id = str(event.self_id) + str(event.group_id)
    user_id = f'{event.user_id}'
    try:
        members = load(universal_id, 'members')
        uid = int(members[user_id]['id'])
    except Exception:
        await bot.send(event=event, message='个人信息获取失败,请检查头衔~')
        return

    colding_time = _validate_id(universal_id, str(uid), gap=3600)
    if colding_time > 0:
        wait_message = '用户ID[%d]尚在查询冷却期,剩余冷却时间%d秒~' % (uid, colding_time)
        await bot.send(event=event, message=wait_message)
        return

    try:
        user_info = await get_user_info(uid)
    except Exception:
        logger.error(traceback.format_exc())
        await bot.send(event=event, message='用户信息获取失败~')
        return

    user_info_message = format_user_info(user_info)
    await bot.send(event=event, message=user_info_message)
Exemple #28
0
async def safe_send(bot: Bot, send_type, type_id, message):
    """发送出现错误时, 尝试重新发送, 并捕获异常且不会中断运行"""
    for i in range(3):
        try:
            message_id = await bot.call_api(
                'send_' + send_type + '_msg', **{
                    'message': message,
                    'user_id' if send_type == 'private' else 'group_id':
                    type_id
                })
            return message_id
        except:
            logger.error(traceback.format_exc())
            if i == 2:
                bot = await restart(bot)
                message = '检测到推送出现异常,已尝试自动重启,如仍有问题请向机器人管理员反馈'
                message_id = await bot.call_api(
                    'send_' + send_type + '_msg', **{
                        'message':
                        message,
                        'user_id' if send_type == 'private' else 'group_id':
                        type_id
                    })
                return message_id
            await asyncio.sleep(0.1)
Exemple #29
0
async def get_user_info(uid: str) -> dict:
    """Get the bilibili user info from UID."""
    headers = {
        'User-Agent': 'Mozilla/5.0',
        'Referer': 'https://www.bilibili.com/'
    }
    url = 'https://api.bilibili.com/x/space/acc/info?mid=%s' % uid
    try:
        async with httpx.AsyncClient() as client:
            r = await client.get(url=url, headers=headers)
            data = r.json()['data']
            result = {}
            result['name'] = data['name']
            result['live_room_url'] = data['live_room']['url']
            result['live_status'] = bool(data['live_room']['liveStatus'])
            result['live_title'] = data['live_room']['title']
            return result
    except Exception:
        logger.error(traceback.format_exc())
        # return a default message if the bot fails to fetch the information
        default = {
            'name': '',
            'live_room_url': '',
            'live_status': False,
            'live_title': '',
        }
        return default
Exemple #30
0
async def _(bot: Bot, event: Event, state: dict) -> None:
    group = str(event.group_id)
    msg = str(event.message)

    if "[CQ:reply" in msg:
        if "搜图" in msg or "识图" in msg:
            if group == "None":
                await SaucenaoSearch_repo.finish("ごめんなさい...\n该功能只对群聊开放哦~~")

            try:
                repo_info = re.findall(r"CQ:reply,id=([0-9]\S+)]", msg)
                msg_id = repo_info[0]
            except Exception:
                logger.error("Get message_id ERROR!")
                await SaucenaoSearch_repo.finish(errorRepo('定位消息内容失败'))
                return

            aim = getMessage(msg_id)[f"{msg_id}"]["message"]
            img = img = re.findall(r"(http://.*?)]", aim)

            if len(img):
                pass
            else:
                await SaucenaoSearch_repo.finish('这消息内貌似没图片呢...')

            await bot.send(event, "别急!正在找图!")

            await SaucenaoSearch.finish(
                resultRepo(state['user'], key_SauceNAO, img[0]))