From c2634d45ad496c077fa6699fd8822993f2031ad7 Mon Sep 17 00:00:00 2001 From: Timothy Jaeryang Baek Date: Fri, 28 Nov 2025 07:27:55 -0500 Subject: [PATCH] refac --- .../b10670c03dd5_update_user_table.py | 17 ++----------- backend/open_webui/models/users.py | 24 ++++++++++++++++--- 2 files changed, 23 insertions(+), 18 deletions(-) diff --git a/backend/open_webui/migrations/versions/b10670c03dd5_update_user_table.py b/backend/open_webui/migrations/versions/b10670c03dd5_update_user_table.py index ce7d3d9870..f35a382645 100644 --- a/backend/open_webui/migrations/versions/b10670c03dd5_update_user_table.py +++ b/backend/open_webui/migrations/versions/b10670c03dd5_update_user_table.py @@ -113,24 +113,12 @@ def _convert_column_to_text(table: str, column: str): def upgrade() -> None: - - op.add_column( - "user", - sa.Column( - "is_active", - sa.Boolean(), - nullable=False, - default=False, - server_default=sa.sql.expression.false(), - ), - ) - op.add_column( "user", sa.Column("profile_banner_image_url", sa.Text(), nullable=True) ) - op.add_column("user", sa.Column("timezone", sa.String(), nullable=True)) + op.add_column("user", sa.Column("presence_state", sa.String(), nullable=True)) op.add_column("user", sa.Column("status_emoji", sa.String(), nullable=True)) op.add_column("user", sa.Column("status_message", sa.Text(), nullable=True)) op.add_column( @@ -249,11 +237,10 @@ def downgrade() -> None: op.drop_table("api_key") with op.batch_alter_table("user") as batch_op: - batch_op.drop_column("is_active") - batch_op.drop_column("profile_banner_image_url") batch_op.drop_column("timezone") + batch_op.drop_column("presence_state") batch_op.drop_column("status_emoji") batch_op.drop_column("status_message") batch_op.drop_column("status_expires_at") diff --git a/backend/open_webui/models/users.py b/backend/open_webui/models/users.py index 1ae33f6537..c09cc93934 100644 --- a/backend/open_webui/models/users.py +++ b/backend/open_webui/models/users.py @@ -46,7 +46,6 @@ class User(Base): role = Column(String) name = Column(String) - is_active = Column(Boolean, nullable=False, default=False) profile_image_url = Column(Text) profile_banner_image_url = Column(Text, nullable=True) @@ -56,6 +55,7 @@ class User(Base): date_of_birth = Column(Date, nullable=True) timezone = Column(String, nullable=True) + presence_state = Column(String, nullable=True) status_emoji = Column(String, nullable=True) status_message = Column(Text, nullable=True) status_expires_at = Column(BigInteger, nullable=True) @@ -78,7 +78,6 @@ class UserModel(BaseModel): role: str = "pending" name: str - is_active: bool = False profile_image_url: str profile_banner_image_url: Optional[str] = None @@ -88,6 +87,7 @@ class UserModel(BaseModel): date_of_birth: Optional[datetime.date] = None timezone: Optional[str] = None + presence_state: Optional[str] = None status_emoji: Optional[str] = None status_message: Optional[str] = None status_expires_at: Optional[int] = None @@ -176,7 +176,7 @@ class UserIdNameResponse(BaseModel): class UserIdNameStatusResponse(BaseModel): id: str name: str - is_active: bool + is_active: bool = False class UserInfoListResponse(BaseModel): @@ -636,5 +636,23 @@ class UsersTable: else: return None + def get_active_user_count(self) -> int: + with get_db() as db: + # Consider user active if last_active_at within the last 3 minutes + three_minutes_ago = int(time.time()) - 180 + count = ( + db.query(User).filter(User.last_active_at >= three_minutes_ago).count() + ) + return count + + def is_user_active(self, user_id: str) -> bool: + with get_db() as db: + user = db.query(User).filter_by(id=user_id).first() + if user and user.last_active_at: + # Consider user active if last_active_at within the last 3 minutes + three_minutes_ago = int(time.time()) - 180 + return user.last_active_at >= three_minutes_ago + return False + Users = UsersTable()