from collections import namedtuple from dataclasses import dataclass, field from datetime import date from typing import List, Optional GRASProjectsQueryResult = namedtuple( "GRASProjectsQueryResult", [ "project_id", "project_title", "rep_owner_key", "project_start_date", "is_deleted", "main_artist_id", "main_artist_name", "main_artist_type", "main_artist_popularity", "main_member_id", "main_member_name", "main_member_type", "main_member_popularity", "artist_id", "artist_name", "artist_type", "artist_popularity", "member_id", "member_name", "member_type", "member_popularity", ], ) GRASProductsQueryResult = namedtuple( "GRASProductsQueryResult", [ "project_id", "product_id", "product_title", "product_type", ], ) GRASRepOwnersQueryResult = namedtuple("GRASRepOwnersQueryResult", ["id", "name", "popularity"]) GRASMultiRepOwnersProjectsQueryResult = namedtuple( "GRASMultiRepOwnersProjectsQueryResult", ["project_id", "rep_owner_id", "rep_owner_popularity"] ) @dataclass class GRASArtist: id: str name: str is_main: bool = False is_primary: bool = False popularity: int = 1 def __str__(self): return f"GRAS_{self.id}|{self.name}" def __repr__(self): return self.__str__() def __eq__(self, other): if isinstance(other, GRASArtist): return self.id == other.id return False @dataclass class GRASRepertoireOwner: id: str name: str @dataclass class GRASProjectRepertoireOwner: project_id: str rep_owner_id: str popularity: int def __str__(self): return f"Project: {self.project_id}| Rep owner: {self.rep_owner_id} Popularity:{self.popularity}" @dataclass class GRASTrack: isrc: str name: str details: str type: str release_date: Optional[date] artists: List[GRASArtist] def __init__(self, isrc: str, name: str, details: str, type: str, release_date: Optional[date]): self.isrc = isrc self.name = name self.artists = [] self.details = details self.type = type self.release_date = release_date def __eq__(self, other): if isinstance(other, GRASTrack): return self.isrc == other.isrc return False def __str__(self): return f"Track: {self.isrc}| Name: {self.name} ({self.details}), Artists:\n {self.artists}" @dataclass class GRASProductModel: id: str title: str project_id: str tracks: List[GRASTrack] type: str def __init__(self, id: str, title: str, project_id: str, type: str, tracks: List[GRASTrack]): self.id = id self.title = title self.project_id = project_id self.type = type self.tracks = tracks def __eq__(self, other): if isinstance(other, GRASProductModel): return self.id == other.id return False def __str__(self): tracks_str = "\n".join([str(track) for track in self.tracks]) return f"Product: {self.id}| Name: {self.title} ({self.type}) Tracks: \n{tracks_str}" @dataclass class GRASProjectModel: id: str title: str start_date: date artists: List[GRASArtist] rep_owner_id: Optional[str] is_deleted: bool primary_artists: List[GRASArtist] = field(default_factory=list) featured_artists: List[GRASArtist] = field(default_factory=list) products: List[GRASProductModel] = field(default_factory=list) def __init__(self, id: str, title: str, rep_owner_key: str, start_date: date, deleted: bool): self.id = id self.title = title self.artists = [] self.is_deleted = deleted self.start_date = start_date self.rep_owner_id = rep_owner_key self.primary_artists = [] self.featured_artists = [] self.products = [] def sorted_artists(self) -> List[GRASArtist]: ordered_artists = sorted(self.artists, key=lambda x: (x.is_main, x.is_primary, x.popularity), reverse=True) return list(ordered_artists)