Добавьте файлы проекта.

This commit is contained in:
FrigaT
2026-04-13 14:16:44 +03:00
parent b2b5a3945a
commit 37c997dbe0
120 changed files with 5364 additions and 0 deletions

View File

@@ -0,0 +1,174 @@
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using PlaylistShared.Api.Entities;
using PlaylistShared.Api.Extensions;
using PlaylistShared.Api.Services;
using PlaylistShared.Shared.DTO;
using PlaylistShared.Shared.Enums;
using PlaylistShared.Shared.Models;
using YandexMusic;
namespace PlaylistShared.Api.Controllers;
[ApiController]
[Route("api/[controller]")]
[Authorize]
public class PlaylistController : ControllerBase
{
private readonly UserManager<ApplicationUser> _userManager;
private readonly SharedPlaylistService _sharedService;
private readonly YandexMusicService _yandexService;
private readonly TrackAdditionLogService _trackLogService;
public PlaylistController(
UserManager<ApplicationUser> userManager,
SharedPlaylistService sharedService,
YandexMusicService yandexService,
TrackAdditionLogService trackLogService)
{
_userManager = userManager;
_sharedService = sharedService;
_yandexService = yandexService;
_trackLogService = trackLogService;
}
[HttpPost("add-tracks")]
public async Task<ActionResult<ApiResponse<object>>> AddTracks([FromBody] AddTrackRequest request)
{
var currentUserId = User.GetUserId();
var playlist = await _sharedService.GetEntityByTokenAsync(request.SharedPlaylistToken);
if (playlist == null)
return NotFound(ApiResponse<object>.Fail(new ErrorResponse { StatusCode = 404, Message = "Плейлист не найден" }));
if (!await _sharedService.CanAddTrackAsync(playlist, currentUserId))
return StatusCode(403, ApiResponse<object>.Fail(new ErrorResponse { StatusCode = 403, Message = "Недостаточно прав для добавления треков" }));
var creator = await _userManager.FindByIdAsync(playlist.CreatorUserId.ToString());
if (creator == null)
return StatusCode(500, ApiResponse<object>.Fail(new ErrorResponse { StatusCode = 500, Message = "Владелец плейлиста не найден" }));
var updatedPlaylist = await _yandexService.AddTracksAsync(creator, playlist.YandexPlaylistOwnerUid, playlist.YandexPlaylistKind, request.TrackIds);
if (updatedPlaylist == null)
return StatusCode(500, ApiResponse<object>.Fail(new ErrorResponse { StatusCode = 500, Message = "Ошибка при добавлении треков в Яндекс.Музыку" }));
// Логируем добавления для права AddedByUserOnly
foreach (var trackId in request.TrackIds)
await _trackLogService.LogAdditionAsync(playlist.Id, trackId, currentUserId);
return Ok(ApiResponse<object>.Ok(new { message = "Треки успешно добавлены" }));
}
[HttpPost("remove-tracks")]
public async Task<ActionResult<ApiResponse<object>>> RemoveTracks([FromBody] AddTrackRequest request)
{
var currentUserId = User.GetUserId();
var playlist = await _sharedService.GetEntityByTokenAsync(request.SharedPlaylistToken);
if (playlist == null)
return NotFound(ApiResponse<object>.Fail(new ErrorResponse { StatusCode = 404, Message = "Плейлист не найден" }));
// Проверяем права на удаление каждого трека
foreach (var trackId in request.TrackIds)
{
if (!await _sharedService.CanRemoveTrackAsync(playlist, currentUserId, trackId))
return StatusCode(403, ApiResponse<object>.Fail(new ErrorResponse { StatusCode = 403, Message = $"Недостаточно прав для удаления трека {trackId}" }));
}
var creator = await _userManager.FindByIdAsync(playlist.CreatorUserId.ToString());
if (creator == null)
return StatusCode(500, ApiResponse<object>.Fail(new ErrorResponse { StatusCode = 500, Message = "Владелец плейлиста не найден" }));
var updatedPlaylist = await _yandexService.RemoveTracksAsync(creator, playlist.YandexPlaylistOwnerUid, playlist.YandexPlaylistKind, request.TrackIds);
if (updatedPlaylist == null)
return StatusCode(500, ApiResponse<object>.Fail(new ErrorResponse { StatusCode = 500, Message = "Ошибка при удалении треков из Яндекс.Музыки" }));
// Удаляем логи добавления для этих треков
foreach (var trackId in request.TrackIds)
await _trackLogService.RemoveLogsForTrackAsync(playlist.Id, trackId);
return Ok(ApiResponse<object>.Ok(new { message = "Треки успешно удалены" }));
}
[HttpGet("info/{ownerUid}/{kind}")]
public async Task<ActionResult<ApiResponse<object>>> GetPlaylistInfo(string ownerUid, string kind)
{
var currentUserId = User.GetUserId();
// Найти шеринг-плейлист по данным Яндекс
var shared = await _sharedService.GetEntityByTokenAsync(null); // не можем по токену, надо по параметрам
// Для простоты сделаем отдельный метод поиска по kind/ownerUid
var playlistEntity = await _sharedService.GetByYandexIdsAsync(ownerUid, kind);
if (playlistEntity == null)
return NotFound(ApiResponse<object>.Fail(new ErrorResponse { StatusCode = 404, Message = "Плейлист не найден" }));
if (!await _sharedService.CanViewAsync(playlistEntity, currentUserId))
return Unauthorized();
var creator = await _userManager.FindByIdAsync(playlistEntity.CreatorUserId.ToString());
var yandexPlaylist = await _yandexService.GetPlaylistAsync(creator, ownerUid, kind);
return Ok(ApiResponse<object>.Ok(yandexPlaylist));
}
[HttpGet("my")]
public async Task<ActionResult<ApiResponse<List<YandexPlaylistInfo>>>> GetMyPlaylists()
{
var userId = User.GetUserId();
var user = await _userManager.FindByIdAsync(userId.ToString());
if (user == null) return Unauthorized();
var decryptedToken = _yandexService.DecryptToken(user.YandexAccessToken);
if (string.IsNullOrEmpty(decryptedToken))
return BadRequest(ApiResponse<object>.Fail(new ErrorResponse { StatusCode = 400, Message = "Токен Яндекс.Музыки не установлен или недействителен" }));
var yandexClient = new YandexMusicClient();
var authSuccess = await yandexClient.Authorize(decryptedToken);
if (!authSuccess)
return BadRequest(ApiResponse<object>.Fail(new ErrorResponse { StatusCode = 400, Message = "Не удалось авторизоваться в Яндекс.Музыке. Проверьте токен." }));
var favorites = await yandexClient.GetFavoritesAsync();
var ownPlaylists = favorites.Where(p => p.Owner.Uid == yandexClient.Account.Uid).ToList();
var sharedPlaylists = await _sharedService.GetAllByUserAsync(userId);
var result = ownPlaylists.Select(p => new YandexPlaylistInfo
{
Kind = p.Kind,
OwnerUid = p.Owner.Uid,
Title = p.Title,
CoverUrl = p.Cover?.GetUrl() ?? "",
TrackCount = p.TrackCount,
IsShared = sharedPlaylists.Any(s => s.YandexPlaylistKind == p.Kind && s.YandexPlaylistOwnerUid == p.Owner.Uid),
ShareToken = sharedPlaylists.FirstOrDefault(s => s.YandexPlaylistKind == p.Kind && s.YandexPlaylistOwnerUid == p.Owner.Uid)?.ShareToken,
}).ToList();
return Ok(ApiResponse<List<YandexPlaylistInfo>>.Ok(result));
}
[HttpPost("share")]
public async Task<ActionResult<ApiResponse<SharedPlaylistDto>>> SharePlaylist([FromBody] SharePlaylistRequest request)
{
var userId = User.GetUserId();
var user = await _userManager.FindByIdAsync(userId.ToString());
if (user == null) return Unauthorized();
// Проверяем, что плейлист действительно принадлежит пользователю
var yandexClient = new YandexMusicClient();
await yandexClient.Authorize(_yandexService.DecryptToken(user.YandexAccessToken));
var playlist = await yandexClient.GetPlaylistAsync(request.OwnerUid, request.Kind);
if (playlist == null || playlist.Owner.Uid != yandexClient.Account.Uid)
return BadRequest(ApiResponse<object>.Fail(new ErrorResponse { StatusCode = 400, Message = "Плейлист не принадлежит вам" }));
var dto = new SharePlaylistDto
{
YandexPlaylistKind = request.Kind,
YandexPlaylistOwnerUid = request.OwnerUid,
Title = playlist.Title,
Description = playlist.Description,
ViewPermission = ViewPermission.Everyone,
AddPermission = EditPermission.AuthorizedOnly,
RemovePermission = EditPermission.AddedByUserOnly
};
var result = await _sharedService.CreateAsync(userId, dto);
return Ok(ApiResponse<SharedPlaylistDto>.Ok(result));
}
}