from __future__ import annotations import enum class Gender(enum.StrEnum): MALE = "MALE" FEMALE = "FEMALE" PREFER_NOT_TO_ANSWER = "PREFER_NOT_TO_ANSWER" NON_BINARY_OTHER = "NON_BINARY_OTHER" class DigitalServiceProvider(enum.StrEnum): APPLE = "APPLE" SPOTIFY = "SPOTIFY" DEEZER = "DEEZER" YOUTUBE = "YOUTUBE" AMAZON = "AMAZON" class LastEngagement(enum.StrEnum): PAST_WEEK = "PAST_WEEK" PAST_2_WEEKS = "PAST_2_WEEKS" PAST_28_DAYS = "PAST_28_DAYS" PAST_6_MONTHS = "PAST_6_MONTHS" PAST_YEAR = "PAST_YEAR" @property def as_sql_interval(self) -> str: if self == self.PAST_WEEK: return "1 week" elif self == self.PAST_2_WEEKS: return "2 weeks" elif self == self.PAST_28_DAYS: return "28 days" elif self == self.PAST_6_MONTHS: return "6 months" elif self == self.PAST_YEAR: return "1 year" return "" class FanSegment(enum.StrEnum): # Order is dictated by business requirements (artist page) SUPER_FANS = "SUPER_FANS" ENGAGED_FANS = "ENGAGED_FANS" CASUAL_FANS = "CASUAL_FANS" FANS_TO_WIN_BACK = "FANS_TO_WIN_BACK" NEW_FANS = "NEW_FANS" SECONDARY_FANS = "SECONDARY_FANS" UNSEGMENTED_FANS = "UNSEGMENTED_FANS" @classmethod def choices(cls) -> list[FanSegment]: return [ item for item in cls if item not in [FanSegment.SECONDARY_FANS, FanSegment.UNSEGMENTED_FANS] ] @classmethod def audience_choices(cls) -> list[FanSegment]: return [item for item in cls if item != FanSegment.UNSEGMENTED_FANS] # noqa @classmethod def ordered(cls) -> tuple[FanSegment, ...]: return ( cls.UNSEGMENTED_FANS, cls.SECONDARY_FANS, cls.NEW_FANS, cls.FANS_TO_WIN_BACK, cls.CASUAL_FANS, cls.ENGAGED_FANS, cls.SUPER_FANS, ) class AcquisitionChannel(enum.StrEnum): WYNG = "WYNG" FILE_UPLOAD_TOOL = "FILE_UPLOAD_TOOL" SMF_UNCATEGORIZED = "SMF_UNCATEGORIZED" SMF_PLAYLIST_GENERATOR_SPOTIFY_LIBRARY_SCAN = ( "SMF_PLAYLIST_GENERATOR_SPOTIFY_LIBRARY_SCAN" ) SMF_PLAYLIST_GENERATOR_QUIZ = "SMF_PLAYLIST_GENERATOR_QUIZ" SMF_BESPOKE_ACTIVATION = "SMF_BESPOKE_ACTIVATION" SMF_SOCIAL_SIGNUP_FORM_COMBO = "SMF_SOCIAL_SIGNUP_FORM_COMBO" SMF_NEWSLETTER_SIGNUP = "SMF_NEWSLETTER_SIGNUP" SMF_FAN_CARD_ACTIVATION = "SMF_FAN_CARD_ACTIVATION" SMF_GENERAL_PRESAVE = "SMF_GENERAL_PRESAVE" SMF_GIVEAWAY = "SMF_GIVEAWAY" MAKE_THE_LINK = "MAKE_THE_LINK" TUNESPEAK = "TUNESPEAK" SHOPIFY = "SHOPIFY" MIGRATION = "MIGRATION" TICKETING = "TICKETING" FEATURE_FM = "FEATURE_FM" SPOTIFY_SONY_MUSIC_NOW = "SPOTIFY_SONY_MUSIC_NOW" PREVIOUS_MAILING_LIST = "PREVIOUS_MAILING_LIST" SMS_CAMPAIGNS = "SMS_CAMPAIGNS" SEATED_LIST = "SEATED_LIST" BANDSINTOWN_LIST = "BANDSINTOWN_LIST" LINKFIRE = "LINKFIRE" MAESTRO_LIST = "MAESTRO_LIST" WEBSITE = "WEBSITE" PAST_PURCHASERS = "PAST_PURCHASERS" SQWAD = "SQWAD" INTERNAL_SONY_LIST_TRANSFER = "INTERNAL_SONY_LIST_TRANSFER" LEVELLR = "LEVELLR" MEDALLION = "MEDALLION" EVENT_SHOP = "EVENT_SHOP" SONGWHIP_PRE_SAVE = "SONGWHIP_PRE_SAVE" SONGWHIP_EXCLUSIVE_CONTENT = "SONGWHIP_EXCLUSIVE_CONTENT" ROSALIA_FILE_UPLOAD_SUBSTACK = "ROSALIA_FILE_UPLOAD_SUBSTACK" ROSALIA_LISTENING_PARTY_LUX = "ROSALIA_LISTENING_PARTY_LUX" ROSALIA_LYRIC_PAGE_LUX = "ROSALIA_LYRIC_PAGE_LUX" ROSALIA_NEWSLETTER_2024 = "ROSALIA_NEWSLETTER_2024" ROSALIA_NEWSLETTER_2025 = "ROSALIA_NEWSLETTER_2025" ROSALIA_PRE_SAVE_LLYLM = "ROSALIA_PRE_SAVE_LLYLM" ROSALIA_PRE_SAVE_LUX = "ROSALIA_PRE_SAVE_LUX" ROSALIA_PRE_SAVE_MOTOMAMI = "ROSALIA_PRE_SAVE_MOTOMAMI" ROSALIA_PRE_SAVE_RR = "ROSALIA_PRE_SAVE_RR" ROSALIA_PRE_SAVE_TUYA = "ROSALIA_PRE_SAVE_TUYA" ROSALIA_NEW_WOMAN_FANCARD = "ROSALIA_NEW_WOMAN_FANCARD" ROSALIA_MISC = "ROSALIA_MISC" ROSALIA_PRE_SAVE_EL_MAL_QUERER = "ROSALIA_PRE_SAVE_EL_MAL_QUERER" ROSALIA_PAST_TICKET_PURCHASERS_2022 = "ROSALIA_PAST_TICKET_PURCHASERS_2022" ROSALIA_LUX_2026_TOUR_PRE_SALE = "ROSALIA_LUX_2026_TOUR_PRE_SALE" class AcquisitionCountry(enum.StrEnum): ANY_COUNTRY = "ANY_COUNTRY" # placeholder class HeavyRotation(enum.StrEnum): IN = "IN" NOT_IN = "NOT_IN" UNKNOWN = "UNKNOWN" class HeavyRotationFilter(enum.StrEnum): IN = "IN" NOT_IN = "NOT_IN" # todo merge with above after new heavy rotation filter is released class HeavyRotationTmp(enum.StrEnum): IN = "IN" IN_BEFORE = "IN_BEFORE" NOT_IN = "NOT_IN" UNKNOWN = "UNKNOWN" class AgeRange(enum.StrEnum): FROM_13_TO_17 = "FROM_13_TO_17" FROM_18_TO_22 = "FROM_18_TO_22" FROM_23_TO_30 = "FROM_23_TO_30" FROM_31_TO_40 = "FROM_31_TO_40" FROM_41_TO_51 = "FROM_41_TO_51" FROM_52_TO_60 = "FROM_52_TO_60" FROM_61 = "FROM_61" class SegmentCategory(enum.StrEnum): SIGN_UP = "SIGN_UP" CAMPAIGN_PARTICIPATION = "CAMPAIGN_PARTICIPATION" EMAIL_CAMPAIGN = "EMAIL_CAMPAIGN" SMS_CAMPAIGN = "SMS_CAMPAIGN" LISTENING = "LISTENING" FOLLOW_ARTIST = "FOLLOW_ARTIST" ADDED_ARTISTS_MUSIC = "ADDED_ARTISTS_MUSIC" HEAVY_LISTENING = "HEAVY_LISTENING" MERCH = "MERCH" CONTEST = "CONTEST" CONCERT_TICKET = "CONCERT_TICKET" LIVE_STREAMING = "LIVE_STREAMING" FAN_CLUB = "FAN_CLUB" @classmethod def ordered(cls) -> tuple[SegmentCategory, ...]: return ( cls.SIGN_UP, cls.CAMPAIGN_PARTICIPATION, cls.EMAIL_CAMPAIGN, cls.SMS_CAMPAIGN, cls.LISTENING, cls.FOLLOW_ARTIST, cls.ADDED_ARTISTS_MUSIC, cls.HEAVY_LISTENING, cls.MERCH, cls.CONTEST, cls.CONCERT_TICKET, cls.LIVE_STREAMING, cls.FAN_CLUB, ) class SegmentExplainedResponseLanguage(enum.StrEnum): english = "en" class AcquisitionCampaign(enum.StrEnum): ANY_CAMPAIGN = "ANY_CAMPAIGN" class Genre(enum.StrEnum): ROCK = "ROCK" POP = "POP" COUNTRY = "COUNTRY" METAL = "METAL" JAZZ = "JAZZ" URBANO = "URBANO" BALLAD = "BALLAD" TROPICAL = "TROPICAL" CLASSICAL = "CLASSICAL" BLUES = "BLUES" SOUL = "SOUL" class BirthMonth(enum.StrEnum): JAN = "JAN" FEB = "FEB" MAR = "MAR" APR = "APR" MAY = "MAY" JUN = "JUN" JUL = "JUL" AUG = "AUG" SEP = "SEP" OCT = "OCT" NOV = "NOV" DEC = "DEC"