"""Logic for retrieving songs top metrics.""" from typing import Any, Dict, Mapping from analytics.constants import cache from analytics.constants.regions import REGIONMAP from analytics.constants.store import TIKTOK_STORE_ID from analytics.handler_utils import user_has_full_access from analytics.queries.format import format_row from analytics.queries.top_metrics import ( TopMetricsSoundRecordings, TopMetricsSoundRecordingsGainers, ) from analytics.schemas.top_metrics import TopMetricsSchema from analytics.utils import store_availability from analytics.utils.cache import cache_in_redis FALLBACK_TABLE_NAME = "V_METRICS_BY_TRACK_COUNTRY_FEED_DISTRIBUTOR_ROLLUP" def _get_top_metrics_table_name(query_params: Mapping[str, Any]) -> str: """Get the table name for top metrics.""" country_ids = query_params.get("country_ids", []) global_participant_ids = query_params.get("global_participant_ids", []) gainers = ( True if ( query_params.get("only_daily_data", False) or query_params.get("only_weekly_data", False) ) else False ) if gainers: # these tables only serve https://insights.theorchard.com/tiktokSongs # (they contain only ISRCs with above certain creations threshold) if query_params.get("only_daily_data", False) or query_params.get( "only_weekly_data", False ): if country_ids: return "METRICS_BY_TRACK_COUNTRY_FEED_DISTRIBUTOR_PRODFAM_CREATIONS_THRESHOLD_ROLLUP_V2" else: return "METRICS_BY_TRACK_FEED_DISTRIBUTOR_PRODFAM_CREATIONS_THRESHOLD_ROLLUP_V2" else: # these table serve https://insights.theorchard.com/catalog/songs if global_participant_ids: if country_ids: return "V_METRICS_BY_TRACK_PARTICIPANT_COUNTRY_FEED_DISTRIBUTOR_ROLLUP" elif not country_ids: return "METRICS_BY_TRACK_PARTICIPANT_FEED_DISTRIBUTOR_ROLLUP" else: if country_ids: if len(country_ids) >= 3: # Attempt to match country_ids to a region # as we have pre-aggregated these regions to improve performance. # The shortest of which is DACH (3) matched_region = REGIONMAP.get(frozenset(country_ids)) if matched_region: query_params["region"] = str(matched_region) return "V_METRICS_BY_TRACK_REGION_FEED_DISTRIBUTOR_ROLLUP" else: return FALLBACK_TABLE_NAME else: return FALLBACK_TABLE_NAME else: return "METRICS_BY_TRACK_FEED_DISTRIBUTOR_ROLLUP" @cache_in_redis(ttl=cache.ONE_DAY) def get_top_metrics( query_params: Mapping[str, Any], permissions: Mapping[str, Any], ) -> Dict: """Get Songs Top Metrics for My Catalog.""" items = [] total_results = 0 if user_has_full_access(permissions): query_params["user_has_full_access"] = True else: query_params["user_has_full_access"] = False store_ids = store_availability.get_query_store_ids( query_params.get("store_ids", []) ) if not store_ids: return TopMetricsSchema.normalized_response( {"items": items, "total_results": total_results} ) store_ids.append(TIKTOK_STORE_ID) query_params["store_ids"] = store_ids query_params["table_name"] = _get_top_metrics_table_name(query_params) # rollup_grain dedups the (label_id, subaccount_id) fan-out from the # transfer-product-ownership dbt PR's widened rollups. The daily/weekly # branch routes to a collapsing rollup with no owner columns — leave # grain off there. query_params["rollup_grain"] = not ( query_params.get("only_daily_data", False) or query_params.get("only_weekly_data", False) ) query_params[ "is_feed_data_available" ] = store_availability.is_apple_spotify_data_in_sync() query = TopMetricsSoundRecordings({**query_params, **permissions}) result = [format_row(data_point) for data_point in query.execute()] if not result: pass else: total_results = result[0]["total_results"] return TopMetricsSchema.normalized_response( {"items": result, "total_results": total_results} ) @cache_in_redis(ttl=cache.ONE_DAY) def get_top_metrics_gainers( query_params: Mapping[str, Any], permissions: Mapping[str, Any], ) -> Dict: """Get Songs Top Metrics for https://insights.theorchard.com/trending/tiktok.""" items = [] total_results = 0 store_ids = store_availability.get_query_store_ids( query_params.get("store_ids", []) ) if not store_ids: return TopMetricsSchema.normalized_response( {"items": items, "total_results": total_results} ) store_ids.append(TIKTOK_STORE_ID) query_params["store_ids"] = store_ids query_params["table_name"] = _get_top_metrics_table_name(query_params) # handle 2 existing cases, otherwise isrc_country_id is equal to the first 2 letters of the ISRC if "US" in query_params.get("isrc_country_ids", []): query_params["isrc_country_ids"].append("QM") if "GB" in query_params.get("isrc_country_ids", []): query_params["isrc_country_ids"].append("UK") query_params[ "is_feed_data_available" ] = store_availability.is_apple_spotify_data_in_sync() query = TopMetricsSoundRecordingsGainers({**query_params, **permissions}) result = [format_row(data_point) for data_point in query.execute()] if not result: pass else: total_results = result[0]["total_results"] return TopMetricsSchema.normalized_response( {"items": result, "total_results": total_results} )