mirror of
https://github.com/zoriya/Kyoo.git
synced 2025-07-09 03:04:20 -04:00
Reworking images
This commit is contained in:
parent
2812c9cacf
commit
9777551b78
@ -23,37 +23,18 @@ namespace Kyoo.Controllers
|
|||||||
/// <typeparam name="T">The type of the item</typeparam>
|
/// <typeparam name="T">The type of the item</typeparam>
|
||||||
/// <returns><c>true</c> if an image has been downloaded, <c>false</c> otherwise.</returns>
|
/// <returns><c>true</c> if an image has been downloaded, <c>false</c> otherwise.</returns>
|
||||||
Task<bool> DownloadImages<T>([NotNull] T item, bool alwaysDownload = false)
|
Task<bool> DownloadImages<T>([NotNull] T item, bool alwaysDownload = false)
|
||||||
where T : IResource;
|
where T : IThumbnails;
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Retrieve the local path of the poster of the given item.
|
/// Retrieve the local path of the poster of the given item.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="item">The item to retrieve the poster from.</param>
|
/// <param name="item">The item to retrieve the poster from.</param>
|
||||||
|
/// <param name="imageID">The ID of the image. See <see cref="Thumbnails"/> for values.</param>
|
||||||
/// <typeparam name="T">The type of the item</typeparam>
|
/// <typeparam name="T">The type of the item</typeparam>
|
||||||
/// <exception cref="NotSupportedException">If the type does not have a poster</exception>
|
/// <exception cref="NotSupportedException">If the type does not have a poster</exception>
|
||||||
/// <returns>The path of the poster for the given resource (it might or might not exists).</returns>
|
/// <returns>The path of the poster for the given resource (it might or might not exists).</returns>
|
||||||
Task<string> GetPoster<T>([NotNull] T item)
|
Task<string> GetImagePath<T>([NotNull] T item, int imageID)
|
||||||
where T : IResource;
|
where T : IThumbnails;
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Retrieve the local path of the logo of the given item.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="item">The item to retrieve the logo from.</param>
|
|
||||||
/// <typeparam name="T">The type of the item</typeparam>
|
|
||||||
/// <exception cref="NotSupportedException">If the type does not have a logo</exception>
|
|
||||||
/// <returns>The path of the logo for the given resource (it might or might not exists).</returns>
|
|
||||||
Task<string> GetLogo<T>([NotNull] T item)
|
|
||||||
where T : IResource;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Retrieve the local path of the thumbnail of the given item.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="item">The item to retrieve the thumbnail from.</param>
|
|
||||||
/// <typeparam name="T">The type of the item</typeparam>
|
|
||||||
/// <exception cref="NotSupportedException">If the type does not have a thumbnail</exception>
|
|
||||||
/// <returns>The path of the thumbnail for the given resource (it might or might not exists).</returns>
|
|
||||||
Task<string> GetThumbnail<T>([NotNull] T item)
|
|
||||||
where T : IResource;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -8,7 +8,7 @@ namespace Kyoo.Models
|
|||||||
/// A class representing collections of <see cref="Show"/>.
|
/// A class representing collections of <see cref="Show"/>.
|
||||||
/// A collection can also be stored in a <see cref="Library"/>.
|
/// A collection can also be stored in a <see cref="Library"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class Collection : IResource, IMetadata
|
public class Collection : IResource, IMetadata, IThumbnails
|
||||||
{
|
{
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public int ID { get; set; }
|
public int ID { get; set; }
|
||||||
@ -21,12 +21,16 @@ namespace Kyoo.Models
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public string Name { get; set; }
|
public string Name { get; set; }
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public Dictionary<int, string> Images { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The path of this poster.
|
/// The path of this poster.
|
||||||
/// By default, the http path for this poster is returned from the public API.
|
/// By default, the http path for this poster is returned from the public API.
|
||||||
/// This can be disabled using the internal query flag.
|
/// This can be disabled using the internal query flag.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[SerializeAs("{HOST}/api/collection/{Slug}/poster")] public string Poster { get; set; }
|
[SerializeAs("{HOST}/api/collection/{Slug}/poster")]
|
||||||
|
public string Poster => Images[Thumbnails.Poster];
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The description of this collection.
|
/// The description of this collection.
|
||||||
@ -44,7 +48,7 @@ namespace Kyoo.Models
|
|||||||
[LoadableRelation] public ICollection<Library> Libraries { get; set; }
|
[LoadableRelation] public ICollection<Library> Libraries { get; set; }
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public ICollection<MetadataID> ExternalIDs { get; set; }
|
[EditableRelation] [LoadableRelation] public ICollection<MetadataID> ExternalIDs { get; set; }
|
||||||
|
|
||||||
#if ENABLE_INTERNAL_LINKS
|
#if ENABLE_INTERNAL_LINKS
|
||||||
|
|
||||||
|
@ -10,7 +10,7 @@ namespace Kyoo.Models
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// A class to represent a single show's episode.
|
/// A class to represent a single show's episode.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class Episode : IResource, IMetadata
|
public class Episode : IResource, IMetadata, IThumbnails
|
||||||
{
|
{
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public int ID { get; set; }
|
public int ID { get; set; }
|
||||||
@ -99,12 +99,16 @@ namespace Kyoo.Models
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
[SerializeIgnore] public string Path { get; set; }
|
[SerializeIgnore] public string Path { get; set; }
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public Dictionary<int, string> Images { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The path of this episode's thumbnail.
|
/// The path of this episode's thumbnail.
|
||||||
/// By default, the http path for the thumbnail is returned from the public API.
|
/// By default, the http path for the thumbnail is returned from the public API.
|
||||||
/// This can be disabled using the internal query flag.
|
/// This can be disabled using the internal query flag.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[SerializeAs("{HOST}/api/episodes/{Slug}/thumb")] public string Thumb { get; set; }
|
[SerializeAs("{HOST}/api/episodes/{Slug}/thumb")]
|
||||||
|
public string Thumb => Images[Thumbnails.Thumbnail];
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The title of this episode.
|
/// The title of this episode.
|
||||||
@ -122,7 +126,7 @@ namespace Kyoo.Models
|
|||||||
public DateTime? ReleaseDate { get; set; }
|
public DateTime? ReleaseDate { get; set; }
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public ICollection<MetadataID> ExternalIDs { get; set; }
|
[EditableRelation] [LoadableRelation] public ICollection<MetadataID> ExternalIDs { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The list of tracks this episode has. This lists video, audio and subtitles available.
|
/// The list of tracks this episode has. This lists video, audio and subtitles available.
|
||||||
|
@ -11,6 +11,7 @@ namespace Kyoo.Models
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// The link to metadata providers that this show has. See <see cref="MetadataID"/> for more information.
|
/// The link to metadata providers that this show has. See <see cref="MetadataID"/> for more information.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[EditableRelation] [LoadableRelation] public ICollection<MetadataID> ExternalIDs { get; set; }
|
[EditableRelation] [LoadableRelation]
|
||||||
|
public ICollection<MetadataID> ExternalIDs { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
49
Kyoo.Common/Models/Resources/Interfaces/IThumbnails.cs
Normal file
49
Kyoo.Common/Models/Resources/Interfaces/IThumbnails.cs
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using Kyoo.Controllers;
|
||||||
|
|
||||||
|
namespace Kyoo.Models
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// An interface representing items that contains images (like posters, thumbnails, logo, banners...)
|
||||||
|
/// </summary>
|
||||||
|
public interface IThumbnails
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// The list of images mapped to a certain index.
|
||||||
|
/// The string value should be a path supported by the <see cref="IFileSystem"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// An arbitrary index should not be used, instead use indexes from <see cref="Thumbnails"/>
|
||||||
|
/// </remarks>
|
||||||
|
public Dictionary<int, string> Images { get; set; }
|
||||||
|
|
||||||
|
// TODO remove Posters properties add them via the json serializer for every IThumbnails
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// A class containing constant values for images. To be used as index of a <see cref="IThumbnails.Images"/>.
|
||||||
|
/// </summary>
|
||||||
|
public static class Thumbnails
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// A poster is a 9/16 format image with the cover of the resource.
|
||||||
|
/// </summary>
|
||||||
|
public const int Poster = 0;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// A thumbnail is a 16/9 format image, it could ether be used as a background or as a preview but it usually
|
||||||
|
/// is not an official image.
|
||||||
|
/// </summary>
|
||||||
|
public const int Thumbnail = 1;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// A logo is a small image representing the resource.
|
||||||
|
/// </summary>
|
||||||
|
public const int Logo = 2;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// A video of a few minutes that tease the content.
|
||||||
|
/// </summary>
|
||||||
|
public const int Trailer = 3;
|
||||||
|
}
|
||||||
|
}
|
@ -6,7 +6,7 @@ namespace Kyoo.Models
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// An actor, voice actor, writer, animator, somebody who worked on a <see cref="Show"/>.
|
/// An actor, voice actor, writer, animator, somebody who worked on a <see cref="Show"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class People : IResource, IMetadata
|
public class People : IResource, IMetadata, IThumbnails
|
||||||
{
|
{
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public int ID { get; set; }
|
public int ID { get; set; }
|
||||||
@ -19,15 +19,19 @@ namespace Kyoo.Models
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public string Name { get; set; }
|
public string Name { get; set; }
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public Dictionary<int, string> Images { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The path of this poster.
|
/// The path of this poster.
|
||||||
/// By default, the http path for this poster is returned from the public API.
|
/// By default, the http path for this poster is returned from the public API.
|
||||||
/// This can be disabled using the internal query flag.
|
/// This can be disabled using the internal query flag.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[SerializeAs("{HOST}/api/people/{Slug}/poster")] public string Poster { get; set; }
|
[SerializeAs("{HOST}/api/people/{Slug}/poster")]
|
||||||
|
public string Poster => Images[Thumbnails.Poster];
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public ICollection<MetadataID> ExternalIDs { get; set; }
|
[EditableRelation] [LoadableRelation] public ICollection<MetadataID> ExternalIDs { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The list of roles this person has played in. See <see cref="PeopleRole"/> for more information.
|
/// The list of roles this person has played in. See <see cref="PeopleRole"/> for more information.
|
||||||
|
@ -9,7 +9,7 @@ namespace Kyoo.Models
|
|||||||
/// This class contains metadata about <see cref="IMetadataProvider"/>.
|
/// This class contains metadata about <see cref="IMetadataProvider"/>.
|
||||||
/// You can have providers even if you don't have the corresponding <see cref="IMetadataProvider"/>.
|
/// You can have providers even if you don't have the corresponding <see cref="IMetadataProvider"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class Provider : IResource
|
public class Provider : IResource, IThumbnails
|
||||||
{
|
{
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public int ID { get; set; }
|
public int ID { get; set; }
|
||||||
@ -22,12 +22,16 @@ namespace Kyoo.Models
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public string Name { get; set; }
|
public string Name { get; set; }
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public Dictionary<int, string> Images { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The path of this provider's logo.
|
/// The path of this provider's logo.
|
||||||
/// By default, the http path for this logo is returned from the public API.
|
/// By default, the http path for this logo is returned from the public API.
|
||||||
/// This can be disabled using the internal query flag.
|
/// This can be disabled using the internal query flag.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[SerializeAs("{HOST}/api/providers/{Slug}/logo")] public string Logo { get; set; }
|
[SerializeAs("{HOST}/api/providers/{Slug}/logo")]
|
||||||
|
public string Logo => Images[Thumbnails.Logo];
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The extension of the logo. This is used for http responses.
|
/// The extension of the logo. This is used for http responses.
|
||||||
@ -61,7 +65,7 @@ namespace Kyoo.Models
|
|||||||
{
|
{
|
||||||
Slug = Utility.ToSlug(name);
|
Slug = Utility.ToSlug(name);
|
||||||
Name = name;
|
Name = name;
|
||||||
Logo = logo;
|
Images[Thumbnails.Logo] = logo;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -10,7 +10,7 @@ namespace Kyoo.Models
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// A season of a <see cref="Show"/>.
|
/// A season of a <see cref="Show"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class Season : IResource, IMetadata
|
public class Season : IResource, IMetadata, IThumbnails
|
||||||
{
|
{
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public int ID { get; set; }
|
public int ID { get; set; }
|
||||||
@ -74,15 +74,19 @@ namespace Kyoo.Models
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public DateTime? EndDate { get; set; }
|
public DateTime? EndDate { get; set; }
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public Dictionary<int, string> Images { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The path of this poster.
|
/// The path of this poster.
|
||||||
/// By default, the http path for this poster is returned from the public API.
|
/// By default, the http path for this poster is returned from the public API.
|
||||||
/// This can be disabled using the internal query flag.
|
/// This can be disabled using the internal query flag.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[SerializeAs("{HOST}/api/seasons/{Slug}/thumb")] public string Poster { get; set; }
|
[SerializeAs("{HOST}/api/seasons/{Slug}/thumb")]
|
||||||
|
public string Poster => Images[Thumbnails.Poster];
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public ICollection<MetadataID> ExternalIDs { get; set; }
|
[EditableRelation] [LoadableRelation] public ICollection<MetadataID> ExternalIDs { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The list of episodes that this season contains.
|
/// The list of episodes that this season contains.
|
||||||
|
@ -11,7 +11,7 @@ namespace Kyoo.Models
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// A series or a movie.
|
/// A series or a movie.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class Show : IResource, IMetadata, IOnMerge
|
public class Show : IResource, IMetadata, IOnMerge, IThumbnails
|
||||||
{
|
{
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public int ID { get; set; }
|
public int ID { get; set; }
|
||||||
@ -49,7 +49,7 @@ namespace Kyoo.Models
|
|||||||
/// An URL to a trailer. This could be any path supported by the <see cref="IFileSystem"/>.
|
/// An URL to a trailer. This could be any path supported by the <see cref="IFileSystem"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// TODO for now, this is set to a youtube url. It should be cached and converted to a local file.
|
/// TODO for now, this is set to a youtube url. It should be cached and converted to a local file.
|
||||||
public string TrailerUrl { get; set; }
|
public string TrailerUrl => Images[Thumbnails.Trailer];
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The date this show started airing. It can be null if this is unknown.
|
/// The date this show started airing. It can be null if this is unknown.
|
||||||
@ -63,26 +63,32 @@ namespace Kyoo.Models
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public DateTime? EndAir { get; set; }
|
public DateTime? EndAir { get; set; }
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public Dictionary<int, string> Images { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The path of this show's poster.
|
/// The path of this show's poster.
|
||||||
/// By default, the http path for this poster is returned from the public API.
|
/// By default, the http path for this poster is returned from the public API.
|
||||||
/// This can be disabled using the internal query flag.
|
/// This can be disabled using the internal query flag.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[SerializeAs("{HOST}/api/shows/{Slug}/poster")] public string Poster { get; set; }
|
[SerializeAs("{HOST}/api/shows/{Slug}/poster")]
|
||||||
|
public string Poster => Images[Thumbnails.Poster];
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The path of this show's logo.
|
/// The path of this show's logo.
|
||||||
/// By default, the http path for this logo is returned from the public API.
|
/// By default, the http path for this logo is returned from the public API.
|
||||||
/// This can be disabled using the internal query flag.
|
/// This can be disabled using the internal query flag.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[SerializeAs("{HOST}/api/shows/{Slug}/logo")] public string Logo { get; set; }
|
[SerializeAs("{HOST}/api/shows/{Slug}/logo")]
|
||||||
|
public string Logo => Images[Thumbnails.Logo];
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The path of this show's backdrop.
|
/// The path of this show's backdrop.
|
||||||
/// By default, the http path for this backdrop is returned from the public API.
|
/// By default, the http path for this backdrop is returned from the public API.
|
||||||
/// This can be disabled using the internal query flag.
|
/// This can be disabled using the internal query flag.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[SerializeAs("{HOST}/api/shows/{Slug}/backdrop")] public string Backdrop { get; set; }
|
[SerializeAs("{HOST}/api/shows/{Slug}/backdrop")]
|
||||||
|
public string Backdrop => Images[Thumbnails.Thumbnail];
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// True if this show represent a movie, false otherwise.
|
/// True if this show represent a movie, false otherwise.
|
||||||
@ -90,7 +96,7 @@ namespace Kyoo.Models
|
|||||||
public bool IsMovie { get; set; }
|
public bool IsMovie { get; set; }
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public ICollection<MetadataID> ExternalIDs { get; set; }
|
[EditableRelation] [LoadableRelation] public ICollection<MetadataID> ExternalIDs { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The ID of the Studio that made this show.
|
/// The ID of the Studio that made this show.
|
||||||
|
@ -25,7 +25,7 @@ namespace Kyoo.Models
|
|||||||
[LoadableRelation] public ICollection<Show> Shows { get; set; }
|
[LoadableRelation] public ICollection<Show> Shows { get; set; }
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public ICollection<MetadataID> ExternalIDs { get; set; }
|
[EditableRelation] [LoadableRelation] public ICollection<MetadataID> ExternalIDs { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Create a new, empty, <see cref="Studio"/>.
|
/// Create a new, empty, <see cref="Studio"/>.
|
||||||
|
@ -41,7 +41,10 @@ namespace Kyoo.Tests
|
|||||||
Slug = "collection",
|
Slug = "collection",
|
||||||
Name = "Collection",
|
Name = "Collection",
|
||||||
Overview = "A nice collection for tests",
|
Overview = "A nice collection for tests",
|
||||||
Poster = "Poster"
|
Images =
|
||||||
|
{
|
||||||
|
[Thumbnails.Poster] = "Poster"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -61,12 +64,14 @@ namespace Kyoo.Tests
|
|||||||
"In time, however, these childhood friends drifted apart, and when they became high " +
|
"In time, however, these childhood friends drifted apart, and when they became high " +
|
||||||
"school students, they had long ceased to think of each other as friends.",
|
"school students, they had long ceased to think of each other as friends.",
|
||||||
Status = Status.Finished,
|
Status = Status.Finished,
|
||||||
TrailerUrl = null,
|
|
||||||
StartAir = new DateTime(2011, 1, 1),
|
StartAir = new DateTime(2011, 1, 1),
|
||||||
EndAir = new DateTime(2011, 1, 1),
|
EndAir = new DateTime(2011, 1, 1),
|
||||||
Poster = "poster",
|
Images =
|
||||||
Logo = "logo",
|
{
|
||||||
Backdrop = "backdrop",
|
[Thumbnails.Poster] = "Poster",
|
||||||
|
[Thumbnails.Logo] = "Logo",
|
||||||
|
[Thumbnails.Thumbnail] = "Thumbnail"
|
||||||
|
},
|
||||||
IsMovie = false,
|
IsMovie = false,
|
||||||
Studio = null
|
Studio = null
|
||||||
}
|
}
|
||||||
@ -83,7 +88,12 @@ namespace Kyoo.Tests
|
|||||||
Overview = "The first season",
|
Overview = "The first season",
|
||||||
StartDate = new DateTime(2020, 06, 05),
|
StartDate = new DateTime(2020, 06, 05),
|
||||||
EndDate = new DateTime(2020, 07, 05),
|
EndDate = new DateTime(2020, 07, 05),
|
||||||
Poster = "poster"
|
Images =
|
||||||
|
{
|
||||||
|
[Thumbnails.Poster] = "Poster",
|
||||||
|
[Thumbnails.Logo] = "Logo",
|
||||||
|
[Thumbnails.Thumbnail] = "Thumbnail"
|
||||||
|
},
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -98,7 +108,12 @@ namespace Kyoo.Tests
|
|||||||
EpisodeNumber = 1,
|
EpisodeNumber = 1,
|
||||||
AbsoluteNumber = 1,
|
AbsoluteNumber = 1,
|
||||||
Path = "/home/kyoo/anohana-s1e1",
|
Path = "/home/kyoo/anohana-s1e1",
|
||||||
Thumb = "thumbnail",
|
Images =
|
||||||
|
{
|
||||||
|
[Thumbnails.Poster] = "Poster",
|
||||||
|
[Thumbnails.Logo] = "Logo",
|
||||||
|
[Thumbnails.Thumbnail] = "Thumbnail"
|
||||||
|
},
|
||||||
Title = "Episode 1",
|
Title = "Episode 1",
|
||||||
Overview = "Summary of the first episode",
|
Overview = "Summary of the first episode",
|
||||||
ReleaseDate = new DateTime(2020, 06, 05)
|
ReleaseDate = new DateTime(2020, 06, 05)
|
||||||
@ -129,7 +144,12 @@ namespace Kyoo.Tests
|
|||||||
ID = 1,
|
ID = 1,
|
||||||
Slug = "the-actor",
|
Slug = "the-actor",
|
||||||
Name = "The Actor",
|
Name = "The Actor",
|
||||||
Poster = "NicePoster"
|
Images =
|
||||||
|
{
|
||||||
|
[Thumbnails.Poster] = "Poster",
|
||||||
|
[Thumbnails.Logo] = "Logo",
|
||||||
|
[Thumbnails.Thumbnail] = "Thumbnail"
|
||||||
|
},
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -138,7 +158,7 @@ namespace Kyoo.Tests
|
|||||||
{
|
{
|
||||||
ID = 1,
|
ID = 1,
|
||||||
Slug = "hyper-studio",
|
Slug = "hyper-studio",
|
||||||
Name = "Hyper studio"
|
Name = "Hyper studio",
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -157,7 +177,12 @@ namespace Kyoo.Tests
|
|||||||
ID = 1,
|
ID = 1,
|
||||||
Slug = "tvdb",
|
Slug = "tvdb",
|
||||||
Name = "The TVDB",
|
Name = "The TVDB",
|
||||||
Logo = "path/tvdb.svg",
|
Images =
|
||||||
|
{
|
||||||
|
[Thumbnails.Poster] = "Poster",
|
||||||
|
[Thumbnails.Logo] = "path/tvdb.svg",
|
||||||
|
[Thumbnails.Thumbnail] = "Thumbnail"
|
||||||
|
},
|
||||||
LogoExtension = "svg"
|
LogoExtension = "svg"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -257,7 +282,12 @@ namespace Kyoo.Tests
|
|||||||
EpisodeNumber = null,
|
EpisodeNumber = null,
|
||||||
AbsoluteNumber = 3,
|
AbsoluteNumber = 3,
|
||||||
Path = "/home/kyoo/anohana-3",
|
Path = "/home/kyoo/anohana-3",
|
||||||
Thumb = "thumbnail",
|
Images =
|
||||||
|
{
|
||||||
|
[Thumbnails.Poster] = "Poster",
|
||||||
|
[Thumbnails.Logo] = "Logo",
|
||||||
|
[Thumbnails.Thumbnail] = "Thumbnail"
|
||||||
|
},
|
||||||
Title = "Episode 3",
|
Title = "Episode 3",
|
||||||
Overview = "Summary of the third absolute episode",
|
Overview = "Summary of the third absolute episode",
|
||||||
ReleaseDate = new DateTime(2020, 06, 05)
|
ReleaseDate = new DateTime(2020, 06, 05)
|
||||||
@ -272,7 +302,12 @@ namespace Kyoo.Tests
|
|||||||
ShowSlug = "anohana",
|
ShowSlug = "anohana",
|
||||||
ShowID = 1,
|
ShowID = 1,
|
||||||
Path = "/home/kyoo/john-wick",
|
Path = "/home/kyoo/john-wick",
|
||||||
Thumb = "thumb",
|
Images =
|
||||||
|
{
|
||||||
|
[Thumbnails.Poster] = "Poster",
|
||||||
|
[Thumbnails.Logo] = "Logo",
|
||||||
|
[Thumbnails.Thumbnail] = "Thumbnail"
|
||||||
|
},
|
||||||
Title = "John wick",
|
Title = "John wick",
|
||||||
Overview = "A movie episode test",
|
Overview = "A movie episode test",
|
||||||
ReleaseDate = new DateTime(1595, 05, 12)
|
ReleaseDate = new DateTime(1595, 05, 12)
|
||||||
|
@ -26,17 +26,21 @@ namespace Kyoo.TheMovieDb
|
|||||||
Title = movie.Title,
|
Title = movie.Title,
|
||||||
Aliases = movie.AlternativeTitles.Titles.Select(x => x.Title).ToArray(),
|
Aliases = movie.AlternativeTitles.Titles.Select(x => x.Title).ToArray(),
|
||||||
Overview = movie.Overview,
|
Overview = movie.Overview,
|
||||||
TrailerUrl = movie.Videos?.Results.Where(x => x.Type is "Trailer" or "Teaser" && x.Site == "YouTube")
|
|
||||||
.Select(x => "https://www.youtube.com/watch?v=" + x.Key).FirstOrDefault(),
|
|
||||||
Status = movie.Status == "Released" ? Status.Finished : Status.Planned,
|
Status = movie.Status == "Released" ? Status.Finished : Status.Planned,
|
||||||
StartAir = movie.ReleaseDate,
|
StartAir = movie.ReleaseDate,
|
||||||
EndAir = movie.ReleaseDate,
|
EndAir = movie.ReleaseDate,
|
||||||
Poster = movie.PosterPath != null
|
Images =
|
||||||
|
{
|
||||||
|
[Thumbnails.Poster] = movie.PosterPath != null
|
||||||
? $"https://image.tmdb.org/t/p/original{movie.PosterPath}"
|
? $"https://image.tmdb.org/t/p/original{movie.PosterPath}"
|
||||||
: null,
|
: null,
|
||||||
Backdrop = movie.BackdropPath != null
|
[Thumbnails.Thumbnail] = movie.BackdropPath != null
|
||||||
? $"https://image.tmdb.org/t/p/original{movie.BackdropPath}"
|
? $"https://image.tmdb.org/t/p/original{movie.BackdropPath}"
|
||||||
: null,
|
: null,
|
||||||
|
[Thumbnails.Trailer] = movie.Videos?.Results
|
||||||
|
.Where(x => x.Type is "Trailer" or "Teaser" && x.Site == "YouTube")
|
||||||
|
.Select(x => "https://www.youtube.com/watch?v=" + x.Key).FirstOrDefault(),
|
||||||
|
},
|
||||||
Genres = movie.Genres.Select(x => new Genre(x.Name)).ToArray(),
|
Genres = movie.Genres.Select(x => new Genre(x.Name)).ToArray(),
|
||||||
Studio = !string.IsNullOrEmpty(movie.ProductionCompanies.FirstOrDefault()?.Name)
|
Studio = !string.IsNullOrEmpty(movie.ProductionCompanies.FirstOrDefault()?.Name)
|
||||||
? new Studio(movie.ProductionCompanies.First().Name)
|
? new Studio(movie.ProductionCompanies.First().Name)
|
||||||
@ -72,17 +76,21 @@ namespace Kyoo.TheMovieDb
|
|||||||
Title = tv.Name,
|
Title = tv.Name,
|
||||||
Aliases = tv.AlternativeTitles.Results.Select(x => x.Title).ToArray(),
|
Aliases = tv.AlternativeTitles.Results.Select(x => x.Title).ToArray(),
|
||||||
Overview = tv.Overview,
|
Overview = tv.Overview,
|
||||||
TrailerUrl = tv.Videos?.Results.Where(x => x.Type is "Trailer" or "Teaser" && x.Site == "YouTube")
|
|
||||||
.Select(x => "https://www.youtube.com/watch?v=" + x.Key).FirstOrDefault(),
|
|
||||||
Status = tv.Status == "Ended" ? Status.Finished : Status.Planned,
|
Status = tv.Status == "Ended" ? Status.Finished : Status.Planned,
|
||||||
StartAir = tv.FirstAirDate,
|
StartAir = tv.FirstAirDate,
|
||||||
EndAir = tv.LastAirDate,
|
EndAir = tv.LastAirDate,
|
||||||
Poster = tv.PosterPath != null
|
Images =
|
||||||
|
{
|
||||||
|
[Thumbnails.Poster] = tv.PosterPath != null
|
||||||
? $"https://image.tmdb.org/t/p/original{tv.PosterPath}"
|
? $"https://image.tmdb.org/t/p/original{tv.PosterPath}"
|
||||||
: null,
|
: null,
|
||||||
Backdrop = tv.BackdropPath != null
|
[Thumbnails.Thumbnail] = tv.BackdropPath != null
|
||||||
? $"https://image.tmdb.org/t/p/original{tv.BackdropPath}"
|
? $"https://image.tmdb.org/t/p/original{tv.BackdropPath}"
|
||||||
: null,
|
: null,
|
||||||
|
[Thumbnails.Trailer] = tv.Videos?.Results
|
||||||
|
.Where(x => x.Type is "Trailer" or "Teaser" && x.Site == "YouTube")
|
||||||
|
.Select(x => "https://www.youtube.com/watch?v=" + x.Key).FirstOrDefault()
|
||||||
|
},
|
||||||
Genres = tv.Genres.Select(x => new Genre(x.Name)).ToArray(),
|
Genres = tv.Genres.Select(x => new Genre(x.Name)).ToArray(),
|
||||||
Studio = !string.IsNullOrEmpty(tv.ProductionCompanies.FirstOrDefault()?.Name)
|
Studio = !string.IsNullOrEmpty(tv.ProductionCompanies.FirstOrDefault()?.Name)
|
||||||
? new Studio(tv.ProductionCompanies.First().Name)
|
? new Studio(tv.ProductionCompanies.First().Name)
|
||||||
@ -117,7 +125,15 @@ namespace Kyoo.TheMovieDb
|
|||||||
{
|
{
|
||||||
Slug = Utility.ToSlug(collection.Name),
|
Slug = Utility.ToSlug(collection.Name),
|
||||||
Name = collection.Name,
|
Name = collection.Name,
|
||||||
Poster = $"https://image.tmdb.org/t/p/original{collection.PosterPath}"
|
Images =
|
||||||
|
{
|
||||||
|
[Thumbnails.Poster] = collection.PosterPath != null
|
||||||
|
? $"https://image.tmdb.org/t/p/original{collection.PosterPath}"
|
||||||
|
: null,
|
||||||
|
[Thumbnails.Thumbnail] = collection.BackdropPath != null
|
||||||
|
? $"https://image.tmdb.org/t/p/original{collection.BackdropPath}"
|
||||||
|
: null
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -136,12 +152,15 @@ namespace Kyoo.TheMovieDb
|
|||||||
Overview = movie.Overview,
|
Overview = movie.Overview,
|
||||||
StartAir = movie.ReleaseDate,
|
StartAir = movie.ReleaseDate,
|
||||||
EndAir = movie.ReleaseDate,
|
EndAir = movie.ReleaseDate,
|
||||||
Poster = movie.PosterPath != null
|
Images =
|
||||||
|
{
|
||||||
|
[Thumbnails.Poster] = movie.PosterPath != null
|
||||||
? $"https://image.tmdb.org/t/p/original{movie.PosterPath}"
|
? $"https://image.tmdb.org/t/p/original{movie.PosterPath}"
|
||||||
: null,
|
: null,
|
||||||
Backdrop = movie.BackdropPath != null
|
[Thumbnails.Thumbnail] = movie.BackdropPath != null
|
||||||
? $"https://image.tmdb.org/t/p/original{movie.BackdropPath}"
|
? $"https://image.tmdb.org/t/p/original{movie.BackdropPath}"
|
||||||
: null,
|
: null,
|
||||||
|
},
|
||||||
IsMovie = true,
|
IsMovie = true,
|
||||||
ExternalIDs = new []
|
ExternalIDs = new []
|
||||||
{
|
{
|
||||||
@ -169,12 +188,15 @@ namespace Kyoo.TheMovieDb
|
|||||||
Title = tv.Name,
|
Title = tv.Name,
|
||||||
Overview = tv.Overview,
|
Overview = tv.Overview,
|
||||||
StartAir = tv.FirstAirDate,
|
StartAir = tv.FirstAirDate,
|
||||||
Poster = tv.PosterPath != null
|
Images =
|
||||||
|
{
|
||||||
|
[Thumbnails.Poster] = tv.PosterPath != null
|
||||||
? $"https://image.tmdb.org/t/p/original{tv.PosterPath}"
|
? $"https://image.tmdb.org/t/p/original{tv.PosterPath}"
|
||||||
: null,
|
: null,
|
||||||
Backdrop = tv.BackdropPath != null
|
[Thumbnails.Thumbnail] = tv.BackdropPath != null
|
||||||
? $"https://image.tmdb.org/t/p/original{tv.BackdropPath}"
|
? $"https://image.tmdb.org/t/p/original{tv.BackdropPath}"
|
||||||
: null,
|
: null,
|
||||||
|
},
|
||||||
IsMovie = true,
|
IsMovie = true,
|
||||||
ExternalIDs = new []
|
ExternalIDs = new []
|
||||||
{
|
{
|
||||||
@ -202,7 +224,12 @@ namespace Kyoo.TheMovieDb
|
|||||||
{
|
{
|
||||||
Slug = Utility.ToSlug(cast.Name),
|
Slug = Utility.ToSlug(cast.Name),
|
||||||
Name = cast.Name,
|
Name = cast.Name,
|
||||||
Poster = cast.ProfilePath != null ? $"https://image.tmdb.org/t/p/original{cast.ProfilePath}" : null,
|
Images =
|
||||||
|
{
|
||||||
|
[Thumbnails.Poster] = cast.ProfilePath != null
|
||||||
|
? $"https://image.tmdb.org/t/p/original{cast.ProfilePath}"
|
||||||
|
: null
|
||||||
|
},
|
||||||
ExternalIDs = new[]
|
ExternalIDs = new[]
|
||||||
{
|
{
|
||||||
new MetadataID
|
new MetadataID
|
||||||
@ -232,7 +259,12 @@ namespace Kyoo.TheMovieDb
|
|||||||
{
|
{
|
||||||
Slug = Utility.ToSlug(cast.Name),
|
Slug = Utility.ToSlug(cast.Name),
|
||||||
Name = cast.Name,
|
Name = cast.Name,
|
||||||
Poster = cast.ProfilePath != null ? $"https://image.tmdb.org/t/p/original{cast.ProfilePath}" : null,
|
Images =
|
||||||
|
{
|
||||||
|
[Thumbnails.Poster] = cast.ProfilePath != null
|
||||||
|
? $"https://image.tmdb.org/t/p/original{cast.ProfilePath}"
|
||||||
|
: null
|
||||||
|
},
|
||||||
ExternalIDs = new[]
|
ExternalIDs = new[]
|
||||||
{
|
{
|
||||||
new MetadataID
|
new MetadataID
|
||||||
@ -262,7 +294,12 @@ namespace Kyoo.TheMovieDb
|
|||||||
{
|
{
|
||||||
Slug = Utility.ToSlug(crew.Name),
|
Slug = Utility.ToSlug(crew.Name),
|
||||||
Name = crew.Name,
|
Name = crew.Name,
|
||||||
Poster = crew.ProfilePath != null ? $"https://image.tmdb.org/t/p/original{crew.ProfilePath}" : null,
|
Images =
|
||||||
|
{
|
||||||
|
[Thumbnails.Poster] = crew.ProfilePath != null
|
||||||
|
? $"https://image.tmdb.org/t/p/original{crew.ProfilePath}"
|
||||||
|
: null
|
||||||
|
},
|
||||||
ExternalIDs = new[]
|
ExternalIDs = new[]
|
||||||
{
|
{
|
||||||
new MetadataID
|
new MetadataID
|
||||||
|
@ -29,7 +29,11 @@ namespace Kyoo.TheMovieDb
|
|||||||
Slug = "the-moviedb",
|
Slug = "the-moviedb",
|
||||||
Name = "TheMovieDB",
|
Name = "TheMovieDB",
|
||||||
LogoExtension = "svg",
|
LogoExtension = "svg",
|
||||||
Logo = "https://www.themoviedb.org/assets/2/v4/logos/v2/blue_short-8e7b30f73a4020692ccca9c88bafe5dcb6f8a62a4c6bc55cd9ba82bb2cd95f6c.svg"
|
Images =
|
||||||
|
{
|
||||||
|
[Thumbnails.Logo] = "https://www.themoviedb.org/assets/2/v4/logos/v2/" +
|
||||||
|
"blue_short-8e7b30f73a4020692ccca9c88bafe5dcb6f8a62a4c6bc55cd9ba82bb2cd95f6c.svg"
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -55,7 +55,12 @@ namespace Kyoo.TheTvdb
|
|||||||
Overview = result.Overview,
|
Overview = result.Overview,
|
||||||
Status = _GetStatus(result.Status),
|
Status = _GetStatus(result.Status),
|
||||||
StartAir = _ParseDate(result.FirstAired),
|
StartAir = _ParseDate(result.FirstAired),
|
||||||
Poster = result.Poster != null ? $"https://www.thetvdb.com{result.Poster}" : null,
|
Images =
|
||||||
|
{
|
||||||
|
[Thumbnails.Poster] = result.Poster != null
|
||||||
|
? $"https://www.thetvdb.com{result.Poster}"
|
||||||
|
: null,
|
||||||
|
},
|
||||||
ExternalIDs = new[]
|
ExternalIDs = new[]
|
||||||
{
|
{
|
||||||
new MetadataID
|
new MetadataID
|
||||||
@ -84,8 +89,15 @@ namespace Kyoo.TheTvdb
|
|||||||
Overview = series.Overview,
|
Overview = series.Overview,
|
||||||
Status = _GetStatus(series.Status),
|
Status = _GetStatus(series.Status),
|
||||||
StartAir = _ParseDate(series.FirstAired),
|
StartAir = _ParseDate(series.FirstAired),
|
||||||
Poster = series.Poster != null ? $"https://www.thetvdb.com/banners/{series.Poster}" : null,
|
Images=
|
||||||
Backdrop = series.FanArt != null ? $"https://www.thetvdb.com/banners/{series.FanArt}" : null,
|
{
|
||||||
|
[Thumbnails.Poster] = series.Poster != null
|
||||||
|
? $"https://www.thetvdb.com/banners/{series.Poster}"
|
||||||
|
: null,
|
||||||
|
[Thumbnails.Thumbnail] = series.FanArt != null
|
||||||
|
? $"https://www.thetvdb.com/banners/{series.FanArt}"
|
||||||
|
: null
|
||||||
|
},
|
||||||
Genres = series.Genre.Select(y => new Genre(y)).ToList(),
|
Genres = series.Genre.Select(y => new Genre(y)).ToList(),
|
||||||
ExternalIDs = new[]
|
ExternalIDs = new[]
|
||||||
{
|
{
|
||||||
@ -113,7 +125,12 @@ namespace Kyoo.TheTvdb
|
|||||||
{
|
{
|
||||||
Slug = Utility.ToSlug(actor.Name),
|
Slug = Utility.ToSlug(actor.Name),
|
||||||
Name = actor.Name,
|
Name = actor.Name,
|
||||||
Poster = actor.Image != null ? $"https://www.thetvdb.com/banners/{actor.Image}" : null,
|
Images =
|
||||||
|
{
|
||||||
|
[Thumbnails.Poster] = actor.Image != null
|
||||||
|
? $"https://www.thetvdb.com/banners/{actor.Image}"
|
||||||
|
: null
|
||||||
|
},
|
||||||
ExternalIDs = new []
|
ExternalIDs = new []
|
||||||
{
|
{
|
||||||
new MetadataID
|
new MetadataID
|
||||||
@ -144,7 +161,12 @@ namespace Kyoo.TheTvdb
|
|||||||
AbsoluteNumber = episode.AbsoluteNumber,
|
AbsoluteNumber = episode.AbsoluteNumber,
|
||||||
Title = episode.EpisodeName,
|
Title = episode.EpisodeName,
|
||||||
Overview = episode.Overview,
|
Overview = episode.Overview,
|
||||||
Thumb = episode.Filename != null ? $"https://www.thetvdb.com/banners/{episode.Filename}" : null,
|
Images =
|
||||||
|
{
|
||||||
|
[Thumbnails.Thumbnail] = episode.Filename != null
|
||||||
|
? $"https://www.thetvdb.com/banners/{episode.Filename}"
|
||||||
|
: null
|
||||||
|
},
|
||||||
ExternalIDs = new[]
|
ExternalIDs = new[]
|
||||||
{
|
{
|
||||||
new MetadataID
|
new MetadataID
|
||||||
|
@ -33,7 +33,10 @@ namespace Kyoo.TheTvdb
|
|||||||
Slug = "the-tvdb",
|
Slug = "the-tvdb",
|
||||||
Name = "TheTVDB",
|
Name = "TheTVDB",
|
||||||
LogoExtension = "png",
|
LogoExtension = "png",
|
||||||
Logo = "https://www.thetvdb.com/images/logo.png"
|
Images =
|
||||||
|
{
|
||||||
|
[Thumbnails.Logo] = "https://www.thetvdb.com/images/logo.png"
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -2,7 +2,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using JetBrains.Annotations;
|
|
||||||
using Kyoo.Models.Options;
|
using Kyoo.Models.Options;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using Microsoft.Extensions.Options;
|
using Microsoft.Extensions.Options;
|
||||||
@ -55,23 +54,6 @@ namespace Kyoo.Controllers
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public Task<bool> DownloadImages<T>(T item, bool alwaysDownload = false)
|
|
||||||
where T : IResource
|
|
||||||
{
|
|
||||||
if (item == null)
|
|
||||||
throw new ArgumentNullException(nameof(item));
|
|
||||||
return item switch
|
|
||||||
{
|
|
||||||
Show show => _Validate(show, alwaysDownload),
|
|
||||||
Season season => _Validate(season, alwaysDownload),
|
|
||||||
Episode episode => _Validate(episode, alwaysDownload),
|
|
||||||
People people => _Validate(people, alwaysDownload),
|
|
||||||
Provider provider => _Validate(provider, alwaysDownload),
|
|
||||||
_ => Task.FromResult(false)
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// An helper function to download an image using a <see cref="LocalFileSystem"/>.
|
/// An helper function to download an image using a <see cref="LocalFileSystem"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -98,195 +80,71 @@ namespace Kyoo.Controllers
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <inheritdoc />
|
||||||
/// Download images of a specified show.
|
public async Task<bool> DownloadImages<T>(T item, bool alwaysDownload = false)
|
||||||
/// </summary>
|
where T : IThumbnails
|
||||||
/// <param name="show">
|
|
||||||
/// The item to cache images.
|
|
||||||
/// </param>
|
|
||||||
/// <param name="alwaysDownload">
|
|
||||||
/// <c>true</c> if images should be downloaded even if they already exists locally, <c>false</c> otherwise.
|
|
||||||
/// </param>
|
|
||||||
/// <returns><c>true</c> if an image has been downloaded, <c>false</c> otherwise.</returns>
|
|
||||||
private async Task<bool> _Validate([NotNull] Show show, bool alwaysDownload)
|
|
||||||
{
|
{
|
||||||
|
if (item == null)
|
||||||
|
throw new ArgumentNullException(nameof(item));
|
||||||
|
|
||||||
|
string name = item is IResource res ? res.Slug : "???";
|
||||||
bool ret = false;
|
bool ret = false;
|
||||||
|
|
||||||
if (show.Poster != null)
|
foreach ((int id, string image) in item.Images)
|
||||||
{
|
{
|
||||||
string posterPath = await GetPoster(show);
|
string localPath = await GetImagePath(item, id);
|
||||||
if (alwaysDownload || !await _files.Exists(posterPath))
|
if (alwaysDownload || !await _files.Exists(localPath))
|
||||||
ret |= await _DownloadImage(show.Poster, posterPath, $"The poster of {show.Title}");
|
ret |= await _DownloadImage(image, localPath, $"The image n°{id} of {name}");
|
||||||
}
|
|
||||||
if (show.Logo != null)
|
|
||||||
{
|
|
||||||
string logoPath = await GetLogo(show);
|
|
||||||
if (alwaysDownload || !await _files.Exists(logoPath))
|
|
||||||
ret |= await _DownloadImage(show.Logo, logoPath, $"The logo of {show.Title}");
|
|
||||||
}
|
|
||||||
if (show.Backdrop != null)
|
|
||||||
{
|
|
||||||
string backdropPath = await GetThumbnail(show);
|
|
||||||
if (alwaysDownload || !await _files.Exists(backdropPath))
|
|
||||||
ret |= await _DownloadImage(show.Backdrop, backdropPath, $"The backdrop of {show.Title}");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Download images of a specified person.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="people">
|
|
||||||
/// The item to cache images.
|
|
||||||
/// </param>
|
|
||||||
/// <param name="alwaysDownload">
|
|
||||||
/// <c>true</c> if images should be downloaded even if they already exists locally, <c>false</c> otherwise.
|
|
||||||
/// </param>
|
|
||||||
/// <returns><c>true</c> if an image has been downloaded, <c>false</c> otherwise.</returns>
|
|
||||||
private async Task<bool> _Validate([NotNull] People people, bool alwaysDownload)
|
|
||||||
{
|
|
||||||
if (people == null)
|
|
||||||
throw new ArgumentNullException(nameof(people));
|
|
||||||
if (people.Poster == null)
|
|
||||||
return false;
|
|
||||||
string localPath = await GetPoster(people);
|
|
||||||
if (alwaysDownload || !await _files.Exists(localPath))
|
|
||||||
return await _DownloadImage(people.Poster, localPath, $"The profile picture of {people.Name}");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Download images of a specified season.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="season">
|
|
||||||
/// The item to cache images.
|
|
||||||
/// </param>
|
|
||||||
/// <param name="alwaysDownload">
|
|
||||||
/// <c>true</c> if images should be downloaded even if they already exists locally, <c>false</c> otherwise.
|
|
||||||
/// </param>
|
|
||||||
/// <returns><c>true</c> if an image has been downloaded, <c>false</c> otherwise.</returns>
|
|
||||||
private async Task<bool> _Validate([NotNull] Season season, bool alwaysDownload)
|
|
||||||
{
|
|
||||||
if (season.Poster == null)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
string localPath = await GetPoster(season);
|
|
||||||
if (alwaysDownload || !await _files.Exists(localPath))
|
|
||||||
return await _DownloadImage(season.Poster, localPath, $"The poster of {season.Slug}");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Download images of a specified episode.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="episode">
|
|
||||||
/// The item to cache images.
|
|
||||||
/// </param>
|
|
||||||
/// <param name="alwaysDownload">
|
|
||||||
/// <c>true</c> if images should be downloaded even if they already exists locally, <c>false</c> otherwise.
|
|
||||||
/// </param>
|
|
||||||
/// <returns><c>true</c> if an image has been downloaded, <c>false</c> otherwise.</returns>
|
|
||||||
private async Task<bool> _Validate([NotNull] Episode episode, bool alwaysDownload)
|
|
||||||
{
|
|
||||||
if (episode.Thumb == null)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
string localPath = await _GetEpisodeThumb(episode);
|
|
||||||
if (alwaysDownload || !await _files.Exists(localPath))
|
|
||||||
return await _DownloadImage(episode.Thumb, localPath, $"The thumbnail of {episode.Slug}");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Download images of a specified provider.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="provider">
|
|
||||||
/// The item to cache images.
|
|
||||||
/// </param>
|
|
||||||
/// <param name="alwaysDownload">
|
|
||||||
/// <c>true</c> if images should be downloaded even if they already exists locally, <c>false</c> otherwise.
|
|
||||||
/// </param>
|
|
||||||
/// <returns><c>true</c> if an image has been downloaded, <c>false</c> otherwise.</returns>
|
|
||||||
private async Task<bool> _Validate([NotNull] Provider provider, bool alwaysDownload)
|
|
||||||
{
|
|
||||||
if (provider.Logo == null)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
string localPath = await GetLogo(provider);
|
|
||||||
if (alwaysDownload || !await _files.Exists(localPath))
|
|
||||||
return await _DownloadImage(provider.Logo, localPath, $"The logo of {provider.Slug}");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public Task<string> GetPoster<T>(T item)
|
public async Task<string> GetImagePath<T>(T item, int imageID)
|
||||||
where T : IResource
|
where T : IThumbnails
|
||||||
{
|
{
|
||||||
if (item == null)
|
if (item == null)
|
||||||
throw new ArgumentNullException(nameof(item));
|
throw new ArgumentNullException(nameof(item));
|
||||||
return item switch
|
string imageName = imageID switch
|
||||||
{
|
{
|
||||||
Show show => Task.FromResult(_files.Combine(_files.GetExtraDirectory(show), "poster.jpg")),
|
Thumbnails.Poster => "poster.jpg",
|
||||||
Season season => _GetSeasonPoster(season),
|
Thumbnails.Logo => "logo.jpg",
|
||||||
People actor => Task.FromResult(_files.Combine(_options.CurrentValue.PeoplePath, $"{actor.Slug}.jpg")),
|
Thumbnails.Thumbnail => "thumbnail.jpg",
|
||||||
_ => throw new NotSupportedException($"The type {typeof(T).Name} does not have a poster.")
|
_ => $"{imageID}.jpg"
|
||||||
};
|
};
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
// TODO implement a generic way, probably need to rework IFileManager.GetExtraDirectory too.
|
||||||
/// Retrieve the path of a season's poster.
|
switch (item)
|
||||||
/// </summary>
|
|
||||||
/// <param name="season">The season to retrieve the poster from.</param>
|
|
||||||
/// <returns>The path of the season's poster.</returns>
|
|
||||||
private async Task<string> _GetSeasonPoster(Season season)
|
|
||||||
{
|
{
|
||||||
|
case Show show:
|
||||||
|
return _files.Combine(_files.GetExtraDirectory(show), imageName);
|
||||||
|
|
||||||
|
case Season season:
|
||||||
if (season.Show == null)
|
if (season.Show == null)
|
||||||
await _library.Value.Load(season, x => x.Show);
|
await _library.Value.Load(season, x => x.Show);
|
||||||
return _files.Combine(_files.GetExtraDirectory(season.Show), $"season-{season.SeasonNumber}.jpg");
|
return _files.Combine(
|
||||||
}
|
_files.GetExtraDirectory(season.Show!),
|
||||||
|
$"season-{season.SeasonNumber}-{imageName}");
|
||||||
|
|
||||||
/// <inheritdoc />
|
case Episode episode:
|
||||||
public Task<string> GetThumbnail<T>(T item)
|
|
||||||
where T : IResource
|
|
||||||
{
|
|
||||||
if (item == null)
|
|
||||||
throw new ArgumentNullException(nameof(item));
|
|
||||||
return item switch
|
|
||||||
{
|
|
||||||
Show show => Task.FromResult(_files.Combine(_files.GetExtraDirectory(show), "backdrop.jpg")),
|
|
||||||
Episode episode => _GetEpisodeThumb(episode),
|
|
||||||
_ => throw new NotSupportedException($"The type {typeof(T).Name} does not have a thumbnail.")
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Get the path for an episode's thumbnail.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="episode">The episode to retrieve the thumbnail from</param>
|
|
||||||
/// <returns>The path of the given episode's thumbnail.</returns>
|
|
||||||
private async Task<string> _GetEpisodeThumb(Episode episode)
|
|
||||||
{
|
|
||||||
if (episode.Show == null)
|
if (episode.Show == null)
|
||||||
await _library.Value.Load(episode, x => x.Show);
|
await _library.Value.Load(episode, x => x.Show);
|
||||||
string dir = _files.Combine(_files.GetExtraDirectory(episode.Show), "Thumbnails");
|
string dir = _files.Combine(_files.GetExtraDirectory(episode.Show!), "Thumbnails");
|
||||||
await _files.CreateDirectory(dir);
|
await _files.CreateDirectory(dir);
|
||||||
return _files.Combine(dir, $"{Path.GetFileNameWithoutExtension(episode.Path)}.jpg");
|
return _files.Combine(dir, $"{Path.GetFileNameWithoutExtension(episode.Path)}-{imageName}");
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
case People actor:
|
||||||
public Task<string> GetLogo<T>(T item)
|
return _files.Combine(_options.CurrentValue.PeoplePath, $"{actor.Slug}-{imageName}");
|
||||||
where T : IResource
|
|
||||||
{
|
case Provider provider:
|
||||||
if (item == null)
|
return _files.Combine(
|
||||||
throw new ArgumentNullException(nameof(item));
|
_options.CurrentValue.ProviderPath,
|
||||||
return Task.FromResult(item switch
|
$"{provider.Slug}-{imageName[..^4]}{provider.LogoExtension}");
|
||||||
{
|
|
||||||
Show show => _files.Combine(_files.GetExtraDirectory(show), "logo.png"),
|
default:
|
||||||
Provider provider => _files.Combine(_options.CurrentValue.ProviderPath,
|
throw new NotSupportedException($"The type {typeof(T).Name} is not supported.");
|
||||||
$"{provider.Slug}.{provider.LogoExtension}"),
|
}
|
||||||
_ => throw new NotSupportedException($"The type {typeof(T).Name} does not have a thumbnail.")
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -163,7 +163,7 @@ namespace Kyoo.Tasks
|
|||||||
/// <typeparam name="T">The type of the item</typeparam>
|
/// <typeparam name="T">The type of the item</typeparam>
|
||||||
/// <returns>The existing or filled item.</returns>
|
/// <returns>The existing or filled item.</returns>
|
||||||
private async Task<T> _RegisterAndFill<T>(T item)
|
private async Task<T> _RegisterAndFill<T>(T item)
|
||||||
where T : class, IResource
|
where T : class, IResource, IThumbnails
|
||||||
{
|
{
|
||||||
if (item == null || string.IsNullOrEmpty(item.Slug))
|
if (item == null || string.IsNullOrEmpty(item.Slug))
|
||||||
return null;
|
return null;
|
||||||
|
@ -195,7 +195,7 @@ namespace Kyoo.Api
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
Episode episode = await _libraryManager.Get<Episode>(id);
|
Episode episode = await _libraryManager.Get<Episode>(id);
|
||||||
return _files.FileResult(await _thumbnails.GetThumbnail(episode));
|
return _files.FileResult(await _thumbnails.GetImagePath(episode, Thumbnails.Thumbnail));
|
||||||
}
|
}
|
||||||
catch (ItemNotFoundException)
|
catch (ItemNotFoundException)
|
||||||
{
|
{
|
||||||
@ -210,7 +210,7 @@ namespace Kyoo.Api
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
Episode episode = await _libraryManager.Get<Episode>(slug);
|
Episode episode = await _libraryManager.Get<Episode>(slug);
|
||||||
return _files.FileResult(await _thumbnails.GetThumbnail(episode));
|
return _files.FileResult(await _thumbnails.GetImagePath(episode, Thumbnails.Thumbnail));
|
||||||
}
|
}
|
||||||
catch (ItemNotFoundException)
|
catch (ItemNotFoundException)
|
||||||
{
|
{
|
||||||
|
@ -94,7 +94,7 @@ namespace Kyoo.Api
|
|||||||
People people = await _libraryManager.GetOrDefault<People>(id);
|
People people = await _libraryManager.GetOrDefault<People>(id);
|
||||||
if (people == null)
|
if (people == null)
|
||||||
return NotFound();
|
return NotFound();
|
||||||
return _files.FileResult(await _thumbs.GetPoster(people));
|
return _files.FileResult(await _thumbs.GetImagePath(people, Thumbnails.Poster));
|
||||||
}
|
}
|
||||||
|
|
||||||
[HttpGet("{slug}/poster")]
|
[HttpGet("{slug}/poster")]
|
||||||
@ -103,7 +103,7 @@ namespace Kyoo.Api
|
|||||||
People people = await _libraryManager.GetOrDefault<People>(slug);
|
People people = await _libraryManager.GetOrDefault<People>(slug);
|
||||||
if (people == null)
|
if (people == null)
|
||||||
return NotFound();
|
return NotFound();
|
||||||
return _files.FileResult(await _thumbs.GetPoster(people));
|
return _files.FileResult(await _thumbs.GetImagePath(people, Thumbnails.Poster));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -36,7 +36,7 @@ namespace Kyoo.Api
|
|||||||
Provider provider = await _libraryManager.GetOrDefault<Provider>(id);
|
Provider provider = await _libraryManager.GetOrDefault<Provider>(id);
|
||||||
if (provider == null)
|
if (provider == null)
|
||||||
return NotFound();
|
return NotFound();
|
||||||
return _files.FileResult(await _thumbnails.GetLogo(provider));
|
return _files.FileResult(await _thumbnails.GetImagePath(provider, Thumbnails.Logo));
|
||||||
}
|
}
|
||||||
|
|
||||||
[HttpGet("{slug}/logo")]
|
[HttpGet("{slug}/logo")]
|
||||||
@ -45,7 +45,7 @@ namespace Kyoo.Api
|
|||||||
Provider provider = await _libraryManager.GetOrDefault<Provider>(slug);
|
Provider provider = await _libraryManager.GetOrDefault<Provider>(slug);
|
||||||
if (provider == null)
|
if (provider == null)
|
||||||
return NotFound();
|
return NotFound();
|
||||||
return _files.FileResult(await _thumbnails.GetLogo(provider));
|
return _files.FileResult(await _thumbnails.GetImagePath(provider, Thumbnails.Logo));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -151,7 +151,7 @@ namespace Kyoo.Api
|
|||||||
if (season == null)
|
if (season == null)
|
||||||
return NotFound();
|
return NotFound();
|
||||||
await _libraryManager.Load(season, x => x.Show);
|
await _libraryManager.Load(season, x => x.Show);
|
||||||
return _files.FileResult(await _thumbs.GetPoster(season));
|
return _files.FileResult(await _thumbs.GetImagePath(season, Thumbnails.Poster));
|
||||||
}
|
}
|
||||||
|
|
||||||
[HttpGet("{slug}/poster")]
|
[HttpGet("{slug}/poster")]
|
||||||
@ -161,7 +161,7 @@ namespace Kyoo.Api
|
|||||||
if (season == null)
|
if (season == null)
|
||||||
return NotFound();
|
return NotFound();
|
||||||
await _libraryManager.Load(season, x => x.Show);
|
await _libraryManager.Load(season, x => x.Show);
|
||||||
return _files.FileResult(await _thumbs.GetPoster(season));
|
return _files.FileResult(await _thumbs.GetImagePath(season, Thumbnails.Poster));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -417,7 +417,7 @@ namespace Kyoo.Api
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
Show show = await _libraryManager.Get<Show>(slug);
|
Show show = await _libraryManager.Get<Show>(slug);
|
||||||
return _files.FileResult(await _thumbs.GetPoster(show));
|
return _files.FileResult(await _thumbs.GetImagePath(show, Thumbnails.Poster));
|
||||||
}
|
}
|
||||||
catch (ItemNotFoundException)
|
catch (ItemNotFoundException)
|
||||||
{
|
{
|
||||||
@ -431,7 +431,7 @@ namespace Kyoo.Api
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
Show show = await _libraryManager.Get<Show>(slug);
|
Show show = await _libraryManager.Get<Show>(slug);
|
||||||
return _files.FileResult(await _thumbs.GetLogo(show));
|
return _files.FileResult(await _thumbs.GetImagePath(show, Thumbnails.Logo));
|
||||||
}
|
}
|
||||||
catch (ItemNotFoundException)
|
catch (ItemNotFoundException)
|
||||||
{
|
{
|
||||||
@ -446,7 +446,7 @@ namespace Kyoo.Api
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
Show show = await _libraryManager.Get<Show>(slug);
|
Show show = await _libraryManager.Get<Show>(slug);
|
||||||
return _files.FileResult(await _thumbs.GetThumbnail(show));
|
return _files.FileResult(await _thumbs.GetImagePath(show, Thumbnails.Thumbnail));
|
||||||
}
|
}
|
||||||
catch (ItemNotFoundException)
|
catch (ItemNotFoundException)
|
||||||
{
|
{
|
||||||
|
Loading…
x
Reference in New Issue
Block a user