from datetime import datetime from typing import Any import sqlalchemy as sa from audience_common import datetimeutc from sqlalchemy.dialects.postgresql import ARRAY from sqlalchemy.orm import Mapped, mapped_column from campaigns.connectors.db.orm import Base from campaigns.connectors.facebook.models import ( TargetingCity, TargetingGeolocations, TargetingInterestShort, TargetingRegion, ) from campaigns.meta.enums import AudienceGender, AudienceGenderSelector from campaigns.utils.uuid import uuid_string class TargetingAudience(Base): __tablename__ = "meta_targeting_audience" id: Mapped[str] = mapped_column(primary_key=True, default=uuid_string) locations: Mapped[list[dict[str, Any]]] = mapped_column(sa.JSON, default=list) age_min: Mapped[int] = mapped_column(sa.SmallInteger) age_max: Mapped[int] = mapped_column(sa.SmallInteger) genders: Mapped[list[AudienceGender]] = mapped_column(ARRAY(sa.Text), default=list) interests: Mapped[list[dict[str, Any]]] = mapped_column(sa.JSON, default=list) created_at: Mapped[datetime] = mapped_column(default=datetimeutc.now) updated_at: Mapped[datetime] = mapped_column( default=datetimeutc.now, onupdate=datetimeutc.now, ) @property def gender(self) -> AudienceGenderSelector: return ( AudienceGenderSelector.from_list(self.genders) or AudienceGenderSelector.ALL ) @property def api_interests(self) -> list[TargetingInterestShort]: api_interests = [] for interest in self.interests: id = interest.get("id", None) name = interest.get("name", None) if id and name: api_interests.append(TargetingInterestShort(id=str(id), name=str(name))) return api_interests @property def api_geo_locations(self) -> TargetingGeolocations: cities = [] regions = [] countries = [] for location in self.locations: type = location.get("type", None) key = location.get("key", None) if not key: continue if type == "city": cities.append(TargetingCity(key=key)) if type == "region": regions.append(TargetingRegion(key=key)) if type == "country": countries.append(key) return TargetingGeolocations( countries=countries if countries else None, regions=regions if regions else None, cities=cities if cities else None, )