Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update to 4.4.1 #62

Merged
merged 5 commits into from
Nov 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions app/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,8 @@ def init_config() -> None:
for item in session.execute(select(Replies)).scalars().fetchall(): # type: Replies
_replies.setdefault(item.group, {})[item.key] = item.value

for _reply_group, _group_replies in _replies.items():
replies.set(reply_group=_reply_group, replies=_group_replies)
for _group, _group_replies in _replies.items():
replies.set_replies(group=_group, replies=_group_replies)

logger.info("Config initialized")

Expand Down
4 changes: 3 additions & 1 deletion app/dispatch.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,9 @@ def load_orders_and_events(self) -> None:

for order in plugin_orders:
if isinstance(order, str) and order:
# Orders should be case-insensitive
orders[plugin.priority].append({
"pattern": re.compile(fr"^({order})\s*([\S\s]*)$"),
"pattern": re.compile(fr"^({order})\s*([\S\s]*)$", re.I),
"name": plugin_name
})

Expand Down Expand Up @@ -114,6 +115,7 @@ def dispatch_order(self, message: Message, message_content: str) -> None:
plugin_class = self.order_plugins[plugin_name]

try:
# Always pass the order converted to lowercase to the plugin
plugin = plugin_class(message, order.lower(), order_content, repetition)

if not plugin.check_enabled():
Expand Down
14 changes: 7 additions & 7 deletions app/exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,37 +8,37 @@ def __init__(self, reply: str) -> None:

class NetworkClientError(DiceRobotException):
def __init__(self) -> None:
super().__init__(replies.get_reply(reply_group="dicerobot", reply_key="network_client_error"))
super().__init__(replies.get_reply(group="dicerobot", key="network_client_error"))


class NetworkServerError(DiceRobotException):
def __init__(self) -> None:
super().__init__(replies.get_reply(reply_group="dicerobot", reply_key="network_server_error"))
super().__init__(replies.get_reply(group="dicerobot", key="network_server_error"))


class NetworkInvalidContentError(DiceRobotException):
def __init__(self) -> None:
super().__init__(replies.get_reply(reply_group="dicerobot", reply_key="network_invalid_content"))
super().__init__(replies.get_reply(group="dicerobot", key="network_invalid_content"))


class NetworkError(DiceRobotException):
def __init__(self) -> None:
super().__init__(replies.get_reply(reply_group="dicerobot", reply_key="network_error"))
super().__init__(replies.get_reply(group="dicerobot", key="network_error"))


class OrderInvalidError(DiceRobotException):
def __init__(self) -> None:
super().__init__(replies.get_reply(reply_group="dicerobot", reply_key="order_invalid"))
super().__init__(replies.get_reply(group="dicerobot", key="order_invalid"))


class OrderSuspiciousError(DiceRobotException):
def __init__(self) -> None:
super().__init__(replies.get_reply(reply_group="dicerobot", reply_key="order_suspicious"))
super().__init__(replies.get_reply(group="dicerobot", key="order_suspicious"))


class OrderRepetitionExceededError(DiceRobotException):
def __init__(self) -> None:
super().__init__(replies.get_reply(reply_group="dicerobot", reply_key="order_repetition_exceeded"))
super().__init__(replies.get_reply(group="dicerobot", key="order_repetition_exceeded"))


class OrderError(DiceRobotException):
Expand Down
12 changes: 7 additions & 5 deletions app/log.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
from typing import Union
import sys
import os
import datetime
from datetime import date
import tarfile

from loguru import logger as _logger

LOG_DIR = os.path.join(os.getcwd(), "logs")
TEMP_LOG_DIR = "/temp/dicerobot-logs"
TEMP_LOG_DIR = "/tmp/dicerobot-logs"
MAX_LENGTH = 1000
MAX_FILE_SIZE = 5 * 1024 * 1024 # 5 MB

Expand Down Expand Up @@ -37,15 +37,17 @@ def init_logger() -> None:
logger.debug("Logger initialized")


def load_logs(date: datetime.date) -> Union[list[str], None, False]:
date = date.strftime("%Y-%m-%d")
file = f"dicerobot-{date}.log"
def load_logs(date_: date) -> Union[list[str], None, False]:
date_ = date_.strftime("%Y-%m-%d")
file = f"dicerobot-{date_}.log"
log_file = os.path.join(LOG_DIR, file)
compressed_file = os.path.join(LOG_DIR, f"{file}.tar.gz")
temp_log_file = os.path.join(TEMP_LOG_DIR, file)

if os.path.isfile(log_file):
return load_log_file(log_file)
elif os.path.isfile(temp_log_file):
return load_log_file(temp_log_file)
elif os.path.isfile(compressed_file):
with tarfile.open(compressed_file, "r:gz") as tar:
tar.extract(file, TEMP_LOG_DIR)
Expand Down
42 changes: 27 additions & 15 deletions app/models/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -276,7 +276,10 @@ def set(cls, *, plugin: str, settings: dict) -> None:
settings: Settings to be set.
"""

cls._plugin_settings[plugin] = deepcopy(settings)
if plugin in cls._plugin_settings:
cls._plugin_settings[plugin] |= deepcopy(settings)
else:
cls._plugin_settings[plugin] = deepcopy(settings)

@classmethod
def dict(cls) -> dict:
Expand Down Expand Up @@ -323,7 +326,11 @@ def set(cls, *, chat_type: ChatType, chat_id: int, setting_group: str, settings:
setting_group: Setting group.
settings: Settings to be set.
"""
cls._chat_settings[chat_type].setdefault(chat_id, {})[setting_group] = deepcopy(settings)

if setting_group in cls._chat_settings[chat_type].setdefault(chat_id, {}):
cls._chat_settings[chat_type][chat_id][setting_group] |= deepcopy(settings)
else:
cls._chat_settings[chat_type][chat_id][setting_group] = deepcopy(settings)

@classmethod
def dict(cls) -> dict:
Expand All @@ -332,6 +339,7 @@ def dict(cls) -> dict:
Returns:
A deep copy of all chat settings.
"""

return deepcopy(cls._chat_settings)


Expand All @@ -351,41 +359,45 @@ class Replies:
}

@classmethod
def get(cls, *, reply_group: str) -> dict:
"""Get replies of a plugin.
def get_replies(cls, *, group: str) -> dict:
"""Get replies of a group.

Args:
reply_group: Reply group, usually the name of the plugin.
group: Reply group, usually the name of the plugin.

Returns:
A deep copy of the replies of the reply group, for preventing modification.
"""

return deepcopy(cls._replies.setdefault(reply_group, {}))
return deepcopy(cls._replies.setdefault(group, {}))

@classmethod
def get_reply(cls, *, reply_group: str, reply_key: str) -> str:
"""Get a reply of a plugin.
def get_reply(cls, *, group: str, key: str) -> str:
"""Get a reply of a group.

Args:
reply_group: Reply group, usually the name of the plugin.
reply_key: Reply key.
group: Reply group, usually the name of the plugin.
key: Reply key.

Returns:
The reply.
"""
return cls._replies[reply_group][reply_key]

return cls._replies[group][key]

@classmethod
def set(cls, *, reply_group: str, replies: dict) -> None:
"""Set replies of a plugin.
def set_replies(cls, *, group: str, replies: dict) -> None:
"""Set replies of a group.

Args:
reply_group: Reply group, usually the name of the plugin.
group: Reply group, usually the name of the plugin.
replies: Replies to be set.
"""

cls._replies[reply_group] = deepcopy(replies)
if group in cls._replies:
cls._replies[group] |= deepcopy(replies)
else:
cls._replies[group] = deepcopy(replies)

@classmethod
def dict(cls) -> dict:
Expand Down
11 changes: 6 additions & 5 deletions app/router/admin.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
from typing import Annotated
from datetime import date, datetime, timedelta
import signal

from fastapi import APIRouter, Depends
from fastapi import APIRouter, Depends, Query

from ..log import logger, load_logs
from ..auth import verify_password, generate_jwt_token, verify_jwt_token
Expand Down Expand Up @@ -34,7 +35,7 @@ async def auth(data: AuthRequest) -> JSONResponse:


@router.get("/logs", dependencies=[Depends(verify_jwt_token, use_cache=False)])
async def get_logs(date_: date) -> JSONResponse:
async def get_logs(date_: Annotated[date, Query(alias="date")]) -> JSONResponse:
logger.info(f"Admin request received: get logs, date: {date_}")

if (logs := load_logs(date_)) is None:
Expand Down Expand Up @@ -160,7 +161,7 @@ async def get_plugin_replies(plugin: str) -> JSONResponse:
if plugin not in status.plugins:
raise ResourceNotFoundError(message="Plugin not found")

return JSONResponse(data=replies.get(reply_group=plugin))
return JSONResponse(data=replies.get_replies(group=plugin))


@router.patch("/plugin/{plugin}/replies", dependencies=[Depends(verify_jwt_token, use_cache=False)])
Expand All @@ -170,7 +171,7 @@ async def update_plugin_replies(plugin: str, data: dict[str, str]) -> JSONRespon
if plugin not in status.plugins:
raise ResourceNotFoundError(message="Plugin not found")

replies.set(reply_group=plugin, replies=data)
replies.set_replies(group=plugin, replies=data)
dispatcher.find_plugin(plugin).load()

return JSONResponse()
Expand All @@ -183,7 +184,7 @@ async def reset_plugin_replies(plugin: str) -> JSONResponse:
if plugin not in status.plugins:
raise ResourceNotFoundError(message="Plugin not found")

replies.set(reply_group=plugin, replies={})
replies.set_replies(group=plugin, replies={})
dispatcher.find_plugin(plugin).load()

return JSONResponse()
Expand Down
2 changes: 1 addition & 1 deletion app/version.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
VERSION = "4.4.0"
VERSION = "4.4.1"
14 changes: 7 additions & 7 deletions plugin/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,9 @@ def load(cls) -> None:
{"enabled": True},
deepcopy(cls.default_plugin_settings), plugin_settings.get(plugin=cls.name)
))
replies.set(reply_group=cls.name, replies=deep_update(
replies.set_replies(group=cls.name, replies=deep_update(
deepcopy(cls.default_replies),
replies.get(reply_group=cls.name)
replies.get_replies(group=cls.name)
))

@classmethod
Expand Down Expand Up @@ -79,27 +79,27 @@ def get_plugin_setting(cls, *, plugin: str = None, key: str) -> Any:
return plugin_settings.get(plugin=plugin or cls.name)[key]

@classmethod
def get_reply(cls, *, reply_group: str = None, reply_key: str) -> str:
def get_reply(cls, *, group: str = None, key: str) -> str:
"""Get plugin reply.

This method should only be used to dynamically get plugin reply within a class method. For normal execution,
use ``self.replies`` instead.

Args:
reply_group: Reply group.
reply_key: Reply key.
group: Reply group.
key: Reply key.

Returns:
Reply.
"""

return replies.get_reply(reply_group=reply_group or cls.name, reply_key=reply_key)
return replies.get_reply(group=group or cls.name, key=key)

def __init__(self) -> None:
"""Initialize DiceRobot plugin."""

self.plugin_settings = plugin_settings.get(plugin=self.name)
self.replies = replies.get(reply_group=self.name)
self.replies = replies.get_replies(group=self.name)

@abstractmethod
def __call__(self) -> None:
Expand Down
4 changes: 2 additions & 2 deletions plugin/dicerobot/order/daily_60s.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ class DailySixtySeconds(OrderPlugin):
name = "dicerobot.daily_60s"
display_name = "每天60秒读懂世界"
description = "每天60秒读懂世界,15条简报+1条微语,让你瞬间了解世界正在发生的大事"
version = "1.1.3"
version = "1.1.4"

default_plugin_settings = {
"api": "https://api.2xb.cn/zaob",
Expand Down Expand Up @@ -42,7 +42,7 @@ def send_daily_60s(cls) -> None:
if result["datatime"] == str(datetime.date.today()):
message = [Image(data=Image.Data(file=result["imageUrl"]))]
else:
message = cls.get_reply(reply_key="api_error")
message = cls.get_reply(key="api_error")

for chat_id in cls.get_plugin_setting(key="subscribers"):
cls.send_group_message(chat_id, message)
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[tool.poetry]
name = "dicerobot"
version = "4.4.0"
version = "4.4.1"
description = "A TRPG assistant bot"
authors = ["Drsanwujiang <[email protected]>"]
license = "MIT"
Expand Down