支持小组件获取每日

This commit is contained in:
qwerdvd 2023-06-19 18:26:20 +08:00
parent 44a55c0866
commit cb0f2f16e9
13 changed files with 176 additions and 102 deletions

View File

@ -52,4 +52,6 @@ GET_FP_URL = 'https://public-data-api.mihoyo.com/device-fp/api/getFp'
GET_FP_URL_OS = 'https://sg-public-data-api.hoyoverse.com/device-fp/api/getFp' GET_FP_URL_OS = 'https://sg-public-data-api.hoyoverse.com/device-fp/api/getFp'
# CREATE_QRCODE = f'{OLD_URL}/event/bbs_sign_reward/gen_auth_code' # CREATE_QRCODE = f'{OLD_URL}/event/bbs_sign_reward/gen_auth_code'
STAR_RAIL_WIDGRT_URL = f'{NEW_URL}/game_record/app/hkrpg/aapi/widget'
_API = locals() _API = locals()

View File

@ -237,6 +237,23 @@ class DailyNoteData(TypedDict):
expeditions: List[Expedition] expeditions: List[Expedition]
class WidgetStamina(TypedDict):
current_stamina: int
max_stamina: int
stamina_recover_time: int
accepted_expedition_num: int
total_expedition_num: int
expeditions: List[Expedition]
current_train_score: int
max_train_score: int
current_rogue_score: int
max_rogue_score: int
has_signed: bool
sign_url: str
home_url: str
note_url: str
################ ################
# 签到相关 # # 签到相关 #
################ ################

View File

@ -29,4 +29,9 @@ CONIFG_DEFAULT: Dict[str, GSC] = {
'用于本插件的前缀设定', '用于本插件的前缀设定',
'sr', 'sr',
), ),
'WidgetResin': GsBoolConfig(
'体力使用组件API',
'开启后mr功能将转为调用组件API, 可能缺失数据、数据不准',
True,
),
} }

View File

@ -11,15 +11,15 @@ from gsuid_core.segment import MessageSegment
from ..utils.convert import get_uid from ..utils.convert import get_uid
from .notice import get_notice_list from .notice import get_notice_list
from ..utils.sr_prefix import PREFIX from ..utils.sr_prefix import PREFIX
from .resin_text import get_resin_text
from ..utils.error_reply import UID_HINT from ..utils.error_reply import UID_HINT
from .draw_resin_card import get_resin_img from .stamina_text import get_stamina_text
from .draw_stamina_card import get_stamina_img
sv_get_resin = SV('sr查询体力') sv_get_stamina = SV('sr查询体力')
sv_get_resin_admin = SV('sr强制推送', pm=1) sv_get_stamina_admin = SV('sr强制推送', pm=1)
@sv_get_resin.on_fullmatch((f'{PREFIX}当前状态')) @sv_get_stamina.on_fullmatch((f'{PREFIX}当前状态'))
async def send_daily_info(bot: Bot, ev: Event): async def send_daily_info(bot: Bot, ev: Event):
await bot.logger.info('开始执行[sr每日信息文字版]') await bot.logger.info('开始执行[sr每日信息文字版]')
uid = await get_uid(bot, ev) uid = await get_uid(bot, ev)
@ -27,11 +27,11 @@ async def send_daily_info(bot: Bot, ev: Event):
return await bot.send(UID_HINT) return await bot.send(UID_HINT)
await bot.logger.info('[sr每日信息文字版]UID: {}'.format(uid)) await bot.logger.info('[sr每日信息文字版]UID: {}'.format(uid))
im = await get_resin_text(uid) im = await get_stamina_text(uid)
await bot.send(im) await bot.send(im)
@sv_get_resin_admin.on_fullmatch((f'{PREFIX}强制推送体力提醒')) @sv_get_stamina_admin.on_fullmatch((f'{PREFIX}强制推送体力提醒'))
async def force_notice_job(bot: Bot, ev: Event): async def force_notice_job(bot: Bot, ev: Event):
await bot.logger.info('开始执行[sr强制推送体力信息]') await bot.logger.info('开始执行[sr强制推送体力信息]')
await sr_notice_job() await sr_notice_job()
@ -63,7 +63,7 @@ async def sr_notice_job():
logger.info('[sr推送检查] 群聊推送完成') logger.info('[sr推送检查] 群聊推送完成')
@sv_get_resin.on_fullmatch( @sv_get_stamina.on_fullmatch(
( (
f'{PREFIX}每日', f'{PREFIX}每日',
f'{PREFIX}mr', f'{PREFIX}mr',
@ -77,5 +77,5 @@ async def send_daily_info_pic(bot: Bot, ev: Event):
user_id = ev.at if ev.at else ev.user_id user_id = ev.at if ev.at else ev.user_id
await bot.logger.info('[sr每日信息]QQ号: {}'.format(user_id)) await bot.logger.info('[sr每日信息]QQ号: {}'.format(user_id))
im = await get_resin_img(bot.bot_id, user_id) im = await get_stamina_img(bot.bot_id, user_id)
await bot.send(im) await bot.send(im)

View File

@ -11,6 +11,7 @@ from ..utils.api import get_sqla
from ..utils.mys_api import mys_api from ..utils.mys_api import mys_api
from ..utils.image.convert import convert_img from ..utils.image.convert import convert_img
from ..sruid_utils.api.mys.models import Expedition from ..sruid_utils.api.mys.models import Expedition
from ..starrailuid_config.sr_config import srconfig
from ..utils.image.image_tools import get_simple_bg from ..utils.image.image_tools import get_simple_bg
from ..utils.fonts.starrail_fonts import ( from ..utils.fonts.starrail_fonts import (
sr_font_22, sr_font_22,
@ -20,6 +21,8 @@ from ..utils.fonts.starrail_fonts import (
sr_font_50, sr_font_50,
) )
use_widget = srconfig.get_config('WidgetResin').data
TEXT_PATH = Path(__file__).parent / 'texture2D' TEXT_PATH = Path(__file__).parent / 'texture2D'
note_bg = Image.open(TEXT_PATH / 'note_bg.png') note_bg = Image.open(TEXT_PATH / 'note_bg.png')
@ -100,7 +103,7 @@ async def _draw_task_img(
) )
async def get_resin_img(bot_id: str, user_id: str): async def get_stamina_img(bot_id: str, user_id: str):
try: try:
sqla = get_sqla(bot_id) sqla = get_sqla(bot_id)
uid_list: List = await sqla.get_bind_sruid_list(user_id) uid_list: List = await sqla.get_bind_sruid_list(user_id)
@ -120,7 +123,7 @@ async def get_resin_img(bot_id: str, user_id: str):
'RGBA', (based_w * len(useable_uid_list), based_h), (0, 0, 0, 0) 'RGBA', (based_w * len(useable_uid_list), based_h), (0, 0, 0, 0)
) )
for uid_index, uid in enumerate(useable_uid_list): for uid_index, uid in enumerate(useable_uid_list):
task.append(_draw_all_resin_img(img, uid, uid_index)) task.append(_draw_all_stamina_img(img, uid, uid_index))
await asyncio.gather(*task) await asyncio.gather(*task)
res = await convert_img(img) res = await convert_img(img)
logger.info('[查询每日信息]绘图已完成,等待发送!') logger.info('[查询每日信息]绘图已完成,等待发送!')
@ -131,9 +134,30 @@ async def get_resin_img(bot_id: str, user_id: str):
return res return res
async def _draw_all_resin_img(img: Image.Image, uid: str, index: int): async def _draw_all_stamina_img(img: Image.Image, uid: str, index: int):
resin_img = await draw_resin_img(uid) stamina_img = await draw_stamina_img(uid)
img.paste(resin_img, (700 * index, 0), resin_img) img.paste(stamina_img, (700 * index, 0), stamina_img)
def get_error(img: Image.Image, uid: str, daily_data: int):
img_draw = ImageDraw.Draw(img)
img.paste(warn_pic, (0, 0), warn_pic)
# 写UID
img_draw.text(
(350, 680),
f'UID{uid}',
font=sr_font_26,
fill=first_color,
anchor='mm',
)
img_draw.text(
(350, 650),
f'错误码 {daily_data}',
font=sr_font_26,
fill=red_color,
anchor='mm',
)
return img
async def seconds2hours_zhcn(seconds: int) -> str: async def seconds2hours_zhcn(seconds: int) -> str:
@ -142,32 +166,19 @@ async def seconds2hours_zhcn(seconds: int) -> str:
return '%02d小时%02d' % (h, m) return '%02d小时%02d' % (h, m)
async def draw_resin_img(sr_uid: str) -> Image.Image: async def draw_stamina_img(sr_uid: str) -> Image.Image:
# 获取数据
daily_data = await mys_api.get_daily_data(sr_uid)
img = await get_simple_bg(based_w, based_h) img = await get_simple_bg(based_w, based_h)
img.paste(white_overlay, (0, 0), white_overlay) img.paste(white_overlay, (0, 0), white_overlay)
if isinstance(daily_data, int): # 获取数据
img_draw = ImageDraw.Draw(img) if use_widget and int(str(sr_uid)[0]) <= 5:
img.paste(warn_pic, (0, 0), warn_pic) _daily_data = await mys_api.get_widget_stamina_data(sr_uid)
# 写UID if isinstance(_daily_data, int):
img_draw.text( return get_error(img, sr_uid, _daily_data)
(350, 680), # daily_data = transform_fake_resin(_daily_data)
f'UID{sr_uid}', daily_data = _daily_data
font=sr_font_26, else:
fill=first_color, daily_data = await mys_api.get_daily_data(sr_uid)
anchor='mm',
)
img_draw.text(
(350, 650),
f'错误码 {daily_data}',
font=sr_font_26,
fill=red_color,
anchor='mm',
)
return img
# nickname and level # nickname and level
# deal with hoyolab with no nickname and level api # deal with hoyolab with no nickname and level api

View File

@ -11,7 +11,7 @@ from ..sruid_utils.api.mys.models import DailyNoteData
MR_NOTICE = '\n可发送[srmr]或者[sr每日]来查看更多信息!\n' MR_NOTICE = '\n可发送[srmr]或者[sr每日]来查看更多信息!\n'
NOTICE = { NOTICE = {
'resin': f'你的开拓力快满啦!{MR_NOTICE}', 'stamina': f'你的开拓力快满啦!{MR_NOTICE}',
'go': f'你有派遣信息即将可收取!{MR_NOTICE}', 'go': f'你有派遣信息即将可收取!{MR_NOTICE}',
} }

View File

@ -19,7 +19,7 @@ def seconds2hours(seconds: int) -> str:
return '%02d:%02d:%02d' % (h, m, s) return '%02d:%02d:%02d' % (h, m, s)
async def get_resin_text(uid: str) -> str: async def get_stamina_text(uid: str) -> str:
try: try:
dailydata = await mys_api.get_daily_data(uid) dailydata = await mys_api.get_daily_data(uid)
if isinstance(dailydata, int): if isinstance(dailydata, int):

View File

Before

Width:  |  Height:  |  Size: 373 KiB

After

Width:  |  Height:  |  Size: 373 KiB

View File

Before

Width:  |  Height:  |  Size: 31 KiB

After

Width:  |  Height:  |  Size: 31 KiB

View File

Before

Width:  |  Height:  |  Size: 784 KiB

After

Width:  |  Height:  |  Size: 784 KiB

View File

Before

Width:  |  Height:  |  Size: 130 KiB

After

Width:  |  Height:  |  Size: 130 KiB

View File

@ -2,11 +2,15 @@ import copy
import time import time
import random import random
from string import digits, ascii_letters from string import digits, ascii_letters
from typing import Dict, Union, Optional, cast from typing import Any, Dict, Union, Optional, cast
from gsuid_core.utils.api.mys_api import _MysApi from gsuid_core.utils.api.mys_api import _MysApi
from gsuid_core.utils.api.mys.models import MysSign, SignInfo, SignList from gsuid_core.utils.api.mys.models import MysSign, SignInfo, SignList
from gsuid_core.utils.api.mys.tools import generate_os_ds, get_web_ds_token from gsuid_core.utils.api.mys.tools import (
_random_int_ds,
generate_os_ds,
get_web_ds_token,
)
from .api import srdbsqla from .api import srdbsqla
from ..sruid_utils.api.mys.api import _API from ..sruid_utils.api.mys.api import _API
@ -19,6 +23,7 @@ from ..sruid_utils.api.mys.models import (
MonthlyAward, MonthlyAward,
DailyNoteData, DailyNoteData,
RoleBasicInfo, RoleBasicInfo,
WidgetStamina,
) )
RECOGNIZE_SERVER = { RECOGNIZE_SERVER = {
@ -32,6 +37,14 @@ RECOGNIZE_SERVER = {
} }
def get_ds_token2(
q: str = '',
b: Optional[Dict[str, Any]] = None,
):
salt = 't0qEgfub6cvueAPgR5m9aQWWVciEer7v'
return _random_int_ds(salt, q, b)
class MysApi(_MysApi): class MysApi(_MysApi):
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs) super().__init__(*args, **kwargs)
@ -83,6 +96,32 @@ class MysApi(_MysApi):
data = cast(DailyNoteData, data['data']) data = cast(DailyNoteData, data['data'])
return data return data
async def get_widget_stamina_data(
self, uid: str
) -> Union[WidgetStamina, int]:
header = copy.deepcopy(self._HEADER)
sk = await self.get_stoken(uid)
if sk is None:
return -51
header['Cookie'] = sk
header['x-rpc-channel'] = 'beta'
header['x-rpc-device_id'] = await self.get_user_device_id(uid)
header['x-rpc-app_version'] = '2.53.0'
header['x-rpc-device_model'] = 'Mi 10'
header['x-rpc-device_fp'] = await self.get_user_fp(uid)
header['x-rpc-client_type'] = '2'
header['DS'] = get_ds_token2()
header['Referer'] = 'https://app.mihoyo.com'
del header['Origin']
header['x-rpc-sys_version'] = '12'
header['User-Agent'] = 'okhttp/4.8.0'
data = await self._mys_request(
_API['STAR_RAIL_WIDGRT_URL'], 'GET', header
)
if isinstance(data, Dict):
data = cast(WidgetStamina, data['data'])
return data
async def get_role_index(self, uid: str) -> Union[RoleIndex, int]: async def get_role_index(self, uid: str) -> Union[RoleIndex, int]:
is_os = self.check_os(uid) is_os = self.check_os(uid)
if is_os: if is_os:

122
poetry.lock generated
View File

@ -248,19 +248,19 @@ test = ["pytest (>=6)"]
[[package]] [[package]]
name = "filelock" name = "filelock"
version = "3.12.0" version = "3.12.2"
description = "A platform independent file lock." description = "A platform independent file lock."
category = "dev" category = "dev"
optional = false optional = false
python-versions = ">=3.7" python-versions = ">=3.7"
files = [ files = [
{file = "filelock-3.12.0-py3-none-any.whl", hash = "sha256:ad98852315c2ab702aeb628412cbf7e95b7ce8c3bf9565670b4eaecf1db370a9"}, {file = "filelock-3.12.2-py3-none-any.whl", hash = "sha256:cbb791cdea2a72f23da6ac5b5269ab0a0d161e9ef0100e653b69049a7706d1ec"},
{file = "filelock-3.12.0.tar.gz", hash = "sha256:fc03ae43288c013d2ea83c8597001b1129db351aad9c57fe2409327916b8e718"}, {file = "filelock-3.12.2.tar.gz", hash = "sha256:002740518d8aa59a26b0c76e10fb8c6e15eae825d34b6fdf670333fd7b938d81"},
] ]
[package.extras] [package.extras]
docs = ["furo (>=2023.3.27)", "sphinx (>=6.1.3)", "sphinx-autodoc-typehints (>=1.23,!=1.23.4)"] docs = ["furo (>=2023.5.20)", "sphinx (>=7.0.1)", "sphinx-autodoc-typehints (>=1.23,!=1.23.4)"]
testing = ["covdefaults (>=2.3)", "coverage (>=7.2.3)", "diff-cover (>=7.5)", "pytest (>=7.3.1)", "pytest-cov (>=4)", "pytest-mock (>=3.10)", "pytest-timeout (>=2.1)"] testing = ["covdefaults (>=2.3)", "coverage (>=7.2.7)", "diff-cover (>=7.5)", "pytest (>=7.3.1)", "pytest-cov (>=4.1)", "pytest-mock (>=3.10)", "pytest-timeout (>=2.1)"]
[[package]] [[package]]
name = "flake8" name = "flake8"
@ -598,19 +598,19 @@ files = [
[[package]] [[package]]
name = "platformdirs" name = "platformdirs"
version = "3.5.1" version = "3.6.0"
description = "A small Python package for determining appropriate platform-specific dirs, e.g. a \"user data dir\"." description = "A small Python package for determining appropriate platform-specific dirs, e.g. a \"user data dir\"."
category = "dev" category = "dev"
optional = false optional = false
python-versions = ">=3.7" python-versions = ">=3.7"
files = [ files = [
{file = "platformdirs-3.5.1-py3-none-any.whl", hash = "sha256:e2378146f1964972c03c085bb5662ae80b2b8c06226c54b2ff4aa9483e8a13a5"}, {file = "platformdirs-3.6.0-py3-none-any.whl", hash = "sha256:ffa199e3fbab8365778c4a10e1fbf1b9cd50707de826eb304b50e57ec0cc8d38"},
{file = "platformdirs-3.5.1.tar.gz", hash = "sha256:412dae91f52a6f84830f39a8078cecd0e866cb72294a5c66808e74d5e88d251f"}, {file = "platformdirs-3.6.0.tar.gz", hash = "sha256:57e28820ca8094678b807ff529196506d7a21e17156cb1cddb3e74cebce54640"},
] ]
[package.extras] [package.extras]
docs = ["furo (>=2023.3.27)", "proselint (>=0.13)", "sphinx (>=6.2.1)", "sphinx-autodoc-typehints (>=1.23,!=1.23.4)"] docs = ["furo (>=2023.5.20)", "proselint (>=0.13)", "sphinx (>=7.0.1)", "sphinx-autodoc-typehints (>=1.23,!=1.23.4)"]
test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=7.3.1)", "pytest-cov (>=4)", "pytest-mock (>=3.10)"] test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=7.3.1)", "pytest-cov (>=4.1)", "pytest-mock (>=3.10)"]
[[package]] [[package]]
name = "pluggy" name = "pluggy"
@ -680,48 +680,48 @@ files = [
[[package]] [[package]]
name = "pydantic" name = "pydantic"
version = "1.10.8" version = "1.10.9"
description = "Data validation and settings management using python type hints" description = "Data validation and settings management using python type hints"
category = "dev" category = "dev"
optional = false optional = false
python-versions = ">=3.7" python-versions = ">=3.7"
files = [ files = [
{file = "pydantic-1.10.8-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:1243d28e9b05003a89d72e7915fdb26ffd1d39bdd39b00b7dbe4afae4b557f9d"}, {file = "pydantic-1.10.9-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e692dec4a40bfb40ca530e07805b1208c1de071a18d26af4a2a0d79015b352ca"},
{file = "pydantic-1.10.8-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c0ab53b609c11dfc0c060d94335993cc2b95b2150e25583bec37a49b2d6c6c3f"}, {file = "pydantic-1.10.9-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:3c52eb595db83e189419bf337b59154bdcca642ee4b2a09e5d7797e41ace783f"},
{file = "pydantic-1.10.8-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f9613fadad06b4f3bc5db2653ce2f22e0de84a7c6c293909b48f6ed37b83c61f"}, {file = "pydantic-1.10.9-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:939328fd539b8d0edf244327398a667b6b140afd3bf7e347cf9813c736211896"},
{file = "pydantic-1.10.8-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:df7800cb1984d8f6e249351139667a8c50a379009271ee6236138a22a0c0f319"}, {file = "pydantic-1.10.9-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b48d3d634bca23b172f47f2335c617d3fcb4b3ba18481c96b7943a4c634f5c8d"},
{file = "pydantic-1.10.8-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:0c6fafa0965b539d7aab0a673a046466d23b86e4b0e8019d25fd53f4df62c277"}, {file = "pydantic-1.10.9-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:f0b7628fb8efe60fe66fd4adadd7ad2304014770cdc1f4934db41fe46cc8825f"},
{file = "pydantic-1.10.8-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:e82d4566fcd527eae8b244fa952d99f2ca3172b7e97add0b43e2d97ee77f81ab"}, {file = "pydantic-1.10.9-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:e1aa5c2410769ca28aa9a7841b80d9d9a1c5f223928ca8bec7e7c9a34d26b1d4"},
{file = "pydantic-1.10.8-cp310-cp310-win_amd64.whl", hash = "sha256:ab523c31e22943713d80d8d342d23b6f6ac4b792a1e54064a8d0cf78fd64e800"}, {file = "pydantic-1.10.9-cp310-cp310-win_amd64.whl", hash = "sha256:eec39224b2b2e861259d6f3c8b6290d4e0fbdce147adb797484a42278a1a486f"},
{file = "pydantic-1.10.8-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:666bdf6066bf6dbc107b30d034615d2627e2121506c555f73f90b54a463d1f33"}, {file = "pydantic-1.10.9-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:d111a21bbbfd85c17248130deac02bbd9b5e20b303338e0dbe0faa78330e37e0"},
{file = "pydantic-1.10.8-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:35db5301b82e8661fa9c505c800d0990bc14e9f36f98932bb1d248c0ac5cada5"}, {file = "pydantic-1.10.9-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:2e9aec8627a1a6823fc62fb96480abe3eb10168fd0d859ee3d3b395105ae19a7"},
{file = "pydantic-1.10.8-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f90c1e29f447557e9e26afb1c4dbf8768a10cc676e3781b6a577841ade126b85"}, {file = "pydantic-1.10.9-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:07293ab08e7b4d3c9d7de4949a0ea571f11e4557d19ea24dd3ae0c524c0c334d"},
{file = "pydantic-1.10.8-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:93e766b4a8226e0708ef243e843105bf124e21331694367f95f4e3b4a92bbb3f"}, {file = "pydantic-1.10.9-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7ee829b86ce984261d99ff2fd6e88f2230068d96c2a582f29583ed602ef3fc2c"},
{file = "pydantic-1.10.8-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:88f195f582851e8db960b4a94c3e3ad25692c1c1539e2552f3df7a9e972ef60e"}, {file = "pydantic-1.10.9-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:4b466a23009ff5cdd7076eb56aca537c745ca491293cc38e72bf1e0e00de5b91"},
{file = "pydantic-1.10.8-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:34d327c81e68a1ecb52fe9c8d50c8a9b3e90d3c8ad991bfc8f953fb477d42fb4"}, {file = "pydantic-1.10.9-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:7847ca62e581e6088d9000f3c497267868ca2fa89432714e21a4fb33a04d52e8"},
{file = "pydantic-1.10.8-cp311-cp311-win_amd64.whl", hash = "sha256:d532bf00f381bd6bc62cabc7d1372096b75a33bc197a312b03f5838b4fb84edd"}, {file = "pydantic-1.10.9-cp311-cp311-win_amd64.whl", hash = "sha256:7845b31959468bc5b78d7b95ec52fe5be32b55d0d09983a877cca6aedc51068f"},
{file = "pydantic-1.10.8-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:7d5b8641c24886d764a74ec541d2fc2c7fb19f6da2a4001e6d580ba4a38f7878"}, {file = "pydantic-1.10.9-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:517a681919bf880ce1dac7e5bc0c3af1e58ba118fd774da2ffcd93c5f96eaece"},
{file = "pydantic-1.10.8-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7b1f6cb446470b7ddf86c2e57cd119a24959af2b01e552f60705910663af09a4"}, {file = "pydantic-1.10.9-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:67195274fd27780f15c4c372f4ba9a5c02dad6d50647b917b6a92bf00b3d301a"},
{file = "pydantic-1.10.8-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c33b60054b2136aef8cf190cd4c52a3daa20b2263917c49adad20eaf381e823b"}, {file = "pydantic-1.10.9-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2196c06484da2b3fded1ab6dbe182bdabeb09f6318b7fdc412609ee2b564c49a"},
{file = "pydantic-1.10.8-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:1952526ba40b220b912cdc43c1c32bcf4a58e3f192fa313ee665916b26befb68"}, {file = "pydantic-1.10.9-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:6257bb45ad78abacda13f15bde5886efd6bf549dd71085e64b8dcf9919c38b60"},
{file = "pydantic-1.10.8-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:bb14388ec45a7a0dc429e87def6396f9e73c8c77818c927b6a60706603d5f2ea"}, {file = "pydantic-1.10.9-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:3283b574b01e8dbc982080d8287c968489d25329a463b29a90d4157de4f2baaf"},
{file = "pydantic-1.10.8-cp37-cp37m-win_amd64.whl", hash = "sha256:16f8c3e33af1e9bb16c7a91fc7d5fa9fe27298e9f299cff6cb744d89d573d62c"}, {file = "pydantic-1.10.9-cp37-cp37m-win_amd64.whl", hash = "sha256:5f8bbaf4013b9a50e8100333cc4e3fa2f81214033e05ac5aa44fa24a98670a29"},
{file = "pydantic-1.10.8-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1ced8375969673929809d7f36ad322934c35de4af3b5e5b09ec967c21f9f7887"}, {file = "pydantic-1.10.9-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:b9cd67fb763248cbe38f0593cd8611bfe4b8ad82acb3bdf2b0898c23415a1f82"},
{file = "pydantic-1.10.8-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:93e6bcfccbd831894a6a434b0aeb1947f9e70b7468f274154d03d71fabb1d7c6"}, {file = "pydantic-1.10.9-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:f50e1764ce9353be67267e7fd0da08349397c7db17a562ad036aa7c8f4adfdb6"},
{file = "pydantic-1.10.8-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:191ba419b605f897ede9892f6c56fb182f40a15d309ef0142212200a10af4c18"}, {file = "pydantic-1.10.9-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:73ef93e5e1d3c8e83f1ff2e7fdd026d9e063c7e089394869a6e2985696693766"},
{file = "pydantic-1.10.8-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:052d8654cb65174d6f9490cc9b9a200083a82cf5c3c5d3985db765757eb3b375"}, {file = "pydantic-1.10.9-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:128d9453d92e6e81e881dd7e2484e08d8b164da5507f62d06ceecf84bf2e21d3"},
{file = "pydantic-1.10.8-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:ceb6a23bf1ba4b837d0cfe378329ad3f351b5897c8d4914ce95b85fba96da5a1"}, {file = "pydantic-1.10.9-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:ad428e92ab68798d9326bb3e5515bc927444a3d71a93b4a2ca02a8a5d795c572"},
{file = "pydantic-1.10.8-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:6f2e754d5566f050954727c77f094e01793bcb5725b663bf628fa6743a5a9108"}, {file = "pydantic-1.10.9-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:fab81a92f42d6d525dd47ced310b0c3e10c416bbfae5d59523e63ea22f82b31e"},
{file = "pydantic-1.10.8-cp38-cp38-win_amd64.whl", hash = "sha256:6a82d6cda82258efca32b40040228ecf43a548671cb174a1e81477195ed3ed56"}, {file = "pydantic-1.10.9-cp38-cp38-win_amd64.whl", hash = "sha256:963671eda0b6ba6926d8fc759e3e10335e1dc1b71ff2a43ed2efd6996634dafb"},
{file = "pydantic-1.10.8-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:3e59417ba8a17265e632af99cc5f35ec309de5980c440c255ab1ca3ae96a3e0e"}, {file = "pydantic-1.10.9-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:970b1bdc6243ef663ba5c7e36ac9ab1f2bfecb8ad297c9824b542d41a750b298"},
{file = "pydantic-1.10.8-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:84d80219c3f8d4cad44575e18404099c76851bc924ce5ab1c4c8bb5e2a2227d0"}, {file = "pydantic-1.10.9-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:7e1d5290044f620f80cf1c969c542a5468f3656de47b41aa78100c5baa2b8276"},
{file = "pydantic-1.10.8-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2e4148e635994d57d834be1182a44bdb07dd867fa3c2d1b37002000646cc5459"}, {file = "pydantic-1.10.9-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:83fcff3c7df7adff880622a98022626f4f6dbce6639a88a15a3ce0f96466cb60"},
{file = "pydantic-1.10.8-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:12f7b0bf8553e310e530e9f3a2f5734c68699f42218bf3568ef49cd9b0e44df4"}, {file = "pydantic-1.10.9-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0da48717dc9495d3a8f215e0d012599db6b8092db02acac5e0d58a65248ec5bc"},
{file = "pydantic-1.10.8-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:42aa0c4b5c3025483240a25b09f3c09a189481ddda2ea3a831a9d25f444e03c1"}, {file = "pydantic-1.10.9-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:0a2aabdc73c2a5960e87c3ffebca6ccde88665616d1fd6d3db3178ef427b267a"},
{file = "pydantic-1.10.8-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:17aef11cc1b997f9d574b91909fed40761e13fac438d72b81f902226a69dac01"}, {file = "pydantic-1.10.9-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:9863b9420d99dfa9c064042304868e8ba08e89081428a1c471858aa2af6f57c4"},
{file = "pydantic-1.10.8-cp39-cp39-win_amd64.whl", hash = "sha256:66a703d1983c675a6e0fed8953b0971c44dba48a929a2000a493c3772eb61a5a"}, {file = "pydantic-1.10.9-cp39-cp39-win_amd64.whl", hash = "sha256:e7c9900b43ac14110efa977be3da28931ffc74c27e96ee89fbcaaf0b0fe338e1"},
{file = "pydantic-1.10.8-py3-none-any.whl", hash = "sha256:7456eb22ed9aaa24ff3e7b4757da20d9e5ce2a81018c1b3ebd81a0b88a18f3b2"}, {file = "pydantic-1.10.9-py3-none-any.whl", hash = "sha256:6cafde02f6699ce4ff643417d1a9223716ec25e228ddc3b436fe7e2d25a1f305"},
{file = "pydantic-1.10.8.tar.gz", hash = "sha256:1410275520dfa70effadf4c21811d755e7ef9bb1f1d077a21958153a92c8d9ca"}, {file = "pydantic-1.10.9.tar.gz", hash = "sha256:95c70da2cd3b6ddf3b9645ecaa8d98f3d80c606624b6d245558d202cd23ea3be"},
] ]
[package.dependencies] [package.dependencies]
@ -758,14 +758,14 @@ files = [
[[package]] [[package]]
name = "pytest" name = "pytest"
version = "7.3.1" version = "7.3.2"
description = "pytest: simple powerful testing with Python" description = "pytest: simple powerful testing with Python"
category = "dev" category = "dev"
optional = false optional = false
python-versions = ">=3.7" python-versions = ">=3.7"
files = [ files = [
{file = "pytest-7.3.1-py3-none-any.whl", hash = "sha256:3799fa815351fea3a5e96ac7e503a96fa51cc9942c3753cda7651b93c1cfa362"}, {file = "pytest-7.3.2-py3-none-any.whl", hash = "sha256:cdcbd012c9312258922f8cd3f1b62a6580fdced17db6014896053d47cddf9295"},
{file = "pytest-7.3.1.tar.gz", hash = "sha256:434afafd78b1d78ed0addf160ad2b77a30d35d4bdf8af234fe621919d9ed15e3"}, {file = "pytest-7.3.2.tar.gz", hash = "sha256:ee990a3cc55ba808b80795a79944756f315c67c12b56abd3ac993a7b8c17030b"},
] ]
[package.dependencies] [package.dependencies]
@ -777,7 +777,7 @@ pluggy = ">=0.12,<2.0"
tomli = {version = ">=1.0.0", markers = "python_version < \"3.11\""} tomli = {version = ">=1.0.0", markers = "python_version < \"3.11\""}
[package.extras] [package.extras]
testing = ["argcomplete", "attrs (>=19.2.0)", "hypothesis (>=3.56)", "mock", "nose", "pygments (>=2.7.2)", "requests", "xmlschema"] testing = ["argcomplete", "attrs (>=19.2.0)", "hypothesis (>=3.56)", "mock", "nose", "pygments (>=2.7.2)", "requests", "setuptools", "xmlschema"]
[[package]] [[package]]
name = "pytest-asyncio" name = "pytest-asyncio"
@ -978,14 +978,14 @@ typing-extensions = ">=3.7.4"
[[package]] [[package]]
name = "urllib3" name = "urllib3"
version = "2.0.2" version = "2.0.3"
description = "HTTP library with thread-safe connection pooling, file post, and more." description = "HTTP library with thread-safe connection pooling, file post, and more."
category = "dev" category = "dev"
optional = false optional = false
python-versions = ">=3.7" python-versions = ">=3.7"
files = [ files = [
{file = "urllib3-2.0.2-py3-none-any.whl", hash = "sha256:d055c2f9d38dc53c808f6fdc8eab7360b6fdbbde02340ed25cfbcd817c62469e"}, {file = "urllib3-2.0.3-py3-none-any.whl", hash = "sha256:48e7fafa40319d358848e1bc6809b208340fafe2096f1725d05d67443d0483d1"},
{file = "urllib3-2.0.2.tar.gz", hash = "sha256:61717a1095d7e155cdb737ac7bb2f4324a858a1e2e6466f6d03ff630ca68d3cc"}, {file = "urllib3-2.0.3.tar.gz", hash = "sha256:bee28b5e56addb8226c96f7f13ac28cb4c301dd5ea8a6ca179c0b9835e032825"},
] ]
[package.extras] [package.extras]
@ -996,24 +996,24 @@ zstd = ["zstandard (>=0.18.0)"]
[[package]] [[package]]
name = "virtualenv" name = "virtualenv"
version = "20.23.0" version = "20.23.1"
description = "Virtual Python Environment builder" description = "Virtual Python Environment builder"
category = "dev" category = "dev"
optional = false optional = false
python-versions = ">=3.7" python-versions = ">=3.7"
files = [ files = [
{file = "virtualenv-20.23.0-py3-none-any.whl", hash = "sha256:6abec7670e5802a528357fdc75b26b9f57d5d92f29c5462ba0fbe45feacc685e"}, {file = "virtualenv-20.23.1-py3-none-any.whl", hash = "sha256:34da10f14fea9be20e0fd7f04aba9732f84e593dac291b757ce42e3368a39419"},
{file = "virtualenv-20.23.0.tar.gz", hash = "sha256:a85caa554ced0c0afbd0d638e7e2d7b5f92d23478d05d17a76daeac8f279f924"}, {file = "virtualenv-20.23.1.tar.gz", hash = "sha256:8ff19a38c1021c742148edc4f81cb43d7f8c6816d2ede2ab72af5b84c749ade1"},
] ]
[package.dependencies] [package.dependencies]
distlib = ">=0.3.6,<1" distlib = ">=0.3.6,<1"
filelock = ">=3.11,<4" filelock = ">=3.12,<4"
platformdirs = ">=3.2,<4" platformdirs = ">=3.5.1,<4"
[package.extras] [package.extras]
docs = ["furo (>=2023.3.27)", "proselint (>=0.13)", "sphinx (>=6.1.3)", "sphinx-argparse (>=0.4)", "sphinxcontrib-towncrier (>=0.2.1a0)", "towncrier (>=22.12)"] docs = ["furo (>=2023.5.20)", "proselint (>=0.13)", "sphinx (>=7.0.1)", "sphinx-argparse (>=0.4)", "sphinxcontrib-towncrier (>=0.2.1a0)", "towncrier (>=23.6)"]
test = ["covdefaults (>=2.3)", "coverage (>=7.2.3)", "coverage-enable-subprocess (>=1)", "flaky (>=3.7)", "packaging (>=23.1)", "pytest (>=7.3.1)", "pytest-env (>=0.8.1)", "pytest-freezegun (>=0.4.2)", "pytest-mock (>=3.10)", "pytest-randomly (>=3.12)", "pytest-timeout (>=2.1)", "setuptools (>=67.7.1)", "time-machine (>=2.9)"] test = ["covdefaults (>=2.3)", "coverage (>=7.2.7)", "coverage-enable-subprocess (>=1)", "flaky (>=3.7)", "packaging (>=23.1)", "pytest (>=7.3.1)", "pytest-env (>=0.8.1)", "pytest-freezer (>=0.4.6)", "pytest-mock (>=3.10)", "pytest-randomly (>=3.12)", "pytest-timeout (>=2.1)", "setuptools (>=67.8)", "time-machine (>=2.9)"]
[[package]] [[package]]
name = "win32-setctime" name = "win32-setctime"