diff --git a/Emby.Server.Implementations/Dto/DtoService.cs b/Emby.Server.Implementations/Dto/DtoService.cs index 9f08c6462..ef66c201c 100644 --- a/Emby.Server.Implementations/Dto/DtoService.cs +++ b/Emby.Server.Implementations/Dto/DtoService.cs @@ -116,9 +116,11 @@ namespace Emby.Server.Implementations.Dto var channelTuples = new List>(); var index = 0; + var allCollectionFolders = _libraryManager.GetUserRootFolder().Children.OfType().ToList(); + foreach (var item in items) { - var dto = GetBaseItemDtoInternal(item, options, user, owner); + var dto = GetBaseItemDtoInternal(item, options, allCollectionFolders, user, owner); var tvChannel = item as LiveTvChannel; if (tvChannel != null) @@ -173,7 +175,8 @@ namespace Emby.Server.Implementations.Dto { var syncDictionary = GetSyncedItemProgress(options); - var dto = GetBaseItemDtoInternal(item, options, user, owner); + var allCollectionFolders = _libraryManager.GetUserRootFolder().Children.OfType().ToList(); + var dto = GetBaseItemDtoInternal(item, options, allCollectionFolders, user, owner); var tvChannel = item as LiveTvChannel; if (tvChannel != null) { @@ -303,7 +306,7 @@ namespace Emby.Server.Implementations.Dto } } - private BaseItemDto GetBaseItemDtoInternal(BaseItem item, DtoOptions options, User user = null, BaseItem owner = null) + private BaseItemDto GetBaseItemDtoInternal(BaseItem item, DtoOptions options, List allCollectionFolders, User user = null, BaseItem owner = null) { var fields = options.Fields; @@ -472,7 +475,8 @@ namespace Emby.Server.Implementations.Dto public BaseItemDto GetItemByNameDto(BaseItem item, DtoOptions options, List taggedItems, Dictionary syncProgress, User user = null) { - var dto = GetBaseItemDtoInternal(item, options, user); + var allCollectionFolders = _libraryManager.GetUserRootFolder().Children.OfType().ToList(); + var dto = GetBaseItemDtoInternal(item, options, allCollectionFolders, user); if (taggedItems != null && options.Fields.Contains(ItemFields.ItemCounts)) { diff --git a/Emby.Server.Implementations/Library/UserViewManager.cs b/Emby.Server.Implementations/Library/UserViewManager.cs index ddab3caa5..dd478dee0 100644 --- a/Emby.Server.Implementations/Library/UserViewManager.cs +++ b/Emby.Server.Implementations/Library/UserViewManager.cs @@ -95,7 +95,9 @@ namespace Emby.Server.Implementations.Library if (parents.Count > 0) { - var localizationKey = viewType.Replace("Tv", string.Empty); + var localizationKey = string.Equals(viewType, CollectionType.TvShows, StringComparison.OrdinalIgnoreCase) ? + "Shows" : + "Movies"; list.Add(GetUserView(parents, viewType, localizationKey, string.Empty, user, query.PresetViews, cancellationToken)); } diff --git a/Emby.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs b/Emby.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs index 4a2836d59..5c32086ff 100644 --- a/Emby.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs +++ b/Emby.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs @@ -1526,13 +1526,13 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV private void TriggerRefresh(string path) { - _logger.Debug("Triggering refresh on {0}", path); + _logger.Info("Triggering refresh on {0}", path); var item = GetAffectedBaseItem(_fileSystem.GetDirectoryName(path)); if (item != null) { - _logger.Debug("Refreshing recording parent {0}", item.Path); + _logger.Info("Refreshing recording parent {0}", item.Path); _providerManager.QueueRefresh(item.Id, new MetadataRefreshOptions(_fileSystem) { diff --git a/Emby.Server.Implementations/Localization/Core/ru.json b/Emby.Server.Implementations/Localization/Core/ru.json index a921349a3..d9cd74273 100644 --- a/Emby.Server.Implementations/Localization/Core/ru.json +++ b/Emby.Server.Implementations/Localization/Core/ru.json @@ -54,7 +54,7 @@ "UserDeletedWithName": "\u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c {0} \u0431\u044b\u043b \u0443\u0434\u0430\u043b\u0451\u043d", "UserConfigurationUpdatedWithName": "\u041a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u044f \u043f\u043e\u043b\u044c\u0437-\u043b\u044f {0} \u0431\u044b\u043b\u0430 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0430", "MessageServerConfigurationUpdated": "\u041a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u044f \u0441\u0435\u0440\u0432\u0435\u0440\u0430 \u0431\u044b\u043b\u0430 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0430", - "MessageNamedServerConfigurationUpdatedWithValue": "\u041a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438 \u0441\u0435\u0440\u0432\u0435\u0440\u0430 (\u0440\u0430\u0437\u0434\u0435\u043b {0}) \u0431\u044b\u043b\u0430 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0430", + "MessageNamedServerConfigurationUpdatedWithValue": "\u041a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u044f \u0441\u0435\u0440\u0432\u0435\u0440\u0430 (\u0440\u0430\u0437\u0434\u0435\u043b {0}) \u0431\u044b\u043b\u0430 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0430", "MessageApplicationUpdated": "Emby Server \u0431\u044b\u043b \u043e\u0431\u043d\u043e\u0432\u043b\u0451\u043d", "FailedLoginAttemptWithUserName": "{0} - \u043f\u043e\u043f\u044b\u0442\u043a\u0430 \u0432\u0445\u043e\u0434\u0430 \u043d\u0435\u0443\u0434\u0430\u0447\u043d\u0430", "AuthenticationSucceededWithUserName": "{0} - \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u044f \u0443\u0441\u043f\u0435\u0448\u043d\u0430", diff --git a/Emby.Server.Implementations/Localization/LocalizationManager.cs b/Emby.Server.Implementations/Localization/LocalizationManager.cs index 278a39cd1..b0cee12be 100644 --- a/Emby.Server.Implementations/Localization/LocalizationManager.cs +++ b/Emby.Server.Implementations/Localization/LocalizationManager.cs @@ -387,36 +387,47 @@ namespace Emby.Server.Implementations.Localization return new LocalizatonOption[] { new LocalizatonOption{ Name="Arabic", Value="ar"}, + new LocalizatonOption{ Name="Belarusian (Belarus)", Value="be-BY"}, new LocalizatonOption{ Name="Bulgarian (Bulgaria)", Value="bg-BG"}, new LocalizatonOption{ Name="Catalan", Value="ca"}, new LocalizatonOption{ Name="Chinese Simplified", Value="zh-CN"}, new LocalizatonOption{ Name="Chinese Traditional", Value="zh-TW"}, + new LocalizatonOption{ Name="Chinese Traditional (Hong Kong)", Value="zh-HK"}, new LocalizatonOption{ Name="Croatian", Value="hr"}, new LocalizatonOption{ Name="Czech", Value="cs"}, new LocalizatonOption{ Name="Danish", Value="da"}, new LocalizatonOption{ Name="Dutch", Value="nl"}, new LocalizatonOption{ Name="English (United Kingdom)", Value="en-GB"}, - new LocalizatonOption{ Name="English (United States)", Value="en-us"}, + new LocalizatonOption{ Name="English (United States)", Value="en-US"}, new LocalizatonOption{ Name="Finnish", Value="fi"}, new LocalizatonOption{ Name="French", Value="fr"}, new LocalizatonOption{ Name="French (Canada)", Value="fr-CA"}, new LocalizatonOption{ Name="German", Value="de"}, new LocalizatonOption{ Name="Greek", Value="el"}, new LocalizatonOption{ Name="Hebrew", Value="he"}, + new LocalizatonOption{ Name="Hindi (India)", Value="hi-IN"}, new LocalizatonOption{ Name="Hungarian", Value="hu"}, new LocalizatonOption{ Name="Indonesian", Value="id"}, new LocalizatonOption{ Name="Italian", Value="it"}, + new LocalizatonOption{ Name="Japanese", Value="ja"}, new LocalizatonOption{ Name="Kazakh", Value="kk"}, + new LocalizatonOption{ Name="Korean", Value="ko"}, + new LocalizatonOption{ Name="Lithuanian", Value="lt-LT"}, + new LocalizatonOption{ Name="Malay", Value="ms"}, new LocalizatonOption{ Name="Norwegian Bokmål", Value="nb"}, new LocalizatonOption{ Name="Persian", Value="fa"}, new LocalizatonOption{ Name="Polish", Value="pl"}, new LocalizatonOption{ Name="Portuguese (Brazil)", Value="pt-BR"}, new LocalizatonOption{ Name="Portuguese (Portugal)", Value="pt-PT"}, + new LocalizatonOption{ Name="Romanian", Value="ro"}, new LocalizatonOption{ Name="Russian", Value="ru"}, + new LocalizatonOption{ Name="Slovak", Value="sk"}, new LocalizatonOption{ Name="Slovenian (Slovenia)", Value="sl-SI"}, - new LocalizatonOption{ Name="Spanish", Value="es-ES"}, + new LocalizatonOption{ Name="Spanish", Value="es"}, + new LocalizatonOption{ Name="Spanish (Latin America)", Value="es-419"}, new LocalizatonOption{ Name="Spanish (Mexico)", Value="es-MX"}, new LocalizatonOption{ Name="Swedish", Value="sv"}, + new LocalizatonOption{ Name="Swiss German", Value="gsw"}, new LocalizatonOption{ Name="Turkish", Value="tr"}, new LocalizatonOption{ Name="Ukrainian", Value="uk"}, new LocalizatonOption{ Name="Vietnamese", Value="vi"} diff --git a/Emby.Server.Implementations/Notifications/NotificationManager.cs b/Emby.Server.Implementations/Notifications/NotificationManager.cs index f49d5a1d1..5b4c43dd5 100644 --- a/Emby.Server.Implementations/Notifications/NotificationManager.cs +++ b/Emby.Server.Implementations/Notifications/NotificationManager.cs @@ -37,6 +37,11 @@ namespace Emby.Server.Implementations.Notifications } public Task SendNotification(NotificationRequest request, CancellationToken cancellationToken) + { + return SendNotification(request, null, cancellationToken); + } + + public Task SendNotification(NotificationRequest request, BaseItem relatedItem, CancellationToken cancellationToken) { var notificationType = request.NotificationType; @@ -45,7 +50,9 @@ namespace Emby.Server.Implementations.Notifications GetConfiguration().GetOptions(notificationType); var users = GetUserIds(request, options) - .Select(i => _userManager.GetUserById(i)); + .Select(i => _userManager.GetUserById(i)) + .Where(i => relatedItem == null || relatedItem.IsVisibleStandalone(i)) + .ToArray(); var title = GetTitle(request, options); var description = GetDescription(request, options); diff --git a/Emby.Server.Implementations/Notifications/Notifications.cs b/Emby.Server.Implementations/Notifications/Notifications.cs index 09c1f07e0..b7e1d6559 100644 --- a/Emby.Server.Implementations/Notifications/Notifications.cs +++ b/Emby.Server.Implementations/Notifications/Notifications.cs @@ -97,7 +97,7 @@ namespace Emby.Server.Implementations.Notifications notification.Variables["UserName"] = e.Argument.Name; - await SendNotification(notification).ConfigureAwait(false); + await SendNotification(notification, null).ConfigureAwait(false); } async void _deviceManager_CameraImageUploaded(object sender, GenericEventArgs e) @@ -111,7 +111,7 @@ namespace Emby.Server.Implementations.Notifications notification.Variables["DeviceName"] = e.Argument.Device.Name; - await SendNotification(notification).ConfigureAwait(false); + await SendNotification(notification, null).ConfigureAwait(false); } async void _appHost_ApplicationUpdated(object sender, GenericEventArgs e) @@ -127,7 +127,7 @@ namespace Emby.Server.Implementations.Notifications notification.Variables["Version"] = e.Argument.versionStr; notification.Variables["ReleaseNotes"] = e.Argument.description; - await SendNotification(notification).ConfigureAwait(false); + await SendNotification(notification, null).ConfigureAwait(false); } async void _installationManager_PluginUpdated(object sender, GenericEventArgs> e) @@ -146,7 +146,7 @@ namespace Emby.Server.Implementations.Notifications notification.Variables["Version"] = installationInfo.Version.ToString(); notification.Variables["ReleaseNotes"] = e.Argument.Item2.description; - await SendNotification(notification).ConfigureAwait(false); + await SendNotification(notification, null).ConfigureAwait(false); } async void _installationManager_PluginInstalled(object sender, GenericEventArgs e) @@ -164,7 +164,7 @@ namespace Emby.Server.Implementations.Notifications notification.Variables["Name"] = installationInfo.name; notification.Variables["Version"] = installationInfo.versionStr; - await SendNotification(notification).ConfigureAwait(false); + await SendNotification(notification, null).ConfigureAwait(false); } async void _appHost_HasUpdateAvailableChanged(object sender, EventArgs e) @@ -183,7 +183,7 @@ namespace Emby.Server.Implementations.Notifications NotificationType = type }; - await SendNotification(notification).ConfigureAwait(false); + await SendNotification(notification, null).ConfigureAwait(false); } async void _appHost_HasPendingRestartChanged(object sender, EventArgs e) @@ -200,7 +200,7 @@ namespace Emby.Server.Implementations.Notifications NotificationType = type }; - await SendNotification(notification).ConfigureAwait(false); + await SendNotification(notification, null).ConfigureAwait(false); } private NotificationOptions GetOptions() @@ -285,7 +285,7 @@ namespace Emby.Server.Implementations.Notifications notification.Variables["AppName"] = e.ClientName; notification.Variables["DeviceName"] = e.DeviceName; - await SendNotification(notification).ConfigureAwait(false); + await SendNotification(notification, null).ConfigureAwait(false); } private string GetPlaybackNotificationType(string mediaType) @@ -390,7 +390,7 @@ namespace Emby.Server.Implementations.Notifications notification.Variables["Name"] = GetItemName(item); - await SendNotification(notification).ConfigureAwait(false); + await SendNotification(notification, item).ConfigureAwait(false); } } @@ -457,7 +457,7 @@ namespace Emby.Server.Implementations.Notifications Description = "Check back here for more notifications." }; - await SendNotification(notification).ConfigureAwait(false); + await SendNotification(notification, null).ConfigureAwait(false); } async void _taskManager_TaskCompleted(object sender, TaskCompletionEventArgs e) @@ -478,7 +478,7 @@ namespace Emby.Server.Implementations.Notifications notification.Variables["Name"] = result.Name; notification.Variables["ErrorMessage"] = result.ErrorMessage; - await SendNotification(notification).ConfigureAwait(false); + await SendNotification(notification, null).ConfigureAwait(false); } } @@ -496,7 +496,7 @@ namespace Emby.Server.Implementations.Notifications notification.Variables["Name"] = plugin.Name; notification.Variables["Version"] = plugin.Version.ToString(); - await SendNotification(notification).ConfigureAwait(false); + await SendNotification(notification, null).ConfigureAwait(false); } async void _installationManager_PackageInstallationFailed(object sender, InstallationFailedEventArgs e) @@ -515,14 +515,14 @@ namespace Emby.Server.Implementations.Notifications notification.Variables["Name"] = installationInfo.Name; notification.Variables["Version"] = installationInfo.Version; - await SendNotification(notification).ConfigureAwait(false); + await SendNotification(notification, null).ConfigureAwait(false); } - private async Task SendNotification(NotificationRequest notification) + private async Task SendNotification(NotificationRequest notification, BaseItem relatedItem) { try { - await _notificationManager.SendNotification(notification, CancellationToken.None).ConfigureAwait(false); + await _notificationManager.SendNotification(notification, relatedItem, CancellationToken.None).ConfigureAwait(false); } catch (Exception ex) { diff --git a/Emby.Server.Implementations/ScheduledTasks/TaskManager.cs b/Emby.Server.Implementations/ScheduledTasks/TaskManager.cs index 5f9bf3731..c0fcb459d 100644 --- a/Emby.Server.Implementations/ScheduledTasks/TaskManager.cs +++ b/Emby.Server.Implementations/ScheduledTasks/TaskManager.cs @@ -11,6 +11,7 @@ using MediaBrowser.Model.Logging; using MediaBrowser.Model.Serialization; using MediaBrowser.Model.System; using MediaBrowser.Model.Tasks; +using System.IO; namespace Emby.Server.Implementations.ScheduledTasks { @@ -86,6 +87,57 @@ namespace Emby.Server.Implementations.ScheduledTasks } } + public void RunTaskOnNextStartup(string key) + { + var path = Path.Combine(ApplicationPaths.CachePath, "startuptasks.txt"); + + List lines; + + try + { + lines = _fileSystem.ReadAllLines(path).ToList() ; + } + catch + { + lines = new List(); + } + + if (!lines.Contains(key, StringComparer.OrdinalIgnoreCase)) + { + lines.Add(key); + _fileSystem.CreateDirectory(_fileSystem.GetDirectoryName(path)); + _fileSystem.WriteAllLines(path, lines); + } + } + + private void RunStartupTasks() + { + var path = Path.Combine(ApplicationPaths.CachePath, "startuptasks.txt"); + + List lines; + + try + { + lines = _fileSystem.ReadAllLines(path).Where(i => !string.IsNullOrWhiteSpace(i)).Distinct(StringComparer.OrdinalIgnoreCase).ToList(); + + foreach (var key in lines) + { + var task = ScheduledTasks.FirstOrDefault(i => string.Equals(i.ScheduledTask.Key, key, StringComparison.OrdinalIgnoreCase)); + + if (task != null) + { + QueueScheduledTask(task, new TaskExecutionOptions()); + } + } + + _fileSystem.DeleteFile(path); + } + catch + { + return; + } + } + /// /// Cancels if running and queue. /// @@ -235,6 +287,8 @@ namespace Emby.Server.Implementations.ScheduledTasks ScheduledTasks = myTasks.ToArray(); BindToSystemEvent(); + + RunStartupTasks(); } /// diff --git a/MediaBrowser.Controller/Entities/BaseItem.cs b/MediaBrowser.Controller/Entities/BaseItem.cs index 46c037a44..051a2cbca 100644 --- a/MediaBrowser.Controller/Entities/BaseItem.cs +++ b/MediaBrowser.Controller/Entities/BaseItem.cs @@ -477,14 +477,36 @@ namespace MediaBrowser.Controller.Entities locationType != LocationType.Virtual; } - public virtual bool IsAuthorizedToDelete(User user) + public virtual bool IsAuthorizedToDelete(User user, List allCollectionFolders) { - return user.Policy.EnableContentDeletion; + if (user.Policy.EnableContentDeletion) + { + return true; + } + + var allowed = user.Policy.EnableContentDeletionFromFolders; + var collectionFolders = LibraryManager.GetCollectionFolders(this, allCollectionFolders); + + foreach (var folder in collectionFolders) + { + if (allowed.Contains(folder.Id.ToString("N"), StringComparer.OrdinalIgnoreCase)) + { + return true; + } + } + + return false; + } + + public bool CanDelete(User user, List allCollectionFolders) + { + return CanDelete() && IsAuthorizedToDelete(user, allCollectionFolders); } public bool CanDelete(User user) { - return CanDelete() && IsAuthorizedToDelete(user); + var allCollectionFolders = LibraryManager.GetUserRootFolder().Children.OfType().ToList(); + return CanDelete(user, allCollectionFolders); } public virtual bool CanDownload() diff --git a/MediaBrowser.Controller/Entities/Movies/BoxSet.cs b/MediaBrowser.Controller/Entities/Movies/BoxSet.cs index bd8d9024d..0067515d8 100644 --- a/MediaBrowser.Controller/Entities/Movies/BoxSet.cs +++ b/MediaBrowser.Controller/Entities/Movies/BoxSet.cs @@ -126,7 +126,7 @@ namespace MediaBrowser.Controller.Entities.Movies } } - public override bool IsAuthorizedToDelete(User user) + public override bool IsAuthorizedToDelete(User user, List allCollectionFolders) { return true; } diff --git a/MediaBrowser.Controller/LiveTv/LiveTvAudioRecording.cs b/MediaBrowser.Controller/LiveTv/LiveTvAudioRecording.cs index 2dfc59d22..bd84541f8 100644 --- a/MediaBrowser.Controller/LiveTv/LiveTvAudioRecording.cs +++ b/MediaBrowser.Controller/LiveTv/LiveTvAudioRecording.cs @@ -132,7 +132,7 @@ namespace MediaBrowser.Controller.LiveTv return true; } - public override bool IsAuthorizedToDelete(User user) + public override bool IsAuthorizedToDelete(User user, List allCollectionFolders) { return user.Policy.EnableLiveTvManagement; } diff --git a/MediaBrowser.Controller/LiveTv/LiveTvVideoRecording.cs b/MediaBrowser.Controller/LiveTv/LiveTvVideoRecording.cs index 1dfed4f75..37c1faac6 100644 --- a/MediaBrowser.Controller/LiveTv/LiveTvVideoRecording.cs +++ b/MediaBrowser.Controller/LiveTv/LiveTvVideoRecording.cs @@ -131,7 +131,7 @@ namespace MediaBrowser.Controller.LiveTv return true; } - public override bool IsAuthorizedToDelete(User user) + public override bool IsAuthorizedToDelete(User user, List allCollectionFolders) { return user.Policy.EnableLiveTvManagement; } diff --git a/MediaBrowser.Controller/Notifications/INotificationManager.cs b/MediaBrowser.Controller/Notifications/INotificationManager.cs index f9d264314..68cfd6ff1 100644 --- a/MediaBrowser.Controller/Notifications/INotificationManager.cs +++ b/MediaBrowser.Controller/Notifications/INotificationManager.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; +using MediaBrowser.Controller.Entities; namespace MediaBrowser.Controller.Notifications { @@ -15,6 +16,8 @@ namespace MediaBrowser.Controller.Notifications /// Task. Task SendNotification(NotificationRequest request, CancellationToken cancellationToken); + Task SendNotification(NotificationRequest request, BaseItem relatedItem, CancellationToken cancellationToken); + /// /// Adds the parts. /// diff --git a/MediaBrowser.Controller/Playlists/Playlist.cs b/MediaBrowser.Controller/Playlists/Playlist.cs index ee96a8c3b..071f8a096 100644 --- a/MediaBrowser.Controller/Playlists/Playlist.cs +++ b/MediaBrowser.Controller/Playlists/Playlist.cs @@ -73,7 +73,7 @@ namespace MediaBrowser.Controller.Playlists return 1; } - public override bool IsAuthorizedToDelete(User user) + public override bool IsAuthorizedToDelete(User user, List allCollectionFolders) { return true; } diff --git a/MediaBrowser.Model/Tasks/ITaskManager.cs b/MediaBrowser.Model/Tasks/ITaskManager.cs index fa3da97b3..1674fc107 100644 --- a/MediaBrowser.Model/Tasks/ITaskManager.cs +++ b/MediaBrowser.Model/Tasks/ITaskManager.cs @@ -74,5 +74,7 @@ namespace MediaBrowser.Model.Tasks event EventHandler> TaskExecuting; event EventHandler TaskCompleted; + + void RunTaskOnNextStartup(string key); } } \ No newline at end of file diff --git a/MediaBrowser.Model/Users/UserPolicy.cs b/MediaBrowser.Model/Users/UserPolicy.cs index 84ee5d637..de2e9cc04 100644 --- a/MediaBrowser.Model/Users/UserPolicy.cs +++ b/MediaBrowser.Model/Users/UserPolicy.cs @@ -44,6 +44,7 @@ namespace MediaBrowser.Model.Users public bool EnablePlaybackRemuxing { get; set; } public bool EnableContentDeletion { get; set; } + public string[] EnableContentDeletionFromFolders { get; set; } public bool EnableContentDownloading { get; set; } /// @@ -73,6 +74,7 @@ namespace MediaBrowser.Model.Users public UserPolicy() { EnableContentDeletion = true; + EnableContentDeletionFromFolders = new string[] { }; EnableSyncTranscoding = true; diff --git a/SharedVersion.cs b/SharedVersion.cs index 1db2b31b5..e92f1a55e 100644 --- a/SharedVersion.cs +++ b/SharedVersion.cs @@ -1,3 +1,3 @@ using System.Reflection; -[assembly: AssemblyVersion("3.2.33.9")] +[assembly: AssemblyVersion("3.2.33.10")]