from datetime import date, timedelta import itertools from typing import Dict, List, Any from server.artist.constants import HEADER_ORDER, COUNTRIES_MAPPER from server.track.constants import GENRES_MAPPER from server.db.constants import DSP_SOUNDCLOUD, DSP_TIKTOK def group_external_links_v4( groups: Dict[str, str], links: List[Dict[str, str]], group_key: str = "name", url_key: str = "url", default_group: str = "extra", ) -> Dict[str, Any]: """ Groups external links by defined groups :param groups: Dict of defined groups e.g. {"youtube": "header", ...} :param links: List of dict with links to be grouped e.g. {"name": "youtube", "url": "https://www.youtube.com/watch?v=dQw4w9WgXcQ"} :param group_key: Key to be grouped by :param url_key: Key to get url from :param default_group: Default group name for links with unknown source :return: Links grouped by defined groups and sources e.g. { "header": [ { "name": "souncloud", "items": [ { "url": "soundcloud.com" }, { "url": "soundcloud.com/2" }, ... ] } ], "social_media": [ { "name": "youtube", "items": [ { "url": "youtube.com" }, { "url": "youtube.com/2" }, ] }, ] } """ # Make sure that links are properly sorted for future grouping sorted_links = sorted(links, key=lambda l: (groups.get(l[group_key], default_group), l[group_key])) result = {} # Group links by defined groups for group_name, links_by_group in itertools.groupby( sorted_links, key=lambda l: groups.get(l[group_key], default_group) ): group_items = [] # Group links by source for source, links_by_source in itertools.groupby(links_by_group, key=lambda l: l[group_key]): group_items.append({"name": source, "items": [{"url": link[url_key]} for link in links_by_source]}) result[group_name] = group_items return result # temporary solutoin only for soundcloud artist and track. def make_chart_dates(result): for dsp in result: if dsp == DSP_SOUNDCLOUD or dsp == DSP_TIKTOK: last_chart_date = date.fromisoformat(result[dsp].pop("last_chart_date")) result[dsp]["chart_dates"] = [last_chart_date - timedelta(days=day) for day in reversed(range(28))] return result def order_header_external_links(results: Dict[str, Any]) -> Dict[str, Any]: # order items in header group according to https://data-analytics.atlassian.net/browse/DNAD-388 if "header" in results: results["header"].sort(key=lambda x: HEADER_ORDER.index(x["name"])) return results def make_contry_obj_from_results(result: Dict[str, Any]) -> Dict[str, Any]: slug_country = result["country"] return [{**country} for country in COUNTRIES_MAPPER if slug_country == country["code"]][0] def make_genres_obj_from_results(result: Dict[str, Any]) -> List[Dict[str, Any]]: result["genres"] = sorted(result["genres"]) return [{**genre_} for genre in result["genres"] for genre_ in GENRES_MAPPER if genre == genre_["code"]]