"""Logic for getting streams data.""" from oto import response as oto_response from analytics.consts import account as account_constants from analytics.consts import models as model_consts from analytics.models import ows_account from analytics.models import streams as streams_model from analytics.utils import parallel def get_streams( start_date, end_date, account_type, account_id, storeids, feed_ids, isrcs, artistids, distributors): """Get daily streams data from model layer.""" if account_type == account_constants.SUBACCOUNT_TYPE: ows_account_response = ows_account.get_vendor_id_by_subaccount_id( subaccount_id=account_id) if not ows_account_response: return ows_account_response subaccount_id = account_id account_id = ows_account_response.message else: subaccount_id = None result = streams_model.get_streams( start_date=start_date, end_date=end_date, labelid=account_id, subaccountid=subaccount_id, storeids=storeids, feed_ids=feed_ids, isrcs=isrcs, artistids=artistids, distributors=distributors) if not result: return result response_dictionary = {'items': result.message} _calculate_overall_metrics(response_dictionary) _calculate_percentage(response_dictionary) return oto_response.Response(message=response_dictionary) def get_placements( start_date, end_date, account_type, account_id, storeids, feed_ids, isrcs, artistids, distributors, limit): """Create playlist placements data for vendor, isrcs, or artists. Args: start_date (str): Start date end_date (str): End date account_type (str): Account type (vendor or subaccount) account_id (str): Account id storeids (list): List of stores to get data for feed_ids (list): List of available feeds isrcs (list): List of isrcs to get data for artistids (list): List of artistids to get data for distributors (list): List of distributors names limit (int | None): Number of top placements to return (value of None indicates to fetch all placements) Returns: response.Response: Playlist placements data """ if account_type == account_constants.SUBACCOUNT_TYPE: ows_account_response = ows_account.get_vendor_id_by_subaccount_id( subaccount_id=account_id) if not ows_account_response: return ows_account_response subaccount_id = account_id account_id = ows_account_response.message else: subaccount_id = None results = parallel.execute_in_parallel({ 'top_placements': { 'func': streams_model.get_placements, 'args': (), 'kwargs': dict( start_date=start_date, end_date=end_date, labelid=account_id, subaccountid=subaccount_id, storeids=storeids, feed_ids=feed_ids, isrcs=isrcs, artistids=artistids, distributors=distributors, limit=limit) }, 'total_placements': { 'func': streams_model.get_placement_totals, 'args': (), 'kwargs': dict( start_date=start_date, end_date=end_date, labelid=account_id, subaccountid=subaccount_id, storeids=storeids, feed_ids=feed_ids, isrcs=isrcs, artistids=artistids, distributors=distributors) } }) top_placements_result = results['top_placements'] total_placements_result = results['total_placements'] if not top_placements_result: return top_placements_result if not total_placements_result: return total_placements_result total = total_placements_result.message response_dictionary = { 'items': top_placements_result.message, 'total': total} return oto_response.Response(message=response_dictionary) def _calculate_percentage(chart): overall_metric = 'overall_number_of_streams' overall_spotify_metric = 'overall_number_of_spotify_streams' for metric in model_consts.STREAMS_METRICS: if not(metric == overall_metric or metric == overall_spotify_metric): if chart[overall_metric] == 0: chart[metric + '_pct'] = 0 continue chart[metric + '_pct'] = round( chart[metric] / chart[overall_metric] * 100) def _calculate_overall_metrics(chart): for metric in model_consts.STREAMS_METRICS: chart[metric] = sum(e[metric] for e in chart['items'] if e[metric])