from anydi import singleton from cachelib import BaseCache as Cache from fansifter_common.adapters.graphql_router import GlobalParticipant from fansifter_common.adapters.ows_account import OwsAccountClient from fansifter_common.artist.validators import ArtistValidator from fansifter_common.auth.account import Account from fansifter_common.utils.cache import cached from email_campaigns.rosters.constants import GLOBAL_FAN_DATA_LISTS_FEATURE_ID from email_campaigns.rosters.exceptions import ( InvalidCustomListIdError, MainRepArtistOnlyAllowedError, ) from email_campaigns.rosters.models import CustomList from email_campaigns.rosters.repositories import ( ArtistRosterLocalRepRepository, ArtistRosterMainRepRepository, CustomListRepository, ) from email_campaigns.rosters.types import FanDataListId DEFAULT_CACHE_TIMEOUT = 60 * 10 # 10 minutes @singleton class FanDataListService: def __init__( self, ows_account_client: OwsAccountClient, main_rep_repository: ArtistRosterMainRepRepository, local_rep_repository: ArtistRosterLocalRepRepository, custom_list_repository: CustomListRepository, artist_validator: ArtistValidator, cache: Cache, ) -> None: self.ows_account_client = ows_account_client self.main_rep_repository = main_rep_repository self.local_rep_repository = local_rep_repository self.custom_list_repository = custom_list_repository self.artist_validator = artist_validator self.cache = cache @cached("global-fandata-list-enabled-for-vendor", timeout=DEFAULT_CACHE_TIMEOUT) def is_global_access_enabled(self, vendor_id: int) -> bool: features = self.ows_account_client.get_vendor_features(vendor_id) for feature in features: if feature.feature_id == GLOBAL_FAN_DATA_LISTS_FEATURE_ID: return True return False def ensure_artist_access( self, fandata_list_id: FanDataListId, account: Account, *, allow_local_rep: bool = False, ) -> None: if not fandata_list_id.is_artist: return if not self.is_global_access_enabled(account.vendor_id): return is_main_rep = ( self.main_rep_repository.exists_by_account_and_global_participant_id( vendor_id=account.vendor_id, subaccount_id=account.subaccount_id, global_participant_id=fandata_list_id.id, ) ) if is_main_rep: return if allow_local_rep: is_local_rep = ( self.local_rep_repository.exists_by_account_and_global_participant_id( vendor_id=account.vendor_id, subaccount_id=account.subaccount_id, global_participant_id=fandata_list_id.id, ) ) if is_local_rep: return raise MainRepArtistOnlyAllowedError( global_participant_id=fandata_list_id.id, ) def resolve_global_participant( self, global_participant_id: str ) -> GlobalParticipant: """Resolve global participant id.""" return self.artist_validator.validate_global_participant_id( global_participant_id=global_participant_id ) def resolve_allowed_custom_list( self, custom_list_id: str, account: Account ) -> CustomList: """Resolve allowed custom list id.""" custom_list = self.custom_list_repository.get_allowed( custom_list_id, vendor_ids=[account.vendor_id], subaccount_ids=[account.subaccount_id], ) if custom_list is None: raise InvalidCustomListIdError return custom_list