mirror of
https://github.com/zhenxun-org/zhenxun_bot.git
synced 2025-12-15 14:22:55 +08:00
fix
This commit is contained in:
parent
b62399e203
commit
910af434ae
@ -2,6 +2,7 @@ from utils.utils import scheduler, get_bot
|
||||
from .data_source import update_member_info
|
||||
from services.log import logger
|
||||
from models.group_info import GroupInfo
|
||||
from asyncpg.exceptions import ConnectionDoesNotExistError
|
||||
|
||||
|
||||
# 自动更新群员信息
|
||||
@ -37,5 +38,5 @@ async def _():
|
||||
if g not in all_group:
|
||||
await update_member_info(g)
|
||||
logger.info(f"快速更新群信息以及权限:{g}")
|
||||
except IndexError:
|
||||
except (IndexError, ConnectionDoesNotExistError):
|
||||
pass
|
||||
|
||||
@ -150,7 +150,7 @@ def no_result() -> str:
|
||||
random.choice(
|
||||
[
|
||||
"你在说啥子?",
|
||||
f"纯洁的{list(get_bot().config.nickname)[0]}没听懂",
|
||||
f"纯洁的小真寻没听懂",
|
||||
"下次再告诉你(下次一定)",
|
||||
"你觉得我听懂了吗?嗯?",
|
||||
"我!不!知!道!",
|
||||
|
||||
@ -4,27 +4,34 @@ from models.friend_user import FriendUser
|
||||
from datetime import datetime
|
||||
from configs.config import AUTO_ADD_FRIEND
|
||||
from nonebot.adapters.cqhttp.exception import ActionFailed
|
||||
from utils.utils import scheduler
|
||||
|
||||
__plugin_name__ = "好友群聊处理请求 [Hidden]"
|
||||
|
||||
friend_req = on_request(priority=5)
|
||||
|
||||
|
||||
exists_list = []
|
||||
|
||||
|
||||
@friend_req.handle()
|
||||
async def _(bot: Bot, event: FriendRequestEvent, state: dict):
|
||||
user = await bot.get_stranger_info(user_id=event.user_id)
|
||||
nickname = user["nickname"]
|
||||
await bot.send_private_msg(
|
||||
user_id=int(list(bot.config.superusers)[0]),
|
||||
message=f"*****一份好友申请*****\n"
|
||||
f"昵称:{nickname}({event.user_id})\n"
|
||||
f"自动同意:{'√' if AUTO_ADD_FRIEND else '×'}\n"
|
||||
f"日期:{str(datetime.now()).split('.')[0]}\n"
|
||||
f"备注:{event.comment}",
|
||||
)
|
||||
if AUTO_ADD_FRIEND:
|
||||
await bot.set_friend_add_request(flag=event.flag, approve=True)
|
||||
await FriendUser.add_friend_info(user["user_id"], user["nickname"])
|
||||
global exists_list
|
||||
if f"{event.user_id}" not in exists_list:
|
||||
exists_list.append(f"{event.user_id}")
|
||||
user = await bot.get_stranger_info(user_id=event.user_id)
|
||||
nickname = user["nickname"]
|
||||
await bot.send_private_msg(
|
||||
user_id=int(list(bot.config.superusers)[0]),
|
||||
message=f"*****一份好友申请*****\n"
|
||||
f"昵称:{nickname}({event.user_id})\n"
|
||||
f"自动同意:{'√' if AUTO_ADD_FRIEND else '×'}\n"
|
||||
f"日期:{str(datetime.now()).split('.')[0]}\n"
|
||||
f"备注:{event.comment}",
|
||||
)
|
||||
if AUTO_ADD_FRIEND:
|
||||
await bot.set_friend_add_request(flag=event.flag, approve=True)
|
||||
await FriendUser.add_friend_info(user["user_id"], user["nickname"])
|
||||
|
||||
|
||||
group_req = on_request(priority=5, block=True)
|
||||
@ -32,6 +39,7 @@ group_req = on_request(priority=5, block=True)
|
||||
|
||||
@group_req.handle()
|
||||
async def _(bot: Bot, event: GroupRequestEvent, state: dict):
|
||||
global exists_list
|
||||
if event.sub_type == "invite":
|
||||
if str(event.user_id) in bot.config.superusers:
|
||||
try:
|
||||
@ -41,17 +49,28 @@ async def _(bot: Bot, event: GroupRequestEvent, state: dict):
|
||||
except ActionFailed:
|
||||
pass
|
||||
else:
|
||||
nickname = await FriendUser.get_user_name(event.user_id)
|
||||
await bot.send_private_msg(
|
||||
user_id=int(list(bot.config.superusers)[0]),
|
||||
message=f"*****一份入群申请*****\n"
|
||||
f"申请人:{nickname}({event.user_id})\n"
|
||||
f"群聊:{event.group_id}\n"
|
||||
f"邀请日期:{str(datetime.now()).split('.')[0]}",
|
||||
)
|
||||
await bot.send_private_msg(
|
||||
user_id=event.user_id,
|
||||
message="想要邀请我偷偷入群嘛~已经提醒真寻的管理员大人了\n"
|
||||
"请确保已经群主或群管理沟通过!\n"
|
||||
"等待管理员处理吧!",
|
||||
)
|
||||
if f"{event.user_id}:{event.group_id}" not in exists_list:
|
||||
exists_list.append(f"{event.user_id}:{event.group_id}")
|
||||
nickname = await FriendUser.get_user_name(event.user_id)
|
||||
await bot.send_private_msg(
|
||||
user_id=int(list(bot.config.superusers)[0]),
|
||||
message=f"*****一份入群申请*****\n"
|
||||
f"申请人:{nickname}({event.user_id})\n"
|
||||
f"群聊:{event.group_id}\n"
|
||||
f"邀请日期:{str(datetime.now()).split('.')[0]}",
|
||||
)
|
||||
await bot.send_private_msg(
|
||||
user_id=event.user_id,
|
||||
message="想要邀请我偷偷入群嘛~已经提醒真寻的管理员大人了\n"
|
||||
"请确保已经群主或群管理沟通过!\n"
|
||||
"等待管理员处理吧!",
|
||||
)
|
||||
|
||||
|
||||
@scheduler.scheduled_job(
|
||||
"interval",
|
||||
minutes=5,
|
||||
)
|
||||
async def _():
|
||||
global exists_list
|
||||
exists_list = []
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
from pathlib import Path
|
||||
from configs.path_config import IMAGE_PATH, TXT_PATH
|
||||
from utils.image_utils import CreateImg
|
||||
from typing import Tuple
|
||||
from typing import Tuple, List
|
||||
from math import sqrt, pow
|
||||
import random
|
||||
|
||||
@ -28,6 +28,7 @@ class Map:
|
||||
deviation: Tuple[int, int] = (25, 51),
|
||||
padding: int = 100,
|
||||
planning_route: bool = False,
|
||||
ratio: float = 1,
|
||||
):
|
||||
"""
|
||||
参数:
|
||||
@ -36,14 +37,21 @@ class Map:
|
||||
:param deviation: 坐标误差
|
||||
:param padding: 截图外边距
|
||||
:param planning_route: 是否规划最佳线路
|
||||
:param ratio: 压缩比率
|
||||
"""
|
||||
self.map = CreateImg(0, 0, background=map_path)
|
||||
self.resource_name = resource_name
|
||||
self.center_x = center_point[0]
|
||||
self.center_y = center_point[1]
|
||||
self.deviation = deviation
|
||||
self.padding = padding
|
||||
self.padding = int(padding * ratio)
|
||||
self.planning_route = planning_route
|
||||
self.ratio = ratio
|
||||
|
||||
self.deviation = (
|
||||
int(self.deviation[0] * ratio),
|
||||
int(self.deviation[1] * ratio),
|
||||
)
|
||||
|
||||
data = json.load(open(resource_label_file, "r", encoding="utf8"))
|
||||
# 资源 id
|
||||
@ -67,27 +75,27 @@ class Map:
|
||||
# 资源坐标
|
||||
data = json.load(open(resource_point_file, "r", encoding="utf8"))
|
||||
self.resource_point = [
|
||||
(
|
||||
self.center_x + int(data[x]["x_pos"]),
|
||||
self.center_y + int(data[x]["y_pos"]),
|
||||
Resources(
|
||||
int((self.center_x + data[x]["x_pos"]) * ratio),
|
||||
int((self.center_y + data[x]["y_pos"]) * ratio),
|
||||
)
|
||||
for x in data
|
||||
if x != "CENTER_POINT" and data[x]["label_id"] == self.resource_id
|
||||
]
|
||||
# 传送锚点坐标
|
||||
self.teleport_anchor_point = [
|
||||
(
|
||||
self.center_x + int(data[x]["x_pos"]),
|
||||
self.center_y + int(data[x]["y_pos"]),
|
||||
Resources(
|
||||
int((self.center_x + data[x]["x_pos"]) * ratio),
|
||||
int((self.center_y + data[x]["y_pos"]) * ratio),
|
||||
)
|
||||
for x in data
|
||||
if x != "CENTER_POINT" and data[x]["label_id"] == self.teleport_anchor_id
|
||||
]
|
||||
# 神像坐标
|
||||
self.teleport_god_point = [
|
||||
(
|
||||
self.center_x + int(data[x]["x_pos"]),
|
||||
self.center_y + int(data[x]["y_pos"]),
|
||||
Resources(
|
||||
int((self.center_x + data[x]["x_pos"]) * ratio),
|
||||
int((self.center_y + data[x]["y_pos"]) * ratio),
|
||||
)
|
||||
for x in data
|
||||
if x != "CENTER_POINT" and data[x]["label_id"] == self.teleport_god_id
|
||||
@ -95,21 +103,23 @@ class Map:
|
||||
|
||||
# 将地图上生成资源图标
|
||||
def generate_resource_icon_in_map(self) -> int:
|
||||
x_list = [x[0] for x in self.resource_point]
|
||||
y_list = [x[1] for x in self.resource_point]
|
||||
x_list = [x.x for x in self.resource_point]
|
||||
y_list = [x.y for x in self.resource_point]
|
||||
min_width = min(x_list) - self.padding
|
||||
max_width = max(x_list) + self.padding
|
||||
min_height = min(y_list) - self.padding
|
||||
max_height = max(y_list) + self.padding
|
||||
self._generate_transfer_icon((min_width, min_height, max_width, max_height))
|
||||
for res in self.resource_point:
|
||||
icon = self._get_icon_image(self.resource_id)
|
||||
self.map.paste(
|
||||
icon, (res.x - self.deviation[0], res.y - self.deviation[1]), True
|
||||
)
|
||||
if self.planning_route:
|
||||
self._generate_best_route()
|
||||
self._generate_transfer_icon((min_width, min_height, max_width, max_height))
|
||||
for x, y in self.resource_point:
|
||||
icon = self._get_icon_image(self.resource_id)
|
||||
self.map.paste(icon, (x - self.deviation[0], y - self.deviation[1]), True)
|
||||
self.map.crop((min_width, min_height, max_width, max_height))
|
||||
rand = random.randint(1, 10000)
|
||||
self.map.save(f'{IMAGE_PATH}/temp/genshin_map_{rand}.png')
|
||||
self.map.save(f"{IMAGE_PATH}/temp/genshin_map_{rand}.png")
|
||||
return rand
|
||||
|
||||
# 资源数量
|
||||
@ -119,40 +129,98 @@ class Map:
|
||||
# 生成传送锚点和神像
|
||||
def _generate_transfer_icon(self, box: Tuple[int, int, int, int]):
|
||||
min_width, min_height, max_width, max_height = box
|
||||
for points in [self.teleport_anchor_point, self.teleport_god_point]:
|
||||
for resources in [self.teleport_anchor_point, self.teleport_god_point]:
|
||||
id_ = (
|
||||
self.teleport_anchor_id
|
||||
if points == self.teleport_anchor_point
|
||||
if resources == self.teleport_anchor_point
|
||||
else self.teleport_god_id
|
||||
)
|
||||
for x, y in points:
|
||||
if min_width < x < max_width and min_height < y < max_height:
|
||||
for res in resources:
|
||||
if min_width < res.x < max_width and min_height < res.y < max_height:
|
||||
icon = self._get_icon_image(id_)
|
||||
self.map.paste(
|
||||
icon, (x - self.deviation[0], y - self.deviation[1]), True
|
||||
icon,
|
||||
(res.x - self.deviation[0], res.y - self.deviation[1]),
|
||||
True,
|
||||
)
|
||||
|
||||
# 生成最优路线(说是最优其实就是直线最短)
|
||||
def _generate_best_route(self):
|
||||
for x, y in self.resource_point:
|
||||
min_deviation = 999999
|
||||
xy = None
|
||||
for points in [
|
||||
self.resource_point,
|
||||
self.teleport_anchor_point,
|
||||
self.teleport_god_point,
|
||||
]:
|
||||
for r_x, r_y in points:
|
||||
distance = int(sqrt(pow(abs(r_x - x), 2) + pow(abs(r_y - y), 2)))
|
||||
if distance < min_deviation and x != r_x and y != r_y:
|
||||
min_deviation = distance
|
||||
xy = (x, y, r_x, r_y)
|
||||
resources_route = []
|
||||
# 先连上最近的资源路径
|
||||
for res in self.resource_point:
|
||||
# 拿到最近的资源
|
||||
current_res, _ = res.get_resource_distance(
|
||||
self.resource_point
|
||||
+ self.teleport_anchor_point
|
||||
+ self.teleport_god_point
|
||||
)
|
||||
self.map.line(
|
||||
(current_res.x, current_res.y, res.x, res.y), (255, 0, 0), width=1
|
||||
)
|
||||
resources_route.append((current_res, res))
|
||||
teleport_list = self.teleport_anchor_point + self.teleport_god_point
|
||||
for res1, res2 in resources_route:
|
||||
point_list = [x for x in resources_route if res1 in x or res2 in x]
|
||||
if not list(set(point_list).intersection(set(teleport_list))):
|
||||
if res1 not in teleport_list and res2 not in teleport_list:
|
||||
# while True:
|
||||
# tmp = [x for x in point_list]
|
||||
# break
|
||||
teleport1, distance1 = res1.get_resource_distance(teleport_list)
|
||||
teleport2, distance2 = res2.get_resource_distance(teleport_list)
|
||||
if distance1 > distance2:
|
||||
self.map.line(
|
||||
(teleport1.x, teleport1.y, res1.x, res1.y),
|
||||
(255, 0, 0),
|
||||
width=1,
|
||||
)
|
||||
else:
|
||||
self.map.line(
|
||||
(teleport2.x, teleport2.y, res2.x, res2.y),
|
||||
(255, 0, 0),
|
||||
width=1,
|
||||
)
|
||||
|
||||
self.map.line(xy, (255, 0, 0), width=3)
|
||||
# self.map.line(xy, (255, 0, 0), width=3)
|
||||
|
||||
# 获取资源图标
|
||||
def _get_icon_image(self, id_: int) -> "CreateImg":
|
||||
icon = icon_path / f"{id_}.png"
|
||||
if icon.exists():
|
||||
return CreateImg(50, 50, background=icon)
|
||||
return CreateImg(50, 50, background=f"{icon_path}/box.png")
|
||||
return CreateImg(
|
||||
int(50 * self.ratio), int(50 * self.ratio), background=icon
|
||||
)
|
||||
return CreateImg(
|
||||
int(50 * self.ratio),
|
||||
int(50 * self.ratio),
|
||||
background=f"{icon_path}/box.png",
|
||||
)
|
||||
|
||||
# def _get_shortest_path(self, res: 'Resources', res_2: 'Resources'):
|
||||
|
||||
|
||||
# 资源类
|
||||
class Resources:
|
||||
def __init__(self, x: int, y: int):
|
||||
self.x = x
|
||||
self.y = y
|
||||
|
||||
def get_distance(self, x: int, y: int):
|
||||
return int(sqrt(pow(abs(self.x - x), 2) + pow(abs(self.y - y), 2)))
|
||||
|
||||
# 拿到资源在该列表中的最短路径
|
||||
def get_resource_distance(self, resources: List["Resources"]) -> "Resources, int":
|
||||
current_res = None
|
||||
min_distance = 999999
|
||||
for res in resources:
|
||||
distance = self.get_distance(res.x, res.y)
|
||||
if distance < min_distance and res != self:
|
||||
current_res = res
|
||||
min_distance = distance
|
||||
return current_res, min_distance
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@ -16,6 +16,7 @@ import nonebot
|
||||
import aiohttp
|
||||
import aiofiles
|
||||
import os
|
||||
|
||||
try:
|
||||
import ujson as json
|
||||
except ModuleNotFoundError:
|
||||
@ -38,20 +39,29 @@ CENTER_POINT: Optional[Tuple[int, int]] = None
|
||||
|
||||
resource_name_list: List[str] = []
|
||||
|
||||
MAP_RATIO = 0.5
|
||||
|
||||
|
||||
# 查找资源
|
||||
async def query_resource(resource_name: str) -> str:
|
||||
global CENTER_POINT
|
||||
planning_route: bool = False
|
||||
if resource_name and resource_name[-2:] == "路径":
|
||||
resource_name = resource_name[:-2].strip()
|
||||
planning_route = True
|
||||
if not resource_name or resource_name not in resource_name_list:
|
||||
return f"未查找到 {resource_name} 资源,可通过 “原神资源列表” 获取全部资源名称.."
|
||||
map_ = Map(resource_name, CENTER_POINT, planning_route=planning_route)
|
||||
map_ = Map(
|
||||
resource_name, CENTER_POINT, planning_route=planning_route, ratio=MAP_RATIO
|
||||
)
|
||||
count = map_.get_resource_count()
|
||||
rand = await asyncio.get_event_loop().run_in_executor(None, map_.generate_resource_icon_in_map)
|
||||
return f"{image(f'genshin_map_{rand}.png', 'temp')}" \
|
||||
f"\n\n※ {resource_name} 一共找到 {count} 个位置点\n※ 数据来源于米游社wiki"
|
||||
rand = await asyncio.get_event_loop().run_in_executor(
|
||||
None, map_.generate_resource_icon_in_map
|
||||
)
|
||||
return (
|
||||
f"{image(f'genshin_map_{rand}.png', 'temp')}"
|
||||
f"\n\n※ {resource_name} 一共找到 {count} 个位置点\n※ 数据来源于米游社wiki"
|
||||
)
|
||||
|
||||
|
||||
# 原神资源列表
|
||||
@ -76,7 +86,7 @@ async def init(flag: bool = False):
|
||||
global CENTER_POINT, resource_name_list
|
||||
semaphore = asyncio.Semaphore(10)
|
||||
async with aiohttp.ClientSession(headers=get_user_agent()) as session:
|
||||
await download_map_init(session, semaphore, flag)
|
||||
await download_map_init(session, semaphore, MAP_RATIO, flag)
|
||||
await download_resource_data(session, semaphore)
|
||||
await download_resource_type(session)
|
||||
if not CENTER_POINT:
|
||||
@ -137,42 +147,57 @@ async def download_resource_data(session: ClientSession, semaphore: Semaphore):
|
||||
|
||||
|
||||
# 下载原神地图并拼图
|
||||
async def download_map_init(session: ClientSession, semaphore: Semaphore, flag: bool = False):
|
||||
global CENTER_POINT
|
||||
async def download_map_init(
|
||||
session: ClientSession, semaphore: Semaphore, ratio: float = 1, flag: bool = False
|
||||
):
|
||||
global CENTER_POINT, MAP_RATIO
|
||||
map_path.mkdir(exist_ok=True, parents=True)
|
||||
_map = map_path / "map.png"
|
||||
if os.path.getsize(_map) > 1024 * 1024 * 30:
|
||||
_map.unlink()
|
||||
async with session.get(MAP_URL, timeout=5) as response:
|
||||
if response.status == 200:
|
||||
data = await response.json()
|
||||
if data["message"] == "OK":
|
||||
data = json.loads(data["data"]["info"]["detail"])
|
||||
CENTER_POINT = (data["origin"][0], data["origin"][1])
|
||||
# padding_w, padding_h = data['padding']
|
||||
data = data["slices"]
|
||||
idx = 0
|
||||
for x in data:
|
||||
idj = 0
|
||||
for j in x:
|
||||
await download_image(
|
||||
j["url"],
|
||||
f"{map_path}/{idx}_{idj}.png",
|
||||
session,
|
||||
semaphore,
|
||||
force_flag=flag
|
||||
)
|
||||
idj += 1
|
||||
idx += 1
|
||||
map_width, map_height = CreateImg(
|
||||
0, 0, background=f"{map_path}/0_0.png"
|
||||
).size
|
||||
lens = len([x for x in os.listdir(f"{map_path}") if x.startswith("0")])
|
||||
background_image = CreateImg(
|
||||
map_width * lens, map_height * lens, map_width, map_height
|
||||
)
|
||||
for i in range(idx):
|
||||
for j in range(idj):
|
||||
x = CreateImg(0, 0, background=f"{map_path}/{i}_{j}.png")
|
||||
background_image.paste(x)
|
||||
background_image.save(f"{map_path}/map.png")
|
||||
if not _map.exists():
|
||||
# padding_w, padding_h = data['padding']
|
||||
data = data["slices"]
|
||||
idx = 0
|
||||
for x in data:
|
||||
idj = 0
|
||||
for j in x:
|
||||
await download_image(
|
||||
j["url"],
|
||||
f"{map_path}/{idx}_{idj}.png",
|
||||
session,
|
||||
semaphore,
|
||||
force_flag=flag,
|
||||
)
|
||||
idj += 1
|
||||
idx += 1
|
||||
map_width, map_height = CreateImg(
|
||||
0, 0, background=f"{map_path}/0_0.png"
|
||||
).size
|
||||
map_width = map_width * MAP_RATIO
|
||||
map_height = map_height * MAP_RATIO
|
||||
lens = len(
|
||||
[x for x in os.listdir(f"{map_path}") if x.startswith("0")]
|
||||
)
|
||||
background_image = CreateImg(
|
||||
map_width * lens, map_height * lens, map_width, map_height
|
||||
)
|
||||
for i in range(idx):
|
||||
for j in range(idj):
|
||||
x = CreateImg(
|
||||
0,
|
||||
0,
|
||||
background=f"{map_path}/{i}_{j}.png",
|
||||
ratio=MAP_RATIO,
|
||||
)
|
||||
background_image.paste(x)
|
||||
background_image.save(f"{map_path}/map.png")
|
||||
else:
|
||||
logger.warning(f'获取原神地图失败 msg: {data["message"]}')
|
||||
else:
|
||||
@ -238,3 +263,8 @@ async def download_image(
|
||||
logger.warning(f"原神图片打开错误..已删除,等待下次更新... file: {path}")
|
||||
if os.path.exists(path):
|
||||
os.remove(path)
|
||||
|
||||
|
||||
#
|
||||
# def _get_point_ratio():
|
||||
#
|
||||
|
||||
@ -3,6 +3,7 @@ from nonebot.adapters.cqhttp import Bot, GroupMessageEvent
|
||||
from nonebot.adapters.cqhttp.permission import GROUP
|
||||
from utils.utils import get_message_text, is_number, get_message_imgs, get_local_proxy
|
||||
from nonebot.typing import T_State
|
||||
from asyncio.exceptions import TimeoutError
|
||||
import time
|
||||
from nonebot.adapters.cqhttp.exception import ActionFailed
|
||||
from configs.path_config import DATA_PATH, IMAGE_PATH
|
||||
@ -47,13 +48,16 @@ def save_data():
|
||||
|
||||
|
||||
async def download_img_and_hash(url, group_id):
|
||||
async with aiohttp.ClientSession() as session:
|
||||
async with session.get(url, proxy=get_local_proxy(), timeout=10) as response:
|
||||
async with aiofiles.open(
|
||||
IMAGE_PATH + f"temp/mute_{group_id}_img.jpg", "wb"
|
||||
) as f:
|
||||
await f.write(await response.read())
|
||||
return str(get_img_hash(IMAGE_PATH + f"temp/mute_{group_id}_img.jpg"))
|
||||
try:
|
||||
async with aiohttp.ClientSession() as session:
|
||||
async with session.get(url, proxy=get_local_proxy(), timeout=10) as response:
|
||||
async with aiofiles.open(
|
||||
IMAGE_PATH + f"temp/mute_{group_id}_img.jpg", "wb"
|
||||
) as f:
|
||||
await f.write(await response.read())
|
||||
return str(get_img_hash(IMAGE_PATH + f"temp/mute_{group_id}_img.jpg"))
|
||||
except TimeoutError:
|
||||
return ''
|
||||
|
||||
|
||||
mute_dict = {}
|
||||
|
||||
@ -36,7 +36,7 @@ flmt = FreqLimiter(60)
|
||||
# 在 Matcher 运行前检测其是否启用
|
||||
@run_preprocessor
|
||||
async def _(matcher: Matcher, bot: Bot, event: Event, state: T_State):
|
||||
if not isinstance(event, MessageEvent):
|
||||
if not isinstance(event, MessageEvent) and matcher.module != 'poke':
|
||||
return
|
||||
plugin = matcher.module
|
||||
group_id = _get_group_id(event)
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
from nonebot import on_message, on_command
|
||||
from nonebot import on_message
|
||||
from services.log import logger
|
||||
from nonebot.adapters.cqhttp import Bot, GroupMessageEvent
|
||||
from nonebot.typing import T_State
|
||||
@ -26,6 +26,7 @@ async def _(bot: Bot, event: GroupMessageEvent, state: T_State):
|
||||
event.json()
|
||||
):
|
||||
data = json.loads(get_message_json(event.json())[0]["data"])
|
||||
print(data)
|
||||
if data:
|
||||
if data.get("desc") == "哔哩哔哩":
|
||||
async with aiohttp.ClientSession(headers=get_user_agent()) as session:
|
||||
|
||||
@ -11,7 +11,7 @@ from models.pixiv import Pixiv
|
||||
import random
|
||||
|
||||
|
||||
pix = on_command("pix", aliases={'PIX'}, priority=5, block=True)
|
||||
pix = on_command("pix", aliases={"PIX"}, priority=5, block=True)
|
||||
|
||||
|
||||
@pix.handle()
|
||||
@ -60,4 +60,4 @@ async def _(bot: Bot, event: MessageEvent, state: T_State):
|
||||
logger.info(
|
||||
f"(USER {event.user_id}, GROUP {event.group_id if isinstance(event, GroupMessageEvent) else 'private'})"
|
||||
f" 查看PIX图库PID: {pid}"
|
||||
)
|
||||
)
|
||||
|
||||
@ -2,7 +2,7 @@ from configs.path_config import IMAGE_PATH
|
||||
from utils.message_builder import image
|
||||
from services.log import logger
|
||||
from aiohttp.client_exceptions import ClientConnectorError
|
||||
from utils.image_utils import get_img_hash
|
||||
from utils.image_utils import get_img_hash, compressed_image
|
||||
from asyncpg.exceptions import UniqueViolationError
|
||||
from utils.utils import get_local_proxy
|
||||
from asyncio.exceptions import TimeoutError
|
||||
@ -10,6 +10,7 @@ from typing import List, Optional
|
||||
from models.setu import Setu
|
||||
import aiohttp
|
||||
import aiofiles
|
||||
import asyncio
|
||||
import os
|
||||
import random
|
||||
|
||||
@ -26,18 +27,15 @@ r18_path = "_r18/"
|
||||
|
||||
# 获取url
|
||||
async def get_setu_urls(
|
||||
tags: List[str], num: int = 1, r18: int = 0, command: str = ''
|
||||
tags: List[str], num: int = 1, r18: int = 0, command: str = ""
|
||||
) -> "List[str], List[str], List[tuple], int":
|
||||
tags = tags[:20] if len(tags) > 20 else tags
|
||||
params = {
|
||||
"r18": r18, # 添加r18参数 0为否,1为是,2为混合
|
||||
"tag": "|".join(tags), # 若指定tag
|
||||
"num": 100, # 一次返回的结果数量,范围为1到10,不提供 APIKEY 时固定为1
|
||||
"size1200": "original", # 是否使用 master_1200 缩略图,以节省流量或提升加载速度
|
||||
"size": ["original"], # 是否使用 master_1200 缩略图,以节省流量或提升加载速度
|
||||
}
|
||||
urls = []
|
||||
text_list = []
|
||||
add_databases_list = []
|
||||
async with aiohttp.ClientSession() as session:
|
||||
for count in range(3):
|
||||
logger.info(f"get_setu_url: count --> {count}")
|
||||
@ -49,36 +47,13 @@ async def get_setu_urls(
|
||||
data = await response.json()
|
||||
if not data["error"]:
|
||||
data = data["data"]
|
||||
for i in range(len(data)):
|
||||
img_url = data[i]["urls"]["original"]
|
||||
img_url = (
|
||||
img_url.replace("i.pixiv.cat", "i.pximg.net")
|
||||
if "i.pixiv.cat" in img_url
|
||||
else img_url
|
||||
)
|
||||
title = data[i]["title"]
|
||||
author = data[i]["author"]
|
||||
pid = data[i]["pid"]
|
||||
urls.append(img_url)
|
||||
text_list.append(
|
||||
f"title:{title}\nauthor:{author}\nPID:{pid}"
|
||||
)
|
||||
tags = []
|
||||
for j in range(len(data[i]["tags"])):
|
||||
tags.append(data[i]["tags"][j])
|
||||
if command != '色图r':
|
||||
if 'R-18' in tags:
|
||||
tags.remove('R-18')
|
||||
add_databases_list.append(
|
||||
(
|
||||
title,
|
||||
author,
|
||||
pid,
|
||||
"",
|
||||
img_url,
|
||||
",".join(tags),
|
||||
)
|
||||
)
|
||||
(
|
||||
urls,
|
||||
text_list,
|
||||
add_databases_list,
|
||||
) = await asyncio.get_event_loop().run_in_executor(
|
||||
None, _setu_data_process, data, command
|
||||
)
|
||||
num = num if num < len(data) else len(data)
|
||||
random_idx = random.sample(range(len(data)), num)
|
||||
x_urls = []
|
||||
@ -101,7 +76,9 @@ headers = {
|
||||
}
|
||||
|
||||
|
||||
async def search_online_setu(url_: str, id_: int = None, path_: str = None) -> "MessageSegment, int":
|
||||
async def search_online_setu(
|
||||
url_: str, id_: int = None, path_: str = None
|
||||
) -> "MessageSegment, int":
|
||||
if "i.pixiv.cat" in url_:
|
||||
url_ = url_.replace("i.pixiv.cat", "i.pximg.net")
|
||||
async with aiohttp.ClientSession(headers=headers) as session:
|
||||
@ -110,18 +87,25 @@ async def search_online_setu(url_: str, id_: int = None, path_: str = None) -> "
|
||||
try:
|
||||
async with session.get(url_, proxy=get_local_proxy(), timeout=3) as res:
|
||||
if res.status == 200:
|
||||
index = str(random.randint(1, 100000)) if id_ is None else id_
|
||||
path_ = 'temp' if path_ is None else path_
|
||||
if id_:
|
||||
file = f'{index}.jpg'
|
||||
else:
|
||||
file = f'{index}_temp_setu.jpg'
|
||||
async with aiofiles.open(f'{IMAGE_PATH}/{path_}/{file}', "wb") as f:
|
||||
index = random.randint(1, 100000) if id_ is None else id_
|
||||
path_ = "temp" if not path_ else path_
|
||||
file = f"{index}_temp_setu.jpg" if not path_ else f"{index}.jpg"
|
||||
async with aiofiles.open(
|
||||
f"{IMAGE_PATH}/{path_}/{file}", "wb"
|
||||
) as f:
|
||||
try:
|
||||
await f.write(await res.read())
|
||||
except TimeoutError:
|
||||
# return '\n这图没下载过来~(网太差?)', -1, False
|
||||
continue
|
||||
if id_ is not None:
|
||||
if (
|
||||
os.path.getsize(f"{IMAGE_PATH}/{path_}/{index}.jpg")
|
||||
> 1024 * 1024 * 1.5
|
||||
):
|
||||
compressed_image(
|
||||
os.path.join(path_, f"{index}.jpg"),
|
||||
os.path.join(path_, f"{index}.jpg"),
|
||||
)
|
||||
logger.info(f"下载 lolicon图片 {url_} 成功, id:{index}")
|
||||
return image(file, path_), index
|
||||
else:
|
||||
@ -152,7 +136,7 @@ async def add_data_to_database(lst: List[tuple]):
|
||||
if tmp:
|
||||
for x in tmp:
|
||||
try:
|
||||
r18 = 1 if 'R-18' in x[5] else 0
|
||||
r18 = 1 if "R-18" in x[5] else 0
|
||||
idx = await Setu.get_image_count(r18)
|
||||
await Setu.add_setu_data(
|
||||
idx,
|
||||
@ -229,3 +213,39 @@ async def find_img_index(img_url, user_id):
|
||||
f"PID:{setu_img.pid}"
|
||||
)
|
||||
return "该图不在色图库中或色图库未更新!"
|
||||
|
||||
|
||||
# 处理色图数据
|
||||
def _setu_data_process(data: dict, command: str) -> "list, list, list":
|
||||
urls = []
|
||||
text_list = []
|
||||
add_databases_list = []
|
||||
for i in range(len(data)):
|
||||
img_url = data[i]["urls"]["original"]
|
||||
img_url = (
|
||||
img_url.replace("i.pixiv.cat", "i.pximg.net")
|
||||
if "i.pixiv.cat" in img_url
|
||||
else img_url
|
||||
)
|
||||
title = data[i]["title"]
|
||||
author = data[i]["author"]
|
||||
pid = data[i]["pid"]
|
||||
urls.append(img_url)
|
||||
text_list.append(f"title:{title}\nauthor:{author}\nPID:{pid}")
|
||||
tags = []
|
||||
for j in range(len(data[i]["tags"])):
|
||||
tags.append(data[i]["tags"][j])
|
||||
if command != "色图r":
|
||||
if "R-18" in tags:
|
||||
tags.remove("R-18")
|
||||
add_databases_list.append(
|
||||
(
|
||||
title,
|
||||
author,
|
||||
pid,
|
||||
"",
|
||||
img_url,
|
||||
",".join(tags),
|
||||
)
|
||||
)
|
||||
return urls, text_list, add_databases_list
|
||||
|
||||
@ -19,7 +19,7 @@ async def _(bot: Bot, event: GroupMessageEvent, state: T_State):
|
||||
@gold_rank.handle()
|
||||
async def _(bot: Bot, event: GroupMessageEvent, state: T_State):
|
||||
all_users = await BagUser.get_all_users(event.group_id)
|
||||
all_user_id = [user.qq for user in all_users]
|
||||
all_user_id = [user.user_qq for user in all_users]
|
||||
all_user_data = [user.gold for user in all_users]
|
||||
await gold_rank.finish(
|
||||
"金币排行:\n" + await init_rank(all_user_id, all_user_data, event.group_id)
|
||||
|
||||
@ -92,7 +92,7 @@ async def _(
|
||||
# print(f'model --> {model}')
|
||||
for plugin in plugins2info_dict:
|
||||
if plugin == model:
|
||||
print(f'plugin --> {plugin}')
|
||||
# print(f'plugin --> {plugin}')
|
||||
try:
|
||||
group_id = str(event.group_id)
|
||||
except AttributeError:
|
||||
|
||||
@ -4,7 +4,7 @@ from models.level_user import LevelUser
|
||||
from nonebot.typing import T_State
|
||||
from nonebot.adapters.cqhttp import Bot, MessageEvent, Message
|
||||
from nonebot.rule import to_me
|
||||
from utils.utils import get_message_at, get_message_text, is_number, get_bot
|
||||
from utils.utils import get_message_at, get_message_text, is_number, get_bot, scheduler
|
||||
from services.log import logger
|
||||
from .data_source import open_remind, close_remind
|
||||
from models.group_info import GroupInfo
|
||||
@ -234,3 +234,17 @@ def _clear_data() -> float:
|
||||
file_size = 0
|
||||
size += file_size
|
||||
return float(size)
|
||||
|
||||
|
||||
# 早上好
|
||||
@scheduler.scheduled_job(
|
||||
"cron",
|
||||
hour=1,
|
||||
minute=1,
|
||||
)
|
||||
async def _():
|
||||
size = await asyncio.get_event_loop().run_in_executor(
|
||||
None, _clear_data
|
||||
)
|
||||
logger.info('自动清理临时数据完成,' + "共清理了 {:.2f}MB 的数据...".format(size / 1024 / 1024))
|
||||
|
||||
|
||||
@ -12,15 +12,22 @@ __plugin_name__ = "更新色图 [Hidden]"
|
||||
|
||||
__plugin_usage__ = '无'
|
||||
|
||||
exists_flag = False
|
||||
|
||||
update_setu = on_command("更新色图", rule=to_me(), permission=SUPERUSER, priority=1, block=True)
|
||||
|
||||
|
||||
@update_setu.handle()
|
||||
async def _(bot: Bot, event: Event, state: T_State):
|
||||
global exists_flag
|
||||
if DOWNLOAD_SETU:
|
||||
await update_setu.send("开始更新色图...", at_sender=True)
|
||||
await update_setu.finish(await update_setu_img(), at_sender=True)
|
||||
if not exists_flag:
|
||||
exists_flag = True
|
||||
await update_setu.send("开始更新色图...", at_sender=True)
|
||||
await update_setu.send(await update_setu_img(), at_sender=True)
|
||||
exists_flag = False
|
||||
else:
|
||||
await update_setu.finish("色图正在更新....")
|
||||
else:
|
||||
await update_setu.finish('更新色图配置未开启')
|
||||
|
||||
@ -32,5 +39,6 @@ async def _(bot: Bot, event: Event, state: T_State):
|
||||
minute=30,
|
||||
)
|
||||
async def _():
|
||||
if DOWNLOAD_SETU:
|
||||
global exists_flag
|
||||
if DOWNLOAD_SETU and not exists_flag:
|
||||
await update_setu_img()
|
||||
|
||||
@ -25,53 +25,54 @@ async def update_old_setu_data():
|
||||
path = Path(TXT_PATH)
|
||||
setu_data_file = path / "setu_data.json"
|
||||
r18_data_file = path / "r18_setu_data.json"
|
||||
index = 0
|
||||
r18_index = 0
|
||||
count = 0
|
||||
fail_count = 0
|
||||
for file in [setu_data_file, r18_data_file]:
|
||||
if file.exists():
|
||||
data = json.load(open(file, "r", encoding="utf8"))
|
||||
for x in data:
|
||||
if file == setu_data_file:
|
||||
idx = index
|
||||
if 'R-18' in data[x]["tags"]:
|
||||
data[x]["tags"].remove('R-18')
|
||||
else:
|
||||
idx = r18_index
|
||||
img_url = (
|
||||
data[x]["img_url"].replace("i.pixiv.cat", "i.pximg.net")
|
||||
if "i.pixiv.cat" in data[x]["img_url"]
|
||||
else data[x]["img_url"]
|
||||
)
|
||||
# idx = r18_index if 'R-18' in data[x]["tags"] else index
|
||||
try:
|
||||
await Setu.add_setu_data(
|
||||
idx,
|
||||
data[x]["title"],
|
||||
data[x]["author"],
|
||||
data[x]["pid"],
|
||||
data[x]["img_hash"],
|
||||
img_url,
|
||||
",".join(data[x]["tags"]),
|
||||
)
|
||||
count += 1
|
||||
if 'R-18' in data[x]["tags"]:
|
||||
r18_index += 1
|
||||
if setu_data_file.exists() or r18_data_file.exists():
|
||||
index = 0
|
||||
r18_index = 0
|
||||
count = 0
|
||||
fail_count = 0
|
||||
for file in [setu_data_file, r18_data_file]:
|
||||
if file.exists():
|
||||
data = json.load(open(file, "r", encoding="utf8"))
|
||||
for x in data:
|
||||
if file == setu_data_file:
|
||||
idx = index
|
||||
if 'R-18' in data[x]["tags"]:
|
||||
data[x]["tags"].remove('R-18')
|
||||
else:
|
||||
index += 1
|
||||
logger.info(f'添加旧色图数据成功 PID:{data[x]["pid"]} index:{idx}....')
|
||||
except UniqueViolationError:
|
||||
fail_count += 1
|
||||
logger.info(f'添加旧色图数据失败,色图重复 PID:{data[x]["pid"]} index:{idx}....')
|
||||
file.unlink()
|
||||
setu_url_path = path / "setu_url.json"
|
||||
setu_r18_url_path = path / "setu_r18_url.json"
|
||||
if setu_url_path.exists():
|
||||
setu_url_path.unlink()
|
||||
if setu_r18_url_path.exists():
|
||||
setu_r18_url_path.unlink()
|
||||
logger.info(f"更新旧色图数据完成,成功更新数据:{count} 条,累计失败:{fail_count} 条")
|
||||
idx = r18_index
|
||||
img_url = (
|
||||
data[x]["img_url"].replace("i.pixiv.cat", "i.pximg.net")
|
||||
if "i.pixiv.cat" in data[x]["img_url"]
|
||||
else data[x]["img_url"]
|
||||
)
|
||||
# idx = r18_index if 'R-18' in data[x]["tags"] else index
|
||||
try:
|
||||
await Setu.add_setu_data(
|
||||
idx,
|
||||
data[x]["title"],
|
||||
data[x]["author"],
|
||||
data[x]["pid"],
|
||||
data[x]["img_hash"],
|
||||
img_url,
|
||||
",".join(data[x]["tags"]),
|
||||
)
|
||||
count += 1
|
||||
if 'R-18' in data[x]["tags"]:
|
||||
r18_index += 1
|
||||
else:
|
||||
index += 1
|
||||
logger.info(f'添加旧色图数据成功 PID:{data[x]["pid"]} index:{idx}....')
|
||||
except UniqueViolationError:
|
||||
fail_count += 1
|
||||
logger.info(f'添加旧色图数据失败,色图重复 PID:{data[x]["pid"]} index:{idx}....')
|
||||
file.unlink()
|
||||
setu_url_path = path / "setu_url.json"
|
||||
setu_r18_url_path = path / "setu_r18_url.json"
|
||||
if setu_url_path.exists():
|
||||
setu_url_path.unlink()
|
||||
if setu_r18_url_path.exists():
|
||||
setu_r18_url_path.unlink()
|
||||
logger.info(f"更新旧色图数据完成,成功更新数据:{count} 条,累计失败:{fail_count} 条")
|
||||
|
||||
|
||||
headers = {
|
||||
@ -142,7 +143,6 @@ async def update_setu_img():
|
||||
break
|
||||
except (TimeoutError, ClientConnectorError) as e:
|
||||
logger.warning(f"{image.local_id}.jpg 更新失败 ..{type(e)}:{e}")
|
||||
pass
|
||||
except Exception as e:
|
||||
_success -= 1
|
||||
logger.error(f"更新色图 {image.local_id}.jpg 错误 {type(e)}: {e}")
|
||||
@ -151,6 +151,8 @@ async def update_setu_img():
|
||||
error_info.append(
|
||||
f"更新色图 {image.local_id}.jpg 错误 {type(e)}: {e}"
|
||||
)
|
||||
else:
|
||||
logger.info(f'更新色图 {image.local_id}.jpg 已存在')
|
||||
await get_bot().send_private_msg(
|
||||
user_id=int(list(get_bot().config.superusers)[0]),
|
||||
message=f'{str(datetime.now()).split(".")[0]} 更新 色图 完成,实际更新 {_success} 张,以下为更新时未知错误:\n'
|
||||
|
||||
@ -1,10 +1,9 @@
|
||||
from nonebot import on_regex
|
||||
from .data_source import get_weather_of_city
|
||||
from .data_source import get_weather_of_city, update_city, get_city_list
|
||||
from nonebot.adapters.cqhttp import Bot, MessageEvent, GroupMessageEvent
|
||||
from jieba import posseg
|
||||
from services.log import logger
|
||||
from nonebot.typing import T_State
|
||||
from .config import city_list
|
||||
import re
|
||||
from utils.utils import get_message_text
|
||||
|
||||
@ -26,14 +25,9 @@ async def _(bot: Bot, event: MessageEvent, state: T_State):
|
||||
msg += "市"
|
||||
city = ""
|
||||
if msg:
|
||||
citys = []
|
||||
for x in city_list.keys():
|
||||
for city in city_list[x]:
|
||||
citys.append(city)
|
||||
city_list = get_city_list()
|
||||
for word in posseg.lcut(msg):
|
||||
if word.word in city_list.keys():
|
||||
await weather.finish("不要查一个省的天气啊,这么大查起来很累人的..", at_sender=True)
|
||||
if word.flag == "ns" or word.word[:-1] in citys:
|
||||
if word.flag == "ns" or word.word[:-1] in city_list:
|
||||
city = str(word.word).strip()
|
||||
break
|
||||
if word.word == "火星":
|
||||
|
||||
@ -1,327 +0,0 @@
|
||||
city_list = {
|
||||
"北京": ["北京"],
|
||||
"天津": ["天津"],
|
||||
"山西": ["太原", "阳泉", "晋城", "长治", "临汾", "运城", "忻州", "吕梁", "晋中", "大同", "朔州"],
|
||||
"河北": [
|
||||
"沧州",
|
||||
"石家庄",
|
||||
"唐山",
|
||||
"保定",
|
||||
"廊坊",
|
||||
"衡水",
|
||||
"邯郸",
|
||||
"邢台",
|
||||
"张家口",
|
||||
"辛集",
|
||||
"秦皇岛",
|
||||
"定州",
|
||||
"承德",
|
||||
"涿州",
|
||||
],
|
||||
"山东": [
|
||||
"济南",
|
||||
"淄博",
|
||||
"聊城",
|
||||
"德州",
|
||||
"滨州",
|
||||
"济宁",
|
||||
"菏泽",
|
||||
"枣庄",
|
||||
"烟台",
|
||||
"威海",
|
||||
"泰安",
|
||||
"青岛",
|
||||
"临沂",
|
||||
"莱芜",
|
||||
"东营",
|
||||
"潍坊",
|
||||
"日照",
|
||||
],
|
||||
"河南": [
|
||||
"郑州",
|
||||
"新乡",
|
||||
"鹤壁",
|
||||
"安阳",
|
||||
"焦作",
|
||||
"濮阳",
|
||||
"开封",
|
||||
"驻马店",
|
||||
"商丘",
|
||||
"三门峡",
|
||||
"南阳",
|
||||
"洛阳",
|
||||
"周口",
|
||||
"许昌",
|
||||
"信阳",
|
||||
"漯河",
|
||||
"平顶山",
|
||||
"济源",
|
||||
],
|
||||
"广东": [
|
||||
"珠海",
|
||||
"中山",
|
||||
"肇庆",
|
||||
"深圳",
|
||||
"清远",
|
||||
"揭阳",
|
||||
"江门",
|
||||
"惠州",
|
||||
"河源",
|
||||
"广州",
|
||||
"佛山",
|
||||
"东莞",
|
||||
"潮州",
|
||||
"汕尾",
|
||||
"梅州",
|
||||
"阳江",
|
||||
"云浮",
|
||||
"韶关",
|
||||
"湛江",
|
||||
"汕头",
|
||||
"茂名",
|
||||
],
|
||||
"浙江": ["舟山", "温州", "台州", "绍兴", "衢州", "宁波", "丽水", "金华", "嘉兴", "湖州", "杭州"],
|
||||
"宁夏": ["中卫", "银川", "吴忠", "石嘴山", "固原"],
|
||||
"江苏": [
|
||||
"镇江",
|
||||
"扬州",
|
||||
"盐城",
|
||||
"徐州",
|
||||
"宿迁",
|
||||
"无锡",
|
||||
"苏州",
|
||||
"南通",
|
||||
"南京",
|
||||
"连云港",
|
||||
"淮安",
|
||||
"常州",
|
||||
"泰州",
|
||||
],
|
||||
"湖南": [
|
||||
"长沙",
|
||||
"邵阳",
|
||||
"怀化",
|
||||
"株洲",
|
||||
"张家界",
|
||||
"永州",
|
||||
"益阳",
|
||||
"湘西",
|
||||
"娄底",
|
||||
"衡阳",
|
||||
"郴州",
|
||||
"岳阳",
|
||||
"常德",
|
||||
"湘潭",
|
||||
],
|
||||
"吉林": ["长春", "长春", "通化", "松原", "四平", "辽源", "吉林", "延边", "白山", "白城"],
|
||||
"福建": ["漳州", "厦门", "福州", "三明", "莆田", "宁德", "南平", "龙岩", "泉州"],
|
||||
"甘肃": [
|
||||
"张掖",
|
||||
"陇南",
|
||||
"兰州",
|
||||
"嘉峪关",
|
||||
"白银",
|
||||
"武威",
|
||||
"天水",
|
||||
"庆阳",
|
||||
"平凉",
|
||||
"临夏",
|
||||
"酒泉",
|
||||
"金昌",
|
||||
"甘南",
|
||||
"定西",
|
||||
],
|
||||
"陕西": ["榆林", "西安", "延安", "咸阳", "渭南", "铜川", "商洛", "汉中", "宝鸡", "安康"],
|
||||
"辽宁": [
|
||||
"营口",
|
||||
"铁岭",
|
||||
"沈阳",
|
||||
"盘锦",
|
||||
"辽阳",
|
||||
"锦州",
|
||||
"葫芦岛",
|
||||
"阜新",
|
||||
"抚顺",
|
||||
"丹东",
|
||||
"大连",
|
||||
"朝阳",
|
||||
"本溪",
|
||||
"鞍山",
|
||||
],
|
||||
"江西": ["鹰潭", "宜春", "上饶", "萍乡", "南昌", "景德镇", "吉安", "抚州", "新余", "九江", "赣州"],
|
||||
"黑龙江": [
|
||||
"伊春",
|
||||
"七台河",
|
||||
"牡丹江",
|
||||
"鸡西",
|
||||
"黑河",
|
||||
"鹤岗",
|
||||
"哈尔滨",
|
||||
"大兴安岭",
|
||||
"绥化",
|
||||
"双鸭山",
|
||||
"齐齐哈尔",
|
||||
"佳木斯",
|
||||
"大庆",
|
||||
],
|
||||
"安徽": [
|
||||
"宣城",
|
||||
"铜陵",
|
||||
"六安",
|
||||
"黄山",
|
||||
"淮南",
|
||||
"合肥",
|
||||
"阜阳",
|
||||
"亳州",
|
||||
"安庆",
|
||||
"池州",
|
||||
"宿州",
|
||||
"芜湖",
|
||||
"马鞍山",
|
||||
"淮北",
|
||||
"滁州",
|
||||
"蚌埠",
|
||||
],
|
||||
"湖北": [
|
||||
"孝感",
|
||||
"武汉",
|
||||
"十堰",
|
||||
"荆门",
|
||||
"黄冈",
|
||||
"襄阳",
|
||||
"咸宁",
|
||||
"随州",
|
||||
"黄石",
|
||||
"恩施",
|
||||
"鄂州",
|
||||
"荆州",
|
||||
"宜昌",
|
||||
"潜江",
|
||||
"天门",
|
||||
"神农架",
|
||||
"仙桃",
|
||||
],
|
||||
"青海": ["西宁", "海西", "海东", "玉树", "黄南", "海南", "海北", "果洛"],
|
||||
"新疆": [
|
||||
"乌鲁木齐",
|
||||
"克州",
|
||||
"阿勒泰",
|
||||
"五家渠",
|
||||
"石河子",
|
||||
"伊犁",
|
||||
"吐鲁番",
|
||||
"塔城",
|
||||
"克拉玛依",
|
||||
"喀什",
|
||||
"和田",
|
||||
"哈密",
|
||||
"昌吉",
|
||||
"博尔塔拉",
|
||||
"阿克苏",
|
||||
"巴音郭楞",
|
||||
"阿拉尔",
|
||||
"图木舒克",
|
||||
"铁门关",
|
||||
],
|
||||
"贵州": ["铜仁", "黔东南", "贵阳", "安顺", "遵义", "黔西南", "黔南", "六盘水", "毕节"],
|
||||
"四川": [
|
||||
"遂宁",
|
||||
"攀枝花",
|
||||
"眉山",
|
||||
"凉山",
|
||||
"成都",
|
||||
"巴中",
|
||||
"广安",
|
||||
"自贡",
|
||||
"甘孜",
|
||||
"资阳",
|
||||
"宜宾",
|
||||
"雅安",
|
||||
"内江",
|
||||
"南充",
|
||||
"绵阳",
|
||||
"泸州",
|
||||
"凉山",
|
||||
"乐山",
|
||||
"广元",
|
||||
"甘孜",
|
||||
"德阳",
|
||||
"达州",
|
||||
"阿坝",
|
||||
],
|
||||
"上海": ["上海"],
|
||||
"广西": [
|
||||
"南宁",
|
||||
"贵港",
|
||||
"玉林",
|
||||
"梧州",
|
||||
"钦州",
|
||||
"柳州",
|
||||
"来宾",
|
||||
"贺州",
|
||||
"河池",
|
||||
"桂林",
|
||||
"防城港",
|
||||
"崇左",
|
||||
"北海",
|
||||
"百色",
|
||||
],
|
||||
"西藏": ["拉萨", "山南", "日喀则", "那曲", "林芝", "昌都", "阿里"],
|
||||
"云南": [
|
||||
"昆明",
|
||||
"红河",
|
||||
"大理",
|
||||
"玉溪",
|
||||
"昭通",
|
||||
"西双版纳",
|
||||
"文山",
|
||||
"曲靖",
|
||||
"普洱",
|
||||
"怒江",
|
||||
"临沧",
|
||||
"丽江",
|
||||
"红河",
|
||||
"迪庆",
|
||||
"德宏",
|
||||
"大理",
|
||||
"楚雄",
|
||||
"保山",
|
||||
],
|
||||
"内蒙古": [
|
||||
"呼和浩特",
|
||||
"乌兰察布",
|
||||
"兴安",
|
||||
"赤峰",
|
||||
"呼伦贝尔",
|
||||
"锡林郭勒",
|
||||
"乌海",
|
||||
"通辽",
|
||||
"巴彦淖尔",
|
||||
"阿拉善",
|
||||
"鄂尔多斯",
|
||||
"包头",
|
||||
],
|
||||
"海南": [
|
||||
"海口",
|
||||
"三沙",
|
||||
"三亚",
|
||||
"临高",
|
||||
"五指山",
|
||||
"陵水",
|
||||
"文昌",
|
||||
"万宁",
|
||||
"白沙",
|
||||
"乐东",
|
||||
"澄迈",
|
||||
"屯昌",
|
||||
"定安",
|
||||
"东方",
|
||||
"保亭",
|
||||
"琼中",
|
||||
"琼海",
|
||||
"儋州",
|
||||
"昌江",
|
||||
],
|
||||
"重庆": ["重庆"],
|
||||
"台湾": ["台北", "高雄", "基隆", "台中", "台南", "新竹", "嘉义", "新北", "桃园"],
|
||||
}
|
||||
@ -1,21 +1,99 @@
|
||||
import requests
|
||||
from services.log import logger
|
||||
from utils.message_builder import image
|
||||
from utils.user_agent import get_user_agent
|
||||
from configs.path_config import TXT_PATH
|
||||
from asyncio.exceptions import TimeoutError
|
||||
from typing import List
|
||||
from nonebot import Driver
|
||||
from pathlib import Path
|
||||
import aiohttp
|
||||
import ujson as json
|
||||
import nonebot
|
||||
|
||||
driver: Driver = nonebot.get_driver()
|
||||
|
||||
china_city = Path(TXT_PATH) / "china_city.json"
|
||||
|
||||
try:
|
||||
with open(china_city, "r", encoding="utf8") as f:
|
||||
data = json.load(f)
|
||||
except FileNotFoundError:
|
||||
data = {}
|
||||
|
||||
|
||||
async def get_weather_of_city(city) -> str:
|
||||
url = "http://wthrcdn.etouch.cn/weather_mini?city=" + city
|
||||
data_json = requests.get(url).json()
|
||||
if "desc" in data_json:
|
||||
if data_json["desc"] == "invilad-citykey":
|
||||
return "你为啥不查火星的天气呢?小真寻只支持国内天气查询!!" + image("shengqi", "zhenxun")
|
||||
elif data_json["desc"] == "OK":
|
||||
w_type = data_json["data"]["forecast"][0]["type"]
|
||||
w_max = data_json["data"]["forecast"][0]["high"][3:]
|
||||
w_min = data_json["data"]["forecast"][0]["low"][3:]
|
||||
fengli = data_json["data"]["forecast"][0]["fengli"][9:-3]
|
||||
ganmao = data_json["data"]["ganmao"]
|
||||
fengxiang = data_json["data"]["forecast"][0]["fengxiang"]
|
||||
repass = f"{city}的天气是 {w_type} 天\n最高温度: {w_max}\n最低温度: {w_min}\n风力: {fengli} {fengxiang}\n{ganmao}"
|
||||
return repass
|
||||
async def get_weather_of_city(city: str) -> str:
|
||||
code = _check_exists_city(city)
|
||||
if code == 999:
|
||||
return "不要查一个省份的天气啊,很累人的!"
|
||||
elif code == 998:
|
||||
return "真寻只可以查询国内的天气喔..."
|
||||
else:
|
||||
return "好像出错了?"
|
||||
async with aiohttp.ClientSession(headers=get_user_agent()) as session:
|
||||
async with session.get(
|
||||
f"http://wthrcdn.etouch.cn/weather_mini?city={city}", timeout=5
|
||||
) as res:
|
||||
data_json = json.loads(await res.text(encoding="utf8"))
|
||||
if "desc" in data_json:
|
||||
if data_json["desc"] == "invilad-citykey":
|
||||
return "你为啥不查火星的天气呢?小真寻只支持国内天气查询!!" + image(
|
||||
"shengqi", "zhenxun"
|
||||
)
|
||||
elif data_json["desc"] == "OK":
|
||||
w_type = data_json["data"]["forecast"][0]["type"]
|
||||
w_max = data_json["data"]["forecast"][0]["high"][3:]
|
||||
w_min = data_json["data"]["forecast"][0]["low"][3:]
|
||||
fengli = data_json["data"]["forecast"][0]["fengli"][9:-3]
|
||||
ganmao = data_json["data"]["ganmao"]
|
||||
fengxiang = data_json["data"]["forecast"][0]["fengxiang"]
|
||||
repass = f"{city}的天气是 {w_type} 天\n最高温度: {w_max}\n最低温度: {w_min}\n风力: {fengli} {fengxiang}\n{ganmao}"
|
||||
return repass
|
||||
else:
|
||||
return "好像出错了?"
|
||||
|
||||
|
||||
# 更新城市
|
||||
@driver.on_startup
|
||||
async def update_city():
|
||||
global data
|
||||
try:
|
||||
async with aiohttp.ClientSession(headers=get_user_agent()) as session:
|
||||
async with session.get(
|
||||
"http://www.weather.com.cn/data/city3jdata/china.html", timeout=5
|
||||
) as res:
|
||||
provinces_data = json.loads(await res.text(encoding="utf8"))
|
||||
for province in provinces_data.keys():
|
||||
data[provinces_data[province]] = []
|
||||
async with session.get(
|
||||
f"http://www.weather.com.cn/data/city3jdata/provshi/{province}.html",
|
||||
timeout=5,
|
||||
) as res:
|
||||
city_data = json.loads(await res.text(encoding="utf8"))
|
||||
for city in city_data.keys():
|
||||
data[provinces_data[province]].append(city_data[city])
|
||||
with open(china_city, "w", encoding="utf8") as f:
|
||||
json.dump(data, f, indent=4, ensure_ascii=False)
|
||||
logger.info("自动更新城市列表完成.....")
|
||||
except TimeoutError:
|
||||
logger.info("自动更新城市列表超时.....")
|
||||
|
||||
|
||||
# 城市是否存在或是否是省份
|
||||
def _check_exists_city(city: str) -> int:
|
||||
city = city if city[-1] != "市" else city[:-1]
|
||||
for province in data.keys():
|
||||
# 查询省份了
|
||||
if city == province and len(data[province]) != 1:
|
||||
return 999
|
||||
for city_ in data[province]:
|
||||
if city_ == city:
|
||||
return 200
|
||||
return 998
|
||||
|
||||
|
||||
def get_city_list() -> List[str]:
|
||||
global data
|
||||
city_list = []
|
||||
for p in data.keys():
|
||||
for c in data[p]:
|
||||
city_list.append(c)
|
||||
return city_list
|
||||
|
||||
@ -1,10 +1,8 @@
|
||||
from nonebot import on_command
|
||||
from .data_source import get_yiqing_data, clear_data
|
||||
from .data_source import get_yiqing_data
|
||||
from services.log import logger
|
||||
from nonebot.adapters.cqhttp import Bot, MessageEvent, GroupMessageEvent
|
||||
from nonebot.typing import T_State
|
||||
from .config import city_list
|
||||
from utils.utils import scheduler
|
||||
|
||||
__plugin_name__ = "疫情查询"
|
||||
__plugin_usage__ = "查询疫情帮助:\n\t对我说 查询疫情 省份/城市,我会回复疫情的实时数据\n\t示例: 查询疫情 温州"
|
||||
@ -16,43 +14,16 @@ yiqing = on_command("疫情", aliases={"查询疫情", "疫情查询"}, priority
|
||||
@yiqing.handle()
|
||||
async def _(bot: Bot, event: MessageEvent, state: T_State):
|
||||
msg = str(event.get_message()).strip()
|
||||
if not msg or msg in ["帮助"]:
|
||||
await yiqing.finish(__plugin_usage__)
|
||||
if msg:
|
||||
if msg in city_list.keys():
|
||||
province = msg
|
||||
city = ""
|
||||
else:
|
||||
for key in city_list.keys():
|
||||
if msg in city_list.get(key):
|
||||
province = key
|
||||
city = msg
|
||||
break
|
||||
result = await get_yiqing_data(msg)
|
||||
if result:
|
||||
await yiqing.send(result)
|
||||
logger.info(
|
||||
f"(USER {event.user_id}, GROUP "
|
||||
f"{event.group_id if isinstance(event, GroupMessageEvent) else 'private'}) 查询疫情: {msg}"
|
||||
)
|
||||
else:
|
||||
await yiqing.finish(__plugin_usage__)
|
||||
try:
|
||||
result = await get_yiqing_data(province, city)
|
||||
if result:
|
||||
await yiqing.send(result)
|
||||
logger.info(
|
||||
f"(USER {event.user_id}, GROUP "
|
||||
f"{event.group_id if isinstance(event, GroupMessageEvent) else 'private'}) 查询疫情:"
|
||||
+ result
|
||||
)
|
||||
else:
|
||||
await yiqing.send("查询失败!!!!", at_sender=True)
|
||||
logger.info(
|
||||
f"(USER {event.user_id}, GROUP "
|
||||
f"{event.group_id if isinstance(event, GroupMessageEvent) else 'private'}) 查询疫情失败"
|
||||
)
|
||||
except UnboundLocalError:
|
||||
await yiqing.finish("参数正确吗?只要一个参数啊", at_sender=True)
|
||||
|
||||
|
||||
@scheduler.scheduled_job(
|
||||
"cron",
|
||||
hour=0,
|
||||
minute=1,
|
||||
)
|
||||
async def _():
|
||||
clear_data()
|
||||
await yiqing.send("查询失败!!!!", at_sender=True)
|
||||
logger.info(
|
||||
f"(USER {event.user_id}, GROUP "
|
||||
f"{event.group_id if isinstance(event, GroupMessageEvent) else 'private'}) 查询疫情失败"
|
||||
)
|
||||
|
||||
@ -1,34 +0,0 @@
|
||||
city_list = {
|
||||
"北京": ["北京"],
|
||||
"天津": ["天津"],
|
||||
"山西": ["太原", "阳泉", "晋城", "长治", "临汾", "运城", "忻州", "吕梁", "晋中", "大同", "朔州"],
|
||||
"河北": ["沧州", "石家庄", "唐山", "保定", "廊坊", "衡水", "邯郸", "邢台", "张家口", "辛集", "秦皇岛", "定州", "承德", "涿州"],
|
||||
"山东": ["济南", "淄博", "聊城", "德州", "滨州", "济宁", "菏泽", "枣庄", "烟台", "威海", "泰安", "青岛", "临沂", "莱芜", "东营", "潍坊", "日照"],
|
||||
"河南": ["郑州", "新乡", "鹤壁", "安阳", "焦作", "濮阳", "开封", "驻马店", "商丘", "三门峡", "南阳", "洛阳", "周口", "许昌", "信阳", "漯河", "平顶山", "济源"],
|
||||
"广东": ["珠海", "中山", "肇庆", "深圳", "清远", "揭阳", "江门", "惠州", "河源", "广州", "佛山", "东莞", "潮州", "汕尾", "梅州", "阳江", "云浮", "韶关", "湛江", "汕头", "茂名"],
|
||||
"浙江": ["舟山", "温州", "台州", "绍兴", "衢州", "宁波", "丽水", "金华", "嘉兴", "湖州", "杭州"],
|
||||
"宁夏": ["中卫", "银川", "吴忠", "石嘴山", "固原"],
|
||||
"江苏": ["镇江", "扬州", "盐城", "徐州", "宿迁", "无锡", "苏州", "南通", "南京", "连云港", "淮安", "常州", "泰州"],
|
||||
"湖南": ["长沙", "邵阳", "怀化", "株洲", "张家界", "永州", "益阳", "湘西", "娄底", "衡阳", "郴州", "岳阳", "常德", "湘潭"],
|
||||
"吉林": ["长春", "长春", "通化", "松原", "四平", "辽源", "吉林", "延边", "白山", "白城"],
|
||||
"福建": ["漳州", "厦门", "福州", "三明", "莆田", "宁德", "南平", "龙岩", "泉州"],
|
||||
"甘肃": ["张掖", "陇南", "兰州", "嘉峪关", "白银", "武威", "天水", "庆阳", "平凉", "临夏", "酒泉", "金昌", "甘南", "定西"],
|
||||
"陕西": ["榆林", "西安", "延安", "咸阳", "渭南", "铜川", "商洛", "汉中", "宝鸡", "安康"],
|
||||
"辽宁": ["营口", "铁岭", "沈阳", "盘锦", "辽阳", "锦州", "葫芦岛", "阜新", "抚顺", "丹东", "大连", "朝阳", "本溪", "鞍山"],
|
||||
"江西": ["鹰潭", "宜春", "上饶", "萍乡", "南昌", "景德镇", "吉安", "抚州", "新余", "九江", "赣州"],
|
||||
"黑龙江": ["伊春", "七台河", "牡丹江", "鸡西", "黑河", "鹤岗", "哈尔滨", "大兴安岭", "绥化", "双鸭山", "齐齐哈尔", "佳木斯", "大庆"],
|
||||
"安徽": ["宣城", "铜陵", "六安", "黄山", "淮南", "合肥", "阜阳", "亳州", "安庆", "池州", "宿州", "芜湖", "马鞍山", "淮北", "滁州", "蚌埠"],
|
||||
"湖北": ["孝感", "武汉", "十堰", "荆门", "黄冈", "襄阳", "咸宁", "随州", "黄石", "恩施", "鄂州", "荆州", "宜昌", "潜江", "天门", "神农架", "仙桃"],
|
||||
"青海": ["西宁", "海西", "海东", "玉树", "黄南", "海南", "海北", "果洛"],
|
||||
"新疆": ["乌鲁木齐", "克州", "阿勒泰", "五家渠", "石河子", "伊犁", "吐鲁番", "塔城", "克拉玛依", "喀什", "和田", "哈密", "昌吉", "博尔塔拉", "阿克苏", "巴音郭楞", "阿拉尔", "图木舒克", "铁门关"],
|
||||
"贵州": ["铜仁", "黔东南", "贵阳", "安顺", "遵义", "黔西南", "黔南", "六盘水", "毕节"],
|
||||
"四川": ["遂宁", "攀枝花", "眉山", "凉山", "成都", "巴中", "广安", "自贡", "甘孜", "资阳", "宜宾", "雅安", "内江", "南充", "绵阳", "泸州", "凉山", "乐山", "广元", "甘孜", "德阳", "达州", "阿坝"],
|
||||
"上海": ["上海"],
|
||||
"广西": ["南宁", "贵港", "玉林", "梧州", "钦州", "柳州", "来宾", "贺州", "河池", "桂林", "防城港", "崇左", "北海", "百色"],
|
||||
"西藏": ["拉萨", "山南", "日喀则", "那曲", "林芝", "昌都", "阿里"],
|
||||
"云南": ["昆明", "红河", "大理", "玉溪", "昭通", "西双版纳", "文山", "曲靖", "普洱", "怒江", "临沧", "丽江", "红河", "迪庆", "德宏", "大理", "楚雄", "保山"],
|
||||
"内蒙古": ["呼和浩特", "乌兰察布", "兴安", "赤峰", "呼伦贝尔", "锡林郭勒", "乌海", "通辽", "巴彦淖尔", "阿拉善", "鄂尔多斯", "包头"],
|
||||
"海南": ["海口", "三沙", "三亚", "临高", "五指山", "陵水", "文昌", "万宁", "白沙", "乐东", "澄迈", "屯昌", "定安", "东方", "保亭", "琼中", "琼海", "儋州", "昌江"],
|
||||
"重庆": ["重庆"],
|
||||
"台湾": ["台北", "高雄", "基隆", "台中", "台南", "新竹", "嘉义", "新北", "桃园"]
|
||||
}
|
||||
@ -1,67 +1,88 @@
|
||||
from datetime import datetime
|
||||
import aiohttp
|
||||
from utils.user_agent import get_user_agent
|
||||
import json
|
||||
import os
|
||||
from configs.path_config import TXT_PATH
|
||||
from utils.utils import get_local_proxy
|
||||
from typing import List
|
||||
from pathlib import Path
|
||||
import ujson as json
|
||||
import aiohttp
|
||||
|
||||
china_city = Path(TXT_PATH) / "china_city.json"
|
||||
|
||||
try:
|
||||
with open(china_city, "r", encoding="utf8") as f:
|
||||
data = json.load(f)
|
||||
except FileNotFoundError:
|
||||
data = {}
|
||||
|
||||
|
||||
url = "https://api.yimian.xyz/coro/"
|
||||
url = "https://view.inews.qq.com/g2/getOnsInfo?name=disease_h5"
|
||||
|
||||
|
||||
async def get_yiqing_data(province, city_=""):
|
||||
if not os.path.exists(TXT_PATH + "yiqing/"):
|
||||
os.mkdir(TXT_PATH + "yiqing/")
|
||||
if not os.path.exists(TXT_PATH + "yiqing/" + str(datetime.now().date()) + ".json"):
|
||||
async with aiohttp.ClientSession(headers=get_user_agent()) as session:
|
||||
async with session.get(url, proxy=get_local_proxy(), timeout=7) as response:
|
||||
datalist = await response.json()
|
||||
with open(
|
||||
TXT_PATH + "yiqing/" + str(datetime.now().date()) + ".json", "w"
|
||||
) as f:
|
||||
json.dump(datalist, f)
|
||||
datalist = json.load(
|
||||
open(TXT_PATH + "yiqing/" + str(datetime.now().date()) + ".json", "r")
|
||||
)
|
||||
result = ""
|
||||
for data in datalist:
|
||||
if data["provinceShortName"] == province:
|
||||
if city_ == "":
|
||||
result = (
|
||||
province
|
||||
+ "疫情数据:\n现存确诊: "
|
||||
+ str(data["currentConfirmedCount"])
|
||||
+ "\n累计确诊: "
|
||||
+ str(data["confirmedCount"])
|
||||
+ "\n治愈: "
|
||||
+ str(data["curedCount"])
|
||||
+ "\n死亡: "
|
||||
+ str(data["deadCount"])
|
||||
)
|
||||
break
|
||||
async def get_yiqing_data(area: str):
|
||||
global data
|
||||
province = None
|
||||
city = None
|
||||
province_type = "省"
|
||||
if area == '中国':
|
||||
province = area
|
||||
province_type = ""
|
||||
elif area in data.keys():
|
||||
province = area
|
||||
if len(data[area]) == 1:
|
||||
province_type = "市"
|
||||
city = ""
|
||||
else:
|
||||
for p in data.keys():
|
||||
if area in data[p]:
|
||||
province = p
|
||||
city = area
|
||||
if not province and not city:
|
||||
return "小真寻只支持国内的疫情查询喔..."
|
||||
async with aiohttp.ClientSession(headers=get_user_agent()) as session:
|
||||
async with session.get(url, timeout=7) as response:
|
||||
epidemic_data = json.loads((await response.json())["data"])
|
||||
last_update_time = epidemic_data["lastUpdateTime"]
|
||||
if area == "中国":
|
||||
data_ = epidemic_data["areaTree"][0]
|
||||
else:
|
||||
for city in data["cities"]:
|
||||
if city["cityName"] == city_:
|
||||
result = (
|
||||
city_
|
||||
+ "疫情数据:\n现存确诊: "
|
||||
+ str(city["currentConfirmedCount"])
|
||||
+ "\n累计确诊: "
|
||||
+ str(city["confirmedCount"])
|
||||
+ "\n治愈: "
|
||||
+ str(city["curedCount"])
|
||||
+ "\n死亡: "
|
||||
+ str(city["deadCount"])
|
||||
)
|
||||
break
|
||||
return result
|
||||
data_ = [
|
||||
x
|
||||
for x in epidemic_data["areaTree"][0]["children"]
|
||||
if x["name"] == province
|
||||
][0]
|
||||
if city:
|
||||
try:
|
||||
data_ = [x for x in data_["children"] if x["name"] == city][0]
|
||||
except IndexError:
|
||||
return '未查询到...'
|
||||
confirm = data_["total"]["confirm"] # 累计确诊
|
||||
heal = data_["total"]["heal"] # 累计治愈
|
||||
dead = data_["total"]["dead"] # 累计死亡
|
||||
dead_rate = data_["total"]["deadRate"] # 死亡率
|
||||
heal_rate = data_["total"]["healRate"] # 治愈率
|
||||
now_confirm = data_["total"]["nowConfirm"] # 目前确诊
|
||||
suspect = data_["total"]["suspect"] # 疑似
|
||||
add_confirm = data_["today"]["confirm"] # 新增确诊
|
||||
x = f"{city}市" if city else f'{province}{province_type}'
|
||||
return (
|
||||
f"{x} 疫情数据:\n"
|
||||
f"\t目前确诊:\n"
|
||||
f"\t\t确诊人数:{now_confirm}(+{add_confirm})\n"
|
||||
f"\t\t疑似人数:{suspect}\n"
|
||||
f"==================\n"
|
||||
f"\t累计数据:\n"
|
||||
f"\t\t确诊人数:{confirm}\n"
|
||||
f"\t\t治愈人数:{heal}\n"
|
||||
f"\t\t死亡人数:{dead}\n"
|
||||
f"\t治愈率:{heal_rate}%\n"
|
||||
f"\t死亡率:{dead_rate}%\n"
|
||||
f"更新日期:{last_update_time}"
|
||||
)
|
||||
|
||||
|
||||
def clear_data():
|
||||
for file in os.listdir(TXT_PATH + "yiqing/"):
|
||||
os.remove(TXT_PATH + "yiqing/" + file)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
print(get_yiqing_data("浙江", city_=""))
|
||||
def get_city_list() -> List[str]:
|
||||
global data
|
||||
city_list = []
|
||||
for p in data.keys():
|
||||
for c in data[p]:
|
||||
city_list.append(c)
|
||||
return city_list
|
||||
|
||||
@ -285,7 +285,8 @@ class CreateImg:
|
||||
"""
|
||||
说明:
|
||||
检查文本所需宽度是否大于图片宽度
|
||||
:param word: 文本内容
|
||||
参数:
|
||||
:param word: 文本内容
|
||||
"""
|
||||
return self.ttfont.getsize(word)[0] > self.w
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user