File size: 2,766 Bytes
346533a
 
 
 
1d20b52
346533a
 
 
 
 
 
1d20b52
346533a
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1d20b52
346533a
1d20b52
 
346533a
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1d20b52
346533a
 
 
1d20b52
346533a
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
import importlib
import importlib.util
import pkgutil
from pathlib import Path
from typing import Optional, Union

from .config import meme_config
from .exception import NoSuchMeme
from .log import logger
from .meme import Meme, MemeArgsType, MemeFunction, MemeParamsType

_memes: dict[str, Meme] = {}


def path_to_module_name(path: Path) -> str:
    rel_path = path.resolve().relative_to(Path.cwd().resolve())
    if rel_path.stem == "__init__":
        return ".".join(rel_path.parts[:-1])
    else:
        return ".".join(rel_path.parts[:-1] + (rel_path.stem,))


def load_meme(module_path: Union[str, Path]):
    module_name = (
        path_to_module_name(module_path)
        if isinstance(module_path, Path)
        else module_path
    )
    try:
        importlib.import_module(module_name)
    except Exception as e:
        logger.opt(colors=True, exception=e).error(f"Failed to import {module_path}!")


def load_memes(dir_path: Union[str, Path]):
    if isinstance(dir_path, Path):
        dir_path = str(dir_path.resolve())

    for module_info in pkgutil.iter_modules([dir_path]):
        if module_info.name.startswith("_"):
            continue
        if not (
            module_spec := module_info.module_finder.find_spec(module_info.name, None)
        ):
            continue
        if not (module_path := module_spec.origin):
            continue
        if not (module_loader := module_spec.loader):
            continue
        try:
            module = importlib.util.module_from_spec(module_spec)
            module_loader.exec_module(module)
        except Exception as e:
            logger.opt(colors=True, exception=e).error(
                f"Failed to import {module_path}!"
            )


def add_meme(
    key: str,
    function: MemeFunction,
    *,
    min_images: int = 0,
    max_images: int = 0,
    min_texts: int = 0,
    max_texts: int = 0,
    default_texts: list[str] = [],
    args_type: Optional[MemeArgsType] = None,
    keywords: list[str] = [],
    patterns: list[str] = [],
):
    if key in _memes:
        logger.warning(f'Meme with key "{key}" already exists!')
        return

    if key in meme_config.meme.meme_disabled_list:
        logger.warning(f'The key "{key}" is in the disabled list!')
        return

    meme = Meme(
        key,
        function,
        MemeParamsType(
            min_images, max_images, min_texts, max_texts, default_texts, args_type
        ),
        keywords=keywords,
        patterns=patterns,
    )

    _memes[key] = meme


def get_meme(key: str) -> Meme:
    if key not in _memes:
        raise NoSuchMeme(key)
    return _memes[key]


def get_memes() -> list[Meme]:
    return list(_memes.values())


def get_meme_keys() -> list[str]:
    return list(_memes.keys())