HeXi/hexi/plugins/nonebot_plugin_steam_info/utils.py

113 lines
3.6 KiB
Python
Raw Normal View History

2026-01-04 17:15:40 +08:00
import time
import pytz
import httpx
import datetime
import calendar
from PIL import Image
from io import BytesIO
from pathlib import Path
from typing import Dict, Optional
from .models import Player
from .data_source import BindData
async def _fetch_avatar(avatar_url: str, proxy: str = None) -> Image.Image:
async with httpx.AsyncClient(proxy=proxy) as client:
response = await client.get(avatar_url)
if response.status_code != 200:
return Image.open(Path(__file__).parent / "res/unknown_avatar.jpg")
return Image.open(BytesIO(response.content))
async def fetch_avatar(
player: Player, avatar_dir: Optional[Path], proxy: str = None
) -> Image.Image:
if avatar_dir is not None:
avatar_path = (
avatar_dir / f"avatar_{player['steamid']}_{player['avatarhash']}.png"
)
if avatar_path.exists():
avatar = Image.open(avatar_path)
else:
avatar = await _fetch_avatar(player["avatarfull"], proxy)
avatar.save(avatar_path)
else:
avatar = await _fetch_avatar(player["avatarfull"], proxy)
return avatar
def convert_player_name_to_nickname(
data: Dict[str, str], parent_id: str, bind_data: BindData
) -> Dict[str, str]:
data["nickname"] = bind_data.get_by_steam_id(parent_id, data["steamid"])["nickname"]
return data
async def simplize_steam_player_data(
player: Player, proxy: str = None, avatar_dir: Path = None
) -> Dict[str, str]:
avatar = await fetch_avatar(player, avatar_dir, proxy)
if player["personastate"] == 0:
if not player.get("lastlogoff"):
status = "离线"
else:
time_logged_off = player["lastlogoff"] # Unix timestamp
time_to_now = calendar.timegm(time.gmtime()) - time_logged_off
# 将时间转换为自然语言
if time_to_now < 60:
status = "上次在线 刚刚"
elif time_to_now < 3600:
status = f"上次在线 {time_to_now // 60} 分钟前"
elif time_to_now < 86400:
status = f"上次在线 {time_to_now // 3600} 小时前"
elif time_to_now < 2592000:
status = f"上次在线 {time_to_now // 86400} 天前"
elif time_to_now < 31536000:
status = f"上次在线 {time_to_now // 2592000} 个月前"
else:
status = f"上次在线 {time_to_now // 31536000} 年前"
elif player["personastate"] in [1, 2, 4]:
status = (
"在线" if player.get("gameextrainfo") is None else player["gameextrainfo"]
)
elif player["personastate"] == 3:
status = (
"离开" if player.get("gameextrainfo") is None else player["gameextrainfo"]
)
elif player["personastate"] in [5, 6]:
status = "在线"
else:
status = "未知"
return {
"steamid": player["steamid"],
"avatar": avatar,
"name": player["personaname"],
"status": status,
"personastate": player["personastate"],
}
def image_to_bytes(image: Image.Image) -> bytes:
with BytesIO() as bio:
image.save(bio, format="PNG")
return bio.getvalue()
def hex_to_rgb(hex_color: str):
return tuple(int(hex_color[i : i + 2], 16) for i in (0, 2, 4))
def convert_timestamp_to_beijing_time(timestamp: int) -> str:
beijing_timezone = pytz.timezone("Asia/Shanghai")
date_utc = datetime.datetime.fromtimestamp(timestamp, pytz.utc)
date_beijing = date_utc.astimezone(beijing_timezone)
return date_beijing.strftime("%Y-%m-%d %H:%M:%S")
# example: 2021-09-06 21:00:00