Пример #1
0
class ServerMonitor:
    """ 服务器状态监控 """
    def __init__(self):
        self._data = PluginData('ff14', config=True)
        # 定时任务
        self._job = None
        # 当前状态
        self._status = None

        # 根据配置启动
        if bool(
            int(self._data.get_config('ff14', 'monitor_server_status', '0'))
        ):
            self.enable()

    def enable(self):
        self._job = scheduler.add_job(
            self.monitor_server_status, 'interval', seconds=self.interval
        )
        self._data.set_config('ff14', 'monitor_server_status', '1')

    def disable(self):
        self._job.remove()
        self._data.set_config('ff14', 'monitor_server_status', '0')

    @property
    def is_enabled(self):
        """ 是否启用服务器状态监控 """
        if self._job:
            return True
        else:
            return False

    @property
    def status(self):
        """ 服务器状态

        返回格式化字符串
        """
        status = self._status
        if status:
            resp = f'当前的服务器状态({status["time"].strftime("%Y-%m-%d %H:%M:%S")})'
            for name, is_open in status['data'].items():
                resp += f'\n{name}:{"在线" if is_open else "离线"}'
            return resp
        else:
            return '无数据'

    @property
    def interval(self):
        return int(
            self._data.get_config('ff14', 'monitor_server_interval', '60')
        )

    @staticmethod
    async def is_open(ip, port):
        """ 查询端口是否开启 """
        conn = asyncio.open_connection(ip, port)
        try:
            _reader, writer = await asyncio.wait_for(conn, timeout=1)
            writer.close()
            await writer.wait_closed()
            return True
        except asyncio.TimeoutError:
            return False

    async def monitor_server_status(self):
        """ 监控服务器状态 """
        group_id = get_bot().config.GROUP_ID[0]
        if not self._status:
            self._status = await self.get_server_status()
        else:
            current_status = await self.get_server_status()
            if self._status['data'] == current_status['data']:
                pass
            else:
                await get_bot().send_msg(
                    message_type='group',
                    group_id=group_id,
                    message=self.status
                )
            self._status = current_status

    async def get_server_status(self):
        """ 获取服务器状态 """
        # data = {
        #     '陆行鸟': await self.is_open('109.244.5.5', 54994),
        #     '莫古力': await self.is_open('109.244.5.162', 54994),
        #     '猫小胖': await self.is_open('116.211.8.5', 54994),
        # }
        data = {
            '猫小胖': await self.is_open('116.211.8.5', 54994),
            '静语庄园': await self.is_open('116.211.8.46', 55022),
        }
        return {'time': datetime.now(), 'data': data}
Пример #2
0
class News:
    def __init__(self):
        self._data = PluginData('ff14', config=True)
        # 新闻数据的地址
        self._url = 'http://api.act.sdo.com/UnionNews/List?gameCode=ff&category=5309,5310,5311,5312,5313&pageIndex=0&pageSize=5'
        # 定时任务
        self._job = None

        # 根据配置启动
        if bool(int(self._data.get_config('ff14', 'push_news', '0'))):
            self.enable()

    def enable(self):
        """ 开启新闻自动推送 """
        logger.info('初始化 最终幻想XIV 新闻推送')
        # 开启后先运行一次
        scheduler.add_job(self.push_news,
                          'date',
                          run_date=(datetime.now() + timedelta(seconds=30)))
        self._job = scheduler.add_job(self.push_news,
                                      'interval',
                                      minutes=self.interval)
        self._data.set_config('ff14', 'push_news', '1')

    def disable(self):
        """ 关闭新闻自动推送 """
        self._job.remove()
        self._data.set_config('ff14', 'push_news', '0')

    @property
    def is_enabled(self):
        """ 是否启用新闻自动推送 """
        if self._job:
            return True
        else:
            return False

    @property
    def interval(self):
        """ 自动推送新闻的间隔,单位 分钟 """
        return int(self._data.get_config('ff14', 'push_news_interval', '30'))

    @property
    def last_news_id(self) -> int:
        """ 上次推送新闻的发布 ID """
        return int(self._data.get_config('ff14', 'push_news_last_news_id',
                                         '0'))

    @last_news_id.setter
    def last_news_id(self, news_id: int):
        self._data.set_config('ff14', 'push_news_last_news_id', str(news_id))

    async def get_news(self):
        """ 获取最新的新闻 """
        try:
            async with httpx.AsyncClient() as client:
                r = await client.get(self._url)
                if r.status_code != 200:
                    # 如果 HTTP 响应状态码不是 200,说明调用失败
                    return None
                return r.json()
        except (httpx.HTTPError, KeyError) as e:
            logger.error(f'获取新闻出错,{e}')
            # 抛出上面任何异常,说明调用失败
            return None

    def format_message(self, item):
        """ 格式化消息 """
        message = ''
        message += f'{item["Title"]}\n'
        message += f'{item["Author"]}\n'
        message += f'{item["Summary"]}'
        return message

    async def push_news(self):
        """ 推送消息 """
        logger.info('开始检查 最终幻想XIV 新闻')
        news_list = []

        news = await self.get_news()
        if news is None:
            logger.error('最终幻想XIV 新闻获取失败')
            return

        if not self.last_news_id:
            # 如果初次运行,则记录并发送第一条新闻
            self.last_news_id = news['Data'][0]['Id']
            news_list.append(news['Data'][0])

        for item in news['Data']:
            if item['Id'] <= self.last_news_id:
                break
            news_list.append(item)

        if news_list:
            # 添加最新的那一条新闻的 ID
            self.last_news_id = news_list[0]['Id']

            group_id = get_bot().config.GROUP_ID[0]
            for item in news_list:
                await get_bot().send_msg(message_type='group',
                                         group_id=group_id,
                                         message=self.format_message(item))