бэк несколько медиа
This commit is contained in:
@@ -31,37 +31,12 @@ async def update_creative(
|
||||
creative.name = input.name
|
||||
if input.text:
|
||||
creative.text = domain.replace_invite_link_with_tag(input.text)
|
||||
if input.media_data is not None:
|
||||
domain.validate_media_size(input.media_data)
|
||||
|
||||
# Удаляем старое медиа из S3 в фоне
|
||||
old_media_key = creative.media_s3_key
|
||||
if old_media_key:
|
||||
|
||||
async def delete_old_media() -> None:
|
||||
try:
|
||||
await self.s3.delete(old_media_key)
|
||||
log.info('Deleted old creative media from S3: %s', old_media_key)
|
||||
except Exception as e:
|
||||
log.warning('Failed to delete old creative media from S3: %s', e)
|
||||
|
||||
asyncio.create_task(delete_old_media())
|
||||
|
||||
# Загружаем новое медиа в S3
|
||||
new_media_data = input.media_data
|
||||
if new_media_data:
|
||||
file_id = uuid.uuid4()
|
||||
new_media_key = f'creatives/{workspace_id}/{file_id}'
|
||||
content_type = _get_content_type(input.media_type)
|
||||
await self.s3.upload(new_media_key, new_media_data, content_type)
|
||||
log.info('Uploaded new creative media to S3: %s', new_media_key)
|
||||
creative.media_s3_key = new_media_key
|
||||
else:
|
||||
creative.media_s3_key = None
|
||||
if input.media_type is not None:
|
||||
creative.media_type = input.media_type
|
||||
if input.media_file_id is not None:
|
||||
creative.media_file_id = input.media_file_id
|
||||
media_items: list[dto.CreativeMediaInput] | None = None
|
||||
if input.media_items is not None:
|
||||
media_items = input.media_items
|
||||
domain.validate_media_items([item.media_type for item in media_items])
|
||||
for item in media_items:
|
||||
domain.validate_media_size(item.media_data)
|
||||
if input.buttons is not None:
|
||||
creative.buttons = [button.model_dump() for button in input.buttons]
|
||||
if input.status:
|
||||
@@ -69,14 +44,17 @@ async def update_creative(
|
||||
|
||||
await self.database.update_creative(creative)
|
||||
|
||||
if media_items is not None:
|
||||
await _replace_media_items(self, creative.id, workspace_id, media_items)
|
||||
|
||||
placements_count = await self.database.count_placement_posts_by_creative(creative.id)
|
||||
creative_media = await _get_media_items(creative)
|
||||
|
||||
return dto.CreativeOutput(
|
||||
id=creative.id,
|
||||
name=creative.name,
|
||||
text=creative.text,
|
||||
media_type=creative.media_type,
|
||||
media_file_id=creative.media_file_id,
|
||||
media_items=creative_media,
|
||||
buttons=creative.buttons,
|
||||
project_id=creative.project_id,
|
||||
project_channel_title=creative.project.channel.title,
|
||||
@@ -96,3 +74,59 @@ def _get_content_type(media_type: str | None) -> str:
|
||||
'animation': 'image/gif',
|
||||
}
|
||||
return mapping.get(media_type, 'application/octet-stream')
|
||||
|
||||
|
||||
async def _replace_media_items(
|
||||
self: 'Usecase',
|
||||
creative_id: uuid.UUID,
|
||||
workspace_id: uuid.UUID,
|
||||
media_items: list[dto.CreativeMediaInput],
|
||||
) -> None:
|
||||
existing_items = await domain.CreativeMedia.filter(creative_id=creative_id).all()
|
||||
if existing_items:
|
||||
old_media_keys = [item.media_s3_key for item in existing_items if item.media_s3_key]
|
||||
await domain.CreativeMedia.filter(creative_id=creative_id).delete()
|
||||
|
||||
if old_media_keys:
|
||||
|
||||
async def delete_old_media() -> None:
|
||||
for key in old_media_keys:
|
||||
try:
|
||||
await self.s3.delete(key)
|
||||
log.info('Deleted old creative media from S3: %s', key)
|
||||
except Exception as e:
|
||||
log.warning('Failed to delete old creative media from S3: %s', e)
|
||||
|
||||
asyncio.create_task(delete_old_media())
|
||||
|
||||
for position, item in enumerate(media_items):
|
||||
media_s3_key: str | None = None
|
||||
if item.media_data:
|
||||
file_id = uuid.uuid4()
|
||||
media_s3_key = f'creatives/{workspace_id}/{file_id}'
|
||||
content_type = _get_content_type(item.media_type)
|
||||
await self.s3.upload(media_s3_key, item.media_data, content_type)
|
||||
log.info('Uploaded new creative media to S3: %s', media_s3_key)
|
||||
await domain.CreativeMedia.create(
|
||||
creative_id=creative_id,
|
||||
media_type=item.media_type,
|
||||
media_file_id=item.media_file_id,
|
||||
media_s3_key=media_s3_key,
|
||||
position=position,
|
||||
)
|
||||
|
||||
|
||||
async def _get_media_items(creative: domain.Creative) -> list[dto.CreativeMediaItem]:
|
||||
media_rel = creative.media_items
|
||||
if hasattr(media_rel, 'all'):
|
||||
items = await media_rel.all().order_by('position')
|
||||
else:
|
||||
items = sorted(media_rel, key=lambda item: item.position)
|
||||
return [
|
||||
dto.CreativeMediaItem(
|
||||
media_type=item.media_type,
|
||||
media_file_id=item.media_file_id,
|
||||
position=item.position,
|
||||
)
|
||||
for item in items
|
||||
]
|
||||
|
||||
Reference in New Issue
Block a user