File size: 4,881 Bytes
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
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
import asyncio
from pathlib import Path
from typing import Any, Dict

import filetype

from meme_generator import get_memes
from meme_generator.meme import Meme

memes = sorted(get_memes(), key=lambda meme: meme.key)

image_path = Path("docs/images")


async def generate_preview_images():
    for meme in memes:

        async def generate_image(name: str, args: Dict[str, Any] = {}):
            for path in image_path.iterdir():
                if name == path.stem:
                    return

            result = await meme.generate_preview(args=args)
            content = result.getvalue()
            ext = filetype.guess_extension(content)
            filename = f"{name}.{ext}"
            with open(image_path / filename, "wb") as f:
                f.write(content)

        await generate_image(f"{meme.key}")
        if args := meme.params_type.args_type:
            if instances := args.instances:
                for i, instance in enumerate(instances):
                    await generate_image(f"{meme.key}_instance{i}", instance.dict())


def meme_doc(meme: Meme) -> str:
    keywords = "、".join([f"`{keyword}`" for keyword in meme.keywords])

    patterns = "、".join([f"`{pattern}`" for pattern in meme.patterns])

    image_num = f"`{meme.params_type.min_images}`"
    if meme.params_type.max_images > meme.params_type.min_images:
        image_num += f" ~ `{meme.params_type.max_images}`"

    text_num = f"`{meme.params_type.min_texts}`"
    if meme.params_type.max_texts > meme.params_type.min_texts:
        text_num += f" ~ `{meme.params_type.max_texts}`"

    default_texts = (
        f"{', '.join([f'`{text}`' for text in meme.params_type.default_texts])}"
    )

    def arg_info(name: str, info: Dict[str, Any]) -> str:
        text = (
            f"    - `{name}`\n"
            f"        - 描述:{info.get('description', '')}\n"
            f"        - 类型:`{info.get('type', '')}`\n"
            f"        - 默认值:`{info.get('default', '')}`"
        )
        if enum := info.get("enum", []):
            assert isinstance(enum, list)
            text += f"\n        - 可选值:{'、'.join([f'`{e}`' for e in enum])}"
        return text

    if args := meme.params_type.args_type:
        model = args.model
        properties: Dict[str, Dict[str, Any]] = (
            model.schema().get("properties", {}).copy()
        )
        properties.pop("user_infos")
        args_info = "\n" + "\n".join(
            [arg_info(name, info) for name, info in properties.items()]
        )
    else:
        args_info = ""

    if args := meme.params_type.args_type:
        parser = args.parser
        parser_info = parser.format_help()
        parser_info = parser_info.replace("update_doc.py", f"meme generate {meme.key}")
    else:
        parser_info = ""

    def image_doc(name: str) -> str:
        for path in image_path.iterdir():
            if name == path.stem:
                img_path = path.relative_to(Path("docs"))
                return (
                    '<div align="left">\n'
                    f'  <img src="{img_path}" width="200" />\n'
                    "</div>"
                )
        return ""

    preview_image = ""
    if args := meme.params_type.args_type:
        if instances := args.instances:
            preview_image = "\n\n".join(
                [
                    f"> 参数:{instance.json(exclude={'user_infos'})}\n"
                    + image_doc(meme.key + f"_instance{i}")
                    for i, instance in enumerate(instances)
                ]
            )
    if not preview_image:
        preview_image = image_doc(meme.key)

    return (
        f"## {meme.key}\n\n"
        + f"- 关键词:{keywords}\n"
        + (f"- 正则表达式:{patterns}\n" if patterns else "")
        + f"- 需要图片数目:{image_num}\n"
        + f"- 需要文字数目:{text_num}\n"
        + (f"- 默认文字:[{default_texts}]\n" if default_texts else "")
        + (f"- 其他参数:{args_info}\n" if args_info else "")
        + (f"- 其他参数(命令行选项):\n```shell\n{parser_info}```\n\n" if parser_info else "")
        + "- 预览:\n"
        + f"{preview_image}"
    )


def generate_toc():
    return "\n".join(
        f"{i}. [{meme.key} ({'/'.join(meme.keywords)})](#{meme.key})"
        for i, meme in enumerate(memes, start=1)
    )


def generate_doc():
    doc = "# 表情列表\n\n以下为内置表情的关键词、所需参数等信息及表情预览\n\n按照表情的 `key` 排列\n\n\n"
    doc += generate_toc() + "\n\n\n"
    doc += "\n\n".join(meme_doc(meme) for meme in memes) + "\n"
    with open("docs/memes.md", "w") as f:
        f.write(doc)


async def main():
    await generate_preview_images()
    generate_doc()


if __name__ == "__main__":
    loop = asyncio.new_event_loop()
    loop.run_until_complete(main())