Skip to content
This repository has been archived by the owner on Oct 13, 2024. It is now read-only.

Commit

Permalink
feat: add progress dashboard (#195)
Browse files Browse the repository at this point in the history
  • Loading branch information
ReenigneArcher authored Dec 21, 2023
1 parent 99d6720 commit 5ae69c3
Show file tree
Hide file tree
Showing 8 changed files with 397 additions and 8 deletions.
1 change: 1 addition & 0 deletions Jellyfin.Plugin.Themerr.Tests/TestPluginConfiguration.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ public TestPluginConfiguration(ITestOutputHelper output)
/// Test getting the default PluginConfiguration.
/// </summary>
[Fact]
[Trait("Category", "Unit")]
public void TestPluginConfigurationInstance()
{
// ensure UpdateInterval is an int
Expand Down
59 changes: 59 additions & 0 deletions Jellyfin.Plugin.Themerr.Tests/TestThemerrController.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
using System.Collections;
using Jellyfin.Plugin.Themerr.Api;
using MediaBrowser.Controller.Library;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using Moq;

namespace Jellyfin.Plugin.Themerr.Tests;

/// <summary>
/// This class is responsible for testing the <see cref="ThemerrController"/>.
/// </summary>
[Collection("Fixture Collection")]
public class TestThemerrController
{
private readonly ThemerrController _controller;

/// <summary>
/// Initializes a new instance of the <see cref="TestThemerrController"/> class.
/// </summary>
/// <param name="output">An <see cref="ITestOutputHelper"/> instance.</param>
public TestThemerrController(ITestOutputHelper output)
{
TestLogger.Initialize(output);

Mock<ILibraryManager> mockLibraryManager = new();
Mock<ILogger<ThemerrManager>> mockLogger = new();
_controller = new ThemerrController(mockLibraryManager.Object, mockLogger.Object);
}

/// <summary>
/// Test GetProgress from API.
/// </summary>
[Fact]
[Trait("Category", "Unit")]
public void TestGetProgress()
{
var result = _controller.GetProgress();
Assert.IsType<JsonResult>(result);

// ensure result["media_count"] is an int
Assert.IsType<int>(((JsonResult)result).Value?.GetType().GetProperty("media_count")?.GetValue(((JsonResult)result).Value, null));

// ensure result["media_percent_complete"] is an int
Assert.IsType<int>(((JsonResult)result).Value?.GetType().GetProperty("media_percent_complete")?.GetValue(((JsonResult)result).Value, null));

// ensure result["items"] is a an array list
Assert.IsType<ArrayList>(((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
}
}
52 changes: 52 additions & 0 deletions Jellyfin.Plugin.Themerr.Tests/TestThemerrManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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")]
Expand All @@ -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()
Expand Down
4 changes: 4 additions & 0 deletions Jellyfin.Plugin.Themerr.Tests/TestThemerrPlugin.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ public TestThemerrPlugin(ITestOutputHelper output)
/// Test getting the plugin name.
/// </summary>
[Fact]
[Trait("Category", "Unit")]
public void TestPluginInstance()
{
Assert.NotNull(_plugin.Name);
Expand All @@ -39,6 +40,7 @@ public void TestPluginInstance()
/// Test getting the plugin description.
/// </summary>
[Fact]
[Trait("Category", "Unit")]
public void TestPluginDescription()
{
Assert.NotNull(_plugin.Description);
Expand All @@ -49,6 +51,7 @@ public void TestPluginDescription()
/// Test get the plugin id.
/// </summary>
[Fact]
[Trait("Category", "Unit")]
public void TestPluginId()
{
Assert.Equal(new Guid("84b59a39-bde4-42f4-adbd-c39882cbb772"), _plugin.Id);
Expand All @@ -58,6 +61,7 @@ public void TestPluginId()
/// Test getting the plugin configuration page.
/// </summary>
[Fact]
[Trait("Category", "Unit")]
public void TestPluginConfigurationPage()
{
var pages = _plugin.GetPages();
Expand Down
77 changes: 77 additions & 0 deletions Jellyfin.Plugin.Themerr/Api/ThemerrController.cs
Original file line number Diff line number Diff line change
@@ -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
{
Expand Down Expand Up @@ -48,5 +53,77 @@ public async Task TriggerUpdateRequest()
await _themerrManager.UpdateAll();
_logger.LogInformation("Completed");
}

/// <summary>
/// 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,
/// }
/// </summary>
/// <returns>JSON object containing progress data.</returns>
[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);
}
}
}
Loading

0 comments on commit 5ae69c3

Please sign in to comment.