using System; using System.IO; using System.Reflection; using System.Text; using Microsoft.AspNetCore.Mvc; namespace Jellyfin.Plugin.Seasonals.Api; [ApiController] [Route("Seasonals")] public class SeasonalsController : ControllerBase { [HttpGet("Config")] [Produces("application/json")] public ActionResult GetConfig() { var config = Plugin.Instance?.Configuration; return new { selectedSeason = config?.SelectedSeason ?? "none", automateSeasonSelection = config?.AutomateSeasonSelection ?? true }; } [HttpGet("Resources/{*path}")] public ActionResult GetResource(string path) { // Sanitize path if (string.IsNullOrWhiteSpace(path) || path.Contains("..")) { return BadRequest(); } var assembly = Assembly.GetExecutingAssembly(); // Convert path to resource name // path: "autumn_images/acorn1.png" -> "Jellyfin.Plugin.Seasonals.Web.autumn_images.acorn1.png" var resourcePath = path.Replace('/', '.').Replace('\\', '.'); var resourceName = $"Jellyfin.Plugin.Seasonals.Web.{resourcePath}"; var stream = assembly.GetManifestResourceStream(resourceName); if (stream == null) { return NotFound($"Resource not found: {resourceName}"); } string contentType = GetContentType(path); return File(stream, contentType); } private string GetContentType(string path) { if (path.EndsWith(".js", StringComparison.OrdinalIgnoreCase)) return "application/javascript"; if (path.EndsWith(".css", StringComparison.OrdinalIgnoreCase)) return "text/css"; if (path.EndsWith(".png", StringComparison.OrdinalIgnoreCase)) return "image/png"; if (path.EndsWith(".jpg", StringComparison.OrdinalIgnoreCase)) return "image/jpeg"; if (path.EndsWith(".gif", StringComparison.OrdinalIgnoreCase)) return "image/gif"; return "application/octet-stream"; } }