Web: Add file api

This commit is contained in:
genteure 2022-06-12 14:44:29 +08:00
parent eed940cc01
commit c059975165
6 changed files with 158 additions and 0 deletions

View File

@ -0,0 +1,99 @@
using System;
using System.Collections.Generic;
using BililiveRecorder.Core;
using BililiveRecorder.Web.Models.Rest.Files;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.FileProviders;
namespace BililiveRecorder.Web.Api
{
[ApiController, Route("api/[controller]", Name = "[controller] [action]")]
public sealed class FileController : ControllerBase, IDisposable
{
private readonly PhysicalFileProvider? fileProvider;
private bool disposedValue;
public FileController(IRecorder recorder, BililiveRecorderFileExplorerSettings fileExplorerSettings)
{
if (recorder is null) throw new ArgumentNullException(nameof(recorder));
if (fileExplorerSettings is null) throw new ArgumentNullException(nameof(fileExplorerSettings));
if (fileExplorerSettings.Enable)
{
this.fileProvider = new PhysicalFileProvider(recorder.Config.Global.WorkDirectory);
}
}
/// <summary>
/// 获取录播目录文件信息
/// </summary>
/// <param name="path" example="/">路径</param>
/// <returns></returns>
[HttpGet]
[ProducesResponseType(StatusCodes.Status200OK)]
public FileApiResult GetFiles([FromQuery] string path)
{
if (this.fileProvider is null || path is null)
return FileApiResult.NotExist;
var contents = this.fileProvider.GetDirectoryContents(path);
if (!contents.Exists)
return FileApiResult.NotExist;
var fileLikes = new List<FileLikeDto>();
foreach (var content in contents)
{
try
{
if (!content.Exists)
continue;
if (content.IsDirectory)
{
fileLikes.Add(new FolderDto
{
Name = content.Name,
LastModified = content.LastModified,
});
}
else
{
fileLikes.Add(new FileDto
{
Name = content.Name,
LastModified = content.LastModified,
Size = content.Length,
// Path.Combine 在 Windows 上会用 \
Url = "/file/" + path.Trim('/') + '/' + content.Name,
});
}
}
catch (Exception) { }
}
return new FileApiResult(true, path, fileLikes);
}
private void Dispose(bool disposing)
{
if (!this.disposedValue)
{
if (disposing)
{
this.fileProvider?.Dispose();
}
this.disposedValue = true;
}
}
public void Dispose()
{
// Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method
this.Dispose(disposing: true);
GC.SuppressFinalize(this);
}
}
}

View File

@ -0,0 +1,23 @@
using System;
using System.Collections.Generic;
namespace BililiveRecorder.Web.Models.Rest.Files
{
public sealed class FileApiResult
{
public static readonly FileApiResult NotExist = new FileApiResult(false, string.Empty, Array.Empty<FileLikeDto>());
public FileApiResult(bool exist, string path, IReadOnlyList<FileLikeDto> files)
{
this.Exist = exist;
this.Path = path ?? throw new ArgumentNullException(nameof(path));
this.Files = files ?? throw new ArgumentNullException(nameof(files));
}
public bool Exist { get; }
public string Path { get; }
public IReadOnlyList<FileLikeDto> Files { get; }
}
}

View File

@ -0,0 +1,12 @@
namespace BililiveRecorder.Web.Models.Rest.Files
{
public sealed class FileDto : FileLikeDto
{
/// <example>false</example>
public override bool IsFolder => false;
public long Size { get; set; }
public string Url { get; set; } = string.Empty;
}
}

View File

@ -0,0 +1,13 @@
using System;
namespace BililiveRecorder.Web.Models.Rest.Files
{
public abstract class FileLikeDto
{
public abstract bool IsFolder { get; }
public string Name { get; set; } = string.Empty;
public DateTimeOffset LastModified { get; set; }
}
}

View File

@ -0,0 +1,8 @@
namespace BililiveRecorder.Web.Models.Rest.Files
{
public sealed class FolderDto : FileLikeDto
{
/// <example>true</example>
public override bool IsFolder => true;
}
}

View File

@ -98,6 +98,9 @@ namespace BililiveRecorder.Web
services
.AddSwaggerGen(c =>
{
c.UseAllOfForInheritance();
c.UseOneOfForPolymorphism();
c.SwaggerDoc("brec", new OpenApiInfo
{
Title = "录播姬 REST API",