223 lines
9.0 KiB
C#
223 lines
9.0 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.IO;
|
|
using System.Threading.Tasks;
|
|
using DysonNetwork.Drive.Interfaces;
|
|
using DysonNetwork.Drive.Models;
|
|
using Microsoft.AspNetCore.Authorization;
|
|
using Microsoft.AspNetCore.Http;
|
|
using Microsoft.AspNetCore.Mvc;
|
|
using Microsoft.Extensions.Logging;
|
|
|
|
namespace DysonNetwork.Drive.Controllers
|
|
{
|
|
[ApiController]
|
|
[Route("api/files")]
|
|
[Authorize]
|
|
public class FileController : ControllerBase
|
|
{
|
|
private readonly IFileService _fileService;
|
|
private readonly ILogger<FileController> _logger;
|
|
|
|
public FileController(IFileService fileService, ILogger<FileController> logger)
|
|
{
|
|
_fileService = fileService ?? throw new ArgumentNullException(nameof(fileService));
|
|
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
|
|
}
|
|
|
|
[HttpGet("{fileId}")]
|
|
[ProducesResponseType(typeof(FileResult), StatusCodes.Status200OK)]
|
|
[ProducesResponseType(StatusCodes.Status404NotFound)]
|
|
public async Task<IActionResult> GetFile(Guid fileId, CancellationToken cancellationToken = default)
|
|
{
|
|
try
|
|
{
|
|
var file = await _fileService.GetFileAsync(fileId, cancellationToken);
|
|
var stream = await _fileService.DownloadFileAsync(fileId, cancellationToken);
|
|
|
|
return File(stream, file.MimeType, file.OriginalName);
|
|
}
|
|
catch (FileNotFoundException ex)
|
|
{
|
|
_logger.LogWarning(ex, "File not found: {FileId}", fileId);
|
|
return NotFound(new { message = $"File with ID {fileId} not found." });
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_logger.LogError(ex, "Error retrieving file: {FileId}", fileId);
|
|
return StatusCode(StatusCodes.Status500InternalServerError, new { message = "An error occurred while retrieving the file." });
|
|
}
|
|
}
|
|
|
|
[HttpPost("upload")]
|
|
[ProducesResponseType(typeof(CloudFile), StatusCodes.Status201Created)]
|
|
[ProducesResponseType(StatusCodes.Status400BadRequest)]
|
|
public async Task<IActionResult> UploadFile(IFormFile file, CancellationToken cancellationToken = default)
|
|
{
|
|
if (file == null || file.Length == 0)
|
|
{
|
|
return BadRequest(new { message = "No file uploaded." });
|
|
}
|
|
|
|
try
|
|
{
|
|
using var stream = file.OpenReadStream();
|
|
var uploadedFile = await _fileService.UploadFileAsync(
|
|
stream,
|
|
file.FileName,
|
|
file.ContentType,
|
|
null,
|
|
cancellationToken);
|
|
|
|
return CreatedAtAction(
|
|
nameof(GetFile),
|
|
new { fileId = uploadedFile.Id },
|
|
uploadedFile);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_logger.LogError(ex, "Error uploading file: {FileName}", file?.FileName);
|
|
return StatusCode(StatusCodes.Status500InternalServerError, new { message = "An error occurred while uploading the file." });
|
|
}
|
|
}
|
|
|
|
[HttpDelete("{fileId}")]
|
|
[ProducesResponseType(StatusCodes.Status204NoContent)]
|
|
[ProducesResponseType(StatusCodes.Status404NotFound)]
|
|
public async Task<IActionResult> DeleteFile(Guid fileId, CancellationToken cancellationToken = default)
|
|
{
|
|
try
|
|
{
|
|
var deleted = await _fileService.DeleteFileAsync(fileId, cancellationToken);
|
|
if (!deleted)
|
|
{
|
|
return NotFound(new { message = $"File with ID {fileId} not found." });
|
|
}
|
|
|
|
return NoContent();
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_logger.LogError(ex, "Error deleting file: {FileId}", fileId);
|
|
return StatusCode(StatusCodes.Status500InternalServerError, new { message = "An error occurred while deleting the file." });
|
|
}
|
|
}
|
|
|
|
[HttpGet("{fileId}/metadata")]
|
|
[ProducesResponseType(typeof(CloudFile), StatusCodes.Status200OK)]
|
|
[ProducesResponseType(StatusCodes.Status404NotFound)]
|
|
public async Task<IActionResult> GetFileMetadata(Guid fileId, CancellationToken cancellationToken = default)
|
|
{
|
|
try
|
|
{
|
|
var file = await _fileService.GetFileAsync(fileId, cancellationToken);
|
|
return Ok(file);
|
|
}
|
|
catch (FileNotFoundException ex)
|
|
{
|
|
_logger.LogWarning(ex, "File not found: {FileId}", fileId);
|
|
return NotFound(new { message = $"File with ID {fileId} not found." });
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_logger.LogError(ex, "Error retrieving file metadata: {FileId}", fileId);
|
|
return StatusCode(StatusCodes.Status500InternalServerError, new { message = "An error occurred while retrieving file metadata." });
|
|
}
|
|
}
|
|
|
|
[HttpPut("{fileId}/metadata")]
|
|
[ProducesResponseType(typeof(CloudFile), StatusCodes.Status200OK)]
|
|
[ProducesResponseType(StatusCodes.Status400BadRequest)]
|
|
[ProducesResponseType(StatusCodes.Status404NotFound)]
|
|
public async Task<IActionResult> UpdateFileMetadata(
|
|
Guid fileId,
|
|
[FromBody] Dictionary<string, string> metadata,
|
|
CancellationToken cancellationToken = default)
|
|
{
|
|
if (metadata == null || metadata.Count == 0)
|
|
{
|
|
return BadRequest(new { message = "No metadata provided." });
|
|
}
|
|
|
|
try
|
|
{
|
|
var updatedFile = await _fileService.UpdateFileMetadataAsync(fileId, metadata, cancellationToken);
|
|
return Ok(updatedFile);
|
|
}
|
|
catch (FileNotFoundException ex)
|
|
{
|
|
_logger.LogWarning(ex, "File not found: {FileId}", fileId);
|
|
return NotFound(new { message = $"File with ID {fileId} not found." });
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_logger.LogError(ex, "Error updating file metadata: {FileId}", fileId);
|
|
return StatusCode(StatusCodes.Status500InternalServerError, new { message = "An error occurred while updating file metadata." });
|
|
}
|
|
}
|
|
|
|
[HttpGet("{fileId}/url")]
|
|
[ProducesResponseType(typeof(string), StatusCodes.Status200OK)]
|
|
[ProducesResponseType(StatusCodes.Status404NotFound)]
|
|
public async Task<IActionResult> GetFileUrl(Guid fileId, [FromQuery] int? expiresInSeconds = null, CancellationToken cancellationToken = default)
|
|
{
|
|
try
|
|
{
|
|
TimeSpan? expiry = expiresInSeconds.HasValue
|
|
? TimeSpan.FromSeconds(expiresInSeconds.Value)
|
|
: null;
|
|
|
|
var url = await _fileService.GetFileUrlAsync(fileId, expiry, cancellationToken);
|
|
return Ok(new { url });
|
|
}
|
|
catch (FileNotFoundException ex)
|
|
{
|
|
_logger.LogWarning(ex, "File not found: {FileId}", fileId);
|
|
return NotFound(new { message = $"File with ID {fileId} not found." });
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_logger.LogError(ex, "Error generating file URL: {FileId}", fileId);
|
|
return StatusCode(StatusCodes.Status500InternalServerError, new { message = "An error occurred while generating the file URL." });
|
|
}
|
|
}
|
|
|
|
[HttpGet("{fileId}/thumbnail")]
|
|
[ProducesResponseType(StatusCodes.Status200OK)]
|
|
[ProducesResponseType(StatusCodes.Status404NotFound)]
|
|
public async Task<IActionResult> GetFileThumbnail(
|
|
Guid fileId,
|
|
[FromQuery] int? width = null,
|
|
[FromQuery] int? height = null,
|
|
[FromQuery] int? expiresInSeconds = null,
|
|
CancellationToken cancellationToken = default)
|
|
{
|
|
try
|
|
{
|
|
TimeSpan? expiry = expiresInSeconds.HasValue
|
|
? TimeSpan.FromSeconds(expiresInSeconds.Value)
|
|
: null;
|
|
|
|
var url = await _fileService.GetFileThumbnailUrlAsync(
|
|
fileId,
|
|
width,
|
|
height,
|
|
expiry,
|
|
cancellationToken);
|
|
|
|
return Ok(new { url });
|
|
}
|
|
catch (FileNotFoundException ex)
|
|
{
|
|
_logger.LogWarning(ex, "File not found: {FileId}", fileId);
|
|
return NotFound(new { message = $"File with ID {fileId} not found." });
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_logger.LogError(ex, "Error generating thumbnail URL: {FileId}", fileId);
|
|
return StatusCode(StatusCodes.Status500InternalServerError, new { message = "An error occurred while generating the thumbnail URL." });
|
|
}
|
|
}
|
|
}
|
|
}
|