mirror of
https://github.com/jellyfin/jellyfin.git
synced 2025-07-09 03:04:24 -04:00
deprecated IndexFolder.cs
This commit is contained in:
parent
50ea8cd941
commit
5f9b99c960
@ -85,7 +85,7 @@ namespace MediaBrowser.Api.Library
|
||||
{
|
||||
allTypes = allTypes.Where(t =>
|
||||
{
|
||||
if (t == typeof(UserRootFolder) || t == typeof(AggregateFolder) || t == typeof(Folder) || t == typeof(IndexFolder) || t == typeof(CollectionFolder) || t == typeof(Year))
|
||||
if (t == typeof(UserRootFolder) || t == typeof(AggregateFolder) || t == typeof(Folder) || t == typeof(CollectionFolder) || t == typeof(Year))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
@ -52,12 +52,6 @@ namespace MediaBrowser.Api.UserLibrary
|
||||
[ApiMember(Name = "SearchTerm", Description = "Optional. If specified, results will be filtered based on a search term.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")]
|
||||
public string SearchTerm { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The dynamic, localized index function name
|
||||
/// </summary>
|
||||
/// <value>The index by.</value>
|
||||
public string IndexBy { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Limit results to items containing specific genres
|
||||
/// </summary>
|
||||
@ -358,7 +352,7 @@ namespace MediaBrowser.Api.UserLibrary
|
||||
}
|
||||
else
|
||||
{
|
||||
items = ((Folder)item).GetChildren(user, true, request.IndexBy);
|
||||
items = ((Folder)item).GetChildren(user, true);
|
||||
}
|
||||
|
||||
if (request.IncludeIndexContainers)
|
||||
|
@ -58,13 +58,6 @@ namespace MediaBrowser.Controller.Entities
|
||||
/// <returns>Task.</returns>
|
||||
protected override Task ValidateChildrenInternal(IProgress<double> progress, CancellationToken cancellationToken, bool? recursive = null, bool forceRefreshMetadata = false)
|
||||
{
|
||||
//we don't directly validate our children
|
||||
//but we do need to clear out the index cache...
|
||||
if (IndexCache != null)
|
||||
{
|
||||
IndexCache.Clear();
|
||||
}
|
||||
|
||||
ResetDynamicChildren();
|
||||
|
||||
return NullTaskResult;
|
||||
|
@ -208,284 +208,25 @@ namespace MediaBrowser.Controller.Entities
|
||||
|
||||
#region Indexing
|
||||
|
||||
/// <summary>
|
||||
/// The _index by options
|
||||
/// </summary>
|
||||
private Dictionary<string, Func<User, IEnumerable<BaseItem>>> _indexByOptions;
|
||||
/// <summary>
|
||||
/// Dictionary of index options - consists of a display value and an indexing function
|
||||
/// which takes User as a parameter and returns an IEnum of BaseItem
|
||||
/// </summary>
|
||||
/// <value>The index by options.</value>
|
||||
[IgnoreDataMember]
|
||||
public Dictionary<string, Func<User, IEnumerable<BaseItem>>> IndexByOptions
|
||||
{
|
||||
get { return _indexByOptions ?? (_indexByOptions = GetIndexByOptions()); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the valid set of index by options for this folder type.
|
||||
/// Override or extend to modify.
|
||||
/// </summary>
|
||||
/// <returns>Dictionary{System.StringFunc{UserIEnumerable{BaseItem}}}.</returns>
|
||||
protected virtual Dictionary<string, Func<User, IEnumerable<BaseItem>>> GetIndexByOptions()
|
||||
protected virtual IEnumerable<string> GetIndexByOptions()
|
||||
{
|
||||
return new Dictionary<string, Func<User, IEnumerable<BaseItem>>> {
|
||||
{LocalizedStrings.Instance.GetString("NoneDispPref"), null},
|
||||
{LocalizedStrings.Instance.GetString("PerformerDispPref"), GetIndexByPerformer},
|
||||
{LocalizedStrings.Instance.GetString("GenreDispPref"), GetIndexByGenre},
|
||||
{LocalizedStrings.Instance.GetString("DirectorDispPref"), GetIndexByDirector},
|
||||
{LocalizedStrings.Instance.GetString("YearDispPref"), GetIndexByYear},
|
||||
return new List<string> {
|
||||
{LocalizedStrings.Instance.GetString("NoneDispPref")},
|
||||
{LocalizedStrings.Instance.GetString("PerformerDispPref")},
|
||||
{LocalizedStrings.Instance.GetString("GenreDispPref")},
|
||||
{LocalizedStrings.Instance.GetString("DirectorDispPref")},
|
||||
{LocalizedStrings.Instance.GetString("YearDispPref")},
|
||||
//{LocalizedStrings.Instance.GetString("OfficialRatingDispPref"), null},
|
||||
{LocalizedStrings.Instance.GetString("StudioDispPref"), GetIndexByStudio}
|
||||
{LocalizedStrings.Instance.GetString("StudioDispPref")}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the index by actor.
|
||||
/// </summary>
|
||||
/// <param name="user">The user.</param>
|
||||
/// <returns>IEnumerable{BaseItem}.</returns>
|
||||
protected IEnumerable<BaseItem> GetIndexByPerformer(User user)
|
||||
{
|
||||
return GetIndexByPerson(user, new List<string> { PersonType.Actor, PersonType.GuestStar }, true, LocalizedStrings.Instance.GetString("PerformerDispPref"));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the index by director.
|
||||
/// </summary>
|
||||
/// <param name="user">The user.</param>
|
||||
/// <returns>IEnumerable{BaseItem}.</returns>
|
||||
protected IEnumerable<BaseItem> GetIndexByDirector(User user)
|
||||
{
|
||||
return GetIndexByPerson(user, new List<string> { PersonType.Director }, false, LocalizedStrings.Instance.GetString("DirectorDispPref"));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the index by person.
|
||||
/// </summary>
|
||||
/// <param name="user">The user.</param>
|
||||
/// <param name="personTypes">The person types we should match on</param>
|
||||
/// <param name="includeAudio">if set to <c>true</c> [include audio].</param>
|
||||
/// <param name="indexName">Name of the index.</param>
|
||||
/// <returns>IEnumerable{BaseItem}.</returns>
|
||||
private IEnumerable<BaseItem> GetIndexByPerson(User user, List<string> personTypes, bool includeAudio, string indexName)
|
||||
{
|
||||
// Even though this implementation means multiple iterations over the target list - it allows us to defer
|
||||
// the retrieval of the individual children for each index value until they are requested.
|
||||
using (new Profiler(indexName + " Index Build for " + Name, Logger))
|
||||
{
|
||||
// Put this in a local variable to avoid an implicitly captured closure
|
||||
var currentIndexName = indexName;
|
||||
|
||||
var us = this;
|
||||
var recursiveChildren = GetRecursiveChildren(user).Where(i => i.IncludeInIndex).ToList();
|
||||
|
||||
// Get the candidates, but handle audio separately
|
||||
var candidates = recursiveChildren.Where(i => i.AllPeople != null && !(i is Audio.Audio)).ToList();
|
||||
|
||||
var indexFolders = candidates.AsParallel().SelectMany(i => i.AllPeople.Where(p => personTypes.Contains(p.Type))
|
||||
.Select(a => a.Name))
|
||||
.Distinct()
|
||||
.Select(i =>
|
||||
{
|
||||
try
|
||||
{
|
||||
return LibraryManager.GetPerson(i);
|
||||
}
|
||||
catch (IOException ex)
|
||||
{
|
||||
Logger.ErrorException("Error getting person {0}", ex, i);
|
||||
return null;
|
||||
}
|
||||
catch (AggregateException ex)
|
||||
{
|
||||
Logger.ErrorException("Error getting person {0}", ex, i);
|
||||
return null;
|
||||
}
|
||||
})
|
||||
.Where(i => i != null)
|
||||
.Select(a => new IndexFolder(us, a,
|
||||
candidates.Where(i => i.AllPeople.Any(p => personTypes.Contains(p.Type) && p.Name.Equals(a.Name, StringComparison.OrdinalIgnoreCase))
|
||||
), currentIndexName)).AsEnumerable();
|
||||
|
||||
if (includeAudio)
|
||||
{
|
||||
var songs = recursiveChildren.OfType<Audio.Audio>().ToList();
|
||||
|
||||
indexFolders = songs.SelectMany(i => i.Artists)
|
||||
.Distinct(StringComparer.OrdinalIgnoreCase)
|
||||
.Select(i =>
|
||||
{
|
||||
try
|
||||
{
|
||||
return LibraryManager.GetArtist(i);
|
||||
}
|
||||
catch (IOException ex)
|
||||
{
|
||||
Logger.ErrorException("Error getting artist {0}", ex, i);
|
||||
return null;
|
||||
}
|
||||
catch (AggregateException ex)
|
||||
{
|
||||
Logger.ErrorException("Error getting artist {0}", ex, i);
|
||||
return null;
|
||||
}
|
||||
})
|
||||
.Where(i => i != null)
|
||||
.Select(a => new IndexFolder(us, a,
|
||||
songs.Where(i => i.Artists.Contains(a.Name, StringComparer.OrdinalIgnoreCase)
|
||||
), currentIndexName)).Concat(indexFolders);
|
||||
}
|
||||
|
||||
return indexFolders;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the index by studio.
|
||||
/// </summary>
|
||||
/// <param name="user">The user.</param>
|
||||
/// <returns>IEnumerable{BaseItem}.</returns>
|
||||
protected IEnumerable<BaseItem> GetIndexByStudio(User user)
|
||||
{
|
||||
// Even though this implementation means multiple iterations over the target list - it allows us to defer
|
||||
// the retrieval of the individual children for each index value until they are requested.
|
||||
using (new Profiler("Studio Index Build for " + Name, Logger))
|
||||
{
|
||||
var indexName = LocalizedStrings.Instance.GetString("StudioDispPref");
|
||||
|
||||
var candidates = GetRecursiveChildren(user).Where(i => i.IncludeInIndex).ToList();
|
||||
|
||||
return candidates.AsParallel().SelectMany(i => i.AllStudios)
|
||||
.Distinct()
|
||||
.Select(i =>
|
||||
{
|
||||
try
|
||||
{
|
||||
return LibraryManager.GetStudio(i);
|
||||
}
|
||||
catch (IOException ex)
|
||||
{
|
||||
Logger.ErrorException("Error getting studio {0}", ex, i);
|
||||
return null;
|
||||
}
|
||||
catch (AggregateException ex)
|
||||
{
|
||||
Logger.ErrorException("Error getting studio {0}", ex, i);
|
||||
return null;
|
||||
}
|
||||
})
|
||||
.Where(i => i != null)
|
||||
.Select(ndx => new IndexFolder(this, ndx, candidates.Where(i => i.AllStudios.Any(s => s.Equals(ndx.Name, StringComparison.OrdinalIgnoreCase))), indexName));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the index by genre.
|
||||
/// </summary>
|
||||
/// <param name="user">The user.</param>
|
||||
/// <returns>IEnumerable{BaseItem}.</returns>
|
||||
protected IEnumerable<BaseItem> GetIndexByGenre(User user)
|
||||
{
|
||||
// Even though this implementation means multiple iterations over the target list - it allows us to defer
|
||||
// the retrieval of the individual children for each index value until they are requested.
|
||||
using (new Profiler("Genre Index Build for " + Name, Logger))
|
||||
{
|
||||
var indexName = LocalizedStrings.Instance.GetString("GenreDispPref");
|
||||
|
||||
//we need a copy of this so we don't double-recurse
|
||||
var candidates = GetRecursiveChildren(user).Where(i => i.IncludeInIndex).ToList();
|
||||
|
||||
return candidates.AsParallel().SelectMany(i => i.AllGenres)
|
||||
.Distinct(StringComparer.OrdinalIgnoreCase)
|
||||
.Select(i =>
|
||||
{
|
||||
try
|
||||
{
|
||||
return LibraryManager.GetGenre(i);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.ErrorException("Error getting genre {0}", ex, i);
|
||||
return null;
|
||||
}
|
||||
})
|
||||
.Where(i => i != null)
|
||||
.Select(genre => new IndexFolder(this, genre, candidates.Where(i => i.AllGenres.Any(g => g.Equals(genre.Name, StringComparison.OrdinalIgnoreCase))), indexName)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the index by year.
|
||||
/// </summary>
|
||||
/// <param name="user">The user.</param>
|
||||
/// <returns>IEnumerable{BaseItem}.</returns>
|
||||
protected IEnumerable<BaseItem> GetIndexByYear(User user)
|
||||
{
|
||||
// Even though this implementation means multiple iterations over the target list - it allows us to defer
|
||||
// the retrieval of the individual children for each index value until they are requested.
|
||||
using (new Profiler("Production Year Index Build for " + Name, Logger))
|
||||
{
|
||||
var indexName = LocalizedStrings.Instance.GetString("YearDispPref");
|
||||
|
||||
//we need a copy of this so we don't double-recurse
|
||||
var candidates = GetRecursiveChildren(user).Where(i => i.IncludeInIndex && i.ProductionYear.HasValue).ToList();
|
||||
|
||||
return candidates.AsParallel().Select(i => i.ProductionYear.Value)
|
||||
.Distinct()
|
||||
.Select(i =>
|
||||
{
|
||||
try
|
||||
{
|
||||
return LibraryManager.GetYear(i);
|
||||
}
|
||||
catch (IOException ex)
|
||||
{
|
||||
Logger.ErrorException("Error getting year {0}", ex, i);
|
||||
return null;
|
||||
}
|
||||
catch (AggregateException ex)
|
||||
{
|
||||
Logger.ErrorException("Error getting year {0}", ex, i);
|
||||
return null;
|
||||
}
|
||||
})
|
||||
.Where(i => i != null)
|
||||
|
||||
.Select(ndx => new IndexFolder(this, ndx, candidates.Where(i => i.ProductionYear == int.Parse(ndx.Name)), indexName));
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the indexed children for this user from the cache. Caches them if not already there.
|
||||
/// </summary>
|
||||
/// <param name="user">The user.</param>
|
||||
/// <param name="indexBy">The index by.</param>
|
||||
/// <returns>IEnumerable{BaseItem}.</returns>
|
||||
private IEnumerable<BaseItem> GetIndexedChildren(User user, string indexBy)
|
||||
{
|
||||
List<BaseItem> result = null;
|
||||
var cacheKey = user.Name + indexBy;
|
||||
|
||||
if (IndexCache != null)
|
||||
{
|
||||
IndexCache.TryGetValue(cacheKey, out result);
|
||||
}
|
||||
|
||||
if (result == null)
|
||||
{
|
||||
//not cached - cache it
|
||||
Func<User, IEnumerable<BaseItem>> indexing;
|
||||
IndexByOptions.TryGetValue(indexBy, out indexing);
|
||||
result = BuildIndex(indexBy, indexing, user);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the list of indexy by choices for this folder (localized).
|
||||
/// </summary>
|
||||
@ -493,31 +234,7 @@ namespace MediaBrowser.Controller.Entities
|
||||
[IgnoreDataMember]
|
||||
public IEnumerable<string> IndexByOptionStrings
|
||||
{
|
||||
get { return IndexByOptions.Keys; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The index cache
|
||||
/// </summary>
|
||||
protected ConcurrentDictionary<string, List<BaseItem>> IndexCache;
|
||||
|
||||
/// <summary>
|
||||
/// Builds the index.
|
||||
/// </summary>
|
||||
/// <param name="indexKey">The index key.</param>
|
||||
/// <param name="indexFunction">The index function.</param>
|
||||
/// <param name="user">The user.</param>
|
||||
/// <returns>List{BaseItem}.</returns>
|
||||
protected virtual List<BaseItem> BuildIndex(string indexKey, Func<User, IEnumerable<BaseItem>> indexFunction, User user)
|
||||
{
|
||||
if (IndexCache == null)
|
||||
{
|
||||
IndexCache = new ConcurrentDictionary<string, List<BaseItem>>();
|
||||
}
|
||||
|
||||
return indexFunction != null
|
||||
? IndexCache[user.Name + indexKey] = indexFunction(user).ToList()
|
||||
: null;
|
||||
get { return GetIndexByOptions(); }
|
||||
}
|
||||
|
||||
#endregion
|
||||
@ -765,12 +482,6 @@ namespace MediaBrowser.Controller.Entities
|
||||
AddChildrenInternal(newItems);
|
||||
|
||||
await ItemRepository.SaveChildren(Id, ActualChildren.Select(i => i.Id).ToList(), cancellationToken).ConfigureAwait(false);
|
||||
|
||||
//force the indexes to rebuild next time
|
||||
if (IndexCache != null)
|
||||
{
|
||||
IndexCache.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
progress.Report(10);
|
||||
@ -988,10 +699,9 @@ namespace MediaBrowser.Controller.Entities
|
||||
/// </summary>
|
||||
/// <param name="user">The user.</param>
|
||||
/// <param name="includeLinkedChildren">if set to <c>true</c> [include linked children].</param>
|
||||
/// <param name="indexBy">The index by.</param>
|
||||
/// <returns>IEnumerable{BaseItem}.</returns>
|
||||
/// <exception cref="System.ArgumentNullException"></exception>
|
||||
public virtual IEnumerable<BaseItem> GetChildren(User user, bool includeLinkedChildren, string indexBy = null)
|
||||
public virtual IEnumerable<BaseItem> GetChildren(User user, bool includeLinkedChildren)
|
||||
{
|
||||
if (user == null)
|
||||
{
|
||||
@ -999,19 +709,7 @@ namespace MediaBrowser.Controller.Entities
|
||||
}
|
||||
|
||||
//the true root should return our users root folder children
|
||||
if (IsPhysicalRoot) return user.RootFolder.GetChildren(user, includeLinkedChildren, indexBy);
|
||||
|
||||
IEnumerable<BaseItem> result = null;
|
||||
|
||||
if (!string.IsNullOrEmpty(indexBy))
|
||||
{
|
||||
result = GetIndexedChildren(user, indexBy);
|
||||
}
|
||||
|
||||
if (result != null)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
if (IsPhysicalRoot) return user.RootFolder.GetChildren(user, includeLinkedChildren);
|
||||
|
||||
var list = new List<BaseItem>();
|
||||
|
||||
|
@ -1,206 +0,0 @@
|
||||
using MediaBrowser.Common.Extensions;
|
||||
using MediaBrowser.Model.Entities;
|
||||
using MoreLinq;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Runtime.Serialization;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace MediaBrowser.Controller.Entities
|
||||
{
|
||||
/// <summary>
|
||||
/// Class IndexFolder
|
||||
/// </summary>
|
||||
public class IndexFolder : Folder
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="IndexFolder" /> class.
|
||||
/// </summary>
|
||||
/// <param name="parent">The parent.</param>
|
||||
/// <param name="shadow">The shadow.</param>
|
||||
/// <param name="children">The children.</param>
|
||||
/// <param name="indexName">Name of the index.</param>
|
||||
/// <param name="groupContents">if set to <c>true</c> [group contents].</param>
|
||||
public IndexFolder(Folder parent, BaseItem shadow, IEnumerable<BaseItem> children, string indexName, bool groupContents = true)
|
||||
{
|
||||
ChildSource = children;
|
||||
ShadowItem = shadow;
|
||||
GroupContents = groupContents;
|
||||
if (shadow == null)
|
||||
{
|
||||
Name = ForcedSortName = "<Unknown>";
|
||||
}
|
||||
else
|
||||
{
|
||||
SetShadowValues();
|
||||
}
|
||||
Id = (parent.Id.ToString() + Name).GetMBId(typeof(IndexFolder));
|
||||
|
||||
IndexName = indexName;
|
||||
Parent = parent;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Resets the parent.
|
||||
/// </summary>
|
||||
/// <param name="parent">The parent.</param>
|
||||
public void ResetParent(Folder parent)
|
||||
{
|
||||
Parent = parent;
|
||||
Id = (parent.Id.ToString() + Name).GetMBId(typeof(IndexFolder));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Override this to true if class should be grouped under a container in indicies
|
||||
/// The container class should be defined via IndexContainer
|
||||
/// </summary>
|
||||
/// <value><c>true</c> if [group in index]; otherwise, <c>false</c>.</value>
|
||||
[IgnoreDataMember]
|
||||
public override bool GroupInIndex
|
||||
{
|
||||
get
|
||||
{
|
||||
return ShadowItem != null && ShadowItem.GroupInIndex;
|
||||
}
|
||||
}
|
||||
|
||||
public override LocationType LocationType
|
||||
{
|
||||
get
|
||||
{
|
||||
return LocationType.Virtual;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Override this to return the folder that should be used to construct a container
|
||||
/// for this item in an index. GroupInIndex should be true as well.
|
||||
/// </summary>
|
||||
/// <value>The index container.</value>
|
||||
[IgnoreDataMember]
|
||||
public override Folder IndexContainer
|
||||
{
|
||||
get { return ShadowItem != null ? ShadowItem.IndexContainer : new IndexFolder(this, null, null, "<Unknown>", false); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether [group contents].
|
||||
/// </summary>
|
||||
/// <value><c>true</c> if [group contents]; otherwise, <c>false</c>.</value>
|
||||
protected bool GroupContents { get; set; }
|
||||
/// <summary>
|
||||
/// Gets or sets the child source.
|
||||
/// </summary>
|
||||
/// <value>The child source.</value>
|
||||
protected IEnumerable<BaseItem> ChildSource { get; set; }
|
||||
/// <summary>
|
||||
/// Gets or sets our children.
|
||||
/// </summary>
|
||||
/// <value>Our children.</value>
|
||||
protected ConcurrentBag<BaseItem> OurChildren { get; set; }
|
||||
/// <summary>
|
||||
/// Gets the name of the index.
|
||||
/// </summary>
|
||||
/// <value>The name of the index.</value>
|
||||
public string IndexName { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Override to return the children defined to us when we were created
|
||||
/// </summary>
|
||||
/// <value>The actual children.</value>
|
||||
protected override IEnumerable<BaseItem> LoadChildren()
|
||||
{
|
||||
var originalChildSource = ChildSource.ToList();
|
||||
|
||||
var kids = originalChildSource;
|
||||
if (GroupContents)
|
||||
{
|
||||
// Recursively group up the chain
|
||||
var group = true;
|
||||
var isSubsequentLoop = false;
|
||||
|
||||
while (group)
|
||||
{
|
||||
kids = isSubsequentLoop || kids.Any(i => i.GroupInIndex)
|
||||
? GroupedSource(kids).ToList()
|
||||
: originalChildSource;
|
||||
|
||||
group = kids.Any(i => i.GroupInIndex);
|
||||
isSubsequentLoop = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Now - since we built the index grouping from the bottom up - we now need to properly set Parents from the top down
|
||||
SetParents(this, kids.OfType<IndexFolder>());
|
||||
|
||||
return kids.DistinctBy(i => i.Id);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the parents.
|
||||
/// </summary>
|
||||
/// <param name="parent">The parent.</param>
|
||||
/// <param name="kids">The kids.</param>
|
||||
private void SetParents(Folder parent, IEnumerable<IndexFolder> kids)
|
||||
{
|
||||
foreach (var child in kids)
|
||||
{
|
||||
child.ResetParent(parent);
|
||||
child.SetParents(child, child.Children.OfType<IndexFolder>());
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Groupeds the source.
|
||||
/// </summary>
|
||||
/// <param name="source">The source.</param>
|
||||
/// <returns>IEnumerable{BaseItem}.</returns>
|
||||
protected IEnumerable<BaseItem> GroupedSource(IEnumerable<BaseItem> source)
|
||||
{
|
||||
return source.GroupBy(i => i.IndexContainer).Select(container => new IndexFolder(this, container.Key, container, null, false));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The item we are shadowing as a folder (Genre, Actor, etc.)
|
||||
/// We inherit the images and other meta from this item
|
||||
/// </summary>
|
||||
/// <value>The shadow item.</value>
|
||||
protected BaseItem ShadowItem { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Sets the shadow values.
|
||||
/// </summary>
|
||||
protected void SetShadowValues()
|
||||
{
|
||||
if (ShadowItem != null)
|
||||
{
|
||||
Name = ShadowItem.Name;
|
||||
ForcedSortName = ShadowItem.SortName;
|
||||
Genres = ShadowItem.Genres;
|
||||
Studios = ShadowItem.Studios;
|
||||
OfficialRating = ShadowItem.OfficialRatingForComparison;
|
||||
BackdropImagePaths = ShadowItem.BackdropImagePaths;
|
||||
Images = ShadowItem.Images;
|
||||
Overview = ShadowItem.Overview;
|
||||
DisplayMediaType = ShadowItem.GetType().Name;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Overrides the base implementation to refresh metadata for local trailers
|
||||
/// </summary>
|
||||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
/// <param name="forceSave">if set to <c>true</c> [is new item].</param>
|
||||
/// <param name="forceRefresh">if set to <c>true</c> [force].</param>
|
||||
/// <param name="allowSlowProviders">if set to <c>true</c> [allow slow providers].</param>
|
||||
/// <param name="resetResolveArgs">if set to <c>true</c> [reset resolve args].</param>
|
||||
/// <returns>Task{System.Boolean}.</returns>
|
||||
public override Task<bool> RefreshMetadata(CancellationToken cancellationToken, bool forceSave = false, bool forceRefresh = false, bool allowSlowProviders = true, bool resetResolveArgs = true)
|
||||
{
|
||||
// We should never get in here since these are not part of the library
|
||||
return Task.FromResult(false);
|
||||
}
|
||||
}
|
||||
}
|
@ -57,13 +57,13 @@ namespace MediaBrowser.Controller.Entities.TV
|
||||
}
|
||||
|
||||
// Genre, Rating and Stuido will all be the same
|
||||
protected override Dictionary<string, Func<User, IEnumerable<BaseItem>>> GetIndexByOptions()
|
||||
protected override IEnumerable<string> GetIndexByOptions()
|
||||
{
|
||||
return new Dictionary<string, Func<User, IEnumerable<BaseItem>>> {
|
||||
{LocalizedStrings.Instance.GetString("NoneDispPref"), null},
|
||||
{LocalizedStrings.Instance.GetString("PerformerDispPref"), GetIndexByPerformer},
|
||||
{LocalizedStrings.Instance.GetString("DirectorDispPref"), GetIndexByDirector},
|
||||
{LocalizedStrings.Instance.GetString("YearDispPref"), GetIndexByYear},
|
||||
return new List<string> {
|
||||
{LocalizedStrings.Instance.GetString("NoneDispPref")},
|
||||
{LocalizedStrings.Instance.GetString("PerformerDispPref")},
|
||||
{LocalizedStrings.Instance.GetString("DirectorDispPref")},
|
||||
{LocalizedStrings.Instance.GetString("YearDispPref")},
|
||||
};
|
||||
}
|
||||
|
||||
@ -240,7 +240,7 @@ namespace MediaBrowser.Controller.Entities.TV
|
||||
.Cast<Episode>();
|
||||
}
|
||||
|
||||
public override IEnumerable<BaseItem> GetChildren(User user, bool includeLinkedChildren, string indexBy = null)
|
||||
public override IEnumerable<BaseItem> GetChildren(User user, bool includeLinkedChildren)
|
||||
{
|
||||
return GetEpisodes(user);
|
||||
}
|
||||
|
@ -89,13 +89,13 @@ namespace MediaBrowser.Controller.Entities.TV
|
||||
}
|
||||
|
||||
// Studio, Genre and Rating will all be the same so makes no sense to index by these
|
||||
protected override Dictionary<string, Func<User, IEnumerable<BaseItem>>> GetIndexByOptions()
|
||||
protected override IEnumerable<string> GetIndexByOptions()
|
||||
{
|
||||
return new Dictionary<string, Func<User, IEnumerable<BaseItem>>> {
|
||||
{LocalizedStrings.Instance.GetString("NoneDispPref"), null},
|
||||
{LocalizedStrings.Instance.GetString("PerformerDispPref"), GetIndexByPerformer},
|
||||
{LocalizedStrings.Instance.GetString("DirectorDispPref"), GetIndexByDirector},
|
||||
{LocalizedStrings.Instance.GetString("YearDispPref"), GetIndexByYear},
|
||||
return new List<string> {
|
||||
{LocalizedStrings.Instance.GetString("NoneDispPref")},
|
||||
{LocalizedStrings.Instance.GetString("PerformerDispPref")},
|
||||
{LocalizedStrings.Instance.GetString("DirectorDispPref")},
|
||||
{LocalizedStrings.Instance.GetString("YearDispPref")},
|
||||
};
|
||||
}
|
||||
|
||||
@ -122,7 +122,7 @@ namespace MediaBrowser.Controller.Entities.TV
|
||||
}
|
||||
}
|
||||
|
||||
public override IEnumerable<BaseItem> GetChildren(User user, bool includeLinkedChildren, string indexBy = null)
|
||||
public override IEnumerable<BaseItem> GetChildren(User user, bool includeLinkedChildren)
|
||||
{
|
||||
return GetSeasons(user);
|
||||
}
|
||||
|
@ -147,7 +147,6 @@
|
||||
<Compile Include="Entities\Folder.cs" />
|
||||
<Compile Include="Entities\Genre.cs" />
|
||||
<Compile Include="Entities\ICollectionFolder.cs" />
|
||||
<Compile Include="Entities\IndexFolder.cs" />
|
||||
<Compile Include="Entities\IVirtualFolderCreator.cs" />
|
||||
<Compile Include="Entities\Movies\BoxSet.cs" />
|
||||
<Compile Include="Entities\Movies\Movie.cs" />
|
||||
|
@ -140,12 +140,6 @@ namespace MediaBrowser.Model.Querying
|
||||
/// <value>The index by.</value>
|
||||
public string SearchTerm { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The dynamic, localized index function name
|
||||
/// </summary>
|
||||
/// <value>The index by.</value>
|
||||
public string IndexBy { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the image types.
|
||||
/// </summary>
|
||||
|
@ -292,8 +292,6 @@ namespace MediaBrowser.Server.Implementations.Dto
|
||||
return info;
|
||||
}
|
||||
|
||||
const string IndexFolderDelimeter = "-index-";
|
||||
|
||||
/// <summary>
|
||||
/// Gets client-side Id of a server-side BaseItem
|
||||
/// </summary>
|
||||
@ -307,13 +305,6 @@ namespace MediaBrowser.Server.Implementations.Dto
|
||||
throw new ArgumentNullException("item");
|
||||
}
|
||||
|
||||
var indexFolder = item as IndexFolder;
|
||||
|
||||
if (indexFolder != null)
|
||||
{
|
||||
return GetDtoId(indexFolder.Parent) + IndexFolderDelimeter + (indexFolder.IndexName ?? string.Empty) + IndexFolderDelimeter + indexFolder.Id;
|
||||
}
|
||||
|
||||
return item.Id.ToString("N");
|
||||
}
|
||||
|
||||
@ -618,26 +609,15 @@ namespace MediaBrowser.Server.Implementations.Dto
|
||||
throw new ArgumentNullException("id");
|
||||
}
|
||||
|
||||
// If the item is an indexed folder we have to do a special routine to get it
|
||||
var isIndexFolder = id.IndexOf(IndexFolderDelimeter, StringComparison.OrdinalIgnoreCase) != -1;
|
||||
|
||||
if (isIndexFolder)
|
||||
{
|
||||
if (userId.HasValue)
|
||||
{
|
||||
return GetIndexFolder(id, userId.Value);
|
||||
}
|
||||
}
|
||||
|
||||
BaseItem item = null;
|
||||
|
||||
if (userId.HasValue || !isIndexFolder)
|
||||
if (userId.HasValue)
|
||||
{
|
||||
item = _libraryManager.GetItemById(new Guid(id));
|
||||
}
|
||||
|
||||
// If we still don't find it, look within individual user views
|
||||
if (item == null && !userId.HasValue && isIndexFolder)
|
||||
if (item == null && !userId.HasValue)
|
||||
{
|
||||
foreach (var user in _userManager.Users)
|
||||
{
|
||||
@ -653,60 +633,6 @@ namespace MediaBrowser.Server.Implementations.Dto
|
||||
return item;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Finds an index folder based on an Id and userId
|
||||
/// </summary>
|
||||
/// <param name="id">The id.</param>
|
||||
/// <param name="userId">The user id.</param>
|
||||
/// <returns>BaseItem.</returns>
|
||||
private BaseItem GetIndexFolder(string id, Guid userId)
|
||||
{
|
||||
var user = _userManager.GetUserById(userId);
|
||||
|
||||
var stringSeparators = new[] { IndexFolderDelimeter };
|
||||
|
||||
// Split using the delimeter
|
||||
var values = id.Split(stringSeparators, StringSplitOptions.None).ToList();
|
||||
|
||||
// Get the top folder normally using the first id
|
||||
var folder = GetItemByDtoId(values[0], userId) as Folder;
|
||||
|
||||
values.RemoveAt(0);
|
||||
|
||||
// Get indexed folders using the remaining values in the id string
|
||||
return GetIndexFolder(values, folder, user);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets indexed folders based on a list of index names and folder id's
|
||||
/// </summary>
|
||||
/// <param name="values">The values.</param>
|
||||
/// <param name="parentFolder">The parent folder.</param>
|
||||
/// <param name="user">The user.</param>
|
||||
/// <returns>BaseItem.</returns>
|
||||
private BaseItem GetIndexFolder(List<string> values, Folder parentFolder, User user)
|
||||
{
|
||||
// The index name is first
|
||||
var indexBy = values[0];
|
||||
|
||||
// The index folder id is next
|
||||
var indexFolderId = new Guid(values[1]);
|
||||
|
||||
// Remove them from the lst
|
||||
values.RemoveRange(0, 2);
|
||||
|
||||
// Get the IndexFolder
|
||||
var indexFolder = parentFolder.GetChildren(user, false, indexBy).FirstOrDefault(i => i.Id == indexFolderId) as Folder;
|
||||
|
||||
// Nested index folder
|
||||
if (values.Count > 0)
|
||||
{
|
||||
return GetIndexFolder(values, indexFolder, user);
|
||||
}
|
||||
|
||||
return indexFolder;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets simple property values on a DTOBaseItem
|
||||
/// </summary>
|
||||
|
@ -100,7 +100,7 @@ namespace MediaBrowser.ServerApplication
|
||||
var prefs = ddlProfile.SelectedItem != null ? _displayPreferencesManager.GetDisplayPreferences(currentFolder.DisplayPreferencesId, (ddlProfile.SelectedItem as User).Id, "LibraryExplorer") ?? new DisplayPreferences { SortBy = ItemSortBy.SortName } : new DisplayPreferences { SortBy = ItemSortBy.SortName };
|
||||
var node = new TreeViewItem { Tag = currentFolder };
|
||||
|
||||
var subChildren = currentFolder.GetChildren(CurrentUser, true, prefs.IndexBy);
|
||||
var subChildren = currentFolder.GetChildren(CurrentUser, true);
|
||||
subChildren = OrderByName(subChildren, CurrentUser);
|
||||
AddChildren(node, subChildren, CurrentUser);
|
||||
node.Header = currentFolder.Name + " (" +
|
||||
@ -371,7 +371,7 @@ namespace MediaBrowser.ServerApplication
|
||||
//re-build the current item's children as an index
|
||||
prefs.IndexBy = ddlIndexBy.SelectedItem as string;
|
||||
treeItem.Items.Clear();
|
||||
AddChildren(treeItem, OrderBy(folder.GetChildren(CurrentUser, true, prefs.IndexBy), CurrentUser, prefs.SortBy), CurrentUser);
|
||||
AddChildren(treeItem, OrderBy(folder.GetChildren(CurrentUser, true), CurrentUser, prefs.SortBy), CurrentUser);
|
||||
treeItem.Header = folder.Name + "(" +
|
||||
treeItem.Items.Count + ")";
|
||||
Cursor = Cursors.Arrow;
|
||||
@ -412,7 +412,7 @@ namespace MediaBrowser.ServerApplication
|
||||
//re-sort
|
||||
prefs.SortBy = ddlSortBy.SelectedItem as string;
|
||||
treeItem.Items.Clear();
|
||||
AddChildren(treeItem, OrderBy(folder.GetChildren(CurrentUser, true, prefs.IndexBy), CurrentUser, prefs.SortBy ?? ItemSortBy.SortName), CurrentUser);
|
||||
AddChildren(treeItem, OrderBy(folder.GetChildren(CurrentUser, true), CurrentUser, prefs.SortBy ?? ItemSortBy.SortName), CurrentUser);
|
||||
treeItem.Header = folder.Name + "(" +
|
||||
treeItem.Items.Count + ")";
|
||||
Cursor = Cursors.Arrow;
|
||||
|
Loading…
x
Reference in New Issue
Block a user