pre-commit-ci[bot] 5140ab2dc3
⬆️ pre-commit-ci自动升级 (#617)
* ⬆️ `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>
2024-02-09 21:56:00 +08:00

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 '已经不在订阅中了'