🎨 重命名一些模块

This commit is contained in:
2024-05-16 05:59:18 +08:00
parent e8539c15cc
commit 3ef7605e11
42 changed files with 6 additions and 10 deletions

View File

@@ -0,0 +1,3 @@
from .player import Player
__all__ = ['Player']

View File

@@ -0,0 +1,17 @@
from datetime import datetime
from typing import Literal
from nonebot_plugin_orm import Model
from sqlalchemy import DateTime, String
from sqlalchemy.orm import Mapped, MappedAsDataclass, mapped_column
from ....db.models import PydanticType
from .schemas.user_profile import UserProfile
class TOPHistoricalData(MappedAsDataclass, Model):
id: Mapped[int] = mapped_column(init=False, primary_key=True)
user_unique_identifier: Mapped[str] = mapped_column(String(24), index=True)
api_type: Mapped[Literal['User Profile']] = mapped_column(String(16), index=True)
data: Mapped[UserProfile] = mapped_column(PydanticType(get_model=[], models={UserProfile}))
update_time: Mapped[datetime] = mapped_column(DateTime, index=True)

View File

@@ -0,0 +1,71 @@
from contextlib import suppress
from datetime import datetime, timezone
from io import StringIO
from urllib.parse import urlencode
from lxml import etree
from pandas import read_html
from ....db import anti_duplicate_add
from ....utils.request import Request, splice_url
from ..constant import BASE_URL, USER_NAME
from .models import TOPHistoricalData
from .schemas.user import User
from .schemas.user_profile import Data, UserProfile
UTC = timezone.utc
class Player:
def __init__(self, *, user_name: str, trust: bool = False) -> None:
self.user_name = user_name
if not trust and not USER_NAME.match(self.user_name):
msg = 'Invalid user name'
raise ValueError(msg)
self.__user: User | None = None
self._user_profile: UserProfile | None = None
@property
async def user(self) -> User:
if self.__user is None:
profile = await self.get_profile()
self.__user = User(user_name=profile.user_name)
return self.__user
async def get_profile(self) -> UserProfile:
"""获取用户信息"""
if self._user_profile is None:
url = splice_url([BASE_URL, 'profile.php', f'?{urlencode({"user":self.user_name})}'])
raw_user_profile = await Request.request(url, is_json=False)
self._user_profile = self._parse_profile(raw_user_profile)
await anti_duplicate_add(
TOPHistoricalData,
TOPHistoricalData(
user_unique_identifier=(await self.user).unique_identifier,
api_type='User Profile',
data=self._user_profile,
update_time=datetime.now(tz=UTC),
),
)
return self._user_profile
def _parse_profile(self, original_user_profile: bytes) -> UserProfile:
html = etree.HTML(original_user_profile)
user_name = html.xpath('//div[@class="mycontent"]/h1/text()')[0].replace("'s profile", '')
today = None
with suppress(ValueError):
today = Data(
lpm=float(str(html.xpath('//div[@class="mycontent"]/text()[3]')[0]).replace('lpm:', '').strip()),
apm=float(str(html.xpath('//div[@class="mycontent"]/text()[4]')[0]).replace('apm:', '').strip()),
)
table = StringIO(
etree.tostring(
html.xpath('//div[@class="mycontent"]/table[@class="mytable"]')[0],
encoding='utf-8',
).decode()
)
dataframe = read_html(table, encoding='utf-8', header=0)[0]
total: list[Data] = []
for _, value in dataframe.iterrows():
total.append(Data(lpm=value['lpm'], apm=value['apm']))
return UserProfile(user_name=user_name, today=today, total=total)

View File

@@ -0,0 +1,17 @@
from typing import Literal
from typing_extensions import override
from ....schemas import BaseUser
from ...constant import GAME_TYPE
class User(BaseUser):
platform: Literal['TOP'] = GAME_TYPE
user_name: str
@property
@override
def unique_identifier(self) -> str:
return self.user_name

View File

@@ -0,0 +1,12 @@
from pydantic import BaseModel
class Data(BaseModel):
lpm: float
apm: float
class UserProfile(BaseModel):
user_name: str
today: Data | None
total: list[Data] | None