from collections import defaultdict from oto import response from masters_registry.constant import api_const from masters_registry.constant import field_const from masters_registry.logic import ownership as ownership_logic from masters_registry.models import ownership from masters_registry.models import ows_carveouts from masters_registry.models import ows_territories from masters_registry.models import yt_ownership def ownership_check_dms_carveout( ownership_info, territories, correlation_id, store_id=api_const.YOUTUBE_DMS): """Check which territories can be sent to a particular DMS Use this function if you do not know the TUID (e.g. when you are locking the territories.) In that case we have to get all TUIDs from the ownership record in dynamo db, and check carveouts for them. Args: ownership_info (dict): ownership object from MR dynamo db territories (list): list of territories to be sent to DMS correlation_id (str): unique ID for logging store_id (str): id of DMS store (default is '453' - YouTube) Returns: Response: List of territories that are allowed to be sent to DMS: * If there is a store-level carveout - empty list; * If there is a substore-level carveout - list of territories, that does not have a substore carveout; * If there are no carveouts - unmodified list of territories; """ owned_territories = ownership_info[field_const.TERRITORIES] allowed_territories = [] tuid_territories = defaultdict(list) for territory in territories: # If territory is unclaimed, we do not have information about it's # TUID, so we are not checking the carveouts for it if territory not in owned_territories: allowed_territories.append(territory) else: tuids = ownership_logic._get_tuids_from_territory( owned_territories[territory]) for tuid in tuids: tuid_territories[tuid].append(territory) for tuid, territories in tuid_territories.items(): carveout_result = tuid_check_dms_carveout( tuid, territories, correlation_id, store_id) if not carveout_result: return carveout_result if carveout_result.message: allowed_territories.extend( carveout_result.message[field_const.ALLOWED_TERRITORIES]) return response.Response(allowed_territories) def tuid_check_dms_carveout( tuid, territories, correlation_id, store_id=api_const.YOUTUBE_DMS): """Check, which territories can be sent to a particular DMS Args: tuid (int): TUID that we are updating territories (list): list of territories to be sent to DMS correlation_id (str): unique ID for logging store_id (str): id of DMS store Returns: Response: List of territories that are allowed to be sent to DMS: * If there is a store-level carveout - empty list; * If there is a substore-level carveout - list of territories, that does not have a substore carveout; * If there are no carveouts - unmodified list of territories; """ upc_response = ownership.get_upc_by_tuid(tuid) if not upc_response: return upc_response upc = upc_response.message[field_const.UPC] carveout_response = ows_carveouts.get_dms_carveout_for_upc( upc, correlation_id) if not carveout_response: return carveout_response carveout = carveout_response.message carvedout_stores = carveout.get(field_const.STORE) store_carvedout = None if carvedout_stores and isinstance(carvedout_stores, dict): store_carvedout = carvedout_stores.get(store_id) has_store_carveout = store_carvedout and field_const.CO_DISTROS.get( field_const.FULL_TRACK) in store_carvedout.get(field_const.DISTROS) if has_store_carveout: return response.Response({ field_const.ALLOWED_TERRITORIES: set(), field_const.SUBSTORE_CARVEOUTS: ( store_id, set()) }) if carveout[field_const.SUBSTORE]: substore_territories = carveout[field_const.SUBSTORE].get(store_id, {}) else: substore_territories = {} territories = set(territories) substore_carveout_territories = set(substore_territories.values()) if substore_carveout_territories: converted = ows_territories.convert_territories( substore_carveout_territories, correlation_id=correlation_id) if not converted: return converted converted_territories_list = [ territory[field_const.TERRITORY_CODE_A2] for territory in converted.message[field_const.ITEMS]] substore_carveout_territories = set(converted_territories_list) allowed_territories = territories.difference(substore_carveout_territories) if substore_carveout_territories: territory_dict = { field_const.ALLOWED_TERRITORIES: allowed_territories, field_const.SUBSTORE_CARVEOUTS: ( store_id, substore_carveout_territories) } else: territory_dict = { field_const.ALLOWED_TERRITORIES: allowed_territories, field_const.SUBSTORE_CARVEOUTS: ( store_id, set()) } return response.Response(territory_dict) def send_message_to_yt_ownership( isrc, tuid, updated_territories, correlation_id, force_update=False): """Check whether some of the updated territories need to be carved out. If so, send to youtube only valid territories. More info in dms_carveout.tuid_check_dms_carveout. Args: isrc (str): international standard recording code tuid (int): track unique identifier updated_territories (list): territories that were updated in DynamoDB correlation_id (str): correlation id for logging force_update (bool): Force update when no territories Returns: response.Response: result of operation, which is needed only if operation failed """ if not updated_territories: yt_ownership.send_message( isrc, updated_territories, correlation_id) return response.Response() dms_carveout_response = tuid_check_dms_carveout( tuid, updated_territories, correlation_id) if not dms_carveout_response: return dms_carveout_response message = dms_carveout_response.message allowed_territories = message[field_const.ALLOWED_TERRITORIES] if allowed_territories: yt_ownership.send_message( isrc, allowed_territories, correlation_id) """ Force update when no territories left from diff with registry and carveout. (only used from refresh endpoint) """ if not allowed_territories and force_update: yt_ownership.send_message( isrc, [], correlation_id) return response.Response()