update v0.0.5.0

This commit is contained in:
HibiKier
2021-10-03 14:24:07 +08:00
parent 87ed445a58
commit 00658cf165
182 changed files with 6439 additions and 3845 deletions
+540 -15
View File
@@ -1,13 +1,16 @@
from configs.path_config import IMAGE_PATH, TTF_PATH
from PIL import Image, ImageFile, ImageDraw, ImageFont
from configs.path_config import IMAGE_PATH, FONT_PATH
from PIL import Image, ImageFile, ImageDraw, ImageFont, ImageFilter
from imagehash import ImageHash
from io import BytesIO
from matplotlib import pyplot as plt
from typing import Tuple, Optional, Union
from typing import Tuple, Optional, Union, List
from pathlib import Path
from math import ceil
import random
import cv2
import base64
import imagehash
ImageFile.LOAD_TRUNCATED_IMAGES = True
Image.MAX_IMAGE_PIXELS = None
@@ -143,11 +146,11 @@ class CreateImg:
h: int,
paste_image_width: int = 0,
paste_image_height: int = 0,
color: Union[str, Tuple[int, int, int], Tuple[int, int, int, int]] = "white",
color: Union[str, Tuple[int, int, int], Tuple[int, int, int, int]] = None,
image_mode: str = "RGBA",
font_size: int = 10,
background: Union[Optional[str], BytesIO] = None,
ttf: str = "yz.ttf",
background: Union[Optional[str], BytesIO, Path] = None,
font: str = "yz.ttf",
ratio: float = 1,
is_alpha: bool = False,
plain_text: Optional[str] = None,
@@ -174,9 +177,13 @@ class CreateImg:
self.paste_image_height = int(paste_image_height)
self.current_w = 0
self.current_h = 0
self.font = ImageFont.truetype(TTF_PATH + ttf, int(font_size))
self.font = ImageFont.truetype(FONT_PATH + font, int(font_size))
if not plain_text and not color:
color = (255, 255, 255)
if not background:
if plain_text:
if not color:
color = (255, 255, 255, 0)
ttf_w, ttf_h = self.getsize(plain_text)
self.w = self.w if self.w > ttf_w else ttf_w
self.h = self.h if self.h > ttf_h else ttf_h
@@ -204,7 +211,7 @@ class CreateImg:
for i in range(w):
for j in range(h):
pos = array[i, j]
is_edit = (sum([1 for x in pos[0:3] if x > 240]) == 3)
is_edit = sum([1 for x in pos[0:3] if x > 240]) == 3
if is_edit:
array[i, j] = (255, 255, 255, 0)
self.draw = ImageDraw.Draw(self.markImg)
@@ -302,7 +309,11 @@ class CreateImg:
self.draw.ellipse(pos, fill, outline, width)
def text(
self, pos: Tuple[int, int], text: str, fill: Tuple[int, int, int] = (0, 0, 0), center_type: Optional[str] = None
self,
pos: Tuple[int, int],
text: str,
fill: Tuple[int, int, int] = (0, 0, 0),
center_type: Optional[str] = None,
):
"""
说明:
@@ -320,23 +331,27 @@ class CreateImg:
)
w, h = self.w, self.h
ttf_w, ttf_h = self.getsize(text)
if center_type == 'center':
if center_type == "center":
w = int((w - ttf_w) / 2)
h = int((h - ttf_h) / 2)
elif center_type == 'by_width':
elif center_type == "by_width":
w = int((w - ttf_w) / 2)
elif center_type == 'by_height':
h = pos[1]
elif center_type == "by_height":
h = int((h - ttf_h) / 2)
w = pos[0]
pos = (w, h)
self.draw.text(pos, text, fill=fill, font=self.font)
def save(self, path: str):
def save(self, path: Union[str, Path]):
"""
说明:
保存图片
参数:
:param path: 图片路径
"""
if isinstance(path, Path):
path = path.absolute()
self.markImg.save(path)
def show(self):
@@ -478,9 +493,519 @@ class CreateImg:
pim_b[i - (r - r3), j - (r - r3)] = pim_a[i, j]
self.markImg = imb
def circle_corner(self, radii: int = 30):
"""
说明:
矩形四角变圆
参数:
:param radii: 半径
"""
# 画圆(用于分离4个角)
circle = Image.new('L', (radii * 2, radii * 2), 0)
draw = ImageDraw.Draw(circle)
draw.ellipse((0, 0, radii * 2, radii * 2), fill=255)
self.markImg = self.markImg.convert("RGBA")
w, h = self.markImg.size
alpha = Image.new('L', self.markImg.size, 255)
alpha.paste(circle.crop((0, 0, radii, radii)), (0, 0))
alpha.paste(circle.crop((radii, 0, radii * 2, radii)), (w - radii, 0))
alpha.paste(circle.crop((radii, radii, radii * 2, radii * 2)), (w - radii, h - radii))
alpha.paste(circle.crop((0, radii, radii, radii * 2)), (0, h - radii))
self.markImg.putalpha(alpha)
def rotate(self, angle: int):
"""
说明:
旋转图片
参数:
:param angle: 角度
"""
self.markImg = self.markImg.rotate(angle)
def filter(self, filter_: str, aud: int = None):
"""
图片变化
:param filter_: 变化效果
:param aud: 利率
"""
_x = None
if filter_ == 'GaussianBlur': # 高斯模糊
_x = ImageFilter.GaussianBlur
elif filter_ == 'EDGE_ENHANCE': # 锐化效果
_x = ImageFilter.EDGE_ENHANCE
elif filter_ == 'BLUR': # 模糊效果
_x = ImageFilter.BLUR
elif filter_ == 'CONTOUR': # 铅笔滤镜
_x = ImageFilter.CONTOUR
elif filter_ == 'FIND_EDGES': # 边缘检测
_x = ImageFilter.FIND_EDGES
if _x:
if aud:
self.markImg = self.markImg.filter(_x(aud))
else:
self.markImg = self.markImg.filter(_x)
#
def getchannel(self, itype):
self.markImg = self.markImg.getchannel(itype)
def getchannel(self, type_):
self.markImg = self.markImg.getchannel(type_)
class CreateMat:
"""
针对 折线图/柱状图,基于 CreateImg 编写的 非常难用的 自定义画图工具
目前仅支持 正整数
"""
def __init__(
self,
y: List[int],
mat_type: str = "line",
*,
x_name: Optional[str] = None,
y_name: Optional[str] = None,
x_index: List[Union[str, int, float]] = None,
y_index: List[Union[str, int, float]] = None,
title: Optional[str] = None,
size: Tuple[int, int] = (1000, 1000),
font_size: int = 20,
display_num: bool = False,
is_grid: bool = False,
background: Optional[List[str]] = None,
background_filler_type: Optional[str] = "center",
bar_color: Optional[List[Union[str, Tuple[int, int, int]]]] = None,
):
"""
说明:
初始化 CreateMat
参数:
:param y: 坐标值
:param mat_type: 图像类型 可能的值:[line]: 折线图,[bar]: 柱状图,[barh]: 横向柱状图
:param x_name: 横坐标名称
:param y_name: 纵坐标名称
:param x_index: 横坐标值
:param y_index: 纵坐标值
:param title: 标题
:param size: 图像大小,建议默认
:param font_size: 字体大小,建议默认
:param display_num: 是否显示数值
:param is_grid: 是否添加栅格
:param background: 背景图片
:param background_filler_type: 图像填充类型
:param bar_color: 柱状图颜色,位 ['*'] 时替换位彩虹随机色
"""
self.mat_type = mat_type
self.markImg = None
self._check_value(y, y_index)
self.w = size[0]
self.h = size[1]
self.y = y
self.x_name = x_name
self.y_name = y_name
self.x_index = x_index
self.y_index = y_index
self.title = title
self.font_size = font_size
self.display_num = display_num
self.is_grid = is_grid
self.background = background
self.background_filler_type = background_filler_type
self.bar_color = bar_color if bar_color else [(0, 0, 0)]
self.size = size
self.padding_w = 120
self.padding_h = 120
self.line_length = 760
self._deviation = 0.905
self._color = {}
if self.bar_color == ["*"]:
self.bar_color = [
"#FF0000",
"#FF7F00",
"#FFFF00",
"#00FF00",
"#00FFFF",
"#0000FF",
"#8B00FF",
]
if not x_index:
raise ValueError("缺少 x_index [横坐标值]...")
self._x_interval = int((self.line_length - 70) / len(x_index))
self._bar_width = int(
(self.line_length - (len(x_index) * (10 if len(x_index) >= 18 else 25)))
/ len(x_index)
)
# 没有 y_index 时自动生成
if not y_index:
_y_index = []
_max_value = max(y)
_max_value = ceil(
_max_value / eval("1" + "0" * (len(str(_max_value)) - 1))
) * eval("1" + "0" * (len(str(_max_value)) - 1))
_step = int(_max_value / 10)
for i in range(_step, _max_value + _step, _step):
_y_index.append(i)
self.y_index = _y_index
self._p = self.line_length / max(self.y_index)
self._y_interval = int((self.line_length - 70) / len(self.y_index))
def gen_graph(self):
"""
说明:
生成图像
"""
self.markImg = self._init_graph(
x_name=self.x_name,
y_name=self.y_name,
x_index=self.x_index,
y_index=self.y_index,
font_size=self.font_size,
is_grid=self.is_grid,
)
if self.mat_type == "line":
self._gen_line_graph(y=self.y, display_num=self.display_num)
elif self.mat_type == "bar":
self._gen_bar_graph(y=self.y, display_num=self.display_num)
elif self.mat_type == "barh":
self._gen_bar_graph(y=self.y, display_num=self.display_num, is_barh=True)
def set_y(self, y: List[int]):
"""
说明:
给坐标点设置新值
参数:
:param y: 坐标点
"""
self._check_value(y, self.y_index)
self.y = y
def set_y_index(self, y_index: List[Union[str, int, float]]):
"""
说明:
设置y轴坐标值
参数:
:param y_index: y轴坐标值
"""
self._check_value(self.y, y_index)
self.y_index = y_index
def set_title(self, title: str, color: Optional[Union[str, Tuple[int, int, int]]]):
"""
说明:
设置标题
参数:
:param title: 标题
:param color: 字体颜色
"""
self.title = title
if color:
self._color["title"] = color
def set_background(
self, background: Optional[List[str]], type_: Optional[str] = None
):
"""
说明:
设置背景图片
参数:
:param background: 图片路径列表
:param type_: 填充类型
"""
self.background = background
self.background_filler_type = type_ if type_ else self.background_filler_type
def show(self):
"""
说明:
展示图像
"""
self.markImg.show()
def pic2bs4(self) -> str:
"""
说明:
转base64
"""
return self.markImg.pic2bs4()
def resize(self, ratio: float = 0.9):
"""
说明:
调整图像大小
参数:
:param ratio: 比例
"""
self.markImg.resize(ratio)
def save(self, path: Union[str, Path]):
"""
说明:
保存图片
参数:
:param path: 路径
"""
self.markImg.save(path)
def _check_value(
self,
y: List[int],
y_index: List[Union[str, int, float]] = None,
x_index: List[Union[str, int, float]] = None,
):
"""
说明:
检查值合法性
参数:
:param y: 坐标值
:param y_index: y轴坐标值
:param x_index: x轴坐标值
"""
if y_index:
_value = x_index if self.mat_type == "barh" else y_index
if max(y) > max(y_index):
raise ValueError("坐标点的值必须小于y轴坐标的最大值...")
i = -9999999999
for y in y_index:
if y > i:
i = y
else:
raise ValueError("y轴坐标值必须有序...")
def _gen_line_graph(
self,
y: List[Union[int, float]],
display_num: bool = False,
):
"""
说明:
生成折线图
参数:
:param y: 坐标点
:param display_num: 显示该点的值
"""
_black_point = CreateImg(7, 7, color=random.choice(self.bar_color))
_black_point.circle()
x_interval = self._x_interval
current_w = self.padding_w + x_interval
current_h = self.padding_h + self.line_length
for i in range(len(y)):
if display_num:
w = int(self.markImg.getsize(str(y[i]))[0] / 2)
self.markImg.text(
(
current_w - w,
current_h - int(y[i] * self._p * self._deviation) - 25,
),
str(y[i]),
)
self.markImg.paste(
_black_point,
(
current_w - 3,
current_h - int(y[i] * self._p * self._deviation) - 3,
),
True,
)
if i != len(y) - 1:
self.markImg.line(
(
current_w,
current_h - int(y[i] * self._p * self._deviation),
current_w + x_interval,
current_h - int(y[i + 1] * self._p * self._deviation),
),
fill=(0, 0, 0),
width=2,
)
current_w += x_interval
def _gen_bar_graph(
self,
y: List[Union[int, float]],
display_num: bool = False,
is_barh: bool = False,
):
"""
说明:
生成柱状图
参数:
:param y: 坐标值
:param display_num: 是否显示数值
:param is_barh: 横柱状图
"""
_interval = self._x_interval
if is_barh:
current_h = self.padding_h + self.line_length - _interval
current_w = self.padding_w
else:
current_w = self.padding_w + _interval
current_h = self.padding_h + self.line_length
for i in range(len(y)):
if display_num:
if is_barh:
font_h = self.markImg.getsize(str(y[i]))[1]
self.markImg.text(
(
self.padding_w + int(y[i] * self._p * self._deviation) + 2,
current_h - int(font_h / 2),
),
str(y[i]),
)
else:
w = int(self.markImg.getsize(str(y[i]))[0] / 2)
self.markImg.text(
(
current_w - w,
current_h - int(y[i] * self._p * self._deviation) - 25,
),
str(y[i]),
)
if i != len(y):
bar_color = random.choice(self.bar_color)
if is_barh:
A = CreateImg(
int(y[i] * self._p * self._deviation),
self._bar_width,
color=bar_color,
)
self.markImg.paste(
A,
(
current_w + 2,
current_h - int(self._bar_width / 2),
),
)
else:
A = CreateImg(
self._bar_width,
int(y[i] * self._p * self._deviation),
color=bar_color,
)
self.markImg.paste(
A,
(
current_w - int(self._bar_width / 2),
current_h - int(y[i] * self._p * self._deviation),
),
)
if is_barh:
current_h -= _interval
else:
current_w += _interval
def _init_graph(
self,
x_name: Optional[str] = None,
y_name: Optional[str] = None,
x_index: List[Union[str, int, float]] = None,
y_index: List[Union[str, int, float]] = None,
font_size: Optional[int] = None,
is_grid: bool = False,
) -> CreateImg:
"""
说明:
初始化图像,生成xy轴
参数:
:param x_name: x轴名称
:param y_name: y轴名称
:param x_index: x轴坐标值
:param y_index: y轴坐标值
:param is_grid: 添加栅格
"""
padding_w = self.padding_w
padding_h = self.padding_h
line_length = self.line_length
background = random.choice(self.background) if self.background else None
A = CreateImg(self.w, self.h, font_size=font_size, background=background)
if background:
_tmp = CreateImg(self.w, self.h)
_tmp.transparent(2)
A.paste(_tmp, alpha=True)
if self.title:
title = CreateImg(
0,
0,
plain_text=self.title,
color=(255, 255, 255, 0),
font_size=35,
font_color=self._color.get("title"),
)
A.paste(title, (0, 25), True, "by_width")
A.line(
(
padding_w,
padding_h + line_length,
padding_w + line_length,
padding_h + line_length,
),
(0, 0, 0),
2,
)
A.line(
(
padding_w,
padding_h,
padding_w,
padding_h + line_length,
),
(0, 0, 0),
2,
)
_interval = self._x_interval
if self.mat_type == "barh":
tmp = x_index
x_index = y_index
y_index = tmp
_interval = self._y_interval
current_w = padding_w + _interval
_text_font = CreateImg(0, 0, font_size=self.font_size)
_grid = self.line_length if is_grid else 10
for _x in x_index:
_p = CreateImg(1, _grid, color="#a9a9a9")
A.paste(_p, (current_w, padding_h + line_length - _grid))
w = int(_text_font.getsize(f"{_x}")[0] / 2)
text = CreateImg(
0,
0,
plain_text=f"{_x}",
font_size=self.font_size,
color=(255, 255, 255, 0),
)
A.paste(text, (current_w - w, padding_h + line_length + 10), alpha=True)
current_w += _interval
_interval = self._x_interval if self.mat_type == "barh" else self._y_interval
current_h = padding_h + line_length - _interval
_text_font = CreateImg(0, 0, font_size=self.font_size)
for _y in y_index:
_p = CreateImg(_grid, 1, color="#a9a9a9")
A.paste(_p, (padding_w, current_h))
w, h = _text_font.getsize(f"{_y}")
h = int(h / 2)
text = CreateImg(
0,
0,
plain_text=f"{_y}",
font_size=self.font_size,
color=(255, 255, 255, 0),
)
while text.size[0] > self.padding_w - 10:
text = CreateImg(
0,
0,
plain_text=f"{_y}",
font_size=int(self.font_size * 0.9),
color=(255, 255, 255, 0),
)
w, _ = text.getsize(f"{_y}")
A.paste(text, (padding_w - w - 10, current_h - h), alpha=True)
current_h -= _interval
if x_name:
A.text((int(padding_w / 2), int(padding_w / 2)), x_name)
if y_name:
A.text(
(int(padding_w + line_length + 50), int(padding_h + line_length + 50)),
y_name,
)
# A.show()
return A
if __name__ == "__main__":
+35
View File
@@ -0,0 +1,35 @@
from typing import Optional
from .group_manager import GroupManager
from pathlib import Path
from .withdraw_message_manager import WithdrawMessageManager
from .plugins2cd_manager import Plugins2cdManager
from .plugins2block_manager import Plugins2blockManager
from .plugins2settings_manager import Plugins2settingsManager
from configs.path_config import DATA_PATH
from nonebot import Driver
import nonebot
driver: Driver = nonebot.get_driver()
# 群功能开关 | 群被动技能 | 群权限 管理
group_manager: Optional[GroupManager] = GroupManager(
Path(DATA_PATH) / "manager" / "group_manager.json"
)
# 撤回消息管理
withdraw_message_manager: Optional[WithdrawMessageManager] = WithdrawMessageManager()
# 插件基本设置管理
plugins2settings_manager: Optional[Plugins2settingsManager] = Plugins2settingsManager(
Path(DATA_PATH) / "configs" / "plugins2settings.yaml"
)
# 插件命令 cd 管理
plugins2cd_manager: Optional[Plugins2cdManager] = Plugins2cdManager(
Path(DATA_PATH) / "configs" / "plugins2cd.yaml"
)
# 插件命令 阻塞 管理
plugins2block_manager: Optional[Plugins2blockManager] = Plugins2blockManager(
Path(DATA_PATH) / "configs" / "plugins2block.yaml"
)
+64
View File
@@ -0,0 +1,64 @@
from typing import Union, Optional
from pathlib import Path
from ruamel.yaml import YAML
import ujson as json
yaml = YAML(typ="safe")
class StaticData:
"""
静态数据共享类
"""
def __init__(self, file: Optional[Path]):
self._data = {}
if file:
file.parent.mkdir(exist_ok=True, parents=True)
self.file = file
if file.exists():
self._data: dict = json.load(open(file, "r", encoding="utf8"))
def set(self, key, value):
self._data[key] = value
def get(self, key):
return self._data.get(key)
def keys(self):
return self._data.keys()
def delete(self, key):
if self._data.get(key) is not None:
del self._data[key]
def get_data(self):
return self._data
def save(self, path: Union[str, Path] = None):
path = path if path else self.file
with open(path, "w", encoding="utf8") as f:
json.dump(self._data, f, ensure_ascii=False, indent=4)
def reload(self):
if self.file.exists():
if self.file.name.endswith('json'):
self._data: dict = json.load(open(self.file, "r", encoding="utf8"))
elif self.file.name.endswith('yaml'):
self._data: dict = yaml.load(open(self.file, "r", encoding="utf8"))
def is_exists(self):
return self.file.exists()
def is_empty(self):
return bool(len(self._data))
def __str__(self):
return str(self._data)
def __setitem__(self, key, value):
self._data[key] = value
def __getitem__(self, key):
return self._data[key]
+319
View File
@@ -0,0 +1,319 @@
from configs.config import DEFAULT_GROUP_LEVEL
from typing import Optional, List, Union, Dict
from pathlib import Path
from .data_class import StaticData
from utils.utils import get_matchers, get_bot
import nonebot
class GroupManager(StaticData):
"""
群权限 | 功能 | 聊天时间 管理器
"""
def __init__(self, file: Path):
super().__init__(file)
if not self._data:
self._data = {
"super": {"close_plugins": {}, "white_group_list": []},
"group_manager": {},
}
self._task = {}
def block_plugin(
self, plugin_cmd: str, group_id: Optional[int] = None, block_type: str = "all"
):
"""
说明:
锁定插件
参数:
:param plugin_cmd: 功能模块名
:param group_id: 群组,None时为超级用户禁用
:param block_type: 限制类型
"""
self._set_plugin_status(plugin_cmd, "block", group_id, block_type)
def unblock_plugin(self, plugin_cmd: str, group_id: Optional[int] = None):
"""
说明:
解锁插件
参数:
:param plugin_cmd: 功能模块名
:param group_id: 群组
"""
self._set_plugin_status(plugin_cmd, "unblock", group_id)
def set_group_level(self, group_id: int, level: int):
"""
说明:
设置群权限
参数:
:param group_id: 群组
:param level: 权限等级
"""
group_id = str(group_id)
if not self._data["group_manager"].get(group_id):
self._init_group(group_id)
self._data["group_manager"][group_id]["level"] = level
self.save()
def get_plugin_status(
self, plugin_cmd: str, group_id: Optional[int] = None, block_type: str = "all"
) -> bool:
"""
说明:
获取插件状态
参数:
:param plugin_cmd: 功能模块名
:param group_id: 群组
:param block_type: 限制类型
"""
group_id = str(group_id) if group_id else group_id
if group_id:
if not self._data["group_manager"].get(group_id):
self._init_group(group_id)
return True
if plugin_cmd in self._data["group_manager"][group_id]["close_plugins"]:
return False
return True
else:
if plugin_cmd in self._data["super"]["close_plugins"]:
if (
self._data["super"]["close_plugins"][plugin_cmd] == "all"
and block_type == "all"
):
return False
else:
return (
not self._data["super"]["close_plugins"][plugin_cmd]
== block_type
)
return True
def get_plugin_block_type(self, plugin_cmd: str) -> str:
"""
说明:
获取功能限制类型
参数:
:param plugin_cmd: 模块名称
"""
if plugin_cmd in self._data["super"]["close_plugins"]:
return self._data["super"]["close_plugins"][plugin_cmd]
return ""
def get_group_level(self, group_id: int) -> int:
"""
说明:
获取群等级
参数:
:param group_id: 群号
"""
group_id = str(group_id)
if not self._data["group_manager"].get(group_id):
self._init_group(group_id)
return self._data["group_manager"][group_id]["level"]
def check_group_is_white(self, group_id: int) -> bool:
"""
说明:
检测群聊是否在白名单
参数:
:param group_id: 群号
"""
return group_id in self._data["super"]["white_group_list"]
def add_group_white_list(self, group_id: int):
"""
说明:
将群聊加入白名单
参数:
:param group_id: 群号
"""
if group_id not in self._data["super"]["white_group_list"]:
self._data["super"]["white_group_list"].append(group_id)
def delete_group_white_list(self, group_id: int):
"""
说明:
将群聊从白名单中删除
参数:
:param group_id: 群号
"""
if group_id in self._data["super"]["white_group_list"]:
self._data["super"]["white_group_list"].remove(group_id)
def get_group_white_list(self) -> List[str]:
"""
说明:
获取所有群白名单
"""
return self._data["super"]["white_group_list"]
async def open_group_task(self, group_id: int, task: str):
"""
开启群被动技能
:param group_id: 群号
:param task: 被动技能名称
"""
await self._set_group_task_status(group_id, task, True)
async def close_group_task(self, group_id: int, task: str):
"""
关闭群被动技能
:param group_id: 群号
:param task: 被动技能名称
"""
await self._set_group_task_status(group_id, task, False)
async def check_group_task_status(self, group_id: int, task: str) -> bool:
"""
查看群被动技能状态
:param group_id: 群号
:param task: 被动技能名称
"""
group_id = str(group_id)
if (
not self._data["group_manager"][group_id].get("group_task_status")
or self._data["group_manager"][group_id]["group_task_status"].get(task)
is None
):
await self.init_group_task(group_id)
return self._data["group_manager"][group_id]["group_task_status"][task]
def get_task_data(self) -> Dict[str, str]:
return self._task
async def group_task_status(self, group_id: int) -> str:
"""
查看群被全部动技能状态
:param group_id: 群号
"""
x = '[群被动技能]:\n'
group_id = str(group_id)
if not self._data["group_manager"][group_id].get("group_task_status"):
await self.init_group_task(group_id)
for key in self._data["group_manager"][group_id]["group_task_status"].keys():
x += f'{self._task[key]}:{"√" if await self.check_group_task_status(int(group_id), key) else "×"}\n'
return x[:-1]
async def _set_group_task_status(self, group_id: int, task: str, status: bool):
"""
管理群被动技能状态
:param group_id: 群号
:param task: 被动技能
:param status: 状态
"""
group_id = str(group_id)
if not self._data["group_manager"].get(group_id):
self._init_group(group_id)
if (
not self._data["group_manager"][group_id].get("group_task_status")
or self._data["group_manager"][group_id]["group_task_status"].get(task)
is None
):
await self.init_group_task(group_id)
self._data["group_manager"][group_id]["group_task_status"][task] = status
self.save()
async def init_group_task(self, group_id: Optional[Union[int, str]] = None):
"""
初始化群聊 被动技能 状态
"""
if not self._task:
for matcher in get_matchers():
_plugin = nonebot.plugin.get_plugin(matcher.module)
_module = _plugin.module
try:
plugin_task = _module.__getattribute__("__plugin_task__")
for key in plugin_task.keys():
self._task[key] = plugin_task[key]
except AttributeError:
pass
bot = get_bot()
if bot or group_id:
if group_id:
_group_list = [group_id]
else:
_group_list = [x["group_id"] for x in await bot.get_group_list()]
for group_id in _group_list:
group_id = str(group_id)
if not self._data["group_manager"].get(group_id):
self._init_group(group_id)
if not self._data["group_manager"][group_id].get("group_task_status"):
self._data["group_manager"][group_id]['group_task_status'] = {}
for task in self._task:
if (
self._data["group_manager"][group_id][
"group_task_status"
].get(task)
is None
):
self._data["group_manager"][group_id]["group_task_status"][
task
] = True
for task in self._data["group_manager"][group_id]["group_task_status"]:
if task not in self._task:
del self._data["group_manager"][group_id]["group_task_status"][
task
]
self.save()
def _set_plugin_status(
self,
plugin_cmd: str,
status: str,
group_id: Optional[str],
block_type: str = "all",
):
"""
说明:
设置功能开关状态
参数:
:param plugin_cmd: 功能模块名
:param status: 功能状态
:param group_id: 群组
:param block_type: 限制类型
"""
group_id = str(group_id) if group_id else group_id
if plugin_cmd:
if group_id:
if not self._data["group_manager"].get(group_id):
self._init_group(group_id)
if status == "block":
if (
plugin_cmd
not in self._data["group_manager"][group_id]["close_plugins"]
):
self._data["group_manager"][group_id]["close_plugins"].append(
plugin_cmd
)
else:
if plugin_cmd in self._data["group_manager"][group_id]["close_plugins"]:
self._data["group_manager"][group_id]["close_plugins"].remove(
plugin_cmd
)
else:
if status == "block":
if (
plugin_cmd not in self._data["super"]["close_plugins"]
or block_type != self._data["super"]["close_plugins"][plugin_cmd]
):
self._data["super"]["close_plugins"][plugin_cmd] = block_type
else:
if plugin_cmd in self._data["super"]["close_plugins"]:
del self._data["super"]["close_plugins"][plugin_cmd]
self.save()
def _init_group(self, group_id: str):
"""
说明:
初始化群数据
参数:
:param group_id: 群号
"""
if not self._data["group_manager"].get(group_id):
self._data["group_manager"][group_id] = {
"level": DEFAULT_GROUP_LEVEL,
"close_plugins": [],
"group_task_status": {},
}
+132
View File
@@ -0,0 +1,132 @@
from typing import Optional, Dict
from .data_class import StaticData
from services.log import logger
from utils.utils import UserBlockLimiter
from pathlib import Path
from ruamel.yaml import YAML
yaml = YAML(typ="safe")
class Plugins2blockManager(StaticData):
"""
插件命令阻塞 管理器
"""
def __init__(self, file: Path):
self.file = file
super().__init__(None)
self._block_limiter: Dict[str, UserBlockLimiter] = {}
def add_block_limit(
self,
plugin: str,
status: Optional[bool] = True,
check_type: Optional[str] = "all",
limit_type: Optional[str] = "user",
rst: Optional[str] = None,
data_dict: Optional[dict] = None,
):
"""
添加插件调用 block 限制
:param plugin: 插件模块名称
:param status: 默认开关状态
:param check_type: 检查类型 'private'/'group'/'all',限制私聊/群聊/全部
:param limit_type: 限制类型 监听对象,以user_id或group_id作为键来限制,'user':用户id,'group':群id
:param rst: 回复的话,为空则不回复
:param data_dict: 封装好的字典数据
"""
if data_dict:
status = data_dict.get('status')
check_type = data_dict.get('check_type')
limit_type = data_dict.get('limit_type')
rst = data_dict.get('rst')
status = status if status is not None else True
check_type = check_type if check_type else 'all'
limit_type = limit_type if limit_type else 'user'
if check_type not in ["all", "group", "private"]:
raise ValueError(
f"{plugin} 添加block限制错误,‘check_type‘ 必须为 'private'/'group'/'all'"
)
if limit_type not in ["user", "group"]:
raise ValueError(f"{plugin} 添加block限制错误,‘limit_type‘ 必须为 'user'/'group'")
self._data[plugin] = {
"status": status,
"check_type": check_type,
"limit_type": limit_type,
"rst": rst,
}
def remove_block_limit(self, plugin: str):
"""
删除一个插件 block 限制
:param plugin: 插件模块名称
"""
if self._data.get(plugin):
del self._data[plugin]
def get_plugin_block_data(self, plugin: str) -> Optional[dict]:
"""
获取插件block数据
:param plugin: 模块名
"""
if self.check_plugin_block_status(plugin):
return self._data[plugin]
return None
def check_plugin_block_status(self, plugin: str) -> bool:
"""
检测插件是否有 block
:param plugin: 模块名
"""
return (
plugin in self._data.keys()
and self._data[plugin]["status"]
)
def check(self, id_: int, plugin: str) -> bool:
"""
检查 block
:param plugin: 模块名
:param id_: 限制 id
"""
if self._block_limiter.get(plugin):
return self._block_limiter[plugin].check(id_)
return False
def set_true(self, id_: int, plugin: str):
"""
对插件 block
:param plugin: 模块名
:param id_: 限制 id
"""
if self._block_limiter.get(plugin):
self._block_limiter[plugin].set_true(id_)
def set_false(self, id_: int, plugin: str):
"""
对插件 unblock
:param plugin: 模块名
:param id_: 限制 id
"""
if self._block_limiter.get(plugin):
self._block_limiter[plugin].set_false(id_)
def reload_block_limit(self):
"""
加载 block 限制器
:return:
"""
for plugin in self._data:
if self.check_plugin_block_status(plugin):
self._block_limiter[plugin] = UserBlockLimiter()
logger.info(f'已成功加载 {len(self._block_limiter)} 个Block限制.')
def reload(self):
"""
重载本地数据
"""
if self.file.exists():
with open(self.file, "r", encoding="utf8") as f:
self._data: dict = yaml.load(f)
self._data = self._data['PluginBlockLimit']
self.reload_block_limit()
+144
View File
@@ -0,0 +1,144 @@
from typing import Optional, Dict
from .data_class import StaticData
from utils.utils import FreqLimiter
from services.log import logger
from pathlib import Path
from ruamel.yaml import YAML
yaml = YAML(typ="safe")
class Plugins2cdManager(StaticData):
"""
插件命令 cd 管理器
"""
def __init__(self, file: Path):
self.file = file
super().__init__(None)
self._freq_limiter: Dict[str, FreqLimiter] = {}
def add_cd_limit(
self,
plugin: str,
*,
cd: Optional[int] = 5,
status: Optional[bool] = True,
check_type: Optional[str] = "all",
limit_type: Optional[str] = "user",
rst: Optional[str] = None,
data_dict: Optional[dict] = None,
):
"""
添加插件调用 cd 限制
:param plugin: 插件模块名称
:param cd: cd 时长
:param status: 默认开关状态
:param check_type: 检查类型 'private'/'group'/'all',限制私聊/群聊/全部
:param limit_type: 限制类型 监听对象,以user_id或group_id作为键来限制,'user':用户id,'group':群id
:param rst: 回复的话,为空则不回复
:param data_dict: 封装好的字典数据
"""
if data_dict:
cd = data_dict.get('cd')
status = data_dict.get('status')
check_type = data_dict.get('check_type')
limit_type = data_dict.get('limit_type')
rst = data_dict.get('rst')
cd = cd if cd is not None else 5
status = status if status is not None else True
check_type = check_type if check_type else 'all'
limit_type = limit_type if limit_type else 'user'
if check_type not in ["all", "group", "private"]:
raise ValueError(
f"{plugin} 添加cd限制错误,‘check_type‘ 必须为 'private'/'group'/'all'"
)
if limit_type not in ["user", "group"]:
raise ValueError(f"{plugin} 添加cd限制错误,‘limit_type‘ 必须为 'user'/'group'")
self._data[plugin] = {
"cd": cd,
"status": status,
"check_type": check_type,
"limit_type": limit_type,
"rst": rst,
}
def remove_cd_limit(self, plugin: str):
"""
删除一个插件 cd 限制
:param plugin: 插件模块名称
"""
if self._data.get(plugin):
del self._data[plugin]
def get_plugin_cd_data(self, plugin: str) -> Optional[dict]:
"""
获取插件cd数据
:param plugin: 模块名
"""
if self.check_plugin_cd_status(plugin):
return self._data[plugin]
return None
def check_plugin_cd_status(self, plugin: str) -> bool:
"""
检测插件是否有 cd
:param plugin: 模块名
"""
return (
plugin in self._data.keys()
and self._data[plugin]["cd"] > 0
and self._data[plugin]["status"]
)
def check(self, plugin: str, id_: int) -> bool:
"""
检查 cd
:param plugin: 模块名
:param id_: 限制 id
"""
if self._freq_limiter.get(plugin):
return self._freq_limiter[plugin].check(id_)
return False
def start_cd(self, plugin: str, id_: int, cd: int = 0):
"""
开始cd
:param plugin: 模块名
:param id_: cd 限制类型
:param cd: cd 时长
:return:
"""
if self._freq_limiter.get(plugin):
self._freq_limiter[plugin].start_cd(id_, cd)
def get_plugin_data(self, plugin: str) -> dict:
"""
获取单个模块限制数据
:param plugin: 模块名
"""
if self._data.get(plugin) is not None:
return self._data.get(plugin)
return {}
def reload_cd_limit(self):
"""
加载 cd 限制器
:return:
"""
for plugin in self._data:
if self.check_plugin_cd_status(plugin):
self._freq_limiter[plugin] = FreqLimiter(self.get_plugin_cd_data(plugin)['cd'])
logger.info(f'已成功加载 {len(self._freq_limiter)} 个Cd限制.')
def reload(self):
"""
重载本地数据
"""
if self.file.exists():
with open(self.file, "r", encoding="utf8") as f:
self._data: dict = yaml.load(f)
self._data = self._data['PluginCdLimit']
self.reload_cd_limit()
+102
View File
@@ -0,0 +1,102 @@
from typing import List, Optional, Union, Tuple
from .data_class import StaticData
from pathlib import Path
from ruamel.yaml import YAML
yaml = YAML(typ="safe")
class Plugins2settingsManager(StaticData):
"""
插件命令阻塞 管理器
"""
def __init__(self, file: Path):
self.file = file
super().__init__(None)
def add_plugin_settings(
self,
plugin: str,
cmd: Optional[List[str]] = None,
default_status: Optional[bool] = True,
level: Optional[int] = 5,
limit_superuser: Optional[bool] = False,
plugin_type: Tuple[Union[str, int]] = ("normal",),
data_dict: Optional[dict] = None,
):
"""
添加一个插件设置
:param plugin: 插件模块名称
:param cmd: 命令 或 命令别名
:param default_status: 默认开关状态
:param level: 功能权限等级
:param limit_superuser: 功能状态是否限制超级用户
:param plugin_type: 插件类型
:param data_dict: 封装好的字典数据
"""
if data_dict:
level = data_dict.get("level") if data_dict.get("level") is not None else 5
default_status = (
data_dict.get("default_status")
if data_dict.get("default_status") is not None
else True
)
limit_superuser = (
data_dict.get("limit_superuser")
if data_dict.get("limit_superuser") is not None
else False
)
cmd = data_dict.get("cmd") if data_dict.get("cmd") is not None else []
self._data[plugin] = {
"level": level if level is not None else 5,
"default_status": default_status if default_status is not None else True,
"limit_superuser": limit_superuser
if limit_superuser is not None
else False,
"cmd": cmd,
"plugin_type": list(plugin_type if plugin_type is not None else ("normal",))
}
def remove_plugin_settings(self, plugin: str):
"""
删除一个插件设置
:param plugin: 插件模块名称
"""
if self._data.get(plugin):
del self._data[plugin]
def get_plugin_data(self, module: str) -> dict:
"""
通过模块名获取数据
:param module: 模块名称
"""
if self._data.get(module) is not None:
return self._data.get(module)
return {}
def get_plugin_module(
self, cmd: str, is_all: bool = False
) -> Union[str, List[str]]:
"""
根据 cmd 获取功能 module
:param cmd: 命令
:param is_all: 获取全部包含cmd的模块
"""
keys = []
for key in self._data.keys():
if cmd in self._data[key]["cmd"]:
if is_all:
keys.append(key)
else:
return key
return keys
def reload(self):
"""
重载本地数据
"""
if self.file.exists():
with open(self.file, "r", encoding="utf8") as f:
self._data: dict = yaml.load(f)
self._data = self._data['PluginSettings']
+28
View File
@@ -0,0 +1,28 @@
from typing import Tuple, Union, Dict
class WithdrawMessageManager:
def __init__(self):
self.data = []
def append(self, message_data: Tuple[Union[int, Dict[str, int]], int]):
"""
说明:
添加一个撤回消息id和时间
参数:
:param message_data: 撤回消息id和时间
"""
if isinstance(message_data[0], dict):
message_data = (message_data[0]['message_id'], message_data[1])
self.data.append(message_data)
def remove(self, message_data: Tuple[int, int]):
"""
说明:
删除一个数据
参数:
:param message_data: 消息id和时间
"""
self.data.remove(message_data)
+6 -3
View File
@@ -8,7 +8,7 @@ import os
def image(
img_name: Union[str, Path] = None, path: str = None, abspath: str = None, b64: str = None
) -> MessageSegment or str:
) -> Union[MessageSegment, str]:
"""
说明:
生成一个 MessageSegment.image 消息
@@ -25,11 +25,14 @@ def image(
if os.path.exists(abspath)
else ""
)
elif isinstance(img_name, Path):
if img_name.exists():
return MessageSegment.image(f"file:///{img_name.absolute()}")
logger.warning(f"图片 {img_name.absolute()}缺失...")
return ""
elif b64:
return MessageSegment.image(b64 if "base64://" in b64 else "base64://" + b64)
else:
# if isinstance(img_name, Path):
# return MessageSegment.image(img_name)
if "http" in img_name:
return MessageSegment.image(img_name)
if len(img_name.split(".")) == 1:
-14
View File
@@ -1,14 +0,0 @@
from typing import Optional
from .group_manager import GroupManager
from pathlib import Path
from .data_source import init
from .data_class import StaticData
# 群管理
group_manager: Optional[GroupManager] = GroupManager(
Path() / "data" / "manager" / "group_manager.json"
)
withdraw_message_id_manager: Optional[StaticData] = StaticData(None)
init(group_manager)
-52
View File
@@ -1,52 +0,0 @@
from typing import Union, Optional
from pathlib import Path
import ujson as json
class StaticData:
"""
静态数据共享类
"""
def __init__(self, file: Optional[Path]):
self.data = {}
if file:
file.parent.mkdir(exist_ok=True, parents=True)
self.file = file
if file.exists():
self.data: dict = json.load(open(file, "r", encoding="utf8"))
def set(self, key, value):
self.data[key] = value
def get(self, key):
return self.data.get(key)
def delete(self, key):
if self.data.get(key) is not None:
del self.data[key]
def save(self, path: Union[str, Path] = None):
path = path if path else self.file
with open(path, "w", encoding="utf8") as f:
json.dump(self.data, f, ensure_ascii=False, indent=4)
def reload(self):
if self.file.exists():
self.data: dict = json.load(open(self.file, "r", encoding="utf8"))
def is_exists(self):
return self.file.exists()
def is_empty(self):
return bool(len(self.data))
def __str__(self):
return str(self.data)
def __setitem__(self, key, value):
self.data[key] = value
def __getitem__(self, key):
return self.data[key]
-27
View File
@@ -1,27 +0,0 @@
from pathlib import Path
import ujson as json
from .group_manager import GroupManager
def init(group_manager: GroupManager):
old_group_level_file = Path() / "data" / "manager" / "group_level.json"
old_plugin_list_file = Path() / "data" / "manager" / "plugin_list.json"
if old_group_level_file.exists():
data = json.load(open(old_group_level_file, 'r', encoding='utf8'))
for key in data.keys():
group = key
level = data[key]
group_manager.set_group_level(group, level)
old_group_level_file.unlink()
group_manager.save()
if old_plugin_list_file.exists():
data = json.load(open(old_plugin_list_file, 'r', encoding='utf8'))
for plugin in data.keys():
for group in data[plugin].keys():
if group == 'default' and not data[plugin]['default']:
group_manager.block_plugin(plugin)
elif not data[plugin][group]:
group_manager.block_plugin(plugin, group)
old_plugin_list_file.unlink()
group_manager.save()
-196
View File
@@ -1,196 +0,0 @@
from configs.config import DEFAULT_GROUP_LEVEL
from typing import Optional, List
from pathlib import Path
from .data_class import StaticData
class GroupManager(StaticData):
"""
群权限 | 功能 | 聊天时间 管理器
"""
def __init__(self, file: Path):
super().__init__(file)
if not self.data:
self.data = {"super": {"close_plugins": {}, "white_group_list": []}, "group_manager": {}}
def block_plugin(
self, plugin_cmd: str, group_id: Optional[str] = None, block_type: str = "all"
):
"""
说明:
锁定插件
参数:
:param plugin_cmd: 功能模块名
:param group_id: 群组,None时为超级用户禁用
:param block_type: 限制类型
"""
self._set_plugin_status(plugin_cmd, "block", group_id, block_type)
def unblock_plugin(self, plugin_cmd: str, group_id: Optional[str] = None):
"""
说明:
解锁插件
参数:
:param plugin_cmd: 功能模块名
:param group_id: 群组
"""
self._set_plugin_status(plugin_cmd, "unblock", group_id)
def set_group_level(self, group_id: str, level: int):
"""
说明:
设置群权限
参数:
:param group_id: 群组
:param level: 权限等级
"""
if not self.data["group_manager"].get(group_id):
self._init_group(group_id)
self.data["group_manager"][group_id]["level"] = level
self.save()
def get_plugin_status(
self, plugin_cmd: str, group_id: Optional[str] = None, block_type: str = "all"
) -> bool:
"""
说明:
获取插件状态
参数:
:param plugin_cmd: 功能模块名
:param group_id: 群组
:param block_type: 限制类型
"""
if group_id:
if not self.data["group_manager"].get(group_id):
self._init_group(group_id)
return True
if plugin_cmd in self.data["group_manager"][group_id]["close_plugins"]:
return False
return True
else:
if plugin_cmd in self.data["super"]["close_plugins"]:
if (
self.data["super"]["close_plugins"][plugin_cmd] == "all"
and block_type == "all"
):
return False
else:
return (
not self.data["super"]["close_plugins"][plugin_cmd]
== block_type
)
return True
def get_plugin_block_type(self, plugin_cmd: str) -> str:
"""
说明:
获取功能限制类型
参数:
:param plugin_cmd: 模块名称
"""
if plugin_cmd in self.data["super"]["close_plugins"]:
return self.data["super"]["close_plugins"][plugin_cmd]
return ""
def get_group_level(self, group_id: str) -> int:
"""
说明:
获取群等级
参数:
:param group_id: 群号
"""
if not self.data["group_manager"].get(group_id):
self._init_group(group_id)
return self.data["group_manager"][group_id]["level"]
def check_group_is_white(self, group_id: int) -> bool:
"""
说明:
检测群聊是否在白名单
参数:
:param group_id: 群号
"""
return group_id in self.data['super']['white_group_list']
def add_group_white_list(self, group_id: int):
"""
说明:
将群聊加入白名单
参数:
:param group_id: 群号
"""
if group_id not in self.data['super']['white_group_list']:
self.data['super']['white_group_list'].append(group_id)
def delete_group_white_list(self, group_id: int):
"""
说明:
将群聊从白名单中删除
参数:
:param group_id: 群号
"""
if group_id in self.data['super']['white_group_list']:
self.data['super']['white_group_list'].remove(group_id)
def get_group_white_list(self) -> List[str]:
"""
说明:
获取所有群白名单
"""
return self.data['super']['white_group_list']
def _set_plugin_status(
self,
plugin_cmd: str,
status: str,
group_id: Optional[str],
block_type: str = "all",
):
"""
说明:
设置功能开关状态
参数:
:param plugin_cmd: 功能模块名
:param status: 功能状态
:param group_id: 群组
:param block_type: 限制类型
"""
if group_id:
if not self.data["group_manager"].get(group_id):
self._init_group(group_id)
if status == "block":
if (
plugin_cmd
not in self.data["group_manager"][group_id]["close_plugins"]
):
self.data["group_manager"][group_id]["close_plugins"].append(
plugin_cmd
)
else:
if plugin_cmd in self.data["group_manager"][group_id]["close_plugins"]:
self.data["group_manager"][group_id]["close_plugins"].remove(
plugin_cmd
)
else:
if status == "block":
if (
plugin_cmd not in self.data["super"]["close_plugins"]
or block_type != self.data["super"]["close_plugins"][plugin_cmd]
):
self.data["super"]["close_plugins"][plugin_cmd] = block_type
else:
if plugin_cmd in self.data["super"]["close_plugins"]:
del self.data["super"]["close_plugins"][plugin_cmd]
self.save()
def _init_group(self, group_id: str):
"""
说明:
初始化群数据
参数:
:param group_id: 群号
"""
self.data["group_manager"][group_id] = {"level": DEFAULT_GROUP_LEVEL, "close_plugins": []}
+65 -40
View File
@@ -1,10 +1,11 @@
from datetime import datetime, timedelta
from collections import defaultdict
from nonebot import require
from configs.path_config import TXT_PATH
from configs.path_config import TEXT_PATH
from configs.config import SYSTEM_PROXY
from typing import List, Union, Optional
from nonebot.adapters import Bot
from typing import List, Union, Optional, Type
from nonebot.adapters.cqhttp import Bot
from nonebot.matcher import matchers, Matcher
import nonebot
import pytz
import pypinyin
@@ -39,7 +40,7 @@ class CountLimiter:
return False
class UserExistLimiter:
class UserBlockLimiter:
"""
检测用户是否正在调用命令
"""
@@ -180,6 +181,17 @@ def get_bot() -> Optional[Bot]:
return None
def get_matchers() -> List[Type[Matcher]]:
"""
获取所有插件
"""
_matchers = []
for i in matchers.keys():
for matcher in matchers[i]:
_matchers.append(matcher)
return _matchers
def get_message_at(data: str) -> List[int]:
"""
说明:
@@ -187,12 +199,15 @@ def get_message_at(data: str) -> List[int]:
参数:
:param data: event.json()
"""
qq_list = []
data = json.loads(data)
for msg in data["message"]:
if msg["type"] == "at":
qq_list.append(int(msg["data"]["qq"]))
return qq_list
try:
qq_list = []
data = json.loads(data)
for msg in data["message"]:
if msg["type"] == "at":
qq_list.append(int(msg["data"]["qq"]))
return qq_list
except KeyError:
return []
def get_message_imgs(data: str) -> List[str]:
@@ -202,12 +217,15 @@ def get_message_imgs(data: str) -> List[str]:
参数:
:param data: event.json()
"""
img_list = []
data = json.loads(data)
for msg in data["message"]:
if msg["type"] == "image":
img_list.append(msg["data"]["url"])
return img_list
try:
img_list = []
data = json.loads(data)
for msg in data["message"]:
if msg["type"] == "image":
img_list.append(msg["data"]["url"])
return img_list
except KeyError:
return []
def get_message_text(data: str) -> str:
@@ -217,12 +235,15 @@ def get_message_text(data: str) -> str:
参数:
:param data: event.json()
"""
data = json.loads(data)
result = ""
for msg in data["message"]:
if msg["type"] == "text":
result += msg["data"]["text"].strip() + " "
return result.strip()
try:
data = json.loads(data)
result = ""
for msg in data["message"]:
if msg["type"] == "text":
result += msg["data"]["text"].strip() + " "
return result.strip()
except KeyError:
return ""
def get_message_record(data: str) -> List[str]:
@@ -232,12 +253,15 @@ def get_message_record(data: str) -> List[str]:
参数:
:param data: event.json()
"""
record_list = []
data = json.loads(data)
for msg in data["message"]:
if msg["type"] == "record":
record_list.append(msg["data"]["url"])
return record_list
try:
record_list = []
data = json.loads(data)
for msg in data["message"]:
if msg["type"] == "record":
record_list.append(msg["data"]["url"])
return record_list
except KeyError:
return []
def get_message_json(data: str) -> List[dict]:
@@ -247,12 +271,15 @@ def get_message_json(data: str) -> List[dict]:
参数:
:param data: event.json()
"""
json_list = []
data = json.loads(data)
for msg in data["message"]:
if msg["type"] == "json":
json_list.append(msg["data"])
return json_list
try:
json_list = []
data = json.loads(data)
for msg in data["message"]:
if msg["type"] == "json":
json_list.append(msg["data"])
return json_list
except KeyError:
return []
# 获取文本加密后的cookie
@@ -263,7 +290,7 @@ def get_cookie_text(cookie_name: str) -> str:
参数:
:param cookie_name: cookie文件名称
"""
with open(TXT_PATH + "cookie/" + cookie_name + ".txt", "r") as f:
with open(TEXT_PATH + "cookie/" + cookie_name + ".txt", "r") as f:
return f.read()
@@ -335,11 +362,9 @@ def change_picture_links(url: str, mode: str):
:param url: 图片原图链接
:param mode: 模式
"""
if mode == 'master':
img_sp = url.rsplit('.', maxsplit=1)
if mode == "master":
img_sp = url.rsplit(".", maxsplit=1)
url = img_sp[0]
img_type = img_sp[1]
url = url.replace('original', 'master') + f'_master1200.{img_type}'
url = url.replace("original", "master") + f"_master1200.{img_type}"
return url