From bd5b51a5e010252675f427d1c6b78f7cfa788423 Mon Sep 17 00:00:00 2001 From: Mikal Stordal Date: Fri, 7 Apr 2023 01:59:43 +0200 Subject: [PATCH] feat: add v3 file stream endpoint --- .../API/v3/Controllers/FileController.cs | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/Shoko.Server/API/v3/Controllers/FileController.cs b/Shoko.Server/API/v3/Controllers/FileController.cs index 7b12678bd..b87c1c89a 100644 --- a/Shoko.Server/API/v3/Controllers/FileController.cs +++ b/Shoko.Server/API/v3/Controllers/FileController.cs @@ -5,6 +5,7 @@ using System.Text.RegularExpressions; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.StaticFiles; using Shoko.Models.Enums; using Shoko.Server.API.Annotations; using Shoko.Server.API.ModelBinders; @@ -160,6 +161,31 @@ public ActionResult GetFileByAnidbFileID([FromRoute] int anidbFileID, [Fro return new File(HttpContext, file, includeXRefs, includeDataFrom, includeMediaInfo); } + /// + /// Returns a file stream for the specified file ID. + /// + /// Shoko ID + /// A file stream for the specified file. + [HttpGet("{fileID}/Stream")] + public ActionResult GetFileStream([FromRoute] int fileID) + { + var file = RepoFactory.VideoLocal.GetByID(fileID); + if (file == null) + return NotFound(FileNotFoundWithFileID); + + var bestLocation = file.GetBestVideoLocalPlace(); + + var fileInfo = bestLocation.GetFile(); + if (fileInfo == null) + return InternalError("Unable to find physical file for reading the stream data."); + + var provider = new FileExtensionContentTypeProvider(); + if (!provider.TryGetContentType(fileInfo.FullName, out var contentType)) + contentType = "application/octet-stream"; + + return PhysicalFile(fileInfo.FullName, contentType, enableRangeProcessing: true); + } + /// /// Get the MediaInfo model for file with VideoLocal ID ///