aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--MediaBrowser.Api/UserLibrary/ItemsService.cs43
-rw-r--r--MediaBrowser.Controller/Dlna/DeviceProfile.cs (renamed from MediaBrowser.Controller/Dlna/DlnaProfile.cs)4
-rw-r--r--MediaBrowser.Controller/Dlna/DirectPlayProfile.cs86
-rw-r--r--MediaBrowser.Controller/Dlna/IDlnaManager.cs6
-rw-r--r--MediaBrowser.Controller/Entities/ISupportsBoxSetGrouping.cs19
-rw-r--r--MediaBrowser.Controller/Entities/Movies/Movie.cs13
-rw-r--r--MediaBrowser.Controller/MediaBrowser.Controller.csproj3
-rw-r--r--MediaBrowser.Dlna/DlnaManager.cs48
-rw-r--r--MediaBrowser.Dlna/PlayTo/PlaylistItem.cs4
-rw-r--r--MediaBrowser.Server.Implementations/Collections/CollectionManager.cs22
-rw-r--r--MediaBrowser.Server.Implementations/Library/Validators/BoxSetPostScanTask.cs50
-rw-r--r--MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj1
-rw-r--r--MediaBrowser.ServerApplication/ApplicationHost.cs2
13 files changed, 268 insertions, 33 deletions
diff --git a/MediaBrowser.Api/UserLibrary/ItemsService.cs b/MediaBrowser.Api/UserLibrary/ItemsService.cs
index b040d3dd8..ec00be988 100644
--- a/MediaBrowser.Api/UserLibrary/ItemsService.cs
+++ b/MediaBrowser.Api/UserLibrary/ItemsService.cs
@@ -238,6 +238,9 @@ namespace MediaBrowser.Api.UserLibrary
[ApiMember(Name = "HasOfficialRating", Description = "Optional filter by items that have official ratings", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")]
public bool? HasOfficialRating { get; set; }
+
+ [ApiMember(Name = "CollapseBoxSetItems", Description = "Whether or not to hide items behind their boxsets.", IsRequired = false, DataType = "bool", ParameterType = "query", Verb = "GET")]
+ public bool CollapseBoxSetItems { get; set; }
}
/// <summary>
@@ -315,6 +318,11 @@ namespace MediaBrowser.Api.UserLibrary
items = items.AsEnumerable();
+ if (request.CollapseBoxSetItems)
+ {
+ items = CollapseItemsWithinBoxSets(items, user);
+ }
+
items = ApplySortOrder(request, items, user, _libraryManager);
// This must be the last filter
@@ -1218,6 +1226,41 @@ namespace MediaBrowser.Api.UserLibrary
return false;
}
+ private IEnumerable<BaseItem> CollapseItemsWithinBoxSets(IEnumerable<BaseItem> items, User user)
+ {
+ var itemsToCollapse = new List<ISupportsBoxSetGrouping>();
+ var boxsets = new List<BaseItem>();
+
+ var list = items.ToList();
+
+ foreach (var item in list.OfType<ISupportsBoxSetGrouping>())
+ {
+ var currentBoxSets = item.BoxSetIdList
+ .Select(i => _libraryManager.GetItemById(i))
+ .Where(i => i != null && i.IsVisible(user))
+ .ToList();
+
+ if (currentBoxSets.Count > 0)
+ {
+ itemsToCollapse.Add(item);
+ boxsets.AddRange(currentBoxSets);
+ }
+ }
+
+ return list.Except(itemsToCollapse.Cast<BaseItem>()).Concat(boxsets).Distinct();
+ }
+
+ private bool AllowBoxSetCollapsing(GetItems request)
+ {
+ // Only allow when using default sort order
+ if (!string.IsNullOrEmpty(request.SortBy) && !string.Equals(request.SortBy, "SortName", StringComparison.OrdinalIgnoreCase))
+ {
+ return false;
+ }
+
+ return true;
+ }
+
internal static IEnumerable<BaseItem> FilterForAdjacency(IEnumerable<BaseItem> items, string adjacentToId)
{
var list = items.ToList();
diff --git a/MediaBrowser.Controller/Dlna/DlnaProfile.cs b/MediaBrowser.Controller/Dlna/DeviceProfile.cs
index 33f95b794..3fecf957b 100644
--- a/MediaBrowser.Controller/Dlna/DlnaProfile.cs
+++ b/MediaBrowser.Controller/Dlna/DeviceProfile.cs
@@ -1,7 +1,7 @@

namespace MediaBrowser.Controller.Dlna
{
- public class DlnaProfile
+ public class DeviceProfile
{
/// <summary>
/// Gets or sets the name.
@@ -45,7 +45,7 @@ namespace MediaBrowser.Controller.Dlna
/// <value>The direct play profiles.</value>
public DirectPlayProfile[] DirectPlayProfiles { get; set; }
- public DlnaProfile()
+ public DeviceProfile()
{
DirectPlayProfiles = new DirectPlayProfile[] { };
TranscodingProfiles = new TranscodingProfile[] { };
diff --git a/MediaBrowser.Controller/Dlna/DirectPlayProfile.cs b/MediaBrowser.Controller/Dlna/DirectPlayProfile.cs
index f1922dd32..8c35b52a8 100644
--- a/MediaBrowser.Controller/Dlna/DirectPlayProfile.cs
+++ b/MediaBrowser.Controller/Dlna/DirectPlayProfile.cs
@@ -1,25 +1,97 @@
-
+using System;
+using System.Collections.Generic;
+using System.Runtime.Serialization;
+using System.Xml.Serialization;
+
namespace MediaBrowser.Controller.Dlna
{
public class DirectPlayProfile
{
- public string[] Containers { get; set; }
- public string[] AudioCodecs { get; set; }
- public string[] VideoCodecs { get; set; }
+ public string Container { get; set; }
+ public string AudioCodec { get; set; }
+ public string VideoCodec { get; set; }
+
+ [IgnoreDataMember]
+ [XmlIgnore]
+ public string[] Containers
+ {
+ get
+ {
+ return (Container ?? string.Empty).Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
+ }
+ set
+ {
+ Container = value == null ? null : string.Join(",", value);
+ }
+ }
+
+ [IgnoreDataMember]
+ [XmlIgnore]
+ public string[] AudioCodecs
+ {
+ get
+ {
+ return (AudioCodec ?? string.Empty).Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
+ }
+ set
+ {
+ AudioCodec = value == null ? null : string.Join(",", value);
+ }
+ }
+
+ [IgnoreDataMember]
+ [XmlIgnore]
+ public string[] VideoCodecs
+ {
+ get
+ {
+ return (VideoCodec ?? string.Empty).Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
+ }
+ set
+ {
+ VideoCodec = value == null ? null : string.Join(",", value);
+ }
+ }
+
public string MimeType { get; set; }
public DlnaProfileType Type { get; set; }
+ public List<ProfileCondition> Conditions { get; set; }
+
public DirectPlayProfile()
{
- Containers = new string[] { };
- AudioCodecs = new string[] { };
- VideoCodecs = new string[] { };
+ Conditions = new List<ProfileCondition>();
}
}
+ public class ProfileCondition
+ {
+ public ProfileConditionType Condition { get; set; }
+ public ProfileConditionValue Value { get; set; }
+ }
+
public enum DlnaProfileType
{
Audio = 0,
Video = 1
}
+
+ public enum ProfileConditionType
+ {
+ Equals = 0,
+ NotEquals = 1,
+ LessThanEqual = 2,
+ GreaterThanEqual = 3
+ }
+
+ public enum ProfileConditionValue
+ {
+ AudioChannels,
+ AudioBitrate,
+ Filesize,
+ VideoWidth,
+ VideoHeight,
+ VideoBitrate,
+ VideoFramerate
+ }
}
diff --git a/MediaBrowser.Controller/Dlna/IDlnaManager.cs b/MediaBrowser.Controller/Dlna/IDlnaManager.cs
index 017dbc874..04f658805 100644
--- a/MediaBrowser.Controller/Dlna/IDlnaManager.cs
+++ b/MediaBrowser.Controller/Dlna/IDlnaManager.cs
@@ -8,13 +8,13 @@ namespace MediaBrowser.Controller.Dlna
/// Gets the dlna profiles.
/// </summary>
/// <returns>IEnumerable{DlnaProfile}.</returns>
- IEnumerable<DlnaProfile> GetProfiles();
+ IEnumerable<DeviceProfile> GetProfiles();
/// <summary>
/// Gets the default profile.
/// </summary>
/// <returns>DlnaProfile.</returns>
- DlnaProfile GetDefaultProfile();
+ DeviceProfile GetDefaultProfile();
/// <summary>
/// Gets the profile.
@@ -23,6 +23,6 @@ namespace MediaBrowser.Controller.Dlna
/// <param name="modelName">Name of the model.</param>
/// <param name="modelNumber">The model number.</param>
/// <returns>DlnaProfile.</returns>
- DlnaProfile GetProfile(string friendlyName, string modelName, string modelNumber);
+ DeviceProfile GetProfile(string friendlyName, string modelName, string modelNumber);
}
}
diff --git a/MediaBrowser.Controller/Entities/ISupportsBoxSetGrouping.cs b/MediaBrowser.Controller/Entities/ISupportsBoxSetGrouping.cs
new file mode 100644
index 000000000..0fd463155
--- /dev/null
+++ b/MediaBrowser.Controller/Entities/ISupportsBoxSetGrouping.cs
@@ -0,0 +1,19 @@
+using System;
+using System.Collections.Generic;
+
+namespace MediaBrowser.Controller.Entities
+{
+ /// <summary>
+ /// Marker interface to denote a class that supports being hidden underneath it's boxset.
+ /// Just about anything can be placed into a boxset,
+ /// but movies should also only appear underneath and not outside separately (subject to configuration).
+ /// </summary>
+ public interface ISupportsBoxSetGrouping
+ {
+ /// <summary>
+ /// Gets or sets the box set identifier list.
+ /// </summary>
+ /// <value>The box set identifier list.</value>
+ List<Guid> BoxSetIdList { get; set; }
+ }
+}
diff --git a/MediaBrowser.Controller/Entities/Movies/Movie.cs b/MediaBrowser.Controller/Entities/Movies/Movie.cs
index 9858dd5a9..f53b67610 100644
--- a/MediaBrowser.Controller/Entities/Movies/Movie.cs
+++ b/MediaBrowser.Controller/Entities/Movies/Movie.cs
@@ -1,11 +1,11 @@
-using MediaBrowser.Controller.Library;
-using MediaBrowser.Controller.Providers;
+using MediaBrowser.Controller.Providers;
using MediaBrowser.Model.Configuration;
using MediaBrowser.Model.Entities;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
+using System.Runtime.Serialization;
using System.Threading;
using System.Threading.Tasks;
@@ -14,7 +14,7 @@ namespace MediaBrowser.Controller.Entities.Movies
/// <summary>
/// Class Movie
/// </summary>
- public class Movie : Video, IHasCriticRating, IHasSoundtracks, IHasBudget, IHasKeywords, IHasTrailers, IHasThemeMedia, IHasTaglines, IHasPreferredMetadataLanguage, IHasAwards, IHasMetascore, IHasLookupInfo<MovieInfo>
+ public class Movie : Video, IHasCriticRating, IHasSoundtracks, IHasBudget, IHasKeywords, IHasTrailers, IHasThemeMedia, IHasTaglines, IHasPreferredMetadataLanguage, IHasAwards, IHasMetascore, IHasLookupInfo<MovieInfo>, ISupportsBoxSetGrouping
{
public List<Guid> SpecialFeatureIds { get; set; }
@@ -24,6 +24,12 @@ namespace MediaBrowser.Controller.Entities.Movies
public List<Guid> ThemeVideoIds { get; set; }
/// <summary>
+ /// This is just a cache to enable quick access by Id
+ /// </summary>
+ [IgnoreDataMember]
+ public List<Guid> BoxSetIdList { get; set; }
+
+ /// <summary>
/// Gets or sets the preferred metadata country code.
/// </summary>
/// <value>The preferred metadata country code.</value>
@@ -39,6 +45,7 @@ namespace MediaBrowser.Controller.Entities.Movies
LocalTrailerIds = new List<Guid>();
ThemeSongIds = new List<Guid>();
ThemeVideoIds = new List<Guid>();
+ BoxSetIdList = new List<Guid>();
Taglines = new List<string>();
Keywords = new List<string>();
}
diff --git a/MediaBrowser.Controller/MediaBrowser.Controller.csproj b/MediaBrowser.Controller/MediaBrowser.Controller.csproj
index 21a501b08..7e5e6d9b0 100644
--- a/MediaBrowser.Controller/MediaBrowser.Controller.csproj
+++ b/MediaBrowser.Controller/MediaBrowser.Controller.csproj
@@ -75,7 +75,7 @@
<Compile Include="Collections\ICollectionManager.cs" />
<Compile Include="Dlna\DirectPlayProfile.cs" />
<Compile Include="Dlna\IDlnaManager.cs" />
- <Compile Include="Dlna\DlnaProfile.cs" />
+ <Compile Include="Dlna\DeviceProfile.cs" />
<Compile Include="Dlna\TranscodingProfile.cs" />
<Compile Include="Drawing\IImageProcessor.cs" />
<Compile Include="Drawing\ImageFormat.cs" />
@@ -114,6 +114,7 @@
<Compile Include="Entities\ILibraryItem.cs" />
<Compile Include="Entities\ImageSourceInfo.cs" />
<Compile Include="Entities\IMetadataContainer.cs" />
+ <Compile Include="Entities\ISupportsBoxSetGrouping.cs" />
<Compile Include="Entities\ISupportsPlaceHolders.cs" />
<Compile Include="Entities\ItemImageInfo.cs" />
<Compile Include="Entities\LinkedChild.cs" />
diff --git a/MediaBrowser.Dlna/DlnaManager.cs b/MediaBrowser.Dlna/DlnaManager.cs
index 1c9cba2be..91d205b47 100644
--- a/MediaBrowser.Dlna/DlnaManager.cs
+++ b/MediaBrowser.Dlna/DlnaManager.cs
@@ -1,4 +1,7 @@
-using MediaBrowser.Controller.Dlna;
+using MediaBrowser.Common.Configuration;
+using MediaBrowser.Common.IO;
+using MediaBrowser.Controller.Dlna;
+using MediaBrowser.Model.Serialization;
using System.Collections.Generic;
using System.Text.RegularExpressions;
@@ -6,11 +9,23 @@ namespace MediaBrowser.Dlna
{
public class DlnaManager : IDlnaManager
{
- public IEnumerable<DlnaProfile> GetProfiles()
+ private IApplicationPaths _appPaths;
+ private readonly IXmlSerializer _xmlSerializer;
+ private readonly IFileSystem _fileSystem;
+
+ public DlnaManager(IXmlSerializer xmlSerializer, IFileSystem fileSystem)
+ {
+ _xmlSerializer = xmlSerializer;
+ _fileSystem = fileSystem;
+
+ //GetProfiles();
+ }
+
+ public IEnumerable<DeviceProfile> GetProfiles()
{
- var list = new List<DlnaProfile>();
+ var list = new List<DeviceProfile>();
- list.Add(new DlnaProfile
+ list.Add(new DeviceProfile
{
Name = "Samsung TV (B Series)",
ClientType = "DLNA",
@@ -59,7 +74,7 @@ namespace MediaBrowser.Dlna
}
});
- list.Add(new DlnaProfile
+ list.Add(new DeviceProfile
{
Name = "Samsung TV (E/F-series)",
ClientType = "DLNA",
@@ -107,7 +122,7 @@ namespace MediaBrowser.Dlna
}
});
- list.Add(new DlnaProfile
+ list.Add(new DeviceProfile
{
Name = "Samsung TV (C/D-series)",
ClientType = "DLNA",
@@ -154,7 +169,7 @@ namespace MediaBrowser.Dlna
}
});
- list.Add(new DlnaProfile
+ list.Add(new DeviceProfile
{
Name = "Xbox 360",
ClientType = "DLNA",
@@ -189,7 +204,7 @@ namespace MediaBrowser.Dlna
}
});
- list.Add(new DlnaProfile
+ list.Add(new DeviceProfile
{
Name = "Xbox One",
ModelName = "Xbox One",
@@ -225,7 +240,7 @@ namespace MediaBrowser.Dlna
}
});
- list.Add(new DlnaProfile
+ list.Add(new DeviceProfile
{
Name = "Sony Bravia (2012)",
ClientType = "DLNA",
@@ -262,7 +277,7 @@ namespace MediaBrowser.Dlna
});
//WDTV does not need any transcoding of the formats we support statically
- list.Add(new DlnaProfile
+ list.Add(new DeviceProfile
{
Name = "WDTV Live",
ClientType = "DLNA",
@@ -284,7 +299,7 @@ namespace MediaBrowser.Dlna
}
});
- list.Add(new DlnaProfile
+ list.Add(new DeviceProfile
{
//Linksys DMA2100us does not need any transcoding of the formats we support statically
Name = "Linksys DMA2100",
@@ -307,12 +322,17 @@ namespace MediaBrowser.Dlna
}
});
+ foreach (var item in list)
+ {
+ //_xmlSerializer.SerializeToFile(item, "d:\\" + _fileSystem.GetValidFilename(item.Name));
+ }
+
return list;
}
- public DlnaProfile GetDefaultProfile()
+ public DeviceProfile GetDefaultProfile()
{
- return new DlnaProfile
+ return new DeviceProfile
{
TranscodingProfiles = new[]
{
@@ -345,7 +365,7 @@ namespace MediaBrowser.Dlna
};
}
- public DlnaProfile GetProfile(string friendlyName, string modelName, string modelNumber)
+ public DeviceProfile GetProfile(string friendlyName, string modelName, string modelNumber)
{
foreach (var profile in GetProfiles())
{
diff --git a/MediaBrowser.Dlna/PlayTo/PlaylistItem.cs b/MediaBrowser.Dlna/PlayTo/PlaylistItem.cs
index cfb2c7d1c..4f776807e 100644
--- a/MediaBrowser.Dlna/PlayTo/PlaylistItem.cs
+++ b/MediaBrowser.Dlna/PlayTo/PlaylistItem.cs
@@ -31,7 +31,7 @@ namespace MediaBrowser.Dlna.PlayTo
public long StartPositionTicks { get; set; }
- public static PlaylistItem Create(BaseItem item, DlnaProfile profile)
+ public static PlaylistItem Create(BaseItem item, DeviceProfile profile)
{
var playlistItem = new PlaylistItem
{
@@ -92,7 +92,7 @@ namespace MediaBrowser.Dlna.PlayTo
return true;
}
- private static bool IsSupported(DlnaProfile profile, TranscodingProfile transcodingProfile, string path)
+ private static bool IsSupported(DeviceProfile profile, TranscodingProfile transcodingProfile, string path)
{
// Placeholder for future conditions
return true;
diff --git a/MediaBrowser.Server.Implementations/Collections/CollectionManager.cs b/MediaBrowser.Server.Implementations/Collections/CollectionManager.cs
index 9a196cc47..8e70c1d3d 100644
--- a/MediaBrowser.Server.Implementations/Collections/CollectionManager.cs
+++ b/MediaBrowser.Server.Implementations/Collections/CollectionManager.cs
@@ -126,6 +126,18 @@ namespace MediaBrowser.Server.Implementations.Collections
ItemType = item.GetType().Name,
Type = LinkedChildType.Manual
});
+
+ var supportsGrouping = item as ISupportsBoxSetGrouping;
+
+ if (supportsGrouping != null)
+ {
+ var boxsetIdList = supportsGrouping.BoxSetIdList.ToList();
+ if (!boxsetIdList.Contains(collectionId))
+ {
+ boxsetIdList.Add(collectionId);
+ }
+ supportsGrouping.BoxSetIdList = boxsetIdList;
+ }
}
collection.LinkedChildren.AddRange(list);
@@ -156,6 +168,16 @@ namespace MediaBrowser.Server.Implementations.Collections
}
list.Add(child);
+
+ var childItem = _libraryManager.GetItemById(itemId);
+ var supportsGrouping = childItem as ISupportsBoxSetGrouping;
+
+ if (supportsGrouping != null)
+ {
+ var boxsetIdList = supportsGrouping.BoxSetIdList.ToList();
+ boxsetIdList.Remove(collectionId);
+ supportsGrouping.BoxSetIdList = boxsetIdList;
+ }
}
var shortcutFiles = Directory
diff --git a/MediaBrowser.Server.Implementations/Library/Validators/BoxSetPostScanTask.cs b/MediaBrowser.Server.Implementations/Library/Validators/BoxSetPostScanTask.cs
new file mode 100644
index 000000000..f02c907c6
--- /dev/null
+++ b/MediaBrowser.Server.Implementations/Library/Validators/BoxSetPostScanTask.cs
@@ -0,0 +1,50 @@
+using MediaBrowser.Controller.Entities;
+using MediaBrowser.Controller.Entities.Movies;
+using MediaBrowser.Controller.Library;
+using System;
+using System.Linq;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace MediaBrowser.Server.Implementations.Library.Validators
+{
+ public class BoxSetPostScanTask : ILibraryPostScanTask
+ {
+ private readonly ILibraryManager _libraryManager;
+
+ public BoxSetPostScanTask(ILibraryManager libraryManager)
+ {
+ _libraryManager = libraryManager;
+ }
+
+ public Task Run(IProgress<double> progress, CancellationToken cancellationToken)
+ {
+ var items = _libraryManager.RootFolder.RecursiveChildren.ToList();
+
+ var boxsets = items.OfType<BoxSet>().ToList();
+
+ var numComplete = 0;
+
+ foreach (var boxset in boxsets)
+ {
+ foreach (var child in boxset.GetLinkedChildren().OfType<ISupportsBoxSetGrouping>())
+ {
+ var boxsetIdList = child.BoxSetIdList.ToList();
+ if (!boxsetIdList.Contains(boxset.Id))
+ {
+ boxsetIdList.Add(boxset.Id);
+ }
+ child.BoxSetIdList = boxsetIdList;
+ }
+
+ numComplete++;
+ double percent = numComplete;
+ percent /= boxsets.Count;
+ progress.Report(percent * 100);
+ }
+
+ progress.Report(100);
+ return Task.FromResult(true);
+ }
+ }
+}
diff --git a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj
index c44b60845..871565133 100644
--- a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj
+++ b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj
@@ -165,6 +165,7 @@
<Compile Include="Library\UserManager.cs" />
<Compile Include="Library\Validators\ArtistsPostScanTask.cs" />
<Compile Include="Library\Validators\ArtistsValidator.cs" />
+ <Compile Include="Library\Validators\BoxSetPostScanTask.cs" />
<Compile Include="Library\Validators\CountHelpers.cs" />
<Compile Include="Library\Validators\GameGenresPostScanTask.cs" />
<Compile Include="Library\Validators\GameGenresValidator.cs" />
diff --git a/MediaBrowser.ServerApplication/ApplicationHost.cs b/MediaBrowser.ServerApplication/ApplicationHost.cs
index 32932fe0b..f55f18cc3 100644
--- a/MediaBrowser.ServerApplication/ApplicationHost.cs
+++ b/MediaBrowser.ServerApplication/ApplicationHost.cs
@@ -492,7 +492,7 @@ namespace MediaBrowser.ServerApplication
var appThemeManager = new AppThemeManager(ApplicationPaths, FileSystemManager, JsonSerializer, Logger);
RegisterSingleInstance<IAppThemeManager>(appThemeManager);
- var dlnaManager = new DlnaManager();
+ var dlnaManager = new DlnaManager(XmlSerializer, FileSystemManager);
RegisterSingleInstance<IDlnaManager>(dlnaManager);
var collectionManager = new CollectionManager(LibraryManager, FileSystemManager, LibraryMonitor);