aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuke Pulverenti <luke.pulverenti@gmail.com>2016-05-21 00:49:17 -0400
committerLuke Pulverenti <luke.pulverenti@gmail.com>2016-05-21 00:49:17 -0400
commitb253d26abadc782c5bddc5ac5352ebe116154553 (patch)
treee2648ab8fc6106aa0a3218cd2ce49a93a9ecb1da
parenta49a905ca2e00753d3658b0a4244374dbcfbed48 (diff)
parent7596365af2fa819d440e1ae65befea88aec29bde (diff)
Merge branch 'beta'
-rw-r--r--MediaBrowser.Api/FilterService.cs3
-rw-r--r--MediaBrowser.Api/GamesService.cs5
-rw-r--r--MediaBrowser.Api/StartupWizardService.cs15
-rw-r--r--MediaBrowser.Api/TvShowsService.cs13
-rw-r--r--MediaBrowser.Api/UserLibrary/BaseItemsByNameService.cs9
-rw-r--r--MediaBrowser.Api/UserLibrary/ItemsService.cs12
-rw-r--r--MediaBrowser.Common.Implementations/MediaBrowser.Common.Implementations.csproj6
-rw-r--r--MediaBrowser.Common.Implementations/packages.config4
-rw-r--r--MediaBrowser.Controller/Entities/AggregateFolder.cs37
-rw-r--r--MediaBrowser.Controller/Entities/Audio/MusicArtist.cs37
-rw-r--r--MediaBrowser.Controller/Entities/CollectionFolder.cs60
-rw-r--r--MediaBrowser.Controller/Entities/Folder.cs93
-rw-r--r--MediaBrowser.Controller/Entities/IItemByName.cs6
-rw-r--r--MediaBrowser.Controller/Entities/InternalItemsQuery.cs3
-rw-r--r--MediaBrowser.Controller/Entities/TV/Season.cs34
-rw-r--r--MediaBrowser.Controller/Entities/TV/Series.cs27
-rw-r--r--MediaBrowser.Controller/Entities/User.cs9
-rw-r--r--MediaBrowser.Controller/Entities/UserRootFolder.cs9
-rw-r--r--MediaBrowser.Controller/Entities/UserView.cs11
-rw-r--r--MediaBrowser.Controller/Entities/UserViewBuilder.cs72
-rw-r--r--MediaBrowser.Controller/Playlists/Playlist.cs12
-rw-r--r--MediaBrowser.Dlna/ContentDirectory/ControlHandler.cs33
-rw-r--r--MediaBrowser.Model/Configuration/ServerConfiguration.cs3
-rw-r--r--MediaBrowser.Model/Entities/MediaStream.cs18
-rw-r--r--MediaBrowser.Model/Extensions/StringHelper.cs5
-rw-r--r--MediaBrowser.Model/LiveTv/LiveTvOptions.cs3
-rw-r--r--MediaBrowser.Model/MediaInfo/AudioCodec.cs17
-rw-r--r--MediaBrowser.Model/Querying/ItemQuery.cs4
-rw-r--r--MediaBrowser.Providers/Manager/MetadataService.cs23
-rw-r--r--MediaBrowser.Providers/TV/DummySeasonProvider.cs12
-rw-r--r--MediaBrowser.Providers/TV/MissingEpisodeProvider.cs2
-rw-r--r--MediaBrowser.Providers/TV/SeasonMetadataService.cs10
-rw-r--r--MediaBrowser.Server.Implementations/Library/LibraryManager.cs8
-rw-r--r--MediaBrowser.Server.Implementations/Library/MusicManager.cs20
-rw-r--r--MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs30
-rw-r--r--MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs28
-rw-r--r--MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj10
-rw-r--r--MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs153
-rw-r--r--MediaBrowser.Server.Implementations/packages.config4
-rw-r--r--MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj6
-rw-r--r--Nuget/MediaBrowser.Common.Internal.nuspec8
-rw-r--r--Nuget/MediaBrowser.Common.nuspec2
-rw-r--r--Nuget/MediaBrowser.Model.Signed.nuspec20
-rw-r--r--Nuget/MediaBrowser.Server.Core.nuspec4
44 files changed, 528 insertions, 372 deletions
diff --git a/MediaBrowser.Api/FilterService.cs b/MediaBrowser.Api/FilterService.cs
index 6d1c5d868d..c4419531c5 100644
--- a/MediaBrowser.Api/FilterService.cs
+++ b/MediaBrowser.Api/FilterService.cs
@@ -103,7 +103,8 @@ namespace MediaBrowser.Api
User = user,
MediaTypes = request.GetMediaTypes(),
IncludeItemTypes = request.GetIncludeItemTypes(),
- Recursive = true
+ Recursive = true,
+ EnableTotalRecordCount = false
};
return query;
diff --git a/MediaBrowser.Api/GamesService.cs b/MediaBrowser.Api/GamesService.cs
index 040872fcc8..387771b6d5 100644
--- a/MediaBrowser.Api/GamesService.cs
+++ b/MediaBrowser.Api/GamesService.cs
@@ -162,7 +162,10 @@ namespace MediaBrowser.Api
var items = user == null ?
system.GetRecursiveChildren(i => i is Game) :
- system.GetRecursiveChildren(user, i => i is Game);
+ system.GetRecursiveChildren(user, new InternalItemsQuery(user)
+ {
+ IncludeItemTypes = new[] { typeof(Game).Name }
+ });
var games = items.Cast<Game>().ToList();
diff --git a/MediaBrowser.Api/StartupWizardService.cs b/MediaBrowser.Api/StartupWizardService.cs
index 14bd6b61f6..28265c72f9 100644
--- a/MediaBrowser.Api/StartupWizardService.cs
+++ b/MediaBrowser.Api/StartupWizardService.cs
@@ -65,11 +65,7 @@ namespace MediaBrowser.Api
public void Post(ReportStartupWizardComplete request)
{
_config.Configuration.IsStartupWizardCompleted = true;
- _config.Configuration.EnableLocalizedGuids = true;
- _config.Configuration.EnableCustomPathSubFolders = true;
- _config.Configuration.EnableDateLastRefresh = true;
- _config.Configuration.EnableStandaloneMusicKeys = true;
- _config.Configuration.EnableCaseSensitiveItemIds = true;
+ SetWizardFinishValues(_config.Configuration);
_config.SaveConfiguration();
}
@@ -111,6 +107,15 @@ namespace MediaBrowser.Api
return result;
}
+ private void SetWizardFinishValues(ServerConfiguration config)
+ {
+ config.EnableLocalizedGuids = true;
+ config.EnableCustomPathSubFolders = true;
+ config.EnableDateLastRefresh = true;
+ config.EnableStandaloneMusicKeys = true;
+ config.EnableCaseSensitiveItemIds = true;
+ }
+
public void Post(UpdateStartupConfiguration request)
{
_config.Configuration.UICulture = request.UICulture;
diff --git a/MediaBrowser.Api/TvShowsService.cs b/MediaBrowser.Api/TvShowsService.cs
index e3dfb7f5a0..c4c603f917 100644
--- a/MediaBrowser.Api/TvShowsService.cs
+++ b/MediaBrowser.Api/TvShowsService.cs
@@ -415,21 +415,10 @@ namespace MediaBrowser.Api
private IEnumerable<Season> FilterVirtualSeasons(GetSeasons request, IEnumerable<Season> items)
{
- if (request.IsMissing.HasValue && request.IsVirtualUnaired.HasValue)
- {
- var isMissing = request.IsMissing.Value;
- var isVirtualUnaired = request.IsVirtualUnaired.Value;
-
- if (!isMissing && !isVirtualUnaired)
- {
- return items.Where(i => !i.IsMissingOrVirtualUnaired);
- }
- }
-
if (request.IsMissing.HasValue)
{
var val = request.IsMissing.Value;
- items = items.Where(i => (i.IsMissingSeason ?? false) == val);
+ items = items.Where(i => (i.IsMissingSeason) == val);
}
if (request.IsVirtualUnaired.HasValue)
diff --git a/MediaBrowser.Api/UserLibrary/BaseItemsByNameService.cs b/MediaBrowser.Api/UserLibrary/BaseItemsByNameService.cs
index b3164ce3f7..565bed0531 100644
--- a/MediaBrowser.Api/UserLibrary/BaseItemsByNameService.cs
+++ b/MediaBrowser.Api/UserLibrary/BaseItemsByNameService.cs
@@ -121,6 +121,13 @@ namespace MediaBrowser.Api.UserLibrary
var includeItemTypes = request.GetIncludeItemTypes();
var mediaTypes = request.GetMediaTypes();
+ var query = new InternalItemsQuery(user)
+ {
+ ExcludeItemTypes = excludeItemTypes,
+ IncludeItemTypes = includeItemTypes,
+ MediaTypes = mediaTypes
+ };
+
Func<BaseItem, bool> filter = i => FilterItem(request, i, excludeItemTypes, includeItemTypes, mediaTypes);
if (parentItem.IsFolder)
@@ -130,7 +137,7 @@ namespace MediaBrowser.Api.UserLibrary
if (!string.IsNullOrWhiteSpace(request.UserId))
{
items = request.Recursive ?
- folder.GetRecursiveChildren(user, filter) :
+ folder.GetRecursiveChildren(user, query) :
folder.GetChildren(user, true).Where(filter);
}
else
diff --git a/MediaBrowser.Api/UserLibrary/ItemsService.cs b/MediaBrowser.Api/UserLibrary/ItemsService.cs
index ff937078e6..dac1a6b1a8 100644
--- a/MediaBrowser.Api/UserLibrary/ItemsService.cs
+++ b/MediaBrowser.Api/UserLibrary/ItemsService.cs
@@ -138,25 +138,19 @@ namespace MediaBrowser.Api.UserLibrary
if (request.Recursive)
{
- var result = await ((Folder)item).GetItems(GetItemsQuery(request, user)).ConfigureAwait(false);
-
- return result;
+ return await ((Folder)item).GetItems(GetItemsQuery(request, user)).ConfigureAwait(false);
}
if (user == null)
{
- var result = await ((Folder)item).GetItems(GetItemsQuery(request, null)).ConfigureAwait(false);
-
- return result;
+ return await ((Folder)item).GetItems(GetItemsQuery(request, null)).ConfigureAwait(false);
}
var userRoot = item as UserRootFolder;
if (userRoot == null)
{
- var result = await ((Folder)item).GetItems(GetItemsQuery(request, user)).ConfigureAwait(false);
-
- return result;
+ return await ((Folder)item).GetItems(GetItemsQuery(request, user)).ConfigureAwait(false);
}
IEnumerable<BaseItem> items = ((Folder)item).GetChildren(user, true);
diff --git a/MediaBrowser.Common.Implementations/MediaBrowser.Common.Implementations.csproj b/MediaBrowser.Common.Implementations/MediaBrowser.Common.Implementations.csproj
index 8da1beb687..70489d7142 100644
--- a/MediaBrowser.Common.Implementations/MediaBrowser.Common.Implementations.csproj
+++ b/MediaBrowser.Common.Implementations/MediaBrowser.Common.Implementations.csproj
@@ -55,7 +55,7 @@
<HintPath>..\packages\morelinq.1.4.0\lib\net35\MoreLinq.dll</HintPath>
</Reference>
<Reference Include="NLog, Version=4.0.0.0, Culture=neutral, PublicKeyToken=5120e14c03d0593c, processorArchitecture=MSIL">
- <HintPath>..\packages\NLog.4.3.1\lib\net45\NLog.dll</HintPath>
+ <HintPath>..\packages\NLog.4.3.4\lib\net45\NLog.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Patterns.Logging">
@@ -65,8 +65,8 @@
<SpecificVersion>False</SpecificVersion>
<HintPath>..\ThirdParty\SharpCompress\SharpCompress.dll</HintPath>
</Reference>
- <Reference Include="SimpleInjector, Version=3.1.3.0, Culture=neutral, PublicKeyToken=984cb50dea722e99, processorArchitecture=MSIL">
- <HintPath>..\packages\SimpleInjector.3.1.3\lib\net45\SimpleInjector.dll</HintPath>
+ <Reference Include="SimpleInjector, Version=3.1.4.0, Culture=neutral, PublicKeyToken=984cb50dea722e99, processorArchitecture=MSIL">
+ <HintPath>..\packages\SimpleInjector.3.1.4\lib\net45\SimpleInjector.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System" />
diff --git a/MediaBrowser.Common.Implementations/packages.config b/MediaBrowser.Common.Implementations/packages.config
index 6d7d861823..d1d135b20c 100644
--- a/MediaBrowser.Common.Implementations/packages.config
+++ b/MediaBrowser.Common.Implementations/packages.config
@@ -2,7 +2,7 @@
<packages>
<package id="CommonIO" version="1.0.0.9" targetFramework="net45" />
<package id="morelinq" version="1.4.0" targetFramework="net45" />
- <package id="NLog" version="4.3.1" targetFramework="net45" />
+ <package id="NLog" version="4.3.4" targetFramework="net45" />
<package id="Patterns.Logging" version="1.0.0.2" targetFramework="net45" />
- <package id="SimpleInjector" version="3.1.3" targetFramework="net45" />
+ <package id="SimpleInjector" version="3.1.4" targetFramework="net45" />
</packages> \ No newline at end of file
diff --git a/MediaBrowser.Controller/Entities/AggregateFolder.cs b/MediaBrowser.Controller/Entities/AggregateFolder.cs
index 018ff6da07..588a65e98d 100644
--- a/MediaBrowser.Controller/Entities/AggregateFolder.cs
+++ b/MediaBrowser.Controller/Entities/AggregateFolder.cs
@@ -64,10 +64,37 @@ namespace MediaBrowser.Controller.Entities
protected override IEnumerable<FileSystemMetadata> GetFileSystemChildren(IDirectoryService directoryService)
{
- return CreateResolveArgs(directoryService).FileSystemChildren;
+ return CreateResolveArgs(directoryService, true).FileSystemChildren;
}
- private ItemResolveArgs CreateResolveArgs(IDirectoryService directoryService)
+ private bool _requiresRefresh;
+ public override bool RequiresRefresh()
+ {
+ var changed = base.RequiresRefresh() || _requiresRefresh;
+
+ if (!changed)
+ {
+ var locations = PhysicalLocations.ToList();
+
+ var newLocations = CreateResolveArgs(new DirectoryService(BaseItem.FileSystem), false).PhysicalLocations.ToList();
+
+ if (!locations.SequenceEqual(newLocations))
+ {
+ changed = true;
+ }
+ }
+
+ return changed;
+ }
+
+ public override bool BeforeMetadataRefresh()
+ {
+ var changed = base.BeforeMetadataRefresh() || _requiresRefresh;
+ _requiresRefresh = false;
+ return changed;
+ }
+
+ private ItemResolveArgs CreateResolveArgs(IDirectoryService directoryService, bool setPhysicalLocations)
{
var path = ContainingFolderPath;
@@ -100,7 +127,11 @@ namespace MediaBrowser.Controller.Entities
args.FileSystemDictionary = fileSystemDictionary;
}
- PhysicalLocationsList = args.PhysicalLocations.ToList();
+ _requiresRefresh = _requiresRefresh || !args.PhysicalLocations.SequenceEqual(PhysicalLocations);
+ if (setPhysicalLocations)
+ {
+ PhysicalLocationsList = args.PhysicalLocations.ToList();
+ }
return args;
}
diff --git a/MediaBrowser.Controller/Entities/Audio/MusicArtist.cs b/MediaBrowser.Controller/Entities/Audio/MusicArtist.cs
index fb8a24061a..02dad93cbe 100644
--- a/MediaBrowser.Controller/Entities/Audio/MusicArtist.cs
+++ b/MediaBrowser.Controller/Entities/Audio/MusicArtist.cs
@@ -56,38 +56,23 @@ namespace MediaBrowser.Controller.Entities.Audio
public IEnumerable<BaseItem> GetTaggedItems(InternalItemsQuery query)
{
- var itemByNameFilter = GetItemFilter();
+ if (query.IncludeItemTypes.Length == 0)
+ {
+ query.IncludeItemTypes = new[] { typeof(Audio).Name, typeof(MusicVideo).Name, typeof(MusicAlbum).Name };
+ query.ArtistNames = new[] { Name };
+ }
- if (query.User != null)
+ // Need this for now since the artist filter isn't yet supported by the db
+ if (ConfigurationManager.Configuration.SchemaVersion < 79)
{
- return query.User.RootFolder
- .GetRecursiveChildren(query.User, i =>
- {
- if (query.IsFolder.HasValue)
- {
- if (query.IsFolder.Value != i.IsFolder)
- {
- return false;
- }
- }
- return itemByNameFilter(i);
- });
+ var filter = GetItemFilter();
+ return LibraryManager.GetItemList(query).Where(filter);
}
- return LibraryManager.RootFolder
- .GetRecursiveChildren(i =>
- {
- if (query.IsFolder.HasValue)
- {
- if (query.IsFolder.Value != i.IsFolder)
- {
- return false;
- }
- }
- return itemByNameFilter(i);
- });
+ return LibraryManager.GetItemList(query);
}
+ [IgnoreDataMember]
protected override IEnumerable<BaseItem> ActualChildren
{
get
diff --git a/MediaBrowser.Controller/Entities/CollectionFolder.cs b/MediaBrowser.Controller/Entities/CollectionFolder.cs
index 5e0cf6e88b..35dfd52e9d 100644
--- a/MediaBrowser.Controller/Entities/CollectionFolder.cs
+++ b/MediaBrowser.Controller/Entities/CollectionFolder.cs
@@ -23,19 +23,6 @@ namespace MediaBrowser.Controller.Entities
PhysicalLocationsList = new List<string>();
}
- /// <summary>
- /// Gets a value indicating whether this instance is virtual folder.
- /// </summary>
- /// <value><c>true</c> if this instance is virtual folder; otherwise, <c>false</c>.</value>
- [IgnoreDataMember]
- public override bool IsVirtualFolder
- {
- get
- {
- return true;
- }
- }
-
[IgnoreDataMember]
protected override bool SupportsShortcutChildren
{
@@ -83,7 +70,34 @@ namespace MediaBrowser.Controller.Entities
protected override IEnumerable<FileSystemMetadata> GetFileSystemChildren(IDirectoryService directoryService)
{
- return CreateResolveArgs(directoryService).FileSystemChildren;
+ return CreateResolveArgs(directoryService, true).FileSystemChildren;
+ }
+
+ private bool _requiresRefresh;
+ public override bool RequiresRefresh()
+ {
+ var changed = base.RequiresRefresh() || _requiresRefresh;
+
+ if (!changed)
+ {
+ var locations = PhysicalLocations.ToList();
+
+ var newLocations = CreateResolveArgs(new DirectoryService(BaseItem.FileSystem), false).PhysicalLocations.ToList();
+
+ if (!locations.SequenceEqual(newLocations))
+ {
+ changed = true;
+ }
+ }
+
+ return changed;
+ }
+
+ public override bool BeforeMetadataRefresh()
+ {
+ var changed = base.BeforeMetadataRefresh() || _requiresRefresh;
+ _requiresRefresh = false;
+ return changed;
}
internal override bool IsValidFromResolver(BaseItem newItem)
@@ -101,7 +115,7 @@ namespace MediaBrowser.Controller.Entities
return base.IsValidFromResolver(newItem);
}
- private ItemResolveArgs CreateResolveArgs(IDirectoryService directoryService)
+ private ItemResolveArgs CreateResolveArgs(IDirectoryService directoryService, bool setPhysicalLocations)
{
var path = ContainingFolderPath;
@@ -135,7 +149,11 @@ namespace MediaBrowser.Controller.Entities
args.FileSystemDictionary = fileSystemDictionary;
}
- PhysicalLocationsList = args.PhysicalLocations.ToList();
+ _requiresRefresh = _requiresRefresh || !args.PhysicalLocations.SequenceEqual(PhysicalLocations);
+ if (setPhysicalLocations)
+ {
+ PhysicalLocationsList = args.PhysicalLocations.ToList();
+ }
return args;
}
@@ -153,15 +171,6 @@ namespace MediaBrowser.Controller.Entities
/// <returns>Task.</returns>
protected override Task ValidateChildrenInternal(IProgress<double> progress, CancellationToken cancellationToken, bool recursive, bool refreshChildMetadata, MetadataRefreshOptions refreshOptions, IDirectoryService directoryService)
{
- var list = PhysicalLocationsList.ToList();
-
- CreateResolveArgs(directoryService);
-
- if (!list.SequenceEqual(PhysicalLocationsList))
- {
- return UpdateToRepository(ItemUpdateType.MetadataImport, cancellationToken);
- }
-
return Task.FromResult(true);
}
@@ -188,6 +197,7 @@ namespace MediaBrowser.Controller.Entities
/// Our children are actually just references to the ones in the physical root...
/// </summary>
/// <value>The actual children.</value>
+ [IgnoreDataMember]
protected override IEnumerable<BaseItem> ActualChildren
{
get { return GetActualChildren(); }
diff --git a/MediaBrowser.Controller/Entities/Folder.cs b/MediaBrowser.Controller/Entities/Folder.cs
index 77e3624191..e7b1df55ad 100644
--- a/MediaBrowser.Controller/Entities/Folder.cs
+++ b/MediaBrowser.Controller/Entities/Folder.cs
@@ -126,19 +126,6 @@ namespace MediaBrowser.Controller.Entities
/// <value><c>true</c> if this instance is root; otherwise, <c>false</c>.</value>
public bool IsRoot { get; set; }
- /// <summary>
- /// Gets a value indicating whether this instance is virtual folder.
- /// </summary>
- /// <value><c>true</c> if this instance is virtual folder; otherwise, <c>false</c>.</value>
- [IgnoreDataMember]
- public virtual bool IsVirtualFolder
- {
- get
- {
- return false;
- }
- }
-
public virtual List<LinkedChild> LinkedChildren { get; set; }
[IgnoreDataMember]
@@ -285,6 +272,7 @@ namespace MediaBrowser.Controller.Entities
/// Gets the actual children.
/// </summary>
/// <value>The actual children.</value>
+ [IgnoreDataMember]
protected virtual IEnumerable<BaseItem> ActualChildren
{
get
@@ -749,7 +737,7 @@ namespace MediaBrowser.Controller.Entities
{
var user = query.User;
- if (RequiresPostFiltering(query))
+ if (!query.ForceDirect && RequiresPostFiltering(query))
{
IEnumerable<BaseItem> items;
Func<BaseItem, bool> filter = i => UserViewBuilder.Filter(i, user, query, UserDataManager, LibraryManager);
@@ -760,7 +748,7 @@ namespace MediaBrowser.Controller.Entities
}
else
{
- items = GetRecursiveChildren(user, filter);
+ items = GetRecursiveChildren(user, query);
}
return PostFilterAndSort(items, query);
@@ -784,7 +772,7 @@ namespace MediaBrowser.Controller.Entities
return true;
}
}
-
+
var supportsUserDataQueries = ConfigurationManager.Configuration.SchemaVersion >= 76;
if (query.SortBy != null && query.SortBy.Length > 0)
@@ -817,19 +805,24 @@ namespace MediaBrowser.Controller.Entities
return true;
}
}
- if (query.SortBy.Contains(ItemSortBy.AiredEpisodeOrder, StringComparer.OrdinalIgnoreCase))
- {
- Logger.Debug("Query requires post-filtering due to ItemSortBy.AiredEpisodeOrder");
- return true;
- }
- if (query.SortBy.Contains(ItemSortBy.AlbumArtist, StringComparer.OrdinalIgnoreCase))
+
+ if (ConfigurationManager.Configuration.SchemaVersion < 79)
{
- Logger.Debug("Query requires post-filtering due to ItemSortBy.AlbumArtist");
- return true;
+ if (query.SortBy.Contains(ItemSortBy.AlbumArtist, StringComparer.OrdinalIgnoreCase))
+ {
+ Logger.Debug("Query requires post-filtering due to ItemSortBy.AlbumArtist");
+ return true;
+ }
+ if (query.SortBy.Contains(ItemSortBy.Artist, StringComparer.OrdinalIgnoreCase))
+ {
+ Logger.Debug("Query requires post-filtering due to ItemSortBy.Artist");
+ return true;
+ }
}
- if (query.SortBy.Contains(ItemSortBy.Artist, StringComparer.OrdinalIgnoreCase))
+
+ if (query.SortBy.Contains(ItemSortBy.AiredEpisodeOrder, StringComparer.OrdinalIgnoreCase))
{
- Logger.Debug("Query requires post-filtering due to ItemSortBy.Artist");
+ Logger.Debug("Query requires post-filtering due to ItemSortBy.AiredEpisodeOrder");
return true;
}
if (query.SortBy.Contains(ItemSortBy.Budget, StringComparer.OrdinalIgnoreCase))
@@ -1109,10 +1102,13 @@ namespace MediaBrowser.Controller.Entities
return true;
}
- if (query.ArtistNames.Length > 0)
+ if (ConfigurationManager.Configuration.SchemaVersion < 79)
{
- Logger.Debug("Query requires post-filtering due to ArtistNames");
- return true;
+ if (query.ArtistNames.Length > 0)
+ {
+ Logger.Debug("Query requires post-filtering due to ArtistNames");
+ return true;
+ }
}
return false;
@@ -1178,7 +1174,7 @@ namespace MediaBrowser.Controller.Entities
else
{
items = query.Recursive
- ? GetRecursiveChildren(user, filter)
+ ? GetRecursiveChildren(user, query)
: GetChildren(user, true).Where(filter);
}
@@ -1215,19 +1211,14 @@ namespace MediaBrowser.Controller.Entities
/// <summary>
/// Adds the children to list.
/// </summary>
- /// <param name="user">The user.</param>
- /// <param name="includeLinkedChildren">if set to <c>true</c> [include linked children].</param>
- /// <param name="result">The result.</param>
- /// <param name="recursive">if set to <c>true</c> [recursive].</param>
- /// <param name="filter">The filter.</param>
/// <returns><c>true</c> if XXXX, <c>false</c> otherwise</returns>
- private void AddChildren(User user, bool includeLinkedChildren, Dictionary<Guid, BaseItem> result, bool recursive, Func<BaseItem, bool> filter)
+ private void AddChildren(User user, bool includeLinkedChildren, Dictionary<Guid, BaseItem> result, bool recursive, InternalItemsQuery query)
{
foreach (var child in GetEligibleChildrenForRecursiveChildren(user))
{
if (child.IsVisible(user))
{
- if (filter == null || filter(child))
+ if (query == null || UserViewBuilder.FilterItem(child, query))
{
result[child.Id] = child;
}
@@ -1236,7 +1227,7 @@ namespace MediaBrowser.Controller.Entities
{
var folder = (Folder)child;
- folder.AddChildren(user, includeLinkedChildren, result, true, filter);
+ folder.AddChildren(user, includeLinkedChildren, result, true, query);
}
}
}
@@ -1247,7 +1238,7 @@ namespace MediaBrowser.Controller.Entities
{
if (child.IsVisible(user))
{
- if (filter == null || filter(child))
+ if (query == null || UserViewBuilder.FilterItem(child, query))
{
result[child.Id] = child;
}
@@ -1265,10 +1256,10 @@ namespace MediaBrowser.Controller.Entities
/// <exception cref="System.ArgumentNullException"></exception>
public IEnumerable<BaseItem> GetRecursiveChildren(User user, bool includeLinkedChildren = true)
{
- return GetRecursiveChildren(user, i => true);
+ return GetRecursiveChildren(user, null);
}
- public virtual IEnumerable<BaseItem> GetRecursiveChildren(User user, Func<BaseItem, bool> filter)
+ public virtual IEnumerable<BaseItem> GetRecursiveChildren(User user, InternalItemsQuery query)
{
if (user == null)
{
@@ -1277,7 +1268,7 @@ namespace MediaBrowser.Controller.Entities
var result = new Dictionary<Guid, BaseItem>();
- AddChildren(user, true, result, true, filter);
+ AddChildren(user, true, result, true, query);
return result.Values;
}
@@ -1303,7 +1294,7 @@ namespace MediaBrowser.Controller.Entities
/// <summary>
/// Adds the children to list.
/// </summary>
- private void AddChildrenToList(Dictionary<Guid,BaseItem> result, bool includeLinkedChildren, bool recursive, Func<BaseItem, bool> filter)
+ private void AddChildrenToList(Dictionary<Guid, BaseItem> result, bool includeLinkedChildren, bool recursive, Func<BaseItem, bool> filter)
{
foreach (var child in Children)
{
@@ -1534,13 +1525,12 @@ namespace MediaBrowser.Controller.Entities
User = user,
Recursive = true,
IsFolder = false,
- IsUnaired = false
-
+ EnableTotalRecordCount = false
};
- if (!user.Configuration.DisplayMissingEpisodes)
+ if (!user.Configuration.DisplayMissingEpisodes || !user.Configuration.DisplayUnairedEpisodes)
{
- query.IsMissing = false;
+ query.ExcludeLocationTypes = new[] { LocationType.Virtual };
}
var itemsResult = await GetItems(query).ConfigureAwait(false);
@@ -1562,7 +1552,8 @@ namespace MediaBrowser.Controller.Entities
{
User = user,
Recursive = true,
- IsFolder = false
+ IsFolder = false,
+ EnableTotalRecordCount = false
}).ConfigureAwait(false);
@@ -1578,7 +1569,8 @@ namespace MediaBrowser.Controller.Entities
{
Recursive = true,
IsFolder = false,
- ExcludeLocationTypes = new[] { LocationType.Virtual }
+ ExcludeLocationTypes = new[] { LocationType.Virtual },
+ EnableTotalRecordCount = false
}).Result;
@@ -1630,7 +1622,8 @@ namespace MediaBrowser.Controller.Entities
{
Recursive = true,
IsFolder = false,
- ExcludeLocationTypes = new[] { LocationType.Virtual }
+ ExcludeLocationTypes = new[] { LocationType.Virtual },
+ EnableTotalRecordCount = false
}).Result;
diff --git a/MediaBrowser.Controller/Entities/IItemByName.cs b/MediaBrowser.Controller/Entities/IItemByName.cs
index 7747e738cb..2ac4af1af7 100644
--- a/MediaBrowser.Controller/Entities/IItemByName.cs
+++ b/MediaBrowser.Controller/Entities/IItemByName.cs
@@ -15,12 +15,6 @@ namespace MediaBrowser.Controller.Entities
/// <returns>IEnumerable{BaseItem}.</returns>
IEnumerable<BaseItem> GetTaggedItems(IEnumerable<BaseItem> inputItems);
- /// <summary>
- /// Gets the item filter.
- /// </summary>
- /// <returns>Func&lt;BaseItem, System.Boolean&gt;.</returns>
- Func<BaseItem, bool> GetItemFilter();
-
IEnumerable<BaseItem> GetTaggedItems(InternalItemsQuery query);
}
diff --git a/MediaBrowser.Controller/Entities/InternalItemsQuery.cs b/MediaBrowser.Controller/Entities/InternalItemsQuery.cs
index ae38f6143d..823f4066c4 100644
--- a/MediaBrowser.Controller/Entities/InternalItemsQuery.cs
+++ b/MediaBrowser.Controller/Entities/InternalItemsQuery.cs
@@ -19,8 +19,6 @@ namespace MediaBrowser.Controller.Entities
public User User { get; set; }
- public Func<BaseItem, bool> Filter { get; set; }
-
public bool? IsFolder { get; set; }
public bool? IsFavorite { get; set; }
public bool? IsFavoriteOrLiked { get; set; }
@@ -138,6 +136,7 @@ namespace MediaBrowser.Controller.Entities
public bool GroupByPresentationUniqueKey { get; set; }
public bool EnableTotalRecordCount { get; set; }
+ public bool ForceDirect { get; set; }
public InternalItemsQuery()
{
diff --git a/MediaBrowser.Controller/Entities/TV/Season.cs b/MediaBrowser.Controller/Entities/TV/Season.cs
index ab125eecb6..68170884c5 100644
--- a/MediaBrowser.Controller/Entities/TV/Season.cs
+++ b/MediaBrowser.Controller/Entities/TV/Season.cs
@@ -134,7 +134,7 @@ namespace MediaBrowser.Controller.Entities.TV
if (!result)
{
- if (!IsMissingSeason.HasValue)
+ if (!IsVirtualItem.HasValue)
{
return true;
}
@@ -144,18 +144,23 @@ namespace MediaBrowser.Controller.Entities.TV
}
[IgnoreDataMember]
- public bool? IsMissingSeason { get; set; }
+ public bool? IsVirtualItem { get; set; }
[IgnoreDataMember]
- public bool IsVirtualUnaired
+ public bool IsMissingSeason
{
- get { return LocationType == LocationType.Virtual && IsUnaired; }
+ get { return (IsVirtualItem ?? DetectIsVirtualItem()) && !IsUnaired; }
}
[IgnoreDataMember]
- public bool IsMissingOrVirtualUnaired
+ public bool IsVirtualUnaired
+ {
+ get { return (IsVirtualItem ?? DetectIsVirtualItem()) && IsUnaired; }
+ }
+
+ private bool DetectIsVirtualItem()
{
- get { return (IsMissingSeason ?? false) || (LocationType == LocationType.Virtual && IsUnaired); }
+ return LocationType == LocationType.Virtual && GetEpisodes().All(i => i.LocationType == LocationType.Virtual);
}
[IgnoreDataMember]
@@ -319,19 +324,14 @@ namespace MediaBrowser.Controller.Entities.TV
{
var hasChanges = base.BeforeMetadataRefresh();
- var locationType = LocationType;
-
- if (locationType == LocationType.FileSystem || locationType == LocationType.Offline)
+ if (!IndexNumber.HasValue && !string.IsNullOrEmpty(Path))
{
- if (!IndexNumber.HasValue && !string.IsNullOrEmpty(Path))
- {
- IndexNumber = IndexNumber ?? LibraryManager.GetSeasonNumberFromPath(Path);
+ IndexNumber = IndexNumber ?? LibraryManager.GetSeasonNumberFromPath(Path);
- // If a change was made record it
- if (IndexNumber.HasValue)
- {
- hasChanges = true;
- }
+ // If a change was made record it
+ if (IndexNumber.HasValue)
+ {
+ hasChanges = true;
}
}
diff --git a/MediaBrowser.Controller/Entities/TV/Series.cs b/MediaBrowser.Controller/Entities/TV/Series.cs
index 82ab99980d..17fc0c0d29 100644
--- a/MediaBrowser.Controller/Entities/TV/Series.cs
+++ b/MediaBrowser.Controller/Entities/TV/Series.cs
@@ -238,20 +238,13 @@ namespace MediaBrowser.Controller.Entities.TV
seasons = LibraryManager.Sort(base.GetChildren(user, true), user, new[] { ItemSortBy.SortName }, SortOrder.Ascending).OfType<Season>();
}
- if (!includeMissingSeasons && !includeVirtualUnaired)
+ if (!includeMissingSeasons)
{
- seasons = seasons.Where(i => !i.IsMissingOrVirtualUnaired);
+ seasons = seasons.Where(i => !(i.IsMissingSeason));
}
- else
+ if (!includeVirtualUnaired)
{
- if (!includeMissingSeasons)
- {
- seasons = seasons.Where(i => !(i.IsMissingSeason ?? false));
- }
- if (!includeVirtualUnaired)
- {
- seasons = seasons.Where(i => !i.IsVirtualUnaired);
- }
+ seasons = seasons.Where(i => !i.IsVirtualUnaired);
}
return seasons;
@@ -381,14 +374,18 @@ namespace MediaBrowser.Controller.Entities.TV
}
else
{
- episodes = GetRecursiveChildren(user, i => i is Episode)
- .Cast<Episode>();
+ episodes = GetRecursiveChildren(user, new InternalItemsQuery(user)
+ {
+ IncludeItemTypes = new[] { typeof(Episode).Name }
+ }).Cast<Episode>();
}
}
else
{
- episodes = GetRecursiveChildren(user, i => i is Episode)
- .Cast<Episode>();
+ episodes = GetRecursiveChildren(user, new InternalItemsQuery(user)
+ {
+ IncludeItemTypes = new[] { typeof(Episode).Name }
+ }).Cast<Episode>();
}
episodes = FilterEpisodesBySeason(episodes, seasonNumber, DisplaySpecialsWithSeasons);
diff --git a/MediaBrowser.Controller/Entities/User.cs b/MediaBrowser.Controller/Entities/User.cs
index e5b39003d0..5c68308f5c 100644
--- a/MediaBrowser.Controller/Entities/User.cs
+++ b/MediaBrowser.Controller/Entities/User.cs
@@ -305,14 +305,7 @@ namespace MediaBrowser.Controller.Entities
public bool IsFolderGrouped(Guid id)
{
- var config = Configuration;
-
- if (config.ExcludeFoldersFromGrouping != null)
- {
- return !config.ExcludeFoldersFromGrouping.Select(i => new Guid(i)).Contains(id);
- }
-
- return config.GroupedFolders.Select(i => new Guid(i)).Contains(id);
+ return Configuration.GroupedFolders.Select(i => new Guid(i)).Contains(id);
}
[IgnoreDataMember]
diff --git a/MediaBrowser.Controller/Entities/UserRootFolder.cs b/MediaBrowser.Controller/Entities/UserRootFolder.cs
index b9e997d175..37c4c91b17 100644
--- a/MediaBrowser.Controller/Entities/UserRootFolder.cs
+++ b/MediaBrowser.Controller/Entities/UserRootFolder.cs
@@ -64,15 +64,6 @@ namespace MediaBrowser.Controller.Entities
return list;
}
- /// <summary>
- /// Get the children of this folder from the actual file system
- /// </summary>
- /// <returns>IEnumerable{BaseItem}.</returns>
- protected override IEnumerable<BaseItem> GetNonCachedChildren(IDirectoryService directoryService)
- {
- return base.GetNonCachedChildren(directoryService);
- }
-
public override bool BeforeMetadataRefresh()
{
var hasChanges = base.BeforeMetadataRefresh();
diff --git a/MediaBrowser.Controller/Entities/UserView.cs b/MediaBrowser.Controller/Entities/UserView.cs
index 40fec3e288..e40d9ca381 100644
--- a/MediaBrowser.Controller/Entities/UserView.cs
+++ b/MediaBrowser.Controller/Entities/UserView.cs
@@ -66,7 +66,8 @@ namespace MediaBrowser.Controller.Entities
{
var result = GetItems(new InternalItemsQuery
{
- User = user
+ User = user,
+ EnableTotalRecordCount = false
}).Result;
@@ -83,17 +84,19 @@ namespace MediaBrowser.Controller.Entities
return true;
}
- public override IEnumerable<BaseItem> GetRecursiveChildren(User user, Func<BaseItem, bool> filter)
+ public override IEnumerable<BaseItem> GetRecursiveChildren(User user, InternalItemsQuery query)
{
var result = GetItems(new InternalItemsQuery
{
User = user,
Recursive = true,
- Filter = filter
+ EnableTotalRecordCount = false,
+
+ ForceDirect = true
}).Result;
- return result.Items;
+ return result.Items.Where(i => UserViewBuilder.FilterItem(i, query));
}
protected override IEnumerable<BaseItem> GetEligibleChildrenForRecursiveChildren(User user)
diff --git a/MediaBrowser.Controller/Entities/UserViewBuilder.cs b/MediaBrowser.Controller/Entities/UserViewBuilder.cs
index b88e8493d2..d4a8b07305 100644
--- a/MediaBrowser.Controller/Entities/UserViewBuilder.cs
+++ b/MediaBrowser.Controller/Entities/UserViewBuilder.cs
@@ -128,7 +128,11 @@ namespace MediaBrowser.Controller.Entities
{
if (query.Recursive)
{
- return GetResult(queryParent.GetRecursiveChildren(user, true), queryParent, query);
+ query.Recursive = true;
+ query.ParentId = queryParent.Id;
+ query.SetUser(user);
+
+ return _libraryManager.GetItemsResult(query);
}
return GetResult(queryParent.GetChildren(user, true), queryParent, query);
}
@@ -251,7 +255,6 @@ namespace MediaBrowser.Controller.Entities
if (query.Recursive)
{
query.Recursive = true;
- query.ParentId = parent.Id;
query.SetUser(user);
if (query.IncludeItemTypes.Length == 0)
@@ -259,7 +262,7 @@ namespace MediaBrowser.Controller.Entities
query.IncludeItemTypes = new[] { typeof(MusicArtist).Name, typeof(MusicAlbum).Name, typeof(Audio.Audio).Name, typeof(MusicVideo).Name };
}
- return _libraryManager.GetItemsResult(query);
+ return parent.QueryRecursive(query);
}
var list = new List<BaseItem>();
@@ -329,9 +332,13 @@ namespace MediaBrowser.Controller.Entities
private QueryResult<BaseItem> GetMusicAlbumArtists(Folder parent, User user, InternalItemsQuery query)
{
- var items = GetRecursiveChildren(parent, user, new[] { CollectionType.Music, CollectionType.MusicVideos })
- .Where(i => !i.IsFolder)
- .OfType<IHasAlbumArtist>();
+ var items = _libraryManager.GetItemList(new InternalItemsQuery(user)
+ {
+ Recursive = true,
+ ParentId = parent.Id,
+ IncludeItemTypes = new[] { typeof(Audio.Audio).Name }
+
+ }).Cast<IHasAlbumArtist>();
var artists = _libraryManager.GetAlbumArtists(items);
@@ -340,9 +347,13 @@ namespace MediaBrowser.Controller.Entities
private QueryResult<BaseItem> GetMusicArtists(Folder parent, User user, InternalItemsQuery query)
{
- var items = GetRecursiveChildren(parent, user, new[] { CollectionType.Music, CollectionType.MusicVideos })
- .Where(i => !i.IsFolder)
- .OfType<IHasArtist>();
+ var items = _libraryManager.GetItemList(new InternalItemsQuery(user)
+ {
+ Recursive = true,
+ ParentId = parent.Id,
+ IncludeItemTypes = new[] { typeof(Audio.Audio).Name, typeof(MusicVideo).Name }
+
+ }).Cast<IHasArtist>();
var artists = _libraryManager.GetArtists(items);
@@ -351,9 +362,13 @@ namespace MediaBrowser.Controller.Entities
private QueryResult<BaseItem> GetFavoriteArtists(Folder parent, User user, InternalItemsQuery query)
{
- var items = GetRecursiveChildren(parent, user, new[] { CollectionType.Music, CollectionType.MusicVideos })
- .Where(i => !i.IsFolder)
- .OfType<IHasAlbumArtist>();
+ var items = _libraryManager.GetItemList(new InternalItemsQuery(user)
+ {
+ Recursive = true,
+ ParentId = parent.Id,
+ IncludeItemTypes = new[] { typeof(Audio.Audio).Name }
+
+ }).Cast<IHasAlbumArtist>();
var artists = _libraryManager.GetAlbumArtists(items).Where(i => _userDataManager.GetUserData(user, i).IsFavorite);
@@ -448,7 +463,6 @@ namespace MediaBrowser.Controller.Entities
if (query.Recursive)
{
query.Recursive = true;
- query.ParentId = parent.Id;
query.SetUser(user);
if (query.IncludeItemTypes.Length == 0)
@@ -456,7 +470,7 @@ namespace MediaBrowser.Controller.Entities
query.IncludeItemTypes = new[] { typeof(Movie).Name, typeof(BoxSet).Name };
}
- return _libraryManager.GetItemsResult(query);
+ return parent.QueryRecursive(query);
}
var list = new List<BaseItem>();
@@ -613,7 +627,6 @@ namespace MediaBrowser.Controller.Entities
if (query.Recursive)
{
query.Recursive = true;
- query.ParentId = parent.Id;
query.SetUser(user);
if (query.IncludeItemTypes.Length == 0)
@@ -621,7 +634,7 @@ namespace MediaBrowser.Controller.Entities
query.IncludeItemTypes = new[] { typeof(Series).Name, typeof(Season).Name, typeof(Episode).Name };
}
- return _libraryManager.GetItemsResult(query);
+ return parent.QueryRecursive(query);
}
var list = new List<BaseItem>();
@@ -756,9 +769,9 @@ namespace MediaBrowser.Controller.Entities
return PostFilterAndSort(items, queryParent, null, query, _libraryManager);
}
- public bool FilterItem(BaseItem item, InternalItemsQuery query)
+ public static bool FilterItem(BaseItem item, InternalItemsQuery query)
{
- return Filter(item, query.User, query, _userDataManager, _libraryManager);
+ return Filter(item, query.User, query, BaseItem.UserDataManager, BaseItem.LibraryManager);
}
private QueryResult<BaseItem> PostFilterAndSort(IEnumerable<BaseItem> items,
@@ -1121,22 +1134,6 @@ namespace MediaBrowser.Controller.Entities
bool? isVirtualUnaired,
bool? isUnaired)
{
- if (isMissing.HasValue && isVirtualUnaired.HasValue)
- {
- if (!isMissing.Value && !isVirtualUnaired.Value)
- {
- return items.Where(i =>
- {
- var e = i as Season;
- if (e != null)
- {
- return !e.IsMissingOrVirtualUnaired;
- }
- return true;
- });
- }
- }
-
if (isMissing.HasValue)
{
var val = isMissing.Value;
@@ -1145,7 +1142,7 @@ namespace MediaBrowser.Controller.Entities
var e = i as Season;
if (e != null)
{
- return (e.IsMissingSeason ?? false) == val;
+ return (e.IsMissingSeason) == val;
}
return true;
});
@@ -1277,11 +1274,6 @@ namespace MediaBrowser.Controller.Entities
return false;
}
- if (query.Filter != null && !query.Filter(item))
- {
- return false;
- }
-
UserItemData userData = null;
if (query.IsLiked.HasValue)
diff --git a/MediaBrowser.Controller/Playlists/Playlist.cs b/MediaBrowser.Controller/Playlists/Playlist.cs
index 67b1d479b9..5ffe3d5daf 100644
--- a/MediaBrowser.Controller/Playlists/Playlist.cs
+++ b/MediaBrowser.Controller/Playlists/Playlist.cs
@@ -63,13 +63,13 @@ namespace MediaBrowser.Controller.Playlists
return GetPlayableItems(user).Result;
}
- public override IEnumerable<BaseItem> GetRecursiveChildren(User user, Func<BaseItem, bool> filter)
+ public override IEnumerable<BaseItem> GetRecursiveChildren(User user, InternalItemsQuery query)
{
var items = GetPlayableItems(user).Result;
- if (filter != null)
+ if (query != null)
{
- items = items.Where(filter);
+ items = items.Where(i => UserViewBuilder.FilterItem(i, query));
}
return items;
@@ -129,7 +129,11 @@ namespace MediaBrowser.Controller.Playlists
var items = user == null
? LibraryManager.RootFolder.GetRecursiveChildren(filter)
- : user.RootFolder.GetRecursiveChildren(user, filter);
+ : user.RootFolder.GetRecursiveChildren(user, new InternalItemsQuery(user)
+ {
+ IncludeItemTypes = new[] { typeof(Audio).Name },
+ ArtistNames = new[] { musicArtist.Name }
+ });
return LibraryManager.Sort(items, user, new[] { ItemSortBy.AlbumArtist, ItemSortBy.Album, ItemSortBy.SortName }, SortOrder.Ascending);
}
diff --git a/MediaBrowser.Dlna/ContentDirectory/ControlHandler.cs b/MediaBrowser.Dlna/ContentDirectory/ControlHandler.cs
index bc9fa1d7e7..233ec9546f 100644
--- a/MediaBrowser.Dlna/ContentDirectory/ControlHandler.cs
+++ b/MediaBrowser.Dlna/ContentDirectory/ControlHandler.cs
@@ -401,10 +401,10 @@ namespace MediaBrowser.Dlna.ContentDirectory
SortOrder = sort.SortOrder,
User = user,
Recursive = true,
- Filter = FilterUnsupportedContent,
+ IsMissing = false,
+ ExcludeItemTypes = new[] { typeof(Game).Name, typeof(Book).Name },
IsFolder = isFolder,
MediaTypes = mediaTypes.ToArray()
-
});
}
@@ -461,8 +461,10 @@ namespace MediaBrowser.Dlna.ContentDirectory
SortBy = sortOrders.ToArray(),
SortOrder = sort.SortOrder,
User = user,
- Filter = FilterUnsupportedContent,
- PresetViews = new[] { CollectionType.Movies, CollectionType.TvShows, CollectionType.Music }
+ IsMissing = false,
+ PresetViews = new[] { CollectionType.Movies, CollectionType.TvShows, CollectionType.Music },
+ ExcludeItemTypes = new[] { typeof(Game).Name, typeof(Book).Name },
+ IsPlaceHolder = false
}).ConfigureAwait(false);
@@ -579,29 +581,6 @@ namespace MediaBrowser.Dlna.ContentDirectory
});
}
- private bool FilterUnsupportedContent(BaseItem i)
- {
- // Unplayable
- if (i.LocationType == LocationType.Virtual && !i.IsFolder)
- {
- return false;
- }
-
- // Unplayable
- var supportsPlaceHolder = i as ISupportsPlaceHolders;
- if (supportsPlaceHolder != null && supportsPlaceHolder.IsPlaceHolder)
- {
- return false;
- }
-
- if (i is Game || i is Book)
- {
- //return false;
- }
-
- return true;
- }
-
private ServerItem GetItemFromObjectId(string id, User user)
{
return DidlBuilder.IsIdRoot(id)
diff --git a/MediaBrowser.Model/Configuration/ServerConfiguration.cs b/MediaBrowser.Model/Configuration/ServerConfiguration.cs
index b115440d60..1cb19afdf2 100644
--- a/MediaBrowser.Model/Configuration/ServerConfiguration.cs
+++ b/MediaBrowser.Model/Configuration/ServerConfiguration.cs
@@ -215,6 +215,9 @@ namespace MediaBrowser.Model.Configuration
{
Migrations = new string[] { };
+ EnableLocalizedGuids = true;
+ EnableCustomPathSubFolders = true;
+
ImageSavingConvention = ImageSavingConvention.Compatible;
PublicPort = 8096;
PublicHttpsPort = 8920;
diff --git a/MediaBrowser.Model/Entities/MediaStream.cs b/MediaBrowser.Model/Entities/MediaStream.cs
index 9b814c5ccc..64c7d9aa6c 100644
--- a/MediaBrowser.Model/Entities/MediaStream.cs
+++ b/MediaBrowser.Model/Entities/MediaStream.cs
@@ -1,8 +1,8 @@
-using System;
-using System.Collections.Generic;
+using System.Collections.Generic;
using MediaBrowser.Model.Dlna;
using MediaBrowser.Model.Extensions;
using System.Diagnostics;
+using MediaBrowser.Model.MediaInfo;
namespace MediaBrowser.Model.Entities
{
@@ -53,18 +53,22 @@ namespace MediaBrowser.Model.Entities
if (!string.IsNullOrEmpty(Language))
{
- attributes.Add(Language);
+ attributes.Add(StringHelper.FirstToUpper(Language));
}
if (!string.IsNullOrEmpty(Codec) && !StringHelper.EqualsIgnoreCase(Codec, "dca"))
{
- attributes.Add(Codec);
- }
- if (!string.IsNullOrEmpty(Profile) && !StringHelper.EqualsIgnoreCase(Profile, "lc"))
+ attributes.Add(AudioCodec.GetFriendlyName(Codec));
+ }
+ else if (!string.IsNullOrEmpty(Profile) && !StringHelper.EqualsIgnoreCase(Profile, "lc"))
{
attributes.Add(Profile);
}
- if (Channels.HasValue)
+ if (!string.IsNullOrEmpty(ChannelLayout))
+ {
+ attributes.Add(ChannelLayout);
+ }
+ else if (Channels.HasValue)
{
attributes.Add(StringHelper.ToStringCultureInvariant(Channels.Value) + " ch");
}
diff --git a/MediaBrowser.Model/Extensions/StringHelper.cs b/MediaBrowser.Model/Extensions/StringHelper.cs
index 99bec68a73..9cde3bfa45 100644
--- a/MediaBrowser.Model/Extensions/StringHelper.cs
+++ b/MediaBrowser.Model/Extensions/StringHelper.cs
@@ -125,5 +125,10 @@ namespace MediaBrowser.Model.Extensions
return sb.ToString();
}
+
+ public static string FirstToUpper(this string str)
+ {
+ return string.IsNullOrEmpty(str) ? "" : str.Substring(0, 1).ToUpper() + str.Substring(1);
+ }
}
}
diff --git a/MediaBrowser.Model/LiveTv/LiveTvOptions.cs b/MediaBrowser.Model/LiveTv/LiveTvOptions.cs
index 4211fbd59f..e00443d191 100644
--- a/MediaBrowser.Model/LiveTv/LiveTvOptions.cs
+++ b/MediaBrowser.Model/LiveTv/LiveTvOptions.cs
@@ -20,12 +20,15 @@ namespace MediaBrowser.Model.LiveTv
public int PrePaddingSeconds { get; set; }
public int PostPaddingSeconds { get; set; }
+ public string[] MediaLocationsCreated { get; set; }
+
public LiveTvOptions()
{
EnableMovieProviders = true;
EnableRecordingSubfolders = true;
TunerHosts = new List<TunerHostInfo>();
ListingProviders = new List<ListingsProviderInfo>();
+ MediaLocationsCreated = new string[] { };
}
}
diff --git a/MediaBrowser.Model/MediaInfo/AudioCodec.cs b/MediaBrowser.Model/MediaInfo/AudioCodec.cs
index 5353f2b3ec..93aba2f434 100644
--- a/MediaBrowser.Model/MediaInfo/AudioCodec.cs
+++ b/MediaBrowser.Model/MediaInfo/AudioCodec.cs
@@ -5,5 +5,22 @@
public const string AAC = "aac";
public const string MP3 = "mp3";
public const string AC3 = "ac3";
+
+ public static string GetFriendlyName(string codec)
+ {
+ if (string.IsNullOrEmpty(codec)) return "";
+
+ switch (codec.ToLower())
+ {
+ case "ac3":
+ return "Dolby Digital";
+ case "eac3":
+ return "Dolby Digital+";
+ case "dca":
+ return "DTS";
+ default:
+ return codec.ToUpper();
+ }
+ }
}
} \ No newline at end of file
diff --git a/MediaBrowser.Model/Querying/ItemQuery.cs b/MediaBrowser.Model/Querying/ItemQuery.cs
index 5a88c0d43e..11c0464522 100644
--- a/MediaBrowser.Model/Querying/ItemQuery.cs
+++ b/MediaBrowser.Model/Querying/ItemQuery.cs
@@ -288,6 +288,8 @@ namespace MediaBrowser.Model.Querying
[Obsolete]
public string Person { get; set; }
+ public bool EnableTotalRecordCount { get; set; }
+
/// <summary>
/// Initializes a new instance of the <see cref="ItemQuery" /> class.
/// </summary>
@@ -306,6 +308,8 @@ namespace MediaBrowser.Model.Querying
VideoTypes = new VideoType[] { };
+ EnableTotalRecordCount = true;
+
Artists = new string[] { };
Studios = new string[] { };
diff --git a/MediaBrowser.Providers/Manager/MetadataService.cs b/MediaBrowser.Providers/Manager/MetadataService.cs
index a0c6bd889a..7184302f19 100644
--- a/MediaBrowser.Providers/Manager/MetadataService.cs
+++ b/MediaBrowser.Providers/Manager/MetadataService.cs
@@ -145,11 +145,15 @@ namespace MediaBrowser.Providers.Manager
bool hasRefreshedMetadata = true;
bool hasRefreshedImages = true;
+ var requiresRefresh = false;
// Next run metadata providers
if (refreshOptions.MetadataRefreshMode != MetadataRefreshMode.None)
{
- var providers = GetProviders(item, refreshResult, refreshOptions)
+ // TODO: If this returns true, should we instead just change metadata refresh mode to Full?
+ requiresRefresh = item.RequiresRefresh();
+
+ var providers = GetProviders(item, refreshResult, refreshOptions, requiresRefresh)
.ToList();
var dateLastRefresh = EnableDateLastRefreshed(item)
@@ -217,11 +221,11 @@ namespace MediaBrowser.Providers.Manager
var isFirstRefresh = GetLastRefreshDate(item) == default(DateTime);
- var beforeSaveResult = await BeforeSave(itemOfType, isFirstRefresh || refreshOptions.ReplaceAllMetadata || refreshOptions.MetadataRefreshMode == MetadataRefreshMode.FullRefresh, updateType).ConfigureAwait(false);
+ var beforeSaveResult = await BeforeSave(itemOfType, isFirstRefresh || refreshOptions.ReplaceAllMetadata || refreshOptions.MetadataRefreshMode == MetadataRefreshMode.FullRefresh || requiresRefresh, updateType).ConfigureAwait(false);
updateType = updateType | beforeSaveResult;
// Save if changes were made, or it's never been saved before
- if (refreshOptions.ForceSave || updateType > ItemUpdateType.None || isFirstRefresh || refreshOptions.ReplaceAllMetadata)
+ if (refreshOptions.ForceSave || updateType > ItemUpdateType.None || isFirstRefresh || refreshOptions.ReplaceAllMetadata || requiresRefresh)
{
// If any of these properties are set then make sure the updateType is not None, just to force everything to save
if (refreshOptions.ForceSave || refreshOptions.ReplaceAllMetadata)
@@ -461,11 +465,8 @@ namespace MediaBrowser.Providers.Manager
/// <summary>
/// Gets the providers.
/// </summary>
- /// <param name="item">The item.</param>
- /// <param name="status">The status.</param>
- /// <param name="options">The options.</param>
/// <returns>IEnumerable{`0}.</returns>
- protected IEnumerable<IMetadataProvider> GetProviders(IHasMetadata item, MetadataStatus status, MetadataRefreshOptions options)
+ protected IEnumerable<IMetadataProvider> GetProviders(IHasMetadata item, MetadataStatus status, MetadataRefreshOptions options, bool requiresRefresh)
{
// Get providers to refresh
var providers = ((ProviderManager)ProviderManager).GetMetadataProviders<TItemType>(item).ToList();
@@ -475,7 +476,7 @@ namespace MediaBrowser.Providers.Manager
: status.DateLastMetadataRefresh ?? default(DateTime);
// Run all if either of these flags are true
- var runAllProviders = options.ReplaceAllMetadata || options.MetadataRefreshMode == MetadataRefreshMode.FullRefresh || dateLastRefresh == default(DateTime) || item.RequiresRefresh();
+ var runAllProviders = options.ReplaceAllMetadata || options.MetadataRefreshMode == MetadataRefreshMode.FullRefresh || dateLastRefresh == default(DateTime) || requiresRefresh;
if (!runAllProviders)
{
@@ -668,12 +669,6 @@ namespace MediaBrowser.Providers.Manager
// If a local provider fails, consider that a failure
refreshResult.ErrorMessage = ex.Message;
-
- if (options.MetadataRefreshMode != MetadataRefreshMode.FullRefresh)
- {
- // If the local provider fails don't continue with remote providers because the user's saved metadata could be lost
- //return refreshResult;
- }
}
}
diff --git a/MediaBrowser.Providers/TV/DummySeasonProvider.cs b/MediaBrowser.Providers/TV/DummySeasonProvider.cs
index 2c6e27294d..909760feef 100644
--- a/MediaBrowser.Providers/TV/DummySeasonProvider.cs
+++ b/MediaBrowser.Providers/TV/DummySeasonProvider.cs
@@ -69,7 +69,7 @@ namespace MediaBrowser.Providers.TV
if (!hasSeason)
{
- await AddSeason(series, seasonNumber, cancellationToken).ConfigureAwait(false);
+ await AddSeason(series, seasonNumber, false, cancellationToken).ConfigureAwait(false);
hasChanges = true;
}
@@ -83,7 +83,7 @@ namespace MediaBrowser.Providers.TV
if (!hasSeason)
{
- await AddSeason(series, null, cancellationToken).ConfigureAwait(false);
+ await AddSeason(series, null, false, cancellationToken).ConfigureAwait(false);
hasChanges = true;
}
@@ -95,12 +95,9 @@ namespace MediaBrowser.Providers.TV
/// <summary>
/// Adds the season.
/// </summary>
- /// <param name="series">The series.</param>
- /// <param name="seasonNumber">The season number.</param>
- /// <param name="cancellationToken">The cancellation token.</param>
- /// <returns>Task{Season}.</returns>
public async Task<Season> AddSeason(Series series,
int? seasonNumber,
+ bool isVirtualItem,
CancellationToken cancellationToken)
{
var seasonName = seasonNumber == 0 ?
@@ -113,7 +110,8 @@ namespace MediaBrowser.Providers.TV
{
Name = seasonName,
IndexNumber = seasonNumber,
- Id = _libraryManager.GetNewItemId((series.Id + (seasonNumber ?? -1).ToString(_usCulture) + seasonName), typeof(Season))
+ Id = _libraryManager.GetNewItemId((series.Id + (seasonNumber ?? -1).ToString(_usCulture) + seasonName), typeof(Season)),
+ IsVirtualItem = isVirtualItem
};
season.SetParent(series);
diff --git a/MediaBrowser.Providers/TV/MissingEpisodeProvider.cs b/MediaBrowser.Providers/TV/MissingEpisodeProvider.cs
index e79ad2dfbd..2a3150c78b 100644
--- a/MediaBrowser.Providers/TV/MissingEpisodeProvider.cs
+++ b/MediaBrowser.Providers/TV/MissingEpisodeProvider.cs
@@ -418,7 +418,7 @@ namespace MediaBrowser.Providers.TV
if (season == null)
{
var provider = new DummySeasonProvider(_config, _logger, _localization, _libraryManager, _fileSystem);
- season = await provider.AddSeason(series, seasonNumber, cancellationToken).ConfigureAwait(false);
+ season = await provider.AddSeason(series, seasonNumber, true, cancellationToken).ConfigureAwait(false);
}
var name = string.Format("Episode {0}", episodeNumber.ToString(_usCulture));
diff --git a/MediaBrowser.Providers/TV/SeasonMetadataService.cs b/MediaBrowser.Providers/TV/SeasonMetadataService.cs
index 292923d824..ae19a6a448 100644
--- a/MediaBrowser.Providers/TV/SeasonMetadataService.cs
+++ b/MediaBrowser.Providers/TV/SeasonMetadataService.cs
@@ -36,7 +36,7 @@ namespace MediaBrowser.Providers.TV
{
var episodes = item.GetEpisodes().ToList();
updateType |= SavePremiereDate(item, episodes);
- updateType |= SaveIsMissing(item, episodes);
+ updateType |= SaveIsVirtualItem(item, episodes);
}
return updateType;
@@ -67,13 +67,13 @@ namespace MediaBrowser.Providers.TV
return ItemUpdateType.None;
}
- private ItemUpdateType SaveIsMissing(Season item, List<Episode> episodes)
+ private ItemUpdateType SaveIsVirtualItem(Season item, List<Episode> episodes)
{
- var isMissing = item.LocationType == LocationType.Virtual && episodes.All(i => i.IsMissingEpisode);
+ var isVirtualItem = item.LocationType == LocationType.Virtual && (episodes.Count == 0 || episodes.All(i => i.LocationType == LocationType.Virtual));
- if (item.IsMissingSeason != isMissing)
+ if (item.IsVirtualItem != isVirtualItem)
{
- item.IsMissingSeason = isMissing;
+ item.IsVirtualItem = isVirtualItem;
return ItemUpdateType.MetadataEdit;
}
diff --git a/MediaBrowser.Server.Implementations/Library/LibraryManager.cs b/MediaBrowser.Server.Implementations/Library/LibraryManager.cs
index 1407cdce30..56d3bd4de1 100644
--- a/MediaBrowser.Server.Implementations/Library/LibraryManager.cs
+++ b/MediaBrowser.Server.Implementations/Library/LibraryManager.cs
@@ -1448,8 +1448,12 @@ namespace MediaBrowser.Server.Implementations.Library
// Handle grouping
if (user != null && !string.IsNullOrWhiteSpace(view.ViewType) && UserView.IsEligibleForGrouping(view.ViewType))
{
- var collectionFolders = user.RootFolder.GetChildren(user, true).OfType<CollectionFolder>().Where(i => string.IsNullOrWhiteSpace(i.CollectionType) || string.Equals(i.CollectionType, view.ViewType, StringComparison.OrdinalIgnoreCase));
- return collectionFolders.SelectMany(i => GetTopParentsForQuery(i, user));
+ return user.RootFolder
+ .GetChildren(user, true)
+ .OfType<CollectionFolder>()
+ .Where(i => string.IsNullOrWhiteSpace(i.CollectionType) || string.Equals(i.CollectionType, view.ViewType, StringComparison.OrdinalIgnoreCase))
+ .Where(i => user.IsFolderGrouped(i.Id))
+ .SelectMany(i => GetTopParentsForQuery(i, user));
}
return new BaseItem[] { };
}
diff --git a/MediaBrowser.Server.Implementations/Library/MusicManager.cs b/MediaBrowser.Server.Implementations/Library/MusicManager.cs
index c82c4cdf7b..ef13ba9960 100644
--- a/MediaBrowser.Server.Implementations/Library/MusicManager.cs
+++ b/MediaBrowser.Server.Implementations/Library/MusicManager.cs
@@ -30,7 +30,10 @@ namespace MediaBrowser.Server.Implementations.Library
public IEnumerable<Audio> GetInstantMixFromArtist(MusicArtist artist, User user)
{
var genres = user.RootFolder
- .GetRecursiveChildren(user, i => i is Audio)
+ .GetRecursiveChildren(user, new InternalItemsQuery(user)
+ {
+ IncludeItemTypes = new[] { typeof(Audio).Name }
+ })
.Cast<Audio>()
.Where(i => i.HasAnyArtist(artist.Name))
.SelectMany(i => i.Genres)
@@ -43,7 +46,10 @@ namespace MediaBrowser.Server.Implementations.Library
public IEnumerable<Audio> GetInstantMixFromAlbum(MusicAlbum item, User user)
{
var genres = item
- .GetRecursiveChildren(user, i => i is Audio)
+ .GetRecursiveChildren(user, new InternalItemsQuery(user)
+ {
+ IncludeItemTypes = new[] { typeof(Audio).Name }
+ })
.Cast<Audio>()
.SelectMany(i => i.Genres)
.Concat(item.Genres)
@@ -55,7 +61,10 @@ namespace MediaBrowser.Server.Implementations.Library
public IEnumerable<Audio> GetInstantMixFromFolder(Folder item, User user)
{
var genres = item
- .GetRecursiveChildren(user, i => i is Audio)
+ .GetRecursiveChildren(user, new InternalItemsQuery(user)
+ {
+ IncludeItemTypes = new[] {typeof(Audio).Name}
+ })
.Cast<Audio>()
.SelectMany(i => i.Genres)
.Concat(item.Genres)
@@ -67,7 +76,10 @@ namespace MediaBrowser.Server.Implementations.Library
public IEnumerable<Audio> GetInstantMixFromPlaylist(Playlist item, User user)
{
var genres = item
- .GetRecursiveChildren(user, i => i is Audio)
+ .GetRecursiveChildren(user, new InternalItemsQuery(user)
+ {
+ IncludeItemTypes = new[] { typeof(Audio).Name }
+ })
.Cast<Audio>()
.SelectMany(i => i.Genres)
.Concat(item.Genres)
diff --git a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs
index 2de51479f2..de75aac9cd 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs
+++ b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs
@@ -115,17 +115,13 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV
{
var recordingFolders = GetRecordingFolders();
- var defaultRecordingPath = DefaultRecordingPath;
- if (!recordingFolders.Any(i => i.Locations.Contains(defaultRecordingPath, StringComparer.OrdinalIgnoreCase)))
- {
- RemovePathFromLibrary(defaultRecordingPath);
- }
-
var virtualFolders = _libraryManager.GetVirtualFolders()
.ToList();
var allExistingPaths = virtualFolders.SelectMany(i => i.Locations).ToList();
+ var pathsAdded = new List<string>();
+
foreach (var recordingFolder in recordingFolders)
{
var pathsToCreate = recordingFolder.Locations
@@ -145,11 +141,33 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV
{
_logger.ErrorException("Error creating virtual folder", ex);
}
+
+ pathsAdded.AddRange(pathsToCreate);
+ }
+
+ var config = GetConfiguration();
+
+ var pathsToRemove = config.MediaLocationsCreated
+ .Except(recordingFolders.SelectMany(i => i.Locations))
+ .ToList();
+
+ if (pathsAdded.Count > 0 || pathsToRemove.Count > 0)
+ {
+ pathsAdded.InsertRange(0, config.MediaLocationsCreated);
+ config.MediaLocationsCreated = pathsAdded.Except(pathsToRemove).Distinct(StringComparer.OrdinalIgnoreCase).ToArray();
+ _config.SaveConfiguration("livetv", config);
+ }
+
+ foreach (var path in pathsToRemove)
+ {
+ RemovePathFromLibrary(path);
}
}
private void RemovePathFromLibrary(string path)
{
+ _logger.Debug("Removing path from library: {0}", path);
+
var requiresRefresh = false;
var virtualFolders = _libraryManager.GetVirtualFolders()
.ToList();
diff --git a/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs b/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs
index 9251ccb9ee..91f84e2fef 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs
+++ b/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs
@@ -527,6 +527,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv
private async Task<LiveTvChannel> GetChannel(ChannelInfo channelInfo, string serviceName, Guid parentFolderId, CancellationToken cancellationToken)
{
var isNew = false;
+ var forceUpdate = false;
var id = _tvDtoService.GetInternalChannelId(serviceName, channelInfo.Id);
@@ -576,10 +577,12 @@ namespace MediaBrowser.Server.Implementations.LiveTv
if (!string.IsNullOrWhiteSpace(channelInfo.ImagePath))
{
item.SetImagePath(ImageType.Primary, channelInfo.ImagePath);
+ forceUpdate = true;
}
else if (!string.IsNullOrWhiteSpace(channelInfo.ImageUrl))
{
item.SetImagePath(ImageType.Primary, channelInfo.ImageUrl);
+ forceUpdate = true;
}
}
@@ -588,9 +591,18 @@ namespace MediaBrowser.Server.Implementations.LiveTv
item.Name = channelInfo.Name;
}
+ if (isNew)
+ {
+ await _libraryManager.CreateItem(item, cancellationToken).ConfigureAwait(false);
+ }
+ else if (forceUpdate)
+ {
+ await _libraryManager.UpdateItem(item, ItemUpdateType.MetadataImport, cancellationToken).ConfigureAwait(false);
+ }
+
await item.RefreshMetadata(new MetadataRefreshOptions(_fileSystem)
{
- ForceSave = isNew
+ ForceSave = isNew || forceUpdate
}, cancellationToken);
@@ -1398,16 +1410,22 @@ namespace MediaBrowser.Server.Implementations.LiveTv
.Where(i => i.IsVisibleStandalone(user))
.ToList();
- var items = _libraryManager.GetItemsResult(new InternalItemsQuery(user)
+ if (folders.Count == 0)
+ {
+ return new QueryResult<BaseItem>();
+ }
+
+ return _libraryManager.GetItemsResult(new InternalItemsQuery(user)
{
MediaTypes = new[] { MediaType.Video },
Recursive = true,
AncestorIds = folders.Select(i => i.Id.ToString("N")).ToArray(),
+ IsFolder = false,
ExcludeLocationTypes = new[] { LocationType.Virtual },
- Limit = Math.Min(10, query.Limit ?? int.MaxValue)
+ Limit = Math.Min(200, query.Limit ?? int.MaxValue),
+ SortBy = new[] { ItemSortBy.DateCreated },
+ SortOrder = SortOrder.Descending
});
-
- return items;
}
public async Task<QueryResult<BaseItem>> GetInternalRecordings(RecordingQuery query, CancellationToken cancellationToken)
diff --git a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj
index aff3a5e160..0aa499f696 100644
--- a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj
+++ b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj
@@ -55,9 +55,9 @@
<Reference Include="Interfaces.IO">
<HintPath>..\packages\Interfaces.IO.1.0.0.5\lib\portable-net45+sl4+wp71+win8+wpa81\Interfaces.IO.dll</HintPath>
</Reference>
- <Reference Include="MediaBrowser.Naming, Version=1.0.5917.1514, Culture=neutral, processorArchitecture=MSIL">
- <SpecificVersion>False</SpecificVersion>
- <HintPath>..\packages\MediaBrowser.Naming.1.0.0.49\lib\portable-net45+sl4+wp71+win8+wpa81\MediaBrowser.Naming.dll</HintPath>
+ <Reference Include="MediaBrowser.Naming, Version=1.0.5981.21615, Culture=neutral, processorArchitecture=MSIL">
+ <HintPath>..\packages\MediaBrowser.Naming.1.0.0.50\lib\portable-net45+sl4+wp71+win8+wpa81\MediaBrowser.Naming.dll</HintPath>
+ <Private>True</Private>
</Reference>
<Reference Include="MoreLinq">
<HintPath>..\packages\morelinq.1.4.0\lib\net35\MoreLinq.dll</HintPath>
@@ -68,8 +68,8 @@
<Reference Include="ServiceStack.Api.Swagger">
<HintPath>..\ThirdParty\ServiceStack\ServiceStack.Api.Swagger.dll</HintPath>
</Reference>
- <Reference Include="SimpleInjector, Version=3.1.3.0, Culture=neutral, PublicKeyToken=984cb50dea722e99, processorArchitecture=MSIL">
- <HintPath>..\packages\SimpleInjector.3.1.3\lib\net45\SimpleInjector.dll</HintPath>
+ <Reference Include="SimpleInjector, Version=3.1.4.0, Culture=neutral, PublicKeyToken=984cb50dea722e99, processorArchitecture=MSIL">
+ <HintPath>..\packages\SimpleInjector.3.1.4\lib\net45\SimpleInjector.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="SocketHttpListener, Version=1.0.5955.1537, Culture=neutral, processorArchitecture=MSIL">
diff --git a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs
index e04c879171..7f45e61842 100644
--- a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs
+++ b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs
@@ -81,10 +81,13 @@ namespace MediaBrowser.Server.Implementations.Persistence
private IDbCommand _deleteUserDataKeysCommand;
private IDbCommand _saveUserDataKeysCommand;
+ private IDbCommand _deleteItemValuesCommand;
+ private IDbCommand _saveItemValuesCommand;
+
private IDbCommand _updateInheritedRatingCommand;
private IDbCommand _updateInheritedTagsCommand;
- public const int LatestSchemaVersion = 78;
+ public const int LatestSchemaVersion = 79;
/// <summary>
/// Initializes a new instance of the <see cref="SqliteItemRepository"/> class.
@@ -136,6 +139,9 @@ namespace MediaBrowser.Server.Implementations.Persistence
"create table if not exists UserDataKeys (ItemId GUID, UserDataKey TEXT, PRIMARY KEY (ItemId, UserDataKey))",
"create index if not exists idx_UserDataKeys1 on UserDataKeys(ItemId)",
+ "create table if not exists ItemValues (ItemId GUID, Type INT, Value TEXT)",
+ "create index if not exists idx_ItemValues on ItemValues(ItemId)",
+
"create table if not exists People (ItemId GUID, Name TEXT NOT NULL, Role TEXT, PersonType TEXT, SortOrder int, ListOrder int)",
"create index if not exists idxPeopleItemId on People(ItemId)",
"create index if not exists idxPeopleName on People(Name)",
@@ -232,6 +238,7 @@ namespace MediaBrowser.Server.Implementations.Persistence
_connection.AddColumn(Logger, "TypedBaseItems", "PrimaryVersionId", "Text");
_connection.AddColumn(Logger, "TypedBaseItems", "DateLastMediaAdded", "DATETIME");
_connection.AddColumn(Logger, "TypedBaseItems", "Album", "Text");
+ _connection.AddColumn(Logger, "TypedBaseItems", "IsVirtualItem", "BIT");
_connection.AddColumn(Logger, "UserDataKeys", "Priority", "INT");
@@ -353,7 +360,8 @@ namespace MediaBrowser.Server.Implementations.Persistence
"DateLastMediaAdded",
"Album",
"CriticRating",
- "CriticRatingSummary"
+ "CriticRatingSummary",
+ "IsVirtualItem"
};
private readonly string[] _mediaStreamSaveColumns =
@@ -468,7 +476,8 @@ namespace MediaBrowser.Server.Implementations.Persistence
"OriginalTitle",
"PrimaryVersionId",
"DateLastMediaAdded",
- "Album"
+ "Album",
+ "IsVirtualItem"
};
_saveItemCommand = _connection.CreateCommand();
_saveItemCommand.CommandText = "replace into TypedBaseItems (" + string.Join(",", saveColumns.ToArray()) + ") values (";
@@ -565,6 +574,17 @@ namespace MediaBrowser.Server.Implementations.Persistence
_saveUserDataKeysCommand.Parameters.Add(_saveUserDataKeysCommand, "@UserDataKey");
_saveUserDataKeysCommand.Parameters.Add(_saveUserDataKeysCommand, "@Priority");
+ // item values
+ _deleteItemValuesCommand = _connection.CreateCommand();
+ _deleteItemValuesCommand.CommandText = "delete from ItemValues where ItemId=@Id";
+ _deleteItemValuesCommand.Parameters.Add(_deleteItemValuesCommand, "@Id");
+
+ _saveItemValuesCommand = _connection.CreateCommand();
+ _saveItemValuesCommand.CommandText = "insert into ItemValues (ItemId, Type, Value) values (@ItemId, @Type, @Value)";
+ _saveItemValuesCommand.Parameters.Add(_saveItemValuesCommand, "@ItemId");
+ _saveItemValuesCommand.Parameters.Add(_saveItemValuesCommand, "@Type");
+ _saveItemValuesCommand.Parameters.Add(_saveItemValuesCommand, "@Value");
+
}
/// <summary>
@@ -722,7 +742,15 @@ namespace MediaBrowser.Server.Implementations.Persistence
_saveItemCommand.GetParameter(index++).Value = item.DateLastRefreshed;
}
- _saveItemCommand.GetParameter(index++).Value = item.DateLastSaved;
+ if (item.DateLastSaved == default(DateTime))
+ {
+ _saveItemCommand.GetParameter(index++).Value = null;
+ }
+ else
+ {
+ _saveItemCommand.GetParameter(index++).Value = item.DateLastSaved;
+ }
+
_saveItemCommand.GetParameter(index++).Value = item.IsInMixedFolder;
_saveItemCommand.GetParameter(index++).Value = string.Join("|", item.LockedFields.Select(i => i.ToString()).ToArray());
_saveItemCommand.GetParameter(index++).Value = string.Join("|", item.Studios.ToArray());
@@ -841,6 +869,16 @@ namespace MediaBrowser.Server.Implementations.Persistence
_saveItemCommand.GetParameter(index++).Value = item.Album;
+ var season = item as Season;
+ if (season != null && season.IsVirtualItem.HasValue)
+ {
+ _saveItemCommand.GetParameter(index++).Value = season.IsVirtualItem.Value;
+ }
+ else
+ {
+ _saveItemCommand.GetParameter(index++).Value = null;
+ }
+
_saveItemCommand.Transaction = transaction;
_saveItemCommand.ExecuteNonQuery();
@@ -851,6 +889,7 @@ namespace MediaBrowser.Server.Implementations.Persistence
}
UpdateUserDataKeys(item.Id, item.GetUserDataKeys().Distinct(StringComparer.OrdinalIgnoreCase).ToList(), transaction);
+ UpdateItemValues(item.Id, GetItemValues(item), transaction);
}
transaction.Commit();
@@ -1255,6 +1294,12 @@ namespace MediaBrowser.Server.Implementations.Persistence
item.CriticRatingSummary = reader.GetString(57);
}
+ var season = item as Season;
+ if (season != null && !reader.IsDBNull(58))
+ {
+ season.IsVirtualItem = reader.GetBoolean(58);
+ }
+
return item;
}
@@ -1661,7 +1706,7 @@ namespace MediaBrowser.Server.Implementations.Persistence
{
var elapsed = (DateTime.UtcNow - startDate).TotalMilliseconds;
- if (elapsed >= 500)
+ if (elapsed >= 400)
{
Logger.Debug("{2} query time (slow): {0}ms. Query: {1}",
Convert.ToInt32(elapsed),
@@ -1795,7 +1840,7 @@ namespace MediaBrowser.Server.Implementations.Persistence
}).ToArray());
}
- private Tuple<string,bool> MapOrderByField(string name)
+ private Tuple<string, bool> MapOrderByField(string name)
{
if (string.Equals(name, ItemSortBy.AirTime, StringComparison.OrdinalIgnoreCase))
{
@@ -1838,6 +1883,14 @@ namespace MediaBrowser.Server.Implementations.Persistence
{
return new Tuple<string, bool>("DateLastMediaAdded", false);
}
+ if (string.Equals(name, ItemSortBy.Artist, StringComparison.OrdinalIgnoreCase))
+ {
+ return new Tuple<string, bool>("(select value from itemvalues where ItemId=Guid and Type=0 LIMIT 1)", false);
+ }
+ if (string.Equals(name, ItemSortBy.AlbumArtist, StringComparison.OrdinalIgnoreCase))
+ {
+ return new Tuple<string, bool>("(select value from itemvalues where ItemId=Guid and Type=1 LIMIT 1)", false);
+ }
return new Tuple<string, bool>(name, false);
}
@@ -2405,17 +2458,20 @@ namespace MediaBrowser.Server.Implementations.Persistence
cmd.Parameters.Add(cmd, "@IsFavorite", DbType.Boolean).Value = query.IsFavorite.Value;
}
- if (query.IsPlayed.HasValue)
+ if (EnableJoinUserData(query))
{
- if (query.IsPlayed.Value)
- {
- whereClauses.Add("(played=@IsPlayed)");
- }
- else
+ if (query.IsPlayed.HasValue)
{
- whereClauses.Add("(played is null or played=@IsPlayed)");
+ if (query.IsPlayed.Value)
+ {
+ whereClauses.Add("(played=@IsPlayed)");
+ }
+ else
+ {
+ whereClauses.Add("(played is null or played=@IsPlayed)");
+ }
+ cmd.Parameters.Add(cmd, "@IsPlayed", DbType.Boolean).Value = query.IsPlayed.Value;
}
- cmd.Parameters.Add(cmd, "@IsPlayed", DbType.Boolean).Value = query.IsPlayed.Value;
}
if (query.IsResumable.HasValue)
@@ -2430,6 +2486,20 @@ namespace MediaBrowser.Server.Implementations.Persistence
}
}
+ if (query.ArtistNames.Length > 0)
+ {
+ var clauses = new List<string>();
+ var index = 0;
+ foreach (var artist in query.ArtistNames)
+ {
+ clauses.Add("@ArtistName" + index + " in (select value from itemvalues where ItemId=Guid and Type <= 1)");
+ cmd.Parameters.Add(cmd, "@ArtistName" + index, DbType.String).Value = artist;
+ index++;
+ }
+ var clause = "(" + string.Join(" OR ", clauses.ToArray()) + ")";
+ whereClauses.Add(clause);
+ }
+
if (query.Genres.Length > 0)
{
var clauses = new List<string>();
@@ -2967,6 +3037,11 @@ namespace MediaBrowser.Server.Implementations.Persistence
_deleteUserDataKeysCommand.Transaction = transaction;
_deleteUserDataKeysCommand.ExecuteNonQuery();
+ // Delete item values
+ _deleteItemValuesCommand.GetParameter(0).Value = id;
+ _deleteItemValuesCommand.Transaction = transaction;
+ _deleteItemValuesCommand.ExecuteNonQuery();
+
// Delete the item
_deleteItemCommand.GetParameter(0).Value = id;
_deleteItemCommand.Transaction = transaction;
@@ -3159,6 +3234,56 @@ namespace MediaBrowser.Server.Implementations.Persistence
}
}
+ private List<Tuple<int, string>> GetItemValues(BaseItem item)
+ {
+ var list = new List<Tuple<int, string>>();
+
+ var hasArtist = item as IHasArtist;
+ if (hasArtist != null)
+ {
+ list.AddRange(hasArtist.Artists.Select(i => new Tuple<int, string>(0, i)));
+ }
+
+ var hasAlbumArtist = item as IHasAlbumArtist;
+ if (hasAlbumArtist != null)
+ {
+ list.AddRange(hasAlbumArtist.AlbumArtists.Select(i => new Tuple<int, string>(1, i)));
+ }
+
+ return list;
+ }
+
+ private void UpdateItemValues(Guid itemId, List<Tuple<int, string>> values, IDbTransaction transaction)
+ {
+ if (itemId == Guid.Empty)
+ {
+ throw new ArgumentNullException("itemId");
+ }
+
+ if (values == null)
+ {
+ throw new ArgumentNullException("keys");
+ }
+
+ CheckDisposed();
+
+ // First delete
+ _deleteItemValuesCommand.GetParameter(0).Value = itemId;
+ _deleteItemValuesCommand.Transaction = transaction;
+
+ _deleteItemValuesCommand.ExecuteNonQuery();
+
+ foreach (var pair in values)
+ {
+ _saveItemValuesCommand.GetParameter(0).Value = itemId;
+ _saveItemValuesCommand.GetParameter(1).Value = pair.Item1;
+ _saveItemValuesCommand.GetParameter(2).Value = pair.Item2;
+ _saveItemValuesCommand.Transaction = transaction;
+
+ _saveItemValuesCommand.ExecuteNonQuery();
+ }
+ }
+
private void UpdateUserDataKeys(Guid itemId, List<string> keys, IDbTransaction transaction)
{
if (itemId == Guid.Empty)
diff --git a/MediaBrowser.Server.Implementations/packages.config b/MediaBrowser.Server.Implementations/packages.config
index dce839b572..b877d41a87 100644
--- a/MediaBrowser.Server.Implementations/packages.config
+++ b/MediaBrowser.Server.Implementations/packages.config
@@ -4,10 +4,10 @@
<package id="Emby.XmlTv" version="1.0.0.48" targetFramework="net45" />
<package id="ini-parser" version="2.2.4" targetFramework="net45" />
<package id="Interfaces.IO" version="1.0.0.5" targetFramework="net45" />
- <package id="MediaBrowser.Naming" version="1.0.0.49" targetFramework="net45" />
+ <package id="MediaBrowser.Naming" version="1.0.0.50" targetFramework="net45" />
<package id="Mono.Nat" version="1.2.24.0" targetFramework="net45" />
<package id="morelinq" version="1.4.0" targetFramework="net45" />
<package id="Patterns.Logging" version="1.0.0.2" targetFramework="net45" />
- <package id="SimpleInjector" version="3.1.3" targetFramework="net45" />
+ <package id="SimpleInjector" version="3.1.4" targetFramework="net45" />
<package id="SocketHttpListener" version="1.0.0.30" targetFramework="net45" />
</packages> \ No newline at end of file
diff --git a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj
index 0061ec5de0..e85f5a27b1 100644
--- a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj
+++ b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj
@@ -107,9 +107,6 @@
<Content Include="dashboard-ui\components\chromecasthelpers.js">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
- <Content Include="dashboard-ui\bower_components\fastclick\lib\fastclick.js">
- <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
- </Content>
<Content Include="dashboard-ui\components\favoriteitems.js">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
@@ -1686,6 +1683,9 @@
<None Include="dashboard-ui\strings\id.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
+ <None Include="dashboard-ui\strings\sk.json">
+ <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+ </None>
<None Include="dashboard-ui\strings\zh-HK.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
diff --git a/Nuget/MediaBrowser.Common.Internal.nuspec b/Nuget/MediaBrowser.Common.Internal.nuspec
index d17fab368d..56429c6a6b 100644
--- a/Nuget/MediaBrowser.Common.Internal.nuspec
+++ b/Nuget/MediaBrowser.Common.Internal.nuspec
@@ -2,7 +2,7 @@
<package xmlns="http://schemas.microsoft.com/packaging/2011/08/nuspec.xsd">
<metadata>
<id>MediaBrowser.Common.Internal</id>
- <version>3.0.647</version>
+ <version>3.0.648</version>
<title>MediaBrowser.Common.Internal</title>
<authors>Luke</authors>
<owners>ebr,Luke,scottisafool</owners>
@@ -12,9 +12,9 @@
<description>Contains common components shared by Emby Theater and Emby Server. Not intended for plugin developer consumption.</description>
<copyright>Copyright © Emby 2013</copyright>
<dependencies>
- <dependency id="MediaBrowser.Common" version="3.0.647" />
- <dependency id="NLog" version="4.3.1" />
- <dependency id="SimpleInjector" version="3.1.3" />
+ <dependency id="MediaBrowser.Common" version="3.0.648" />
+ <dependency id="NLog" version="4.3.4" />
+ <dependency id="SimpleInjector" version="3.1.4" />
</dependencies>
</metadata>
<files>
diff --git a/Nuget/MediaBrowser.Common.nuspec b/Nuget/MediaBrowser.Common.nuspec
index f0f6320f02..d129848697 100644
--- a/Nuget/MediaBrowser.Common.nuspec
+++ b/Nuget/MediaBrowser.Common.nuspec
@@ -2,7 +2,7 @@
<package xmlns="http://schemas.microsoft.com/packaging/2011/08/nuspec.xsd">
<metadata>
<id>MediaBrowser.Common</id>
- <version>3.0.647</version>
+ <version>3.0.648</version>
<title>MediaBrowser.Common</title>
<authors>Emby Team</authors>
<owners>ebr,Luke,scottisafool</owners>
diff --git a/Nuget/MediaBrowser.Model.Signed.nuspec b/Nuget/MediaBrowser.Model.Signed.nuspec
deleted file mode 100644
index 6c47b62eb1..0000000000
--- a/Nuget/MediaBrowser.Model.Signed.nuspec
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<package xmlns="http://schemas.microsoft.com/packaging/2011/08/nuspec.xsd">
- <metadata>
- <id>MediaBrowser.Model.Signed</id>
- <version>3.0.647</version>
- <title>MediaBrowser.Model - Signed Edition</title>
- <authors>Emby Team</authors>
- <owners>ebr,Luke,scottisafool</owners>
- <projectUrl>https://github.com/MediaBrowser/MediaBrowser</projectUrl>
- <iconUrl>http://www.mb3admin.com/images/mb3icons1-1.png</iconUrl>
- <requireLicenseAcceptance>false</requireLicenseAcceptance>
- <description>Contains common model objects and interfaces used by all Emby solutions.</description>
- <copyright>Copyright © Emby 2013</copyright>
- <dependencies>
- </dependencies>
- </metadata>
- <files>
- <file src="dllssigned\net45\MediaBrowser.Model.dll" target="lib\net45\MediaBrowser.Model.dll" />
- </files>
-</package> \ No newline at end of file
diff --git a/Nuget/MediaBrowser.Server.Core.nuspec b/Nuget/MediaBrowser.Server.Core.nuspec
index 8060298caa..a9caab74cd 100644
--- a/Nuget/MediaBrowser.Server.Core.nuspec
+++ b/Nuget/MediaBrowser.Server.Core.nuspec
@@ -2,7 +2,7 @@
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
<metadata>
<id>MediaBrowser.Server.Core</id>
- <version>3.0.647</version>
+ <version>3.0.648</version>
<title>Media Browser.Server.Core</title>
<authors>Emby Team</authors>
<owners>ebr,Luke,scottisafool</owners>
@@ -12,7 +12,7 @@
<description>Contains core components required to build plugins for Emby Server.</description>
<copyright>Copyright © Emby 2013</copyright>
<dependencies>
- <dependency id="MediaBrowser.Common" version="3.0.647" />
+ <dependency id="MediaBrowser.Common" version="3.0.648" />
<dependency id="Interfaces.IO" version="1.0.0.5" />
</dependencies>
</metadata>