diff options
| author | Luke Pulverenti <luke.pulverenti@gmail.com> | 2016-05-21 00:49:17 -0400 |
|---|---|---|
| committer | Luke Pulverenti <luke.pulverenti@gmail.com> | 2016-05-21 00:49:17 -0400 |
| commit | b253d26abadc782c5bddc5ac5352ebe116154553 (patch) | |
| tree | e2648ab8fc6106aa0a3218cd2ce49a93a9ecb1da /MediaBrowser.Server.Implementations | |
| parent | a49a905ca2e00753d3658b0a4244374dbcfbed48 (diff) | |
| parent | 7596365af2fa819d440e1ae65befea88aec29bde (diff) | |
Merge branch 'beta'
Diffstat (limited to 'MediaBrowser.Server.Implementations')
7 files changed, 215 insertions, 38 deletions
diff --git a/MediaBrowser.Server.Implementations/Library/LibraryManager.cs b/MediaBrowser.Server.Implementations/Library/LibraryManager.cs index 1407cdce3..56d3bd4de 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 c82c4cdf7..ef13ba996 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 2de51479f..de75aac9c 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 9251ccb9e..91f84e2fe 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 aff3a5e16..0aa499f69 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 e04c87917..7f45e6184 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 dce839b57..b877d41a8 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 |
