Lisoveliy 4a95ba0d86
Some checks failed
Deploy / update (push) Has been cancelled
Build Project .NET / build (push) Has been cancelled
fix: fixed search of tidal tracks using WebUtils
2025-05-12 21:37:29 +03:00

97 lines
4.1 KiB
C#
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using System.Net;
using System.Text.Json;
using System.Web;
using Microsoft.Extensions.Options;
using SWAD.API.Consts;
using SWAD.API.Consts.Enums;
using SWAD.API.Controllers.DTOs;
using SWAD.API.Exceptions;
using SWAD.API.Models.Config.ApiServices;
using SWAD.API.Models.JsonStructures.MusicAPI.Yandex;
using SWAD.API.Services.MusicAPI.Auth;
namespace SWAD.API.Services.MusicAPI.Api;
public class YandexService : ApiService
{
public YandexService(IOptions<ApiServicesConfig> config, IEnumerable<AbstractAuthService> authServices)
{
ServiceType = MusicService.Yandex;
var configServices = config.Value.ServicesData;
Config = configServices.First(x => x.Name == ServiceType.ToString());
}
public override async Task<string?> GetLinkByQuery(TrackDto query)
{
var searchUri = new Uri(new Uri(Config.Endpoints.Api), Config.ApiPaths.Search);
using var client = new HttpClient();
var clientHeaders = client.DefaultRequestHeaders;
var response = await client.PostAsync(searchUri, new FormUrlEncodedContent([
new("text", GetQuery(query))
]));
if (!response.IsSuccessStatusCode)
{
var requestDebugData = await response.Content.ReadAsStringAsync();
throw new HttpRequestException($"{ErrorResources.Unsuccessful}\n Service returned: {requestDebugData}");
}
var json = await response.Content.ReadFromJsonAsync<YandexSearchResponse>();
// ReSharper disable once NullableWarningSuppressionIsUsed
if (json?.Entities.Count < 1)
{
throw new TrackNotFoundException($"Track is not found in {ServiceType}");
}
var results = json?.Entities.FirstOrDefault(x => x.Type == "track")?.Results;
/*
* ВНИМАНИЕ
* Yandex API писали шизы поэтому когда будешь добавлять поля в YandexSearchResponse и здесь их юзать
* ПОМНИ: ID у артистов и альбомов в разных местах JSON в одних и тех же объектах то string то number
* ЭТО ВЫЗОВЕТ ИСКЛЮЧЕНИЕ
* Думой
*/
var resultTrack = results?.FirstOrDefault(x => x.Track.Title == query.Name) ??
results?[0];
return $"{Config.Endpoints.MusicLink[0]}{resultTrack?.Track.Id ??
throw new TrackNotFoundException($"Track is not found in {ServiceType}")}";
}
public override async Task<TrackDto> GetQueryObject(string link, string countryCode = "RU")
{
var url = new Uri(link);
var id = url.Segments[^1];
//Prepare request
using var client = new HttpClient();
var getTrackUrl = new UriBuilder(new Uri(new Uri(Config.Endpoints.Api), Config.ApiPaths.GetTrack))
{
Port = -1
};
var urlQuery = HttpUtility.ParseQueryString(url.Query);
urlQuery["track"] = id;
getTrackUrl.Query = urlQuery.ToString();
//Get response
var response = await client.GetAsync(getTrackUrl.Uri);
if (!response.IsSuccessStatusCode)
if (response.StatusCode == HttpStatusCode.NotFound)
{
throw new TrackNotFoundException("Ну, сори, яндекс кал");
}
else
throw new HttpRequestException(ErrorResources.Unsuccessful);
try
{
var json = await response.Content.ReadFromJsonAsync<YandexTrackResponse>();
// ReSharper disable once NullableWarningSuppressionIsUsed
var artists = string.Join(", ", json!.Artists.ToList().ConvertAll(x => x.Name));
return new TrackDto(json.Track.Title, artists, json.Track.Albums[0].Title, ServiceType);
}
catch (JsonException ex)
{
throw new TooManyRequestsException("Яндекс, похоже, считает что мы робот, что по сути является правдой. Попробуйте позже.");
}
}
}