chore(lint): add mypy

This commit is contained in:
XYenon 2022-03-09 22:06:40 +08:00
parent 2c2ff9de1e
commit b07c89d06b
6 changed files with 116 additions and 210 deletions

View File

@ -15,3 +15,12 @@ repos:
rev: 5.10.1 rev: 5.10.1
hooks: hooks:
- id: isort - id: isort
- repo: https://github.com/pre-commit/mirrors-mypy
rev: v0.931
hooks:
- id: mypy
additional_dependencies:
- types-requests
- types-setuptools
- types-toml

View File

@ -17,6 +17,7 @@ from efb_qq_slave import BaseClient, QQMessengerChannel
from ehforwarderbot import Chat, Message, MsgType, Status, coordinator from ehforwarderbot import Chat, Message, MsgType, Status, coordinator
from ehforwarderbot.chat import ( from ehforwarderbot.chat import (
ChatMember, ChatMember,
GroupChat,
PrivateChat, PrivateChat,
SelfChatMember, SelfChatMember,
SystemChatMember, SystemChatMember,
@ -26,7 +27,6 @@ from ehforwarderbot.exceptions import (
EFBMessageError, EFBMessageError,
EFBOperationNotSupported, EFBOperationNotSupported,
) )
from ehforwarderbot.chat import GroupChat
from ehforwarderbot.message import MessageCommand, MessageCommands from ehforwarderbot.message import MessageCommand, MessageCommands
from ehforwarderbot.status import MessageRemoval from ehforwarderbot.status import MessageRemoval
from ehforwarderbot.types import ChatID, MessageID from ehforwarderbot.types import ChatID, MessageID
@ -68,18 +68,15 @@ class GoCQHttp(BaseClient):
fallback=True, fallback=True,
) )
_ = translator.gettext friend_list: List[Dict] = []
ngettext = translator.ngettext
friend_list = []
friend_dict: Dict[int, dict] = {} friend_dict: Dict[int, dict] = {}
stranger_dict: Dict[int, dict] = {} stranger_dict: Dict[int, dict] = {}
group_list = [] group_list: List[Dict] = []
group_dict: Dict[int, dict] = {} group_dict: Dict[int, dict] = {}
group_member_dict: Dict[int, Dict[str, Any]] = {} group_member_dict: Dict[int, Dict[str, Any]] = {}
group_member_info_dict: Dict[Tuple[int, int], dict] = {} group_member_info_dict: Dict[Tuple[int, int], dict] = {}
discuss_list = [] discuss_list: List[Dict] = []
extra_group_list = [] extra_group_list: List[Dict] = []
repeat_counter = 0 repeat_counter = 0
update_repeat_counter = 0 update_repeat_counter = 0
event = threading.Event() event = threading.Event()
@ -106,7 +103,7 @@ class GoCQHttp(BaseClient):
self.msg_decorator = QQMsgProcessor(instance=self) self.msg_decorator = QQMsgProcessor(instance=self)
def forward_msgs_wrapper(msg_elements: List[Dict[str, Any]]) -> List[Dict[str, Any]]: def forward_msgs_wrapper(msg_elements: List[Dict[str, Any]]) -> List[Dict[str, Any]]:
fmt_msgs = [] fmt_msgs: List[Dict] = []
for msg in msg_elements: for msg in msg_elements:
from_user = self.get_user_info(msg["sender"]["user_id"]) from_user = self.get_user_info(msg["sender"]["user_id"])
header_text = {"data": {"text": f'{from_user["remark"]}{from_user["nickname"]}\n'}, "type": "text"} header_text = {"data": {"text": f'{from_user["remark"]}{from_user["nickname"]}\n'}, "type": "text"}
@ -173,7 +170,8 @@ class GoCQHttp(BaseClient):
footer_msg = {"data": {"text": "合并转发消息结束"}, "type": "text"} footer_msg = {"data": {"text": "合并转发消息结束"}, "type": "text"}
fmt_forward_msgs.insert(0, header_msg) fmt_forward_msgs.insert(0, header_msg)
fmt_forward_msgs.append(footer_msg) fmt_forward_msgs.append(footer_msg)
return message_elements_wrapper(context, fmt_forward_msgs, chat) main_text, messages, _ = message_elements_wrapper(context, fmt_forward_msgs, chat)
return main_text, messages, []
else: else:
messages.extend(self.call_msg_decorator(msg_type, msg_data, chat)) messages.extend(self.call_msg_decorator(msg_type, msg_data, chat))
return main_text, messages, at_list return main_text, messages, at_list
@ -215,7 +213,7 @@ class GoCQHttp(BaseClient):
if "anonymous" not in context or context["anonymous"] is None: if "anonymous" not in context or context["anonymous"] is None:
if context["message_type"] == "group": if context["message_type"] == "group":
if context["sub_type"] == "notice": if context["sub_type"] == "notice":
context["event_description"] = self._("System Notification") context["event_description"] = "System Notification"
context["uid_prefix"] = "group_notification" context["uid_prefix"] = "group_notification"
author = chat.add_system_member( author = chat.add_system_member(
name=context["event_description"], name=context["event_description"],
@ -242,8 +240,11 @@ class GoCQHttp(BaseClient):
if not isinstance(messages[i], Message): if not isinstance(messages[i], Message):
continue continue
efb_msg: Message = messages[i] efb_msg: Message = messages[i]
efb_msg.uid = f"{chat.uid.split('_')[-1]}_{coolq_msg_id}_{i}" if i > 0 else \ efb_msg.uid = (
f"{chat.uid.split('_')[-1]}_{coolq_msg_id}" f"{chat.uid.split('_')[-1]}_{coolq_msg_id}_{i}"
if i > 0
else f"{chat.uid.split('_')[-1]}_{coolq_msg_id}"
)
efb_msg.chat = chat efb_msg.chat = chat
efb_msg.author = author efb_msg.author = author
# if qq_uid != '80000000': # if qq_uid != '80000000':
@ -261,11 +262,11 @@ class GoCQHttp(BaseClient):
@self.coolq_bot.on_notice("group_increase") @self.coolq_bot.on_notice("group_increase")
def handle_group_increase_msg(context): def handle_group_increase_msg(context):
context["event_description"] = self._("\u2139 Group Member Increase Event") context["event_description"] = "\u2139 Group Member Increase Event"
if (context["sub_type"]) == "invite": if (context["sub_type"]) == "invite":
text = self._("{nickname}({context[user_id]}) joined the group({group_name}) via invitation") text = "{nickname}({context[user_id]}) joined the group({group_name}) via invitation"
else: else:
text = self._("{nickname}({context[user_id]}) joined the group({group_name})") text = "{nickname}({context[user_id]}) joined the group({group_name})"
original_group = self.get_group_info(context["group_id"], False) original_group = self.get_group_info(context["group_id"], False)
group_name = context["group_id"] group_name = context["group_id"]
@ -282,19 +283,19 @@ class GoCQHttp(BaseClient):
@self.coolq_bot.on_notice("group_decrease") @self.coolq_bot.on_notice("group_decrease")
def handle_group_decrease_msg(context): def handle_group_decrease_msg(context):
context["event_description"] = self._("\u2139 Group Member Decrease Event") context["event_description"] = "\u2139 Group Member Decrease Event"
original_group = self.get_group_info(context["group_id"], False) original_group = self.get_group_info(context["group_id"], False)
group_name = context["group_id"] group_name = context["group_id"]
if original_group is not None and "group_name" in original_group: if original_group is not None and "group_name" in original_group:
group_name = original_group["group_name"] group_name = original_group["group_name"]
text = "" text = ""
if context["sub_type"] == "kick_me": if context["sub_type"] == "kick_me":
text = self._("You've been kicked from the group({})").format(group_name) text = ("You've been kicked from the group({})").format(group_name)
else: else:
if context["sub_type"] == "leave": if context["sub_type"] == "leave":
text = self._("{nickname}({context[user_id]}) quited the group({group_name})") text = "{nickname}({context[user_id]}) quited the group({group_name})"
else: else:
text = self._("{nickname}({context[user_id]}) was kicked from the group({group_name})") text = "{nickname}({context[user_id]}) was kicked from the group({group_name})"
text = text.format( text = text.format(
nickname=self.get_stranger_info(context["user_id"])["nickname"], nickname=self.get_stranger_info(context["user_id"])["nickname"],
context=context, context=context,
@ -305,11 +306,11 @@ class GoCQHttp(BaseClient):
@self.coolq_bot.on_notice("offline_file") @self.coolq_bot.on_notice("offline_file")
def handle_offline_file_upload_msg(context): def handle_offline_file_upload_msg(context):
context["event_description"] = self._("\u2139 Offline File Upload Event") context["event_description"] = "\u2139 Offline File Upload Event"
context["uid_prefix"] = "offline_file" context["uid_prefix"] = "offline_file"
file_info_msg = self._("Filename: {file[name]}\n" "File size: {file[size]}").format(file=context["file"]) file_info_msg = ("Filename: {file[name]}\n" "File size: {file[size]}").format(file=context["file"])
user = self.get_user_info(context["user_id"]) user = self.get_user_info(context["user_id"])
text = self._("{remark}({nickname}) uploaded a file to you\n") text = "{remark}({nickname}) uploaded a file to you\n"
text = text.format(remark=user["remark"], nickname=user["nickname"]) + file_info_msg text = text.format(remark=user["remark"], nickname=user["nickname"]) + file_info_msg
context["message"] = text context["message"] = text
self.send_msg_to_master(context) self.send_msg_to_master(context)
@ -321,19 +322,19 @@ class GoCQHttp(BaseClient):
@self.coolq_bot.on_notice("group_upload") @self.coolq_bot.on_notice("group_upload")
def handle_group_file_upload_msg(context): def handle_group_file_upload_msg(context):
context["event_description"] = self._("\u2139 Group File Upload Event") context["event_description"] = "\u2139 Group File Upload Event"
context["uid_prefix"] = "group_upload" context["uid_prefix"] = "group_upload"
original_group = self.get_group_info(context["group_id"], False) original_group = self.get_group_info(context["group_id"], False)
group_name = context["group_id"] group_name = context["group_id"]
if original_group is not None and "group_name" in original_group: if original_group is not None and "group_name" in original_group:
group_name = original_group["group_name"] group_name = original_group["group_name"]
file_info_msg = self._("File ID: {file[id]}\n" "Filename: {file[name]}\n" "File size: {file[size]}").format( file_info_msg = ("File ID: {file[id]}\n" "Filename: {file[name]}\n" "File size: {file[size]}").format(
file=context["file"] file=context["file"]
) )
member_info = self.get_user_info(context["user_id"], group_id=context["group_id"])["in_group_info"] member_info = self.get_user_info(context["user_id"], group_id=context["group_id"])["in_group_info"]
group_card = member_info["card"] if member_info["card"] != "" else member_info["nickname"] group_card = member_info["card"] if member_info["card"] != "" else member_info["nickname"]
text = self._("{member_card}({context[user_id]}) uploaded a file to group({group_name})\n") text = "{member_card}({context[user_id]}) uploaded a file to group({group_name})\n"
text = text.format(member_card=group_card, context=context, group_name=group_name) + file_info_msg text = text.format(member_card=group_card, context=context, group_name=group_name) + file_info_msg
context["message"] = text context["message"] = text
self.send_efb_group_notice(context) self.send_efb_group_notice(context)
@ -349,9 +350,9 @@ class GoCQHttp(BaseClient):
@self.coolq_bot.on_notice("friend_add") @self.coolq_bot.on_notice("friend_add")
def handle_friend_add_msg(context): def handle_friend_add_msg(context):
context["event_description"] = self._("\u2139 New Friend Event") context["event_description"] = "\u2139 New Friend Event"
context["uid_prefix"] = "friend_add" context["uid_prefix"] = "friend_add"
text = self._("{nickname}({context[user_id]}) has become your friend!") text = "{nickname}({context[user_id]}) has become your friend!"
text = text.format( text = text.format(
nickname=self.get_stranger_info(context["user_id"])["nickname"], nickname=self.get_stranger_info(context["user_id"])["nickname"],
context=context, context=context,
@ -364,13 +365,10 @@ class GoCQHttp(BaseClient):
coolq_msg_id = context["message_id"] coolq_msg_id = context["message_id"]
chat = GroupChat(channel=self.channel, uid=f"group_{context['group_id']}") chat = GroupChat(channel=self.channel, uid=f"group_{context['group_id']}")
efb_msg = Message( efb_msg = Message(chat=chat, uid=MessageID(f"{chat.uid.split('_')[-1]}_{coolq_msg_id}"))
chat=chat, coordinator.send_status(
uid=MessageID(f"{chat.uid.split('_')[-1]}_{coolq_msg_id}") MessageRemoval(source_channel=self.channel, destination_channel=coordinator.master, message=efb_msg)
) )
coordinator.send_status(MessageRemoval(source_channel=self.channel,
destination_channel=coordinator.master,
message=efb_msg))
@self.coolq_bot.on_notice("friend_recall") @self.coolq_bot.on_notice("friend_recall")
def handle_friend_recall_msg(context): def handle_friend_recall_msg(context):
@ -378,22 +376,19 @@ class GoCQHttp(BaseClient):
try: try:
chat: PrivateChat = self.chat_manager.build_efb_chat_as_private(context) chat: PrivateChat = self.chat_manager.build_efb_chat_as_private(context)
except: except Exception:
return return
efb_msg = Message( efb_msg = Message(chat=chat, uid=MessageID(f"{chat.uid.split('_')[-1]}_{coolq_msg_id}"))
chat=chat, coordinator.send_status(
uid=MessageID(f"{chat.uid.split('_')[-1]}_{coolq_msg_id}") MessageRemoval(source_channel=self.channel, destination_channel=coordinator.master, message=efb_msg)
) )
coordinator.send_status(MessageRemoval(source_channel=self.channel,
destination_channel=coordinator.master,
message=efb_msg))
@self.coolq_bot.on_request("friend") # Add friend request @self.coolq_bot.on_request("friend") # Add friend request
def handle_add_friend_request(context): def handle_add_friend_request(context):
self.logger.debug(repr(context)) self.logger.debug(repr(context))
context["event_description"] = self._("\u2139 New Friend Request") context["event_description"] = "\u2139 New Friend Request"
context["uid_prefix"] = "friend_request" context["uid_prefix"] = "friend_request"
text = self._( text = (
"{nickname}({context[user_id]}) wants to be your friend!\n" "{nickname}({context[user_id]}) wants to be your friend!\n"
"Here is the verification comment:\n" "Here is the verification comment:\n"
"{context[comment]}" "{context[comment]}"
@ -405,12 +400,12 @@ class GoCQHttp(BaseClient):
context["message"] = text context["message"] = text
commands = [ commands = [
MessageCommand( MessageCommand(
name=self._("Accept"), name=("Accept"),
callable_name="process_friend_request", callable_name="process_friend_request",
kwargs={"result": "accept", "flag": context["flag"]}, kwargs={"result": "accept", "flag": context["flag"]},
), ),
MessageCommand( MessageCommand(
name=self._("Decline"), name=("Decline"),
callable_name="process_friend_request", callable_name="process_friend_request",
kwargs={"result": "decline", "flag": context["flag"]}, kwargs={"result": "decline", "flag": context["flag"]},
), ),
@ -422,7 +417,7 @@ class GoCQHttp(BaseClient):
def handle_group_request(context): def handle_group_request(context):
self.logger.debug(repr(context)) self.logger.debug(repr(context))
context["uid_prefix"] = "group_request" context["uid_prefix"] = "group_request"
context["group_name"] = self._("[Request]") + self.get_group_info(context["group_id"])["group_name"] context["group_name"] = ("[Request]") + self.get_group_info(context["group_id"])["group_name"]
context["group_id_orig"] = context["group_id"] context["group_id_orig"] = context["group_id"]
context["group_id"] = str(context["group_id"]) + "_notification" context["group_id"] = str(context["group_id"]) + "_notification"
context["message_type"] = "group" context["message_type"] = "group"
@ -455,7 +450,7 @@ class GoCQHttp(BaseClient):
msg.commands = MessageCommands( msg.commands = MessageCommands(
[ [
MessageCommand( MessageCommand(
name=self._("Accept"), name=("Accept"),
callable_name="process_group_request", callable_name="process_group_request",
kwargs={ kwargs={
"result": "accept", "result": "accept",
@ -464,7 +459,7 @@ class GoCQHttp(BaseClient):
}, },
), ),
MessageCommand( MessageCommand(
name=self._("Decline"), name=("Decline"),
callable_name="process_group_request", callable_name="process_group_request",
kwargs={ kwargs={
"result": "decline", "result": "decline",
@ -493,8 +488,8 @@ class GoCQHttp(BaseClient):
cherrypy.engine.wait(states.EXITING) cherrypy.engine.wait(states.EXITING)
@extra( @extra(
name=_("Restart CoolQ Client"), name=("Restart CoolQ Client"),
desc=_( desc=(
"Force CoolQ to restart\n" "Force CoolQ to restart\n"
"Usage: {function_name} [-l] [-c] [-e]\n" "Usage: {function_name} [-l] [-c] [-e]\n"
" -l: Restart and clean log\n" " -l: Restart and clean log\n"
@ -516,7 +511,7 @@ class GoCQHttp(BaseClient):
elif each_param == "-e": elif each_param == "-e":
param_dict["clean_event"] = "true" param_dict["clean_event"] = "true"
else: else:
return self._("Unknown parameter: {}.").format(param) return ("Unknown parameter: {}.").format(param)
self.logger.debug(repr(param_dict)) self.logger.debug(repr(param_dict))
self.coolq_api_query("_set_restart", **param_dict) self.coolq_api_query("_set_restart", **param_dict)
return "Done. Please wait for a while." return "Done. Please wait for a while."
@ -525,8 +520,8 @@ class GoCQHttp(BaseClient):
raise NotImplementedError raise NotImplementedError
@extra( @extra(
name=_("Check CoolQ Status"), name=("Check CoolQ Status"),
desc=_("Force efb-qq-slave to refresh status from CoolQ Client.\n" "Usage: {function_name}"), desc=("Force efb-qq-slave to refresh status from CoolQ Client.\n" "Usage: {function_name}"),
) )
def login(self, param: str = ""): def login(self, param: str = ""):
self.check_status_periodically(None) self.check_status_periodically(None)
@ -577,7 +572,7 @@ class GoCQHttp(BaseClient):
try: try:
self.update_friend_list() # Force update friend list self.update_friend_list() # Force update friend list
except CoolQAPIFailureException: except CoolQAPIFailureException:
self.deliver_alert_to_master(self._("Failed to retrieve the friend list.\n" "Only groups are shown.")) self.deliver_alert_to_master(("Failed to retrieve the friend list.\n" "Only groups are shown."))
return [] return []
users = [] users = []
for current_user in self.friend_list: for current_user in self.friend_list:
@ -616,7 +611,7 @@ class GoCQHttp(BaseClient):
self.recall_message(uid_type[1]) self.recall_message(uid_type[1])
except CoolQAPIFailureException: except CoolQAPIFailureException:
raise EFBOperationNotSupported( raise EFBOperationNotSupported(
self._("Failed to recall the message!\n" "This message may have already expired.") ("Failed to recall the message!\n" "This message may have already expired.")
) )
if msg.type in [MsgType.Text, MsgType.Link]: if msg.type in [MsgType.Text, MsgType.Link]:
@ -646,7 +641,7 @@ class GoCQHttp(BaseClient):
if not self.can_send_image: if not self.can_send_image:
self.check_features() # Force checking features self.check_features() # Force checking features
raise EFBOperationNotSupported( raise EFBOperationNotSupported(
self._("Unable to send image now. Please check your CoolQ version " "or retry later") ("Unable to send image now. Please check your CoolQ version " "or retry later")
) )
if msg.type != MsgType.Sticker: if msg.type != MsgType.Sticker:
text += m.coolq_code_image_wrapper(msg.file, msg.path) text += m.coolq_code_image_wrapper(msg.file, msg.path)
@ -673,7 +668,7 @@ class GoCQHttp(BaseClient):
if not self.can_send_voice: if not self.can_send_voice:
self.check_features() # Force checking features self.check_features() # Force checking features
raise EFBOperationNotSupported( raise EFBOperationNotSupported(
self._( (
"Unable to send voice now. Please check your CoolQ version " "Unable to send voice now. Please check your CoolQ version "
" and install CoolQ audio library or retry later" " and install CoolQ audio library or retry later"
) )
@ -710,7 +705,7 @@ class GoCQHttp(BaseClient):
try: try:
member_list = self.coolq_api_query("get_group_member_list", group_id=group_id, no_cache=no_cache) member_list = self.coolq_api_query("get_group_member_list", group_id=group_id, no_cache=no_cache)
except CoolQAPIFailureException as e: except CoolQAPIFailureException as e:
self.deliver_alert_to_master(self._("Failed the get group member detail.") + "{}".format(e)) self.deliver_alert_to_master(("Failed the get group member detail.") + "{}".format(e))
return [] return []
self.group_member_dict[group_id] = { self.group_member_dict[group_id] = {
"members": member_list, "members": member_list,
@ -722,15 +717,19 @@ class GoCQHttp(BaseClient):
user_id = int(user_id) user_id = int(user_id)
if no_cache or (not self.friend_list) or (user_id not in self.friend_dict): if no_cache or (not self.friend_list) or (user_id not in self.friend_dict):
self.update_friend_list() self.update_friend_list()
friend = copy.deepcopy(self.friend_dict.get(user_id)) friend = self.friend_dict.get(user_id)
if friend: if friend:
user = friend user = copy.deepcopy(friend)
user["is_friend"] = True user["is_friend"] = True
else: else:
user = copy.deepcopy(self.stranger_dict.get(user_id)) if no_cache:
if no_cache or (user is None): stranger = self.coolq_api_query("get_stranger_info", user_id=user_id)
user = self.coolq_api_query("get_stranger_info", user_id=user_id) self.stranger_dict[user_id] = stranger
self.stranger_dict[user_id] = copy.deepcopy(user) stranger = self.stranger_dict.get(user_id)
if stranger is None:
stranger = self.coolq_api_query("get_stranger_info", user_id=user_id)
self.stranger_dict[user_id] = stranger
user = copy.deepcopy(stranger)
user["is_friend"] = False user["is_friend"] = False
if group_id is not None: if group_id is not None:
user["is_in_group"] = False user["is_in_group"] = False
@ -773,12 +772,10 @@ class GoCQHttp(BaseClient):
func = getattr(self.coolq_bot, func_name) func = getattr(self.coolq_bot, func_name)
res = func(**kwargs) res = func(**kwargs)
except RequestException as e: except RequestException as e:
raise CoolQDisconnectedException( raise CoolQDisconnectedException(("Unable to connect to CoolQ Client!" "Error Message:\n{}").format(str(e)))
self._("Unable to connect to CoolQ Client!" "Error Message:\n{}").format(str(e))
)
except cqhttp.Error as ex: except cqhttp.Error as ex:
api_ex = CoolQAPIFailureException( api_ex = CoolQAPIFailureException(
self._("CoolQ HTTP API encountered an error!\n" "Status Code:{} " "Return Code:{}").format( ("CoolQ HTTP API encountered an error!\n" "Status Code:{} " "Return Code:{}").format(
ex.status_code, ex.retcode ex.status_code, ex.retcode
) )
) )
@ -793,9 +790,9 @@ class GoCQHttp(BaseClient):
if res["good"] or res["online"]: if res["good"] or res["online"]:
return True return True
else: else:
raise CoolQOfflineException(self._("CoolQ Client isn't working correctly!")) raise CoolQOfflineException(("CoolQ Client isn't working correctly!"))
def coolq_api_query(self, func_name, **kwargs): def coolq_api_query(self, func_name, **kwargs) -> Any:
"""# Do not call get_status too frequently """# Do not call get_status too frequently
if self.check_running_status(): if self.check_running_status():
return self._coolq_api_wrapper(func_name, **kwargs) return self._coolq_api_wrapper(func_name, **kwargs)
@ -803,7 +800,7 @@ class GoCQHttp(BaseClient):
if self.is_logged_in and self.is_connected: if self.is_logged_in and self.is_connected:
return self._coolq_api_wrapper(func_name, **kwargs) return self._coolq_api_wrapper(func_name, **kwargs)
elif self.repeat_counter < 3: elif self.repeat_counter < 3:
self.deliver_alert_to_master(self._("Your status is offline.\n" "You may try login with /0_login")) self.deliver_alert_to_master(("Your status is offline.\n" "You may try login with /0_login"))
self.repeat_counter += 1 self.repeat_counter += 1
def check_status_periodically(self, t_event): def check_status_periodically(self, t_event):
@ -815,7 +812,7 @@ class GoCQHttp(BaseClient):
except CoolQDisconnectedException as e: except CoolQDisconnectedException as e:
if self.repeat_counter < 3: if self.repeat_counter < 3:
self.deliver_alert_to_master( self.deliver_alert_to_master(
self._( (
"We're unable to communicate with CoolQ Client.\n" "We're unable to communicate with CoolQ Client.\n"
"Please check the connection and credentials provided.\n" "Please check the connection and credentials provided.\n"
"{}" "{}"
@ -828,7 +825,7 @@ class GoCQHttp(BaseClient):
except (CoolQOfflineException, CoolQAPIFailureException): except (CoolQOfflineException, CoolQAPIFailureException):
if self.repeat_counter < 3: if self.repeat_counter < 3:
self.deliver_alert_to_master( self.deliver_alert_to_master(
self._( (
"CoolQ is running in abnormal status.\n" "CoolQ is running in abnormal status.\n"
"You may need to relogin your account " "You may need to relogin your account "
"or have a check in CoolQ Client.\n" "or have a check in CoolQ Client.\n"
@ -842,7 +839,7 @@ class GoCQHttp(BaseClient):
if not flag: if not flag:
if self.repeat_counter < 3: if self.repeat_counter < 3:
self.deliver_alert_to_master( self.deliver_alert_to_master(
self._( (
"We don't know why, but status check failed.\n" "We don't know why, but status check failed.\n"
"Please enable debug mode and consult the log " "Please enable debug mode and consult the log "
"for more details." "for more details."
@ -866,7 +863,7 @@ class GoCQHttp(BaseClient):
context = { context = {
"message": message, "message": message,
"uid_prefix": "alert", "uid_prefix": "alert",
"event_description": self._("CoolQ Alert"), "event_description": ("CoolQ Alert"),
} }
self.send_msg_to_master(context) self.send_msg_to_master(context)
@ -901,7 +898,7 @@ class GoCQHttp(BaseClient):
if (ex.status_code) == 200 and (ex.retcode) == 104 and self.update_repeat_counter < 3: if (ex.status_code) == 200 and (ex.retcode) == 104 and self.update_repeat_counter < 3:
self.send_cookie_expired_alarm() self.send_cookie_expired_alarm()
if self.update_repeat_counter < 3: if self.update_repeat_counter < 3:
self.deliver_alert_to_master(self._("Errors occurred when updating contacts: ") + (ex.message)) self.deliver_alert_to_master(("Errors occurred when updating contacts: ") + (ex.message))
self.update_repeat_counter += 1 self.update_repeat_counter += 1
else: else:
self.update_repeat_counter = 0 self.update_repeat_counter = 0
@ -968,12 +965,12 @@ class GoCQHttp(BaseClient):
def send_status(self, status: "Status"): def send_status(self, status: "Status"):
if isinstance(status, MessageRemoval): if isinstance(status, MessageRemoval):
if not isinstance(status.message.author, SelfChatMember): if not isinstance(status.message.author, SelfChatMember):
raise EFBMessageError(self._("You can only recall your own messages.")) raise EFBMessageError(("You can only recall your own messages."))
try: try:
uid_type = status.message.uid.split("_") uid_type = status.message.uid.split("_")
self.recall_message(uid_type[1]) self.recall_message(uid_type[1])
except CoolQAPIFailureException: except CoolQAPIFailureException:
raise EFBMessageError(self._("Failed to recall the message. This message may have already expired.")) raise EFBMessageError(("Failed to recall the message. This message may have already expired."))
else: else:
raise EFBOperationNotSupported() raise EFBOperationNotSupported()
# todo # todo
@ -983,7 +980,7 @@ class GoCQHttp(BaseClient):
def send_cookie_expired_alarm(self): def send_cookie_expired_alarm(self):
self.deliver_alert_to_master( self.deliver_alert_to_master(
self._( (
"Your cookie of CoolQ Client seems to be expired. " "Your cookie of CoolQ Client seems to be expired. "
"Although it will not affect the normal functioning of sending/receiving " "Although it will not affect the normal functioning of sending/receiving "
"messages, however, you may encounter issues like failing to retrieve " "messages, however, you may encounter issues like failing to retrieve "
@ -998,7 +995,7 @@ class GoCQHttp(BaseClient):
try: try:
self.coolq_api_query("set_friend_add_request", approve=res, flag=flag) self.coolq_api_query("set_friend_add_request", approve=res, flag=flag)
except CoolQAPIFailureException as e: except CoolQAPIFailureException as e:
return self._("Failed to process request! Error Message:\n") + getattr(e, "message", repr(e)) return ("Failed to process request! Error Message:\n") + getattr(e, "message", repr(e))
return "Done" return "Done"
def process_group_request(self, result, flag, sub_type): def process_group_request(self, result, flag, sub_type):
@ -1006,13 +1003,13 @@ class GoCQHttp(BaseClient):
try: try:
self.coolq_api_query("set_group_add_request", approve=res, flag=flag, sub_type=sub_type) self.coolq_api_query("set_group_add_request", approve=res, flag=flag, sub_type=sub_type)
except CoolQAPIFailureException as e: except CoolQAPIFailureException as e:
return self._("Failed to process request! Error Message:\n") + getattr(e, "message", repr(e)) return ("Failed to process request! Error Message:\n") + getattr(e, "message", repr(e))
return "Done" return "Done"
def async_download_file(self, context, download_url): def async_download_file(self, context, download_url):
res = download_file(download_url) res = download_file(download_url)
if isinstance(res, str): if isinstance(res, str):
context["message"] = self._("[Download] ") + res context["message"] = ("[Download] ") + res
self.send_efb_group_notice(context) self.send_efb_group_notice(context)
elif res is None: elif res is None:
pass pass
@ -1055,7 +1052,7 @@ class GoCQHttp(BaseClient):
if chat_type[0] == "private": if chat_type[0] == "private":
qq_uid = int(chat_type[1]) qq_uid = int(chat_type[1])
remark = self.get_friend_remark(qq_uid) remark = self.get_friend_remark(qq_uid)
context = {"user_id": qq_uid} context: Dict[str, Any] = {"user_id": qq_uid}
if remark is not None: if remark is not None:
context["alias"] = remark context["alias"] = remark
return self.chat_manager.build_efb_chat_as_private(context) return self.chat_manager.build_efb_chat_as_private(context)

View File

@ -3,41 +3,44 @@ import html
import json import json
import logging import logging
import sys import sys
from typing import TYPE_CHECKING
import magic import magic
from ehforwarderbot import Chat, Message, MsgType from ehforwarderbot import Chat, Message, MsgType
from ehforwarderbot.message import LinkAttribute, LocationAttribute, Substitutions from ehforwarderbot.message import LinkAttribute, LocationAttribute, Substitutions
from . import GoCQHttp
from .Utils import cq_get_image, download_file, download_voice from .Utils import cq_get_image, download_file, download_voice
if TYPE_CHECKING:
from .GoCQHttp import GoCQHttp
class QQMsgProcessor: class QQMsgProcessor:
inst: GoCQHttp inst: "GoCQHttp"
logger: logging.Logger = logging.getLogger(__name__) logger: logging.Logger = logging.getLogger(__name__)
def __init__(self, instance: GoCQHttp): def __init__(self, instance: "GoCQHttp"):
self.inst = instance self.inst = instance
self._ = instance._
pass pass
def qq_image_wrapper(self, data, chat: Chat = None): def qq_image_wrapper(self, data, chat: Chat = None):
efb_msg = Message() efb_msg = Message()
if "url" not in data: if "url" not in data:
efb_msg.type = MsgType.Text efb_msg.type = MsgType.Text
efb_msg.text = self._("[Image Source missing]") efb_msg.text = "[Image Source missing]"
return [efb_msg] return [efb_msg]
# flash picture # flash picture
if "flash" == data.get("type", ""): if "flash" == data.get("type", ""):
data["url"] = f'https://gchat.qpic.cn/gchatpic_new/1/1-1-' \ data["url"] = (
f'{data["file"].replace(".image", "").upper()}/0?term=3%27' f"https://gchat.qpic.cn/gchatpic_new/1/1-1-" f'{data["file"].replace(".image", "").upper()}/0?term=3%27'
efb_msg.text = self._('Send a flash picture.') )
efb_msg.text = "Send a flash picture."
efb_msg.file = cq_get_image(data["url"]) efb_msg.file = cq_get_image(data["url"])
if efb_msg.file is None: if efb_msg.file is None:
efb_msg.type = MsgType.Text efb_msg.type = MsgType.Text
efb_msg.text = self._("[Download image failed, please check on your QQ client]") efb_msg.text = "[Download image failed, please check on your QQ client]"
return [efb_msg] return [efb_msg]
efb_msg.type = MsgType.Image efb_msg.type = MsgType.Image
@ -64,7 +67,7 @@ class QQMsgProcessor:
efb_msg.mime = mime efb_msg.mime = mime
except Exception: except Exception:
efb_msg.type = MsgType.Unsupported efb_msg.type = MsgType.Unsupported
efb_msg.text = self._("[Voice Message] Please check it on your QQ") efb_msg.text = "[Voice Message] Please check it on your QQ"
logging.getLogger(__name__).exception("Failed to download voice") logging.getLogger(__name__).exception("Failed to download voice")
return [efb_msg] return [efb_msg]
@ -90,7 +93,7 @@ class QQMsgProcessor:
return [efb_msg] return [efb_msg]
def qq_shake_wrapper(self, data, chat: Chat = None): def qq_shake_wrapper(self, data, chat: Chat = None):
efb_msg = Message(type=MsgType.Text, text=self._("[Your friend shakes you!]")) efb_msg = Message(type=MsgType.Text, text=("[Your friend shakes you!]"))
return [efb_msg] return [efb_msg]
def qq_contact_wrapper(self, data, chat: Chat = None): def qq_contact_wrapper(self, data, chat: Chat = None):
@ -98,14 +101,14 @@ class QQMsgProcessor:
contact_type = data["type"] contact_type = data["type"]
efb_msg = Message( efb_msg = Message(
type=MsgType.Text, type=MsgType.Text,
text=self._("Chat Recommendation Received\nID: {}\nType: {}").format(uid, contact_type), text=("Chat Recommendation Received\nID: {}\nType: {}").format(uid, contact_type),
) )
return [efb_msg] return [efb_msg]
def qq_bface_wrapper(self, data, chat: Chat = None): def qq_bface_wrapper(self, data, chat: Chat = None):
efb_msg = Message( efb_msg = Message(
type=MsgType.Unsupported, type=MsgType.Unsupported,
text=self._("[Here comes the BigFace Emoji, please check it on your phone]"), text=("[Here comes the BigFace Emoji, please check it on your phone]"),
) )
return [efb_msg] return [efb_msg]
@ -114,11 +117,11 @@ class QQMsgProcessor:
pass pass
def qq_sign_wrapper(self, data, chat: Chat = None): def qq_sign_wrapper(self, data, chat: Chat = None):
location = self._("at {}").format(data["location"]) if "location" in data else self._("at Unknown Place") location = ("at {}").format(data["location"]) if "location" in data else ("at Unknown Place")
title = "" if "title" not in data else (self._("with title {}").format(data["title"])) title = "" if "title" not in data else (("with title {}").format(data["title"]))
efb_msg = Message( efb_msg = Message(
type=MsgType.Text, type=MsgType.Text,
text=self._("signed in {location} {title}").format(title=title, location=location), text=("signed in {location} {title}").format(title=title, location=location),
) )
return [efb_msg] return [efb_msg]
@ -126,7 +129,7 @@ class QQMsgProcessor:
efb_messages = list() efb_messages = list()
efb_msg = Message( efb_msg = Message(
type=MsgType.Unsupported, type=MsgType.Unsupported,
text=self._("[Here comes the Rich Text, dumping...] \n"), text=("[Here comes the Rich Text, dumping...] \n"),
) )
for key, value in data.items(): for key, value in data.items():
efb_msg.text += key + ": " + value + "\n" efb_msg.text += key + ": " + value + "\n"
@ -189,7 +192,7 @@ class QQMsgProcessor:
efb_msg.filename = data["filename"] efb_msg.filename = data["filename"]
return efb_msg return efb_msg
def qq_group_broadcast_wrapper(self, data, chat: Chat = None): def qq_group_broadcast_wrapper(self, data, chat: Chat):
try: try:
at_list = {} at_list = {}
content_data = json.loads(data["content"]) content_data = json.loads(data["content"])
@ -215,9 +218,9 @@ class QQMsgProcessor:
else: else:
return self.qq_text_simple_wrapper(text, at_list) return self.qq_text_simple_wrapper(text, at_list)
except Exception: except Exception:
return self.qq_group_broadcast_alternative_wrapper(data) return self.qq_group_broadcast_alternative_wrapper(data, chat)
def qq_group_broadcast_alternative_wrapper(self, data, chat: Chat = None): def qq_group_broadcast_alternative_wrapper(self, data, chat: Chat):
try: try:
at_list = {} at_list = {}
content_data = json.loads(data["content"]) content_data = json.loads(data["content"])

View File

@ -2,6 +2,7 @@ import logging
import tempfile import tempfile
import urllib.request import urllib.request
from gettext import translation from gettext import translation
from typing import IO, Optional
from urllib.error import ContentTooShortError, HTTPError, URLError from urllib.error import ContentTooShortError, HTTPError, URLError
import pilk import pilk
@ -648,7 +649,7 @@ _ = translator.gettext
ngettext = translator.ngettext ngettext = translator.ngettext
def cq_get_image(image_link: str) -> tempfile: # Download image from QQ def cq_get_image(image_link: str) -> Optional[IO]: # Download image from QQ
file = tempfile.NamedTemporaryFile() file = tempfile.NamedTemporaryFile()
try: try:
urllib.request.urlretrieve(image_link, file.name) urllib.request.urlretrieve(image_link, file.name)

106
pdm.lock
View File

@ -31,12 +31,6 @@ name = "certifi"
version = "2021.10.8" version = "2021.10.8"
summary = "Python package for providing Mozilla's CA Bundle." summary = "Python package for providing Mozilla's CA Bundle."
[[package]]
name = "cfgv"
version = "3.3.1"
requires_python = ">=3.6.1"
summary = "Validate configuration and produce human readable error messages."
[[package]] [[package]]
name = "charset-normalizer" name = "charset-normalizer"
version = "2.0.11" version = "2.0.11"
@ -99,11 +93,6 @@ dependencies = [
"requests", "requests",
] ]
[[package]]
name = "distlib"
version = "0.3.4"
summary = "Distribution utilities"
[[package]] [[package]]
name = "efb-qq-slave" name = "efb-qq-slave"
version = "2.0.1.dev0" version = "2.0.1.dev0"
@ -164,12 +153,6 @@ dependencies = [
"future", "future",
] ]
[[package]]
name = "filelock"
version = "3.4.2"
requires_python = ">=3.7"
summary = "A platform independent file lock."
[[package]] [[package]]
name = "flask" name = "flask"
version = "2.0.2" version = "2.0.2"
@ -197,12 +180,6 @@ dependencies = [
"importlib-metadata; python_version < \"3.8\"", "importlib-metadata; python_version < \"3.8\"",
] ]
[[package]]
name = "identify"
version = "2.4.8"
requires_python = ">=3.7"
summary = "File identification library for Python"
[[package]] [[package]]
name = "idna" name = "idna"
version = "3.3" version = "3.3"
@ -305,11 +282,6 @@ version = "8.12.0"
requires_python = ">=3.5" requires_python = ">=3.5"
summary = "More routines for operating on iterables, beyond itertools" summary = "More routines for operating on iterables, beyond itertools"
[[package]]
name = "nodeenv"
version = "1.6.0"
summary = "Node.js virtual environment builder"
[[package]] [[package]]
name = "peewee" name = "peewee"
version = "3.14.9" version = "3.14.9"
@ -327,12 +299,6 @@ version = "9.0.1"
requires_python = ">=3.7" requires_python = ">=3.7"
summary = "Python Imaging Library (Fork)" summary = "Python Imaging Library (Fork)"
[[package]]
name = "platformdirs"
version = "2.4.1"
requires_python = ">=3.7"
summary = "A small Python module for determining appropriate platform-specific dirs, e.g. a \"user data dir\"."
[[package]] [[package]]
name = "portend" name = "portend"
version = "3.1.0" version = "3.1.0"
@ -342,21 +308,6 @@ dependencies = [
"tempora>=1.8", "tempora>=1.8",
] ]
[[package]]
name = "pre-commit"
version = "2.17.0"
requires_python = ">=3.6.1"
summary = "A framework for managing and maintaining multi-language pre-commit hooks."
dependencies = [
"cfgv>=2.0.0",
"identify>=1.0.0",
"importlib-metadata; python_version < \"3.8\"",
"nodeenv>=0.11.1",
"pyyaml>=5.1",
"toml",
"virtualenv>=20.0.8",
]
[[package]] [[package]]
name = "pydub" name = "pydub"
version = "0.25.1" version = "0.25.1"
@ -464,12 +415,6 @@ dependencies = [
"pytz", "pytz",
] ]
[[package]]
name = "toml"
version = "0.10.2"
requires_python = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*"
summary = "Python Library for Tom's Obvious, Minimal Language"
[[package]] [[package]]
name = "tornado" name = "tornado"
version = "6.1" version = "6.1"
@ -505,19 +450,6 @@ version = "1.26.8"
requires_python = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, <4" requires_python = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, <4"
summary = "HTTP library with thread-safe connection pooling, file post, and more." summary = "HTTP library with thread-safe connection pooling, file post, and more."
[[package]]
name = "virtualenv"
version = "20.13.0"
requires_python = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7"
summary = "Virtual Python Environment builder"
dependencies = [
"distlib<1,>=0.3.1",
"filelock<4,>=3.2",
"importlib-metadata>=0.12; python_version < \"3.8\"",
"platformdirs<3,>=2",
"six<2,>=1.9.0",
]
[[package]] [[package]]
name = "werkzeug" name = "werkzeug"
version = "2.0.2" version = "2.0.2"
@ -540,7 +472,7 @@ summary = "Backport of pathlib-compatible object wrapper for zip files"
[metadata] [metadata]
lock_version = "3.1" lock_version = "3.1"
content_hash = "sha256:22cb2a81b3aaf8b67d35ab2bbd2582a15ef5e1f33f67d0c901b89de94f22d303" content_hash = "sha256:978b5cbd8b5efd554ae429512f6909ca9e5be239ca11531f954c51c274b984cc"
[metadata.files] [metadata.files]
"apscheduler 3.6.3" = [ "apscheduler 3.6.3" = [
@ -577,10 +509,6 @@ content_hash = "sha256:22cb2a81b3aaf8b67d35ab2bbd2582a15ef5e1f33f67d0c901b89de94
{file = "certifi-2021.10.8-py2.py3-none-any.whl", hash = "sha256:d62a0163eb4c2344ac042ab2bdf75399a71a2d8c7d47eac2e2ee91b9d6339569"}, {file = "certifi-2021.10.8-py2.py3-none-any.whl", hash = "sha256:d62a0163eb4c2344ac042ab2bdf75399a71a2d8c7d47eac2e2ee91b9d6339569"},
{file = "certifi-2021.10.8.tar.gz", hash = "sha256:78884e7c1d4b00ce3cea67b44566851c4343c120abd683433ce934a68ea58872"}, {file = "certifi-2021.10.8.tar.gz", hash = "sha256:78884e7c1d4b00ce3cea67b44566851c4343c120abd683433ce934a68ea58872"},
] ]
"cfgv 3.3.1" = [
{file = "cfgv-3.3.1-py2.py3-none-any.whl", hash = "sha256:c6a0883f3917a037485059700b9e75da2464e6c27051014ad85ba6aaa5884426"},
{file = "cfgv-3.3.1.tar.gz", hash = "sha256:f5a830efb9ce7a445376bb66ec94c638a9787422f96264c98edc6bdeed8ab736"},
]
"charset-normalizer 2.0.11" = [ "charset-normalizer 2.0.11" = [
{file = "charset_normalizer-2.0.11-py3-none-any.whl", hash = "sha256:2842d8f5e82a1f6aa437380934d5e1cd4fcf2003b06fed6940769c164a480a45"}, {file = "charset_normalizer-2.0.11-py3-none-any.whl", hash = "sha256:2842d8f5e82a1f6aa437380934d5e1cd4fcf2003b06fed6940769c164a480a45"},
{file = "charset-normalizer-2.0.11.tar.gz", hash = "sha256:98398a9d69ee80548c762ba991a4728bfc3836768ed226b3945908d1a688371c"}, {file = "charset-normalizer-2.0.11.tar.gz", hash = "sha256:98398a9d69ee80548c762ba991a4728bfc3836768ed226b3945908d1a688371c"},
@ -608,10 +536,6 @@ content_hash = "sha256:22cb2a81b3aaf8b67d35ab2bbd2582a15ef5e1f33f67d0c901b89de94
"cqhttp 1.3.1" = [ "cqhttp 1.3.1" = [
{file = "cqhttp-1.3.1.tar.gz", hash = "sha256:4cb0dae03872162df395ef49f3bb2ec69501cc0d686193dfb1b413097b062821"}, {file = "cqhttp-1.3.1.tar.gz", hash = "sha256:4cb0dae03872162df395ef49f3bb2ec69501cc0d686193dfb1b413097b062821"},
] ]
"distlib 0.3.4" = [
{file = "distlib-0.3.4-py2.py3-none-any.whl", hash = "sha256:6564fe0a8f51e734df6333d08b8b94d4ea8ee6b99b5ed50613f731fd4089f34b"},
{file = "distlib-0.3.4.zip", hash = "sha256:e4b58818180336dc9c529bfb9a0b58728ffc09ad92027a3f30b7cd91e3458579"},
]
"efb-telegram-master 2.2.4" = [ "efb-telegram-master 2.2.4" = [
{file = "efb_telegram_master-2.2.4-py3-none-any.whl", hash = "sha256:c4c523d79f3cb39e6a30a339807366514ba0d841acb90c2f322aba4b535fb74c"}, {file = "efb_telegram_master-2.2.4-py3-none-any.whl", hash = "sha256:c4c523d79f3cb39e6a30a339807366514ba0d841acb90c2f322aba4b535fb74c"},
{file = "efb-telegram-master-2.2.4.tar.gz", hash = "sha256:ab40c9c97656921ce339194af91ba56cdb6680fea9a2ec5016649b6205919f44"}, {file = "efb-telegram-master-2.2.4.tar.gz", hash = "sha256:ab40c9c97656921ce339194af91ba56cdb6680fea9a2ec5016649b6205919f44"},
@ -624,10 +548,6 @@ content_hash = "sha256:22cb2a81b3aaf8b67d35ab2bbd2582a15ef5e1f33f67d0c901b89de94
{file = "ffmpeg_python-0.2.0-py3-none-any.whl", hash = "sha256:ac441a0404e053f8b6a1113a77c0f452f1cfc62f6344a769475ffdc0f56c23c5"}, {file = "ffmpeg_python-0.2.0-py3-none-any.whl", hash = "sha256:ac441a0404e053f8b6a1113a77c0f452f1cfc62f6344a769475ffdc0f56c23c5"},
{file = "ffmpeg-python-0.2.0.tar.gz", hash = "sha256:65225db34627c578ef0e11c8b1eb528bb35e024752f6f10b78c011f6f64c4127"}, {file = "ffmpeg-python-0.2.0.tar.gz", hash = "sha256:65225db34627c578ef0e11c8b1eb528bb35e024752f6f10b78c011f6f64c4127"},
] ]
"filelock 3.4.2" = [
{file = "filelock-3.4.2-py3-none-any.whl", hash = "sha256:cf0fc6a2f8d26bd900f19bf33915ca70ba4dd8c56903eeb14e1e7a2fd7590146"},
{file = "filelock-3.4.2.tar.gz", hash = "sha256:38b4f4c989f9d06d44524df1b24bd19e167d851f19b50bf3e3559952dddc5b80"},
]
"flask 2.0.2" = [ "flask 2.0.2" = [
{file = "Flask-2.0.2-py3-none-any.whl", hash = "sha256:cb90f62f1d8e4dc4621f52106613488b5ba826b2e1e10a33eac92f723093ab6a"}, {file = "Flask-2.0.2-py3-none-any.whl", hash = "sha256:cb90f62f1d8e4dc4621f52106613488b5ba826b2e1e10a33eac92f723093ab6a"},
{file = "Flask-2.0.2.tar.gz", hash = "sha256:7b2fb8e934ddd50731893bdcdb00fc8c0315916f9fcd50d22c7cc1a95ab634e2"}, {file = "Flask-2.0.2.tar.gz", hash = "sha256:7b2fb8e934ddd50731893bdcdb00fc8c0315916f9fcd50d22c7cc1a95ab634e2"},
@ -639,10 +559,6 @@ content_hash = "sha256:22cb2a81b3aaf8b67d35ab2bbd2582a15ef5e1f33f67d0c901b89de94
{file = "humanize-4.0.0-py3-none-any.whl", hash = "sha256:8d86333b8557dacffd4dce1dbe09c81c189e2caf7bb17a970b2212f0f58f10f2"}, {file = "humanize-4.0.0-py3-none-any.whl", hash = "sha256:8d86333b8557dacffd4dce1dbe09c81c189e2caf7bb17a970b2212f0f58f10f2"},
{file = "humanize-4.0.0.tar.gz", hash = "sha256:ee1f872fdfc7d2ef4a28d4f80ddde9f96d36955b5d6b0dac4bdeb99502bddb00"}, {file = "humanize-4.0.0.tar.gz", hash = "sha256:ee1f872fdfc7d2ef4a28d4f80ddde9f96d36955b5d6b0dac4bdeb99502bddb00"},
] ]
"identify 2.4.8" = [
{file = "identify-2.4.8-py2.py3-none-any.whl", hash = "sha256:a55bdd671b6063eb837af938c250ec00bba6e610454265133b0d2db7ae718d0f"},
{file = "identify-2.4.8.tar.gz", hash = "sha256:97e839c1779f07011b84c92af183e1883d9745d532d83412cca1ca76d3808c1c"},
]
"idna 3.3" = [ "idna 3.3" = [
{file = "idna-3.3-py3-none-any.whl", hash = "sha256:84d9dd047ffa80596e0f246e2eab0b391788b0503584e8945f2368256d2735ff"}, {file = "idna-3.3-py3-none-any.whl", hash = "sha256:84d9dd047ffa80596e0f246e2eab0b391788b0503584e8945f2368256d2735ff"},
{file = "idna-3.3.tar.gz", hash = "sha256:9d643ff0a55b762d5cdb124b8eaa99c66322e2157b69160bc32796e824360e6d"}, {file = "idna-3.3.tar.gz", hash = "sha256:9d643ff0a55b762d5cdb124b8eaa99c66322e2157b69160bc32796e824360e6d"},
@ -762,10 +678,6 @@ content_hash = "sha256:22cb2a81b3aaf8b67d35ab2bbd2582a15ef5e1f33f67d0c901b89de94
{file = "more_itertools-8.12.0-py3-none-any.whl", hash = "sha256:43e6dd9942dffd72661a2c4ef383ad7da1e6a3e968a927ad7a6083ab410a688b"}, {file = "more_itertools-8.12.0-py3-none-any.whl", hash = "sha256:43e6dd9942dffd72661a2c4ef383ad7da1e6a3e968a927ad7a6083ab410a688b"},
{file = "more-itertools-8.12.0.tar.gz", hash = "sha256:7dc6ad46f05f545f900dd59e8dfb4e84a4827b97b3cfecb175ea0c7d247f6064"}, {file = "more-itertools-8.12.0.tar.gz", hash = "sha256:7dc6ad46f05f545f900dd59e8dfb4e84a4827b97b3cfecb175ea0c7d247f6064"},
] ]
"nodeenv 1.6.0" = [
{file = "nodeenv-1.6.0-py2.py3-none-any.whl", hash = "sha256:621e6b7076565ddcacd2db0294c0381e01fd28945ab36bcf00f41c5daf63bef7"},
{file = "nodeenv-1.6.0.tar.gz", hash = "sha256:3ef13ff90291ba2a4a7a4ff9a979b63ffdd00a464dbe04acf0ea6471517a4c2b"},
]
"peewee 3.14.9" = [ "peewee 3.14.9" = [
{file = "peewee-3.14.9.tar.gz", hash = "sha256:69c1b88dc89b184231cc1ce6df241075aca5cec43e89749cc4a63108f9ceea47"}, {file = "peewee-3.14.9.tar.gz", hash = "sha256:69c1b88dc89b184231cc1ce6df241075aca5cec43e89749cc4a63108f9ceea47"},
] ]
@ -814,18 +726,10 @@ content_hash = "sha256:22cb2a81b3aaf8b67d35ab2bbd2582a15ef5e1f33f67d0c901b89de94
{file = "Pillow-9.0.1-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:a9f44cd7e162ac6191491d7249cceb02b8116b0f7e847ee33f739d7cb1ea1f70"}, {file = "Pillow-9.0.1-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:a9f44cd7e162ac6191491d7249cceb02b8116b0f7e847ee33f739d7cb1ea1f70"},
{file = "Pillow-9.0.1.tar.gz", hash = "sha256:6c8bc8238a7dfdaf7a75f5ec5a663f4173f8c367e5a39f87e720495e1eed75fa"}, {file = "Pillow-9.0.1.tar.gz", hash = "sha256:6c8bc8238a7dfdaf7a75f5ec5a663f4173f8c367e5a39f87e720495e1eed75fa"},
] ]
"platformdirs 2.4.1" = [
{file = "platformdirs-2.4.1-py3-none-any.whl", hash = "sha256:1d7385c7db91728b83efd0ca99a5afb296cab9d0ed8313a45ed8ba17967ecfca"},
{file = "platformdirs-2.4.1.tar.gz", hash = "sha256:440633ddfebcc36264232365d7840a970e75e1018d15b4327d11f91909045fda"},
]
"portend 3.1.0" = [ "portend 3.1.0" = [
{file = "portend-3.1.0-py3-none-any.whl", hash = "sha256:9e735cee3a5c1961f09e3f3ba6dc498198c2d70b473d98d0d1504b8d1e7a3d61"}, {file = "portend-3.1.0-py3-none-any.whl", hash = "sha256:9e735cee3a5c1961f09e3f3ba6dc498198c2d70b473d98d0d1504b8d1e7a3d61"},
{file = "portend-3.1.0.tar.gz", hash = "sha256:239e3116045ea823f6df87d6168107ad75ccc0590e37242af0cc1e98c5d224e4"}, {file = "portend-3.1.0.tar.gz", hash = "sha256:239e3116045ea823f6df87d6168107ad75ccc0590e37242af0cc1e98c5d224e4"},
] ]
"pre-commit 2.17.0" = [
{file = "pre_commit-2.17.0-py2.py3-none-any.whl", hash = "sha256:725fa7459782d7bec5ead072810e47351de01709be838c2ce1726b9591dad616"},
{file = "pre_commit-2.17.0.tar.gz", hash = "sha256:c1a8040ff15ad3d648c70cc3e55b93e4d2d5b687320955505587fd79bbaed06a"},
]
"pydub 0.25.1" = [ "pydub 0.25.1" = [
{file = "pydub-0.25.1-py2.py3-none-any.whl", hash = "sha256:65617e33033874b59d87db603aa1ed450633288aefead953b30bded59cb599a6"}, {file = "pydub-0.25.1-py2.py3-none-any.whl", hash = "sha256:65617e33033874b59d87db603aa1ed450633288aefead953b30bded59cb599a6"},
{file = "pydub-0.25.1.tar.gz", hash = "sha256:980a33ce9949cab2a569606b65674d748ecbca4f0796887fd6f46173a7b0d30f"}, {file = "pydub-0.25.1.tar.gz", hash = "sha256:980a33ce9949cab2a569606b65674d748ecbca4f0796887fd6f46173a7b0d30f"},
@ -945,10 +849,6 @@ content_hash = "sha256:22cb2a81b3aaf8b67d35ab2bbd2582a15ef5e1f33f67d0c901b89de94
{file = "tempora-5.0.1-py3-none-any.whl", hash = "sha256:fbca6a229af666ea4ea8b2f9f80ac9a074f7cf53a97987855b1d15b6e93fd63b"}, {file = "tempora-5.0.1-py3-none-any.whl", hash = "sha256:fbca6a229af666ea4ea8b2f9f80ac9a074f7cf53a97987855b1d15b6e93fd63b"},
{file = "tempora-5.0.1.tar.gz", hash = "sha256:cba0f197a64883bf3e73657efbc0324d5bf17179e7769b1385b4d75d26cd9127"}, {file = "tempora-5.0.1.tar.gz", hash = "sha256:cba0f197a64883bf3e73657efbc0324d5bf17179e7769b1385b4d75d26cd9127"},
] ]
"toml 0.10.2" = [
{file = "toml-0.10.2-py2.py3-none-any.whl", hash = "sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b"},
{file = "toml-0.10.2.tar.gz", hash = "sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f"},
]
"tornado 6.1" = [ "tornado 6.1" = [
{file = "tornado-6.1-cp35-cp35m-macosx_10_9_x86_64.whl", hash = "sha256:d371e811d6b156d82aa5f9a4e08b58debf97c302a35714f6f45e35139c332e32"}, {file = "tornado-6.1-cp35-cp35m-macosx_10_9_x86_64.whl", hash = "sha256:d371e811d6b156d82aa5f9a4e08b58debf97c302a35714f6f45e35139c332e32"},
{file = "tornado-6.1-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:0d321a39c36e5f2c4ff12b4ed58d41390460f798422c4504e09eb5678e09998c"}, {file = "tornado-6.1-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:0d321a39c36e5f2c4ff12b4ed58d41390460f798422c4504e09eb5678e09998c"},
@ -1008,10 +908,6 @@ content_hash = "sha256:22cb2a81b3aaf8b67d35ab2bbd2582a15ef5e1f33f67d0c901b89de94
{file = "urllib3-1.26.8-py2.py3-none-any.whl", hash = "sha256:000ca7f471a233c2251c6c7023ee85305721bfdf18621ebff4fd17a8653427ed"}, {file = "urllib3-1.26.8-py2.py3-none-any.whl", hash = "sha256:000ca7f471a233c2251c6c7023ee85305721bfdf18621ebff4fd17a8653427ed"},
{file = "urllib3-1.26.8.tar.gz", hash = "sha256:0e7c33d9a63e7ddfcb86780aac87befc2fbddf46c58dbb487e0855f7ceec283c"}, {file = "urllib3-1.26.8.tar.gz", hash = "sha256:0e7c33d9a63e7ddfcb86780aac87befc2fbddf46c58dbb487e0855f7ceec283c"},
] ]
"virtualenv 20.13.0" = [
{file = "virtualenv-20.13.0-py2.py3-none-any.whl", hash = "sha256:339f16c4a86b44240ba7223d0f93a7887c3ca04b5f9c8129da7958447d079b09"},
{file = "virtualenv-20.13.0.tar.gz", hash = "sha256:d8458cf8d59d0ea495ad9b34c2599487f8a7772d796f9910858376d1600dd2dd"},
]
"werkzeug 2.0.2" = [ "werkzeug 2.0.2" = [
{file = "Werkzeug-2.0.2-py3-none-any.whl", hash = "sha256:63d3dc1cf60e7b7e35e97fa9861f7397283b75d765afcaefd993d6046899de8f"}, {file = "Werkzeug-2.0.2-py3-none-any.whl", hash = "sha256:63d3dc1cf60e7b7e35e97fa9861f7397283b75d765afcaefd993d6046899de8f"},
{file = "Werkzeug-2.0.2.tar.gz", hash = "sha256:aa2bb6fc8dee8d6c504c0ac1e7f5f7dc5810a9903e793b6f715a9f015bdadb9a"}, {file = "Werkzeug-2.0.2.tar.gz", hash = "sha256:aa2bb6fc8dee8d6c504c0ac1e7f5f7dc5810a9903e793b6f715a9f015bdadb9a"},

View File

@ -56,7 +56,7 @@ build-backend = "pdm.pep517.api"
version = { from = "efb_qq_plugin_go_cqhttp/__init__.py" } version = { from = "efb_qq_plugin_go_cqhttp/__init__.py" }
[tool.pdm.dev-dependencies] [tool.pdm.dev-dependencies]
dev = ["pre-commit", "efb-telegram-master~=2.2.4"] dev = ["efb-telegram-master~=2.2.4"]
[tool.black] [tool.black]
line-length = 120 line-length = 120