mirror of
https://github.com/KimigaiiWuyi/GenshinUID.git
synced 2025-05-07 20:45:49 +08:00
* ⬆️ `pre-commit-ci`自动升级 updates: - [github.com/psf/black: 23.12.1 → 24.1.1](https://github.com/psf/black/compare/23.12.1...24.1.1) - [github.com/pycqa/flake8: 6.1.0 → 7.0.0](https://github.com/pycqa/flake8/compare/6.1.0...7.0.0) * 🚨 `pre-commit-ci`修复格式错误 --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
232 lines
6.9 KiB
Python
232 lines
6.9 KiB
Python
import re
|
|
from pathlib import Path
|
|
|
|
from bs4 import BeautifulSoup
|
|
from PIL import Image, ImageOps, ImageDraw
|
|
|
|
from .main import ann
|
|
from .util import filter_list
|
|
from ..utils.image.convert import convert_img
|
|
from ..genshinuid_config.gs_config import gsconfig
|
|
from ..utils.fonts.genshin_fonts import gs_font_18, gs_font_26
|
|
from ..utils.image.image_tools import (
|
|
get_pic,
|
|
easy_paste,
|
|
draw_text_by_line,
|
|
easy_alpha_composite,
|
|
)
|
|
|
|
assets_dir = Path(__file__).parent / 'assets'
|
|
|
|
list_head = Image.open(assets_dir / 'list.png')
|
|
list_item = (
|
|
Image.open(assets_dir / 'item.png').resize((384, 96)).convert('RGBA')
|
|
)
|
|
|
|
|
|
async def ann_list_card() -> bytes:
|
|
ann_list = await ann().get_ann_list()
|
|
if not ann_list:
|
|
raise Exception('获取游戏公告失败,请检查接口是否正常')
|
|
|
|
height_len = max(len(ann_list[0]['list']), len(ann_list[1]['list']))
|
|
|
|
bg = Image.new(
|
|
'RGBA',
|
|
(
|
|
list_head.width,
|
|
list_head.height + list_item.height * height_len + 20 + 30,
|
|
),
|
|
'#f9f6f2',
|
|
)
|
|
easy_paste(bg, list_head, (0, 0))
|
|
|
|
for data in ann_list:
|
|
x = 45
|
|
if data['type_id'] == 1:
|
|
x = 472
|
|
|
|
for index, ann_info in enumerate(data['list']):
|
|
new_item = list_item.copy()
|
|
subtitle = ann_info['subtitle']
|
|
draw_text_by_line(
|
|
new_item,
|
|
(0, 30 - (len(subtitle) > 10 and 10 or 0)),
|
|
subtitle,
|
|
gs_font_26,
|
|
'#3b4354',
|
|
250,
|
|
True,
|
|
)
|
|
|
|
draw_text_by_line(
|
|
new_item,
|
|
(new_item.width - 80, 10),
|
|
str(ann_info['ann_id']),
|
|
gs_font_18,
|
|
'#3b4354',
|
|
100,
|
|
)
|
|
|
|
bg = easy_alpha_composite(
|
|
bg, new_item, (x, list_head.height + (index * new_item.height))
|
|
)
|
|
|
|
tip = (
|
|
'*可以使用 原神公告#0000(右上角ID) 来查看详细内容, 例子: 原神公告#2434'
|
|
)
|
|
draw_text_by_line(
|
|
bg, (0, bg.height - 35), tip, gs_font_18, '#767779', 1000, True
|
|
)
|
|
|
|
return await convert_img(bg)
|
|
|
|
|
|
async def ann_detail_card(ann_id):
|
|
ann_list = await ann().get_ann_content()
|
|
if not ann_list:
|
|
raise Exception('获取游戏公告失败,请检查接口是否正常')
|
|
content = filter_list(ann_list, lambda x: x['ann_id'] == ann_id)
|
|
if not content:
|
|
raise Exception('没有找到对应的公告ID :%s' % ann_id)
|
|
soup = BeautifulSoup(content[0]['content'], 'lxml')
|
|
banner = content[0]['banner']
|
|
ann_img = banner if banner else ''
|
|
for a in soup.find_all('a'):
|
|
a.string = ''
|
|
|
|
msg_list = [ann_img]
|
|
for img in soup.find_all('img'):
|
|
msg_list.append(img.get('src'))
|
|
# img.string = img.get('src')
|
|
|
|
msg_list.extend(
|
|
[
|
|
BeautifulSoup(x.get_text('').replace('<<', ''), 'lxml').get_text()
|
|
+ '\n'
|
|
for x in soup.find_all('p')
|
|
]
|
|
)
|
|
|
|
drow_height = 0
|
|
for msg in msg_list:
|
|
if msg.strip().endswith(('jpg', 'png')):
|
|
_msg = re.search(r'(https://.*[png|jpg])', msg)
|
|
if _msg:
|
|
msg = _msg.group(0)
|
|
img = await get_pic(msg.strip())
|
|
img_height = img.size[1]
|
|
if img.width > 1080:
|
|
img_height = int(img.height * 0.6)
|
|
drow_height += img_height + 40
|
|
else:
|
|
(
|
|
x_drow_duanluo,
|
|
x_drow_note_height,
|
|
x_drow_line_height,
|
|
x_drow_height,
|
|
) = split_text(msg)
|
|
drow_height += x_drow_height
|
|
|
|
im = Image.new('RGB', (1080, drow_height), '#f9f6f2')
|
|
draw = ImageDraw.Draw(im)
|
|
# 左上角开始
|
|
x, y = 0, 0
|
|
for msg in msg_list:
|
|
if msg.strip().endswith(('jpg', 'png')):
|
|
_msg = re.search(r'(https://.*[png|jpg])', msg)
|
|
if _msg:
|
|
msg = _msg.group(0)
|
|
img = await get_pic(msg.strip())
|
|
if img.width > im.width:
|
|
img = img.resize((int(img.width * 0.6), int(img.height * 0.6)))
|
|
easy_paste(im, img, (0, y))
|
|
y += img.size[1] + 40
|
|
else:
|
|
(
|
|
drow_duanluo,
|
|
drow_note_height,
|
|
drow_line_height,
|
|
drow_height,
|
|
) = split_text(msg)
|
|
for duanluo, line_count in drow_duanluo:
|
|
draw.text((x, y), duanluo, fill=(0, 0, 0), font=gs_font_26)
|
|
y += drow_line_height * line_count
|
|
|
|
if hasattr(gs_font_26, 'getsize'):
|
|
_x, _y = gs_font_26.getsize('囗') # type: ignore
|
|
else:
|
|
bbox = gs_font_26.getbbox('囗')
|
|
_x, _y = bbox[2] - bbox[0], bbox[3] - bbox[1]
|
|
|
|
padding = (_x, _y, _x, _y)
|
|
im = ImageOps.expand(im, padding, '#f9f6f2')
|
|
|
|
return await convert_img(im)
|
|
|
|
|
|
def split_text(content: str):
|
|
# 按规定宽度分组
|
|
max_line_height, total_lines = 0, 0
|
|
allText = []
|
|
for text in content.split('\n'):
|
|
duanluo, line_height, line_count = get_duanluo(text)
|
|
max_line_height = max(line_height, max_line_height)
|
|
total_lines += line_count
|
|
allText.append((duanluo, line_count))
|
|
line_height = max_line_height
|
|
total_height = total_lines * line_height
|
|
drow_height = total_lines * line_height
|
|
return allText, total_height, line_height, drow_height
|
|
|
|
|
|
def get_duanluo(text: str):
|
|
txt = Image.new('RGBA', (600, 800), (255, 255, 255, 0))
|
|
draw = ImageDraw.Draw(txt)
|
|
# 所有文字的段落
|
|
duanluo = ''
|
|
max_width = 1080
|
|
# 宽度总和
|
|
sum_width = 0
|
|
# 几行
|
|
line_count = 1
|
|
# 行高
|
|
line_height = 0
|
|
for char in text:
|
|
left, top, right, bottom = draw.textbbox((0, 0), char, gs_font_26)
|
|
width, height = (right - left, bottom - top)
|
|
sum_width += width
|
|
if sum_width > max_width: # 超过预设宽度就修改段落 以及当前行数
|
|
line_count += 1
|
|
sum_width = 0
|
|
duanluo += '\n'
|
|
duanluo += char
|
|
line_height = max(height, line_height)
|
|
if not duanluo.endswith('\n'):
|
|
duanluo += '\n'
|
|
return duanluo, line_height, line_count
|
|
|
|
|
|
def sub_ann(bot_id: str, group: str):
|
|
groups = gsconfig.get_config('Ann_Groups').data
|
|
if bot_id not in groups:
|
|
groups[bot_id] = []
|
|
if group in groups[bot_id]:
|
|
return '已经订阅了'
|
|
else:
|
|
groups[bot_id].append(group)
|
|
gsconfig.set_config('Ann_Groups', groups)
|
|
return '成功订阅原神公告'
|
|
|
|
|
|
def unsub_ann(bot_id: str, group: str):
|
|
groups = gsconfig.get_config('Ann_Groups').data
|
|
if bot_id not in groups:
|
|
groups[bot_id] = []
|
|
if group in groups[bot_id]:
|
|
groups[bot_id].remove(group)
|
|
gsconfig.set_config('Ann_Groups', groups)
|
|
return '成功取消订阅原神公告'
|
|
else:
|
|
return '已经不在订阅中了'
|