GenshinUID/genshinuid_resin/draw_resin_card.py
2022-08-29 23:26:46 +08:00

313 lines
9.4 KiB
Python

import json
import asyncio
from typing import List
from pathlib import Path
from nonebot.log import logger
from PIL import Image, ImageDraw
from ..utils.mhy_api.get_mhy_data import get_daily_data
from ..utils.enka_api.get_enka_data import get_enka_info
from ..utils.alias.enName_to_avatarId import enName_to_avatarId
from ..utils.draw_image_tools.send_image_tool import convert_img
from ..utils.draw_image_tools.draw_image_tool import get_simple_bg
from ..utils.genshin_fonts.genshin_fonts import genshin_font_origin
from ..utils.db_operation.db_operation import select_db, owner_cookies
TEXT_PATH = Path(__file__).parent / 'texture2D'
CHAR_SIDE_PATH = Path(__file__).parents[1] / 'resource' / 'char_side'
resin_fg_pic = Image.open(TEXT_PATH / 'resin_fg.png')
yes_pic = Image.open(TEXT_PATH / 'yes.png')
no_pic = Image.open(TEXT_PATH / 'no.png')
based_w = 500
based_h = 900
white_overlay = Image.new('RGBA', (based_w, based_h), (255, 251, 242, 225))
first_color = (29, 29, 29)
second_color = (98, 98, 98)
green_color = (15, 196, 35)
orange_color = (237, 115, 61)
red_color = (235, 61, 75)
gs_font_20 = genshin_font_origin(20)
gs_font_26 = genshin_font_origin(26)
gs_font_32 = genshin_font_origin(32)
gs_font_60 = genshin_font_origin(60)
async def _draw_task_img(
img: Image.Image, img_draw: ImageDraw.ImageDraw, index: int, char: dict
):
char_en_name = char['avatar_side_icon'].split('_')[-1].split('.')[0]
avatar_id = await enName_to_avatarId(char_en_name)
char_pic = (
Image.open(CHAR_SIDE_PATH / f'{avatar_id}.png')
.convert('RGBA')
.resize((80, 80), Image.Resampling.LANCZOS) # type: ignore
)
img.paste(char_pic, (22 + index * 90, 770), char_pic)
if char['status'] == 'Finished':
status_mark = '待收取'
status_color = red_color
else:
status_mark = '已派遣'
status_color = green_color
img_draw.text(
(65 + index * 90, 870),
status_mark,
font=gs_font_20,
fill=status_color,
anchor='mm',
)
async def get_resin_img(qid: int):
try:
uid_list: List = await select_db(qid, mode='list') # type: ignore
logger.info('[每日信息]UID: {}'.format(uid_list))
# 进行校验UID是否绑定CK
useable_uid_list = []
for uid in uid_list:
status = await owner_cookies(uid)
if status != '该用户没有绑定过Cookies噢~':
useable_uid_list.append(uid)
logger.info('[每日信息]可用UID: {}'.format(useable_uid_list))
if len(useable_uid_list) == 0:
return '请先绑定一个可用CK & UID再来查询哦~'
# 开始绘图任务
task = []
img = Image.new(
'RGBA', (based_w * len(useable_uid_list), based_h), (0, 0, 0, 0)
)
for uid_index, uid in enumerate(useable_uid_list):
task.append(_draw_all_resin_img(img, uid, uid_index))
await asyncio.gather(*task)
res = await convert_img(img)
logger.info('[查询每日信息]绘图已完成,等待发送!')
except TypeError:
logger.exception('[查询每日信息]绘图失败!')
res = '你绑定过的UID中可能存在过期CK~请重新绑定一下噢~'
return res
async def _draw_all_resin_img(img: Image.Image, uid: str, index: int):
resin_img = await draw_resin_img(uid)
img.paste(resin_img, (500 * index, 0), resin_img)
async def seconds2hours(seconds: int) -> str:
m, s = divmod(int(seconds), 60)
h, m = divmod(m, 60)
return '%02d小时%02d' % (h, m)
async def draw_resin_img(uid: str) -> Image.Image:
# 获取数据
daily_data = await get_daily_data(uid)
daily_data = daily_data['data']
enta_data_path = (
Path(__file__).parents[1] / 'player' / uid / 'rawData.json'
)
if enta_data_path.exists():
with open(enta_data_path, 'r', encoding='utf-8') as f:
player_data = json.load(f)
else:
try:
player_data = await get_enka_info(uid)
except Exception:
player_data = {}
# 处理数据
if player_data:
if 'signature' in player_data['playerInfo']:
signature = player_data['playerInfo']['signature']
else:
signature = '该旅行者还没有签名噢~'
world_level = player_data['playerInfo']['level']
world_level_str = f'探索等级{str(world_level)}'
else:
signature = '暂无获取数据'
world_level_str = '暂无数据'
# 获取背景图片各项参数
img = await get_simple_bg(based_w, based_h)
img.paste(white_overlay, (0, 0), white_overlay)
img.paste(resin_fg_pic, (0, 0), resin_fg_pic)
# 树脂
resin = daily_data['current_resin']
max_resin = daily_data['max_resin']
resin_str = f'{resin}/{max_resin}'
resin_percent = resin / max_resin
if resin_percent > 0.8:
resin_color = red_color
else:
resin_color = second_color
resin_recovery_time = await seconds2hours(
daily_data['resin_recovery_time']
)
delay = 53
# 洞天宝钱
home_coin = daily_data['current_home_coin']
max_home_coin = daily_data['max_home_coin']
home_coin_str = f'{home_coin}/{max_home_coin}'
if max_home_coin - home_coin < 200:
home_coin_mark = '可收取'
home_coin_color = red_color
img.paste(no_pic, (35, 559), no_pic)
else:
home_coin_mark = '已收取'
home_coin_color = green_color
img.paste(yes_pic, (35, 559), yes_pic)
# 完成委托
finish_task = daily_data['finished_task_num']
total_task = daily_data['total_task_num']
is_task_reward = daily_data['is_extra_task_reward_received']
task_str = f'{finish_task}/{total_task}'
if is_task_reward:
task_mark = '已领取'
task_color = green_color
img.paste(yes_pic, (35, 559 + delay), yes_pic)
else:
task_mark = '未领取'
task_color = red_color
img.paste(no_pic, (35, 559 + delay), no_pic)
# 周本减半
weekly_half = daily_data['remain_resin_discount_num']
max_weekly_half = daily_data['resin_discount_num_limit']
weekly_half_str = f'{weekly_half}/{max_weekly_half}'
if weekly_half == 0:
weekly_half_mark = '已使用'
weekly_half_color = green_color
img.paste(yes_pic, (35, 559 + delay * 2), yes_pic)
else:
weekly_half_mark = '未用完'
weekly_half_color = red_color
img.paste(no_pic, (35, 559 + delay * 2), no_pic)
# 参量质变仪
transformer = daily_data['transformer']['recovery_time']['reached']
transformer_day = daily_data['transformer']['recovery_time']['Day']
transformer_hour = daily_data['transformer']['recovery_time']['Hour']
transformer_str = f'还剩{transformer_day}{transformer_hour}小时'
if transformer:
transformer_mark = '可使用'
transformer_color = red_color
img.paste(no_pic, (35, 559 + delay * 3), no_pic)
else:
transformer_mark = '已使用'
transformer_color = green_color
img.paste(yes_pic, (35, 559 + delay * 3), yes_pic)
img_draw = ImageDraw.Draw(img)
# 派遣
task_task = []
for index, char in enumerate(daily_data['expeditions']):
task_task.append(_draw_task_img(img, img_draw, index, char))
await asyncio.gather(*task_task)
# 绘制树脂圆环
ring_pic = Image.open(TEXT_PATH / 'ring.apng')
ring_pic.seek(round(resin_percent * 49))
img.paste(ring_pic, (0, 0), ring_pic)
# 写树脂剩余时间
img_draw.text(
(250, 370),
f'还剩{resin_recovery_time}',
font=gs_font_20,
fill=resin_color,
anchor='mm',
)
# 写签名
img_draw.text(
(48, 137), signature, font=gs_font_26, fill=second_color, anchor='lm'
)
# 写UID
img_draw.text(
(250, 518), f'UID{uid}', font=gs_font_26, fill=first_color, anchor='mm'
)
# 写探索等级
img_draw.text(
(250, 281),
world_level_str,
font=gs_font_26,
fill=second_color,
anchor='mm',
)
# 写树脂
img_draw.text(
(250, 327),
resin_str,
font=gs_font_60,
fill=first_color,
anchor='mm',
)
# 写洞天宝钱
img_draw.text(
(335, 588),
home_coin_str,
font=gs_font_20,
fill=first_color,
anchor='lm',
)
img_draw.text(
(225, 584),
home_coin_mark,
font=gs_font_32,
fill=home_coin_color,
anchor='lm',
)
# 写完成委托
img_draw.text(
(335, 588 + delay),
task_str,
font=gs_font_20,
fill=first_color,
anchor='lm',
)
img_draw.text(
(225, 584 + delay),
task_mark,
font=gs_font_32,
fill=task_color,
anchor='lm',
)
# 写周本减半
img_draw.text(
(335, 588 + delay * 2),
weekly_half_str,
font=gs_font_20,
fill=first_color,
anchor='lm',
)
img_draw.text(
(225, 584 + delay * 2),
weekly_half_mark,
font=gs_font_32,
fill=weekly_half_color,
anchor='lm',
)
# 写参量质变仪
img_draw.text(
(335, 588 + delay * 3),
transformer_str,
font=gs_font_20,
fill=first_color,
anchor='lm',
)
img_draw.text(
(225, 584 + delay * 3),
transformer_mark,
font=gs_font_32,
fill=transformer_color,
anchor='lm',
)
return img