forked from bot/app
🔥 小型重构
This commit is contained in:
parent
35823be13e
commit
8b01943d14
2
.gitignore
vendored
2
.gitignore
vendored
@ -15,7 +15,7 @@ _config.yml
|
|||||||
config.yml
|
config.yml
|
||||||
config.example.yml
|
config.example.yml
|
||||||
compile.bat
|
compile.bat
|
||||||
liteyuki/resources/templates/latest-debug.html
|
src/resources/templates/latest-debug.html
|
||||||
# vuepress
|
# vuepress
|
||||||
.github
|
.github
|
||||||
pyproject.toml
|
pyproject.toml
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import {defineClientConfig} from "vuepress/client";
|
import {defineClientConfig} from "vuepress/client";
|
||||||
import resourceStoreComp from "./components/res_store.vue";
|
import resourceStoreComp from "./components/ResStore.vue";
|
||||||
import pluginStoreComp from "./components/plugin_store.vue";
|
import pluginStoreComp from "./components/PluginStore.vue";
|
||||||
//导入element-plus
|
//导入element-plus
|
||||||
import ElementPlus from 'element-plus';
|
import ElementPlus from 'element-plus';
|
||||||
|
|
||||||
@ -9,6 +9,5 @@ export default defineClientConfig({
|
|||||||
app.component("resourceStoreComp", resourceStoreComp);
|
app.component("resourceStoreComp", resourceStoreComp);
|
||||||
app.component("pluginStoreComp", pluginStoreComp);
|
app.component("pluginStoreComp", pluginStoreComp);
|
||||||
app.use(ElementPlus);
|
app.use(ElementPlus);
|
||||||
|
|
||||||
},
|
},
|
||||||
});
|
});
|
@ -1,6 +1,6 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import {ref} from 'vue'
|
import {ref} from 'vue'
|
||||||
import ItemCard from './plugin_item_card.vue'
|
import ItemCard from './PluginItemCard.vue'
|
||||||
|
|
||||||
// 插件商店Nonebot
|
// 插件商店Nonebot
|
||||||
let items = ref([])
|
let items = ref([])
|
@ -1,10 +1,10 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import {ref} from 'vue'
|
import {ref} from 'vue'
|
||||||
import ItemCard from './res_item_card.vue'
|
import ItemCard from './ResItemCard.vue'
|
||||||
|
|
||||||
// 从public/assets/resources.json加载插件
|
// 从public/assets/resources.json加载插件
|
||||||
let items = ref([])
|
let items = ref([])
|
||||||
fetch('https://bot.liteyuki.icu/assets/resources.json')
|
fetch('/assets/resources.json')
|
||||||
.then(response => response.json())
|
.then(response => response.json())
|
||||||
.then(data => {
|
.then(data => {
|
||||||
items.value = data
|
items.value = data
|
@ -10,6 +10,7 @@ export default defineUserConfig({
|
|||||||
description: "LiteyukiBot | 轻雪机器人 | An OneBot Standard ChatBot | 一个OneBot标准的聊天机器人",
|
description: "LiteyukiBot | 轻雪机器人 | An OneBot Standard ChatBot | 一个OneBot标准的聊天机器人",
|
||||||
head: [
|
head: [
|
||||||
// 设置 favor.ico,.vuepress/public 下
|
// 设置 favor.ico,.vuepress/public 下
|
||||||
|
["script", {src: "/js/style.js", "type": "module"}],
|
||||||
['link', {rel: 'icon', href: 'https://cdn.liteyuki.icu/favicon.ico'},],
|
['link', {rel: 'icon', href: 'https://cdn.liteyuki.icu/favicon.ico'},],
|
||||||
|
|
||||||
['link', {rel: 'stylesheet', href: 'https://cdn.bootcdn.net/ajax/libs/firacode/6.2.0/fira_code.min.css'}],
|
['link', {rel: 'stylesheet', href: 'https://cdn.bootcdn.net/ajax/libs/firacode/6.2.0/fira_code.min.css'}],
|
||||||
|
22
docs/.vuepress/public/js/style.js
Normal file
22
docs/.vuepress/public/js/style.js
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
function applyStyle() {
|
||||||
|
let lineNumbers = document.body.querySelectorAll('[class^="language-"].line-numbers-mode')
|
||||||
|
lineNumbers.forEach((item) => {
|
||||||
|
// 插入现成的html文本
|
||||||
|
let title = item.getAttribute('data-title')
|
||||||
|
let tabStr =
|
||||||
|
"<div class='tab' style='display: flex; background-color: #d0e9ff'>" +
|
||||||
|
" <div class='tab-buttons'>" +
|
||||||
|
" <div class='tab-button' style='background-color: #FF5F57'></div>" +
|
||||||
|
" <div class='tab-button' style='background-color: #FFBD2E'></div>" +
|
||||||
|
" <div class='tab-button' style='background-color: #27C93F'></div>" +
|
||||||
|
" </div>" +
|
||||||
|
` <div class='tab-title'>${title}</div>` +
|
||||||
|
" <div style='flex: 1'></div>" +
|
||||||
|
"</div>"
|
||||||
|
// 在代码块前插入选项卡
|
||||||
|
item.insertAdjacentHTML('beforebegin', tabStr);
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
applyStyle()
|
@ -1,5 +1,10 @@
|
|||||||
// place your custom styles here
|
// place your custom styles here
|
||||||
|
|
||||||
|
:root {
|
||||||
|
--code-window-border-radius: 10px;
|
||||||
|
--button-distance: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
#main-title {
|
#main-title {
|
||||||
font-family: ColorTube, "Fira Code", serif;
|
font-family: ColorTube, "Fira Code", serif;
|
||||||
color: #ff0000 !important; /* 你想要的颜色 */
|
color: #ff0000 !important; /* 你想要的颜色 */
|
||||||
@ -23,3 +28,54 @@ code {
|
|||||||
#main-title {
|
#main-title {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.theme-hope-content pre {
|
||||||
|
overflow: auto;
|
||||||
|
margin: 0 0;
|
||||||
|
padding: 1rem;
|
||||||
|
border-radius: 6px;
|
||||||
|
line-height: 1.375;
|
||||||
|
}
|
||||||
|
// 移除该before
|
||||||
|
.theme-hope-content pre::before {
|
||||||
|
content: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.theme-hope-content > div[class*=language-] {
|
||||||
|
margin: 0 0 0 0;
|
||||||
|
// 仅下半部分有圆弧
|
||||||
|
border-radius: 0 0 var(--code-window-border-radius) var(--code-window-border-radius);
|
||||||
|
}
|
||||||
|
|
||||||
|
.tab {
|
||||||
|
display: flex;
|
||||||
|
height: 25px;
|
||||||
|
margin-bottom: 0;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
border-top-left-radius: var(--code-window-border-radius);
|
||||||
|
border-top-right-radius: var(--code-window-border-radius);
|
||||||
|
}
|
||||||
|
|
||||||
|
.tab-buttons {
|
||||||
|
padding: 7px;
|
||||||
|
flex: 1;
|
||||||
|
display: flex;
|
||||||
|
justify-content: flex-start;
|
||||||
|
height: 60%;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tab-button {
|
||||||
|
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
|
||||||
|
margin-right: var(--button-distance);
|
||||||
|
border-radius: 50%;
|
||||||
|
height: 100%;
|
||||||
|
aspect-ratio: 1/1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tab-title{
|
||||||
|
text-align: center;
|
||||||
|
justify-content: center;
|
||||||
|
flex: 1;
|
||||||
|
}
|
@ -21,6 +21,7 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"clipboard": "^2.0.11",
|
"clipboard": "^2.0.11",
|
||||||
"element-plus": "^2.7.0",
|
"element-plus": "^2.7.0",
|
||||||
"element-ui": "^2.15.14"
|
"element-ui": "^2.15.14",
|
||||||
|
"vue-router": "^4.4.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -14,6 +14,9 @@ dependencies:
|
|||||||
element-ui:
|
element-ui:
|
||||||
specifier: ^2.15.14
|
specifier: ^2.15.14
|
||||||
version: 2.15.14(vue@3.4.21)
|
version: 2.15.14(vue@3.4.21)
|
||||||
|
vue-router:
|
||||||
|
specifier: ^4.4.0
|
||||||
|
version: 4.4.0(vue@3.4.21)
|
||||||
|
|
||||||
devDependencies:
|
devDependencies:
|
||||||
'@vuepress/bundler-vite':
|
'@vuepress/bundler-vite':
|
||||||
@ -938,7 +941,6 @@ packages:
|
|||||||
|
|
||||||
/@vue/devtools-api@6.6.1:
|
/@vue/devtools-api@6.6.1:
|
||||||
resolution: {integrity: sha512-LgPscpE3Vs0x96PzSSB4IGVSZXZBZHpfxs+ZA1d+VEPwHdOXowy/Y2CsvCAIFrf+ssVU1pD1jidj505EpUnfbA==}
|
resolution: {integrity: sha512-LgPscpE3Vs0x96PzSSB4IGVSZXZBZHpfxs+ZA1d+VEPwHdOXowy/Y2CsvCAIFrf+ssVU1pD1jidj505EpUnfbA==}
|
||||||
dev: true
|
|
||||||
|
|
||||||
/@vue/reactivity@3.4.21:
|
/@vue/reactivity@3.4.21:
|
||||||
resolution: {integrity: sha512-UhenImdc0L0/4ahGCyEzc/pZNwVgcglGy9HVzJ1Bq2Mm9qXOpP8RyNTjookw/gOCUlXSEtuZ2fUg5nrHcoqJcw==}
|
resolution: {integrity: sha512-UhenImdc0L0/4ahGCyEzc/pZNwVgcglGy9HVzJ1Bq2Mm9qXOpP8RyNTjookw/gOCUlXSEtuZ2fUg5nrHcoqJcw==}
|
||||||
@ -985,7 +987,7 @@ packages:
|
|||||||
rollup: 4.13.1
|
rollup: 4.13.1
|
||||||
vite: 5.2.6
|
vite: 5.2.6
|
||||||
vue: 3.4.21
|
vue: 3.4.21
|
||||||
vue-router: 4.3.0(vue@3.4.21)
|
vue-router: 4.4.0(vue@3.4.21)
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- '@types/node'
|
- '@types/node'
|
||||||
- jiti
|
- jiti
|
||||||
@ -1021,7 +1023,7 @@ packages:
|
|||||||
'@vue/devtools-api': 6.6.1
|
'@vue/devtools-api': 6.6.1
|
||||||
'@vuepress/shared': 2.0.0-rc.9
|
'@vuepress/shared': 2.0.0-rc.9
|
||||||
vue: 3.4.21
|
vue: 3.4.21
|
||||||
vue-router: 4.3.0(vue@3.4.21)
|
vue-router: 4.4.0(vue@3.4.21)
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- typescript
|
- typescript
|
||||||
dev: true
|
dev: true
|
||||||
@ -2739,14 +2741,13 @@ packages:
|
|||||||
dependencies:
|
dependencies:
|
||||||
vue: 3.4.21
|
vue: 3.4.21
|
||||||
|
|
||||||
/vue-router@4.3.0(vue@3.4.21):
|
/vue-router@4.4.0(vue@3.4.21):
|
||||||
resolution: {integrity: sha512-dqUcs8tUeG+ssgWhcPbjHvazML16Oga5w34uCUmsk7i0BcnskoLGwjpa15fqMr2Fa5JgVBrdL2MEgqz6XZ/6IQ==}
|
resolution: {integrity: sha512-HB+t2p611aIZraV2aPSRNXf0Z/oLZFrlygJm+sZbdJaW6lcFqEDQwnzUBXn+DApw+/QzDU/I9TeWx9izEjTmsA==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
vue: ^3.2.0
|
vue: ^3.2.0
|
||||||
dependencies:
|
dependencies:
|
||||||
'@vue/devtools-api': 6.6.1
|
'@vue/devtools-api': 6.6.1
|
||||||
vue: 3.4.21
|
vue: 3.4.21
|
||||||
dev: true
|
|
||||||
|
|
||||||
/vue@3.4.21:
|
/vue@3.4.21:
|
||||||
resolution: {integrity: sha512-5hjyV/jLEIKD/jYl4cavMcnzKwjMKohureP8ejn3hhEjwhWIhWeuzL2kJAjzl/WyVsgPY56Sy4Z40C3lVshxXA==}
|
resolution: {integrity: sha512-5hjyV/jLEIKD/jYl4cavMcnzKwjMKohureP8ejn3hhEjwhWIhWeuzL2kJAjzl/WyVsgPY56Sy4Z40C3lVshxXA==}
|
||||||
|
12
main.py
12
main.py
@ -1,8 +1,8 @@
|
|||||||
import nonebot
|
import nonebot
|
||||||
from liteyuki.utils import adapter_manager, driver_manager, init
|
from src.utils import adapter_manager, driver_manager, init
|
||||||
from liteyuki.utils.base.config import load_from_yaml
|
from src.utils.base.config import load_from_yaml
|
||||||
from liteyuki.utils.base.data_manager import StoredConfig, common_db
|
from src.utils.base.data_manager import StoredConfig, common_db
|
||||||
from liteyuki.utils.base.ly_api import liteyuki_api
|
from src.utils.base.ly_api import liteyuki_api
|
||||||
|
|
||||||
if __name__ == "__mp_main__":
|
if __name__ == "__mp_main__":
|
||||||
# Start as multiprocessing
|
# Start as multiprocessing
|
||||||
@ -15,7 +15,7 @@ if __name__ == "__mp_main__":
|
|||||||
nonebot.init(**store_config)
|
nonebot.init(**store_config)
|
||||||
adapter_manager.register()
|
adapter_manager.register()
|
||||||
try:
|
try:
|
||||||
nonebot.load_plugin("liteyuki.liteyuki_main")
|
nonebot.load_plugin("src.liteyuki_main")
|
||||||
nonebot.load_from_toml("pyproject.toml")
|
nonebot.load_from_toml("pyproject.toml")
|
||||||
except BaseException as e:
|
except BaseException as e:
|
||||||
if not isinstance(e, KeyboardInterrupt):
|
if not isinstance(e, KeyboardInterrupt):
|
||||||
@ -24,6 +24,6 @@ if __name__ == "__mp_main__":
|
|||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
# Start as __main__
|
# Start as __main__
|
||||||
from liteyuki.utils.base.reloader import Reloader
|
from src.utils.base.reloader import Reloader
|
||||||
|
|
||||||
nonebot.run()
|
nonebot.run()
|
||||||
|
@ -10,6 +10,7 @@ nonebot-adapter-onebot~=2.4.3
|
|||||||
nonebot-plugin-alconna~=0.46.3
|
nonebot-plugin-alconna~=0.46.3
|
||||||
nonebot_plugin_apscheduler~=0.4.0
|
nonebot_plugin_apscheduler~=0.4.0
|
||||||
nonebot-adapter-satori~=0.11.5
|
nonebot-adapter-satori~=0.11.5
|
||||||
|
numpy~=2.0.0
|
||||||
packaging~=23.1
|
packaging~=23.1
|
||||||
psutil~=5.9.8
|
psutil~=5.9.8
|
||||||
py-cpuinfo~=9.0.0
|
py-cpuinfo~=9.0.0
|
||||||
|
6
src/liteyuki/bot/__init__.py
Normal file
6
src/liteyuki/bot/__init__.py
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
import abc
|
||||||
|
|
||||||
|
|
||||||
|
class Bot(abc.ABC):
|
||||||
|
def __init__(self):
|
||||||
|
pass
|
10
src/liteyuki/exception.py
Normal file
10
src/liteyuki/exception.py
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
"""exception模块包含了liteyuki运行中的所有错误
|
||||||
|
"""
|
||||||
|
|
||||||
|
from typing import Any, Optional
|
||||||
|
|
||||||
|
|
||||||
|
class LiteyukiException(BaseException):
|
||||||
|
"""Liteyuki的异常基类。"""
|
||||||
|
def __str__(self) -> str:
|
||||||
|
return self.__repr__()
|
@ -1,7 +1,7 @@
|
|||||||
import nonebot
|
import nonebot
|
||||||
from git import Repo
|
from git import Repo
|
||||||
|
|
||||||
from liteyuki.utils.base.config import get_config
|
from src.utils.base.config import get_config
|
||||||
|
|
||||||
remote_urls = [
|
remote_urls = [
|
||||||
"https://github.com/snowykami/LiteyukiBot.git",
|
"https://github.com/snowykami/LiteyukiBot.git",
|
@ -11,13 +11,13 @@ from nonebot.exception import MockApiException
|
|||||||
from nonebot.internal.matcher import Matcher
|
from nonebot.internal.matcher import Matcher
|
||||||
from nonebot.permission import SUPERUSER
|
from nonebot.permission import SUPERUSER
|
||||||
|
|
||||||
from liteyuki.utils.base.config import get_config, load_from_yaml
|
from src.utils.base.config import get_config, load_from_yaml
|
||||||
from liteyuki.utils.base.data_manager import StoredConfig, TempConfig, common_db
|
from src.utils.base.data_manager import StoredConfig, TempConfig, common_db
|
||||||
from liteyuki.utils.base.language import get_user_lang
|
from src.utils.base.language import get_user_lang
|
||||||
from liteyuki.utils.base.ly_typing import T_Bot, T_MessageEvent
|
from src.utils.base.ly_typing import T_Bot, T_MessageEvent
|
||||||
from liteyuki.utils.message.message import MarkdownMessage as md, broadcast_to_superusers
|
from src.utils.message.message import MarkdownMessage as md, broadcast_to_superusers
|
||||||
from liteyuki.utils.base.reloader import Reloader
|
from src.utils.base.reloader import Reloader
|
||||||
from liteyuki.utils import event as event_utils, satori_utils
|
from src.utils import event as event_utils, satori_utils
|
||||||
from .api import update_liteyuki
|
from .api import update_liteyuki
|
||||||
from ..utils.base.ly_function import get_function
|
from ..utils.base.ly_function import get_function
|
||||||
|
|
@ -2,34 +2,37 @@ import nonebot
|
|||||||
from watchdog.observers import Observer
|
from watchdog.observers import Observer
|
||||||
from watchdog.events import FileSystemEventHandler
|
from watchdog.events import FileSystemEventHandler
|
||||||
|
|
||||||
from liteyuki.utils.base.config import get_config
|
from src.utils.base.config import get_config
|
||||||
from liteyuki.utils.base.reloader import Reloader
|
from src.utils.base.reloader import Reloader
|
||||||
from liteyuki.utils.base.resource import load_resources
|
from src.utils.base.resource import load_resources
|
||||||
|
|
||||||
if get_config("debug", False):
|
if get_config("debug", False):
|
||||||
|
|
||||||
src_directories = (
|
src_directories = (
|
||||||
"liteyuki/liteyuki_main",
|
"src/liteyuki_main",
|
||||||
"liteyuki/plugins",
|
"src/plugins",
|
||||||
"liteyuki/utils",
|
"src/utils",
|
||||||
)
|
)
|
||||||
src_excludes_extensions = (
|
src_excludes_extensions = (
|
||||||
"pyc",
|
"pyc",
|
||||||
)
|
)
|
||||||
|
|
||||||
res_directories = (
|
res_directories = (
|
||||||
"liteyuki/resources",
|
"src/resources",
|
||||||
"resources",
|
"resources",
|
||||||
)
|
)
|
||||||
|
|
||||||
nonebot.logger.info("Liteyuki Reload is enable, watching for file changes...")
|
nonebot.logger.info("Liteyuki Reload is enable, watching for file changes...")
|
||||||
|
|
||||||
|
|
||||||
class CodeModifiedHandler(FileSystemEventHandler):
|
class CodeModifiedHandler(FileSystemEventHandler):
|
||||||
"""
|
"""
|
||||||
Handler for code file changes
|
Handler for code file changes
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def on_modified(self, event):
|
def on_modified(self, event):
|
||||||
if event.src_path.endswith(src_excludes_extensions) or event.is_directory or "__pycache__" in event.src_path:
|
if event.src_path.endswith(
|
||||||
|
src_excludes_extensions) or event.is_directory or "__pycache__" in event.src_path:
|
||||||
return
|
return
|
||||||
nonebot.logger.info(f"{event.src_path} modified, reloading bot...")
|
nonebot.logger.info(f"{event.src_path} modified, reloading bot...")
|
||||||
Reloader.reload()
|
Reloader.reload()
|
||||||
@ -39,6 +42,7 @@ if get_config("debug", False):
|
|||||||
"""
|
"""
|
||||||
Handler for resource file changes
|
Handler for resource file changes
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def on_modified(self, event):
|
def on_modified(self, event):
|
||||||
nonebot.logger.info(f"{event.src_path} modified, reloading resource...")
|
nonebot.logger.info(f"{event.src_path} modified, reloading resource...")
|
||||||
load_resources()
|
load_resources()
|
@ -1,10 +1,10 @@
|
|||||||
import nonebot.plugin
|
import nonebot.plugin
|
||||||
from nonebot import get_driver
|
from nonebot import get_driver
|
||||||
from liteyuki.utils import init_log
|
from src.utils import init_log
|
||||||
from liteyuki.utils.base.config import get_config
|
from src.utils.base.config import get_config
|
||||||
from liteyuki.utils.base.data_manager import InstalledPlugin, plugin_db
|
from src.utils.base.data_manager import InstalledPlugin, plugin_db
|
||||||
from liteyuki.utils.base.resource import load_resources
|
from src.utils.base.resource import load_resources
|
||||||
from liteyuki.utils.message.tools import check_for_package
|
from src.utils.message.tools import check_for_package
|
||||||
|
|
||||||
load_resources()
|
load_resources()
|
||||||
init_log()
|
init_log()
|
@ -3,11 +3,11 @@ from urllib.parse import quote
|
|||||||
import aiohttp
|
import aiohttp
|
||||||
from nonebot import require
|
from nonebot import require
|
||||||
|
|
||||||
from liteyuki.utils.event import get_user_id
|
from src.utils.event import get_user_id
|
||||||
from liteyuki.utils.base.language import Language
|
from src.utils.base.language import Language
|
||||||
from liteyuki.utils.base.ly_typing import T_MessageEvent
|
from src.utils.base.ly_typing import T_MessageEvent
|
||||||
from liteyuki.utils.base.resource import get_path
|
from src.utils.base.resource import get_path
|
||||||
from liteyuki.utils.message.html_tool import template2image
|
from src.utils.message.html_tool import template2image
|
||||||
|
|
||||||
require("nonebot_plugin_alconna")
|
require("nonebot_plugin_alconna")
|
||||||
|
|
@ -2,9 +2,9 @@ import nonebot
|
|||||||
from nonebot import on_message, require
|
from nonebot import on_message, require
|
||||||
from nonebot.plugin import PluginMetadata
|
from nonebot.plugin import PluginMetadata
|
||||||
|
|
||||||
from liteyuki.utils.base.data import Database, LiteModel
|
from src.utils.base.data import Database, LiteModel
|
||||||
from liteyuki.utils.base.ly_typing import T_Bot, T_MessageEvent
|
from src.utils.base.ly_typing import T_Bot, T_MessageEvent
|
||||||
from liteyuki.utils.message.message import MarkdownMessage as md
|
from src.utils.message.message import MarkdownMessage as md
|
||||||
|
|
||||||
require("nonebot_plugin_alconna")
|
require("nonebot_plugin_alconna")
|
||||||
from nonebot_plugin_alconna import on_alconna
|
from nonebot_plugin_alconna import on_alconna
|
@ -4,9 +4,9 @@ from nonebot.params import CommandArg
|
|||||||
from nonebot.permission import SUPERUSER
|
from nonebot.permission import SUPERUSER
|
||||||
from nonebot.plugin import PluginMetadata
|
from nonebot.plugin import PluginMetadata
|
||||||
|
|
||||||
from liteyuki.utils.base.ly_typing import T_Bot, T_MessageEvent, v11
|
from src.utils.base.ly_typing import T_Bot, T_MessageEvent, v11
|
||||||
from liteyuki.utils.message.message import MarkdownMessage as md, broadcast_to_superusers
|
from src.utils.message.message import MarkdownMessage as md, broadcast_to_superusers
|
||||||
from liteyuki.utils.message.html_tool import *
|
from src.utils.message.html_tool import *
|
||||||
|
|
||||||
md_test = on_command("mdts", permission=SUPERUSER)
|
md_test = on_command("mdts", permission=SUPERUSER)
|
||||||
btn_test = on_command("btnts", permission=SUPERUSER)
|
btn_test = on_command("btnts", permission=SUPERUSER)
|
@ -1,6 +1,6 @@
|
|||||||
import random
|
import random
|
||||||
from pydantic import BaseModel
|
from pydantic import BaseModel
|
||||||
from liteyuki.utils.message.message import MarkdownMessage as md
|
from src.utils.message.message import MarkdownMessage as md
|
||||||
|
|
||||||
class Dot(BaseModel):
|
class Dot(BaseModel):
|
||||||
row: int
|
row: int
|
@ -1,7 +1,7 @@
|
|||||||
from nonebot import require
|
from nonebot import require
|
||||||
|
|
||||||
from liteyuki.utils.base.ly_typing import T_Bot, T_MessageEvent
|
from src.utils.base.ly_typing import T_Bot, T_MessageEvent
|
||||||
from liteyuki.utils.message.message import MarkdownMessage as md
|
from src.utils.message.message import MarkdownMessage as md
|
||||||
|
|
||||||
require("nonebot_plugin_alconna")
|
require("nonebot_plugin_alconna")
|
||||||
from .game import Minesweeper
|
from .game import Minesweeper
|
@ -5,10 +5,10 @@ import aiofiles
|
|||||||
import nonebot.plugin
|
import nonebot.plugin
|
||||||
from nonebot.adapters import satori
|
from nonebot.adapters import satori
|
||||||
|
|
||||||
from liteyuki.utils import event as event_utils
|
from src.utils import event as event_utils
|
||||||
from liteyuki.utils.base.data import LiteModel
|
from src.utils.base.data import LiteModel
|
||||||
from liteyuki.utils.base.data_manager import GlobalPlugin, Group, User, group_db, plugin_db, user_db
|
from src.utils.base.data_manager import GlobalPlugin, Group, User, group_db, plugin_db, user_db
|
||||||
from liteyuki.utils.base.ly_typing import T_MessageEvent
|
from src.utils.base.ly_typing import T_MessageEvent
|
||||||
|
|
||||||
__group_data = {} # 群数据缓存, {group_id: Group}
|
__group_data = {} # 群数据缓存, {group_id: Group}
|
||||||
__user_data = {} # 用户数据缓存, {user_id: User}
|
__user_data = {} # 用户数据缓存, {user_id: User}
|
@ -14,13 +14,13 @@ from nonebot.permission import SUPERUSER
|
|||||||
from nonebot.plugin import Plugin, PluginMetadata
|
from nonebot.plugin import Plugin, PluginMetadata
|
||||||
from nonebot.utils import run_sync
|
from nonebot.utils import run_sync
|
||||||
|
|
||||||
from liteyuki.utils.base.data_manager import InstalledPlugin
|
from src.utils.base.data_manager import InstalledPlugin
|
||||||
from liteyuki.utils.base.language import get_user_lang
|
from src.utils.base.language import get_user_lang
|
||||||
from liteyuki.utils.base.ly_typing import T_Bot
|
from src.utils.base.ly_typing import T_Bot
|
||||||
from liteyuki.utils.message.message import MarkdownMessage as md
|
from src.utils.message.message import MarkdownMessage as md
|
||||||
from liteyuki.utils.message.markdown import MarkdownComponent as mdc, compile_md, escape_md
|
from src.utils.message.markdown import MarkdownComponent as mdc, compile_md, escape_md
|
||||||
from liteyuki.utils.base.permission import GROUP_ADMIN, GROUP_OWNER
|
from src.utils.base.permission import GROUP_ADMIN, GROUP_OWNER
|
||||||
from liteyuki.utils.message.tools import clamp
|
from src.utils.message.tools import clamp
|
||||||
from .common import *
|
from .common import *
|
||||||
|
|
||||||
require("nonebot_plugin_alconna")
|
require("nonebot_plugin_alconna")
|
@ -6,10 +6,10 @@ from nonebot import require
|
|||||||
from nonebot.internal.matcher import Matcher
|
from nonebot.internal.matcher import Matcher
|
||||||
from nonebot.permission import SUPERUSER
|
from nonebot.permission import SUPERUSER
|
||||||
|
|
||||||
from liteyuki.utils.base.language import get_user_lang
|
from src.utils.base.language import get_user_lang
|
||||||
from liteyuki.utils.base.ly_typing import T_Bot, T_MessageEvent
|
from src.utils.base.ly_typing import T_Bot, T_MessageEvent
|
||||||
from liteyuki.utils.message.message import MarkdownMessage as md
|
from src.utils.message.message import MarkdownMessage as md
|
||||||
from liteyuki.utils.base.resource import (ResourceMetadata, add_resource_pack, change_priority, check_exist, check_status, get_loaded_resource_packs, get_resource_metadata, load_resources, remove_resource_pack)
|
from src.utils.base.resource import (ResourceMetadata, add_resource_pack, change_priority, check_exist, check_status, get_loaded_resource_packs, get_resource_metadata, load_resources, remove_resource_pack)
|
||||||
|
|
||||||
require("nonebot_plugin_alconna")
|
require("nonebot_plugin_alconna")
|
||||||
from nonebot_plugin_alconna import Alconna, Args, on_alconna, Arparma, Subcommand
|
from nonebot_plugin_alconna import Alconna, Args, on_alconna, Arparma, Subcommand
|
@ -2,11 +2,11 @@ import nonebot
|
|||||||
|
|
||||||
from nonebot.message import event_preprocessor
|
from nonebot.message import event_preprocessor
|
||||||
# from nonebot_plugin_alconna.typings import Event
|
# from nonebot_plugin_alconna.typings import Event
|
||||||
from liteyuki.utils.base.ly_typing import T_MessageEvent
|
from src.utils.base.ly_typing import T_MessageEvent
|
||||||
from liteyuki.utils import satori_utils
|
from src.utils import satori_utils
|
||||||
from nonebot.adapters import satori
|
from nonebot.adapters import satori
|
||||||
from nonebot_plugin_alconna.typings import Event
|
from nonebot_plugin_alconna.typings import Event
|
||||||
from liteyuki.plugins.liteyuki_status.counter_for_satori import satori_counter
|
from src.plugins.liteyuki_status.counter_for_satori import satori_counter
|
||||||
|
|
||||||
|
|
||||||
@event_preprocessor
|
@event_preprocessor
|
@ -5,10 +5,10 @@ import aiohttp
|
|||||||
from nonebot import require
|
from nonebot import require
|
||||||
from nonebot.plugin import PluginMetadata
|
from nonebot.plugin import PluginMetadata
|
||||||
|
|
||||||
from liteyuki.utils.base.config import get_config
|
from src.utils.base.config import get_config
|
||||||
from liteyuki.utils.base.data import Database, LiteModel
|
from src.utils.base.data import Database, LiteModel
|
||||||
from liteyuki.utils.base.resource import get_path
|
from src.utils.base.resource import get_path
|
||||||
from liteyuki.utils.message.html_tool import template2image
|
from src.utils.message.html_tool import template2image
|
||||||
|
|
||||||
require("nonebot_plugin_alconna")
|
require("nonebot_plugin_alconna")
|
||||||
require("nonebot_plugin_apscheduler")
|
require("nonebot_plugin_apscheduler")
|
@ -8,12 +8,12 @@ from nonebot.permission import SUPERUSER
|
|||||||
from nonebot.rule import to_me
|
from nonebot.rule import to_me
|
||||||
from nonebot.typing import T_State
|
from nonebot.typing import T_State
|
||||||
|
|
||||||
from liteyuki.utils.base.ly_typing import T_MessageEvent
|
from src.utils.base.ly_typing import T_MessageEvent
|
||||||
from .utils import get_keywords
|
from .utils import get_keywords
|
||||||
from liteyuki.utils.base.word_bank import get_reply
|
from src.utils.base.word_bank import get_reply
|
||||||
from liteyuki.utils.event import get_message_type
|
from src.utils.event import get_message_type
|
||||||
from liteyuki.utils.base.permission import GROUP_ADMIN, GROUP_OWNER
|
from src.utils.base.permission import GROUP_ADMIN, GROUP_OWNER
|
||||||
from liteyuki.utils.base.data_manager import group_db, Group
|
from src.utils.base.data_manager import group_db, Group
|
||||||
|
|
||||||
require("nonebot_plugin_alconna")
|
require("nonebot_plugin_alconna")
|
||||||
from nonebot_plugin_alconna import on_alconna, Alconna, Args, Arparma
|
from nonebot_plugin_alconna import on_alconna, Alconna, Args, Arparma
|
@ -1,4 +1,4 @@
|
|||||||
from liteyuki.utils.base.data import Database, LiteModel
|
from src.utils.base.data import Database, LiteModel
|
||||||
|
|
||||||
|
|
||||||
class MessageEventModel(LiteModel):
|
class MessageEventModel(LiteModel):
|
@ -5,11 +5,11 @@ from collections import Counter
|
|||||||
|
|
||||||
from nonebot import Bot
|
from nonebot import Bot
|
||||||
|
|
||||||
from liteyuki.utils.message.html_tool import template2image
|
from src.utils.message.html_tool import template2image
|
||||||
from .common import MessageEventModel, msg_db
|
from .common import MessageEventModel, msg_db
|
||||||
from liteyuki.utils.base.language import Language
|
from src.utils.base.language import Language
|
||||||
from liteyuki.utils.base.resource import get_path
|
from src.utils.base.resource import get_path
|
||||||
from liteyuki.utils.message.string_tool import convert_seconds_to_time
|
from src.utils.message.string_tool import convert_seconds_to_time
|
||||||
from ...utils.external.logo import get_group_icon, get_user_icon
|
from ...utils.external.logo import get_group_icon, get_user_icon
|
||||||
|
|
||||||
|
|
@ -1,9 +1,9 @@
|
|||||||
from nonebot import Bot, require
|
from nonebot import Bot, require
|
||||||
from liteyuki.utils.message.string_tool import convert_duration, convert_time_to_seconds
|
from src.utils.message.string_tool import convert_duration, convert_time_to_seconds
|
||||||
from .stat_api import *
|
from .data_source import *
|
||||||
from liteyuki.utils import event as event_utils
|
from src.utils import event as event_utils
|
||||||
from liteyuki.utils.base.language import Language
|
from src.utils.base.language import Language
|
||||||
from liteyuki.utils.base.ly_typing import T_MessageEvent
|
from src.utils.base.ly_typing import T_MessageEvent
|
||||||
|
|
||||||
require("nonebot_plugin_alconna")
|
require("nonebot_plugin_alconna")
|
||||||
|
|
@ -3,13 +3,13 @@ import time
|
|||||||
from nonebot import require
|
from nonebot import require
|
||||||
from nonebot.message import event_postprocessor
|
from nonebot.message import event_postprocessor
|
||||||
|
|
||||||
from liteyuki.utils.base.data import Database, LiteModel
|
from src.utils.base.data import Database, LiteModel
|
||||||
from liteyuki.utils.base.ly_typing import v11, v12, satori
|
from src.utils.base.ly_typing import v11, v12, satori
|
||||||
|
|
||||||
from liteyuki.utils.base.ly_typing import T_Bot, T_MessageEvent
|
from src.utils.base.ly_typing import T_Bot, T_MessageEvent
|
||||||
|
|
||||||
from .common import MessageEventModel, msg_db
|
from .common import MessageEventModel, msg_db
|
||||||
from liteyuki.utils import event as event_utils
|
from src.utils import event as event_utils
|
||||||
|
|
||||||
require("nonebot_plugin_alconna")
|
require("nonebot_plugin_alconna")
|
||||||
|
|
21
src/plugins/liteyuki_statistics/word_cloud/LICENSE
Normal file
21
src/plugins/liteyuki_statistics/word_cloud/LICENSE
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2022 hemengyang
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
107
src/plugins/liteyuki_statistics/word_cloud/data_source.py
Normal file
107
src/plugins/liteyuki_statistics/word_cloud/data_source.py
Normal file
@ -0,0 +1,107 @@
|
|||||||
|
import asyncio
|
||||||
|
import concurrent.futures
|
||||||
|
import contextlib
|
||||||
|
import re
|
||||||
|
from functools import partial
|
||||||
|
from io import BytesIO
|
||||||
|
from random import choice
|
||||||
|
from typing import Optional
|
||||||
|
|
||||||
|
import jieba
|
||||||
|
import jieba.analyse
|
||||||
|
import numpy as np
|
||||||
|
from emoji import replace_emoji
|
||||||
|
from PIL import Image
|
||||||
|
from wordcloud import WordCloud
|
||||||
|
|
||||||
|
from .config import global_config, plugin_config
|
||||||
|
|
||||||
|
|
||||||
|
def pre_precess(msg: str) -> str:
|
||||||
|
"""对消息进行预处理"""
|
||||||
|
# 去除网址
|
||||||
|
# https://stackoverflow.com/a/17773849/9212748
|
||||||
|
url_regex = re.compile(
|
||||||
|
r"(https?:\/\/(?:www\.|(?!www))[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\.[^\s]{2,}|www\.[a-zA-Z0-9][a-zA-Z0-9-]"
|
||||||
|
r"+[a-zA-Z0-9]\.[^\s]{2,}|https?:\/\/(?:www\.|(?!www))[a-zA-Z0-9]+\.[^\s]{2,}|www\.[a-zA-Z0-9]+\.[^\s]{2,})"
|
||||||
|
)
|
||||||
|
msg = url_regex.sub("", msg)
|
||||||
|
|
||||||
|
# 去除 \u200b
|
||||||
|
msg = re.sub(r"\u200b", "", msg)
|
||||||
|
|
||||||
|
# 去除 emoji
|
||||||
|
# https://github.com/carpedm20/emoji
|
||||||
|
msg = replace_emoji(msg)
|
||||||
|
|
||||||
|
return msg
|
||||||
|
|
||||||
|
|
||||||
|
def analyse_message(msg: str) -> dict[str, float]:
|
||||||
|
"""分析消息
|
||||||
|
|
||||||
|
分词,并统计词频
|
||||||
|
"""
|
||||||
|
# 设置停用词表
|
||||||
|
if plugin_config.wordcloud_stopwords_path:
|
||||||
|
jieba.analyse.set_stop_words(plugin_config.wordcloud_stopwords_path)
|
||||||
|
# 加载用户词典
|
||||||
|
if plugin_config.wordcloud_userdict_path:
|
||||||
|
jieba.load_userdict(str(plugin_config.wordcloud_userdict_path))
|
||||||
|
# 基于 TF-IDF 算法的关键词抽取
|
||||||
|
# 返回所有关键词,因为设置了数量其实也只是 tags[:topK],不如交给词云库处理
|
||||||
|
words = jieba.analyse.extract_tags(msg, topK=0, withWeight=True)
|
||||||
|
return dict(words)
|
||||||
|
|
||||||
|
|
||||||
|
def get_mask(key: str):
|
||||||
|
"""获取 mask"""
|
||||||
|
mask_path = plugin_config.get_mask_path(key)
|
||||||
|
if mask_path.exists():
|
||||||
|
return np.array(Image.open(mask_path))
|
||||||
|
# 如果指定 mask 文件不存在,则尝试默认 mask
|
||||||
|
default_mask_path = plugin_config.get_mask_path()
|
||||||
|
if default_mask_path.exists():
|
||||||
|
return np.array(Image.open(default_mask_path))
|
||||||
|
|
||||||
|
|
||||||
|
def _get_wordcloud(messages: list[str], mask_key: str) -> Optional[bytes]:
|
||||||
|
# 过滤掉命令
|
||||||
|
command_start = tuple(i for i in global_config.command_start if i)
|
||||||
|
message = " ".join(m for m in messages if not m.startswith(command_start))
|
||||||
|
# 预处理
|
||||||
|
message = pre_precess(message)
|
||||||
|
# 分析消息。分词,并统计词频
|
||||||
|
frequency = analyse_message(message)
|
||||||
|
# 词云参数
|
||||||
|
wordcloud_options = {}
|
||||||
|
wordcloud_options.update(plugin_config.wordcloud_options)
|
||||||
|
wordcloud_options.setdefault("font_path", str(plugin_config.wordcloud_font_path))
|
||||||
|
wordcloud_options.setdefault("width", plugin_config.wordcloud_width)
|
||||||
|
wordcloud_options.setdefault("height", plugin_config.wordcloud_height)
|
||||||
|
wordcloud_options.setdefault(
|
||||||
|
"background_color", plugin_config.wordcloud_background_color
|
||||||
|
)
|
||||||
|
# 如果 colormap 是列表,则随机选择一个
|
||||||
|
colormap = (
|
||||||
|
plugin_config.wordcloud_colormap
|
||||||
|
if isinstance(plugin_config.wordcloud_colormap, str)
|
||||||
|
else choice(plugin_config.wordcloud_colormap)
|
||||||
|
)
|
||||||
|
wordcloud_options.setdefault("colormap", colormap)
|
||||||
|
wordcloud_options.setdefault("mask", get_mask(mask_key))
|
||||||
|
with contextlib.suppress(ValueError):
|
||||||
|
wordcloud = WordCloud(**wordcloud_options)
|
||||||
|
image = wordcloud.generate_from_frequencies(frequency).to_image()
|
||||||
|
image_bytes = BytesIO()
|
||||||
|
image.save(image_bytes, format="PNG")
|
||||||
|
return image_bytes.getvalue()
|
||||||
|
|
||||||
|
|
||||||
|
async def get_wordcloud(messages: list[str], mask_key: str) -> Optional[bytes]:
|
||||||
|
loop = asyncio.get_running_loop()
|
||||||
|
pfunc = partial(_get_wordcloud, messages, mask_key)
|
||||||
|
# 虽然不知道具体是哪里泄漏了,但是通过每次关闭线程池可以避免这个问题
|
||||||
|
# https://github.com/he0119/nonebot-plugin-wordcloud/issues/99
|
||||||
|
with concurrent.futures.ThreadPoolExecutor() as pool:
|
||||||
|
return await loop.run_in_executor(pool, pfunc)
|
@ -7,13 +7,13 @@ from cpuinfo import cpuinfo
|
|||||||
from nonebot import require
|
from nonebot import require
|
||||||
from nonebot.adapters import satori
|
from nonebot.adapters import satori
|
||||||
|
|
||||||
from liteyuki.utils import __NAME__, __VERSION__
|
from src.utils import __NAME__, __VERSION__
|
||||||
from liteyuki.utils.base.config import get_config
|
from src.utils.base.config import get_config
|
||||||
from liteyuki.utils.base.data_manager import TempConfig, common_db
|
from src.utils.base.data_manager import TempConfig, common_db
|
||||||
from liteyuki.utils.base.language import Language
|
from src.utils.base.language import Language
|
||||||
from liteyuki.utils.base.resource import get_loaded_resource_packs, get_path
|
from src.utils.base.resource import get_loaded_resource_packs, get_path
|
||||||
from liteyuki.utils.message.html_tool import template2image
|
from src.utils.message.html_tool import template2image
|
||||||
from liteyuki.utils import satori_utils
|
from src.utils import satori_utils
|
||||||
from .counter_for_satori import satori_counter
|
from .counter_for_satori import satori_counter
|
||||||
from git import Repo
|
from git import Repo
|
||||||
|
|
@ -1,6 +1,6 @@
|
|||||||
from liteyuki.utils import event as event_utils
|
from src.utils import event as event_utils
|
||||||
from liteyuki.utils.base.language import get_user_lang
|
from src.utils.base.language import get_user_lang
|
||||||
from liteyuki.utils.base.ly_typing import T_Bot, T_MessageEvent
|
from src.utils.base.ly_typing import T_Bot, T_MessageEvent
|
||||||
from .api import *
|
from .api import *
|
||||||
|
|
||||||
require("nonebot_plugin_alconna")
|
require("nonebot_plugin_alconna")
|
@ -3,13 +3,13 @@ from typing import Optional
|
|||||||
import pytz
|
import pytz
|
||||||
from nonebot import require
|
from nonebot import require
|
||||||
|
|
||||||
from liteyuki.utils.base.data import LiteModel, Database
|
from src.utils.base.data import LiteModel, Database
|
||||||
from liteyuki.utils.base.data_manager import User, user_db, group_db
|
from src.utils.base.data_manager import User, user_db, group_db
|
||||||
from liteyuki.utils.base.language import Language, change_user_lang, get_all_lang, get_user_lang
|
from src.utils.base.language import Language, change_user_lang, get_all_lang, get_user_lang
|
||||||
from liteyuki.utils.base.ly_typing import T_Bot, T_MessageEvent
|
from src.utils.base.ly_typing import T_Bot, T_MessageEvent
|
||||||
from liteyuki.utils.message.message import MarkdownMessage as md
|
from src.utils.message.message import MarkdownMessage as md
|
||||||
from .const import representative_timezones_list
|
from .const import representative_timezones_list
|
||||||
from liteyuki.utils import event as event_utils
|
from src.utils import event as event_utils
|
||||||
|
|
||||||
require("nonebot_plugin_alconna")
|
require("nonebot_plugin_alconna")
|
||||||
from nonebot_plugin_alconna import Alconna, Args, Arparma, Subcommand, on_alconna
|
from nonebot_plugin_alconna import Alconna, Args, Arparma, Subcommand, on_alconna
|
@ -1,4 +1,4 @@
|
|||||||
from liteyuki.utils.base.data import LiteModel
|
from src.utils.base.data import LiteModel
|
||||||
|
|
||||||
|
|
||||||
class Location(LiteModel):
|
class Location(LiteModel):
|
@ -3,15 +3,15 @@ from nonebot.adapters import satori
|
|||||||
from nonebot.adapters.onebot.v11 import MessageSegment
|
from nonebot.adapters.onebot.v11 import MessageSegment
|
||||||
from nonebot.internal.matcher import Matcher
|
from nonebot.internal.matcher import Matcher
|
||||||
|
|
||||||
from liteyuki.utils.base.config import get_config
|
from src.utils.base.config import get_config
|
||||||
from liteyuki.utils.base.ly_typing import T_MessageEvent
|
from src.utils.base.ly_typing import T_MessageEvent
|
||||||
|
|
||||||
from .qw_api import *
|
from .qw_api import *
|
||||||
from liteyuki.utils.base.data_manager import User, user_db
|
from src.utils.base.data_manager import User, user_db
|
||||||
from liteyuki.utils.base.language import Language, get_user_lang
|
from src.utils.base.language import Language, get_user_lang
|
||||||
from liteyuki.utils.base.resource import get_path
|
from src.utils.base.resource import get_path
|
||||||
from liteyuki.utils.message.html_tool import template2image
|
from src.utils.message.html_tool import template2image
|
||||||
from liteyuki.utils import event as event_utils
|
from src.utils import event as event_utils
|
||||||
|
|
||||||
require("nonebot_plugin_alconna")
|
require("nonebot_plugin_alconna")
|
||||||
from nonebot_plugin_alconna import on_alconna, Alconna, Args, MultiVar, Arparma, UniMessage
|
from nonebot_plugin_alconna import on_alconna, Alconna, Args, MultiVar, Arparma, UniMessage
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user