Пример #1
0
    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()
Пример #2
0
    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()
Пример #3
0
    subprocess.run(f'cd "{YOBOT_DIR}" && git checkout . && git pull',
                   shell=True,
                   check=True)
    return '升级成功,请重新启动'


if not YOBOT_DIR.exists():
    download_yobot()

# 配置 Yobot
configure_yobot()

from .yobot.src.client.yobot import Yobot

DATA = PluginData('pcr')

verinfo = {
    "run-as": "nonebot-plugin",
    "ver_name": "yobot{}".format(Yobot.Version),
}

cqbot = get_bot()
bot = Yobot(
    data_path=str(DATA._base_path),
    verinfo=verinfo,
    scheduler=scheduler,
    quart_app=cqbot.server_app,
    bot_api=cqbot._api,
)
Пример #4
0
""" 每日早安插件
"""
import re
from random import randint

import requests
from nonebot import CommandSession, on_command

from coolqbot import PluginData, bot

DATA = PluginData('morning', config=True)

HOUR = int(DATA.config_get('morning', 'hour', fallback='7'))
MINUTE = int(DATA.config_get('morning', 'minute', fallback='30'))
SECOND = int(DATA.config_get('morning', 'second', fallback='0'))


@bot.scheduler.scheduled_job('cron',
                             hour=HOUR,
                             minute=MINUTE,
                             second=SECOND,
                             id='morning')
async def morning():
    """ 早安
    """
    hello_str = get_message()
    await bot.get_bot().send_msg(message_type='group',
                                 group_id=bot.get_bot().config.GROUP_ID,
                                 message=hello_str)
    bot.logger.info('发送早安信息')
Пример #5
0
""" 记录数据
"""
from datetime import datetime, timedelta

from coolqbot import PluginData, bot


def get_history_pkl_name(dt):
    time_str = dt.strftime('%Y-%m')
    return time_str


DATA = PluginData('recorder')


class Recorder:
    def __init__(self, data=None):
        self._name = 'recorder'

        # 运行数据
        self.last_message_on = datetime.now()
        self._msg_send_time = []
        self._repeat_list = {}
        self._msg_number_list = {}

        # 酷Q 状态
        self.start_time = datetime.now()
        self.coolq_status = False
        # 是否需要发送问好
        self.send_hello = False
Пример #6
0
""" 图灵机器人

http://www.turingapi.com/
"""
import json
from typing import Optional

import httpx
from nonebot import CommandSession
from nonebot.helpers import context_id

from coolqbot import PluginData

DATA = PluginData('robot', config=True)
TULING_API_KEY = DATA.get_config('tuling', 'api_key')


async def call_tuling_api(session: CommandSession, text: str) -> Optional[str]:
    """ 调用图灵机器人的 API 获取回复
    """
    if not TULING_API_KEY:
        return None

    if not text:
        return None

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

    # 构造请求数据
    payload = {
        'reqType': 0,
Пример #7
0
"""
import hashlib
import json
import random
import string
import time
from typing import Optional
from urllib import parse

import aiohttp
from nonebot import CommandSession
from nonebot.helpers import context_id

from coolqbot import PluginData

DATA = PluginData('robot', config=True)
TENCENT_AI_APP_ID = DATA.config_get('tencent', 'app_id')
TENCENT_AI_APP_KEY = DATA.config_get('tencent', 'app_key')


async def call_tencent_api(session: CommandSession,
                           text: str) -> Optional[str]:
    """ 调用腾讯机器人的 API 获取回复
    """
    if not TENCENT_AI_APP_KEY:
        return None

    if not text:
        return None

    url = 'https://api.ai.qq.com/fcgi-bin/nlp/nlp_textchat'
Пример #8
0
"""
from nonebot import CommandGroup

from coolqbot import PluginData

__plugin_name__ = 'repeat'
__plugin_usage__ = r"""
人类本质

用来模仿人类,同时提供排行榜,历史记录和记录复读状态功能。

例如:
-------排行榜---------
/rank
/rank 30n0
-------历史记录-------
/history
/history 2020-01
/history 2020-01-01
-------状态-----------
/status

命令均需要在群里使用。
""".strip()

cg = CommandGroup('repeat')

DATA = PluginData('repeat', config=True)

from . import commands, nlp
Пример #9
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}
Пример #10
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))
Пример #11
0
""" 一些数据

副本与职业数据
"""
from dataclasses import dataclass
from typing import Dict, List, Optional

from coolqbot import PluginData

DATA = PluginData('fflogs', config=True)

# (zone, encounter, difficulty): [nicknames]
boss_list = {
    (28, 1045, 100): ['提坦妮雅歼殛战', '缇坦妮雅', '妖精', '极妖精', '妖灵王', '妖精王', '老婆', '10王'],
    (28, 1046, 100): ['无瑕灵君歼殛战', '无瑕灵君', '肥宅', '极肥宅', '全能王'],
    (28, 1049, 100): ['哈迪斯歼殛战', '哈迪斯', '老公'],
    (29, 65, 100):   ['伊甸希望乐园 觉醒之章1', 'E1', 'e1'],
    (29, 66, 100):   ['伊甸希望乐园 觉醒之章2', 'E2', 'e2'],
    (29, 67, 100):   ['伊甸希望乐园 觉醒之章3', 'E3', 'e3'],
    (29, 68, 100):   ['伊甸希望乐园 觉醒之章4', 'E4', 'e4'],
    (29, 65, 0):     ['伊甸零式希望乐园 觉醒之章1', 'E1S', 'e1s', 'E1s', 'e1S'],
    (29, 66, 0):     ['伊甸零式希望乐园 觉醒之章2', 'E2S', 'e2s', 'E2s', 'e2S'],
    (29, 67, 0):     ['伊甸零式希望乐园 觉醒之章3', 'E3S', 'e3s', 'E3s', 'e3S'],
    (29, 68, 0):     ['伊甸零式希望乐园 觉醒之章4', 'E4S', 'e4s', 'E4s', 'e4S'],
} # yapf: disable

# spec: [nicknames]
job_list = {
    1:  ['占星术士', '占星'],
    2:  ['吟游诗人', '诗人'],
    3:  ['黑魔法师', '黑魔', '伏地魔', '永动机'],
Пример #12
0
""" 历史记录插件
"""
import re
from calendar import monthrange
from datetime import datetime, timedelta

from dateutil.relativedelta import relativedelta
from nonebot import CommandSession, on_command, permission

from coolqbot import PluginData, bot

from .rank import Ranking
from .recorder import Recorder, get_history_pkl_name, recorder

DATA = PluginData('history')


@bot.scheduler.scheduled_job('cron',
                             day=1,
                             hour=0,
                             minute=0,
                             second=0,
                             id='clear_data')
async def clear_data():
    """ 每个月最后一天 24 点(下月 0 点)保存记录于历史记录文件夹,并重置记录
    """
    # 保存数据到历史文件夹
    date = datetime.now() - timedelta(hours=1)
    DATA.save_pkl(recorder.get_data(), get_history_pkl_name(date))
    # 清除现有数据
    recorder.init_data()
Пример #13
0
""" 和风天气
"""
import json
import re
import urllib

import requests

from coolqbot import PluginData

DATA = PluginData('weather', config=True)
KEY = DATA.config_get('heweather', 'key')


def heweather(city):
    """ 和风天气 API

    日本 东京
    当前温度:25(体感温度:29)
    2018-08-13 中雨 降水概率:0% 温度:32~26℃
    2018-08-14 小雨 降水概率:13% 温度:33~26℃
    2018-08-15 小雨 降水概率:11% 温度:32~25℃
    """
    if not KEY:
        return None

    try:
        city_name = urllib.parse.quote(city.encode('utf-8'))
        url_str = f'https://free-api.heweather.com/s6/weather?location={city_name}&key={KEY}'
        response = requests.get(url_str)
        data = response.content.decode('utf-8')
Пример #14
0
""" 复读插件
"""
import re
import secrets
from datetime import datetime, timedelta

from nonebot import (CommandSession, IntentCommand, NLPSession, on_command,
                     on_natural_language, on_notice, permission)

from coolqbot import PluginData, bot

from .recorder import recorder

DATA = PluginData('repeat', config=True)
# 复读概率
REPEAT_RATE = int(DATA.config_get('bot', 'repeat_rate', fallback='10'))
# 复读间隔
REPEAT_INTERVAL = int(DATA.config_get('bot', 'repeat_interval', fallback='1'))


def is_repeat(session: CommandSession, message):
    group_id = session.ctx['group_id']
    user_id = session.ctx['sender']['user_id']
    # 只复读指定群内消息
    if group_id not in session.bot.config.GROUP_ID:
        return False

    # 不要复读指令
    match = re.match(r'^\/', message)
    if match:
        return False
Пример #15
0
""" 和风天气
"""
import re
import urllib

import httpx

from coolqbot import PluginData

DATA = PluginData('weather', config=True)
KEY = DATA.get_config('heweather', 'key')


async def heweather(city):
    """ 和风天气 API

    日本 东京
    当前温度:25(体感温度:29)
    2018-08-13 中雨 降水概率:0% 温度:32~26℃
    2018-08-14 小雨 降水概率:13% 温度:33~26℃
    2018-08-15 小雨 降水概率:11% 温度:32~25℃
    """
    if not KEY:
        return None

    try:
        city_name = urllib.parse.quote(city.encode('utf-8'))
        url_str = f'https://free-api.heweather.com/s6/weather?location={city_name}&key={KEY}'
        async with httpx.AsyncClient() as client:
            resp = await client.get(url_str)
        weather_result = resp.json()['HeWeather6'][0]