Skip to content

Commit

Permalink
Initial release
Browse files Browse the repository at this point in the history
  • Loading branch information
crobibero committed Nov 8, 2020
1 parent f141389 commit a2c4472
Show file tree
Hide file tree
Showing 8 changed files with 369 additions and 210 deletions.
2 changes: 1 addition & 1 deletion Jellyfin.Plugin.TvMaze/Jellyfin.Plugin.TvMaze.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
<PackageReference Include="Jellyfin.Data" Version="10.6.0" />
<PackageReference Include="Jellyfin.Model" Version="10.6.0" />
<PackageReference Include="Microsoft.Extensions.Http" Version="3.1.9" />
<PackageReference Include="TvMaze.Api.Client" Version="0.0.16" />
<PackageReference Include="TvMaze.Api.Client" Version="0.0.21" />
</ItemGroup>

<!-- Code Analyzers-->
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using MediaBrowser.Model.Entities;

namespace Jellyfin.Plugin.TvMaze.Providers
{
/// <summary>
/// Search helpers.
/// </summary>
public static class Helpers
public static class TvHelpers
{
internal static int? GetTvMazeId(Dictionary<string, string> providerIds)
{
Expand All @@ -26,7 +25,7 @@ public static class Helpers
/// </summary>
/// <param name="input">Input string.</param>
/// <returns>Stripped input.</returns>
internal static string StripHtml(string input)
internal static string GetStrippedHtml(string input)
{
return input
.Replace("<br>", Environment.NewLine, StringComparison.OrdinalIgnoreCase)
Expand Down
85 changes: 50 additions & 35 deletions Jellyfin.Plugin.TvMaze/Providers/TvMazeEpisodeImageProvider.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.Collections.Generic;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
Expand All @@ -8,6 +9,7 @@
using MediaBrowser.Controller.Providers;
using MediaBrowser.Model.Entities;
using MediaBrowser.Model.Providers;
using Microsoft.Extensions.Logging;
using TvMaze.Api.Client;

namespace Jellyfin.Plugin.TvMaze.Providers
Expand All @@ -18,15 +20,18 @@ namespace Jellyfin.Plugin.TvMaze.Providers
public class TvMazeEpisodeImageProvider : IRemoteImageProvider
{
private readonly IHttpClient _httpClient;
private readonly ILogger<TvMazeEpisodeImageProvider> _logger;
private readonly ITvMazeClient _tvMazeClient;

/// <summary>
/// Initializes a new instance of the <see cref="TvMazeEpisodeImageProvider"/> class.
/// </summary>
/// <param name="httpClient">Instance of the <see cref="IHttpClient"/> interface.</param>
public TvMazeEpisodeImageProvider(IHttpClient httpClient)
/// <param name="logger">Instance of <see cref="ILogger{TvMazeEpisodeImageProvider}"/>.</param>
public TvMazeEpisodeImageProvider(IHttpClient httpClient, ILogger<TvMazeEpisodeImageProvider> logger)
{
_httpClient = httpClient;
_logger = logger;
_tvMazeClient = new TvMazeClient();
}

Expand All @@ -48,46 +53,56 @@ public IEnumerable<ImageType> GetSupportedImages(BaseItem item)
/// <inheritdoc />
public async Task<IEnumerable<RemoteImageInfo>> GetImages(BaseItem item, CancellationToken cancellationToken)
{
var episode = (Episode)item;
var series = episode.Series;
if (series == null)
try
{
// Episode or series is null.
return Enumerable.Empty<RemoteImageInfo>();
}
_logger.LogDebug("[GetImages] {name}", item.Name);
var episode = (Episode)item;
var series = episode.Series;
if (series == null)
{
// Episode or series is null.
return Enumerable.Empty<RemoteImageInfo>();
}

var tvMazeId = Helpers.GetTvMazeId(episode.Series.ProviderIds);
if (tvMazeId == null)
{
// Requires series tv maze id.
return Enumerable.Empty<RemoteImageInfo>();
}
var tvMazeId = TvHelpers.GetTvMazeId(episode.Series.ProviderIds);
if (tvMazeId == null)
{
// Requires series tv maze id.
return Enumerable.Empty<RemoteImageInfo>();
}

if (episode.IndexNumber == null || episode.ParentIndexNumber == null)
{
// Missing episode or season number.
return Enumerable.Empty<RemoteImageInfo>();
}
if (episode.IndexNumber == null || episode.ParentIndexNumber == null)
{
// Missing episode or season number.
return Enumerable.Empty<RemoteImageInfo>();
}

var tvMazeEpisode = await _tvMazeClient.Shows.GetEpisodeByNumberAsync(tvMazeId.Value, episode.ParentIndexNumber.Value, episode.IndexNumber.Value).ConfigureAwait(false);
if (tvMazeEpisode == null)
{
return Enumerable.Empty<RemoteImageInfo>();
}
var tvMazeEpisode = await _tvMazeClient.Shows.GetEpisodeByNumberAsync(tvMazeId.Value, episode.ParentIndexNumber.Value, episode.IndexNumber.Value).ConfigureAwait(false);
if (tvMazeEpisode == null)
{
return Enumerable.Empty<RemoteImageInfo>();
}

var imageResults = new List<RemoteImageInfo>();
if (tvMazeEpisode.Image?.Original != null)
{
imageResults.Add(new RemoteImageInfo
var imageResults = new List<RemoteImageInfo>();
if (tvMazeEpisode.Image?.Original != null)
{
Url = tvMazeEpisode.Image.Original,
ProviderName = TvMazePlugin.ProviderName,
Language = "en",
Type = ImageType.Primary
});
}
imageResults.Add(new RemoteImageInfo
{
Url = tvMazeEpisode.Image.Original,
ProviderName = TvMazePlugin.ProviderName,
Language = "en",
Type = ImageType.Primary
});
}

return imageResults;
_logger.LogInformation("[GetImages] Images found for {name}: {@images}", item.Name, imageResults);
return imageResults;
}
catch (Exception e)
{
_logger.LogWarning(e, "[GetImages]");
return Enumerable.Empty<RemoteImageInfo>();
}
}

/// <inheritdoc />
Expand Down
84 changes: 54 additions & 30 deletions Jellyfin.Plugin.TvMaze/Providers/TvMazeEpisodeProvider.cs
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using MediaBrowser.Common.Net;
using MediaBrowser.Controller.Entities.TV;
using MediaBrowser.Controller.Providers;
using MediaBrowser.Model.Entities;
using MediaBrowser.Model.Providers;
using Microsoft.Extensions.Logging;
using TvMaze.Api.Client;

namespace Jellyfin.Plugin.TvMaze.Providers
Expand All @@ -19,16 +21,19 @@ public class TvMazeEpisodeProvider : IRemoteMetadataProvider<Episode, EpisodeInf
{
private readonly ITvMazeClient _tvMazeClient;
private readonly IHttpClient _httpClient;
private readonly ILogger<TvMazeEpisodeProvider> _logger;

/// <summary>
/// Initializes a new instance of the <see cref="TvMazeEpisodeProvider"/> class.
/// </summary>
/// <param name="httpClient">Instance of the <see cref="IHttpClient"/> interface.</param>
public TvMazeEpisodeProvider(IHttpClient httpClient)
/// <param name="logger">Instance of <see cref="ILogger{TvMazeEpisodeProvider}"/>.</param>
public TvMazeEpisodeProvider(IHttpClient httpClient, ILogger<TvMazeEpisodeProvider> logger)
{
// TODO DI.
_tvMazeClient = new TvMazeClient();
_httpClient = httpClient;
_logger = logger;
}

/// <inheritdoc />
Expand All @@ -37,46 +42,65 @@ public TvMazeEpisodeProvider(IHttpClient httpClient)
/// <inheritdoc />
public async Task<IEnumerable<RemoteSearchResult>> GetSearchResults(EpisodeInfo searchInfo, CancellationToken cancellationToken)
{
var results = new List<RemoteSearchResult>();

var tvMazeId = Helpers.GetTvMazeId(searchInfo.SeriesProviderIds);
if (!tvMazeId.HasValue)
try
{
// Requires a tv maze id.
_logger.LogDebug("[GetSearchResults] Starting for {name} {seasonNumber}x{episodeNumber}", searchInfo.Name, searchInfo.ParentIndexNumber, searchInfo.IndexNumber);
var results = new List<RemoteSearchResult>();

var tvMazeId = TvHelpers.GetTvMazeId(searchInfo.SeriesProviderIds);
if (!tvMazeId.HasValue)
{
// Requires a tv maze id.
return results;
}

var episode = await GetMetadataInternal(searchInfo).ConfigureAwait(false);
if (episode != null)
{
results.Add(new RemoteSearchResult
{
IndexNumber = episode.IndexNumber,
Name = episode.Name,
ParentIndexNumber = episode.ParentIndexNumber,
PremiereDate = episode.PremiereDate,
ProductionYear = episode.ProductionYear,
ProviderIds = episode.ProviderIds,
SearchProviderName = Name,
IndexNumberEnd = episode.IndexNumberEnd
});
}

_logger.LogDebug("[GetSearchResults] Results for {name}: {@episode}", searchInfo.Name, results);
return results;
}

var episode = await GetMetadataInternal(searchInfo).ConfigureAwait(false);
if (episode != null)
catch (Exception e)
{
results.Add(new RemoteSearchResult
{
IndexNumber = episode.IndexNumber,
Name = episode.Name,
ParentIndexNumber = episode.ParentIndexNumber,
PremiereDate = episode.PremiereDate,
ProductionYear = episode.ProductionYear,
ProviderIds = episode.ProviderIds,
SearchProviderName = Name,
IndexNumberEnd = episode.IndexNumberEnd
});
_logger.LogWarning(e, "[GetSearchResults]");
return Enumerable.Empty<RemoteSearchResult>();
}

return results;
}

/// <inheritdoc />
public async Task<MetadataResult<Episode>> GetMetadata(EpisodeInfo info, CancellationToken cancellationToken)
{
var result = new MetadataResult<Episode>();
var episode = await GetMetadataInternal(info).ConfigureAwait(false);
if (episode != null)
try
{
result.Item = episode;
result.HasMetadata = true;
}
_logger.LogDebug("[GetMetadata] Starting for {name}", info.Name);
var episode = await GetMetadataInternal(info).ConfigureAwait(false);
if (episode != null)
{
result.Item = episode;
result.HasMetadata = true;
}

return result;
return result;
}
catch (Exception e)
{
_logger.LogWarning(e, "[GetMetadata]");
return result;
}
}

/// <inheritdoc />
Expand All @@ -91,7 +115,7 @@ public Task<HttpResponseInfo> GetImageResponse(string url, CancellationToken can

private async Task<Episode?> GetMetadataInternal(EpisodeInfo info)
{
var tvMazeId = Helpers.GetTvMazeId(info.SeriesProviderIds);
var tvMazeId = TvHelpers.GetTvMazeId(info.SeriesProviderIds);
if (!tvMazeId.HasValue)
{
// Requires a tv maze id.
Expand Down Expand Up @@ -128,7 +152,7 @@ public Task<HttpResponseInfo> GetImageResponse(string url, CancellationToken can
episode.RunTimeTicks = TimeSpan.FromTicks(tvMazeEpisode.Runtime.Value).Ticks;
}

episode.Overview = Helpers.StripHtml(tvMazeEpisode.Summary);
episode.Overview = TvHelpers.GetStrippedHtml(tvMazeEpisode.Summary);
episode.SetProviderId(TvMazePlugin.ProviderId, tvMazeEpisode.Id.ToString(CultureInfo.InvariantCulture));

return episode;
Expand Down
41 changes: 28 additions & 13 deletions Jellyfin.Plugin.TvMaze/Providers/TvMazeSeasonImageProvider.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.Collections.Generic;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
Expand All @@ -8,6 +9,7 @@
using MediaBrowser.Controller.Providers;
using MediaBrowser.Model.Entities;
using MediaBrowser.Model.Providers;
using Microsoft.Extensions.Logging;
using TvMaze.Api.Client;

namespace Jellyfin.Plugin.TvMaze.Providers
Expand All @@ -19,14 +21,17 @@ public class TvMazeSeasonImageProvider : IRemoteImageProvider
{
private readonly IHttpClient _httpClient;
private readonly ITvMazeClient _tvMazeClient;
private readonly ILogger<TvMazeSeasonImageProvider> _logger;

/// <summary>
/// Initializes a new instance of the <see cref="TvMazeSeasonImageProvider"/> class.
/// </summary>
/// <param name="httpClient">Instance of the <see cref="IHttpClient"/> interface.</param>
public TvMazeSeasonImageProvider(IHttpClient httpClient)
/// <param name="logger">Instance of the <see cref="ILogger{TvMazeSeasonImageProvider}"/> interface.</param>
public TvMazeSeasonImageProvider(IHttpClient httpClient, ILogger<TvMazeSeasonImageProvider> logger)
{
_httpClient = httpClient;
_logger = logger;
// TODO DI.
_tvMazeClient = new TvMazeClient();
}
Expand All @@ -49,21 +54,31 @@ public IEnumerable<ImageType> GetSupportedImages(BaseItem item)
/// <inheritdoc />
public async Task<IEnumerable<RemoteImageInfo>> GetImages(BaseItem item, CancellationToken cancellationToken)
{
var season = (Season)item;
var series = season.Series;

if (series == null)
try
{
// Invalid link.
return Enumerable.Empty<RemoteImageInfo>();
}
var season = (Season)item;
var series = season.Series;

if (series == null)
{
// Invalid link.
return Enumerable.Empty<RemoteImageInfo>();
}

if (!season.IndexNumber.HasValue)
if (!season.IndexNumber.HasValue)
{
return Enumerable.Empty<RemoteImageInfo>();
}

var imageResults = await GetSeasonImagesInternal(series, season.IndexNumber.Value).ConfigureAwait(false);
_logger.LogInformation("[GetImages] Images found for {name}: {@images}", item.Name, imageResults);
return imageResults;
}
catch (Exception e)
{
_logger.LogWarning(e, "[GetImages]");
return Enumerable.Empty<RemoteImageInfo>();
}

return await GetSeasonImagesInternal(series, season.IndexNumber.Value).ConfigureAwait(false);
}

/// <inheritdoc />
Expand All @@ -78,7 +93,7 @@ public Task<HttpResponseInfo> GetImageResponse(string url, CancellationToken can

private async Task<IEnumerable<RemoteImageInfo>> GetSeasonImagesInternal(IHasProviderIds series, int seasonNumber)
{
var tvMazeId = Helpers.GetTvMazeId(series.ProviderIds);
var tvMazeId = TvHelpers.GetTvMazeId(series.ProviderIds);
if (tvMazeId == null)
{
// Requires series tv maze id.
Expand Down
Loading

0 comments on commit a2c4472

Please sign in to comment.