SwapDude/SWAD.API/Services/Links/LinksService.cs
Lisoveliy aebe654c38
Some checks are pending
Deploy / update (push) Waiting to run
Build Project .NET / build (push) Waiting to run
chore: init commit from GitHub
2025-05-12 19:44:33 +03:00

121 lines
4.2 KiB
C#

using StackExchange.Redis;
using SWAD.API.Consts.Enums;
using SWAD.API.Controllers.DTOs;
using SWAD.API.Exceptions;
using SWAD.API.Services.MusicAPI.Api;
namespace SWAD.API.Services.Links;
/// <summary>
/// Service for manipulating with links (LinkController)
/// </summary>
public class LinksService
{
private readonly Dictionary<MusicService, ApiService> _services;
private readonly IDatabase _redis;
private readonly ILogger _logger;
public LinksService(IEnumerable<ApiService> services, IDatabase redis, ILogger<LinksService> logger)
{
_services = services.ToList()
.ConvertAll(x => new KeyValuePair<MusicService, ApiService>(x.ServiceType, x)).ToDictionary();
_redis = redis;
_logger = logger;
}
/// <summary>
/// Get link by query
/// </summary>
/// <param Name="query">Search query</param>
/// <returns>Success, Failure, BadRequest, NoResponse</returns>
public async Task<(string? link, ServiceResult result)> GetLinkByQuery(TrackDto query)
{
//Mapping service
var service = _services.GetValueOrDefault(query.Service);
//Throw result
try
{
var output = await service!.GetLinkByQuery(query);
return (output, output != null ? ServiceResult.Success : ServiceResult.Failure);
}
catch (HttpRequestException)
{
return (null, ServiceResult.BadRequest);
}
catch (TimeoutException)
{
return (null, ServiceResult.NoResponse);
}
}
/// <summary>
/// Get MusicService by url
/// </summary>
/// <param Name="link"></param>
/// <returns>Success, Failure</returns>
public async Task<(MusicService? service, ServiceResult result)> GetServiceByLink(string link)
{
var cacheKey = $"GET_SERVICE_{link}";
var cache = await _redis.StringGetAsync(cacheKey);
if (cache.HasValue)
{
var result = (MusicService?)Enum.Parse(typeof(MusicService), cache.ToString());
return (result, ServiceResult.Success);
}
_logger.LogInformation($"Getting service for {link}...");
foreach (var service in _services.Values)
if (service.Config.Endpoints.MusicLink.Any(link.StartsWith))
{
await _redis.StringSetAsync(cacheKey, service.ServiceType.ToString(), TimeSpan.FromDays(30));
return (service.ServiceType, ServiceResult.Success);
}
_logger.LogInformation($"FAIL");
return (null, ServiceResult.Failure);
}
/// <summary>
/// Get Link from other service
/// </summary>
/// <param Name="trackLink">link from first service</param>
/// <returns>link from another service, Success, Failure, BadRequest, NoResponse</returns>
public async Task<(string? link, ServiceResult result)> MapLinks(TrackLinkDto trackLink)
{
var service = await GetServiceByLink(trackLink.Link);
if (service.result != ServiceResult.Success) return (null, service.result);
var cacheKey = $"{service.service}_{trackLink.Link}_{Enum.GetName(trackLink.Service)}";
var cache = await _redis.StringGetAsync(cacheKey);
if (cache.HasValue)
{
return (cache.ToString(), ServiceResult.Success);
}
_logger.LogInformation($"Getting {trackLink.Link} for {Enum.GetName(trackLink.Service)}...");
try
{
var apiService = _services[service.service!.Value];
var query = await apiService.GetQueryObject(trackLink.Link);
var linkApiService = _services[trackLink.Service];
var link = await linkApiService.GetLinkByQuery(query);
if (link == null)
return (null, ServiceResult.Failure);
await _redis.StringSetAsync(cacheKey, link, TimeSpan.FromDays(30));
return (link, ServiceResult.Success);
}
catch (TrackNotFoundException)
{
return (null, ServiceResult.NotFound);
}
catch (HttpRequestException)
{
return (null, ServiceResult.BadRequest);
}
catch (TimeoutException)
{
return (null, ServiceResult.NoResponse);
}
}
}