mirror of
https://github.com/zoriya/Kyoo.git
synced 2025-07-07 10:14:13 -04:00
Placing fonts on the episode directory, removing in show extras
This commit is contained in:
parent
22c600bd09
commit
a71c22db92
63
src/Kyoo.Abstractions/Controllers/ITranscoder.cs
Normal file
63
src/Kyoo.Abstractions/Controllers/ITranscoder.cs
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
// Kyoo - A portable and vast media library solution.
|
||||||
|
// Copyright (c) Kyoo.
|
||||||
|
//
|
||||||
|
// See AUTHORS.md and LICENSE file in the project root for full license information.
|
||||||
|
//
|
||||||
|
// Kyoo is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// any later version.
|
||||||
|
//
|
||||||
|
// Kyoo is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with Kyoo. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using JetBrains.Annotations;
|
||||||
|
using Kyoo.Abstractions.Models;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
|
||||||
|
namespace Kyoo.Abstractions.Controllers
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Transcoder responsible of handling low level video details.
|
||||||
|
/// </summary>
|
||||||
|
public interface ITranscoder
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Retrieve tracks for a specific episode.
|
||||||
|
/// Subtitles, chapters and fonts should also be extracted and cached when calling this method.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="episode">The episode to retrieve tracks for.</param>
|
||||||
|
/// <param name="reExtract">Should the cache be invalidated and subtitles and others be re-extracted?</param>
|
||||||
|
/// <returns>The list of tracks available for this episode.</returns>
|
||||||
|
Task<ICollection<Track>> ExtractInfos(Episode episode, bool reExtract);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// List fonts assosiated with this episode.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="episode">Th episode to list fonts for.</param>
|
||||||
|
/// <returns>The list of attachements for this epiosode.</returns>
|
||||||
|
Task<ICollection<Font>> ListFonts(Episode episode);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Get the specified font for this episode.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="episode">The episode to list fonts for.</param>
|
||||||
|
/// <param name="slug">The slug of the specific font to retrive.</param>
|
||||||
|
/// <returns>The <see cref="Font"/> with the given slug or null.</returns>
|
||||||
|
[ItemCanBeNull] Task<Font> GetFont(Episode episode, string slug);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Transmux the selected episode to hls.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="episode">The episode to transmux.</param>
|
||||||
|
/// <returns>The master file (m3u8) of the transmuxed hls file.</returns>
|
||||||
|
IActionResult Transmux(Episode episode);
|
||||||
|
}
|
||||||
|
}
|
67
src/Kyoo.Abstractions/Models/Font.cs
Normal file
67
src/Kyoo.Abstractions/Models/Font.cs
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
// Kyoo - A portable and vast media library solution.
|
||||||
|
// Copyright (c) Kyoo.
|
||||||
|
//
|
||||||
|
// See AUTHORS.md and LICENSE file in the project root for full license information.
|
||||||
|
//
|
||||||
|
// Kyoo is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// any later version.
|
||||||
|
//
|
||||||
|
// Kyoo is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with Kyoo. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
using Kyoo.Abstractions.Models.Attributes;
|
||||||
|
using Kyoo.Utils;
|
||||||
|
using PathIO = System.IO.Path;
|
||||||
|
|
||||||
|
namespace Kyoo.Abstractions.Models
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// A font of an <see cref="Episode"/>.
|
||||||
|
/// </summary>
|
||||||
|
public class Font
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// A human-readable identifier, used in the URL.
|
||||||
|
/// </summary>
|
||||||
|
public string Slug { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The name of the font file (with the extension).
|
||||||
|
/// </summary>
|
||||||
|
public string File { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The format of this font (the extension).
|
||||||
|
/// </summary>
|
||||||
|
public string Format { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The path of the font.
|
||||||
|
/// </summary>
|
||||||
|
[SerializeIgnore] public string Path { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Create a new empty <see cref="Font"/>.
|
||||||
|
/// </summary>
|
||||||
|
public Font() { }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Create a new <see cref="Font"/> from a path.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="path">The path of the font.</param>
|
||||||
|
public Font(string path)
|
||||||
|
{
|
||||||
|
Slug = Utility.ToSlug(PathIO.GetFileNameWithoutExtension(path));
|
||||||
|
Path = path;
|
||||||
|
File = PathIO.GetFileName(path);
|
||||||
|
Format = PathIO.GetExtension(path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -50,12 +50,6 @@ namespace Kyoo.Abstractions.Models
|
|||||||
/// The stream is a subtitle.
|
/// The stream is a subtitle.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
Subtitle = 3,
|
Subtitle = 3,
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The stream is an attachment (a font, an image or something else).
|
|
||||||
/// Only fonts are handled by kyoo but they are not saved to the database.
|
|
||||||
/// </summary>
|
|
||||||
Attachment = 4
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -153,17 +153,12 @@ namespace Kyoo.Core.Controllers
|
|||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public Task<string> GetExtraDirectory<T>(T resource)
|
public Task<string> GetExtraDirectory<T>(T resource)
|
||||||
{
|
{
|
||||||
if (!_options.CurrentValue.MetadataInShow)
|
string path = resource switch
|
||||||
return Task.FromResult<string>(null);
|
|
||||||
return Task.FromResult(resource switch
|
|
||||||
{
|
{
|
||||||
Show show => Combine(show.Path, "Extra"),
|
IResource res => Combine(_options.CurrentValue.MetadataPath, typeof(T).Name.ToLower(), res.Slug),
|
||||||
Season season => Combine(season.Show.Path, "Extra"),
|
_ => Combine(_options.CurrentValue.MetadataPath, typeof(T).Name.ToLower())
|
||||||
// TODO: extras should not be on the same directory for every episodes/seasons/tracks. If this is fixed, fonts handling will break.
|
};
|
||||||
Episode episode => Combine(episode.Show.Path, "Extra"),
|
return CreateDirectory(path);
|
||||||
Track track => Combine(track.Episode.Show.Path, "Extra"),
|
|
||||||
_ => null
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
|
@ -25,8 +25,8 @@ using System.Threading.Tasks;
|
|||||||
using Kyoo.Abstractions.Controllers;
|
using Kyoo.Abstractions.Controllers;
|
||||||
using Kyoo.Abstractions.Models;
|
using Kyoo.Abstractions.Models;
|
||||||
using Kyoo.Abstractions.Models.Exceptions;
|
using Kyoo.Abstractions.Models.Exceptions;
|
||||||
|
using Kyoo.Core.Models;
|
||||||
using Kyoo.Core.Models.Options;
|
using Kyoo.Core.Models.Options;
|
||||||
using Kyoo.Core.Models.Watch;
|
|
||||||
using Kyoo.Utils;
|
using Kyoo.Utils;
|
||||||
using Microsoft.Extensions.Options;
|
using Microsoft.Extensions.Options;
|
||||||
|
|
||||||
|
@ -129,18 +129,6 @@ namespace Kyoo.Core.Controllers
|
|||||||
Images.Trailer => "trailer",
|
Images.Trailer => "trailer",
|
||||||
_ => $"{imageID}"
|
_ => $"{imageID}"
|
||||||
};
|
};
|
||||||
|
|
||||||
switch (item)
|
|
||||||
{
|
|
||||||
case Season season:
|
|
||||||
imageName = $"season-{season.SeasonNumber}-{imageName}";
|
|
||||||
break;
|
|
||||||
case Episode episode:
|
|
||||||
directory = await _files.CreateDirectory(_files.Combine(directory, "Thumbnails"));
|
|
||||||
imageName = $"{Path.GetFileNameWithoutExtension(episode.Path)}-{imageName}";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return _files.Combine(directory, imageName);
|
return _files.Combine(directory, imageName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -19,11 +19,14 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Kyoo.Abstractions.Controllers;
|
using Kyoo.Abstractions.Controllers;
|
||||||
using Kyoo.Abstractions.Models;
|
using Kyoo.Abstractions.Models;
|
||||||
using Kyoo.Core.Models.Options;
|
using Kyoo.Core.Models.Options;
|
||||||
|
using Kyoo.Core.Models.Watch;
|
||||||
|
using Kyoo.Utils;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using Microsoft.Extensions.Options;
|
using Microsoft.Extensions.Options;
|
||||||
@ -48,16 +51,16 @@ namespace Kyoo.Core.Controllers
|
|||||||
private const string TranscoderPath = "transcoder";
|
private const string TranscoderPath = "transcoder";
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initialize the C library, setup the logger and return the size of a <see cref="Models.Watch.Stream"/>.
|
/// Initialize the C library, setup the logger and return the size of a <see cref="FTrack"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>The size of a <see cref="Models.Watch.Stream"/></returns>
|
/// <returns>The size of a <see cref="FTrack"/></returns>
|
||||||
[DllImport(TranscoderPath, CallingConvention = CallingConvention.Cdecl)]
|
[DllImport(TranscoderPath, CallingConvention = CallingConvention.Cdecl)]
|
||||||
private static extern int init();
|
private static extern int init();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initialize the C library, setup the logger and return the size of a <see cref="Models.Watch.Stream"/>.
|
/// Initialize the C library, setup the logger and return the size of a <see cref="FTrack"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>The size of a <see cref="Models.Watch.Stream"/></returns>
|
/// <returns>The size of a <see cref="FTrack"/></returns>
|
||||||
public static int Init() => init();
|
public static int Init() => init();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -99,7 +102,7 @@ namespace Kyoo.Core.Controllers
|
|||||||
/// <param name="length">The size of the returned array.</param>
|
/// <param name="length">The size of the returned array.</param>
|
||||||
/// <param name="trackCount">The number of tracks in the returned array.</param>
|
/// <param name="trackCount">The number of tracks in the returned array.</param>
|
||||||
/// <param name="reExtract">Should the cache be invalidated and information re-extracted or not?</param>
|
/// <param name="reExtract">Should the cache be invalidated and information re-extracted or not?</param>
|
||||||
/// <returns>A pointer to an array of <see cref="Models.Watch.Stream"/></returns>
|
/// <returns>A pointer to an array of <see cref="FTrack"/></returns>
|
||||||
[DllImport(TranscoderPath, CallingConvention = CallingConvention.Cdecl,
|
[DllImport(TranscoderPath, CallingConvention = CallingConvention.Cdecl,
|
||||||
CharSet = CharSet.Ansi, BestFitMapping = false, ThrowOnUnmappableChar = true)]
|
CharSet = CharSet.Ansi, BestFitMapping = false, ThrowOnUnmappableChar = true)]
|
||||||
private static extern IntPtr extract_infos(string path,
|
private static extern IntPtr extract_infos(string path,
|
||||||
@ -109,7 +112,7 @@ namespace Kyoo.Core.Controllers
|
|||||||
bool reExtract);
|
bool reExtract);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// An helper method to free an array of <see cref="Models.Watch.Stream"/>.
|
/// An helper method to free an array of <see cref="FTrack"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="streams">A pointer to the first element of the array</param>
|
/// <param name="streams">A pointer to the first element of the array</param>
|
||||||
/// <param name="count">The number of items in the array.</param>
|
/// <param name="count">The number of items in the array.</param>
|
||||||
@ -128,7 +131,7 @@ namespace Kyoo.Core.Controllers
|
|||||||
path = path.Replace('\\', '/');
|
path = path.Replace('\\', '/');
|
||||||
outPath = outPath.Replace('\\', '/');
|
outPath = outPath.Replace('\\', '/');
|
||||||
|
|
||||||
int size = Marshal.SizeOf<Models.Watch.Stream>();
|
int size = Marshal.SizeOf<FTrack>();
|
||||||
IntPtr ptr = extract_infos(path, outPath, out uint arrayLength, out uint trackCount, reExtract);
|
IntPtr ptr = extract_infos(path, outPath, out uint arrayLength, out uint trackCount, reExtract);
|
||||||
IntPtr streamsPtr = ptr;
|
IntPtr streamsPtr = ptr;
|
||||||
Track[] tracks;
|
Track[] tracks;
|
||||||
@ -140,8 +143,8 @@ namespace Kyoo.Core.Controllers
|
|||||||
int j = 0;
|
int j = 0;
|
||||||
for (int i = 0; i < arrayLength; i++)
|
for (int i = 0; i < arrayLength; i++)
|
||||||
{
|
{
|
||||||
Models.Watch.Stream stream = Marshal.PtrToStructure<Models.Watch.Stream>(streamsPtr);
|
FTrack stream = Marshal.PtrToStructure<FTrack>(streamsPtr);
|
||||||
if (stream!.Type != StreamType.Unknown)
|
if (stream!.Type != FTrackType.Unknown && stream.Type != FTrackType.Attachment)
|
||||||
{
|
{
|
||||||
tracks[j] = stream.ToTrack();
|
tracks[j] = stream.ToTrack();
|
||||||
j++;
|
j++;
|
||||||
@ -188,7 +191,7 @@ namespace Kyoo.Core.Controllers
|
|||||||
_options = options;
|
_options = options;
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
|
|
||||||
if (TranscoderAPI.Init() != Marshal.SizeOf<Models.Watch.Stream>())
|
if (TranscoderAPI.Init() != Marshal.SizeOf<FTrack>())
|
||||||
_logger.LogCritical("The transcoder library could not be initialized correctly");
|
_logger.LogCritical("The transcoder library could not be initialized correctly");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -204,6 +207,26 @@ namespace Kyoo.Core.Controllers
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public async Task<ICollection<Font>> ListFonts(Episode episode)
|
||||||
|
{
|
||||||
|
string path = _files.Combine(await _files.GetExtraDirectory(episode), "Attachments");
|
||||||
|
return (await _files.ListFiles(path))
|
||||||
|
.Select(x => new Font(x))
|
||||||
|
.ToArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public async Task<Font> GetFont(Episode episode, string slug)
|
||||||
|
{
|
||||||
|
string path = _files.Combine(await _files.GetExtraDirectory(episode), "Attachments");
|
||||||
|
string font = (await _files.ListFiles(path))
|
||||||
|
.FirstOrDefault(x => Utility.ToSlug(Path.GetFileName(x)) == slug);
|
||||||
|
if (font == null)
|
||||||
|
return null;
|
||||||
|
return new Font(path);
|
||||||
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public IActionResult Transmux(Episode episode)
|
public IActionResult Transmux(Episode episode)
|
||||||
{
|
{
|
||||||
@ -293,27 +316,4 @@ namespace Kyoo.Core.Controllers
|
|||||||
#pragma warning restore 4014
|
#pragma warning restore 4014
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The transcoder used by the <see cref="LocalFileSystem"/>. This is on a different interface than the file system
|
|
||||||
/// to offset the work.
|
|
||||||
/// </summary>
|
|
||||||
public interface ITranscoder
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Retrieve tracks for a specific episode.
|
|
||||||
/// Subtitles, chapters and fonts should also be extracted and cached when calling this method.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="episode">The episode to retrieve tracks for.</param>
|
|
||||||
/// <param name="reExtract">Should the cache be invalidated and subtitles and others be re-extracted?</param>
|
|
||||||
/// <returns>The list of tracks available for this episode.</returns>
|
|
||||||
Task<ICollection<Track>> ExtractInfos(Episode episode, bool reExtract);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Transmux the selected episode to hls.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="episode">The episode to transmux.</param>
|
|
||||||
/// <returns>The master file (m3u8) of the transmuxed hls file.</returns>
|
|
||||||
IActionResult Transmux(Episode episode);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -21,11 +21,45 @@ using Kyoo.Abstractions.Models;
|
|||||||
|
|
||||||
namespace Kyoo.Core.Models.Watch
|
namespace Kyoo.Core.Models.Watch
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// The list of available stream types.
|
||||||
|
/// Attachments are only used temporarily by the transcoder but are not stored in a database.
|
||||||
|
/// This is another <see cref="StreamType"/> enum used internally to communicate with ffmpeg.
|
||||||
|
/// </summary>
|
||||||
|
public enum FTrackType
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// The type of the stream is not known.
|
||||||
|
/// </summary>
|
||||||
|
Unknown = StreamType.Unknown,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The stream is a video.
|
||||||
|
/// </summary>
|
||||||
|
Video = StreamType.Video,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The stream is an audio.
|
||||||
|
/// </summary>
|
||||||
|
Audio = StreamType.Audio,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The stream is a subtitle.
|
||||||
|
/// </summary>
|
||||||
|
Subtitle = StreamType.Subtitle,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The stream is an attachment (a font, an image or something else).
|
||||||
|
/// Only fonts are handled by kyoo but they are not saved to the database.
|
||||||
|
/// </summary>
|
||||||
|
Attachment
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The unmanaged stream that the transcoder will return.
|
/// The unmanaged stream that the transcoder will return.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
|
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
|
||||||
public struct Stream
|
public struct FTrack
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The title of the stream.
|
/// The title of the stream.
|
||||||
@ -60,7 +94,7 @@ namespace Kyoo.Core.Models.Watch
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// The type of this stream.
|
/// The type of this stream.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public StreamType Type;
|
public FTrackType Type;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Create a track from this stream.
|
/// Create a track from this stream.
|
||||||
@ -76,7 +110,7 @@ namespace Kyoo.Core.Models.Watch
|
|||||||
IsDefault = IsDefault,
|
IsDefault = IsDefault,
|
||||||
IsForced = IsForced,
|
IsForced = IsForced,
|
||||||
Path = Path,
|
Path = Path,
|
||||||
Type = Type,
|
Type = Type < FTrackType.Attachment ? (StreamType)Type : StreamType.Unknown,
|
||||||
IsExternal = false
|
IsExternal = false
|
||||||
};
|
};
|
||||||
}
|
}
|
@ -20,7 +20,7 @@ using System.Collections.Generic;
|
|||||||
using System.Collections.Immutable;
|
using System.Collections.Immutable;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
|
||||||
namespace Kyoo.Core.Models.Watch
|
namespace Kyoo.Core.Models
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// A static class allowing one to identify files extensions.
|
/// A static class allowing one to identify files extensions.
|
||||||
|
@ -25,7 +25,7 @@ using System.Threading.Tasks;
|
|||||||
using Kyoo.Abstractions.Controllers;
|
using Kyoo.Abstractions.Controllers;
|
||||||
using Kyoo.Abstractions.Models;
|
using Kyoo.Abstractions.Models;
|
||||||
using Kyoo.Abstractions.Models.Attributes;
|
using Kyoo.Abstractions.Models.Attributes;
|
||||||
using Kyoo.Core.Models.Watch;
|
using Kyoo.Core.Models;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
|
|
||||||
namespace Kyoo.Core.Tasks
|
namespace Kyoo.Core.Tasks
|
||||||
|
@ -150,9 +150,7 @@ namespace Kyoo.Core.Tasks
|
|||||||
if (!show.IsMovie)
|
if (!show.IsMovie)
|
||||||
episode = await _metadataProvider.Get(episode);
|
episode = await _metadataProvider.Get(episode);
|
||||||
progress.Report(70);
|
progress.Report(70);
|
||||||
episode.Tracks = (await _transcoder.ExtractInfos(episode, false))
|
episode.Tracks = await _transcoder.ExtractInfos(episode, false);
|
||||||
.Where(x => x.Type != StreamType.Attachment)
|
|
||||||
.ToArray();
|
|
||||||
await _thumbnailsManager.DownloadImages(episode);
|
await _thumbnailsManager.DownloadImages(episode);
|
||||||
progress.Report(90);
|
progress.Report(90);
|
||||||
|
|
||||||
|
@ -47,20 +47,34 @@ namespace Kyoo.Core.Api
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
private readonly ILibraryManager _libraryManager;
|
private readonly ILibraryManager _libraryManager;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The transcoder used to retrive fonts.
|
||||||
|
/// </summary>
|
||||||
|
private readonly ITranscoder _transcoder;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The file system used to send fonts.
|
||||||
|
/// </summary>
|
||||||
|
private readonly IFileSystem _files;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Create a new <see cref="EpisodeApi"/>.
|
/// Create a new <see cref="EpisodeApi"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="libraryManager">
|
/// <param name="libraryManager">
|
||||||
/// The library manager used to modify or retrieve information in the data store.
|
/// The library manager used to modify or retrieve information in the data store.
|
||||||
/// </param>
|
/// </param>
|
||||||
|
/// <param name="transcoder">The transcoder used to retrive fonts</param>
|
||||||
/// <param name="files">The file manager used to send images.</param>
|
/// <param name="files">The file manager used to send images.</param>
|
||||||
/// <param name="thumbnails">The thumbnail manager used to retrieve images paths.</param>
|
/// <param name="thumbnails">The thumbnail manager used to retrieve images paths.</param>
|
||||||
public EpisodeApi(ILibraryManager libraryManager,
|
public EpisodeApi(ILibraryManager libraryManager,
|
||||||
|
ITranscoder transcoder,
|
||||||
IFileSystem files,
|
IFileSystem files,
|
||||||
IThumbnailsManager thumbnails)
|
IThumbnailsManager thumbnails)
|
||||||
: base(libraryManager.EpisodeRepository, files, thumbnails)
|
: base(libraryManager.EpisodeRepository, files, thumbnails)
|
||||||
{
|
{
|
||||||
_libraryManager = libraryManager;
|
_libraryManager = libraryManager;
|
||||||
|
_transcoder = transcoder;
|
||||||
|
_files = files;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -158,5 +172,58 @@ namespace Kyoo.Core.Api
|
|||||||
return BadRequest(new RequestError(ex.Message));
|
return BadRequest(new RequestError(ex.Message));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// List fonts
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// List available fonts for this episode.
|
||||||
|
/// </remarks>
|
||||||
|
/// <param name="identifier">The ID or slug of the <see cref="Episode"/>.</param>
|
||||||
|
/// <returns>An object containing the name of the font followed by the url to retrieve it.</returns>
|
||||||
|
[HttpGet("{identifier:id}/fonts")]
|
||||||
|
[HttpGet("{identifier:id}/font", Order = AlternativeRoute)]
|
||||||
|
[PartialPermission(Kind.Read)]
|
||||||
|
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||||
|
[ProducesResponseType(StatusCodes.Status404NotFound)]
|
||||||
|
public async Task<ActionResult<ICollection<Font>>> GetFonts(Identifier identifier)
|
||||||
|
{
|
||||||
|
Episode episode = await identifier.Match(
|
||||||
|
id => _libraryManager.GetOrDefault<Episode>(id),
|
||||||
|
slug => _libraryManager.GetOrDefault<Episode>(slug)
|
||||||
|
);
|
||||||
|
if (episode == null)
|
||||||
|
return NotFound();
|
||||||
|
return Ok(await _transcoder.ListFonts(episode));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Get font
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// Get a font file that is used in subtitles of this episode.
|
||||||
|
/// </remarks>
|
||||||
|
/// <param name="identifier">The ID or slug of the <see cref="Episode"/>.</param>
|
||||||
|
/// <param name="slug">The slug of the font to retrieve.</param>
|
||||||
|
/// <returns>A page of collections.</returns>
|
||||||
|
/// <response code="404">No show with the given ID/slug could be found or the font does not exist.</response>
|
||||||
|
[HttpGet("{identifier:id}/fonts/{font}")]
|
||||||
|
[HttpGet("{identifier:id}/font/{font}", Order = AlternativeRoute)]
|
||||||
|
[PartialPermission(Kind.Read)]
|
||||||
|
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||||
|
[ProducesResponseType(StatusCodes.Status404NotFound)]
|
||||||
|
public async Task<IActionResult> GetFont(Identifier identifier, string slug)
|
||||||
|
{
|
||||||
|
Episode episode = await identifier.Match(
|
||||||
|
id => _libraryManager.GetOrDefault<Episode>(id),
|
||||||
|
slug => _libraryManager.GetOrDefault<Episode>(slug)
|
||||||
|
);
|
||||||
|
if (episode == null)
|
||||||
|
return NotFound();
|
||||||
|
Font font = await _transcoder.GetFont(episode, slug);
|
||||||
|
if (font == null)
|
||||||
|
return NotFound();
|
||||||
|
return _files.FileResult(font.Path);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -375,66 +375,5 @@ namespace Kyoo.Core.Api
|
|||||||
return BadRequest(new RequestError(ex.Message));
|
return BadRequest(new RequestError(ex.Message));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// List fonts
|
|
||||||
/// </summary>
|
|
||||||
/// <remarks>
|
|
||||||
/// List available fonts for this show.
|
|
||||||
/// </remarks>
|
|
||||||
/// <param name="identifier">The ID or slug of the <see cref="Show"/>.</param>
|
|
||||||
/// <returns>An object containing the name of the font followed by the url to retrieve it.</returns>
|
|
||||||
[HttpGet("{identifier:id}/fonts")]
|
|
||||||
[HttpGet("{identifier:id}/font", Order = AlternativeRoute)]
|
|
||||||
[PartialPermission(Kind.Read)]
|
|
||||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
|
||||||
[ProducesResponseType(StatusCodes.Status404NotFound)]
|
|
||||||
public async Task<ActionResult<Dictionary<string, string>>> GetFonts(Identifier identifier)
|
|
||||||
{
|
|
||||||
Show show = await identifier.Match(
|
|
||||||
id => _libraryManager.GetOrDefault<Show>(id),
|
|
||||||
slug => _libraryManager.GetOrDefault<Show>(slug)
|
|
||||||
);
|
|
||||||
if (show == null)
|
|
||||||
return NotFound();
|
|
||||||
string path = _files.Combine(await _files.GetExtraDirectory(show), "Attachments");
|
|
||||||
return (await _files.ListFiles(path))
|
|
||||||
.DistinctBy(Path.GetFileNameWithoutExtension)
|
|
||||||
.ToDictionary(
|
|
||||||
Path.GetFileNameWithoutExtension,
|
|
||||||
x => $"{_baseURL}api/shows/{identifier}/fonts/{Path.GetFileName(x)}"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Get font
|
|
||||||
/// </summary>
|
|
||||||
/// <remarks>
|
|
||||||
/// Get a font file that is used in subtitles of this show.
|
|
||||||
/// </remarks>
|
|
||||||
/// <param name="identifier">The ID or slug of the <see cref="Show"/>.</param>
|
|
||||||
/// <param name="font">The name of the font to retrieve (with it's file extension).</param>
|
|
||||||
/// <returns>A page of collections.</returns>
|
|
||||||
/// <response code="400">The font name is invalid.</response>
|
|
||||||
/// <response code="404">No show with the given ID/slug could be found or the font does not exist.</response>
|
|
||||||
[HttpGet("{identifier:id}/fonts/{font}")]
|
|
||||||
[HttpGet("{identifier:id}/font/{font}", Order = AlternativeRoute)]
|
|
||||||
[PartialPermission(Kind.Read)]
|
|
||||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
|
||||||
[ProducesResponseType(StatusCodes.Status400BadRequest, Type = typeof(RequestError))]
|
|
||||||
[ProducesResponseType(StatusCodes.Status404NotFound)]
|
|
||||||
public async Task<IActionResult> GetFont(Identifier identifier, string font)
|
|
||||||
{
|
|
||||||
if (font.Contains('/') || font.Contains('\\'))
|
|
||||||
return BadRequest(new RequestError("Invalid font name."));
|
|
||||||
Show show = await identifier.Match(
|
|
||||||
id => _libraryManager.GetOrDefault<Show>(id),
|
|
||||||
slug => _libraryManager.GetOrDefault<Show>(slug)
|
|
||||||
);
|
|
||||||
if (show == null)
|
|
||||||
return NotFound();
|
|
||||||
string path = _files.Combine(await _files.GetExtraDirectory(show), "Attachments", font);
|
|
||||||
return _files.FileResult(path);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -44,12 +44,6 @@ namespace Kyoo.Host.Generic.Controllers
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
private readonly ICollection<Meta<Func<IFileSystem>, FileSystemMetadataAttribute>> _fileSystems;
|
private readonly ICollection<Meta<Func<IFileSystem>, FileSystemMetadataAttribute>> _fileSystems;
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The library manager used to load shows to retrieve their path
|
|
||||||
/// (only if the option is set to metadata in show)
|
|
||||||
/// </summary>
|
|
||||||
private readonly ILibraryManager _libraryManager;
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Options to check if the metadata should be kept in the show directory or in a kyoo's directory.
|
/// Options to check if the metadata should be kept in the show directory or in a kyoo's directory.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -60,14 +54,11 @@ namespace Kyoo.Host.Generic.Controllers
|
|||||||
/// metadata.
|
/// metadata.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="fileSystems">The list of filesystem mapped to their metadata.</param>
|
/// <param name="fileSystems">The list of filesystem mapped to their metadata.</param>
|
||||||
/// <param name="libraryManager">The library manager used to load shows to retrieve their path.</param>
|
|
||||||
/// <param name="options">The options to use.</param>
|
/// <param name="options">The options to use.</param>
|
||||||
public FileSystemComposite(ICollection<Meta<Func<IFileSystem>, FileSystemMetadataAttribute>> fileSystems,
|
public FileSystemComposite(ICollection<Meta<Func<IFileSystem>, FileSystemMetadataAttribute>> fileSystems,
|
||||||
ILibraryManager libraryManager,
|
|
||||||
IOptionsMonitor<BasicOptions> options)
|
IOptionsMonitor<BasicOptions> options)
|
||||||
{
|
{
|
||||||
_fileSystems = fileSystems;
|
_fileSystems = fileSystems;
|
||||||
_libraryManager = libraryManager;
|
|
||||||
_options = options;
|
_options = options;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -178,41 +169,10 @@ namespace Kyoo.Host.Generic.Controllers
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public async Task<string> GetExtraDirectory<T>(T resource)
|
public Task<string> GetExtraDirectory<T>(T resource)
|
||||||
{
|
{
|
||||||
switch (resource)
|
IFileSystem fs = _GetFileSystemForPath(_options.CurrentValue.MetadataPath, out string path);
|
||||||
{
|
return fs.GetExtraDirectory(resource);
|
||||||
case Season season:
|
|
||||||
await _libraryManager.Load(season, x => x.Show);
|
|
||||||
break;
|
|
||||||
case Episode episode:
|
|
||||||
await _libraryManager.Load(episode, x => x.Show);
|
|
||||||
break;
|
|
||||||
case Track track:
|
|
||||||
await _libraryManager.Load(track, x => x.Episode);
|
|
||||||
await _libraryManager.Load(track.Episode, x => x.Show);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
IFileSystem fs = resource switch
|
|
||||||
{
|
|
||||||
Show show => _GetFileSystemForPath(show.Path, out string _),
|
|
||||||
Season season => _GetFileSystemForPath(season.Show.Path, out string _),
|
|
||||||
Episode episode => _GetFileSystemForPath(episode.Show.Path, out string _),
|
|
||||||
Track track => _GetFileSystemForPath(track.Episode.Show.Path, out string _),
|
|
||||||
_ => _GetFileSystemForPath(_options.CurrentValue.MetadataPath, out string _)
|
|
||||||
};
|
|
||||||
string path = await fs.GetExtraDirectory(resource)
|
|
||||||
?? resource switch
|
|
||||||
{
|
|
||||||
IResource res => Combine(
|
|
||||||
_options.CurrentValue.MetadataPath,
|
|
||||||
typeof(T).Name.ToLower(),
|
|
||||||
res.Slug
|
|
||||||
),
|
|
||||||
_ => Combine(_options.CurrentValue.MetadataPath, typeof(T).Name.ToLower())
|
|
||||||
};
|
|
||||||
return await CreateDirectory(path);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
|
@ -1 +1 @@
|
|||||||
Subproject commit 7bae8def39ace7bab481efea4825c4802e9e1f31
|
Subproject commit 913c8e986e220ea48749b815593cdd10b2acb8de
|
Loading…
x
Reference in New Issue
Block a user