aboutsummaryrefslogtreecommitdiff
path: root/MediaBrowser.Controller/Entities/Folder.cs
diff options
context:
space:
mode:
Diffstat (limited to 'MediaBrowser.Controller/Entities/Folder.cs')
-rw-r--r--MediaBrowser.Controller/Entities/Folder.cs116
1 files changed, 109 insertions, 7 deletions
diff --git a/MediaBrowser.Controller/Entities/Folder.cs b/MediaBrowser.Controller/Entities/Folder.cs
index c6d6bf221..297d513e5 100644
--- a/MediaBrowser.Controller/Entities/Folder.cs
+++ b/MediaBrowser.Controller/Entities/Folder.cs
@@ -1,5 +1,6 @@
using MediaBrowser.Common.Extensions;
using MediaBrowser.Common.Progress;
+using MediaBrowser.Controller.IO;
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.Localization;
using MediaBrowser.Controller.Persistence;
@@ -21,6 +22,11 @@ namespace MediaBrowser.Controller.Entities
/// </summary>
public class Folder : BaseItem
{
+ public Folder()
+ {
+ LinkedChildren = new List<LinkedChild>();
+ }
+
/// <summary>
/// Gets a value indicating whether this instance is folder.
/// </summary>
@@ -83,6 +89,13 @@ namespace MediaBrowser.Controller.Entities
return (userId + DisplayPreferencesId.ToString()).GetMD5();
}
+ public List<LinkedChild> LinkedChildren { get; set; }
+
+ protected virtual bool SupportsLinkedChildren
+ {
+ get { return false; }
+ }
+
/// <summary>
/// Adds the child.
/// </summary>
@@ -878,10 +891,11 @@ namespace MediaBrowser.Controller.Entities
/// Gets allowed children of an item
/// </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, string indexBy = null)
+ public virtual IEnumerable<BaseItem> GetChildren(User user, bool includeLinkedChildren, string indexBy = null)
{
if (user == null)
{
@@ -889,7 +903,7 @@ namespace MediaBrowser.Controller.Entities
}
//the true root should return our users root folder children
- if (IsPhysicalRoot) return user.RootFolder.GetChildren(user, indexBy);
+ if (IsPhysicalRoot) return user.RootFolder.GetChildren(user, includeLinkedChildren, indexBy);
IEnumerable<BaseItem> result = null;
@@ -898,24 +912,37 @@ namespace MediaBrowser.Controller.Entities
result = GetIndexedChildren(user, indexBy);
}
+ if (result != null)
+ {
+ return result;
+ }
+
+ var children = Children;
+
+ if (includeLinkedChildren)
+ {
+ children = children.Concat(GetLinkedChildren());
+ }
+
// If indexed is false or the indexing function is null
- return result ?? (Children.Where(c => c.IsVisible(user)));
+ return children.Where(c => c.IsVisible(user));
}
/// <summary>
/// Gets allowed recursive children of an item
/// </summary>
/// <param name="user">The user.</param>
+ /// <param name="includeLinkedChildren">if set to <c>true</c> [include linked children].</param>
/// <returns>IEnumerable{BaseItem}.</returns>
/// <exception cref="System.ArgumentNullException"></exception>
- public IEnumerable<BaseItem> GetRecursiveChildren(User user)
+ public IEnumerable<BaseItem> GetRecursiveChildren(User user, bool includeLinkedChildren = false)
{
if (user == null)
{
throw new ArgumentNullException();
}
- foreach (var item in GetChildren(user))
+ foreach (var item in GetChildren(user, includeLinkedChildren))
{
yield return item;
@@ -923,7 +950,7 @@ namespace MediaBrowser.Controller.Entities
if (subFolder != null)
{
- foreach (var subitem in subFolder.GetRecursiveChildren(user))
+ foreach (var subitem in subFolder.GetRecursiveChildren(user, includeLinkedChildren))
{
yield return subitem;
}
@@ -932,6 +959,81 @@ namespace MediaBrowser.Controller.Entities
}
/// <summary>
+ /// Gets the linked children.
+ /// </summary>
+ /// <returns>IEnumerable{BaseItem}.</returns>
+ public IEnumerable<BaseItem> GetLinkedChildren()
+ {
+ return LinkedChildren
+ .Select(i => LibraryManager.RootFolder.FindByPath(i.Path))
+ .Where(i => i != null);
+ }
+
+ public override async Task<bool> RefreshMetadata(CancellationToken cancellationToken, bool forceSave = false, bool forceRefresh = false, bool allowSlowProviders = true, bool resetResolveArgs = true)
+ {
+ var changed = await base.RefreshMetadata(cancellationToken, forceSave, forceRefresh, allowSlowProviders, resetResolveArgs).ConfigureAwait(false);
+
+ return changed || (SupportsLinkedChildren && RefreshLinkedChildren());
+ }
+
+ /// <summary>
+ /// Refreshes the linked children.
+ /// </summary>
+ /// <returns><c>true</c> if XXXX, <c>false</c> otherwise</returns>
+ private bool RefreshLinkedChildren()
+ {
+ ItemResolveArgs resolveArgs;
+
+ try
+ {
+ resolveArgs = ResolveArgs;
+
+ if (!resolveArgs.IsDirectory)
+ {
+ return false;
+ }
+ }
+ catch (IOException ex)
+ {
+ Logger.ErrorException("Error getting ResolveArgs for {0}", ex, Path);
+ return false;
+ }
+
+ var currentManualLinks = LinkedChildren.Where(i => i.Type == LinkedChildType.Manual).ToList();
+ var currentShortcutLinks = LinkedChildren.Where(i => i.Type == LinkedChildType.Shortcut).ToList();
+
+ var newShortcutLinks = resolveArgs.FileSystemChildren
+ .Where(i => (i.Attributes & FileAttributes.Directory) != FileAttributes.Directory && FileSystem.IsShortcut(i.FullName))
+ .Select(i =>
+ {
+ try
+ {
+ return new LinkedChild
+ {
+ Path = FileSystem.ResolveShortcut(i.FullName),
+ Type = LinkedChildType.Shortcut
+ };
+ }
+ catch (IOException ex)
+ {
+ Logger.ErrorException("Error resolving shortcut {0}", ex, i.FullName);
+ return null;
+ }
+ })
+ .Where(i => i != null)
+ .ToList();
+
+ if (!newShortcutLinks.SequenceEqual(currentShortcutLinks))
+ {
+ newShortcutLinks.AddRange(currentManualLinks);
+ LinkedChildren = newShortcutLinks;
+ return true;
+ }
+
+ return false;
+ }
+
+ /// <summary>
/// Folders need to validate and refresh
/// </summary>
/// <returns>Task.</returns>
@@ -954,7 +1056,7 @@ namespace MediaBrowser.Controller.Entities
public override async Task SetPlayedStatus(User user, bool wasPlayed, IUserDataRepository userManager)
{
// Sweep through recursively and update status
- var tasks = GetRecursiveChildren(user).Where(i => !i.IsFolder).Select(c => c.SetPlayedStatus(user, wasPlayed, userManager));
+ var tasks = GetRecursiveChildren(user, true).Where(i => !i.IsFolder).Select(c => c.SetPlayedStatus(user, wasPlayed, userManager));
await Task.WhenAll(tasks).ConfigureAwait(false);
}