mirror of
https://github.com/suyiiyii/nonebot-bison.git
synced 2026-05-11 03:18:29 +08:00
Compare commits
6 Commits
94daf74359
..
pnpm
| Author | SHA1 | Date | |
|---|---|---|---|
| f01c2567c1 | |||
| 75ab14cd98 | |||
| bd81449534 | |||
| cf6b7fcd6d | |||
| 2c70d3c44e | |||
| d5c31394df |
@@ -4,7 +4,7 @@
|
||||
"features": {
|
||||
"ghcr.io/devcontainers-contrib/features/poetry:2": {}
|
||||
},
|
||||
"postCreateCommand": "poetry config virtualenvs.in-project true && poetry install -E all && poetry run pre-commit install && yarn install",
|
||||
"postCreateCommand": "poetry config virtualenvs.in-project true && poetry install -E all && poetry run pre-commit install && npm install -g pnpm && pnpm install",
|
||||
"customizations": {
|
||||
"vscode": {
|
||||
"settings": {
|
||||
|
||||
@@ -10,5 +10,5 @@ runs:
|
||||
- name: Build Frontend
|
||||
shell: bash
|
||||
run: |
|
||||
yarn install
|
||||
yarn docs:build
|
||||
pnpm install
|
||||
pnpm docs:build
|
||||
|
||||
@@ -11,5 +11,5 @@ runs:
|
||||
shell: bash
|
||||
working-directory: ./admin-frontend
|
||||
run: |
|
||||
yarn install
|
||||
yarn build
|
||||
pnpm install
|
||||
pnpm build
|
||||
|
||||
@@ -8,11 +8,16 @@ runs:
|
||||
with:
|
||||
node-version: "20"
|
||||
|
||||
- id: yarn-cache-dir-path
|
||||
run: echo "::set-output name=dir::$(yarn cache dir)"
|
||||
- name: Set Up Pnpm
|
||||
uses: pnpm/action-setup@v4
|
||||
with:
|
||||
version: 9
|
||||
|
||||
- id: pnpm-cache-dir-path
|
||||
run: echo "::set-output name=dir::$(pnpm store path)"
|
||||
shell: bash
|
||||
|
||||
- uses: actions/cache@v4
|
||||
with:
|
||||
path: ${{ steps.yarn-cache-dir-path.outputs.dir }}
|
||||
key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
|
||||
path: ${{ steps.pnpm-cache-dir-path.outputs.dir }}
|
||||
key: ${{ runner.os }}-pnpm-${{ hashFiles('**/pnpm-lock.yaml') }}
|
||||
|
||||
@@ -13,18 +13,18 @@
|
||||
"@testing-library/dom": "^10.4.0",
|
||||
"@testing-library/react": "^16.0.1",
|
||||
"@testing-library/user-event": "^14.5.2",
|
||||
"@types/jest": "^29.5.12",
|
||||
"@types/jest": "^29.5.13",
|
||||
"@types/node": "^20.16.5",
|
||||
"@types/react": "^18.3.5",
|
||||
"@types/react": "^18.3.7",
|
||||
"@types/react-dom": "^18.3.0",
|
||||
"react": "^18.3.1",
|
||||
"react-dom": "^18.3.1",
|
||||
"react-redux": "^9.1.2",
|
||||
"react-router-dom": "^6.26.1",
|
||||
"react-router-dom": "^6.26.2",
|
||||
"react-scripts": "5.0.1",
|
||||
"redux": "^5.0.1",
|
||||
"redux-persist": "^6.0.0",
|
||||
"typescript": "^5.5.4",
|
||||
"typescript": "^5.6.2",
|
||||
"web-vitals": "^3.5.2"
|
||||
},
|
||||
"scripts": {
|
||||
@@ -54,15 +54,15 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"@testing-library/jest-dom": "^6.5.0",
|
||||
"@typescript-eslint/eslint-plugin": "^8.4.0",
|
||||
"@typescript-eslint/parser": "^8.4.0",
|
||||
"eslint": "^9.10.0",
|
||||
"@typescript-eslint/eslint-plugin": "^8.6.0",
|
||||
"@typescript-eslint/parser": "^8.6.0",
|
||||
"eslint": "^8.57.1",
|
||||
"eslint-config-airbnb": "^19.0.4",
|
||||
"eslint-config-airbnb-typescript": "^18.0.0",
|
||||
"eslint-import-resolver-typescript": "^3.6.3",
|
||||
"eslint-plugin-import": "^2.30.0",
|
||||
"eslint-plugin-jsx-a11y": "^6.10.0",
|
||||
"eslint-plugin-react": "^7.35.2",
|
||||
"eslint-plugin-react": "^7.36.1",
|
||||
"eslint-plugin-react-hooks": "^4.6.2",
|
||||
"eslint-plugin-react-redux": "^4.2.0"
|
||||
}
|
||||
|
||||
Generated
+339
-350
File diff suppressed because it is too large
Load Diff
+2
-1
@@ -1,7 +1,8 @@
|
||||
FROM node:20.17.0 as frontend
|
||||
ADD . /app
|
||||
WORKDIR /app/admin-frontend
|
||||
RUN yarn && yarn build
|
||||
RUN npm install -g pnpm
|
||||
RUN pnpm install && pnpm build
|
||||
|
||||
FROM python:3.11
|
||||
RUN python3 -m pip install poetry && poetry config virtualenvs.create false
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# syntax=docker/dockerfile:1.9
|
||||
# syntax=docker/dockerfile:1.10
|
||||
FROM python:3.11-slim-bullseye as base
|
||||
|
||||
FROM base as builder
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# syntax=docker/dockerfile:1.9
|
||||
# syntax=docker/dockerfile:1.10
|
||||
FROM python:3.11-slim-bullseye as base
|
||||
|
||||
FROM base as builder
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
from typing import cast
|
||||
|
||||
import nonebot
|
||||
from fastapi import status
|
||||
from fastapi.routing import APIRouter
|
||||
@@ -14,18 +12,14 @@ from ..apis import check_sub_target
|
||||
from .jwt import load_jwt, pack_jwt
|
||||
from ..types import Target as T_Target
|
||||
from ..utils.get_bot import get_groups
|
||||
from ..platform import platform_manager
|
||||
from .token_manager import token_manager
|
||||
from ..config.db_config import SubscribeDupException
|
||||
from ..platform import site_manager, platform_manager
|
||||
from ..utils.site import CookieClientManager, is_cookie_client_manager
|
||||
from ..config import NoSuchUserException, NoSuchTargetException, NoSuchSubscribeException, config
|
||||
from .types import (
|
||||
Cookie,
|
||||
TokenResp,
|
||||
GlobalConf,
|
||||
SiteConfig,
|
||||
StatusResp,
|
||||
CookieTarget,
|
||||
SubscribeResp,
|
||||
PlatformConfig,
|
||||
AddSubscribeReq,
|
||||
@@ -60,20 +54,16 @@ async def check_is_superuser(token_obj: dict = Depends(get_jwt_obj)):
|
||||
|
||||
@router.get("/global_conf")
|
||||
async def get_global_conf() -> GlobalConf:
|
||||
platform_res = {}
|
||||
res = {}
|
||||
for platform_name, platform in platform_manager.items():
|
||||
platform_res[platform_name] = PlatformConfig(
|
||||
res[platform_name] = PlatformConfig(
|
||||
platformName=platform_name,
|
||||
categories=platform.categories,
|
||||
enabledTag=platform.enable_tag,
|
||||
site_name=platform.site.name,
|
||||
name=platform.name,
|
||||
hasTarget=getattr(platform, "has_target"),
|
||||
)
|
||||
site_res = {}
|
||||
for site_name, site in site_manager.items():
|
||||
site_res[site_name] = SiteConfig(name=site_name, enable_cookie=is_cookie_client_manager(site.client_mgr))
|
||||
return GlobalConf(platformConf=platform_res, siteConf=site_res)
|
||||
return GlobalConf(platformConf=res)
|
||||
|
||||
|
||||
async def get_admin_groups(qq: int):
|
||||
@@ -207,64 +197,3 @@ async def update_weigth_config(platformName: str, target: str, weight_config: We
|
||||
except NoSuchTargetException:
|
||||
raise HTTPException(status.HTTP_400_BAD_REQUEST, "no such subscribe")
|
||||
return StatusResp(ok=True, msg="")
|
||||
|
||||
|
||||
@router.get("/cookie", dependencies=[Depends(check_is_superuser)])
|
||||
async def get_cookie(site_name: str = None, target: str = None) -> list[Cookie]:
|
||||
cookies_in_db = await config.get_cookie(site_name, is_anonymous=False)
|
||||
client_mgr = cast(CookieClientManager, site_manager[site_name].client_mgr)
|
||||
friendly_names = [await client_mgr.get_cookie_friendly_name(x) for x in cookies_in_db]
|
||||
return [
|
||||
Cookie(
|
||||
id=cookies_in_db[i].id,
|
||||
friendly_name=friendly_names[i],
|
||||
site_name=cookies_in_db[i].site_name,
|
||||
last_usage=cookies_in_db[i].last_usage,
|
||||
status=cookies_in_db[i].status,
|
||||
cd_milliseconds=cookies_in_db[i].cd_milliseconds,
|
||||
is_universal=cookies_in_db[i].is_universal,
|
||||
is_anonymous=cookies_in_db[i].is_anonymous,
|
||||
tags=cookies_in_db[i].tags,
|
||||
)
|
||||
for i in range(len(cookies_in_db))
|
||||
]
|
||||
|
||||
|
||||
@router.post("/cookie", dependencies=[Depends(check_is_superuser)])
|
||||
async def add_cookie(site_name: str, content: str) -> StatusResp:
|
||||
client_mgr = cast(CookieClientManager, site_manager[site_name].client_mgr)
|
||||
await client_mgr.add_user_cookie(content)
|
||||
return StatusResp(ok=True, msg="")
|
||||
|
||||
|
||||
@router.delete("/cookie/{cookie_id}", dependencies=[Depends(check_is_superuser)])
|
||||
async def delete_cookie_by_id(cookie_id: int) -> StatusResp:
|
||||
await config.delete_cookie_by_id(cookie_id)
|
||||
return StatusResp(ok=True, msg="")
|
||||
|
||||
|
||||
@router.get("/cookie_target", dependencies=[Depends(check_is_superuser)])
|
||||
async def get_cookie_target(
|
||||
site_name: str | None = None, target: str | None = None, cookie_id: int | None = None
|
||||
) -> list[CookieTarget]:
|
||||
cookie_targets = await config.get_cookie_target()
|
||||
# TODO: filter in SQL
|
||||
return [
|
||||
x
|
||||
for x in cookie_targets
|
||||
if (site_name is None or x.cookie.site_name == site_name)
|
||||
and (target is None or x.target.target == target)
|
||||
and (cookie_id is None or x.cookie.id == cookie_id)
|
||||
]
|
||||
|
||||
|
||||
@router.post("/cookie_target", dependencies=[Depends(check_is_superuser)])
|
||||
async def add_cookie_target(platform_name: str, target: str, cookie_id: int) -> StatusResp:
|
||||
await config.add_cookie_target(target, platform_name, cookie_id)
|
||||
return StatusResp(ok=True, msg="")
|
||||
|
||||
|
||||
@router.delete("/cookie_target", dependencies=[Depends(check_is_superuser)])
|
||||
async def del_cookie_target(platform_name: str, target: str, cookie_id: int) -> StatusResp:
|
||||
await config.delete_cookie_target(target, platform_name, cookie_id)
|
||||
return StatusResp(ok=True, msg="")
|
||||
|
||||
@@ -6,22 +6,14 @@ class PlatformConfig(BaseModel):
|
||||
categories: dict[int, str]
|
||||
enabledTag: bool
|
||||
platformName: str
|
||||
site_name: str
|
||||
hasTarget: bool
|
||||
|
||||
|
||||
class SiteConfig(BaseModel):
|
||||
name: str
|
||||
enable_cookie: bool
|
||||
|
||||
|
||||
AllPlatformConf = dict[str, PlatformConfig]
|
||||
AllSiteConf = dict[str, SiteConfig]
|
||||
|
||||
|
||||
class GlobalConf(BaseModel):
|
||||
platformConf: AllPlatformConf
|
||||
siteConf: AllSiteConf
|
||||
|
||||
|
||||
class TokenResp(BaseModel):
|
||||
@@ -58,32 +50,3 @@ class AddSubscribeReq(BaseModel):
|
||||
class StatusResp(BaseModel):
|
||||
ok: bool
|
||||
msg: str
|
||||
|
||||
|
||||
from typing import Any
|
||||
from datetime import datetime
|
||||
|
||||
from pydantic import BaseModel
|
||||
|
||||
|
||||
class Target(BaseModel):
|
||||
platform_name: str
|
||||
target_name: str
|
||||
target: str
|
||||
|
||||
|
||||
class Cookie(BaseModel):
|
||||
id: int
|
||||
site_name: str
|
||||
friendly_name: str
|
||||
last_usage: datetime
|
||||
status: str
|
||||
cd_milliseconds: int
|
||||
is_universal: bool
|
||||
is_anonymous: bool
|
||||
tags: dict[str, Any]
|
||||
|
||||
|
||||
class CookieTarget(BaseModel):
|
||||
target: Target
|
||||
cookie_id: int
|
||||
|
||||
@@ -12,8 +12,8 @@ from nonebot_plugin_datastore import create_session
|
||||
|
||||
from ..types import Tag
|
||||
from ..types import Target as T_Target
|
||||
from .utils import NoSuchTargetException, DuplicateCookieTargetException
|
||||
from .db_model import User, Cookie, Target, Subscribe, CookieTarget, ScheduleTimeWeight
|
||||
from .utils import NoSuchTargetException
|
||||
from .db_model import User, Target, Subscribe, ScheduleTimeWeight
|
||||
from ..types import Category, UserSubInfo, WeightConfig, TimeWeightConfig, PlatformWeightConfigResp
|
||||
|
||||
|
||||
@@ -259,108 +259,5 @@ class DBConfig:
|
||||
)
|
||||
return res
|
||||
|
||||
async def get_cookie(
|
||||
self,
|
||||
site_name: str | None = None,
|
||||
target: T_Target | None = None,
|
||||
is_universal: bool | None = None,
|
||||
is_anonymous: bool | None = None,
|
||||
) -> Sequence[Cookie]:
|
||||
"""获取满足传入条件的所有 cookie"""
|
||||
async with create_session() as sess:
|
||||
query = select(Cookie).distinct()
|
||||
if is_universal is not None:
|
||||
query = query.where(Cookie.is_universal == is_universal)
|
||||
if is_anonymous is not None:
|
||||
query = query.where(Cookie.is_anonymous == is_anonymous)
|
||||
if site_name:
|
||||
query = query.where(Cookie.site_name == site_name)
|
||||
query = query.outerjoin(CookieTarget).options(selectinload(Cookie.targets))
|
||||
res = (await sess.scalars(query)).all()
|
||||
if target:
|
||||
# 如果指定了 target,过滤掉不满足要求的cookie
|
||||
query = select(CookieTarget.cookie_id).join(Target).where(Target.target == target)
|
||||
ids = set((await sess.scalars(query)).all())
|
||||
# 如果指定了 target 且未指定 is_universal,则添加返回 universal cookie
|
||||
res = [cookie for cookie in res if cookie.id in ids or cookie.is_universal]
|
||||
return res
|
||||
|
||||
async def add_cookie(self, cookie: Cookie) -> int:
|
||||
async with create_session() as sess:
|
||||
sess.add(cookie)
|
||||
await sess.commit()
|
||||
await sess.refresh(cookie)
|
||||
return cookie.id
|
||||
|
||||
async def update_cookie(self, cookie: Cookie):
|
||||
async with create_session() as sess:
|
||||
cookie_in_db: Cookie | None = await sess.scalar(select(Cookie).where(Cookie.id == cookie.id))
|
||||
if not cookie_in_db:
|
||||
raise ValueError(f"cookie {cookie.id} not found")
|
||||
cookie_in_db.content = cookie.content
|
||||
cookie_in_db.last_usage = cookie.last_usage
|
||||
cookie_in_db.status = cookie.status
|
||||
cookie_in_db.tags = cookie.tags
|
||||
await sess.commit()
|
||||
|
||||
async def delete_cookie_by_id(self, cookie_id: int):
|
||||
async with create_session() as sess:
|
||||
cookie = await sess.scalar(
|
||||
select(Cookie)
|
||||
.where(Cookie.id == cookie_id)
|
||||
.outerjoin(CookieTarget)
|
||||
.options(selectinload(Cookie.targets))
|
||||
)
|
||||
if len(cookie.targets) > 0:
|
||||
raise Exception(f"cookie {cookie.id} in use")
|
||||
await sess.execute(delete(Cookie).where(Cookie.id == cookie_id))
|
||||
await sess.commit()
|
||||
|
||||
async def add_cookie_target(self, target: T_Target, platform_name: str, cookie_id: int):
|
||||
"""通过 cookie_id 可以唯一确定一个 Cookie,通过 target 和 platform_name 可以唯一确定一个 Target"""
|
||||
async with create_session() as sess:
|
||||
target_obj = await sess.scalar(
|
||||
select(Target).where(Target.platform_name == platform_name, Target.target == target)
|
||||
)
|
||||
# check if relation exists
|
||||
cookie_target = await sess.scalar(
|
||||
select(CookieTarget).where(CookieTarget.target == target_obj, CookieTarget.cookie_id == cookie_id)
|
||||
)
|
||||
if cookie_target:
|
||||
raise DuplicateCookieTargetException()
|
||||
cookie_obj = await sess.scalar(select(Cookie).where(Cookie.id == cookie_id))
|
||||
cookie_target = CookieTarget(target=target_obj, cookie=cookie_obj)
|
||||
sess.add(cookie_target)
|
||||
await sess.commit()
|
||||
|
||||
async def delete_cookie_target(self, target: T_Target, platform_name: str, cookie_id: int):
|
||||
async with create_session() as sess:
|
||||
target_obj = await sess.scalar(
|
||||
select(Target).where(Target.platform_name == platform_name, Target.target == target)
|
||||
)
|
||||
cookie_obj = await sess.scalar(select(Cookie).where(Cookie.id == cookie_id))
|
||||
await sess.execute(
|
||||
delete(CookieTarget).where(CookieTarget.target == target_obj, CookieTarget.cookie == cookie_obj)
|
||||
)
|
||||
await sess.commit()
|
||||
|
||||
async def delete_cookie_target_by_id(self, cookie_target_id: int):
|
||||
async with create_session() as sess:
|
||||
await sess.execute(delete(CookieTarget).where(CookieTarget.id == cookie_target_id))
|
||||
await sess.commit()
|
||||
|
||||
async def get_cookie_target(self) -> list[CookieTarget]:
|
||||
async with create_session() as sess:
|
||||
query = (
|
||||
select(CookieTarget)
|
||||
.outerjoin(Target)
|
||||
.options(selectinload(CookieTarget.target))
|
||||
.outerjoin(Cookie)
|
||||
.options(selectinload(CookieTarget.cookie))
|
||||
)
|
||||
res = list((await sess.scalars(query)).all())
|
||||
res.sort(key=lambda x: (x.target.platform_name, x.cookie_id, x.target_id))
|
||||
return res
|
||||
|
||||
|
||||
config = DBConfig()
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import datetime
|
||||
from typing import Any
|
||||
from pathlib import Path
|
||||
|
||||
from nonebot_plugin_saa import PlatformTarget
|
||||
@@ -7,7 +6,7 @@ from sqlalchemy.dialects.postgresql import JSONB
|
||||
from nonebot.compat import PYDANTIC_V2, ConfigDict
|
||||
from nonebot_plugin_datastore import get_plugin_data
|
||||
from sqlalchemy.orm import Mapped, relationship, mapped_column
|
||||
from sqlalchemy import JSON, String, DateTime, ForeignKey, UniqueConstraint
|
||||
from sqlalchemy import JSON, String, ForeignKey, UniqueConstraint
|
||||
|
||||
from ..types import Tag, Category
|
||||
|
||||
@@ -37,7 +36,6 @@ class Target(Model):
|
||||
|
||||
subscribes: Mapped[list["Subscribe"]] = relationship(back_populates="target")
|
||||
time_weight: Mapped[list["ScheduleTimeWeight"]] = relationship(back_populates="target")
|
||||
cookies: Mapped[list["CookieTarget"]] = relationship(back_populates="target")
|
||||
|
||||
|
||||
class ScheduleTimeWeight(Model):
|
||||
@@ -68,40 +66,3 @@ class Subscribe(Model):
|
||||
|
||||
target: Mapped[Target] = relationship(back_populates="subscribes")
|
||||
user: Mapped[User] = relationship(back_populates="subscribes")
|
||||
|
||||
|
||||
class Cookie(Model):
|
||||
id: Mapped[int] = mapped_column(primary_key=True)
|
||||
site_name: Mapped[str] = mapped_column(String(100))
|
||||
content: Mapped[str] = mapped_column(String(1024))
|
||||
# 最后使用的时刻
|
||||
last_usage: Mapped[datetime.datetime] = mapped_column(DateTime, default=datetime.datetime(1970, 1, 1))
|
||||
# Cookie 当前的状态
|
||||
status: Mapped[str] = mapped_column(String(20), default="")
|
||||
# 使用一次之后,需要的冷却时间
|
||||
cd_milliseconds: Mapped[int] = mapped_column(default=0)
|
||||
# 是否是通用 Cookie(对所有Target都有效)
|
||||
is_universal: Mapped[bool] = mapped_column(default=False)
|
||||
# 是否是匿名 Cookie
|
||||
is_anonymous: Mapped[bool] = mapped_column(default=False)
|
||||
# 标签,扩展用
|
||||
tags: Mapped[dict[str, Any]] = mapped_column(JSON().with_variant(JSONB, "postgresql"), default={})
|
||||
|
||||
targets: Mapped[list["CookieTarget"]] = relationship(back_populates="cookie")
|
||||
|
||||
@property
|
||||
def cd(self) -> datetime.timedelta:
|
||||
return datetime.timedelta(milliseconds=self.cd_milliseconds)
|
||||
|
||||
@cd.setter
|
||||
def cd(self, value: datetime.timedelta):
|
||||
self.cd_milliseconds = int(value.total_seconds() * 1000)
|
||||
|
||||
|
||||
class CookieTarget(Model):
|
||||
id: Mapped[int] = mapped_column(primary_key=True)
|
||||
target_id: Mapped[int] = mapped_column(ForeignKey("nonebot_bison_target.id", ondelete="CASCADE"))
|
||||
cookie_id: Mapped[int] = mapped_column(ForeignKey("nonebot_bison_cookie.id", ondelete="CASCADE"))
|
||||
|
||||
target: Mapped[Target] = relationship(back_populates="cookies")
|
||||
cookie: Mapped[Cookie] = relationship(back_populates="targets")
|
||||
|
||||
@@ -1,62 +0,0 @@
|
||||
"""empty message
|
||||
|
||||
Revision ID: ef796b74b0fe
|
||||
Revises: f9baef347cc8
|
||||
Create Date: 2024-09-13 00:34:08.601438
|
||||
|
||||
"""
|
||||
|
||||
import sqlalchemy as sa
|
||||
from alembic import op
|
||||
from sqlalchemy import Text
|
||||
from sqlalchemy.dialects import postgresql
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision = "ef796b74b0fe"
|
||||
down_revision = "f9baef347cc8"
|
||||
branch_labels = None
|
||||
depends_on = None
|
||||
|
||||
|
||||
def upgrade() -> None:
|
||||
# ### commands auto generated by Alembic - please adjust! ###
|
||||
op.create_table(
|
||||
"nonebot_bison_cookie",
|
||||
sa.Column("id", sa.Integer(), nullable=False),
|
||||
sa.Column("site_name", sa.String(length=100), nullable=False),
|
||||
sa.Column("content", sa.String(length=1024), nullable=False),
|
||||
sa.Column("last_usage", sa.DateTime(), nullable=False),
|
||||
sa.Column("status", sa.String(length=20), nullable=False),
|
||||
sa.Column("cd_milliseconds", sa.Integer(), nullable=False),
|
||||
sa.Column("is_universal", sa.Boolean(), nullable=False),
|
||||
sa.Column("is_anonymous", sa.Boolean(), nullable=False),
|
||||
sa.Column("tags", sa.JSON().with_variant(postgresql.JSONB(astext_type=Text()), "postgresql"), nullable=False),
|
||||
sa.PrimaryKeyConstraint("id", name=op.f("pk_nonebot_bison_cookie")),
|
||||
)
|
||||
op.create_table(
|
||||
"nonebot_bison_cookietarget",
|
||||
sa.Column("id", sa.Integer(), nullable=False),
|
||||
sa.Column("target_id", sa.Integer(), nullable=False),
|
||||
sa.Column("cookie_id", sa.Integer(), nullable=False),
|
||||
sa.ForeignKeyConstraint(
|
||||
["cookie_id"],
|
||||
["nonebot_bison_cookie.id"],
|
||||
name=op.f("fk_nonebot_bison_cookietarget_cookie_id_nonebot_bison_cookie"),
|
||||
ondelete="CASCADE",
|
||||
),
|
||||
sa.ForeignKeyConstraint(
|
||||
["target_id"],
|
||||
["nonebot_bison_target.id"],
|
||||
name=op.f("fk_nonebot_bison_cookietarget_target_id_nonebot_bison_target"),
|
||||
ondelete="CASCADE",
|
||||
),
|
||||
sa.PrimaryKeyConstraint("id", name=op.f("pk_nonebot_bison_cookietarget")),
|
||||
)
|
||||
# ### end Alembic commands ###
|
||||
|
||||
|
||||
def downgrade() -> None:
|
||||
# ### commands auto generated by Alembic - please adjust! ###
|
||||
op.drop_table("nonebot_bison_cookietarget")
|
||||
op.drop_table("nonebot_bison_cookie")
|
||||
# ### end Alembic commands ###
|
||||
@@ -8,7 +8,3 @@ class NoSuchSubscribeException(Exception):
|
||||
|
||||
class NoSuchTargetException(Exception):
|
||||
pass
|
||||
|
||||
|
||||
class DuplicateCookieTargetException(Exception):
|
||||
pass
|
||||
|
||||
@@ -3,7 +3,6 @@ from pkgutil import iter_modules
|
||||
from collections import defaultdict
|
||||
from importlib import import_module
|
||||
|
||||
from ..utils import Site
|
||||
from ..plugin_config import plugin_config
|
||||
from .platform import Platform, make_no_target_group
|
||||
|
||||
@@ -36,10 +35,3 @@ def _get_unavailable_platforms() -> dict[str, str]:
|
||||
|
||||
# platform => reason for not available
|
||||
unavailable_paltforms: dict[str, str] = _get_unavailable_platforms()
|
||||
|
||||
|
||||
site_manager: dict[str, type[Site]] = {}
|
||||
for site in Site.registry:
|
||||
if not hasattr(site, "name"):
|
||||
continue
|
||||
site_manager[site.name] = site
|
||||
|
||||
@@ -16,7 +16,7 @@ from nonebot_plugin_saa import PlatformTarget
|
||||
from ..post import Post
|
||||
from ..utils import Site, ProcessContext
|
||||
from ..plugin_config import plugin_config
|
||||
from ..types import Tag, Target, RawPost, SubUnit, Category, RegistryMeta
|
||||
from ..types import Tag, Target, RawPost, SubUnit, Category
|
||||
|
||||
|
||||
class CategoryNotSupport(Exception):
|
||||
@@ -29,6 +29,21 @@ class CategoryNotRecognize(Exception):
|
||||
"""raise in get_category, when you don't know the category of post"""
|
||||
|
||||
|
||||
class RegistryMeta(type):
|
||||
def __new__(cls, name, bases, namespace, **kwargs):
|
||||
return super().__new__(cls, name, bases, namespace)
|
||||
|
||||
def __init__(cls, name, bases, namespace, **kwargs):
|
||||
if kwargs.get("base"):
|
||||
# this is the base class
|
||||
cls.registry = []
|
||||
elif not kwargs.get("abstract"):
|
||||
# this is the subclass
|
||||
cls.registry.append(cls)
|
||||
|
||||
super().__init__(name, bases, namespace, **kwargs)
|
||||
|
||||
|
||||
P = ParamSpec("P")
|
||||
R = TypeVar("R")
|
||||
|
||||
|
||||
@@ -10,14 +10,12 @@ from ..post import Post
|
||||
from .platform import NewMessage
|
||||
from ..types import Target, RawPost
|
||||
from ..utils import Site, text_similarity
|
||||
from ..utils.site import create_cookie_client_manager
|
||||
|
||||
|
||||
class RssSite(Site):
|
||||
name = "rss"
|
||||
schedule_type = "interval"
|
||||
schedule_setting = {"seconds": 30}
|
||||
client_mgr = create_cookie_client_manager("rss")
|
||||
|
||||
|
||||
class RssPost(Post):
|
||||
@@ -65,7 +63,7 @@ class Rss(NewMessage):
|
||||
return post.id
|
||||
|
||||
async def get_sub_list(self, target: Target) -> list[RawPost]:
|
||||
client = await self.ctx.get_client(target)
|
||||
client = await self.ctx.get_client()
|
||||
res = await client.get(target, timeout=10.0)
|
||||
feed = feedparser.parse(res)
|
||||
entries = feed.entries
|
||||
|
||||
@@ -13,7 +13,6 @@ from bs4 import BeautifulSoup as bs
|
||||
from ..post import Post
|
||||
from .platform import NewMessage
|
||||
from ..utils import Site, http_client
|
||||
from ..utils.site import create_cookie_client_manager
|
||||
from ..types import Tag, Target, RawPost, ApiError, Category
|
||||
|
||||
_HEADER = {
|
||||
@@ -40,7 +39,6 @@ class WeiboSite(Site):
|
||||
name = "weibo.com"
|
||||
schedule_type = "interval"
|
||||
schedule_setting = {"seconds": 3}
|
||||
client_mgr = create_cookie_client_manager(name)
|
||||
|
||||
|
||||
class Weibo(NewMessage):
|
||||
@@ -80,11 +78,9 @@ class Weibo(NewMessage):
|
||||
raise cls.ParseTargetException(prompt="正确格式:\n1. 用户数字UID\n2. https://weibo.com/u/xxxx")
|
||||
|
||||
async def get_sub_list(self, target: Target) -> list[RawPost]:
|
||||
client = await self.ctx.get_client(target)
|
||||
header = {"Referer": f"https://m.weibo.cn/u/{target}", "MWeibo-Pwa": "1", "X-Requested-With": "XMLHttpRequest"}
|
||||
# 获取 cookie 见 https://docs.rsshub.app/zh/deploy/config#%E5%BE%AE%E5%8D%9A
|
||||
client = await self.ctx.get_client()
|
||||
params = {"containerid": "107603" + target}
|
||||
res = await client.get("https://m.weibo.cn/api/container/getIndex?", headers=header, params=params, timeout=4.0)
|
||||
res = await client.get("https://m.weibo.cn/api/container/getIndex?", params=params, timeout=4.0)
|
||||
res_data = json.loads(res.text)
|
||||
if not res_data["ok"] and res_data["msg"] != "这里还没有内容":
|
||||
raise ApiError(res.request.url)
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
from typing import cast
|
||||
|
||||
from nonebot.log import logger
|
||||
|
||||
from ..utils import Site
|
||||
@@ -9,7 +7,6 @@ from ..config.db_model import Target
|
||||
from ..types import Target as T_Target
|
||||
from ..platform import platform_manager
|
||||
from ..plugin_config import plugin_config
|
||||
from ..utils.site import CookieClientManager, is_cookie_client_manager
|
||||
|
||||
scheduler_dict: dict[type[Site], Scheduler] = {}
|
||||
|
||||
@@ -33,9 +30,6 @@ async def init_scheduler():
|
||||
else:
|
||||
_schedule_class_platform_dict[site].append(platform_name)
|
||||
for site, target_list in _schedule_class_dict.items():
|
||||
if is_cookie_client_manager(site.client_mgr):
|
||||
client_mgr = cast(CookieClientManager, site.client_mgr)
|
||||
await client_mgr.refresh_anonymous_cookie()
|
||||
if not plugin_config.bison_use_browser and site.require_browser:
|
||||
logger.warning(f"{site.name} requires browser, it will not schedule.")
|
||||
continue
|
||||
|
||||
@@ -12,7 +12,6 @@ from ..send import send_msgs
|
||||
from ..types import Target, SubUnit
|
||||
from ..platform import platform_manager
|
||||
from ..utils import Site, ProcessContext
|
||||
from ..utils.site import SkipRequestException
|
||||
|
||||
|
||||
@dataclass
|
||||
@@ -108,8 +107,6 @@ class Scheduler:
|
||||
schedulable.platform_name, schedulable.target
|
||||
)
|
||||
to_send = await platform_obj.do_fetch_new_post(SubUnit(schedulable.target, send_userinfo_list))
|
||||
except SkipRequestException as err:
|
||||
logger.debug(f"skip request: {err}")
|
||||
except Exception as err:
|
||||
records = context.gen_req_records()
|
||||
for record in records:
|
||||
|
||||
@@ -14,10 +14,6 @@ from nonebot.adapters.onebot.v11.event import PrivateMessageEvent
|
||||
from .add_sub import do_add_sub
|
||||
from .del_sub import do_del_sub
|
||||
from .query_sub import do_query_sub
|
||||
from .add_cookie import do_add_cookie
|
||||
from .del_cookie import do_del_cookie
|
||||
from .add_cookie_target import do_add_cookie_target
|
||||
from .del_cookie_target import do_del_cookie_target
|
||||
from .utils import common_platform, admin_permission, gen_handle_cancel, configurable_to_me, set_target_user_info
|
||||
|
||||
add_sub_matcher = on_command(
|
||||
@@ -30,10 +26,12 @@ add_sub_matcher = on_command(
|
||||
add_sub_matcher.handle()(set_target_user_info)
|
||||
do_add_sub(add_sub_matcher)
|
||||
|
||||
|
||||
query_sub_matcher = on_command("查询订阅", rule=configurable_to_me, priority=5, block=True)
|
||||
query_sub_matcher.handle()(set_target_user_info)
|
||||
do_query_sub(query_sub_matcher)
|
||||
|
||||
|
||||
del_sub_matcher = on_command(
|
||||
"删除订阅",
|
||||
rule=configurable_to_me,
|
||||
@@ -44,46 +42,6 @@ del_sub_matcher = on_command(
|
||||
del_sub_matcher.handle()(set_target_user_info)
|
||||
do_del_sub(del_sub_matcher)
|
||||
|
||||
add_cookie_matcher = on_command(
|
||||
"添加cookie",
|
||||
aliases={"添加Cookie"},
|
||||
rule=to_me(),
|
||||
permission=SUPERUSER,
|
||||
priority=5,
|
||||
block=True,
|
||||
)
|
||||
do_add_cookie(add_cookie_matcher)
|
||||
|
||||
add_cookie_target_matcher = on_command(
|
||||
"关联cookie",
|
||||
aliases={"关联Cookie"},
|
||||
rule=to_me(),
|
||||
permission=SUPERUSER,
|
||||
priority=5,
|
||||
block=True,
|
||||
)
|
||||
do_add_cookie_target(add_cookie_target_matcher)
|
||||
|
||||
del_cookie_target_matcher = on_command(
|
||||
"取消关联cookie",
|
||||
aliases={"取消关联Cookie"},
|
||||
rule=to_me(),
|
||||
permission=SUPERUSER,
|
||||
priority=5,
|
||||
block=True,
|
||||
)
|
||||
do_del_cookie_target(del_cookie_target_matcher)
|
||||
|
||||
del_cookie_matcher = on_command(
|
||||
"删除cookie",
|
||||
aliases={"删除Cookie"},
|
||||
rule=to_me(),
|
||||
permission=SUPERUSER,
|
||||
priority=5,
|
||||
block=True,
|
||||
)
|
||||
do_del_cookie(del_cookie_matcher)
|
||||
|
||||
group_manage_matcher = on_command("群管理", rule=to_me(), permission=SUPERUSER, priority=4, block=True)
|
||||
|
||||
group_handle_cancel = gen_handle_cancel(group_manage_matcher, "已取消")
|
||||
@@ -167,8 +125,4 @@ __all__ = [
|
||||
"del_sub_matcher",
|
||||
"group_manage_matcher",
|
||||
"no_permission_matcher",
|
||||
"add_cookie_matcher",
|
||||
"add_cookie_target_matcher",
|
||||
"del_cookie_target_matcher",
|
||||
"del_cookie_matcher",
|
||||
]
|
||||
|
||||
@@ -1,69 +0,0 @@
|
||||
from typing import cast
|
||||
|
||||
from nonebot.typing import T_State
|
||||
from nonebot.matcher import Matcher
|
||||
from nonebot.params import Arg, ArgPlainText
|
||||
from nonebot.adapters import Message, MessageTemplate
|
||||
|
||||
from ..platform import platform_manager
|
||||
from .utils import common_platform, gen_handle_cancel
|
||||
from ..utils.site import CookieClientManager, is_cookie_client_manager
|
||||
|
||||
|
||||
def do_add_cookie(add_cookie: type[Matcher]):
|
||||
handle_cancel = gen_handle_cancel(add_cookie, "已中止添加cookie")
|
||||
|
||||
@add_cookie.handle()
|
||||
async def init_promote(state: T_State):
|
||||
state["_prompt"] = (
|
||||
"请输入想要添加 Cookie 的平台,目前支持,请输入冒号左边的名称:\n"
|
||||
+ "".join(
|
||||
[
|
||||
f"{platform_name}: {platform_manager[platform_name].name}\n"
|
||||
for platform_name in common_platform
|
||||
if is_cookie_client_manager(platform_manager[platform_name].site.client_mgr)
|
||||
]
|
||||
)
|
||||
+ "要查看全部平台请输入:“全部”\n中止添加cookie过程请输入:“取消”"
|
||||
)
|
||||
|
||||
@add_cookie.got("platform", MessageTemplate("{_prompt}"), [handle_cancel])
|
||||
async def parse_platform(state: T_State, platform: str = ArgPlainText()) -> None:
|
||||
if platform == "全部":
|
||||
message = "全部平台\n" + "\n".join(
|
||||
[
|
||||
f"{platform_name}: {platform.name}"
|
||||
for platform_name, platform in platform_manager.items()
|
||||
if is_cookie_client_manager(platform_manager[platform_name].site.client_mgr)
|
||||
]
|
||||
)
|
||||
await add_cookie.reject(message)
|
||||
elif platform == "取消":
|
||||
await add_cookie.finish("已中止添加cookie")
|
||||
elif platform in platform_manager:
|
||||
state["platform"] = platform
|
||||
state["site"] = platform_manager[platform].site
|
||||
else:
|
||||
await add_cookie.reject("平台输入错误")
|
||||
|
||||
@add_cookie.handle()
|
||||
async def prepare_get_id(state: T_State):
|
||||
state["_prompt"] = "请输入 Cookie"
|
||||
|
||||
@add_cookie.got("cookie", MessageTemplate("{_prompt}"), [handle_cancel])
|
||||
async def got_cookie(state: T_State, cookie: Message = Arg()):
|
||||
client_mgr: type[CookieClientManager] = cast(
|
||||
type[CookieClientManager], platform_manager[state["platform"]].site.client_mgr
|
||||
)
|
||||
cookie_text = cookie.extract_plain_text()
|
||||
if not await client_mgr.validate_cookie(cookie_text):
|
||||
await add_cookie.reject(state["site"].cookie_format_prompt)
|
||||
state["cookie"] = cookie_text
|
||||
|
||||
@add_cookie.handle()
|
||||
async def add_cookie_process(state: T_State):
|
||||
client_mgr = cast(CookieClientManager, platform_manager[state["platform"]].site.client_mgr)
|
||||
await client_mgr.add_user_cookie(state["cookie"])
|
||||
await add_cookie.finish(
|
||||
f"已添加 Cookie: {state['cookie']} 到平台 {state['platform']}" + "\n请使用“关联cookie”为 Cookie 关联订阅"
|
||||
)
|
||||
@@ -1,75 +0,0 @@
|
||||
from typing import cast
|
||||
|
||||
from nonebot.typing import T_State
|
||||
from nonebot.matcher import Matcher
|
||||
from nonebot.params import ArgPlainText
|
||||
from nonebot_plugin_saa import MessageFactory
|
||||
from nonebot.internal.adapter import MessageTemplate
|
||||
|
||||
from ..config import config
|
||||
from ..utils import parse_text
|
||||
from ..platform import platform_manager
|
||||
from ..utils.site import CookieClientManager
|
||||
from .utils import gen_handle_cancel, generate_sub_list_text
|
||||
|
||||
|
||||
def do_add_cookie_target(add_cookie_target_matcher: type[Matcher]):
|
||||
handle_cancel = gen_handle_cancel(add_cookie_target_matcher, "已中止关联 cookie")
|
||||
|
||||
@add_cookie_target_matcher.handle()
|
||||
async def init_promote(state: T_State):
|
||||
res = await generate_sub_list_text(
|
||||
add_cookie_target_matcher, state, is_index=True, is_show_cookie=True, is_hide_no_cookie_platfrom=True
|
||||
)
|
||||
res += "请输入要关联 cookie 的订阅的序号\n输入'取消'中止"
|
||||
await MessageFactory(await parse_text(res)).send()
|
||||
|
||||
@add_cookie_target_matcher.got("target_idx", parameterless=[handle_cancel])
|
||||
async def got_target_idx(state: T_State, target_idx: str = ArgPlainText()):
|
||||
try:
|
||||
target_idx = int(target_idx)
|
||||
state["target"] = state["sub_table"][target_idx]
|
||||
state["site"] = platform_manager[state["target"]["platform_name"]].site
|
||||
except Exception:
|
||||
await add_cookie_target_matcher.reject("序号错误")
|
||||
|
||||
@add_cookie_target_matcher.handle()
|
||||
async def init_promote_cookie(state: T_State):
|
||||
|
||||
# 获取 site 的所有用户 cookie,再排除掉已经关联的 cookie,剩下的就是可以关联的 cookie
|
||||
cookies = await config.get_cookie(site_name=state["site"].name, is_anonymous=False)
|
||||
associated_cookies = await config.get_cookie(
|
||||
target=state["target"]["target"],
|
||||
site_name=state["site"].name,
|
||||
is_anonymous=False,
|
||||
)
|
||||
associated_cookie_ids = {cookie.id for cookie in associated_cookies}
|
||||
cookies = [cookie for cookie in cookies if cookie.id not in associated_cookie_ids]
|
||||
if not cookies:
|
||||
await add_cookie_target_matcher.finish(
|
||||
"当前平台暂无可关联的 Cookie,请使用“添加cookie”命令添加或检查已关联的 Cookie"
|
||||
)
|
||||
state["cookies"] = cookies
|
||||
|
||||
client_mgr = cast(CookieClientManager, state["site"].client_mgr)
|
||||
state["_prompt"] = "请选择一个 Cookie,已关联的 Cookie 不会显示\n" + "\n".join(
|
||||
[f"{idx}. {await client_mgr.get_cookie_friendly_name(cookie)}" for idx, cookie in enumerate(cookies, 1)]
|
||||
)
|
||||
|
||||
@add_cookie_target_matcher.got("cookie_idx", MessageTemplate("{_prompt}"), [handle_cancel])
|
||||
async def got_cookie_idx(state: T_State, cookie_idx: str = ArgPlainText()):
|
||||
try:
|
||||
cookie_idx = int(cookie_idx)
|
||||
state["cookie"] = state["cookies"][cookie_idx - 1]
|
||||
except Exception:
|
||||
await add_cookie_target_matcher.reject("序号错误")
|
||||
|
||||
@add_cookie_target_matcher.handle()
|
||||
async def add_cookie_target_process(state: T_State):
|
||||
await config.add_cookie_target(state["target"]["target"], state["target"]["platform_name"], state["cookie"].id)
|
||||
cookie = state["cookie"]
|
||||
client_mgr = cast(CookieClientManager, state["site"].client_mgr)
|
||||
await add_cookie_target_matcher.finish(
|
||||
f"已关联 Cookie: {await client_mgr.get_cookie_friendly_name(cookie)} "
|
||||
f"到订阅 {state['site'].name} {state['target']['target']}"
|
||||
)
|
||||
@@ -1,48 +0,0 @@
|
||||
from nonebot.typing import T_State
|
||||
from nonebot.matcher import Matcher
|
||||
from nonebot.params import EventPlainText
|
||||
from nonebot_plugin_saa import MessageFactory
|
||||
|
||||
from ..config import config
|
||||
from ..utils import parse_text
|
||||
from ..platform import site_manager
|
||||
from .utils import gen_handle_cancel
|
||||
|
||||
|
||||
def do_del_cookie(del_cookie: type[Matcher]):
|
||||
handle_cancel = gen_handle_cancel(del_cookie, "删除中止")
|
||||
|
||||
@del_cookie.handle()
|
||||
async def send_list(state: T_State):
|
||||
cookies = await config.get_cookie(is_anonymous=False)
|
||||
if not cookies:
|
||||
await del_cookie.finish("暂无已添加的 Cookie\n请使用“添加cookie”命令添加")
|
||||
res = "已添加的 Cookie 为:\n"
|
||||
state["cookie_table"] = {}
|
||||
for index, cookie in enumerate(cookies, 1):
|
||||
state["cookie_table"][index] = cookie
|
||||
client_mgr = site_manager[cookie.site_name].client_mgr
|
||||
friendly_name = await client_mgr.get_cookie_friendly_name(cookie)
|
||||
res += f"{index} {cookie.site_name} {friendly_name} {len(cookie.targets)}个关联\n"
|
||||
if res[-1] != "\n":
|
||||
res += "\n"
|
||||
res += "请输入要删除的 Cookie 的序号\n输入'取消'中止"
|
||||
await MessageFactory(await parse_text(res)).send()
|
||||
|
||||
@del_cookie.receive(parameterless=[handle_cancel])
|
||||
async def do_del(
|
||||
state: T_State,
|
||||
index_str: str = EventPlainText(),
|
||||
):
|
||||
try:
|
||||
index = int(index_str)
|
||||
cookie = state["cookie_table"][index]
|
||||
if cookie.targets:
|
||||
await del_cookie.reject("只能删除未关联的 Cookie,请使用“取消关联cookie”命令取消关联")
|
||||
await config.delete_cookie_by_id(cookie.id)
|
||||
except KeyError:
|
||||
await del_cookie.reject("序号错误")
|
||||
except Exception:
|
||||
await del_cookie.reject("删除错误")
|
||||
else:
|
||||
await del_cookie.finish("删除成功")
|
||||
@@ -1,51 +0,0 @@
|
||||
from typing import cast
|
||||
|
||||
from nonebot.typing import T_State
|
||||
from nonebot.matcher import Matcher
|
||||
from nonebot.params import EventPlainText
|
||||
from nonebot_plugin_saa import MessageFactory
|
||||
|
||||
from ..config import config
|
||||
from ..utils import parse_text
|
||||
from .utils import gen_handle_cancel
|
||||
from ..platform import platform_manager
|
||||
from ..utils.site import CookieClientManager
|
||||
|
||||
|
||||
def do_del_cookie_target(del_cookie_target: type[Matcher]):
|
||||
handle_cancel = gen_handle_cancel(del_cookie_target, "取消关联中止")
|
||||
|
||||
@del_cookie_target.handle()
|
||||
async def send_list(state: T_State):
|
||||
cookie_targets = await config.get_cookie_target()
|
||||
if not cookie_targets:
|
||||
await del_cookie_target.finish("暂无已关联 Cookie\n请使用“添加cookie”命令添加关联")
|
||||
res = "已关联的 Cookie 为:\n"
|
||||
state["cookie_target_table"] = {}
|
||||
for index, cookie_target in enumerate(cookie_targets, 1):
|
||||
client_mgr = cast(CookieClientManager, platform_manager[cookie_target.target.platform_name].site.client_mgr)
|
||||
friendly_name = await client_mgr.get_cookie_friendly_name(cookie_target.cookie)
|
||||
state["cookie_target_table"][index] = {
|
||||
"platform_name": cookie_target.target.platform_name,
|
||||
"target": cookie_target.target,
|
||||
"friendly_name": friendly_name,
|
||||
"cookie_target": cookie_target,
|
||||
}
|
||||
res += f"{index} {cookie_target.target.platform_name} {cookie_target.target.target_name} {friendly_name}\n"
|
||||
if res[-1] != "\n":
|
||||
res += "\n"
|
||||
res += "请输入要删除的关联的序号\n输入'取消'中止"
|
||||
await MessageFactory(await parse_text(res)).send()
|
||||
|
||||
@del_cookie_target.receive(parameterless=[handle_cancel])
|
||||
async def do_del(
|
||||
state: T_State,
|
||||
index_str: str = EventPlainText(),
|
||||
):
|
||||
try:
|
||||
index = int(index_str)
|
||||
await config.delete_cookie_target_by_id(state["cookie_target_table"][index]["cookie_target"].id)
|
||||
except Exception:
|
||||
await del_cookie_target.reject("删除错误")
|
||||
else:
|
||||
await del_cookie_target.finish("删除成功")
|
||||
@@ -1,21 +1,16 @@
|
||||
import contextlib
|
||||
from itertools import groupby
|
||||
from operator import attrgetter
|
||||
from typing import Annotated, cast
|
||||
from typing import Annotated
|
||||
|
||||
from nonebot.rule import Rule
|
||||
from nonebot.adapters import Event
|
||||
from nonebot.typing import T_State
|
||||
from nonebot.matcher import Matcher
|
||||
from nonebot.permission import SUPERUSER
|
||||
from nonebot_plugin_saa import extract_target
|
||||
from nonebot.params import Depends, EventToMe, EventPlainText
|
||||
from nonebot_plugin_saa import PlatformTarget, extract_target
|
||||
|
||||
from ..config import config
|
||||
from ..types import Category
|
||||
from ..platform import platform_manager
|
||||
from ..plugin_config import plugin_config
|
||||
from ..platform import site_manager, platform_manager
|
||||
from ..utils.site import CookieClientManager, is_cookie_client_manager
|
||||
|
||||
|
||||
def _configurable_to_me(to_me: bool = EventToMe()):
|
||||
@@ -65,59 +60,3 @@ def admin_permission():
|
||||
permission = permission | GROUP_ADMIN | GROUP_OWNER
|
||||
|
||||
return permission
|
||||
|
||||
|
||||
async def generate_sub_list_text(
|
||||
matcher: type[Matcher],
|
||||
state: T_State,
|
||||
user_info: PlatformTarget = None,
|
||||
is_index=False,
|
||||
is_show_cookie=False,
|
||||
is_hide_no_cookie_platfrom=False,
|
||||
):
|
||||
"""根据配置参数,生产订阅列表文本,同时将订阅信息存入state["sub_table"]"""
|
||||
if user_info:
|
||||
sub_list = await config.list_subscribe(user_info)
|
||||
else:
|
||||
sub_list = await config.list_subs_with_all_info()
|
||||
sub_list = [
|
||||
next(group)
|
||||
for key, group in groupby(sorted(sub_list, key=attrgetter("target_id")), key=attrgetter("target_id"))
|
||||
]
|
||||
if is_hide_no_cookie_platfrom:
|
||||
sub_list = [
|
||||
sub
|
||||
for sub in sub_list
|
||||
if is_cookie_client_manager(platform_manager.get(sub.target.platform_name).site.client_mgr)
|
||||
]
|
||||
if not sub_list:
|
||||
await matcher.finish("暂无已订阅账号\n请使用“添加订阅”命令添加订阅")
|
||||
res = "订阅的帐号为:\n"
|
||||
state["sub_table"] = {}
|
||||
for index, sub in enumerate(sub_list, 1):
|
||||
state["sub_table"][index] = {
|
||||
"platform_name": sub.target.platform_name,
|
||||
"target": sub.target.target,
|
||||
}
|
||||
res += f"{index} " if is_index else ""
|
||||
res += f"{sub.target.platform_name} {sub.target.target_name} {sub.target.target}\n"
|
||||
if platform := platform_manager.get(sub.target.platform_name):
|
||||
if platform.categories:
|
||||
res += " [{}]".format(", ".join(platform.categories[Category(x)] for x in sub.categories)) + "\n"
|
||||
if platform.enable_tag:
|
||||
if sub.tags:
|
||||
res += " {}".format(", ".join(sub.tags)) + "\n"
|
||||
if is_show_cookie:
|
||||
target_cookies = await config.get_cookie(
|
||||
target=sub.target.target, site_name=platform.site.name, is_anonymous=False
|
||||
)
|
||||
if target_cookies:
|
||||
res += " 关联的 Cookie:\n"
|
||||
for cookie in target_cookies:
|
||||
client_mgr = cast(CookieClientManager, site_manager[platform.site.name].client_mgr)
|
||||
res += f" \t{await client_mgr.get_cookie_friendly_name(cookie)}\n"
|
||||
|
||||
else:
|
||||
res += f" (平台 {sub.target.platform_name} 已失效,请删除此订阅)"
|
||||
|
||||
return res
|
||||
|
||||
@@ -58,18 +58,3 @@ class ApiError(Exception):
|
||||
class SubUnit(NamedTuple):
|
||||
sub_target: Target
|
||||
user_sub_infos: list[UserSubInfo]
|
||||
|
||||
|
||||
class RegistryMeta(type):
|
||||
def __new__(cls, name, bases, namespace, **kwargs):
|
||||
return super().__new__(cls, name, bases, namespace)
|
||||
|
||||
def __init__(cls, name, bases, namespace, **kwargs):
|
||||
if kwargs.get("base"):
|
||||
# this is the base class
|
||||
cls.registry = []
|
||||
elif not kwargs.get("abstract"):
|
||||
# this is the subclass
|
||||
cls.registry.append(cls)
|
||||
|
||||
super().__init__(name, bases, namespace, **kwargs)
|
||||
|
||||
@@ -1,25 +1,25 @@
|
||||
import difflib
|
||||
import re
|
||||
import sys
|
||||
import difflib
|
||||
|
||||
import nonebot
|
||||
from nonebot.plugin import require
|
||||
from bs4 import BeautifulSoup as bs
|
||||
from nonebot.log import logger, default_format
|
||||
from nonebot.plugin import require
|
||||
from nonebot_plugin_saa import Text, Image, MessageSegmentFactory
|
||||
|
||||
from .context import ProcessContext as ProcessContext
|
||||
from .site import Site as Site
|
||||
from ..plugin_config import plugin_config
|
||||
from .image import pic_merge as pic_merge
|
||||
from .http import http_client as http_client
|
||||
from .image import capture_html as capture_html
|
||||
from .image import is_pics_mergable as is_pics_mergable
|
||||
from .image import pic_merge as pic_merge
|
||||
from .image import pic_url_to_image as pic_url_to_image
|
||||
from .image import text_to_image as text_to_image
|
||||
from .site import ClientManager as ClientManager
|
||||
from .site import DefaultClientManager as DefaultClientManager
|
||||
from .site import Site as Site
|
||||
from .image import text_to_image as text_to_image
|
||||
from .site import anonymous_site as anonymous_site
|
||||
from ..plugin_config import plugin_config
|
||||
from .context import ProcessContext as ProcessContext
|
||||
from .image import is_pics_mergable as is_pics_mergable
|
||||
from .image import pic_url_to_image as pic_url_to_image
|
||||
from .site import DefaultClientManager as DefaultClientManager
|
||||
|
||||
|
||||
class Singleton(type):
|
||||
|
||||
@@ -22,9 +22,8 @@ class ProcessContext:
|
||||
async def _log_to_ctx(r: Response):
|
||||
self._log_response(r)
|
||||
|
||||
existing_hooks = client.event_hooks["response"]
|
||||
hooks = {
|
||||
"response": [*existing_hooks, _log_to_ctx],
|
||||
"response": [_log_to_ctx],
|
||||
}
|
||||
client.event_hooks = hooks
|
||||
|
||||
|
||||
+2
-122
@@ -1,17 +1,10 @@
|
||||
import json
|
||||
from typing import Literal
|
||||
from json import JSONDecodeError
|
||||
from abc import ABC, abstractmethod
|
||||
from datetime import datetime, timedelta
|
||||
|
||||
import httpx
|
||||
from httpx import AsyncClient
|
||||
from nonebot.log import logger
|
||||
|
||||
from ..config import config
|
||||
from ..types import Target
|
||||
from .http import http_client
|
||||
from ..config.db_model import Cookie
|
||||
from ..types import Target, RegistryMeta
|
||||
|
||||
|
||||
class ClientManager(ABC):
|
||||
@@ -42,121 +35,12 @@ class DefaultClientManager(ClientManager):
|
||||
pass
|
||||
|
||||
|
||||
class CookieClientManager(ClientManager):
|
||||
_site_name: str
|
||||
_default_cd: int = timedelta(seconds=10)
|
||||
|
||||
@classmethod
|
||||
async def refresh_anonymous_cookie(cls):
|
||||
"""移除已有的匿名cookie,添加一个新的匿名cookie"""
|
||||
anonymous_cookies = await config.get_cookie(cls._site_name, is_anonymous=True)
|
||||
anonymous_cookie = Cookie(site_name=cls._site_name, content="{}", is_universal=True, is_anonymous=True)
|
||||
for cookie in anonymous_cookies:
|
||||
if not cookie.is_anonymous:
|
||||
continue
|
||||
await config.delete_cookie_by_id(cookie.id)
|
||||
anonymous_cookie.id = cookie.id # 保持原有的id
|
||||
anonymous_cookie.last_usage = datetime.now() # 使得第一次请求优先使用用户 cookie
|
||||
await config.add_cookie(anonymous_cookie)
|
||||
|
||||
@classmethod
|
||||
async def add_user_cookie(cls, content: str):
|
||||
"""添加用户 cookie"""
|
||||
cookie = Cookie(site_name=cls._site_name, content=content)
|
||||
cookie.cd = cls._default_cd
|
||||
await config.add_cookie(cookie)
|
||||
|
||||
@classmethod
|
||||
async def validate_cookie(cls, content: str) -> bool:
|
||||
"""验证 cookie 内容是否有效,添加 cookie 时用,可根据平台的具体情况进行重写"""
|
||||
try:
|
||||
data = json.loads(content)
|
||||
if not isinstance(data, dict):
|
||||
return False
|
||||
except JSONDecodeError:
|
||||
return False
|
||||
return True
|
||||
|
||||
@classmethod
|
||||
async def get_cookie_friendly_name(cls, cookie: Cookie) -> str:
|
||||
"""获取 cookie 的友好名字,用于展示"""
|
||||
from . import text_fletten
|
||||
|
||||
return text_fletten(f"{cookie.site_name} [{cookie.content[:10]}]")
|
||||
|
||||
def _generate_hook(self, cookie: Cookie) -> callable:
|
||||
"""hook 函数生成器,用于回写请求状态到数据库"""
|
||||
|
||||
async def _response_hook(resp: httpx.Response):
|
||||
if resp.status_code == 200:
|
||||
logger.trace(f"请求成功: {cookie.id} {resp.request.url}")
|
||||
cookie.status = "success"
|
||||
else:
|
||||
logger.warning(f"请求失败:{cookie.id} {resp.request.url}, 状态码: {resp.status_code}")
|
||||
cookie.status = "failed"
|
||||
cookie.last_usage = datetime.now()
|
||||
await config.update_cookie(cookie)
|
||||
|
||||
return _response_hook
|
||||
|
||||
async def _choose_cookie(self, target: Target | None) -> Cookie:
|
||||
"""选择 cookie 的具体算法"""
|
||||
cookies = await config.get_cookie(self._site_name, target)
|
||||
cookies = (cookie for cookie in cookies if cookie.last_usage + cookie.cd < datetime.now())
|
||||
cookie = min(cookies, key=lambda x: x.last_usage)
|
||||
return cookie
|
||||
|
||||
async def get_client(self, target: Target | None) -> AsyncClient:
|
||||
"""获取 client,根据 target 选择 cookie"""
|
||||
client = http_client()
|
||||
cookie = await self._choose_cookie(target)
|
||||
if cookie.is_universal:
|
||||
logger.trace(f"平台 {self._site_name} 未获取到用户cookie, 使用匿名cookie")
|
||||
else:
|
||||
logger.trace(f"平台 {self._site_name} 获取到用户cookie: {cookie.id}")
|
||||
|
||||
return await self._assemble_client(client, cookie)
|
||||
|
||||
async def _assemble_client(self, client, cookie) -> AsyncClient:
|
||||
"""组装 client,可以自定义 cookie 对象的 content 装配到 client 中的方式"""
|
||||
cookies = httpx.Cookies()
|
||||
if cookie:
|
||||
cookies.update(json.loads(cookie.content))
|
||||
client.cookies = cookies
|
||||
client.event_hooks = {"response": [self._generate_hook(cookie)]}
|
||||
return client
|
||||
|
||||
async def get_client_for_static(self) -> AsyncClient:
|
||||
return http_client()
|
||||
|
||||
async def get_query_name_client(self) -> AsyncClient:
|
||||
return http_client()
|
||||
|
||||
async def refresh_client(self):
|
||||
pass
|
||||
|
||||
|
||||
def is_cookie_client_manager(manger: type[ClientManager]) -> bool:
|
||||
return issubclass(manger, CookieClientManager)
|
||||
|
||||
|
||||
def create_cookie_client_manager(site_name: str) -> type[CookieClientManager]:
|
||||
"""创建一个平台特化的 CookieClientManger"""
|
||||
return type(
|
||||
"CookieClientManager",
|
||||
(CookieClientManager,),
|
||||
{"_site_name": site_name},
|
||||
)
|
||||
|
||||
|
||||
class Site(metaclass=RegistryMeta, base=True):
|
||||
class Site:
|
||||
schedule_type: Literal["date", "interval", "cron"]
|
||||
schedule_setting: dict
|
||||
name: str
|
||||
client_mgr: type[ClientManager] = DefaultClientManager
|
||||
require_browser: bool = False
|
||||
registry: list[type["Site"]]
|
||||
cookie_format_prompt = "无效的 Cookie,请检查后重新输入,详情见<待添加的文档>"
|
||||
|
||||
def __str__(self):
|
||||
return f"[{self.name}]-{self.name}-{self.schedule_setting}"
|
||||
@@ -172,7 +56,3 @@ def anonymous_site(schedule_type: Literal["date", "interval", "cron"], schedule_
|
||||
"client_mgr": DefaultClientManager,
|
||||
},
|
||||
)
|
||||
|
||||
|
||||
class SkipRequestException(Exception):
|
||||
pass
|
||||
|
||||
+1
-1
@@ -12,7 +12,7 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"@vuepress/bundler-vite": "2.0.0-rc.15",
|
||||
"vue": "^3.5.3",
|
||||
"vue": "^3.5.6",
|
||||
"vuepress": "2.0.0-rc.15",
|
||||
"vuepress-theme-hope": "2.0.0-rc.52"
|
||||
}
|
||||
|
||||
Generated
+2037
-1682
File diff suppressed because it is too large
Load Diff
Generated
+215
-215
@@ -2589,13 +2589,13 @@ reference = "offical-source"
|
||||
|
||||
[[package]]
|
||||
name = "nonebot-adapter-onebot"
|
||||
version = "2.4.4"
|
||||
version = "2.4.5"
|
||||
description = "OneBot(CQHTTP) adapter for nonebot2"
|
||||
optional = false
|
||||
python-versions = ">=3.9,<4.0"
|
||||
files = [
|
||||
{file = "nonebot_adapter_onebot-2.4.4-py3-none-any.whl", hash = "sha256:4dceeec7332bb560652c764405e9dd350268303f69b7c0e92b7cfebe876e8d39"},
|
||||
{file = "nonebot_adapter_onebot-2.4.4.tar.gz", hash = "sha256:c8a3645f74a3e43c85f092fb670508c662c36831f019a15e4d74eaac686089f0"},
|
||||
{file = "nonebot_adapter_onebot-2.4.5-py3-none-any.whl", hash = "sha256:882780f2a8eb52137177643c78a6b36c73c38cc53b20e11a5f83aa66cd8bce3f"},
|
||||
{file = "nonebot_adapter_onebot-2.4.5.tar.gz", hash = "sha256:5897903792226683323c960472e2cced7609d45e8e8c3730646e9db5d9c3241e"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
@@ -3347,26 +3347,26 @@ reference = "offical-source"
|
||||
|
||||
[[package]]
|
||||
name = "pydantic"
|
||||
version = "2.9.0"
|
||||
version = "2.9.2"
|
||||
description = "Data validation using Python type hints"
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "pydantic-2.9.0-py3-none-any.whl", hash = "sha256:f66a7073abd93214a20c5f7b32d56843137a7a2e70d02111f3be287035c45370"},
|
||||
{file = "pydantic-2.9.0.tar.gz", hash = "sha256:c7a8a9fdf7d100afa49647eae340e2d23efa382466a8d177efcd1381e9be5598"},
|
||||
{file = "pydantic-2.9.2-py3-none-any.whl", hash = "sha256:f048cec7b26778210e28a0459867920654d48e5e62db0958433636cde4254f12"},
|
||||
{file = "pydantic-2.9.2.tar.gz", hash = "sha256:d155cef71265d1e9807ed1c32b4c8deec042a44a50a4188b25ac67ecd81a9c0f"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
annotated-types = ">=0.4.0"
|
||||
pydantic-core = "2.23.2"
|
||||
annotated-types = ">=0.6.0"
|
||||
pydantic-core = "2.23.4"
|
||||
typing-extensions = [
|
||||
{version = ">=4.12.2", markers = "python_version >= \"3.13\""},
|
||||
{version = ">=4.6.1", markers = "python_version < \"3.13\""},
|
||||
]
|
||||
tzdata = {version = "*", markers = "python_version >= \"3.9\""}
|
||||
|
||||
[package.extras]
|
||||
email = ["email-validator (>=2.0.0)"]
|
||||
timezone = ["tzdata"]
|
||||
|
||||
[package.source]
|
||||
type = "legacy"
|
||||
@@ -3375,100 +3375,100 @@ reference = "offical-source"
|
||||
|
||||
[[package]]
|
||||
name = "pydantic-core"
|
||||
version = "2.23.2"
|
||||
version = "2.23.4"
|
||||
description = "Core functionality for Pydantic validation and serialization"
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "pydantic_core-2.23.2-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:7d0324a35ab436c9d768753cbc3c47a865a2cbc0757066cb864747baa61f6ece"},
|
||||
{file = "pydantic_core-2.23.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:276ae78153a94b664e700ac362587c73b84399bd1145e135287513442e7dfbc7"},
|
||||
{file = "pydantic_core-2.23.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:964c7aa318da542cdcc60d4a648377ffe1a2ef0eb1e996026c7f74507b720a78"},
|
||||
{file = "pydantic_core-2.23.2-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:1cf842265a3a820ebc6388b963ead065f5ce8f2068ac4e1c713ef77a67b71f7c"},
|
||||
{file = "pydantic_core-2.23.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ae90b9e50fe1bd115b24785e962b51130340408156d34d67b5f8f3fa6540938e"},
|
||||
{file = "pydantic_core-2.23.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8ae65fdfb8a841556b52935dfd4c3f79132dc5253b12c0061b96415208f4d622"},
|
||||
{file = "pydantic_core-2.23.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5c8aa40f6ca803f95b1c1c5aeaee6237b9e879e4dfb46ad713229a63651a95fb"},
|
||||
{file = "pydantic_core-2.23.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:c53100c8ee5a1e102766abde2158077d8c374bee0639201f11d3032e3555dfbc"},
|
||||
{file = "pydantic_core-2.23.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:d6b9dd6aa03c812017411734e496c44fef29b43dba1e3dd1fa7361bbacfc1354"},
|
||||
{file = "pydantic_core-2.23.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:b18cf68255a476b927910c6873d9ed00da692bb293c5b10b282bd48a0afe3ae2"},
|
||||
{file = "pydantic_core-2.23.2-cp310-none-win32.whl", hash = "sha256:e460475719721d59cd54a350c1f71c797c763212c836bf48585478c5514d2854"},
|
||||
{file = "pydantic_core-2.23.2-cp310-none-win_amd64.whl", hash = "sha256:5f3cf3721eaf8741cffaf092487f1ca80831202ce91672776b02b875580e174a"},
|
||||
{file = "pydantic_core-2.23.2-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:7ce8e26b86a91e305858e018afc7a6e932f17428b1eaa60154bd1f7ee888b5f8"},
|
||||
{file = "pydantic_core-2.23.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:7e9b24cca4037a561422bf5dc52b38d390fb61f7bfff64053ce1b72f6938e6b2"},
|
||||
{file = "pydantic_core-2.23.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:753294d42fb072aa1775bfe1a2ba1012427376718fa4c72de52005a3d2a22178"},
|
||||
{file = "pydantic_core-2.23.2-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:257d6a410a0d8aeb50b4283dea39bb79b14303e0fab0f2b9d617701331ed1515"},
|
||||
{file = "pydantic_core-2.23.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c8319e0bd6a7b45ad76166cc3d5d6a36c97d0c82a196f478c3ee5346566eebfd"},
|
||||
{file = "pydantic_core-2.23.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7a05c0240f6c711eb381ac392de987ee974fa9336071fb697768dfdb151345ce"},
|
||||
{file = "pydantic_core-2.23.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8d5b0ff3218858859910295df6953d7bafac3a48d5cd18f4e3ed9999efd2245f"},
|
||||
{file = "pydantic_core-2.23.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:96ef39add33ff58cd4c112cbac076726b96b98bb8f1e7f7595288dcfb2f10b57"},
|
||||
{file = "pydantic_core-2.23.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:0102e49ac7d2df3379ef8d658d3bc59d3d769b0bdb17da189b75efa861fc07b4"},
|
||||
{file = "pydantic_core-2.23.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:a6612c2a844043e4d10a8324c54cdff0042c558eef30bd705770793d70b224aa"},
|
||||
{file = "pydantic_core-2.23.2-cp311-none-win32.whl", hash = "sha256:caffda619099cfd4f63d48462f6aadbecee3ad9603b4b88b60cb821c1b258576"},
|
||||
{file = "pydantic_core-2.23.2-cp311-none-win_amd64.whl", hash = "sha256:6f80fba4af0cb1d2344869d56430e304a51396b70d46b91a55ed4959993c0589"},
|
||||
{file = "pydantic_core-2.23.2-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:4c83c64d05ffbbe12d4e8498ab72bdb05bcc1026340a4a597dc647a13c1605ec"},
|
||||
{file = "pydantic_core-2.23.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:6294907eaaccf71c076abdd1c7954e272efa39bb043161b4b8aa1cd76a16ce43"},
|
||||
{file = "pydantic_core-2.23.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4a801c5e1e13272e0909c520708122496647d1279d252c9e6e07dac216accc41"},
|
||||
{file = "pydantic_core-2.23.2-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:cc0c316fba3ce72ac3ab7902a888b9dc4979162d320823679da270c2d9ad0cad"},
|
||||
{file = "pydantic_core-2.23.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6b06c5d4e8701ac2ba99a2ef835e4e1b187d41095a9c619c5b185c9068ed2a49"},
|
||||
{file = "pydantic_core-2.23.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:82764c0bd697159fe9947ad59b6db6d7329e88505c8f98990eb07e84cc0a5d81"},
|
||||
{file = "pydantic_core-2.23.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2b1a195efd347ede8bcf723e932300292eb13a9d2a3c1f84eb8f37cbbc905b7f"},
|
||||
{file = "pydantic_core-2.23.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b7efb12e5071ad8d5b547487bdad489fbd4a5a35a0fc36a1941517a6ad7f23e0"},
|
||||
{file = "pydantic_core-2.23.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:5dd0ec5f514ed40e49bf961d49cf1bc2c72e9b50f29a163b2cc9030c6742aa73"},
|
||||
{file = "pydantic_core-2.23.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:820f6ee5c06bc868335e3b6e42d7ef41f50dfb3ea32fbd523ab679d10d8741c0"},
|
||||
{file = "pydantic_core-2.23.2-cp312-none-win32.whl", hash = "sha256:3713dc093d5048bfaedbba7a8dbc53e74c44a140d45ede020dc347dda18daf3f"},
|
||||
{file = "pydantic_core-2.23.2-cp312-none-win_amd64.whl", hash = "sha256:e1895e949f8849bc2757c0dbac28422a04be031204df46a56ab34bcf98507342"},
|
||||
{file = "pydantic_core-2.23.2-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:da43cbe593e3c87d07108d0ebd73771dc414488f1f91ed2e204b0370b94b37ac"},
|
||||
{file = "pydantic_core-2.23.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:64d094ea1aa97c6ded4748d40886076a931a8bf6f61b6e43e4a1041769c39dd2"},
|
||||
{file = "pydantic_core-2.23.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:084414ffe9a85a52940b49631321d636dadf3576c30259607b75516d131fecd0"},
|
||||
{file = "pydantic_core-2.23.2-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:043ef8469f72609c4c3a5e06a07a1f713d53df4d53112c6d49207c0bd3c3bd9b"},
|
||||
{file = "pydantic_core-2.23.2-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3649bd3ae6a8ebea7dc381afb7f3c6db237fc7cebd05c8ac36ca8a4187b03b30"},
|
||||
{file = "pydantic_core-2.23.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6db09153d8438425e98cdc9a289c5fade04a5d2128faff8f227c459da21b9703"},
|
||||
{file = "pydantic_core-2.23.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5668b3173bb0b2e65020b60d83f5910a7224027232c9f5dc05a71a1deac9f960"},
|
||||
{file = "pydantic_core-2.23.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:1c7b81beaf7c7ebde978377dc53679c6cba0e946426fc7ade54251dfe24a7604"},
|
||||
{file = "pydantic_core-2.23.2-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:ae579143826c6f05a361d9546446c432a165ecf1c0b720bbfd81152645cb897d"},
|
||||
{file = "pydantic_core-2.23.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:19f1352fe4b248cae22a89268720fc74e83f008057a652894f08fa931e77dced"},
|
||||
{file = "pydantic_core-2.23.2-cp313-none-win32.whl", hash = "sha256:e1a79ad49f346aa1a2921f31e8dbbab4d64484823e813a002679eaa46cba39e1"},
|
||||
{file = "pydantic_core-2.23.2-cp313-none-win_amd64.whl", hash = "sha256:582871902e1902b3c8e9b2c347f32a792a07094110c1bca6c2ea89b90150caac"},
|
||||
{file = "pydantic_core-2.23.2-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:743e5811b0c377eb830150d675b0847a74a44d4ad5ab8845923d5b3a756d8100"},
|
||||
{file = "pydantic_core-2.23.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:6650a7bbe17a2717167e3e23c186849bae5cef35d38949549f1c116031b2b3aa"},
|
||||
{file = "pydantic_core-2.23.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:56e6a12ec8d7679f41b3750ffa426d22b44ef97be226a9bab00a03365f217b2b"},
|
||||
{file = "pydantic_core-2.23.2-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:810ca06cca91de9107718dc83d9ac4d2e86efd6c02cba49a190abcaf33fb0472"},
|
||||
{file = "pydantic_core-2.23.2-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:785e7f517ebb9890813d31cb5d328fa5eda825bb205065cde760b3150e4de1f7"},
|
||||
{file = "pydantic_core-2.23.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3ef71ec876fcc4d3bbf2ae81961959e8d62f8d74a83d116668409c224012e3af"},
|
||||
{file = "pydantic_core-2.23.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d50ac34835c6a4a0d456b5db559b82047403c4317b3bc73b3455fefdbdc54b0a"},
|
||||
{file = "pydantic_core-2.23.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:16b25a4a120a2bb7dab51b81e3d9f3cde4f9a4456566c403ed29ac81bf49744f"},
|
||||
{file = "pydantic_core-2.23.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:41ae8537ad371ec018e3c5da0eb3f3e40ee1011eb9be1da7f965357c4623c501"},
|
||||
{file = "pydantic_core-2.23.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:07049ec9306ec64e955b2e7c40c8d77dd78ea89adb97a2013d0b6e055c5ee4c5"},
|
||||
{file = "pydantic_core-2.23.2-cp38-none-win32.whl", hash = "sha256:086c5db95157dc84c63ff9d96ebb8856f47ce113c86b61065a066f8efbe80acf"},
|
||||
{file = "pydantic_core-2.23.2-cp38-none-win_amd64.whl", hash = "sha256:67b6655311b00581914aba481729971b88bb8bc7996206590700a3ac85e457b8"},
|
||||
{file = "pydantic_core-2.23.2-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:358331e21a897151e54d58e08d0219acf98ebb14c567267a87e971f3d2a3be59"},
|
||||
{file = "pydantic_core-2.23.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:c4d9f15ffe68bcd3898b0ad7233af01b15c57d91cd1667f8d868e0eacbfe3f87"},
|
||||
{file = "pydantic_core-2.23.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0123655fedacf035ab10c23450163c2f65a4174f2bb034b188240a6cf06bb123"},
|
||||
{file = "pydantic_core-2.23.2-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:e6e3ccebdbd6e53474b0bb7ab8b88e83c0cfe91484b25e058e581348ee5a01a5"},
|
||||
{file = "pydantic_core-2.23.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:fc535cb898ef88333cf317777ecdfe0faac1c2a3187ef7eb061b6f7ecf7e6bae"},
|
||||
{file = "pydantic_core-2.23.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:aab9e522efff3993a9e98ab14263d4e20211e62da088298089a03056980a3e69"},
|
||||
{file = "pydantic_core-2.23.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:05b366fb8fe3d8683b11ac35fa08947d7b92be78ec64e3277d03bd7f9b7cda79"},
|
||||
{file = "pydantic_core-2.23.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:7568f682c06f10f30ef643a1e8eec4afeecdafde5c4af1b574c6df079e96f96c"},
|
||||
{file = "pydantic_core-2.23.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:cdd02a08205dc90238669f082747612cb3c82bd2c717adc60f9b9ecadb540f80"},
|
||||
{file = "pydantic_core-2.23.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:1a2ab4f410f4b886de53b6bddf5dd6f337915a29dd9f22f20f3099659536b2f6"},
|
||||
{file = "pydantic_core-2.23.2-cp39-none-win32.whl", hash = "sha256:0448b81c3dfcde439551bb04a9f41d7627f676b12701865c8a2574bcea034437"},
|
||||
{file = "pydantic_core-2.23.2-cp39-none-win_amd64.whl", hash = "sha256:4cebb9794f67266d65e7e4cbe5dcf063e29fc7b81c79dc9475bd476d9534150e"},
|
||||
{file = "pydantic_core-2.23.2-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:e758d271ed0286d146cf7c04c539a5169a888dd0b57026be621547e756af55bc"},
|
||||
{file = "pydantic_core-2.23.2-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:f477d26183e94eaafc60b983ab25af2a809a1b48ce4debb57b343f671b7a90b6"},
|
||||
{file = "pydantic_core-2.23.2-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:da3131ef2b940b99106f29dfbc30d9505643f766704e14c5d5e504e6a480c35e"},
|
||||
{file = "pydantic_core-2.23.2-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:329a721253c7e4cbd7aad4a377745fbcc0607f9d72a3cc2102dd40519be75ed2"},
|
||||
{file = "pydantic_core-2.23.2-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:7706e15cdbf42f8fab1e6425247dfa98f4a6f8c63746c995d6a2017f78e619ae"},
|
||||
{file = "pydantic_core-2.23.2-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:e64ffaf8f6e17ca15eb48344d86a7a741454526f3a3fa56bc493ad9d7ec63936"},
|
||||
{file = "pydantic_core-2.23.2-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:dd59638025160056687d598b054b64a79183f8065eae0d3f5ca523cde9943940"},
|
||||
{file = "pydantic_core-2.23.2-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:12625e69b1199e94b0ae1c9a95d000484ce9f0182f9965a26572f054b1537e44"},
|
||||
{file = "pydantic_core-2.23.2-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:5d813fd871b3d5c3005157622ee102e8908ad6011ec915a18bd8fde673c4360e"},
|
||||
{file = "pydantic_core-2.23.2-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:1eb37f7d6a8001c0f86dc8ff2ee8d08291a536d76e49e78cda8587bb54d8b329"},
|
||||
{file = "pydantic_core-2.23.2-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7ce7eaf9a98680b4312b7cebcdd9352531c43db00fca586115845df388f3c465"},
|
||||
{file = "pydantic_core-2.23.2-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f087879f1ffde024dd2788a30d55acd67959dcf6c431e9d3682d1c491a0eb474"},
|
||||
{file = "pydantic_core-2.23.2-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:6ce883906810b4c3bd90e0ada1f9e808d9ecf1c5f0b60c6b8831d6100bcc7dd6"},
|
||||
{file = "pydantic_core-2.23.2-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:a8031074a397a5925d06b590121f8339d34a5a74cfe6970f8a1124eb8b83f4ac"},
|
||||
{file = "pydantic_core-2.23.2-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:23af245b8f2f4ee9e2c99cb3f93d0e22fb5c16df3f2f643f5a8da5caff12a653"},
|
||||
{file = "pydantic_core-2.23.2-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:c57e493a0faea1e4c38f860d6862ba6832723396c884fbf938ff5e9b224200e2"},
|
||||
{file = "pydantic_core-2.23.2.tar.gz", hash = "sha256:95d6bf449a1ac81de562d65d180af5d8c19672793c81877a2eda8fde5d08f2fd"},
|
||||
{file = "pydantic_core-2.23.4-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:b10bd51f823d891193d4717448fab065733958bdb6a6b351967bd349d48d5c9b"},
|
||||
{file = "pydantic_core-2.23.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:4fc714bdbfb534f94034efaa6eadd74e5b93c8fa6315565a222f7b6f42ca1166"},
|
||||
{file = "pydantic_core-2.23.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:63e46b3169866bd62849936de036f901a9356e36376079b05efa83caeaa02ceb"},
|
||||
{file = "pydantic_core-2.23.4-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ed1a53de42fbe34853ba90513cea21673481cd81ed1be739f7f2efb931b24916"},
|
||||
{file = "pydantic_core-2.23.4-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:cfdd16ab5e59fc31b5e906d1a3f666571abc367598e3e02c83403acabc092e07"},
|
||||
{file = "pydantic_core-2.23.4-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:255a8ef062cbf6674450e668482456abac99a5583bbafb73f9ad469540a3a232"},
|
||||
{file = "pydantic_core-2.23.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4a7cd62e831afe623fbb7aabbb4fe583212115b3ef38a9f6b71869ba644624a2"},
|
||||
{file = "pydantic_core-2.23.4-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f09e2ff1f17c2b51f2bc76d1cc33da96298f0a036a137f5440ab3ec5360b624f"},
|
||||
{file = "pydantic_core-2.23.4-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:e38e63e6f3d1cec5a27e0afe90a085af8b6806ee208b33030e65b6516353f1a3"},
|
||||
{file = "pydantic_core-2.23.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:0dbd8dbed2085ed23b5c04afa29d8fd2771674223135dc9bc937f3c09284d071"},
|
||||
{file = "pydantic_core-2.23.4-cp310-none-win32.whl", hash = "sha256:6531b7ca5f951d663c339002e91aaebda765ec7d61b7d1e3991051906ddde119"},
|
||||
{file = "pydantic_core-2.23.4-cp310-none-win_amd64.whl", hash = "sha256:7c9129eb40958b3d4500fa2467e6a83356b3b61bfff1b414c7361d9220f9ae8f"},
|
||||
{file = "pydantic_core-2.23.4-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:77733e3892bb0a7fa797826361ce8a9184d25c8dffaec60b7ffe928153680ba8"},
|
||||
{file = "pydantic_core-2.23.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1b84d168f6c48fabd1f2027a3d1bdfe62f92cade1fb273a5d68e621da0e44e6d"},
|
||||
{file = "pydantic_core-2.23.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:df49e7a0861a8c36d089c1ed57d308623d60416dab2647a4a17fe050ba85de0e"},
|
||||
{file = "pydantic_core-2.23.4-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ff02b6d461a6de369f07ec15e465a88895f3223eb75073ffea56b84d9331f607"},
|
||||
{file = "pydantic_core-2.23.4-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:996a38a83508c54c78a5f41456b0103c30508fed9abcad0a59b876d7398f25fd"},
|
||||
{file = "pydantic_core-2.23.4-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d97683ddee4723ae8c95d1eddac7c192e8c552da0c73a925a89fa8649bf13eea"},
|
||||
{file = "pydantic_core-2.23.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:216f9b2d7713eb98cb83c80b9c794de1f6b7e3145eef40400c62e86cee5f4e1e"},
|
||||
{file = "pydantic_core-2.23.4-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:6f783e0ec4803c787bcea93e13e9932edab72068f68ecffdf86a99fd5918878b"},
|
||||
{file = "pydantic_core-2.23.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:d0776dea117cf5272382634bd2a5c1b6eb16767c223c6a5317cd3e2a757c61a0"},
|
||||
{file = "pydantic_core-2.23.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:d5f7a395a8cf1621939692dba2a6b6a830efa6b3cee787d82c7de1ad2930de64"},
|
||||
{file = "pydantic_core-2.23.4-cp311-none-win32.whl", hash = "sha256:74b9127ffea03643e998e0c5ad9bd3811d3dac8c676e47db17b0ee7c3c3bf35f"},
|
||||
{file = "pydantic_core-2.23.4-cp311-none-win_amd64.whl", hash = "sha256:98d134c954828488b153d88ba1f34e14259284f256180ce659e8d83e9c05eaa3"},
|
||||
{file = "pydantic_core-2.23.4-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:f3e0da4ebaef65158d4dfd7d3678aad692f7666877df0002b8a522cdf088f231"},
|
||||
{file = "pydantic_core-2.23.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:f69a8e0b033b747bb3e36a44e7732f0c99f7edd5cea723d45bc0d6e95377ffee"},
|
||||
{file = "pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:723314c1d51722ab28bfcd5240d858512ffd3116449c557a1336cbe3919beb87"},
|
||||
{file = "pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:bb2802e667b7051a1bebbfe93684841cc9351004e2badbd6411bf357ab8d5ac8"},
|
||||
{file = "pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d18ca8148bebe1b0a382a27a8ee60350091a6ddaf475fa05ef50dc35b5df6327"},
|
||||
{file = "pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:33e3d65a85a2a4a0dc3b092b938a4062b1a05f3a9abde65ea93b233bca0e03f2"},
|
||||
{file = "pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:128585782e5bfa515c590ccee4b727fb76925dd04a98864182b22e89a4e6ed36"},
|
||||
{file = "pydantic_core-2.23.4-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:68665f4c17edcceecc112dfed5dbe6f92261fb9d6054b47d01bf6371a6196126"},
|
||||
{file = "pydantic_core-2.23.4-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:20152074317d9bed6b7a95ade3b7d6054845d70584216160860425f4fbd5ee9e"},
|
||||
{file = "pydantic_core-2.23.4-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:9261d3ce84fa1d38ed649c3638feefeae23d32ba9182963e465d58d62203bd24"},
|
||||
{file = "pydantic_core-2.23.4-cp312-none-win32.whl", hash = "sha256:4ba762ed58e8d68657fc1281e9bb72e1c3e79cc5d464be146e260c541ec12d84"},
|
||||
{file = "pydantic_core-2.23.4-cp312-none-win_amd64.whl", hash = "sha256:97df63000f4fea395b2824da80e169731088656d1818a11b95f3b173747b6cd9"},
|
||||
{file = "pydantic_core-2.23.4-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:7530e201d10d7d14abce4fb54cfe5b94a0aefc87da539d0346a484ead376c3cc"},
|
||||
{file = "pydantic_core-2.23.4-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:df933278128ea1cd77772673c73954e53a1c95a4fdf41eef97c2b779271bd0bd"},
|
||||
{file = "pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0cb3da3fd1b6a5d0279a01877713dbda118a2a4fc6f0d821a57da2e464793f05"},
|
||||
{file = "pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:42c6dcb030aefb668a2b7009c85b27f90e51e6a3b4d5c9bc4c57631292015b0d"},
|
||||
{file = "pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:696dd8d674d6ce621ab9d45b205df149399e4bb9aa34102c970b721554828510"},
|
||||
{file = "pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2971bb5ffe72cc0f555c13e19b23c85b654dd2a8f7ab493c262071377bfce9f6"},
|
||||
{file = "pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8394d940e5d400d04cad4f75c0598665cbb81aecefaca82ca85bd28264af7f9b"},
|
||||
{file = "pydantic_core-2.23.4-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:0dff76e0602ca7d4cdaacc1ac4c005e0ce0dcfe095d5b5259163a80d3a10d327"},
|
||||
{file = "pydantic_core-2.23.4-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:7d32706badfe136888bdea71c0def994644e09fff0bfe47441deaed8e96fdbc6"},
|
||||
{file = "pydantic_core-2.23.4-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:ed541d70698978a20eb63d8c5d72f2cc6d7079d9d90f6b50bad07826f1320f5f"},
|
||||
{file = "pydantic_core-2.23.4-cp313-none-win32.whl", hash = "sha256:3d5639516376dce1940ea36edf408c554475369f5da2abd45d44621cb616f769"},
|
||||
{file = "pydantic_core-2.23.4-cp313-none-win_amd64.whl", hash = "sha256:5a1504ad17ba4210df3a045132a7baeeba5a200e930f57512ee02909fc5c4cb5"},
|
||||
{file = "pydantic_core-2.23.4-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:d4488a93b071c04dc20f5cecc3631fc78b9789dd72483ba15d423b5b3689b555"},
|
||||
{file = "pydantic_core-2.23.4-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:81965a16b675b35e1d09dd14df53f190f9129c0202356ed44ab2728b1c905658"},
|
||||
{file = "pydantic_core-2.23.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4ffa2ebd4c8530079140dd2d7f794a9d9a73cbb8e9d59ffe24c63436efa8f271"},
|
||||
{file = "pydantic_core-2.23.4-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:61817945f2fe7d166e75fbfb28004034b48e44878177fc54d81688e7b85a3665"},
|
||||
{file = "pydantic_core-2.23.4-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:29d2c342c4bc01b88402d60189f3df065fb0dda3654744d5a165a5288a657368"},
|
||||
{file = "pydantic_core-2.23.4-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5e11661ce0fd30a6790e8bcdf263b9ec5988e95e63cf901972107efc49218b13"},
|
||||
{file = "pydantic_core-2.23.4-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9d18368b137c6295db49ce7218b1a9ba15c5bc254c96d7c9f9e924a9bc7825ad"},
|
||||
{file = "pydantic_core-2.23.4-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:ec4e55f79b1c4ffb2eecd8a0cfba9955a2588497d96851f4c8f99aa4a1d39b12"},
|
||||
{file = "pydantic_core-2.23.4-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:374a5e5049eda9e0a44c696c7ade3ff355f06b1fe0bb945ea3cac2bc336478a2"},
|
||||
{file = "pydantic_core-2.23.4-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:5c364564d17da23db1106787675fc7af45f2f7b58b4173bfdd105564e132e6fb"},
|
||||
{file = "pydantic_core-2.23.4-cp38-none-win32.whl", hash = "sha256:d7a80d21d613eec45e3d41eb22f8f94ddc758a6c4720842dc74c0581f54993d6"},
|
||||
{file = "pydantic_core-2.23.4-cp38-none-win_amd64.whl", hash = "sha256:5f5ff8d839f4566a474a969508fe1c5e59c31c80d9e140566f9a37bba7b8d556"},
|
||||
{file = "pydantic_core-2.23.4-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:a4fa4fc04dff799089689f4fd502ce7d59de529fc2f40a2c8836886c03e0175a"},
|
||||
{file = "pydantic_core-2.23.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:0a7df63886be5e270da67e0966cf4afbae86069501d35c8c1b3b6c168f42cb36"},
|
||||
{file = "pydantic_core-2.23.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dcedcd19a557e182628afa1d553c3895a9f825b936415d0dbd3cd0bbcfd29b4b"},
|
||||
{file = "pydantic_core-2.23.4-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5f54b118ce5de9ac21c363d9b3caa6c800341e8c47a508787e5868c6b79c9323"},
|
||||
{file = "pydantic_core-2.23.4-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:86d2f57d3e1379a9525c5ab067b27dbb8a0642fb5d454e17a9ac434f9ce523e3"},
|
||||
{file = "pydantic_core-2.23.4-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:de6d1d1b9e5101508cb37ab0d972357cac5235f5c6533d1071964c47139257df"},
|
||||
{file = "pydantic_core-2.23.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1278e0d324f6908e872730c9102b0112477a7f7cf88b308e4fc36ce1bdb6d58c"},
|
||||
{file = "pydantic_core-2.23.4-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:9a6b5099eeec78827553827f4c6b8615978bb4b6a88e5d9b93eddf8bb6790f55"},
|
||||
{file = "pydantic_core-2.23.4-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:e55541f756f9b3ee346b840103f32779c695a19826a4c442b7954550a0972040"},
|
||||
{file = "pydantic_core-2.23.4-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:a5c7ba8ffb6d6f8f2ab08743be203654bb1aaa8c9dcb09f82ddd34eadb695605"},
|
||||
{file = "pydantic_core-2.23.4-cp39-none-win32.whl", hash = "sha256:37b0fe330e4a58d3c58b24d91d1eb102aeec675a3db4c292ec3928ecd892a9a6"},
|
||||
{file = "pydantic_core-2.23.4-cp39-none-win_amd64.whl", hash = "sha256:1498bec4c05c9c787bde9125cfdcc63a41004ff167f495063191b863399b1a29"},
|
||||
{file = "pydantic_core-2.23.4-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:f455ee30a9d61d3e1a15abd5068827773d6e4dc513e795f380cdd59932c782d5"},
|
||||
{file = "pydantic_core-2.23.4-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:1e90d2e3bd2c3863d48525d297cd143fe541be8bbf6f579504b9712cb6b643ec"},
|
||||
{file = "pydantic_core-2.23.4-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2e203fdf807ac7e12ab59ca2bfcabb38c7cf0b33c41efeb00f8e5da1d86af480"},
|
||||
{file = "pydantic_core-2.23.4-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e08277a400de01bc72436a0ccd02bdf596631411f592ad985dcee21445bd0068"},
|
||||
{file = "pydantic_core-2.23.4-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f220b0eea5965dec25480b6333c788fb72ce5f9129e8759ef876a1d805d00801"},
|
||||
{file = "pydantic_core-2.23.4-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:d06b0c8da4f16d1d1e352134427cb194a0a6e19ad5db9161bf32b2113409e728"},
|
||||
{file = "pydantic_core-2.23.4-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:ba1a0996f6c2773bd83e63f18914c1de3c9dd26d55f4ac302a7efe93fb8e7433"},
|
||||
{file = "pydantic_core-2.23.4-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:9a5bce9d23aac8f0cf0836ecfc033896aa8443b501c58d0602dbfd5bd5b37753"},
|
||||
{file = "pydantic_core-2.23.4-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:78ddaaa81421a29574a682b3179d4cf9e6d405a09b99d93ddcf7e5239c742e21"},
|
||||
{file = "pydantic_core-2.23.4-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:883a91b5dd7d26492ff2f04f40fbb652de40fcc0afe07e8129e8ae779c2110eb"},
|
||||
{file = "pydantic_core-2.23.4-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:88ad334a15b32a791ea935af224b9de1bf99bcd62fabf745d5f3442199d86d59"},
|
||||
{file = "pydantic_core-2.23.4-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:233710f069d251feb12a56da21e14cca67994eab08362207785cf8c598e74577"},
|
||||
{file = "pydantic_core-2.23.4-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:19442362866a753485ba5e4be408964644dd6a09123d9416c54cd49171f50744"},
|
||||
{file = "pydantic_core-2.23.4-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:624e278a7d29b6445e4e813af92af37820fafb6dcc55c012c834f9e26f9aaaef"},
|
||||
{file = "pydantic_core-2.23.4-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:f5ef8f42bec47f21d07668a043f077d507e5bf4e668d5c6dfe6aaba89de1a5b8"},
|
||||
{file = "pydantic_core-2.23.4-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:aea443fffa9fbe3af1a9ba721a87f926fe548d32cab71d188a6ede77d0ff244e"},
|
||||
{file = "pydantic_core-2.23.4.tar.gz", hash = "sha256:2584f7cf844ac4d970fba483a717dbe10c1c1c96a969bf65d61ffe94df1b2863"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
@@ -3615,13 +3615,13 @@ reference = "offical-source"
|
||||
|
||||
[[package]]
|
||||
name = "pytest"
|
||||
version = "8.3.2"
|
||||
version = "8.3.3"
|
||||
description = "pytest: simple powerful testing with Python"
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "pytest-8.3.2-py3-none-any.whl", hash = "sha256:4ba08f9ae7dcf84ded419494d229b48d0903ea6407b030eaec46df5e6a73bba5"},
|
||||
{file = "pytest-8.3.2.tar.gz", hash = "sha256:c132345d12ce551242c87269de812483f5bcc87cdbb4722e48487ba194f9fdce"},
|
||||
{file = "pytest-8.3.3-py3-none-any.whl", hash = "sha256:a6853c7375b2663155079443d2e45de913a911a11d669df02a50814944db57b2"},
|
||||
{file = "pytest-8.3.3.tar.gz", hash = "sha256:70b98107bd648308a7952b06e6ca9a50bc660be218d53c257cc1fc94fda10181"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
@@ -4185,29 +4185,29 @@ reference = "offical-source"
|
||||
|
||||
[[package]]
|
||||
name = "ruff"
|
||||
version = "0.6.4"
|
||||
version = "0.6.5"
|
||||
description = "An extremely fast Python linter and code formatter, written in Rust."
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
{file = "ruff-0.6.4-py3-none-linux_armv6l.whl", hash = "sha256:c4b153fc152af51855458e79e835fb6b933032921756cec9af7d0ba2aa01a258"},
|
||||
{file = "ruff-0.6.4-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:bedff9e4f004dad5f7f76a9d39c4ca98af526c9b1695068198b3bda8c085ef60"},
|
||||
{file = "ruff-0.6.4-py3-none-macosx_11_0_arm64.whl", hash = "sha256:d02a4127a86de23002e694d7ff19f905c51e338c72d8e09b56bfb60e1681724f"},
|
||||
{file = "ruff-0.6.4-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7862f42fc1a4aca1ea3ffe8a11f67819d183a5693b228f0bb3a531f5e40336fc"},
|
||||
{file = "ruff-0.6.4-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:eebe4ff1967c838a1a9618a5a59a3b0a00406f8d7eefee97c70411fefc353617"},
|
||||
{file = "ruff-0.6.4-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:932063a03bac394866683e15710c25b8690ccdca1cf192b9a98260332ca93408"},
|
||||
{file = "ruff-0.6.4-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:50e30b437cebef547bd5c3edf9ce81343e5dd7c737cb36ccb4fe83573f3d392e"},
|
||||
{file = "ruff-0.6.4-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c44536df7b93a587de690e124b89bd47306fddd59398a0fb12afd6133c7b3818"},
|
||||
{file = "ruff-0.6.4-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0ea086601b22dc5e7693a78f3fcfc460cceabfdf3bdc36dc898792aba48fbad6"},
|
||||
{file = "ruff-0.6.4-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0b52387d3289ccd227b62102c24714ed75fbba0b16ecc69a923a37e3b5e0aaaa"},
|
||||
{file = "ruff-0.6.4-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:0308610470fcc82969082fc83c76c0d362f562e2f0cdab0586516f03a4e06ec6"},
|
||||
{file = "ruff-0.6.4-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:803b96dea21795a6c9d5bfa9e96127cc9c31a1987802ca68f35e5c95aed3fc0d"},
|
||||
{file = "ruff-0.6.4-py3-none-musllinux_1_2_i686.whl", hash = "sha256:66dbfea86b663baab8fcae56c59f190caba9398df1488164e2df53e216248baa"},
|
||||
{file = "ruff-0.6.4-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:34d5efad480193c046c86608dbba2bccdc1c5fd11950fb271f8086e0c763a5d1"},
|
||||
{file = "ruff-0.6.4-py3-none-win32.whl", hash = "sha256:f0f8968feea5ce3777c0d8365653d5e91c40c31a81d95824ba61d871a11b8523"},
|
||||
{file = "ruff-0.6.4-py3-none-win_amd64.whl", hash = "sha256:549daccee5227282289390b0222d0fbee0275d1db6d514550d65420053021a58"},
|
||||
{file = "ruff-0.6.4-py3-none-win_arm64.whl", hash = "sha256:ac4b75e898ed189b3708c9ab3fc70b79a433219e1e87193b4f2b77251d058d14"},
|
||||
{file = "ruff-0.6.4.tar.gz", hash = "sha256:ac3b5bfbee99973f80aa1b7cbd1c9cbce200883bdd067300c22a6cc1c7fba212"},
|
||||
{file = "ruff-0.6.5-py3-none-linux_armv6l.whl", hash = "sha256:7e4e308f16e07c95fc7753fc1aaac690a323b2bb9f4ec5e844a97bb7fbebd748"},
|
||||
{file = "ruff-0.6.5-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:932cd69eefe4daf8c7d92bd6689f7e8182571cb934ea720af218929da7bd7d69"},
|
||||
{file = "ruff-0.6.5-py3-none-macosx_11_0_arm64.whl", hash = "sha256:3a8d42d11fff8d3143ff4da41742a98f8f233bf8890e9fe23077826818f8d680"},
|
||||
{file = "ruff-0.6.5-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a50af6e828ee692fb10ff2dfe53f05caecf077f4210fae9677e06a808275754f"},
|
||||
{file = "ruff-0.6.5-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:794ada3400a0d0b89e3015f1a7e01f4c97320ac665b7bc3ade24b50b54cb2972"},
|
||||
{file = "ruff-0.6.5-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:381413ec47f71ce1d1c614f7779d88886f406f1fd53d289c77e4e533dc6ea200"},
|
||||
{file = "ruff-0.6.5-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:52e75a82bbc9b42e63c08d22ad0ac525117e72aee9729a069d7c4f235fc4d276"},
|
||||
{file = "ruff-0.6.5-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:09c72a833fd3551135ceddcba5ebdb68ff89225d30758027280968c9acdc7810"},
|
||||
{file = "ruff-0.6.5-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:800c50371bdcb99b3c1551d5691e14d16d6f07063a518770254227f7f6e8c178"},
|
||||
{file = "ruff-0.6.5-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8e25ddd9cd63ba1f3bd51c1f09903904a6adf8429df34f17d728a8fa11174253"},
|
||||
{file = "ruff-0.6.5-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:7291e64d7129f24d1b0c947ec3ec4c0076e958d1475c61202497c6aced35dd19"},
|
||||
{file = "ruff-0.6.5-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:9ad7dfbd138d09d9a7e6931e6a7e797651ce29becd688be8a0d4d5f8177b4b0c"},
|
||||
{file = "ruff-0.6.5-py3-none-musllinux_1_2_i686.whl", hash = "sha256:005256d977021790cc52aa23d78f06bb5090dc0bfbd42de46d49c201533982ae"},
|
||||
{file = "ruff-0.6.5-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:482c1e6bfeb615eafc5899127b805d28e387bd87db38b2c0c41d271f5e58d8cc"},
|
||||
{file = "ruff-0.6.5-py3-none-win32.whl", hash = "sha256:cf4d3fa53644137f6a4a27a2b397381d16454a1566ae5335855c187fbf67e4f5"},
|
||||
{file = "ruff-0.6.5-py3-none-win_amd64.whl", hash = "sha256:3e42a57b58e3612051a636bc1ac4e6b838679530235520e8f095f7c44f706ff9"},
|
||||
{file = "ruff-0.6.5-py3-none-win_arm64.whl", hash = "sha256:51935067740773afdf97493ba9b8231279e9beef0f2a8079188c4776c25688e0"},
|
||||
{file = "ruff-0.6.5.tar.gz", hash = "sha256:4d32d87fab433c0cf285c3683dd4dae63be05fd7a1d65b3f5bf7cdd05a6b96fb"},
|
||||
]
|
||||
|
||||
[package.source]
|
||||
@@ -5013,103 +5013,103 @@ reference = "offical-source"
|
||||
|
||||
[[package]]
|
||||
name = "yarl"
|
||||
version = "1.11.0"
|
||||
version = "1.11.1"
|
||||
description = "Yet another URL library"
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "yarl-1.11.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:0a657db1b9982f3dac0e360614d0e8945d2873da6e681fb7fca23ef1c3eb37f8"},
|
||||
{file = "yarl-1.11.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:65a1a05efca52b102691e64db5fcf973030a1c88fee393804ff91f99c95a6e74"},
|
||||
{file = "yarl-1.11.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:f4cb417d380e2d77961eecec75aaaf6f7ab14e6de26eb3a498f498029a6556a1"},
|
||||
{file = "yarl-1.11.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8aee7c8378c6aa3103b99d1eb9995268ef730fa9f88ea68b9eee4341e204eec9"},
|
||||
{file = "yarl-1.11.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:84624db40e2358cfd5cf2558b1aaffd93366d27ee32228a97785f2ec87d44a17"},
|
||||
{file = "yarl-1.11.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2a596bb15e036952549871a4ccd2205679902dc7f241e3ced6b2ab2e44c55795"},
|
||||
{file = "yarl-1.11.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c9d4d2cc4b076c8ad0175a15ee9482a387b3303c97d4b71062db7356b2ac04c7"},
|
||||
{file = "yarl-1.11.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:25f8bc849004122591104793a576e9c747b0e5d9486d6a30225521b817255748"},
|
||||
{file = "yarl-1.11.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:e38176a559edde0cfff4b663791a007a5f9f90c73aee1d6f7ddbcf6bfb7287b3"},
|
||||
{file = "yarl-1.11.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:706ac0f77b45e9e0278ec6c98929764e119d3ce3136792b6475e7ae961da53ec"},
|
||||
{file = "yarl-1.11.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:48bac099586cf75ae5837b0ac17a674450d01f451f38afcb02acfc940110b60b"},
|
||||
{file = "yarl-1.11.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:540fd5f62fe21f3d1d9efe8af5c4d9dbbb184ce03ce95acb0289500e46215dd2"},
|
||||
{file = "yarl-1.11.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:05ab59db0bb64e847972373c5cda8924e6605480f6b13cc04573fa0d87bfc637"},
|
||||
{file = "yarl-1.11.0-cp310-cp310-win32.whl", hash = "sha256:ddab47748933ac9cf5f29d6e9e2e2060cff40b2751d02c55129661ea4e577152"},
|
||||
{file = "yarl-1.11.0-cp310-cp310-win_amd64.whl", hash = "sha256:976d02274e6d88b24c7131e7b26a083412b2592f2bbcef53d3b00b2508cad26c"},
|
||||
{file = "yarl-1.11.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:39e3087e1ef70862de81e22af9eb299faee580f41673ef92829949022791b521"},
|
||||
{file = "yarl-1.11.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:7fd535cc41b81a566ad347081b671ab5c7e5f5b6a15526d85b4e748baf065cf0"},
|
||||
{file = "yarl-1.11.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f7cc02d8e9a612174869f4b983f159e87659096f7e2dc1fe9effd9902e408739"},
|
||||
{file = "yarl-1.11.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:30f391ccf4b1b1e0ba4880075ba337d41a619a5350f67053927f67ebe764bf44"},
|
||||
{file = "yarl-1.11.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4c19a0d95943bb2c914b4e71043803be34bc75c08c4a6ca232bdc649a1e9ef1b"},
|
||||
{file = "yarl-1.11.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ead4d89eade0e09b8ef97877664abb0e2e8704787db5564f83658fdee5c36497"},
|
||||
{file = "yarl-1.11.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:195f7791bc23d5f2480efe53f935daf8a61661000dfbfbdd70dbd06397594fff"},
|
||||
{file = "yarl-1.11.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:01a7905e662665ca8e058635377522bc3c98bdb873be761ff42c86eb72b03914"},
|
||||
{file = "yarl-1.11.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:53c80b1927b75aed208d7fd965a3a705dc8c1db4d50b9112418fa0f7784363e6"},
|
||||
{file = "yarl-1.11.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:11af21bbf807688d49b7d4915bb28cbc2e3aa028a2ee194738477eabcc413c65"},
|
||||
{file = "yarl-1.11.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:732d56da00ea7a5da4f0d15adbbd22dcb37da7825510aafde40112e53f6baa52"},
|
||||
{file = "yarl-1.11.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:7bd54d79025b59d1dc5fb26a09734d6a9cc651a04bc381966ed264b28331a168"},
|
||||
{file = "yarl-1.11.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:aacd62ff67efd54cb18cea2aa7ae4fb83cfbca19a07055d4777266b70561defe"},
|
||||
{file = "yarl-1.11.0-cp311-cp311-win32.whl", hash = "sha256:68e14ae71e5b51c8282ae5db53ccb3baffc40e1551370a8a2361f1c1d8a0bf8c"},
|
||||
{file = "yarl-1.11.0-cp311-cp311-win_amd64.whl", hash = "sha256:3ade2265716667b6bd4123d6f684b5f7cf4a8d83dcf1d5581ac44643466bb00a"},
|
||||
{file = "yarl-1.11.0-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:6e73dab98e3c3b5441720153e72a5f28e717aac2d22f1ec4b08ef33417d9987e"},
|
||||
{file = "yarl-1.11.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:4a0d090d296ced05edfe29c6ff34869412fa6a97d0928c12b00939c4842884cd"},
|
||||
{file = "yarl-1.11.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:d29e446cfb0a82d3df7745968b9fa286665a9be8b4d68de46bcc32d917cb218e"},
|
||||
{file = "yarl-1.11.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4c8dc0efcf8266ecfe057b95e01f43eb62516196a4bbf3918fd1dcb8d0dc0dff"},
|
||||
{file = "yarl-1.11.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:202f5ec49ff163dcc767426deb55020a28078e61d6bbe1f80331d92bca53b236"},
|
||||
{file = "yarl-1.11.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8055b0d78ce1cafa657c4b455e22661e8d3b2834de66a0753c3567da47fcc4aa"},
|
||||
{file = "yarl-1.11.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:60ed3c7f64e820959d7f682ec2f559b4f4df723dc09df619d269853a4214a4b4"},
|
||||
{file = "yarl-1.11.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2371510367d39d74997acfdcd1dead17938c79c99365482821627f7838a8eba0"},
|
||||
{file = "yarl-1.11.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:e24bb6a8be89ccc3ce8c47e8940fdfcb7429e9efbf65ce6fa3e7d122fcf0bcf0"},
|
||||
{file = "yarl-1.11.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:18ec42da256cfcb9b4cd5d253e04c291f69911a5228d1438a7d431c15ba0ae40"},
|
||||
{file = "yarl-1.11.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:418eeb8f228ea36c368bf6782ebd6016ecebfb1a8b90145ef6726ffcbba65ef8"},
|
||||
{file = "yarl-1.11.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:07e8cfb1dd7669a129f8fd5df1da65efa73aea77582bde2a3a837412e2863543"},
|
||||
{file = "yarl-1.11.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:3c458483711d393dad51340505c3fab3194748fd06bab311d2f8b5b7a7349e9a"},
|
||||
{file = "yarl-1.11.0-cp312-cp312-win32.whl", hash = "sha256:5b008c3127382503e7a1e12b4c3a3236e3dd833a4c62a066f4a0fbd650c655d2"},
|
||||
{file = "yarl-1.11.0-cp312-cp312-win_amd64.whl", hash = "sha256:bc94be7472b9f88d7441340534a3ecae05c86ccfec7ba75ce5b6e4778b2bfc6e"},
|
||||
{file = "yarl-1.11.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:a45e51ba3777031e0b20c1e7ab59114ed4e1884b3c1db48962c1d8d08aefb418"},
|
||||
{file = "yarl-1.11.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:765128029218eade3a01187cdd7f375977cc827505ed31828196c8ae9b622928"},
|
||||
{file = "yarl-1.11.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:2516e238daf0339c8ac4dfab9d7cda9afad652ff073517f200d653d5d8371f7e"},
|
||||
{file = "yarl-1.11.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d10be62bee117f05b1ad75a6c2538ca9e5367342dc8a4f3c206c87dadbc1189c"},
|
||||
{file = "yarl-1.11.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:50ceaeda771ee3e382291168c90c7ede62b63ecf3e181024bcfeb35c0ea6c84f"},
|
||||
{file = "yarl-1.11.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3a601c99fc20fd0eea84e7bc0dc9e7f196f55a0ded67242d724988c754295538"},
|
||||
{file = "yarl-1.11.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:42ff79371614764fc0a4ab8eaba9adb493bf9ad856e2a4664f6c754fc907a903"},
|
||||
{file = "yarl-1.11.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:93fca4c9f88c17ead902b3f3285b2d039fc8f26d117e1441973ba64315109b54"},
|
||||
{file = "yarl-1.11.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:e7dddf5f41395c84fc59e0ed5493b24bfeb39fb04823e880b52c8c55085d4695"},
|
||||
{file = "yarl-1.11.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:ea501ea07e14ba6364ff2621bfc8b2381e5b1e10353927fa9a607057fd2b98e5"},
|
||||
{file = "yarl-1.11.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:a4f7e470f2c9c8b8774a5bda72adfb8e9dc4ec32311fe9bdaa4921e36cf6659b"},
|
||||
{file = "yarl-1.11.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:361fdb3993431157302b7104d525092b5df4d7d346df5a5ffeee2d1ca8e0d15b"},
|
||||
{file = "yarl-1.11.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:e300eaf5e0329ad31b3d53e2f3d26b4b6dff1217207c6ab1d4212967b54b2185"},
|
||||
{file = "yarl-1.11.0-cp313-cp313-win32.whl", hash = "sha256:f1e2d4ce72e06e38a16da3e9c24a0520dbc19018a69ef6ed57b6b38527cb275c"},
|
||||
{file = "yarl-1.11.0-cp313-cp313-win_amd64.whl", hash = "sha256:fa9de2f87be58f714a230bd1f3ef3aad1ed65c9931146e3fc55f85fcbe6bacc3"},
|
||||
{file = "yarl-1.11.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:24da0b38274727fe9266d09229987e7f0efdb97beb94c0bb2d327d65f112e78d"},
|
||||
{file = "yarl-1.11.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:0310eb2e63872de66047e05ad9982f2e53ad6405dc42fa60d7cc670bf6ca8aa8"},
|
||||
{file = "yarl-1.11.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:52433604340a4ab3d1f32281c6eb9ad9b47c99435b4212f763121bf7348c8c00"},
|
||||
{file = "yarl-1.11.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:98e2eb182d59f0845a79434003f94b4f61cd69465248f9388c2e5bf2191c9f7f"},
|
||||
{file = "yarl-1.11.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b3dd10f0fe0e0f659926c1da791de5bef05fd48974ad74618c9168e302e2b7cc"},
|
||||
{file = "yarl-1.11.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:121d3798e4bb35a4321b2422cb887f80ea39f94bf52f0eb5cb2c168bb0043c9b"},
|
||||
{file = "yarl-1.11.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b8bbac56c80610dd659ace534765d7bcd2488f6600023f6984f35108b2b3f4f0"},
|
||||
{file = "yarl-1.11.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:79d420399f0e82e302236a762d8b8ceec89761ce3b30c83ac1d4d6e29f811444"},
|
||||
{file = "yarl-1.11.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:03a726fb50588307dfe1d233b67535d493fb0bb157bdbfda6bb34e04189f2f57"},
|
||||
{file = "yarl-1.11.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:9057f5de2fade7440e6db358913bc7ae8de43ba72c83cf95420a1fc1a6c6b59e"},
|
||||
{file = "yarl-1.11.0-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:6471d747d0ac8059895e66d32ca8630c8db5b572ca7763150d0927eaa257df67"},
|
||||
{file = "yarl-1.11.0-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:d97cb22ad380850754fa16ef8d490d9340d8573d81f73429f3975e8e87db0586"},
|
||||
{file = "yarl-1.11.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:fe78dec8caeda1e7b353cbd8aa0cc5a5bc182b22998d64ec8fa9ee59c898ab3b"},
|
||||
{file = "yarl-1.11.0-cp38-cp38-win32.whl", hash = "sha256:7ff371002fbbb79613269d76a2932c99979dac15fac30107064ef70d25f35474"},
|
||||
{file = "yarl-1.11.0-cp38-cp38-win_amd64.whl", hash = "sha256:4fa9d762eee63eed767895d68b994c58e29f809292a4d0fca483e9cc6fdc22c8"},
|
||||
{file = "yarl-1.11.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:4ae63bc65e5bf8843bd1eca46e75eaa9eb157e0312fb362123181512892daad8"},
|
||||
{file = "yarl-1.11.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:3d1bd3262e00043907e0a6d7d4f7b7a4815281acc25699a2384552870c79f1f0"},
|
||||
{file = "yarl-1.11.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:0c58656c2e0b41b5d325130b8da4f8e216aad10029e7de5c523a6be25faa9fe8"},
|
||||
{file = "yarl-1.11.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9425c333575fce5e0fb414b766492c6ba4aa335ef910a7540dbdefe58a78232e"},
|
||||
{file = "yarl-1.11.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9dc66e2420e1e282105071934883bbb9c37c16901b5b8aa0a8aee370b477eac6"},
|
||||
{file = "yarl-1.11.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2949067359d1ef5bf3228c7f1deb102c209832a13df5419239f99449bc1d3fa9"},
|
||||
{file = "yarl-1.11.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c006fe73f851cf20b9986b3b4cc15239795bd5da9c3fda76bb3e043da5bec4ff"},
|
||||
{file = "yarl-1.11.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:969ad4ee3892e893471b6572bbf2bbb091f93e7c81de25d6b3a5c0a5126e5ccb"},
|
||||
{file = "yarl-1.11.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:c9fbe9dc6ee8bfe1af34137e3add6f0e49799dd5467dd6af189d27616879161e"},
|
||||
{file = "yarl-1.11.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:69a45c711fea9b783b592a75f26f6dc59b2e4a923b97bf6eec357566fcb1d922"},
|
||||
{file = "yarl-1.11.0-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:1a29b82c42a7791ffe53ee6dfbf29acc61ea7ec05643dcacc50510ed6187b897"},
|
||||
{file = "yarl-1.11.0-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:ed0c090f00c3fc024f7b0799cab9dd7c419fcd8f1a00634d1f9952bab7e7bfb2"},
|
||||
{file = "yarl-1.11.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:31df9d9b3fe6e15decee629fc7976a5fb21eaa39e290f60e57e1d422827194c6"},
|
||||
{file = "yarl-1.11.0-cp39-cp39-win32.whl", hash = "sha256:fcb7c36ba8b663a5900e6d40533f0e698ba0f38f744aad5410d4e38129e41a70"},
|
||||
{file = "yarl-1.11.0-cp39-cp39-win_amd64.whl", hash = "sha256:c6c0d640bad721834a737e25267fb71d296684ada21ca7d5ad2e63da7b73f1b7"},
|
||||
{file = "yarl-1.11.0-py3-none-any.whl", hash = "sha256:03717a6627e55934b2a1d9caf24f299b461a2e8d048a90920f42ad5c20ae1b82"},
|
||||
{file = "yarl-1.11.0.tar.gz", hash = "sha256:f86f4f4a57a29ef08fa70c4667d04c5e3ba513500da95586208b285437cb9592"},
|
||||
{file = "yarl-1.11.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:400cd42185f92de559d29eeb529e71d80dfbd2f45c36844914a4a34297ca6f00"},
|
||||
{file = "yarl-1.11.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:8258c86f47e080a258993eed877d579c71da7bda26af86ce6c2d2d072c11320d"},
|
||||
{file = "yarl-1.11.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2164cd9725092761fed26f299e3f276bb4b537ca58e6ff6b252eae9631b5c96e"},
|
||||
{file = "yarl-1.11.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a08ea567c16f140af8ddc7cb58e27e9138a1386e3e6e53982abaa6f2377b38cc"},
|
||||
{file = "yarl-1.11.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:768ecc550096b028754ea28bf90fde071c379c62c43afa574edc6f33ee5daaec"},
|
||||
{file = "yarl-1.11.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2909fa3a7d249ef64eeb2faa04b7957e34fefb6ec9966506312349ed8a7e77bf"},
|
||||
{file = "yarl-1.11.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:01a8697ec24f17c349c4f655763c4db70eebc56a5f82995e5e26e837c6eb0e49"},
|
||||
{file = "yarl-1.11.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e286580b6511aac7c3268a78cdb861ec739d3e5a2a53b4809faef6b49778eaff"},
|
||||
{file = "yarl-1.11.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:4179522dc0305c3fc9782549175c8e8849252fefeb077c92a73889ccbcd508ad"},
|
||||
{file = "yarl-1.11.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:27fcb271a41b746bd0e2a92182df507e1c204759f460ff784ca614e12dd85145"},
|
||||
{file = "yarl-1.11.1-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:f61db3b7e870914dbd9434b560075e0366771eecbe6d2b5561f5bc7485f39efd"},
|
||||
{file = "yarl-1.11.1-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:c92261eb2ad367629dc437536463dc934030c9e7caca861cc51990fe6c565f26"},
|
||||
{file = "yarl-1.11.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:d95b52fbef190ca87d8c42f49e314eace4fc52070f3dfa5f87a6594b0c1c6e46"},
|
||||
{file = "yarl-1.11.1-cp310-cp310-win32.whl", hash = "sha256:489fa8bde4f1244ad6c5f6d11bb33e09cf0d1d0367edb197619c3e3fc06f3d91"},
|
||||
{file = "yarl-1.11.1-cp310-cp310-win_amd64.whl", hash = "sha256:476e20c433b356e16e9a141449f25161e6b69984fb4cdbd7cd4bd54c17844998"},
|
||||
{file = "yarl-1.11.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:946eedc12895873891aaceb39bceb484b4977f70373e0122da483f6c38faaa68"},
|
||||
{file = "yarl-1.11.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:21a7c12321436b066c11ec19c7e3cb9aec18884fe0d5b25d03d756a9e654edfe"},
|
||||
{file = "yarl-1.11.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:c35f493b867912f6fda721a59cc7c4766d382040bdf1ddaeeaa7fa4d072f4675"},
|
||||
{file = "yarl-1.11.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:25861303e0be76b60fddc1250ec5986c42f0a5c0c50ff57cc30b1be199c00e63"},
|
||||
{file = "yarl-1.11.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e4b53f73077e839b3f89c992223f15b1d2ab314bdbdf502afdc7bb18e95eae27"},
|
||||
{file = "yarl-1.11.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:327c724b01b8641a1bf1ab3b232fb638706e50f76c0b5bf16051ab65c868fac5"},
|
||||
{file = "yarl-1.11.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4307d9a3417eea87715c9736d050c83e8c1904e9b7aada6ce61b46361b733d92"},
|
||||
{file = "yarl-1.11.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:48a28bed68ab8fb7e380775f0029a079f08a17799cb3387a65d14ace16c12e2b"},
|
||||
{file = "yarl-1.11.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:067b961853c8e62725ff2893226fef3d0da060656a9827f3f520fb1d19b2b68a"},
|
||||
{file = "yarl-1.11.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:8215f6f21394d1f46e222abeb06316e77ef328d628f593502d8fc2a9117bde83"},
|
||||
{file = "yarl-1.11.1-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:498442e3af2a860a663baa14fbf23fb04b0dd758039c0e7c8f91cb9279799bff"},
|
||||
{file = "yarl-1.11.1-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:69721b8effdb588cb055cc22f7c5105ca6fdaa5aeb3ea09021d517882c4a904c"},
|
||||
{file = "yarl-1.11.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:1e969fa4c1e0b1a391f3fcbcb9ec31e84440253325b534519be0d28f4b6b533e"},
|
||||
{file = "yarl-1.11.1-cp311-cp311-win32.whl", hash = "sha256:7d51324a04fc4b0e097ff8a153e9276c2593106a811704025bbc1d6916f45ca6"},
|
||||
{file = "yarl-1.11.1-cp311-cp311-win_amd64.whl", hash = "sha256:15061ce6584ece023457fb8b7a7a69ec40bf7114d781a8c4f5dcd68e28b5c53b"},
|
||||
{file = "yarl-1.11.1-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:a4264515f9117be204935cd230fb2a052dd3792789cc94c101c535d349b3dab0"},
|
||||
{file = "yarl-1.11.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:f41fa79114a1d2eddb5eea7b912d6160508f57440bd302ce96eaa384914cd265"},
|
||||
{file = "yarl-1.11.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:02da8759b47d964f9173c8675710720b468aa1c1693be0c9c64abb9d8d9a4867"},
|
||||
{file = "yarl-1.11.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9361628f28f48dcf8b2f528420d4d68102f593f9c2e592bfc842f5fb337e44fd"},
|
||||
{file = "yarl-1.11.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b91044952da03b6f95fdba398d7993dd983b64d3c31c358a4c89e3c19b6f7aef"},
|
||||
{file = "yarl-1.11.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:74db2ef03b442276d25951749a803ddb6e270d02dda1d1c556f6ae595a0d76a8"},
|
||||
{file = "yarl-1.11.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7e975a2211952a8a083d1b9d9ba26472981ae338e720b419eb50535de3c02870"},
|
||||
{file = "yarl-1.11.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8aef97ba1dd2138112890ef848e17d8526fe80b21f743b4ee65947ea184f07a2"},
|
||||
{file = "yarl-1.11.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:a7915ea49b0c113641dc4d9338efa9bd66b6a9a485ffe75b9907e8573ca94b84"},
|
||||
{file = "yarl-1.11.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:504cf0d4c5e4579a51261d6091267f9fd997ef58558c4ffa7a3e1460bd2336fa"},
|
||||
{file = "yarl-1.11.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:3de5292f9f0ee285e6bd168b2a77b2a00d74cbcfa420ed078456d3023d2f6dff"},
|
||||
{file = "yarl-1.11.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:a34e1e30f1774fa35d37202bbeae62423e9a79d78d0874e5556a593479fdf239"},
|
||||
{file = "yarl-1.11.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:66b63c504d2ca43bf7221a1f72fbe981ff56ecb39004c70a94485d13e37ebf45"},
|
||||
{file = "yarl-1.11.1-cp312-cp312-win32.whl", hash = "sha256:a28b70c9e2213de425d9cba5ab2e7f7a1c8ca23a99c4b5159bf77b9c31251447"},
|
||||
{file = "yarl-1.11.1-cp312-cp312-win_amd64.whl", hash = "sha256:17b5a386d0d36fb828e2fb3ef08c8829c1ebf977eef88e5367d1c8c94b454639"},
|
||||
{file = "yarl-1.11.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:1fa2e7a406fbd45b61b4433e3aa254a2c3e14c4b3186f6e952d08a730807fa0c"},
|
||||
{file = "yarl-1.11.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:750f656832d7d3cb0c76be137ee79405cc17e792f31e0a01eee390e383b2936e"},
|
||||
{file = "yarl-1.11.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:0b8486f322d8f6a38539136a22c55f94d269addb24db5cb6f61adc61eabc9d93"},
|
||||
{file = "yarl-1.11.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3fce4da3703ee6048ad4138fe74619c50874afe98b1ad87b2698ef95bf92c96d"},
|
||||
{file = "yarl-1.11.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8ed653638ef669e0efc6fe2acb792275cb419bf9cb5c5049399f3556995f23c7"},
|
||||
{file = "yarl-1.11.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:18ac56c9dd70941ecad42b5a906820824ca72ff84ad6fa18db33c2537ae2e089"},
|
||||
{file = "yarl-1.11.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:688654f8507464745ab563b041d1fb7dab5d9912ca6b06e61d1c4708366832f5"},
|
||||
{file = "yarl-1.11.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4973eac1e2ff63cf187073cd4e1f1148dcd119314ab79b88e1b3fad74a18c9d5"},
|
||||
{file = "yarl-1.11.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:964a428132227edff96d6f3cf261573cb0f1a60c9a764ce28cda9525f18f7786"},
|
||||
{file = "yarl-1.11.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:6d23754b9939cbab02c63434776df1170e43b09c6a517585c7ce2b3d449b7318"},
|
||||
{file = "yarl-1.11.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:c2dc4250fe94d8cd864d66018f8344d4af50e3758e9d725e94fecfa27588ff82"},
|
||||
{file = "yarl-1.11.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:09696438cb43ea6f9492ef237761b043f9179f455f405279e609f2bc9100212a"},
|
||||
{file = "yarl-1.11.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:999bfee0a5b7385a0af5ffb606393509cfde70ecca4f01c36985be6d33e336da"},
|
||||
{file = "yarl-1.11.1-cp313-cp313-win32.whl", hash = "sha256:ce928c9c6409c79e10f39604a7e214b3cb69552952fbda8d836c052832e6a979"},
|
||||
{file = "yarl-1.11.1-cp313-cp313-win_amd64.whl", hash = "sha256:501c503eed2bb306638ccb60c174f856cc3246c861829ff40eaa80e2f0330367"},
|
||||
{file = "yarl-1.11.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:dae7bd0daeb33aa3e79e72877d3d51052e8b19c9025ecf0374f542ea8ec120e4"},
|
||||
{file = "yarl-1.11.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:3ff6b1617aa39279fe18a76c8d165469c48b159931d9b48239065767ee455b2b"},
|
||||
{file = "yarl-1.11.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:3257978c870728a52dcce8c2902bf01f6c53b65094b457bf87b2644ee6238ddc"},
|
||||
{file = "yarl-1.11.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0f351fa31234699d6084ff98283cb1e852270fe9e250a3b3bf7804eb493bd937"},
|
||||
{file = "yarl-1.11.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8aef1b64da41d18026632d99a06b3fefe1d08e85dd81d849fa7c96301ed22f1b"},
|
||||
{file = "yarl-1.11.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7175a87ab8f7fbde37160a15e58e138ba3b2b0e05492d7351314a250d61b1591"},
|
||||
{file = "yarl-1.11.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba444bdd4caa2a94456ef67a2f383710928820dd0117aae6650a4d17029fa25e"},
|
||||
{file = "yarl-1.11.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0ea9682124fc062e3d931c6911934a678cb28453f957ddccf51f568c2f2b5e05"},
|
||||
{file = "yarl-1.11.1-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:8418c053aeb236b20b0ab8fa6bacfc2feaaf7d4683dd96528610989c99723d5f"},
|
||||
{file = "yarl-1.11.1-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:61a5f2c14d0a1adfdd82258f756b23a550c13ba4c86c84106be4c111a3a4e413"},
|
||||
{file = "yarl-1.11.1-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:f3a6d90cab0bdf07df8f176eae3a07127daafcf7457b997b2bf46776da2c7eb7"},
|
||||
{file = "yarl-1.11.1-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:077da604852be488c9a05a524068cdae1e972b7dc02438161c32420fb4ec5e14"},
|
||||
{file = "yarl-1.11.1-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:15439f3c5c72686b6c3ff235279630d08936ace67d0fe5c8d5bbc3ef06f5a420"},
|
||||
{file = "yarl-1.11.1-cp38-cp38-win32.whl", hash = "sha256:238a21849dd7554cb4d25a14ffbfa0ef380bb7ba201f45b144a14454a72ffa5a"},
|
||||
{file = "yarl-1.11.1-cp38-cp38-win_amd64.whl", hash = "sha256:67459cf8cf31da0e2cbdb4b040507e535d25cfbb1604ca76396a3a66b8ba37a6"},
|
||||
{file = "yarl-1.11.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:884eab2ce97cbaf89f264372eae58388862c33c4f551c15680dd80f53c89a269"},
|
||||
{file = "yarl-1.11.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:8a336eaa7ee7e87cdece3cedb395c9657d227bfceb6781295cf56abcd3386a26"},
|
||||
{file = "yarl-1.11.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:87f020d010ba80a247c4abc335fc13421037800ca20b42af5ae40e5fd75e7909"},
|
||||
{file = "yarl-1.11.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:637c7ddb585a62d4469f843dac221f23eec3cbad31693b23abbc2c366ad41ff4"},
|
||||
{file = "yarl-1.11.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:48dfd117ab93f0129084577a07287376cc69c08138694396f305636e229caa1a"},
|
||||
{file = "yarl-1.11.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:75e0ae31fb5ccab6eda09ba1494e87eb226dcbd2372dae96b87800e1dcc98804"},
|
||||
{file = "yarl-1.11.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f46f81501160c28d0c0b7333b4f7be8983dbbc161983b6fb814024d1b4952f79"},
|
||||
{file = "yarl-1.11.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:04293941646647b3bfb1719d1d11ff1028e9c30199509a844da3c0f5919dc520"},
|
||||
{file = "yarl-1.11.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:250e888fa62d73e721f3041e3a9abf427788a1934b426b45e1b92f62c1f68366"},
|
||||
{file = "yarl-1.11.1-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:e8f63904df26d1a66aabc141bfd258bf738b9bc7bc6bdef22713b4f5ef789a4c"},
|
||||
{file = "yarl-1.11.1-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:aac44097d838dda26526cffb63bdd8737a2dbdf5f2c68efb72ad83aec6673c7e"},
|
||||
{file = "yarl-1.11.1-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:267b24f891e74eccbdff42241c5fb4f974de2d6271dcc7d7e0c9ae1079a560d9"},
|
||||
{file = "yarl-1.11.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:6907daa4b9d7a688063ed098c472f96e8181733c525e03e866fb5db480a424df"},
|
||||
{file = "yarl-1.11.1-cp39-cp39-win32.whl", hash = "sha256:14438dfc5015661f75f85bc5adad0743678eefee266ff0c9a8e32969d5d69f74"},
|
||||
{file = "yarl-1.11.1-cp39-cp39-win_amd64.whl", hash = "sha256:94d0caaa912bfcdc702a4204cd5e2bb01eb917fc4f5ea2315aa23962549561b0"},
|
||||
{file = "yarl-1.11.1-py3-none-any.whl", hash = "sha256:72bf26f66456baa0584eff63e44545c9f0eaed9b73cb6601b647c91f14c11f38"},
|
||||
{file = "yarl-1.11.1.tar.gz", hash = "sha256:1bb2d9e212fb7449b8fb73bc461b51eaa17cc8430b4a87d87be7b25052d92f53"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
@@ -5129,4 +5129,4 @@ yaml = []
|
||||
[metadata]
|
||||
lock-version = "2.0"
|
||||
python-versions = ">=3.10,<4.0.0"
|
||||
content-hash = "0d6702e9c2ba4213fabab50083389aa44e4625b25edaf5a52f76e0e510b887db"
|
||||
content-hash = "02cf0461830f2012ad533f01d152e7b4abb9e8bd94158956a73369f4f91c96b6"
|
||||
|
||||
+5
-5
@@ -26,7 +26,7 @@ beautifulsoup4 = ">=4.12.3"
|
||||
feedparser = "^6.0.11"
|
||||
httpx = ">=0.27.2"
|
||||
nonebot2 = { extras = ["fastapi"], version = "^2.3.3" }
|
||||
nonebot-adapter-onebot = "^2.4.4"
|
||||
nonebot-adapter-onebot = "^2.4.5"
|
||||
nonebot-plugin-htmlrender = ">=0.3.5"
|
||||
nonebot-plugin-datastore = ">=1.3.0,<2.0.0"
|
||||
nonebot-plugin-apscheduler = ">=0.5.0"
|
||||
@@ -36,9 +36,9 @@ pyjwt = "^2.9.0"
|
||||
python-socketio = "^5.11.4"
|
||||
tinydb = "^4.8.0"
|
||||
qrcode = "^7.4.2"
|
||||
pydantic = ">=2.9.0,<3.0.0,!=2.5.0,!=2.5.1"
|
||||
pydantic = ">=2.9.2,<3.0.0,!=2.5.0,!=2.5.1"
|
||||
lxml = ">=5.3.0"
|
||||
yarl = ">=1.11.0"
|
||||
yarl = ">=1.11.1"
|
||||
hishel = "^0.0.30"
|
||||
expiringdictx = "^1.1.0"
|
||||
rapidfuzz = "^3.9.7"
|
||||
@@ -50,13 +50,13 @@ isort = "^5.13.2"
|
||||
nonemoji = "^0.1.4"
|
||||
nb-cli = "^1.4.2"
|
||||
pre-commit = "^3.8.0"
|
||||
ruff = "^0.6.4"
|
||||
ruff = "^0.6.5"
|
||||
|
||||
[tool.poetry.group.test.dependencies]
|
||||
flaky = "^3.8.1"
|
||||
nonebug = "^0.3.7"
|
||||
nonebug-saa = "^0.4.1"
|
||||
pytest = ">=8.3.2,<9.0.0"
|
||||
pytest = ">=8.3.3,<9.0.0"
|
||||
pytest-asyncio = ">=0.24.0,<0.24.1"
|
||||
pytest-cov = ">=5.0.0,<6"
|
||||
pytest-mock = "^3.14.0"
|
||||
|
||||
@@ -1,123 +0,0 @@
|
||||
import json
|
||||
from typing import cast
|
||||
from datetime import datetime
|
||||
|
||||
import pytest
|
||||
from nonebug import App
|
||||
|
||||
|
||||
async def test_cookie(app: App, init_scheduler):
|
||||
from nonebot_plugin_saa import TargetQQGroup
|
||||
|
||||
from nonebot_bison.platform import site_manager
|
||||
from nonebot_bison.config.db_config import config
|
||||
from nonebot_bison.types import Target as T_Target
|
||||
from nonebot_bison.utils.site import CookieClientManager
|
||||
from nonebot_bison.config.utils import DuplicateCookieTargetException
|
||||
|
||||
target = T_Target("weibo_id")
|
||||
platform_name = "weibo"
|
||||
await config.add_subscribe(
|
||||
TargetQQGroup(group_id=123),
|
||||
target=target,
|
||||
target_name="weibo_name",
|
||||
platform_name=platform_name,
|
||||
cats=[],
|
||||
tags=[],
|
||||
)
|
||||
site = site_manager["weibo.com"]
|
||||
client_mgr = cast(CookieClientManager, site.client_mgr)
|
||||
|
||||
# 刷新匿名cookie
|
||||
await client_mgr.refresh_anonymous_cookie()
|
||||
|
||||
cookies = await config.get_cookie(site_name=site.name)
|
||||
assert len(cookies) == 1
|
||||
|
||||
# 添加用户cookie
|
||||
await client_mgr.add_user_cookie(json.dumps({"test_cookie": "1"}))
|
||||
await client_mgr.add_user_cookie(json.dumps({"test_cookie": "2"}))
|
||||
|
||||
cookies = await config.get_cookie(site_name=site.name)
|
||||
assert len(cookies) == 3
|
||||
|
||||
cookies = await config.get_cookie(site_name=site.name, is_anonymous=False)
|
||||
assert len(cookies) == 2
|
||||
|
||||
# 单个target,多个cookie
|
||||
await config.add_cookie_target(target, platform_name, cookies[0].id)
|
||||
await config.add_cookie_target(target, platform_name, cookies[1].id)
|
||||
|
||||
cookies = await config.get_cookie(site_name=site.name, target=target)
|
||||
assert len(cookies) == 3
|
||||
|
||||
cookies = await config.get_cookie(site_name=site.name, target=target, is_anonymous=False)
|
||||
assert len(cookies) == 2
|
||||
|
||||
cookies = await config.get_cookie(site_name=site.name, target=target, is_universal=False)
|
||||
assert len(cookies) == 2
|
||||
|
||||
# 测试不同的target
|
||||
target2 = T_Target("weibo_id2")
|
||||
await config.add_subscribe(
|
||||
TargetQQGroup(group_id=123),
|
||||
target=target2,
|
||||
target_name="weibo_name2",
|
||||
platform_name=platform_name,
|
||||
cats=[],
|
||||
tags=[],
|
||||
)
|
||||
await client_mgr.add_user_cookie(json.dumps({"test_cookie": "3"}))
|
||||
cookies = await config.get_cookie(site_name=site.name, is_anonymous=False)
|
||||
|
||||
# 多个target,多个cookie
|
||||
await config.add_cookie_target(target2, platform_name, cookies[0].id)
|
||||
await config.add_cookie_target(target2, platform_name, cookies[2].id)
|
||||
|
||||
cookies = await config.get_cookie(site_name=site.name, target=target2)
|
||||
assert len(cookies) == 3
|
||||
|
||||
# 重复关联 target
|
||||
with pytest.raises(DuplicateCookieTargetException) as e:
|
||||
await config.add_cookie_target(target2, platform_name, cookies[2].id)
|
||||
assert isinstance(e.value, DuplicateCookieTargetException)
|
||||
|
||||
cookies = await config.get_cookie(site_name=site.name, target=target2, is_anonymous=False)
|
||||
assert len(cookies) == 2
|
||||
|
||||
# 有关联的cookie不能删除
|
||||
with pytest.raises(Exception, match="cookie") as e:
|
||||
await config.delete_cookie_by_id(cookies[1].id)
|
||||
cookies = await config.get_cookie(site_name=site.name, target=target2, is_anonymous=False)
|
||||
assert len(cookies) == 2
|
||||
|
||||
await config.delete_cookie_target(target2, platform_name, cookies[1].id)
|
||||
await config.delete_cookie_by_id(cookies[1].id)
|
||||
cookies = await config.get_cookie(site_name=site.name, target=target2, is_anonymous=False)
|
||||
assert len(cookies) == 1
|
||||
|
||||
cookie = cookies[0]
|
||||
cookie_id = cookie.id
|
||||
cookie.last_usage = datetime(2024, 9, 13)
|
||||
cookie.status = "test"
|
||||
await config.update_cookie(cookie)
|
||||
cookies = await config.get_cookie(site_name=site.name, target=target2, is_anonymous=False)
|
||||
assert len(cookies) == 1
|
||||
assert cookies[0].id == cookie_id
|
||||
assert cookies[0].last_usage == datetime(2024, 9, 13)
|
||||
assert cookies[0].status == "test"
|
||||
|
||||
# 不存在的 cookie_id
|
||||
cookie.id = 114514
|
||||
with pytest.raises(ValueError, match="cookie") as e:
|
||||
await config.update_cookie(cookie)
|
||||
|
||||
# 获取所有关联对象
|
||||
cookie_targets = await config.get_cookie_target()
|
||||
assert len(cookie_targets) == 3
|
||||
|
||||
# 删除关联对象
|
||||
await config.delete_cookie_target_by_id(cookie_targets[0].id)
|
||||
|
||||
cookie_targets = await config.get_cookie_target()
|
||||
assert len(cookie_targets) == 2
|
||||
@@ -1,212 +0,0 @@
|
||||
import json
|
||||
|
||||
from nonebug.app import App
|
||||
from pytest_mock import MockerFixture
|
||||
|
||||
from ..utils import BotReply, fake_superuser, fake_admin_user, fake_private_message_event
|
||||
|
||||
|
||||
async def test_add_cookie_rule(app: App, mocker: MockerFixture):
|
||||
from nonebot.adapters.onebot.v11.bot import Bot
|
||||
from nonebot.adapters.onebot.v11.message import Message
|
||||
|
||||
from nonebot_bison.plugin_config import plugin_config
|
||||
from nonebot_bison.sub_manager import add_cookie_matcher
|
||||
|
||||
mocker.patch.object(plugin_config, "bison_to_me", True)
|
||||
|
||||
async with app.test_matcher(add_cookie_matcher) as ctx:
|
||||
bot = ctx.create_bot(base=Bot)
|
||||
event = fake_private_message_event(message=Message("添加cookie"), sender=fake_superuser)
|
||||
ctx.receive_event(bot, event)
|
||||
ctx.should_pass_rule()
|
||||
ctx.should_pass_permission()
|
||||
|
||||
async with app.test_matcher(add_cookie_matcher) as ctx:
|
||||
bot = ctx.create_bot(base=Bot)
|
||||
event = fake_private_message_event(message=Message("添加cookie"), sender=fake_admin_user)
|
||||
ctx.receive_event(bot, event)
|
||||
ctx.should_not_pass_rule()
|
||||
ctx.should_pass_permission()
|
||||
|
||||
|
||||
async def test_add_cookie_target_no_cookie(app: App, mocker: MockerFixture):
|
||||
from nonebot.adapters.onebot.v11.bot import Bot
|
||||
from nonebot.adapters.onebot.v11.message import Message
|
||||
|
||||
from nonebot_bison.sub_manager import add_cookie_target_matcher
|
||||
|
||||
async with app.test_matcher(add_cookie_target_matcher) as ctx:
|
||||
bot = ctx.create_bot(base=Bot)
|
||||
from nonebug_saa import should_send_saa
|
||||
from nonebot_plugin_saa import TargetQQGroup, MessageFactory
|
||||
|
||||
from nonebot_bison.config import config
|
||||
from nonebot_bison.types import Target as T_Target
|
||||
|
||||
target = T_Target("weibo_id")
|
||||
platform_name = "weibo"
|
||||
await config.add_subscribe(
|
||||
TargetQQGroup(group_id=123),
|
||||
target=target,
|
||||
target_name="weibo_name",
|
||||
platform_name=platform_name,
|
||||
cats=[],
|
||||
tags=[],
|
||||
)
|
||||
|
||||
event_1 = fake_private_message_event(
|
||||
message=Message("关联cookie"), sender=fake_superuser, to_me=True, user_id=fake_superuser.user_id
|
||||
)
|
||||
ctx.receive_event(bot, event_1)
|
||||
ctx.should_pass_rule()
|
||||
should_send_saa(
|
||||
ctx,
|
||||
MessageFactory(
|
||||
"订阅的帐号为:\n1 weibo weibo_name weibo_id\n []\n请输入要关联 cookie 的订阅的序号\n输入'取消'中止"
|
||||
),
|
||||
bot,
|
||||
event=event_1,
|
||||
)
|
||||
event_2 = fake_private_message_event(
|
||||
message=Message("1"), sender=fake_superuser, to_me=True, user_id=fake_superuser.user_id
|
||||
)
|
||||
ctx.receive_event(bot, event_2)
|
||||
ctx.should_pass_rule()
|
||||
ctx.should_call_send(
|
||||
event_2,
|
||||
"当前平台暂无可关联的 Cookie,请使用“添加cookie”命令添加或检查已关联的 Cookie",
|
||||
True,
|
||||
)
|
||||
|
||||
|
||||
async def test_add_cookie(app: App, mocker: MockerFixture):
|
||||
from nonebot.adapters.onebot.v11.bot import Bot
|
||||
from nonebot.adapters.onebot.v11.message import Message
|
||||
|
||||
from nonebot_bison.platform import platform_manager
|
||||
from nonebot_bison.sub_manager import common_platform, add_cookie_matcher, add_cookie_target_matcher
|
||||
|
||||
async with app.test_matcher(add_cookie_matcher) as ctx:
|
||||
bot = ctx.create_bot(base=Bot)
|
||||
event_1 = fake_private_message_event(
|
||||
message=Message("添加Cookie"), sender=fake_superuser, to_me=True, user_id=fake_superuser.user_id
|
||||
)
|
||||
ctx.receive_event(bot, event_1)
|
||||
ctx.should_pass_rule()
|
||||
ctx.should_call_send(
|
||||
event_1,
|
||||
BotReply.add_reply_on_add_cookie(platform_manager, common_platform),
|
||||
True,
|
||||
)
|
||||
event_2 = fake_private_message_event(
|
||||
message=Message("全部"), sender=fake_superuser, to_me=True, user_id=fake_superuser.user_id
|
||||
)
|
||||
ctx.receive_event(bot, event_2)
|
||||
ctx.should_pass_rule()
|
||||
ctx.should_rejected()
|
||||
ctx.should_call_send(
|
||||
event_2,
|
||||
BotReply.add_reply_on_add_cookie_input_allplatform(platform_manager),
|
||||
True,
|
||||
)
|
||||
event_3 = fake_private_message_event(
|
||||
message=Message("weibo"), sender=fake_superuser, to_me=True, user_id=fake_superuser.user_id
|
||||
)
|
||||
ctx.receive_event(bot, event_3)
|
||||
ctx.should_pass_rule()
|
||||
ctx.should_call_send(event_3, BotReply.add_reply_on_input_cookie)
|
||||
event_4_err = fake_private_message_event(
|
||||
message=Message("test"), sender=fake_superuser, to_me=True, user_id=fake_superuser.user_id
|
||||
)
|
||||
ctx.receive_event(bot, event_4_err)
|
||||
ctx.should_call_send(event_4_err, "无效的 Cookie,请检查后重新输入,详情见<待添加的文档>", True)
|
||||
ctx.should_rejected()
|
||||
event_4_ok = fake_private_message_event(
|
||||
message=Message(json.dumps({"cookie": "test"})),
|
||||
sender=fake_superuser,
|
||||
to_me=True,
|
||||
user_id=fake_superuser.user_id,
|
||||
)
|
||||
ctx.receive_event(bot, event_4_ok)
|
||||
ctx.should_pass_rule()
|
||||
ctx.should_call_send(
|
||||
event_4_ok, '已添加 Cookie: {"cookie": "test"} 到平台 weibo\n请使用“关联cookie”为 Cookie 关联订阅', True
|
||||
)
|
||||
|
||||
async with app.test_matcher(add_cookie_target_matcher) as ctx:
|
||||
from nonebug_saa import should_send_saa
|
||||
from nonebot_plugin_saa import TargetQQGroup, MessageFactory
|
||||
|
||||
from nonebot_bison.config import config
|
||||
from nonebot_bison.types import Target as T_Target
|
||||
|
||||
target = T_Target("weibo_id")
|
||||
platform_name = "weibo"
|
||||
await config.add_subscribe(
|
||||
TargetQQGroup(group_id=123),
|
||||
target=target,
|
||||
target_name="weibo_name",
|
||||
platform_name=platform_name,
|
||||
cats=[],
|
||||
tags=[],
|
||||
)
|
||||
bot = ctx.create_bot(base=Bot)
|
||||
event_1 = fake_private_message_event(
|
||||
message=Message("关联cookie"), sender=fake_superuser, to_me=True, user_id=fake_superuser.user_id
|
||||
)
|
||||
ctx.receive_event(bot, event_1)
|
||||
ctx.should_pass_rule()
|
||||
should_send_saa(
|
||||
ctx,
|
||||
MessageFactory(
|
||||
"订阅的帐号为:\n1 weibo weibo_name weibo_id\n []\n请输入要关联 cookie 的订阅的序号\n输入'取消'中止"
|
||||
),
|
||||
bot,
|
||||
event=event_1,
|
||||
)
|
||||
event_2_err = fake_private_message_event(
|
||||
message=Message("2"), sender=fake_superuser, to_me=True, user_id=fake_superuser.user_id
|
||||
)
|
||||
ctx.receive_event(bot, event_2_err)
|
||||
ctx.should_call_send(event_2_err, "序号错误", True)
|
||||
ctx.should_rejected()
|
||||
event_2_ok = fake_private_message_event(
|
||||
message=Message("1"), sender=fake_superuser, to_me=True, user_id=fake_superuser.user_id
|
||||
)
|
||||
ctx.receive_event(bot, event_2_ok)
|
||||
ctx.should_pass_rule()
|
||||
ctx.should_call_send(event_2_ok, '请选择一个 Cookie,已关联的 Cookie 不会显示\n1. weibo.com [{"cookie":]', True)
|
||||
event_3_err = fake_private_message_event(
|
||||
message=Message("2"), sender=fake_superuser, to_me=True, user_id=fake_superuser.user_id
|
||||
)
|
||||
ctx.receive_event(bot, event_3_err)
|
||||
ctx.should_call_send(event_3_err, "序号错误", True)
|
||||
ctx.should_rejected()
|
||||
event_3_ok = fake_private_message_event(
|
||||
message=Message("1"), sender=fake_superuser, to_me=True, user_id=fake_superuser.user_id
|
||||
)
|
||||
ctx.receive_event(bot, event_3_ok)
|
||||
ctx.should_pass_rule()
|
||||
ctx.should_call_send(event_3_ok, '已关联 Cookie: weibo.com [{"cookie":] 到订阅 weibo.com weibo_id', True)
|
||||
|
||||
|
||||
async def test_add_cookie_target_no_target(app: App, mocker: MockerFixture):
|
||||
|
||||
from nonebot.adapters.onebot.v11.bot import Bot
|
||||
from nonebot.adapters.onebot.v11.message import Message
|
||||
|
||||
from nonebot_bison.sub_manager import add_cookie_target_matcher
|
||||
|
||||
async with app.test_matcher(add_cookie_target_matcher) as ctx:
|
||||
bot = ctx.create_bot(base=Bot)
|
||||
event_1 = fake_private_message_event(
|
||||
message=Message("关联cookie"), sender=fake_superuser, to_me=True, user_id=fake_superuser.user_id
|
||||
)
|
||||
ctx.receive_event(bot, event_1)
|
||||
ctx.should_pass_rule()
|
||||
ctx.should_call_send(
|
||||
event_1,
|
||||
"暂无已订阅账号\n请使用“添加订阅”命令添加订阅",
|
||||
True,
|
||||
)
|
||||
@@ -1,133 +0,0 @@
|
||||
import json
|
||||
|
||||
from nonebug.app import App
|
||||
|
||||
from ..utils import fake_superuser, fake_private_message_event
|
||||
|
||||
|
||||
async def test_del_cookie_err(app: App):
|
||||
from nonebug_saa import should_send_saa
|
||||
from nonebot.adapters.onebot.v11.bot import Bot
|
||||
from nonebot.adapters.onebot.v11.message import Message
|
||||
from nonebot_plugin_saa import TargetQQGroup, MessageFactory
|
||||
|
||||
from nonebot_bison.config import config
|
||||
from nonebot_bison.config.db_model import Cookie
|
||||
from nonebot_bison.types import Target as T_Target
|
||||
from nonebot_bison.sub_manager import del_cookie_matcher
|
||||
|
||||
async with app.test_matcher(del_cookie_matcher) as ctx:
|
||||
bot = ctx.create_bot(base=Bot)
|
||||
event = fake_private_message_event(
|
||||
message=Message("删除cookie"), sender=fake_superuser, to_me=True, user_id=fake_superuser.user_id
|
||||
)
|
||||
ctx.receive_event(bot, event)
|
||||
ctx.should_pass_rule()
|
||||
ctx.should_pass_permission()
|
||||
ctx.should_call_send(event, "暂无已添加的 Cookie\n请使用“添加cookie”命令添加", True)
|
||||
|
||||
async with app.test_matcher(del_cookie_matcher) as ctx:
|
||||
bot = ctx.create_bot(base=Bot)
|
||||
target = T_Target("weibo_id")
|
||||
platform_name = "weibo"
|
||||
await config.add_subscribe(
|
||||
TargetQQGroup(group_id=123),
|
||||
target=target,
|
||||
target_name="weibo_name",
|
||||
platform_name=platform_name,
|
||||
cats=[],
|
||||
tags=[],
|
||||
)
|
||||
await config.add_cookie(Cookie(content=json.dumps({"cookie": "test"}), site_name="weibo.com"))
|
||||
cookies = await config.get_cookie(is_anonymous=False)
|
||||
await config.add_cookie_target(target, platform_name, cookies[0].id)
|
||||
|
||||
event_1 = fake_private_message_event(
|
||||
message=Message("删除cookie"), sender=fake_superuser, to_me=True, user_id=fake_superuser.user_id
|
||||
)
|
||||
ctx.receive_event(bot, event_1)
|
||||
ctx.should_pass_rule()
|
||||
ctx.should_pass_permission()
|
||||
should_send_saa(
|
||||
ctx,
|
||||
MessageFactory(
|
||||
'已添加的 Cookie 为:\n1 weibo.com weibo.com [{"cookie":] '
|
||||
"1个关联\n请输入要删除的 Cookie 的序号\n输入'取消'中止"
|
||||
),
|
||||
bot,
|
||||
event=event_1,
|
||||
)
|
||||
event_2_err = fake_private_message_event(
|
||||
message=Message("2"), sender=fake_superuser, to_me=True, user_id=fake_superuser.user_id
|
||||
)
|
||||
ctx.receive_event(bot, event_2_err)
|
||||
ctx.should_call_send(event_2_err, "序号错误", True)
|
||||
ctx.should_rejected()
|
||||
|
||||
event_2 = fake_private_message_event(
|
||||
message=Message("1"), sender=fake_superuser, to_me=True, user_id=fake_superuser.user_id
|
||||
)
|
||||
ctx.receive_event(bot, event_2)
|
||||
ctx.should_pass_rule()
|
||||
ctx.should_call_send(event_2, "只能删除未关联的 Cookie,请使用“取消关联cookie”命令取消关联", True)
|
||||
ctx.should_call_send(event_2, "删除错误", True)
|
||||
ctx.should_rejected()
|
||||
|
||||
|
||||
async def test_del_cookie(app: App):
|
||||
from nonebug_saa import should_send_saa
|
||||
from nonebot.adapters.onebot.v11.bot import Bot
|
||||
from nonebot.adapters.onebot.v11.message import Message
|
||||
from nonebot_plugin_saa import TargetQQGroup, MessageFactory
|
||||
|
||||
from nonebot_bison.config import config
|
||||
from nonebot_bison.config.db_model import Cookie
|
||||
from nonebot_bison.types import Target as T_Target
|
||||
from nonebot_bison.sub_manager import del_cookie_matcher
|
||||
|
||||
async with app.test_matcher(del_cookie_matcher) as ctx:
|
||||
bot = ctx.create_bot(base=Bot)
|
||||
event = fake_private_message_event(
|
||||
message=Message("删除cookie"), sender=fake_superuser, to_me=True, user_id=fake_superuser.user_id
|
||||
)
|
||||
ctx.receive_event(bot, event)
|
||||
ctx.should_pass_rule()
|
||||
ctx.should_pass_permission()
|
||||
ctx.should_call_send(event, "暂无已添加的 Cookie\n请使用“添加cookie”命令添加", True)
|
||||
|
||||
async with app.test_matcher(del_cookie_matcher) as ctx:
|
||||
bot = ctx.create_bot(base=Bot)
|
||||
target = T_Target("weibo_id")
|
||||
platform_name = "weibo"
|
||||
await config.add_subscribe(
|
||||
TargetQQGroup(group_id=123),
|
||||
target=target,
|
||||
target_name="weibo_name",
|
||||
platform_name=platform_name,
|
||||
cats=[],
|
||||
tags=[],
|
||||
)
|
||||
await config.add_cookie(Cookie(content=json.dumps({"cookie": "test"}), site_name="weibo.com"))
|
||||
|
||||
event_1 = fake_private_message_event(
|
||||
message=Message("删除cookie"), sender=fake_superuser, to_me=True, user_id=fake_superuser.user_id
|
||||
)
|
||||
ctx.receive_event(bot, event_1)
|
||||
ctx.should_pass_rule()
|
||||
ctx.should_pass_permission()
|
||||
should_send_saa(
|
||||
ctx,
|
||||
MessageFactory(
|
||||
'已添加的 Cookie 为:\n1 weibo.com weibo.com [{"cookie":]'
|
||||
" 0个关联\n请输入要删除的 Cookie 的序号\n输入'取消'中止"
|
||||
),
|
||||
bot,
|
||||
event=event_1,
|
||||
)
|
||||
event_2 = fake_private_message_event(
|
||||
message=Message("1"), sender=fake_superuser, to_me=True, user_id=fake_superuser.user_id
|
||||
)
|
||||
ctx.receive_event(bot, event_2)
|
||||
ctx.should_pass_rule()
|
||||
ctx.should_pass_permission()
|
||||
ctx.should_call_send(event_2, "删除成功", True)
|
||||
@@ -89,7 +89,6 @@ add_reply_on_id_input_search = (
|
||||
|
||||
|
||||
class BotReply:
|
||||
|
||||
@staticmethod
|
||||
def add_reply_on_platform(platform_manager, common_platform):
|
||||
return (
|
||||
@@ -160,33 +159,3 @@ class BotReply:
|
||||
add_reply_on_tags_need_more_info = "订阅标签直接输入标签内容\n屏蔽标签请在标签名称前添加~号\n详见https://nonebot-bison.netlify.app/usage/#%E5%B9%B3%E5%8F%B0%E8%AE%A2%E9%98%85%E6%A0%87%E7%AD%BE-tag"
|
||||
add_reply_abort = "已中止订阅"
|
||||
no_permission = "您没有权限进行此操作,请联系 Bot 管理员"
|
||||
|
||||
@staticmethod
|
||||
def add_reply_on_add_cookie(platform_manager, common_platform):
|
||||
from nonebot_bison.utils.site import is_cookie_client_manager
|
||||
|
||||
return (
|
||||
"请输入想要添加 Cookie 的平台,目前支持,请输入冒号左边的名称:\n"
|
||||
+ "".join(
|
||||
[
|
||||
f"{platform_name}: {platform_manager[platform_name].name}\n"
|
||||
for platform_name in common_platform
|
||||
if is_cookie_client_manager(platform_manager[platform_name].site.client_mgr)
|
||||
]
|
||||
)
|
||||
+ "要查看全部平台请输入:“全部”\n中止添加cookie过程请输入:“取消”"
|
||||
)
|
||||
|
||||
@staticmethod
|
||||
def add_reply_on_add_cookie_input_allplatform(platform_manager):
|
||||
from nonebot_bison.utils.site import is_cookie_client_manager
|
||||
|
||||
return "全部平台\n" + "\n".join(
|
||||
[
|
||||
f"{platform_name}: {platform.name}"
|
||||
for platform_name, platform in platform_manager.items()
|
||||
if is_cookie_client_manager(platform.site.client_mgr)
|
||||
]
|
||||
)
|
||||
|
||||
add_reply_on_input_cookie = "请输入 Cookie"
|
||||
|
||||
Reference in New Issue
Block a user