diff --git a/README.md b/README.md index 47ab6d1..4059f9b 100644 --- a/README.md +++ b/README.md @@ -145,6 +145,28 @@ XUN 是一个基于 [NoneBot](https://github.com/richardchien/nonebot) 和 [酷Q *此功能没有启用 `自然语言处理器` 模块,所以请用 `标准命令格式 + 查询单词` 的形式来使用* +### 留言板 + +![19.png](https://i.loli.net/2020/09/22/MdSUifzKTn2Ps3h.png) + +一个简单的留言板功能,可以留言或者查看留言,通过修改 `config.py` 中的 `MAX_MGB_LIST` 和 `MAX_MGB_WORD` 来修改查看留言的条数和留言的字数限制,详细配置请参考上面 [配置](#user-content-配置) 这一节的内容。 + +**查看的留言为所设置条数最新的几条留言,但所有的留言都保存在根目录下的 `msg_board.csv` 文件里** + +### 致电管理员 + +![20.png](https://i.loli.net/2020/09/22/I3mdNwfqx6j4kvW.png) + +通过小寻来致电管理员的功能,可通过修改 `config.py` 中的 `CALL_BLACK_DICT` 的值来设置黑名单,详细配置请参考上面 [配置](#user-content-配置) 这一节的内容。 + +### 群通知 + +![21.png](https://i.loli.net/2020/09/22/oVUnmP3AG2WFJQu.png) + +通过小寻来通知指定群的功能,可通过修改 `config.py` 中的 `PUSH_GROUP_DICT` 的值来设置要通知的群列表,详细配置请参考上面 [配置](#user-content-配置) 这一节的内容。 + +**此功能为管理员功能,非管理员无法唤醒** + ### 上车(已暂停更新,使用时可能会出现报错或者无反应) ![8.png](https://i.loli.net/2020/01/16/J5NSW2BfbjMK6VZ.png) @@ -256,6 +278,7 @@ SUPERUSERS = {123456} # 管理员(你)的QQ号 # ————————以下是部分功能模块需要的额外配置,请参见github上的说明进行配置———————— + # Permission类 PERMISSION_LEVEL: int = 6 # 权限等级值,建议不要设置为8以下 @@ -276,13 +299,15 @@ MAX_PERFORMANCE_PERCENT: List[int] = [92,92,92] # 自检功能中的服务器占 MAX_RSS_P: int = 2 MAX_RSS_G: int = 5 MAX_RSS_D: int = 5 # 以上三个分别为RSS订阅功能的个人(private)、群(group)、讨论组(discuss)订阅的最大订阅数限制 +MAX_MGB_WORD: int = 200 # 留言板功能的最大字数 +MAX_MGB_LIST:int = 5 # 留言板功能的最大查看留言条数 # TimeLimit类 TIMELIMIT_IMAGE: float = 7 # 识图功能的时间限制 TIMELIMIT_REIMU: float = 12 # 上车功能的时间限制 TIMELIMIT_JD: float = 7 # 日语词典功能的时间限制 TIMELIMIT_TRANSL: float = 7 # 翻译功能的时间限制 -TIMELIMIT_ANIME: float = 16 # 搜番功能的时间限制 +TIMELIMIT_ANIME: float = 12 # 搜番功能的时间限制 # Bool类 CONFIGURATION_WIZARD: bool = True # 设置每次运行时是否需要确认运行配置向导 @@ -309,6 +334,11 @@ RSSINTERVAL: dict = { # 'second': 0 } # RSS订阅功能的检查间隔, 作为 scheduled_job 的的参数传入,默认值的意思为每隔1小时检测一次。 + # 详细配置参考:https://apscheduler.readthedocs.io/en/latest/modules/triggers/interval.html?highlight=interval#module-apscheduler.triggers.interval +CALL_BLACK_DICT: dict = {123456} # 致电管理员功能的黑名单,需要填入qq号 +PUSH_GROUP_DICT: dict = {123456} # 群通知功能公告的群 + + # ————————————————————————————————————————————————————————————————————————— ``` @@ -330,6 +360,8 @@ RSSINTERVAL: dict = { * `MAXINFO_BT` :在 磁力搜索 功能中配置查找的资源的数量限制,最多只能显示指定数量的资源数,推荐设置为4。 * `MAXLINE_JD` :在 日文词典 功能中查找条目的内容所允许的最大行书,超过该条数的内容将被省略,并报出提示。 * `MAXWOED_JD` :在 日文词典 功能查找条目的内容所允许的最大字数,超过该字数的内容将被省略,并报出提示。 + * `MAX_MGB_WORD` :在 留言板 功能中留言所允许的最大字数,超过该字数的内容将无法留言,并报出提示。 + * `MAX_MGB_LIST` :在 留言板 功能中查看留言板中留言的最大条数,超过该条数的旧留言将被省略。 * `MAX_PERFORMANCE_PERCENT` : 在 自我检查 功能中的服务器占用比率最高值,需填入长度为3的list,根据顺序分别对应CPU、内存和硬盘的最大占有率,如果超过该值,在群聊中,进行自检时会有对应的回应,并向所有管理员发送通知。 * `MAX_RSS_P`&`MAX_RSS_G`&`MAX_RSS_D` :在 RSSHub订阅 功能中分别对应私人、群、讨论组的订阅数最大值,超过该值则不会完成订阅,并报出提示。 * TimeLimit类 @@ -348,6 +380,8 @@ RSSINTERVAL: dict = { * `PROCESS_NAME_LIST` :在 自我检查 功能中需要提供的格外检查的进程名,如果发现同名的进程中至少有一个进程的状态不是"running"的时候,在群聊中,进行自检时会有对应的回应,并向所有管理员发送通知。 * `TO_TRANSL` : 在 翻译 功能中指定翻译的目标语言,默认为中文,其他语言的列表请参考 [百度翻译开发者手册](http://api.fanyi.baidu.com/doc/21) 和 [Googletrans](https://github.com/ssut/py-googletrans) * `RSSINTERVAL` : 在 RSSHub订阅 功能中检查订阅列表更新的时间间隔,每个时间键的值类型应该为int,默认值的意思为每隔1小时检测一次,如果想设置为每半小时检查一次,应该注释掉`hour`行,取消`minutes`行的注释,并把对应值`0`改为`30`。不建议设置为10分钟以下。该值其实是作为 `scheduled_job` 的的参数传入的,详细说明参考 [官方说明](https://apscheduler.readthedocs.io/en/latest/modules/triggers/interval.html?highlight=interval#module-apscheduler.triggers.interval)。 + * `CALL_BLACK_DICT` :在 致电管理员 功能中设置黑名单,在黑名单中的QQ号将无法致电。 + * `PUSH_GROUP_DICT` :在 群通知 功能中设置需要通知的群,当管理员使用该功能通知时,仅通知所含指定群。
diff --git a/config.py b/config.py index ac9f453..1bd2da8 100644 --- a/config.py +++ b/config.py @@ -14,6 +14,7 @@ # ————————以下是部分功能模块需要的额外配置,请参见github上的说明进行配置———————— + # Permission类 PERMISSION_LEVEL: int = 6 # 权限等级值,建议不要设置为8以下 @@ -34,6 +35,8 @@ MAX_RSS_P: int = 2 MAX_RSS_G: int = 5 MAX_RSS_D: int = 5 # 以上三个分别为RSS订阅功能的个人(private)、群(group)、讨论组(discuss)订阅的最大订阅数限制 +MAX_MGB_WORD: int = 200 # 留言板功能的最大字数 +MAX_MGB_LIST:int = 5 # 留言板功能的最大查看留言条数 # TimeLimit类 TIMELIMIT_IMAGE: float = 7 # 识图功能的时间限制 @@ -68,5 +71,8 @@ } # RSS订阅功能的检查间隔, 作为 scheduled_job 的的参数传入,默认值的意思为每隔1小时检测一次。 # 详细配置参考:https://apscheduler.readthedocs.io/en/latest/modules/triggers/interval.html?highlight=interval#module-apscheduler.triggers.interval +CALL_BLACK_DICT: dict = {123456} # 致电管理员功能的黑名单,需要填入qq号 +PUSH_GROUP_DICT: dict = {123456} # 群通知功能公告的群 + # ————————————————————————————————————————————————————————————————————————— \ No newline at end of file diff --git a/xunbot/plugins/call_admin/__init__.py b/xunbot/plugins/call_admin/__init__.py new file mode 100644 index 0000000..af5ef5a --- /dev/null +++ b/xunbot/plugins/call_admin/__init__.py @@ -0,0 +1,64 @@ +import time + +from nonebot import on_command, CommandSession, permission + +from ...xlog import xlogger +from xunbot import get_bot + +Bot = get_bot() + +CALL_BLACK_DICT = Bot.config.CALL_BLACK_DICT +SUPERUSERS = Bot.config.SUPERUSERS + +__plugin_name__ = '致电管理员' +__plugin_usage__ = r""" +让小寻帮忙致电管理员 + +*请不要发无意义的内容* + +call_admin [致电内容] +致电管理员 [内容] + +eg. +call_admin 小寻XX功能失效了 +致电管理员 希望加入XX功能 +""".strip() + + +@on_command('call_admin', aliases=('call_admin', '致电管理员', '致電管理員'), permission=Bot.level) +async def call_admin(session: CommandSession): + id = session.event['user_id'] + + if id not in CALL_BLACK_DICT: + info = session.get('info', prompt='给我你需要致电的信息') + xlogger.info("Get Information: {} \nfrom ID: {}".format(info, id)) + + if SUPERUSERS: + sender_info = "\n——@{}({}) | {}".format(session.event['sender']['nickname'], id, + time.strftime("%Y-%m-%d", time.localtime(session.event['time']))) + + for admin in SUPERUSERS: + await Bot.send_private_msg(user_id=admin, message="您有一条致电的信息:") + await Bot.send_private_msg(user_id=admin, message=info + sender_info) + await session.send("致电成功:)") + xlogger.info("Successful call admin") + else: + await session.send("……管理员鸽了,知道管理员在哪儿摸鱼的话请把他拖回来~") + else: + xlogger.info("ID: {} wanna call admin, but in blacklist".format(id)) + await session.send("致电失败:)\n您已被列入黑名单,无法致电") + + +@call_admin.args_parser +async def _(session: CommandSession): + arg = session.current_arg + + if session.is_first_run: + if arg: + session.state['info'] = arg + return + + if not arg: + session.pause('管理员让我给宁带个话:宁搁这儿虚空致电呢?GKD把信息给我!') + + session.state[session.current_key] = arg \ No newline at end of file diff --git a/xunbot/plugins/help/__init__.py b/xunbot/plugins/help/__init__.py index dcbeb7b..c2c1f89 100644 --- a/xunbot/plugins/help/__init__.py +++ b/xunbot/plugins/help/__init__.py @@ -12,7 +12,7 @@ ps.无参数时,返回功能列表 eg. help [无参数] #返回功能列表 -help [功能名称] +help 使用帮助 """.strip() diff --git a/xunbot/plugins/message_board/__init__.py b/xunbot/plugins/message_board/__init__.py new file mode 100644 index 0000000..5150dc7 --- /dev/null +++ b/xunbot/plugins/message_board/__init__.py @@ -0,0 +1,43 @@ +import time + +from nonebot import on_command, CommandSession, permission + +from .data_source import get_msg_from_board, save_msg_board +from ...xlog import xlogger +from xunbot import get_bot + +Bot = get_bot() +MAX_MGB_WORD = Bot.config.MAX_MGB_WORD +MAX_MGB_LIST = Bot.config.MAX_MGB_LIST + + +__plugin_name__ = '留言板' +__plugin_usage__ = r""" +在留言板上进行留言或者查看留言 + +注意留言字数不要超过{}字 +最多查看最后{}条留言 + +mgb [留言] +留言板 [留言] +ps.无参数时,为查看留言 + +eg. +mgb sk是屑的天花板 +留言板 skwlp +mgb #查看留言 +""".format(MAX_MGB_WORD,MAX_MGB_LIST).strip() + + +@on_command('message_board', aliases=('mgb', '留言板'), permission=Bot.level) +async def message_board(session: CommandSession): + msg = session.current_arg_text.strip() + if msg: + if len(msg) <= MAX_MGB_WORD: + save_msg_board(session.event['sender'], msg, session.event['time']) + await session.send("留言成功:)") + else: + await session.send("留言失败:(\n超过字数限制,请不要超过{}字。".format(MAX_MGB_WORD)) + else: + message_board_report = await get_msg_from_board(MAX_MGB_LIST) + await session.send(message_board_report) \ No newline at end of file diff --git a/xunbot/plugins/message_board/data_source.py b/xunbot/plugins/message_board/data_source.py new file mode 100644 index 0000000..11f854f --- /dev/null +++ b/xunbot/plugins/message_board/data_source.py @@ -0,0 +1,38 @@ +import time +from os import path, getcwd + +import pandas as pd + +from ...xlog import xlogger + + +async def get_msg_from_board(num: int) -> str: + try: + all_msg = load_msg_board() + except FileNotFoundError as e: + return "暂时没有留言" + + line_list = ["{}\n——@{}({}) | {}".format( + data['message'], data['nickname'], data['id'], + time.strftime("%Y-%m-%d", time.localtime(data['time']))) + for index, data in all_msg[-num:].iterrows()] + + return "\n\n".join(line_list) + + +def load_msg_board() -> pd.DataFrame: + all_msg = pd.read_csv(getcwd() + "\\msg_board.csv").sort_values(by='time') + xlogger.info("Message board data read successfully") + return all_msg + + +def save_msg_board(sender: dict, msg: str, time: int): + msg_board_f = open(getcwd() + '\\msg_board.csv', "a", encoding='utf-8') + if not msg_board_f.tell(): + msg_board_f.write("nickname,id,time,message" + "\n") + + info = "{},{},{},{}".format(sender['nickname'], sender['user_id'], time, msg) + msg_board_f.write(info + "\n") + xlogger.debug("Message board is written {}".format(info)) + msg_board_f.close() + xlogger.info("Message board saved successfully") \ No newline at end of file diff --git a/xunbot/plugins/notice/__init__.py b/xunbot/plugins/notice/__init__.py new file mode 100644 index 0000000..3299895 --- /dev/null +++ b/xunbot/plugins/notice/__init__.py @@ -0,0 +1,50 @@ +import time + +from nonebot import on_command, CommandSession, permission + +from ...xlog import xlogger +from xunbot import get_bot + +Bot = get_bot() + +PUSH_GROUP_DICT = Bot.config.PUSH_GROUP_DICT + +__plugin_name__ = '群通知' +__plugin_usage__ = r""" +【管理员功能】 +用于管理员通知群的功能 + +通知 【信息】 +push 【信息】 +""".strip() + + +@on_command('notice', aliases=('push', '通知'), permission=0xF000) +async def notice(session: CommandSession): + info = session.get('info', prompt='请给出需要通知的信息') + + if PUSH_GROUP_DICT: + header = "🔈群通知🔈\n\n" + sender_info = "\n\n——{}(管理员) 发布于 {}".format(session.event['sender']['nickname'], + time.strftime("%Y-%m-%d", time.localtime(session.event['time']))) + + for group in PUSH_GROUP_DICT: + await Bot.send_group_msg(group_id=group, message=header + info + sender_info) + await session.send("通知成功:)") + else: + await session.send("没有要通知的群,请注意修改config.py文件中对应值") + + +@notice.args_parser +async def _(session: CommandSession): + arg = session.current_arg + + if session.is_first_run: + if arg: + session.state['info'] = arg + return + + if not arg: + session.pause('通知的信息不能为空,请重新输入') + + session.state[session.current_key] = arg \ No newline at end of file