generated from ricardo/MVCLogin
308 lines
12 KiB
C#
308 lines
12 KiB
C#
using BaseDomain.Results;
|
|
using Microsoft.AspNetCore.Http;
|
|
using Postall.Domain;
|
|
using Postall.Domain.Contracts.Repositories;
|
|
using Postall.Domain.Dtos;
|
|
using Postall.Domain.Entities;
|
|
using Postall.Domain.Services.Contracts;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Security.Claims;
|
|
using System.Threading.Tasks;
|
|
|
|
namespace Postall.Infra.Services
|
|
{
|
|
public class VideoService : IVideoService
|
|
{
|
|
private readonly IHttpContextAccessor _httpContextAccessor;
|
|
private readonly IVideoRepository _videoRepository;
|
|
private readonly IChannelRepository _channelRepository;
|
|
private readonly IVideoYoutubeService _videoYoutubeService;
|
|
|
|
public VideoService(
|
|
IHttpContextAccessor httpContextAccessor,
|
|
IVideoRepository videoRepository,
|
|
IChannelRepository channelRepository,
|
|
IVideoYoutubeService videoYoutubeService)
|
|
{
|
|
_httpContextAccessor = httpContextAccessor;
|
|
_videoRepository = videoRepository;
|
|
_channelRepository = channelRepository;
|
|
_videoYoutubeService = videoYoutubeService;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Obtém o ID do usuário atual a partir das claims
|
|
/// </summary>
|
|
private string GetCurrentUserId()
|
|
{
|
|
var user = _httpContextAccessor.HttpContext.User;
|
|
var userId = user.FindFirst(ClaimTypes.NameIdentifier)?.Value;
|
|
|
|
if (string.IsNullOrEmpty(userId))
|
|
{
|
|
var email = user.FindFirst(ClaimTypes.Email)?.Value;
|
|
if (!string.IsNullOrEmpty(email))
|
|
{
|
|
userId = Convert.ToBase64String(
|
|
System.Text.Encoding.UTF8.GetBytes(email)
|
|
).Replace("/", "_").Replace("+", "-").Replace("=", "");
|
|
}
|
|
}
|
|
|
|
return userId;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Obtém todos os vídeos do usuário atual
|
|
/// </summary>
|
|
public async Task<Result<List<VideoResponse>>> GetUserVideosAsync()
|
|
{
|
|
var userId = GetCurrentUserId();
|
|
|
|
if (string.IsNullOrEmpty(userId))
|
|
return new List<VideoResponse>();
|
|
|
|
var videos = await _videoRepository.GetByUserIdAsync(userId);
|
|
return videos.Select(v => v.ToVideoResponse()).ToList();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Obtém os vídeos de um canal específico para o usuário atual
|
|
/// </summary>
|
|
public async Task<Result<List<VideoResponse>>> GetVideosByChannelIdAsync(string channelId)
|
|
{
|
|
if (string.IsNullOrEmpty(channelId))
|
|
return new List<VideoResponse>();
|
|
|
|
var userId = GetCurrentUserId();
|
|
|
|
if (string.IsNullOrEmpty(userId))
|
|
return new List<VideoResponse>();
|
|
|
|
var videos = await _videoRepository.GetByUserIdAndChannelIdAsync(userId, channelId);
|
|
return videos.Select(v => v.ToVideoResponse()).ToList();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Obtém os detalhes de um vídeo específico
|
|
/// </summary>
|
|
public async Task<Result<VideoResponse>> GetVideoDetailsAsync(string videoId)
|
|
{
|
|
if (string.IsNullOrEmpty(videoId))
|
|
return Result<VideoResponse>.Failure("ID do vídeo inválido");
|
|
|
|
var videoDetails = await _videoYoutubeService.GetVideoDetailsAsync(videoId);
|
|
return videoDetails;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Obtém os vídeos de um canal diretamente do YouTube
|
|
/// </summary>
|
|
public async Task<Result<List<VideoResponse>>> GetChannelVideosFromYouTubeAsync(string channelId, int maxResults = 10)
|
|
{
|
|
if (string.IsNullOrEmpty(channelId))
|
|
return Result<List<VideoResponse>>.Failure("ID do canal inválido");
|
|
|
|
// Verifica se o canal existe para o usuário
|
|
var userId = GetCurrentUserId();
|
|
var channel = await _channelRepository.GetByUserIdAndChannelIdAsync(userId, channelId);
|
|
|
|
if (channel == null)
|
|
return Result<List<VideoResponse>>.Failure("Canal não encontrado para este usuário");
|
|
|
|
// Obtém os vídeos que o usuário já adicionou para este canal
|
|
var userVideos = await _videoRepository.GetByUserIdAndChannelIdAsync(userId, channelId);
|
|
var userVideoIds = userVideos.Select(v => v.VideoId).ToHashSet();
|
|
|
|
// Busca os vídeos do canal no YouTube
|
|
var channelVideos = await _videoYoutubeService.GetChannelVideosAsync(channelId, maxResults);
|
|
|
|
if (!channelVideos.IsSuccess)
|
|
return channelVideos;
|
|
|
|
// Marca os vídeos que já foram adicionados pelo usuário
|
|
foreach (var video in channelVideos.Value)
|
|
{
|
|
if (userVideoIds.Contains(video.VideoId))
|
|
{
|
|
// Esse vídeo já foi adicionado pelo usuário
|
|
video.Id = userVideos.First(v => v.VideoId == video.VideoId).Id;
|
|
}
|
|
}
|
|
|
|
return channelVideos;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Adiciona um vídeo à lista do usuário
|
|
/// </summary>
|
|
public async Task<Result<bool>> AddVideoAsync(string videoId, string channelId)
|
|
{
|
|
if (string.IsNullOrEmpty(videoId))
|
|
return Result<bool>.Failure("ID do vídeo inválido");
|
|
|
|
if (string.IsNullOrEmpty(channelId))
|
|
return Result<bool>.Failure("ID do canal inválido");
|
|
|
|
var userId = GetCurrentUserId();
|
|
|
|
if (string.IsNullOrEmpty(userId))
|
|
return Result<bool>.Failure("Usuário não identificado");
|
|
|
|
// Verifica se o canal existe para o usuário
|
|
var channel = await _channelRepository.GetByUserIdAndChannelIdAsync(userId, channelId);
|
|
|
|
if (channel == null)
|
|
return Result<bool>.Failure("Canal não encontrado para este usuário");
|
|
|
|
// Verifica se o vídeo já existe para o usuário
|
|
var existingVideo = await _videoRepository.GetByUserIdAndVideoIdAsync(userId, videoId);
|
|
|
|
if (existingVideo != null)
|
|
return true; // Vídeo já existe, retorna sucesso
|
|
|
|
try
|
|
{
|
|
// Obtém os detalhes do vídeo do YouTube
|
|
var videoDetails = await _videoYoutubeService.GetVideoDetailsAsync(videoId);
|
|
|
|
if (!videoDetails.IsSuccess)
|
|
return Result<bool>.Failure(videoDetails.Error);
|
|
|
|
// Cria o objeto de dados do vídeo
|
|
var videoData = new VideoData
|
|
{
|
|
UserId = userId,
|
|
ChannelId = channelId,
|
|
VideoId = videoId,
|
|
Title = videoDetails.Value.Title,
|
|
Description = videoDetails.Value.Description,
|
|
ThumbnailUrl = videoDetails.Value.ThumbnailUrl,
|
|
PublishedAt = videoDetails.Value.PublishedAt,
|
|
ViewCount = videoDetails.Value.ViewCount,
|
|
LikeCount = videoDetails.Value.LikeCount,
|
|
DislikeCount = videoDetails.Value.DislikeCount,
|
|
CommentCount = videoDetails.Value.CommentCount,
|
|
CreatedAt = DateTime.UtcNow
|
|
};
|
|
|
|
// Adiciona o vídeo ao repositório
|
|
await _videoRepository.AddAsync(videoData);
|
|
|
|
return true;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
return Result<bool>.Failure(ex.Message);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Adiciona múltiplos vídeos à lista do usuário
|
|
/// </summary>
|
|
public async Task<Result<bool>> AddVideosAsync(List<string> videoIds, string channelId)
|
|
{
|
|
if (videoIds == null || !videoIds.Any())
|
|
return Result<bool>.Failure("Lista de IDs de vídeos inválida");
|
|
|
|
if (string.IsNullOrEmpty(channelId))
|
|
return Result<bool>.Failure("ID do canal inválido");
|
|
|
|
var userId = GetCurrentUserId();
|
|
|
|
if (string.IsNullOrEmpty(userId))
|
|
return Result<bool>.Failure("Usuário não identificado");
|
|
|
|
// Verifica se o canal existe para o usuário
|
|
var channel = await _channelRepository.GetByUserIdAndChannelIdAsync(userId, channelId);
|
|
|
|
if (channel == null)
|
|
return Result<bool>.Failure("Canal não encontrado para este usuário");
|
|
|
|
// Obtém os vídeos que o usuário já adicionou
|
|
var existingVideos = await _videoRepository.GetByUserIdAsync(userId);
|
|
var existingVideoIds = existingVideos.Select(v => v.VideoId).ToHashSet();
|
|
|
|
// Filtra os vídeos que ainda não foram adicionados
|
|
var newVideoIds = videoIds.Where(id => !existingVideoIds.Contains(id)).ToList();
|
|
|
|
if (newVideoIds.Count == 0)
|
|
return true; // Todos os vídeos já existem
|
|
|
|
try
|
|
{
|
|
var videoDataList = new List<VideoData>();
|
|
|
|
// Obtém os detalhes de cada vídeo do YouTube e cria os objetos de dados
|
|
foreach (var videoId in newVideoIds)
|
|
{
|
|
var videoDetails = await _videoYoutubeService.GetVideoDetailsAsync(videoId);
|
|
|
|
if (videoDetails.IsSuccess)
|
|
{
|
|
videoDataList.Add(new VideoData
|
|
{
|
|
UserId = userId,
|
|
ChannelId = channelId,
|
|
VideoId = videoId,
|
|
Title = videoDetails.Value.Title,
|
|
Description = videoDetails.Value.Description,
|
|
ThumbnailUrl = videoDetails.Value.ThumbnailUrl,
|
|
PublishedAt = videoDetails.Value.PublishedAt,
|
|
ViewCount = videoDetails.Value.ViewCount,
|
|
LikeCount = videoDetails.Value.LikeCount,
|
|
DislikeCount = videoDetails.Value.DislikeCount,
|
|
CommentCount = videoDetails.Value.CommentCount,
|
|
CreatedAt = DateTime.UtcNow
|
|
});
|
|
}
|
|
}
|
|
|
|
// Adiciona os vídeos ao repositório
|
|
if (videoDataList.Any())
|
|
{
|
|
await _videoRepository.AddManyAsync(videoDataList);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
return Result<bool>.Failure(ex.Message);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Remove um vídeo da lista do usuário
|
|
/// </summary>
|
|
public async Task<Result<bool>> RemoveVideoAsync(string videoId)
|
|
{
|
|
if (string.IsNullOrEmpty(videoId))
|
|
return Result<bool>.Failure("ID do vídeo inválido");
|
|
|
|
try
|
|
{
|
|
await _videoRepository.DeleteAsync(videoId);
|
|
return true;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
return Result<bool>.Failure(ex.Message);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Busca vídeos no YouTube pelo título ou descrição
|
|
/// </summary>
|
|
public async Task<Result<List<VideoResponse>>> SearchVideosAsync(string query, int maxResults = 10)
|
|
{
|
|
if (string.IsNullOrEmpty(query) || query.Length < 3)
|
|
return new List<VideoResponse>();
|
|
|
|
var results = await _videoYoutubeService.SearchVideosAsync(query, maxResults);
|
|
return results;
|
|
}
|
|
}
|
|
} |