import json from db import db from models.territories import Territory from models.marketing_accounts import MarketingAccount, MarketingAccountSource from typing import List, Optional from psycopg2.extras import NumericRange from utils.snowflake.tiktok_data.models import TikTokCampaignsQueryResult from constants.labels_constants import TEST_UK_LABEL_ID, TEST_US_LABEL_ID class TikTokImporterUtils: def marketing_accounts(self) -> List[str]: accounts = ( db.session.query(MarketingAccount.external_id) .filter( MarketingAccount.source == MarketingAccountSource.TIKTOK.value, MarketingAccount.label_id.notin_([TEST_UK_LABEL_ID, TEST_US_LABEL_ID]) ) .all() ) return [item[0] for item in accounts] def map_artists_external_ids(self, item: TikTokCampaignsQueryResult) -> List[str]: artists = [] if item.artists: artists = json.loads(item.artists) ids = [artist.get("member_id", artist["artist_id"]) for artist in artists if artist.get("artist_id")] return [f"GRAS_{id_}" for id_ in ids] class TikTokWorkerUtils: global_country_code = "GLBL" global_territory_id = 0 default_campaign_type = "Social Ads" platform_id = 34 source_name = "tiktok" default_genders = [1, 2, 3] all_ages = 0, 100 def build_gender_ids(self, genders: List[str]) -> Optional[List[int]]: if not genders: return None return list(map(self.__map_gender_from, genders)) @staticmethod def __map_gender_from(gender_string: str) -> (int, int): if gender_string == "MALE": return 1 if gender_string == "FEMALE": return 2 else: return 3 @staticmethod def remove_none_string_from_list(lst: List): res = [] for el in lst: if isinstance(el, str) and el.lower() != "none": res.append(el) return res def map_territories(self, country_codes: List[str]): if country_codes is None: return [self.global_territory_id] country_codes = self.remove_none_string_from_list(country_codes) if not country_codes: return [self.global_territory_id] territory_ids = db.session.query(Territory.id).filter(Territory.code.in_(country_codes)).all() if not territory_ids: territory_ids = [self.global_territory_id] return territory_ids @staticmethod def build_objective(objective: Optional[str]) -> int: objective_map = { "TRAFFIC": 16, # Traffic "REACH": 13, # Reach "VIDEO_VIEWS": 17, # Video Views "ENGAGEMENT": 14, # Engagement "CONVERSIONS": 3, # Conversions "RF_REACH": 13, # Reach? "RF_VIDEO_VIEW": 17, # Video Views ? "RF_TRAFFIC": 16, # Traffic ? "APP_INSTALL": 1 # App Promotion } return objective_map.get(objective, 1) def build_age_range(self, age_ranges: List[str]) -> NumericRange: age_ranges = self.remove_none_string_from_list(age_ranges) if not age_ranges: return NumericRange(self.all_ages[0], self.all_ages[1], "[]") years = [] for range_years in age_ranges: values = range_years.lstrip("AGE_").split("_") years.extend([int(val) for val in values if val.isdigit()]) return NumericRange(min(years), max(years), "[]")