mirror of
https://github.com/zoriya/Kyoo.git
synced 2025-07-09 03:04:20 -04:00
Implementing the tvdb provider
This commit is contained in:
parent
ecb4101924
commit
2d45d6422d
@ -35,7 +35,7 @@ namespace Kyoo.Controllers
|
||||
/// If this metadata provider does not support <typeparamref name="T"/>.
|
||||
/// </exception>
|
||||
/// <returns>A new <typeparamref name="T"/> containing metadata from your provider</returns>
|
||||
[ItemNotNull]
|
||||
[ItemCanBeNull]
|
||||
Task<T> Get<T>([NotNull] T item)
|
||||
where T : class, IResource;
|
||||
|
||||
|
157
Kyoo.TheTvdb/Convertors.cs
Normal file
157
Kyoo.TheTvdb/Convertors.cs
Normal file
@ -0,0 +1,157 @@
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using Kyoo.Models;
|
||||
using TvDbSharper.Dto;
|
||||
|
||||
namespace Kyoo.TheTvdb
|
||||
{
|
||||
/// <summary>
|
||||
/// A set of extensions methods used to convert tvdb models to Kyoo models.
|
||||
/// </summary>
|
||||
public static class Convertors
|
||||
{
|
||||
/// <summary>
|
||||
/// Convert the string representation of the status in the tvdb API to a Kyoo's <see cref="Status"/> enum.
|
||||
/// </summary>
|
||||
/// <param name="status">The string representing the status.</param>
|
||||
/// <returns>A kyoo <see cref="Status"/> value or null.</returns>
|
||||
private static Status? GetStatus(string status)
|
||||
{
|
||||
return status switch
|
||||
{
|
||||
"Ended" => Status.Finished,
|
||||
"Continuing" => Status.Airing,
|
||||
_ => null
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Parse a TVDB date and return a <see cref="DateTime"/> or null if the string is invalid.
|
||||
/// </summary>
|
||||
/// <param name="date">The date string to parse</param>
|
||||
/// <returns>The parsed <see cref="DateTime"/> or null.</returns>
|
||||
private static DateTime ParseDate(string date)
|
||||
{
|
||||
DateTime.TryParseExact(date, "yyyy-mm-dd", CultureInfo.InvariantCulture, DateTimeStyles.None, out DateTime parsed);
|
||||
return parsed;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert a series search to a show.
|
||||
/// </summary>
|
||||
/// <param name="result">The search result</param>
|
||||
/// <param name="provider">The provider representing the tvdb inside kyoo</param>
|
||||
/// <returns>A show representing the given search result.</returns>
|
||||
public static Show ToShow(this SeriesSearchResult result, Provider provider)
|
||||
{
|
||||
return new()
|
||||
{
|
||||
Slug = result.Slug,
|
||||
Title = result.SeriesName,
|
||||
Aliases = result.Aliases,
|
||||
Overview = result.Overview,
|
||||
Status = GetStatus(result.Status),
|
||||
StartAir = ParseDate(result.FirstAired),
|
||||
Poster = result.Poster != null ? $"https://www.thetvdb.com{result.Poster}" : null,
|
||||
ExternalIDs = new[]
|
||||
{
|
||||
new MetadataID<Show>
|
||||
{
|
||||
DataID = result.Id.ToString(),
|
||||
Link = $"https://www.thetvdb.com/series/{result.Slug}",
|
||||
Second = provider
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert a tvdb series to a kyoo show.
|
||||
/// </summary>
|
||||
/// <param name="series">The series to convert</param>
|
||||
/// <param name="provider">The provider representing the tvdb inside kyoo</param>
|
||||
/// <returns>A show representing the given series.</returns>
|
||||
public static Show ToShow(this Series series, Provider provider)
|
||||
{
|
||||
return new()
|
||||
{
|
||||
Slug = series.Slug,
|
||||
Title = series.SeriesName,
|
||||
Aliases = series.Aliases,
|
||||
Overview = series.Overview,
|
||||
Status = GetStatus(series.Status),
|
||||
StartAir = ParseDate(series.FirstAired),
|
||||
Poster = series.Poster != null ? $"https://www.thetvdb.com/banners/{series.Poster}" : null,
|
||||
Backdrop = series.FanArt != null ? $"https://www.thetvdb.com/banners/{series.FanArt}" : null,
|
||||
Genres = series.Genre.Select(y => new Genre(y)).ToList(),
|
||||
ExternalIDs = new[]
|
||||
{
|
||||
new MetadataID<Show>
|
||||
{
|
||||
DataID = series.Id.ToString(),
|
||||
Link = $"https://www.thetvdb.com/series/{series.Slug}",
|
||||
Second = provider
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert a tvdb actor to a kyoo <see cref="PeopleRole"/>.
|
||||
/// </summary>
|
||||
/// <param name="actor">The actor to convert</param>
|
||||
/// <param name="provider">The provider representing the tvdb inside kyoo</param>
|
||||
/// <returns>A people role representing the given actor in the role they played.</returns>
|
||||
public static PeopleRole ToPeopleRole(this Actor actor, Provider provider)
|
||||
{
|
||||
return new()
|
||||
{
|
||||
People = new People
|
||||
{
|
||||
Slug = Utility.ToSlug(actor.Name),
|
||||
Name = actor.Name,
|
||||
Poster = actor.Image != null ? $"https://www.thetvdb.com/banners/{actor.Image}" : null,
|
||||
ExternalIDs = new []
|
||||
{
|
||||
new MetadataID<People>()
|
||||
{
|
||||
DataID = actor.Id.ToString(),
|
||||
Link = $"https://www.thetvdb.com/people/{actor.Id}",
|
||||
Second = provider
|
||||
}
|
||||
}
|
||||
},
|
||||
Role = actor.Role
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert a tvdb episode to a kyoo <see cref="Episode"/>.
|
||||
/// </summary>
|
||||
/// <param name="episode">The episode to convert</param>
|
||||
/// <param name="provider">The provider representing the tvdb inside kyoo</param>
|
||||
/// <returns>A episode representing the given tvdb episode.</returns>
|
||||
public static Episode ToEpisode(this EpisodeRecord episode, Provider provider)
|
||||
{
|
||||
return new()
|
||||
{
|
||||
SeasonNumber = episode.AiredSeason,
|
||||
EpisodeNumber = episode.AiredEpisodeNumber,
|
||||
AbsoluteNumber = episode.AbsoluteNumber,
|
||||
Title = episode.EpisodeName,
|
||||
Overview = episode.Overview,
|
||||
Thumb = episode.Filename != null ? $"https://www.thetvdb.com/banners/{episode.Filename}" : null,
|
||||
ExternalIDs = new[]
|
||||
{
|
||||
new MetadataID<Episode>
|
||||
{
|
||||
DataID = episode.Id.ToString(),
|
||||
Link = $"https://www.thetvdb.com/series/{episode.SeriesId}/episodes/{episode.Id}",
|
||||
Second = provider
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
@ -1,7 +1,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Autofac;
|
||||
using Kyoo.Controllers;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
namespace Kyoo.TheTvdb
|
||||
{
|
||||
@ -33,9 +33,9 @@ namespace Kyoo.TheTvdb
|
||||
|
||||
|
||||
/// <inheritdoc />
|
||||
public void Configure(IServiceCollection services, ICollection<Type> availableTypes)
|
||||
public void Configure(ContainerBuilder builder)
|
||||
{
|
||||
// services.AddProvider<ProviderTvdb>();
|
||||
builder.RegisterProvider<ProviderTvdb>();
|
||||
}
|
||||
}
|
||||
}
|
@ -1,8 +1,8 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using JetBrains.Annotations;
|
||||
using Kyoo.Controllers;
|
||||
using Kyoo.Models;
|
||||
using TvDbSharper;
|
||||
@ -15,189 +15,97 @@ namespace Kyoo.TheTvdb
|
||||
/// </summary>
|
||||
public class ProviderTvdb : IMetadataProvider
|
||||
{
|
||||
public Provider Provider { get; }
|
||||
public Task<T> Get<T>(T item) where T : class, IResource
|
||||
/// <summary>
|
||||
/// The internal tvdb client used to make requests.
|
||||
/// </summary>
|
||||
private readonly TvDbClient _client = new();
|
||||
|
||||
/// <summary>
|
||||
/// The API key used to authenticate with the tvdb API.
|
||||
/// </summary>
|
||||
private readonly string _apiKey;
|
||||
|
||||
/// <inheritdoc />
|
||||
public Provider Provider => new()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
Slug = "the-tvdb",
|
||||
Name = "TheTVDB",
|
||||
LogoExtension = "png",
|
||||
Logo = "https://www.thetvdb.com/images/logo.png"
|
||||
};
|
||||
|
||||
|
||||
public ProviderTvdb(string apiKey)
|
||||
{
|
||||
_apiKey = apiKey;
|
||||
}
|
||||
|
||||
public Task<ICollection<T>> Search<T>(string query) where T : class, IResource
|
||||
private Task _Authenticate()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
if (_client.Authentication.Token == null)
|
||||
return _client.Authentication.AuthenticateAsync(_apiKey);
|
||||
return _client.Authentication.RefreshTokenAsync();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public async Task<T> Get<T>(T item)
|
||||
where T : class, IResource
|
||||
{
|
||||
await _Authenticate();
|
||||
return item switch
|
||||
{
|
||||
Show show => await _GetShow(show) as T,
|
||||
Episode episode => await _GetEpisode(episode) as T,
|
||||
_ => throw new NotSupportedException()
|
||||
};
|
||||
}
|
||||
|
||||
[ItemCanBeNull]
|
||||
private async Task<Show> _GetShow([NotNull] Show show)
|
||||
{
|
||||
if (!int.TryParse(show.GetID(Provider.Slug), out int id))
|
||||
return (await _SearchShow(show.Title)).FirstOrDefault();
|
||||
TvDbResponse<Series> series = await _client.Series.GetAsync(id);
|
||||
return series.Data.ToShow(Provider);
|
||||
}
|
||||
|
||||
public Task<ICollection<PeopleRole>> GetPeople(Show show)
|
||||
[ItemCanBeNull]
|
||||
private async Task<Episode> _GetEpisode([NotNull] Episode episode)
|
||||
{
|
||||
if (!int.TryParse(episode.Show?.GetID(Provider.Slug), out int id))
|
||||
return null;
|
||||
EpisodeQuery query = episode.AbsoluteNumber != null
|
||||
? new EpisodeQuery {AbsoluteNumber = episode.AbsoluteNumber}
|
||||
: new EpisodeQuery {AiredSeason = episode.SeasonNumber, AiredEpisode = episode.EpisodeNumber};
|
||||
TvDbResponse<EpisodeRecord[]> episodes = await _client.Series.GetEpisodesAsync(id, 0, query);
|
||||
return episodes.Data.FirstOrDefault()?.ToEpisode(Provider);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public async Task<ICollection<T>> Search<T>(string query)
|
||||
where T : class, IResource
|
||||
{
|
||||
await _Authenticate();
|
||||
if (typeof(T) == typeof(Show))
|
||||
return (await _SearchShow(query) as ICollection<T>)!;
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
[ItemNotNull]
|
||||
private async Task<ICollection<Show>> _SearchShow(string query)
|
||||
{
|
||||
TvDbResponse<SeriesSearchResult[]> shows = await _client.Search.SearchSeriesByNameAsync(query);
|
||||
return shows.Data.Select(x => x.ToShow(Provider)).ToArray();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public async Task<ICollection<PeopleRole>> GetPeople(Show show)
|
||||
{
|
||||
if (!int.TryParse(show?.GetID(Provider.Name), out int id))
|
||||
return null;
|
||||
await _Authenticate();
|
||||
TvDbResponse<Actor[]> people = await _client.Series.GetActorsAsync(id);
|
||||
return people.Data.Select(x => x.ToPeopleRole(Provider)).ToArray();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// public class Old
|
||||
// {
|
||||
// private static readonly ProviderID _provider = new()
|
||||
// {
|
||||
// Slug = "the-tvdb",
|
||||
// Name = "TheTVDB",
|
||||
// LogoExtension = "png",
|
||||
// Logo = "https://www.thetvdb.com/images/logo.png"
|
||||
// };
|
||||
// public ProviderID Provider => _provider;
|
||||
//
|
||||
//
|
||||
// private readonly TvDbClient _client = new();
|
||||
//
|
||||
// private Task Authentificate()
|
||||
// {
|
||||
// if (_client.Authentication.Token == null)
|
||||
// return _client.Authentication.AuthenticateAsync(APIKey);
|
||||
// return _client.Authentication.RefreshTokenAsync();
|
||||
// }
|
||||
//
|
||||
// public Task<Collection> GetCollectionFromName(string name)
|
||||
// {
|
||||
// return Task.FromResult<Collection>(null);
|
||||
// }
|
||||
//
|
||||
// public async Task<ICollection<Show>> SearchShows(string showName, bool isMovie)
|
||||
// {
|
||||
// await Authentificate();
|
||||
//
|
||||
// if (isMovie)
|
||||
// return null; //There is no movie search API for now on TheTVDB.
|
||||
// TvDbResponse<SeriesSearchResult[]> shows = await _client.Search.SearchSeriesAsync(showName, SearchParameter.Name);
|
||||
// return shows.Data.Select(x => x.ToShow(Provider)).ToArray();
|
||||
// }
|
||||
//
|
||||
// public async Task<Show> GetShowByID(Show show)
|
||||
// {
|
||||
// if (!int.TryParse(show?.GetID(Provider.Name), out int id))
|
||||
// return await Task.FromResult<Show>(null);
|
||||
// await Authentificate();
|
||||
// TvDbResponse<Series> serie = await _client.Series.GetAsync(id);
|
||||
// return serie.Data.ToShow(Provider);
|
||||
// }
|
||||
//
|
||||
// public async Task<ICollection<PeopleRole>> GetPeople(Show show)
|
||||
// {
|
||||
// if (!int.TryParse(show?.GetID(Provider.Name), out int id))
|
||||
// return null;
|
||||
// await Authentificate();
|
||||
// TvDbResponse<Actor[]> people = await _client.Series.GetActorsAsync(id);
|
||||
// return people.Data.Select(x => x.ToPeopleRole(Provider)).ToArray();
|
||||
// }
|
||||
//
|
||||
// public Task<Season> GetSeason(Show show, int seasonNumber)
|
||||
// {
|
||||
// return Task.FromResult<Season>(null);
|
||||
// }
|
||||
//
|
||||
// public async Task<Episode> GetEpisode(Show show, int seasonNumber, int episodeNumber, int absoluteNumber)
|
||||
// {
|
||||
// if (!int.TryParse(show?.GetID(Provider.Name), out int id))
|
||||
// return null;
|
||||
// await Authentificate();
|
||||
// TvDbResponse<EpisodeRecord[]> episodes = absoluteNumber != -1
|
||||
// ? await _client.Series.GetEpisodesAsync(id, 0, new EpisodeQuery {AbsoluteNumber = absoluteNumber})
|
||||
// : await _client.Series.GetEpisodesAsync(id, 0, new EpisodeQuery {AiredSeason = seasonNumber, AiredEpisode = episodeNumber});
|
||||
// EpisodeRecord x = episodes.Data[0];
|
||||
//
|
||||
// if (absoluteNumber == -1)
|
||||
// absoluteNumber = x.AbsoluteNumber ?? -1;
|
||||
// else
|
||||
// {
|
||||
// seasonNumber = x.AiredSeason ?? -1;
|
||||
// episodeNumber = x.AiredEpisodeNumber ?? -1;
|
||||
// }
|
||||
//
|
||||
// return new Episode(seasonNumber,
|
||||
// episodeNumber,
|
||||
// absoluteNumber,
|
||||
// x.EpisodeName,
|
||||
// x.Overview,
|
||||
// DateTime.ParseExact(x.FirstAired, "yyyy-MM-dd", CultureInfo.InvariantCulture),
|
||||
// -1,
|
||||
// x.Filename != null ? "https://www.thetvdb.com/banners/" + x.Filename : null,
|
||||
// new []
|
||||
// {
|
||||
// new MetadataID(Provider, x.Id.ToString(), $"https://www.thetvdb.com/series/{id}/episodes/{x.Id}")
|
||||
// });
|
||||
// }
|
||||
// }
|
||||
|
||||
// public static class Convertors
|
||||
// {
|
||||
// private static int? GetYear(string firstAired)
|
||||
// {
|
||||
// if (firstAired?.Length >= 4 && int.TryParse(firstAired.Substring(0, 4), out int year))
|
||||
// return year;
|
||||
// return null;
|
||||
// }
|
||||
//
|
||||
// private static Status? GetStatus(string status)
|
||||
// {
|
||||
// return status switch
|
||||
// {
|
||||
// "Ended" => Status.Finished,
|
||||
// "Continuing" => Status.Airing,
|
||||
// _ => null
|
||||
// };
|
||||
// }
|
||||
//
|
||||
// public static Show ToShow(this SeriesSearchResult x, ProviderID provider)
|
||||
// {
|
||||
// Show ret = new(x.Slug,
|
||||
// x.SeriesName,
|
||||
// x.Aliases,
|
||||
// null,
|
||||
// x.Overview,
|
||||
// null,
|
||||
// null,
|
||||
// GetStatus(x.Status),
|
||||
// GetYear(x.FirstAired),
|
||||
// null,
|
||||
// new[]
|
||||
// {
|
||||
// new MetadataID(provider, x.Id.ToString(), $"https://www.thetvdb.com/series/{x.Slug}")
|
||||
// });
|
||||
// if (x.Poster != null)
|
||||
// Utility.SetImage(ret, $"https://www.thetvdb.com{x.Poster}", ImageType.Poster);
|
||||
// return ret;
|
||||
// }
|
||||
//
|
||||
// public static Show ToShow(this Series x, ProviderID provider)
|
||||
// {
|
||||
// return new(x.Slug,
|
||||
// x.SeriesName,
|
||||
// x.Aliases,
|
||||
// null,
|
||||
// x.Overview,
|
||||
// null,
|
||||
// x.Genre.Select(y => new Genre(Utility.ToSlug(y), y)),
|
||||
// GetStatus(x.Status),
|
||||
// GetYear(x.FirstAired),
|
||||
// null,
|
||||
// new[]
|
||||
// {
|
||||
// new MetadataID(provider, x.Id.ToString(),$"https://www.thetvdb.com/series/{x.Slug}")
|
||||
// })
|
||||
// {
|
||||
// Poster = x.Poster != null ? $"https://www.thetvdb.com/banners/{x.Poster}" : null,
|
||||
// Backdrop = x.FanArt != null ? $"https://www.thetvdb.com/banners/{x.FanArt}" : null
|
||||
// };
|
||||
// }
|
||||
//
|
||||
// public static PeopleRole ToPeopleRole(this Actor x, ProviderID provider)
|
||||
// {
|
||||
// return new (Utility.ToSlug(x.Name),
|
||||
// x.Name,
|
||||
// x.Role,
|
||||
// null,
|
||||
// x.Image != null ? $"https://www.thetvdb.com/banners/{x.Image}" : null,
|
||||
// new[]
|
||||
// {
|
||||
// new MetadataID(provider, x.Id.ToString(), $"https://www.thetvdb.com/people/{x.Id}")
|
||||
// });
|
||||
// }
|
||||
// }
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user