From 9ebeff70994191abe6052e53bb58541f08917f5a Mon Sep 17 00:00:00 2001
From: Kyomotoi <kyomotoiowo@gmail.com>
Date: Sun, 20 Mar 2022 09:06:49 +0800
Subject: =?UTF-8?q?=E2=9C=A8=20=E6=B7=BB=E5=8A=A0=E6=9B=B4=E6=96=B0?=
 =?UTF-8?q?=E6=A3=80=E6=9F=A5?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 ATRI/plugins/essential.py  | 22 +++++++++++++-----
 ATRI/utils/check_update.py | 58 ++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 74 insertions(+), 6 deletions(-)
 create mode 100644 ATRI/utils/check_update.py

(limited to 'ATRI')

diff --git a/ATRI/plugins/essential.py b/ATRI/plugins/essential.py
index 6ec5401..f71a472 100644
--- a/ATRI/plugins/essential.py
+++ b/ATRI/plugins/essential.py
@@ -2,6 +2,7 @@ import os
 import json
 import shutil
 import asyncio
+from time import sleep
 from datetime import datetime
 from pydantic.main import BaseModel
 from random import choice, randint
@@ -33,6 +34,7 @@ from ATRI.log import logger as log
 from ATRI.config import BotSelfConfig
 from ATRI.utils import MessageChecker
 from ATRI.utils.apscheduler import scheduler
+from ATRI.utils.check_update import CheckUpdate
 
 
 driver = ATRI.driver()
@@ -50,6 +52,17 @@ os.makedirs(TEMP_PATH, exist_ok=True)
 @driver.on_startup
 async def startup():
     log.info(f"Now running: {ATRI.__version__}")
+
+    log.info("Starting to check update...")
+    log.info(await CheckUpdate.show_latest_commit_info())
+    sleep(1)
+    
+    l_v, l_v_t = await CheckUpdate.show_latest_version()
+    if l_v != ATRI.__version__:
+        log.warning("New version has been released, please update.")
+        log.warning(f"Latest version: {l_v} Update time: {l_v_t}")
+        sleep(3)
+    
     log.info("アトリは、高性能ですから!")
 
 
@@ -106,14 +119,9 @@ class GroupRequestInfo(BaseModel):
     is_approve: bool
 
 
-__doc__ = """
-对bot基础/必须请求进行处理
-"""
-
-
 class Essential(Service):
     def __init__(self):
-        Service.__init__(self, "基础部件", __doc__)
+        Service.__init__(self, "基础部件", "对bot基础/必须请求进行处理")
 
 
 friend_add_event = Essential().on_request("好友添加", "好友添加检测")
@@ -279,6 +287,7 @@ async def _recall_group_event(bot: Bot, event: GroupRecallNoticeEvent):
     except BaseException:
         return
 
+    log.debug(f"Recall raw msg:\n{repo}")
     user = event.user_id
     group = event.group_id
     repo = repo["message"]
@@ -310,6 +319,7 @@ async def _recall_private_event(bot: Bot, event: FriendRecallNoticeEvent):
     except BaseException:
         return
 
+    log.debug(f"Recall raw msg:\n{repo}")
     user = event.user_id
     repo = repo["message"]
 
diff --git a/ATRI/utils/check_update.py b/ATRI/utils/check_update.py
new file mode 100644
index 0000000..b2f8b53
--- /dev/null
+++ b/ATRI/utils/check_update.py
@@ -0,0 +1,58 @@
+from ATRI.exceptions import RequestError
+
+from . import request
+
+
+REPO_COMMITS_URL = "https://api.github.com/repos/Kyomotoi/ATRI/commits"
+REPO_RELEASE_URL = "https://api.github.com/repos/Kyomotoi/ATRI/releases"
+
+
+class CheckUpdate:
+    
+    @staticmethod
+    async def _get_commits_info() -> dict:
+        req = await request.get(REPO_COMMITS_URL)
+        return req.json()
+    
+    @staticmethod
+    async def _get_release_info() -> dict:
+        req = await request.get(REPO_RELEASE_URL)
+        return req.json()
+
+    @classmethod
+    async def show_latest_commit_info(cls) -> str:
+        try:
+            data = await cls._get_commits_info()
+        except RequestError:
+            raise RequestError("Getting commit info timeout...")
+        
+        try:
+            commit_data: dict = data[0]
+        except Exception:
+            raise Exception("GitHub has been error!!!")
+
+        c_info = commit_data["commit"]
+        c_msg = c_info["message"]
+        c_sha = commit_data["sha"][0:5]
+        c_time = c_info["author"]["date"]
+
+        return f"Latest commit {c_msg} | sha: {c_sha} | time: {c_time}"
+
+    @classmethod
+    async def show_latest_version(cls) -> tuple:
+        try:
+            data = await cls._get_release_info()
+        except RequestError:
+            raise RequestError("Getting release list timeout...")
+        
+        try:
+            release_data: dict = data[0]
+        except Exception:
+            raise Exception("GitHub has been error!!!")
+        
+        l_v = release_data["tag_name"]
+        l_v_t = release_data["published_at"]
+        return l_v, l_v_t
+
+
+
-- 
cgit v1.2.3


From c0487efd321da4ea21d3ebb817cbac0e73d4fda6 Mon Sep 17 00:00:00 2001
From: Kyomotoi <kyomotoiowo@gmail.com>
Date: Sun, 20 Mar 2022 09:07:38 +0800
Subject: =?UTF-8?q?=F0=9F=9A=B8=20=E4=BC=98=E5=8C=96=E7=94=A8=E6=88=B7?=
 =?UTF-8?q?=E4=BD=93=E9=AA=8C?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 ATRI/plugins/bilibili_dynamic/__init__.py | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

(limited to 'ATRI')

diff --git a/ATRI/plugins/bilibili_dynamic/__init__.py b/ATRI/plugins/bilibili_dynamic/__init__.py
index 82fbb4d..f1ac8d2 100644
--- a/ATRI/plugins/bilibili_dynamic/__init__.py
+++ b/ATRI/plugins/bilibili_dynamic/__init__.py
@@ -18,18 +18,18 @@ from datetime import datetime, timedelta
 from ATRI.log import logger
 
 bilibili_dynamic = BilibiliDynamicSubscriptor().on_command(
-    "/bilibili_dynamic", "b站动态订阅助手", aliases={"b站动态"}
+    "/bilibili_dynamic", "b站动态订阅助手", aliases={"/bd", "b站动态"}
 )
 
-__help__ = """欢迎使用【b站动态订阅助手】~
-目前支持的功能如下...请选择:
+__help__ = """好哦!是b站动态订阅诶~
+目前支持的功能如下...请键入对应关键词:
 1.添加订阅
 2.取消订阅
 3.订阅列表
 -----------------------------------
-用法示例1:/bilibili_dynamic 添加订阅
-用法示例2:/bilibili_dynamic 取消订阅 401742377(数字uid)
-用法示例3:/bilibili_dynamic 订阅列表"""
+用法示例1:/bd 添加订阅
+用法示例2:/bd 取消订阅 401742377(数字uid)
+用法示例3:/bd 订阅列表"""
 
 
 def help() -> str:
-- 
cgit v1.2.3


From cc5c0fab220776508eab9ac6831f8efa1010d083 Mon Sep 17 00:00:00 2001
From: Lint Action <noreply@github.com>
Date: Sun, 20 Mar 2022 01:09:34 +0000
Subject: =?UTF-8?q?:rotating=5Flight:=20=E8=87=AA=E5=8A=A8=E8=BF=9B?=
 =?UTF-8?q?=E8=A1=8C=E4=BB=A3=E7=A0=81=E6=A0=BC=E5=BC=8F=E5=8C=96?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 ATRI/plugins/essential.py  |  4 ++--
 ATRI/utils/check_update.py | 12 ++++--------
 2 files changed, 6 insertions(+), 10 deletions(-)

(limited to 'ATRI')

diff --git a/ATRI/plugins/essential.py b/ATRI/plugins/essential.py
index f71a472..6a2ee22 100644
--- a/ATRI/plugins/essential.py
+++ b/ATRI/plugins/essential.py
@@ -56,13 +56,13 @@ async def startup():
     log.info("Starting to check update...")
     log.info(await CheckUpdate.show_latest_commit_info())
     sleep(1)
-    
+
     l_v, l_v_t = await CheckUpdate.show_latest_version()
     if l_v != ATRI.__version__:
         log.warning("New version has been released, please update.")
         log.warning(f"Latest version: {l_v} Update time: {l_v_t}")
         sleep(3)
-    
+
     log.info("アトリは、高性能ですから!")
 
 
diff --git a/ATRI/utils/check_update.py b/ATRI/utils/check_update.py
index b2f8b53..a8575ab 100644
--- a/ATRI/utils/check_update.py
+++ b/ATRI/utils/check_update.py
@@ -8,12 +8,11 @@ REPO_RELEASE_URL = "https://api.github.com/repos/Kyomotoi/ATRI/releases"
 
 
 class CheckUpdate:
-    
     @staticmethod
     async def _get_commits_info() -> dict:
         req = await request.get(REPO_COMMITS_URL)
         return req.json()
-    
+
     @staticmethod
     async def _get_release_info() -> dict:
         req = await request.get(REPO_RELEASE_URL)
@@ -25,7 +24,7 @@ class CheckUpdate:
             data = await cls._get_commits_info()
         except RequestError:
             raise RequestError("Getting commit info timeout...")
-        
+
         try:
             commit_data: dict = data[0]
         except Exception:
@@ -44,15 +43,12 @@ class CheckUpdate:
             data = await cls._get_release_info()
         except RequestError:
             raise RequestError("Getting release list timeout...")
-        
+
         try:
             release_data: dict = data[0]
         except Exception:
             raise Exception("GitHub has been error!!!")
-        
+
         l_v = release_data["tag_name"]
         l_v_t = release_data["published_at"]
         return l_v, l_v_t
-
-
-
-- 
cgit v1.2.3


From 347699256c1e063698474b8c07dc8a9ee67b104f Mon Sep 17 00:00:00 2001
From: Kyomotoi <kyomotoiowo@gmail.com>
Date: Sun, 27 Mar 2022 15:20:53 +0800
Subject: =?UTF-8?q?=F0=9F=94=A5=20=E7=A7=BB=E9=99=A4=E6=97=A0=E7=94=A8?=
 =?UTF-8?q?=E5=8A=9F=E8=83=BD?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 ATRI/plugins/setu/__init__.py    | 21 ---------------------
 ATRI/plugins/setu/data_source.py | 25 -------------------------
 2 files changed, 46 deletions(-)

(limited to 'ATRI')

diff --git a/ATRI/plugins/setu/__init__.py b/ATRI/plugins/setu/__init__.py
index cf38fd6..f4bc99d 100644
--- a/ATRI/plugins/setu/__init__.py
+++ b/ATRI/plugins/setu/__init__.py
@@ -171,27 +171,6 @@ async def _deal_setting(msg: str = ArgPlainText("catcher_set")):
     await catcher_setting.finish(repo)
 
 
-@scheduler.scheduled_job(
-    "interval", name="涩批诱捕器", hours=1, misfire_grace_time=60, args=[Bot]
-)
-async def _scheduler_setu(bot):
-    try:
-        group_list = await bot.get_group_list()
-        lucky_group = choice(group_list)
-        group_id = lucky_group["group_id"]
-        setu = await Setu().scheduler()
-        if not setu:
-            return
-
-        msg_0 = await bot.send_group_msg(group_id=int(group_id), message=Message(setu))
-        message_id = msg_0["message_id"]
-        await asyncio.sleep(60)
-        await bot.delete_msg(message_id=message_id)
-
-    except Exception:
-        pass
-
-
 _ag_l = ["涩图来", "来点涩图", "来份涩图"]
 _ag_patt = r"来[张点丶份](.*?)的[涩色🐍]图"
 
diff --git a/ATRI/plugins/setu/data_source.py b/ATRI/plugins/setu/data_source.py
index b7c5162..e7d769d 100644
--- a/ATRI/plugins/setu/data_source.py
+++ b/ATRI/plugins/setu/data_source.py
@@ -1,5 +1,4 @@
 import asyncio
-from random import choice
 from nonebot.adapters.onebot.v11 import Bot, MessageSegment
 
 from ATRI.service import Service
@@ -78,30 +77,6 @@ class Setu(Service):
         data = await detect_image(url, file_size)
         return data
 
-    @classmethod
-    async def scheduler(cls) -> str:
-        """
-        每隔指定时间随机抽取一个群发送涩图.
-        格式:
-            是{tag}哦~❤
-            {setu}
-        """
-        res = await request.get(LOLICON_URL)
-        data: dict = res.json()
-        temp_data: dict = data.get("data", list())
-        if not temp_data:
-            return ""
-
-        tag = choice(temp_data.get("tags", ["女孩子"]))
-
-        url = temp_data[0]["urls"].get(
-            "original",
-            cls._use_proxy(DEFAULT_SETU),
-        )
-        setu = MessageSegment.image(url, timeout=114514)
-        repo = f"是{tag}哦~❤\n{setu}"
-        return repo
-
     @staticmethod
     async def async_recall(bot: Bot, event_id):
         await asyncio.sleep(30)
-- 
cgit v1.2.3


From 08a29bc7bb4e85cbb34abcc2f0c9377a3a9f4b7e Mon Sep 17 00:00:00 2001
From: Kyomotoi <kyomotoiowo@gmail.com>
Date: Sun, 27 Mar 2022 15:22:05 +0800
Subject: =?UTF-8?q?=F0=9F=8E=A8=F0=9F=91=94=20=E4=BC=98=E5=8C=96=E4=BB=A3?=
 =?UTF-8?q?=E7=A0=81=20&=20=E6=8F=90=E5=8D=87=E4=BD=93=E9=AA=8C?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 ATRI/service.py | 54 +++++++++++++++++++++++++++---------------------------
 1 file changed, 27 insertions(+), 27 deletions(-)

(limited to 'ATRI')

diff --git a/ATRI/service.py b/ATRI/service.py
index 9f680c8..c9509df 100644
--- a/ATRI/service.py
+++ b/ATRI/service.py
@@ -4,7 +4,7 @@ import json
 from pathlib import Path
 from types import ModuleType
 from pydantic import BaseModel
-from typing import List, Set, Tuple, Type, Union, Optional, TYPE_CHECKING
+from typing import List, Set, Tuple, Type, Union, Optional
 
 from nonebot.matcher import Matcher
 from nonebot.permission import Permission
@@ -19,9 +19,6 @@ from nonebot.rule import Rule, command, keyword, regex
 
 from ATRI.exceptions import ReadFileError, WriteError
 
-if TYPE_CHECKING:
-    from nonebot.adapters import Bot, Event
-
 
 SERVICE_DIR = Path(".") / "data" / "service"
 SERVICES_DIR = SERVICE_DIR / "services"
@@ -69,7 +66,7 @@ class Service:
     def __init__(
         self,
         service: str,
-        docs: str = None,
+        docs: str,
         only_admin: bool = False,
         rule: Optional[Union[Rule, T_RuleChecker]] = None,
         permission: Optional[Permission] = None,
@@ -77,6 +74,7 @@ class Service:
         temp: bool = False,
         priority: int = 1,
         state: Optional[T_State] = None,
+        main_cmd: str = str(),
     ):
         self.service = service
         self.docs = docs
@@ -87,13 +85,9 @@ class Service:
         self.temp = temp
         self.priority = priority
         self.state = state
+        self.main_cmd = (main_cmd,)
 
-    def _generate_service_config(self, service: str = None, docs: str = None) -> None:
-        if not service:
-            service = self.service
-        if not docs:
-            docs = self.docs or str()
-
+    def _generate_service_config(self, service: str, docs: str = str()) -> None:
         path = SERVICES_DIR / f"{service}.json"
         data = ServiceInfo(
             service=service,
@@ -110,31 +104,28 @@ class Service:
         except WriteError:
             raise WriteError("Write service info failed!")
 
-    def save_service(self, service_data: dict, service: str = None) -> None:
+    def save_service(self, service_data: dict, service: str) -> None:
         if not service:
             service = self.service
 
         path = SERVICES_DIR / f"{service}.json"
         if not path.is_file():
-            self._generate_service_config()
+            self._generate_service_config(service, self.docs)
 
         with open(path, "w", encoding="utf-8") as w:
             w.write(json.dumps(service_data, indent=4))
 
-    def load_service(self, service: str = None) -> dict:
-        if not service:
-            service = self.service
-
+    def load_service(self, service: str) -> dict:
         path = SERVICES_DIR / f"{service}.json"
         if not path.is_file():
-            self._generate_service_config()
+            self._generate_service_config(service, self.docs)
 
         try:
             data = json.loads(path.read_bytes())
         except ReadFileError:
             with open(path, "w", encoding="utf-8") as w:
                 w.write(json.dumps({}))
-            self._generate_service_config()
+            self._generate_service_config(service, self.docs)
             data = json.loads(path.read_bytes())
         return data
 
@@ -142,25 +133,25 @@ class Service:
         data = self.load_service(self.service)
         temp_data: dict = data["cmd_list"]
         temp_data.update(cmds)
-        self.save_service(data)
+        self.save_service(data, self.service)
 
     def _load_cmds(self) -> dict:
         path = SERVICES_DIR / f"{self.service}.json"
         if not path.is_file():
-            self._generate_service_config()
+            self._generate_service_config(self.service, self.docs)
 
         data = json.loads(path.read_bytes())
         return data["cmd_list"]
 
     def on_message(
         self,
-        name: str = None,
+        name: str = str(),
         docs: str = str(),
         rule: Optional[Union[Rule, T_RuleChecker]] = None,
         permission: Optional[Union[Permission, T_PermissionChecker]] = None,
         handlers: Optional[List[Union[T_Handler, Dependent]]] = None,
         block: bool = True,
-        priority: int = None,
+        priority: int = 1,
         state: Optional[T_State] = None,
     ) -> Type[Matcher]:
         if not rule:
@@ -169,8 +160,6 @@ class Service:
             permission = self.permission
         if not handlers:
             handlers = self.handlers
-        if not priority:
-            priority = self.priority
         if not state:
             state = self.state
 
@@ -253,11 +242,13 @@ class Service:
         if not aliases:
             aliases = set()
 
+        if isinstance(cmd, tuple):
+            cmd = ".".join(map(str, cmd))
+
         cmd_list[cmd] = CommandInfo(
             type="command", docs=docs, aliases=list(aliases)
         ).dict()
         self._save_cmds(cmd_list)
-
         commands = set([cmd]) | (aliases or set())
         return self.on_message(rule=command(*commands) & rule, block=True, **kwargs)
 
@@ -297,6 +288,15 @@ class Service:
 
         return self.on_message(rule=regex(pattern, flags) & rule, **kwargs)
 
+    def cmd_as_group(self, cmd: str, docs: str, **kwargs) -> Type[Matcher]:
+        sub_cmd = (cmd,) if isinstance(cmd, str) else cmd
+        _cmd = self.main_cmd + sub_cmd
+
+        if "aliases" in kwargs:
+            del kwargs["aliases"]
+
+        return self.on_command(_cmd, docs, **kwargs)
+
 
 class ServiceTools(object):
     @staticmethod
@@ -327,7 +327,7 @@ class ServiceTools(object):
         return data
 
     @classmethod
-    def auth_service(cls, service, user_id: str = None, group_id: str = None) -> bool:
+    def auth_service(cls, service, user_id: str = str(), group_id: str = str()) -> bool:
         data = cls.load_service(service)
 
         auth_global = data.get("enabled", True)
-- 
cgit v1.2.3


From 138513235bdcb8dfde5f241273a7cb687606dc1a Mon Sep 17 00:00:00 2001
From: Kyomotoi <kyomotoiowo@gmail.com>
Date: Sun, 27 Mar 2022 15:44:25 +0800
Subject: =?UTF-8?q?=F0=9F=90=9B=20=E4=BF=AE=E5=A4=8D=E5=9B=A0=E8=AF=B7?=
 =?UTF-8?q?=E6=B1=82=E8=B6=85=E6=97=B6=E8=80=8C=E5=BC=BA=E5=88=B6=E9=80=80?=
 =?UTF-8?q?=E5=87=BA?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 ATRI/plugins/essential.py | 23 +++++++++++++----------
 1 file changed, 13 insertions(+), 10 deletions(-)

(limited to 'ATRI')

diff --git a/ATRI/plugins/essential.py b/ATRI/plugins/essential.py
index 6a2ee22..242e267 100644
--- a/ATRI/plugins/essential.py
+++ b/ATRI/plugins/essential.py
@@ -53,15 +53,18 @@ os.makedirs(TEMP_PATH, exist_ok=True)
 async def startup():
     log.info(f"Now running: {ATRI.__version__}")
 
-    log.info("Starting to check update...")
-    log.info(await CheckUpdate.show_latest_commit_info())
-    sleep(1)
-
-    l_v, l_v_t = await CheckUpdate.show_latest_version()
-    if l_v != ATRI.__version__:
-        log.warning("New version has been released, please update.")
-        log.warning(f"Latest version: {l_v} Update time: {l_v_t}")
-        sleep(3)
+    try:
+        log.info("Starting to check update...")
+        log.info(await CheckUpdate.show_latest_commit_info())
+        sleep(1)
+
+        l_v, l_v_t = await CheckUpdate.show_latest_version()
+        if l_v != ATRI.__version__:
+            log.warning("New version has been released, please update.")
+            log.warning(f"Latest version: {l_v} Update time: {l_v_t}")
+            sleep(3)
+    except Exception:
+        log.error("检查 更新/最新推送 失败...")
 
     log.info("アトリは、高性能ですから!")
 
@@ -357,7 +360,7 @@ async def _():
     await acc_recall.finish("现在可以接受撤回信息啦!")
 
 
-@scheduler.scheduled_job("interval", name="清除缓存", minutes=30, misfire_grace_time=5)
+@scheduler.scheduled_job("interval", name="清除缓存", minutes=30, misfire_grace_time=5)  # type: ignore
 async def _clear_cache():
     try:
         shutil.rmtree(TEMP_PATH)
-- 
cgit v1.2.3


From 8474e13ebb99f1115cf48041e39528327288c9d0 Mon Sep 17 00:00:00 2001
From: Kyomotoi <kyomotoiowo@gmail.com>
Date: Sun, 27 Mar 2022 15:25:59 +0800
Subject: =?UTF-8?q?=F0=9F=9A=A8=20=E5=AE=89=E6=8A=9A=20pylance?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 ATRI/plugins/anime_search.py         |  9 ++++-----
 ATRI/plugins/applet/data_source.py   | 10 +++++-----
 ATRI/plugins/chat/data_source.py     |  6 +-----
 ATRI/plugins/funny/data_source.py    |  7 +------
 ATRI/plugins/manage/data_source.py   |  5 ++---
 ATRI/plugins/repo.py                 |  2 +-
 ATRI/plugins/saucenao/data_source.py |  9 +++------
 ATRI/plugins/status/__init__.py      |  2 +-
 ATRI/plugins/status/data_source.py   |  5 +----
 9 files changed, 19 insertions(+), 36 deletions(-)

(limited to 'ATRI')

diff --git a/ATRI/plugins/anime_search.py b/ATRI/plugins/anime_search.py
index 3bfeedb..773748d 100644
--- a/ATRI/plugins/anime_search.py
+++ b/ATRI/plugins/anime_search.py
@@ -8,17 +8,16 @@ from ATRI.rule import is_in_service
 from ATRI.utils import request, Translate
 from ATRI.exceptions import RequestError
 
+
 URL = "https://api.trace.moe/search?anilistInfo=true&url="
 _anime_flmt_notice = choice(["慢...慢一..点❤", "冷静1下", "歇会歇会~~"])
 
-__doc__ = """
-通过一张图片搜索你需要的番!据说里*也可以
-"""
-
 
 class Anime(Service):
     def __init__(self):
-        Service.__init__(self, "以图搜番", __doc__, rule=is_in_service("以图搜番"))
+        Service.__init__(
+            self, "以图搜番", "通过一张图片搜索你需要的番!据说里*也可以", rule=is_in_service("以图搜番")
+        )
 
     @staticmethod
     async def _request(url: str) -> dict:
diff --git a/ATRI/plugins/applet/data_source.py b/ATRI/plugins/applet/data_source.py
index 3fc1bc5..e94c0d9 100644
--- a/ATRI/plugins/applet/data_source.py
+++ b/ATRI/plugins/applet/data_source.py
@@ -15,18 +15,18 @@ s = [11, 10, 3, 8, 4, 6]
 xor = 177451812
 add = 8728348608
 
-__doc__ = "啥b腾讯小程序给👴爪巴\n目前只整了b站的"
-
 
 class Applet(Service):
     def __init__(self):
-        Service.__init__(self, "小程序处理", __doc__, rule=is_in_service("小程序处理"))
+        Service.__init__(
+            self, "小程序处理", "啥b腾讯小程序给👴爪巴\n目前只整了b站的", rule=is_in_service("小程序处理")
+        )
 
     @staticmethod
     def _bv_dec(x) -> str:
         r = 0
         for i in range(6):
-            r += tr[x[s[i]]] * 58 ** i
+            r += tr[x[s[i]]] * 58**i
         return str((r - add) ^ xor)
 
     @staticmethod
@@ -34,7 +34,7 @@ class Applet(Service):
         x = (x ^ xor) + add
         r = list("BV1  4 1 7  ")
         for i in range(6):
-            r[s[i]] = table[x // 58 ** i % 58]
+            r[s[i]] = table[x // 58**i % 58]
         return "".join(r)
 
     @staticmethod
diff --git a/ATRI/plugins/chat/data_source.py b/ATRI/plugins/chat/data_source.py
index 576db03..70c6345 100644
--- a/ATRI/plugins/chat/data_source.py
+++ b/ATRI/plugins/chat/data_source.py
@@ -11,10 +11,6 @@ from ATRI.utils import request
 from ATRI.exceptions import ReadFileError, WriteError
 
 
-__doc__ = """
-好像有点涩?
-"""
-
 CHAT_PATH = Path(".") / "data" / "database" / "chat"
 os.makedirs(CHAT_PATH, exist_ok=True)
 KIMO_URL = "https://cdn.jsdelivr.net/gh/Kyomotoi/AnimeThesaurus/data.json"
@@ -23,7 +19,7 @@ KIMO_URL = "https://cdn.jsdelivr.net/gh/Kyomotoi/AnimeThesaurus/data.json"
 class Chat(Service):
     def __init__(self):
         Service.__init__(
-            self, "闲聊", __doc__, rule=to_bot() & is_in_service("闲聊"), priority=5
+            self, "闲聊", "好像有点涩?", rule=to_bot() & is_in_service("闲聊"), priority=5
         )
 
     @staticmethod
diff --git a/ATRI/plugins/funny/data_source.py b/ATRI/plugins/funny/data_source.py
index 8edc88a..75fa4ee 100644
--- a/ATRI/plugins/funny/data_source.py
+++ b/ATRI/plugins/funny/data_source.py
@@ -17,14 +17,9 @@ FUNNY_DIR = Path(".") / "data"
 os.makedirs(FUNNY_DIR, exist_ok=True)
 
 
-__doc__ = """
-乐1乐,莫当真
-"""
-
-
 class Funny(Service):
     def __init__(self):
-        Service.__init__(self, "乐", __doc__, rule=is_in_service("乐"))
+        Service.__init__(self, "乐", "乐1乐,莫当真", rule=is_in_service("乐"))
 
     @staticmethod
     async def idk_laugh(name: str) -> str:
diff --git a/ATRI/plugins/manage/data_source.py b/ATRI/plugins/manage/data_source.py
index bc9f801..395a165 100644
--- a/ATRI/plugins/manage/data_source.py
+++ b/ATRI/plugins/manage/data_source.py
@@ -6,6 +6,7 @@ from datetime import datetime
 from ATRI.service import Service, ServiceTools
 from ATRI.exceptions import ReadFileError, load_error
 
+
 MANAGE_DIR = Path(".") / "data" / "database" / "manege"
 ESSENTIAL_DIR = Path(".") / "data" / "database" / "essential"
 os.makedirs(MANAGE_DIR, exist_ok=True)
@@ -17,12 +18,10 @@ Time: {time}
 {content}
 """.strip()
 
-__doc__ = """控制bot的各项服务"""
-
 
 class Manage(Service):
     def __init__(self):
-        Service.__init__(self, "管理", __doc__, True)
+        Service.__init__(self, "管理", "控制bot的各项服务", True)
 
     @staticmethod
     def _load_block_user_list() -> dict:
diff --git a/ATRI/plugins/repo.py b/ATRI/plugins/repo.py
index 9c5818a..7087afa 100644
--- a/ATRI/plugins/repo.py
+++ b/ATRI/plugins/repo.py
@@ -15,7 +15,7 @@ _repo_flmt_notice = choice(["慢...慢一..点❤", "冷静1下", "歇会歇会~
 REPO_FORMAT = """
 来自用户{user}反馈:
 {msg}
-"""
+""".strip()
 
 
 class Repo(Service):
diff --git a/ATRI/plugins/saucenao/data_source.py b/ATRI/plugins/saucenao/data_source.py
index 80b6b52..738c647 100644
--- a/ATRI/plugins/saucenao/data_source.py
+++ b/ATRI/plugins/saucenao/data_source.py
@@ -5,24 +5,21 @@ from ATRI.rule import is_in_service
 from ATRI.exceptions import RequestError
 from ATRI.utils import request
 
-URL = "https://saucenao.com/search.php"
 
-__doc__ = """
-以图搜图,仅限二刺螈
-"""
+URL = "https://saucenao.com/search.php"
 
 
 class SaouceNao(Service):
     def __init__(
         self,
-        api_key: str = None,
+        api_key: str = str(),
         output_type=2,
         testmode=1,
         dbmaski=32768,
         db=5,
         numres=5,
     ):
-        Service.__init__(self, "以图搜图", __doc__, rule=is_in_service("以图搜图"))
+        Service.__init__(self, "以图搜图", "以图搜图,仅限二刺螈", rule=is_in_service("以图搜图"))
 
         params = dict()
         params["api_key"] = api_key
diff --git a/ATRI/plugins/status/__init__.py b/ATRI/plugins/status/__init__.py
index 3e18e1d..f62c86a 100644
--- a/ATRI/plugins/status/__init__.py
+++ b/ATRI/plugins/status/__init__.py
@@ -22,7 +22,7 @@ async def _status():
 info_msg = "アトリは高性能ですから!"
 
 
-@scheduler.scheduled_job("interval", name="状态检查", minutes=10, misfire_grace_time=15)
+@scheduler.scheduled_job("interval", name="状态检查", minutes=10, misfire_grace_time=15)  # type: ignore
 async def _status_checking():
     msg, stat = IsSurvive().get_status()
     if not stat:
diff --git a/ATRI/plugins/status/data_source.py b/ATRI/plugins/status/data_source.py
index 74882de..68ad216 100644
--- a/ATRI/plugins/status/data_source.py
+++ b/ATRI/plugins/status/data_source.py
@@ -8,12 +8,9 @@ from ATRI.rule import is_in_service
 from ATRI.exceptions import GetStatusError
 
 
-__doc__ = "检查咱自身状态"
-
-
 class IsSurvive(Service):
     def __init__(self):
-        Service.__init__(self, "状态", __doc__, rule=is_in_service("状态"))
+        Service.__init__(self, "状态", "检查自身状态", rule=is_in_service("状态"))
 
     @staticmethod
     def ping() -> str:
-- 
cgit v1.2.3


From 66100f025f6705d68cf40549b5c2057d8426871f Mon Sep 17 00:00:00 2001
From: Kyomotoi <kyomotoiowo@gmail.com>
Date: Sun, 27 Mar 2022 15:27:34 +0800
Subject: =?UTF-8?q?=F0=9F=9A=B8=F0=9F=9A=A8=20=E4=BC=98=E5=8C=96=E7=94=A8?=
 =?UTF-8?q?=E6=88=B7=E4=BD=93=E9=AA=8C=20&=20=E5=AE=89=E6=8A=9A=20pylance?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 ATRI/plugins/code_runner/__init__.py    | 38 +++++++++++++++++++++------------
 ATRI/plugins/code_runner/data_source.py |  8 +++----
 ATRI/plugins/help/__init__.py           | 27 +++++++++++------------
 ATRI/plugins/help/data_source.py        |  4 ++--
 4 files changed, 41 insertions(+), 36 deletions(-)

(limited to 'ATRI')

diff --git a/ATRI/plugins/code_runner/__init__.py b/ATRI/plugins/code_runner/__init__.py
index adf6407..77240ec 100644
--- a/ATRI/plugins/code_runner/__init__.py
+++ b/ATRI/plugins/code_runner/__init__.py
@@ -11,33 +11,43 @@ from .data_source import CodeRunner
 _flmt_notice = choice(["慢...慢一..点❤", "冷静1下", "歇会歇会~~"])
 
 
-code_runner = CodeRunner().on_command("/code", "在线运行一段代码,帮助:/code help")
+code_runner = CodeRunner().on_command("/code", "在线运行一段代码,获取帮助:/code.help")
 
 
 @code_runner.handle([Cooldown(5, prompt=_flmt_notice)])
-async def _code_runner(
-    matcher: Matcher, event: MessageEvent, args: Message = CommandArg()
-):
-    user_id = event.get_user_id()
+async def _code_runner(matcher: Matcher, args: Message = CommandArg()):
     msg = args.extract_plain_text()
 
     if msg:
         matcher.set_arg("opt", args)
     else:
-        content = f"> {MessageSegment.at(user_id)}\n" + "请键入 /code help 以获取帮助~!"
+        content = "请键入 /code.help 以获取帮助~!"
         await code_runner.finish(Message(content))
 
 
-@code_runner.got("opt")
+@code_runner.got("opt", prompt="需要运行的语言及代码?\n获取帮助:/code.help")
 async def _(event: MessageEvent, opt: str = ArgPlainText("opt")):
     user_id = event.get_user_id()
-    msg = opt.split("\n")
 
-    if msg[0] == "help":
-        content = f"> {MessageSegment.at(user_id)}\n" + "请键入 /code help 以获取帮助~!"
-    elif msg[0] == "list":
-        content = f"> {MessageSegment.at(user_id)}\n" + CodeRunner().list_supp_lang()
-    else:
-        content = MessageSegment.at(user_id) + await CodeRunner().runner(unescape(opt))
+    # 拯救傻瓜用户
+    if opt == "/code.help":
+        await code_runner.finish(CodeRunner().help())
 
+    content = MessageSegment.at(user_id) + str(await CodeRunner().runner(unescape(opt)))
     await code_runner.finish(Message(content))
+
+
+code_runner_helper = CodeRunner().cmd_as_group("help", "使用说明")
+
+
+@code_runner_helper.handle()
+async def _():
+    await code_runner_helper.finish(CodeRunner().help())
+
+
+code_supp_list = CodeRunner().cmd_as_group("list", "查看支持的语言")
+
+
+@code_supp_list.handle()
+async def _():
+    await code_supp_list.finish(CodeRunner().list_supp_lang())
diff --git a/ATRI/plugins/code_runner/data_source.py b/ATRI/plugins/code_runner/data_source.py
index bf3d8b2..87ae792 100644
--- a/ATRI/plugins/code_runner/data_source.py
+++ b/ATRI/plugins/code_runner/data_source.py
@@ -34,13 +34,11 @@ SUPPORTED_LANGUAGES = {
 }
 
 
-__doc__ = """在线跑代码
-"""
-
-
 class CodeRunner(Service):
     def __init__(self):
-        Service.__init__(self, "在线跑代码", __doc__, rule=is_in_service("在线跑代码"))
+        Service.__init__(
+            self, "在线跑代码", "在线跑代码", rule=is_in_service("在线跑代码"), main_cmd="/code"
+        )
 
     @staticmethod
     def help() -> str:
diff --git a/ATRI/plugins/help/__init__.py b/ATRI/plugins/help/__init__.py
index d4b8b36..c6f915e 100644
--- a/ATRI/plugins/help/__init__.py
+++ b/ATRI/plugins/help/__init__.py
@@ -3,34 +3,31 @@ from nonebot.adapters.onebot.v11 import MessageEvent
 from .data_source import Helper
 
 
-main_help = Helper().on_command("菜单", "获取食用bot的方法", aliases={"menu"})
+menu = Helper().on_command("菜单", "获取食用bot的方法", aliases={"menu"})
 
 
-@main_help.handle()
-async def _main_help():
-    repo = Helper().menu()
-    await main_help.finish(repo)
+@menu.handle()
+async def _():
+    await menu.finish(Helper().menu())
 
 
-about_me = Helper().on_command("关于", "获取关于bot的信息", aliases={"about"})
+about = Helper().on_command("关于", "获取关于bot的信息", aliases={"about"})
 
 
-@about_me.handle()
-async def _about_me():
-    repo = Helper().about()
-    await about_me.finish(repo)
+@about.handle()
+async def _():
+    await about.finish(Helper().about())
 
 
-service_list = Helper().on_command("服务列表", "查看所有可用服务", aliases={"功能列表"})
+service_list = Helper().on_command("服务列表", "获取服务列表", aliases={"功能列表"})
 
 
 @service_list.handle()
-async def _service_list():
-    repo = Helper().service_list()
-    await service_list.finish(repo)
+async def _():
+    await service_list.finish(Helper().service_list())
 
 
-service_info = Helper().on_command("帮助", "获取服务详细帮助", aliases={"help"})
+service_info = Helper().on_command("帮助", "获取对应服务详细信息", aliases={"help"})
 
 
 @service_info.handle()
diff --git a/ATRI/plugins/help/data_source.py b/ATRI/plugins/help/data_source.py
index f96d59e..e3dd1ff 100644
--- a/ATRI/plugins/help/data_source.py
+++ b/ATRI/plugins/help/data_source.py
@@ -72,7 +72,7 @@ class Helper(Service):
                 )
         table = tabulate(
             services,
-            headers=["服务名称", "开启状态", "仅支持管理员"],
+            headers=["服务名称", "开启状态(全局)", "仅支持管理员"],
             tablefmt="plain",
             showindex=True,
         )
@@ -91,7 +91,7 @@ class Helper(Service):
         service_enabled = data.get("enabled", True)
 
         _service_cmd_list = list(data.get("cmd_list", {"error"}))
-        service_cmd_list = "、".join(map(str, _service_cmd_list))
+        service_cmd_list = "\n".join(map(str, _service_cmd_list))
 
         repo = SERVICE_INFO_FORMAT.format(
             service=service_name,
-- 
cgit v1.2.3


From d4e5574755a88638f7d592532ad2a13c9b15c23e Mon Sep 17 00:00:00 2001
From: Kyomotoi <kyomotoiowo@gmail.com>
Date: Sun, 27 Mar 2022 15:28:55 +0800
Subject: =?UTF-8?q?=F0=9F=94=A5=F0=9F=9A=A8=20=E5=88=A0=E9=99=A4=E9=83=A8?=
 =?UTF-8?q?=E5=88=86=E4=BB=A3=E7=A0=81=20&=20=E5=AE=89=E6=8A=9A=20pylance?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 ATRI/plugins/bilibili_dynamic/__init__.py    | 32 +++++++++++-----------------
 ATRI/plugins/bilibili_dynamic/data_source.py | 32 ++++++++++++++--------------
 2 files changed, 29 insertions(+), 35 deletions(-)

(limited to 'ATRI')

diff --git a/ATRI/plugins/bilibili_dynamic/__init__.py b/ATRI/plugins/bilibili_dynamic/__init__.py
index f1ac8d2..d69f81b 100644
--- a/ATRI/plugins/bilibili_dynamic/__init__.py
+++ b/ATRI/plugins/bilibili_dynamic/__init__.py
@@ -1,22 +1,24 @@
+import re
+from tabulate import tabulate
+from datetime import datetime, timedelta
+
 import pytz
 from apscheduler.triggers.base import BaseTrigger
 from apscheduler.triggers.combining import AndTrigger
 from apscheduler.triggers.interval import IntervalTrigger
 
-from ATRI.utils.apscheduler import scheduler
-from ATRI.utils import timestamp2datetime
-
 from nonebot.params import State
 from nonebot.adapters.onebot.v11 import MessageSegment, GroupMessageEvent, Message
 from nonebot.typing import T_State
 from nonebot import get_bot
 
-from .data_source import BilibiliDynamicSubscriptor
-import re
-from tabulate import tabulate
-from datetime import datetime, timedelta
+from ATRI.utils.apscheduler import scheduler
+from ATRI.utils import timestamp2datetime
 from ATRI.log import logger
 
+from .data_source import BilibiliDynamicSubscriptor
+
+
 bilibili_dynamic = BilibiliDynamicSubscriptor().on_command(
     "/bilibili_dynamic", "b站动态订阅助手", aliases={"/bd", "b站动态"}
 )
@@ -39,7 +41,6 @@ def help() -> str:
 @bilibili_dynamic.handle()
 async def _menu(event: GroupMessageEvent, state: T_State = State()):
     args = str(event.get_plaintext()).strip().lower().split()[1:]
-    # print(args)
     if not args:
         await bilibili_dynamic.finish(help())
     elif args and len(args) == 1:
@@ -58,7 +59,6 @@ async def handle_subcommand(event: GroupMessageEvent, state: T_State = State()):
 
     if state["sub_command"] == "订阅列表":
         subscriptor = BilibiliDynamicSubscriptor()
-        # print(event.group_id)
         r = await subscriptor.get_subscriptions(query_map={"groupid": event.group_id})
         subs = []
         for s in r:
@@ -80,8 +80,6 @@ async def handle_uid(event: GroupMessageEvent, state: T_State = State()):
 
     if uid == "-1":
         await bilibili_dynamic.finish("已经成功退出订阅~")
-    # print(state)
-    # print(uid)
     if not re.match(r"^\d+$", uid):
         await bilibili_dynamic.reject("这似乎不是UID呢, 请重新输入:")
     uid = int(uid)
@@ -107,7 +105,6 @@ async def handle_uid(event: GroupMessageEvent, state: T_State = State()):
                 )
             )
         success = await subscriptor.add_subscription(uid, event.group_id)
-        print(success)
         success = success and (
             await subscriptor.update_subscription_by_uid(
                 uid=uid,
@@ -141,9 +138,9 @@ tq = Queue()
 class BilibiliDynamicCheckEnabledTrigger(BaseTrigger):
     # 自定义trigger 保证服务开启
     # 实现abstract方法 <get_next_fire_time>
-    def get_next_fire_time(self, previous_fire_time, now):
+    def get_next_fire_time(self, now):
         subscriptor = BilibiliDynamicSubscriptor()
-        config = subscriptor.load_service()
+        config = subscriptor.load_service("b站动态订阅")
         if config["enabled"] == False:
             return None
         else:
@@ -156,8 +153,8 @@ class BilibiliDynamicCheckEnabledTrigger(BaseTrigger):
 @scheduler.scheduled_job(
     AndTrigger([IntervalTrigger(seconds=10), BilibiliDynamicCheckEnabledTrigger()]),
     name="b站动态检查",
-    max_instances=3,
-    misfire_grace_time=60,
+    max_instances=3,  # type: ignore
+    misfire_grace_time=60,  # type: ignore
 )
 async def _check_dynamic():
     from ATRI.database.models import Subscription
@@ -171,7 +168,6 @@ async def _check_dynamic():
         d: Subscription = tq.get()
         logger.info("准备查询UP【{up}】的动态 队列剩余{size}".format(up=d.nickname, size=tq.qsize()))
         ts = int(d.last_update.timestamp())
-        # logger.info("上一次更新的时间戳{time}".format(time=ts))
         info: dict = await subscriptor.get_recent_dynamic_by_uid(d.uid)
         res = []
         if info:
@@ -181,11 +177,9 @@ async def _check_dynamic():
         if len(res) == 0:
             logger.warning("获取UP【{up}】的动态为空".format(up=d.nickname))
         for i in res:
-            # logger.info("获取UP【{up}】的动态,时间{time},内容{content}".format(up=d.nickname, time=i["timestamp"],content=i["content"][:20]))
             i["name"] = d.nickname
             if ts < i["timestamp"]:
                 text, pic_url = subscriptor.generate_output(pattern=i)
-                # print(text,pic_url)
                 output = Message(
                     [MessageSegment.text(text), MessageSegment.image(pic_url)]
                 )
diff --git a/ATRI/plugins/bilibili_dynamic/data_source.py b/ATRI/plugins/bilibili_dynamic/data_source.py
index 49ffce7..a419b45 100644
--- a/ATRI/plugins/bilibili_dynamic/data_source.py
+++ b/ATRI/plugins/bilibili_dynamic/data_source.py
@@ -11,13 +11,11 @@ import asyncio
 from typing import Any
 from operator import itemgetter
 
-__doc__ = """b站订阅动态助手
-"""
 
 __session_pool = {}
 
 
-def get_api(field: str):
+def get_api(field: str) -> dict:
     """
     获取 API。
 
@@ -33,9 +31,11 @@ def get_api(field: str):
     if os.path.exists(path):
         with open(path, encoding="utf8") as f:
             return json.loads(f.read())
+    else:
+        return dict()
 
 
-API = get_api("user")
+API: dict = get_api("user")
 
 
 def get_session():
@@ -57,12 +57,12 @@ def get_session():
 async def bilibili_request(
     method: str,
     url: str,
-    params: dict = None,
+    params: dict = dict(),
     data: Any = None,
     no_csrf: bool = False,
     json_body: bool = False,
     **kwargs,
-):
+) -> dict:
     """
     向接口发送请求。
 
@@ -130,21 +130,21 @@ async def bilibili_request(
         # 检查响应头 Content-Length
         content_length = resp.headers.get("content-length")
         if content_length and int(content_length) == 0:
-            return None
+            return dict()
 
         # 检查响应头 Content-Type
         content_type = resp.headers.get("content-type")
 
         # 不是 application/json
-        if content_type.lower().index("application/json") == -1:
+        if content_type.lower().index("application/json") == -1:  # type: ignore
             raise Exception("响应不是 application/json 类型")
 
         raw_data = await resp.text()
-        resp_data: dict
+        resp_data: dict = dict()
 
         if "callback" in params:
             # JSONP 请求
-            resp_data = json.loads(re.match("^.*?({.*}).*$", raw_data, re.S).group(1))
+            resp_data = json.loads(re.match("^.*?({.*}).*$", raw_data, re.S).group(1))  # type: ignore
         else:
             # JSON
             resp_data = json.loads(raw_data)
@@ -181,9 +181,9 @@ class User:
         """
         self.uid = uid
 
-        self.__self_info = None
+        self.__self_info = None  # 暂时无用
 
-    async def get_user_info(self):
+    async def get_user_info(self) -> dict:
         """
         获取用户信息(昵称,性别,生日,签名,头像 URL,空间横幅 URL 等)
 
@@ -216,7 +216,7 @@ class User:
             "offset_dynamic_id": offset,
             "need_top": 1 if need_top else 0,
         }
-        data = await bilibili_request("GET", url=api["url"], params=params)
+        data: dict = await bilibili_request("GET", url=api["url"], params=params)
         # card 字段自动转换成 JSON。
         if "cards" in data:
             for card in data["cards"]:
@@ -227,7 +227,7 @@ class User:
 
 class BilibiliDynamicSubscriptor(Service):
     def __init__(self):
-        Service.__init__(self, "b站动态订阅", __doc__, rule=is_in_service("b站动态订阅"))
+        Service.__init__(self, "b站动态订阅", "b站订阅动态助手", rule=is_in_service("b站动态订阅"))
 
     async def add_subscription(self, uid: int, groupid: int) -> bool:
         async with DB() as db:
@@ -261,7 +261,7 @@ class BilibiliDynamicSubscriptor(Service):
     async def get_upname_by_uid(self, uid: int) -> str:
         try:
             u = User(uid)
-            info = await u.get_user_info()
+            info: dict = await u.get_user_info()
             return info.get("name")
         except:
             return ""
@@ -334,7 +334,7 @@ class BilibiliDynamicSubscriptor(Service):
         ret = sorted(ret, key=itemgetter("timestamp"))
         return ret
 
-    def generate_output(self, pattern: dict) -> (str, str):
+    def generate_output(self, pattern: dict) -> tuple:
         # 限制摘要的字数
         abstractLimit = 40
         text_part = """【UP名称】{name}\n【动态类型】{dynamic_type}\n【时间】{time}\n【内容摘要】{content}\n""".format(
-- 
cgit v1.2.3


From bd699cc615b65168864d940fd75420fde4e172ae Mon Sep 17 00:00:00 2001
From: Lint Action <noreply@github.com>
Date: Sun, 27 Mar 2022 07:48:00 +0000
Subject: =?UTF-8?q?:rotating=5Flight:=20=E8=87=AA=E5=8A=A8=E8=BF=9B?=
 =?UTF-8?q?=E8=A1=8C=E4=BB=A3=E7=A0=81=E6=A0=BC=E5=BC=8F=E5=8C=96?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 ATRI/plugins/applet/data_source.py | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

(limited to 'ATRI')

diff --git a/ATRI/plugins/applet/data_source.py b/ATRI/plugins/applet/data_source.py
index e94c0d9..60ca581 100644
--- a/ATRI/plugins/applet/data_source.py
+++ b/ATRI/plugins/applet/data_source.py
@@ -26,7 +26,7 @@ class Applet(Service):
     def _bv_dec(x) -> str:
         r = 0
         for i in range(6):
-            r += tr[x[s[i]]] * 58**i
+            r += tr[x[s[i]]] * 58 ** i
         return str((r - add) ^ xor)
 
     @staticmethod
@@ -34,7 +34,7 @@ class Applet(Service):
         x = (x ^ xor) + add
         r = list("BV1  4 1 7  ")
         for i in range(6):
-            r[s[i]] = table[x // 58**i % 58]
+            r[s[i]] = table[x // 58 ** i % 58]
         return "".join(r)
 
     @staticmethod
-- 
cgit v1.2.3


From d07348c2a2dd551c00aa330fcc1015155854e874 Mon Sep 17 00:00:00 2001
From: Kyomotoi <kyomotoiowo@gmail.com>
Date: Mon, 4 Apr 2022 17:03:25 +0800
Subject: =?UTF-8?q?=F0=9F=9A=B8=20=E6=9B=B4=E6=94=B9=E6=95=B0=E6=8D=AE?=
 =?UTF-8?q?=E5=BA=93=E4=BD=8D=E7=BD=AE=20=E6=96=B9=E9=9D=A2=E6=9B=B4?=
 =?UTF-8?q?=E6=96=B0=E6=97=B6=E4=B8=80=E9=94=AE=E8=BF=81=E7=A7=BB?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 ATRI/database/db.py | 9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)

(limited to 'ATRI')

diff --git a/ATRI/database/db.py b/ATRI/database/db.py
index c2aa015..68db8cf 100644
--- a/ATRI/database/db.py
+++ b/ATRI/database/db.py
@@ -1,7 +1,12 @@
+from pathlib import Path
 from tortoise import Tortoise
+from nonebot import get_driver
 
 from ATRI.database import models
-from nonebot import get_driver
+
+
+DB_DIR = Path(".") / "data" / "database" / "sql"
+DB_DIR.mkdir(exist_ok=True)
 
 
 # 关于数据库的操作类,只实现与数据库有关的CRUD
@@ -17,7 +22,7 @@ class DB:
         from ATRI.database import models
 
         await Tortoise.init(
-            db_url="sqlite://ATRI/database/db.sqlite3",
+            db_url=f"sqlite://{DB_DIR}/db.sqlite3",
             modules={"models": [locals()["models"]]},
         )
         # Generate the schema
-- 
cgit v1.2.3


From 1caf5ae8bb3e0560451f967f276ff1291a80d1dd Mon Sep 17 00:00:00 2001
From: Kyomotoi <kyomotoiowo@gmail.com>
Date: Mon, 4 Apr 2022 17:06:09 +0800
Subject: =?UTF-8?q?=F0=9F=A7=B1=20=E9=92=88=E5=AF=B9=20=20=E9=83=A8?=
 =?UTF-8?q?=E5=88=86=E5=B0=8F=E4=BF=AE=E6=94=B9?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 ATRI/plugins/essential.py       |  4 ++++
 ATRI/plugins/status/__init__.py |  2 +-
 ATRI/utils/apscheduler.py       | 23 +----------------------
 3 files changed, 6 insertions(+), 23 deletions(-)

(limited to 'ATRI')

diff --git a/ATRI/plugins/essential.py b/ATRI/plugins/essential.py
index 242e267..37c18a4 100644
--- a/ATRI/plugins/essential.py
+++ b/ATRI/plugins/essential.py
@@ -66,6 +66,10 @@ async def startup():
     except Exception:
         log.error("检查 更新/最新推送 失败...")
 
+    if not scheduler.running:
+        scheduler.start()
+        log.info("Scheduler Started.")
+
     log.info("アトリは、高性能ですから!")
 
 
diff --git a/ATRI/plugins/status/__init__.py b/ATRI/plugins/status/__init__.py
index f62c86a..05ece79 100644
--- a/ATRI/plugins/status/__init__.py
+++ b/ATRI/plugins/status/__init__.py
@@ -23,7 +23,7 @@ info_msg = "アトリは高性能ですから!"
 
 
 @scheduler.scheduled_job("interval", name="状态检查", minutes=10, misfire_grace_time=15)  # type: ignore
-async def _status_checking():
+async def _check_runtime():
     msg, stat = IsSurvive().get_status()
     if not stat:
         await status.finish(msg)
diff --git a/ATRI/utils/apscheduler.py b/ATRI/utils/apscheduler.py
index 186ff8e..e1959c1 100644
--- a/ATRI/utils/apscheduler.py
+++ b/ATRI/utils/apscheduler.py
@@ -1,34 +1,13 @@
-"""
-Fork from: https://github.com/nonebot/plugin-apscheduler
-"""
 import logging
 from apscheduler.schedulers.asyncio import AsyncIOScheduler
 
-from nonebot import get_driver
-from nonebot.log import logger, LoguruHandler
+from nonebot.log import LoguruHandler
 
 
-apscheduler_autostart: bool = True
-# apscheduler_config: dict = {"apscheduler.timezone": "Asia/Shanghai"}
-
-
-driver = get_driver()
 scheduler = AsyncIOScheduler(timezone="Asia/Shanghai")
 
 
-async def _start_scheduler():
-    if not scheduler.running:
-        # scheduler.configure(apscheduler_config)
-        scheduler.start()
-        logger.info("Scheduler Started.")
-
-
-if apscheduler_autostart:
-    driver.on_startup(_start_scheduler)
-
 aps_logger = logging.getLogger("apscheduler")
 aps_logger.setLevel(logging.DEBUG)
 aps_logger.handlers.clear()
 aps_logger.addHandler(LoguruHandler())
-
-from apscheduler.triggers.date import DateTrigger
-- 
cgit v1.2.3


From a5905ef59ed9d6820557b69ee5a41849c4dbccdc Mon Sep 17 00:00:00 2001
From: Kyomotoi <kyomotoiowo@gmail.com>
Date: Mon, 4 Apr 2022 17:07:18 +0800
Subject: =?UTF-8?q?=F0=9F=90=9B=20=E4=BF=AE=E5=A4=8D=E5=9B=A0=E7=BC=BA?=
 =?UTF-8?q?=E5=B0=91=E5=8F=82=E6=95=B0=E8=80=8C=E5=AF=BC=E8=87=B4=E7=9A=84?=
 =?UTF-8?q?=E6=8A=A5=E9=94=99=20Issue:=20#50?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 ATRI/plugins/bilibili_dynamic/__init__.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'ATRI')

diff --git a/ATRI/plugins/bilibili_dynamic/__init__.py b/ATRI/plugins/bilibili_dynamic/__init__.py
index d69f81b..a42a0e3 100644
--- a/ATRI/plugins/bilibili_dynamic/__init__.py
+++ b/ATRI/plugins/bilibili_dynamic/__init__.py
@@ -138,7 +138,7 @@ tq = Queue()
 class BilibiliDynamicCheckEnabledTrigger(BaseTrigger):
     # 自定义trigger 保证服务开启
     # 实现abstract方法 <get_next_fire_time>
-    def get_next_fire_time(self, now):
+    def get_next_fire_time(self, previous_fire_time, now):
         subscriptor = BilibiliDynamicSubscriptor()
         config = subscriptor.load_service("b站动态订阅")
         if config["enabled"] == False:
-- 
cgit v1.2.3


From f1ce42da9027f416561ecabe34e0f5592bdfdd3e Mon Sep 17 00:00:00 2001
From: Kyomotoi <kyomotoiowo@gmail.com>
Date: Mon, 4 Apr 2022 17:08:28 +0800
Subject: =?UTF-8?q?=E2=9A=B0=EF=B8=8F=20=E6=B8=85=E9=99=A4=E6=9C=AA?=
 =?UTF-8?q?=E4=BD=BF=E7=94=A8=E7=9A=84=E4=BB=A3=E7=A0=81?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 ATRI/plugins/saucenao/__init__.py | 1 -
 ATRI/plugins/setu/__init__.py     | 1 -
 ATRI/plugins/util/data_source.py  | 7 +------
 ATRI/utils/__init__.py            | 7 ++-----
 4 files changed, 3 insertions(+), 13 deletions(-)

(limited to 'ATRI')

diff --git a/ATRI/plugins/saucenao/__init__.py b/ATRI/plugins/saucenao/__init__.py
index d3ad38f..071af98 100644
--- a/ATRI/plugins/saucenao/__init__.py
+++ b/ATRI/plugins/saucenao/__init__.py
@@ -1,4 +1,3 @@
-from re import findall
 from random import choice
 
 from nonebot.adapters.onebot.v11 import MessageEvent, Message, MessageSegment
diff --git a/ATRI/plugins/setu/__init__.py b/ATRI/plugins/setu/__init__.py
index f4bc99d..00eba07 100644
--- a/ATRI/plugins/setu/__init__.py
+++ b/ATRI/plugins/setu/__init__.py
@@ -9,7 +9,6 @@ from nonebot.adapters.onebot.v11 import Bot, MessageEvent, Message, MessageSegme
 from nonebot.adapters.onebot.v11.helpers import extract_image_urls, Cooldown
 
 from ATRI.config import BotSelfConfig
-from ATRI.utils.apscheduler import scheduler
 from .data_source import Setu
 
 
diff --git a/ATRI/plugins/util/data_source.py b/ATRI/plugins/util/data_source.py
index 7b36ebe..4a73c26 100644
--- a/ATRI/plugins/util/data_source.py
+++ b/ATRI/plugins/util/data_source.py
@@ -8,14 +8,9 @@ from ATRI.service import Service
 from ATRI.rule import is_in_service
 
 
-__doc__ = """
-非常实用(?)的工具们!
-"""
-
-
 class Utils(Service):
     def __init__(self):
-        Service.__init__(self, "小工具", __doc__, rule=is_in_service("小工具"))
+        Service.__init__(self, "小工具", "非常实用(?)的工具们!", rule=is_in_service("小工具"))
 
     @staticmethod
     def roll_dice(par: str) -> str:
diff --git a/ATRI/utils/__init__.py b/ATRI/utils/__init__.py
index 565de97..29c9f05 100644
--- a/ATRI/utils/__init__.py
+++ b/ATRI/utils/__init__.py
@@ -5,18 +5,15 @@ import yaml
 import aiofiles
 import time
 from pathlib import Path
-from aiohttp import FormData
 from datetime import datetime
 from PIL import Image, ImageFile
 from aiofiles.threadpool.text import AsyncTextIOWrapper
 
-from . import request
-
 
 def timestamp2datetimestr(timestamp: int) -> str:
     format = "%Y-%m-%d %H:%M:%S"
-    timestamp = time.localtime(timestamp)
-    dt = time.strftime(format, timestamp)
+    tt = time.localtime(timestamp)
+    dt = time.strftime(format, tt)
     return dt
 
 
-- 
cgit v1.2.3


From 080df928cb3fa8b23481211c8c1072453e89b774 Mon Sep 17 00:00:00 2001
From: Kyomotoi <kyomotoiowo@gmail.com>
Date: Mon, 4 Apr 2022 17:09:31 +0800
Subject: =?UTF-8?q?=F0=9F=9A=B8=20=E5=A2=9E=E5=8A=A0=E5=AF=B9=E9=83=A8?=
 =?UTF-8?q?=E5=88=86=E6=8F=92=E4=BB=B6=E6=89=80=E9=9C=80key=E7=9A=84?=
 =?UTF-8?q?=E5=A1=AB=E5=86=99=E6=A3=80=E6=9F=A5?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 ATRI/plugins/saucenao/data_source.py | 10 +++++++++-
 1 file changed, 9 insertions(+), 1 deletion(-)

(limited to 'ATRI')

diff --git a/ATRI/plugins/saucenao/data_source.py b/ATRI/plugins/saucenao/data_source.py
index 738c647..9e2bd75 100644
--- a/ATRI/plugins/saucenao/data_source.py
+++ b/ATRI/plugins/saucenao/data_source.py
@@ -1,9 +1,11 @@
 from random import choice
 
-from ATRI.service import Service
+from ATRI.service import Service, ServiceTools
 from ATRI.rule import is_in_service
 from ATRI.exceptions import RequestError
 from ATRI.utils import request
+from ATRI.config import SauceNAO as sa
+from ATRI.log import logger as log
 
 
 URL = "https://saucenao.com/search.php"
@@ -21,6 +23,12 @@ class SaouceNao(Service):
     ):
         Service.__init__(self, "以图搜图", "以图搜图,仅限二刺螈", rule=is_in_service("以图搜图"))
 
+        if not sa.key:
+            data = ServiceTools.load_service("以图搜图")
+            data["enabled"] = False
+            ServiceTools.save_service(data, "以图搜图")
+            log.warning("key 未配置,本插件将被禁用")
+
         params = dict()
         params["api_key"] = api_key
         params["output_type"] = output_type
-- 
cgit v1.2.3


From 1cc36babf513559758b92eaa719adcf9caf44241 Mon Sep 17 00:00:00 2001
From: Kyomotoi <kyomotoiowo@gmail.com>
Date: Mon, 4 Apr 2022 17:56:48 +0800
Subject: =?UTF-8?q?=F0=9F=9A=A8=20=E5=AE=89=E6=8A=9Apylance?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 ATRI/plugins/chat/__init__.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'ATRI')

diff --git a/ATRI/plugins/chat/__init__.py b/ATRI/plugins/chat/__init__.py
index 4219d56..3cb5dbb 100644
--- a/ATRI/plugins/chat/__init__.py
+++ b/ATRI/plugins/chat/__init__.py
@@ -66,7 +66,7 @@ async def _deal_say(msg: str = ArgPlainText("say")):
     await say.finish(msg)
 
 
-@scheduler.scheduled_job("interval", name="闲聊词库检查更新", hours=3, misfire_grace_time=60)
+@scheduler.scheduled_job("interval", name="闲聊词库检查更新", hours=3, misfire_grace_time=60)  # type: ignore
 async def _check_kimo():
     try:
         await Chat().update_data()
-- 
cgit v1.2.3


From d7176305b5658db05d2e2713c4b389d2081e3b51 Mon Sep 17 00:00:00 2001
From: Kyomotoi <kyomotoiowo@gmail.com>
Date: Tue, 5 Apr 2022 15:18:00 +0800
Subject: =?UTF-8?q?=F0=9F=9A=9A=20=E6=8F=92=E4=BB=B6=20=20=E9=87=8D?=
 =?UTF-8?q?=E5=91=BD=E5=90=8D=E4=B8=BA?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 ATRI/plugins/chat/__init__.py    |  74 ---------------------
 ATRI/plugins/chat/data_source.py | 136 ---------------------------------------
 ATRI/plugins/kimo/__init__.py    |  59 +++++++++++++++++
 ATRI/plugins/kimo/data_source.py | 136 +++++++++++++++++++++++++++++++++++++++
 4 files changed, 195 insertions(+), 210 deletions(-)
 delete mode 100644 ATRI/plugins/chat/__init__.py
 delete mode 100644 ATRI/plugins/chat/data_source.py
 create mode 100644 ATRI/plugins/kimo/__init__.py
 create mode 100644 ATRI/plugins/kimo/data_source.py

(limited to 'ATRI')

diff --git a/ATRI/plugins/chat/__init__.py b/ATRI/plugins/chat/__init__.py
deleted file mode 100644
index 3cb5dbb..0000000
--- a/ATRI/plugins/chat/__init__.py
+++ /dev/null
@@ -1,74 +0,0 @@
-from random import choice
-
-from nonebot.matcher import Matcher
-from nonebot.params import ArgPlainText, CommandArg
-from nonebot.adapters.onebot.v11 import MessageEvent, Message
-from nonebot.adapters.onebot.v11.helpers import Cooldown
-
-from ATRI.utils.apscheduler import scheduler
-from .data_source import Chat
-
-
-_chat_flmt_notice = choice(["慢...慢一..点❤", "冷静1下", "歇会歇会~~", "我开始为你以后的伴侣担心了..."])
-
-
-chat = Chat().on_message("文爱", "闲聊(文爱")
-
-
-@chat.handle([Cooldown(3, prompt=_chat_flmt_notice)])
-async def _chat(event: MessageEvent):
-    user_id = event.get_user_id()
-    msg = str(event.message)
-    repo = await Chat().deal(msg, user_id)
-    try:
-        await chat.finish(repo)
-    except Exception:
-        return
-
-
-my_name_is = Chat().on_command("叫我", "更改闲聊(文爱)时的称呼", aliases={"我是"}, priority=1)
-
-
-@my_name_is.handle([Cooldown(3, prompt=_chat_flmt_notice)])
-async def _name(matcher: Matcher, args: Message = CommandArg()):
-    msg = args.extract_plain_text()
-    if msg:
-        matcher.set_arg("name", args)
-
-
-@my_name_is.got("name", "欧尼酱想让咱如何称呼呢!0w0")
-async def _deal_name(event: MessageEvent, new_name: str = ArgPlainText("name")):
-    user_id = event.get_user_id()
-    repo = choice(
-        [
-            f"好~w 那咱以后就称呼你为{new_name}!",
-            f"噢噢噢!原来你叫{new_name}阿~",
-            f"好欸!{new_name}ちゃん~~~",
-            "很不错的称呼呢w",
-        ]
-    )
-    Chat().name_is(user_id, new_name)
-    await my_name_is.finish(repo)
-
-
-say = Chat().on_command("说", "别人让我说啥就说啥(", priority=1)
-
-
-@say.handle([Cooldown(3, prompt=_chat_flmt_notice)])
-async def _ready_say(matcher: Matcher, args: Message = CommandArg()):
-    msg = args.extract_plain_text()
-    if msg:
-        matcher.set_arg("say", args)
-
-
-@say.got("say", "想要咱复读啥呢...")
-async def _deal_say(msg: str = ArgPlainText("say")):
-    await say.finish(msg)
-
-
-@scheduler.scheduled_job("interval", name="闲聊词库检查更新", hours=3, misfire_grace_time=60)  # type: ignore
-async def _check_kimo():
-    try:
-        await Chat().update_data()
-    except BaseException:
-        pass
diff --git a/ATRI/plugins/chat/data_source.py b/ATRI/plugins/chat/data_source.py
deleted file mode 100644
index 70c6345..0000000
--- a/ATRI/plugins/chat/data_source.py
+++ /dev/null
@@ -1,136 +0,0 @@
-import os
-import json
-from pathlib import Path
-from jieba import posseg
-from random import choice, shuffle
-
-from ATRI.service import Service
-from ATRI.rule import to_bot, is_in_service
-from ATRI.log import logger as log
-from ATRI.utils import request
-from ATRI.exceptions import ReadFileError, WriteError
-
-
-CHAT_PATH = Path(".") / "data" / "database" / "chat"
-os.makedirs(CHAT_PATH, exist_ok=True)
-KIMO_URL = "https://cdn.jsdelivr.net/gh/Kyomotoi/AnimeThesaurus/data.json"
-
-
-class Chat(Service):
-    def __init__(self):
-        Service.__init__(
-            self, "闲聊", "好像有点涩?", rule=to_bot() & is_in_service("闲聊"), priority=5
-        )
-
-    @staticmethod
-    async def _request(url: str) -> dict:
-        res = await request.get(url)
-        data = res.json()
-        return data
-
-    @classmethod
-    async def _generate_data(cls) -> None:
-        file_name = "kimo.json"
-        path = CHAT_PATH / file_name
-        if not path.is_file():
-            log.warning("未检测到词库,生成中")
-            data = await cls._request(KIMO_URL)
-            try:
-                with open(path, "w", encoding="utf-8") as w:
-                    w.write(json.dumps(data, indent=4))
-                log.info("生成完成")
-            except WriteError:
-                raise WriteError("Writing kimo words failed!")
-
-    @classmethod
-    async def _load_data(cls) -> dict:
-        file_name = "kimo.json"
-        path = CHAT_PATH / file_name
-        if not path.is_file():
-            await cls._generate_data()
-
-        with open(path, "r", encoding="utf-8") as r:
-            data = json.loads(r.read())
-        return data
-
-    @classmethod
-    async def update_data(cls) -> None:
-        log.info("更新闲聊词库ing...")
-        file_name = "kimo.json"
-        path = CHAT_PATH / file_name
-        if not path.is_file():
-            await cls._generate_data()
-
-        updata_data = await cls._request(KIMO_URL)
-        data = json.loads(path.read_bytes())
-        for i in updata_data:
-            if i not in data:
-                data[i] = updata_data[i]
-
-        with open(path, "w", encoding="utf-8") as w:
-            w.write(json.dumps(data, indent=4))
-        log.info("闲聊词库更新完成")
-
-    @staticmethod
-    def name_is(user_id: str, new_name: str):
-        file_name = "users.json"
-        path = CHAT_PATH / file_name
-        if not path.is_file():
-            with open(path, "w", encoding="utf-8") as w:
-                w.write(json.dumps({}))
-            data = {}
-
-        data = json.loads(path.read_bytes())
-        data[user_id] = new_name
-        try:
-            with open(path, "w", encoding="utf-8") as w:
-                w.write(json.dumps(data, indent=4))
-        except ReadFileError:
-            raise ReadFileError("Update user name failed!")
-
-    @staticmethod
-    def load_name(user_id: str) -> str:
-        file_name = "users.json"
-        path = CHAT_PATH / file_name
-        if not path.is_file():
-            with open(path, "w", encoding="utf-8") as w:
-                w.write(json.dumps({}))
-            return "你"
-
-        data = json.loads(path.read_bytes())
-        try:
-            result = data[user_id]
-        except BaseException:
-            result = "你"
-        return result
-
-    @classmethod
-    async def deal(cls, msg: str, user_id: str) -> str:
-        keywords = posseg.lcut(msg)
-        shuffle(keywords)
-
-        data = await cls._load_data()
-
-        repo = str()
-        for i in keywords:
-            a = i.word
-            b = list(a)
-            try:
-                if b[0] == b[1]:
-                    a = b[0]
-            except BaseException:
-                pass
-            if a in data:
-                repo = data.get(a, str())
-
-        if not repo:
-            temp_data = list(data)
-            shuffle(temp_data)
-            for i in temp_data:
-                if i in msg:
-                    repo = data.get(i, str())
-
-        a = choice(repo) if type(repo) is list else repo
-        user_name = cls.load_name(user_id)
-        repo = a.replace("你", user_name)
-        return repo
diff --git a/ATRI/plugins/kimo/__init__.py b/ATRI/plugins/kimo/__init__.py
new file mode 100644
index 0000000..b1c5698
--- /dev/null
+++ b/ATRI/plugins/kimo/__init__.py
@@ -0,0 +1,59 @@
+from random import choice
+
+from nonebot.matcher import Matcher
+from nonebot.params import ArgPlainText, CommandArg
+from nonebot.adapters.onebot.v11 import MessageEvent, Message
+from nonebot.adapters.onebot.v11.helpers import Cooldown
+
+from ATRI.utils.apscheduler import scheduler
+from .data_source import Kimo
+
+
+_chat_flmt_notice = choice(["慢...慢一..点❤", "冷静1下", "歇会歇会~~", "我开始为你以后的伴侣担心了..."])
+
+
+kimo = Kimo().on_message("文爱", "闲聊(文爱")
+
+
+@kimo.handle([Cooldown(3, prompt=_chat_flmt_notice)])
+async def _chat(event: MessageEvent):
+    user_id = event.get_user_id()
+    msg = str(event.message)
+    repo = await Kimo().deal(msg, user_id)
+    try:
+        await kimo.finish(repo)
+    except Exception:
+        return
+
+
+my_name_is = Kimo().on_command("叫我", "更改kimo时的称呼", aliases={"我是"}, priority=1)
+
+
+@my_name_is.handle([Cooldown(3, prompt=_chat_flmt_notice)])
+async def _name(matcher: Matcher, args: Message = CommandArg()):
+    msg = args.extract_plain_text()
+    if msg:
+        matcher.set_arg("name", args)
+
+
+@my_name_is.got("name", "欧尼酱想让咱如何称呼呢!0w0")
+async def _deal_name(event: MessageEvent, new_name: str = ArgPlainText("name")):
+    user_id = event.get_user_id()
+    repo = choice(
+        [
+            f"好~w 那咱以后就称呼你为{new_name}!",
+            f"噢噢噢!原来你叫{new_name}阿~",
+            f"好欸!{new_name}ちゃん~~~",
+            "很不错的称呼呢w",
+        ]
+    )
+    Kimo().name_is(user_id, new_name)
+    await my_name_is.finish(repo)
+
+
+@scheduler.scheduled_job("interval", name="kimo词库检查更新", hours=3, misfire_grace_time=60)  # type: ignore
+async def _check_kimo():
+    try:
+        await Kimo().update_data()
+    except BaseException:
+        pass
diff --git a/ATRI/plugins/kimo/data_source.py b/ATRI/plugins/kimo/data_source.py
new file mode 100644
index 0000000..6dd448a
--- /dev/null
+++ b/ATRI/plugins/kimo/data_source.py
@@ -0,0 +1,136 @@
+import os
+import json
+from pathlib import Path
+from jieba import posseg
+from random import choice, shuffle
+
+from ATRI.service import Service
+from ATRI.rule import to_bot, is_in_service
+from ATRI.log import logger as log
+from ATRI.utils import request
+from ATRI.exceptions import ReadFileError, WriteError
+
+
+CHAT_PATH = Path(".") / "data" / "database" / "kimo"
+os.makedirs(CHAT_PATH, exist_ok=True)
+KIMO_URL = "https://cdn.jsdelivr.net/gh/Kyomotoi/AnimeThesaurus/data.json"
+
+
+class Kimo(Service):
+    def __init__(self):
+        Service.__init__(
+            self, "kimo", "好像有点涩?", rule=to_bot() & is_in_service("kimo"), priority=5
+        )
+
+    @staticmethod
+    async def _request(url: str) -> dict:
+        res = await request.get(url)
+        data = res.json()
+        return data
+
+    @classmethod
+    async def _generate_data(cls) -> None:
+        file_name = "kimo.json"
+        path = CHAT_PATH / file_name
+        if not path.is_file():
+            log.warning("未检测到词库,生成中")
+            data = await cls._request(KIMO_URL)
+            try:
+                with open(path, "w", encoding="utf-8") as w:
+                    w.write(json.dumps(data, indent=4))
+                log.info("生成完成")
+            except WriteError:
+                raise WriteError("Writing kimo words failed!")
+
+    @classmethod
+    async def _load_data(cls) -> dict:
+        file_name = "kimo.json"
+        path = CHAT_PATH / file_name
+        if not path.is_file():
+            await cls._generate_data()
+
+        with open(path, "r", encoding="utf-8") as r:
+            data = json.loads(r.read())
+        return data
+
+    @classmethod
+    async def update_data(cls) -> None:
+        log.info("更新闲聊词库ing...")
+        file_name = "kimo.json"
+        path = CHAT_PATH / file_name
+        if not path.is_file():
+            await cls._generate_data()
+
+        updata_data = await cls._request(KIMO_URL)
+        data = json.loads(path.read_bytes())
+        for i in updata_data:
+            if i not in data:
+                data[i] = updata_data[i]
+
+        with open(path, "w", encoding="utf-8") as w:
+            w.write(json.dumps(data, indent=4))
+        log.info("kimo词库更新完成")
+
+    @staticmethod
+    def name_is(user_id: str, new_name: str):
+        file_name = "users.json"
+        path = CHAT_PATH / file_name
+        if not path.is_file():
+            with open(path, "w", encoding="utf-8") as w:
+                w.write(json.dumps({}))
+            data = {}
+
+        data = json.loads(path.read_bytes())
+        data[user_id] = new_name
+        try:
+            with open(path, "w", encoding="utf-8") as w:
+                w.write(json.dumps(data, indent=4))
+        except ReadFileError:
+            raise ReadFileError("Update user name failed!")
+
+    @staticmethod
+    def load_name(user_id: str) -> str:
+        file_name = "users.json"
+        path = CHAT_PATH / file_name
+        if not path.is_file():
+            with open(path, "w", encoding="utf-8") as w:
+                w.write(json.dumps({}))
+            return "你"
+
+        data = json.loads(path.read_bytes())
+        try:
+            result = data[user_id]
+        except BaseException:
+            result = "你"
+        return result
+
+    @classmethod
+    async def deal(cls, msg: str, user_id: str) -> str:
+        keywords = posseg.lcut(msg)
+        shuffle(keywords)
+
+        data = await cls._load_data()
+
+        repo = str()
+        for i in keywords:
+            a = i.word
+            b = list(a)
+            try:
+                if b[0] == b[1]:
+                    a = b[0]
+            except BaseException:
+                pass
+            if a in data:
+                repo = data.get(a, str())
+
+        if not repo:
+            temp_data = list(data)
+            shuffle(temp_data)
+            for i in temp_data:
+                if i in msg:
+                    repo = data.get(i, str())
+
+        a = choice(repo) if type(repo) is list else repo
+        user_name = cls.load_name(user_id)
+        repo = a.replace("你", user_name)
+        return repo
-- 
cgit v1.2.3


From 76cfd49f4129702ac9694077adb7529e390a2957 Mon Sep 17 00:00:00 2001
From: Kyomotoi <kyomotoiowo@gmail.com>
Date: Tue, 5 Apr 2022 15:19:45 +0800
Subject: =?UTF-8?q?=F0=9F=9A=B8=20=E6=8F=90=E9=AB=98=E8=87=AA=E8=BA=AB?=
 =?UTF-8?q?=E7=8A=B6=E6=80=81=E5=8F=AF=E8=A7=82=E6=80=A7?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 ATRI/plugins/status/data_source.py | 33 ++++++++++++++++++++++++---------
 1 file changed, 24 insertions(+), 9 deletions(-)

(limited to 'ATRI')

diff --git a/ATRI/plugins/status/data_source.py b/ATRI/plugins/status/data_source.py
index 68ad216..3595c0c 100644
--- a/ATRI/plugins/status/data_source.py
+++ b/ATRI/plugins/status/data_source.py
@@ -8,6 +8,21 @@ from ATRI.rule import is_in_service
 from ATRI.exceptions import GetStatusError
 
 
+_status_msg = """
+> Status Overview
+
+[CPU: {cpu}%]
+[Memory: {mem}%]
+[Disk usage: {disk}%]
+
+[Net sent: {inteSENT}MB]
+[Net recv: {inteRECV}MB]
+
+[Runtime: {up_time}]
+{msg}
+""".strip()
+
+
 class IsSurvive(Service):
     def __init__(self):
         Service.__init__(self, "状态", "检查自身状态", rule=is_in_service("状态"))
@@ -52,14 +67,14 @@ class IsSurvive(Service):
             log.info("资源占用正常")
             is_ok = True
 
-        msg0 = (
-            "Self status:\n"
-            f"* CPU: {cpu}%\n"
-            f"* MEM: {mem}%\n"
-            f"* DISK: {disk}%\n"
-            f"* netSENT: {inteSENT}MB\n"
-            f"* netRECV: {inteRECV}MB\n"
-            f"* Runtime: {up_time}\n"
-        ) + msg
+        msg0 = _status_msg.format(
+            cpu=cpu,
+            mem=mem,
+            disk=disk,
+            inteSENT=inteSENT,
+            inteRECV=inteRECV,
+            up_time=up_time,
+            msg=msg,
+        )
 
         return msg0, is_ok
-- 
cgit v1.2.3


From 770e5d7b5888f15a4d328a5b21ed15f84cd8da7e Mon Sep 17 00:00:00 2001
From: Kyomotoi <kyomotoiowo@gmail.com>
Date: Tue, 5 Apr 2022 15:20:25 +0800
Subject: =?UTF-8?q?=F0=9F=93=B1=20=E6=98=8E=E7=A1=AE=E7=BC=BA=E5=B0=91?=
 =?UTF-8?q?=E7=9A=84=E5=86=85=E5=AE=B9?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 ATRI/plugins/saucenao/data_source.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'ATRI')

diff --git a/ATRI/plugins/saucenao/data_source.py b/ATRI/plugins/saucenao/data_source.py
index 9e2bd75..8350839 100644
--- a/ATRI/plugins/saucenao/data_source.py
+++ b/ATRI/plugins/saucenao/data_source.py
@@ -27,7 +27,7 @@ class SaouceNao(Service):
             data = ServiceTools.load_service("以图搜图")
             data["enabled"] = False
             ServiceTools.save_service(data, "以图搜图")
-            log.warning("key 未配置,本插件将被禁用")
+            log.warning("插件 SauceNao 所需的 key 未配置,将被全局禁用,后续填写请手动启用")
 
         params = dict()
         params["api_key"] = api_key
-- 
cgit v1.2.3


From 93e71022a5987ca898ca42a84e10cf3a1ddacd0a Mon Sep 17 00:00:00 2001
From: Kyomotoi <kyomotoiowo@gmail.com>
Date: Tue, 5 Apr 2022 15:22:04 +0800
Subject: =?UTF-8?q?=E2=9C=A8=20=E6=96=B0=E5=A2=9E=E6=8F=92=E4=BB=B6:?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 ATRI/plugins/polaroid/__init__.py     | 27 ++++++++++++++++
 ATRI/plugins/polaroid/data_source.py  | 60 +++++++++++++++++++++++++++++++++++
 ATRI/plugins/polaroid/image_dealer.py | 46 +++++++++++++++++++++++++++
 3 files changed, 133 insertions(+)
 create mode 100644 ATRI/plugins/polaroid/__init__.py
 create mode 100644 ATRI/plugins/polaroid/data_source.py
 create mode 100644 ATRI/plugins/polaroid/image_dealer.py

(limited to 'ATRI')

diff --git a/ATRI/plugins/polaroid/__init__.py b/ATRI/plugins/polaroid/__init__.py
new file mode 100644
index 0000000..a3d2d61
--- /dev/null
+++ b/ATRI/plugins/polaroid/__init__.py
@@ -0,0 +1,27 @@
+from random import choice
+
+from nonebot.adapters.onebot.v11 import MessageEvent, MessageSegment, Message
+from nonebot.adapters.onebot.v11.helpers import Cooldown
+
+from ATRI.rule import to_bot
+from .data_source import Polaroid, TEMP_PATH
+
+
+_flmt_notice = choice(["慢...慢一..点❤", "冷静1下", "歇会歇会~~"])
+
+
+polaroid = Polaroid().on_command("拍立得", "获取一张以自己头像的拍立得图片!需at", rule=to_bot())
+
+
+@polaroid.handle([Cooldown(15, prompt=_flmt_notice)])
+async def _(event: MessageEvent):
+    user_id = event.get_user_id()
+
+    temp_p = TEMP_PATH / f"{user_id}.png"
+    if not temp_p.is_file():
+        pol = await Polaroid().generate(user_id)
+        result = MessageSegment.image(pol)
+    else:
+        result = MessageSegment.image(temp_p)
+
+    await polaroid.finish(Message(result))
diff --git a/ATRI/plugins/polaroid/data_source.py b/ATRI/plugins/polaroid/data_source.py
new file mode 100644
index 0000000..82e0337
--- /dev/null
+++ b/ATRI/plugins/polaroid/data_source.py
@@ -0,0 +1,60 @@
+import asyncio
+
+from ATRI.service import Service
+from ATRI.rule import is_in_service
+from ATRI.utils import request
+from ATRI.log import logger as log
+from ATRI.exceptions import RequestError, WriteError
+from .image_dealer import image_dealer
+
+
+TENCENT_AVATER_URL = "https://q1.qlogo.cn/g?b=qq&nk={user_id}&s=640"
+SOURCE_URL = "https://cdn.jsdelivr.net/gh/Kyomotoi/CDN@master/project/ATRI/"
+
+
+class Polaroid(Service):
+    def __init__(self):
+        Service.__init__(self, "拍立得", "根据头像生成拍立得风格照片!", rule=is_in_service("拍立得"))
+
+    @classmethod
+    async def _request(cls, user_id: str) -> bytes:
+        try:
+            res = await request.get(TENCENT_AVATER_URL.format(user_id=user_id))
+        except RequestError:
+            raise RequestError("Request failed!")
+        data = res.read()
+        return data
+
+    @classmethod
+    async def generate(cls, user_id: str):
+        await init_source()
+
+        user_avater = await cls._request(user_id)
+
+        result = image_dealer(user_avater, user_id)
+        return f"file:///{result}"
+
+
+from .image_dealer import TEMP_PATH, POLAROID_DIR
+
+
+async def init_source():
+    files = ["frame-0.PNG", "frame-1.PNG", "font-0.ttf"]
+
+    for i in files:
+        path = POLAROID_DIR / i
+        if not path.is_file():
+            log.warning("插件 polaroid 缺少所需资源,装载中")
+
+            url = SOURCE_URL + i
+            data = await request.get(url)
+            try:
+                with open(path, "wb") as w:
+                    w.write(data.read())
+                log.info("所需资源装载完成")
+            except WriteError:
+                raise WriteError("装载资源失败")
+
+
+loop = asyncio.get_event_loop()
+loop.create_task(init_source())
diff --git a/ATRI/plugins/polaroid/image_dealer.py b/ATRI/plugins/polaroid/image_dealer.py
new file mode 100644
index 0000000..c1ab50b
--- /dev/null
+++ b/ATRI/plugins/polaroid/image_dealer.py
@@ -0,0 +1,46 @@
+from random import choice
+from pathlib import Path
+from datetime import datetime
+
+from PIL import Image, ImageFont, ImageDraw
+
+
+POLAROID_DIR = Path(".") / "data" / "database" / "polaroid"
+TEMP_PATH = Path(".") / "data" / "temp"
+POLAROID_DIR.mkdir(exist_ok=True)
+
+
+def image_dealer(user_img: bytes, user_id):
+    user_p = str((TEMP_PATH / f"{user_id}.png").absolute())
+
+    with open(user_p, "wb") as w:
+        w.write(user_img)
+
+    bg = Image.new("RGBA", (689, 1097), color=(0, 0, 0, 0))
+
+    pol_frame = Image.open(POLAROID_DIR / f"frame-{choice([0, 1])}.PNG").convert("RGBA")
+    user = Image.open(user_p).convert("RGBA").resize((800, 800), Image.ANTIALIAS)
+
+    _, _, _, a = pol_frame.split()
+
+    f_path = str(POLAROID_DIR / "font-0.ttf")
+    f_date = ImageFont.truetype(f_path, 100)  # type: ignore
+    f_msg = ImageFont.truetype(f_path, 110)  # type: ignore
+
+    bg.paste(user, (0, 53))
+    bg.paste(pol_frame, (0, 0), a)
+
+    msg = f"今天辛苦了{choice(['!', '❤️', '✨'])}"
+    now = datetime.now().strftime("%m / %d")
+
+    img = ImageDraw.Draw(bg)
+    img.text((25, 805), now, font=f_date, fill=(99, 184, 255))
+    img.text(
+        (15, 915),
+        msg,
+        font=f_msg,
+        fill=(255, 100, 97),
+    )
+
+    bg.save(user_p)
+    return user_p
-- 
cgit v1.2.3