From d8d5dd487326dd3fccf4e9f30cd8f7e3783fcfda Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Mon, 12 Jan 2015 22:46:44 -0500 Subject: make channel access opt-in rather than opt out --- MediaBrowser.Controller/Channels/Channel.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'MediaBrowser.Controller/Channels') diff --git a/MediaBrowser.Controller/Channels/Channel.cs b/MediaBrowser.Controller/Channels/Channel.cs index 5a9fc33227..6ee6fe0062 100644 --- a/MediaBrowser.Controller/Channels/Channel.cs +++ b/MediaBrowser.Controller/Channels/Channel.cs @@ -14,7 +14,7 @@ namespace MediaBrowser.Controller.Channels public override bool IsVisible(User user) { - if (user.Policy.BlockedChannels.Contains(Id.ToString("N"), StringComparer.OrdinalIgnoreCase)) + if (!user.Policy.EnableAllChannels && !user.Policy.EnabledChannels.Contains(Id.ToString("N"), StringComparer.OrdinalIgnoreCase)) { return false; } -- cgit v1.2.3 From f636c10e24a6f26f1c8e41ba6d3751334d6dcb90 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Tue, 20 Jan 2015 22:54:45 -0500 Subject: sync updates --- .../Library/LibraryStructureService.cs | 32 +------- .../ScheduledTasks/ScheduledTaskService.cs | 2 +- MediaBrowser.Api/StartupWizardService.cs | 1 + MediaBrowser.Api/Sync/SyncService.cs | 28 +++++++ MediaBrowser.Controller/Channels/Channel.cs | 14 +++- MediaBrowser.Controller/Entities/Folder.cs | 21 +++++- MediaBrowser.Controller/Library/ILibraryManager.cs | 9 +-- MediaBrowser.Controller/Sync/ISyncManager.cs | 19 +++++ .../Configuration/ServerConfiguration.cs | 1 + MediaBrowser.Model/Sync/SyncJobItem.cs | 2 + .../Configuration/ServerConfigurationManager.cs | 12 ++- .../Library/LibraryManager.cs | 12 +-- .../Library/UserManager.cs | 88 +--------------------- .../Localization/JavaScript/javascript.json | 5 ++ .../Sync/SyncJobProcessor.cs | 20 +++-- .../Sync/SyncManager.cs | 83 +++++++++++++++++++- .../Sync/SyncRepository.cs | 12 ++- .../ApplicationHost.cs | 2 +- 18 files changed, 206 insertions(+), 157 deletions(-) (limited to 'MediaBrowser.Controller/Channels') diff --git a/MediaBrowser.Api/Library/LibraryStructureService.cs b/MediaBrowser.Api/Library/LibraryStructureService.cs index 23f4e4e5c1..27944a4ea7 100644 --- a/MediaBrowser.Api/Library/LibraryStructureService.cs +++ b/MediaBrowser.Api/Library/LibraryStructureService.cs @@ -3,7 +3,6 @@ using MediaBrowser.Controller; using MediaBrowser.Controller.Library; using MediaBrowser.Controller.Net; using MediaBrowser.Model.Entities; -using MediaBrowser.Model.Logging; using ServiceStack; using System; using System.Collections.Generic; @@ -18,7 +17,6 @@ namespace MediaBrowser.Api.Library /// Class GetDefaultVirtualFolders /// [Route("/Library/VirtualFolders", "GET")] - [Route("/Users/{UserId}/VirtualFolders", "GET")] public class GetVirtualFolders : IReturn> { /// @@ -143,11 +141,6 @@ namespace MediaBrowser.Api.Library /// private readonly IServerApplicationPaths _appPaths; - /// - /// The _user manager - /// - private readonly IUserManager _userManager; - /// /// The _library manager /// @@ -156,27 +149,21 @@ namespace MediaBrowser.Api.Library private readonly ILibraryMonitor _libraryMonitor; private readonly IFileSystem _fileSystem; - private readonly ILogger _logger; /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// - /// The app paths. - /// The user manager. - /// The library manager. - public LibraryStructureService(IServerApplicationPaths appPaths, IUserManager userManager, ILibraryManager libraryManager, ILibraryMonitor libraryMonitor, IFileSystem fileSystem, ILogger logger) + public LibraryStructureService(IServerApplicationPaths appPaths, ILibraryManager libraryManager, ILibraryMonitor libraryMonitor, IFileSystem fileSystem) { if (appPaths == null) { throw new ArgumentNullException("appPaths"); } - _userManager = userManager; _appPaths = appPaths; _libraryManager = libraryManager; _libraryMonitor = libraryMonitor; _fileSystem = fileSystem; - _logger = logger; } /// @@ -186,20 +173,9 @@ namespace MediaBrowser.Api.Library /// System.Object. public object Get(GetVirtualFolders request) { - if (string.IsNullOrEmpty(request.UserId)) - { - var result = _libraryManager.GetDefaultVirtualFolders().OrderBy(i => i.Name).ToList(); + var result = _libraryManager.GetVirtualFolders().OrderBy(i => i.Name).ToList(); - return ToOptimizedSerializedResultUsingCache(result); - } - else - { - var user = _userManager.GetUserById(request.UserId); - - var result = _libraryManager.GetVirtualFolders(user).OrderBy(i => i.Name).ToList(); - - return ToOptimizedSerializedResultUsingCache(result); - } + return ToOptimizedSerializedResultUsingCache(result); } /// diff --git a/MediaBrowser.Api/ScheduledTasks/ScheduledTaskService.cs b/MediaBrowser.Api/ScheduledTasks/ScheduledTaskService.cs index f5b3d173bd..947b99d35f 100644 --- a/MediaBrowser.Api/ScheduledTasks/ScheduledTaskService.cs +++ b/MediaBrowser.Api/ScheduledTasks/ScheduledTaskService.cs @@ -141,7 +141,7 @@ namespace MediaBrowser.Api.ScheduledTasks result = result.Where(i => { - var isEnabled = false; + var isEnabled = true; var configurableTask = i.ScheduledTask as IConfigurableScheduledTask; diff --git a/MediaBrowser.Api/StartupWizardService.cs b/MediaBrowser.Api/StartupWizardService.cs index 97401bbf84..cb0c54674a 100644 --- a/MediaBrowser.Api/StartupWizardService.cs +++ b/MediaBrowser.Api/StartupWizardService.cs @@ -63,6 +63,7 @@ namespace MediaBrowser.Api _config.Configuration.IsStartupWizardCompleted = true; _config.Configuration.EnableLocalizedGuids = true; _config.Configuration.StoreArtistsInMetadata = true; + _config.Configuration.EnableStandaloneMetadata = true; _config.Configuration.EnableLibraryMetadataSubFolder = true; _config.SaveConfiguration(); } diff --git a/MediaBrowser.Api/Sync/SyncService.cs b/MediaBrowser.Api/Sync/SyncService.cs index 8d5ec824f8..c763aa8df1 100644 --- a/MediaBrowser.Api/Sync/SyncService.cs +++ b/MediaBrowser.Api/Sync/SyncService.cs @@ -37,6 +37,20 @@ namespace MediaBrowser.Api.Sync { } + [Route("/Sync/JobItems/{Id}/Enable", "POST", Summary = "Enables a cancelled or queued sync job item")] + public class EnableSyncJobItem : IReturnVoid + { + [ApiMember(Name = "Id", Description = "Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "POST")] + public string Id { get; set; } + } + + [Route("/Sync/JobItems/{Id}", "DELETE", Summary = "Cancels a sync job item")] + public class CancelSyncJobItem : IReturnVoid + { + [ApiMember(Name = "Id", Description = "Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "DELETE")] + public string Id { get; set; } + } + [Route("/Sync/Jobs", "GET", Summary = "Gets sync jobs.")] public class GetSyncJobs : SyncJobQuery, IReturn> { @@ -271,5 +285,19 @@ namespace MediaBrowser.Api.Sync return ToStaticFileResult(file.Path); } + + public void Post(EnableSyncJobItem request) + { + var task = _syncManager.ReEnableJobItem(request.Id); + + Task.WaitAll(task); + } + + public void Delete(CancelSyncJobItem request) + { + var task = _syncManager.CancelJobItem(request.Id); + + Task.WaitAll(task); + } } } diff --git a/MediaBrowser.Controller/Channels/Channel.cs b/MediaBrowser.Controller/Channels/Channel.cs index 6ee6fe0062..32ad2ff122 100644 --- a/MediaBrowser.Controller/Channels/Channel.cs +++ b/MediaBrowser.Controller/Channels/Channel.cs @@ -14,9 +14,19 @@ namespace MediaBrowser.Controller.Channels public override bool IsVisible(User user) { - if (!user.Policy.EnableAllChannels && !user.Policy.EnabledChannels.Contains(Id.ToString("N"), StringComparer.OrdinalIgnoreCase)) + if (user.Policy.BlockedChannels != null) { - return false; + if (user.Policy.BlockedChannels.Contains(Id.ToString("N"), StringComparer.OrdinalIgnoreCase)) + { + return false; + } + } + else + { + if (!user.Policy.EnableAllChannels && !user.Policy.EnabledChannels.Contains(Id.ToString("N"), StringComparer.OrdinalIgnoreCase)) + { + return false; + } } return base.IsVisible(user); diff --git a/MediaBrowser.Controller/Entities/Folder.cs b/MediaBrowser.Controller/Entities/Folder.cs index 8faab4c36f..005f263f7c 100644 --- a/MediaBrowser.Controller/Entities/Folder.cs +++ b/MediaBrowser.Controller/Entities/Folder.cs @@ -303,9 +303,22 @@ namespace MediaBrowser.Controller.Entities { if (this is ICollectionFolder) { - if (!user.Policy.EnableAllFolders && !user.Policy.EnabledFolders.Contains(Id.ToString("N"), StringComparer.OrdinalIgnoreCase)) + if (user.Policy.BlockedMediaFolders != null) { - return false; + if (user.Policy.BlockedMediaFolders.Contains(Id.ToString("N"), StringComparer.OrdinalIgnoreCase) || + + // Backwards compatibility + user.Policy.BlockedMediaFolders.Contains(Name, StringComparer.OrdinalIgnoreCase)) + { + return false; + } + } + else + { + if (!user.Policy.EnableAllFolders && !user.Policy.EnabledFolders.Contains(Id.ToString("N"), StringComparer.OrdinalIgnoreCase)) + { + return false; + } } } @@ -675,12 +688,12 @@ namespace MediaBrowser.Controller.Entities path = System.IO.Path.GetDirectoryName(path); } - if (ContainsPath(LibraryManager.GetDefaultVirtualFolders(), originalPath)) + if (ContainsPath(LibraryManager.GetVirtualFolders(), originalPath)) { return true; } - return UserManager.Users.Any(user => ContainsPath(LibraryManager.GetVirtualFolders(user), originalPath)); + return ContainsPath(LibraryManager.GetVirtualFolders(), originalPath); } /// diff --git a/MediaBrowser.Controller/Library/ILibraryManager.cs b/MediaBrowser.Controller/Library/ILibraryManager.cs index 2ebd1cab93..9871ef3c5f 100644 --- a/MediaBrowser.Controller/Library/ILibraryManager.cs +++ b/MediaBrowser.Controller/Library/ILibraryManager.cs @@ -123,14 +123,7 @@ namespace MediaBrowser.Controller.Library /// Gets the default view. /// /// IEnumerable{VirtualFolderInfo}. - IEnumerable GetDefaultVirtualFolders(); - - /// - /// Gets the view. - /// - /// The user. - /// IEnumerable{VirtualFolderInfo}. - IEnumerable GetVirtualFolders(User user); + IEnumerable GetVirtualFolders(); /// /// Gets the item by id. diff --git a/MediaBrowser.Controller/Sync/ISyncManager.cs b/MediaBrowser.Controller/Sync/ISyncManager.cs index 59136c0e6f..8e4b6a44a0 100644 --- a/MediaBrowser.Controller/Sync/ISyncManager.cs +++ b/MediaBrowser.Controller/Sync/ISyncManager.cs @@ -1,8 +1,10 @@ using MediaBrowser.Controller.Entities; using MediaBrowser.Model.Dlna; +using MediaBrowser.Model.Events; using MediaBrowser.Model.Querying; using MediaBrowser.Model.Sync; using MediaBrowser.Model.Users; +using System; using System.Collections.Generic; using System.Threading.Tasks; @@ -10,6 +12,9 @@ namespace MediaBrowser.Controller.Sync { public interface ISyncManager { + event EventHandler> SyncJobCreated; + event EventHandler> SyncJobCancelled; + /// /// Creates the job. /// @@ -44,6 +49,20 @@ namespace MediaBrowser.Controller.Sync /// Task. Task UpdateJob(SyncJob job); + /// + /// Res the enable job item. + /// + /// The identifier. + /// Task. + Task ReEnableJobItem(string id); + + /// + /// Cnacels the job item. + /// + /// The identifier. + /// Task. + Task CancelJobItem(string id); + /// /// Cancels the job. /// diff --git a/MediaBrowser.Model/Configuration/ServerConfiguration.cs b/MediaBrowser.Model/Configuration/ServerConfiguration.cs index 71580f3535..c641edff7f 100644 --- a/MediaBrowser.Model/Configuration/ServerConfiguration.cs +++ b/MediaBrowser.Model/Configuration/ServerConfiguration.cs @@ -169,6 +169,7 @@ namespace MediaBrowser.Model.Configuration public string DashboardSourcePath { get; set; } public bool StoreArtistsInMetadata { get; set; } + public bool EnableStandaloneMetadata { get; set; } /// /// Gets or sets the image saving convention. diff --git a/MediaBrowser.Model/Sync/SyncJobItem.cs b/MediaBrowser.Model/Sync/SyncJobItem.cs index 943014c0d2..133065bf92 100644 --- a/MediaBrowser.Model/Sync/SyncJobItem.cs +++ b/MediaBrowser.Model/Sync/SyncJobItem.cs @@ -88,6 +88,8 @@ namespace MediaBrowser.Model.Sync public string TemporaryPath { get; set; } public List AdditionalFiles { get; set; } + public bool IsMarkedForRemoval { get; set; } + public SyncJobItem() { AdditionalFiles = new List(); diff --git a/MediaBrowser.Server.Implementations/Configuration/ServerConfigurationManager.cs b/MediaBrowser.Server.Implementations/Configuration/ServerConfigurationManager.cs index b3b8ccbd8e..5f7ccec4b9 100644 --- a/MediaBrowser.Server.Implementations/Configuration/ServerConfigurationManager.cs +++ b/MediaBrowser.Server.Implementations/Configuration/ServerConfigurationManager.cs @@ -99,10 +99,20 @@ namespace MediaBrowser.Server.Implementations.Configuration private void UpdateMetadataPath() { ((ServerApplicationPaths)ApplicationPaths).InternalMetadataPath = string.IsNullOrEmpty(Configuration.MetadataPath) ? - null : + GetInternalMetadataPath() : Configuration.MetadataPath; } + private string GetInternalMetadataPath() + { + if (Configuration.EnableStandaloneMetadata) + { + return Path.Combine(ApplicationPaths.ProgramDataPath, "metadata"); + } + + return null; + } + /// /// Updates the transcoding temporary path. /// diff --git a/MediaBrowser.Server.Implementations/Library/LibraryManager.cs b/MediaBrowser.Server.Implementations/Library/LibraryManager.cs index eaab469f53..b28c987286 100644 --- a/MediaBrowser.Server.Implementations/Library/LibraryManager.cs +++ b/MediaBrowser.Server.Implementations/Library/LibraryManager.cs @@ -1124,21 +1124,11 @@ namespace MediaBrowser.Server.Implementations.Library /// Gets the default view. /// /// IEnumerable{VirtualFolderInfo}. - public IEnumerable GetDefaultVirtualFolders() + public IEnumerable GetVirtualFolders() { return GetView(ConfigurationManager.ApplicationPaths.DefaultUserViewsPath); } - /// - /// Gets the view. - /// - /// The user. - /// IEnumerable{VirtualFolderInfo}. - public IEnumerable GetVirtualFolders(User user) - { - return GetDefaultVirtualFolders(); - } - /// /// Gets the view. /// diff --git a/MediaBrowser.Server.Implementations/Library/UserManager.cs b/MediaBrowser.Server.Implementations/Library/UserManager.cs index 3020a224de..c4c0e53950 100644 --- a/MediaBrowser.Server.Implementations/Library/UserManager.cs +++ b/MediaBrowser.Server.Implementations/Library/UserManager.cs @@ -3,7 +3,6 @@ using MediaBrowser.Common.Extensions; using MediaBrowser.Common.IO; using MediaBrowser.Common.Net; using MediaBrowser.Controller; -using MediaBrowser.Controller.Channels; using MediaBrowser.Controller.Configuration; using MediaBrowser.Controller.Connect; using MediaBrowser.Controller.Drawing; @@ -13,7 +12,6 @@ using MediaBrowser.Controller.Library; using MediaBrowser.Controller.Net; using MediaBrowser.Controller.Persistence; using MediaBrowser.Controller.Providers; -using MediaBrowser.Model.Channels; using MediaBrowser.Model.Configuration; using MediaBrowser.Model.Connect; using MediaBrowser.Model.Dto; @@ -72,12 +70,10 @@ namespace MediaBrowser.Server.Implementations.Library private readonly Func _imageProcessorFactory; private readonly Func _dtoServiceFactory; private readonly Func _connectFactory; - private readonly Func _channelManager; - private readonly Func _libraryManager; private readonly IServerApplicationHost _appHost; private readonly IFileSystem _fileSystem; - public UserManager(ILogger logger, IServerConfigurationManager configurationManager, IUserRepository userRepository, IXmlSerializer xmlSerializer, INetworkManager networkManager, Func imageProcessorFactory, Func dtoServiceFactory, Func connectFactory, IServerApplicationHost appHost, IJsonSerializer jsonSerializer, IFileSystem fileSystem, Func channelManager, Func libraryManager) + public UserManager(ILogger logger, IServerConfigurationManager configurationManager, IUserRepository userRepository, IXmlSerializer xmlSerializer, INetworkManager networkManager, Func imageProcessorFactory, Func dtoServiceFactory, Func connectFactory, IServerApplicationHost appHost, IJsonSerializer jsonSerializer, IFileSystem fileSystem) { _logger = logger; UserRepository = userRepository; @@ -89,8 +85,6 @@ namespace MediaBrowser.Server.Implementations.Library _appHost = appHost; _jsonSerializer = jsonSerializer; _fileSystem = fileSystem; - _channelManager = channelManager; - _libraryManager = libraryManager; ConfigurationManager = configurationManager; Users = new List(); @@ -174,8 +168,6 @@ namespace MediaBrowser.Server.Implementations.Library foreach (var user in users) { await DoPolicyMigration(user).ConfigureAwait(false); - await DoChannelMigration(user).ConfigureAwait(false); - await DoLibraryMigration(user).ConfigureAwait(false); } // If there are no local users with admin rights, make them all admins @@ -354,84 +346,6 @@ namespace MediaBrowser.Server.Implementations.Library } } - private async Task DoChannelMigration(User user) - { - if (user.Policy.BlockedChannels != null) - { - if (user.Policy.BlockedChannels.Length > 0) - { - user.Policy.EnableAllChannels = false; - - try - { - var channelResult = await _channelManager().GetChannelsInternal(new ChannelQuery - { - UserId = user.Id.ToString("N") - - }, CancellationToken.None).ConfigureAwait(false); - - user.Policy.EnabledChannels = channelResult.Items - .Select(i => i.Id.ToString("N")) - .Except(user.Policy.BlockedChannels) - .ToArray(); - } - catch - { - user.Policy.EnabledChannels = new string[] { }; - } - } - else - { - user.Policy.EnableAllChannels = true; - user.Policy.EnabledChannels = new string[] { }; - } - - user.Policy.BlockedChannels = null; - - await UpdateUserPolicy(user, user.Policy, false); - } - } - - private async Task DoLibraryMigration(User user) - { - if (user.Policy.BlockedMediaFolders != null) - { - if (user.Policy.BlockedMediaFolders.Length > 0) - { - user.Policy.EnableAllFolders = false; - - try - { - user.Policy.EnabledFolders = _libraryManager().RootFolder - .Children - .Where(i => !user.Policy.BlockedMediaFolders.Contains(i.Name, StringComparer.OrdinalIgnoreCase) && !user.Policy.BlockedMediaFolders.Contains(i.Id.ToString("N"), StringComparer.OrdinalIgnoreCase)) - .Select(i => i.Id.ToString("N")) - .ToArray(); - } - catch - { - user.Policy.EnabledFolders = new string[] { }; - user.Policy.EnableAllFolders = true; - } - } - else - { - user.Policy.EnableAllFolders = true; - user.Policy.EnabledFolders = new string[] { }; - } - - // Just to be safe - if (user.Policy.EnabledFolders.Length == 0) - { - user.Policy.EnableAllFolders = true; - } - - user.Policy.BlockedMediaFolders = null; - - await UpdateUserPolicy(user, user.Policy, false); - } - } - public UserDto GetUserDto(User user, string remoteEndPoint = null) { if (user == null) diff --git a/MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json b/MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json index afc9bff62f..e4d20d3a15 100644 --- a/MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json +++ b/MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json @@ -56,6 +56,9 @@ "HeaderChannelAccess": "Channel Access", "HeaderDeviceAccess": "Device Access", "HeaderSelectDevices": "Select Devices", + "ButtonCancelItem": "Cancel item", + "ButtonQueueForRetry": "Queue for retry", + "ButtonReenable": "Re-enable", "LabelAbortedByServerShutdown": "(Aborted by server shutdown)", "LabelScheduledTaskLastRan": "Last ran {0}, taking {1}.", "HeaderDeleteTaskTrigger": "Delete Task Trigger", @@ -71,6 +74,8 @@ "LabelForcedStream": "(Forced)", "LabelDefaultForcedStream": "(Default/Forced)", "LabelUnknownLanguage": "Unknown language", + "HeaderConfirmation": "Confirmation", + "MessageConfirmSyncJobItemCancellation": "Are you sure you wish to cancel this item?", "ButtonMute": "Mute", "ButtonUnmute": "Unmute", "ButtonStop": "Stop", diff --git a/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs b/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs index cf0138a295..67f9d363e2 100644 --- a/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs +++ b/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs @@ -1,5 +1,4 @@ -using System.Globalization; -using MediaBrowser.Common.Configuration; +using MediaBrowser.Common.Configuration; using MediaBrowser.Common.IO; using MediaBrowser.Common.Progress; using MediaBrowser.Controller.Entities; @@ -361,11 +360,20 @@ namespace MediaBrowser.Server.Implementations.Sync var innerProgress = new ActionableProgress(); innerProgress.RegisterAction(p => progress.Report(startingPercent + (percentPerItem * p))); - var job = _syncRepo.GetJob(item.JobId); - await ProcessJobItem(job, item, enableConversion, innerProgress, cancellationToken).ConfigureAwait(false); + // Pull it fresh from the db just to make sure it wasn't deleted or cancelled while another item was converting + var jobItem = enableConversion ? _syncRepo.GetJobItem(item.Id) : item; - job = _syncRepo.GetJob(item.JobId); - await UpdateJobStatus(job).ConfigureAwait(false); + if (jobItem != null) + { + var job = _syncRepo.GetJob(jobItem.JobId); + if (jobItem.Status != SyncJobItemStatus.Cancelled) + { + await ProcessJobItem(job, jobItem, enableConversion, innerProgress, cancellationToken).ConfigureAwait(false); + } + + job = _syncRepo.GetJob(jobItem.JobId); + await UpdateJobStatus(job).ConfigureAwait(false); + } numComplete++; double percent = numComplete; diff --git a/MediaBrowser.Server.Implementations/Sync/SyncManager.cs b/MediaBrowser.Server.Implementations/Sync/SyncManager.cs index b8d884cee5..7e4455ab36 100644 --- a/MediaBrowser.Server.Implementations/Sync/SyncManager.cs +++ b/MediaBrowser.Server.Implementations/Sync/SyncManager.cs @@ -1,5 +1,6 @@ using MediaBrowser.Common; using MediaBrowser.Common.Configuration; +using MediaBrowser.Common.Events; using MediaBrowser.Common.Extensions; using MediaBrowser.Common.IO; using MediaBrowser.Controller.Channels; @@ -16,6 +17,7 @@ using MediaBrowser.Controller.TV; using MediaBrowser.Model.Dlna; using MediaBrowser.Model.Dto; using MediaBrowser.Model.Entities; +using MediaBrowser.Model.Events; using MediaBrowser.Model.Logging; using MediaBrowser.Model.Querying; using MediaBrowser.Model.Sync; @@ -47,6 +49,9 @@ namespace MediaBrowser.Server.Implementations.Sync private ISyncProvider[] _providers = { }; + public event EventHandler> SyncJobCreated; + public event EventHandler> SyncJobCancelled; + public SyncManager(ILibraryManager libraryManager, ISyncRepository repo, IImageProcessor imageProcessor, ILogger logger, IUserManager userManager, Func dtoService, IApplicationHost appHost, ITVSeriesManager tvSeriesManager, Func mediaEncoder, IFileSystem fileSystem, Func subtitleEncoder, IConfigurationManager config) { _libraryManager = libraryManager; @@ -144,6 +149,15 @@ namespace MediaBrowser.Server.Implementations.Sync await processor.SyncJobItems(jobItemsResult.Items, false, new Progress(), CancellationToken.None) .ConfigureAwait(false); + if (SyncJobCreated != null) + { + EventHelper.FireEventIfNotNull(SyncJobCreated, this, new GenericEventArgs + { + Argument = job + + }, _logger); + } + return new SyncJobCreationResult { Job = GetJob(jobId) @@ -275,9 +289,25 @@ namespace MediaBrowser.Server.Implementations.Sync } } - public Task CancelJob(string id) + public async Task CancelJob(string id) { - return _repo.DeleteJob(id); + var job = GetJob(id); + + if (job == null) + { + throw new ArgumentException("Job not found."); + } + + await _repo.DeleteJob(id).ConfigureAwait(false); + + if (SyncJobCancelled != null) + { + EventHelper.FireEventIfNotNull(SyncJobCancelled, this, new GenericEventArgs + { + Argument = job + + }, _logger); + } } public SyncJob GetJob(string id) @@ -496,7 +526,7 @@ namespace MediaBrowser.Server.Implementations.Sync .FirstOrDefault(i => string.Equals(i.Id, jobItem.MediaSourceId)); syncedItem.Item.MediaSources = new List(); - + // This will be null for items that are not audio/video if (mediaSource == null) { @@ -545,7 +575,12 @@ namespace MediaBrowser.Server.Implementations.Sync var job = _repo.GetJob(jobItem.JobId); var user = _userManager.GetUserById(job.UserId); - if (user == null) + if (jobItem.IsMarkedForRemoval) + { + // Tell the device to remove it since it has been marked for removal + response.ItemIdsToRemove.Add(jobItem.ItemId); + } + else if (user == null) { // Tell the device to remove it since the user is gone now response.ItemIdsToRemove.Add(jobItem.ItemId); @@ -609,5 +644,45 @@ namespace MediaBrowser.Server.Implementations.Sync return true; } + + public async Task ReEnableJobItem(string id) + { + var jobItem = _repo.GetJobItem(id); + + if (jobItem.Status != SyncJobItemStatus.Failed && jobItem.Status != SyncJobItemStatus.Cancelled) + { + throw new ArgumentException("Operation is not valid for this job item"); + } + + jobItem.Status = SyncJobItemStatus.Queued; + jobItem.Progress = 0; + jobItem.IsMarkedForRemoval = false; + + await _repo.Update(jobItem).ConfigureAwait(false); + + var processor = GetSyncJobProcessor(); + + await processor.UpdateJobStatus(jobItem.JobId).ConfigureAwait(false); + } + + public async Task CancelJobItem(string id) + { + var jobItem = _repo.GetJobItem(id); + + if (jobItem.Status != SyncJobItemStatus.Queued && jobItem.Status != SyncJobItemStatus.Transferring && jobItem.Status != SyncJobItemStatus.Converting) + { + throw new ArgumentException("Operation is not valid for this job item"); + } + + jobItem.Status = SyncJobItemStatus.Cancelled; + jobItem.Progress = 0; + jobItem.IsMarkedForRemoval = true; + + await _repo.Update(jobItem).ConfigureAwait(false); + + var processor = GetSyncJobProcessor(); + + await processor.UpdateJobStatus(jobItem.JobId).ConfigureAwait(false); + } } } diff --git a/MediaBrowser.Server.Implementations/Sync/SyncRepository.cs b/MediaBrowser.Server.Implementations/Sync/SyncRepository.cs index ae91437104..1cd8e8a9d4 100644 --- a/MediaBrowser.Server.Implementations/Sync/SyncRepository.cs +++ b/MediaBrowser.Server.Implementations/Sync/SyncRepository.cs @@ -41,7 +41,7 @@ namespace MediaBrowser.Server.Implementations.Sync public async Task Initialize() { - var dbFile = Path.Combine(_appPaths.DataPath, "sync12.db"); + var dbFile = Path.Combine(_appPaths.DataPath, "sync13.db"); _connection = await SqliteExtensions.ConnectToDb(dbFile, _logger).ConfigureAwait(false); @@ -50,7 +50,7 @@ namespace MediaBrowser.Server.Implementations.Sync "create table if not exists SyncJobs (Id GUID PRIMARY KEY, TargetId TEXT NOT NULL, Name TEXT NOT NULL, Quality TEXT NOT NULL, Status TEXT NOT NULL, Progress FLOAT, UserId TEXT NOT NULL, ItemIds TEXT NOT NULL, Category TEXT, ParentId TEXT, UnwatchedOnly BIT, ItemLimit INT, SyncNewContent BIT, DateCreated DateTime, DateLastModified DateTime, ItemCount int)", "create index if not exists idx_SyncJobs on SyncJobs(Id)", - "create table if not exists SyncJobItems (Id GUID PRIMARY KEY, ItemId TEXT, ItemName TEXT, MediaSourceId TEXT, JobId TEXT, TemporaryPath TEXT, OutputPath TEXT, Status TEXT, TargetId TEXT, DateCreated DateTime, Progress FLOAT, AdditionalFiles TEXT, MediaSource TEXT)", + "create table if not exists SyncJobItems (Id GUID PRIMARY KEY, ItemId TEXT, ItemName TEXT, MediaSourceId TEXT, JobId TEXT, TemporaryPath TEXT, OutputPath TEXT, Status TEXT, TargetId TEXT, DateCreated DateTime, Progress FLOAT, AdditionalFiles TEXT, MediaSource TEXT, IsMarkedForRemoval BIT)", "create index if not exists idx_SyncJobItems on SyncJobs(Id)", //pragmas @@ -95,7 +95,7 @@ namespace MediaBrowser.Server.Implementations.Sync _saveJobCommand.Parameters.Add(_saveJobCommand, "@ItemCount"); _saveJobItemCommand = _connection.CreateCommand(); - _saveJobItemCommand.CommandText = "replace into SyncJobItems (Id, ItemId, ItemName, MediaSourceId, JobId, TemporaryPath, OutputPath, Status, TargetId, DateCreated, Progress, AdditionalFiles, MediaSource) values (@Id, @ItemId, @ItemName, @MediaSourceId, @JobId, @TemporaryPath, @OutputPath, @Status, @TargetId, @DateCreated, @Progress, @AdditionalFiles, @MediaSource)"; + _saveJobItemCommand.CommandText = "replace into SyncJobItems (Id, ItemId, ItemName, MediaSourceId, JobId, TemporaryPath, OutputPath, Status, TargetId, DateCreated, Progress, AdditionalFiles, MediaSource, IsMarkedForRemoval) values (@Id, @ItemId, @ItemName, @MediaSourceId, @JobId, @TemporaryPath, @OutputPath, @Status, @TargetId, @DateCreated, @Progress, @AdditionalFiles, @MediaSource, @IsMarkedForRemoval)"; _saveJobItemCommand.Parameters.Add(_saveJobItemCommand, "@Id"); _saveJobItemCommand.Parameters.Add(_saveJobItemCommand, "@ItemId"); @@ -110,10 +110,11 @@ namespace MediaBrowser.Server.Implementations.Sync _saveJobItemCommand.Parameters.Add(_saveJobItemCommand, "@Progress"); _saveJobItemCommand.Parameters.Add(_saveJobItemCommand, "@AdditionalFiles"); _saveJobItemCommand.Parameters.Add(_saveJobItemCommand, "@MediaSource"); + _saveJobItemCommand.Parameters.Add(_saveJobItemCommand, "@IsMarkedForRemoval"); } private const string BaseJobSelectText = "select Id, TargetId, Name, Quality, Status, Progress, UserId, ItemIds, Category, ParentId, UnwatchedOnly, ItemLimit, SyncNewContent, DateCreated, DateLastModified, ItemCount from SyncJobs"; - private const string BaseJobItemSelectText = "select Id, ItemId, ItemName, MediaSourceId, JobId, TemporaryPath, OutputPath, Status, TargetId, DateCreated, Progress, AdditionalFiles, MediaSource from SyncJobItems"; + private const string BaseJobItemSelectText = "select Id, ItemId, ItemName, MediaSourceId, JobId, TemporaryPath, OutputPath, Status, TargetId, DateCreated, Progress, AdditionalFiles, MediaSource, IsMarkedForRemoval from SyncJobItems"; public SyncJob GetJob(string id) { @@ -572,6 +573,7 @@ namespace MediaBrowser.Server.Implementations.Sync _saveJobItemCommand.GetParameter(index++).Value = jobItem.Progress; _saveJobItemCommand.GetParameter(index++).Value = _json.SerializeToString(jobItem.AdditionalFiles); _saveJobItemCommand.GetParameter(index++).Value = jobItem.MediaSource == null ? null : _json.SerializeToString(jobItem.MediaSource); + _saveJobItemCommand.GetParameter(index++).Value = jobItem.IsMarkedForRemoval; _saveJobItemCommand.Transaction = transaction; @@ -673,6 +675,8 @@ namespace MediaBrowser.Server.Implementations.Sync } } + info.IsMarkedForRemoval = reader.GetBoolean(13); + return info; } diff --git a/MediaBrowser.Server.Startup.Common/ApplicationHost.cs b/MediaBrowser.Server.Startup.Common/ApplicationHost.cs index f481a902d0..7eb68187a3 100644 --- a/MediaBrowser.Server.Startup.Common/ApplicationHost.cs +++ b/MediaBrowser.Server.Startup.Common/ApplicationHost.cs @@ -407,7 +407,7 @@ namespace MediaBrowser.Server.Startup.Common SyncRepository = await GetSyncRepository().ConfigureAwait(false); RegisterSingleInstance(SyncRepository); - UserManager = new UserManager(LogManager.GetLogger("UserManager"), ServerConfigurationManager, UserRepository, XmlSerializer, NetworkManager, () => ImageProcessor, () => DtoService, () => ConnectManager, this, JsonSerializer, FileSystemManager, () => ChannelManager, () => LibraryManager); + UserManager = new UserManager(LogManager.GetLogger("UserManager"), ServerConfigurationManager, UserRepository, XmlSerializer, NetworkManager, () => ImageProcessor, () => DtoService, () => ConnectManager, this, JsonSerializer, FileSystemManager); RegisterSingleInstance(UserManager); LibraryManager = new LibraryManager(Logger, TaskManager, UserManager, ServerConfigurationManager, UserDataManager, () => LibraryMonitor, FileSystemManager, () => ProviderManager); -- cgit v1.2.3 From 1af651bc56025935cebe2762d6f36be41530eba1 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Fri, 23 Jan 2015 23:50:45 -0500 Subject: add Add to collection buttons --- MediaBrowser.Controller/Channels/Channel.cs | 7 ++++++- MediaBrowser.Controller/Entities/BaseItem.cs | 17 ++++------------- MediaBrowser.Controller/Entities/UserViewBuilder.cs | 18 +++++++++++++++++- MediaBrowser.Providers/Manager/ProviderManager.cs | 9 ++++++--- .../Channels/ChannelManager.cs | 6 +++--- .../Library/LibraryManager.cs | 2 +- .../Library/Resolvers/Movies/BoxSetResolver.cs | 12 ------------ .../Localization/JavaScript/javascript.json | 7 +++++++ .../Localization/Server/server.json | 9 +++++---- .../Themes/AppThemeManager.cs | 2 +- MediaBrowser.Server.Startup.Common/ApplicationHost.cs | 2 +- MediaBrowser.WebDashboard/Api/PackageCreator.cs | 3 ++- .../MediaBrowser.WebDashboard.csproj | 3 +++ 13 files changed, 56 insertions(+), 41 deletions(-) (limited to 'MediaBrowser.Controller/Channels') diff --git a/MediaBrowser.Controller/Channels/Channel.cs b/MediaBrowser.Controller/Channels/Channel.cs index 32ad2ff122..87d257f12e 100644 --- a/MediaBrowser.Controller/Channels/Channel.cs +++ b/MediaBrowser.Controller/Channels/Channel.cs @@ -60,7 +60,12 @@ namespace MediaBrowser.Controller.Channels protected override string GetInternalMetadataPath(string basePath) { - return System.IO.Path.Combine(basePath, "channels", Id.ToString("N"), "metadata"); + return GetInternalMetadataPath(basePath, Id); + } + + public static string GetInternalMetadataPath(string basePath, Guid id) + { + return System.IO.Path.Combine(basePath, "channels", id.ToString("N"), "metadata"); } } } diff --git a/MediaBrowser.Controller/Entities/BaseItem.cs b/MediaBrowser.Controller/Entities/BaseItem.cs index 6a30df7fe8..2be4f99e9c 100644 --- a/MediaBrowser.Controller/Entities/BaseItem.cs +++ b/MediaBrowser.Controller/Entities/BaseItem.cs @@ -381,11 +381,6 @@ namespace MediaBrowser.Controller.Entities { var basePath = ConfigurationManager.ApplicationPaths.InternalMetadataPath; - if (ConfigurationManager.Configuration.EnableLibraryMetadataSubFolder) - { - basePath = System.IO.Path.Combine(basePath, "library"); - } - return GetInternalMetadataPath(basePath); } @@ -393,14 +388,10 @@ namespace MediaBrowser.Controller.Entities { var idString = Id.ToString("N"); - return System.IO.Path.Combine(basePath, idString.Substring(0, 2), idString); - } - - public static string GetInternalMetadataPathForId(Guid id) - { - var idString = id.ToString("N"); - - var basePath = ConfigurationManager.ApplicationPaths.InternalMetadataPath; + if (ConfigurationManager.Configuration.EnableLibraryMetadataSubFolder) + { + basePath = System.IO.Path.Combine(basePath, "library"); + } return System.IO.Path.Combine(basePath, idString.Substring(0, 2), idString); } diff --git a/MediaBrowser.Controller/Entities/UserViewBuilder.cs b/MediaBrowser.Controller/Entities/UserViewBuilder.cs index 166d56c514..deb85ed6a0 100644 --- a/MediaBrowser.Controller/Entities/UserViewBuilder.cs +++ b/MediaBrowser.Controller/Entities/UserViewBuilder.cs @@ -117,7 +117,7 @@ namespace MediaBrowser.Controller.Entities return await GetGameView(user, queryParent, query).ConfigureAwait(false); case CollectionType.BoxSets: - return GetResult(GetMediaFolders(user).SelectMany(i => i.GetRecursiveChildren(user)).OfType(), queryParent, query); + return await GetBoxsetView(queryParent, user, query).ConfigureAwait(false); case CollectionType.TvShows: return await GetTvView(queryParent, user, query).ConfigureAwait(false); @@ -526,6 +526,22 @@ namespace MediaBrowser.Controller.Entities return GetResult(items, queryParent, query); } + private async Task> GetBoxsetView(Folder parent, User user, InternalItemsQuery query) + { + return GetResult(GetMediaFolders(user).SelectMany(i => + { + var hasCollectionType = i as ICollectionFolder; + + if (hasCollectionType != null && string.Equals(hasCollectionType.CollectionType, CollectionType.BoxSets, StringComparison.OrdinalIgnoreCase)) + { + return i.GetChildren(user, true); + } + + return i.GetRecursiveChildren(user); + + }).OfType(), parent, query); + } + private async Task> GetTvView(Folder parent, User user, InternalItemsQuery query) { if (query.Recursive) diff --git a/MediaBrowser.Providers/Manager/ProviderManager.cs b/MediaBrowser.Providers/Manager/ProviderManager.cs index d9982e7863..823c34a756 100644 --- a/MediaBrowser.Providers/Manager/ProviderManager.cs +++ b/MediaBrowser.Providers/Manager/ProviderManager.cs @@ -1,5 +1,6 @@ using MediaBrowser.Common.IO; using MediaBrowser.Common.Net; +using MediaBrowser.Controller; using MediaBrowser.Controller.Configuration; using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Entities.Audio; @@ -58,6 +59,7 @@ namespace MediaBrowser.Providers.Manager private IMetadataProvider[] _metadataProviders = { }; private IEnumerable _savers; private IImageSaver[] _imageSavers; + private readonly IServerApplicationPaths _appPaths; private IExternalId[] _externalIds; @@ -69,13 +71,14 @@ namespace MediaBrowser.Providers.Manager /// The directory watchers. /// The log manager. /// The file system. - public ProviderManager(IHttpClient httpClient, IServerConfigurationManager configurationManager, ILibraryMonitor libraryMonitor, ILogManager logManager, IFileSystem fileSystem) + public ProviderManager(IHttpClient httpClient, IServerConfigurationManager configurationManager, ILibraryMonitor libraryMonitor, ILogManager logManager, IFileSystem fileSystem, IServerApplicationPaths appPaths) { _logger = logManager.GetLogger("ProviderManager"); _httpClient = httpClient; ConfigurationManager = configurationManager; _libraryMonitor = libraryMonitor; _fileSystem = fileSystem; + _appPaths = appPaths; } /// @@ -467,7 +470,7 @@ namespace MediaBrowser.Providers.Manager // Give it a dummy path just so that it looks like a file system item var dummy = new T() { - Path = BaseItem.GetInternalMetadataPathForId(Guid.NewGuid()), + Path = Path.Combine(_appPaths.InternalMetadataPath, "dummy"), // Dummy this up to fool the local trailer check Parent = new Folder() @@ -709,7 +712,7 @@ namespace MediaBrowser.Providers.Manager // Give it a dummy path just so that it looks like a file system item var dummy = new TItemType { - Path = BaseItem.GetInternalMetadataPathForId(Guid.NewGuid()), + Path = Path.Combine(_appPaths.InternalMetadataPath, "dummy"), // Dummy this up to fool the local trailer check Parent = new Folder() diff --git a/MediaBrowser.Server.Implementations/Channels/ChannelManager.cs b/MediaBrowser.Server.Implementations/Channels/ChannelManager.cs index a7e248ea46..99ca0b5dac 100644 --- a/MediaBrowser.Server.Implementations/Channels/ChannelManager.cs +++ b/MediaBrowser.Server.Implementations/Channels/ChannelManager.cs @@ -393,7 +393,9 @@ namespace MediaBrowser.Server.Implementations.Channels private async Task GetChannel(IChannel channelInfo, CancellationToken cancellationToken) { - var path = Path.Combine(_config.ApplicationPaths.ItemsByNamePath, "channels", _fileSystem.GetValidFilename(channelInfo.Name)); + var id = GetInternalChannelId(channelInfo.Name); + + var path = Channel.GetInternalMetadataPath(_config.ApplicationPaths.InternalMetadataPath, id); var fileInfo = new DirectoryInfo(path); @@ -414,8 +416,6 @@ namespace MediaBrowser.Server.Implementations.Channels isNew = true; } - var id = GetInternalChannelId(channelInfo.Name); - var item = _libraryManager.GetItemById(id) as Channel; if (item == null) diff --git a/MediaBrowser.Server.Implementations/Library/LibraryManager.cs b/MediaBrowser.Server.Implementations/Library/LibraryManager.cs index b28c987286..1306188dad 100644 --- a/MediaBrowser.Server.Implementations/Library/LibraryManager.cs +++ b/MediaBrowser.Server.Implementations/Library/LibraryManager.cs @@ -1646,7 +1646,7 @@ namespace MediaBrowser.Server.Implementations.Library var id = GetNewItemId("7_namedview_" + name + user.Id.ToString("N") + parentId, typeof(UserView)); - var path = BaseItem.GetInternalMetadataPathForId(id); + var path = Path.Combine(ConfigurationManager.ApplicationPaths.InternalMetadataPath, "views", "specialviews", id.ToString("N")); var item = GetItemById(id) as UserView; diff --git a/MediaBrowser.Server.Implementations/Library/Resolvers/Movies/BoxSetResolver.cs b/MediaBrowser.Server.Implementations/Library/Resolvers/Movies/BoxSetResolver.cs index 67b9d546fd..e3447afc99 100644 --- a/MediaBrowser.Server.Implementations/Library/Resolvers/Movies/BoxSetResolver.cs +++ b/MediaBrowser.Server.Implementations/Library/Resolvers/Movies/BoxSetResolver.cs @@ -4,7 +4,6 @@ using MediaBrowser.Controller.Library; using MediaBrowser.Model.Entities; using System; using System.IO; -using System.Linq; namespace MediaBrowser.Server.Implementations.Library.Resolvers.Movies { @@ -46,17 +45,6 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers.Movies return null; } - private bool IsInvalid(string collectionType) - { - var validCollectionTypes = new[] - { - CollectionType.Movies, - CollectionType.BoxSets - }; - - return !validCollectionTypes.Contains(collectionType ?? string.Empty, StringComparer.OrdinalIgnoreCase); - } - /// /// Sets the initial item values. /// diff --git a/MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json b/MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json index 5d37007e06..914924f42b 100644 --- a/MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json +++ b/MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json @@ -45,8 +45,14 @@ "LabelFailed": "(failed)", "ButtonHelp": "Help", "ButtonSave": "Save", + "HeaderAddToCollection": "Add to Collection", + "NewCollectionNameExample": "Example: Star Wars Collection", + "OptionSearchForInternetMetadata": "Search the internet for artwork and metadata", + "LabelSelectCollection": "Select collection:", "HeaderDevices": "Devices", "ButtonScheduledTasks": "Scheduled tasks", + "MessageItemsAdded": "Items added", + "ButtonAddToCollection": "Add to collection", "HeaderSelectCertificatePath": "Select Certificate Path", "ConfirmMessageScheduledTaskButton": "This operation normally runs automatically as a scheduled task. It can also be run manually here. To configure the scheduled task, see:", "HeaderSupporterBenefit": "A supporter membership provides additional benefits such as access to premium plugins, internet channel content, and more. {0}Learn more{1}.", @@ -223,6 +229,7 @@ "ButtonRefresh": "Refresh", "LabelCurrentPath": "Current path:", "HeaderSelectMediaPath": "Select Media Path", + "HeaderSelectPath": "Select Path", "ButtonNetwork": "Network", "MessageDirectoryPickerInstruction": "Network paths can be entered manually in the event the Network button fails to locate your devices. For example, {0} or {1}.", "HeaderMenu": "Menu", diff --git a/MediaBrowser.Server.Implementations/Localization/Server/server.json b/MediaBrowser.Server.Implementations/Localization/Server/server.json index 3a5e7c77e7..576e0493e2 100644 --- a/MediaBrowser.Server.Implementations/Localization/Server/server.json +++ b/MediaBrowser.Server.Implementations/Localization/Server/server.json @@ -55,6 +55,8 @@ "HeaderAudio": "Audio", "HeaderVideo": "Video", "HeaderPaths": "Paths", + "LabelSyncTempPath": "Temporary file path:", + "LabelSyncTempPathHelp": "", "LabelCustomCertificatePath": "Custom certificate path:", "LabelCustomCertificatePathHelp": "Supply your own ssl certificate. If omitted, the server will create a self-signed certificate.", "TitleNotifications": "Notifications", @@ -516,10 +518,7 @@ "LabelPreferredDisplayLanguageHelp": "Translating Media Browser is an ongoing project and is not yet complete.", "LabelReadHowYouCanContribute": "Read about how you can contribute.", "HeaderNewCollection": "New Collection", - "HeaderAddToCollection": "Add to Collection", "ButtonSubmit": "Submit", - "NewCollectionNameExample": "Example: Star Wars Collection", - "OptionSearchForInternetMetadata": "Search the internet for artwork and metadata", "ButtonCreate": "Create", "LabelCustomCss": "Custom css:", "LabelCustomCssHelp": "Apply your own custom css to the web interface.", @@ -891,6 +890,8 @@ "OptionDefaultSort": "Default", "OptionCommunityMostWatchedSort": "Most Watched", "TabNextUp": "Next Up", + "HeaderBecomeMediaBrowserSupporter": "Become a Media Browser Supporter", + "TextAccessPremiumFeatures": "Enjoy Premium Features", "MessageNoMovieSuggestionsAvailable": "No movie suggestions are currently available. Start watching and rating your movies, and then come back to view your recommendations.", "MessageNoCollectionsAvailable": "Collections allow you to enjoy personalized groupings of Movies, Series, Albums, Books and Games. Click the + button to start creating Collections.", "MessageNoPlaylistsAvailable": "Playlists allow you to create lists of content to play consecutively at a time. To add items to playlists, right click or tap and hold, then select Add to Playlist.", @@ -907,7 +908,6 @@ "LabelChannelDownloadAge": "Delete content after: (days)", "LabelChannelDownloadAgeHelp": "Downloaded content older than this will be deleted. It will remain playable via internet streaming.", "ChannelSettingsFormHelp": "Install channels such as Trailers and Vimeo in the plugin catalog.", - "LabelSelectCollection": "Select collection:", "ButtonOptions": "Options", "ViewTypeMovies": "Movies", "ViewTypeTvShows": "TV", @@ -969,6 +969,7 @@ "LabelGroupChannelsIntoViews": "Display the following channels directly within my views:", "LabelGroupChannelsIntoViewsHelp": "If enabled, these channels will be displayed directly alongside other views. If disabled, they'll be displayed within a separate Channels view.", "LabelDisplayCollectionsView": "Display a collections view to show movie collections", + "LabelDisplayCollectionsViewHelp": "This will create a separate view to display collections that you've created or have access to. To create a collection, right-click or tap-hold any movie and select 'Add to Collection'. ", "LabelKodiMetadataEnableExtraThumbs": "Copy extrafanart into extrathumbs", "LabelKodiMetadataEnableExtraThumbsHelp": "When downloading images they can be saved into both extrafanart and extrathumbs for maximum Kodi skin compatibility.", "TabServices": "Services", diff --git a/MediaBrowser.Server.Implementations/Themes/AppThemeManager.cs b/MediaBrowser.Server.Implementations/Themes/AppThemeManager.cs index 9845f38674..2711c08aac 100644 --- a/MediaBrowser.Server.Implementations/Themes/AppThemeManager.cs +++ b/MediaBrowser.Server.Implementations/Themes/AppThemeManager.cs @@ -33,7 +33,7 @@ namespace MediaBrowser.Server.Implementations.Themes { get { - return Path.Combine(_appPaths.ItemsByNamePath, "appthemes"); + return Path.Combine(_appPaths.ProgramDataPath, "appthemes"); } } diff --git a/MediaBrowser.Server.Startup.Common/ApplicationHost.cs b/MediaBrowser.Server.Startup.Common/ApplicationHost.cs index 4fc6ae6fa1..439d74ab90 100644 --- a/MediaBrowser.Server.Startup.Common/ApplicationHost.cs +++ b/MediaBrowser.Server.Startup.Common/ApplicationHost.cs @@ -419,7 +419,7 @@ namespace MediaBrowser.Server.Startup.Common LibraryMonitor = new LibraryMonitor(LogManager, TaskManager, LibraryManager, ServerConfigurationManager, FileSystemManager); RegisterSingleInstance(LibraryMonitor); - ProviderManager = new ProviderManager(HttpClient, ServerConfigurationManager, LibraryMonitor, LogManager, FileSystemManager); + ProviderManager = new ProviderManager(HttpClient, ServerConfigurationManager, LibraryMonitor, LogManager, FileSystemManager, ApplicationPaths); RegisterSingleInstance(ProviderManager); SeriesOrderManager = new SeriesOrderManager(); diff --git a/MediaBrowser.WebDashboard/Api/PackageCreator.cs b/MediaBrowser.WebDashboard/Api/PackageCreator.cs index 90a5b4ab64..340b02be75 100644 --- a/MediaBrowser.WebDashboard/Api/PackageCreator.cs +++ b/MediaBrowser.WebDashboard/Api/PackageCreator.cs @@ -565,7 +565,8 @@ namespace MediaBrowser.WebDashboard.Api "userimage.css", "livetv.css", "nowplaying.css", - "icons.css" + "icons.css", + "materialize.css" }; var builder = new StringBuilder(); diff --git a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj index 1f720eb26c..7613195ea3 100644 --- a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj +++ b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj @@ -96,6 +96,9 @@ PreserveNewest + + PreserveNewest + PreserveNewest -- cgit v1.2.3 From 67559378009062a26173888ad457d0c9116bfc9a Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sat, 24 Jan 2015 17:33:26 -0500 Subject: sync updates --- .../Channels/ChannelAudioItem.cs | 2 +- .../Channels/ChannelFolderItem.cs | 2 +- .../Channels/ChannelVideoItem.cs | 4 +-- MediaBrowser.Controller/Entities/Audio/Audio.cs | 4 +-- .../Entities/Audio/MusicAlbum.cs | 4 +-- .../Entities/Audio/MusicArtist.cs | 2 +- .../Entities/Audio/MusicGenre.cs | 2 +- MediaBrowser.Controller/Entities/BaseItem.cs | 18 +++++++++++-- MediaBrowser.Controller/Entities/Folder.cs | 2 +- MediaBrowser.Controller/Entities/Game.cs | 4 +-- MediaBrowser.Controller/Entities/GameGenre.cs | 2 +- MediaBrowser.Controller/Entities/GameSystem.cs | 4 +-- MediaBrowser.Controller/Entities/Genre.cs | 2 +- MediaBrowser.Controller/Entities/Movies/Movie.cs | 4 +-- MediaBrowser.Controller/Entities/MusicVideo.cs | 19 ++----------- MediaBrowser.Controller/Entities/Person.cs | 2 +- MediaBrowser.Controller/Entities/Studio.cs | 2 +- MediaBrowser.Controller/Entities/TV/Episode.cs | 4 +-- MediaBrowser.Controller/Entities/TV/Season.cs | 4 +-- MediaBrowser.Controller/Entities/TV/Series.cs | 4 +-- MediaBrowser.Controller/Entities/Trailer.cs | 4 +-- .../Entities/UserViewBuilder.cs | 19 ++++++++++--- MediaBrowser.Controller/Entities/Year.cs | 2 +- .../LiveTv/LiveTvAudioRecording.cs | 2 +- MediaBrowser.Controller/LiveTv/LiveTvChannel.cs | 2 +- MediaBrowser.Controller/LiveTv/LiveTvProgram.cs | 2 +- .../LiveTv/LiveTvVideoRecording.cs | 2 +- MediaBrowser.Providers/Manager/MetadataService.cs | 3 +-- .../Collections/ManualCollectionsFolder.cs | 4 ++- .../FileOrganization/NameUtils.cs | 3 --- .../Library/UserViewManager.cs | 20 +++----------- .../Localization/Server/server.json | 2 ++ .../MediaBrowser.Server.Implementations.csproj | 1 + .../Sync/SyncJobProcessor.cs | 12 ++++++++- .../Sync/SyncRegistrationInfo.cs | 31 ++++++++++++++++++++++ Nuget/MediaBrowser.Common.Internal.nuspec | 4 +-- Nuget/MediaBrowser.Common.nuspec | 2 +- Nuget/MediaBrowser.Model.Signed.nuspec | 2 +- Nuget/MediaBrowser.Server.Core.nuspec | 4 +-- 39 files changed, 126 insertions(+), 86 deletions(-) create mode 100644 MediaBrowser.Server.Implementations/Sync/SyncRegistrationInfo.cs (limited to 'MediaBrowser.Controller/Channels') diff --git a/MediaBrowser.Controller/Channels/ChannelAudioItem.cs b/MediaBrowser.Controller/Channels/ChannelAudioItem.cs index 896d598bb0..d9330f8a30 100644 --- a/MediaBrowser.Controller/Channels/ChannelAudioItem.cs +++ b/MediaBrowser.Controller/Channels/ChannelAudioItem.cs @@ -32,7 +32,7 @@ namespace MediaBrowser.Controller.Channels return config.BlockUnratedItems.Contains(UnratedItem.ChannelContent); } - public override string GetUserDataKey() + protected override string CreateUserDataKey() { return ExternalId; } diff --git a/MediaBrowser.Controller/Channels/ChannelFolderItem.cs b/MediaBrowser.Controller/Channels/ChannelFolderItem.cs index 8482e38dff..dce9840eda 100644 --- a/MediaBrowser.Controller/Channels/ChannelFolderItem.cs +++ b/MediaBrowser.Controller/Channels/ChannelFolderItem.cs @@ -40,7 +40,7 @@ namespace MediaBrowser.Controller.Channels return false; } - public override string GetUserDataKey() + protected override string CreateUserDataKey() { return ExternalId; } diff --git a/MediaBrowser.Controller/Channels/ChannelVideoItem.cs b/MediaBrowser.Controller/Channels/ChannelVideoItem.cs index f0eafcbdff..e3fad56e90 100644 --- a/MediaBrowser.Controller/Channels/ChannelVideoItem.cs +++ b/MediaBrowser.Controller/Channels/ChannelVideoItem.cs @@ -28,8 +28,8 @@ namespace MediaBrowser.Controller.Channels public string OriginalImageUrl { get; set; } public List ChannelMediaSources { get; set; } - - public override string GetUserDataKey() + + protected override string CreateUserDataKey() { if (ContentType == ChannelMediaContentType.MovieExtra) { diff --git a/MediaBrowser.Controller/Entities/Audio/Audio.cs b/MediaBrowser.Controller/Entities/Audio/Audio.cs index c5ed09016c..f110f85d2e 100644 --- a/MediaBrowser.Controller/Entities/Audio/Audio.cs +++ b/MediaBrowser.Controller/Entities/Audio/Audio.cs @@ -169,7 +169,7 @@ namespace MediaBrowser.Controller.Entities.Audio /// Gets the user data key. /// /// System.String. - public override string GetUserDataKey() + protected override string CreateUserDataKey() { var parent = FindParent(); @@ -186,7 +186,7 @@ namespace MediaBrowser.Controller.Entities.Audio } } - return base.GetUserDataKey(); + return base.CreateUserDataKey(); } protected override bool GetBlockUnratedValue(UserPolicy config) diff --git a/MediaBrowser.Controller/Entities/Audio/MusicAlbum.cs b/MediaBrowser.Controller/Entities/Audio/MusicAlbum.cs index 90edfcce70..7974657d9d 100644 --- a/MediaBrowser.Controller/Entities/Audio/MusicAlbum.cs +++ b/MediaBrowser.Controller/Entities/Audio/MusicAlbum.cs @@ -136,7 +136,7 @@ namespace MediaBrowser.Controller.Entities.Audio /// Gets the user data key. /// /// System.String. - public override string GetUserDataKey() + protected override string CreateUserDataKey() { var id = this.GetProviderId(MetadataProviders.MusicBrainzReleaseGroup); @@ -152,7 +152,7 @@ namespace MediaBrowser.Controller.Entities.Audio return "MusicAlbum-Musicbrainz-" + id; } - return base.GetUserDataKey(); + return base.CreateUserDataKey(); } protected override bool GetBlockUnratedValue(UserPolicy config) diff --git a/MediaBrowser.Controller/Entities/Audio/MusicArtist.cs b/MediaBrowser.Controller/Entities/Audio/MusicArtist.cs index a60258d1a7..45476d6a6d 100644 --- a/MediaBrowser.Controller/Entities/Audio/MusicArtist.cs +++ b/MediaBrowser.Controller/Entities/Audio/MusicArtist.cs @@ -68,7 +68,7 @@ namespace MediaBrowser.Controller.Entities.Audio /// Gets the user data key. /// /// System.String. - public override string GetUserDataKey() + protected override string CreateUserDataKey() { return GetUserDataKey(this); } diff --git a/MediaBrowser.Controller/Entities/Audio/MusicGenre.cs b/MediaBrowser.Controller/Entities/Audio/MusicGenre.cs index 928eb64630..ad2d39c794 100644 --- a/MediaBrowser.Controller/Entities/Audio/MusicGenre.cs +++ b/MediaBrowser.Controller/Entities/Audio/MusicGenre.cs @@ -14,7 +14,7 @@ namespace MediaBrowser.Controller.Entities.Audio /// Gets the user data key. /// /// System.String. - public override string GetUserDataKey() + protected override string CreateUserDataKey() { return "MusicGenre-" + Name; } diff --git a/MediaBrowser.Controller/Entities/BaseItem.cs b/MediaBrowser.Controller/Entities/BaseItem.cs index 2be4f99e9c..234a33d78f 100644 --- a/MediaBrowser.Controller/Entities/BaseItem.cs +++ b/MediaBrowser.Controller/Entities/BaseItem.cs @@ -359,7 +359,7 @@ namespace MediaBrowser.Controller.Entities { get { - if (!string.IsNullOrEmpty(ForcedSortName)) + if (!string.IsNullOrWhiteSpace(ForcedSortName)) { return ForcedSortName; } @@ -887,11 +887,22 @@ namespace MediaBrowser.Controller.Entities get { return null; } } + private string _userDataKey; /// /// Gets the user data key. /// /// System.String. - public virtual string GetUserDataKey() + public string GetUserDataKey() + { + if (!string.IsNullOrWhiteSpace(_userDataKey)) + { + return _userDataKey; + } + + return _userDataKey ?? (_userDataKey = CreateUserDataKey()); + } + + protected virtual string CreateUserDataKey() { return Id.ToString(); } @@ -1701,6 +1712,9 @@ namespace MediaBrowser.Controller.Entities /// public virtual bool BeforeMetadataRefresh() { + _userDataKey = null; + _sortName = null; + var hasChanges = false; if (string.IsNullOrEmpty(Name) && !string.IsNullOrEmpty(Path)) diff --git a/MediaBrowser.Controller/Entities/Folder.cs b/MediaBrowser.Controller/Entities/Folder.cs index ff6e8e85b1..dd3d145a03 100644 --- a/MediaBrowser.Controller/Entities/Folder.cs +++ b/MediaBrowser.Controller/Entities/Folder.cs @@ -807,7 +807,7 @@ namespace MediaBrowser.Controller.Entities protected QueryResult SortAndFilter(IEnumerable items, InternalItemsQuery query) { - return UserViewBuilder.SortAndFilter(items, this, null, query, LibraryManager, UserDataManager); + return UserViewBuilder.FilterAndSort(items, this, null, query, LibraryManager, UserDataManager); } /// diff --git a/MediaBrowser.Controller/Entities/Game.cs b/MediaBrowser.Controller/Entities/Game.cs index bf32d3e634..71642ea902 100644 --- a/MediaBrowser.Controller/Entities/Game.cs +++ b/MediaBrowser.Controller/Entities/Game.cs @@ -88,7 +88,7 @@ namespace MediaBrowser.Controller.Entities /// public List MultiPartGameFiles { get; set; } - public override string GetUserDataKey() + protected override string CreateUserDataKey() { var id = this.GetProviderId(MetadataProviders.Gamesdb); @@ -96,7 +96,7 @@ namespace MediaBrowser.Controller.Entities { return "Game-Gamesdb-" + id; } - return base.GetUserDataKey(); + return base.CreateUserDataKey(); } public override IEnumerable GetDeletePaths() diff --git a/MediaBrowser.Controller/Entities/GameGenre.cs b/MediaBrowser.Controller/Entities/GameGenre.cs index 8254689540..16ca6e70a0 100644 --- a/MediaBrowser.Controller/Entities/GameGenre.cs +++ b/MediaBrowser.Controller/Entities/GameGenre.cs @@ -10,7 +10,7 @@ namespace MediaBrowser.Controller.Entities /// Gets the user data key. /// /// System.String. - public override string GetUserDataKey() + protected override string CreateUserDataKey() { return "GameGenre-" + Name; } diff --git a/MediaBrowser.Controller/Entities/GameSystem.cs b/MediaBrowser.Controller/Entities/GameSystem.cs index 7584989779..cf69167638 100644 --- a/MediaBrowser.Controller/Entities/GameSystem.cs +++ b/MediaBrowser.Controller/Entities/GameSystem.cs @@ -35,13 +35,13 @@ namespace MediaBrowser.Controller.Entities /// Gets the user data key. /// /// System.String. - public override string GetUserDataKey() + protected override string CreateUserDataKey() { if (!string.IsNullOrEmpty(GameSystemName)) { return "GameSystem-" + GameSystemName; } - return base.GetUserDataKey(); + return base.CreateUserDataKey(); } protected override bool GetBlockUnratedValue(UserPolicy config) diff --git a/MediaBrowser.Controller/Entities/Genre.cs b/MediaBrowser.Controller/Entities/Genre.cs index 05442f2b7f..da5569afc9 100644 --- a/MediaBrowser.Controller/Entities/Genre.cs +++ b/MediaBrowser.Controller/Entities/Genre.cs @@ -14,7 +14,7 @@ namespace MediaBrowser.Controller.Entities /// Gets the user data key. /// /// System.String. - public override string GetUserDataKey() + protected override string CreateUserDataKey() { return "Genre-" + Name; } diff --git a/MediaBrowser.Controller/Entities/Movies/Movie.cs b/MediaBrowser.Controller/Entities/Movies/Movie.cs index 2fa5fc6e1e..cfe008bd7c 100644 --- a/MediaBrowser.Controller/Entities/Movies/Movie.cs +++ b/MediaBrowser.Controller/Entities/Movies/Movie.cs @@ -100,9 +100,9 @@ namespace MediaBrowser.Controller.Entities.Movies /// Gets the user data key. /// /// System.String. - public override string GetUserDataKey() + protected override string CreateUserDataKey() { - return this.GetProviderId(MetadataProviders.Tmdb) ?? this.GetProviderId(MetadataProviders.Imdb) ?? base.GetUserDataKey(); + return this.GetProviderId(MetadataProviders.Tmdb) ?? this.GetProviderId(MetadataProviders.Imdb) ?? base.CreateUserDataKey(); } protected override async Task RefreshedOwnedItems(MetadataRefreshOptions options, List fileSystemChildren, CancellationToken cancellationToken) diff --git a/MediaBrowser.Controller/Entities/MusicVideo.cs b/MediaBrowser.Controller/Entities/MusicVideo.cs index 4ca8cf1c5a..771c62fd6d 100644 --- a/MediaBrowser.Controller/Entities/MusicVideo.cs +++ b/MediaBrowser.Controller/Entities/MusicVideo.cs @@ -47,21 +47,6 @@ namespace MediaBrowser.Controller.Entities } } - /// - /// TODO: Remove - /// - public string Artist - { - get { return Artists.FirstOrDefault(); } - set - { - if (!string.IsNullOrEmpty(value) && !Artists.Contains(value, StringComparer.OrdinalIgnoreCase)) - { - Artists.Add(value); - } - } - } - /// /// Determines whether the specified name has artist. /// @@ -76,9 +61,9 @@ namespace MediaBrowser.Controller.Entities /// Gets the user data key. /// /// System.String. - public override string GetUserDataKey() + protected override string CreateUserDataKey() { - return this.GetProviderId(MetadataProviders.Tmdb) ?? this.GetProviderId(MetadataProviders.Imdb) ?? base.GetUserDataKey(); + return this.GetProviderId(MetadataProviders.Tmdb) ?? this.GetProviderId(MetadataProviders.Imdb) ?? base.CreateUserDataKey(); } protected override bool GetBlockUnratedValue(UserPolicy config) diff --git a/MediaBrowser.Controller/Entities/Person.cs b/MediaBrowser.Controller/Entities/Person.cs index fe8d618362..6d256e81c7 100644 --- a/MediaBrowser.Controller/Entities/Person.cs +++ b/MediaBrowser.Controller/Entities/Person.cs @@ -20,7 +20,7 @@ namespace MediaBrowser.Controller.Entities /// Gets the user data key. /// /// System.String. - public override string GetUserDataKey() + protected override string CreateUserDataKey() { return "Person-" + Name; } diff --git a/MediaBrowser.Controller/Entities/Studio.cs b/MediaBrowser.Controller/Entities/Studio.cs index 0d934ad0a5..58d46facc9 100644 --- a/MediaBrowser.Controller/Entities/Studio.cs +++ b/MediaBrowser.Controller/Entities/Studio.cs @@ -20,7 +20,7 @@ namespace MediaBrowser.Controller.Entities /// Gets the user data key. /// /// System.String. - public override string GetUserDataKey() + protected override string CreateUserDataKey() { return "Studio-" + Name; } diff --git a/MediaBrowser.Controller/Entities/TV/Episode.cs b/MediaBrowser.Controller/Entities/TV/Episode.cs index 6b67cebc88..a2731f6dfb 100644 --- a/MediaBrowser.Controller/Entities/TV/Episode.cs +++ b/MediaBrowser.Controller/Entities/TV/Episode.cs @@ -117,7 +117,7 @@ namespace MediaBrowser.Controller.Entities.TV /// Gets the user data key. /// /// System.String. - public override string GetUserDataKey() + protected override string CreateUserDataKey() { var series = Series; @@ -126,7 +126,7 @@ namespace MediaBrowser.Controller.Entities.TV return series.GetUserDataKey() + ParentIndexNumber.Value.ToString("000") + IndexNumber.Value.ToString("000"); } - return base.GetUserDataKey(); + return base.CreateUserDataKey(); } /// diff --git a/MediaBrowser.Controller/Entities/TV/Season.cs b/MediaBrowser.Controller/Entities/TV/Season.cs index 54db12b6f8..61d0aec607 100644 --- a/MediaBrowser.Controller/Entities/TV/Season.cs +++ b/MediaBrowser.Controller/Entities/TV/Season.cs @@ -92,7 +92,7 @@ namespace MediaBrowser.Controller.Entities.TV /// Gets the user data key. /// /// System.String. - public override string GetUserDataKey() + protected override string CreateUserDataKey() { if (Series != null) { @@ -100,7 +100,7 @@ namespace MediaBrowser.Controller.Entities.TV return Series.GetUserDataKey() + seasonNo.ToString("000"); } - return base.GetUserDataKey(); + return base.CreateUserDataKey(); } /// diff --git a/MediaBrowser.Controller/Entities/TV/Series.cs b/MediaBrowser.Controller/Entities/TV/Series.cs index 55cfffeb26..0ec9121f37 100644 --- a/MediaBrowser.Controller/Entities/TV/Series.cs +++ b/MediaBrowser.Controller/Entities/TV/Series.cs @@ -117,9 +117,9 @@ namespace MediaBrowser.Controller.Entities.TV /// Gets the user data key. /// /// System.String. - public override string GetUserDataKey() + protected override string CreateUserDataKey() { - return this.GetProviderId(MetadataProviders.Tvdb) ?? this.GetProviderId(MetadataProviders.Tvcom) ?? base.GetUserDataKey(); + return this.GetProviderId(MetadataProviders.Tvdb) ?? this.GetProviderId(MetadataProviders.Tvcom) ?? base.CreateUserDataKey(); } /// diff --git a/MediaBrowser.Controller/Entities/Trailer.cs b/MediaBrowser.Controller/Entities/Trailer.cs index 7a1eef8dbb..72e3640f27 100644 --- a/MediaBrowser.Controller/Entities/Trailer.cs +++ b/MediaBrowser.Controller/Entities/Trailer.cs @@ -79,7 +79,7 @@ namespace MediaBrowser.Controller.Entities } } - public override string GetUserDataKey() + protected override string CreateUserDataKey() { var key = this.GetProviderId(MetadataProviders.Imdb) ?? this.GetProviderId(MetadataProviders.Tmdb); @@ -96,7 +96,7 @@ namespace MediaBrowser.Controller.Entities return key; } - return base.GetUserDataKey(); + return base.CreateUserDataKey(); } protected override bool GetBlockUnratedValue(UserPolicy config) diff --git a/MediaBrowser.Controller/Entities/UserViewBuilder.cs b/MediaBrowser.Controller/Entities/UserViewBuilder.cs index deb85ed6a0..ac8be37d44 100644 --- a/MediaBrowser.Controller/Entities/UserViewBuilder.cs +++ b/MediaBrowser.Controller/Entities/UserViewBuilder.cs @@ -18,6 +18,7 @@ using System.IO; using System.Linq; using System.Threading; using System.Threading.Tasks; +using MoreLinq; namespace MediaBrowser.Controller.Entities { @@ -412,7 +413,19 @@ namespace MediaBrowser.Controller.Entities { if (query.Recursive) { - return GetResult(GetRecursiveChildren(parent, user, new[] { CollectionType.Movies, CollectionType.BoxSets, string.Empty }).Where(i => i is Movie || i is BoxSet), parent, query); + var recursiveItems = GetRecursiveChildren(parent, user, + new[] {CollectionType.Movies, CollectionType.BoxSets, string.Empty}) + .Where(i => i is Movie || i is BoxSet); + + //var collections = _collectionManager.CollapseItemsWithinBoxSets(recursiveItems, user).ToList(); + + //if (collections.Count > 0) + //{ + // recursiveItems.AddRange(_collectionManager.CollapseItemsWithinBoxSets(recursiveItems, user)); + // recursiveItems = recursiveItems.DistinctBy(i => i.Id).ToList(); + //} + + return GetResult(recursiveItems, parent, query); } var list = new List(); @@ -744,10 +757,10 @@ namespace MediaBrowser.Controller.Entities InternalItemsQuery query) where T : BaseItem { - return SortAndFilter(items, queryParent, totalRecordLimit, query, _libraryManager, _userDataManager); + return FilterAndSort(items, queryParent, totalRecordLimit, query, _libraryManager, _userDataManager); } - public static QueryResult SortAndFilter(IEnumerable items, + public static QueryResult FilterAndSort(IEnumerable items, BaseItem queryParent, int? totalRecordLimit, InternalItemsQuery query, diff --git a/MediaBrowser.Controller/Entities/Year.cs b/MediaBrowser.Controller/Entities/Year.cs index 8deb930e8b..11b0ce3d28 100644 --- a/MediaBrowser.Controller/Entities/Year.cs +++ b/MediaBrowser.Controller/Entities/Year.cs @@ -13,7 +13,7 @@ namespace MediaBrowser.Controller.Entities /// Gets the user data key. /// /// System.String. - public override string GetUserDataKey() + protected override string CreateUserDataKey() { return "Year-" + Name; } diff --git a/MediaBrowser.Controller/LiveTv/LiveTvAudioRecording.cs b/MediaBrowser.Controller/LiveTv/LiveTvAudioRecording.cs index f29204689f..5cfdb5dbf5 100644 --- a/MediaBrowser.Controller/LiveTv/LiveTvAudioRecording.cs +++ b/MediaBrowser.Controller/LiveTv/LiveTvAudioRecording.cs @@ -12,7 +12,7 @@ namespace MediaBrowser.Controller.LiveTv /// Gets the user data key. /// /// System.String. - public override string GetUserDataKey() + protected override string CreateUserDataKey() { var name = GetClientTypeName(); diff --git a/MediaBrowser.Controller/LiveTv/LiveTvChannel.cs b/MediaBrowser.Controller/LiveTv/LiveTvChannel.cs index b4b9fa77b8..72b4970262 100644 --- a/MediaBrowser.Controller/LiveTv/LiveTvChannel.cs +++ b/MediaBrowser.Controller/LiveTv/LiveTvChannel.cs @@ -16,7 +16,7 @@ namespace MediaBrowser.Controller.LiveTv /// Gets the user data key. /// /// System.String. - public override string GetUserDataKey() + protected override string CreateUserDataKey() { return GetClientTypeName() + "-" + Name; } diff --git a/MediaBrowser.Controller/LiveTv/LiveTvProgram.cs b/MediaBrowser.Controller/LiveTv/LiveTvProgram.cs index 74cf950d42..6308a71dc3 100644 --- a/MediaBrowser.Controller/LiveTv/LiveTvProgram.cs +++ b/MediaBrowser.Controller/LiveTv/LiveTvProgram.cs @@ -16,7 +16,7 @@ namespace MediaBrowser.Controller.LiveTv /// Gets the user data key. /// /// System.String. - public override string GetUserDataKey() + protected override string CreateUserDataKey() { return GetClientTypeName() + "-" + Name; } diff --git a/MediaBrowser.Controller/LiveTv/LiveTvVideoRecording.cs b/MediaBrowser.Controller/LiveTv/LiveTvVideoRecording.cs index 91edc06c11..098400b502 100644 --- a/MediaBrowser.Controller/LiveTv/LiveTvVideoRecording.cs +++ b/MediaBrowser.Controller/LiveTv/LiveTvVideoRecording.cs @@ -12,7 +12,7 @@ namespace MediaBrowser.Controller.LiveTv /// Gets the user data key. /// /// System.String. - public override string GetUserDataKey() + protected override string CreateUserDataKey() { var name = GetClientTypeName(); diff --git a/MediaBrowser.Providers/Manager/MetadataService.cs b/MediaBrowser.Providers/Manager/MetadataService.cs index f55eddfcf1..fc329d64c5 100644 --- a/MediaBrowser.Providers/Manager/MetadataService.cs +++ b/MediaBrowser.Providers/Manager/MetadataService.cs @@ -437,8 +437,7 @@ namespace MediaBrowser.Providers.Manager localProviders.Count == 0 && refreshResult.UpdateType > ItemUpdateType.None) { - // TODO: If the new metadata from above has some blank data, this - // can cause old data to get filled into those empty fields + // TODO: If the new metadata from above has some blank data, this can cause old data to get filled into those empty fields MergeData(item, temp, new List(), false, true); } diff --git a/MediaBrowser.Server.Implementations/Collections/ManualCollectionsFolder.cs b/MediaBrowser.Server.Implementations/Collections/ManualCollectionsFolder.cs index fa4de728b9..bbe37cb506 100644 --- a/MediaBrowser.Server.Implementations/Collections/ManualCollectionsFolder.cs +++ b/MediaBrowser.Server.Implementations/Collections/ManualCollectionsFolder.cs @@ -1,4 +1,5 @@ using MediaBrowser.Controller.Entities; +using MediaBrowser.Controller.Entities.Movies; using System.Linq; namespace MediaBrowser.Server.Implementations.Collections @@ -14,7 +15,8 @@ namespace MediaBrowser.Server.Implementations.Collections public override bool IsVisible(User user) { return base.IsVisible(user) && GetChildren(user, false) - .Any(); + .OfType() + .Any(i => i.IsVisible(user)); } public override bool IsHidden diff --git a/MediaBrowser.Server.Implementations/FileOrganization/NameUtils.cs b/MediaBrowser.Server.Implementations/FileOrganization/NameUtils.cs index 795be1e2f3..624133d4fb 100644 --- a/MediaBrowser.Server.Implementations/FileOrganization/NameUtils.cs +++ b/MediaBrowser.Server.Implementations/FileOrganization/NameUtils.cs @@ -54,9 +54,6 @@ namespace MediaBrowser.Server.Implementations.FileOrganization private static string GetComparableName(string name) { - // TODO: Improve this - should ignore spaces, periods, underscores, most likely all symbols and - // possibly remove sorting words like "the", "and", etc. - name = RemoveDiacritics(name); name = " " + name + " "; diff --git a/MediaBrowser.Server.Implementations/Library/UserViewManager.cs b/MediaBrowser.Server.Implementations/Library/UserViewManager.cs index bd0f44adc2..d8c5f85c02 100644 --- a/MediaBrowser.Server.Implementations/Library/UserViewManager.cs +++ b/MediaBrowser.Server.Implementations/Library/UserViewManager.cs @@ -88,24 +88,10 @@ namespace MediaBrowser.Server.Implementations.Library list.Add(await GetUserView(CollectionType.Games, string.Empty, cancellationToken).ConfigureAwait(false)); } - if (user.Configuration.DisplayCollectionsView) + if (foldersWithViewTypes.Any(i => string.Equals(i.CollectionType, CollectionType.BoxSets, StringComparison.OrdinalIgnoreCase))) { - bool showCollectionView; - if (_config.Configuration.EnableLegacyCollections) - { - showCollectionView = folders - .Except(standaloneFolders) - .SelectMany(i => i.GetRecursiveChildren(user, false)).OfType().Any(); - } - else - { - showCollectionView = _collectionManager.GetCollections(user).Any(); - } - - if (showCollectionView) - { - list.Add(await GetUserView(CollectionType.BoxSets, string.Empty, cancellationToken).ConfigureAwait(false)); - } + //list.Add(_collectionManager.GetCollectionsFolder(user.Id.ToString("N"))); + list.Add(await GetUserView(CollectionType.BoxSets, string.Empty, cancellationToken).ConfigureAwait(false)); } if (foldersWithViewTypes.Any(i => string.Equals(i.CollectionType, CollectionType.Playlists, StringComparison.OrdinalIgnoreCase))) diff --git a/MediaBrowser.Server.Implementations/Localization/Server/server.json b/MediaBrowser.Server.Implementations/Localization/Server/server.json index 34a0b327d3..15bc624123 100644 --- a/MediaBrowser.Server.Implementations/Localization/Server/server.json +++ b/MediaBrowser.Server.Implementations/Localization/Server/server.json @@ -55,6 +55,8 @@ "HeaderAudio": "Audio", "HeaderVideo": "Video", "HeaderPaths": "Paths", + "HeaderSyncRequiresSupporterMembership": "Sync Requires a Supporter Membership", + "HeaderEnjoyDayTrial": "Enjoy a 14 Day Free Trial", "LabelSyncTempPath": "Temporary file path:", "LabelSyncTempPathHelp": "Specify a custom sync working folder. Converted media created during the sync process will be stored here.", "LabelCustomCertificatePath": "Custom certificate path:", diff --git a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj index e95bd6503b..30384d1ffc 100644 --- a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj +++ b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj @@ -306,6 +306,7 @@ + diff --git a/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs b/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs index 716584084c..b926ee3388 100644 --- a/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs +++ b/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs @@ -90,7 +90,7 @@ namespace MediaBrowser.Server.Implementations.Sync continue; } - var index = jobItems.Count == 0 ? + var index = jobItems.Count == 0 ? 0 : (jobItems.Select(i => i.JobItemIndex).Max() + 1); @@ -348,10 +348,20 @@ namespace MediaBrowser.Server.Implementations.Sync private void CleanDeadSyncFiles() { // TODO + // Clean files in sync temp folder that are not linked to any sync jobs } public async Task SyncJobItems(SyncJobItem[] items, bool enableConversion, IProgress progress, CancellationToken cancellationToken) { + if (items.Length > 0) + { + if (!SyncRegistrationInfo.Instance.IsRegistered) + { + _logger.Debug("Cancelling sync job processing. Please obtain a supporter membership."); + return; + } + } + var numComplete = 0; foreach (var item in items) diff --git a/MediaBrowser.Server.Implementations/Sync/SyncRegistrationInfo.cs b/MediaBrowser.Server.Implementations/Sync/SyncRegistrationInfo.cs new file mode 100644 index 0000000000..40b84b1c21 --- /dev/null +++ b/MediaBrowser.Server.Implementations/Sync/SyncRegistrationInfo.cs @@ -0,0 +1,31 @@ +using MediaBrowser.Common.Security; +using System.Threading.Tasks; + +namespace MediaBrowser.Server.Implementations.Sync +{ + public class SyncRegistrationInfo : IRequiresRegistration + { + private readonly ISecurityManager _securityManager; + + public static SyncRegistrationInfo Instance; + + public SyncRegistrationInfo(ISecurityManager securityManager) + { + _securityManager = securityManager; + Instance = this; + } + + private bool _registered; + public bool IsRegistered + { + get { return _registered; } + } + + public async Task LoadRegistrationInfoAsync() + { + var info = await _securityManager.GetRegistrationStatus("sync").ConfigureAwait(false); + + _registered = info.IsValid; + } + } +} diff --git a/Nuget/MediaBrowser.Common.Internal.nuspec b/Nuget/MediaBrowser.Common.Internal.nuspec index 6de8801790..1a7dc626a3 100644 --- a/Nuget/MediaBrowser.Common.Internal.nuspec +++ b/Nuget/MediaBrowser.Common.Internal.nuspec @@ -2,7 +2,7 @@ MediaBrowser.Common.Internal - 3.0.545 + 3.0.546 MediaBrowser.Common.Internal Luke ebr,Luke,scottisafool @@ -12,7 +12,7 @@ Contains common components shared by Media Browser Theater and Media Browser Server. Not intended for plugin developer consumption. Copyright © Media Browser 2013 - + diff --git a/Nuget/MediaBrowser.Common.nuspec b/Nuget/MediaBrowser.Common.nuspec index 94445107e6..3eb6621b31 100644 --- a/Nuget/MediaBrowser.Common.nuspec +++ b/Nuget/MediaBrowser.Common.nuspec @@ -2,7 +2,7 @@ MediaBrowser.Common - 3.0.545 + 3.0.546 MediaBrowser.Common Media Browser Team ebr,Luke,scottisafool diff --git a/Nuget/MediaBrowser.Model.Signed.nuspec b/Nuget/MediaBrowser.Model.Signed.nuspec index c441d3b636..f73b375a2f 100644 --- a/Nuget/MediaBrowser.Model.Signed.nuspec +++ b/Nuget/MediaBrowser.Model.Signed.nuspec @@ -2,7 +2,7 @@ MediaBrowser.Model.Signed - 3.0.545 + 3.0.546 MediaBrowser.Model - Signed Edition Media Browser Team ebr,Luke,scottisafool diff --git a/Nuget/MediaBrowser.Server.Core.nuspec b/Nuget/MediaBrowser.Server.Core.nuspec index 5409d970d5..451a376540 100644 --- a/Nuget/MediaBrowser.Server.Core.nuspec +++ b/Nuget/MediaBrowser.Server.Core.nuspec @@ -2,7 +2,7 @@ MediaBrowser.Server.Core - 3.0.545 + 3.0.546 Media Browser.Server.Core Media Browser Team ebr,Luke,scottisafool @@ -12,7 +12,7 @@ Contains core components required to build plugins for Media Browser Server. Copyright © Media Browser 2013 - + -- cgit v1.2.3 From b6d59c7688fc39d4689bc9070a7a99271d5b41ee Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Fri, 6 Feb 2015 00:39:07 -0500 Subject: fixes #1001 - Support downloading --- MediaBrowser.Api/Library/LibraryService.cs | 56 +++++++++++++++------- MediaBrowser.Api/Playback/BaseStreamingService.cs | 12 ++--- .../Playback/Progressive/VideoService.cs | 1 + MediaBrowser.Controller/Channels/Channel.cs | 5 ++ .../Channels/ChannelAudioItem.cs | 7 ++- .../Channels/ChannelFolderItem.cs | 12 +++-- .../Channels/ChannelVideoItem.cs | 7 ++- .../Entities/AggregateFolder.cs | 5 ++ MediaBrowser.Controller/Entities/Audio/Audio.cs | 7 +++ .../Entities/Audio/MusicArtist.cs | 12 +++-- .../Entities/Audio/MusicGenre.cs | 5 ++ MediaBrowser.Controller/Entities/BaseItem.cs | 32 +++++++++++++ .../Entities/BasePluginFolder.cs | 5 ++ MediaBrowser.Controller/Entities/Book.cs | 8 ++++ .../Entities/CollectionFolder.cs | 5 ++ MediaBrowser.Controller/Entities/Game.cs | 9 +++- MediaBrowser.Controller/Entities/GameGenre.cs | 5 ++ MediaBrowser.Controller/Entities/Genre.cs | 5 ++ MediaBrowser.Controller/Entities/IItemByName.cs | 4 ++ MediaBrowser.Controller/Entities/Movies/BoxSet.cs | 5 ++ MediaBrowser.Controller/Entities/Person.cs | 5 ++ MediaBrowser.Controller/Entities/Studio.cs | 5 ++ MediaBrowser.Controller/Entities/UserView.cs | 5 ++ MediaBrowser.Controller/Entities/Video.cs | 13 +++++ MediaBrowser.Controller/Entities/Year.cs | 5 ++ MediaBrowser.Controller/LiveTv/ILiveTvRecording.cs | 4 ++ .../LiveTv/LiveTvAudioRecording.cs | 6 +++ MediaBrowser.Controller/LiveTv/LiveTvChannel.cs | 9 +++- MediaBrowser.Controller/LiveTv/LiveTvProgram.cs | 13 +++-- .../LiveTv/LiveTvVideoRecording.cs | 5 ++ MediaBrowser.Controller/Playlists/Playlist.cs | 7 ++- MediaBrowser.MediaEncoding/Encoder/BaseEncoder.cs | 8 ++-- MediaBrowser.Model/Dto/BaseItemDto.cs | 2 + MediaBrowser.Model/LiveTv/RecordingInfoDto.cs | 6 +++ MediaBrowser.Model/Querying/ItemFields.cs | 13 ++++- MediaBrowser.Model/Users/UserPolicy.cs | 5 +- .../Dto/DtoService.cs | 14 ++++++ .../HttpServer/Security/AuthService.cs | 26 +++++++++- .../LiveTv/LiveTvDtoService.cs | 4 ++ .../Localization/JavaScript/javascript.json | 2 + .../Localization/Server/server.json | 13 ++--- .../Sync/SyncJobProcessor.cs | 4 +- MediaBrowser.WebDashboard/Api/PackageCreator.cs | 1 - .../MediaBrowser.WebDashboard.csproj | 6 --- 44 files changed, 322 insertions(+), 66 deletions(-) (limited to 'MediaBrowser.Controller/Channels') diff --git a/MediaBrowser.Api/Library/LibraryService.cs b/MediaBrowser.Api/Library/LibraryService.cs index f147234fe0..a97e2b52ee 100644 --- a/MediaBrowser.Api/Library/LibraryService.cs +++ b/MediaBrowser.Api/Library/LibraryService.cs @@ -226,6 +226,18 @@ namespace MediaBrowser.Api.Library public string TvdbId { get; set; } } + [Route("/Items/{Id}/Download", "GET", Summary = "Downloads item media")] + [Authenticated(Roles = "download")] + public class GetDownload + { + /// + /// Gets or sets the id. + /// + /// The id. + [ApiMember(Name = "Id", Description = "Item Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "GET")] + public string Id { get; set; } + } + /// /// Class LibraryService /// @@ -273,7 +285,7 @@ namespace MediaBrowser.Api.Library } var dtoOptions = GetDtoOptions(request); - + var result = new ItemsResult { TotalRecordCount = items.Count, @@ -289,6 +301,28 @@ namespace MediaBrowser.Api.Library Task.Run(() => _libraryManager.ValidateMediaLibrary(new Progress(), CancellationToken.None)); } + public object Get(GetDownload request) + { + var item = _libraryManager.GetItemById(request.Id); + + if (!item.CanDelete()) + { + throw new ArgumentException("Item does not support downloading"); + } + + var headers = new Dictionary(); + + // Quotes are valid in linux. They'll possibly cause issues here + var filename = Path.GetFileName(item.Path).Replace("\"", string.Empty); + headers["Content-Disposition"] = string.Format("inline; filename=\"{0}\"", filename); + + return ResultFactory.GetStaticFileResult(Request, new StaticFileResultOptions + { + Path = item.Path, + ResponseHeaders = headers + }); + } + public object Get(GetFile request) { var item = _libraryManager.GetItemById(request.Id); @@ -347,7 +381,7 @@ namespace MediaBrowser.Api.Library var dtoOptions = GetDtoOptions(request); BaseItem parent = item.Parent; - + while (parent != null) { if (user != null) @@ -458,23 +492,9 @@ namespace MediaBrowser.Api.Library var auth = _authContext.GetAuthorizationInfo(Request); var user = _userManager.GetUserById(auth.UserId); - if (item is Playlist || item is BoxSet) + if (!item.CanDelete(user)) { - // For now this is allowed if user can see the playlist - } - else if (item is ILiveTvRecording) - { - if (!user.Policy.EnableLiveTvManagement) - { - throw new UnauthorizedAccessException(); - } - } - else - { - if (!user.Policy.EnableContentDeletion) - { - throw new UnauthorizedAccessException(); - } + throw new UnauthorizedAccessException(); } var task = _libraryManager.DeleteItem(item); diff --git a/MediaBrowser.Api/Playback/BaseStreamingService.cs b/MediaBrowser.Api/Playback/BaseStreamingService.cs index 6d555e136a..d26ca27216 100644 --- a/MediaBrowser.Api/Playback/BaseStreamingService.cs +++ b/MediaBrowser.Api/Playback/BaseStreamingService.cs @@ -123,7 +123,7 @@ namespace MediaBrowser.Api.Playback private string GetOutputFilePath(StreamState state) { var folder = ServerConfigurationManager.ApplicationPaths.TranscodingTempPath; - + var outputFileExtension = GetOutputFileExtension(state); var data = GetCommandLineArguments("dummy\\dummy", "dummyTranscodingId", state, false); @@ -323,13 +323,13 @@ namespace MediaBrowser.Api.Playback switch (qualitySetting) { case EncodingQuality.HighSpeed: - param += " -crf 23"; + param += " -subq 0 -crf 23"; break; case EncodingQuality.HighQuality: - param += " -crf 20"; + param += " -subq 3 -crf 20"; break; case EncodingQuality.MaxQuality: - param += " -crf 18"; + param += " -subq 6 -crf 18"; break; } } @@ -507,7 +507,7 @@ namespace MediaBrowser.Api.Playback } } - return param; + return "-pix_fmt yuv420p " + param; } protected string GetAudioFilterParam(StreamState state, bool isHls) @@ -918,7 +918,7 @@ namespace MediaBrowser.Api.Playback if (SupportsThrottleWithStream) { var url = "http://localhost:" + ServerConfigurationManager.Configuration.HttpServerPortNumber.ToString(UsCulture) + "/videos/" + state.Request.Id + "/stream?static=true&Throttle=true&mediaSourceId=" + state.Request.MediaSourceId; - + url += "&transcodingJobId=" + transcodingJobId; return string.Format("\"{0}\"", url); diff --git a/MediaBrowser.Api/Playback/Progressive/VideoService.cs b/MediaBrowser.Api/Playback/Progressive/VideoService.cs index 8924bb38f6..7e86b867f6 100644 --- a/MediaBrowser.Api/Playback/Progressive/VideoService.cs +++ b/MediaBrowser.Api/Playback/Progressive/VideoService.cs @@ -97,6 +97,7 @@ namespace MediaBrowser.Api.Playback.Progressive if (string.Equals(Path.GetExtension(outputPath), ".mp4", StringComparison.OrdinalIgnoreCase)) { + // Comparison: https://github.com/jansmolders86/mediacenterjs/blob/master/lib/transcoding/desktop.js format = " -f mp4 -movflags frag_keyframe+empty_moov"; } diff --git a/MediaBrowser.Controller/Channels/Channel.cs b/MediaBrowser.Controller/Channels/Channel.cs index 87d257f12e..a482f45fe0 100644 --- a/MediaBrowser.Controller/Channels/Channel.cs +++ b/MediaBrowser.Controller/Channels/Channel.cs @@ -67,5 +67,10 @@ namespace MediaBrowser.Controller.Channels { return System.IO.Path.Combine(basePath, "channels", id.ToString("N"), "metadata"); } + + public override bool CanDelete() + { + return false; + } } } diff --git a/MediaBrowser.Controller/Channels/ChannelAudioItem.cs b/MediaBrowser.Controller/Channels/ChannelAudioItem.cs index d9330f8a30..91b2407bee 100644 --- a/MediaBrowser.Controller/Channels/ChannelAudioItem.cs +++ b/MediaBrowser.Controller/Channels/ChannelAudioItem.cs @@ -3,10 +3,10 @@ using MediaBrowser.Model.Channels; using MediaBrowser.Model.Configuration; using MediaBrowser.Model.Dto; using MediaBrowser.Model.Entities; +using MediaBrowser.Model.Users; using System.Collections.Generic; using System.Linq; using System.Threading; -using MediaBrowser.Model.Users; namespace MediaBrowser.Controller.Channels { @@ -89,5 +89,10 @@ namespace MediaBrowser.Controller.Channels return list; } + + public override bool CanDelete() + { + return false; + } } } diff --git a/MediaBrowser.Controller/Channels/ChannelFolderItem.cs b/MediaBrowser.Controller/Channels/ChannelFolderItem.cs index dce9840eda..7ba73d126c 100644 --- a/MediaBrowser.Controller/Channels/ChannelFolderItem.cs +++ b/MediaBrowser.Controller/Channels/ChannelFolderItem.cs @@ -1,11 +1,10 @@ -using System; -using MediaBrowser.Controller.Entities; +using MediaBrowser.Controller.Entities; using MediaBrowser.Model.Channels; -using MediaBrowser.Model.Configuration; using MediaBrowser.Model.Querying; +using MediaBrowser.Model.Users; +using System; using System.Threading; using System.Threading.Tasks; -using MediaBrowser.Model.Users; namespace MediaBrowser.Controller.Channels { @@ -76,5 +75,10 @@ namespace MediaBrowser.Controller.Channels { return System.IO.Path.Combine(basePath, "channels", ChannelId, Id.ToString("N")); } + + public override bool CanDelete() + { + return false; + } } } diff --git a/MediaBrowser.Controller/Channels/ChannelVideoItem.cs b/MediaBrowser.Controller/Channels/ChannelVideoItem.cs index e3fad56e90..d7d4483cd1 100644 --- a/MediaBrowser.Controller/Channels/ChannelVideoItem.cs +++ b/MediaBrowser.Controller/Channels/ChannelVideoItem.cs @@ -4,11 +4,11 @@ using MediaBrowser.Model.Channels; using MediaBrowser.Model.Configuration; using MediaBrowser.Model.Dto; using MediaBrowser.Model.Entities; +using MediaBrowser.Model.Users; using System.Collections.Generic; using System.Globalization; using System.Linq; using System.Threading; -using MediaBrowser.Model.Users; namespace MediaBrowser.Controller.Channels { @@ -119,5 +119,10 @@ namespace MediaBrowser.Controller.Channels { return System.IO.Path.Combine(basePath, "channels", ChannelId, Id.ToString("N")); } + + public override bool CanDelete() + { + return false; + } } } diff --git a/MediaBrowser.Controller/Entities/AggregateFolder.cs b/MediaBrowser.Controller/Entities/AggregateFolder.cs index af2cca5e63..66a0d551b2 100644 --- a/MediaBrowser.Controller/Entities/AggregateFolder.cs +++ b/MediaBrowser.Controller/Entities/AggregateFolder.cs @@ -32,6 +32,11 @@ namespace MediaBrowser.Controller.Entities } } + public override bool CanDelete() + { + return false; + } + /// /// The _virtual children /// diff --git a/MediaBrowser.Controller/Entities/Audio/Audio.cs b/MediaBrowser.Controller/Entities/Audio/Audio.cs index 2dcea37bdf..a7b91b8681 100644 --- a/MediaBrowser.Controller/Entities/Audio/Audio.cs +++ b/MediaBrowser.Controller/Entities/Audio/Audio.cs @@ -113,6 +113,13 @@ namespace MediaBrowser.Controller.Entities.Audio } } + public override bool CanDownload() + { + var locationType = LocationType; + return locationType != LocationType.Remote && + locationType != LocationType.Virtual; + } + /// /// Gets or sets the artist. /// diff --git a/MediaBrowser.Controller/Entities/Audio/MusicArtist.cs b/MediaBrowser.Controller/Entities/Audio/MusicArtist.cs index 038aa98aae..e65d3c0e78 100644 --- a/MediaBrowser.Controller/Entities/Audio/MusicArtist.cs +++ b/MediaBrowser.Controller/Entities/Audio/MusicArtist.cs @@ -1,14 +1,13 @@ -using System.Runtime.Serialization; -using MediaBrowser.Common.Progress; -using MediaBrowser.Controller.Providers; +using MediaBrowser.Controller.Providers; using MediaBrowser.Model.Configuration; using MediaBrowser.Model.Entities; +using MediaBrowser.Model.Users; using System; using System.Collections.Generic; using System.Linq; +using System.Runtime.Serialization; using System.Threading; using System.Threading.Tasks; -using MediaBrowser.Model.Users; namespace MediaBrowser.Controller.Entities.Audio { @@ -35,6 +34,11 @@ namespace MediaBrowser.Controller.Entities.Audio get { return true; } } + public override bool CanDelete() + { + return !IsAccessedByName; + } + protected override IEnumerable ActualChildren { get diff --git a/MediaBrowser.Controller/Entities/Audio/MusicGenre.cs b/MediaBrowser.Controller/Entities/Audio/MusicGenre.cs index 9689d7cce2..ed09560732 100644 --- a/MediaBrowser.Controller/Entities/Audio/MusicGenre.cs +++ b/MediaBrowser.Controller/Entities/Audio/MusicGenre.cs @@ -39,6 +39,11 @@ namespace MediaBrowser.Controller.Entities.Audio } } + public override bool CanDelete() + { + return false; + } + /// /// Gets a value indicating whether this instance is owned item. /// diff --git a/MediaBrowser.Controller/Entities/BaseItem.cs b/MediaBrowser.Controller/Entities/BaseItem.cs index 4925bcd8ad..1443d99d32 100644 --- a/MediaBrowser.Controller/Entities/BaseItem.cs +++ b/MediaBrowser.Controller/Entities/BaseItem.cs @@ -239,6 +239,38 @@ namespace MediaBrowser.Controller.Entities get { return this.GetImagePath(ImageType.Primary); } } + public virtual bool CanDelete() + { + var locationType = LocationType; + return locationType != LocationType.Remote && + locationType != LocationType.Virtual; + } + + public virtual bool IsAuthorizedToDelete(User user) + { + return user.Policy.EnableContentDeletion; + } + + public bool CanDelete(User user) + { + return CanDelete() && IsAuthorizedToDelete(user); + } + + public virtual bool CanDownload() + { + return false; + } + + public virtual bool IsAuthorizedToDownload(User user) + { + return user.Policy.EnableContentDownloading; + } + + public bool CanDownload(User user) + { + return CanDownload() && IsAuthorizedToDownload(user); + } + /// /// Gets or sets the date created. /// diff --git a/MediaBrowser.Controller/Entities/BasePluginFolder.cs b/MediaBrowser.Controller/Entities/BasePluginFolder.cs index b30bd81b96..785c441d37 100644 --- a/MediaBrowser.Controller/Entities/BasePluginFolder.cs +++ b/MediaBrowser.Controller/Entities/BasePluginFolder.cs @@ -11,5 +11,10 @@ namespace MediaBrowser.Controller.Entities { get { return null; } } + + public override bool CanDelete() + { + return false; + } } } diff --git a/MediaBrowser.Controller/Entities/Book.cs b/MediaBrowser.Controller/Entities/Book.cs index 381b2101d2..e59db67a6a 100644 --- a/MediaBrowser.Controller/Entities/Book.cs +++ b/MediaBrowser.Controller/Entities/Book.cs @@ -2,6 +2,7 @@ using MediaBrowser.Model.Configuration; using System.Collections.Generic; using System.Linq; +using MediaBrowser.Model.Entities; using MediaBrowser.Model.Users; namespace MediaBrowser.Controller.Entities @@ -37,6 +38,13 @@ namespace MediaBrowser.Controller.Entities Tags = new List(); } + public override bool CanDownload() + { + var locationType = LocationType; + return locationType != LocationType.Remote && + locationType != LocationType.Virtual; + } + protected override bool GetBlockUnratedValue(UserPolicy config) { return config.BlockUnratedItems.Contains(UnratedItem.Book); diff --git a/MediaBrowser.Controller/Entities/CollectionFolder.cs b/MediaBrowser.Controller/Entities/CollectionFolder.cs index f82934a51b..a39357f2b0 100644 --- a/MediaBrowser.Controller/Entities/CollectionFolder.cs +++ b/MediaBrowser.Controller/Entities/CollectionFolder.cs @@ -35,6 +35,11 @@ namespace MediaBrowser.Controller.Entities } } + public override bool CanDelete() + { + return false; + } + public string CollectionType { get; set; } /// diff --git a/MediaBrowser.Controller/Entities/Game.cs b/MediaBrowser.Controller/Entities/Game.cs index 71642ea902..899e5628f1 100644 --- a/MediaBrowser.Controller/Entities/Game.cs +++ b/MediaBrowser.Controller/Entities/Game.cs @@ -1,10 +1,10 @@ using MediaBrowser.Controller.Providers; using MediaBrowser.Model.Configuration; using MediaBrowser.Model.Entities; +using MediaBrowser.Model.Users; using System; using System.Collections.Generic; using System.Linq; -using MediaBrowser.Model.Users; namespace MediaBrowser.Controller.Entities { @@ -38,6 +38,13 @@ namespace MediaBrowser.Controller.Entities public List LocalTrailerIds { get; set; } public List RemoteTrailerIds { get; set; } + public override bool CanDownload() + { + var locationType = LocationType; + return locationType != LocationType.Remote && + locationType != LocationType.Virtual; + } + /// /// Gets or sets the tags. /// diff --git a/MediaBrowser.Controller/Entities/GameGenre.cs b/MediaBrowser.Controller/Entities/GameGenre.cs index 41ce0c12ab..b246b9388f 100644 --- a/MediaBrowser.Controller/Entities/GameGenre.cs +++ b/MediaBrowser.Controller/Entities/GameGenre.cs @@ -43,6 +43,11 @@ namespace MediaBrowser.Controller.Entities } } + public override bool CanDelete() + { + return false; + } + public IEnumerable GetTaggedItems(IEnumerable inputItems) { return inputItems.Where(GetItemFilter()); diff --git a/MediaBrowser.Controller/Entities/Genre.cs b/MediaBrowser.Controller/Entities/Genre.cs index f581c55e83..e17a5c1d8b 100644 --- a/MediaBrowser.Controller/Entities/Genre.cs +++ b/MediaBrowser.Controller/Entities/Genre.cs @@ -34,6 +34,11 @@ namespace MediaBrowser.Controller.Entities } } + public override bool CanDelete() + { + return false; + } + /// /// Gets a value indicating whether this instance is owned item. /// diff --git a/MediaBrowser.Controller/Entities/IItemByName.cs b/MediaBrowser.Controller/Entities/IItemByName.cs index b48ad788fc..14b69b8fde 100644 --- a/MediaBrowser.Controller/Entities/IItemByName.cs +++ b/MediaBrowser.Controller/Entities/IItemByName.cs @@ -15,6 +15,10 @@ namespace MediaBrowser.Controller.Entities /// IEnumerable{BaseItem}. IEnumerable GetTaggedItems(IEnumerable inputItems); + /// + /// Gets the item filter. + /// + /// Func<BaseItem, System.Boolean>. Func GetItemFilter(); } diff --git a/MediaBrowser.Controller/Entities/Movies/BoxSet.cs b/MediaBrowser.Controller/Entities/Movies/BoxSet.cs index 7f74e33793..d874046efd 100644 --- a/MediaBrowser.Controller/Entities/Movies/BoxSet.cs +++ b/MediaBrowser.Controller/Entities/Movies/BoxSet.cs @@ -74,6 +74,11 @@ namespace MediaBrowser.Controller.Entities.Movies } } + public override bool IsAuthorizedToDelete(User user) + { + return true; + } + /// /// Gets the trailer ids. /// diff --git a/MediaBrowser.Controller/Entities/Person.cs b/MediaBrowser.Controller/Entities/Person.cs index 25509b1530..d8cb69ca17 100644 --- a/MediaBrowser.Controller/Entities/Person.cs +++ b/MediaBrowser.Controller/Entities/Person.cs @@ -45,6 +45,11 @@ namespace MediaBrowser.Controller.Entities } } + public override bool CanDelete() + { + return false; + } + /// /// Gets a value indicating whether this instance is owned item. /// diff --git a/MediaBrowser.Controller/Entities/Studio.cs b/MediaBrowser.Controller/Entities/Studio.cs index 76193d6c42..31bbaf422e 100644 --- a/MediaBrowser.Controller/Entities/Studio.cs +++ b/MediaBrowser.Controller/Entities/Studio.cs @@ -40,6 +40,11 @@ namespace MediaBrowser.Controller.Entities } } + public override bool CanDelete() + { + return false; + } + /// /// Gets a value indicating whether this instance is owned item. /// diff --git a/MediaBrowser.Controller/Entities/UserView.cs b/MediaBrowser.Controller/Entities/UserView.cs index cd179eb428..5f7ca3d3f4 100644 --- a/MediaBrowser.Controller/Entities/UserView.cs +++ b/MediaBrowser.Controller/Entities/UserView.cs @@ -40,6 +40,11 @@ namespace MediaBrowser.Controller.Entities return result.Items; } + public override bool CanDelete() + { + return false; + } + public override IEnumerable GetRecursiveChildren(User user, Func filter) { var result = GetItems(new InternalItemsQuery diff --git a/MediaBrowser.Controller/Entities/Video.cs b/MediaBrowser.Controller/Entities/Video.cs index 3abaf095c8..12c377c906 100644 --- a/MediaBrowser.Controller/Entities/Video.cs +++ b/MediaBrowser.Controller/Entities/Video.cs @@ -64,6 +64,19 @@ namespace MediaBrowser.Controller.Entities LinkedAlternateVersions = new List(); } + public override bool CanDownload() + { + if (VideoType == VideoType.HdDvd || VideoType == VideoType.Dvd || + VideoType == VideoType.BluRay) + { + return false; + } + + var locationType = LocationType; + return locationType != LocationType.Remote && + locationType != LocationType.Virtual; + } + [IgnoreDataMember] public override bool SupportsAddingToPlaylist { diff --git a/MediaBrowser.Controller/Entities/Year.cs b/MediaBrowser.Controller/Entities/Year.cs index 59a4bf16d3..cf3ad3b6ab 100644 --- a/MediaBrowser.Controller/Entities/Year.cs +++ b/MediaBrowser.Controller/Entities/Year.cs @@ -34,6 +34,11 @@ namespace MediaBrowser.Controller.Entities } } + public override bool CanDelete() + { + return false; + } + /// /// Gets a value indicating whether this instance is owned item. /// diff --git a/MediaBrowser.Controller/LiveTv/ILiveTvRecording.cs b/MediaBrowser.Controller/LiveTv/ILiveTvRecording.cs index ba1cb30436..784cb6ea18 100644 --- a/MediaBrowser.Controller/LiveTv/ILiveTvRecording.cs +++ b/MediaBrowser.Controller/LiveTv/ILiveTvRecording.cs @@ -25,5 +25,9 @@ namespace MediaBrowser.Controller.LiveTv Task RefreshMetadata(MetadataRefreshOptions options, CancellationToken cancellationToken); PlayAccess GetPlayAccess(User user); + + bool CanDelete(); + + bool CanDelete(User user); } } diff --git a/MediaBrowser.Controller/LiveTv/LiveTvAudioRecording.cs b/MediaBrowser.Controller/LiveTv/LiveTvAudioRecording.cs index 8faaa895c2..9815066efc 100644 --- a/MediaBrowser.Controller/LiveTv/LiveTvAudioRecording.cs +++ b/MediaBrowser.Controller/LiveTv/LiveTvAudioRecording.cs @@ -1,4 +1,5 @@ using System.Runtime.Serialization; +using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Entities.Audio; using MediaBrowser.Model.Configuration; using MediaBrowser.Model.Entities; @@ -93,5 +94,10 @@ namespace MediaBrowser.Controller.LiveTv { return System.IO.Path.Combine(basePath, "livetv", Id.ToString("N")); } + + public override bool IsAuthorizedToDelete(User user) + { + return user.Policy.EnableLiveTvManagement; + } } } diff --git a/MediaBrowser.Controller/LiveTv/LiveTvChannel.cs b/MediaBrowser.Controller/LiveTv/LiveTvChannel.cs index 1948ce0d50..eaea6cfa45 100644 --- a/MediaBrowser.Controller/LiveTv/LiveTvChannel.cs +++ b/MediaBrowser.Controller/LiveTv/LiveTvChannel.cs @@ -1,5 +1,4 @@ -using System.Runtime.Serialization; -using MediaBrowser.Controller.Entities; +using MediaBrowser.Controller.Entities; using MediaBrowser.Model.Configuration; using MediaBrowser.Model.Dto; using MediaBrowser.Model.Entities; @@ -8,6 +7,7 @@ using MediaBrowser.Model.MediaInfo; using MediaBrowser.Model.Users; using System.Collections.Generic; using System.Linq; +using System.Runtime.Serialization; namespace MediaBrowser.Controller.LiveTv { @@ -135,5 +135,10 @@ namespace MediaBrowser.Controller.LiveTv { return System.IO.Path.Combine(basePath, "livetv", Id.ToString("N"), "metadata"); } + + public override bool CanDelete() + { + return false; + } } } diff --git a/MediaBrowser.Controller/LiveTv/LiveTvProgram.cs b/MediaBrowser.Controller/LiveTv/LiveTvProgram.cs index a66aaad6f8..ee85ce20b0 100644 --- a/MediaBrowser.Controller/LiveTv/LiveTvProgram.cs +++ b/MediaBrowser.Controller/LiveTv/LiveTvProgram.cs @@ -1,13 +1,13 @@ -using System.Runtime.Serialization; -using MediaBrowser.Controller.Entities; +using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Library; using MediaBrowser.Model.Configuration; using MediaBrowser.Model.LiveTv; +using MediaBrowser.Model.Users; using System; +using System.Linq; +using System.Runtime.Serialization; using System.Threading; using System.Threading.Tasks; -using System.Linq; -using MediaBrowser.Model.Users; namespace MediaBrowser.Controller.LiveTv { @@ -215,5 +215,10 @@ namespace MediaBrowser.Controller.LiveTv { return System.IO.Path.Combine(basePath, "livetv", Id.ToString("N")); } + + public override bool CanDelete() + { + return false; + } } } diff --git a/MediaBrowser.Controller/LiveTv/LiveTvVideoRecording.cs b/MediaBrowser.Controller/LiveTv/LiveTvVideoRecording.cs index 34fe757a71..207684d55d 100644 --- a/MediaBrowser.Controller/LiveTv/LiveTvVideoRecording.cs +++ b/MediaBrowser.Controller/LiveTv/LiveTvVideoRecording.cs @@ -92,5 +92,10 @@ namespace MediaBrowser.Controller.LiveTv { return System.IO.Path.Combine(basePath, "livetv", Id.ToString("N")); } + + public override bool IsAuthorizedToDelete(User user) + { + return user.Policy.EnableLiveTvManagement; + } } } diff --git a/MediaBrowser.Controller/Playlists/Playlist.cs b/MediaBrowser.Controller/Playlists/Playlist.cs index 0f0c6a97ed..3479902cbd 100644 --- a/MediaBrowser.Controller/Playlists/Playlist.cs +++ b/MediaBrowser.Controller/Playlists/Playlist.cs @@ -1,7 +1,5 @@ using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Entities.Audio; -using MediaBrowser.Controller.Entities.Movies; -using MediaBrowser.Controller.Entities.TV; using MediaBrowser.Model.Entities; using MediaBrowser.Model.Querying; using System; @@ -40,6 +38,11 @@ namespace MediaBrowser.Controller.Playlists } } + public override bool IsAuthorizedToDelete(User user) + { + return true; + } + public override bool IsSaveLocalMetadataEnabled() { return true; diff --git a/MediaBrowser.MediaEncoding/Encoder/BaseEncoder.cs b/MediaBrowser.MediaEncoding/Encoder/BaseEncoder.cs index 344eb9fbdf..5a00c3d3fe 100644 --- a/MediaBrowser.MediaEncoding/Encoder/BaseEncoder.cs +++ b/MediaBrowser.MediaEncoding/Encoder/BaseEncoder.cs @@ -631,13 +631,13 @@ namespace MediaBrowser.MediaEncoding.Encoder switch (qualitySetting) { case EncodingQuality.HighSpeed: - param += " -crf 23"; + param += " -subq 0 -crf 23"; break; case EncodingQuality.HighQuality: - param += " -crf 20"; + param += " -subq 3 -crf 20"; break; case EncodingQuality.MaxQuality: - param += " -crf 18"; + param += " -subq 6 -crf 18"; break; } } @@ -740,7 +740,7 @@ namespace MediaBrowser.MediaEncoding.Encoder param += " -level " + state.Options.Level.Value.ToString(UsCulture); } - return param; + return "-pix_fmt yuv420p " + param; } protected string GetVideoBitrateParam(EncodingJob state, string videoCodec, bool isHls) diff --git a/MediaBrowser.Model/Dto/BaseItemDto.cs b/MediaBrowser.Model/Dto/BaseItemDto.cs index c1a34a7f61..be3cd99be8 100644 --- a/MediaBrowser.Model/Dto/BaseItemDto.cs +++ b/MediaBrowser.Model/Dto/BaseItemDto.cs @@ -56,6 +56,8 @@ namespace MediaBrowser.Model.Dto public int? AirsBeforeEpisodeNumber { get; set; } public int? AbsoluteEpisodeNumber { get; set; } public bool? DisplaySpecialsWithSeasons { get; set; } + public bool? CanDelete { get; set; } + public bool? CanDownload { get; set; } public string PreferredMetadataLanguage { get; set; } public string PreferredMetadataCountryCode { get; set; } diff --git a/MediaBrowser.Model/LiveTv/RecordingInfoDto.cs b/MediaBrowser.Model/LiveTv/RecordingInfoDto.cs index 15378a9af1..a6cd85d8d3 100644 --- a/MediaBrowser.Model/LiveTv/RecordingInfoDto.cs +++ b/MediaBrowser.Model/LiveTv/RecordingInfoDto.cs @@ -99,6 +99,12 @@ namespace MediaBrowser.Model.LiveTv /// The path. public string Path { get; set; } + /// + /// Gets or sets a value indicating whether this instance can delete. + /// + /// null if [can delete] contains no value, true if [can delete]; otherwise, false. + public bool? CanDelete { get; set; } + /// /// Overview of the recording. /// diff --git a/MediaBrowser.Model/Querying/ItemFields.cs b/MediaBrowser.Model/Querying/ItemFields.cs index 5018f8e516..7a91d77fff 100644 --- a/MediaBrowser.Model/Querying/ItemFields.cs +++ b/MediaBrowser.Model/Querying/ItemFields.cs @@ -1,5 +1,4 @@ - -namespace MediaBrowser.Model.Querying +namespace MediaBrowser.Model.Querying { /// /// Used to control the data that gets attached to DtoBaseItems @@ -26,6 +25,16 @@ namespace MediaBrowser.Model.Querying /// Budget, + /// + /// The can delete + /// + CanDelete, + + /// + /// The can download + /// + CanDownload, + /// /// The chapters /// diff --git a/MediaBrowser.Model/Users/UserPolicy.cs b/MediaBrowser.Model/Users/UserPolicy.cs index cdc5077b02..9606cbe3fe 100644 --- a/MediaBrowser.Model/Users/UserPolicy.cs +++ b/MediaBrowser.Model/Users/UserPolicy.cs @@ -42,7 +42,8 @@ namespace MediaBrowser.Model.Users public bool EnableMediaPlayback { get; set; } public bool EnableContentDeletion { get; set; } - + public bool EnableContentDownloading { get; set; } + /// /// Gets or sets a value indicating whether [enable synchronize]. /// @@ -80,6 +81,8 @@ namespace MediaBrowser.Model.Users EnabledDevices = new string[] { }; EnableAllDevices = true; + + EnableContentDownloading = true; } } } diff --git a/MediaBrowser.Server.Implementations/Dto/DtoService.cs b/MediaBrowser.Server.Implementations/Dto/DtoService.cs index 7b36321f18..75bddda723 100644 --- a/MediaBrowser.Server.Implementations/Dto/DtoService.cs +++ b/MediaBrowser.Server.Implementations/Dto/DtoService.cs @@ -284,6 +284,20 @@ namespace MediaBrowser.Server.Implementations.Dto AttachLinkedChildImages(dto, playlist, user, options); } + if (fields.Contains(ItemFields.CanDelete)) + { + dto.CanDelete = user == null + ? item.CanDelete() + : item.CanDelete(user); + } + + if (fields.Contains(ItemFields.CanDownload)) + { + dto.CanDownload = user == null + ? item.CanDownload() + : item.CanDownload(user); + } + return dto; } diff --git a/MediaBrowser.Server.Implementations/HttpServer/Security/AuthService.cs b/MediaBrowser.Server.Implementations/HttpServer/Security/AuthService.cs index c374a31b36..77953ee43b 100644 --- a/MediaBrowser.Server.Implementations/HttpServer/Security/AuthService.cs +++ b/MediaBrowser.Server.Implementations/HttpServer/Security/AuthService.cs @@ -74,7 +74,9 @@ namespace MediaBrowser.Server.Implementations.HttpServer.Security ValidateUserAccess(user, request, authAttribtues, auth); } - if (!IsExemptFromRoles(auth, authAttribtues)) + var info = (AuthenticationInfo)request.Items["OriginalAuthenticationInfo"]; + + if (!IsExemptFromRoles(auth, authAttribtues, info)) { var roles = authAttribtues.GetRoles().ToList(); @@ -142,7 +144,7 @@ namespace MediaBrowser.Server.Implementations.HttpServer.Security StringComparer.OrdinalIgnoreCase); } - private bool IsExemptFromRoles(AuthorizationInfo auth, IAuthenticationAttributes authAttribtues) + private bool IsExemptFromRoles(AuthorizationInfo auth, IAuthenticationAttributes authAttribtues, AuthenticationInfo tokenInfo) { if (!_config.Configuration.IsStartupWizardCompleted && authAttribtues.AllowBeforeStartupWizard) @@ -150,6 +152,16 @@ namespace MediaBrowser.Server.Implementations.HttpServer.Security return true; } + if (string.IsNullOrWhiteSpace(auth.Token)) + { + return true; + } + + if (tokenInfo != null && string.IsNullOrWhiteSpace(tokenInfo.UserId)) + { + return true; + } + return false; } @@ -175,6 +187,16 @@ namespace MediaBrowser.Server.Implementations.HttpServer.Security }; } } + if (roles.Contains("download", StringComparer.OrdinalIgnoreCase)) + { + if (user == null || !user.Policy.EnableContentDownloading) + { + throw new SecurityException("User does not have download access.") + { + SecurityExceptionType = SecurityExceptionType.Unauthenticated + }; + } + } } private bool IsValidConnectKey(string token) diff --git a/MediaBrowser.Server.Implementations/LiveTv/LiveTvDtoService.cs b/MediaBrowser.Server.Implementations/LiveTv/LiveTvDtoService.cs index b3066b460f..f1bb5c13ae 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/LiveTvDtoService.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/LiveTvDtoService.cs @@ -229,6 +229,10 @@ namespace MediaBrowser.Server.Implementations.LiveTv ServerId = _appHost.SystemId }; + dto.CanDelete = user == null + ? recording.CanDelete() + : recording.CanDelete(user); + dto.MediaStreams = dto.MediaSources.SelectMany(i => i.MediaStreams).ToList(); if (info.Status == RecordingStatus.InProgress) diff --git a/MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json b/MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json index 3fddf274c6..184a7f9a4e 100644 --- a/MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json +++ b/MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json @@ -48,6 +48,7 @@ "LabelFailed": "(failed)", "ButtonHelp": "Help", "ButtonSave": "Save", + "ButtonDownload": "Download", "SyncJobStatusQueued": "Queued", "SyncJobStatusConverting": "Converting", "SyncJobStatusFailed": "Failed", @@ -56,6 +57,7 @@ "SyncJobStatusReadyToTransfer": "Ready to Transfer", "SyncJobStatusTransferring": "Transferring", "SyncJobStatusCompletedWithError": "Synced with errors", + "SyncJobItemStatusReadyToTransfer": "Ready to Transfer", "LabelCollection": "Collection", "HeaderAddToCollection": "Add to Collection", "NewCollectionNameExample": "Example: Star Wars Collection", diff --git a/MediaBrowser.Server.Implementations/Localization/Server/server.json b/MediaBrowser.Server.Implementations/Localization/Server/server.json index aaf05d1ff5..c280b32ea2 100644 --- a/MediaBrowser.Server.Implementations/Localization/Server/server.json +++ b/MediaBrowser.Server.Implementations/Localization/Server/server.json @@ -285,10 +285,10 @@ "ButtonHelp": "Help", "OptionAllowUserToManageServer": "Allow this user to manage the server", "HeaderFeatureAccess": "Feature Access", - "OptionAllowMediaPlayback": "Allow media playback", - "OptionAllowBrowsingLiveTv": "Allow browsing of live tv", - "OptionAllowDeleteLibraryContent": "Allow deletion of library content", - "OptionAllowManageLiveTv": "Allow management of live tv recordings", + "OptionAllowMediaPlayback": "Media playback", + "OptionAllowBrowsingLiveTv": "Live TV", + "OptionAllowDeleteLibraryContent": "Media deletion", + "OptionAllowManageLiveTv": "Live TV recording management", "OptionAllowRemoteControlOthers": "Allow remote control of other users", "OptionAllowRemoteSharedDevices": "Allow remote control of shared devices", "OptionAllowRemoteSharedDevicesHelp": "Dlna devices are considered shared until a user begins controlling it.", @@ -1133,7 +1133,7 @@ "ViewTypeLiveTvRecordingGroups": "Recordings", "ViewTypeLiveTvChannels": "Channels", "LabelEasyPinCode": "Easy pin code:", - "EasyPasswordHelp": "Your easy pin code is used for offline access with supported Media Browser apps, and can also be used for easy in-network sign in.", + "EasyPasswordHelp": "Your easy pin code is used for offline access with supported Media Browser apps, and can also be used for easy in-network sign in.", "LabelInNetworkSignInWithEasyPassword": "Enable in-network sign in with my easy pin code", "LabelInNetworkSignInWithEasyPasswordHelp": "If enabled, you'll be able to use your easy pin code to sign in to Media Browser apps from inside your home network. Your regular password will only be needed away from home. If the pin code is left blank, you won't need a password within your home network.", "HeaderPassword": "Password", @@ -1362,7 +1362,8 @@ "LabelEnableSingleImageInDidlLimitHelp": "Some devices will not render properly if multiple images are embedded within Didl.", "TabActivity": "Activity", "TitleSync": "Sync", - "OptionAllowSyncContent": "Allow syncing media to devices", + "OptionAllowSyncContent": "Sync", + "OptionAllowContentDownloading": "Media downloading", "NameSeasonUnknown": "Season Unknown", "NameSeasonNumber": "Season {0}", "LabelNewUserNameHelp": "Usernames can contain letters (a-z), numbers (0-9), dashes (-), underscores (_), apostrophes ('), and periods (.)", diff --git a/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs b/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs index e418448db7..9ecb80f3ba 100644 --- a/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs +++ b/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs @@ -311,8 +311,10 @@ namespace MediaBrowser.Server.Implementations.Sync var itemByName = item as IItemByName; if (itemByName != null) { + var itemByNameFilter = itemByName.GetItemFilter(); + return user.RootFolder - .GetRecursiveChildren(user, itemByName.GetItemFilter()); + .GetRecursiveChildren(user, i => !i.IsFolder && itemByNameFilter(i)); } if (item.IsFolder) diff --git a/MediaBrowser.WebDashboard/Api/PackageCreator.cs b/MediaBrowser.WebDashboard/Api/PackageCreator.cs index 3eb98e95d0..8bf0050219 100644 --- a/MediaBrowser.WebDashboard/Api/PackageCreator.cs +++ b/MediaBrowser.WebDashboard/Api/PackageCreator.cs @@ -414,7 +414,6 @@ namespace MediaBrowser.WebDashboard.Api "indexpage.js", "itembynamedetailpage.js", "itemdetailpage.js", - "itemgallery.js", "itemlistpage.js", "librarypathmapping.js", "reports.js", diff --git a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj index 34b0e9e88e..bc610b7b65 100644 --- a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj +++ b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj @@ -1656,9 +1656,6 @@ - - PreserveNewest - PreserveNewest @@ -1707,9 +1704,6 @@ PreserveNewest - - PreserveNewest - PreserveNewest -- cgit v1.2.3 From 01828f19a766b8bdddb022665cb5302f5cd745fd Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Mon, 9 Feb 2015 01:17:11 -0500 Subject: added an allow mode filter for tags --- MediaBrowser.Controller/Channels/Channel.cs | 6 ++++ MediaBrowser.Controller/Entities/BaseItem.cs | 32 +++++++++++++++++++++- MediaBrowser.Controller/Entities/Folder.cs | 14 ++++++++++ MediaBrowser.Dlna/Profiles/Xbox360Profile.cs | 4 +-- MediaBrowser.Dlna/Profiles/Xml/Xbox 360.xml | 4 +-- .../MediaBrowser.Model.Portable.csproj | 6 ++++ .../MediaBrowser.Model.net35.csproj | 6 ++++ MediaBrowser.Model/MediaBrowser.Model.csproj | 2 ++ MediaBrowser.Model/Users/TagFilter.cs | 9 ++++++ MediaBrowser.Model/Users/TagFilterMode.cs | 9 ++++++ MediaBrowser.Model/Users/UserPolicy.cs | 5 +++- .../Library/UserManager.cs | 20 ++++++++++++++ .../Localization/JavaScript/javascript.json | 2 +- .../Localization/Server/server.json | 8 ++++-- .../MediaBrowser.WebDashboard.csproj | 2 +- 15 files changed, 119 insertions(+), 10 deletions(-) create mode 100644 MediaBrowser.Model/Users/TagFilter.cs create mode 100644 MediaBrowser.Model/Users/TagFilterMode.cs (limited to 'MediaBrowser.Controller/Channels') diff --git a/MediaBrowser.Controller/Channels/Channel.cs b/MediaBrowser.Controller/Channels/Channel.cs index a482f45fe0..ab76f4e67f 100644 --- a/MediaBrowser.Controller/Channels/Channel.cs +++ b/MediaBrowser.Controller/Channels/Channel.cs @@ -5,6 +5,7 @@ using System; using System.Linq; using System.Threading; using System.Threading.Tasks; +using MediaBrowser.Model.Users; namespace MediaBrowser.Controller.Channels { @@ -72,5 +73,10 @@ namespace MediaBrowser.Controller.Channels { return false; } + + protected override bool IsTagFilterEnforced(TagFilterMode mode) + { + return false; + } } } diff --git a/MediaBrowser.Controller/Entities/BaseItem.cs b/MediaBrowser.Controller/Entities/BaseItem.cs index 1379ba829e..75a09a7b04 100644 --- a/MediaBrowser.Controller/Entities/BaseItem.cs +++ b/MediaBrowser.Controller/Entities/BaseItem.cs @@ -1080,7 +1080,7 @@ namespace MediaBrowser.Controller.Entities if (hasTags != null) { - if (user.Policy.BlockedTags.Any(i => hasTags.Tags.Contains(i, StringComparer.OrdinalIgnoreCase))) + if (user.Policy.TagFilters.Any(i => !IsTagFilterAccepted(hasTags, i))) { return false; } @@ -1089,6 +1089,36 @@ namespace MediaBrowser.Controller.Entities return true; } + private bool IsTagFilterAccepted(IHasTags hasTags, TagFilter filter) + { + if (IsTagFilterEnforced(filter.Mode)) + { + if (filter.Mode == TagFilterMode.Block) + { + // If content has the tag, it's not allowed + if (hasTags.Tags.Contains(filter.Tag, StringComparer.OrdinalIgnoreCase)) + { + return false; + } + } + else if (filter.Mode == TagFilterMode.Allow) + { + // If content doesn't have the tag, it's not allowed + if (!hasTags.Tags.Contains(filter.Tag, StringComparer.OrdinalIgnoreCase)) + { + return false; + } + } + } + + return true; + } + + protected virtual bool IsTagFilterEnforced(TagFilterMode mode) + { + return true; + } + /// /// Gets the block unrated value. /// diff --git a/MediaBrowser.Controller/Entities/Folder.cs b/MediaBrowser.Controller/Entities/Folder.cs index e85dee354a..fe9bea53b1 100644 --- a/MediaBrowser.Controller/Entities/Folder.cs +++ b/MediaBrowser.Controller/Entities/Folder.cs @@ -14,6 +14,7 @@ using System.Linq; using System.Runtime.Serialization; using System.Threading; using System.Threading.Tasks; +using MediaBrowser.Model.Users; namespace MediaBrowser.Controller.Entities { @@ -79,6 +80,19 @@ namespace MediaBrowser.Controller.Entities } } + protected override bool IsTagFilterEnforced(TagFilterMode mode) + { + if (this is ICollectionFolder) + { + return false; + } + if (this is UserView) + { + return false; + } + return true; + } + /// /// Gets or sets a value indicating whether this instance is physical root. /// diff --git a/MediaBrowser.Dlna/Profiles/Xbox360Profile.cs b/MediaBrowser.Dlna/Profiles/Xbox360Profile.cs index 7aa924be0f..e3dd832248 100644 --- a/MediaBrowser.Dlna/Profiles/Xbox360Profile.cs +++ b/MediaBrowser.Dlna/Profiles/Xbox360Profile.cs @@ -15,11 +15,11 @@ namespace MediaBrowser.Dlna.Profiles Name = "Xbox 360"; // Required according to above - ModelName = "Windows Media Connect"; + ModelName = "Windows Media Player Sharing"; ModelNumber = "12.0"; - FriendlyName = "${HostName} : 1 : Windows Media Connect"; + FriendlyName = "${HostName} : 1"; ModelUrl = "http://www.microsoft.com/"; Manufacturer = "Microsoft Corporation"; diff --git a/MediaBrowser.Dlna/Profiles/Xml/Xbox 360.xml b/MediaBrowser.Dlna/Profiles/Xml/Xbox 360.xml index 96b728bdc1..da55724075 100644 --- a/MediaBrowser.Dlna/Profiles/Xml/Xbox 360.xml +++ b/MediaBrowser.Dlna/Profiles/Xml/Xbox 360.xml @@ -8,10 +8,10 @@ - ${HostName} : 1 : Windows Media Connect + ${HostName} : 1 Microsoft Corporation http://www.microsoft.com/ - Windows Media Connect + Windows Media Player Sharing Media Browser 12.0 http://www.microsoft.com/ diff --git a/MediaBrowser.Model.Portable/MediaBrowser.Model.Portable.csproj b/MediaBrowser.Model.Portable/MediaBrowser.Model.Portable.csproj index ba3065bc9d..561ae1e41e 100644 --- a/MediaBrowser.Model.Portable/MediaBrowser.Model.Portable.csproj +++ b/MediaBrowser.Model.Portable/MediaBrowser.Model.Portable.csproj @@ -1181,6 +1181,12 @@ Users\PinRedeemResult.cs + + Users\TagFilter.cs + + + Users\TagFilterMode.cs + Users\UserAction.cs diff --git a/MediaBrowser.Model.net35/MediaBrowser.Model.net35.csproj b/MediaBrowser.Model.net35/MediaBrowser.Model.net35.csproj index 8d22f25a90..bf5624f7a9 100644 --- a/MediaBrowser.Model.net35/MediaBrowser.Model.net35.csproj +++ b/MediaBrowser.Model.net35/MediaBrowser.Model.net35.csproj @@ -1140,6 +1140,12 @@ Users\PinRedeemResult.cs + + Users\TagFilter.cs + + + Users\TagFilterMode.cs + Users\UserAction.cs diff --git a/MediaBrowser.Model/MediaBrowser.Model.csproj b/MediaBrowser.Model/MediaBrowser.Model.csproj index c8e09dd826..7f71c85c59 100644 --- a/MediaBrowser.Model/MediaBrowser.Model.csproj +++ b/MediaBrowser.Model/MediaBrowser.Model.csproj @@ -433,6 +433,8 @@ + + diff --git a/MediaBrowser.Model/Users/TagFilter.cs b/MediaBrowser.Model/Users/TagFilter.cs new file mode 100644 index 0000000000..5a30c435cf --- /dev/null +++ b/MediaBrowser.Model/Users/TagFilter.cs @@ -0,0 +1,9 @@ + +namespace MediaBrowser.Model.Users +{ + public class TagFilter + { + public string Tag { get; set; } + public TagFilterMode Mode { get; set; } + } +} diff --git a/MediaBrowser.Model/Users/TagFilterMode.cs b/MediaBrowser.Model/Users/TagFilterMode.cs new file mode 100644 index 0000000000..bce75b41fc --- /dev/null +++ b/MediaBrowser.Model/Users/TagFilterMode.cs @@ -0,0 +1,9 @@ + +namespace MediaBrowser.Model.Users +{ + public enum TagFilterMode + { + Block = 0, + Allow = 1 + } +} diff --git a/MediaBrowser.Model/Users/UserPolicy.cs b/MediaBrowser.Model/Users/UserPolicy.cs index 9606cbe3fe..c82b887bae 100644 --- a/MediaBrowser.Model/Users/UserPolicy.cs +++ b/MediaBrowser.Model/Users/UserPolicy.cs @@ -58,6 +58,8 @@ namespace MediaBrowser.Model.Users public string[] EnabledFolders { get; set; } public bool EnableAllFolders { get; set; } + + public TagFilter[] TagFilters { get; set; } public UserPolicy() { @@ -66,7 +68,6 @@ namespace MediaBrowser.Model.Users EnableLiveTvAccess = true; EnableSharedDeviceControl = true; - BlockedTags = new string[] { }; BlockUnratedItems = new UnratedItem[] { }; EnableUserPreferenceAccess = true; @@ -83,6 +84,8 @@ namespace MediaBrowser.Model.Users EnableAllDevices = true; EnableContentDownloading = true; + + TagFilters = new TagFilter[] { }; } } } diff --git a/MediaBrowser.Server.Implementations/Library/UserManager.cs b/MediaBrowser.Server.Implementations/Library/UserManager.cs index 37f7e31fa6..47903525b6 100644 --- a/MediaBrowser.Server.Implementations/Library/UserManager.cs +++ b/MediaBrowser.Server.Implementations/Library/UserManager.cs @@ -168,6 +168,7 @@ namespace MediaBrowser.Server.Implementations.Library foreach (var user in users) { await DoPolicyMigration(user).ConfigureAwait(false); + await DoBlockedTagMigration(user).ConfigureAwait(false); } // If there are no local users with admin rights, make them all admins @@ -346,6 +347,25 @@ namespace MediaBrowser.Server.Implementations.Library } } + private async Task DoBlockedTagMigration(User user) + { + if (user.Policy.BlockedTags != null) + { + user.Policy.TagFilters = user.Policy + .BlockedTags + .Select(i => new TagFilter + { + Tag = i, + Mode = TagFilterMode.Block + }) + .ToArray(); + + user.Policy.BlockedTags = null; + + await UpdateUserPolicy(user, user.Policy, false); + } + } + public UserDto GetUserDto(User user, string remoteEndPoint = null) { if (user == null) diff --git a/MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json b/MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json index 184a7f9a4e..cb99b57bbd 100644 --- a/MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json +++ b/MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json @@ -276,7 +276,7 @@ "ButtonStart": "Start", "HeaderChannels": "Channels", "HeaderMediaFolders": "Media Folders", - "HeaderBlockItemsWithNoRating": "Block items with no rating information:", + "HeaderBlockItemsWithNoRating": "Block content with no rating information:", "OptionBlockOthers": "Others", "OptionBlockTvShows": "TV Shows", "OptionBlockTrailers": "Trailers", diff --git a/MediaBrowser.Server.Implementations/Localization/Server/server.json b/MediaBrowser.Server.Implementations/Localization/Server/server.json index a75f4c83bb..e78b19c059 100644 --- a/MediaBrowser.Server.Implementations/Localization/Server/server.json +++ b/MediaBrowser.Server.Implementations/Localization/Server/server.json @@ -1356,8 +1356,10 @@ "HeaderVideoTypes": "Video Types", "HeaderYears": "Years", "HeaderAddTag": "Add Tag", - "LabelBlockItemsWithTags": "Block items with tags:", + "LabelBlockOrAllowItemsWithTags": "Block or allow content with tags:", "LabelTag": "Tag:", + "OptionBlockItemWithTag": "Block all content with this tag", + "OptionAllowItemWithTag": "Allow only content with this tag", "LabelEnableSingleImageInDidlLimit": "Limit to single embedded image", "LabelEnableSingleImageInDidlLimitHelp": "Some devices will not render properly if multiple images are embedded within Didl.", "TabActivity": "Activity", @@ -1368,5 +1370,7 @@ "NameSeasonNumber": "Season {0}", "LabelNewUserNameHelp": "Usernames can contain letters (a-z), numbers (0-9), dashes (-), underscores (_), apostrophes ('), and periods (.)", "TabJobs": "Jobs", - "TabSyncJobs": "Sync Jobs" + "TabSyncJobs": "Sync Jobs", + "LabelTagFilterMode": "Mode:", + "LabelTagFilterAllowModeHelp": "If used as part of a deeply nested folder structure, content that is tagged with this mechanism will require parent folders to be tagged as well." } diff --git a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj index bc610b7b65..19098a3eea 100644 --- a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj +++ b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj @@ -90,7 +90,7 @@ PreserveNewest - + PreserveNewest -- cgit v1.2.3 From f03f2346f387010c84159ac2d2b3b22e9cc3b5c6 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Mon, 9 Feb 2015 01:56:45 -0500 Subject: revise opt-in tags --- MediaBrowser.Controller/Channels/Channel.cs | 2 +- MediaBrowser.Controller/Entities/BaseItem.cs | 27 ++++------------------ MediaBrowser.Controller/Entities/Folder.cs | 2 +- .../MediaBrowser.Model.Portable.csproj | 6 ----- .../MediaBrowser.Model.net35.csproj | 6 ----- MediaBrowser.Model/MediaBrowser.Model.csproj | 2 -- MediaBrowser.Model/Users/TagFilter.cs | 9 -------- MediaBrowser.Model/Users/TagFilterMode.cs | 9 -------- MediaBrowser.Model/Users/UserPolicy.cs | 9 ++++---- .../Library/UserManager.cs | 22 +----------------- .../Localization/JavaScript/javascript.json | 4 +--- .../Localization/Server/server.json | 7 +++--- 12 files changed, 16 insertions(+), 89 deletions(-) delete mode 100644 MediaBrowser.Model/Users/TagFilter.cs delete mode 100644 MediaBrowser.Model/Users/TagFilterMode.cs (limited to 'MediaBrowser.Controller/Channels') diff --git a/MediaBrowser.Controller/Channels/Channel.cs b/MediaBrowser.Controller/Channels/Channel.cs index ab76f4e67f..b6514ca0a6 100644 --- a/MediaBrowser.Controller/Channels/Channel.cs +++ b/MediaBrowser.Controller/Channels/Channel.cs @@ -74,7 +74,7 @@ namespace MediaBrowser.Controller.Channels return false; } - protected override bool IsTagFilterEnforced(TagFilterMode mode) + protected override bool IsAllowTagFilterEnforced() { return false; } diff --git a/MediaBrowser.Controller/Entities/BaseItem.cs b/MediaBrowser.Controller/Entities/BaseItem.cs index 75a09a7b04..89706f9177 100644 --- a/MediaBrowser.Controller/Entities/BaseItem.cs +++ b/MediaBrowser.Controller/Entities/BaseItem.cs @@ -1080,31 +1080,14 @@ namespace MediaBrowser.Controller.Entities if (hasTags != null) { - if (user.Policy.TagFilters.Any(i => !IsTagFilterAccepted(hasTags, i))) + var policy = user.Policy; + if (policy.BlockedTags.Any(i => hasTags.Tags.Contains(i, StringComparer.OrdinalIgnoreCase))) { return false; } - } - - return true; - } - - private bool IsTagFilterAccepted(IHasTags hasTags, TagFilter filter) - { - if (IsTagFilterEnforced(filter.Mode)) - { - if (filter.Mode == TagFilterMode.Block) - { - // If content has the tag, it's not allowed - if (hasTags.Tags.Contains(filter.Tag, StringComparer.OrdinalIgnoreCase)) - { - return false; - } - } - else if (filter.Mode == TagFilterMode.Allow) + if (policy.AllowedTags.Length > 0 && IsAllowTagFilterEnforced()) { - // If content doesn't have the tag, it's not allowed - if (!hasTags.Tags.Contains(filter.Tag, StringComparer.OrdinalIgnoreCase)) + if (policy.AllowedTags.Any(i => !hasTags.Tags.Contains(i, StringComparer.OrdinalIgnoreCase))) { return false; } @@ -1114,7 +1097,7 @@ namespace MediaBrowser.Controller.Entities return true; } - protected virtual bool IsTagFilterEnforced(TagFilterMode mode) + protected virtual bool IsAllowTagFilterEnforced() { return true; } diff --git a/MediaBrowser.Controller/Entities/Folder.cs b/MediaBrowser.Controller/Entities/Folder.cs index fe9bea53b1..0d9bb03acf 100644 --- a/MediaBrowser.Controller/Entities/Folder.cs +++ b/MediaBrowser.Controller/Entities/Folder.cs @@ -80,7 +80,7 @@ namespace MediaBrowser.Controller.Entities } } - protected override bool IsTagFilterEnforced(TagFilterMode mode) + protected override bool IsAllowTagFilterEnforced() { if (this is ICollectionFolder) { diff --git a/MediaBrowser.Model.Portable/MediaBrowser.Model.Portable.csproj b/MediaBrowser.Model.Portable/MediaBrowser.Model.Portable.csproj index 561ae1e41e..ba3065bc9d 100644 --- a/MediaBrowser.Model.Portable/MediaBrowser.Model.Portable.csproj +++ b/MediaBrowser.Model.Portable/MediaBrowser.Model.Portable.csproj @@ -1181,12 +1181,6 @@ Users\PinRedeemResult.cs - - Users\TagFilter.cs - - - Users\TagFilterMode.cs - Users\UserAction.cs diff --git a/MediaBrowser.Model.net35/MediaBrowser.Model.net35.csproj b/MediaBrowser.Model.net35/MediaBrowser.Model.net35.csproj index bf5624f7a9..8d22f25a90 100644 --- a/MediaBrowser.Model.net35/MediaBrowser.Model.net35.csproj +++ b/MediaBrowser.Model.net35/MediaBrowser.Model.net35.csproj @@ -1140,12 +1140,6 @@ Users\PinRedeemResult.cs - - Users\TagFilter.cs - - - Users\TagFilterMode.cs - Users\UserAction.cs diff --git a/MediaBrowser.Model/MediaBrowser.Model.csproj b/MediaBrowser.Model/MediaBrowser.Model.csproj index 7f71c85c59..c8e09dd826 100644 --- a/MediaBrowser.Model/MediaBrowser.Model.csproj +++ b/MediaBrowser.Model/MediaBrowser.Model.csproj @@ -433,8 +433,6 @@ - - diff --git a/MediaBrowser.Model/Users/TagFilter.cs b/MediaBrowser.Model/Users/TagFilter.cs deleted file mode 100644 index 5a30c435cf..0000000000 --- a/MediaBrowser.Model/Users/TagFilter.cs +++ /dev/null @@ -1,9 +0,0 @@ - -namespace MediaBrowser.Model.Users -{ - public class TagFilter - { - public string Tag { get; set; } - public TagFilterMode Mode { get; set; } - } -} diff --git a/MediaBrowser.Model/Users/TagFilterMode.cs b/MediaBrowser.Model/Users/TagFilterMode.cs deleted file mode 100644 index bce75b41fc..0000000000 --- a/MediaBrowser.Model/Users/TagFilterMode.cs +++ /dev/null @@ -1,9 +0,0 @@ - -namespace MediaBrowser.Model.Users -{ - public enum TagFilterMode - { - Block = 0, - Allow = 1 - } -} diff --git a/MediaBrowser.Model/Users/UserPolicy.cs b/MediaBrowser.Model/Users/UserPolicy.cs index c82b887bae..3e27340d8b 100644 --- a/MediaBrowser.Model/Users/UserPolicy.cs +++ b/MediaBrowser.Model/Users/UserPolicy.cs @@ -29,6 +29,7 @@ namespace MediaBrowser.Model.Users public int? MaxParentalRating { get; set; } public string[] BlockedTags { get; set; } + public string[] AllowedTags { get; set; } public bool EnableUserPreferenceAccess { get; set; } public AccessSchedule[] AccessSchedules { get; set; } public UnratedItem[] BlockUnratedItems { get; set; } @@ -59,8 +60,6 @@ namespace MediaBrowser.Model.Users public string[] EnabledFolders { get; set; } public bool EnableAllFolders { get; set; } - public TagFilter[] TagFilters { get; set; } - public UserPolicy() { EnableLiveTvManagement = true; @@ -68,6 +67,8 @@ namespace MediaBrowser.Model.Users EnableLiveTvAccess = true; EnableSharedDeviceControl = true; + BlockedTags = new string[] { }; + AllowedTags = new string[] { }; BlockUnratedItems = new UnratedItem[] { }; EnableUserPreferenceAccess = true; @@ -84,8 +85,6 @@ namespace MediaBrowser.Model.Users EnableAllDevices = true; EnableContentDownloading = true; - - TagFilters = new TagFilter[] { }; } } -} +} \ No newline at end of file diff --git a/MediaBrowser.Server.Implementations/Library/UserManager.cs b/MediaBrowser.Server.Implementations/Library/UserManager.cs index 47903525b6..b8bc8585ef 100644 --- a/MediaBrowser.Server.Implementations/Library/UserManager.cs +++ b/MediaBrowser.Server.Implementations/Library/UserManager.cs @@ -168,7 +168,6 @@ namespace MediaBrowser.Server.Implementations.Library foreach (var user in users) { await DoPolicyMigration(user).ConfigureAwait(false); - await DoBlockedTagMigration(user).ConfigureAwait(false); } // If there are no local users with admin rights, make them all admins @@ -347,25 +346,6 @@ namespace MediaBrowser.Server.Implementations.Library } } - private async Task DoBlockedTagMigration(User user) - { - if (user.Policy.BlockedTags != null) - { - user.Policy.TagFilters = user.Policy - .BlockedTags - .Select(i => new TagFilter - { - Tag = i, - Mode = TagFilterMode.Block - }) - .ToArray(); - - user.Policy.BlockedTags = null; - - await UpdateUserPolicy(user, user.Policy, false); - } - } - public UserDto GetUserDto(User user, string remoteEndPoint = null) { if (user == null) @@ -1036,4 +1016,4 @@ namespace MediaBrowser.Server.Implementations.Library } } } -} +} \ No newline at end of file diff --git a/MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json b/MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json index b31db164a5..9d2c98c831 100644 --- a/MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json +++ b/MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json @@ -727,7 +727,5 @@ "SyncJobItemStatusSynced": "Synced", "SyncJobItemStatusFailed": "Failed", "SyncJobItemStatusRemovedFromDevice": "Removed from device", - "SyncJobItemStatusCancelled": "Cancelled", - "MessageBlockContentWithThisTag": "Block all content with this tag", - "MessageAllowContentWithThisTag": "Allow only content with this tag" + "SyncJobItemStatusCancelled": "Cancelled" } diff --git a/MediaBrowser.Server.Implementations/Localization/Server/server.json b/MediaBrowser.Server.Implementations/Localization/Server/server.json index e78b19c059..c28a61da43 100644 --- a/MediaBrowser.Server.Implementations/Localization/Server/server.json +++ b/MediaBrowser.Server.Implementations/Localization/Server/server.json @@ -1356,10 +1356,9 @@ "HeaderVideoTypes": "Video Types", "HeaderYears": "Years", "HeaderAddTag": "Add Tag", - "LabelBlockOrAllowItemsWithTags": "Block or allow content with tags:", + "LabelBlockContentWithTags": "Block content with tags:", + "LabelAllowContentWithTags": "Allow only content with tags:", "LabelTag": "Tag:", - "OptionBlockItemWithTag": "Block all content with this tag", - "OptionAllowItemWithTag": "Allow only content with this tag", "LabelEnableSingleImageInDidlLimit": "Limit to single embedded image", "LabelEnableSingleImageInDidlLimitHelp": "Some devices will not render properly if multiple images are embedded within Didl.", "TabActivity": "Activity", @@ -1372,5 +1371,5 @@ "TabJobs": "Jobs", "TabSyncJobs": "Sync Jobs", "LabelTagFilterMode": "Mode:", - "LabelTagFilterAllowModeHelp": "If used as part of a deeply nested folder structure, content that is tagged with this mechanism will require parent folders to be tagged as well." + "LabelTagFilterAllowModeHelp": "If allowed tags are used as part of a deeply nested folder structure, content that is tagged will require parent folders to be tagged as well." } -- cgit v1.2.3