from db import db from workers.base_worker import BaseWorker from utils.snowflake.facebook_data.models import FacebookAdSetModel from typing import List from models import Territory from campaigns.repositories.campaigns_repository import CampaignsRepository from campaigns.services.campaigns_history_service import CampaignHistoryService from utils.reporting.worker_logger import WorkerLogger from utils.snowflake.facebook_data.utils import FacebookWorkerUtils from models.campaign_ad import CampaignAd, CampaignAdLink, CampaignAdTerritory class FacebookAdSetsWorker(BaseWorker): campaigns_repository: CampaignsRepository = CampaignsRepository() history_service: CampaignHistoryService = CampaignHistoryService() utils: FacebookWorkerUtils = FacebookWorkerUtils() logger: WorkerLogger = WorkerLogger() def execute(self, ad_sets: List[FacebookAdSetModel]): mapped_campaign_ads = [] for ad_set in ad_sets: fb_campaign = self.campaigns_repository.get_campaign_by_external_id(ad_set.campaign_id) if not fb_campaign: continue ad_set_campaign = ( db.session.query(CampaignAd).filter(CampaignAd.external_id == str(ad_set.id)).one_or_none() ) if not ad_set_campaign: ad_set_campaign = CampaignAd() ad_set_campaign.campaign_id = fb_campaign.id ad_set_campaign.external_id = ad_set.id ad_set_campaign.name = ad_set.name ad_set_campaign.start_date = ad_set.start_date ad_set_campaign.end_date = ad_set.end_date ad_set_campaign.planned_budget = ad_set.budget ad_set_campaign.budget_spend = ad_set.spend ad_set_campaign.age_range = self.utils.build_age_range(ad_set.ages) ad_set_campaign.genders = self.campaigns_repository.get_campaign_genders_by_ids( self.utils.build_gender_ids(ad_set.genders) or self.utils.default_genders ) ad_set_campaign.objective_id = self.utils.build_objective(ad_set.objective) ad_set_campaign.platform = self.__map_platforms(ad_set.platforms) self.__update_campaign_ad_link(ad_set_campaign, self.utils.build_campaign_links(ad_set.links)) self.__update_campaign_ad_territories(ad_set_campaign, self.utils.map_territories(ad_set.country_codes)) db.session.add(ad_set_campaign) db.session.flush() db.session.refresh(ad_set_campaign) mapped_campaign_ads.append(ad_set_campaign) db.session.commit() CampaignAd.index_models(mapped_campaign_ads) db.session.close() def __update_campaign_ad_link(self, campaign_ad: CampaignAd, links: List[str]): if campaign_ad.id: db.session.execute(CampaignAdLink.__table__.delete().where(CampaignAdLink.campaign_ad_id == campaign_ad.id)) campaign_ad.links = [CampaignAdLink(link=link) for link in links] def __update_campaign_ad_territories(self, campaign_ad: CampaignAd, territories: List[int]): if campaign_ad.id: db.session.execute( CampaignAdTerritory.__table__.delete().where(CampaignAdTerritory.campaign_ad_id == campaign_ad.id) ) campaign_ad.territories = [CampaignAdTerritory(territory_id=id) for id in territories] def __map_platforms(self, types): mapping = { "facebook": "Facebook", "instagram": "Instagram", "audience_network": "Audience Network", "messenger": "Messenger", } if types is None or len(types) == 0: return mapping.get("facebook") if "all" in types or "All (Automated App Ads)" in types: types = mapping.keys() mapped_types = [mapping.get(c_type) for c_type in sorted(types)] mapped_types = [item for item in mapped_types if item] # Remove None values if any return ", ".join(mapped_types) def map_territories(self, country_codes: List[str]): territory_ids = db.session.query(Territory.id).filter(Territory.code.in_(country_codes)).all() if len(territory_ids) == 0: territory_ids = [0] return territory_ids