支持设置定时任务

This commit is contained in:
Wuyi无疑 2023-02-22 00:53:11 +08:00
parent 3a6c9f70f6
commit 3f0ab97b04
14 changed files with 97 additions and 54 deletions

1
.gitignore vendored
View File

@ -665,3 +665,4 @@ FodyWeavers.xsd
config.json config.json
res_data res_data
GsData.db GsData.db
GenshinUID

17
gsuid_core/aps.py Normal file
View File

@ -0,0 +1,17 @@
from apscheduler.schedulers.asyncio import AsyncIOScheduler
from gsuid_core.logger import logger
scheduler = AsyncIOScheduler()
async def start_scheduler():
if not scheduler.running:
scheduler.start()
logger.info('定时任务启动...')
async def shutdown_scheduler():
if scheduler.running:
scheduler.shutdown()
logger.info('定时任务结束...')

View File

@ -1,12 +1,13 @@
import asyncio import asyncio
from typing import List, Union, Optional from typing import List, Union, Literal, Optional
from logger import logger
from fastapi import WebSocket from fastapi import WebSocket
from gs_logger import GsLogger
from segment import MessageSegment
from msgspec import json as msgjson from msgspec import json as msgjson
from models import Message, MessageSend
from gsuid_core.logger import logger
from gsuid_core.gs_logger import GsLogger
from gsuid_core.segment import MessageSegment
from gsuid_core.models import Message, MessageSend
class Bot: class Bot:
@ -21,6 +22,18 @@ class Bot:
self.user_type: Optional[str] = None self.user_type: Optional[str] = None
async def send(self, message: Union[Message, List[Message], str, bytes]): async def send(self, message: Union[Message, List[Message], str, bytes]):
await self.target_send(
message,
self.user_type, # type:ignore
self.group_id if self.group_id else self.user_id,
)
async def target_send(
self,
message: Union[Message, List[Message], str, bytes],
target_type: Literal['group', 'driect', 'channel', 'sub_channel'],
target_id: Optional[str],
):
if isinstance(message, Message): if isinstance(message, Message):
message = [message] message = [message]
elif isinstance(message, str): elif isinstance(message, str):
@ -33,8 +46,8 @@ class Bot:
send = MessageSend( send = MessageSend(
content=message, content=message,
bot_id=self.bot_id, bot_id=self.bot_id,
target_type=self.user_type, target_type=target_type,
target_id=self.group_id if self.group_id else self.user_id, target_id=target_id,
) )
logger.info(f'[发送消息] {send}') logger.info(f'[发送消息] {send}')
await self.bot.send_bytes(msgjson.encode(send)) await self.bot.send_bytes(msgjson.encode(send))

View File

@ -36,7 +36,7 @@ class GsClient:
intent = await self._input() intent = await self._input()
msg = MessageReceive( msg = MessageReceive(
bot_id='Nonebot', bot_id='Nonebot',
user_type='DIRECT', user_type='direct',
user_pm=2, user_pm=2,
group_id=None, group_id=None,
user_id='5253123', user_id='5253123',

View File

@ -1,13 +1,18 @@
import sys
import asyncio import asyncio
from pathlib import Path
import uvicorn import uvicorn
from gss import gss
from config import core_config
from handler import handle_event
from models import MessageReceive
from msgspec import json as msgjson from msgspec import json as msgjson
from fastapi import FastAPI, WebSocket, WebSocketDisconnect from fastapi import FastAPI, WebSocket, WebSocketDisconnect
sys.path.append(str(Path(__file__).parents[1]))
from gsuid_core.gss import gss # noqa: E402
from gsuid_core.config import core_config # noqa: E402
from gsuid_core.handler import handle_event # noqa: E402
from gsuid_core.models import MessageReceive # noqa: E402
from gsuid_core.aps import start_scheduler, shutdown_scheduler # noqa: E402
app = FastAPI() app = FastAPI()
HOST = core_config.get_config('HOST') HOST = core_config.get_config('HOST')
PORT = int(core_config.get_config('PORT')) PORT = int(core_config.get_config('PORT'))
@ -32,5 +37,15 @@ async def websocket_endpoint(websocket: WebSocket, bot_id: str):
await asyncio.gather(process(), start()) await asyncio.gather(process(), start())
@app.on_event('startup')
async def startup_event():
await start_scheduler()
@app.on_event('shutdown')
async def shutdown_event():
await shutdown_scheduler()
if __name__ == "__main__": if __name__ == "__main__":
uvicorn.run(app, host=HOST, port=PORT) uvicorn.run(app, host=HOST, port=PORT)

View File

@ -1,10 +1,11 @@
from typing import Literal from typing import Literal
from fastapi import WebSocket from fastapi import WebSocket
from models import MessageSend
from segment import MessageSegment
from msgspec import json as msgjson from msgspec import json as msgjson
from gsuid_core.models import MessageSend
from gsuid_core.segment import MessageSegment
class GsLogger: class GsLogger:
def __init__(self, bot_id: str, ws: WebSocket): def __init__(self, bot_id: str, ws: WebSocket):

View File

@ -1,6 +1,16 @@
from server import GsServer from gsuid_core.aps import scheduler
from gsuid_core.server import GsServer
gss = GsServer() gss = GsServer()
if not gss.is_load: if not gss.is_load:
gss.is_load = True gss.is_load = True
gss.load_plugins() gss.load_plugins()
repeat_jobs = {}
for i in scheduler.get_jobs():
if i.name not in repeat_jobs:
repeat_jobs[i.name] = i
else:
scheduler.remove_job(i.id)
del repeat_jobs

View File

@ -1,11 +1,10 @@
import asyncio import asyncio
from bot import Bot
from trigger import Trigger
from config import core_config
from models import MessageContent, MessageReceive
from gsuid_core.sv import SL from gsuid_core.sv import SL
from gsuid_core.bot import Bot
from gsuid_core.trigger import Trigger
from gsuid_core.config import core_config
from gsuid_core.models import MessageContent, MessageReceive
config_masters = core_config.get_config('masters') config_masters = core_config.get_config('masters')
config_superusers = core_config.get_config('superusers') config_superusers = core_config.get_config('superusers')

View File

@ -1,19 +0,0 @@
from functools import wraps
from typing import Callable, Optional
from gsuid_core.server import gss
from gsuid_core.logger import logger
def on_bot_connect():
def deco(func: Callable) -> Callable:
gss.bot_connect_def.append(func)
@wraps(func)
async def wrapper(*args, **kwargs) -> Optional[Callable]:
logger.info('@on_bot_connect已成功调用...')
return await func(*args, **kwargs)
return wrapper
return deco

View File

@ -1,4 +1,4 @@
from typing import Any, List, Optional from typing import Any, List, Literal, Optional
from msgspec import Struct from msgspec import Struct
@ -10,7 +10,9 @@ class Message(Struct):
class MessageReceive(Struct, frozen=True): class MessageReceive(Struct, frozen=True):
bot_id: str = 'Bot' bot_id: str = 'Bot'
user_type: Optional[str] = None user_type: Optional[
Literal['group', 'direct', 'channel', 'sub_channel']
] = None
group_id: Optional[str] = None group_id: Optional[str] = None
user_id: str = '' user_id: str = ''
user_pm: int = 3 user_pm: int = 3

View File

@ -3,7 +3,8 @@ from base64 import b64encode
from typing import List, Union, Literal from typing import List, Union, Literal
from PIL import Image from PIL import Image
from models import Message
from gsuid_core.models import Message
class MessageSegment: class MessageSegment:

View File

@ -4,11 +4,10 @@ import importlib
from pathlib import Path from pathlib import Path
from typing import Dict, Callable from typing import Dict, Callable
from bot import Bot
from logger import logger
from fastapi import WebSocket from fastapi import WebSocket
sys.path.append(str(Path(__file__).parents[1])) from gsuid_core.bot import Bot
from gsuid_core.logger import logger
class GsServer: class GsServer:
@ -25,10 +24,12 @@ class GsServer:
def __init__(self): def __init__(self):
if not self.is_initialized: if not self.is_initialized:
self.active_bot: Dict[str, WebSocket] = {} self.active_ws: Dict[str, WebSocket] = {}
self.active_bot: Dict[str, Bot] = {}
self.is_initialized = True self.is_initialized = True
def load_plugins(self): def load_plugins(self):
logger.info('开始导入插件...')
sys.path.append(str(Path(__file__).parents[1])) sys.path.append(str(Path(__file__).parents[1]))
plug_path = Path(__file__).parent / 'plugins' plug_path = Path(__file__).parent / 'plugins'
# 遍历插件文件夹内所有文件 # 遍历插件文件夹内所有文件
@ -57,21 +58,23 @@ class GsServer:
async def connect(self, websocket: WebSocket, bot_id: str) -> Bot: async def connect(self, websocket: WebSocket, bot_id: str) -> Bot:
await websocket.accept() await websocket.accept()
self.active_bot[bot_id] = websocket self.active_ws[bot_id] = websocket
self.active_bot[bot_id] = bot = Bot(bot_id, websocket)
logger.info(f'{bot_id}已连接!') logger.info(f'{bot_id}已连接!')
_task = [_def() for _def in self.bot_connect_def] _task = [_def() for _def in self.bot_connect_def]
asyncio.gather(*_task) asyncio.gather(*_task)
return Bot(bot_id, websocket) return bot
def disconnect(self, bot_id: str): def disconnect(self, bot_id: str):
del self.active_ws[bot_id]
del self.active_bot[bot_id] del self.active_bot[bot_id]
logger.warning(f'{bot_id}已中断!') logger.warning(f'{bot_id}已中断!')
async def send(self, message: str, bot_id: str): async def send(self, message: str, bot_id: str):
await self.active_bot[bot_id].send_text(message) await self.active_ws[bot_id].send_text(message)
async def broadcast(self, message: str): async def broadcast(self, message: str):
for bot_id in self.active_bot: for bot_id in self.active_ws:
await self.send(message, bot_id) await self.send(message, bot_id)
@classmethod @classmethod

View File

@ -3,9 +3,9 @@ from __future__ import annotations
from functools import wraps from functools import wraps
from typing import Dict, List, Tuple, Union, Literal, Callable, Optional from typing import Dict, List, Tuple, Union, Literal, Callable, Optional
from logger import logger from gsuid_core.logger import logger
from trigger import Trigger from gsuid_core.trigger import Trigger
from config import core_config from gsuid_core.config import core_config
class SVList: class SVList:

View File

@ -1,6 +1,6 @@
from typing import Literal, Callable from typing import Literal, Callable
from models import MessageContent from gsuid_core.models import MessageContent
class Trigger: class Trigger: