from apollo_utils.service.schemas.fields.datetime import DateStringField from apollo_utils.service.schemas.fields.enum import EnumField, EnumListField from apollo_utils.service.schemas.fields.list import SplitUniqueListField from apollo_utils.service.schemas.mixins.isrc import IsrcListRequiredMixin, IsrcRequiredMixin from apollo_utils.service.schemas.mixins.market import MarketListOptionalMixin from apollo_utils.service.schemas.mixins.misc import get_dependant_mixin from apollo_utils.service.schemas.mixins.search import SearchNoneLowerMixin from marshmallow import fields, validate from server.constants import DSP_SPOTIFY_APPLE from server.constants.tracks import TrackPlaylistInclude, TrackPlaylistsOrder from server.schemas.base.image import ImageSizeTrackAppleDefaultMixin from server.schemas.base.pagination import PaginationResultMixin, get_pagination_mixin from server.schemas.base.schemas import RequestSchema, Schema class TracksPlaylists: class Request( RequestSchema, SearchNoneLowerMixin, MarketListOptionalMixin, IsrcListRequiredMixin, ImageSizeTrackAppleDefaultMixin, get_pagination_mixin(page_limit=None), get_dependant_mixin( "order_by", "include", enum=TrackPlaylistsOrder, depends_mapping={ TrackPlaylistsOrder.PLAYLIST_STREAMS: TrackPlaylistInclude.PLAYLIST_STREAMS, TrackPlaylistsOrder.PLAYLIST_STREAMS_DESC: TrackPlaylistInclude.PLAYLIST_STREAMS, TrackPlaylistsOrder.TRACK_STREAMS: TrackPlaylistInclude.TRACK_STREAMS, TrackPlaylistsOrder.TRACK_STREAMS_DESC: TrackPlaylistInclude.TRACK_STREAMS, TrackPlaylistsOrder.FOLLOWERS: TrackPlaylistInclude.FOLLOWERS, TrackPlaylistsOrder.FOLLOWERS_DESC: TrackPlaylistInclude.FOLLOWERS, }, ), ): """Request schema to get track playlists.""" dsp = EnumField(DSP_SPOTIFY_APPLE, data_key="vendor", required=True) recent_adds_only = fields.Boolean(missing=False) include = EnumListField(TrackPlaylistInclude, allow_all=True, missing=[]) order_by = EnumListField(TrackPlaylistsOrder, missing=[TrackPlaylistsOrder.ADDED_DATE.value]) streams_markets_list = SplitUniqueListField( fields.String(validate=validate.Length(max=10, min=2)), data_key="streams_market", required=False, missing=None, ) class Response(Schema, PaginationResultMixin): """Track playlists output schema.""" class TrackPlaylistsItem(Schema): added_date = DateStringField() country_code = fields.String() current_position = fields.Integer() id = fields.String() image_url = fields.String() name = fields.String() personalized = fields.Boolean() position_change_date = DateStringField() track_id = fields.String() trend = fields.Integer() updated_date = DateStringField() is_new = fields.Boolean() playlist_streams = fields.Integer() track_streams = fields.Integer() followers = fields.Integer() username = fields.String() track_count = fields.Integer() items = fields.List(fields.Nested(TrackPlaylistsItem)) class TracksPlaylistsHH: class Request(RequestSchema, IsrcRequiredMixin, get_pagination_mixin(page_limit=None)): order_by = fields.List(fields.String()) include = fields.List(fields.String()) region = fields.String() class Response(Schema): class PlaylistItem(Schema): playlist_id = fields.String() playlist_name = fields.String() isrc = fields.String() code = fields.String() name = fields.String() market = fields.String() region = fields.String() entry_date = DateStringField() position = fields.Integer() previous_position = fields.Integer() position_change = fields.Integer() peak_position = fields.Integer() latest_date = DateStringField() image_url = fields.String() added_days = fields.Integer() is_new = fields.Boolean() top_market = fields.Integer() class RegionItem(Schema): name = fields.String() code = fields.String() placements = fields.Integer() total = fields.Integer() count = fields.Integer() items = fields.List(fields.Nested(PlaylistItem)) total = fields.Integer() positions_avg = fields.Integer() positions_top_total = fields.Integer() regions = fields.List(fields.Nested(RegionItem)) class HotHitsPlaylistItem(Schema): playlist_id = fields.String() market = fields.String() rank = fields.Integer() region = fields.String() playlist_name = fields.String() playlist_image = fields.String() class TracksPlaylistsHHBulk: class Request(RequestSchema, IsrcListRequiredMixin): pass class Response(Schema): class FullPlaylistItem(HotHitsPlaylistItem): latest_date = DateStringField() class TrackItem(Schema): class TrackPlaylistItem(HotHitsPlaylistItem): entry_date = DateStringField() peak_position = fields.Integer() peak_date = DateStringField() class PreviousTrackPlaylistItem(TrackPlaylistItem): exit_date = DateStringField() class CurrentTrackPlaylistItem(TrackPlaylistItem): position = fields.Integer() trend = fields.Integer() is_entry = fields.Boolean() isrc = fields.String(required=True) non_featured = fields.Nested(HotHitsPlaylistItem, many=True) previous = fields.Nested(PreviousTrackPlaylistItem, many=True) current = fields.Nested(CurrentTrackPlaylistItem, many=True) avg_position = fields.Integer() current_count = fields.Integer() items = fields.Nested(TrackItem, many=True) hot_hits_date = DateStringField(required=True) regions = fields.List(fields.String()) outdated = fields.Nested(HotHitsPlaylistItem, many=True) playlists = fields.Nested(FullPlaylistItem, many=True) playlists_by_markets = fields.Dict(fields.String())