diff --git a/.github/publish.txt b/.github/publish.txt index dfe77b4e..64b26fba 100644 --- a/.github/publish.txt +++ b/.github/publish.txt @@ -1 +1 @@ -v6.4.4 +v6.4.5 diff --git a/.gitignore b/.gitignore index ceda7571..c0fc8210 100644 --- a/.gitignore +++ b/.gitignore @@ -11,6 +11,7 @@ .DS_Store +config/cos.yaml config/remote.yaml main*.py diff --git a/build/uploadFile.py b/build/uploadFile.py index 75fcca29..4c06e002 100644 --- a/build/uploadFile.py +++ b/build/uploadFile.py @@ -14,7 +14,8 @@ def __init__( bucket: str = None, logger_level: int = logging.DEBUG, ): - logging.basicConfig(level=logger_level, stream=sys.stdout) + if logger_level: + logging.basicConfig(level=logger_level, stream=sys.stdout) config = CosConfig(Region=region, SecretId=secret_id, SecretKey=secret_key) self.client = CosS3Client(config) @@ -43,7 +44,13 @@ def delete_file(self, files: Union[list, str]): for file in files: delete_list.append({'Key': file}) - self.client.delete_objects(Bucket=self.bucket, Delete={'Object': delete_list}) + return self.client.delete_objects( + Bucket=self.bucket, + Delete={ + 'Quiet': 'true', + 'Object': delete_list, + }, + ) def delete_folder(self, folders: Union[list, str], max_keys: int = 100): if type(folders) is not list: diff --git a/core/config/__init__.py b/core/config/__init__.py index cdd73624..b819af45 100644 --- a/core/config/__init__.py +++ b/core/config/__init__.py @@ -1 +1,2 @@ +from .cos import cos_config from .remote import remote_config diff --git a/core/config/cos.py b/core/config/cos.py new file mode 100644 index 00000000..ae102cf4 --- /dev/null +++ b/core/config/cos.py @@ -0,0 +1,18 @@ +from dataclasses import dataclass +from core.util import init_config_file + + +@dataclass +class CosConfig: + activate: bool = False + secret_id: str = '' + secret_key: str = '' + domain: str = '' + folder: str = '' + + +def init(file: str) -> CosConfig: + return init_config_file(file, CosConfig) + + +cos_config = init('config/cos.yaml') diff --git a/core/config/remote.py b/core/config/remote.py index 3dc70cec..5e836e81 100644 --- a/core/config/remote.py +++ b/core/config/remote.py @@ -1,7 +1,5 @@ -import os - -from dataclasses import dataclass, asdict, field -from core.util import read_yaml, create_yaml, merge_dict +from dataclasses import dataclass, field +from core.util import init_config_file @dataclass @@ -18,12 +16,7 @@ class RemoteConfig: def init(file: str) -> RemoteConfig: - config = {} - if os.path.exists(file): - config = read_yaml(file, _dict=True) - - create_yaml(file, merge_dict(config, asdict(RemoteConfig())), True) - return read_yaml(file) + return init_config_file(file, RemoteConfig) remote_config = init('config/remote.yaml') diff --git a/core/cosChainBuilder.py b/core/cosChainBuilder.py new file mode 100644 index 00000000..078cb59b --- /dev/null +++ b/core/cosChainBuilder.py @@ -0,0 +1,90 @@ +import os +import logging +import asyncio + +from typing import Union, Optional +from amiyabot.adapters.tencent.qqGroup import QQGroupChainBuilder, QQGroupChainBuilderOptions +from build.uploadFile import COSUploader +from core.util import run_in_thread_pool +from core.config import cos_config + + +class COSQQGroupChainBuilder(QQGroupChainBuilder): + def __init__(self, options: QQGroupChainBuilderOptions): + super().__init__(options) + + self.cos: Optional[COSUploader] = None + self.cos_caches = {} + + if cos_config.secret_id and cos_config.secret_key: + self.cos = COSUploader( + cos_config.secret_id, + cos_config.secret_key, + logger_level=logging.NOTSET, + ) + + @property + def domain(self): + return cos_config.domain + cos_config.folder + + def start(self): + ... + + def temp_filename(self, suffix: str): + path, url = super().temp_filename(suffix) + + self.cos_caches[url] = f'{cos_config.folder}/{os.path.basename(path)}' + + return path, url + + def remove_file(self, url: str): + super().remove_file(url) + + if url in self.cos_caches: + asyncio.create_task( + run_in_thread_pool( + self.cos.client.delete_object, + self.cos.bucket, + self.cos_caches[url], + ) + ) + del self.cos_caches[url] + + async def get_image(self, image: Union[str, bytes]) -> Union[str, bytes]: + if isinstance(image, str) and image.startswith('http'): + return image + + url = await super().get_image(image) + + self.cos.upload_file( + self.file_caches[url], + self.cos_caches[url], + ) + + return url + + async def get_voice(self, voice_file: str) -> str: + if voice_file.startswith('http'): + return voice_file + + url = await super().get_voice(voice_file) + + self.cos.upload_file( + self.file_caches[url], + self.cos_caches[url], + ) + + return url + + async def get_video(self, video_file: str) -> str: + if video_file.startswith('http'): + return video_file + + url = await super().get_video(video_file) + + self.cos.upload_file( + self.file_caches[url], + self.cos_caches[url], + ) + + return url diff --git a/core/database/bot.py b/core/database/bot.py index 5cbac80f..e001ab4b 100644 --- a/core/database/bot.py +++ b/core/database/bot.py @@ -1,6 +1,8 @@ from amiyabot import AmiyaBot, KOOKBotInstance from amiyabot.database import * +from core.config import cos_config from core.database import config, is_mysql +from core.cosChainBuilder import COSQQGroupChainBuilder from typing import Union from amiyabot.adapters.tencent.qqGroup import qq_group, QQGroupChainBuilderOptions @@ -82,14 +84,21 @@ def build_conf(cls, item): ) if item.adapter == 'qq_group': - conf['adapter'] = qq_group( - item.client_secret, - default_chain_builder_options=QQGroupChainBuilderOptions( - item.host or '0.0.0.0', - item.http_port or 8086, - './resource/group_temp', - ), + opt = QQGroupChainBuilderOptions( + item.host or '0.0.0.0', + item.http_port or 8086, + './resource/group_temp', ) + if cos_config.activate: + conf['adapter'] = qq_group( + item.client_secret, + default_chain_builder=COSQQGroupChainBuilder(opt), + ) + else: + conf['adapter'] = qq_group( + item.client_secret, + default_chain_builder_options=opt, + ) if item.adapter == 'websocket': conf['adapter'] = test_instance(item.host, item.ws_port) diff --git a/core/util/yamlManager.py b/core/util/yamlManager.py index 688d8d99..fc1ea6f9 100644 --- a/core/util/yamlManager.py +++ b/core/util/yamlManager.py @@ -3,8 +3,9 @@ from yaml import SafeDumper from attrdict import AttrDict +from dataclasses import asdict -from .common import create_dir +from .common import create_dir, merge_dict class YamlManager: @@ -41,3 +42,12 @@ def create_yaml(cls, path: str, data: dict, overwrite: bool = False): yaml.safe_dump(data, file, indent=4, default_flow_style=False, allow_unicode=True) return True + + +def init_config_file(file: str, build_cls): + config = {} + if os.path.exists(file): + config = YamlManager.read_yaml(file, _dict=True) + + YamlManager.create_yaml(file, merge_dict(config, asdict(build_cls())), True) + return YamlManager.read_yaml(file) diff --git a/pluginsDev b/pluginsDev index c847ccd8..a505ec02 160000 --- a/pluginsDev +++ b/pluginsDev @@ -1 +1 @@ -Subproject commit c847ccd8e5f64128f0e0aac3ff1c9668a81f1010 +Subproject commit a505ec02a09464e1dce3b3eb2c396f13cf3e40f0 diff --git a/requirements.txt b/requirements.txt index bf87161f..697864dc 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,4 +1,4 @@ -amiyabot==1.8.7 +amiyabot==1.9.0 attrdict~=2.0.1 baidu-aip dhash~=1.3