mirror of
https://github.com/flibusta-apps/users_settings_server.git
synced 2025-12-06 06:35:39 +01:00
Add user activity
This commit is contained in:
40
src/app/alembic/versions/64fe2045bf28_.py
Normal file
40
src/app/alembic/versions/64fe2045bf28_.py
Normal file
@@ -0,0 +1,40 @@
|
||||
"""empty message
|
||||
|
||||
Revision ID: 64fe2045bf28
|
||||
Revises: 750640043cd4
|
||||
Create Date: 2023-01-05 18:28:05.296720
|
||||
|
||||
"""
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision = "64fe2045bf28"
|
||||
down_revision = "750640043cd4"
|
||||
branch_labels = None
|
||||
depends_on = None
|
||||
|
||||
|
||||
def upgrade():
|
||||
# ### commands auto generated by Alembic - please adjust! ###
|
||||
op.create_table(
|
||||
"user_activity",
|
||||
sa.Column("id", sa.Integer(), nullable=False),
|
||||
sa.Column("user", sa.Integer(), nullable=False),
|
||||
sa.Column("updated", sa.DateTime(), nullable=False),
|
||||
sa.ForeignKeyConstraint(
|
||||
["user"],
|
||||
["user_settings.id"],
|
||||
name="fk_user_activity_user_settings_id_user",
|
||||
),
|
||||
sa.PrimaryKeyConstraint("id"),
|
||||
sa.UniqueConstraint("user"),
|
||||
)
|
||||
# ### end Alembic commands ###
|
||||
|
||||
|
||||
def downgrade():
|
||||
# ### commands auto generated by Alembic - please adjust! ###
|
||||
op.drop_table("user_activity")
|
||||
# ### end Alembic commands ###
|
||||
@@ -1,3 +1,5 @@
|
||||
from datetime import datetime
|
||||
|
||||
import ormar
|
||||
|
||||
from core.db import metadata, database
|
||||
@@ -30,3 +32,15 @@ class User(ormar.Model):
|
||||
source: str = ormar.String(max_length=32) # type: ignore
|
||||
|
||||
allowed_langs = ormar.ManyToMany(Language)
|
||||
|
||||
|
||||
class UserActivity(ormar.Model):
|
||||
class Meta(BaseMeta):
|
||||
tablename = "user_activity"
|
||||
|
||||
id: int = ormar.Integer(primary_key=True) # type: ignore
|
||||
|
||||
user: User = ormar.ForeignKey(
|
||||
User, nullable=False, unique=True, related_name="last_activity"
|
||||
)
|
||||
updated: datetime = ormar.DateTime(timezone=False) # type: ignore
|
||||
|
||||
@@ -33,4 +33,5 @@ class UserUpdate(BaseModel):
|
||||
|
||||
|
||||
class UserDetail(UserBase):
|
||||
id: int
|
||||
allowed_langs: list[LanguageDetail]
|
||||
|
||||
@@ -50,7 +50,7 @@ class UsersDataManager:
|
||||
@classmethod
|
||||
async def get_user(
|
||||
cls, user_id: int, redis: aioredis.Redis
|
||||
) -> Optional[UserDetail]:
|
||||
) -> Optional[UserDetail | User]:
|
||||
if cached_user := await cls._get_user_from_cache(user_id, redis):
|
||||
return cached_user
|
||||
|
||||
@@ -60,7 +60,7 @@ class UsersDataManager:
|
||||
return None
|
||||
|
||||
await cls._cache_user(user, redis)
|
||||
return user # type: ignore
|
||||
return user
|
||||
|
||||
@classmethod
|
||||
def _is_has_data_to_update(cls, new_user: UserUpdate) -> bool:
|
||||
@@ -106,7 +106,7 @@ class UsersDataManager:
|
||||
@classmethod
|
||||
async def create_or_update_user(
|
||||
cls, data: UserCreateOrUpdate, redis: aioredis.Redis
|
||||
):
|
||||
) -> User | UserDetail:
|
||||
user = await cls.get_user(data.user_id, redis)
|
||||
|
||||
if user is None:
|
||||
@@ -121,7 +121,9 @@ class UsersDataManager:
|
||||
|
||||
@classmethod
|
||||
def _is_need_update(
|
||||
cls, old_user: UserDetail, new_user: Union[UserUpdate, UserCreateOrUpdate]
|
||||
cls,
|
||||
old_user: UserDetail | User,
|
||||
new_user: Union[UserUpdate, UserCreateOrUpdate],
|
||||
) -> bool:
|
||||
old_data = old_user.dict()
|
||||
new_data = new_user.dict()
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
from datetime import datetime
|
||||
|
||||
from fastapi import APIRouter, HTTPException, status, Depends, Request
|
||||
|
||||
from fastapi_pagination import Page, Params
|
||||
@@ -5,7 +7,7 @@ from fastapi_pagination.ext.ormar import paginate
|
||||
from redis import asyncio as aioredis
|
||||
|
||||
from app.depends import check_token
|
||||
from app.models import User, Language
|
||||
from app.models import User, Language, UserActivity
|
||||
from app.serializers import (
|
||||
UserCreateOrUpdate,
|
||||
UserUpdate,
|
||||
@@ -49,6 +51,23 @@ async def update_user(request: Request, user_id: int, data: UserUpdate):
|
||||
return await UsersDataManager.update_user(user_id, data, redis)
|
||||
|
||||
|
||||
@users_router.post("/{user_id}/update_activity")
|
||||
async def update_activity(
|
||||
request: Request, user_id: int, data: UserCreateOrUpdate
|
||||
) -> None:
|
||||
redis: aioredis.Redis = request.app.state.redis
|
||||
user = await UsersDataManager.create_or_update_user(data, redis)
|
||||
|
||||
activity = await UserActivity.objects.get_or_none(user__user_id=user_id)
|
||||
|
||||
if activity is None:
|
||||
await UserActivity.objects.create(user=user.id, updated=datetime.now())
|
||||
return
|
||||
|
||||
activity.updated = datetime.now()
|
||||
await activity.update()
|
||||
|
||||
|
||||
languages_router = APIRouter(
|
||||
prefix="/languages", tags=["languages"], dependencies=[Depends(check_token)]
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user