抽象数据库模型和方法, 便于插件继承建表调用

This commit is contained in:
Wuyi无疑 2023-08-05 22:15:56 +08:00
parent 0cc9552c4a
commit 32dbd988be
7 changed files with 947 additions and 530 deletions

View File

@ -3,6 +3,7 @@ from gsuid_core.bot import Bot
from gsuid_core.gss import gss from gsuid_core.gss import gss
from gsuid_core.models import Event from gsuid_core.models import Event
from gsuid_core.logger import logger from gsuid_core.logger import logger
from gsuid_core.segment import Message
from .draw_user_card import get_user_card from .draw_user_card import get_user_card
@ -23,5 +24,10 @@ async def send_direct_msg(bot: Bot, ev: Event):
logger.info('开始执行[给我发消息]') logger.info('开始执行[给我发消息]')
for bot_id in gss.active_bot: for bot_id in gss.active_bot:
await gss.active_bot[bot_id].target_send( await gss.active_bot[bot_id].target_send(
'这是一条主动消息', 'direct', ev.user_id, ev.bot_id, ev.bot_self_id, '' [Message('text', '这是一条主动消息'), Message('group', ev.group_id)],
'direct',
ev.user_id,
ev.bot_id,
ev.bot_self_id,
'',
) )

View File

@ -1,16 +1,18 @@
import re
import asyncio import asyncio
from typing import Dict from typing import Dict, Type, Tuple, Union, Optional, overload
from sqlalchemy import event from sqlalchemy import event
from gsuid_core.data_store import get_res_path from gsuid_core.bot import Bot
from gsuid_core.models import Event
from gsuid_core.utils.database.dal import SQLA from gsuid_core.utils.database.dal import SQLA
from gsuid_core.utils.database.base_models import Bind, engine
is_wal = False is_wal = False
active_sqla: Dict[str, SQLA] = {} active_sqla: Dict[str, SQLA] = {}
active_sr_sqla: Dict[str, SQLA] = {} active_sr_sqla: Dict[str, SQLA] = {}
db_url = str(get_res_path().parent / 'GsData.db')
class DBSqla: class DBSqla:
@ -25,15 +27,15 @@ class DBSqla:
def _get_sqla(self, bot_id, is_sr: bool = False) -> SQLA: def _get_sqla(self, bot_id, is_sr: bool = False) -> SQLA:
sqla_list = active_sr_sqla if is_sr else active_sqla sqla_list = active_sr_sqla if is_sr else active_sqla
if bot_id not in sqla_list: if bot_id not in sqla_list:
sqla = SQLA(db_url, bot_id, is_sr) sqla = SQLA(bot_id, is_sr)
sqla_list[bot_id] = sqla sqla_list[bot_id] = sqla
sqla.create_all() sqla.create_all()
@event.listens_for(sqla.engine.sync_engine, 'connect') @event.listens_for(engine.sync_engine, "connect")
def engine_connect(conn, branch): def set_sqlite_pragma(dbapi_connection, connection_record):
if is_wal: if is_wal:
cursor = conn.cursor() cursor = dbapi_connection.cursor()
cursor.execute('PRAGMA journal_mode=WAL') cursor.execute("PRAGMA journal_mode=WAL")
cursor.close() cursor.close()
return sqla_list[bot_id] return sqla_list[bot_id]
@ -43,3 +45,44 @@ class DBSqla:
def get_sr_sqla(self, bot_id): def get_sr_sqla(self, bot_id):
return self._get_sqla(bot_id, True) return self._get_sqla(bot_id, True)
@overload
async def get_uid(
bot: Bot,
ev: Event,
bind_model: Type[Bind],
game_name: Optional[str] = None,
) -> Optional[str]:
...
@overload
async def get_uid(
bot: Bot,
ev: Event,
bind_model: Type[Bind],
game_name: Optional[str] = None,
get_user_id: bool = True,
) -> Tuple[Optional[str], str]:
...
async def get_uid(
bot: Bot,
ev: Event,
bind_model: Type[Bind],
game_name: Optional[str] = None,
get_user_id: bool = False,
) -> Union[Optional[str], Tuple[Optional[str], str]]:
uid_data = re.findall(r'\d+', ev.text)
user_id = ev.at if ev.at else ev.user_id
if uid_data:
uid: Optional[str] = uid_data[0]
if uid:
ev.text = ev.text.replace(uid, '')
else:
uid = await bind_model.get_uid_by_game(user_id, ev.bot_id, game_name)
if get_user_id:
return uid, user_id
return uid

View File

@ -0,0 +1,661 @@
from functools import wraps
from typing_extensions import ParamSpec, Concatenate
from typing import (
Any,
Dict,
List,
Type,
TypeVar,
Callable,
Optional,
Awaitable,
)
from sqlalchemy.future import select
from sqlalchemy.orm import sessionmaker
from sqlmodel import Field, SQLModel, col
from sqlalchemy.sql.expression import func
from sqlalchemy import and_, delete, update
from sqlalchemy.ext.asyncio import AsyncSession, create_async_engine
from gsuid_core.data_store import get_res_path
T_BaseModel = TypeVar('T_BaseModel', bound='BaseModel')
T_BaseIDModel = TypeVar('T_BaseIDModel', bound='BaseIDModel')
T_User = TypeVar('T_User', bound='User')
P = ParamSpec("P")
R = TypeVar("R")
db_url = str(get_res_path().parent / 'GsData.db')
url = f'sqlite+aiosqlite:///{db_url}'
engine = create_async_engine(url, pool_recycle=1500)
async_maker = sessionmaker(engine, expire_on_commit=False, class_=AsyncSession)
def with_session(
func: Callable[Concatenate[Any, AsyncSession, P], Awaitable[R]]
) -> Callable[Concatenate[Any, P], Awaitable[R]]:
@wraps(func)
async def wrapper(self, *args: P.args, **kwargs: P.kwargs):
async with async_maker() as session:
return await func(self, session, *args, **kwargs)
return wrapper
class BaseIDModel(SQLModel):
id: Optional[int] = Field(default=None, primary_key=True, title='序号')
@classmethod
def get_gameid_name(cls, game_name: Optional[str] = None):
if game_name:
return f'{game_name}_uid'
else:
return 'uid'
@classmethod
@with_session
async def full_insert_data(
cls, session: AsyncSession, model: Type["BaseIDModel"], **data
) -> int:
session.add(model(**data))
await session.commit()
return 0
@classmethod
@with_session
async def base_select_data(
cls, session: AsyncSession, model: Type[T_BaseIDModel], **data
) -> Optional[T_BaseIDModel]:
conditions = []
for key, value in data.items():
conditions.append(getattr(model, key) == value)
where_clause = and_(*conditions)
sql = select(model).where(where_clause)
result = await session.execute(sql)
data = result.scalars().all()
return data[0] if data else None
@classmethod
async def data_exist(cls, model: Type[T_BaseIDModel], **data) -> bool:
return bool(await cls.base_select_data(model, **data))
class BaseBotIDModel(BaseIDModel):
bot_id: str = Field(title='平台')
@classmethod
@with_session
async def update_data_by_uid(
cls,
session: AsyncSession,
uid: str,
bot_id: str,
game_name: Optional[str] = None,
**data,
) -> int:
sql = update(cls).where(
getattr(cls, cls.get_gameid_name(game_name)) == uid,
cls.bot_id == bot_id,
)
if data is not None:
query = sql.values(**data)
query.execution_options(synchronize_session='fetch')
await session.execute(query)
return 0
return -1
class BaseModel(BaseBotIDModel):
user_id: str = Field(title='账号')
################################
# 基本的增删改查 #
################################
@classmethod
@with_session
async def select_data(
cls: Type[T_BaseModel],
session: AsyncSession,
user_id: str,
bot_id: Optional[str] = None,
) -> Optional[T_BaseModel]:
if bot_id is None:
sql = select(cls).where(cls.user_id == user_id)
else:
sql = select(cls).where(
cls.user_id == user_id, cls.bot_id == bot_id
)
result = await session.execute(sql)
data = result.scalars().all()
return data[0] if data else None
@classmethod
@with_session
async def insert_data(
cls, session: AsyncSession, user_id: str, bot_id: str, **data
) -> int:
session.add(cls(user_id=user_id, bot_id=bot_id, **data))
await session.commit()
return 0
@classmethod
@with_session
async def delete_data(
cls, session: AsyncSession, user_id: str, bot_id: str, **data
) -> int:
await session.delete(cls(user_id=user_id, bot_id=bot_id, **data))
await session.commit()
return 0
@classmethod
@with_session
async def update_data(
cls, session: AsyncSession, user_id: str, bot_id: str, **data
) -> int:
sql = update(cls).where(cls.user_id == user_id, cls.bot_id == bot_id)
if data is not None:
query = sql.values(**data)
query.execution_options(synchronize_session='fetch')
await session.execute(query)
await session.commit()
return 0
return -1
class Bind(BaseModel):
group_id: Optional[str] = Field(title='群号')
################################
# 额外的扩展方法 #
################################
@classmethod
async def get_uid_list_by_game(
cls,
user_id: str,
bot_id: str,
game_name: Optional[str] = None,
) -> Optional[List[str]]:
result = await cls.select_data(user_id, bot_id)
if result is None:
return None
uid = getattr(result, cls.get_gameid_name(game_name))
if uid is None:
return None
else:
uid_list = uid.split('_')
if uid_list:
return uid_list
else:
return None
@classmethod
async def get_uid_by_game(
cls,
user_id: str,
bot_id: str,
game_name: Optional[str] = None,
) -> Optional[str]:
result = await cls.get_uid_list_by_game(user_id, bot_id, game_name)
if result is None or not result:
return None
return result[0]
@classmethod
async def bind_exists(
cls,
user_id: str,
bot_id: str,
) -> bool:
'''
查询当前user_id是否已有绑定数据
'''
return bool(await cls.select_data(user_id, bot_id))
@classmethod
async def insert_uid(
cls,
user_id: str,
bot_id: str,
uid: str,
group_id: Optional[str] = None,
lenth_limit: Optional[int] = None,
is_digit: Optional[bool] = True,
game_name: Optional[str] = None,
) -> int:
'''
为数据库增加绑定UID
如果有传`lenth_limit`, 当uid位数不等于的时候, 返回`-1`
如果该UID已绑定, 则返回`-2`
`is_digit`默认为`True`, 进行合法性校验, 如果不是全数字, 返回`-3`
成功绑定, 则返回`0`
'''
result = await cls.get_uid_list_by_game(user_id, bot_id, game_name)
if lenth_limit:
if len(uid) != lenth_limit:
return -1
if is_digit is not None:
if not uid.isdigit():
return -3
if result is None and not await cls.bind_exists(user_id, bot_id):
return await cls.insert_data(
user_id,
bot_id,
**{cls.get_gameid_name(game_name): uid, 'group_id': group_id},
)
elif result is None:
new_uid = uid
elif uid in result:
return -2
else:
result.append(uid)
new_uid = '_'.join(result)
await cls.update_data(
user_id,
bot_id,
**{cls.get_gameid_name(game_name): new_uid},
)
return 0
@classmethod
async def delete_uid(
cls,
user_id: str,
bot_id: str,
uid: str,
game_name: Optional[str] = None,
):
result = await cls.get_uid_list_by_game(user_id, bot_id, game_name)
if result is None:
return -1
if uid not in result:
return -1
result.remove(uid)
new_uid = '_'.join(result)
await cls.update_data(
user_id,
bot_id,
**{cls.get_gameid_name(game_name): new_uid},
)
return 0
@classmethod
@with_session
async def get_all_uid_list_by_game(
cls,
session: AsyncSession,
bot_id: str,
game_name: Optional[str] = None,
) -> List[str]:
sql = select(cls).where(cls.bot_id == bot_id)
result = await session.execute(sql)
data: List["Bind"] = result.scalars().all()
uid_list: List[str] = []
for item in data:
uid = getattr(item, cls.get_gameid_name(game_name))
if uid is not None and uid:
game_uid_list: List[str] = uid.split("_")
uid_list.extend(game_uid_list)
return uid_list
@classmethod
async def switch_uid_by_game(
cls,
user_id: str,
bot_id: str,
uid: Optional[str] = None,
game_name: Optional[str] = None,
) -> int:
'''
切换用户UID, 成功返回0
可传确定的UID
如果不传UID,则自动切换序列下一个UID
如果不存在绑定记录,则返回-1
如果传了UID但是不存在绑定列表,则返回-2
如果绑定UID列表不足2个,返回-3
'''
uid_list = await cls.get_uid_list_by_game(user_id, bot_id, game_name)
if not uid_list:
return -1
elif len(uid_list) <= 1:
return -3
elif uid is None:
uid = uid_list[1]
old_uid = uid_list[0]
uid_list.remove(uid)
uid_list.remove(old_uid)
uid_list.insert(0, uid)
uid_list.append(old_uid)
elif uid not in uid_list:
return -2
else:
uid_list.remove(uid)
uid_list.insert(0, uid)
await cls.update_data(
user_id,
bot_id,
**{cls.get_gameid_name(game_name): uid_list},
)
return 0
@classmethod
async def get_bind_group_list(cls, user_id: str, bot_id: str) -> List[str]:
data: Optional["Bind"] = await cls.select_data(user_id, bot_id)
return data.group_id.split("_") if data and data.group_id else []
@classmethod
async def get_bind_group(cls, user_id: str, bot_id: str) -> Optional[str]:
data = await cls.get_bind_group_list(user_id, bot_id)
return data[0] if data else None
@classmethod
@with_session
async def get_group_all_uid(cls, session: AsyncSession, group_id: str):
result = await session.scalars(
select(cls).where(col(cls.group_id).contains(group_id))
)
data = result.all()
return data[0] if data else None
class User(BaseModel):
cookie: str = Field(default=None, title='Cookie')
stoken: Optional[str] = Field(default=None, title='Stoken')
status: Optional[str] = Field(default=None, title='状态')
push_switch: str = Field(default='off', title='全局推送开关')
sign_switch: str = Field(default='off', title='自动签到')
@classmethod
@with_session
async def select_data_by_uid(
cls: Type[T_User],
session: AsyncSession,
uid: str,
game_name: Optional[str] = None,
) -> Optional[T_User]:
result = await session.execute(
select(cls).where(
getattr(cls, cls.get_gameid_name(game_name)) == uid,
)
)
data = result.scalars().all()
return data[0] if data else None
@classmethod
@with_session
async def get_user_all_data_by_user_id(
cls: Type[T_User], session: AsyncSession, user_id: str
) -> Optional[List[T_User]]:
result = await session.execute(
select(cls).where(cls.user_id == user_id)
)
data = result.scalars().all()
return data if data else None
@classmethod
async def get_user_attr(
cls,
user_id: str,
bot_id: str,
attr: str,
) -> Optional[Any]:
result = await cls.select_data(user_id, bot_id)
return getattr(result, attr) if result else None
@classmethod
async def get_user_attr_by_uid(
cls,
uid: str,
attr: str,
game_name: Optional[str] = None,
) -> Optional[Any]:
result = await cls.select_data_by_uid(uid, game_name)
return getattr(result, attr) if result else None
@classmethod
async def get_user_attr_by_user_id(
cls,
user_id: str,
attr: str,
) -> Optional[Any]:
result = await cls.select_data(user_id)
return getattr(result, attr) if result else None
@classmethod
@with_session
async def mark_invalid(cls, session: AsyncSession, cookie: str, mark: str):
sql = update(cls).where(cls.cookie == cookie).values(status=mark)
await session.execute(sql)
await session.commit()
return True
@classmethod
async def get_user_cookie_by_uid(
cls, uid: str, game_name: Optional[str] = None
) -> Optional[str]:
return await cls.get_user_attr_by_uid(uid, 'cookie', game_name)
@classmethod
async def get_user_cookie_by_user_id(
cls, user_id: str, bot_id: str
) -> Optional[str]:
return await cls.get_user_attr(user_id, bot_id, 'cookie')
@classmethod
async def get_user_stoken_by_uid(
cls, uid: str, game_name: Optional[str] = None
) -> Optional[str]:
return await cls.get_user_attr_by_uid(uid, 'stoken', game_name)
@classmethod
async def get_user_stoken_by_user_id(
cls, user_id: str, bot_id: str
) -> Optional[str]:
return await cls.get_user_attr(user_id, bot_id, 'stoken')
@classmethod
async def cookie_validate(
cls, uid: str, game_name: Optional[str] = None
) -> bool:
data = await cls.get_user_attr_by_uid(uid, 'status', game_name)
if not data:
return True
else:
return False
@classmethod
@with_session
async def get_switch_open_list(
cls: Type[T_User], session: AsyncSession, switch_name: str
) -> List[T_User]:
_switch = getattr(cls, switch_name, cls.push_switch)
sql = select(cls).filter(_switch != 'off')
data = await session.execute(sql)
data_list: List[T_User] = data.scalars().all()
return [user for user in data_list]
@classmethod
@with_session
async def get_all_user(
cls: Type[T_User], session: AsyncSession
) -> List[T_User]:
sql = select(cls).where(cls.cookie is not None, cls.cookie != '')
result = await session.execute(sql)
data: List[T_User] = result.scalars().all()
return data
@classmethod
async def get_all_cookie(cls) -> List[str]:
data = await cls.get_all_user()
return [_u.cookie for _u in data if _u.cookie]
@classmethod
async def get_all_stoken(cls) -> List[str]:
data = await cls.get_all_user()
return [_u.stoken for _u in data if _u.stoken]
@classmethod
async def get_all_error_cookie(cls) -> List[str]:
data = await cls.get_all_user()
return [_u.cookie for _u in data if _u.cookie and _u.status]
@classmethod
async def get_all_push_user_list(cls: Type[T_User]) -> List[T_User]:
data = await cls.get_all_user()
return [user for user in data if user.push_switch != 'off']
@classmethod
async def user_exists(
cls, uid: str, game_name: Optional[str] = None
) -> bool:
data = await cls.select_data_by_uid(uid, game_name)
return True if data else False
@classmethod
@with_session
async def get_random_cookie(
cls: Type[T_User],
session: AsyncSession,
uid: str,
cache_model: Optional[Type["Cache"]] = None,
condition: Optional[Dict[str, str]] = None,
game_name: Optional[str] = None,
) -> Optional[str]:
# 有绑定自己CK 并且该CK有效的前提下优先使用自己CK
if await cls.user_exists(uid, game_name) and await cls.cookie_validate(
uid, game_name
):
return await cls.get_user_cookie_by_uid(uid, game_name)
# 自动刷新缓存
# await self.delete_error_cache()
# 获得缓存库Ck
if cache_model is not None:
cache_data = await cache_model.select_cache_cookie(uid, game_name)
if cache_data is not None:
return cache_data
# 随机取CK
if condition:
for i in condition:
sql = (
select(cls)
.where(getattr(cls, i) == condition[i])
.order_by(func.random())
)
data = await session.execute(sql)
user_list: List[T_User] = data.scalars().all()
break
else:
user_list = await cls.get_all_user()
else:
user_list = await cls.get_all_user()
for user in user_list:
if not user.status and user.cookie:
if cache_model:
# 进入缓存
await cache_model.insert_cache_data(
user.cookie,
**{cls.get_gameid_name(game_name): uid},
)
return user.cookie
continue
else:
return None
@classmethod
@with_session
async def delete_user_data_by_uid(
cls, session: AsyncSession, uid: str, game_name: Optional[str] = None
):
if await cls.user_exists(uid, game_name):
sql = delete(cls).where(
getattr(cls, cls.get_gameid_name(game_name)) == uid
)
await session.execute(sql)
await session.commit()
return True
return False
class Cache(BaseIDModel):
cookie: str = Field(default=None, title='Cookie')
@classmethod
@with_session
async def select_cache_cookie(
cls, session: AsyncSession, uid: str, game_name: Optional[str]
) -> Optional[str]:
sql = select(cls).where(
getattr(cls, cls.get_gameid_name(game_name)) == uid
)
result = await session.execute(sql)
data: List["Cache"] = result.scalars().all()
return data[0].cookie if len(data) >= 1 else None
@classmethod
@with_session
async def delete_error_cache(
cls, session: AsyncSession, user: Type["User"]
) -> bool:
data = await user.get_all_error_cookie()
for cookie in data:
sql = delete(cls).where(cls.cookie == cookie)
await session.execute(sql)
return True
@classmethod
@with_session
async def delete_all_cache(
cls, session: AsyncSession, user: Type["User"]
) -> bool:
sql = update(user).where(user.status == 'limit30').values(status=None)
empty_sql = delete(cls)
await session.execute(sql)
await session.execute(empty_sql)
await session.commit()
return True
@classmethod
@with_session
async def refresh_cache(
cls, session: AsyncSession, uid: str, game_name: Optional[str] = None
) -> bool:
await session.execute(
delete(cls).where(
getattr(cls, cls.get_gameid_name(game_name)) == uid
)
)
return True
@classmethod
@with_session
async def insert_cache_data(
cls, session: AsyncSession, cookie: str, **data
) -> bool:
new_data = cls(cookie=cookie, **data)
session.add(new_data)
await session.commit()
return True
class Push(BaseBotIDModel):
pass

View File

@ -2,27 +2,18 @@ import re
import asyncio import asyncio
from typing import Dict, List, Literal, Optional from typing import Dict, List, Literal, Optional
from sqlmodel import SQLModel
from sqlalchemy.sql import text from sqlalchemy.sql import text
from sqlmodel import SQLModel, col
from sqlalchemy.future import select
from sqlalchemy import delete, update
from sqlalchemy.orm import sessionmaker
from sqlalchemy.sql.expression import func
from sqlalchemy.ext.asyncio import AsyncSession, create_async_engine
from .utils import SERVER, SR_SERVER from .utils import SERVER, SR_SERVER
from .base_models import engine, async_maker
from .models import GsBind, GsPush, GsUser, GsCache from .models import GsBind, GsPush, GsUser, GsCache
class SQLA: class SQLA:
def __init__(self, url: str, bot_id: str, is_sr: bool = False): def __init__(self, bot_id: str, is_sr: bool = False):
self.bot_id = bot_id self.bot_id = bot_id
self.is_sr = is_sr self.is_sr = is_sr
self.url = f'sqlite+aiosqlite:///{url}'
self.engine = create_async_engine(self.url, pool_recycle=1500)
self.async_session = sessionmaker(
self.engine, expire_on_commit=False, class_=AsyncSession
)
def create_all(self): def create_all(self):
try: try:
@ -33,7 +24,7 @@ class SQLA:
loop.close() loop.close()
async def _create_all(self): async def _create_all(self):
async with self.engine.begin() as conn: async with engine.begin() as conn:
await conn.run_sync(SQLModel.metadata.create_all) await conn.run_sync(SQLModel.metadata.create_all)
await self.sr_adapter() await self.sr_adapter()
@ -50,7 +41,7 @@ class SQLA:
'ALTER TABLE GsUser ADD COLUMN draw_switch TEXT DEFAULT "off"', 'ALTER TABLE GsUser ADD COLUMN draw_switch TEXT DEFAULT "off"',
'ALTER TABLE GsCache ADD COLUMN sr_uid TEXT', 'ALTER TABLE GsCache ADD COLUMN sr_uid TEXT',
] ]
async with self.async_session() as session: async with async_maker() as session:
for _t in exec_list: for _t in exec_list:
try: try:
await session.execute(text(_t)) await session.execute(text(_t))
@ -62,213 +53,119 @@ class SQLA:
# GsBind 部分 # # GsBind 部分 #
##################### #####################
async def select_bind_data(self, user_id: str) -> Optional[GsBind]: async def select_bind_data(self, user_id: str) -> Optional[GsBind]:
async with self.async_session() as session: return await GsBind.select_data(user_id, self.bot_id)
async with session.begin():
result = await session.execute(
select(GsBind).where(
GsBind.user_id == user_id, GsBind.bot_id == self.bot_id
)
)
data = result.scalars().all()
return data[0] if data else None
async def insert_bind_data(self, user_id: str, **data) -> int: async def insert_bind_data(self, user_id: str, **data) -> int:
async with self.async_session() as session: group_id = data['group_id'] if 'group_id' in data else None
async with session.begin(): new_uid: str = data['uid'] if 'uid' in data else ''
new_uid: str = data['uid'] if 'uid' in data else '' new_uid = new_uid.strip()
new_uid = new_uid.strip() new_sr_uid: str = data['sr_uid'] if 'sr_uid' in data else ''
new_sr_uid: str = data['sr_uid'] if 'sr_uid' in data else '' new_sr_uid = new_sr_uid.strip()
new_sr_uid = new_sr_uid.strip() if new_uid:
if len(new_uid) != 9 and len(new_sr_uid) != 9: retcode = await GsBind.insert_uid(
return -1 user_id, self.bot_id, new_uid, group_id, 9, True
elif not new_uid.isdigit() and not new_sr_uid.isdigit(): )
return -3 if retcode:
if new_uid and await self.bind_exists(user_id): return retcode
uid_list = await self.get_bind_uid_list(user_id) if new_sr_uid:
if new_uid not in uid_list: retcode = await GsBind.insert_uid(
uid_list.append(new_uid) user_id,
else: self.bot_id,
return -2 new_sr_uid,
data['uid'] = '_'.join(uid_list) group_id,
await self.update_bind_data(user_id, data) 9,
elif new_sr_uid and await self.bind_exists(user_id): True,
sr_uid_list = await self.get_bind_sruid_list(user_id) 'sr',
if new_sr_uid not in sr_uid_list: )
sr_uid_list.append(new_sr_uid) if retcode:
else: return retcode
return -2 return 0
data['sr_uid'] = '_'.join(sr_uid_list)
await self.update_bind_data(user_id, data)
else:
new_data = GsBind(
user_id=user_id, bot_id=self.bot_id, **data
)
session.add(new_data)
await session.commit()
return 0
async def delete_bind_data(self, user_id: str, **data) -> int: async def delete_bind_data(self, user_id: str, **data) -> int:
async with self.async_session() as session: _uid = data['uid'] if 'uid' in data else ''
async with session.begin(): _sr_uid = data['sr_uid'] if 'sr_uid' in data else ''
_uid = data['uid'] if 'uid' in data else '' if _uid:
_sr_uid = data['sr_uid'] if 'sr_uid' in data else '' return await GsBind.delete_uid(user_id, self.bot_id, _uid)
if _uid and await self.bind_exists(user_id): elif _sr_uid:
uid_list = await self.get_bind_uid_list(user_id) return await GsBind.delete_uid(user_id, self.bot_id, _uid, 'sr')
if uid_list and _uid in uid_list: else:
uid_list.remove(_uid) return -1
else:
return -1
data['uid'] = '_'.join(uid_list)
await self.update_bind_data(user_id, data)
await session.commit()
return 0
elif _sr_uid and await self.bind_exists(user_id):
uid_list = await self.get_bind_sruid_list(user_id)
if uid_list and _sr_uid in uid_list:
uid_list.remove(_sr_uid)
else:
return -1
data['sr_uid'] = '_'.join(uid_list)
await self.update_bind_data(user_id, data)
await session.commit()
return 0
else:
return -1
async def update_bind_data(self, user_id: str, data: Optional[Dict]): async def update_bind_data(self, user_id: str, data: Optional[Dict]):
async with self.async_session() as session: if data is not None:
async with session.begin(): await GsBind.update_data(user_id, self.bot_id, **data)
sql = update(GsBind).where(
GsBind.user_id == user_id, GsBind.bot_id == self.bot_id
)
if data is not None:
query = sql.values(**data)
query.execution_options(synchronize_session='fetch')
await session.execute(query)
async def bind_exists(self, user_id: str) -> bool: async def bind_exists(self, user_id: str) -> bool:
return bool(await self.select_bind_data(user_id)) return await GsBind.bind_exists(user_id, self.bot_id)
async def get_all_uid_list(self) -> List[str]: async def get_all_uid_list(self) -> List[str]:
async with self.async_session() as session: return await GsBind.get_all_uid_list_by_game(
async with session.begin(): self.bot_id, 'sr' if self.is_sr else None
sql = select(GsBind).where(GsBind.bot_id == self.bot_id) )
result = await session.execute(sql)
data: List[GsBind] = result.scalars().all()
uid_list: List[str] = []
for item in data:
uid_list.extend(item.uid.split("_") if item.uid else [])
return uid_list
async def get_bind_group_list(self, user_id: str) -> List[str]: async def get_bind_group_list(self, user_id: str) -> List[str]:
data = await self.select_bind_data(user_id) return await GsBind.get_bind_group_list(user_id, self.bot_id)
return data.group_id.split("_") if data and data.group_id else []
async def get_bind_group(self, user_id: str) -> Optional[str]: async def get_bind_group(self, user_id: str) -> Optional[str]:
data = await self.get_bind_group_list(user_id) return await GsBind.get_bind_group(user_id, self.bot_id)
return data[0] if data else None
async def get_group_all_uid(self, group_id: str): async def get_group_all_uid(self, group_id: str):
async with self.async_session() as session: return await GsBind.get_group_all_uid(group_id)
async with session.begin():
result = await session.scalars(
select(GsBind).where(
col(GsBind.group_id).contains(group_id)
)
)
data = result.all()
return data[0] if data else None
async def get_bind_uid_list(self, user_id: str) -> List[str]: async def get_bind_uid_list(self, user_id: str) -> Optional[List[str]]:
data = await self.select_bind_data(user_id) return await GsBind.get_uid_list_by_game(user_id, self.bot_id)
return data.uid.split("_") if data and data.uid else []
async def get_bind_uid(self, user_id: str) -> Optional[str]: async def get_bind_uid(self, user_id: str) -> Optional[str]:
data = await self.get_bind_uid_list(user_id) return await GsBind.get_uid_by_game(user_id, self.bot_id)
return data[0] if data else None
async def get_bind_sruid_list(self, user_id: str) -> List[str]: async def get_bind_sruid_list(self, user_id: str) -> Optional[List[str]]:
data = await self.select_bind_data(user_id) return await GsBind.get_uid_list_by_game(user_id, self.bot_id, 'sr')
return data.sr_uid.split("_") if data and data.sr_uid else []
async def get_bind_sruid(self, user_id: str) -> Optional[str]: async def get_bind_sruid(self, user_id: str) -> Optional[str]:
data = await self.get_bind_sruid_list(user_id) return await GsBind.get_uid_by_game(user_id, self.bot_id)
return data[0] if data else None
async def switch_uid( async def switch_uid(
self, user_id: str, uid: Optional[str] = None self, user_id: str, uid: Optional[str] = None
) -> Optional[List]: ) -> Optional[List]:
uid_list = ( retcode = await GsBind.switch_uid_by_game(
await self.get_bind_sruid_list(user_id) user_id,
if self.is_sr self.bot_id,
else await self.get_bind_uid_list(user_id) uid,
'sr' if self.is_sr else None,
) )
id_type = 'sr_uid' if self.is_sr else 'uid' if retcode == 0:
if uid_list and len(uid_list) >= 1: return await GsBind.get_uid_list_by_game(
if uid and uid not in uid_list: user_id,
return None self.bot_id,
elif uid: 'sr' if self.is_sr else None,
pass )
else:
uid = uid_list[1]
uid_list.remove(uid)
uid_list.insert(0, uid)
await self.update_bind_data(user_id, {id_type: '_'.join(uid_list)})
return uid_list
else:
return None
##################### #####################
# GsUser、GsCache 部分 # # GsUser、GsCache 部分 #
##################### #####################
async def select_user_data(self, uid: str) -> Optional[GsUser]: async def select_user_data(self, uid: str) -> Optional[GsUser]:
async with self.async_session() as session: return await GsUser.select_data_by_uid(
async with session.begin(): uid, 'sr' if self.is_sr else None
sql = ( )
select(GsUser).where(GsUser.sr_uid == uid)
if self.is_sr
else select(GsUser).where(GsUser.uid == uid)
)
result = await session.execute(sql)
return data[0] if (data := result.scalars().all()) else None
async def select_user_all_data_by_user_id( async def select_user_all_data_by_user_id(
self, user_id: str self, user_id: str
) -> Optional[List[GsUser]]: ) -> Optional[List[GsUser]]:
async with self.async_session() as session: return await GsUser.get_user_all_data_by_user_id(user_id)
async with session.begin():
sql = select(GsUser).where(GsUser.user_id == user_id)
result = await session.execute(sql)
data = result.scalars().all()
return data if data else None
async def select_user_data_by_user_id( async def select_user_data_by_user_id(
self, user_id: str self, user_id: str
) -> Optional[GsUser]: ) -> Optional[GsUser]:
data = await self.select_user_all_data_by_user_id(user_id) return await GsUser.select_data(user_id)
return data[0] if data else None
async def select_cache_cookie(self, uid: str) -> Optional[str]: async def select_cache_cookie(self, uid: str) -> Optional[str]:
async with self.async_session() as session: return await GsCache.select_cache_cookie(
async with session.begin(): uid, 'sr' if self.is_sr else None
sql = ( )
select(GsCache).where(GsCache.sr_uid == uid)
if self.is_sr
else select(GsCache).where(GsCache.uid == uid)
)
result = await session.execute(sql)
data: List[GsCache] = result.scalars().all()
return data[0].cookie if len(data) >= 1 else None
async def delete_error_cache(self) -> bool: async def delete_error_cache(self) -> bool:
async with self.async_session() as session: return await GsCache.delete_error_cache(GsUser)
async with session.begin():
data = await self.get_all_error_cookie()
for cookie in data:
sql = delete(GsCache).where(GsCache.cookie == cookie)
await session.execute(sql)
return True
async def get_user_fp(self, uid: str) -> Optional[str]: async def get_user_fp(self, uid: str) -> Optional[str]:
data = await self.select_user_data(uid) data = await self.select_user_data(uid)
@ -285,14 +182,9 @@ class SQLA:
sr_uid: Optional[str] = None, sr_uid: Optional[str] = None,
mys_id: Optional[str] = None, mys_id: Optional[str] = None,
) -> bool: ) -> bool:
async with self.async_session() as session: return await GsCache.insert_cache_data(
async with session.begin(): cookie, uid=uid, sr_uid=sr_uid, mys_id=mys_id
new_data = GsCache( )
cookie=cookie, uid=uid, sr_uid=sr_uid, mys_id=mys_id
)
session.add(new_data)
await session.commit()
return True
async def insert_user_data( async def insert_user_data(
self, self,
@ -304,122 +196,75 @@ class SQLA:
fp: Optional[str] = None, fp: Optional[str] = None,
device_id: Optional[str] = None, device_id: Optional[str] = None,
) -> bool: ) -> bool:
async with self.async_session() as session: if uid and await GsUser.user_exists(uid):
async with session.begin(): retcode = await GsUser.update_data_by_uid(
if uid and await self.user_exists(uid): uid,
sql = ( self.bot_id,
update(GsUser) cookie=cookie,
.where(GsUser.uid == uid) status=None,
.values( stoken=stoken,
cookie=cookie, sr_uid=sr_uid,
status=None, fp=fp,
stoken=stoken, )
bot_id=self.bot_id, elif sr_uid and await self.user_exists(sr_uid):
user_id=user_id, retcode = await GsUser.update_data_by_uid(
sr_uid=sr_uid, sr_uid,
fp=fp, self.bot_id,
) 'sr',
) cookie=cookie,
await session.execute(sql) status=None,
elif sr_uid and await self.user_exists(sr_uid): stoken=stoken,
sql = ( sr_uid=sr_uid,
update(GsUser) fp=fp,
.where(GsUser.sr_uid == sr_uid) )
.values( else:
cookie=cookie, if cookie is None:
status=None,
stoken=stoken,
bot_id=self.bot_id,
user_id=user_id,
uid=uid,
fp=fp,
)
)
await session.execute(sql)
else:
if cookie is None:
return False
account_id = re.search(r'account_id=(\d*)', cookie)
assert account_id is not None
account_id = str(account_id.group(1))
user_data = GsUser(
uid=uid,
sr_uid=sr_uid,
mys_id=account_id,
cookie=cookie,
stoken=stoken if stoken else None,
user_id=user_id,
bot_id=self.bot_id,
sign_switch='off',
push_switch='off',
bbs_switch='off',
draw_switch='off',
region=SERVER.get(uid[0], 'cn_gf01') if uid else None,
sr_region=SR_SERVER.get(sr_uid[0], None)
if sr_uid
else None,
fp=fp,
device_id=device_id,
sr_push_switch='off',
sr_sign_switch='off',
)
session.add(user_data)
await session.commit()
return True
async def update_user_data(self, uid: str, data: Optional[Dict]):
async with self.async_session() as session:
async with session.begin():
sql = (
update(GsUser).where(GsUser.sr_uid == uid)
if self.is_sr
else update(GsUser).where(GsUser.uid == uid)
)
if data is not None:
query = sql.values(**data)
query.execution_options(synchronize_session='fetch')
await session.execute(query)
await session.commit()
async def delete_user_data(self, uid: str):
async with self.async_session() as session:
async with session.begin():
if await self.user_exists(uid):
sql = (
delete(GsUser).where(GsUser.sr_uid == uid)
if self.is_sr
else delete(GsUser).where(GsUser.uid == uid)
)
await session.execute(sql)
await session.commit()
return True
return False return False
account_id = re.search(r'account_id=(\d*)', cookie)
assert account_id is not None
account_id = str(account_id.group(1))
retcode = await GsUser.insert_data(
user_id=user_id,
bot_id=self.bot_id,
uid=uid,
sr_uid=sr_uid,
mys_id=account_id,
cookie=cookie,
stoken=stoken if stoken else None,
sign_switch='off',
push_switch='off',
bbs_switch='off',
draw_switch='off',
region=SERVER.get(uid[0], 'cn_gf01') if uid else None,
sr_region=SR_SERVER.get(sr_uid[0], None) if sr_uid else None,
fp=fp,
device_id=device_id,
sr_push_switch='off',
sr_sign_switch='off',
)
if retcode == 0:
return True
else:
return False
async def update_user_data(self, uid: str, data: Dict = {}):
return await GsUser.update_data_by_uid(
uid, self.bot_id, 'sr' if self.is_sr else None, **data
)
async def delete_user_data(self, uid: str):
if await GsUser.user_exists(uid):
return await GsUser.delete_user_data_by_uid(
uid, 'sr' if self.is_sr else None
)
async def delete_cache(self): async def delete_cache(self):
async with self.async_session() as session: return await GsCache.delete_all_cache(GsUser)
async with session.begin():
sql = (
update(GsUser)
.where(GsUser.status == 'limit30')
.values(status=None)
)
empty_sql = delete(GsCache)
await session.execute(sql)
await session.execute(empty_sql)
await session.commit()
async def mark_invalid(self, cookie: str, mark: str): async def mark_invalid(self, cookie: str, mark: str):
async with self.async_session() as session: await GsUser.mark_invalid(cookie, mark)
async with session.begin():
sql = (
update(GsUser)
.where(GsUser.cookie == cookie)
.values(status=mark)
)
await session.execute(sql)
await session.commit()
async def user_exists(self, uid: str) -> bool: async def user_exists(self, uid: str) -> bool:
data = await self.select_user_data(uid) data = await self.select_user_data(uid)
@ -428,212 +273,108 @@ class SQLA:
async def update_user_stoken( async def update_user_stoken(
self, uid: str, stoken: Optional[str] self, uid: str, stoken: Optional[str]
) -> bool: ) -> bool:
async with self.async_session() as session: retcode = -1
async with session.begin(): if await GsUser.user_exists(uid):
if await self.user_exists(uid): retcode = await GsUser.update_data_by_uid(
sql = ( uid, self.bot_id, 'sr' if self.is_sr else None, stoken=stoken
( )
update(GsUser) return bool(retcode)
.where(GsUser.sr_uid == uid)
.values(stoken=stoken)
)
if self.is_sr
else (
update(GsUser)
.where(GsUser.uid == uid)
.values(stoken=stoken)
)
)
await session.execute(sql)
await session.commit()
return True
return False
async def update_user_cookie( async def update_user_cookie(
self, uid: str, cookie: Optional[str] self, uid: str, cookie: Optional[str]
) -> bool: ) -> bool:
async with self.async_session() as session: retcode = -1
async with session.begin(): if await GsUser.user_exists(uid):
if await self.user_exists(uid): retcode = await GsUser.update_data_by_uid(
sql = ( uid, self.bot_id, 'sr' if self.is_sr else None, cookie=cookie
( )
update(GsUser) return bool(retcode)
.where(GsUser.sr_uid == uid)
.values(cookie=cookie)
)
if self.is_sr
else (
update(GsUser)
.where(GsUser.uid == uid)
.values(cookie=cookie)
)
)
await session.execute(sql)
await session.commit()
return True
return False
async def update_switch_status(self, uid: str, data: Dict) -> bool: async def update_switch_status(self, uid: str, data: Dict) -> bool:
async with self.async_session() as session: retcode = -1
async with session.begin(): if await GsUser.user_exists(uid):
if await self.user_exists(uid): retcode = await GsUser.update_data_by_uid(
sql = ( uid, self.bot_id, 'sr' if self.is_sr else None, **data
( )
update(GsUser) return bool(retcode)
.where(GsUser.sr_uid == uid)
.values(**data)
)
if self.is_sr
else (
update(GsUser)
.where(GsUser.uid == uid)
.values(**data)
)
)
await session.execute(sql)
await session.commit()
return True
return False
async def update_error_status(self, cookie: str, err: str) -> bool: async def update_error_status(self, cookie: str, err: str) -> bool:
async with self.async_session() as session: return await GsUser.mark_invalid(cookie, err)
async with session.begin():
sql = (
update(GsUser)
.where(GsUser.cookie == cookie)
.values(status=err)
)
await session.execute(sql)
await session.commit()
return True
async def get_user_cookie(self, uid: str) -> Optional[str]: async def get_user_cookie(self, uid: str) -> Optional[str]:
data = await self.select_user_data(uid) return await GsUser.get_user_cookie_by_uid(
return data.cookie if data else None uid, 'sr' if self.is_sr else None
)
async def get_user_cookie_by_user_id(self, user_id: str) -> Optional[str]: async def get_user_cookie_by_user_id(self, user_id: str) -> Optional[str]:
data = await self.select_user_data_by_user_id(user_id) return await GsUser.get_user_cookie_by_user_id(user_id, self.bot_id)
return data.cookie if data else None
async def cookie_validate(self, uid: str) -> bool: async def cookie_validate(self, uid: str) -> bool:
data = await self.select_user_data(uid) return await GsUser.cookie_validate(uid, 'sr' if self.is_sr else None)
return True if data and data.status is None else False
async def get_user_stoken_by_user_id(self, user_id: str) -> Optional[str]: async def get_user_stoken_by_user_id(self, user_id: str) -> Optional[str]:
data = await self.select_user_data_by_user_id(user_id) return await GsUser.get_user_stoken_by_user_id(user_id, self.bot_id)
return data.stoken if data and data.stoken else None
async def get_user_stoken(self, uid: str) -> Optional[str]: async def get_user_stoken(self, uid: str) -> Optional[str]:
data = await self.select_user_data(uid) return await GsUser.get_user_stoken_by_uid(
return data.stoken if data and data.stoken else None uid, 'sr' if self.is_sr else None
)
async def get_all_user(self) -> List[GsUser]: async def get_all_user(self) -> List[GsUser]:
async with self.async_session() as session: return await GsUser.get_all_user()
async with session.begin():
sql = select(GsUser).where(
GsUser.cookie is not None, GsUser.cookie != ''
)
result = await session.execute(sql)
data: List[GsUser] = result.scalars().all()
return data
async def get_all_cookie(self) -> List[str]: async def get_all_cookie(self) -> List[str]:
data = await self.get_all_user() return await GsUser.get_all_cookie()
return [_u.cookie for _u in data if _u.cookie]
async def get_all_stoken(self) -> List[str]: async def get_all_stoken(self) -> List[str]:
data = await self.get_all_user() return await GsUser.get_all_stoken()
return [_u.stoken for _u in data if _u.stoken]
async def get_all_error_cookie(self) -> List[str]: async def get_all_error_cookie(self) -> List[str]:
data = await self.get_all_user() return await GsUser.get_all_error_cookie()
return [_u.cookie for _u in data if _u.cookie and _u.status]
async def get_all_push_user_list(self) -> List[GsUser]: async def get_all_push_user_list(self) -> List[GsUser]:
data = await self.get_all_user() return await GsUser.get_all_push_user_list()
return [user for user in data if user.push_switch != 'off']
async def get_random_cookie(self, uid: str) -> Optional[str]: async def get_random_cookie(self, uid: str) -> Optional[str]:
async with self.async_session() as session: server = SERVER.get(uid[0], 'cn_gf01')
async with session.begin(): return await GsUser.get_random_cookie(
# 有绑定自己CK 并且该CK有效的前提下优先使用自己CK uid, GsCache, {'region': server}, 'sr' if self.is_sr else None
if await self.user_exists(uid) and await self.cookie_validate( )
uid
):
return await self.get_user_cookie(uid)
# 自动刷新缓存
await self.delete_error_cache()
# 获得缓存库Ck
cache_data = await self.select_cache_cookie(uid)
if cache_data is not None:
return cache_data
# 随机取CK
server = SERVER.get(uid[0], 'cn_gf01')
sql = (
select(GsUser)
.where(GsUser.region == server)
.order_by(func.random())
)
data = await session.execute(sql)
user_list: List[GsUser] = data.scalars().all()
for user in user_list:
if not user.status and user.cookie:
# 进入缓存
if self.is_sr:
await self.insert_cache_data(
user.cookie, sr_uid=uid
)
else:
await self.insert_cache_data(user.cookie, uid)
return user.cookie
continue
else:
return None
async def get_switch_status_list( async def get_switch_status_list(
self, switch: Literal['push', 'sign', 'bbs', 'sr_push', 'sr_sign'] self, switch: Literal['push', 'sign', 'bbs', 'sr_push', 'sr_sign']
) -> List[GsUser]: ) -> List[GsUser]:
async with self.async_session() as session: return await GsUser.get_switch_open_list(switch)
async with session.begin():
_switch = getattr(GsUser, switch, GsUser.push_switch)
sql = select(GsUser).filter(_switch != 'off')
data = await session.execute(sql)
data_list: List[GsUser] = data.scalars().all()
return [user for user in data_list]
##################### #####################
# GsPush 部分 # # GsPush 部分 #
##################### #####################
async def insert_push_data(self, uid: str): async def insert_push_data(self, uid: str):
async with self.async_session() as session: await GsPush.full_insert_data(
async with session.begin(): GsPush,
push_data = GsPush( bot_id=self.bot_id,
bot_id=self.bot_id, uid=uid,
uid=uid, coin_push='off',
coin_push='off', coin_value=2100,
coin_value=2100, coin_is_push='off',
coin_is_push='off', resin_push='on',
resin_push='on', resin_value=140,
resin_value=140, resin_is_push='off',
resin_is_push='off', go_push='off',
go_push='off', go_value=120,
go_value=120, go_is_push='off',
go_is_push='off', transform_push='off',
transform_push='off', transform_value=140,
transform_value=140, transform_is_push='off',
transform_is_push='off', )
)
session.add(push_data)
await session.commit()
async def update_push_data(self, uid: str, data: dict) -> bool: async def update_push_data(self, uid: str, data: dict) -> bool:
async with self.async_session() as session: retcode = -1
async with session.begin(): if await GsPush.data_exist(GsPush, uid=uid):
await self.push_exists(uid) retcode = await GsPush.update_data_by_uid(
sql = update(GsPush).where(GsPush.uid == uid).values(**data) uid, self.bot_id, 'sr' if self.is_sr else None, **data
await session.execute(sql) )
await session.commit() return not bool(retcode)
return True
async def change_push_status( async def change_push_status(
self, self,
@ -644,54 +385,22 @@ class SQLA:
await self.update_push_data(uid, {f'{mode}_is_push': status}) await self.update_push_data(uid, {f'{mode}_is_push': status})
async def select_push_data(self, uid: str) -> Optional[GsPush]: async def select_push_data(self, uid: str) -> Optional[GsPush]:
async with self.async_session() as session: return await GsPush.base_select_data(GsPush, uid=uid)
async with session.begin():
await self.push_exists(uid)
sql = select(GsPush).where(GsPush.uid == uid)
result = await session.execute(sql)
data = result.scalars().all()
return data[0] if len(data) >= 1 else None
async def push_exists(self, uid: str) -> bool: async def push_exists(self, uid: str) -> bool:
async with self.async_session() as session: return await GsPush.data_exist(GsPush, uid=uid)
async with session.begin():
sql = select(GsPush).where(GsPush.uid == uid)
result = await session.execute(sql)
data = result.scalars().all()
if not data:
await self.insert_push_data(uid)
return True
##################### #####################
# 杂项部分 # # 杂项部分 #
##################### #####################
async def refresh_cache(self, uid: str): async def refresh_cache(self, uid: str):
async with self.async_session() as session: await GsCache.refresh_cache(uid, 'sr' if self.is_sr else None)
async with session.begin():
sql = (
delete(GsCache).where(GsCache.sr_uid == uid)
if self.is_sr
else delete(GsCache).where(GsCache.uid == uid)
)
await session.execute(sql)
return True
async def close(self): async def close(self):
async with self.async_session() as session: async with async_maker() as session:
async with session.begin(): async with session.begin():
await session.close() await session.close()
async def insert_new_bind(self, **kwargs): async def insert_new_bind(self, **kwargs):
async with self.async_session() as session: await GsBind.full_insert_data(GsBind, **kwargs)
async with session.begin():
new_data = GsBind(**kwargs)
session.add(new_data)
await session.commit()
async def insert_new_user(self, **kwargs):
async with self.async_session() as session:
async with session.begin():
new_data = GsUser(**kwargs)
session.add(new_data)
await session.commit()

View File

@ -1,54 +1,43 @@
from typing import Optional from typing import Optional
from sqlmodel import Field, SQLModel from sqlmodel import Field
from .base_models import Bind, Push, User, Cache
class GsBind(SQLModel, table=True): class GsBind(Bind, table=True):
__table_args__ = {'keep_existing': True} __table_args__ = {'extend_existing': True}
id: Optional[int] = Field(default=None, primary_key=True, title='序号')
bot_id: str = Field(title='平台')
user_id: str = Field(title='账号')
group_id: Optional[str] = Field(title='群号')
uid: Optional[str] = Field(default=None, title='原神UID') uid: Optional[str] = Field(default=None, title='原神UID')
sr_uid: Optional[str] = Field(default=None, title='星铁UID') sr_uid: Optional[str] = Field(default=None, title='星铁UID')
mys_id: Optional[str] = Field(default=None, title='米游社通行证') mys_id: Optional[str] = Field(default=None, title='米游社通行证')
class GsUser(SQLModel, table=True): class GsUser(User, table=True):
__table_args__ = {'keep_existing': True} __table_args__ = {'extend_existing': True}
id: Optional[int] = Field(default=None, primary_key=True, title='序号')
bot_id: str = Field(title='平台')
uid: Optional[str] = Field(default=None, title='原神UID') uid: Optional[str] = Field(default=None, title='原神UID')
sr_uid: Optional[str] = Field(default=None, title='星铁UID') sr_uid: Optional[str] = Field(default=None, title='星铁UID')
mys_id: Optional[str] = Field(default=None, title='米游社通行证') mys_id: Optional[str] = Field(default=None, title='米游社通行证')
region: Optional[str] = Field(default=None, title='原神地区') region: Optional[str] = Field(default=None, title='原神地区')
sr_region: Optional[str] = Field(default=None, title='星铁地区') sr_region: Optional[str] = Field(default=None, title='星铁地区')
cookie: Optional[str] = Field(default=None, title='Cookie')
stoken: Optional[str] = Field(default=None, title='Stoken')
user_id: str = Field(title='账号')
push_switch: str = Field(default='off', title='全局推送开关')
sign_switch: str = Field(default='off', title='自动签到')
bbs_switch: str = Field(default='off', title='自动米游币') bbs_switch: str = Field(default='off', title='自动米游币')
draw_switch: str = Field(default='off', title='自动留影叙佳期') draw_switch: str = Field(default='off', title='自动留影叙佳期')
sr_push_switch: str = Field(default='off', title='星铁全局推送开关') sr_push_switch: str = Field(default='off', title='星铁全局推送开关')
sr_sign_switch: str = Field(default='off', title='星铁自动签到') sr_sign_switch: str = Field(default='off', title='星铁自动签到')
status: Optional[str] = Field(default=None, title='状态')
fp: Optional[str] = Field(default=None, title='Fingerprint') fp: Optional[str] = Field(default=None, title='Fingerprint')
device_id: Optional[str] = Field(default=None, title='设备ID') device_id: Optional[str] = Field(default=None, title='设备ID')
class GsCache(SQLModel, table=True): class GsCache(Cache, table=True):
__table_args__ = {'keep_existing': True} __table_args__ = {'extend_existing': True}
id: Optional[int] = Field(default=None, primary_key=True, title='序号')
cookie: str = Field(default=None, title='Cookie') cookie: str = Field(default=None, title='Cookie')
uid: Optional[str] = Field(default=None, title='原神UID') uid: Optional[str] = Field(default=None, title='原神UID')
sr_uid: Optional[str] = Field(default=None, title='星铁UID') sr_uid: Optional[str] = Field(default=None, title='星铁UID')
mys_id: Optional[str] = Field(default=None, title='米游社通行证') mys_id: Optional[str] = Field(default=None, title='米游社通行证')
class GsPush(SQLModel, table=True): class GsPush(Push, table=True):
__table_args__ = {'keep_existing': True} __table_args__ = {'extend_existing': True}
id: Optional[int] = Field(default=None, primary_key=True, title='序号')
bot_id: str = Field(title='平台') bot_id: str = Field(title='平台')
uid: str = Field(default=None, title='原神UID') uid: str = Field(default=None, title='原神UID')
coin_push: Optional[str] = Field(title='洞天宝钱推送', default='off') coin_push: Optional[str] = Field(title='洞天宝钱推送', default='off')

View File

@ -0,0 +1,9 @@
from typing import Any, Dict
from gsuid_core.bot import Bot
async def send_diff_msg(bot: Bot, code: Any, data: Dict):
for retcode in data:
if code == retcode:
return await bot.send(data[retcode])

View File

@ -37,8 +37,8 @@ from fastapi_amis_admin.amis.components import (
) )
from gsuid_core.logger import logger from gsuid_core.logger import logger
from gsuid_core.utils.database.api import db_url
from gsuid_core.webconsole.models import WebUser from gsuid_core.webconsole.models import WebUser
from gsuid_core.utils.database.base_models import db_url
from gsuid_core.utils.cookie_manager.add_ck import _deal_ck from gsuid_core.utils.cookie_manager.add_ck import _deal_ck
from gsuid_core.webconsole.html import gsuid_webconsole_help from gsuid_core.webconsole.html import gsuid_webconsole_help
from gsuid_core.webconsole.create_sv_panel import get_sv_page from gsuid_core.webconsole.create_sv_panel import get_sv_page