mirror of
https://github.com/LiteyukiStudio/nonebot-plugin-acgnshow.git
synced 2024-11-11 01:27:39 +08:00
✨v0.2,不会接受字数大于5的展览查询,添加展览详细信息展示,返回详细错误信息
This commit is contained in:
parent
80a9b4d565
commit
d5eeea6c80
@ -80,3 +80,4 @@ _✨ 从哔哩哔哩会员购获取展览简易信息 ✨_
|
|||||||
| 配置项 | 必填 | 默认值 | 说明 |
|
| 配置项 | 必填 | 默认值 | 说明 |
|
||||||
| :---------------: | :--: | :----: | :----------------------------------------------------------: |
|
| :---------------: | :--: | :----: | :----------------------------------------------------------: |
|
||||||
| ACGNSHOW_PAGESIZE | 否 | 8 | 单个图片的条目数,最大为 20,条目数过大可能导致 Bot 无法发送 |
|
| ACGNSHOW_PAGESIZE | 否 | 8 | 单个图片的条目数,最大为 20,条目数过大可能导致 Bot 无法发送 |
|
||||||
|
| ACGNSHOW_BGIMAGE_PATH | 否 | 插件内置背景图 | 插件返回图片的背景图目录路径 |
|
@ -10,14 +10,19 @@ usage = """命令格式:
|
|||||||
展览 <地区> [页码]
|
展览 <地区> [页码]
|
||||||
或
|
或
|
||||||
<地区>展览 [页码]
|
<地区>展览 [页码]
|
||||||
|
获取指定地区的展览列表
|
||||||
其中地区为省级行政区或地级行政区(不包含后缀)
|
其中地区为省级行政区或地级行政区(不包含后缀)
|
||||||
(如北京,福建,平顶山,绍兴,香港...,或海外/全国)
|
(如北京,福建,平顶山,绍兴,香港...,或海外/全国)
|
||||||
|
|
||||||
|
展览详情 <ID>
|
||||||
|
其中ID为展览列表处返回的ID
|
||||||
|
|
||||||
示例:
|
示例:
|
||||||
展览 福建 2
|
展览 福建 2
|
||||||
福建展览 2
|
福建展览 2
|
||||||
全国展览
|
全国展览
|
||||||
海外展览
|
海外展览
|
||||||
|
展览详情 86827
|
||||||
|
|
||||||
※数据来源于哔哩哔哩会员购,由于API返回结果与实际存在差异,数据可能不准确。"""
|
※数据来源于哔哩哔哩会员购,由于API返回结果与实际存在差异,数据可能不准确。"""
|
||||||
__author__ = "Asankilp"
|
__author__ = "Asankilp"
|
||||||
|
@ -7,6 +7,7 @@ from .util import *
|
|||||||
|
|
||||||
CITY_API_ROOT = "https://show.bilibili.com/api/ticket/city/list?channel=3"
|
CITY_API_ROOT = "https://show.bilibili.com/api/ticket/city/list?channel=3"
|
||||||
SHOWS_API_ROOT = "https://show.bilibili.com/api/ticket/project/listV2"
|
SHOWS_API_ROOT = "https://show.bilibili.com/api/ticket/project/listV2"
|
||||||
|
SHOW_DETAILS_API_ROOT = "https://show.bilibili.com/api/ticket/project/getV2"
|
||||||
HEADERS = {
|
HEADERS = {
|
||||||
"user-agent": "Mozilla/5.0 (Linux; Android 14; 114514YAJU Build/UKQ1.114514.001; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/125.0.6422.165 Mobile Safari/537.36 BiliApp/7810200 mobi_app/android isNotchWindow/0 NotchHeight=34 mallVersion/7810200 mVersion/242 disable_rcmd/0 7.81.0 os/android model/114514YAJU mobi_app/android build/7810200 channel/bilih5 innerVer/7810210 osVer/14 network/2"
|
"user-agent": "Mozilla/5.0 (Linux; Android 14; 114514YAJU Build/UKQ1.114514.001; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/125.0.6422.165 Mobile Safari/537.36 BiliApp/7810200 mobi_app/android isNotchWindow/0 NotchHeight=34 mallVersion/7810200 mVersion/242 disable_rcmd/0 7.81.0 os/android model/114514YAJU mobi_app/android build/7810200 channel/bilih5 innerVer/7810210 osVer/14 network/2"
|
||||||
}
|
}
|
||||||
@ -57,28 +58,74 @@ async def get_shows_data(region_id: int, page=1, pagesize=20):
|
|||||||
shows_data = await resp.json()
|
shows_data = await resp.json()
|
||||||
return shows_data
|
return shows_data
|
||||||
|
|
||||||
|
async def get_show_details(show_id: int):
|
||||||
|
param = {
|
||||||
|
"id": show_id,
|
||||||
|
"project_id": show_id,
|
||||||
|
"requestSource": "neul-next"
|
||||||
|
}
|
||||||
|
async with ClientSession() as session:
|
||||||
|
async with session.get(SHOW_DETAILS_API_ROOT, headers=HEADERS, params=param) as resp:
|
||||||
|
show_details_data = await resp.json()
|
||||||
|
return show_details_data
|
||||||
|
|
||||||
# def process_shows_data_to_text(shows_data: dict):
|
def process_show_details_data_to_template(show_details_data: dict):
|
||||||
# showlist = []
|
data = show_details_data["data"]
|
||||||
# data = shows_data["data"]
|
|
||||||
# total_pages = data["numPages"]
|
|
||||||
# result = data["result"]
|
|
||||||
# for i in result:
|
|
||||||
# name = i["project_name"]
|
|
||||||
# venue_name = i["venue_name"]
|
|
||||||
# project_id = i["project_id"]
|
|
||||||
# sale_flag = i["sale_flag"]
|
|
||||||
# # start_time = i["start_time"]
|
|
||||||
# start_unix = i["start_unix"]
|
|
||||||
# start_time = convert_timestamp(start_unix)
|
|
||||||
# end_time = i["end_time"]
|
|
||||||
# price_low = i["price_low"] / 100
|
|
||||||
# price_high = i["price_high"] / 100
|
|
||||||
# district_name = i["district_name"]
|
|
||||||
# text = f"名称:{name}\n举办地:{venue_name}\nid:{project_id}\nflag:{sale_flag}\n开始时间:{start_time}\n结束时间:{end_time}\n最低票价:{price_low}\n最高票价:{price_high}\n区名:{district_name}\n\n"
|
|
||||||
# showlist.append(text)
|
|
||||||
# return showlist
|
|
||||||
|
|
||||||
|
banner_url = "https:"+data["banner"]
|
||||||
|
# banner_url = extract_banner_url(data["performance_image"])
|
||||||
|
|
||||||
|
# 提取事件基本信息
|
||||||
|
name = data["name"]
|
||||||
|
start_time = convert_timestamp(data["start_time"])
|
||||||
|
end_time = convert_timestamp(data["end_time"])
|
||||||
|
|
||||||
|
# 提取场馆信息
|
||||||
|
venue_name = data["venue_info"]["name"]
|
||||||
|
venue_detail = data["venue_info"]["address_detail"]
|
||||||
|
|
||||||
|
# 提取主办方信息
|
||||||
|
organizer = data["merchant"]["company"]
|
||||||
|
|
||||||
|
# 提取实名制,退票等信息
|
||||||
|
is_refund = data["is_refund"]
|
||||||
|
id_bind = data["id_bind"]
|
||||||
|
has_eticket = data["has_eticket"]
|
||||||
|
|
||||||
|
# 提取票务信息
|
||||||
|
ticket_info = []
|
||||||
|
for screen in data.get("screen_list", []):
|
||||||
|
for ticket in screen.get("ticket_list", []):
|
||||||
|
ticket_info.append({
|
||||||
|
"description": ticket.get("desc", ""),
|
||||||
|
"price": ticket.get("price", 0),
|
||||||
|
"sale_start": convert_timestamp(ticket.get("saleStart", 0)),
|
||||||
|
"sale_end": convert_timestamp(ticket.get("saleEnd", 0)),
|
||||||
|
"status": ticket.get("sale_flag", {}).get("display_name", "")
|
||||||
|
})
|
||||||
|
guests_list = data["guests"]
|
||||||
|
if guests_list != None:
|
||||||
|
guests = "、".join(n["name"] for n in guests_list)
|
||||||
|
else:
|
||||||
|
guests = ""
|
||||||
|
|
||||||
|
# 构建返回的字典
|
||||||
|
item_dict = {
|
||||||
|
"banner_url": banner_url,
|
||||||
|
"name": name,
|
||||||
|
"start_time": start_time,
|
||||||
|
"end_time": end_time,
|
||||||
|
"venue_name": venue_name,
|
||||||
|
"venue_detail": venue_detail,
|
||||||
|
"organizer": organizer,
|
||||||
|
"ticket_info": ticket_info,
|
||||||
|
"guests": guests,
|
||||||
|
"is_refund": is_refund,
|
||||||
|
"id_bind": id_bind,
|
||||||
|
"has_eticket": has_eticket
|
||||||
|
}
|
||||||
|
|
||||||
|
return item_dict
|
||||||
|
|
||||||
def process_shows_data_to_template(shows_data: dict):
|
def process_shows_data_to_template(shows_data: dict):
|
||||||
showlist = []
|
showlist = []
|
||||||
|
@ -7,7 +7,7 @@ from nonebot_plugin_htmlrender import template_to_pic
|
|||||||
from nonebot_plugin_alconna import on_alconna
|
from nonebot_plugin_alconna import on_alconna
|
||||||
from nonebot_plugin_alconna.uniseg import UniMessage
|
from nonebot_plugin_alconna.uniseg import UniMessage
|
||||||
from arclet.alconna import Alconna, Args
|
from arclet.alconna import Alconna, Args
|
||||||
from .config import RES_PATH, TEMPLATE_NAME, config
|
from .config import RES_PATH, LIST_TEMPLATE_NAME, DETAILS_TEMPLATE_NAME, config
|
||||||
from .util import *
|
from .util import *
|
||||||
from .__init__ import __plugin_meta__
|
from .__init__ import __plugin_meta__
|
||||||
|
|
||||||
@ -25,10 +25,43 @@ showcmd.shortcut(
|
|||||||
"args": ["{region}", "{page}", "{date}"],
|
"args": ["{region}", "{page}", "{date}"],
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
showcmd_details = on_alconna(
|
||||||
|
Alconna(
|
||||||
|
"展览详情",
|
||||||
|
Args["id?", int], # 这里定义了一个必需的 int 参数 "id"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
showcmd_details.shortcut(
|
||||||
|
r"展览详情\s*(?P<id>\d+)", # 正则表达式匹配 "展览详情" 后跟一个整数 ID
|
||||||
|
{
|
||||||
|
"prefix": True,
|
||||||
|
"command": "展览详情",
|
||||||
|
"args": ["{id}"], # 将 ID 参数传递给命令
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
@showcmd_details.handle()
|
||||||
|
async def get_show_details_cmd(
|
||||||
|
id: Optional[int] = None
|
||||||
|
):
|
||||||
|
show_details = await get_show_details(id)
|
||||||
|
if show_details["errno"] != 0: await UniMessage("发生错误").send() ; return
|
||||||
|
try:
|
||||||
|
show_details_data = process_show_details_data_to_template(show_details)
|
||||||
|
print(show_details_data)
|
||||||
|
template = {
|
||||||
|
"show": show_details_data,
|
||||||
|
"bgimage": choose_random_bgimage(),
|
||||||
|
}
|
||||||
|
pic = await template_to_pic(str(RES_PATH), DETAILS_TEMPLATE_NAME, template)
|
||||||
|
except Exception as e:
|
||||||
|
await UniMessage(f"图片生成时产生错误:\n{str(e)}").send()
|
||||||
|
traceback.print_exc()
|
||||||
|
return
|
||||||
|
await UniMessage.image(raw=pic).send()
|
||||||
|
|
||||||
@showcmd.handle()
|
@showcmd.handle()
|
||||||
async def find_show(
|
async def find_shows_cmd(
|
||||||
region: Optional[str] = None,
|
region: Optional[str] = None,
|
||||||
page: Optional[int] = None,
|
page: Optional[int] = None,
|
||||||
date: Optional[str] = None,
|
date: Optional[str] = None,
|
||||||
@ -36,6 +69,8 @@ async def find_show(
|
|||||||
if not region:
|
if not region:
|
||||||
await UniMessage(__plugin_meta__.usage).send()
|
await UniMessage(__plugin_meta__.usage).send()
|
||||||
return
|
return
|
||||||
|
if len(region) > 5:
|
||||||
|
return
|
||||||
if not page:
|
if not page:
|
||||||
page = 1
|
page = 1
|
||||||
if not date:
|
if not date:
|
||||||
@ -55,9 +90,9 @@ async def find_show(
|
|||||||
"bgimage": choose_random_bgimage(),
|
"bgimage": choose_random_bgimage(),
|
||||||
"global_data": shows_data[1],
|
"global_data": shows_data[1],
|
||||||
}
|
}
|
||||||
pic = await template_to_pic(str(RES_PATH), TEMPLATE_NAME, template)
|
pic = await template_to_pic(str(RES_PATH), LIST_TEMPLATE_NAME, template)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
await UniMessage("图片生成时产生未知错误").send()
|
await UniMessage(f"图片生成时产生错误:\n{str(e)}").send()
|
||||||
traceback.print_exc()
|
traceback.print_exc()
|
||||||
return
|
return
|
||||||
|
|
||||||
|
@ -3,7 +3,8 @@ from pydantic import BaseModel
|
|||||||
from nonebot import get_plugin_config
|
from nonebot import get_plugin_config
|
||||||
|
|
||||||
RES_PATH = Path(__file__).parent / "res"
|
RES_PATH = Path(__file__).parent / "res"
|
||||||
TEMPLATE_NAME = "template.html"
|
LIST_TEMPLATE_NAME = "template.html"
|
||||||
|
DETAILS_TEMPLATE_NAME = "details.html"
|
||||||
BGIMAGE_PATH = RES_PATH / "bgimage"
|
BGIMAGE_PATH = RES_PATH / "bgimage"
|
||||||
|
|
||||||
|
|
||||||
|
@ -7,31 +7,52 @@ body {
|
|||||||
font-family: "Source Han Sans", sans-serif;
|
font-family: "Source Han Sans", sans-serif;
|
||||||
}
|
}
|
||||||
|
|
||||||
.container, .header, .content, .footer, .details, .image {
|
.background {
|
||||||
border: 1px solid black;
|
position: fixed;
|
||||||
box-sizing: border-box;
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
background-size: cover;
|
||||||
|
filter: blur(40%);
|
||||||
|
z-index: -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
.container {
|
.container {
|
||||||
width: 98%;
|
width: 98%;
|
||||||
margin: 1%;
|
margin: 1%;
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
background-color: rgba(255, 255, 255, 0.8);
|
border: 1px solid #fff;
|
||||||
|
box-sizing: border-box;
|
||||||
|
background-color: rgba(255, 255, 255, 0.8); /* 半透明白色背景 */
|
||||||
}
|
}
|
||||||
|
|
||||||
.header, .designer {
|
.header {
|
||||||
|
border: 1px solid black;
|
||||||
|
padding: 5px;
|
||||||
|
margin-bottom: 10px;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
font-size: 10px;
|
font-size: 10px;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
padding: 5px;
|
|
||||||
margin: 10px 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.content {
|
.content {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
border: 1px solid black;
|
||||||
margin-bottom: 10px;
|
margin-bottom: 10px;
|
||||||
padding: 5px;
|
padding: 5px;
|
||||||
position: relative;
|
position: relative;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
.detail_content {
|
||||||
|
display: flex;
|
||||||
|
border: 1px solid black;
|
||||||
|
height: 201px;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
padding: 5px;
|
||||||
|
position: relative;
|
||||||
|
box-sizing: border-box;
|
||||||
}
|
}
|
||||||
|
|
||||||
.image {
|
.image {
|
||||||
@ -39,6 +60,37 @@ body {
|
|||||||
height: 201px;
|
height: 201px;
|
||||||
border: 1px solid rgba(128, 64, 128, 0.5);
|
border: 1px solid rgba(128, 64, 128, 0.5);
|
||||||
text-align: center;
|
text-align: center;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
.vector_icon {
|
||||||
|
width: 20px;
|
||||||
|
height: 20px;
|
||||||
|
vertical-align: bottom;
|
||||||
|
margin-left: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.banner {
|
||||||
|
margin-bottom: 15px;
|
||||||
|
border: 2px solid #000; /* 为 banner 添加边框 */
|
||||||
|
display: flex;
|
||||||
|
justify-content: center; /* 居中对齐图片 */
|
||||||
|
align-items: center; /* 垂直居中对齐图片 */
|
||||||
|
}
|
||||||
|
|
||||||
|
.banner img {
|
||||||
|
width: 450px;
|
||||||
|
height: 253px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.details .ticket_box {
|
||||||
|
display: inline-block; /* 根据内容的宽度自动调整 */
|
||||||
|
background-color: rgba(255, 255, 255, 0.1); /* 半透明白色背景 */
|
||||||
|
border-radius: 15px; /* 圆角半径 */
|
||||||
|
padding: 20px; /* 内边距 */
|
||||||
|
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); /* 添加阴影以增强视觉效果 */
|
||||||
|
text-align: center; /* 内容水平居中 */
|
||||||
|
width: auto; /* 根据内容宽度自动调整 */
|
||||||
}
|
}
|
||||||
|
|
||||||
.details {
|
.details {
|
||||||
@ -46,38 +98,31 @@ body {
|
|||||||
padding-left: 10px;
|
padding-left: 10px;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
position: relative; /* 使子元素绝对定位相对于这个父元素 */
|
||||||
font-size: 10px;
|
font-size: 10px;
|
||||||
position: relative;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.details .title {
|
.details .title {
|
||||||
font-weight: bold;
|
font-weight: bold; /* 加粗字体 */
|
||||||
margin-bottom: 5px;
|
margin-bottom: 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.details .venue_name,
|
.details .venue_name,
|
||||||
.details .guests,
|
.details .guests,
|
||||||
.details .placeholder,
|
.details .placeholder {
|
||||||
.details .price,
|
|
||||||
.details .wish,
|
|
||||||
.details .start-time,
|
|
||||||
.details .end-time {
|
|
||||||
margin-bottom: 5px;
|
margin-bottom: 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.details .sale_flag,
|
|
||||||
.details .id {
|
|
||||||
position: absolute;
|
|
||||||
font-size: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.details .sale_flag {
|
.details .sale_flag {
|
||||||
color: red;
|
color: red;
|
||||||
|
position: absolute;
|
||||||
top: 5px;
|
top: 5px;
|
||||||
right: 5px;
|
right: 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.details .id {
|
.details .id {
|
||||||
|
color: black;
|
||||||
|
position: absolute;
|
||||||
top: 20px;
|
top: 20px;
|
||||||
right: 5px;
|
right: 5px;
|
||||||
}
|
}
|
||||||
@ -85,32 +130,53 @@ body {
|
|||||||
.details .price {
|
.details .price {
|
||||||
color: #fb7299;
|
color: #fb7299;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
|
position: absolute;
|
||||||
bottom: 5px;
|
bottom: 5px;
|
||||||
left: 5px;
|
left: 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.details .status {
|
||||||
|
position: absolute;
|
||||||
|
display: flex;
|
||||||
|
bottom: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
.details .wish {
|
.details .wish {
|
||||||
color: gray;
|
color: gray;
|
||||||
|
position: absolute;
|
||||||
bottom: 5px;
|
bottom: 5px;
|
||||||
left: 60px;
|
left: 60px; /* 适当调整以避免与price重叠 */
|
||||||
}
|
}
|
||||||
|
|
||||||
.details .start-time {
|
.details .start-time {
|
||||||
bottom: 20px;
|
position: absolute;
|
||||||
|
bottom: 20px; /* 与end-time有一定的高度差异 */
|
||||||
right: 5px;
|
right: 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.details .end-time {
|
.details .end-time {
|
||||||
|
position: absolute;
|
||||||
bottom: 5px;
|
bottom: 5px;
|
||||||
right: 5px;
|
right: 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.footer {
|
.footer {
|
||||||
|
border: 1px solid black;
|
||||||
|
flex: 1;
|
||||||
|
padding-left: 10px;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
font-size: 10px;
|
|
||||||
position: relative;
|
position: relative;
|
||||||
|
font-size: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer .designer {
|
||||||
|
text-align: center;
|
||||||
|
font-weight: bold;
|
||||||
|
font-size: 10px;
|
||||||
|
padding: 5px;
|
||||||
|
margin: 10px 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.footer .pages,
|
.footer .pages,
|
||||||
|
65
nonebot_plugin_acgnshow/res/details.html
Normal file
65
nonebot_plugin_acgnshow/res/details.html
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="zh-CN">
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8" />
|
||||||
|
<title>展览信息</title>
|
||||||
|
<link rel="stylesheet" href="./css/style.css" />
|
||||||
|
<style>
|
||||||
|
body {
|
||||||
|
background-image: url("{{ bgimage }}");
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<div class="background"></div>
|
||||||
|
<div class="container">
|
||||||
|
<div class="header">展览信息</div>
|
||||||
|
|
||||||
|
<!-- Banner 图 -->
|
||||||
|
<div class="banner">
|
||||||
|
<img src="{{ show.banner_url }}" alt="Banner" style="width: 450px; height: 253px;" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 单个展览内容 -->
|
||||||
|
<div class="detail_content">
|
||||||
|
<div class="details">
|
||||||
|
<div class="title">{{ show.name }}</div>
|
||||||
|
<div class="venue_name">地点:{{ show.venue_name }} {{show.venue_detail}}</div>
|
||||||
|
<div class="start-time">开始时间:{{ show.start_time }}</div>
|
||||||
|
<div class="end-time">结束时间:{{ show.end_time }}</div>
|
||||||
|
<div class="organizer">主办方:{{ show.organizer }}</div>
|
||||||
|
<div class="status">
|
||||||
|
{% macro icon(name) %}
|
||||||
|
<img src="./svg/{{ name }}.svg" class="vector_icon" width="8px" height="8px">
|
||||||
|
{% endmacro %}
|
||||||
|
{% if show.is_refund == 0 %}
|
||||||
|
{{ icon('no') }} 不可退
|
||||||
|
{% endif %}
|
||||||
|
{% if show.id_bind == 1 %}
|
||||||
|
{{ icon('yes') }} 实名制
|
||||||
|
{% endif %}
|
||||||
|
{% if show.has_eticket == True %}
|
||||||
|
{{ icon('yes') }} 电子票/兑换票
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
<div class="placeholder"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="details">
|
||||||
|
{% for ticket in show.ticket_info %}
|
||||||
|
<div class="ticket_box">{{ ticket.description }} {{ ticket.sale_start }} -- {{ ticket.sale_end }} ¥{{ ticket.price / 100 }} ({{ ticket.status }})</div>
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 页脚 -->
|
||||||
|
<div class="footer">
|
||||||
|
<div class="designer">Designed by Asankilp?</div>
|
||||||
|
<div class="project_name">nonebot-plugin-acgnshow</div>
|
||||||
|
<div class="notice_text">本页信息仅供参考,具体内容请访问展览官方详情页,并自行检索实际信息</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
1
nonebot_plugin_acgnshow/res/svg/no.svg
Normal file
1
nonebot_plugin_acgnshow/res/svg/no.svg
Normal file
@ -0,0 +1 @@
|
|||||||
|
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1724505806097" class="icon" viewBox="0 0 1028 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="10250" xmlns:xlink="http://www.w3.org/1999/xlink" width="200.78125" height="200"><path d="M875.086452 153.730058C676.053818-45.302575 353.260522-45.302575 154.128323 153.730058s-199.032634 521.825929 0 720.958129 521.825929 199.032634 720.958129 0 199.032634-521.825929 0-720.958129zM725.836868 725.438604c-9.757478 9.757478-25.488922 9.757478-35.246399 0L514.557604 549.405739 338.624306 725.438604c-9.757478 9.757478-25.488922 9.757478-35.2464 0s-9.757478-25.488922 0-35.2464l176.032865-176.032864-176.032865-175.933299c-9.757478-9.757478-9.757478-25.488922 0-35.246399 9.757478-9.757478 25.488922-9.757478 35.2464 0l176.032864 176.032865 176.032865-176.032865c9.757478-9.757478 25.488922-9.757478 35.246399 0 9.757478 9.757478 9.757478 25.488922 0 35.246399L549.804004 514.15934 725.836868 690.192204c9.657912 9.757478 9.657912 25.488922 0 35.2464z" fill="#F56C6C" p-id="10251"></path></svg>
|
After Width: | Height: | Size: 1.1 KiB |
1
nonebot_plugin_acgnshow/res/svg/yes.svg
Normal file
1
nonebot_plugin_acgnshow/res/svg/yes.svg
Normal file
@ -0,0 +1 @@
|
|||||||
|
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1724506220274" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="13079" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M512 76.8c-236.8 0-435.2 192-435.2 435.2s192 435.2 435.2 435.2 435.2-192 435.2-435.2S748.8 76.8 512 76.8z m249.6 320L480 704c-12.8 12.8-38.4 12.8-51.2 0L288 556.8c-12.8-12.8-12.8-38.4 0-51.2 12.8-12.8 38.4-12.8 51.2 0l115.2 115.2L704 339.2c12.8-12.8 38.4-12.8 51.2 0 25.6 12.8 25.6 38.4 6.4 57.6z" fill="#68D279" p-id="13080"></path><path d="M710.4 339.2l-256 281.6-115.2-115.2c-12.8-12.8-38.4-12.8-51.2 0-12.8 12.8-12.8 38.4 0 51.2l147.2 140.8c12.8 12.8 38.4 12.8 51.2 0L768 390.4c12.8-12.8 12.8-38.4 0-51.2-19.2-12.8-44.8-12.8-57.6 0z" fill="#FFFFFF" p-id="13081"></path></svg>
|
After Width: | Height: | Size: 913 B |
@ -1,6 +1,7 @@
|
|||||||
import os
|
import os
|
||||||
import random
|
import random
|
||||||
import datetime
|
import datetime
|
||||||
|
import json
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from .config import config
|
from .config import config
|
||||||
|
|
||||||
@ -20,3 +21,8 @@ def convert_timestamp(timestamp) -> str:
|
|||||||
将时间戳转换为日期格式
|
将时间戳转换为日期格式
|
||||||
"""
|
"""
|
||||||
return datetime.datetime.fromtimestamp(timestamp).strftime("%Y-%m-%d %H:%M:%S")
|
return datetime.datetime.fromtimestamp(timestamp).strftime("%Y-%m-%d %H:%M:%S")
|
||||||
|
|
||||||
|
def extract_banner_url(value) -> str:
|
||||||
|
a = json.loads(value)
|
||||||
|
url = "https:"+a["banner"]["url"]
|
||||||
|
return url
|
@ -1,6 +1,6 @@
|
|||||||
[project]
|
[project]
|
||||||
name = "nonebot-plugin-acgnshow"
|
name = "nonebot-plugin-acgnshow"
|
||||||
version = "0.1.5.1"
|
version = "0.2"
|
||||||
description = "Nonebot2插件,从哔哩哔哩会员购获取简易展览数据"
|
description = "Nonebot2插件,从哔哩哔哩会员购获取简易展览数据"
|
||||||
readme = "README.md"
|
readme = "README.md"
|
||||||
requires-python = "<4.0,>=3.9"
|
requires-python = "<4.0,>=3.9"
|
||||||
@ -10,7 +10,7 @@ dependencies = [
|
|||||||
"nonebot-plugin-alconna>=0.48.0",
|
"nonebot-plugin-alconna>=0.48.0",
|
||||||
"nonebot-plugin-htmlrender>=0.3.2",
|
"nonebot-plugin-htmlrender>=0.3.2",
|
||||||
"jinja2>=3.1.4",
|
"jinja2>=3.1.4",
|
||||||
"aiohttp>=3.9",
|
"aiohttp>=3.9"
|
||||||
]
|
]
|
||||||
license = { text = "MIT" }
|
license = { text = "MIT" }
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user