From 4fbab13369bf903614419adbbdb46e9bf7a68ddc Mon Sep 17 00:00:00 2001 From: 苏向夜 Date: Thu, 14 Dec 2023 15:44:33 +0800 Subject: :recycle: 重命名主包 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hydrorollcore/__init__.py | 6 --- src/hydrorollcore/cli.py | 45 --------------------- src/hydrorollcore/consts/__init__.py | 0 src/hydrorollcore/consts/templates.py | 69 -------------------------------- src/hydrorollcore/event.py | 43 -------------------- src/hydrorollcore/exceptions.py | 6 --- src/hydrorollcore/logging.py | 40 ------------------- src/hydrorollcore/manager.py | 18 --------- src/hydrorollcore/rule.py | 75 ----------------------------------- src/hydrorollcore/settings.py | 1 - src/hydrorollcore/typing.py | 41 ------------------- src/infini/__init__.py | 6 +++ src/infini/cli.py | 45 +++++++++++++++++++++ src/infini/consts/__init__.py | 0 src/infini/consts/templates.py | 69 ++++++++++++++++++++++++++++++++ src/infini/event.py | 43 ++++++++++++++++++++ src/infini/exceptions.py | 6 +++ src/infini/logging.py | 40 +++++++++++++++++++ src/infini/manager.py | 18 +++++++++ src/infini/rule.py | 75 +++++++++++++++++++++++++++++++++++ src/infini/settings.py | 1 + src/infini/typing.py | 41 +++++++++++++++++++ 22 files changed, 344 insertions(+), 344 deletions(-) delete mode 100644 src/hydrorollcore/__init__.py delete mode 100644 src/hydrorollcore/cli.py delete mode 100644 src/hydrorollcore/consts/__init__.py delete mode 100644 src/hydrorollcore/consts/templates.py delete mode 100644 src/hydrorollcore/event.py delete mode 100644 src/hydrorollcore/exceptions.py delete mode 100644 src/hydrorollcore/logging.py delete mode 100644 src/hydrorollcore/manager.py delete mode 100644 src/hydrorollcore/rule.py delete mode 100644 src/hydrorollcore/settings.py delete mode 100644 src/hydrorollcore/typing.py create mode 100644 src/infini/__init__.py create mode 100644 src/infini/cli.py create mode 100644 src/infini/consts/__init__.py create mode 100644 src/infini/consts/templates.py create mode 100644 src/infini/event.py create mode 100644 src/infini/exceptions.py create mode 100644 src/infini/logging.py create mode 100644 src/infini/manager.py create mode 100644 src/infini/rule.py create mode 100644 src/infini/settings.py create mode 100644 src/infini/typing.py (limited to 'src') diff --git a/src/hydrorollcore/__init__.py b/src/hydrorollcore/__init__.py deleted file mode 100644 index 9c88b4f9..00000000 --- a/src/hydrorollcore/__init__.py +++ /dev/null @@ -1,6 +0,0 @@ -from infini.cli import Cli -from infini.rule import Rule, Result, Dice -from infini.typing import Config as ConfigTyping -from infini.event import Event - -__all__ = ["Rule", "Cli", "Result", "Dice", "Event", "ConfigTyping"] diff --git a/src/hydrorollcore/cli.py b/src/hydrorollcore/cli.py deleted file mode 100644 index e372b4b4..00000000 --- a/src/hydrorollcore/cli.py +++ /dev/null @@ -1,45 +0,0 @@ -from pathlib import Path -from .consts import templates -from .logging import logger - -import argparse -import os -import sys -import importlib - - -class Cli: - def parse_args(self, argv: list[str] | None = None): - parser = argparse.ArgumentParser(description="HydroRoll 命令行工具") - - parser.add_argument("--new", action="store_true", help="创建一个 HydroRoll 规则包模板") - parser.add_argument("--run", action="store_true", help="运行 HydroRoll 规则包") - parser.add_argument("--gui", action="store_true", help="显示弹窗") - parser.add_argument("--path", help="指定路径") - - args = parser.parse_args(argv if argv else sys.argv[1:]) - - if args.gui: - logger.critical("选项[--gui]尚未被支持!") - sys.exit(1) - - path = Path(args.path).resolve() if args.path else Path(os.getcwd()).resolve() - if args.new and args.run: - logger.error("无法确定的指令要求: 你同时指定了new与run指令。") - sys.exit(1) - - if args.new: - if path.exists(): - logger.error("指定的文件夹已经存在!") - sys.exit(1) - - path.mkdir(parents=True, exist_ok=True) - (path / "rule.py").write_text(templates.RULE, encoding="utf-8") - (path / "event.py").write_text(templates.EVENT, encoding="utf-8") - (path / "dice.py").write_text(templates.DICE, encoding="utf-8") - - logger.success("HydroRoll 规则包模板已创建!") - - if args.run: - sys.path.append(str(path)) - importlib.import_module("event") diff --git a/src/hydrorollcore/consts/__init__.py b/src/hydrorollcore/consts/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/src/hydrorollcore/consts/templates.py b/src/hydrorollcore/consts/templates.py deleted file mode 100644 index e2edc2d6..00000000 --- a/src/hydrorollcore/consts/templates.py +++ /dev/null @@ -1,69 +0,0 @@ -RULE = """from infini import Rule, Result, Dice - - -class MyRule(Rule): - \"\"\"自设规则包\"\"\" - - name = "MyRule" - priority: int = 0 - - def __init__(self) -> None: - \"\"\"初始化你的规则包\"\"\" - - def check(self, dice: Dice) -> Result: - \"\"\"声明规则包检定方式\"\"\" - return Result("myevent.event1", True) -""" - -EVENT = """from infini import Event - -__events__ = ["MyEvent"] - - -class MyEvent(Event): - name = "event1" - output = "检定成功!" -""" - -DICE = """from infini import Dice - -import random -import re - - -class BaseDice(Dice): - \"\"\"多面骰\"\"\" - - def __init__(self, roll_string: str = "") -> None: - self.roll_string = roll_string - self.parse() - - def parse(self) -> "Dice": - self.dices = [] - split = re.split(r"[dD]", self.roll_string) - - if split[0]: - self.a = int(split[0]) - else: - self.a = 1 - - if split[1]: - self.b = int(split[1]) - else: - self.b = 100 - - self.db = f"{self.a}D{self.b}" - self.dices += [f"D{self.b}"] * self.a - return self - - def roll(self) -> int: - self.results = [] - - for _ in range(self.a): - result = random.randint(1, self.b) - - self.results.append(result) - - self.outcome = sum(self.results) - return self.outcome -""" diff --git a/src/hydrorollcore/event.py b/src/hydrorollcore/event.py deleted file mode 100644 index 9ce34bd9..00000000 --- a/src/hydrorollcore/event.py +++ /dev/null @@ -1,43 +0,0 @@ -from .typing import Dict -from .logging import logger - -import re - -__all__ = ["Event", "events"] - - -class Events: - """事件集合""" - - _events: Dict[str, str] = {} - - def regist(self, name: str, output: str) -> None: - self._events[name.lower()] = output - - def process(self, name: str, **kwargs) -> str: - if string := self._events.get(name.lower()): - return self._format(string, **kwargs) - logger.warning(f"事件[{name.lower()}]不存在,将返回空字符串!") - return "" - - def _format(self, string: str, **kwargs): - pattern = r"{(.*?)}" - values = re.findall(pattern, string) - for value in values: - kwarg = kwargs.get(value) - value = kwarg if kwarg else "" - string = re.sub(pattern, value, string) - return string - - -class Event: - """事件基类""" - - name: str - output: str - - def __init_subclass__(cls) -> None: - events.regist(cls.name, cls.output) - - -events = Events() diff --git a/src/hydrorollcore/exceptions.py b/src/hydrorollcore/exceptions.py deleted file mode 100644 index 62c88fa1..00000000 --- a/src/hydrorollcore/exceptions.py +++ /dev/null @@ -1,6 +0,0 @@ -class HydroError(Exception): - """HydroRoll 异常基类""" - - -class RuleLoadError(HydroError): - """规则导入错误""" diff --git a/src/hydrorollcore/logging.py b/src/hydrorollcore/logging.py deleted file mode 100644 index a1458ef4..00000000 --- a/src/hydrorollcore/logging.py +++ /dev/null @@ -1,40 +0,0 @@ -"""infini 日志。 - -infini 使用 [loguru](https://github.com/Delgan/loguru) 来记录日志信息。 -自定义 logger 请参考 [loguru](https://github.com/Delgan/loguru) 文档。 -""" -from datetime import datetime -from multilogging import multilogger -from pathlib import Path -from .settings import DEBUG - - -__all__ = ["logger", "error_or_exception"] - -logger = multilogger( - name="HydroRoll", payload="Core", level="DEBUG" if DEBUG else "INFO" -) -current_path = Path(__file__).resolve().parent -LOG_PATH = current_path / "logs" -if not LOG_PATH.exists(): - LOG_PATH.mkdir(parents=True, exist_ok=True) -logger.add( - sink=LOG_PATH / (datetime.now().strftime("%Y-%m-%d") + ".log"), - level="INFO", - rotation="10 MB", -) # 每个日志文件最大为 10MB - - -def error_or_exception(message: str, exception: Exception, verbose: bool = True): - # 弃用的方法 - # logger.remove() - # logger.add( - # sys.stderr, - # format="{time:YYYY-MM-DD HH:mm:ss.SSS} [{level}] > {name}:{function}:{line} - {message}", - # ) - - if verbose: - logger.exception(exception) - logger.critical(message) - else: - logger.critical(f"{message} {exception!r}") diff --git a/src/hydrorollcore/manager.py b/src/hydrorollcore/manager.py deleted file mode 100644 index 42e79563..00000000 --- a/src/hydrorollcore/manager.py +++ /dev/null @@ -1,18 +0,0 @@ -from .event import Events, events -from .logging import logger -from .typing import Dict - - -class Manager: - """事件处理单元""" - - events: Events - - def __init__(self, _events: Events = None) -> None: - self.events = _events if _events else events - - def roll(self): - ... - - -manager = Manager() diff --git a/src/hydrorollcore/rule.py b/src/hydrorollcore/rule.py deleted file mode 100644 index a1f04151..00000000 --- a/src/hydrorollcore/rule.py +++ /dev/null @@ -1,75 +0,0 @@ -from abc import ABCMeta, abstractmethod -from enum import Enum -from .exceptions import HydroError -from .typing import Dict - -__all__ = ["RuleLoadType", "Result", "Dice", "Rule"] - - -class RuleLoadType(Enum): - """The Type Of Rules To Be Loaded""" - - DIR = "dir" - NAME = "name" - FILE = "file" - CLASS = "class" - - -class Result(metaclass=ABCMeta): - """规则检定结果基类""" - - event: str - status: bool - exception: HydroError | None = None - - def __init__(self, event: str, status: bool, exception: HydroError | None) -> None: - self.event = event - self.status = status - self.exception = exception - - def ok(self): - """规则执行期间是否产生异常""" - return isinstance(self.exception, HydroError) - - -class Dice(metaclass=ABCMeta): - """掷骰基类""" - - roll_string: str - db: str - outcome: int - - def __repr__(self) -> str: - return f'' - - def __str__(self) -> str: - return self.db.upper() - - def __int__(self) -> int: - return self.outcome - - @abstractmethod - def parse(self) -> "Dice": - """解析传入的掷骰字符串`roll_string`,返回一个`Dice`对象""" - raise NotImplementedError - - @abstractmethod - def roll(self) -> int: - """掷骰方法,返回掷骰结果""" - raise NotImplementedError - - -class Rule(metaclass=ABCMeta): - """规则基类""" - - name: str - dices: Dict[str, str] = {} - priority: int = 0 - - @abstractmethod - def __init__(self) -> None: - raise NotImplementedError - - @abstractmethod - def check(self, dice: Dice) -> Result: - raise NotImplementedError diff --git a/src/hydrorollcore/settings.py b/src/hydrorollcore/settings.py deleted file mode 100644 index 51c64dd2..00000000 --- a/src/hydrorollcore/settings.py +++ /dev/null @@ -1 +0,0 @@ -DEBUG = True diff --git a/src/hydrorollcore/typing.py b/src/hydrorollcore/typing.py deleted file mode 100644 index 333a763b..00000000 --- a/src/hydrorollcore/typing.py +++ /dev/null @@ -1,41 +0,0 @@ -from pydantic import BaseModel -from typing import ( - Dict as Dict, - TYPE_CHECKING as TYPE_CHECKING, - TypeVar as TypeVar, - Callable as Callable, - NoReturn as NoReturn, - Awaitable as Awaitable, -) - - -class Config(BaseModel): - rule_dir: list = [] - rules: list = [] - - -class DiceConfig(BaseModel): - sides: int - counts: int - init_dice_pool: int - - -class PlayerCard(BaseModel): - name: str - traits: list - - -class Bonus(BaseModel): - level: int - cost: int - - -class WikiPage(BaseModel): - title: str - content: str - tags: list = [] - - -class WikiModel: - class Setting(BaseModel): - desc: str diff --git a/src/infini/__init__.py b/src/infini/__init__.py new file mode 100644 index 00000000..9c88b4f9 --- /dev/null +++ b/src/infini/__init__.py @@ -0,0 +1,6 @@ +from infini.cli import Cli +from infini.rule import Rule, Result, Dice +from infini.typing import Config as ConfigTyping +from infini.event import Event + +__all__ = ["Rule", "Cli", "Result", "Dice", "Event", "ConfigTyping"] diff --git a/src/infini/cli.py b/src/infini/cli.py new file mode 100644 index 00000000..e372b4b4 --- /dev/null +++ b/src/infini/cli.py @@ -0,0 +1,45 @@ +from pathlib import Path +from .consts import templates +from .logging import logger + +import argparse +import os +import sys +import importlib + + +class Cli: + def parse_args(self, argv: list[str] | None = None): + parser = argparse.ArgumentParser(description="HydroRoll 命令行工具") + + parser.add_argument("--new", action="store_true", help="创建一个 HydroRoll 规则包模板") + parser.add_argument("--run", action="store_true", help="运行 HydroRoll 规则包") + parser.add_argument("--gui", action="store_true", help="显示弹窗") + parser.add_argument("--path", help="指定路径") + + args = parser.parse_args(argv if argv else sys.argv[1:]) + + if args.gui: + logger.critical("选项[--gui]尚未被支持!") + sys.exit(1) + + path = Path(args.path).resolve() if args.path else Path(os.getcwd()).resolve() + if args.new and args.run: + logger.error("无法确定的指令要求: 你同时指定了new与run指令。") + sys.exit(1) + + if args.new: + if path.exists(): + logger.error("指定的文件夹已经存在!") + sys.exit(1) + + path.mkdir(parents=True, exist_ok=True) + (path / "rule.py").write_text(templates.RULE, encoding="utf-8") + (path / "event.py").write_text(templates.EVENT, encoding="utf-8") + (path / "dice.py").write_text(templates.DICE, encoding="utf-8") + + logger.success("HydroRoll 规则包模板已创建!") + + if args.run: + sys.path.append(str(path)) + importlib.import_module("event") diff --git a/src/infini/consts/__init__.py b/src/infini/consts/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/src/infini/consts/templates.py b/src/infini/consts/templates.py new file mode 100644 index 00000000..e2edc2d6 --- /dev/null +++ b/src/infini/consts/templates.py @@ -0,0 +1,69 @@ +RULE = """from infini import Rule, Result, Dice + + +class MyRule(Rule): + \"\"\"自设规则包\"\"\" + + name = "MyRule" + priority: int = 0 + + def __init__(self) -> None: + \"\"\"初始化你的规则包\"\"\" + + def check(self, dice: Dice) -> Result: + \"\"\"声明规则包检定方式\"\"\" + return Result("myevent.event1", True) +""" + +EVENT = """from infini import Event + +__events__ = ["MyEvent"] + + +class MyEvent(Event): + name = "event1" + output = "检定成功!" +""" + +DICE = """from infini import Dice + +import random +import re + + +class BaseDice(Dice): + \"\"\"多面骰\"\"\" + + def __init__(self, roll_string: str = "") -> None: + self.roll_string = roll_string + self.parse() + + def parse(self) -> "Dice": + self.dices = [] + split = re.split(r"[dD]", self.roll_string) + + if split[0]: + self.a = int(split[0]) + else: + self.a = 1 + + if split[1]: + self.b = int(split[1]) + else: + self.b = 100 + + self.db = f"{self.a}D{self.b}" + self.dices += [f"D{self.b}"] * self.a + return self + + def roll(self) -> int: + self.results = [] + + for _ in range(self.a): + result = random.randint(1, self.b) + + self.results.append(result) + + self.outcome = sum(self.results) + return self.outcome +""" diff --git a/src/infini/event.py b/src/infini/event.py new file mode 100644 index 00000000..9ce34bd9 --- /dev/null +++ b/src/infini/event.py @@ -0,0 +1,43 @@ +from .typing import Dict +from .logging import logger + +import re + +__all__ = ["Event", "events"] + + +class Events: + """事件集合""" + + _events: Dict[str, str] = {} + + def regist(self, name: str, output: str) -> None: + self._events[name.lower()] = output + + def process(self, name: str, **kwargs) -> str: + if string := self._events.get(name.lower()): + return self._format(string, **kwargs) + logger.warning(f"事件[{name.lower()}]不存在,将返回空字符串!") + return "" + + def _format(self, string: str, **kwargs): + pattern = r"{(.*?)}" + values = re.findall(pattern, string) + for value in values: + kwarg = kwargs.get(value) + value = kwarg if kwarg else "" + string = re.sub(pattern, value, string) + return string + + +class Event: + """事件基类""" + + name: str + output: str + + def __init_subclass__(cls) -> None: + events.regist(cls.name, cls.output) + + +events = Events() diff --git a/src/infini/exceptions.py b/src/infini/exceptions.py new file mode 100644 index 00000000..62c88fa1 --- /dev/null +++ b/src/infini/exceptions.py @@ -0,0 +1,6 @@ +class HydroError(Exception): + """HydroRoll 异常基类""" + + +class RuleLoadError(HydroError): + """规则导入错误""" diff --git a/src/infini/logging.py b/src/infini/logging.py new file mode 100644 index 00000000..a1458ef4 --- /dev/null +++ b/src/infini/logging.py @@ -0,0 +1,40 @@ +"""infini 日志。 + +infini 使用 [loguru](https://github.com/Delgan/loguru) 来记录日志信息。 +自定义 logger 请参考 [loguru](https://github.com/Delgan/loguru) 文档。 +""" +from datetime import datetime +from multilogging import multilogger +from pathlib import Path +from .settings import DEBUG + + +__all__ = ["logger", "error_or_exception"] + +logger = multilogger( + name="HydroRoll", payload="Core", level="DEBUG" if DEBUG else "INFO" +) +current_path = Path(__file__).resolve().parent +LOG_PATH = current_path / "logs" +if not LOG_PATH.exists(): + LOG_PATH.mkdir(parents=True, exist_ok=True) +logger.add( + sink=LOG_PATH / (datetime.now().strftime("%Y-%m-%d") + ".log"), + level="INFO", + rotation="10 MB", +) # 每个日志文件最大为 10MB + + +def error_or_exception(message: str, exception: Exception, verbose: bool = True): + # 弃用的方法 + # logger.remove() + # logger.add( + # sys.stderr, + # format="{time:YYYY-MM-DD HH:mm:ss.SSS} [{level}] > {name}:{function}:{line} - {message}", + # ) + + if verbose: + logger.exception(exception) + logger.critical(message) + else: + logger.critical(f"{message} {exception!r}") diff --git a/src/infini/manager.py b/src/infini/manager.py new file mode 100644 index 00000000..42e79563 --- /dev/null +++ b/src/infini/manager.py @@ -0,0 +1,18 @@ +from .event import Events, events +from .logging import logger +from .typing import Dict + + +class Manager: + """事件处理单元""" + + events: Events + + def __init__(self, _events: Events = None) -> None: + self.events = _events if _events else events + + def roll(self): + ... + + +manager = Manager() diff --git a/src/infini/rule.py b/src/infini/rule.py new file mode 100644 index 00000000..a1f04151 --- /dev/null +++ b/src/infini/rule.py @@ -0,0 +1,75 @@ +from abc import ABCMeta, abstractmethod +from enum import Enum +from .exceptions import HydroError +from .typing import Dict + +__all__ = ["RuleLoadType", "Result", "Dice", "Rule"] + + +class RuleLoadType(Enum): + """The Type Of Rules To Be Loaded""" + + DIR = "dir" + NAME = "name" + FILE = "file" + CLASS = "class" + + +class Result(metaclass=ABCMeta): + """规则检定结果基类""" + + event: str + status: bool + exception: HydroError | None = None + + def __init__(self, event: str, status: bool, exception: HydroError | None) -> None: + self.event = event + self.status = status + self.exception = exception + + def ok(self): + """规则执行期间是否产生异常""" + return isinstance(self.exception, HydroError) + + +class Dice(metaclass=ABCMeta): + """掷骰基类""" + + roll_string: str + db: str + outcome: int + + def __repr__(self) -> str: + return f'' + + def __str__(self) -> str: + return self.db.upper() + + def __int__(self) -> int: + return self.outcome + + @abstractmethod + def parse(self) -> "Dice": + """解析传入的掷骰字符串`roll_string`,返回一个`Dice`对象""" + raise NotImplementedError + + @abstractmethod + def roll(self) -> int: + """掷骰方法,返回掷骰结果""" + raise NotImplementedError + + +class Rule(metaclass=ABCMeta): + """规则基类""" + + name: str + dices: Dict[str, str] = {} + priority: int = 0 + + @abstractmethod + def __init__(self) -> None: + raise NotImplementedError + + @abstractmethod + def check(self, dice: Dice) -> Result: + raise NotImplementedError diff --git a/src/infini/settings.py b/src/infini/settings.py new file mode 100644 index 00000000..51c64dd2 --- /dev/null +++ b/src/infini/settings.py @@ -0,0 +1 @@ +DEBUG = True diff --git a/src/infini/typing.py b/src/infini/typing.py new file mode 100644 index 00000000..333a763b --- /dev/null +++ b/src/infini/typing.py @@ -0,0 +1,41 @@ +from pydantic import BaseModel +from typing import ( + Dict as Dict, + TYPE_CHECKING as TYPE_CHECKING, + TypeVar as TypeVar, + Callable as Callable, + NoReturn as NoReturn, + Awaitable as Awaitable, +) + + +class Config(BaseModel): + rule_dir: list = [] + rules: list = [] + + +class DiceConfig(BaseModel): + sides: int + counts: int + init_dice_pool: int + + +class PlayerCard(BaseModel): + name: str + traits: list + + +class Bonus(BaseModel): + level: int + cost: int + + +class WikiPage(BaseModel): + title: str + content: str + tags: list = [] + + +class WikiModel: + class Setting(BaseModel): + desc: str -- cgit v1.2.3-70-g09d2 From bb630e0b1a7f824a70449a4a513d504dbe11098c Mon Sep 17 00:00:00 2001 From: 苏向夜 Date: Thu, 14 Dec 2023 16:43:41 +0800 Subject: :recycle: 重构Infini结构树 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/infini/__init__.py | 8 ++--- src/infini/__main__.py | 40 ++++++++++++++++++++++ src/infini/cli.py | 45 ------------------------- src/infini/consts/templates.py | 6 ++-- src/infini/event.py | 7 ++-- src/infini/exceptions.py | 8 +++++ src/infini/handler.py | 52 +++++++++++++++++++++++++++++ src/infini/logging.py | 11 ++----- src/infini/manager.py | 18 ---------- src/infini/matcher.py | 41 +++++++++++++++++++++++ src/infini/rule.py | 75 ------------------------------------------ src/infini/utils/cli.py | 13 ++++++++ src/infini/utils/gui.py | 2 ++ src/test.py | 4 --- 14 files changed, 168 insertions(+), 162 deletions(-) create mode 100644 src/infini/__main__.py delete mode 100644 src/infini/cli.py create mode 100644 src/infini/handler.py delete mode 100644 src/infini/manager.py create mode 100644 src/infini/matcher.py delete mode 100644 src/infini/rule.py create mode 100644 src/infini/utils/cli.py create mode 100644 src/infini/utils/gui.py delete mode 100644 src/test.py (limited to 'src') diff --git a/src/infini/__init__.py b/src/infini/__init__.py index 9c88b4f9..5f6d1105 100644 --- a/src/infini/__init__.py +++ b/src/infini/__init__.py @@ -1,6 +1,4 @@ -from infini.cli import Cli -from infini.rule import Rule, Result, Dice -from infini.typing import Config as ConfigTyping -from infini.event import Event +from infini.handler import Handler, Result +from infini.event import MessageEvent -__all__ = ["Rule", "Cli", "Result", "Dice", "Event", "ConfigTyping"] +__all__ = ["Handler", "Result", "MessageEvent"] diff --git a/src/infini/__main__.py b/src/infini/__main__.py new file mode 100644 index 00000000..b7a282e9 --- /dev/null +++ b/src/infini/__main__.py @@ -0,0 +1,40 @@ +from pathlib import Path +from .utils.cli import parse_args +from .consts import templates +from .logging import logger + +import os +import importlib +import sys + + +def main(): + args = parse_args() + + if args.gui: + logger.critical("选项[--gui]尚未被支持!") + sys.exit(1) + + path = Path(args.path).resolve() if args.path else Path(os.getcwd()).resolve() + if args.new and args.run: + logger.error("无法确定的指令要求: 你同时指定了new与run指令。") + sys.exit(1) + + if args.new: + if path.exists(): + logger.error("指定的文件夹已经存在!") + sys.exit(1) + + path.mkdir(parents=True, exist_ok=True) + (path / "rule.py").write_text(templates.RULE, encoding="utf-8") + (path / "event.py").write_text(templates.EVENT, encoding="utf-8") + (path / "dice.py").write_text(templates.DICE, encoding="utf-8") + + logger.success("HydroRoll 规则包模板已创建!") + + if args.run: + sys.path.append(str(path)) + importlib.import_module("event") + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/src/infini/cli.py b/src/infini/cli.py deleted file mode 100644 index e372b4b4..00000000 --- a/src/infini/cli.py +++ /dev/null @@ -1,45 +0,0 @@ -from pathlib import Path -from .consts import templates -from .logging import logger - -import argparse -import os -import sys -import importlib - - -class Cli: - def parse_args(self, argv: list[str] | None = None): - parser = argparse.ArgumentParser(description="HydroRoll 命令行工具") - - parser.add_argument("--new", action="store_true", help="创建一个 HydroRoll 规则包模板") - parser.add_argument("--run", action="store_true", help="运行 HydroRoll 规则包") - parser.add_argument("--gui", action="store_true", help="显示弹窗") - parser.add_argument("--path", help="指定路径") - - args = parser.parse_args(argv if argv else sys.argv[1:]) - - if args.gui: - logger.critical("选项[--gui]尚未被支持!") - sys.exit(1) - - path = Path(args.path).resolve() if args.path else Path(os.getcwd()).resolve() - if args.new and args.run: - logger.error("无法确定的指令要求: 你同时指定了new与run指令。") - sys.exit(1) - - if args.new: - if path.exists(): - logger.error("指定的文件夹已经存在!") - sys.exit(1) - - path.mkdir(parents=True, exist_ok=True) - (path / "rule.py").write_text(templates.RULE, encoding="utf-8") - (path / "event.py").write_text(templates.EVENT, encoding="utf-8") - (path / "dice.py").write_text(templates.DICE, encoding="utf-8") - - logger.success("HydroRoll 规则包模板已创建!") - - if args.run: - sys.path.append(str(path)) - importlib.import_module("event") diff --git a/src/infini/consts/templates.py b/src/infini/consts/templates.py index e2edc2d6..f645d822 100644 --- a/src/infini/consts/templates.py +++ b/src/infini/consts/templates.py @@ -1,7 +1,7 @@ -RULE = """from infini import Rule, Result, Dice +RULE = """from infini import Handler, Result -class MyRule(Rule): +class HandlerRule(Handler): \"\"\"自设规则包\"\"\" name = "MyRule" @@ -10,7 +10,7 @@ class MyRule(Rule): def __init__(self) -> None: \"\"\"初始化你的规则包\"\"\" - def check(self, dice: Dice) -> Result: + def check(self) -> Result: \"\"\"声明规则包检定方式\"\"\" return Result("myevent.event1", True) """ diff --git a/src/infini/event.py b/src/infini/event.py index 9ce34bd9..21dc724c 100644 --- a/src/infini/event.py +++ b/src/infini/event.py @@ -1,9 +1,10 @@ +from abc import ABCMeta from .typing import Dict from .logging import logger import re -__all__ = ["Event", "events"] +__all__ = ["MessageEvent", "events"] class Events: @@ -30,8 +31,8 @@ class Events: return string -class Event: - """事件基类""" +class MessageEvent(metaclass=ABCMeta): + """消息事件基类""" name: str output: str diff --git a/src/infini/exceptions.py b/src/infini/exceptions.py index 62c88fa1..2ca7dfdb 100644 --- a/src/infini/exceptions.py +++ b/src/infini/exceptions.py @@ -4,3 +4,11 @@ class HydroError(Exception): class RuleLoadError(HydroError): """规则导入错误""" + + +class EventError(HydroError): + """事件处理时异常""" + + +class UnknownMatcherEvent(EventError): + """未知的给入实现""" diff --git a/src/infini/handler.py b/src/infini/handler.py new file mode 100644 index 00000000..fb6d50e5 --- /dev/null +++ b/src/infini/handler.py @@ -0,0 +1,52 @@ +from abc import ABCMeta, abstractmethod +from .exceptions import HydroError +from .typing import Dict, Callable + + +__all__ = ["Result", "Handler"] + + +class Result(metaclass=ABCMeta): + """规则包运行结果基类""" + + event: str + status: bool + exception: HydroError | None = None + + def __init__(self, event: str, status: bool, exception: HydroError | None) -> None: + self.event = event + self.status = status + self.exception = exception + + def ok(self): + """规则执行期间是否产生异常""" + return isinstance(self.exception, HydroError) + + +class Handler(metaclass=ABCMeta): + """规则包业务基类""" + + name: str + priority: int = 0 + + def __init_subclass__(cls) -> None: + handlers.regist(cls.name, cls.process) + + @abstractmethod + def process(self) -> Result: + raise NotImplementedError + + +class Handlers: + """规则包业务集合""" + + _handlers: Dict[str, Callable] = {} + + def regist(self, name: str, handler: Callable) -> None: + self._handlers[name.lower()] = handler + + def match(self, name: str) -> Callable | None: + return self._handlers.get(name.lower()) + + +handlers = Handlers() diff --git a/src/infini/logging.py b/src/infini/logging.py index a1458ef4..1346c7f7 100644 --- a/src/infini/logging.py +++ b/src/infini/logging.py @@ -1,6 +1,6 @@ -"""infini 日志。 +"""Infini 日志。 -infini 使用 [loguru](https://github.com/Delgan/loguru) 来记录日志信息。 +Infini 使用 [loguru](https://github.com/Delgan/loguru) 来记录日志信息。 自定义 logger 请参考 [loguru](https://github.com/Delgan/loguru) 文档。 """ from datetime import datetime @@ -26,13 +26,6 @@ logger.add( def error_or_exception(message: str, exception: Exception, verbose: bool = True): - # 弃用的方法 - # logger.remove() - # logger.add( - # sys.stderr, - # format="{time:YYYY-MM-DD HH:mm:ss.SSS} [{level}] > {name}:{function}:{line} - {message}", - # ) - if verbose: logger.exception(exception) logger.critical(message) diff --git a/src/infini/manager.py b/src/infini/manager.py deleted file mode 100644 index 42e79563..00000000 --- a/src/infini/manager.py +++ /dev/null @@ -1,18 +0,0 @@ -from .event import Events, events -from .logging import logger -from .typing import Dict - - -class Manager: - """事件处理单元""" - - events: Events - - def __init__(self, _events: Events = None) -> None: - self.events = _events if _events else events - - def roll(self): - ... - - -manager = Manager() diff --git a/src/infini/matcher.py b/src/infini/matcher.py new file mode 100644 index 00000000..635d8ad7 --- /dev/null +++ b/src/infini/matcher.py @@ -0,0 +1,41 @@ +from .event import Events, events +from .handler import Handlers, Result +from .exceptions import UnknownMatcherEvent +from .typing import Callable + + +class MatcherEvent: + """Matcher 事件""" + + name: str + kwargs: dict + + def __init__(self, name: str, **kwargs): + self.name = name + self.kwargs = kwargs + + def __repr__(self) -> str: + return f"" + + +class Matcher: + """事件处理单元""" + + events: Events + handlers: Handlers + + def __init__(self, _events: Events | None = None) -> None: + self.events = _events if _events else events + + def match(self, name: str) -> Callable: + if handler := self.handlers.match(name): + return handler + else: + raise UnknownMatcherEvent(f"未知的规则包: {name}") + + def run(self, event: MatcherEvent) -> str: + result: Result = self.match(event.name)() + return self.events.process(result.event, **event.kwargs) + + +matcher = Matcher() diff --git a/src/infini/rule.py b/src/infini/rule.py deleted file mode 100644 index a1f04151..00000000 --- a/src/infini/rule.py +++ /dev/null @@ -1,75 +0,0 @@ -from abc import ABCMeta, abstractmethod -from enum import Enum -from .exceptions import HydroError -from .typing import Dict - -__all__ = ["RuleLoadType", "Result", "Dice", "Rule"] - - -class RuleLoadType(Enum): - """The Type Of Rules To Be Loaded""" - - DIR = "dir" - NAME = "name" - FILE = "file" - CLASS = "class" - - -class Result(metaclass=ABCMeta): - """规则检定结果基类""" - - event: str - status: bool - exception: HydroError | None = None - - def __init__(self, event: str, status: bool, exception: HydroError | None) -> None: - self.event = event - self.status = status - self.exception = exception - - def ok(self): - """规则执行期间是否产生异常""" - return isinstance(self.exception, HydroError) - - -class Dice(metaclass=ABCMeta): - """掷骰基类""" - - roll_string: str - db: str - outcome: int - - def __repr__(self) -> str: - return f'' - - def __str__(self) -> str: - return self.db.upper() - - def __int__(self) -> int: - return self.outcome - - @abstractmethod - def parse(self) -> "Dice": - """解析传入的掷骰字符串`roll_string`,返回一个`Dice`对象""" - raise NotImplementedError - - @abstractmethod - def roll(self) -> int: - """掷骰方法,返回掷骰结果""" - raise NotImplementedError - - -class Rule(metaclass=ABCMeta): - """规则基类""" - - name: str - dices: Dict[str, str] = {} - priority: int = 0 - - @abstractmethod - def __init__(self) -> None: - raise NotImplementedError - - @abstractmethod - def check(self, dice: Dice) -> Result: - raise NotImplementedError diff --git a/src/infini/utils/cli.py b/src/infini/utils/cli.py new file mode 100644 index 00000000..ea886de7 --- /dev/null +++ b/src/infini/utils/cli.py @@ -0,0 +1,13 @@ +import argparse +import sys + +def parse_args(argv: list[str] | None = None) -> argparse.Namespace: + parser = argparse.ArgumentParser(description="HydroRoll 命令行工具") + + parser.add_argument("--new", action="store_true", help="创建一个 HydroRoll 规则包模板") + parser.add_argument("--run", action="store_true", help="运行 HydroRoll 规则包") + parser.add_argument("--gui", action="store_true", help="显示弹窗") + parser.add_argument("--path", help="指定路径") + + args = parser.parse_args(argv if argv else sys.argv[1:]) + return args \ No newline at end of file diff --git a/src/infini/utils/gui.py b/src/infini/utils/gui.py new file mode 100644 index 00000000..d7bc24ae --- /dev/null +++ b/src/infini/utils/gui.py @@ -0,0 +1,2 @@ +"""Infini 核心图形界面""" +# TODO diff --git a/src/test.py b/src/test.py deleted file mode 100644 index 349b1bfd..00000000 --- a/src/test.py +++ /dev/null @@ -1,4 +0,0 @@ -import infini - -client = infini.Cli() -client.parse_args() -- cgit v1.2.3-70-g09d2 From ddb8dbae2fc97b35c9cdf595ea926f925e987fcc Mon Sep 17 00:00:00 2001 From: 苏向夜 Date: Thu, 14 Dec 2023 16:45:19 +0800 Subject: :fire: 清理DICE模块 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/infini/__main__.py | 4 ++-- src/infini/consts/templates.py | 47 ++---------------------------------------- 2 files changed, 4 insertions(+), 47 deletions(-) (limited to 'src') diff --git a/src/infini/__main__.py b/src/infini/__main__.py index b7a282e9..f8f74457 100644 --- a/src/infini/__main__.py +++ b/src/infini/__main__.py @@ -28,7 +28,6 @@ def main(): path.mkdir(parents=True, exist_ok=True) (path / "rule.py").write_text(templates.RULE, encoding="utf-8") (path / "event.py").write_text(templates.EVENT, encoding="utf-8") - (path / "dice.py").write_text(templates.DICE, encoding="utf-8") logger.success("HydroRoll 规则包模板已创建!") @@ -36,5 +35,6 @@ def main(): sys.path.append(str(path)) importlib.import_module("event") + if __name__ == "__main__": - main() \ No newline at end of file + main() diff --git a/src/infini/consts/templates.py b/src/infini/consts/templates.py index f645d822..d3176468 100644 --- a/src/infini/consts/templates.py +++ b/src/infini/consts/templates.py @@ -15,55 +15,12 @@ class HandlerRule(Handler): return Result("myevent.event1", True) """ -EVENT = """from infini import Event +EVENT = """from infini import MessageEvent __events__ = ["MyEvent"] -class MyEvent(Event): +class MyEvent(MessageEvent): name = "event1" output = "检定成功!" """ - -DICE = """from infini import Dice - -import random -import re - - -class BaseDice(Dice): - \"\"\"多面骰\"\"\" - - def __init__(self, roll_string: str = "") -> None: - self.roll_string = roll_string - self.parse() - - def parse(self) -> "Dice": - self.dices = [] - split = re.split(r"[dD]", self.roll_string) - - if split[0]: - self.a = int(split[0]) - else: - self.a = 1 - - if split[1]: - self.b = int(split[1]) - else: - self.b = 100 - - self.db = f"{self.a}D{self.b}" - self.dices += [f"D{self.b}"] * self.a - return self - - def roll(self) -> int: - self.results = [] - - for _ in range(self.a): - result = random.randint(1, self.b) - - self.results.append(result) - - self.outcome = sum(self.results) - return self.outcome -""" -- cgit v1.2.3-70-g09d2 From 7a52c069c1eaa01341bb4101eb2ffede72c432d7 Mon Sep 17 00:00:00 2001 From: 苏向夜 Date: Thu, 14 Dec 2023 16:53:12 +0800 Subject: :bug: 修复Result传参问题 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/infini/handler.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/infini/handler.py b/src/infini/handler.py index fb6d50e5..30eac0ab 100644 --- a/src/infini/handler.py +++ b/src/infini/handler.py @@ -13,7 +13,9 @@ class Result(metaclass=ABCMeta): status: bool exception: HydroError | None = None - def __init__(self, event: str, status: bool, exception: HydroError | None) -> None: + def __init__( + self, event: str, status: bool, exception: HydroError | None = None + ) -> None: self.event = event self.status = status self.exception = exception -- cgit v1.2.3-70-g09d2 From a32887aa6f397e695112bd7e66e94b3a0481d132 Mon Sep 17 00:00:00 2001 From: 苏向夜 Date: Thu, 14 Dec 2023 16:56:02 +0800 Subject: :sparkles: 修订命令行展示 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/infini/utils/cli.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/infini/utils/cli.py b/src/infini/utils/cli.py index ea886de7..8e510a35 100644 --- a/src/infini/utils/cli.py +++ b/src/infini/utils/cli.py @@ -1,8 +1,9 @@ import argparse import sys + def parse_args(argv: list[str] | None = None) -> argparse.Namespace: - parser = argparse.ArgumentParser(description="HydroRoll 命令行工具") + parser = argparse.ArgumentParser(prog="Infini CLI", description="Infini 命令行工具") parser.add_argument("--new", action="store_true", help="创建一个 HydroRoll 规则包模板") parser.add_argument("--run", action="store_true", help="运行 HydroRoll 规则包") @@ -10,4 +11,4 @@ def parse_args(argv: list[str] | None = None) -> argparse.Namespace: parser.add_argument("--path", help="指定路径") args = parser.parse_args(argv if argv else sys.argv[1:]) - return args \ No newline at end of file + return args -- cgit v1.2.3-70-g09d2 From b225d40a2588df9fc5f0bb279e8dc6d95ae4fbf0 Mon Sep 17 00:00:00 2001 From: 苏向夜 Date: Thu, 14 Dec 2023 17:07:59 +0800 Subject: :bug: 修复handlers未声明的问题 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/infini/matcher.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/infini/matcher.py b/src/infini/matcher.py index 635d8ad7..5fde8445 100644 --- a/src/infini/matcher.py +++ b/src/infini/matcher.py @@ -1,5 +1,5 @@ from .event import Events, events -from .handler import Handlers, Result +from .handler import Handlers, Result, handlers from .exceptions import UnknownMatcherEvent from .typing import Callable @@ -24,8 +24,9 @@ class Matcher: events: Events handlers: Handlers - def __init__(self, _events: Events | None = None) -> None: + def __init__(self, _events: Events | None = None, _handlers: Handlers | None = None) -> None: self.events = _events if _events else events + self.handlers = _handlers if _handlers else handlers def match(self, name: str) -> Callable: if handler := self.handlers.match(name): -- cgit v1.2.3-70-g09d2 From 92c23714e2abe03158202b02915379f843aed8c9 Mon Sep 17 00:00:00 2001 From: 苏向夜 Date: Thu, 14 Dec 2023 17:08:17 +0800 Subject: :sparkles: 新增声明 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/infini/exceptions.py | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src') diff --git a/src/infini/exceptions.py b/src/infini/exceptions.py index 2ca7dfdb..2c181b48 100644 --- a/src/infini/exceptions.py +++ b/src/infini/exceptions.py @@ -12,3 +12,7 @@ class EventError(HydroError): class UnknownMatcherEvent(EventError): """未知的给入实现""" + + +class UnknownMessageEvent(EventError): + """未知的给出实现""" -- cgit v1.2.3-70-g09d2 From 1efeba89c3c1463f57dfe33d80aa98c206605e1f Mon Sep 17 00:00:00 2001 From: 苏向夜 Date: Thu, 14 Dec 2023 17:08:47 +0800 Subject: :sparkles: 使用抛出异常替代返回异常 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/infini/event.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/infini/event.py b/src/infini/event.py index 21dc724c..f456500a 100644 --- a/src/infini/event.py +++ b/src/infini/event.py @@ -1,6 +1,6 @@ from abc import ABCMeta from .typing import Dict -from .logging import logger +from .exceptions import UnknownMessageEvent import re @@ -18,8 +18,7 @@ class Events: def process(self, name: str, **kwargs) -> str: if string := self._events.get(name.lower()): return self._format(string, **kwargs) - logger.warning(f"事件[{name.lower()}]不存在,将返回空字符串!") - return "" + raise UnknownMessageEvent(f"事件[{name.lower()}]不存在!") def _format(self, string: str, **kwargs): pattern = r"{(.*?)}" -- cgit v1.2.3-70-g09d2 From 67002563cd9e4074ffcfd2de79e59a03ff700a4b Mon Sep 17 00:00:00 2001 From: 苏向夜 Date: Thu, 14 Dec 2023 17:31:51 +0800 Subject: :sparkles: 使用Handler作为对象传参 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/infini/__main__.py | 20 ++++++++++++++++---- src/infini/consts/templates.py | 11 +++++++++-- src/infini/handler.py | 13 ++++++------- src/infini/matcher.py | 12 ++++++++---- src/infini/utils/cli.py | 5 +++-- 5 files changed, 42 insertions(+), 19 deletions(-) (limited to 'src') diff --git a/src/infini/__main__.py b/src/infini/__main__.py index f8f74457..bd6a2b64 100644 --- a/src/infini/__main__.py +++ b/src/infini/__main__.py @@ -16,8 +16,8 @@ def main(): sys.exit(1) path = Path(args.path).resolve() if args.path else Path(os.getcwd()).resolve() - if args.new and args.run: - logger.error("无法确定的指令要求: 你同时指定了new与run指令。") + if args.new and args.test: + logger.error("无法确定的指令要求: 你同时指定了new与test指令。") sys.exit(1) if args.new: @@ -26,14 +26,26 @@ def main(): sys.exit(1) path.mkdir(parents=True, exist_ok=True) - (path / "rule.py").write_text(templates.RULE, encoding="utf-8") + (path / "handler.py").write_text(templates.RULE, encoding="utf-8") (path / "event.py").write_text(templates.EVENT, encoding="utf-8") + (path / "tests.py").write_text(templates.TEST, encoding="utf-8") logger.success("HydroRoll 规则包模板已创建!") - if args.run: + if args.load: sys.path.append(str(path)) importlib.import_module("event") + importlib.import_module("handler") + sys.path.remove(str(path)) + + if args.test: + logger.info(f"开始测试规则包: {str(path)}...") + sys.path.append(str(path)) + importlib.import_module("event") + importlib.import_module("handler") + tests = importlib.import_module("tests") + tests.test() + sys.path.remove(str(path)) if __name__ == "__main__": diff --git a/src/infini/consts/templates.py b/src/infini/consts/templates.py index d3176468..10ec12b4 100644 --- a/src/infini/consts/templates.py +++ b/src/infini/consts/templates.py @@ -10,9 +10,9 @@ class HandlerRule(Handler): def __init__(self) -> None: \"\"\"初始化你的规则包\"\"\" - def check(self) -> Result: + def process(self) -> Result: \"\"\"声明规则包检定方式\"\"\" - return Result("myevent.event1", True) + return Result("event1", True) """ EVENT = """from infini import MessageEvent @@ -24,3 +24,10 @@ class MyEvent(MessageEvent): name = "event1" output = "检定成功!" """ + +TEST = """from infini.matcher import matcher, MatcherEvent + +def test(): + event = MatcherEvent("event1") + print(matcher.run(event)) +""" diff --git a/src/infini/handler.py b/src/infini/handler.py index 30eac0ab..922023e7 100644 --- a/src/infini/handler.py +++ b/src/infini/handler.py @@ -1,7 +1,6 @@ from abc import ABCMeta, abstractmethod from .exceptions import HydroError -from .typing import Dict, Callable - +from .typing import Dict __all__ = ["Result", "Handler"] @@ -25,14 +24,14 @@ class Result(metaclass=ABCMeta): return isinstance(self.exception, HydroError) -class Handler(metaclass=ABCMeta): +class Handler: """规则包业务基类""" name: str priority: int = 0 def __init_subclass__(cls) -> None: - handlers.regist(cls.name, cls.process) + handlers.regist(cls.name, cls()) @abstractmethod def process(self) -> Result: @@ -42,12 +41,12 @@ class Handler(metaclass=ABCMeta): class Handlers: """规则包业务集合""" - _handlers: Dict[str, Callable] = {} + _handlers: Dict[str, Handler] = {} - def regist(self, name: str, handler: Callable) -> None: + def regist(self, name: str, handler: Handler) -> None: self._handlers[name.lower()] = handler - def match(self, name: str) -> Callable | None: + def match(self, name: str) -> Handler | None: return self._handlers.get(name.lower()) diff --git a/src/infini/matcher.py b/src/infini/matcher.py index 5fde8445..078a39e8 100644 --- a/src/infini/matcher.py +++ b/src/infini/matcher.py @@ -1,7 +1,8 @@ from .event import Events, events -from .handler import Handlers, Result, handlers +from .handler import Handlers, Handler, Result, handlers from .exceptions import UnknownMatcherEvent from .typing import Callable +from .logging import logger class MatcherEvent: @@ -24,18 +25,21 @@ class Matcher: events: Events handlers: Handlers - def __init__(self, _events: Events | None = None, _handlers: Handlers | None = None) -> None: + def __init__( + self, _events: Events | None = None, _handlers: Handlers | None = None + ) -> None: self.events = _events if _events else events self.handlers = _handlers if _handlers else handlers - def match(self, name: str) -> Callable: + def match(self, name: str) -> Handler: if handler := self.handlers.match(name): return handler else: raise UnknownMatcherEvent(f"未知的规则包: {name}") def run(self, event: MatcherEvent) -> str: - result: Result = self.match(event.name)() + logger.debug(f"开始处理事件: {event.name}...") + result = self.match(event.name).process() return self.events.process(result.event, **event.kwargs) diff --git a/src/infini/utils/cli.py b/src/infini/utils/cli.py index 8e510a35..b594cdd8 100644 --- a/src/infini/utils/cli.py +++ b/src/infini/utils/cli.py @@ -5,8 +5,9 @@ import sys def parse_args(argv: list[str] | None = None) -> argparse.Namespace: parser = argparse.ArgumentParser(prog="Infini CLI", description="Infini 命令行工具") - parser.add_argument("--new", action="store_true", help="创建一个 HydroRoll 规则包模板") - parser.add_argument("--run", action="store_true", help="运行 HydroRoll 规则包") + parser.add_argument("--new", action="store_true", help="创建一个 Infini 规则包模板") + parser.add_argument("--load", action="store_true", help="导入 Infini 规则包") + parser.add_argument("--test", action="store_true", help="运行 Infini 规则包测试") parser.add_argument("--gui", action="store_true", help="显示弹窗") parser.add_argument("--path", help="指定路径") -- cgit v1.2.3-70-g09d2 From 3c509e39213376e7f09565cce4668fb5b44a6590 Mon Sep 17 00:00:00 2001 From: 苏向夜 Date: Thu, 14 Dec 2023 17:38:42 +0800 Subject: :sparkles: 新增参数传递 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/infini/consts/templates.py | 15 +++++++-------- src/infini/handler.py | 2 +- src/infini/matcher.py | 7 ++----- 3 files changed, 10 insertions(+), 14 deletions(-) (limited to 'src') diff --git a/src/infini/consts/templates.py b/src/infini/consts/templates.py index 10ec12b4..c3b979bd 100644 --- a/src/infini/consts/templates.py +++ b/src/infini/consts/templates.py @@ -1,16 +1,15 @@ RULE = """from infini import Handler, Result +__handlers__ = ["HandlerRule"] -class HandlerRule(Handler): - \"\"\"自设规则包\"\"\" - name = "MyRule" - priority: int = 0 +class HandlerRule(Handler): + \"\"\"自设业务函数\"\"\" - def __init__(self) -> None: - \"\"\"初始化你的规则包\"\"\" + name = "MyRule" # 规则包名 + priority: int = 0 # 规则包权重 - def process(self) -> Result: + def process(self, **kwargs) -> Result: \"\"\"声明规则包检定方式\"\"\" return Result("event1", True) """ @@ -28,6 +27,6 @@ class MyEvent(MessageEvent): TEST = """from infini.matcher import matcher, MatcherEvent def test(): - event = MatcherEvent("event1") + event = MatcherEvent("MyRule") print(matcher.run(event)) """ diff --git a/src/infini/handler.py b/src/infini/handler.py index 922023e7..1edef9fa 100644 --- a/src/infini/handler.py +++ b/src/infini/handler.py @@ -34,7 +34,7 @@ class Handler: handlers.regist(cls.name, cls()) @abstractmethod - def process(self) -> Result: + def process(self, **kwargs) -> Result: raise NotImplementedError diff --git a/src/infini/matcher.py b/src/infini/matcher.py index 078a39e8..1a6bfe45 100644 --- a/src/infini/matcher.py +++ b/src/infini/matcher.py @@ -1,8 +1,6 @@ from .event import Events, events -from .handler import Handlers, Handler, Result, handlers +from .handler import Handlers, Handler, handlers from .exceptions import UnknownMatcherEvent -from .typing import Callable -from .logging import logger class MatcherEvent: @@ -38,8 +36,7 @@ class Matcher: raise UnknownMatcherEvent(f"未知的规则包: {name}") def run(self, event: MatcherEvent) -> str: - logger.debug(f"开始处理事件: {event.name}...") - result = self.match(event.name).process() + result = self.match(event.name).process(**event.kwargs) return self.events.process(result.event, **event.kwargs) -- cgit v1.2.3-70-g09d2 From 61bda5c7c0d96ba7d5cdb61828e9182bbf2741a2 Mon Sep 17 00:00:00 2001 From: 苏向夜 Date: Thu, 14 Dec 2023 17:41:19 +0800 Subject: :sparkles: 允许在业务层拦截参数 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/infini/handler.py | 12 +++--------- src/infini/matcher.py | 4 +++- 2 files changed, 6 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/src/infini/handler.py b/src/infini/handler.py index 1edef9fa..8f50fc8c 100644 --- a/src/infini/handler.py +++ b/src/infini/handler.py @@ -10,18 +10,12 @@ class Result(metaclass=ABCMeta): event: str status: bool - exception: HydroError | None = None + kwargs: dict = {} - def __init__( - self, event: str, status: bool, exception: HydroError | None = None - ) -> None: + def __init__(self, event: str, status: bool, **kwargs) -> None: self.event = event self.status = status - self.exception = exception - - def ok(self): - """规则执行期间是否产生异常""" - return isinstance(self.exception, HydroError) + self.kwargs = kwargs class Handler: diff --git a/src/infini/matcher.py b/src/infini/matcher.py index 1a6bfe45..d7cfa336 100644 --- a/src/infini/matcher.py +++ b/src/infini/matcher.py @@ -37,7 +37,9 @@ class Matcher: def run(self, event: MatcherEvent) -> str: result = self.match(event.name).process(**event.kwargs) - return self.events.process(result.event, **event.kwargs) + return self.events.process( + result.event, **result.kwargs if result.kwargs else event.kwargs + ) matcher = Matcher() -- cgit v1.2.3-70-g09d2 From aa81ffa1770ee32103769c598531b21692985fb5 Mon Sep 17 00:00:00 2001 From: 苏向夜 Date: Thu, 14 Dec 2023 18:05:23 +0800 Subject: :recycle: 使用子命令实现命令行 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/infini/__main__.py | 38 +++++++++++++++++++++----------------- src/infini/utils/cli.py | 19 ++++++++++++++----- 2 files changed, 35 insertions(+), 22 deletions(-) (limited to 'src') diff --git a/src/infini/__main__.py b/src/infini/__main__.py index bd6a2b64..47c82b75 100644 --- a/src/infini/__main__.py +++ b/src/infini/__main__.py @@ -16,12 +16,9 @@ def main(): sys.exit(1) path = Path(args.path).resolve() if args.path else Path(os.getcwd()).resolve() - if args.new and args.test: - logger.error("无法确定的指令要求: 你同时指定了new与test指令。") - sys.exit(1) - if args.new: - if path.exists(): + if args.operate == "new": + if path.exists() and not args.force: logger.error("指定的文件夹已经存在!") sys.exit(1) @@ -32,20 +29,27 @@ def main(): logger.success("HydroRoll 规则包模板已创建!") - if args.load: - sys.path.append(str(path)) - importlib.import_module("event") - importlib.import_module("handler") - sys.path.remove(str(path)) - - if args.test: - logger.info(f"开始测试规则包: {str(path)}...") + if args.operate == "test": + logger.info(f"开始测试规则包: {path.name}...") sys.path.append(str(path)) - importlib.import_module("event") - importlib.import_module("handler") - tests = importlib.import_module("tests") - tests.test() + logger.info(f"初始化规则包中...") + try: + importlib.import_module("event") + importlib.import_module("handler") + except Exception as error: + if args.verbose: + logger.exception(error) + logger.critical(f"初始化规则包时出现异常: {error}") + return + try: + errors = importlib.import_module("tests").test() + except Exception as error: + if args.verbose: + logger.exception(error) + logger.critical(f"测试规则包时出现异常: {error}") + return sys.path.remove(str(path)) + logger.info(f"测试规则包 {path.name} 出现 {len(errors)} 个异常, 测试完成.") if __name__ == "__main__": diff --git a/src/infini/utils/cli.py b/src/infini/utils/cli.py index b594cdd8..cb794133 100644 --- a/src/infini/utils/cli.py +++ b/src/infini/utils/cli.py @@ -5,11 +5,20 @@ import sys def parse_args(argv: list[str] | None = None) -> argparse.Namespace: parser = argparse.ArgumentParser(prog="Infini CLI", description="Infini 命令行工具") - parser.add_argument("--new", action="store_true", help="创建一个 Infini 规则包模板") - parser.add_argument("--load", action="store_true", help="导入 Infini 规则包") - parser.add_argument("--test", action="store_true", help="运行 Infini 规则包测试") - parser.add_argument("--gui", action="store_true", help="显示弹窗") - parser.add_argument("--path", help="指定路径") + parser.add_argument("--gui", action="store_true", help="启用 GUI 模式") + + subparsers = parser.add_subparsers(title="功能件", dest="operate") + + # 子命令 `new` + new_parser = subparsers.add_parser("new", help="创建一个 Infini 规则包模板") + new_parser.add_argument("path", help="目标位置") + new_parser.add_argument("-v", "--verbose", action="store_true", help="异常追踪") + new_parser.add_argument("-f", "--force", action="store_true", help="强制创建") + + # 子命令 `test` + test_parser = subparsers.add_parser("test", help="测试 Infini 规则包") + test_parser.add_argument("path", help="目标位置") + test_parser.add_argument("-v", "--verbose", action="store_true", help="异常追踪") args = parser.parse_args(argv if argv else sys.argv[1:]) return args -- cgit v1.2.3-70-g09d2 From c559e35fb99733c60ab97e536aa10fac59766f55 Mon Sep 17 00:00:00 2001 From: 苏向夜 Date: Thu, 14 Dec 2023 18:22:32 +0800 Subject: :sparkles: 新增原始消息传递 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 23 +++++++---------------- pyproject.toml | 2 +- src/infini/consts/templates.py | 7 ++++++- src/infini/event.py | 16 ++++++++++++++++ src/infini/handler.py | 4 ++-- src/infini/logging.py | 2 +- src/infini/matcher.py | 18 ++---------------- 7 files changed, 35 insertions(+), 37 deletions(-) (limited to 'src') diff --git a/README.md b/README.md index 5b69d574..cdb2d7ce 100644 --- a/README.md +++ b/README.md @@ -41,25 +41,16 @@ 2. 创建规则包实例 - 创建`cli.py`并写入以下内容: - - ```python - import infini - - client = infini.Cli() - client.parse_args() - ``` - - 打开终端并执行: + 确保你的`infini`正确安装后,打开终端并执行: ``` shell - python cli.py --new --path MyRule + python -m infini new MyRule ``` - 你可以在生成的 `MyRule\rule.py` 创建一个或者多个 `rule` 实例并继承 `Rule` 基类, 通过编写合适的相关方法与类注册规则包实现规则的自定义。 + 你可以在生成的 `MyRule\rule.py` 创建一个或者多个继承 `Handler` 基类的实例, 通过编写合适的相关方法与类注册规则包实现规则的自定义。 ``` python - from infini import Rule, Result, Dice + from infini import Handler, Result class MyRule(Rule): """自设规则包""" @@ -70,12 +61,12 @@ def __init__(self) -> None: """初始化你的规则包""" - def check(self, dice: Dice) -> Result: - """声明规则包检定方式""" + def process(self, **kwargs) -> Result: + """声明规则包运行方式""" return Result("event1", True) ``` - `check`函数应当返回一个`Result`对象,它应当包含一个消息事件名(例如示例中的`event1`),该消息事件名应当在 `MyRule\event.py` 中被注册。消息事件的动态内容通过`{name}`的方式声明并通过`name="内容"`的方式实现。 + `process`函数应当返回一个`Result`对象,它应当包含一个消息事件名(例如示例中的`event1`),该消息事件名应当在 `MyRule\event.py` 中被注册。消息事件的动态内容通过`{name}`的方式声明并通过`name="内容"`的方式实现。 3. 合理修改你的 `config.toml` 配置文件,完成注册! diff --git a/pyproject.toml b/pyproject.toml index 6084eb00..da3c0b59 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,7 +1,7 @@ [project] name = "infini" version = "1.0.4" -description = "The `Core` of `HydroRoll`, the `Loader` of your rules packages." +description = "Infini 核心标准输入输出模块" authors = [{ name = "简律纯", email = "i@jyunko.cn" }, { name = "苏向夜", email = "fu050409@163.com" }] dependencies = [ "mkdocs>=1.5.3", diff --git a/src/infini/consts/templates.py b/src/infini/consts/templates.py index c3b979bd..a662814c 100644 --- a/src/infini/consts/templates.py +++ b/src/infini/consts/templates.py @@ -28,5 +28,10 @@ TEST = """from infini.matcher import matcher, MatcherEvent def test(): event = MatcherEvent("MyRule") - print(matcher.run(event)) + try: + matcher.run(event) + except Exception as error: + return [error] + finally: + return [] """ diff --git a/src/infini/event.py b/src/infini/event.py index f456500a..a83c4042 100644 --- a/src/infini/event.py +++ b/src/infini/event.py @@ -40,4 +40,20 @@ class MessageEvent(metaclass=ABCMeta): events.regist(cls.name, cls.output) +class MatcherEvent: + """Matcher 事件""" + + name: str + string: str + kwargs: dict + + def __init__(self, event_name: str, string: str | None = None, **kwargs): + self.name = event_name + self.string = string or "" + self.kwargs = kwargs + + def __repr__(self) -> str: + return f"" + + events = Events() diff --git a/src/infini/handler.py b/src/infini/handler.py index 8f50fc8c..06d5c5fa 100644 --- a/src/infini/handler.py +++ b/src/infini/handler.py @@ -1,5 +1,5 @@ from abc import ABCMeta, abstractmethod -from .exceptions import HydroError +from .event import MatcherEvent from .typing import Dict __all__ = ["Result", "Handler"] @@ -28,7 +28,7 @@ class Handler: handlers.regist(cls.name, cls()) @abstractmethod - def process(self, **kwargs) -> Result: + def process(self, event: MatcherEvent) -> Result: raise NotImplementedError diff --git a/src/infini/logging.py b/src/infini/logging.py index 1346c7f7..72736ef7 100644 --- a/src/infini/logging.py +++ b/src/infini/logging.py @@ -12,7 +12,7 @@ from .settings import DEBUG __all__ = ["logger", "error_or_exception"] logger = multilogger( - name="HydroRoll", payload="Core", level="DEBUG" if DEBUG else "INFO" + name="Infini", payload="Core", level="DEBUG" if DEBUG else "INFO" ) current_path = Path(__file__).resolve().parent LOG_PATH = current_path / "logs" diff --git a/src/infini/matcher.py b/src/infini/matcher.py index d7cfa336..7fc5b88a 100644 --- a/src/infini/matcher.py +++ b/src/infini/matcher.py @@ -1,22 +1,8 @@ -from .event import Events, events +from .event import MatcherEvent, Events, events from .handler import Handlers, Handler, handlers from .exceptions import UnknownMatcherEvent -class MatcherEvent: - """Matcher 事件""" - - name: str - kwargs: dict - - def __init__(self, name: str, **kwargs): - self.name = name - self.kwargs = kwargs - - def __repr__(self) -> str: - return f"" - - class Matcher: """事件处理单元""" @@ -36,7 +22,7 @@ class Matcher: raise UnknownMatcherEvent(f"未知的规则包: {name}") def run(self, event: MatcherEvent) -> str: - result = self.match(event.name).process(**event.kwargs) + result = self.match(event.name).process(event) return self.events.process( result.event, **result.kwargs if result.kwargs else event.kwargs ) -- cgit v1.2.3-70-g09d2 From f7f775b4c529b1d65e55a12ee6b4e7c6c636f004 Mon Sep 17 00:00:00 2001 From: Sourcery AI <> Date: Fri, 15 Dec 2023 02:09:06 +0000 Subject: 'Refactored by Sourcery' --- src/infini/__main__.py | 2 +- src/infini/utils/cli.py | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/infini/__main__.py b/src/infini/__main__.py index 47c82b75..5c4dc2eb 100644 --- a/src/infini/__main__.py +++ b/src/infini/__main__.py @@ -32,7 +32,7 @@ def main(): if args.operate == "test": logger.info(f"开始测试规则包: {path.name}...") sys.path.append(str(path)) - logger.info(f"初始化规则包中...") + logger.info("初始化规则包中...") try: importlib.import_module("event") importlib.import_module("handler") diff --git a/src/infini/utils/cli.py b/src/infini/utils/cli.py index cb794133..6a4f9128 100644 --- a/src/infini/utils/cli.py +++ b/src/infini/utils/cli.py @@ -20,5 +20,4 @@ def parse_args(argv: list[str] | None = None) -> argparse.Namespace: test_parser.add_argument("path", help="目标位置") test_parser.add_argument("-v", "--verbose", action="store_true", help="异常追踪") - args = parser.parse_args(argv if argv else sys.argv[1:]) - return args + return parser.parse_args(argv if argv else sys.argv[1:]) -- cgit v1.2.3-70-g09d2