All checks were successful
Auto Release Plugin / build-and-release (push) Successful in 43s
90 lines
3.4 KiB
C#
90 lines
3.4 KiB
C#
using System;
|
|
using System.IO;
|
|
using System.Threading.Tasks;
|
|
using Microsoft.AspNetCore.Http;
|
|
using Microsoft.AspNetCore.Mvc;
|
|
using MediaBrowser.Common.Configuration;
|
|
|
|
namespace Jellyfin.Plugin.MediaBarEnhanced.Api
|
|
{
|
|
/// <summary>
|
|
/// Controller for handling custom overlay image uploads and retrieval.
|
|
/// </summary>
|
|
[ApiController]
|
|
[Route("MediaBarEnhanced")]
|
|
public class OverlayImageController : ControllerBase
|
|
{
|
|
private readonly IApplicationPaths _applicationPaths;
|
|
private readonly string _imageDirectory;
|
|
private readonly string _imagePath;
|
|
|
|
public OverlayImageController(IApplicationPaths applicationPaths)
|
|
{
|
|
_applicationPaths = applicationPaths;
|
|
|
|
// We use the plugin's data folder to store the image
|
|
_imageDirectory = MediaBarEnhancedPlugin.Instance?.DataFolderPath ?? Path.Combine(applicationPaths.DataPath, "plugins", "MediaBarEnhanced");
|
|
|
|
// We'll just overwrite this single file each time
|
|
_imagePath = Path.Combine(_imageDirectory, "custom_overlay_image.dat");
|
|
}
|
|
|
|
/// <summary>
|
|
/// Uploads a new custom overlay image.
|
|
/// </summary>
|
|
[HttpPost("OverlayImage")]
|
|
[Consumes("multipart/form-data")]
|
|
public async Task<IActionResult> UploadImage([FromForm] IFormFile file)
|
|
{
|
|
if (file == null || file.Length == 0)
|
|
{
|
|
return BadRequest("No file uploaded.");
|
|
}
|
|
|
|
try
|
|
{
|
|
if (!Directory.Exists(_imageDirectory))
|
|
{
|
|
Directory.CreateDirectory(_imageDirectory);
|
|
}
|
|
|
|
// Delete is not strictly necessary and can cause locking issues if someone is currently reading it.
|
|
// FileMode.Create will truncate the file if it exists, effectively overwriting it.
|
|
// We use FileShare.None to ensure we have exclusive write access, but handle potential IOExceptions gracefully.
|
|
using (var stream = new FileStream(_imagePath, FileMode.Create, FileAccess.Write, FileShare.None))
|
|
{
|
|
await file.CopyToAsync(stream).ConfigureAwait(false);
|
|
}
|
|
|
|
// Return the GET URL that the frontend can use
|
|
var getUrl = "/MediaBarEnhanced/OverlayImage?t=" + DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
|
|
return Ok(new { url = getUrl });
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
return StatusCode(500, $"Internal server error: {ex.Message}");
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Retrieves the custom overlay image.
|
|
/// </summary>
|
|
[HttpGet("OverlayImage")]
|
|
public IActionResult GetImage()
|
|
{
|
|
if (!System.IO.File.Exists(_imagePath))
|
|
{
|
|
return NotFound();
|
|
}
|
|
|
|
// Read the file and return as a generic octet stream.
|
|
// We use FileShare.ReadWrite so that if someone is currently overwriting the file (uploading), we don't block them,
|
|
// and we also don't get blocked by other readers.
|
|
var stream = new FileStream(_imagePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
|
|
|
|
// "image/*" works reliably as browsers will sniff the exact image mime type (jpeg, png, webp).
|
|
return File(stream, "image/*");
|
|
}
|
|
}
|
|
}
|