(((JsonResult)result).Value?.GetType().GetProperty("items")?.GetValue(((JsonResult)result).Value, null));
+
+ // ensure int values are 0
+ Assert.Equal(0, ((JsonResult)result).Value?.GetType().GetProperty("media_count")?.GetValue(((JsonResult)result).Value, null));
+ Assert.Equal(0, ((JsonResult)result).Value?.GetType().GetProperty("media_percent_complete")?.GetValue(((JsonResult)result).Value, null));
+
+ // ensure array list has no items
+ Assert.Equal(0, (((JsonResult)result).Value?.GetType().GetProperty("items")?.GetValue(((JsonResult)result).Value, null) as ArrayList)?.Count);
+
+ // todo: add tests for when there are items
+ }
+}
diff --git a/Jellyfin.Plugin.Themerr.Tests/TestThemerrManager.cs b/Jellyfin.Plugin.Themerr.Tests/TestThemerrManager.cs
index 4077330..be122ab 100644
--- a/Jellyfin.Plugin.Themerr.Tests/TestThemerrManager.cs
+++ b/Jellyfin.Plugin.Themerr.Tests/TestThemerrManager.cs
@@ -197,6 +197,18 @@ private void TestSaveMp3InvalidUrl()
Assert.False(File.Exists(destinationFile), $"File {destinationFile} exists");
}
+ [Fact]
+ [Trait("Category", "Unit")]
+ private void TestGetMoviesFromLibrary()
+ {
+ var movies = _themerrManager.GetMoviesFromLibrary();
+
+ // movies list should be empty
+ Assert.Empty(movies);
+
+ // todo: test with actual movies
+ }
+
// todo: fix this test
// [Fact]
// [Trait("Category", "Unit")]
@@ -216,6 +228,46 @@ private void TestSaveMp3InvalidUrl()
// }
// }
+ [Fact]
+ [Trait("Category", "Unit")]
+ private void TestGetTmdbId()
+ {
+ // get fixture movies
+ var mockMovies = FixtureJellyfinServer.MockMovies();
+
+ foreach (var movie in mockMovies)
+ {
+ // get the movie theme
+ var tmdbId = _themerrManager.GetTmdbId(movie);
+
+ // ensure tmdbId is not empty
+ Assert.NotEmpty(tmdbId);
+
+ // ensure tmdbId is the same as the one in the movie fixture
+ Assert.Equal(movie.ProviderIds[MetadataProvider.Tmdb.ToString()], tmdbId);
+ }
+ }
+
+ // todo: fix this test
+ // [Fact]
+ // [Trait("Category", "Unit")]
+ // private void TestGetThemeProvider()
+ // {
+ // // get fixture movies
+ // var mockMovies = FixtureJellyfinServer.MockMovies();
+ //
+ // foreach (var movie in mockMovies)
+ // {
+ // // get the movie theme
+ // var themeProvider = _themerrManager.GetThemeProvider(movie);
+ //
+ // // ensure themeProvider null
+ // Assert.Null(themeProvider);
+ // }
+ //
+ // // todo: test with actual movies
+ // }
+
[Fact]
[Trait("Category", "Unit")]
private void TestContinueDownload()
diff --git a/Jellyfin.Plugin.Themerr.Tests/TestThemerrPlugin.cs b/Jellyfin.Plugin.Themerr.Tests/TestThemerrPlugin.cs
index 5b61644..8d5d32b 100644
--- a/Jellyfin.Plugin.Themerr.Tests/TestThemerrPlugin.cs
+++ b/Jellyfin.Plugin.Themerr.Tests/TestThemerrPlugin.cs
@@ -29,6 +29,7 @@ public TestThemerrPlugin(ITestOutputHelper output)
/// Test getting the plugin name.
///
[Fact]
+ [Trait("Category", "Unit")]
public void TestPluginInstance()
{
Assert.NotNull(_plugin.Name);
@@ -39,6 +40,7 @@ public void TestPluginInstance()
/// Test getting the plugin description.
///
[Fact]
+ [Trait("Category", "Unit")]
public void TestPluginDescription()
{
Assert.NotNull(_plugin.Description);
@@ -49,6 +51,7 @@ public void TestPluginDescription()
/// Test get the plugin id.
///
[Fact]
+ [Trait("Category", "Unit")]
public void TestPluginId()
{
Assert.Equal(new Guid("84b59a39-bde4-42f4-adbd-c39882cbb772"), _plugin.Id);
@@ -58,6 +61,7 @@ public void TestPluginId()
/// Test getting the plugin configuration page.
///
[Fact]
+ [Trait("Category", "Unit")]
public void TestPluginConfigurationPage()
{
var pages = _plugin.GetPages();
diff --git a/Jellyfin.Plugin.Themerr/Api/ThemerrController.cs b/Jellyfin.Plugin.Themerr/Api/ThemerrController.cs
index 5c60a76..15668ad 100644
--- a/Jellyfin.Plugin.Themerr/Api/ThemerrController.cs
+++ b/Jellyfin.Plugin.Themerr/Api/ThemerrController.cs
@@ -1,10 +1,15 @@
+using System;
+using System.Collections;
+using System.Linq;
using System.Net.Mime;
using System.Threading.Tasks;
+using MediaBrowser.Controller.Entities.Movies;
using MediaBrowser.Controller.Library;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
+using Newtonsoft.Json;
namespace Jellyfin.Plugin.Themerr.Api
{
@@ -48,5 +53,77 @@ public async Task TriggerUpdateRequest()
await _themerrManager.UpdateAll();
_logger.LogInformation("Completed");
}
+
+ ///
+ /// Get the data required to populate the progress dashboard.
+ ///
+ /// Loop over all Jellyfin libraries and movies, creating a json object with the following structure:
+ /// {
+ /// "items": [Movies],
+ /// "media_count": Movies.Count,
+ /// "media_percent_complete": ThemedMovies.Count / Movies.Count * 100,
+ /// }
+ ///
+ /// JSON object containing progress data.
+ [HttpGet("GetProgress")]
+ [ProducesResponseType(StatusCodes.Status200OK)]
+ public ActionResult GetProgress()
+ {
+ // url components
+ const string issueBase = "https://github.com/LizardByte/ThemerrDB/issues/new?assignees=&labels=request-theme&template=theme.yml&title=[MOVIE]:%20";
+ const string databaseBase = "https://www.themoviedb.org/movie/";
+
+ var tmpItems = new ArrayList();
+
+ var mediaCount = 0;
+ var mediaWithThemes = 0;
+ var mediaPercentComplete = 0;
+
+ var movies = _themerrManager.GetMoviesFromLibrary();
+
+ // sort movies by name, then year
+ var enumerable = movies.OrderBy(m => m.Name).ThenBy(m => m.ProductionYear);
+
+ foreach (var movie in enumerable)
+ {
+ var urlEncodedName = movie.Name.Replace(" ", "%20");
+ var year = movie.ProductionYear;
+ var tmdbId = _themerrManager.GetTmdbId(movie);
+ var themeProvider = _themerrManager.GetThemeProvider(movie);
+ var item = new
+ {
+ name = movie.Name,
+ id = movie.Id,
+ issue_url = $"{issueBase}{urlEncodedName}%20({year})&database_url={databaseBase}{tmdbId}",
+ theme_provider = themeProvider,
+ year = year
+ };
+ tmpItems.Add(item);
+
+ mediaCount++;
+
+ var themeSongs = movie.GetThemeSongs();
+ if (themeSongs.Count > 0)
+ {
+ mediaWithThemes++;
+ }
+ }
+
+ if (mediaCount > 0)
+ {
+ mediaPercentComplete = (int)Math.Round((double)mediaWithThemes / mediaCount * 100);
+ }
+
+ var tmpObject = new
+ {
+ items = tmpItems,
+ media_count = mediaCount,
+ media_percent_complete = mediaPercentComplete
+ };
+
+ _logger.LogInformation("Progress Items: {Items}", JsonConvert.SerializeObject(tmpObject));
+
+ return new JsonResult(tmpObject);
+ }
}
}
diff --git a/Jellyfin.Plugin.Themerr/Configuration/configPage.html b/Jellyfin.Plugin.Themerr/Configuration/configPage.html
index 0d39bcd..7b81953 100644
--- a/Jellyfin.Plugin.Themerr/Configuration/configPage.html
+++ b/Jellyfin.Plugin.Themerr/Configuration/configPage.html
@@ -21,7 +21,7 @@ Themerr
-
+
+
+
+