Skip to content

Commit

Permalink
Merge pull request #54 from Ailitonia/dev_perm_coold
Browse files Browse the repository at this point in the history
Add: Plugins Manager
  • Loading branch information
Ailitonia authored Sep 12, 2021
2 parents 8194767 + e598dea commit 6063263
Show file tree
Hide file tree
Showing 56 changed files with 929 additions and 471 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,14 @@
## 功能 & 特点

- 基于异步 SQLAlchemy / MySQL 的数据存储
- 插件管理系统
- 权限控制及管理系统
- 针对不同群组可选启用通知权限、命令权限、权限等级控制
- 针对不同好友可选启用 Bot 功能
- 针对不同群组、好友独立配置插件权限节点
- 支持多协议端连接, 各协议端权限及订阅配置相互独立
- 命令冷却系统
- 速率控制系统
- HTTP 代理功能
- 自动处理加好友和被邀请进群
- 插件帮助功能 (支持群聊 / 私聊)
Expand Down
3 changes: 2 additions & 1 deletion omega_miya/database/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
from .model import (
DBUser, DBFriend, DBBot, DBBotGroup, DBGroup, DBSkill, DBSubscription, DBDynamic,
DBPixivUserArtwork, DBPixivillust, DBPixivision, DBEmail, DBEmailBox, DBHistory,
DBAuth, DBCoolDownEvent, DBStatus, DBStatistic)
DBAuth, DBCoolDownEvent, DBStatus, DBStatistic, DBPlugin)


__all__ = [
Expand All @@ -29,5 +29,6 @@
'DBCoolDownEvent',
'DBStatus',
'DBStatistic',
'DBPlugin',
'Result'
]
2 changes: 1 addition & 1 deletion omega_miya/database/database.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ async def database_init():
# where synchronous IO calls will be transparently translated for
# await.
await conn.run_sync(Base.metadata.create_all)
nonebot.logger.opt(colors=True).info(f'<lg>数据库初始化已完成.</lg>')
nonebot.logger.opt(colors=True).success(f'<lg>数据库初始化已完成.</lg>')
except Exception as e_:
import sys
nonebot.logger.opt(colors=True).critical(f'<r>数据库初始化失败</r>, error: {repr(e_)}')
Expand Down
9 changes: 6 additions & 3 deletions omega_miya/database/model/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,13 @@
from .pixiv_user_artwork import DBPixivUserArtwork
from .pixivillust import DBPixivillust
from .pixivision import DBPixivision
from .plugins import DBPlugin
from .skill import DBSkill
from .statistic import DBStatistic
from .status import DBStatus
from .subscription import DBSubscription
from .user import DBUser
from .status import DBStatus


__all__ = [
'DBAuth',
Expand All @@ -30,9 +32,10 @@
'DBPixivUserArtwork',
'DBPixivillust',
'DBPixivision',
'DBPlugin',
'DBSkill',
'DBStatistic',
'DBStatus',
'DBSubscription',
'DBUser',
'DBStatus'
'DBUser'
]
51 changes: 30 additions & 21 deletions omega_miya/database/model/cooldown.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,14 @@


class DBCoolDownEvent(object):
global_group_type: str = 'global_group'
global_user_type: str = 'global_user'
group_type: str = 'group'
user_type: str = 'user'

@classmethod
async def add_global_cool_down_event(cls, stop_at: datetime, description: str = None) -> Result.IntResult:
async def add_global_group_cool_down_event(
cls, group_id: int, stop_at: datetime, description: str = None) -> Result.IntResult:
"""
:return:
result = 0: Success
Expand All @@ -21,7 +27,8 @@ async def add_global_cool_down_event(cls, stop_at: datetime, description: str =
try:
session_result = await session.execute(
select(CoolDownEvent).
where(CoolDownEvent.event_type == 'global')
where(CoolDownEvent.event_type == cls.global_group_type).
where(CoolDownEvent.group_id == group_id)
)
exist_event = session_result.scalar_one()
exist_event.stop_at = stop_at
Expand All @@ -30,7 +37,8 @@ async def add_global_cool_down_event(cls, stop_at: datetime, description: str =
result = Result.IntResult(error=False, info='Success upgraded', result=0)
except NoResultFound:
new_event = CoolDownEvent(
event_type='global', stop_at=stop_at, description=description, created_at=datetime.now())
event_type=cls.global_group_type, group_id=group_id, stop_at=stop_at,
description=description, created_at=datetime.now())
session.add(new_event)
result = Result.IntResult(error=False, info='Success added', result=0)
await session.commit()
Expand All @@ -43,7 +51,7 @@ async def add_global_cool_down_event(cls, stop_at: datetime, description: str =
return result

@classmethod
async def check_global_cool_down_event(cls) -> Result.IntResult:
async def check_global_group_cool_down_event(cls, group_id: int) -> Result.IntResult:
"""
:return:
result = 2: Success with CoolDown Event expired
Expand All @@ -57,7 +65,8 @@ async def check_global_cool_down_event(cls) -> Result.IntResult:
try:
session_result = await session.execute(
select(CoolDownEvent).
where(CoolDownEvent.event_type == 'global')
where(CoolDownEvent.event_type == cls.global_group_type).
where(CoolDownEvent.group_id == group_id)
)
event = session_result.scalar_one()
stop_at = event.stop_at
Expand All @@ -74,8 +83,8 @@ async def check_global_cool_down_event(cls) -> Result.IntResult:
return result

@classmethod
async def add_plugin_cool_down_event(
cls, plugin: str, stop_at: datetime, description: str = None) -> Result.IntResult:
async def add_global_user_cool_down_event(
cls, user_id: int, stop_at: datetime, description: str = None) -> Result.IntResult:
"""
:return:
result = 0: Success
Expand All @@ -88,8 +97,8 @@ async def add_plugin_cool_down_event(
try:
session_result = await session.execute(
select(CoolDownEvent).
where(CoolDownEvent.event_type == 'plugin').
where(CoolDownEvent.plugin == plugin)
where(CoolDownEvent.event_type == cls.global_user_type).
where(CoolDownEvent.user_id == user_id)
)
exist_event = session_result.scalar_one()
exist_event.stop_at = stop_at
Expand All @@ -98,8 +107,8 @@ async def add_plugin_cool_down_event(
result = Result.IntResult(error=False, info='Success upgraded', result=0)
except NoResultFound:
new_event = CoolDownEvent(
event_type='plugin', plugin=plugin, stop_at=stop_at, description=description,
created_at=datetime.now())
event_type=cls.global_user_type, user_id=user_id, stop_at=stop_at,
description=description, created_at=datetime.now())
session.add(new_event)
result = Result.IntResult(error=False, info='Success added', result=0)
await session.commit()
Expand All @@ -112,7 +121,7 @@ async def add_plugin_cool_down_event(
return result

@classmethod
async def check_plugin_cool_down_event(cls, plugin: str) -> Result.IntResult:
async def check_global_user_cool_down_event(cls, user_id: int) -> Result.IntResult:
"""
:return:
result = 2: Success with CoolDown Event expired
Expand All @@ -126,8 +135,8 @@ async def check_plugin_cool_down_event(cls, plugin: str) -> Result.IntResult:
try:
session_result = await session.execute(
select(CoolDownEvent).
where(CoolDownEvent.event_type == 'plugin').
where(CoolDownEvent.plugin == plugin)
where(CoolDownEvent.event_type == cls.global_user_type).
where(CoolDownEvent.user_id == user_id)
)
event = session_result.scalar_one()
stop_at = event.stop_at
Expand Down Expand Up @@ -158,7 +167,7 @@ async def add_group_cool_down_event(
try:
session_result = await session.execute(
select(CoolDownEvent).
where(CoolDownEvent.event_type == 'group').
where(CoolDownEvent.event_type == cls.group_type).
where(CoolDownEvent.plugin == plugin).
where(CoolDownEvent.group_id == group_id)
)
Expand All @@ -169,7 +178,7 @@ async def add_group_cool_down_event(
result = Result.IntResult(error=False, info='Success upgraded', result=0)
except NoResultFound:
new_event = CoolDownEvent(
event_type='group', plugin=plugin, group_id=group_id, stop_at=stop_at,
event_type=cls.group_type, plugin=plugin, group_id=group_id, stop_at=stop_at,
description=description, created_at=datetime.now())
session.add(new_event)
result = Result.IntResult(error=False, info='Success added', result=0)
Expand Down Expand Up @@ -197,7 +206,7 @@ async def check_group_cool_down_event(cls, plugin: str, group_id: int) -> Result
try:
session_result = await session.execute(
select(CoolDownEvent).
where(CoolDownEvent.event_type == 'group').
where(CoolDownEvent.event_type == cls.group_type).
where(CoolDownEvent.plugin == plugin).
where(CoolDownEvent.group_id == group_id)
)
Expand Down Expand Up @@ -230,7 +239,7 @@ async def add_user_cool_down_event(
try:
session_result = await session.execute(
select(CoolDownEvent).
where(CoolDownEvent.event_type == 'user').
where(CoolDownEvent.event_type == cls.user_type).
where(CoolDownEvent.plugin == plugin).
where(CoolDownEvent.user_id == user_id)
)
Expand All @@ -241,8 +250,8 @@ async def add_user_cool_down_event(
result = Result.IntResult(error=False, info='Success upgraded', result=0)
except NoResultFound:
new_event = CoolDownEvent(
event_type='user', plugin=plugin, user_id=user_id, stop_at=stop_at, description=description,
created_at=datetime.now())
event_type=cls.user_type, plugin=plugin, user_id=user_id, stop_at=stop_at,
description=description, created_at=datetime.now())
session.add(new_event)
result = Result.IntResult(error=False, info='Success added', result=0)
await session.commit()
Expand All @@ -269,7 +278,7 @@ async def check_user_cool_down_event(cls, plugin: str, user_id: int) -> Result.I
try:
session_result = await session.execute(
select(CoolDownEvent).
where(CoolDownEvent.event_type == 'user').
where(CoolDownEvent.event_type == cls.user_type).
where(CoolDownEvent.plugin == plugin).
where(CoolDownEvent.user_id == user_id)
)
Expand Down
109 changes: 109 additions & 0 deletions omega_miya/database/model/plugins.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
"""
@Author : Ailitonia
@Date : 2021/09/12 12:19
@FileName : plugins.py
@Project : nonebot2_miya
@Description : 数据库 plugins 表 module
@GitHub : https://github.com/Ailitonia
@Software : PyCharm
"""

from typing import Optional
from omega_miya.database.database import BaseDB
from omega_miya.database.class_result import Result
from omega_miya.database.tables import OmegaPlugins
from datetime import datetime
from sqlalchemy.future import select
from sqlalchemy.orm.exc import NoResultFound, MultipleResultsFound


class DBPlugin(object):
def __init__(self, plugin_name: str):
self.plugin_name = plugin_name

async def update(
self,
enabled: Optional[int] = None,
*,
matchers: Optional[int] = None,
info: Optional[str] = None
) -> Result.IntResult:
async_session = BaseDB().get_async_session()
async with async_session() as session:
try:
async with session.begin():
try:
# 已存在则更新
session_result = await session.execute(
select(OmegaPlugins).where(OmegaPlugins.plugin_name == self.plugin_name)
)
exist_plugin = session_result.scalar_one()
if enabled is not None:
exist_plugin.enabled = enabled
if matchers is not None:
exist_plugin.matchers = matchers
if info is not None:
exist_plugin.info = info
exist_plugin.updated_at = datetime.now()
result = Result.IntResult(error=False, info='Success upgraded', result=0)
except NoResultFound:
# 不存在则添加信息
if enabled is None:
enabled = 1
new_plugin = OmegaPlugins(
plugin_name=self.plugin_name,
enabled=enabled,
matchers=matchers,
info=info,
created_at=datetime.now())
session.add(new_plugin)
result = Result.IntResult(error=False, info='Success added', result=0)
await session.commit()
except MultipleResultsFound:
await session.rollback()
result = Result.IntResult(error=True, info=f'{self.plugin_name} MultipleResultsFound', result=-1)
except Exception as e:
await session.rollback()
result = Result.IntResult(error=True, info=f'{self.plugin_name} update failed, {repr(e)}', result=-1)
return result

async def get_enabled_status(self) -> Result.IntResult:
async_session = BaseDB().get_async_session()
async with async_session() as session:
async with session.begin():
try:
session_result = await session.execute(
select(OmegaPlugins.enabled).where(OmegaPlugins.plugin_name == self.plugin_name)
)
enabled = session_result.scalar_one()
result = Result.IntResult(error=False, info='Success', result=enabled)
except NoResultFound:
result = Result.IntResult(error=True, info='NoResultFound', result=-1)
except MultipleResultsFound:
result = Result.IntResult(error=True, info='MultipleResultsFound', result=-1)
except Exception as e:
result = Result.IntResult(error=True, info=repr(e), result=-1)
return result

@classmethod
async def list_plugins(cls, *, enabled: Optional[int] = None) -> Result.TextListResult:
async_session = BaseDB().get_async_session()
async with async_session() as session:
async with session.begin():
try:
if enabled is None:
session_result = await session.execute(select(OmegaPlugins.plugin_name))
else:
session_result = await session.execute(
select(OmegaPlugins.plugin_name).where(OmegaPlugins.enabled == enabled)
)
res = [x for x in session_result.scalars().all()]
result = Result.TextListResult(error=False, info='Success', result=res)
except Exception as e:
result = Result.TextListResult(error=True, info=repr(e), result=[])
return result


__all__ = [
'DBPlugin'
]
37 changes: 36 additions & 1 deletion omega_miya/database/tables.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,41 @@ def __repr__(self):
f"created_at='{self.created_at}', updated_at='{self.updated_at}')>"


# 插件表, 存放插件信息
class OmegaPlugins(Base):
__tablename__ = f'{TABLE_PREFIX}plugins'
__table_args__ = {'mysql_engine': 'InnoDB', 'mysql_charset': 'utf8mb4'}

# 表结构
id = Column(Integer, Sequence('omega_plugins_id_seq'), primary_key=True, nullable=False, index=True, unique=True)
plugin_name = Column(String(64), nullable=False, index=True, unique=True, comment='插件名称')
enabled = Column(Integer, nullable=False, index=True, comment='启用状态, 1: 启用, 0: 禁用, -1: 失效或未安装')
matchers = Column(Integer, nullable=True, comment='插件的matcher数')
info = Column(String(256), nullable=True, comment='附加说明')
created_at = Column(DateTime, nullable=True)
updated_at = Column(DateTime, nullable=True)

def __init__(self,
plugin_name: str,
enabled: int,
*,
matchers: int = 0,
info: Optional[str] = None,
created_at: Optional[datetime] = None,
updated_at: Optional[datetime] = None):
self.plugin_name = plugin_name
self.enabled = enabled
self.matchers = matchers
self.info = info
self.created_at = created_at
self.updated_at = updated_at

def __repr__(self):
return f"<OmegaPlugins(plugin_name='{self.plugin_name}', enabled='{self.enabled}', " \
f"matchers='{self.matchers}', info='{self.info}', " \
f"created_at='{self.created_at}', updated_at='{self.updated_at}')>"


# 统计信息表, 存放插件运行统计
class OmegaStatistics(Base):
__tablename__ = f'{TABLE_PREFIX}statistics'
Expand Down Expand Up @@ -748,7 +783,7 @@ class History(Base):
__table_args__ = {'mysql_engine': 'InnoDB', 'mysql_charset': 'utf8mb4'}

# 表结构
id = Column(Integer, Sequence('history_id_seq'), primary_key=True, nullable=False, index=True, unique=True)
id = Column(BigInteger, Sequence('history_id_seq'), primary_key=True, nullable=False, index=True, unique=True)
time = Column(BigInteger, nullable=False, comment='事件发生的时间戳')
self_id = Column(BigInteger, nullable=False, index=True, comment='收到事件的机器人QQ号')
post_type = Column(String(64), nullable=False, index=True, comment='事件类型')
Expand Down
Loading

0 comments on commit 6063263

Please sign in to comment.