From f7198e8722f310926cf147bd0b218c5d9ef5d6c3 Mon Sep 17 00:00:00 2001
From: Kyomotoi <1172294279@qq.com>
Date: Sun, 22 Nov 2020 01:01:43 +0800
Subject: [Update]
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
新增:
* 舆情检测
* 对涩图加以调用限制
修复:
* Pixiv插件全体
* 储存群聊信息时无法创建文件
优化:
* 部分代码重构,效率up
* 调整插件结构,使其看起来更舒服
---
ATRI/__init__.py | 77 ++++++++
ATRI/check.py | 111 +++++++++++
ATRI/data/data_Error/error.json | 2 +-
ATRI/data/data_HTML/api/data/times/api_all.json | 2 +-
ATRI/data/data_HTML/api/data/times/api_index.json | 2 +-
ATRI/data/data_Sqlite/setu/nearR18.db | Bin 81920 -> 0 bytes
ATRI/data/data_Sqlite/setu/normal.db | Bin 36864 -> 0 bytes
ATRI/data/data_Sqlite/setu/r18.db | Bin 12288 -> 0 bytes
ATRI/plugins/plugin_admin/__init__.py | 164 +++++++---------
ATRI/plugins/plugin_anime/__init__.py | 151 +++++++--------
ATRI/plugins/plugin_anime/body.py | 71 -------
ATRI/plugins/plugin_anime/data_source.py | 71 +++++++
ATRI/plugins/plugin_anime/sepi_list.json | 1 +
ATRI/plugins/plugin_chat/__init__.py | 196 ++++++++++++++++---
ATRI/plugins/plugin_chat/drifting_bottle.json | 1 +
ATRI/plugins/plugin_chat/public_opinion.json | 0
ATRI/plugins/plugin_pixiv/__init__.py | 84 +++++----
ATRI/plugins/plugin_rich/__init__.py | 14 +-
ATRI/plugins/plugin_rich/body.py | 32 ----
ATRI/plugins/plugin_rich/data_source.py | 34 ++++
ATRI/plugins/plugin_sqlite/__init__.py | 19 +-
ATRI/plugins/plugin_status/__init__.py | 8 +-
ATRI/plugins/plugin_test/__init__.py | 15 +-
ATRI/plugins/plugin_utils/__init__.py | 42 +++--
ATRI/plugins/plugin_utils/data_source.py | 194 +++++++++++++++++++
ATRI/plugins/plugin_utils/generate.py | 47 -----
ATRI/plugins/plugin_utils/genshin.py | 118 ------------
ATRI/plugins/plugin_utils/roll.py | 59 ------
ATRI/utils/utils_ban/__init__.py | 25 +++
ATRI/utils/utils_error/__init__.py | 54 ++++++
ATRI/utils/utils_history/__init__.py | 105 +++++++++++
ATRI/utils/utils_img/__init__.py | 62 ++++++
ATRI/utils/utils_request/__init__.py | 39 ++++
ATRI/utils/utils_rule/__init__.py | 151 +++++++++++++++
ATRI/utils/utils_rule/ban_list_group.json | 1 +
ATRI/utils/utils_rule/ban_list_user.json | 1 +
ATRI/utils/utils_rule/switch.json | 1 +
ATRI/utils/utils_switch/__init__.py | 79 ++++++++
ATRI/utils/utils_textcheck/__init__.py | 60 ++++++
ATRI/utils/utils_textcheck/public_opinion.json | 1 +
ATRI/utils/utils_times/__init__.py | 27 +++
ATRI/utils/utils_translate/__init__.py | 56 ++++++
ATRI/utils/utils_yml/__init__.py | 25 +++
LICENSE | 219 ----------------------
bot.py | 72 +------
check.py | 77 --------
config.yml | 15 +-
utils/utils_error/__init__.py | 54 ------
utils/utils_history/__init__.py | 108 -----------
utils/utils_img/__init__.py | 62 ------
utils/utils_request/__init__.py | 39 ----
utils/utils_rule/__init__.py | 143 --------------
utils/utils_rule/ban_list_group.json | 1 -
utils/utils_rule/ban_list_user.json | 1 -
utils/utils_rule/switch.json | 1 -
utils/utils_switch/__init__.py | 80 --------
utils/utils_times/__init__.py | 27 ---
utils/utils_translate/__init__.py | 56 ------
utils/utils_yml/__init__.py | 25 ---
59 files changed, 1591 insertions(+), 1591 deletions(-)
create mode 100644 ATRI/__init__.py
create mode 100644 ATRI/check.py
delete mode 100644 ATRI/data/data_Sqlite/setu/nearR18.db
delete mode 100644 ATRI/data/data_Sqlite/setu/normal.db
delete mode 100644 ATRI/data/data_Sqlite/setu/r18.db
delete mode 100644 ATRI/plugins/plugin_anime/body.py
create mode 100644 ATRI/plugins/plugin_anime/data_source.py
create mode 100644 ATRI/plugins/plugin_anime/sepi_list.json
create mode 100644 ATRI/plugins/plugin_chat/drifting_bottle.json
delete mode 100644 ATRI/plugins/plugin_chat/public_opinion.json
delete mode 100644 ATRI/plugins/plugin_rich/body.py
create mode 100644 ATRI/plugins/plugin_rich/data_source.py
create mode 100644 ATRI/plugins/plugin_utils/data_source.py
delete mode 100644 ATRI/plugins/plugin_utils/generate.py
delete mode 100644 ATRI/plugins/plugin_utils/genshin.py
delete mode 100644 ATRI/plugins/plugin_utils/roll.py
create mode 100644 ATRI/utils/utils_ban/__init__.py
create mode 100644 ATRI/utils/utils_error/__init__.py
create mode 100644 ATRI/utils/utils_history/__init__.py
create mode 100644 ATRI/utils/utils_img/__init__.py
create mode 100644 ATRI/utils/utils_request/__init__.py
create mode 100644 ATRI/utils/utils_rule/__init__.py
create mode 100644 ATRI/utils/utils_rule/ban_list_group.json
create mode 100644 ATRI/utils/utils_rule/ban_list_user.json
create mode 100644 ATRI/utils/utils_rule/switch.json
create mode 100644 ATRI/utils/utils_switch/__init__.py
create mode 100644 ATRI/utils/utils_textcheck/__init__.py
create mode 100644 ATRI/utils/utils_textcheck/public_opinion.json
create mode 100644 ATRI/utils/utils_times/__init__.py
create mode 100644 ATRI/utils/utils_translate/__init__.py
create mode 100644 ATRI/utils/utils_yml/__init__.py
delete mode 100644 LICENSE
delete mode 100644 check.py
delete mode 100644 utils/utils_error/__init__.py
delete mode 100644 utils/utils_history/__init__.py
delete mode 100644 utils/utils_img/__init__.py
delete mode 100644 utils/utils_request/__init__.py
delete mode 100644 utils/utils_rule/__init__.py
delete mode 100644 utils/utils_rule/ban_list_group.json
delete mode 100644 utils/utils_rule/ban_list_user.json
delete mode 100644 utils/utils_rule/switch.json
delete mode 100644 utils/utils_switch/__init__.py
delete mode 100644 utils/utils_times/__init__.py
delete mode 100644 utils/utils_translate/__init__.py
delete mode 100644 utils/utils_yml/__init__.py
diff --git a/ATRI/__init__.py b/ATRI/__init__.py
new file mode 100644
index 0000000..c795e29
--- /dev/null
+++ b/ATRI/__init__.py
@@ -0,0 +1,77 @@
+#!/usr/bin/env python3
+# -*- encoding: utf-8 -*-
+'''
+@File : __init__.py
+@Time : 2020/11/21 09:53:07
+@Author : Kyomotoi
+@Contact : kyomotoiowo@gmail.com
+@Github : https://github.com/Kyomotoi
+@License : Copyright © 2018-2020 Kyomotoi, All Rights Reserved.
+'''
+__author__ = 'kyomotoi'
+
+from .check import checkATRI
+
+checkATRI().chechConfig()
+checkATRI().checkRely()
+
+import time
+import nonebot
+import datetime
+from pathlib import Path
+from .utils.utils_yml import load_yaml
+from nonebot.log import default_format, logger
+
+COPYRIGHT = (r"""====================[ATRI | アトリ]====================
+* Mirai + NoneBot2 + Python
+* Copyright © 2018-2020 Kyomotoi,All Rights Reserved
+* Project: https://github.com/Kyomotoi/ATRI
+* Blog: blog.lolihub.icu
+=======================================================""")
+print(COPYRIGHT)
+time.sleep(1)
+
+CONFIG_PATH = Path('.') / 'config.yml'
+config = load_yaml(CONFIG_PATH)
+config = config['bot']
+
+LOGGER_INFO_PATH = Path(
+ '.'
+) / 'logs' / 'info' / f"{datetime.datetime.now().strftime('%Y%m%d-%H%M%S')}-INFO.log"
+LOGGER_ERROR_PATH = Path(
+ '.'
+) / 'logs' / 'error' / f"{datetime.datetime.now().strftime('%Y%m%d-%H%M%S')}-ERROR.log"
+
+_app = None
+
+
+class Service:
+ def init(self) -> None:
+ global _app
+ logger.info('ATRI is initializing...')
+ nonebot.init(debug=bool(config['debug']),
+ superusers=set(config['superusers']),
+ nickname=set(config['nickname']),
+ command_start=set(config['command_start']),
+ command_sep=set(config['command_sep']))
+
+ _app = nonebot.get_asgi()
+
+ nonebot.load_plugins('ATRI/plugins')
+
+ logger.add(LOGGER_INFO_PATH,
+ rotation='10 MB',
+ diagnose=False,
+ level='INFO',
+ format=default_format)
+ logger.add(LOGGER_ERROR_PATH,
+ rotation='10 MB',
+ diagnose=False,
+ level='ERROR',
+ format=default_format)
+
+ def run(self) -> None:
+ logger.info("Running ATRI...")
+ nonebot.get_driver().run(app='ATRI:_app', # type: ignore
+ host=config['host'],
+ port=config['port'])
diff --git a/ATRI/check.py b/ATRI/check.py
new file mode 100644
index 0000000..8be8c5c
--- /dev/null
+++ b/ATRI/check.py
@@ -0,0 +1,111 @@
+#!/usr/bin/env python3
+# -*- encoding: utf-8 -*-
+'''
+@File : check.py
+@Time : 2020/11/07 14:30:34
+@Author : Kyomotoi
+@Contact : kyomotoiowo@gmail.com
+@Github : https://github.com/Kyomotoi
+@License : Copyright © 2018-2020 Kyomotoi, All Rights Reserved.
+'''
+__author__ = 'kyomotoi'
+
+import os
+import sys
+import time
+import pkg_resources
+
+rely_list = ''.join(f'{rely}' for rely in pkg_resources.working_set)
+need_rely_list = ['pathlib', 'pyyaml', 'rich']
+for rely in need_rely_list:
+ if rely not in rely_list:
+ os.system(f'pip3 install {rely}')
+
+from pathlib import Path
+from rich.progress import Progress
+from .utils.utils_yml import load_yaml
+
+CONFIG_PATH = Path('.') / 'config.yml'
+config = load_yaml(CONFIG_PATH)
+
+
+class checkATRI():
+ """运行前检查必要条件"""
+ def chechConfig(self) -> None:
+ """检查配置文件是否填写完整"""
+ len_config = len(config) + len(config['bot']) + len(
+ config['api']) + len(config['html'])
+
+ with Progress() as progress:
+ task = progress.add_task("[cyan]Checking Config...",
+ total=len_config)
+
+ while not progress.finished:
+ # 检查基本配置
+ bot = config['bot']
+ for key in bot:
+ if key == 'debug':
+ if bot['debug'] != 0:
+ print('DEBUG now is open.')
+ progress.update(task, advance=1)
+ time.sleep(0.1)
+ else:
+ if not bot[key]:
+ print(f"Can't load [{key}] from config.yml")
+ time.sleep(5)
+ sys.exit(0)
+
+ else:
+ progress.update(task, advance=1)
+ time.sleep(0.1)
+
+ # 检查接口配置
+ api = config['api']
+ for key in api:
+ if not api[key]:
+ print(f"Can't load [{key}] from config.yml")
+ time.sleep(5)
+ sys.exit(0)
+ else:
+ progress.update(task, advance=1)
+ time.sleep(0.1)
+
+ # 检查网页配置
+ html = config['html']
+ for key in html:
+ if not html[key]:
+ print(f"Can't load [{key}] from config.yml")
+ time.sleep(5)
+ sys.exit(0)
+ else:
+ progress.update(task, advance=1)
+ time.sleep(0.1)
+
+ def checkRely(self) -> None:
+ '''
+ 检查依赖是否完整
+ 如不完整自动安装
+ 别吐槽 暴 力
+ '''
+ rely_list = [
+ 'nonebot2', 'nonebot2[scheduler]', 'nonebot2[test]', 'nltk',
+ 'requests', 'pillow', 'psutil'
+ ]
+ rely_len = len(rely_list)
+
+ with Progress() as progress:
+ task = progress.add_task("[cyan]Checking Rely...", total=rely_len)
+
+ while not progress.finished:
+ for rely in rely_list:
+ if rely not in rely_list:
+ try:
+ os.system(f'pip3 install {rely}')
+ except:
+ print(
+ "Can't install package {rely}. Please use Google/Bing search error repo and fix it by yourself."
+ )
+ time.sleep(5)
+ sys.exit(0)
+ progress.update(task, advance=1)
+ time.sleep(0.1)
diff --git a/ATRI/data/data_Error/error.json b/ATRI/data/data_Error/error.json
index 9e26dfe..afcc10e 100644
--- a/ATRI/data/data_Error/error.json
+++ b/ATRI/data/data_Error/error.json
@@ -1 +1 @@
-{}
\ No newline at end of file
+{"DKkj6IEFz0ArpaGh": "Traceback (most recent call last):\n File \"ATRI/plugins\\plugin_chat\\__init__.py\", line 179, in _\n await fxxkMe.finish(request_api_text(URL))\n File \"C:\\Users\\Administrator.DESKTOP-D764LND\\AppData\\Local\\Programs\\Python\\Python38\\lib\\site-packages\\nonebot\\matcher.py\", line 583, in finish\n raise FinishedException\nnonebot.exception.FinishedException\n", "piNxHF16v4mWODBX": "Traceback (most recent call last):\n File \"ATRI/plugins\\plugin_utils\\__init__.py\", line 106, in _\n uid_info = JsonAnalysis(GetInfo(uid))\n File \"ATRI/plugins\\plugin_utils\\genshin.py\", line 66, in JsonAnalysis\n Character_List = data[\"data\"][\"avatars\"]\nTypeError: 'NoneType' object is not subscriptable\n"}
\ No newline at end of file
diff --git a/ATRI/data/data_HTML/api/data/times/api_all.json b/ATRI/data/data_HTML/api/data/times/api_all.json
index 9e26dfe..415b649 100644
--- a/ATRI/data/data_HTML/api/data/times/api_all.json
+++ b/ATRI/data/data_HTML/api/data/times/api_all.json
@@ -1 +1 @@
-{}
\ No newline at end of file
+{"1604140447.514061": ["127.0.0.1:28598", {"status": "fail", "message": "reserved range", "query": "127.0.0.1"}, "index"], "1604140466.7449028": ["127.0.0.1:28648", {"status": "fail", "message": "reserved range", "query": "127.0.0.1"}, "index"]}
\ No newline at end of file
diff --git a/ATRI/data/data_HTML/api/data/times/api_index.json b/ATRI/data/data_HTML/api/data/times/api_index.json
index 9e26dfe..88778a1 100644
--- a/ATRI/data/data_HTML/api/data/times/api_index.json
+++ b/ATRI/data/data_HTML/api/data/times/api_index.json
@@ -1 +1 @@
-{}
\ No newline at end of file
+{"1604140447.514061": ["127.0.0.1:28598", {"status": "fail", "message": "reserved range", "query": "127.0.0.1"}], "1604140466.7449028": ["127.0.0.1:28648", {"status": "fail", "message": "reserved range", "query": "127.0.0.1"}]}
\ No newline at end of file
diff --git a/ATRI/data/data_Sqlite/setu/nearR18.db b/ATRI/data/data_Sqlite/setu/nearR18.db
deleted file mode 100644
index 5cedb05..0000000
Binary files a/ATRI/data/data_Sqlite/setu/nearR18.db and /dev/null differ
diff --git a/ATRI/data/data_Sqlite/setu/normal.db b/ATRI/data/data_Sqlite/setu/normal.db
deleted file mode 100644
index caf04d8..0000000
Binary files a/ATRI/data/data_Sqlite/setu/normal.db and /dev/null differ
diff --git a/ATRI/data/data_Sqlite/setu/r18.db b/ATRI/data/data_Sqlite/setu/r18.db
deleted file mode 100644
index 7bcd784..0000000
Binary files a/ATRI/data/data_Sqlite/setu/r18.db and /dev/null differ
diff --git a/ATRI/plugins/plugin_admin/__init__.py b/ATRI/plugins/plugin_admin/__init__.py
index b83da69..7dd18e7 100644
--- a/ATRI/plugins/plugin_admin/__init__.py
+++ b/ATRI/plugins/plugin_admin/__init__.py
@@ -1,6 +1,5 @@
#!/usr/bin/env python3
# -*- encoding: utf-8 -*-
-
'''
@File : __init__.py
@Time : 2020/10/11 14:37:53
@@ -18,13 +17,14 @@ from pathlib import Path
from random import randint
from nonebot.plugin import on_command
-from nonebot.adapters.cqhttp import Bot, Event
+from nonebot.typing import Bot, Event
from nonebot.permission import GROUP_ADMIN, GROUP_OWNER, SUPERUSER
-from utils.utils_yml import load_yaml
-from utils.utils_error import errorRepo
-from utils.utils_rule import check_banlist
-from utils.utils_switch import controlSwitch
+from ATRI.utils.utils_yml import load_yaml
+from ATRI.utils.utils_error import errorRepo
+from ATRI.utils.utils_rule import check_banlist
+from ATRI.utils.utils_textcheck import PUBLIC_OPINION_PATH, Textcheck
+from ATRI.utils.utils_switch import controlSwitch
CONFIG_PATH = Path('.') / 'config.yml'
master = load_yaml(CONFIG_PATH)['bot']['superusers']
@@ -34,26 +34,25 @@ switch = on_command('switch',
permission=(SUPERUSER | GROUP_OWNER | GROUP_ADMIN))
-@switch.handle() # type: ignore
+@switch.handle()
async def _(bot: Bot, event: Event, state: dict) -> None:
user = str(event.user_id)
group = str(event.group_id)
-
func = str(event.message).strip()
+ SWITCH_PATH = Path('.') / 'ATRI' / 'utils' / 'utils_rule' / 'switch.json'
+ with open(SWITCH_PATH, 'r') as f:
+ data = json.load(f)
+
if not func:
msg0 = "-==ATRI Switch Control System==-\n"
- msg0 += "┌Usage: switch on/off-{service}\n"
- msg0 += "├For SUPERUSER:\n"
- msg0 += "│ └Usage: switch all-on/off-{service}\n"
- msg0 += "└Service:\n"
- msg0 += " ├anime-setu\n"
- msg0 += " ├anime-pic-search\n"
- msg0 += " ├anime-vid-search\n"
- msg0 += " ├ai-face\n"
- msg0 += " ├pixiv-pic-search\n"
- msg0 += " ├pixiv-author-search\n"
- msg0 += " └pixiv-rank"
+ msg0 += "Usage: switch on/off-{service}\n"
+ msg0 += "* For SUPERUSER:\n"
+ msg0 += " - Usage: switch all-on/off-{service}\n"
+ msg0 += "Service:\n"
+
+ for i in data.keys():
+ msg0 += f" {i}\n"
await switch.finish(msg0)
@@ -84,128 +83,105 @@ async def _(bot: Bot, event: Event, state: dict) -> None:
# 舆情监控系统
-publicOpinion = on_command("舆情",
- rule=check_banlist(),
- permission=SUPERUSER | GROUP_ADMIN | GROUP_OWNER)
-data_PO = Path(
- '.') / 'ATRI' / 'plugins' / 'plugin_chat' / 'public_opinion.json'
+publicOpinion = on_command("舆情", rule=check_banlist(), permission=SUPERUSER)
-@publicOpinion.handle() # type: ignore
+@publicOpinion.handle()
async def _(bot: Bot, event: Event, state: dict) -> None:
msg = str(event.message).strip().split(' ')
+ with open(PUBLIC_OPINION_PATH, 'r') as f:
+ data = json.load(f)
+
if msg[0] == '':
msg0 = "---=====ATRI POM System=====---\n"
msg0 += "Usage:\n"
- msg0 += " - 舆情 [key] [times] [ban time(bot)] [repo]\n"
+ msg0 += " - 舆情 [key] [repo] [times] [ban time(bot)]\n"
+ msg0 += " - 舆情 del [key]\n"
+ msg0 += " - 舆情 list\n"
msg0 += "Tips:\n"
msg0 += " - 非 SUPERU 只能设置本群\n"
msg0 += " - SUPERU 需在后跟随 -a 以启用全局效果\n"
msg0 += " - 参数类型:\n"
msg0 += " * key: 关键词(将使用正则匹配)\n"
+ msg0 += " * repo: 触发后的关键词(可选),如为图片,键入 img\n"
msg0 += " * times: 容忍次数(n>0, int)\n"
- msg0 += " * ban time: bot对其失效时间(min, int)\n"
- msg0 += " * repo: 触发后的关键词(可选),如为图片,键入 img"
+ msg0 += " * ban time: bot对其失效时间(min, int)"
await publicOpinion.finish(msg0)
+ if msg[0] == 'del':
+ await publicOpinion.finish(Textcheck().del_word(msg[1]))
+
+ if msg[0] == 'list':
+ msg0 = "舆情检测列表如下:\n"
+ for w in data.keys():
+ msg0 += f' {w}\n'
+
if msg[0] and msg[1] and msg[2] and msg[3]:
pass
else:
msg0 = "请检查格式奥~!\n"
- msg0 += "舆情 [key] [times] [ban time(bot)] [repo]\n"
+ msg0 += "舆情 [key] [repo] [times] [ban time(bot)]\n"
msg0 += " * key: 关键词(将使用正则匹配)\n"
+ msg0 += " * repo: 触发后的关键词(可选),如为图片,键入 img\n"
msg0 += " * times: 容忍次数(n>0, int)\n"
- msg0 += " * ban time: bot对其失效时间(min, int)\n"
- msg0 += " * repo: 触发后的关键词(可选),如为图片,键入 img"
+ msg0 += " * ban time: bot对其失效时间(min, int)"
await publicOpinion.finish(msg0)
- key_word = msg[0]
- remind = msg[1]
- punish = msg[2]
- repo = msg[3]
+ key = msg[0]
+ repo = msg[1]
+ max_times = msg[2]
+ ban_time = msg[3]
- if key_word and remind and punish and repo:
- if re.findall(r"/^\d{1,}$/", remind) and re.findall(
- r"/^\d{1,}$/", punish):
- pass
-
- else:
+ if key and repo and max_times and ban_time:
+ if not re.findall(r"/^\d{1,}$/", max_times) and re.findall(
+ r"/^\d{1,}$/", ban_time):
await publicOpinion.finish("非法字符!请注意(times, ban time)类型为int(阿拉伯数字)"
)
else:
- await publicOpinion.finish("请键入完整信息!\n如需帮助,请键入 舆情")
+ await publicOpinion.finish("请键入完整信息!\n如需帮助,请键入:舆情")
if repo == "img":
- state["key_word"] = key_word
- state["remind"] = remind
- state["punish"] = punish
+ state["key"] = key
+ state["max_times"] = max_times
+ state["ban_time"] = ban_time
else:
- try:
- with open(data_PO, "r") as f:
- data = json.load(f)
- except FileNotFoundError:
- data = {}
-
- data[key_word] = [remind, punish, repo]
-
- with open(data_PO, "w") as f:
- f.write(json.dumps(data))
- f.close()
-
- msg0 = "舆情信息记录完成~!\n"
- msg0 += f"Keyword: {key_word}\n"
- msg0 += f"Times: {remind}\n"
- msg0 += f"Ban time: {punish}\n"
- msg0 += f"Repo: {repo}"
-
- await publicOpinion.finish(msg0)
+ await publicOpinion.finish(Textcheck().add_word(
+ key, repo, int(max_times), int(ban_time)))
-@publicOpinion.got("repo", prompt="检测到 repo 类型为 img,请发送一张图片") # type: ignore
+@publicOpinion.got("repo", prompt="检测到 repo 类型为 img,请发送一张图片")
async def _(bot: Bot, event: Event, state: dict) -> None:
- key_word = state["key_word"]
- remind = state["remind"]
- punish = state["punish"]
+ key = state["key"]
repo = state["repo"]
+ max_times = state["max_times"]
+ ban_time = state["ban_time"]
if "[CQ:image" not in repo:
await publicOpinion.reject("请发送一张图片而不是图片以外的东西~!(")
- try:
- with open(data_PO, "r") as f:
- data = json.load(f)
- except FileNotFoundError:
- data = {}
-
- data[key_word] = [remind, punish, repo]
-
- with open(data_PO, "w") as f:
- f.write(json.dumps(data))
- f.close()
-
- msg0 = "舆情信息记录完成~!\n"
- msg0 += f"Keyword: {key_word}\n"
- msg0 += f"Times: {remind}\n"
- msg0 += f"Ban time: {punish}\n"
- msg0 += f"Repo: {repo}"
-
- await publicOpinion.finish(msg0)
+ await publicOpinion.finish(Textcheck().add_word(key, repo, int(max_times),
+ int(ban_time)))
trackError = on_command("track", permission=SUPERUSER)
file_error = Path('.') / 'ATRI' / 'data' / 'data_Error' / 'error.json'
-@trackError.handle() # type: ignore
+@trackError.handle()
async def _(bot: Bot, event: Event, state: dict) -> None:
- track_id = str(event.message).strip()
+ args = str(event.message).strip()
+
+ if args:
+ state['track_id'] = args
+
- if not track_id:
- await trackError.finish("请告诉咱追踪ID嗷~!不然无法获取错误堆栈呢!!")
+@trackError.got('track_id', prompt='请告诉咱追踪ID嗷~!不然无法获取错误堆栈呢!!')
+async def _(bot: Bot, event: Event, state: dict) -> None:
+ track_id = state['track_id']
data = {}
@@ -230,7 +206,7 @@ async def _(bot: Bot, event: Event, state: dict) -> None:
groupSendMessage = on_command("群发", permission=SUPERUSER)
-@groupSendMessage.handle() # type: ignore
+@groupSendMessage.handle()
async def _(bot: Bot, event: Event, state: dict) -> None:
args = str(event.message).strip()
@@ -238,7 +214,7 @@ async def _(bot: Bot, event: Event, state: dict) -> None:
state['msg'] = args
-@groupSendMessage.got('msg', prompt='请告诉咱需要群发的内容~!') # type: ignore
+@groupSendMessage.got('msg', prompt='请告诉咱需要群发的内容~!')
async def _(bot: Bot, event: Event, state: dict) -> None:
msg = state['msg']
group_list = await bot.get_group_list()
@@ -251,7 +227,7 @@ async def _(bot: Bot, event: Event, state: dict) -> None:
for group in group_list:
if group['group_id'] not in ban_group_list:
- asyncio.sleep(randint(1,5))
+ asyncio.sleep(randint(1, 5))
try:
await bot.send_group_msg(group_id=group['group_id'],
message=msg)
diff --git a/ATRI/plugins/plugin_anime/__init__.py b/ATRI/plugins/plugin_anime/__init__.py
index 6fde78c..c51e73f 100644
--- a/ATRI/plugins/plugin_anime/__init__.py
+++ b/ATRI/plugins/plugin_anime/__init__.py
@@ -15,21 +15,25 @@ import json
import sqlite3
from pathlib import Path
from random import randint
+from datetime import datetime, timedelta
+from apscheduler.triggers.date import DateTrigger
from nonebot.log import logger
+from nonebot.sched import scheduler
+from nonebot.typing import Bot, Event
from nonebot.permission import SUPERUSER
-from nonebot.adapters.cqhttp import Bot, Event
from nonebot.plugin import on_message, on_command, on_regex
-from utils.utils_yml import load_yaml
-from utils.utils_error import errorRepo
-from utils.utils_history import getMessage
-from utils.utils_translate import toSimpleString
-from utils.utils_rule import check_banlist, check_switch
-from utils.utils_request import aio_get_bytes, request_get
-from utils.utils_img import compress_image, aio_download_pics
+from ATRI.utils.utils_times import countX
+from ATRI.utils.utils_yml import load_yaml
+from ATRI.utils.utils_error import errorRepo
+from ATRI.utils.utils_history import getMessage
+from ATRI.utils.utils_translate import toSimpleString
+from ATRI.utils.utils_rule import check_banlist, check_switch
+from ATRI.utils.utils_request import aio_get_bytes, request_get
+from ATRI.utils.utils_img import compress_image, aio_download_pics
-from .body import resultRepo
+from .data_source import resultRepo
CONFIG_PATH = Path('.') / 'config.yml'
config = load_yaml(CONFIG_PATH)
@@ -38,10 +42,11 @@ plugin_name_0 = "anime-pic-search"
key_SauceNAO = config['api']['SauceNaoKEY']
SaucenaoSearch = on_command('以图搜图',
- rule=check_banlist() & check_switch(plugin_name_0))
+ rule=check_banlist()
+ & check_switch(plugin_name_0, True))
-@SaucenaoSearch.handle() # type: ignore
+@SaucenaoSearch.handle()
async def _(bot: Bot, event: Event, state: dict) -> None:
user = str(event.user_id)
group = str(event.group_id)
@@ -55,7 +60,7 @@ async def _(bot: Bot, event: Event, state: dict) -> None:
state["img_url"] = img
-@SaucenaoSearch.got("img_url", prompt="请发送一张目标图片") # type: ignore
+@SaucenaoSearch.got("img_url", prompt="请发送一张目标图片")
async def _(bot: Bot, event: Event, state: dict) -> None:
img = state["img_url"]
img = re.findall(r"(http://.*?)]", img)
@@ -72,10 +77,10 @@ async def _(bot: Bot, event: Event, state: dict) -> None:
SaucenaoSearch_repo = on_message(rule=check_banlist()
- & check_switch(plugin_name_0))
+ & check_switch(plugin_name_0, True))
-@SaucenaoSearch_repo.handle() # type: ignore
+@SaucenaoSearch_repo.handle()
async def _(bot: Bot, event: Event, state: dict) -> None:
group = str(event.group_id)
msg = str(event.message)
@@ -109,10 +114,11 @@ async def _(bot: Bot, event: Event, state: dict) -> None:
plugin_name_1 = "anime-vid-search"
AnimeSearch = on_command('以图搜番',
- rule=check_banlist() & check_switch(plugin_name_1))
+ rule=check_banlist()
+ & check_switch(plugin_name_1, True))
-@AnimeSearch.handle() # type: ignore
+@AnimeSearch.handle()
async def _(bot: Bot, event: Event, state: dict) -> None:
user = str(event.user_id)
group = str(event.group_id)
@@ -126,7 +132,7 @@ async def _(bot: Bot, event: Event, state: dict) -> None:
state["img_url"] = img
-@AnimeSearch.got("img_url", prompt="请发送一张目标图片") # type: ignore
+@AnimeSearch.got("img_url", prompt="请发送一张目标图片")
async def _(bot: Bot, event: Event, state: dict) -> None:
img = state["img_url"]
img = re.findall(r"(http://.*?)]", img)
@@ -194,18 +200,53 @@ async def _(bot: Bot, event: Event, state: dict) -> None:
plugin_name_2 = "anime-setu"
key_LoliconAPI = config['api']['LoliconAPI']
setu_type = 1 # setu-type: 1(local), 2(url: https://api.lolicon.app/#/setu) default: 1(local)
+SP_temp_list = []
+SP_list = []
+SEPI_PATH = Path('.') / 'ATRI' / 'plugins' / 'plugin_anime' / 'sepi_list.json'
-setus = on_regex(
- r"来[点丶张份副个幅][涩色瑟][图圖]|[涩色瑟][图圖]来|[涩色瑟][图圖][gkd|GKD|搞快点]|[gkd|GKD|搞快点][涩色瑟][图圖]",
- rule=check_banlist() & check_switch(plugin_name_2))
+async def check_sepi(bot: Bot, event: Event, state: dict) -> bool:
+ """检查目标是否是涩批"""
+ if event.user_id in SP_list:
+ await bot.send(event, "你可少冲点吧!涩批!哼唧")
+ return False
+ else:
+ return True
+
+def add_sepi(user: int) -> None:
+ """将目标移入涩批名单"""
+ global SP_list
+ SP_list.append(user)
+
+def del_sepi(user: int) -> None:
+ """将目标移出涩批名单"""
+ global SP_list
+ SP_list.remove(user)
+
+
+setu = on_regex(
+ r"来[点丶张份副个幅][涩色瑟][图圖]|[涩色瑟][图圖]来|[涩色瑟][图圖][gkd|GKD|搞快点]|[gkd|GKD|搞快点][涩色瑟][图圖]",
+ rule=check_banlist() & check_switch(plugin_name_2, False) & check_sepi)
-@setus.handle() # type: ignore
-async def _setu(bot: Bot, event: Event, state: dict) -> None:
- group = str(event.group_id)
+@setu.handle()
+async def _(bot: Bot, event: Event, state: dict) -> None:
+ global SP_temp_list
+ user = event.user_id
+ group = event.group_id
res = randint(1, 5)
+ if countX(SP_temp_list, user) == 5:
+ add_sepi(user) # type: ignore
+ SP_temp_list = list(set(SP_temp_list))
+ delta = timedelta(hours=1)
+ trigger = DateTrigger(run_date=datetime.now() + delta)
+ scheduler.add_job(func=del_sepi,
+ trigger=trigger,
+ args=(user, ),
+ misfire_grace_time=60)
+ return
+
if setu_type == 1:
con = sqlite3.connect(
@@ -225,7 +266,8 @@ async def _setu(bot: Bot, event: Event, state: dict) -> None:
msg0 += f"[CQ:image,file=file:///{compress_image(await aio_download_pics(img))}]"
if 1 <= res < 5:
- await setus.finish(msg0)
+ SP_temp_list.append(user)
+ await setu.finish(msg0)
elif res == 5:
await bot.send(event, "我找到涩图了!但我发给主人了\nο(=•ω<=)ρ⌒☆")
@@ -246,7 +288,7 @@ async def _setu(bot: Bot, event: Event, state: dict) -> None:
data = json.loads(
request_get('https://api.lolicon.app/setu/', params))
except Exception:
- await setus.finish(errorRepo("请求数据失败,也可能为接口调用次数达上限"))
+ await setu.finish(errorRepo("请求数据失败,也可能为接口调用次数达上限"))
msg0 = "setu info:\n"
msg0 += f'Title: {data["data"][0]["title"]}\n'
@@ -254,7 +296,8 @@ async def _setu(bot: Bot, event: Event, state: dict) -> None:
msg0 += f'[CQ:image,file=file:///{compress_image(await aio_download_pics(data["data"][0]["url"]))}]'
if 1 <= res < 5:
- await setus.finish(msg0)
+ SP_temp_list.append(user)
+ await setu.finish(msg0)
elif res == 5:
await bot.send(event, "我找到涩图了!但我发给主人了\nο(=•ω<=)ρ⌒☆")
@@ -297,59 +340,3 @@ async def _(bot: Bot, event: Event, state: dict) -> None:
await setuType.finish("请检查类型是否输入正确嗷!")
await setuType.finish("Type conversion completed!")
-
-
-# @scheduler.scheduled_job(
-# "cron",
-# minute=45,
-# bot=Bot,
-# event=Event,
-# state=dict
-# )
-# async def _(bot: Bot, event: Event, state: dict) -> None:
-# group = str(event.group_id)
-
-# if banList(group=group):
-# if checkSwitch(plugin_name_2, group):
-# # group_list = await bot.get_group_list()
-# # group = sample(group_list, 1)
-# # group = group['group_id']
-
-# if setu_type == 1:
-
-# con = sqlite3.connect(Path('.') / 'ATRI' / 'data' / 'data_Sqlite' / 'setu' / 'nearR18.db')
-# cur = con.cursor()
-# msg = cur.execute('SELECT * FROM nearR18 ORDER BY RANDOM() limit 1;')
-
-# for i in msg:
-# pid = i[0]
-# title = i[1]
-# img = i[7]
-
-# msg0 = f"setu info:\n"
-# msg0 += f"Title: {title}\n"
-# msg0 += f"Pid: {pid}\n"
-# msg0 += f"[CQ:image,file=file:///{compress_image(await aio_download_pics(img))}]"
-
-# await setu.finish(msg0)
-
-# else:
-# params = {
-# "apikey": key_LoliconAPI,
-# "r18": "0",
-# "num": "1"
-# }
-
-# data = {}
-
-# try:
-# data = json.loads(request_get('https://api.lolicon.app/setu/', params))
-# except Exception:
-# await setu.finish(errorRepo("请求数据失败,也可能为接口调用次数达上限"))
-
-# msg0 = f"setu info:\n"
-# msg0 += f'Title: {data["data"][0]["title"]}\n'
-# msg0 += f'Pid: {data["data"][0]["pid"]}\n'
-# msg0 += f'[CQ:image,file=file:///{compress_image(await aio_download_pics(data["data"][0]["url"]))}]'
-
-# await setu.finish(msg0)
diff --git a/ATRI/plugins/plugin_anime/body.py b/ATRI/plugins/plugin_anime/body.py
deleted file mode 100644
index d7dae84..0000000
--- a/ATRI/plugins/plugin_anime/body.py
+++ /dev/null
@@ -1,71 +0,0 @@
-#!/usr/bin/env python3
-# -*- encoding: utf-8 -*-
-'''
-@File : body.py
-@Time : 2020/10/11 14:38:23
-@Author : Kyomotoi
-@Contact : kyomotoiowo@gmail.com
-@Github : https://github.com/Kyomotoi
-@License : Copyright © 2018-2020 Kyomotoi, All Rights Reserved.
-'''
-__author__ = 'kyomotoi'
-
-import json
-
-from utils.utils_error import errorRepo
-from utils.utils_request import request_get
-
-
-class SauceNAO:
- """搜图请求主体"""
- def __init__(self,
- api_key,
- output_type=2,
- testmode=0,
- dbmask=None,
- dbmaski=32768,
- db=5,
- numres=1):
- api = 'https://saucenao.com/search.php'
- self.api = api
- params = dict()
- params['api_key'] = api_key
- params['output_type'] = output_type
- params['testmode'] = testmode
- params['dbmask'] = dbmask
- params['dbmaski'] = dbmaski
- params['db'] = db
- params['numres'] = numres
- self.params = params
-
- def search(self, url):
- self.params['url'] = url
- return request_get(self.api, self.params)
-
-
-def resultRepo(user: str, key: str, img_url: str):
- try:
- task = SauceNAO(key)
- data = task.search(img_url)
- except Exception:
- return errorRepo('请求数据失败')
-
- data = json.loads(data)['results'][0]
- msg0 = ''
- print(data)
-
- msg0 += f'[CQ:at,qq={user}]\n'
- msg0 += "SauceNAO INFO:\n"
- msg0 += f"[CQ:image,file={data['header'].get('thumbnail', None)}]\n"
- msg0 += f"Like:{data['header'].get('similarity', 0)}%\n"
- msg0 += f"Title:{data['data'].get('title', None)}\n"
- msg0 += f"Pixiv ID:{data['data'].get('pixiv_id', None)}\n"
- msg0 += f"Author:{data['data'].get('member_name', None)}\n"
- msg0 += f"Autoor ID:{data['data'].get('member_id', None)}\n"
- msg0 += f"Pixiv URL: https://www.pixiv.net/artworks/{data['data'].get('pixiv_id', None)}\n"
- msg0 += f"Pic URL: https://pixiv.cat/{data['data'].get('pixiv_id', None)}.jpg"
-
- if float(data['header'].get('similarity', 0)) < 65:
- msg0 += '\n注:相似率小于65%不一定正确'
-
- return msg0
\ No newline at end of file
diff --git a/ATRI/plugins/plugin_anime/data_source.py b/ATRI/plugins/plugin_anime/data_source.py
new file mode 100644
index 0000000..21f7d74
--- /dev/null
+++ b/ATRI/plugins/plugin_anime/data_source.py
@@ -0,0 +1,71 @@
+#!/usr/bin/env python3
+# -*- encoding: utf-8 -*-
+'''
+@File : body.py
+@Time : 2020/10/11 14:38:23
+@Author : Kyomotoi
+@Contact : kyomotoiowo@gmail.com
+@Github : https://github.com/Kyomotoi
+@License : Copyright © 2018-2020 Kyomotoi, All Rights Reserved.
+'''
+__author__ = 'kyomotoi'
+
+import json
+
+from ATRI.utils.utils_error import errorRepo
+from ATRI.utils.utils_request import request_get
+
+
+class SauceNAO:
+ """搜图请求主体"""
+ def __init__(self,
+ api_key,
+ output_type=2,
+ testmode=0,
+ dbmask=None,
+ dbmaski=32768,
+ db=5,
+ numres=1):
+ api = 'https://saucenao.com/search.php'
+ self.api = api
+ params = dict()
+ params['api_key'] = api_key
+ params['output_type'] = output_type
+ params['testmode'] = testmode
+ params['dbmask'] = dbmask
+ params['dbmaski'] = dbmaski
+ params['db'] = db
+ params['numres'] = numres
+ self.params = params
+
+ def search(self, url):
+ self.params['url'] = url
+ return request_get(self.api, self.params)
+
+
+def resultRepo(user: str, key: str, img_url: str):
+ try:
+ task = SauceNAO(key)
+ data = task.search(img_url)
+ except Exception:
+ return errorRepo('请求数据失败')
+
+ data = json.loads(data)['results'][0]
+ msg0 = ''
+ print(data)
+
+ msg0 += f'[CQ:at,qq={user}]\n'
+ msg0 += "SauceNAO INFO:\n"
+ msg0 += f"[CQ:image,file={data['header'].get('thumbnail', None)}]\n"
+ msg0 += f"Like:{data['header'].get('similarity', 0)}%\n"
+ msg0 += f"Title:{data['data'].get('title', None)}\n"
+ msg0 += f"Pixiv ID:{data['data'].get('pixiv_id', None)}\n"
+ msg0 += f"Author:{data['data'].get('member_name', None)}\n"
+ msg0 += f"Autoor ID:{data['data'].get('member_id', None)}\n"
+ msg0 += f"Pixiv URL: https://www.pixiv.net/artworks/{data['data'].get('pixiv_id', None)}\n"
+ msg0 += f"Pic URL: https://pixiv.cat/{data['data'].get('pixiv_id', None)}.jpg"
+
+ if float(data['header'].get('similarity', 0)) < 65:
+ msg0 += '\n注:相似率小于65%不一定正确'
+
+ return msg0
\ No newline at end of file
diff --git a/ATRI/plugins/plugin_anime/sepi_list.json b/ATRI/plugins/plugin_anime/sepi_list.json
new file mode 100644
index 0000000..9e26dfe
--- /dev/null
+++ b/ATRI/plugins/plugin_anime/sepi_list.json
@@ -0,0 +1 @@
+{}
\ No newline at end of file
diff --git a/ATRI/plugins/plugin_chat/__init__.py b/ATRI/plugins/plugin_chat/__init__.py
index ec6738f..13c6348 100644
--- a/ATRI/plugins/plugin_chat/__init__.py
+++ b/ATRI/plugins/plugin_chat/__init__.py
@@ -10,23 +10,28 @@
'''
__author__ = 'kyomotoi'
+import os
import json
from pathlib import Path
from random import choice
-from nonebot.permission import SUPERUSER
+from random import randint
from requests import exceptions
from nonebot.log import logger
from nonebot.rule import to_me
-from nonebot.adapters.cqhttp import Bot, Event
+from nonebot.typing import Bot, Event
+from nonebot.permission import SUPERUSER
from nonebot.plugin import on_command, on_message, on_notice, on_request
-from utils.utils_times import countX
-from utils.utils_yml import load_yaml
-from utils.utils_error import errorRepo
-from utils.utils_rule import check_banlist
-from utils.utils_history import saveMessage
-from utils.utils_request import request_api_text
+from ATRI.utils.utils_ban import ban
+from ATRI.utils.utils_times import countX
+from ATRI.utils.utils_yml import load_yaml
+from ATRI.utils.utils_error import errorRepo
+from ATRI.utils.utils_textcheck import Textcheck
+from ATRI.utils.utils_history import saveMessage
+from ATRI.utils.utils_request import request_api_text
+from ATRI.utils.utils_rule import check_banlist, check_switch
+
CONFIG_PATH = Path('.') / 'config.yml'
config = load_yaml(CONFIG_PATH)['bot']
@@ -37,7 +42,7 @@ master = config['superusers']
MessageSave = on_message()
-@MessageSave.handle() # type: ignore
+@MessageSave.handle()
async def _(bot: Bot, event: Event, state: dict) -> None:
user = str(event.user_id)
group = str(event.group_id)
@@ -50,7 +55,7 @@ async def _(bot: Bot, event: Event, state: dict) -> None:
saveMessage(message_id, message, user, group)
logger.opt(colors=True).info(
- f"[{group}]-U: ({user}) | Message: ({message}) Saved successfully"
+ f"GROUP[{group}]: USER({user}) > Message: ({message}) Saved successfully"
)
@@ -58,7 +63,7 @@ async def _(bot: Bot, event: Event, state: dict) -> None:
callMe = on_message(rule=check_banlist())
-@callMe.handle() # type: ignore
+@callMe.handle()
async def _(bot: Bot, event: Event, state: dict) -> None:
msg = str(event.raw_event['raw_message']).strip()
@@ -73,7 +78,7 @@ async def _(bot: Bot, event: Event, state: dict) -> None:
pokehah = on_command("戳一戳", rule=to_me() & check_banlist())
-@pokehah.handle() # type: ignore
+@pokehah.handle()
async def _poke(bot: Bot, event: Event, state: dict) -> None:
msg = choice([
"你再戳!", "?再戳试试?", "别戳了别戳了再戳就坏了555", "我爪巴爪巴,球球别再戳了", "你戳你🐎呢?!",
@@ -100,7 +105,7 @@ poke.handle()(_poke)
groupEvent = on_notice()
-@groupEvent.handle() # type: ignore
+@groupEvent.handle()
async def _(bot: Bot, event: Event, state: dict) -> None:
if event.raw_event['notice_type'] == 'group_increase':
if event.user_id != int(event.self_id):
@@ -125,7 +130,7 @@ FRIEND_ADD = 0
GROUP_INVITE = 0
-@selfEvent.handle() # type: ignore
+@selfEvent.handle()
async def _(bot: Bot, event: Event, state: dict) -> None:
print(event.raw_event)
flag = event.raw_event['flag']
@@ -175,7 +180,7 @@ async def _(bot: Bot, event: Event, state: dict) -> None:
controlSelfEvent = on_command('selfevent', permission=SUPERUSER)
-@controlSelfEvent.handle() # type: ignore
+@controlSelfEvent.handle()
async def _(bot: Bot, event: Event, state: dict) -> None:
args = str(event.message).strip()
msg0 = ''
@@ -204,16 +209,6 @@ async def _(bot: Bot, event: Event, state: dict) -> None:
await controlSelfEvent.finish('DONE!')
-# # 舆情监听系统
-# listenPublicOpinion = on_message()
-# file_PO = Path(
-# '.') / 'ATRI' / 'plugins' / 'plugin_chat' / 'public_opinion.json'
-
-# @groupEvent.handle() # type: ignore
-# async def _(bot: Bot, event: Event, state: dict) -> None:
-# with open(file_PO, 'r') as f:
-# data = json.load(f)
-
# 口臭一下
fxxkMe = on_command('口臭一下',
aliases={'口臭', '骂我'},
@@ -221,13 +216,14 @@ fxxkMe = on_command('口臭一下',
list_M = []
-@fxxkMe.handle() # type: ignore
+@fxxkMe.handle()
async def _(bot: Bot, event: Event, state: dict) -> None:
user = str(event.user_id)
global list_M
if countX(list_M, user) >= 3:
await fxxkMe.finish("不是??你这么想被咱骂的嘛??被咱骂就这么舒服的吗?!该......你该不会是.....M吧!")
+ list_M = list(set(list_M))
elif countX(list_M, user) >= 6:
await fxxkMe.finish("给我适可而止阿!?")
@@ -253,7 +249,7 @@ hitokoto = on_command('一言',
list_Y = []
-@hitokoto.handle() # type: ignore
+@hitokoto.handle()
async def _(bot: Bot, event: Event, state: dict) -> None:
user = str(event.user_id)
global list_Y
@@ -292,4 +288,148 @@ async def _(bot: Bot, event: Event, state: dict) -> None:
# result.append(line.strip('\n'))
# resu = choice(result)
-# print(resu%name)
\ No newline at end of file
+# print(resu%name)
+
+# 扔漂流瓶
+plugin_name = 'drifting-bottle'
+DRIFTING_BOTTLE_PATH = Path(
+ '.') / 'ATRI' / 'plugins' / 'plugin_chat' / 'drifting_bottle.json'
+driftingBottle = on_command('扔漂流瓶',
+ rule=to_me() & check_banlist()
+ & check_switch(plugin_name, True))
+
+
+@driftingBottle.handle()
+async def _(bot: Bot, event: Event, state: dict) -> None:
+ args = str(event.message).strip()
+
+ if args:
+ state['args'] = args
+
+
+@driftingBottle.got('args', prompt='请告诉咱瓶中内容~!')
+async def _(bot: Bot, event: Event, state: dict) -> None:
+ args = state['args']
+ user = event.user_id
+ group = event.group_id
+
+ if not DRIFTING_BOTTLE_PATH.is_file():
+ with open(DRIFTING_BOTTLE_PATH, 'w') as f:
+ f.write(json.dumps({}))
+
+ with open(DRIFTING_BOTTLE_PATH, 'r') as f:
+ data = json.load(f)
+
+ num = len(data)
+ data[num + 1] = [user, group, args]
+
+ with open(DRIFTING_BOTTLE_PATH, 'w') as f:
+ f.write(json.dumps(data))
+
+ await driftingBottle.finish('漂流瓶已飘向远方...')
+
+
+# 捡漂流瓶
+getDriftingBottle = on_command('捞漂流瓶',
+ rule=to_me() & check_banlist()
+ & check_switch(plugin_name, True))
+
+
+@getDriftingBottle.handle()
+async def _(bot: Bot, event: Event, state: dict) -> None:
+ if not DRIFTING_BOTTLE_PATH.is_file():
+ with open(DRIFTING_BOTTLE_PATH, 'w') as f:
+ f.write(json.dumps({}))
+
+ with open(DRIFTING_BOTTLE_PATH, 'r') as f:
+ data = json.load(f)
+
+ num = len(data)
+ if not num:
+ await getDriftingBottle.finish('暂无漂流瓶可供打捞呢~(')
+
+ num = randint(1, num)
+ bottle = data[str(num)]
+ user = bottle[0]
+ group = bottle[1]
+ msg = bottle[2]
+
+ msg0 = f'[CQ:at,qq={event.user_id}]\n'
+ msg0 += f'漂流瓶[{num}]来自群[{group}][{user}],内容如下\n'
+ msg0 += msg
+
+ await getDriftingBottle.finish(msg0)
+
+
+# 清除漂流瓶
+delDriftingBottle = on_command('清除漂流瓶',
+ rule=check_banlist(),
+ permission=SUPERUSER)
+
+
+@delDriftingBottle.handle()
+async def _(bot: Bot, event: Event, state: dict) -> None:
+ args = str(event.message).strip()
+
+ if not args:
+ msg0 = 'Drifting Bottle:\n'
+ msg0 += '*For SUPERUSERS'
+ msg0 += '- delall\n'
+ msg0 += '- del [num]\n'
+ msg0 += 'eg: 清除漂流瓶 del 123'
+
+ await delDriftingBottle.finish(msg0)
+
+ if not DRIFTING_BOTTLE_PATH.is_file():
+ with open(DRIFTING_BOTTLE_PATH, 'w') as f:
+ f.write(json.dumps({}))
+
+ await delDriftingBottle.finish('清除了个寂寞...')
+
+ with open(DRIFTING_BOTTLE_PATH, 'r') as f:
+ data = json.load(f)
+
+ if args[0] == 'delall':
+ os.remove(os.path.abspath(DRIFTING_BOTTLE_PATH))
+
+ elif args[0] == 'del':
+ try:
+ del data[args[1]]
+ except:
+ await delDriftingBottle.finish(errorRepo('清除失败了...'))
+
+ with open(DRIFTING_BOTTLE_PATH, 'w') as f:
+ f.write(json.dumps(data))
+ f.close()
+
+ result = args[1] if args[0] == 'del' else "ALL"
+ await delDriftingBottle.finish(
+ f'完成啦!成功清除漂流瓶[{result}],目前还剩余[{len(data)}]个~')
+
+
+# 舆情监听
+publicOpinion = on_message(rule=check_banlist(True))
+ban_temp_list = []
+
+
+@publicOpinion.handle()
+async def _(bot: Bot, event: Event, state: dict) -> None:
+ global ban_temp_list
+ msg = str(event.message)
+ user = str(event.user_id)
+
+ # 检查是否满足条件
+ if countX(ban_temp_list, user) == Textcheck().get_times(str(Textcheck().check(msg))):
+ ban_temp_list = list(set(ban_temp_list))
+ ban(user)
+
+ if Textcheck().check(msg) == "False":
+ return
+
+ if Textcheck().check(msg):
+ if user in master:
+ await publicOpinion.finish("主人你给我注意点阿?!你这可是在死亡边缘试探呢!!")
+
+ ban_temp_list.append(int(user))
+
+ await publicOpinion.finish(Textcheck().check(msg))
diff --git a/ATRI/plugins/plugin_chat/drifting_bottle.json b/ATRI/plugins/plugin_chat/drifting_bottle.json
new file mode 100644
index 0000000..9e26dfe
--- /dev/null
+++ b/ATRI/plugins/plugin_chat/drifting_bottle.json
@@ -0,0 +1 @@
+{}
\ No newline at end of file
diff --git a/ATRI/plugins/plugin_chat/public_opinion.json b/ATRI/plugins/plugin_chat/public_opinion.json
deleted file mode 100644
index e69de29..0000000
diff --git a/ATRI/plugins/plugin_pixiv/__init__.py b/ATRI/plugins/plugin_pixiv/__init__.py
index 3c5b849..c7687ed 100644
--- a/ATRI/plugins/plugin_pixiv/__init__.py
+++ b/ATRI/plugins/plugin_pixiv/__init__.py
@@ -15,18 +15,18 @@ import json
from requests import exceptions
from nonebot.plugin import on_command
-from nonebot.adapters.cqhttp import Bot, Event
+from nonebot.typing import Bot, Event
-from utils.utils_error import errorRepo
-from utils.utils_request import request_get
-from utils.utils_rule import check_banlist, check_switch
+from ATRI.utils.utils_error import errorRepo
+from ATRI.utils.utils_img import aio_download_pics
+from ATRI.utils.utils_rule import check_banlist, check_switch
plugin_name_0 = "pixiv-pic-search"
pixivSearchIMG = on_command('p站搜图',
- rule=check_banlist() & check_switch(plugin_name_0))
+ rule=check_banlist() & check_switch(plugin_name_0, True))
-@pixivSearchIMG.handle() # type: ignore
+@pixivSearchIMG.handle()
async def _(bot: Bot, event: Event, state: dict) -> None:
user = str(event.user_id)
group = str(event.group_id)
@@ -40,7 +40,7 @@ async def _(bot: Bot, event: Event, state: dict) -> None:
state["pid"] = pid
-@pixivSearchIMG.got("pid", prompt="请发送目标PID码") # type: ignore
+@pixivSearchIMG.got("pid", prompt="请发送目标PID码")
async def _(bot: Bot, event: Event, state: dict) -> None:
pid = state["pid"]
pid = re.findall(r"\d+", pid)
@@ -52,24 +52,27 @@ async def _(bot: Bot, event: Event, state: dict) -> None:
await bot.send(event, "别急!在搜索了!")
- URL = f"https://api.imjad.cn/pixiv/v1/?type=illust&id={pid}"
+ URL = f"https://api.imjad.cn/pixiv/v1/?type=illust&id={pid[0]}"
data = {}
try:
- data = json.loads(request_get(URL))
+ data = json.loads(await aio_download_pics(URL))
except exceptions:
await pixivSearchIMG.finish(errorRepo("请求数据失败"))
+ IMG = data["response"][0]["image_urls"]["large"]
+ IMG = IMG.replace("i.pximg.net", "i.pixiv.cat")
+
msg0 = f'[CQ:at,qq={state["user"]}]\n'
msg0 += "Search result:\n"
- msg0 += f"Pid: {pid}\n"
+ msg0 += f"Pid: {pid[0]}\n"
msg0 += f'Title {data["response"][0]["title"]}\n'
msg0 += f'W&H: {data["response"][0]["width"]}x{data["response"][0]["height"]}\n'
msg0 += f'Tags: {data["response"][0]["tags"]}\n'
msg0 += f'Account Name: {data["response"][0]["user"]["account"]}\n'
msg0 += f'Author Name: {data["response"][0]["user"]["name"]}\n'
msg0 += f'Link: https://www.pixiv.net/users/{data["response"][0]["user"]["id"]}\n'
- msg0 += f'IMG: https://pixiv.cat/{pid}.jpg'
+ msg0 += IMG
await pixivSearchIMG.finish(msg0)
@@ -77,10 +80,10 @@ async def _(bot: Bot, event: Event, state: dict) -> None:
plugin_name_1 = "pixiv-author-search"
pixivSearchAuthor = on_command("p站画师",
rule=check_banlist()
- & check_switch(plugin_name_1))
+ & check_switch(plugin_name_1, True))
-@pixivSearchAuthor.handle() # type: ignore
+@pixivSearchAuthor.handle()
async def _(bot: Bot, event: Event, state: dict) -> None:
user = str(event.user_id)
group = str(event.group_id)
@@ -94,7 +97,7 @@ async def _(bot: Bot, event: Event, state: dict) -> None:
state["author_id"] = author_id
-@pixivSearchAuthor.got("author_id", prompt="请发送目标画师id") # type: ignore
+@pixivSearchAuthor.got("author_id", prompt="请发送目标画师id")
async def _(bot: Bot, event: Event, state: dict) -> None:
author_id = state["author_id"]
author_id = re.findall(r"\d+", author_id)
@@ -104,43 +107,48 @@ async def _(bot: Bot, event: Event, state: dict) -> None:
else:
await pixivSearchAuthor.reject("请发送纯阿拉伯数字的画师id")
- await bot.send(event, f"别急!在搜索了!\n将展示画师[{author_id}]的前三项作品")
+ await bot.send(event, f"别急!在搜索了!\n将展示画师[{author_id[0]}]的前三项作品")
- URL = f"https://api.imjad.cn/pixiv/v1/?type=member_illust&id={author_id}"
+ URL = f"https://api.imjad.cn/pixiv/v1/?type=member_illust&id={author_id[0]}"
data = {}
try:
- data = json.loads(request_get(URL))
+ data = json.loads(await aio_download_pics(URL))
except exceptions:
await pixivSearchAuthor.finish(errorRepo("请求网络失败"))
+ d = {}
+
for i in range(0, 3):
pid = data["response"][i]["id"]
- IMG = f"https://pixiv.cat/{author_id}.jpg"
- data[i] = [f"{pid}", f"{IMG}"]
+ title = data["response"][i]["title"]
+ IMG = data["response"][i]["image_urls"]["large"]
+ IMG = IMG.replace("i.pximg.net", "i.pixiv.cat")
+ d[i] = [f"{pid}", f"{title}", f"{IMG}"]
- msg0 = f'[CQ:at,qq={state["user"]}]\n'
+ msg = f'[CQ:at,qq={state["user"]}]'
- result = sorted(data.items(), key=lambda x: x[1], reverse=True)
+ result = sorted(d.items(), key=lambda x: x[1], reverse=True)
t = 0
for i in result:
t += 1
- msg = "\n---------------\n"
+ msg += "\n————————————\n"
msg += f"({t})\n"
- msg += f"Pid: {i[1][0]}\n{i[1][1]}"
- msg0 += msg
+ msg += f"Title: {i[1][1]}\n"
+ msg += f"Pid: {i[1][0]}\n"
+ msg += f"{i[1][2]}"
- await pixivSearchAuthor.finish(msg0)
+ await pixivSearchAuthor.finish(msg)
plugin_name_2 = "pixiv-rank"
pixivRank = on_command("p站排行榜",
- rule=check_banlist() & check_switch(plugin_name_2))
+ rule=check_banlist() & check_switch(plugin_name_2, True))
-@pixivRank.handle() # type: ignore
+@pixivRank.handle()
async def _(bot: Bot, event: Event, state: dict) -> None:
user = str(event.user_id)
@@ -150,27 +158,31 @@ async def _(bot: Bot, event: Event, state: dict) -> None:
data = {}
try:
- data = json.loads(request_get(URL))
+ data = json.loads(await aio_download_pics(URL))
except exceptions:
await pixivRank.finish(errorRepo("网络请求失败"))
+ d = {}
+
for i in range(0, 5):
pid = data["response"][0]["works"][i]["work"]["id"]
- IMG = f"https://pixiv.cat/{pid}.jpg"
- data[i] = [f"{pid}", f"{IMG}"]
+ title = data["response"][0]["works"][i]["work"]["title"]
+ IMG = data["response"][i]["works"]["image_urls"]["large"]
+ IMG = IMG.replace("i.pximg.net", "i.pixiv.cat")
+ d[i] = [f"{pid}", f"{title}", f"{IMG}"]
- msg0 = f"[CQ:at,qq={user}]"
+ msg = f"[CQ:at,qq={user}]"
- result = sorted(data.items(), key=lambda x: x[1], reverse=True)
+ result = sorted(d.items(), key=lambda x: x[1], reverse=True)
t = 0
for i in result:
t += 1
- msg = "\n---------------\n"
+ msg += "\n————————————\n"
msg += f"({t})\n"
+ msg += f"Title: {i[1][1]}"
msg += f"Pid: {i[1][0]}"
- msg += f"{i[1][1]}"
- msg0 += msg
+ msg += f"{i[1][2]}"
- await pixivRank.finish(msg0)
+ await pixivRank.finish(msg)
diff --git a/ATRI/plugins/plugin_rich/__init__.py b/ATRI/plugins/plugin_rich/__init__.py
index 51b86e8..6d2dec8 100644
--- a/ATRI/plugins/plugin_rich/__init__.py
+++ b/ATRI/plugins/plugin_rich/__init__.py
@@ -15,13 +15,13 @@ import json
import requests
from nonebot.log import logger
+from nonebot.typing import Bot, Event
from nonebot.plugin import on_message
-from nonebot.adapters.cqhttp import Bot, Event
-from utils.utils_times import countX
-from utils.utils_rule import check_banlist
-from utils.utils_request import request_get
-from .body import dec
+from ATRI.utils.utils_times import countX
+from ATRI.utils.utils_rule import check_banlist
+from ATRI.utils.utils_request import request_get
+from .data_source import dec
BILI_REPORT_FORMAT = """[{aid}] Info:
Title: {title}
@@ -36,7 +36,7 @@ bilibiliRich = on_message(rule=check_banlist())
b_list = []
-@bilibiliRich.handle() # type: ignore
+@bilibiliRich.handle()
async def _(bot: Bot, event: Event, state: dict) -> None:
global b_list
user = event.user_id
@@ -101,7 +101,7 @@ cloudmusicRich = on_message(rule=check_banlist())
c_list = []
-@cloudmusicRich.handle() # type: ignore
+@cloudmusicRich.handle()
async def _(bot: Bot, event: Event, state: dict) -> None:
global c_list
user = event.user_id
diff --git a/ATRI/plugins/plugin_rich/body.py b/ATRI/plugins/plugin_rich/body.py
deleted file mode 100644
index ae3d99b..0000000
--- a/ATRI/plugins/plugin_rich/body.py
+++ /dev/null
@@ -1,32 +0,0 @@
-#!/usr/bin/env python3
-# -*- encoding: utf-8 -*-
-'''
-@File : body.py
-@Time : 2020/10/11 14:40:43
-@Author : Kyomotoi
-@Contact : kyomotoiowo@gmail.com
-@Github : https://github.com/Kyomotoi
-@License : Copyright © 2018-2020 Kyomotoi, All Rights Reserved.
-'''
-__author__ = 'kyomotoi'
-
-table='fZodR9XQDSUm21yCkr6zBqiveYah8bt4xsWpHnJE7jL5VG3guMTKNPAwcF'
-tr={}
-for i in range(58):
- tr[table[i]]=i
-s=[11,10,3,8,4,6]
-xor=177451812
-add=8728348608
-
-def dec(x) -> int:
- r=0
- for i in range(6):
- r+=tr[x[s[i]]]*58**i
- return (r-add)^xor
-
-def enc(x) -> str:
- x=(x^xor)+add
- r=list('BV1 4 1 7 ')
- for i in range(6):
- r[s[i]]=table[x//58**i%58]
- return ''.join(r)
\ No newline at end of file
diff --git a/ATRI/plugins/plugin_rich/data_source.py b/ATRI/plugins/plugin_rich/data_source.py
new file mode 100644
index 0000000..148d64b
--- /dev/null
+++ b/ATRI/plugins/plugin_rich/data_source.py
@@ -0,0 +1,34 @@
+#!/usr/bin/env python3
+# -*- encoding: utf-8 -*-
+'''
+@File : data_source.py
+@Time : 2020/11/21 11:11:37
+@Author : Kyomotoi
+@Contact : kyomotoiowo@gmail.com
+@Github : https://github.com/Kyomotoi
+@License : Copyright © 2018-2020 Kyomotoi, All Rights Reserved.
+'''
+__author__ = 'kyomotoi'
+
+table = 'fZodR9XQDSUm21yCkr6zBqiveYah8bt4xsWpHnJE7jL5VG3guMTKNPAwcF'
+tr = {}
+for i in range(58):
+ tr[table[i]] = i
+s = [11, 10, 3, 8, 4, 6]
+xor = 177451812
+add = 8728348608
+
+
+def dec(x) -> int:
+ r = 0
+ for i in range(6):
+ r += tr[x[s[i]]] * 58**i
+ return (r - add) ^ xor
+
+
+def enc(x) -> str:
+ x = (x ^ xor) + add
+ r = list('BV1 4 1 7 ')
+ for i in range(6):
+ r[s[i]] = table[x // 58**i % 58]
+ return ''.join(r)
diff --git a/ATRI/plugins/plugin_sqlite/__init__.py b/ATRI/plugins/plugin_sqlite/__init__.py
index a1208f1..45c33da 100644
--- a/ATRI/plugins/plugin_sqlite/__init__.py
+++ b/ATRI/plugins/plugin_sqlite/__init__.py
@@ -14,18 +14,18 @@ import os
import json
import sqlite3
from pathlib import Path
+from nonebot.typing import Bot, Event
from aiohttp import client_exceptions
from nonebot.plugin import on_command
from nonebot.permission import SUPERUSER
-from nonebot.adapters.cqhttp import Bot, Event
-from utils.utils_error import errorRepo
-from utils.utils_request import aio_get_bytes
+from ATRI.utils.utils_error import errorRepo
+from ATRI.utils.utils_request import aio_get_bytes
SetuData = on_command('setu', permission=SUPERUSER)
-@SetuData.handle() # type: ignore
+@SetuData.handle()
async def _(bot: Bot, event: Event, state: dict) -> None:
msg0 = "-==ATRI Setu Data System==-\n"
msg0 += "Upload:\n"
@@ -39,7 +39,7 @@ async def _(bot: Bot, event: Event, state: dict) -> None:
UploadSetu = on_command('setu-upload', permission=SUPERUSER)
-@UploadSetu.handle() # type: ignore
+@UploadSetu.handle()
async def _(bot: Bot, event: Event, state: dict) -> None:
msg = str(event.message).strip().split(' ')
@@ -72,10 +72,11 @@ async def _(bot: Bot, event: Event, state: dict) -> None:
name = info["user"]["name"]
u_id = info["user"]["id"]
user_link = f'https://www.pixiv.net/users/{u_id}'
- img = f'https://pixiv.cat/{pid}.jpg'
+ IMG = info["iamge_urls"]["large"]
+ IMG = IMG.replace("i.pximg.net", "i.pixiv.cat")
data_setu = (f'{pid}', f'{title}', f'{tags}', f'{account}', f'{name}',
- f'{u_id}', f'{user_link}', f'{img}')
+ f'{u_id}', f'{user_link}', f'{IMG}')
if s_type == "nearr18":
s_type = "nearR18"
@@ -84,6 +85,8 @@ async def _(bot: Bot, event: Event, state: dict) -> None:
else:
pass
+ os.makedirs('ATRI/data/data_Sqlite/setu', exist_ok=True)
+
if os.path.exists(f'ATRI/data/data_Sqlite/setu/{s_type}.db'):
print('数据文件存在!')
else:
@@ -114,7 +117,7 @@ async def _(bot: Bot, event: Event, state: dict) -> None:
DeleteSetu = on_command('setu-delete', permission=SUPERUSER)
-@DeleteSetu.handle() # type: ignore
+@DeleteSetu.handle()
async def _(bot: Bot, event: Event, state: dict) -> None:
msg = str(event.message).strip().split(' ')
diff --git a/ATRI/plugins/plugin_status/__init__.py b/ATRI/plugins/plugin_status/__init__.py
index bc4fd13..0f9098d 100644
--- a/ATRI/plugins/plugin_status/__init__.py
+++ b/ATRI/plugins/plugin_status/__init__.py
@@ -15,15 +15,15 @@ import sqlite3
from pathlib import Path
from nonebot.plugin import on_command
-from nonebot.adapters.cqhttp import Bot, Event
+from nonebot.typing import Bot, Event
-from utils.utils_error import errorRepo
-from utils.utils_rule import check_banlist
+from ATRI.utils.utils_error import errorRepo
+from ATRI.utils.utils_rule import check_banlist
status_info = on_command('status', rule=check_banlist())
-@status_info.handle() # type: ignore
+@status_info.handle()
async def _(bot: Bot, event: Event, state: dict) -> None:
msg = str(event.message).strip()
diff --git a/ATRI/plugins/plugin_test/__init__.py b/ATRI/plugins/plugin_test/__init__.py
index a83052d..72c7372 100644
--- a/ATRI/plugins/plugin_test/__init__.py
+++ b/ATRI/plugins/plugin_test/__init__.py
@@ -16,16 +16,16 @@ from pathlib import Path
from random import sample
import nonebot
+from nonebot.typing import Bot, Event
from nonebot.plugin import on_command
from nonebot.permission import SUPERUSER
-from nonebot.adapters.cqhttp import Bot, Event
# 此目录下均为功能测试!
testRecord = on_command('测试语音', permission=SUPERUSER)
-@testRecord.handle() # type: ignore
+@testRecord.handle()
async def _(bot: Bot, event: Event, state: dict) -> None:
await testRecord.finish(
f"[CQ:record,file=file:///{os.path.abspath(Path('.') / 'ATRI' / 'plugins' / 'plugin_test' / 'test.mp3')}]"
@@ -35,17 +35,8 @@ async def _(bot: Bot, event: Event, state: dict) -> None:
testGroupList = on_command('获取群列表', permission=SUPERUSER)
-@testGroupList.handle() # type: ignore
+@testGroupList.handle()
async def _(bot: Bot, event: Event, state: dict) -> None:
group_list = await bot.get_group_list()
group = sample(group_list, 1)
print(group[0]['group_id'], type(group[0]['group_id']))
-
-
-testBot = on_command('获取bot', permission=SUPERUSER)
-
-
-@testBot.handle() # type: ignore
-async def _(bot: Bot, event: Event, state: dict) -> None:
- test_bot = nonebot.get_bots()
- print(test_bot, type(test_bot.keys()))
diff --git a/ATRI/plugins/plugin_utils/__init__.py b/ATRI/plugins/plugin_utils/__init__.py
index 9d29a82..16a57d2 100644
--- a/ATRI/plugins/plugin_utils/__init__.py
+++ b/ATRI/plugins/plugin_utils/__init__.py
@@ -16,23 +16,22 @@ from time import strftime
from datetime import datetime, timedelta
from nonebot.plugin import on_command
-from nonebot.adapters.cqhttp import Bot, Event
+from nonebot.typing import Bot, Event
-from utils.utils_error import errorRepo
-from utils.utils_rule import check_banlist, check_switch
-
-from .roll import roll_dice
-from .generate import infoID, numberID
-from .genshin import GetInfo, JsonAnalysis
+from ATRI.utils.utils_error import errorRepo
+from ATRI.utils.utils_rule import check_banlist, check_switch
+from .data_source import Generate, Genshin, Roll
plugin_name_0 = "one-key-adult"
generateID = on_command("我要转大人,一天打25小时游戏",
- rule=check_banlist() & check_switch(plugin_name_0))
+ aliases={'虚拟身份', '一键成年'},
+ rule=check_banlist()
+ & check_switch(plugin_name_0, True))
-@generateID.handle() # type: ignore
+@generateID.handle()
async def _(bot: Bot, event: Event, state: dict) -> None:
- NAME, AREA = infoID()
+ NAME, AREA = Generate().infoID()
BIRTH_BEGIN = datetime(*[1980, 10, 10]) # type: ignore
BIRTH_END = datetime(*[2002, 10, 10]) # type: ignore
@@ -45,7 +44,8 @@ async def _(bot: Bot, event: Event, state: dict) -> None:
(BIRTH_BEGIN + id_card_year_old).timetuple())
id_card_sex = random.choice([0, 1])
id_card_name = random.choice(NAME[{0: "female", 1: "male"}[id_card_sex]])
- id_card_id = numberID(id_card_area, id_card_sex, id_card_birth_day) # type: ignore
+ id_card_id = Generate().numberID(id_card_area, id_card_sex,
+ id_card_birth_day) # type: ignore
msg0 = "恭喜,你已经成大人了!\n"
msg0 += "这是你一天25h游戏的通行证:\n"
@@ -61,7 +61,7 @@ async def _(bot: Bot, event: Event, state: dict) -> None:
rollD = on_command("roll", rule=check_banlist())
-@rollD.handle() # type: ignore
+@rollD.handle()
async def _(bot: Bot, event: Event, state: dict) -> None:
args = str(event.message).strip()
@@ -69,8 +69,7 @@ async def _(bot: Bot, event: Event, state: dict) -> None:
state['resu'] = args
-@rollD.got("resu",
- prompt="roll 参数不能为空~!\ndemo:1d10 或 2d10+2d10") # type: ignore
+@rollD.got("resu", prompt="roll 参数不能为空~!\ndemo:1d10 或 2d10+2d10")
async def _(bot: Bot, event: Event, state: dict) -> None:
resu = state['resu']
match = re.match(r'^([\dd+\s]+?)$', resu)
@@ -78,15 +77,16 @@ async def _(bot: Bot, event: Event, state: dict) -> None:
if not match:
await rollD.finish("请输入正确的参数!!\ndemo:1d10 或 2d10+2d10")
- await rollD.finish(roll_dice(resu))
+ await rollD.finish(Roll().roll_dice(resu))
plugin_name_1 = 'genshin-search'
genshinInfo = on_command('genshin',
- rule=check_banlist() & check_switch(plugin_name_1))
+ rule=check_banlist()
+ & check_switch(plugin_name_1, True))
-@genshinInfo.handle() # type: ignore
+@genshinInfo.handle()
async def _(bot: Bot, event: Event, state: dict) -> None:
args = str(event.message).strip()
@@ -94,7 +94,7 @@ async def _(bot: Bot, event: Event, state: dict) -> None:
state['uid'] = args
-@genshinInfo.got('uid', prompt='请告诉咱需要查询的UID,暂时只支持国服嗷~(') # type: ignore
+@genshinInfo.got('uid', prompt='请告诉咱需要查询的UID,暂时只支持国服嗷~(')
async def _(bot: Bot, event: Event, state: dict) -> None:
uid = str(state['uid'])
@@ -103,12 +103,14 @@ async def _(bot: Bot, event: Event, state: dict) -> None:
uid_info = ''
try:
- uid_info = JsonAnalysis(GetInfo(uid))
+ uid_info = Genshin().JsonAnalysis(Genshin().GetInfo(uid))
except:
- await genshinInfo.finish(errorRepo("数据请求错误,原因可能为ID输入错误或不存在\n暂时只支持国服查询("))
+ await genshinInfo.finish(
+ errorRepo("数据请求错误,原因可能为ID输入错误或不存在\n暂时只支持国服查询("))
msg0 = f'{uid} Genshin Info:\n'
msg0 += uid_info
+ print(uid_info)
await genshinInfo.finish(msg0)
else:
diff --git a/ATRI/plugins/plugin_utils/data_source.py b/ATRI/plugins/plugin_utils/data_source.py
new file mode 100644
index 0000000..da6c52c
--- /dev/null
+++ b/ATRI/plugins/plugin_utils/data_source.py
@@ -0,0 +1,194 @@
+#!/usr/bin/env python3
+# -*- encoding: utf-8 -*-
+'''
+@File : data_source.py
+@Time : 2020/11/21 11:13:42
+@Author : Kyomotoi
+@Contact : kyomotoiowo@gmail.com
+@Github : https://github.com/Kyomotoi
+@License : Copyright © 2018-2020 Kyomotoi, All Rights Reserved.
+'''
+__author__ = 'kyomotoi'
+
+import re
+import os
+import time
+import json
+import string
+import random
+import hashlib
+import requests
+from pathlib import Path
+from zipfile import PyZipFile
+from typing import Tuple, Dict, List
+
+
+class Generate:
+ """虚拟身份证部分"""
+ GENERATE_DATA_PATH = Path(
+ '.') / 'ATRI' / 'plugins' / 'plugin_utils' / 'main.bin'
+
+ def infoID(self) -> Tuple[Dict[str, List[str]], Dict[str, str]]:
+ with PyZipFile(os.path.abspath(self.GENERATE_DATA_PATH),
+ "r") as zipFile:
+ with zipFile.open("name.json", "r") as f:
+ name = json.loads(f.read().decode())
+ with zipFile.open("area.json", "r") as f:
+ area = json.loads(f.read().decode())
+ return name, area
+
+ def numberID(self, area: int, sex: int, birth: int) -> str:
+ def checkSum(fullCode: str) -> int or str:
+ assert len(fullCode) == 17
+ checkSum = sum([((1 << (17 - i)) % 11) * int(fullCode[i])
+ for i in range(0, 17)])
+ checkDigit = (12 - (checkSum % 11)) % 11
+ if checkDigit < 10:
+ return checkDigit
+ else:
+ return "X" # type: ignore
+
+ orderCode = str(random.randint(10, 99))
+ sexCode = str(random.randrange(sex, 10, step=2))
+ fullCode = str(area) + str(birth) + str(orderCode) + str(sexCode)
+ fullCode += str(checkSum(fullCode))
+ return fullCode
+
+
+class Genshin:
+ """原神部分"""
+ def md5(self, text: str) -> str:
+ """text 转 md5"""
+ md5 = hashlib.md5()
+ md5.update(text.encode())
+ return md5.hexdigest()
+
+ def DSGet(self) -> str:
+ mhyVersion = "2.1.0"
+ n = self.md5(mhyVersion)
+ i = str(int(time.time()))
+ r = ''.join(random.sample(string.ascii_lowercase + string.digits, 6))
+ c = self.md5("salt=" + n + "&t=" + i + "&r=" + r)
+ return i + "," + r + "," + c
+
+ def GetInfo(self, uid: str) -> str:
+ """请求API"""
+ req = requests.get(
+ url=
+ f"https://api-takumi.mihoyo.com/game_record/genshin/api/index?server=cn_gf01&role_id={uid}",
+ headers={
+ 'Accept': 'application/json, text/plain, */*',
+ 'DS': self.DSGet(),
+ 'Origin': 'https://webstatic.mihoyo.com',
+ 'x-rpc-app_version': '2.1.0',
+ 'User-Agent':
+ 'Mozilla/5.0 (Linux; Android 9; Unspecified Device) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/39.0.0.0 Mobile Safari/537.36 miHoYoBBS/2.2.0',
+ 'x-rpc-client_type': '4',
+ 'Referer':
+ 'https://webstatic.mihoyo.com/app/community-game-records/index.html?v=6',
+ 'Accept-Encoding': 'gzip, deflate',
+ 'Accept-Language': 'zh-CN,en-US;q=0.8',
+ 'X-Requested-With': 'com.mihoyo.hyperion'
+ })
+ return req.text
+
+ def JsonAnalysis(self, JsonText) -> str:
+ """解析数据"""
+ data = json.loads(JsonText)
+
+ Character_Info = "Roles:\n"
+ Character_List = []
+ Character_List = data["data"]["avatars"]
+ for i in Character_List:
+ if (i["element"] == "None"):
+ Character_Type = "无属性"
+ elif (i["element"] == "Anemo"):
+ Character_Type = "风属性"
+ elif (i["element"] == "Pyro"):
+ Character_Type = "火属性"
+ elif (i["element"] == "Geo"):
+ Character_Type = "岩属性"
+ elif (i["element"] == "Electro"):
+ Character_Type = "雷属性"
+ elif (i["element"] == "Cryo"):
+ Character_Type = "冰属性"
+ elif (i["element"] == "Hydro"):
+ Character_Type = "水属性"
+ else:
+ Character_Type = "草属性"
+
+ if (i["name"] == "旅行者"):
+ if (i["image"].find("UI_AvatarIcon_PlayerGirl") != -1):
+ TempText = f'* {i["name"]}:\n'
+ TempText += f' - [萤——妹妹] {i["level"]}级 {Character_Type}\n'
+
+ elif (i["image"].find("UI_AvatarIcon_PlayerBoy") != -1):
+ TempText = f'* {i["name"]}:\n'
+ TempText += f' - [空——哥哥] {i["level"]}级 {Character_Type}\n'
+
+ else:
+ TempText = f'* {i["name"]}:\n'
+ TempText += f' - [性别判断失败] {i["level"]}级 {Character_Type}\n'
+ else:
+ TempText = f'* {i["name"]} {i["rarity"]}★角色:\n'
+ TempText += f' - {i["level"]}级 好感度({i["fetter"]})级 {Character_Type}\n'
+
+ Character_Info = Character_Info + TempText
+
+ a1 = data["data"]["stats"]["spiral_abyss"]
+
+ Account_Info = 'Account Info:\n'
+ Account_Info += f'- 活跃天数:{data["data"]["stats"]["active_day_number"]} 天\n'
+ Account_Info += f'- 达成成就:{data["data"]["stats"]["achievement_number"]} 个\n'
+ Account_Info += f'- 获得角色:{data["data"]["stats"]["avatar_number"]}个\n'
+ Account_Info += f'- 深渊螺旋:{"没打" if (data["data"]["stats"]["spiral_abyss"] == "-") else f"打到了{a1}"}\n'
+ Account_Info += f'* 收集:\n'
+ Account_Info += f' - 风神瞳{data["data"]["stats"]["anemoculus_number"]}个 岩神瞳{data["data"]["stats"]["geoculus_number"]}个\n'
+ Account_Info += f'* 解锁:\n'
+ Account_Info += f' - 传送点{data["data"]["stats"]["way_point_number"]}个 秘境{data["data"]["stats"]["domain_number"]}个\n'
+ Account_Info += f'* 共开启宝箱:\n'
+ Account_Info += f' - 普通:{data["data"]["stats"]["common_chest_number"]}个 精致:{data["data"]["stats"]["exquisite_chest_number"]}个\n'
+ Account_Info += f' - 珍贵:{data["data"]["stats"]["luxurious_chest_number"]}个 华丽:{data["data"]["stats"]["precious_chest_number"]}个'
+
+ return Character_Info + "\r\n" + Account_Info
+
+
+class Roll:
+ """骰娘部分"""
+ def roll_dice(self, par: str) -> str:
+ """掷骰子"""
+ result = 0
+ proc = ''
+ proc_list = []
+ p = par.split('+')
+
+ # 计算每个单独的roll
+ for i in p:
+ args = re.findall(r"(\d{0,10})(?:(d)(\d{1,10}))", i)
+ args = list(args[0])
+
+ if not args[0]:
+ args[0] = 1
+
+ if int(args[0]) >= 5000 or int(args[2]) >= 5000:
+ return '阿..好大...'
+
+ for a in range(1, int(args[0]) + 1):
+ rd = random.randint(1, int(args[2]))
+ result = result + rd
+
+ if len(proc_list) <= 10:
+ proc_list.append(rd)
+
+ if len(proc_list) <= 10:
+ proc += "+".join(map(str, proc_list))
+
+ elif len(proc_list) >= 10:
+ proc += '太长了不展示了就酱'
+
+ else:
+ proc += str(result)
+
+ result = f"{par}=({proc})={result}"
+
+ return str(result)
\ No newline at end of file
diff --git a/ATRI/plugins/plugin_utils/generate.py b/ATRI/plugins/plugin_utils/generate.py
deleted file mode 100644
index 4749bab..0000000
--- a/ATRI/plugins/plugin_utils/generate.py
+++ /dev/null
@@ -1,47 +0,0 @@
-#!/usr/bin/env python3
-# -*- encoding: utf-8 -*-
-'''
-@File : generateID.py
-@Time : 2020/11/08 10:35:09
-@Author : Kyomotoi
-@Contact : kyomotoiowo@gmail.com
-@Github : https://github.com/Kyomotoi
-@License : Copyright © 2018-2020 Kyomotoi, All Rights Reserved.
-'''
-__author__ = 'kyomotoi'
-
-import os
-import json
-import random
-from pathlib import Path
-from zipfile import PyZipFile
-from typing import Tuple, Dict, List
-
-FILE = Path('.') / 'ATRI' / 'plguins' / 'plugin_utils' / 'main.bin'
-
-
-def infoID() -> Tuple[Dict[str, List[str]], Dict[str, str]]:
- with PyZipFile(os.path.abspath(FILE), "r") as zipFile:
- with zipFile.open("name.json", "r") as f:
- name = json.loads(f.read().decode())
- with zipFile.open("area.json", "r") as f:
- area = json.loads(f.read().decode())
- return name, area
-
-
-def numberID(area: int, sex: int, birth: int) -> str:
- def checkSum(fullCode: str) -> int or str:
- assert len(fullCode) == 17
- checkSum = sum([((1 << (17 - i)) % 11) * int(fullCode[i])
- for i in range(0, 17)])
- checkDigit = (12 - (checkSum % 11)) % 11
- if checkDigit < 10:
- return checkDigit
- else:
- return "X" # type: ignore
-
- orderCode = str(random.randint(10, 99))
- sexCode = str(random.randrange(sex, 10, step=2))
- fullCode = str(area) + str(birth) + str(orderCode) + str(sexCode)
- fullCode += str(checkSum(fullCode))
- return fullCode
diff --git a/ATRI/plugins/plugin_utils/genshin.py b/ATRI/plugins/plugin_utils/genshin.py
deleted file mode 100644
index 642773d..0000000
--- a/ATRI/plugins/plugin_utils/genshin.py
+++ /dev/null
@@ -1,118 +0,0 @@
-#!/usr/bin/env python3
-# -*- encoding: utf-8 -*-
-'''
-@File : genshin.py
-@Time : 2020/11/07 22:34:58
-@Author : Kyomotoi
-@Contact : kyomotoiowo@gmail.com
-@Github : https://github.com/Kyomotoi
-@License : Copyright © 2018-2020 Kyomotoi, All Rights Reserved.
-@Docs : Fork from https://github.com/Womsxd/YuanShen_User_Info
-'''
-__author__ = 'kyomotoi'
-
-import json
-import time
-import string
-import random
-import hashlib
-import requests
-
-
-def md5(text: str) -> str:
- """text 转 md5"""
- md5 = hashlib.md5()
- md5.update(text.encode())
- return md5.hexdigest()
-
-
-def DSGet() -> str:
- mhyVersion = "2.1.0"
- n = md5(mhyVersion)
- i = str(int(time.time()))
- r = ''.join(random.sample(string.ascii_lowercase + string.digits, 6))
- c = md5("salt=" + n + "&t=" + i + "&r=" + r)
- return i + "," + r + "," + c
-
-
-def GetInfo(uid: str) -> str:
- """请求API"""
- req = requests.get(
- url=
- f"https://api-takumi.mihoyo.com/game_record/genshin/api/index?server=cn_gf01&role_id={uid}",
- headers={
- 'Accept': 'application/json, text/plain, */*',
- 'DS': DSGet(),
- 'Origin': 'https://webstatic.mihoyo.com',
- 'x-rpc-app_version': '2.1.0',
- 'User-Agent':
- 'Mozilla/5.0 (Linux; Android 9; Unspecified Device) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/39.0.0.0 Mobile Safari/537.36 miHoYoBBS/2.2.0',
- 'x-rpc-client_type': '4',
- 'Referer':
- 'https://webstatic.mihoyo.com/app/community-game-records/index.html?v=6',
- 'Accept-Encoding': 'gzip, deflate',
- 'Accept-Language': 'zh-CN,en-US;q=0.8',
- 'X-Requested-With': 'com.mihoyo.hyperion'
- })
- return req.text
-
-
-def JsonAnalysis(JsonText) -> str:
- """解析数据"""
- data = json.loads(JsonText)
-
- Character_Info = "Roles:\n"
- Character_List = []
- Character_List = data["data"]["avatars"]
- for i in Character_List:
- if (i["element"] == "None"):
- Character_Type = "无属性"
- elif (i["element"] == "Anemo"):
- Character_Type = "风属性"
- elif (i["element"] == "Pyro"):
- Character_Type = "火属性"
- elif (i["element"] == "Geo"):
- Character_Type = "岩属性"
- elif (i["element"] == "Electro"):
- Character_Type = "雷属性"
- elif (i["element"] == "Cryo"):
- Character_Type = "冰属性"
- elif (i["element"] == "Hydro"):
- Character_Type = "水属性"
- else:
- Character_Type = "草属性"
-
- if (i["name"] == "旅行者"):
- if (i["image"].find("UI_AvatarIcon_PlayerGirl") != -1):
- TempText = f'* {i["name"]}:\n'
- TempText += f' - [萤——妹妹] {i["level"]}级 {Character_Type}\n'
-
- elif (i["image"].find("UI_AvatarIcon_PlayerBoy") != -1):
- TempText = f'* {i["name"]}:\n'
- TempText += f' - [空——哥哥] {i["level"]}级 {Character_Type}\n'
-
- else:
- TempText = f'* {i["name"]}:\n'
- TempText += f' - [性别判断失败] {i["level"]}级 {Character_Type}\n'
- else:
- TempText = f'* {i["name"]} {i["rarity"]}★角色:\n'
- TempText += f' - {i["level"]}级 好感度({i["fetter"]})级 {Character_Type}\n'
-
- Character_Info = Character_Info + TempText
-
- a1 = data["data"]["stats"]["spiral_abyss"]
-
- Account_Info = 'Account Info:\n'
- Account_Info += f'- 活跃天数:{data["data"]["stats"]["active_day_number"]} 天\n'
- Account_Info += f'- 达成成就:{data["data"]["stats"]["achievement_number"]} 个\n'
- Account_Info += f'- 获得角色:{data["data"]["stats"]["avatar_number"]}个\n'
- Account_Info += f'- 深渊螺旋:{"没打" if (data["data"]["stats"]["spiral_abyss"] == "-") else f"打到了{a1}"}\n'
- Account_Info += f'* 收集:\n'
- Account_Info += f' - 风神瞳{data["data"]["stats"]["anemoculus_number"]}个 岩神瞳{data["data"]["stats"]["geoculus_number"]}个\n'
- Account_Info += f'* 解锁:\n'
- Account_Info += f' - 传送点{data["data"]["stats"]["way_point_number"]}个 秘境{data["data"]["stats"]["domain_number"]}个\n'
- Account_Info += f'* 共开启宝箱:\n'
- Account_Info += f' - 普通:{data["data"]["stats"]["common_chest_number"]}个 精致:{data["data"]["stats"]["exquisite_chest_number"]}个\n'
- Account_Info += f' - 珍贵:{data["data"]["stats"]["luxurious_chest_number"]}个 华丽:{data["data"]["stats"]["precious_chest_number"]}个'
-
- return Character_Info + "\r\n" + Account_Info
\ No newline at end of file
diff --git a/ATRI/plugins/plugin_utils/roll.py b/ATRI/plugins/plugin_utils/roll.py
deleted file mode 100644
index bf87aa3..0000000
--- a/ATRI/plugins/plugin_utils/roll.py
+++ /dev/null
@@ -1,59 +0,0 @@
-#!/usr/bin/env python3
-# -*- encoding: utf-8 -*-
-'''
-@File : roll.py
-@Time : 2020/11/07 15:56:02
-@Author : Kyomotoi
-@Contact : kyomotoiowo@gmail.com
-@Github : https://github.com/Kyomotoi
-@License : Copyright © 2018-2020 Kyomotoi, All Rights Reserved.
-'''
-__author__ = 'kyomotoi'
-
-import re
-from random import randint
-
-
-def roll_dice(par: str) -> str:
- """掷骰子"""
- result = 0
- proc = ''
- proc_list = []
- p = par.split('+')
-
- # 计算每个单独的roll
- for i in p:
- args = re.findall(r"(\d{0,10})(?:(d)(\d{1,10}))", i)
- args = list(args[0])
-
- if not args[0]:
- args[0] = 1
-
- if int(args[0]) >= 5000 or int(args[2]) >= 5000:
- return '阿..好大...'
-
- for a in range(1, int(args[0]) + 1):
- rd = randint(1, int(args[2]))
- result = result + rd
-
- if len(proc_list) <= 10:
- proc_list.append(rd)
-
- if len(proc_list) == 10:
- temp_list = []
- for i in proc_list:
- if len(temp_list) == 9:
- proc += str(i)
- else:
- proc += str(i) + '+'
- temp_list.append(i)
-
- elif len(proc_list) >= 10:
- proc += '太长了不展示了'
-
- else:
- proc += str(result)
-
- result = f"{par}=({proc})={result}"
-
- return str(result)
diff --git a/ATRI/utils/utils_ban/__init__.py b/ATRI/utils/utils_ban/__init__.py
new file mode 100644
index 0000000..1946c5c
--- /dev/null
+++ b/ATRI/utils/utils_ban/__init__.py
@@ -0,0 +1,25 @@
+#!/usr/bin/env python3
+# -*- encoding: utf-8 -*-
+
+'''
+@File : __init__.py
+@Time : 2020/11/21 22:50:49
+@Author : Kyomotoi
+@Contact : kyomotoiowo@gmail.com
+@Github : https://github.com/Kyomotoi
+@License : Copyright © 2018-2020 Kyomotoi, All Rights Reserved.
+'''
+__author__ = 'kyomotoi'
+
+import json
+from pathlib import Path
+
+BAN_LIST_PATH = Path('.') / 'ATRI' / 'utils' / 'utils_rule' / 'ban_list_user.json'
+with open(BAN_LIST_PATH, 'r') as f:
+ data = json.load(f)
+
+
+def ban(user: str) -> None:
+ data[user] = user
+ with open(BAN_LIST_PATH, 'w') as f:
+ f.write(json.dumps(data))
diff --git a/ATRI/utils/utils_error/__init__.py b/ATRI/utils/utils_error/__init__.py
new file mode 100644
index 0000000..d033613
--- /dev/null
+++ b/ATRI/utils/utils_error/__init__.py
@@ -0,0 +1,54 @@
+#!/usr/bin/env python3
+# -*- encoding: utf-8 -*-
+'''
+@File : __init__.py
+@Time : 2020/10/11 14:43:10
+@Author : Kyomotoi
+@Contact : kyomotoiowo@gmail.com
+@Github : https://github.com/Kyomotoi
+@License : Copyright © 2018-2020 Kyomotoi, All Rights Reserved.
+'''
+__author__ = 'kyomotoi'
+
+import json
+import string
+from pathlib import Path
+from random import sample
+from typing import Optional
+from datetime import datetime
+from traceback import format_exc
+
+
+def errorRepo(repo_msg: Optional[str] = None) -> str:
+ '''
+ 出错时返回错误堆栈
+
+ :return: str
+ '''
+ file_error = Path('.') / 'ATRI' / 'data' / 'data_Error' / 'error.json'
+ try:
+ with open(file_error, 'r') as f:
+ data_error = json.load(f)
+ except FileNotFoundError:
+ data_error = {}
+
+ key_error = ''.join(sample(string.ascii_letters + string.digits, 16))
+ msg_error = f"{datetime.now()}\n"
+ msg_error = f"{format_exc()}"
+ data_error[f"{key_error}"] = f"{msg_error}"
+
+ with open(file_error, 'w') as f:
+ f.write(json.dumps(data_error))
+ f.close()
+
+ if repo_msg:
+ pass
+ else:
+ repo_msg = 'unknown'
+
+ msg0 = f'ERROR! Reason: [{repo_msg}]\n'
+ msg0 += f'trackID: {key_error}\n'
+ msg0 += "请使用[来杯红茶]功能以联系维护者\n"
+ msg0 += "并附上 trackID"
+
+ return msg0
\ No newline at end of file
diff --git a/ATRI/utils/utils_history/__init__.py b/ATRI/utils/utils_history/__init__.py
new file mode 100644
index 0000000..3aae3fa
--- /dev/null
+++ b/ATRI/utils/utils_history/__init__.py
@@ -0,0 +1,105 @@
+#!/usr/bin/env python3
+# -*- encoding: utf-8 -*-
+'''
+@File : __init__.py
+@Time : 2020/11/07 14:33:22
+@Author : Kyomotoi
+@Contact : kyomotoiowo@gmail.com
+@Github : https://github.com/Kyomotoi
+@License : Copyright © 2018-2020 Kyomotoi, All Rights Reserved.
+'''
+__author__ = 'kyomotoi'
+
+import os
+import json
+import datetime
+from pathlib import Path
+from typing import Optional
+
+
+def saveMessage(message_id: str,
+ message: str,
+ user: str,
+ group: Optional[str] = None) -> None:
+ """储存消息"""
+ GROUP_PATH = Path(
+ '.'
+ ) / 'ATRI' / 'data' / 'data_Group' / f'{group}' / f"{datetime.datetime.now().strftime('%Y-%m-%d')}-message.json"
+ PRIVATE_PATH = Path(
+ '.'
+ ) / 'ATRI' / 'data' / 'data_Private_Message' / f"{datetime.datetime.now().strftime('%Y-%m-%d')}-private-message.json"
+
+ # 检查目标文件目录
+ if not GROUP_PATH.is_file():
+ os.makedirs(Path('.') / 'ATRI' / 'data' / 'data_Group', exist_ok=True)
+ os.makedirs(Path('.') / 'ATRI' / 'data' / 'data_Group' / f'{group}',
+ exist_ok=True)
+
+ with open(GROUP_PATH, 'w') as f:
+ f.write(json.dumps({}))
+
+ if not PRIVATE_PATH.is_file():
+ os.makedirs(Path('.') / 'ATRI' / 'data' / 'data_Private_Message',
+ exist_ok=True)
+
+ with open(PRIVATE_PATH, 'w') as f:
+ f.write(json.dumps({}))
+
+ # 加载目标文件
+ with open(GROUP_PATH, 'r') as f:
+ DATA_GROUP = json.load(f)
+
+ with open(PRIVATE_PATH, 'r') as f:
+ DATA_PRIVATE = json.load(f)
+
+ # 写入
+ if group:
+ DATA_GROUP[f"{message_id}"] = {
+ "message": f"{message}",
+ "user_id": f"{user}",
+ "group_id": f"{group}"
+ }
+
+ with open(GROUP_PATH, 'w') as f:
+ f.write(json.dumps(DATA_GROUP))
+
+ else:
+ DATA_PRIVATE[f"{message_id}"] = {
+ "message": f"{message}",
+ "user_id": f"{user}"
+ }
+
+ with open(PRIVATE_PATH, 'w') as f:
+ f.write(json.dumps(DATA_PRIVATE))
+
+
+def getMessage(message_id: str, group: Optional[str] = None) -> dict:
+ '''
+ 传入消息id以获取对应信息
+
+ :return: dict
+ '''
+ GROUP_PATH = Path(
+ '.'
+ ) / 'ATRI' / 'data' / 'data_Group' / f'{group}' / f"{datetime.datetime.now().strftime('%Y-%m-%d')}-message.json"
+ PRIVATE_PATH = Path(
+ '.'
+ ) / 'ATRI' / 'data' / 'data_Private_Message' / f"{datetime.datetime.now().strftime('%Y-%m-%d')}-private-message.json"
+
+ if group:
+ try:
+ with open(GROUP_PATH, 'r') as f:
+ data_group = json.load(f)
+ return data_group[message_id]
+
+ except:
+ return {"status": 0}
+
+ else:
+ try:
+ with open(PRIVATE_PATH, 'r') as f:
+ data_private = json.load(f)
+ return data_private[message_id]
+
+ except:
+ return {"status": 0}
diff --git a/ATRI/utils/utils_img/__init__.py b/ATRI/utils/utils_img/__init__.py
new file mode 100644
index 0000000..7b79146
--- /dev/null
+++ b/ATRI/utils/utils_img/__init__.py
@@ -0,0 +1,62 @@
+#!/usr/bin/env python3
+# -*- encoding: utf-8 -*-
+
+'''
+@File : __init__.py
+@Time : 2020/11/07 14:17:37
+@Author : Kyomotoi
+@Contact : kyomotoiowo@gmail.com
+@Github : https://github.com/Kyomotoi
+@License : Copyright © 2018-2020 Kyomotoi, All Rights Reserved.
+'''
+__author__ = 'kyomotoi'
+
+import os
+import string
+import aiohttp
+from pathlib import Path
+from random import sample
+
+import PIL.Image as Image
+from PIL import ImageFile
+
+async def aio_download_pics(url) -> str:
+ '''
+ 下载图片并重命名
+
+ :return: img file
+ '''
+ path = Path('.') / 'ATRI' / 'data' / 'data_Temp' / 'img'
+ path = os.path.abspath(path)
+ img_key = ''.join(sample(string.ascii_letters + string.digits, 16))
+ img = path + f'\\{img_key}.png'
+ async with aiohttp.ClientSession() as session:
+ async with session.get(url) as response:
+ pic = await response.read() #以Bytes方式读入非文字
+ with open(img, mode='wb') as f:# 写入文件
+ f.write(pic)
+ f.close()
+ return img
+
+def compress_image(outfile: str, kb=400, quality=85, k=0.9) -> str:
+ '''
+ 压缩图片
+
+ :return: img file
+ '''
+ o_size = os.path.getsize(outfile) // 1024
+ if o_size <= kb:
+ return outfile
+
+ ImageFile.LOAD_TRUNCATED_IMAGES = True # type: ignore
+ while o_size > kb:
+ im = Image.open(outfile)
+ x, y = im.size
+ out = im.resize((int(x*k), int(y*k)), Image.ANTIALIAS)
+ try:
+ out.save(outfile, quality=quality)
+ except Exception as e:
+ print(e)
+ break
+ o_size = os.path.getsize(outfile) // 1024
+ return outfile
diff --git a/ATRI/utils/utils_request/__init__.py b/ATRI/utils/utils_request/__init__.py
new file mode 100644
index 0000000..fd235bf
--- /dev/null
+++ b/ATRI/utils/utils_request/__init__.py
@@ -0,0 +1,39 @@
+#!/usr/bin/env python3
+# -*- encoding: utf-8 -*-
+'''
+@File : __init__.py
+@Time : 2020/10/11 14:43:55
+@Author : Kyomotoi
+@Contact : kyomotoiowo@gmail.com
+@Github : https://github.com/Kyomotoi
+@License : Copyright © 2018-2020 Kyomotoi, All Rights Reserved.
+'''
+__author__ = 'kyomotoi'
+
+import requests
+from typing import Optional
+from aiohttp import ClientSession
+
+def request_get(url: str, params: Optional[dict] = None) -> bytes:
+ '''
+ 通过 GET 方式请求 url。
+
+ :return: bytes
+ '''
+ return requests.get(url, params).content
+
+def request_api_text(url: str) -> str:
+ res = requests.request("GET", url)
+ html = res.text
+ return html
+
+async def aio_get_bytes(url: str, headers: Optional[dict] = None) -> bytes:
+ '''
+ 通过 GET 以 异步 方式请求 url。
+
+ :return: bytes
+ '''
+ async with ClientSession() as asyncSession:
+ async with asyncSession.get(url, headers=headers) as resp:
+ result = await resp.read()
+ return result
\ No newline at end of file
diff --git a/ATRI/utils/utils_rule/__init__.py b/ATRI/utils/utils_rule/__init__.py
new file mode 100644
index 0000000..dcaeedc
--- /dev/null
+++ b/ATRI/utils/utils_rule/__init__.py
@@ -0,0 +1,151 @@
+#!/usr/bin/env python3
+# -*- encoding: utf-8 -*-
+'''
+@File : __init__.py
+@Time : 2020/11/06 19:27:00
+@Author : Kyomotoi
+@Contact : kyomotoiowo@gmail.com
+@Github : https://github.com/Kyomotoi
+@License : Copyright © 2018-2020 Kyomotoi, All Rights Reserved.
+'''
+__author__ = 'kyomotoi'
+
+import os
+import json
+from pathlib import Path
+from typing import Optional
+from nonebot.rule import Rule
+from nonebot.typing import Bot, Event
+
+
+def check_banlist(for_group: Optional[bool] = False) -> Rule:
+ '''
+ 检查目标是否存在于封禁名单
+
+ :return: bool
+ '''
+ async def _chech_banlist(bot: Bot, event: Event, state: dict) -> bool:
+ # 获取目标信息
+ user = str(event.user_id)
+ group = str(event.group_id)
+
+ # 名单目录
+ BAN_LIST_USER_PATH = Path(
+ '.') / 'ATRI' / 'utils' / 'utils_rule' / 'ban_list_user.json'
+ BAN_LIST_GROUP_PATH = Path(
+ '.') / 'ATRI' / 'utils' / 'utils_rule' / 'ban_list_group.json'
+
+ # 检查文件是否存在,如不存在,自动创建并写入默认值
+ if not BAN_LIST_USER_PATH.is_file():
+ with open(BAN_LIST_USER_PATH, 'w') as f:
+ f.write(json.dumps({}))
+
+ if not BAN_LIST_GROUP_PATH.is_file():
+ with open(BAN_LIST_GROUP_PATH, 'w') as f:
+ f.write(json.dumps({}))
+
+ # 读取文件
+ with open(BAN_LIST_USER_PATH, 'r') as f:
+ data_user = json.load(f)
+
+ with open(BAN_LIST_GROUP_PATH, 'r') as f:
+ data_group = json.load(f)
+
+ # 判断目标
+ if not for_group:
+ if user:
+ if user not in data_user:
+ if group:
+ if group not in data_group:
+ return True
+ else:
+ return False
+ else:
+ return True
+ else:
+ return False
+
+ elif group:
+ if group not in data_group:
+ if user:
+ if user not in data_user:
+ return True
+ else:
+ return False
+ else:
+ return True
+ else:
+ return False
+ else:
+ return False
+ else:
+ if group not in data_group:
+ return True
+ else:
+ return False
+
+ return Rule(_chech_banlist)
+
+
+def check_switch(func_name: str, notice: bool) -> Rule:
+ '''
+ 检查目标功能是否开启
+
+ :return: bool
+ '''
+ async def _check_switch(bot: Bot, event: Event, state: dict) -> bool:
+ # 获取目标信息
+ group = str(event.group_id)
+
+ # 文件目录
+ SWITCH_ALL_PATH = Path('.') / 'ATRI' / 'utils' / 'utils_rule' / 'switch.json'
+ SWITCH_ALONE_PATH = Path(
+ '.') / 'ATRI' / 'data' / 'data_Group' / f'{group}' / 'switch.json'
+
+ # 检查文件是否存在,如不存在,自动创建并写入默认值
+ if not SWITCH_ALL_PATH.is_file():
+ with open(SWITCH_ALL_PATH, 'ws') as f:
+ f.write(json.dumps({}))
+
+ if not SWITCH_ALONE_PATH.is_file():
+ try:
+ os.mkdir(
+ Path('.') / 'ATRI' / 'data' / 'data_Group' / f'{group}')
+ except:
+ pass
+
+ with open(SWITCH_ALONE_PATH, 'w') as f:
+ f.write(json.dumps({}))
+
+ # 读取文件
+ with open(SWITCH_ALL_PATH, 'r') as f:
+ data_all = json.load(f)
+
+ with open(SWITCH_ALONE_PATH, 'r') as f:
+ data_alone = json.load(f)
+
+ # 判断目标是否存在于将要读取的文件,如不存在,写入
+ # 此项举措是为了适应以后版本更新出现新插件的状况
+ # 不至于每次都需要修改
+ if func_name not in data_all:
+ data_all[func_name] = "True"
+ with open(SWITCH_ALL_PATH, 'w') as f:
+ f.write(json.dumps(data_all))
+
+ if func_name not in data_alone:
+ data_alone[func_name] = "True"
+ with open(SWITCH_ALONE_PATH, 'w') as f:
+ f.write(json.dumps(data_alone))
+
+ # 判断目标
+ if data_all[func_name] == "True":
+ if data_alone[func_name] == "True":
+ return True
+ else:
+ return False
+ else:
+ if notice:
+ await bot.send(event, f"Service-{func_name} has been closed.")
+ return False
+
+ return Rule(_check_switch)
diff --git a/ATRI/utils/utils_rule/ban_list_group.json b/ATRI/utils/utils_rule/ban_list_group.json
new file mode 100644
index 0000000..9e26dfe
--- /dev/null
+++ b/ATRI/utils/utils_rule/ban_list_group.json
@@ -0,0 +1 @@
+{}
\ No newline at end of file
diff --git a/ATRI/utils/utils_rule/ban_list_user.json b/ATRI/utils/utils_rule/ban_list_user.json
new file mode 100644
index 0000000..9e26dfe
--- /dev/null
+++ b/ATRI/utils/utils_rule/ban_list_user.json
@@ -0,0 +1 @@
+{}
\ No newline at end of file
diff --git a/ATRI/utils/utils_rule/switch.json b/ATRI/utils/utils_rule/switch.json
new file mode 100644
index 0000000..1717be3
--- /dev/null
+++ b/ATRI/utils/utils_rule/switch.json
@@ -0,0 +1 @@
+{"anime-setu": "False", "anime-pic-search": "True", "anime-vid-search": "True", "all-off-anime-setu": "True", "pixiv-pic-search": "True", "pixiv-author-search": "True", "pixiv-rank": "True", "one-key-adult": "True", "genshin-search": "True", "drifting-bottle": "True"}
\ No newline at end of file
diff --git a/ATRI/utils/utils_switch/__init__.py b/ATRI/utils/utils_switch/__init__.py
new file mode 100644
index 0000000..4c80e94
--- /dev/null
+++ b/ATRI/utils/utils_switch/__init__.py
@@ -0,0 +1,79 @@
+#!/usr/bin/env python3
+# -*- encoding: utf-8 -*-
+'''
+@File : __init__.py
+@Time : 2020/10/11 14:44:06
+@Author : Kyomotoi
+@Contact : kyomotoiowo@gmail.com
+@Github : https://github.com/Kyomotoi
+@License : Copyright © 2018-2020 Kyomotoi, All Rights Reserved.
+'''
+__author__ = 'kyomotoi'
+
+import json
+from pathlib import Path
+from typing import Optional
+
+
+def controlSwitch(func_name: str,
+ control: bool,
+ group: Optional[str] = None) -> str:
+ '''
+ 控制开关 开启或关闭
+
+ :return: str
+ '''
+ file_switch_all = Path('.') / 'ATRI' / 'utils' / 'utils_rule' / 'switch.json'
+
+ if group:
+ file_switch_group = Path(
+ '.') / 'ATRI' / 'data' / 'data_Group' / f'{group}' / 'switch.json'
+ try:
+ with open(file_switch_group, 'r') as f:
+ data_switch_group = json.load(f)
+ except FileNotFoundError:
+ data_switch_group = {}
+
+ if data_switch_group[f"{func_name}"]:
+ pass
+ else:
+ return f"Can't find func({func_name})"
+
+ data_switch_group[f"{func_name}"] = f"{control}"
+
+ with open(file_switch_group, 'w') as f:
+ f.write(json.dumps(data_switch_group))
+ f.close()
+
+ else:
+ pass
+
+
+ with open(file_switch_all, 'r') as f:
+ try:
+ data_switch_all = json.load(f)
+ except:
+ data_switch_all = {}
+
+ if not data_switch_all[f"{func_name}"]:
+ return f"Can't find func({func_name})"
+
+ data_switch_all[f"{func_name}"] = f"{control}"
+
+ with open(file_switch_all, 'w') as f:
+ f.write(json.dumps(data_switch_all))
+ f.close()
+
+ if control == True:
+ if group:
+ msg = f"({func_name}) has been opened for group ({group})!"
+ else:
+ msg = f"({func_name}) has been opened!"
+
+ else:
+ if group:
+ msg = f"({func_name}) has been closed for group ({group})!"
+ else:
+ msg = f"({func_name}) has been closed!"
+
+ return msg
\ No newline at end of file
diff --git a/ATRI/utils/utils_textcheck/__init__.py b/ATRI/utils/utils_textcheck/__init__.py
new file mode 100644
index 0000000..531bf69
--- /dev/null
+++ b/ATRI/utils/utils_textcheck/__init__.py
@@ -0,0 +1,60 @@
+#!/usr/bin/env python3
+# -*- encoding: utf-8 -*-
+'''
+@File : data_source.py
+@Time : 2020/11/21 19:54:11
+@Author : Kyomotoi
+@Contact : kyomotoiowo@gmail.com
+@Github : https://github.com/Kyomotoi
+@License : Copyright © 2018-2020 Kyomotoi, All Rights Reserved.
+'''
+__author__ = 'kyomotoi'
+
+import json
+from pathlib import Path
+from typing import Optional
+
+PUBLIC_OPINION_PATH = Path('.') / 'ATRI' / 'utils' / 'utils_textcheck' / 'public_opinion.json'
+
+
+class Textcheck:
+ """文字检查,专供舆情"""
+ with open(PUBLIC_OPINION_PATH, 'r+') as f:
+ try:
+ data = json.load(f)
+ except:
+ data = {}
+
+ def check(self, msg: str) -> Optional[str]:
+ wait_list = [keys for keys in self.data.keys()]
+ for word in wait_list:
+ if word in msg:
+ return self.data[word]
+ else:
+ return "False"
+
+ def add_word(self, word: str, repo: str, max_times: int,
+ ban_time: int) -> Optional[str]:
+ if word in self.data:
+ return '相关关键词已经有啦~!'
+ else:
+ self.data[word] = [repo, max_times, ban_time]
+ msg0 = '学習しました!\n'
+ msg0 += f'Key: {word}\n'
+ msg0 += f'Repo: {repo}\n'
+ msg0 += f'Max times: {max_times}\n'
+ msg0 += f'Ban time: {ban_time}'
+ return msg0
+
+ def del_word(self, word: str) -> str:
+ if word in self.data:
+ del self.data[word]
+ return "好叻~!"
+ else:
+ return "未发现相关关键词呢..."
+
+ def get_times(self, word: str) -> Optional[int]:
+ if word not in self.data:
+ return 0
+ else:
+ return self.data[word][1]
diff --git a/ATRI/utils/utils_textcheck/public_opinion.json b/ATRI/utils/utils_textcheck/public_opinion.json
new file mode 100644
index 0000000..9e26dfe
--- /dev/null
+++ b/ATRI/utils/utils_textcheck/public_opinion.json
@@ -0,0 +1 @@
+{}
\ No newline at end of file
diff --git a/ATRI/utils/utils_times/__init__.py b/ATRI/utils/utils_times/__init__.py
new file mode 100644
index 0000000..1f65fc6
--- /dev/null
+++ b/ATRI/utils/utils_times/__init__.py
@@ -0,0 +1,27 @@
+#!/usr/bin/env python3
+# -*- encoding: utf-8 -*-
+'''
+@File : __init__.py
+@Time : 2020/10/31 19:36:49
+@Author : Kyomotoi
+@Contact : kyomotoiowo@gmail.com
+@Github : https://github.com/Kyomotoi
+@License : Copyright © 2018-2020 Kyomotoi, All Rights Reserved.
+'''
+__author__ = 'kyomotoi'
+
+import warnings
+
+
+def countX(lst: list, aim) -> int:
+ '''
+ 检查某列表某元素出现次数
+
+ :return: int
+ '''
+ warnings.simplefilter('ignore', ResourceWarning)
+ count = 0
+ for ele in lst:
+ if (ele == aim):
+ count = count + 1
+ return count
diff --git a/ATRI/utils/utils_translate/__init__.py b/ATRI/utils/utils_translate/__init__.py
new file mode 100644
index 0000000..29026e7
--- /dev/null
+++ b/ATRI/utils/utils_translate/__init__.py
@@ -0,0 +1,56 @@
+#!/usr/bin/env python3
+# -*- encoding: utf-8 -*-
+'''
+@File : __init__.py
+@Time : 2020/10/23 21:59:02
+@Author : Kyomotoi
+@Contact : kyomotoiowo@gmail.com
+@Github : https://github.com/Kyomotoi
+@License : Copyright © 2018-2020 Kyomotoi, All Rights Reserved.
+'''
+__author__ = 'kyomotoi'
+
+SIMPLE = "万与丑专业丛东丝丢两严丧个丬丰临为丽举么义乌乐乔习乡书买乱争于亏云亘亚产亩亲亵亸亿仅从仑仓仪们价众优伙会伛伞伟传伤伥伦伧伪伫体余佣佥侠侣侥侦侧侨侩侪侬俣俦俨俩俪俭债倾偬偻偾偿傥傧储傩儿兑兖党兰关兴兹养兽冁内冈册写军农冢冯冲决况冻净凄凉凌减凑凛几凤凫凭凯击凼凿刍划刘则刚创删别刬刭刽刿剀剂剐剑剥剧劝办务劢动励劲劳势勋勐勚匀匦匮区医华协单卖卢卤卧卫却卺厂厅历厉压厌厍厕厢厣厦厨厩厮县参叆叇双发变叙叠叶号叹叽吁后吓吕吗吣吨听启吴呒呓呕呖呗员呙呛呜咏咔咙咛咝咤咴咸哌响哑哒哓哔哕哗哙哜哝哟唛唝唠唡唢唣唤唿啧啬啭啮啰啴啸喷喽喾嗫呵嗳嘘嘤嘱噜噼嚣嚯团园囱围囵国图圆圣圹场坂坏块坚坛坜坝坞坟坠垄垅垆垒垦垧垩垫垭垯垱垲垴埘埙埚埝埯堑堕塆墙壮声壳壶壸处备复够头夸夹夺奁奂奋奖奥妆妇妈妩妪妫姗姜娄娅娆娇娈娱娲娴婳婴婵婶媪嫒嫔嫱嬷孙学孪宁宝实宠审宪宫宽宾寝对寻导寿将尔尘尧尴尸尽层屃屉届属屡屦屿岁岂岖岗岘岙岚岛岭岳岽岿峃峄峡峣峤峥峦崂崃崄崭嵘嵚嵛嵝嵴巅巩巯币帅师帏帐帘帜带帧帮帱帻帼幂幞干并广庄庆庐庑库应庙庞废庼廪开异弃张弥弪弯弹强归当录彟彦彻径徕御忆忏忧忾怀态怂怃怄怅怆怜总怼怿恋恳恶恸恹恺恻恼恽悦悫悬悭悯惊惧惨惩惫惬惭惮惯愍愠愤愦愿慑慭憷懑懒懔戆戋戏戗战戬户扎扑扦执扩扪扫扬扰抚抛抟抠抡抢护报担拟拢拣拥拦拧拨择挂挚挛挜挝挞挟挠挡挢挣挤挥挦捞损捡换捣据捻掳掴掷掸掺掼揸揽揿搀搁搂搅携摄摅摆摇摈摊撄撑撵撷撸撺擞攒敌敛数斋斓斗斩断无旧时旷旸昙昼昽显晋晒晓晔晕晖暂暧札术朴机杀杂权条来杨杩杰极构枞枢枣枥枧枨枪枫枭柜柠柽栀栅标栈栉栊栋栌栎栏树栖样栾桊桠桡桢档桤桥桦桧桨桩梦梼梾检棂椁椟椠椤椭楼榄榇榈榉槚槛槟槠横樯樱橥橱橹橼檐檩欢欤欧歼殁殇残殒殓殚殡殴毁毂毕毙毡毵氇气氢氩氲汇汉污汤汹沓沟没沣沤沥沦沧沨沩沪沵泞泪泶泷泸泺泻泼泽泾洁洒洼浃浅浆浇浈浉浊测浍济浏浐浑浒浓浔浕涂涌涛涝涞涟涠涡涢涣涤润涧涨涩淀渊渌渍渎渐渑渔渖渗温游湾湿溃溅溆溇滗滚滞滟滠满滢滤滥滦滨滩滪漤潆潇潋潍潜潴澜濑濒灏灭灯灵灾灿炀炉炖炜炝点炼炽烁烂烃烛烟烦烧烨烩烫烬热焕焖焘煅煳熘爱爷牍牦牵牺犊犟状犷犸犹狈狍狝狞独狭狮狯狰狱狲猃猎猕猡猪猫猬献獭玑玙玚玛玮环现玱玺珉珏珐珑珰珲琎琏琐琼瑶瑷璇璎瓒瓮瓯电画畅畲畴疖疗疟疠疡疬疮疯疱疴痈痉痒痖痨痪痫痴瘅瘆瘗瘘瘪瘫瘾瘿癞癣癫癯皑皱皲盏盐监盖盗盘眍眦眬着睁睐睑瞒瞩矫矶矾矿砀码砖砗砚砜砺砻砾础硁硅硕硖硗硙硚确硷碍碛碜碱碹磙礼祎祢祯祷祸禀禄禅离秃秆种积称秽秾稆税稣稳穑穷窃窍窑窜窝窥窦窭竖竞笃笋笔笕笺笼笾筑筚筛筜筝筹签简箓箦箧箨箩箪箫篑篓篮篱簖籁籴类籼粜粝粤粪粮糁糇紧絷纟纠纡红纣纤纥约级纨纩纪纫纬纭纮纯纰纱纲纳纴纵纶纷纸纹纺纻纼纽纾线绀绁绂练组绅细织终绉绊绋绌绍绎经绐绑绒结绔绕绖绗绘给绚绛络绝绞统绠绡绢绣绤绥绦继绨绩绪绫绬续绮绯绰绱绲绳维绵绶绷绸绹绺绻综绽绾绿缀缁缂缃缄缅缆缇缈缉缊缋缌缍缎缏缐缑缒缓缔缕编缗缘缙缚缛缜缝缞缟缠缡缢缣缤缥缦缧缨缩缪缫缬缭缮缯缰缱缲缳缴缵罂网罗罚罢罴羁羟羡翘翙翚耢耧耸耻聂聋职聍联聩聪肃肠肤肷肾肿胀胁胆胜胧胨胪胫胶脉脍脏脐脑脓脔脚脱脶脸腊腌腘腭腻腼腽腾膑臜舆舣舰舱舻艰艳艹艺节芈芗芜芦苁苇苈苋苌苍苎苏苘苹茎茏茑茔茕茧荆荐荙荚荛荜荞荟荠荡荣荤荥荦荧荨荩荪荫荬荭荮药莅莜莱莲莳莴莶获莸莹莺莼萚萝萤营萦萧萨葱蒇蒉蒋蒌蓝蓟蓠蓣蓥蓦蔷蔹蔺蔼蕲蕴薮藁藓虏虑虚虫虬虮虽虾虿蚀蚁蚂蚕蚝蚬蛊蛎蛏蛮蛰蛱蛲蛳蛴蜕蜗蜡蝇蝈蝉蝎蝼蝾螀螨蟏衅衔补衬衮袄袅袆袜袭袯装裆裈裢裣裤裥褛褴襁襕见观觃规觅视觇览觉觊觋觌觍觎觏觐觑觞触觯詟誉誊讠计订讣认讥讦讧讨让讪讫训议讯记讱讲讳讴讵讶讷许讹论讻讼讽设访诀证诂诃评诅识诇诈诉诊诋诌词诎诏诐译诒诓诔试诖诗诘诙诚诛诜话诞诟诠诡询诣诤该详诧诨诩诪诫诬语诮误诰诱诲诳说诵诶请诸诹诺读诼诽课诿谀谁谂调谄谅谆谇谈谊谋谌谍谎谏谐谑谒谓谔谕谖谗谘谙谚谛谜谝谞谟谠谡谢谣谤谥谦谧谨谩谪谫谬谭谮谯谰谱谲谳谴谵谶谷豮贝贞负贠贡财责贤败账货质贩贪贫贬购贮贯贰贱贲贳贴贵贶贷贸费贺贻贼贽贾贿赀赁赂赃资赅赆赇赈赉赊赋赌赍赎赏赐赑赒赓赔赕赖赗赘赙赚赛赜赝赞赟赠赡赢赣赪赵赶趋趱趸跃跄跖跞践跶跷跸跹跻踊踌踪踬踯蹑蹒蹰蹿躏躜躯车轧轨轩轪轫转轭轮软轰轱轲轳轴轵轶轷轸轹轺轻轼载轾轿辀辁辂较辄辅辆辇辈辉辊辋辌辍辎辏辐辑辒输辔辕辖辗辘辙辚辞辩辫边辽达迁过迈运还这进远违连迟迩迳迹适选逊递逦逻遗遥邓邝邬邮邹邺邻郁郄郏郐郑郓郦郧郸酝酦酱酽酾酿释里鉅鉴銮錾钆钇针钉钊钋钌钍钎钏钐钑钒钓钔钕钖钗钘钙钚钛钝钞钟钠钡钢钣钤钥钦钧钨钩钪钫钬钭钮钯钰钱钲钳钴钵钶钷钸钹钺钻钼钽钾钿铀铁铂铃铄铅铆铈铉铊铋铍铎铏铐铑铒铕铗铘铙铚铛铜铝铞铟铠铡铢铣铤铥铦铧铨铪铫铬铭铮铯铰铱铲铳铴铵银铷铸铹铺铻铼铽链铿销锁锂锃锄锅锆锇锈锉锊锋锌锍锎锏锐锑锒锓锔锕锖锗错锚锜锞锟锠锡锢锣锤锥锦锨锩锫锬锭键锯锰锱锲锳锴锵锶锷锸锹锺锻锼锽锾锿镀镁镂镃镆镇镈镉镊镌镍镎镏镐镑镒镕镖镗镙镚镛镜镝镞镟镠镡镢镣镤镥镦镧镨镩镪镫镬镭镮镯镰镱镲镳镴镶长门闩闪闫闬闭问闯闰闱闲闳间闵闶闷闸闹闺闻闼闽闾闿阀阁阂阃阄阅阆阇阈阉阊阋阌阍阎阏阐阑阒阓阔阕阖阗阘阙阚阛队阳阴阵阶际陆陇陈陉陕陧陨险随隐隶隽难雏雠雳雾霁霉霭靓静靥鞑鞒鞯鞴韦韧韨韩韪韫韬韵页顶顷顸项顺须顼顽顾顿颀颁颂颃预颅领颇颈颉颊颋颌颍颎颏颐频颒颓颔颕颖颗题颙颚颛颜额颞颟颠颡颢颣颤颥颦颧风飏飐飑飒飓飔飕飖飗飘飙飚飞飨餍饤饥饦饧饨饩饪饫饬饭饮饯饰饱饲饳饴饵饶饷饸饹饺饻饼饽饾饿馀馁馂馃馄馅馆馇馈馉馊馋馌馍馎馏馐馑馒馓馔馕马驭驮驯驰驱驲驳驴驵驶驷驸驹驺驻驼驽驾驿骀骁骂骃骄骅骆骇骈骉骊骋验骍骎骏骐骑骒骓骔骕骖骗骘骙骚骛骜骝骞骟骠骡骢骣骤骥骦骧髅髋髌鬓魇魉鱼鱽鱾鱿鲀鲁鲂鲄鲅鲆鲇鲈鲉鲊鲋鲌鲍鲎鲏鲐鲑鲒鲓鲔鲕鲖鲗鲘鲙鲚鲛鲜鲝鲞鲟鲠鲡鲢鲣鲤鲥鲦鲧鲨鲩鲪鲫鲬鲭鲮鲯鲰鲱鲲鲳鲴鲵鲶鲷鲸鲹鲺鲻鲼鲽鲾鲿鳀鳁鳂鳃鳄鳅鳆鳇鳈鳉鳊鳋鳌鳍鳎鳏鳐鳑鳒鳓鳔鳕鳖鳗鳘鳙鳛鳜鳝鳞鳟鳠鳡鳢鳣鸟鸠鸡鸢鸣鸤鸥鸦鸧鸨鸩鸪鸫鸬鸭鸮鸯鸰鸱鸲鸳鸴鸵鸶鸷鸸鸹鸺鸻鸼鸽鸾鸿鹀鹁鹂鹃鹄鹅鹆鹇鹈鹉鹊鹋鹌鹍鹎鹏鹐鹑鹒鹓鹔鹕鹖鹗鹘鹚鹛鹜鹝鹞鹟鹠鹡鹢鹣鹤鹥鹦鹧鹨鹩鹪鹫鹬鹭鹯鹰鹱鹲鹳鹴鹾麦麸黄黉黡黩黪黾鼋鼌鼍鼗鼹齄齐齑齿龀龁龂龃龄龅龆龇龈龉龊龋龌龙龚龛龟志制咨只里系范松没尝尝闹面准钟别闲干尽脏拼"
+TRADITION = "萬與醜專業叢東絲丟兩嚴喪個爿豐臨為麗舉麼義烏樂喬習鄉書買亂爭於虧雲亙亞產畝親褻嚲億僅從侖倉儀們價眾優夥會傴傘偉傳傷倀倫傖偽佇體餘傭僉俠侶僥偵側僑儈儕儂俁儔儼倆儷儉債傾傯僂僨償儻儐儲儺兒兌兗黨蘭關興茲養獸囅內岡冊寫軍農塚馮衝決況凍淨淒涼淩減湊凜幾鳳鳧憑凱擊氹鑿芻劃劉則剛創刪別剗剄劊劌剴劑剮劍剝劇勸辦務勱動勵勁勞勢勳猛勩勻匭匱區醫華協單賣盧鹵臥衛卻巹廠廳曆厲壓厭厙廁廂厴廈廚廄廝縣參靉靆雙發變敘疊葉號歎嘰籲後嚇呂嗎唚噸聽啟吳嘸囈嘔嚦唄員咼嗆嗚詠哢嚨嚀噝吒噅鹹呱響啞噠嘵嗶噦嘩噲嚌噥喲嘜嗊嘮啢嗩唕喚呼嘖嗇囀齧囉嘽嘯噴嘍嚳囁嗬噯噓嚶囑嚕劈囂謔團園囪圍圇國圖圓聖壙場阪壞塊堅壇壢壩塢墳墜壟壟壚壘墾坰堊墊埡墶壋塏堖塒塤堝墊垵塹墮壪牆壯聲殼壺壼處備復夠頭誇夾奪奩奐奮獎奧妝婦媽嫵嫗媯姍薑婁婭嬈嬌孌娛媧嫻嫿嬰嬋嬸媼嬡嬪嬙嬤孫學孿寧寶實寵審憲宮寬賓寢對尋導壽將爾塵堯尷屍盡層屭屜屆屬屢屨嶼歲豈嶇崗峴嶴嵐島嶺嶽崠巋嶨嶧峽嶢嶠崢巒嶗崍嶮嶄嶸嶔崳嶁脊巔鞏巰幣帥師幃帳簾幟帶幀幫幬幘幗冪襆幹並廣莊慶廬廡庫應廟龐廢廎廩開異棄張彌弳彎彈強歸當錄彠彥徹徑徠禦憶懺憂愾懷態慫憮慪悵愴憐總懟懌戀懇惡慟懨愷惻惱惲悅愨懸慳憫驚懼慘懲憊愜慚憚慣湣慍憤憒願懾憖怵懣懶懍戇戔戲戧戰戩戶紮撲扡執擴捫掃揚擾撫拋摶摳掄搶護報擔擬攏揀擁攔擰撥擇掛摯攣掗撾撻挾撓擋撟掙擠揮撏撈損撿換搗據撚擄摑擲撣摻摜摣攬撳攙擱摟攪攜攝攄擺搖擯攤攖撐攆擷擼攛擻攢敵斂數齋斕鬥斬斷無舊時曠暘曇晝曨顯晉曬曉曄暈暉暫曖劄術樸機殺雜權條來楊榪傑極構樅樞棗櫪梘棖槍楓梟櫃檸檉梔柵標棧櫛櫳棟櫨櫟欄樹棲樣欒棬椏橈楨檔榿橋樺檜槳樁夢檮棶檢欞槨櫝槧欏橢樓欖櫬櫚櫸檟檻檳櫧橫檣櫻櫫櫥櫓櫞簷檁歡歟歐殲歿殤殘殞殮殫殯毆毀轂畢斃氈毿氌氣氫氬氳彙漢汙湯洶遝溝沒灃漚瀝淪滄渢溈滬濔濘淚澩瀧瀘濼瀉潑澤涇潔灑窪浹淺漿澆湞溮濁測澮濟瀏滻渾滸濃潯濜塗湧濤澇淶漣潿渦溳渙滌潤澗漲澀澱淵淥漬瀆漸澠漁瀋滲溫遊灣濕潰濺漵漊潷滾滯灩灄滿瀅濾濫灤濱灘澦濫瀠瀟瀲濰潛瀦瀾瀨瀕灝滅燈靈災燦煬爐燉煒熗點煉熾爍爛烴燭煙煩燒燁燴燙燼熱煥燜燾煆糊溜愛爺牘犛牽犧犢強狀獷獁猶狽麅獮獰獨狹獅獪猙獄猻獫獵獼玀豬貓蝟獻獺璣璵瑒瑪瑋環現瑲璽瑉玨琺瓏璫琿璡璉瑣瓊瑤璦璿瓔瓚甕甌電畫暢佘疇癤療瘧癘瘍鬁瘡瘋皰屙癰痙癢瘂癆瘓癇癡癉瘮瘞瘺癟癱癮癭癩癬癲臒皚皺皸盞鹽監蓋盜盤瞘眥矓著睜睞瞼瞞矚矯磯礬礦碭碼磚硨硯碸礪礱礫礎硜矽碩硤磽磑礄確鹼礙磧磣堿镟滾禮禕禰禎禱禍稟祿禪離禿稈種積稱穢穠穭稅穌穩穡窮竊竅窯竄窩窺竇窶豎競篤筍筆筧箋籠籩築篳篩簹箏籌簽簡籙簀篋籜籮簞簫簣簍籃籬籪籟糴類秈糶糲粵糞糧糝餱緊縶糸糾紆紅紂纖紇約級紈纊紀紉緯紜紘純紕紗綱納紝縱綸紛紙紋紡紵紖紐紓線紺絏紱練組紳細織終縐絆紼絀紹繹經紿綁絨結絝繞絰絎繪給絢絳絡絕絞統綆綃絹繡綌綏絛繼綈績緒綾緓續綺緋綽緔緄繩維綿綬繃綢綯綹綣綜綻綰綠綴緇緙緗緘緬纜緹緲緝縕繢緦綞緞緶線緱縋緩締縷編緡緣縉縛縟縝縫縗縞纏縭縊縑繽縹縵縲纓縮繆繅纈繚繕繒韁繾繰繯繳纘罌網羅罰罷羆羈羥羨翹翽翬耮耬聳恥聶聾職聹聯聵聰肅腸膚膁腎腫脹脅膽勝朧腖臚脛膠脈膾髒臍腦膿臠腳脫腡臉臘醃膕齶膩靦膃騰臏臢輿艤艦艙艫艱豔艸藝節羋薌蕪蘆蓯葦藶莧萇蒼苧蘇檾蘋莖蘢蔦塋煢繭荊薦薘莢蕘蓽蕎薈薺蕩榮葷滎犖熒蕁藎蓀蔭蕒葒葤藥蒞蓧萊蓮蒔萵薟獲蕕瑩鶯蓴蘀蘿螢營縈蕭薩蔥蕆蕢蔣蔞藍薊蘺蕷鎣驀薔蘞藺藹蘄蘊藪槁蘚虜慮虛蟲虯蟣雖蝦蠆蝕蟻螞蠶蠔蜆蠱蠣蟶蠻蟄蛺蟯螄蠐蛻蝸蠟蠅蟈蟬蠍螻蠑螿蟎蠨釁銜補襯袞襖嫋褘襪襲襏裝襠褌褳襝褲襇褸襤繈襴見觀覎規覓視覘覽覺覬覡覿覥覦覯覲覷觴觸觶讋譽謄訁計訂訃認譏訐訌討讓訕訖訓議訊記訒講諱謳詎訝訥許訛論訩訟諷設訪訣證詁訶評詛識詗詐訴診詆謅詞詘詔詖譯詒誆誄試詿詩詰詼誠誅詵話誕詬詮詭詢詣諍該詳詫諢詡譸誡誣語誚誤誥誘誨誑說誦誒請諸諏諾讀諑誹課諉諛誰諗調諂諒諄誶談誼謀諶諜謊諫諧謔謁謂諤諭諼讒諮諳諺諦謎諞諝謨讜謖謝謠謗諡謙謐謹謾謫譾謬譚譖譙讕譜譎讞譴譫讖穀豶貝貞負貟貢財責賢敗賬貨質販貪貧貶購貯貫貳賤賁貰貼貴貺貸貿費賀貽賊贄賈賄貲賃賂贓資賅贐賕賑賚賒賦賭齎贖賞賜贔賙賡賠賧賴賵贅賻賺賽賾贗讚贇贈贍贏贛赬趙趕趨趲躉躍蹌蹠躒踐躂蹺蹕躚躋踴躊蹤躓躑躡蹣躕躥躪躦軀車軋軌軒軑軔轉軛輪軟轟軲軻轤軸軹軼軤軫轢軺輕軾載輊轎輈輇輅較輒輔輛輦輩輝輥輞輬輟輜輳輻輯轀輸轡轅轄輾轆轍轔辭辯辮邊遼達遷過邁運還這進遠違連遲邇逕跡適選遜遞邐邏遺遙鄧鄺鄔郵鄒鄴鄰鬱郤郟鄶鄭鄆酈鄖鄲醞醱醬釅釃釀釋裏钜鑒鑾鏨釓釔針釘釗釙釕釷釺釧釤鈒釩釣鍆釹鍚釵鈃鈣鈈鈦鈍鈔鍾鈉鋇鋼鈑鈐鑰欽鈞鎢鉤鈧鈁鈥鈄鈕鈀鈺錢鉦鉗鈷缽鈳鉕鈽鈸鉞鑽鉬鉭鉀鈿鈾鐵鉑鈴鑠鉛鉚鈰鉉鉈鉍鈹鐸鉶銬銠鉺銪鋏鋣鐃銍鐺銅鋁銱銦鎧鍘銖銑鋌銩銛鏵銓鉿銚鉻銘錚銫鉸銥鏟銃鐋銨銀銣鑄鐒鋪鋙錸鋱鏈鏗銷鎖鋰鋥鋤鍋鋯鋨鏽銼鋝鋒鋅鋶鐦鐧銳銻鋃鋟鋦錒錆鍺錯錨錡錁錕錩錫錮鑼錘錐錦鍁錈錇錟錠鍵鋸錳錙鍥鍈鍇鏘鍶鍔鍤鍬鍾鍛鎪鍠鍰鎄鍍鎂鏤鎡鏌鎮鎛鎘鑷鐫鎳鎿鎦鎬鎊鎰鎔鏢鏜鏍鏰鏞鏡鏑鏃鏇鏐鐔钁鐐鏷鑥鐓鑭鐠鑹鏹鐙鑊鐳鐶鐲鐮鐿鑔鑣鑞鑲長門閂閃閆閈閉問闖閏闈閑閎間閔閌悶閘鬧閨聞闥閩閭闓閥閣閡閫鬮閱閬闍閾閹閶鬩閿閽閻閼闡闌闃闠闊闋闔闐闒闕闞闤隊陽陰陣階際陸隴陳陘陝隉隕險隨隱隸雋難雛讎靂霧霽黴靄靚靜靨韃鞽韉韝韋韌韍韓韙韞韜韻頁頂頃頇項順須頊頑顧頓頎頒頌頏預顱領頗頸頡頰頲頜潁熲頦頤頻頮頹頷頴穎顆題顒顎顓顏額顳顢顛顙顥纇顫顬顰顴風颺颭颮颯颶颸颼颻飀飄飆飆飛饗饜飣饑飥餳飩餼飪飫飭飯飲餞飾飽飼飿飴餌饒餉餄餎餃餏餅餑餖餓餘餒餕餜餛餡館餷饋餶餿饞饁饃餺餾饈饉饅饊饌饢馬馭馱馴馳驅馹駁驢駔駛駟駙駒騶駐駝駑駕驛駘驍罵駰驕驊駱駭駢驫驪騁驗騂駸駿騏騎騍騅騌驌驂騙騭騤騷騖驁騮騫騸驃騾驄驏驟驥驦驤髏髖髕鬢魘魎魚魛魢魷魨魯魴魺鮁鮃鯰鱸鮋鮓鮒鮊鮑鱟鮍鮐鮭鮚鮳鮪鮞鮦鰂鮜鱠鱭鮫鮮鮺鯗鱘鯁鱺鰱鰹鯉鰣鰷鯀鯊鯇鮶鯽鯒鯖鯪鯕鯫鯡鯤鯧鯝鯢鯰鯛鯨鯵鯴鯔鱝鰈鰏鱨鯷鰮鰃鰓鱷鰍鰒鰉鰁鱂鯿鰠鼇鰭鰨鰥鰩鰟鰜鰳鰾鱈鱉鰻鰵鱅鰼鱖鱔鱗鱒鱯鱤鱧鱣鳥鳩雞鳶鳴鳲鷗鴉鶬鴇鴆鴣鶇鸕鴨鴞鴦鴒鴟鴝鴛鴬鴕鷥鷙鴯鴰鵂鴴鵃鴿鸞鴻鵐鵓鸝鵑鵠鵝鵒鷳鵜鵡鵲鶓鵪鶤鵯鵬鵮鶉鶊鵷鷫鶘鶡鶚鶻鶿鶥鶩鷊鷂鶲鶹鶺鷁鶼鶴鷖鸚鷓鷚鷯鷦鷲鷸鷺鸇鷹鸌鸏鸛鸘鹺麥麩黃黌黶黷黲黽黿鼂鼉鞀鼴齇齊齏齒齔齕齗齟齡齙齠齜齦齬齪齲齷龍龔龕龜誌製谘隻裡係範鬆冇嚐嘗鬨麵準鐘彆閒乾儘臟拚"
+
+
+def toTraditionString(msg: str) -> str:
+ '''
+ 简体转繁体。
+
+ :return: str
+ '''
+ output_str_list = []
+ str_len = len(msg)
+
+ for i in range(str_len):
+ found_index = SIMPLE.find(msg[i])
+
+ if not (found_index == -1):
+ output_str_list.append(TRADITION[found_index])
+
+ else:
+ output_str_list.append(msg[i])
+
+ return "".join(output_str_list)
+
+
+def toSimpleString(msg: str) -> str:
+ '''
+ 繁体转简体。
+
+ :return: str
+ '''
+ output_str_list = []
+ str_len = len(msg)
+
+ for i in range(str_len):
+ found_index = TRADITION.find(msg[i])
+
+ if not (found_index == -1):
+ output_str_list.append(SIMPLE[found_index])
+
+ else:
+ output_str_list.append(msg[i])
+
+ return "".join(output_str_list)
diff --git a/ATRI/utils/utils_yml/__init__.py b/ATRI/utils/utils_yml/__init__.py
new file mode 100644
index 0000000..2617a21
--- /dev/null
+++ b/ATRI/utils/utils_yml/__init__.py
@@ -0,0 +1,25 @@
+#!/usr/bin/env python3
+# -*- encoding: utf-8 -*-
+'''
+@File : __init__.py
+@Time : 2020/11/06 22:26:06
+@Author : Kyomotoi
+@Contact : kyomotoiowo@gmail.com
+@Github : https://github.com/Kyomotoi
+@License : Copyright © 2018-2020 Kyomotoi, All Rights Reserved.
+'''
+__author__ = 'kyomotoi'
+
+import yaml
+from pathlib import Path
+
+
+def load_yaml(file: Path) -> dict:
+ '''
+ 读取yaml文件
+
+ :return: dict
+ '''
+ with open(file, 'r', encoding='utf-8') as f:
+ data = yaml.safe_load(f)
+ return data
diff --git a/LICENSE b/LICENSE
deleted file mode 100644
index eb02016..0000000
--- a/LICENSE
+++ /dev/null
@@ -1,219 +0,0 @@
-GNU GENERAL PUBLIC LICENSE
-Version 3, 29 June 2007
-
-Copyright © 2007 Free Software Foundation, Inc.
-
-Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed.
-
-Preamble
-The GNU General Public License is a free, copyleft license for software and other kinds of works.
-
-The licenses for most software and other practical works are designed to take away your freedom to share and change the works. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change all versions of a program--to make sure it remains free software for all its users. We, the Free Software Foundation, use the GNU General Public License for most of our software; it applies also to any other work released this way by its authors. You can apply it to your programs, too.
-
-When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for them if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs, and that you know you can do these things.
-
-To protect your rights, we need to prevent others from denying you these rights or asking you to surrender the rights. Therefore, you have certain responsibilities if you distribute copies of the software, or if you modify it: responsibilities to respect the freedom of others.
-
-For example, if you distribute copies of such a program, whether gratis or for a fee, you must pass on to the recipients the same freedoms that you received. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights.
-
-Developers that use the GNU GPL protect your rights with two steps: (1) assert copyright on the software, and (2) offer you this License giving you legal permission to copy, distribute and/or modify it.
-
-For the developers' and authors' protection, the GPL clearly explains that there is no warranty for this free software. For both users' and authors' sake, the GPL requires that modified versions be marked as changed, so that their problems will not be attributed erroneously to authors of previous versions.
-
-Some devices are designed to deny users access to install or run modified versions of the software inside them, although the manufacturer can do so. This is fundamentally incompatible with the aim of protecting users' freedom to change the software. The systematic pattern of such abuse occurs in the area of products for individuals to use, which is precisely where it is most unacceptable. Therefore, we have designed this version of the GPL to prohibit the practice for those products. If such problems arise substantially in other domains, we stand ready to extend this provision to those domains in future versions of the GPL, as needed to protect the freedom of users.
-
-Finally, every program is threatened constantly by software patents. States should not allow patents to restrict development and use of software on general-purpose computers, but in those that do, we wish to avoid the special danger that patents applied to a free program could make it effectively proprietary. To prevent this, the GPL assures that patents cannot be used to render the program non-free.
-
-The precise terms and conditions for copying, distribution and modification follow.
-
-TERMS AND CONDITIONS
-0. Definitions.
-“This License” refers to version 3 of the GNU General Public License.
-
-“Copyright” also means copyright-like laws that apply to other kinds of works, such as semiconductor masks.
-
-“The Program” refers to any copyrightable work licensed under this License. Each licensee is addressed as “you”. “Licensees” and “recipients” may be individuals or organizations.
-
-To “modify” a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission, other than the making of an exact copy. The resulting work is called a “modified version” of the earlier work or a work “based on” the earlier work.
-
-A “covered work” means either the unmodified Program or a work based on the Program.
-
-To “propagate” a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy. Propagation includes copying, distribution (with or without modification), making available to the public, and in some countries other activities as well.
-
-To “convey” a work means any kind of propagation that enables other parties to make or receive copies. Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying.
-
-An interactive user interface displays “Appropriate Legal Notices” to the extent that it includes a convenient and prominently visible feature that (1) displays an appropriate copyright notice, and (2) tells the user that there is no warranty for the work (except to the extent that warranties are provided), that licensees may convey the work under this License, and how to view a copy of this License. If the interface presents a list of user commands or options, such as a menu, a prominent item in the list meets this criterion.
-
-1. Source Code.
-The “source code” for a work means the preferred form of the work for making modifications to it. “Object code” means any non-source form of a work.
-
-A “Standard Interface” means an interface that either is an official standard defined by a recognized standards body, or, in the case of interfaces specified for a particular programming language, one that is widely used among developers working in that language.
-
-The “System Libraries” of an executable work include anything, other than the work as a whole, that (a) is included in the normal form of packaging a Major Component, but which is not part of that Major Component, and (b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an implementation is available to the public in source code form. A “Major Component”, in this context, means a major essential component (kernel, window system, and so on) of the specific operating system (if any) on which the executable work runs, or a compiler used to produce the work, or an object code interpreter used to run it.
-
-The “Corresponding Source” for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to control those activities. However, it does not include the work's System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work. For example, Corresponding Source includes interface definition files associated with source files for the work, and the source code for shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work.
-
-The Corresponding Source need not include anything that users can regenerate automatically from other parts of the Corresponding Source.
-
-The Corresponding Source for a work in source code form is that same work.
-
-2. Basic Permissions.
-All rights granted under this License are granted for the term of copyright on the Program, and are irrevocable provided the stated conditions are met. This License explicitly affirms your unlimited permission to run the unmodified Program. The output from running a covered work is covered by this License only if the output, given its content, constitutes a covered work. This License acknowledges your rights of fair use or other equivalent, as provided by copyright law.
-
-You may make, run and propagate covered works that you do not convey, without conditions so long as your license otherwise remains in force. You may convey covered works to others for the sole purpose of having them make modifications exclusively for you, or provide you with facilities for running those works, provided that you comply with the terms of this License in conveying all material for which you do not control copyright. Those thus making or running the covered works for you must do so exclusively on your behalf, under your direction and control, on terms that prohibit them from making any copies of your copyrighted material outside their relationship with you.
-
-Conveying under any other circumstances is permitted solely under the conditions stated below. Sublicensing is not allowed; section 10 makes it unnecessary.
-
-3. Protecting Users' Legal Rights From Anti-Circumvention Law.
-No covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obligations under article 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention of such measures.
-
-When you convey a covered work, you waive any legal power to forbid circumvention of technological measures to the extent such circumvention is effected by exercising rights under this License with respect to the covered work, and you disclaim any intention to limit operation or modification of the work as a means of enforcing, against the work's users, your or third parties' legal rights to forbid circumvention of technological measures.
-
-4. Conveying Verbatim Copies.
-You may convey verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice; keep intact all notices stating that this License and any non-permissive terms added in accord with section 7 apply to the code; keep intact all notices of the absence of any warranty; and give all recipients a copy of this License along with the Program.
-
-You may charge any price or no price for each copy that you convey, and you may offer support or warranty protection for a fee.
-
-5. Conveying Modified Source Versions.
-You may convey a work based on the Program, or the modifications to produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions:
-
-a) The work must carry prominent notices stating that you modified it, and giving a relevant date.
-b) The work must carry prominent notices stating that it is released under this License and any conditions added under section 7. This requirement modifies the requirement in section 4 to “keep intact all notices”.
-c) You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy. This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged. This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it.
-d) If the work has interactive user interfaces, each must display Appropriate Legal Notices; however, if the Program has interactive interfaces that do not display Appropriate Legal Notices, your work need not make them do so.
-A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an “aggregate” if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation's users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate.
-
-6. Conveying Non-Source Forms.
-You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways:
-
-a) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by the Corresponding Source fixed on a durable physical medium customarily used for software interchange.
-b) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by a written offer, valid for at least three years and valid for as long as you offer spare parts or customer support for that product model, to give anyone who possesses the object code either (1) a copy of the Corresponding Source for all the software in the product that is covered by this License, on a durable physical medium customarily used for software interchange, for a price no more than your reasonable cost of physically performing this conveying of source, or (2) access to copy the Corresponding Source from a network server at no charge.
-c) Convey individual copies of the object code with a copy of the written offer to provide the Corresponding Source. This alternative is allowed only occasionally and noncommercially, and only if you received the object code with such an offer, in accord with subsection 6b.
-d) Convey the object code by offering access from a designated place (gratis or for a charge), and offer equivalent access to the Corresponding Source in the same way through the same place at no further charge. You need not require recipients to copy the Corresponding Source along with the object code. If the place to copy the object code is a network server, the Corresponding Source may be on a different server (operated by you or a third party) that supports equivalent copying facilities, provided you maintain clear directions next to the object code saying where to find the Corresponding Source. Regardless of what server hosts the Corresponding Source, you remain obligated to ensure that it is available for as long as needed to satisfy these requirements.
-e) Convey the object code using peer-to-peer transmission, provided you inform other peers where the object code and Corresponding Source of the work are being offered to the general public at no charge under subsection 6d.
-A separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be included in conveying the object code work.
-
-A “User Product” is either (1) a “consumer product”, which means any tangible personal property which is normally used for personal, family, or household purposes, or (2) anything designed or sold for incorporation into a dwelling. In determining whether a product is a consumer product, doubtful cases shall be resolved in favor of coverage. For a particular product received by a particular user, “normally used” refers to a typical or common use of that class of product, regardless of the status of the particular user or of the way in which the particular user actually uses, or expects or is expected to use, the product. A product is a consumer product regardless of whether the product has substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of use of the product.
-
-“Installation Information” for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from a modified version of its Corresponding Source. The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made.
-
-If you convey an object code work under this section in, or with, or specifically for use in, a User Product, and the conveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred to the recipient in perpetuity or for a fixed term (regardless of how the transaction is characterized), the Corresponding Source conveyed under this section must be accompanied by the Installation Information. But this requirement does not apply if neither you nor any third party retains the ability to install modified object code on the User Product (for example, the work has been installed in ROM).
-
-The requirement to provide Installation Information does not include a requirement to continue to provide support service, warranty, or updates for a work that has been modified or installed by the recipient, or for the User Product in which it has been modified or installed. Access to a network may be denied when the modification itself materially and adversely affects the operation of the network or violates the rules and protocols for communication across the network.
-
-Corresponding Source conveyed, and Installation Information provided, in accord with this section must be in a format that is publicly documented (and with an implementation available to the public in source code form), and must require no special password or key for unpacking, reading or copying.
-
-7. Additional Terms.
-“Additional permissions” are terms that supplement the terms of this License by making exceptions from one or more of its conditions. Additional permissions that are applicable to the entire Program shall be treated as though they were included in this License, to the extent that they are valid under applicable law. If additional permissions apply only to part of the Program, that part may be used separately under those permissions, but the entire Program remains governed by this License without regard to the additional permissions.
-
-When you convey a copy of a covered work, you may at your option remove any additional permissions from that copy, or from any part of it. (Additional permissions may be written to require their own removal in certain cases when you modify the work.) You may place additional permissions on material, added by you to a covered work, for which you have or can give appropriate copyright permission.
-
-Notwithstanding any other provision of this License, for material you add to a covered work, you may (if authorized by the copyright holders of that material) supplement the terms of this License with terms:
-
-a) Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or
-b) Requiring preservation of specified reasonable legal notices or author attributions in that material or in the Appropriate Legal Notices displayed by works containing it; or
-c) Prohibiting misrepresentation of the origin of that material, or requiring that modified versions of such material be marked in reasonable ways as different from the original version; or
-d) Limiting the use for publicity purposes of names of licensors or authors of the material; or
-e) Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or
-f) Requiring indemnification of licensors and authors of that material by anyone who conveys the material (or modified versions of it) with contractual assumptions of liability to the recipient, for any liability that these contractual assumptions directly impose on those licensors and authors.
-All other non-permissive additional terms are considered “further restrictions” within the meaning of section 10. If the Program as you received it, or any part of it, contains a notice stating that it is governed by this License along with a term that is a further restriction, you may remove that term. If a license document contains a further restriction but permits relicensing or conveying under this License, you may add to a covered work material governed by the terms of that license document, provided that the further restriction does not survive such relicensing or conveying.
-
-If you add terms to a covered work in accord with this section, you must place, in the relevant source files, a statement of the additional terms that apply to those files, or a notice indicating where to find the applicable terms.
-
-Additional terms, permissive or non-permissive, may be stated in the form of a separately written license, or stated as exceptions; the above requirements apply either way.
-
-8. Termination.
-You may not propagate or modify a covered work except as expressly provided under this License. Any attempt otherwise to propagate or modify it is void, and will automatically terminate your rights under this License (including any patent licenses granted under the third paragraph of section 11).
-
-However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation.
-
-Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice.
-
-Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, you do not qualify to receive new licenses for the same material under section 10.
-
-9. Acceptance Not Required for Having Copies.
-You are not required to accept this License in order to receive or run a copy of the Program. Ancillary propagation of a covered work occurring solely as a consequence of using peer-to-peer transmission to receive a copy likewise does not require acceptance. However, nothing other than this License grants you permission to propagate or modify any covered work. These actions infringe copyright if you do not accept this License. Therefore, by modifying or propagating a covered work, you indicate your acceptance of this License to do so.
-
-10. Automatic Licensing of Downstream Recipients.
-Each time you convey a covered work, the recipient automatically receives a license from the original licensors, to run, modify and propagate that work, subject to this License. You are not responsible for enforcing compliance by third parties with this License.
-
-An “entity transaction” is a transaction transferring control of an organization, or substantially all assets of one, or subdividing an organization, or merging organizations. If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever licenses to the work the party's predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts.
-
-You may not impose any further restrictions on the exercise of the rights granted or affirmed under this License. For example, you may not impose a license fee, royalty, or other charge for exercise of rights granted under this License, and you may not initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patent claim is infringed by making, using, selling, offering for sale, or importing the Program or any portion of it.
-
-11. Patents.
-A “contributor” is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based. The work thus licensed is called the contributor's “contributor version”.
-
-A contributor's “essential patent claims” are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, but do not include claims that would be infringed only as a consequence of further modification of the contributor version. For purposes of this definition, “control” includes the right to grant patent sublicenses in a manner consistent with the requirements of this License.
-
-Each contributor grants you a non-exclusive, worldwide, royalty-free patent license under the contributor's essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version.
-
-In the following three paragraphs, a “patent license” is any express agreement or commitment, however denominated, not to enforce a patent (such as an express permission to practice a patent or covenant not to sue for patent infringement). To “grant” such a patent license to a party means to make such an agreement or commitment not to enforce a patent against the party.
-
-If you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the work is not available for anyone to copy, free of charge and under the terms of this License, through a publicly available network server or other readily accessible means, then you must either (1) cause the Corresponding Source to be so available, or (2) arrange to deprive yourself of the benefit of the patent license for this particular work, or (3) arrange, in a manner consistent with the requirements of this License, to extend the patent license to downstream recipients. “Knowingly relying” means you have actual knowledge that, but for the patent license, your conveying the covered work in a country, or your recipient's use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid.
-
-If, pursuant to or in connection with a single transaction or arrangement, you convey, or propagate by procuring conveyance of, a covered work, and grant a patent license to some of the parties receiving the covered work authorizing them to use, propagate, modify or convey a specific copy of the covered work, then the patent license you grant is automatically extended to all recipients of the covered work and works based on it.
-
-A patent license is “discriminatory” if it does not include within the scope of its coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or more of the rights that are specifically granted under this License. You may not convey a covered work if you are a party to an arrangement with a third party that is in the business of distributing software, under which you make payment to the third party based on the extent of your activity of conveying the work, and under which the third party grants, to any of the parties who would receive the covered work from you, a discriminatory patent license (a) in connection with copies of the covered work conveyed by you (or copies made from those copies), or (b) primarily for and in connection with specific products or compilations that contain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007.
-
-Nothing in this License shall be construed as excluding or limiting any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law.
-
-12. No Surrender of Others' Freedom.
-If conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot convey a covered work so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not convey it at all. For example, if you agree to terms that obligate you to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program.
-
-13. Use with the GNU Affero General Public License.
-Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed under version 3 of the GNU Affero General Public License into a single combined work, and to convey the resulting work. The terms of this License will continue to apply to the part which is the covered work, but the special requirements of the GNU Affero General Public License, section 13, concerning interaction through a network will apply to the combination as such.
-
-14. Revised Versions of this License.
-The Free Software Foundation may publish revised and/or new versions of the GNU General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns.
-
-Each version is given a distinguishing version number. If the Program specifies that a certain numbered version of the GNU General Public License “or any later version” applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the GNU General Public License, you may choose any version ever published by the Free Software Foundation.
-
-If the Program specifies that a proxy can decide which future versions of the GNU General Public License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Program.
-
-Later license versions may give you additional or different permissions. However, no additional obligations are imposed on any author or copyright holder as a result of your choosing to follow a later version.
-
-15. Disclaimer of Warranty.
-THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM “AS IS” WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
-
-16. Limitation of Liability.
-IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
-
-17. Interpretation of Sections 15 and 16.
-If the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect according to their terms, reviewing courts shall apply local law that most closely approximates an absolute waiver of all civil liability in connection with the Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee.
-
-END OF TERMS AND CONDITIONS
-
-How to Apply These Terms to Your New Programs
-If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms.
-
-To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively state the exclusion of warranty; and each file should have at least the “copyright” line and a pointer to where the full notice is found.
-
-
- Copyright (C)
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see .
-Also add information on how to contact you by electronic and paper mail.
-
-If the program does terminal interaction, make it output a short notice like this when it starts in an interactive mode:
-
- Copyright (C)
- This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
- This is free software, and you are welcome to redistribute it
- under certain conditions; type `show c' for details.
-The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, your program's commands might be different; for a GUI interface, you would use an “about box”.
-
-You should also get your employer (if you work as a programmer) or school, if any, to sign a “copyright disclaimer” for the program, if necessary. For more information on this, and how to apply and follow the GNU GPL, see .
-
-The GNU General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. But first, please read .
diff --git a/bot.py b/bot.py
index 8a42b0a..ab24c74 100644
--- a/bot.py
+++ b/bot.py
@@ -1,74 +1,10 @@
#!/usr/bin/env python3
# -*- encoding: utf-8 -*-
-'''
-@File : bot.py
-@Time : 2020/10/11 14:36:01
-@Author : Kyomotoi
-@Contact : kyomotoiowo@gmail.com
-@Github : https://github.com/Kyomotoi
-@License : Copyright © 2018-2020 Kyomotoi, All Rights Reserved.
-'''
-__author__ = 'kyomotoi'
-import time
-import nonebot
-import datetime
-from pathlib import Path
-from utils.utils_yml import load_yaml
-from nonebot.log import default_format, logger
+import ATRI
-from check import checkATRI
-
-# 版权说明
-COPYRIGHT = (r"""====================[ATRI | アトリ]====================
-* Mirai + NoneBot2 + Python
-* Copyright © 2018-2020 Kyomotoi,All Rights Reserved
-* Project: https://github.com/Kyomotoi/ATRI
-* Blog: blog.lolihub.icu
-=======================================================""")
-print(COPYRIGHT)
-time.sleep(1)
-
-# 检查是否符合条件运行
-checkATRI()
-
-# 读取配置
-CONFIG_PATH = Path('.') / 'config.yml'
-config = load_yaml(CONFIG_PATH)
-config = config['bot']
-
-# 初始化
-nonebot.init(debug=bool(config['debug']),
- superusers=set(config['superusers']),
- nickname=set(config['nickname']),
- command_start=set(config['command_start']),
- command_sep=set(config['command_sep']))
-app = nonebot.get_asgi()
-
-# 读取插件目录
-nonebot.load_plugins('ATRI/plugins')
-
-# 自定义 Logger
-LOGGER_INFO_PATH = Path(
- '.'
-) / 'logs' / 'info' / f"{datetime.datetime.now().strftime('%Y%m%d-%H%M%S')}-INFO.log"
-LOGGER_ERROR_PATH = Path(
- '.'
-) / 'logs' / 'error' / f"{datetime.datetime.now().strftime('%Y%m%d-%H%M%S')}-ERROR.log"
-
-# 记录正常日志
-logger.add(LOGGER_INFO_PATH,
- rotation='10 MB',
- diagnose=False,
- level='INFO',
- format=default_format)
-
-# 记录报错日志
-logger.add(LOGGER_ERROR_PATH,
- rotation='10 MB',
- diagnose=False,
- level='ERROR',
- format=default_format)
+bot = ATRI.Service()
if __name__ == '__main__':
- nonebot.run(app='bot:app', host=config['host'], port=config['port'])
+ bot.init()
+ bot.run()
diff --git a/check.py b/check.py
deleted file mode 100644
index a1d4960..0000000
--- a/check.py
+++ /dev/null
@@ -1,77 +0,0 @@
-#!/usr/bin/env python3
-# -*- encoding: utf-8 -*-
-'''
-@File : check.py
-@Time : 2020/11/07 14:30:34
-@Author : Kyomotoi
-@Contact : kyomotoiowo@gmail.com
-@Github : https://github.com/Kyomotoi
-@License : Copyright © 2018-2020 Kyomotoi, All Rights Reserved.
-'''
-__author__ = 'kyomotoi'
-
-import sys
-import time
-from pathlib import Path
-from nonebot.log import logger
-from rich.progress import Progress
-
-from utils.utils_yml import load_yaml
-
-CONFIG_PATH = Path('.') / 'config.yml'
-config = load_yaml(CONFIG_PATH)
-
-
-class checkATRI():
- """运行前检查必要条件"""
- logger.info('Checking Config...')
-
- def __init__(self) -> None:
- """检查配置文件是否填写完整"""
- len_config = len(config) + len(config['bot']) + len(
- config['api']) + len(config['html'])
-
- with Progress() as progress:
-
- task = progress.add_task("[cyan]Checking Config...",
- total=len_config)
-
- while not progress.finished:
-
- # 检查基本配置
- bot = config['bot']
- for key in bot:
- if key == 'debug':
- if bot['debug'] != 0:
- logger.warning('DEBUG open.')
- progress.update(task, advance=1)
- time.sleep(0.2)
- else:
- if not bot[key]:
- logger.warning(
- f"Can't load [{key}] from config.yml")
- sys.exit(0)
-
- else:
- progress.update(task, advance=1)
- time.sleep(0.2)
-
- # 检查接口配置
- api = config['api']
- for key in api:
- if not api[key]:
- logger.warning(f"Can't load [{key}] from config.yml")
- sys.exit(0)
- else:
- progress.update(task, advance=1)
- time.sleep(0.2)
-
- # 检查网页配置
- html = config['html']
- for key in html:
- if not html[key]:
- logger.warning(f"Can't load [{key}] from config.yml")
- sys.exit(0)
- else:
- progress.update(task, advance=1)
- time.sleep(0.2)
diff --git a/config.yml b/config.yml
index 293f5f7..df9d3f6 100644
--- a/config.yml
+++ b/config.yml
@@ -5,25 +5,22 @@ bot:
# 反向ws端口
port: 8080
# 非开发者无需理会
- debug: false
+ debug: 0
# 超级用户,填自己的QQ号,用“,”隔开
- superusers: [""]
+ superusers: []
# 机器人昵称,建议不动
- nickname: ["ATRI", "Atri", "atri", "亚托莉", "アトリ"]
+ nickname: ['ATRI', 'Atri', 'atri', '亚托莉', 'アトリ']
# 命令触发头,建议不动,除非你知道你在做什么
command_start: ['', '/']
# 命令分离,建议不动,除非你知道你在做什么
- command_sep: ["."]
+ command_sep: ['.']
# 接口相关配置
api:
# 涩图接口,URL:https://api.lolicon.app/#/setu
- LoliconAPI:
- # 换脸接口,URL:https://www.faceplusplus.com.cn/
- FaceplusAPI:
- FaceplusSECRET:
+ LoliconAPI: xxx
# 搜图接口,URL:https://saucenao.com/
- SauceNaoKEY:
+ SauceNaoKEY: xxx
# 内置网页端
html:
diff --git a/utils/utils_error/__init__.py b/utils/utils_error/__init__.py
deleted file mode 100644
index d033613..0000000
--- a/utils/utils_error/__init__.py
+++ /dev/null
@@ -1,54 +0,0 @@
-#!/usr/bin/env python3
-# -*- encoding: utf-8 -*-
-'''
-@File : __init__.py
-@Time : 2020/10/11 14:43:10
-@Author : Kyomotoi
-@Contact : kyomotoiowo@gmail.com
-@Github : https://github.com/Kyomotoi
-@License : Copyright © 2018-2020 Kyomotoi, All Rights Reserved.
-'''
-__author__ = 'kyomotoi'
-
-import json
-import string
-from pathlib import Path
-from random import sample
-from typing import Optional
-from datetime import datetime
-from traceback import format_exc
-
-
-def errorRepo(repo_msg: Optional[str] = None) -> str:
- '''
- 出错时返回错误堆栈
-
- :return: str
- '''
- file_error = Path('.') / 'ATRI' / 'data' / 'data_Error' / 'error.json'
- try:
- with open(file_error, 'r') as f:
- data_error = json.load(f)
- except FileNotFoundError:
- data_error = {}
-
- key_error = ''.join(sample(string.ascii_letters + string.digits, 16))
- msg_error = f"{datetime.now()}\n"
- msg_error = f"{format_exc()}"
- data_error[f"{key_error}"] = f"{msg_error}"
-
- with open(file_error, 'w') as f:
- f.write(json.dumps(data_error))
- f.close()
-
- if repo_msg:
- pass
- else:
- repo_msg = 'unknown'
-
- msg0 = f'ERROR! Reason: [{repo_msg}]\n'
- msg0 += f'trackID: {key_error}\n'
- msg0 += "请使用[来杯红茶]功能以联系维护者\n"
- msg0 += "并附上 trackID"
-
- return msg0
\ No newline at end of file
diff --git a/utils/utils_history/__init__.py b/utils/utils_history/__init__.py
deleted file mode 100644
index 4453e11..0000000
--- a/utils/utils_history/__init__.py
+++ /dev/null
@@ -1,108 +0,0 @@
-#!/usr/bin/env python3
-# -*- encoding: utf-8 -*-
-'''
-@File : __init__.py
-@Time : 2020/11/07 14:33:22
-@Author : Kyomotoi
-@Contact : kyomotoiowo@gmail.com
-@Github : https://github.com/Kyomotoi
-@License : Copyright © 2018-2020 Kyomotoi, All Rights Reserved.
-'''
-__author__ = 'kyomotoi'
-
-import os
-import json
-import datetime
-from pathlib import Path
-from typing import Optional
-
-
-def saveMessage(message_id: str,
- message: str,
- user: str,
- group: Optional[str] = None) -> None:
- """储存消息"""
- GROUP_PATH = Path(
- '.'
- ) / 'ATRI' / 'data' / 'data_Group' / f'{group}' / f"{datetime.datetime.now().strftime('%Y-%m-%d')}-message.json"
- PRIVATE_PATH = Path(
- '.'
- ) / 'ATRI' / 'data' / 'data_Private_Message' / f"{datetime.datetime.now().strftime('%Y-%m-%d')}-private-message.json"
-
- # 检查目标文件目录
- if not GROUP_PATH.is_file():
- try:
- os.mkdir(Path('.') / 'ATRI' / 'data' / 'data_Group' / f'{group}')
- except:
- pass
-
- with open(GROUP_PATH, 'w') as f:
- f.write(json.dumps({}))
-
- if not PRIVATE_PATH.is_file():
- try:
- os.mkdir(Path('.') / 'ATRI' / 'data' / 'data_Private_Message')
- except:
- pass
-
- with open(PRIVATE_PATH, 'w') as f:
- f.write(json.dumps({}))
-
- # 加载目标文件
- with open(GROUP_PATH, 'r') as f:
- DATA_GROUP = json.load(f)
-
- with open(PRIVATE_PATH, 'r') as f:
- DATA_PRIVATE = json.load(f)
-
- # 写入
- if group:
- DATA_GROUP[f"{message_id}"] = {
- "message": f"{message}",
- "user_id": f"{user}",
- "group_id": f"{group}"
- }
-
- with open(GROUP_PATH, 'w') as f:
- f.write(json.dumps(DATA_GROUP))
-
- else:
- DATA_PRIVATE[f"{message_id}"] = {
- "message": f"{message}",
- "user_id": f"{user}"
- }
-
- with open(PRIVATE_PATH, 'w') as f:
- f.write(json.dumps(DATA_PRIVATE))
-
-
-def getMessage(message_id: str, group: Optional[str] = None) -> dict:
- '''
- 传入消息id以获取对应信息
-
- :return: dict
- '''
- GROUP_PATH = Path(
- '.'
- ) / 'ATRI' / 'data' / 'data_Group' / f'{group}' / f"{datetime.datetime.now().strftime('%Y-%m-%d')}-message.json"
- PRIVATE_PATH = Path(
- '.'
- ) / 'ATRI' / 'data' / 'data_Private_Message' / f"{datetime.datetime.now().strftime('%Y-%m-%d')}-private-message.json"
-
- if group:
- try:
- with open(GROUP_PATH, 'r') as f:
- data_group = json.load(f)
- return data_group[message_id]
-
- except:
- return {"status": 0}
-
- else:
- try:
- with open(PRIVATE_PATH, 'r') as f:
- data_private = json.load(f)
- return data_private[message_id]
-
- except:
- return {"status": 0}
diff --git a/utils/utils_img/__init__.py b/utils/utils_img/__init__.py
deleted file mode 100644
index 7b79146..0000000
--- a/utils/utils_img/__init__.py
+++ /dev/null
@@ -1,62 +0,0 @@
-#!/usr/bin/env python3
-# -*- encoding: utf-8 -*-
-
-'''
-@File : __init__.py
-@Time : 2020/11/07 14:17:37
-@Author : Kyomotoi
-@Contact : kyomotoiowo@gmail.com
-@Github : https://github.com/Kyomotoi
-@License : Copyright © 2018-2020 Kyomotoi, All Rights Reserved.
-'''
-__author__ = 'kyomotoi'
-
-import os
-import string
-import aiohttp
-from pathlib import Path
-from random import sample
-
-import PIL.Image as Image
-from PIL import ImageFile
-
-async def aio_download_pics(url) -> str:
- '''
- 下载图片并重命名
-
- :return: img file
- '''
- path = Path('.') / 'ATRI' / 'data' / 'data_Temp' / 'img'
- path = os.path.abspath(path)
- img_key = ''.join(sample(string.ascii_letters + string.digits, 16))
- img = path + f'\\{img_key}.png'
- async with aiohttp.ClientSession() as session:
- async with session.get(url) as response:
- pic = await response.read() #以Bytes方式读入非文字
- with open(img, mode='wb') as f:# 写入文件
- f.write(pic)
- f.close()
- return img
-
-def compress_image(outfile: str, kb=400, quality=85, k=0.9) -> str:
- '''
- 压缩图片
-
- :return: img file
- '''
- o_size = os.path.getsize(outfile) // 1024
- if o_size <= kb:
- return outfile
-
- ImageFile.LOAD_TRUNCATED_IMAGES = True # type: ignore
- while o_size > kb:
- im = Image.open(outfile)
- x, y = im.size
- out = im.resize((int(x*k), int(y*k)), Image.ANTIALIAS)
- try:
- out.save(outfile, quality=quality)
- except Exception as e:
- print(e)
- break
- o_size = os.path.getsize(outfile) // 1024
- return outfile
diff --git a/utils/utils_request/__init__.py b/utils/utils_request/__init__.py
deleted file mode 100644
index fd235bf..0000000
--- a/utils/utils_request/__init__.py
+++ /dev/null
@@ -1,39 +0,0 @@
-#!/usr/bin/env python3
-# -*- encoding: utf-8 -*-
-'''
-@File : __init__.py
-@Time : 2020/10/11 14:43:55
-@Author : Kyomotoi
-@Contact : kyomotoiowo@gmail.com
-@Github : https://github.com/Kyomotoi
-@License : Copyright © 2018-2020 Kyomotoi, All Rights Reserved.
-'''
-__author__ = 'kyomotoi'
-
-import requests
-from typing import Optional
-from aiohttp import ClientSession
-
-def request_get(url: str, params: Optional[dict] = None) -> bytes:
- '''
- 通过 GET 方式请求 url。
-
- :return: bytes
- '''
- return requests.get(url, params).content
-
-def request_api_text(url: str) -> str:
- res = requests.request("GET", url)
- html = res.text
- return html
-
-async def aio_get_bytes(url: str, headers: Optional[dict] = None) -> bytes:
- '''
- 通过 GET 以 异步 方式请求 url。
-
- :return: bytes
- '''
- async with ClientSession() as asyncSession:
- async with asyncSession.get(url, headers=headers) as resp:
- result = await resp.read()
- return result
\ No newline at end of file
diff --git a/utils/utils_rule/__init__.py b/utils/utils_rule/__init__.py
deleted file mode 100644
index 1ec09db..0000000
--- a/utils/utils_rule/__init__.py
+++ /dev/null
@@ -1,143 +0,0 @@
-#!/usr/bin/env python3
-# -*- encoding: utf-8 -*-
-'''
-@File : __init__.py
-@Time : 2020/11/06 19:27:00
-@Author : Kyomotoi
-@Contact : kyomotoiowo@gmail.com
-@Github : https://github.com/Kyomotoi
-@License : Copyright © 2018-2020 Kyomotoi, All Rights Reserved.
-'''
-__author__ = 'kyomotoi'
-
-import os
-import json
-from pathlib import Path
-from nonebot.rule import Rule
-from nonebot.typing import Bot, Event
-
-
-def check_banlist() -> Rule:
- '''
- 检查目标是否存在于封禁名单
-
- :return: bool
- '''
- async def _chech_banlist(bot: Bot, event: Event, state: dict) -> bool:
- # 获取目标信息
- user = str(event.user_id)
- group = str(event.group_id)
-
- # 名单目录
- BAN_LIST_USER_PATH = Path(
- '.') / 'utils' / 'utils_rule' / 'ban_list_user.json'
- BAN_LIST_GROUP_PATH = Path(
- '.') / 'utils' / 'utils_rule' / 'ban_list_group.json'
-
- # 检查文件是否存在,如不存在,自动创建并写入默认值
- if not BAN_LIST_USER_PATH.is_file():
- with open(BAN_LIST_USER_PATH, 'w') as f:
- f.write(json.dumps({}))
-
- if not BAN_LIST_GROUP_PATH.is_file():
- with open(BAN_LIST_GROUP_PATH, 'w') as f:
- f.write(json.dumps({}))
-
- # 读取文件
- with open(BAN_LIST_USER_PATH, 'r') as f:
- data_user = json.load(f)
-
- with open(BAN_LIST_GROUP_PATH, 'r') as f:
- data_group = json.load(f)
-
- # 判断目标
- if user:
- if user not in data_user:
- if group:
- if group not in data_group:
- return True
- else:
- return False
- else:
- return True
- else:
- return False
-
- elif group:
- if group not in data_group:
- if user:
- if user not in data_user:
- return True
- else:
- return False
- else:
- return True
- else:
- return False
- else:
- return False
-
- return Rule(_chech_banlist)
-
-
-def check_switch(func_name: str) -> Rule:
- '''
- 检查目标功能是否开启
-
- :return: bool
- '''
- async def _check_switch(bot: Bot, event: Event, state: dict) -> bool:
- # 获取目标信息
- group = str(event.group_id)
-
- # 文件目录
- SWITCH_ALL_PATH = Path('.') / 'utils' / 'utils_rule' / 'switch.json'
- SWITCH_ALONE_PATH = Path(
- '.') / 'ATRI' / 'data' / 'data_Group' / f'{group}' / 'switch.json'
-
- # 检查文件是否存在,如不存在,自动创建并写入默认值
- if not SWITCH_ALL_PATH.is_file():
- with open(SWITCH_ALL_PATH, 'ws') as f:
- f.write(json.dumps({}))
-
- if not SWITCH_ALONE_PATH.is_file():
- try:
- os.mkdir(
- Path('.') / 'ATRI' / 'data' / 'data_Group' / f'{group}')
- except:
- pass
-
- with open(SWITCH_ALONE_PATH, 'w') as f:
- f.write(json.dumps({}))
-
- # 读取文件
- with open(SWITCH_ALL_PATH, 'r') as f:
- data_all = json.load(f)
-
- with open(SWITCH_ALONE_PATH, 'r') as f:
- data_alone = json.load(f)
-
- # 判断目标是否存在于将要读取的文件,如不存在,写入
- # 此项举措是为了适应以后版本更新出现新插件的状况
- # 不至于每次都需要修改
- if func_name not in data_all:
- data_all[func_name] = "True"
- with open(SWITCH_ALL_PATH, 'w') as f:
- f.write(json.dumps(data_all))
-
- if func_name not in data_alone:
- data_alone[func_name] = "True"
- with open(SWITCH_ALONE_PATH, 'w') as f:
- f.write(json.dumps(data_alone))
-
- # 判断目标
- if data_all[func_name] == "True":
- if data_alone[func_name] == "True":
- return True
- else:
- return False
- else:
- await bot.send(event, f"Service-{func_name} has been closed.")
- return False
-
- return Rule(_check_switch)
\ No newline at end of file
diff --git a/utils/utils_rule/ban_list_group.json b/utils/utils_rule/ban_list_group.json
deleted file mode 100644
index 9e26dfe..0000000
--- a/utils/utils_rule/ban_list_group.json
+++ /dev/null
@@ -1 +0,0 @@
-{}
\ No newline at end of file
diff --git a/utils/utils_rule/ban_list_user.json b/utils/utils_rule/ban_list_user.json
deleted file mode 100644
index 9e26dfe..0000000
--- a/utils/utils_rule/ban_list_user.json
+++ /dev/null
@@ -1 +0,0 @@
-{}
\ No newline at end of file
diff --git a/utils/utils_rule/switch.json b/utils/utils_rule/switch.json
deleted file mode 100644
index c19bf91..0000000
--- a/utils/utils_rule/switch.json
+++ /dev/null
@@ -1 +0,0 @@
-{"anime-setu": "True", "anime-pic-search": "True", "anime-vid-search": "True", "all-off-anime-setu": "True", "ai-face": "True", "pixiv-pic-search": "True", "pixiv-author-search": "True", "pixiv-rank": "True", "one-key-adult": "True", "genshin-search": "True"}
\ No newline at end of file
diff --git a/utils/utils_switch/__init__.py b/utils/utils_switch/__init__.py
deleted file mode 100644
index 31abe16..0000000
--- a/utils/utils_switch/__init__.py
+++ /dev/null
@@ -1,80 +0,0 @@
-#!/usr/bin/env python3
-# -*- encoding: utf-8 -*-
-'''
-@File : __init__.py
-@Time : 2020/10/11 14:44:06
-@Author : Kyomotoi
-@Contact : kyomotoiowo@gmail.com
-@Github : https://github.com/Kyomotoi
-@License : Copyright © 2018-2020 Kyomotoi, All Rights Reserved.
-'''
-__author__ = 'kyomotoi'
-
-import json
-from pathlib import Path
-from typing import Optional
-
-
-def controlSwitch(func_name: str,
- control: bool,
- group: Optional[str] = None) -> str:
- '''
- 控制开关 开启或关闭
-
- :return: str
- '''
- file_switch_all = Path('.') / 'utils' / 'utils_rule' / 'switch.json'
-
- if group:
- file_switch_group = Path(
- '.') / 'ATRI' / 'data' / 'data_Group' / f'{group}' / 'switch.json'
- try:
- with open(file_switch_group, 'r') as f:
- data_switch_group = json.load(f)
- except FileNotFoundError:
- data_switch_group = {}
-
- if data_switch_group[f"{func_name}"]:
- pass
- else:
- return f"Can't find func({func_name})"
-
- data_switch_group[f"{func_name}"] = f"{control}"
-
- with open(file_switch_group, 'w') as f:
- f.write(json.dumps(data_switch_group))
- f.close()
-
- else:
- pass
-
- try:
- with open(file_switch_all, 'r') as f:
- data_switch_all = json.load(f)
- except FileNotFoundError:
- data_switch_all = {}
-
- if data_switch_all[f"{func_name}"]:
- pass
- else:
- return f"Can't find func({func_name})"
-
- data_switch_all[f"{func_name}"] = f"{control}"
-
- with open(file_switch_all, 'w') as f:
- f.write(json.dumps(data_switch_all))
- f.close()
-
- if control == True:
- if group:
- msg = f"({func_name}) has been opened for group ({group})!"
- else:
- msg = f"({func_name}) has been opened!"
-
- else:
- if group:
- msg = f"({func_name}) has been closed for group ({group})!"
- else:
- msg = f"({func_name}) has been closed!"
-
- return msg
\ No newline at end of file
diff --git a/utils/utils_times/__init__.py b/utils/utils_times/__init__.py
deleted file mode 100644
index dc65642..0000000
--- a/utils/utils_times/__init__.py
+++ /dev/null
@@ -1,27 +0,0 @@
-#!/usr/bin/env python3
-# -*- encoding: utf-8 -*-
-'''
-@File : __init__.py
-@Time : 2020/10/31 19:36:49
-@Author : Kyomotoi
-@Contact : kyomotoiowo@gmail.com
-@Github : https://github.com/Kyomotoi
-@License : Copyright © 2018-2020 Kyomotoi, All Rights Reserved.
-'''
-__author__ = 'kyomotoi'
-
-import warnings
-
-
-def countX(lst: list, aim) -> int:
- '''
- 检查某列表某元素出现次数
-
- :return: int
- '''
- warnings.simplefilter('ignore', ResourceWarning)
- count = 0
- for ele in lst:
- if (ele == aim):
- count = count + 1
- return count
\ No newline at end of file
diff --git a/utils/utils_translate/__init__.py b/utils/utils_translate/__init__.py
deleted file mode 100644
index e587bf9..0000000
--- a/utils/utils_translate/__init__.py
+++ /dev/null
@@ -1,56 +0,0 @@
-#!/usr/bin/env python3
-# -*- encoding: utf-8 -*-
-'''
-@File : __init__.py
-@Time : 2020/10/23 21:59:02
-@Author : Kyomotoi
-@Contact : kyomotoiowo@gmail.com
-@Github : https://github.com/Kyomotoi
-@License : Copyright © 2018-2020 Kyomotoi, All Rights Reserved.
-'''
-__author__ = 'kyomotoi'
-
-SIMPLE = "万与丑专业丛东丝丢两严丧个丬丰临为丽举么义乌乐乔习乡书买乱争于亏云亘亚产亩亲亵亸亿仅从仑仓仪们价众优伙会伛伞伟传伤伥伦伧伪伫体余佣佥侠侣侥侦侧侨侩侪侬俣俦俨俩俪俭债倾偬偻偾偿傥傧储傩儿兑兖党兰关兴兹养兽冁内冈册写军农冢冯冲决况冻净凄凉凌减凑凛几凤凫凭凯击凼凿刍划刘则刚创删别刬刭刽刿剀剂剐剑剥剧劝办务劢动励劲劳势勋勐勚匀匦匮区医华协单卖卢卤卧卫却卺厂厅历厉压厌厍厕厢厣厦厨厩厮县参叆叇双发变叙叠叶号叹叽吁后吓吕吗吣吨听启吴呒呓呕呖呗员呙呛呜咏咔咙咛咝咤咴咸哌响哑哒哓哔哕哗哙哜哝哟唛唝唠唡唢唣唤唿啧啬啭啮啰啴啸喷喽喾嗫呵嗳嘘嘤嘱噜噼嚣嚯团园囱围囵国图圆圣圹场坂坏块坚坛坜坝坞坟坠垄垅垆垒垦垧垩垫垭垯垱垲垴埘埙埚埝埯堑堕塆墙壮声壳壶壸处备复够头夸夹夺奁奂奋奖奥妆妇妈妩妪妫姗姜娄娅娆娇娈娱娲娴婳婴婵婶媪嫒嫔嫱嬷孙学孪宁宝实宠审宪宫宽宾寝对寻导寿将尔尘尧尴尸尽层屃屉届属屡屦屿岁岂岖岗岘岙岚岛岭岳岽岿峃峄峡峣峤峥峦崂崃崄崭嵘嵚嵛嵝嵴巅巩巯币帅师帏帐帘帜带帧帮帱帻帼幂幞干并广庄庆庐庑库应庙庞废庼廪开异弃张弥弪弯弹强归当录彟彦彻径徕御忆忏忧忾怀态怂怃怄怅怆怜总怼怿恋恳恶恸恹恺恻恼恽悦悫悬悭悯惊惧惨惩惫惬惭惮惯愍愠愤愦愿慑慭憷懑懒懔戆戋戏戗战戬户扎扑扦执扩扪扫扬扰抚抛抟抠抡抢护报担拟拢拣拥拦拧拨择挂挚挛挜挝挞挟挠挡挢挣挤挥挦捞损捡换捣据捻掳掴掷掸掺掼揸揽揿搀搁搂搅携摄摅摆摇摈摊撄撑撵撷撸撺擞攒敌敛数斋斓斗斩断无旧时旷旸昙昼昽显晋晒晓晔晕晖暂暧札术朴机杀杂权条来杨杩杰极构枞枢枣枥枧枨枪枫枭柜柠柽栀栅标栈栉栊栋栌栎栏树栖样栾桊桠桡桢档桤桥桦桧桨桩梦梼梾检棂椁椟椠椤椭楼榄榇榈榉槚槛槟槠横樯樱橥橱橹橼檐檩欢欤欧歼殁殇残殒殓殚殡殴毁毂毕毙毡毵氇气氢氩氲汇汉污汤汹沓沟没沣沤沥沦沧沨沩沪沵泞泪泶泷泸泺泻泼泽泾洁洒洼浃浅浆浇浈浉浊测浍济浏浐浑浒浓浔浕涂涌涛涝涞涟涠涡涢涣涤润涧涨涩淀渊渌渍渎渐渑渔渖渗温游湾湿溃溅溆溇滗滚滞滟滠满滢滤滥滦滨滩滪漤潆潇潋潍潜潴澜濑濒灏灭灯灵灾灿炀炉炖炜炝点炼炽烁烂烃烛烟烦烧烨烩烫烬热焕焖焘煅煳熘爱爷牍牦牵牺犊犟状犷犸犹狈狍狝狞独狭狮狯狰狱狲猃猎猕猡猪猫猬献獭玑玙玚玛玮环现玱玺珉珏珐珑珰珲琎琏琐琼瑶瑷璇璎瓒瓮瓯电画畅畲畴疖疗疟疠疡疬疮疯疱疴痈痉痒痖痨痪痫痴瘅瘆瘗瘘瘪瘫瘾瘿癞癣癫癯皑皱皲盏盐监盖盗盘眍眦眬着睁睐睑瞒瞩矫矶矾矿砀码砖砗砚砜砺砻砾础硁硅硕硖硗硙硚确硷碍碛碜碱碹磙礼祎祢祯祷祸禀禄禅离秃秆种积称秽秾稆税稣稳穑穷窃窍窑窜窝窥窦窭竖竞笃笋笔笕笺笼笾筑筚筛筜筝筹签简箓箦箧箨箩箪箫篑篓篮篱簖籁籴类籼粜粝粤粪粮糁糇紧絷纟纠纡红纣纤纥约级纨纩纪纫纬纭纮纯纰纱纲纳纴纵纶纷纸纹纺纻纼纽纾线绀绁绂练组绅细织终绉绊绋绌绍绎经绐绑绒结绔绕绖绗绘给绚绛络绝绞统绠绡绢绣绤绥绦继绨绩绪绫绬续绮绯绰绱绲绳维绵绶绷绸绹绺绻综绽绾绿缀缁缂缃缄缅缆缇缈缉缊缋缌缍缎缏缐缑缒缓缔缕编缗缘缙缚缛缜缝缞缟缠缡缢缣缤缥缦缧缨缩缪缫缬缭缮缯缰缱缲缳缴缵罂网罗罚罢罴羁羟羡翘翙翚耢耧耸耻聂聋职聍联聩聪肃肠肤肷肾肿胀胁胆胜胧胨胪胫胶脉脍脏脐脑脓脔脚脱脶脸腊腌腘腭腻腼腽腾膑臜舆舣舰舱舻艰艳艹艺节芈芗芜芦苁苇苈苋苌苍苎苏苘苹茎茏茑茔茕茧荆荐荙荚荛荜荞荟荠荡荣荤荥荦荧荨荩荪荫荬荭荮药莅莜莱莲莳莴莶获莸莹莺莼萚萝萤营萦萧萨葱蒇蒉蒋蒌蓝蓟蓠蓣蓥蓦蔷蔹蔺蔼蕲蕴薮藁藓虏虑虚虫虬虮虽虾虿蚀蚁蚂蚕蚝蚬蛊蛎蛏蛮蛰蛱蛲蛳蛴蜕蜗蜡蝇蝈蝉蝎蝼蝾螀螨蟏衅衔补衬衮袄袅袆袜袭袯装裆裈裢裣裤裥褛褴襁襕见观觃规觅视觇览觉觊觋觌觍觎觏觐觑觞触觯詟誉誊讠计订讣认讥讦讧讨让讪讫训议讯记讱讲讳讴讵讶讷许讹论讻讼讽设访诀证诂诃评诅识诇诈诉诊诋诌词诎诏诐译诒诓诔试诖诗诘诙诚诛诜话诞诟诠诡询诣诤该详诧诨诩诪诫诬语诮误诰诱诲诳说诵诶请诸诹诺读诼诽课诿谀谁谂调谄谅谆谇谈谊谋谌谍谎谏谐谑谒谓谔谕谖谗谘谙谚谛谜谝谞谟谠谡谢谣谤谥谦谧谨谩谪谫谬谭谮谯谰谱谲谳谴谵谶谷豮贝贞负贠贡财责贤败账货质贩贪贫贬购贮贯贰贱贲贳贴贵贶贷贸费贺贻贼贽贾贿赀赁赂赃资赅赆赇赈赉赊赋赌赍赎赏赐赑赒赓赔赕赖赗赘赙赚赛赜赝赞赟赠赡赢赣赪赵赶趋趱趸跃跄跖跞践跶跷跸跹跻踊踌踪踬踯蹑蹒蹰蹿躏躜躯车轧轨轩轪轫转轭轮软轰轱轲轳轴轵轶轷轸轹轺轻轼载轾轿辀辁辂较辄辅辆辇辈辉辊辋辌辍辎辏辐辑辒输辔辕辖辗辘辙辚辞辩辫边辽达迁过迈运还这进远违连迟迩迳迹适选逊递逦逻遗遥邓邝邬邮邹邺邻郁郄郏郐郑郓郦郧郸酝酦酱酽酾酿释里鉅鉴銮錾钆钇针钉钊钋钌钍钎钏钐钑钒钓钔钕钖钗钘钙钚钛钝钞钟钠钡钢钣钤钥钦钧钨钩钪钫钬钭钮钯钰钱钲钳钴钵钶钷钸钹钺钻钼钽钾钿铀铁铂铃铄铅铆铈铉铊铋铍铎铏铐铑铒铕铗铘铙铚铛铜铝铞铟铠铡铢铣铤铥铦铧铨铪铫铬铭铮铯铰铱铲铳铴铵银铷铸铹铺铻铼铽链铿销锁锂锃锄锅锆锇锈锉锊锋锌锍锎锏锐锑锒锓锔锕锖锗错锚锜锞锟锠锡锢锣锤锥锦锨锩锫锬锭键锯锰锱锲锳锴锵锶锷锸锹锺锻锼锽锾锿镀镁镂镃镆镇镈镉镊镌镍镎镏镐镑镒镕镖镗镙镚镛镜镝镞镟镠镡镢镣镤镥镦镧镨镩镪镫镬镭镮镯镰镱镲镳镴镶长门闩闪闫闬闭问闯闰闱闲闳间闵闶闷闸闹闺闻闼闽闾闿阀阁阂阃阄阅阆阇阈阉阊阋阌阍阎阏阐阑阒阓阔阕阖阗阘阙阚阛队阳阴阵阶际陆陇陈陉陕陧陨险随隐隶隽难雏雠雳雾霁霉霭靓静靥鞑鞒鞯鞴韦韧韨韩韪韫韬韵页顶顷顸项顺须顼顽顾顿颀颁颂颃预颅领颇颈颉颊颋颌颍颎颏颐频颒颓颔颕颖颗题颙颚颛颜额颞颟颠颡颢颣颤颥颦颧风飏飐飑飒飓飔飕飖飗飘飙飚飞飨餍饤饥饦饧饨饩饪饫饬饭饮饯饰饱饲饳饴饵饶饷饸饹饺饻饼饽饾饿馀馁馂馃馄馅馆馇馈馉馊馋馌馍馎馏馐馑馒馓馔馕马驭驮驯驰驱驲驳驴驵驶驷驸驹驺驻驼驽驾驿骀骁骂骃骄骅骆骇骈骉骊骋验骍骎骏骐骑骒骓骔骕骖骗骘骙骚骛骜骝骞骟骠骡骢骣骤骥骦骧髅髋髌鬓魇魉鱼鱽鱾鱿鲀鲁鲂鲄鲅鲆鲇鲈鲉鲊鲋鲌鲍鲎鲏鲐鲑鲒鲓鲔鲕鲖鲗鲘鲙鲚鲛鲜鲝鲞鲟鲠鲡鲢鲣鲤鲥鲦鲧鲨鲩鲪鲫鲬鲭鲮鲯鲰鲱鲲鲳鲴鲵鲶鲷鲸鲹鲺鲻鲼鲽鲾鲿鳀鳁鳂鳃鳄鳅鳆鳇鳈鳉鳊鳋鳌鳍鳎鳏鳐鳑鳒鳓鳔鳕鳖鳗鳘鳙鳛鳜鳝鳞鳟鳠鳡鳢鳣鸟鸠鸡鸢鸣鸤鸥鸦鸧鸨鸩鸪鸫鸬鸭鸮鸯鸰鸱鸲鸳鸴鸵鸶鸷鸸鸹鸺鸻鸼鸽鸾鸿鹀鹁鹂鹃鹄鹅鹆鹇鹈鹉鹊鹋鹌鹍鹎鹏鹐鹑鹒鹓鹔鹕鹖鹗鹘鹚鹛鹜鹝鹞鹟鹠鹡鹢鹣鹤鹥鹦鹧鹨鹩鹪鹫鹬鹭鹯鹰鹱鹲鹳鹴鹾麦麸黄黉黡黩黪黾鼋鼌鼍鼗鼹齄齐齑齿龀龁龂龃龄龅龆龇龈龉龊龋龌龙龚龛龟志制咨只里系范松没尝尝闹面准钟别闲干尽脏拼"
-TRADITION = "萬與醜專業叢東絲丟兩嚴喪個爿豐臨為麗舉麼義烏樂喬習鄉書買亂爭於虧雲亙亞產畝親褻嚲億僅從侖倉儀們價眾優夥會傴傘偉傳傷倀倫傖偽佇體餘傭僉俠侶僥偵側僑儈儕儂俁儔儼倆儷儉債傾傯僂僨償儻儐儲儺兒兌兗黨蘭關興茲養獸囅內岡冊寫軍農塚馮衝決況凍淨淒涼淩減湊凜幾鳳鳧憑凱擊氹鑿芻劃劉則剛創刪別剗剄劊劌剴劑剮劍剝劇勸辦務勱動勵勁勞勢勳猛勩勻匭匱區醫華協單賣盧鹵臥衛卻巹廠廳曆厲壓厭厙廁廂厴廈廚廄廝縣參靉靆雙發變敘疊葉號歎嘰籲後嚇呂嗎唚噸聽啟吳嘸囈嘔嚦唄員咼嗆嗚詠哢嚨嚀噝吒噅鹹呱響啞噠嘵嗶噦嘩噲嚌噥喲嘜嗊嘮啢嗩唕喚呼嘖嗇囀齧囉嘽嘯噴嘍嚳囁嗬噯噓嚶囑嚕劈囂謔團園囪圍圇國圖圓聖壙場阪壞塊堅壇壢壩塢墳墜壟壟壚壘墾坰堊墊埡墶壋塏堖塒塤堝墊垵塹墮壪牆壯聲殼壺壼處備復夠頭誇夾奪奩奐奮獎奧妝婦媽嫵嫗媯姍薑婁婭嬈嬌孌娛媧嫻嫿嬰嬋嬸媼嬡嬪嬙嬤孫學孿寧寶實寵審憲宮寬賓寢對尋導壽將爾塵堯尷屍盡層屭屜屆屬屢屨嶼歲豈嶇崗峴嶴嵐島嶺嶽崠巋嶨嶧峽嶢嶠崢巒嶗崍嶮嶄嶸嶔崳嶁脊巔鞏巰幣帥師幃帳簾幟帶幀幫幬幘幗冪襆幹並廣莊慶廬廡庫應廟龐廢廎廩開異棄張彌弳彎彈強歸當錄彠彥徹徑徠禦憶懺憂愾懷態慫憮慪悵愴憐總懟懌戀懇惡慟懨愷惻惱惲悅愨懸慳憫驚懼慘懲憊愜慚憚慣湣慍憤憒願懾憖怵懣懶懍戇戔戲戧戰戩戶紮撲扡執擴捫掃揚擾撫拋摶摳掄搶護報擔擬攏揀擁攔擰撥擇掛摯攣掗撾撻挾撓擋撟掙擠揮撏撈損撿換搗據撚擄摑擲撣摻摜摣攬撳攙擱摟攪攜攝攄擺搖擯攤攖撐攆擷擼攛擻攢敵斂數齋斕鬥斬斷無舊時曠暘曇晝曨顯晉曬曉曄暈暉暫曖劄術樸機殺雜權條來楊榪傑極構樅樞棗櫪梘棖槍楓梟櫃檸檉梔柵標棧櫛櫳棟櫨櫟欄樹棲樣欒棬椏橈楨檔榿橋樺檜槳樁夢檮棶檢欞槨櫝槧欏橢樓欖櫬櫚櫸檟檻檳櫧橫檣櫻櫫櫥櫓櫞簷檁歡歟歐殲歿殤殘殞殮殫殯毆毀轂畢斃氈毿氌氣氫氬氳彙漢汙湯洶遝溝沒灃漚瀝淪滄渢溈滬濔濘淚澩瀧瀘濼瀉潑澤涇潔灑窪浹淺漿澆湞溮濁測澮濟瀏滻渾滸濃潯濜塗湧濤澇淶漣潿渦溳渙滌潤澗漲澀澱淵淥漬瀆漸澠漁瀋滲溫遊灣濕潰濺漵漊潷滾滯灩灄滿瀅濾濫灤濱灘澦濫瀠瀟瀲濰潛瀦瀾瀨瀕灝滅燈靈災燦煬爐燉煒熗點煉熾爍爛烴燭煙煩燒燁燴燙燼熱煥燜燾煆糊溜愛爺牘犛牽犧犢強狀獷獁猶狽麅獮獰獨狹獅獪猙獄猻獫獵獼玀豬貓蝟獻獺璣璵瑒瑪瑋環現瑲璽瑉玨琺瓏璫琿璡璉瑣瓊瑤璦璿瓔瓚甕甌電畫暢佘疇癤療瘧癘瘍鬁瘡瘋皰屙癰痙癢瘂癆瘓癇癡癉瘮瘞瘺癟癱癮癭癩癬癲臒皚皺皸盞鹽監蓋盜盤瞘眥矓著睜睞瞼瞞矚矯磯礬礦碭碼磚硨硯碸礪礱礫礎硜矽碩硤磽磑礄確鹼礙磧磣堿镟滾禮禕禰禎禱禍稟祿禪離禿稈種積稱穢穠穭稅穌穩穡窮竊竅窯竄窩窺竇窶豎競篤筍筆筧箋籠籩築篳篩簹箏籌簽簡籙簀篋籜籮簞簫簣簍籃籬籪籟糴類秈糶糲粵糞糧糝餱緊縶糸糾紆紅紂纖紇約級紈纊紀紉緯紜紘純紕紗綱納紝縱綸紛紙紋紡紵紖紐紓線紺絏紱練組紳細織終縐絆紼絀紹繹經紿綁絨結絝繞絰絎繪給絢絳絡絕絞統綆綃絹繡綌綏絛繼綈績緒綾緓續綺緋綽緔緄繩維綿綬繃綢綯綹綣綜綻綰綠綴緇緙緗緘緬纜緹緲緝縕繢緦綞緞緶線緱縋緩締縷編緡緣縉縛縟縝縫縗縞纏縭縊縑繽縹縵縲纓縮繆繅纈繚繕繒韁繾繰繯繳纘罌網羅罰罷羆羈羥羨翹翽翬耮耬聳恥聶聾職聹聯聵聰肅腸膚膁腎腫脹脅膽勝朧腖臚脛膠脈膾髒臍腦膿臠腳脫腡臉臘醃膕齶膩靦膃騰臏臢輿艤艦艙艫艱豔艸藝節羋薌蕪蘆蓯葦藶莧萇蒼苧蘇檾蘋莖蘢蔦塋煢繭荊薦薘莢蕘蓽蕎薈薺蕩榮葷滎犖熒蕁藎蓀蔭蕒葒葤藥蒞蓧萊蓮蒔萵薟獲蕕瑩鶯蓴蘀蘿螢營縈蕭薩蔥蕆蕢蔣蔞藍薊蘺蕷鎣驀薔蘞藺藹蘄蘊藪槁蘚虜慮虛蟲虯蟣雖蝦蠆蝕蟻螞蠶蠔蜆蠱蠣蟶蠻蟄蛺蟯螄蠐蛻蝸蠟蠅蟈蟬蠍螻蠑螿蟎蠨釁銜補襯袞襖嫋褘襪襲襏裝襠褌褳襝褲襇褸襤繈襴見觀覎規覓視覘覽覺覬覡覿覥覦覯覲覷觴觸觶讋譽謄訁計訂訃認譏訐訌討讓訕訖訓議訊記訒講諱謳詎訝訥許訛論訩訟諷設訪訣證詁訶評詛識詗詐訴診詆謅詞詘詔詖譯詒誆誄試詿詩詰詼誠誅詵話誕詬詮詭詢詣諍該詳詫諢詡譸誡誣語誚誤誥誘誨誑說誦誒請諸諏諾讀諑誹課諉諛誰諗調諂諒諄誶談誼謀諶諜謊諫諧謔謁謂諤諭諼讒諮諳諺諦謎諞諝謨讜謖謝謠謗諡謙謐謹謾謫譾謬譚譖譙讕譜譎讞譴譫讖穀豶貝貞負貟貢財責賢敗賬貨質販貪貧貶購貯貫貳賤賁貰貼貴貺貸貿費賀貽賊贄賈賄貲賃賂贓資賅贐賕賑賚賒賦賭齎贖賞賜贔賙賡賠賧賴賵贅賻賺賽賾贗讚贇贈贍贏贛赬趙趕趨趲躉躍蹌蹠躒踐躂蹺蹕躚躋踴躊蹤躓躑躡蹣躕躥躪躦軀車軋軌軒軑軔轉軛輪軟轟軲軻轤軸軹軼軤軫轢軺輕軾載輊轎輈輇輅較輒輔輛輦輩輝輥輞輬輟輜輳輻輯轀輸轡轅轄輾轆轍轔辭辯辮邊遼達遷過邁運還這進遠違連遲邇逕跡適選遜遞邐邏遺遙鄧鄺鄔郵鄒鄴鄰鬱郤郟鄶鄭鄆酈鄖鄲醞醱醬釅釃釀釋裏钜鑒鑾鏨釓釔針釘釗釙釕釷釺釧釤鈒釩釣鍆釹鍚釵鈃鈣鈈鈦鈍鈔鍾鈉鋇鋼鈑鈐鑰欽鈞鎢鉤鈧鈁鈥鈄鈕鈀鈺錢鉦鉗鈷缽鈳鉕鈽鈸鉞鑽鉬鉭鉀鈿鈾鐵鉑鈴鑠鉛鉚鈰鉉鉈鉍鈹鐸鉶銬銠鉺銪鋏鋣鐃銍鐺銅鋁銱銦鎧鍘銖銑鋌銩銛鏵銓鉿銚鉻銘錚銫鉸銥鏟銃鐋銨銀銣鑄鐒鋪鋙錸鋱鏈鏗銷鎖鋰鋥鋤鍋鋯鋨鏽銼鋝鋒鋅鋶鐦鐧銳銻鋃鋟鋦錒錆鍺錯錨錡錁錕錩錫錮鑼錘錐錦鍁錈錇錟錠鍵鋸錳錙鍥鍈鍇鏘鍶鍔鍤鍬鍾鍛鎪鍠鍰鎄鍍鎂鏤鎡鏌鎮鎛鎘鑷鐫鎳鎿鎦鎬鎊鎰鎔鏢鏜鏍鏰鏞鏡鏑鏃鏇鏐鐔钁鐐鏷鑥鐓鑭鐠鑹鏹鐙鑊鐳鐶鐲鐮鐿鑔鑣鑞鑲長門閂閃閆閈閉問闖閏闈閑閎間閔閌悶閘鬧閨聞闥閩閭闓閥閣閡閫鬮閱閬闍閾閹閶鬩閿閽閻閼闡闌闃闠闊闋闔闐闒闕闞闤隊陽陰陣階際陸隴陳陘陝隉隕險隨隱隸雋難雛讎靂霧霽黴靄靚靜靨韃鞽韉韝韋韌韍韓韙韞韜韻頁頂頃頇項順須頊頑顧頓頎頒頌頏預顱領頗頸頡頰頲頜潁熲頦頤頻頮頹頷頴穎顆題顒顎顓顏額顳顢顛顙顥纇顫顬顰顴風颺颭颮颯颶颸颼颻飀飄飆飆飛饗饜飣饑飥餳飩餼飪飫飭飯飲餞飾飽飼飿飴餌饒餉餄餎餃餏餅餑餖餓餘餒餕餜餛餡館餷饋餶餿饞饁饃餺餾饈饉饅饊饌饢馬馭馱馴馳驅馹駁驢駔駛駟駙駒騶駐駝駑駕驛駘驍罵駰驕驊駱駭駢驫驪騁驗騂駸駿騏騎騍騅騌驌驂騙騭騤騷騖驁騮騫騸驃騾驄驏驟驥驦驤髏髖髕鬢魘魎魚魛魢魷魨魯魴魺鮁鮃鯰鱸鮋鮓鮒鮊鮑鱟鮍鮐鮭鮚鮳鮪鮞鮦鰂鮜鱠鱭鮫鮮鮺鯗鱘鯁鱺鰱鰹鯉鰣鰷鯀鯊鯇鮶鯽鯒鯖鯪鯕鯫鯡鯤鯧鯝鯢鯰鯛鯨鯵鯴鯔鱝鰈鰏鱨鯷鰮鰃鰓鱷鰍鰒鰉鰁鱂鯿鰠鼇鰭鰨鰥鰩鰟鰜鰳鰾鱈鱉鰻鰵鱅鰼鱖鱔鱗鱒鱯鱤鱧鱣鳥鳩雞鳶鳴鳲鷗鴉鶬鴇鴆鴣鶇鸕鴨鴞鴦鴒鴟鴝鴛鴬鴕鷥鷙鴯鴰鵂鴴鵃鴿鸞鴻鵐鵓鸝鵑鵠鵝鵒鷳鵜鵡鵲鶓鵪鶤鵯鵬鵮鶉鶊鵷鷫鶘鶡鶚鶻鶿鶥鶩鷊鷂鶲鶹鶺鷁鶼鶴鷖鸚鷓鷚鷯鷦鷲鷸鷺鸇鷹鸌鸏鸛鸘鹺麥麩黃黌黶黷黲黽黿鼂鼉鞀鼴齇齊齏齒齔齕齗齟齡齙齠齜齦齬齪齲齷龍龔龕龜誌製谘隻裡係範鬆冇嚐嘗鬨麵準鐘彆閒乾儘臟拚"
-
-
-def toTraditionString(msg: str) -> str:
- '''
- 简体转繁体。
-
- :return: str
- '''
- output_str_list = []
- str_len = len(msg)
-
- for i in range(str_len):
- found_index = SIMPLE.find(msg[i])
-
- if not (found_index == -1):
- output_str_list.append(TRADITION[found_index])
-
- else:
- output_str_list.append(msg[i])
-
- return "".join(output_str_list)
-
-
-def toSimpleString(msg: str) -> str:
- '''
- 繁体转简体。
-
- :return: str
- '''
- output_str_list = []
- str_len = len(msg)
-
- for i in range(str_len):
- found_index = TRADITION.find(msg[i])
-
- if not (found_index == -1):
- output_str_list.append(SIMPLE[found_index])
-
- else:
- output_str_list.append(msg[i])
-
- return "".join(output_str_list)
\ No newline at end of file
diff --git a/utils/utils_yml/__init__.py b/utils/utils_yml/__init__.py
deleted file mode 100644
index 2617a21..0000000
--- a/utils/utils_yml/__init__.py
+++ /dev/null
@@ -1,25 +0,0 @@
-#!/usr/bin/env python3
-# -*- encoding: utf-8 -*-
-'''
-@File : __init__.py
-@Time : 2020/11/06 22:26:06
-@Author : Kyomotoi
-@Contact : kyomotoiowo@gmail.com
-@Github : https://github.com/Kyomotoi
-@License : Copyright © 2018-2020 Kyomotoi, All Rights Reserved.
-'''
-__author__ = 'kyomotoi'
-
-import yaml
-from pathlib import Path
-
-
-def load_yaml(file: Path) -> dict:
- '''
- 读取yaml文件
-
- :return: dict
- '''
- with open(file, 'r', encoding='utf-8') as f:
- data = yaml.safe_load(f)
- return data
--
cgit v1.2.3