38 lines
1.5 KiB
Python
38 lines
1.5 KiB
Python
from __future__ import annotations
|
|
|
|
from botocore.exceptions import ClientError
|
|
|
|
from src.application.abstractions import IUnitOfWork
|
|
from src.application.contracts import ICache, ILogger, IS3
|
|
from src.application.domain.entities import UserEntity
|
|
from src.infrastructure.database.decorators import transactional
|
|
|
|
|
|
class DeleteAvatarCommand:
|
|
def __init__(self, unit_of_work: IUnitOfWork, logger: ILogger, cache: ICache, s3: IS3):
|
|
self._unit_of_work = unit_of_work
|
|
self._logger = logger
|
|
self._cache = cache
|
|
self._s3 = s3
|
|
|
|
async def __call__(self, user_id: str) -> UserEntity:
|
|
prior = await self._unit_of_work.user_repository.get_user_by_id(user_id)
|
|
link = prior.avatar_link
|
|
if link:
|
|
key = self._s3.object_key_from_public_url(link)
|
|
if key:
|
|
try:
|
|
await self._s3.delete_object(key=key)
|
|
except ClientError as exc:
|
|
code = exc.response.get('Error', {}).get('Code', '')
|
|
if code not in ('NoSuchKey', '404'):
|
|
self._logger.warning(f'S3 delete avatar failed user_id={user_id} code={code}: {exc}')
|
|
user = await self._clear_avatar_link(user_id)
|
|
await self._cache.set_user(user_id, user)
|
|
self._logger.info(f'Avatar removed user_id={user_id}')
|
|
return user
|
|
|
|
@transactional
|
|
async def _clear_avatar_link(self, user_id: str) -> UserEntity:
|
|
return await self._unit_of_work.user_repository.set_avatar_link(user_id, None)
|