from typing import Any, Dict, List, Mapping from analytics.constants import cache from analytics.queries.format import format_row from analytics.queries.product import ProductSummary from analytics.utils.cache import cache_in_redis from analytics.utils.streams import ( breakdown_by_sos, calc_date_skip_rate, check_store_ids_for_sos_detailed, get_streams_sos_detailed_columns, get_streams_sos_detailed_columns_from_stream_sources, ) TOTAL_SUMMARY_TYPE = "TOTAL" AGGREGATION_FIELDS_SUMMARY = { "TOTAL": "product_id", "STORE": "store_id", # TODO SOUND_RECORDING was "tracks.track_unique_id", check data and multi product "SOUND_RECORDING": "isrc", "COUNTRY": "country_code", # TODO check data is accurate when using this for id "SOS": "product_id", "SOS_DETAILED": "product_id", } # map of type -> aggregation type -> dict of tables required PRODUCT_TABLES_SUMMARY = { # Product streams "TOTAL": { "total": { "streams_table": "V_STREAMS_BY_PRODUCT_TRACK_FEED_DISTRIBUTOR_DAILY", "product_downloads_table": "DOWNLOADS_BY_PRODUCT_FEED_DISTRIBUTOR_DAILY", "product_track_downloads_table": "DOWNLOADS_BY_PRODUCT_TRACK_FEED_DISTRIBUTOR_DAILY", # noqa }, "country": { "streams_table": "V_STREAMS_BY_PRODUCT_TRACK_COUNTRY_FEED_DISTRIBUTOR_DAILY", # noqa "product_downloads_table": "DOWNLOADS_BY_PRODUCT_COUNTRY_FEED_DISTRIBUTOR_DAILY", # noqa "product_track_downloads_table": "DOWNLOADS_BY_PRODUCT_TRACK_COUNTRY_FEED_DISTRIBUTOR_DAILY", # noqa }, }, "SOUND_RECORDING": { "total": { "streams_table": "V_STREAMS_BY_PRODUCT_TRACK_FEED_DISTRIBUTOR_DAILY", "product_downloads_table": "DOWNLOADS_BY_PRODUCT_TRACK_FEED_DISTRIBUTOR_DAILY", # noqa "product_track_downloads_table": "DOWNLOADS_BY_PRODUCT_TRACK_FEED_DISTRIBUTOR_DAILY", # noqa }, "country": { "streams_table": "V_STREAMS_BY_PRODUCT_TRACK_COUNTRY_FEED_DISTRIBUTOR_DAILY", # noqa "product_downloads_table": "DOWNLOADS_BY_PRODUCT_TRACK_COUNTRY_FEED_DISTRIBUTOR_DAILY", # noqa "product_track_downloads_table": "DOWNLOADS_BY_PRODUCT_TRACK_COUNTRY_FEED_DISTRIBUTOR_DAILY", # noqa }, }, "COUNTRY": { "total": { "streams_table": "V_STREAMS_BY_PRODUCT_TRACK_COUNTRY_FEED_DISTRIBUTOR_DAILY", # noqa "product_downloads_table": "DOWNLOADS_BY_PRODUCT_COUNTRY_FEED_DISTRIBUTOR_DAILY", # noqa "product_track_downloads_table": "DOWNLOADS_BY_PRODUCT_TRACK_COUNTRY_FEED_DISTRIBUTOR_DAILY", # noqa }, "country": { "streams_table": "V_STREAMS_BY_PRODUCT_TRACK_COUNTRY_FEED_DISTRIBUTOR_DAILY", # noqa "product_downloads_table": "DOWNLOADS_BY_PRODUCT_COUNTRY_FEED_DISTRIBUTOR_DAILY", # noqa "product_track_downloads_table": "DOWNLOADS_BY_PRODUCT_TRACK_COUNTRY_FEED_DISTRIBUTOR_DAILY", # noqa }, }, "STORE": { "total": { "streams_table": "V_STREAMS_BY_PRODUCT_TRACK_FEED_DISTRIBUTOR_DAILY", "product_downloads_table": "DOWNLOADS_BY_PRODUCT_FEED_DISTRIBUTOR_DAILY", "product_track_downloads_table": "DOWNLOADS_BY_PRODUCT_TRACK_FEED_DISTRIBUTOR_DAILY", # noqa }, "country": { "streams_table": "V_STREAMS_BY_PRODUCT_TRACK_COUNTRY_FEED_DISTRIBUTOR_DAILY", # noqa "product_downloads_table": "DOWNLOADS_BY_PRODUCT_COUNTRY_FEED_DISTRIBUTOR_DAILY", # noqa "product_track_downloads_table": "DOWNLOADS_BY_PRODUCT_TRACK_COUNTRY_FEED_DISTRIBUTOR_DAILY", # noqa }, }, "SOS": { "total": { "streams_table": "V_STREAMS_BY_PRODUCT_TRACK_FEED_DISTRIBUTOR_DAILY", "product_downloads_table": "DOWNLOADS_BY_PRODUCT_TRACK_FEED_DISTRIBUTOR_DAILY", # noqa "product_track_downloads_table": "DOWNLOADS_BY_PRODUCT_TRACK_FEED_DISTRIBUTOR_DAILY", # noqa }, "country": { "streams_table": "V_STREAMS_BY_PRODUCT_TRACK_COUNTRY_FEED_DISTRIBUTOR_DAILY", # noqa "product_downloads_table": "DOWNLOADS_BY_PRODUCT_TRACK_COUNTRY_FEED_DISTRIBUTOR_DAILY", # noqa "product_track_downloads_table": "DOWNLOADS_BY_PRODUCT_TRACK_COUNTRY_FEED_DISTRIBUTOR_DAILY", # noqa }, }, "SOS_DETAILED": { "total": { "streams_table": "V_STREAMS_BY_PRODUCT_TRACK_FEED_DISTRIBUTOR_DAILY", "product_downloads_table": "DOWNLOADS_BY_PRODUCT_TRACK_FEED_DISTRIBUTOR_DAILY", # noqa "product_track_downloads_table": "DOWNLOADS_BY_PRODUCT_TRACK_FEED_DISTRIBUTOR_DAILY", # noqa }, "country": { "streams_table": "V_STREAMS_BY_PRODUCT_TRACK_COUNTRY_FEED_DISTRIBUTOR_DAILY", # noqa "product_downloads_table": "DOWNLOADS_BY_PRODUCT_TRACK_COUNTRY_FEED_DISTRIBUTOR_DAILY", # noqa "product_track_downloads_table": "DOWNLOADS_BY_PRODUCT_TRACK_COUNTRY_FEED_DISTRIBUTOR_DAILY", # noqa }, }, } def get_product_tables_for_summary( query_type: str, countries: List, ) -> dict: key = "total" if len(countries) != 0: key = "country" table_options = PRODUCT_TABLES_SUMMARY.get(query_type) if not table_options: raise NotImplementedError(f"Query {query_type} not supported") tables = table_options.get(key) if not tables: raise NotImplementedError(f"Query {query_type} not supported with type {key}") return tables @cache_in_redis(ttl=cache.ONE_DAY) def get_product_summary( query_params: Mapping[str, Any], permissions: Mapping[str, Any], ) -> List[Dict]: query_type = query_params.get("type", TOTAL_SUMMARY_TYPE) aggregation_field = AGGREGATION_FIELDS_SUMMARY.get(query_type) if aggregation_field: query_params["aggregation_field"] = aggregation_field countries = query_params.get("countries", []) tables = get_product_tables_for_summary(query_type, countries) query_params.update(tables) if query_type == "SOS_DETAILED": store_ids = check_store_ids_for_sos_detailed(query_params.get("store_ids", [])) stream_sources = query_params.get("stream_sources", []) if stream_sources: query_params[ "streams_sos_columns" ] = get_streams_sos_detailed_columns_from_stream_sources( store_ids, stream_sources ) else: query_params["streams_sos_columns"] = get_streams_sos_detailed_columns( store_ids ) query = ProductSummary({**query_params, **permissions}) summary = query.execute() ts = [] for data_point in summary: data_point = format_row(data_point) if ( data_point.get("streams_with_skips") or data_point.get("streams_with_skips") == 0 ): skip_rate = calc_date_skip_rate(data_point) del data_point["streams_with_skips"] data_point["skip_rate"] = skip_rate ts.append(data_point) if ts and query_type == "SOS": ts = breakdown_by_sos(ts[0], key="streams", timeseries=False) if ts and query_type == "SOS_DETAILED": ts = breakdown_by_sos( ts[0], key="streams", timeseries=False, version=2, sources=query_params["streams_sos_columns"], ) return ts