From 15f0832a042ef77bee549958fcf130986af9f430 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sat, 21 May 2016 02:12:00 -0400 Subject: deprecate refreshinfo db --- .../Library/LibraryManager.cs | 2 +- .../MediaBrowser.Server.Implementations.csproj | 1 - .../Persistence/SqliteItemRepository.cs | 44 ---- .../Persistence/SqliteProviderInfoRepository.cs | 248 --------------------- 4 files changed, 1 insertion(+), 294 deletions(-) delete mode 100644 MediaBrowser.Server.Implementations/Persistence/SqliteProviderInfoRepository.cs (limited to 'MediaBrowser.Server.Implementations') diff --git a/MediaBrowser.Server.Implementations/Library/LibraryManager.cs b/MediaBrowser.Server.Implementations/Library/LibraryManager.cs index 56d3bd4de..961819f0d 100644 --- a/MediaBrowser.Server.Implementations/Library/LibraryManager.cs +++ b/MediaBrowser.Server.Implementations/Library/LibraryManager.cs @@ -502,7 +502,7 @@ namespace MediaBrowser.Server.Implementations.Library throw new ArgumentNullException("type"); } - if (ConfigurationManager.Configuration.EnableLocalizedGuids && key.StartsWith(ConfigurationManager.ApplicationPaths.ProgramDataPath)) + if (key.StartsWith(ConfigurationManager.ApplicationPaths.ProgramDataPath)) { // Try to normalize paths located underneath program-data in an attempt to make them more portable key = key.Substring(ConfigurationManager.ApplicationPaths.ProgramDataPath.Length) diff --git a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj index 0aa499f69..c65ae7f8a 100644 --- a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj +++ b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj @@ -276,7 +276,6 @@ - diff --git a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs index 7f45e6184..c5e4fcd07 100644 --- a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs +++ b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs @@ -254,53 +254,9 @@ namespace MediaBrowser.Server.Implementations.Persistence new MediaStreamColumns(_connection, Logger).AddColumns(); - var mediaStreamsDbFile = Path.Combine(_config.ApplicationPaths.DataPath, "mediainfo.db"); - if (File.Exists(mediaStreamsDbFile)) - { - MigrateMediaStreams(mediaStreamsDbFile); - } - DataExtensions.Attach(_connection, Path.Combine(_config.ApplicationPaths.DataPath, "userdata_v2.db"), "UserDataDb"); } - private void MigrateMediaStreams(string file) - { - try - { - var backupFile = file + ".bak"; - File.Copy(file, backupFile, true); - DataExtensions.Attach(_connection, backupFile, "MediaInfoOld"); - - var columns = string.Join(",", _mediaStreamSaveColumns); - - string[] queries = { - "REPLACE INTO mediastreams("+columns+") SELECT "+columns+" FROM MediaInfoOld.mediastreams;" - }; - - _connection.RunQueries(queries, Logger); - } - catch (Exception ex) - { - Logger.ErrorException("Error migrating media info database", ex); - } - finally - { - TryDeleteFile(file); - } - } - - private void TryDeleteFile(string file) - { - try - { - File.Delete(file); - } - catch (Exception ex) - { - Logger.ErrorException("Error deleting file {0}", ex, file); - } - } - private readonly string[] _retriveItemColumns = { "type", diff --git a/MediaBrowser.Server.Implementations/Persistence/SqliteProviderInfoRepository.cs b/MediaBrowser.Server.Implementations/Persistence/SqliteProviderInfoRepository.cs deleted file mode 100644 index 40d5c9586..000000000 --- a/MediaBrowser.Server.Implementations/Persistence/SqliteProviderInfoRepository.cs +++ /dev/null @@ -1,248 +0,0 @@ -using MediaBrowser.Common.Configuration; -using MediaBrowser.Controller.Providers; -using MediaBrowser.Model.Logging; -using System; -using System.Data; -using System.IO; -using System.Linq; -using System.Text; -using System.Threading; -using System.Threading.Tasks; - -namespace MediaBrowser.Server.Implementations.Persistence -{ - public class SqliteProviderInfoRepository : BaseSqliteRepository, IProviderRepository - { - private IDbConnection _connection; - - private IDbCommand _saveStatusCommand; - private readonly IApplicationPaths _appPaths; - - public SqliteProviderInfoRepository(ILogManager logManager, IApplicationPaths appPaths) : base(logManager) - { - _appPaths = appPaths; - } - - /// - /// Gets the name of the repository - /// - /// The name. - public string Name - { - get - { - return "SQLite"; - } - } - - /// - /// Opens the connection to the database - /// - /// Task. - public async Task Initialize(IDbConnector dbConnector) - { - var dbFile = Path.Combine(_appPaths.DataPath, "refreshinfo.db"); - - _connection = await dbConnector.Connect(dbFile).ConfigureAwait(false); - - string[] queries = { - - "create table if not exists MetadataStatus (ItemId GUID PRIMARY KEY, DateLastMetadataRefresh datetime, DateLastImagesRefresh datetime, ItemDateModified DateTimeNull)", - "create index if not exists idx_MetadataStatus on MetadataStatus(ItemId)", - - //pragmas - "pragma temp_store = memory", - - "pragma shrink_memory" - }; - - _connection.RunQueries(queries, Logger); - - AddItemDateModifiedCommand(); - - PrepareStatements(); - } - - private static readonly string[] StatusColumns = - { - "ItemId", - "DateLastMetadataRefresh", - "DateLastImagesRefresh", - "ItemDateModified" - }; - - private void AddItemDateModifiedCommand() - { - using (var cmd = _connection.CreateCommand()) - { - cmd.CommandText = "PRAGMA table_info(MetadataStatus)"; - - using (var reader = cmd.ExecuteReader(CommandBehavior.SequentialAccess | CommandBehavior.SingleResult)) - { - while (reader.Read()) - { - if (!reader.IsDBNull(1)) - { - var name = reader.GetString(1); - - if (string.Equals(name, "ItemDateModified", StringComparison.OrdinalIgnoreCase)) - { - return; - } - } - } - } - } - - var builder = new StringBuilder(); - - builder.AppendLine("alter table MetadataStatus"); - builder.AppendLine("add column ItemDateModified DateTime NULL"); - - _connection.RunQueries(new[] { builder.ToString() }, Logger); - } - - /// - /// Prepares the statements. - /// - private void PrepareStatements() - { - _saveStatusCommand = _connection.CreateCommand(); - - _saveStatusCommand.CommandText = string.Format("replace into MetadataStatus ({0}) values ({1})", - string.Join(",", StatusColumns), - string.Join(",", StatusColumns.Select(i => "@" + i).ToArray())); - - foreach (var col in StatusColumns) - { - _saveStatusCommand.Parameters.Add(_saveStatusCommand, "@" + col); - } - } - - public MetadataStatus GetMetadataStatus(Guid itemId) - { - if (itemId == Guid.Empty) - { - throw new ArgumentNullException("itemId"); - } - - using (var cmd = _connection.CreateCommand()) - { - var cmdText = "select " + string.Join(",", StatusColumns) + " from MetadataStatus where"; - - cmdText += " ItemId=@ItemId"; - cmd.Parameters.Add(cmd, "@ItemId", DbType.Guid).Value = itemId; - - cmd.CommandText = cmdText; - - using (var reader = cmd.ExecuteReader(CommandBehavior.SequentialAccess | CommandBehavior.SingleResult | CommandBehavior.SingleRow)) - { - while (reader.Read()) - { - return GetStatus(reader); - } - - return null; - } - } - } - - private MetadataStatus GetStatus(IDataReader reader) - { - var result = new MetadataStatus - { - ItemId = reader.GetGuid(0) - }; - - if (!reader.IsDBNull(1)) - { - result.DateLastMetadataRefresh = reader.GetDateTime(1).ToUniversalTime(); - } - - if (!reader.IsDBNull(2)) - { - result.DateLastImagesRefresh = reader.GetDateTime(2).ToUniversalTime(); - } - - if (!reader.IsDBNull(3)) - { - result.ItemDateModified = reader.GetDateTime(3).ToUniversalTime(); - } - - return result; - } - - public async Task SaveMetadataStatus(MetadataStatus status, CancellationToken cancellationToken) - { - if (status == null) - { - throw new ArgumentNullException("status"); - } - - cancellationToken.ThrowIfCancellationRequested(); - - await WriteLock.WaitAsync(cancellationToken).ConfigureAwait(false); - - IDbTransaction transaction = null; - - try - { - transaction = _connection.BeginTransaction(); - - _saveStatusCommand.GetParameter(0).Value = status.ItemId; - _saveStatusCommand.GetParameter(1).Value = status.DateLastMetadataRefresh; - _saveStatusCommand.GetParameter(2).Value = status.DateLastImagesRefresh; - _saveStatusCommand.GetParameter(3).Value = status.ItemDateModified; - - _saveStatusCommand.Transaction = transaction; - - _saveStatusCommand.ExecuteNonQuery(); - - transaction.Commit(); - } - catch (OperationCanceledException) - { - if (transaction != null) - { - transaction.Rollback(); - } - - throw; - } - catch (Exception e) - { - Logger.ErrorException("Failed to save provider info:", e); - - if (transaction != null) - { - transaction.Rollback(); - } - - throw; - } - finally - { - if (transaction != null) - { - transaction.Dispose(); - } - - WriteLock.Release(); - } - } - - protected override void CloseConnection() - { - if (_connection != null) - { - if (_connection.IsOpen()) - { - _connection.Close(); - } - - _connection.Dispose(); - _connection = null; - } - } - } -} -- cgit v1.2.3 From bfcbbde808f4361b270986977f640f65c121eceb Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sun, 22 May 2016 12:47:22 -0400 Subject: update recording probe size --- MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EncodedRecorder.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'MediaBrowser.Server.Implementations') diff --git a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EncodedRecorder.cs b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EncodedRecorder.cs index e9ea49fa3..0752d4132 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EncodedRecorder.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EncodedRecorder.cs @@ -145,7 +145,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV videoArgs = "-codec:v:0 copy"; } - var commandLineArgs = "-fflags +genpts -async 1 -vsync -1 -i \"{0}\" -t {4} -sn {2} -map_metadata -1 -threads 0 {3} -y \"{1}\""; + var commandLineArgs = "-probesize 1G -analyzeduration 200M -fflags +genpts -async 1 -vsync -1 -i \"{0}\" -t {4} -sn {2} -map_metadata -1 -threads 0 {3} -y \"{1}\""; if (mediaSource.ReadAtNativeFramerate) { -- cgit v1.2.3 From 04302136f3a6052ff744b54054520372b4dce4fe Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sun, 22 May 2016 13:07:30 -0400 Subject: update recording folder generation --- .../LiveTv/EmbyTV/EmbyTV.cs | 16 +++++++++++++--- .../LiveTv/LiveTvManager.cs | 2 ++ .../MediaBrowser.WebDashboard.csproj | 6 ------ 3 files changed, 15 insertions(+), 9 deletions(-) (limited to 'MediaBrowser.Server.Implementations') diff --git a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs index de75aac9c..248c3bf3b 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs @@ -102,8 +102,6 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV _timerProvider.RestartTimers(); SystemEvents.PowerModeChanged += SystemEvents_PowerModeChanged; - - CreateRecordingFolders(); } private void OnRecordingFoldersChanged() @@ -111,7 +109,19 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV CreateRecordingFolders(); } - private void CreateRecordingFolders() + internal void CreateRecordingFolders() + { + try + { + CreateRecordingFoldersInternal(); + } + catch (Exception ex) + { + _logger.ErrorException("Error creating recording folders", ex); + } + } + + internal void CreateRecordingFoldersInternal() { var recordingFolders = GetRecordingFolders(); diff --git a/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs b/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs index 91f84e2fe..a35a7c940 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs @@ -1126,6 +1126,8 @@ namespace MediaBrowser.Server.Implementations.LiveTv private async Task RefreshChannelsInternal(IProgress progress, CancellationToken cancellationToken) { + EmbyTV.EmbyTV.Current.CreateRecordingFolders(); + var numComplete = 0; double progressPerService = _services.Count == 0 ? 0 diff --git a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj index 1901108af..9967a3cdf 100644 --- a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj +++ b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj @@ -215,9 +215,6 @@ PreserveNewest - - PreserveNewest - PreserveNewest @@ -935,9 +932,6 @@ PreserveNewest - - PreserveNewest - PreserveNewest -- cgit v1.2.3 From e5049f92b4ea4f67ea1406888269c0093ff193ae Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sun, 22 May 2016 14:53:37 -0400 Subject: remove schema version checks --- .../Entities/Audio/MusicArtist.cs | 7 -- MediaBrowser.Controller/Entities/Folder.cs | 87 ---------------------- .../Persistence/SqliteItemRepository.cs | 49 +++--------- 3 files changed, 11 insertions(+), 132 deletions(-) (limited to 'MediaBrowser.Server.Implementations') diff --git a/MediaBrowser.Controller/Entities/Audio/MusicArtist.cs b/MediaBrowser.Controller/Entities/Audio/MusicArtist.cs index 02dad93cb..c1743c749 100644 --- a/MediaBrowser.Controller/Entities/Audio/MusicArtist.cs +++ b/MediaBrowser.Controller/Entities/Audio/MusicArtist.cs @@ -62,13 +62,6 @@ namespace MediaBrowser.Controller.Entities.Audio query.ArtistNames = new[] { Name }; } - // Need this for now since the artist filter isn't yet supported by the db - if (ConfigurationManager.Configuration.SchemaVersion < 79) - { - var filter = GetItemFilter(); - return LibraryManager.GetItemList(query).Where(filter); - } - return LibraryManager.GetItemList(query); } diff --git a/MediaBrowser.Controller/Entities/Folder.cs b/MediaBrowser.Controller/Entities/Folder.cs index e7b1df55a..ac49dc3b2 100644 --- a/MediaBrowser.Controller/Entities/Folder.cs +++ b/MediaBrowser.Controller/Entities/Folder.cs @@ -773,53 +773,8 @@ namespace MediaBrowser.Controller.Entities } } - var supportsUserDataQueries = ConfigurationManager.Configuration.SchemaVersion >= 76; - if (query.SortBy != null && query.SortBy.Length > 0) { - if (!supportsUserDataQueries) - { - if (query.SortBy.Contains(ItemSortBy.DatePlayed, StringComparer.OrdinalIgnoreCase)) - { - Logger.Debug("Query requires post-filtering due to ItemSortBy.IsFavoriteOrLiked"); - return true; - } - if (query.SortBy.Contains(ItemSortBy.PlayCount, StringComparer.OrdinalIgnoreCase)) - { - Logger.Debug("Query requires post-filtering due to ItemSortBy.PlayCount"); - return true; - } - if (query.SortBy.Contains(ItemSortBy.IsFavoriteOrLiked, StringComparer.OrdinalIgnoreCase)) - { - Logger.Debug("Query requires post-filtering due to ItemSortBy.IsFavoriteOrLiked"); - return true; - } - if (query.SortBy.Contains(ItemSortBy.IsPlayed, StringComparer.OrdinalIgnoreCase)) - { - Logger.Debug("Query requires post-filtering due to ItemSortBy.IsPlayed"); - return true; - } - if (query.SortBy.Contains(ItemSortBy.IsUnplayed, StringComparer.OrdinalIgnoreCase)) - { - Logger.Debug("Query requires post-filtering due to ItemSortBy.IsUnplayed"); - return true; - } - } - - if (ConfigurationManager.Configuration.SchemaVersion < 79) - { - 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.AiredEpisodeOrder, StringComparer.OrdinalIgnoreCase)) { Logger.Debug("Query requires post-filtering due to ItemSortBy.AiredEpisodeOrder"); @@ -884,39 +839,6 @@ namespace MediaBrowser.Controller.Entities return true; } - if (!supportsUserDataQueries) - { - if (query.IsLiked.HasValue) - { - Logger.Debug("Query requires post-filtering due to IsLiked"); - return true; - } - - if (query.IsFavoriteOrLiked.HasValue) - { - Logger.Debug("Query requires post-filtering due to IsFavoriteOrLiked"); - return true; - } - - if (query.IsFavorite.HasValue) - { - Logger.Debug("Query requires post-filtering due to IsFavorite"); - return true; - } - - if (query.IsResumable.HasValue) - { - Logger.Debug("Query requires post-filtering due to IsResumable"); - return true; - } - - if (query.IsPlayed.HasValue) - { - Logger.Debug("Query requires post-filtering due to IsPlayed"); - return true; - } - } - if (query.IsInBoxSet.HasValue) { Logger.Debug("Query requires post-filtering due to IsInBoxSet"); @@ -1102,15 +1024,6 @@ namespace MediaBrowser.Controller.Entities return true; } - if (ConfigurationManager.Configuration.SchemaVersion < 79) - { - if (query.ArtistNames.Length > 0) - { - Logger.Debug("Query requires post-filtering due to ArtistNames"); - return true; - } - } - return false; } diff --git a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs index c5e4fcd07..19f9653a8 100644 --- a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs +++ b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs @@ -1504,11 +1504,6 @@ namespace MediaBrowser.Server.Implementations.Persistence private bool EnableJoinUserData(InternalItemsQuery query) { - if (_config.Configuration.SchemaVersion < 76) - { - return false; - } - if (query.User == null) { return false; @@ -1623,7 +1618,7 @@ namespace MediaBrowser.Server.Implementations.Persistence cmd.CommandText += whereText; - if (EnableGroupByPresentationUniqueKey(query) && _config.Configuration.SchemaVersion >= 66) + if (EnableGroupByPresentationUniqueKey(query)) { cmd.CommandText += " Group by PresentationUniqueKey"; } @@ -1711,7 +1706,7 @@ namespace MediaBrowser.Server.Implementations.Persistence cmd.CommandText += whereText; - if (EnableGroupByPresentationUniqueKey(query) && _config.Configuration.SchemaVersion >= 66) + if (EnableGroupByPresentationUniqueKey(query)) { cmd.CommandText += " Group by PresentationUniqueKey"; } @@ -1730,7 +1725,7 @@ namespace MediaBrowser.Server.Implementations.Persistence } } - if (EnableGroupByPresentationUniqueKey(query) && _config.Configuration.SchemaVersion >= 66) + if (EnableGroupByPresentationUniqueKey(query)) { cmd.CommandText += "; select count (distinct PresentationUniqueKey) from TypedBaseItems"; } @@ -1880,7 +1875,7 @@ namespace MediaBrowser.Server.Implementations.Persistence cmd.CommandText += whereText; - if (EnableGroupByPresentationUniqueKey(query) && _config.Configuration.SchemaVersion >= 66) + if (EnableGroupByPresentationUniqueKey(query)) { cmd.CommandText += " Group by PresentationUniqueKey"; } @@ -1940,7 +1935,7 @@ namespace MediaBrowser.Server.Implementations.Persistence cmd.CommandText += whereText; - if (EnableGroupByPresentationUniqueKey(query) && _config.Configuration.SchemaVersion >= 66) + if (EnableGroupByPresentationUniqueKey(query)) { cmd.CommandText += " Group by PresentationUniqueKey"; } @@ -2023,7 +2018,7 @@ namespace MediaBrowser.Server.Implementations.Persistence cmd.CommandText += whereText; - if (EnableGroupByPresentationUniqueKey(query) && _config.Configuration.SchemaVersion >= 66) + if (EnableGroupByPresentationUniqueKey(query)) { cmd.CommandText += " Group by PresentationUniqueKey"; } @@ -2042,7 +2037,7 @@ namespace MediaBrowser.Server.Implementations.Persistence } } - if (EnableGroupByPresentationUniqueKey(query) && _config.Configuration.SchemaVersion >= 66) + if (EnableGroupByPresentationUniqueKey(query)) { cmd.CommandText += "; select count (distinct PresentationUniqueKey) from TypedBaseItems"; } @@ -2319,41 +2314,19 @@ namespace MediaBrowser.Server.Implementations.Persistence if (!string.IsNullOrWhiteSpace(query.SlugName)) { - if (_config.Configuration.SchemaVersion >= 70) - { - whereClauses.Add("SlugName=@SlugName"); - } - else - { - whereClauses.Add("Name=@SlugName"); - } + whereClauses.Add("SlugName=@SlugName"); cmd.Parameters.Add(cmd, "@SlugName", DbType.String).Value = query.SlugName; } if (!string.IsNullOrWhiteSpace(query.Name)) { - if (_config.Configuration.SchemaVersion >= 66) - { - whereClauses.Add("CleanName=@Name"); - cmd.Parameters.Add(cmd, "@Name", DbType.String).Value = query.Name.RemoveDiacritics(); - } - else - { - whereClauses.Add("Name=@Name"); - cmd.Parameters.Add(cmd, "@Name", DbType.String).Value = query.Name; - } + whereClauses.Add("CleanName=@Name"); + cmd.Parameters.Add(cmd, "@Name", DbType.String).Value = query.Name.RemoveDiacritics(); } if (!string.IsNullOrWhiteSpace(query.NameContains)) { - if (_config.Configuration.SchemaVersion >= 66) - { - whereClauses.Add("CleanName like @NameContains"); - } - else - { - whereClauses.Add("Name like @NameContains"); - } + whereClauses.Add("CleanName like @NameContains"); cmd.Parameters.Add(cmd, "@NameContains", DbType.String).Value = "%" + query.NameContains.RemoveDiacritics() + "%"; } if (!string.IsNullOrWhiteSpace(query.NameStartsWith)) -- cgit v1.2.3 From acd2defbf7161077c430518cb41782f5771f3282 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sun, 22 May 2016 18:37:50 -0400 Subject: handle flat tv folders --- MediaBrowser.Model/ApiClient/ServerCredentials.cs | 4 ++ MediaBrowser.Model/ApiClient/ServerInfo.cs | 1 + .../Dto/DtoService.cs | 69 +++++++++++----------- .../Library/Resolvers/TV/EpisodeResolver.cs | 8 ++- .../MediaBrowser.WebDashboard.csproj | 3 + 5 files changed, 47 insertions(+), 38 deletions(-) (limited to 'MediaBrowser.Server.Implementations') diff --git a/MediaBrowser.Model/ApiClient/ServerCredentials.cs b/MediaBrowser.Model/ApiClient/ServerCredentials.cs index 0f0ab65d4..19f68445e 100644 --- a/MediaBrowser.Model/ApiClient/ServerCredentials.cs +++ b/MediaBrowser.Model/ApiClient/ServerCredentials.cs @@ -57,6 +57,10 @@ namespace MediaBrowser.Model.ApiClient { existing.RemoteAddress = server.RemoteAddress; } + if (!string.IsNullOrEmpty(server.ConnectServerId)) + { + existing.ConnectServerId = server.ConnectServerId; + } if (!string.IsNullOrEmpty(server.LocalAddress)) { existing.LocalAddress = server.LocalAddress; diff --git a/MediaBrowser.Model/ApiClient/ServerInfo.cs b/MediaBrowser.Model/ApiClient/ServerInfo.cs index e1fa581d7..48995e80a 100644 --- a/MediaBrowser.Model/ApiClient/ServerInfo.cs +++ b/MediaBrowser.Model/ApiClient/ServerInfo.cs @@ -12,6 +12,7 @@ namespace MediaBrowser.Model.ApiClient public String Name { get; set; } public String Id { get; set; } + public String ConnectServerId { get; set; } public String LocalAddress { get; set; } public String RemoteAddress { get; set; } public String ManualAddress { get; set; } diff --git a/MediaBrowser.Server.Implementations/Dto/DtoService.cs b/MediaBrowser.Server.Implementations/Dto/DtoService.cs index dfbac47d5..eb868d363 100644 --- a/MediaBrowser.Server.Implementations/Dto/DtoService.cs +++ b/MediaBrowser.Server.Implementations/Dto/DtoService.cs @@ -1412,6 +1412,7 @@ namespace MediaBrowser.Server.Implementations.Dto if (episode != null) { dto.IndexNumberEnd = episode.IndexNumberEnd; + dto.SeriesName = episode.SeriesName; if (fields.Contains(ItemFields.AlternateEpisodeNumbers)) { @@ -1427,74 +1428,70 @@ namespace MediaBrowser.Server.Implementations.Dto dto.AirsBeforeSeasonNumber = episode.AirsBeforeSeasonNumber; } + var seasonId = episode.SeasonId; + if (seasonId.HasValue) + { + dto.SeasonId = seasonId.Value.ToString("N"); + } + var episodeSeason = episode.Season; if (episodeSeason != null) { - dto.SeasonId = episodeSeason.Id.ToString("N"); - if (fields.Contains(ItemFields.SeasonName)) { dto.SeasonName = episodeSeason.Name; } } - if (fields.Contains(ItemFields.SeriesGenres)) + var episodeSeries = episode.Series; + + if (episodeSeries != null) { - var episodeseries = episode.Series; - if (episodeseries != null) + if (fields.Contains(ItemFields.SeriesGenres)) { - dto.SeriesGenres = episodeseries.Genres.ToList(); + dto.SeriesGenres = episodeSeries.Genres.ToList(); } - } - } - - // Add SeriesInfo - var series = item as Series; - if (series != null) - { - dto.AirDays = series.AirDays; - dto.AirTime = series.AirTime; - dto.SeriesStatus = series.Status; - - if (fields.Contains(ItemFields.Settings)) - { - dto.DisplaySpecialsWithSeasons = series.DisplaySpecialsWithSeasons; - } - dto.AnimeSeriesIndex = series.AnimeSeriesIndex; - } - - if (episode != null) - { - series = episode.Series; - - if (series != null) - { - dto.SeriesId = GetDtoId(series); - dto.SeriesName = series.Name; + dto.SeriesId = GetDtoId(episodeSeries); if (fields.Contains(ItemFields.AirTime)) { - dto.AirTime = series.AirTime; + dto.AirTime = episodeSeries.AirTime; } if (options.GetImageLimit(ImageType.Thumb) > 0) { - dto.SeriesThumbImageTag = GetImageCacheTag(series, ImageType.Thumb); + dto.SeriesThumbImageTag = GetImageCacheTag(episodeSeries, ImageType.Thumb); } if (options.GetImageLimit(ImageType.Primary) > 0) { - dto.SeriesPrimaryImageTag = GetImageCacheTag(series, ImageType.Primary); + dto.SeriesPrimaryImageTag = GetImageCacheTag(episodeSeries, ImageType.Primary); } if (fields.Contains(ItemFields.SeriesStudio)) { - dto.SeriesStudio = series.Studios.FirstOrDefault(); + dto.SeriesStudio = episodeSeries.Studios.FirstOrDefault(); } } } + // Add SeriesInfo + var series = item as Series; + if (series != null) + { + dto.AirDays = series.AirDays; + dto.AirTime = series.AirTime; + dto.SeriesStatus = series.Status; + + if (fields.Contains(ItemFields.Settings)) + { + dto.DisplaySpecialsWithSeasons = series.DisplaySpecialsWithSeasons; + } + + dto.AnimeSeriesIndex = series.AnimeSeriesIndex; + } + // Add SeasonInfo var season = item as Season; if (season != null) diff --git a/MediaBrowser.Server.Implementations/Library/Resolvers/TV/EpisodeResolver.cs b/MediaBrowser.Server.Implementations/Library/Resolvers/TV/EpisodeResolver.cs index e62049821..14e5e446b 100644 --- a/MediaBrowser.Server.Implementations/Library/Resolvers/TV/EpisodeResolver.cs +++ b/MediaBrowser.Server.Implementations/Library/Resolvers/TV/EpisodeResolver.cs @@ -1,6 +1,9 @@ -using MediaBrowser.Controller.Entities.TV; +using System; +using System.IO; +using MediaBrowser.Controller.Entities.TV; using MediaBrowser.Controller.Library; using System.Linq; +using MediaBrowser.Model.Entities; namespace MediaBrowser.Server.Implementations.Library.Resolvers.TV { @@ -37,7 +40,8 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers.TV } // If the parent is a Season or Series, then this is an Episode if the VideoResolver returns something - if (season != null || args.HasParent()) + // Also handle flat tv folders + if (season != null || args.HasParent() || string.Equals(args.GetCollectionType(), CollectionType.TvShows, StringComparison.OrdinalIgnoreCase)) { var episode = ResolveVideo(args, false); diff --git a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj index 8e1f8c773..761e5ae6e 100644 --- a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj +++ b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj @@ -356,6 +356,9 @@ PreserveNewest + + PreserveNewest + PreserveNewest -- cgit v1.2.3 From 1c28dcc78bcd9b1a74418e82c169251cac2eb2d2 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sun, 22 May 2016 23:55:00 -0400 Subject: update user config --- MediaBrowser.Model/Configuration/UserConfiguration.cs | 1 - MediaBrowser.Server.Implementations/Library/UserViewManager.cs | 6 ------ 2 files changed, 7 deletions(-) (limited to 'MediaBrowser.Server.Implementations') diff --git a/MediaBrowser.Model/Configuration/UserConfiguration.cs b/MediaBrowser.Model/Configuration/UserConfiguration.cs index 5f42dd2de..062c4674e 100644 --- a/MediaBrowser.Model/Configuration/UserConfiguration.cs +++ b/MediaBrowser.Model/Configuration/UserConfiguration.cs @@ -34,7 +34,6 @@ namespace MediaBrowser.Model.Configuration public SubtitlePlaybackMode SubtitleMode { get; set; } public bool DisplayCollectionsView { get; set; } - public bool DisplayFoldersView { get; set; } public bool EnableLocalPassword { get; set; } diff --git a/MediaBrowser.Server.Implementations/Library/UserViewManager.cs b/MediaBrowser.Server.Implementations/Library/UserViewManager.cs index 1bba20ec5..6c88f506b 100644 --- a/MediaBrowser.Server.Implementations/Library/UserViewManager.cs +++ b/MediaBrowser.Server.Implementations/Library/UserViewManager.cs @@ -105,12 +105,6 @@ namespace MediaBrowser.Server.Implementations.Library } } - if (user.Configuration.DisplayFoldersView) - { - var name = _localizationManager.GetLocalizedString("ViewType" + CollectionType.Folders); - list.Add(await _libraryManager.GetNamedView(name, CollectionType.Folders, string.Empty, cancellationToken).ConfigureAwait(false)); - } - if (query.IncludeExternalContent) { var channelResult = await _channelManager.GetChannelsInternal(new ChannelQuery -- cgit v1.2.3 From bc2f18bce37794b6968e19f13ca69eb109ec7c03 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Mon, 23 May 2016 00:11:37 -0400 Subject: save series name separately --- MediaBrowser.Model/Configuration/ServerConfiguration.cs | 1 - .../Persistence/SqliteItemRepository.cs | 16 ++++++++++++++-- 2 files changed, 14 insertions(+), 3 deletions(-) (limited to 'MediaBrowser.Server.Implementations') diff --git a/MediaBrowser.Model/Configuration/ServerConfiguration.cs b/MediaBrowser.Model/Configuration/ServerConfiguration.cs index e9084d4d1..66bea95bb 100644 --- a/MediaBrowser.Model/Configuration/ServerConfiguration.cs +++ b/MediaBrowser.Model/Configuration/ServerConfiguration.cs @@ -223,7 +223,6 @@ namespace MediaBrowser.Model.Configuration DenyIFrameEmbedding = true; EnableUPnP = true; - SchemaVersion = 79; SharingExpirationDays = 30; MinResumePct = 5; MaxResumePct = 90; diff --git a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs index 19f9653a8..7e2cc2da3 100644 --- a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs +++ b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs @@ -87,7 +87,7 @@ namespace MediaBrowser.Server.Implementations.Persistence private IDbCommand _updateInheritedRatingCommand; private IDbCommand _updateInheritedTagsCommand; - public const int LatestSchemaVersion = 79; + public const int LatestSchemaVersion = 80; /// /// Initializes a new instance of the class. @@ -239,6 +239,7 @@ namespace MediaBrowser.Server.Implementations.Persistence _connection.AddColumn(Logger, "TypedBaseItems", "DateLastMediaAdded", "DATETIME"); _connection.AddColumn(Logger, "TypedBaseItems", "Album", "Text"); _connection.AddColumn(Logger, "TypedBaseItems", "IsVirtualItem", "BIT"); + _connection.AddColumn(Logger, "TypedBaseItems", "SeriesName", "Text"); _connection.AddColumn(Logger, "UserDataKeys", "Priority", "INT"); @@ -433,7 +434,8 @@ namespace MediaBrowser.Server.Implementations.Persistence "PrimaryVersionId", "DateLastMediaAdded", "Album", - "IsVirtualItem" + "IsVirtualItem", + "SeriesName" }; _saveItemCommand = _connection.CreateCommand(); _saveItemCommand.CommandText = "replace into TypedBaseItems (" + string.Join(",", saveColumns.ToArray()) + ") values ("; @@ -835,6 +837,16 @@ namespace MediaBrowser.Server.Implementations.Persistence _saveItemCommand.GetParameter(index++).Value = null; } + var hasSeries = item as IHasSeries; + if (hasSeries != null) + { + _saveItemCommand.GetParameter(index++).Value = hasSeries.SeriesName; + } + else + { + _saveItemCommand.GetParameter(index++).Value = null; + } + _saveItemCommand.Transaction = transaction; _saveItemCommand.ExecuteNonQuery(); -- cgit v1.2.3 From 91aab66857330b6e2445a4fb1d9f0d42952bec03 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Mon, 23 May 2016 00:47:02 -0400 Subject: create recording folders on start --- MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs | 1 + 1 file changed, 1 insertion(+) (limited to 'MediaBrowser.Server.Implementations') diff --git a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs index 248c3bf3b..205000fdc 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs @@ -102,6 +102,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV _timerProvider.RestartTimers(); SystemEvents.PowerModeChanged += SystemEvents_PowerModeChanged; + CreateRecordingFolders(); } private void OnRecordingFoldersChanged() -- cgit v1.2.3 From 4fcdeaffee6d3a8775850c2babd719dec5f621ff Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Mon, 23 May 2016 13:52:16 -0400 Subject: restore localized guids config switch --- MediaBrowser.Api/StartupWizardService.cs | 1 + MediaBrowser.Model/Configuration/ServerConfiguration.cs | 2 ++ MediaBrowser.Server.Implementations/Library/LibraryManager.cs | 2 +- 3 files changed, 4 insertions(+), 1 deletion(-) (limited to 'MediaBrowser.Server.Implementations') diff --git a/MediaBrowser.Api/StartupWizardService.cs b/MediaBrowser.Api/StartupWizardService.cs index cdc00a9aa..8bb840697 100644 --- a/MediaBrowser.Api/StartupWizardService.cs +++ b/MediaBrowser.Api/StartupWizardService.cs @@ -109,6 +109,7 @@ namespace MediaBrowser.Api private void SetWizardFinishValues(ServerConfiguration config) { + config.EnableLocalizedGuids = true; config.EnableCustomPathSubFolders = true; config.EnableStandaloneMusicKeys = true; config.EnableCaseSensitiveItemIds = true; diff --git a/MediaBrowser.Model/Configuration/ServerConfiguration.cs b/MediaBrowser.Model/Configuration/ServerConfiguration.cs index 66bea95bb..1971b812e 100644 --- a/MediaBrowser.Model/Configuration/ServerConfiguration.cs +++ b/MediaBrowser.Model/Configuration/ServerConfiguration.cs @@ -199,6 +199,7 @@ namespace MediaBrowser.Model.Configuration public bool EnableAnonymousUsageReporting { get; set; } public bool EnableStandaloneMusicKeys { get; set; } + public bool EnableLocalizedGuids { get; set; } /// /// Initializes a new instance of the class. @@ -208,6 +209,7 @@ namespace MediaBrowser.Model.Configuration Migrations = new string[] { }; EnableCustomPathSubFolders = true; + EnableLocalizedGuids = true; ImageSavingConvention = ImageSavingConvention.Compatible; PublicPort = 8096; diff --git a/MediaBrowser.Server.Implementations/Library/LibraryManager.cs b/MediaBrowser.Server.Implementations/Library/LibraryManager.cs index 961819f0d..56d3bd4de 100644 --- a/MediaBrowser.Server.Implementations/Library/LibraryManager.cs +++ b/MediaBrowser.Server.Implementations/Library/LibraryManager.cs @@ -502,7 +502,7 @@ namespace MediaBrowser.Server.Implementations.Library throw new ArgumentNullException("type"); } - if (key.StartsWith(ConfigurationManager.ApplicationPaths.ProgramDataPath)) + if (ConfigurationManager.Configuration.EnableLocalizedGuids && key.StartsWith(ConfigurationManager.ApplicationPaths.ProgramDataPath)) { // Try to normalize paths located underneath program-data in an attempt to make them more portable key = key.Substring(ConfigurationManager.ApplicationPaths.ProgramDataPath.Length) -- cgit v1.2.3 From 446b50e5567311f96ce9ef91425fe82fed27bbc7 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Mon, 23 May 2016 14:25:52 -0400 Subject: add index on TopParentId --- .../Persistence/SqliteItemRepository.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'MediaBrowser.Server.Implementations') diff --git a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs index 7e2cc2da3..9978e9781 100644 --- a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs +++ b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs @@ -246,7 +246,8 @@ namespace MediaBrowser.Server.Implementations.Persistence string[] postQueries = { "create index if not exists idx_PresentationUniqueKey on TypedBaseItems(PresentationUniqueKey)", - "create index if not exists idx_Type on TypedBaseItems(Type)" + "create index if not exists idx_Type on TypedBaseItems(Type)", + "create index if not exists idx_TopParentId on TypedBaseItems(TopParentId)" }; _connection.RunQueries(postQueries, Logger); -- cgit v1.2.3 From b23ca6a04c97df25ffc5a6b2ddd62dbc80188736 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Mon, 23 May 2016 15:21:28 -0400 Subject: update simpleinjector --- .../MediaBrowser.Common.Implementations.csproj | 4 ++-- MediaBrowser.Common.Implementations/packages.config | 2 +- .../MediaBrowser.Server.Implementations.csproj | 4 ++-- MediaBrowser.Server.Implementations/packages.config | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) (limited to 'MediaBrowser.Server.Implementations') diff --git a/MediaBrowser.Common.Implementations/MediaBrowser.Common.Implementations.csproj b/MediaBrowser.Common.Implementations/MediaBrowser.Common.Implementations.csproj index 70489d714..a889879d5 100644 --- a/MediaBrowser.Common.Implementations/MediaBrowser.Common.Implementations.csproj +++ b/MediaBrowser.Common.Implementations/MediaBrowser.Common.Implementations.csproj @@ -65,8 +65,8 @@ False ..\ThirdParty\SharpCompress\SharpCompress.dll - - ..\packages\SimpleInjector.3.1.4\lib\net45\SimpleInjector.dll + + ..\packages\SimpleInjector.3.1.5\lib\net45\SimpleInjector.dll True diff --git a/MediaBrowser.Common.Implementations/packages.config b/MediaBrowser.Common.Implementations/packages.config index d1d135b20..d1ede89a1 100644 --- a/MediaBrowser.Common.Implementations/packages.config +++ b/MediaBrowser.Common.Implementations/packages.config @@ -4,5 +4,5 @@ - + \ No newline at end of file diff --git a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj index c65ae7f8a..336310888 100644 --- a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj +++ b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj @@ -68,8 +68,8 @@ ..\ThirdParty\ServiceStack\ServiceStack.Api.Swagger.dll - - ..\packages\SimpleInjector.3.1.4\lib\net45\SimpleInjector.dll + + ..\packages\SimpleInjector.3.1.5\lib\net45\SimpleInjector.dll True diff --git a/MediaBrowser.Server.Implementations/packages.config b/MediaBrowser.Server.Implementations/packages.config index b877d41a8..31b1454d5 100644 --- a/MediaBrowser.Server.Implementations/packages.config +++ b/MediaBrowser.Server.Implementations/packages.config @@ -8,6 +8,6 @@ - + \ No newline at end of file -- cgit v1.2.3 From accdbfaab259152d171ba09b887355c221fc7a11 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Tue, 24 May 2016 03:40:45 -0400 Subject: update live tv suggestions --- .../LiveTv/LiveTvManager.cs | 56 ++++++---------------- 1 file changed, 14 insertions(+), 42 deletions(-) (limited to 'MediaBrowser.Server.Implementations') diff --git a/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs b/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs index a35a7c940..de7fb5c8a 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs @@ -939,9 +939,15 @@ namespace MediaBrowser.Server.Implementations.LiveTv IsMovie = query.IsMovie, IsSports = query.IsSports, IsKids = query.IsKids, - EnableTotalRecordCount = query.EnableTotalRecordCount + EnableTotalRecordCount = query.EnableTotalRecordCount, + SortBy = new[] { ItemSortBy.StartDate } }; + if (query.Limit.HasValue) + { + internalQuery.Limit = Math.Max(query.Limit.Value * 5, 500); + } + if (query.HasAired.HasValue) { if (query.HasAired.Value) @@ -958,15 +964,10 @@ namespace MediaBrowser.Server.Implementations.LiveTv var programList = programs.ToList(); - var genres = programList.SelectMany(i => i.Genres) - .Where(i => !string.IsNullOrWhiteSpace(i)) - .DistinctNames() - .Select(i => _libraryManager.GetGenre(i)) - .DistinctBy(i => i.Id) - .ToDictionary(i => i.Name, StringComparer.OrdinalIgnoreCase); + var factorChannelWatchCount = (query.IsAiring ?? false) || (query.IsKids ?? false) || (query.IsSports ?? false) || (query.IsMovie ?? false); programs = programList.OrderBy(i => i.HasImage(ImageType.Primary) ? 0 : 1) - .ThenByDescending(i => GetRecommendationScore(i, user.Id, genres)) + .ThenByDescending(i => GetRecommendationScore(i, user.Id, factorChannelWatchCount)) .ThenBy(i => i.StartDate); if (query.Limit.HasValue) @@ -1004,7 +1005,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv return result; } - private int GetRecommendationScore(LiveTvProgram program, Guid userId, Dictionary genres) + private int GetRecommendationScore(LiveTvProgram program, Guid userId, bool factorChannelWatchCount) { var score = 0; @@ -1036,41 +1037,12 @@ namespace MediaBrowser.Server.Implementations.LiveTv score += 3; } - score += GetGenreScore(program.Genres, userId, genres); - - return score; - } - - private int GetGenreScore(IEnumerable programGenres, Guid userId, Dictionary genres) - { - return programGenres.Select(i => + if (factorChannelWatchCount) { - var score = 0; - - Genre genre; - - if (genres.TryGetValue(i, out genre)) - { - var genreUserdata = _userDataManager.GetUserData(userId, genre); - - if (genreUserdata.Likes ?? false) - { - score++; - } - else if (!(genreUserdata.Likes ?? true)) - { - score--; - } - - if (genreUserdata.IsFavorite) - { - score += 2; - } - } - - return score; + score += channelUserdata.PlayCount; + } - }).Sum(); + return score; } private async Task AddRecordingInfo(IEnumerable> programs, CancellationToken cancellationToken) -- cgit v1.2.3 From 8000a30d9a230610056d93a6be18e53b4f4914a9 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Tue, 24 May 2016 12:58:36 -0400 Subject: update UserDataManager --- .../Library/UserDataManager.cs | 22 +++++++++------------- 1 file changed, 9 insertions(+), 13 deletions(-) (limited to 'MediaBrowser.Server.Implementations') diff --git a/MediaBrowser.Server.Implementations/Library/UserDataManager.cs b/MediaBrowser.Server.Implementations/Library/UserDataManager.cs index 0e211937f..afbce87a9 100644 --- a/MediaBrowser.Server.Implementations/Library/UserDataManager.cs +++ b/MediaBrowser.Server.Implementations/Library/UserDataManager.cs @@ -170,22 +170,18 @@ namespace MediaBrowser.Server.Implementations.Library return value; } } + } - if (keys.Count > 0) + if (keys.Count > 0) + { + return new UserItemData { - var key = keys[0]; - var cacheKey = GetCacheKey(userId, key); - var userdata = new UserItemData - { - UserId = userId, - Key = key - }; - _userData[cacheKey] = userdata; - return userdata; - } - - return null; + UserId = userId, + Key = keys[0] + }; } + + return null; } /// -- cgit v1.2.3 From 58d4534a2690389c37a7ad5bb247e6dc28c01401 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Tue, 24 May 2016 12:58:56 -0400 Subject: update live tv suggestions --- MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'MediaBrowser.Server.Implementations') diff --git a/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs b/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs index de7fb5c8a..bbdc4ab0d 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs @@ -945,7 +945,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv if (query.Limit.HasValue) { - internalQuery.Limit = Math.Max(query.Limit.Value * 5, 500); + internalQuery.Limit = Math.Max(query.Limit.Value * 5, 300); } if (query.HasAired.HasValue) -- cgit v1.2.3 From 178a5f6978c417b3209c27bb9bde184749a9ef58 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Tue, 24 May 2016 14:28:58 -0400 Subject: fix attach --- MediaBrowser.Server.Implementations/Persistence/DataExtensions.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'MediaBrowser.Server.Implementations') diff --git a/MediaBrowser.Server.Implementations/Persistence/DataExtensions.cs b/MediaBrowser.Server.Implementations/Persistence/DataExtensions.cs index 103b75f84..61ce6e351 100644 --- a/MediaBrowser.Server.Implementations/Persistence/DataExtensions.cs +++ b/MediaBrowser.Server.Implementations/Persistence/DataExtensions.cs @@ -122,7 +122,10 @@ namespace MediaBrowser.Server.Implementations.Persistence { using (var cmd = db.CreateCommand()) { - cmd.CommandText = string.Format("attach '{0}' as {1};", path, alias); + cmd.CommandText = string.Format("attach @dbPath as {0};", alias); + cmd.Parameters.Add(cmd, "@dbPath", DbType.String); + cmd.GetParameter(0).Value = path; + cmd.ExecuteNonQuery(); } } -- cgit v1.2.3 From 6bb6e0ff849e09fa39281adf6001599c0a73f979 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Tue, 24 May 2016 20:22:41 -0400 Subject: update logging --- .../Persistence/SqliteItemRepository.cs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'MediaBrowser.Server.Implementations') diff --git a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs index 9978e9781..ec10fdaf6 100644 --- a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs +++ b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs @@ -1670,7 +1670,13 @@ namespace MediaBrowser.Server.Implementations.Persistence { var elapsed = (DateTime.UtcNow - startDate).TotalMilliseconds; - if (elapsed >= 400) + var slowThreshold = 1000; + +#if DEBUG + slowThreshold = 200; +#endif + + if (elapsed >= slowThreshold) { Logger.Debug("{2} query time (slow): {0}ms. Query: {1}", Convert.ToInt32(elapsed), -- cgit v1.2.3 From cc19c762b419fe427abb8d03a2625e2be796e443 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Tue, 24 May 2016 22:06:56 -0400 Subject: update refresh --- MediaBrowser.Controller/Entities/BaseItem.cs | 4 +--- MediaBrowser.Controller/Entities/Folder.cs | 8 +++----- MediaBrowser.Providers/Manager/MetadataService.cs | 6 ------ .../Devices/CameraUploadsFolder.cs | 1 + 4 files changed, 5 insertions(+), 14 deletions(-) (limited to 'MediaBrowser.Server.Implementations') diff --git a/MediaBrowser.Controller/Entities/BaseItem.cs b/MediaBrowser.Controller/Entities/BaseItem.cs index 61060766f..1a9bd618d 100644 --- a/MediaBrowser.Controller/Entities/BaseItem.cs +++ b/MediaBrowser.Controller/Entities/BaseItem.cs @@ -1031,9 +1031,7 @@ namespace MediaBrowser.Controller.Entities } : options; - var result = await ProviderManager.RefreshSingleItem(this, refreshOptions, cancellationToken).ConfigureAwait(false); - - return result; + return await ProviderManager.RefreshSingleItem(this, refreshOptions, cancellationToken).ConfigureAwait(false); } [IgnoreDataMember] diff --git a/MediaBrowser.Controller/Entities/Folder.cs b/MediaBrowser.Controller/Entities/Folder.cs index ac49dc3b2..cbbd0ad68 100644 --- a/MediaBrowser.Controller/Entities/Folder.cs +++ b/MediaBrowser.Controller/Entities/Folder.cs @@ -461,17 +461,15 @@ namespace MediaBrowser.Controller.Entities foreach (var item in itemsRemoved) { - if (item.LocationType == LocationType.Virtual || - item.LocationType == LocationType.Remote) + var itemLocationType = item.LocationType; + if (itemLocationType == LocationType.Virtual || + itemLocationType == LocationType.Remote) { - // Don't remove these because there's no way to accurately validate them. - validChildren.Add(item); } else if (!string.IsNullOrEmpty(item.Path) && IsPathOffline(item.Path)) { await UpdateIsOffline(item, true).ConfigureAwait(false); - validChildren.Add(item); } else { diff --git a/MediaBrowser.Providers/Manager/MetadataService.cs b/MediaBrowser.Providers/Manager/MetadataService.cs index 0c2954424..b84d1b0ff 100644 --- a/MediaBrowser.Providers/Manager/MetadataService.cs +++ b/MediaBrowser.Providers/Manager/MetadataService.cs @@ -422,12 +422,6 @@ namespace MediaBrowser.Providers.Manager providers = providers .Where(i => { - var hasChangeMonitor = i as IHasChangeMonitor; - if (hasChangeMonitor != null) - { - return HasChanged(item, hasChangeMonitor, dateLastImageRefresh, options.DirectoryService); - } - var hasFileChangeMonitor = i as IHasItemChangeMonitor; if (hasFileChangeMonitor != null) { diff --git a/MediaBrowser.Server.Implementations/Devices/CameraUploadsFolder.cs b/MediaBrowser.Server.Implementations/Devices/CameraUploadsFolder.cs index 947933561..3dfc04c26 100644 --- a/MediaBrowser.Server.Implementations/Devices/CameraUploadsFolder.cs +++ b/MediaBrowser.Server.Implementations/Devices/CameraUploadsFolder.cs @@ -28,6 +28,7 @@ namespace MediaBrowser.Server.Implementations.Devices return base.IsVisible(user) && HasChildren(); } + [IgnoreDataMember] public override string CollectionType { get { return Model.Entities.CollectionType.Photos; } -- cgit v1.2.3 From e50566c01fe6e3b516ce5d4b5d94ded02e197815 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Wed, 25 May 2016 00:57:48 -0400 Subject: update people interval --- .../Library/Validators/PeopleValidator.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'MediaBrowser.Server.Implementations') diff --git a/MediaBrowser.Server.Implementations/Library/Validators/PeopleValidator.cs b/MediaBrowser.Server.Implementations/Library/Validators/PeopleValidator.cs index 500a5ad3d..5c43f2e13 100644 --- a/MediaBrowser.Server.Implementations/Library/Validators/PeopleValidator.cs +++ b/MediaBrowser.Server.Implementations/Library/Validators/PeopleValidator.cs @@ -125,7 +125,7 @@ namespace MediaBrowser.Server.Implementations.Library.Validators validIds.Add(item.Id); var hasMetdata = !string.IsNullOrWhiteSpace(item.Overview); - var performFullRefresh = !hasMetdata && (DateTime.UtcNow - item.DateLastRefreshed).TotalDays >= 14; + var performFullRefresh = !hasMetdata && (DateTime.UtcNow - item.DateLastRefreshed).TotalDays >= 30; var defaultMetadataRefreshMode = performFullRefresh ? MetadataRefreshMode.FullRefresh -- cgit v1.2.3 From b0bf7119baa7f74966e476078e42a4a1f14bb8df Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Wed, 25 May 2016 12:11:08 -0400 Subject: update EncodedRecorder --- MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EncodedRecorder.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'MediaBrowser.Server.Implementations') diff --git a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EncodedRecorder.cs b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EncodedRecorder.cs index 0752d4132..e9ea49fa3 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EncodedRecorder.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EncodedRecorder.cs @@ -145,7 +145,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV videoArgs = "-codec:v:0 copy"; } - var commandLineArgs = "-probesize 1G -analyzeduration 200M -fflags +genpts -async 1 -vsync -1 -i \"{0}\" -t {4} -sn {2} -map_metadata -1 -threads 0 {3} -y \"{1}\""; + var commandLineArgs = "-fflags +genpts -async 1 -vsync -1 -i \"{0}\" -t {4} -sn {2} -map_metadata -1 -threads 0 {3} -y \"{1}\""; if (mediaSource.ReadAtNativeFramerate) { -- cgit v1.2.3 From e0a213601b3efa24565b41eaf7ed1d4b36aeec9a Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Thu, 26 May 2016 00:11:27 -0400 Subject: stub out file refresher --- .../IO/FileRefresher.cs | 241 +++++++++++++++++++++ .../MediaBrowser.Server.Implementations.csproj | 1 + 2 files changed, 242 insertions(+) create mode 100644 MediaBrowser.Server.Implementations/IO/FileRefresher.cs (limited to 'MediaBrowser.Server.Implementations') diff --git a/MediaBrowser.Server.Implementations/IO/FileRefresher.cs b/MediaBrowser.Server.Implementations/IO/FileRefresher.cs new file mode 100644 index 000000000..74dfbc679 --- /dev/null +++ b/MediaBrowser.Server.Implementations/IO/FileRefresher.cs @@ -0,0 +1,241 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; +using CommonIO; +using MediaBrowser.Common.ScheduledTasks; +using MediaBrowser.Controller.Configuration; +using MediaBrowser.Controller.Entities; +using MediaBrowser.Controller.Library; +using MediaBrowser.Model.Logging; +using MediaBrowser.Server.Implementations.ScheduledTasks; + +namespace MediaBrowser.Server.Implementations.IO +{ + public class FileRefresher : IDisposable + { + private ILogger Logger { get; set; } + private ITaskManager TaskManager { get; set; } + private ILibraryManager LibraryManager { get; set; } + private IServerConfigurationManager ConfigurationManager { get; set; } + private readonly IFileSystem _fileSystem; + private readonly List _affectedPaths = new List(); + private Timer _timer; + private readonly object _timerLock = new object(); + + public FileRefresher(string path, IFileSystem fileSystem, IServerConfigurationManager configurationManager, ILibraryManager libraryManager, ITaskManager taskManager, ILogger logger) + { + _affectedPaths.Add(path); + + _fileSystem = fileSystem; + ConfigurationManager = configurationManager; + LibraryManager = libraryManager; + TaskManager = taskManager; + Logger = logger; + } + + private void RestartTimer() + { + lock (_timerLock) + { + if (_timer == null) + { + _timer = new Timer(OnTimerCallback, null, TimeSpan.FromSeconds(ConfigurationManager.Configuration.LibraryMonitorDelay), TimeSpan.FromMilliseconds(-1)); + } + else + { + _timer.Change(TimeSpan.FromSeconds(ConfigurationManager.Configuration.LibraryMonitorDelay), TimeSpan.FromMilliseconds(-1)); + } + } + } + + private async void OnTimerCallback(object state) + { + // Extend the timer as long as any of the paths are still being written to. + if (_affectedPaths.Any(IsFileLocked)) + { + Logger.Info("Timer extended."); + RestartTimer(); + return; + } + + Logger.Debug("Timer stopped."); + + DisposeTimer(); + + try + { + await ProcessPathChanges(_affectedPaths).ConfigureAwait(false); + } + catch (Exception ex) + { + Logger.ErrorException("Error processing directory changes", ex); + } + } + + private async Task ProcessPathChanges(List paths) + { + var itemsToRefresh = paths + .Select(GetAffectedBaseItem) + .Where(item => item != null) + .Distinct() + .ToList(); + + foreach (var p in paths) + { + Logger.Info(p + " reports change."); + } + + // If the root folder changed, run the library task so the user can see it + if (itemsToRefresh.Any(i => i is AggregateFolder)) + { + TaskManager.CancelIfRunningAndQueue(); + return; + } + + foreach (var item in itemsToRefresh) + { + Logger.Info(item.Name + " (" + item.Path + ") will be refreshed."); + + try + { + await item.ChangedExternally().ConfigureAwait(false); + } + catch (IOException ex) + { + // For now swallow and log. + // Research item: If an IOException occurs, the item may be in a disconnected state (media unavailable) + // Should we remove it from it's parent? + Logger.ErrorException("Error refreshing {0}", ex, item.Name); + } + catch (Exception ex) + { + Logger.ErrorException("Error refreshing {0}", ex, item.Name); + } + } + } + + /// + /// Gets the affected base item. + /// + /// The path. + /// BaseItem. + private BaseItem GetAffectedBaseItem(string path) + { + BaseItem item = null; + + while (item == null && !string.IsNullOrEmpty(path)) + { + item = LibraryManager.FindByPath(path, null); + + path = Path.GetDirectoryName(path); + } + + if (item != null) + { + // If the item has been deleted find the first valid parent that still exists + while (!_fileSystem.DirectoryExists(item.Path) && !_fileSystem.FileExists(item.Path)) + { + item = item.GetParent(); + + if (item == null) + { + break; + } + } + } + + return item; + } + + private bool IsFileLocked(string path) + { + if (Environment.OSVersion.Platform != PlatformID.Win32NT) + { + // Causing lockups on linux + return false; + } + + try + { + var data = _fileSystem.GetFileSystemInfo(path); + + if (!data.Exists + || data.IsDirectory + + // Opening a writable stream will fail with readonly files + || data.Attributes.HasFlag(FileAttributes.ReadOnly)) + { + return false; + } + } + catch (IOException) + { + return false; + } + catch (Exception ex) + { + Logger.ErrorException("Error getting file system info for: {0}", ex, path); + return false; + } + + // In order to determine if the file is being written to, we have to request write access + // But if the server only has readonly access, this is going to cause this entire algorithm to fail + // So we'll take a best guess about our access level + var requestedFileAccess = ConfigurationManager.Configuration.SaveLocalMeta + ? FileAccess.ReadWrite + : FileAccess.Read; + + try + { + using (_fileSystem.GetFileStream(path, FileMode.Open, requestedFileAccess, FileShare.ReadWrite)) + { + //file is not locked + return false; + } + } + catch (DirectoryNotFoundException) + { + // File may have been deleted + return false; + } + catch (FileNotFoundException) + { + // File may have been deleted + return false; + } + catch (IOException) + { + //the file is unavailable because it is: + //still being written to + //or being processed by another thread + //or does not exist (has already been processed) + Logger.Debug("{0} is locked.", path); + return true; + } + catch (Exception ex) + { + Logger.ErrorException("Error determining if file is locked: {0}", ex, path); + return false; + } + } + + public void DisposeTimer() + { + lock (_timerLock) + { + if (_timer != null) + { + _timer.Dispose(); + } + } + } + + public void Dispose() + { + DisposeTimer(); + } + } +} diff --git a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj index 336310888..28edbfcc4 100644 --- a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj +++ b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj @@ -180,6 +180,7 @@ + -- cgit v1.2.3 From 4e624c2cefd3b7f3358ca00253064b7e8cf89de4 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Thu, 26 May 2016 13:18:58 -0400 Subject: removed dead code --- .../MediaBrowser.Controller.csproj | 4 -- .../Providers/IItemIdentityConverter.cs | 4 -- .../Providers/IItemIdentityProvider.cs | 4 -- .../Providers/IProviderManager.cs | 20 +----- .../Providers/ItemIdentifier.cs | 36 ---------- .../Providers/ItemIdentities.cs | 16 ----- MediaBrowser.Providers/Manager/MetadataService.cs | 12 ---- MediaBrowser.Providers/Manager/ProviderManager.cs | 19 ----- .../MediaBrowser.Providers.csproj | 1 - .../TV/TheTVDB/TvdbEpisodeProvider.cs | 82 +--------------------- .../TV/TheTVDB/TvdbSeasonIdentityProvider.cs | 65 ----------------- .../TV/TheTVDB/TvdbSeasonImageProvider.cs | 15 ---- .../TV/TheTVDB/TvdbSeriesProvider.cs | 2 +- .../LiveTv/EmbyTV/EmbyTV.cs | 4 +- .../ApplicationHost.cs | 2 - 15 files changed, 5 insertions(+), 281 deletions(-) delete mode 100644 MediaBrowser.Controller/Providers/IItemIdentityConverter.cs delete mode 100644 MediaBrowser.Controller/Providers/IItemIdentityProvider.cs delete mode 100644 MediaBrowser.Controller/Providers/ItemIdentifier.cs delete mode 100644 MediaBrowser.Controller/Providers/ItemIdentities.cs delete mode 100644 MediaBrowser.Providers/TV/TheTVDB/TvdbSeasonIdentityProvider.cs (limited to 'MediaBrowser.Server.Implementations') diff --git a/MediaBrowser.Controller/MediaBrowser.Controller.csproj b/MediaBrowser.Controller/MediaBrowser.Controller.csproj index 57855008d..4d9999b37 100644 --- a/MediaBrowser.Controller/MediaBrowser.Controller.csproj +++ b/MediaBrowser.Controller/MediaBrowser.Controller.csproj @@ -290,8 +290,6 @@ - - @@ -329,8 +327,6 @@ - - diff --git a/MediaBrowser.Controller/Providers/IItemIdentityConverter.cs b/MediaBrowser.Controller/Providers/IItemIdentityConverter.cs deleted file mode 100644 index bfdd1dbf3..000000000 --- a/MediaBrowser.Controller/Providers/IItemIdentityConverter.cs +++ /dev/null @@ -1,4 +0,0 @@ -namespace MediaBrowser.Controller.Providers -{ - public interface IItemIdentityConverter { } -} \ No newline at end of file diff --git a/MediaBrowser.Controller/Providers/IItemIdentityProvider.cs b/MediaBrowser.Controller/Providers/IItemIdentityProvider.cs deleted file mode 100644 index 6b403bb55..000000000 --- a/MediaBrowser.Controller/Providers/IItemIdentityProvider.cs +++ /dev/null @@ -1,4 +0,0 @@ -namespace MediaBrowser.Controller.Providers -{ - public interface IItemIdentityProvider { } -} \ No newline at end of file diff --git a/MediaBrowser.Controller/Providers/IProviderManager.cs b/MediaBrowser.Controller/Providers/IProviderManager.cs index 57e4ff320..a976a7f71 100644 --- a/MediaBrowser.Controller/Providers/IProviderManager.cs +++ b/MediaBrowser.Controller/Providers/IProviderManager.cs @@ -97,13 +97,11 @@ namespace MediaBrowser.Controller.Providers /// /// The image providers. /// The metadata services. - /// The identity providers. - /// The identity converters. /// The metadata providers. /// The savers. /// The image savers. /// The external ids. - void AddParts(IEnumerable imageProviders, IEnumerable metadataServices, IEnumerable identityProviders, IEnumerable identityConverters, IEnumerable metadataProviders, + void AddParts(IEnumerable imageProviders, IEnumerable metadataServices, IEnumerable metadataProviders, IEnumerable savers, IEnumerable imageSavers, IEnumerable externalIds); @@ -190,21 +188,5 @@ namespace MediaBrowser.Controller.Providers /// The cancellation token. /// Task{HttpResponseInfo}. Task GetSearchImage(string providerName, string url, CancellationToken cancellationToken); - - /// - /// Gets the item identity providers. - /// - /// The type of the t lookup information. - /// IEnumerable<IItemIdentityProvider<TLookupInfo, TIdentity>>. - IEnumerable> GetItemIdentityProviders() - where TLookupInfo : ItemLookupInfo; - - /// - /// Gets the item identity converters. - /// - /// The type of the t lookup information. - /// IEnumerable<IItemIdentityConverter<TIdentity>>. - IEnumerable> GetItemIdentityConverters() - where TLookupInfo : ItemLookupInfo; } } \ No newline at end of file diff --git a/MediaBrowser.Controller/Providers/ItemIdentifier.cs b/MediaBrowser.Controller/Providers/ItemIdentifier.cs deleted file mode 100644 index bbc6dd76c..000000000 --- a/MediaBrowser.Controller/Providers/ItemIdentifier.cs +++ /dev/null @@ -1,36 +0,0 @@ -using System.Linq; -using System.Threading; -using System.Threading.Tasks; - -namespace MediaBrowser.Controller.Providers -{ - public static class ItemIdentifier - where TLookupInfo : ItemLookupInfo - { - public static async Task FindIdentities(TLookupInfo item, IProviderManager providerManager, CancellationToken cancellationToken) - { - var providers = providerManager.GetItemIdentityProviders(); - var converters = providerManager.GetItemIdentityConverters().ToList(); - - foreach (var provider in providers) - { - await provider.Identify(item); - } - - bool changesMade = true; - - while (changesMade) - { - changesMade = false; - - foreach (var converter in converters) - { - if (await converter.Convert(item)) - { - changesMade = true; - } - } - } - } - } -} \ No newline at end of file diff --git a/MediaBrowser.Controller/Providers/ItemIdentities.cs b/MediaBrowser.Controller/Providers/ItemIdentities.cs deleted file mode 100644 index 48316d0f4..000000000 --- a/MediaBrowser.Controller/Providers/ItemIdentities.cs +++ /dev/null @@ -1,16 +0,0 @@ -using System.Threading.Tasks; - -namespace MediaBrowser.Controller.Providers -{ - public interface IItemIdentityProvider : IItemIdentityProvider - where TLookupInfo : ItemLookupInfo - { - Task Identify(TLookupInfo info); - } - - public interface IItemIdentityConverter : IItemIdentityConverter - where TLookupInfo : ItemLookupInfo - { - Task Convert(TLookupInfo info); - } -} \ No newline at end of file diff --git a/MediaBrowser.Providers/Manager/MetadataService.cs b/MediaBrowser.Providers/Manager/MetadataService.cs index b84d1b0ff..678d495cb 100644 --- a/MediaBrowser.Providers/Manager/MetadataService.cs +++ b/MediaBrowser.Providers/Manager/MetadataService.cs @@ -179,18 +179,6 @@ namespace MediaBrowser.Providers.Manager lookupInfo.Year = result.ProductionYear; } - private async Task FindIdentities(TIdType id, CancellationToken cancellationToken) - { - try - { - await ItemIdentifier.FindIdentities(id, ProviderManager, cancellationToken).ConfigureAwait(false); - } - catch (Exception ex) - { - Logger.ErrorException("Error in FindIdentities", ex); - } - } - private DateTime GetLastRefreshDate(IHasMetadata item) { return item.DateLastRefreshed; diff --git a/MediaBrowser.Providers/Manager/ProviderManager.cs b/MediaBrowser.Providers/Manager/ProviderManager.cs index c95d58a42..29897e073 100644 --- a/MediaBrowser.Providers/Manager/ProviderManager.cs +++ b/MediaBrowser.Providers/Manager/ProviderManager.cs @@ -55,8 +55,6 @@ namespace MediaBrowser.Providers.Manager private readonly IFileSystem _fileSystem; private IMetadataService[] _metadataServices = { }; - private IItemIdentityProvider[] _identityProviders = { }; - private IItemIdentityConverter[] _identityConverters = { }; private IMetadataProvider[] _metadataProviders = { }; private IEnumerable _savers; private IImageSaver[] _imageSavers; @@ -92,22 +90,17 @@ namespace MediaBrowser.Providers.Manager /// /// The image providers. /// The metadata services. - /// The identity providers. - /// The identity converters. /// The metadata providers. /// The metadata savers. /// The image savers. /// The external ids. public void AddParts(IEnumerable imageProviders, IEnumerable metadataServices, - IEnumerable identityProviders, IEnumerable identityConverters, IEnumerable metadataProviders, IEnumerable metadataSavers, IEnumerable imageSavers, IEnumerable externalIds) { ImageProviders = imageProviders.ToArray(); _metadataServices = metadataServices.OrderBy(i => i.Order).ToArray(); - _identityProviders = identityProviders.ToArray(); - _identityConverters = identityConverters.ToArray(); _metadataProviders = metadataProviders.ToArray(); _imageSavers = imageSavers.ToArray(); _externalIds = externalIds.OrderBy(i => i.Name).ToArray(); @@ -301,18 +294,6 @@ namespace MediaBrowser.Providers.Manager .ThenBy(GetDefaultOrder); } - public IEnumerable> GetItemIdentityProviders() - where TLookupInfo : ItemLookupInfo - { - return _identityProviders.OfType>(); - } - - public IEnumerable> GetItemIdentityConverters() - where TLookupInfo : ItemLookupInfo - { - return _identityConverters.OfType>(); - } - private IEnumerable GetRemoteImageProviders(IHasImages item, bool includeDisabled) { var options = GetMetadataOptions(item); diff --git a/MediaBrowser.Providers/MediaBrowser.Providers.csproj b/MediaBrowser.Providers/MediaBrowser.Providers.csproj index bbfa20738..240b2e2cc 100644 --- a/MediaBrowser.Providers/MediaBrowser.Providers.csproj +++ b/MediaBrowser.Providers/MediaBrowser.Providers.csproj @@ -177,7 +177,6 @@ - diff --git a/MediaBrowser.Providers/TV/TheTVDB/TvdbEpisodeProvider.cs b/MediaBrowser.Providers/TV/TheTVDB/TvdbEpisodeProvider.cs index 7005ba8f5..a41a95c12 100644 --- a/MediaBrowser.Providers/TV/TheTVDB/TvdbEpisodeProvider.cs +++ b/MediaBrowser.Providers/TV/TheTVDB/TvdbEpisodeProvider.cs @@ -24,7 +24,7 @@ namespace MediaBrowser.Providers.TV /// /// Class RemoteEpisodeProvider /// - class TvdbEpisodeProvider : IRemoteMetadataProvider, IItemIdentityProvider + class TvdbEpisodeProvider : IRemoteMetadataProvider { private static readonly string FullIdKey = MetadataProviders.Tvdb + "-Full"; @@ -871,86 +871,6 @@ namespace MediaBrowser.Providers.TV }); } - public Task Identify(EpisodeInfo info) - { - if (info.ProviderIds.ContainsKey(FullIdKey)) - { - return Task.FromResult(null); - } - - string seriesTvdbId; - info.SeriesProviderIds.TryGetValue(MetadataProviders.Tvdb.ToString(), out seriesTvdbId); - - if (string.IsNullOrEmpty(seriesTvdbId) || info.IndexNumber == null) - { - return Task.FromResult(null); - } - - var id = new Identity(seriesTvdbId, info.ParentIndexNumber, info.IndexNumber.Value, info.IndexNumberEnd); - info.SetProviderId(FullIdKey, id.ToString()); - - return Task.FromResult(id); - } - public int Order { get { return 0; } } - - public struct Identity - { - public string SeriesId { get; private set; } - public int? SeasonIndex { get; private set; } - public int EpisodeNumber { get; private set; } - public int? EpisodeNumberEnd { get; private set; } - - public Identity(string id) - : this() - { - this = ParseIdentity(id).Value; - } - - public Identity(string seriesId, int? seasonIndex, int episodeNumber, int? episodeNumberEnd) - : this() - { - SeriesId = seriesId; - SeasonIndex = seasonIndex; - EpisodeNumber = episodeNumber; - EpisodeNumberEnd = episodeNumberEnd; - } - - public override string ToString() - { - return string.Format("{0}:{1}:{2}", - SeriesId, - SeasonIndex != null ? SeasonIndex.Value.ToString() : "A", - EpisodeNumber + (EpisodeNumberEnd != null ? "-" + EpisodeNumberEnd.Value.ToString() : "")); - } - - public static Identity? ParseIdentity(string id) - { - if (string.IsNullOrEmpty(id)) - return null; - - try { - var parts = id.Split(':'); - var series = parts[0]; - var season = parts[1] != "A" ? (int?)int.Parse(parts[1]) : null; - - int index; - int? indexEnd; - - if (parts[2].Contains("-")) { - var split = parts[2].IndexOf("-", StringComparison.OrdinalIgnoreCase); - index = int.Parse(parts[2].Substring(0, split)); - indexEnd = int.Parse(parts[2].Substring(split + 1)); - } else { - index = int.Parse(parts[2]); - indexEnd = null; - } - - return new Identity(series, season, index, indexEnd); - } catch { - return null; - } - } - } } } diff --git a/MediaBrowser.Providers/TV/TheTVDB/TvdbSeasonIdentityProvider.cs b/MediaBrowser.Providers/TV/TheTVDB/TvdbSeasonIdentityProvider.cs deleted file mode 100644 index 4198430c9..000000000 --- a/MediaBrowser.Providers/TV/TheTVDB/TvdbSeasonIdentityProvider.cs +++ /dev/null @@ -1,65 +0,0 @@ -using System.Threading.Tasks; -using MediaBrowser.Controller.Providers; -using MediaBrowser.Model.Entities; - -namespace MediaBrowser.Providers.TV -{ - public class TvdbSeasonIdentityProvider : IItemIdentityProvider - { - public static readonly string FullIdKey = MetadataProviders.Tvdb + "-Full"; - - public Task Identify(SeasonInfo info) - { - string tvdbSeriesId; - if (!info.SeriesProviderIds.TryGetValue(MetadataProviders.Tvdb.ToString(), out tvdbSeriesId) || string.IsNullOrEmpty(tvdbSeriesId) || info.IndexNumber == null) - { - return Task.FromResult(null); - } - - if (string.IsNullOrEmpty(info.GetProviderId(FullIdKey))) - { - var id = string.Format("{0}:{1}", tvdbSeriesId, info.IndexNumber.Value); - info.SetProviderId(FullIdKey, id); - } - - return Task.FromResult(null); - } - - public static TvdbSeasonIdentity? ParseIdentity(string id) - { - if (id == null) - { - return null; - } - - try - { - var parts = id.Split(':'); - return new TvdbSeasonIdentity(parts[0], int.Parse(parts[1])); - } - catch - { - return null; - } - } - } - - public struct TvdbSeasonIdentity - { - public string SeriesId { get; private set; } - public int Index { get; private set; } - - public TvdbSeasonIdentity(string id) - : this() - { - this = TvdbSeasonIdentityProvider.ParseIdentity(id).Value; - } - - public TvdbSeasonIdentity(string seriesId, int index) - : this() - { - SeriesId = seriesId; - Index = index; - } - } -} \ No newline at end of file diff --git a/MediaBrowser.Providers/TV/TheTVDB/TvdbSeasonImageProvider.cs b/MediaBrowser.Providers/TV/TheTVDB/TvdbSeasonImageProvider.cs index 71587db97..4b619665c 100644 --- a/MediaBrowser.Providers/TV/TheTVDB/TvdbSeasonImageProvider.cs +++ b/MediaBrowser.Providers/TV/TheTVDB/TvdbSeasonImageProvider.cs @@ -70,21 +70,6 @@ namespace MediaBrowser.Providers.TV var seriesProviderIds = series.ProviderIds; var seasonNumber = season.IndexNumber.Value; - var identity = TvdbSeasonIdentityProvider.ParseIdentity(season.GetProviderId(TvdbSeasonIdentityProvider.FullIdKey)); - if (identity == null) - { - identity = new TvdbSeasonIdentity(series.GetProviderId(MetadataProviders.Tvdb), seasonNumber); - } - - if (identity != null) - { - var id = identity.Value; - seasonNumber = AdjustForSeriesOffset(series, id.Index); - - seriesProviderIds = new Dictionary(StringComparer.OrdinalIgnoreCase); - seriesProviderIds[MetadataProviders.Tvdb.ToString()] = id.SeriesId; - } - var seriesDataPath = await TvdbSeriesProvider.Current.EnsureSeriesInfo(seriesProviderIds, series.GetPreferredMetadataLanguage(), cancellationToken).ConfigureAwait(false); if (!string.IsNullOrWhiteSpace(seriesDataPath)) diff --git a/MediaBrowser.Providers/TV/TheTVDB/TvdbSeriesProvider.cs b/MediaBrowser.Providers/TV/TheTVDB/TvdbSeriesProvider.cs index 15b0c97ac..49ca5cdf2 100644 --- a/MediaBrowser.Providers/TV/TheTVDB/TvdbSeriesProvider.cs +++ b/MediaBrowser.Providers/TV/TheTVDB/TvdbSeriesProvider.cs @@ -25,7 +25,7 @@ using CommonIO; namespace MediaBrowser.Providers.TV { - public class TvdbSeriesProvider : IRemoteMetadataProvider, IItemIdentityProvider, IHasOrder + public class TvdbSeriesProvider : IRemoteMetadataProvider, IHasOrder { private const string TvdbSeriesOffset = "TvdbSeriesOffset"; private const string TvdbSeriesOffsetFormat = "{0}-{1}"; diff --git a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs index 205000fdc..25822a81b 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs @@ -929,10 +929,10 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV recordPath = recorder.GetOutputPath(mediaStreamInfo, recordPath); recordPath = EnsureFileUnique(recordPath, timer.Id); - _fileSystem.CreateDirectory(Path.GetDirectoryName(recordPath)); - activeRecordingInfo.Path = recordPath; _libraryMonitor.ReportFileSystemChangeBeginning(recordPath); + _fileSystem.CreateDirectory(Path.GetDirectoryName(recordPath)); + activeRecordingInfo.Path = recordPath; var duration = recordingEndDate - DateTime.UtcNow; diff --git a/MediaBrowser.Server.Startup.Common/ApplicationHost.cs b/MediaBrowser.Server.Startup.Common/ApplicationHost.cs index 7b958779d..59a8a4f78 100644 --- a/MediaBrowser.Server.Startup.Common/ApplicationHost.cs +++ b/MediaBrowser.Server.Startup.Common/ApplicationHost.cs @@ -804,8 +804,6 @@ namespace MediaBrowser.Server.Startup.Common ProviderManager.AddParts(GetExports(), GetExports(), - GetExports(), - GetExports(), GetExports(), GetExports(), GetExports(), -- cgit v1.2.3 From a02e0473d8ae4b84f31e90ebce00d0f1e681904d Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Thu, 26 May 2016 13:28:20 -0400 Subject: update logging --- .../Persistence/SqliteItemRepository.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'MediaBrowser.Server.Implementations') diff --git a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs index ec10fdaf6..2775389a2 100644 --- a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs +++ b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs @@ -247,7 +247,8 @@ namespace MediaBrowser.Server.Implementations.Persistence { "create index if not exists idx_PresentationUniqueKey on TypedBaseItems(PresentationUniqueKey)", "create index if not exists idx_Type on TypedBaseItems(Type)", - "create index if not exists idx_TopParentId on TypedBaseItems(TopParentId)" + "create index if not exists idx_TopParentId on TypedBaseItems(TopParentId)", + "create index if not exists idx_TypeTopParentId on TypedBaseItems(Type,TopParentId)" }; _connection.RunQueries(postQueries, Logger); @@ -1673,7 +1674,7 @@ namespace MediaBrowser.Server.Implementations.Persistence var slowThreshold = 1000; #if DEBUG - slowThreshold = 200; + slowThreshold = 100; #endif if (elapsed >= slowThreshold) -- cgit v1.2.3 From dd9cb28ee9e1fe95564618bdbc1b3eaaee1f7d96 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Thu, 26 May 2016 15:22:37 -0400 Subject: update index --- MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'MediaBrowser.Server.Implementations') diff --git a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs index 2775389a2..b1f43d20f 100644 --- a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs +++ b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs @@ -248,7 +248,7 @@ namespace MediaBrowser.Server.Implementations.Persistence "create index if not exists idx_PresentationUniqueKey on TypedBaseItems(PresentationUniqueKey)", "create index if not exists idx_Type on TypedBaseItems(Type)", "create index if not exists idx_TopParentId on TypedBaseItems(TopParentId)", - "create index if not exists idx_TypeTopParentId on TypedBaseItems(Type,TopParentId)" + //"create index if not exists idx_TypeTopParentId on TypedBaseItems(Type,TopParentId)" }; _connection.RunQueries(postQueries, Logger); -- cgit v1.2.3 From 6b31083e435b24e7a7accc4ba190940457e18477 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Thu, 26 May 2016 16:54:05 -0400 Subject: separate file monitor to avoid paths getting stuck --- .../IO/FileRefresher.cs | 49 +++- .../IO/LibraryMonitor.cs | 276 +++++---------------- 2 files changed, 104 insertions(+), 221 deletions(-) (limited to 'MediaBrowser.Server.Implementations') diff --git a/MediaBrowser.Server.Implementations/IO/FileRefresher.cs b/MediaBrowser.Server.Implementations/IO/FileRefresher.cs index 74dfbc679..18c52ab29 100644 --- a/MediaBrowser.Server.Implementations/IO/FileRefresher.cs +++ b/MediaBrowser.Server.Implementations/IO/FileRefresher.cs @@ -5,6 +5,7 @@ using System.Linq; using System.Threading; using System.Threading.Tasks; using CommonIO; +using MediaBrowser.Common.Events; using MediaBrowser.Common.ScheduledTasks; using MediaBrowser.Controller.Configuration; using MediaBrowser.Controller.Entities; @@ -24,9 +25,14 @@ namespace MediaBrowser.Server.Implementations.IO private readonly List _affectedPaths = new List(); private Timer _timer; private readonly object _timerLock = new object(); + public string Path { get; private set; } + + public event EventHandler Completed; public FileRefresher(string path, IFileSystem fileSystem, IServerConfigurationManager configurationManager, ILibraryManager libraryManager, ITaskManager taskManager, ILogger logger) { + logger.Debug("New file refresher created for {0}", path); + Path = path; _affectedPaths.Add(path); _fileSystem = fileSystem; @@ -36,7 +42,24 @@ namespace MediaBrowser.Server.Implementations.IO Logger = logger; } - private void RestartTimer() + private void AddAffectedPath(string path) + { + if (!_affectedPaths.Contains(path, StringComparer.Ordinal)) + { + _affectedPaths.Add(path); + } + } + + public void AddPath(string path) + { + lock (_timerLock) + { + AddAffectedPath(path); + } + RestartTimer(); + } + + public void RestartTimer() { lock (_timerLock) { @@ -51,6 +74,23 @@ namespace MediaBrowser.Server.Implementations.IO } } + public void ResetPath(string path, string affectedFile) + { + lock (_timerLock) + { + Logger.Debug("Resetting file refresher from {0} to {1}", Path, path); + + Path = path; + AddAffectedPath(path); + + if (!string.IsNullOrWhiteSpace(affectedFile)) + { + AddAffectedPath(affectedFile); + } + } + RestartTimer(); + } + private async void OnTimerCallback(object state) { // Extend the timer as long as any of the paths are still being written to. @@ -64,10 +104,11 @@ namespace MediaBrowser.Server.Implementations.IO Logger.Debug("Timer stopped."); DisposeTimer(); + EventHelper.FireEventIfNotNull(Completed, this, EventArgs.Empty, Logger); try { - await ProcessPathChanges(_affectedPaths).ConfigureAwait(false); + await ProcessPathChanges(_affectedPaths.ToList()).ConfigureAwait(false); } catch (Exception ex) { @@ -130,7 +171,7 @@ namespace MediaBrowser.Server.Implementations.IO { item = LibraryManager.FindByPath(path, null); - path = Path.GetDirectoryName(path); + path = System.IO.Path.GetDirectoryName(path); } if (item != null) @@ -222,7 +263,7 @@ namespace MediaBrowser.Server.Implementations.IO } } - public void DisposeTimer() + private void DisposeTimer() { lock (_timerLock) { diff --git a/MediaBrowser.Server.Implementations/IO/LibraryMonitor.cs b/MediaBrowser.Server.Implementations/IO/LibraryMonitor.cs index 09ca134d1..0de6ff306 100644 --- a/MediaBrowser.Server.Implementations/IO/LibraryMonitor.cs +++ b/MediaBrowser.Server.Implementations/IO/LibraryMonitor.cs @@ -26,13 +26,9 @@ namespace MediaBrowser.Server.Implementations.IO /// private readonly ConcurrentDictionary _fileSystemWatchers = new ConcurrentDictionary(StringComparer.OrdinalIgnoreCase); /// - /// The update timer - /// - private Timer _updateTimer; - /// /// The affected paths /// - private readonly ConcurrentDictionary _affectedPaths = new ConcurrentDictionary(); + private readonly List _activeRefreshers = new List(); /// /// A dynamic list of paths that should be ignored. Added to during our own file sytem modifications. @@ -44,8 +40,8 @@ namespace MediaBrowser.Server.Implementations.IO /// private readonly IReadOnlyList _alwaysIgnoreFiles = new List { - "thumbs.db", - "small.jpg", + "thumbs.db", + "small.jpg", "albumart.jpg", // WMC temp recording directories that will constantly be written to @@ -53,11 +49,6 @@ namespace MediaBrowser.Server.Implementations.IO "TempSBE" }; - /// - /// The timer lock - /// - private readonly object _timerLock = new object(); - /// /// Add the path to our temporary ignore list. Use when writing to a path within our listening scope. /// @@ -463,226 +454,58 @@ namespace MediaBrowser.Server.Implementations.IO if (monitorPath) { // Avoid implicitly captured closure - var affectedPath = path; - _affectedPaths.AddOrUpdate(path, path, (key, oldValue) => affectedPath); - } - - RestartTimer(); - } - - private void RestartTimer() - { - lock (_timerLock) - { - if (_updateTimer == null) - { - _updateTimer = new Timer(TimerStopped, null, TimeSpan.FromSeconds(ConfigurationManager.Configuration.LibraryMonitorDelay), TimeSpan.FromMilliseconds(-1)); - } - else - { - _updateTimer.Change(TimeSpan.FromSeconds(ConfigurationManager.Configuration.LibraryMonitorDelay), TimeSpan.FromMilliseconds(-1)); - } - } - } - - /// - /// Timers the stopped. - /// - /// The state info. - private async void TimerStopped(object stateInfo) - { - // Extend the timer as long as any of the paths are still being written to. - if (_affectedPaths.Any(p => IsFileLocked(p.Key))) - { - Logger.Info("Timer extended."); - RestartTimer(); - return; - } - - Logger.Debug("Timer stopped."); - - DisposeTimer(); - - var paths = _affectedPaths.Keys.ToList(); - _affectedPaths.Clear(); - - try - { - await ProcessPathChanges(paths).ConfigureAwait(false); - } - catch (Exception ex) - { - Logger.ErrorException("Error processing directory changes", ex); + CreateRefresher(path); } } - private bool IsFileLocked(string path) + private void CreateRefresher(string path) { - if (Environment.OSVersion.Platform != PlatformID.Win32NT) - { - // Causing lockups on linux - return false; - } + var parentPath = Path.GetDirectoryName(path); - try + lock (_activeRefreshers) { - var data = _fileSystem.GetFileSystemInfo(path); - - if (!data.Exists - || data.IsDirectory - - // Opening a writable stream will fail with readonly files - || data.Attributes.HasFlag(FileAttributes.ReadOnly)) + var refreshers = _activeRefreshers.ToList(); + foreach (var refresher in refreshers) { - return false; - } - } - catch (IOException) - { - return false; - } - catch (Exception ex) - { - Logger.ErrorException("Error getting file system info for: {0}", ex, path); - return false; - } - - // In order to determine if the file is being written to, we have to request write access - // But if the server only has readonly access, this is going to cause this entire algorithm to fail - // So we'll take a best guess about our access level - var requestedFileAccess = ConfigurationManager.Configuration.SaveLocalMeta - ? FileAccess.ReadWrite - : FileAccess.Read; + // Path is already being refreshed + if (string.Equals(path, refresher.Path, StringComparison.Ordinal)) + { + refresher.RestartTimer(); + return; + } - try - { - using (_fileSystem.GetFileStream(path, FileMode.Open, requestedFileAccess, FileShare.ReadWrite)) - { - if (_updateTimer != null) + // Parent folder is already being refreshed + if (_fileSystem.ContainsSubPath(refresher.Path, path)) { - //file is not locked - return false; + refresher.AddPath(path); + return; } - } - } - catch (DirectoryNotFoundException) - { - // File may have been deleted - return false; - } - catch (FileNotFoundException) - { - // File may have been deleted - return false; - } - catch (IOException) - { - //the file is unavailable because it is: - //still being written to - //or being processed by another thread - //or does not exist (has already been processed) - Logger.Debug("{0} is locked.", path); - return true; - } - catch (Exception ex) - { - Logger.ErrorException("Error determining if file is locked: {0}", ex, path); - return false; - } - return false; - } + // New path is a parent + if (_fileSystem.ContainsSubPath(path, refresher.Path)) + { + refresher.ResetPath(path, null); + return; + } - private void DisposeTimer() - { - lock (_timerLock) - { - if (_updateTimer != null) - { - _updateTimer.Dispose(); - _updateTimer = null; + // Siblings + if (string.Equals(parentPath, Path.GetDirectoryName(refresher.Path), StringComparison.Ordinal)) + { + refresher.ResetPath(parentPath, path); + return; + } } - } - } - - /// - /// Processes the path changes. - /// - /// The paths. - /// Task. - private async Task ProcessPathChanges(List paths) - { - var itemsToRefresh = paths - .Select(GetAffectedBaseItem) - .Where(item => item != null) - .Distinct() - .ToList(); - - foreach (var p in paths) - { - Logger.Info(p + " reports change."); - } - - // If the root folder changed, run the library task so the user can see it - if (itemsToRefresh.Any(i => i is AggregateFolder)) - { - TaskManager.CancelIfRunningAndQueue(); - return; - } - - foreach (var item in itemsToRefresh) - { - Logger.Info(item.Name + " (" + item.Path + ") will be refreshed."); - try - { - await item.ChangedExternally().ConfigureAwait(false); - } - catch (IOException ex) - { - // For now swallow and log. - // Research item: If an IOException occurs, the item may be in a disconnected state (media unavailable) - // Should we remove it from it's parent? - Logger.ErrorException("Error refreshing {0}", ex, item.Name); - } - catch (Exception ex) - { - Logger.ErrorException("Error refreshing {0}", ex, item.Name); - } + var newRefresher = new FileRefresher(path, _fileSystem, ConfigurationManager, LibraryManager, TaskManager, Logger); + newRefresher.Completed += NewRefresher_Completed; + _activeRefreshers.Add(newRefresher); } } - /// - /// Gets the affected base item. - /// - /// The path. - /// BaseItem. - private BaseItem GetAffectedBaseItem(string path) + private void NewRefresher_Completed(object sender, EventArgs e) { - BaseItem item = null; - - while (item == null && !string.IsNullOrEmpty(path)) - { - item = LibraryManager.FindByPath(path, null); - - path = Path.GetDirectoryName(path); - } - - if (item != null) - { - // If the item has been deleted find the first valid parent that still exists - while (!_fileSystem.DirectoryExists(item.Path) && !_fileSystem.FileExists(item.Path)) - { - item = item.GetParent(); - - if (item == null) - { - break; - } - } - } - - return item; + var refresher = (FileRefresher)sender; + DisposeRefresher(refresher); } /// @@ -713,10 +536,29 @@ namespace MediaBrowser.Server.Implementations.IO watcher.Dispose(); } - DisposeTimer(); - _fileSystemWatchers.Clear(); - _affectedPaths.Clear(); + DisposeRefreshers(); + } + + private void DisposeRefresher(FileRefresher refresher) + { + lock (_activeRefreshers) + { + refresher.Dispose(); + _activeRefreshers.Remove(refresher); + } + } + + private void DisposeRefreshers() + { + lock (_activeRefreshers) + { + foreach (var refresher in _activeRefreshers.ToList()) + { + refresher.Dispose(); + } + _activeRefreshers.Clear(); + } } /// -- cgit v1.2.3 From 3c29feca5fe12a9968fc0d58697faaab2dab7308 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Thu, 26 May 2016 23:46:21 -0400 Subject: comment --- MediaBrowser.Server.Implementations/IO/LibraryMonitor.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'MediaBrowser.Server.Implementations') diff --git a/MediaBrowser.Server.Implementations/IO/LibraryMonitor.cs b/MediaBrowser.Server.Implementations/IO/LibraryMonitor.cs index 0de6ff306..0690d62dd 100644 --- a/MediaBrowser.Server.Implementations/IO/LibraryMonitor.cs +++ b/MediaBrowser.Server.Implementations/IO/LibraryMonitor.cs @@ -488,7 +488,7 @@ namespace MediaBrowser.Server.Implementations.IO return; } - // Siblings + // They are siblings. Rebase the refresher to the parent folder. if (string.Equals(parentPath, Path.GetDirectoryName(refresher.Path), StringComparison.Ordinal)) { refresher.ResetPath(parentPath, path); -- cgit v1.2.3 From e5655d32f122b4840057aac30bba24d2a94c36fe Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Fri, 27 May 2016 13:17:57 -0400 Subject: fix timestamps in hls subtitles --- MediaBrowser.Api/Subtitles/SubtitleService.cs | 6 +++++- MediaBrowser.Controller/MediaEncoding/ISubtitleEncoder.cs | 8 +------- MediaBrowser.MediaEncoding/Subtitles/SubtitleEncoder.cs | 6 ++++-- MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs | 2 +- 4 files changed, 11 insertions(+), 11 deletions(-) (limited to 'MediaBrowser.Server.Implementations') diff --git a/MediaBrowser.Api/Subtitles/SubtitleService.cs b/MediaBrowser.Api/Subtitles/SubtitleService.cs index c2183ad7b..1382527e2 100644 --- a/MediaBrowser.Api/Subtitles/SubtitleService.cs +++ b/MediaBrowser.Api/Subtitles/SubtitleService.cs @@ -98,6 +98,9 @@ namespace MediaBrowser.Api.Subtitles [ApiMember(Name = "EndPositionTicks", Description = "EndPositionTicks", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")] public long? EndPositionTicks { get; set; } + + [ApiMember(Name = "CopyTimestamps", Description = "CopyTimestamps", IsRequired = false, DataType = "bool", ParameterType = "query", Verb = "GET")] + public bool CopyTimestamps { get; set; } } [Route("/Videos/{Id}/{MediaSourceId}/Subtitles/{Index}/subtitles.m3u8", "GET", Summary = "Gets an HLS subtitle playlist.")] @@ -175,7 +178,7 @@ namespace MediaBrowser.Api.Subtitles var endPositionTicks = Math.Min(runtime, positionTicks + segmentLengthTicks); - var url = string.Format("stream.vtt?StartPositionTicks={0}&EndPositionTicks={1}&api_key={2}", + var url = string.Format("stream.vtt?CopyTimestamps=true,StartPositionTicks={0}&EndPositionTicks={1}&api_key={2}", positionTicks.ToString(CultureInfo.InvariantCulture), endPositionTicks.ToString(CultureInfo.InvariantCulture), accessToken); @@ -222,6 +225,7 @@ namespace MediaBrowser.Api.Subtitles request.Format, request.StartPositionTicks, request.EndPositionTicks, + request.CopyTimestamps, CancellationToken.None).ConfigureAwait(false); } diff --git a/MediaBrowser.Controller/MediaEncoding/ISubtitleEncoder.cs b/MediaBrowser.Controller/MediaEncoding/ISubtitleEncoder.cs index e538b84d8..44489cbf5 100644 --- a/MediaBrowser.Controller/MediaEncoding/ISubtitleEncoder.cs +++ b/MediaBrowser.Controller/MediaEncoding/ISubtitleEncoder.cs @@ -10,13 +10,6 @@ namespace MediaBrowser.Controller.MediaEncoding /// /// Gets the subtitles. /// - /// The item identifier. - /// The media source identifier. - /// Index of the subtitle stream. - /// The output format. - /// The start time ticks. - /// The end time ticks. - /// The cancellation token. /// Task{Stream}. Task GetSubtitles(string itemId, string mediaSourceId, @@ -24,6 +17,7 @@ namespace MediaBrowser.Controller.MediaEncoding string outputFormat, long startTimeTicks, long? endTimeTicks, + bool preserveOriginalTimestamps, CancellationToken cancellationToken); /// diff --git a/MediaBrowser.MediaEncoding/Subtitles/SubtitleEncoder.cs b/MediaBrowser.MediaEncoding/Subtitles/SubtitleEncoder.cs index 8c33cc7c0..25adbcdb0 100644 --- a/MediaBrowser.MediaEncoding/Subtitles/SubtitleEncoder.cs +++ b/MediaBrowser.MediaEncoding/Subtitles/SubtitleEncoder.cs @@ -58,6 +58,7 @@ namespace MediaBrowser.MediaEncoding.Subtitles string outputFormat, long startTimeTicks, long? endTimeTicks, + bool preserveOriginalTimestamps, CancellationToken cancellationToken) { var ms = new MemoryStream(); @@ -68,7 +69,7 @@ namespace MediaBrowser.MediaEncoding.Subtitles var trackInfo = reader.Parse(stream, cancellationToken); - FilterEvents(trackInfo, startTimeTicks, endTimeTicks, false); + FilterEvents(trackInfo, startTimeTicks, endTimeTicks, preserveOriginalTimestamps); var writer = GetWriter(outputFormat); @@ -116,6 +117,7 @@ namespace MediaBrowser.MediaEncoding.Subtitles string outputFormat, long startTimeTicks, long? endTimeTicks, + bool preserveOriginalTimestamps, CancellationToken cancellationToken) { var subtitle = await GetSubtitleStream(itemId, mediaSourceId, subtitleStreamIndex, cancellationToken) @@ -130,7 +132,7 @@ namespace MediaBrowser.MediaEncoding.Subtitles using (var stream = subtitle.Item1) { - return await ConvertSubtitles(stream, inputFormat, outputFormat, startTimeTicks, endTimeTicks, cancellationToken).ConfigureAwait(false); + return await ConvertSubtitles(stream, inputFormat, outputFormat, startTimeTicks, endTimeTicks, preserveOriginalTimestamps, cancellationToken).ConfigureAwait(false); } } diff --git a/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs b/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs index bbba06870..398dcc86b 100644 --- a/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs +++ b/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs @@ -748,7 +748,7 @@ namespace MediaBrowser.Server.Implementations.Sync _fileSystem.CreateDirectory(Path.GetDirectoryName(path)); - using (var stream = await _subtitleEncoder.GetSubtitles(streamInfo.ItemId, streamInfo.MediaSourceId, subtitleStreamIndex, subtitleStreamInfo.Format, 0, null, cancellationToken).ConfigureAwait(false)) + using (var stream = await _subtitleEncoder.GetSubtitles(streamInfo.ItemId, streamInfo.MediaSourceId, subtitleStreamIndex, subtitleStreamInfo.Format, 0, null, false, cancellationToken).ConfigureAwait(false)) { using (var fs = _fileSystem.GetFileStream(path, FileMode.Create, FileAccess.Write, FileShare.Read, true)) { -- cgit v1.2.3 From 2d80f5b807207e8deacdb5ea021185a0c40c8677 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Fri, 27 May 2016 13:19:20 -0400 Subject: update timer defaults --- MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'MediaBrowser.Server.Implementations') diff --git a/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs b/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs index bbdc4ab0d..e126e5411 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs @@ -1959,10 +1959,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv var defaults = await GetNewTimerDefaultsInternal(cancellationToken, program).ConfigureAwait(false); var info = _tvDtoService.GetSeriesTimerInfoDto(defaults.Item1, defaults.Item2, null); - info.Days = new List - { - program.StartDate.ToLocalTime().DayOfWeek - }; + info.Days = defaults.Item1.Days; info.DayPattern = _tvDtoService.GetDayPattern(info.Days); -- cgit v1.2.3 From cba6c99d548ba8735de3ffdbc2f6c710a00f096b Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sun, 29 May 2016 14:42:18 -0400 Subject: add null check to sync process --- MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'MediaBrowser.Server.Implementations') diff --git a/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs b/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs index 398dcc86b..886308d43 100644 --- a/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs +++ b/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs @@ -483,6 +483,11 @@ namespace MediaBrowser.Server.Implementations.Sync private async Task ProcessJobItem(SyncJobItem jobItem, bool enableConversion, IProgress progress, CancellationToken cancellationToken) { + if (jobItem == null) + { + throw new ArgumentNullException("jobItem"); + } + var item = _libraryManager.GetItemById(jobItem.ItemId); if (item == null) { -- cgit v1.2.3 From c5e5aba027ee889ac6347ce464e739280cac5da9 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sun, 29 May 2016 14:42:28 -0400 Subject: update index --- MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'MediaBrowser.Server.Implementations') diff --git a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs index b1f43d20f..2775389a2 100644 --- a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs +++ b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs @@ -248,7 +248,7 @@ namespace MediaBrowser.Server.Implementations.Persistence "create index if not exists idx_PresentationUniqueKey on TypedBaseItems(PresentationUniqueKey)", "create index if not exists idx_Type on TypedBaseItems(Type)", "create index if not exists idx_TopParentId on TypedBaseItems(TopParentId)", - //"create index if not exists idx_TypeTopParentId on TypedBaseItems(Type,TopParentId)" + "create index if not exists idx_TypeTopParentId on TypedBaseItems(Type,TopParentId)" }; _connection.RunQueries(postQueries, Logger); -- cgit v1.2.3 From bed6d6bd38be118f9bb8edd79beade0d14da54bd Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sun, 29 May 2016 14:42:39 -0400 Subject: update recording default values --- .../LiveTv/EmbyTV/EmbyTV.cs | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) (limited to 'MediaBrowser.Server.Implementations') diff --git a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs index 25822a81b..6e5e8298f 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs @@ -548,9 +548,20 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV { PostPaddingSeconds = Math.Max(config.PostPaddingSeconds, 0), PrePaddingSeconds = Math.Max(config.PrePaddingSeconds, 0), - RecordAnyChannel = false, - RecordAnyTime = false, - RecordNewOnly = false + RecordAnyChannel = true, + RecordAnyTime = true, + RecordNewOnly = false, + + Days = new List + { + DayOfWeek.Sunday, + DayOfWeek.Monday, + DayOfWeek.Tuesday, + DayOfWeek.Wednesday, + DayOfWeek.Thursday, + DayOfWeek.Friday, + DayOfWeek.Saturday + } }; if (program != null) @@ -1215,6 +1226,8 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV if (!seriesTimer.RecordAnyTime) { allPrograms = allPrograms.Where(epg => Math.Abs(seriesTimer.StartDate.TimeOfDay.Ticks - epg.StartDate.TimeOfDay.Ticks) < TimeSpan.FromMinutes(5).Ticks); + + allPrograms = allPrograms.Where(i => seriesTimer.Days.Contains(i.StartDate.ToLocalTime().DayOfWeek)); } if (seriesTimer.RecordNewOnly) @@ -1227,8 +1240,6 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV allPrograms = allPrograms.Where(epg => string.Equals(epg.ChannelId, seriesTimer.ChannelId, StringComparison.OrdinalIgnoreCase)); } - allPrograms = allPrograms.Where(i => seriesTimer.Days.Contains(i.StartDate.ToLocalTime().DayOfWeek)); - if (string.IsNullOrWhiteSpace(seriesTimer.SeriesId)) { _logger.Error("seriesTimer.SeriesId is null. Cannot find programs for series"); -- cgit v1.2.3 From ec663b7811d96b816be925e06e3788791bbda299 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sun, 29 May 2016 17:02:32 -0400 Subject: fix search typo --- MediaBrowser.Server.Implementations/Library/SearchEngine.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'MediaBrowser.Server.Implementations') diff --git a/MediaBrowser.Server.Implementations/Library/SearchEngine.cs b/MediaBrowser.Server.Implementations/Library/SearchEngine.cs index e271fbcb2..262178790 100644 --- a/MediaBrowser.Server.Implementations/Library/SearchEngine.cs +++ b/MediaBrowser.Server.Implementations/Library/SearchEngine.cs @@ -122,7 +122,7 @@ namespace MediaBrowser.Server.Implementations.Library AddIfMissing(excludeItemTypes, typeof(MusicGenre).Name); } - if (query.IncludePeople && (includeItemTypes.Count == 0 || includeItemTypes.Contains("People", StringComparer.OrdinalIgnoreCase))) + if (query.IncludePeople && (includeItemTypes.Count == 0 || includeItemTypes.Contains("People", StringComparer.OrdinalIgnoreCase) || includeItemTypes.Contains("Person", StringComparer.OrdinalIgnoreCase))) { if (!query.IncludeMedia) { -- cgit v1.2.3 From b6b6b85bf4d8bb6f58ea860a622dbc8902721b68 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sun, 29 May 2016 17:04:49 -0400 Subject: remove x-frame-options --- MediaBrowser.Model/Configuration/ServerConfiguration.cs | 3 --- .../HttpServer/HttpListenerHost.cs | 2 +- MediaBrowser.Server.Implementations/HttpServer/ResponseFilter.cs | 9 +-------- 3 files changed, 2 insertions(+), 12 deletions(-) (limited to 'MediaBrowser.Server.Implementations') diff --git a/MediaBrowser.Model/Configuration/ServerConfiguration.cs b/MediaBrowser.Model/Configuration/ServerConfiguration.cs index 1971b812e..df0e42869 100644 --- a/MediaBrowser.Model/Configuration/ServerConfiguration.cs +++ b/MediaBrowser.Model/Configuration/ServerConfiguration.cs @@ -184,8 +184,6 @@ namespace MediaBrowser.Model.Configuration public bool EnableVideoArchiveFiles { get; set; } public int RemoteClientBitrateLimit { get; set; } - public bool DenyIFrameEmbedding { get; set; } - public AutoOnOff EnableLibraryMonitor { get; set; } public int SharingExpirationDays { get; set; } @@ -222,7 +220,6 @@ namespace MediaBrowser.Model.Configuration EnableAnonymousUsageReporting = true; EnableAutomaticRestart = true; - DenyIFrameEmbedding = true; EnableUPnP = true; SharingExpirationDays = 30; diff --git a/MediaBrowser.Server.Implementations/HttpServer/HttpListenerHost.cs b/MediaBrowser.Server.Implementations/HttpServer/HttpListenerHost.cs index c5cb810e5..f091f0f1f 100644 --- a/MediaBrowser.Server.Implementations/HttpServer/HttpListenerHost.cs +++ b/MediaBrowser.Server.Implementations/HttpServer/HttpListenerHost.cs @@ -106,7 +106,7 @@ namespace MediaBrowser.Server.Implementations.HttpServer } }); - HostContext.GlobalResponseFilters.Add(new ResponseFilter(_logger, () => _config.Configuration.DenyIFrameEmbedding).FilterResponse); + HostContext.GlobalResponseFilters.Add(new ResponseFilter(_logger).FilterResponse); } public override void OnAfterInit() diff --git a/MediaBrowser.Server.Implementations/HttpServer/ResponseFilter.cs b/MediaBrowser.Server.Implementations/HttpServer/ResponseFilter.cs index f993d4437..ee05702f4 100644 --- a/MediaBrowser.Server.Implementations/HttpServer/ResponseFilter.cs +++ b/MediaBrowser.Server.Implementations/HttpServer/ResponseFilter.cs @@ -12,12 +12,10 @@ namespace MediaBrowser.Server.Implementations.HttpServer { private static readonly CultureInfo UsCulture = new CultureInfo("en-US"); private readonly ILogger _logger; - private readonly Func _denyIframeEmbedding; - public ResponseFilter(ILogger logger, Func denyIframeEmbedding) + public ResponseFilter(ILogger logger) { _logger = logger; - _denyIframeEmbedding = denyIframeEmbedding; } /// @@ -31,11 +29,6 @@ namespace MediaBrowser.Server.Implementations.HttpServer // Try to prevent compatibility view res.AddHeader("X-UA-Compatible", "IE=Edge"); - if (_denyIframeEmbedding()) - { - res.AddHeader("X-Frame-Options", "SAMEORIGIN"); - } - var exception = dto as Exception; if (exception != null) -- cgit v1.2.3 From 0619717f38a26879b08d18029c86847e88b3df8d Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Mon, 30 May 2016 12:08:46 -0400 Subject: ignore socket error --- MediaBrowser.Server.Implementations/Session/SessionManager.cs | 5 +++++ .../Session/SessionWebSocketListener.cs | 7 ++++++- 2 files changed, 11 insertions(+), 1 deletion(-) (limited to 'MediaBrowser.Server.Implementations') diff --git a/MediaBrowser.Server.Implementations/Session/SessionManager.cs b/MediaBrowser.Server.Implementations/Session/SessionManager.cs index 77843ef6b..0dabcac4b 100644 --- a/MediaBrowser.Server.Implementations/Session/SessionManager.cs +++ b/MediaBrowser.Server.Implementations/Session/SessionManager.cs @@ -1748,6 +1748,11 @@ namespace MediaBrowser.Server.Implementations.Session public void ReportNowViewingItem(string sessionId, string itemId) { + if (string.IsNullOrWhiteSpace(itemId)) + { + throw new ArgumentNullException("itemId"); + } + var item = _libraryManager.GetItemById(new Guid(itemId)); var info = GetItemInfo(item, null, null); diff --git a/MediaBrowser.Server.Implementations/Session/SessionWebSocketListener.cs b/MediaBrowser.Server.Implementations/Session/SessionWebSocketListener.cs index 602bc4876..ddd7ba53a 100644 --- a/MediaBrowser.Server.Implementations/Session/SessionWebSocketListener.cs +++ b/MediaBrowser.Server.Implementations/Session/SessionWebSocketListener.cs @@ -230,7 +230,12 @@ namespace MediaBrowser.Server.Implementations.Session { var vals = message.Data.Split('|'); - _sessionManager.ReportNowViewingItem(session.Id, vals[1]); + var itemId = vals[1]; + + if (!string.IsNullOrWhiteSpace(itemId)) + { + _sessionManager.ReportNowViewingItem(session.Id, itemId); + } } } -- cgit v1.2.3 From ca100ff2d13b0bf885826e02e7c1ed6a4496694e Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Mon, 30 May 2016 12:22:31 -0400 Subject: add null checks on session & device creation --- MediaBrowser.Server.Implementations/Devices/DeviceManager.cs | 5 +++++ MediaBrowser.Server.Implementations/Session/SessionManager.cs | 4 ++++ 2 files changed, 9 insertions(+) (limited to 'MediaBrowser.Server.Implementations') diff --git a/MediaBrowser.Server.Implementations/Devices/DeviceManager.cs b/MediaBrowser.Server.Implementations/Devices/DeviceManager.cs index 6b1af8d2d..c3db9140c 100644 --- a/MediaBrowser.Server.Implementations/Devices/DeviceManager.cs +++ b/MediaBrowser.Server.Implementations/Devices/DeviceManager.cs @@ -51,6 +51,11 @@ namespace MediaBrowser.Server.Implementations.Devices public async Task RegisterDevice(string reportedId, string name, string appName, string appVersion, string usedByUserId) { + if (string.IsNullOrWhiteSpace(reportedId)) + { + throw new ArgumentNullException("reportedId"); + } + var device = GetDevice(reportedId) ?? new DeviceInfo { Id = reportedId diff --git a/MediaBrowser.Server.Implementations/Session/SessionManager.cs b/MediaBrowser.Server.Implementations/Session/SessionManager.cs index 0dabcac4b..4386b785a 100644 --- a/MediaBrowser.Server.Implementations/Session/SessionManager.cs +++ b/MediaBrowser.Server.Implementations/Session/SessionManager.cs @@ -404,6 +404,10 @@ namespace MediaBrowser.Server.Implementations.Session /// SessionInfo. private async Task GetSessionInfo(string appName, string appVersion, string deviceId, string deviceName, string remoteEndPoint, User user) { + if (string.IsNullOrWhiteSpace(deviceId)) + { + throw new ArgumentNullException("deviceId"); + } var key = GetSessionKey(appName, deviceId); await _sessionLock.WaitAsync(CancellationToken.None).ConfigureAwait(false); -- cgit v1.2.3 From f091e6f55f741e2ebd9a818a837c1950c49c1967 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Mon, 30 May 2016 14:16:44 -0400 Subject: stub out tv movies in suggestions --- MediaBrowser.Api/Movies/MoviesService.cs | 27 +++++++++------- .../Persistence/SqliteItemRepository.cs | 36 +++++++++++++++++++++- 2 files changed, 51 insertions(+), 12 deletions(-) (limited to 'MediaBrowser.Server.Implementations') diff --git a/MediaBrowser.Api/Movies/MoviesService.cs b/MediaBrowser.Api/Movies/MoviesService.cs index 8a6e5b8df..b06007c78 100644 --- a/MediaBrowser.Api/Movies/MoviesService.cs +++ b/MediaBrowser.Api/Movies/MoviesService.cs @@ -14,6 +14,7 @@ using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; +using MediaBrowser.Controller.LiveTv; namespace MediaBrowser.Api.Movies { @@ -132,13 +133,15 @@ namespace MediaBrowser.Api.Movies var query = new InternalItemsQuery(user) { - IncludeItemTypes = new[] { typeof(Movie).Name } + IncludeItemTypes = new[] + { + typeof(Movie).Name, + typeof(Trailer).Name, + //typeof(LiveTvProgram).Name + }, + // IsMovie = true }; - var includeList = query.IncludeItemTypes.ToList(); - includeList.Add(typeof(Trailer).Name); - query.IncludeItemTypes = includeList.ToArray(); - var parentIds = string.IsNullOrWhiteSpace(request.ParentId) ? new string[] { } : new[] { request.ParentId }; var movies = _libraryManager.GetItemList(query, parentIds) .OrderBy(i => (int)i.SourceType); @@ -179,16 +182,18 @@ namespace MediaBrowser.Api.Movies var item = string.IsNullOrEmpty(request.Id) ? (!string.IsNullOrWhiteSpace(request.UserId) ? user.RootFolder : _libraryManager.RootFolder) : _libraryManager.GetItemById(request.Id); - + var query = new InternalItemsQuery(user) { - IncludeItemTypes = new[] { typeof(Movie).Name } + IncludeItemTypes = new[] + { + typeof(Movie).Name, + typeof(Trailer).Name, + //typeof(LiveTvProgram).Name + }, + //IsMovie = true }; - var includeList = query.IncludeItemTypes.ToList(); - includeList.Add(typeof(Trailer).Name); - query.IncludeItemTypes = includeList.ToArray(); - var list = _libraryManager.GetItemList(query) .OrderBy(i => (int)i.SourceType) .DistinctBy(i => i.GetProviderId(MetadataProviders.Imdb) ?? Guid.NewGuid().ToString("N")) diff --git a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs index 2775389a2..1de0ea710 100644 --- a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs +++ b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs @@ -2132,7 +2132,41 @@ namespace MediaBrowser.Server.Implementations.Persistence } if (query.IsMovie.HasValue) { - whereClauses.Add("IsMovie=@IsMovie"); + var alternateTypes = new List(); + if (query.IncludeItemTypes.Length == 0 || query.IncludeItemTypes.Contains(typeof(Movie).Name)) + { + alternateTypes.Add(typeof(Movie).FullName); + } + if (query.IncludeItemTypes.Length == 0 || query.IncludeItemTypes.Contains(typeof(Trailer).Name)) + { + alternateTypes.Add(typeof(Trailer).FullName); + } + + if (alternateTypes.Count == 0) + { + whereClauses.Add("IsMovie=@IsMovie"); + } + else + { + if (query.IsMovie.Value) + { + var typeClauses = new List(); + var typeIndex = 0; + foreach (var type in alternateTypes) + { + var paramName = "@AlternateType" + typeIndex.ToString(CultureInfo.InvariantCulture); + typeClauses.Add("Type=" + paramName); + cmd.Parameters.Add(cmd, paramName, DbType.String).Value = type; + typeIndex++; + } + + whereClauses.Add("(IsMovie=@IsMovie OR " + string.Join(" OR ", typeClauses.ToArray()) + ")"); + } + else + { + whereClauses.Add("(IsMovie is null OR IsMovie=@IsMovie)"); + } + } cmd.Parameters.Add(cmd, "@IsMovie", DbType.Boolean).Value = query.IsMovie; } if (query.IsKids.HasValue) -- cgit v1.2.3 From 977f62336be3c54fc33b3476d80d3cce4c0b244c Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Tue, 31 May 2016 14:07:54 -0400 Subject: update storage of genres, studios, tags, & keywords --- MediaBrowser.Api/ItemUpdateService.cs | 6 +--- MediaBrowser.Api/SimilarItemsHelper.cs | 8 +----- MediaBrowser.Controller/Entities/BaseItem.cs | 3 ++ MediaBrowser.Controller/Entities/IHasKeywords.cs | 31 -------------------- .../Entities/InternalItemsQuery.cs | 2 ++ .../Entities/KeywordExtensions.cs | 21 ++++++++++++++ MediaBrowser.Controller/Entities/Movies/BoxSet.cs | 9 +----- MediaBrowser.Controller/Entities/Movies/Movie.cs | 4 +-- MediaBrowser.Controller/Entities/Trailer.cs | 4 +-- .../MediaBrowser.Controller.csproj | 2 +- .../Providers/BaseItemXmlParser.cs | 8 ++---- .../Savers/XmlSaverHelpers.cs | 18 +++++------- MediaBrowser.Providers/Manager/ProviderUtils.cs | 10 ++----- .../Movies/GenericMovieDbInfo.cs | 6 +--- .../Dto/DtoService.cs | 11 +------- .../Intros/DefaultIntroProvider.cs | 8 +----- .../Persistence/SqliteItemRepository.cs | 33 +++++++++++++++++----- .../Native/SqliteExtensions.cs | 2 +- .../Native/SqliteExtensions.cs | 2 +- MediaBrowser.XbmcMetadata/Parsers/BaseNfoParser.cs | 8 ++---- MediaBrowser.XbmcMetadata/Savers/BaseNfoSaver.cs | 8 ++---- 21 files changed, 78 insertions(+), 126 deletions(-) delete mode 100644 MediaBrowser.Controller/Entities/IHasKeywords.cs create mode 100644 MediaBrowser.Controller/Entities/KeywordExtensions.cs (limited to 'MediaBrowser.Server.Implementations') diff --git a/MediaBrowser.Api/ItemUpdateService.cs b/MediaBrowser.Api/ItemUpdateService.cs index 5bb4ed5f0..36e8a504c 100644 --- a/MediaBrowser.Api/ItemUpdateService.cs +++ b/MediaBrowser.Api/ItemUpdateService.cs @@ -298,11 +298,7 @@ namespace MediaBrowser.Api hasShortOverview.ShortOverview = request.ShortOverview; } - var hasKeywords = item as IHasKeywords; - if (hasKeywords != null) - { - hasKeywords.Keywords = request.Keywords; - } + item.Keywords = request.Keywords; if (request.Studios != null) { diff --git a/MediaBrowser.Api/SimilarItemsHelper.cs b/MediaBrowser.Api/SimilarItemsHelper.cs index 277bba1dd..76bc16a96 100644 --- a/MediaBrowser.Api/SimilarItemsHelper.cs +++ b/MediaBrowser.Api/SimilarItemsHelper.cs @@ -127,13 +127,7 @@ namespace MediaBrowser.Api private static IEnumerable GetKeywords(BaseItem item) { - var hasTags = item as IHasKeywords; - if (hasTags != null) - { - return hasTags.Keywords; - } - - return new List(); + return item.Keywords; } /// diff --git a/MediaBrowser.Controller/Entities/BaseItem.cs b/MediaBrowser.Controller/Entities/BaseItem.cs index 2a00ce992..78f1828ea 100644 --- a/MediaBrowser.Controller/Entities/BaseItem.cs +++ b/MediaBrowser.Controller/Entities/BaseItem.cs @@ -37,6 +37,7 @@ namespace MediaBrowser.Controller.Entities { protected BaseItem() { + Keywords = new List(); Tags = new List(); Genres = new List(); Studios = new List(); @@ -811,6 +812,8 @@ namespace MediaBrowser.Controller.Entities [IgnoreDataMember] public List Tags { get; set; } + public List Keywords { get; set; } + /// /// Gets or sets the home page URL. /// diff --git a/MediaBrowser.Controller/Entities/IHasKeywords.cs b/MediaBrowser.Controller/Entities/IHasKeywords.cs deleted file mode 100644 index ab9eb4aee..000000000 --- a/MediaBrowser.Controller/Entities/IHasKeywords.cs +++ /dev/null @@ -1,31 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; - -namespace MediaBrowser.Controller.Entities -{ - public interface IHasKeywords - { - /// - /// Gets or sets the keywords. - /// - /// The keywords. - List Keywords { get; set; } - } - - public static class KeywordExtensions - { - public static void AddKeyword(this IHasKeywords item, string name) - { - if (string.IsNullOrWhiteSpace(name)) - { - throw new ArgumentNullException("name"); - } - - if (!item.Keywords.Contains(name, StringComparer.OrdinalIgnoreCase)) - { - item.Keywords.Add(name); - } - } - } -} diff --git a/MediaBrowser.Controller/Entities/InternalItemsQuery.cs b/MediaBrowser.Controller/Entities/InternalItemsQuery.cs index 823f4066c..7e38d7ed9 100644 --- a/MediaBrowser.Controller/Entities/InternalItemsQuery.cs +++ b/MediaBrowser.Controller/Entities/InternalItemsQuery.cs @@ -33,6 +33,7 @@ namespace MediaBrowser.Controller.Entities public string[] ExcludeTags { get; set; } public string[] ExcludeInheritedTags { get; set; } public string[] Genres { get; set; } + public string[] Keywords { get; set; } public bool? IsMissing { get; set; } public bool? IsUnaired { get; set; } @@ -151,6 +152,7 @@ namespace MediaBrowser.Controller.Entities OfficialRatings = new string[] { }; SortBy = new string[] { }; MediaTypes = new string[] { }; + Keywords = new string[] { }; IncludeItemTypes = new string[] { }; ExcludeItemTypes = new string[] { }; Genres = new string[] { }; diff --git a/MediaBrowser.Controller/Entities/KeywordExtensions.cs b/MediaBrowser.Controller/Entities/KeywordExtensions.cs new file mode 100644 index 000000000..5c9afdf3d --- /dev/null +++ b/MediaBrowser.Controller/Entities/KeywordExtensions.cs @@ -0,0 +1,21 @@ +using System; +using System.Linq; + +namespace MediaBrowser.Controller.Entities +{ + public static class KeywordExtensions + { + public static void AddKeyword(this BaseItem item, string name) + { + if (string.IsNullOrWhiteSpace(name)) + { + throw new ArgumentNullException("name"); + } + + if (!item.Keywords.Contains(name, StringComparer.OrdinalIgnoreCase)) + { + item.Keywords.Add(name); + } + } + } +} diff --git a/MediaBrowser.Controller/Entities/Movies/BoxSet.cs b/MediaBrowser.Controller/Entities/Movies/BoxSet.cs index 09a9d97bc..4effc162e 100644 --- a/MediaBrowser.Controller/Entities/Movies/BoxSet.cs +++ b/MediaBrowser.Controller/Entities/Movies/BoxSet.cs @@ -15,7 +15,7 @@ namespace MediaBrowser.Controller.Entities.Movies /// /// Class BoxSet /// - public class BoxSet : Folder, IHasTrailers, IHasKeywords, IHasDisplayOrder, IHasLookupInfo, IHasShares + public class BoxSet : Folder, IHasTrailers, IHasDisplayOrder, IHasLookupInfo, IHasShares { public List Shares { get; set; } @@ -26,7 +26,6 @@ namespace MediaBrowser.Controller.Entities.Movies RemoteTrailerIds = new List(); DisplayOrder = ItemSortBy.PremiereDate; - Keywords = new List(); Shares = new List(); } @@ -47,12 +46,6 @@ namespace MediaBrowser.Controller.Entities.Movies /// The remote trailers. public List RemoteTrailers { get; set; } - /// - /// Gets or sets the tags. - /// - /// The tags. - public List Keywords { get; set; } - /// /// Gets or sets the display order. /// diff --git a/MediaBrowser.Controller/Entities/Movies/Movie.cs b/MediaBrowser.Controller/Entities/Movies/Movie.cs index 605221dcd..c7a833c58 100644 --- a/MediaBrowser.Controller/Entities/Movies/Movie.cs +++ b/MediaBrowser.Controller/Entities/Movies/Movie.cs @@ -15,7 +15,7 @@ namespace MediaBrowser.Controller.Entities.Movies /// /// Class Movie /// - public class Movie : Video, IHasCriticRating, IHasSpecialFeatures, IHasProductionLocations, IHasBudget, IHasKeywords, IHasTrailers, IHasThemeMedia, IHasTaglines, IHasAwards, IHasMetascore, IHasLookupInfo, ISupportsBoxSetGrouping, IHasOriginalTitle + public class Movie : Video, IHasCriticRating, IHasSpecialFeatures, IHasProductionLocations, IHasBudget, IHasTrailers, IHasThemeMedia, IHasTaglines, IHasAwards, IHasMetascore, IHasLookupInfo, ISupportsBoxSetGrouping, IHasOriginalTitle { public List SpecialFeatureIds { get; set; } @@ -32,7 +32,6 @@ namespace MediaBrowser.Controller.Entities.Movies ThemeSongIds = new List(); ThemeVideoIds = new List(); Taglines = new List(); - Keywords = new List(); ProductionLocations = new List(); } @@ -42,7 +41,6 @@ namespace MediaBrowser.Controller.Entities.Movies public List LocalTrailerIds { get; set; } public List RemoteTrailerIds { get; set; } - public List Keywords { get; set; } public List RemoteTrailers { get; set; } diff --git a/MediaBrowser.Controller/Entities/Trailer.cs b/MediaBrowser.Controller/Entities/Trailer.cs index 74645bbe9..eab5ab679 100644 --- a/MediaBrowser.Controller/Entities/Trailer.cs +++ b/MediaBrowser.Controller/Entities/Trailer.cs @@ -12,7 +12,7 @@ namespace MediaBrowser.Controller.Entities /// /// Class Trailer /// - public class Trailer : Video, IHasCriticRating, IHasProductionLocations, IHasBudget, IHasKeywords, IHasTaglines, IHasMetascore, IHasOriginalTitle, IHasLookupInfo + public class Trailer : Video, IHasCriticRating, IHasProductionLocations, IHasBudget, IHasTaglines, IHasMetascore, IHasOriginalTitle, IHasLookupInfo { public List ProductionLocations { get; set; } @@ -31,8 +31,6 @@ namespace MediaBrowser.Controller.Entities public List RemoteTrailers { get; set; } - public List Keywords { get; set; } - [IgnoreDataMember] public bool IsLocalTrailer { diff --git a/MediaBrowser.Controller/MediaBrowser.Controller.csproj b/MediaBrowser.Controller/MediaBrowser.Controller.csproj index 4d9999b37..b15bb94c7 100644 --- a/MediaBrowser.Controller/MediaBrowser.Controller.csproj +++ b/MediaBrowser.Controller/MediaBrowser.Controller.csproj @@ -142,7 +142,7 @@ - + diff --git a/MediaBrowser.Controller/Providers/BaseItemXmlParser.cs b/MediaBrowser.Controller/Providers/BaseItemXmlParser.cs index 1014fc2ee..aaa440060 100644 --- a/MediaBrowser.Controller/Providers/BaseItemXmlParser.cs +++ b/MediaBrowser.Controller/Providers/BaseItemXmlParser.cs @@ -816,11 +816,7 @@ namespace MediaBrowser.Controller.Providers { using (var subtree = reader.ReadSubtree()) { - var hasTags = item as IHasKeywords; - if (hasTags != null) - { - FetchFromKeywordsNode(subtree, hasTags); - } + FetchFromKeywordsNode(subtree, item); } break; } @@ -1099,7 +1095,7 @@ namespace MediaBrowser.Controller.Providers } } - private void FetchFromKeywordsNode(XmlReader reader, IHasKeywords item) + private void FetchFromKeywordsNode(XmlReader reader, BaseItem item) { reader.MoveToContent(); diff --git a/MediaBrowser.LocalMetadata/Savers/XmlSaverHelpers.cs b/MediaBrowser.LocalMetadata/Savers/XmlSaverHelpers.cs index be81d21d2..ca19b403a 100644 --- a/MediaBrowser.LocalMetadata/Savers/XmlSaverHelpers.cs +++ b/MediaBrowser.LocalMetadata/Savers/XmlSaverHelpers.cs @@ -609,20 +609,16 @@ namespace MediaBrowser.LocalMetadata.Savers } } - var hasKeywords = item as IHasKeywords; - if (hasKeywords != null) + if (item.Keywords.Count > 0) { - if (hasKeywords.Keywords.Count > 0) - { - builder.Append(""); - - foreach (var tag in hasKeywords.Keywords) - { - builder.Append("" + SecurityElement.Escape(tag) + ""); - } + builder.Append(""); - builder.Append(""); + foreach (var tag in item.Keywords) + { + builder.Append("" + SecurityElement.Escape(tag) + ""); } + + builder.Append(""); } var people = libraryManager.GetPeople(item); diff --git a/MediaBrowser.Providers/Manager/ProviderUtils.cs b/MediaBrowser.Providers/Manager/ProviderUtils.cs index 59a2da460..a6f02f3f7 100644 --- a/MediaBrowser.Providers/Manager/ProviderUtils.cs +++ b/MediaBrowser.Providers/Manager/ProviderUtils.cs @@ -165,15 +165,9 @@ namespace MediaBrowser.Providers.Manager if (!lockedFields.Contains(MetadataFields.Keywords)) { - var sourceHasKeywords = source as IHasKeywords; - var targetHasKeywords = target as IHasKeywords; - - if (sourceHasKeywords != null && targetHasKeywords != null) + if (replaceData || target.Keywords.Count == 0) { - if (replaceData || targetHasKeywords.Keywords.Count == 0) - { - targetHasKeywords.Keywords = sourceHasKeywords.Keywords; - } + target.Keywords = source.Keywords; } } diff --git a/MediaBrowser.Providers/Movies/GenericMovieDbInfo.cs b/MediaBrowser.Providers/Movies/GenericMovieDbInfo.cs index d13716cba..3b3065893 100644 --- a/MediaBrowser.Providers/Movies/GenericMovieDbInfo.cs +++ b/MediaBrowser.Providers/Movies/GenericMovieDbInfo.cs @@ -314,11 +314,7 @@ namespace MediaBrowser.Providers.Movies if (movieData.keywords != null && movieData.keywords.keywords != null) { - var hasTags = movie as IHasKeywords; - if (hasTags != null) - { - hasTags.Keywords = movieData.keywords.keywords.Select(i => i.name).ToList(); - } + movie.Keywords = movieData.keywords.keywords.Select(i => i.name).ToList(); } if (movieData.trailers != null && movieData.trailers.youtube != null && diff --git a/MediaBrowser.Server.Implementations/Dto/DtoService.cs b/MediaBrowser.Server.Implementations/Dto/DtoService.cs index eb868d363..bfcdb2a26 100644 --- a/MediaBrowser.Server.Implementations/Dto/DtoService.cs +++ b/MediaBrowser.Server.Implementations/Dto/DtoService.cs @@ -983,16 +983,7 @@ namespace MediaBrowser.Server.Implementations.Dto if (fields.Contains(ItemFields.Keywords)) { - var hasTags = item as IHasKeywords; - if (hasTags != null) - { - dto.Keywords = hasTags.Keywords; - } - - if (dto.Keywords == null) - { - dto.Keywords = new List(); - } + dto.Keywords = item.Keywords; } if (fields.Contains(ItemFields.ProductionLocations)) diff --git a/MediaBrowser.Server.Implementations/Intros/DefaultIntroProvider.cs b/MediaBrowser.Server.Implementations/Intros/DefaultIntroProvider.cs index 49012c65a..df128a90b 100644 --- a/MediaBrowser.Server.Implementations/Intros/DefaultIntroProvider.cs +++ b/MediaBrowser.Server.Implementations/Intros/DefaultIntroProvider.cs @@ -433,13 +433,7 @@ namespace MediaBrowser.Server.Implementations.Intros private static IEnumerable GetKeywords(BaseItem item) { - var hasTags = item as IHasKeywords; - if (hasTags != null) - { - return hasTags.Keywords; - } - - return new List(); + return item.Keywords; } public IEnumerable GetAllIntroFiles() diff --git a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs index 1de0ea710..a85bf1c81 100644 --- a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs +++ b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs @@ -87,7 +87,7 @@ namespace MediaBrowser.Server.Implementations.Persistence private IDbCommand _updateInheritedRatingCommand; private IDbCommand _updateInheritedTagsCommand; - public const int LatestSchemaVersion = 80; + public const int LatestSchemaVersion = 82; /// /// Initializes a new instance of the class. @@ -2489,8 +2489,8 @@ namespace MediaBrowser.Server.Implementations.Persistence var index = 0; foreach (var item in query.Genres) { - clauses.Add("Genres like @Genres" + index); - cmd.Parameters.Add(cmd, "@Genres" + index, DbType.String).Value = "%" + item + "%"; + clauses.Add("@Genre" + index + " in (select value from itemvalues where ItemId=Guid and Type=2)"); + cmd.Parameters.Add(cmd, "@Genre" + index, DbType.String).Value = item; index++; } var clause = "(" + string.Join(" OR ", clauses.ToArray()) + ")"; @@ -2503,8 +2503,8 @@ namespace MediaBrowser.Server.Implementations.Persistence var index = 0; foreach (var item in query.Tags) { - clauses.Add("Tags like @Tags" + index); - cmd.Parameters.Add(cmd, "@Tags" + index, DbType.String).Value = "%" + item + "%"; + clauses.Add("@Tag" + index + " in (select value from itemvalues where ItemId=Guid and Type=4)"); + cmd.Parameters.Add(cmd, "@Tag" + index, DbType.String).Value = item; index++; } var clause = "(" + string.Join(" OR ", clauses.ToArray()) + ")"; @@ -2517,8 +2517,22 @@ namespace MediaBrowser.Server.Implementations.Persistence var index = 0; foreach (var item in query.Studios) { - clauses.Add("Studios like @Studios" + index); - cmd.Parameters.Add(cmd, "@Studios" + index, DbType.String).Value = "%" + item + "%"; + clauses.Add("@Studio" + index + " in (select value from itemvalues where ItemId=Guid and Type=3)"); + cmd.Parameters.Add(cmd, "@Studio" + index, DbType.String).Value = item; + index++; + } + var clause = "(" + string.Join(" OR ", clauses.ToArray()) + ")"; + whereClauses.Add(clause); + } + + if (query.Keywords.Length > 0) + { + var clauses = new List(); + var index = 0; + foreach (var item in query.Keywords) + { + clauses.Add("@Keyword" + index + " in (select value from itemvalues where ItemId=Guid and Type=5)"); + cmd.Parameters.Add(cmd, "@Keyword" + index, DbType.String).Value = item; index++; } var clause = "(" + string.Join(" OR ", clauses.ToArray()) + ")"; @@ -3233,6 +3247,11 @@ namespace MediaBrowser.Server.Implementations.Persistence list.AddRange(hasAlbumArtist.AlbumArtists.Select(i => new Tuple(1, i))); } + list.AddRange(item.Genres.Select(i => new Tuple(2, i))); + list.AddRange(item.Studios.Select(i => new Tuple(3, i))); + list.AddRange(item.Tags.Select(i => new Tuple(4, i))); + list.AddRange(item.Keywords.Select(i => new Tuple(5, i))); + return list; } diff --git a/MediaBrowser.Server.Mono/Native/SqliteExtensions.cs b/MediaBrowser.Server.Mono/Native/SqliteExtensions.cs index 385a7d0c5..ca2327282 100644 --- a/MediaBrowser.Server.Mono/Native/SqliteExtensions.cs +++ b/MediaBrowser.Server.Mono/Native/SqliteExtensions.cs @@ -32,7 +32,7 @@ namespace MediaBrowser.Server.Mono.Native { PageSize = 4096, CacheSize = 2000, - SyncMode = SynchronizationModes.Full, + SyncMode = SynchronizationModes.Normal, DataSource = dbPath, JournalMode = SQLiteJournalModeEnum.Wal }; diff --git a/MediaBrowser.ServerApplication/Native/SqliteExtensions.cs b/MediaBrowser.ServerApplication/Native/SqliteExtensions.cs index 4e6c82495..bdf5c3323 100644 --- a/MediaBrowser.ServerApplication/Native/SqliteExtensions.cs +++ b/MediaBrowser.ServerApplication/Native/SqliteExtensions.cs @@ -32,7 +32,7 @@ namespace MediaBrowser.ServerApplication.Native { PageSize = 4096, CacheSize = 2000, - SyncMode = SynchronizationModes.Full, + SyncMode = SynchronizationModes.Normal, DataSource = dbPath, JournalMode = SQLiteJournalModeEnum.Wal }; diff --git a/MediaBrowser.XbmcMetadata/Parsers/BaseNfoParser.cs b/MediaBrowser.XbmcMetadata/Parsers/BaseNfoParser.cs index d020a73fe..ad1c6802d 100644 --- a/MediaBrowser.XbmcMetadata/Parsers/BaseNfoParser.cs +++ b/MediaBrowser.XbmcMetadata/Parsers/BaseNfoParser.cs @@ -932,13 +932,9 @@ namespace MediaBrowser.XbmcMetadata.Parsers { var val = reader.ReadElementContentAsString(); - var hasKeywords = item as IHasKeywords; - if (hasKeywords != null) + if (!string.IsNullOrWhiteSpace(val)) { - if (!string.IsNullOrWhiteSpace(val)) - { - hasKeywords.AddKeyword(val); - } + item.AddKeyword(val); } break; } diff --git a/MediaBrowser.XbmcMetadata/Savers/BaseNfoSaver.cs b/MediaBrowser.XbmcMetadata/Savers/BaseNfoSaver.cs index d2e09d4eb..5bb9577ff 100644 --- a/MediaBrowser.XbmcMetadata/Savers/BaseNfoSaver.cs +++ b/MediaBrowser.XbmcMetadata/Savers/BaseNfoSaver.cs @@ -752,13 +752,9 @@ namespace MediaBrowser.XbmcMetadata.Savers } } - var hasKeywords = item as IHasKeywords; - if (hasKeywords != null) + foreach (var tag in item.Keywords) { - foreach (var tag in hasKeywords.Keywords) - { - writer.WriteElementString("plotkeyword", tag); - } + writer.WriteElementString("plotkeyword", tag); } var hasAwards = item as IHasAwards; -- cgit v1.2.3 From ec23e084d04bcb3361fcc0799e65943ae9ea95b5 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Tue, 31 May 2016 14:45:37 -0400 Subject: update movie suggestions --- .../Persistence/SqliteItemRepository.cs | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'MediaBrowser.Server.Implementations') diff --git a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs index a85bf1c81..3149352a9 100644 --- a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs +++ b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs @@ -2628,6 +2628,20 @@ namespace MediaBrowser.Server.Implementations.Persistence whereClauses.Add("MediaType in (" + val + ")"); } + if (query.ExcludeItemIds.Length > 0) + { + var excludeIds = new List(); + + var index = 0; + foreach (var id in query.ExcludeItemIds) + { + excludeIds.Add("Guid <> @ExcludeId" + index); + cmd.Parameters.Add(cmd, "@ExcludeId" + index, DbType.Guid).Value = new Guid(id); + index++; + } + + whereClauses.Add(string.Join(" AND ", excludeIds.ToArray())); + } if (query.AlbumNames.Length > 0) { -- cgit v1.2.3 From 0915d1f3836844afcb432b1a9ed8386f7d1b63c0 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Tue, 31 May 2016 16:17:16 -0400 Subject: update nuget --- .../MediaBrowser.Server.Implementations.csproj | 4 ++-- MediaBrowser.Server.Implementations/packages.config | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'MediaBrowser.Server.Implementations') diff --git a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj index 28edbfcc4..385a94aa5 100644 --- a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj +++ b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj @@ -46,8 +46,8 @@ ..\packages\CommonIO.1.0.0.9\lib\net45\CommonIO.dll - False - ..\packages\Emby.XmlTv.1.0.0.48\lib\net45\Emby.XmlTv.dll + ..\packages\Emby.XmlTv.1.0.0.49\lib\net45\Emby.XmlTv.dll + True ..\packages\ini-parser.2.2.4\lib\net20\INIFileParser.dll diff --git a/MediaBrowser.Server.Implementations/packages.config b/MediaBrowser.Server.Implementations/packages.config index 31b1454d5..9b050672c 100644 --- a/MediaBrowser.Server.Implementations/packages.config +++ b/MediaBrowser.Server.Implementations/packages.config @@ -1,7 +1,7 @@  - + -- cgit v1.2.3 From a3c3fff39f64c5966cb18616dcb444ee0135df87 Mon Sep 17 00:00:00 2001 From: Alex Stevens Date: Tue, 31 May 2016 23:00:20 +0100 Subject: Added first stab at a XmlTvListingsProvider --- .../LiveTv/Listings/XmlTv.cs | 44 ---------- .../LiveTv/Listings/XmlTvListingsProvider.cs | 95 ++++++++++++++++++++++ .../MediaBrowser.Server.Implementations.csproj | 2 +- 3 files changed, 96 insertions(+), 45 deletions(-) delete mode 100644 MediaBrowser.Server.Implementations/LiveTv/Listings/XmlTv.cs create mode 100644 MediaBrowser.Server.Implementations/LiveTv/Listings/XmlTvListingsProvider.cs (limited to 'MediaBrowser.Server.Implementations') diff --git a/MediaBrowser.Server.Implementations/LiveTv/Listings/XmlTv.cs b/MediaBrowser.Server.Implementations/LiveTv/Listings/XmlTv.cs deleted file mode 100644 index ac316f9a1..000000000 --- a/MediaBrowser.Server.Implementations/LiveTv/Listings/XmlTv.cs +++ /dev/null @@ -1,44 +0,0 @@ -using MediaBrowser.Controller.LiveTv; -using MediaBrowser.Model.Dto; -using MediaBrowser.Model.LiveTv; -using System; -using System.Collections.Generic; -using System.Threading; -using System.Threading.Tasks; - -namespace MediaBrowser.Server.Implementations.LiveTv.Listings -{ - public class XmlTv : IListingsProvider - { - public string Name - { - get { return "XmlTV"; } - } - - public string Type - { - get { return "xmltv"; } - } - - public Task> GetProgramsAsync(ListingsProviderInfo info, string channelNumber, string channelName, DateTime startDateUtc, DateTime endDateUtc, CancellationToken cancellationToken) - { - throw new NotImplementedException(); - } - - public async Task AddMetadata(ListingsProviderInfo info, List channels, CancellationToken cancellationToken) - { - // Might not be needed - } - - public async Task Validate(ListingsProviderInfo info, bool validateLogin, bool validateListings) - { - // Check that the path or url is valid. If not, throw a file not found exception - } - - public Task> GetLineups(ListingsProviderInfo info, string country, string location) - { - // In theory this should never be called because there is always only one lineup - throw new NotImplementedException(); - } - } -} diff --git a/MediaBrowser.Server.Implementations/LiveTv/Listings/XmlTvListingsProvider.cs b/MediaBrowser.Server.Implementations/LiveTv/Listings/XmlTvListingsProvider.cs new file mode 100644 index 000000000..ef596e533 --- /dev/null +++ b/MediaBrowser.Server.Implementations/LiveTv/Listings/XmlTvListingsProvider.cs @@ -0,0 +1,95 @@ +using MediaBrowser.Controller.LiveTv; +using MediaBrowser.Model.Dto; +using MediaBrowser.Model.LiveTv; +using System; +using System.Linq; +using System.Collections.Generic; +using System.Threading; +using System.Threading.Tasks; + +using Emby.XmlTv.Classes; +using System.IO; + +namespace MediaBrowser.Server.Implementations.LiveTv.Listings +{ + public class XmlTvListingsProvider : IListingsProvider + { + private string _filePath = "C:\\Temp\\"; + private string _language = null; + + public string Name + { + get { return "XmlTV"; } + } + + public string Type + { + get { return "xmltv"; } + } + + // TODO: Should this method be async? + public Task> GetProgramsAsync(ListingsProviderInfo info, string channelNumber, string channelName, DateTime startDateUtc, DateTime endDateUtc, CancellationToken cancellationToken) + { + var reader = new XmlTvReader(_filePath, _language, null); + var results = reader.GetProgrammes(channelNumber, startDateUtc, endDateUtc, cancellationToken); + return Task.FromResult(results.Select(p => new ProgramInfo() + { + ChannelId = p.ChannelId, + //CommunityRating = p.Rating., + EndDate = p.EndDate, + EpisodeNumber = p.Episode == null ? null : p.Episode.Episode, + EpisodeTitle = p.Episode == null ? null : p.Episode.Title, + Genres = p.Categories, + Id = String.Format("{0}_{1:O}", p.ChannelId, p.StartDate), // Construct an id from the channel and start date, + StartDate = p.StartDate, + Name = p.Title, + Overview = p.Description, + // OfficialRating = p.OfficialRating, + ShortOverview = p.Description, + ProductionYear = !p.CopyrightDate.HasValue ? (int?)null : p.CopyrightDate.Value.Year, + SeasonNumber = p.Episode == null ? null : p.Episode.Series, + IsSeries = p.IsSeries, + IsRepeat = p.IsRepeat, + IsPremiere = !p.PreviouslyShown.HasValue, + })); + } + + public async Task AddMetadata(ListingsProviderInfo info, List channels, CancellationToken cancellationToken) + { + // Add the channel image url + var reader = new XmlTvReader(_filePath, _language, null); + var results = reader.GetChannels().ToList(); + + if (channels != null && channels.Count > 0) + { + channels.ForEach(c => { + var match = results.FirstOrDefault(r => r.Id == c.Id); + if (match != null) + { + // c.ImageUrl = match.Url; + // TODO: Add support for the channel logo to the XMLTv Component + } + }); + } + } + + public async Task Validate(ListingsProviderInfo info, bool validateLogin, bool validateListings) + { + // Check that the path or url is valid. If not, throw a file not found exception + if (!File.Exists(_filePath)) + { + throw new FileNotFoundException("Could not find the XmlTv file specified", _filePath); + } + } + + public Task> GetLineups(ListingsProviderInfo info, string country, string location) + { + // In theory this should never be called because there is always only one lineup + var reader = new XmlTvReader(_filePath, _language, null); + var results = reader.GetChannels(); + + // Should this method be async? + return Task.FromResult(results.Select(c => new NameIdPair() { Id = c.Id, Name = c.DisplayName }).ToList()); + } + } +} \ No newline at end of file diff --git a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj index 385a94aa5..a27b12a89 100644 --- a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj +++ b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj @@ -232,7 +232,7 @@ - + -- cgit v1.2.3 From e1f562e16ff585b440a43029efe9db314b4de965 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Wed, 1 Jun 2016 01:50:00 -0400 Subject: calculate similarity at database level --- MediaBrowser.Api/GamesService.cs | 41 +++-- MediaBrowser.Api/Movies/MoviesService.cs | 114 +++++--------- MediaBrowser.Api/TvShowsService.cs | 41 +++-- .../Entities/InternalItemsQuery.cs | 2 + .../Persistence/IDbConnector.cs | 1 + .../Persistence/SqliteExtensions.cs | 175 +++++++++++++++++++++ .../Persistence/SqliteItemRepository.cs | 80 +++++++--- .../MediaBrowser.Server.Mono.csproj | 5 +- MediaBrowser.Server.Mono/Native/DbConnector.cs | 29 ++++ .../Native/SqliteExtensions.cs | 62 -------- .../MediaBrowser.ServerApplication.csproj | 5 +- .../Native/DbConnector.cs | 38 +++++ .../Native/SqliteExtensions.cs | 71 --------- 13 files changed, 409 insertions(+), 255 deletions(-) create mode 100644 MediaBrowser.Server.Implementations/Persistence/SqliteExtensions.cs create mode 100644 MediaBrowser.Server.Mono/Native/DbConnector.cs delete mode 100644 MediaBrowser.Server.Mono/Native/SqliteExtensions.cs create mode 100644 MediaBrowser.ServerApplication/Native/DbConnector.cs delete mode 100644 MediaBrowser.ServerApplication/Native/SqliteExtensions.cs (limited to 'MediaBrowser.Server.Implementations') diff --git a/MediaBrowser.Api/GamesService.cs b/MediaBrowser.Api/GamesService.cs index 387771b6d..cb77e62ad 100644 --- a/MediaBrowser.Api/GamesService.cs +++ b/MediaBrowser.Api/GamesService.cs @@ -10,6 +10,7 @@ using System.Collections.Generic; using System.Globalization; using System.IO; using System.Linq; +using MediaBrowser.Model.Querying; namespace MediaBrowser.Api { @@ -187,18 +188,40 @@ namespace MediaBrowser.Api /// System.Object. public object Get(GetSimilarGames request) { + var result = GetSimilarItemsResult(request); + + return ToOptimizedSerializedResultUsingCache(result); + } + + private QueryResult GetSimilarItemsResult(BaseGetSimilarItemsFromItem request) + { + var user = !string.IsNullOrWhiteSpace(request.UserId) ? _userManager.GetUserById(request.UserId) : null; + + var item = string.IsNullOrEmpty(request.Id) ? + (!string.IsNullOrWhiteSpace(request.UserId) ? user.RootFolder : + _libraryManager.RootFolder) : _libraryManager.GetItemById(request.Id); + + var itemsResult = _libraryManager.GetItemList(new InternalItemsQuery(user) + { + Limit = request.Limit, + IncludeItemTypes = new[] + { + typeof(Game).Name + }, + SimilarTo = item + + }).ToList(); + var dtoOptions = GetDtoOptions(request); - var result = SimilarItemsHelper.GetSimilarItemsResult(dtoOptions, _userManager, - _itemRepo, - _libraryManager, - _userDataRepository, - _dtoService, - Logger, - request, new[] { typeof(Game) }, - SimilarItemsHelper.GetSimiliarityScore); + var result = new QueryResult + { + Items = _dtoService.GetBaseItemDtos(itemsResult, dtoOptions, user).ToArray(), - return ToOptimizedSerializedResultUsingCache(result); + TotalRecordCount = itemsResult.Count + }; + + return result; } } } diff --git a/MediaBrowser.Api/Movies/MoviesService.cs b/MediaBrowser.Api/Movies/MoviesService.cs index ce36dd2ac..ff18d440c 100644 --- a/MediaBrowser.Api/Movies/MoviesService.cs +++ b/MediaBrowser.Api/Movies/MoviesService.cs @@ -111,18 +111,16 @@ namespace MediaBrowser.Api.Movies /// /// The request. /// System.Object. - public async Task Get(GetSimilarMovies request) + public object Get(GetSimilarMovies request) { - var result = await GetSimilarItemsResult( - request, SimilarItemsHelper.GetSimiliarityScore).ConfigureAwait(false); + var result = GetSimilarItemsResult(request); return ToOptimizedSerializedResultUsingCache(result); } - public async Task Get(GetSimilarTrailers request) + public object Get(GetSimilarTrailers request) { - var result = await GetSimilarItemsResult( - request, SimilarItemsHelper.GetSimiliarityScore).ConfigureAwait(false); + var result = GetSimilarItemsResult(request); return ToOptimizedSerializedResultUsingCache(result); } @@ -131,42 +129,16 @@ namespace MediaBrowser.Api.Movies { var user = _userManager.GetUserById(request.UserId); - var query = new InternalItemsQuery(user) - { - IncludeItemTypes = new[] - { - typeof(Movie).Name, - typeof(Trailer).Name, - //typeof(LiveTvProgram).Name - }, - // IsMovie = true - }; - - var parentIds = string.IsNullOrWhiteSpace(request.ParentId) ? new string[] { } : new[] { request.ParentId }; - var movies = _libraryManager.GetItemList(query, parentIds) - .OrderBy(i => (int)i.SourceType); - - var listEligibleForSuggestion = new List(); - - var list = movies.ToList(); - - listEligibleForSuggestion.AddRange(list); - - listEligibleForSuggestion = listEligibleForSuggestion - .DistinctBy(i => i.Name, StringComparer.OrdinalIgnoreCase) - .DistinctBy(i => i.GetProviderId(MetadataProviders.Imdb) ?? Guid.NewGuid().ToString(), StringComparer.OrdinalIgnoreCase) - .ToList(); - var dtoOptions = GetDtoOptions(request); dtoOptions.Fields = request.GetItemFields().ToList(); - var result = GetRecommendationCategories(user, request.ParentId, listEligibleForSuggestion, request.CategoryLimit, request.ItemLimit, dtoOptions); + var result = GetRecommendationCategories(user, request.ParentId, request.CategoryLimit, request.ItemLimit, dtoOptions); return ToOptimizedResult(result); } - private async Task GetSimilarItemsResult(BaseGetSimilarItemsFromItem request, Func, List, BaseItem, int> getSimilarityScore) + private QueryResult GetSimilarItemsResult(BaseGetSimilarItemsFromItem request) { var user = !string.IsNullOrWhiteSpace(request.UserId) ? _userManager.GetUserById(request.UserId) : null; @@ -174,57 +146,32 @@ namespace MediaBrowser.Api.Movies (!string.IsNullOrWhiteSpace(request.UserId) ? user.RootFolder : _libraryManager.RootFolder) : _libraryManager.GetItemById(request.Id); - var query = new InternalItemsQuery(user) + var itemsResult = _libraryManager.GetItemList(new InternalItemsQuery(user) { + Limit = request.Limit, IncludeItemTypes = new[] { - typeof(Movie).Name, - typeof(Trailer).Name, - //typeof(LiveTvProgram).Name + typeof(Movie).Name, + typeof(Trailer).Name, + typeof(LiveTvProgram).Name }, - //IsMovie = true - }; - - var list = _libraryManager.GetItemList(query) - .OrderBy(i => (int)i.SourceType) - .DistinctBy(i => i.GetProviderId(MetadataProviders.Imdb) ?? Guid.NewGuid().ToString("N")) - .ToList(); - - if (item is Video) - { - var imdbId = item.GetProviderId(MetadataProviders.Imdb); - - // Use imdb id to try to filter duplicates of the same item - if (!string.IsNullOrWhiteSpace(imdbId)) - { - list = list - .Where(i => !string.Equals(imdbId, i.GetProviderId(MetadataProviders.Imdb), StringComparison.OrdinalIgnoreCase)) - .ToList(); - } - } - - var items = SimilarItemsHelper.GetSimilaritems(item, _libraryManager, list, getSimilarityScore).ToList(); - - IEnumerable returnItems = items; - - if (request.Limit.HasValue) - { - returnItems = returnItems.Take(request.Limit.Value); - } + IsMovie = true, + SimilarTo = item + }).ToList(); var dtoOptions = GetDtoOptions(request); - var result = new ItemsResult + var result = new QueryResult { - Items = _dtoService.GetBaseItemDtos(returnItems, dtoOptions, user).ToArray(), + Items = _dtoService.GetBaseItemDtos(itemsResult, dtoOptions, user).ToArray(), - TotalRecordCount = items.Count + TotalRecordCount = itemsResult.Count }; return result; } - private IEnumerable GetRecommendationCategories(User user, string parentId, List allMovies, int categoryLimit, int itemLimit, DtoOptions dtoOptions) + private IEnumerable GetRecommendationCategories(User user, string parentId, int categoryLimit, int itemLimit, DtoOptions dtoOptions) { var categories = new List(); @@ -260,7 +207,7 @@ namespace MediaBrowser.Api.Movies IsFavoriteOrLiked = true, ExcludeItemIds = recentlyPlayedMovies.Select(i => i.Id.ToString("N")).ToArray() - }, parentIds); + }, parentIds).ToList(); var mostRecentMovies = recentlyPlayedMovies.Take(6).ToList(); // Get recently played directors @@ -273,8 +220,8 @@ namespace MediaBrowser.Api.Movies .OrderBy(i => Guid.NewGuid()) .ToList(); - var similarToRecentlyPlayed = GetSimilarTo(user, allMovies, recentlyPlayedMovies.Take(7).OrderBy(i => Guid.NewGuid()), itemLimit, dtoOptions, RecommendationType.SimilarToRecentlyPlayed).GetEnumerator(); - var similarToLiked = GetSimilarTo(user, allMovies, likedMovies, itemLimit, dtoOptions, RecommendationType.SimilarToLikedItem).GetEnumerator(); + var similarToRecentlyPlayed = GetSimilarTo(user, recentlyPlayedMovies, itemLimit, dtoOptions, RecommendationType.SimilarToRecentlyPlayed).GetEnumerator(); + var similarToLiked = GetSimilarTo(user, likedMovies, itemLimit, dtoOptions, RecommendationType.SimilarToLikedItem).GetEnumerator(); var hasDirectorFromRecentlyPlayed = GetWithDirector(user, recentDirectors, itemLimit, dtoOptions, RecommendationType.HasDirectorFromRecentlyPlayed).GetEnumerator(); var hasActorFromRecentlyPlayed = GetWithActor(user, recentActors, itemLimit, dtoOptions, RecommendationType.HasActorFromRecentlyPlayed).GetEnumerator(); @@ -389,14 +336,23 @@ namespace MediaBrowser.Api.Movies } } - private IEnumerable GetSimilarTo(User user, List allMovies, IEnumerable baselineItems, int itemLimit, DtoOptions dtoOptions, RecommendationType type) + private IEnumerable GetSimilarTo(User user, List baselineItems, int itemLimit, DtoOptions dtoOptions, RecommendationType type) { foreach (var item in baselineItems) { - var similar = SimilarItemsHelper - .GetSimilaritems(item, _libraryManager, allMovies, SimilarItemsHelper.GetSimiliarityScore) - .Take(itemLimit) - .ToList(); + var similar = _libraryManager.GetItemList(new InternalItemsQuery(user) + { + Limit = itemLimit, + IncludeItemTypes = new[] + { + typeof(Movie).Name, + typeof(Trailer).Name, + typeof(LiveTvProgram).Name + }, + IsMovie = true, + SimilarTo = item + + }).ToList(); if (similar.Count > 0) { diff --git a/MediaBrowser.Api/TvShowsService.cs b/MediaBrowser.Api/TvShowsService.cs index aa0485d57..5ccfede1e 100644 --- a/MediaBrowser.Api/TvShowsService.cs +++ b/MediaBrowser.Api/TvShowsService.cs @@ -12,6 +12,7 @@ using ServiceStack; using System; using System.Collections.Generic; using System.Linq; +using MediaBrowser.Model.Dto; namespace MediaBrowser.Api { @@ -273,18 +274,40 @@ namespace MediaBrowser.Api /// System.Object. public object Get(GetSimilarShows request) { + var result = GetSimilarItemsResult(request); + + return ToOptimizedSerializedResultUsingCache(result); + } + + private QueryResult GetSimilarItemsResult(BaseGetSimilarItemsFromItem request) + { + var user = !string.IsNullOrWhiteSpace(request.UserId) ? _userManager.GetUserById(request.UserId) : null; + + var item = string.IsNullOrEmpty(request.Id) ? + (!string.IsNullOrWhiteSpace(request.UserId) ? user.RootFolder : + _libraryManager.RootFolder) : _libraryManager.GetItemById(request.Id); + + var itemsResult = _libraryManager.GetItemList(new InternalItemsQuery(user) + { + Limit = request.Limit, + IncludeItemTypes = new[] + { + typeof(Series).Name + }, + SimilarTo = item + + }).ToList(); + var dtoOptions = GetDtoOptions(request); - var result = SimilarItemsHelper.GetSimilarItemsResult(dtoOptions, _userManager, - _itemRepo, - _libraryManager, - _userDataManager, - _dtoService, - Logger, - request, new[] { typeof(Series) }, - SimilarItemsHelper.GetSimiliarityScore); + var result = new QueryResult + { + Items = _dtoService.GetBaseItemDtos(itemsResult, dtoOptions, user).ToArray(), - return ToOptimizedSerializedResultUsingCache(result); + TotalRecordCount = itemsResult.Count + }; + + return result; } public object Get(GetUpcomingEpisodes request) diff --git a/MediaBrowser.Controller/Entities/InternalItemsQuery.cs b/MediaBrowser.Controller/Entities/InternalItemsQuery.cs index f3f05a08f..0047a13b2 100644 --- a/MediaBrowser.Controller/Entities/InternalItemsQuery.cs +++ b/MediaBrowser.Controller/Entities/InternalItemsQuery.cs @@ -19,6 +19,8 @@ namespace MediaBrowser.Controller.Entities public User User { get; set; } + public BaseItem SimilarTo { get; set; } + public bool? IsFolder { get; set; } public bool? IsFavorite { get; set; } public bool? IsFavoriteOrLiked { get; set; } diff --git a/MediaBrowser.Server.Implementations/Persistence/IDbConnector.cs b/MediaBrowser.Server.Implementations/Persistence/IDbConnector.cs index cac9fe983..985d79a0a 100644 --- a/MediaBrowser.Server.Implementations/Persistence/IDbConnector.cs +++ b/MediaBrowser.Server.Implementations/Persistence/IDbConnector.cs @@ -6,5 +6,6 @@ namespace MediaBrowser.Server.Implementations.Persistence public interface IDbConnector { Task Connect(string dbPath); + void BindSimilarityScoreFunction(IDbConnection connection); } } diff --git a/MediaBrowser.Server.Implementations/Persistence/SqliteExtensions.cs b/MediaBrowser.Server.Implementations/Persistence/SqliteExtensions.cs new file mode 100644 index 000000000..5e07bac31 --- /dev/null +++ b/MediaBrowser.Server.Implementations/Persistence/SqliteExtensions.cs @@ -0,0 +1,175 @@ +using System; +using System.Collections.Generic; +using System.Data; +using System.Data.SQLite; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using MediaBrowser.Model.Logging; + +namespace MediaBrowser.Server.Implementations.Persistence +{ + /// + /// Class SQLiteExtensions + /// + public static class SqliteExtensions + { + /// + /// Connects to db. + /// + /// The db path. + /// The logger. + /// Task{IDbConnection}. + /// dbPath + public static async Task ConnectToDb(string dbPath, ILogger logger) + { + if (string.IsNullOrEmpty(dbPath)) + { + throw new ArgumentNullException("dbPath"); + } + + logger.Info("Sqlite {0} opening {1}", SQLiteConnection.SQLiteVersion, dbPath); + + var connectionstr = new SQLiteConnectionStringBuilder + { + PageSize = 4096, + CacheSize = 2000, + SyncMode = SynchronizationModes.Normal, + DataSource = dbPath, + JournalMode = SQLiteJournalModeEnum.Wal + }; + + var connection = new SQLiteConnection(connectionstr.ConnectionString); + + await connection.OpenAsync().ConfigureAwait(false); + + return connection; + } + + public static void BindGetSimilarityScore(IDbConnection connection, ILogger logger) + { + var sqlConnection = (SQLiteConnection) connection; + SimiliarToFunction.Logger = logger; + sqlConnection.BindFunction(new SimiliarToFunction()); + } + + public static void BindFunction(this SQLiteConnection connection, SQLiteFunction function) + { + var attributes = function.GetType().GetCustomAttributes(typeof(SQLiteFunctionAttribute), true).Cast().ToArray(); + if (attributes.Length == 0) + { + throw new InvalidOperationException("SQLiteFunction doesn't have SQLiteFunctionAttribute"); + } + connection.BindFunction(attributes[0], function); + } + } + + [SQLiteFunction(Name = "GetSimilarityScore", Arguments = 12, FuncType = FunctionType.Scalar)] + public class SimiliarToFunction : SQLiteFunction + { + internal static ILogger Logger; + + public override object Invoke(object[] args) + { + var score = 0; + + var inputOfficialRating = args[0] as string; + var rowOfficialRating = args[1] as string; + if (!string.IsNullOrWhiteSpace(inputOfficialRating) && string.Equals(inputOfficialRating, rowOfficialRating)) + { + score += 10; + } + + long? inputYear = args[2] == null ? (long?)null : (long)args[2]; + long? rowYear = args[3] == null ? (long?)null : (long)args[3]; + + if (inputYear.HasValue && rowYear.HasValue) + { + var diff = Math.Abs(inputYear.Value - rowYear.Value); + + // Add if they came out within the same decade + if (diff < 10) + { + score += 2; + } + + // And more if within five years + if (diff < 5) + { + score += 2; + } + } + + // genres + score += GetListScore(args, 4, 5); + + // tags + score += GetListScore(args, 6, 7); + + // keywords + score += GetListScore(args, 8, 9); + + // studios + score += GetListScore(args, 10, 11, 3); + + + // TODO: People + // var item2PeopleNames = allPeople.Where(i => i.ItemId == item2.Id) + //.Select(i => i.Name) + //.Where(i => !string.IsNullOrWhiteSpace(i)) + //.DistinctNames() + //.ToDictionary(i => i, StringComparer.OrdinalIgnoreCase); + + // points += item1People.Where(i => item2PeopleNames.ContainsKey(i.Name)).Sum(i => + // { + // if (string.Equals(i.Type, PersonType.Director, StringComparison.OrdinalIgnoreCase) || string.Equals(i.Role, PersonType.Director, StringComparison.OrdinalIgnoreCase)) + // { + // return 5; + // } + // if (string.Equals(i.Type, PersonType.Actor, StringComparison.OrdinalIgnoreCase) || string.Equals(i.Role, PersonType.Actor, StringComparison.OrdinalIgnoreCase)) + // { + // return 3; + // } + // if (string.Equals(i.Type, PersonType.Composer, StringComparison.OrdinalIgnoreCase) || string.Equals(i.Role, PersonType.Composer, StringComparison.OrdinalIgnoreCase)) + // { + // return 3; + // } + // if (string.Equals(i.Type, PersonType.GuestStar, StringComparison.OrdinalIgnoreCase) || string.Equals(i.Role, PersonType.GuestStar, StringComparison.OrdinalIgnoreCase)) + // { + // return 3; + // } + // if (string.Equals(i.Type, PersonType.Writer, StringComparison.OrdinalIgnoreCase) || string.Equals(i.Role, PersonType.Writer, StringComparison.OrdinalIgnoreCase)) + // { + // return 2; + // } + + // return 1; + // }); + + // return points; + + //Logger.Debug("Returning score {0}", score); + return score; + } + + private int GetListScore(object[] args, int index1, int index2, int value = 10) + { + var score = 0; + + var inputGenres = args[index1] as string; + var rowGenres = args[index2] as string; + var inputGenreList = string.IsNullOrWhiteSpace(inputGenres) ? new string[] { } : inputGenres.Split(new[] { '|' }, StringSplitOptions.RemoveEmptyEntries); + var rowGenresList = string.IsNullOrWhiteSpace(rowGenres) ? new string[] { } : rowGenres.Split(new[] { '|' }, StringSplitOptions.RemoveEmptyEntries); + + foreach (var genre in inputGenreList) + { + if (rowGenresList.Contains(genre, StringComparer.OrdinalIgnoreCase)) + { + score += value; + } + } + + return score; + } + } +} diff --git a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs index 3149352a9..131158dd2 100644 --- a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs +++ b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs @@ -15,6 +15,7 @@ using System.Globalization; using System.IO; using System.Linq; using System.Runtime.Serialization; +using System.Text; using System.Threading; using System.Threading.Tasks; using MediaBrowser.Common.Extensions; @@ -258,6 +259,8 @@ namespace MediaBrowser.Server.Implementations.Persistence new MediaStreamColumns(_connection, Logger).AddColumns(); DataExtensions.Attach(_connection, Path.Combine(_config.ApplicationPaths.DataPath, "userdata_v2.db"), "UserDataDb"); + + dbConnector.BindSimilarityScoreFunction(_connection); } private readonly string[] _retriveItemColumns = @@ -1575,7 +1578,7 @@ namespace MediaBrowser.Server.Implementations.Persistence return false; } - private string[] GetFinalColumnsToSelect(InternalItemsQuery query, string[] startColumns) + private string[] GetFinalColumnsToSelect(InternalItemsQuery query, string[] startColumns, IDbCommand cmd) { var list = startColumns.ToList(); @@ -1590,6 +1593,45 @@ namespace MediaBrowser.Server.Implementations.Persistence list.Add("UserDataDb.UserData.rating"); } + if (query.SimilarTo != null) + { + var item = query.SimilarTo; + + var builder = new StringBuilder(); + builder.Append("GetSimilarityScore("); + + builder.Append("@ItemOfficialRating,"); + builder.Append("OfficialRating,"); + + builder.Append("@ItemProductionYear,"); + builder.Append("ProductionYear,"); + + builder.Append("@ItemGenres,"); + builder.Append("Genres,"); + + builder.Append("@ItemTags,"); + builder.Append("Tags,"); + + builder.Append("@ItemKeywords,"); + builder.Append("(select group_concat((Select Value from ItemValues where ItemId=Guid and Type=5), '|')),"); + + builder.Append("@ItemStudios,"); + builder.Append("Studios"); + builder.Append(") as SimilarityScore"); + + list.Add(builder.ToString()); + cmd.Parameters.Add(cmd, "@ItemOfficialRating", DbType.String).Value = item.OfficialRating; + cmd.Parameters.Add(cmd, "@ItemProductionYear", DbType.Int32).Value = item.ProductionYear ?? -1; + cmd.Parameters.Add(cmd, "@ItemGenres", DbType.String).Value = string.Join("|", item.Genres.ToArray()); + cmd.Parameters.Add(cmd, "@ItemTags", DbType.String).Value = string.Join("|", item.Tags.ToArray()); + cmd.Parameters.Add(cmd, "@ItemKeywords", DbType.String).Value = string.Join("|", item.Keywords.ToArray()); + cmd.Parameters.Add(cmd, "@ItemStudios", DbType.String).Value = string.Join("|", item.Studios.ToArray()); + + var excludeIds = query.ExcludeItemIds.ToList(); + excludeIds.Add(item.Id.ToString("N")); + query.ExcludeItemIds = excludeIds.ToArray(); + } + return list.ToArray(); } @@ -1616,7 +1658,7 @@ namespace MediaBrowser.Server.Implementations.Persistence using (var cmd = _connection.CreateCommand()) { - cmd.CommandText = "select " + string.Join(",", GetFinalColumnsToSelect(query, _retriveItemColumns)) + " from TypedBaseItems"; + cmd.CommandText = "select " + string.Join(",", GetFinalColumnsToSelect(query, _retriveItemColumns, cmd)) + " from TypedBaseItems"; cmd.CommandText += GetJoinUserDataText(query); if (EnableJoinUserData(query)) @@ -1706,7 +1748,7 @@ namespace MediaBrowser.Server.Implementations.Persistence using (var cmd = _connection.CreateCommand()) { - cmd.CommandText = "select " + string.Join(",", GetFinalColumnsToSelect(query, _retriveItemColumns)) + " from TypedBaseItems"; + cmd.CommandText = "select " + string.Join(",", GetFinalColumnsToSelect(query, _retriveItemColumns, cmd)) + " from TypedBaseItems"; cmd.CommandText += GetJoinUserDataText(query); if (EnableJoinUserData(query)) @@ -1789,6 +1831,15 @@ namespace MediaBrowser.Server.Implementations.Persistence private string GetOrderByText(InternalItemsQuery query) { + if (query.SimilarTo != null) + { + if (query.SortBy == null || query.SortBy.Length == 0) + { + query.SortBy = new[] { "SimilarityScore", "Random" }; + query.SortOrder = SortOrder.Descending; + } + } + if (query.SortBy == null || query.SortBy.Length == 0) { return string.Empty; @@ -1879,7 +1930,7 @@ namespace MediaBrowser.Server.Implementations.Persistence using (var cmd = _connection.CreateCommand()) { - cmd.CommandText = "select " + string.Join(",", GetFinalColumnsToSelect(query, new[] { "guid" })) + " from TypedBaseItems"; + cmd.CommandText = "select " + string.Join(",", GetFinalColumnsToSelect(query, new[] { "guid" }, cmd)) + " from TypedBaseItems"; cmd.CommandText += GetJoinUserDataText(query); if (EnableJoinUserData(query)) @@ -2022,7 +2073,7 @@ namespace MediaBrowser.Server.Implementations.Persistence using (var cmd = _connection.CreateCommand()) { - cmd.CommandText = "select " + string.Join(",", GetFinalColumnsToSelect(query, new[] { "guid" })) + " from TypedBaseItems"; + cmd.CommandText = "select " + string.Join(",", GetFinalColumnsToSelect(query, new[] { "guid" }, cmd)) + " from TypedBaseItems"; var whereClauses = GetWhereClauses(query, cmd); cmd.CommandText += GetJoinUserDataText(query); @@ -2148,24 +2199,7 @@ namespace MediaBrowser.Server.Implementations.Persistence } else { - if (query.IsMovie.Value) - { - var typeClauses = new List(); - var typeIndex = 0; - foreach (var type in alternateTypes) - { - var paramName = "@AlternateType" + typeIndex.ToString(CultureInfo.InvariantCulture); - typeClauses.Add("Type=" + paramName); - cmd.Parameters.Add(cmd, paramName, DbType.String).Value = type; - typeIndex++; - } - - whereClauses.Add("(IsMovie=@IsMovie OR " + string.Join(" OR ", typeClauses.ToArray()) + ")"); - } - else - { - whereClauses.Add("(IsMovie is null OR IsMovie=@IsMovie)"); - } + whereClauses.Add("(IsMovie is null OR IsMovie=@IsMovie)"); } cmd.Parameters.Add(cmd, "@IsMovie", DbType.Boolean).Value = query.IsMovie; } diff --git a/MediaBrowser.Server.Mono/MediaBrowser.Server.Mono.csproj b/MediaBrowser.Server.Mono/MediaBrowser.Server.Mono.csproj index b71877e17..45071c9d9 100644 --- a/MediaBrowser.Server.Mono/MediaBrowser.Server.Mono.csproj +++ b/MediaBrowser.Server.Mono/MediaBrowser.Server.Mono.csproj @@ -82,11 +82,14 @@ + + Native\SqliteExtensions.cs + Properties\SharedVersion.cs - + diff --git a/MediaBrowser.Server.Mono/Native/DbConnector.cs b/MediaBrowser.Server.Mono/Native/DbConnector.cs new file mode 100644 index 000000000..536cd7322 --- /dev/null +++ b/MediaBrowser.Server.Mono/Native/DbConnector.cs @@ -0,0 +1,29 @@ +using System; +using System.Data; +using System.Data.SQLite; +using System.Threading.Tasks; +using MediaBrowser.Model.Logging; +using MediaBrowser.Server.Implementations.Persistence; + +namespace MediaBrowser.Server.Mono.Native +{ + public class DbConnector : IDbConnector + { + private readonly ILogger _logger; + + public DbConnector(ILogger logger) + { + _logger = logger; + } + + public void BindSimilarityScoreFunction(IDbConnection connection) + { + SqliteExtensions.BindGetSimilarityScore(connection, _logger); + } + + public Task Connect(string dbPath) + { + return SqliteExtensions.ConnectToDb(dbPath, _logger); + } + } +} \ No newline at end of file diff --git a/MediaBrowser.Server.Mono/Native/SqliteExtensions.cs b/MediaBrowser.Server.Mono/Native/SqliteExtensions.cs deleted file mode 100644 index ca2327282..000000000 --- a/MediaBrowser.Server.Mono/Native/SqliteExtensions.cs +++ /dev/null @@ -1,62 +0,0 @@ -using System; -using System.Data; -using System.Data.SQLite; -using System.Threading.Tasks; -using MediaBrowser.Model.Logging; -using MediaBrowser.Server.Implementations.Persistence; - -namespace MediaBrowser.Server.Mono.Native -{ - /// - /// Class SQLiteExtensions - /// - static class SqliteExtensions - { - /// - /// Connects to db. - /// - /// The db path. - /// The logger. - /// Task{IDbConnection}. - /// dbPath - public static async Task ConnectToDb(string dbPath, ILogger logger) - { - if (string.IsNullOrEmpty(dbPath)) - { - throw new ArgumentNullException("dbPath"); - } - - logger.Info("Sqlite {0} opening {1}", SQLiteConnection.SQLiteVersion, dbPath); - - var connectionstr = new SQLiteConnectionStringBuilder - { - PageSize = 4096, - CacheSize = 2000, - SyncMode = SynchronizationModes.Normal, - DataSource = dbPath, - JournalMode = SQLiteJournalModeEnum.Wal - }; - - var connection = new SQLiteConnection(connectionstr.ConnectionString); - - await connection.OpenAsync().ConfigureAwait(false); - - return connection; - } - } - - public class DbConnector : IDbConnector - { - private readonly ILogger _logger; - - public DbConnector(ILogger logger) - { - _logger = logger; - } - - public Task Connect(string dbPath) - { - return SqliteExtensions.ConnectToDb(dbPath, _logger); - } - } -} \ No newline at end of file diff --git a/MediaBrowser.ServerApplication/MediaBrowser.ServerApplication.csproj b/MediaBrowser.ServerApplication/MediaBrowser.ServerApplication.csproj index 366d4b608..35660b2b1 100644 --- a/MediaBrowser.ServerApplication/MediaBrowser.ServerApplication.csproj +++ b/MediaBrowser.ServerApplication/MediaBrowser.ServerApplication.csproj @@ -97,6 +97,9 @@ + + Native\SqliteExtensions.cs + Properties\SharedVersion.cs @@ -114,7 +117,7 @@ - + diff --git a/MediaBrowser.ServerApplication/Native/DbConnector.cs b/MediaBrowser.ServerApplication/Native/DbConnector.cs new file mode 100644 index 000000000..f93cad62c --- /dev/null +++ b/MediaBrowser.ServerApplication/Native/DbConnector.cs @@ -0,0 +1,38 @@ +using System; +using System.Data; +using System.Data.SQLite; +using System.Threading.Tasks; +using MediaBrowser.Model.Logging; +using MediaBrowser.Server.Implementations.Persistence; + +namespace MediaBrowser.ServerApplication.Native +{ + public class DbConnector : IDbConnector + { + private readonly ILogger _logger; + + public DbConnector(ILogger logger) + { + _logger = logger; + } + + public void BindSimilarityScoreFunction(IDbConnection connection) + { + SqliteExtensions.BindGetSimilarityScore(connection, _logger); + } + + public async Task Connect(string dbPath) + { + try + { + return await SqliteExtensions.ConnectToDb(dbPath, _logger).ConfigureAwait(false); + } + catch (Exception ex) + { + _logger.ErrorException("Error opening database {0}", ex, dbPath); + + throw; + } + } + } +} \ No newline at end of file diff --git a/MediaBrowser.ServerApplication/Native/SqliteExtensions.cs b/MediaBrowser.ServerApplication/Native/SqliteExtensions.cs deleted file mode 100644 index bdf5c3323..000000000 --- a/MediaBrowser.ServerApplication/Native/SqliteExtensions.cs +++ /dev/null @@ -1,71 +0,0 @@ -using System; -using System.Data; -using System.Data.SQLite; -using System.Threading.Tasks; -using MediaBrowser.Model.Logging; -using MediaBrowser.Server.Implementations.Persistence; - -namespace MediaBrowser.ServerApplication.Native -{ - /// - /// Class SQLiteExtensions - /// - static class SqliteExtensions - { - /// - /// Connects to db. - /// - /// The db path. - /// The logger. - /// Task{IDbConnection}. - /// dbPath - public static async Task ConnectToDb(string dbPath, ILogger logger) - { - if (string.IsNullOrEmpty(dbPath)) - { - throw new ArgumentNullException("dbPath"); - } - - logger.Info("Sqlite {0} opening {1}", SQLiteConnection.SQLiteVersion, dbPath); - - var connectionstr = new SQLiteConnectionStringBuilder - { - PageSize = 4096, - CacheSize = 2000, - SyncMode = SynchronizationModes.Normal, - DataSource = dbPath, - JournalMode = SQLiteJournalModeEnum.Wal - }; - - var connection = new SQLiteConnection(connectionstr.ConnectionString); - - await connection.OpenAsync().ConfigureAwait(false); - - return connection; - } - } - - public class DbConnector : IDbConnector - { - private readonly ILogger _logger; - - public DbConnector(ILogger logger) - { - _logger = logger; - } - - public async Task Connect(string dbPath) - { - try - { - return await SqliteExtensions.ConnectToDb(dbPath, _logger).ConfigureAwait(false); - } - catch (Exception ex) - { - _logger.ErrorException("Error opening database {0}", ex, dbPath); - - throw; - } - } - } -} \ No newline at end of file -- cgit v1.2.3 From 669af870148a92db4a851868781e2e3af4111a26 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Wed, 1 Jun 2016 02:01:43 -0400 Subject: support querying more fields --- MediaBrowser.Controller/Entities/Folder.cs | 16 ---------------- .../Persistence/SqliteItemRepository.cs | 22 ++++++++++++++++++++++ 2 files changed, 22 insertions(+), 16 deletions(-) (limited to 'MediaBrowser.Server.Implementations') diff --git a/MediaBrowser.Controller/Entities/Folder.cs b/MediaBrowser.Controller/Entities/Folder.cs index cbbd0ad68..0d307c35b 100644 --- a/MediaBrowser.Controller/Entities/Folder.cs +++ b/MediaBrowser.Controller/Entities/Folder.cs @@ -793,11 +793,6 @@ namespace MediaBrowser.Controller.Entities Logger.Debug("Query requires post-filtering due to ItemSortBy.Metascore"); return true; } - if (query.SortBy.Contains(ItemSortBy.OfficialRating, StringComparer.OrdinalIgnoreCase)) - { - Logger.Debug("Query requires post-filtering due to ItemSortBy.OfficialRating"); - return true; - } if (query.SortBy.Contains(ItemSortBy.Players, StringComparer.OrdinalIgnoreCase)) { Logger.Debug("Query requires post-filtering due to ItemSortBy.Players"); @@ -813,11 +808,6 @@ namespace MediaBrowser.Controller.Entities Logger.Debug("Query requires post-filtering due to ItemSortBy.SeriesSortName"); return true; } - if (query.SortBy.Contains(ItemSortBy.Studio, StringComparer.OrdinalIgnoreCase)) - { - Logger.Debug("Query requires post-filtering due to ItemSortBy.Studio"); - return true; - } if (query.SortBy.Contains(ItemSortBy.VideoBitRate, StringComparer.OrdinalIgnoreCase)) { Logger.Debug("Query requires post-filtering due to ItemSortBy.VideoBitRate"); @@ -962,12 +952,6 @@ namespace MediaBrowser.Controller.Entities return true; } - if (query.OfficialRatings.Length > 0) - { - Logger.Debug("Query requires post-filtering due to OfficialRatings"); - return true; - } - if (query.IsMissing.HasValue) { Logger.Debug("Query requires post-filtering due to IsMissing"); diff --git a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs index 131158dd2..9b815bc0b 100644 --- a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs +++ b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs @@ -1913,6 +1913,14 @@ namespace MediaBrowser.Server.Implementations.Persistence { return new Tuple("(select value from itemvalues where ItemId=Guid and Type=1 LIMIT 1)", false); } + if (string.Equals(name, ItemSortBy.OfficialRating, StringComparison.OrdinalIgnoreCase)) + { + return new Tuple("ParentalRatingValue", false); + } + if (string.Equals(name, ItemSortBy.Studio, StringComparison.OrdinalIgnoreCase)) + { + return new Tuple("(select value from itemvalues where ItemId=Guid and Type=3 LIMIT 1)", false); + } return new Tuple(name, false); } @@ -2573,6 +2581,20 @@ namespace MediaBrowser.Server.Implementations.Persistence whereClauses.Add(clause); } + if (query.OfficialRatings.Length > 0) + { + var clauses = new List(); + var index = 0; + foreach (var item in query.OfficialRatings) + { + clauses.Add("OfficialRating=@OfficialRating" + index); + cmd.Parameters.Add(cmd, "@OfficialRating" + index, DbType.String).Value = item; + index++; + } + var clause = "(" + string.Join(" OR ", clauses.ToArray()) + ")"; + whereClauses.Add(clause); + } + if (query.MinParentalRating.HasValue) { whereClauses.Add("InheritedParentalRatingValue<=@MinParentalRating"); -- cgit v1.2.3 From 900cf09e0329af915b36b203b4a1e03477507e04 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Wed, 1 Jun 2016 02:20:21 -0400 Subject: use similar query for intros --- .../Intros/DefaultIntroProvider.cs | 182 +-------------------- .../Persistence/SqliteItemRepository.cs | 14 +- 2 files changed, 21 insertions(+), 175 deletions(-) (limited to 'MediaBrowser.Server.Implementations') diff --git a/MediaBrowser.Server.Implementations/Intros/DefaultIntroProvider.cs b/MediaBrowser.Server.Implementations/Intros/DefaultIntroProvider.cs index df128a90b..7c7a535cd 100644 --- a/MediaBrowser.Server.Implementations/Intros/DefaultIntroProvider.cs +++ b/MediaBrowser.Server.Implementations/Intros/DefaultIntroProvider.cs @@ -63,16 +63,8 @@ namespace MediaBrowser.Server.Implementations.Intros ? null : _localization.GetRatingLevel(item.OfficialRating); - var random = new Random(Environment.TickCount + Guid.NewGuid().GetHashCode()); - var candidates = new List(); - var itemPeople = _libraryManager.GetPeople(item); - var allPeople = _libraryManager.GetPeople(new InternalPeopleQuery - { - AppearsInItemId = item.Id - }); - var trailerTypes = new List(); if (config.EnableIntrosFromMoviesInLibrary) @@ -105,26 +97,25 @@ namespace MediaBrowser.Server.Implementations.Intros var trailerResult = _libraryManager.GetItemList(new InternalItemsQuery { IncludeItemTypes = new[] { typeof(Trailer).Name }, - TrailerTypes = trailerTypes.ToArray() + TrailerTypes = trailerTypes.ToArray(), + SimilarTo = item, + IsPlayed = config.EnableIntrosForWatchedContent ? (bool?) null : false, + MaxParentalRating = config.EnableIntrosParentalControl ? ratingLevel : null, + Limit = config.TrailerLimit }); candidates.AddRange(trailerResult.Select(i => new ItemWithTrailer { Item = i, Type = i.SourceType == SourceType.Channel ? ItemWithTrailerType.ChannelTrailer : ItemWithTrailerType.ItemWithTrailer, - User = user, - WatchingItem = item, - WatchingItemPeople = itemPeople, - AllPeople = allPeople, - Random = random, LibraryManager = _libraryManager })); } - return GetResult(item, candidates, config, ratingLevel); + return GetResult(item, candidates, config); } - private IEnumerable GetResult(BaseItem item, IEnumerable candidates, CinemaModeConfiguration config, int? ratingLevel) + private IEnumerable GetResult(BaseItem item, IEnumerable candidates, CinemaModeConfiguration config) { var customIntros = !string.IsNullOrWhiteSpace(config.CustomIntroPath) ? GetCustomIntros(config) : @@ -134,48 +125,12 @@ namespace MediaBrowser.Server.Implementations.Intros GetMediaInfoIntros(config, item) : new List(); - var trailerLimit = config.TrailerLimit; - // Avoid implicitly captured closure - return candidates.Where(i => - { - if (config.EnableIntrosParentalControl && !FilterByParentalRating(ratingLevel, i.Item)) - { - return false; - } - - if (!config.EnableIntrosForWatchedContent && i.IsPlayed) - { - return false; - } - return !IsDuplicate(item, i.Item); - }) - .OrderByDescending(i => i.Score) - .ThenBy(i => Guid.NewGuid()) - .ThenByDescending(i => i.IsPlayed ? 0 : 1) - .Select(i => i.IntroInfo) - .Take(trailerLimit) + return candidates.Select(i => i.IntroInfo) .Concat(customIntros.Take(1)) .Concat(mediaInfoIntros); } - private bool IsDuplicate(BaseItem playingContent, BaseItem test) - { - var id = playingContent.GetProviderId(MetadataProviders.Imdb); - if (!string.IsNullOrWhiteSpace(id) && string.Equals(id, test.GetProviderId(MetadataProviders.Imdb), StringComparison.OrdinalIgnoreCase)) - { - return true; - } - - id = playingContent.GetProviderId(MetadataProviders.Tmdb); - if (!string.IsNullOrWhiteSpace(id) && string.Equals(id, test.GetProviderId(MetadataProviders.Tmdb), StringComparison.OrdinalIgnoreCase)) - { - return true; - } - - return false; - } - private CinemaModeConfiguration GetOptions() { return _serverConfig.GetConfiguration("cinemamode"); @@ -346,96 +301,6 @@ namespace MediaBrowser.Server.Implementations.Intros return list.Distinct(StringComparer.OrdinalIgnoreCase); } - private bool FilterByParentalRating(int? ratingLevel, BaseItem item) - { - // Only content rated same or lower - if (ratingLevel.HasValue) - { - var level = string.IsNullOrWhiteSpace(item.OfficialRating) - ? (int?)null - : _localization.GetRatingLevel(item.OfficialRating); - - return level.HasValue && level.Value <= ratingLevel.Value; - } - - return true; - } - - internal static int GetSimiliarityScore(BaseItem item1, List item1People, List allPeople, BaseItem item2, Random random, ILibraryManager libraryManager) - { - var points = 0; - - if (!string.IsNullOrEmpty(item1.OfficialRating) && string.Equals(item1.OfficialRating, item2.OfficialRating, StringComparison.OrdinalIgnoreCase)) - { - points += 10; - } - - // Find common genres - points += item1.Genres.Where(i => item2.Genres.Contains(i, StringComparer.OrdinalIgnoreCase)).Sum(i => 10); - - // Find common tags - points += GetTags(item1).Where(i => GetTags(item2).Contains(i, StringComparer.OrdinalIgnoreCase)).Sum(i => 10); - - // Find common keywords - points += GetKeywords(item1).Where(i => GetKeywords(item2).Contains(i, StringComparer.OrdinalIgnoreCase)).Sum(i => 10); - - // Find common studios - points += item1.Studios.Where(i => item2.Studios.Contains(i, StringComparer.OrdinalIgnoreCase)).Sum(i => 5); - - var item2PeopleNames = allPeople.Where(i => i.ItemId == item2.Id) - .Select(i => i.Name) - .Where(i => !string.IsNullOrWhiteSpace(i)) - .DistinctNames() - .ToDictionary(i => i, StringComparer.OrdinalIgnoreCase); - - points += item1People.Where(i => item2PeopleNames.ContainsKey(i.Name)).Sum(i => - { - if (string.Equals(i.Type, PersonType.Director, StringComparison.OrdinalIgnoreCase) || string.Equals(i.Role, PersonType.Director, StringComparison.OrdinalIgnoreCase)) - { - return 5; - } - if (string.Equals(i.Type, PersonType.Actor, StringComparison.OrdinalIgnoreCase) || string.Equals(i.Role, PersonType.Actor, StringComparison.OrdinalIgnoreCase)) - { - return 3; - } - if (string.Equals(i.Type, PersonType.Composer, StringComparison.OrdinalIgnoreCase) || string.Equals(i.Role, PersonType.Composer, StringComparison.OrdinalIgnoreCase)) - { - return 3; - } - if (string.Equals(i.Type, PersonType.GuestStar, StringComparison.OrdinalIgnoreCase) || string.Equals(i.Role, PersonType.GuestStar, StringComparison.OrdinalIgnoreCase)) - { - return 3; - } - if (string.Equals(i.Type, PersonType.Writer, StringComparison.OrdinalIgnoreCase) || string.Equals(i.Role, PersonType.Writer, StringComparison.OrdinalIgnoreCase)) - { - return 2; - } - - return 1; - }); - - // Add some randomization so that you're not always seeing the same ones for a given movie - points += random.Next(0, 50); - - return points; - } - - private static IEnumerable GetTags(BaseItem item) - { - var hasTags = item as IHasTags; - if (hasTags != null) - { - return hasTags.Tags; - } - - return new List(); - } - - private static IEnumerable GetKeywords(BaseItem item) - { - return item.Keywords; - } - public IEnumerable GetAllIntroFiles() { return GetCustomIntroFiles(GetOptions(), true, true); @@ -455,39 +320,8 @@ namespace MediaBrowser.Server.Implementations.Intros { internal BaseItem Item; internal ItemWithTrailerType Type; - internal User User; - internal BaseItem WatchingItem; - internal List WatchingItemPeople; - internal List AllPeople; - internal Random Random; internal ILibraryManager LibraryManager; - private bool? _isPlayed; - public bool IsPlayed - { - get - { - if (!_isPlayed.HasValue) - { - _isPlayed = Item.IsPlayed(User); - } - return _isPlayed.Value; - } - } - - private int? _score; - public int Score - { - get - { - if (!_score.HasValue) - { - _score = GetSimiliarityScore(WatchingItem, WatchingItemPeople, AllPeople, Item, Random, LibraryManager); - } - return _score.Value; - } - } - public IntroInfo IntroInfo { get diff --git a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs index 9b815bc0b..c00c4bf30 100644 --- a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs +++ b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs @@ -1526,6 +1526,11 @@ namespace MediaBrowser.Server.Implementations.Persistence return false; } + if (query.SimilarTo != null) + { + return true; + } + if (query.SortBy != null && query.SortBy.Length > 0) { if (query.SortBy.Contains(ItemSortBy.IsFavoriteOrLiked, StringComparer.OrdinalIgnoreCase)) @@ -1835,7 +1840,14 @@ namespace MediaBrowser.Server.Implementations.Persistence { if (query.SortBy == null || query.SortBy.Length == 0) { - query.SortBy = new[] { "SimilarityScore", "Random" }; + if (query.User != null) + { + query.SortBy = new[] { "SimilarityScore", "IsUnplayed", "Random" }; + } + else + { + query.SortBy = new[] { "SimilarityScore", "Random" }; + } query.SortOrder = SortOrder.Descending; } } -- cgit v1.2.3 From df3cd3e2f688c8397f2ed07eff36d4894bc0804e Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Wed, 1 Jun 2016 11:21:22 -0400 Subject: updated nuget --- MediaBrowser.Providers/Movies/MovieExternalIds.cs | 7 +++++++ .../MediaBrowser.Server.Implementations.csproj | 7 ++++--- MediaBrowser.Server.Implementations/packages.config | 4 ++-- 3 files changed, 13 insertions(+), 5 deletions(-) (limited to 'MediaBrowser.Server.Implementations') diff --git a/MediaBrowser.Providers/Movies/MovieExternalIds.cs b/MediaBrowser.Providers/Movies/MovieExternalIds.cs index 3bceb976e..a6b7bde6f 100644 --- a/MediaBrowser.Providers/Movies/MovieExternalIds.cs +++ b/MediaBrowser.Providers/Movies/MovieExternalIds.cs @@ -148,6 +148,13 @@ namespace MediaBrowser.Providers.Movies public bool Supports(IHasProviderIds item) { + // Supports images for tv movies + var tvProgram = item as LiveTvProgram; + if (tvProgram != null && tvProgram.IsMovie) + { + return true; + } + return item is Movie || item is MusicVideo || item is Series || item is Episode || item is Trailer; } } diff --git a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj index 385a94aa5..0df6c338c 100644 --- a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj +++ b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj @@ -46,11 +46,12 @@ ..\packages\CommonIO.1.0.0.9\lib\net45\CommonIO.dll - ..\packages\Emby.XmlTv.1.0.0.49\lib\net45\Emby.XmlTv.dll + ..\packages\Emby.XmlTv.1.0.0.50\lib\net45\Emby.XmlTv.dll True - - ..\packages\ini-parser.2.2.4\lib\net20\INIFileParser.dll + + ..\packages\ini-parser.2.3.0\lib\net20\INIFileParser.dll + True ..\packages\Interfaces.IO.1.0.0.5\lib\portable-net45+sl4+wp71+win8+wpa81\Interfaces.IO.dll diff --git a/MediaBrowser.Server.Implementations/packages.config b/MediaBrowser.Server.Implementations/packages.config index 9b050672c..9d1aa2c33 100644 --- a/MediaBrowser.Server.Implementations/packages.config +++ b/MediaBrowser.Server.Implementations/packages.config @@ -1,8 +1,8 @@  - - + + -- cgit v1.2.3 From a8c11c0fd2c6517205e3b47a7ec63b825c1b85c8 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Wed, 1 Jun 2016 11:54:11 -0400 Subject: support trailers for episodes --- MediaBrowser.Server.Implementations/Library/LibraryManager.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'MediaBrowser.Server.Implementations') diff --git a/MediaBrowser.Server.Implementations/Library/LibraryManager.cs b/MediaBrowser.Server.Implementations/Library/LibraryManager.cs index 56d3bd4de..032f8dbb7 100644 --- a/MediaBrowser.Server.Implementations/Library/LibraryManager.cs +++ b/MediaBrowser.Server.Implementations/Library/LibraryManager.cs @@ -2309,7 +2309,7 @@ namespace MediaBrowser.Server.Implementations.Library public IEnumerable