from dataclasses import dataclass from campaigns.assets.dtos import AssetUploadCredentials from campaigns.assets.services import AssetService from campaigns.connectors.facebook.base import FacebookClient from campaigns.meta.enums import AssetPositionGroup from campaigns.meta.exceptions import CampaignVideoDoesNotExist from campaigns.meta.models import Campaign, CampaignVideo from campaigns.meta.repositories import CampaignVideoRepository @dataclass class CampaignVideoService: facebook_client: FacebookClient campaign_video_repository: CampaignVideoRepository asset_service: AssetService async def create_campaign_video( self, campaign: Campaign, *, filename: str, position_group: AssetPositionGroup, ) -> tuple[CampaignVideo, AssetUploadCredentials]: asset, credentials = await self.asset_service.create_asset_with_credentials( filename ) video = CampaignVideo() video.campaign_id = campaign.id video.asset_id = asset.id video.position_group = position_group self.campaign_video_repository.add(video) credentials.upload_metadata.update( { "meta_campaign_id": video.campaign_id, "meta_campaign_video_id": video.id, "meta_campaign_video_position_group": video.position_group, } ) return video, credentials async def get_video(self, video_id: str) -> CampaignVideo: video = await self.campaign_video_repository.get(video_id) if not video: raise CampaignVideoDoesNotExist return video async def delete_video(self, video: CampaignVideo) -> None: await self.asset_service.delete_asset(video.asset) if video.external_id: await self.facebook_client.delete_ad_video(video.external_id) await self.campaign_video_repository.delete(video) return None