mirror of
https://github.com/PaiGramTeam/fastapi_genshin_map.git
synced 2024-11-16 03:55:30 +00:00
parent
715c6813f3
commit
5905b4aebe
@ -1,47 +1,44 @@
|
||||
import random
|
||||
from io import BytesIO
|
||||
from pathlib import Path
|
||||
from time import time
|
||||
from typing import Optional, Union
|
||||
|
||||
import yaml
|
||||
|
||||
from fastapi import APIRouter, HTTPException, Query
|
||||
from fastapi.responses import FileResponse, StreamingResponse
|
||||
from fastapi import APIRouter
|
||||
from fastapi.responses import FileResponse
|
||||
from PIL import Image
|
||||
|
||||
from .GenshinMap.genshinmap import img, models, request, utils
|
||||
from .logger import logger
|
||||
|
||||
Image.MAX_IMAGE_PIXELS = 333120000
|
||||
router = APIRouter(prefix='/get_map')
|
||||
TEXT_PATH = Path(__file__).parent / 'texture2d'
|
||||
mark_quest = Image.open(TEXT_PATH / 'mark_quest.png').resize((32, 32))
|
||||
MAP = Path(__file__).parent / 'map_data'
|
||||
RESOURCE_PATH = Path(__file__).parent / 'resource_data'
|
||||
CHASM_PATH = MAP / 'chasm.png'
|
||||
ENKANOMIYA_PATH = MAP / 'enkanomiya.png'
|
||||
TEYVAT_PATH = MAP / 'teyvat.png'
|
||||
router = APIRouter(prefix="/get_map")
|
||||
TEXT_PATH = Path(__file__).parent / "texture2d"
|
||||
mark_quest = Image.open(TEXT_PATH / "mark_quest.png").resize((32, 32))
|
||||
MAP = Path(__file__).parent / "map_data"
|
||||
RESOURCE_PATH = Path(__file__).parent / "resource_data"
|
||||
CHASM_PATH = MAP / "chasm.png"
|
||||
ENKANOMIYA_PATH = MAP / "enkanomiya.png"
|
||||
TEYVAT_PATH = MAP / "teyvat.png"
|
||||
|
||||
with open(Path(__file__).parent / 'map.yaml', 'r', encoding='utf-8') as ymlfile:
|
||||
with open(Path(__file__).parent / "map.yaml", "r", encoding="utf-8") as ymlfile:
|
||||
resource_aliases = yaml.load(ymlfile, Loader=yaml.SafeLoader)
|
||||
|
||||
MAP_ID_DICT = {
|
||||
'2': models.MapID.teyvat, # 提瓦特
|
||||
'9': models.MapID.chasm, # 层岩巨渊
|
||||
'7': models.MapID.enkanomiya, # 渊下宫
|
||||
"2": models.MapID.teyvat, # 提瓦特
|
||||
"9": models.MapID.chasm, # 层岩巨渊
|
||||
"7": models.MapID.enkanomiya, # 渊下宫
|
||||
# MapID.golden_apple_archipelago, # 金苹果群岛
|
||||
}
|
||||
|
||||
|
||||
@router.on_event('startup')
|
||||
@router.on_event("startup")
|
||||
async def create_genshin_map():
|
||||
if CHASM_PATH.exists() and ENKANOMIYA_PATH.exists() and TEYVAT_PATH.exists():
|
||||
logger.info('****************** 开始地图API服务 *****************')
|
||||
logger.info("****************** 开始地图API服务 *****************")
|
||||
return
|
||||
logger.info('****************** 地图API服务进行初始化 *****************')
|
||||
mark_god_pic = Image.open(TEXT_PATH / 'mark_god.png')
|
||||
mark_trans_pic = Image.open(TEXT_PATH / 'mark_trans.png')
|
||||
logger.info("****************** 地图API服务进行初始化 *****************")
|
||||
mark_god_pic = Image.open(TEXT_PATH / "mark_god.png")
|
||||
mark_trans_pic = Image.open(TEXT_PATH / "mark_trans.png")
|
||||
for map_id in models.MapID:
|
||||
maps = await request.get_maps(map_id)
|
||||
points = await request.get_points(map_id)
|
||||
@ -68,56 +65,29 @@ async def create_genshin_map():
|
||||
)
|
||||
if not MAP.exists():
|
||||
MAP.mkdir()
|
||||
map_img.save(MAP / f'{map_id.name}.png')
|
||||
logger.info('****************** 开始地图API服务 *****************')
|
||||
map_img.save(MAP / f"{map_id.name}.png")
|
||||
logger.info("****************** 开始地图API服务 *****************")
|
||||
|
||||
|
||||
@router.get('')
|
||||
async def get_map_by_point(
|
||||
resource_name: str = '甜甜花',
|
||||
map_id: Union[str, int] = 2,
|
||||
is_cluster: bool = False,
|
||||
):
|
||||
req_id = random.randint(10000, 99999)
|
||||
# 判断别名
|
||||
for m in resource_aliases:
|
||||
for a in resource_aliases[m]:
|
||||
for r in resource_aliases[m][a]:
|
||||
if resource_name == r:
|
||||
resource_name = a
|
||||
|
||||
prefix = f'>> [请求序列:{req_id}]'
|
||||
logger.info(f'{prefix} 收到资源点访问请求! [资源名称] {resource_name} [地图ID] {map_id}')
|
||||
ERROR = {
|
||||
'retcode': -1,
|
||||
'message': f'该资源点 - {resource_name} 不存在!',
|
||||
}
|
||||
# 校验map_id有效性
|
||||
if map_id not in MAP_ID_DICT:
|
||||
logger.warning(f'{prefix} 请求失败! 原因: 该地图ID [{map_id}] 不存在!')
|
||||
return {
|
||||
'retcode': -1,
|
||||
'message': f'该地图ID - {map_id} 不存在!',
|
||||
}
|
||||
|
||||
async def get_map_response(
|
||||
prefix: str, resource_name: str, map_id: models.MapID, is_cluster: bool
|
||||
) -> Optional[Path]:
|
||||
# 寻找主地图的缓存
|
||||
map_data = MAP_ID_DICT[map_id]
|
||||
map_path = MAP / f'{map_data.name}.png'
|
||||
map_path = MAP / f"{map_id.name}.png"
|
||||
|
||||
# 寻找保存点
|
||||
if not RESOURCE_PATH.exists():
|
||||
RESOURCE_PATH.mkdir()
|
||||
if is_cluster:
|
||||
save_path = RESOURCE_PATH / f'{map_data.name}_{resource_name}_KMEANS.jpg'
|
||||
save_path = RESOURCE_PATH / f"{map_id.name}_{resource_name}_KMEANS.jpg"
|
||||
else:
|
||||
save_path = RESOURCE_PATH / f'{map_data.name}_{resource_name}.jpg'
|
||||
save_path = RESOURCE_PATH / f"{map_id.name}_{resource_name}.jpg"
|
||||
|
||||
# 如果存在缓存,直接回复
|
||||
if save_path.exists():
|
||||
logger.info(f'{prefix} [成功] [资源名称] {resource_name} 已有缓存, 直接发送!')
|
||||
return FileResponse(save_path)
|
||||
logger.info(f"{prefix} [查询成功]:发送缓存 [{save_path.name}]!")
|
||||
return save_path
|
||||
|
||||
logger.info(f'{prefix} [资源名称] {resource_name} 暂无缓存, 开始执行绘制...')
|
||||
maps = await request.get_maps(map_id)
|
||||
labels = await request.get_labels(map_id)
|
||||
|
||||
@ -131,8 +101,7 @@ async def get_map_by_point(
|
||||
break
|
||||
|
||||
if resource_id == 0:
|
||||
logger.warning(f'{prefix} 请求失败! 原因: 该资源点 [{resource_name}] 不存在!')
|
||||
return ERROR
|
||||
return
|
||||
|
||||
# 请求坐标点
|
||||
points = await request.get_points(map_id)
|
||||
@ -147,7 +116,7 @@ async def get_map_by_point(
|
||||
else:
|
||||
# 如果资源点不存在,返回错误
|
||||
if len(transmittable_converted) == 0:
|
||||
return ERROR
|
||||
return
|
||||
else:
|
||||
# 计算极限坐标
|
||||
up = 20000
|
||||
@ -172,6 +141,7 @@ async def get_map_by_point(
|
||||
]
|
||||
]
|
||||
|
||||
logger.info(f"{prefix} [新增缓存]:开始绘制 {save_path.name}...")
|
||||
# 打开主地图
|
||||
genshin_map = Image.open(map_path)
|
||||
|
||||
@ -202,13 +172,56 @@ async def get_map_by_point(
|
||||
)
|
||||
|
||||
# 转换RGB图
|
||||
genshin_map = genshin_map.convert('RGB')
|
||||
genshin_map = genshin_map.convert("RGB")
|
||||
|
||||
# 转为Bytes,暂时废弃
|
||||
# result_buffer = BytesIO()
|
||||
# genshin_map.save(result_buffer, format='PNG', quality=80, subsampling=0)
|
||||
|
||||
# 进行保存
|
||||
genshin_map.save(save_path, 'JPEG', quality=85)
|
||||
logger.info(f'{prefix} [成功] [资源名称] {resource_name} 绘制完成!')
|
||||
return FileResponse(save_path)
|
||||
genshin_map.save(save_path, "JPEG", quality=85)
|
||||
logger.info(f"{prefix} [查询成功]:新增缓存 [{save_path.name}]!")
|
||||
return save_path
|
||||
|
||||
|
||||
@router.get("")
|
||||
async def get_map_by_point(
|
||||
resource_name: str = "甜甜花",
|
||||
map_id: Union[str, int] = 0,
|
||||
is_cluster: bool = False,
|
||||
):
|
||||
req_id = random.randint(10000, 99999)
|
||||
# 判断别名
|
||||
for m in resource_aliases:
|
||||
for a in resource_aliases[m]:
|
||||
for r in resource_aliases[m][a]:
|
||||
if resource_name == r:
|
||||
resource_name = a
|
||||
|
||||
prefix = f">> [请求序列:{req_id}]"
|
||||
logger.info(f'{prefix} [查询请求]:在地图 ID {map_id or "auto"} 内查询 {resource_name}...')
|
||||
|
||||
if map_id:
|
||||
# 校验 map_id 有效性
|
||||
if map_id not in MAP_ID_DICT:
|
||||
logger.warning(f"{prefix} [失败]:地图 ID - {map_id} 不存在!")
|
||||
return {
|
||||
"retcode": -1,
|
||||
"message": f"地图 ID - {map_id} 不存在!",
|
||||
}
|
||||
maps = [MAP_ID_DICT[str(map_id)]]
|
||||
else:
|
||||
# 自动选择地图
|
||||
maps = list(MAP_ID_DICT.values())
|
||||
|
||||
for idx, map in enumerate(maps):
|
||||
res = await get_map_response(prefix, resource_name, map, is_cluster)
|
||||
if res:
|
||||
return FileResponse(res)
|
||||
if len(maps) > 1:
|
||||
logger.info(f"{prefix} [自动重试]:地图 ID {map._value_} 内不存在 {resource_name}...")
|
||||
logger.warning(f"{prefix} [失败]:资源点 - {resource_name} 不存在!")
|
||||
return {
|
||||
"retcode": -1,
|
||||
"message": f"资源点 - {resource_name} 不存在!",
|
||||
}
|
||||
|
BIN
requirements.txt
Normal file
BIN
requirements.txt
Normal file
Binary file not shown.
Loading…
Reference in New Issue
Block a user