"""Logic tier for calling ows-services.""" from flask import current_app from flask_executor import Executor from oto import response from feature_fm.constants.permissions import ADMIN_ROLE_ID from feature_fm.constants.permissions import ADVERTISING_ROLE_ID from feature_fm.constants.permissions import CAMPAIGNS_FEATURE_NAME from feature_fm.constants.permissions import WHITELIST_FEATURE_NAME from feature_fm.constants.permissions import WHITELIST_MONTHLY_BUDGET from feature_fm.models import ows_account from feature_fm.models import ows_accounting from feature_fm.models import ows_artist from feature_fm.models import ows_search from feature_fm.models import ows_users def get_artists( account_type, account_id, page_limit=None, page_offset=None, updated_since=None): """Get a paginated list of artists for a given vendor/subaccount. Args: account_type (str): The account type (vendor or subaccount) account_id (int): The account id page_limit (str): The page limit of the request page_offset (str): The page offset of the request updated_since (int): The timestamp to restrict the query Returns: response.Response: containing the artists """ artists_response = ows_artist.get_artists( account_type, account_id, page_limit, page_offset, updated_since) if not artists_response: return artists_response return response.Response(map_artists_result(artists_response.message)) def map_artists_result(artists_result): """Map the artists result for FeatureFM. Args: artists_result [dict]: the artists result. Returns: [dict]: the mapped artists result. """ items = artists_result.get('items', []) artist_pagination = artists_result.get('pagination', {}) artists = [] for item in items: artists.append({ 'artist_id': item.get('artist_id'), 'name': item.get('name'), 'genres': item.get('genres') }) pagination = { 'page_limit': artist_pagination.get('limit'), 'page_offset': artist_pagination.get('offset'), 'total_records': artist_pagination.get('total_records') } return {'items': artists, 'pagination': pagination} def get_artists_bulk(account_type, account_id, artist_ids): """Get a list of artists for a specified list of artist ids. Args: account_type (str): The account type (vendor or subaccount) account_id (int): The account id artist_ids ([int]): The list of artist ids to fetch Returns: response.Response: containing the artists """ return ows_artist.get_artists_bulk(account_type, account_id, artist_ids) def get_artist_releases( account_type, account_id, artist_id, search_term=None, page_size=None): """Get a paginated list of releases for an artist. Args: account_type (str): The account type (vendor or subaccount) account_id (int): The account id artist_id: (int): The artist id search_term (str): The search term page_size (int): The page size Returns: response.Response: containing the releases """ releases_response = ows_search.get_artist_releases( account_type, account_id, artist_id, search_term, page_size) if not releases_response: return releases_response return response.Response(map_releases_result(releases_response.message)) def get_label_releases( account_type, account_id, search_term=None, page_size=None): """Get a paginated list of releases for a label. Args: account_type (str): The account type (vendor or subaccount) account_id (int): The account id search_term (str): The search term page_size (int): The page size Returns: response.Response: containing the releases """ releases_response = ows_search.get_label_releases( account_type, account_id, search_term, page_size) if not releases_response: return releases_response return response.Response(map_releases_result(releases_response.message)) def map_releases_result(releases_result): """Map the releases result for FeatureFM. Args: releases_result ([dict]): the releases result. Returns: [dict]: the mapped releases result. """ results = releases_result.get('results') releases = [] if results: for key, item in results.items(): release_name = item.get('release_name') if 'delivered_version' in item: release_name += ' ({0})'.format(item.get('delivered_version')) releases.append({ 'release_id': int(item.get('release_id')), 'release_name': release_name, 'original_release_name': item.get('release_name'), 'release_image': item.get('coverart_paths', {}).get('thumb'), 'upc': item.get('display_upc'), 'artist_name': item.get('artist_name'), 'version': item.get('version'), 'delivered_version': item.get('delivered_version') }) pagination = { 'page_limit': int(releases_result.get('pageSize')), 'total_records': releases_result.get('totalHits') } return {'items': releases, 'pagination': pagination} def get_user_info( account_type, account_id, user_id, fetch_artists, correlation_id): """Get user's info. Args: account_type (str): The account type (vendor or subaccount). account_id (int): The account id. user_id (str): The user id (e.g. alw:123). fetch_artists (bool): Flag that declares if we should fetch artists correlation_id (str): the correlation ID. Returns: response.Response: containing the user's info. """ request_list = [ {'function_to_call': ows_users.get_user_info, 'params': [user_id, correlation_id]}, {'function_to_call': ows_account.get_enabled_features_for_vendor, 'params': [account_id, correlation_id]} ] with Executor(current_app) as executor: response_list = list(executor.map(_make_request, request_list)) for response_item in response_list: if not response_item: return response_item user_info = response_list[0].message user_account = user_info.get('account', {}) account_id_key = '{0}_id'.format(account_type) features_response = response_list[1] if account_id != user_account.get(account_id_key): return response.create_not_found_response() vendor_id = user_account['vendor_id'] currency_code = ows_account.get_vendor_currency_code(vendor_id) if fetch_artists or fetch_artists is None: artists_response = ows_artist.get_all_artist_ids( account_type, account_id) if not artists_response: return artists_response return response.Response(map_user_info( user_info, artists_response.message, features_response.message, currency_code)) return response.Response(map_user_info( user_info, [], features_response.message, currency_code)) def map_user_info(user_info, artists_result, features_result, currency_code): """Map the user's info for FeatureFM. Args: user_info (dict): the user's info. artists_result (dict): containing the artist ids. features_result (dict): containing the enabled features. Returns: dict: the mapped user's info. """ features = [item['feature_name'] for item in features_result['items']] permissions = { 'action_pages': 'W', 'smart_links': 'W'} role_ids = user_info.get('role_ids') if CAMPAIGNS_FEATURE_NAME in features: if ADVERTISING_ROLE_ID in role_ids or ADMIN_ROLE_ID in role_ids: permissions.update({'campaigns': 'W'}) else: permissions.update({'campaigns': 'N'}) else: permissions.update({'campaigns': 'N'}) ga_flags = { 'orchard_advertising': ( CAMPAIGNS_FEATURE_NAME in features or False), 'orchard_advertising_tier_1': ( WHITELIST_FEATURE_NAME in features or False), 'advertising_role': ( ( (ADVERTISING_ROLE_ID in role_ids) or ( ADMIN_ROLE_ID in role_ids)) or False) } result = { 'user_id': user_info.get('user_id'), 'first_name': user_info.get('first_name'), 'last_name': user_info.get('last_name'), 'email': user_info.get('email'), 'language': user_info.get('language'), 'currency': currency_code, 'company': user_info.get('company'), 'permissions': permissions, 'ga_flags': ga_flags } if len(artists_result): result.update({'artist_ids': artists_result.get('items')}) return result def get_artist_by_id(account_type, account_id, artist_id): """Get artist's info. Args: account_type (str): The account type (vendor or subaccount). account_id (int): The account id. artist_id (str): The artist . Returns: response.Response: containing the artist's info. """ return ows_artist.get_artist_by_id( account_type, account_id, artist_id) def get_campaign_budget(account_type, account_id): """Get the monthly campaign budget for a vendor or subaccount. Args: account_type (str): The account type (vendor or subaccount). account_id (int): The account id (e.g. 7123). Returns: flask.Response: Containing the monthly campaign budget. """ # TODO: We're only supporting vendors at the moment but in the future we # should fetch vendor_id from ows-account if account_type is subaccount. features_response = ows_account.get_enabled_features_for_vendor( account_id) if not features_response: return features_response features = [f['feature_name'] for f in features_response.message['items']] if CAMPAIGNS_FEATURE_NAME not in features: return response.Response({'monthly_total_budget': 0}) if WHITELIST_FEATURE_NAME in features: return response.Response({ 'monthly_total_budget': WHITELIST_MONTHLY_BUDGET }) accounting_response = ows_accounting.get_average_monthly_net_revenue( account_type, account_id) if not accounting_response: return accounting_response return response.Response({ 'monthly_total_budget': accounting_response.message[ 'average_monthly_net_revenue'] }) def get_budget_caps(): """Get budget caps for all the labels. Returns: flask.Response: Containing the budget caps for all the labels. """ accounting_response = ows_accounting.get_budget_caps() if not accounting_response: return accounting_response return response.Response(accounting_response.message) def _make_request(request_item): """Make a request as part of a multi-thread series of requests. Args: request_item (dict): containing a function and parameters. Returns: Result of calling the given function with the given parameters. """ return request_item.get('function_to_call')(*request_item.get('params'))