from apollo_utils.core.constants.dsp import DSP_SPOTIFY_APPLE_AMAZON from apollo_utils.service.schemas.fields.enum import EnumListField from apollo_utils.service.schemas.fields.list import SplitUniqueListField from marshmallow import ValidationError, fields, post_load, validate, validates_schema from server.constants.devices import Platform from server.constants.favorites import EntityType, SettingsType, UserFavoritesInclude from server.schemas.base.schemas import RequestSchema, Schema class AppVersion(Schema): min = fields.String(missing=None) max = fields.String(missing=None) eq = fields.String(missing=None) include_unset = fields.Boolean(missing=False) @validates_schema def validate_min_max_eq(self, data, **kwargs): if any([data["min"], data["max"]]) and data["eq"]: raise ValidationError("Only one of ['min', 'max'] or 'eq' should be filled.") class Versions(Schema): min = fields.String(missing=None) max = fields.String(missing=None) eq = fields.String(missing=None) @validates_schema def validate_min_max_eq(self, data, **kwargs): if any([data["min"], data["max"]]) and data["eq"]: raise ValidationError("Only one of ['min', 'max'] or 'eq' should be filled.") class UserFavorites: """Register favorite tracks or playlists.""" class Request(RequestSchema): class Entity(Schema): type = fields.String(validate=validate.OneOf(EntityType.values()), required=True) id = fields.List(fields.String(), required=False, validate=validate.Length(max=100)) dsp = EnumListField( DSP_SPOTIFY_APPLE_AMAZON, required=False, missing=[DSP_SPOTIFY_APPLE_AMAZON.SPOTIFY.value, DSP_SPOTIFY_APPLE_AMAZON.APPLE.value], ) class Device(Schema): is_active = fields.Boolean(missing=None, default=None) os = SplitUniqueListField( fields.String(validate=validate.OneOf(Platform.values())), ) app_version = fields.Nested(AppVersion, missing=None) class User(Schema): id = fields.List(fields.String(), required=False, validate=validate.Length(max=100)) class Account(Schema): id = fields.List(fields.Integer(), required=False, validate=validate.Length(max=100)) class Settings(Schema): type = fields.String(required=False, default=SettingsType.MOBILE) version = fields.String(required=False) versions = fields.Nested(Versions, missing=None) entity = fields.Nested(Entity, required=True) device = fields.Nested(Device, required=False) user = fields.Nested(User, required=False) account = fields.Nested(Account, required=False) settings = fields.Nested(Settings, required=False) include = SplitUniqueListField( fields.String(validate=validate.OneOf(UserFavoritesInclude.values(with_all=True))), ) @post_load def validate_user(self, data, **kwargs): if data.get("user") and data.get("account"): raise ValidationError("Only one of 'user' or 'account' is viable.") return data class Response(Schema): class Entity(Schema): class Account(Schema): class Device(Schema): id = fields.Integer() is_active = fields.Boolean() os = fields.String() expo_token = fields.String() class Settings(Schema): id = fields.Integer() type = fields.String() version = fields.String() data = fields.Dict() account_id = fields.Integer() user_id = fields.String() devices = fields.List(fields.Nested(Device)) settings = fields.Nested(Settings) entity_type = fields.String() entity_id = fields.String() accounts = fields.List(fields.Nested(Account)) data = fields.List(fields.Nested(Entity))