103 lines
3.1 KiB
Python
103 lines
3.1 KiB
Python
from collections.abc import Mapping
|
|
from typing import Optional
|
|
|
|
from app.dao.parent import ParentDAO
|
|
from app.service.avatar_storage import AvatarStorageService
|
|
from app.settings import settings
|
|
|
|
|
|
class ParentService:
|
|
def __init__(self, db, avatar_storage: AvatarStorageService | None = None):
|
|
self.dao = ParentDAO(db)
|
|
self.avatar_storage = avatar_storage or AvatarStorageService()
|
|
|
|
def create(
|
|
self,
|
|
openid: str,
|
|
unionid: Optional[str] = None,
|
|
nickname: Optional[str] = None,
|
|
avatar_url: Optional[str] = None,
|
|
) -> Mapping:
|
|
user_id = self.dao.upsert(openid, unionid, nickname, avatar_url)
|
|
return self.get(user_id)
|
|
|
|
def get(self, user_id: int) -> Optional[Mapping]:
|
|
return self._present_parent(self.dao.get_by_id(user_id))
|
|
|
|
def update(
|
|
self,
|
|
user_id: int,
|
|
nickname: Optional[str] = None,
|
|
avatar_url: Optional[str] = None,
|
|
phone: Optional[str] = None,
|
|
) -> Mapping:
|
|
self.dao.update(user_id, nickname, avatar_url, phone)
|
|
return self.get(user_id)
|
|
|
|
def upload_avatar(
|
|
self,
|
|
*,
|
|
user_id: int,
|
|
filename: str | None,
|
|
content_type: str | None,
|
|
content: bytes,
|
|
) -> Optional[Mapping]:
|
|
existing = self.dao.get_by_id(user_id)
|
|
if not existing:
|
|
return None
|
|
|
|
stored = self.avatar_storage.upload_avatar(
|
|
user_id=user_id,
|
|
filename=filename,
|
|
content_type=content_type,
|
|
content=content,
|
|
)
|
|
old_avatar_file_key = existing.get("avatar_file_key")
|
|
|
|
try:
|
|
self.dao.set_avatar_file_key(user_id, stored.file_key)
|
|
except Exception:
|
|
try:
|
|
self.avatar_storage.delete_avatar(stored.file_key)
|
|
except Exception:
|
|
pass
|
|
raise
|
|
|
|
if old_avatar_file_key and old_avatar_file_key != stored.file_key:
|
|
try:
|
|
self.avatar_storage.delete_avatar(old_avatar_file_key)
|
|
except Exception:
|
|
pass
|
|
|
|
return self.get(user_id)
|
|
|
|
def get_avatar_download(self, user_id: int) -> Optional[dict]:
|
|
parent = self.dao.get_by_id(user_id)
|
|
if not parent:
|
|
return None
|
|
|
|
avatar_file_key = parent.get("avatar_file_key")
|
|
if avatar_file_key:
|
|
return {
|
|
"avatar_url": self.avatar_storage.get_avatar_url(avatar_file_key),
|
|
"expires_in": settings.cos_avatar_url_expire_seconds,
|
|
}
|
|
|
|
avatar_url = parent.get("avatar_url")
|
|
if avatar_url:
|
|
return {
|
|
"avatar_url": avatar_url,
|
|
"expires_in": None,
|
|
}
|
|
return None
|
|
|
|
def _present_parent(self, parent: Optional[Mapping]) -> Optional[dict]:
|
|
if not parent:
|
|
return None
|
|
|
|
data = dict(parent)
|
|
avatar_file_key = data.get("avatar_file_key")
|
|
if avatar_file_key:
|
|
data["avatar_url"] = self.avatar_storage.get_avatar_url(avatar_file_key)
|
|
return data
|