mirror of
https://github.com/A-Minos/nonebot-plugin-tetris-stats.git
synced 2026-03-05 05:36:54 +08:00
* 🚧 查数据图初版测试 Co-authored-by: C1ystal <m17687496044@163.com> Co-authored-by: C29H25N3O5 <michaelgu495@gmail.com> * 🙈 添加一些 ignore 文件 * 🎨 格式化代码 * 🐛 修复格式化导致的样式爆炸 * 💄 优化曲线图观感 * 💄 将雷达图的指示器名称旋转显示 * 💄 查数据图第二版 Co-authored-by: C29H25N3O5 <michaelgu495@gmail.com> * ✏️ 修复 typo * 💄 把用户头像文件的引用放到 html 里 * 💄 账户绑定图第一版 Co-authored-by: C1ystal <m17687496044@163.com> Co-authored-by: C29H25N3O5 <michaelgu495@gmail.com> * 🚧 模板化测试 * ➕ 添加依赖 fastapi * ✨ 通过 FastAPI 提供静态文件 * ➕ 添加依赖 jinja2 * 💄 更新数据图模板 (#291) * feat(template): show actual value * feat(template): add user avatar * feat(template): fix radar * feat(style): fix name container width fixed caused display misplacement * feat(style): fix vs value wrap display * feat(template): make check data length in template * feat(template): update radar data * feat(jinja): update data * fix(template): fix typo * feat(style): prevent sign too long * feat(template): turn off echarts animation * chore(deps): add identicon.js * fix(template): fix typo * 🙈 更新.gitignore * 🏗️ 大部分重构为 flex 布局 --------- Co-authored-by: shoucandanghehe <wallfjjd@gmail.com> Co-authored-by: 呵呵です <51957264+shoucandanghehe@users.noreply.github.com> * ➕ 添加依赖 nonebot_plugin_userinfo * ✨ 通过 FastAPI 托管渲染后的模板 * ✨ 新增头像 api 使用 playwright 生成 * ✨ 修正模板资源文件引用路径 被托管后的正确路径 * 💄 将绑定图模板化 * 💄 重命名变量 * 🚚 重命名资源 * ✨ 使用 jinja2 渲染模板 * ✨ 使用 playwright 渲染网页 * 🩹 渲染模板时对 IO 进行一些额外处理 * ➕ 添加依赖 pillow * 🚚 修改托管页面的路由路径 * 💬 优化绑定图文案 * ✨ 新增获取自身网络位置的方法 * 🍱 更新 unknown.svg * ✨ 新增获取用户头像的方法 * ✨ 绑定消息使用图片回复 * ✨ 为 identicon api 添加缓存 * 🔥 删除旧文件 * 🚚 重命名模板 * 📄 添加字体 License * 🙈 更新.gitignore --------- Co-authored-by: C1ystal <m17687496044@163.com> Co-authored-by: C29H25N3O5 <michaelgu495@gmail.com> Co-authored-by: 渣渣120 <WOSHIZHAZHA120@qq.com>
82 lines
2.6 KiB
Python
82 lines
2.6 KiB
Python
from base64 import b64decode, b64encode
|
|
from io import BytesIO
|
|
from typing import Literal, overload
|
|
|
|
from nonebot_plugin_userinfo import UserInfo # type: ignore[import-untyped]
|
|
from PIL import Image
|
|
|
|
from ..templates import path
|
|
from .browser import BrowserManager
|
|
|
|
|
|
@overload
|
|
async def get_avatar(user: UserInfo, scheme: Literal['Data URI'], default: str | None) -> str:
|
|
"""获取用户头像的指定格式
|
|
|
|
Args:
|
|
user (UserInfo): 要获取的用户
|
|
scheme (Literal['Data URI']): 格式
|
|
default (str | None): 获取不到时的默认值
|
|
|
|
Raises:
|
|
TypeError: Can't get avatar: 当获取不到头像并且没有设置默认值时抛出
|
|
TypeError: Can't get avatar format: 当获取到的头像无法识别格式时抛出
|
|
|
|
Returns:
|
|
str: Data URI 格式的头像
|
|
"""
|
|
|
|
|
|
@overload
|
|
async def get_avatar(user: UserInfo, scheme: Literal['bytes'], default: str | None) -> bytes:
|
|
"""获取用户头像的指定格式
|
|
|
|
Args:
|
|
user (UserInfo): 要获取的用户
|
|
scheme (Literal['bytes']): 格式
|
|
default (str | None): 获取不到时的默认值
|
|
|
|
Returns:
|
|
bytes: bytes 格式的头像
|
|
"""
|
|
|
|
|
|
async def get_avatar(user: UserInfo, scheme: Literal['Data URI', 'bytes'], default: str | None) -> str | bytes:
|
|
if user.user_avatar is None:
|
|
if default is None:
|
|
raise TypeError("Can't get avatar")
|
|
return default
|
|
bot_avatar = await user.user_avatar.get_image()
|
|
if scheme == 'Data URI':
|
|
avatar_format = Image.open(BytesIO(bot_avatar)).format
|
|
if avatar_format is None:
|
|
raise TypeError("Can't get avatar format")
|
|
return f'data:{Image.MIME[avatar_format]};base64,{b64encode(bot_avatar).decode()}'
|
|
return bot_avatar
|
|
|
|
|
|
async def generate_identicon(hash: str) -> bytes: # noqa: A002
|
|
"""使用 identicon 生成头像
|
|
|
|
Args:
|
|
hash (str): 提交给 identicon 的 hash 值
|
|
|
|
Returns:
|
|
bytes: identicon 生成的 svg 的二进制数据
|
|
"""
|
|
browser = await BrowserManager.get_browser()
|
|
async with await browser.new_page() as page:
|
|
await page.add_script_tag(path=path / 'js/identicon.js')
|
|
return b64decode(
|
|
await page.evaluate(rf"""
|
|
new Identicon('{hash}', {{
|
|
background: [0x08, 0x0a, 0x06, 255],
|
|
margin: 0.15,
|
|
size: 300,
|
|
brightness: 0.48,
|
|
saturation: 0.65,
|
|
format: 'svg',
|
|
}}).toString();
|
|
""")
|
|
)
|