kook support
This commit is contained in:
parent
5c70ef69d5
commit
07910322a9
7 changed files with 389 additions and 1 deletions
0
bots/kook/__init__.py
Normal file
0
bots/kook/__init__.py
Normal file
40
bots/kook/bot.py
Normal file
40
bots/kook/bot.py
Normal file
|
@ -0,0 +1,40 @@
|
|||
import os
|
||||
|
||||
from bots.kook.client import bot
|
||||
from khl import Message, MessageTypes
|
||||
from core.builtins import PrivateAssets, Url
|
||||
from core.logger import Logger
|
||||
from core.parser.message import parser
|
||||
from core.types import MsgInfo, Session
|
||||
from core.utils.bot import load_prompt, init_async
|
||||
from bots.kook.message import MessageSession, FetchTarget
|
||||
|
||||
PrivateAssets.set(os.path.abspath(os.path.dirname(__file__) + '/assets'))
|
||||
|
||||
|
||||
@bot.on_message((MessageTypes.TEXT, MessageTypes.IMG))
|
||||
async def msg_handler(message: Message):
|
||||
targetId = f'Kook|{message.channel_type.name}|{message.target_id}'
|
||||
replyId = None
|
||||
if 'quote' in message.extra:
|
||||
replyId = message.extra['quote']['rong_id']
|
||||
|
||||
msg = MessageSession(MsgInfo(targetId=targetId,
|
||||
senderId=f'Kook|User|{message.author_id}',
|
||||
targetFrom=f'Kook|{message.channel_type.name}',
|
||||
senderFrom='Kook|User', senderName=message.author.nickname,
|
||||
clientName='Kook',
|
||||
messageId=message.id,
|
||||
replyId=replyId),
|
||||
Session(message=message, target=message.target_id, sender=message.author_id))
|
||||
await parser(msg)
|
||||
|
||||
|
||||
@bot.on_startup
|
||||
async def _(b: bot):
|
||||
await init_async()
|
||||
await load_prompt(FetchTarget)
|
||||
|
||||
|
||||
if bot:
|
||||
bot.run()
|
11
bots/kook/client.py
Normal file
11
bots/kook/client.py
Normal file
|
@ -0,0 +1,11 @@
|
|||
from khl import Bot
|
||||
|
||||
from config import Config
|
||||
|
||||
token = Config('kook_token')
|
||||
|
||||
|
||||
if token:
|
||||
bot = Bot(token=token)
|
||||
else:
|
||||
bot = False
|
241
bots/kook/message.py
Normal file
241
bots/kook/message.py
Normal file
|
@ -0,0 +1,241 @@
|
|||
import re
|
||||
import traceback
|
||||
import ujson as json
|
||||
from typing import List, Union
|
||||
|
||||
import aiohttp
|
||||
from khl import MessageTypes, Message
|
||||
|
||||
from bots.kook.client import bot
|
||||
from config import Config
|
||||
from core.builtins import Bot, Plain, Image, Voice, MessageSession as MS, ErrorMessage
|
||||
from core.builtins.message.chain import MessageChain
|
||||
from core.logger import Logger
|
||||
from core.types import MsgInfo, Session, FetchTarget as FT, FetchedSession as FS, \
|
||||
FinishedSession as FinS
|
||||
from core.utils.image import image_split
|
||||
from database import BotDBUtil
|
||||
|
||||
enable_analytics = Config('enable_analytics')
|
||||
kook_base = "https://www.kookapp.cn"
|
||||
kook_headers = {f'Authorization': f"Bot {Config('kook_token')}"}
|
||||
|
||||
|
||||
async def direct_msg_delete(msg_id: str):
|
||||
"""删除私聊消息"""
|
||||
url = kook_base + "/api/v3/direct-message/delete"
|
||||
params = {"msg_id": msg_id}
|
||||
async with aiohttp.ClientSession() as session:
|
||||
async with session.post(url, data=params, headers=kook_headers) as response:
|
||||
res = json.loads(await response.text())
|
||||
return res
|
||||
|
||||
|
||||
async def channel_msg_delete(msg_id: str):
|
||||
"""删除普通消息"""
|
||||
url = kook_base + "/api/v3/message/delete"
|
||||
params = {"msg_id": msg_id}
|
||||
async with aiohttp.ClientSession() as session:
|
||||
async with session.post(url, data=params, headers=kook_headers) as response:
|
||||
res = json.loads(await response.text())
|
||||
return res
|
||||
|
||||
|
||||
class FinishedSession(FinS):
|
||||
async def delete(self):
|
||||
"""
|
||||
用于删除这条消息。
|
||||
"""
|
||||
try:
|
||||
for x in self.result:
|
||||
if x['type'] == 'PERSON':
|
||||
await direct_msg_delete(x)
|
||||
else:
|
||||
await channel_msg_delete(x)
|
||||
except Exception:
|
||||
Logger.error(traceback.format_exc())
|
||||
|
||||
|
||||
class MessageSession(MS):
|
||||
class Feature:
|
||||
image = True
|
||||
voice = True
|
||||
embed = False
|
||||
forward = False
|
||||
delete = True
|
||||
quote = True
|
||||
wait = True
|
||||
|
||||
async def sendMessage(self, msgchain, quote=True, disable_secret_check=False,
|
||||
allow_split_image=True) -> FinishedSession:
|
||||
self.session.message: Message
|
||||
msgchain = MessageChain(msgchain)
|
||||
if not msgchain.is_safe and not disable_secret_check:
|
||||
return await self.sendMessage(Plain(ErrorMessage(self.locale.t("error.message.chain.unsafe"))))
|
||||
self.sent.append(msgchain)
|
||||
count = 0
|
||||
send = []
|
||||
for x in msgchain.asSendable(embed=False):
|
||||
if isinstance(x, Plain):
|
||||
send_ = await self.session.message.reply(x.text, quote=quote if quote
|
||||
and count == 0 and self.session.message else None)
|
||||
|
||||
Logger.info(f'[Bot] -> [{self.target.targetId}]: {x.text}')
|
||||
send.append(send_)
|
||||
count += 1
|
||||
elif isinstance(x, Image):
|
||||
url = await bot.create_asset(open(await x.get(), 'rb'))
|
||||
send_ = await self.session.message.reply(url, type=MessageTypes.IMG, quote=quote if quote
|
||||
and count == 0 and self.session.message else None)
|
||||
Logger.info(f'[Bot] -> [{self.target.targetId}]: Image: {str(x.__dict__)}')
|
||||
send.append(send_)
|
||||
count += 1
|
||||
elif isinstance(x, Voice):
|
||||
url = await bot.create_asset(open(x.path), 'rb')
|
||||
send_ = await self.session.message.reply(url, type=MessageTypes.AUDIO, quote=quote if quote
|
||||
and count == 0 and self.session.message else None)
|
||||
Logger.info(f'[Bot] -> [{self.target.targetId}]: Voice: {str(x.__dict__)}')
|
||||
send.append(send_)
|
||||
count += 1
|
||||
|
||||
msgIds = []
|
||||
for x in send:
|
||||
msgIds.append({x['msg_id']: self.session.message.channel_type.name})
|
||||
return FinishedSession(self, msgIds, send)
|
||||
|
||||
async def checkPermission(self):
|
||||
self.session.message: Message
|
||||
if self.session.message.channel_type.name == 'PERSON' or self.target.senderId in self.custom_admins \
|
||||
or self.target.senderInfo.query.isSuperUser:
|
||||
return True
|
||||
return await self.checkNativePermission()
|
||||
|
||||
async def checkNativePermission(self):
|
||||
self.session.message: Message
|
||||
if self.session.message.channel_type.name == 'PERSON':
|
||||
return True
|
||||
guild = await bot.client.fetch_guild(self.session.message.ctx.guild.id)
|
||||
user_roles = (await guild.fetch_user(self.session.message.author.id)).roles
|
||||
guild_roles = await guild.fetch_roles()
|
||||
for i in guild_roles: # 遍历服务器身分组
|
||||
if i.id in user_roles and i.has_permission(0):
|
||||
return True
|
||||
if self.session.message.author.id == guild.master_id:
|
||||
return True
|
||||
return False
|
||||
|
||||
def asDisplay(self, text_only=False):
|
||||
if self.session.message.content:
|
||||
msg = re.sub(r'\[.*]\((.*)\)', '\\1', self.session.message.content)
|
||||
return msg
|
||||
return ''
|
||||
|
||||
async def toMessageChain(self):
|
||||
lst = []
|
||||
if self.session.message.type == MessageTypes.TEXT:
|
||||
lst.append(Plain(self.session.message.content))
|
||||
elif self.session.message.type == MessageTypes.IMG:
|
||||
lst.append(Image(self.session.message.content))
|
||||
elif self.session.message.type == MessageTypes.AUDIO:
|
||||
lst.append(Voice(self.session.message.content))
|
||||
return MessageChain(lst)
|
||||
|
||||
async def delete(self):
|
||||
self.session.message: Message
|
||||
try:
|
||||
if self.session.message.channel_type.name == 'PERSON':
|
||||
await direct_msg_delete(self.session.message.id)
|
||||
else:
|
||||
await channel_msg_delete(self.session.message.id)
|
||||
except Exception:
|
||||
Logger.error(traceback.format_exc())
|
||||
|
||||
class Typing:
|
||||
def __init__(self, msg: MS):
|
||||
self.msg = msg
|
||||
|
||||
async def __aenter__(self):
|
||||
# await bot.answer_chat_action(self.msg.session.target, 'typing')
|
||||
pass
|
||||
|
||||
async def __aexit__(self, exc_type, exc_val, exc_tb):
|
||||
pass
|
||||
|
||||
|
||||
class FetchedSession(FS):
|
||||
def __init__(self, targetFrom, targetId):
|
||||
self.target = MsgInfo(targetId=f'{targetFrom}|{targetId}',
|
||||
senderId=f'{targetFrom}|{targetId}',
|
||||
targetFrom=targetFrom,
|
||||
senderFrom=targetFrom,
|
||||
senderName='',
|
||||
clientName='Kook', messageId=0, replyId=None)
|
||||
self.session = Session(message=False, target=targetId, sender=targetId)
|
||||
self.parent = MessageSession(self.target, self.session)
|
||||
|
||||
|
||||
class FetchTarget(FT):
|
||||
name = 'Telegram'
|
||||
|
||||
@staticmethod
|
||||
async def fetch_target(targetId) -> Union[FetchedSession, bool]:
|
||||
matchChannel = re.match(r'^(Kook\|.*?)\|(.*)', targetId)
|
||||
if matchChannel:
|
||||
return FetchedSession(matchChannel.group(1), matchChannel.group(2))
|
||||
else:
|
||||
return False
|
||||
|
||||
@staticmethod
|
||||
async def fetch_target_list(targetList: list) -> List[FetchedSession]:
|
||||
lst = []
|
||||
for x in targetList:
|
||||
fet = await FetchTarget.fetch_target(x)
|
||||
if fet:
|
||||
lst.append(fet)
|
||||
return lst
|
||||
|
||||
@staticmethod
|
||||
async def post_message(module_name, message, user_list: List[FetchedSession] = None, i18n=False, **kwargs):
|
||||
if user_list is not None:
|
||||
for x in user_list:
|
||||
try:
|
||||
if i18n:
|
||||
if isinstance(message, dict):
|
||||
if (gm := message.get(x.parent.locale.locale)) is not None:
|
||||
await x.sendDirectMessage(gm)
|
||||
else:
|
||||
await x.sendDirectMessage(message.get('fallback'))
|
||||
else:
|
||||
await x.sendDirectMessage(x.parent.locale.t(message, **kwargs))
|
||||
|
||||
else:
|
||||
await x.sendDirectMessage(message)
|
||||
if enable_analytics:
|
||||
BotDBUtil.Analytics(x).add('', module_name, 'schedule')
|
||||
except Exception:
|
||||
Logger.error(traceback.format_exc())
|
||||
else:
|
||||
get_target_id = BotDBUtil.TargetInfo.get_enabled_this(module_name, "Telegram")
|
||||
for x in get_target_id:
|
||||
fetch = await FetchTarget.fetch_target(x.targetId)
|
||||
if fetch:
|
||||
try:
|
||||
if i18n:
|
||||
if isinstance(message, dict):
|
||||
if (gm := message.get(fetch.parent.locale.locale)) is not None:
|
||||
await fetch.sendDirectMessage(gm)
|
||||
else:
|
||||
await fetch.sendDirectMessage(message.get('fallback'))
|
||||
else:
|
||||
await fetch.sendDirectMessage(fetch.parent.locale.t(message, **kwargs))
|
||||
|
||||
else:
|
||||
await fetch.sendDirectMessage(message)
|
||||
if enable_analytics:
|
||||
BotDBUtil.Analytics(fetch).add('', module_name, 'schedule')
|
||||
except Exception:
|
||||
Logger.error(traceback.format_exc())
|
||||
|
||||
|
||||
Bot.MessageSession = MessageSession
|
||||
Bot.FetchTarget = FetchTarget
|
61
poetry.lock
generated
61
poetry.lock
generated
|
@ -1821,6 +1821,23 @@ MarkupSafe = ">=2.0"
|
|||
[package.extras]
|
||||
i18n = ["Babel (>=2.7)"]
|
||||
|
||||
[[package]]
|
||||
name = "khl-py"
|
||||
version = "0.3.16"
|
||||
description = "Python SDK for kaiheila.cn API"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=3.6"
|
||||
files = [
|
||||
{file = "khl.py-0.3.16-py3-none-any.whl", hash = "sha256:c55a7caca054ac4678b4ff8f35f8555cc295d5ec9bd4db15857dcbec9cd0a42e"},
|
||||
{file = "khl.py-0.3.16.tar.gz", hash = "sha256:d4e608d560cc809bd3b657d2ddb2ca3e9370f6b84d299215b87d0768d4133d76"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
aiohttp = "*"
|
||||
apscheduler = "*"
|
||||
pycryptodomex = "*"
|
||||
|
||||
[[package]]
|
||||
name = "kiwisolver"
|
||||
version = "1.4.4"
|
||||
|
@ -3079,6 +3096,48 @@ files = [
|
|||
{file = "pycryptodome-3.18.0.tar.gz", hash = "sha256:c9adee653fc882d98956e33ca2c1fb582e23a8af7ac82fee75bd6113c55a0413"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pycryptodomex"
|
||||
version = "3.18.0"
|
||||
description = "Cryptographic library for Python"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
|
||||
files = [
|
||||
{file = "pycryptodomex-3.18.0-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:160a39a708c36fa0b168ab79386dede588e62aec06eb505add870739329aecc6"},
|
||||
{file = "pycryptodomex-3.18.0-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:c2953afebf282a444c51bf4effe751706b4d0d63d7ca2cc51db21f902aa5b84e"},
|
||||
{file = "pycryptodomex-3.18.0-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:ba95abd563b0d1b88401658665a260852a8e6c647026ee6a0a65589287681df8"},
|
||||
{file = "pycryptodomex-3.18.0-cp27-cp27m-manylinux2014_aarch64.whl", hash = "sha256:192306cf881fe3467dda0e174a4f47bb3a8bb24b90c9cdfbdc248eec5fc0578c"},
|
||||
{file = "pycryptodomex-3.18.0-cp27-cp27m-musllinux_1_1_aarch64.whl", hash = "sha256:f9ab5ef0718f6a8716695dea16d83b671b22c45e9c0c78fd807c32c0192e54b5"},
|
||||
{file = "pycryptodomex-3.18.0-cp27-cp27m-win32.whl", hash = "sha256:50308fcdbf8345e5ec224a5502b4215178bdb5e95456ead8ab1a69ffd94779cb"},
|
||||
{file = "pycryptodomex-3.18.0-cp27-cp27m-win_amd64.whl", hash = "sha256:4d9379c684efea80fdab02a3eb0169372bca7db13f9332cb67483b8dc8b67c37"},
|
||||
{file = "pycryptodomex-3.18.0-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:5594a125dae30d60e94f37797fc67ce3c744522de7992c7c360d02fdb34918f8"},
|
||||
{file = "pycryptodomex-3.18.0-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:8ff129a5a0eb5ff16e45ca4fa70a6051da7f3de303c33b259063c19be0c43d35"},
|
||||
{file = "pycryptodomex-3.18.0-cp27-cp27mu-manylinux2014_aarch64.whl", hash = "sha256:3d9314ac785a5b75d5aaf924c5f21d6ca7e8df442e5cf4f0fefad4f6e284d422"},
|
||||
{file = "pycryptodomex-3.18.0-cp27-cp27mu-musllinux_1_1_aarch64.whl", hash = "sha256:f237278836dda412a325e9340ba2e6a84cb0f56b9244781e5b61f10b3905de88"},
|
||||
{file = "pycryptodomex-3.18.0-cp35-abi3-macosx_10_9_universal2.whl", hash = "sha256:ac614363a86cc53d8ba44b6c469831d1555947e69ab3276ae8d6edc219f570f7"},
|
||||
{file = "pycryptodomex-3.18.0-cp35-abi3-macosx_10_9_x86_64.whl", hash = "sha256:302a8f37c224e7b5d72017d462a2be058e28f7be627bdd854066e16722d0fc0c"},
|
||||
{file = "pycryptodomex-3.18.0-cp35-abi3-manylinux2014_aarch64.whl", hash = "sha256:6421d23d6a648e83ba2670a352bcd978542dad86829209f59d17a3f087f4afef"},
|
||||
{file = "pycryptodomex-3.18.0-cp35-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d84e105787f5e5d36ec6a581ff37a1048d12e638688074b2a00bcf402f9aa1c2"},
|
||||
{file = "pycryptodomex-3.18.0-cp35-abi3-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6875eb8666f68ddbd39097867325bd22771f595b4e2b0149739b5623c8bf899b"},
|
||||
{file = "pycryptodomex-3.18.0-cp35-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:27072a494ce621cc7a9096bbf60ed66826bb94db24b49b7359509e7951033e74"},
|
||||
{file = "pycryptodomex-3.18.0-cp35-abi3-musllinux_1_1_i686.whl", hash = "sha256:1949e09ea49b09c36d11a951b16ff2a05a0ffe969dda1846e4686ee342fe8646"},
|
||||
{file = "pycryptodomex-3.18.0-cp35-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:6ed3606832987018615f68e8ed716a7065c09a0fe94afd7c9ca1b6777f0ac6eb"},
|
||||
{file = "pycryptodomex-3.18.0-cp35-abi3-win32.whl", hash = "sha256:d56c9ec41258fd3734db9f5e4d2faeabe48644ba9ca23b18e1839b3bdf093222"},
|
||||
{file = "pycryptodomex-3.18.0-cp35-abi3-win_amd64.whl", hash = "sha256:e00a4bacb83a2627e8210cb353a2e31f04befc1155db2976e5e239dd66482278"},
|
||||
{file = "pycryptodomex-3.18.0-pp27-pypy_73-manylinux2010_x86_64.whl", hash = "sha256:2dc4eab20f4f04a2d00220fdc9258717b82d31913552e766d5f00282c031b70a"},
|
||||
{file = "pycryptodomex-3.18.0-pp27-pypy_73-win32.whl", hash = "sha256:75672205148bdea34669173366df005dbd52be05115e919551ee97171083423d"},
|
||||
{file = "pycryptodomex-3.18.0-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:bec6c80994d4e7a38312072f89458903b65ec99bed2d65aa4de96d997a53ea7a"},
|
||||
{file = "pycryptodomex-3.18.0-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d35a8ffdc8b05e4b353ba281217c8437f02c57d7233363824e9d794cf753c419"},
|
||||
{file = "pycryptodomex-3.18.0-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:76f0a46bee539dae4b3dfe37216f678769349576b0080fdbe431d19a02da42ff"},
|
||||
{file = "pycryptodomex-3.18.0-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:71687eed47df7e965f6e0bf3cadef98f368d5221f0fb89d2132effe1a3e6a194"},
|
||||
{file = "pycryptodomex-3.18.0-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:73d64b32d84cf48d9ec62106aa277dbe99ab5fbfd38c5100bc7bddd3beb569f7"},
|
||||
{file = "pycryptodomex-3.18.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bbdcce0a226d9205560a5936b05208c709b01d493ed8307792075dedfaaffa5f"},
|
||||
{file = "pycryptodomex-3.18.0-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:58fc0aceb9c961b9897facec9da24c6a94c5db04597ec832060f53d4d6a07196"},
|
||||
{file = "pycryptodomex-3.18.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:215be2980a6b70704c10796dd7003eb4390e7be138ac6fb8344bf47e71a8d470"},
|
||||
{file = "pycryptodomex-3.18.0.tar.gz", hash = "sha256:3e3ecb5fe979e7c1bb0027e518340acf7ee60415d79295e5251d13c68dde576e"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pydantic"
|
||||
version = "1.10.7"
|
||||
|
@ -4433,4 +4492,4 @@ cffi = ["cffi (>=1.11)"]
|
|||
[metadata]
|
||||
lock-version = "2.0"
|
||||
python-versions = "^3.8.1"
|
||||
content-hash = "21c1f768442311a5d4fa657d4f07b5290eb7f1b8fd09b8be89cae12c15904c70"
|
||||
content-hash = "255986b7eedf346049cf3eb592530a3fde64114dfca510e14e4efb7fc6d3b922"
|
||||
|
|
|
@ -53,6 +53,7 @@ tiktoken = "^0.3.3"
|
|||
pycryptodome = "^3.18.0"
|
||||
langconv = "^0.2.0"
|
||||
toml = "^0.10.2"
|
||||
khl-py = "^0.3.16"
|
||||
|
||||
|
||||
[tool.poetry.group.dev.dependencies]
|
||||
|
|
|
@ -908,6 +908,9 @@ jaraco-context==4.3.0 ; python_full_version >= "3.8.1" and python_full_version <
|
|||
jinja2==3.1.2 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0" \
|
||||
--hash=sha256:31351a702a408a9e7595a8fc6150fc3f43bb6bf7e319770cbc0db9df9437e852 \
|
||||
--hash=sha256:6088930bfe239f0e6710546ab9c19c9ef35e29792895fed6e6e31a023a182a61
|
||||
khl-py==0.3.16 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0" \
|
||||
--hash=sha256:c55a7caca054ac4678b4ff8f35f8555cc295d5ec9bd4db15857dcbec9cd0a42e \
|
||||
--hash=sha256:d4e608d560cc809bd3b657d2ddb2ca3e9370f6b84d299215b87d0768d4133d76
|
||||
kiwisolver==1.4.4 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0" \
|
||||
--hash=sha256:02f79693ec433cb4b5f51694e8477ae83b3205768a6fb48ffba60549080e295b \
|
||||
--hash=sha256:03baab2d6b4a54ddbb43bba1a3a2d1627e82d205c5cf8f4c924dc49284b87166 \
|
||||
|
@ -1602,6 +1605,39 @@ pycryptodome==3.18.0 ; python_full_version >= "3.8.1" and python_full_version <
|
|||
--hash=sha256:f022a4fd2a5263a5c483a2bb165f9cb27f2be06f2f477113783efe3fe2ad887b \
|
||||
--hash=sha256:f21efb8438971aa16924790e1c3dba3a33164eb4000106a55baaed522c261acf \
|
||||
--hash=sha256:fc0a73f4db1e31d4a6d71b672a48f3af458f548059aa05e83022d5f61aac9c08
|
||||
pycryptodomex==3.18.0 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0" \
|
||||
--hash=sha256:160a39a708c36fa0b168ab79386dede588e62aec06eb505add870739329aecc6 \
|
||||
--hash=sha256:192306cf881fe3467dda0e174a4f47bb3a8bb24b90c9cdfbdc248eec5fc0578c \
|
||||
--hash=sha256:1949e09ea49b09c36d11a951b16ff2a05a0ffe969dda1846e4686ee342fe8646 \
|
||||
--hash=sha256:215be2980a6b70704c10796dd7003eb4390e7be138ac6fb8344bf47e71a8d470 \
|
||||
--hash=sha256:27072a494ce621cc7a9096bbf60ed66826bb94db24b49b7359509e7951033e74 \
|
||||
--hash=sha256:2dc4eab20f4f04a2d00220fdc9258717b82d31913552e766d5f00282c031b70a \
|
||||
--hash=sha256:302a8f37c224e7b5d72017d462a2be058e28f7be627bdd854066e16722d0fc0c \
|
||||
--hash=sha256:3d9314ac785a5b75d5aaf924c5f21d6ca7e8df442e5cf4f0fefad4f6e284d422 \
|
||||
--hash=sha256:3e3ecb5fe979e7c1bb0027e518340acf7ee60415d79295e5251d13c68dde576e \
|
||||
--hash=sha256:4d9379c684efea80fdab02a3eb0169372bca7db13f9332cb67483b8dc8b67c37 \
|
||||
--hash=sha256:50308fcdbf8345e5ec224a5502b4215178bdb5e95456ead8ab1a69ffd94779cb \
|
||||
--hash=sha256:5594a125dae30d60e94f37797fc67ce3c744522de7992c7c360d02fdb34918f8 \
|
||||
--hash=sha256:58fc0aceb9c961b9897facec9da24c6a94c5db04597ec832060f53d4d6a07196 \
|
||||
--hash=sha256:6421d23d6a648e83ba2670a352bcd978542dad86829209f59d17a3f087f4afef \
|
||||
--hash=sha256:6875eb8666f68ddbd39097867325bd22771f595b4e2b0149739b5623c8bf899b \
|
||||
--hash=sha256:6ed3606832987018615f68e8ed716a7065c09a0fe94afd7c9ca1b6777f0ac6eb \
|
||||
--hash=sha256:71687eed47df7e965f6e0bf3cadef98f368d5221f0fb89d2132effe1a3e6a194 \
|
||||
--hash=sha256:73d64b32d84cf48d9ec62106aa277dbe99ab5fbfd38c5100bc7bddd3beb569f7 \
|
||||
--hash=sha256:75672205148bdea34669173366df005dbd52be05115e919551ee97171083423d \
|
||||
--hash=sha256:76f0a46bee539dae4b3dfe37216f678769349576b0080fdbe431d19a02da42ff \
|
||||
--hash=sha256:8ff129a5a0eb5ff16e45ca4fa70a6051da7f3de303c33b259063c19be0c43d35 \
|
||||
--hash=sha256:ac614363a86cc53d8ba44b6c469831d1555947e69ab3276ae8d6edc219f570f7 \
|
||||
--hash=sha256:ba95abd563b0d1b88401658665a260852a8e6c647026ee6a0a65589287681df8 \
|
||||
--hash=sha256:bbdcce0a226d9205560a5936b05208c709b01d493ed8307792075dedfaaffa5f \
|
||||
--hash=sha256:bec6c80994d4e7a38312072f89458903b65ec99bed2d65aa4de96d997a53ea7a \
|
||||
--hash=sha256:c2953afebf282a444c51bf4effe751706b4d0d63d7ca2cc51db21f902aa5b84e \
|
||||
--hash=sha256:d35a8ffdc8b05e4b353ba281217c8437f02c57d7233363824e9d794cf753c419 \
|
||||
--hash=sha256:d56c9ec41258fd3734db9f5e4d2faeabe48644ba9ca23b18e1839b3bdf093222 \
|
||||
--hash=sha256:d84e105787f5e5d36ec6a581ff37a1048d12e638688074b2a00bcf402f9aa1c2 \
|
||||
--hash=sha256:e00a4bacb83a2627e8210cb353a2e31f04befc1155db2976e5e239dd66482278 \
|
||||
--hash=sha256:f237278836dda412a325e9340ba2e6a84cb0f56b9244781e5b61f10b3905de88 \
|
||||
--hash=sha256:f9ab5ef0718f6a8716695dea16d83b671b22c45e9c0c78fd807c32c0192e54b5
|
||||
pydantic==1.10.7 ; python_full_version >= "3.8.1" and python_version < "4.0" \
|
||||
--hash=sha256:01aea3a42c13f2602b7ecbbea484a98169fb568ebd9e247593ea05f01b884b2e \
|
||||
--hash=sha256:0cd181f1d0b1d00e2b705f1bf1ac7799a2d938cce3376b8007df62b29be3c2c6 \
|
||||
|
|
Reference in a new issue