nonebot-plugin-user-perm 0.1.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,152 @@
1
+ Metadata-Version: 2.3
2
+ Name: nonebot-plugin-user-perm
3
+ Version: 0.1.1
4
+ Summary: 插件描述
5
+ Author: dontdot
6
+ Author-email: dontdot <55482264+dontdot@users.noreply.github.com>
7
+ Requires-Dist: nonebot-adapter-onebot
8
+ Requires-Dist: nonebot-plugin-localstore>=0.7.4,<1.0.0
9
+ Requires-Dist: nonebot2>=2.5.0,<3.0.0
10
+ Requires-Python: >=3.10
11
+ Project-URL: Homepage, https://github.com/dontdot/nonebot-plugin-user-perm
12
+ Project-URL: Issues, https://github.com/dontdot/nonebot-plugin-user-perm/issues
13
+ Project-URL: Repository, https://github.com/dontdot/nonebot-plugin-user-perm.git
14
+ Description-Content-Type: text/markdown
15
+
16
+ <div align="center">
17
+ <a href="https://v2.nonebot.dev/store">
18
+ <img src="https://raw.githubusercontent.com/fllesser/nonebot-plugin-template/refs/heads/resource/.docs/NoneBotPlugin.svg" width="310" alt="logo"></a>
19
+
20
+ ## ✨ nonebot-plugin-user-perm ✨
21
+ [![LICENSE](https://img.shields.io/github/license/dontdot/nonebot-plugin-user-perm.svg)](./LICENSE)
22
+ [![pypi](https://img.shields.io/pypi/v/nonebot-plugin-user-perm.svg)](https://pypi.python.org/pypi/nonebot-plugin-user-perm)
23
+ [![python](https://img.shields.io/badge/python-3.10|3.11|3.12|3.13-blue.svg)](https://www.python.org)
24
+ [![uv](https://img.shields.io/badge/package%20manager-uv-black?style=flat-square&logo=uv)](https://github.com/astral-sh/uv)
25
+ <br/>
26
+ [![ruff](https://img.shields.io/badge/code%20style-ruff-black?style=flat-square&logo=ruff)](https://github.com/astral-sh/ruff)
27
+ [![pre-commit](https://results.pre-commit.ci/badge/github/dontdot/nonebot-plugin-user-perm/master.svg)](https://results.pre-commit.ci/latest/github/dontdot/nonebot-plugin-user-perm/master)
28
+
29
+ </div>
30
+
31
+ ## 📖 介绍
32
+
33
+ 设置群聊的某些普通用户使用插件的某个权限命令!
34
+
35
+ 使用onebotv11适配器提供 `isPermUser` 函数给其他插件使用在响应器中
36
+
37
+ 注意:`isPermUser`只接受群消息事件`GroupMessageEvent`
38
+
39
+ > `isPermUser` 将判断这条消息发送人是否是该群聊设置的特定普通用户 + super用户
40
+
41
+ 默认数据格式:{'super': [ ], 'group': { } }
42
+
43
+ > 例如:{'super': [12345], 'group': {'某个qq群号': [112233, 223344]}} \
44
+ > 每个[ ]里填入普通用户的qq号(int类型)
45
+
46
+
47
+ ## 💿 安装
48
+
49
+ <details open>
50
+ <summary>使用 nb-cli 安装</summary>
51
+ 在 nonebot2 项目的根目录下打开命令行, 输入以下指令即可安装
52
+
53
+ nb plugin install nonebot-plugin-user-perm --upgrade
54
+ 使用 **pypi** 源安装
55
+
56
+ nb plugin install nonebot-plugin-user-perm --upgrade -i "https://pypi.org/simple"
57
+ 使用**清华源**安装
58
+
59
+ nb plugin install nonebot-plugin-user-perm --upgrade -i "https://pypi.tuna.tsinghua.edu.cn/simple"
60
+
61
+
62
+ </details>
63
+
64
+ <details>
65
+ <summary>使用包管理器安装</summary>
66
+ 在 nonebot2 项目的插件目录下, 打开命令行, 根据你使用的包管理器, 输入相应的安装命令
67
+
68
+ <details open>
69
+ <summary>uv</summary>
70
+
71
+ uv add nonebot-plugin-user-perm
72
+ 安装仓库 master 分支
73
+
74
+ uv add git+https://github.com/dontdot/nonebot-plugin-user-perm@master
75
+ </details>
76
+
77
+ <details>
78
+ <summary>pdm</summary>
79
+
80
+ pdm add nonebot-plugin-user-perm
81
+ 安装仓库 master 分支
82
+
83
+ pdm add git+https://github.com/dontdot/nonebot-plugin-user-perm@master
84
+ </details>
85
+ <details>
86
+ <summary>poetry</summary>
87
+
88
+ poetry add nonebot-plugin-user-perm
89
+ 安装仓库 master 分支
90
+
91
+ poetry add git+https://github.com/dontdot/nonebot-plugin-user-perm@master
92
+ </details>
93
+
94
+ 打开 nonebot2 项目根目录下的 `pyproject.toml` 文件, 在 `[tool.nonebot]` 部分追加写入
95
+
96
+ plugins = ["nonebot_plugin_user_perm"]
97
+
98
+ </details>
99
+
100
+ <details>
101
+ <summary>使用 nbr 安装(使用 uv 管理依赖可用)</summary>
102
+
103
+ [nbr](https://github.com/fllesser/nbr) 是一个基于 uv 的 nb-cli,可以方便地管理 nonebot2
104
+
105
+ nbr plugin install nonebot-plugin-user-perm
106
+ 使用 **pypi** 源安装
107
+
108
+ nbr plugin install nonebot-plugin-user-perm -i "https://pypi.org/simple"
109
+ 使用**清华源**安装
110
+
111
+ nbr plugin install nonebot-plugin-user-perm -i "https://pypi.tuna.tsinghua.edu.cn/simple"
112
+
113
+ </details>
114
+
115
+
116
+ ## ⚙️ 配置
117
+
118
+ 使用`nonebot-plugin-localstore`持久化保存数据
119
+ 可在 nonebot2 项目的`.env`文件中添加以下配置,使数据文件保存在bot项目下的`data`目录
120
+
121
+ > LOCALSTORE_USE_CWD=True
122
+
123
+
124
+
125
+ ## 🎉 使用
126
+
127
+ 示例:在其他插件上使用
128
+
129
+ ```python
130
+ ...
131
+ from nonebot import require
132
+ require("nonebot_plugin_apscheduler")
133
+ from nonebot_plugin_extrauserperm import isPermUser
134
+
135
+ weather = on_command("天气", permission=isPermUser)`
136
+ ```
137
+
138
+ or
139
+
140
+ ```python
141
+ ...
142
+ from nonebot import require
143
+ require("nonebot_plugin_apscheduler")
144
+ from nonebot_plugin_extrauserperm import isPermUser
145
+
146
+ any_permission = SUPERUSER | GROUP_ADMIN | GROUP_OWNER | Permission(isPermUser)
147
+ weather = on_command("天气", permission=any_permission)
148
+ ```
149
+
150
+
151
+ ### 🎨 效果图
152
+ 如果有效果图的话
@@ -0,0 +1,137 @@
1
+ <div align="center">
2
+ <a href="https://v2.nonebot.dev/store">
3
+ <img src="https://raw.githubusercontent.com/fllesser/nonebot-plugin-template/refs/heads/resource/.docs/NoneBotPlugin.svg" width="310" alt="logo"></a>
4
+
5
+ ## ✨ nonebot-plugin-user-perm ✨
6
+ [![LICENSE](https://img.shields.io/github/license/dontdot/nonebot-plugin-user-perm.svg)](./LICENSE)
7
+ [![pypi](https://img.shields.io/pypi/v/nonebot-plugin-user-perm.svg)](https://pypi.python.org/pypi/nonebot-plugin-user-perm)
8
+ [![python](https://img.shields.io/badge/python-3.10|3.11|3.12|3.13-blue.svg)](https://www.python.org)
9
+ [![uv](https://img.shields.io/badge/package%20manager-uv-black?style=flat-square&logo=uv)](https://github.com/astral-sh/uv)
10
+ <br/>
11
+ [![ruff](https://img.shields.io/badge/code%20style-ruff-black?style=flat-square&logo=ruff)](https://github.com/astral-sh/ruff)
12
+ [![pre-commit](https://results.pre-commit.ci/badge/github/dontdot/nonebot-plugin-user-perm/master.svg)](https://results.pre-commit.ci/latest/github/dontdot/nonebot-plugin-user-perm/master)
13
+
14
+ </div>
15
+
16
+ ## 📖 介绍
17
+
18
+ 设置群聊的某些普通用户使用插件的某个权限命令!
19
+
20
+ 使用onebotv11适配器提供 `isPermUser` 函数给其他插件使用在响应器中
21
+
22
+ 注意:`isPermUser`只接受群消息事件`GroupMessageEvent`
23
+
24
+ > `isPermUser` 将判断这条消息发送人是否是该群聊设置的特定普通用户 + super用户
25
+
26
+ 默认数据格式:{'super': [ ], 'group': { } }
27
+
28
+ > 例如:{'super': [12345], 'group': {'某个qq群号': [112233, 223344]}} \
29
+ > 每个[ ]里填入普通用户的qq号(int类型)
30
+
31
+
32
+ ## 💿 安装
33
+
34
+ <details open>
35
+ <summary>使用 nb-cli 安装</summary>
36
+ 在 nonebot2 项目的根目录下打开命令行, 输入以下指令即可安装
37
+
38
+ nb plugin install nonebot-plugin-user-perm --upgrade
39
+ 使用 **pypi** 源安装
40
+
41
+ nb plugin install nonebot-plugin-user-perm --upgrade -i "https://pypi.org/simple"
42
+ 使用**清华源**安装
43
+
44
+ nb plugin install nonebot-plugin-user-perm --upgrade -i "https://pypi.tuna.tsinghua.edu.cn/simple"
45
+
46
+
47
+ </details>
48
+
49
+ <details>
50
+ <summary>使用包管理器安装</summary>
51
+ 在 nonebot2 项目的插件目录下, 打开命令行, 根据你使用的包管理器, 输入相应的安装命令
52
+
53
+ <details open>
54
+ <summary>uv</summary>
55
+
56
+ uv add nonebot-plugin-user-perm
57
+ 安装仓库 master 分支
58
+
59
+ uv add git+https://github.com/dontdot/nonebot-plugin-user-perm@master
60
+ </details>
61
+
62
+ <details>
63
+ <summary>pdm</summary>
64
+
65
+ pdm add nonebot-plugin-user-perm
66
+ 安装仓库 master 分支
67
+
68
+ pdm add git+https://github.com/dontdot/nonebot-plugin-user-perm@master
69
+ </details>
70
+ <details>
71
+ <summary>poetry</summary>
72
+
73
+ poetry add nonebot-plugin-user-perm
74
+ 安装仓库 master 分支
75
+
76
+ poetry add git+https://github.com/dontdot/nonebot-plugin-user-perm@master
77
+ </details>
78
+
79
+ 打开 nonebot2 项目根目录下的 `pyproject.toml` 文件, 在 `[tool.nonebot]` 部分追加写入
80
+
81
+ plugins = ["nonebot_plugin_user_perm"]
82
+
83
+ </details>
84
+
85
+ <details>
86
+ <summary>使用 nbr 安装(使用 uv 管理依赖可用)</summary>
87
+
88
+ [nbr](https://github.com/fllesser/nbr) 是一个基于 uv 的 nb-cli,可以方便地管理 nonebot2
89
+
90
+ nbr plugin install nonebot-plugin-user-perm
91
+ 使用 **pypi** 源安装
92
+
93
+ nbr plugin install nonebot-plugin-user-perm -i "https://pypi.org/simple"
94
+ 使用**清华源**安装
95
+
96
+ nbr plugin install nonebot-plugin-user-perm -i "https://pypi.tuna.tsinghua.edu.cn/simple"
97
+
98
+ </details>
99
+
100
+
101
+ ## ⚙️ 配置
102
+
103
+ 使用`nonebot-plugin-localstore`持久化保存数据
104
+ 可在 nonebot2 项目的`.env`文件中添加以下配置,使数据文件保存在bot项目下的`data`目录
105
+
106
+ > LOCALSTORE_USE_CWD=True
107
+
108
+
109
+
110
+ ## 🎉 使用
111
+
112
+ 示例:在其他插件上使用
113
+
114
+ ```python
115
+ ...
116
+ from nonebot import require
117
+ require("nonebot_plugin_apscheduler")
118
+ from nonebot_plugin_extrauserperm import isPermUser
119
+
120
+ weather = on_command("天气", permission=isPermUser)`
121
+ ```
122
+
123
+ or
124
+
125
+ ```python
126
+ ...
127
+ from nonebot import require
128
+ require("nonebot_plugin_apscheduler")
129
+ from nonebot_plugin_extrauserperm import isPermUser
130
+
131
+ any_permission = SUPERUSER | GROUP_ADMIN | GROUP_OWNER | Permission(isPermUser)
132
+ weather = on_command("天气", permission=any_permission)
133
+ ```
134
+
135
+
136
+ ### 🎨 效果图
137
+ 如果有效果图的话
@@ -0,0 +1,135 @@
1
+ [project]
2
+ name = "nonebot-plugin-user-perm"
3
+ version = "0.1.1"
4
+ description = "插件描述"
5
+ readme = "README.md"
6
+ requires-python = ">=3.10"
7
+ authors = [{ name = "dontdot", email = "55482264+dontdot@users.noreply.github.com" }]
8
+ dependencies = [
9
+ "nonebot-adapter-onebot",
10
+ "nonebot-plugin-localstore>=0.7.4,<1.0.0", # 存储文件
11
+ "nonebot2>=2.5.0,<3.0.0",
12
+ ]
13
+
14
+ [project.urls]
15
+ Homepage = "https://github.com/dontdot/nonebot-plugin-user-perm"
16
+ Issues = "https://github.com/dontdot/nonebot-plugin-user-perm/issues"
17
+ Repository = "https://github.com/dontdot/nonebot-plugin-user-perm.git"
18
+
19
+ [dependency-groups]
20
+ dev = [
21
+ "bump-my-version>=1.2.7",
22
+ "nonebot2[fastapi]>=2.5.0,<3.0.0",
23
+ "poethepoet>=0.42.1",
24
+ "ruff>=0.15.2,<1.0.0",
25
+ { include-group = "test" },
26
+ ]
27
+ test = [
28
+ "nonebot-adapter-onebot>=2.4.6,<3.0.0",
29
+ "nonebot2[fastapi]>=2.5.0,<3.0.0",
30
+ "nonebug>=0.4.4,<1.0.0",
31
+ "pytest>=9.0.2,<10.0.0",
32
+ "poethepoet>=0.42.1",
33
+ "pytest-asyncio>=1.3.0,<1.4.0",
34
+ "pytest-cov>=7.0.0",
35
+ "pytest-xdist>=3.8.0,<4.0.0",
36
+ ]
37
+
38
+ [build-system]
39
+ requires = ["uv_build>=0.10.0,<0.11.0"]
40
+ build-backend = "uv_build"
41
+
42
+
43
+ [tool.bumpversion]
44
+ current_version = "0.1.1"
45
+ commit = true
46
+ message = "release: bump vesion from {current_version} to {new_version}"
47
+ tag = true
48
+
49
+ [[tool.bumpversion.files]]
50
+ filename = "uv.lock"
51
+ search = "name = \"nonebot-plugin-user-perm\"\nversion = \"{current_version}\""
52
+ replace = "name = \"nonebot-plugin-user-perm\"\nversion = \"{new_version}\""
53
+
54
+ [tool.coverage.report]
55
+ exclude_lines = [
56
+ "raise NotImplementedError",
57
+ "if TYPE_CHECKING:",
58
+ "@overload",
59
+ "except ImportError:",
60
+ ]
61
+
62
+ [tool.nonebot]
63
+ plugins = ["nonebot_plugin_user_perm"]
64
+
65
+ [tool.poe.tasks]
66
+ test = "pytest --cov=src --cov-report xml --junitxml=./junit.xml -n auto"
67
+ bump = "bump-my-version bump"
68
+ show-bump = "bump-my-version show-bump"
69
+
70
+ [tool.pyright]
71
+ pythonVersion = "3.10"
72
+ pythonPlatform = "All"
73
+ defineConstant = { PYDANTIC_V2 = true }
74
+ executionEnvironments = [
75
+ { root = "./tests", extraPaths = [
76
+ "./src",
77
+ ] },
78
+ { root = "./src" },
79
+ ]
80
+ typeCheckingMode = "standard"
81
+ disableBytesTypePromotions = true
82
+
83
+ [tool.pytest]
84
+ addopts = [
85
+ "--import-mode=prepend", # 导入模式
86
+ "--strict-markers", # 严格标记模式
87
+ "--tb=short", # 简短的错误回溯
88
+ "-ra", # 显示所有测试结果摘要
89
+ "-s", # 显示打印信息
90
+ "-v", # 详细输出
91
+ ]
92
+ pythonpath = ["src"]
93
+ asyncio_mode = "auto"
94
+ asyncio_default_fixture_loop_scope = "session"
95
+
96
+ [tool.ruff]
97
+ line-length = 88
98
+
99
+ [tool.ruff.format]
100
+ line-ending = "lf"
101
+
102
+ [tool.ruff.lint]
103
+ select = [
104
+ "F", # Pyflakes
105
+ "W", # pycodestyle warnings
106
+ "E", # pycodestyle errors
107
+ "I", # isort
108
+ "UP", # pyupgrade
109
+ "ASYNC", # flake8-async
110
+ "C4", # flake8-comprehensions
111
+ "T10", # flake8-debugger
112
+ "T20", # flake8-print
113
+ "PYI", # flake8-pyi
114
+ "PT", # flake8-pytest-style
115
+ "Q", # flake8-quotes
116
+ "TID", # flake8-tidy-imports
117
+ "RUF", # Ruff-specific rules
118
+ ]
119
+ ignore = [
120
+ "E402", # module-import-not-at-top-of-file
121
+ "UP037", # quoted-annotation
122
+ "RUF001", # ambiguous-unicode-character-string
123
+ "RUF002", # ambiguous-unicode-character-docstring
124
+ "RUF003", # ambiguous-unicode-character-comment
125
+ "W191", # indentation contains tabs
126
+ "TID252", # relative-import
127
+ ]
128
+
129
+ [tool.ruff.lint.isort]
130
+ length-sort = true
131
+ known-first-party = ["tests/*"]
132
+ extra-standard-library = ["typing_extensions"]
133
+
134
+ [tool.ruff.lint.pyupgrade]
135
+ keep-runtime-typing = true
@@ -0,0 +1,134 @@
1
+ import re
2
+ import json
3
+ from pathlib import Path
4
+ from pydantic import BaseModel
5
+ from typing import Dict, List
6
+
7
+ from nonebot import require, get_driver, logger
8
+ from nonebot.plugin import PluginMetadata
9
+ from nonebot.permission import SUPERUSER
10
+ from nonebot.adapters.onebot.v11 import GroupMessageEvent
11
+
12
+ require("nonebot_plugin_localstore")
13
+
14
+ import nonebot_plugin_localstore as store
15
+
16
+
17
+ __plugin_meta__ = PluginMetadata(
18
+ name="user_perm",
19
+ description="为其他nonebot插件提供q群普通用户权限管理",
20
+ usage="给响应器的rule或者permission添加isPermUser来检查",
21
+ type="library", # library
22
+ homepage="https://github.com/dontdot/nonebot-plugin-user-perm",
23
+ supported_adapters={"~onebot.v11"}, # 仅 onebot
24
+ extra={"author": "dontdot 55482264+dontdot@users.noreply.github.com"},
25
+ )
26
+
27
+ driver = get_driver()
28
+
29
+ data_dir = store.get_plugin_data_dir()
30
+
31
+ data_file_path: Path = data_dir / "user_perm.json"
32
+
33
+
34
+ class Users(BaseModel):
35
+ users: List[int] = []
36
+
37
+
38
+ class PermConfig(BaseModel):
39
+ super: List[int] = []
40
+ group: Dict[int, Users] = {}
41
+
42
+
43
+ class PermStore:
44
+ perm: dict = {}
45
+
46
+ @classmethod
47
+ def _load(cls):
48
+ data_file_path.parent.mkdir(parents=True, exist_ok=True)
49
+ if not data_file_path.exists():
50
+ cls._save(PermConfig().model_dump())
51
+ return
52
+ try:
53
+ with open(data_file_path, "r", encoding="utf-8") as f:
54
+ data = json.load(f)
55
+ if "group" in data:
56
+ data["group"] = {
57
+ int(k): cls._sw_value_int(v) for k, v in data["group"].items()
58
+ }
59
+ cls.perm = data
60
+ return
61
+ except (json.JSONDecodeError, ValueError) as e:
62
+ # 尝试修复读取的数据
63
+ logger.error(f"读取数据文件出错:\n {e}")
64
+ cls._fix_data()
65
+
66
+ @classmethod
67
+ def _save(cls, data=None):
68
+ data_file_path.parent.mkdir(parents=True, exist_ok=True)
69
+ _data = data if data else cls.perm
70
+ if "group" in _data:
71
+ _data["group"] = {
72
+ str(k): cls._sw_value_int(v) for k, v in _data["group"].items()
73
+ }
74
+ with open(data_file_path, "w", encoding="utf-8") as f:
75
+ json.dump(_data, f, indent=4, ensure_ascii=True)
76
+
77
+ @classmethod
78
+ def _sw_value_int(cls, data: List):
79
+ return [int(i) for i in data]
80
+
81
+ @classmethod
82
+ def _sw_value_str(cls, data: List):
83
+ return [str(i) for i in data]
84
+
85
+ @classmethod
86
+ def _fix_data(cls):
87
+ with open(data_file_path, "r", encoding="utf-8") as f:
88
+ err_data = f.read()
89
+ fixed = re.sub(r"(\d+)(?=\s*:)", r'"\1"', err_data)
90
+ logger.debug(f"err_data:{err_data}")
91
+ logger.debug(f"fixed:{fixed}")
92
+ try:
93
+ fixed_data = json.loads(fixed)
94
+ logger.debug(f"fixed_data:{fixed_data}")
95
+ fixed_data["group"] = {
96
+ int(k): cls._sw_value_int(v) for k, v in fixed_data["group"].items()
97
+ }
98
+ cls.perm = fixed_data
99
+ cls._save()
100
+ logger.info("Json格式已修复")
101
+ except:
102
+ # 修复失败,使用默认
103
+ logger.info("数据Json文件修复失败,使用默认")
104
+ cls.perm = PermConfig().model_dump()
105
+ cls._save()
106
+
107
+ @classmethod
108
+ async def get_user_perm(cls, group_id) -> List[int]:
109
+ _users = []
110
+ _users.extend(cls.perm["group"].get(group_id, []))
111
+ _users.extend(cls.perm.get("super", []))
112
+ _users = list(set(_users))
113
+ return _users
114
+
115
+
116
+ async def isPermUser(event: GroupMessageEvent) -> bool:
117
+ user = event.user_id
118
+ try:
119
+ if user in (_premUser := await PermStore.get_user_perm(event.group_id)):
120
+ return True
121
+ else:
122
+ return False
123
+ except Exception as e:
124
+ logger.error(f"PermUser判断失败:\n{e}")
125
+ return False
126
+
127
+
128
+ @driver.on_startup
129
+ async def _():
130
+ PermStore._load()
131
+ logger.info(f"额外用户权限已启动,具体如下:\n{PermStore.perm}")
132
+
133
+
134
+ __all__ = ["PermStore", "isPermUser"]