mirror of
https://github.com/nonebot/nonebot2.git
synced 2025-07-28 00:31:14 +00:00
🚧 add event parser
This commit is contained in:
@ -6,10 +6,10 @@
|
||||
"""
|
||||
|
||||
import abc
|
||||
from typing_extensions import Literal
|
||||
from functools import reduce, partial
|
||||
from dataclasses import dataclass, field
|
||||
from typing import Any, Dict, Union, TypeVar, Optional, Callable, Iterable, Awaitable, Generic, TYPE_CHECKING
|
||||
from typing_extensions import Literal
|
||||
from typing import Any, Dict, Union, Optional, Callable, Iterable, Awaitable, TYPE_CHECKING
|
||||
|
||||
from pydantic import BaseModel
|
||||
|
||||
@ -162,6 +162,14 @@ class Event(abc.ABC, BaseModel):
|
||||
def get_session_id(self) -> str:
|
||||
raise NotImplementedError
|
||||
|
||||
@abc.abstractmethod
|
||||
def get_message(self) -> "Message":
|
||||
raise NotImplementedError
|
||||
|
||||
@abc.abstractmethod
|
||||
def get_plaintext(self) -> str:
|
||||
raise NotImplementedError
|
||||
|
||||
|
||||
# T = TypeVar("T", bound=BaseModel)
|
||||
|
||||
|
@ -10,7 +10,7 @@ CQHTTP (OneBot) v11 协议适配
|
||||
https://github.com/howmanybots/onebot/blob/master/README.md
|
||||
"""
|
||||
|
||||
from .event import Event
|
||||
from .event import CQHTTPEvent
|
||||
from .message import Message, MessageSegment
|
||||
from .utils import log, escape, unescape, _b2s
|
||||
from .bot import Bot, _check_at_me, _check_nickname, _check_reply, _handle_api_result
|
||||
|
@ -15,9 +15,9 @@ from nonebot.adapters import Bot as BaseBot
|
||||
from nonebot.exception import RequestDenied
|
||||
|
||||
from .utils import log
|
||||
from .event import Reply, CQHTTPEvent, MessageEvent
|
||||
from .message import Message, MessageSegment
|
||||
from .exception import NetworkError, ApiNotAvailable, ActionFailed
|
||||
from .event import Reply, CQHTTPEvent, MessageEvent, get_event_model
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from nonebot.drivers import Driver, WebSocket
|
||||
@ -297,7 +297,20 @@ class Bot(BaseBot):
|
||||
return
|
||||
|
||||
try:
|
||||
event = CQHTTPEvent.parse_obj(message)
|
||||
post_type = message['post_type']
|
||||
detail_type = message.get(f"{post_type}_type")
|
||||
detail_type = f".{detail_type}" if detail_type else ""
|
||||
sub_type = message.get("sub_type")
|
||||
sub_type = f".{sub_type}" if sub_type else ""
|
||||
models = get_event_model(f".{post_type}{detail_type}{sub_type}")
|
||||
for model in models:
|
||||
try:
|
||||
event = model.parse_obj(message)
|
||||
break
|
||||
except Exception as e:
|
||||
log("DEBUG", "Event Parser Error", e)
|
||||
else:
|
||||
event = CQHTTPEvent.parse_obj(message)
|
||||
|
||||
# Check whether user is calling me
|
||||
await _check_reply(self, event)
|
||||
|
@ -1,7 +1,9 @@
|
||||
from typing import Optional
|
||||
import inspect
|
||||
from typing_extensions import Literal
|
||||
from typing import Type, List, Optional
|
||||
|
||||
from pydantic import BaseModel
|
||||
from pygtrie import StringTrie
|
||||
from nonebot.adapters import Event
|
||||
from nonebot.utils import escape_tag
|
||||
from nonebot.typing import overrides
|
||||
@ -210,6 +212,7 @@ from .message import Message
|
||||
|
||||
|
||||
class CQHTTPEvent(Event):
|
||||
__event__ = ""
|
||||
time: int
|
||||
self_id: int
|
||||
post_type: Literal["message", "notice", "request", "meta_event"]
|
||||
@ -226,6 +229,14 @@ class CQHTTPEvent(Event):
|
||||
def get_event_description(self) -> str:
|
||||
return str(self.dict())
|
||||
|
||||
@overrides(Event)
|
||||
def get_message(self) -> Message:
|
||||
raise ValueError("Event has no message!")
|
||||
|
||||
@overrides(Event)
|
||||
def get_plaintext(self) -> str:
|
||||
raise ValueError("Event has no message!")
|
||||
|
||||
|
||||
# Models
|
||||
class Sender(BaseModel):
|
||||
@ -284,6 +295,7 @@ class Status(BaseModel):
|
||||
|
||||
# Message Events
|
||||
class MessageEvent(CQHTTPEvent):
|
||||
__event__ = "message"
|
||||
post_type: Literal["message"]
|
||||
sub_type: str
|
||||
user_id: int
|
||||
@ -302,8 +314,17 @@ class MessageEvent(CQHTTPEvent):
|
||||
return f"{self.post_type}.{self.message_type}" + (f".{sub_type}"
|
||||
if sub_type else "")
|
||||
|
||||
@overrides(CQHTTPEvent)
|
||||
def get_message(self) -> Message:
|
||||
return self.message
|
||||
|
||||
@overrides(CQHTTPEvent)
|
||||
def get_plaintext(self) -> str:
|
||||
return self.message.extract_plain_text()
|
||||
|
||||
|
||||
class PrivateMessageEvent(MessageEvent):
|
||||
__event__ = "message.private"
|
||||
message_type: Literal["private"]
|
||||
|
||||
@overrides(CQHTTPEvent)
|
||||
@ -316,6 +337,7 @@ class PrivateMessageEvent(MessageEvent):
|
||||
|
||||
|
||||
class GroupMessageEvent(MessageEvent):
|
||||
__event__ = "message.group"
|
||||
message_type: Literal["group"]
|
||||
group_id: int
|
||||
anonymous: Anonymous
|
||||
@ -333,6 +355,7 @@ class GroupMessageEvent(MessageEvent):
|
||||
|
||||
# Notice Events
|
||||
class NoticeEvent(CQHTTPEvent):
|
||||
__event__ = "notice"
|
||||
post_type: Literal["notice"]
|
||||
notice_type: str
|
||||
|
||||
@ -344,6 +367,7 @@ class NoticeEvent(CQHTTPEvent):
|
||||
|
||||
|
||||
class GroupUploadNoticeEvent(NoticeEvent):
|
||||
__event__ = "notice.group_upload"
|
||||
notice_type: Literal["group_upload"]
|
||||
user_id: int
|
||||
group_id: int
|
||||
@ -351,6 +375,7 @@ class GroupUploadNoticeEvent(NoticeEvent):
|
||||
|
||||
|
||||
class GroupAdminNoticeEvent(NoticeEvent):
|
||||
__event__ = "notice.group_admin"
|
||||
notice_type: Literal["group_admin"]
|
||||
sub_type: str
|
||||
user_id: int
|
||||
@ -358,6 +383,7 @@ class GroupAdminNoticeEvent(NoticeEvent):
|
||||
|
||||
|
||||
class GroupDecreaseNoticeEvent(NoticeEvent):
|
||||
__event__ = "notice.group_decrease"
|
||||
notice_type: Literal["group_decrease"]
|
||||
sub_type: str
|
||||
user_id: int
|
||||
@ -366,6 +392,7 @@ class GroupDecreaseNoticeEvent(NoticeEvent):
|
||||
|
||||
|
||||
class GroupIncreaseNoticeEvent(NoticeEvent):
|
||||
__event__ = "notice.group_increase"
|
||||
notice_type: Literal["group_increase"]
|
||||
sub_type: str
|
||||
user_id: int
|
||||
@ -374,6 +401,7 @@ class GroupIncreaseNoticeEvent(NoticeEvent):
|
||||
|
||||
|
||||
class GroupBanNoticeEvent(NoticeEvent):
|
||||
__event__ = "notice.group_ban"
|
||||
notice_type: Literal["group_ban"]
|
||||
sub_type: str
|
||||
user_id: int
|
||||
@ -383,11 +411,13 @@ class GroupBanNoticeEvent(NoticeEvent):
|
||||
|
||||
|
||||
class FriendAddNoticeEvent(NoticeEvent):
|
||||
__event__ = "notice.friend_add"
|
||||
notice_type: Literal["friend_add"]
|
||||
user_id: int
|
||||
|
||||
|
||||
class GroupRecallNoticeEvent(NoticeEvent):
|
||||
__event__ = "notice.group_recall"
|
||||
notice_type: Literal["group_recall"]
|
||||
user_id: int
|
||||
group_id: int
|
||||
@ -396,12 +426,14 @@ class GroupRecallNoticeEvent(NoticeEvent):
|
||||
|
||||
|
||||
class FriendRecallNoticeEvent(NoticeEvent):
|
||||
__event__ = "notice.friend_recall"
|
||||
notice_type: Literal["friend_recall"]
|
||||
user_id: int
|
||||
message_id: int
|
||||
|
||||
|
||||
class NotifyEvent(NoticeEvent):
|
||||
__event__ = "notice.notify"
|
||||
notice_type: Literal["notify"]
|
||||
sub_type: str
|
||||
user_id: int
|
||||
@ -409,19 +441,26 @@ class NotifyEvent(NoticeEvent):
|
||||
|
||||
|
||||
class PokeNotifyEvent(NotifyEvent):
|
||||
__event__ = "notice.notify.poke"
|
||||
sub_type: Literal["poke"]
|
||||
target_id: int
|
||||
|
||||
|
||||
class LuckyKingNotifyEvent(NotifyEvent):
|
||||
__event__ = "notice.notify.lucky_king"
|
||||
sub_type: Literal["lucky_king"]
|
||||
target_id: int
|
||||
|
||||
|
||||
class HonorNotifyEvent(NotifyEvent):
|
||||
__event__ = "notice.notify.honor"
|
||||
sub_type: Literal["honor"]
|
||||
honor_type: str
|
||||
|
||||
|
||||
# Request Events
|
||||
class RequestEvent(CQHTTPEvent):
|
||||
__event__ = "request"
|
||||
post_type: Literal["request"]
|
||||
request_type: str
|
||||
|
||||
@ -433,6 +472,7 @@ class RequestEvent(CQHTTPEvent):
|
||||
|
||||
|
||||
class FriendRequestEvent(RequestEvent):
|
||||
__event__ = "request.friend"
|
||||
request_type: Literal["friend"]
|
||||
user_id: int
|
||||
comment: str
|
||||
@ -440,6 +480,7 @@ class FriendRequestEvent(RequestEvent):
|
||||
|
||||
|
||||
class GroupRequestEvent(RequestEvent):
|
||||
__event__ = "request.group"
|
||||
request_type: Literal["group"]
|
||||
sub_type: str
|
||||
group_id: int
|
||||
@ -450,6 +491,7 @@ class GroupRequestEvent(RequestEvent):
|
||||
|
||||
# Meta Events
|
||||
class MetaEvent(CQHTTPEvent):
|
||||
__event__ = "meta_event"
|
||||
post_type: Literal["meta_event"]
|
||||
meta_event_type: str
|
||||
|
||||
@ -465,11 +507,26 @@ class MetaEvent(CQHTTPEvent):
|
||||
|
||||
|
||||
class LifecycleMetaEvent(MetaEvent):
|
||||
__event__ = "meta_event.lifecycle"
|
||||
meta_event_type: Literal["lifecycle"]
|
||||
sub_type: str
|
||||
|
||||
|
||||
class HeartbeatMetaEvent(MetaEvent):
|
||||
__event__ = "meta_event.heartbeat"
|
||||
meta_event_type: Literal["heartbeat"]
|
||||
status: Status
|
||||
interval: int
|
||||
|
||||
|
||||
_t = StringTrie(separator=".")
|
||||
|
||||
model = None
|
||||
for model in globals().values():
|
||||
if not inspect.isclass(model) or not issubclass(model, CQHTTPEvent):
|
||||
continue
|
||||
_t["." + model.__event__] = model
|
||||
|
||||
|
||||
def get_event_model(event_name) -> List[Type[CQHTTPEvent]]:
|
||||
return [model.value for model in _t.prefixes("." + event_name)][::-1]
|
||||
|
Reference in New Issue
Block a user