├── .github
└── workflows
│ └── python-publish.yml
├── LICENSE
├── README.md
├── image
├── image.png
└── image2.png
├── nonebot_plugin_dog
├── __init__.py
├── check.py
├── handle.py
├── update.py
└── utils.py
├── pyproject.toml
└── setup.py
/.github/workflows/python-publish.yml:
--------------------------------------------------------------------------------
1 | # This workflow will upload a Python Package using Twine when a release is created
2 | # For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-python#publishing-to-package-registries
3 |
4 | # This workflow uses actions that are not certified by GitHub.
5 | # They are provided by a third-party and are governed by
6 | # separate terms of service, privacy policy, and support
7 | # documentation.
8 |
9 | name: Build and Upload
10 |
11 | on:
12 | release:
13 | types: [published]
14 |
15 | permissions:
16 | contents: read
17 |
18 | jobs:
19 | deploy:
20 |
21 | runs-on: ubuntu-latest
22 |
23 | steps:
24 | - uses: actions/checkout@v3
25 | - name: Set up Python
26 | uses: actions/setup-python@v3
27 | with:
28 | python-version: '3.x'
29 | - name: Install dependencies
30 | run: |
31 | python -m pip install --upgrade pip
32 | pip install build
33 | - name: Build package
34 | run: python -m build
35 | - name: Publish package
36 | uses: pypa/gh-action-pypi-publish@27b31702a0e7fc50959f5ad993c78deac1bdfc29
37 | with:
38 | user: __token__
39 | password: ${{ secrets.PYPI_API_TOKEN }}
40 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2023 Reversedeer
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 | # nonebot-plugin-dog
14 |
15 | _✨随机返回一句舔狗日记...(~~舔狗,舔到最后一无所有~~)✨_
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 | ## 介绍: 点点Star✨
32 |
33 | > 在群聊里发送“舔狗日记/一言”(等)命令时,bot返回一句舔狗日记/一言等文案
34 | >
35 | > 你可能需要在env里配置指令响应头 " / ",取决于你的command_start设置
36 | >
37 | > SUPERUSER | 群主 | 管理 可以使用:“开启/关闭文案”来控制指令开关(默认=true)
38 | >
39 | > 插件所有配置文件和备份目录在/date/dog/下
40 | >
41 | > ⚠️插件支持手动检查更新:Command: "/检查更新",如果没有报错,发送: "/重启"完成bot更新,可不使用pip install --upgrade 更新
42 |
43 | ## 安装方式
44 |
45 | ### nb-cli(推荐)
46 |
47 | ```
48 | nb plugin install nonebot_plugin_dog
49 | ```
50 |
51 |
52 | pip
53 |
54 | ```
55 | pip install nonebot_plugin_dog
56 | ```
57 |
58 |
59 |
60 | ### 更新
61 |
62 | ```
63 | pip install --upgrade nonebot-plugin-dog
64 | ```
65 |
66 | #### 还可以在群内发送指令:"/检查更新"来检查更新; 发送 "/重启"完成bot更新(推荐)
67 |
68 | ## 配置
69 |
70 | 在bot目录对应的.env.*文件中添加(有默认值,cd=0为不限制)
71 |
72 | | config | type | default | example | usage |
73 | | :---------: | :--: | :-----: | :------------: | :------------------------: |
74 | | dog_cd | int | 20 | dog_cd = 20 | 调用''舔狗日记'cd默认值 |
75 | | laugh_cd | int | 20 | laugh_cd=20 | 调用''讲个笑话''cd的默认值 |
76 | | hitokoto_cd | int | 20 | hitokoto_cd=20 | 调用"一言"cd的默认值 |
77 | | wenan_cd | int | 20 | wenan_cd=20 | 调用“文案”cd的默认值 |
78 |
79 | ## 示例
80 |
81 |
82 |
83 |
84 |
85 | ## TODO
86 |
87 | - [x] 增加指令开关
88 | - [x] 增加插件热更新
89 | - [x] 增加CD限制
90 | - [ ] 增加图片发送
91 | - [x] 整合更多的API
92 |
93 |
94 | 更新日志
95 |
96 | - 0.3.0
97 |
98 | - 适配插件元数据
99 |
100 | - 优化代码
101 |
102 | - 0.2.9
103 | - 修复热更新bug
104 |
105 | - 0.2.8
106 | - 实现插件热更新
107 |
108 | - 0.2.7.1
109 | - 增加"舔狗日记"api
110 |
111 | - 插件支持手动检测更新
112 | - 0.2.7 # 2023-3-13
113 | - 修复api
114 | - 0.2.6 #2023-3-5
115 | - 修复了文案中存在换行符,且无法换行的错误
116 |
117 | - 优化cd逻辑,可以分别对应每一个指令
118 |
119 | - 整合了更多的api
120 | - 0.2.5 #2023-3-3
121 | - 整合了更多的api
122 | - 优化cd模式
123 | - 0.2.3 #2023-2-1
124 | - 修复文本末多出的空行
125 | - 修复readme中的错误
126 | - 增加指令开关
127 | - 更改指令CD默认值为20
128 | - 0.1.9 #2023-1-30
129 | - 增加cd限制
130 | - 0.1.0 #2023-1-29
131 | - 发布并优化代码
132 |
133 |
134 |
135 | ## 关于 ISSUE
136 |
137 | 以下 ISSUE 会被直接关闭
138 |
139 | - 提交 BUG 不使用 Template
140 | - 询问已知问题
141 | - 提问找不到重点
142 | - 重复提问
143 |
144 | > 请注意, 开发者并没有义务回复您的问题. 您应该具备基本的提问技巧。
145 | > 有关如何提问,请阅读[《提问的智慧》](https://github.com/ryanhanwu/How-To-Ask-Questions-The-Smart-Way/blob/main/README-zh_CN.md)
146 |
147 |
148 |
149 | ## 其他插件
150 |
151 | [QQ群消息,事件检测插件](https://github.com/Reversedeer/nonebot_plugin_eventmonitor)
--------------------------------------------------------------------------------
/image/image.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Reversedeer/nonebot_plugin_dog/9d638dd68c20e06e51cf11419a284b471613a3b1/image/image.png
--------------------------------------------------------------------------------
/image/image2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Reversedeer/nonebot_plugin_dog/9d638dd68c20e06e51cf11419a284b471613a3b1/image/image2.png
--------------------------------------------------------------------------------
/nonebot_plugin_dog/__init__.py:
--------------------------------------------------------------------------------
1 | ''' 插件入口'''
2 | import os
3 | import platform
4 |
5 |
6 | from nonebot.params import ArgStr
7 | from nonebot.matcher import Matcher
8 | from nonebot.permission import SUPERUSER
9 | from nonebot import on_command, on_endswith
10 | from nonebot.plugin import PluginMetadata
11 | from nonebot.adapters.onebot.v11.permission import GROUP_OWNER, GROUP_ADMIN
12 |
13 | from .utils import utils
14 | from .handle import dog
15 |
16 | on_endswith(
17 | "文案",
18 | permission=SUPERUSER | GROUP_ADMIN | GROUP_OWNER,
19 | priority=10,
20 | block=True,
21 | handlers=[dog.openstates]
22 | )
23 | on_command(
24 | "舔狗日记",
25 | aliases={"舔狗嘤嘤嘤"},
26 | priority=10,
27 | block=True,
28 | handlers=[dog.lickdog]
29 | )
30 | on_command(
31 | "讲个笑话",
32 | aliases={"说个笑话"},
33 | priority=10,
34 | block=True,
35 | handlers=[dog.laugh]
36 | )
37 | on_command(
38 | "一言",aliases={"一言"},
39 | priority=10,
40 | block=True,
41 | handlers=[dog.hitokoto]
42 | )
43 | on_command(
44 | "文案语录",
45 | aliases={"语录"},
46 | priority=10,
47 | block=True,
48 | handlers=[dog.wenan]
49 | )
50 | on_command(
51 | "检查更新",
52 | priority=1,
53 | permission=SUPERUSER,
54 | block=True,
55 | handlers=[dog.check]
56 | )
57 | restart = on_command(
58 | "重启",
59 | aliases={"restart"},
60 | priority=1,
61 | permission=SUPERUSER,
62 | block=True
63 | )
64 |
65 | @restart.got("flag", prompt="确定是否重启?确定请回复[是|好|确定](重启失败咱们将失去联系,请谨慎!)")
66 | async def _(matcher: Matcher, flag: str = ArgStr("flag")):
67 | if flag.lower() in {"true", "是", "好", "确定", "确定是"}:
68 | await matcher.send("开始重启..请稍等...")
69 | open("data/dog/new_version", "w")
70 | if str(platform.system()).lower() == "windows":
71 | import sys
72 |
73 | python = sys.executable
74 | os.execl(python, python, *sys.argv)
75 | else:
76 | os.system("./restart.sh")
77 | else:
78 | await matcher.send("已取消操作...")
79 |
80 | __plugin_meta__ = PluginMetadata(
81 | name="dog",
82 | description="随机返回一句舔狗日记...嘤嘤嘤和其他文案的插件",
83 | usage=utils.usage,
84 | type="application",
85 | homepage="https://github.com/Reversedeer/nonebot_plugin_dog",
86 | supported_adapters={"~onebot.v11"},
87 | extra={
88 | "author": "Reversedeer",
89 | "version": "0.3.0",
90 | "priority": 10,
91 | }
92 | )
--------------------------------------------------------------------------------
/nonebot_plugin_dog/check.py:
--------------------------------------------------------------------------------
1 | import os
2 | import httpx
3 | import shutil
4 | import tarfile
5 |
6 | from pathlib import Path
7 | from nonebot.log import logger
8 | from nonebot.adapters.onebot.v11 import Bot, Message
9 |
10 | from .update import config
11 | from .utils import utils
12 |
13 |
14 | async def fetch_data(tar_gz_url):
15 | async with httpx.AsyncClient() as client:
16 | return await client.get(tar_gz_url)
17 |
18 | async def download_file(tar_gz_url, latest_tar_gz):
19 | async with httpx.AsyncClient() as client:
20 | response = await client.get(tar_gz_url)
21 | if response.status_code == 200:
22 | with open(latest_tar_gz, "wb") as f:
23 | f.write(response.content)
24 | return True
25 | else:
26 | return False
27 |
28 |
29 |
30 | async def check_update(bot: Bot):
31 | global latest_version
32 | logger.info("开始更新插件...")
33 | data = await config.get_latest_version_data()
34 | if data:
35 | latest_version = data["name"]
36 | if utils.current_version != latest_version:
37 | tar_gz_url = data["tarball_url"]
38 | logger.info(f"检测插件dog:有更新,当前版本:{utils.current_version},最新版本:{latest_version}")
39 | await bot.send_private_msg(
40 | user_id=int(list(bot.config.superusers)[0]),
41 | message=f"检测插件:dog有更新,当前版本:{utils.current_version},最新版本:{latest_version}\n" f"开始更新.....",
42 | )
43 | tar_gz_url = (await fetch_data(tar_gz_url)).headers.get("Location")
44 | if await download_file(tar_gz_url, config.latest_tar_gz):
45 | logger.info("下载插件最新版文件完成....")
46 | error = await _file_handle(latest_version)
47 | if error:
48 | return 998, error
49 | logger.info("更新完毕,清理文件完成....")
50 | await bot.send_private_msg(
51 | user_id=int(list(bot.config.superusers)[0]),
52 | message=Message(
53 | f"插件更新完成,版本:{utils.current_version} -> {latest_version}\n"
54 | f"插件更新日期:{data['created_at']}\n"
55 | ),
56 | )
57 | return 200, ""
58 | else:
59 | logger.warning(f"下载最新版本失败..请检查网络是否通畅.版本号:{latest_version}")
60 | await bot.send_private_msg(
61 | user_id=int(list(bot.config.superusers)[0]),
62 | message=f"下载最新版本失败qwq..请检查网络是否通畅.版本号:{latest_version}",
63 | )
64 | else:
65 | logger.info(f"自动获取版本成功:{latest_version},当前版本为最新版,无需更新...")
66 | await bot.send_private_msg(
67 | user_id=int(list(bot.config.superusers)[0]),
68 | message=f"自动获取版本成功:{latest_version},当前版本为最新版,无需更新...",
69 | )
70 | else:
71 | logger.warning("自动获取版本失败....")
72 | await bot.send_private_msg(
73 | user_id=int(list(bot.config.superusers)[0]), message="自动获取版本失败...."
74 | )
75 | return 999, ""
76 |
77 |
78 | async def _file_handle(latest_version: str) -> str:
79 | # 接收最新版本号作为参数,并返回处理结果字符串
80 |
81 | if not config.temp_dir.exists():
82 | # 检查临时目录是否存在,如果不存在则创建
83 | config.temp_dir.mkdir(exist_ok=True, parents=True)
84 |
85 | if config.backup_dir.exists():
86 | # 如果备份目录存在,则删除整个备份目录
87 | shutil.rmtree(config.backup_dir)
88 |
89 | tf = None
90 | # 初始化一个tarfile对象tf
91 |
92 | config.backup_dir.mkdir(exist_ok=True, parents=True)
93 | # 创建备份目录,如果备份目录已存在,则不会重新创建
94 |
95 | logger.info("开始解压文件压缩包....")
96 | # 记录日志,表示开始解压文件压缩包
97 | tf = tarfile.open(config.latest_tar_gz)
98 | # 打开文件压缩包,获取tarfile对象tf
99 | tf.extractall(config.temp_dir)
100 | # 将压缩包中的所有文件解压到临时目录temp_dir中
101 | logger.info("解压文件压缩包完成....")
102 | # 记录日志,表示解压文件压缩包完成
103 |
104 | latest_file = Path(config.temp_dir) / os.listdir(config.temp_dir)[0]
105 | # 获取临时目录中的第一个文件,作为最新版本的文件夹路径
106 | update_info_file = Path(latest_file) / os.listdir(latest_file)[1]
107 | # 获取最新版本文件夹中的第二个文件,作为更新信息文件的路径
108 | try:
109 |
110 | pycache_dir = os.path.join(config.destination_directory, '__pycache__')
111 | if os.path.exists(pycache_dir):
112 | shutil.rmtree(pycache_dir)
113 |
114 | for file in os.listdir(config.destination_directory):
115 | if file != '__pycache__':
116 | logger.info("正在备份插件目录...")
117 | temp_file = os.path.join(config.destination_directory, file)
118 | backup_file = os.path.join(config.backup_dir, file)
119 | shutil.copy2(temp_file, backup_file)
120 | logger.info("文件备份成功")
121 |
122 |
123 | for file in os.listdir(update_info_file):
124 | logger.info("开始更新插件...")
125 | updata_file = os.path.join(update_info_file, file)
126 | destination_file = os.path.join(config.destination_directory, file)
127 | shutil.copy2(updata_file, destination_file)
128 | logger.info("插件更新成功!")
129 | except Exception as e:
130 | raise e
131 |
132 | if tf:
133 | tf.close()
134 | # 关闭tarfile对象,释放资源
135 | if config.temp_dir.exists():
136 | shutil.rmtree(config.temp_dir)
137 | # 删除临时目录及其中的所有文件
138 | if config.latest_tar_gz.exists():
139 | config.latest_tar_gz.unlink()
140 | # 删除最新版本的压缩包文件
141 |
142 | with open(config.version_file, "w", encoding="utf-8") as f:
143 | f.write(f"{latest_version}")
144 | # 将最新版本号写入版本文件中
145 |
146 | os.system(f"poetry run pip install -r {(update_info_file / 'pyproject.toml').absolute()}")
147 | # 使用os.system命令执行shell命令,安装更新后的依赖包
148 |
149 | return ""
150 | # 返回一个空字符串
151 |
152 |
--------------------------------------------------------------------------------
/nonebot_plugin_dog/handle.py:
--------------------------------------------------------------------------------
1 | import re
2 | import httpx
3 | import random
4 | import nonebot
5 |
6 | from nonebot.log import logger
7 | from nonebot.matcher import Matcher
8 | from nonebot.adapters.onebot.v11 import MessageEvent, MessageSegment, GroupMessageEvent, Bot
9 |
10 | from .check import check_update
11 | from .utils import utils, check_group_allow, write_group_data, groupdata
12 |
13 | class Dog:
14 | @staticmethod
15 | async def lickdog(matcher: Matcher, event: GroupMessageEvent): # 定义异步函数 dog
16 | if not (await check_group_allow(str(event.group_id))):
17 | await matcher.finish(utils.notAllow, at_sender=True)
18 | uid = event.get_user_id() # 获取用户id
19 | try:
20 | cd = event.time - utils.dog_CD_dir[uid] # 计算cd
21 | except KeyError:
22 | cd = utils.dog_cd + 1 # 没有记录则cd为cd_time+1
23 | if (
24 | cd > utils.dog_cd
25 | or event.get_user_id() in nonebot.get_driver().config.superusers
26 | ): # 记录cd
27 | utils.dog_CD_dir.update({uid: event.time})
28 | urls = ["https://api.mxycn.cn/api/tgrj.php", "https://api.oick.cn/dog/api.php"]
29 | url = random.choice(urls)
30 | try:
31 | # 使用 httpx.AsyncClient 获取 API,存储为 response 变量
32 | async with httpx.AsyncClient() as client:
33 | response = await client.get(url)
34 | response_text = response.text
35 | except Exception as error:
36 | await matcher.finish(MessageSegment.text(str(error)))
37 | await matcher.finish(MessageSegment.text(response_text.strip()), block=True)
38 | else:
39 | await matcher.finish(
40 | MessageSegment.text(f"不要深情了喵,休息{utils.dog_cd - cd:.0f}秒后再找我喵~"),
41 | at_sender=True, block=True)
42 |
43 | @staticmethod
44 | async def laugh(event: GroupMessageEvent, matcher: Matcher): # 定义异步函数 laugh
45 | if not (await check_group_allow(str(event.group_id))):
46 | await matcher.finish(utils.notAllow, at_sender=True)
47 | uid = event.get_user_id() # 获取用户id
48 | try:
49 | cd = event.time - utils.laugh_CD_dir[uid] # 计算cd
50 | except KeyError:
51 | cd = utils.laugh_cd + 1 # 没有记录则cd为cd_time+1
52 | if (
53 | cd > utils.laugh_cd
54 | or event.get_user_id() in nonebot.get_driver().config.superusers
55 | ): # 记录cd
56 | utils.laugh_CD_dir.update({uid: event.time})
57 | try:
58 | # 使用 httpx.AsyncClient 获取 API,存储为 response 变量
59 | async with httpx.AsyncClient() as client:
60 | response = await client.get("https://api.mxycn.cn/api/qwxh.php")
61 | response_text = response.text
62 | except Exception as error:
63 | await matcher.finish(MessageSegment.text(str(error)))
64 | response_text = re.sub(r'。。\\n', '\n', response_text)
65 | response_text = response_text.replace('。。', '')
66 | await matcher.finish(MessageSegment.text(response_text.strip()), block=True)
67 | else:
68 | await matcher.finish(
69 | MessageSegment.text(f"我在准备更精彩的笑话喵,等待{utils.laugh_cd - cd:.0f}秒后再找我喵~"),
70 | at_sender=True, block=True)
71 |
72 |
73 | @staticmethod
74 | async def hitokoto(event: GroupMessageEvent, matcher: Matcher): # 定义异步函数hitokoto
75 | if not (await check_group_allow(str(event.group_id))):
76 | await matcher.finish(utils.notAllow, at_sender=True)
77 | uid = event.get_user_id() # 获取用户id
78 | try:
79 | cd = event.time - utils.hitokoto_CD_dir[uid] # 计算cd
80 | except KeyError:
81 | # 没有记录则cd为cd_time+1
82 | cd = utils.hitokoto_cd + 1
83 | if (
84 | cd > utils.hitokoto_cd
85 | or event.get_user_id() in nonebot.get_driver().config.superusers
86 | ): # 记录cd
87 | utils.hitokoto_CD_dir.update({uid: event.time})
88 | try:
89 | async with httpx.AsyncClient() as client:
90 | response = await client.get("https://v1.hitokoto.cn?c=a&c=b&c=c&c=d&c=e&c=f&c=j")
91 | except Exception as error:
92 | await matcher.finish(
93 | MessageSegment.text("获取一言失败"), at_sender=True, block=True
94 | )
95 | data = response.json()
96 | msg = data["hitokoto"]
97 | add = ""
98 | if works := data["from"]:
99 | add += f"《{works}》"
100 | if from_who := data["from_who"]:
101 | add += f"{from_who}"
102 | if add:
103 | msg += f"\n——{add}"
104 | await matcher.finish(msg)
105 | else:
106 | await matcher.finish(
107 | MessageSegment.text(f"休息 {utils.hitokoto_cd - cd:.0f}秒后才能再使用喵~"),
108 | at_sender=True, block=True)
109 |
110 |
111 | @staticmethod
112 | async def wenan(event: GroupMessageEvent, matcher: Matcher): # 定义异步函数wenan
113 | if not (await check_group_allow(str(event.group_id))):
114 | await matcher.finish(utils.notAllow, at_sender=True)
115 | uid = event.get_user_id() # 获取用户id
116 | try:
117 | cd = event.time - utils.wenan_CD_dir[uid] # 计算cd
118 | except KeyError:
119 | cd = utils.wenan_cd + 1 # 没有记录则cd为cd_time+1
120 | if (
121 | cd > utils.wenan_cd
122 | or event.get_user_id() in nonebot.get_driver().config.superusers
123 | ): # 记录cd
124 | utils.wenan_CD_dir.update({uid: event.time})
125 | try:
126 | # 使用 httpx.AsyncClient 获取 API,存储为 response 变量
127 | async with httpx.AsyncClient() as client:
128 | response = await client.get("https://api.mxycn.cn/api/sgyl.php")
129 | response_text = response.text
130 | except Exception as error:
131 | await matcher.finish(MessageSegment.text(str(error)))
132 | await matcher.finish(MessageSegment.text(response_text.strip()), block=True)
133 | else:
134 | await matcher.finish(
135 | MessageSegment.text(f"文案准备中喵,等待{utils.wenan_cd - cd:.0f}秒后再找我喵~"),
136 | at_sender=True, block=True)
137 |
138 | @staticmethod
139 | async def openstates(event: GroupMessageEvent, matcher: Matcher):
140 | gid = str(event.group_id) # 群号
141 | # 获取用户输入的参数
142 | command = event.message.extract_plain_text().replace("文案", "")
143 | if command == "开启":
144 | if gid in groupdata:
145 | groupdata[gid]["allow"] = True
146 | else:
147 | groupdata.update({gid: {"allow": True}})
148 | write_group_data()
149 | await matcher.finish("功能已开启喵~")
150 | elif "关闭" in command:
151 | if gid in groupdata:
152 | groupdata[gid]["allow"] = False
153 | else:
154 | groupdata.update({gid: {"allow": False}})
155 | write_group_data()
156 | await matcher.finish("功能已禁用喵~")
157 | else:
158 | return
159 |
160 | @staticmethod
161 | async def check(bot: Bot, event: MessageEvent):
162 | try:
163 | code, error = await check_update(bot)
164 | if error:
165 | logger.error(f"错误: {error}", "插件检查更新")
166 | await bot.send_private_msg(
167 | user_id=event.user_id, message=f"更新插件dog更新时发生未知错误 {error}"
168 | )
169 | except Exception as e:
170 | logger.error("更新插件dog时发生未知错误", "检查更新", e=e)
171 | await bot.send_private_msg(
172 | user_id=event.user_id,
173 | message=f"更新插件dog时发生未知错误 {type(e)}: {e}",
174 | )
175 | else:
176 | if code == 200:
177 | await bot.send_private_msg(user_id=event.user_id, message="更新完毕,请重启bot....")
178 |
179 | dog = Dog()
--------------------------------------------------------------------------------
/nonebot_plugin_dog/update.py:
--------------------------------------------------------------------------------
1 | import os
2 | import httpx
3 | import nonebot
4 | import platform
5 |
6 | from pathlib import Path
7 | from nonebot.log import logger
8 | from nonebot.adapters.onebot.v11 import Bot
9 |
10 |
11 | class Config:
12 |
13 | release_url = "https://api.github.com/repos/Reversedeer/nonebot_plugin_dog/releases/latest"
14 | config_path = Path() / "data/dog"
15 | latest_tar_gz = config_path / "latest_file.tar.gz"
16 | temp_dir = config_path / "temp"
17 | backup_dir = config_path / "backup"
18 | version_file = config_path / "new_version"
19 | destination_directory = 'src/plugins/nonebot_plugin_dog' # 目标文件夹
20 | driver = nonebot.get_driver()
21 |
22 | @staticmethod
23 | @driver.on_bot_connect
24 | async def remind(bot: Bot):
25 | system = platform.system()
26 | if system != 'windows':
27 | restart = config.config_path / "restart.sh"
28 | if not restart.exists():
29 | with open(restart, "w", encoding="utf8") as f:
30 | f.write(
31 | (
32 | f"pid=$(netstat -tunlp | grep {str(bot.config.port)}"
33 | + " | awk '{print $7}')\n"
34 | "pid=${pid%/*}\n"
35 | "kill -9 $pid\n"
36 | "sleep 3\n"
37 | "nb run"
38 | )
39 | )
40 | os.system("chmod +x ./restart.sh")
41 | logger.info("已自动生成 restart.sh(重启) 文件,请检查脚本是否与本地指令符合...")
42 | Version = config.version_file
43 | if Version.exists():
44 | await bot.send_private_msg(
45 | user_id=int(list(bot.config.superusers)[0]),
46 | message="插件更新成功"
47 | )
48 | Version.unlink()
49 |
50 | @staticmethod
51 | async def get_latest_version_data() -> dict:
52 | for _ in range(3):
53 | try:
54 | async with httpx.AsyncClient() as client:
55 | res = await client.get(config.release_url)
56 | if res.status_code == 200:
57 | return res.json()
58 | except TimeoutError:
59 | pass
60 | except Exception as e:
61 | logger.error("检查最新版本失败")
62 | return {}
63 |
64 | config = Config()
--------------------------------------------------------------------------------
/nonebot_plugin_dog/utils.py:
--------------------------------------------------------------------------------
1 | import os
2 | import json
3 | import nonebot
4 |
5 | class Utils:
6 | def __init__(self) -> None:
7 |
8 | self.usage = """
9 | 指令1:/舔狗日记
10 | 指令2:/讲个笑话
11 | 指令3:/一言
12 | 指令4:/文案语录
13 | 指令5:/检查更新
14 | 指令6:/重启
15 | 指令7:/开启|关闭文案
16 | """
17 | self.dog_CD_dir = {} # 记录舔狗日记cd的字典
18 | self.laugh_CD_dir = {} # 记录讲个笑话cd的字典
19 | self.hitokoto_CD_dir = {} # 记录一言cd的字典
20 | self.wenan_CD_dir = {} # 记录文案cd的字典
21 | self.current_version = '0.3.0'
22 | config = nonebot.get_driver().config # 获取配置
23 | self.dog_cd: int = getattr(config, "dog_cd", 20)
24 | self.laugh_cd: int = getattr(config, "laugh_cd", 20)
25 | self.hitokoto_cd: int = getattr(config, "hitokoto_cd", 20)
26 | self.wenan_cd: int = getattr(config, "wenan_cd", 20)
27 | self.notAllow = "群内还未开启文案功能, 请管理员或群主发送\"开启文案\", \"关闭文案\"以开启/关闭该功能"
28 |
29 | utils = Utils()
30 |
31 | if os.path.exists("data/dog/groupdata.json"): # 读取用户数据
32 | with open("data/dog/groupdata.json", "r", encoding="utf-8") as f:
33 | groupdata = json.load(f)
34 | else: # 不存在则创建
35 | if not os.path.exists("data/dog"):
36 | os.makedirs("data/dog") # 创建文件夹
37 | groupdata = {}
38 |
39 | async def check_group_allow(gid: str) -> bool:
40 | #检查群是否允许
41 | if gid not in groupdata:
42 | groupdata[gid] = {"allow": True}# 写入默认值为true
43 | return groupdata[gid]["allow"]
44 |
45 |
46 | def write_group_data() -> None:
47 | #写入群配置
48 | with open("data/dog/groupdata.json", "w", encoding="utf-8") as f:
49 | json.dump(groupdata, f, indent=4)
50 |
51 |
52 |
53 |
54 |
--------------------------------------------------------------------------------
/pyproject.toml:
--------------------------------------------------------------------------------
1 | [tool.poetry]
2 | name = "nonebot-plugin-dog"
3 | version = "0.3.01"
4 | description = "随机返回一句舔狗日记...嘤嘤嘤"
5 | license = "MIT"
6 | authors = ["Reversedeer"]
7 | readme = "README.md"
8 | homepage = "https://github.com/Reversedeer/nonebot_plugin_dog"
9 | repository = "https://github.com/Reversedeer/nonebot_plugin_dog"
10 |
11 |
12 | [tool.poetry.dependencies]
13 | python = "^3.8"
14 | nonebot2 = ">=2.0.0rc2"
15 | httpx = "^0.23.1"
16 | poetry = "^1.5.0"
17 | nonebot-adapter-onebot = ">=2.1.3"
18 |
19 | [build-system]
20 | requires = ["poetry-core>=1.0.0"]
21 | build-backend = "poetry.core.masonry.api"
--------------------------------------------------------------------------------
/setup.py:
--------------------------------------------------------------------------------
1 | import setuptools
2 |
3 | with open("README.md", "r", encoding="utf-8") as fh:
4 | long_description = fh.read()
5 |
6 | setuptools.setup(
7 | name="nonebot_plugin_dog",
8 | version="0.3.01",
9 | author="Reversedeer",
10 | description="Lick the dog diary! Lick the dog and lick to the last nothing.",
11 | long_description=long_description,
12 | long_description_content_type="text/markdown",
13 | url="https://github.com/Reversedeer/nonebot_plugin_dog",
14 | project_urls={
15 | "Bug Tracker": "https://github.com/Reversedeer/nonebot_plugin_dog/issues",
16 | },
17 | classifiers=[
18 | "Programming Language :: Python :: 3",
19 | "License :: OSI Approved :: MIT License",
20 | "Operating System :: OS Independent",
21 | ],
22 | packages=setuptools.find_packages(),
23 | python_requires=">=3.8",
24 | install_requires = [
25 | 'httpx>=0.23.1',
26 | 'nonebot2>=2.0.0rc2',
27 | 'poetry>=1.5.0',
28 | "nonebot-adapter-onebot>=2.1.3"
29 | ]
30 | )
--------------------------------------------------------------------------------