✨ v0.2.2 支持活动列表
This commit is contained in:
parent
6f78fa4a68
commit
23bf92acc7
2
.gitignore
vendored
2
.gitignore
vendored
@ -139,3 +139,5 @@ config.ini
|
||||
|
||||
# Data
|
||||
temp/
|
||||
assets/icon/
|
||||
assets/data/list.json
|
||||
|
BIN
assets/event/event_1.png
Normal file
BIN
assets/event/event_1.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 184 KiB |
BIN
assets/event/event_2.png
Normal file
BIN
assets/event/event_2.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 183 KiB |
@ -1,4 +1,4 @@
|
||||
import difflib, json, re, bs4, requests
|
||||
import difflib, json, re, requests, yaml
|
||||
from os import getcwd, sep
|
||||
from xpinyin import Pinyin
|
||||
from json.decoder import JSONDecodeError
|
||||
@ -17,12 +17,39 @@ def nic2name(name):
|
||||
return name
|
||||
|
||||
|
||||
def repl(match):
|
||||
content = re.sub(" ", "",match.group(0))
|
||||
length = len(content) - 1
|
||||
result = ''
|
||||
if content[0] == '[':
|
||||
result = '[""'
|
||||
length -= 1
|
||||
|
||||
after = ','
|
||||
if content[-1] == ']':
|
||||
length -= 1
|
||||
after += '""]'
|
||||
|
||||
return result + (',""' * length) + after
|
||||
|
||||
|
||||
def get_json(name: str) -> dict:
|
||||
if name not in ["空", "荧"]:
|
||||
name = nic2name(name)
|
||||
res = requests.get(f'https://api.minigg.cn/characters?query={name}')
|
||||
if res.text == "undefined\n":
|
||||
raise JSONDecodeError("", "", 0)
|
||||
py_dict = yaml.safe_load(re.sub(r'\[? *(, *)+\]?', repl, res.text))
|
||||
return py_dict
|
||||
|
||||
|
||||
def get_json_mz(name: str) -> dict:
|
||||
name = nic2name(name)
|
||||
res = requests.get(f'https://genshin.minigg.cn/?data={name}')
|
||||
soup = bs4.BeautifulSoup(res.text, "lxml").body
|
||||
character_json = json.loads(soup.text)
|
||||
return character_json
|
||||
res = requests.get(f'https://api.minigg.cn/constellations?query={name}')
|
||||
if res.text == "undefined\n":
|
||||
raise JSONDecodeError("", "", 0)
|
||||
py_dict = yaml.safe_load(re.sub(r'\[? *(, *)+\]?', repl, res.text))
|
||||
return py_dict
|
||||
|
||||
|
||||
def num_to_char(num):
|
||||
@ -51,12 +78,11 @@ def char_to_char(char):
|
||||
|
||||
def get_character(name: str):
|
||||
# 角色常见昵称转换为官方角色名
|
||||
nick_name = nic2name(name)
|
||||
nick_name = name
|
||||
if name not in ["空", "荧"]:
|
||||
nick_name = nic2name(name)
|
||||
try:
|
||||
data0 = get_json(nick_name)
|
||||
data = data0['角色信息']
|
||||
if nick_name == '旅行者':
|
||||
data["简介"] = '无'
|
||||
data = get_json(nick_name)
|
||||
except JSONDecodeError:
|
||||
correct_result = auto_correct(nick_name)
|
||||
if correct_result is None:
|
||||
@ -69,17 +95,20 @@ def get_character(name: str):
|
||||
else:
|
||||
return f"派蒙这里没找到 <code>{name}</code> ,你是要搜索 <code>{correct_result[0]}</code> 吗", None
|
||||
result = f"<b>{nick_name}</b>\n" \
|
||||
f"<b>命之座:</b>{data['命之座']}\n" \
|
||||
f"<b>所属:</b>{data['所属']}\n" \
|
||||
f"<b>武器类型:</b>{data['武器类型']}\n" \
|
||||
f"<b>生日:</b>{data['生日']}\n"
|
||||
f"<b>稀有度:</b>{data['rarity']}\n" \
|
||||
f"<b>命之座:</b>{data['constellation']}\n" \
|
||||
f"<b>所属:</b>{data['affiliation']}\n" \
|
||||
f"<b>突破加成:</b>{data['substat']}\n" \
|
||||
f"<b>武器类型:</b>{data['weapontype']}\n" \
|
||||
f"<b>生日:</b>{data['birthday']}\n" \
|
||||
f"<b>神之眼/心:</b>{data['element']}\n" \
|
||||
f"<b>称号:</b>{data['title']}\n" \
|
||||
f"<b>CV:</b>{data['cv']['chinese']}\n" \
|
||||
f"<b>简介:</b>{data['description']}"
|
||||
try:
|
||||
result += f"<b>神之眼:</b>{data['神之眼']}\n"
|
||||
url = data["images"]["cover1"]
|
||||
except KeyError:
|
||||
result += f"<b>神之心:</b>{data['神之心']}\n"
|
||||
result += f"<b>称号:</b>{data['称号']}\n" \
|
||||
f"<b>简介:</b>{data['简介']}"
|
||||
url = data0['avatar'].split('?')[0]
|
||||
url = data["images"]["icon"]
|
||||
return result, url
|
||||
|
||||
|
||||
@ -99,24 +128,26 @@ async def get_mz(name_mz: str) -> str:
|
||||
except IndexError:
|
||||
num = -1
|
||||
try:
|
||||
data0 = get_json(name)
|
||||
data = data0['命之座']
|
||||
data = get_json_mz(name)
|
||||
except:
|
||||
return f"派蒙这没有 <code>{name}</code> ,可能是官方资料没有该资料,可能是你输入的名字不正确哦。"
|
||||
result = ''
|
||||
if num == -1:
|
||||
n = 1
|
||||
for key, value in data.items():
|
||||
result = result + num_to_char(n) + '命' + key + ':' + str(value['introduction']) + '\n'
|
||||
for i in range(6):
|
||||
try:
|
||||
result = result + f"{num_to_char(n)}命{data['c{}'.format(n)]['name']}:" \
|
||||
f"{data['c{}'.format(n)]['effect'].replace('*', '')}\n"
|
||||
except KeyError:
|
||||
break
|
||||
n = n + 1
|
||||
return f'{name}' + '\n' + result
|
||||
elif 0 < num < 7:
|
||||
n = 1
|
||||
for key, value in data.items():
|
||||
result = num_to_char(num) + '命' + key + ':' + str(value['introduction'])
|
||||
if n == num:
|
||||
return f'{name}的' + result
|
||||
n = n + 1
|
||||
try:
|
||||
return f'{name}的' + f"{num_to_char(num)}命{data['c{}'.format(num)]['name']}:" \
|
||||
f"{data['c{}'.format(num)]['effect'].replace('*', '')}\n"
|
||||
except KeyError:
|
||||
return f"查询错误!你家 <code>{name}</code> 有 <code>{num}</code> 命??"
|
||||
elif num == 0:
|
||||
return "你搁这原地tp呢?"
|
||||
else:
|
||||
|
126
defs/event.py
Normal file
126
defs/event.py
Normal file
@ -0,0 +1,126 @@
|
||||
import time
|
||||
import datetime
|
||||
import os
|
||||
from requests import get
|
||||
from io import BytesIO
|
||||
from PIL import Image, ImageDraw, ImageFont
|
||||
from defs.redis_load import redis_status, redis
|
||||
|
||||
|
||||
def ys_font(size):
|
||||
return ImageFont.truetype(f"assets{os.sep}fonts{os.sep}ZhuZiAWan-2.ttc", size=size)
|
||||
|
||||
|
||||
def generate_event():
|
||||
# 生成图片到 temp 文件夹
|
||||
TEXT_PATH = f"assets{os.sep}event"
|
||||
raw_data = get(
|
||||
"https://hk4e-api.mihoyo.com/common/hk4e_cn/announcement/api/getAnnList?game=hk4e&game_biz=hk4e_cn&lang=zh-cn"
|
||||
"&bundle_id=hk4e_cn&platform=pc®ion=cn_gf01&level=55&uid=100000000").json()
|
||||
now_time = datetime.datetime.now().strftime('%Y-%m-%d')
|
||||
raw_time_data = get(
|
||||
"https://api-takumi.mihoyo.com/event/bbs_activity_calendar/getActList?"
|
||||
"time={}&game_biz=ys_cn&page=1&tag_id=0".format(now_time)).json()
|
||||
|
||||
data = raw_data["data"]["list"][1]["list"]
|
||||
|
||||
event_data = {"gacha_event": [], "normal_event": [], "other_event": []}
|
||||
for k in data:
|
||||
for i in raw_time_data["data"]["act_list"]:
|
||||
if i["name"] == k["title"]:
|
||||
k["act_begin_time"] = i["act_begin_time"]
|
||||
k["act_end_time"] = i["act_end_time"]
|
||||
elif "神铸赋形" in k["title"] and "神铸赋形" in i["name"]:
|
||||
k["act_begin_time"] = i["act_begin_time"]
|
||||
k["act_end_time"] = i["act_end_time"]
|
||||
elif "传说任务" in k["title"]:
|
||||
k["act_begin_time"] = k["start_time"]
|
||||
k["act_end_time"] = "永久开放"
|
||||
elif k["subtitle"] in i["name"]:
|
||||
k["act_begin_time"] = i["act_begin_time"]
|
||||
k["act_end_time"] = i["act_end_time"]
|
||||
else:
|
||||
k["act_begin_time"] = "{}-{}-{} {}".format(k["start_time"].split()[0].split("-")[0],
|
||||
k["start_time"].split()[0].split("-")[1],
|
||||
str(int(k["start_time"].split()[0].split("-")[2]) + 2),
|
||||
"10:00:00(?)")
|
||||
k["act_end_time"] = k["end_time"]
|
||||
|
||||
if "冒险助力礼包" in k["title"] or "纪行" in k["title"]:
|
||||
continue
|
||||
# if "角色试用" in k["title"] or "传说任务" in k["title"]:
|
||||
# event_data['other_event'].append(k)
|
||||
elif k["tag_label"] == "扭蛋":
|
||||
event_data['gacha_event'].append(k)
|
||||
elif k["tag_label"] == "活动":
|
||||
event_data['normal_event'].append(k)
|
||||
|
||||
# base_h = 900 + ((1 + (len(event_data['normal_event'])+len(event_data['other_event'])))//2)*390 +
|
||||
# ((1 + len(event_data['gacha_event']))//2)*533
|
||||
base_h = 600 + len(event_data['normal_event']) * (390 + 90) + len(event_data['gacha_event']) * (533 + 90)
|
||||
base_img = Image.new(mode="RGB", size=(1080, base_h), color=(237, 217, 195))
|
||||
|
||||
event1_path = os.path.join(TEXT_PATH, "event_1.png")
|
||||
event2_path = os.path.join(TEXT_PATH, "event_2.png")
|
||||
# event3_path = os.path.join(TEXT_PATH,"event_3.png")
|
||||
event1 = Image.open(event1_path)
|
||||
event2 = Image.open(event2_path)
|
||||
# event3 = Image.open(event3_path)
|
||||
|
||||
base_img.paste(event1, (0, 0), event1)
|
||||
# base_img.paste(event2,(0,300+((1+len(event_data['normal_event']))//2)*390),event2)
|
||||
base_img.paste(event2, (0, len(event_data['normal_event']) * (390 + 90) + 300), event2)
|
||||
# base_img.paste(event3,(0,600+((1+len(event_data['normal_event']))//2)*390 + ((1 +
|
||||
# len(event_data['gacha_event']))//2)*533),event3)
|
||||
|
||||
time_img1 = Image.new(mode="RGB", size=(1080, len(event_data['normal_event']) * (390 + 90)),
|
||||
color=(237, 130, 116))
|
||||
time_img2 = Image.new(mode="RGB", size=(1080, len(event_data['gacha_event']) * (533 + 90)),
|
||||
color=(237, 130, 116))
|
||||
base_img.paste(time_img1, (0, 300))
|
||||
base_img.paste(time_img2, (0, 600 + len(event_data['normal_event']) * (390 + 90)))
|
||||
base_draw = ImageDraw.Draw(base_img)
|
||||
for index, value in enumerate(event_data['normal_event']):
|
||||
img = Image.open(BytesIO(get(value["banner"]).content))
|
||||
base_draw.text((540, 300 + 45 + 390 + (390 + 90) * index + 1),
|
||||
value["act_begin_time"] + " —— " + value["act_end_time"], (255, 255, 255), ys_font(42),
|
||||
anchor="mm")
|
||||
# base_img.paste(img,((index%2)*1080,300 + 390*(index//2)))
|
||||
base_img.paste(img, (0, 300 + (390 + 90) * index))
|
||||
|
||||
for index, value in enumerate(event_data['gacha_event']):
|
||||
img = Image.open(BytesIO(get(value["banner"]).content))
|
||||
base_draw.text((540, 600 + 45 + (390 + 90) * len(event_data['normal_event']) + 533 + index * (533 + 90)),
|
||||
value["act_begin_time"] + " —— " + value["act_end_time"], (255, 255, 255), ys_font(42),
|
||||
anchor="mm")
|
||||
# base_img.paste(img,((index%2)*1080,600 + ((1 + len(event_data['normal_event']))//2)*390 +
|
||||
# 533*(index//2)))
|
||||
base_img.paste(img, (0, 600 + (390 + 90) * len(event_data['normal_event']) + index * (533 + 90)))
|
||||
# for index,value in enumerate(event_data['other_event']):
|
||||
# img = Image.open(BytesIO(get(value["banner"]).content))
|
||||
# base_img.paste(img,((index%2)*1080,900 + ((1 + len(event_data['normal_event']))//2)*390 +
|
||||
# ((1 + len(event_data['gacha_event']))//2)*533 + 390*(index//2)))
|
||||
|
||||
base_img = base_img.convert('RGB')
|
||||
base_img.save(f'temp{os.sep}event.jpg', format='JPEG', subsampling=0, quality=90)
|
||||
|
||||
# 更新缓存的日程的更新日期
|
||||
if redis_status():
|
||||
redis.set('event', time.strftime("%Y-%m-%d"))
|
||||
|
||||
|
||||
def get_event_image():
|
||||
# 判断是否需要重新生成事件,无 redis 每次生成。
|
||||
if redis_status():
|
||||
try:
|
||||
date = redis.get('event').decode()
|
||||
except AttributeError:
|
||||
date = None
|
||||
if not date == time.strftime("%Y-%m-%d"):
|
||||
generate_event()
|
||||
return f'temp{os.sep}event.jpg'
|
||||
else:
|
||||
return redis.get('event_file_id').decode()
|
||||
else:
|
||||
generate_event()
|
||||
return f'temp{os.sep}event.jpg'
|
@ -1,3 +1,5 @@
|
||||
from os.path import exists
|
||||
|
||||
from PIL import Image, ImageMath
|
||||
from io import BytesIO
|
||||
import json
|
||||
@ -75,8 +77,9 @@ async def download_icon(url):
|
||||
async def download_json(url):
|
||||
# 获取资源数据,返回 JSON
|
||||
if url == POINT_LIST_URL:
|
||||
with open(f"assets{os.sep}data{os.sep}list.json", "rb") as f:
|
||||
return json.loads(f.read())
|
||||
if exists(f"assets{os.sep}data{os.sep}list.json"):
|
||||
with open(f"assets{os.sep}data{os.sep}list.json", "rb") as f:
|
||||
return json.loads(f.read())
|
||||
async with httpx.AsyncClient() as client:
|
||||
resp = await client.get(url=url)
|
||||
if resp.status_code != 200:
|
||||
|
17
plugins/event.py
Normal file
17
plugins/event.py
Normal file
@ -0,0 +1,17 @@
|
||||
from pyrogram import Client
|
||||
from pyrogram.types import Message
|
||||
from defs.event import get_event_image
|
||||
from defs.redis_load import redis
|
||||
|
||||
|
||||
async def event_msg(client: Client, message: Message):
|
||||
# 活动列表
|
||||
text = '旅行者你好,这是提瓦特大陆今日份的活动列表。'
|
||||
path = get_event_image()
|
||||
if 'event.jpg' in path:
|
||||
# 开始上传
|
||||
msg = await message.reply_document(document=path, caption=text, quote=True)
|
||||
# 缓存 file_id
|
||||
redis.set('event_file_id', msg.document.file_id)
|
||||
else:
|
||||
await message.reply_document(document=path, caption=text, quote=True)
|
@ -5,6 +5,7 @@ from plugins.start import welcome_command, ping_command, help_command, leave_com
|
||||
from plugins.almanac import almanac_msg
|
||||
from plugins.challenge import tf_msg, wq_msg, zb_msg
|
||||
from plugins.character import character_msg, mz_msg
|
||||
from plugins.event import event_msg
|
||||
from plugins.weapons import weapon_msg
|
||||
from plugins.fortunate import fortunate_msg, set_fortunate_img
|
||||
from plugins.artifact_rate import artifact_rate_msg
|
||||
@ -31,6 +32,9 @@ async def process_private_msg(client: Client, message: Message):
|
||||
if '黄历' in message.text:
|
||||
await almanac_msg(client, message)
|
||||
await log(client, message, '查询原神黄历')
|
||||
if '活动列表' in message.text:
|
||||
await event_msg(client, message)
|
||||
await log(client, message, '查询活动列表')
|
||||
# 授权管理员
|
||||
# if msg_list[0] == '/promote':
|
||||
# await promote_command(client, message)
|
||||
@ -52,13 +56,13 @@ async def process_private_msg(client: Client, message: Message):
|
||||
await zb_msg(client, message)
|
||||
await log(client, message, '查询周本')
|
||||
# # 角色查询
|
||||
# if '角色资料' in message.text or '角色简介' in message.text or '角色查询' in message.text:
|
||||
# await character_msg(client, message)
|
||||
# await log(client, message, '查询角色资料')
|
||||
if '角色资料' in message.text or '角色简介' in message.text or '角色查询' in message.text:
|
||||
await character_msg(client, message)
|
||||
await log(client, message, '查询角色资料')
|
||||
# # 命座查询
|
||||
# if '命座' in message.text:
|
||||
# await mz_msg(client, message)
|
||||
# await log(client, message, '查询角色命座')
|
||||
if '命座' in message.text:
|
||||
await mz_msg(client, message)
|
||||
await log(client, message, '查询角色命座')
|
||||
# 设置运势
|
||||
if '设置运势' in message.text:
|
||||
await set_fortunate_img(client, message)
|
||||
@ -104,6 +108,9 @@ async def process_group_msg(client: Client, message: Message):
|
||||
if message.text == '原神黄历':
|
||||
await almanac_msg(client, message)
|
||||
await log(client, message, '查询原神黄历')
|
||||
if message.text == '活动列表':
|
||||
await event_msg(client, message)
|
||||
await log(client, message, '查询活动列表')
|
||||
# 天赋
|
||||
if text[-2:] == '天赋':
|
||||
await tf_msg(client, message)
|
||||
@ -113,13 +120,13 @@ async def process_group_msg(client: Client, message: Message):
|
||||
await zb_msg(client, message)
|
||||
await log(client, message, '查询周本')
|
||||
# # 角色查询
|
||||
# if text.startswith('角色资料') or text.startswith('角色简介') or text.startswith('角色查询'):
|
||||
# await character_msg(client, message)
|
||||
# await log(client, message, '查询角色资料')
|
||||
if text.startswith('角色资料') or text.startswith('角色简介') or text.startswith('角色查询'):
|
||||
await character_msg(client, message)
|
||||
await log(client, message, '查询角色资料')
|
||||
# # 命座查询
|
||||
# if text.startswith('命座'):
|
||||
# await mz_msg(client, message)
|
||||
# await log(client, message, '查询角色命座')
|
||||
if text.startswith('命座'):
|
||||
await mz_msg(client, message)
|
||||
await log(client, message, '查询角色命座')
|
||||
# 运势查询
|
||||
if text.startswith('运势') or text.startswith('今日运势'):
|
||||
await fortunate_msg(client, message)
|
||||
|
@ -47,15 +47,16 @@ async def help_command(client: Client, message: Message):
|
||||
'④ [运势 (名字)] 查看今日运势\n' \
|
||||
' 💠 <code>运势 (重云)</code>\n' \
|
||||
' 💠 <code>设置运势 (重云)</code>\n' \
|
||||
'⑤ [原神黄历] 查看随机生成的原神黄历\n' \
|
||||
'⑥ [圣遗物评分] 我也想拥有这种分数的圣遗物(切实)\n' \
|
||||
'⑦ [哪里有 (资源名)] 查看资源的位置\n' \
|
||||
'⑧ [资源列表] 查看原神所有资源'
|
||||
'⑤ [角色查询 名字] 查看人物简介\n' \
|
||||
' 💠 <code>角色查询 重云</code>\n' \
|
||||
'⑥ [命座 名字] 查看人物命座\n' \
|
||||
' 💠 <code>命座 重云一命</code>\n' \
|
||||
'⑦ [原神黄历] 查看随机生成的原神黄历\n' \
|
||||
'⑧ [活动列表] 查看今日活动列表和祈愿列表\n' \
|
||||
'⑨ [圣遗物评分] 我也想拥有这种分数的圣遗物(切实)\n' \
|
||||
'⑩ [哪里有 (资源名)] 查看资源的位置\n' \
|
||||
'(11) [资源列表] 查看原神所有资源'
|
||||
await message.reply(text, quote=True, disable_web_page_preview=True)
|
||||
|
||||
# '④ [武器查询 武器名] 查看武器资料\n' \
|
||||
# ' 💠 <code>武器查询 沐浴龙血的剑</code>\n' \
|
||||
# '⑤ [角色查询 名字] 查看人物简介\n' \
|
||||
# ' 💠 <code>角色查询 重云</code>\n' \
|
||||
# '⑥ [命座 名字] 查看人物命座\n' \
|
||||
# ' 💠 <code>命座 重云一命</code>\n' \
|
||||
|
@ -7,4 +7,5 @@ beautifulsoup4>=4.9.3
|
||||
requests>=2.27.1
|
||||
xpinyin>=0.7.6
|
||||
lxml>=4.6.3
|
||||
httpx>=0.21.3
|
||||
httpx>=0.21.3
|
||||
pyyaml>=6.0
|
||||
|
Loading…
Reference in New Issue
Block a user