2020-04-11 23:04:31 +08:00
|
|
|
from functools import update_wrapper
|
2020-04-07 21:58:10 +08:00
|
|
|
from typing import List, Optional, Callable, Union
|
2018-06-27 22:50:01 +08:00
|
|
|
|
2020-03-15 22:48:22 +08:00
|
|
|
from aiocqhttp import Event as CQEvent
|
2018-06-27 22:50:01 +08:00
|
|
|
from aiocqhttp.bus import EventBus
|
|
|
|
|
2018-07-04 09:28:31 +08:00
|
|
|
from . import NoneBot
|
2018-10-16 01:03:50 +08:00
|
|
|
from .exceptions import CQHttpError
|
2018-06-27 22:50:01 +08:00
|
|
|
from .log import logger
|
2018-07-02 16:54:29 +08:00
|
|
|
from .session import BaseSession
|
2018-06-27 22:50:01 +08:00
|
|
|
|
|
|
|
_bus = EventBus()
|
|
|
|
|
2020-04-07 21:58:10 +08:00
|
|
|
class EventHandler:
|
2020-04-11 23:04:31 +08:00
|
|
|
__slots__ = ('events', 'func', '__name__', '__qualname__', '__doc__',
|
|
|
|
'__annotations__', '__dict__')
|
2020-04-07 21:58:10 +08:00
|
|
|
|
|
|
|
def __init__(self, events: List[str], func: Callable):
|
|
|
|
self.events = events
|
|
|
|
self.func = func
|
|
|
|
|
2018-06-27 22:50:01 +08:00
|
|
|
|
|
|
|
def _make_event_deco(post_type: str) -> Callable:
|
|
|
|
def deco_deco(arg: Optional[Union[str, Callable]] = None,
|
|
|
|
*events: str) -> Callable:
|
2020-04-07 21:58:10 +08:00
|
|
|
def deco(func: Callable) -> EventHandler:
|
2018-06-27 22:50:01 +08:00
|
|
|
if isinstance(arg, str):
|
2020-04-07 21:58:10 +08:00
|
|
|
events_tmp = list(map(lambda x: f"{post_type}.{x}", [arg] + list(events)))
|
|
|
|
for e in events_tmp:
|
|
|
|
_bus.subscribe(e, func)
|
2020-04-11 23:04:31 +08:00
|
|
|
handler = EventHandler(events_tmp, func)
|
|
|
|
return update_wrapper(handler, func) # type: ignore
|
2018-06-27 22:50:01 +08:00
|
|
|
else:
|
|
|
|
_bus.subscribe(post_type, func)
|
2020-04-11 23:04:31 +08:00
|
|
|
handler = EventHandler([post_type], func)
|
|
|
|
return update_wrapper(handler, func) # type: ignore
|
2018-06-27 22:50:01 +08:00
|
|
|
|
|
|
|
if isinstance(arg, Callable):
|
2020-04-07 21:58:10 +08:00
|
|
|
return deco(arg) # type: ignore
|
2018-06-27 22:50:01 +08:00
|
|
|
return deco
|
|
|
|
|
|
|
|
return deco_deco
|
|
|
|
|
|
|
|
|
|
|
|
on_notice = _make_event_deco('notice')
|
|
|
|
on_request = _make_event_deco('request')
|
|
|
|
|
|
|
|
|
|
|
|
class NoticeSession(BaseSession):
|
|
|
|
__slots__ = ()
|
|
|
|
|
2020-03-15 22:48:22 +08:00
|
|
|
def __init__(self, bot: NoneBot, event: CQEvent):
|
|
|
|
super().__init__(bot, event)
|
2018-06-27 22:50:01 +08:00
|
|
|
|
|
|
|
|
|
|
|
class RequestSession(BaseSession):
|
|
|
|
__slots__ = ()
|
|
|
|
|
2020-03-15 22:48:22 +08:00
|
|
|
def __init__(self, bot: NoneBot, event: CQEvent):
|
|
|
|
super().__init__(bot, event)
|
2018-06-27 22:50:01 +08:00
|
|
|
|
2018-08-22 23:00:22 +08:00
|
|
|
async def approve(self, remark: str = '') -> None:
|
|
|
|
"""
|
|
|
|
Approve the request.
|
|
|
|
|
|
|
|
:param remark: remark of friend (only works in friend request)
|
|
|
|
"""
|
2018-06-30 18:26:48 +08:00
|
|
|
try:
|
2018-07-02 23:29:37 +08:00
|
|
|
await self.bot.call_action(
|
|
|
|
action='.handle_quick_operation_async',
|
2020-03-15 22:48:22 +08:00
|
|
|
self_id=self.event.self_id,
|
|
|
|
context=self.event,
|
2018-07-02 23:29:37 +08:00
|
|
|
operation={'approve': True, 'remark': remark}
|
|
|
|
)
|
2018-06-30 18:26:48 +08:00
|
|
|
except CQHttpError:
|
|
|
|
pass
|
|
|
|
|
2018-08-22 23:00:22 +08:00
|
|
|
async def reject(self, reason: str = '') -> None:
|
|
|
|
"""
|
|
|
|
Reject the request.
|
|
|
|
|
|
|
|
:param reason: reason to reject (only works in group request)
|
|
|
|
"""
|
2018-06-30 18:26:48 +08:00
|
|
|
try:
|
2018-07-02 23:29:37 +08:00
|
|
|
await self.bot.call_action(
|
|
|
|
action='.handle_quick_operation_async',
|
2020-03-15 22:48:22 +08:00
|
|
|
self_id=self.event.self_id,
|
|
|
|
context=self.event,
|
2018-07-02 23:29:37 +08:00
|
|
|
operation={'approve': False, 'reason': reason}
|
|
|
|
)
|
2018-06-30 18:26:48 +08:00
|
|
|
except CQHttpError:
|
|
|
|
pass
|
2018-06-27 22:50:01 +08:00
|
|
|
|
|
|
|
|
2020-03-15 22:48:22 +08:00
|
|
|
async def handle_notice_or_request(bot: NoneBot, event: CQEvent) -> None:
|
|
|
|
if event.type == 'notice':
|
|
|
|
_log_notice(event)
|
|
|
|
session = NoticeSession(bot, event)
|
2018-07-01 20:01:05 +08:00
|
|
|
else: # must be 'request'
|
2020-03-15 22:48:22 +08:00
|
|
|
_log_request(event)
|
|
|
|
session = RequestSession(bot, event)
|
2018-06-27 22:50:01 +08:00
|
|
|
|
2020-03-15 22:48:22 +08:00
|
|
|
ev_name = event.name
|
|
|
|
logger.debug(f'Emitting event: {ev_name}')
|
2018-12-25 20:40:36 +08:00
|
|
|
try:
|
2020-03-15 22:48:22 +08:00
|
|
|
await _bus.emit(ev_name, session)
|
2018-12-25 20:40:36 +08:00
|
|
|
except Exception as e:
|
2020-03-15 22:48:22 +08:00
|
|
|
logger.error(f'An exception occurred while handling event {ev_name}:')
|
2018-12-25 20:40:36 +08:00
|
|
|
logger.exception(e)
|
2018-07-21 00:46:34 +08:00
|
|
|
|
|
|
|
|
2020-03-15 22:48:22 +08:00
|
|
|
def _log_notice(event: CQEvent) -> None:
|
|
|
|
logger.info(f'Notice: {event}')
|
2018-07-21 00:46:34 +08:00
|
|
|
|
|
|
|
|
2020-03-15 22:48:22 +08:00
|
|
|
def _log_request(event: CQEvent) -> None:
|
|
|
|
logger.info(f'Request: {event}')
|