from dataclasses import dataclass from campaigns.assets.services import AssetService from campaigns.connectors.db import Database, session_context from campaigns.connectors.facebook.base import FacebookClient from campaigns.connectors.facebook.enums import AdVideoStatus from campaigns.core.handler import Handler from campaigns.meta.errors import MetaErrors from campaigns.meta.exceptions import CampaignAdVideoDoesNotExist from campaigns.meta.models import CampaignVideo from campaigns.meta.repositories import CampaignVideoRepository from campaigns.meta.services import CampaignVideoService from campaigns.utils.image import get_image_content_or_none @dataclass(frozen=True) class RefreshCampaignAdVideoRequest: video_id: str @dataclass class RefreshCampaignAdVideoHandler( Handler[RefreshCampaignAdVideoRequest, CampaignVideo], ): db: Database facebook_client: FacebookClient campaign_video_repository: CampaignVideoRepository campaign_video_service: CampaignVideoService asset_service: AssetService @session_context(in_transaction=True) async def handle(self, request: RefreshCampaignAdVideoRequest) -> CampaignVideo: video = await self.campaign_video_service.get_video(request.video_id) if not video.external_id: raise CampaignAdVideoDoesNotExist ad_video = await self.facebook_client.get_ad_video(video.external_id) video.external_status = ad_video.status.video_status video.is_valid = ad_video.is_valid if not ad_video.is_valid: video.add_error( actual=ad_video.status.video_status, expected=[AdVideoStatus.READY], code=MetaErrors.video_invalid_ad_video.code, ) if ad_video.thumbnail_url and not video.asset.thumbnail_key: thumbnail_content = await get_image_content_or_none( target=ad_video.thumbnail_url ) if thumbnail_content: video.asset = await self.asset_service.save_asset_thumbnail( video.asset, content=thumbnail_content, content_type="image/jpg", extension=".jpg", ) self.campaign_video_repository.add(video) return video