diff --git a/README.md b/README.md index 4ea90660..4f8e3b6d 100644 --- a/README.md +++ b/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 * 修复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) * fix: 修复远古时期残留的epic推送问题 [@pull/122](https://github.com/HibiKier/zhenxun_bot/pull/122) -### 2022/2/11 +### 2021/2/11 * 修复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提供文本敏感词过滤器 * 疫情插件适配新版腾讯API @@ -355,7 +365,7 @@ __Docker 最新版本由 [Sakuracio](https://github.com/Sakuracio) 提供__ * “send_success_msg”(发送成功的交互信息->即:使用道具 {name} {num} 次成功) * “_max_num_limit”(该道具单次使用的最多个数,默认1) -### 2022/1/5 \[v0.0.8.2] +### 2021/1/5 \[v0.0.8.2] * 提供金币消费hook,可在plugins2settings.yaml中配置该功能需要消费的金币 * 商店插件将作为内置插件移动至basic_plugins diff --git a/__version__ b/__version__ index 804f21b7..8fb47179 100644 --- a/__version__ +++ b/__version__ @@ -1 +1 @@ -__version__: v0.1.4.4 \ No newline at end of file +__version__: v0.1.4.5 \ No newline at end of file diff --git a/basic_plugins/admin_bot_manage/rule.py b/basic_plugins/admin_bot_manage/rule.py index 11d7e384..b0685a0f 100755 --- a/basic_plugins/admin_bot_manage/rule.py +++ b/basic_plugins/admin_bot_manage/rule.py @@ -24,11 +24,17 @@ def switch_rule(event: Event) -> bool: _data = plugins2settings_manager.get_data() for key in _data: try: - for x in _data[key]["cmd"]: - cmd.append(f"开启{x}") - cmd.append(f"关闭{x}") - cmd.append(f"开启 {x}") - cmd.append(f"关闭 {x}") + if isinstance(_data[key]["cmd"], list): + for x in _data[key]["cmd"]: + 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: pass msg = get_message_text(event.json()).split() diff --git a/basic_plugins/init_plugin_config/init_plugins_settings.py b/basic_plugins/init_plugin_config/init_plugins_settings.py index dfabbe28..0670e366 100755 --- a/basic_plugins/init_plugin_config/init_plugins_settings.py +++ b/basic_plugins/init_plugin_config/init_plugins_settings.py @@ -74,7 +74,7 @@ def init_plugins_settings(data_path: str): if plugin_settings.get('cost_gold') is None: plugin_settings['cost_gold'] = 0 if ( - plugin_settings["cmd"] is not None + plugin_settings.get("cmd") is not None and plugin_name not in plugin_settings["cmd"] ): plugin_settings["cmd"].append(plugin_name) diff --git a/plugins/ai/data_source.py b/plugins/ai/data_source.py index 30221678..ca5827f6 100755 --- a/plugins/ai/data_source.py +++ b/plugins/ai/data_source.py @@ -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 nickname.find("大人") == -1: nickname += "大~人~" - rst = rst.replace("小主人", nickname).replace("小朋友", nickname) + rst = str(rst).replace("小主人", nickname).replace("小朋友", nickname) ai_message_manager.add_result(user_id, rst) return rst diff --git a/plugins/alapi/wbtop.py b/plugins/alapi/wbtop.py index bcbf4294..f1fb73ab 100755 --- a/plugins/alapi/wbtop.py +++ b/plugins/alapi/wbtop.py @@ -56,15 +56,15 @@ async def _(event: MessageEvent, arg: Message = CommandArg()): ) if is_number(msg) and 0 < int(msg) <= 50: url = wbtop_data[int(msg) - 1]["url"] - try: - await wbtop.send("开始截取数据...") - img = await AsyncPlaywright.screenshot( - url, - f"{IMAGE_PATH}/temp/wbtop_{event.user_id}.png", - "#pl_feedlist_index", - sleep=5 - ) + await wbtop.send("开始截取数据...") + img = await AsyncPlaywright.screenshot( + url, + f"{IMAGE_PATH}/temp/wbtop_{event.user_id}.png", + "#pl_feedlist_index", + wait_time=5 + ) + if img: await wbtop.send(img) - except Exception as e: - logger.error(f"微博热搜截图出错... {type(e)}: {e}") + else: await wbtop.send("发生了一些错误.....") + diff --git a/plugins/bilibili_sub/__init__.py b/plugins/bilibili_sub/__init__.py index d30bb427..98834f4d 100755 --- a/plugins/bilibili_sub/__init__.py +++ b/plugins/bilibili_sub/__init__.py @@ -211,7 +211,7 @@ async def _(): await sub_manager.reload_sub_data() sub = await sub_manager.random_sub_data() 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) await send_sub_msg(rst, sub, bot) if sub.sub_type == "live": diff --git a/plugins/bilibili_sub/data_source.py b/plugins/bilibili_sub/data_source.py index e3a8645a..274b8e18 100755 --- a/plugins/bilibili_sub/data_source.py +++ b/plugins/bilibili_sub/data_source.py @@ -311,28 +311,32 @@ async def get_user_dynamic( dynamic_upload_time = dynamic_info["cards"][0]["desc"]["timestamp"] if local_user.dynamic_upload_time < dynamic_upload_time: page = await browser.new_page() - await page.goto( - f"https://space.bilibili.com/{local_user.uid}/dynamic", - wait_until="networkidle", - timeout=10000, - ) - await page.set_viewport_size({"width": 2560, "height": 1080}) - # 删除置顶 - await page.evaluate( + try: + await page.goto( + f"https://space.bilibili.com/{local_user.uid}/dynamic", + wait_until="networkidle", + timeout=10000, + ) + await page.set_viewport_size({"width": 2560, "height": 1080}) + # 删除置顶 + 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) { - x.remove(); - } - """ - ) - card = await page.query_selector(".card") - # 截图并保存 - await card.screenshot( - path=dynamic_path / f"{local_user.sub_id}_{dynamic_upload_time}.jpg", - timeout=100000, - ) - await page.close() + ) + card = await page.query_selector(".card") + # 截图并保存 + await card.screenshot( + path=dynamic_path / f"{local_user.sub_id}_{dynamic_upload_time}.jpg", + timeout=100000, + ) + except Exception as e: + logger.error(f"B站订阅:获取用户动态 发送错误 {type(e)}:{e}") + finally: + await page.close() return ( image( f"{local_user.sub_id}_{dynamic_upload_time}.jpg", diff --git a/plugins/bt/data_source.py b/plugins/bt/data_source.py index 42513987..a7754625 100755 --- a/plugins/bt/data_source.py +++ b/plugins/bt/data_source.py @@ -9,7 +9,7 @@ if platform.system() == "Windows": 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): diff --git a/plugins/genshin/query_user/query_memo/data_source.py b/plugins/genshin/query_user/query_memo/data_source.py index aa4fef60..f1f7fb77 100644 --- a/plugins/genshin/query_user/query_memo/data_source.py +++ b/plugins/genshin/query_user/query_memo/data_source.py @@ -200,7 +200,7 @@ def _parse_data_and_draw( file_name = x["avatar_side_icon"].split("_")[-1] role_avatar = memo_path / "role_avatar" / file_name _ava_img = BuildImage(75, 75, background=role_avatar) - _ava_img.circle() + # _ava_img.circle() if x["status"] == "Finished": msg = "探索完成" font_color = (146, 188, 63) @@ -218,10 +218,10 @@ def _parse_data_and_draw( a_circle.circle() b_circle = BuildImage(47, 47) b_circle.circle() - a_circle.paste(b_circle, (4, 4), alpha=True) - _circle_bk.paste(a_circle, (4, 4), alpha=True) + a_circle.paste(b_circle, (4, 4), 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.text((100, 0), msg, font_color, "by_height") _bk.circle_corner(20) diff --git a/plugins/genshin/query_user/query_role/draw_image.py b/plugins/genshin/query_user/query_role/draw_image.py index eb7dfa8a..a6bdda52 100644 --- a/plugins/genshin/query_user/query_role/draw_image.py +++ b/plugins/genshin/query_user/query_role/draw_image.py @@ -296,9 +296,11 @@ def get_country_data_image(world_data_dict: Dict) -> BuildImage: 画出国家探索供奉等图像 :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 - for country in ["蒙德", "龙脊雪山", "璃月", "稻妻", "渊下宫"]: + + for country in ["蒙德", "龙脊雪山", "璃月", "璃月层岩巨渊", "稻妻", "渊下宫"]: x = BuildImage(790, 250, color="#3A4467") logo = BuildImage(180, 180, background=image_path / "logo" / f"{country}.png") 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']}", 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 ["龙脊雪山"]: content_bk.text((300, 40), "探索", fill=(239, 211, 114)) content_bk.text( diff --git a/plugins/statistics/statistics_handle.py b/plugins/statistics/statistics_handle.py index 74daafda..37c1e439 100755 --- a/plugins/statistics/statistics_handle.py +++ b/plugins/statistics/statistics_handle.py @@ -276,4 +276,4 @@ def update_data(data: dict): tmp_dict[plugin_name] = 1 else: tmp_dict[plugin_name] += data[day][plugin_name] - return tmp_dict + return tmp_dict \ No newline at end of file diff --git a/plugins/web_ui/__init__.py b/plugins/web_ui/__init__.py new file mode 100644 index 00000000..1dcff95c --- /dev/null +++ b/plugins/web_ui/__init__.py @@ -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_="前端管理密码" +) diff --git a/plugins/web_ui/auth/__init__.py b/plugins/web_ui/auth/__init__.py new file mode 100644 index 00000000..187ad64f --- /dev/null +++ b/plugins/web_ui/auth/__init__.py @@ -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) diff --git a/plugins/web_ui/config.py b/plugins/web_ui/config.py new file mode 100644 index 00000000..270c4916 --- /dev/null +++ b/plugins/web_ui/config.py @@ -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 diff --git a/plugins/web_ui/manager/__init__.py b/plugins/web_ui/manager/__init__.py new file mode 100644 index 00000000..512e010e --- /dev/null +++ b/plugins/web_ui/manager/__init__.py @@ -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) diff --git a/poetry.lock b/poetry.lock index 38aa11b3..130e7c1c 100644 --- a/poetry.lock +++ b/poetry.lock @@ -377,6 +377,26 @@ type = "legacy" url = "https://pypi.tuna.tsinghua.edu.cn/simple" 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]] name = "fastapi" version = "0.73.0" @@ -520,14 +540,14 @@ reference = "tsinghua" [[package]] name = "httptools" -version = "0.2.0" +version = "0.4.0" description = "A collection of framework independent HTTP protocol utils." category = "main" optional = false -python-versions = "*" +python-versions = ">=3.5.0" [package.extras] -test = ["Cython (==0.29.22)"] +test = ["Cython (>=0.29.24,<0.30.0)"] [package.source] type = "legacy" @@ -915,6 +935,19 @@ type = "legacy" url = "https://pypi.tuna.tsinghua.edu.cn/simple" 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]] name = "pydantic" version = "1.9.0" @@ -1023,6 +1056,45 @@ type = "legacy" url = "https://pypi.tuna.tsinghua.edu.cn/simple" 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]] name = "pytz" version = "2021.3" @@ -1130,6 +1202,22 @@ type = "legacy" url = "https://pypi.tuna.tsinghua.edu.cn/simple" 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]] name = "ruamel.yaml" version = "0.17.21" @@ -1403,7 +1491,7 @@ reference = "tsinghua" [[package]] name = "uvicorn" -version = "0.17.5" +version = "0.17.6" description = "The lightning-fast ASGI server." category = "main" optional = false @@ -1414,7 +1502,7 @@ asgiref = ">=3.4.0" click = ">=7.0" colorama = {version = ">=0.4", optional = true, markers = "sys_platform == \"win32\" and extra == \"standard\""} 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\""} 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\""} @@ -1422,7 +1510,7 @@ watchgod = {version = ">=0.6", optional = true, markers = "extra == \"standard\" websockets = {version = ">=10.0", optional = true, markers = "extra == \"standard\""} [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] type = "legacy" @@ -1522,7 +1610,7 @@ reference = "tsinghua" [metadata] lock-version = "1.1" python-versions = "^3.8" -content-hash = "2521c3cd7346f1f1b3b22276fa71ca9680447f85fc13fd23ede0e33d6f942423" +content-hash = "a467c2f5d871d65cd76363a2839023a38bde9b4aacd37f3019dca6fe0f199723" [metadata.files] aiofiles = [ @@ -1764,6 +1852,10 @@ dateparser = [ {file = "dateparser-1.1.0-py2.py3-none-any.whl", hash = "sha256:fec344db1f73d005182e214c0ff27313c748bbe0c1638ce9d48a809ddfdab2a0"}, {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 = [ {file = "fastapi-0.73.0-py3-none-any.whl", hash = "sha256:f0a618aff5f6942862f2d3f20f39b1c037e33314d1b8207fd1c3a2cca76dfd8c"}, {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"}, ] httptools = [ - {file = "httptools-0.2.0-cp35-cp35m-macosx_10_14_x86_64.whl", hash = "sha256:79dbc21f3612a78b28384e989b21872e2e3cf3968532601544696e4ed0007ce5"}, - {file = "httptools-0.2.0-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:78d03dd39b09c99ec917d50189e6743adbfd18c15d5944392d2eabda688bf149"}, - {file = "httptools-0.2.0-cp36-cp36m-macosx_10_14_x86_64.whl", hash = "sha256:a23166e5ae2775709cf4f7ad4c2048755ebfb272767d244e1a96d55ac775cca7"}, - {file = "httptools-0.2.0-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:3ab1f390d8867f74b3b5ee2a7ecc9b8d7f53750bd45714bf1cb72a953d7dfa77"}, - {file = "httptools-0.2.0-cp36-cp36m-win_amd64.whl", hash = "sha256:a7594f9a010cdf1e16a58b3bf26c9da39bbf663e3b8d46d39176999d71816658"}, - {file = "httptools-0.2.0-cp37-cp37m-macosx_10_14_x86_64.whl", hash = "sha256:01b392a166adcc8bc2f526a939a8aabf89fe079243e1543fd0e7dc1b58d737cb"}, - {file = "httptools-0.2.0-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:80ffa04fe8c8dfacf6e4cef8277347d35b0442c581f5814f3b0cf41b65c43c6e"}, - {file = "httptools-0.2.0-cp37-cp37m-win_amd64.whl", hash = "sha256:d5682eeb10cca0606c4a8286a3391d4c3c5a36f0c448e71b8bd05be4e1694bfb"}, - {file = "httptools-0.2.0-cp38-cp38-macosx_10_14_x86_64.whl", hash = "sha256:a289c27ccae399a70eacf32df9a44059ca2ba4ac444604b00a19a6c1f0809943"}, - {file = "httptools-0.2.0-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:813871f961edea6cb2fe312f2d9b27d12a51ba92545380126f80d0de1917ea15"}, - {file = "httptools-0.2.0-cp38-cp38-win_amd64.whl", hash = "sha256:cc9be041e428c10f8b6ab358c6b393648f9457094e1dcc11b4906026d43cd380"}, - {file = "httptools-0.2.0-cp39-cp39-macosx_10_14_x86_64.whl", hash = "sha256:b08d00d889a118f68f37f3c43e359aab24ee29eb2e3fe96d64c6a2ba8b9d6557"}, - {file = "httptools-0.2.0-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:fd3b8905e21431ad306eeaf56644a68fdd621bf8f3097eff54d0f6bdf7262065"}, - {file = "httptools-0.2.0-cp39-cp39-win_amd64.whl", hash = "sha256:200fc1cdf733a9ff554c0bb97a4047785cfaad9875307d6087001db3eb2b417f"}, - {file = "httptools-0.2.0.tar.gz", hash = "sha256:94505026be56652d7a530ab03d89474dc6021019d6b8682281977163b3471ea0"}, + {file = "httptools-0.4.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:fcddfe70553be717d9745990dfdb194e22ee0f60eb8f48c0794e7bfeda30d2d5"}, + {file = "httptools-0.4.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:1ee0b459257e222b878a6c09ccf233957d3a4dcb883b0847640af98d2d9aac23"}, + {file = "httptools-0.4.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ceafd5e960b39c7e0d160a1936b68eb87c5e79b3979d66e774f0c77d4d8faaed"}, + {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.4.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:abe829275cdd4174b4c4e65ad718715d449e308d59793bf3a931ee1bf7e7b86c"}, + {file = "httptools-0.4.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:7af6bdbd21a2a25d6784f6d67f44f5df33ef39b6159543b9f9064d365c01f919"}, + {file = "httptools-0.4.0-cp310-cp310-win_amd64.whl", hash = "sha256:5d1fe6b6661022fd6cac541f54a4237496b246e6f1c0a6b41998ee08a1135afe"}, + {file = "httptools-0.4.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:48e48530d9b995a84d1d89ae6b3ec4e59ea7d494b150ac3bbc5e2ac4acce92cd"}, + {file = "httptools-0.4.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a113789e53ac1fa26edf99856a61e4c493868e125ae0dd6354cf518948fbbd5c"}, + {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.4.0-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:7ee9f226acab9085037582c059d66769862706e8e8cd2340470ceb8b3850873d"}, + {file = "httptools-0.4.0-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:701e66b59dd21a32a274771238025d58db7e2b6ecebbab64ceff51b8e31527ae"}, + {file = "httptools-0.4.0-cp36-cp36m-win_amd64.whl", hash = "sha256:6a1a7dfc1f9c78a833e2c4904757a0f47ce25d08634dd2a52af394eefe5f9777"}, + {file = "httptools-0.4.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:903f739c9fb78dab8970b0f3ea51f21955b24b45afa77b22ff0e172fc11ef111"}, + {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 = [ {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.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 = [ {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"}, @@ -2288,6 +2403,13 @@ python-dotenv = [ {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"}, ] +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 = [ {file = "pytz-2021.3-py2.py3-none-any.whl", hash = "sha256:3672058bc3453457b622aab7a1c3bfd5ab0bdae451512f6cf25f64ed37f5b87c"}, {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.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" = [ {file = "ruamel.yaml-0.17.21-py3-none-any.whl", hash = "sha256:742b35d3d665023981bd6d16b3d24248ce5df75fdb4e2924e93a05c1f8b61ca7"}, {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"}, ] uvicorn = [ - {file = "uvicorn-0.17.5-py3-none-any.whl", hash = "sha256:8adddf629b79857b48b999ae1b14d6c92c95d4d7840bd86461f09bee75f1653e"}, - {file = "uvicorn-0.17.5.tar.gz", hash = "sha256:c04a9c069111489c324f427501b3840d306c6b91a77b00affc136a840a3f45f1"}, + {file = "uvicorn-0.17.6-py3-none-any.whl", hash = "sha256:19e2a0e96c9ac5581c01eb1a79a7d2f72bb479691acd2b8921fce48ed5b961a6"}, + {file = "uvicorn-0.17.6.tar.gz", hash = "sha256:5180f9d059611747d841a4a4c4ab675edf54c8489e97f96d0583ee90ac3bfc23"}, ] uvloop = [ {file = "uvloop-0.16.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:6224f1401025b748ffecb7a6e2652b17768f30b1a6a3f7b44660e5b5b690b12d"}, diff --git a/pyproject.toml b/pyproject.toml index d25f60a8..7be907aa 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -38,6 +38,8 @@ black = "^22.1.0" pypinyin = "^0.46.0" dateparser = "^1.1.0" cn2an = "^0.5.16" +python-jose = "^3.3.0" +python-multipart = "^0.0.5" [tool.poetry.dev-dependencies] diff --git a/update_info.json b/update_info.json index a0f81cac..a1d8a124 100644 --- a/update_info.json +++ b/update_info.json @@ -8,7 +8,8 @@ "configs/path_config.py", "configs/utils", "poetry.lock", - "pyproject.toml" + "pyproject.toml", + "resources/font" ], "add_file": [], "delete_file": [] diff --git a/utils/http_utils.py b/utils/http_utils.py index 42be9515..29c94d49 100644 --- a/utils/http_utils.py +++ b/utils/http_utils.py @@ -295,7 +295,7 @@ class AsyncPlaywright: path: Union[Path, str], element: Union[str, List[str]], *, - sleep: Optional[int] = None, + wait_time: Optional[int] = None, viewport_size: Dict[str, int] = None, wait_until: Optional[ Literal["domcontentloaded", "load", "networkidle"] @@ -311,7 +311,7 @@ class AsyncPlaywright: :param url: 网址 :param path: 存储路径 :param element: 元素选择 - :param sleep: 延迟截取 + :param wait_time: 等待截取超时时间 :param viewport_size: 窗口大小 :param wait_until: 等待类型 :param timeout: 超时限制 @@ -325,14 +325,18 @@ class AsyncPlaywright: try: page = await cls.goto(url, wait_until=wait_until, **kwargs) await page.set_viewport_size(viewport_size) - if sleep: - await asyncio.sleep(sleep) 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: card = page 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_) return image(path) except Exception as e: diff --git a/utils/manager/data_class.py b/utils/manager/data_class.py index 7fcadb52..f726221b 100755 --- a/utils/manager/data_class.py +++ b/utils/manager/data_class.py @@ -2,6 +2,7 @@ from typing import Union, Optional from pathlib import Path from ruamel.yaml import YAML import ujson as json +import copy yaml = YAML(typ="safe") @@ -47,7 +48,7 @@ class StaticData: del self._data[key] def get_data(self) -> dict: - return self._data + return copy.deepcopy(self._data) def save(self, path: Union[str, Path] = None): path = path if path else self.file diff --git a/utils/manager/requests_manager.py b/utils/manager/requests_manager.py index 8a796ae3..ce0d6965 100755 --- a/utils/manager/requests_manager.py +++ b/utils/manager/requests_manager.py @@ -2,7 +2,7 @@ from utils.manager.data_class import StaticData from nonebot.adapters.onebot.v11 import Bot from nonebot.adapters.onebot.v11.exception import ActionFailed from services.log import logger -from typing import Optional +from typing import Optional, Literal from utils.image_utils import BuildImage from utils.utils import get_user_avatar from pathlib import Path @@ -80,7 +80,10 @@ class RequestManager(StaticData): 通过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]: """ @@ -100,13 +103,28 @@ class RequestManager(StaticData): """ 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() + 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): """ 设置群聊名称 @@ -223,7 +241,7 @@ class RequestManager(StaticData): :param approve: 是否同意 """ id_ = str(id_) - if id_ in self._data[type_]: + if id_ in self._data[type_].keys(): try: if type_ == "private": await bot.set_friend_add_request( @@ -244,7 +262,7 @@ class RequestManager(StaticData): ) return None 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 '入群'}请求..." ) del self._data[type_][id_]