diff --git a/MediaBrowser.Api/ConfigurationService.cs b/MediaBrowser.Api/ConfigurationService.cs index d8ecc3685..b0b74ed66 100644 --- a/MediaBrowser.Api/ConfigurationService.cs +++ b/MediaBrowser.Api/ConfigurationService.cs @@ -55,6 +55,13 @@ namespace MediaBrowser.Api public bool Enabled { get; set; } } + [Route("/System/Configuration/VideoImageExtraction", "POST")] + [Api(("Updates image extraction for all types"))] + public class UpdateVideoImageExtraction : IReturnVoid + { + public bool Enabled { get; set; } + } + public class ConfigurationService : BaseApiService { /// @@ -123,6 +130,20 @@ namespace MediaBrowser.Api /// This is a temporary method used until image settings get broken out. /// /// + public void Post(UpdateVideoImageExtraction request) + { + var config = _configurationManager.Configuration; + + EnableImageExtractionForType(typeof(Movie), config, request.Enabled); + EnableImageExtractionForType(typeof(Episode), config, request.Enabled); + EnableImageExtractionForType(typeof(AdultVideo), config, request.Enabled); + EnableImageExtractionForType(typeof(MusicVideo), config, request.Enabled); + EnableImageExtractionForType(typeof(Video), config, request.Enabled); + EnableImageExtractionForType(typeof(Trailer), config, request.Enabled); + + _configurationManager.SaveConfiguration(); + } + public void Post(UpdateSaveLocalMetadata request) { var config = _configurationManager.Configuration; @@ -157,7 +178,7 @@ namespace MediaBrowser.Api _configurationManager.SaveConfiguration(); } - + private void DisableSaversForType(Type type, ServerConfiguration config) { var options = GetMetadataOptions(type, config); @@ -174,6 +195,32 @@ namespace MediaBrowser.Api } } + private void EnableImageExtractionForType(Type type, ServerConfiguration config, bool enabled) + { + var options = GetMetadataOptions(type, config); + + const string imageProviderName = "Screen Grabber"; + + var contains = options.DisabledImageFetchers.Contains(imageProviderName, StringComparer.OrdinalIgnoreCase); + + if (!enabled && !contains) + { + var list = options.DisabledImageFetchers.ToList(); + + list.Add(imageProviderName); + + options.DisabledImageFetchers = list.ToArray(); + } + else if (enabled && contains) + { + var list = options.DisabledImageFetchers.ToList(); + + list.Remove(imageProviderName); + + options.DisabledImageFetchers = list.ToArray(); + } + } + private MetadataOptions GetMetadataOptions(Type type, ServerConfiguration config) { var options = config.MetadataOptions diff --git a/MediaBrowser.Api/LibraryService.cs b/MediaBrowser.Api/LibraryService.cs index aeb795a78..f8b4caf94 100644 --- a/MediaBrowser.Api/LibraryService.cs +++ b/MediaBrowser.Api/LibraryService.cs @@ -435,56 +435,11 @@ namespace MediaBrowser.Api Task.WaitAll(task); } - private async Task DeleteItem(DeleteItem request) + private Task DeleteItem(DeleteItem request) { var item = _dtoService.GetItemByDtoId(request.Id); - var parent = item.Parent; - - var locationType = item.LocationType; - - if (locationType == LocationType.FileSystem || locationType == LocationType.Offline) - { - foreach (var path in item.GetDeletePaths().ToList()) - { - if (Directory.Exists(path)) - { - Directory.Delete(path, true); - } - else if (File.Exists(path)) - { - File.Delete(path); - } - } - - if (parent != null) - { - try - { - await parent.ValidateChildren(new Progress(), CancellationToken.None) - .ConfigureAwait(false); - } - catch (Exception ex) - { - Logger.ErrorException("Error refreshing item", ex); - } - } - } - else if (parent != null) - { - try - { - await parent.RemoveChild(item, CancellationToken.None).ConfigureAwait(false); - } - catch (Exception ex) - { - Logger.ErrorException("Error removing item", ex); - } - } - else - { - throw new InvalidOperationException("Don't know how to delete " + item.Name); - } + return _libraryManager.DeleteItem(item); } /// diff --git a/MediaBrowser.Controller/Library/ILibraryManager.cs b/MediaBrowser.Controller/Library/ILibraryManager.cs index e5e7db13d..a34cfa78e 100644 --- a/MediaBrowser.Controller/Library/ILibraryManager.cs +++ b/MediaBrowser.Controller/Library/ILibraryManager.cs @@ -330,5 +330,12 @@ namespace MediaBrowser.Controller.Library /// /// The item. void RegisterItem(BaseItem item); + + /// + /// Deletes the item. + /// + /// The item. + /// Task. + Task DeleteItem(BaseItem item); } } \ No newline at end of file diff --git a/MediaBrowser.Controller/Persistence/IItemRepository.cs b/MediaBrowser.Controller/Persistence/IItemRepository.cs index 3a5cb4e87..cc4314256 100644 --- a/MediaBrowser.Controller/Persistence/IItemRepository.cs +++ b/MediaBrowser.Controller/Persistence/IItemRepository.cs @@ -26,6 +26,14 @@ namespace MediaBrowser.Controller.Persistence /// Task. Task SaveItem(BaseItem item, CancellationToken cancellationToken); + /// + /// Deletes the item. + /// + /// The identifier. + /// The cancellation token. + /// Task. + Task DeleteItem(Guid id, CancellationToken cancellationToken); + /// /// Gets the critic reviews. /// diff --git a/MediaBrowser.Model/Configuration/ServerConfiguration.cs b/MediaBrowser.Model/Configuration/ServerConfiguration.cs index 62b9c0e47..21414768e 100644 --- a/MediaBrowser.Model/Configuration/ServerConfiguration.cs +++ b/MediaBrowser.Model/Configuration/ServerConfiguration.cs @@ -166,8 +166,6 @@ namespace MediaBrowser.Model.Configuration public bool EnableTmdbUpdates { get; set; } public bool EnableFanArtUpdates { get; set; } - public bool EnableVideoImageExtraction { get; set; } - /// /// Gets or sets the image saving convention. /// @@ -218,7 +216,6 @@ namespace MediaBrowser.Model.Configuration EnableHttpLevelLogging = true; EnableDashboardResponseCaching = true; - EnableVideoImageExtraction = true; EnableMovieChapterImageExtraction = true; EnableEpisodeChapterImageExtraction = false; EnableOtherVideoChapterImageExtraction = false; diff --git a/MediaBrowser.Providers/BoxSets/MovieDbBoxSetProvider.cs b/MediaBrowser.Providers/BoxSets/MovieDbBoxSetProvider.cs index 75a104edf..beb8fe887 100644 --- a/MediaBrowser.Providers/BoxSets/MovieDbBoxSetProvider.cs +++ b/MediaBrowser.Providers/BoxSets/MovieDbBoxSetProvider.cs @@ -1,5 +1,4 @@ -using System.Linq; -using MediaBrowser.Common.Configuration; +using MediaBrowser.Common.Configuration; using MediaBrowser.Common.IO; using MediaBrowser.Common.Net; using MediaBrowser.Controller.Configuration; @@ -14,6 +13,7 @@ using System; using System.Collections.Generic; using System.Globalization; using System.IO; +using System.Linq; using System.Threading; using System.Threading.Tasks; diff --git a/MediaBrowser.Providers/GameGenres/GameGenreImageProvider.cs b/MediaBrowser.Providers/GameGenres/GameGenreImageProvider.cs index 12f14676f..e994e27c3 100644 --- a/MediaBrowser.Providers/GameGenres/GameGenreImageProvider.cs +++ b/MediaBrowser.Providers/GameGenres/GameGenreImageProvider.cs @@ -37,7 +37,7 @@ namespace MediaBrowser.Providers.GameGenres public static string ProviderName { - get { return "Media Browser Images"; } + get { return "Media Browser Designs"; } } public bool Supports(IHasImages item) diff --git a/MediaBrowser.Providers/Genres/GenreImageProvider.cs b/MediaBrowser.Providers/Genres/GenreImageProvider.cs index 4d19bb91e..5d5c2873a 100644 --- a/MediaBrowser.Providers/Genres/GenreImageProvider.cs +++ b/MediaBrowser.Providers/Genres/GenreImageProvider.cs @@ -38,7 +38,7 @@ namespace MediaBrowser.Providers.Genres public static string ProviderName { - get { return "Media Browser Images"; } + get { return "Media Browser Designs"; } } public bool Supports(IHasImages item) diff --git a/MediaBrowser.Providers/MediaInfo/AudioImageProvider.cs b/MediaBrowser.Providers/MediaInfo/AudioImageProvider.cs index 772f60163..7d9e3e315 100644 --- a/MediaBrowser.Providers/MediaInfo/AudioImageProvider.cs +++ b/MediaBrowser.Providers/MediaInfo/AudioImageProvider.cs @@ -151,7 +151,7 @@ namespace MediaBrowser.Providers.MediaInfo public string Name { - get { return "Embedded Image"; } + get { return "Image Extractor"; } } public bool Supports(IHasImages item) diff --git a/MediaBrowser.Providers/MediaInfo/VideoImageProvider.cs b/MediaBrowser.Providers/MediaInfo/VideoImageProvider.cs index c230f65f9..03cdc3e72 100644 --- a/MediaBrowser.Providers/MediaInfo/VideoImageProvider.cs +++ b/MediaBrowser.Providers/MediaInfo/VideoImageProvider.cs @@ -113,16 +113,11 @@ namespace MediaBrowser.Providers.MediaInfo public string Name { - get { return "Embedded Image"; } + get { return "Screen Grabber"; } } public bool Supports(IHasImages item) { - if (!_config.Configuration.EnableVideoImageExtraction) - { - return false; - } - return item.LocationType == LocationType.FileSystem && item is Video; } diff --git a/MediaBrowser.Providers/Movies/FanartMovieImageProvider.cs b/MediaBrowser.Providers/Movies/FanartMovieImageProvider.cs index b11569495..730d66cc2 100644 --- a/MediaBrowser.Providers/Movies/FanartMovieImageProvider.cs +++ b/MediaBrowser.Providers/Movies/FanartMovieImageProvider.cs @@ -431,7 +431,7 @@ namespace MediaBrowser.Providers.Movies if (fileInfo.Exists) { - if (_config.Configuration.EnableFanArtUpdates || (DateTime.UtcNow - _fileSystem.GetLastWriteTimeUtc(fileInfo)).TotalDays <= 7) + if ((DateTime.UtcNow - _fileSystem.GetLastWriteTimeUtc(fileInfo)).TotalDays <= 7) { return _cachedTask; } diff --git a/MediaBrowser.Providers/Movies/MovieDbProvider.cs b/MediaBrowser.Providers/Movies/MovieDbProvider.cs index 0a92092e5..2dc65e620 100644 --- a/MediaBrowser.Providers/Movies/MovieDbProvider.cs +++ b/MediaBrowser.Providers/Movies/MovieDbProvider.cs @@ -187,7 +187,7 @@ namespace MediaBrowser.Providers.Movies if (fileInfo.Exists) { // If it's recent or automatic updates are enabled, don't re-download - if ((_configurationManager.Configuration.EnableTmdbUpdates) || (DateTime.UtcNow - _fileSystem.GetLastWriteTimeUtc(fileInfo)).TotalDays <= 7) + if ((DateTime.UtcNow - _fileSystem.GetLastWriteTimeUtc(fileInfo)).TotalDays <= 7) { return _cachedTask; } diff --git a/MediaBrowser.Providers/Music/AlbumImageFromSongProvider.cs b/MediaBrowser.Providers/Music/AlbumImageFromSongProvider.cs index 0e073c783..dac3c4836 100644 --- a/MediaBrowser.Providers/Music/AlbumImageFromSongProvider.cs +++ b/MediaBrowser.Providers/Music/AlbumImageFromSongProvider.cs @@ -33,7 +33,7 @@ namespace MediaBrowser.Providers.Music public string Name { - get { return "Embedded Image"; } + get { return "Image Extractor"; } } public bool Supports(IHasImages item) diff --git a/MediaBrowser.Providers/Music/FanArtArtistProvider.cs b/MediaBrowser.Providers/Music/FanArtArtistProvider.cs index d96178059..b5557d6f0 100644 --- a/MediaBrowser.Providers/Music/FanArtArtistProvider.cs +++ b/MediaBrowser.Providers/Music/FanArtArtistProvider.cs @@ -398,7 +398,7 @@ namespace MediaBrowser.Providers.Music if (fileInfo.Exists) { - if (_config.Configuration.EnableFanArtUpdates || (DateTime.UtcNow - _fileSystem.GetLastWriteTimeUtc(fileInfo)).TotalDays <= 7) + if ((DateTime.UtcNow - _fileSystem.GetLastWriteTimeUtc(fileInfo)).TotalDays <= 7) { return _cachedTask; } diff --git a/MediaBrowser.Providers/MusicGenres/MusicGenreImageProvider.cs b/MediaBrowser.Providers/MusicGenres/MusicGenreImageProvider.cs index 6c239ab30..3236567fc 100644 --- a/MediaBrowser.Providers/MusicGenres/MusicGenreImageProvider.cs +++ b/MediaBrowser.Providers/MusicGenres/MusicGenreImageProvider.cs @@ -38,7 +38,7 @@ namespace MediaBrowser.Providers.MusicGenres public static string ProviderName { - get { return "Media Browser Images"; } + get { return "Media Browser Designs"; } } public bool Supports(IHasImages item) diff --git a/MediaBrowser.Providers/Studios/StudiosImageProvider.cs b/MediaBrowser.Providers/Studios/StudiosImageProvider.cs index 994b70902..f46c9a906 100644 --- a/MediaBrowser.Providers/Studios/StudiosImageProvider.cs +++ b/MediaBrowser.Providers/Studios/StudiosImageProvider.cs @@ -37,7 +37,7 @@ namespace MediaBrowser.Providers.Studios public static string ProviderName { - get { return "Media Browser Images"; } + get { return "Media Browser Designs"; } } public bool Supports(IHasImages item) diff --git a/MediaBrowser.Providers/TV/FanartSeriesProvider.cs b/MediaBrowser.Providers/TV/FanartSeriesProvider.cs index 1b9f62dd4..5f9754e4a 100644 --- a/MediaBrowser.Providers/TV/FanartSeriesProvider.cs +++ b/MediaBrowser.Providers/TV/FanartSeriesProvider.cs @@ -376,7 +376,7 @@ namespace MediaBrowser.Providers.TV if (fileInfo.Exists) { - if (_config.Configuration.EnableFanArtUpdates || (DateTime.UtcNow - _fileSystem.GetLastWriteTimeUtc(fileInfo)).TotalDays <= 7) + if ((DateTime.UtcNow - _fileSystem.GetLastWriteTimeUtc(fileInfo)).TotalDays <= 7) { return _cachedTask; } diff --git a/MediaBrowser.Providers/TV/MovieDbSeriesProvider.cs b/MediaBrowser.Providers/TV/MovieDbSeriesProvider.cs index 733e2c915..5b7679e74 100644 --- a/MediaBrowser.Providers/TV/MovieDbSeriesProvider.cs +++ b/MediaBrowser.Providers/TV/MovieDbSeriesProvider.cs @@ -272,7 +272,7 @@ namespace MediaBrowser.Providers.TV if (fileInfo.Exists) { // If it's recent or automatic updates are enabled, don't re-download - if ((_configurationManager.Configuration.EnableTmdbUpdates) || (DateTime.UtcNow - _fileSystem.GetLastWriteTimeUtc(fileInfo)).TotalDays <= 7) + if ((DateTime.UtcNow - _fileSystem.GetLastWriteTimeUtc(fileInfo)).TotalDays <= 7) { return _cachedTask; } diff --git a/MediaBrowser.Server.Implementations/Library/LibraryManager.cs b/MediaBrowser.Server.Implementations/Library/LibraryManager.cs index a06e03c4a..656e0993f 100644 --- a/MediaBrowser.Server.Implementations/Library/LibraryManager.cs +++ b/MediaBrowser.Server.Implementations/Library/LibraryManager.cs @@ -408,6 +408,83 @@ namespace MediaBrowser.Server.Implementations.Library LibraryItemsCache.AddOrUpdate(item.Id, item, delegate { return item; }); } + public async Task DeleteItem(BaseItem item) + { + var parent = item.Parent; + + var locationType = item.LocationType; + + var children = item.IsFolder + ? ((Folder)item).RecursiveChildren.ToList() + : new List(); + + foreach (var metadataPath in GetMetadataPaths(item, children)) + { + _logger.Debug("Deleting path {0}", metadataPath); + + try + { + Directory.Delete(metadataPath, true); + } + catch (DirectoryNotFoundException) + { + + } + catch (Exception ex) + { + _logger.ErrorException("Error deleting {0}", ex, metadataPath); + } + } + + if (locationType == LocationType.FileSystem || locationType == LocationType.Offline) + { + foreach (var path in item.GetDeletePaths().ToList()) + { + if (Directory.Exists(path)) + { + _logger.Debug("Deleting path {0}", path); + Directory.Delete(path, true); + } + else if (File.Exists(path)) + { + _logger.Debug("Deleting path {0}", path); + File.Delete(path); + } + } + + if (parent != null) + { + await parent.ValidateChildren(new Progress(), CancellationToken.None) + .ConfigureAwait(false); + } + } + else if (parent != null) + { + await parent.RemoveChild(item, CancellationToken.None).ConfigureAwait(false); + } + else + { + throw new InvalidOperationException("Don't know how to delete " + item.Name); + } + + foreach (var child in children) + { + await ItemRepository.DeleteItem(child.Id, CancellationToken.None).ConfigureAwait(false); + } + } + + private IEnumerable GetMetadataPaths(BaseItem item, IEnumerable children) + { + var list = new List + { + ConfigurationManager.ApplicationPaths.GetInternalMetadataPath(item.Id) + }; + + list.AddRange(children.Select(i => ConfigurationManager.ApplicationPaths.GetInternalMetadataPath(i.Id))); + + return list; + } + /// /// Resolves the item. /// diff --git a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs index 71cf58785..1098dbf6d 100644 --- a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs +++ b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs @@ -61,6 +61,7 @@ namespace MediaBrowser.Server.Implementations.Persistence private IDbCommand _deleteChildrenCommand; private IDbCommand _saveChildrenCommand; + private IDbCommand _deleteItemCommand; /// /// Initializes a new instance of the class. @@ -156,6 +157,10 @@ namespace MediaBrowser.Server.Implementations.Persistence _deleteChildrenCommand.CommandText = "delete from ChildrenIds where ParentId=@ParentId"; _deleteChildrenCommand.Parameters.Add(_deleteChildrenCommand, "@ParentId"); + _deleteItemCommand = _connection.CreateCommand(); + _deleteItemCommand.CommandText = "delete from TypedBaseItems where guid=@Id"; + _deleteItemCommand.Parameters.Add(_deleteItemCommand, "@Id"); + _saveChildrenCommand = _connection.CreateCommand(); _saveChildrenCommand.CommandText = "replace into ChildrenIds (ParentId, ItemId) values (@ParentId, @ItemId)"; _saveChildrenCommand.Parameters.Add(_saveChildrenCommand, "@ParentId"); @@ -463,6 +468,64 @@ namespace MediaBrowser.Server.Implementations.Persistence } } + public async Task DeleteItem(Guid id, CancellationToken cancellationToken) + { + if (id == Guid.Empty) + { + throw new ArgumentNullException("id"); + } + + await _writeLock.WaitAsync(cancellationToken).ConfigureAwait(false); + + IDbTransaction transaction = null; + + try + { + transaction = _connection.BeginTransaction(); + + // First delete children + _deleteChildrenCommand.GetParameter(0).Value = id; + _deleteChildrenCommand.Transaction = transaction; + _deleteChildrenCommand.ExecuteNonQuery(); + + // Delete the item + _deleteItemCommand.GetParameter(0).Value = id; + _deleteItemCommand.Transaction = transaction; + _deleteItemCommand.ExecuteNonQuery(); + + transaction.Commit(); + } + catch (OperationCanceledException) + { + if (transaction != null) + { + transaction.Rollback(); + } + + throw; + } + catch (Exception e) + { + _logger.ErrorException("Failed to save children:", e); + + if (transaction != null) + { + transaction.Rollback(); + } + + throw; + } + finally + { + if (transaction != null) + { + transaction.Dispose(); + } + + _writeLock.Release(); + } + } + public async Task SaveChildren(Guid parentId, IEnumerable children, CancellationToken cancellationToken) { if (parentId == Guid.Empty) @@ -475,8 +538,6 @@ namespace MediaBrowser.Server.Implementations.Persistence throw new ArgumentNullException("children"); } - cancellationToken.ThrowIfCancellationRequested(); - await _writeLock.WaitAsync(cancellationToken).ConfigureAwait(false); IDbTransaction transaction = null;