diff --git a/YandexMusic.API/API/YAlbumAPI.cs b/YandexMusic.API/API/YAlbumAPI.cs index 5d2d11f..8c52247 100644 --- a/YandexMusic.API/API/YAlbumAPI.cs +++ b/YandexMusic.API/API/YAlbumAPI.cs @@ -5,34 +5,24 @@ using YandexMusic.API.Requests.Album; namespace YandexMusic.API; -/// -/// API для взаимодействия с альбомами -/// +/// API для работы с альбомами. public class YAlbumAPI : YCommonAPI { - public YAlbumAPI(YandexMusicApi yandex) : base(yandex) - { - } + /// Инициализирует новый экземпляр API альбомов. + /// Экземпляр основного API. + public YAlbumAPI(YandexMusicApi yandex) : base(yandex) { } /// Получает альбом по идентификатору. - /// Хранилище авторизации. - /// Идентификатор альбома. - /// + /// Хранилище данных авторизации. + /// Идентификатор альбома. + /// Ответ API с моделью альбома. public Task> GetAsync(AuthStorage storage, string albumId) - { - return new YGetAlbumBuilder(api, storage) - .Build(albumId) - .GetResponseAsync(); - } + => new YGetAlbumBuilder(api, storage).Build(albumId).GetResponseAsync(); - /// Получение альбомов по списку идентификаторов. - /// Хранилище авторизации. - /// Идентификаторы альбомов. - /// + /// Получает несколько альбомов по списку идентификаторов. + /// Хранилище данных авторизации. + /// Список идентификаторов альбомов. + /// Ответ API со списком альбомов. public Task>> GetAsync(AuthStorage storage, IEnumerable albumIds) - { - return new YGetAlbumsBuilder(api, storage) - .Build(albumIds) - .GetResponseAsync(); - } + => new YGetAlbumsBuilder(api, storage).Build(albumIds).GetResponseAsync(); } \ No newline at end of file diff --git a/YandexMusic.API/API/YCommonAPI.cs b/YandexMusic.API/API/YCommonAPI.cs index d066141..b0f63dc 100644 --- a/YandexMusic.API/API/YCommonAPI.cs +++ b/YandexMusic.API/API/YCommonAPI.cs @@ -1,14 +1,12 @@ namespace YandexMusic.API; -/// -/// Родительский класс для ветки API -/// -public class YCommonAPI +/// Родительский класс для всех веток API. +public abstract class YCommonAPI { - protected YandexMusicApi api; + /// Основной экземпляр API. + protected readonly YandexMusicApi api; - public YCommonAPI(YandexMusicApi yandex) - { - api = yandex; - } -} + /// Инициализирует новый экземпляр. + /// Экземпляр основного API. + protected YCommonAPI(YandexMusicApi yandex) => api = yandex; +} \ No newline at end of file diff --git a/YandexMusic.API/API/YLabelAPI.cs b/YandexMusic.API/API/YLabelAPI.cs new file mode 100644 index 0000000..42b53c8 --- /dev/null +++ b/YandexMusic.API/API/YLabelAPI.cs @@ -0,0 +1,39 @@ +using YandexMusic.API.Common; +using YandexMusic.API.Models.Common; +using YandexMusic.API.Models.Label; +using YandexMusic.API.Requests.Label; + +namespace YandexMusic.API; + +public partial class YLabelAPI : YCommonAPI +{ + public YLabelAPI(YandexMusicApi yandex) : base(yandex) + { + } + + /// + /// Постраничное получение альбомов лейбла + /// + /// Хранилище + /// Лейбл + /// Страница + public Task> GetAlbumsByLabelAsync(AuthStorage storage, YLabel label, int page) + { + return new YGetLabelAlbumsBuilder(api, storage) + .Build((label, page)) + .GetResponseAsync(); + } + + /// + /// Постраничное получение артистов лейбла + /// + /// Хранилище + /// Лейбл + /// Страница + public Task> GetArtistsByLabelAsync(AuthStorage storage, YLabel label, int page) + { + return new YGetLabelArtistsBuilder(api, storage) + .Build((label, page)) + .GetResponseAsync(); + } +} \ No newline at end of file diff --git a/YandexMusic.API/API/YLabelAPIAsync.cs b/YandexMusic.API/API/YLabelAPIAsync.cs deleted file mode 100644 index eeac03b..0000000 --- a/YandexMusic.API/API/YLabelAPIAsync.cs +++ /dev/null @@ -1,40 +0,0 @@ -using YandexMusic.API.Common; -using YandexMusic.API.Models.Common; -using YandexMusic.API.Models.Label; -using YandexMusic.API.Requests.Label; - -namespace YandexMusic.API -{ - public partial class YLabelAPI : YCommonAPI - { - public YLabelAPI(YandexMusicApi yandex) : base(yandex) - { - } - - /// - /// Постраничное получение альбомов лейбла - /// - /// Хранилище - /// Лейбл - /// Страница - public Task> GetAlbumsByLabelAsync(AuthStorage storage, YLabel label, int page) - { - return new YGetLabelAlbumsBuilder(api, storage) - .Build((label, page)) - .GetResponseAsync(); - } - - /// - /// Постраничное получение артистов лейбла - /// - /// Хранилище - /// Лейбл - /// Страница - public Task> GetArtistsByLabelAsync(AuthStorage storage, YLabel label, int page) - { - return new YGetLabelArtistsBuilder(api, storage) - .Build((label, page)) - .GetResponseAsync(); - } - } -} \ No newline at end of file diff --git a/YandexMusic.API/API/YLandingAPI.cs b/YandexMusic.API/API/YLandingAPI.cs new file mode 100644 index 0000000..b91cecc --- /dev/null +++ b/YandexMusic.API/API/YLandingAPI.cs @@ -0,0 +1,43 @@ +using YandexMusic.API.Common; +using YandexMusic.API.Models.Common; +using YandexMusic.API.Models.Feed; +using YandexMusic.API.Models.Landing; +using YandexMusic.API.Requests.Feed; +using YandexMusic.API.Requests.Landing; + +namespace YandexMusic.API; + +/// API для взаимодействия с главной страницей (лендингом). +public class YLandingAPI : YCommonAPI +{ + /// Инициализирует новый экземпляр API лендинга. + /// Экземпляр основного API. + public YLandingAPI(YandexMusicApi yandex) : base(yandex) { } + + /// Получает персональные блоки лендинга. + /// Хранилище авторизации. + /// Типы запрашиваемых блоков. + /// Ответ API с лендингом. + /// Если массив blocks равен null. + public Task> GetAsync(AuthStorage storage, params YLandingBlockType[] blocks) + { + if (blocks == null) + throw new ArgumentNullException(nameof(blocks), "Массив блоков не может быть null"); + + return new YGetLandingBuilder(api, storage) + .Build(blocks) + .GetResponseAsync(); + } + + /// Получает ленту событий (фид). + /// Хранилище авторизации. + /// Ответ API с лентой. + public Task> GetFeedAsync(AuthStorage storage) + => new YGetFeedBuilder(api, storage).Build(null!).GetResponseAsync(); + + /// Получает лендинг детского раздела. + /// Хранилище авторизации. + /// Ответ API с детским лендингом. + public Task> GetChildrenLandingAsync(AuthStorage storage) + => new YGetChildrenLandingBuilder(api, storage).Build(null!).GetResponseAsync(); +} \ No newline at end of file diff --git a/YandexMusic.API/API/YLandingAPIAsync.cs b/YandexMusic.API/API/YLandingAPIAsync.cs deleted file mode 100644 index 8ff4fe9..0000000 --- a/YandexMusic.API/API/YLandingAPIAsync.cs +++ /dev/null @@ -1,63 +0,0 @@ -using YandexMusic.API.Common; -using YandexMusic.API.Models.Common; -using YandexMusic.API.Models.Feed; -using YandexMusic.API.Models.Landing; -using YandexMusic.API.Requests.Feed; -using YandexMusic.API.Requests.Landing; - -namespace YandexMusic.API -{ - /// - /// API для взаимодействия с главной страницей - /// - public partial class YLandingAPI : YCommonAPI - { - - - public YLandingAPI(YandexMusicApi yandex) : base(yandex) - { - } - - /// - /// Получение персональных списков - /// - /// Хранилище - /// Типы запрашиваемых блоков - /// - public Task> GetAsync(AuthStorage storage, params YLandingBlockType[] blocks) - { - if (blocks == null) - return null; - - return new YGetLandingBuilder(api, storage) - .Build(blocks) - .GetResponseAsync(); - } - - /// - /// Получение ленты - /// - /// Хранилище - /// - public Task> GetFeedAsync(AuthStorage storage) - { - return new YGetFeedBuilder(api, storage) - .Build(null) - .GetResponseAsync(); - } - - /// - /// Получение лендинга детского раздела - /// - /// Хранилище - /// - public Task> GetChildrenLandingAsync(AuthStorage storage) - { - return new YGetChildrenLandingBuilder(api, storage) - .Build(null) - .GetResponseAsync(); - } - - - } -} \ No newline at end of file diff --git a/YandexMusic.API/API/YLibraryAPI.cs b/YandexMusic.API/API/YLibraryAPI.cs new file mode 100644 index 0000000..df1b86c --- /dev/null +++ b/YandexMusic.API/API/YLibraryAPI.cs @@ -0,0 +1,253 @@ +using YandexMusic.API.Common; +using YandexMusic.API.Models.Album; +using YandexMusic.API.Models.Artist; +using YandexMusic.API.Models.Common; +using YandexMusic.API.Models.Landing.Entity.Entities.Context; +using YandexMusic.API.Models.Library; +using YandexMusic.API.Models.Playlist; +using YandexMusic.API.Models.Track; +using YandexMusic.API.Requests.Library; + +namespace YandexMusic.API; + +/// +/// API для взаимодействия с библиотекой +/// +public partial class YLibraryAPI : YCommonAPI +{ + /// + /// Получение секции библиотеки + /// + /// Тип объекта библиотеки + /// Хранилище + /// Секция + /// Тип + /// Список объектов из секции + private Task> GetLibrarySection(AuthStorage storage, YLibrarySection section, YLibrarySectionType type = YLibrarySectionType.Likes) + { + return new YGetLibrarySectionBuilder(api, storage) + .Build((section, type)) + .GetResponseAsync(); + } + + + + public YLibraryAPI(YandexMusicApi yandex) : base(yandex) + { + } + + #region Лайки + + /// + /// Получение лайкнутых треков + /// + /// Хранилище + /// + public Task> GetLikedTracksAsync(AuthStorage storage) + { + return GetLibrarySection(storage, YLibrarySection.Tracks); + } + + /// + /// Получение лайкнутых альбомов + /// + /// Хранилище + /// + public Task>> GetLikedAlbumsAsync(AuthStorage storage) + { + return GetLibrarySection>(storage, YLibrarySection.Albums); + } + + /// + /// Получение лайкнутых исполнителей + /// + /// Хранилище + /// + public Task>> GetLikedArtistsAsync(AuthStorage storage) + { + return GetLibrarySection>(storage, YLibrarySection.Artists); + } + + /// + /// Получение лайкнутых плейлистов + /// + /// Хранилище + /// + public Task>> GetLikedPlaylistsAsync(AuthStorage storage) + { + return GetLibrarySection>(storage, YLibrarySection.Playlists); + } + + #endregion Лайки + + #region Дизлайки + + /// + /// Получение дизлайкнутых треков + /// + /// Хранилище + /// + public Task> GetDislikedTracksAsync(AuthStorage storage) + { + return GetLibrarySection(storage, YLibrarySection.Tracks, YLibrarySectionType.Dislikes); + } + + /// + /// Получение дизлайкнутых исполнителей + /// + /// Хранилище + /// + public Task>> GetDislikedArtistsAsync(AuthStorage storage) + { + return GetLibrarySection>(storage, YLibrarySection.Artists, YLibrarySectionType.Dislikes); + } + + #endregion Дизлайки + + #region Добавление в списки лайков/дизлайков + + /// + /// Добавить трек в список лайкнутых + /// + /// Хранилище + /// Трек + /// + public Task> AddTrackLikeAsync(AuthStorage storage, YTrack track) + { + return new YLibraryAddBuilder(api, storage) + .Build((track.GetKey().ToString(), YLibrarySection.Tracks, YLibrarySectionType.Likes)) + .GetResponseAsync(); + } + + /// + /// Удалить трек из списка лайкнутых + /// + /// Хранилище + /// Трек + /// + public Task> RemoveTrackLikeAsync(AuthStorage storage, YTrack track) + { + return new YLibraryRemoveBuilder(api, storage) + .Build((track.GetKey().ToString(), YLibrarySection.Tracks, YLibrarySectionType.Likes)) + .GetResponseAsync(); + } + + /// + /// Добавить трек в список дизлайкнутых + /// + /// Хранилище + /// Трек + /// + public Task> AddTrackDislikeAsync(AuthStorage storage, YTrack track) + { + return new YLibraryAddBuilder(api, storage) + .Build((track.GetKey().ToString(), YLibrarySection.Tracks, YLibrarySectionType.Dislikes)) + .GetResponseAsync(); + } + + /// + /// Удалить трек из списка дизлайкнутых + /// + /// Хранилище + /// Трек + /// + public Task> RemoveTrackDislikeAsync(AuthStorage storage, YTrack track) + { + return new YLibraryRemoveBuilder(api, storage) + .Build((track.GetKey().ToString(), YLibrarySection.Tracks, YLibrarySectionType.Dislikes)) + .GetResponseAsync(); + } + + /// + /// Добавить альбом в список лайкнутых + /// + /// Хранилище + /// Альбом + /// + public Task> AddAlbumLikeAsync(AuthStorage storage, YAlbum album) + { + return new YLibraryAddBuilder(api, storage) + .Build((album.Id, YLibrarySection.Albums, YLibrarySectionType.Likes)) + .GetResponseAsync(); + } + + /// + /// Удалить альбом из списка лайкнутых + /// + /// Хранилище + /// Альбом + /// + public Task> RemoveAlbumLikeAsync(AuthStorage storage, YAlbum album) + { + return new YLibraryRemoveBuilder(api, storage) + .Build((album.Id, YLibrarySection.Albums, YLibrarySectionType.Likes)) + .GetResponseAsync(); + } + + /// + /// Добавить исполнителя в список лайкнутых + /// + /// Хранилище + /// Исполнитель + /// + public Task> AddArtistLikeAsync(AuthStorage storage, YArtist artist) + { + return new YLibraryAddBuilder(api, storage) + .Build((artist.Id, YLibrarySection.Artists, YLibrarySectionType.Likes)) + .GetResponseAsync(); + } + + /// + /// Удалить исполнителя из списка лайкнутых + /// + /// Хранилище + /// Исполнитель + /// + public Task> RemoveArtistLikeAsync(AuthStorage storage, YArtist artist) + { + return new YLibraryRemoveBuilder(api, storage) + .Build((artist.Id, YLibrarySection.Artists, YLibrarySectionType.Likes)) + .GetResponseAsync(); + } + + /// + /// Добавить плейлист в список лайкнутых + /// + /// Хранилище + /// Плейлист + /// + public Task> AddPlaylistLikeAsync(AuthStorage storage, YPlaylist playlist) + { + return new YLibraryAddBuilder(api, storage) + .Build((playlist.GetKey().ToString(), YLibrarySection.Playlists, YLibrarySectionType.Likes)) + .GetResponseAsync(); + } + + /// + /// Удалить плейлист из списка лайкнутых + /// + /// Хранилище + /// Плейлист + /// + public Task> RemovePlaylistLikeAsync(AuthStorage storage, YPlaylist playlist) + { + return new YLibraryRemoveBuilder(api, storage) + .Build((playlist.GetKey().ToString(), YLibrarySection.Playlists, YLibrarySectionType.Likes)) + .GetResponseAsync(); + } + + #endregion Добавление/удаление в списки лайков/дизлайков + + #region Получение списка "Вы недавно слушали" + + public Task> GetRecentlyListenedAsync(AuthStorage storage, IEnumerable contextTypes, int trackCount, int contextCount) + { + return new YGetLibraryRecentlyListenedBuilder(api, storage) + .Build((contextTypes, trackCount, contextCount)) + .GetResponseAsync(); + } + + #endregion Получение списка "Вы недавно слушали" + + +} \ No newline at end of file diff --git a/YandexMusic.API/API/YLibraryAPIAsync.cs b/YandexMusic.API/API/YLibraryAPIAsync.cs deleted file mode 100644 index 46b5209..0000000 --- a/YandexMusic.API/API/YLibraryAPIAsync.cs +++ /dev/null @@ -1,258 +0,0 @@ -using YandexMusic.API.Common; -using YandexMusic.API.Models.Album; -using YandexMusic.API.Models.Artist; -using YandexMusic.API.Models.Common; -using YandexMusic.API.Models.Landing.Entity.Entities.Context; -using YandexMusic.API.Models.Library; -using YandexMusic.API.Models.Playlist; -using YandexMusic.API.Models.Track; -using YandexMusic.API.Requests.Library; - -namespace YandexMusic.API -{ - /// - /// API для взаимодействия с библиотекой - /// - public partial class YLibraryAPI : YCommonAPI - { - #region Вспомогательные функции - - /// - /// Получение секции библиотеки - /// - /// Тип объекта библиотеки - /// Хранилище - /// Секция - /// Тип - /// Список объектов из секции - private Task> GetLibrarySection(AuthStorage storage, YLibrarySection section, YLibrarySectionType type = YLibrarySectionType.Likes) - { - return new YGetLibrarySectionBuilder(api, storage) - .Build((section, type)) - .GetResponseAsync(); - } - - #endregion Вспомогательные функции - - - - public YLibraryAPI(YandexMusicApi yandex) : base(yandex) - { - } - - #region Лайки - - /// - /// Получение лайкнутых треков - /// - /// Хранилище - /// - public Task> GetLikedTracksAsync(AuthStorage storage) - { - return GetLibrarySection(storage, YLibrarySection.Tracks); - } - - /// - /// Получение лайкнутых альбомов - /// - /// Хранилище - /// - public Task>> GetLikedAlbumsAsync(AuthStorage storage) - { - return GetLibrarySection>(storage, YLibrarySection.Albums); - } - - /// - /// Получение лайкнутых исполнителей - /// - /// Хранилище - /// - public Task>> GetLikedArtistsAsync(AuthStorage storage) - { - return GetLibrarySection>(storage, YLibrarySection.Artists); - } - - /// - /// Получение лайкнутых плейлистов - /// - /// Хранилище - /// - public Task>> GetLikedPlaylistsAsync(AuthStorage storage) - { - return GetLibrarySection>(storage, YLibrarySection.Playlists); - } - - #endregion Лайки - - #region Дизлайки - - /// - /// Получение дизлайкнутых треков - /// - /// Хранилище - /// - public Task> GetDislikedTracksAsync(AuthStorage storage) - { - return GetLibrarySection(storage, YLibrarySection.Tracks, YLibrarySectionType.Dislikes); - } - - /// - /// Получение дизлайкнутых исполнителей - /// - /// Хранилище - /// - public Task>> GetDislikedArtistsAsync(AuthStorage storage) - { - return GetLibrarySection>(storage, YLibrarySection.Artists, YLibrarySectionType.Dislikes); - } - - #endregion Дизлайки - - #region Добавление в списки лайков/дизлайков - - /// - /// Добавить трек в список лайкнутых - /// - /// Хранилище - /// Трек - /// - public Task> AddTrackLikeAsync(AuthStorage storage, YTrack track) - { - return new YLibraryAddBuilder(api, storage) - .Build((track.GetKey().ToString(), YLibrarySection.Tracks, YLibrarySectionType.Likes)) - .GetResponseAsync(); - } - - /// - /// Удалить трек из списка лайкнутых - /// - /// Хранилище - /// Трек - /// - public Task> RemoveTrackLikeAsync(AuthStorage storage, YTrack track) - { - return new YLibraryRemoveBuilder(api, storage) - .Build((track.GetKey().ToString(), YLibrarySection.Tracks, YLibrarySectionType.Likes)) - .GetResponseAsync(); - } - - /// - /// Добавить трек в список дизлайкнутых - /// - /// Хранилище - /// Трек - /// - public Task> AddTrackDislikeAsync(AuthStorage storage, YTrack track) - { - return new YLibraryAddBuilder(api, storage) - .Build((track.GetKey().ToString(), YLibrarySection.Tracks, YLibrarySectionType.Dislikes)) - .GetResponseAsync(); - } - - /// - /// Удалить трек из списка дизлайкнутых - /// - /// Хранилище - /// Трек - /// - public Task> RemoveTrackDislikeAsync(AuthStorage storage, YTrack track) - { - return new YLibraryRemoveBuilder(api, storage) - .Build((track.GetKey().ToString(), YLibrarySection.Tracks, YLibrarySectionType.Dislikes)) - .GetResponseAsync(); - } - - /// - /// Добавить альбом в список лайкнутых - /// - /// Хранилище - /// Альбом - /// - public Task> AddAlbumLikeAsync(AuthStorage storage, YAlbum album) - { - return new YLibraryAddBuilder(api, storage) - .Build((album.Id, YLibrarySection.Albums, YLibrarySectionType.Likes)) - .GetResponseAsync(); - } - - /// - /// Удалить альбом из списка лайкнутых - /// - /// Хранилище - /// Альбом - /// - public Task> RemoveAlbumLikeAsync(AuthStorage storage, YAlbum album) - { - return new YLibraryRemoveBuilder(api, storage) - .Build((album.Id, YLibrarySection.Albums, YLibrarySectionType.Likes)) - .GetResponseAsync(); - } - - /// - /// Добавить исполнителя в список лайкнутых - /// - /// Хранилище - /// Исполнитель - /// - public Task> AddArtistLikeAsync(AuthStorage storage, YArtist artist) - { - return new YLibraryAddBuilder(api, storage) - .Build((artist.Id, YLibrarySection.Artists, YLibrarySectionType.Likes)) - .GetResponseAsync(); - } - - /// - /// Удалить исполнителя из списка лайкнутых - /// - /// Хранилище - /// Исполнитель - /// - public Task> RemoveArtistLikeAsync(AuthStorage storage, YArtist artist) - { - return new YLibraryRemoveBuilder(api, storage) - .Build((artist.Id, YLibrarySection.Artists, YLibrarySectionType.Likes)) - .GetResponseAsync(); - } - - /// - /// Добавить плейлист в список лайкнутых - /// - /// Хранилище - /// Плейлист - /// - public Task> AddPlaylistLikeAsync(AuthStorage storage, YPlaylist playlist) - { - return new YLibraryAddBuilder(api, storage) - .Build((playlist.GetKey().ToString(), YLibrarySection.Playlists, YLibrarySectionType.Likes)) - .GetResponseAsync(); - } - - /// - /// Удалить плейлист из списка лайкнутых - /// - /// Хранилище - /// Плейлист - /// - public Task> RemovePlaylistLikeAsync(AuthStorage storage, YPlaylist playlist) - { - return new YLibraryRemoveBuilder(api, storage) - .Build((playlist.GetKey().ToString(), YLibrarySection.Playlists, YLibrarySectionType.Likes)) - .GetResponseAsync(); - } - - #endregion Добавление/удаление в списки лайков/дизлайков - - #region Получение списка "Вы недавно слушали" - - public Task> GetRecentlyListenedAsync(AuthStorage storage, IEnumerable contextTypes, int trackCount, int contextCount) - { - return new YGetLibraryRecentlyListenedBuilder(api, storage) - .Build((contextTypes, trackCount, contextCount)) - .GetResponseAsync(); - } - - #endregion Получение списка "Вы недавно слушали" - - - } -} \ No newline at end of file diff --git a/YandexMusic.API/API/YPinsAPI.cs b/YandexMusic.API/API/YPinsAPI.cs new file mode 100644 index 0000000..bc1dc4f --- /dev/null +++ b/YandexMusic.API/API/YPinsAPI.cs @@ -0,0 +1,20 @@ +using YandexMusic.API.Common; +using YandexMusic.API.Models.Common; +using YandexMusic.API.Models.Pins; +using YandexMusic.API.Requests.Pins; + +namespace YandexMusic.API; + +/// API для взаимодействия с закреплёнными объектами (пинами). +public class YPinsAPI : YCommonAPI +{ + /// Инициализирует новый экземпляр API пинов. + /// Экземпляр основного API. + public YPinsAPI(YandexMusicApi yandex) : base(yandex) { } + + /// Получает список закреплённых объектов. + /// Хранилище авторизации. + /// Ответ API со списком пинов. + public Task> GetAsync(AuthStorage storage) + => new YGetPinsBuilder(api, storage).Build(null!).GetResponseAsync(); +} \ No newline at end of file diff --git a/YandexMusic.API/API/YPinsAPIAsync.cs b/YandexMusic.API/API/YPinsAPIAsync.cs deleted file mode 100644 index 279e323..0000000 --- a/YandexMusic.API/API/YPinsAPIAsync.cs +++ /dev/null @@ -1,33 +0,0 @@ -using YandexMusic.API.Common; -using YandexMusic.API.Models.Common; -using YandexMusic.API.Models.Pins; -using YandexMusic.API.Requests.Pins; - -namespace YandexMusic.API -{ - /// - /// API для взаимодействия с прикреплёнными объектами - /// - public partial class YPinsAPI : YCommonAPI - { - - - public YPinsAPI(YandexMusicApi yandex) : base(yandex) - { - } - - /// - /// Получение списка прикреплённых объектов - /// - /// Хранилище - /// - public Task> GetAsync(AuthStorage storage) - { - return new YGetPinsBuilder(api, storage) - .Build(null) - .GetResponseAsync(); - } - - - } -} \ No newline at end of file diff --git a/YandexMusic.API/API/YPlaylistAPI.cs b/YandexMusic.API/API/YPlaylistAPI.cs new file mode 100644 index 0000000..985b331 --- /dev/null +++ b/YandexMusic.API/API/YPlaylistAPI.cs @@ -0,0 +1,149 @@ +using YandexMusic.API.Common; +using YandexMusic.API.Models.Common; +using YandexMusic.API.Models.Landing; +using YandexMusic.API.Models.Landing.Entity.Entities; +using YandexMusic.API.Models.Playlist; +using YandexMusic.API.Models.Track; +using YandexMusic.API.Requests.Playlist; + +namespace YandexMusic.API; + +/// API для взаимодействия с плейлистами. +public class YPlaylistAPI : YCommonAPI +{ + /// Инициализирует новый экземпляр API плейлистов. + /// Экземпляр основного API. + public YPlaylistAPI(YandexMusicApi yandex) : base(yandex) { } + + /// Получает список персональных плейлистов с главной страницы. + /// Хранилище авторизации. + /// Список ответов с плейлистами. + public async Task>> GetPersonalPlaylistsAsync(AuthStorage storage) + { + var landing = await api.Landing.GetAsync(storage, YLandingBlockType.PersonalPlaylists); + var block = landing.Result?.Blocks?.FirstOrDefault(b => b.Type == YLandingBlockType.PersonalPlaylists); + if (block?.Entities == null) + return new List>(); + + var tasks = block.Entities + .OfType() + .Select(e => api.Playlist.GetAsync(storage, e.Data?.Data)); + + return new List>(await Task.WhenAll(tasks)); + } + + /// Получает избранные плейлисты. + public Task>> FavoritesAsync(AuthStorage storage) + => new YGetPlaylistFavoritesBuilder(api, storage).Build(null!).GetResponseAsync(); + + /// Получает плейлист дня. + public Task> OfTheDayAsync(AuthStorage storage) + => GetPersonalPlaylistAsync(storage, YGeneratedPlaylistType.PlaylistOfTheDay); + + /// Получает плейлист «Дежавю». + public Task> DejaVuAsync(AuthStorage storage) + => GetPersonalPlaylistAsync(storage, YGeneratedPlaylistType.NeverHeard); + + /// Получает плейлист «Премьера». + public Task> PremiereAsync(AuthStorage storage) + => GetPersonalPlaylistAsync(storage, YGeneratedPlaylistType.RecentTracks); + + /// Получает плейлист «Тайник». + public Task> MissedAsync(AuthStorage storage) + => GetPersonalPlaylistAsync(storage, YGeneratedPlaylistType.MissedLikes); + + /// Получает плейлист «Кинопоиск». + public Task> KinopoiskAsync(AuthStorage storage) + => GetPersonalPlaylistAsync(storage, YGeneratedPlaylistType.Kinopoisk); + + private async Task> GetPersonalPlaylistAsync(AuthStorage storage, YGeneratedPlaylistType type) + { + var list = await GetPersonalPlaylistsAsync(storage); + return list.FirstOrDefault(e => string.Equals(e.Result?.GeneratedPlaylistType, type.ToString(), StringComparison.CurrentCultureIgnoreCase)) + ?? throw new Exception($"Плейлист типа {type} не найден."); + } + + /// Получает плейлист по идентификатору пользователя и типа. + public Task> GetAsync(AuthStorage storage, string user, string kind) + => new YGetPlaylistBuilder(api, storage).Build((user, kind)).GetResponseAsync(); + + /// Получает плейлист по UUID. + public Task> GetAsync(AuthStorage storage, string uuid) + => new YGetPlaylistByUuidBuilder(api, storage).Build(uuid).GetResponseAsync(); + + /// Получает несколько плейлистов по списку пар (пользователь, тип). + public Task>> GetAsync(AuthStorage storage, IEnumerable<(string user, string kind)> ids) + => new YGetPlaylistsBuilder(api, storage).Build(ids).GetResponseAsync(); + + /// Получает плейлист по объекту плейлиста (обновляет его треки). + public Task> GetAsync(AuthStorage storage, YPlaylist playlist) + => new YGetPlaylistBuilder(api, storage).Build((playlist.Owner.Uid, playlist.Kind)).GetResponseAsync(); + + /// Создаёт новый плейлист с заданным именем. + public Task> CreateAsync(AuthStorage storage, string name) + => new YPlaylistCreateBuilder(api, storage).Build(name).GetResponseAsync(); + + /// Переименовывает плейлист. + public Task> RenameAsync(AuthStorage storage, string kind, string name) + => new YPlaylistRenameBuilder(api, storage).Build((kind, name)).GetResponseAsync(); + + /// Переименовывает плейлист. + public Task> RenameAsync(AuthStorage storage, YPlaylist playlist, string name) + => RenameAsync(storage, playlist.Kind, name); + + /// Удаляет плейлист. + public async Task DeleteAsync(AuthStorage storage, string kind) + { + try + { + await new YPlaylistRemoveBuilder(api, storage).Build(kind).GetResponseAsync(); + return true; + } + catch (Exception ex) + { + // Логирование ошибки можно добавить через ILogger + return false; + } + } + + /// Удаляет плейлист. + public Task DeleteAsync(AuthStorage storage, YPlaylist playlist) + => DeleteAsync(storage, playlist.Kind); + + /// Добавляет треки в начало плейлиста. + public async Task> InsertTracksAsync(AuthStorage storage, YPlaylist playlist, IEnumerable tracks) + { + var change = await ChangePlaylistAsync(storage, playlist, new List + { + new() + { + Operation = YPlaylistChangeType.Insert, + At = 0, + Tracks = tracks.Select(t => t.GetKey()) + } + }); + return await GetAsync(storage, change.Result); + } + + /// Удаляет треки из плейлиста. + public Task> DeleteTracksAsync(AuthStorage storage, YPlaylist playlist, IEnumerable tracks) + { + var distinctTracks = tracks.Distinct().ToList(); + var changes = distinctTracks + .Select(t => playlist.Tracks?.FindIndex(ct => ct.Track?.GetKey() == t.GetKey()) ?? -1) + .Where(i => i != -1) + .Select(i => new YPlaylistChange + { + Operation = YPlaylistChangeType.Delete, + From = i, + To = i + 1, + Tracks = new List { playlist.Tracks![i].Track!.GetKey() } + }) + .ToList(); + + return ChangePlaylistAsync(storage, playlist, changes); + } + + private Task> ChangePlaylistAsync(AuthStorage storage, YPlaylist playlist, IEnumerable changes) + => new YPlaylistChangeBuilder(api, storage).Build((playlist, changes)).GetResponseAsync(); +} \ No newline at end of file diff --git a/YandexMusic.API/API/YPlaylistAPIAsync.cs b/YandexMusic.API/API/YPlaylistAPIAsync.cs deleted file mode 100644 index cf94f73..0000000 --- a/YandexMusic.API/API/YPlaylistAPIAsync.cs +++ /dev/null @@ -1,335 +0,0 @@ -using YandexMusic.API.Common; -using YandexMusic.API.Models.Common; -using YandexMusic.API.Models.Landing; -using YandexMusic.API.Models.Landing.Entity.Entities; -using YandexMusic.API.Models.Playlist; -using YandexMusic.API.Models.Track; -using YandexMusic.API.Requests.Playlist; - -namespace YandexMusic.API -{ - /// - /// API для взамодействия с плейлистами - /// - public partial class YPlaylistAPI : YCommonAPI - { - #region Вспомогательные функции - - /// - /// Получение персональных плейлистов - /// - /// Хранилище - /// Тип - /// Плейлист - private async Task> GetPersonalPlaylist(AuthStorage storage, YGeneratedPlaylistType type) - { - List> list = await GetPersonalPlaylistsAsync(storage); - return list.FirstOrDefault(e => string.Equals(e.Result.GeneratedPlaylistType, type.ToString(), StringComparison.CurrentCultureIgnoreCase)); - } - - /// - /// Изменение плейлиста - /// - /// Хранилище - /// Плейлист - /// Список изменений - /// Плейлист после изменений - private Task> ChangePlaylist(AuthStorage storage, YPlaylist playlist, IEnumerable changes) - { - return new YPlaylistChangeBuilder(api, storage) - .Build((playlist, changes)) - .GetResponseAsync(); - } - - private IEnumerable RemoveIdentical(IEnumerable tracks) - { - return tracks.Distinct(); - } - - #endregion Вспомогательные функции - - - - public YPlaylistAPI(YandexMusicApi yandex) : base(yandex) - { - } - - #region Список с главной - - /// - /// Получение списка персональных плейлистов - /// - /// Хранилище - /// - public async Task>> GetPersonalPlaylistsAsync(AuthStorage storage) - { - YResponse landing = await api.Landing.GetAsync(storage, YLandingBlockType.PersonalPlaylists); - - IEnumerable>> tasks = landing - .Result - .Blocks - .FirstOrDefault(b => b.Type == YLandingBlockType.PersonalPlaylists) - ?.Entities - .Select(e => api.Playlist.GetAsync(storage, ((YLandingEntityPersonalPlaylist)e).Data?.Data)); - - return tasks == null - ? new List>() - : new List>(await Task.WhenAll(tasks)); - } - - #endregion Список с главной - - #region Стандартные плейлисты - - /// - /// Избранное - /// - /// Хранилище - /// - public Task>> FavoritesAsync(AuthStorage storage) - { - return new YGetPlaylistFavoritesBuilder(api, storage) - .Build(null) - .GetResponseAsync(); - } - - /// - /// Плейлист дня - /// - /// Хранилище - /// - public Task> OfTheDayAsync(AuthStorage storage) - { - return GetPersonalPlaylist(storage, YGeneratedPlaylistType.PlaylistOfTheDay); - } - - /// - /// Дежавю - /// - /// Хранилище - /// - public Task> DejaVuAsync(AuthStorage storage) - { - return GetPersonalPlaylist(storage, YGeneratedPlaylistType.NeverHeard); - } - - /// - /// Премьера - /// - /// Хранилище - /// - public Task> PremiereAsync(AuthStorage storage) - { - return GetPersonalPlaylist(storage, YGeneratedPlaylistType.RecentTracks); - } - - /// - /// Тайник - /// - /// Хранилище - /// - public Task> MissedAsync(AuthStorage storage) - { - return GetPersonalPlaylist(storage, YGeneratedPlaylistType.MissedLikes); - } - - /// - /// Кинопоиск - /// - /// Хранилище - /// - public Task> KinopoiskAsync(AuthStorage storage) - { - return GetPersonalPlaylist(storage, YGeneratedPlaylistType.Kinopoisk); - } - - #endregion Стандартные плейлисты - - #region Получение плейлиста - - /// - /// Получение плейлиста - /// - /// Хранилище - /// Uid пользователя-владельца плейлиста - /// Тип - /// - public Task> GetAsync(AuthStorage storage, string user, string kind) - { - return new YGetPlaylistBuilder(api, storage) - .Build((user, kind)) - .GetResponseAsync(); - } - - /// - /// Получение плейлиста по uuid - /// - /// Хранилище - /// uuid - /// - public Task> GetAsync(AuthStorage storage, string uuid) - { - return new YGetPlaylistByUuidBuilder(api, storage) - .Build(uuid) - .GetResponseAsync(); - } - - /// - /// Получение плейлистов - /// - /// Хранилище - /// Список пар пользователь:тип - /// - public Task>> GetAsync(AuthStorage storage, IEnumerable<(string user, string kind)> ids) - { - return new YGetPlaylistsBuilder(api, storage) - .Build(ids) - .GetResponseAsync(); - } - - /// - /// Получение плейлиста - /// - /// Хранилище - /// Описание плейлиста, для которого будут запрошены треки - /// - public Task> GetAsync(AuthStorage storage, YPlaylist playlist) - { - return new YGetPlaylistBuilder(api, storage) - .Build((playlist.Owner.Uid, playlist.Kind)) - .GetResponseAsync(); - } - - #endregion Получение плейлиста - - #region Операции над плейлистами - - /// - /// Создание - /// - /// Хранилище - /// Заголовок - /// - public Task> CreateAsync(AuthStorage storage, string name) - { - return new YPlaylistCreateBuilder(api, storage) - .Build(name) - .GetResponseAsync(); - } - - /// - /// Переименование - /// - /// Хранилище - /// Идентификатор плейлиста - /// Заголовок - /// - public Task> RenameAsync(AuthStorage storage, string kinds, string name) - { - return new YPlaylistRenameBuilder(api, storage) - .Build((kinds, name)) - .GetResponseAsync(); - } - - /// - /// Переименование - /// - /// Хранилище - /// Плейлист - /// Заголовок - /// - public Task> RenameAsync(AuthStorage storage, YPlaylist playlist, string name) - { - return RenameAsync(storage, playlist.Kind, name); - } - - /// - /// Удаление - /// - /// Хранилище - /// Тип - /// - public async Task DeleteAsync(AuthStorage storage, string kinds) - { - try - { - await new YPlaylistRemoveBuilder(api, storage) - .Build(kinds) - .GetResponseAsync(); - - return true; - } - catch (Exception ex) - { - Console.WriteLine(ex); - } - - return false; - } - - /// - /// Удаление - /// - /// Хранилище - /// Плейлист - /// - public Task DeleteAsync(AuthStorage storage, YPlaylist playlist) - { - return DeleteAsync(storage, playlist.Kind); - } - - /// - /// Добавление трека - /// - /// Хранилище - /// Плейлист - /// Треки для добавления - /// - public async Task> InsertTracksAsync(AuthStorage storage, YPlaylist playlist, IEnumerable tracks) - { - YResponse change = await ChangePlaylist(storage, playlist, new List { - new() { - Operation = YPlaylistChangeType.Insert, - At = 0, - Tracks = tracks.Select(t => t.GetKey()) - } - }); - - return await GetAsync(storage, change.Result); - } - - /// - /// Удаление треков - /// - /// Хранилище - /// Плейлист - /// Треки для удаления - /// - public Task> DeleteTracksAsync(AuthStorage storage, YPlaylist playlist, IEnumerable tracks) - { - List changes = RemoveIdentical(tracks) - .Select(t => playlist.Tracks.Select(c => c.Track).ToList().IndexOf(t)) - .Where(i => i != -1) - .Select(i => - { - YTrackContainer t = playlist.Tracks[i]; - return new YPlaylistChange - { - Operation = YPlaylistChangeType.Delete, - From = i, - To = i + 1, - Tracks = new List { - t.Track.GetKey() - } - }; - }) - .ToList(); - - return ChangePlaylist(storage, playlist, changes); - } - - #endregion Операции над плейлистами - - - } -} \ No newline at end of file diff --git a/YandexMusic.API/API/YQueueAPI.cs b/YandexMusic.API/API/YQueueAPI.cs new file mode 100644 index 0000000..f7881cf --- /dev/null +++ b/YandexMusic.API/API/YQueueAPI.cs @@ -0,0 +1,72 @@ +using YandexMusic.API.Common; +using YandexMusic.API.Models.Common; +using YandexMusic.API.Models.Queue; +using YandexMusic.API.Requests.Queue; + +namespace YandexMusic.API; + +/// +/// API для взаимодействия с очередями +/// +public partial class YQueueAPI : YCommonAPI +{ + public YQueueAPI(YandexMusicApi yandex) : base(yandex) + { + } + + /// + /// Получение всех очередей треков с разных устройств для синхронизации между ними + /// + /// Хранилище + /// Устройство + /// + public Task> ListAsync(AuthStorage storage, string? device = null) + { + return new YQueuesListBuilder(api, storage) + .Build(device) + .GetResponseAsync(); + } + + /// + /// Получение очереди + /// + /// Хранилище + /// Идентификатор очереди + /// + public Task> GetAsync(AuthStorage storage, string queueId) + { + return new YGetQueueBuilder(api, storage) + .Build(queueId) + .GetResponseAsync(); + } + + /// + /// Создание новой очереди треков + /// + /// Хранилище + /// Очередь треков + /// Устройство + /// + public Task> CreateAsync(AuthStorage storage, YQueue queue, string? device = null) + { + return new YQueueCreateBuilder(api, storage, device) + .Build(queue) + .GetResponseAsync(); + } + + /// + /// Установка текущего индекса проигрываемого трека в очереди треков + /// + /// Хранилище + /// Идентификатор очереди + /// Текущий индекс + /// Флаг интерактивности + /// Устройство + /// + public Task> UpdatePositionAsync(AuthStorage storage, string queueId, int currentIndex, bool isInteractive, string device = null) + { + return new YQueueUpdatePositionBuilder(api, storage, device) + .Build((queueId, currentIndex, isInteractive)) + .GetResponseAsync(); + } +} diff --git a/YandexMusic.API/API/YQueueAPIAsync.cs b/YandexMusic.API/API/YQueueAPIAsync.cs deleted file mode 100644 index aa380fd..0000000 --- a/YandexMusic.API/API/YQueueAPIAsync.cs +++ /dev/null @@ -1,73 +0,0 @@ -using YandexMusic.API.Common; -using YandexMusic.API.Models.Common; -using YandexMusic.API.Models.Queue; -using YandexMusic.API.Requests.Queue; - -namespace YandexMusic.API -{ - /// - /// API для взаимодействия с очередями - /// - public partial class YQueueAPI : YCommonAPI - { - public YQueueAPI(YandexMusicApi yandex) : base(yandex) - { - } - - /// - /// Получение всех очередей треков с разных устройств для синхронизации между ними - /// - /// Хранилище - /// Устройство - /// - public Task> ListAsync(AuthStorage storage, string device = null) - { - return new YQueuesListBuilder(api, storage) - .Build(device) - .GetResponseAsync(); - } - - /// - /// Получение очереди - /// - /// Хранилище - /// Идентификатор очереди - /// - public Task> GetAsync(AuthStorage storage, string queueId) - { - return new YGetQueueBuilder(api, storage) - .Build(queueId) - .GetResponseAsync(); - } - - /// - /// Создание новой очереди треков - /// - /// Хранилище - /// Очередь треков - /// Устройство - /// - public Task> CreateAsync(AuthStorage storage, YQueue queue, string device = null) - { - return new YQueueCreateBuilder(api, storage, device) - .Build(queue) - .GetResponseAsync(); - } - - /// - /// Установка текущего индекса проигрываемого трека в очереди треков - /// - /// Хранилище - /// Идентификатор очереди - /// Текущий индекс - /// Флаг интерактивности - /// Устройство - /// - public Task> UpdatePositionAsync(AuthStorage storage, string queueId, int currentIndex, bool isInteractive, string device = null) - { - return new YQueueUpdatePositionBuilder(api, storage, device) - .Build((queueId, currentIndex, isInteractive)) - .GetResponseAsync(); - } - } -} diff --git a/YandexMusic.API/API/YRadioAPI.cs b/YandexMusic.API/API/YRadioAPI.cs new file mode 100644 index 0000000..02172bc --- /dev/null +++ b/YandexMusic.API/API/YRadioAPI.cs @@ -0,0 +1,113 @@ +using YandexMusic.API.Common; +using YandexMusic.API.Models.Common; +using YandexMusic.API.Models.Radio; +using YandexMusic.API.Models.Track; +using YandexMusic.API.Requests.Radio; + +namespace YandexMusic.API; + +/// +/// API для взаимодействия с радио +/// +public partial class YRadioAPI : YCommonAPI +{ + public YRadioAPI(YandexMusicApi yandex) : base(yandex) + { + } + + /// + /// Получение списка рекомендованных радиостанций + /// + /// Хранилище + /// + public Task> GetStationsDashboardAsync(AuthStorage storage) + { + return new YGetStationsDashboardBuilder(api, storage) + .Build(null) + .GetResponseAsync(); + } + + /// + /// Получение списка радиостанций + /// + /// Хранилище + /// + public Task>> GetStationsAsync(AuthStorage storage) + { + return new YGetStationsBuilder(api, storage) + .Build(null) + .GetResponseAsync(); + } + + /// + /// Получение информации о радиостанции + /// + /// Хранилище + /// Тип + /// Тэг + /// + public Task>> GetStationAsync(AuthStorage storage, string type, string tag) + { + return new YGetStationBuilder(api, storage) + .Build((type, tag)) + .GetResponseAsync(); + } + + /// + /// Получение информации о радиостанции + /// + /// Хранилище + /// Идентификатор станции + /// + public Task>> GetStationAsync(AuthStorage storage, YStationId id) + { + return GetStationAsync(storage, id.Type, id.Tag); + } + + /// + /// Получение последовательности треков радиостанции + /// + /// Хранилище + /// Радиостанция + /// Идентификатор предыдущего трека + /// + public Task> GetStationTracksAsync(AuthStorage storage, YStation station, string prevTrackId = "") + { + return new YGetStationTracksBuilder(api, storage) + .Build((station.Station, prevTrackId)) + .GetResponseAsync(); + } + + /// + /// Установка настроек подбора треков + /// + /// Хранилище + /// Радиостанция + /// Настройки + /// + public Task> SetStationSettings2Async(AuthStorage storage, YStation station, YStationSettings2 settings) + { + return new YSetSettings2Builder(api, storage) + .Build((station.Station, settings)) + .GetResponseAsync(); + } + + /// + /// Отправка обратной связи на действия при прослушивании радио + /// + /// Хранилище + /// Радиостанция + /// Тип обратной связи + /// Трек + /// Уникальный идентификатор партии треков. Возвращается при получении треков + /// Сколько было проиграно секунд трека перед действием + /// + public Task SendStationFeedBackAsync(AuthStorage storage, YStation station, YStationFeedbackType type, YTrack track = null, string batchId = "", double totalPlayedSeconds = 0) + { + return new YSetStationFeedbackBuilder(api, storage) + .Build((type, station, track, batchId, totalPlayedSeconds)) + .GetResponseAsync(); + } + + +} \ No newline at end of file diff --git a/YandexMusic.API/API/YRadioAPIAsync.cs b/YandexMusic.API/API/YRadioAPIAsync.cs deleted file mode 100644 index 169976d..0000000 --- a/YandexMusic.API/API/YRadioAPIAsync.cs +++ /dev/null @@ -1,116 +0,0 @@ -using YandexMusic.API.Common; -using YandexMusic.API.Models.Common; -using YandexMusic.API.Models.Radio; -using YandexMusic.API.Models.Track; -using YandexMusic.API.Requests.Radio; - -namespace YandexMusic.API -{ - /// - /// API для взаимодействия с радио - /// - public partial class YRadioAPI : YCommonAPI - { - - - public YRadioAPI(YandexMusicApi yandex) : base(yandex) - { - } - - /// - /// Получение списка рекомендованных радиостанций - /// - /// Хранилище - /// - public Task> GetStationsDashboardAsync(AuthStorage storage) - { - return new YGetStationsDashboardBuilder(api, storage) - .Build(null) - .GetResponseAsync(); - } - - /// - /// Получение списка радиостанций - /// - /// Хранилище - /// - public Task>> GetStationsAsync(AuthStorage storage) - { - return new YGetStationsBuilder(api, storage) - .Build(null) - .GetResponseAsync(); - } - - /// - /// Получение информации о радиостанции - /// - /// Хранилище - /// Тип - /// Тэг - /// - public Task>> GetStationAsync(AuthStorage storage, string type, string tag) - { - return new YGetStationBuilder(api, storage) - .Build((type, tag)) - .GetResponseAsync(); - } - - /// - /// Получение информации о радиостанции - /// - /// Хранилище - /// Идентификатор станции - /// - public Task>> GetStationAsync(AuthStorage storage, YStationId id) - { - return GetStationAsync(storage, id.Type, id.Tag); - } - - /// - /// Получение последовательности треков радиостанции - /// - /// Хранилище - /// Радиостанция - /// Идентификатор предыдущего трека - /// - public Task> GetStationTracksAsync(AuthStorage storage, YStation station, string prevTrackId = "") - { - return new YGetStationTracksBuilder(api, storage) - .Build((station.Station, prevTrackId)) - .GetResponseAsync(); - } - - /// - /// Установка настроек подбора треков - /// - /// Хранилище - /// Радиостанция - /// Настройки - /// - public Task> SetStationSettings2Async(AuthStorage storage, YStation station, YStationSettings2 settings) - { - return new YSetSettings2Builder(api, storage) - .Build((station.Station, settings)) - .GetResponseAsync(); - } - - /// - /// Отправка обратной связи на действия при прослушивании радио - /// - /// Хранилище - /// Радиостанция - /// Тип обратной связи - /// Трек - /// Уникальный идентификатор партии треков. Возвращается при получении треков - /// Сколько было проиграно секунд трека перед действием - /// - public Task SendStationFeedBackAsync(AuthStorage storage, YStation station, YStationFeedbackType type, YTrack track = null, string batchId = "", double totalPlayedSeconds = 0) - { - return new YSetStationFeedbackBuilder(api, storage) - .Build((type, station, track, batchId, totalPlayedSeconds)) - .GetResponseAsync(); - } - - - } -} \ No newline at end of file diff --git a/YandexMusic.API/API/YSearchAPI.cs b/YandexMusic.API/API/YSearchAPI.cs new file mode 100644 index 0000000..1a9a690 --- /dev/null +++ b/YandexMusic.API/API/YSearchAPI.cs @@ -0,0 +1,139 @@ +using YandexMusic.API.Common; +using YandexMusic.API.Models.Common; +using YandexMusic.API.Models.Search; +using YandexMusic.API.Requests.Search; + +namespace YandexMusic.API; + +/// +/// API для поиска +/// +public partial class YSearchAPI : YCommonAPI +{ + + public YSearchAPI(YandexMusicApi yandex) : base(yandex) + { + } + + /// + /// Поиск по трекам + /// + /// Хранилище + /// Имя трека + /// Номер страницы + /// Размер страницы + /// + public Task> TrackAsync(AuthStorage storage, string trackName, int pageNumber = 0, int pageSize = 20) + { + return SearchAsync(storage, trackName, YSearchType.Track, pageNumber, pageSize); + } + + /// + /// Поиск по альбомам + /// + /// Хранилище + /// Имя альбома + /// Номер страницы + /// Размер страницы + /// + public Task> AlbumsAsync(AuthStorage storage, string albumName, int pageNumber = 0, int pageSize = 20) + { + return SearchAsync(storage, albumName, YSearchType.Album, pageNumber, pageSize); + } + + /// + /// Поиск по артисту + /// + /// Хранилище + /// Имя артиста + /// Номер страницы + /// Размер страницы + /// + public Task> ArtistAsync(AuthStorage storage, string artistName, int pageNumber = 0, int pageSize = 20) + { + return SearchAsync(storage, artistName, YSearchType.Artist, pageNumber, pageSize); + } + + /// + /// Поиск по плейлистам + /// + /// Хранилище + /// Имя плейлиста + /// Номер страницы + /// Размер страницы + /// + public Task> PlaylistAsync(AuthStorage storage, string playlistName, int pageNumber = 0, int pageSize = 20) + { + return SearchAsync(storage, playlistName, YSearchType.Playlist, pageNumber, pageSize); + } + + /// + /// Поиск по плейлистам + /// + /// Хранилище + /// Имя подкаста + /// Номер страницы + /// Размер страницы + /// + public Task> PodcastEpisodeAsync(AuthStorage storage, string podcastName, int pageNumber = 0, int pageSize = 20) + { + return SearchAsync(storage, podcastName, YSearchType.PodcastEpisode, pageNumber, pageSize); + } + + /// + /// Поиск по видео + /// + /// Хранилище + /// Имя видео + /// Номер страницы + /// Размер страницы + /// + public Task> VideosAsync(AuthStorage storage, string videoName, int pageNumber = 0, int pageSize = 20) + { + return SearchAsync(storage, videoName, YSearchType.Video, pageNumber, pageSize); + } + + /// + /// Поиск по пользователям + /// + /// Хранилище + /// Имя пользователя + /// Номер страницы + /// Размер страницы + /// + public Task> UsersAsync(AuthStorage storage, string userName, int pageNumber = 0, int pageSize = 20) + { + return SearchAsync(storage, userName, YSearchType.User, pageNumber, pageSize); + } + + /// + /// Поиск + /// + /// Хранилище + /// Поисковый запрос + /// Тип поиска + /// Страница + /// Размер страницы + /// + public Task> SearchAsync(AuthStorage storage, string searchText, YSearchType searchType, int page = 0, int pageSize = 20) + { + return new YSearchBuilder(api, storage) + .Build((searchText, searchType, page, pageSize)) + .GetResponseAsync(); + } + + /// + /// Подсказка + /// + /// Хранилище + /// Поисковый запрос + /// + public Task> SuggestAsync(AuthStorage storage, string searchText) + { + return new YSearchSuggestBuilder(api, storage) + .Build(searchText) + .GetResponseAsync(); + } + + +} \ No newline at end of file diff --git a/YandexMusic.API/API/YSearchAPIAsync.cs b/YandexMusic.API/API/YSearchAPIAsync.cs deleted file mode 100644 index 515a27c..0000000 --- a/YandexMusic.API/API/YSearchAPIAsync.cs +++ /dev/null @@ -1,141 +0,0 @@ -using YandexMusic.API.Common; -using YandexMusic.API.Models.Common; -using YandexMusic.API.Models.Search; -using YandexMusic.API.Requests.Search; - -namespace YandexMusic.API -{ - /// - /// API для поиска - /// - public partial class YSearchAPI : YCommonAPI - { - - - public YSearchAPI(YandexMusicApi yandex) : base(yandex) - { - } - - /// - /// Поиск по трекам - /// - /// Хранилище - /// Имя трека - /// Номер страницы - /// Размер страницы - /// - public Task> TrackAsync(AuthStorage storage, string trackName, int pageNumber = 0, int pageSize = 20) - { - return SearchAsync(storage, trackName, YSearchType.Track, pageNumber, pageSize); - } - - /// - /// Поиск по альбомам - /// - /// Хранилище - /// Имя альбома - /// Номер страницы - /// Размер страницы - /// - public Task> AlbumsAsync(AuthStorage storage, string albumName, int pageNumber = 0, int pageSize = 20) - { - return SearchAsync(storage, albumName, YSearchType.Album, pageNumber, pageSize); - } - - /// - /// Поиск по артисту - /// - /// Хранилище - /// Имя артиста - /// Номер страницы - /// Размер страницы - /// - public Task> ArtistAsync(AuthStorage storage, string artistName, int pageNumber = 0, int pageSize = 20) - { - return SearchAsync(storage, artistName, YSearchType.Artist, pageNumber, pageSize); - } - - /// - /// Поиск по плейлистам - /// - /// Хранилище - /// Имя плейлиста - /// Номер страницы - /// Размер страницы - /// - public Task> PlaylistAsync(AuthStorage storage, string playlistName, int pageNumber = 0, int pageSize = 20) - { - return SearchAsync(storage, playlistName, YSearchType.Playlist, pageNumber, pageSize); - } - - /// - /// Поиск по плейлистам - /// - /// Хранилище - /// Имя подкаста - /// Номер страницы - /// Размер страницы - /// - public Task> PodcastEpisodeAsync(AuthStorage storage, string podcastName, int pageNumber = 0, int pageSize = 20) - { - return SearchAsync(storage, podcastName, YSearchType.PodcastEpisode, pageNumber, pageSize); - } - - /// - /// Поиск по видео - /// - /// Хранилище - /// Имя видео - /// Номер страницы - /// Размер страницы - /// - public Task> VideosAsync(AuthStorage storage, string videoName, int pageNumber = 0, int pageSize = 20) - { - return SearchAsync(storage, videoName, YSearchType.Video, pageNumber, pageSize); - } - - /// - /// Поиск по пользователям - /// - /// Хранилище - /// Имя пользователя - /// Номер страницы - /// Размер страницы - /// - public Task> UsersAsync(AuthStorage storage, string userName, int pageNumber = 0, int pageSize = 20) - { - return SearchAsync(storage, userName, YSearchType.User, pageNumber, pageSize); - } - - /// - /// Поиск - /// - /// Хранилище - /// Поисковый запрос - /// Тип поиска - /// Страница - /// Размер страницы - /// - public Task> SearchAsync(AuthStorage storage, string searchText, YSearchType searchType, int page = 0, int pageSize = 20) - { - return new YSearchBuilder(api, storage) - .Build((searchText, searchType, page, pageSize)) - .GetResponseAsync(); - } - - /// - /// Подсказка - /// - /// Хранилище - /// Поисковый запрос - /// - public Task> SuggestAsync(AuthStorage storage, string searchText) - { - return new YSearchSuggestBuilder(api, storage) - .Build(searchText) - .GetResponseAsync(); - } - - - } -} \ No newline at end of file diff --git a/YandexMusic.API/API/YTrackAPI.cs b/YandexMusic.API/API/YTrackAPI.cs new file mode 100644 index 0000000..f495dd6 --- /dev/null +++ b/YandexMusic.API/API/YTrackAPI.cs @@ -0,0 +1,307 @@ +using System.Security.Cryptography; +using System.Text; + +using YandexMusic.API.Common; +using YandexMusic.API.Models.Common; +using YandexMusic.API.Models.Track; +using YandexMusic.API.Requests.Track; + +namespace YandexMusic.API; + +/// +/// API для взаимодействия с треками +/// +public partial class YTrackAPI : YCommonAPI +{ + #region Вспомогательные функции + + private string BuildLinkForDownload(YTrackDownloadInfo mainDownloadResponse, YStorageDownloadFile storageDownload) + { + string path = storageDownload.Path; + string host = storageDownload.Host; + string ts = storageDownload.Ts; + string s = storageDownload.S; + string codec = mainDownloadResponse.Codec; + + string secret = $"XGRlBW9FXlekgbPrRHuSiA{path.Substring(1, path.Length - 1)}{s}"; + MD5 md5 = MD5.Create(); + byte[] md5Hash = md5.ComputeHash(Encoding.UTF8.GetBytes(secret)); + HMACSHA1 hmacsha1 = new(); + byte[] hmasha1Hash = hmacsha1.ComputeHash(md5Hash); + string sign = BitConverter.ToString(hmasha1Hash).Replace("-", "").ToLower(); + + string link = $"https://{host}/get-{codec}/{sign}/{ts}{path}"; + + return link; + } + + #endregion Вспомогательные функции + + + + public YTrackAPI(YandexMusicApi yandex) : base(yandex) + { + } + + /// + /// Получение треков + /// + /// Хранилище + /// Идентификатор трека + /// + public Task>> GetAsync(AuthStorage storage, string trackId) + { + return new YGetTracksBuilder(api, storage) + .Build(new[] { trackId }) + .GetResponseAsync(); + } + + /// + /// Получение треков + /// + /// Хранилище + /// Идентификаторы треков + /// + public Task>> GetAsync(AuthStorage storage, IEnumerable trackIds) + { + return new YGetTracksBuilder(api, storage) + .Build(trackIds) + .GetResponseAsync(); + } + + /// + /// Получение метаданных для загрузки + /// + /// Хранилище + /// Ключ трека в формате {идентифактор трека:идентификатор альбома} + /// Должен ли ответ содержать прямую ссылку на загрузку + /// + public Task>> GetMetadataForDownloadAsync(AuthStorage storage, string trackKey, bool direct = false) + { + return new YTrackDownloadInfoBuilder(api, storage) + .Build((trackKey, direct)) + .GetResponseAsync(); + } + + /// + /// Получение метаданных для загрузки + /// + /// Хранилище + /// Трек + /// Должен ли ответ содержать прямую ссылку на загрузку + /// + public Task>> GetMetadataForDownloadAsync(AuthStorage storage, YTrack track, bool direct = false) + { + return GetMetadataForDownloadAsync(storage, track.GetKey().ToString(), direct); + } + + /// + /// Получение информации для формирования ссылки для загрузки + /// + /// Хранилище + /// Метаданные для загрузки + /// + public Task GetDownloadFileInfoAsync(AuthStorage storage, YTrackDownloadInfo metadataInfo) + { + return new YStorageDownloadFileBuilder(api, storage) + .Build(metadataInfo.DownloadInfoUrl) + .GetResponseAsync(); + } + + /// + /// Получение ссылки для загрузки + /// + /// Хранилище + /// Ключ трека в формате {идентификатор трека:идентификатор альбома} + /// + public async Task GetFileLinkAsync(AuthStorage storage, string trackKey) + { + YResponse> meta = await GetMetadataForDownloadAsync(storage, trackKey); + YTrackDownloadInfo info = meta.Result + .OrderByDescending(i => i.BitrateInKbps) + .First(m => m.Codec == "mp3"); + YStorageDownloadFile storageDownload = await GetDownloadFileInfoAsync(storage, info); + return BuildLinkForDownload(info, storageDownload); + } + + /// + /// Получение ссылки для загрузки + /// + /// Хранилище + /// Трек + /// + public Task GetFileLinkAsync(AuthStorage storage, YTrack track) + { + return GetFileLinkAsync(storage, track.GetKey().ToString()); + } + + /// + /// Отправка текущего состояния прослушиваемого трека + /// Хранилище + /// Трек + /// Наименования клиента, с которого происходит прослушивание + /// Проигрывается ли трек с кеша + /// Уникальный идентификатор проигрывания + /// Уникальный идентификатор плейлиста, если таковой прослушивается + /// Сколько было всего воспроизведено трека в секундах + /// Окончательное значение воспроизведенных секунд + /// + /// + public Task SendPlayTrackInfoAsync(AuthStorage storage, YTrack track, string from, bool fromCache = false, string playId = "", string playlistId = "", double totalPlayedSeconds = 0, double endPositionSeconds = 0) + { + return new YSendTrackInfoBuilder(api, storage) + .Build((track, from, fromCache, playId, playlistId, totalPlayedSeconds, endPositionSeconds)) + .GetResponseAsync(); + } + + #region GetSupplement + + /// + /// Получение дополнительной информации для трека + /// + /// Хранилище + /// Идентификатор трека + /// + public Task> GetSupplementAsync(AuthStorage storage, string trackId) + { + return new YGetTrackSupplementBuilder(api, storage) + .Build(trackId) + .GetResponseAsync(); + } + + /// + /// Получение дополнительной информации для трека + /// + /// Хранилище + /// Трек + /// + public Task> GetSupplementAsync(AuthStorage storage, YTrack track) + { + return new YGetTrackSupplementBuilder(api, storage) + .Build(track.GetKey().ToString()) + .GetResponseAsync(); + } + + #endregion GetSupplement + + #region GetSimilar + + /// + /// Получение похожих треков + /// + /// Хранилище + /// Идентификатор трека + /// + public Task> GetSimilarAsync(AuthStorage storage, string trackId) + { + return new YGetTrackSimilarBuilder(api, storage) + .Build(trackId) + .GetResponseAsync(); + } + + /// + /// Получение похожих треков + /// + /// Хранилище + /// Трек + /// + public Task> GetSimilarAsync(AuthStorage storage, YTrack track) + { + return new YGetTrackSimilarBuilder(api, storage) + .Build(track.GetKey().ToString()) + .GetResponseAsync(); + } + + #endregion GetSimilar + + #region Получение данных трека + + #region В файл + + /// + /// Выгрузка в файл + /// + /// Хранилище + /// Ключ трека в формате {идентификатор трека:идентификатор альбома} + /// Путь для файла + public async Task ExtractToFileAsync(AuthStorage storage, string trackKey, string filePath) + { + string url = await GetFileLinkAsync(storage, trackKey); + await new DataDownloader(storage).ToFile(url, filePath); + } + + /// + /// Выгрузка в файл + /// + /// Хранилище + /// Трек + /// Путь для файла + public Task ExtractToFileAsync(AuthStorage storage, YTrack track, string filePath) + { + return ExtractToFileAsync(storage, track.GetKey().ToString(), filePath); + } + + #endregion В файл + + #region В массив байт + + /// + /// Получение двоичного массива данных + /// + /// Хранилище + /// Ключ трека в формате {идентификатор трека:идентификатор альбома} + /// + public async Task ExtractDataAsync(AuthStorage storage, string trackKey) + { + string url = await GetFileLinkAsync(storage, trackKey); + return await new DataDownloader(storage).AsBytes(url); + } + + /// + /// Получение двоичного массива данных + /// + /// Хранилище + /// Трек + /// + public Task ExtractDataAsync(AuthStorage storage, YTrack track) + { + return ExtractDataAsync(storage, track.GetKey().ToString()); + } + + #endregion В массив байт + + #region В поток + + /// + /// Получение потока данных + /// + /// Хранилище + /// Ключ трека в формате {идентификатор трека:идентификатор альбома} + /// Параметры передачи управления при http запросе + /// + public async Task ExtractStreamAsync(AuthStorage storage, string trackKey, + HttpCompletionOption httpCompletionOption = HttpCompletionOption.ResponseContentRead) + { + string url = await GetFileLinkAsync(storage, trackKey); + return await new DataDownloader(storage).AsStream(url, httpCompletionOption); + } + + /// + /// Получение потока данных + /// + /// Хранилище + /// Трек + /// Параметры передачи управления при http запросе + /// + public Task ExtractStreamAsync(AuthStorage storage, YTrack track, + HttpCompletionOption httpCompletionOption = HttpCompletionOption.ResponseContentRead) + { + return ExtractStreamAsync(storage, track.GetKey().ToString(), httpCompletionOption); + } + + #endregion В поток + + #endregion Получение данных трека + + +} \ No newline at end of file diff --git a/YandexMusic.API/API/YTrackAPIAsync.cs b/YandexMusic.API/API/YTrackAPIAsync.cs deleted file mode 100644 index 555465c..0000000 --- a/YandexMusic.API/API/YTrackAPIAsync.cs +++ /dev/null @@ -1,308 +0,0 @@ -using System.Security.Cryptography; -using System.Text; - -using YandexMusic.API.Common; -using YandexMusic.API.Models.Common; -using YandexMusic.API.Models.Track; -using YandexMusic.API.Requests.Track; - -namespace YandexMusic.API -{ - /// - /// API для взаимодействия с треками - /// - public partial class YTrackAPI : YCommonAPI - { - #region Вспомогательные функции - - private string BuildLinkForDownload(YTrackDownloadInfo mainDownloadResponse, YStorageDownloadFile storageDownload) - { - string path = storageDownload.Path; - string host = storageDownload.Host; - string ts = storageDownload.Ts; - string s = storageDownload.S; - string codec = mainDownloadResponse.Codec; - - string secret = $"XGRlBW9FXlekgbPrRHuSiA{path.Substring(1, path.Length - 1)}{s}"; - MD5 md5 = MD5.Create(); - byte[] md5Hash = md5.ComputeHash(Encoding.UTF8.GetBytes(secret)); - HMACSHA1 hmacsha1 = new(); - byte[] hmasha1Hash = hmacsha1.ComputeHash(md5Hash); - string sign = BitConverter.ToString(hmasha1Hash).Replace("-", "").ToLower(); - - string link = $"https://{host}/get-{codec}/{sign}/{ts}{path}"; - - return link; - } - - #endregion Вспомогательные функции - - - - public YTrackAPI(YandexMusicApi yandex) : base(yandex) - { - } - - /// - /// Получение треков - /// - /// Хранилище - /// Идентификатор трека - /// - public Task>> GetAsync(AuthStorage storage, string trackId) - { - return new YGetTracksBuilder(api, storage) - .Build(new[] { trackId }) - .GetResponseAsync(); - } - - /// - /// Получение треков - /// - /// Хранилище - /// Идентификаторы треков - /// - public Task>> GetAsync(AuthStorage storage, IEnumerable trackIds) - { - return new YGetTracksBuilder(api, storage) - .Build(trackIds) - .GetResponseAsync(); - } - - /// - /// Получение метаданных для загрузки - /// - /// Хранилище - /// Ключ трека в формате {идентифактор трека:идентификатор альбома} - /// Должен ли ответ содержать прямую ссылку на загрузку - /// - public Task>> GetMetadataForDownloadAsync(AuthStorage storage, string trackKey, bool direct = false) - { - return new YTrackDownloadInfoBuilder(api, storage) - .Build((trackKey, direct)) - .GetResponseAsync(); - } - - /// - /// Получение метаданных для загрузки - /// - /// Хранилище - /// Трек - /// Должен ли ответ содержать прямую ссылку на загрузку - /// - public Task>> GetMetadataForDownloadAsync(AuthStorage storage, YTrack track, bool direct = false) - { - return GetMetadataForDownloadAsync(storage, track.GetKey().ToString(), direct); - } - - /// - /// Получение информации для формирования ссылки для загрузки - /// - /// Хранилище - /// Метаданные для загрузки - /// - public Task GetDownloadFileInfoAsync(AuthStorage storage, YTrackDownloadInfo metadataInfo) - { - return new YStorageDownloadFileBuilder(api, storage) - .Build(metadataInfo.DownloadInfoUrl) - .GetResponseAsync(); - } - - /// - /// Получение ссылки для загрузки - /// - /// Хранилище - /// Ключ трека в формате {идентификатор трека:идентификатор альбома} - /// - public async Task GetFileLinkAsync(AuthStorage storage, string trackKey) - { - YResponse> meta = await GetMetadataForDownloadAsync(storage, trackKey); - YTrackDownloadInfo info = meta.Result - .OrderByDescending(i => i.BitrateInKbps) - .First(m => m.Codec == "mp3"); - YStorageDownloadFile storageDownload = await GetDownloadFileInfoAsync(storage, info); - return BuildLinkForDownload(info, storageDownload); - } - - /// - /// Получение ссылки для загрузки - /// - /// Хранилище - /// Трек - /// - public Task GetFileLinkAsync(AuthStorage storage, YTrack track) - { - return GetFileLinkAsync(storage, track.GetKey().ToString()); - } - - /// - /// Отправка текущего состояния прослушиваемого трека - /// Хранилище - /// Трек - /// Наименования клиента, с которого происходит прослушивание - /// Проигрывается ли трек с кеша - /// Уникальный идентификатор проигрывания - /// Уникальный идентификатор плейлиста, если таковой прослушивается - /// Сколько было всего воспроизведено трека в секундах - /// Окончательное значение воспроизведенных секунд - /// - /// - public Task SendPlayTrackInfoAsync(AuthStorage storage, YTrack track, string from, bool fromCache = false, string playId = "", string playlistId = "", double totalPlayedSeconds = 0, double endPositionSeconds = 0) - { - return new YSendTrackInfoBuilder(api, storage) - .Build((track, from, fromCache, playId, playlistId, totalPlayedSeconds, endPositionSeconds)) - .GetResponseAsync(); - } - - #region GetSupplement - - /// - /// Получение дополнительной информации для трека - /// - /// Хранилище - /// Идентификатор трека - /// - public Task> GetSupplementAsync(AuthStorage storage, string trackId) - { - return new YGetTrackSupplementBuilder(api, storage) - .Build(trackId) - .GetResponseAsync(); - } - - /// - /// Получение дополнительной информации для трека - /// - /// Хранилище - /// Трек - /// - public Task> GetSupplementAsync(AuthStorage storage, YTrack track) - { - return new YGetTrackSupplementBuilder(api, storage) - .Build(track.GetKey().ToString()) - .GetResponseAsync(); - } - - #endregion GetSupplement - - #region GetSimilar - - /// - /// Получение похожих треков - /// - /// Хранилище - /// Идентификатор трека - /// - public Task> GetSimilarAsync(AuthStorage storage, string trackId) - { - return new YGetTrackSimilarBuilder(api, storage) - .Build(trackId) - .GetResponseAsync(); - } - - /// - /// Получение похожих треков - /// - /// Хранилище - /// Трек - /// - public Task> GetSimilarAsync(AuthStorage storage, YTrack track) - { - return new YGetTrackSimilarBuilder(api, storage) - .Build(track.GetKey().ToString()) - .GetResponseAsync(); - } - - #endregion GetSimilar - - #region Получение данных трека - - #region В файл - - /// - /// Выгрузка в файл - /// - /// Хранилище - /// Ключ трека в формате {идентификатор трека:идентификатор альбома} - /// Путь для файла - public async Task ExtractToFileAsync(AuthStorage storage, string trackKey, string filePath) - { - string url = await GetFileLinkAsync(storage, trackKey); - await new DataDownloader(storage).ToFile(url, filePath); - } - - /// - /// Выгрузка в файл - /// - /// Хранилище - /// Трек - /// Путь для файла - public Task ExtractToFileAsync(AuthStorage storage, YTrack track, string filePath) - { - return ExtractToFileAsync(storage, track.GetKey().ToString(), filePath); - } - - #endregion В файл - - #region В массив байт - - /// - /// Получение двоичного массива данных - /// - /// Хранилище - /// Ключ трека в формате {идентификатор трека:идентификатор альбома} - /// - public async Task ExtractDataAsync(AuthStorage storage, string trackKey) - { - string url = await GetFileLinkAsync(storage, trackKey); - return await new DataDownloader(storage).AsBytes(url); - } - - /// - /// Получение двоичного массива данных - /// - /// Хранилище - /// Трек - /// - public Task ExtractDataAsync(AuthStorage storage, YTrack track) - { - return ExtractDataAsync(storage, track.GetKey().ToString()); - } - - #endregion В массив байт - - #region В поток - - /// - /// Получение потока данных - /// - /// Хранилище - /// Ключ трека в формате {идентификатор трека:идентификатор альбома} - /// Параметры передачи управления при http запросе - /// - public async Task ExtractStreamAsync(AuthStorage storage, string trackKey, - HttpCompletionOption httpCompletionOption = HttpCompletionOption.ResponseContentRead) - { - string url = await GetFileLinkAsync(storage, trackKey); - return await new DataDownloader(storage).AsStream(url, httpCompletionOption); - } - - /// - /// Получение потока данных - /// - /// Хранилище - /// Трек - /// Параметры передачи управления при http запросе - /// - public Task ExtractStreamAsync(AuthStorage storage, YTrack track, - HttpCompletionOption httpCompletionOption = HttpCompletionOption.ResponseContentRead) - { - return ExtractStreamAsync(storage, track.GetKey().ToString(), httpCompletionOption); - } - - #endregion В поток - - #endregion Получение данных трека - - - } -} \ No newline at end of file diff --git a/YandexMusic.API/API/YUgcAPI.cs b/YandexMusic.API/API/YUgcAPI.cs new file mode 100644 index 0000000..bc6536c --- /dev/null +++ b/YandexMusic.API/API/YUgcAPI.cs @@ -0,0 +1,71 @@ +using YandexMusic.API.Common; +using YandexMusic.API.Models.Common; +using YandexMusic.API.Models.Playlist; +using YandexMusic.API.Models.Ugc; +using YandexMusic.API.Requests.Ugc; + +namespace YandexMusic.API; + +public partial class YUgcAPI : YCommonAPI +{ + public YUgcAPI(YandexMusicApi yandex) : base(yandex) + { + } + + /// + /// Получение ссылки на загрузчик трека + /// + /// Хранилище + /// Плейлист, куда будет загружен трек + /// Название файла для загрузки + public Task GetUgcUploadLinkAsync(AuthStorage storage, YPlaylist playlist, string fileName) + { + return new YUgcGetUploadLinkBuilder(api, storage) + .Build((playlist, fileName)) + .GetResponseAsync(); + } + + /// + /// Загрузка трека из файла + /// + /// Хранилище + /// Ссылка на балансировщик для загрузки, можно получить из GetUgcUploadLinkAsync + /// Загружаемый файл + public Task> UploadUgcTrackAsync(AuthStorage storage, string uploadLink, string filePath) + { + if (!File.Exists(filePath)) + throw new FileNotFoundException("Файл для загрузки не существует.", filePath); + + return UploadUgcTrackAsync(storage, uploadLink, File.Open(filePath, FileMode.Open)); + } + + /// + /// Загрузка трека из потока + /// + /// Хранилище + /// Ссылка на балансировщик для загрузки, можно получить из GetUgcUploadLinkAsync + /// Поток с данными для загрузки + public Task> UploadUgcTrackAsync(AuthStorage storage, string uploadLink, Stream stream) + { + if (stream == null) + throw new NullReferenceException("Пустая ссылка на поток загрузки."); + + using MemoryStream ms = new(); + stream.CopyTo(ms); + + return UploadUgcTrackAsync(storage, uploadLink, ms.ToArray()); + } + + /// + /// Загрузка трека из массива + /// + /// Хранилище + /// Ссылка на балансировщик для загрузки, можно получить из GetUgcUploadLinkAsync + /// Загружаемый трек в виде массив байтов + public Task> UploadUgcTrackAsync(AuthStorage storage, string uploadLink, byte[] file) + { + return new YUgcUploadBuilder(api, storage) + .Build((uploadLink, file)) + .GetResponseAsync(); + } +} \ No newline at end of file diff --git a/YandexMusic.API/API/YUgcAPIAsync.cs b/YandexMusic.API/API/YUgcAPIAsync.cs deleted file mode 100644 index 9316b28..0000000 --- a/YandexMusic.API/API/YUgcAPIAsync.cs +++ /dev/null @@ -1,72 +0,0 @@ -using YandexMusic.API.Common; -using YandexMusic.API.Models.Common; -using YandexMusic.API.Models.Playlist; -using YandexMusic.API.Models.Ugc; -using YandexMusic.API.Requests.Ugc; - -namespace YandexMusic.API -{ - public partial class YUgcAPI : YCommonAPI - { - public YUgcAPI(YandexMusicApi yandex) : base(yandex) - { - } - - /// - /// Получение ссылки на загрузчик трека - /// - /// Хранилище - /// Плейлист, куда будет загружен трек - /// Название файла для загрузки - public Task GetUgcUploadLinkAsync(AuthStorage storage, YPlaylist playlist, string fileName) - { - return new YUgcGetUploadLinkBuilder(api, storage) - .Build((playlist, fileName)) - .GetResponseAsync(); - } - - /// - /// Загрузка трека из файла - /// - /// Хранилище - /// Ссылка на балансировщик для загрузки, можно получить из GetUgcUploadLinkAsync - /// Загружаемый файл - public Task> UploadUgcTrackAsync(AuthStorage storage, string uploadLink, string filePath) - { - if (!File.Exists(filePath)) - throw new FileNotFoundException("Файл для загрузки не существует.", filePath); - - return UploadUgcTrackAsync(storage, uploadLink, File.Open(filePath, FileMode.Open)); - } - - /// - /// Загрузка трека из потока - /// - /// Хранилище - /// Ссылка на балансировщик для загрузки, можно получить из GetUgcUploadLinkAsync - /// Поток с данными для загрузки - public Task> UploadUgcTrackAsync(AuthStorage storage, string uploadLink, Stream stream) - { - if (stream == null) - throw new NullReferenceException("Пустая ссылка на поток загрузки."); - - using MemoryStream ms = new(); - stream.CopyTo(ms); - - return UploadUgcTrackAsync(storage, uploadLink, ms.ToArray()); - } - - /// - /// Загрузка трека из массива - /// - /// Хранилище - /// Ссылка на балансировщик для загрузки, можно получить из GetUgcUploadLinkAsync - /// Загружаемый трек в виде массив байтов - public Task> UploadUgcTrackAsync(AuthStorage storage, string uploadLink, byte[] file) - { - return new YUgcUploadBuilder(api, storage) - .Build((uploadLink, file)) - .GetResponseAsync(); - } - } -} \ No newline at end of file diff --git a/YandexMusic.API/API/YUserAPI.cs b/YandexMusic.API/API/YUserAPI.cs new file mode 100644 index 0000000..d66d638 --- /dev/null +++ b/YandexMusic.API/API/YUserAPI.cs @@ -0,0 +1,300 @@ +using System.Security.Authentication; +using System.Text.RegularExpressions; + +using YandexMusic.API.Common; +using YandexMusic.API.Models.Account; +using YandexMusic.API.Models.Common; +using YandexMusic.API.Requests.Account; + +namespace YandexMusic.API; + +/// +/// API для пользователя +/// +public partial class YUserAPI : YCommonAPI +{ + #region Вспомогательные функции + + private async Task GetCsrfTokenAsync(AuthStorage storage) + { + using HttpResponseMessage authMethodsResponse = await new YGetAuthMethodsBuilder(api, storage) + .Build(null) + .GetResponseAsync(); + + if (!authMethodsResponse.IsSuccessStatusCode) + throw new HttpRequestException("Невозможно получить CFRF-токен."); + + string responseString = await authMethodsResponse.Content + .ReadAsStringAsync(); + Match match = Regex.Match(responseString, "\"csrf_token\" value=\"([^\"]+)\""); + + if (!match.Success || match.Groups.Count < 2) + return false; + + storage.AuthToken = new YAuthToken + { + CsfrToken = match.Groups[1].Value + }; + + return true; + } + + private async Task LoginByCookiesAsync(AuthStorage storage) + { + if (storage.AuthToken == null) + throw new AuthenticationException("Невозможно инициализировать сессию входа."); + + YAccessToken accessToken = await new YGetAuthCookiesBuilder(api, storage) + .Build(null) + .GetResponseAsync(); + + storage.IsAuthorized = !string.IsNullOrEmpty(accessToken.AccessToken); + + storage.AccessToken = accessToken; + storage.Token = accessToken.AccessToken; + + YShortAccountInfo validateTokenResponse = await new YGetShortAccountInifoBuilder(api, storage) + .Build(null) + .GetResponseAsync(); + + if (validateTokenResponse.Status != YAuthStatus.Ok) + throw new Exception("Вход в аккаунт не выполнен."); + + storage.IsAuthorized = !string.IsNullOrWhiteSpace(validateTokenResponse.Uid); + + return storage.IsAuthorized; + } + + #endregion Вспомогательные функции + + public YUserAPI(YandexMusicApi yandex) : base(yandex) + { + } + + /// + /// Авторизация + /// + /// Хранилище + /// Токен авторизации + /// + public async Task AuthorizeAsync(AuthStorage storage, string token) + { + if (string.IsNullOrEmpty(token)) + throw new Exception("Задан пустой токен авторизации."); + + storage.Token = token; + + // Пытаемся получить информацию о пользователе + YResponse authInfo = await GetUserAuthAsync(storage); + + // Если не авторизован, то авторизуем + if (string.IsNullOrEmpty(authInfo.Result.Account.Uid)) + throw new Exception("Пользователь незалогинен."); + + // Флаг авторизации + storage.IsAuthorized = true; + storage.User = authInfo.Result.Account; + } + + /// + /// Получение информации об авторизации + /// + /// Хранилище + /// + public Task> GetUserAuthAsync(AuthStorage storage) + { + return new YGetAuthInfoBuilder(api, storage) + .Build(null) + .GetResponseAsync(); + } + + /// + /// Создание сеанса и получение доступных методов авторизации + /// + /// Хранилище + /// Имя пользователя + /// + public async Task CreateAuthSessionAsync(AuthStorage storage, string userName) + { + if (!await GetCsrfTokenAsync(storage)) + throw new Exception("Невозможно инициализировать сессию входа."); + + YAuthTypes types = await new YGetAuthLoginUserBuilder(api, storage) + .Build((storage.AuthToken.CsfrToken, userName)) + .GetResponseAsync(); + + storage.AuthToken.TrackId = types.TrackId; + + return types; + } + + /// + /// Получение ссылки на QR-код + /// + /// Хранилище + /// + public async Task GetAuthQRLinkAsync(AuthStorage storage) + { + if (!await GetCsrfTokenAsync(storage)) + throw new Exception("Невозможно инициализировать сессию входа."); + + YAuthQR result = await new YGetAuthQRBuilder(api, storage) + .Build(null) + .GetResponseAsync(); + + if (result.Status != YAuthStatus.Ok) + return string.Empty; + + storage.AuthToken = new YAuthToken + { + TrackId = result.TrackId, + CsfrToken = result.CsrfToken + }; + + return $"https://passport.yandex.ru/auth/magic/code/?track_id={result.TrackId}"; + } + + /// + /// Авторизация по QR-коду + /// + /// Хранилище + /// + public async Task AuthorizeByQRAsync(AuthStorage storage) + { + if (storage.AuthToken == null) + throw new Exception("Не выполнен запрос на авторизацию по QR."); + + try + { + YAuthQRStatus qrStatus = await new YGetAuthLoginQRBuilder(api, storage) + .Build(null) + .GetResponseAsync(); + if (qrStatus.Status != YAuthStatus.Ok) + return qrStatus; + + bool ok = await LoginByCookiesAsync(storage); + if (!ok) + throw new AuthenticationException("Ошибка авторизации по QR."); + + return qrStatus; + } + catch (Exception ex) + { + throw new AuthenticationException("Ошибка авторизации по QR.", ex); + } + } + + /// + /// Получение + /// + /// Хранилище + /// + public Task GetCaptchaAsync(AuthStorage storage) + { + if (storage.AuthToken == null || string.IsNullOrWhiteSpace(storage.AuthToken.CsfrToken)) + throw new AuthenticationException($"Не найдена сессия входа. Выполните {nameof(CreateAuthSessionAsync)} перед использованием."); + + return new YGetAuthCaptchaBuilder(api, storage) + .Build(null) + .GetResponseAsync(); + } + + /// + /// Авторизация по captcha + /// + /// Хранилище + /// Значение captcha + /// + public Task AuthorizeByCaptchaAsync(AuthStorage storage, string captchaValue) + { + if (storage.AuthToken == null || string.IsNullOrWhiteSpace(storage.AuthToken.CsfrToken)) + throw new AuthenticationException($"Не найдена сессия входа. Выполните {nameof(CreateAuthSessionAsync)} перед использованием."); + + return new YGetAuthLoginCaptchaBuilder(api, storage) + .Build(captchaValue) + .GetResponseAsync(); + } + + /// + /// Получение письма авторизации на почту пользователя + /// + /// Хранилище + /// + public Task GetAuthLetterAsync(AuthStorage storage) + { + return new YGetAuthLetterBuilder(api, storage) + .Build(null) + .GetResponseAsync(); + } + + /// + /// Авторизация после подтверждения входа через письмо + /// + /// Хранилище + /// + public async Task AuthorizeByLetterAsync(AuthStorage storage) + { + YAuthLetterStatus status = await new YGetAuthLoginLetterBuilder(api, storage) + .Build(null) + .GetResponseAsync(); + + if (status.Status == YAuthStatus.Ok && !status.MagicLinkConfirmed) + throw new Exception("Не подтвержден вход посредством e-mail."); + + return await LoginByCookiesAsync(storage); + } + + /// + /// Авторизация с помощью пароля из приложения Яндекс + /// + /// Хранилище + /// Пароль + /// + public async Task AuthorizeByAppPasswordAsync(AuthStorage storage, string password) + { + if (storage.AuthToken == null || string.IsNullOrWhiteSpace(storage.AuthToken.CsfrToken)) + throw new AuthenticationException($"Не найдена сессия входа. Выполните {nameof(CreateAuthSessionAsync)} перед использованием."); + + YAuthBase response = await new YGetAuthAppPasswordBuilder(api, storage) + .Build(password) + .GetResponseAsync(); + + if (response.Status == YAuthStatus.Ok) + { + bool ok = await LoginByCookiesAsync(storage); + if (!ok) + throw new AuthenticationException("Ошибка авторизации."); + } + + return response; + } + + /// + /// Получение после авторизации с помощью QR, e-mail, пароля из приложения + /// + public async Task GetAccessTokenAsync(AuthStorage storage) + { + if (storage.AuthToken == null) + throw new Exception("Не найдена сессия входа."); + + YAccessToken accessToken = await new YGetMusicTokenBuilder(api, storage) + .Build(null) + .GetResponseAsync(); + + storage.Token = accessToken.AccessToken; + + return accessToken; + } + + /// + /// Получение информации о пользователе через логин Яндекса + /// + public Task GetLoginInfoAsync(AuthStorage storage) + { + return new YGetLoginInfoBuilder(api, storage) + .Build(null) + .GetResponseAsync(); + } + + +} diff --git a/YandexMusic.API/API/YUserAPIAsync.cs b/YandexMusic.API/API/YUserAPIAsync.cs deleted file mode 100644 index 0c84ffa..0000000 --- a/YandexMusic.API/API/YUserAPIAsync.cs +++ /dev/null @@ -1,303 +0,0 @@ -using System.Security.Authentication; -using System.Text.RegularExpressions; - -using YandexMusic.API.Common; -using YandexMusic.API.Models.Account; -using YandexMusic.API.Models.Common; -using YandexMusic.API.Requests.Account; - -namespace YandexMusic.API -{ - /// - /// API для пользователя - /// - public partial class YUserAPI : YCommonAPI - { - #region Вспомогательные функции - - private async Task GetCsrfTokenAsync(AuthStorage storage) - { - using HttpResponseMessage authMethodsResponse = await new YGetAuthMethodsBuilder(api, storage) - .Build(null) - .GetResponseAsync(); - - if (!authMethodsResponse.IsSuccessStatusCode) - throw new HttpRequestException("Невозможно получить CFRF-токен."); - - string responseString = await authMethodsResponse.Content - .ReadAsStringAsync(); - Match match = Regex.Match(responseString, "\"csrf_token\" value=\"([^\"]+)\""); - - if (!match.Success || match.Groups.Count < 2) - return false; - - storage.AuthToken = new YAuthToken - { - CsfrToken = match.Groups[1].Value - }; - - return true; - } - - private async Task LoginByCookiesAsync(AuthStorage storage) - { - if (storage.AuthToken == null) - throw new AuthenticationException("Невозможно инициализировать сессию входа."); - - YAccessToken accessToken = await new YGetAuthCookiesBuilder(api, storage) - .Build(null) - .GetResponseAsync(); - - storage.IsAuthorized = !string.IsNullOrEmpty(accessToken.AccessToken); - - storage.AccessToken = accessToken; - storage.Token = accessToken.AccessToken; - - YShortAccountInfo validateTokenResponse = await new YGetShortAccountInifoBuilder(api, storage) - .Build(null) - .GetResponseAsync(); - - if (validateTokenResponse.Status != YAuthStatus.Ok) - throw new Exception("Вход в аккаунт не выполнен."); - - storage.IsAuthorized = !string.IsNullOrWhiteSpace(validateTokenResponse.Uid); - - return storage.IsAuthorized; - } - - #endregion Вспомогательные функции - - - - public YUserAPI(YandexMusicApi yandex) : base(yandex) - { - } - - /// - /// Авторизация - /// - /// Хранилище - /// Токен авторизации - /// - public async Task AuthorizeAsync(AuthStorage storage, string token) - { - if (string.IsNullOrEmpty(token)) - throw new Exception("Задан пустой токен авторизации."); - - storage.Token = token; - - // Пытаемся получить информацию о пользователе - YResponse authInfo = await GetUserAuthAsync(storage); - - // Если не авторизован, то авторизуем - if (string.IsNullOrEmpty(authInfo.Result.Account.Uid)) - throw new Exception("Пользователь незалогинен."); - - // Флаг авторизации - storage.IsAuthorized = true; - storage.User = authInfo.Result.Account; - } - - /// - /// Получение информации об авторизации - /// - /// Хранилище - /// - public Task> GetUserAuthAsync(AuthStorage storage) - { - return new YGetAuthInfoBuilder(api, storage) - .Build(null) - .GetResponseAsync(); - } - - /// - /// Создание сеанса и получение доступных методов авторизации - /// - /// Хранилище - /// Имя пользователя - /// - public async Task CreateAuthSessionAsync(AuthStorage storage, string userName) - { - if (!await GetCsrfTokenAsync(storage)) - throw new Exception("Невозможно инициализировать сессию входа."); - - YAuthTypes types = await new YGetAuthLoginUserBuilder(api, storage) - .Build((storage.AuthToken.CsfrToken, userName)) - .GetResponseAsync(); - - storage.AuthToken.TrackId = types.TrackId; - - return types; - } - - /// - /// Получение ссылки на QR-код - /// - /// Хранилище - /// - public async Task GetAuthQRLinkAsync(AuthStorage storage) - { - if (!await GetCsrfTokenAsync(storage)) - throw new Exception("Невозможно инициализировать сессию входа."); - - YAuthQR result = await new YGetAuthQRBuilder(api, storage) - .Build(null) - .GetResponseAsync(); - - if (result.Status != YAuthStatus.Ok) - return string.Empty; - - storage.AuthToken = new YAuthToken - { - TrackId = result.TrackId, - CsfrToken = result.CsrfToken - }; - - return $"https://passport.yandex.ru/auth/magic/code/?track_id={result.TrackId}"; - } - - /// - /// Авторизация по QR-коду - /// - /// Хранилище - /// - public async Task AuthorizeByQRAsync(AuthStorage storage) - { - if (storage.AuthToken == null) - throw new Exception("Не выполнен запрос на авторизацию по QR."); - - try - { - YAuthQRStatus qrStatus = await new YGetAuthLoginQRBuilder(api, storage) - .Build(null) - .GetResponseAsync(); - if (qrStatus.Status != YAuthStatus.Ok) - return qrStatus; - - bool ok = await LoginByCookiesAsync(storage); - if (!ok) - throw new AuthenticationException("Ошибка авторизации по QR."); - - return qrStatus; - } - catch (Exception ex) - { - throw new AuthenticationException("Ошибка авторизации по QR.", ex); - } - } - - /// - /// Получение - /// - /// Хранилище - /// - public Task GetCaptchaAsync(AuthStorage storage) - { - if (storage.AuthToken == null || string.IsNullOrWhiteSpace(storage.AuthToken.CsfrToken)) - throw new AuthenticationException($"Не найдена сессия входа. Выполните {nameof(CreateAuthSessionAsync)} перед использованием."); - - return new YGetAuthCaptchaBuilder(api, storage) - .Build(null) - .GetResponseAsync(); - } - - /// - /// Авторизация по captcha - /// - /// Хранилище - /// Значение captcha - /// - public Task AuthorizeByCaptchaAsync(AuthStorage storage, string captchaValue) - { - if (storage.AuthToken == null || string.IsNullOrWhiteSpace(storage.AuthToken.CsfrToken)) - throw new AuthenticationException($"Не найдена сессия входа. Выполните {nameof(CreateAuthSessionAsync)} перед использованием."); - - return new YGetAuthLoginCaptchaBuilder(api, storage) - .Build(captchaValue) - .GetResponseAsync(); - } - - /// - /// Получение письма авторизации на почту пользователя - /// - /// Хранилище - /// - public Task GetAuthLetterAsync(AuthStorage storage) - { - return new YGetAuthLetterBuilder(api, storage) - .Build(null) - .GetResponseAsync(); - } - - /// - /// Авторизация после подтверждения входа через письмо - /// - /// Хранилище - /// - public async Task AuthorizeByLetterAsync(AuthStorage storage) - { - YAuthLetterStatus status = await new YGetAuthLoginLetterBuilder(api, storage) - .Build(null) - .GetResponseAsync(); - - if (status.Status == YAuthStatus.Ok && !status.MagicLinkConfirmed) - throw new Exception("Не подтвержден вход посредством e-mail."); - - return await LoginByCookiesAsync(storage); - } - - /// - /// Авторизация с помощью пароля из приложения Яндекс - /// - /// Хранилище - /// Пароль - /// - public async Task AuthorizeByAppPasswordAsync(AuthStorage storage, string password) - { - if (storage.AuthToken == null || string.IsNullOrWhiteSpace(storage.AuthToken.CsfrToken)) - throw new AuthenticationException($"Не найдена сессия входа. Выполните {nameof(CreateAuthSessionAsync)} перед использованием."); - - YAuthBase response = await new YGetAuthAppPasswordBuilder(api, storage) - .Build(password) - .GetResponseAsync(); - - if (response.Status == YAuthStatus.Ok) - { - bool ok = await LoginByCookiesAsync(storage); - if (!ok) - throw new AuthenticationException("Ошибка авторизации."); - } - - return response; - } - - /// - /// Получение после авторизации с помощью QR, e-mail, пароля из приложения - /// - public async Task GetAccessTokenAsync(AuthStorage storage) - { - if (storage.AuthToken == null) - throw new Exception("Не найдена сессия входа."); - - YAccessToken accessToken = await new YGetMusicTokenBuilder(api, storage) - .Build(null) - .GetResponseAsync(); - - storage.Token = accessToken.AccessToken; - - return accessToken; - } - - /// - /// Получение информации о пользователе через логин Яндекса - /// - public Task GetLoginInfoAsync(AuthStorage storage) - { - return new YGetLoginInfoBuilder(api, storage) - .Build(null) - .GetResponseAsync(); - } - - - } -} diff --git a/YandexMusic.API/API/YYnisonAPI.cs b/YandexMusic.API/API/YYnisonAPI.cs new file mode 100644 index 0000000..dc9b307 --- /dev/null +++ b/YandexMusic.API/API/YYnisonAPI.cs @@ -0,0 +1,21 @@ +using YandexMusic.API.Common; +using YandexMusic.API.Common.Ynison; + +namespace YandexMusic.API; +/// +/// API Ynison +/// +public partial class YYnisonAPI : YCommonAPI +{ + public YYnisonAPI(YandexMusicApi yandex) : base(yandex) + { + } + + public YnisonPlayer GetPlayer(AuthStorage storage) + { + if (string.IsNullOrEmpty(storage.Token)) + throw new Exception("Токен пользователя не задан."); + + return new(api, storage); + } +} diff --git a/YandexMusic.API/Common/AuthStorage.cs b/YandexMusic.API/Common/AuthStorage.cs index 81ba0ee..b3164aa 100644 --- a/YandexMusic.API/Common/AuthStorage.cs +++ b/YandexMusic.API/Common/AuthStorage.cs @@ -1,103 +1,70 @@ using System.Net; - -using YandexMusic.API.Common.Debug; using YandexMusic.API.Common.Providers; using YandexMusic.API.Models.Account; using YandexMusic.API.Requests.Common; -namespace YandexMusic.API.Common +namespace YandexMusic.API.Common; + +/// +/// Хранилище данных пользователя +/// +public class AuthStorage { /// - /// Хранилище данных пользователя + /// Http-контекст /// - public class AuthStorage + public HttpContext Context { get; } + + /// + /// Флаг авторизации + /// + public bool IsAuthorized { get; internal set; } + + /// + /// Идентификатор устройства + /// + public string DeviceId { get; set; } = "csharp"; + + /// + /// Токен авторизации + /// + public string Token { get; internal set; } + + /// + /// Аккаунт + /// + public YAccount User { get; set; } + + /// + /// Провайдер запросов + /// + public IRequestProvider Provider { get; } + + /// + /// Токен доступа + /// + public YAccessToken AccessToken { get; set; } + + internal YAuthToken AuthToken { get; set; } + + /// + /// Конструктор + /// + public AuthStorage(IRequestProvider provider) { - #region Свойства - - /// - /// Http-контекст - /// - public HttpContext Context { get; } - - public DebugSettings Debug { get; set; } - - /// - /// Флаг авторизации - /// - public bool IsAuthorized { get; internal set; } - - /// - /// Идентификатор устройства - /// - public string DeviceId { get; set; } = "csharp"; - - /// - /// Токен авторизации - /// - public string Token { get; internal set; } - - /// - /// Аккаунт - /// - public YAccount User { get; set; } - - /// - /// Провайдер запросов - /// - public IRequestProvider Provider { get; } - - /// - /// Токен доступа - /// - public YAccessToken AccessToken { get; set; } - - internal YAuthToken AuthToken { get; set; } - - #endregion Свойства - - - - /// - /// Конструктор - /// - public AuthStorage(DebugSettings settings = null) - { - User = new YAccount(); - Context = new HttpContext(); - Debug = settings; - Provider = new DefaultRequestProvider(this); - - if (Debug is { ClearDirectory: true }) - { - Debug.Clear(); - } - } - - /// - /// Конструктор - /// - public AuthStorage(IRequestProvider provider, DebugSettings settings = null) - { - User = new YAccount(); - Context = new HttpContext(); - Debug = settings; - Provider = provider; - - if (Debug is { ClearDirectory: true }) - { - Debug.Clear(); - } - } - - /// - /// Установка прокси для пользователия - /// - /// Прокси - public void SetProxy(IWebProxy proxy) - { - Context.WebProxy = proxy; - } - - + User = new YAccount(); + Context = new HttpContext(); + Provider = provider; } + + /// + /// Установка прокси для пользователия + /// + /// Прокси + public void SetProxy(IWebProxy proxy) + { + Context.WebProxy = proxy; + } + + } \ No newline at end of file diff --git a/YandexMusic.API/Common/DataDownloader.cs b/YandexMusic.API/Common/DataDownloader.cs index fbec075..9b73c6d 100644 --- a/YandexMusic.API/Common/DataDownloader.cs +++ b/YandexMusic.API/Common/DataDownloader.cs @@ -1,44 +1,43 @@ using System.Net; -namespace YandexMusic.API.Common +namespace YandexMusic.API.Common; + +/// +/// Загрузчик файлов по ссылке +/// +public class DataDownloader { - /// - /// Загрузчик файлов по ссылке - /// - public class DataDownloader + private AuthStorage authStorage; + + private async Task GetResponseContent(string url, HttpCompletionOption httpCompletionOption = HttpCompletionOption.ResponseContentRead) { - private AuthStorage authStorage; + HttpRequestMessage message = new(new HttpMethod(WebRequestMethods.Http.Get), url); - private async Task GetResponseContent(string url, HttpCompletionOption httpCompletionOption = HttpCompletionOption.ResponseContentRead) - { - HttpRequestMessage message = new(new HttpMethod(WebRequestMethods.Http.Get), url); + HttpResponseMessage response = await authStorage.Provider.GetWebResponseAsync(message, httpCompletionOption); + return response.Content; + } - HttpResponseMessage response = await authStorage.Provider.GetWebResponseAsync(message, httpCompletionOption); - return response.Content; - } + public async Task AsStream(string url, HttpCompletionOption httpCompletionOption = HttpCompletionOption.ResponseContentRead) + { + HttpContent content = await GetResponseContent(url, httpCompletionOption); + return await content.ReadAsStreamAsync(); + } - public async Task AsStream(string url, HttpCompletionOption httpCompletionOption = HttpCompletionOption.ResponseContentRead) - { - HttpContent content = await GetResponseContent(url, httpCompletionOption); - return await content.ReadAsStreamAsync(); - } + public async Task AsBytes(string url) + { + HttpContent content = await GetResponseContent(url); + return await content.ReadAsByteArrayAsync(); + } - public async Task AsBytes(string url) - { - HttpContent content = await GetResponseContent(url); - return await content.ReadAsByteArrayAsync(); - } + public async Task ToFile(string url, string fileName) + { + using Stream stream = await AsStream(url); + using FileStream fs = File.Create(fileName); + await stream.CopyToAsync(fs); + } - public async Task ToFile(string url, string fileName) - { - using Stream stream = await AsStream(url); - using FileStream fs = File.Create(fileName); - await stream.CopyToAsync(fs); - } - - public DataDownloader(AuthStorage storage) - { - authStorage = storage; - } + public DataDownloader(AuthStorage storage) + { + authStorage = storage; } } \ No newline at end of file diff --git a/YandexMusic.API/Common/Encryptor.cs b/YandexMusic.API/Common/Encryptor.cs index 541a57e..f85c5fc 100644 --- a/YandexMusic.API/Common/Encryptor.cs +++ b/YandexMusic.API/Common/Encryptor.cs @@ -1,75 +1,63 @@ using System.Security.Cryptography; using System.Text; -namespace YandexMusic.API.Common +namespace YandexMusic.API.Common; + +/// +/// Класс для шифровки +/// +public class Encryptor { - /// - /// Класс для шифровки - /// - public class Encryptor + private readonly string IV = "encryption"; + private readonly byte[] IVHash; + + private readonly byte[] keyHash; + + private readonly MD5 md5; + private readonly Aes aesAlg; + + private byte[] GetHash(string value) { - #region Поля - - private readonly string IV = "encryption"; - private readonly byte[] IVHash; - - private readonly byte[] keyHash; - - private readonly MD5 md5; - private readonly Aes aesAlg; - - - #endregion Поля - - #region Вспомогательные функции - - private byte[] GetHash(string value) - { - return md5.ComputeHash(Encoding.UTF8.GetBytes(value)); - } - - #endregion Вспомогательные функции - - - - public Encryptor(string key) - { - md5 = MD5.Create(); - - aesAlg = Aes.Create(); - aesAlg.BlockSize = 128; - aesAlg.Padding = PaddingMode.PKCS7; - - keyHash = GetHash(key); - IVHash = GetHash(IV); - } - - public byte[] Encrypt(byte[] data) - { - using MemoryStream ms = new(); - using CryptoStream csEncrypt = new(ms, aesAlg.CreateEncryptor(keyHash, IVHash), CryptoStreamMode.Write); - - csEncrypt.Write(data, 0, data.Length); - - if (!csEncrypt.HasFlushedFinalBlock) - csEncrypt.FlushFinalBlock(); - - return ms.ToArray(); - } - - public byte[] Decrypt(byte[] data) - { - using MemoryStream ms = new(); - using CryptoStream csDecrypt = new(ms, aesAlg.CreateDecryptor(keyHash, IVHash), CryptoStreamMode.Write); - - csDecrypt.Write(data, 0, data.Length); - - if (!csDecrypt.HasFlushedFinalBlock) - csDecrypt.FlushFinalBlock(); - - return ms.ToArray(); - } - - + return md5.ComputeHash(Encoding.UTF8.GetBytes(value)); } + + public Encryptor(string key) + { + md5 = MD5.Create(); + + aesAlg = Aes.Create(); + aesAlg.BlockSize = 128; + aesAlg.Padding = PaddingMode.PKCS7; + + keyHash = GetHash(key); + IVHash = GetHash(IV); + } + + public byte[] Encrypt(byte[] data) + { + using MemoryStream ms = new(); + using CryptoStream csEncrypt = new(ms, aesAlg.CreateEncryptor(keyHash, IVHash), CryptoStreamMode.Write); + + csEncrypt.Write(data, 0, data.Length); + + if (!csEncrypt.HasFlushedFinalBlock) + csEncrypt.FlushFinalBlock(); + + return ms.ToArray(); + } + + public byte[] Decrypt(byte[] data) + { + using MemoryStream ms = new(); + using CryptoStream csDecrypt = new(ms, aesAlg.CreateDecryptor(keyHash, IVHash), CryptoStreamMode.Write); + + csDecrypt.Write(data, 0, data.Length); + + if (!csDecrypt.HasFlushedFinalBlock) + csDecrypt.FlushFinalBlock(); + + return ms.ToArray(); + } + + } \ No newline at end of file diff --git a/YandexMusic.API/Common/Providers/CommonRequestProvider.cs b/YandexMusic.API/Common/Providers/CommonRequestProvider.cs index de4ac1d..2ede2e6 100644 --- a/YandexMusic.API/Common/Providers/CommonRequestProvider.cs +++ b/YandexMusic.API/Common/Providers/CommonRequestProvider.cs @@ -1,60 +1,56 @@ -using YandexMusic.API.Models.Common; +using System.Text.Json; +using System.Text.Json.Serialization; +using YandexMusic.API.Models.Common; -namespace YandexMusic.API.Common.Providers +namespace YandexMusic.API.Common.Providers; + +/// Базовый провайдер HTTP-запросов с общей логикой десериализации. +public abstract class CommonRequestProvider : IRequestProvider { - public class CommonRequestProvider : IRequestProvider + /// Хранилище данных авторизации. + protected readonly AuthStorage storage; + + /// Настройки сериализации JSON (регистронезависимые, поддержка enum-строк). + private static readonly JsonSerializerOptions JsonOptions = new() { - #region Поля + PropertyNameCaseInsensitive = true, + Converters = { new JsonStringEnumConverter(JsonNamingPolicy.CamelCase) } + }; - protected AuthStorage storage; + /// Инициализирует новый экземпляр провайдера. + /// Хранилище авторизации. + protected CommonRequestProvider(AuthStorage authStorage) + { + storage = authStorage; + } - #endregion Поля + /// Выполняет HTTP-запрос и возвращает ответ. + public abstract Task GetWebResponseAsync( + HttpRequestMessage message, + HttpCompletionOption completionOption = HttpCompletionOption.ResponseContentRead); + /// Преобразует HTTP-ответ в объект типа T. + public virtual async Task GetDataFromResponseAsync( + YandexMusicApi api, + HttpResponseMessage response) + { + var json = await response.Content.ReadAsStringAsync(); - - public CommonRequestProvider(AuthStorage authStorage) + if (!response.IsSuccessStatusCode) { - storage = authStorage; + var error = JsonSerializer.Deserialize(json, JsonOptions); + throw error ?? new Exception("Ошибка десериализации ответа с ошибкой."); } - - - #region IRequestProvider - - public virtual Task GetWebResponseAsync(HttpRequestMessage message, HttpCompletionOption completionOption = HttpCompletionOption.ResponseContentRead) + try { - throw new NotImplementedException(); + // Если нужен контекст выполнения, он добавляется через кастомный конвертер + return JsonSerializer.Deserialize(json, JsonOptions) + ?? throw new JsonException("Десериализация вернула null"); } - - public virtual async Task GetDataFromResponseAsync(YandexMusicApi api, HttpResponseMessage response) + catch (Exception ex) { - string result = await response.Content.ReadAsStringAsync(); - - if (!response.IsSuccessStatusCode) - { - YErrorResponse exception = JsonConvert.DeserializeObject(result); - throw exception ?? new Exception("Ошибка десериализации ответа с ошибкой."); - } - - try - { - JsonSerializerSettings settings = new() - { - Converters = new List { - new YExecutionContextConverter(api, storage) - } - }; - - return storage.Debug != null - ? storage.Debug.Deserialize(response.RequestMessage?.RequestUri?.AbsolutePath, result, settings) - : JsonConvert.DeserializeObject(result, settings); - } - catch (Exception ex) - { - throw new Exception($"Ошибка десериализации {ex}"); - } + throw new Exception($"Ошибка десериализации: {ex.Message}", ex); } - - #endregion IRequestProvider } } \ No newline at end of file diff --git a/YandexMusic.API/Common/Providers/DefaultRequestProvider.cs b/YandexMusic.API/Common/Providers/DefaultRequestProvider.cs index c46820f..b000c00 100644 --- a/YandexMusic.API/Common/Providers/DefaultRequestProvider.cs +++ b/YandexMusic.API/Common/Providers/DefaultRequestProvider.cs @@ -1,69 +1,45 @@ using System.Net; -using YandexMusic.API.Models.Common; +namespace YandexMusic.API.Common.Providers; -namespace YandexMusic.API.Common.Providers +/// Стандартный провайдер HTTP-запросов с использованием HttpClient. +public class DefaultRequestProvider : CommonRequestProvider { - /// - /// Стандартный провайдер запросов - /// - public class DefaultRequestProvider : CommonRequestProvider + /// Инициализирует новый экземпляр провайдера. + /// Хранилище авторизации. + public DefaultRequestProvider(AuthStorage authStorage) : base(authStorage) { } + + /// Выполняет HTTP-запрос и возвращает ответ. + /// HTTP-запрос. + /// Опция завершения запроса. + /// HTTP-ответ. + public override async Task GetWebResponseAsync( + HttpRequestMessage message, + HttpCompletionOption completionOption = HttpCompletionOption.ResponseContentRead) { - #region Вспомогательные функции - - private Exception ProcessException(Exception ex) + using var handler = new SocketsHttpHandler { - if (ex is not WebException webException) - return ex; + Proxy = storage.Context.WebProxy, + AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate, + UseCookies = true, + CookieContainer = storage.Context.Cookies, + AllowAutoRedirect = true, + MaxAutomaticRedirections = 10 + }; - if (webException.Response is null) - return ex; + using var client = new HttpClient(handler); - Stream s = webException.Response.GetResponseStream(); - if (s is null) - return ex; - - using StreamReader sr = new(s); - string result = sr.ReadToEnd(); - - YErrorResponse exception = JsonConvert.DeserializeObject(result); - - return exception ?? ex; - } - - #endregion Вспомогательные функции - - - - public DefaultRequestProvider(AuthStorage authStorage) : base(authStorage) + try { + return await client.SendAsync(message, completionOption); } - - - - #region IRequestProvider - - public override Task GetWebResponseAsync(HttpRequestMessage message, - HttpCompletionOption completionOption = HttpCompletionOption.ResponseContentRead) + catch (HttpRequestException ex) { - try - { - HttpClient client = new(new SocketsHttpHandler - { - Proxy = storage.Context.WebProxy, - AutomaticDecompression = DecompressionMethods.GZip, - UseCookies = true, - CookieContainer = storage.Context.Cookies, - }); + // Пытаемся извлечь тело ошибки, если оно доступно + if (ex.InnerException == null) + throw; - return client.SendAsync(message, completionOption); - } - catch (Exception ex) - { - throw ProcessException(ex); - } + throw new Exception($"Ошибка HTTP-запроса: {ex.Message}", ex); } - - #endregion IRequestProvider } } \ No newline at end of file diff --git a/YandexMusic.API/Common/Providers/MockRequestProvider.cs b/YandexMusic.API/Common/Providers/MockRequestProvider.cs index df3937d..dcd6476 100644 --- a/YandexMusic.API/Common/Providers/MockRequestProvider.cs +++ b/YandexMusic.API/Common/Providers/MockRequestProvider.cs @@ -9,7 +9,6 @@ public MockRequestProvider(AuthStorage authStorage) : base(authStorage) { - storage = authStorage; } diff --git a/YandexMusic.API/Common/Ynison/UpperSnakeCaseNamingPolicy.cs b/YandexMusic.API/Common/Ynison/UpperSnakeCaseNamingPolicy.cs new file mode 100644 index 0000000..74ac25e --- /dev/null +++ b/YandexMusic.API/Common/Ynison/UpperSnakeCaseNamingPolicy.cs @@ -0,0 +1,43 @@ +using System.Text; +using System.Text.Json; + +namespace YandexMusic.API.Common.Ynison; + +/// Политика именования в формате UPPER_SNAKE_CASE (все буквы верхнего регистра, слова через подчёркивание). +public class UpperSnakeCaseNamingPolicy : SnakeCaseNamingPolicy +{ + /// Преобразует имя свойства в формат UPPER_SNAKE_CASE. + public override string ConvertName(string name) + { + var snakeCase = base.ConvertName(name); + return snakeCase.ToUpperInvariant(); + } +} + +/// Базовая политика именования в формате snake_case (все буквы нижнего регистра, слова через подчёркивание). +public class SnakeCaseNamingPolicy : JsonNamingPolicy +{ + /// Преобразует имя свойства в формат snake_case. + public override string ConvertName(string name) + { + if (string.IsNullOrEmpty(name)) + return name; + + var sb = new StringBuilder(); + for (int i = 0; i < name.Length; i++) + { + char c = name[i]; + if (char.IsUpper(c)) + { + if (i > 0) + sb.Append('_'); + sb.Append(char.ToLowerInvariant(c)); + } + else + { + sb.Append(c); + } + } + return sb.ToString(); + } +} \ No newline at end of file diff --git a/YandexMusic.API/Common/Ynison/UpperSnakeCaseNamingStrategy.cs b/YandexMusic.API/Common/Ynison/UpperSnakeCaseNamingStrategy.cs deleted file mode 100644 index 752f9ba..0000000 --- a/YandexMusic.API/Common/Ynison/UpperSnakeCaseNamingStrategy.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace YandexMusic.API.Common.Ynison -{ - public class UpperSnakeCaseNamingStrategy : SnakeCaseNamingStrategy - { - protected override string ResolvePropertyName(string name) => base.ResolvePropertyName(name).ToUpper(); - } -} \ No newline at end of file diff --git a/YandexMusic.API/Common/Ynison/YnisonPlayer.cs b/YandexMusic.API/Common/Ynison/YnisonPlayer.cs index 713f208..45fcb16 100644 --- a/YandexMusic.API/Common/Ynison/YnisonPlayer.cs +++ b/YandexMusic.API/Common/Ynison/YnisonPlayer.cs @@ -1,315 +1,183 @@ using System.Net.WebSockets; +using System.Text.Json; +using System.Text.Json.Serialization; using YandexMusic.API.Models.Track; using YandexMusic.API.Models.Ynison; using YandexMusic.API.Models.Ynison.Messages; -namespace YandexMusic.API.Common.Ynison +namespace YandexMusic.API.Common.Ynison; + +/// Плеер для управления воспроизведением через протокол Ynison (WebSocket). +public class YnisonPlayer : IDisposable { - public class YnisonPlayer : IDisposable + private readonly JsonSerializerOptions _jsonOptions; + private readonly AuthStorage _storage; + private YnisonWebSocket? _redirector; + private YnisonWebSocket? _state; + + /// API Яндекс Музыки. + public YandexMusicApi API { get; } + + /// Текущее состояние плеера. + public YYnisonState? State { get; private set; } + + /// Текущий проигрываемый трек. + public YTrack? Current => GetCurrentAsync().GetAwaiter().GetResult(); + + /// Событие получения нового состояния. + public event EventHandler? OnReceive; + + /// Событие закрытия соединения. + public event EventHandler? OnClose; + + /// Аргументы события получения состояния. + public class ReceiveEventArgs : EventArgs { - #region Поля + /// Состояние плеера. + public YYnisonState State { get; init; } = null!; + } - private readonly JsonSerializerSettings jsonSettings = new() + /// Аргументы события закрытия соединения. + public class CloseEventArgs : EventArgs + { + /// Статус закрытия. + public WebSocketCloseStatus? Status { get; init; } + /// Описание причины закрытия. + public string? Description { get; init; } + } + + internal YnisonPlayer(YandexMusicApi api, AuthStorage authStorage) + { + API = api; + _storage = authStorage; + _jsonOptions = new JsonSerializerOptions { - Converters = new List { - new StringEnumConverter(new UpperSnakeCaseNamingStrategy()) - }, + PropertyNamingPolicy = JsonNamingPolicy.SnakeCaseLower, + DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull, + Converters = { new JsonStringEnumConverter(new UpperSnakeCaseNamingPolicy(), false) } + }; + _redirector = new YnisonWebSocket(); + _state = new YnisonWebSocket(); + } - NullValueHandling = NullValueHandling.Ignore, - ContractResolver = new DefaultContractResolver + private string SerializeJson(object data) => JsonSerializer.Serialize(data, _jsonOptions); + + private T Deserialize(YYnisonMessageType messageType, string data) + { + return JsonSerializer.Deserialize(data, _jsonOptions) + ?? throw new JsonException("Десериализация вернула null"); + } + + private T DeserializeMessage(YYnisonMessageType messageType, string data) + { + using var doc = JsonDocument.Parse(data); + if (doc.RootElement.TryGetProperty("error", out _)) + { + var error = Deserialize(YYnisonMessageType.Error, data); + throw error ?? new Exception("Ошибка десериализации ответа с ошибкой."); + } + return Deserialize(messageType, data); + } + + private string DefaultState() + { + var version = new YYnisonVersion + { + DeviceId = _storage.DeviceId, + Version = "0" + }; + var fullState = new YYnisonUpdateFullStateMessage + { + UpdateFullState = new YYnisonFullState { - // Важно! Унисон отдаёт данные в SnakeCase - NamingStrategy = new SnakeCaseNamingStrategy() + Device = new YYnisonDevice + { + Capabilities = new YYnisonDeviceCapabilities { CanBePlayer = true }, + Info = new YYnisonDeviceInfo + { + DeviceId = _storage.DeviceId, + AppName = "Yandex Music API", + AppVersion = "0.0.1", + Type = "WEB", + Title = "YandexMusicAPI" + }, + IsShadow = true + }, + PlayerState = new YYnisonPlayerState + { + PlayerQueue = new YYnisonPlayerQueue { Version = version }, + Status = new YYnisonPlayerStateStatus { Version = version } + } } }; + return SerializeJson(fullState); + } - private AuthStorage storage; - private YnisonWebSocket redirector; - private YnisonWebSocket state; + private async Task GetCurrentAsync() + { + if (State == null) return null; + int index = State.PlayerState.PlayerQueue.CurrentPlayableIndex; + if (index < 0 || index >= State.PlayerState.PlayerQueue.PlayableList.Count) + return null; + var item = State.PlayerState.PlayerQueue.PlayableList[index]; + var response = await API.Track.GetAsync(_storage, item.PlayableId); + return response?.Result?.FirstOrDefault(); + } - #endregion Поля - - #region Свойства - - /// - /// API - /// - public YandexMusicApi API { get; internal set; } - - /// - /// Состояние - /// - public YYnisonState State { get; internal set; } - - /// - /// Текущий проигрываемый трек - /// - public YTrack Current => GetCurrent(); - - #endregion Свойства - - #region События - - public class ReceiveEventArgs + private async Task UpdateStateAsync() + { + if (State == null) return; + var update = new YYnisonUpdatePlayerStateMessage { - public YYnisonState State { get; internal set; } - } + UpdatePlayerState = State.PlayerState + }; + update.UpdatePlayerState.Status.Version = new YYnisonVersion { DeviceId = _storage.DeviceId }; + update.UpdatePlayerState.PlayerQueue.Version = new YYnisonVersion { DeviceId = _storage.DeviceId }; + if (_state != null) + await _state.SendAsync(SerializeJson(update)); + } - public delegate void OnReceiveEventHandler(YnisonPlayer player, ReceiveEventArgs args); - - /// - /// Получение данных - /// - public event OnReceiveEventHandler OnReceive; - - - public class CloseEventArgs + /// Подключается к Ynison и начинает получение состояния. + public async Task ConnectAsync() + { + if (_redirector == null) throw new ObjectDisposedException(nameof(YnisonPlayer)); + await _redirector.ConnectAsync(_storage, "wss://ynison.music.yandex.ru/redirector.YnisonRedirectService/GetRedirectToYnison"); + _redirector.OnReceive += async (socket, data) => { - public WebSocketCloseStatus? Status { get; set; } - public string Description { get; set; } - } - - public delegate void OnCloseEventHandler(YnisonPlayer player, CloseEventArgs args); - - /// - /// Получение данных - /// - public event OnCloseEventHandler OnClose; - - #endregion События - - #region Вспомогательные функции - - private string SerializeJson(object data) - { - return JsonConvert.SerializeObject(data, jsonSettings); - } - - private T Deserialize(YYnisonMessageType messageType, string data) - { - return storage.Debug != null - ? storage.Debug.Deserialize($"Ynison{messageType}", data, jsonSettings) - : JsonConvert.DeserializeObject(data, jsonSettings); - } - - private T DeserializeMessage(YYnisonMessageType messageType, string data) - { - JObject o = JObject.Parse(data); - // Сообщение с ошибкой - if (o.ContainsKey("error")) + var redirectInfo = Deserialize(YYnisonMessageType.Redirect, data.Data); + if (_state == null) return; + if (_state.IsConnected) return; + await _state.ConnectAsync(_storage, $"wss://{redirectInfo.Host}/ynison_state.YnisonStateService/PutYnisonState", redirectInfo.RedirectTicket); + _state.OnReceive += (s, d) => { - YYnisonErrorMessage exception = Deserialize(YYnisonMessageType.Error, data); - throw exception ?? new Exception("Ошибка десериализации ответа с ошибкой."); - } - - return Deserialize(messageType, data); - } - - private string DefaultState() - { - YYnisonVersion version = new() - { - DeviceId = storage.DeviceId, - Version = "0" + var message = DeserializeMessage(YYnisonMessageType.State, d.Data); + State = message; + OnReceive?.Invoke(this, new ReceiveEventArgs { State = State }); }; - - YYnisonUpdateFullStateMessage fullState = new() + _state.OnClose += (s, args) => { - UpdateFullState = new() - { - Device = new() - { - Capabilities = new() - { - CanBePlayer = true - }, - Info = new() - { - DeviceId = storage.DeviceId, - AppName = "Yandex Music API", - AppVersion = "0.0.1", - Type = "WEB", - Title = "YandexMusicAPI" - }, - IsShadow = true - }, - PlayerState = new() - { - PlayerQueue = new() - { - Version = version - }, - Status = new() - { - Version = version - } - } - } + OnClose?.Invoke(this, new CloseEventArgs { Status = args.Status, Description = args.Description }); }; + _ = _state.BeginReceiveAsync(); + await _state.SendAsync(DefaultState()); + }; + await _redirector.BeginReceiveAsync(); + } - return SerializeJson(fullState); - } + /// Отключается от Ynison. + public async Task DisconnectAsync() + { + if (_state != null) await _state.StopReceiveAsync(); + if (_redirector != null) await _redirector.StopReceiveAsync(); + } - private YTrack GetCurrent() - { - if (State == null) - return null; - - int index = State.PlayerState.PlayerQueue.CurrentPlayableIndex; - if (index < 0 || index > State.PlayerState.PlayerQueue.PlayableList.Count) - return null; - - YYnisonPlayableItem item = State.PlayerState.PlayerQueue.PlayableList[index]; - - return API.Track.Get(storage, item.PlayableId) - .Result - .FirstOrDefault(); - } - - private void UpdateState() - { - YYnisonUpdatePlayerStateMessage update = new() - { - UpdatePlayerState = State.PlayerState - }; - - update.UpdatePlayerState.Status.Version = new() - { - DeviceId = storage.DeviceId - }; - - update.UpdatePlayerState.PlayerQueue.Version = new() - { - DeviceId = storage.DeviceId - }; - - try - { - state.Send(SerializeJson(update)); - } - catch (Exception ex) - { - Console.WriteLine(ex); - throw; - } - } - - #endregion Вспомогательные функции - - - - #region Подключение - - public void Connect() - { - redirector.Connect(storage, "wss://ynison.music.yandex.ru/redirector.YnisonRedirectService/GetRedirectToYnison"); - redirector.OnReceive += (socket, data) => - { - YYnisonRedirect redirectInfo = Deserialize(YYnisonMessageType.Redirect, data.Data); - - if (state.IsConnected) - return; - - state.Connect(storage, $"wss://{redirectInfo.Host}/ynison_state.YnisonStateService/PutYnisonState", redirectInfo.RedirectTicket); - state.OnReceive += (s, d) => - { - YYnisonState message = DeserializeMessage(YYnisonMessageType.State, d.Data); - - State = message; - - OnReceive?.Invoke(this, new ReceiveEventArgs - { - State = State - }); - }; - - state.OnClose += (s, args) => - { - OnClose?.Invoke(this, new CloseEventArgs - { - Status = args.Status, - Description = args.Description - }); - }; - - state.BeginReceive(); - // Отправка изначального состояния - state.Send(DefaultState()); - }; - - redirector.BeginReceive(); - } - - public void Disconnect() - { - state?.StopReceive(); - redirector?.StopReceive(); - } - - #endregion Подключение - - #region Плеер - - /* - public void Play() - { - - } - - public void Stop() - { - - } - - public void Next() - { - List list = State.PlayerState.PlayerQueue.PlayableList; - - if (State.PlayerState.PlayerQueue.EntityType == YYnisonEntityType.Radio) - { - YYnisonPlayableItem next = State.PlayerState.PlayerQueue.Queue.WaveQueue.RecommendedPlayableList - .FirstOrDefault(); - - list.RemoveAt(0); - list.Add(next); - - UpdateState(); - } - - if (State.PlayerState.PlayerQueue.CurrentPlayableIndex < list.Count - 1) - { - State.PlayerState.PlayerQueue.CurrentPlayableIndex++; - UpdateState(); - } - } - - public void Previous() - { - - } - */ - - #endregion Плеер - - internal YnisonPlayer(YandexMusicApi api, AuthStorage authStorage) - { - API = api; - storage = authStorage; - - redirector = new(); - state = new(); - } - - - - #region IDisposable - - public void Dispose() - { - redirector?.StopReceive(); - redirector?.Dispose(); - } - - #endregion IDisposable + /// Освобождает ресурсы. + public void Dispose() + { + _redirector?.Dispose(); + _state?.Dispose(); + _redirector = null; + _state = null; + GC.SuppressFinalize(this); } } \ No newline at end of file diff --git a/YandexMusic.API/Common/Ynison/YnisonWebSocket.cs b/YandexMusic.API/Common/Ynison/YnisonWebSocket.cs index 01363fe..8c0b7a4 100644 --- a/YandexMusic.API/Common/Ynison/YnisonWebSocket.cs +++ b/YandexMusic.API/Common/Ynison/YnisonWebSocket.cs @@ -1,179 +1,142 @@ using System.Net.WebSockets; using System.Text; +using System.Text.Json; -namespace YandexMusic.API.Common.Ynison +namespace YandexMusic.API.Common.Ynison; + +/// WebSocket-клиент для взаимодействия с протоколом Ynison. +public class YnisonWebSocket : IDisposable { - public class YnisonWebSocket : IDisposable + private readonly ClientWebSocket _socketClient = new(); + private CancellationTokenSource? _cancellationTokenSource; + private CancellationToken _cancellationToken; + private readonly StringBuilder _data = new(); + private const int BufferSize = 4096; + + /// Флаг, указывает, открыто ли соединение. + public bool IsConnected => _socketClient.State == WebSocketState.Open; + + /// Событие получения сообщения. + public event EventHandler? OnReceive; + + /// Событие закрытия соединения. + public event EventHandler? OnClose; + + /// Аргументы события получения данных. + public class ReceiveEventArgs : EventArgs { - #region Поля + /// Полученные данные (JSON-строка). + public string Data { get; init; } = null!; + } - private readonly JsonSerializerSettings jsonSettings = new() + /// Аргументы события закрытия соединения. + public class CloseEventArgs : EventArgs + { + /// Статус закрытия. + public WebSocketCloseStatus? Status { get; init; } + /// Описание причины закрытия. + public string? Description { get; init; } + } + + private static string GetProtocolData(string deviceId, string? redirectTicket) + { + var deviceInfo = new Dictionary { - Converters = new List { - new StringEnumConverter { - NamingStrategy = new CamelCaseNamingStrategy() - } - }, - NullValueHandling = NullValueHandling.Ignore + { "app_name", "Chrome" }, + { "type", 1 } }; - - private readonly ClientWebSocket socketClient = new(); - - private CancellationTokenSource cancellationTokenSource = new(); - private CancellationToken cancellation; - - private readonly StringBuilder data = new(); - private readonly int size = 4096; - - #endregion Поля - - #region Свойства - - public bool IsConnected => socketClient.State == WebSocketState.Open; - - #endregion Свойства - - #region События - - public class ReceiveEventArgs + var protocol = new Dictionary { - public string Data { get; internal set; } - } + { "Ynison-Device-Id", deviceId }, + { "Ynison-Device-Info", JsonSerializer.Serialize(deviceInfo) } + }; + if (!string.IsNullOrEmpty(redirectTicket)) + protocol.Add("Ynison-Redirect-Ticket", redirectTicket); + return JsonSerializer.Serialize(protocol); + } - public delegate void OnReceiveEventHandler(YnisonWebSocket socket, ReceiveEventArgs args); - /// - /// Получение данных - /// - public event OnReceiveEventHandler OnReceive; - - public class CloseEventArgs + private async Task ReadSocketContentAsync() + { + var buffer = new byte[BufferSize]; + WebSocketReceiveResult result; + do { - public WebSocketCloseStatus? Status { get; set; } - public string Description { get; set; } - } + result = await _socketClient.ReceiveAsync(new ArraySegment(buffer), _cancellationToken); + _data.Append(Encoding.UTF8.GetString(buffer, 0, result.Count)); + } while (!result.EndOfMessage); + return _data.ToString(); + } - public delegate void OnCloseEventHandler(YnisonWebSocket socket, CloseEventArgs args); - /// - /// Закрытие соединения - /// - public event OnCloseEventHandler OnClose; + /// Подключается к WebSocket. + /// Хранилище авторизации. + /// URL WebSocket. + /// Тикет перенаправления (опционально). + public async Task ConnectAsync(AuthStorage storage, string url, string? redirectTicket = null) + { + _socketClient.Options.AddSubProtocol("Bearer"); + var protocolData = GetProtocolData(storage.DeviceId, redirectTicket); + _socketClient.Options.SetRequestHeader("Sec-WebSocket-Protocol", $"Bearer, v2, {protocolData}"); + _socketClient.Options.SetRequestHeader("Origin", "https://music.yandex.ru"); + _socketClient.Options.SetRequestHeader("Authorization", $"OAuth {storage.Token}"); + _socketClient.Options.Proxy = storage.Context.WebProxy; - #endregion События + _cancellationTokenSource = new CancellationTokenSource(); + _cancellationToken = _cancellationTokenSource.Token; - #region Вспомогательные функции + await _socketClient.ConnectAsync(new Uri(url), CancellationToken.None); + } - private string SerializeJson(object obj) + /// Начинает асинхронный приём сообщений. + public async Task BeginReceiveAsync() + { + if (_socketClient.State != WebSocketState.Open) + return; + + try { - return JsonConvert.SerializeObject(obj, jsonSettings); - } - - private string GetProtocolData(string deviceId, string redirectTicket) - { - Dictionary deviceInfo = new() { - { "app_name", "Chrome" }, - { "type", 1 } - }; - - Dictionary protocol = new() { - { "Ynison-Device-Id", deviceId }, - { "Ynison-Device-Info", SerializeJson(deviceInfo) } - }; - - if (!string.IsNullOrEmpty(redirectTicket)) - protocol.Add("Ynison-Redirect-Ticket", redirectTicket); - - return SerializeJson(protocol); - } - - private async Task ReadSocketContent() - { - byte[] buffer = new byte[size]; - WebSocketReceiveResult result; - - do + while (!_cancellationToken.IsCancellationRequested && _socketClient.State == WebSocketState.Open) { - result = await socketClient.ReceiveAsync(new ArraySegment(buffer), CancellationToken.None); - data.Append(Encoding.UTF8.GetString(buffer, 0, result.Count)); - } while (!result.EndOfMessage); - - return data.ToString(); + var content = await ReadSocketContentAsync(); + OnReceive?.Invoke(this, new ReceiveEventArgs { Data = content }); + _data.Clear(); + } } - - #endregion Вспомогательные функции - - - - public bool Connect(AuthStorage storage, string url, string redirectTicket = null) + catch (OperationCanceledException) { - socketClient.Options.AddSubProtocol("Bearer"); - - socketClient.Options.SetRequestHeader("Sec-WebSocket-Protocol", $"Bearer, v2, {GetProtocolData(storage.DeviceId, redirectTicket)}"); - socketClient.Options.SetRequestHeader("Origin", "https://music.yandex.ru"); - socketClient.Options.SetRequestHeader("Authorization", $"OAuth {storage.Token}"); - - socketClient.Options.Proxy = storage.Context.WebProxy; - - socketClient.ConnectAsync(new Uri(url), CancellationToken.None) - .GetAwaiter() - .GetResult(); - - cancellation = cancellationTokenSource.Token; - - return socketClient.State == WebSocketState.Open; + // Ожидаемая отмена } - - public async Task BeginReceive() + finally { - if (socketClient.State != WebSocketState.Open) - return; - - do - { - string content = await ReadSocketContent(); - OnReceive?.Invoke(this, new ReceiveEventArgs - { - Data = content - }); - - data.Clear(); - } while (!cancellation.IsCancellationRequested && socketClient.State == WebSocketState.Open); - - OnClose?.Invoke(this, new CloseEventArgs - { - Status = socketClient.CloseStatus, - Description = socketClient.CloseStatusDescription - }); - - await socketClient.CloseAsync(WebSocketCloseStatus.NormalClosure, string.Empty, CancellationToken.None); + var closeStatus = _socketClient.CloseStatus; + var closeDesc = _socketClient.CloseStatusDescription; + OnClose?.Invoke(this, new CloseEventArgs { Status = closeStatus, Description = closeDesc }); + if (_socketClient.State == WebSocketState.Open) + await _socketClient.CloseAsync(WebSocketCloseStatus.NormalClosure, string.Empty, CancellationToken.None); } + } + /// Отправляет JSON-сообщение. + /// JSON-строка. + public async ValueTask SendAsync(string json) + { + var bytes = Encoding.UTF8.GetBytes(json); + await _socketClient.SendAsync(new ArraySegment(bytes), WebSocketMessageType.Text, true, _cancellationToken); + } - public ValueTask Send(string json) + /// Останавливает приём сообщений. + public async Task StopReceiveAsync() + { + if (_cancellationTokenSource != null && !_cancellationTokenSource.IsCancellationRequested) { - ReadOnlyMemory message = new(Encoding.UTF8.GetBytes(json)); - return socketClient.SendAsync(message, WebSocketMessageType.Text, false, CancellationToken.None); + await _cancellationTokenSource.CancelAsync(); } + } - public Task StopReceive() - { - if (socketClient.State != WebSocketState.Open) - return Task.CompletedTask; - - cancellationTokenSource.Cancel(false); - - return Task.CompletedTask; - } - - - - #region IDisposable - - public void Dispose() - { - socketClient?.Dispose(); - cancellationTokenSource?.Dispose(); - } - - #endregion IDisposable + /// Освобождает ресурсы. + public void Dispose() + { + _cancellationTokenSource?.Dispose(); + _socketClient.Dispose(); + GC.SuppressFinalize(this); } } \ No newline at end of file diff --git a/YandexMusic.API/Extensions/API/YAlbumExtensions.cs b/YandexMusic.API/Extensions/API/YAlbumExtensions.cs index 5585628..e0d7e94 100644 --- a/YandexMusic.API/Extensions/API/YAlbumExtensions.cs +++ b/YandexMusic.API/Extensions/API/YAlbumExtensions.cs @@ -1,25 +1,24 @@ using YandexMusic.API.Models.Album; -namespace YandexMusic.API.Extensions.API +namespace YandexMusic.API.Extensions.API; + +/// +/// Методы-расширения для альбома +/// +public static partial class YAlbumExtensions { - /// - /// Методы-расширения для альбома - /// - public static partial class YAlbumExtensions + public static YAlbum WithTracks(this YAlbum album) { - public static YAlbum WithTracks(this YAlbum album) - { - return WithTracksAsync(album).GetAwaiter().GetResult(); - } + return WithTracksAsync(album).GetAwaiter().GetResult(); + } - public static string AddLike(this YAlbum album) - { - return AddLikeAsync(album).GetAwaiter().GetResult(); - } + public static string AddLike(this YAlbum album) + { + return AddLikeAsync(album).GetAwaiter().GetResult(); + } - public static string RemoveLike(this YAlbum album) - { - return RemoveLikeAsync(album).GetAwaiter().GetResult(); - } + public static string RemoveLike(this YAlbum album) + { + return RemoveLikeAsync(album).GetAwaiter().GetResult(); } } diff --git a/YandexMusic.API/Extensions/API/YAlbumExtensionsAsync.cs b/YandexMusic.API/Extensions/API/YAlbumExtensionsAsync.cs index ca5243c..0007837 100644 --- a/YandexMusic.API/Extensions/API/YAlbumExtensionsAsync.cs +++ b/YandexMusic.API/Extensions/API/YAlbumExtensionsAsync.cs @@ -1,30 +1,29 @@ using YandexMusic.API.Models.Album; -namespace YandexMusic.API.Extensions.API +namespace YandexMusic.API.Extensions.API; + +/// +/// Методы-расширения для альбома +/// +public static partial class YAlbumExtensions { - /// - /// Методы-расширения для альбома - /// - public static partial class YAlbumExtensions + public static async Task WithTracksAsync(this YAlbum album) { - public static async Task WithTracksAsync(this YAlbum album) - { - return album.Volumes != null - ? album - : (await album.Context.API.Album.GetAsync(album.Context.Storage, album.Id)) - .Result; - } - - public static async Task AddLikeAsync(this YAlbum album) - { - return (await album.Context.API.Library.AddAlbumLikeAsync(album.Context.Storage, album)) + return album.Volumes != null + ? album + : (await album.Context.API.Album.GetAsync(album.Context.Storage, album.Id)) .Result; - } + } - public static async Task RemoveLikeAsync(this YAlbum album) - { - return (await album.Context.API.Library.RemoveAlbumLikeAsync(album.Context.Storage, album)) - .Result; - } + public static async Task AddLikeAsync(this YAlbum album) + { + return (await album.Context.API.Library.AddAlbumLikeAsync(album.Context.Storage, album)) + .Result; + } + + public static async Task RemoveLikeAsync(this YAlbum album) + { + return (await album.Context.API.Library.RemoveAlbumLikeAsync(album.Context.Storage, album)) + .Result; } } diff --git a/YandexMusic.API/Extensions/API/YArtistExtensions.cs b/YandexMusic.API/Extensions/API/YArtistExtensions.cs index e9c4f2e..f80160d 100644 --- a/YandexMusic.API/Extensions/API/YArtistExtensions.cs +++ b/YandexMusic.API/Extensions/API/YArtistExtensions.cs @@ -1,36 +1,35 @@ using YandexMusic.API.Models.Artist; using YandexMusic.API.Models.Track; -namespace YandexMusic.API.Extensions.API +namespace YandexMusic.API.Extensions.API; + +/// +/// Методы-расширения для исполнителя +/// +public static partial class YArtistExtensions { - /// - /// Методы-расширения для исполнителя - /// - public static partial class YArtistExtensions + public static YArtistBriefInfo BriefInfo(this YArtist artist) { - public static YArtistBriefInfo BriefInfo(this YArtist artist) - { - return BriefInfoAsync(artist).GetAwaiter().GetResult(); - } + return BriefInfoAsync(artist).GetAwaiter().GetResult(); + } - public static YTracksPage GetTracks(this YArtist artist, int page = 0, int pageSize = 20) - { - return GetTracksAsync(artist, page, pageSize).GetAwaiter().GetResult(); - } + public static YTracksPage GetTracks(this YArtist artist, int page = 0, int pageSize = 20) + { + return GetTracksAsync(artist, page, pageSize).GetAwaiter().GetResult(); + } - public static List GetAllTracks(this YArtist artist) - { - return GetAllTracksAsync(artist).GetAwaiter().GetResult(); - } + public static List GetAllTracks(this YArtist artist) + { + return GetAllTracksAsync(artist).GetAwaiter().GetResult(); + } - public static string AddLike(this YArtist artist) - { - return AddLikeAsync(artist).GetAwaiter().GetResult(); - } + public static string AddLike(this YArtist artist) + { + return AddLikeAsync(artist).GetAwaiter().GetResult(); + } - public static string RemoveLike(this YArtist artist) - { - return RemoveLikeAsync(artist).GetAwaiter().GetResult(); - } + public static string RemoveLike(this YArtist artist) + { + return RemoveLikeAsync(artist).GetAwaiter().GetResult(); } } diff --git a/YandexMusic.API/Extensions/API/YArtistExtensionsAsync.cs b/YandexMusic.API/Extensions/API/YArtistExtensionsAsync.cs index 6812591..0d99bd2 100644 --- a/YandexMusic.API/Extensions/API/YArtistExtensionsAsync.cs +++ b/YandexMusic.API/Extensions/API/YArtistExtensionsAsync.cs @@ -1,41 +1,40 @@ using YandexMusic.API.Models.Artist; using YandexMusic.API.Models.Track; -namespace YandexMusic.API.Extensions.API +namespace YandexMusic.API.Extensions.API; + +/// +/// Методы-расширения для исполнителя +/// +public static partial class YArtistExtensions { - /// - /// Методы-расширения для исполнителя - /// - public static partial class YArtistExtensions + public static async Task BriefInfoAsync(this YArtist artist) { - public static async Task BriefInfoAsync(this YArtist artist) - { - return (await artist.Context.API.Artist.GetAsync(artist.Context.Storage, artist.Id)) - .Result; - } + return (await artist.Context.API.Artist.GetAsync(artist.Context.Storage, artist.Id)) + .Result; + } - public static async Task GetTracksAsync(this YArtist artist, int page = 0, int pageSize = 20) - { - return (await artist.Context.API.Artist.GetTracksAsync(artist.Context.Storage, artist.Id, page, pageSize)) - .Result; - } + public static async Task GetTracksAsync(this YArtist artist, int page = 0, int pageSize = 20) + { + return (await artist.Context.API.Artist.GetTracksAsync(artist.Context.Storage, artist.Id, page, pageSize)) + .Result; + } - public static async Task> GetAllTracksAsync(this YArtist artist) - { - return (await artist.Context.API.Artist.GetAllTracksAsync(artist.Context.Storage, artist.Id)) - .Result.Tracks; - } + public static async Task> GetAllTracksAsync(this YArtist artist) + { + return (await artist.Context.API.Artist.GetAllTracksAsync(artist.Context.Storage, artist.Id)) + .Result.Tracks; + } - public static async Task AddLikeAsync(this YArtist artist) - { - return (await artist.Context.API.Library.AddArtistLikeAsync(artist.Context.Storage, artist)) - .Result; - } + public static async Task AddLikeAsync(this YArtist artist) + { + return (await artist.Context.API.Library.AddArtistLikeAsync(artist.Context.Storage, artist)) + .Result; + } - public static async Task RemoveLikeAsync(this YArtist artist) - { - return (await artist.Context.API.Library.RemoveArtistLikeAsync(artist.Context.Storage, artist)) - .Result; - } + public static async Task RemoveLikeAsync(this YArtist artist) + { + return (await artist.Context.API.Library.RemoveArtistLikeAsync(artist.Context.Storage, artist)) + .Result; } } diff --git a/YandexMusic.API/Extensions/API/YPlaylistExtensions.cs b/YandexMusic.API/Extensions/API/YPlaylistExtensions.cs index ef3b46f..222ea9f 100644 --- a/YandexMusic.API/Extensions/API/YPlaylistExtensions.cs +++ b/YandexMusic.API/Extensions/API/YPlaylistExtensions.cs @@ -1,56 +1,55 @@ using YandexMusic.API.Models.Playlist; using YandexMusic.API.Models.Track; -namespace YandexMusic.API.Extensions.API +namespace YandexMusic.API.Extensions.API; + +/// +/// Методы-расширения для плейлиста +/// +public static partial class YPlaylistExtensions { - /// - /// Методы-расширения для плейлиста - /// - public static partial class YPlaylistExtensions + private static bool CheckUser(YPlaylist playlist) { - private static bool CheckUser(YPlaylist playlist) - { - return playlist.Owner.Uid == playlist.Context.Storage.User.Uid; - } + return playlist.Owner.Uid == playlist.Context.Storage.User.Uid; + } - public static YPlaylist WithTracks(this YPlaylist playlist) - { - return WithTracksAsync(playlist).GetAwaiter().GetResult(); - } + public static YPlaylist WithTracks(this YPlaylist playlist) + { + return WithTracksAsync(playlist).GetAwaiter().GetResult(); + } - public static string AddLike(this YPlaylist playlist) - { - return AddLikeAsync(playlist).GetAwaiter().GetResult(); - } + public static string AddLike(this YPlaylist playlist) + { + return AddLikeAsync(playlist).GetAwaiter().GetResult(); + } - public static string RemoveLike(this YPlaylist playlist) - { - return RemoveLikeAsync(playlist).GetAwaiter().GetResult(); - } + public static string RemoveLike(this YPlaylist playlist) + { + return RemoveLikeAsync(playlist).GetAwaiter().GetResult(); + } - public static YPlaylist Rename(this YPlaylist playlist, string newName) - { - return RenameAsync(playlist, newName).GetAwaiter().GetResult(); - } + public static YPlaylist Rename(this YPlaylist playlist, string newName) + { + return RenameAsync(playlist, newName).GetAwaiter().GetResult(); + } - public static bool Delete(this YPlaylist playlist) - { - return DeleteAsync(playlist).GetAwaiter().GetResult(); - } + public static bool Delete(this YPlaylist playlist) + { + return DeleteAsync(playlist).GetAwaiter().GetResult(); + } - public static YPlaylist InsertTracks(this YPlaylist playlist, params YTrack[] tracks) - { - return InsertTracksAsync(playlist, tracks).GetAwaiter().GetResult(); - } + public static YPlaylist InsertTracks(this YPlaylist playlist, params YTrack[] tracks) + { + return InsertTracksAsync(playlist, tracks).GetAwaiter().GetResult(); + } - public static YPlaylist RemoveTracks(this YPlaylist playlist, params YTrack[] tracks) - { - return RemoveTracksAsync(playlist, tracks).GetAwaiter().GetResult(); - } + public static YPlaylist RemoveTracks(this YPlaylist playlist, params YTrack[] tracks) + { + return RemoveTracksAsync(playlist, tracks).GetAwaiter().GetResult(); + } - public static bool UploadTracks(this YPlaylist playlist, string filePath, string fileName) - { - return UploadTracksAsync(playlist, filePath, fileName).GetAwaiter().GetResult(); - } + public static bool UploadTracks(this YPlaylist playlist, string filePath, string fileName) + { + return UploadTracksAsync(playlist, filePath, fileName).GetAwaiter().GetResult(); } } diff --git a/YandexMusic.API/Extensions/API/YPlaylistExtensionsAsync.cs b/YandexMusic.API/Extensions/API/YPlaylistExtensionsAsync.cs index e1338d3..bcfaf5b 100644 --- a/YandexMusic.API/Extensions/API/YPlaylistExtensionsAsync.cs +++ b/YandexMusic.API/Extensions/API/YPlaylistExtensionsAsync.cs @@ -1,72 +1,71 @@ using YandexMusic.API.Models.Playlist; using YandexMusic.API.Models.Track; -namespace YandexMusic.API.Extensions.API +namespace YandexMusic.API.Extensions.API; + +/// +/// Методы-расширения для плейлиста +/// +public static partial class YPlaylistExtensions { - /// - /// Методы-расширения для плейлиста - /// - public static partial class YPlaylistExtensions + public static async Task WithTracksAsync(this YPlaylist playlist) { - public static async Task WithTracksAsync(this YPlaylist playlist) - { - return playlist.Tracks != null - ? playlist - : (await playlist.Context.API.Playlist.GetAsync(playlist.Context.Storage, playlist)) - .Result; - } - - public static async Task AddLikeAsync(this YPlaylist playlist) - { - return (await playlist.Context.API.Library.AddPlaylistLikeAsync(playlist.Context.Storage, playlist)) + return playlist.Tracks != null + ? playlist + : (await playlist.Context.API.Playlist.GetAsync(playlist.Context.Storage, playlist)) .Result; - } + } - public static async Task RemoveLikeAsync(this YPlaylist playlist) - { - return (await playlist.Context.API.Library.RemovePlaylistLikeAsync(playlist.Context.Storage, playlist)) - .Result; - } + public static async Task AddLikeAsync(this YPlaylist playlist) + { + return (await playlist.Context.API.Library.AddPlaylistLikeAsync(playlist.Context.Storage, playlist)) + .Result; + } - public static async Task RenameAsync(this YPlaylist playlist, string newName) - { - return CheckUser(playlist) - ? (await playlist.Context.API.Playlist.RenameAsync(playlist.Context.Storage, playlist, newName)) - .Result - : playlist; - } + public static async Task RemoveLikeAsync(this YPlaylist playlist) + { + return (await playlist.Context.API.Library.RemovePlaylistLikeAsync(playlist.Context.Storage, playlist)) + .Result; + } - public static async Task DeleteAsync(this YPlaylist playlist) - { - return CheckUser(playlist) && await playlist.Context.API.Playlist.DeleteAsync(playlist.Context.Storage, playlist); - } + public static async Task RenameAsync(this YPlaylist playlist, string newName) + { + return CheckUser(playlist) + ? (await playlist.Context.API.Playlist.RenameAsync(playlist.Context.Storage, playlist, newName)) + .Result + : playlist; + } - public static async Task InsertTracksAsync(this YPlaylist playlist, params YTrack[] tracks) - { - return CheckUser(playlist) - ? (await playlist.Context.API.Playlist.InsertTracksAsync(playlist.Context.Storage, playlist, tracks)) - .Result - : playlist; - } + public static async Task DeleteAsync(this YPlaylist playlist) + { + return CheckUser(playlist) && await playlist.Context.API.Playlist.DeleteAsync(playlist.Context.Storage, playlist); + } - public static async Task RemoveTracksAsync(this YPlaylist playlist, params YTrack[] tracks) - { - return CheckUser(playlist) - ? (await playlist.Context.API.Playlist.DeleteTracksAsync(playlist.Context.Storage, playlist, tracks)) - .Result - : playlist; - } + public static async Task InsertTracksAsync(this YPlaylist playlist, params YTrack[] tracks) + { + return CheckUser(playlist) + ? (await playlist.Context.API.Playlist.InsertTracksAsync(playlist.Context.Storage, playlist, tracks)) + .Result + : playlist; + } - public static async Task UploadTracksAsync(this YPlaylist playlist, string filePath, string fileName) - { - if (!CheckUser(playlist)) - return false; + public static async Task RemoveTracksAsync(this YPlaylist playlist, params YTrack[] tracks) + { + return CheckUser(playlist) + ? (await playlist.Context.API.Playlist.DeleteTracksAsync(playlist.Context.Storage, playlist, tracks)) + .Result + : playlist; + } - string target = (await playlist.Context.API.UserGeneratedContent.GetUgcUploadLinkAsync(playlist.Context.Storage, playlist, fileName)) - .PostTarget; + public static async Task UploadTracksAsync(this YPlaylist playlist, string filePath, string fileName) + { + if (!CheckUser(playlist)) + return false; - return (await playlist.Context.API.UserGeneratedContent.UploadUgcTrackAsync(playlist.Context.Storage, target, filePath)) - .Result == "CREATED"; - } + string target = (await playlist.Context.API.UserGeneratedContent.GetUgcUploadLinkAsync(playlist.Context.Storage, playlist, fileName)) + .PostTarget; + + return (await playlist.Context.API.UserGeneratedContent.UploadUgcTrackAsync(playlist.Context.Storage, target, filePath)) + .Result == "CREATED"; } } diff --git a/YandexMusic.API/Extensions/API/YStationResultExtensions.cs b/YandexMusic.API/Extensions/API/YStationResultExtensions.cs index 39e11a0..f0d774b 100644 --- a/YandexMusic.API/Extensions/API/YStationResultExtensions.cs +++ b/YandexMusic.API/Extensions/API/YStationResultExtensions.cs @@ -1,26 +1,25 @@ using YandexMusic.API.Models.Radio; using YandexMusic.API.Models.Track; -namespace YandexMusic.API.Extensions.API +namespace YandexMusic.API.Extensions.API; + +/// +/// Методы-расширения для радиостанции +/// +public static partial class YStationResultExtensions { - /// - /// Методы-расширения для радиостанции - /// - public static partial class YStationResultExtensions + public static List GetTracks(this YStation station, string prevTrackId = "") { - public static List GetTracks(this YStation station, string prevTrackId = "") - { - return GetTracksAsync(station, prevTrackId).GetAwaiter().GetResult(); - } + return GetTracksAsync(station, prevTrackId).GetAwaiter().GetResult(); + } - public static string SetSettings2(this YStation station, YStationSettings2 settings) - { - return SetSettings2Async(station, settings).GetAwaiter().GetResult(); - } + public static string SetSettings2(this YStation station, YStationSettings2 settings) + { + return SetSettings2Async(station, settings).GetAwaiter().GetResult(); + } - public static string SendFeedBack(this YStation station, YStationFeedbackType type, YTrack track = null, string batchId = "", double totalPlayedSeconds = 0) - { - return SendFeedBackAsync(station, type, track, batchId, totalPlayedSeconds).GetAwaiter().GetResult(); - } + public static string SendFeedBack(this YStation station, YStationFeedbackType type, YTrack track = null, string batchId = "", double totalPlayedSeconds = 0) + { + return SendFeedBackAsync(station, type, track, batchId, totalPlayedSeconds).GetAwaiter().GetResult(); } } diff --git a/YandexMusic.API/Extensions/API/YStationResultExtensionsAsync.cs b/YandexMusic.API/Extensions/API/YStationResultExtensionsAsync.cs index 764e007..9ac2a48 100644 --- a/YandexMusic.API/Extensions/API/YStationResultExtensionsAsync.cs +++ b/YandexMusic.API/Extensions/API/YStationResultExtensionsAsync.cs @@ -1,28 +1,27 @@ using YandexMusic.API.Models.Radio; using YandexMusic.API.Models.Track; -namespace YandexMusic.API.Extensions.API +namespace YandexMusic.API.Extensions.API; + +/// +/// Методы-расширения для радиостанции +/// +public static partial class YStationResultExtensions { - /// - /// Методы-расширения для радиостанции - /// - public static partial class YStationResultExtensions + public static async Task> GetTracksAsync(this YStation station, string prevTrackId = "") { - public static async Task> GetTracksAsync(this YStation station, string prevTrackId = "") - { - return (await station.Context.API.Radio.GetStationTracksAsync(station.Context.Storage, station, prevTrackId)) - .Result.Sequence; - } + return (await station.Context.API.Radio.GetStationTracksAsync(station.Context.Storage, station, prevTrackId)) + .Result.Sequence; + } - public static async Task SetSettings2Async(this YStation station, YStationSettings2 settings) - { - return (await station.Context.API.Radio.SetStationSettings2Async(station.Context.Storage, station, settings)) - .Result; - } + public static async Task SetSettings2Async(this YStation station, YStationSettings2 settings) + { + return (await station.Context.API.Radio.SetStationSettings2Async(station.Context.Storage, station, settings)) + .Result; + } - public static Task SendFeedBackAsync(this YStation station, YStationFeedbackType type, YTrack track = null, string batchId = "", double totalPlayedSeconds = 0) - { - return station.Context.API.Radio.SendStationFeedBackAsync(station.Context.Storage, station, type, track, batchId, totalPlayedSeconds); - } + public static Task SendFeedBackAsync(this YStation station, YStationFeedbackType type, YTrack track = null, string batchId = "", double totalPlayedSeconds = 0) + { + return station.Context.API.Radio.SendStationFeedBackAsync(station.Context.Storage, station, type, track, batchId, totalPlayedSeconds); } } diff --git a/YandexMusic.API/Extensions/API/YTrackExtensions.cs b/YandexMusic.API/Extensions/API/YTrackExtensions.cs index 052e621..61465c6 100644 --- a/YandexMusic.API/Extensions/API/YTrackExtensions.cs +++ b/YandexMusic.API/Extensions/API/YTrackExtensions.cs @@ -1,55 +1,54 @@ using YandexMusic.API.Models.Track; -namespace YandexMusic.API.Extensions.API +namespace YandexMusic.API.Extensions.API; + +/// +/// Методы-расширения для трека +/// +public static partial class YTrackExtensions { - /// - /// Методы-расширения для трека - /// - public static partial class YTrackExtensions + public static string GetLink(this YTrack track) { - public static string GetLink(this YTrack track) - { - return GetLinkAsync(track).GetAwaiter().GetResult(); - } + return GetLinkAsync(track).GetAwaiter().GetResult(); + } - public static void Save(this YTrack track, string filePath) - { - SaveAsync(track, filePath).GetAwaiter().GetResult(); - } + public static void Save(this YTrack track, string filePath) + { + SaveAsync(track, filePath).GetAwaiter().GetResult(); + } - public static int AddLike(this YTrack track) - { - return AddLikeAsync(track).GetAwaiter().GetResult(); - } + public static int AddLike(this YTrack track) + { + return AddLikeAsync(track).GetAwaiter().GetResult(); + } - public static int RemoveLike(this YTrack track) - { - return RemoveLikeAsync(track).GetAwaiter().GetResult(); - } + public static int RemoveLike(this YTrack track) + { + return RemoveLikeAsync(track).GetAwaiter().GetResult(); + } - public static int AddDislike(this YTrack track) - { - return AddDislikeAsync(track).GetAwaiter().GetResult(); - } + public static int AddDislike(this YTrack track) + { + return AddDislikeAsync(track).GetAwaiter().GetResult(); + } - public static int RemoveDislike(this YTrack track) - { - return RemoveDislikeAsync(track).GetAwaiter().GetResult(); - } + public static int RemoveDislike(this YTrack track) + { + return RemoveDislikeAsync(track).GetAwaiter().GetResult(); + } - public static string SendPlayTrackInfo(this YTrack track, string from, bool fromCache = false, string playId = "", string playlistId = "", double totalPlayedSeconds = 0, double endPositionSeconds = 0) - { - return SendPlayTrackInfoAsync(track, from, fromCache, playId, playlistId, totalPlayedSeconds).GetAwaiter().GetResult(); - } + public static string SendPlayTrackInfo(this YTrack track, string from, bool fromCache = false, string playId = "", string playlistId = "", double totalPlayedSeconds = 0, double endPositionSeconds = 0) + { + return SendPlayTrackInfoAsync(track, from, fromCache, playId, playlistId, totalPlayedSeconds).GetAwaiter().GetResult(); + } - public static YTrackSupplement Supplement(this YTrack track) - { - return SupplementAsync(track).GetAwaiter().GetResult(); - } + public static YTrackSupplement Supplement(this YTrack track) + { + return SupplementAsync(track).GetAwaiter().GetResult(); + } - public static YTrackSimilar Similar(this YTrack track) - { - return SimilarAsync(track).GetAwaiter().GetResult(); - } + public static YTrackSimilar Similar(this YTrack track) + { + return SimilarAsync(track).GetAwaiter().GetResult(); } } diff --git a/YandexMusic.API/Extensions/API/YTrackExtensionsAsync.cs b/YandexMusic.API/Extensions/API/YTrackExtensionsAsync.cs index cbfba1f..e1168c3 100644 --- a/YandexMusic.API/Extensions/API/YTrackExtensionsAsync.cs +++ b/YandexMusic.API/Extensions/API/YTrackExtensionsAsync.cs @@ -1,61 +1,60 @@ using YandexMusic.API.Models.Track; -namespace YandexMusic.API.Extensions.API +namespace YandexMusic.API.Extensions.API; + +/// +/// Методы-расширения для трека +/// +public static partial class YTrackExtensions { - /// - /// Методы-расширения для трека - /// - public static partial class YTrackExtensions + public static Task GetLinkAsync(this YTrack track) { - public static Task GetLinkAsync(this YTrack track) - { - return track.Context.API.Track.GetFileLinkAsync(track.Context.Storage, track); - } + return track.Context.API.Track.GetFileLinkAsync(track.Context.Storage, track); + } - public static Task SaveAsync(this YTrack track, string filePath) - { - return track.Context.API.Track.ExtractToFileAsync(track.Context.Storage, track, filePath); - } + public static Task SaveAsync(this YTrack track, string filePath) + { + return track.Context.API.Track.ExtractToFileAsync(track.Context.Storage, track, filePath); + } - public static async Task AddLikeAsync(this YTrack track) - { - return (await track.Context.API.Library.AddTrackLikeAsync(track.Context.Storage, track)) - .Result.Revision; - } + public static async Task AddLikeAsync(this YTrack track) + { + return (await track.Context.API.Library.AddTrackLikeAsync(track.Context.Storage, track)) + .Result.Revision; + } - public static async Task RemoveLikeAsync(this YTrack track) - { - return (await track.Context.API.Library.RemoveTrackLikeAsync(track.Context.Storage, track)) - .Result.Revision; - } + public static async Task RemoveLikeAsync(this YTrack track) + { + return (await track.Context.API.Library.RemoveTrackLikeAsync(track.Context.Storage, track)) + .Result.Revision; + } - public static async Task AddDislikeAsync(this YTrack track) - { - return (await track.Context.API.Library.AddTrackDislikeAsync(track.Context.Storage, track)) - .Result.Revision; - } + public static async Task AddDislikeAsync(this YTrack track) + { + return (await track.Context.API.Library.AddTrackDislikeAsync(track.Context.Storage, track)) + .Result.Revision; + } - public static async Task RemoveDislikeAsync(this YTrack track) - { - return (await track.Context.API.Library.RemoveTrackDislikeAsync(track.Context.Storage, track)) - ?.Result.Revision ?? -1; - } + public static async Task RemoveDislikeAsync(this YTrack track) + { + return (await track.Context.API.Library.RemoveTrackDislikeAsync(track.Context.Storage, track)) + ?.Result.Revision ?? -1; + } - public static Task SendPlayTrackInfoAsync(this YTrack track, string from, bool fromCache = false, string playId = "", string playlistId = "", double totalPlayedSeconds = 0, double endPositionSeconds = 0) - { - return track.Context.API.Track.SendPlayTrackInfoAsync(track.Context.Storage, track, from, fromCache, playId, playlistId, totalPlayedSeconds); - } + public static Task SendPlayTrackInfoAsync(this YTrack track, string from, bool fromCache = false, string playId = "", string playlistId = "", double totalPlayedSeconds = 0, double endPositionSeconds = 0) + { + return track.Context.API.Track.SendPlayTrackInfoAsync(track.Context.Storage, track, from, fromCache, playId, playlistId, totalPlayedSeconds); + } - public static async Task SupplementAsync(this YTrack track) - { - return (await track.Context.API.Track.GetSupplementAsync(track.Context.Storage, track)) - .Result; - } + public static async Task SupplementAsync(this YTrack track) + { + return (await track.Context.API.Track.GetSupplementAsync(track.Context.Storage, track)) + .Result; + } - public static async Task SimilarAsync(this YTrack track) - { - return (await track.Context.API.Track.GetSimilarAsync(track.Context.Storage, track)) - .Result; - } + public static async Task SimilarAsync(this YTrack track) + { + return (await track.Context.API.Track.GetSimilarAsync(track.Context.Storage, track)) + .Result; } } diff --git a/YandexMusic.API/Extensions/HttpRequestHeaderExtensions.cs b/YandexMusic.API/Extensions/HttpRequestHeaderExtensions.cs index 8d6c8e3..18b647a 100644 --- a/YandexMusic.API/Extensions/HttpRequestHeaderExtensions.cs +++ b/YandexMusic.API/Extensions/HttpRequestHeaderExtensions.cs @@ -1,12 +1,11 @@ using System.Net; -namespace YandexMusic.API.Extensions +namespace YandexMusic.API.Extensions; + +public static class HttpRequestHeaderExtensions { - public static class HttpRequestHeaderExtensions + public static string GetName(this HttpRequestHeader header) { - public static string GetName(this HttpRequestHeader header) - { - return header.ToString().SplitByCapitalLetter("-"); - } + return header.ToString().SplitByCapitalLetter("-"); } } \ No newline at end of file diff --git a/YandexMusic.API/Extensions/StringExtensions.cs b/YandexMusic.API/Extensions/StringExtensions.cs index e4911f2..7bb85dc 100644 --- a/YandexMusic.API/Extensions/StringExtensions.cs +++ b/YandexMusic.API/Extensions/StringExtensions.cs @@ -1,50 +1,49 @@ using System.Text.RegularExpressions; -namespace YandexMusic.API.Extensions +namespace YandexMusic.API.Extensions; + +public static class StringExtensions { - public static class StringExtensions + public static string ReplaceRegex(this string str, string regExpr, string replStr, RegexOptions options = RegexOptions.IgnoreCase) { - public static string ReplaceRegex(this string str, string regExpr, string replStr, RegexOptions options = RegexOptions.IgnoreCase) - { - return str == null - ? string.Empty - : Regex.Replace(str, regExpr, replStr); - } + return str == null + ? string.Empty + : Regex.Replace(str, regExpr, replStr); + } - public static string SplitByCapitalLetter(this string str, string delimiter) - { - return string.Join(delimiter, Regex.Matches(str, @"([A-Z]+)(?=([A-Z][a-z]|$)) | [A-Z][a-z].+?(?=([A-Z]|$))", RegexOptions.IgnorePatternWhitespace) + public static string SplitByCapitalLetter(this string str, string delimiter) + { + return string.Join(delimiter, Regex.Matches(str, @"([A-Z]+)(?=([A-Z][a-z]|$)) | [A-Z][a-z].+?(?=([A-Z]|$))", RegexOptions.IgnorePatternWhitespace) + .Cast() + .Select(m => m.ToString())); + } + + /// + /// Проверяет соответствие регулярному выражению + /// + public static bool IsMatch(this string str, string pattern, RegexOptions options) + { + return Regex.IsMatch(str, pattern, options); + } + + /// + /// Проверяет соответствие регулярному выражению + /// + public static bool IsMatch(this string str, string pattern) + { + return IsMatch(str, pattern, RegexOptions.IgnoreCase); + } + + /// + /// Возвращает совпадения для регулярного выражения + /// + public static string[] GetMatches(this string str, string pattern, RegexOptions options = RegexOptions.IgnoreCase) + { + return str.IsMatch(pattern, options) + ? Regex.Matches(str, pattern, options) .Cast() - .Select(m => m.ToString())); - } - - /// - /// Проверяет соответствие регулярному выражению - /// - public static bool IsMatch(this string str, string pattern, RegexOptions options) - { - return Regex.IsMatch(str, pattern, options); - } - - /// - /// Проверяет соответствие регулярному выражению - /// - public static bool IsMatch(this string str, string pattern) - { - return IsMatch(str, pattern, RegexOptions.IgnoreCase); - } - - /// - /// Возвращает совпадения для регулярного выражения - /// - public static string[] GetMatches(this string str, string pattern, RegexOptions options = RegexOptions.IgnoreCase) - { - return str.IsMatch(pattern, options) - ? Regex.Matches(str, pattern, options) - .Cast() - .Select(m => m.Value) - .ToArray() - : new string[] { }; - } + .Select(m => m.Value) + .ToArray() + : new string[] { }; } } \ No newline at end of file diff --git a/YandexMusic.API/Models/Account/YAccessToken.cs b/YandexMusic.API/Models/Account/YAccessToken.cs index 75dbbb3..1ceac5c 100644 --- a/YandexMusic.API/Models/Account/YAccessToken.cs +++ b/YandexMusic.API/Models/Account/YAccessToken.cs @@ -1,15 +1,20 @@ -namespace YandexMusic.API.Models.Account +using System.Text.Json.Serialization; + +namespace YandexMusic.API.Models.Account; + +public class YAccessToken { - public class YAccessToken - { - [JsonProperty("status")] - public string Status { get; set; } - [JsonProperty("access_token")] - public string AccessToken { get; set; } - [JsonProperty("expires_in")] - public string Expires { get; set; } - [JsonProperty("token_type")] - public string TokenType { get; set; } - public string Uid { get; set; } - } + [JsonPropertyName("status")] + public string Status { get; set; } + + [JsonPropertyName("access_token")] + public string AccessToken { get; set; } + + [JsonPropertyName("expires_in")] + public string Expires { get; set; } + + [JsonPropertyName("token_type")] + public string TokenType { get; set; } + + public string Uid { get; set; } } diff --git a/YandexMusic.API/Models/Account/YAccount.cs b/YandexMusic.API/Models/Account/YAccount.cs index c533034..8e463f5 100644 --- a/YandexMusic.API/Models/Account/YAccount.cs +++ b/YandexMusic.API/Models/Account/YAccount.cs @@ -1,25 +1,40 @@ +using System.Text.Json.Serialization; using YandexMusic.API.Models.Common; -namespace YandexMusic.API.Models.Account +namespace YandexMusic.API.Models.Account; + +public class YAccount { - public class YAccount - { - public bool Child { get; set; } - public string Birthday { get; set; } - public string DisplayName { get; set; } - public string FirstName { get; set; } - public string FullName { get; set; } - public bool HostedUser { get; set; } - public string Login { get; set; } - public bool NonOwnerFamilyMember { get; set; } - public DateTime Now { get; set; } - [JsonProperty("passport-phones")] - public List PassportPhones { get; set; } - public int Region { get; set; } - public string RegionCode { get; set; } - public DateTime RegisteredAt { get; set; } - public string SecondName { get; set; } - public bool ServiceAvailable { get; set; } - public string Uid { get; set; } - } + public bool Child { get; set; } + + public string Birthday { get; set; } + + public string DisplayName { get; set; } + + public string FirstName { get; set; } + + public string FullName { get; set; } + + public bool HostedUser { get; set; } + + public string Login { get; set; } + + public bool NonOwnerFamilyMember { get; set; } + + public DateTime Now { get; set; } + + [JsonPropertyName("passport-phones")] + public List PassportPhones { get; set; } + + public int Region { get; set; } + + public string RegionCode { get; set; } + + public DateTime RegisteredAt { get; set; } + + public string SecondName { get; set; } + + public bool ServiceAvailable { get; set; } + + public string Uid { get; set; } } \ No newline at end of file diff --git a/YandexMusic.API/Models/Account/YAccountResult.cs b/YandexMusic.API/Models/Account/YAccountResult.cs index dbeb5ba..dbfe58b 100644 --- a/YandexMusic.API/Models/Account/YAccountResult.cs +++ b/YandexMusic.API/Models/Account/YAccountResult.cs @@ -1,26 +1,37 @@ +using System.Text.Json.Serialization; using YandexMusic.API.Models.Common; -namespace YandexMusic.API.Models.Account +namespace YandexMusic.API.Models.Account; + +public class YAccountResult { - public class YAccountResult + public YAccount Account { get; set; } + + public string DefaultEmail { get; set; } + + public List HasOptions { get; set; } + + public YMasterHub MasterHub { get; set; } + + public YPermissions Permissions { get; set; } + + public YPlus Plus { get; set; } + + public bool PretrialActive { get; set; } + + public bool SubEditor { get; set; } + + public int SubEditorLevel { get; set; } + + public YSubscription Subscription { get; set; } + + public YBar BarBelow { get; set; } + + [JsonPropertyName("bar-below")] + private YBar BarBelow2 { - public YAccount Account { get; set; } - public string DefaultEmail { get; set; } - public List HasOptions { get; set; } - public YMasterHub MasterHub { get; set; } - public YPermissions Permissions { get; set; } - public YPlus Plus { get; set; } - public bool PretrialActive { get; set; } - public bool SubEditor { get; set; } - public int SubEditorLevel { get; set; } - public YSubscription Subscription { get; set; } - public YBar BarBelow { get; set; } - // Повторяющееся свойство с другим названием - [JsonProperty("bar-below")] - private YBar BarBelow2 - { - set => BarBelow = value; - } - public string Userhash { get; set; } + set => BarBelow = value; } + + public string Userhash { get; set; } } \ No newline at end of file diff --git a/YandexMusic.API/Models/Account/YAuthBase.cs b/YandexMusic.API/Models/Account/YAuthBase.cs index 8c02c0b..a476c2a 100644 --- a/YandexMusic.API/Models/Account/YAuthBase.cs +++ b/YandexMusic.API/Models/Account/YAuthBase.cs @@ -1,12 +1,13 @@ -namespace YandexMusic.API.Models.Account +using System.Text.Json.Serialization; + +namespace YandexMusic.API.Models.Account; + +public class YAuthBase { - public class YAuthBase - { - public YAuthStatus Status { get; set; } + public YAuthStatus Status { get; set; } - [JsonProperty("redirect_url")] - public string RedirectUrl { get; set; } + [JsonPropertyName("redirect_url")] + public string RedirectUrl { get; set; } - public List Errors { get; set; } - } + public List Errors { get; set; } } diff --git a/YandexMusic.API/Models/Account/YAuthCaptcha.cs b/YandexMusic.API/Models/Account/YAuthCaptcha.cs index 01becec..23d1b20 100644 --- a/YandexMusic.API/Models/Account/YAuthCaptcha.cs +++ b/YandexMusic.API/Models/Account/YAuthCaptcha.cs @@ -1,28 +1,29 @@ -namespace YandexMusic.API.Models.Account +using System.Text.Json.Serialization; + +namespace YandexMusic.API.Models.Account; + +public class YAuthCaptcha : YAuthBase { - public class YAuthCaptcha : YAuthBase - { - public string Id { get; set; } + public string Id { get; set; } - public string Name { get; set; } + public string Name { get; set; } - public string Label { get; set; } + public string Label { get; set; } - public string Mode { get; set; } + public string Mode { get; set; } - public List Error { get; set; } + public List Error { get; set; } - public bool CountryFromAudioWhiteList { get; set; } + public bool CountryFromAudioWhiteList { get; set; } - public YAuthCaptchaOptions Options { get; set; } + public YAuthCaptchaOptions Options { get; set; } - public YAuthCaptchaVoice Voice { get; set; } + public YAuthCaptchaVoice Voice { get; set; } - [JsonProperty("image_url")] - public string ImageUrl { get; set; } + [JsonPropertyName("image_url")] + public string ImageUrl { get; set; } - public string Key { get; set; } + public string Key { get; set; } - public string Static { get; set; } - } + public string Static { get; set; } } diff --git a/YandexMusic.API/Models/Account/YAuthCaptchaError.cs b/YandexMusic.API/Models/Account/YAuthCaptchaError.cs index 17385f6..38da47f 100644 --- a/YandexMusic.API/Models/Account/YAuthCaptchaError.cs +++ b/YandexMusic.API/Models/Account/YAuthCaptchaError.cs @@ -1,8 +1,7 @@ -namespace YandexMusic.API.Models.Account +namespace YandexMusic.API.Models.Account; + +public class YAuthCaptchaError { - public class YAuthCaptchaError - { - public string Message { get; set; } - public YAuthCaptchaErrorCode Code { get; set; } - } + public string Message { get; set; } + public YAuthCaptchaErrorCode Code { get; set; } } diff --git a/YandexMusic.API/Models/Account/YAuthCaptchaErrorCode.cs b/YandexMusic.API/Models/Account/YAuthCaptchaErrorCode.cs index 5faf756..1375e2a 100644 --- a/YandexMusic.API/Models/Account/YAuthCaptchaErrorCode.cs +++ b/YandexMusic.API/Models/Account/YAuthCaptchaErrorCode.cs @@ -1,9 +1,8 @@ -namespace YandexMusic.API.Models.Account +namespace YandexMusic.API.Models.Account; + +public enum YAuthCaptchaErrorCode { - public enum YAuthCaptchaErrorCode - { - MissingValue, - CaptchaLocate, - Incorrect - } + MissingValue, + CaptchaLocate, + Incorrect } diff --git a/YandexMusic.API/Models/Account/YAuthCaptchaOptions.cs b/YandexMusic.API/Models/Account/YAuthCaptchaOptions.cs index 812e7d5..d65b126 100644 --- a/YandexMusic.API/Models/Account/YAuthCaptchaOptions.cs +++ b/YandexMusic.API/Models/Account/YAuthCaptchaOptions.cs @@ -1,7 +1,6 @@ -namespace YandexMusic.API.Models.Account +namespace YandexMusic.API.Models.Account; + +public class YAuthCaptchaOptions { - public class YAuthCaptchaOptions - { - public bool AsyncCheck { get; set; } - } + public bool AsyncCheck { get; set; } } diff --git a/YandexMusic.API/Models/Account/YAuthCaptchaVoice.cs b/YandexMusic.API/Models/Account/YAuthCaptchaVoice.cs index cdfb7b8..ef1487a 100644 --- a/YandexMusic.API/Models/Account/YAuthCaptchaVoice.cs +++ b/YandexMusic.API/Models/Account/YAuthCaptchaVoice.cs @@ -1,10 +1,11 @@ -namespace YandexMusic.API.Models.Account -{ - public class YAuthCaptchaVoice - { - public string Url { get; set; } +using System.Text.Json.Serialization; - [JsonProperty("intro_url")] - public string IntroUrl { get; set; } - } +namespace YandexMusic.API.Models.Account; + +public class YAuthCaptchaVoice +{ + public string Url { get; set; } + + [JsonPropertyName("intro_url")] + public string IntroUrl { get; set; } } \ No newline at end of file diff --git a/YandexMusic.API/Models/Account/YAuthError.cs b/YandexMusic.API/Models/Account/YAuthError.cs index 1b12e4e..ccc8e06 100644 --- a/YandexMusic.API/Models/Account/YAuthError.cs +++ b/YandexMusic.API/Models/Account/YAuthError.cs @@ -1,22 +1,27 @@ using System.Runtime.Serialization; -namespace YandexMusic.API.Models.Account +namespace YandexMusic.API.Models.Account; + +public enum YAuthError { - public enum YAuthError - { - [EnumMember(Value = "authorization.invalid")] - AuthorizationInvalid, - [EnumMember(Value = "sessionid.invalid")] - SessionIdInvalid, - [EnumMember(Value = "password.not_matched")] - PasswordNotMatched, - [EnumMember(Value = "password.empty")] - PasswordEmpty, - [EnumMember(Value = "captcha.required")] - CaptchaRequired, - [EnumMember(Value = "captcha.not_matched")] - CaptchaNotMatched, - [EnumMember(Value = "oauth_token.invalid")] - OAuthTokenInvalid - } + [EnumMember(Value = "authorization.invalid")] + AuthorizationInvalid, + + [EnumMember(Value = "sessionid.invalid")] + SessionIdInvalid, + + [EnumMember(Value = "password.not_matched")] + PasswordNotMatched, + + [EnumMember(Value = "password.empty")] + PasswordEmpty, + + [EnumMember(Value = "captcha.required")] + CaptchaRequired, + + [EnumMember(Value = "captcha.not_matched")] + CaptchaNotMatched, + + [EnumMember(Value = "oauth_token.invalid")] + OAuthTokenInvalid, } diff --git a/YandexMusic.API/Models/Account/YAuthLetter.cs b/YandexMusic.API/Models/Account/YAuthLetter.cs index 7e13d3a..28d2718 100644 --- a/YandexMusic.API/Models/Account/YAuthLetter.cs +++ b/YandexMusic.API/Models/Account/YAuthLetter.cs @@ -1,9 +1,8 @@ -namespace YandexMusic.API.Models.Account -{ - public class YAuthLetter : YAuthBase - { - public List Code { get; set; } +namespace YandexMusic.API.Models.Account; - public string Id { get; set; } - } +public class YAuthLetter : YAuthBase +{ + public List Code { get; set; } + + public string Id { get; set; } } \ No newline at end of file diff --git a/YandexMusic.API/Models/Account/YAuthLetterStatus.cs b/YandexMusic.API/Models/Account/YAuthLetterStatus.cs index e367ed0..f0c03a4 100644 --- a/YandexMusic.API/Models/Account/YAuthLetterStatus.cs +++ b/YandexMusic.API/Models/Account/YAuthLetterStatus.cs @@ -1,11 +1,12 @@ -namespace YandexMusic.API.Models.Account -{ - public class YAuthLetterStatus : YAuthBase - { - [JsonProperty("magic_link_confirmed")] - public bool MagicLinkConfirmed { get; set; } +using System.Text.Json.Serialization; - [JsonProperty("track_id")] - public string TrackId { get; set; } - } +namespace YandexMusic.API.Models.Account; + +public class YAuthLetterStatus : YAuthBase +{ + [JsonPropertyName("magic_link_confirmed")] + public bool MagicLinkConfirmed { get; set; } + + [JsonPropertyName("track_id")] + public string TrackId { get; set; } } \ No newline at end of file diff --git a/YandexMusic.API/Models/Account/YAuthMethod.cs b/YandexMusic.API/Models/Account/YAuthMethod.cs index fbc77a2..3106e12 100644 --- a/YandexMusic.API/Models/Account/YAuthMethod.cs +++ b/YandexMusic.API/Models/Account/YAuthMethod.cs @@ -1,22 +1,29 @@ using System.Runtime.Serialization; -namespace YandexMusic.API.Models.Account +namespace YandexMusic.API.Models.Account; + +public enum YAuthMethod { - public enum YAuthMethod - { - Password, - [EnumMember(Value = "magic_x_token")] - MagicToken, - [EnumMember(Value = "magic_x_token_with_pictures")] - MagicTokenWithPictures, - [EnumMember(Value = "magic_link")] - MagicLink, - Magic, - Otp, - [EnumMember(Value = "social_gg")] - Social, - WebAuthN, - [EnumMember(Value = "sms_code")] - SmsCode - } + Password, + + [EnumMember(Value = "magic_x_token")] + MagicToken, + + [EnumMember(Value = "magic_x_token_with_pictures")] + MagicTokenWithPictures, + + [EnumMember(Value = "magic_link")] + MagicLink, + + Magic, + + Otp, + + [EnumMember(Value = "social_gg")] + Social, + + WebAuthN, + + [EnumMember(Value = "sms_code")] + SmsCode, } diff --git a/YandexMusic.API/Models/Account/YAuthQr.cs b/YandexMusic.API/Models/Account/YAuthQr.cs index 48c4ac1..ea6b533 100644 --- a/YandexMusic.API/Models/Account/YAuthQr.cs +++ b/YandexMusic.API/Models/Account/YAuthQr.cs @@ -1,11 +1,12 @@ -namespace YandexMusic.API.Models.Account -{ - public class YAuthQR : YAuthBase - { - [JsonProperty("track_id")] - public string TrackId { get; set; } +using System.Text.Json.Serialization; - [JsonProperty("csrf_token")] - public string CsrfToken { get; set; } - } +namespace YandexMusic.API.Models.Account; + +public class YAuthQR : YAuthBase +{ + [JsonPropertyName("track_id")] + public string TrackId { get; set; } + + [JsonPropertyName("csrf_token")] + public string CsrfToken { get; set; } } \ No newline at end of file diff --git a/YandexMusic.API/Models/Account/YAuthQrStatus.cs b/YandexMusic.API/Models/Account/YAuthQrStatus.cs index 707986b..491e7d5 100644 --- a/YandexMusic.API/Models/Account/YAuthQrStatus.cs +++ b/YandexMusic.API/Models/Account/YAuthQrStatus.cs @@ -1,19 +1,20 @@ -namespace YandexMusic.API.Models.Account +using System.Text.Json.Serialization; + +namespace YandexMusic.API.Models.Account; + +public class YAuthQRStatus : YAuthBase { - public class YAuthQRStatus : YAuthBase - { - [JsonProperty("default_uid")] - public int DefaultUid { get; set; } + [JsonPropertyName("default_uid")] + public int DefaultUid { get; set; } - public string RetPath { get; set; } + public string RetPath { get; set; } - [JsonProperty("track_id")] - public string TrackId { get; set; } + [JsonPropertyName("track_id")] + public string TrackId { get; set; } - public string Id { get; set; } + public string Id { get; set; } - public string State { get; set; } + public string State { get; set; } - public YAuthCaptcha Captcha { get; set; } - } + public YAuthCaptcha Captcha { get; set; } } diff --git a/YandexMusic.API/Models/Account/YAuthStatus.cs b/YandexMusic.API/Models/Account/YAuthStatus.cs index 6742cc7..612e9be 100644 --- a/YandexMusic.API/Models/Account/YAuthStatus.cs +++ b/YandexMusic.API/Models/Account/YAuthStatus.cs @@ -1,8 +1,7 @@ -namespace YandexMusic.API.Models.Account +namespace YandexMusic.API.Models.Account; + +public enum YAuthStatus { - public enum YAuthStatus - { - Ok, - Error - } + Ok, + Error } diff --git a/YandexMusic.API/Models/Account/YAuthToken.cs b/YandexMusic.API/Models/Account/YAuthToken.cs index d1aeaa7..6ccee11 100644 --- a/YandexMusic.API/Models/Account/YAuthToken.cs +++ b/YandexMusic.API/Models/Account/YAuthToken.cs @@ -1,11 +1,12 @@ -namespace YandexMusic.API.Models.Account -{ - public class YAuthToken - { - [JsonProperty("csfr_token")] - public string CsfrToken { get; set; } +using System.Text.Json.Serialization; - [JsonProperty("track_id")] - public string TrackId { get; set; } - } +namespace YandexMusic.API.Models.Account; + +public class YAuthToken +{ + [JsonPropertyName("csfr_token")] + public string CsfrToken { get; set; } + + [JsonPropertyName("track_id")] + public string TrackId { get; set; } } \ No newline at end of file diff --git a/YandexMusic.API/Models/Account/YAuthTypes.cs b/YandexMusic.API/Models/Account/YAuthTypes.cs index 378f392..d8866dd 100644 --- a/YandexMusic.API/Models/Account/YAuthTypes.cs +++ b/YandexMusic.API/Models/Account/YAuthTypes.cs @@ -1,47 +1,48 @@ -namespace YandexMusic.API.Models.Account +using System.Text.Json.Serialization; + +namespace YandexMusic.API.Models.Account; + +public class YAuthTypes : YAuthBase { - public class YAuthTypes : YAuthBase - { - [JsonProperty("primary_alias_type")] - public string PrimaryAliasType { get; set; } + [JsonPropertyName("primary_alias_type")] + public string PrimaryAliasType { get; set; } - [JsonProperty("csrf_token")] - public string CsrfToken { get; set; } + [JsonPropertyName("csrf_token")] + public string CsrfToken { get; set; } - public string LocCsrf { get; set; } + public string LocCsrf { get; set; } - [JsonProperty("use_new_suggest_by_phone")] - public bool UseNewSuggestByPhone { get; set; } + [JsonPropertyName("use_new_suggest_by_phone")] + public bool UseNewSuggestByPhone { get; set; } - [JsonProperty("is_rfc_2fa_enabled")] - public bool IsRfc2faEnabled { get; set; } + [JsonPropertyName("is_rfc_2fa_enabled")] + public bool IsRfc2faEnabled { get; set; } - [JsonProperty("track_id")] - public string TrackId { get; set; } + [JsonPropertyName("track_id")] + public string TrackId { get; set; } - [JsonProperty("can_authorize")] - public string CanAuthorize { get; set; } + [JsonPropertyName("can_authorize")] + public string CanAuthorize { get; set; } - [JsonProperty("preferred_auth_method")] - public YAuthMethod PreferredAuthMethod { get; set; } + [JsonPropertyName("preferred_auth_method")] + public YAuthMethod PreferredAuthMethod { get; set; } - [JsonProperty("auth_methods")] - public List AuthMethods { get; set; } + [JsonPropertyName("auth_methods")] + public List AuthMethods { get; set; } - [JsonProperty("can_register")] - public bool CanRegister { get; set; } + [JsonPropertyName("can_register")] + public bool CanRegister { get; set; } - [JsonProperty("location_id")] - public string LocationId { get; set; } + [JsonPropertyName("location_id")] + public string LocationId { get; set; } - public string Country { get; set; } + public string Country { get; set; } - [JsonProperty("phone_number")] - public YPhoneNumber PhoneNumberNumber { get; set; } + [JsonPropertyName("phone_number")] + public YPhoneNumber PhoneNumberNumber { get; set; } - [JsonProperty("magic_link_email")] - public string MagicLinkEmail { get; set; } + [JsonPropertyName("magic_link_email")] + public string MagicLinkEmail { get; set; } - public string TractorTargetLocationHost { get; set; } - } + public string TractorTargetLocationHost { get; set; } } \ No newline at end of file diff --git a/YandexMusic.API/Models/Account/YBar.cs b/YandexMusic.API/Models/Account/YBar.cs index 770bcc5..9f126d6 100644 --- a/YandexMusic.API/Models/Account/YBar.cs +++ b/YandexMusic.API/Models/Account/YBar.cs @@ -1,14 +1,13 @@ using YandexMusic.API.Models.Common; -namespace YandexMusic.API.Models.Account +namespace YandexMusic.API.Models.Account; + +public class YBar : YStyle { - public class YBar : YStyle - { - public string AlertId { get; set; } - public string Text { get; set; } - public string AlertType { get; set; } - public YButton Button { get; set; } - public bool CloseButton { get; set; } - public YCloseButtonStyles CloseButtonStyles { get; set; } - } + public string AlertId { get; set; } + public string Text { get; set; } + public string AlertType { get; set; } + public YButton Button { get; set; } + public bool CloseButton { get; set; } + public YCloseButtonStyles CloseButtonStyles { get; set; } } diff --git a/YandexMusic.API/Models/Account/YLoginInfo.cs b/YandexMusic.API/Models/Account/YLoginInfo.cs index 829518b..9519035 100644 --- a/YandexMusic.API/Models/Account/YLoginInfo.cs +++ b/YandexMusic.API/Models/Account/YLoginInfo.cs @@ -1,31 +1,32 @@ -namespace YandexMusic.API.Models.Account +using System.Text.Json.Serialization; + +namespace YandexMusic.API.Models.Account; + +public class YLoginInfo { - public class YLoginInfo - { - public string Id { get; set; } - public string Login { get; set; } - [JsonProperty("client_id")] - public string ClientId { get; set; } - [JsonProperty("display_name")] - public string DisplayName { get; set; } - [JsonProperty("real_name")] - public string RealName { get; set; } - [JsonProperty("first_name")] - public string FirstName { get; set; } - [JsonProperty("last_name")] - public string LastName { get; set; } - public string Sex { get; set; } - [JsonProperty("default_email")] - public string DefaultEmail { get; set; } - public List Emails { get; set; } - public string Birthday { get; set; } - [JsonProperty("default_avatar_id")] - public string DefaultAvatarId { get; set; } + public string Id { get; set; } + public string Login { get; set; } + [JsonPropertyName("client_id")] + public string ClientId { get; set; } + [JsonPropertyName("display_name")] + public string DisplayName { get; set; } + [JsonPropertyName("real_name")] + public string RealName { get; set; } + [JsonPropertyName("first_name")] + public string FirstName { get; set; } + [JsonPropertyName("last_name")] + public string LastName { get; set; } + public string Sex { get; set; } + [JsonPropertyName("default_email")] + public string DefaultEmail { get; set; } + public List Emails { get; set; } + public string Birthday { get; set; } + [JsonPropertyName("default_avatar_id")] + public string DefaultAvatarId { get; set; } - public string AvatarUrl => $"https://avatars.mds.yandex.net/get-yapic/{DefaultAvatarId}/islands-200"; - [JsonProperty("is_avatar_empty")] - public bool IsAvatarEmpty { get; set; } - public string PsuId { get; set; } + public string AvatarUrl => $"https://avatars.mds.yandex.net/get-yapic/{DefaultAvatarId}/islands-200"; + [JsonPropertyName("is_avatar_empty")] + public bool IsAvatarEmpty { get; set; } + public string PsuId { get; set; } - } } \ No newline at end of file diff --git a/YandexMusic.API/Models/Account/YPhoneNumber.cs b/YandexMusic.API/Models/Account/YPhoneNumber.cs index 70c9f2e..4a97a34 100644 --- a/YandexMusic.API/Models/Account/YPhoneNumber.cs +++ b/YandexMusic.API/Models/Account/YPhoneNumber.cs @@ -1,20 +1,21 @@ -namespace YandexMusic.API.Models.Account +using System.Text.Json.Serialization; + +namespace YandexMusic.API.Models.Account; + +public class YPhoneNumber { - public class YPhoneNumber - { - [JsonProperty("masked_e164")] - public string MaskedE164 { get; set; } + [JsonPropertyName("masked_e164")] + public string MaskedE164 { get; set; } - public string E164 { get; set; } + public string E164 { get; set; } - public string International { get; set; } + public string International { get; set; } - [JsonProperty("masked_original")] - public string MaskedOriginal { get; set; } + [JsonPropertyName("masked_original")] + public string MaskedOriginal { get; set; } - public string Original { get; set; } + public string Original { get; set; } - [JsonProperty("masked_international")] - public string MaskedInternational { get; set; } - } + [JsonPropertyName("masked_international")] + public string MaskedInternational { get; set; } } \ No newline at end of file diff --git a/YandexMusic.API/Models/Account/YShortAccountInfo.cs b/YandexMusic.API/Models/Account/YShortAccountInfo.cs index a1768da..6edf8e9 100644 --- a/YandexMusic.API/Models/Account/YShortAccountInfo.cs +++ b/YandexMusic.API/Models/Account/YShortAccountInfo.cs @@ -1,8 +1,10 @@ -namespace YandexMusic.API.Models.Account +using System.Text.Json.Serialization; + +namespace YandexMusic.API.Models.Account { public class YShortAccountInfo : YAuthBase { - [JsonProperty("public_id")] + [JsonPropertyName("public_id")] public string PublicId { get; set; } public string Uid { get; set; } @@ -13,69 +15,69 @@ public string Birthday { get; set; } - [JsonProperty("has_password")] + [JsonPropertyName("has_password")] public bool HasPassword { get; set; } public List Partitions { get; set; } - [JsonProperty("primary_alias_type")] + [JsonPropertyName("primary_alias_type")] public int PrimaryAliasType { get; set; } - [JsonProperty("display_name")] + [JsonPropertyName("display_name")] public string DisplayName { get; set; } - [JsonProperty("normalized_display_login")] + [JsonPropertyName("normalized_display_login")] public string NormalizedDisplayLogin { get; set; } - [JsonProperty("x_token_issued_at")] + [JsonPropertyName("x_token_issued_at")] public int XTokenIssuedAt { get; set; } - [JsonProperty("display_login")] + [JsonPropertyName("display_login")] public string DisplayLogin { get; set; } - [JsonProperty("public_name")] + [JsonPropertyName("public_name")] public string PublicName { get; set; } - [JsonProperty("avatar_url")] + [JsonPropertyName("avatar_url")] public string AvatarUrl { get; set; } - [JsonProperty("native_default_email")] + [JsonPropertyName("native_default_email")] public string NativeDefaultEmail { get; set; } - [JsonProperty("has_plus")] + [JsonPropertyName("has_plus")] public bool HasPlus { get; set; } - [JsonProperty("location_id")] + [JsonPropertyName("location_id")] public int LocationId { get; set; } - [JsonProperty("gender")] + [JsonPropertyName("gender")] public string Gender { get; set; } - [JsonProperty("is_avatar_empty")] + [JsonPropertyName("is_avatar_empty")] public bool IsAvatarEmpty { get; set; } - [JsonProperty("machine_readable_login")] + [JsonPropertyName("machine_readable_login")] public string MachineReadableLogin { get; set; } - [JsonProperty("has_cards")] + [JsonPropertyName("has_cards")] public bool HasCards { get; set; } - [JsonProperty("has_family")] + [JsonPropertyName("has_family")] public bool HasFamily { get; set; } - [JsonProperty("picture_login_forbidden")] + [JsonPropertyName("picture_login_forbidden")] public bool PictureLoginForbidden { get; set; } - [JsonProperty("can_account_join_master")] + [JsonPropertyName("can_account_join_master")] public bool CanAccountJoinMaster { get; set; } - [JsonProperty("secure_phone_number")] + [JsonPropertyName("secure_phone_number")] public string SecurePhoneNumber { get; set; } - [JsonProperty("x_token_client_id")] + [JsonPropertyName("x_token_client_id")] public string XTokenClientId { get; set; } - [JsonProperty("x_token_need_reset")] + [JsonPropertyName("x_token_need_reset")] public bool XTokenNeedReset { get; set; } } } diff --git a/YandexMusic.API/Models/Album/YAlbum.cs b/YandexMusic.API/Models/Album/YAlbum.cs index 80055c3..0984822 100644 --- a/YandexMusic.API/Models/Album/YAlbum.cs +++ b/YandexMusic.API/Models/Album/YAlbum.cs @@ -1,98 +1,59 @@ +using System.Text.Json.Serialization; using YandexMusic.API.Models.Artist; using YandexMusic.API.Models.Common; using YandexMusic.API.Models.Common.Cover; using YandexMusic.API.Models.Track; -namespace YandexMusic.API.Models.Album +namespace YandexMusic.API.Models.Album; + +/// Модель альбома. +public class YAlbum : YBaseModel { - public sealed class YLabelConverter : JsonConverter - { - public override bool CanConvert(Type objectType) - { - throw new NotImplementedException(); - } - - public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) - { - if (reader.TokenType == JsonToken.Null) - return null; - - JArray jArray = JArray.Load(reader); - JTokenType tokenType = jArray.FirstOrDefault()?.Type ?? JTokenType.String; - object label; - - try - { - label = tokenType switch - { - JTokenType.Object => jArray.ToObject>(), - _ => jArray.ToObject>() - }; - } - catch (Exception ex) - { - throw new Exception($"Ошибка десериализации типа \"{objectType.Name}\".", ex); - } - - return label; - } - - public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) - { - JArray array = JArray.FromObject(value); - - array.WriteTo(writer); - } - } - - public class YAlbum : YBaseModel - { - public YButton ActionButton { get; set; } - public List Artists { get; set; } - public bool Available { get; set; } - public bool AvailableForMobile { get; set; } - public List AvailableForOptions { get; set; } - public bool AvailableForPremiumUsers { get; set; } - public bool AvailablePartially { get; set; } - public string BackgroundImageUrl { get; set; } - public string BackgroundVideoUrl { get; set; } - public List Bests { get; set; } - public List Buy { get; set; } - public bool ChildContent { get; set; } - public string ContentWarning { get; set; } - public string CoverUri { get; set; } - [JsonConverter(typeof(YCoverConverter))] - public YCover Cover { get; set; } - public YCustomWave CustomWave { get; set; } - public YDerivedColors DerivedColors { get; set; } - public string Description { get; set; } - public List Disclaimers { get; set; } - public List Duplicates { get; set; } - public bool HasTrailer { get; set; } - public string Genre { get; set; } - public string Id { get; set; } - [JsonConverter(typeof(YLabelConverter))] - public dynamic Labels { get; set; } - public int LikesCount { get; set; } - public bool ListeningFinished { get; set; } - public string MetaTagId { get; set; } - public YMetaType MetaType { get; set; } - public string OgImage { get; set; } - public YPager Pager { get; set; } - public List Prerolls { get; set; } - public bool Recent { get; set; } - public DateTime ReleaseDate { get; set; } - public string ShortDescription { get; set; } - public YSortOrder SortOrder { get; set; } - public string StorageDir { get; set; } - public string Title { get; set; } - public int TrackCount { get; set; } - public YTrackPosition TrackPosition { get; set; } - public YTrailer Trailer { get; set; } - public string Type { get; set; } - public string Version { get; set; } - public bool VeryImportant { get; set; } - public List> Volumes { get; set; } - public int Year { get; set; } - } + public YButton ActionButton { get; set; } + public List Artists { get; set; } + public bool Available { get; set; } + public bool AvailableForMobile { get; set; } + public List AvailableForOptions { get; set; } + public bool AvailableForPremiumUsers { get; set; } + public bool AvailablePartially { get; set; } + public string BackgroundImageUrl { get; set; } + public string BackgroundVideoUrl { get; set; } + public List Bests { get; set; } + public List Buy { get; set; } + public bool ChildContent { get; set; } + public string ContentWarning { get; set; } + public string CoverUri { get; set; } + [JsonConverter(typeof(YCoverConverter))] + public YCover Cover { get; set; } + public YCustomWave CustomWave { get; set; } + public YDerivedColors DerivedColors { get; set; } + public string Description { get; set; } + public List Disclaimers { get; set; } + public List Duplicates { get; set; } + public bool HasTrailer { get; set; } + public string Genre { get; set; } + public string Id { get; set; } + [JsonConverter(typeof(YLabelConverter))] + public dynamic Labels { get; set; } + public int LikesCount { get; set; } + public bool ListeningFinished { get; set; } + public string MetaTagId { get; set; } + public YMetaType MetaType { get; set; } + public string OgImage { get; set; } + public YPager Pager { get; set; } + public List Prerolls { get; set; } + public bool Recent { get; set; } + public DateTime ReleaseDate { get; set; } + public string ShortDescription { get; set; } + public YSortOrder SortOrder { get; set; } + public string StorageDir { get; set; } + public string Title { get; set; } + public int TrackCount { get; set; } + public YTrackPosition TrackPosition { get; set; } + public YTrailer Trailer { get; set; } + public string Type { get; set; } + public string Version { get; set; } + public bool VeryImportant { get; set; } + public List> Volumes { get; set; } + public int Year { get; set; } } \ No newline at end of file diff --git a/YandexMusic.API/Models/Album/YLabelConverter.cs b/YandexMusic.API/Models/Album/YLabelConverter.cs new file mode 100644 index 0000000..ff9faa9 --- /dev/null +++ b/YandexMusic.API/Models/Album/YLabelConverter.cs @@ -0,0 +1,32 @@ +using System.Text.Json; +using System.Text.Json.Serialization; +using YandexMusic.API.Models.Common; + +namespace YandexMusic.API.Models.Album; + +/// Конвертер для поля Labels, которое может быть списком строк или объектов. +public sealed class YLabelConverter : JsonConverter +{ + public override object Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + { + if (reader.TokenType != JsonTokenType.StartArray) + throw new JsonException("Ожидается массив"); + + var list = new List(); + while (reader.Read()) + { + if (reader.TokenType == JsonTokenType.EndArray) break; + if (reader.TokenType == JsonTokenType.String) + list.Add(reader.GetString()!); + else if (reader.TokenType == JsonTokenType.StartObject) + { + var label = JsonSerializer.Deserialize(ref reader, options); + list.Add(label!); + } + } + return list; + } + + public override void Write(Utf8JsonWriter writer, object value, JsonSerializerOptions options) + => JsonSerializer.Serialize(writer, value, options); +} diff --git a/YandexMusic.API/Models/Artist/YArtist.cs b/YandexMusic.API/Models/Artist/YArtist.cs index c4c36fa..783aa74 100644 --- a/YandexMusic.API/Models/Artist/YArtist.cs +++ b/YandexMusic.API/Models/Artist/YArtist.cs @@ -1,41 +1,41 @@ +using System.Text.Json.Serialization; using YandexMusic.API.Models.Common; using YandexMusic.API.Models.Common.Cover; -namespace YandexMusic.API.Models.Artist +namespace YandexMusic.API.Models.Artist; + +public class YArtist : YBaseModel { - public class YArtist : YBaseModel - { - public YButton ActionButton { get; set; } - public bool Available { get; set; } - public bool Composer { get; set; } - public List Countries { get; set; } - public YArtistCounts Counts { get; set; } - [JsonConverter(typeof(YCoverConverter))] - public YCover Cover { get; set; } - public List DbAliases { get; set; } + public YButton ActionButton { get; set; } + public bool Available { get; set; } + public bool Composer { get; set; } + public List Countries { get; set; } + public YArtistCounts Counts { get; set; } + [JsonConverter(typeof(YCoverConverter))] + public YCover Cover { get; set; } + public List DbAliases { get; set; } #warning Непонятная коллекция с содержимым разных типов - public List Decomposed { get; set; } - public YDerivedColors DerivedColors { get; set; } - public YDescription Description { get; set; } - public YDeprecation Deprecation { get; set; } - public List Disclaimers { get; set; } - public string EndDate { get; set; } - public string EnWikipediaLink { get; set; } - public List ExtraActions { get; set; } - public List Genres { get; set; } - public string Id { get; set; } - public string InitDate { get; set; } - public int LikesCount { get; set; } - public List Links { get; set; } - public string Name { get; set; } - public bool NoPicturesFromSearch { get; set; } - public string OgImage { get; set; } - public YArtistRatings Ratings { get; set; } - public bool TicketsAvailable { get; set; } - public DateTime Timestamp { get; set; } - public bool Various { get; set; } - public string YaMoneyId { get; set; } - public bool HasTrailer { get; set; } - public YTrailer Trailer { get; set; } - } + public List Decomposed { get; set; } + public YDerivedColors DerivedColors { get; set; } + public YDescription Description { get; set; } + public YDeprecation Deprecation { get; set; } + public List Disclaimers { get; set; } + public string EndDate { get; set; } + public string EnWikipediaLink { get; set; } + public List ExtraActions { get; set; } + public List Genres { get; set; } + public string Id { get; set; } + public string InitDate { get; set; } + public int LikesCount { get; set; } + public List Links { get; set; } + public string Name { get; set; } + public bool NoPicturesFromSearch { get; set; } + public string OgImage { get; set; } + public YArtistRatings Ratings { get; set; } + public bool TicketsAvailable { get; set; } + public DateTime Timestamp { get; set; } + public bool Various { get; set; } + public string YaMoneyId { get; set; } + public bool HasTrailer { get; set; } + public YTrailer Trailer { get; set; } } diff --git a/YandexMusic.API/Models/Artist/YArtistBriefInfo.cs b/YandexMusic.API/Models/Artist/YArtistBriefInfo.cs index 085d684..376baf1 100644 --- a/YandexMusic.API/Models/Artist/YArtistBriefInfo.cs +++ b/YandexMusic.API/Models/Artist/YArtistBriefInfo.cs @@ -1,36 +1,36 @@ +using System.Text.Json.Serialization; using YandexMusic.API.Models.Album; using YandexMusic.API.Models.Common; using YandexMusic.API.Models.Common.Cover; using YandexMusic.API.Models.Playlist; using YandexMusic.API.Models.Track; -namespace YandexMusic.API.Models.Artist +namespace YandexMusic.API.Models.Artist; + +public class YArtistBriefInfo { - public class YArtistBriefInfo - { - public YButton ActionButton { get; set; } - public List Albums { get; set; } - [JsonProperty(ItemConverterType = typeof(YCoverConverter))] - public List AllCovers { get; set; } - public List AlsoAlbums { get; set; } - public YArtist Artist { get; set; } - public string BackgroundVideoUrl { get; set; } - public YBandlinkScannerLink BandlinkScannerLink { get; set; } - public List Clips { get; set; } - public List Concerts { get; set; } - public YCustomWave CustomWave { get; set; } - public List ExtraActions { get; set; } - public bool HasPromotions { get; set; } - public bool HasTrailer { get; set; } - public List LastReleaseIds { get; set; } - public List LastReleases { get; set; } - public List PlaylistIds { get; set; } - public List Playlists { get; set; } - public List PopularTracks { get; set; } - public List SimilarArtists { get; set; } - public YStats Stats { get; set; } - public List Videos { get; set; } - public List Vinyls { get; set; } - public List Links { get; set; } - } + public YButton ActionButton { get; set; } + public List Albums { get; set; } + [JsonConverter(typeof(YCoverConverter))] + public List AllCovers { get; set; } + public List AlsoAlbums { get; set; } + public YArtist Artist { get; set; } + public string BackgroundVideoUrl { get; set; } + public YBandlinkScannerLink BandlinkScannerLink { get; set; } + public List Clips { get; set; } + public List Concerts { get; set; } + public YCustomWave CustomWave { get; set; } + public List ExtraActions { get; set; } + public bool HasPromotions { get; set; } + public bool HasTrailer { get; set; } + public List LastReleaseIds { get; set; } + public List LastReleases { get; set; } + public List PlaylistIds { get; set; } + public List Playlists { get; set; } + public List PopularTracks { get; set; } + public List SimilarArtists { get; set; } + public YStats Stats { get; set; } + public List Videos { get; set; } + public List Vinyls { get; set; } + public List Links { get; set; } } \ No newline at end of file diff --git a/YandexMusic.API/Models/Artist/YArtistCounts.cs b/YandexMusic.API/Models/Artist/YArtistCounts.cs index 2b24ed0..197a057 100644 --- a/YandexMusic.API/Models/Artist/YArtistCounts.cs +++ b/YandexMusic.API/Models/Artist/YArtistCounts.cs @@ -1,10 +1,9 @@ -namespace YandexMusic.API.Models.Artist +namespace YandexMusic.API.Models.Artist; + +public class YArtistCounts { - public class YArtistCounts - { - public int AlsoAlbums { get; set; } - public int AlsoTracks { get; set; } - public int DirectAlbums { get; set; } - public int Tracks { get; set; } - } + public int AlsoAlbums { get; set; } + public int AlsoTracks { get; set; } + public int DirectAlbums { get; set; } + public int Tracks { get; set; } } \ No newline at end of file diff --git a/YandexMusic.API/Models/Artist/YArtistRatings.cs b/YandexMusic.API/Models/Artist/YArtistRatings.cs index 4312010..f93e2d8 100644 --- a/YandexMusic.API/Models/Artist/YArtistRatings.cs +++ b/YandexMusic.API/Models/Artist/YArtistRatings.cs @@ -1,9 +1,8 @@ -namespace YandexMusic.API.Models.Artist +namespace YandexMusic.API.Models.Artist; + +public class YArtistRatings { - public class YArtistRatings - { - public int Day { get; set; } - public int Month { get; set; } - public int Week { get; set; } - } + public int Day { get; set; } + public int Month { get; set; } + public int Week { get; set; } } \ No newline at end of file diff --git a/YandexMusic.API/Models/Artist/YBandlinkScannerLink.cs b/YandexMusic.API/Models/Artist/YBandlinkScannerLink.cs index e05c405..862ae1c 100644 --- a/YandexMusic.API/Models/Artist/YBandlinkScannerLink.cs +++ b/YandexMusic.API/Models/Artist/YBandlinkScannerLink.cs @@ -1,10 +1,9 @@ -namespace YandexMusic.API.Models.Artist +namespace YandexMusic.API.Models.Artist; + +public class YBandlinkScannerLink { - public class YBandlinkScannerLink - { - public string Title { get; set; } - public string Subtitle { get; set; } - public string Url { get; set; } - public string ImgUrl { get; set; } - } + public string Title { get; set; } + public string Subtitle { get; set; } + public string Url { get; set; } + public string ImgUrl { get; set; } } \ No newline at end of file diff --git a/YandexMusic.API/Models/Artist/YConcert.cs b/YandexMusic.API/Models/Artist/YConcert.cs index a867253..99c73f0 100644 --- a/YandexMusic.API/Models/Artist/YConcert.cs +++ b/YandexMusic.API/Models/Artist/YConcert.cs @@ -1,29 +1,29 @@ +using System.Text.Json.Serialization; using YandexMusic.API.Models.Common; -namespace YandexMusic.API.Models.Artist +namespace YandexMusic.API.Models.Artist; + +public class YConcert { - public class YConcert - { - public string Address { get; set; } - public string AfishaUrl { get; set; } - public YArtist Artist { get; set; } - public string City { get; set; } - public string ConcertTitle { get; set; } - public string ContentRating { get; set; } - public List Coordinates { get; set; } - public YCashback Cashback { get; set; } - [JsonProperty("data-session-id")] - public string DataSessionId { get; set; } - public DateTime DateTime { get; set; } - public string Hash { get; set; } - public string Id { get; set; } - public List Images { get; set; } - public string ImageUrl { get; set; } - public string Map { get; set; } - public string MapUrl { get; set; } - [JsonProperty("metro-stations")] - public List MetroStations { get; set; } - public string Place { get; set; } - public YPrice MinPrice { get; set; } - } + public string Address { get; set; } + public string AfishaUrl { get; set; } + public YArtist Artist { get; set; } + public string City { get; set; } + public string ConcertTitle { get; set; } + public string ContentRating { get; set; } + public List Coordinates { get; set; } + public YCashback Cashback { get; set; } + [JsonPropertyName("data-session-id")] + public string DataSessionId { get; set; } + public DateTime DateTime { get; set; } + public string Hash { get; set; } + public string Id { get; set; } + public List Images { get; set; } + public string ImageUrl { get; set; } + public string Map { get; set; } + public string MapUrl { get; set; } + [JsonPropertyName("metro-stations")] + public List MetroStations { get; set; } + public string Place { get; set; } + public YPrice MinPrice { get; set; } } \ No newline at end of file diff --git a/YandexMusic.API/Models/Artist/YDeprecation.cs b/YandexMusic.API/Models/Artist/YDeprecation.cs index 3d2522b..736ab80 100644 --- a/YandexMusic.API/Models/Artist/YDeprecation.cs +++ b/YandexMusic.API/Models/Artist/YDeprecation.cs @@ -1,7 +1,6 @@ -namespace YandexMusic.API.Models.Artist +namespace YandexMusic.API.Models.Artist; + +public class YDeprecation { - public class YDeprecation - { - public string TargetArtistId { get; set; } - } + public string TargetArtistId { get; set; } } \ No newline at end of file diff --git a/YandexMusic.API/Models/Artist/YMetroStation.cs b/YandexMusic.API/Models/Artist/YMetroStation.cs index bba4d40..eb04f05 100644 --- a/YandexMusic.API/Models/Artist/YMetroStation.cs +++ b/YandexMusic.API/Models/Artist/YMetroStation.cs @@ -1,9 +1,10 @@ -namespace YandexMusic.API.Models.Artist +using System.Text.Json.Serialization; + +namespace YandexMusic.API.Models.Artist; + +public class YMetroStation { - public class YMetroStation - { - [JsonProperty("line-color")] - public string LineColor { get; set; } - public string Title { get; set; } - } + [JsonPropertyName("line-color")] + public string LineColor { get; set; } + public string Title { get; set; } } \ No newline at end of file diff --git a/YandexMusic.API/Models/Artist/YTracksPage.cs b/YandexMusic.API/Models/Artist/YTracksPage.cs index e4885fb..9380176 100644 --- a/YandexMusic.API/Models/Artist/YTracksPage.cs +++ b/YandexMusic.API/Models/Artist/YTracksPage.cs @@ -1,12 +1,11 @@ using YandexMusic.API.Models.Common; using YandexMusic.API.Models.Track; -namespace YandexMusic.API.Models.Artist -{ - public class YTracksPage - { - public YPager Pager { get; set; } +namespace YandexMusic.API.Models.Artist; - public List Tracks { get; set; } - } +public class YTracksPage +{ + public YPager Pager { get; set; } + + public List Tracks { get; set; } } \ No newline at end of file diff --git a/YandexMusic.API/Models/Common/Cover/YCover.cs b/YandexMusic.API/Models/Common/Cover/YCover.cs index 5b6e855..be93992 100644 --- a/YandexMusic.API/Models/Common/Cover/YCover.cs +++ b/YandexMusic.API/Models/Common/Cover/YCover.cs @@ -1,71 +1,35 @@ -namespace YandexMusic.API.Models.Common.Cover +using System.Text.Json; +using System.Text.Json.Serialization; + +namespace YandexMusic.API.Models.Common.Cover; + +public class YCoverConverter : JsonConverter { - public sealed class YCoverConverter : JsonConverter + public override YCover? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { - public override bool CanConvert(Type objectType) + if (reader.TokenType != JsonTokenType.StartObject) return null; + using var doc = JsonDocument.ParseValue(ref reader); + var root = doc.RootElement; + var type = root.TryGetProperty("type", out var t) ? t.GetString() : null; + if (root.TryGetProperty("error", out _)) type = "error"; + + return type switch { - return typeof(YCover).IsAssignableFrom(objectType); - } - - public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) - { - if (reader.TokenType == JsonToken.Null) - return null; - - JObject jObject = JObject.Load(reader); - YCover cover; - - try - { - // Фиктивный тип, т.к. у такой обложки нет поля с типом - if (jObject["type"] == null) - jObject.Add("type", "color"); - - YCoverType type = jObject["error"] != null - ? YCoverType.Error - : jObject["type"].ToObject(); - - switch (type) - { - case YCoverType.Error: - cover = jObject.ToObject(); - break; - case YCoverType.Color: - cover = jObject.ToObject(); - break; - case YCoverType.FromAlbumCover: - case YCoverType.FromArtistPhotos: - cover = jObject.ToObject(); - break; - case YCoverType.Pic: - cover = jObject.ToObject(); - break; - case YCoverType.Mosaic: - cover = jObject.ToObject(); - break; - default: - cover = jObject.ToObject(); - break; - } - } - catch (Exception ex) - { - throw new Exception($"Ошибка десериализации типа \"{objectType.Name}\".", ex); - } - - return cover; - } - - public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) - { - JObject cover = JObject.FromObject(value, serializer); - - cover.WriteTo(writer); - } + "color" => JsonSerializer.Deserialize(root.GetRawText(), options), + "error" => JsonSerializer.Deserialize(root.GetRawText(), options), + "from-artist-photos" or "from-album-cover" => JsonSerializer.Deserialize(root.GetRawText(), options), + "pic" => JsonSerializer.Deserialize(root.GetRawText(), options), + "mosaic" => JsonSerializer.Deserialize(root.GetRawText(), options), + _ => JsonSerializer.Deserialize(root.GetRawText(), options) + }; } - public class YCover - { - public YCoverType Type { get; set; } - } + public override void Write(Utf8JsonWriter writer, YCover value, JsonSerializerOptions options) + => JsonSerializer.Serialize(writer, value, options); +} + +[JsonConverter(typeof(YCoverConverter))] +public class YCover +{ + public YCoverType Type { get; set; } } \ No newline at end of file diff --git a/YandexMusic.API/Models/Common/Cover/YCoverColor.cs b/YandexMusic.API/Models/Common/Cover/YCoverColor.cs index de8af5f..59d5e3f 100644 --- a/YandexMusic.API/Models/Common/Cover/YCoverColor.cs +++ b/YandexMusic.API/Models/Common/Cover/YCoverColor.cs @@ -1,8 +1,7 @@ -namespace YandexMusic.API.Models.Common.Cover +namespace YandexMusic.API.Models.Common.Cover; + +public class YCoverColor : YCover { - public class YCoverColor : YCover - { - public string Uri { get; set; } - public string Color { get; set; } - } + public string Uri { get; set; } + public string Color { get; set; } } \ No newline at end of file diff --git a/YandexMusic.API/Models/Common/Cover/YCoverError.cs b/YandexMusic.API/Models/Common/Cover/YCoverError.cs index 1475748..16bfe77 100644 --- a/YandexMusic.API/Models/Common/Cover/YCoverError.cs +++ b/YandexMusic.API/Models/Common/Cover/YCoverError.cs @@ -1,7 +1,6 @@ -namespace YandexMusic.API.Models.Common.Cover +namespace YandexMusic.API.Models.Common.Cover; + +public class YCoverError : YCover { - public class YCoverError : YCover - { - public string Error { get; set; } - } + public string Error { get; set; } } \ No newline at end of file diff --git a/YandexMusic.API/Models/Common/Cover/YCoverImage.cs b/YandexMusic.API/Models/Common/Cover/YCoverImage.cs index 613d270..7d34c7d 100644 --- a/YandexMusic.API/Models/Common/Cover/YCoverImage.cs +++ b/YandexMusic.API/Models/Common/Cover/YCoverImage.cs @@ -1,8 +1,7 @@ -namespace YandexMusic.API.Models.Common.Cover +namespace YandexMusic.API.Models.Common.Cover; + +public class YCoverImage : YCover { - public class YCoverImage : YCover - { - public string Prefix { get; set; } - public string Uri { get; set; } - } + public string Prefix { get; set; } + public string Uri { get; set; } } \ No newline at end of file diff --git a/YandexMusic.API/Models/Common/Cover/YCoverMosaic.cs b/YandexMusic.API/Models/Common/Cover/YCoverMosaic.cs index 91d00b5..4c17c06 100644 --- a/YandexMusic.API/Models/Common/Cover/YCoverMosaic.cs +++ b/YandexMusic.API/Models/Common/Cover/YCoverMosaic.cs @@ -1,8 +1,7 @@ -namespace YandexMusic.API.Models.Common.Cover +namespace YandexMusic.API.Models.Common.Cover; + +public class YCoverMosaic : YCover { - public class YCoverMosaic : YCover - { - public bool Custom { get; set; } - public List ItemsUri { get; set; } - } + public bool Custom { get; set; } + public List ItemsUri { get; set; } } \ No newline at end of file diff --git a/YandexMusic.API/Models/Common/Cover/YCoverPic.cs b/YandexMusic.API/Models/Common/Cover/YCoverPic.cs index 42c606d..c91b86b 100644 --- a/YandexMusic.API/Models/Common/Cover/YCoverPic.cs +++ b/YandexMusic.API/Models/Common/Cover/YCoverPic.cs @@ -1,11 +1,10 @@ -namespace YandexMusic.API.Models.Common.Cover +namespace YandexMusic.API.Models.Common.Cover; + +public class YCoverPic : YCover { - public class YCoverPic : YCover - { - public bool Custom { get; set; } - public string Dir { get; set; } - public bool IsCustom { get; set; } - public string Uri { get; set; } - public string Version { get; set; } - } + public bool Custom { get; set; } + public string Dir { get; set; } + public bool IsCustom { get; set; } + public string Uri { get; set; } + public string Version { get; set; } } \ No newline at end of file diff --git a/YandexMusic.API/Models/Common/Cover/YCoverType.cs b/YandexMusic.API/Models/Common/Cover/YCoverType.cs index ac5ec0c..cc9273c 100644 --- a/YandexMusic.API/Models/Common/Cover/YCoverType.cs +++ b/YandexMusic.API/Models/Common/Cover/YCoverType.cs @@ -1,17 +1,17 @@ using System.Runtime.Serialization; +using System.Text.Json.Serialization; -namespace YandexMusic.API.Models.Common.Cover +namespace YandexMusic.API.Models.Common.Cover; + +[JsonConverter(typeof(JsonStringEnumConverter))] +public enum YCoverType { - [JsonConverter(typeof(StringEnumConverter))] - public enum YCoverType - { - Color, - Error, - [EnumMember(Value = "from-artist-photos")] - FromArtistPhotos, - [EnumMember(Value = "from-album-cover")] - FromAlbumCover, - Mosaic, - Pic - } + Color, + Error, + [EnumMember(Value = "from-artist-photos")] + FromArtistPhotos, + [EnumMember(Value = "from-album-cover")] + FromAlbumCover, + Mosaic, + Pic, } \ No newline at end of file diff --git a/YandexMusic.API/Models/Common/YBaseModel.cs b/YandexMusic.API/Models/Common/YBaseModel.cs index 9548767..0e236ee 100644 --- a/YandexMusic.API/Models/Common/YBaseModel.cs +++ b/YandexMusic.API/Models/Common/YBaseModel.cs @@ -1,8 +1,9 @@ -namespace YandexMusic.API.Models.Common +using System.Text.Json.Serialization; + +namespace YandexMusic.API.Models.Common; + +public class YBaseModel { - public class YBaseModel - { - [JsonIgnore] - public YExecutionContext Context { get; set; } - } + [JsonIgnore] + public YExecutionContext Context { get; set; } } diff --git a/YandexMusic.API/Models/Common/YButton.cs b/YandexMusic.API/Models/Common/YButton.cs index 5f43da2..95a1dca 100644 --- a/YandexMusic.API/Models/Common/YButton.cs +++ b/YandexMusic.API/Models/Common/YButton.cs @@ -1,12 +1,10 @@ -namespace YandexMusic.API.Models.Common +namespace YandexMusic.API.Models.Common; + +public class YButton : YStyle { - public class YButton : YStyle - { - public string Text { get; set; } - public string Url { get; set; } -#warning Дублирование? - public string Uri { get; set; } - public string Color { get; set; } - public bool ViewBrowser { get; set; } - } + public string Text { get; set; } + public string Url { get; set; } + public string Uri { get; set; } + public string Color { get; set; } + public bool ViewBrowser { get; set; } } diff --git a/YandexMusic.API/Models/Common/YCashback.cs b/YandexMusic.API/Models/Common/YCashback.cs index dda2e79..36103f1 100644 --- a/YandexMusic.API/Models/Common/YCashback.cs +++ b/YandexMusic.API/Models/Common/YCashback.cs @@ -1,7 +1,6 @@ -namespace YandexMusic.API.Models.Common +namespace YandexMusic.API.Models.Common; + +public class YCashback { - public class YCashback - { - public string Title { get; set; } - } + public string Title { get; set; } } \ No newline at end of file diff --git a/YandexMusic.API/Models/Common/YChart.cs b/YandexMusic.API/Models/Common/YChart.cs index b5515be..371faa7 100644 --- a/YandexMusic.API/Models/Common/YChart.cs +++ b/YandexMusic.API/Models/Common/YChart.cs @@ -1,12 +1,11 @@ using YandexMusic.API.Models.Landing.Entity.Entities; -namespace YandexMusic.API.Models.Common +namespace YandexMusic.API.Models.Common; + +public class YChart { - public class YChart - { - public int Position { get; set; } - public int Listeners { get; set; } - public int Shift { get; set; } - public YChartProgress Progress { get; set; } - } + public int Position { get; set; } + public int Listeners { get; set; } + public int Shift { get; set; } + public YChartProgress Progress { get; set; } } \ No newline at end of file diff --git a/YandexMusic.API/Models/Common/YClip.cs b/YandexMusic.API/Models/Common/YClip.cs index 8096b11..a6b436b 100644 --- a/YandexMusic.API/Models/Common/YClip.cs +++ b/YandexMusic.API/Models/Common/YClip.cs @@ -1,19 +1,18 @@ using YandexMusic.API.Models.Artist; -namespace YandexMusic.API.Models.Common +namespace YandexMusic.API.Models.Common; + +public class YClip { - public class YClip - { - public List Artists { get; set; } - public string ClipId { get; set; } - public List Disclaimers { get; set; } - public int Duration { get; set; } - public bool Explicit { get; set; } - public string PlayerId { get; set; } - public string PreviewUrl { get; set; } - public string Uuid { get; set; } - public string Thumbnail { get; set; } - public string Title { get; set; } - public List TrackIds { get; set; } - } + public List Artists { get; set; } + public string ClipId { get; set; } + public List Disclaimers { get; set; } + public int Duration { get; set; } + public bool Explicit { get; set; } + public string PlayerId { get; set; } + public string PreviewUrl { get; set; } + public string Uuid { get; set; } + public string Thumbnail { get; set; } + public string Title { get; set; } + public List TrackIds { get; set; } } \ No newline at end of file diff --git a/YandexMusic.API/Models/Common/YCloseButtonStyles.cs b/YandexMusic.API/Models/Common/YCloseButtonStyles.cs index 6e7692c..6ee47c0 100644 --- a/YandexMusic.API/Models/Common/YCloseButtonStyles.cs +++ b/YandexMusic.API/Models/Common/YCloseButtonStyles.cs @@ -1,8 +1,7 @@ -namespace YandexMusic.API.Models.Common +namespace YandexMusic.API.Models.Common; + +public class YCloseButtonStyles { - public class YCloseButtonStyles - { - public YStyle White { get; set; } - public YStyle Black { get; set; } - } + public YStyle White { get; set; } + public YStyle Black { get; set; } } \ No newline at end of file diff --git a/YandexMusic.API/Models/Common/YCountsTracks.cs b/YandexMusic.API/Models/Common/YCountsTracks.cs index 7ef3e34..a0165f0 100644 --- a/YandexMusic.API/Models/Common/YCountsTracks.cs +++ b/YandexMusic.API/Models/Common/YCountsTracks.cs @@ -1,9 +1,8 @@ -namespace YandexMusic.API.Models.Common +namespace YandexMusic.API.Models.Common; + +public class YCountsTracks { - public class YCountsTracks - { - public int All { get; set; } - public int Favorite { get; set; } - public int Ugc { get; set; } - } + public int All { get; set; } + public int Favorite { get; set; } + public int Ugc { get; set; } } \ No newline at end of file diff --git a/YandexMusic.API/Models/Common/YCustomWave.cs b/YandexMusic.API/Models/Common/YCustomWave.cs index db10f30..6b2eeab 100644 --- a/YandexMusic.API/Models/Common/YCustomWave.cs +++ b/YandexMusic.API/Models/Common/YCustomWave.cs @@ -1,11 +1,10 @@ -namespace YandexMusic.API.Models.Common +namespace YandexMusic.API.Models.Common; + +public class YCustomWave { - public class YCustomWave - { - public string AnimationUrl { get; set; } - public string BackgroundImageUrl { get; set; } - public string Header { get; set; } - public string Position { get; set; } - public string Title { get; set; } - } + public string AnimationUrl { get; set; } + public string BackgroundImageUrl { get; set; } + public string Header { get; set; } + public string Position { get; set; } + public string Title { get; set; } } \ No newline at end of file diff --git a/YandexMusic.API/Models/Common/YDerivedColors.cs b/YandexMusic.API/Models/Common/YDerivedColors.cs index 6b3295f..1b8f15a 100644 --- a/YandexMusic.API/Models/Common/YDerivedColors.cs +++ b/YandexMusic.API/Models/Common/YDerivedColors.cs @@ -1,10 +1,9 @@ -namespace YandexMusic.API.Models.Common +namespace YandexMusic.API.Models.Common; + +public class YDerivedColors { - public class YDerivedColors - { - public string Average { get; set; } - public string WaveText { get; set; } - public string MiniPlayer { get; set; } - public string Accent { get; set; } - } + public string Average { get; set; } + public string WaveText { get; set; } + public string MiniPlayer { get; set; } + public string Accent { get; set; } } \ No newline at end of file diff --git a/YandexMusic.API/Models/Common/YDescription.cs b/YandexMusic.API/Models/Common/YDescription.cs index 736f6ce..07b90ae 100644 --- a/YandexMusic.API/Models/Common/YDescription.cs +++ b/YandexMusic.API/Models/Common/YDescription.cs @@ -1,8 +1,7 @@ -namespace YandexMusic.API.Models.Common +namespace YandexMusic.API.Models.Common; + +public class YDescription { - public class YDescription - { - public string Text { get; set; } - public string Uri { get; set; } - } + public string Text { get; set; } + public string Uri { get; set; } } \ No newline at end of file diff --git a/YandexMusic.API/Models/Common/YError.cs b/YandexMusic.API/Models/Common/YError.cs index 0421110..4fe05c2 100644 --- a/YandexMusic.API/Models/Common/YError.cs +++ b/YandexMusic.API/Models/Common/YError.cs @@ -1,8 +1,7 @@ -namespace YandexMusic.API.Models.Common +namespace YandexMusic.API.Models.Common; + +public class YError { - public class YError - { - public string Name { get; set; } - public string Message { get; set; } - } + public string Name { get; set; } + public string Message { get; set; } } \ No newline at end of file diff --git a/YandexMusic.API/Models/Common/YErrorResponse.cs b/YandexMusic.API/Models/Common/YErrorResponse.cs index ea40cbb..b93b52f 100644 --- a/YandexMusic.API/Models/Common/YErrorResponse.cs +++ b/YandexMusic.API/Models/Common/YErrorResponse.cs @@ -1,8 +1,7 @@ -namespace YandexMusic.API.Models.Common +namespace YandexMusic.API.Models.Common; + +public class YErrorResponse : Exception { - public class YErrorResponse : Exception - { - public YInvocationInfo InvocationInfo { get; set; } - public YError Error { get; set; } - } + public YInvocationInfo InvocationInfo { get; set; } + public YError Error { get; set; } } \ No newline at end of file diff --git a/YandexMusic.API/Models/Common/YExecutionContext.cs b/YandexMusic.API/Models/Common/YExecutionContext.cs index 9305479..ef76ed6 100644 --- a/YandexMusic.API/Models/Common/YExecutionContext.cs +++ b/YandexMusic.API/Models/Common/YExecutionContext.cs @@ -1,57 +1,12 @@ using YandexMusic.API.Common; -namespace YandexMusic.API.Models.Common +namespace YandexMusic.API.Models.Common; + +/// Контекст выполнения, содержащий ссылки на API и хранилище. +public class YExecutionContext { - public sealed class YExecutionContextConverter : JsonConverter - { - #region Поля - - private YandexMusicApi api; - private AuthStorage storage; - - #endregion Поля - - public override bool CanConvert(Type objectType) - { - return typeof(YBaseModel).IsAssignableFrom(objectType); - } - - public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) - { - try - { - YBaseModel obj = (YBaseModel)Activator.CreateInstance(objectType); - serializer.Populate(reader, obj); - - obj.Context = new YExecutionContext - { - API = api, - Storage = storage - }; - - return obj; - } - catch (Exception ex) - { - throw new Exception($"Ошибка десериализации типа \"{objectType.Name}\".", ex); - } - } - - public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) - { - throw new NotImplementedException(); - } - - public YExecutionContextConverter(YandexMusicApi yandex, AuthStorage auth) - { - api = yandex; - storage = auth; - } - } - - public class YExecutionContext - { - public YandexMusicApi API { get; internal set; } - public AuthStorage Storage { get; internal set; } - } -} + /// Экземпляр основного API. + public YandexMusicApi API { get; internal set; } = null!; + /// Хранилище данных авторизации. + public AuthStorage Storage { get; internal set; } = null!; +} \ No newline at end of file diff --git a/YandexMusic.API/Models/Common/YExecutionContextConverter.cs b/YandexMusic.API/Models/Common/YExecutionContextConverter.cs new file mode 100644 index 0000000..115978c --- /dev/null +++ b/YandexMusic.API/Models/Common/YExecutionContextConverter.cs @@ -0,0 +1,41 @@ +using System.Text.Json; +using System.Text.Json.Serialization; +using YandexMusic.API.Common; + +namespace YandexMusic.API.Models.Common; + +/// Конвертер для внедрения контекста выполнения (API и хранилище) в модели. +public class YExecutionContextConverter : JsonConverter +{ + private readonly YandexMusicApi _api; + private readonly AuthStorage _storage; + + public YExecutionContextConverter(YandexMusicApi api, AuthStorage storage) + { + _api = api; + _storage = storage; + } + + public override YBaseModel? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + { + // Десериализуем объект без контекста + var obj = (YBaseModel?)JsonSerializer.Deserialize(ref reader, typeToConvert, options); + if (obj != null) + { + obj.Context = new YExecutionContext + { + API = _api, + Storage = _storage + }; + } + return obj; + } + + public override void Write(Utf8JsonWriter writer, YBaseModel value, JsonSerializerOptions options) + { + // При сериализации игнорируем контекст + var cloneOptions = new JsonSerializerOptions(options); + cloneOptions.Converters.Remove(this); + JsonSerializer.Serialize(writer, value, cloneOptions); + } +} diff --git a/YandexMusic.API/Models/Common/YExtraAction.cs b/YandexMusic.API/Models/Common/YExtraAction.cs index e4467a1..3b8610a 100644 --- a/YandexMusic.API/Models/Common/YExtraAction.cs +++ b/YandexMusic.API/Models/Common/YExtraAction.cs @@ -1,11 +1,10 @@ -namespace YandexMusic.API.Models.Common +namespace YandexMusic.API.Models.Common; + +public class YExtraAction { - public class YExtraAction - { - public string Type { get; set; } - public string Title { get; set; } - public string Color { get; set; } - public string Url { get; set; } - public bool ViewBrowser { get; set; } - } + public string Type { get; set; } + public string Title { get; set; } + public string Color { get; set; } + public string Url { get; set; } + public bool ViewBrowser { get; set; } } \ No newline at end of file diff --git a/YandexMusic.API/Models/Common/YId.cs b/YandexMusic.API/Models/Common/YId.cs index 33030b3..c671121 100644 --- a/YandexMusic.API/Models/Common/YId.cs +++ b/YandexMusic.API/Models/Common/YId.cs @@ -1,7 +1,6 @@ -namespace YandexMusic.API.Models.Common +namespace YandexMusic.API.Models.Common; + +public class YId { - public class YId - { - public string Id { get; set; } - } + public string Id { get; set; } } diff --git a/YandexMusic.API/Models/Common/YInvocationInfo.cs b/YandexMusic.API/Models/Common/YInvocationInfo.cs index 4318bfe..c919676 100644 --- a/YandexMusic.API/Models/Common/YInvocationInfo.cs +++ b/YandexMusic.API/Models/Common/YInvocationInfo.cs @@ -1,13 +1,14 @@ -namespace YandexMusic.API.Models.Common +using System.Text.Json.Serialization; + +namespace YandexMusic.API.Models.Common; + +public class YInvocationInfo { - public class YInvocationInfo - { - [JsonProperty("app-name")] - public string AppName { get; set; } - [JsonProperty("exec-duration-millis")] - public int ExecDurationMillis { get; set; } - public string HostName { get; set; } - [JsonProperty("req-id")] - public string ReqId { get; set; } - } + [JsonPropertyName("app-name")] + public string AppName { get; set; } + [JsonPropertyName("exec-duration-millis")] + public int ExecDurationMillis { get; set; } + public string HostName { get; set; } + [JsonPropertyName("req-id")] + public string ReqId { get; set; } } \ No newline at end of file diff --git a/YandexMusic.API/Models/Common/YLabel.cs b/YandexMusic.API/Models/Common/YLabel.cs index faa3d2b..e2ef825 100644 --- a/YandexMusic.API/Models/Common/YLabel.cs +++ b/YandexMusic.API/Models/Common/YLabel.cs @@ -1,8 +1,7 @@ -namespace YandexMusic.API.Models.Common +namespace YandexMusic.API.Models.Common; + +public class YLabel { - public class YLabel - { - public string Id { get; set; } - public string Name { get; set; } - } + public string Id { get; set; } + public string Name { get; set; } } \ No newline at end of file diff --git a/YandexMusic.API/Models/Common/YLikedCounts.cs b/YandexMusic.API/Models/Common/YLikedCounts.cs index 91c564e..2768511 100644 --- a/YandexMusic.API/Models/Common/YLikedCounts.cs +++ b/YandexMusic.API/Models/Common/YLikedCounts.cs @@ -1,8 +1,7 @@ -namespace YandexMusic.API.Models.Common +namespace YandexMusic.API.Models.Common; + +public class YLikedCounts { - public class YLikedCounts - { - public long LikedAlbums { get; set; } - public long LikedArtists { get; set; } - } + public long LikedAlbums { get; set; } + public long LikedArtists { get; set; } } \ No newline at end of file diff --git a/YandexMusic.API/Models/Common/YLink.cs b/YandexMusic.API/Models/Common/YLink.cs index 22b5434..5ce63ac 100644 --- a/YandexMusic.API/Models/Common/YLink.cs +++ b/YandexMusic.API/Models/Common/YLink.cs @@ -1,13 +1,12 @@ -namespace YandexMusic.API.Models.Common +namespace YandexMusic.API.Models.Common; + +public class YLink { - public class YLink - { - public string Href { get; set; } - public string Url { get; set; } - public string ImgUrl { get; set; } - public string SocialNetwork { get; set; } - public string Subtitle { get; set; } - public string Title { get; set; } - public YLinkType Type { get; set; } - } + public string Href { get; set; } + public string Url { get; set; } + public string ImgUrl { get; set; } + public string SocialNetwork { get; set; } + public string Subtitle { get; set; } + public string Title { get; set; } + public YLinkType Type { get; set; } } \ No newline at end of file diff --git a/YandexMusic.API/Models/Common/YLinkType.cs b/YandexMusic.API/Models/Common/YLinkType.cs index b1fa892..80f11c8 100644 --- a/YandexMusic.API/Models/Common/YLinkType.cs +++ b/YandexMusic.API/Models/Common/YLinkType.cs @@ -1,25 +1,24 @@ -namespace YandexMusic.API.Models.Common +namespace YandexMusic.API.Models.Common; + +public enum YLinkType { - public enum YLinkType - { - /// - /// Официальный сайт - /// - Official, + /// + /// Официальный сайт + /// + Official, - /// - /// Социальная сеть - /// - Social, + /// + /// Социальная сеть + /// + Social, - /// - /// Twitter - /// - Twitter, + /// + /// Twitter + /// + Twitter, - /// - /// YouTube - /// - YouTube - } + /// + /// YouTube + /// + YouTube, } \ No newline at end of file diff --git a/YandexMusic.API/Models/Common/YLyrics.cs b/YandexMusic.API/Models/Common/YLyrics.cs index ca8b34f..d10c23a 100644 --- a/YandexMusic.API/Models/Common/YLyrics.cs +++ b/YandexMusic.API/Models/Common/YLyrics.cs @@ -1,12 +1,11 @@ -namespace YandexMusic.API.Models.Common +namespace YandexMusic.API.Models.Common; + +public class YLyrics { - public class YLyrics - { - public string Id { get; set; } - public string Lyrics { get; set; } - public string FullLyrics { get; set; } - public bool HasRights { get; set; } - public bool ShowTranslation { get; set; } - public string TextLanguage { get; set; } - } + public string Id { get; set; } + public string Lyrics { get; set; } + public string FullLyrics { get; set; } + public bool HasRights { get; set; } + public bool ShowTranslation { get; set; } + public string TextLanguage { get; set; } } \ No newline at end of file diff --git a/YandexMusic.API/Models/Common/YLyricsInfo.cs b/YandexMusic.API/Models/Common/YLyricsInfo.cs index 3d4d057..c2d21df 100644 --- a/YandexMusic.API/Models/Common/YLyricsInfo.cs +++ b/YandexMusic.API/Models/Common/YLyricsInfo.cs @@ -1,8 +1,7 @@ -namespace YandexMusic.API.Models.Common +namespace YandexMusic.API.Models.Common; + +public class YLyricsInfo { - public class YLyricsInfo - { - public bool HasAvailableSyncLyrics { get; set; } - public bool HasAvailableTextLyrics { get; set; } - } + public bool HasAvailableSyncLyrics { get; set; } + public bool HasAvailableTextLyrics { get; set; } } \ No newline at end of file diff --git a/YandexMusic.API/Models/Common/YMajor.cs b/YandexMusic.API/Models/Common/YMajor.cs index fe9ffb6..d3f9ebe 100644 --- a/YandexMusic.API/Models/Common/YMajor.cs +++ b/YandexMusic.API/Models/Common/YMajor.cs @@ -1,8 +1,7 @@ -namespace YandexMusic.API.Models.Common +namespace YandexMusic.API.Models.Common; + +public class YMajor { - public class YMajor - { - public string Id { get; set; } - public string Name { get; set; } - } + public string Id { get; set; } + public string Name { get; set; } } \ No newline at end of file diff --git a/YandexMusic.API/Models/Common/YMasterHub.cs b/YandexMusic.API/Models/Common/YMasterHub.cs index 13ea416..1b816ad 100644 --- a/YandexMusic.API/Models/Common/YMasterHub.cs +++ b/YandexMusic.API/Models/Common/YMasterHub.cs @@ -1,8 +1,7 @@ -namespace YandexMusic.API.Models.Common +namespace YandexMusic.API.Models.Common; + +public class YMasterHub { - public class YMasterHub - { - public YSubscription[] ActiveSubscriptions { get; set; } - public YSubscription[] AvailableSubscriptions { get; set; } - } + public YSubscription[] ActiveSubscriptions { get; set; } + public YSubscription[] AvailableSubscriptions { get; set; } } diff --git a/YandexMusic.API/Models/Common/YMetaType.cs b/YandexMusic.API/Models/Common/YMetaType.cs index 78cf0a8..9e8ca24 100644 --- a/YandexMusic.API/Models/Common/YMetaType.cs +++ b/YandexMusic.API/Models/Common/YMetaType.cs @@ -1,8 +1,7 @@ -namespace YandexMusic.API.Models.Common +namespace YandexMusic.API.Models.Common; + +public enum YMetaType { - public enum YMetaType - { - Music, - Podcast - } + Music, + Podcast, } \ No newline at end of file diff --git a/YandexMusic.API/Models/Common/YOwner.cs b/YandexMusic.API/Models/Common/YOwner.cs index ef95bf0..c79a45a 100644 --- a/YandexMusic.API/Models/Common/YOwner.cs +++ b/YandexMusic.API/Models/Common/YOwner.cs @@ -1,11 +1,10 @@ -namespace YandexMusic.API.Models.Common +namespace YandexMusic.API.Models.Common; + +public class YOwner { - public class YOwner - { - public string Login { get; set; } - public string Name { get; set; } - public string Sex { get; set; } - public string Uid { get; set; } - public bool Verified { get; set; } - } + public string Login { get; set; } + public string Name { get; set; } + public string Sex { get; set; } + public string Uid { get; set; } + public bool Verified { get; set; } } \ No newline at end of file diff --git a/YandexMusic.API/Models/Common/YPager.cs b/YandexMusic.API/Models/Common/YPager.cs index 89ee60a..a7f38f7 100644 --- a/YandexMusic.API/Models/Common/YPager.cs +++ b/YandexMusic.API/Models/Common/YPager.cs @@ -1,9 +1,8 @@ -namespace YandexMusic.API.Models.Common +namespace YandexMusic.API.Models.Common; + +public class YPager { - public class YPager - { - public int Total { get; set; } - public int Page { get; set; } - public int PerPage { get; set; } - } + public int Total { get; set; } + public int Page { get; set; } + public int PerPage { get; set; } } diff --git a/YandexMusic.API/Models/Common/YPeriod.cs b/YandexMusic.API/Models/Common/YPeriod.cs index 76c579d..6d87136 100644 --- a/YandexMusic.API/Models/Common/YPeriod.cs +++ b/YandexMusic.API/Models/Common/YPeriod.cs @@ -1,8 +1,7 @@ -namespace YandexMusic.API.Models.Common +namespace YandexMusic.API.Models.Common; + +public class YPeriod { - public class YPeriod - { - public DateTime Start { get; set; } - public DateTime End { get; set; } - } + public DateTime Start { get; set; } + public DateTime End { get; set; } } diff --git a/YandexMusic.API/Models/Common/YPermissions.cs b/YandexMusic.API/Models/Common/YPermissions.cs index 026118b..54bcd68 100644 --- a/YandexMusic.API/Models/Common/YPermissions.cs +++ b/YandexMusic.API/Models/Common/YPermissions.cs @@ -1,9 +1,8 @@ -namespace YandexMusic.API.Models.Common +namespace YandexMusic.API.Models.Common; + +public class YPermissions { - public class YPermissions - { - public List Default { get; set; } - public DateTime Until { get; set; } - public List Values { get; set; } - } + public List Default { get; set; } + public DateTime Until { get; set; } + public List Values { get; set; } } \ No newline at end of file diff --git a/YandexMusic.API/Models/Common/YPhone.cs b/YandexMusic.API/Models/Common/YPhone.cs index d2c7734..6a60af9 100644 --- a/YandexMusic.API/Models/Common/YPhone.cs +++ b/YandexMusic.API/Models/Common/YPhone.cs @@ -1,7 +1,6 @@ -namespace YandexMusic.API.Models.Common +namespace YandexMusic.API.Models.Common; + +public class YPhone { - public class YPhone - { - public string Phone { get; set; } - } + public string Phone { get; set; } } \ No newline at end of file diff --git a/YandexMusic.API/Models/Common/YPlus.cs b/YandexMusic.API/Models/Common/YPlus.cs index df10819..005c5dd 100644 --- a/YandexMusic.API/Models/Common/YPlus.cs +++ b/YandexMusic.API/Models/Common/YPlus.cs @@ -1,8 +1,7 @@ -namespace YandexMusic.API.Models.Common +namespace YandexMusic.API.Models.Common; + +public class YPlus { - public class YPlus - { - public bool HasPlus { get; set; } - public bool IsTutorialCompleted { get; set; } - } + public bool HasPlus { get; set; } + public bool IsTutorialCompleted { get; set; } } \ No newline at end of file diff --git a/YandexMusic.API/Models/Common/YPodcastEpisodeType.cs b/YandexMusic.API/Models/Common/YPodcastEpisodeType.cs index 0ed8cee..6805ae0 100644 --- a/YandexMusic.API/Models/Common/YPodcastEpisodeType.cs +++ b/YandexMusic.API/Models/Common/YPodcastEpisodeType.cs @@ -1,9 +1,8 @@ -namespace YandexMusic.API.Models.Common +namespace YandexMusic.API.Models.Common; + +public enum YPodcastEpisodeType { - public enum YPodcastEpisodeType - { - Full, - Trailer, - Bonus - } + Full, + Trailer, + Bonus, } diff --git a/YandexMusic.API/Models/Common/YPrerolls.cs b/YandexMusic.API/Models/Common/YPrerolls.cs index bfde8e2..32dc94f 100644 --- a/YandexMusic.API/Models/Common/YPrerolls.cs +++ b/YandexMusic.API/Models/Common/YPrerolls.cs @@ -1,8 +1,7 @@ -namespace YandexMusic.API.Models.Common +namespace YandexMusic.API.Models.Common; + +public class YPrerolls { - public class YPrerolls - { - public string Id { get; set; } - public string Link { get; set; } - } + public string Id { get; set; } + public string Link { get; set; } } \ No newline at end of file diff --git a/YandexMusic.API/Models/Common/YPrice.cs b/YandexMusic.API/Models/Common/YPrice.cs index 57a7043..beeeadb 100644 --- a/YandexMusic.API/Models/Common/YPrice.cs +++ b/YandexMusic.API/Models/Common/YPrice.cs @@ -1,10 +1,9 @@ -namespace YandexMusic.API.Models.Common +namespace YandexMusic.API.Models.Common; + +public class YPrice { - public class YPrice - { - public decimal Amount { get; set; } - public string Currency { get; set; } - public string CurrencySymbol { get; set; } - public decimal Value { get; set; } - } + public decimal Amount { get; set; } + public string Currency { get; set; } + public string CurrencySymbol { get; set; } + public decimal Value { get; set; } } diff --git a/YandexMusic.API/Models/Common/YProduct.cs b/YandexMusic.API/Models/Common/YProduct.cs index 04d3137..695d322 100644 --- a/YandexMusic.API/Models/Common/YProduct.cs +++ b/YandexMusic.API/Models/Common/YProduct.cs @@ -1,22 +1,21 @@ -namespace YandexMusic.API.Models.Common +namespace YandexMusic.API.Models.Common; + +public class YProduct { - public class YProduct - { - public string IntroPeriodDuration { get; set; } - public string StartPeriodDuration { get; set; } - public string CommonPeriodDuration { get; set; } - public string TrialPeriodDuration { get; set; } - public bool Debug { get; set; } - public int Duration { get; set; } - public bool Family { get; set; } - public string Feature { get; set; } - public List Features { get; set; } - public bool Plus { get; set; } - public YPrice IntroPrice { get; set; } - public YPrice StartPrice { get; set; } - public YPrice Price { get; set; } - public string ProductId { get; set; } - public int TrialDuration { get; set; } - public YProductType Type { get; set; } - } + public string IntroPeriodDuration { get; set; } + public string StartPeriodDuration { get; set; } + public string CommonPeriodDuration { get; set; } + public string TrialPeriodDuration { get; set; } + public bool Debug { get; set; } + public int Duration { get; set; } + public bool Family { get; set; } + public string Feature { get; set; } + public List Features { get; set; } + public bool Plus { get; set; } + public YPrice IntroPrice { get; set; } + public YPrice StartPrice { get; set; } + public YPrice Price { get; set; } + public string ProductId { get; set; } + public int TrialDuration { get; set; } + public YProductType Type { get; set; } } diff --git a/YandexMusic.API/Models/Common/YProductType.cs b/YandexMusic.API/Models/Common/YProductType.cs index 30751bc..3621460 100644 --- a/YandexMusic.API/Models/Common/YProductType.cs +++ b/YandexMusic.API/Models/Common/YProductType.cs @@ -1,7 +1,6 @@ -namespace YandexMusic.API.Models.Common +namespace YandexMusic.API.Models.Common; + +public enum YProductType { - public enum YProductType - { - Subscription - } + Subscription } \ No newline at end of file diff --git a/YandexMusic.API/Models/Common/YProfile.cs b/YandexMusic.API/Models/Common/YProfile.cs index ce11719..0e6bb64 100644 --- a/YandexMusic.API/Models/Common/YProfile.cs +++ b/YandexMusic.API/Models/Common/YProfile.cs @@ -1,8 +1,7 @@ -namespace YandexMusic.API.Models.Common +namespace YandexMusic.API.Models.Common; + +public class YProfile { - public class YProfile - { - public List Addresses { get; set; } - public string Provider { get; set; } - } + public List Addresses { get; set; } + public string Provider { get; set; } } \ No newline at end of file diff --git a/YandexMusic.API/Models/Common/YReminder.cs b/YandexMusic.API/Models/Common/YReminder.cs index b631a16..45790be 100644 --- a/YandexMusic.API/Models/Common/YReminder.cs +++ b/YandexMusic.API/Models/Common/YReminder.cs @@ -1,7 +1,6 @@ -namespace YandexMusic.API.Models.Common +namespace YandexMusic.API.Models.Common; + +public class YReminder { - public class YReminder - { - public int Days { get; set; } - } + public int Days { get; set; } } diff --git a/YandexMusic.API/Models/Common/YResponse.cs b/YandexMusic.API/Models/Common/YResponse.cs index d9264e3..ef35ed6 100644 --- a/YandexMusic.API/Models/Common/YResponse.cs +++ b/YandexMusic.API/Models/Common/YResponse.cs @@ -1,12 +1,11 @@ -namespace YandexMusic.API.Models.Common +namespace YandexMusic.API.Models.Common; + +/// +/// Модель ответа от API +/// +public class YResponse { - /// - /// Модель ответа от API - /// - public class YResponse - { - public YInvocationInfo InvocationInfo { get; set; } - public T Result { get; set; } - public YPager Pager { get; set; } - } + public YInvocationInfo InvocationInfo { get; set; } + public T Result { get; set; } + public YPager Pager { get; set; } } \ No newline at end of file diff --git a/YandexMusic.API/Models/Common/YRevision.cs b/YandexMusic.API/Models/Common/YRevision.cs index 05cad29..3ec3f02 100644 --- a/YandexMusic.API/Models/Common/YRevision.cs +++ b/YandexMusic.API/Models/Common/YRevision.cs @@ -1,7 +1,6 @@ -namespace YandexMusic.API.Models.Common +namespace YandexMusic.API.Models.Common; + +public class YRevision { - public class YRevision - { - public int Revision { get; set; } - } + public int Revision { get; set; } } \ No newline at end of file diff --git a/YandexMusic.API/Models/Common/YSearchType.cs b/YandexMusic.API/Models/Common/YSearchType.cs index d2f65ab..202a6bc 100644 --- a/YandexMusic.API/Models/Common/YSearchType.cs +++ b/YandexMusic.API/Models/Common/YSearchType.cs @@ -1,56 +1,55 @@ using System.Runtime.Serialization; -namespace YandexMusic.API.Models.Common +namespace YandexMusic.API.Models.Common; + +/// +/// Тип объекта поиска +/// +public enum YSearchType { /// - /// Тип объекта поиска + /// Отсутствует значение /// - public enum YSearchType - { - /// - /// Отсутствует значение - /// - None, + None, - /// - /// Артисты - /// - Artist, + /// + /// Артисты + /// + Artist, - /// - /// Альбомы - /// - Album, + /// + /// Альбомы + /// + Album, - /// - /// Все - /// - All, + /// + /// Все + /// + All, - /// - /// Плейлисты - /// - Playlist, + /// + /// Плейлисты + /// + Playlist, - /// - /// Эпизод подкаста - /// - [EnumMember(Value = "podcast_episode")] - PodcastEpisode, + /// + /// Эпизод подкаста + /// + [EnumMember(Value = "podcast_episode")] + PodcastEpisode, - /// - /// Видео - /// - Video, + /// + /// Видео + /// + Video, - /// - /// Треки - /// - Track, + /// + /// Треки + /// + Track, - /// - /// Пользователи - /// - User - } + /// + /// Пользователи + /// + User } \ No newline at end of file diff --git a/YandexMusic.API/Models/Common/YSortOrder.cs b/YandexMusic.API/Models/Common/YSortOrder.cs index 9ffa67a..51c3b5f 100644 --- a/YandexMusic.API/Models/Common/YSortOrder.cs +++ b/YandexMusic.API/Models/Common/YSortOrder.cs @@ -1,8 +1,7 @@ -namespace YandexMusic.API.Models.Common +namespace YandexMusic.API.Models.Common; + +public enum YSortOrder { - public enum YSortOrder - { - Asc, - Desc - } + Asc, + Desc } diff --git a/YandexMusic.API/Models/Common/YStats.cs b/YandexMusic.API/Models/Common/YStats.cs index 55f36fb..d4b1e37 100644 --- a/YandexMusic.API/Models/Common/YStats.cs +++ b/YandexMusic.API/Models/Common/YStats.cs @@ -1,8 +1,7 @@ -namespace YandexMusic.API.Models.Common +namespace YandexMusic.API.Models.Common; + +public class YStats { - public class YStats - { - public int LastMonthListeners { get; set; } - public int LastMonthListenersDelta { get; set; } - } + public int LastMonthListeners { get; set; } + public int LastMonthListenersDelta { get; set; } } \ No newline at end of file diff --git a/YandexMusic.API/Models/Common/YStorageDownloadFile.cs b/YandexMusic.API/Models/Common/YStorageDownloadFile.cs index 8ff22e5..a6981e4 100644 --- a/YandexMusic.API/Models/Common/YStorageDownloadFile.cs +++ b/YandexMusic.API/Models/Common/YStorageDownloadFile.cs @@ -1,10 +1,9 @@ -namespace YandexMusic.API.Models.Common +namespace YandexMusic.API.Models.Common; + +public class YStorageDownloadFile { - public class YStorageDownloadFile - { - public string Host { get; set; } - public string Path { get; set; } - public string S { get; set; } - public string Ts { get; set; } - } + public string Host { get; set; } + public string Path { get; set; } + public string S { get; set; } + public string Ts { get; set; } } \ No newline at end of file diff --git a/YandexMusic.API/Models/Common/YStyle.cs b/YandexMusic.API/Models/Common/YStyle.cs index f917837..e2fc458 100644 --- a/YandexMusic.API/Models/Common/YStyle.cs +++ b/YandexMusic.API/Models/Common/YStyle.cs @@ -1,9 +1,8 @@ -namespace YandexMusic.API.Models.Common +namespace YandexMusic.API.Models.Common; + +public class YStyle { - public class YStyle - { - public string BgColor { get; set; } - public string BorderColor { get; set; } - public string TextColor { get; set; } - } + public string BgColor { get; set; } + public string BorderColor { get; set; } + public string TextColor { get; set; } } \ No newline at end of file diff --git a/YandexMusic.API/Models/Common/YSubscription.cs b/YandexMusic.API/Models/Common/YSubscription.cs index 5581791..c4c298a 100644 --- a/YandexMusic.API/Models/Common/YSubscription.cs +++ b/YandexMusic.API/Models/Common/YSubscription.cs @@ -1,12 +1,11 @@ -namespace YandexMusic.API.Models.Common +namespace YandexMusic.API.Models.Common; + +public class YSubscription { - public class YSubscription - { - public List AutoRenewable { get; set; } - public bool CanStartTrial { get; set; } - public bool HadAnySubscription { get; set; } - public bool McDonalds { get; set; } - public YPeriod NonAutoRenewable { get; set; } - public YReminder NonAutoRenewableRemainder { get; set; } - } + public List AutoRenewable { get; set; } + public bool CanStartTrial { get; set; } + public bool HadAnySubscription { get; set; } + public bool McDonalds { get; set; } + public YPeriod NonAutoRenewable { get; set; } + public YReminder NonAutoRenewableRemainder { get; set; } } \ No newline at end of file diff --git a/YandexMusic.API/Models/Common/YSubscriptionService.cs b/YandexMusic.API/Models/Common/YSubscriptionService.cs index c6e6d0a..c106345 100644 --- a/YandexMusic.API/Models/Common/YSubscriptionService.cs +++ b/YandexMusic.API/Models/Common/YSubscriptionService.cs @@ -1,13 +1,12 @@ -namespace YandexMusic.API.Models.Common +namespace YandexMusic.API.Models.Common; + +public class YSubscriptionService { - public class YSubscriptionService - { - public DateTime Expires { get; set; } - public bool Finished { get; set; } - public decimal OrderId { get; set; } - public string ProductId { get; set; } - public YProduct Product { get; set; } - public string Vendor { get; set; } - public string VendorHelpUrl { get; set; } - } + public DateTime Expires { get; set; } + public bool Finished { get; set; } + public decimal OrderId { get; set; } + public string ProductId { get; set; } + public YProduct Product { get; set; } + public string Vendor { get; set; } + public string VendorHelpUrl { get; set; } } diff --git a/YandexMusic.API/Models/Common/YTag.cs b/YandexMusic.API/Models/Common/YTag.cs index da6d20e..d359d2c 100644 --- a/YandexMusic.API/Models/Common/YTag.cs +++ b/YandexMusic.API/Models/Common/YTag.cs @@ -1,8 +1,7 @@ -namespace YandexMusic.API.Models.Common +namespace YandexMusic.API.Models.Common; + +public class YTag { - public class YTag - { - public string Id { get; set; } - public string Value { get; set; } - } + public string Id { get; set; } + public string Value { get; set; } } \ No newline at end of file diff --git a/YandexMusic.API/Models/Common/YTrackDownloadInfo.cs b/YandexMusic.API/Models/Common/YTrackDownloadInfo.cs index 44f3244..5669ee5 100644 --- a/YandexMusic.API/Models/Common/YTrackDownloadInfo.cs +++ b/YandexMusic.API/Models/Common/YTrackDownloadInfo.cs @@ -1,12 +1,11 @@ -namespace YandexMusic.API.Models.Common +namespace YandexMusic.API.Models.Common; + +public class YTrackDownloadInfo { - public class YTrackDownloadInfo - { - public int BitrateInKbps { get; set; } - public string Codec { get; set; } - public bool Direct { get; set; } - public string DownloadInfoUrl { get; set; } - public bool Gain { get; set; } - public bool Preview { get; set; } - } + public int BitrateInKbps { get; set; } + public string Codec { get; set; } + public bool Direct { get; set; } + public string DownloadInfoUrl { get; set; } + public bool Gain { get; set; } + public bool Preview { get; set; } } \ No newline at end of file diff --git a/YandexMusic.API/Models/Common/YTrackId.cs b/YandexMusic.API/Models/Common/YTrackId.cs index 1c7e9df..26d1f8e 100644 --- a/YandexMusic.API/Models/Common/YTrackId.cs +++ b/YandexMusic.API/Models/Common/YTrackId.cs @@ -1,10 +1,9 @@ -namespace YandexMusic.API.Models.Common +namespace YandexMusic.API.Models.Common; + +public class YTrackId { - public class YTrackId - { - public string Id { get; set; } - public string TrackId { get; set; } - public string AlbumId { get; set; } - public string From { get; set; } - } + public string Id { get; set; } + public string TrackId { get; set; } + public string AlbumId { get; set; } + public string From { get; set; } } diff --git a/YandexMusic.API/Models/Common/YTrackSharingFlag.cs b/YandexMusic.API/Models/Common/YTrackSharingFlag.cs index 9b07ead..77a1000 100644 --- a/YandexMusic.API/Models/Common/YTrackSharingFlag.cs +++ b/YandexMusic.API/Models/Common/YTrackSharingFlag.cs @@ -1,12 +1,11 @@ using System.Runtime.Serialization; -namespace YandexMusic.API.Models.Common +namespace YandexMusic.API.Models.Common; + +public enum YTrackSharingFlag { - public enum YTrackSharingFlag - { - [EnumMember(Value = "VIDEO_ALLOWED")] - VideoAllowed, - [EnumMember(Value = "COVER_ONLY")] - CoverOnly - } + [EnumMember(Value = "VIDEO_ALLOWED")] + VideoAllowed, + [EnumMember(Value = "COVER_ONLY")] + CoverOnly } diff --git a/YandexMusic.API/Models/Common/YTrackSource.cs b/YandexMusic.API/Models/Common/YTrackSource.cs index 6ae8cc5..ce23882 100644 --- a/YandexMusic.API/Models/Common/YTrackSource.cs +++ b/YandexMusic.API/Models/Common/YTrackSource.cs @@ -1,18 +1,17 @@ using System.ComponentModel; using System.Runtime.Serialization; -namespace YandexMusic.API.Models.Common +namespace YandexMusic.API.Models.Common; + +public enum YTrackSource { - public enum YTrackSource - { - [EnumMember(Value = "OWN")] - Own, + [EnumMember(Value = "OWN")] + Own, - [EnumMember(Value = "UGC")] - [Description("User Generated Content")] - UGC, + [EnumMember(Value = "UGC")] + [Description("User Generated Content")] + UGC, - [EnumMember(Value = "OWN_REPLACED_TO_UGC")] - OwnReplacedToUGC, - } + [EnumMember(Value = "OWN_REPLACED_TO_UGC")] + OwnReplacedToUGC, } \ No newline at end of file diff --git a/YandexMusic.API/Models/Common/YTrailer.cs b/YandexMusic.API/Models/Common/YTrailer.cs index 1bc74b3..a146403 100644 --- a/YandexMusic.API/Models/Common/YTrailer.cs +++ b/YandexMusic.API/Models/Common/YTrailer.cs @@ -1,7 +1,6 @@ -namespace YandexMusic.API.Models.Common +namespace YandexMusic.API.Models.Common; + +public class YTrailer { - public class YTrailer - { - public bool Available { get; set; } - } + public bool Available { get; set; } } \ No newline at end of file diff --git a/YandexMusic.API/Models/Common/YUser.cs b/YandexMusic.API/Models/Common/YUser.cs index 0d71baa..980afa8 100644 --- a/YandexMusic.API/Models/Common/YUser.cs +++ b/YandexMusic.API/Models/Common/YUser.cs @@ -1,17 +1,16 @@ -namespace YandexMusic.API.Models.Common +namespace YandexMusic.API.Models.Common; + +public class YUser { - public class YUser - { - public string DeviceId { get; set; } - public string Experiments { get; set; } - public string FirstName { get; set; } - public string Lang { get; set; } - public string Login { get; set; } - public string Name { get; set; } - public string SecondName { get; set; } - public string Sign { get; set; } - public long Timestamp { get; set; } - public string Uid { get; set; } - public string YandexId { get; set; } - } + public string DeviceId { get; set; } + public string Experiments { get; set; } + public string FirstName { get; set; } + public string Lang { get; set; } + public string Login { get; set; } + public string Name { get; set; } + public string SecondName { get; set; } + public string Sign { get; set; } + public long Timestamp { get; set; } + public string Uid { get; set; } + public string YandexId { get; set; } } \ No newline at end of file diff --git a/YandexMusic.API/Models/Common/YVideo.cs b/YandexMusic.API/Models/Common/YVideo.cs index b41d8fc..1db16ec 100644 --- a/YandexMusic.API/Models/Common/YVideo.cs +++ b/YandexMusic.API/Models/Common/YVideo.cs @@ -1,11 +1,10 @@ -namespace YandexMusic.API.Models.Common +namespace YandexMusic.API.Models.Common; + +public class YVideo { - public class YVideo - { - public string Cover { get; set; } - public string EmbedUrl { get; set; } - public string Provider { get; set; } - public string ProviderVideoId { get; set; } - public string Title { get; set; } - } + public string Cover { get; set; } + public string EmbedUrl { get; set; } + public string Provider { get; set; } + public string ProviderVideoId { get; set; } + public string Title { get; set; } } \ No newline at end of file diff --git a/YandexMusic.API/Models/Common/YVinyl.cs b/YandexMusic.API/Models/Common/YVinyl.cs index ad27843..25ec472 100644 --- a/YandexMusic.API/Models/Common/YVinyl.cs +++ b/YandexMusic.API/Models/Common/YVinyl.cs @@ -1,14 +1,13 @@ -namespace YandexMusic.API.Models.Common +namespace YandexMusic.API.Models.Common; + +public class YVinyl { - public class YVinyl - { - public List ArtistIds { get; set; } - public string Media { get; set; } - public string OfferId { get; set; } - public string Picture { get; set; } - public decimal Price { get; set; } - public string Title { get; set; } - public string Url { get; set; } - public int Year { get; set; } - } + public List ArtistIds { get; set; } + public string Media { get; set; } + public string OfferId { get; set; } + public string Picture { get; set; } + public decimal Price { get; set; } + public string Title { get; set; } + public string Url { get; set; } + public int Year { get; set; } } \ No newline at end of file diff --git a/YandexMusic.API/Models/Feed/Event/YArtistsFromHistory.cs b/YandexMusic.API/Models/Feed/Event/YArtistsFromHistory.cs index 25ec5d9..e9c9734 100644 --- a/YandexMusic.API/Models/Feed/Event/YArtistsFromHistory.cs +++ b/YandexMusic.API/Models/Feed/Event/YArtistsFromHistory.cs @@ -1,10 +1,9 @@ using YandexMusic.API.Models.Artist; -namespace YandexMusic.API.Models.Feed.Event +namespace YandexMusic.API.Models.Feed.Event; + +public class YArtistsFromHistory { - public class YArtistsFromHistory - { - public YArtist Artist { get; set; } - public List ArtistsFromHistory { get; set; } - } + public YArtist Artist { get; set; } + public List ArtistsFromHistory { get; set; } } \ No newline at end of file diff --git a/YandexMusic.API/Models/Feed/Event/YFeedEvent.cs b/YandexMusic.API/Models/Feed/Event/YFeedEvent.cs index 5cea1ae..22d53af 100644 --- a/YandexMusic.API/Models/Feed/Event/YFeedEvent.cs +++ b/YandexMusic.API/Models/Feed/Event/YFeedEvent.cs @@ -1,104 +1,9 @@ -namespace YandexMusic.API.Models.Feed.Event +using YandexMusic.API.Models.Feed.Event; + +namespace YandexMusic.API.Models.Feed; + +public class YFeedEvent { - public sealed class YFeedEventConverter : JsonConverter - { - private YFeedEventTitled GetEvent(JToken jObject) - { - YFeedEventTitled feedEvent; - - YFeedEventType type = jObject[jObject["typeForFrom"] != null ? "typeForFrom" : "type"] - .ToObject(); - - switch (type) - { - case YFeedEventType.GenreTop: - feedEvent = jObject.ToObject(); - break; - - case YFeedEventType.NewAlbums: - feedEvent = jObject.ToObject(); - break; - - case YFeedEventType.NewAlbumsOfFavoriteGenre: - feedEvent = jObject.ToObject(); - break; - - case YFeedEventType.Notification: - feedEvent = jObject.ToObject(); - break; - - case YFeedEventType.Promotion: - feedEvent = jObject.ToObject(); - break; - - case YFeedEventType.RecentTrackLikeToTracks: - feedEvent = jObject.ToObject(); - break; - - case YFeedEventType.RecommendedArtistsWithArtistsFromHistory: - feedEvent = jObject.ToObject(); - break; - - case YFeedEventType.RecommendedSimilarArtists: - feedEvent = jObject.ToObject(); - break; - - case YFeedEventType.RecommendedSimilarGenre: - feedEvent = jObject.ToObject(); - break; - - case YFeedEventType.MissedTracksByArtist: - case YFeedEventType.RareArtist: - case YFeedEventType.RecommendedTracksByArtistFromHistory: - feedEvent = jObject.ToObject(); - break; - - case YFeedEventType.NewTracksOfFavoriteGenre: - case YFeedEventType.TracksByGenre: - feedEvent = jObject.ToObject(); - break; - - case YFeedEventType.WellForgottenOldArtists: - feedEvent = jObject.ToObject(); - break; - - case YFeedEventType.NeverHeardFromLibrary: - case YFeedEventType.WellForgottenOldTracks: - feedEvent = jObject.ToObject(); - break; - - default: - feedEvent = jObject.ToObject(); - break; - } - - return feedEvent; - } - - public override bool CanConvert(Type objectType) - { - return typeof(YFeedEventTitled).IsAssignableFrom(objectType); - } - - public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) - { - if (reader.TokenType == JsonToken.Null) - return null; - - return JArray.Load(reader) - .Select(GetEvent) - .ToList(); - } - - public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) - { - throw new NotImplementedException(); - } - } - - public class YFeedEvent - { - public string Id { get; set; } - public YFeedEventType Type { get; set; } - } + public string Id { get; set; } + public YFeedEventType Type { get; set; } } \ No newline at end of file diff --git a/YandexMusic.API/Models/Feed/Event/YFeedEventAlbums.cs b/YandexMusic.API/Models/Feed/Event/YFeedEventAlbums.cs index 2acfeb3..02efa6b 100644 --- a/YandexMusic.API/Models/Feed/Event/YFeedEventAlbums.cs +++ b/YandexMusic.API/Models/Feed/Event/YFeedEventAlbums.cs @@ -1,9 +1,8 @@ using YandexMusic.API.Models.Album; -namespace YandexMusic.API.Models.Feed.Event +namespace YandexMusic.API.Models.Feed.Event; + +public class YFeedEventAlbums : YFeedEventTitled { - public class YFeedEventAlbums : YFeedEventTitled - { - public List Albums { get; set; } - } + public List Albums { get; set; } } \ No newline at end of file diff --git a/YandexMusic.API/Models/Feed/Event/YFeedEventArtist.cs b/YandexMusic.API/Models/Feed/Event/YFeedEventArtist.cs index e89f34b..e1cee11 100644 --- a/YandexMusic.API/Models/Feed/Event/YFeedEventArtist.cs +++ b/YandexMusic.API/Models/Feed/Event/YFeedEventArtist.cs @@ -1,9 +1,8 @@ using YandexMusic.API.Models.Artist; -namespace YandexMusic.API.Models.Feed.Event +namespace YandexMusic.API.Models.Feed.Event; + +public class YFeedEventArtist : YFeedEventTracks { - public class YFeedEventArtist : YFeedEventTracks - { - public YArtist Artist { get; set; } - } + public YArtist Artist { get; set; } } \ No newline at end of file diff --git a/YandexMusic.API/Models/Feed/Event/YFeedEventArtistWithArtists.cs b/YandexMusic.API/Models/Feed/Event/YFeedEventArtistWithArtists.cs index 412673e..5903d41 100644 --- a/YandexMusic.API/Models/Feed/Event/YFeedEventArtistWithArtists.cs +++ b/YandexMusic.API/Models/Feed/Event/YFeedEventArtistWithArtists.cs @@ -1,7 +1,6 @@ -namespace YandexMusic.API.Models.Feed.Event +namespace YandexMusic.API.Models.Feed.Event; + +public class YFeedEventArtistWithArtists : YFeedEventTitled { - public class YFeedEventArtistWithArtists : YFeedEventTitled - { - public List ArtistsWithArtistsFromHistory { get; set; } - } + public List ArtistsWithArtistsFromHistory { get; set; } } \ No newline at end of file diff --git a/YandexMusic.API/Models/Feed/Event/YFeedEventArtists.cs b/YandexMusic.API/Models/Feed/Event/YFeedEventArtists.cs index 4d180e5..f7c3550 100644 --- a/YandexMusic.API/Models/Feed/Event/YFeedEventArtists.cs +++ b/YandexMusic.API/Models/Feed/Event/YFeedEventArtists.cs @@ -1,9 +1,8 @@ using YandexMusic.API.Models.Artist; -namespace YandexMusic.API.Models.Feed.Event +namespace YandexMusic.API.Models.Feed.Event; + +public class YFeedEventArtists : YFeedEventTitled { - public class YFeedEventArtists : YFeedEventTitled - { - public List Artists { get; set; } - } + public List Artists { get; set; } } \ No newline at end of file diff --git a/YandexMusic.API/Models/Feed/Event/YFeedEventConverter.cs b/YandexMusic.API/Models/Feed/Event/YFeedEventConverter.cs new file mode 100644 index 0000000..386666b --- /dev/null +++ b/YandexMusic.API/Models/Feed/Event/YFeedEventConverter.cs @@ -0,0 +1,97 @@ +using System.Text.Json; +using System.Text.Json.Serialization; +using YandexMusic.API.Models.Feed.Event; + +namespace YandexMusic.API.Models.Feed; + +/// Конвертер для событий ленты (десериализация в конкретные типы на основе поля type). +public class YFeedEventConverter : JsonConverter> +{ + public override List Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + { + if (reader.TokenType != JsonTokenType.StartArray) + throw new JsonException("Ожидается массив событий"); + + var events = new List(); + while (reader.Read()) + { + if (reader.TokenType == JsonTokenType.EndArray) + break; + + if (reader.TokenType != JsonTokenType.StartObject) + throw new JsonException("Ожидается объект события"); + + using var doc = JsonDocument.ParseValue(ref reader); + var root = doc.RootElement; + + // Определяем тип события: может быть в поле "typeForFrom" или "type" + var typeToken = root.TryGetProperty("typeForFrom", out var tf) ? tf : + (root.TryGetProperty("type", out var t) ? t : throw new JsonException("Не найден тип события")); + var typeStr = typeToken.GetString(); + if (!Enum.TryParse(typeStr, true, out var eventType)) + throw new JsonException($"Неизвестный тип события: {typeStr}"); + + YFeedEventTitled? feedEvent = null; + var rawText = root.GetRawText(); + + switch (eventType) + { + case YFeedEventType.GenreTop: + feedEvent = JsonSerializer.Deserialize(rawText, options); + break; + case YFeedEventType.NewAlbums: + feedEvent = JsonSerializer.Deserialize(rawText, options); + break; + case YFeedEventType.NewAlbumsOfFavoriteGenre: + feedEvent = JsonSerializer.Deserialize(rawText, options); + break; + case YFeedEventType.Notification: + feedEvent = JsonSerializer.Deserialize(rawText, options); + break; + case YFeedEventType.Promotion: + feedEvent = JsonSerializer.Deserialize(rawText, options); + break; + case YFeedEventType.RecentTrackLikeToTracks: + feedEvent = JsonSerializer.Deserialize(rawText, options); + break; + case YFeedEventType.RecommendedArtistsWithArtistsFromHistory: + feedEvent = JsonSerializer.Deserialize(rawText, options); + break; + case YFeedEventType.RecommendedSimilarArtists: + feedEvent = JsonSerializer.Deserialize(rawText, options); + break; + case YFeedEventType.RecommendedSimilarGenre: + feedEvent = JsonSerializer.Deserialize(rawText, options); + break; + case YFeedEventType.MissedTracksByArtist: + case YFeedEventType.RareArtist: + case YFeedEventType.RecommendedTracksByArtistFromHistory: + feedEvent = JsonSerializer.Deserialize(rawText, options); + break; + case YFeedEventType.NewTracksOfFavoriteGenre: + case YFeedEventType.TracksByGenre: + feedEvent = JsonSerializer.Deserialize(rawText, options); + break; + case YFeedEventType.WellForgottenOldArtists: + feedEvent = JsonSerializer.Deserialize(rawText, options); + break; + case YFeedEventType.NeverHeardFromLibrary: + case YFeedEventType.WellForgottenOldTracks: + feedEvent = JsonSerializer.Deserialize(rawText, options); + break; + default: + feedEvent = JsonSerializer.Deserialize(rawText, options); + break; + } + + if (feedEvent != null) + events.Add(feedEvent); + } + return events; + } + + public override void Write(Utf8JsonWriter writer, List value, JsonSerializerOptions options) + { + JsonSerializer.Serialize(writer, value, options); + } +} diff --git a/YandexMusic.API/Models/Feed/Event/YFeedEventGenreAlbums.cs b/YandexMusic.API/Models/Feed/Event/YFeedEventGenreAlbums.cs index dea9b71..18718b8 100644 --- a/YandexMusic.API/Models/Feed/Event/YFeedEventGenreAlbums.cs +++ b/YandexMusic.API/Models/Feed/Event/YFeedEventGenreAlbums.cs @@ -1,7 +1,6 @@ -namespace YandexMusic.API.Models.Feed.Event +namespace YandexMusic.API.Models.Feed.Event; + +public class YFeedEventGenreAlbums : YFeedEventAlbums { - public class YFeedEventGenreAlbums : YFeedEventAlbums - { - public string Genre { get; set; } - } + public string Genre { get; set; } } \ No newline at end of file diff --git a/YandexMusic.API/Models/Feed/Event/YFeedEventGenreTracks.cs b/YandexMusic.API/Models/Feed/Event/YFeedEventGenreTracks.cs index 73d6719..f15d4e6 100644 --- a/YandexMusic.API/Models/Feed/Event/YFeedEventGenreTracks.cs +++ b/YandexMusic.API/Models/Feed/Event/YFeedEventGenreTracks.cs @@ -1,7 +1,6 @@ -namespace YandexMusic.API.Models.Feed.Event +namespace YandexMusic.API.Models.Feed.Event; + +public class YFeedEventGenreTracks : YFeedEventTracks { - public class YFeedEventGenreTracks : YFeedEventTracks - { - public string Genre { get; set; } - } + public string Genre { get; set; } } \ No newline at end of file diff --git a/YandexMusic.API/Models/Feed/Event/YFeedEventGenreTracksTop.cs b/YandexMusic.API/Models/Feed/Event/YFeedEventGenreTracksTop.cs index 9b26809..8247ec7 100644 --- a/YandexMusic.API/Models/Feed/Event/YFeedEventGenreTracksTop.cs +++ b/YandexMusic.API/Models/Feed/Event/YFeedEventGenreTracksTop.cs @@ -1,7 +1,6 @@ -namespace YandexMusic.API.Models.Feed.Event +namespace YandexMusic.API.Models.Feed.Event; + +public class YFeedEventGenreTracksTop : YFeedEventGenreTracks { - public class YFeedEventGenreTracksTop : YFeedEventGenreTracks - { - public bool RadioIsAvailable { get; set; } - } + public bool RadioIsAvailable { get; set; } } \ No newline at end of file diff --git a/YandexMusic.API/Models/Feed/Event/YFeedEventLikeTrack.cs b/YandexMusic.API/Models/Feed/Event/YFeedEventLikeTrack.cs index 0a7a2b1..66d6192 100644 --- a/YandexMusic.API/Models/Feed/Event/YFeedEventLikeTrack.cs +++ b/YandexMusic.API/Models/Feed/Event/YFeedEventLikeTrack.cs @@ -1,9 +1,8 @@ using YandexMusic.API.Models.Track; -namespace YandexMusic.API.Models.Feed.Event +namespace YandexMusic.API.Models.Feed.Event; + +public class YFeedEventLikeTrack : YFeedEventTracks { - public class YFeedEventLikeTrack : YFeedEventTracks - { - public YTrack LikedTrack { get; set; } - } + public YTrack LikedTrack { get; set; } } \ No newline at end of file diff --git a/YandexMusic.API/Models/Feed/Event/YFeedEventNotification.cs b/YandexMusic.API/Models/Feed/Event/YFeedEventNotification.cs index 8db2406..d1f1e6b 100644 --- a/YandexMusic.API/Models/Feed/Event/YFeedEventNotification.cs +++ b/YandexMusic.API/Models/Feed/Event/YFeedEventNotification.cs @@ -1,7 +1,6 @@ -namespace YandexMusic.API.Models.Feed.Event +namespace YandexMusic.API.Models.Feed.Event; + +public class YFeedEventNotification : YFeedEventTitled { - public class YFeedEventNotification : YFeedEventTitled - { - public string Message { get; set; } - } + public string Message { get; set; } } \ No newline at end of file diff --git a/YandexMusic.API/Models/Feed/Event/YFeedEventPromotion.cs b/YandexMusic.API/Models/Feed/Event/YFeedEventPromotion.cs index ea2716a..c56009c 100644 --- a/YandexMusic.API/Models/Feed/Event/YFeedEventPromotion.cs +++ b/YandexMusic.API/Models/Feed/Event/YFeedEventPromotion.cs @@ -1,7 +1,6 @@ -namespace YandexMusic.API.Models.Feed.Event +namespace YandexMusic.API.Models.Feed.Event; + +public class YFeedEventPromotion : YFeedEventTitled { - public class YFeedEventPromotion : YFeedEventTitled - { - public YFeedPromotion Promo { get; set; } - } + public YFeedPromotion Promo { get; set; } } \ No newline at end of file diff --git a/YandexMusic.API/Models/Feed/Event/YFeedEventPromotionType.cs b/YandexMusic.API/Models/Feed/Event/YFeedEventPromotionType.cs index 3f7d1b0..3a7b9ee 100644 --- a/YandexMusic.API/Models/Feed/Event/YFeedEventPromotionType.cs +++ b/YandexMusic.API/Models/Feed/Event/YFeedEventPromotionType.cs @@ -1,8 +1,7 @@ -namespace YandexMusic.API.Models.Feed.Event +namespace YandexMusic.API.Models.Feed.Event; + +public enum YFeedEventPromotionType { - public enum YFeedEventPromotionType - { - Albums, - Tracks - } + Albums, + Tracks } \ No newline at end of file diff --git a/YandexMusic.API/Models/Feed/Event/YFeedEventSimilarArtists.cs b/YandexMusic.API/Models/Feed/Event/YFeedEventSimilarArtists.cs index 2ad0537..2ba210e 100644 --- a/YandexMusic.API/Models/Feed/Event/YFeedEventSimilarArtists.cs +++ b/YandexMusic.API/Models/Feed/Event/YFeedEventSimilarArtists.cs @@ -1,10 +1,9 @@ using YandexMusic.API.Models.Artist; -namespace YandexMusic.API.Models.Feed.Event +namespace YandexMusic.API.Models.Feed.Event; + +public class YFeedEventSimilarArtists : YFeedEventTitled { - public class YFeedEventSimilarArtists : YFeedEventTitled - { - public YArtist SimilarToArtist { get; set; } - public List SimilarArtists { get; set; } - } + public YArtist SimilarToArtist { get; set; } + public List SimilarArtists { get; set; } } \ No newline at end of file diff --git a/YandexMusic.API/Models/Feed/Event/YFeedEventSimilarGenre.cs b/YandexMusic.API/Models/Feed/Event/YFeedEventSimilarGenre.cs index 0136615..7b402a0 100644 --- a/YandexMusic.API/Models/Feed/Event/YFeedEventSimilarGenre.cs +++ b/YandexMusic.API/Models/Feed/Event/YFeedEventSimilarGenre.cs @@ -1,8 +1,7 @@ -namespace YandexMusic.API.Models.Feed.Event +namespace YandexMusic.API.Models.Feed.Event; + +public class YFeedEventSimilarGenre : YFeedEventTracks { - public class YFeedEventSimilarGenre : YFeedEventTracks - { - public string SimilarToGenre { get; set; } - public string SimilarGenre { get; set; } - } + public string SimilarToGenre { get; set; } + public string SimilarGenre { get; set; } } \ No newline at end of file diff --git a/YandexMusic.API/Models/Feed/Event/YFeedEventTitle.cs b/YandexMusic.API/Models/Feed/Event/YFeedEventTitle.cs index df2f444..71fa72d 100644 --- a/YandexMusic.API/Models/Feed/Event/YFeedEventTitle.cs +++ b/YandexMusic.API/Models/Feed/Event/YFeedEventTitle.cs @@ -1,10 +1,9 @@ -namespace YandexMusic.API.Models.Feed.Event +namespace YandexMusic.API.Models.Feed.Event; + +public class YFeedEventTitle { - public class YFeedEventTitle - { - public string Id { get; set; } - public YFeedEventTitleType Type { get; set; } - public string Name { get; set; } - public string Text { get; set; } - } + public string Id { get; set; } + public YFeedEventTitleType Type { get; set; } + public string Name { get; set; } + public string Text { get; set; } } \ No newline at end of file diff --git a/YandexMusic.API/Models/Feed/Event/YFeedEventTitleType.cs b/YandexMusic.API/Models/Feed/Event/YFeedEventTitleType.cs index f124547..0fd5c6a 100644 --- a/YandexMusic.API/Models/Feed/Event/YFeedEventTitleType.cs +++ b/YandexMusic.API/Models/Feed/Event/YFeedEventTitleType.cs @@ -1,10 +1,9 @@ -namespace YandexMusic.API.Models.Feed.Event +namespace YandexMusic.API.Models.Feed.Event; + +public enum YFeedEventTitleType { - public enum YFeedEventTitleType - { - Artist, - Genre, - Text, - Track - } + Artist, + Genre, + Text, + Track } \ No newline at end of file diff --git a/YandexMusic.API/Models/Feed/Event/YFeedEventTitled.cs b/YandexMusic.API/Models/Feed/Event/YFeedEventTitled.cs index fc510bd..c590ea5 100644 --- a/YandexMusic.API/Models/Feed/Event/YFeedEventTitled.cs +++ b/YandexMusic.API/Models/Feed/Event/YFeedEventTitled.cs @@ -1,8 +1,7 @@ -namespace YandexMusic.API.Models.Feed.Event +namespace YandexMusic.API.Models.Feed.Event; + +public class YFeedEventTitled : YFeedEvent { - public class YFeedEventTitled : YFeedEvent - { - public List Title { get; set; } - public YFeedEventType TypeForFrom { get; set; } - } + public List Title { get; set; } + public YFeedEventType TypeForFrom { get; set; } } \ No newline at end of file diff --git a/YandexMusic.API/Models/Feed/Event/YFeedEventTracks.cs b/YandexMusic.API/Models/Feed/Event/YFeedEventTracks.cs index b259c59..265a99d 100644 --- a/YandexMusic.API/Models/Feed/Event/YFeedEventTracks.cs +++ b/YandexMusic.API/Models/Feed/Event/YFeedEventTracks.cs @@ -1,9 +1,8 @@ using YandexMusic.API.Models.Track; -namespace YandexMusic.API.Models.Feed.Event +namespace YandexMusic.API.Models.Feed.Event; + +public class YFeedEventTracks : YFeedEventTitled { - public class YFeedEventTracks : YFeedEventTitled - { - public List Tracks { get; set; } - } + public List Tracks { get; set; } } \ No newline at end of file diff --git a/YandexMusic.API/Models/Feed/Event/YFeedEventType.cs b/YandexMusic.API/Models/Feed/Event/YFeedEventType.cs index b111c02..8eb6d11 100644 --- a/YandexMusic.API/Models/Feed/Event/YFeedEventType.cs +++ b/YandexMusic.API/Models/Feed/Event/YFeedEventType.cs @@ -1,59 +1,58 @@ using System.Runtime.Serialization; -namespace YandexMusic.API.Models.Feed.Event +namespace YandexMusic.API.Models.Feed.Event; + +public enum YFeedEventType { - public enum YFeedEventType - { - [EnumMember(Value = "genre-top")] - GenreTop, + [EnumMember(Value = "genre-top")] + GenreTop, - [EnumMember(Value = "missed-tracks-by-artist")] - MissedTracksByArtist, + [EnumMember(Value = "missed-tracks-by-artist")] + MissedTracksByArtist, - [EnumMember(Value = "never-heard-from-library")] - NeverHeardFromLibrary, + [EnumMember(Value = "never-heard-from-library")] + NeverHeardFromLibrary, - [EnumMember(Value = "new-albums")] - NewAlbums, + [EnumMember(Value = "new-albums")] + NewAlbums, - [EnumMember(Value = "new-albums-of-favorite-genre")] - NewAlbumsOfFavoriteGenre, + [EnumMember(Value = "new-albums-of-favorite-genre")] + NewAlbumsOfFavoriteGenre, - [EnumMember(Value = "new-tracks-of-favorite-genre")] - NewTracksOfFavoriteGenre, + [EnumMember(Value = "new-tracks-of-favorite-genre")] + NewTracksOfFavoriteGenre, - Notification, + Notification, - Promotion, + Promotion, - [EnumMember(Value = "rare-artist")] - RareArtist, + [EnumMember(Value = "rare-artist")] + RareArtist, - [EnumMember(Value = "recent-track-like-to-tracks")] - RecentTrackLikeToTracks, + [EnumMember(Value = "recent-track-like-to-tracks")] + RecentTrackLikeToTracks, - [EnumMember(Value = "recommended-artists-with-artists-from-history")] - RecommendedArtistsWithArtistsFromHistory, + [EnumMember(Value = "recommended-artists-with-artists-from-history")] + RecommendedArtistsWithArtistsFromHistory, - [EnumMember(Value = "recommended-similar-artists")] - RecommendedSimilarArtists, + [EnumMember(Value = "recommended-similar-artists")] + RecommendedSimilarArtists, - [EnumMember(Value = "recommended-similar-genre")] - RecommendedSimilarGenre, + [EnumMember(Value = "recommended-similar-genre")] + RecommendedSimilarGenre, - [EnumMember(Value = "recommended-tracks-by-artist-from-history")] - RecommendedTracksByArtistFromHistory, + [EnumMember(Value = "recommended-tracks-by-artist-from-history")] + RecommendedTracksByArtistFromHistory, - [EnumMember(Value = "similar-tracks-from-history")] - SimilarTracksFromHistory, + [EnumMember(Value = "similar-tracks-from-history")] + SimilarTracksFromHistory, - [EnumMember(Value = "tracks-by-genre")] - TracksByGenre, + [EnumMember(Value = "tracks-by-genre")] + TracksByGenre, - [EnumMember(Value = "well-forgotten-old-artists")] - WellForgottenOldArtists, + [EnumMember(Value = "well-forgotten-old-artists")] + WellForgottenOldArtists, - [EnumMember(Value = "well-forgotten-old-tracks")] - WellForgottenOldTracks - } + [EnumMember(Value = "well-forgotten-old-tracks")] + WellForgottenOldTracks, } \ No newline at end of file diff --git a/YandexMusic.API/Models/Feed/Event/YFeedPromotion.cs b/YandexMusic.API/Models/Feed/Event/YFeedPromotion.cs index 13c95fe..72cf754 100644 --- a/YandexMusic.API/Models/Feed/Event/YFeedPromotion.cs +++ b/YandexMusic.API/Models/Feed/Event/YFeedPromotion.cs @@ -2,23 +2,22 @@ using YandexMusic.API.Models.Common; using YandexMusic.API.Models.Track; -namespace YandexMusic.API.Models.Feed.Event -{ - public class YFeedPromotion - { - public string PromoId { get; set; } - public string Description { get; set; } - public string Background { get; set; } - public string ImagePosition { get; set; } - public YFeedEventPromotionType PromotionType { get; set; } - public DateTime StartDate { get; set; } - public string SubTitle { get; set; } - public string SubtitleUrl { get; set; } - public string Title { get; set; } - public string TitleUrl { get; set; } - public List Tags { get; set; } +namespace YandexMusic.API.Models.Feed.Event; - public List Albums { get; set; } - public List Tracks { get; set; } - } +public class YFeedPromotion +{ + public string PromoId { get; set; } + public string Description { get; set; } + public string Background { get; set; } + public string ImagePosition { get; set; } + public YFeedEventPromotionType PromotionType { get; set; } + public DateTime StartDate { get; set; } + public string SubTitle { get; set; } + public string SubtitleUrl { get; set; } + public string Title { get; set; } + public string TitleUrl { get; set; } + public List Tags { get; set; } + + public List Albums { get; set; } + public List Tracks { get; set; } } \ No newline at end of file diff --git a/YandexMusic.API/Models/Feed/YFeed.cs b/YandexMusic.API/Models/Feed/YFeed.cs index a39858d..c06cbcf 100644 --- a/YandexMusic.API/Models/Feed/YFeed.cs +++ b/YandexMusic.API/Models/Feed/YFeed.cs @@ -1,16 +1,15 @@ using YandexMusic.API.Models.Landing.Entity.Entities; -namespace YandexMusic.API.Models.Feed +namespace YandexMusic.API.Models.Feed; + +public class YFeed { - public class YFeed - { - public DateTime NextRevision { get; set; } - public bool CanGetMoreEvents { get; set; } - public bool Pumpkin { get; set; } - public bool IsWizardPassed { get; set; } - public List Days { get; set; } - public List GeneratedPlaylists { get; set; } - public List Headlines { get; set; } - public DateTime Today { get; set; } - } + public DateTime NextRevision { get; set; } + public bool CanGetMoreEvents { get; set; } + public bool Pumpkin { get; set; } + public bool IsWizardPassed { get; set; } + public List Days { get; set; } + public List GeneratedPlaylists { get; set; } + public List Headlines { get; set; } + public DateTime Today { get; set; } } \ No newline at end of file diff --git a/YandexMusic.API/Models/Feed/YFeedDay.cs b/YandexMusic.API/Models/Feed/YFeedDay.cs index 45c9cce..b2be7d3 100644 --- a/YandexMusic.API/Models/Feed/YFeedDay.cs +++ b/YandexMusic.API/Models/Feed/YFeedDay.cs @@ -1,14 +1,14 @@ -using YandexMusic.API.Models.Feed.Event; +using System.Text.Json.Serialization; +using YandexMusic.API.Models.Feed.Event; using YandexMusic.API.Models.Track; -namespace YandexMusic.API.Models.Feed +namespace YandexMusic.API.Models.Feed; + +public class YFeedDay { - public class YFeedDay - { - public DateTime Day { get; set; } - [JsonConverter(typeof(YFeedEventConverter))] - public List Events { get; set; } - public List TracksToPlay { get; set; } - public List TracksToPlayWithAds { get; set; } - } + public DateTime Day { get; set; } + [JsonConverter(typeof(YFeedEventConverter))] + public List Events { get; set; } + public List TracksToPlay { get; set; } + public List TracksToPlayWithAds { get; set; } } \ No newline at end of file diff --git a/YandexMusic.API/Models/Feed/YFeedDayTrackWithAds.cs b/YandexMusic.API/Models/Feed/YFeedDayTrackWithAds.cs index 4a8090a..3fa9800 100644 --- a/YandexMusic.API/Models/Feed/YFeedDayTrackWithAds.cs +++ b/YandexMusic.API/Models/Feed/YFeedDayTrackWithAds.cs @@ -1,10 +1,9 @@ using YandexMusic.API.Models.Track; -namespace YandexMusic.API.Models.Feed +namespace YandexMusic.API.Models.Feed; + +public class YFeedDayTrackWithAds { - public class YFeedDayTrackWithAds - { - public YFeedDayTrackWithAdsType Type { get; set; } - public YTrack Track { get; set; } - } + public YFeedDayTrackWithAdsType Type { get; set; } + public YTrack Track { get; set; } } \ No newline at end of file diff --git a/YandexMusic.API/Models/Feed/YFeedDayTrackWithAdsType.cs b/YandexMusic.API/Models/Feed/YFeedDayTrackWithAdsType.cs index 0963411..213878f 100644 --- a/YandexMusic.API/Models/Feed/YFeedDayTrackWithAdsType.cs +++ b/YandexMusic.API/Models/Feed/YFeedDayTrackWithAdsType.cs @@ -1,7 +1,6 @@ -namespace YandexMusic.API.Models.Feed +namespace YandexMusic.API.Models.Feed; + +public enum YFeedDayTrackWithAdsType { - public enum YFeedDayTrackWithAdsType - { - Track - } + Track, } \ No newline at end of file diff --git a/YandexMusic.API/Models/Feed/YHeadline.cs b/YandexMusic.API/Models/Feed/YHeadline.cs index 3f0dcb9..7d53a28 100644 --- a/YandexMusic.API/Models/Feed/YHeadline.cs +++ b/YandexMusic.API/Models/Feed/YHeadline.cs @@ -1,9 +1,8 @@ -namespace YandexMusic.API.Models.Feed +namespace YandexMusic.API.Models.Feed; + +public class YHeadline { - public class YHeadline - { - public string Id { get; set; } - public string Message { get; set; } - public YHeadlineType Type { get; set; } - } + public string Id { get; set; } + public string Message { get; set; } + public YHeadlineType Type { get; set; } } \ No newline at end of file diff --git a/YandexMusic.API/Models/Feed/YHeadlineType.cs b/YandexMusic.API/Models/Feed/YHeadlineType.cs index 0c03b00..a375534 100644 --- a/YandexMusic.API/Models/Feed/YHeadlineType.cs +++ b/YandexMusic.API/Models/Feed/YHeadlineType.cs @@ -1,7 +1,6 @@ -namespace YandexMusic.API.Models.Feed +namespace YandexMusic.API.Models.Feed; + +public enum YHeadlineType { - public enum YHeadlineType - { - Notification - } + Notification } \ No newline at end of file diff --git a/YandexMusic.API/Models/Label/YLabelAlbums.cs b/YandexMusic.API/Models/Label/YLabelAlbums.cs index 00aec45..7699d59 100644 --- a/YandexMusic.API/Models/Label/YLabelAlbums.cs +++ b/YandexMusic.API/Models/Label/YLabelAlbums.cs @@ -1,11 +1,10 @@ using YandexMusic.API.Models.Album; using YandexMusic.API.Models.Common; -namespace YandexMusic.API.Models.Label +namespace YandexMusic.API.Models.Label; + +public class YLabelAlbums { - public class YLabelAlbums - { - public YPager Pager { get; set; } - public List Albums { get; set; } - } + public YPager Pager { get; set; } + public List Albums { get; set; } } \ No newline at end of file diff --git a/YandexMusic.API/Models/Label/YLabelArtists.cs b/YandexMusic.API/Models/Label/YLabelArtists.cs index b6f958f..bb2ceac 100644 --- a/YandexMusic.API/Models/Label/YLabelArtists.cs +++ b/YandexMusic.API/Models/Label/YLabelArtists.cs @@ -1,11 +1,10 @@ using YandexMusic.API.Models.Artist; using YandexMusic.API.Models.Common; -namespace YandexMusic.API.Models.Label +namespace YandexMusic.API.Models.Label; + +public class YLabelArtists { - public class YLabelArtists - { - public YPager Pager { get; set; } - public List Artists { get; set; } - } + public YPager Pager { get; set; } + public List Artists { get; set; } } \ No newline at end of file diff --git a/YandexMusic.API/Models/Landing/Entity/Entities/Context/YPlayContext.cs b/YandexMusic.API/Models/Landing/Entity/Entities/Context/YPlayContext.cs index be31d5a..9e8d0f4 100644 --- a/YandexMusic.API/Models/Landing/Entity/Entities/Context/YPlayContext.cs +++ b/YandexMusic.API/Models/Landing/Entity/Entities/Context/YPlayContext.cs @@ -1,58 +1,8 @@ -namespace YandexMusic.API.Models.Landing.Entity.Entities.Context +namespace YandexMusic.API.Models.Landing.Entity.Entities.Context; + +public class YPlayContext { - public sealed class YPlayContextConverter : JsonConverter - { - public override bool CanConvert(Type objectType) - { - return typeof(YLandingEntity).IsAssignableFrom(objectType); - } - - public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) - { - if (reader.TokenType == JsonToken.Null) - return null; - - JObject jObject = JObject.Load(reader); - - YPlayContext context; - try - { - YPlayContextType type = jObject["context"].ToObject(); - - switch (type) - { - case YPlayContextType.Album: - context = jObject.ToObject(); - break; - case YPlayContextType.Artist: - context = jObject.ToObject(); - break; - case YPlayContextType.Playlist: - context = jObject.ToObject(); - break; - default: - context = jObject.ToObject(); - break; - } - } - catch (Exception ex) - { - throw new Exception($"Ошибка десериализации типа \"{jObject["type"]}\".", ex); - } - - return context; - } - - public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) - { - throw new NotImplementedException(); - } - } - - public class YPlayContext - { - public string Client { get; set; } - public YPlayContextType Context { get; set; } - public string ContextItem { get; set; } - } + public string Client { get; set; } + public YPlayContextType Context { get; set; } + public string ContextItem { get; set; } } \ No newline at end of file diff --git a/YandexMusic.API/Models/Landing/Entity/Entities/Context/YPlayContextAlbum.cs b/YandexMusic.API/Models/Landing/Entity/Entities/Context/YPlayContextAlbum.cs index a0fb1f1..dbc649a 100644 --- a/YandexMusic.API/Models/Landing/Entity/Entities/Context/YPlayContextAlbum.cs +++ b/YandexMusic.API/Models/Landing/Entity/Entities/Context/YPlayContextAlbum.cs @@ -1,9 +1,8 @@ using YandexMusic.API.Models.Album; -namespace YandexMusic.API.Models.Landing.Entity.Entities.Context +namespace YandexMusic.API.Models.Landing.Entity.Entities.Context; + +public class YPlayContextAlbum : YPlayContext { - public class YPlayContextAlbum : YPlayContext - { - public YAlbum Payload { get; set; } - } + public YAlbum Payload { get; set; } } \ No newline at end of file diff --git a/YandexMusic.API/Models/Landing/Entity/Entities/Context/YPlayContextArtist.cs b/YandexMusic.API/Models/Landing/Entity/Entities/Context/YPlayContextArtist.cs index 24657dd..1cba4bc 100644 --- a/YandexMusic.API/Models/Landing/Entity/Entities/Context/YPlayContextArtist.cs +++ b/YandexMusic.API/Models/Landing/Entity/Entities/Context/YPlayContextArtist.cs @@ -1,9 +1,8 @@ using YandexMusic.API.Models.Artist; -namespace YandexMusic.API.Models.Landing.Entity.Entities.Context +namespace YandexMusic.API.Models.Landing.Entity.Entities.Context; + +public class YPlayContextArtist : YPlayContext { - public class YPlayContextArtist : YPlayContext - { - public YArtist Payload { get; set; } - } + public YArtist Payload { get; set; } } \ No newline at end of file diff --git a/YandexMusic.API/Models/Landing/Entity/Entities/Context/YPlayContextConverter.cs b/YandexMusic.API/Models/Landing/Entity/Entities/Context/YPlayContextConverter.cs new file mode 100644 index 0000000..4ddbee6 --- /dev/null +++ b/YandexMusic.API/Models/Landing/Entity/Entities/Context/YPlayContextConverter.cs @@ -0,0 +1,37 @@ +using System.Text.Json; +using System.Text.Json.Serialization; + +namespace YandexMusic.API.Models.Landing.Entity.Entities.Context; + +/// Конвертер для контекста воспроизведения (альбом, исполнитель, плейлист). +public class YPlayContextConverter : JsonConverter +{ + public override YPlayContext? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + { + if (reader.TokenType != JsonTokenType.StartObject) + throw new JsonException("Ожидается объект контекста"); + + using var doc = JsonDocument.ParseValue(ref reader); + var root = doc.RootElement; + + var contextProp = root.GetProperty("context"); + var contextStr = contextProp.GetString(); + if (!Enum.TryParse(contextStr, true, out var contextType)) + throw new JsonException($"Неизвестный тип контекста: {contextStr}"); + + var rawText = root.GetRawText(); + + return contextType switch + { + YPlayContextType.Album => JsonSerializer.Deserialize(rawText, options), + YPlayContextType.Artist => JsonSerializer.Deserialize(rawText, options), + YPlayContextType.Playlist => JsonSerializer.Deserialize(rawText, options), + _ => JsonSerializer.Deserialize(rawText, options) + }; + } + + public override void Write(Utf8JsonWriter writer, YPlayContext value, JsonSerializerOptions options) + { + JsonSerializer.Serialize(writer, value, options); + } +} \ No newline at end of file diff --git a/YandexMusic.API/Models/Landing/Entity/Entities/Context/YPlayContextPlaylist.cs b/YandexMusic.API/Models/Landing/Entity/Entities/Context/YPlayContextPlaylist.cs index 3ae9d26..07f2a0b 100644 --- a/YandexMusic.API/Models/Landing/Entity/Entities/Context/YPlayContextPlaylist.cs +++ b/YandexMusic.API/Models/Landing/Entity/Entities/Context/YPlayContextPlaylist.cs @@ -1,9 +1,8 @@ using YandexMusic.API.Models.Playlist; -namespace YandexMusic.API.Models.Landing.Entity.Entities.Context +namespace YandexMusic.API.Models.Landing.Entity.Entities.Context; + +public class YPlayContextPlaylist : YPlayContext { - public class YPlayContextPlaylist : YPlayContext - { - public YPlaylist Payload { get; set; } - } + public YPlaylist Payload { get; set; } } \ No newline at end of file diff --git a/YandexMusic.API/Models/Landing/Entity/Entities/Context/YPlayContextType.cs b/YandexMusic.API/Models/Landing/Entity/Entities/Context/YPlayContextType.cs index 6b4f332..522359d 100644 --- a/YandexMusic.API/Models/Landing/Entity/Entities/Context/YPlayContextType.cs +++ b/YandexMusic.API/Models/Landing/Entity/Entities/Context/YPlayContextType.cs @@ -1,9 +1,8 @@ -namespace YandexMusic.API.Models.Landing.Entity.Entities.Context +namespace YandexMusic.API.Models.Landing.Entity.Entities.Context; + +public enum YPlayContextType { - public enum YPlayContextType - { - Album, - Artist, - Playlist - } + Album, + Artist, + Playlist, } \ No newline at end of file diff --git a/YandexMusic.API/Models/Landing/Entity/Entities/YAlbumMenuItem.cs b/YandexMusic.API/Models/Landing/Entity/Entities/YAlbumMenuItem.cs index a843ff2..ab8b2d9 100644 --- a/YandexMusic.API/Models/Landing/Entity/Entities/YAlbumMenuItem.cs +++ b/YandexMusic.API/Models/Landing/Entity/Entities/YAlbumMenuItem.cs @@ -1,7 +1,6 @@ -namespace YandexMusic.API.Models.Landing.Entity.Entities +namespace YandexMusic.API.Models.Landing.Entity.Entities; + +public class YAlbumMenuItem : YBlockEntity { - public class YAlbumMenuItem : YBlockEntity - { - public string Title { get; set; } - } + public string Title { get; set; } } \ No newline at end of file diff --git a/YandexMusic.API/Models/Landing/Entity/Entities/YBlockEntity.cs b/YandexMusic.API/Models/Landing/Entity/Entities/YBlockEntity.cs index 9d9ee4c..efeaf56 100644 --- a/YandexMusic.API/Models/Landing/Entity/Entities/YBlockEntity.cs +++ b/YandexMusic.API/Models/Landing/Entity/Entities/YBlockEntity.cs @@ -1,7 +1,6 @@ -namespace YandexMusic.API.Models.Landing.Entity.Entities +namespace YandexMusic.API.Models.Landing.Entity.Entities; + +public class YBlockEntity { - public class YBlockEntity - { - public string BlockEntityDataId { get; set; } - } + public string BlockEntityDataId { get; set; } } \ No newline at end of file diff --git a/YandexMusic.API/Models/Landing/Entity/Entities/YCategory.cs b/YandexMusic.API/Models/Landing/Entity/Entities/YCategory.cs index e1ac974..0f111ef 100644 --- a/YandexMusic.API/Models/Landing/Entity/Entities/YCategory.cs +++ b/YandexMusic.API/Models/Landing/Entity/Entities/YCategory.cs @@ -1,16 +1,15 @@ -namespace YandexMusic.API.Models.Landing.Entity.Entities -{ - public class YCategory : YBlockEntity - { - public string BackgroundImageUri { get; set; } - public string CategoryId { get; set; } - public bool HasBackgroundImageText { get; set; } - public string Url { get; set; } - public string UrlScheme { get; set; } - public string VoiceTitle { get; set; } - public string TextColor { get; set; } - public string TextBackgroundColor { get; set; } - public string Title { get; set; } +namespace YandexMusic.API.Models.Landing.Entity.Entities; + +public class YCategory : YBlockEntity +{ + public string BackgroundImageUri { get; set; } + public string CategoryId { get; set; } + public bool HasBackgroundImageText { get; set; } + public string Url { get; set; } + public string UrlScheme { get; set; } + public string VoiceTitle { get; set; } + public string TextColor { get; set; } + public string TextBackgroundColor { get; set; } + public string Title { get; set; } - } } \ No newline at end of file diff --git a/YandexMusic.API/Models/Landing/Entity/Entities/YChartItem.cs b/YandexMusic.API/Models/Landing/Entity/Entities/YChartItem.cs index 0ed85d0..26ce1dc 100644 --- a/YandexMusic.API/Models/Landing/Entity/Entities/YChartItem.cs +++ b/YandexMusic.API/Models/Landing/Entity/Entities/YChartItem.cs @@ -1,11 +1,10 @@ using YandexMusic.API.Models.Common; using YandexMusic.API.Models.Track; -namespace YandexMusic.API.Models.Landing.Entity.Entities +namespace YandexMusic.API.Models.Landing.Entity.Entities; + +public class YChartItem { - public class YChartItem - { - public YTrack Track { get; set; } - public YChart Chart { get; set; } - } + public YTrack Track { get; set; } + public YChart Chart { get; set; } } \ No newline at end of file diff --git a/YandexMusic.API/Models/Landing/Entity/Entities/YChartProgress.cs b/YandexMusic.API/Models/Landing/Entity/Entities/YChartProgress.cs index f5c768d..0092e47 100644 --- a/YandexMusic.API/Models/Landing/Entity/Entities/YChartProgress.cs +++ b/YandexMusic.API/Models/Landing/Entity/Entities/YChartProgress.cs @@ -1,10 +1,9 @@ -namespace YandexMusic.API.Models.Landing.Entity.Entities +namespace YandexMusic.API.Models.Landing.Entity.Entities; + +public enum YChartProgress { - public enum YChartProgress - { - New, - Up, - Down, - Same - } + New, + Up, + Down, + Same, } \ No newline at end of file diff --git a/YandexMusic.API/Models/Landing/Entity/Entities/YClientWidget.cs b/YandexMusic.API/Models/Landing/Entity/Entities/YClientWidget.cs index c5b5fc4..4940aca 100644 --- a/YandexMusic.API/Models/Landing/Entity/Entities/YClientWidget.cs +++ b/YandexMusic.API/Models/Landing/Entity/Entities/YClientWidget.cs @@ -1,11 +1,10 @@ -namespace YandexMusic.API.Models.Landing.Entity.Entities +namespace YandexMusic.API.Models.Landing.Entity.Entities; + +public class YClientWidget : YBlockEntity { - public class YClientWidget : YBlockEntity - { - public string ImagePath { get; set; } - public string Subtitle { get; set; } - public string Text { get; set; } - public string Title { get; set; } - public string Type { get; set; } - } + public string ImagePath { get; set; } + public string Subtitle { get; set; } + public string Text { get; set; } + public string Title { get; set; } + public string Type { get; set; } } \ No newline at end of file diff --git a/YandexMusic.API/Models/Landing/Entity/Entities/YLandingEntityAlbum.cs b/YandexMusic.API/Models/Landing/Entity/Entities/YLandingEntityAlbum.cs index bcc970b..7b75b7b 100644 --- a/YandexMusic.API/Models/Landing/Entity/Entities/YLandingEntityAlbum.cs +++ b/YandexMusic.API/Models/Landing/Entity/Entities/YLandingEntityAlbum.cs @@ -1,9 +1,8 @@ using YandexMusic.API.Models.Album; -namespace YandexMusic.API.Models.Landing.Entity.Entities +namespace YandexMusic.API.Models.Landing.Entity.Entities; + +public class YLandingEntityAlbum : YLandingEntity { - public class YLandingEntityAlbum : YLandingEntity - { - public YAlbum Data { get; set; } - } + public YAlbum Data { get; set; } } \ No newline at end of file diff --git a/YandexMusic.API/Models/Landing/Entity/Entities/YLandingEntityAlbumMenuItem.cs b/YandexMusic.API/Models/Landing/Entity/Entities/YLandingEntityAlbumMenuItem.cs index 741da5d..c2cf0d6 100644 --- a/YandexMusic.API/Models/Landing/Entity/Entities/YLandingEntityAlbumMenuItem.cs +++ b/YandexMusic.API/Models/Landing/Entity/Entities/YLandingEntityAlbumMenuItem.cs @@ -1,7 +1,6 @@ -namespace YandexMusic.API.Models.Landing.Entity.Entities +namespace YandexMusic.API.Models.Landing.Entity.Entities; + +public class YLandingEntityAlbumMenuItem : YLandingEntity { - public class YLandingEntityAlbumMenuItem : YLandingEntity - { - public YAlbumMenuItem Data { get; set; } - } + public YAlbumMenuItem Data { get; set; } } \ No newline at end of file diff --git a/YandexMusic.API/Models/Landing/Entity/Entities/YLandingEntityCategory.cs b/YandexMusic.API/Models/Landing/Entity/Entities/YLandingEntityCategory.cs index 8d0752f..15c0b47 100644 --- a/YandexMusic.API/Models/Landing/Entity/Entities/YLandingEntityCategory.cs +++ b/YandexMusic.API/Models/Landing/Entity/Entities/YLandingEntityCategory.cs @@ -1,7 +1,6 @@ -namespace YandexMusic.API.Models.Landing.Entity.Entities +namespace YandexMusic.API.Models.Landing.Entity.Entities; + +public class YLandingEntityCategory : YLandingEntity { - public class YLandingEntityCategory : YLandingEntity - { - public YCategory Data { get; set; } - } + public YCategory Data { get; set; } } \ No newline at end of file diff --git a/YandexMusic.API/Models/Landing/Entity/Entities/YLandingEntityChart.cs b/YandexMusic.API/Models/Landing/Entity/Entities/YLandingEntityChart.cs index ff31d7e..9b7b576 100644 --- a/YandexMusic.API/Models/Landing/Entity/Entities/YLandingEntityChart.cs +++ b/YandexMusic.API/Models/Landing/Entity/Entities/YLandingEntityChart.cs @@ -1,7 +1,6 @@ -namespace YandexMusic.API.Models.Landing.Entity.Entities +namespace YandexMusic.API.Models.Landing.Entity.Entities; + +public class YLandingEntityChart : YLandingEntity { - public class YLandingEntityChart : YLandingEntity - { - public YChartItem Data { get; set; } - } + public YChartItem Data { get; set; } } \ No newline at end of file diff --git a/YandexMusic.API/Models/Landing/Entity/Entities/YLandingEntityClientWidget.cs b/YandexMusic.API/Models/Landing/Entity/Entities/YLandingEntityClientWidget.cs index a9491b9..681aea9 100644 --- a/YandexMusic.API/Models/Landing/Entity/Entities/YLandingEntityClientWidget.cs +++ b/YandexMusic.API/Models/Landing/Entity/Entities/YLandingEntityClientWidget.cs @@ -1,7 +1,6 @@ -namespace YandexMusic.API.Models.Landing.Entity.Entities +namespace YandexMusic.API.Models.Landing.Entity.Entities; + +public class YLandingEntityClientWidget : YLandingEntity { - public class YLandingEntityClientWidget : YLandingEntity - { - public YClientWidget Data { get; set; } - } + public YClientWidget Data { get; set; } } \ No newline at end of file diff --git a/YandexMusic.API/Models/Landing/Entity/Entities/YLandingEntityPersonalPlaylist.cs b/YandexMusic.API/Models/Landing/Entity/Entities/YLandingEntityPersonalPlaylist.cs index 2b6aed2..dcd5771 100644 --- a/YandexMusic.API/Models/Landing/Entity/Entities/YLandingEntityPersonalPlaylist.cs +++ b/YandexMusic.API/Models/Landing/Entity/Entities/YLandingEntityPersonalPlaylist.cs @@ -1,7 +1,6 @@ -namespace YandexMusic.API.Models.Landing.Entity.Entities +namespace YandexMusic.API.Models.Landing.Entity.Entities; + +public class YLandingEntityPersonalPlaylist : YLandingEntity { - public class YLandingEntityPersonalPlaylist : YLandingEntity - { - public YPersonalPlaylist Data { get; set; } - } + public YPersonalPlaylist Data { get; set; } } \ No newline at end of file diff --git a/YandexMusic.API/Models/Landing/Entity/Entities/YLandingEntityPlayContext.cs b/YandexMusic.API/Models/Landing/Entity/Entities/YLandingEntityPlayContext.cs index c2db5dd..cb8a884 100644 --- a/YandexMusic.API/Models/Landing/Entity/Entities/YLandingEntityPlayContext.cs +++ b/YandexMusic.API/Models/Landing/Entity/Entities/YLandingEntityPlayContext.cs @@ -1,10 +1,10 @@ -using YandexMusic.API.Models.Landing.Entity.Entities.Context; +using System.Text.Json.Serialization; +using YandexMusic.API.Models.Landing.Entity.Entities.Context; -namespace YandexMusic.API.Models.Landing.Entity.Entities +namespace YandexMusic.API.Models.Landing.Entity.Entities; + +public class YLandingEntityPlayContext : YLandingEntity { - public class YLandingEntityPlayContext : YLandingEntity - { - [JsonConverter(typeof(YPlayContextConverter))] - public YPlayContext Data { get; set; } - } + [JsonConverter(typeof(YPlayContextConverter))] + public YPlayContext Data { get; set; } } \ No newline at end of file diff --git a/YandexMusic.API/Models/Landing/Entity/Entities/YLandingEntityPlaylist.cs b/YandexMusic.API/Models/Landing/Entity/Entities/YLandingEntityPlaylist.cs index 9e7cc81..aedef7a 100644 --- a/YandexMusic.API/Models/Landing/Entity/Entities/YLandingEntityPlaylist.cs +++ b/YandexMusic.API/Models/Landing/Entity/Entities/YLandingEntityPlaylist.cs @@ -1,9 +1,8 @@ using YandexMusic.API.Models.Playlist; -namespace YandexMusic.API.Models.Landing.Entity.Entities +namespace YandexMusic.API.Models.Landing.Entity.Entities; + +public class YLandingEntityPlaylist : YLandingEntity { - public class YLandingEntityPlaylist : YLandingEntity - { - public YPlaylist Data { get; set; } - } + public YPlaylist Data { get; set; } } \ No newline at end of file diff --git a/YandexMusic.API/Models/Landing/Entity/Entities/YLandingEntityPodcast.cs b/YandexMusic.API/Models/Landing/Entity/Entities/YLandingEntityPodcast.cs index 6573655..105a224 100644 --- a/YandexMusic.API/Models/Landing/Entity/Entities/YLandingEntityPodcast.cs +++ b/YandexMusic.API/Models/Landing/Entity/Entities/YLandingEntityPodcast.cs @@ -1,10 +1,9 @@ -namespace YandexMusic.API.Models.Landing.Entity.Entities +namespace YandexMusic.API.Models.Landing.Entity.Entities; + +public class YLandingEntityPodcast : YLandingEntity { - public class YLandingEntityPodcast : YLandingEntity - { - public string Description { get; set; } - public string DescriptionFormatted { get; set; } - public DateTime LastUpdated { get; set; } - public YPodcast Data { get; set; } - } + public string Description { get; set; } + public string DescriptionFormatted { get; set; } + public DateTime LastUpdated { get; set; } + public YPodcast Data { get; set; } } \ No newline at end of file diff --git a/YandexMusic.API/Models/Landing/Entity/Entities/YLandingEntityPromotion.cs b/YandexMusic.API/Models/Landing/Entity/Entities/YLandingEntityPromotion.cs index 984b634..4b4d24d 100644 --- a/YandexMusic.API/Models/Landing/Entity/Entities/YLandingEntityPromotion.cs +++ b/YandexMusic.API/Models/Landing/Entity/Entities/YLandingEntityPromotion.cs @@ -1,7 +1,6 @@ -namespace YandexMusic.API.Models.Landing.Entity.Entities +namespace YandexMusic.API.Models.Landing.Entity.Entities; + +public class YLandingEntityPromotion : YLandingEntity { - public class YLandingEntityPromotion : YLandingEntity - { - public YPromotion Data { get; set; } - } + public YPromotion Data { get; set; } } \ No newline at end of file diff --git a/YandexMusic.API/Models/Landing/Entity/Entities/YLandingEntityStation.cs b/YandexMusic.API/Models/Landing/Entity/Entities/YLandingEntityStation.cs index 399d3cd..588431a 100644 --- a/YandexMusic.API/Models/Landing/Entity/Entities/YLandingEntityStation.cs +++ b/YandexMusic.API/Models/Landing/Entity/Entities/YLandingEntityStation.cs @@ -1,7 +1,6 @@ -namespace YandexMusic.API.Models.Landing.Entity.Entities +namespace YandexMusic.API.Models.Landing.Entity.Entities; + +public class YLandingEntityStation : YLandingEntity { - public class YLandingEntityStation : YLandingEntity - { - public YCategory Data { get; set; } - } + public YCategory Data { get; set; } } \ No newline at end of file diff --git a/YandexMusic.API/Models/Landing/Entity/Entities/YLandingStation.cs b/YandexMusic.API/Models/Landing/Entity/Entities/YLandingStation.cs index 6ac03bf..147e524 100644 --- a/YandexMusic.API/Models/Landing/Entity/Entities/YLandingStation.cs +++ b/YandexMusic.API/Models/Landing/Entity/Entities/YLandingStation.cs @@ -1,10 +1,9 @@ using YandexMusic.API.Models.Radio; -namespace YandexMusic.API.Models.Landing.Entity.Entities +namespace YandexMusic.API.Models.Landing.Entity.Entities; + +public class YLandingStation { - public class YLandingStation - { - public YStationId Id { get; set; } - public YStationDescription Data { get; set; } - } + public YStationId Id { get; set; } + public YStationDescription Data { get; set; } } \ No newline at end of file diff --git a/YandexMusic.API/Models/Landing/Entity/Entities/YPersonalPlaylist.cs b/YandexMusic.API/Models/Landing/Entity/Entities/YPersonalPlaylist.cs index fd28fe8..85a8db8 100644 --- a/YandexMusic.API/Models/Landing/Entity/Entities/YPersonalPlaylist.cs +++ b/YandexMusic.API/Models/Landing/Entity/Entities/YPersonalPlaylist.cs @@ -1,14 +1,13 @@ using YandexMusic.API.Models.Playlist; -namespace YandexMusic.API.Models.Landing.Entity.Entities +namespace YandexMusic.API.Models.Landing.Entity.Entities; + +public class YPersonalPlaylist { - public class YPersonalPlaylist - { - public YPlaylist Data { get; set; } - public List Description { get; set; } - public bool Notify { get; set; } - public string PreviewDescription { get; set; } - public bool Ready { get; set; } - public string Type { get; set; } - } + public YPlaylist Data { get; set; } + public List Description { get; set; } + public bool Notify { get; set; } + public string PreviewDescription { get; set; } + public bool Ready { get; set; } + public string Type { get; set; } } \ No newline at end of file diff --git a/YandexMusic.API/Models/Landing/Entity/Entities/YPodcast.cs b/YandexMusic.API/Models/Landing/Entity/Entities/YPodcast.cs index eb703fc..b92b518 100644 --- a/YandexMusic.API/Models/Landing/Entity/Entities/YPodcast.cs +++ b/YandexMusic.API/Models/Landing/Entity/Entities/YPodcast.cs @@ -1,12 +1,11 @@ using YandexMusic.API.Models.Album; -namespace YandexMusic.API.Models.Landing.Entity.Entities +namespace YandexMusic.API.Models.Landing.Entity.Entities; + +public class YPodcast { - public class YPodcast - { - public string Description { get; set; } - public string DescriptionFormatted { get; set; } - public DateTime LastUpdated { get; set; } - public YAlbum Podcast { get; set; } - } + public string Description { get; set; } + public string DescriptionFormatted { get; set; } + public DateTime LastUpdated { get; set; } + public YAlbum Podcast { get; set; } } \ No newline at end of file diff --git a/YandexMusic.API/Models/Landing/Entity/Entities/YPromotion.cs b/YandexMusic.API/Models/Landing/Entity/Entities/YPromotion.cs index 974e2d0..3eb88ab 100644 --- a/YandexMusic.API/Models/Landing/Entity/Entities/YPromotion.cs +++ b/YandexMusic.API/Models/Landing/Entity/Entities/YPromotion.cs @@ -1,15 +1,14 @@ -namespace YandexMusic.API.Models.Landing.Entity.Entities +namespace YandexMusic.API.Models.Landing.Entity.Entities; + +public class YPromotion { - public class YPromotion - { - public string PromoId { get; set; } - public string Title { get; set; } - public string Subtitle { get; set; } - public string Heading { get; set; } - public string UrlScheme { get; set; } - public string Url { get; set; } - public string TextColor { get; set; } - public string Gradient { get; set; } - public string Image { get; set; } - } + public string PromoId { get; set; } + public string Title { get; set; } + public string Subtitle { get; set; } + public string Heading { get; set; } + public string UrlScheme { get; set; } + public string Url { get; set; } + public string TextColor { get; set; } + public string Gradient { get; set; } + public string Image { get; set; } } \ No newline at end of file diff --git a/YandexMusic.API/Models/Landing/Entity/YLandingEntity.cs b/YandexMusic.API/Models/Landing/Entity/YLandingEntity.cs index f3caa16..30abfb5 100644 --- a/YandexMusic.API/Models/Landing/Entity/YLandingEntity.cs +++ b/YandexMusic.API/Models/Landing/Entity/YLandingEntity.cs @@ -1,90 +1,7 @@ -using YandexMusic.API.Models.Landing.Entity.Entities; +namespace YandexMusic.API.Models.Landing.Entity; -namespace YandexMusic.API.Models.Landing.Entity +public abstract class YLandingEntity { - public sealed class YLandingEntityConverter : JsonConverter - { - private YLandingEntity GetEntity(JToken jObject) - { - YLandingEntity entity; - - try - { - YLandingEntityType type = jObject["type"].ToObject(); - - switch (type) - { - case YLandingEntityType.Album: - entity = jObject.ToObject(); - break; - case YLandingEntityType.ChartItem: - entity = jObject.ToObject(); - break; - case YLandingEntityType.PersonalPlaylist: - entity = jObject.ToObject(); - break; - case YLandingEntityType.PlayContext: - entity = jObject.ToObject(); - break; - case YLandingEntityType.Playlist: - entity = jObject.ToObject(); - break; - case YLandingEntityType.Podcast: - entity = jObject.ToObject(); - break; - case YLandingEntityType.Promotion: - entity = jObject.ToObject(); - break; - case YLandingEntityType.Category: - entity = jObject.ToObject(); - break; - case YLandingEntityType.Station: - entity = jObject.ToObject(); - break; - case YLandingEntityType.MenuItemAlbum: - case YLandingEntityType.MenuItemPlaylist: - entity = jObject.ToObject(); - break; - case YLandingEntityType.ClientWidget: - entity = jObject.ToObject(); - break; - default: - entity = jObject.ToObject(); - break; - } - } - catch (Exception ex) - { - throw new Exception($"Ошибка десериализации типа \"{jObject["type"]}\".", ex); - } - - return entity; - } - - public override bool CanConvert(Type objectType) - { - return typeof(YLandingEntity).IsAssignableFrom(objectType); - } - - public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) - { - if (reader.TokenType == JsonToken.Null) - return null; - - return JArray.Load(reader) - .Select(GetEntity) - .ToList(); - } - - public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) - { - throw new NotImplementedException(); - } - } - - public abstract class YLandingEntity - { - public string Id { get; set; } - public YLandingEntityType Type { get; set; } - } + public string Id { get; set; } + public YLandingEntityType Type { get; set; } } \ No newline at end of file diff --git a/YandexMusic.API/Models/Landing/Entity/YLandingEntityConverter.cs b/YandexMusic.API/Models/Landing/Entity/YLandingEntityConverter.cs new file mode 100644 index 0000000..2f1e0e1 --- /dev/null +++ b/YandexMusic.API/Models/Landing/Entity/YLandingEntityConverter.cs @@ -0,0 +1,86 @@ +using System.Text.Json; +using System.Text.Json.Serialization; +using YandexMusic.API.Models.Landing.Entity.Entities; + +namespace YandexMusic.API.Models.Landing.Entity; + +/// Конвертер для сущностей лендинга (десериализация в конкретные типы на основе поля type). +public class YLandingEntityConverter : JsonConverter> +{ + public override List Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + { + if (reader.TokenType != JsonTokenType.StartArray) + throw new JsonException("Ожидается массив сущностей"); + + var entities = new List(); + while (reader.Read()) + { + if (reader.TokenType == JsonTokenType.EndArray) + break; + + if (reader.TokenType != JsonTokenType.StartObject) + throw new JsonException("Ожидается объект сущности"); + + using var doc = JsonDocument.ParseValue(ref reader); + var root = doc.RootElement; + + var typeProp = root.GetProperty("type"); + var typeStr = typeProp.GetString(); + if (!Enum.TryParse(typeStr, true, out var entityType)) + throw new JsonException($"Неизвестный тип сущности: {typeStr}"); + + YLandingEntity? entity = null; + var rawText = root.GetRawText(); + + switch (entityType) + { + case YLandingEntityType.Album: + entity = JsonSerializer.Deserialize(rawText, options); + break; + case YLandingEntityType.ChartItem: + entity = JsonSerializer.Deserialize(rawText, options); + break; + case YLandingEntityType.PersonalPlaylist: + entity = JsonSerializer.Deserialize(rawText, options); + break; + case YLandingEntityType.PlayContext: + entity = JsonSerializer.Deserialize(rawText, options); + break; + case YLandingEntityType.Playlist: + entity = JsonSerializer.Deserialize(rawText, options); + break; + case YLandingEntityType.Podcast: + entity = JsonSerializer.Deserialize(rawText, options); + break; + case YLandingEntityType.Promotion: + entity = JsonSerializer.Deserialize(rawText, options); + break; + case YLandingEntityType.Category: + entity = JsonSerializer.Deserialize(rawText, options); + break; + case YLandingEntityType.Station: + entity = JsonSerializer.Deserialize(rawText, options); + break; + case YLandingEntityType.MenuItemAlbum: + case YLandingEntityType.MenuItemPlaylist: + entity = JsonSerializer.Deserialize(rawText, options); + break; + case YLandingEntityType.ClientWidget: + entity = JsonSerializer.Deserialize(rawText, options); + break; + default: + entity = JsonSerializer.Deserialize(rawText, options); + break; + } + + if (entity != null) + entities.Add(entity); + } + return entities; + } + + public override void Write(Utf8JsonWriter writer, List value, JsonSerializerOptions options) + { + JsonSerializer.Serialize(writer, value, options); + } +} diff --git a/YandexMusic.API/Models/Landing/Entity/YLandingEntityType.cs b/YandexMusic.API/Models/Landing/Entity/YLandingEntityType.cs index 2aee6bf..a31c005 100644 --- a/YandexMusic.API/Models/Landing/Entity/YLandingEntityType.cs +++ b/YandexMusic.API/Models/Landing/Entity/YLandingEntityType.cs @@ -1,26 +1,25 @@ using System.Runtime.Serialization; -namespace YandexMusic.API.Models.Landing.Entity +namespace YandexMusic.API.Models.Landing.Entity; + +public enum YLandingEntityType { - public enum YLandingEntityType - { - Album, - [EnumMember(Value = "chart-item")] - ChartItem, - [EnumMember(Value = "personal-playlist")] - PersonalPlaylist, - [EnumMember(Value = "play-context")] - PlayContext, - Playlist, - Podcast, - Promotion, - Category, - Station, - [EnumMember(Value = "menu-item-album")] - MenuItemAlbum, - [EnumMember(Value = "menu-item-playlist")] - MenuItemPlaylist, - [EnumMember(Value = "client-widget")] - ClientWidget - } + Album, + [EnumMember(Value = "chart-item")] + ChartItem, + [EnumMember(Value = "personal-playlist")] + PersonalPlaylist, + [EnumMember(Value = "play-context")] + PlayContext, + Playlist, + Podcast, + Promotion, + Category, + Station, + [EnumMember(Value = "menu-item-album")] + MenuItemAlbum, + [EnumMember(Value = "menu-item-playlist")] + MenuItemPlaylist, + [EnumMember(Value = "client-widget")] + ClientWidget, } \ No newline at end of file diff --git a/YandexMusic.API/Models/Landing/YChildrenLanding.cs b/YandexMusic.API/Models/Landing/YChildrenLanding.cs index 7db7269..490134c 100644 --- a/YandexMusic.API/Models/Landing/YChildrenLanding.cs +++ b/YandexMusic.API/Models/Landing/YChildrenLanding.cs @@ -1,9 +1,8 @@ -namespace YandexMusic.API.Models.Landing +namespace YandexMusic.API.Models.Landing; + +public class YChildrenLanding { - public class YChildrenLanding - { - public string Title { get; set; } - public bool RupEnabled { get; set; } - public List Blocks { get; set; } - } + public string Title { get; set; } + public bool RupEnabled { get; set; } + public List Blocks { get; set; } } \ No newline at end of file diff --git a/YandexMusic.API/Models/Landing/YLanding.cs b/YandexMusic.API/Models/Landing/YLanding.cs index 2bce23d..ddc5dff 100644 --- a/YandexMusic.API/Models/Landing/YLanding.cs +++ b/YandexMusic.API/Models/Landing/YLanding.cs @@ -1,10 +1,9 @@ -namespace YandexMusic.API.Models.Landing +namespace YandexMusic.API.Models.Landing; + +public class YLanding { - public class YLanding - { - public List Blocks { get; set; } - public string ContentId { get; set; } - public YLandingHeaderSpecialBlock HeaderSpecialBlock { get; set; } - public bool Pumpkin { get; set; } - } + public List Blocks { get; set; } + public string ContentId { get; set; } + public YLandingHeaderSpecialBlock HeaderSpecialBlock { get; set; } + public bool Pumpkin { get; set; } } \ No newline at end of file diff --git a/YandexMusic.API/Models/Landing/YLandingBlock.cs b/YandexMusic.API/Models/Landing/YLandingBlock.cs index 03c3cd5..a7c0a8d 100644 --- a/YandexMusic.API/Models/Landing/YLandingBlock.cs +++ b/YandexMusic.API/Models/Landing/YLandingBlock.cs @@ -1,21 +1,21 @@ +using System.Text.Json.Serialization; using YandexMusic.API.Models.Landing.Entity; -namespace YandexMusic.API.Models.Landing +namespace YandexMusic.API.Models.Landing; + +public class YLandingBlock { - public class YLandingBlock - { - public string Id { get; set; } - public string BackgroundImageUrl { get; set; } - public string BackgroundVideoUrl { get; set; } - public YLandingBlockData Data { get; set; } - public string Description { get; set; } - [JsonConverter(typeof(YLandingEntityConverter))] - public List Entities { get; set; } - public YLandingBlockPlayContext PlayContext { get; set; } - public string ViewAllUrl { get; set; } - public string viewAllUrlScheme { get; set; } - public string Title { get; set; } - public YLandingBlockType Type { get; set; } - public string TypeForFrom { get; set; } - } + public string Id { get; set; } + public string BackgroundImageUrl { get; set; } + public string BackgroundVideoUrl { get; set; } + public YLandingBlockData Data { get; set; } + public string Description { get; set; } + [JsonConverter(typeof(YLandingEntityConverter))] + public List Entities { get; set; } + public YLandingBlockPlayContext PlayContext { get; set; } + public string ViewAllUrl { get; set; } + public string viewAllUrlScheme { get; set; } + public string Title { get; set; } + public YLandingBlockType Type { get; set; } + public string TypeForFrom { get; set; } } \ No newline at end of file diff --git a/YandexMusic.API/Models/Landing/YLandingBlockData.cs b/YandexMusic.API/Models/Landing/YLandingBlockData.cs index b70521f..a13e836 100644 --- a/YandexMusic.API/Models/Landing/YLandingBlockData.cs +++ b/YandexMusic.API/Models/Landing/YLandingBlockData.cs @@ -1,7 +1,6 @@ -namespace YandexMusic.API.Models.Landing +namespace YandexMusic.API.Models.Landing; + +public class YLandingBlockData { - public class YLandingBlockData - { - public bool IsWizardPassed { get; set; } - } + public bool IsWizardPassed { get; set; } } \ No newline at end of file diff --git a/YandexMusic.API/Models/Landing/YLandingBlockType.cs b/YandexMusic.API/Models/Landing/YLandingBlockType.cs index e91df59..5ce7cf5 100644 --- a/YandexMusic.API/Models/Landing/YLandingBlockType.cs +++ b/YandexMusic.API/Models/Landing/YLandingBlockType.cs @@ -1,29 +1,28 @@ using System.Runtime.Serialization; -namespace YandexMusic.API.Models.Landing +namespace YandexMusic.API.Models.Landing; + +public enum YLandingBlockType { - public enum YLandingBlockType - { - Chart, - [EnumMember(Value = "client-widget")] - ClientWidget, - [EnumMember(Value = "categories-tab")] - CategoriesTab, - [EnumMember(Value = "editorial-playlists")] - EditorialPlaylists, - Menu, - Mixes, - [EnumMember(Value = "new-releases")] - NewReleases, - [EnumMember(Value = "new-playlists")] - NewPlaylists, - [EnumMember(Value = "personal-playlists")] - PersonalPlaylists, - [EnumMember(Value = "play-contexts")] - PlayContexts, - Playlists, - Podcasts, - Promotions, - Radio - } + Chart, + [EnumMember(Value = "client-widget")] + ClientWidget, + [EnumMember(Value = "categories-tab")] + CategoriesTab, + [EnumMember(Value = "editorial-playlists")] + EditorialPlaylists, + Menu, + Mixes, + [EnumMember(Value = "new-releases")] + NewReleases, + [EnumMember(Value = "new-playlists")] + NewPlaylists, + [EnumMember(Value = "personal-playlists")] + PersonalPlaylists, + [EnumMember(Value = "play-contexts")] + PlayContexts, + Playlists, + Podcasts, + Promotions, + Radio, } \ No newline at end of file diff --git a/YandexMusic.API/Models/Landing/YLandingHeaderButton.cs b/YandexMusic.API/Models/Landing/YLandingHeaderButton.cs index ff3f468..3b7e3f7 100644 --- a/YandexMusic.API/Models/Landing/YLandingHeaderButton.cs +++ b/YandexMusic.API/Models/Landing/YLandingHeaderButton.cs @@ -1,8 +1,7 @@ -namespace YandexMusic.API.Models.Landing +namespace YandexMusic.API.Models.Landing; + +public class YLandingHeaderButton { - public class YLandingHeaderButton - { - public string Deeplink { get; set; } - public string Title { get; set; } - } + public string Deeplink { get; set; } + public string Title { get; set; } } \ No newline at end of file diff --git a/YandexMusic.API/Models/Landing/YLandingHeaderSpecialBlock.cs b/YandexMusic.API/Models/Landing/YLandingHeaderSpecialBlock.cs index fe1a204..3610993 100644 --- a/YandexMusic.API/Models/Landing/YLandingHeaderSpecialBlock.cs +++ b/YandexMusic.API/Models/Landing/YLandingHeaderSpecialBlock.cs @@ -1,13 +1,12 @@ -namespace YandexMusic.API.Models.Landing +namespace YandexMusic.API.Models.Landing; + +public class YLandingHeaderSpecialBlock { - public class YLandingHeaderSpecialBlock - { - public string AnimationUrl { get; set; } - public string BgImageUrl { get; set; } - public YLandingHeaderButton Button { get; set; } - public string DoodleImageUrl { get; set; } - public string EndGradientColor { get; set; } - public string StartGradientColor { get; set; } - public string Title { get; set; } - } + public string AnimationUrl { get; set; } + public string BgImageUrl { get; set; } + public YLandingHeaderButton Button { get; set; } + public string DoodleImageUrl { get; set; } + public string EndGradientColor { get; set; } + public string StartGradientColor { get; set; } + public string Title { get; set; } } \ No newline at end of file diff --git a/YandexMusic.API/Models/Landing/YLandingPlayContext.cs b/YandexMusic.API/Models/Landing/YLandingPlayContext.cs index 8e2c983..c57276c 100644 --- a/YandexMusic.API/Models/Landing/YLandingPlayContext.cs +++ b/YandexMusic.API/Models/Landing/YLandingPlayContext.cs @@ -1,9 +1,8 @@ -namespace YandexMusic.API.Models.Landing +namespace YandexMusic.API.Models.Landing; + +public class YLandingBlockPlayContext { - public class YLandingBlockPlayContext - { - public string Uid { get; set; } - public string Kind { get; set; } - public string PlaylistUuid { get; set; } - } + public string Uid { get; set; } + public string Kind { get; set; } + public string PlaylistUuid { get; set; } } \ No newline at end of file diff --git a/YandexMusic.API/Models/Library/YLibrary.cs b/YandexMusic.API/Models/Library/YLibrary.cs index c70b05c..91f56c6 100644 --- a/YandexMusic.API/Models/Library/YLibrary.cs +++ b/YandexMusic.API/Models/Library/YLibrary.cs @@ -1,10 +1,9 @@ -namespace YandexMusic.API.Models.Library +namespace YandexMusic.API.Models.Library; + +public class YLibrary { - public class YLibrary - { - public string PlaylistUuid { get; set; } - public int Revision { get; set; } - public List Tracks { get; set; } - public string Uid { get; set; } - } + public string PlaylistUuid { get; set; } + public int Revision { get; set; } + public List Tracks { get; set; } + public string Uid { get; set; } } \ No newline at end of file diff --git a/YandexMusic.API/Models/Library/YLibraryAlbum.cs b/YandexMusic.API/Models/Library/YLibraryAlbum.cs index 042466c..6ab934b 100644 --- a/YandexMusic.API/Models/Library/YLibraryAlbum.cs +++ b/YandexMusic.API/Models/Library/YLibraryAlbum.cs @@ -1,8 +1,7 @@ -namespace YandexMusic.API.Models.Library +namespace YandexMusic.API.Models.Library; + +public class YLibraryAlbum { - public class YLibraryAlbum - { - public string Id { get; set; } - public DateTime Timestamp { get; set; } - } + public string Id { get; set; } + public DateTime Timestamp { get; set; } } \ No newline at end of file diff --git a/YandexMusic.API/Models/Library/YLibraryPlaylists.cs b/YandexMusic.API/Models/Library/YLibraryPlaylists.cs index 0856c20..ce54926 100644 --- a/YandexMusic.API/Models/Library/YLibraryPlaylists.cs +++ b/YandexMusic.API/Models/Library/YLibraryPlaylists.cs @@ -1,10 +1,9 @@ using YandexMusic.API.Models.Playlist; -namespace YandexMusic.API.Models.Library +namespace YandexMusic.API.Models.Library; + +public class YLibraryPlaylists { - public class YLibraryPlaylists - { - public YPlaylist Playlist { get; set; } - public DateTime Timestamp { get; set; } - } + public YPlaylist Playlist { get; set; } + public DateTime Timestamp { get; set; } } \ No newline at end of file diff --git a/YandexMusic.API/Models/Library/YLibrarySection.cs b/YandexMusic.API/Models/Library/YLibrarySection.cs index 4fe100f..58d4d63 100644 --- a/YandexMusic.API/Models/Library/YLibrarySection.cs +++ b/YandexMusic.API/Models/Library/YLibrarySection.cs @@ -1,28 +1,27 @@ -namespace YandexMusic.API.Models.Library +namespace YandexMusic.API.Models.Library; + +/// +/// Раздел библиотеки +/// +public enum YLibrarySection { /// - /// Раздел библиотеки + /// Альбомы /// - public enum YLibrarySection - { - /// - /// Альбомы - /// - Albums, + Albums, - /// - /// Исполнители - /// - Artists, + /// + /// Исполнители + /// + Artists, - /// - /// Плейлисты - /// - Playlists, + /// + /// Плейлисты + /// + Playlists, - /// - /// Треки - /// - Tracks - } + /// + /// Треки + /// + Tracks, } \ No newline at end of file diff --git a/YandexMusic.API/Models/Library/YLibrarySectionType.cs b/YandexMusic.API/Models/Library/YLibrarySectionType.cs index a8fdb63..3e8c931 100644 --- a/YandexMusic.API/Models/Library/YLibrarySectionType.cs +++ b/YandexMusic.API/Models/Library/YLibrarySectionType.cs @@ -1,18 +1,17 @@ -namespace YandexMusic.API.Models.Library +namespace YandexMusic.API.Models.Library; + +/// +/// Раздел библиотеки +/// +public enum YLibrarySectionType { /// - /// Раздел библиотеки + /// Лайки /// - public enum YLibrarySectionType - { - /// - /// Лайки - /// - Likes, + Likes, - /// - /// Дизлайки - /// - Dislikes - } + /// + /// Дизлайки + /// + Dislikes, } \ No newline at end of file diff --git a/YandexMusic.API/Models/Library/YLibraryTrack.cs b/YandexMusic.API/Models/Library/YLibraryTrack.cs index 870c354..c5ce042 100644 --- a/YandexMusic.API/Models/Library/YLibraryTrack.cs +++ b/YandexMusic.API/Models/Library/YLibraryTrack.cs @@ -1,9 +1,8 @@ -namespace YandexMusic.API.Models.Library +namespace YandexMusic.API.Models.Library; + +public class YLibraryTrack { - public class YLibraryTrack - { - public string AlbumId { get; set; } - public string Id { get; set; } - public DateTime Timestamp { get; set; } - } + public string AlbumId { get; set; } + public string Id { get; set; } + public DateTime Timestamp { get; set; } } \ No newline at end of file diff --git a/YandexMusic.API/Models/Library/YLibraryTracks.cs b/YandexMusic.API/Models/Library/YLibraryTracks.cs index 8931028..dfd3a13 100644 --- a/YandexMusic.API/Models/Library/YLibraryTracks.cs +++ b/YandexMusic.API/Models/Library/YLibraryTracks.cs @@ -1,7 +1,6 @@ -namespace YandexMusic.API.Models.Library +namespace YandexMusic.API.Models.Library; + +public class YLibraryTracks { - public class YLibraryTracks - { - public YLibrary Library { get; set; } - } + public YLibrary Library { get; set; } } \ No newline at end of file diff --git a/YandexMusic.API/Models/Library/YListenedTrack.cs b/YandexMusic.API/Models/Library/YListenedTrack.cs index acf00a4..b9713f8 100644 --- a/YandexMusic.API/Models/Library/YListenedTrack.cs +++ b/YandexMusic.API/Models/Library/YListenedTrack.cs @@ -1,10 +1,9 @@ using YandexMusic.API.Models.Common; -namespace YandexMusic.API.Models.Library +namespace YandexMusic.API.Models.Library; + +public class YListenedTrack { - public class YListenedTrack - { - public YTrackId TrackId { get; set; } - public DateTime TimeStamp { get; set; } - } + public YTrackId TrackId { get; set; } + public DateTime TimeStamp { get; set; } } \ No newline at end of file diff --git a/YandexMusic.API/Models/Library/YRecentlyListened.cs b/YandexMusic.API/Models/Library/YRecentlyListened.cs index 1fe39a6..8fd4c9a 100644 --- a/YandexMusic.API/Models/Library/YRecentlyListened.cs +++ b/YandexMusic.API/Models/Library/YRecentlyListened.cs @@ -1,12 +1,11 @@ using YandexMusic.API.Models.Landing.Entity.Entities.Context; -namespace YandexMusic.API.Models.Library +namespace YandexMusic.API.Models.Library; + +public class YRecentlyListened { - public class YRecentlyListened - { - public string Client { get; set; } - public YPlayContextType Context { get; set; } - public string ContextItem { get; set; } - public List Tracks { get; set; } - } + public string Client { get; set; } + public YPlayContextType Context { get; set; } + public string ContextItem { get; set; } + public List Tracks { get; set; } } \ No newline at end of file diff --git a/YandexMusic.API/Models/Library/YRecentlyListenedContext.cs b/YandexMusic.API/Models/Library/YRecentlyListenedContext.cs index 17b44cc..c519251 100644 --- a/YandexMusic.API/Models/Library/YRecentlyListenedContext.cs +++ b/YandexMusic.API/Models/Library/YRecentlyListenedContext.cs @@ -1,10 +1,9 @@ using YandexMusic.API.Models.Track; -namespace YandexMusic.API.Models.Library +namespace YandexMusic.API.Models.Library; + +public class YRecentlyListenedContext { - public class YRecentlyListenedContext - { - public List Contexts { get; set; } - public List OtherTracks { get; set; } - } + public List Contexts { get; set; } + public List OtherTracks { get; set; } } \ No newline at end of file diff --git a/YandexMusic.API/Models/Pins/Items/YPin.cs b/YandexMusic.API/Models/Pins/Items/YPin.cs index 8cfec7e..e7e6798 100644 --- a/YandexMusic.API/Models/Pins/Items/YPin.cs +++ b/YandexMusic.API/Models/Pins/Items/YPin.cs @@ -1,68 +1,11 @@ -namespace YandexMusic.API.Models.Pins.Items +namespace YandexMusic.API.Models.Pins.Items; + +public abstract class YPin { - public sealed class YPinConverter : JsonConverter - { - private YPin GetEvent(JToken jObject) - { - YPin pin; + public YPinType Type { get; set; } +} - YPinType type = jObject["type"] - .ToObject(); - - switch (type) - { - case YPinType.Album: - pin = jObject.ToObject>(); - break; - - case YPinType.Artist: - pin = jObject.ToObject>(); - break; - - case YPinType.Playlist: - pin = jObject.ToObject>(); - break; - - case YPinType.Wave: - pin = jObject.ToObject>(); - break; - - default: - pin = jObject.ToObject(); - break; - } - - return pin; - } - - public override bool CanConvert(Type objectType) - { - return typeof(YPin).IsAssignableFrom(objectType); - } - - public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) - { - if (reader.TokenType == JsonToken.Null) - return null; - - return JArray.Load(reader) - .Select(GetEvent) - .ToList(); - } - - public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) - { - throw new NotImplementedException(); - } - } - - public abstract class YPin - { - public YPinType Type { get; set; } - } - - public class YPin : YPin - { - public T Data { get; set; } - } +public class YPin : YPin +{ + public T Data { get; set; } } \ No newline at end of file diff --git a/YandexMusic.API/Models/Pins/Items/YPinAlbumData.cs b/YandexMusic.API/Models/Pins/Items/YPinAlbumData.cs index 410c7b3..6700493 100644 --- a/YandexMusic.API/Models/Pins/Items/YPinAlbumData.cs +++ b/YandexMusic.API/Models/Pins/Items/YPinAlbumData.cs @@ -1,7 +1,6 @@ -namespace YandexMusic.API.Models.Pins.Items -{ - public class YPinAlbumData - { +namespace YandexMusic.API.Models.Pins.Items; + +public class YPinAlbumData +{ - } } \ No newline at end of file diff --git a/YandexMusic.API/Models/Pins/Items/YPinArtistData.cs b/YandexMusic.API/Models/Pins/Items/YPinArtistData.cs index 2af8bd9..8cde4d5 100644 --- a/YandexMusic.API/Models/Pins/Items/YPinArtistData.cs +++ b/YandexMusic.API/Models/Pins/Items/YPinArtistData.cs @@ -1,7 +1,6 @@ -namespace YandexMusic.API.Models.Pins.Items -{ - public class YPinArtistData - { +namespace YandexMusic.API.Models.Pins.Items; + +public class YPinArtistData +{ - } } \ No newline at end of file diff --git a/YandexMusic.API/Models/Pins/Items/YPinConverter.cs b/YandexMusic.API/Models/Pins/Items/YPinConverter.cs new file mode 100644 index 0000000..f73748b --- /dev/null +++ b/YandexMusic.API/Models/Pins/Items/YPinConverter.cs @@ -0,0 +1,64 @@ +using System.Text.Json; +using System.Text.Json.Serialization; +using YandexMusic.API.Models.Pins.Items; + +namespace YandexMusic.API.Models.Pins; + +/// Конвертер для закреплённых объектов (пинов). Десериализует в конкретные типы на основе поля type. +public class YPinConverter : JsonConverter> +{ + public override List Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + { + if (reader.TokenType != JsonTokenType.StartArray) + throw new JsonException("Ожидается массив пинов"); + + var pins = new List(); + while (reader.Read()) + { + if (reader.TokenType == JsonTokenType.EndArray) + break; + + if (reader.TokenType != JsonTokenType.StartObject) + throw new JsonException("Ожидается объект пина"); + + using var doc = JsonDocument.ParseValue(ref reader); + var root = doc.RootElement; + + var typeProp = root.GetProperty("type"); + var typeStr = typeProp.GetString(); + if (!Enum.TryParse(typeStr, true, out var pinType)) + throw new JsonException($"Неизвестный тип пина: {typeStr}"); + + YPin? pin = null; + var rawText = root.GetRawText(); + + switch (pinType) + { + case YPinType.Album: + pin = JsonSerializer.Deserialize>(rawText, options); + break; + case YPinType.Artist: + pin = JsonSerializer.Deserialize>(rawText, options); + break; + case YPinType.Playlist: + pin = JsonSerializer.Deserialize>(rawText, options); + break; + case YPinType.Wave: + pin = JsonSerializer.Deserialize>(rawText, options); + break; + default: + pin = JsonSerializer.Deserialize(rawText, options); + break; + } + + if (pin != null) + pins.Add(pin); + } + return pins; + } + + public override void Write(Utf8JsonWriter writer, List value, JsonSerializerOptions options) + { + JsonSerializer.Serialize(writer, value, options); + } +} \ No newline at end of file diff --git a/YandexMusic.API/Models/Pins/Items/YPinPlaylistData.cs b/YandexMusic.API/Models/Pins/Items/YPinPlaylistData.cs index 4dc1745..9d1b848 100644 --- a/YandexMusic.API/Models/Pins/Items/YPinPlaylistData.cs +++ b/YandexMusic.API/Models/Pins/Items/YPinPlaylistData.cs @@ -1,7 +1,6 @@ -namespace YandexMusic.API.Models.Pins.Items -{ - public class YPinPlaylistData - { +namespace YandexMusic.API.Models.Pins.Items; + +public class YPinPlaylistData +{ - } } \ No newline at end of file diff --git a/YandexMusic.API/Models/Pins/Items/YPinWaveData.cs b/YandexMusic.API/Models/Pins/Items/YPinWaveData.cs index 4e6864c..e6f2b15 100644 --- a/YandexMusic.API/Models/Pins/Items/YPinWaveData.cs +++ b/YandexMusic.API/Models/Pins/Items/YPinWaveData.cs @@ -1,7 +1,6 @@ -namespace YandexMusic.API.Models.Pins.Items -{ - public class YPinWaveData - { +namespace YandexMusic.API.Models.Pins.Items; + +public class YPinWaveData +{ - } } \ No newline at end of file diff --git a/YandexMusic.API/Models/Pins/YPinType.cs b/YandexMusic.API/Models/Pins/YPinType.cs index 0baa048..02ccf80 100644 --- a/YandexMusic.API/Models/Pins/YPinType.cs +++ b/YandexMusic.API/Models/Pins/YPinType.cs @@ -1,19 +1,18 @@ using System.Runtime.Serialization; -namespace YandexMusic.API.Models.Pins +namespace YandexMusic.API.Models.Pins; + +public enum YPinType { - public enum YPinType - { - [EnumMember(Value = "album_item")] - Album, + [EnumMember(Value = "album_item")] + Album, - [EnumMember(Value = "artist_item")] - Artist, + [EnumMember(Value = "artist_item")] + Artist, - [EnumMember(Value = "playlist_item")] - Playlist, + [EnumMember(Value = "playlist_item")] + Playlist, - [EnumMember(Value = "wave_item")] - Wave - } + [EnumMember(Value = "wave_item")] + Wave, } \ No newline at end of file diff --git a/YandexMusic.API/Models/Pins/YPins.cs b/YandexMusic.API/Models/Pins/YPins.cs index a911d20..0737e96 100644 --- a/YandexMusic.API/Models/Pins/YPins.cs +++ b/YandexMusic.API/Models/Pins/YPins.cs @@ -1,10 +1,10 @@ -using YandexMusic.API.Models.Pins.Items; +using System.Text.Json.Serialization; +using YandexMusic.API.Models.Pins.Items; -namespace YandexMusic.API.Models.Pins +namespace YandexMusic.API.Models.Pins; + +public class YPins { - public class YPins - { - [JsonConverter(typeof(YPinConverter))] - public List Pins { get; set; } - } + [JsonConverter(typeof(YPinConverter))] + public List Pins { get; set; } } \ No newline at end of file diff --git a/YandexMusic.API/Models/Playlist/YArtistPlaylistType.cs b/YandexMusic.API/Models/Playlist/YArtistPlaylistType.cs index 13ab599..ccd05a8 100644 --- a/YandexMusic.API/Models/Playlist/YArtistPlaylistType.cs +++ b/YandexMusic.API/Models/Playlist/YArtistPlaylistType.cs @@ -1,12 +1,11 @@ using System.Runtime.Serialization; -namespace YandexMusic.API.Models.Playlist +namespace YandexMusic.API.Models.Playlist; + +public enum YArtistPlaylistType { - public enum YArtistPlaylistType - { - [EnumMember(Value = "TOP")] - Top, - [EnumMember(Value = "SIMILAR")] - Similar - } + [EnumMember(Value = "TOP")] + Top, + [EnumMember(Value = "SIMILAR")] + Similar, } \ No newline at end of file diff --git a/YandexMusic.API/Models/Playlist/YGeneratedPlaylistType.cs b/YandexMusic.API/Models/Playlist/YGeneratedPlaylistType.cs index 779c7bf..405a83e 100644 --- a/YandexMusic.API/Models/Playlist/YGeneratedPlaylistType.cs +++ b/YandexMusic.API/Models/Playlist/YGeneratedPlaylistType.cs @@ -1,42 +1,41 @@ -namespace YandexMusic.API.Models.Playlist +namespace YandexMusic.API.Models.Playlist; + +public enum YGeneratedPlaylistType { - public enum YGeneratedPlaylistType - { - None, + None, - /// - /// Редакторский список - /// - Editorial, + /// + /// Редакторский список + /// + Editorial, - /// - /// Плейлист дня - /// - PlaylistOfTheDay, + /// + /// Плейлист дня + /// + PlaylistOfTheDay, - /// - /// Премьера - /// - RecentTracks, + /// + /// Премьера + /// + RecentTracks, - /// - /// Дежавю - /// - NeverHeard, + /// + /// Дежавю + /// + NeverHeard, - /// - /// Тайник - /// - MissedLikes, + /// + /// Тайник + /// + MissedLikes, - /// - /// Алиса - /// - Origin, + /// + /// Алиса + /// + Origin, - /// - /// Кинопоиск - /// - Kinopoisk - } + /// + /// Кинопоиск + /// + Kinopoisk, } \ No newline at end of file diff --git a/YandexMusic.API/Models/Playlist/YPlaylist.cs b/YandexMusic.API/Models/Playlist/YPlaylist.cs index b30c232..17dc376 100644 --- a/YandexMusic.API/Models/Playlist/YPlaylist.cs +++ b/YandexMusic.API/Models/Playlist/YPlaylist.cs @@ -1,82 +1,75 @@ +using System.Text.Json.Serialization; using YandexMusic.API.Models.Common; using YandexMusic.API.Models.Common.Cover; using YandexMusic.API.Models.Track; -namespace YandexMusic.API.Models.Playlist +namespace YandexMusic.API.Models.Playlist; + +public class YPlaylist : YBaseModel { - public class YPlaylist : YBaseModel + + public YPlaylistUidPair GetKey() { - #region Поля - - public YPlaylistUidPair GetKey() + return new YPlaylistUidPair { - return new YPlaylistUidPair - { - Uid = Owner.Uid, - Kind = Kind - }; - } - - #endregion Поля - - #region Свойства - - public YButton ActionButton { get; set; } - public string AnimatedCoverUri { get; set; } - public bool Available { get; set; } - public YArtistPlaylistType ArtistPlaylistType { get; set; } - public string BackgroundColor { get; set; } - public string BackgroundImageUrl { get; set; } - public string BackgroundVideoUrl { get; set; } - public bool Collective { get; set; } - [JsonConverter(typeof(YCoverConverter))] - public YCover Cover { get; set; } - [JsonConverter(typeof(YCoverConverter))] - public YCover CoverWithoutText { get; set; } - public YCustomWave CustomWave { get; set; } - public List RecentTracks { get; set; } - public DateTime Created { get; set; } - public YDerivedColors DerivedColors { get; set; } - public string Description { get; set; } - public string DescriptionFormatted { get; set; } - public bool DoNotIndex { get; set; } - public long DurationMs { get; set; } - public bool EverPlayed { get; set; } - public string GeneratedPlaylistType { get; set; } - public bool HasTrailer { get; set; } - public string IdForFrom { get; set; } - public string Image { get; set; } - public bool IsBanner { get; set; } - public bool IsPremiere { get; set; } - public string Kind { get; set; } - public List LastOwnerPlaylists { get; set; } - public int LikesCount { get; set; } - public YPlaylistMadeFor MadeFor { get; set; } - public string MetrikaId { get; set; } - public string Modified { get; set; } - public string OgImage { get; set; } - public string OgTitle { get; set; } - public string OgDescription { get; set; } - public YOwner Owner { get; set; } - public YPager Pager { get; set; } - public decimal PersonalColor { get; set; } - public YPlaylistPlayCounter PlayCounter { get; set; } - public string PlaylistUuid { get; set; } - public List Prerolls { get; set; } - public int Revision { get; set; } - public List SimilarPlaylists { get; set; } - public int Snapshot { get; set; } - public List Tags { get; set; } - public string TextColor { get; set; } - public string Title { get; set; } - public int TrackCount { get; set; } - public List TrackIds { get; set; } - public List Tracks { get; set; } - public YTrailer Trailer { get; set; } - public string Uid { get; set; } - public string UrlPart { get; set; } - public string Visibility { get; set; } - - #endregion Свойства + Uid = Owner.Uid, + Kind = Kind + }; } + + public YButton ActionButton { get; set; } + public string AnimatedCoverUri { get; set; } + public bool Available { get; set; } + public YArtistPlaylistType ArtistPlaylistType { get; set; } + public string BackgroundColor { get; set; } + public string BackgroundImageUrl { get; set; } + public string BackgroundVideoUrl { get; set; } + public bool Collective { get; set; } + [JsonConverter(typeof(YCoverConverter))] + public YCover Cover { get; set; } + [JsonConverter(typeof(YCoverConverter))] + public YCover CoverWithoutText { get; set; } + public YCustomWave CustomWave { get; set; } + public List RecentTracks { get; set; } + public DateTime Created { get; set; } + public YDerivedColors DerivedColors { get; set; } + public string Description { get; set; } + public string DescriptionFormatted { get; set; } + public bool DoNotIndex { get; set; } + public long DurationMs { get; set; } + public bool EverPlayed { get; set; } + public string GeneratedPlaylistType { get; set; } + public bool HasTrailer { get; set; } + public string IdForFrom { get; set; } + public string Image { get; set; } + public bool IsBanner { get; set; } + public bool IsPremiere { get; set; } + public string Kind { get; set; } + public List LastOwnerPlaylists { get; set; } + public int LikesCount { get; set; } + public YPlaylistMadeFor MadeFor { get; set; } + public string MetrikaId { get; set; } + public string Modified { get; set; } + public string OgImage { get; set; } + public string OgTitle { get; set; } + public string OgDescription { get; set; } + public YOwner Owner { get; set; } + public YPager Pager { get; set; } + public decimal PersonalColor { get; set; } + public YPlaylistPlayCounter PlayCounter { get; set; } + public string PlaylistUuid { get; set; } + public List Prerolls { get; set; } + public int Revision { get; set; } + public List SimilarPlaylists { get; set; } + public int Snapshot { get; set; } + public List Tags { get; set; } + public string TextColor { get; set; } + public string Title { get; set; } + public int TrackCount { get; set; } + public List TrackIds { get; set; } + public List Tracks { get; set; } + public YTrailer Trailer { get; set; } + public string Uid { get; set; } + public string UrlPart { get; set; } + public string Visibility { get; set; } } \ No newline at end of file diff --git a/YandexMusic.API/Models/Playlist/YPlaylistChange.cs b/YandexMusic.API/Models/Playlist/YPlaylistChange.cs index 50452ce..5cdcd1c 100644 --- a/YandexMusic.API/Models/Playlist/YPlaylistChange.cs +++ b/YandexMusic.API/Models/Playlist/YPlaylistChange.cs @@ -1,14 +1,14 @@ +using System.Text.Json.Serialization; using YandexMusic.API.Models.Track; -namespace YandexMusic.API.Models.Playlist +namespace YandexMusic.API.Models.Playlist; + +public class YPlaylistChange { - public class YPlaylistChange - { - public int? At { get; set; } - public int? From { get; set; } - [JsonProperty("op")] - public YPlaylistChangeType Operation { get; set; } - public int? To { get; set; } - public IEnumerable Tracks { get; set; } - } + public int? At { get; set; } + public int? From { get; set; } + [JsonPropertyName("op")] + public YPlaylistChangeType Operation { get; set; } + public int? To { get; set; } + public IEnumerable Tracks { get; set; } } \ No newline at end of file diff --git a/YandexMusic.API/Models/Playlist/YPlaylistChangeType.cs b/YandexMusic.API/Models/Playlist/YPlaylistChangeType.cs index f161bd4..bbfbba1 100644 --- a/YandexMusic.API/Models/Playlist/YPlaylistChangeType.cs +++ b/YandexMusic.API/Models/Playlist/YPlaylistChangeType.cs @@ -1,8 +1,7 @@ -namespace YandexMusic.API.Models.Playlist +namespace YandexMusic.API.Models.Playlist; + +public enum YPlaylistChangeType { - public enum YPlaylistChangeType - { - Insert, - Delete - } + Insert, + Delete } \ No newline at end of file diff --git a/YandexMusic.API/Models/Playlist/YPlaylistMadeFor.cs b/YandexMusic.API/Models/Playlist/YPlaylistMadeFor.cs index 2c838eb..8655ca0 100644 --- a/YandexMusic.API/Models/Playlist/YPlaylistMadeFor.cs +++ b/YandexMusic.API/Models/Playlist/YPlaylistMadeFor.cs @@ -1,28 +1,19 @@ using YandexMusic.API.Models.Common; -namespace YandexMusic.API.Models.Playlist +namespace YandexMusic.API.Models.Playlist; + +public class YPlaylistMadeFor { - public class YPlaylistMadeFor + public class YMadeForCaseForms { - public class YMadeForCaseForms - { - #region Свойства - - public string Accusative { get; set; } - public string Dative { get; set; } - public string Genitive { get; set; } - public string Instrumental { get; set; } - public string Nominative { get; set; } - public string Prepositional { get; set; } - - #endregion Свойства - } - - #region Свойства - - public YMadeForCaseForms CaseForms { get; set; } - public YOwner UserInfo { get; set; } - - #endregion Свойства + public string Accusative { get; set; } + public string Dative { get; set; } + public string Genitive { get; set; } + public string Instrumental { get; set; } + public string Nominative { get; set; } + public string Prepositional { get; set; } } + + public YMadeForCaseForms CaseForms { get; set; } + public YOwner UserInfo { get; set; } } \ No newline at end of file diff --git a/YandexMusic.API/Models/Playlist/YPlaylistPlayCounter.cs b/YandexMusic.API/Models/Playlist/YPlaylistPlayCounter.cs index eef5b39..f9c3b75 100644 --- a/YandexMusic.API/Models/Playlist/YPlaylistPlayCounter.cs +++ b/YandexMusic.API/Models/Playlist/YPlaylistPlayCounter.cs @@ -1,10 +1,9 @@ -namespace YandexMusic.API.Models.Playlist +namespace YandexMusic.API.Models.Playlist; + +public class YPlaylistPlayCounter { - public class YPlaylistPlayCounter - { - public string Description { get; set; } - public string DescriptionNext { get; set; } - public bool Updated { get; set; } - public int? Value { get; set; } - } + public string Description { get; set; } + public string DescriptionNext { get; set; } + public bool Updated { get; set; } + public int? Value { get; set; } } \ No newline at end of file diff --git a/YandexMusic.API/Models/Playlist/YPlaylistUidPair.cs b/YandexMusic.API/Models/Playlist/YPlaylistUidPair.cs index f195fdc..67e01bb 100644 --- a/YandexMusic.API/Models/Playlist/YPlaylistUidPair.cs +++ b/YandexMusic.API/Models/Playlist/YPlaylistUidPair.cs @@ -1,13 +1,12 @@ -namespace YandexMusic.API.Models.Playlist -{ - public class YPlaylistUidPair - { - public string Kind { get; set; } - public string Uid { get; set; } +namespace YandexMusic.API.Models.Playlist; - public override string ToString() - { - return $"{Uid}:{Kind}"; - } +public class YPlaylistUidPair +{ + public string Kind { get; set; } + public string Uid { get; set; } + + public override string ToString() + { + return $"{Uid}:{Kind}"; } } \ No newline at end of file diff --git a/YandexMusic.API/Models/Queue/YContext.cs b/YandexMusic.API/Models/Queue/YContext.cs index e7ddc8f..d0755d3 100644 --- a/YandexMusic.API/Models/Queue/YContext.cs +++ b/YandexMusic.API/Models/Queue/YContext.cs @@ -1,10 +1,9 @@ -namespace YandexMusic.API.Models.Queue +namespace YandexMusic.API.Models.Queue; + +public class YContext { - public class YContext - { - public string Type { get; set; } - public string Id { get; set; } - public string Login { get; set; } - public string Description { get; set; } - } + public string Type { get; set; } + public string Id { get; set; } + public string Login { get; set; } + public string Description { get; set; } } diff --git a/YandexMusic.API/Models/Queue/YNewQueue.cs b/YandexMusic.API/Models/Queue/YNewQueue.cs index c76466c..9c49332 100644 --- a/YandexMusic.API/Models/Queue/YNewQueue.cs +++ b/YandexMusic.API/Models/Queue/YNewQueue.cs @@ -1,9 +1,8 @@ using YandexMusic.API.Models.Common; -namespace YandexMusic.API.Models.Queue +namespace YandexMusic.API.Models.Queue; + +public class YNewQueue : YId { - public class YNewQueue : YId - { - public string Modified { get; set; } - } + public string Modified { get; set; } } diff --git a/YandexMusic.API/Models/Queue/YQueue.cs b/YandexMusic.API/Models/Queue/YQueue.cs index c8bb27c..6e3db66 100644 --- a/YandexMusic.API/Models/Queue/YQueue.cs +++ b/YandexMusic.API/Models/Queue/YQueue.cs @@ -1,15 +1,14 @@ using YandexMusic.API.Models.Common; -namespace YandexMusic.API.Models.Queue +namespace YandexMusic.API.Models.Queue; + +public class YQueue { - public class YQueue - { - public string Id { get; set; } - public YContext Context { get; set; } - public List Tracks { get; set; } - public int? CurrentIndex { get; set; } - public string Modified { get; set; } - public string From { get; set; } - public bool IsInteractive { get; set; } - } + public string Id { get; set; } + public YContext Context { get; set; } + public List Tracks { get; set; } + public int? CurrentIndex { get; set; } + public string Modified { get; set; } + public string From { get; set; } + public bool IsInteractive { get; set; } } diff --git a/YandexMusic.API/Models/Queue/YQueueItem.cs b/YandexMusic.API/Models/Queue/YQueueItem.cs index 6a27b32..6c88916 100644 --- a/YandexMusic.API/Models/Queue/YQueueItem.cs +++ b/YandexMusic.API/Models/Queue/YQueueItem.cs @@ -1,10 +1,9 @@ -namespace YandexMusic.API.Models.Queue +namespace YandexMusic.API.Models.Queue; + +public class YQueueItem { - public class YQueueItem - { - public string Id { get; set; } - public YContext Context { get; set; } - public YContext InitialContext { get; set; } - public string Modified { get; set; } - } + public string Id { get; set; } + public YContext Context { get; set; } + public YContext InitialContext { get; set; } + public string Modified { get; set; } } diff --git a/YandexMusic.API/Models/Queue/YQueueItemsContainer.cs b/YandexMusic.API/Models/Queue/YQueueItemsContainer.cs index 98c51cf..9bfb0d1 100644 --- a/YandexMusic.API/Models/Queue/YQueueItemsContainer.cs +++ b/YandexMusic.API/Models/Queue/YQueueItemsContainer.cs @@ -1,7 +1,6 @@ -namespace YandexMusic.API.Models.Queue +namespace YandexMusic.API.Models.Queue; + +public class YQueueItemsContainer { - public class YQueueItemsContainer - { - public List Queues { get; set; } - } + public List Queues { get; set; } } diff --git a/YandexMusic.API/Models/Queue/YUpdatedQueue.cs b/YandexMusic.API/Models/Queue/YUpdatedQueue.cs index 1b8482a..73796b5 100644 --- a/YandexMusic.API/Models/Queue/YUpdatedQueue.cs +++ b/YandexMusic.API/Models/Queue/YUpdatedQueue.cs @@ -1,8 +1,7 @@ -namespace YandexMusic.API.Models.Queue +namespace YandexMusic.API.Models.Queue; + +public class YUpdatedQueue { - public class YUpdatedQueue - { - public string Status { get; set; } - public bool MostRecentQueue { get; set; } - } + public string Status { get; set; } + public bool MostRecentQueue { get; set; } } diff --git a/YandexMusic.API/Models/Radio/Restriction/YRestriction.cs b/YandexMusic.API/Models/Radio/Restriction/YRestriction.cs index fc2ab84..f169304 100644 --- a/YandexMusic.API/Models/Radio/Restriction/YRestriction.cs +++ b/YandexMusic.API/Models/Radio/Restriction/YRestriction.cs @@ -1,54 +1,8 @@ -namespace YandexMusic.API.Models.Radio.Restriction +namespace YandexMusic.API.Models.Radio.Restriction; + + +public class YRestriction { - public sealed class YRestrictionConverter : JsonConverter - { - public override bool CanConvert(Type objectType) - { - return typeof(YRestriction).IsAssignableFrom(objectType); - } - - public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) - { - if (reader.TokenType == JsonToken.Null) - return null; - - JObject jObject = JObject.Load(reader); - YRestriction restriction; - - try - { - YRestrictionType type = jObject["type"].ToObject(); - - switch (type) - { - case YRestrictionType.Enum: - restriction = jObject.ToObject(); - break; - case YRestrictionType.DiscreteScale: - restriction = jObject.ToObject(); - break; - default: - restriction = jObject.ToObject(); - break; - } - } - catch (Exception ex) - { - throw new Exception($"Ошибка десериализации типа \"{objectType.Name}\".", ex); - } - - return restriction; - } - - public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) - { - throw new NotImplementedException(); - } - } - - public class YRestriction - { - public string Name { get; set; } - public YRestrictionType Type { get; set; } - } + public string Name { get; set; } + public YRestrictionType Type { get; set; } } diff --git a/YandexMusic.API/Models/Radio/Restriction/YRestrictionConverter.cs b/YandexMusic.API/Models/Radio/Restriction/YRestrictionConverter.cs new file mode 100644 index 0000000..f2ec6fe --- /dev/null +++ b/YandexMusic.API/Models/Radio/Restriction/YRestrictionConverter.cs @@ -0,0 +1,36 @@ +using System.Text.Json; +using System.Text.Json.Serialization; + +namespace YandexMusic.API.Models.Radio.Restriction; + +/// Конвертер для ограничений радиостанции (дискретная шкала или перечисление). +public class YRestrictionConverter : JsonConverter +{ + public override YRestriction? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + { + if (reader.TokenType != JsonTokenType.StartObject) + throw new JsonException("Ожидается объект ограничения"); + + using var doc = JsonDocument.ParseValue(ref reader); + var root = doc.RootElement; + + var typeProp = root.GetProperty("type"); + var typeStr = typeProp.GetString(); + if (!Enum.TryParse(typeStr, true, out var restrictionType)) + throw new JsonException($"Неизвестный тип ограничения: {typeStr}"); + + var rawText = root.GetRawText(); + + return restrictionType switch + { + YRestrictionType.Enum => JsonSerializer.Deserialize(rawText, options), + YRestrictionType.DiscreteScale => JsonSerializer.Deserialize(rawText, options), + _ => JsonSerializer.Deserialize(rawText, options) + }; + } + + public override void Write(Utf8JsonWriter writer, YRestriction value, JsonSerializerOptions options) + { + JsonSerializer.Serialize(writer, value, options); + } +} \ No newline at end of file diff --git a/YandexMusic.API/Models/Radio/Restriction/YRestrictionDiscreteScale.cs b/YandexMusic.API/Models/Radio/Restriction/YRestrictionDiscreteScale.cs index bd9cbcd..f165ffa 100644 --- a/YandexMusic.API/Models/Radio/Restriction/YRestrictionDiscreteScale.cs +++ b/YandexMusic.API/Models/Radio/Restriction/YRestrictionDiscreteScale.cs @@ -1,8 +1,7 @@ -namespace YandexMusic.API.Models.Radio.Restriction +namespace YandexMusic.API.Models.Radio.Restriction; + +public class YRestrictionDiscreteScale : YRestriction { - public class YRestrictionDiscreteScale : YRestriction - { - public YRestrictionValue Min { get; set; } - public YRestrictionValue Max { get; set; } - } + public YRestrictionValue Min { get; set; } + public YRestrictionValue Max { get; set; } } diff --git a/YandexMusic.API/Models/Radio/Restriction/YRestrictionEnum.cs b/YandexMusic.API/Models/Radio/Restriction/YRestrictionEnum.cs index fcc7fd7..59ba889 100644 --- a/YandexMusic.API/Models/Radio/Restriction/YRestrictionEnum.cs +++ b/YandexMusic.API/Models/Radio/Restriction/YRestrictionEnum.cs @@ -1,7 +1,6 @@ -namespace YandexMusic.API.Models.Radio.Restriction +namespace YandexMusic.API.Models.Radio.Restriction; + +public class YRestrictionEnum : YRestriction { - public class YRestrictionEnum : YRestriction - { - public List> PossibleValues { get; set; } - } + public List> PossibleValues { get; set; } } diff --git a/YandexMusic.API/Models/Radio/Restriction/YRestrictionType.cs b/YandexMusic.API/Models/Radio/Restriction/YRestrictionType.cs index db69964..0f7dfde 100644 --- a/YandexMusic.API/Models/Radio/Restriction/YRestrictionType.cs +++ b/YandexMusic.API/Models/Radio/Restriction/YRestrictionType.cs @@ -1,12 +1,12 @@ using System.Runtime.Serialization; +using System.Text.Json.Serialization; -namespace YandexMusic.API.Models.Radio.Restriction +namespace YandexMusic.API.Models.Radio.Restriction; + +[JsonConverter(typeof(JsonStringEnumConverter))] +public enum YRestrictionType { - [JsonConverter(typeof(StringEnumConverter))] - public enum YRestrictionType - { - [EnumMember(Value = "discrete-scale")] - DiscreteScale, - Enum - } + [EnumMember(Value = "discrete-scale")] + DiscreteScale, + Enum } diff --git a/YandexMusic.API/Models/Radio/Restriction/YRestrictionValue.cs b/YandexMusic.API/Models/Radio/Restriction/YRestrictionValue.cs index 2d62671..63da171 100644 --- a/YandexMusic.API/Models/Radio/Restriction/YRestrictionValue.cs +++ b/YandexMusic.API/Models/Radio/Restriction/YRestrictionValue.cs @@ -1,8 +1,7 @@ -namespace YandexMusic.API.Models.Radio.Restriction +namespace YandexMusic.API.Models.Radio.Restriction; + +public class YRestrictionValue { - public class YRestrictionValue - { - public string Name { get; set; } - public T Value { get; set; } - } + public string Name { get; set; } + public T Value { get; set; } } diff --git a/YandexMusic.API/Models/Radio/YAdParams.cs b/YandexMusic.API/Models/Radio/YAdParams.cs index b1abf40..49597af 100644 --- a/YandexMusic.API/Models/Radio/YAdParams.cs +++ b/YandexMusic.API/Models/Radio/YAdParams.cs @@ -1,14 +1,13 @@ -namespace YandexMusic.API.Models.Radio +namespace YandexMusic.API.Models.Radio; + +public class YAdParams { - public class YAdParams - { - public decimal AdVolume { get; set; } - public string CategoryId { get; set; } - public int GenreId { get; set; } - public string GenreName { get; set; } - public string OtherParams { get; set; } - public string PageRef { get; set; } - public string PartnerId { get; set; } - public string TargetRef { get; set; } - } + public decimal AdVolume { get; set; } + public string CategoryId { get; set; } + public int GenreId { get; set; } + public string GenreName { get; set; } + public string OtherParams { get; set; } + public string PageRef { get; set; } + public string PartnerId { get; set; } + public string TargetRef { get; set; } } \ No newline at end of file diff --git a/YandexMusic.API/Models/Radio/YBrand.cs b/YandexMusic.API/Models/Radio/YBrand.cs index 90035f8..2ea7532 100644 --- a/YandexMusic.API/Models/Radio/YBrand.cs +++ b/YandexMusic.API/Models/Radio/YBrand.cs @@ -1,12 +1,11 @@ -namespace YandexMusic.API.Models.Radio +namespace YandexMusic.API.Models.Radio; + +public class YBrand { - public class YBrand - { - public string AdvertiserUrl { get; set; } - public string BackgroundColor { get; set; } - public string BackgroundImageUri { get; set; } - public string GlowColor { get; set; } - public string MainImageUri { get; set; } - public string Theme { get; set; } - } + public string AdvertiserUrl { get; set; } + public string BackgroundColor { get; set; } + public string BackgroundImageUri { get; set; } + public string GlowColor { get; set; } + public string MainImageUri { get; set; } + public string Theme { get; set; } } \ No newline at end of file diff --git a/YandexMusic.API/Models/Radio/YSequenceItem.cs b/YandexMusic.API/Models/Radio/YSequenceItem.cs index 6c003d4..5057157 100644 --- a/YandexMusic.API/Models/Radio/YSequenceItem.cs +++ b/YandexMusic.API/Models/Radio/YSequenceItem.cs @@ -1,12 +1,11 @@ using YandexMusic.API.Models.Track; -namespace YandexMusic.API.Models.Radio +namespace YandexMusic.API.Models.Radio; + +public class YSequenceItem { - public class YSequenceItem - { - public bool Liked { get; set; } - public YTrack Track { get; set; } - public YTrackParameters TrackParameters { get; set; } - public string Type { get; set; } - } + public bool Liked { get; set; } + public YTrack Track { get; set; } + public YTrackParameters TrackParameters { get; set; } + public string Type { get; set; } } diff --git a/YandexMusic.API/Models/Radio/YStation.cs b/YandexMusic.API/Models/Radio/YStation.cs index c43afdd..93a5836 100644 --- a/YandexMusic.API/Models/Radio/YStation.cs +++ b/YandexMusic.API/Models/Radio/YStation.cs @@ -1,18 +1,17 @@ using YandexMusic.API.Models.Common; -namespace YandexMusic.API.Models.Radio +namespace YandexMusic.API.Models.Radio; + +public class YStation : YBaseModel { - public class YStation : YBaseModel - { - public YAdParams AdParams { get; set; } - public string CustomName { get; set; } - public YStationData Data { get; set; } - public string Explanation { get; set; } - public List Prerolls { get; set; } - public string RupTitle { get; set; } - public string RupDescription { get; set; } - public YStationSettings Settings { get; set; } - public YStationSettings2 Settings2 { get; set; } - public YStationDescription Station { get; set; } - } + public YAdParams AdParams { get; set; } + public string CustomName { get; set; } + public YStationData Data { get; set; } + public string Explanation { get; set; } + public List Prerolls { get; set; } + public string RupTitle { get; set; } + public string RupDescription { get; set; } + public YStationSettings Settings { get; set; } + public YStationSettings2 Settings2 { get; set; } + public YStationDescription Station { get; set; } } \ No newline at end of file diff --git a/YandexMusic.API/Models/Radio/YStationData.cs b/YandexMusic.API/Models/Radio/YStationData.cs index c694373..5b2cb2d 100644 --- a/YandexMusic.API/Models/Radio/YStationData.cs +++ b/YandexMusic.API/Models/Radio/YStationData.cs @@ -1,13 +1,12 @@ using YandexMusic.API.Models.Artist; -namespace YandexMusic.API.Models.Radio +namespace YandexMusic.API.Models.Radio; + +public class YStationData { - public class YStationData - { - public List Artists { get; set; } - public YBrand Brand { get; set; } - public string Description { get; set; } - public string ImageUri { get; set; } - public string Title { get; set; } - } + public List Artists { get; set; } + public YBrand Brand { get; set; } + public string Description { get; set; } + public string ImageUri { get; set; } + public string Title { get; set; } } \ No newline at end of file diff --git a/YandexMusic.API/Models/Radio/YStationDescription.cs b/YandexMusic.API/Models/Radio/YStationDescription.cs index 7deb637..76d9cbc 100644 --- a/YandexMusic.API/Models/Radio/YStationDescription.cs +++ b/YandexMusic.API/Models/Radio/YStationDescription.cs @@ -1,17 +1,16 @@ -namespace YandexMusic.API.Models.Radio +namespace YandexMusic.API.Models.Radio; + +public class YStationDescription { - public class YStationDescription - { - public string FullImageUrl { get; set; } - public YStationIcon GeocellIcon { get; set; } - public YStationIcon Icon { get; set; } - public YStationId Id { get; set; } - public string IdForFrom { get; set; } - public string MtsFullImageUrl { get; set; } - public YStationIcon MtsIcon { get; set; } - public string Name { get; set; } - public YStationId ParentId { get; set; } - public YStationRestrictions Restrictions { get; set; } - public YStationRestrictions2 Restrictions2 { get; set; } - } + public string FullImageUrl { get; set; } + public YStationIcon GeocellIcon { get; set; } + public YStationIcon Icon { get; set; } + public YStationId Id { get; set; } + public string IdForFrom { get; set; } + public string MtsFullImageUrl { get; set; } + public YStationIcon MtsIcon { get; set; } + public string Name { get; set; } + public YStationId ParentId { get; set; } + public YStationRestrictions Restrictions { get; set; } + public YStationRestrictions2 Restrictions2 { get; set; } } \ No newline at end of file diff --git a/YandexMusic.API/Models/Radio/YStationFeedback.cs b/YandexMusic.API/Models/Radio/YStationFeedback.cs index 267e581..cc1a2e4 100644 --- a/YandexMusic.API/Models/Radio/YStationFeedback.cs +++ b/YandexMusic.API/Models/Radio/YStationFeedback.cs @@ -1,11 +1,10 @@ -namespace YandexMusic.API.Models.Radio +namespace YandexMusic.API.Models.Radio; + +internal sealed class YStationFeedback { - internal sealed class YStationFeedback - { - public YStationFeedbackType Type { get; set; } - public long Timestamp { get; set; } - public string From { get; set; } - public double TotalPlayedSeconds { get; set; } - public string TrackId { get; set; } - } + public YStationFeedbackType Type { get; set; } + public long Timestamp { get; set; } + public string From { get; set; } + public double TotalPlayedSeconds { get; set; } + public string TrackId { get; set; } } \ No newline at end of file diff --git a/YandexMusic.API/Models/Radio/YStationFeedbackType.cs b/YandexMusic.API/Models/Radio/YStationFeedbackType.cs index 6264f08..5d23a58 100644 --- a/YandexMusic.API/Models/Radio/YStationFeedbackType.cs +++ b/YandexMusic.API/Models/Radio/YStationFeedbackType.cs @@ -1,10 +1,9 @@ -namespace YandexMusic.API.Models.Radio +namespace YandexMusic.API.Models.Radio; + +public enum YStationFeedbackType { - public enum YStationFeedbackType - { - RadioStarted, - TrackStarted, - TrackFinished, - Skip - } + RadioStarted, + TrackStarted, + TrackFinished, + Skip, } \ No newline at end of file diff --git a/YandexMusic.API/Models/Radio/YStationIcon.cs b/YandexMusic.API/Models/Radio/YStationIcon.cs index 5c381da..f61d352 100644 --- a/YandexMusic.API/Models/Radio/YStationIcon.cs +++ b/YandexMusic.API/Models/Radio/YStationIcon.cs @@ -1,8 +1,7 @@ -namespace YandexMusic.API.Models.Radio +namespace YandexMusic.API.Models.Radio; + +public class YStationIcon { - public class YStationIcon - { - public string BackgroundColor { get; set; } - public string ImageUrl { get; set; } - } + public string BackgroundColor { get; set; } + public string ImageUrl { get; set; } } diff --git a/YandexMusic.API/Models/Radio/YStationId.cs b/YandexMusic.API/Models/Radio/YStationId.cs index 9646dfe..66a3f3e 100644 --- a/YandexMusic.API/Models/Radio/YStationId.cs +++ b/YandexMusic.API/Models/Radio/YStationId.cs @@ -1,8 +1,7 @@ -namespace YandexMusic.API.Models.Radio +namespace YandexMusic.API.Models.Radio; + +public class YStationId { - public class YStationId - { - public string Tag { get; set; } - public string Type { get; set; } - } + public string Tag { get; set; } + public string Type { get; set; } } diff --git a/YandexMusic.API/Models/Radio/YStationRestrictions.cs b/YandexMusic.API/Models/Radio/YStationRestrictions.cs index b0cafd4..aaf872b 100644 --- a/YandexMusic.API/Models/Radio/YStationRestrictions.cs +++ b/YandexMusic.API/Models/Radio/YStationRestrictions.cs @@ -1,16 +1,16 @@ +using System.Text.Json.Serialization; using YandexMusic.API.Models.Radio.Restriction; -namespace YandexMusic.API.Models.Radio +namespace YandexMusic.API.Models.Radio; + +public class YStationRestrictions { - public class YStationRestrictions - { - [JsonConverter(typeof(YRestrictionConverter))] - public YRestriction Diversity { get; set; } - [JsonConverter(typeof(YRestrictionConverter))] - public YRestriction Energy { get; set; } - [JsonConverter(typeof(YRestrictionConverter))] - public YRestriction Language { get; set; } - [JsonConverter(typeof(YRestrictionConverter))] - public YRestriction Mood { get; set; } - } + [JsonConverter(typeof(YRestrictionConverter))] + public YRestriction Diversity { get; set; } + [JsonConverter(typeof(YRestrictionConverter))] + public YRestriction Energy { get; set; } + [JsonConverter(typeof(YRestrictionConverter))] + public YRestriction Language { get; set; } + [JsonConverter(typeof(YRestrictionConverter))] + public YRestriction Mood { get; set; } } \ No newline at end of file diff --git a/YandexMusic.API/Models/Radio/YStationRestrictions2.cs b/YandexMusic.API/Models/Radio/YStationRestrictions2.cs index d3dd9fb..9c2b9ab 100644 --- a/YandexMusic.API/Models/Radio/YStationRestrictions2.cs +++ b/YandexMusic.API/Models/Radio/YStationRestrictions2.cs @@ -1,14 +1,14 @@ +using System.Text.Json.Serialization; using YandexMusic.API.Models.Radio.Restriction; -namespace YandexMusic.API.Models.Radio +namespace YandexMusic.API.Models.Radio; + +public class YStationRestrictions2 { - public class YStationRestrictions2 - { - [JsonConverter(typeof(YRestrictionConverter))] - public YRestriction Diversity { get; set; } - [JsonConverter(typeof(YRestrictionConverter))] - public YRestriction Language { get; set; } - [JsonConverter(typeof(YRestrictionConverter))] - public YRestriction MoodEnergy { get; set; } - } + [JsonConverter(typeof(YRestrictionConverter))] + public YRestriction Diversity { get; set; } + [JsonConverter(typeof(YRestrictionConverter))] + public YRestriction Language { get; set; } + [JsonConverter(typeof(YRestrictionConverter))] + public YRestriction MoodEnergy { get; set; } } \ No newline at end of file diff --git a/YandexMusic.API/Models/Radio/YStationSequence.cs b/YandexMusic.API/Models/Radio/YStationSequence.cs index eeaffff..5cfaa10 100644 --- a/YandexMusic.API/Models/Radio/YStationSequence.cs +++ b/YandexMusic.API/Models/Radio/YStationSequence.cs @@ -1,11 +1,10 @@ -namespace YandexMusic.API.Models.Radio +namespace YandexMusic.API.Models.Radio; + +public class YStationSequence { - public class YStationSequence - { - public string BatchId { get; set; } - public YStationId Id { get; set; } - public bool Pumpkin { get; set; } - public string RadioSessionId { get; set; } - public List Sequence { get; set; } - } + public string BatchId { get; set; } + public YStationId Id { get; set; } + public bool Pumpkin { get; set; } + public string RadioSessionId { get; set; } + public List Sequence { get; set; } } \ No newline at end of file diff --git a/YandexMusic.API/Models/Radio/YStationSettings.cs b/YandexMusic.API/Models/Radio/YStationSettings.cs index e52eaba..9e7a185 100644 --- a/YandexMusic.API/Models/Radio/YStationSettings.cs +++ b/YandexMusic.API/Models/Radio/YStationSettings.cs @@ -1,10 +1,9 @@ -namespace YandexMusic.API.Models.Radio +namespace YandexMusic.API.Models.Radio; + +public class YStationSettings { - public class YStationSettings - { - public string Diversity { get; set; } - public string Energy { get; set; } - public string Language { get; set; } - public string Mood { get; set; } - } + public string Diversity { get; set; } + public string Energy { get; set; } + public string Language { get; set; } + public string Mood { get; set; } } \ No newline at end of file diff --git a/YandexMusic.API/Models/Radio/YStationSettings2.cs b/YandexMusic.API/Models/Radio/YStationSettings2.cs index e5fad02..0c7acf2 100644 --- a/YandexMusic.API/Models/Radio/YStationSettings2.cs +++ b/YandexMusic.API/Models/Radio/YStationSettings2.cs @@ -1,9 +1,8 @@ -namespace YandexMusic.API.Models.Radio +namespace YandexMusic.API.Models.Radio; + +public class YStationSettings2 { - public class YStationSettings2 - { - public string Diversity { get; set; } - public string Language { get; set; } - public string MoodEnergy { get; set; } - } + public string Diversity { get; set; } + public string Language { get; set; } + public string MoodEnergy { get; set; } } \ No newline at end of file diff --git a/YandexMusic.API/Models/Radio/YStationsDashboard.cs b/YandexMusic.API/Models/Radio/YStationsDashboard.cs index f9b7f6d..07f8b05 100644 --- a/YandexMusic.API/Models/Radio/YStationsDashboard.cs +++ b/YandexMusic.API/Models/Radio/YStationsDashboard.cs @@ -1,9 +1,8 @@ -namespace YandexMusic.API.Models.Radio +namespace YandexMusic.API.Models.Radio; + +public class YStationsDashboard { - public class YStationsDashboard - { - public string DashboardId { get; set; } - public bool Pumpkin { get; set; } - public List Stations { get; set; } - } + public string DashboardId { get; set; } + public bool Pumpkin { get; set; } + public List Stations { get; set; } } diff --git a/YandexMusic.API/Models/Radio/YTrackParameters.cs b/YandexMusic.API/Models/Radio/YTrackParameters.cs index e7ca49c..cb02f43 100644 --- a/YandexMusic.API/Models/Radio/YTrackParameters.cs +++ b/YandexMusic.API/Models/Radio/YTrackParameters.cs @@ -1,9 +1,8 @@ -namespace YandexMusic.API.Models.Radio +namespace YandexMusic.API.Models.Radio; + +public class YTrackParameters { - public class YTrackParameters - { - public int Bpm { get; set; } - public int Hue { get; set; } - public decimal Energy { get; set; } - } + public int Bpm { get; set; } + public int Hue { get; set; } + public decimal Energy { get; set; } } diff --git a/YandexMusic.API/Models/Search/Album/YSearchAlbumModel.cs b/YandexMusic.API/Models/Search/Album/YSearchAlbumModel.cs index e98ee42..7f3cf52 100644 --- a/YandexMusic.API/Models/Search/Album/YSearchAlbumModel.cs +++ b/YandexMusic.API/Models/Search/Album/YSearchAlbumModel.cs @@ -1,11 +1,10 @@ using YandexMusic.API.Models.Album; -namespace YandexMusic.API.Models.Search.Album +namespace YandexMusic.API.Models.Search.Album; + +public class YSearchAlbumModel : YAlbum { - public class YSearchAlbumModel : YAlbum - { - public List AvailableRegions { get; set; } - public int OriginalReleaseYear { get; set; } - public List Regions { get; set; } - } + public List AvailableRegions { get; set; } + public int OriginalReleaseYear { get; set; } + public List Regions { get; set; } } \ No newline at end of file diff --git a/YandexMusic.API/Models/Search/Artist/YSearchArtist.cs b/YandexMusic.API/Models/Search/Artist/YSearchArtist.cs index a8d6980..c015ef9 100644 --- a/YandexMusic.API/Models/Search/Artist/YSearchArtist.cs +++ b/YandexMusic.API/Models/Search/Artist/YSearchArtist.cs @@ -1,15 +1,15 @@ +using System.Text.Json.Serialization; using YandexMusic.API.Models.Common.Cover; -namespace YandexMusic.API.Models.Search.Artist +namespace YandexMusic.API.Models.Search.Artist; + +public class YSearchArtist { - public class YSearchArtist - { - public bool Composer { get; set; } - [JsonConverter(typeof(YCoverConverter))] - public YCover Cover { get; set; } - public List Decomposed { get; set; } - public string Id { get; set; } - public string Name { get; set; } - public bool Various { get; set; } - } + public bool Composer { get; set; } + [JsonConverter(typeof(YCoverConverter))] + public YCover Cover { get; set; } + public List Decomposed { get; set; } + public string Id { get; set; } + public string Name { get; set; } + public bool Various { get; set; } } \ No newline at end of file diff --git a/YandexMusic.API/Models/Search/Artist/YSearchArtistCounter.cs b/YandexMusic.API/Models/Search/Artist/YSearchArtistCounter.cs index d94de1b..187f236 100644 --- a/YandexMusic.API/Models/Search/Artist/YSearchArtistCounter.cs +++ b/YandexMusic.API/Models/Search/Artist/YSearchArtistCounter.cs @@ -1,10 +1,9 @@ -namespace YandexMusic.API.Models.Search.Artist +namespace YandexMusic.API.Models.Search.Artist; + +public class YSearchArtistCounter { - public class YSearchArtistCounter - { - public int? AlsoAlbums { get; set; } - public int? AlsoTracks { get; set; } - public int? DirectAlbums { get; set; } - public int? Tracks { get; set; } - } + public int? AlsoAlbums { get; set; } + public int? AlsoTracks { get; set; } + public int? DirectAlbums { get; set; } + public int? Tracks { get; set; } } \ No newline at end of file diff --git a/YandexMusic.API/Models/Search/Artist/YSearchArtistModel.cs b/YandexMusic.API/Models/Search/Artist/YSearchArtistModel.cs index 2ec7b5d..9ae6da8 100644 --- a/YandexMusic.API/Models/Search/Artist/YSearchArtistModel.cs +++ b/YandexMusic.API/Models/Search/Artist/YSearchArtistModel.cs @@ -1,11 +1,10 @@ using YandexMusic.API.Models.Artist; using YandexMusic.API.Models.Search.Track; -namespace YandexMusic.API.Models.Search.Artist +namespace YandexMusic.API.Models.Search.Artist; + +public class YSearchArtistModel : YArtist { - public class YSearchArtistModel : YArtist - { - public List PopularTracks { get; set; } - public List Regions { get; set; } - } + public List PopularTracks { get; set; } + public List Regions { get; set; } } \ No newline at end of file diff --git a/YandexMusic.API/Models/Search/Playlist/YSearchPlaylistModel.cs b/YandexMusic.API/Models/Search/Playlist/YSearchPlaylistModel.cs index 821c846..7919a36 100644 --- a/YandexMusic.API/Models/Search/Playlist/YSearchPlaylistModel.cs +++ b/YandexMusic.API/Models/Search/Playlist/YSearchPlaylistModel.cs @@ -1,10 +1,9 @@ using YandexMusic.API.Models.Playlist; -namespace YandexMusic.API.Models.Search.Playlist +namespace YandexMusic.API.Models.Search.Playlist; + +public class YSearchPlaylistModel : YPlaylist { - public class YSearchPlaylistModel : YPlaylist - { - public string CoverUri { get; set; } - public List Regions { get; set; } - } + public string CoverUri { get; set; } + public List Regions { get; set; } } \ No newline at end of file diff --git a/YandexMusic.API/Models/Search/Track/YSearchTrackModel.cs b/YandexMusic.API/Models/Search/Track/YSearchTrackModel.cs index 280199e..388cf89 100644 --- a/YandexMusic.API/Models/Search/Track/YSearchTrackModel.cs +++ b/YandexMusic.API/Models/Search/Track/YSearchTrackModel.cs @@ -1,13 +1,12 @@ using YandexMusic.API.Models.Search.Album; using YandexMusic.API.Models.Track; -namespace YandexMusic.API.Models.Search.Track +namespace YandexMusic.API.Models.Search.Track; + +public class YSearchTrackModel : YTrack { - public class YSearchTrackModel : YTrack - { - public new List Albums { get; set; } - public bool AvailableAsRbt { get; set; } - public bool Explicit { get; set; } - public List Regions { get; set; } - } + public new List Albums { get; set; } + public bool AvailableAsRbt { get; set; } + public bool Explicit { get; set; } + public List Regions { get; set; } } \ No newline at end of file diff --git a/YandexMusic.API/Models/Search/Track/YSearchTrackType.cs b/YandexMusic.API/Models/Search/Track/YSearchTrackType.cs index 4c9f798..9edf4f7 100644 --- a/YandexMusic.API/Models/Search/Track/YSearchTrackType.cs +++ b/YandexMusic.API/Models/Search/Track/YSearchTrackType.cs @@ -1,7 +1,6 @@ -namespace YandexMusic.API.Models.Search.Track +namespace YandexMusic.API.Models.Search.Track; + +public enum YSearchTrackType { - public enum YSearchTrackType - { - Music - } + Music, } diff --git a/YandexMusic.API/Models/Search/User/YSearchUserModel.cs b/YandexMusic.API/Models/Search/User/YSearchUserModel.cs index 668efd1..c4863bd 100644 --- a/YandexMusic.API/Models/Search/User/YSearchUserModel.cs +++ b/YandexMusic.API/Models/Search/User/YSearchUserModel.cs @@ -1,6 +1,5 @@ -namespace YandexMusic.API.Models.Search.User +namespace YandexMusic.API.Models.Search.User; + +public class YSearchUserModel { - public class YSearchUserModel - { - } } \ No newline at end of file diff --git a/YandexMusic.API/Models/Search/Video/YSearchVideoModel.cs b/YandexMusic.API/Models/Search/Video/YSearchVideoModel.cs index ce0d0c3..0bb481d 100644 --- a/YandexMusic.API/Models/Search/Video/YSearchVideoModel.cs +++ b/YandexMusic.API/Models/Search/Video/YSearchVideoModel.cs @@ -1,13 +1,12 @@ -namespace YandexMusic.API.Models.Search.Video +namespace YandexMusic.API.Models.Search.Video; + +public class YSearchVideoModel { - public class YSearchVideoModel - { - public int Duration { get; set; } - public string HtmlAutoPlayVideoPlayer { get; set; } - public List Regions { get; set; } - public string Text { get; set; } - public string ThumbnailUrl { get; set; } - public string Title { get; set; } - public string YoutubeUrl { get; set; } - } + public int Duration { get; set; } + public string HtmlAutoPlayVideoPlayer { get; set; } + public List Regions { get; set; } + public string Text { get; set; } + public string ThumbnailUrl { get; set; } + public string Title { get; set; } + public string YoutubeUrl { get; set; } } \ No newline at end of file diff --git a/YandexMusic.API/Models/Search/YSearch.cs b/YandexMusic.API/Models/Search/YSearch.cs index 79b560e..f1a827b 100644 --- a/YandexMusic.API/Models/Search/YSearch.cs +++ b/YandexMusic.API/Models/Search/YSearch.cs @@ -1,3 +1,4 @@ +using System.Text.Json.Serialization; using YandexMusic.API.Models.Common; using YandexMusic.API.Models.Search.Album; using YandexMusic.API.Models.Search.Artist; @@ -22,7 +23,7 @@ namespace YandexMusic.API.Models.Search public int Page { get; set; } public int PerPage { get; set; } public YSearchResult Playlists { get; set; } - [JsonProperty("podcast_episodes")] + [JsonPropertyName("podcast_episodes")] public YSearchResult PodcastEpisode { get; set; } public string SearchRequestId { get; set; } public string Text { get; set; } diff --git a/YandexMusic.API/Models/Search/YSearchBest.cs b/YandexMusic.API/Models/Search/YSearchBest.cs index 65eb083..89a9ff4 100644 --- a/YandexMusic.API/Models/Search/YSearchBest.cs +++ b/YandexMusic.API/Models/Search/YSearchBest.cs @@ -1,70 +1,14 @@ +using System.Text.Json.Serialization; using YandexMusic.API.Models.Common; -using YandexMusic.API.Models.Search.Album; -using YandexMusic.API.Models.Search.Artist; -using YandexMusic.API.Models.Search.Playlist; -using YandexMusic.API.Models.Search.Track; -using YandexMusic.API.Models.Search.Video; -namespace YandexMusic.API.Models.Search +namespace YandexMusic.API.Models.Search; + +/// Лучший результат поиска. +[JsonConverter(typeof(YSearchBestConverter))] +public class YSearchBest { - /// - /// Конвертер для поля Result - /// - internal class YSearchBestConverter : JsonConverter - { - public override bool CanConvert(Type objectType) - { - throw new NotImplementedException(); - } - - public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) - { - if (reader.TokenType == JsonToken.Null) - return null; - - JObject obj = JObject.Load(reader); - JsonObjectContract contract = (JsonObjectContract)serializer.ContractResolver.ResolveContract(objectType); - YSearchBest best = existingValue as YSearchBest ?? (YSearchBest)contract.DefaultCreator(); - - best.Type = (YSearchType)Enum.Parse(typeof(YSearchType), obj["type"].ToString(), true); - - switch (best.Type) - { - case YSearchType.Track: - best.Result = JsonConvert.DeserializeObject(obj["result"].ToString()); - break; - case YSearchType.Album: - best.Result = JsonConvert.DeserializeObject(obj["result"].ToString()); - break; - case YSearchType.Artist: - best.Result = JsonConvert.DeserializeObject(obj["result"].ToString()); - break; - case YSearchType.Playlist: - best.Result = JsonConvert.DeserializeObject(obj["result"].ToString()); - break; - case YSearchType.PodcastEpisode: - best.Result = JsonConvert.DeserializeObject(obj["result"].ToString()); - break; - case YSearchType.Video: - best.Result = JsonConvert.DeserializeObject(obj["result"].ToString()); - break; - } - - return best; - } - - public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) - { - throw new NotImplementedException(); - } - - public override bool CanWrite => false; - } - - [JsonConverter(typeof(YSearchBestConverter))] - public class YSearchBest - { - public dynamic Result { get; set; } - public YSearchType Type { get; set; } - } + /// Тип найденного объекта. + public YSearchType Type { get; set; } + /// Найденный объект (тип зависит от Type). + public object? Result { get; set; } } \ No newline at end of file diff --git a/YandexMusic.API/Models/Search/YSearchBestConverter.cs b/YandexMusic.API/Models/Search/YSearchBestConverter.cs new file mode 100644 index 0000000..a9e11a6 --- /dev/null +++ b/YandexMusic.API/Models/Search/YSearchBestConverter.cs @@ -0,0 +1,73 @@ +using System.Text.Json; +using System.Text.Json.Serialization; +using YandexMusic.API.Models.Common; +using YandexMusic.API.Models.Search.Album; +using YandexMusic.API.Models.Search.Artist; +using YandexMusic.API.Models.Search.Playlist; +using YandexMusic.API.Models.Search.Track; +using YandexMusic.API.Models.Search.Video; + +namespace YandexMusic.API.Models.Search; + +/// Конвертер для лучшего результата поиска (поле Best). Десериализует в конкретный тип в зависимости от значения поля type. +public class YSearchBestConverter : JsonConverter +{ + public override YSearchBest? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + { + if (reader.TokenType != JsonTokenType.StartObject) + throw new JsonException("Ожидается объект Best"); + + using var doc = JsonDocument.ParseValue(ref reader); + var root = doc.RootElement; + + var typeProp = root.GetProperty("type"); + var typeStr = typeProp.GetString(); + if (!Enum.TryParse(typeStr, true, out var searchType)) + throw new JsonException($"Неизвестный тип поиска: {typeStr}"); + + var resultElement = root.GetProperty("result"); + var resultRaw = resultElement.GetRawText(); + + object? result = null; + + switch (searchType) + { + case YSearchType.Track: + result = JsonSerializer.Deserialize(resultRaw, options); + break; + case YSearchType.Album: + result = JsonSerializer.Deserialize(resultRaw, options); + break; + case YSearchType.Artist: + result = JsonSerializer.Deserialize(resultRaw, options); + break; + case YSearchType.Playlist: + result = JsonSerializer.Deserialize(resultRaw, options); + break; + case YSearchType.PodcastEpisode: + result = JsonSerializer.Deserialize(resultRaw, options); + break; + case YSearchType.Video: + result = JsonSerializer.Deserialize(resultRaw, options); + break; + default: + result = null; + break; + } + + return new YSearchBest + { + Type = searchType, + Result = result + }; + } + + public override void Write(Utf8JsonWriter writer, YSearchBest value, JsonSerializerOptions options) + { + writer.WriteStartObject(); + writer.WriteString("type", value.Type.ToString().ToLowerInvariant()); + writer.WritePropertyName("result"); + JsonSerializer.Serialize(writer, value.Result, options); + writer.WriteEndObject(); + } +} \ No newline at end of file diff --git a/YandexMusic.API/Models/Search/YSearchResult.cs b/YandexMusic.API/Models/Search/YSearchResult.cs index fc76e46..6c8a745 100644 --- a/YandexMusic.API/Models/Search/YSearchResult.cs +++ b/YandexMusic.API/Models/Search/YSearchResult.cs @@ -1,10 +1,9 @@ -namespace YandexMusic.API.Models.Search +namespace YandexMusic.API.Models.Search; + +public class YSearchResult { - public class YSearchResult - { - public int Order { get; set; } - public int PerPage { get; set; } - public List Results { get; set; } - public int Total { get; set; } - } + public int Order { get; set; } + public int PerPage { get; set; } + public List Results { get; set; } + public int Total { get; set; } } \ No newline at end of file diff --git a/YandexMusic.API/Models/Search/YSearchSuggest.cs b/YandexMusic.API/Models/Search/YSearchSuggest.cs index 469f92a..ebd8d8e 100644 --- a/YandexMusic.API/Models/Search/YSearchSuggest.cs +++ b/YandexMusic.API/Models/Search/YSearchSuggest.cs @@ -1,8 +1,7 @@ -namespace YandexMusic.API.Models.Search +namespace YandexMusic.API.Models.Search; + +public class YSearchSuggest { - public class YSearchSuggest - { - public YSearchBest Best { get; set; } - public List Suggestions { get; set; } - } + public YSearchBest Best { get; set; } + public List Suggestions { get; set; } } \ No newline at end of file diff --git a/YandexMusic.API/Models/Track/YTrack.cs b/YandexMusic.API/Models/Track/YTrack.cs index d9a6bab..fe8de83 100644 --- a/YandexMusic.API/Models/Track/YTrack.cs +++ b/YandexMusic.API/Models/Track/YTrack.cs @@ -2,83 +2,82 @@ using YandexMusic.API.Models.Album; using YandexMusic.API.Models.Artist; using YandexMusic.API.Models.Common; -namespace YandexMusic.API.Models.Track +namespace YandexMusic.API.Models.Track; + +public class YTrack : YBaseModel, IEquatable { - public class YTrack : YBaseModel, IEquatable + public List Albums { get; set; } + public List Artists { get; set; } + public bool Available { get; set; } + public bool AvailableForPremiumUsers { get; set; } + public bool AvailableFullWithoutPermission { get; set; } + public List AvailableForOptions { get; set; } + public string BackgroundVideoUri { get; set; } + public bool Best { get; set; } + public YChart Chart { get; set; } + public string ContentWarning { get; set; } + public string CoverUri { get; set; } + public List ClipIds { get; set; } + public YDerivedColors DerivedColors { get; set; } + public List Disclaimers { get; set; } + public long DurationMs { get; set; } + public string Error { get; set; } + public YTrackFade Fade { get; set; } + public long FileSize { get; set; } + public string Id { get; set; } + public bool IsSuitableForChildren { get; set; } + public YMajor Major { get; set; } + public YTrackNormalization Normalization { get; set; } + public YTrackNormalizationR128 R128 { get; set; } + public string OgImage { get; set; } + public bool LyricsAvailable { get; set; } + public YLyricsInfo LyricsInfo { get; set; } + public string PlayerId { get; set; } + public long PreviewDurationMs { get; set; } + public YPodcastEpisodeType PodcastEpisodeType { get; set; } + public DateTime PubDate { get; set; } + public string RealId { get; set; } + public bool RememberPosition { get; set; } + public string ShortDescription { get; set; } + public List SpecialAudioResources { get; set; } + public string StorageDir { get; set; } + public YTrack Substituted { get; set; } + public string Title { get; set; } + public YTrackSharingFlag TrackSharingFlag { get; set; } + public YTrackSource TrackSource { get; set; } + public string Type { get; set; } + public string Version { get; set; } + + public YTrackAlbumPair GetKey() { - public List Albums { get; set; } - public List Artists { get; set; } - public bool Available { get; set; } - public bool AvailableForPremiumUsers { get; set; } - public bool AvailableFullWithoutPermission { get; set; } - public List AvailableForOptions { get; set; } - public string BackgroundVideoUri { get; set; } - public bool Best { get; set; } - public YChart Chart { get; set; } - public string ContentWarning { get; set; } - public string CoverUri { get; set; } - public List ClipIds { get; set; } - public YDerivedColors DerivedColors { get; set; } - public List Disclaimers { get; set; } - public long DurationMs { get; set; } - public string Error { get; set; } - public YTrackFade Fade { get; set; } - public long FileSize { get; set; } - public string Id { get; set; } - public bool IsSuitableForChildren { get; set; } - public YMajor Major { get; set; } - public YTrackNormalization Normalization { get; set; } - public YTrackNormalizationR128 R128 { get; set; } - public string OgImage { get; set; } - public bool LyricsAvailable { get; set; } - public YLyricsInfo LyricsInfo { get; set; } - public string PlayerId { get; set; } - public long PreviewDurationMs { get; set; } - public YPodcastEpisodeType PodcastEpisodeType { get; set; } - public DateTime PubDate { get; set; } - public string RealId { get; set; } - public bool RememberPosition { get; set; } - public string ShortDescription { get; set; } - public List SpecialAudioResources { get; set; } - public string StorageDir { get; set; } - public YTrack Substituted { get; set; } - public string Title { get; set; } - public YTrackSharingFlag TrackSharingFlag { get; set; } - public YTrackSource TrackSource { get; set; } - public string Type { get; set; } - public string Version { get; set; } - - public YTrackAlbumPair GetKey() + return new YTrackAlbumPair { - return new YTrackAlbumPair - { - Id = Id, - AlbumId = Albums?.FirstOrDefault()?.Id - }; - } - - #region IEquatable - - public bool Equals(YTrack other) - { - if (ReferenceEquals(null, other)) return false; - if (ReferenceEquals(this, other)) return true; - return GetKey().Equals(other.GetKey()); - } - - public override bool Equals(object obj) - { - if (ReferenceEquals(null, obj)) return false; - if (ReferenceEquals(this, obj)) return true; - if (obj.GetType() != GetType()) return false; - return Equals((YTrack)obj); - } - - public override int GetHashCode() - { - return GetKey().GetHashCode(); - } - - #endregion IEquatable + Id = Id, + AlbumId = Albums?.FirstOrDefault()?.Id + }; } + + #region IEquatable + + public bool Equals(YTrack other) + { + if (ReferenceEquals(null, other)) return false; + if (ReferenceEquals(this, other)) return true; + return GetKey().Equals(other.GetKey()); + } + + public override bool Equals(object obj) + { + if (ReferenceEquals(null, obj)) return false; + if (ReferenceEquals(this, obj)) return true; + if (obj.GetType() != GetType()) return false; + return Equals((YTrack)obj); + } + + public override int GetHashCode() + { + return GetKey().GetHashCode(); + } + + #endregion IEquatable } \ No newline at end of file diff --git a/YandexMusic.API/Models/Track/YTrackAlbumPair.cs b/YandexMusic.API/Models/Track/YTrackAlbumPair.cs index 4aff2ee..9d511b6 100644 --- a/YandexMusic.API/Models/Track/YTrackAlbumPair.cs +++ b/YandexMusic.API/Models/Track/YTrackAlbumPair.cs @@ -1,40 +1,35 @@ -namespace YandexMusic.API.Models.Track +namespace YandexMusic.API.Models.Track; + +public class YTrackAlbumPair : IEquatable { - public class YTrackAlbumPair : IEquatable + public string AlbumId { get; set; } + public string Id { get; set; } + + public override string ToString() { - public string AlbumId { get; set; } - public string Id { get; set; } + return string.Join(":", new[] { Id, AlbumId }.Where(s => !string.IsNullOrEmpty(s))); + } - public override string ToString() + public bool Equals(YTrackAlbumPair other) + { + if (ReferenceEquals(null, other)) return false; + if (ReferenceEquals(this, other)) return true; + return string.Equals(Id, other.Id) && string.Equals(AlbumId, other.AlbumId); + } + + public override bool Equals(object obj) + { + if (ReferenceEquals(null, obj)) return false; + if (ReferenceEquals(this, obj)) return true; + if (obj.GetType() != GetType()) return false; + return Equals((YTrackAlbumPair)obj); + } + + public override int GetHashCode() + { + unchecked { - return string.Join(":", new[] { Id, AlbumId }.Where(s => !string.IsNullOrEmpty(s))); + return ((Id != null ? Id.GetHashCode() : 0) * 397) ^ (AlbumId != null ? AlbumId.GetHashCode() : 0); } - - #region IEquatable - - public bool Equals(YTrackAlbumPair other) - { - if (ReferenceEquals(null, other)) return false; - if (ReferenceEquals(this, other)) return true; - return string.Equals(Id, other.Id) && string.Equals(AlbumId, other.AlbumId); - } - - public override bool Equals(object obj) - { - if (ReferenceEquals(null, obj)) return false; - if (ReferenceEquals(this, obj)) return true; - if (obj.GetType() != GetType()) return false; - return Equals((YTrackAlbumPair)obj); - } - - public override int GetHashCode() - { - unchecked - { - return ((Id != null ? Id.GetHashCode() : 0) * 397) ^ (AlbumId != null ? AlbumId.GetHashCode() : 0); - } - } - - #endregion IEquatable } } \ No newline at end of file diff --git a/YandexMusic.API/Models/Track/YTrackContainer.cs b/YandexMusic.API/Models/Track/YTrackContainer.cs index 055512b..1f44e5f 100644 --- a/YandexMusic.API/Models/Track/YTrackContainer.cs +++ b/YandexMusic.API/Models/Track/YTrackContainer.cs @@ -1,38 +1,33 @@ -namespace YandexMusic.API.Models.Track +namespace YandexMusic.API.Models.Track; + +public class YTrackContainer : IEquatable { - public class YTrackContainer : IEquatable + public string Id { get; set; } + public string AlbumId { get; set; } + public decimal OriginalIndex { get; set; } + public decimal OriginalShuffleIndex { get; set; } + + public bool Recent { get; set; } + public DateTime Timestamp { get; set; } + public YTrack Track { get; set; } + + public bool Equals(YTrackContainer other) { - public string Id { get; set; } - public string AlbumId { get; set; } - public decimal OriginalIndex { get; set; } - public decimal OriginalShuffleIndex { get; set; } + if (ReferenceEquals(null, other)) return false; + if (ReferenceEquals(this, other)) return true; + return Track.GetKey() == other.Track.GetKey(); + } - public bool Recent { get; set; } - public DateTime Timestamp { get; set; } - public YTrack Track { get; set; } + public override bool Equals(object obj) + { + if (ReferenceEquals(null, obj)) return false; + if (ReferenceEquals(this, obj)) return true; + if (obj.GetType() != GetType()) return false; + return Equals((YTrackContainer)obj); + } - #region IEquatable - - public bool Equals(YTrackContainer other) - { - if (ReferenceEquals(null, other)) return false; - if (ReferenceEquals(this, other)) return true; - return Track.GetKey() == other.Track.GetKey(); - } - - public override bool Equals(object obj) - { - if (ReferenceEquals(null, obj)) return false; - if (ReferenceEquals(this, obj)) return true; - if (obj.GetType() != GetType()) return false; - return Equals((YTrackContainer)obj); - } - - public override int GetHashCode() - { - return Track != null ? Track.GetHashCode() : 0; - } - - #endregion IEquatable + public override int GetHashCode() + { + return Track != null ? Track.GetHashCode() : 0; } } \ No newline at end of file diff --git a/YandexMusic.API/Models/Track/YTrackFade.cs b/YandexMusic.API/Models/Track/YTrackFade.cs index 759ba16..0de3cb6 100644 --- a/YandexMusic.API/Models/Track/YTrackFade.cs +++ b/YandexMusic.API/Models/Track/YTrackFade.cs @@ -1,10 +1,9 @@ -namespace YandexMusic.API.Models.Track +namespace YandexMusic.API.Models.Track; + +public class YTrackFade { - public class YTrackFade - { - public decimal InStart { get; set; } - public decimal InStop { get; set; } - public decimal OutStart { get; set; } - public decimal OutStop { get; set; } - } + public decimal InStart { get; set; } + public decimal InStop { get; set; } + public decimal OutStart { get; set; } + public decimal OutStop { get; set; } } \ No newline at end of file diff --git a/YandexMusic.API/Models/Track/YTrackNormalization.cs b/YandexMusic.API/Models/Track/YTrackNormalization.cs index 5a07529..0a07b04 100644 --- a/YandexMusic.API/Models/Track/YTrackNormalization.cs +++ b/YandexMusic.API/Models/Track/YTrackNormalization.cs @@ -1,8 +1,7 @@ -namespace YandexMusic.API.Models.Track +namespace YandexMusic.API.Models.Track; + +public class YTrackNormalization { - public class YTrackNormalization - { - public double Gain { get; set; } - public double Peak { get; set; } - } + public double Gain { get; set; } + public double Peak { get; set; } } \ No newline at end of file diff --git a/YandexMusic.API/Models/Track/YTrackNormalizationR128.cs b/YandexMusic.API/Models/Track/YTrackNormalizationR128.cs index 032aff6..f9a43f3 100644 --- a/YandexMusic.API/Models/Track/YTrackNormalizationR128.cs +++ b/YandexMusic.API/Models/Track/YTrackNormalizationR128.cs @@ -1,8 +1,7 @@ -namespace YandexMusic.API.Models.Track +namespace YandexMusic.API.Models.Track; + +public class YTrackNormalizationR128 { - public class YTrackNormalizationR128 - { - public double I { get; set; } - public double Tp { get; set; } - } + public double I { get; set; } + public double Tp { get; set; } } \ No newline at end of file diff --git a/YandexMusic.API/Models/Track/YTrackPosition.cs b/YandexMusic.API/Models/Track/YTrackPosition.cs index 435d83f..db0ac7c 100644 --- a/YandexMusic.API/Models/Track/YTrackPosition.cs +++ b/YandexMusic.API/Models/Track/YTrackPosition.cs @@ -1,8 +1,7 @@ -namespace YandexMusic.API.Models.Track +namespace YandexMusic.API.Models.Track; + +public class YTrackPosition { - public class YTrackPosition - { - public int? Index { get; set; } - public int? Volume { get; set; } - } + public int? Index { get; set; } + public int? Volume { get; set; } } \ No newline at end of file diff --git a/YandexMusic.API/Models/Track/YTrackSimilar.cs b/YandexMusic.API/Models/Track/YTrackSimilar.cs index bb2dbd0..c93df86 100644 --- a/YandexMusic.API/Models/Track/YTrackSimilar.cs +++ b/YandexMusic.API/Models/Track/YTrackSimilar.cs @@ -1,8 +1,7 @@ -namespace YandexMusic.API.Models.Track +namespace YandexMusic.API.Models.Track; + +public class YTrackSimilar { - public class YTrackSimilar - { - public YTrack Track { get; set; } - public List SimilarTracks { get; set; } - } + public YTrack Track { get; set; } + public List SimilarTracks { get; set; } } \ No newline at end of file diff --git a/YandexMusic.API/Models/Track/YTrackSupplement.cs b/YandexMusic.API/Models/Track/YTrackSupplement.cs index 8452a37..5ee7c8c 100644 --- a/YandexMusic.API/Models/Track/YTrackSupplement.cs +++ b/YandexMusic.API/Models/Track/YTrackSupplement.cs @@ -1,12 +1,11 @@ using YandexMusic.API.Models.Common; -namespace YandexMusic.API.Models.Track +namespace YandexMusic.API.Models.Track; + +public class YTrackSupplement { - public class YTrackSupplement - { - public string Id { get; set; } - public List Clips { get; set; } - public YLyrics Lyrics { get; set; } - public List Videos { get; set; } - } + public string Id { get; set; } + public List Clips { get; set; } + public YLyrics Lyrics { get; set; } + public List Videos { get; set; } } \ No newline at end of file diff --git a/YandexMusic.API/Models/Ugc/YUgcUpload.cs b/YandexMusic.API/Models/Ugc/YUgcUpload.cs index f9adb30..7bd8957 100644 --- a/YandexMusic.API/Models/Ugc/YUgcUpload.cs +++ b/YandexMusic.API/Models/Ugc/YUgcUpload.cs @@ -1,12 +1,13 @@ -namespace YandexMusic.API.Models.Ugc +using System.Text.Json.Serialization; + +namespace YandexMusic.API.Models.Ugc; + +public class YUgcUpload { - public class YUgcUpload - { - [JsonProperty("poll-result")] - public string PollResult { get; set; } - [JsonProperty("post-target")] - public string PostTarget { get; set; } - [JsonProperty("ugc-track-id")] - public string UgcTrackId { get; set; } - } + [JsonPropertyName("poll-result")] + public string PollResult { get; set; } + [JsonPropertyName("post-target")] + public string PostTarget { get; set; } + [JsonPropertyName("ugc-track-id")] + public string UgcTrackId { get; set; } } \ No newline at end of file diff --git a/YandexMusic.API/Models/Ynison/YYnisonDevice.cs b/YandexMusic.API/Models/Ynison/YYnisonDevice.cs index 196fefe..0b540e5 100644 --- a/YandexMusic.API/Models/Ynison/YYnisonDevice.cs +++ b/YandexMusic.API/Models/Ynison/YYnisonDevice.cs @@ -1,10 +1,9 @@ -namespace YandexMusic.API.Models.Ynison +namespace YandexMusic.API.Models.Ynison; + +public class YYnisonDevice { - public class YYnisonDevice - { - public YYnisonDeviceInfo Info { get; set; } - public YYnisonDeviceCapabilities Capabilities { get; set; } = new(); - public YYnisonDeviceVolumeInfo VolumeInfo { get; set; } = new(); - public bool IsShadow { get; set; } - } + public YYnisonDeviceInfo Info { get; set; } + public YYnisonDeviceCapabilities Capabilities { get; set; } = new(); + public YYnisonDeviceVolumeInfo VolumeInfo { get; set; } = new(); + public bool IsShadow { get; set; } } \ No newline at end of file diff --git a/YandexMusic.API/Models/Ynison/YYnisonDeviceCapabilities.cs b/YandexMusic.API/Models/Ynison/YYnisonDeviceCapabilities.cs index ae56d52..aa6e43f 100644 --- a/YandexMusic.API/Models/Ynison/YYnisonDeviceCapabilities.cs +++ b/YandexMusic.API/Models/Ynison/YYnisonDeviceCapabilities.cs @@ -1,9 +1,8 @@ -namespace YandexMusic.API.Models.Ynison +namespace YandexMusic.API.Models.Ynison; + +public class YYnisonDeviceCapabilities { - public class YYnisonDeviceCapabilities - { - public bool CanBePlayer { get; set; } - public bool CanBeRemoteController { get; set; } - public decimal VolumeGranularity { get; set; } - } + public bool CanBePlayer { get; set; } + public bool CanBeRemoteController { get; set; } + public decimal VolumeGranularity { get; set; } } \ No newline at end of file diff --git a/YandexMusic.API/Models/Ynison/YYnisonDeviceFull.cs b/YandexMusic.API/Models/Ynison/YYnisonDeviceFull.cs index d0fb6d1..59c5e3f 100644 --- a/YandexMusic.API/Models/Ynison/YYnisonDeviceFull.cs +++ b/YandexMusic.API/Models/Ynison/YYnisonDeviceFull.cs @@ -1,10 +1,9 @@ -namespace YandexMusic.API.Models.Ynison +namespace YandexMusic.API.Models.Ynison; + +public class YYnisonDeviceFull : YYnisonDevice { - public class YYnisonDeviceFull : YYnisonDevice - { - public YYnisonSession Session { get; set; } - public decimal Volume { get; set; } - // Эта опция даёт ошибку 500 при попытке отправки на инициализации - public bool IsOffline { get; set; } - } + public YYnisonSession Session { get; set; } + public decimal Volume { get; set; } + // Эта опция даёт ошибку 500 при попытке отправки на инициализации + public bool IsOffline { get; set; } } \ No newline at end of file diff --git a/YandexMusic.API/Models/Ynison/YYnisonDeviceInfo.cs b/YandexMusic.API/Models/Ynison/YYnisonDeviceInfo.cs index b852580..357d286 100644 --- a/YandexMusic.API/Models/Ynison/YYnisonDeviceInfo.cs +++ b/YandexMusic.API/Models/Ynison/YYnisonDeviceInfo.cs @@ -1,11 +1,10 @@ -namespace YandexMusic.API.Models.Ynison +namespace YandexMusic.API.Models.Ynison; + +public class YYnisonDeviceInfo { - public class YYnisonDeviceInfo - { - public string DeviceId { get; set; } - public string Type { get; set; } - public string Title { get; set; } - public string AppName { get; set; } - public string AppVersion { get; set; } - } + public string DeviceId { get; set; } + public string Type { get; set; } + public string Title { get; set; } + public string AppName { get; set; } + public string AppVersion { get; set; } } \ No newline at end of file diff --git a/YandexMusic.API/Models/Ynison/YYnisonDeviceVolumeInfo.cs b/YandexMusic.API/Models/Ynison/YYnisonDeviceVolumeInfo.cs index 6a5d8b6..bbe748f 100644 --- a/YandexMusic.API/Models/Ynison/YYnisonDeviceVolumeInfo.cs +++ b/YandexMusic.API/Models/Ynison/YYnisonDeviceVolumeInfo.cs @@ -1,8 +1,7 @@ -namespace YandexMusic.API.Models.Ynison +namespace YandexMusic.API.Models.Ynison; + +public class YYnisonDeviceVolumeInfo { - public class YYnisonDeviceVolumeInfo - { - public decimal Volume { get; set; } - public YYnisonVersion Version { get; set; } - } + public decimal Volume { get; set; } + public YYnisonVersion Version { get; set; } } \ No newline at end of file diff --git a/YandexMusic.API/Models/Ynison/YYnisonEntityContext.cs b/YandexMusic.API/Models/Ynison/YYnisonEntityContext.cs index 43d75c7..50bc5a8 100644 --- a/YandexMusic.API/Models/Ynison/YYnisonEntityContext.cs +++ b/YandexMusic.API/Models/Ynison/YYnisonEntityContext.cs @@ -1,7 +1,6 @@ -namespace YandexMusic.API.Models.Ynison +namespace YandexMusic.API.Models.Ynison; + +public enum YYnisonEntityContext { - public enum YYnisonEntityContext - { - BasedOnEntityByDefault - } + BasedOnEntityByDefault } \ No newline at end of file diff --git a/YandexMusic.API/Models/Ynison/YYnisonEntityType.cs b/YandexMusic.API/Models/Ynison/YYnisonEntityType.cs index 9db48c1..279c914 100644 --- a/YandexMusic.API/Models/Ynison/YYnisonEntityType.cs +++ b/YandexMusic.API/Models/Ynison/YYnisonEntityType.cs @@ -1,16 +1,15 @@ -namespace YandexMusic.API.Models.Ynison +namespace YandexMusic.API.Models.Ynison; + +public enum YYnisonEntityType { - public enum YYnisonEntityType - { - Unspecified, - Album, - Artist, - Various, - Radio, - Generative, - FmRadio, - VideoWave, - LocalTracks, - Playlist - } + Unspecified, + Album, + Artist, + Various, + Radio, + Generative, + FmRadio, + VideoWave, + LocalTracks, + Playlist, } \ No newline at end of file diff --git a/YandexMusic.API/Models/Ynison/YYnisonError.cs b/YandexMusic.API/Models/Ynison/YYnisonError.cs index e74c103..76b16c2 100644 --- a/YandexMusic.API/Models/Ynison/YYnisonError.cs +++ b/YandexMusic.API/Models/Ynison/YYnisonError.cs @@ -1,11 +1,10 @@ -namespace YandexMusic.API.Models.Ynison +namespace YandexMusic.API.Models.Ynison; + +public class YYnisonError { - public class YYnisonError - { - public YYnisonErrorDetails Details { get; set; } - public int GrpcCode { get; set; } - public int HttpCode { get; set; } - public string HttpStatus { get; set; } - public string Message { get; set; } - } + public YYnisonErrorDetails Details { get; set; } + public int GrpcCode { get; set; } + public int HttpCode { get; set; } + public string HttpStatus { get; set; } + public string Message { get; set; } } \ No newline at end of file diff --git a/YandexMusic.API/Models/Ynison/YYnisonErrorDetails.cs b/YandexMusic.API/Models/Ynison/YYnisonErrorDetails.cs index 090fd47..bb29d8c 100644 --- a/YandexMusic.API/Models/Ynison/YYnisonErrorDetails.cs +++ b/YandexMusic.API/Models/Ynison/YYnisonErrorDetails.cs @@ -1,8 +1,7 @@ -namespace YandexMusic.API.Models.Ynison +namespace YandexMusic.API.Models.Ynison; + +public class YYnisonErrorDetails { - public class YYnisonErrorDetails - { - public string YnisonErrorCode { get; set; } - public string YnisonBackoffMillis { get; set; } - } + public string YnisonErrorCode { get; set; } + public string YnisonBackoffMillis { get; set; } } \ No newline at end of file diff --git a/YandexMusic.API/Models/Ynison/YYnisonFullState.cs b/YandexMusic.API/Models/Ynison/YYnisonFullState.cs index d0c82ae..b214743 100644 --- a/YandexMusic.API/Models/Ynison/YYnisonFullState.cs +++ b/YandexMusic.API/Models/Ynison/YYnisonFullState.cs @@ -1,9 +1,8 @@ -namespace YandexMusic.API.Models.Ynison +namespace YandexMusic.API.Models.Ynison; + +public class YYnisonFullState { - public class YYnisonFullState - { - public YYnisonPlayerState PlayerState { get; set; } - public YYnisonDevice Device { get; set; } - public bool IsCurrentlyActive { get; set; } - } + public YYnisonPlayerState PlayerState { get; set; } + public YYnisonDevice Device { get; set; } + public bool IsCurrentlyActive { get; set; } } \ No newline at end of file diff --git a/YandexMusic.API/Models/Ynison/YYnisonId.cs b/YandexMusic.API/Models/Ynison/YYnisonId.cs index 6a30e35..74792ae 100644 --- a/YandexMusic.API/Models/Ynison/YYnisonId.cs +++ b/YandexMusic.API/Models/Ynison/YYnisonId.cs @@ -1,7 +1,6 @@ -namespace YandexMusic.API.Models.Ynison +namespace YandexMusic.API.Models.Ynison; + +public class YYnisonId { - public class YYnisonId - { - public string Id { get; set; } - } + public string Id { get; set; } } \ No newline at end of file diff --git a/YandexMusic.API/Models/Ynison/YYnisonKeepAliveParams.cs b/YandexMusic.API/Models/Ynison/YYnisonKeepAliveParams.cs index 21e5990..edd6ce0 100644 --- a/YandexMusic.API/Models/Ynison/YYnisonKeepAliveParams.cs +++ b/YandexMusic.API/Models/Ynison/YYnisonKeepAliveParams.cs @@ -1,8 +1,7 @@ -namespace YandexMusic.API.Models.Ynison +namespace YandexMusic.API.Models.Ynison; + +public class YYnisonKeepAliveParams { - public class YYnisonKeepAliveParams - { - public int KeepAliveTimeSeconds { get; set; } - public int KeepAliveTimeoutSeconds { get; set; } - } + public int KeepAliveTimeSeconds { get; set; } + public int KeepAliveTimeoutSeconds { get; set; } } \ No newline at end of file diff --git a/YandexMusic.API/Models/Ynison/YYnisonPlayableItem.cs b/YandexMusic.API/Models/Ynison/YYnisonPlayableItem.cs index 69de6ce..779a39a 100644 --- a/YandexMusic.API/Models/Ynison/YYnisonPlayableItem.cs +++ b/YandexMusic.API/Models/Ynison/YYnisonPlayableItem.cs @@ -1,20 +1,18 @@ -namespace YandexMusic.API.Models.Ynison +namespace YandexMusic.API.Models.Ynison; + +public class YYnisonPlayableItem { - public class YYnisonPlayableItem - { - public string AlbumIdOptional { get; set; } + public string AlbumIdOptional { get; set; } - public string CoverUrlOptional { get; set; } + public string CoverUrlOptional { get; set; } -#warning нужен enum - public string From { get; set; } + public string From { get; set; } - public string PlayableId { get; set; } + public string PlayableId { get; set; } - public YYnisonPlayableItemType PlayableType { get; set; } + public YYnisonPlayableItemType PlayableType { get; set; } - public string Title { get; set; } + public string Title { get; set; } - public YYnisonTrackInfo TrackInfo { get; set; } - } + public YYnisonTrackInfo TrackInfo { get; set; } } \ No newline at end of file diff --git a/YandexMusic.API/Models/Ynison/YYnisonPlayableItemType.cs b/YandexMusic.API/Models/Ynison/YYnisonPlayableItemType.cs index 5649d80..b2bcd1e 100644 --- a/YandexMusic.API/Models/Ynison/YYnisonPlayableItemType.cs +++ b/YandexMusic.API/Models/Ynison/YYnisonPlayableItemType.cs @@ -1,7 +1,6 @@ -namespace YandexMusic.API.Models.Ynison +namespace YandexMusic.API.Models.Ynison; + +public enum YYnisonPlayableItemType { - public enum YYnisonPlayableItemType - { - Track - } + Track } \ No newline at end of file diff --git a/YandexMusic.API/Models/Ynison/YYnisonPlayerQueue.cs b/YandexMusic.API/Models/Ynison/YYnisonPlayerQueue.cs index 2b95bd8..f97712b 100644 --- a/YandexMusic.API/Models/Ynison/YYnisonPlayerQueue.cs +++ b/YandexMusic.API/Models/Ynison/YYnisonPlayerQueue.cs @@ -1,22 +1,21 @@ -namespace YandexMusic.API.Models.Ynison +namespace YandexMusic.API.Models.Ynison; + +public class YYnisonPlayerQueue { - public class YYnisonPlayerQueue - { - public int CurrentPlayableIndex { get; set; } = -1; + public int CurrentPlayableIndex { get; set; } = -1; - public string EntityId { get; set; } + public string EntityId { get; set; } - public YYnisonEntityType EntityType { get; set; } = YYnisonEntityType.Various; + public YYnisonEntityType EntityType { get; set; } = YYnisonEntityType.Various; - public YYnisonEntityContext EntityContext { get; set; } = YYnisonEntityContext.BasedOnEntityByDefault; + public YYnisonEntityContext EntityContext { get; set; } = YYnisonEntityContext.BasedOnEntityByDefault; - public YYnisonQueueOptions Options { get; set; } = new(); + public YYnisonQueueOptions Options { get; set; } = new(); - public List PlayableList { get; set; } = new(); - public YYnisonQueue Queue { get; set; } + public List PlayableList { get; set; } = new(); + public YYnisonQueue Queue { get; set; } - public string FromOptional { get; set; } + public string FromOptional { get; set; } - public YYnisonVersion Version { get; set; } - } + public YYnisonVersion Version { get; set; } } \ No newline at end of file diff --git a/YandexMusic.API/Models/Ynison/YYnisonPlayerState.cs b/YandexMusic.API/Models/Ynison/YYnisonPlayerState.cs index 5c00c68..af592f9 100644 --- a/YandexMusic.API/Models/Ynison/YYnisonPlayerState.cs +++ b/YandexMusic.API/Models/Ynison/YYnisonPlayerState.cs @@ -1,9 +1,8 @@ -namespace YandexMusic.API.Models.Ynison -{ - public class YYnisonPlayerState - { - public YYnisonPlayerQueue PlayerQueue { get; set; } +namespace YandexMusic.API.Models.Ynison; - public YYnisonPlayerStateStatus Status { get; set; } - } +public class YYnisonPlayerState +{ + public YYnisonPlayerQueue PlayerQueue { get; set; } + + public YYnisonPlayerStateStatus Status { get; set; } } \ No newline at end of file diff --git a/YandexMusic.API/Models/Ynison/YYnisonPlayerStateStatus.cs b/YandexMusic.API/Models/Ynison/YYnisonPlayerStateStatus.cs index 3f8f0c4..04a6091 100644 --- a/YandexMusic.API/Models/Ynison/YYnisonPlayerStateStatus.cs +++ b/YandexMusic.API/Models/Ynison/YYnisonPlayerStateStatus.cs @@ -1,11 +1,10 @@ -namespace YandexMusic.API.Models.Ynison +namespace YandexMusic.API.Models.Ynison; + +public class YYnisonPlayerStateStatus { - public class YYnisonPlayerStateStatus - { - public decimal DurationMs { get; set; } - public bool Paused { get; set; } = true; - public decimal PlaybackSpeed { get; set; } = 1; - public decimal ProgressMs { get; set; } - public YYnisonVersion Version { get; set; } - } + public decimal DurationMs { get; set; } + public bool Paused { get; set; } = true; + public decimal PlaybackSpeed { get; set; } = 1; + public decimal ProgressMs { get; set; } + public YYnisonVersion Version { get; set; } } \ No newline at end of file diff --git a/YandexMusic.API/Models/Ynison/YYnisonQueue.cs b/YandexMusic.API/Models/Ynison/YYnisonQueue.cs index 6f92d31..ee21156 100644 --- a/YandexMusic.API/Models/Ynison/YYnisonQueue.cs +++ b/YandexMusic.API/Models/Ynison/YYnisonQueue.cs @@ -1,9 +1,8 @@ using YandexMusic.API.Models.Ynison.Wave; -namespace YandexMusic.API.Models.Ynison +namespace YandexMusic.API.Models.Ynison; + +public class YYnisonQueue { - public class YYnisonQueue - { - public YYnisonWaveQueue WaveQueue { get; set; } - } + public YYnisonWaveQueue WaveQueue { get; set; } } \ No newline at end of file diff --git a/YandexMusic.API/Models/Ynison/YYnisonQueueOptions.cs b/YandexMusic.API/Models/Ynison/YYnisonQueueOptions.cs index 781e988..a7f2532 100644 --- a/YandexMusic.API/Models/Ynison/YYnisonQueueOptions.cs +++ b/YandexMusic.API/Models/Ynison/YYnisonQueueOptions.cs @@ -1,8 +1,6 @@ -namespace YandexMusic.API.Models.Ynison +namespace YandexMusic.API.Models.Ynison; + +public class YYnisonQueueOptions { - public class YYnisonQueueOptions - { -#warning нужен enum - public string RepeatMode { get; set; } = "NONE"; - } + public string RepeatMode { get; set; } = "NONE"; } \ No newline at end of file diff --git a/YandexMusic.API/Models/Ynison/YYnisonRedirect.cs b/YandexMusic.API/Models/Ynison/YYnisonRedirect.cs index 1536a63..84d310b 100644 --- a/YandexMusic.API/Models/Ynison/YYnisonRedirect.cs +++ b/YandexMusic.API/Models/Ynison/YYnisonRedirect.cs @@ -1,10 +1,9 @@ -namespace YandexMusic.API.Models.Ynison +namespace YandexMusic.API.Models.Ynison; + +public class YYnisonRedirect { - public class YYnisonRedirect - { - public string Host { get; set; } - public string RedirectTicket { get; set; } - public string SessionId { get; set; } - public YYnisonKeepAliveParams KeepAliveParams { get; set; } - } + public string Host { get; set; } + public string RedirectTicket { get; set; } + public string SessionId { get; set; } + public YYnisonKeepAliveParams KeepAliveParams { get; set; } } \ No newline at end of file diff --git a/YandexMusic.API/Models/Ynison/YYnisonSession.cs b/YandexMusic.API/Models/Ynison/YYnisonSession.cs index 851754b..70bc56b 100644 --- a/YandexMusic.API/Models/Ynison/YYnisonSession.cs +++ b/YandexMusic.API/Models/Ynison/YYnisonSession.cs @@ -1,7 +1,6 @@ -namespace YandexMusic.API.Models.Ynison -{ - public class YYnisonSession : YYnisonId - { +namespace YandexMusic.API.Models.Ynison; + +public class YYnisonSession : YYnisonId +{ - } } \ No newline at end of file diff --git a/YandexMusic.API/Models/Ynison/YYnisonState.cs b/YandexMusic.API/Models/Ynison/YYnisonState.cs index a831547..72c58e1 100644 --- a/YandexMusic.API/Models/Ynison/YYnisonState.cs +++ b/YandexMusic.API/Models/Ynison/YYnisonState.cs @@ -1,11 +1,10 @@ using YandexMusic.API.Models.Ynison.Messages; -namespace YandexMusic.API.Models.Ynison +namespace YandexMusic.API.Models.Ynison; + +public class YYnisonState : YYnisonMessage { - public class YYnisonState : YYnisonMessage - { - public List Devices { get; set; } - public YYnisonPlayerState PlayerState { get; set; } - public decimal TimestampMs { get; set; } - } + public List Devices { get; set; } + public YYnisonPlayerState PlayerState { get; set; } + public decimal TimestampMs { get; set; } } \ No newline at end of file diff --git a/YandexMusic.API/Models/Ynison/YYnisonTrackInfo.cs b/YandexMusic.API/Models/Ynison/YYnisonTrackInfo.cs index 1aad080..6544188 100644 --- a/YandexMusic.API/Models/Ynison/YYnisonTrackInfo.cs +++ b/YandexMusic.API/Models/Ynison/YYnisonTrackInfo.cs @@ -1,7 +1,6 @@ -namespace YandexMusic.API.Models.Ynison +namespace YandexMusic.API.Models.Ynison; + +public class YYnisonTrackInfo { - public class YYnisonTrackInfo - { - public decimal TrackSourceKey { get; set; } - } + public decimal TrackSourceKey { get; set; } } \ No newline at end of file diff --git a/YandexMusic.API/Models/Ynison/YYnisonVersion.cs b/YandexMusic.API/Models/Ynison/YYnisonVersion.cs index f2d0a73..6878b4b 100644 --- a/YandexMusic.API/Models/Ynison/YYnisonVersion.cs +++ b/YandexMusic.API/Models/Ynison/YYnisonVersion.cs @@ -1,9 +1,8 @@ -namespace YandexMusic.API.Models.Ynison +namespace YandexMusic.API.Models.Ynison; + +public class YYnisonVersion { - public class YYnisonVersion - { - public string DeviceId { get; set; } - public string Version { get; set; } = Math.Floor(0x8000000000000000 * new Random().NextDouble()).ToString("##############################") + "0"; - public decimal TimestampMs { get; set; } = DateTimeOffset.Now.ToUnixTimeMilliseconds(); - } + public string DeviceId { get; set; } + public string Version { get; set; } = Math.Floor(0x8000000000000000 * new Random().NextDouble()).ToString("##############################") + "0"; + public decimal TimestampMs { get; set; } = DateTimeOffset.Now.ToUnixTimeMilliseconds(); } \ No newline at end of file diff --git a/YandexMusic.API/Requests/Account/YGetAuthAppPasswordBuilder.cs b/YandexMusic.API/Requests/Account/YGetAuthAppPasswordBuilder.cs index a8d019f..db263c8 100644 --- a/YandexMusic.API/Requests/Account/YGetAuthAppPasswordBuilder.cs +++ b/YandexMusic.API/Requests/Account/YGetAuthAppPasswordBuilder.cs @@ -5,23 +5,22 @@ using YandexMusic.API.Models.Account; using YandexMusic.API.Requests.Common; using YandexMusic.API.Requests.Common.Attributes; -namespace YandexMusic.API.Requests.Account -{ - [YPassportRequest(WebRequestMethods.Http.Post, "registration-validations/auth/multi_step/commit_password")] - internal class YGetAuthAppPasswordBuilder : YRequestBuilder - { - public YGetAuthAppPasswordBuilder(YandexMusicApi yandex, AuthStorage auth) : base(yandex, auth) - { - } +namespace YandexMusic.API.Requests.Account; - protected override HttpContent GetContent(string tuple) - { - return new FormUrlEncodedContent(new Dictionary { - { "csrf_token", storage.AuthToken.CsfrToken }, - { "track_id", storage.AuthToken.TrackId }, - { "password", tuple }, - { "retpath", "https://passport.yandex.ru/am/finish?status=ok&from=Login" } - }); - } +[YPassportRequest(WebRequestMethods.Http.Post, "registration-validations/auth/multi_step/commit_password")] +internal class YGetAuthAppPasswordBuilder : YRequestBuilder +{ + public YGetAuthAppPasswordBuilder(YandexMusicApi yandex, AuthStorage auth) : base(yandex, auth) + { + } + + protected override HttpContent GetContent(string tuple) + { + return new FormUrlEncodedContent(new Dictionary { + { "csrf_token", storage.AuthToken.CsfrToken }, + { "track_id", storage.AuthToken.TrackId }, + { "password", tuple }, + { "retpath", "https://passport.yandex.ru/am/finish?status=ok&from=Login" } + }); } } \ No newline at end of file diff --git a/YandexMusic.API/Requests/Account/YGetAuthCaptchaBuilder.cs b/YandexMusic.API/Requests/Account/YGetAuthCaptchaBuilder.cs index 2ade7a6..2e6f111 100644 --- a/YandexMusic.API/Requests/Account/YGetAuthCaptchaBuilder.cs +++ b/YandexMusic.API/Requests/Account/YGetAuthCaptchaBuilder.cs @@ -5,26 +5,25 @@ using YandexMusic.API.Common; using YandexMusic.API.Requests.Common; using YandexMusic.API.Requests.Common.Attributes; -namespace YandexMusic.API.Requests.Account +namespace YandexMusic.API.Requests.Account; + +[YPassportRequest(WebRequestMethods.Http.Post, "registration-validations/textcaptcha")] +internal class YGetAuthCaptchaBuilder : YRequestBuilder { - [YPassportRequest(WebRequestMethods.Http.Post, "registration-validations/textcaptcha")] - internal class YGetAuthCaptchaBuilder : YRequestBuilder + public YGetAuthCaptchaBuilder(YandexMusicApi yandex, AuthStorage auth) : base(yandex, auth) { - public YGetAuthCaptchaBuilder(YandexMusicApi yandex, AuthStorage auth) : base(yandex, auth) - { - } + } - protected override HttpContent GetContent(string tuple) - { - return new FormUrlEncodedContent(new Dictionary { - { "csrf_token", storage.AuthToken.CsfrToken }, - { "track_id", storage.AuthToken.TrackId }, - }); - } + protected override HttpContent GetContent(string tuple) + { + return new FormUrlEncodedContent(new Dictionary { + { "csrf_token", storage.AuthToken.CsfrToken }, + { "track_id", storage.AuthToken.TrackId }, + }); + } - protected override void SetCustomHeaders(HttpRequestHeaders headers) - { - headers.Add("X-Requested-With", "XMLHttpRequest"); - } + protected override void SetCustomHeaders(HttpRequestHeaders headers) + { + headers.Add("X-Requested-With", "XMLHttpRequest"); } } \ No newline at end of file diff --git a/YandexMusic.API/Requests/Account/YGetAuthCookiesBuilder.cs b/YandexMusic.API/Requests/Account/YGetAuthCookiesBuilder.cs index e97f4e1..8b66c39 100644 --- a/YandexMusic.API/Requests/Account/YGetAuthCookiesBuilder.cs +++ b/YandexMusic.API/Requests/Account/YGetAuthCookiesBuilder.cs @@ -6,32 +6,31 @@ using YandexMusic.API.Models.Account; using YandexMusic.API.Requests.Common; using YandexMusic.API.Requests.Common.Attributes; -namespace YandexMusic.API.Requests.Account +namespace YandexMusic.API.Requests.Account; + +[YMobileProxyRequest(WebRequestMethods.Http.Post, "1/bundle/oauth/token_by_sessionid")] +internal class YGetAuthCookiesBuilder : YRequestBuilder { - [YMobileProxyRequest(WebRequestMethods.Http.Post, "1/bundle/oauth/token_by_sessionid")] - internal class YGetAuthCookiesBuilder : YRequestBuilder + public YGetAuthCookiesBuilder(YandexMusicApi yandex, AuthStorage auth) : base(yandex, auth) { - public YGetAuthCookiesBuilder(YandexMusicApi yandex, AuthStorage auth) : base(yandex, auth) - { - } + } - protected override void SetCustomHeaders(HttpRequestHeaders headers) - { - CookieCollection cookieCollection = new() { - storage.Context.Cookies.GetCookies(new Uri("https://yandex.ru/")), - storage.Context.Cookies.GetCookies(new Uri("https://passport.yandex.ru/")) - }; + protected override void SetCustomHeaders(HttpRequestHeaders headers) + { + CookieCollection cookieCollection = new() { + storage.Context.Cookies.GetCookies(new Uri("https://yandex.ru/")), + storage.Context.Cookies.GetCookies(new Uri("https://passport.yandex.ru/")) + }; - headers.Add("Ya-Client-Cookie", string.Join(";", cookieCollection.Select(c => $"{c.Name}={c.Value}"))); - headers.Add("Ya-Client-Host", "passport.yandex.ru"); - } + headers.Add("Ya-Client-Cookie", string.Join(";", cookieCollection.Select(c => $"{c.Name}={c.Value}"))); + headers.Add("Ya-Client-Host", "passport.yandex.ru"); + } - protected override HttpContent GetContent(string tuple) - { - return new FormUrlEncodedContent(new Dictionary { - { "client_id", YConstants.XClientId }, - { "client_secret", YConstants.XClientSecret } - }); - } + protected override HttpContent GetContent(string tuple) + { + return new FormUrlEncodedContent(new Dictionary { + { "client_id", YConstants.XClientId }, + { "client_secret", YConstants.XClientSecret } + }); } } \ No newline at end of file diff --git a/YandexMusic.API/Requests/Account/YGetAuthInfoBuilder.cs b/YandexMusic.API/Requests/Account/YGetAuthInfoBuilder.cs index bad7e32..69b5cf6 100644 --- a/YandexMusic.API/Requests/Account/YGetAuthInfoBuilder.cs +++ b/YandexMusic.API/Requests/Account/YGetAuthInfoBuilder.cs @@ -6,13 +6,12 @@ using YandexMusic.API.Models.Common; using YandexMusic.API.Requests.Common; using YandexMusic.API.Requests.Common.Attributes; -namespace YandexMusic.API.Requests.Account +namespace YandexMusic.API.Requests.Account; + +[YApiRequest(WebRequestMethods.Http.Get, "account/status")] +public class YGetAuthInfoBuilder : YRequestBuilder, object> { - [YApiRequest(WebRequestMethods.Http.Get, "account/status")] - public class YGetAuthInfoBuilder : YRequestBuilder, object> + public YGetAuthInfoBuilder(YandexMusicApi yandex, AuthStorage auth) : base(yandex, auth) { - public YGetAuthInfoBuilder(YandexMusicApi yandex, AuthStorage auth) : base(yandex, auth) - { - } } } \ No newline at end of file diff --git a/YandexMusic.API/Requests/Account/YGetAuthLetterBuilder.cs b/YandexMusic.API/Requests/Account/YGetAuthLetterBuilder.cs index 1059b89..7e50ca0 100644 --- a/YandexMusic.API/Requests/Account/YGetAuthLetterBuilder.cs +++ b/YandexMusic.API/Requests/Account/YGetAuthLetterBuilder.cs @@ -4,27 +4,26 @@ using YandexMusic.API.Common; using YandexMusic.API.Requests.Common; using YandexMusic.API.Requests.Common.Attributes; -namespace YandexMusic.API.Requests.Account +namespace YandexMusic.API.Requests.Account; + +[YPassportRequest(WebRequestMethods.Http.Post, "registration-validations/auth/send_magic_letter")] +internal class YGetAuthLetterBuilder : YRequestBuilder { - [YPassportRequest(WebRequestMethods.Http.Post, "registration-validations/auth/send_magic_letter")] - internal class YGetAuthLetterBuilder : YRequestBuilder + public YGetAuthLetterBuilder(YandexMusicApi yandex, AuthStorage auth) : base(yandex, auth) { - public YGetAuthLetterBuilder(YandexMusicApi yandex, AuthStorage auth) : base(yandex, auth) + } + + protected override HttpContent GetContent(string tuple) + { + if (storage.AuthToken == null) { + throw new Exception("Не найдена сессия входа."); } - protected override HttpContent GetContent(string tuple) + return new FormUrlEncodedContent(new Dictionary { - if (storage.AuthToken == null) - { - throw new Exception("Не найдена сессия входа."); - } - - return new FormUrlEncodedContent(new Dictionary - { - { "csrf_token", storage.AuthToken.CsfrToken }, - { "track_id", storage.AuthToken.TrackId }, - }); - } + { "csrf_token", storage.AuthToken.CsfrToken }, + { "track_id", storage.AuthToken.TrackId }, + }); } } \ No newline at end of file diff --git a/YandexMusic.API/Requests/Account/YGetAuthLoginCaptchaBuilder.cs b/YandexMusic.API/Requests/Account/YGetAuthLoginCaptchaBuilder.cs index 4a90466..6536013 100644 --- a/YandexMusic.API/Requests/Account/YGetAuthLoginCaptchaBuilder.cs +++ b/YandexMusic.API/Requests/Account/YGetAuthLoginCaptchaBuilder.cs @@ -6,27 +6,26 @@ using YandexMusic.API.Models.Account; using YandexMusic.API.Requests.Common; using YandexMusic.API.Requests.Common.Attributes; -namespace YandexMusic.API.Requests.Account +namespace YandexMusic.API.Requests.Account; + +[YPassportRequest(WebRequestMethods.Http.Post, "registration-validations/checkHuman")] +internal class YGetAuthLoginCaptchaBuilder : YRequestBuilder { - [YPassportRequest(WebRequestMethods.Http.Post, "registration-validations/checkHuman")] - internal class YGetAuthLoginCaptchaBuilder : YRequestBuilder + public YGetAuthLoginCaptchaBuilder(YandexMusicApi yandex, AuthStorage auth) : base(yandex, auth) { - public YGetAuthLoginCaptchaBuilder(YandexMusicApi yandex, AuthStorage auth) : base(yandex, auth) - { - } + } - protected override HttpContent GetContent(string tuple) - { - return new FormUrlEncodedContent(new Dictionary { - { "csrf_token", storage.AuthToken.CsfrToken }, - { "track_id", storage.AuthToken.TrackId }, - { "answer", tuple } - }); - } + protected override HttpContent GetContent(string tuple) + { + return new FormUrlEncodedContent(new Dictionary { + { "csrf_token", storage.AuthToken.CsfrToken }, + { "track_id", storage.AuthToken.TrackId }, + { "answer", tuple } + }); + } - protected override void SetCustomHeaders(HttpRequestHeaders headers) - { - headers.Add("X-Requested-With", "XMLHttpRequest"); - } + protected override void SetCustomHeaders(HttpRequestHeaders headers) + { + headers.Add("X-Requested-With", "XMLHttpRequest"); } } \ No newline at end of file diff --git a/YandexMusic.API/Requests/Account/YGetAuthLoginLetterBuilder.cs b/YandexMusic.API/Requests/Account/YGetAuthLoginLetterBuilder.cs index 4eb7d33..17866b2 100644 --- a/YandexMusic.API/Requests/Account/YGetAuthLoginLetterBuilder.cs +++ b/YandexMusic.API/Requests/Account/YGetAuthLoginLetterBuilder.cs @@ -5,21 +5,20 @@ using YandexMusic.API.Models.Account; using YandexMusic.API.Requests.Common; using YandexMusic.API.Requests.Common.Attributes; -namespace YandexMusic.API.Requests.Account -{ - [YPassportRequest(WebRequestMethods.Http.Post, "auth/letter/status/")] - internal class YGetAuthLoginLetterBuilder : YRequestBuilder - { - public YGetAuthLoginLetterBuilder(YandexMusicApi yandex, AuthStorage auth) : base(yandex, auth) - { - } +namespace YandexMusic.API.Requests.Account; - protected override HttpContent GetContent(string tuple) - { - return new FormUrlEncodedContent(new Dictionary { - { "csrf_token", storage.AuthToken.CsfrToken }, - { "track_id", storage.AuthToken.TrackId }, - }); - } +[YPassportRequest(WebRequestMethods.Http.Post, "auth/letter/status/")] +internal class YGetAuthLoginLetterBuilder : YRequestBuilder +{ + public YGetAuthLoginLetterBuilder(YandexMusicApi yandex, AuthStorage auth) : base(yandex, auth) + { + } + + protected override HttpContent GetContent(string tuple) + { + return new FormUrlEncodedContent(new Dictionary { + { "csrf_token", storage.AuthToken.CsfrToken }, + { "track_id", storage.AuthToken.TrackId }, + }); } } \ No newline at end of file diff --git a/YandexMusic.API/Requests/Account/YGetAuthLoginQRBuilder.cs b/YandexMusic.API/Requests/Account/YGetAuthLoginQRBuilder.cs index 6d0954b..2d038f2 100644 --- a/YandexMusic.API/Requests/Account/YGetAuthLoginQRBuilder.cs +++ b/YandexMusic.API/Requests/Account/YGetAuthLoginQRBuilder.cs @@ -5,21 +5,20 @@ using YandexMusic.API.Models.Account; using YandexMusic.API.Requests.Common; using YandexMusic.API.Requests.Common.Attributes; -namespace YandexMusic.API.Requests.Account -{ - [YPassportRequest(WebRequestMethods.Http.Post, "auth/new/magic/status/")] - internal class YGetAuthLoginQRBuilder : YRequestBuilder - { - public YGetAuthLoginQRBuilder(YandexMusicApi yandex, AuthStorage auth) : base(yandex, auth) - { - } +namespace YandexMusic.API.Requests.Account; - protected override HttpContent GetContent(string tuple) - { - return new FormUrlEncodedContent(new Dictionary { - { "csrf_token", storage.AuthToken.CsfrToken }, - { "track_id", storage.AuthToken.TrackId } - }); - } +[YPassportRequest(WebRequestMethods.Http.Post, "auth/new/magic/status/")] +internal class YGetAuthLoginQRBuilder : YRequestBuilder +{ + public YGetAuthLoginQRBuilder(YandexMusicApi yandex, AuthStorage auth) : base(yandex, auth) + { + } + + protected override HttpContent GetContent(string tuple) + { + return new FormUrlEncodedContent(new Dictionary { + { "csrf_token", storage.AuthToken.CsfrToken }, + { "track_id", storage.AuthToken.TrackId } + }); } } \ No newline at end of file diff --git a/YandexMusic.API/Requests/Account/YGetAuthLoginUserBuilder.cs b/YandexMusic.API/Requests/Account/YGetAuthLoginUserBuilder.cs index 1ea5fd0..658ce4a 100644 --- a/YandexMusic.API/Requests/Account/YGetAuthLoginUserBuilder.cs +++ b/YandexMusic.API/Requests/Account/YGetAuthLoginUserBuilder.cs @@ -5,21 +5,20 @@ using YandexMusic.API.Models.Account; using YandexMusic.API.Requests.Common; using YandexMusic.API.Requests.Common.Attributes; -namespace YandexMusic.API.Requests.Account -{ - [YPassportRequest(WebRequestMethods.Http.Post, "registration-validations/auth/multi_step/start")] - internal class YGetAuthLoginUserBuilder : YRequestBuilder - { - public YGetAuthLoginUserBuilder(YandexMusicApi yandex, AuthStorage auth) : base(yandex, auth) - { - } +namespace YandexMusic.API.Requests.Account; - protected override HttpContent GetContent((string token, string login) tuple) - { - return new FormUrlEncodedContent(new Dictionary { - { "csrf_token", tuple.token }, - { "login", tuple.login } - }); - } +[YPassportRequest(WebRequestMethods.Http.Post, "registration-validations/auth/multi_step/start")] +internal class YGetAuthLoginUserBuilder : YRequestBuilder +{ + public YGetAuthLoginUserBuilder(YandexMusicApi yandex, AuthStorage auth) : base(yandex, auth) + { + } + + protected override HttpContent GetContent((string token, string login) tuple) + { + return new FormUrlEncodedContent(new Dictionary { + { "csrf_token", tuple.token }, + { "login", tuple.login } + }); } } \ No newline at end of file diff --git a/YandexMusic.API/Requests/Account/YGetAuthMethodsBuilder.cs b/YandexMusic.API/Requests/Account/YGetAuthMethodsBuilder.cs index 95a7576..72dfd78 100644 --- a/YandexMusic.API/Requests/Account/YGetAuthMethodsBuilder.cs +++ b/YandexMusic.API/Requests/Account/YGetAuthMethodsBuilder.cs @@ -5,20 +5,19 @@ using YandexMusic.API.Common; using YandexMusic.API.Requests.Common; using YandexMusic.API.Requests.Common.Attributes; -namespace YandexMusic.API.Requests.Account -{ - [YPassportRequest(WebRequestMethods.Http.Get, "am")] - internal class YGetAuthMethodsBuilder : YRequestBuilder - { - public YGetAuthMethodsBuilder(YandexMusicApi yandex, AuthStorage auth) : base(yandex, auth) - { - } +namespace YandexMusic.API.Requests.Account; - protected override NameValueCollection GetQueryParams(string tuple) - { - return new NameValueCollection { - { "app_platform", "android" } - }; - } +[YPassportRequest(WebRequestMethods.Http.Get, "am")] +internal class YGetAuthMethodsBuilder : YRequestBuilder +{ + public YGetAuthMethodsBuilder(YandexMusicApi yandex, AuthStorage auth) : base(yandex, auth) + { + } + + protected override NameValueCollection GetQueryParams(string tuple) + { + return new NameValueCollection { + { "app_platform", "android" } + }; } } \ No newline at end of file diff --git a/YandexMusic.API/Requests/Account/YGetAuthQRBuilder.cs b/YandexMusic.API/Requests/Account/YGetAuthQRBuilder.cs index 720f74d..d81cc28 100644 --- a/YandexMusic.API/Requests/Account/YGetAuthQRBuilder.cs +++ b/YandexMusic.API/Requests/Account/YGetAuthQRBuilder.cs @@ -5,22 +5,21 @@ using YandexMusic.API.Models.Account; using YandexMusic.API.Requests.Common; using YandexMusic.API.Requests.Common.Attributes; -namespace YandexMusic.API.Requests.Account -{ - [YPassportRequest(WebRequestMethods.Http.Post, "registration-validations/auth/password/submit")] - internal class YGetAuthQRBuilder : YRequestBuilder - { - public YGetAuthQRBuilder(YandexMusicApi yandex, AuthStorage auth) : base(yandex, auth) - { - } +namespace YandexMusic.API.Requests.Account; - protected override HttpContent GetContent(string tuple) - { - return new FormUrlEncodedContent(new Dictionary { - { "csrf_token", storage.AuthToken.CsfrToken }, - { "retpath", "https://passport.yandex.ru/profile" }, - { "with_code", "1" }, - }); - } +[YPassportRequest(WebRequestMethods.Http.Post, "registration-validations/auth/password/submit")] +internal class YGetAuthQRBuilder : YRequestBuilder +{ + public YGetAuthQRBuilder(YandexMusicApi yandex, AuthStorage auth) : base(yandex, auth) + { + } + + protected override HttpContent GetContent(string tuple) + { + return new FormUrlEncodedContent(new Dictionary { + { "csrf_token", storage.AuthToken.CsfrToken }, + { "retpath", "https://passport.yandex.ru/profile" }, + { "with_code", "1" }, + }); } } \ No newline at end of file diff --git a/YandexMusic.API/Requests/Account/YGetLoginInfoBuilder.cs b/YandexMusic.API/Requests/Account/YGetLoginInfoBuilder.cs index a23433e..e637c6a 100644 --- a/YandexMusic.API/Requests/Account/YGetLoginInfoBuilder.cs +++ b/YandexMusic.API/Requests/Account/YGetLoginInfoBuilder.cs @@ -5,13 +5,12 @@ using YandexMusic.API.Models.Account; using YandexMusic.API.Requests.Common; using YandexMusic.API.Requests.Common.Attributes; -namespace YandexMusic.API.Requests.Account +namespace YandexMusic.API.Requests.Account; + +[YLoginRequest(WebRequestMethods.Http.Get, "info")] +public class YGetLoginInfoBuilder : YRequestBuilder { - [YLoginRequest(WebRequestMethods.Http.Get, "info")] - public class YGetLoginInfoBuilder : YRequestBuilder + public YGetLoginInfoBuilder(YandexMusicApi yandex, AuthStorage auth) : base(yandex, auth) { - public YGetLoginInfoBuilder(YandexMusicApi yandex, AuthStorage auth) : base(yandex, auth) - { - } } } \ No newline at end of file diff --git a/YandexMusic.API/Requests/Account/YGetMusicTokenBuilder.cs b/YandexMusic.API/Requests/Account/YGetMusicTokenBuilder.cs index 8054614..1c52dd6 100644 --- a/YandexMusic.API/Requests/Account/YGetMusicTokenBuilder.cs +++ b/YandexMusic.API/Requests/Account/YGetMusicTokenBuilder.cs @@ -6,31 +6,30 @@ using YandexMusic.API.Models.Account; using YandexMusic.API.Requests.Common; using YandexMusic.API.Requests.Common.Attributes; -namespace YandexMusic.API.Requests.Account +namespace YandexMusic.API.Requests.Account; + +[YOAuthMobile(WebRequestMethods.Http.Post, "/1/token")] +internal class YGetMusicTokenBuilder : YRequestBuilder { - [YOAuthMobile(WebRequestMethods.Http.Post, "/1/token")] - internal class YGetMusicTokenBuilder : YRequestBuilder + public YGetMusicTokenBuilder(YandexMusicApi yandex, AuthStorage auth) : base(yandex, auth) { - public YGetMusicTokenBuilder(YandexMusicApi yandex, AuthStorage auth) : base(yandex, auth) - { - } + } - protected override HttpContent GetContent(string tuple) + protected override HttpContent GetContent(string tuple) + { + return new FormUrlEncodedContent(new Dictionary { - return new FormUrlEncodedContent(new Dictionary - { - { "client_id", YConstants.ClientId }, - { "client_secret", YConstants.ClientSecret }, - { "grant_type", "x-token" }, - { "access_token", storage.AccessToken.AccessToken } - }); - } + { "client_id", YConstants.ClientId }, + { "client_secret", YConstants.ClientSecret }, + { "grant_type", "x-token" }, + { "access_token", storage.AccessToken.AccessToken } + }); + } - protected override void SetCustomHeaders(HttpRequestHeaders headers) - { - headers.Remove("Authorization"); + protected override void SetCustomHeaders(HttpRequestHeaders headers) + { + headers.Remove("Authorization"); - base.SetCustomHeaders(headers); - } + base.SetCustomHeaders(headers); } } \ No newline at end of file diff --git a/YandexMusic.API/Requests/Account/YGetShortAccountInifoBuilder.cs b/YandexMusic.API/Requests/Account/YGetShortAccountInifoBuilder.cs index 758961d..13ee364 100644 --- a/YandexMusic.API/Requests/Account/YGetShortAccountInifoBuilder.cs +++ b/YandexMusic.API/Requests/Account/YGetShortAccountInifoBuilder.cs @@ -7,25 +7,24 @@ using YandexMusic.API.Models.Account; using YandexMusic.API.Requests.Common; using YandexMusic.API.Requests.Common.Attributes; -namespace YandexMusic.API.Requests.Account +namespace YandexMusic.API.Requests.Account; + +[YMobileProxyRequest(WebRequestMethods.Http.Get, "/1/bundle/account/short_info/")] +internal class YGetShortAccountInifoBuilder : YRequestBuilder { - [YMobileProxyRequest(WebRequestMethods.Http.Get, "/1/bundle/account/short_info/")] - internal class YGetShortAccountInifoBuilder : YRequestBuilder + public YGetShortAccountInifoBuilder(YandexMusicApi yandex, AuthStorage auth) : base(yandex, auth) { - public YGetShortAccountInifoBuilder(YandexMusicApi yandex, AuthStorage auth) : base(yandex, auth) - { - } + } - protected override NameValueCollection GetQueryParams(object tuple) - { - return new NameValueCollection { - { "avatar_size", "islands-300" } - }; - } + protected override NameValueCollection GetQueryParams(object tuple) + { + return new NameValueCollection { + { "avatar_size", "islands-300" } + }; + } - protected override void SetCustomHeaders(HttpRequestHeaders headers) - { - headers.Add("Ya-Consumer-Authorization", $"OAuth {storage.AccessToken.AccessToken}"); - } + protected override void SetCustomHeaders(HttpRequestHeaders headers) + { + headers.Add("Ya-Consumer-Authorization", $"OAuth {storage.AccessToken.AccessToken}"); } } \ No newline at end of file diff --git a/YandexMusic.API/Requests/Album/YGetAlbumBuilder.cs b/YandexMusic.API/Requests/Album/YGetAlbumBuilder.cs index 9dc8f7c..7fa6695 100644 --- a/YandexMusic.API/Requests/Album/YGetAlbumBuilder.cs +++ b/YandexMusic.API/Requests/Album/YGetAlbumBuilder.cs @@ -6,20 +6,19 @@ using YandexMusic.API.Models.Common; using YandexMusic.API.Requests.Common; using YandexMusic.API.Requests.Common.Attributes; -namespace YandexMusic.API.Requests.Album -{ - [YApiRequest(WebRequestMethods.Http.Get, "albums/{albumId}/with-tracks")] - public class YGetAlbumBuilder : YRequestBuilder, string> - { - public YGetAlbumBuilder(YandexMusicApi yandex, AuthStorage auth) : base(yandex, auth) - { - } +namespace YandexMusic.API.Requests.Album; - protected override Dictionary GetSubstitutions(string albumId) - { - return new Dictionary { - { "albumId", albumId } - }; - } +[YApiRequest(WebRequestMethods.Http.Get, "albums/{albumId}/with-tracks")] +public class YGetAlbumBuilder : YRequestBuilder, string> +{ + public YGetAlbumBuilder(YandexMusicApi yandex, AuthStorage auth) : base(yandex, auth) + { + } + + protected override Dictionary GetSubstitutions(string albumId) + { + return new Dictionary { + { "albumId", albumId } + }; } } \ No newline at end of file diff --git a/YandexMusic.API/Requests/Album/YGetAlbumsBuilder.cs b/YandexMusic.API/Requests/Album/YGetAlbumsBuilder.cs index 8031851..04fd695 100644 --- a/YandexMusic.API/Requests/Album/YGetAlbumsBuilder.cs +++ b/YandexMusic.API/Requests/Album/YGetAlbumsBuilder.cs @@ -6,20 +6,19 @@ using YandexMusic.API.Models.Common; using YandexMusic.API.Requests.Common; using YandexMusic.API.Requests.Common.Attributes; -namespace YandexMusic.API.Requests.Album -{ - [YApiRequest(WebRequestMethods.Http.Post, "albums")] - public class YGetAlbumsBuilder : YRequestBuilder>, IEnumerable> - { - public YGetAlbumsBuilder(YandexMusicApi yandex, AuthStorage auth) : base(yandex, auth) - { - } +namespace YandexMusic.API.Requests.Album; - protected override HttpContent GetContent(IEnumerable albumIds) - { - return new FormUrlEncodedContent(new Dictionary { - { "album-ids", string.Join(",", albumIds) } - }); - } +[YApiRequest(WebRequestMethods.Http.Post, "albums")] +public class YGetAlbumsBuilder : YRequestBuilder>, IEnumerable> +{ + public YGetAlbumsBuilder(YandexMusicApi yandex, AuthStorage auth) : base(yandex, auth) + { + } + + protected override HttpContent GetContent(IEnumerable albumIds) + { + return new FormUrlEncodedContent(new Dictionary { + { "album-ids", string.Join(",", albumIds) } + }); } } \ No newline at end of file diff --git a/YandexMusic.API/Requests/Artist/YGetArtistBuilder.cs b/YandexMusic.API/Requests/Artist/YGetArtistBuilder.cs index 9e5c5c7..a71d978 100644 --- a/YandexMusic.API/Requests/Artist/YGetArtistBuilder.cs +++ b/YandexMusic.API/Requests/Artist/YGetArtistBuilder.cs @@ -6,20 +6,19 @@ using YandexMusic.API.Models.Common; using YandexMusic.API.Requests.Common; using YandexMusic.API.Requests.Common.Attributes; -namespace YandexMusic.API.Requests.Artist -{ - [YApiRequest(WebRequestMethods.Http.Get, "artists/{artistId}/brief-info")] - public class YGetArtistBuilder : YRequestBuilder, string> - { - public YGetArtistBuilder(YandexMusicApi yandex, AuthStorage auth) : base(yandex, auth) - { - } +namespace YandexMusic.API.Requests.Artist; - protected override Dictionary GetSubstitutions(string artistId) - { - return new Dictionary { - { "artistId", artistId } - }; - } +[YApiRequest(WebRequestMethods.Http.Get, "artists/{artistId}/brief-info")] +public class YGetArtistBuilder : YRequestBuilder, string> +{ + public YGetArtistBuilder(YandexMusicApi yandex, AuthStorage auth) : base(yandex, auth) + { + } + + protected override Dictionary GetSubstitutions(string artistId) + { + return new Dictionary { + { "artistId", artistId } + }; } } \ No newline at end of file diff --git a/YandexMusic.API/Requests/Artist/YGetArtistTrackBuilder.cs b/YandexMusic.API/Requests/Artist/YGetArtistTrackBuilder.cs index 907ee0f..b8049f5 100644 --- a/YandexMusic.API/Requests/Artist/YGetArtistTrackBuilder.cs +++ b/YandexMusic.API/Requests/Artist/YGetArtistTrackBuilder.cs @@ -7,26 +7,25 @@ using YandexMusic.API.Models.Common; using YandexMusic.API.Requests.Common; using YandexMusic.API.Requests.Common.Attributes; -namespace YandexMusic.API.Requests.Artist +namespace YandexMusic.API.Requests.Artist; + +[YApiRequest(WebRequestMethods.Http.Get, "artists/{artistId}/tracks")] +public class YGetArtistTrackBuilder : YRequestBuilder, (string id, int page, int pageSize)> { - [YApiRequest(WebRequestMethods.Http.Get, "artists/{artistId}/tracks")] - public class YGetArtistTrackBuilder : YRequestBuilder, (string id, int page, int pageSize)> + public YGetArtistTrackBuilder(YandexMusicApi yandex, AuthStorage auth) : base(yandex, auth) { } + + protected override Dictionary GetSubstitutions((string id, int page, int pageSize) tuple) { - public YGetArtistTrackBuilder(YandexMusicApi yandex, AuthStorage auth) : base(yandex, auth) { } + return new Dictionary { + { "artistId", tuple.id }, + }; + } - protected override Dictionary GetSubstitutions((string id, int page, int pageSize) tuple) - { - return new Dictionary { - { "artistId", tuple.id }, - }; - } - - protected override NameValueCollection GetQueryParams((string id, int page, int pageSize) tuple) - { - return new NameValueCollection { - { "page", tuple.page.ToString() }, - { "pageSize", tuple.pageSize.ToString() }, - }; - } + protected override NameValueCollection GetQueryParams((string id, int page, int pageSize) tuple) + { + return new NameValueCollection { + { "page", tuple.page.ToString() }, + { "pageSize", tuple.pageSize.ToString() }, + }; } } \ No newline at end of file diff --git a/YandexMusic.API/Requests/Artist/YGetArtistsBuilder.cs b/YandexMusic.API/Requests/Artist/YGetArtistsBuilder.cs index 9860d42..7bd6c2f 100644 --- a/YandexMusic.API/Requests/Artist/YGetArtistsBuilder.cs +++ b/YandexMusic.API/Requests/Artist/YGetArtistsBuilder.cs @@ -6,20 +6,19 @@ using YandexMusic.API.Models.Common; using YandexMusic.API.Requests.Common; using YandexMusic.API.Requests.Common.Attributes; -namespace YandexMusic.API.Requests.Artist -{ - [YApiRequest(WebRequestMethods.Http.Post, "artists")] - public class YGetArtistsBuilder : YRequestBuilder>, IEnumerable> - { - public YGetArtistsBuilder(YandexMusicApi yandex, AuthStorage auth) : base(yandex, auth) - { - } +namespace YandexMusic.API.Requests.Artist; - protected override HttpContent GetContent(IEnumerable artistIds) - { - return new FormUrlEncodedContent(new Dictionary { - { "artist-Ids", string.Join(",", artistIds) } - }); - } +[YApiRequest(WebRequestMethods.Http.Post, "artists")] +public class YGetArtistsBuilder : YRequestBuilder>, IEnumerable> +{ + public YGetArtistsBuilder(YandexMusicApi yandex, AuthStorage auth) : base(yandex, auth) + { + } + + protected override HttpContent GetContent(IEnumerable artistIds) + { + return new FormUrlEncodedContent(new Dictionary { + { "artist-Ids", string.Join(",", artistIds) } + }); } } \ No newline at end of file diff --git a/YandexMusic.API/Requests/Common/Attributes/YApiRequestAttribute.cs b/YandexMusic.API/Requests/Common/Attributes/YApiRequestAttribute.cs index 4610b03..f7a0fd6 100644 --- a/YandexMusic.API/Requests/Common/Attributes/YApiRequestAttribute.cs +++ b/YandexMusic.API/Requests/Common/Attributes/YApiRequestAttribute.cs @@ -1,10 +1,9 @@ -namespace YandexMusic.API.Requests.Common.Attributes +namespace YandexMusic.API.Requests.Common.Attributes; + +public class YApiRequestAttribute : YBasePathRequestAttribute { - public class YApiRequestAttribute : YBasePathRequestAttribute + public YApiRequestAttribute(string method, string url) : base(method, url) { - public YApiRequestAttribute(string method, string url) : base(method, url) - { - basePath = "https://api.music.yandex.net"; - } + basePath = "https://api.music.yandex.net"; } } \ No newline at end of file diff --git a/YandexMusic.API/Requests/Common/Attributes/YBasePathRequestAttribute.cs b/YandexMusic.API/Requests/Common/Attributes/YBasePathRequestAttribute.cs index e842aee..4ce0030 100644 --- a/YandexMusic.API/Requests/Common/Attributes/YBasePathRequestAttribute.cs +++ b/YandexMusic.API/Requests/Common/Attributes/YBasePathRequestAttribute.cs @@ -1,32 +1,31 @@ -namespace YandexMusic.API.Requests.Common.Attributes +namespace YandexMusic.API.Requests.Common.Attributes; + +/// +/// Атрибут запроса относительно базового адреса +/// +public class YBasePathRequestAttribute : YRequestAttribute { - /// - /// Атрибут запроса относительно базового адреса - /// - public class YBasePathRequestAttribute : YRequestAttribute + #region Поля + + protected string basePath; + + #endregion Поля + + #region Свойства + public override string Url => GetFullUrl(); + + #endregion Свойства + + #region Вспомогательные функции + + private string GetFullUrl() { - #region Поля + return $"{basePath.TrimEnd('/')}/{path.TrimStart('/')}"; + } - protected string basePath; + #endregion Вспомогательные функции - #endregion Поля - - #region Свойства - public override string Url => GetFullUrl(); - - #endregion Свойства - - #region Вспомогательные функции - - private string GetFullUrl() - { - return $"{basePath.TrimEnd('/')}/{path.TrimStart('/')}"; - } - - #endregion Вспомогательные функции - - public YBasePathRequestAttribute(string method, string url) : base(method, url) - { - } + public YBasePathRequestAttribute(string method, string url) : base(method, url) + { } } \ No newline at end of file diff --git a/YandexMusic.API/Requests/Common/Attributes/YLoginRequestAttribute.cs b/YandexMusic.API/Requests/Common/Attributes/YLoginRequestAttribute.cs index cc21fa4..bbf0cfe 100644 --- a/YandexMusic.API/Requests/Common/Attributes/YLoginRequestAttribute.cs +++ b/YandexMusic.API/Requests/Common/Attributes/YLoginRequestAttribute.cs @@ -1,10 +1,9 @@ -namespace YandexMusic.API.Requests.Common.Attributes +namespace YandexMusic.API.Requests.Common.Attributes; + +public class YLoginRequestAttribute : YBasePathRequestAttribute { - public class YLoginRequestAttribute : YBasePathRequestAttribute + public YLoginRequestAttribute(string method, string url) : base(method, url) { - public YLoginRequestAttribute(string method, string url) : base(method, url) - { - basePath = "https://login.yandex.ru"; - } + basePath = "https://login.yandex.ru"; } } \ No newline at end of file diff --git a/YandexMusic.API/Requests/Common/Attributes/YMobileProxyRequestAttribute.cs b/YandexMusic.API/Requests/Common/Attributes/YMobileProxyRequestAttribute.cs index 130b831..f36f22a 100644 --- a/YandexMusic.API/Requests/Common/Attributes/YMobileProxyRequestAttribute.cs +++ b/YandexMusic.API/Requests/Common/Attributes/YMobileProxyRequestAttribute.cs @@ -1,10 +1,9 @@ -namespace YandexMusic.API.Requests.Common.Attributes +namespace YandexMusic.API.Requests.Common.Attributes; + +public class YMobileProxyRequestAttribute : YBasePathRequestAttribute { - public class YMobileProxyRequestAttribute : YBasePathRequestAttribute + public YMobileProxyRequestAttribute(string method, string url) : base(method, url) { - public YMobileProxyRequestAttribute(string method, string url) : base(method, url) - { - basePath = "https://mobileproxy.passport.yandex.net"; - } + basePath = "https://mobileproxy.passport.yandex.net"; } } \ No newline at end of file diff --git a/YandexMusic.API/Requests/Common/Attributes/YOAuthMobileAttribute.cs b/YandexMusic.API/Requests/Common/Attributes/YOAuthMobileAttribute.cs index 29a9961..ef5b13a 100644 --- a/YandexMusic.API/Requests/Common/Attributes/YOAuthMobileAttribute.cs +++ b/YandexMusic.API/Requests/Common/Attributes/YOAuthMobileAttribute.cs @@ -1,10 +1,9 @@ -namespace YandexMusic.API.Requests.Common.Attributes +namespace YandexMusic.API.Requests.Common.Attributes; + +public class YOAuthMobileAttribute : YBasePathRequestAttribute { - public class YOAuthMobileAttribute : YBasePathRequestAttribute + public YOAuthMobileAttribute(string method, string url) : base(method, url) { - public YOAuthMobileAttribute(string method, string url) : base(method, url) - { - basePath = "https://oauth.mobile.yandex.net"; - } + basePath = "https://oauth.mobile.yandex.net"; } } \ No newline at end of file diff --git a/YandexMusic.API/Requests/Common/Attributes/YOAuthRequestAttribute.cs b/YandexMusic.API/Requests/Common/Attributes/YOAuthRequestAttribute.cs index 16eef58..3ebd9bd 100644 --- a/YandexMusic.API/Requests/Common/Attributes/YOAuthRequestAttribute.cs +++ b/YandexMusic.API/Requests/Common/Attributes/YOAuthRequestAttribute.cs @@ -1,10 +1,9 @@ -namespace YandexMusic.API.Requests.Common.Attributes +namespace YandexMusic.API.Requests.Common.Attributes; + +public class YOAuthRequestAttribute : YBasePathRequestAttribute { - public class YOAuthRequestAttribute : YBasePathRequestAttribute + public YOAuthRequestAttribute(string method, string url) : base(method, url) { - public YOAuthRequestAttribute(string method, string url) : base(method, url) - { - basePath = "https://oauth.yandex.ru"; - } + basePath = "https://oauth.yandex.ru"; } } \ No newline at end of file diff --git a/YandexMusic.API/Requests/Common/Attributes/YPassportRequestAttribute.cs b/YandexMusic.API/Requests/Common/Attributes/YPassportRequestAttribute.cs index a678f45..83a0e2d 100644 --- a/YandexMusic.API/Requests/Common/Attributes/YPassportRequestAttribute.cs +++ b/YandexMusic.API/Requests/Common/Attributes/YPassportRequestAttribute.cs @@ -1,10 +1,9 @@ -namespace YandexMusic.API.Requests.Common.Attributes +namespace YandexMusic.API.Requests.Common.Attributes; + +public class YPassportRequestAttribute : YBasePathRequestAttribute { - public class YPassportRequestAttribute : YBasePathRequestAttribute + public YPassportRequestAttribute(string method, string url) : base(method, url) { - public YPassportRequestAttribute(string method, string url) : base(method, url) - { - basePath = "https://passport.yandex.ru"; - } + basePath = "https://passport.yandex.ru"; } } \ No newline at end of file diff --git a/YandexMusic.API/Requests/Common/Attributes/YRequestAttribute.cs b/YandexMusic.API/Requests/Common/Attributes/YRequestAttribute.cs index 0bcd8f2..478d12a 100644 --- a/YandexMusic.API/Requests/Common/Attributes/YRequestAttribute.cs +++ b/YandexMusic.API/Requests/Common/Attributes/YRequestAttribute.cs @@ -1,27 +1,26 @@ -namespace YandexMusic.API.Requests.Common.Attributes +namespace YandexMusic.API.Requests.Common.Attributes; + +/// +/// Атрибут запроса без привязки к базовому адресу +/// +public class YRequestAttribute : Attribute { - /// - /// Атрибут запроса без привязки к базовому адресу - /// - public class YRequestAttribute : Attribute + #region Поля + + protected string path; + + #endregion Поля + + #region Свойства + + public string Method { get; } + public virtual string Url => path; + + #endregion Свойства + + public YRequestAttribute(string method, string url) { - #region Поля - - protected string path; - - #endregion Поля - - #region Свойства - - public string Method { get; } - public virtual string Url => path; - - #endregion Свойства - - public YRequestAttribute(string method, string url) - { - Method = method; - path = url; - } + Method = method; + path = url; } } \ No newline at end of file diff --git a/YandexMusic.API/Requests/Common/Attributes/YWebApiRequestAttribute.cs b/YandexMusic.API/Requests/Common/Attributes/YWebApiRequestAttribute.cs index 22314f4..cb52e3b 100644 --- a/YandexMusic.API/Requests/Common/Attributes/YWebApiRequestAttribute.cs +++ b/YandexMusic.API/Requests/Common/Attributes/YWebApiRequestAttribute.cs @@ -1,10 +1,9 @@ -namespace YandexMusic.API.Requests.Common.Attributes +namespace YandexMusic.API.Requests.Common.Attributes; + +public class YWebApiRequestAttribute : YBasePathRequestAttribute { - public class YWebApiRequestAttribute : YBasePathRequestAttribute + public YWebApiRequestAttribute(string method, string url) : base(method, url) { - public YWebApiRequestAttribute(string method, string url) : base(method, url) - { - basePath = "https://music.yandex.ru"; - } + basePath = "https://music.yandex.ru"; } } \ No newline at end of file diff --git a/YandexMusic.API/Requests/Common/HttpContext.cs b/YandexMusic.API/Requests/Common/HttpContext.cs index 7666088..4eb0833 100644 --- a/YandexMusic.API/Requests/Common/HttpContext.cs +++ b/YandexMusic.API/Requests/Common/HttpContext.cs @@ -1,26 +1,25 @@ using System.Net; -namespace YandexMusic.API.Requests.Common +namespace YandexMusic.API.Requests.Common; + +public class HttpContext { - public class HttpContext + public CookieContainer Cookies; + + public HttpContext() { - public CookieContainer Cookies; + Cookies = new CookieContainer(); + } - public HttpContext() - { - Cookies = new CookieContainer(); - } + public IWebProxy WebProxy { get; set; } - public IWebProxy WebProxy { get; set; } + public long GetTimeInterval() + { + DateTime dt = TimeZoneInfo.ConvertTimeToUtc(DateTime.Now); + DateTime dt1970 = new(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc); + TimeSpan tsInterval = dt.Subtract(dt1970); + long iMilliseconds = Convert.ToInt64(tsInterval.TotalMilliseconds); - public long GetTimeInterval() - { - DateTime dt = TimeZoneInfo.ConvertTimeToUtc(DateTime.Now); - DateTime dt1970 = new(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc); - TimeSpan tsInterval = dt.Subtract(dt1970); - long iMilliseconds = Convert.ToInt64(tsInterval.TotalMilliseconds); - - return iMilliseconds; - } + return iMilliseconds; } } \ No newline at end of file diff --git a/YandexMusic.API/Requests/Common/YConstants.cs b/YandexMusic.API/Requests/Common/YConstants.cs index 7dbef77..03a88a8 100644 --- a/YandexMusic.API/Requests/Common/YConstants.cs +++ b/YandexMusic.API/Requests/Common/YConstants.cs @@ -1,11 +1,10 @@ -namespace YandexMusic.API.Requests.Common -{ - internal class YConstants - { - public static string ClientId = "23cabbbdc6cd418abb4b39c32c41195d"; - public static string ClientSecret = "53bc75238f0c4d08a118e51fe9203300"; +namespace YandexMusic.API.Requests.Common; - public const string XClientId = "c0ebe342af7d48fbbbfcf2d2eedb8f9e"; - public const string XClientSecret = "ad0a908f0aa341a182a37ecd75bc319e"; - } +internal class YConstants +{ + public static string ClientId = "23cabbbdc6cd418abb4b39c32c41195d"; + public static string ClientSecret = "53bc75238f0c4d08a118e51fe9203300"; + + public const string XClientId = "c0ebe342af7d48fbbbfcf2d2eedb8f9e"; + public const string XClientSecret = "ad0a908f0aa341a182a37ecd75bc319e"; } \ No newline at end of file diff --git a/YandexMusic.API/Requests/Common/YRequest.cs b/YandexMusic.API/Requests/Common/YRequest.cs index 21ad639..61d741b 100644 --- a/YandexMusic.API/Requests/Common/YRequest.cs +++ b/YandexMusic.API/Requests/Common/YRequest.cs @@ -1,48 +1,45 @@ using YandexMusic.API.Common; using YandexMusic.API.Common.Providers; -namespace YandexMusic.API.Requests.Common +namespace YandexMusic.API.Requests.Common; + +internal class YRequest { - internal class YRequest + #region Поля + + private HttpRequestMessage msg; + private IRequestProvider provider; + + protected YandexMusicApi api; + + #endregion Поля + + public YRequest(HttpRequestMessage message, YandexMusicApi yandex, AuthStorage auth) { - #region Поля - - private HttpRequestMessage msg; - private IRequestProvider provider; - - protected YandexMusicApi api; - - #endregion Поля - - - - public YRequest(HttpRequestMessage message, YandexMusicApi yandex, AuthStorage auth) - { - msg = message; - api = yandex; - provider = auth.Provider; - } - - public async Task GetResponseAsync() - { - if (msg == null) - return default; - - HttpResponseMessage response = await provider.GetWebResponseAsync(msg); - - if (typeof(T) == typeof(HttpResponseMessage)) - return (T)(object)response; - - try - { - return await provider.GetDataFromResponseAsync(api, response); - } - finally - { - response.Dispose(); - } - } - - + msg = message; + api = yandex; + provider = auth.Provider; } + + public async Task GetResponseAsync() + { + if (msg == null) + return default; + + HttpResponseMessage response = await provider.GetWebResponseAsync(msg); + + if (typeof(T) == typeof(HttpResponseMessage)) + return (T)(object)response; + + try + { + return await provider.GetDataFromResponseAsync(api, response); + } + finally + { + response.Dispose(); + } + } + + } \ No newline at end of file diff --git a/YandexMusic.API/Requests/Common/YRequestBuilder.cs b/YandexMusic.API/Requests/Common/YRequestBuilder.cs index daa463b..a50dfa7 100644 --- a/YandexMusic.API/Requests/Common/YRequestBuilder.cs +++ b/YandexMusic.API/Requests/Common/YRequestBuilder.cs @@ -3,156 +3,95 @@ using System.Net; using System.Net.Http.Headers; using System.Reflection; using System.Text; +using System.Text.Json; +using System.Text.Json.Serialization; using System.Web; - using YandexMusic.API.Common; using YandexMusic.API.Extensions; using YandexMusic.API.Requests.Common.Attributes; -namespace YandexMusic.API.Requests.Common +namespace YandexMusic.API.Requests.Common; + +/// Базовый строитель HTTP-запросов к API Яндекс.Музыки. +/// Тип ответа. +/// Тип параметров запроса. +public abstract class YRequestBuilder { - public class YRequestBuilder + private readonly YRequestAttribute _requestInfo; + private Dictionary _substitutions = null!; + private readonly JsonSerializerOptions _jsonOptions; + + protected readonly YandexMusicApi api; + protected readonly AuthStorage storage; + protected string device; + + protected YRequestBuilder(YandexMusicApi yandex, AuthStorage auth) { - #region Поля + _requestInfo = GetType().GetCustomAttribute() + ?? throw new NotImplementedException($"Отсутствует атрибут {nameof(YRequestAttribute)}"); + api = yandex; + storage = auth; + device = $"os=CSharp; os_version=; manufacturer=K1llM@n; model=Yandex Music API; clid=; device_id={storage.DeviceId}; uuid=random"; - private readonly JsonSerializerSettings jsonSettings = new() + _jsonOptions = new JsonSerializerOptions { - Converters = new List { - new StringEnumConverter { - NamingStrategy = new CamelCaseNamingStrategy() - } - }, - NullValueHandling = NullValueHandling.Ignore, - ContractResolver = new CamelCasePropertyNamesContractResolver() + PropertyNamingPolicy = JsonNamingPolicy.CamelCase, + DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull, + Converters = { new JsonStringEnumConverter(JsonNamingPolicy.CamelCase) } }; - - private YRequestAttribute requestInfo; - private Dictionary subs; - - protected YandexMusicApi api; - protected AuthStorage storage; - protected string device; - - #endregion Поля - - #region Свойства - - protected YandexMusicApi API => api; - protected AuthStorage Storage => storage; - - #endregion Свойства - - #region Вспомогательные функции - - private Uri BuildUri(ParamsTuple tuple) - { - NameValueCollection queryParams = GetQueryParams(tuple); - NameValueCollection modifiedParams = HttpUtility.ParseQueryString(string.Empty); - - // Подстановка в параметры - foreach (string key in queryParams.Keys) - { - modifiedParams.Set(key, ReplaceSubs(queryParams.Get(key))); - } - - string endpoint = ReplaceSubs(requestInfo.Url); - - UriBuilder builder = new(endpoint) - { - Query = modifiedParams.ToString() ?? string.Empty - }; - - - return builder.Uri; - } - - private HttpRequestMessage CreateMessage(ParamsTuple tuple) - { - HttpRequestMessage msg = new() - { - RequestUri = BuildUri(tuple), - Method = new HttpMethod(requestInfo.Method), - Content = GetContent(tuple) - }; - - msg.Headers.TryAddWithoutValidation(HttpRequestHeader.AcceptCharset.GetName(), Encoding.UTF8.WebName); - msg.Headers.TryAddWithoutValidation(HttpRequestHeader.AcceptEncoding.GetName(), "gzip"); - - // Добавление заголовка авторизации - if (!string.IsNullOrEmpty(storage.Token)) - msg.Headers.TryAddWithoutValidation(HttpRequestHeader.Authorization.GetName(), $"OAuth {storage.Token}"); - - SetCustomHeaders(msg.Headers); - - return msg; - } - - protected string ReplaceSubs(string str) - { - string[] sub = str.GetMatches(@"\{.+?\}"); - - foreach (string s in sub) - { - if (!subs.TryGetValue(s.ReplaceRegex(@"[\{\}]", string.Empty), out string value)) - throw new Exception($"Не найдена подстановка {s}"); - - str = str.Replace(s, value); - } - - return str; - } - protected virtual Dictionary GetSubstitutions(ParamsTuple tuple) - { - return new Dictionary(); - } - - protected virtual NameValueCollection GetQueryParams(ParamsTuple tuple) - { - return new NameValueCollection(); - } - - protected virtual HttpContent GetContent(ParamsTuple tuple) - { - return null; - } - - protected virtual void SetCustomHeaders(HttpRequestHeaders headers) - { - } - - protected string SerializeJson(object data) - { - return JsonConvert.SerializeObject(data, jsonSettings); - } - - #endregion Вспомогательные функции - - - - public YRequestBuilder(YandexMusicApi yandex, AuthStorage auth) - { - requestInfo = GetType() - .GetCustomAttributes() - .FirstOrDefault(); - - if (requestInfo == null) - throw new NotImplementedException($"Отсутствует атрибут {nameof(YRequestAttribute)}"); - - api = yandex; - storage = auth; - - // Устройство по умолчанию - device = $"os=CSharp; os_version=; manufacturer=K1llM@n; model=Yandex Music API; clid=; device_id={storage.DeviceId}; uuid=random"; - } - - internal YRequest Build(ParamsTuple tuple) - { - subs = GetSubstitutions(tuple); - HttpRequestMessage msg = CreateMessage(tuple); - - return new YRequest(msg, api, storage); - } - - } -} + + private Uri BuildUri(TParams tuple) + { + var queryParams = GetQueryParams(tuple); + var modifiedParams = HttpUtility.ParseQueryString(string.Empty); + foreach (string? key in queryParams) + if (key != null) + modifiedParams[key] = ReplaceSubs(queryParams[key]!); + var endpoint = ReplaceSubs(_requestInfo.Url); + var builder = new UriBuilder(endpoint) { Query = modifiedParams.ToString() ?? string.Empty }; + return builder.Uri; + } + + private HttpRequestMessage CreateMessage(TParams tuple) + { + var msg = new HttpRequestMessage + { + RequestUri = BuildUri(tuple), + Method = new HttpMethod(_requestInfo.Method), + Content = GetContent(tuple) + }; + msg.Headers.TryAddWithoutValidation(HttpRequestHeader.AcceptCharset.GetName(), Encoding.UTF8.WebName); + msg.Headers.TryAddWithoutValidation(HttpRequestHeader.AcceptEncoding.GetName(), "gzip"); + if (!string.IsNullOrEmpty(storage.Token)) + msg.Headers.TryAddWithoutValidation(HttpRequestHeader.Authorization.GetName(), $"OAuth {storage.Token}"); + SetCustomHeaders(msg.Headers); + return msg; + } + + protected string ReplaceSubs(string str) + { + var subs = str.GetMatches(@"\{.+?\}"); + foreach (var s in subs) + { + var key = s.ReplaceRegex(@"[\{\}]", string.Empty); + if (!_substitutions.TryGetValue(key, out var value)) + throw new Exception($"Не найдена подстановка {s}"); + str = str.Replace(s, value); + } + return str; + } + + protected virtual Dictionary GetSubstitutions(TParams tuple) => []; + protected virtual NameValueCollection GetQueryParams(TParams tuple) => []; + protected virtual HttpContent? GetContent(TParams tuple) => null; + protected virtual void SetCustomHeaders(HttpRequestHeaders headers) { } + protected string SerializeJson(object data) => JsonSerializer.Serialize(data, _jsonOptions); + + internal YRequest Build(TParams tuple) + { + _substitutions = GetSubstitutions(tuple); + var msg = CreateMessage(tuple); + return new YRequest(msg, api, storage); + } +} \ No newline at end of file diff --git a/YandexMusic.API/Requests/Feed/YGetFeedBuilder.cs b/YandexMusic.API/Requests/Feed/YGetFeedBuilder.cs index e17eb7a..961b61b 100644 --- a/YandexMusic.API/Requests/Feed/YGetFeedBuilder.cs +++ b/YandexMusic.API/Requests/Feed/YGetFeedBuilder.cs @@ -6,13 +6,12 @@ using YandexMusic.API.Models.Feed; using YandexMusic.API.Requests.Common; using YandexMusic.API.Requests.Common.Attributes; -namespace YandexMusic.API.Requests.Feed +namespace YandexMusic.API.Requests.Feed; + +[YApiRequest(WebRequestMethods.Http.Get, "feed")] +public class YGetFeedBuilder : YRequestBuilder, object> { - [YApiRequest(WebRequestMethods.Http.Get, "feed")] - public class YGetFeedBuilder : YRequestBuilder, object> + public YGetFeedBuilder(YandexMusicApi yandex, AuthStorage auth) : base(yandex, auth) { - public YGetFeedBuilder(YandexMusicApi yandex, AuthStorage auth) : base(yandex, auth) - { - } } } \ No newline at end of file diff --git a/YandexMusic.API/Requests/Label/YGetLabelAlbumsBuilder.cs b/YandexMusic.API/Requests/Label/YGetLabelAlbumsBuilder.cs index 9cff2a7..c081433 100644 --- a/YandexMusic.API/Requests/Label/YGetLabelAlbumsBuilder.cs +++ b/YandexMusic.API/Requests/Label/YGetLabelAlbumsBuilder.cs @@ -7,27 +7,26 @@ using YandexMusic.API.Models.Label; using YandexMusic.API.Requests.Common; using YandexMusic.API.Requests.Common.Attributes; -namespace YandexMusic.API.Requests.Label +namespace YandexMusic.API.Requests.Label; + +[YApiRequest(WebRequestMethods.Http.Get, "labels/{labelId}/albums")] +public class YGetLabelAlbumsBuilder : YRequestBuilder, (YLabel label, int pageNumber)> { - [YApiRequest(WebRequestMethods.Http.Get, "labels/{labelId}/albums")] - public class YGetLabelAlbumsBuilder : YRequestBuilder, (YLabel label, int pageNumber)> + public YGetLabelAlbumsBuilder(YandexMusicApi yandex, AuthStorage auth) : base(yandex, auth) { - public YGetLabelAlbumsBuilder(YandexMusicApi yandex, AuthStorage auth) : base(yandex, auth) - { - } + } - protected override NameValueCollection GetQueryParams((YLabel label, int pageNumber) tuple) - { - return new NameValueCollection { - { "page", tuple.pageNumber.ToString() } - }; - } + protected override NameValueCollection GetQueryParams((YLabel label, int pageNumber) tuple) + { + return new NameValueCollection { + { "page", tuple.pageNumber.ToString() } + }; + } - protected override Dictionary GetSubstitutions((YLabel label, int pageNumber) tuple) - { - return new Dictionary { - { "labelId", tuple.label.Id } - }; - } + protected override Dictionary GetSubstitutions((YLabel label, int pageNumber) tuple) + { + return new Dictionary { + { "labelId", tuple.label.Id } + }; } } diff --git a/YandexMusic.API/Requests/Label/YGetLabelArtistsBuilder.cs b/YandexMusic.API/Requests/Label/YGetLabelArtistsBuilder.cs index f3055c3..db010be 100644 --- a/YandexMusic.API/Requests/Label/YGetLabelArtistsBuilder.cs +++ b/YandexMusic.API/Requests/Label/YGetLabelArtistsBuilder.cs @@ -7,27 +7,26 @@ using YandexMusic.API.Models.Label; using YandexMusic.API.Requests.Common; using YandexMusic.API.Requests.Common.Attributes; -namespace YandexMusic.API.Requests.Label +namespace YandexMusic.API.Requests.Label; + +[YApiRequest(WebRequestMethods.Http.Get, "labels/{labelId}/artists")] +public class YGetLabelArtistsBuilder : YRequestBuilder, (YLabel label, int pageNumber)> { - [YApiRequest(WebRequestMethods.Http.Get, "labels/{labelId}/artists")] - public class YGetLabelArtistsBuilder : YRequestBuilder, (YLabel label, int pageNumber)> + public YGetLabelArtistsBuilder(YandexMusicApi yandex, AuthStorage auth) : base(yandex, auth) { - public YGetLabelArtistsBuilder(YandexMusicApi yandex, AuthStorage auth) : base(yandex, auth) - { - } + } - protected override NameValueCollection GetQueryParams((YLabel label, int pageNumber) tuple) - { - return new NameValueCollection { - { "page", tuple.pageNumber.ToString() } - }; - } + protected override NameValueCollection GetQueryParams((YLabel label, int pageNumber) tuple) + { + return new NameValueCollection { + { "page", tuple.pageNumber.ToString() } + }; + } - protected override Dictionary GetSubstitutions((YLabel label, int pageNumber) tuple) - { - return new Dictionary { - { "labelId", tuple.label.Id } - }; - } + protected override Dictionary GetSubstitutions((YLabel label, int pageNumber) tuple) + { + return new Dictionary { + { "labelId", tuple.label.Id } + }; } } diff --git a/YandexMusic.API/Requests/Landing/YGetChildrenLandingBuilder.cs b/YandexMusic.API/Requests/Landing/YGetChildrenLandingBuilder.cs index 2e5cf91..7ec065f 100644 --- a/YandexMusic.API/Requests/Landing/YGetChildrenLandingBuilder.cs +++ b/YandexMusic.API/Requests/Landing/YGetChildrenLandingBuilder.cs @@ -6,13 +6,12 @@ using YandexMusic.API.Models.Landing; using YandexMusic.API.Requests.Common; using YandexMusic.API.Requests.Common.Attributes; -namespace YandexMusic.API.Requests.Landing +namespace YandexMusic.API.Requests.Landing; + +[YApiRequest(WebRequestMethods.Http.Get, "children-landing/catalogue")] +public class YGetChildrenLandingBuilder : YRequestBuilder, object> { - [YApiRequest(WebRequestMethods.Http.Get, "children-landing/catalogue")] - public class YGetChildrenLandingBuilder : YRequestBuilder, object> + public YGetChildrenLandingBuilder(YandexMusicApi yandex, AuthStorage auth) : base(yandex, auth) { - public YGetChildrenLandingBuilder(YandexMusicApi yandex, AuthStorage auth) : base(yandex, auth) - { - } } } \ No newline at end of file diff --git a/YandexMusic.API/Requests/Landing/YGetLandingBuilder.cs b/YandexMusic.API/Requests/Landing/YGetLandingBuilder.cs index 1023cb9..98ee8a6 100644 --- a/YandexMusic.API/Requests/Landing/YGetLandingBuilder.cs +++ b/YandexMusic.API/Requests/Landing/YGetLandingBuilder.cs @@ -7,23 +7,22 @@ using YandexMusic.API.Models.Landing; using YandexMusic.API.Requests.Common; using YandexMusic.API.Requests.Common.Attributes; -namespace YandexMusic.API.Requests.Landing +namespace YandexMusic.API.Requests.Landing; + +[YApiRequest(WebRequestMethods.Http.Get, "landing3")] +public class YGetLandingBuilder : YRequestBuilder, YLandingBlockType[]> { - [YApiRequest(WebRequestMethods.Http.Get, "landing3")] - public class YGetLandingBuilder : YRequestBuilder, YLandingBlockType[]> + public YGetLandingBuilder(YandexMusicApi yandex, AuthStorage auth) : base(yandex, auth) { - public YGetLandingBuilder(YandexMusicApi yandex, AuthStorage auth) : base(yandex, auth) - { - } + } - protected override NameValueCollection GetQueryParams(YLandingBlockType[] tuple) - { - string blocks = string.Join(",", tuple - .Select(b => SerializeJson(b).Replace("\"", string.Empty))); + protected override NameValueCollection GetQueryParams(YLandingBlockType[] tuple) + { + string blocks = string.Join(",", tuple + .Select(b => SerializeJson(b).Replace("\"", string.Empty))); - return new NameValueCollection { - { "blocks", blocks } - }; - } + return new NameValueCollection { + { "blocks", blocks } + }; } } \ No newline at end of file diff --git a/YandexMusic.API/Requests/Library/YGetLibraryRecentlyListenedBuilder.cs b/YandexMusic.API/Requests/Library/YGetLibraryRecentlyListenedBuilder.cs index e360120..94d3ed1 100644 --- a/YandexMusic.API/Requests/Library/YGetLibraryRecentlyListenedBuilder.cs +++ b/YandexMusic.API/Requests/Library/YGetLibraryRecentlyListenedBuilder.cs @@ -8,30 +8,29 @@ using YandexMusic.API.Models.Library; using YandexMusic.API.Requests.Common; using YandexMusic.API.Requests.Common.Attributes; -namespace YandexMusic.API.Requests.Library +namespace YandexMusic.API.Requests.Library; + +[YApiRequest(WebRequestMethods.Http.Get, "/users/{uid}/contexts")] +public class YGetLibraryRecentlyListenedBuilder : YRequestBuilder, + (IEnumerable contextTypes, int trackCount, int contextCount)> { - [YApiRequest(WebRequestMethods.Http.Get, "/users/{uid}/contexts")] - public class YGetLibraryRecentlyListenedBuilder : YRequestBuilder, - (IEnumerable contextTypes, int trackCount, int contextCount)> + public YGetLibraryRecentlyListenedBuilder(YandexMusicApi yandex, AuthStorage auth) : base(yandex, auth) { - public YGetLibraryRecentlyListenedBuilder(YandexMusicApi yandex, AuthStorage auth) : base(yandex, auth) - { - } + } - protected override NameValueCollection GetQueryParams((IEnumerable contextTypes, int trackCount, int contextCount) tuple) - { - return new NameValueCollection { - { "trackCount", tuple.trackCount.ToString() }, - { "contextCount", tuple.contextCount.ToString() }, - { "types", string.Join(",", tuple.contextTypes.Select(x => x.ToString().ToLowerInvariant())) } - }; - } + protected override NameValueCollection GetQueryParams((IEnumerable contextTypes, int trackCount, int contextCount) tuple) + { + return new NameValueCollection { + { "trackCount", tuple.trackCount.ToString() }, + { "contextCount", tuple.contextCount.ToString() }, + { "types", string.Join(",", tuple.contextTypes.Select(x => x.ToString().ToLowerInvariant())) } + }; + } - protected override Dictionary GetSubstitutions((IEnumerable contextTypes, int trackCount, int contextCount) tuple) - { - return new Dictionary { - { "uid", storage.User.Uid } - }; - } + protected override Dictionary GetSubstitutions((IEnumerable contextTypes, int trackCount, int contextCount) tuple) + { + return new Dictionary { + { "uid", storage.User.Uid } + }; } } \ No newline at end of file diff --git a/YandexMusic.API/Requests/Library/YGetLibrarySectionBuilder.cs b/YandexMusic.API/Requests/Library/YGetLibrarySectionBuilder.cs index 3322bb7..eadd41f 100644 --- a/YandexMusic.API/Requests/Library/YGetLibrarySectionBuilder.cs +++ b/YandexMusic.API/Requests/Library/YGetLibrarySectionBuilder.cs @@ -6,22 +6,21 @@ using YandexMusic.API.Models.Library; using YandexMusic.API.Requests.Common; using YandexMusic.API.Requests.Common.Attributes; -namespace YandexMusic.API.Requests.Library -{ - [YApiRequest(WebRequestMethods.Http.Get, "users/{uid}/{type}/{section}")] - public class YGetLibrarySectionBuilder : YRequestBuilder, (YLibrarySection section, YLibrarySectionType type)> - { - public YGetLibrarySectionBuilder(YandexMusicApi yandex, AuthStorage auth) : base(yandex, auth) - { - } +namespace YandexMusic.API.Requests.Library; - protected override Dictionary GetSubstitutions((YLibrarySection section, YLibrarySectionType type) tuple) - { - return new Dictionary { - { "uid", storage.User.Uid }, - { "type", tuple.type.ToString().ToLower() }, - { "section", tuple.section.ToString().ToLower() }, - }; - } +[YApiRequest(WebRequestMethods.Http.Get, "users/{uid}/{type}/{section}")] +public class YGetLibrarySectionBuilder : YRequestBuilder, (YLibrarySection section, YLibrarySectionType type)> +{ + public YGetLibrarySectionBuilder(YandexMusicApi yandex, AuthStorage auth) : base(yandex, auth) + { + } + + protected override Dictionary GetSubstitutions((YLibrarySection section, YLibrarySectionType type) tuple) + { + return new Dictionary { + { "uid", storage.User.Uid }, + { "type", tuple.type.ToString().ToLower() }, + { "section", tuple.section.ToString().ToLower() }, + }; } } \ No newline at end of file diff --git a/YandexMusic.API/Requests/Library/YLibraryAddBuilder.cs b/YandexMusic.API/Requests/Library/YLibraryAddBuilder.cs index 31af84d..24c1a2f 100644 --- a/YandexMusic.API/Requests/Library/YLibraryAddBuilder.cs +++ b/YandexMusic.API/Requests/Library/YLibraryAddBuilder.cs @@ -6,29 +6,28 @@ using YandexMusic.API.Models.Library; using YandexMusic.API.Requests.Common; using YandexMusic.API.Requests.Common.Attributes; -namespace YandexMusic.API.Requests.Library +namespace YandexMusic.API.Requests.Library; + +[YApiRequest(WebRequestMethods.Http.Post, "users/{uid}/{type}/{section}/add-multiple")] +public class YLibraryAddBuilder : YRequestBuilder, (string id, YLibrarySection section, YLibrarySectionType type)> { - [YApiRequest(WebRequestMethods.Http.Post, "users/{uid}/{type}/{section}/add-multiple")] - public class YLibraryAddBuilder : YRequestBuilder, (string id, YLibrarySection section, YLibrarySectionType type)> + public YLibraryAddBuilder(YandexMusicApi yandex, AuthStorage auth) : base(yandex, auth) { - public YLibraryAddBuilder(YandexMusicApi yandex, AuthStorage auth) : base(yandex, auth) - { - } + } - protected override Dictionary GetSubstitutions((string id, YLibrarySection section, YLibrarySectionType type) tuple) - { - return new Dictionary { - { "uid", storage.User.Uid }, - { "type", tuple.type.ToString().ToLower() }, - { "section", tuple.section.ToString().ToLower() }, - }; - } + protected override Dictionary GetSubstitutions((string id, YLibrarySection section, YLibrarySectionType type) tuple) + { + return new Dictionary { + { "uid", storage.User.Uid }, + { "type", tuple.type.ToString().ToLower() }, + { "section", tuple.section.ToString().ToLower() }, + }; + } - protected override HttpContent GetContent((string id, YLibrarySection section, YLibrarySectionType type) tuple) - { - return new FormUrlEncodedContent(new Dictionary { - { $"{tuple.section.ToString().ToLower().TrimEnd('s')}-ids", tuple.id } - }); - } + protected override HttpContent GetContent((string id, YLibrarySection section, YLibrarySectionType type) tuple) + { + return new FormUrlEncodedContent(new Dictionary { + { $"{tuple.section.ToString().ToLower().TrimEnd('s')}-ids", tuple.id } + }); } } \ No newline at end of file diff --git a/YandexMusic.API/Requests/Library/YLibraryRemoveBuilder.cs b/YandexMusic.API/Requests/Library/YLibraryRemoveBuilder.cs index cd07fc4..0809d83 100644 --- a/YandexMusic.API/Requests/Library/YLibraryRemoveBuilder.cs +++ b/YandexMusic.API/Requests/Library/YLibraryRemoveBuilder.cs @@ -6,29 +6,28 @@ using YandexMusic.API.Models.Library; using YandexMusic.API.Requests.Common; using YandexMusic.API.Requests.Common.Attributes; -namespace YandexMusic.API.Requests.Library +namespace YandexMusic.API.Requests.Library; + +[YApiRequest(WebRequestMethods.Http.Post, "users/{uid}/{type}/{section}/remove")] +public class YLibraryRemoveBuilder : YRequestBuilder, (string id, YLibrarySection section, YLibrarySectionType type)> { - [YApiRequest(WebRequestMethods.Http.Post, "users/{uid}/{type}/{section}/remove")] - public class YLibraryRemoveBuilder : YRequestBuilder, (string id, YLibrarySection section, YLibrarySectionType type)> + public YLibraryRemoveBuilder(YandexMusicApi yandex, AuthStorage auth) : base(yandex, auth) { - public YLibraryRemoveBuilder(YandexMusicApi yandex, AuthStorage auth) : base(yandex, auth) - { - } + } - protected override Dictionary GetSubstitutions((string id, YLibrarySection section, YLibrarySectionType type) tuple) - { - return new Dictionary { - { "uid", storage.User.Uid }, - { "type", tuple.type.ToString().ToLower() }, - { "section", tuple.section.ToString().ToLower() }, - }; - } + protected override Dictionary GetSubstitutions((string id, YLibrarySection section, YLibrarySectionType type) tuple) + { + return new Dictionary { + { "uid", storage.User.Uid }, + { "type", tuple.type.ToString().ToLower() }, + { "section", tuple.section.ToString().ToLower() }, + }; + } - protected override HttpContent GetContent((string id, YLibrarySection section, YLibrarySectionType type) tuple) - { - return new FormUrlEncodedContent(new Dictionary { - { $"{tuple.section.ToString().ToLower().TrimEnd('s')}-ids", tuple.id } - }); - } + protected override HttpContent GetContent((string id, YLibrarySection section, YLibrarySectionType type) tuple) + { + return new FormUrlEncodedContent(new Dictionary { + { $"{tuple.section.ToString().ToLower().TrimEnd('s')}-ids", tuple.id } + }); } } \ No newline at end of file diff --git a/YandexMusic.API/Requests/Pins/YGetPinsBuilder.cs b/YandexMusic.API/Requests/Pins/YGetPinsBuilder.cs index 044c927..0621fcd 100644 --- a/YandexMusic.API/Requests/Pins/YGetPinsBuilder.cs +++ b/YandexMusic.API/Requests/Pins/YGetPinsBuilder.cs @@ -6,13 +6,12 @@ using YandexMusic.API.Models.Pins; using YandexMusic.API.Requests.Common; using YandexMusic.API.Requests.Common.Attributes; -namespace YandexMusic.API.Requests.Pins +namespace YandexMusic.API.Requests.Pins; + +[YApiRequest(WebRequestMethods.Http.Get, "pins")] +public class YGetPinsBuilder : YRequestBuilder, object> { - [YApiRequest(WebRequestMethods.Http.Get, "pins")] - public class YGetPinsBuilder : YRequestBuilder, object> + public YGetPinsBuilder(YandexMusicApi yandex, AuthStorage auth) : base(yandex, auth) { - public YGetPinsBuilder(YandexMusicApi yandex, AuthStorage auth) : base(yandex, auth) - { - } } } \ No newline at end of file diff --git a/YandexMusic.API/Requests/Playlist/YGetPlaylistBuilder.cs b/YandexMusic.API/Requests/Playlist/YGetPlaylistBuilder.cs index 7c10838..be05cbf 100644 --- a/YandexMusic.API/Requests/Playlist/YGetPlaylistBuilder.cs +++ b/YandexMusic.API/Requests/Playlist/YGetPlaylistBuilder.cs @@ -6,21 +6,20 @@ using YandexMusic.API.Models.Playlist; using YandexMusic.API.Requests.Common; using YandexMusic.API.Requests.Common.Attributes; -namespace YandexMusic.API.Requests.Playlist -{ - [YApiRequest(WebRequestMethods.Http.Get, "users/{user}/playlists/{kind}")] - public class YGetPlaylistBuilder : YRequestBuilder, (string user, string kind)> - { - public YGetPlaylistBuilder(YandexMusicApi yandex, AuthStorage auth) : base(yandex, auth) - { - } +namespace YandexMusic.API.Requests.Playlist; - protected override Dictionary GetSubstitutions((string user, string kind) tuple) - { - return new Dictionary { - { "user", tuple.user }, - { "kind", tuple.kind }, - }; - } +[YApiRequest(WebRequestMethods.Http.Get, "users/{user}/playlists/{kind}")] +public class YGetPlaylistBuilder : YRequestBuilder, (string user, string kind)> +{ + public YGetPlaylistBuilder(YandexMusicApi yandex, AuthStorage auth) : base(yandex, auth) + { + } + + protected override Dictionary GetSubstitutions((string user, string kind) tuple) + { + return new Dictionary { + { "user", tuple.user }, + { "kind", tuple.kind }, + }; } } \ No newline at end of file diff --git a/YandexMusic.API/Requests/Playlist/YGetPlaylistByUuidBuilder.cs b/YandexMusic.API/Requests/Playlist/YGetPlaylistByUuidBuilder.cs index 9efcdc1..cb816a0 100644 --- a/YandexMusic.API/Requests/Playlist/YGetPlaylistByUuidBuilder.cs +++ b/YandexMusic.API/Requests/Playlist/YGetPlaylistByUuidBuilder.cs @@ -6,20 +6,19 @@ using YandexMusic.API.Models.Playlist; using YandexMusic.API.Requests.Common; using YandexMusic.API.Requests.Common.Attributes; -namespace YandexMusic.API.Requests.Playlist -{ - [YApiRequest(WebRequestMethods.Http.Get, "playlist/{uuid}")] - public class YGetPlaylistByUuidBuilder : YRequestBuilder, string> - { - public YGetPlaylistByUuidBuilder(YandexMusicApi yandex, AuthStorage auth) : base(yandex, auth) - { - } +namespace YandexMusic.API.Requests.Playlist; - protected override Dictionary GetSubstitutions(string uuid) - { - return new Dictionary { - { "uuid", uuid }, - }; - } +[YApiRequest(WebRequestMethods.Http.Get, "playlist/{uuid}")] +public class YGetPlaylistByUuidBuilder : YRequestBuilder, string> +{ + public YGetPlaylistByUuidBuilder(YandexMusicApi yandex, AuthStorage auth) : base(yandex, auth) + { + } + + protected override Dictionary GetSubstitutions(string uuid) + { + return new Dictionary { + { "uuid", uuid }, + }; } } \ No newline at end of file diff --git a/YandexMusic.API/Requests/Playlist/YGetPlaylistFavoritesBuilder.cs b/YandexMusic.API/Requests/Playlist/YGetPlaylistFavoritesBuilder.cs index 43b7642..6ca4bd9 100644 --- a/YandexMusic.API/Requests/Playlist/YGetPlaylistFavoritesBuilder.cs +++ b/YandexMusic.API/Requests/Playlist/YGetPlaylistFavoritesBuilder.cs @@ -6,20 +6,19 @@ using YandexMusic.API.Models.Playlist; using YandexMusic.API.Requests.Common; using YandexMusic.API.Requests.Common.Attributes; -namespace YandexMusic.API.Requests.Playlist -{ - [YApiRequest(WebRequestMethods.Http.Get, "users/{uid}/playlists/list")] - public class YGetPlaylistFavoritesBuilder : YRequestBuilder>, object> - { - public YGetPlaylistFavoritesBuilder(YandexMusicApi yandex, AuthStorage auth) : base(yandex, auth) - { - } +namespace YandexMusic.API.Requests.Playlist; - protected override Dictionary GetSubstitutions(object tuple) - { - return new Dictionary { - { "uid", storage.User.Uid } - }; - } +[YApiRequest(WebRequestMethods.Http.Get, "users/{uid}/playlists/list")] +public class YGetPlaylistFavoritesBuilder : YRequestBuilder>, object> +{ + public YGetPlaylistFavoritesBuilder(YandexMusicApi yandex, AuthStorage auth) : base(yandex, auth) + { + } + + protected override Dictionary GetSubstitutions(object tuple) + { + return new Dictionary { + { "uid", storage.User.Uid } + }; } } \ No newline at end of file diff --git a/YandexMusic.API/Requests/Playlist/YGetPlaylistsBuilder.cs b/YandexMusic.API/Requests/Playlist/YGetPlaylistsBuilder.cs index fdc2860..901d595 100644 --- a/YandexMusic.API/Requests/Playlist/YGetPlaylistsBuilder.cs +++ b/YandexMusic.API/Requests/Playlist/YGetPlaylistsBuilder.cs @@ -6,20 +6,19 @@ using YandexMusic.API.Models.Playlist; using YandexMusic.API.Requests.Common; using YandexMusic.API.Requests.Common.Attributes; -namespace YandexMusic.API.Requests.Playlist -{ - [YApiRequest(WebRequestMethods.Http.Post, "playlists/list")] - public class YGetPlaylistsBuilder : YRequestBuilder>, IEnumerable<(string User, string Kind)>> - { - public YGetPlaylistsBuilder(YandexMusicApi yandex, AuthStorage auth) : base(yandex, auth) - { - } +namespace YandexMusic.API.Requests.Playlist; - protected override HttpContent GetContent(IEnumerable<(string User, string Kind)> playlistIds) - { - return new FormUrlEncodedContent(new Dictionary { - { "playlist-Ids", string.Join(",", playlistIds.Select(t => $"{t.User}:{t.Kind}")) } - }); - } +[YApiRequest(WebRequestMethods.Http.Post, "playlists/list")] +public class YGetPlaylistsBuilder : YRequestBuilder>, IEnumerable<(string User, string Kind)>> +{ + public YGetPlaylistsBuilder(YandexMusicApi yandex, AuthStorage auth) : base(yandex, auth) + { + } + + protected override HttpContent GetContent(IEnumerable<(string User, string Kind)> playlistIds) + { + return new FormUrlEncodedContent(new Dictionary { + { "playlist-Ids", string.Join(",", playlistIds.Select(t => $"{t.User}:{t.Kind}")) } + }); } } \ No newline at end of file diff --git a/YandexMusic.API/Requests/Playlist/YPlaylistChangeBuilder.cs b/YandexMusic.API/Requests/Playlist/YPlaylistChangeBuilder.cs index ee300c4..1d543da 100644 --- a/YandexMusic.API/Requests/Playlist/YPlaylistChangeBuilder.cs +++ b/YandexMusic.API/Requests/Playlist/YPlaylistChangeBuilder.cs @@ -6,30 +6,29 @@ using YandexMusic.API.Models.Playlist; using YandexMusic.API.Requests.Common; using YandexMusic.API.Requests.Common.Attributes; -namespace YandexMusic.API.Requests.Playlist +namespace YandexMusic.API.Requests.Playlist; + +[YApiRequest(WebRequestMethods.Http.Post, "users/{uid}/playlists/{kind}/change")] +public class YPlaylistChangeBuilder : YRequestBuilder, (YPlaylist playlist, IEnumerable changes)> { - [YApiRequest(WebRequestMethods.Http.Post, "users/{uid}/playlists/{kind}/change")] - public class YPlaylistChangeBuilder : YRequestBuilder, (YPlaylist playlist, IEnumerable changes)> + public YPlaylistChangeBuilder(YandexMusicApi yandex, AuthStorage auth) : base(yandex, auth) { - public YPlaylistChangeBuilder(YandexMusicApi yandex, AuthStorage auth) : base(yandex, auth) - { - } + } - protected override Dictionary GetSubstitutions((YPlaylist playlist, IEnumerable changes) tuple) - { - return new Dictionary { - { "uid", storage.User.Uid }, - { "kind", tuple.playlist.Kind } - }; - } + protected override Dictionary GetSubstitutions((YPlaylist playlist, IEnumerable changes) tuple) + { + return new Dictionary { + { "uid", storage.User.Uid }, + { "kind", tuple.playlist.Kind } + }; + } - protected override HttpContent GetContent((YPlaylist playlist, IEnumerable changes) tuple) - { - return new FormUrlEncodedContent(new Dictionary { - { "kind", tuple.playlist.Kind }, - { "revision", tuple.playlist.Revision.ToString() }, - { "diff", SerializeJson(tuple.changes) } - }); - } + protected override HttpContent GetContent((YPlaylist playlist, IEnumerable changes) tuple) + { + return new FormUrlEncodedContent(new Dictionary { + { "kind", tuple.playlist.Kind }, + { "revision", tuple.playlist.Revision.ToString() }, + { "diff", SerializeJson(tuple.changes) } + }); } } \ No newline at end of file diff --git a/YandexMusic.API/Requests/Playlist/YPlaylistCreateBuilder.cs b/YandexMusic.API/Requests/Playlist/YPlaylistCreateBuilder.cs index 2769d75..c835683 100644 --- a/YandexMusic.API/Requests/Playlist/YPlaylistCreateBuilder.cs +++ b/YandexMusic.API/Requests/Playlist/YPlaylistCreateBuilder.cs @@ -6,28 +6,27 @@ using YandexMusic.API.Models.Playlist; using YandexMusic.API.Requests.Common; using YandexMusic.API.Requests.Common.Attributes; -namespace YandexMusic.API.Requests.Playlist +namespace YandexMusic.API.Requests.Playlist; + +[YApiRequest(WebRequestMethods.Http.Post, "users/{uid}/playlists/create")] +public class YPlaylistCreateBuilder : YRequestBuilder, string> { - [YApiRequest(WebRequestMethods.Http.Post, "users/{uid}/playlists/create")] - public class YPlaylistCreateBuilder : YRequestBuilder, string> + public YPlaylistCreateBuilder(YandexMusicApi yandex, AuthStorage auth) : base(yandex, auth) { - public YPlaylistCreateBuilder(YandexMusicApi yandex, AuthStorage auth) : base(yandex, auth) - { - } + } - protected override Dictionary GetSubstitutions(string name) - { - return new Dictionary { - { "uid", storage.User.Uid } - }; - } + protected override Dictionary GetSubstitutions(string name) + { + return new Dictionary { + { "uid", storage.User.Uid } + }; + } - protected override HttpContent GetContent(string name) - { - return new FormUrlEncodedContent(new Dictionary { - { "title", name }, - { "visibility", "public" } - }); - } + protected override HttpContent GetContent(string name) + { + return new FormUrlEncodedContent(new Dictionary { + { "title", name }, + { "visibility", "public" } + }); } } \ No newline at end of file diff --git a/YandexMusic.API/Requests/Playlist/YPlaylistRemoveBuilder.cs b/YandexMusic.API/Requests/Playlist/YPlaylistRemoveBuilder.cs index de3636b..19b8226 100644 --- a/YandexMusic.API/Requests/Playlist/YPlaylistRemoveBuilder.cs +++ b/YandexMusic.API/Requests/Playlist/YPlaylistRemoveBuilder.cs @@ -6,28 +6,27 @@ using YandexMusic.API.Models.Playlist; using YandexMusic.API.Requests.Common; using YandexMusic.API.Requests.Common.Attributes; -namespace YandexMusic.API.Requests.Playlist +namespace YandexMusic.API.Requests.Playlist; + +[YApiRequest(WebRequestMethods.Http.Post, "users/{uid}/playlists/{kind}/name")] +public class YPlaylistRenameBuilder : YRequestBuilder, (string kind, string name)> { - [YApiRequest(WebRequestMethods.Http.Post, "users/{uid}/playlists/{kind}/name")] - public class YPlaylistRenameBuilder : YRequestBuilder, (string kind, string name)> + public YPlaylistRenameBuilder(YandexMusicApi yandex, AuthStorage auth) : base(yandex, auth) { - public YPlaylistRenameBuilder(YandexMusicApi yandex, AuthStorage auth) : base(yandex, auth) - { - } + } - protected override Dictionary GetSubstitutions((string kind, string name) tuple) - { - return new Dictionary { - { "uid", storage.User.Uid }, - { "kind", tuple.kind } - }; - } + protected override Dictionary GetSubstitutions((string kind, string name) tuple) + { + return new Dictionary { + { "uid", storage.User.Uid }, + { "kind", tuple.kind } + }; + } - protected override HttpContent GetContent((string kind, string name) tuple) - { - return new FormUrlEncodedContent(new Dictionary { - { "value", tuple.name } - }); - } + protected override HttpContent GetContent((string kind, string name) tuple) + { + return new FormUrlEncodedContent(new Dictionary { + { "value", tuple.name } + }); } } \ No newline at end of file diff --git a/YandexMusic.API/Requests/Playlist/YPlaylistRenameBuilder.cs b/YandexMusic.API/Requests/Playlist/YPlaylistRenameBuilder.cs index 1cd8550..04dcb12 100644 --- a/YandexMusic.API/Requests/Playlist/YPlaylistRenameBuilder.cs +++ b/YandexMusic.API/Requests/Playlist/YPlaylistRenameBuilder.cs @@ -4,21 +4,20 @@ using YandexMusic.API.Common; using YandexMusic.API.Requests.Common; using YandexMusic.API.Requests.Common.Attributes; -namespace YandexMusic.API.Requests.Playlist -{ - [YApiRequest(WebRequestMethods.Http.Post, "users/{uid}/playlists/{kind}/delete")] - public class YPlaylistRemoveBuilder : YRequestBuilder - { - public YPlaylistRemoveBuilder(YandexMusicApi yandex, AuthStorage auth) : base(yandex, auth) - { - } +namespace YandexMusic.API.Requests.Playlist; - protected override Dictionary GetSubstitutions(string kind) - { - return new Dictionary { - { "uid", storage.User.Uid }, - { "kind", kind } - }; - } +[YApiRequest(WebRequestMethods.Http.Post, "users/{uid}/playlists/{kind}/delete")] +public class YPlaylistRemoveBuilder : YRequestBuilder +{ + public YPlaylistRemoveBuilder(YandexMusicApi yandex, AuthStorage auth) : base(yandex, auth) + { + } + + protected override Dictionary GetSubstitutions(string kind) + { + return new Dictionary { + { "uid", storage.User.Uid }, + { "kind", kind } + }; } } \ No newline at end of file diff --git a/YandexMusic.API/Requests/Queue/YGetQueueBuilder.cs b/YandexMusic.API/Requests/Queue/YGetQueueBuilder.cs index d564833..95da016 100644 --- a/YandexMusic.API/Requests/Queue/YGetQueueBuilder.cs +++ b/YandexMusic.API/Requests/Queue/YGetQueueBuilder.cs @@ -6,20 +6,19 @@ using YandexMusic.API.Models.Queue; using YandexMusic.API.Requests.Common; using YandexMusic.API.Requests.Common.Attributes; -namespace YandexMusic.API.Requests.Queue -{ - [YApiRequest(WebRequestMethods.Http.Get, "queues/{queueId}")] - public class YGetQueueBuilder : YRequestBuilder, string> - { - public YGetQueueBuilder(YandexMusicApi yandex, AuthStorage auth) : base(yandex, auth) - { - } +namespace YandexMusic.API.Requests.Queue; - protected override Dictionary GetSubstitutions(string queueId) - { - return new Dictionary { - { "queueId", queueId } - }; - } +[YApiRequest(WebRequestMethods.Http.Get, "queues/{queueId}")] +public class YGetQueueBuilder : YRequestBuilder, string> +{ + public YGetQueueBuilder(YandexMusicApi yandex, AuthStorage auth) : base(yandex, auth) + { + } + + protected override Dictionary GetSubstitutions(string queueId) + { + return new Dictionary { + { "queueId", queueId } + }; } } diff --git a/YandexMusic.API/Requests/Queue/YQueueCreateBuilder.cs b/YandexMusic.API/Requests/Queue/YQueueCreateBuilder.cs index aef7005..323998c 100644 --- a/YandexMusic.API/Requests/Queue/YQueueCreateBuilder.cs +++ b/YandexMusic.API/Requests/Queue/YQueueCreateBuilder.cs @@ -11,34 +11,33 @@ using YandexMusic.API.Models.Queue; using YandexMusic.API.Requests.Common; using YandexMusic.API.Requests.Common.Attributes; -namespace YandexMusic.API.Requests.Queue +namespace YandexMusic.API.Requests.Queue; + +[YApiRequest(WebRequestMethods.Http.Post, "queues")] +public class YQueueCreateBuilder : YRequestBuilder, YQueue> { - [YApiRequest(WebRequestMethods.Http.Post, "queues")] - public class YQueueCreateBuilder : YRequestBuilder, YQueue> + public YQueueCreateBuilder(YandexMusicApi yandex, AuthStorage auth, string? device = null) : base(yandex, auth) { - public YQueueCreateBuilder(YandexMusicApi yandex, AuthStorage auth, string device = null) : base(yandex, auth) - { - if (device != null) - this.device = device; - } + if (device != null) + this.device = device; + } - protected override HttpContent GetContent(YQueue queue) + protected override HttpContent GetContent(YQueue queue) + { + JsonSerializerOptions settings = new() { - JsonSerializerOptions settings = new() - { - Converters = { - new JsonStringEnumConverter() - }, - Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping, - PropertyNamingPolicy = JsonNamingPolicy.CamelCase - }; + Converters = { + new JsonStringEnumConverter() + }, + Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping, + PropertyNamingPolicy = JsonNamingPolicy.CamelCase + }; - return JsonContent.Create(queue, new MediaTypeHeaderValue("application/json"), settings); - } + return JsonContent.Create(queue, new MediaTypeHeaderValue("application/json"), settings); + } - protected override void SetCustomHeaders(HttpRequestHeaders headers) - { - headers.Add("X-Yandex-Music-Device", device); - } + protected override void SetCustomHeaders(HttpRequestHeaders headers) + { + headers.Add("X-Yandex-Music-Device", device); } } diff --git a/YandexMusic.API/Requests/Queue/YQueueUpdatePositionBuilder.cs b/YandexMusic.API/Requests/Queue/YQueueUpdatePositionBuilder.cs index fe5e730..c58990c 100644 --- a/YandexMusic.API/Requests/Queue/YQueueUpdatePositionBuilder.cs +++ b/YandexMusic.API/Requests/Queue/YQueueUpdatePositionBuilder.cs @@ -8,35 +8,34 @@ using YandexMusic.API.Models.Queue; using YandexMusic.API.Requests.Common; using YandexMusic.API.Requests.Common.Attributes; -namespace YandexMusic.API.Requests.Queue +namespace YandexMusic.API.Requests.Queue; + +[YApiRequest(WebRequestMethods.Http.Post, "queues/{queueId}/update-position")] +public class YQueueUpdatePositionBuilder : YRequestBuilder, (string queueId, int currentIndex, bool isInteractive)> { - [YApiRequest(WebRequestMethods.Http.Post, "queues/{queueId}/update-position")] - public class YQueueUpdatePositionBuilder : YRequestBuilder, (string queueId, int currentIndex, bool isInteractive)> + public YQueueUpdatePositionBuilder(YandexMusicApi yandex, AuthStorage auth, string device = null) : base(yandex, auth) { - public YQueueUpdatePositionBuilder(YandexMusicApi yandex, AuthStorage auth, string device = null) : base(yandex, auth) - { - if (device != null) - this.device = device; - } + if (device != null) + this.device = device; + } - protected override Dictionary GetSubstitutions((string queueId, int currentIndex, bool isInteractive) tuple) - { - return new Dictionary { - { "queueId", tuple.queueId }, - }; - } + protected override Dictionary GetSubstitutions((string queueId, int currentIndex, bool isInteractive) tuple) + { + return new Dictionary { + { "queueId", tuple.queueId }, + }; + } - protected override void SetCustomHeaders(HttpRequestHeaders headers) - { - headers.Add("X-Yandex-Music-Device", device); - } + protected override void SetCustomHeaders(HttpRequestHeaders headers) + { + headers.Add("X-Yandex-Music-Device", device); + } - protected override NameValueCollection GetQueryParams((string queueId, int currentIndex, bool isInteractive) tuple) - { - return new NameValueCollection { - { "currentIndex", tuple.currentIndex.ToString() }, - { "isInteractive", tuple.isInteractive.ToString().ToLower() } - }; - } + protected override NameValueCollection GetQueryParams((string queueId, int currentIndex, bool isInteractive) tuple) + { + return new NameValueCollection { + { "currentIndex", tuple.currentIndex.ToString() }, + { "isInteractive", tuple.isInteractive.ToString().ToLower() } + }; } } diff --git a/YandexMusic.API/Requests/Queue/YQueuesListBuilder.cs b/YandexMusic.API/Requests/Queue/YQueuesListBuilder.cs index 898d64a..26f5ccd 100644 --- a/YandexMusic.API/Requests/Queue/YQueuesListBuilder.cs +++ b/YandexMusic.API/Requests/Queue/YQueuesListBuilder.cs @@ -7,20 +7,19 @@ using YandexMusic.API.Models.Queue; using YandexMusic.API.Requests.Common; using YandexMusic.API.Requests.Common.Attributes; -namespace YandexMusic.API.Requests.Queue -{ - [YApiRequest(WebRequestMethods.Http.Get, "queues")] - public class YQueuesListBuilder : YRequestBuilder, string> - { - public YQueuesListBuilder(YandexMusicApi yandex, AuthStorage auth, string device = null) : base(yandex, auth) - { - if (device != null) - this.device = device; - } +namespace YandexMusic.API.Requests.Queue; - protected override void SetCustomHeaders(HttpRequestHeaders headers) - { - headers.Add("X-Yandex-Music-Device", device); - } +[YApiRequest(WebRequestMethods.Http.Get, "queues")] +public class YQueuesListBuilder : YRequestBuilder, string> +{ + public YQueuesListBuilder(YandexMusicApi yandex, AuthStorage auth, string? device = null) : base(yandex, auth) + { + if (device != null) + this.device = device; + } + + protected override void SetCustomHeaders(HttpRequestHeaders headers) + { + headers.Add("X-Yandex-Music-Device", device); } } diff --git a/YandexMusic.API/Requests/Radio/YGetStationBuilder.cs b/YandexMusic.API/Requests/Radio/YGetStationBuilder.cs index df3254e..18497d8 100644 --- a/YandexMusic.API/Requests/Radio/YGetStationBuilder.cs +++ b/YandexMusic.API/Requests/Radio/YGetStationBuilder.cs @@ -6,21 +6,20 @@ using YandexMusic.API.Models.Radio; using YandexMusic.API.Requests.Common; using YandexMusic.API.Requests.Common.Attributes; -namespace YandexMusic.API.Requests.Radio -{ - [YApiRequest(WebRequestMethods.Http.Get, "rotor/station/{type}:{tag}/info")] - public class YGetStationBuilder : YRequestBuilder>, (string type, string tag)> - { - public YGetStationBuilder(YandexMusicApi yandex, AuthStorage auth) : base(yandex, auth) - { - } +namespace YandexMusic.API.Requests.Radio; - protected override Dictionary GetSubstitutions((string type, string tag) tuple) - { - return new Dictionary { - { "type", tuple.type }, - { "tag", tuple.tag } - }; - } +[YApiRequest(WebRequestMethods.Http.Get, "rotor/station/{type}:{tag}/info")] +public class YGetStationBuilder : YRequestBuilder>, (string type, string tag)> +{ + public YGetStationBuilder(YandexMusicApi yandex, AuthStorage auth) : base(yandex, auth) + { + } + + protected override Dictionary GetSubstitutions((string type, string tag) tuple) + { + return new Dictionary { + { "type", tuple.type }, + { "tag", tuple.tag } + }; } } \ No newline at end of file diff --git a/YandexMusic.API/Requests/Radio/YGetStationTracksBuilder.cs b/YandexMusic.API/Requests/Radio/YGetStationTracksBuilder.cs index 64cb14b..077600f 100644 --- a/YandexMusic.API/Requests/Radio/YGetStationTracksBuilder.cs +++ b/YandexMusic.API/Requests/Radio/YGetStationTracksBuilder.cs @@ -7,33 +7,32 @@ using YandexMusic.API.Models.Radio; using YandexMusic.API.Requests.Common; using YandexMusic.API.Requests.Common.Attributes; -namespace YandexMusic.API.Requests.Radio +namespace YandexMusic.API.Requests.Radio; + +[YApiRequest(WebRequestMethods.Http.Get, "rotor/station/{type}:{tag}/tracks")] +public class YGetStationTracksBuilder : YRequestBuilder, (YStationDescription station, string prevTrackId)> { - [YApiRequest(WebRequestMethods.Http.Get, "rotor/station/{type}:{tag}/tracks")] - public class YGetStationTracksBuilder : YRequestBuilder, (YStationDescription station, string prevTrackId)> + public YGetStationTracksBuilder(YandexMusicApi yandex, AuthStorage auth) : base(yandex, auth) { - public YGetStationTracksBuilder(YandexMusicApi yandex, AuthStorage auth) : base(yandex, auth) - { - } + } - protected override Dictionary GetSubstitutions((YStationDescription station, string prevTrackId) tuple) - { - return new Dictionary { - { "type", tuple.station.Id.Type }, - { "tag", tuple.station.Id.Tag }, - }; - } + protected override Dictionary GetSubstitutions((YStationDescription station, string prevTrackId) tuple) + { + return new Dictionary { + { "type", tuple.station.Id.Type }, + { "tag", tuple.station.Id.Tag }, + }; + } - protected override NameValueCollection GetQueryParams((YStationDescription station, string prevTrackId) tuple) - { - NameValueCollection query = new() { - { "settings2", "true" } - }; + protected override NameValueCollection GetQueryParams((YStationDescription station, string prevTrackId) tuple) + { + NameValueCollection query = new() { + { "settings2", "true" } + }; - if (!string.IsNullOrEmpty(tuple.prevTrackId)) - query.Add("queue", tuple.prevTrackId); + if (!string.IsNullOrEmpty(tuple.prevTrackId)) + query.Add("queue", tuple.prevTrackId); - return base.GetQueryParams(tuple); - } + return base.GetQueryParams(tuple); } } \ No newline at end of file diff --git a/YandexMusic.API/Requests/Radio/YGetStationsBuilder.cs b/YandexMusic.API/Requests/Radio/YGetStationsBuilder.cs index c41a393..b70e315 100644 --- a/YandexMusic.API/Requests/Radio/YGetStationsBuilder.cs +++ b/YandexMusic.API/Requests/Radio/YGetStationsBuilder.cs @@ -6,13 +6,12 @@ using YandexMusic.API.Models.Radio; using YandexMusic.API.Requests.Common; using YandexMusic.API.Requests.Common.Attributes; -namespace YandexMusic.API.Requests.Radio +namespace YandexMusic.API.Requests.Radio; + +[YApiRequest(WebRequestMethods.Http.Get, "rotor/stations/list")] +public class YGetStationsBuilder : YRequestBuilder>, object> { - [YApiRequest(WebRequestMethods.Http.Get, "rotor/stations/list")] - public class YGetStationsBuilder : YRequestBuilder>, object> + public YGetStationsBuilder(YandexMusicApi yandex, AuthStorage auth) : base(yandex, auth) { - public YGetStationsBuilder(YandexMusicApi yandex, AuthStorage auth) : base(yandex, auth) - { - } } } \ No newline at end of file diff --git a/YandexMusic.API/Requests/Radio/YGetStationsDashboardBuilder.cs b/YandexMusic.API/Requests/Radio/YGetStationsDashboardBuilder.cs index 8a7f152..27fc73e 100644 --- a/YandexMusic.API/Requests/Radio/YGetStationsDashboardBuilder.cs +++ b/YandexMusic.API/Requests/Radio/YGetStationsDashboardBuilder.cs @@ -6,13 +6,12 @@ using YandexMusic.API.Models.Radio; using YandexMusic.API.Requests.Common; using YandexMusic.API.Requests.Common.Attributes; -namespace YandexMusic.API.Requests.Radio +namespace YandexMusic.API.Requests.Radio; + +[YApiRequest(WebRequestMethods.Http.Get, "rotor/stations/dashboard")] +public class YGetStationsDashboardBuilder : YRequestBuilder, object> { - [YApiRequest(WebRequestMethods.Http.Get, "rotor/stations/dashboard")] - public class YGetStationsDashboardBuilder : YRequestBuilder, object> + public YGetStationsDashboardBuilder(YandexMusicApi yandex, AuthStorage auth) : base(yandex, auth) { - public YGetStationsDashboardBuilder(YandexMusicApi yandex, AuthStorage auth) : base(yandex, auth) - { - } } } \ No newline at end of file diff --git a/YandexMusic.API/Requests/Radio/YSetSettings2Builder.cs b/YandexMusic.API/Requests/Radio/YSetSettings2Builder.cs index a9b5ab6..f77bee3 100644 --- a/YandexMusic.API/Requests/Radio/YSetSettings2Builder.cs +++ b/YandexMusic.API/Requests/Radio/YSetSettings2Builder.cs @@ -11,36 +11,35 @@ using YandexMusic.API.Models.Radio; using YandexMusic.API.Requests.Common; using YandexMusic.API.Requests.Common.Attributes; -namespace YandexMusic.API.Requests.Radio +namespace YandexMusic.API.Requests.Radio; + +[YApiRequest(WebRequestMethods.Http.Post, "rotor/station/{type}:{tag}/settings2")] +public class YSetSettings2Builder : YRequestBuilder, (YStationDescription station, YStationSettings2 settings2)> { - [YApiRequest(WebRequestMethods.Http.Post, "rotor/station/{type}:{tag}/settings2")] - public class YSetSettings2Builder : YRequestBuilder, (YStationDescription station, YStationSettings2 settings2)> + public YSetSettings2Builder(YandexMusicApi yandex, AuthStorage auth) : base(yandex, auth) { - public YSetSettings2Builder(YandexMusicApi yandex, AuthStorage auth) : base(yandex, auth) - { - } + } - protected override Dictionary GetSubstitutions((YStationDescription station, YStationSettings2 settings2) tuple) - { - return new Dictionary { - { "type", tuple.station.Id.Type }, - { "tag", tuple.station.Id.Tag }, - }; - } + protected override Dictionary GetSubstitutions((YStationDescription station, YStationSettings2 settings2) tuple) + { + return new Dictionary { + { "type", tuple.station.Id.Type }, + { "tag", tuple.station.Id.Tag }, + }; + } - protected override HttpContent GetContent((YStationDescription station, YStationSettings2 settings2) tuple) + protected override HttpContent GetContent((YStationDescription station, YStationSettings2 settings2) tuple) + { + JsonSerializerOptions settings = new() { - JsonSerializerOptions settings = new() - { - Converters = { - new JsonStringEnumConverter() - }, - Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping, - PropertyNamingPolicy = JsonNamingPolicy.CamelCase, - DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull - }; + Converters = { + new JsonStringEnumConverter() + }, + Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping, + PropertyNamingPolicy = JsonNamingPolicy.CamelCase, + DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull + }; - return JsonContent.Create(tuple.settings2, new MediaTypeHeaderValue("application/json"), settings); - } + return JsonContent.Create(tuple.settings2, new MediaTypeHeaderValue("application/json"), settings); } } \ No newline at end of file diff --git a/YandexMusic.API/Requests/Radio/YSetStationFeedbackBuilder.cs b/YandexMusic.API/Requests/Radio/YSetStationFeedbackBuilder.cs index 0c532d2..a2611d0 100644 --- a/YandexMusic.API/Requests/Radio/YSetStationFeedbackBuilder.cs +++ b/YandexMusic.API/Requests/Radio/YSetStationFeedbackBuilder.cs @@ -12,61 +12,60 @@ using YandexMusic.API.Models.Track; using YandexMusic.API.Requests.Common; using YandexMusic.API.Requests.Common.Attributes; -namespace YandexMusic.API.Requests.Radio +namespace YandexMusic.API.Requests.Radio; + +[YApiRequest(WebRequestMethods.Http.Post, "rotor/station/{type}:{tag}/feedback")] +public class YSetStationFeedbackBuilder : YRequestBuilder { - [YApiRequest(WebRequestMethods.Http.Post, "rotor/station/{type}:{tag}/feedback")] - public class YSetStationFeedbackBuilder : YRequestBuilder + public YSetStationFeedbackBuilder(YandexMusicApi yandex, AuthStorage auth) : base(yandex, auth) { - public YSetStationFeedbackBuilder(YandexMusicApi yandex, AuthStorage auth) : base(yandex, auth) + } + + protected override Dictionary GetSubstitutions((YStationFeedbackType type, YStation station, YTrack track, string batchId, double totalPlayedSeconds) tuple) + { + return new Dictionary { + { "type", tuple.station.Station.Id.Type }, + { "tag", tuple.station.Station.Id.Tag } + }; + } + + protected override HttpContent GetContent((YStationFeedbackType type, YStation station, YTrack track, string batchId, double totalPlayedSeconds) tuple) + { + long timestamp = ((DateTimeOffset)DateTime.Now).ToUnixTimeSeconds(); + + JsonSerializerOptions settings = new() { - } + Converters = { + new JsonStringEnumConverter(JsonNamingPolicy.CamelCase) + }, + Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping, + PropertyNamingPolicy = JsonNamingPolicy.CamelCase, + DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingDefault + }; - protected override Dictionary GetSubstitutions((YStationFeedbackType type, YStation station, YTrack track, string batchId, double totalPlayedSeconds) tuple) + YStationFeedback feedBack = new() { - return new Dictionary { - { "type", tuple.station.Station.Id.Type }, - { "tag", tuple.station.Station.Id.Tag } - }; - } + Type = tuple.type, + From = tuple.station.Station.IdForFrom, + Timestamp = timestamp + }; - protected override HttpContent GetContent((YStationFeedbackType type, YStation station, YTrack track, string batchId, double totalPlayedSeconds) tuple) - { - long timestamp = ((DateTimeOffset)DateTime.Now).ToUnixTimeSeconds(); + if (tuple.track != null) + feedBack.TrackId = tuple.track.Id; - JsonSerializerOptions settings = new() - { - Converters = { - new JsonStringEnumConverter(JsonNamingPolicy.CamelCase) - }, - Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping, - PropertyNamingPolicy = JsonNamingPolicy.CamelCase, - DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingDefault - }; + if (tuple.totalPlayedSeconds > 0) + feedBack.TotalPlayedSeconds = tuple.totalPlayedSeconds; - YStationFeedback feedBack = new() - { - Type = tuple.type, - From = tuple.station.Station.IdForFrom, - Timestamp = timestamp - }; + return JsonContent.Create(feedBack, new MediaTypeHeaderValue("application/json"), settings); ; + } - if (tuple.track != null) - feedBack.TrackId = tuple.track.Id; + protected override NameValueCollection GetQueryParams((YStationFeedbackType type, YStation station, YTrack track, string batchId, double totalPlayedSeconds) tuple) + { + NameValueCollection query = new(); - if (tuple.totalPlayedSeconds > 0) - feedBack.TotalPlayedSeconds = tuple.totalPlayedSeconds; + if (!string.IsNullOrWhiteSpace(tuple.batchId)) + query.Add("batch-id", tuple.batchId); - return JsonContent.Create(feedBack, new MediaTypeHeaderValue("application/json"), settings); ; - } - - protected override NameValueCollection GetQueryParams((YStationFeedbackType type, YStation station, YTrack track, string batchId, double totalPlayedSeconds) tuple) - { - NameValueCollection query = new(); - - if (!string.IsNullOrWhiteSpace(tuple.batchId)) - query.Add("batch-id", tuple.batchId); - - return query; - } + return query; } } \ No newline at end of file diff --git a/YandexMusic.API/Requests/Search/YSearchBuilder.cs b/YandexMusic.API/Requests/Search/YSearchBuilder.cs index d23926e..e8f9689 100644 --- a/YandexMusic.API/Requests/Search/YSearchBuilder.cs +++ b/YandexMusic.API/Requests/Search/YSearchBuilder.cs @@ -7,23 +7,22 @@ using YandexMusic.API.Models.Search; using YandexMusic.API.Requests.Common; using YandexMusic.API.Requests.Common.Attributes; -namespace YandexMusic.API.Requests.Search -{ - [YApiRequest(WebRequestMethods.Http.Get, "search")] - public class YSearchBuilder : YRequestBuilder, (string searchText, YSearchType searchType, int page, int pageSize)> - { - public YSearchBuilder(YandexMusicApi yandex, AuthStorage auth) : base(yandex, auth) - { - } +namespace YandexMusic.API.Requests.Search; - protected override NameValueCollection GetQueryParams((string searchText, YSearchType searchType, int page, int pageSize) tuple) - { - return new NameValueCollection { - { "text", tuple.searchText }, - { "type", tuple.searchType.ToString() }, - { "page", tuple.page.ToString() }, - { "pageSize", tuple.pageSize.ToString() } - }; - } +[YApiRequest(WebRequestMethods.Http.Get, "search")] +public class YSearchBuilder : YRequestBuilder, (string searchText, YSearchType searchType, int page, int pageSize)> +{ + public YSearchBuilder(YandexMusicApi yandex, AuthStorage auth) : base(yandex, auth) + { + } + + protected override NameValueCollection GetQueryParams((string searchText, YSearchType searchType, int page, int pageSize) tuple) + { + return new NameValueCollection { + { "text", tuple.searchText }, + { "type", tuple.searchType.ToString() }, + { "page", tuple.page.ToString() }, + { "pageSize", tuple.pageSize.ToString() } + }; } } \ No newline at end of file diff --git a/YandexMusic.API/Requests/Search/YSearchSuggestBuilder.cs b/YandexMusic.API/Requests/Search/YSearchSuggestBuilder.cs index ff566d7..24356e2 100644 --- a/YandexMusic.API/Requests/Search/YSearchSuggestBuilder.cs +++ b/YandexMusic.API/Requests/Search/YSearchSuggestBuilder.cs @@ -7,20 +7,19 @@ using YandexMusic.API.Models.Search; using YandexMusic.API.Requests.Common; using YandexMusic.API.Requests.Common.Attributes; -namespace YandexMusic.API.Requests.Search -{ - [YApiRequest(WebRequestMethods.Http.Get, "search/suggest")] - public class YSearchSuggestBuilder : YRequestBuilder, string> - { - public YSearchSuggestBuilder(YandexMusicApi yandex, AuthStorage auth) : base(yandex, auth) - { - } +namespace YandexMusic.API.Requests.Search; - protected override NameValueCollection GetQueryParams(string searchText) - { - return new NameValueCollection { - { "part", searchText } - }; - } +[YApiRequest(WebRequestMethods.Http.Get, "search/suggest")] +public class YSearchSuggestBuilder : YRequestBuilder, string> +{ + public YSearchSuggestBuilder(YandexMusicApi yandex, AuthStorage auth) : base(yandex, auth) + { + } + + protected override NameValueCollection GetQueryParams(string searchText) + { + return new NameValueCollection { + { "part", searchText } + }; } } \ No newline at end of file diff --git a/YandexMusic.API/Requests/Track/YGetTrackSimilarBuilder.cs b/YandexMusic.API/Requests/Track/YGetTrackSimilarBuilder.cs index b7bb568..a770e3e 100644 --- a/YandexMusic.API/Requests/Track/YGetTrackSimilarBuilder.cs +++ b/YandexMusic.API/Requests/Track/YGetTrackSimilarBuilder.cs @@ -6,20 +6,19 @@ using YandexMusic.API.Models.Track; using YandexMusic.API.Requests.Common; using YandexMusic.API.Requests.Common.Attributes; -namespace YandexMusic.API.Requests.Track -{ - [YApiRequest(WebRequestMethods.Http.Get, "tracks/{trackId}/similar")] - public class YGetTrackSimilarBuilder : YRequestBuilder, string> - { - public YGetTrackSimilarBuilder(YandexMusicApi yandex, AuthStorage auth) : base(yandex, auth) - { - } +namespace YandexMusic.API.Requests.Track; - protected override Dictionary GetSubstitutions(string trackId) - { - return new Dictionary { - { "trackId", trackId } - }; - } +[YApiRequest(WebRequestMethods.Http.Get, "tracks/{trackId}/similar")] +public class YGetTrackSimilarBuilder : YRequestBuilder, string> +{ + public YGetTrackSimilarBuilder(YandexMusicApi yandex, AuthStorage auth) : base(yandex, auth) + { + } + + protected override Dictionary GetSubstitutions(string trackId) + { + return new Dictionary { + { "trackId", trackId } + }; } } \ No newline at end of file diff --git a/YandexMusic.API/Requests/Track/YGetTrackSupplementBuilder.cs b/YandexMusic.API/Requests/Track/YGetTrackSupplementBuilder.cs index efdb9cd..8bfaf8d 100644 --- a/YandexMusic.API/Requests/Track/YGetTrackSupplementBuilder.cs +++ b/YandexMusic.API/Requests/Track/YGetTrackSupplementBuilder.cs @@ -6,20 +6,19 @@ using YandexMusic.API.Models.Track; using YandexMusic.API.Requests.Common; using YandexMusic.API.Requests.Common.Attributes; -namespace YandexMusic.API.Requests.Track -{ - [YApiRequest(WebRequestMethods.Http.Get, "tracks/{trackId}/supplement")] - public class YGetTrackSupplementBuilder : YRequestBuilder, string> - { - public YGetTrackSupplementBuilder(YandexMusicApi yandex, AuthStorage auth) : base(yandex, auth) - { - } +namespace YandexMusic.API.Requests.Track; - protected override Dictionary GetSubstitutions(string trackId) - { - return new Dictionary { - { "trackId", trackId } - }; - } +[YApiRequest(WebRequestMethods.Http.Get, "tracks/{trackId}/supplement")] +public class YGetTrackSupplementBuilder : YRequestBuilder, string> +{ + public YGetTrackSupplementBuilder(YandexMusicApi yandex, AuthStorage auth) : base(yandex, auth) + { + } + + protected override Dictionary GetSubstitutions(string trackId) + { + return new Dictionary { + { "trackId", trackId } + }; } } \ No newline at end of file diff --git a/YandexMusic.API/Requests/Track/YGetTracksBuilder.cs b/YandexMusic.API/Requests/Track/YGetTracksBuilder.cs index 07040e9..ae1db7b 100644 --- a/YandexMusic.API/Requests/Track/YGetTracksBuilder.cs +++ b/YandexMusic.API/Requests/Track/YGetTracksBuilder.cs @@ -6,21 +6,20 @@ using YandexMusic.API.Models.Track; using YandexMusic.API.Requests.Common; using YandexMusic.API.Requests.Common.Attributes; -namespace YandexMusic.API.Requests.Track -{ - [YApiRequest(WebRequestMethods.Http.Post, "tracks")] - public class YGetTracksBuilder : YRequestBuilder>, IEnumerable> - { - public YGetTracksBuilder(YandexMusicApi yandex, AuthStorage auth) : base(yandex, auth) - { - } +namespace YandexMusic.API.Requests.Track; - protected override HttpContent GetContent(IEnumerable trackIds) - { - return new FormUrlEncodedContent(new Dictionary { - { "track-ids", string.Join(",", trackIds) }, - { "with-positions", "true" } - }); - } +[YApiRequest(WebRequestMethods.Http.Post, "tracks")] +public class YGetTracksBuilder : YRequestBuilder>, IEnumerable> +{ + public YGetTracksBuilder(YandexMusicApi yandex, AuthStorage auth) : base(yandex, auth) + { + } + + protected override HttpContent GetContent(IEnumerable trackIds) + { + return new FormUrlEncodedContent(new Dictionary { + { "track-ids", string.Join(",", trackIds) }, + { "with-positions", "true" } + }); } } \ No newline at end of file diff --git a/YandexMusic.API/Requests/Track/YSendTrackInfoBuilder.cs b/YandexMusic.API/Requests/Track/YSendTrackInfoBuilder.cs index 78f5a2a..e74bed7 100644 --- a/YandexMusic.API/Requests/Track/YSendTrackInfoBuilder.cs +++ b/YandexMusic.API/Requests/Track/YSendTrackInfoBuilder.cs @@ -6,33 +6,32 @@ using YandexMusic.API.Models.Track; using YandexMusic.API.Requests.Common; using YandexMusic.API.Requests.Common.Attributes; -namespace YandexMusic.API.Requests.Track +namespace YandexMusic.API.Requests.Track; + +[YApiRequest(WebRequestMethods.Http.Post, "play-audio")] +public class YSendTrackInfoBuilder : YRequestBuilder { - [YApiRequest(WebRequestMethods.Http.Post, "play-audio")] - public class YSendTrackInfoBuilder : YRequestBuilder + public YSendTrackInfoBuilder(YandexMusicApi yandex, AuthStorage auth) : base(yandex, auth) { - public YSendTrackInfoBuilder(YandexMusicApi yandex, AuthStorage auth) : base(yandex, auth) - { - } + } - protected override HttpContent GetContent((YTrack track, string from, bool fromCache, string playId, string playlistId, double totalPlayedSeconds, double endPositionSeconds) tuple) - { - Dictionary formData = new() { - { "track_id", tuple.track.Id }, - { "from-cache", tuple.fromCache.ToString() }, - { "play_id", tuple.playId }, - { "uid", Storage.User.Uid }, - { "timestamp", DateTime.Now.ToString("o", CultureInfo.InvariantCulture) }, - { "client-now", DateTime.Now.ToString("o", CultureInfo.InvariantCulture) }, - { "album-id", tuple.track.Albums.FirstOrDefault()?.Id }, - { "from", tuple.from }, - { "playlist-id", tuple.playlistId }, - { "track-length-seconds", ((double)(tuple.track.DurationMs / 1000)).ToString(CultureInfo.InvariantCulture) }, - { "total-played-seconds", tuple.totalPlayedSeconds.ToString(CultureInfo.InvariantCulture) }, - { "end-position-seconds", tuple.endPositionSeconds.ToString(CultureInfo.InvariantCulture) }, - }; + protected override HttpContent GetContent((YTrack track, string from, bool fromCache, string playId, string playlistId, double totalPlayedSeconds, double endPositionSeconds) tuple) + { + Dictionary formData = new() { + { "track_id", tuple.track.Id }, + { "from-cache", tuple.fromCache.ToString() }, + { "play_id", tuple.playId }, + { "uid", storage.User.Uid }, + { "timestamp", DateTime.Now.ToString("o", CultureInfo.InvariantCulture) }, + { "client-now", DateTime.Now.ToString("o", CultureInfo.InvariantCulture) }, + { "album-id", tuple.track.Albums.FirstOrDefault()?.Id }, + { "from", tuple.from }, + { "playlist-id", tuple.playlistId }, + { "track-length-seconds", ((double)(tuple.track.DurationMs / 1000)).ToString(CultureInfo.InvariantCulture) }, + { "total-played-seconds", tuple.totalPlayedSeconds.ToString(CultureInfo.InvariantCulture) }, + { "end-position-seconds", tuple.endPositionSeconds.ToString(CultureInfo.InvariantCulture) }, + }; - return new FormUrlEncodedContent(formData); - } + return new FormUrlEncodedContent(formData); } } \ No newline at end of file diff --git a/YandexMusic.API/Requests/Track/YStorageDownloadFileBuilder.cs b/YandexMusic.API/Requests/Track/YStorageDownloadFileBuilder.cs index 965920c..f32d8ee 100644 --- a/YandexMusic.API/Requests/Track/YStorageDownloadFileBuilder.cs +++ b/YandexMusic.API/Requests/Track/YStorageDownloadFileBuilder.cs @@ -6,38 +6,37 @@ using YandexMusic.API.Models.Common; using YandexMusic.API.Requests.Common; using YandexMusic.API.Requests.Common.Attributes; -namespace YandexMusic.API.Requests.Track +namespace YandexMusic.API.Requests.Track; + +[YRequest(WebRequestMethods.Http.Get, "{src}")] +public class YStorageDownloadFileBuilder : YRequestBuilder { - [YRequest(WebRequestMethods.Http.Get, "{src}")] - public class YStorageDownloadFileBuilder : YRequestBuilder + public YStorageDownloadFileBuilder(YandexMusicApi yandex, AuthStorage auth) : base(yandex, auth) { - public YStorageDownloadFileBuilder(YandexMusicApi yandex, AuthStorage auth) : base(yandex, auth) - { - } + } - protected override Dictionary GetSubstitutions(string src) - { - return new Dictionary { - { "src", src.Split('?')[0] } - }; - } + protected override Dictionary GetSubstitutions(string src) + { + return new Dictionary { + { "src", src.Split('?')[0] } + }; + } - protected override NameValueCollection GetQueryParams(string src) - { - NameValueCollection query = new() { - { "format", "json" } - }; + protected override NameValueCollection GetQueryParams(string src) + { + NameValueCollection query = new() { + { "format", "json" } + }; - src.Split('?')[1] - .Split('&') - .ToList() - .ForEach(p => - { - string[] param = p.Split('='); - query.Add(param[0], param[1]); - }); + src.Split('?')[1] + .Split('&') + .ToList() + .ForEach(p => + { + string[] param = p.Split('='); + query.Add(param[0], param[1]); + }); - return query; - } + return query; } } \ No newline at end of file diff --git a/YandexMusic.API/Requests/Track/YTrackDownloadInfoBuilder.cs b/YandexMusic.API/Requests/Track/YTrackDownloadInfoBuilder.cs index bbeea59..633bec2 100644 --- a/YandexMusic.API/Requests/Track/YTrackDownloadInfoBuilder.cs +++ b/YandexMusic.API/Requests/Track/YTrackDownloadInfoBuilder.cs @@ -6,27 +6,26 @@ using YandexMusic.API.Models.Common; using YandexMusic.API.Requests.Common; using YandexMusic.API.Requests.Common.Attributes; -namespace YandexMusic.API.Requests.Track +namespace YandexMusic.API.Requests.Track; + +[YApiRequest(WebRequestMethods.Http.Get, "tracks/{trackKey}/download-info")] +public class YTrackDownloadInfoBuilder : YRequestBuilder>, (string trackKey, bool direct)> { - [YApiRequest(WebRequestMethods.Http.Get, "tracks/{trackKey}/download-info")] - public class YTrackDownloadInfoBuilder : YRequestBuilder>, (string trackKey, bool direct)> + public YTrackDownloadInfoBuilder(YandexMusicApi yandex, AuthStorage auth) : base(yandex, auth) { - public YTrackDownloadInfoBuilder(YandexMusicApi yandex, AuthStorage auth) : base(yandex, auth) - { - } + } - protected override Dictionary GetSubstitutions((string trackKey, bool direct) tuple) - { - return new Dictionary { - { "trackKey", tuple.trackKey } - }; - } + protected override Dictionary GetSubstitutions((string trackKey, bool direct) tuple) + { + return new Dictionary { + { "trackKey", tuple.trackKey } + }; + } - protected override NameValueCollection GetQueryParams((string trackKey, bool direct) tuple) - { - return new NameValueCollection { - { "direct", tuple.direct.ToString() } - }; - } + protected override NameValueCollection GetQueryParams((string trackKey, bool direct) tuple) + { + return new NameValueCollection { + { "direct", tuple.direct.ToString() } + }; } } \ No newline at end of file diff --git a/YandexMusic.API/Requests/Ugc/YUgcGetUploadLinkBuilder.cs b/YandexMusic.API/Requests/Ugc/YUgcGetUploadLinkBuilder.cs index acc4359..c9d8dee 100644 --- a/YandexMusic.API/Requests/Ugc/YUgcGetUploadLinkBuilder.cs +++ b/YandexMusic.API/Requests/Ugc/YUgcGetUploadLinkBuilder.cs @@ -8,26 +8,25 @@ using YandexMusic.API.Models.Ugc; using YandexMusic.API.Requests.Common; using YandexMusic.API.Requests.Common.Attributes; -namespace YandexMusic.API.Requests.Ugc +namespace YandexMusic.API.Requests.Ugc; + +[YWebApiRequest(WebRequestMethods.Http.Get, "handlers/ugc-upload.jsx")] +public class YUgcGetUploadLinkBuilder : YRequestBuilder { - [YWebApiRequest(WebRequestMethods.Http.Get, "handlers/ugc-upload.jsx")] - public class YUgcGetUploadLinkBuilder : YRequestBuilder + private static readonly Lazy Random = new(() => new Random()); + + public YUgcGetUploadLinkBuilder(YandexMusicApi yandex, AuthStorage auth) : base(yandex, auth) { - private static readonly Lazy Random = new(() => new Random()); + } - public YUgcGetUploadLinkBuilder(YandexMusicApi yandex, AuthStorage auth) : base(yandex, auth) - { - } - - protected override NameValueCollection GetQueryParams((YPlaylist playlist, string fileName) tuple) - { - return new NameValueCollection { - { "filename", tuple.fileName }, - { "kind", tuple.playlist.Kind }, - { "visibility", "private" }, - { "external-domain", "music.yandex.ru" }, - { "ncrnd", Random.Value.NextDouble().ToString(CultureInfo.InvariantCulture) } - }; - } + protected override NameValueCollection GetQueryParams((YPlaylist playlist, string fileName) tuple) + { + return new NameValueCollection { + { "filename", tuple.fileName }, + { "kind", tuple.playlist.Kind }, + { "visibility", "private" }, + { "external-domain", "music.yandex.ru" }, + { "ncrnd", Random.Value.NextDouble().ToString(CultureInfo.InvariantCulture) } + }; } } \ No newline at end of file diff --git a/YandexMusic.API/Requests/Ugc/YUgcUploadBuilder.cs b/YandexMusic.API/Requests/Ugc/YUgcUploadBuilder.cs index 1d87a54..d326612 100644 --- a/YandexMusic.API/Requests/Ugc/YUgcUploadBuilder.cs +++ b/YandexMusic.API/Requests/Ugc/YUgcUploadBuilder.cs @@ -5,28 +5,27 @@ using YandexMusic.API.Models.Common; using YandexMusic.API.Requests.Common; using YandexMusic.API.Requests.Common.Attributes; -namespace YandexMusic.API.Requests.Ugc +namespace YandexMusic.API.Requests.Ugc; + +[YRequest(WebRequestMethods.Http.Post, "{postTargetLink}")] +public class YUgcUploadBuilder : YRequestBuilder, (string postTargetLink, byte[] fileBytes)> { - [YRequest(WebRequestMethods.Http.Post, "{postTargetLink}")] - public class YUgcUploadBuilder : YRequestBuilder, (string postTargetLink, byte[] fileBytes)> + public YUgcUploadBuilder(YandexMusicApi yandex, AuthStorage auth) : base(yandex, auth) { - public YUgcUploadBuilder(YandexMusicApi yandex, AuthStorage auth) : base(yandex, auth) - { - } - - protected override Dictionary GetSubstitutions((string postTargetLink, byte[] fileBytes) tuple) - { - return new Dictionary { - { "postTargetLink", tuple.postTargetLink } - }; - } - - protected override HttpContent GetContent((string postTargetLink, byte[] fileBytes) tuple) - { - return new MultipartFormDataContent { - { new ByteArrayContent(tuple.fileBytes), "file" } - }; - } - } + + protected override Dictionary GetSubstitutions((string postTargetLink, byte[] fileBytes) tuple) + { + return new Dictionary { + { "postTargetLink", tuple.postTargetLink } + }; + } + + protected override HttpContent GetContent((string postTargetLink, byte[] fileBytes) tuple) + { + return new MultipartFormDataContent { + { new ByteArrayContent(tuple.fileBytes), "file" } + }; + } + } \ No newline at end of file diff --git a/YandexMusic.API/YandexMusic.API.csproj b/YandexMusic.API/YandexMusic.API.csproj index 57c3c05..31c1f7b 100644 --- a/YandexMusic.API/YandexMusic.API.csproj +++ b/YandexMusic.API/YandexMusic.API.csproj @@ -6,7 +6,6 @@ FrigaT Асинхронная библиотека для неофициального API Яндекс Музыки. yandex;music;api;async - last enable enable