Implement basic metadata and image providers for episodes
This commit is contained in:
@@ -14,5 +14,10 @@ namespace Jellyfin.Plugin.TubeArchivistMetadata
|
|||||||
/// Plugin GUID.
|
/// Plugin GUID.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public const string PluginGuid = "dc97d0c6-28b0-4242-afb4-5833ae1b3715";
|
public const string PluginGuid = "dc97d0c6-28b0-4242-afb4-5833ae1b3715";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Providers name.
|
||||||
|
/// </summary>
|
||||||
|
public const string ProviderName = "TubeArchivist";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,6 +13,7 @@
|
|||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Jellyfin.Controller" Version="10.8.13" />
|
<PackageReference Include="Jellyfin.Controller" Version="10.8.13" />
|
||||||
<PackageReference Include="Jellyfin.Model" Version="10.8.13" />
|
<PackageReference Include="Jellyfin.Model" Version="10.8.13" />
|
||||||
|
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
|
using System.Net.Http;
|
||||||
using Jellyfin.Plugin.TubeArchivistMetadata.Configuration;
|
using Jellyfin.Plugin.TubeArchivistMetadata.Configuration;
|
||||||
using MediaBrowser.Common.Configuration;
|
using MediaBrowser.Common.Configuration;
|
||||||
using MediaBrowser.Common.Plugins;
|
using MediaBrowser.Common.Plugins;
|
||||||
@@ -23,6 +24,11 @@ namespace Jellyfin.Plugin.TubeArchivistMetadata
|
|||||||
: base(applicationPaths, xmlSerializer)
|
: base(applicationPaths, xmlSerializer)
|
||||||
{
|
{
|
||||||
Instance = this;
|
Instance = this;
|
||||||
|
HttpClientHandler handler = new HttpClientHandler();
|
||||||
|
handler.AllowAutoRedirect = false;
|
||||||
|
handler.CheckCertificateRevocationList = true;
|
||||||
|
HttpClient = new HttpClient(handler);
|
||||||
|
HttpClient.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Token", Instance?.Configuration.TubeArchivistApiKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
@@ -36,6 +42,11 @@ namespace Jellyfin.Plugin.TubeArchivistMetadata
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public static Plugin? Instance { get; private set; }
|
public static Plugin? Instance { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the HTTP client used globally in the plugin.
|
||||||
|
/// </summary>
|
||||||
|
public HttpClient HttpClient { get; }
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public IEnumerable<PluginPageInfo> GetPages() => new[]
|
public IEnumerable<PluginPageInfo> GetPages() => new[]
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -0,0 +1,71 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Data;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Net.Http;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Jellyfin.Plugin.TubeArchivistMetadata.TubeArchivist;
|
||||||
|
using MediaBrowser.Controller.Entities;
|
||||||
|
using MediaBrowser.Controller.Entities.TV;
|
||||||
|
using MediaBrowser.Controller.Providers;
|
||||||
|
using MediaBrowser.Model.Entities;
|
||||||
|
using MediaBrowser.Model.Providers;
|
||||||
|
|
||||||
|
namespace Jellyfin.Plugin.TubeArchivistMetadata.Providers
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Image provider which interacts with TubeArchivist library.
|
||||||
|
/// </summary>
|
||||||
|
public class EpisodeImageProvider : IRemoteImageProvider
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the provider name.
|
||||||
|
/// </summary>
|
||||||
|
public string Name => "TubeArchivist";
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public bool Supports(BaseItem item) => item is Episode;
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public IEnumerable<ImageType> GetSupportedImages(BaseItem item)
|
||||||
|
{
|
||||||
|
return new[] { ImageType.Primary };
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public async Task<IEnumerable<RemoteImageInfo>> GetImages(BaseItem item, CancellationToken cancellationToken)
|
||||||
|
{
|
||||||
|
var list = new List<RemoteImageInfo>();
|
||||||
|
var taApi = TubeArchivistApi.GetInstance();
|
||||||
|
var videoTAId = item.Path.Split("/").Last().Split(".").First();
|
||||||
|
var video = await taApi.GetVideo(videoTAId).ConfigureAwait(true);
|
||||||
|
|
||||||
|
if (video != null)
|
||||||
|
{
|
||||||
|
list.Add(new RemoteImageInfo
|
||||||
|
{
|
||||||
|
ProviderName = Name,
|
||||||
|
Type = ImageType.Primary,
|
||||||
|
Url = video.VidThumbUrl
|
||||||
|
});
|
||||||
|
Console.WriteLine("ThumbURL: " + video.VidThumbUrl);
|
||||||
|
}
|
||||||
|
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public async Task<HttpResponseMessage> GetImageResponse(string url, CancellationToken cancellationToken)
|
||||||
|
{
|
||||||
|
if (Plugin.Instance == null)
|
||||||
|
{
|
||||||
|
throw new DataException("Uninitialized plugin!");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return await Plugin.Instance.HttpClient.GetAsync(new Uri(Plugin.Instance.Configuration.TubeArchivistUrl + url), cancellationToken).ConfigureAwait(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,87 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Data;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Net.Http;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Jellyfin.Plugin.TubeArchivistMetadata.TubeArchivist;
|
||||||
|
using MediaBrowser.Controller.Entities;
|
||||||
|
using MediaBrowser.Controller.Entities.TV;
|
||||||
|
using MediaBrowser.Controller.Providers;
|
||||||
|
using MediaBrowser.Model.Entities;
|
||||||
|
using MediaBrowser.Model.Providers;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
|
namespace Jellyfin.Plugin.TubeArchivistMetadata.Providers
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Metadata provider which interacts with TubeArchivist library.
|
||||||
|
/// </summary>
|
||||||
|
public class EpisodeMetadataProvider : IRemoteMetadataProvider<Episode, EpisodeInfo>
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the provider name.
|
||||||
|
/// </summary>
|
||||||
|
public string Name => "TubeArchivist";
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public async Task<MetadataResult<Episode>> GetMetadata(EpisodeInfo info, CancellationToken cancellationToken)
|
||||||
|
{
|
||||||
|
var result = new MetadataResult<Episode>();
|
||||||
|
var taApi = TubeArchivistApi.GetInstance();
|
||||||
|
var videoTAId = info.Path.Split("/").Last().Split(".").First();
|
||||||
|
var video = await taApi.GetVideo(videoTAId).ConfigureAwait(true);
|
||||||
|
Console.WriteLine("Metadata video received: ");
|
||||||
|
Console.WriteLine(JsonConvert.SerializeObject(video));
|
||||||
|
Console.WriteLine("Media YT id: " + videoTAId);
|
||||||
|
|
||||||
|
if (video != null)
|
||||||
|
{
|
||||||
|
var peopleInfo = new List<PersonInfo>();
|
||||||
|
PeopleHelper.AddPerson(peopleInfo, new PersonInfo
|
||||||
|
{
|
||||||
|
Name = video.Channel.Name,
|
||||||
|
ImageUrl = video.Channel.ThumbUrl,
|
||||||
|
Type = PersonType.Actor,
|
||||||
|
});
|
||||||
|
result.HasMetadata = true;
|
||||||
|
result.Item = video.ToEpisode();
|
||||||
|
result.Provider = Name;
|
||||||
|
result.People = peopleInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
Console.WriteLine(result.Item.ProductionYear);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public async Task<IEnumerable<RemoteSearchResult>> GetSearchResults(EpisodeInfo searchInfo, CancellationToken cancellationToken)
|
||||||
|
{
|
||||||
|
var results = new List<RemoteSearchResult>();
|
||||||
|
|
||||||
|
var taApi = TubeArchivistApi.GetInstance();
|
||||||
|
var videoTAId = searchInfo.Path.Split("/").Last().Split(".").First();
|
||||||
|
var video = await taApi.GetVideo(videoTAId).ConfigureAwait(true);
|
||||||
|
if (video != null)
|
||||||
|
{
|
||||||
|
results.Add(video.ToSearchResult());
|
||||||
|
}
|
||||||
|
|
||||||
|
return results;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public async Task<HttpResponseMessage> GetImageResponse(string url, CancellationToken cancellationToken)
|
||||||
|
{
|
||||||
|
if (Plugin.Instance == null)
|
||||||
|
{
|
||||||
|
throw new DataException("Uninitialized plugin!");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return await Plugin.Instance.HttpClient.GetAsync(url, cancellationToken).ConfigureAwait(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,71 @@
|
|||||||
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
|
namespace Jellyfin.Plugin.TubeArchivistMetadata.TubeArchivist
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// A class representing TubeArchivist API channel data.
|
||||||
|
/// </summary>
|
||||||
|
public class Channel
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the <see cref="Channel"/> class.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="bannerUrl">URL of the channel banner image.</param>
|
||||||
|
/// <param name="description">Channel description.</param>
|
||||||
|
/// <param name="id">Channel YouTube id.</param>
|
||||||
|
/// <param name="name">Channel name.</param>
|
||||||
|
/// <param name="thumbUrl">URL of the channel thumb image.</param>
|
||||||
|
/// <param name="tvartUrl">URL of the channel tvart image.</param>
|
||||||
|
public Channel(
|
||||||
|
string bannerUrl,
|
||||||
|
string description,
|
||||||
|
string id,
|
||||||
|
string name,
|
||||||
|
string thumbUrl,
|
||||||
|
string tvartUrl)
|
||||||
|
{
|
||||||
|
this.BannerUrl = bannerUrl;
|
||||||
|
this.Description = description;
|
||||||
|
this.Id = id;
|
||||||
|
this.Name = name;
|
||||||
|
this.ThumbUrl = thumbUrl;
|
||||||
|
this.TvartUrl = tvartUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the URL of the channel banner image.
|
||||||
|
/// </summary>
|
||||||
|
[JsonProperty(PropertyName = "channel_banner_url")]
|
||||||
|
public string BannerUrl { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the channel description.
|
||||||
|
/// </summary>
|
||||||
|
[JsonProperty(PropertyName = "channel_description")]
|
||||||
|
public string Description { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the channel YouTube id.
|
||||||
|
/// </summary>
|
||||||
|
[JsonProperty(PropertyName = "channel_id")]
|
||||||
|
public string Id { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the channel name.
|
||||||
|
/// </summary>
|
||||||
|
[JsonProperty(PropertyName = "channel_name")]
|
||||||
|
public string Name { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the URL of the channel thumb image.
|
||||||
|
/// </summary>
|
||||||
|
[JsonProperty(PropertyName = "channel_thumb_url")]
|
||||||
|
public string ThumbUrl { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the URL of the channel tvart image.
|
||||||
|
/// </summary>
|
||||||
|
[JsonProperty(PropertyName = "channel_tvart_url")]
|
||||||
|
public string TvartUrl { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
namespace Jellyfin.Plugin.TubeArchivistMetadata.TubeArchivist
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Class representing the base common structure of TubeArchivist API responses.
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="T">The contained data type.</typeparam>
|
||||||
|
public class ResponseContainer<T>
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the contained data object.
|
||||||
|
/// </summary>
|
||||||
|
public T? Data { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,124 @@
|
|||||||
|
using System;
|
||||||
|
using System.Data;
|
||||||
|
using System.Net;
|
||||||
|
using System.Net.Http;
|
||||||
|
using System.Net.Http.Headers;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
|
namespace Jellyfin.Plugin.TubeArchivistMetadata.TubeArchivist
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Class to interact with TubeArchivist API.
|
||||||
|
/// </summary>
|
||||||
|
public class TubeArchivistApi
|
||||||
|
{
|
||||||
|
private HttpClient client;
|
||||||
|
private static TubeArchivistApi _taApiInstance = null!;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the <see cref="TubeArchivistApi"/> class.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="httpClient">HTTP client to make requests to TubeArchivist API.</param>
|
||||||
|
private TubeArchivistApi(HttpClient httpClient)
|
||||||
|
{
|
||||||
|
client = httpClient;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the instance of the <see cref="TubeArchivistApi"/> class.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>The TubeArchivistApi instance.</returns>
|
||||||
|
public static TubeArchivistApi GetInstance()
|
||||||
|
{
|
||||||
|
if (_taApiInstance == null)
|
||||||
|
{
|
||||||
|
if (Plugin.Instance != null)
|
||||||
|
{
|
||||||
|
_taApiInstance = new TubeArchivistApi(Plugin.Instance.HttpClient);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw new DataException("Uninitialized plugin!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return _taApiInstance;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Retrieves the given channel information from TubeArchivist.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="channelId">YouTube channel id.</param>
|
||||||
|
/// <returns>A task.</returns>
|
||||||
|
public async Task<Channel?> GetChannel(string channelId)
|
||||||
|
{
|
||||||
|
ResponseContainer<Channel>? channel = null;
|
||||||
|
Console.WriteLine(Plugin.Instance?.Configuration.TubeArchivistUrl);
|
||||||
|
Console.WriteLine(Plugin.Instance?.Configuration.TubeArchivistApiKey);
|
||||||
|
|
||||||
|
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Token", Plugin.Instance?.Configuration.TubeArchivistApiKey);
|
||||||
|
|
||||||
|
var channelsEndpoint = "/api/channel/";
|
||||||
|
var url = new Uri(Plugin.Instance?.Configuration.TubeArchivistUrl + channelsEndpoint + channelId);
|
||||||
|
var response = await client.GetAsync(url).ConfigureAwait(true);
|
||||||
|
Console.WriteLine(response.StatusCode);
|
||||||
|
while (response.StatusCode == HttpStatusCode.Moved)
|
||||||
|
{
|
||||||
|
Console.WriteLine("Received redirect to: " + response.Headers.Location);
|
||||||
|
response = await client.GetAsync(response.Headers.Location).ConfigureAwait(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
Console.WriteLine(url + ": " + response.StatusCode);
|
||||||
|
|
||||||
|
if (response.IsSuccessStatusCode)
|
||||||
|
{
|
||||||
|
string rawData = await response.Content.ReadAsStringAsync().ConfigureAwait(true);
|
||||||
|
channel = JsonConvert.DeserializeObject<ResponseContainer<Channel>>(rawData);
|
||||||
|
|
||||||
|
Console.WriteLine("Channel null? " + channel == null);
|
||||||
|
Console.WriteLine("Channel: " + channel?.Data?.Name);
|
||||||
|
if (channel != null && channel.Data != null)
|
||||||
|
{
|
||||||
|
Console.WriteLine(JsonConvert.SerializeObject(channel));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return channel?.Data;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Retrieves the given video information from TubeArchivist.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="videoId">YouTube video id.</param>
|
||||||
|
/// <returns>A task.</returns>
|
||||||
|
public async Task<Video?> GetVideo(string videoId)
|
||||||
|
{
|
||||||
|
ResponseContainer<Video>? video = null;
|
||||||
|
Console.WriteLine(Plugin.Instance?.Configuration.TubeArchivistUrl);
|
||||||
|
Console.WriteLine(Plugin.Instance?.Configuration.TubeArchivistApiKey);
|
||||||
|
|
||||||
|
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Token", Plugin.Instance?.Configuration.TubeArchivistApiKey);
|
||||||
|
|
||||||
|
var videosEndpoint = "/api/video/";
|
||||||
|
var url = new Uri(Plugin.Instance?.Configuration.TubeArchivistUrl + videosEndpoint + videoId);
|
||||||
|
var response = await client.GetAsync(url).ConfigureAwait(true);
|
||||||
|
Console.WriteLine(response.StatusCode);
|
||||||
|
while (response.StatusCode == HttpStatusCode.Moved)
|
||||||
|
{
|
||||||
|
Console.WriteLine("Received redirect to: " + response.Headers.Location);
|
||||||
|
response = await client.GetAsync(response.Headers.Location).ConfigureAwait(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
Console.WriteLine(url + ": " + response.StatusCode);
|
||||||
|
|
||||||
|
if (response.IsSuccessStatusCode)
|
||||||
|
{
|
||||||
|
string rawData = await response.Content.ReadAsStringAsync().ConfigureAwait(true);
|
||||||
|
video = JsonConvert.DeserializeObject<ResponseContainer<Video>>(rawData);
|
||||||
|
}
|
||||||
|
|
||||||
|
return video?.Data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,122 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Globalization;
|
||||||
|
using MediaBrowser.Controller.Entities;
|
||||||
|
using MediaBrowser.Controller.Entities.TV;
|
||||||
|
using MediaBrowser.Model.Entities;
|
||||||
|
using MediaBrowser.Model.Providers;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
|
namespace Jellyfin.Plugin.TubeArchivistMetadata.TubeArchivist
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// A class representing TubeArchivist API video data.
|
||||||
|
/// </summary>
|
||||||
|
public class Video
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the <see cref="Video"/> class.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="channel">Channel the video belongs to.</param>
|
||||||
|
/// <param name="title">Video title.</param>
|
||||||
|
/// <param name="description">Video description.</param>
|
||||||
|
/// <param name="published">Video published date.</param>
|
||||||
|
/// <param name="vidThumbUrl">Video thuumb image URL.</param>
|
||||||
|
/// <param name="youtubeId">Video YouTube id.</param>
|
||||||
|
public Video(
|
||||||
|
Channel channel,
|
||||||
|
string title,
|
||||||
|
string description,
|
||||||
|
DateTime published,
|
||||||
|
string vidThumbUrl,
|
||||||
|
string youtubeId)
|
||||||
|
{
|
||||||
|
this.Channel = channel;
|
||||||
|
this.Title = title;
|
||||||
|
this.Description = description;
|
||||||
|
this.Published = published;
|
||||||
|
this.VidThumbUrl = vidThumbUrl;
|
||||||
|
this.YoutubeId = youtubeId;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the channel info.
|
||||||
|
/// </summary>
|
||||||
|
[JsonProperty(PropertyName = "channel")]
|
||||||
|
public Channel Channel { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets video title.
|
||||||
|
/// </summary>
|
||||||
|
[JsonProperty(PropertyName = "title")]
|
||||||
|
public string Title { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets video description.
|
||||||
|
/// </summary>
|
||||||
|
[JsonProperty(PropertyName = "description")]
|
||||||
|
public string Description { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets video published date.
|
||||||
|
/// </summary>
|
||||||
|
[JsonProperty(PropertyName = "published")]
|
||||||
|
public DateTime Published { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets video thumb image URL.
|
||||||
|
/// </summary>
|
||||||
|
[JsonProperty(PropertyName = "vid_thumb_url")]
|
||||||
|
public string VidThumbUrl { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets video YouTube id.
|
||||||
|
/// </summary>
|
||||||
|
[JsonProperty(PropertyName = "youtube_id")]
|
||||||
|
public string YoutubeId { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Converts the TubeArchivist API video to a Jellyfin <see cref="RemoteSearchResult"/> object.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>The video equivalent Jellyfin <see cref="RemoteSearchResult"/> object.</returns>
|
||||||
|
public RemoteSearchResult ToSearchResult()
|
||||||
|
{
|
||||||
|
return new RemoteSearchResult
|
||||||
|
{
|
||||||
|
Name = Title,
|
||||||
|
SearchProviderName = Constants.ProviderName,
|
||||||
|
ProductionYear = Published.Year,
|
||||||
|
ImageUrl = VidThumbUrl,
|
||||||
|
ProviderIds = new Dictionary<string, string>() { { Constants.ProviderName, YoutubeId } }
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Converts the TubeArchivist API video to a Jellyfin <see cref="Episode"/> object.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>The video equivalent Jellyfin <see cref="Episode"/> object.</returns>
|
||||||
|
public Episode ToEpisode()
|
||||||
|
{
|
||||||
|
return new Episode
|
||||||
|
{
|
||||||
|
Name = Title,
|
||||||
|
SeasonName = Published.Year.ToString(CultureInfo.CurrentCulture),
|
||||||
|
SeriesName = Channel.Name,
|
||||||
|
ProviderIds = new Dictionary<string, string>()
|
||||||
|
{
|
||||||
|
{
|
||||||
|
Constants.ProviderName, YoutubeId
|
||||||
|
}
|
||||||
|
},
|
||||||
|
ImageInfos = new[]
|
||||||
|
{
|
||||||
|
new ItemImageInfo
|
||||||
|
{
|
||||||
|
Path = VidThumbUrl,
|
||||||
|
Type = ImageType.Primary
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user