Skip to content

Commit

Permalink
Merge pull request #4 from lgc2333/main
Browse files Browse the repository at this point in the history
refactor project
  • Loading branch information
lgc2333 authored Nov 30, 2023
2 parents a8feb3b + 3dd6b7e commit e87f909
Show file tree
Hide file tree
Showing 14 changed files with 1,452 additions and 163 deletions.
4 changes: 1 addition & 3 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
nonebot2-store-test.py

*__pycache__/

poetry.lock
venv
build/
125 changes: 91 additions & 34 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,71 +1,128 @@
<h1 align="center">Nonebot Plugin Color</h1></br>
<!-- markdownlint-disable MD031 MD033 MD036 MD041 -->

<div align="center">

<p align="center">🤖 用于生成指定色彩图片的 Nonebot2 插件</p></br>
<a href="https://v2.nonebot.dev/store">
<img src="https://raw.githubusercontent.com/A-kirami/nonebot-plugin-template/resources/nbp_logo.png" width="180" height="180" alt="NoneBotPluginLogo">
</a>

<p>
<img src="https://raw.githubusercontent.com/A-kirami/nonebot-plugin-template/resources/NoneBotPlugin.svg" width="240" alt="NoneBotPluginText">
</p>

<p align="center">
<a href="https://github.com/monsterxcn/nonebot-plugin-color/actions">
<img src="https://img.shields.io/github/workflow/status/monsterxcn/nonebot-plugin-color/Build%20distributions?style=flat-square" alt="actions">
</a>
<a href="https://raw.githubusercontent.com/monsterxcn/nonebot-plugin-color/master/LICENSE">
<img src="https://img.shields.io/github/license/monsterxcn/nonebot-plugin-color?style=flat-square" alt="license">
</a>
<a href="https://pypi.python.org/pypi/nonebot-plugin-color">
<img src="https://img.shields.io/pypi/v/nonebot-plugin-color?style=flat-square" alt="pypi">
</a>
<img src="https://img.shields.io/badge/python-3.7.3+-blue?style=flat-square" alt="python"><br />
</p></br>
# NoneBot-Plugin-Color

_✨ 用于生成指定色彩图片的 NoneBot2 插件 ✨_

**安装方法**
<img src="https://img.shields.io/badge/python-3.8+-blue.svg" alt="python">
<a href="https://pdm.fming.dev">
<img src="https://img.shields.io/badge/pdm-managed-blueviolet" alt="pdm-managed">
</a>

<br />

<a href="./LICENSE">
<img src="https://img.shields.io/github/license/monsterxcn/nonebot-plugin-color.svg" alt="license">
</a>
<a href="https://pypi.python.org/pypi/nonebot-plugin-color">
<img src="https://img.shields.io/pypi/v/nonebot-plugin-color.svg" alt="pypi">
</a>
<a href="https://pypi.python.org/pypi/nonebot-plugin-color">
<img src="https://img.shields.io/pypi/dm/nonebot-plugin-color" alt="pypi download">
</a>

</div>

## 💿 安装

以下提到的方法 任选**其一** 即可

<details open>
<summary>[推荐] 使用 nb-cli 安装</summary>
在 nonebot2 项目的根目录下打开命令行, 输入以下指令即可安装

```bash
# 从 PyPI 安装
python3 -m pip install nonebot-plugin-color
nb plugin install nonebot-plugin-color
```

</details>

<details><summary><i>从 Git 安装</i></summary></br>
<details>
<summary>使用包管理器安装</summary>
在 nonebot2 项目的插件目录下, 打开命令行, 根据你使用的包管理器, 输入相应的安装命令

<details>
<summary>pip</summary>

```bash
# 从 Git 安装
git clone https://github.com/monsterxcn/nonebot-plugin-color.git
cd nonebot_plugin_color
cp -r nonebot_plugin_color /path/to/nonebot/plugins/
pip install nonebot-plugin-color
```

</details>
<details>
<summary>pdm</summary>

```bash
pdm add nonebot-plugin-color
```

</details>
<details>
<summary>poetry</summary>

```bash
poetry add nonebot-plugin-color
```

</details>
<details>
<summary>conda</summary>

重启 Bot 即可体验此插件。
```bash
conda install nonebot-plugin-color
```

</details>

**使用方法**
打开 nonebot2 项目根目录下的 `pyproject.toml` 文件, 在 `[tool.nonebot]` 部分的 `plugins` 项里追加写入

```toml
[tool.nonebot]
plugins = [
# ...
"nonebot_plugin_color"
]
```

插件支持类似以下格式的命令,基于正则匹配:
</details>

## ⚙️ 配置

- `#ABCD88`
- `123 234 33`
- `色图 #123456`
- `color#123456`

## 🎉 使用

<details><summary><i>哎哟这个色啊!好色!</i></summary></br>
插件基于 `pydantic``Color` 类解析颜色,详见 [这里](https://docs.pydantic.dev/1.10/usage/types/#color-type)
当发送符合其格式的消息时,Bot 将会回复你一张颜色图片

也可以作为指令 `color` / `色图` 的参数来使用

![色图来咯](screenshot.png)
例子:

- 颜色别名:`yellow` / `` / `黄色`(插件对中文颜色别名做了特殊处理,支持的名称列表见 [const.py](./nonebot_plugin_color/const.py)
- 十六进制(HEX):`#ff0` / `#ff0f` / `#ffff00` / `#ffff00ff`
- CSS RGB / RGBA:`rgb(255, 255, 0)` / `rgba(255, 255, 255, 1)`
- CSS HSL:`hsl(60, 100%, 50%)` / `hsl(60, 100%, 50%, 1)`

</details>
<details>
<summary><i>哎哟这个色啊!好色!</i></summary>

![色图来咯](./res/screenshot.png)

**特别鸣谢**
</details>

## 💡 鸣谢

[@nonebot/nonebot2](https://github.com/nonebot/nonebot2/) | [@Mrs4s/go-cqhttp](https://github.com/Mrs4s/go-cqhttp)
- [@nonebot/nonebot2](https://github.com/nonebot/nonebot2/)
- [@nonebot/plugin-alconna](https://github.com/nonebot/plugin-alconna)
- [@Mrs4s/go-cqhttp](https://github.com/Mrs4s/go-cqhttp)
54 changes: 25 additions & 29 deletions nonebot_plugin_color/__init__.py
Original file line number Diff line number Diff line change
@@ -1,33 +1,29 @@
from re import RegexFlag
from nonebot.plugin import PluginMetadata, inherit_supported_adapters, require

try:
from nonebot.adapters.onebot.v11 import Bot, MessageEvent, MessageSegment
except ImportError:
from nonebot.adapters.cqhttp import Bot, MessageSegment
from nonebot.adapters.cqhttp.event import MessageEvent
require("nonebot_plugin_alconna")

from nonebot import on_regex
from nonebot.typing import T_State
from . import __main__ as __main__ # noqa: E402
from .config import ConfigModel # noqa: E402

from .data_source import gnrtImg

# zero2max = r"(25[0-5]|2[0-4][0-9]|[0-1]?[0-9]?[0-9])"
color = on_regex(
r"^(色图|color)?\s*((#[a-f0-9]{6})|((25[0-5]|2[0-4][0-9]|[0-1]?[0-9]?[0-9])\s+(25[0-5]|2[0-4][0-9]|[0-1]?[0-9]?[0-9])\s+(25[0-5]|2[0-4][0-9]|[0-1]?[0-9]?[0-9])))$",
flags=RegexFlag.IGNORECASE, block=True, priority=13
__version__ = "0.2.0"
__plugin_meta__ = PluginMetadata(
name="色图生成",
description="用于生成指定色彩图片的 NoneBot2 插件",
usage=(
"插件基于 `pydantic` 的 `Color` 类解析颜色,"
"当发送符合其格式的消息时,Bot 将会回复你一张颜色图片\n"
" \n"
"也可以作为指令 `color` / `色图` 的参数来使用\n"
" \n"
"例子:\n"
"- 颜色别名:`yellow` / `黄` / `黄色`(插件对中文颜色别名做了特殊处理)\n"
"- 十六进制(HEX):`#ff0` / `#ff0f` / `#ffff00` / `#ffff00ff`\n"
"- CSS RGB / RGBA:`rgb(255, 255, 0)` / `rgba(255, 255, 255, 1)`\n"
"- CSS HSL:`hsl(60, 100%, 50%)` / `hsl(60, 100%, 50%, 1)`"
),
type="application",
homepage="https://github.com/monsterxcn/nonebot-plugin-color",
config=ConfigModel,
supported_adapters=inherit_supported_adapters("nonebot_plugin_alconna"),
extra={"License": "MIT", "Author": "student_2333"},
)


@color.handle()
async def _(bot: Bot, event: MessageEvent, state: T_State):
if state["_matched_groups"][2]:
c = state["_matched_groups"][2]
elif state["_matched_groups"][3]:
c = state["_matched_groups"][4:7]
else:
await color.finish("奇怪的颜色增加了呢!")
res = await gnrtImg(c)
if res[0] == "b": # "base64://"
await color.finish(MessageSegment.image(res))
else:
await color.finish(res)
89 changes: 89 additions & 0 deletions nonebot_plugin_color/__main__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
from contextlib import suppress
from typing import Optional

from nonebot import logger, on_command, on_message
from nonebot.adapters import Message as BaseMessage
from nonebot.matcher import Matcher
from nonebot.params import Depends, EventMessage
from nonebot.params import _command_arg as get_command_arg
from nonebot.typing import T_State
from nonebot_plugin_alconna.uniseg import Image, UniMessage
from nonebot_plugin_alconna.uniseg.segment import RawData
from pydantic.color import Color
from pydantic.errors import ColorError

from .const import COLOR_CHINESE_NAME_MAP
from .data_source import generate_image

KEY_COLOR = "color"
IMG_SIZE = 200


def parse_color(color: str) -> Optional[Color]:
with suppress(ColorError):
return Color(color)

# chinese name compatibility
if color.endswith("色"):
color = color[:-1]
if color in COLOR_CHINESE_NAME_MAP:
return Color(COLOR_CHINESE_NAME_MAP[color])

# old `r g b` format compatibility
with suppress(ColorError, ValueError):
splitted = color.split()
if 3 <= len(splitted) <= 4:
r, g, b = map(int, splitted[:3])
a = (
(a if (a := float(splitted[3])) < 1 else a / 255)
if len(splitted) == 4
else None
)
return Color((r, g, b) if a is None else (r, g, b, a))

return None


async def rule_color_msg(state: T_State, msg: BaseMessage = EventMessage()) -> bool:
if color := parse_color(msg.extract_plain_text().strip()):
state[KEY_COLOR] = color
return True
return False


async def dep_color(state: T_State) -> Optional[Color]:
if KEY_COLOR in state and (color := state[KEY_COLOR]):
return color

with suppress(KeyError):
arg = get_command_arg(state).extract_plain_text().strip()
if color := parse_color(arg):
return color

return None


cmd_color = on_command("color", aliases={"色图"})
msg_color = on_message(rule=rule_color_msg, priority=5)


@cmd_color.handle()
@msg_color.handle()
async def handle_color(
matcher: Matcher,
color: Optional[Color] = Depends(dep_color, use_cache=False),
):
if not color:
await matcher.finish("奇怪的颜色增加了呢!")

try:
image = await generate_image(color)
except Exception as e:
logger.exception("Error occurred while generating image")
await matcher.finish(f"不许色色!\n{type(e).__name__}: {e}")

await matcher.finish(
await UniMessage(
Image(raw=RawData(data=image, mimetype="image/png")),
).export(),
)
Binary file removed nonebot_plugin_color/color.ttf
Binary file not shown.
9 changes: 9 additions & 0 deletions nonebot_plugin_color/config.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
from nonebot import get_driver
from pydantic import BaseModel


class ConfigModel(BaseModel):
pass


config: ConfigModel = ConfigModel.parse_obj(get_driver().config)
Loading

0 comments on commit e87f909

Please sign in to comment.