mirror of
https://github.com/flibusta-apps/users_settings_server.git
synced 2025-12-06 14:45:38 +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
|
import ormar
|
||||||
|
|
||||||
from core.db import metadata, database
|
from core.db import metadata, database
|
||||||
@@ -30,3 +32,15 @@ class User(ormar.Model):
|
|||||||
source: str = ormar.String(max_length=32) # type: ignore
|
source: str = ormar.String(max_length=32) # type: ignore
|
||||||
|
|
||||||
allowed_langs = ormar.ManyToMany(Language)
|
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):
|
class UserDetail(UserBase):
|
||||||
|
id: int
|
||||||
allowed_langs: list[LanguageDetail]
|
allowed_langs: list[LanguageDetail]
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ class UsersDataManager:
|
|||||||
@classmethod
|
@classmethod
|
||||||
async def get_user(
|
async def get_user(
|
||||||
cls, user_id: int, redis: aioredis.Redis
|
cls, user_id: int, redis: aioredis.Redis
|
||||||
) -> Optional[UserDetail]:
|
) -> Optional[UserDetail | User]:
|
||||||
if cached_user := await cls._get_user_from_cache(user_id, redis):
|
if cached_user := await cls._get_user_from_cache(user_id, redis):
|
||||||
return cached_user
|
return cached_user
|
||||||
|
|
||||||
@@ -60,7 +60,7 @@ class UsersDataManager:
|
|||||||
return None
|
return None
|
||||||
|
|
||||||
await cls._cache_user(user, redis)
|
await cls._cache_user(user, redis)
|
||||||
return user # type: ignore
|
return user
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def _is_has_data_to_update(cls, new_user: UserUpdate) -> bool:
|
def _is_has_data_to_update(cls, new_user: UserUpdate) -> bool:
|
||||||
@@ -106,7 +106,7 @@ class UsersDataManager:
|
|||||||
@classmethod
|
@classmethod
|
||||||
async def create_or_update_user(
|
async def create_or_update_user(
|
||||||
cls, data: UserCreateOrUpdate, redis: aioredis.Redis
|
cls, data: UserCreateOrUpdate, redis: aioredis.Redis
|
||||||
):
|
) -> User | UserDetail:
|
||||||
user = await cls.get_user(data.user_id, redis)
|
user = await cls.get_user(data.user_id, redis)
|
||||||
|
|
||||||
if user is None:
|
if user is None:
|
||||||
@@ -121,7 +121,9 @@ class UsersDataManager:
|
|||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def _is_need_update(
|
def _is_need_update(
|
||||||
cls, old_user: UserDetail, new_user: Union[UserUpdate, UserCreateOrUpdate]
|
cls,
|
||||||
|
old_user: UserDetail | User,
|
||||||
|
new_user: Union[UserUpdate, UserCreateOrUpdate],
|
||||||
) -> bool:
|
) -> bool:
|
||||||
old_data = old_user.dict()
|
old_data = old_user.dict()
|
||||||
new_data = new_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 import APIRouter, HTTPException, status, Depends, Request
|
||||||
|
|
||||||
from fastapi_pagination import Page, Params
|
from fastapi_pagination import Page, Params
|
||||||
@@ -5,7 +7,7 @@ from fastapi_pagination.ext.ormar import paginate
|
|||||||
from redis import asyncio as aioredis
|
from redis import asyncio as aioredis
|
||||||
|
|
||||||
from app.depends import check_token
|
from app.depends import check_token
|
||||||
from app.models import User, Language
|
from app.models import User, Language, UserActivity
|
||||||
from app.serializers import (
|
from app.serializers import (
|
||||||
UserCreateOrUpdate,
|
UserCreateOrUpdate,
|
||||||
UserUpdate,
|
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)
|
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(
|
languages_router = APIRouter(
|
||||||
prefix="/languages", tags=["languages"], dependencies=[Depends(check_token)]
|
prefix="/languages", tags=["languages"], dependencies=[Depends(check_token)]
|
||||||
)
|
)
|
||||||
|
|||||||
Reference in New Issue
Block a user