mirror of
https://github.com/zhenxun-org/zhenxun_bot.git
synced 2025-12-15 06:12:53 +08:00
update v0.1.4.5
This commit is contained in:
parent
b5ce4fab31
commit
0f59895c3b
20
README.md
20
README.md
@ -236,6 +236,16 @@ __Docker 最新版本由 [Sakuracio](https://github.com/Sakuracio) 提供__
|
|||||||
|
|
||||||
## 更新
|
## 更新
|
||||||
|
|
||||||
|
### 2022/4/4 \[v0.1.4.5]
|
||||||
|
|
||||||
|
* 替换了bt搜索URL
|
||||||
|
* 优化使用playwright的相关代码
|
||||||
|
* 原神玩家查询新增层岩巨渊探索
|
||||||
|
* 修复原神便笺角色头像黑框
|
||||||
|
* 修复同意群聊请求错误
|
||||||
|
* 提供webui方面的api
|
||||||
|
* 新增web-ui(前端简易管理页面插件)插件
|
||||||
|
|
||||||
### 2022/3/21
|
### 2022/3/21
|
||||||
|
|
||||||
* 修复statistics_handle.py乱码
|
* 修复statistics_handle.py乱码
|
||||||
@ -318,15 +328,15 @@ __Docker 最新版本由 [Sakuracio](https://github.com/Sakuracio) 提供__
|
|||||||
* epic restful 替换 [@pull/119](https://github.com/HibiKier/zhenxun_bot/pull/119)
|
* epic restful 替换 [@pull/119](https://github.com/HibiKier/zhenxun_bot/pull/119)
|
||||||
* fix: 修复远古时期残留的epic推送问题 [@pull/122](https://github.com/HibiKier/zhenxun_bot/pull/122)
|
* fix: 修复远古时期残留的epic推送问题 [@pull/122](https://github.com/HibiKier/zhenxun_bot/pull/122)
|
||||||
|
|
||||||
### 2022/2/11
|
### 2021/2/11
|
||||||
|
|
||||||
* 修复pix不使用反代无法下载图片
|
* 修复pix不使用反代无法下载图片
|
||||||
|
|
||||||
### 2022/2/10 \[v0.1.1]
|
### 2021/2/10 \[v0.1.1]
|
||||||
|
|
||||||
* 修复购买道具出错
|
* 修复购买道具出错
|
||||||
|
|
||||||
### 2022/2/9 \[v0.1]
|
### 2021/2/9 \[v0.1]
|
||||||
|
|
||||||
* 新增原神自动签到和手动签到
|
* 新增原神自动签到和手动签到
|
||||||
* 新增原神树脂提醒
|
* 新增原神树脂提醒
|
||||||
@ -336,7 +346,7 @@ __Docker 最新版本由 [Sakuracio](https://github.com/Sakuracio) 提供__
|
|||||||
* 修复修改商品时限制时间出错
|
* 修复修改商品时限制时间出错
|
||||||
* 修复超时商品依旧可以被购买
|
* 修复超时商品依旧可以被购买
|
||||||
|
|
||||||
### 2022/1/16 \[v0.0.9.0]
|
### 2021/1/16 \[v0.0.9.0]
|
||||||
|
|
||||||
* Ai提供文本敏感词过滤器
|
* Ai提供文本敏感词过滤器
|
||||||
* 疫情插件适配新版腾讯API
|
* 疫情插件适配新版腾讯API
|
||||||
@ -355,7 +365,7 @@ __Docker 最新版本由 [Sakuracio](https://github.com/Sakuracio) 提供__
|
|||||||
* “send_success_msg”(发送成功的交互信息->即:使用道具 {name} {num} 次成功)
|
* “send_success_msg”(发送成功的交互信息->即:使用道具 {name} {num} 次成功)
|
||||||
* “_max_num_limit”(该道具单次使用的最多个数,默认1)
|
* “_max_num_limit”(该道具单次使用的最多个数,默认1)
|
||||||
|
|
||||||
### 2022/1/5 \[v0.0.8.2]
|
### 2021/1/5 \[v0.0.8.2]
|
||||||
|
|
||||||
* 提供金币消费hook,可在plugins2settings.yaml中配置该功能需要消费的金币
|
* 提供金币消费hook,可在plugins2settings.yaml中配置该功能需要消费的金币
|
||||||
* 商店插件将作为内置插件移动至basic_plugins
|
* 商店插件将作为内置插件移动至basic_plugins
|
||||||
|
|||||||
@ -1 +1 @@
|
|||||||
__version__: v0.1.4.4
|
__version__: v0.1.4.5
|
||||||
@ -24,11 +24,17 @@ def switch_rule(event: Event) -> bool:
|
|||||||
_data = plugins2settings_manager.get_data()
|
_data = plugins2settings_manager.get_data()
|
||||||
for key in _data:
|
for key in _data:
|
||||||
try:
|
try:
|
||||||
for x in _data[key]["cmd"]:
|
if isinstance(_data[key]["cmd"], list):
|
||||||
cmd.append(f"开启{x}")
|
for x in _data[key]["cmd"]:
|
||||||
cmd.append(f"关闭{x}")
|
cmd.append(f"开启{x}")
|
||||||
cmd.append(f"开启 {x}")
|
cmd.append(f"关闭{x}")
|
||||||
cmd.append(f"关闭 {x}")
|
cmd.append(f"开启 {x}")
|
||||||
|
cmd.append(f"关闭 {x}")
|
||||||
|
else:
|
||||||
|
cmd.append(f"开启{key}")
|
||||||
|
cmd.append(f"关闭{key}")
|
||||||
|
cmd.append(f"开启 {key}")
|
||||||
|
cmd.append(f"关闭 {key}")
|
||||||
except KeyError:
|
except KeyError:
|
||||||
pass
|
pass
|
||||||
msg = get_message_text(event.json()).split()
|
msg = get_message_text(event.json()).split()
|
||||||
|
|||||||
@ -74,7 +74,7 @@ def init_plugins_settings(data_path: str):
|
|||||||
if plugin_settings.get('cost_gold') is None:
|
if plugin_settings.get('cost_gold') is None:
|
||||||
plugin_settings['cost_gold'] = 0
|
plugin_settings['cost_gold'] = 0
|
||||||
if (
|
if (
|
||||||
plugin_settings["cmd"] is not None
|
plugin_settings.get("cmd") is not None
|
||||||
and plugin_name not in plugin_settings["cmd"]
|
and plugin_name not in plugin_settings["cmd"]
|
||||||
):
|
):
|
||||||
plugin_settings["cmd"].append(plugin_name)
|
plugin_settings["cmd"].append(plugin_name)
|
||||||
|
|||||||
@ -57,7 +57,7 @@ async def get_chat_result(text: str, img_url: str, user_id: int, nickname: str)
|
|||||||
if random.random() < 0.2:
|
if random.random() < 0.2:
|
||||||
if nickname.find("大人") == -1:
|
if nickname.find("大人") == -1:
|
||||||
nickname += "大~人~"
|
nickname += "大~人~"
|
||||||
rst = rst.replace("小主人", nickname).replace("小朋友", nickname)
|
rst = str(rst).replace("小主人", nickname).replace("小朋友", nickname)
|
||||||
ai_message_manager.add_result(user_id, rst)
|
ai_message_manager.add_result(user_id, rst)
|
||||||
return rst
|
return rst
|
||||||
|
|
||||||
|
|||||||
@ -56,15 +56,15 @@ async def _(event: MessageEvent, arg: Message = CommandArg()):
|
|||||||
)
|
)
|
||||||
if is_number(msg) and 0 < int(msg) <= 50:
|
if is_number(msg) and 0 < int(msg) <= 50:
|
||||||
url = wbtop_data[int(msg) - 1]["url"]
|
url = wbtop_data[int(msg) - 1]["url"]
|
||||||
try:
|
await wbtop.send("开始截取数据...")
|
||||||
await wbtop.send("开始截取数据...")
|
img = await AsyncPlaywright.screenshot(
|
||||||
img = await AsyncPlaywright.screenshot(
|
url,
|
||||||
url,
|
f"{IMAGE_PATH}/temp/wbtop_{event.user_id}.png",
|
||||||
f"{IMAGE_PATH}/temp/wbtop_{event.user_id}.png",
|
"#pl_feedlist_index",
|
||||||
"#pl_feedlist_index",
|
wait_time=5
|
||||||
sleep=5
|
)
|
||||||
)
|
if img:
|
||||||
await wbtop.send(img)
|
await wbtop.send(img)
|
||||||
except Exception as e:
|
else:
|
||||||
logger.error(f"微博热搜截图出错... {type(e)}: {e}")
|
|
||||||
await wbtop.send("发生了一些错误.....")
|
await wbtop.send("发生了一些错误.....")
|
||||||
|
|
||||||
|
|||||||
@ -211,7 +211,7 @@ async def _():
|
|||||||
await sub_manager.reload_sub_data()
|
await sub_manager.reload_sub_data()
|
||||||
sub = await sub_manager.random_sub_data()
|
sub = await sub_manager.random_sub_data()
|
||||||
if sub:
|
if sub:
|
||||||
logger.info(f"Bilibili订阅开始检测:{sub.sub_id}")
|
logger.debug(f"Bilibili订阅开始检测:{sub.sub_id}")
|
||||||
rst = await get_sub_status(sub.sub_id, sub.sub_type)
|
rst = await get_sub_status(sub.sub_id, sub.sub_type)
|
||||||
await send_sub_msg(rst, sub, bot)
|
await send_sub_msg(rst, sub, bot)
|
||||||
if sub.sub_type == "live":
|
if sub.sub_type == "live":
|
||||||
|
|||||||
@ -311,28 +311,32 @@ async def get_user_dynamic(
|
|||||||
dynamic_upload_time = dynamic_info["cards"][0]["desc"]["timestamp"]
|
dynamic_upload_time = dynamic_info["cards"][0]["desc"]["timestamp"]
|
||||||
if local_user.dynamic_upload_time < dynamic_upload_time:
|
if local_user.dynamic_upload_time < dynamic_upload_time:
|
||||||
page = await browser.new_page()
|
page = await browser.new_page()
|
||||||
await page.goto(
|
try:
|
||||||
f"https://space.bilibili.com/{local_user.uid}/dynamic",
|
await page.goto(
|
||||||
wait_until="networkidle",
|
f"https://space.bilibili.com/{local_user.uid}/dynamic",
|
||||||
timeout=10000,
|
wait_until="networkidle",
|
||||||
)
|
timeout=10000,
|
||||||
await page.set_viewport_size({"width": 2560, "height": 1080})
|
)
|
||||||
# 删除置顶
|
await page.set_viewport_size({"width": 2560, "height": 1080})
|
||||||
await page.evaluate(
|
# 删除置顶
|
||||||
|
await page.evaluate(
|
||||||
|
"""
|
||||||
|
xs = document.getElementsByClassName('first-card-with-title');
|
||||||
|
for (x of xs) {
|
||||||
|
x.remove();
|
||||||
|
}
|
||||||
"""
|
"""
|
||||||
xs = document.getElementsByClassName('first-card-with-title');
|
)
|
||||||
for (x of xs) {
|
card = await page.query_selector(".card")
|
||||||
x.remove();
|
# 截图并保存
|
||||||
}
|
await card.screenshot(
|
||||||
"""
|
path=dynamic_path / f"{local_user.sub_id}_{dynamic_upload_time}.jpg",
|
||||||
)
|
timeout=100000,
|
||||||
card = await page.query_selector(".card")
|
)
|
||||||
# 截图并保存
|
except Exception as e:
|
||||||
await card.screenshot(
|
logger.error(f"B站订阅:获取用户动态 发送错误 {type(e)}:{e}")
|
||||||
path=dynamic_path / f"{local_user.sub_id}_{dynamic_upload_time}.jpg",
|
finally:
|
||||||
timeout=100000,
|
await page.close()
|
||||||
)
|
|
||||||
await page.close()
|
|
||||||
return (
|
return (
|
||||||
image(
|
image(
|
||||||
f"{local_user.sub_id}_{dynamic_upload_time}.jpg",
|
f"{local_user.sub_id}_{dynamic_upload_time}.jpg",
|
||||||
|
|||||||
@ -9,7 +9,7 @@ if platform.system() == "Windows":
|
|||||||
asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy())
|
asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy())
|
||||||
|
|
||||||
|
|
||||||
url = "http://www.eclzz.world"
|
url = "http://www.eclzz.mobi"
|
||||||
|
|
||||||
|
|
||||||
async def get_bt_info(keyword: str, page: int):
|
async def get_bt_info(keyword: str, page: int):
|
||||||
|
|||||||
@ -200,7 +200,7 @@ def _parse_data_and_draw(
|
|||||||
file_name = x["avatar_side_icon"].split("_")[-1]
|
file_name = x["avatar_side_icon"].split("_")[-1]
|
||||||
role_avatar = memo_path / "role_avatar" / file_name
|
role_avatar = memo_path / "role_avatar" / file_name
|
||||||
_ava_img = BuildImage(75, 75, background=role_avatar)
|
_ava_img = BuildImage(75, 75, background=role_avatar)
|
||||||
_ava_img.circle()
|
# _ava_img.circle()
|
||||||
if x["status"] == "Finished":
|
if x["status"] == "Finished":
|
||||||
msg = "探索完成"
|
msg = "探索完成"
|
||||||
font_color = (146, 188, 63)
|
font_color = (146, 188, 63)
|
||||||
@ -218,10 +218,10 @@ def _parse_data_and_draw(
|
|||||||
a_circle.circle()
|
a_circle.circle()
|
||||||
b_circle = BuildImage(47, 47)
|
b_circle = BuildImage(47, 47)
|
||||||
b_circle.circle()
|
b_circle.circle()
|
||||||
a_circle.paste(b_circle, (4, 4), alpha=True)
|
a_circle.paste(b_circle, (4, 4), True)
|
||||||
_circle_bk.paste(a_circle, (4, 4), alpha=True)
|
_circle_bk.paste(a_circle, (4, 4), True)
|
||||||
|
|
||||||
_bk.paste(_circle_bk, (25, 0), True, center_type="by_height")
|
_bk.paste(_circle_bk, (25, 0), True, "by_height")
|
||||||
_bk.paste(_ava_img, (19, -13), True)
|
_bk.paste(_ava_img, (19, -13), True)
|
||||||
_bk.text((100, 0), msg, font_color, "by_height")
|
_bk.text((100, 0), msg, font_color, "by_height")
|
||||||
_bk.circle_corner(20)
|
_bk.circle_corner(20)
|
||||||
|
|||||||
@ -296,9 +296,11 @@ def get_country_data_image(world_data_dict: Dict) -> BuildImage:
|
|||||||
画出国家探索供奉等图像
|
画出国家探索供奉等图像
|
||||||
:param world_data_dict: 国家数据字典
|
:param world_data_dict: 国家数据字典
|
||||||
"""
|
"""
|
||||||
region = BuildImage(790, 267 * len(world_data_dict), color="#F9F6F2")
|
# 层岩巨渊 和 地下矿区 算一个
|
||||||
|
region = BuildImage(790, 267 * (len(world_data_dict) - 1), color="#F9F6F2")
|
||||||
height = 0
|
height = 0
|
||||||
for country in ["蒙德", "龙脊雪山", "璃月", "稻妻", "渊下宫"]:
|
|
||||||
|
for country in ["蒙德", "龙脊雪山", "璃月", "璃月层岩巨渊", "稻妻", "渊下宫"]:
|
||||||
x = BuildImage(790, 250, color="#3A4467")
|
x = BuildImage(790, 250, color="#3A4467")
|
||||||
logo = BuildImage(180, 180, background=image_path / "logo" / f"{country}.png")
|
logo = BuildImage(180, 180, background=image_path / "logo" / f"{country}.png")
|
||||||
tmp_bk = BuildImage(770, 230, color="#606779")
|
tmp_bk = BuildImage(770, 230, color="#606779")
|
||||||
@ -320,6 +322,25 @@ def get_country_data_image(world_data_dict: Dict) -> BuildImage:
|
|||||||
f"Lv.{world_data_dict[country]['level']}",
|
f"Lv.{world_data_dict[country]['level']}",
|
||||||
fill=(255, 255, 255),
|
fill=(255, 255, 255),
|
||||||
)
|
)
|
||||||
|
elif country in ["璃月层岩巨渊"]:
|
||||||
|
content_bk.text((300, 20), "层岩巨渊探索", fill=(239, 211, 114))
|
||||||
|
content_bk.text(
|
||||||
|
(570, 20),
|
||||||
|
f"{world_data_dict['璃月层岩巨渊']['exploration_percentage'] / 10}%",
|
||||||
|
fill=(255, 255, 255),
|
||||||
|
)
|
||||||
|
content_bk.text((300, 85), "地下矿区探索", fill=(239, 211, 114))
|
||||||
|
content_bk.text(
|
||||||
|
(570, 85),
|
||||||
|
f"{world_data_dict['璃月层岩巨渊·地下矿区']['exploration_percentage'] / 10}%",
|
||||||
|
fill=(255, 255, 255),
|
||||||
|
)
|
||||||
|
content_bk.text((300, 150), "流明石触媒", fill=(239, 211, 114))
|
||||||
|
content_bk.text(
|
||||||
|
(570, 150),
|
||||||
|
f"LV.{world_data_dict['璃月层岩巨渊·地下矿区']['offerings'][0]['level']}",
|
||||||
|
fill=(255, 255, 255),
|
||||||
|
)
|
||||||
elif country in ["龙脊雪山"]:
|
elif country in ["龙脊雪山"]:
|
||||||
content_bk.text((300, 40), "探索", fill=(239, 211, 114))
|
content_bk.text((300, 40), "探索", fill=(239, 211, 114))
|
||||||
content_bk.text(
|
content_bk.text(
|
||||||
|
|||||||
@ -276,4 +276,4 @@ def update_data(data: dict):
|
|||||||
tmp_dict[plugin_name] = 1
|
tmp_dict[plugin_name] = 1
|
||||||
else:
|
else:
|
||||||
tmp_dict[plugin_name] += data[day][plugin_name]
|
tmp_dict[plugin_name] += data[day][plugin_name]
|
||||||
return tmp_dict
|
return tmp_dict
|
||||||
20
plugins/web_ui/__init__.py
Normal file
20
plugins/web_ui/__init__.py
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
from configs.config import Config as gConfig
|
||||||
|
from .manager import *
|
||||||
|
from .auth import *
|
||||||
|
|
||||||
|
|
||||||
|
gConfig.add_plugin_config(
|
||||||
|
"web-ui",
|
||||||
|
"username",
|
||||||
|
"admin",
|
||||||
|
name="web-ui",
|
||||||
|
help_="前端管理用户名"
|
||||||
|
)
|
||||||
|
|
||||||
|
gConfig.add_plugin_config(
|
||||||
|
"web-ui",
|
||||||
|
"password",
|
||||||
|
None,
|
||||||
|
name="web-ui",
|
||||||
|
help_="前端管理密码"
|
||||||
|
)
|
||||||
89
plugins/web_ui/auth/__init__.py
Normal file
89
plugins/web_ui/auth/__init__.py
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
from datetime import datetime, timedelta
|
||||||
|
from typing import Optional
|
||||||
|
from starlette import status
|
||||||
|
from fastapi import Depends, HTTPException
|
||||||
|
from fastapi.security import OAuth2PasswordBearer, OAuth2PasswordRequestForm
|
||||||
|
from pydantic import BaseModel
|
||||||
|
from configs.config import Config
|
||||||
|
from jose import JWTError, jwt
|
||||||
|
import nonebot
|
||||||
|
|
||||||
|
app = nonebot.get_app()
|
||||||
|
|
||||||
|
|
||||||
|
SECRET_KEY = "09d25e094faa6ca2556c818166b7a9563b93f7099f6f0f4caa6cf63b88e8d3e7"
|
||||||
|
ALGORITHM = "HS256"
|
||||||
|
ACCESS_TOKEN_EXPIRE_MINUTES = 30
|
||||||
|
|
||||||
|
oauth2_scheme = OAuth2PasswordBearer(tokenUrl="webui/login")
|
||||||
|
|
||||||
|
|
||||||
|
class User(BaseModel):
|
||||||
|
username: str
|
||||||
|
password: str
|
||||||
|
|
||||||
|
|
||||||
|
class Token(BaseModel):
|
||||||
|
access_token: str
|
||||||
|
token_type: str
|
||||||
|
|
||||||
|
|
||||||
|
# USER_LIST = [
|
||||||
|
# User(username="admin", password="123")
|
||||||
|
# ]
|
||||||
|
|
||||||
|
|
||||||
|
def get_user(uname: str) -> Optional[User]:
|
||||||
|
username = Config.get_config("web-ui", "username")
|
||||||
|
password = Config.get_config("web-ui", "password")
|
||||||
|
if username and password and uname == username:
|
||||||
|
return User(username=username, password=password)
|
||||||
|
|
||||||
|
|
||||||
|
form_exception = HTTPException(
|
||||||
|
status_code=status.HTTP_401_UNAUTHORIZED,
|
||||||
|
detail="Could not validate credentials",
|
||||||
|
headers={"WWW-Authenticate": "Bearer"},
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def create_token(user: User, expires_delta: Optional[timedelta] = None):
|
||||||
|
expire = datetime.utcnow() + expires_delta or timedelta(minutes=15)
|
||||||
|
return jwt.encode(
|
||||||
|
claims={"sub": user.username, "exp": expire},
|
||||||
|
key=SECRET_KEY,
|
||||||
|
algorithm=ALGORITHM
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@app.post("/webui/login")
|
||||||
|
async def login_get_token(form_data: OAuth2PasswordRequestForm = Depends()):
|
||||||
|
user: User = get_user(form_data.username)
|
||||||
|
if not user or user.password != form_data.password:
|
||||||
|
raise form_exception
|
||||||
|
access_token = create_token(user=user, expires_delta=timedelta(minutes=ACCESS_TOKEN_EXPIRE_MINUTES))
|
||||||
|
return {"access_token": access_token, "token_type": "bearer"}
|
||||||
|
|
||||||
|
|
||||||
|
credentials_exception = HTTPException(
|
||||||
|
status_code=status.HTTP_401_UNAUTHORIZED,
|
||||||
|
detail="Could not validate credentials",
|
||||||
|
headers={"WWW-Authenticate": "Bearer"},
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def token_to_user(token: str = Depends(oauth2_scheme)):
|
||||||
|
try:
|
||||||
|
payload = jwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM])
|
||||||
|
username, expire = payload.get("sub"), payload.get("exp")
|
||||||
|
user = get_user(username)
|
||||||
|
if user is None:
|
||||||
|
raise JWTError
|
||||||
|
except JWTError:
|
||||||
|
raise credentials_exception
|
||||||
|
return user
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
import uvicorn
|
||||||
|
uvicorn.run(app, host="127.0.0.1", port=8080)
|
||||||
112
plugins/web_ui/config.py
Normal file
112
plugins/web_ui/config.py
Normal file
@ -0,0 +1,112 @@
|
|||||||
|
from typing import Optional, List, Any
|
||||||
|
from pydantic import BaseModel
|
||||||
|
from fastapi.middleware.cors import CORSMiddleware
|
||||||
|
import nonebot
|
||||||
|
|
||||||
|
|
||||||
|
app = nonebot.get_app()
|
||||||
|
|
||||||
|
origins = ["http://localhost"]
|
||||||
|
|
||||||
|
app.add_middleware(
|
||||||
|
CORSMiddleware,
|
||||||
|
allow_origins=origins,
|
||||||
|
allow_credentials=True,
|
||||||
|
allow_methods=["*"],
|
||||||
|
allow_headers=["*"],
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class CdLimit(BaseModel):
|
||||||
|
cd: int
|
||||||
|
status: bool
|
||||||
|
check_type: str
|
||||||
|
limit_type: str
|
||||||
|
rst: Optional[str]
|
||||||
|
|
||||||
|
|
||||||
|
class BlockLimit(BaseModel):
|
||||||
|
status: bool
|
||||||
|
check_type: str
|
||||||
|
limit_type: str
|
||||||
|
rst: Optional[str]
|
||||||
|
|
||||||
|
|
||||||
|
class CountLimit(BaseModel):
|
||||||
|
max_count: int
|
||||||
|
status: bool
|
||||||
|
limit_type: bool
|
||||||
|
rst: Optional[str]
|
||||||
|
|
||||||
|
|
||||||
|
class PluginManager(BaseModel):
|
||||||
|
plugin_name: str # 插件名称
|
||||||
|
status: Optional[bool] # 插件状态
|
||||||
|
error: Optional[bool] # 加载状态
|
||||||
|
version: Optional[float] # 版本
|
||||||
|
author: Optional[str] # 作者
|
||||||
|
block_type: Optional[str] # 禁用类型
|
||||||
|
|
||||||
|
|
||||||
|
class PluginSettings(BaseModel):
|
||||||
|
level: Optional[int] # 群权限等级
|
||||||
|
default_status: Optional[bool] # 默认开关
|
||||||
|
limit_superuser: Optional[bool] # 是否限制超级用户
|
||||||
|
cmd: Optional[str] # cmd别名
|
||||||
|
cost_gold: Optional[int] # 花费金币限制
|
||||||
|
plugin_type: Optional[str] # 帮助类型
|
||||||
|
|
||||||
|
|
||||||
|
class Plugin(BaseModel):
|
||||||
|
model: str # 模块
|
||||||
|
plugin_settings: Optional[PluginSettings]
|
||||||
|
plugin_manager: Optional[PluginManager]
|
||||||
|
cd_limit: Optional[CdLimit]
|
||||||
|
block_limit: Optional[BlockLimit]
|
||||||
|
count_limit: Optional[CountLimit]
|
||||||
|
|
||||||
|
|
||||||
|
class Group(BaseModel):
|
||||||
|
group_id: int
|
||||||
|
group_name: str
|
||||||
|
member_count: int
|
||||||
|
max_member_count: int
|
||||||
|
|
||||||
|
|
||||||
|
class Task(BaseModel):
|
||||||
|
name: str
|
||||||
|
nameZh: str
|
||||||
|
status: bool
|
||||||
|
|
||||||
|
|
||||||
|
class GroupResult(BaseModel):
|
||||||
|
group: Group
|
||||||
|
level: int
|
||||||
|
status: bool
|
||||||
|
close_plugins: List[str]
|
||||||
|
task: List[Task]
|
||||||
|
|
||||||
|
|
||||||
|
class RequestResult(BaseModel):
|
||||||
|
oid: str
|
||||||
|
id: int
|
||||||
|
flag: str
|
||||||
|
nickname: Optional[str]
|
||||||
|
level: Optional[int]
|
||||||
|
sex: Optional[str]
|
||||||
|
age: Optional[int]
|
||||||
|
from_: Optional[str]
|
||||||
|
comment: Optional[str]
|
||||||
|
invite_group: Optional[int]
|
||||||
|
group_name: Optional[str]
|
||||||
|
|
||||||
|
|
||||||
|
class RequestParma(BaseModel):
|
||||||
|
id: int
|
||||||
|
handle: str
|
||||||
|
type: str
|
||||||
|
|
||||||
|
|
||||||
|
class Result(BaseModel):
|
||||||
|
code: int
|
||||||
|
data: Any
|
||||||
209
plugins/web_ui/manager/__init__.py
Normal file
209
plugins/web_ui/manager/__init__.py
Normal file
@ -0,0 +1,209 @@
|
|||||||
|
from utils.manager import (
|
||||||
|
plugins_manager,
|
||||||
|
group_manager,
|
||||||
|
plugins2settings_manager,
|
||||||
|
plugins2cd_manager,
|
||||||
|
plugins2block_manager,
|
||||||
|
plugins2count_manager,
|
||||||
|
requests_manager,
|
||||||
|
)
|
||||||
|
from ..auth import token_to_user, Depends, User
|
||||||
|
from utils.utils import get_matchers, get_bot
|
||||||
|
from models.group_info import GroupInfo
|
||||||
|
from pydantic.error_wrappers import ValidationError
|
||||||
|
from services.log import logger
|
||||||
|
from ..config import *
|
||||||
|
import nonebot
|
||||||
|
|
||||||
|
app = nonebot.get_app()
|
||||||
|
|
||||||
|
|
||||||
|
plugin_name_list = None
|
||||||
|
|
||||||
|
|
||||||
|
@app.get("/webui/plugins")
|
||||||
|
def _(type_: Optional[str], user: User = Depends(token_to_user)) -> Result:
|
||||||
|
"""
|
||||||
|
获取插件列表
|
||||||
|
:param type_: 类型 normal, superuser, hidden, admin
|
||||||
|
"""
|
||||||
|
global plugin_name_list
|
||||||
|
if not plugin_name_list:
|
||||||
|
plugin_name_list = [x.plugin_name for x in get_matchers()]
|
||||||
|
plugin_list = []
|
||||||
|
plugin_data = plugins_manager.get_data()
|
||||||
|
for model in plugin_data:
|
||||||
|
if model in plugin_name_list:
|
||||||
|
data = plugin_data.get(model)
|
||||||
|
data["model"] = model
|
||||||
|
plugin_name = data.get("plugin_name")
|
||||||
|
if (
|
||||||
|
(type_ == "hidden" and "[hidden]" not in plugin_name.lower())
|
||||||
|
or (type_ == "admin" and "[admin]" not in plugin_name.lower())
|
||||||
|
or (type_ == "superuser" and "[superuser]" not in plugin_name.lower())
|
||||||
|
):
|
||||||
|
continue
|
||||||
|
if type_ == "normal" and (
|
||||||
|
"[hidden]" in plugin_name.lower()
|
||||||
|
or "[admin]" in plugin_name.lower()
|
||||||
|
or "[superuser]" in plugin_name.lower()
|
||||||
|
):
|
||||||
|
continue
|
||||||
|
data = {"model": model}
|
||||||
|
if x := plugin_data.get(model):
|
||||||
|
if not x.get("status") and x.get("block_type") in [
|
||||||
|
"group",
|
||||||
|
"private",
|
||||||
|
"all",
|
||||||
|
]:
|
||||||
|
x["block_type"] = (
|
||||||
|
"群聊"
|
||||||
|
if x["block_type"] == "group"
|
||||||
|
else "私聊"
|
||||||
|
if x["block_type"] == "private"
|
||||||
|
else "全部"
|
||||||
|
)
|
||||||
|
data["plugin_manager"] = PluginManager(**x)
|
||||||
|
if x := plugins2settings_manager.get(model):
|
||||||
|
if x.get("cmd") and isinstance(x.get("cmd"), list):
|
||||||
|
x["cmd"] = ",".join(x["cmd"])
|
||||||
|
if isinstance(x["plugin_type"], list):
|
||||||
|
x["plugin_type"] = x["plugin_type"][0]
|
||||||
|
data["plugin_settings"] = PluginSettings(**x)
|
||||||
|
if x := plugins2cd_manager.get(model):
|
||||||
|
data["cd_limit"] = CdLimit(**x)
|
||||||
|
if x := plugins2block_manager.get(model):
|
||||||
|
data["block_limit"] = BlockLimit(**x)
|
||||||
|
if x := plugins2count_manager.get(model):
|
||||||
|
data["count_limit"] = CountLimit(**x)
|
||||||
|
# if x := resources_manager.get(model):
|
||||||
|
# data = dict(data, **x)
|
||||||
|
plugin_list.append(Plugin(**data))
|
||||||
|
return Result(code=200, data=plugin_list)
|
||||||
|
|
||||||
|
|
||||||
|
@app.post("/webui/plugins")
|
||||||
|
def _(plugin: Plugin, user: User = Depends(token_to_user)) -> Result:
|
||||||
|
"""
|
||||||
|
修改插件信息
|
||||||
|
:param plugin: 插件内容
|
||||||
|
"""
|
||||||
|
|
||||||
|
print(plugin)
|
||||||
|
if plugin.plugin_settings:
|
||||||
|
for key, value in plugin.plugin_settings:
|
||||||
|
plugins2settings_manager.set_module_data(plugin.model, key, value)
|
||||||
|
if plugin.plugin_manager:
|
||||||
|
for key, value in plugin.plugin_manager:
|
||||||
|
print(key, value)
|
||||||
|
plugins_manager.set_module_data(plugin.model, key, value)
|
||||||
|
return Result(code=200)
|
||||||
|
|
||||||
|
|
||||||
|
@app.get("/webui/group")
|
||||||
|
async def _(user: User = Depends(token_to_user)) -> Result:
|
||||||
|
"""
|
||||||
|
获取群信息
|
||||||
|
"""
|
||||||
|
group_list_result = []
|
||||||
|
group_info = {}
|
||||||
|
if bot := get_bot():
|
||||||
|
group_list = await bot.get_group_list()
|
||||||
|
for g in group_list:
|
||||||
|
group_info[g["group_id"]] = Group(**g)
|
||||||
|
group_data = group_manager.get_data()
|
||||||
|
for group_id in group_data["group_manager"]:
|
||||||
|
try:
|
||||||
|
task_list = []
|
||||||
|
data = group_data["group_manager"][group_id]
|
||||||
|
for tn, status in data["group_task_status"].items():
|
||||||
|
task_list.append(
|
||||||
|
Task(
|
||||||
|
**{
|
||||||
|
"name": tn,
|
||||||
|
"nameZh": group_manager.get_task_data().get(tn) or tn,
|
||||||
|
"status": status,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
|
data["task"] = task_list
|
||||||
|
if x := group_info.get(int(group_id)):
|
||||||
|
data["group"] = x
|
||||||
|
else:
|
||||||
|
continue
|
||||||
|
try:
|
||||||
|
group_list_result.append(GroupResult(**data))
|
||||||
|
except ValidationError:
|
||||||
|
pass
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(f"WEB_UI /webui/group 发生错误 {type(e)}:{e}")
|
||||||
|
return Result(code=200, data=group_list_result)
|
||||||
|
|
||||||
|
|
||||||
|
@app.post("/webui/group")
|
||||||
|
async def _(group: GroupResult, user: User = Depends(token_to_user)) -> Result:
|
||||||
|
"""
|
||||||
|
修改群信息
|
||||||
|
"""
|
||||||
|
group_id = group.group.group_id
|
||||||
|
group_manager.set_group_level(group_id, group.level)
|
||||||
|
if group.status:
|
||||||
|
group_manager.turn_on_group_bot_status(group_id)
|
||||||
|
else:
|
||||||
|
group_manager.shutdown_group_bot_status(group_id)
|
||||||
|
return Result(code=200)
|
||||||
|
|
||||||
|
|
||||||
|
@app.get("/webui/request")
|
||||||
|
def _(type_: Optional[str], user: User = Depends(token_to_user)) -> Result:
|
||||||
|
req_data = requests_manager.get_data()
|
||||||
|
req_list = []
|
||||||
|
if type_ in ["group", "private"]:
|
||||||
|
req_data = req_data[type_]
|
||||||
|
for x in req_data:
|
||||||
|
req_data[x]["oid"] = x
|
||||||
|
req_list.append(RequestResult(**req_data[x]))
|
||||||
|
return Result(code=200, data=req_list)
|
||||||
|
|
||||||
|
|
||||||
|
@app.delete("/webui/request")
|
||||||
|
def _(type_: Optional[str], user: User = Depends(token_to_user)) -> Result:
|
||||||
|
"""
|
||||||
|
清空请求
|
||||||
|
:param type_: 类型
|
||||||
|
"""
|
||||||
|
requests_manager.clear(type_)
|
||||||
|
return Result(code=200)
|
||||||
|
|
||||||
|
|
||||||
|
@app.post("/webui/request")
|
||||||
|
async def _(parma: RequestParma, user: User = Depends(token_to_user)) -> Result:
|
||||||
|
"""
|
||||||
|
操作请求
|
||||||
|
:param parma: 参数
|
||||||
|
"""
|
||||||
|
result = "error"
|
||||||
|
if bot := get_bot():
|
||||||
|
if parma.handle == "approve":
|
||||||
|
if parma.type == "group":
|
||||||
|
rid = requests_manager.get_group_id(parma.id)
|
||||||
|
if await GroupInfo.get_group_info(rid):
|
||||||
|
await GroupInfo.set_group_flag(rid, 1)
|
||||||
|
else:
|
||||||
|
group_info = await bot.get_group_info(group_id=rid)
|
||||||
|
await GroupInfo.add_group_info(
|
||||||
|
rid,
|
||||||
|
group_info["group_name"],
|
||||||
|
group_info["max_member_count"],
|
||||||
|
group_info["member_count"],
|
||||||
|
1,
|
||||||
|
)
|
||||||
|
if await requests_manager.approve(bot, parma.id, parma.type):
|
||||||
|
result = "ok"
|
||||||
|
elif parma.handle == "refuse":
|
||||||
|
if await requests_manager.refused(bot, parma.id, parma.type):
|
||||||
|
result = "ok"
|
||||||
|
elif parma.handle == "delete":
|
||||||
|
requests_manager.delete_request(parma.id, parma.type)
|
||||||
|
result = "ok"
|
||||||
|
return Result(code=200, data=result)
|
||||||
174
poetry.lock
generated
174
poetry.lock
generated
@ -377,6 +377,26 @@ type = "legacy"
|
|||||||
url = "https://pypi.tuna.tsinghua.edu.cn/simple"
|
url = "https://pypi.tuna.tsinghua.edu.cn/simple"
|
||||||
reference = "tsinghua"
|
reference = "tsinghua"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ecdsa"
|
||||||
|
version = "0.17.0"
|
||||||
|
description = "ECDSA cryptographic signature library (pure python)"
|
||||||
|
category = "main"
|
||||||
|
optional = false
|
||||||
|
python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*"
|
||||||
|
|
||||||
|
[package.dependencies]
|
||||||
|
six = ">=1.9.0"
|
||||||
|
|
||||||
|
[package.extras]
|
||||||
|
gmpy = ["gmpy"]
|
||||||
|
gmpy2 = ["gmpy2"]
|
||||||
|
|
||||||
|
[package.source]
|
||||||
|
type = "legacy"
|
||||||
|
url = "https://pypi.tuna.tsinghua.edu.cn/simple"
|
||||||
|
reference = "tsinghua"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "fastapi"
|
name = "fastapi"
|
||||||
version = "0.73.0"
|
version = "0.73.0"
|
||||||
@ -520,14 +540,14 @@ reference = "tsinghua"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "httptools"
|
name = "httptools"
|
||||||
version = "0.2.0"
|
version = "0.4.0"
|
||||||
description = "A collection of framework independent HTTP protocol utils."
|
description = "A collection of framework independent HTTP protocol utils."
|
||||||
category = "main"
|
category = "main"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = "*"
|
python-versions = ">=3.5.0"
|
||||||
|
|
||||||
[package.extras]
|
[package.extras]
|
||||||
test = ["Cython (==0.29.22)"]
|
test = ["Cython (>=0.29.24,<0.30.0)"]
|
||||||
|
|
||||||
[package.source]
|
[package.source]
|
||||||
type = "legacy"
|
type = "legacy"
|
||||||
@ -915,6 +935,19 @@ type = "legacy"
|
|||||||
url = "https://pypi.tuna.tsinghua.edu.cn/simple"
|
url = "https://pypi.tuna.tsinghua.edu.cn/simple"
|
||||||
reference = "tsinghua"
|
reference = "tsinghua"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "pyasn1"
|
||||||
|
version = "0.4.8"
|
||||||
|
description = "ASN.1 types and codecs"
|
||||||
|
category = "main"
|
||||||
|
optional = false
|
||||||
|
python-versions = "*"
|
||||||
|
|
||||||
|
[package.source]
|
||||||
|
type = "legacy"
|
||||||
|
url = "https://pypi.tuna.tsinghua.edu.cn/simple"
|
||||||
|
reference = "tsinghua"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pydantic"
|
name = "pydantic"
|
||||||
version = "1.9.0"
|
version = "1.9.0"
|
||||||
@ -1023,6 +1056,45 @@ type = "legacy"
|
|||||||
url = "https://pypi.tuna.tsinghua.edu.cn/simple"
|
url = "https://pypi.tuna.tsinghua.edu.cn/simple"
|
||||||
reference = "tsinghua"
|
reference = "tsinghua"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "python-jose"
|
||||||
|
version = "3.3.0"
|
||||||
|
description = "JOSE implementation in Python"
|
||||||
|
category = "main"
|
||||||
|
optional = false
|
||||||
|
python-versions = "*"
|
||||||
|
|
||||||
|
[package.dependencies]
|
||||||
|
ecdsa = "!=0.15"
|
||||||
|
pyasn1 = "*"
|
||||||
|
rsa = "*"
|
||||||
|
|
||||||
|
[package.extras]
|
||||||
|
cryptography = ["cryptography (>=3.4.0)"]
|
||||||
|
pycrypto = ["pycrypto (>=2.6.0,<2.7.0)", "pyasn1"]
|
||||||
|
pycryptodome = ["pycryptodome (>=3.3.1,<4.0.0)", "pyasn1"]
|
||||||
|
|
||||||
|
[package.source]
|
||||||
|
type = "legacy"
|
||||||
|
url = "https://pypi.tuna.tsinghua.edu.cn/simple"
|
||||||
|
reference = "tsinghua"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "python-multipart"
|
||||||
|
version = "0.0.5"
|
||||||
|
description = "A streaming multipart parser for Python"
|
||||||
|
category = "main"
|
||||||
|
optional = false
|
||||||
|
python-versions = "*"
|
||||||
|
|
||||||
|
[package.dependencies]
|
||||||
|
six = ">=1.4.0"
|
||||||
|
|
||||||
|
[package.source]
|
||||||
|
type = "legacy"
|
||||||
|
url = "https://pypi.tuna.tsinghua.edu.cn/simple"
|
||||||
|
reference = "tsinghua"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pytz"
|
name = "pytz"
|
||||||
version = "2021.3"
|
version = "2021.3"
|
||||||
@ -1130,6 +1202,22 @@ type = "legacy"
|
|||||||
url = "https://pypi.tuna.tsinghua.edu.cn/simple"
|
url = "https://pypi.tuna.tsinghua.edu.cn/simple"
|
||||||
reference = "tsinghua"
|
reference = "tsinghua"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rsa"
|
||||||
|
version = "4.8"
|
||||||
|
description = "Pure-Python RSA implementation"
|
||||||
|
category = "main"
|
||||||
|
optional = false
|
||||||
|
python-versions = ">=3.6,<4"
|
||||||
|
|
||||||
|
[package.dependencies]
|
||||||
|
pyasn1 = ">=0.1.3"
|
||||||
|
|
||||||
|
[package.source]
|
||||||
|
type = "legacy"
|
||||||
|
url = "https://pypi.tuna.tsinghua.edu.cn/simple"
|
||||||
|
reference = "tsinghua"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ruamel.yaml"
|
name = "ruamel.yaml"
|
||||||
version = "0.17.21"
|
version = "0.17.21"
|
||||||
@ -1403,7 +1491,7 @@ reference = "tsinghua"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "uvicorn"
|
name = "uvicorn"
|
||||||
version = "0.17.5"
|
version = "0.17.6"
|
||||||
description = "The lightning-fast ASGI server."
|
description = "The lightning-fast ASGI server."
|
||||||
category = "main"
|
category = "main"
|
||||||
optional = false
|
optional = false
|
||||||
@ -1414,7 +1502,7 @@ asgiref = ">=3.4.0"
|
|||||||
click = ">=7.0"
|
click = ">=7.0"
|
||||||
colorama = {version = ">=0.4", optional = true, markers = "sys_platform == \"win32\" and extra == \"standard\""}
|
colorama = {version = ">=0.4", optional = true, markers = "sys_platform == \"win32\" and extra == \"standard\""}
|
||||||
h11 = ">=0.8"
|
h11 = ">=0.8"
|
||||||
httptools = {version = ">=0.2.0,<0.4.0", optional = true, markers = "extra == \"standard\""}
|
httptools = {version = ">=0.4.0", optional = true, markers = "extra == \"standard\""}
|
||||||
python-dotenv = {version = ">=0.13", optional = true, markers = "extra == \"standard\""}
|
python-dotenv = {version = ">=0.13", optional = true, markers = "extra == \"standard\""}
|
||||||
PyYAML = {version = ">=5.1", optional = true, markers = "extra == \"standard\""}
|
PyYAML = {version = ">=5.1", optional = true, markers = "extra == \"standard\""}
|
||||||
uvloop = {version = ">=0.14.0,<0.15.0 || >0.15.0,<0.15.1 || >0.15.1", optional = true, markers = "sys_platform != \"win32\" and sys_platform != \"cygwin\" and platform_python_implementation != \"PyPy\" and extra == \"standard\""}
|
uvloop = {version = ">=0.14.0,<0.15.0 || >0.15.0,<0.15.1 || >0.15.1", optional = true, markers = "sys_platform != \"win32\" and sys_platform != \"cygwin\" and platform_python_implementation != \"PyPy\" and extra == \"standard\""}
|
||||||
@ -1422,7 +1510,7 @@ watchgod = {version = ">=0.6", optional = true, markers = "extra == \"standard\"
|
|||||||
websockets = {version = ">=10.0", optional = true, markers = "extra == \"standard\""}
|
websockets = {version = ">=10.0", optional = true, markers = "extra == \"standard\""}
|
||||||
|
|
||||||
[package.extras]
|
[package.extras]
|
||||||
standard = ["websockets (>=10.0)", "httptools (>=0.2.0,<0.4.0)", "watchgod (>=0.6)", "python-dotenv (>=0.13)", "PyYAML (>=5.1)", "uvloop (>=0.14.0,!=0.15.0,!=0.15.1)", "colorama (>=0.4)"]
|
standard = ["websockets (>=10.0)", "httptools (>=0.4.0)", "watchgod (>=0.6)", "python-dotenv (>=0.13)", "PyYAML (>=5.1)", "uvloop (>=0.14.0,!=0.15.0,!=0.15.1)", "colorama (>=0.4)"]
|
||||||
|
|
||||||
[package.source]
|
[package.source]
|
||||||
type = "legacy"
|
type = "legacy"
|
||||||
@ -1522,7 +1610,7 @@ reference = "tsinghua"
|
|||||||
[metadata]
|
[metadata]
|
||||||
lock-version = "1.1"
|
lock-version = "1.1"
|
||||||
python-versions = "^3.8"
|
python-versions = "^3.8"
|
||||||
content-hash = "2521c3cd7346f1f1b3b22276fa71ca9680447f85fc13fd23ede0e33d6f942423"
|
content-hash = "a467c2f5d871d65cd76363a2839023a38bde9b4aacd37f3019dca6fe0f199723"
|
||||||
|
|
||||||
[metadata.files]
|
[metadata.files]
|
||||||
aiofiles = [
|
aiofiles = [
|
||||||
@ -1764,6 +1852,10 @@ dateparser = [
|
|||||||
{file = "dateparser-1.1.0-py2.py3-none-any.whl", hash = "sha256:fec344db1f73d005182e214c0ff27313c748bbe0c1638ce9d48a809ddfdab2a0"},
|
{file = "dateparser-1.1.0-py2.py3-none-any.whl", hash = "sha256:fec344db1f73d005182e214c0ff27313c748bbe0c1638ce9d48a809ddfdab2a0"},
|
||||||
{file = "dateparser-1.1.0.tar.gz", hash = "sha256:faa2b97f51f3b5ff1ba2f17be90de2b733fb6191f89b4058787473e8202f3044"},
|
{file = "dateparser-1.1.0.tar.gz", hash = "sha256:faa2b97f51f3b5ff1ba2f17be90de2b733fb6191f89b4058787473e8202f3044"},
|
||||||
]
|
]
|
||||||
|
ecdsa = [
|
||||||
|
{file = "ecdsa-0.17.0-py2.py3-none-any.whl", hash = "sha256:5cf31d5b33743abe0dfc28999036c849a69d548f994b535e527ee3cb7f3ef676"},
|
||||||
|
{file = "ecdsa-0.17.0.tar.gz", hash = "sha256:b9f500bb439e4153d0330610f5d26baaf18d17b8ced1bc54410d189385ea68aa"},
|
||||||
|
]
|
||||||
fastapi = [
|
fastapi = [
|
||||||
{file = "fastapi-0.73.0-py3-none-any.whl", hash = "sha256:f0a618aff5f6942862f2d3f20f39b1c037e33314d1b8207fd1c3a2cca76dfd8c"},
|
{file = "fastapi-0.73.0-py3-none-any.whl", hash = "sha256:f0a618aff5f6942862f2d3f20f39b1c037e33314d1b8207fd1c3a2cca76dfd8c"},
|
||||||
{file = "fastapi-0.73.0.tar.gz", hash = "sha256:dcfee92a7f9a72b5d4b7ca364bd2b009f8fc10d95ed5769be20e94f39f7e5a15"},
|
{file = "fastapi-0.73.0.tar.gz", hash = "sha256:dcfee92a7f9a72b5d4b7ca364bd2b009f8fc10d95ed5769be20e94f39f7e5a15"},
|
||||||
@ -1846,21 +1938,40 @@ httpcore = [
|
|||||||
{file = "httpcore-0.14.7.tar.gz", hash = "sha256:7503ec1c0f559066e7e39bc4003fd2ce023d01cf51793e3c173b864eb456ead1"},
|
{file = "httpcore-0.14.7.tar.gz", hash = "sha256:7503ec1c0f559066e7e39bc4003fd2ce023d01cf51793e3c173b864eb456ead1"},
|
||||||
]
|
]
|
||||||
httptools = [
|
httptools = [
|
||||||
{file = "httptools-0.2.0-cp35-cp35m-macosx_10_14_x86_64.whl", hash = "sha256:79dbc21f3612a78b28384e989b21872e2e3cf3968532601544696e4ed0007ce5"},
|
{file = "httptools-0.4.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:fcddfe70553be717d9745990dfdb194e22ee0f60eb8f48c0794e7bfeda30d2d5"},
|
||||||
{file = "httptools-0.2.0-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:78d03dd39b09c99ec917d50189e6743adbfd18c15d5944392d2eabda688bf149"},
|
{file = "httptools-0.4.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:1ee0b459257e222b878a6c09ccf233957d3a4dcb883b0847640af98d2d9aac23"},
|
||||||
{file = "httptools-0.2.0-cp36-cp36m-macosx_10_14_x86_64.whl", hash = "sha256:a23166e5ae2775709cf4f7ad4c2048755ebfb272767d244e1a96d55ac775cca7"},
|
{file = "httptools-0.4.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ceafd5e960b39c7e0d160a1936b68eb87c5e79b3979d66e774f0c77d4d8faaed"},
|
||||||
{file = "httptools-0.2.0-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:3ab1f390d8867f74b3b5ee2a7ecc9b8d7f53750bd45714bf1cb72a953d7dfa77"},
|
{file = "httptools-0.4.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:fdb9f9ed79bc6f46b021b3319184699ba1a22410a82204e6e89c774530069683"},
|
||||||
{file = "httptools-0.2.0-cp36-cp36m-win_amd64.whl", hash = "sha256:a7594f9a010cdf1e16a58b3bf26c9da39bbf663e3b8d46d39176999d71816658"},
|
{file = "httptools-0.4.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:abe829275cdd4174b4c4e65ad718715d449e308d59793bf3a931ee1bf7e7b86c"},
|
||||||
{file = "httptools-0.2.0-cp37-cp37m-macosx_10_14_x86_64.whl", hash = "sha256:01b392a166adcc8bc2f526a939a8aabf89fe079243e1543fd0e7dc1b58d737cb"},
|
{file = "httptools-0.4.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:7af6bdbd21a2a25d6784f6d67f44f5df33ef39b6159543b9f9064d365c01f919"},
|
||||||
{file = "httptools-0.2.0-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:80ffa04fe8c8dfacf6e4cef8277347d35b0442c581f5814f3b0cf41b65c43c6e"},
|
{file = "httptools-0.4.0-cp310-cp310-win_amd64.whl", hash = "sha256:5d1fe6b6661022fd6cac541f54a4237496b246e6f1c0a6b41998ee08a1135afe"},
|
||||||
{file = "httptools-0.2.0-cp37-cp37m-win_amd64.whl", hash = "sha256:d5682eeb10cca0606c4a8286a3391d4c3c5a36f0c448e71b8bd05be4e1694bfb"},
|
{file = "httptools-0.4.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:48e48530d9b995a84d1d89ae6b3ec4e59ea7d494b150ac3bbc5e2ac4acce92cd"},
|
||||||
{file = "httptools-0.2.0-cp38-cp38-macosx_10_14_x86_64.whl", hash = "sha256:a289c27ccae399a70eacf32df9a44059ca2ba4ac444604b00a19a6c1f0809943"},
|
{file = "httptools-0.4.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a113789e53ac1fa26edf99856a61e4c493868e125ae0dd6354cf518948fbbd5c"},
|
||||||
{file = "httptools-0.2.0-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:813871f961edea6cb2fe312f2d9b27d12a51ba92545380126f80d0de1917ea15"},
|
{file = "httptools-0.4.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:8e2eb957787cbb614a0f006bfc5798ff1d90ac7c4dd24854c84edbdc8c02369e"},
|
||||||
{file = "httptools-0.2.0-cp38-cp38-win_amd64.whl", hash = "sha256:cc9be041e428c10f8b6ab358c6b393648f9457094e1dcc11b4906026d43cd380"},
|
{file = "httptools-0.4.0-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:7ee9f226acab9085037582c059d66769862706e8e8cd2340470ceb8b3850873d"},
|
||||||
{file = "httptools-0.2.0-cp39-cp39-macosx_10_14_x86_64.whl", hash = "sha256:b08d00d889a118f68f37f3c43e359aab24ee29eb2e3fe96d64c6a2ba8b9d6557"},
|
{file = "httptools-0.4.0-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:701e66b59dd21a32a274771238025d58db7e2b6ecebbab64ceff51b8e31527ae"},
|
||||||
{file = "httptools-0.2.0-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:fd3b8905e21431ad306eeaf56644a68fdd621bf8f3097eff54d0f6bdf7262065"},
|
{file = "httptools-0.4.0-cp36-cp36m-win_amd64.whl", hash = "sha256:6a1a7dfc1f9c78a833e2c4904757a0f47ce25d08634dd2a52af394eefe5f9777"},
|
||||||
{file = "httptools-0.2.0-cp39-cp39-win_amd64.whl", hash = "sha256:200fc1cdf733a9ff554c0bb97a4047785cfaad9875307d6087001db3eb2b417f"},
|
{file = "httptools-0.4.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:903f739c9fb78dab8970b0f3ea51f21955b24b45afa77b22ff0e172fc11ef111"},
|
||||||
{file = "httptools-0.2.0.tar.gz", hash = "sha256:94505026be56652d7a530ab03d89474dc6021019d6b8682281977163b3471ea0"},
|
{file = "httptools-0.4.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:54bbd295f031b866b9799dd39cb45deee81aca036c9bff9f58ca06726f6494f1"},
|
||||||
|
{file = "httptools-0.4.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:3194f6d6443befa8d4db16c1946b2fc428a3ceb8ab32eb6f09a59f86104dc1a0"},
|
||||||
|
{file = "httptools-0.4.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:cd1295f52971097f757edfbfce827b6dbbfb0f7a74901ee7d4933dff5ad4c9af"},
|
||||||
|
{file = "httptools-0.4.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:20a45bcf22452a10fa8d58b7dbdb474381f6946bf5b8933e3662d572bc61bae4"},
|
||||||
|
{file = "httptools-0.4.0-cp37-cp37m-win_amd64.whl", hash = "sha256:d1f27bb0f75bef722d6e22dc609612bfa2f994541621cd2163f8c943b6463dfe"},
|
||||||
|
{file = "httptools-0.4.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:7f7bfb74718f52d5ed47d608d507bf66d3bc01d4a8b3e6dd7134daaae129357b"},
|
||||||
|
{file = "httptools-0.4.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:a522d12e2ddbc2e91842ffb454a1aeb0d47607972c7d8fc88bd0838d97fb8a2a"},
|
||||||
|
{file = "httptools-0.4.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2db44a0b294d317199e9f80123e72c6b005c55b625b57fae36de68670090fa48"},
|
||||||
|
{file = "httptools-0.4.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:c286985b5e194ca0ebb2908d71464b9be8f17cc66d6d3e330e8d5407248f56ad"},
|
||||||
|
{file = "httptools-0.4.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:d3a4e165ca6204f34856b765d515d558dc84f1352033b8721e8d06c3e44930c3"},
|
||||||
|
{file = "httptools-0.4.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:72aa3fbe636b16d22e04b5a9d24711b043495e0ecfe58080addf23a1a37f3409"},
|
||||||
|
{file = "httptools-0.4.0-cp38-cp38-win_amd64.whl", hash = "sha256:9967d9758df505975913304c434cb9ab21e2c609ad859eb921f2f615a038c8de"},
|
||||||
|
{file = "httptools-0.4.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:f72b5d24d6730035128b238decdc4c0f2104b7056a7ca55cf047c106842ec890"},
|
||||||
|
{file = "httptools-0.4.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:29bf97a5c532da9c7a04de2c7a9c31d1d54f3abd65a464119b680206bbbb1055"},
|
||||||
|
{file = "httptools-0.4.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:98993805f1e3cdb53de4eed02b55dcc953cdf017ba7bbb2fd89226c086a6d855"},
|
||||||
|
{file = "httptools-0.4.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:d9b90bf58f3ba04e60321a23a8723a1ff2a9377502535e70495e5ada8e6e6722"},
|
||||||
|
{file = "httptools-0.4.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:1a99346ebcb801b213c591540837340bdf6fd060a8687518d01c607d338b7424"},
|
||||||
|
{file = "httptools-0.4.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:645373c070080e632480a3d251d892cb795be3d3a15f86975d0f1aca56fd230d"},
|
||||||
|
{file = "httptools-0.4.0-cp39-cp39-win_amd64.whl", hash = "sha256:34d2903dd2a3dd85d33705b6fde40bf91fc44411661283763fd0746723963c83"},
|
||||||
|
{file = "httptools-0.4.0.tar.gz", hash = "sha256:2c9a930c378b3d15d6b695fb95ebcff81a7395b4f9775c4f10a076beb0b2c1ff"},
|
||||||
]
|
]
|
||||||
httpx = [
|
httpx = [
|
||||||
{file = "httpx-0.22.0-py3-none-any.whl", hash = "sha256:e35e83d1d2b9b2a609ef367cc4c1e66fd80b750348b20cc9e19d1952fc2ca3f6"},
|
{file = "httpx-0.22.0-py3-none-any.whl", hash = "sha256:e35e83d1d2b9b2a609ef367cc4c1e66fd80b750348b20cc9e19d1952fc2ca3f6"},
|
||||||
@ -2228,6 +2339,10 @@ psutil = [
|
|||||||
{file = "psutil-5.9.0-cp39-cp39-win_amd64.whl", hash = "sha256:7d190ee2eaef7831163f254dc58f6d2e2a22e27382b936aab51c835fc080c3d3"},
|
{file = "psutil-5.9.0-cp39-cp39-win_amd64.whl", hash = "sha256:7d190ee2eaef7831163f254dc58f6d2e2a22e27382b936aab51c835fc080c3d3"},
|
||||||
{file = "psutil-5.9.0.tar.gz", hash = "sha256:869842dbd66bb80c3217158e629d6fceaecc3a3166d3d1faee515b05dd26ca25"},
|
{file = "psutil-5.9.0.tar.gz", hash = "sha256:869842dbd66bb80c3217158e629d6fceaecc3a3166d3d1faee515b05dd26ca25"},
|
||||||
]
|
]
|
||||||
|
pyasn1 = [
|
||||||
|
{file = "pyasn1-0.4.8-py2.py3-none-any.whl", hash = "sha256:39c7e2ec30515947ff4e87fb6f456dfc6e84857d34be479c9d4a4ba4bf46aa5d"},
|
||||||
|
{file = "pyasn1-0.4.8.tar.gz", hash = "sha256:aef77c9fb94a3ac588e87841208bdec464471d9871bd5050a287cc9a475cd0ba"},
|
||||||
|
]
|
||||||
pydantic = [
|
pydantic = [
|
||||||
{file = "pydantic-1.9.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:cb23bcc093697cdea2708baae4f9ba0e972960a835af22560f6ae4e7e47d33f5"},
|
{file = "pydantic-1.9.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:cb23bcc093697cdea2708baae4f9ba0e972960a835af22560f6ae4e7e47d33f5"},
|
||||||
{file = "pydantic-1.9.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:1d5278bd9f0eee04a44c712982343103bba63507480bfd2fc2790fa70cd64cf4"},
|
{file = "pydantic-1.9.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:1d5278bd9f0eee04a44c712982343103bba63507480bfd2fc2790fa70cd64cf4"},
|
||||||
@ -2288,6 +2403,13 @@ python-dotenv = [
|
|||||||
{file = "python-dotenv-0.19.2.tar.gz", hash = "sha256:a5de49a31e953b45ff2d2fd434bbc2670e8db5273606c1e737cc6b93eff3655f"},
|
{file = "python-dotenv-0.19.2.tar.gz", hash = "sha256:a5de49a31e953b45ff2d2fd434bbc2670e8db5273606c1e737cc6b93eff3655f"},
|
||||||
{file = "python_dotenv-0.19.2-py2.py3-none-any.whl", hash = "sha256:32b2bdc1873fd3a3c346da1c6db83d0053c3c62f28f1f38516070c4c8971b1d3"},
|
{file = "python_dotenv-0.19.2-py2.py3-none-any.whl", hash = "sha256:32b2bdc1873fd3a3c346da1c6db83d0053c3c62f28f1f38516070c4c8971b1d3"},
|
||||||
]
|
]
|
||||||
|
python-jose = [
|
||||||
|
{file = "python-jose-3.3.0.tar.gz", hash = "sha256:55779b5e6ad599c6336191246e95eb2293a9ddebd555f796a65f838f07e5d78a"},
|
||||||
|
{file = "python_jose-3.3.0-py2.py3-none-any.whl", hash = "sha256:9b1376b023f8b298536eedd47ae1089bcdb848f1535ab30555cd92002d78923a"},
|
||||||
|
]
|
||||||
|
python-multipart = [
|
||||||
|
{file = "python-multipart-0.0.5.tar.gz", hash = "sha256:f7bb5f611fc600d15fa47b3974c8aa16e93724513b49b5f95c81e6624c83fa43"},
|
||||||
|
]
|
||||||
pytz = [
|
pytz = [
|
||||||
{file = "pytz-2021.3-py2.py3-none-any.whl", hash = "sha256:3672058bc3453457b622aab7a1c3bfd5ab0bdae451512f6cf25f64ed37f5b87c"},
|
{file = "pytz-2021.3-py2.py3-none-any.whl", hash = "sha256:3672058bc3453457b622aab7a1c3bfd5ab0bdae451512f6cf25f64ed37f5b87c"},
|
||||||
{file = "pytz-2021.3.tar.gz", hash = "sha256:acad2d8b20a1af07d4e4c9d2e9285c5ed9104354062f275f3fcd88dcef4f1326"},
|
{file = "pytz-2021.3.tar.gz", hash = "sha256:acad2d8b20a1af07d4e4c9d2e9285c5ed9104354062f275f3fcd88dcef4f1326"},
|
||||||
@ -2450,6 +2572,10 @@ rfc3986 = [
|
|||||||
{file = "rfc3986-1.5.0-py2.py3-none-any.whl", hash = "sha256:a86d6e1f5b1dc238b218b012df0aa79409667bb209e58da56d0b94704e712a97"},
|
{file = "rfc3986-1.5.0-py2.py3-none-any.whl", hash = "sha256:a86d6e1f5b1dc238b218b012df0aa79409667bb209e58da56d0b94704e712a97"},
|
||||||
{file = "rfc3986-1.5.0.tar.gz", hash = "sha256:270aaf10d87d0d4e095063c65bf3ddbc6ee3d0b226328ce21e036f946e421835"},
|
{file = "rfc3986-1.5.0.tar.gz", hash = "sha256:270aaf10d87d0d4e095063c65bf3ddbc6ee3d0b226328ce21e036f946e421835"},
|
||||||
]
|
]
|
||||||
|
rsa = [
|
||||||
|
{file = "rsa-4.8-py3-none-any.whl", hash = "sha256:95c5d300c4e879ee69708c428ba566c59478fd653cc3a22243eeb8ed846950bb"},
|
||||||
|
{file = "rsa-4.8.tar.gz", hash = "sha256:5c6bd9dc7a543b7fe4304a631f8a8a3b674e2bbfc49c2ae96200cdbe55df6b17"},
|
||||||
|
]
|
||||||
"ruamel.yaml" = [
|
"ruamel.yaml" = [
|
||||||
{file = "ruamel.yaml-0.17.21-py3-none-any.whl", hash = "sha256:742b35d3d665023981bd6d16b3d24248ce5df75fdb4e2924e93a05c1f8b61ca7"},
|
{file = "ruamel.yaml-0.17.21-py3-none-any.whl", hash = "sha256:742b35d3d665023981bd6d16b3d24248ce5df75fdb4e2924e93a05c1f8b61ca7"},
|
||||||
{file = "ruamel.yaml-0.17.21.tar.gz", hash = "sha256:8b7ce697a2f212752a35c1ac414471dc16c424c9573be4926b56ff3f5d23b7af"},
|
{file = "ruamel.yaml-0.17.21.tar.gz", hash = "sha256:8b7ce697a2f212752a35c1ac414471dc16c424c9573be4926b56ff3f5d23b7af"},
|
||||||
@ -2638,8 +2764,8 @@ urllib3 = [
|
|||||||
{file = "urllib3-1.26.8.tar.gz", hash = "sha256:0e7c33d9a63e7ddfcb86780aac87befc2fbddf46c58dbb487e0855f7ceec283c"},
|
{file = "urllib3-1.26.8.tar.gz", hash = "sha256:0e7c33d9a63e7ddfcb86780aac87befc2fbddf46c58dbb487e0855f7ceec283c"},
|
||||||
]
|
]
|
||||||
uvicorn = [
|
uvicorn = [
|
||||||
{file = "uvicorn-0.17.5-py3-none-any.whl", hash = "sha256:8adddf629b79857b48b999ae1b14d6c92c95d4d7840bd86461f09bee75f1653e"},
|
{file = "uvicorn-0.17.6-py3-none-any.whl", hash = "sha256:19e2a0e96c9ac5581c01eb1a79a7d2f72bb479691acd2b8921fce48ed5b961a6"},
|
||||||
{file = "uvicorn-0.17.5.tar.gz", hash = "sha256:c04a9c069111489c324f427501b3840d306c6b91a77b00affc136a840a3f45f1"},
|
{file = "uvicorn-0.17.6.tar.gz", hash = "sha256:5180f9d059611747d841a4a4c4ab675edf54c8489e97f96d0583ee90ac3bfc23"},
|
||||||
]
|
]
|
||||||
uvloop = [
|
uvloop = [
|
||||||
{file = "uvloop-0.16.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:6224f1401025b748ffecb7a6e2652b17768f30b1a6a3f7b44660e5b5b690b12d"},
|
{file = "uvloop-0.16.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:6224f1401025b748ffecb7a6e2652b17768f30b1a6a3f7b44660e5b5b690b12d"},
|
||||||
|
|||||||
@ -38,6 +38,8 @@ black = "^22.1.0"
|
|||||||
pypinyin = "^0.46.0"
|
pypinyin = "^0.46.0"
|
||||||
dateparser = "^1.1.0"
|
dateparser = "^1.1.0"
|
||||||
cn2an = "^0.5.16"
|
cn2an = "^0.5.16"
|
||||||
|
python-jose = "^3.3.0"
|
||||||
|
python-multipart = "^0.0.5"
|
||||||
|
|
||||||
[tool.poetry.dev-dependencies]
|
[tool.poetry.dev-dependencies]
|
||||||
|
|
||||||
|
|||||||
@ -8,7 +8,8 @@
|
|||||||
"configs/path_config.py",
|
"configs/path_config.py",
|
||||||
"configs/utils",
|
"configs/utils",
|
||||||
"poetry.lock",
|
"poetry.lock",
|
||||||
"pyproject.toml"
|
"pyproject.toml",
|
||||||
|
"resources/font"
|
||||||
],
|
],
|
||||||
"add_file": [],
|
"add_file": [],
|
||||||
"delete_file": []
|
"delete_file": []
|
||||||
|
|||||||
@ -295,7 +295,7 @@ class AsyncPlaywright:
|
|||||||
path: Union[Path, str],
|
path: Union[Path, str],
|
||||||
element: Union[str, List[str]],
|
element: Union[str, List[str]],
|
||||||
*,
|
*,
|
||||||
sleep: Optional[int] = None,
|
wait_time: Optional[int] = None,
|
||||||
viewport_size: Dict[str, int] = None,
|
viewport_size: Dict[str, int] = None,
|
||||||
wait_until: Optional[
|
wait_until: Optional[
|
||||||
Literal["domcontentloaded", "load", "networkidle"]
|
Literal["domcontentloaded", "load", "networkidle"]
|
||||||
@ -311,7 +311,7 @@ class AsyncPlaywright:
|
|||||||
:param url: 网址
|
:param url: 网址
|
||||||
:param path: 存储路径
|
:param path: 存储路径
|
||||||
:param element: 元素选择
|
:param element: 元素选择
|
||||||
:param sleep: 延迟截取
|
:param wait_time: 等待截取超时时间
|
||||||
:param viewport_size: 窗口大小
|
:param viewport_size: 窗口大小
|
||||||
:param wait_until: 等待类型
|
:param wait_until: 等待类型
|
||||||
:param timeout: 超时限制
|
:param timeout: 超时限制
|
||||||
@ -325,14 +325,18 @@ class AsyncPlaywright:
|
|||||||
try:
|
try:
|
||||||
page = await cls.goto(url, wait_until=wait_until, **kwargs)
|
page = await cls.goto(url, wait_until=wait_until, **kwargs)
|
||||||
await page.set_viewport_size(viewport_size)
|
await page.set_viewport_size(viewport_size)
|
||||||
if sleep:
|
|
||||||
await asyncio.sleep(sleep)
|
|
||||||
if isinstance(element, str):
|
if isinstance(element, str):
|
||||||
card = await page.query_selector(element)
|
if wait_time:
|
||||||
|
card = await page.wait_for_selector(element, timeout=wait_time)
|
||||||
|
else:
|
||||||
|
card = await page.query_selector(element)
|
||||||
else:
|
else:
|
||||||
card = page
|
card = page
|
||||||
for e in element:
|
for e in element:
|
||||||
card = await card.query_selector(e)
|
if wait_time:
|
||||||
|
card = await card.wait_for_selector(e, timeout=wait_time)
|
||||||
|
else:
|
||||||
|
card = await card.query_selector(e)
|
||||||
await card.screenshot(path=path, timeout=timeout, type=type_)
|
await card.screenshot(path=path, timeout=timeout, type=type_)
|
||||||
return image(path)
|
return image(path)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
|||||||
@ -2,6 +2,7 @@ from typing import Union, Optional
|
|||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from ruamel.yaml import YAML
|
from ruamel.yaml import YAML
|
||||||
import ujson as json
|
import ujson as json
|
||||||
|
import copy
|
||||||
|
|
||||||
yaml = YAML(typ="safe")
|
yaml = YAML(typ="safe")
|
||||||
|
|
||||||
@ -47,7 +48,7 @@ class StaticData:
|
|||||||
del self._data[key]
|
del self._data[key]
|
||||||
|
|
||||||
def get_data(self) -> dict:
|
def get_data(self) -> dict:
|
||||||
return self._data
|
return copy.deepcopy(self._data)
|
||||||
|
|
||||||
def save(self, path: Union[str, Path] = None):
|
def save(self, path: Union[str, Path] = None):
|
||||||
path = path if path else self.file
|
path = path if path else self.file
|
||||||
|
|||||||
@ -2,7 +2,7 @@ from utils.manager.data_class import StaticData
|
|||||||
from nonebot.adapters.onebot.v11 import Bot
|
from nonebot.adapters.onebot.v11 import Bot
|
||||||
from nonebot.adapters.onebot.v11.exception import ActionFailed
|
from nonebot.adapters.onebot.v11.exception import ActionFailed
|
||||||
from services.log import logger
|
from services.log import logger
|
||||||
from typing import Optional
|
from typing import Optional, Literal
|
||||||
from utils.image_utils import BuildImage
|
from utils.image_utils import BuildImage
|
||||||
from utils.utils import get_user_avatar
|
from utils.utils import get_user_avatar
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
@ -80,7 +80,10 @@ class RequestManager(StaticData):
|
|||||||
通过id获取群号
|
通过id获取群号
|
||||||
:param id_: id
|
:param id_: id
|
||||||
"""
|
"""
|
||||||
return self._data["group"].get(id_)
|
data = self._data["group"].get(str(id_))
|
||||||
|
if data:
|
||||||
|
return data["invite_group"]
|
||||||
|
return None
|
||||||
|
|
||||||
async def approve(self, bot: Bot, id_: int, type_: str) -> Optional[int]:
|
async def approve(self, bot: Bot, id_: int, type_: str) -> Optional[int]:
|
||||||
"""
|
"""
|
||||||
@ -100,13 +103,28 @@ class RequestManager(StaticData):
|
|||||||
"""
|
"""
|
||||||
return await self._set_add_request(bot, id_, type_, False)
|
return await self._set_add_request(bot, id_, type_, False)
|
||||||
|
|
||||||
def clear(self):
|
def clear(self, type_: Optional[str] = None): # type_: Optional[Literal["group", "private"]] = None
|
||||||
"""
|
"""
|
||||||
清空所有请求信息,无视请求
|
清空所有请求信息,无视请求
|
||||||
|
:param type_: 类型
|
||||||
"""
|
"""
|
||||||
self._data = {"private": {}, "group": {}}
|
if type_:
|
||||||
|
self._data[type_] = {}
|
||||||
|
else:
|
||||||
|
self._data = {"private": {}, "group": {}}
|
||||||
self.save()
|
self.save()
|
||||||
|
|
||||||
|
def delete_request(self, id_: int, type_: str): # type_: Literal["group", "private"]
|
||||||
|
"""
|
||||||
|
删除请求
|
||||||
|
:param id_: id
|
||||||
|
:param type_: 类型
|
||||||
|
"""
|
||||||
|
id_ = str(id_)
|
||||||
|
if self._data[type_].get(id_):
|
||||||
|
del self._data[type_][id_]
|
||||||
|
self.save()
|
||||||
|
|
||||||
def set_group_name(self, group_name: str, group_id: int):
|
def set_group_name(self, group_name: str, group_id: int):
|
||||||
"""
|
"""
|
||||||
设置群聊名称
|
设置群聊名称
|
||||||
@ -223,7 +241,7 @@ class RequestManager(StaticData):
|
|||||||
:param approve: 是否同意
|
:param approve: 是否同意
|
||||||
"""
|
"""
|
||||||
id_ = str(id_)
|
id_ = str(id_)
|
||||||
if id_ in self._data[type_]:
|
if id_ in self._data[type_].keys():
|
||||||
try:
|
try:
|
||||||
if type_ == "private":
|
if type_ == "private":
|
||||||
await bot.set_friend_add_request(
|
await bot.set_friend_add_request(
|
||||||
@ -244,7 +262,7 @@ class RequestManager(StaticData):
|
|||||||
)
|
)
|
||||||
return None
|
return None
|
||||||
logger.info(
|
logger.info(
|
||||||
f"同意{self._data[type_][id_]['nickname']}({self._data[type_][id_]['id']})"
|
f"{'同意' if approve else '拒绝'}{self._data[type_][id_]['nickname']}({self._data[type_][id_]['id']})"
|
||||||
f"的{'好友' if type_ == 'private' else '入群'}请求..."
|
f"的{'好友' if type_ == 'private' else '入群'}请求..."
|
||||||
)
|
)
|
||||||
del self._data[type_][id_]
|
del self._data[type_][id_]
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user