Only serializing useful informations for each query. Cleaning up the rest API

This commit is contained in:
Zoe Roux 2020-02-11 22:26:38 +01:00
parent aca93acc86
commit 84f8d545a6
17 changed files with 183 additions and 104 deletions

View File

@ -25,7 +25,7 @@ namespace Kyoo.Models
[JsonIgnore] public string ImgPrimary { get; set; } [JsonIgnore] public string ImgPrimary { get; set; }
public string ExternalIDs { get; set; } public string ExternalIDs { get; set; }
public virtual IEnumerable<Track> Tracks { get; set; } [JsonIgnore] public virtual IEnumerable<Track> Tracks { get; set; }
public string ShowTitle; //Used in the API response only public string ShowTitle; //Used in the API response only
public string Link; //Used in the API response only public string Link; //Used in the API response only

View File

@ -29,15 +29,15 @@ namespace Kyoo.Models
public bool IsCollection; public bool IsCollection;
public virtual IEnumerable<Genre> Genres [JsonIgnore] public virtual IEnumerable<Genre> Genres
{ {
get { return GenreLinks?.Select(x => x.Genre).OrderBy(x => x.Name); } get { return GenreLinks?.Select(x => x.Genre).OrderBy(x => x.Name); }
set { GenreLinks = value?.Select(x => new GenreLink(this, x)).ToList(); } set { GenreLinks = value?.Select(x => new GenreLink(this, x)).ToList(); }
} }
[JsonIgnore] public virtual List<GenreLink> GenreLinks { get; set; } [JsonIgnore] public virtual List<GenreLink> GenreLinks { get; set; }
public virtual Studio Studio { get; set; } [JsonIgnore] public virtual Studio Studio { get; set; }
public virtual IEnumerable<PeopleLink> People { get; set; } [JsonIgnore] public virtual IEnumerable<PeopleLink> People { get; set; }
public virtual IEnumerable<Season> Seasons { get; set; } [JsonIgnore] public virtual IEnumerable<Season> Seasons { get; set; }
[JsonIgnore] public virtual IEnumerable<Episode> Episodes { get; set; } [JsonIgnore] public virtual IEnumerable<Episode> Episodes { get; set; }

View File

@ -67,6 +67,7 @@ namespace Kyoo.Controllers
public IEnumerable<Show> GetShows(string searchQuery) public IEnumerable<Show> GetShows(string searchQuery)
{ {
// TODO use case insensitive queries.
return (from show in _database.Shows from l in _database.CollectionLinks.DefaultIfEmpty() return (from show in _database.Shows from l in _database.CollectionLinks.DefaultIfEmpty()
where l.CollectionID == null select show).AsEnumerable().Union( where l.CollectionID == null select show).AsEnumerable().Union(
from collection in _database.Collections select collection.AsShow()) from collection in _database.Collections select collection.AsShow())

View File

@ -1,7 +1,8 @@
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using System.Threading; using System.Threading;
using Kyoo.Controllers;
namespace Kyoo.Controllers namespace Kyoo.Api
{ {
[Route("api/[controller]")] [Route("api/[controller]")]
[ApiController] [ApiController]

View File

@ -3,7 +3,7 @@ using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
namespace Kyoo.Controllers namespace Kyoo.Api
{ {
public class AuthentificationAPI : Controller public class AuthentificationAPI : Controller
{ {

View File

@ -3,23 +3,23 @@ using Kyoo.Models;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using System.Collections.Generic; using System.Collections.Generic;
namespace Kyoo.Controllers namespace Kyoo.Api
{ {
[Route("api/[controller]")] [Route("api/[controller]")]
[ApiController] [ApiController]
public class CollectionController : ControllerBase public class CollectionController : ControllerBase
{ {
private readonly ILibraryManager libraryManager; private readonly ILibraryManager _libraryManager;
public CollectionController(ILibraryManager libraryManager) public CollectionController(ILibraryManager libraryManager)
{ {
this.libraryManager = libraryManager; _libraryManager = libraryManager;
} }
[HttpGet("{collectionSlug}")] [HttpGet("{collectionSlug}")]
public ActionResult<Collection> GetShows(string collectionSlug) public ActionResult<Collection> GetShows(string collectionSlug)
{ {
Collection collection = libraryManager.GetCollection(collectionSlug); Collection collection = _libraryManager.GetCollection(collectionSlug);
if (collection == null) if (collection == null)
return NotFound(); return NotFound();

View File

@ -2,8 +2,9 @@
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using Kyoo.Controllers;
namespace Kyoo.Controllers namespace Kyoo.Api
{ {
[Route("api/[controller]")] [Route("api/[controller]")]
[ApiController] [ApiController]
@ -28,6 +29,7 @@ namespace Kyoo.Controllers
} }
[HttpGet("{showSlug}/season/{seasonNumber}/episode/{episodeNumber}")] [HttpGet("{showSlug}/season/{seasonNumber}/episode/{episodeNumber}")]
[JsonDetailed]
public ActionResult<Episode> GetEpisode(string showSlug, long seasonNumber, long episodeNumber) public ActionResult<Episode> GetEpisode(string showSlug, long seasonNumber, long episodeNumber)
{ {
Episode episode = _libraryManager.GetEpisode(showSlug, seasonNumber, episodeNumber); Episode episode = _libraryManager.GetEpisode(showSlug, seasonNumber, episodeNumber);

View File

@ -0,0 +1,89 @@
using System;
using System.Buffers;
using System.Collections.Generic;
using System.Reflection;
using Kyoo.Models;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.AspNetCore.Mvc.Formatters;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;
namespace Kyoo.Controllers
{
public class JsonPropertySelector : DefaultContractResolver
{
private readonly Dictionary<Type, HashSet<string>> _ignored;
private readonly Dictionary<Type, HashSet<string>> _forceSerialize;
public JsonPropertySelector()
{
_ignored = new Dictionary<Type, HashSet<string>>();
_forceSerialize = new Dictionary<Type, HashSet<string>>();
}
public JsonPropertySelector(Dictionary<Type, HashSet<string>> ignored, Dictionary<Type, HashSet<string>> forceSerialize)
{
_ignored = ignored ?? new Dictionary<Type, HashSet<string>>();
_forceSerialize = forceSerialize ?? new Dictionary<Type, HashSet<string>>();
}
private bool IsIgnored(Type type, string propertyName)
{
if (_ignored.ContainsKey(type) && _ignored[type].Contains(propertyName))
return true;
if (type.BaseType == null)
return false;
return _ignored.ContainsKey(type.BaseType) && _ignored[type.BaseType].Contains(propertyName);
}
private bool IsSerializationForced(Type type, string propertyName)
{
if (_forceSerialize.ContainsKey(type) && _forceSerialize[type].Contains(propertyName))
return true;
if (type.BaseType == null)
return false;
return _forceSerialize.ContainsKey(type.BaseType) && _forceSerialize[type.BaseType].Contains(propertyName);
}
protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization)
{
JsonProperty property = base.CreateProperty(member, memberSerialization);
if (IsIgnored(property.DeclaringType, property.PropertyName))
{
property.ShouldSerialize = i => false;
property.Ignored = true;
}
else if (IsSerializationForced(property.DeclaringType, property.PropertyName))
{
property.ShouldSerialize = i => true;
property.Ignored = false;
}
return property;
}
}
public class JsonDetailed : ActionFilterAttribute
{
public override void OnActionExecuted(ActionExecutedContext context)
{
if (context.Result is ObjectResult result)
{
result.Formatters.Add(new NewtonsoftJsonOutputFormatter(
new JsonSerializerSettings
{
ContractResolver = new JsonPropertySelector(null, new Dictionary<Type, HashSet<string>>()
{
{typeof(Show), new HashSet<string> {"Genres", "Studio", "People", "Seasons"}},
{typeof(Episode), new HashSet<string> {"Tracks"}}
})
},
context.HttpContext.RequestServices.GetRequiredService<ArrayPool<char>>(),
context.HttpContext.RequestServices.GetRequiredService<IOptions<MvcOptions>>().Value));
}
}
}
}

View File

@ -4,7 +4,7 @@ using Microsoft.AspNetCore.Mvc;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
namespace Kyoo.Controllers namespace Kyoo.Api
{ {
[Route("api/libraries")] [Route("api/libraries")]
[ApiController] [ApiController]

View File

@ -1,31 +1,30 @@
using Kyoo.Controllers; using Kyoo.Controllers;
using Kyoo.Models; using Kyoo.Models;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using System.Diagnostics;
namespace Kyoo.Controllers namespace Kyoo.Api
{ {
[Route("api/[controller]")] [Route("api/[controller]")]
[ApiController] [ApiController]
public class PeopleController : ControllerBase public class PeopleController : ControllerBase
{ {
private readonly ILibraryManager libraryManager; private readonly ILibraryManager _libraryManager;
public PeopleController(ILibraryManager libraryManager) public PeopleController(ILibraryManager libraryManager)
{ {
this.libraryManager = libraryManager; _libraryManager = libraryManager;
} }
[HttpGet("{peopleSlug}")] [HttpGet("{peopleSlug}")]
public ActionResult<Collection> GetPeople(string peopleSlug) public ActionResult<Collection> GetPeople(string peopleSlug)
{ {
People people = libraryManager.GetPeopleBySlug(peopleSlug); People people = _libraryManager.GetPeopleBySlug(peopleSlug);
if (people == null) if (people == null)
return NotFound(); return NotFound();
Collection collection = new Collection(people.Slug, people.Name, null, null) Collection collection = new Collection(people.Slug, people.Name, null, null)
{ {
Shows = libraryManager.GetShowsByPeople(people.ID), Shows = _libraryManager.GetShowsByPeople(people.ID),
Poster = "peopleimg/" + people.Slug Poster = "peopleimg/" + people.Slug
}; };
return collection; return collection;

View File

@ -2,7 +2,7 @@
using Kyoo.Models; using Kyoo.Models;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
namespace Kyoo.Controllers namespace Kyoo.Api
{ {
[Route("api/[controller]")] [Route("api/[controller]")]
[ApiController] [ApiController]

View File

@ -1,35 +1,36 @@
using Kyoo.Controllers; using Kyoo.Models;
using Kyoo.Models;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using System.Collections.Generic; using System.Collections.Generic;
using Kyoo.Controllers;
namespace Kyoo.Controllers namespace Kyoo.Api
{ {
[Route("api/shows")] [Route("api/shows")]
[ApiController] [ApiController]
public class ShowsController : ControllerBase public class ShowsController : ControllerBase
{ {
private readonly ILibraryManager libraryManager; private readonly ILibraryManager _libraryManager;
public ShowsController(ILibraryManager libraryManager) public ShowsController(ILibraryManager libraryManager)
{ {
this.libraryManager = libraryManager; _libraryManager = libraryManager;
} }
[HttpGet] [HttpGet]
public IEnumerable<Show> GetShows() public IEnumerable<Show> GetShows()
{ {
return libraryManager.GetShows(); return _libraryManager.GetShows();
} }
[HttpGet("{slug}")] [HttpGet("{slug}")]
[JsonDetailed]
public ActionResult<Show> GetShow(string slug) public ActionResult<Show> GetShow(string slug)
{ {
Show show = libraryManager.GetShowBySlug(slug); Show show = _libraryManager.GetShowBySlug(slug);
if (show == null) if (show == null)
return NotFound(); return NotFound();
return show; return show;
} }
} }

View File

@ -3,20 +3,21 @@ using Microsoft.AspNetCore.Mvc;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using System.Threading.Tasks; using System.Threading.Tasks;
using Kyoo.Controllers;
namespace Kyoo.Controllers namespace Kyoo.Api
{ {
[Route("[controller]")] [Route("[controller]")]
[ApiController] [ApiController]
public class SubtitleController : ControllerBase public class SubtitleController : ControllerBase
{ {
private readonly ILibraryManager libraryManager; private readonly ILibraryManager _libraryManager;
private readonly ITranscoder transcoder; private readonly ITranscoder _transcoder;
public SubtitleController(ILibraryManager libraryManager, ITranscoder transcoder) public SubtitleController(ILibraryManager libraryManager, ITranscoder transcoder)
{ {
this.libraryManager = libraryManager; _libraryManager = libraryManager;
this.transcoder = transcoder; _transcoder = transcoder;
} }
[HttpGet("{showSlug}-s{seasonNumber:int}e{episodeNumber:int}.{identifier}.{extension?}")] [HttpGet("{showSlug}-s{seasonNumber:int}e{episodeNumber:int}.{identifier}.{extension?}")]
@ -25,7 +26,7 @@ namespace Kyoo.Controllers
string languageTag = identifier.Substring(0, 3); string languageTag = identifier.Substring(0, 3);
bool forced = identifier.Length > 3 && identifier.Substring(4) == "forced"; bool forced = identifier.Length > 3 && identifier.Substring(4) == "forced";
Track subtitle = libraryManager.GetSubtitle(showSlug, seasonNumber, episodeNumber, languageTag, forced); Track subtitle = _libraryManager.GetSubtitle(showSlug, seasonNumber, episodeNumber, languageTag, forced);
if (subtitle == null) if (subtitle == null)
return NotFound(); return NotFound();
@ -49,14 +50,14 @@ namespace Kyoo.Controllers
[HttpGet("extract/{showSlug}-s{seasonNumber}e{episodeNumber}")] [HttpGet("extract/{showSlug}-s{seasonNumber}e{episodeNumber}")]
public async Task<string> ExtractSubtitle(string showSlug, long seasonNumber, long episodeNumber) public async Task<string> ExtractSubtitle(string showSlug, long seasonNumber, long episodeNumber)
{ {
Episode episode = libraryManager.GetEpisode(showSlug, seasonNumber, episodeNumber); Episode episode = _libraryManager.GetEpisode(showSlug, seasonNumber, episodeNumber);
libraryManager.ClearSubtitles(episode.ID); _libraryManager.ClearSubtitles(episode.ID);
Track[] tracks = await transcoder.ExtractSubtitles(episode.Path); Track[] tracks = await _transcoder.ExtractSubtitles(episode.Path);
foreach (Track track in tracks) foreach (Track track in tracks)
{ {
track.EpisodeID = episode.ID; track.EpisodeID = episode.ID;
libraryManager.RegisterTrack(track); _libraryManager.RegisterTrack(track);
} }
return "Done. " + tracks.Length + " track(s) extracted."; return "Done. " + tracks.Length + " track(s) extracted.";
@ -65,16 +66,16 @@ namespace Kyoo.Controllers
[HttpGet("extract/{showSlug}")] [HttpGet("extract/{showSlug}")]
public async Task<string> ExtractSubtitle(string showSlug) public async Task<string> ExtractSubtitle(string showSlug)
{ {
IEnumerable<Episode> episodes = libraryManager.GetEpisodes(showSlug); IEnumerable<Episode> episodes = _libraryManager.GetEpisodes(showSlug);
foreach (Episode episode in episodes) foreach (Episode episode in episodes)
{ {
libraryManager.ClearSubtitles(episode.ID); _libraryManager.ClearSubtitles(episode.ID);
Track[] tracks = await transcoder.ExtractSubtitles(episode.Path); Track[] tracks = await _transcoder.ExtractSubtitles(episode.Path);
foreach (Track track in tracks) foreach (Track track in tracks)
{ {
track.EpisodeID = episode.ID; track.EpisodeID = episode.ID;
libraryManager.RegisterTrack(track); _libraryManager.RegisterTrack(track);
} }
} }
@ -85,11 +86,11 @@ namespace Kyoo.Controllers
public class ConvertSubripToVtt : IActionResult public class ConvertSubripToVtt : IActionResult
{ {
private readonly string path; private readonly string _path;
public ConvertSubripToVtt(string subtitlePath) public ConvertSubripToVtt(string subtitlePath)
{ {
path = subtitlePath; _path = subtitlePath;
} }
public async Task ExecuteResultAsync(ActionContext context) public async Task ExecuteResultAsync(ActionContext context)
@ -100,13 +101,13 @@ namespace Kyoo.Controllers
context.HttpContext.Response.StatusCode = 200; context.HttpContext.Response.StatusCode = 200;
context.HttpContext.Response.Headers.Add("Content-Type", "text/vtt"); context.HttpContext.Response.Headers.Add("Content-Type", "text/vtt");
using (StreamWriter writer = new StreamWriter(context.HttpContext.Response.Body)) await using (StreamWriter writer = new StreamWriter(context.HttpContext.Response.Body))
{ {
await writer.WriteLineAsync("WEBVTT"); await writer.WriteLineAsync("WEBVTT");
await writer.WriteLineAsync(""); await writer.WriteLineAsync("");
await writer.WriteLineAsync(""); await writer.WriteLineAsync("");
using (StreamReader reader = new StreamReader(path)) using (StreamReader reader = new StreamReader(_path))
{ {
while ((line = await reader.ReadLineAsync()) != null) while ((line = await reader.ReadLineAsync()) != null)
{ {
@ -127,7 +128,7 @@ namespace Kyoo.Controllers
await context.HttpContext.Response.Body.FlushAsync(); await context.HttpContext.Response.Body.FlushAsync();
} }
public List<string> ConvertBlock(List<string> lines) private static List<string> ConvertBlock(List<string> lines)
{ {
lines[1] = lines[1].Replace(',', '.'); lines[1] = lines[1].Replace(',', '.');
if (lines[2].Length > 5) if (lines[2].Length > 5)

View File

@ -1,25 +1,26 @@
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Configuration;
using System.IO; using System.IO;
using Kyoo.Controllers;
namespace Kyoo.Controllers namespace Kyoo.Api
{ {
public class ThumbnailController : ControllerBase public class ThumbnailController : ControllerBase
{ {
private readonly ILibraryManager libraryManager; private readonly ILibraryManager _libraryManager;
private readonly string peoplePath; private readonly string _peoplePath;
public ThumbnailController(ILibraryManager libraryManager, IConfiguration config) public ThumbnailController(ILibraryManager libraryManager, IConfiguration config)
{ {
this.libraryManager = libraryManager; _libraryManager = libraryManager;
peoplePath = config.GetValue<string>("peoplePath"); _peoplePath = config.GetValue<string>("peoplePath");
} }
[HttpGet("poster/{showSlug}")] [HttpGet("poster/{showSlug}")]
public IActionResult GetShowThumb(string showSlug) public IActionResult GetShowThumb(string showSlug)
{ {
string path = libraryManager.GetShowBySlug(showSlug)?.Path; string path = _libraryManager.GetShowBySlug(showSlug)?.Path;
if (path == null) if (path == null)
return NotFound(); return NotFound();
@ -27,14 +28,13 @@ namespace Kyoo.Controllers
if (System.IO.File.Exists(thumb)) if (System.IO.File.Exists(thumb))
return new PhysicalFileResult(thumb, "image/jpg"); return new PhysicalFileResult(thumb, "image/jpg");
else return NotFound();
return NotFound();
} }
[HttpGet("logo/{showSlug}")] [HttpGet("logo/{showSlug}")]
public IActionResult GetShowLogo(string showSlug) public IActionResult GetShowLogo(string showSlug)
{ {
string path = libraryManager.GetShowBySlug(showSlug)?.Path; string path = _libraryManager.GetShowBySlug(showSlug)?.Path;
if (path == null) if (path == null)
return NotFound(); return NotFound();
@ -42,14 +42,13 @@ namespace Kyoo.Controllers
if (System.IO.File.Exists(thumb)) if (System.IO.File.Exists(thumb))
return new PhysicalFileResult(thumb, "image/jpg"); return new PhysicalFileResult(thumb, "image/jpg");
else return NotFound();
return NotFound();
} }
[HttpGet("backdrop/{showSlug}")] [HttpGet("backdrop/{showSlug}")]
public IActionResult GetShowBackdrop(string showSlug) public IActionResult GetShowBackdrop(string showSlug)
{ {
string path = libraryManager.GetShowBySlug(showSlug)?.Path; string path = _libraryManager.GetShowBySlug(showSlug)?.Path;
if (path == null) if (path == null)
return NotFound(); return NotFound();
@ -57,14 +56,13 @@ namespace Kyoo.Controllers
if (System.IO.File.Exists(thumb)) if (System.IO.File.Exists(thumb))
return new PhysicalFileResult(thumb, "image/jpg"); return new PhysicalFileResult(thumb, "image/jpg");
else return NotFound();
return NotFound();
} }
[HttpGet("peopleimg/{peopleSlug}")] [HttpGet("peopleimg/{peopleSlug}")]
public IActionResult GetPeopleIcon(string peopleSlug) public IActionResult GetPeopleIcon(string peopleSlug)
{ {
string thumbPath = Path.Combine(peoplePath, peopleSlug + ".jpg"); string thumbPath = Path.Combine(_peoplePath, peopleSlug + ".jpg");
if (!System.IO.File.Exists(thumbPath)) if (!System.IO.File.Exists(thumbPath))
return NotFound(); return NotFound();
@ -74,7 +72,7 @@ namespace Kyoo.Controllers
[HttpGet("thumb/{showSlug}-s{seasonNumber}e{episodeNumber}")] [HttpGet("thumb/{showSlug}-s{seasonNumber}e{episodeNumber}")]
public IActionResult GetEpisodeThumb(string showSlug, long seasonNumber, long episodeNumber) public IActionResult GetEpisodeThumb(string showSlug, long seasonNumber, long episodeNumber)
{ {
string path = libraryManager.GetEpisode(showSlug, seasonNumber, episodeNumber)?.Path; string path = _libraryManager.GetEpisode(showSlug, seasonNumber, episodeNumber)?.Path;
if (path == null) if (path == null)
return NotFound(); return NotFound();

View File

@ -5,55 +5,50 @@ using Microsoft.Extensions.Configuration;
using System.IO; using System.IO;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace Kyoo.Controllers namespace Kyoo.Api
{ {
[Route("[controller]")] [Route("[controller]")]
[ApiController] [ApiController]
public class VideoController : ControllerBase public class VideoController : ControllerBase
{ {
private readonly ILibraryManager libraryManager; private readonly ILibraryManager _libraryManager;
private readonly ITranscoder transcoder; private readonly ITranscoder _transcoder;
private readonly string transmuxPath; private readonly string _transmuxPath;
public VideoController(ILibraryManager libraryManager, ITranscoder transcoder, IConfiguration config) public VideoController(ILibraryManager libraryManager, ITranscoder transcoder, IConfiguration config)
{ {
this.libraryManager = libraryManager; _libraryManager = libraryManager;
this.transcoder = transcoder; _transcoder = transcoder;
transmuxPath = config.GetValue<string>("transmuxTempPath"); _transmuxPath = config.GetValue<string>("transmuxTempPath");
} }
[HttpGet("{showSlug}-s{seasonNumber}e{episodeNumber}")] [HttpGet("{showSlug}-s{seasonNumber}e{episodeNumber}")]
public IActionResult Index(string showSlug, long seasonNumber, long episodeNumber) public IActionResult Index(string showSlug, long seasonNumber, long episodeNumber)
{ {
WatchItem episode = libraryManager.GetWatchItem(showSlug, seasonNumber, episodeNumber); WatchItem episode = _libraryManager.GetWatchItem(showSlug, seasonNumber, episodeNumber);
if (episode != null && System.IO.File.Exists(episode.Path)) if (episode != null && System.IO.File.Exists(episode.Path))
return PhysicalFile(episode.Path, "video/x-matroska", true); return PhysicalFile(episode.Path, "video/x-matroska", true);
else return NotFound();
return NotFound();
} }
[HttpGet("transmux/{showSlug}-s{seasonNumber}e{episodeNumber}")] [HttpGet("transmux/{showSlug}-s{seasonNumber}e{episodeNumber}")]
public async Task<IActionResult> Transmux(string showSlug, long seasonNumber, long episodeNumber) public async Task<IActionResult> Transmux(string showSlug, long seasonNumber, long episodeNumber)
{ {
WatchItem episode = libraryManager.GetWatchItem(showSlug, seasonNumber, episodeNumber); WatchItem episode = _libraryManager.GetWatchItem(showSlug, seasonNumber, episodeNumber);
if (episode != null && System.IO.File.Exists(episode.Path)) if (episode == null || !System.IO.File.Exists(episode.Path))
{ return NotFound();
string path = await transcoder.Transmux(episode); string path = await _transcoder.Transmux(episode);
if (path != null) if (path != null)
return PhysicalFile(path, "application/x-mpegURL ", true); return PhysicalFile(path, "application/x-mpegURL ", true);
else return StatusCode(500);
return StatusCode(500);
}
else
return NotFound();
} }
[HttpGet("transmux/{episodeLink}/segment/{chunk}")] [HttpGet("transmux/{episodeLink}/segment/{chunk}")]
public IActionResult GetTransmuxedChunk(string episodeLink, string chunk) public IActionResult GetTransmuxedChunk(string episodeLink, string chunk)
{ {
string path = Path.Combine(transmuxPath, episodeLink); string path = Path.Combine(_transmuxPath, episodeLink);
path = Path.Combine(path, "segments" + Path.DirectorySeparatorChar + chunk); path = Path.Combine(path, "segments" + Path.DirectorySeparatorChar + chunk);
return PhysicalFile(path, "video/MP2T"); return PhysicalFile(path, "video/MP2T");
@ -62,18 +57,14 @@ namespace Kyoo.Controllers
[HttpGet("transcode/{showSlug}-s{seasonNumber}e{episodeNumber}")] [HttpGet("transcode/{showSlug}-s{seasonNumber}e{episodeNumber}")]
public async Task<IActionResult> Transcode(string showSlug, long seasonNumber, long episodeNumber) public async Task<IActionResult> Transcode(string showSlug, long seasonNumber, long episodeNumber)
{ {
WatchItem episode = libraryManager.GetWatchItem(showSlug, seasonNumber, episodeNumber); WatchItem episode = _libraryManager.GetWatchItem(showSlug, seasonNumber, episodeNumber);
if (episode != null && System.IO.File.Exists(episode.Path)) if (episode == null || !System.IO.File.Exists(episode.Path))
{ return NotFound();
string path = await transcoder.Transcode(episode); string path = await _transcoder.Transcode(episode);
if (path != null) if (path != null)
return PhysicalFile(path, "application/x-mpegURL ", true); return PhysicalFile(path, "application/x-mpegURL ", true);
else return StatusCode(500);
return StatusCode(500);
}
else
return NotFound();
} }
} }
} }

View File

@ -1,27 +1,24 @@
using Kyoo.Controllers; using Kyoo.Controllers;
using Kyoo.Models; using Kyoo.Models;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using System.Diagnostics;
// For more information on enabling MVC for empty projects, visit https://go.microsoft.com/fwlink/?LinkID=397860 namespace Kyoo.Api
namespace Kyoo.Controllers
{ {
[Route("api/[controller]")] [Route("api/[controller]")]
[ApiController] [ApiController]
public class WatchController : ControllerBase public class WatchController : ControllerBase
{ {
private readonly ILibraryManager libraryManager; private readonly ILibraryManager _libraryManager;
public WatchController(ILibraryManager libraryManager) public WatchController(ILibraryManager libraryManager)
{ {
this.libraryManager = libraryManager; _libraryManager = libraryManager;
} }
[HttpGet("{showSlug}-s{seasonNumber}e{episodeNumber}")] [HttpGet("{showSlug}-s{seasonNumber}e{episodeNumber}")]
public ActionResult<WatchItem> Index(string showSlug, long seasonNumber, long episodeNumber) public ActionResult<WatchItem> Index(string showSlug, long seasonNumber, long episodeNumber)
{ {
WatchItem item = libraryManager.GetWatchItem(showSlug, seasonNumber, episodeNumber); WatchItem item = _libraryManager.GetWatchItem(showSlug, seasonNumber, episodeNumber);
if(item == null) if(item == null)
return NotFound(); return NotFound();

View File

@ -19,7 +19,6 @@
<ItemGroup> <ItemGroup>
<PackageReference Include="IdentityServer4" Version="3.0.2" /> <PackageReference Include="IdentityServer4" Version="3.0.2" />
<PackageReference Include="IdentityServer4.AspNetIdentity" Version="3.0.2" /> <PackageReference Include="IdentityServer4.AspNetIdentity" Version="3.0.2" />
<PackageReference Include="Microsoft.AspNet.WebApi.Client" Version="5.2.7" />
<PackageReference Include="Microsoft.AspNetCore.Authentication.OpenIdConnect" Version="3.0.2" /> <PackageReference Include="Microsoft.AspNetCore.Authentication.OpenIdConnect" Version="3.0.2" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="3.0.0" /> <PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="3.0.0" />
<PackageReference Include="Microsoft.AspNetCore.SpaServices" Version="3.0.0" /> <PackageReference Include="Microsoft.AspNetCore.SpaServices" Version="3.0.0" />