123
This commit is contained in:
18
backend/shared/models/__init__.py
Normal file
18
backend/shared/models/__init__.py
Normal file
@@ -0,0 +1,18 @@
|
||||
"""Shared ORM models for Weibo-HotSign."""
|
||||
|
||||
from .base import Base, get_db, engine, AsyncSessionLocal
|
||||
from .user import User
|
||||
from .account import Account
|
||||
from .task import Task
|
||||
from .signin_log import SigninLog
|
||||
|
||||
__all__ = [
|
||||
"Base",
|
||||
"get_db",
|
||||
"engine",
|
||||
"AsyncSessionLocal",
|
||||
"User",
|
||||
"Account",
|
||||
"Task",
|
||||
"SigninLog",
|
||||
]
|
||||
BIN
backend/shared/models/__pycache__/__init__.cpython-311.pyc
Normal file
BIN
backend/shared/models/__pycache__/__init__.cpython-311.pyc
Normal file
Binary file not shown.
BIN
backend/shared/models/__pycache__/account.cpython-311.pyc
Normal file
BIN
backend/shared/models/__pycache__/account.cpython-311.pyc
Normal file
Binary file not shown.
BIN
backend/shared/models/__pycache__/base.cpython-311.pyc
Normal file
BIN
backend/shared/models/__pycache__/base.cpython-311.pyc
Normal file
Binary file not shown.
BIN
backend/shared/models/__pycache__/signin_log.cpython-311.pyc
Normal file
BIN
backend/shared/models/__pycache__/signin_log.cpython-311.pyc
Normal file
Binary file not shown.
BIN
backend/shared/models/__pycache__/task.cpython-311.pyc
Normal file
BIN
backend/shared/models/__pycache__/task.cpython-311.pyc
Normal file
Binary file not shown.
BIN
backend/shared/models/__pycache__/user.cpython-311.pyc
Normal file
BIN
backend/shared/models/__pycache__/user.cpython-311.pyc
Normal file
Binary file not shown.
30
backend/shared/models/account.py
Normal file
30
backend/shared/models/account.py
Normal file
@@ -0,0 +1,30 @@
|
||||
"""Account ORM model."""
|
||||
|
||||
import uuid
|
||||
|
||||
from sqlalchemy import Column, DateTime, ForeignKey, String, Text
|
||||
from sqlalchemy.orm import relationship
|
||||
from sqlalchemy.sql import func
|
||||
|
||||
from .base import Base
|
||||
|
||||
|
||||
class Account(Base):
|
||||
__tablename__ = "accounts"
|
||||
|
||||
id = Column(String(36), primary_key=True, default=lambda: str(uuid.uuid4()))
|
||||
user_id = Column(String(36), ForeignKey("users.id", ondelete="CASCADE"), nullable=False)
|
||||
weibo_user_id = Column(String(20), nullable=False)
|
||||
remark = Column(String(100))
|
||||
encrypted_cookies = Column(Text, nullable=False)
|
||||
iv = Column(String(32), nullable=False)
|
||||
status = Column(String(20), default="pending")
|
||||
last_checked_at = Column(DateTime, nullable=True)
|
||||
created_at = Column(DateTime, server_default=func.now())
|
||||
|
||||
user = relationship("User", back_populates="accounts")
|
||||
tasks = relationship("Task", back_populates="account", cascade="all, delete-orphan")
|
||||
signin_logs = relationship("SigninLog", back_populates="account")
|
||||
|
||||
def __repr__(self):
|
||||
return f"<Account(id={self.id}, weibo_user_id='{self.weibo_user_id}')>"
|
||||
33
backend/shared/models/base.py
Normal file
33
backend/shared/models/base.py
Normal file
@@ -0,0 +1,33 @@
|
||||
"""
|
||||
Database engine, session factory, and declarative base.
|
||||
"""
|
||||
|
||||
from typing import AsyncGenerator
|
||||
|
||||
from sqlalchemy.ext.asyncio import AsyncSession, create_async_engine
|
||||
from sqlalchemy.orm import sessionmaker, declarative_base
|
||||
|
||||
from ..config import shared_settings
|
||||
|
||||
_engine_kwargs: dict = {"echo": False}
|
||||
if "sqlite" not in shared_settings.DATABASE_URL:
|
||||
_engine_kwargs.update(pool_size=20, max_overflow=30, pool_pre_ping=True)
|
||||
|
||||
engine = create_async_engine(shared_settings.DATABASE_URL, **_engine_kwargs)
|
||||
|
||||
AsyncSessionLocal = sessionmaker(
|
||||
engine,
|
||||
class_=AsyncSession,
|
||||
expire_on_commit=False,
|
||||
)
|
||||
|
||||
Base = declarative_base()
|
||||
|
||||
|
||||
async def get_db() -> AsyncGenerator[AsyncSession, None]:
|
||||
"""Dependency that yields an async database session."""
|
||||
async with AsyncSessionLocal() as session:
|
||||
try:
|
||||
yield session
|
||||
finally:
|
||||
await session.close()
|
||||
23
backend/shared/models/signin_log.py
Normal file
23
backend/shared/models/signin_log.py
Normal file
@@ -0,0 +1,23 @@
|
||||
"""SigninLog ORM model."""
|
||||
|
||||
from sqlalchemy import Integer, Column, DateTime, ForeignKey, JSON, String, Text
|
||||
from sqlalchemy.orm import relationship
|
||||
from sqlalchemy.sql import func
|
||||
|
||||
from .base import Base
|
||||
|
||||
|
||||
class SigninLog(Base):
|
||||
__tablename__ = "signin_logs"
|
||||
id = Column(Integer, primary_key=True, autoincrement=True)
|
||||
account_id = Column(String(36), ForeignKey("accounts.id"), nullable=False)
|
||||
topic_title = Column(String(100))
|
||||
status = Column(String(20), nullable=False)
|
||||
reward_info = Column(JSON, nullable=True)
|
||||
error_message = Column(Text, nullable=True)
|
||||
signed_at = Column(DateTime, server_default=func.now())
|
||||
|
||||
account = relationship("Account", back_populates="signin_logs")
|
||||
|
||||
def __repr__(self):
|
||||
return f"<SigninLog(id={self.id}, status='{self.status}')>"
|
||||
24
backend/shared/models/task.py
Normal file
24
backend/shared/models/task.py
Normal file
@@ -0,0 +1,24 @@
|
||||
"""Task ORM model."""
|
||||
|
||||
import uuid
|
||||
|
||||
from sqlalchemy import Boolean, Column, DateTime, ForeignKey, String
|
||||
from sqlalchemy.orm import relationship
|
||||
from sqlalchemy.sql import func
|
||||
|
||||
from .base import Base
|
||||
|
||||
|
||||
class Task(Base):
|
||||
__tablename__ = "tasks"
|
||||
|
||||
id = Column(String(36), primary_key=True, default=lambda: str(uuid.uuid4()))
|
||||
account_id = Column(String(36), ForeignKey("accounts.id", ondelete="CASCADE"), nullable=False)
|
||||
cron_expression = Column(String(50), nullable=False)
|
||||
is_enabled = Column(Boolean, default=True)
|
||||
created_at = Column(DateTime, server_default=func.now())
|
||||
|
||||
account = relationship("Account", back_populates="tasks")
|
||||
|
||||
def __repr__(self):
|
||||
return f"<Task(id={self.id}, cron='{self.cron_expression}')>"
|
||||
25
backend/shared/models/user.py
Normal file
25
backend/shared/models/user.py
Normal file
@@ -0,0 +1,25 @@
|
||||
"""User ORM model."""
|
||||
|
||||
import uuid
|
||||
|
||||
from sqlalchemy import Boolean, Column, DateTime, String
|
||||
from sqlalchemy.orm import relationship
|
||||
from sqlalchemy.sql import func
|
||||
|
||||
from .base import Base
|
||||
|
||||
|
||||
class User(Base):
|
||||
__tablename__ = "users"
|
||||
|
||||
id = Column(String(36), primary_key=True, default=lambda: str(uuid.uuid4()))
|
||||
username = Column(String(50), unique=True, nullable=False, index=True)
|
||||
email = Column(String(255), unique=True, nullable=False, index=True)
|
||||
hashed_password = Column(String(255), nullable=False)
|
||||
created_at = Column(DateTime, server_default=func.now())
|
||||
is_active = Column(Boolean, default=True)
|
||||
|
||||
accounts = relationship("Account", back_populates="user", cascade="all, delete-orphan")
|
||||
|
||||
def __repr__(self):
|
||||
return f"<User(id={self.id}, username='{self.username}')>"
|
||||
Reference in New Issue
Block a user