diff --git a/.github/workflows/build-validation.yml b/.github/workflows/build-validation.yml index 8561d18..f5b1a09 100644 --- a/.github/workflows/build-validation.yml +++ b/.github/workflows/build-validation.yml @@ -9,7 +9,7 @@ on: - '**.csproj' env: - DOTNET_VERSION: '6.0.300' # The .NET SDK version to use + DOTNET_VERSION: '8.0.104' # The .NET SDK version to use jobs: build: diff --git a/Jellyfin.Plugin.YoutubeMetadata.Providers.Tests/Jellyfin.Plugin.YoutubeMetadata.Tests.csproj b/Jellyfin.Plugin.YoutubeMetadata.Providers.Tests/Jellyfin.Plugin.YoutubeMetadata.Tests.csproj index 17ca2b8..ea6ee8e 100644 --- a/Jellyfin.Plugin.YoutubeMetadata.Providers.Tests/Jellyfin.Plugin.YoutubeMetadata.Tests.csproj +++ b/Jellyfin.Plugin.YoutubeMetadata.Providers.Tests/Jellyfin.Plugin.YoutubeMetadata.Tests.csproj @@ -1,16 +1,16 @@ - net6.0 + net8.0 enable false - - - + + + diff --git a/Jellyfin.Plugin.YoutubeMetadata.Providers.Tests/ProviderTests.cs b/Jellyfin.Plugin.YoutubeMetadata.Providers.Tests/ProviderTests.cs index 37aef73..9e1c4d2 100644 --- a/Jellyfin.Plugin.YoutubeMetadata.Providers.Tests/ProviderTests.cs +++ b/Jellyfin.Plugin.YoutubeMetadata.Providers.Tests/ProviderTests.cs @@ -8,14 +8,12 @@ using System.Collections.Generic; using System.Text.Json; using MediaBrowser.Controller.Entities; -using MediaBrowser.Model.Entities; using MediaBrowser.Controller.Entities.Movies; using System.Net.Http; +using Jellyfin.Data.Enums; namespace Jellyfin.Plugin.YoutubeMetadata.Tests { - - public class YTDLEpisodeProviderTest { private readonly Moq.Mock _jf_fs; @@ -66,7 +64,7 @@ public void RemoteProviderCachedResultsTest() _fs.AddFile(@"\cache\youtubemetadata\AAAAAAAAAAA\ytvideo.info.json", new MockFileData(JsonSerializer.Serialize(json))); _epInfo.Path = "/Something [AAAAAAAAAAA].mkv"; - //var provider = new YTDLEpisodeProvider(_jf_fs.Object, new Mock>().Object, _config.Object, _fs); + //var provider = new YTDLEpisodeProvider(_jf_fs.Object, new Mock().Object, new Mock>().Object, _config.Object, _fs); var metadata = _provider.GetMetadata(_epInfo, _token); metadata.Wait(); Assert.Equal(json.title, metadata.Result.Item.Name); @@ -150,7 +148,7 @@ public void YTDLJsonToMovieTest() }, People = new List {new PersonInfo { Name = "ankenyr", - Type = PersonType.Director, + Type = PersonKind.Director, ProviderIds = new Dictionary { { "YoutubeMetadata", "abc123" } } } } } @@ -180,12 +178,13 @@ public void YTDLJsonToMovieTest() }, People = new List {new PersonInfo { Name = "ankenyr", - Type = PersonType.Director, + Type = PersonKind.Director, ProviderIds = new Dictionary { { "YoutubeMetadata", "abc123" } } } } } } }; + [Theory] [MemberData(nameof(MusicJsonTests))] public void YTDLJsonToMusicVideo(YTDLData json, MetadataResult expected) @@ -219,12 +218,13 @@ public void YTDLJsonToMusicVideo(YTDLData json, MetadataResult expec }, People = new List {new PersonInfo { Name = "ankenyr", - Type = PersonType.Director, + Type = PersonKind.Director, ProviderIds = new Dictionary { { "YoutubeMetadata", "abc123" } } } } } } }; + [Theory] [MemberData(nameof(MovieJsonTests))] public void YTDLJsonToMovie(YTDLData json, MetadataResult expected) @@ -232,14 +232,5 @@ public void YTDLJsonToMovie(YTDLData json, MetadataResult expected) var result = JsonSerializer.Serialize(YTDLEpisodeProvider.YTDLJsonToMovie(json, "id123")); Assert.Equal(JsonSerializer.Serialize(expected), result); } - - } - - - - - - - } \ No newline at end of file diff --git a/Jellyfin.Plugin.YoutubeMetadata.Providers.Tests/UtilsTests.cs b/Jellyfin.Plugin.YoutubeMetadata.Providers.Tests/UtilsTests.cs index 81adf0c..73feb3d 100644 --- a/Jellyfin.Plugin.YoutubeMetadata.Providers.Tests/UtilsTests.cs +++ b/Jellyfin.Plugin.YoutubeMetadata.Providers.Tests/UtilsTests.cs @@ -1,16 +1,15 @@ using Xunit; -using Jellyfin.Plugin.YoutubeMetadata; using MediaBrowser.Controller.Entities; -using MediaBrowser.Model.Entities; using Newtonsoft.Json; using MediaBrowser.Controller; using Moq; using System.Collections.Generic; -using System.IO.Abstractions.TestingHelpers; -using System.Threading; using MediaBrowser.Controller.Providers; using MediaBrowser.Controller.Entities.Movies; using System; +using System.IO; +using Jellyfin.Data.Enums; +using Jellyfin.Plugin.YoutubeMetadata; namespace Jellyfin.Plugin.YoutubeMetadata.Tests { @@ -23,38 +22,37 @@ public class UtilsTest public void GetYTIDTest(string fn, string expected) { Assert.Equal(expected, Utils.GetYTID(fn)); - - } [Fact] public void CreatePersonTest() { var result = Utils.CreatePerson("3Blue1Brown", "UCYO_jab_esuFRV4b17AJtAw"); - var expected = new PersonInfo { Name = "3Blue1Brown", Type = PersonType.Director, ProviderIds = new Dictionary { { "YoutubeMetadata", "UCYO_jab_esuFRV4b17AJtAw" } } }; - + var expected = new PersonInfo { Name = "3Blue1Brown", Type = PersonKind.Director, ProviderIds = new Dictionary { { "YoutubeMetadata", "UCYO_jab_esuFRV4b17AJtAw" } } }; Assert.Equal(JsonConvert.SerializeObject(expected), JsonConvert.SerializeObject(result)); } + [Fact] public void GetVideoInfoPathTest() { - var mockAppPath = Mock.Of(a => - a.CachePath == @"\foo\bar"); - + var mockAppPath = Mock.Of(a => a.CachePath == Path.Combine("foo", "bar").ToString()); + var result = Utils.GetVideoInfoPath(mockAppPath, "id123"); - Assert.Equal(@"\foo\bar\youtubemetadata\id123\ytvideo.info.json", result); + Assert.Equal(Path.Combine("foo", "bar", "youtubemetadata", "id123", "ytvideo.info.json").ToString(), result); } [Fact] public void YTDLJsonToMovieTest() { - var data = new YTDLData { + var data = new YTDLData + { title = "Foo", description = "Some cool movie!", upload_date = "20220131", uploader = "SomeGuyIKnow", - channel_id = "ABCDEFGHIJKLMNOPQRSTUVWX" }; + channel_id = "ABCDEFGHIJKLMNOPQRSTUVWX" + }; var result = Utils.YTDLJsonToMovie(data); var person = new PersonInfo { @@ -78,7 +76,7 @@ public void YTDLJsonToMovieTest() Assert.Equal("Foo", result.Item.Name); Assert.Equal("Some cool movie!", result.Item.Overview); Assert.Equal(2022, result.Item.ProductionYear); - Assert.Equal("1/31/2022 12:00:00 AM", result.Item.PremiereDate.ToString()); + Assert.Equal("1/31/2022 12:00:00 AM", result.Item.PremiereDate.ToString()); Assert.Equal("SomeGuyIKnow", result.People[0].Name); Assert.Equal("ABCDEFGHIJKLMNOPQRSTUVWX", result.People[0].ProviderIds["YoutubeMetadata"]); } @@ -105,7 +103,7 @@ public void YTDLJsonToMusicTest() Assert.Equal("Foo", result.Item.Name); Assert.Equal("Some cool movie!", result.Item.Overview); Assert.Equal(2022, result.Item.ProductionYear); - Assert.Equal("1/31/2022 12:00:00 AM", result.Item.PremiereDate.ToString()); + Assert.Equal("1/31/2022 12:00:00 AM", result.Item.PremiereDate.ToString()); Assert.Equal("SomeGuyIKnow", result.People[0].Name); Assert.Equal("ABCDEFGHIJKLMNOPQRSTUVWX", result.People[0].ProviderIds["YoutubeMetadata"]); } @@ -133,7 +131,7 @@ public void YTDLJsonToMusicWithTrackTest() Assert.Equal("Bar", result.Item.Name); Assert.Equal("Some cool movie!", result.Item.Overview); Assert.Equal(2022, result.Item.ProductionYear); - Assert.Equal("1/31/2022 12:00:00 AM", result.Item.PremiereDate.ToString()); + Assert.Equal("1/31/2022 12:00:00 AM", result.Item.PremiereDate.ToString()); Assert.Equal("SomeGuyIKnow", result.People[0].Name); Assert.Equal("ABCDEFGHIJKLMNOPQRSTUVWX", result.People[0].ProviderIds["YoutubeMetadata"]); } @@ -160,7 +158,7 @@ public void YTDLJsonToEpisodeTest() Assert.Equal("Foo", result.Item.Name); Assert.Equal("Some cool movie!", result.Item.Overview); Assert.Equal(2022, result.Item.ProductionYear); - Assert.Equal("1/31/2022 12:00:00 AM", result.Item.PremiereDate.ToString()); + Assert.Equal("1/31/2022 12:00:00 AM", result.Item.PremiereDate.ToString()); Assert.Equal("SomeGuyIKnow", result.People[0].Name); Assert.Equal("ABCDEFGHIJKLMNOPQRSTUVWX", result.People[0].ProviderIds["YoutubeMetadata"]); Assert.Equal("20220131-Foo", result.Item.ForcedSortName); @@ -187,5 +185,4 @@ public void YTDLJsonToSeriesTest() Assert.Equal("ABCDEFGHIJKLMNOPQRSTUVWX", result.Item.ProviderIds["YoutubeMetadata"]); } } - } \ No newline at end of file diff --git a/Jellyfin.Plugin.YoutubeMetadata/Jellyfin.Plugin.YoutubeMetadata.csproj b/Jellyfin.Plugin.YoutubeMetadata/Jellyfin.Plugin.YoutubeMetadata.csproj index 1b7b15d..9520c3f 100644 --- a/Jellyfin.Plugin.YoutubeMetadata/Jellyfin.Plugin.YoutubeMetadata.csproj +++ b/Jellyfin.Plugin.YoutubeMetadata/Jellyfin.Plugin.YoutubeMetadata.csproj @@ -1,10 +1,10 @@  - net6.0 + net8.0 Jellyfin.Plugin.YoutubeMetadata - 1.0.3.8 - 1.0.3.8 - 1.0.3.9 + 1.0.4.0 + 1.0.4.0 + 1.0.4.0 @@ -14,11 +14,11 @@ - - - - - - + + + + + + - + \ No newline at end of file diff --git a/Jellyfin.Plugin.YoutubeMetadata/Plugin.cs b/Jellyfin.Plugin.YoutubeMetadata/Plugin.cs index d5208a5..2b9cb74 100644 --- a/Jellyfin.Plugin.YoutubeMetadata/Plugin.cs +++ b/Jellyfin.Plugin.YoutubeMetadata/Plugin.cs @@ -10,6 +10,8 @@ using MediaBrowser.Model.Plugins; using MediaBrowser.Model.Serialization; using Microsoft.Extensions.DependencyInjection; +using MediaBrowser.Controller; +using MediaBrowser.Controller.Plugins; namespace Jellyfin.Plugin.YoutubeMetadata { @@ -19,6 +21,7 @@ public class Plugin : BasePlugin, IHasWebPages public override Guid Id => Guid.Parse(Constants.PluginGuid); IHttpClientFactory _httpClientFactory; + public Plugin(IApplicationPaths applicationPaths, IXmlSerializer xmlSerializer, IHttpClientFactory httpClientFactory) : base(applicationPaths, xmlSerializer) { Instance = this; @@ -34,6 +37,7 @@ public HttpClient GetHttpClient() return httpClient; } + public IEnumerable GetPages() { return new[] @@ -53,9 +57,9 @@ public IEnumerable GetPages() public class PluginServiceRegistrator : IPluginServiceRegistrator { /// - public void RegisterServices(IServiceCollection serviceCollection) + public void RegisterServices(IServiceCollection serviceCollection, IServerApplicationHost applicationHost) { serviceCollection.AddScoped(); } } -} +} \ No newline at end of file diff --git a/Jellyfin.Plugin.YoutubeMetadata/Utils.cs b/Jellyfin.Plugin.YoutubeMetadata/Utils.cs index 7552172..ec1bce6 100644 --- a/Jellyfin.Plugin.YoutubeMetadata/Utils.cs +++ b/Jellyfin.Plugin.YoutubeMetadata/Utils.cs @@ -3,7 +3,6 @@ using MediaBrowser.Controller.Entities.Movies; using MediaBrowser.Controller.Entities.TV; using MediaBrowser.Controller.Providers; -using MediaBrowser.Model.Entities; using NYoutubeDL; using System; using System.Collections.Generic; @@ -12,6 +11,7 @@ using System.Text.RegularExpressions; using System.Threading; using System.Threading.Tasks; +using Jellyfin.Data.Enums; namespace Jellyfin.Plugin.YoutubeMetadata { @@ -52,7 +52,7 @@ public static PersonInfo CreatePerson(string name, string channel_id) return new PersonInfo { Name = name, - Type = PersonType.Director, + Type = PersonKind.Director, ProviderIds = new Dictionary { { Constants.PluginName, channel_id } }, }; @@ -70,7 +70,7 @@ public static string GetVideoInfoPath(IServerApplicationPaths appPaths, string y return Path.Combine(dataPath, "ytvideo.info.json"); } - public static async Task SearchChannel (string query, IServerApplicationPaths appPaths, CancellationToken cancellationToken) + public static async Task SearchChannel(string query, IServerApplicationPaths appPaths, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); var ytd = new YoutubeDLP(); @@ -100,6 +100,7 @@ public static async Task SearchChannel (string query, IServerApplication return null; } } + public static async Task ValidCookie(IServerApplicationPaths appPaths, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); @@ -115,7 +116,7 @@ public static async Task ValidCookie(IServerApplicationPaths appPaths, Can ytd.Options.FilesystemOptions.Cookies = cookie_file; } await task; - + foreach (string err in ytdl_errs) { var match = Regex.Match(err, @".*The playlist does not exist\..*"); @@ -126,6 +127,7 @@ public static async Task ValidCookie(IServerApplicationPaths appPaths, Can } return true; } + public static async Task GetChannelInfo(string id, string name, IServerApplicationPaths appPaths, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); @@ -144,6 +146,7 @@ public static async Task GetChannelInfo(string id, string name, IServerApplicati var task = ytd.DownloadAsync(String.Format(Constants.ChannelUrl, id)); await task; } + public static async Task YTDLMetadata(string id, IServerApplicationPaths appPaths, CancellationToken cancellationToken) { //var foo = await ValidCookie(appPaths, cancellationToken); @@ -152,19 +155,21 @@ public static async Task YTDLMetadata(string id, IServerApplicationPaths appPath ytd.Options.FilesystemOptions.WriteInfoJson = true; ytd.Options.VerbositySimulationOptions.SkipDownload = true; var cookie_file = Path.Join(appPaths.PluginsPath, "YoutubeMetadata", "cookies.txt"); - if ( File.Exists(cookie_file) ) { + if (File.Exists(cookie_file)) + { ytd.Options.FilesystemOptions.Cookies = cookie_file; } - + var dlstring = "https://www.youtube.com/watch?v=" + id; var dataPath = Path.Combine(appPaths.CachePath, "youtubemetadata", id, "ytvideo"); ytd.Options.FilesystemOptions.Output = dataPath; - + List ytdl_errs = new(); ytd.StandardErrorEvent += (sender, error) => ytdl_errs.Add(error); var task = ytd.DownloadAsync(dlstring); await task; } + /// /// Reads JSON data from file. /// @@ -272,6 +277,7 @@ public static MetadataResult YTDLJsonToEpisode(YTDLData json) result.Item.ParentIndexNumber = 1; return result; } + /// /// Provides a MusicVideo Metadata Result from a json object. /// @@ -291,5 +297,4 @@ public static MetadataResult YTDLJsonToSeries(YTDLData json) return result; } } - -} +} \ No newline at end of file diff --git a/build.yaml b/build.yaml index d8d1cbb..b8cd725 100644 --- a/build.yaml +++ b/build.yaml @@ -2,18 +2,14 @@ name: "YouTube Metadata" guid: "b4b4353e-dc57-4398-82c1-de9079e7146a" version: "1.0.3.2" -targetAbi: "10.7.0.0" +targetAbi: "10.9.1.0" owner: "ankenyr" overview: "YouTube metadata provider" description: "Provides YouTube metadata from the YouTube API and Youtube-dl metadata files." category: "Metadata" artifacts: - "Jellyfin.Plugin.YoutubeMetadata.dll" -- "Newtonsoft.Json.dll" -- "Google.Apis.dll" -- "Google.Apis.Core.dll" -- "Google.Apis.Auth.dll" -- "Google.Apis.Auth.PlatformServices.dll" -- "Google.Apis.YouTube.v3.dll" +- "NYoutubeDLP.dll" +- "System.IO.Abstractions.dll" changelog: > changelog