Merge pull request #1 from EillesWan/main

😑格式化代码,细节优化,修复了图片边框不完整的问题
This commit is contained in:
Akarin~ 2024-08-24 16:56:22 +08:00 committed by GitHub
commit d5017e687f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 145 additions and 85 deletions

View File

@ -10,7 +10,6 @@
_✨ 从哔哩哔哩会员购获取展览简易信息 ✨_
<a href="./LICENSE">
<img src="https://img.shields.io/github/license/LiteyukiStudio/nonebot-plugin-acgnshow.svg" alt="license">
</a>
@ -21,7 +20,6 @@ _✨ 从哔哩哔哩会员购获取展览简易信息 ✨_
</div>
## 📖 介绍
一个简单的 Nonebot2 插件,可以从哔哩哔哩会员购 API 获取展览(漫展等)的时间,地点,票价等信息。
@ -44,21 +42,25 @@ _✨ 从哔哩哔哩会员购获取展览简易信息 ✨_
<summary>pip</summary>
pip install nonebot-plugin-acgnshow
</details>
<details>
<summary>pdm</summary>
pdm add nonebot-plugin-acgnshow
</details>
<details>
<summary>poetry</summary>
poetry add nonebot-plugin-acgnshow
</details>
<details>
<summary>conda</summary>
conda install nonebot-plugin-acgnshow
</details>
打开 nonebot2 项目根目录下的 `pyproject.toml` 文件, 在 `[tool.nonebot]` 部分追加写入
@ -67,13 +69,14 @@ _✨ 从哔哩哔哩会员购获取展览简易信息 ✨_
</details>
## 🎉 使用
## 🎉 使用
发送`展览`指令可以获取使用说明
## ⚙️ 配置
在 nonebot2 项目的`.env`文件中添加下表中的配置
| 配置项 | 必填 | 默认值 | 说明 |
|:-----:|:----:|:----:|:----:|
| ACGNSHOW_PAGESIZE | 否 | 8 | 单个图片的条目数最大为20条目数过大可能导致 Bot 无法发送 |
| 配置项 | 必填 | 默认值 | 说明 |
| :---------------: | :--: | :----: | :----------------------------------------------------------: |
| ACGNSHOW_PAGESIZE | 否 | 8 | 单个图片的条目数,最大为 20条目数过大可能导致 Bot 无法发送 |

View File

@ -1,9 +1,11 @@
from nonebot.plugin import PluginMetadata, inherit_supported_adapters, require
require("nonebot_plugin_htmlrender")
require("nonebot_plugin_alconna")
from .acgnshower import *
from nonebot import get_driver
from .config import ConfigModel
usage = """命令格式:
展览 <地区> [页码]
@ -27,8 +29,8 @@ __plugin_meta__ = PluginMetadata(
config=ConfigModel,
homepage="https://github.com/LiteyukiStudio/nonebot-plugin-acgnshow",
supported_adapters=inherit_supported_adapters("nonebot_plugin_alconna"),
#extra={"License":"MIT","Author":"Swankily"} snowykami的奇妙纠错
extra={"License":"MIT","Author":"Asankilp"}
# extra={"License":"MIT","Author":"Swankily"} snowykami的奇妙纠错
extra={"License": "MIT", "Author": "Asankilp"},
)
driver = get_driver()
@ -36,4 +38,3 @@ driver = get_driver()
@driver.on_startup
async def _():
pass

View File

@ -9,7 +9,7 @@ from .util import *
CITY_API_ROOT = "https://show.bilibili.com/api/ticket/city/list?channel=3"
SHOWS_API_ROOT = "https://show.bilibili.com/api/ticket/project/listV2"
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"
}
@ -31,13 +31,8 @@ async def get_regions_dict() -> Dict[str, int]:
city_data = await get_cities_data()
for i in city_data.data.list:
for j in i.city_list:
data.update({
j.name: j.id
})
data.update({
"全国": -1,
"海外": 900000
})
data.update({j.name: j.id})
data.update({"全国": -1, "海外": 900000})
return data
@ -50,13 +45,13 @@ async def get_shows_data(region_id: int, page=1, pagesize=20):
pagesize: 一页最大条目数最大20
"""
param = {
"version" : 133,
"area" : region_id,
"page" : page,
"pagesize": pagesize,
"platform": "web",
"p_type" : "展览",
"style" : 1
"version": 133,
"area": region_id,
"page": page,
"pagesize": pagesize,
"platform": "web",
"p_type": "展览",
"style": 1,
}
async with ClientSession() as session:
async with session.get(SHOWS_API_ROOT, headers=HEADERS, params=param) as resp:
@ -108,30 +103,31 @@ def process_shows_data_to_template(shows_data: dict):
district_name = i["district_name"]
wish = i["wish"]
cover = "https:" + i["cover"]
if district_name == None: district_name = ""
if district_name == None:
district_name = ""
guests_list = i["guests"]
guests = ""
if guests_list != None:
for n in guests_list:
guests += n["name"] + ","
guests = "".join(n["name"] for n in guests_list)
else:
guests = ""
item_dict = {
"name" : name,
"location" : district_name + venue_name,
"sale_flag" : sale_flag,
"id" : project_id,
"price" : price_low,
"start_time" : start_time,
"end_time" : end_time,
"wish" : wish,
"image_url" : cover,
"guests" : guests,
"page" : page,
"total_pages": total_pages
"name": name,
"location": district_name + venue_name,
"sale_flag": sale_flag,
"id": project_id,
"price": price_low,
"start_time": start_time,
"end_time": end_time,
"wish": wish,
"image_url": cover,
"guests": guests,
"page": page,
"total_pages": total_pages,
}
showlist.append(item_dict)
global_data_dict = {
"page" : page,
"total_pages" : total_pages,
"total_results": total_results
"page": page,
"total_pages": total_pages,
"total_results": total_results,
}
return [showlist, global_data_dict]

View File

@ -20,36 +20,44 @@ showcmd = on_alconna(
showcmd.shortcut(
r"(?P<region>.+?)展览\s*(?P<page>\d+)?\s*(?P<date>.+)?",
{
"prefix" : True,
"command": "展览",
"args" : ["{region}", "{page}", "{date}"],
}
"prefix": True,
"command": "展览",
"args": ["{region}", "{page}", "{date}"],
},
)
@showcmd.handle()
async def find_show(
region: Optional[str] = None, page: Optional[int] = None, date: Optional[str] = None,
region: Optional[str] = None,
page: Optional[int] = None,
date: Optional[str] = None,
):
if not region: await UniMessage(__plugin_meta__.usage).send(); return
if not page: page = 1
if not date: date = ""
if not region:
await UniMessage(__plugin_meta__.usage).send()
return
if not page:
page = 1
if not date:
date = ""
regions_dict = await get_regions_dict()
regionid = regions_dict.get(region, None)
if regionid == None: await UniMessage("不支持此地区").send(); return
if regionid == None:
await UniMessage("地区未寻得或输入格式错误").send()
return
# await showcmd.send("日期:"+ date)
shows = await get_shows_data(regionid, page=page, pagesize=config.acgnshow_pagesize)
# print(shows)
try:
shows_data = process_shows_data_to_template(shows)
template = {
"shows" : shows_data[0],
"bgimage" : choose_random_bgimage(),
"global_data": shows_data[1]
"shows": shows_data[0],
"bgimage": choose_random_bgimage(),
"global_data": shows_data[1],
}
pic = await template_to_pic(RES_PATH, TEMPLATE_NAME, template)
pic = await template_to_pic(str(RES_PATH), TEMPLATE_NAME, template)
except Exception as e:
await UniMessage("发生错误").send()
await UniMessage("图片生成时产生未知错误").send()
traceback.print_exc()
return

View File

@ -1,11 +1,14 @@
from pathlib import Path
from pydantic import BaseModel
from nonebot import get_plugin_config
RES_PATH = Path(__file__).parent / "res"
TEMPLATE_NAME = "template.html"
BGIMAGE_PATH = RES_PATH / "bgimage"
class ConfigModel(BaseModel):
acgnshow_pagesize: int = 8
config: ConfigModel = get_plugin_config(ConfigModel)
config: ConfigModel = get_plugin_config(ConfigModel)

View File

@ -17,6 +17,7 @@ class City(BaseModel):
"""
热门城市
"""
id: int
type: int
first_letter: str
@ -31,6 +32,7 @@ class CityDataList(BaseModel):
"""
城市首字母
"""
letter: str
city_list: List[City]
@ -39,6 +41,7 @@ class CityData(BaseModel):
"""
城市数据
"""
hot: List[City]
list: List[CityDataList]
located_id: int
@ -48,6 +51,7 @@ class CityResp(BaseModel):
"""
城市数据
"""
errno: int
errtag: int
msg: str

View File

@ -1,17 +1,20 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta charset="UTF-8" />
<title>Show Information</title>
<style>
@font-face {
font-family: 'Source Han Sans';
src: url('SourceHanSans.otf') format('opentype');
font-family: "Source Han Sans";
src: url("SourceHanSans.otf") format("opentype");
}
body {
font-family: 'Source Han Sans', sans-serif;
background-image: url('{{ bgimage }}');
font-family: "Source Han Sans", sans-serif;
background-image: url("{{ bgimage }}");
}
.background {
position: fixed;
top: 0;
@ -22,14 +25,17 @@
filter: blur(40%);
z-index: -1;
}
.container {
width: 98%;
margin: 1%;
border: 1px solid #fff;
padding: 10px;
box-sizing: border-box;
background-color: rgba(255, 255, 255, 0.8); /* 半透明白色背景 */
background-color: rgba(255, 255, 255, 0.8);
/* 半透明白色背景 */
}
.header {
border: 1px solid black;
padding: 5px;
@ -38,6 +44,7 @@
font-size: 10px;
font-weight: bold;
}
.content {
display: flex;
border: 1px solid black;
@ -46,13 +53,15 @@
position: relative;
box-sizing: border-box;
}
.image {
width: 148px;
height: 200px;
border: 1px solid black;
width: 149px;
height: 201px;
border: 1px solid rgba(128, 64, 128, 0.5);
text-align: center;
box-sizing: border-box;
}
.details {
flex: 1;
padding-left: 10px;
@ -62,26 +71,32 @@
position: relative;
font-size: 10px;
}
.details .title {
font-size: 10px;
font-weight: bold;
margin-bottom: 5px;
}
.details .venue_name {
font-size: 10px;
font-weight: normal;
margin-bottom: 5px;
}
.details .guests {
font-size: 10px;
word-wrap: break-word;
white-space: pre-wrap; /* 自动换行 */
white-space: pre-wrap;
/* 自动换行 */
margin-bottom: 5px;
}
.details .placeholder {
font-size: 10px;
margin-bottom: 5px;
}
.details .sale_flag {
color: red;
font-size: 10px;
@ -89,6 +104,7 @@
top: 5px;
right: 5px;
}
.details .id {
color: black;
font-size: 10px;
@ -96,34 +112,40 @@
top: 20px;
right: 5px;
}
.details .price {
color: #FB7299;
color: #fb7299;
font-size: 10px;
font-weight: bold;
position: absolute;
bottom: 5px;
left: 5px;
}
.details .wish {
color: gray;
position: absolute;
bottom: 5px;
left: 60px;
}
.details .start-time,
.details .end-time {
font-size: 10px;
}
.details .start-time {
position: absolute;
bottom: 20px;
right: 5px;
}
.details .end-time {
position: absolute;
bottom: 5px;
right: 5px;
}
.footer {
border: 1px solid black;
flex: 1;
@ -134,40 +156,53 @@
position: relative;
font-size: 10px;
}
.footer .designer {
text-align: center;
font-weight: bold;
font-size: 10px;
padding: 5px;
margin-bottom: 10px;
margin-top: 10px;
}
.footer .pages {
position: absolute;
bottom: 5px;
right: 5px;
font-size: 10px;
}
.footer .total_results {
position: absolute;
bottom: 5px;
left: 5px;
font-size: 10px;
}
.footer .project_name {
position: relative;
font-size: 10px;
text-align: center;
color: rgb(50, 227, 227);
}
.footer .notice_text {
position: relative;
font-size: 8px;
text-align: center;
color: slateblue;
}
</style>
</head>
<body>
<div class="container">
<div class="header">展览信息</div>
{% for show in shows %}
<div class="content">
<div class="image">
<img src="{{ show.image_url }}" alt="Image" width="148" height="200">
<img src="{{ show.image_url }}" alt="Image" width="147px" height="199px" />
</div>
<div class="details">
<div class="title">{{ show.name }}</div>
@ -186,11 +221,17 @@
</div>
{% endfor %}
<div class="footer">
<div class="designer"> Designed by Asankilp? </div>
<div class="total_results">共 {{ global_data.total_results }} 个结果</div>
<div class="pages">{{ global_data.page }} / {{ global_data.total_pages }} 页</div>
<div class="designer">Designed by Asankilp?</div>
<div class="total_results">
共 {{ global_data.total_results }} 个结果
</div>
<div class="pages">
{{ global_data.page }} / {{ global_data.total_pages }} 页
</div>
<div class="project_name">nonebot-plugin-acgnshow</div>
<div class="notice_text">本页信息仅供参考,具体内容请访问展览官方详情页,并自行检索实际信息</div>
</div>
</div>
</body>
</html>

View File

@ -1,15 +1,21 @@
from .config import BGIMAGE_PATH
import os
import random
import datetime
from .config import BGIMAGE_PATH
def choose_random_bgimage():
randomfile = random.choice(list(BGIMAGE_PATH.iterdir()))
randomurl = randomfile.as_uri()
def choose_random_bgimage() -> str:
"""
从背景图片文件夹中随机选择一张图片返回图片的uri地址
"""
randomfile = random.choice(os.listdir(BGIMAGE_PATH))
randomurl = (BGIMAGE_PATH / randomfile).as_uri()
return randomurl
def convert_timestamp(timestamp):
obj = datetime.datetime.fromtimestamp(timestamp)
formatted_time = obj.strftime('%Y-%m-%d %H:%M:%S')
return formatted_time
def convert_timestamp(timestamp) -> str:
"""
将时间戳转换为日期格式
"""
return datetime.datetime.fromtimestamp(timestamp).strftime("%Y-%m-%d %H:%M:%S")

View File

@ -4,9 +4,7 @@ version = "0.1.5"
description = "Nonebot2插件从哔哩哔哩会员购获取简易展览数据"
readme = "README.md"
requires-python = "<4.0,>=3.9"
authors = [
{ name = "Asankilp", email = "asankilp@outlook.com" },
]
authors = [{ name = "Asankilp", email = "asankilp@outlook.com" }]
dependencies = [
"nonebot2[fastapi, websockets]>=2.2.0",
"nonebot-plugin-alconna>=0.48.0",