Skip to content

Commit

Permalink
up
Browse files Browse the repository at this point in the history
  • Loading branch information
lgc2333 committed Mar 10, 2024
1 parent a27374e commit a9e559a
Show file tree
Hide file tree
Showing 12 changed files with 121 additions and 375 deletions.
72 changes: 45 additions & 27 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@ _✨ 网易云多选点歌 ✨_

<br />

<a href="https://pydantic.dev">
<img src="https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/lgc-NB2Dev/readme/main/template/pyd-v1-or-v2.json" alt="Pydantic Version 1 Or 2" >
</a>
<a href="./LICENSE">
<img src="https://img.shields.io/github/license/lgc-NB2Dev/nonebot-plugin-multincm.svg" alt="license">
</a>
Expand Down Expand Up @@ -136,31 +139,31 @@ plugins = [

在 nonebot2 项目的 `.env` 文件中添加下表中的必填配置

| 配置项 | 必填 | 默认值 | 说明 |
| :-------------------------: | :--: | :---------------: | :-------------------------------------------------------------------------------------------------------: |
| **登录相关** | | | |
| `NCM_CTCODE` || `86` | 手机号登录用,登录手机区号 |
| `NCM_PHONE` || | 手机号登录用,登录手机号 |
| `NCM_EMAIL` || | 邮箱登录用,登录邮箱 |
| `NCM_PASSWORD` || | 帐号明文密码,邮箱登录时为邮箱密码 |
| `NCM_PASSWORD_HASH` || | 帐号密码 MD5 哈希,邮箱登录时为邮箱密码 |
| **展示相关** | | | |
| `NCM_LIST_LIMIT` || `20` | 歌曲列表每页的最大数量 |
| `NCM_LIST_FONT` || | 渲染歌曲列表使用的字体 |
| `NCM_MAX_NAME_LEN` || `600` | 歌曲列表中歌名列的最大文本宽度(像素) |
| `NCM_MAX_ARTIST_LEN` || `400` | 歌曲列表中歌手列的最大文本宽度(像素) |
| `NCM_LRC_EMPTY_LINE` || `--------` | 填充歌词空行的字符 |
| **功能相关** | | | |
| `NCM_MSG_CACHE_TIME` || `43200` | 缓存 用户最近一次操作 的时长(秒) |
| `NCM_AUTO_RESOLVE` || `False` | 当用户发送音乐链接时,是否自动解析并发送音乐卡片 |
| `NCM_RESOLVE_PLAYABLE_CARD` || `False` | 开启自动解析时,是否解析可播放的卡片 |
| `NCM_ILLEGAL_CMD_FINISH` || `False` | 当用户在点歌时输入了非法指令,是否直接退出点歌 |
| `NCM_ILLEGAL_CMD_LIMIT` || `3` | 当未启用 `NCM_ILLEGAL_CMD_FINISH` 时,用户在点歌时输入了多少次非法指令后直接退出点歌,填 `0` 以禁用此功能 |
| `NCM_USE_PLAYWRIGHT` || `False` | 是否使用 `playwright` 绘制歌曲列表与歌词图片 |
| `NCM_DELETE_LIST_MSG` || `True` | 是否在退出点歌模式后自动撤回歌曲列表 |
| `NCM_DELETE_LIST_MSG_DELAY` || `[0.5, 2.0]` | 自动撤回歌曲列表消息间隔时间(单位秒) |
| `NCM_UPLOAD_FOLDER_NAME` || `MultiNCM` | 在群内使用上传指令时,上传到的文件夹名称,不存在时会自动创建,如果创建失败会上传到根目录 |
| `NCM_ENABLE_RECORD` || `False` | 是否开启发送歌曲语音的功能 |
| 配置项 | 必填 | 默认值 | 说明 |
| :-------------------------: | :--: | :----------: | :-------------------------------------------------------------------------------------------------------: |
| **登录相关** | | | |
| `NCM_CTCODE` || `86` | 手机号登录用,登录手机区号 |
| `NCM_PHONE` || | 手机号登录用,登录手机号 |
| `NCM_EMAIL` || | 邮箱登录用,登录邮箱 |
| `NCM_PASSWORD` || | 帐号明文密码,邮箱登录时为邮箱密码 |
| `NCM_PASSWORD_HASH` || | 帐号密码 MD5 哈希,邮箱登录时为邮箱密码 |
| **展示相关** | | | |
| `NCM_LIST_LIMIT` || `20` | 歌曲列表每页的最大数量 |
| `NCM_LIST_FONT` || | 渲染歌曲列表使用的字体 |
| `NCM_MAX_NAME_LEN` || `600` | 歌曲列表中歌名列的最大文本宽度(像素) |
| `NCM_MAX_ARTIST_LEN` || `400` | 歌曲列表中歌手列的最大文本宽度(像素) |
| `NCM_LRC_EMPTY_LINE` || `--------` | 填充歌词空行的字符 |
| **功能相关** | | | |
| `NCM_MSG_CACHE_TIME` || `43200` | 缓存 用户最近一次操作 的时长(秒) |
| `NCM_AUTO_RESOLVE` || `False` | 当用户发送音乐链接时,是否自动解析并发送音乐卡片 |
| `NCM_RESOLVE_PLAYABLE_CARD` || `False` | 开启自动解析时,是否解析可播放的卡片 |
| `NCM_ILLEGAL_CMD_FINISH` || `False` | 当用户在点歌时输入了非法指令,是否直接退出点歌 |
| `NCM_ILLEGAL_CMD_LIMIT` || `3` | 当未启用 `NCM_ILLEGAL_CMD_FINISH` 时,用户在点歌时输入了多少次非法指令后直接退出点歌,填 `0` 以禁用此功能 |
| `NCM_USE_PLAYWRIGHT` || `False` | 是否使用 `playwright` 绘制歌曲列表与歌词图片 |
| `NCM_DELETE_LIST_MSG` || `True` | 是否在退出点歌模式后自动撤回歌曲列表 |
| `NCM_DELETE_LIST_MSG_DELAY` || `[0.5, 2.0]` | 自动撤回歌曲列表消息间隔时间(单位秒) |
| `NCM_UPLOAD_FOLDER_NAME` || `MultiNCM` | 在群内使用上传指令时,上传到的文件夹名称,不存在时会自动创建,如果创建失败会上传到根目录 |
| `NCM_ENABLE_RECORD` || `False` | 是否开启发送歌曲语音的功能 |

## 🎉 使用

Expand Down Expand Up @@ -242,10 +245,25 @@ Telegram:[@lgc2333](https://t.me/lgc2333)

### 0.5.0(开发中)

- 支持歌单,专辑等(开发中)
<details open>
<summary>TODO</summary>

- 多平台发送逻辑(暂定):
- OneBot V11 首先发送卡片,如果发送失败则 fallback
- 以文件形式发送
- 直接发送直链
- issue #17
- 只有在手动回复解析时才会要求选择,发送链接自动解析时只输出歌单信息
- 重构图片样式,现在的歌曲列表好丑,歌词图片要限长

<br />
</details>

- 适配 Pydantic V1 & V2
- 支持歌单,专辑等,支持多平台(开发中)
- 点歌指令可以回复一条文本消息作为搜索内容了
- 支持使用语音发送歌曲
- resolve [#14](https://github.com/lgc-NB2Dev/nonebot-plugin-multincm/issues/14)
- 弃用 Pillow
- 重构部分代码

### 0.4.4
Expand Down
2 changes: 1 addition & 1 deletion nonebot_plugin_multincm/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

auto_resolve_tip = "▶ Bot 会自动解析你发送的网易云链接\n"

__version__ = "0.5.0.dev8"
__version__ = "0.5.0.dev9"
__plugin_meta__ = PluginMetadata(
name="MultiNCM",
description="网易云多选点歌",
Expand Down
17 changes: 17 additions & 0 deletions nonebot_plugin_multincm/compact.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
from typing import Literal, Optional

from nonebot.compat import PYDANTIC_V2

if PYDANTIC_V2:
from pydantic import field_validator # type: ignore

else:
from pydantic import validator

def field_validator(
__field: str,
*fields: str,
mode: Literal["before", "after", "wrap", "plain"] = "after",
check_fields: Optional[bool] = None, # noqa: ARG001
):
return validator(__field, *fields, pre=(mode == "before"), allow_reuse=True)
10 changes: 6 additions & 4 deletions nonebot_plugin_multincm/config.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
from typing import Optional, Tuple

from nonebot import get_driver
from pydantic import BaseModel, validator
from nonebot import get_plugin_config
from pydantic import BaseModel

from .compact import field_validator


class ConfigModel(BaseModel):
Expand All @@ -28,12 +30,12 @@ class ConfigModel(BaseModel):
ncm_upload_folder_name: str = "MultiNCM"
ncm_enable_record: bool = False

@validator("ncm_upload_folder_name")
@field_validator("ncm_upload_folder_name")
def validate_upload_folder_name(cls, v: str) -> str: # noqa: N805
v = v.strip("/")
if "/" in v:
raise ValueError("Upload folder name cannot contain `/`")
return v


config: ConfigModel = ConfigModel.parse_obj(get_driver().config.dict())
config = get_plugin_config(ConfigModel)
Original file line number Diff line number Diff line change
@@ -1,44 +1,73 @@
from dataclasses import dataclass
from math import ceil
from pathlib import Path
from typing import Optional
from typing import List, Literal, NamedTuple, Optional, Tuple, Union

import bbcode
import bbcode # TODO 弃用 bbcode
from jinja2 import Template
from nonebot import logger
from nonebot_plugin_htmlrender import get_new_page
from pil_utils.fonts import Font
from pil_utils.types import ColorType, HAlignType

from ..config import config
from ..const import RES_DIR
from .shared import TablePage
from .config import config
from .const import RES_DIR

ColorType = Union[str, Tuple[int, int, int], Tuple[int, int, int, int]]
HAlignType = Literal["left", "right", "center"]


SONG_LIST_TEMPLATE = Template(
(RES_DIR / "song_list.html.jinja").read_text(encoding="u8"),
autoescape=True,
enable_async=True,
)
LYRIC_TEMPLATE = Template(
(RES_DIR / "lyric.html.jinja").read_text(encoding="u8"),
autoescape=True,
enable_async=True,
)
BBCODE_PARSER = bbcode.Parser()
BBCODE_PARSER.install_default_formatters()


@dataclass()
class TableHead:
name: str
align: HAlignType = "left"
min_width: Optional[int] = None
max_width: Optional[int] = None


class Table(NamedTuple):
head: List[TableHead]
rows: List[List[str]]


@dataclass()
class TablePage:
table: Table
calling: str
current_page: int
max_count: int

@property
def max_page(self) -> int:
return ceil(self.max_count / config.ncm_list_limit)


def get_font_path_uri() -> Optional[str]:
font_path = config.ncm_list_font
if font_path:
if (path := Path(font_path)).exists():
return path.resolve().as_uri()
return Font.find(font_path).path.as_uri()
return None
if font_path and (path := Path(font_path)).exists():
p = path.resolve().as_uri().replace("\\", "\\\\").replace("'", "\\'")
return f"url('{p}')"
return f"local('{font_path}')" if font_path else None


async def render_template(
template: "Template",
**kwargs,
) -> bytes:
html_txt = await template.render_async(**kwargs)
logger.debug(html_txt)
if (dbg := Path.cwd() / "multincm-debug.html").exists():
dbg.write_text(html_txt, encoding="u8")
async with get_new_page() as page:
await page.goto(RES_DIR.as_uri())
await page.set_content(html_txt, wait_until="networkidle")
Expand Down
12 changes: 0 additions & 12 deletions nonebot_plugin_multincm/draw/__init__.py

This file was deleted.

Loading

0 comments on commit a9e559a

Please sign in to comment.