generated from lgc-NB2Dev/nonebot-plugin-template
-
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
7 changed files
with
164 additions
and
11 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
import random | ||
from typing import List, NoReturn | ||
|
||
from nonebot import on_command | ||
from nonebot.adapters import Message | ||
from nonebot.internal.adapter import Event | ||
from nonebot.matcher import Matcher | ||
from nonebot.params import CommandArg | ||
from nonebot.typing import T_State | ||
from nonebot_plugin_saa import Image, MessageFactory, Text | ||
|
||
from .config import config | ||
from .data_source import MemeItem, fetch_meme, meme_list, search_meme_items | ||
|
||
|
||
async def finish_with_meme(meme_item: MemeItem) -> NoReturn: | ||
image_bytes = await fetch_meme(meme_item.path) | ||
await MessageFactory( | ||
[ | ||
Text(f"# {meme_item.name}"), | ||
Image(image_bytes), | ||
], | ||
).finish() | ||
|
||
|
||
cmd_meme = on_command("nonememe", aliases={"nb草图", "nb梗图"}) | ||
|
||
|
||
@cmd_meme.handle() | ||
async def _(matcher: Matcher, state: T_State, arg_msg: Message = CommandArg()): | ||
arg = arg_msg.extract_plain_text().strip() | ||
if not arg: | ||
await finish_with_meme(random.choice(meme_list)) | ||
|
||
use_regex = arg.startswith("/") and arg.endswith("/") | ||
if use_regex: | ||
arg = arg[1:-1] | ||
|
||
searched = search_meme_items(arg, use_regex=use_regex) | ||
if not searched: | ||
await matcher.finish("没有找到相关 NoneMeme") | ||
if len(searched) == 1: | ||
await finish_with_meme(searched[0]) | ||
|
||
over_length = len(searched) > config.nonememe_search_limit | ||
if over_length: | ||
searched = searched[: config.nonememe_search_limit] | ||
state["items"] = searched | ||
|
||
list_text = "\n".join(f"{i }. {item.name}" for i, item in enumerate(searched, 1)) | ||
over_len_tip = ( | ||
f"\nTip:搜索到的结果过多,仅显示前 {config.nonememe_search_limit} 条" if over_length else "" | ||
) | ||
await matcher.pause(f"找到多张图片,请发送序号选择:\n{list_text}{over_len_tip}") | ||
|
||
|
||
@cmd_meme.handle() | ||
async def _(matcher: Matcher, state: T_State, event: Event): | ||
arg = event.get_plaintext().strip() | ||
if arg in ("0", "q", "quit", "exit", "退出"): | ||
await matcher.finish("已退出选择") | ||
|
||
searched: List[MemeItem] = state["items"] | ||
if not (arg.isdigit() and (0 <= (index := (int(arg) - 1)) < len(searched))): | ||
await matcher.reject("请输入正确的结果序号,退出选择请发送 `0`") | ||
|
||
await finish_with_meme(searched[index]) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,9 +1,16 @@ | ||
from typing import Optional | ||
|
||
from nonebot import get_driver | ||
from pydantic import BaseModel | ||
|
||
|
||
class ConfigModel(BaseModel): | ||
pass | ||
nonememe_proxy: Optional[str] = None | ||
nonememe_repo_prefix: str = ( | ||
"https://raw.githubusercontent.com/NoneMeme/NoneMeme/main" | ||
) | ||
|
||
nonememe_search_limit: int = 5 | ||
|
||
|
||
config: ConfigModel = ConfigModel.parse_obj(get_driver().config.dict()) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
import re | ||
import urllib.parse | ||
from dataclasses import dataclass | ||
from pathlib import Path | ||
from typing import List, cast | ||
|
||
import json5 | ||
from httpx import AsyncClient | ||
from nonebot import get_driver, logger | ||
|
||
from .config import config | ||
|
||
|
||
@dataclass | ||
class MemeItem: | ||
name: str | ||
path: str | ||
|
||
|
||
meme_list: List[MemeItem] = [] | ||
|
||
|
||
def search_meme_items( | ||
keyword: str, | ||
use_regex: bool = False, # noqa: FBT001 | ||
) -> List[MemeItem]: | ||
if use_regex: | ||
pattern = re.compile(keyword, re.I) | ||
return [item for item in meme_list if pattern.search(item.name)] | ||
|
||
kws = keyword.lower().split() | ||
matches = [ | ||
(s, x) | ||
for x in meme_list | ||
if (s := len([kw for kw in kws if kw in x.name.lower()])) | ||
] | ||
return [x[1] for x in sorted(matches, key=lambda x: x[0], reverse=True)] | ||
|
||
|
||
async def fetch_meme(path: str) -> bytes: | ||
async with AsyncClient(proxies=config.nonememe_proxy) as cli: | ||
resp = await cli.get(f"{config.nonememe_repo_prefix}/{path}") | ||
return resp.content | ||
|
||
|
||
def build_meme_item(meme_path: str) -> MemeItem: | ||
name = Path(urllib.parse.unquote(meme_path)).stem | ||
return MemeItem(name=name, path=meme_path) | ||
|
||
|
||
async def fetch_meme_list() -> List[MemeItem]: | ||
async with AsyncClient(proxies=config.nonememe_proxy) as cli: | ||
resp = await cli.get(f"{config.nonememe_repo_prefix}/static/scripts/config.js") | ||
text = resp.text | ||
text = text[text.find("{") : text.rfind("}") + 1] | ||
|
||
items: List[str] = cast(dict, json5.loads(text))["items"] | ||
return [build_meme_item(item) for item in items] | ||
|
||
|
||
async def init_meme_list(): | ||
meme_list.clear() | ||
meme_list.extend(await fetch_meme_list()) | ||
logger.opt(colors=True).success( | ||
f"Succeed to init meme list, Loaded <y>{len(meme_list)}</y> memes", | ||
) | ||
print(meme_list) | ||
|
||
|
||
driver = get_driver() | ||
driver.on_startup(init_meme_list) |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters