This commit is contained in:
Cody Robibero 2024-05-11 13:25:15 -06:00 committed by GitHub
parent e9dfdc7c3b
commit 946a9e4144
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 49 additions and 48 deletions

View File

@ -238,9 +238,8 @@ namespace Jellyfin.Plugin.Reports.Api.Common
protected string GetSeriesProductionYear(BaseItem item)
{
string productionYear = item.ProductionYear.ToString();
var series = item as Series;
if (series == null)
string productionYear = item.ProductionYear?.ToString(CultureInfo.InvariantCulture);
if (item is not Series series)
{
if (item.ProductionYear == null || item.ProductionYear == 0)
return string.Empty;
@ -248,10 +247,10 @@ namespace Jellyfin.Plugin.Reports.Api.Common
}
if (series.Status == SeriesStatus.Continuing)
return productionYear += "-Present";
return productionYear + "-Present";
if (series.EndDate != null && series.EndDate.Value.Year != series.ProductionYear)
return productionYear += "-" + series.EndDate.Value.Year;
return productionYear + "-" + series.EndDate.Value.Year;
return productionYear;
}
@ -298,8 +297,8 @@ namespace Jellyfin.Plugin.Reports.Api.Common
MediaStreamType.Video);
if (stream != null && stream.Width != null)
return string.Format(CultureInfo.InvariantCulture, "{0} * {1}",
stream.Width,
stream.Height != null ? stream.Height.ToString() : "-");
stream.Width,
stream.Height?.ToString(CultureInfo.InvariantCulture) ?? "-");
return string.Empty;
}

View File

@ -1,6 +1,7 @@
#nullable disable
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using Jellyfin.Plugin.Reports.Api.Common;
using Jellyfin.Plugin.Reports.Api.Model;
@ -389,7 +390,7 @@ namespace Jellyfin.Plugin.Reports.Api.Data
break;
case HeaderMetadata.SeasonNumber:
option.Column = (i, r) => this.GetObject<Season, string>(i, (x) => x.IndexNumber == null ? "" : x.IndexNumber.ToString());
option.Column = (i, r) => this.GetObject<Season, string>(i, (x) => x.IndexNumber == null ? "" : x.IndexNumber?.ToString(CultureInfo.InvariantCulture));
option.Header.SortField = "IndexNumber";
option.Header.HeaderFieldType = ReportFieldType.Int;
break;
@ -429,7 +430,7 @@ namespace Jellyfin.Plugin.Reports.Api.Data
break;
case HeaderMetadata.EpisodeNumber:
option.Column = (i, r) => this.GetObject<BaseItem, string>(i, (x) => x.IndexNumber == null ? "" : x.IndexNumber.ToString());
option.Column = (i, r) => this.GetObject<BaseItem, string>(i, (x) => x.IndexNumber == null ? "" : x.IndexNumber?.ToString(CultureInfo.InvariantCulture));
//option.Header.SortField = "IndexNumber";
//option.Header.HeaderFieldType = ReportFieldType.Int;
break;

View File

@ -21,7 +21,7 @@ namespace Jellyfin.Plugin.Reports.Api.Data
static string EscapeText(string text)
{
string escapedText = text.Replace("\"", "\"\"", System.StringComparison.Ordinal);
return text.IndexOfAny(new char[4] { '"', ',', '\n', '\r' }) == -1 ? escapedText : $"\"{escapedText}\"";
return text.IndexOfAny(['"', ',', '\n', '\r']) == -1 ? escapedText : $"\"{escapedText}\"";
}
static void AppendRows(StreamWriter writer, List<ReportRow> rows)
{
@ -153,7 +153,7 @@ namespace Jellyfin.Plugin.Reports.Api.Data
nextRow += rows.Count();
}
using IXLWorkbook workbook = new XLWorkbook(XLEventTracking.Disabled);
using var workbook = new XLWorkbook(XLEventTracking.Disabled);
IXLWorksheet worksheet = workbook.Worksheets.Add("ReportExport");
// Add report rows

View File

@ -3,6 +3,7 @@
using System;
using System.ComponentModel;
using System.Linq;
using DocumentFormat.OpenXml.Spreadsheet;
using Jellyfin.Data.Enums;
using Jellyfin.Plugin.Reports.Api.Common;
using MediaBrowser.Model.Entities;
@ -94,7 +95,7 @@ namespace Jellyfin.Plugin.Reports.Api
public bool? HasTrailer { get; set; }
// [ApiMember(Name = "AdjacentTo", Description = "Optional. Return items that are siblings of a supplied item.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")]
public string AdjacentTo { get; set; }
public Guid? AdjacentTo { get; set; }
// [ApiMember(Name = "MinIndexNumber", Description = "Optional filter by minimum index number.", IsRequired = false, DataType = "int", ParameterType = "query", Verb = "GET")]
public int? MinIndexNumber { get; set; }
@ -403,46 +404,50 @@ namespace Jellyfin.Plugin.Reports.Api
public string[] GetGenres()
{
return (Genres ?? string.Empty).Split(new[] { '|' }, StringSplitOptions.RemoveEmptyEntries);
return (Genres ?? string.Empty).Split( '|', StringSplitOptions.RemoveEmptyEntries);
}
public string[] GetTags()
{
return (Tags ?? string.Empty).Split(new[] { '|' }, StringSplitOptions.RemoveEmptyEntries);
return (Tags ?? string.Empty).Split('|', StringSplitOptions.RemoveEmptyEntries);
}
public string[] GetOfficialRatings()
{
return (OfficialRatings ?? string.Empty).Split(new[] { '|' }, StringSplitOptions.RemoveEmptyEntries);
return (OfficialRatings ?? string.Empty).Split('|', StringSplitOptions.RemoveEmptyEntries);
}
public string[] GetMediaTypes()
public MediaType[] GetMediaTypes()
{
return (MediaTypes ?? string.Empty).Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
return (MediaTypes ?? string.Empty).Split(',', StringSplitOptions.RemoveEmptyEntries)
.Select(r => Enum.TryParse(r, out MediaType mt) ? mt : (MediaType?)null)
.Where(r => r is not null)
.Select(r => r.Value)
.ToArray();
}
public BaseItemKind[] GetIncludeItemTypes() => GetBaseItemKinds(IncludeItemTypes);
public string[] GetExcludeItemIds()
{
return (ExcludeItemIds ?? string.Empty).Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
return (ExcludeItemIds ?? string.Empty).Split(',', StringSplitOptions.RemoveEmptyEntries);
}
public BaseItemKind[] GetExcludeItemTypes() => GetBaseItemKinds(ExcludeItemTypes);
public int[] GetYears()
{
return (Years ?? string.Empty).Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries).Select(int.Parse).ToArray();
return (Years ?? string.Empty).Split(',', StringSplitOptions.RemoveEmptyEntries).Select(int.Parse).ToArray();
}
public Guid[] GetGuids(string value)
{
return (value ?? string.Empty).Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries).Select(i => new Guid(i)).ToArray();
return (value ?? string.Empty).Split(',', StringSplitOptions.RemoveEmptyEntries).Select(i => new Guid(i)).ToArray();
}
public string[] GetStudios()
{
return (Studios ?? string.Empty).Split(new[] { '|' }, StringSplitOptions.RemoveEmptyEntries);
return (Studios ?? string.Empty).Split('|', StringSplitOptions.RemoveEmptyEntries);
}
public Guid[] GetArtistIds()
@ -462,7 +467,7 @@ namespace Jellyfin.Plugin.Reports.Api
public string[] GetPersonTypes()
{
return (PersonTypes ?? string.Empty).Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
return (PersonTypes ?? string.Empty).Split(',', StringSplitOptions.RemoveEmptyEntries);
}
public Guid[] GetPersonIds()
@ -484,7 +489,7 @@ namespace Jellyfin.Plugin.Reports.Api
return Array.Empty<VideoType>();
}
return val.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries).Select(v => (VideoType)Enum.Parse(typeof(VideoType), v, true)).ToArray();
return val.Split(',', StringSplitOptions.RemoveEmptyEntries).Select(v => (VideoType)Enum.Parse(typeof(VideoType), v, true)).ToArray();
}
/// <summary>
@ -500,7 +505,7 @@ namespace Jellyfin.Plugin.Reports.Api
return Array.Empty<ItemFilter>();
}
return val.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries).Select(v => (ItemFilter)Enum.Parse(typeof(ItemFilter), v, true)).ToArray();
return val.Split(',', StringSplitOptions.RemoveEmptyEntries).Select(v => (ItemFilter)Enum.Parse(typeof(ItemFilter), v, true)).ToArray();
}
/// <summary>
@ -523,18 +528,18 @@ namespace Jellyfin.Plugin.Reports.Api
/// Gets the order by.
/// </summary>
/// <returns>IEnumerable{ItemSortBy}.</returns>
public ValueTuple<string, SortOrder>[] GetOrderBy()
public ValueTuple<ItemSortBy, SortOrder>[] GetOrderBy()
{
return GetOrderBy(SortBy, SortOrder);
}
public static (string, SortOrder)[] GetOrderBy(string sortBy, string requestedSortOrder)
public static (ItemSortBy, SortOrder)[] GetOrderBy(string sortBy, string requestedSortOrder)
{
var val = sortBy;
if (string.IsNullOrEmpty(val))
{
return Array.Empty<(string, SortOrder)>();
return Array.Empty<(ItemSortBy, SortOrder)>();
}
var vals = val.Split(',');
@ -545,16 +550,21 @@ namespace Jellyfin.Plugin.Reports.Api
var sortOrders = requestedSortOrder.Split(',');
var result = new (string, SortOrder)[vals.Length];
var result = new (ItemSortBy, SortOrder)[vals.Length];
for (var i = 0; i < vals.Length; i++)
{
if (!Enum.TryParse(vals[i], out ItemSortBy currentSortBy))
{
continue;
}
var sortOrderIndex = sortOrders.Length > i ? i : 0;
var sortOrderValue = sortOrders.Length > sortOrderIndex ? sortOrders[sortOrderIndex] : null;
var sortOrder = string.Equals(sortOrderValue, "Descending", StringComparison.OrdinalIgnoreCase) ? Jellyfin.Data.Enums.SortOrder.Descending : Jellyfin.Data.Enums.SortOrder.Ascending;
result[i] = (vals[i], sortOrder);
result[i] = (currentSortBy, sortOrder);
}
return result;

View File

@ -1,4 +1,5 @@
using System.Net.Mime;
using System;
using System.Net.Mime;
using System.Threading.Tasks;
using Jellyfin.Plugin.Reports.Api.Common;
using Jellyfin.Plugin.Reports.Api.Model;
@ -6,13 +7,14 @@ using MediaBrowser.Controller.Library;
using MediaBrowser.Model.Activity;
using MediaBrowser.Model.Globalization;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
namespace Jellyfin.Plugin.Reports.Api
{
[ApiController]
[Route("[controller]")]
[Authorize(Policy = "DefaultAuthorization")]
[Authorize]
[Produces(MediaTypeNames.Application.Json)]
public class ReportsController : ControllerBase
{
@ -37,7 +39,7 @@ namespace Jellyfin.Plugin.Reports.Api
[FromQuery] bool? hasSubtitles,
[FromQuery] bool? hasSpecialFeature,
[FromQuery] bool? hasTrailer,
[FromQuery] string? adjacentTo,
[FromQuery] Guid? adjacentTo,
[FromQuery] int? minIndexNumber,
[FromQuery] int? parentIndexNumber,
[FromQuery] bool? hasParentalRating,
@ -260,7 +262,7 @@ namespace Jellyfin.Plugin.Reports.Api
[FromQuery] bool? hasSubtitles,
[FromQuery] bool? hasSpecialFeature,
[FromQuery] bool? hasTrailer,
[FromQuery] string? adjacentTo,
[FromQuery] Guid? adjacentTo,
[FromQuery] int? minIndexNumber,
[FromQuery] int? parentIndexNumber,
[FromQuery] bool? hasParentalRating,
@ -427,7 +429,7 @@ namespace Jellyfin.Plugin.Reports.Api
foreach (var (key, value) in headers)
{
Response.Headers.Add(key, value);
Response.Headers.Append(key, value);
}
return File(content, contentType);

View File

@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<TargetFramework>net8.0</TargetFramework>
<RootNamespace>Jellyfin.Plugin.Reports</RootNamespace>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<CodeAnalysisRuleSet>../jellyfin.ruleset</CodeAnalysisRuleSet>

View File

@ -3,8 +3,8 @@ name: "Reports"
guid: "d4312cd9-5c90-4f38-82e8-51da566790e8"
imageUrl: "https://repo.jellyfin.org/releases/plugin/images/jellyfin-plugin-reports.png"
version: 15
targetAbi: "10.8.1.0"
framework: "net6.0"
targetAbi: "10.9.0.0"
framework: "net8.0"
owner: "jellyfin"
overview: "Generate reports of your media library"
description: "Generate reports of your media library"
@ -16,14 +16,3 @@ artifacts:
- "ExcelNumberFormat.dll"
- "System.IO.Packaging.dll"
changelog: |2-
### Bug Fixes ###
- Fix CSV Export Format (#73) @mwildgoose
### Code or Repo Maintenance ###
- Use meta ci (#66) @crobibero
- Performance improvements (#59) @Bond-009
- Style fixes, enable analysis and nullable (#57) @Bond-009
### CI & build changes ###
- fix: meta ci workflows (#68) @h1dden-da3m0n
- Use meta ci (#66) @crobibero