Skip to content

Commit

Permalink
Merge pull request #58 from Sevenyine/dev
Browse files Browse the repository at this point in the history
点赞功能的半成品
  • Loading branch information
LambdaYH authored Oct 22, 2023
2 parents 6729f64 + b50e367 commit 1ed0180
Show file tree
Hide file tree
Showing 7 changed files with 164 additions and 34 deletions.
10 changes: 8 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
# Nonebot 漂流瓶插件
# **⚠️注意**
> 2023年10月22日,本插件推送了2.0.0版本。建议在升级2.0.0版本前,先运行`nb datastore upgrade`命令(需要[nb_cli](https://github.com/nonebot/nb-cli))。
>
## 安装
- 使用 `pip install nonebot_plugin_bottle`
- 使用 `nb plugin install nonebot_plugin_bottle`
Expand All @@ -22,7 +25,7 @@
## 功能须知
- 所有用户:
- `扔漂流瓶`指令无字数限制,如需要可在代码中修改。若只说了扔漂流瓶,则插件将会监听用户的下一条消息。
- `捡漂流瓶`若捡到的漂流瓶存在回复,则会显示最近三条(默认),使用`查看漂流瓶`查看所有回复
- `捡漂流瓶`若捡到的漂流瓶存在回复,则会显示最近三条(默认),使用`查看漂流瓶`查看所有回复,捡漂流瓶后发送`+`可以点赞漂流瓶。
- `查看漂流瓶`为保证随机性,无评论时不展示漂流瓶内容,可在代码中修改。漂流瓶的发送者可以通过本指令查看内容,无论有无评论。
- `评论漂流瓶`评论内容将通过该瓶子扔出的方式告诉扔出瓶子的人
- `举报漂流瓶`五次(默认)后将自动删除,举报成功后会私聊SUPERUSER漂流瓶详情内容
Expand Down Expand Up @@ -81,7 +84,7 @@
## 配置文件(.env.*

| 配置项 | 配置名 | 变量类型 | 默认值 |
|:--------|:----------|:-------------:|------:|
|:--------|:----------|:-------------:|:------:|
| API KEY | nonebot_plugin_bottle_api_key | str | "" |
| SECRET KEY | nonebot_plugin_bottle_secret_key | str | "" |
| 是否缓存图片 | nonebot_plugin_bottle_local_storage | bool | True |
Expand All @@ -91,6 +94,9 @@


## 更新日志
- 2.0.0 [2023-10-22] [#58](https://github.com/Todysheep/nonebot_plugin_bottle/pull/58)
- 添加漂流瓶点赞功能
- 格式化代码
- ***重构版本*** 1.0.0 [2023-3-10] [#32](https://github.com/Todysheep/nonebot_plugin_bottle/issues/32) [@LambdaYH](https://github.com/LambdaYH)
- 使用`nonebot_plugin_datastore`重构
- 异步读取违禁词文件
Expand Down
101 changes: 73 additions & 28 deletions nonebot_plugin_bottle/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import random
import asyncio
from typing import Union

from nonebot.typing import T_State
from nonebot.matcher import Matcher
Expand All @@ -22,7 +23,7 @@
)

from .model import Bottle
from .config import Config, maxlen, maxrt, rtrate
from .config import Config, maxrt, maxlen, rtrate
from .data_source import (
ba,
text_audit,
Expand Down Expand Up @@ -61,7 +62,7 @@
"unique_name": "nonebot_plugin_bottle",
"example": "扔漂流瓶\n寄漂流瓶\n捡漂流瓶\n评论漂流瓶\n举报漂流瓶\n查看漂流瓶\n删除漂流瓶",
"author": "Todysheep",
"version": "1.0.0",
"version": "2.0.0",
},
)

Expand Down Expand Up @@ -96,9 +97,9 @@


async def get_bottle(
index: str, matcher: Matcher, session: AsyncSession, include_del=False
index: Union[str, int], matcher: Matcher, session: AsyncSession, include_del=False
) -> Bottle:
if not index.isdigit():
if isinstance(index, str) and not index.isdigit():
await matcher.finish("漂流瓶编号必须为正整数!")
bottle = await bottle_manager.get_bottle(
index=int(index), session=session, include_del=include_del
Expand Down Expand Up @@ -132,7 +133,7 @@ async def _(
bottles_info = []
for bottle in bottles:
content_preview = get_content_preview(bottle)
bottles_info.append(f"#{bottle.id}{content_preview}")
bottles_info.append(f"#{bottle.id}【+{bottle.like}{content_preview}")

# 整理消息
messages = []
Expand Down Expand Up @@ -202,7 +203,7 @@ async def _(
ba.add("cooldown", event.user_id)

if "__has_content__" not in state and message_text in cancel:
await throw.finish(MessageSegment.reply(message_id)+"已取消扔漂流瓶操作。")
await throw.finish(MessageSegment.reply(message_id) + "已取消扔漂流瓶操作。")

if maxlen != 0 and ((msg_len := len(message_text)) > maxlen):
await throw.finish(
Expand All @@ -222,9 +223,16 @@ async def _(
audit = await text_audit(text=message_text)
if not audit == "pass":
if audit == "Error":
await throw.finish(MessageSegment.reply(message_id)+"文字审核未通过!原因:调用审核API失败,请检查违禁词词表是否存在,或token是否正确设置!")
await throw.finish(
MessageSegment.reply(message_id)
+ "文字审核未通过!原因:调用审核API失败,请检查违禁词词表是否存在,或token是否正确设置!"
)
elif audit["conclusion"] == "不合规":
await throw.finish(MessageSegment.reply(message_id)+"文字审核未通过!原因:" + audit["data"][0]["msg"])
await throw.finish(
MessageSegment.reply(message_id)
+ "文字审核未通过!原因:"
+ audit["data"][0]["msg"]
)

try:
group_info = await bot.get_group_info(group_id=event.group_id)
Expand Down Expand Up @@ -258,11 +266,15 @@ async def _(
await throw.send("你的瓶子以奇怪的方式消失掉了!")


likes = set(["+","点赞","赞"])


@get.handle()
async def _(
bot: Bot,
matcher: Matcher,
event: GroupMessageEvent,
state: T_State,
session: AsyncSession = Depends(get_session),
):
await verify(matcher=matcher, event=event)
Expand All @@ -289,13 +301,15 @@ async def _(
)
ba.add("cooldown", event.user_id)
bottle_content = deserialize_message(bottle.content).extract_plain_text().strip()
bottle_message = f"【漂流瓶No.{bottle.id}\n来自【{group_name}】的“{user_name}”!\n"\
+ f"时间:{bottle.time.strftime('%Y-%m-%d')}\n"\
+ f"内容:\n"\
+ deserialize_message(bottle.content)\
bottle_message = (
f"【漂流瓶No.{bottle.id}】【+{bottle.like}\n来自【{group_name}】的“{user_name}”!\n"
+ f"时间:{bottle.time.strftime('%Y-%m-%d')}\n"
+ f"内容:\n"
+ deserialize_message(bottle.content)
+ (f"\n★前 {len(comments)} 条评论★\n{comment_str}" if comment_str else "")

if bottle_content.count("\n") >=7 or len(bottle_content)>200:
)

if bottle_content.count("\n") >= 7 or len(bottle_content) > 200:
await bot.send_group_forward_msg(
group_id=event.group_id,
messages=[
Expand All @@ -306,13 +320,34 @@ async def _(
)
else:
message_id = event.message_id
await get.send(
MessageSegment.reply(message_id)
+ bottle_message
)
await get.send(MessageSegment.reply(message_id) + bottle_message)
state["bottle_id"] = bottle.id
await session.commit()


@get.got("prompt")
async def _(
matcher: Matcher,
event: GroupMessageEvent,
like: str = ArgStr("prompt"),
bottle_id: int = Arg("bottle_id"),
session: AsyncSession = Depends(get_session),
):
if like in likes:
bottle = await get_bottle(index=bottle_id, matcher=matcher, session=session)
result = await bottle_manager.like_bottle(
bottle=bottle, user_id=event.user_id, session=session
)
if result == 0:
await get.send("你已经点过赞了。")
elif result == 1:
ba.add("cooldown", event.user_id)
await get.send(f"点赞成功~该漂流瓶已有 {bottle.like} 次点赞!")
await session.commit()
else:
matcher.block = False


@report.handle()
async def _(
bot: Bot,
Expand Down Expand Up @@ -373,9 +408,9 @@ async def _(
command = args.extract_plain_text().strip().split()
message_id = event.message_id
if not command:
await comment.finish(MessageSegment.reply(message_id)+f"请在指令后接 漂流瓶id 评论")
await comment.finish(MessageSegment.reply(message_id) + f"请在指令后接 漂流瓶id 评论")
if len(command) == 1:
await comment.finish(MessageSegment.reply(message_id)+"想评论什么呀,在后边写上吧!")
await comment.finish(MessageSegment.reply(message_id) + "想评论什么呀,在后边写上吧!")
bottle = await get_bottle(index=command[0], matcher=matcher, session=session)
user_info = await bot.get_group_member_info(
group_id=event.group_id, user_id=event.user_id
Expand All @@ -387,9 +422,16 @@ async def _(
audit = await text_audit(text=command[1])
if not audit == "pass":
if audit == "Error":
await comment.finish(MessageSegment.reply(message_id)+"文字审核未通过!原因:调用审核API失败,请检查违禁词词表格式是否正确,或token是否正确设置!")
await comment.finish(
MessageSegment.reply(message_id)
+ "文字审核未通过!原因:调用审核API失败,请检查违禁词词表格式是否正确,或token是否正确设置!"
)
elif audit["conclusion"] == "不合规":
await comment.finish(MessageSegment.reply(message_id)+"文字审核未通过!原因:" + audit["data"][0]["msg"])
await comment.finish(
MessageSegment.reply(message_id)
+ "文字审核未通过!原因:"
+ audit["data"][0]["msg"]
)

# 审核通过
bottle_manager.comment(
Expand Down Expand Up @@ -442,7 +484,7 @@ async def _(
if not comments and event.user_id != bottle.user_id:
await check_bottle.finish(
MessageSegment.reply(message_id)
+ f"这个编号的漂流瓶还没有评论或你不是此漂流瓶的主人,不能给你看里面的东西\n【该#{index} 漂流瓶来自{group_name}】的 {user_name},被捡到{bottle.picked}次,于{bottle.time.strftime('%Y-%m-%d %H:%M:%S')}扔出】"
+ f"这个漂流瓶还没有评论,或你不是此漂流瓶的主人,因此不能给你看里面的东西\n【该#{index} 漂流瓶(+{bottle.like})来自{group_name}】的 {user_name},被捡到{bottle.picked}次,于{bottle.time.strftime('%Y-%m-%d %H:%M:%S')}扔出】"
)
comment_str = "\n".join(
[f"{comment.user_name}{comment.content}" for comment in comments]
Expand Down Expand Up @@ -470,9 +512,12 @@ async def _(
if str(event.user_id) in bot.config.superusers or bottle.user_id == event.user_id:
content_preview = get_content_preview(bottle)
matcher.set_arg("index", int(index))
await remove.send(MessageSegment.reply(message_id)+f"真的要删除{index}号漂流瓶(Y/N)?漂流瓶将会永久失去。(真的很久!)\n漂流瓶内容:{content_preview}")
await remove.send(
MessageSegment.reply(message_id)
+ f"真的要删除{index}号漂流瓶(Y/N)?【+{bottle.like}】漂流瓶将会永久失去。(真的很久!)\n漂流瓶内容:{content_preview}"
)
else:
await remove.finish(MessageSegment.reply(message_id)+"删除失败!你没有相关的权限!")
await remove.finish(MessageSegment.reply(message_id) + "你没有相关权限。")


@remove.got("prompt")
Expand All @@ -487,9 +532,9 @@ async def _(
# 行数越少越好.jpg
(await bottle_manager.get_bottle(index=index, session=session)).is_del = True
await session.commit()
await remove.send(MessageSegment.reply(message_id)+f"成功删除 {index} 号漂流瓶!")
await remove.send(MessageSegment.reply(message_id) + f"成功删除 {index} 号漂流瓶!")
else:
await remove.finish(MessageSegment.reply(message_id)+"取消删除操作。")
await remove.finish(MessageSegment.reply(message_id) + "取消删除操作。")


###### SUPERUSER命令 ######
Expand Down Expand Up @@ -530,7 +575,7 @@ async def _(
bottle = await get_bottle(
index=index, matcher=matcher, session=session, include_del=True
)
mes = f"漂流瓶编号:{index}\n用户QQ{bottle.user_id}\n来源群组:{bottle.group_id}\n发送时间:{bottle.time.strftime('%Y-%m-%d %H:%M:%S')}\n"
mes = f"漂流瓶编号:{index}\n【+{bottle.like}】用户QQ{bottle.user_id}\n来源群组:{bottle.group_id}\n发送时间:{bottle.time.strftime('%Y-%m-%d %H:%M:%S')}\n"
await listqq.send(mes + deserialize_message(bottle.content))

comments = await bottle_manager.get_comment(
Expand Down
2 changes: 1 addition & 1 deletion nonebot_plugin_bottle/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,4 @@ class Config(BaseModel, extra=Extra.ignore):
local_storage = config.nonebot_plugin_bottle_local_storage
maxlen = config.nonebot_plugin_bottle_max_length
maxrt = config.nonebot_plugin_bottle_max_return
rtrate = config.nonebot_plugin_bottle_rt_rate
rtrate = config.nonebot_plugin_bottle_rt_rate
27 changes: 26 additions & 1 deletion nonebot_plugin_bottle/data_source.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
from nonebot.adapters.onebot.v11 import Message, MessageSegment
from nonebot_plugin_datastore.db import get_engine, post_db_init, create_session

from .model import Bottle, Report, Comment
from .model import Like, Bottle, Report, Comment
from .config import api_key, secret_key, local_storage

data_dir = Path("data/bottle")
Expand Down Expand Up @@ -294,6 +294,31 @@ def comment(
)
session.add(new_comment)

async def like_bottle(
self,
bottle: Bottle,
user_id: int,
session: AsyncSession,
) -> int:
"""点赞漂流瓶
Args:
bottle (Bottle): 瓶子
user_id (int): 用户id
session (AsyncSession): 会话
返回
0 点赞失败
1 点赞成功
"""
if await session.scalar(
select(Like).where(Like.user_id == user_id, Like.bottle_id == bottle.id)
):
return 0
bottle.like += 1
session.add(Like(user_id=user_id, bottle_id=bottle.id))
return 1

async def get_comment(
self,
bottle: Bottle,
Expand Down
46 changes: 46 additions & 0 deletions nonebot_plugin_bottle/migrations/01a750736ea0_add_like.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
"""add_like
Revision ID: 01a750736ea0
Revises: 449e066410fd
Create Date: 2023-10-21 23:59:18.971313
"""
import sqlalchemy as sa
from alembic import op

# revision identifiers, used by Alembic.
revision = "01a750736ea0"
down_revision = "449e066410fd"
branch_labels = None
depends_on = None


def upgrade() -> None:
# ### commands auto generated by Alembic - please adjust! ###
op.create_table(
"nonebot_plugin_bottle_like",
sa.Column("id", sa.Integer(), nullable=False),
sa.Column("user_id", sa.BigInteger(), nullable=False),
sa.Column("bottle_id", sa.Integer(), nullable=False),
sa.PrimaryKeyConstraint("id"),
sa.UniqueConstraint("user_id", "bottle_id"),
)
with op.batch_alter_table("nonebot_plugin_bottle_bottle", schema=None) as batch_op:
batch_op.add_column(
sa.Column(
"like",
sa.Integer(),
nullable=False,
server_default=sa.schema.DefaultClause("0")
),

)
# ### end Alembic commands ###


def downgrade() -> None:
# ### commands auto generated by Alembic - please adjust! ###
op.drop_table("nonebot_plugin_bottle_like")
with op.batch_alter_table("nonebot_plugin_bottle_bottle", schema=None) as batch_op:
batch_op.drop_column("like")
# ### end Alembic commands ###
10 changes: 9 additions & 1 deletion nonebot_plugin_bottle/model.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,14 @@ class Comment(Model):
bottle_id: Mapped[int]


class Like(Model):
__table_args__ = (UniqueConstraint("user_id", "bottle_id"),)

id: Mapped[int] = mapped_column(primary_key=True)
user_id: Mapped[int] = mapped_column(BigInteger)
bottle_id: Mapped[int]


class Report(Model):
__table_args__ = (
UniqueConstraint(
Expand All @@ -29,7 +37,6 @@ class Report(Model):

id: Mapped[int] = mapped_column(primary_key=True)
user_id: Mapped[int] = mapped_column(BigInteger)

bottle_id: Mapped[int]


Expand All @@ -41,6 +48,7 @@ class Bottle(Model):
group_name: Mapped[str]
content: Mapped[List[Dict[str, Any]]] = mapped_column(JSON)
report: Mapped[int] = mapped_column(default=0)
like: Mapped[int] = mapped_column(default=0)
picked: Mapped[int] = mapped_column(default=0)
is_del: Mapped[bool] = mapped_column(default=False)
time: Mapped[datetime] = mapped_column(default=datetime.now())
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[tool.poetry]
name = "nonebot_plugin_bottle"
version = "1.0.2.3"
version = "2.0.0.0"
description = "Bottle post plugin in Nonebot"
authors = ["Todysheep <[email protected]>"]
license = "GNU GPLv3"
Expand Down

0 comments on commit 1ed0180

Please sign in to comment.