Spaces:
Sleeping
Sleeping
File size: 6,632 Bytes
346533a 1d20b52 346533a 1d20b52 346533a 1d20b52 346533a 1d20b52 346533a de89ca4 346533a de89ca4 346533a de89ca4 346533a 1d20b52 de89ca4 346533a de89ca4 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 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 |
import asyncio
import copy
from argparse import ArgumentParser
from pathlib import Path
from typing import Any
import filetype
from meme_generator.app import run_server
from meme_generator.config import meme_config
from meme_generator.download import check_resources
from meme_generator.exception import MemeGeneratorException, NoSuchMeme
from meme_generator.log import setup_logger
from meme_generator.manager import get_meme, get_memes
parser = ArgumentParser("meme")
subparsers = parser.add_subparsers(dest="handle")
list_parser = subparsers.add_parser("list", aliases=["ls"], help="查看表情列表")
show_parser = subparsers.add_parser("info", aliases=["show"], help="查看表情详情")
show_parser.add_argument("key", type=str, help="表情名")
preview_parser = subparsers.add_parser("preview", help="生成表情预览")
preview_parser.add_argument("key", type=str, help="表情名")
generate_parser = subparsers.add_parser("generate", aliases=["make"], help="制作表情")
memes_subparsers = generate_parser.add_subparsers(dest="key", help="表情名")
run_parser = subparsers.add_parser("run", aliases=["start"], help="启动 web server")
download_parser = subparsers.add_parser("download", help="下载内置表情图片")
download_parser.add_argument(
"--url", type=str, help="指定资源链接", default=meme_config.resource.resource_url
)
def add_parsers():
for meme in get_memes():
meme_parser = (
copy.deepcopy(meme.params_type.args_type.parser)
if meme.params_type.args_type
else ArgumentParser()
)
meme_parser.add_argument("--images", nargs="+", default=[], help="输入图片路径")
meme_parser.add_argument("--texts", nargs="+", default=[], help="输入文字")
memes_subparsers.add_parser(
meme.key,
parents=[meme_parser],
add_help=False,
prefix_chars=meme_parser.prefix_chars,
)
def list_memes() -> str:
memes = sorted(get_memes(), key=lambda meme: meme.key)
return "\n".join(
f"{i}. {meme.key} ({'/'.join(meme.keywords)})"
for i, meme in enumerate(memes, start=1)
)
def meme_info(key: str) -> str:
try:
meme = get_meme(key)
except NoSuchMeme:
return f'表情 "{key}" 不存在!'
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 = ", ".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 += "\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", {})
properties.pop("user_infos")
args_info = "\n" + "\n".join(
[arg_info(name, info) for name, info in properties.items()]
)
else:
args_info = ""
return (
f"表情名:{meme.key}\n"
+ f"关键词:{keywords}\n"
+ (f"正则表达式:{patterns}\n" if patterns else "")
+ "参数:\n"
+ f" 需要图片数目:{image_num}\n"
+ f" 需要文字数目:{text_num}\n"
+ (f" 默认文字:[{default_texts}]\n" if default_texts else "")
+ (f" 其他参数:{args_info}\n" if args_info else "")
)
def generate_meme_preview(key: str) -> str:
try:
meme = get_meme(key)
except NoSuchMeme:
return f'表情 "{key}" 不存在!'
try:
loop = asyncio.new_event_loop()
result = loop.run_until_complete(meme.generate_preview())
content = result.getvalue()
ext = filetype.guess_extension(content)
filename = f"result.{ext}"
with open(filename, "wb") as f:
f.write(content)
return f'表情制作成功!生成的表情文件为 "{filename}"'
except MemeGeneratorException as e:
return str(e)
def generate_meme(
key: str, images: list[str], texts: list[str], args: dict[str, Any]
) -> str:
try:
meme = get_meme(key)
except NoSuchMeme:
return f'表情 "{key}" 不存在!'
for image in images:
if not Path(image).exists():
return f'图片路径 "{image}" 不存在!'
try:
loop = asyncio.new_event_loop()
result = loop.run_until_complete(meme(images=images, texts=texts, args=args))
content = result.getvalue()
ext = filetype.guess_extension(content)
filename = f"result.{ext}"
with open(filename, "wb") as f:
f.write(content)
return f'表情制作成功!生成的表情文件为 "{filename}"'
except MemeGeneratorException as e:
return str(e)
def main():
setup_logger()
add_parsers()
args = parser.parse_args()
handle = str(args.handle)
if handle in ["list", "ls"]:
print(list_memes()) # noqa: T201
elif handle in ["info", "show"]:
key = str(args.key)
print(meme_info(key)) # noqa: T201
elif handle in ["preview"]:
key = str(args.key)
print(generate_meme_preview(key)) # noqa: T201
elif handle in ["generate", "make"]:
kwargs = vars(args)
kwargs.pop("handle")
key: str = kwargs.pop("key")
images: list[str] = kwargs.pop("images")
texts: list[str] = kwargs.pop("texts")
print(generate_meme(key, images, texts, kwargs)) # noqa: T201
elif handle in ["run", "start"]:
run_server()
elif handle in ["download"]:
meme_config.resource.resource_url = args.url
loop = asyncio.new_event_loop()
loop.run_until_complete(check_resources())
else:
print(parser.format_help()) # noqa: T201
if __name__ == "__main__":
main()
|