"""Interface to the ows-product microservice. Used for product ownership """ from flask import g from oto import response from oto import status from owsrequest import request # as requests from backend.constants import error from backend.constants import services from backend.constants import track_field as tf from backend.utils import api as api_utils from backend.utils import model_utils _response_cache = {} def verify_product_ownership(account_type, account_id, product_id): """Get product ownership verification for a given vendor and subaccount. Args: account_type (str): Account type to check. account_id (int): Account id to verify product ownership for. product_id (int): Product id of product of which to verify ownership. Returns: response.Response """ # Construct the endpoint endpoint = '/{}/{}/product/{}'.format( account_type, account_id, product_id) return _get_head_from_ows_product_service(endpoint) def get_product_by_product_id(product_id): """Get product metadata from product_id. Args: product_id (int): Product id of product of which to verify ownership. Returns: response.Response """ # Construct the endpoint endpoint = '/product/{}'.format(product_id) return _get_from_ows_product_service(endpoint) def update_track_localization( tuid, language_id, track_name, version, artists=None): """Update track localization via ows-product service. Args: tuid (str): track unique id language_id (str): language identifier track_name (str): track name version (str): track version artists (list): List of track artist dictionaries Returns: response.Response """ endpoint = '/localization/track/{tuid}/language/{language_id}'.format( tuid=tuid, language_id=language_id) request_json = { tf.TRACK_NAME: track_name, tf.VERSION: version } if artists: request_json[tf.ARTISTS] = _convert_artist_list_to_dict(artists) localization_response = request.put( services.OWS_PRODUCT, endpoint, json=request_json) if localization_response.status_code == status.OK: response_json = localization_response.json() updated_artists = [] if artists: # Replacing response artists dict of {track_artist_id: name} with # a list of artist objects, containing artist type as well. response_artists = response_json.pop(tf.ARTISTS) for artist in artists: if response_artists.get(str(artist[tf.TRACK_ARTIST_ID])): updated_artists.append(artist) response_json[tf.ARTISTS] = updated_artists return response.Response(response_json) else: return model_utils.process_error_response( localization_response, code=error.OWS_PRODUCT_ERROR_CODE) def update_localizations(localizations): """Bulk update several localizations for several TUIDs. Args: localizations (list): list of tracks to update. E.g. [{ 'language_id': 1, 'tuid': 2, 'track_name': 'Translated Track Name', 'version': 'Translated Version', 'artists': [{ 'track_artist_id': 3230, 'artist_type': 'performer', 'name': 'Translated Performer 1'}, ...] }, ...] Returns: response.Response """ request_json = {'items': []} for localization in localizations: request_loc = localization.copy() request_loc[tf.ARTISTS] = \ _convert_artist_list_to_dict(localization[tf.ARTISTS]) request_json['items'].append(request_loc) endpoint = '/localization/tracks' localization_response = request.put( services.OWS_PRODUCT, endpoint, json=request_json) if localization_response.status_code == status.OK: response_json = localization_response.json() return response.Response(message=response_json) return model_utils.process_error_response( localization_response, code=error.OWS_PRODUCT_ERROR_CODE) def delete_track_localization(tuid, language_id): """Delete track localization via ows-product service. Args: tuid (str): track unique id language_id (str): language identifier Returns: response.Response """ endpoint = '/localization/track/{tuid}/language/{language_id}'.format( tuid=tuid, language_id=language_id) localization_response = request.delete(services.OWS_PRODUCT, endpoint) if localization_response.status_code == status.OK: return response.Response({ 'tuid': tuid, 'language_id': language_id }) return model_utils.process_error_response( localization_response, code=error.OWS_PRODUCT_ERROR_CODE) def delete_track_localizations(tuids): """Delete localizations from given tracks. Args: tuids (list): List of tuids. Returns: response.Response """ endpoint = '/localization/track/{}'.format(','.join(str(t) for t in tuids)) ows_product_response = request.delete(services.OWS_PRODUCT, endpoint) if ows_product_response.status_code == status.OK: return response.Response({'tuids': tuids}) return model_utils.process_error_response( ows_product_response, code=error.OWS_PRODUCT_ERROR_CODE) def get_track_localizations(tuids): """Get track localizations via ows-product service. Args: tuids (list): list of track unique ids Returns: response.Response: localizations for tracks """ if not isinstance(tuids, list): tuids = [tuids] request_json = {'tuids': tuids} endpoint = '/localization/track' track_localization_response = request.post( services.OWS_PRODUCT, endpoint, json=request_json) if track_localization_response.status_code == 200: return response.Response(message=track_localization_response.json()) return model_utils.process_error_response( track_localization_response, code=error.OWS_PRODUCT_ERROR_CODE) def _get_head_from_ows_product_service(endpoint): """Helper function to call ows-product and return a Response. Args: endpoint (str): API endpoint to make head request to. Returns: response.Response """ product_head_response = request.head(services.OWS_PRODUCT, endpoint) if product_head_response.status_code == 200: return api_utils.create_ok_response() return response.create_error_response( code=error.OWS_PRODUCT_ERROR_CODE, message=error.OWS_PRODUCT_FORBIDDEN_MESSAGE, status=product_head_response.status_code) def _get_from_ows_product_service(endpoint): """Helper function to call ows-product and return a Response. Args: endpoint (str): endpoint to Returns: response.Response """ product_get_response = request.get(services.OWS_PRODUCT, endpoint) if product_get_response.status_code == 200: return response.Response(message=product_get_response.json()) return model_utils.process_error_response( product_get_response, code=error.OWS_PRODUCT_ERROR_CODE) def _convert_artist_list_to_dict(artist_list): """Convert list of artists to dict format. This allows OWS Product to consume data Args: artist_list (list): List of artist dicts Return: dict: Artist Id/Artist Name (key/value pair) """ return { artist[tf.TRACK_ARTIST_ID]: artist[tf.NAME] for artist in artist_list } def get_localization_languages(): """Get localization languages via ows-product service. Returns: response.Response: localization languages """ result = _response_cache.get('localization_languages') if not result: result = _get_from_ows_product_service('/localization/languages') _response_cache['localization_languages'] = result if not result: # Log error error_msg = '{message} {error}'.format( message=error.OWS_PRODUCT_FAILED_TO_GET_LOCALIZATION_LANGS_MSG, error=result.errors.get('message')) g.log.error(error_msg) return api_utils.copy_response(result)