import logging from dataclasses import dataclass from anydi import singleton from fansifter_common.auth.identity import Identity from fansifter_common.utils import timezone from dmp.adapters.db import ReportingDB from dmp.audiences.enums import AudienceTarget from dmp.audiences.exceptions import AudienceTargetNotSupportedError from dmp.audiences.models import Audience from dmp.audiences.repositories import AudienceEmailFanRepository from dmp.audiences.services import AudienceService from dmp.config import Settings from dmp.rosters.services import GlobalFanDataAccessService logger = logging.getLogger(__name__) @dataclass(kw_only=True) class UpsertAudienceFansRequest: audience_id: str @singleton class UpsertAudienceFansHandler: def __init__( self, db: ReportingDB, audience_service: AudienceService, global_fandata_access_service: GlobalFanDataAccessService, audience_email_repository: AudienceEmailFanRepository, settings: Settings, ) -> None: self.db = db self.audience_service = audience_service self.global_fandata_access_service = global_fandata_access_service self.audience_email_repository = audience_email_repository self.settings = settings def handle(self, request: UpsertAudienceFansRequest) -> int: with self.db.transaction(): audience = self.audience_service.get_audience(request.audience_id) if audience.target not in (AudienceTarget.TEXT, AudienceTarget.EMAIL): raise AudienceTargetNotSupportedError logger.info( "Upserting audience fans.", extra={ "audience_id": audience.id, "target": audience.target, "audience_email_to_fansifter_only": ( self.settings.audience_email_to_fansifter_only ), }, ) # In non-production environments, save email audiences only to Fansifter. # Skip this when running in production. if ( audience.target == AudienceTarget.EMAIL and self.settings.audience_email_to_fansifter_only ): return self.save_fansifter_email_audience(audience) global_fandata_list_enabled = ( self.global_fandata_access_service.is_enabled_for_any_vendor( vendor_ids=[audience.vendor_id], ) ) fan_count = self.audience_service.upsert_audience_fans( audience, identity=Identity( id=audience.updated_by, brand="ignore", is_internal_employee=False, ), is_global=global_fandata_list_enabled, ) audience.fan_count = fan_count audience.refreshed_at = timezone.now() self.audience_service.save_audience(audience) return fan_count def save_fansifter_email_audience(self, audience: Audience) -> int: self.audience_email_repository.delete_by_audience_id(audience.id) fan_count = self.audience_email_repository.insert_bulk_fansifter_only( audience_id=audience.id ) audience.fan_count = fan_count audience.refreshed_at = timezone.now() self.audience_service.save_audience(audience) return fan_count