mirror of
https://github.com/jellyfin/jellyfin.git
synced 2024-07-08 23:00:51 +02:00
fixes #943 - Add web client filtering by genres, parental ratings, tags and years
This commit is contained in:
parent
1a80362a0f
commit
95eaf88abd
|
@ -193,13 +193,6 @@ namespace MediaBrowser.Api.UserLibrary
|
|||
|
||||
var filters = request.GetFilters().ToList();
|
||||
|
||||
if (filters.Count == 0)
|
||||
{
|
||||
return items;
|
||||
}
|
||||
|
||||
items = items.AsParallel();
|
||||
|
||||
if (filters.Contains(ItemFilter.Dislikes))
|
||||
{
|
||||
items = items.Where(i =>
|
||||
|
@ -243,9 +236,56 @@ namespace MediaBrowser.Api.UserLibrary
|
|||
});
|
||||
}
|
||||
|
||||
return items.AsEnumerable();
|
||||
// Avoid implicitly captured closure
|
||||
var currentRequest = request;
|
||||
return items.Where(i => ApplyAdditionalFilters(currentRequest, i, user, false));
|
||||
}
|
||||
|
||||
private bool ApplyAdditionalFilters(BaseItemsRequest request, BaseItem i, User user, bool isPreFiltered)
|
||||
{
|
||||
if (!isPreFiltered)
|
||||
{
|
||||
// Apply tag filter
|
||||
var tags = request.GetTags();
|
||||
if (tags.Length > 0)
|
||||
{
|
||||
var hasTags = i as IHasTags;
|
||||
if (hasTags == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (!(tags.Any(v => hasTags.Tags.Contains(v, StringComparer.OrdinalIgnoreCase))))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Apply official rating filter
|
||||
var officialRatings = request.GetOfficialRatings();
|
||||
if (officialRatings.Length > 0 && !officialRatings.Contains(i.OfficialRating ?? string.Empty))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Apply genre filter
|
||||
var genres = request.GetGenres();
|
||||
if (genres.Length > 0 && !(genres.Any(v => i.Genres.Contains(v, StringComparer.OrdinalIgnoreCase))))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Apply year filter
|
||||
var years = request.GetYears();
|
||||
if (years.Length > 0 && !(i.ProductionYear.HasValue && years.Contains(i.ProductionYear.Value)))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Filters the items.
|
||||
/// </summary>
|
||||
|
|
|
@ -96,6 +96,41 @@ namespace MediaBrowser.Api.UserLibrary
|
|||
[ApiMember(Name = "IsPlayed", Description = "Optional filter by items that are played, or not.", IsRequired = false, DataType = "bool", ParameterType = "query", Verb = "GET")]
|
||||
public bool? IsPlayed { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Limit results to items containing specific genres
|
||||
/// </summary>
|
||||
/// <value>The genres.</value>
|
||||
[ApiMember(Name = "Genres", Description = "Optional. If specified, results will be filtered based on genre. This allows multiple, pipe delimeted.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET", AllowMultiple = true)]
|
||||
public string Genres { get; set; }
|
||||
|
||||
[ApiMember(Name = "OfficialRatings", Description = "Optional. If specified, results will be filtered based on OfficialRating. This allows multiple, pipe delimeted.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET", AllowMultiple = true)]
|
||||
public string OfficialRatings { get; set; }
|
||||
|
||||
[ApiMember(Name = "Tags", Description = "Optional. If specified, results will be filtered based on tag. This allows multiple, pipe delimeted.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET", AllowMultiple = true)]
|
||||
public string Tags { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Limit results to items containing specific years
|
||||
/// </summary>
|
||||
/// <value>The years.</value>
|
||||
[ApiMember(Name = "Years", Description = "Optional. If specified, results will be filtered based on production year. This allows multiple, comma delimeted.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET", AllowMultiple = true)]
|
||||
public string Years { get; set; }
|
||||
|
||||
public string[] GetGenres()
|
||||
{
|
||||
return (Genres ?? string.Empty).Split(new[] { '|' }, StringSplitOptions.RemoveEmptyEntries);
|
||||
}
|
||||
|
||||
public string[] GetTags()
|
||||
{
|
||||
return (Tags ?? string.Empty).Split(new[] { '|' }, StringSplitOptions.RemoveEmptyEntries);
|
||||
}
|
||||
|
||||
public string[] GetOfficialRatings()
|
||||
{
|
||||
return (OfficialRatings ?? string.Empty).Split(new[] { '|' }, StringSplitOptions.RemoveEmptyEntries);
|
||||
}
|
||||
|
||||
public string[] GetMediaTypes()
|
||||
{
|
||||
return (MediaTypes ?? string.Empty).Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
|
||||
|
@ -110,6 +145,11 @@ namespace MediaBrowser.Api.UserLibrary
|
|||
{
|
||||
return (ExcludeItemTypes ?? string.Empty).Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
|
||||
}
|
||||
|
||||
public int[] GetYears()
|
||||
{
|
||||
return (Years ?? string.Empty).Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries).Select(int.Parse).ToArray();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the filters.
|
||||
|
|
|
@ -46,13 +46,6 @@ namespace MediaBrowser.Api.UserLibrary
|
|||
[ApiMember(Name = "PersonTypes", Description = "Optional. If specified, along with Person, results will be filtered to include only those containing the specified person and PersonType. Allows multiple, comma-delimited", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")]
|
||||
public string PersonTypes { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Limit results to items containing specific genres
|
||||
/// </summary>
|
||||
/// <value>The genres.</value>
|
||||
[ApiMember(Name = "Genres", Description = "Optional. If specified, results will be filtered based on genre. This allows multiple, pipe delimeted.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET", AllowMultiple = true)]
|
||||
public string Genres { get; set; }
|
||||
|
||||
[ApiMember(Name = "AllGenres", Description = "Optional. If specified, results will be filtered based on genre. This allows multiple, pipe delimeted.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET", AllowMultiple = true)]
|
||||
public string AllGenres { get; set; }
|
||||
|
||||
|
@ -73,13 +66,6 @@ namespace MediaBrowser.Api.UserLibrary
|
|||
[ApiMember(Name = "Albums", Description = "Optional. If specified, results will be filtered based on album. This allows multiple, pipe delimeted.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET", AllowMultiple = true)]
|
||||
public string Albums { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Limit results to items containing specific years
|
||||
/// </summary>
|
||||
/// <value>The years.</value>
|
||||
[ApiMember(Name = "Years", Description = "Optional. If specified, results will be filtered based on production year. This allows multiple, comma delimeted.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET", AllowMultiple = true)]
|
||||
public string Years { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the item ids.
|
||||
/// </summary>
|
||||
|
@ -247,11 +233,6 @@ namespace MediaBrowser.Api.UserLibrary
|
|||
return (AllGenres ?? string.Empty).Split(new[] { '|' }, StringSplitOptions.RemoveEmptyEntries);
|
||||
}
|
||||
|
||||
public string[] GetGenres()
|
||||
{
|
||||
return (Genres ?? string.Empty).Split(new[] { '|' }, StringSplitOptions.RemoveEmptyEntries);
|
||||
}
|
||||
|
||||
public string[] GetStudios()
|
||||
{
|
||||
return (Studios ?? string.Empty).Split(new[] { '|' }, StringSplitOptions.RemoveEmptyEntries);
|
||||
|
@ -262,11 +243,6 @@ namespace MediaBrowser.Api.UserLibrary
|
|||
return (PersonTypes ?? string.Empty).Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
|
||||
}
|
||||
|
||||
public int[] GetYears()
|
||||
{
|
||||
return (Years ?? string.Empty).Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries).Select(int.Parse).ToArray();
|
||||
}
|
||||
|
||||
public IEnumerable<VideoType> GetVideoTypes()
|
||||
{
|
||||
var val = VideoTypes;
|
||||
|
@ -520,6 +496,8 @@ namespace MediaBrowser.Api.UserLibrary
|
|||
HasThemeSong = request.HasThemeSong,
|
||||
HasThemeVideo = request.HasThemeVideo,
|
||||
HasTrailer = request.HasTrailer,
|
||||
Tags = request.GetTags(),
|
||||
OfficialRatings = request.GetOfficialRatings(),
|
||||
Genres = request.GetGenres(),
|
||||
AllGenres = request.GetAllGenres(),
|
||||
Studios = request.GetStudios(),
|
||||
|
@ -951,6 +929,28 @@ namespace MediaBrowser.Api.UserLibrary
|
|||
}
|
||||
}
|
||||
|
||||
// Apply tag filter
|
||||
var tags = request.GetTags();
|
||||
if (tags.Length > 0)
|
||||
{
|
||||
var hasTags = i as IHasTags;
|
||||
if (hasTags == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (!(tags.Any(v => hasTags.Tags.Contains(v, StringComparer.OrdinalIgnoreCase))))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Apply official rating filter
|
||||
var officialRatings = request.GetOfficialRatings();
|
||||
if (officialRatings.Length > 0 && !officialRatings.Contains(i.OfficialRating ?? string.Empty))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Apply genre filter
|
||||
var genres = request.GetGenres();
|
||||
if (genres.Length > 0 && !(genres.Any(v => i.Genres.Contains(v, StringComparer.OrdinalIgnoreCase))))
|
||||
|
|
|
@ -398,14 +398,16 @@ namespace MediaBrowser.Common.Implementations.IO
|
|||
throw new ArgumentNullException("path");
|
||||
}
|
||||
|
||||
//if (path.IndexOf("://", StringComparison.OrdinalIgnoreCase) != -1 &&
|
||||
// !path.StartsWith("file://", StringComparison.OrdinalIgnoreCase))
|
||||
//{
|
||||
// return false;
|
||||
//}
|
||||
//return true;
|
||||
// Cannot use Path.IsPathRooted because it returns false under mono when using windows-based paths, e.g. C:\\
|
||||
|
||||
return Path.IsPathRooted(path);
|
||||
if (path.IndexOf("://", StringComparison.OrdinalIgnoreCase) != -1 &&
|
||||
!path.StartsWith("file://", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
||||
//return Path.IsPathRooted(path);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -69,9 +69,13 @@ namespace MediaBrowser.Controller.Entities
|
|||
public ImageType[] ImageTypes { get; set; }
|
||||
public VideoType[] VideoTypes { get; set; }
|
||||
public int[] Years { get; set; }
|
||||
public string[] Tags { get; set; }
|
||||
public string[] OfficialRatings { get; set; }
|
||||
|
||||
public InternalItemsQuery()
|
||||
{
|
||||
Tags = new string[] { };
|
||||
OfficialRatings = new string[] { };
|
||||
SortBy = new string[] { };
|
||||
MediaTypes = new string[] { };
|
||||
IncludeItemTypes = new string[] { };
|
||||
|
|
|
@ -870,6 +870,16 @@ namespace MediaBrowser.Controller.Entities
|
|||
return false;
|
||||
}
|
||||
|
||||
if (request.Tags.Length > 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (request.OfficialRatings.Length > 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -1405,6 +1415,12 @@ namespace MediaBrowser.Controller.Entities
|
|||
}
|
||||
}
|
||||
|
||||
// Apply official rating filter
|
||||
if (query.OfficialRatings.Length > 0 && !query.OfficialRatings.Contains(item.OfficialRating ?? string.Empty))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Apply person filter
|
||||
if (!string.IsNullOrEmpty(query.Person))
|
||||
{
|
||||
|
@ -1431,6 +1447,21 @@ namespace MediaBrowser.Controller.Entities
|
|||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Apply tag filter
|
||||
var tags = query.Tags;
|
||||
if (tags.Length > 0)
|
||||
{
|
||||
var hasTags = item as IHasTags;
|
||||
if (hasTags == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (!(tags.Any(v => hasTags.Tags.Contains(v, StringComparer.OrdinalIgnoreCase))))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
|
|
|
@ -1,14 +1,9 @@
|
|||
using MediaBrowser.Controller;
|
||||
using MediaBrowser.Controller.Configuration;
|
||||
using MediaBrowser.Controller.Library;
|
||||
using MediaBrowser.Controller.Localization;
|
||||
using MediaBrowser.Controller.Persistence;
|
||||
using MediaBrowser.Model.Logging;
|
||||
using MediaBrowser.Model.Serialization;
|
||||
using MediaBrowser.Server.Startup.Common.Browser;
|
||||
using MediaBrowser.ServerApplication.Native;
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace MediaBrowser.ServerApplication
|
||||
|
@ -17,18 +12,18 @@ namespace MediaBrowser.ServerApplication
|
|||
{
|
||||
bool IsDisposing = false;
|
||||
|
||||
private System.Windows.Forms.NotifyIcon notifyIcon1;
|
||||
private System.Windows.Forms.ContextMenuStrip contextMenuStrip1;
|
||||
private System.Windows.Forms.ToolStripMenuItem cmdExit;
|
||||
private System.Windows.Forms.ToolStripMenuItem cmdBrowse;
|
||||
private System.Windows.Forms.ToolStripMenuItem cmdConfigure;
|
||||
private System.Windows.Forms.ToolStripSeparator toolStripSeparator2;
|
||||
private System.Windows.Forms.ToolStripMenuItem cmdRestart;
|
||||
private System.Windows.Forms.ToolStripSeparator toolStripSeparator1;
|
||||
private System.Windows.Forms.ToolStripMenuItem cmdCommunity;
|
||||
private System.Windows.Forms.ToolStripMenuItem cmdApiDocs;
|
||||
private System.Windows.Forms.ToolStripMenuItem cmdSwagger;
|
||||
private System.Windows.Forms.ToolStripMenuItem cmdGtihub;
|
||||
private NotifyIcon notifyIcon1;
|
||||
private ContextMenuStrip contextMenuStrip1;
|
||||
private ToolStripMenuItem cmdExit;
|
||||
private ToolStripMenuItem cmdBrowse;
|
||||
private ToolStripMenuItem cmdConfigure;
|
||||
private ToolStripSeparator toolStripSeparator2;
|
||||
private ToolStripMenuItem cmdRestart;
|
||||
private ToolStripSeparator toolStripSeparator1;
|
||||
private ToolStripMenuItem cmdCommunity;
|
||||
private ToolStripMenuItem cmdApiDocs;
|
||||
private ToolStripMenuItem cmdSwagger;
|
||||
private ToolStripMenuItem cmdGtihub;
|
||||
|
||||
private readonly ILogger _logger;
|
||||
private readonly IServerApplicationHost _appHost;
|
||||
|
@ -61,19 +56,19 @@ namespace MediaBrowser.ServerApplication
|
|||
var components = new System.ComponentModel.Container();
|
||||
|
||||
var resources = new System.ComponentModel.ComponentResourceManager(typeof(MainForm));
|
||||
contextMenuStrip1 = new System.Windows.Forms.ContextMenuStrip(components);
|
||||
notifyIcon1 = new System.Windows.Forms.NotifyIcon(components);
|
||||
contextMenuStrip1 = new ContextMenuStrip(components);
|
||||
notifyIcon1 = new NotifyIcon(components);
|
||||
|
||||
cmdExit = new System.Windows.Forms.ToolStripMenuItem();
|
||||
cmdCommunity = new System.Windows.Forms.ToolStripMenuItem();
|
||||
toolStripSeparator1 = new System.Windows.Forms.ToolStripSeparator();
|
||||
cmdRestart = new System.Windows.Forms.ToolStripMenuItem();
|
||||
toolStripSeparator2 = new System.Windows.Forms.ToolStripSeparator();
|
||||
cmdConfigure = new System.Windows.Forms.ToolStripMenuItem();
|
||||
cmdBrowse = new System.Windows.Forms.ToolStripMenuItem();
|
||||
cmdApiDocs = new System.Windows.Forms.ToolStripMenuItem();
|
||||
cmdSwagger = new System.Windows.Forms.ToolStripMenuItem();
|
||||
cmdGtihub = new System.Windows.Forms.ToolStripMenuItem();
|
||||
cmdExit = new ToolStripMenuItem();
|
||||
cmdCommunity = new ToolStripMenuItem();
|
||||
toolStripSeparator1 = new ToolStripSeparator();
|
||||
cmdRestart = new ToolStripMenuItem();
|
||||
toolStripSeparator2 = new ToolStripSeparator();
|
||||
cmdConfigure = new ToolStripMenuItem();
|
||||
cmdBrowse = new ToolStripMenuItem();
|
||||
cmdApiDocs = new ToolStripMenuItem();
|
||||
cmdSwagger = new ToolStripMenuItem();
|
||||
cmdGtihub = new ToolStripMenuItem();
|
||||
|
||||
//
|
||||
// notifyIcon1
|
||||
|
@ -85,7 +80,7 @@ namespace MediaBrowser.ServerApplication
|
|||
//
|
||||
// contextMenuStrip1
|
||||
//
|
||||
contextMenuStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
|
||||
contextMenuStrip1.Items.AddRange(new ToolStripItem[] {
|
||||
cmdBrowse,
|
||||
cmdConfigure,
|
||||
toolStripSeparator2,
|
||||
|
@ -136,7 +131,7 @@ namespace MediaBrowser.ServerApplication
|
|||
//
|
||||
// cmdApiDocs
|
||||
//
|
||||
cmdApiDocs.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
|
||||
cmdApiDocs.DropDownItems.AddRange(new ToolStripItem[] {
|
||||
cmdSwagger,
|
||||
cmdGtihub});
|
||||
cmdApiDocs.Name = "cmdApiDocs";
|
||||
|
|
Loading…
Reference in a new issue