feat(user): support online & last_visit
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
from datetime import UTC, datetime
|
||||
from typing import TYPE_CHECKING, NotRequired, TypedDict
|
||||
|
||||
from app.dependencies.database import get_redis
|
||||
from app.models.model import UTCBaseModel
|
||||
from app.models.score import GameMode
|
||||
from app.models.user import Country, Page, RankHistory
|
||||
@@ -157,7 +158,7 @@ class User(AsyncAttrs, UserBase, table=True):
|
||||
|
||||
class UserResp(UserBase):
|
||||
id: int | None = None
|
||||
is_online: bool = True # TODO
|
||||
is_online: bool = False
|
||||
groups: list = [] # TODO
|
||||
country: Country = Field(default_factory=lambda: Country(code="CN", name="China"))
|
||||
favourite_beatmapset_count: int = 0 # TODO
|
||||
@@ -225,6 +226,8 @@ class UserResp(UserBase):
|
||||
.limit(200)
|
||||
)
|
||||
).one()
|
||||
redis = get_redis()
|
||||
u.is_online = await redis.exists(f"metadata:online:{obj.id}")
|
||||
u.cover_url = (
|
||||
obj.cover.get(
|
||||
"url", "https://assets.ppy.sh/user-profile-covers/default.jpeg"
|
||||
|
||||
@@ -482,7 +482,6 @@ async def process_user(
|
||||
previous_score_best_mod = await get_user_best_score_with_mod_in_beatmap(
|
||||
session, score.beatmap_id, user.id, mod_for_save, score.gamemode
|
||||
)
|
||||
print(previous_score_best, previous_score_best_mod)
|
||||
add_to_db = False
|
||||
mouthly_playcount = (
|
||||
await session.exec(
|
||||
|
||||
@@ -22,7 +22,7 @@ class OsuDotDirectFetcher(BaseFetcher):
|
||||
async def get_or_fetch_beatmap_raw(
|
||||
self, redis: redis.Redis, beatmap_id: int
|
||||
) -> str:
|
||||
if redis.exists(f"beatmap:{beatmap_id}:raw"):
|
||||
if await redis.exists(f"beatmap:{beatmap_id}:raw"):
|
||||
return await redis.get(f"beatmap:{beatmap_id}:raw") # pyright: ignore[reportReturnType]
|
||||
raw = await self.get_beatmap_raw(beatmap_id)
|
||||
await redis.set(f"beatmap:{beatmap_id}:raw", raw, ex=60 * 60 * 24)
|
||||
|
||||
@@ -2,10 +2,12 @@ from __future__ import annotations
|
||||
|
||||
import asyncio
|
||||
from collections.abc import Coroutine
|
||||
from datetime import UTC, datetime
|
||||
from typing import override
|
||||
|
||||
from app.database import Relationship, RelationshipType
|
||||
from app.dependencies.database import engine
|
||||
from app.database.lazer_user import User
|
||||
from app.dependencies.database import engine, get_redis
|
||||
from app.models.metadata_hub import MetadataClientState, OnlineStatus, UserActivity
|
||||
|
||||
from .hub import Client, Hub
|
||||
@@ -54,6 +56,18 @@ class MetadataHub(Hub[MetadataClientState]):
|
||||
async def _clean_state(self, state: MetadataClientState) -> None:
|
||||
if state.pushable:
|
||||
await asyncio.gather(*self.broadcast_tasks(int(state.connection_id), None))
|
||||
redis = get_redis()
|
||||
if await redis.exists(f"metadata:online:{state.connection_id}"):
|
||||
await redis.delete(f"metadata:online:{state.connection_id}")
|
||||
async with AsyncSession(engine) as session:
|
||||
async with session.begin():
|
||||
user = (
|
||||
await session.exec(
|
||||
select(User).where(User.id == int(state.connection_id))
|
||||
)
|
||||
).one()
|
||||
user.last_visit = datetime.now(UTC)
|
||||
await session.commit()
|
||||
|
||||
@override
|
||||
def create_state(self, client: Client) -> MetadataClientState:
|
||||
@@ -93,6 +107,8 @@ class MetadataHub(Hub[MetadataClientState]):
|
||||
)
|
||||
)
|
||||
await asyncio.gather(*tasks)
|
||||
redis = get_redis()
|
||||
await redis.set(f"metadata:online:{user_id}", "")
|
||||
|
||||
async def UpdateStatus(self, client: Client, status: int) -> None:
|
||||
status_ = OnlineStatus(status)
|
||||
|
||||
Reference in New Issue
Block a user