mirror of
https://github.com/zoriya/Kyoo.git
synced 2025-07-09 03:04:20 -04:00
Only serializing useful informations for each query. Cleaning up the rest API
This commit is contained in:
parent
aca93acc86
commit
84f8d545a6
@ -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
|
||||||
|
@ -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; }
|
||||||
|
|
||||||
|
|
||||||
|
@ -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())
|
||||||
|
@ -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]
|
||||||
|
@ -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
|
||||||
{
|
{
|
||||||
|
@ -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();
|
||||||
|
@ -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);
|
||||||
|
89
Kyoo/HtmlAPI/JsonSerializer.cs
Normal file
89
Kyoo/HtmlAPI/JsonSerializer.cs
Normal 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));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -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]
|
||||||
|
@ -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;
|
||||||
|
@ -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]
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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)
|
||||||
|
@ -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();
|
||||||
|
|
||||||
|
@ -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();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -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();
|
||||||
|
@ -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" />
|
||||||
|
Loading…
x
Reference in New Issue
Block a user