From 58f21da19ce0106f13c1e57e43228416249db787 Mon Sep 17 00:00:00 2001 From: FrigaT Date: Tue, 21 Apr 2026 11:44:11 +0300 Subject: [PATCH] =?UTF-8?q?=D0=94=D0=BE=D1=80=D0=B0=D0=B1=D0=BE=D1=82?= =?UTF-8?q?=D0=B0=D0=BD=D1=8B=20=D1=81=D0=B5=D1=80=D0=B2=D0=B8=D1=81=D1=8B?= =?UTF-8?q?:=20=D1=83=D0=BC=D0=B5=D0=BD=D1=8C=D1=88=D0=B5=D0=BD=D0=BD?= =?UTF-8?q?=D0=BE=20=D0=BA=D0=BE=D0=BB-=D0=B2=D0=BE=20=D1=81=D0=BE=D0=B7?= =?UTF-8?q?=D0=B4=D0=B0=D0=B2=D0=B0=D0=B5=D0=BC=D1=8B=D1=85=20=D0=BE=D0=B1?= =?UTF-8?q?=D1=8A=D0=B5=D0=BA=D1=82=D0=BE=D0=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Controllers/PlaylistsController.cs | 8 +- PlaylistShared.Api/PlaylistShared.Api.csproj | 2 +- .../Services/Yandex/YandexApiService.cs | 31 +++++-- .../Services/Yandex/YandexAuthService.cs | 31 +++---- .../Services/Yandex/YandexMusicService.cs | 86 ++++++++----------- 5 files changed, 80 insertions(+), 78 deletions(-) diff --git a/PlaylistShared.Api/Controllers/PlaylistsController.cs b/PlaylistShared.Api/Controllers/PlaylistsController.cs index 4284c62..7a553a6 100644 --- a/PlaylistShared.Api/Controllers/PlaylistsController.cs +++ b/PlaylistShared.Api/Controllers/PlaylistsController.cs @@ -8,7 +8,6 @@ using PlaylistShared.Shared; using PlaylistShared.Shared.Enums; using PlaylistShared.Shared.SharedPlaylist; using PlaylistShared.Shared.Yandex; -using YandexMusic; namespace PlaylistShared.Api.Controllers; @@ -45,13 +44,12 @@ public class PlaylistsController : ControllerBase if (string.IsNullOrEmpty(decryptedToken)) return BadRequest(ApiResponse.Fail(new ErrorResponse { StatusCode = 400, Message = "Токен Яндекс.Музыки не установлен или недействителен" })); - var yandexClient = new YandexMusicClient(); - var authSuccess = await yandexClient.Authorize(decryptedToken); + var authSuccess = await _yandexApiService.AuthAsync(decryptedToken); if (!authSuccess) return BadRequest(ApiResponse.Fail(new ErrorResponse { StatusCode = 400, Message = "Не удалось авторизоваться в Яндекс.Музыке. Проверьте токен." })); - var favorites = await yandexClient.GetFavoritesAsync(); - var ownPlaylists = favorites.Where(p => p.Owner.Uid == yandexClient.Account.Uid).ToList(); + var favorites = await _yandexApiService.Client.Api.Playlist.FavoritesAsync(); + var ownPlaylists = favorites.Where(p => p.Owner.Uid == _yandexApiService.Client.Account.Uid).ToList(); var sharedPlaylists = await _sharedService.GetAllByUserAsync(userId); diff --git a/PlaylistShared.Api/PlaylistShared.Api.csproj b/PlaylistShared.Api/PlaylistShared.Api.csproj index f7d4a24..4c5a891 100644 --- a/PlaylistShared.Api/PlaylistShared.Api.csproj +++ b/PlaylistShared.Api/PlaylistShared.Api.csproj @@ -27,7 +27,7 @@ - + diff --git a/PlaylistShared.Api/Services/Yandex/YandexApiService.cs b/PlaylistShared.Api/Services/Yandex/YandexApiService.cs index 7399135..b25545f 100644 --- a/PlaylistShared.Api/Services/Yandex/YandexApiService.cs +++ b/PlaylistShared.Api/Services/Yandex/YandexApiService.cs @@ -44,7 +44,28 @@ public class YandexApiService : IDisposable if (decryptedToken == null) return null; - return await _client.Authorize(decryptedToken); + return await AuthorizeAsync(decryptedToken); + } + + /// + /// Авторизуется с помощью OAuth-токена. + /// + public async Task AuthAsync(string token) + { + return await AuthorizeAsync(token); + } + + private async Task AuthorizeAsync(string token) + { + try + { + await _client.Api.Auth.AuthorizeAsync(token); + return true; + } + catch + { + return false; + } } /// @@ -100,14 +121,6 @@ public class YandexApiService : IDisposable return cookie?.Value; } - /// - /// Авторизуется с помощью OAuth-токена. - /// - public async Task AuthorizeAsync(string token) - { - return await _client.Authorize(token); - } - public void Dispose() { _client.Dispose(); diff --git a/PlaylistShared.Api/Services/Yandex/YandexAuthService.cs b/PlaylistShared.Api/Services/Yandex/YandexAuthService.cs index 8e85c99..5b2007e 100644 --- a/PlaylistShared.Api/Services/Yandex/YandexAuthService.cs +++ b/PlaylistShared.Api/Services/Yandex/YandexAuthService.cs @@ -4,6 +4,7 @@ using PlaylistShared.Api.Entities; using PlaylistShared.Shared.Yandex; using System.Net; using System.Text.Json; +using YandexMusic.API; namespace PlaylistShared.Api.Services; @@ -13,6 +14,7 @@ public class YandexAuthService private readonly ApplicationDbContext _dbContext; public YandexApiService Service => _apiService; + public YandexMusicApi Api => _apiService.Client.Api; public YandexAuthService(YandexApiService apiService, ApplicationDbContext dbContext) { @@ -41,12 +43,11 @@ public class YandexAuthService internal async Task GenerateQrAsync(ApplicationUser user) { - var client = _apiService.Client; - var qr = await client.GetAuthQRLink(); - var trackId = client.AuthStorage.AuthToken.TrackId; - var csfrToken = client.AuthStorage.AuthToken.CsfrToken; - var headerProcessUuid = client.AuthStorage.HeaderToken.ProcessUuid; - var headerCsfrToken = client.AuthStorage.HeaderToken.CsfrToken; + var qr = await Api.Passport.GetAuthQRLinkAsync(); + var trackId = Service.Client.AuthStorage.AuthToken.TrackId; + var csfrToken = Service.Client.AuthStorage.AuthToken.CsfrToken; + var headerProcessUuid = Service.Client.AuthStorage.HeaderToken.ProcessUuid; + var headerCsfrToken = Service.Client.AuthStorage.HeaderToken.CsfrToken; if (string.IsNullOrEmpty(qr)) throw new Exception("Не удалось получить QR-ссылку"); @@ -82,24 +83,24 @@ public class YandexAuthService var session = await _dbContext.YandexAuthSessions.FindAsync(sessionId); if (session == null) return null; - RestoreCookies(_apiService.CookieContainer, session.SerializedCookies); - if (_apiService.Client.AuthStorage.AuthToken is null) + RestoreCookies(Service.CookieContainer, session.SerializedCookies); + if (Service.Client.AuthStorage.AuthToken is null) { - _apiService.Client.AuthStorage.AuthToken = new(); + Service.Client.AuthStorage.AuthToken = new(); } - _apiService.Client.AuthStorage.AuthToken.CsfrToken = session?.CsfrToken ?? ""; - _apiService.Client.AuthStorage.AuthToken.TrackId = session?.TrackId ?? ""; - _apiService.Client.AuthStorage.HeaderToken.CsfrToken = session?.HeaderCsfrToken ?? ""; - _apiService.Client.AuthStorage.HeaderToken.ProcessUuid = session?.HeaderProcessId ?? ""; + Service.Client.AuthStorage.AuthToken.CsfrToken = session?.CsfrToken ?? ""; + Service.Client.AuthStorage.AuthToken.TrackId = session?.TrackId ?? ""; + Service.Client.AuthStorage.HeaderToken.CsfrToken = session?.HeaderCsfrToken ?? ""; + Service.Client.AuthStorage.HeaderToken.ProcessUuid = session?.HeaderProcessId ?? ""; - var status = await _apiService.Client.CheckQRStatusAsync(); + var status = await Api.Passport.CheckQRStatusAsync(); if (status?.State == "otp_auth_finished") { try { - var auth = await _apiService.Client.AuthorizeByQR(); + var auth = await Api.Passport.AuthorizeByQRAsync(); } catch (Exception ex) { diff --git a/PlaylistShared.Api/Services/Yandex/YandexMusicService.cs b/PlaylistShared.Api/Services/Yandex/YandexMusicService.cs index 31308a5..2ce9555 100644 --- a/PlaylistShared.Api/Services/Yandex/YandexMusicService.cs +++ b/PlaylistShared.Api/Services/Yandex/YandexMusicService.cs @@ -1,10 +1,8 @@ -using Microsoft.AspNetCore.DataProtection; -using PlaylistShared.Api.Entities; +using PlaylistShared.Api.Entities; using PlaylistShared.Api.Extensions; using PlaylistShared.Shared.Enums; using PlaylistShared.Shared.Yandex; -using YandexMusic; -using YandexMusic.API.Extensions.API; +using YandexMusic.API; using YandexMusic.API.Models.Playlist; using YandexMusic.API.Models.Track; @@ -12,56 +10,45 @@ namespace PlaylistShared.Api.Services; public class YandexMusicService { - private readonly IDataProtector _dataProtector; + private readonly YandexApiService _yandexApiService; + private YandexMusicApi Api => _yandexApiService.Client.Api; + private bool IsAuthorized => _yandexApiService.Client.IsAuthorized; - public YandexMusicService(IDataProtectionProvider provider) + public YandexMusicService(YandexApiService yandexApiService) { - _dataProtector = provider.CreateProtector("YandexTokens"); + _yandexApiService = yandexApiService; } - private async Task CreateClientAsync(ApplicationUser user) + private async Task AuthorizeIfNot(ApplicationUser user) { - if (string.IsNullOrEmpty(user.YandexAccessToken)) - return null; - - string decryptedToken; - try + if (!IsAuthorized) { - decryptedToken = _dataProtector.Unprotect(user.YandexAccessToken); + var authResult = await _yandexApiService.AuthAsync(user); + if (authResult == null || authResult == false) + throw new Exception("Не удалось авторизоваться в Яндекс.Музыке. Проверьте токен."); } - catch - { - return null; - } - - var client = new YandexMusicClient(); - var success = await client.Authorize(decryptedToken); - return success ? client : null; } public async Task GetPlaylistAsync(ApplicationUser user, string ownerUid, string kind) { - var client = await CreateClientAsync(user); - if (client == null) return null; - return await client.GetPlaylistAsync(ownerUid, kind); + await AuthorizeIfNot(user); + return await Api.Playlist.GetAsync(ownerUid, kind); } public async Task CreatePlaylistAsync(ApplicationUser user, string title) { - var client = await CreateClientAsync(user); - if (client == null) return null; - return await client.CreatePlaylistAsync(title); + await AuthorizeIfNot(user); + return await Api.Playlist.CreateAsync(title); } public async Task AddTracksAsync(ApplicationUser user, string ownerUid, string kind, IEnumerable trackIds) { - var client = await CreateClientAsync(user); - if (client == null) return null; + await AuthorizeIfNot(user); - var playlist = await client.GetPlaylistAsync(ownerUid, kind); + var playlist = await Api.Playlist.GetAsync(ownerUid, kind); if (playlist == null) return null; - var tracks = await client.GetTracksAsync(trackIds); + var tracks = await Api.Track.GetAsync(trackIds); if (tracks == null || !tracks.Any()) return null; var insertedTracks = tracks.Where(t => !playlist.Tracks.Any(p => p.Track.Id == t.Id)).ToArray(); @@ -71,27 +58,32 @@ public class YandexMusicService public async Task RemoveTracksAsync(ApplicationUser user, string ownerUid, string kind, IEnumerable trackIds) { - var client = await CreateClientAsync(user); - if (client == null) return null; - var tracks = await client.GetTracksAsync(trackIds); + await AuthorizeIfNot(user); + + var tracks = await Api.Track.GetAsync(trackIds); if (tracks == null || !tracks.Any()) return null; - var playlist = await client.GetPlaylistAsync(ownerUid, kind); + + var playlist = await Api.Playlist.GetAsync(ownerUid, kind); if (playlist == null) return null; + return await playlist.RemoveTracksAsync(tracks.ToArray()); } public async Task GetTrackFileUrlAsync(ApplicationUser user, string trackId) { + await AuthorizeIfNot(user); + var track = await GetYTrackAsync(user, trackId); if (track == null) return null; + return await track.GetLinkAsync(); } public async Task GetYTrackAsync(ApplicationUser user, string trackId) { - using var client = await CreateClientAsync(user); - if (client == null) return null; - var track = await client.GetTrackAsync(trackId); + await AuthorizeIfNot(user); + + var track = await Api.Track.GetAsync(trackId); return track; } @@ -102,8 +94,7 @@ public class YandexMusicService int limit = 20 ) { - var client = await CreateClientAsync(user); - if (client == null) return new YandexSearchResult(); + await AuthorizeIfNot(user); var ySerchType = searchType switch { @@ -114,7 +105,7 @@ public class YandexMusicService _ => YandexMusic.API.Models.Common.YSearchType.All }; - var searchResult = await client.SearchAsync(query, ySerchType, page: 0, pageSize: limit); + var searchResult = await Api.Search.SearchAsync(query, ySerchType, page: 0, pageSize: limit); if (searchResult?.Tracks?.Results == null) return new YandexSearchResult(); return new YandexSearchResult @@ -179,8 +170,7 @@ public class YandexMusicService { YandexSearchResult result = new(); - var client = await CreateClientAsync(user); - if (client == null) return result; + await AuthorizeIfNot(user); if (searchType == TrackSearchType.All) { @@ -189,7 +179,7 @@ public class YandexMusicService else if (searchType == TrackSearchType.Track) { - var track = await client.GetTrackAsync(id); + var track = await Api.Track.GetAsync(id); if (track != null) { @@ -215,7 +205,7 @@ public class YandexMusicService else if (searchType == TrackSearchType.Album) { - var album = await client.GetAlbumAsync(id); + var album = await Api.Album.GetAsync(id); result.Tracks = album?.Volumes.SelectMany(v => v).Select(t => new YandexTrack { @@ -235,7 +225,7 @@ public class YandexMusicService else if (searchType == TrackSearchType.Artist) { - var artist = await client.GetArtistAsync(id); + var artist = await Api.Artist.GetAsync(id); if (artist != null) { result.Albums = artist.Albums.Select(a => new YandexAlbum() @@ -284,7 +274,7 @@ public class YandexMusicService else if (searchType == TrackSearchType.Playlist) { - var playlist = await client.GetPlaylistAsync(id); + var playlist = await Api.Playlist.GetAsync(id); result.Tracks = playlist?.Tracks.Select(p => new YandexTrack {