diff --git a/.gitignore b/.gitignore index 122774be..71c3837d 100644 --- a/.gitignore +++ b/.gitignore @@ -5,4 +5,6 @@ __pycache__ venv build dist -*.egg-info \ No newline at end of file +*.egg-info + +none_demo/data \ No newline at end of file diff --git a/none/__init__.py b/none/__init__.py index 1a27bc12..d18c45c9 100644 --- a/none/__init__.py +++ b/none/__init__.py @@ -3,7 +3,7 @@ import importlib import logging import os import re -from typing import Any +from typing import Any, Optional from aiocqhttp import CQHttp from aiocqhttp.message import Message @@ -13,47 +13,88 @@ from .log import logger class NoneBot(CQHttp): - def __init__(self, *args, **kwargs): - super().__init__(*args, **kwargs) - self.config = default_config + def __init__(self, config_object: Any = None): + if config_object is None: + config_object = default_config + + super_kwargs = {k.lower(): v for k, v in config_object.__dict__.items() + if k.isupper() and not k.startswith('_')} + super().__init__(message_class=Message, **super_kwargs) + + self.config = config_object + self.asgi.debug = self.config.DEBUG + + from .message import handle_message + from .notice_request import handle_notice_or_request + + @self.on_message + async def _(ctx): + asyncio.ensure_future(handle_message(self, ctx)) + + @self.on_notice + async def _(ctx): + asyncio.ensure_future(handle_notice_or_request(self, ctx)) + + @self.on_request + async def _(ctx): + asyncio.ensure_future(handle_notice_or_request(self, ctx)) + + def run(self, host=None, port=None, *args, **kwargs): + super().run(host=host, port=port, loop=asyncio.get_event_loop(), + *args, **kwargs) + + def get_data_folder(self, + *sub_folder: str) -> Optional[str]: + folder = self.config.DATA_FOLDER + if not folder: + return None + + if sub_folder: + folder = os.path.join(folder, *sub_folder) + + if not os.path.isdir(folder): + os.makedirs(folder, 0o755, exist_ok=True) + return folder + + def get_data_file(self, path: str, *others: str) -> Optional[str]: + rel_path = os.path.join(path, *others) + parent = self.get_data_folder(os.path.dirname(rel_path)) + if not parent: + return None + return os.path.join(parent, os.path.basename(rel_path)) -def create_bot(config_object: Any = None) -> NoneBot: - if config_object is None: - config_object = default_config +_bot = None - kwargs = {k.lower(): v for k, v in config_object.__dict__.items() - if k.isupper() and not k.startswith('_')} - bot = NoneBot(message_class=Message, **kwargs) - bot.config = config_object - if bot.config.DEBUG: +def init(config_object: Any = None) -> NoneBot: + global _bot + _bot = NoneBot(config_object) + if _bot.config.DEBUG: logger.setLevel(logging.DEBUG) else: logger.setLevel(logging.INFO) - bot.asgi.debug = bot.config.DEBUG + return _bot - from .message import handle_message - from .notice_request import handle_notice_or_request - @bot.on_message - async def _(ctx): - asyncio.ensure_future(handle_message(bot, ctx)) +def get_bot() -> NoneBot: + if _bot is None: + raise ValueError('NoneBot instance has not been initialized') + # noinspection PyTypeChecker + return _bot - @bot.on_notice - async def _(ctx): - asyncio.ensure_future(handle_notice_or_request(bot, ctx)) - @bot.on_request - async def _(ctx): - asyncio.ensure_future(handle_notice_or_request(bot, ctx)) - - return bot +def run(host: str = None, port: int = None, *args, **kwargs) -> None: + get_bot().run(host=host, port=port, *args, **kwargs) _plugins = set() +def clear_plugins() -> None: + _plugins.clear() + + def load_plugins(plugin_dir: str, module_prefix: str) -> None: for name in os.listdir(plugin_dir): path = os.path.join(plugin_dir, name) diff --git a/none/default_config.py b/none/default_config.py index 25bbb783..a3d6e152 100644 --- a/none/default_config.py +++ b/none/default_config.py @@ -1,3 +1,4 @@ +import os from datetime import timedelta API_ROOT = '' @@ -12,3 +13,5 @@ NICKNAME = '' COMMAND_START = {'/', '!', '/', '!'} COMMAND_SEP = {'/', '.'} SESSION_EXPIRE_TIMEOUT = timedelta(minutes=5) + +DATA_FOLDER = os.path.join(os.getcwd(), 'data') diff --git a/none_demo/__init__.py b/none_demo/__init__.py index e69de29b..5d5fbe2d 100644 --- a/none_demo/__init__.py +++ b/none_demo/__init__.py @@ -0,0 +1,13 @@ +from os import path + +import none +from none_demo import config + +bot = none.init(config) +app = bot.asgi + +if __name__ == '__main__': + none.load_builtin_plugins() + none.load_plugins(path.join(path.dirname(__file__), 'plugins'), + 'none_demo.plugins') + none.run(host=config.HOST, port=config.PORT) diff --git a/none_demo/plugins/repeater.py b/none_demo/plugins/repeater.py index a34e8852..4468a70f 100644 --- a/none_demo/plugins/repeater.py +++ b/none_demo/plugins/repeater.py @@ -1,6 +1,4 @@ -from none import ( - on_natural_language, NLPSession, NLPResult -) +from none import on_natural_language, NLPSession, NLPResult _last_session = None diff --git a/none_demo/run.py b/none_demo/run.py deleted file mode 100644 index 11c76d10..00000000 --- a/none_demo/run.py +++ /dev/null @@ -1,15 +0,0 @@ -from os import path - -import none -from none_demo import config - -bot = none.create_bot(config) - -none.load_builtin_plugins() -plugin_dir = path.join(path.dirname(__file__), 'plugins') -none.load_plugins(plugin_dir, 'none_demo.plugins') - -app = bot.asgi - -if __name__ == '__main__': - bot.run(host=config.HOST, port=config.PORT) diff --git a/setup.py b/setup.py index edf25ab2..801a6157 100644 --- a/setup.py +++ b/setup.py @@ -14,7 +14,8 @@ setup( description='A QQ bot framework', long_description=long_description, long_description_content_type="text/markdown", - install_requires=['aiocqhttp>=0.5', 'aiocache'], + install_requires=['aiocqhttp>=0.5', 'aiocache', + 'apscheduler', 'sqlalchemy'], python_requires='>=3.6', platforms='any', classifiers=(