diff --git a/MediaBrowser.Api/Library/LibraryStructureService.cs b/MediaBrowser.Api/Library/LibraryStructureService.cs index ac2a109244..68ef58a9d0 100644 --- a/MediaBrowser.Api/Library/LibraryStructureService.cs +++ b/MediaBrowser.Api/Library/LibraryStructureService.cs @@ -1,4 +1,5 @@ -using MediaBrowser.Controller; +using System.Threading.Tasks; +using MediaBrowser.Controller; using MediaBrowser.Controller.IO; using MediaBrowser.Controller.Library; using MediaBrowser.Model.Entities; @@ -45,6 +46,12 @@ namespace MediaBrowser.Api.Library /// /// The type of the collection. public string CollectionType { get; set; } + + /// + /// Gets or sets a value indicating whether [refresh library]. + /// + /// true if [refresh library]; otherwise, false. + public bool RefreshLibrary { get; set; } } [Route("/Library/VirtualFolders/{Name}", "DELETE")] @@ -62,6 +69,12 @@ namespace MediaBrowser.Api.Library /// /// The name. public string Name { get; set; } + + /// + /// Gets or sets a value indicating whether [refresh library]. + /// + /// true if [refresh library]; otherwise, false. + public bool RefreshLibrary { get; set; } } [Route("/Library/VirtualFolders/{Name}/Name", "POST")] @@ -85,6 +98,12 @@ namespace MediaBrowser.Api.Library /// /// The name. public string NewName { get; set; } + + /// + /// Gets or sets a value indicating whether [refresh library]. + /// + /// true if [refresh library]; otherwise, false. + public bool RefreshLibrary { get; set; } } [Route("/Library/VirtualFolders/{Name}/Paths", "POST")] @@ -108,6 +127,12 @@ namespace MediaBrowser.Api.Library /// /// The name. public string Path { get; set; } + + /// + /// Gets or sets a value indicating whether [refresh library]. + /// + /// true if [refresh library]; otherwise, false. + public bool RefreshLibrary { get; set; } } [Route("/Library/VirtualFolders/{Name}/Paths", "DELETE")] @@ -131,6 +156,12 @@ namespace MediaBrowser.Api.Library /// /// The name. public string Path { get; set; } + + /// + /// Gets or sets a value indicating whether [refresh library]. + /// + /// true if [refresh library]; otherwise, false. + public bool RefreshLibrary { get; set; } } /// @@ -202,7 +233,7 @@ namespace MediaBrowser.Api.Library /// Posts the specified request. /// /// The request. - public void Post(AddVirtualFolder request) + public async void Post(AddVirtualFolder request) { _directoryWatchers.Stop(); @@ -218,20 +249,26 @@ namespace MediaBrowser.Api.Library LibraryHelpers.AddVirtualFolder(request.Name, request.CollectionType, user, _appPaths); } + + // Need to add a delay here or directory watchers may still pick up the changes + await Task.Delay(1000).ConfigureAwait(false); } finally { _directoryWatchers.Start(); } - _libraryManager.ValidateMediaLibrary(new Progress(), CancellationToken.None); + if (request.RefreshLibrary) + { + _libraryManager.ValidateMediaLibrary(new Progress(), CancellationToken.None); + } } /// /// Posts the specified request. /// /// The request. - public void Post(RenameVirtualFolder request) + public async void Post(RenameVirtualFolder request) { _directoryWatchers.Stop(); @@ -247,20 +284,26 @@ namespace MediaBrowser.Api.Library LibraryHelpers.RenameVirtualFolder(request.Name, request.NewName, user, _appPaths); } + + // Need to add a delay here or directory watchers may still pick up the changes + await Task.Delay(1000).ConfigureAwait(false); } finally { _directoryWatchers.Start(); } - _libraryManager.ValidateMediaLibrary(new Progress(), CancellationToken.None); + if (request.RefreshLibrary) + { + _libraryManager.ValidateMediaLibrary(new Progress(), CancellationToken.None); + } } /// /// Deletes the specified request. /// /// The request. - public void Delete(RemoveVirtualFolder request) + public async void Delete(RemoveVirtualFolder request) { _directoryWatchers.Stop(); @@ -276,20 +319,26 @@ namespace MediaBrowser.Api.Library LibraryHelpers.RemoveVirtualFolder(request.Name, user, _appPaths); } + + // Need to add a delay here or directory watchers may still pick up the changes + await Task.Delay(1000).ConfigureAwait(false); } finally { _directoryWatchers.Start(); } - _libraryManager.ValidateMediaLibrary(new Progress(), CancellationToken.None); + if (request.RefreshLibrary) + { + _libraryManager.ValidateMediaLibrary(new Progress(), CancellationToken.None); + } } /// /// Posts the specified request. /// /// The request. - public void Post(AddMediaPath request) + public async void Post(AddMediaPath request) { _directoryWatchers.Stop(); @@ -305,20 +354,26 @@ namespace MediaBrowser.Api.Library LibraryHelpers.AddMediaPath(request.Name, request.Path, user, _appPaths); } + + // Need to add a delay here or directory watchers may still pick up the changes + await Task.Delay(1000).ConfigureAwait(false); } finally { _directoryWatchers.Start(); } - _libraryManager.ValidateMediaLibrary(new Progress(), CancellationToken.None); + if (request.RefreshLibrary) + { + _libraryManager.ValidateMediaLibrary(new Progress(), CancellationToken.None); + } } /// /// Deletes the specified request. /// /// The request. - public void Delete(RemoveMediaPath request) + public async void Delete(RemoveMediaPath request) { _directoryWatchers.Stop(); @@ -334,13 +389,19 @@ namespace MediaBrowser.Api.Library LibraryHelpers.RemoveMediaPath(request.Name, request.Path, user, _appPaths); } + + // Need to add a delay here or directory watchers may still pick up the changes + await Task.Delay(1000).ConfigureAwait(false); } finally { _directoryWatchers.Start(); } - _libraryManager.ValidateMediaLibrary(new Progress(), CancellationToken.None); + if (request.RefreshLibrary) + { + _libraryManager.ValidateMediaLibrary(new Progress(), CancellationToken.None); + } } } } diff --git a/MediaBrowser.Server.Implementations/ScheduledTasks/ChapterImagesTask.cs b/MediaBrowser.Server.Implementations/ScheduledTasks/ChapterImagesTask.cs index c579996d2b..d9b88368b3 100644 --- a/MediaBrowser.Server.Implementations/ScheduledTasks/ChapterImagesTask.cs +++ b/MediaBrowser.Server.Implementations/ScheduledTasks/ChapterImagesTask.cs @@ -123,6 +123,8 @@ namespace MediaBrowser.Server.Implementations.ScheduledTasks /// IEnumerable{BaseTaskTrigger}. public IEnumerable GetDefaultTriggers() { + // IMPORTANT: Make sure to update the dashboard "wizardsettings" page if this default ever changes + return new ITaskTrigger[] { new DailyTrigger { TimeOfDay = TimeSpan.FromHours(4) } @@ -198,7 +200,11 @@ namespace MediaBrowser.Server.Implementations.ScheduledTasks /// The name. public string Name { - get { return "Chapter image extraction"; } + get + { + // IMPORTANT: Make sure to update the dashboard "wizardsettings" page if this name ever changes + return "Chapter image extraction"; + } } /// diff --git a/MediaBrowser.WebDashboard/Api/DashboardService.cs b/MediaBrowser.WebDashboard/Api/DashboardService.cs index df66d972ea..cea1776610 100644 --- a/MediaBrowser.WebDashboard/Api/DashboardService.cs +++ b/MediaBrowser.WebDashboard/Api/DashboardService.cs @@ -509,6 +509,7 @@ namespace MediaBrowser.WebDashboard.Api "userprofilespage.js", "wizardfinishpage.js", "wizardstartpage.js", + "wizardsettings.js", "wizarduserpage.js" }; diff --git a/MediaBrowser.WebDashboard/ApiClient.js b/MediaBrowser.WebDashboard/ApiClient.js index 29bfb1068f..e9679c3f04 100644 --- a/MediaBrowser.WebDashboard/ApiClient.js +++ b/MediaBrowser.WebDashboard/ApiClient.js @@ -910,7 +910,7 @@ MediaBrowser.ApiClient = function ($, navigator, JSON, WebSocket, setTimeout) { * Removes a virtual folder from either the default view or a user view * @param {String} name */ - self.removeVirtualFolder = function (name, userId) { + self.removeVirtualFolder = function (name, userId, refreshLibrary) { if (!name) { throw new Error("null name"); @@ -919,7 +919,10 @@ MediaBrowser.ApiClient = function ($, navigator, JSON, WebSocket, setTimeout) { var url = userId ? "Users/" + userId + "/VirtualFolders" : "Library/VirtualFolders"; url += "/" + name; - url = self.getUrl(url); + + url = self.getUrl(url, { + refreshLibrary: refreshLibrary ? true : false + }); return self.ajax({ type: "DELETE", @@ -931,7 +934,7 @@ MediaBrowser.ApiClient = function ($, navigator, JSON, WebSocket, setTimeout) { * Adds a virtual folder to either the default view or a user view * @param {String} name */ - self.addVirtualFolder = function (name, type, userId) { + self.addVirtualFolder = function (name, type, userId, refreshLibrary) { if (!name) { throw new Error("null name"); @@ -943,6 +946,8 @@ MediaBrowser.ApiClient = function ($, navigator, JSON, WebSocket, setTimeout) { options.collectionType = type; } + options.refreshLibrary = refreshLibrary ? true : false; + var url = userId ? "Users/" + userId + "/VirtualFolders" : "Library/VirtualFolders"; url += "/" + name; @@ -958,7 +963,7 @@ MediaBrowser.ApiClient = function ($, navigator, JSON, WebSocket, setTimeout) { * Renames a virtual folder, within either the default view or a user view * @param {String} name */ - self.renameVirtualFolder = function (name, newName, userId) { + self.renameVirtualFolder = function (name, newName, userId, refreshLibrary) { if (!name) { throw new Error("null name"); @@ -968,7 +973,10 @@ MediaBrowser.ApiClient = function ($, navigator, JSON, WebSocket, setTimeout) { url += "/" + name + "/Name"; - url = self.getUrl(url, { newName: newName }); + url = self.getUrl(url, { + refreshLibrary: refreshLibrary ? true : false, + newName: newName + }); return self.ajax({ type: "POST", @@ -980,7 +988,7 @@ MediaBrowser.ApiClient = function ($, navigator, JSON, WebSocket, setTimeout) { * Adds an additional mediaPath to an existing virtual folder, within either the default view or a user view * @param {String} name */ - self.addMediaPath = function (virtualFolderName, mediaPath, userId) { + self.addMediaPath = function (virtualFolderName, mediaPath, userId, refreshLibrary) { if (!virtualFolderName) { throw new Error("null virtualFolderName"); @@ -994,7 +1002,11 @@ MediaBrowser.ApiClient = function ($, navigator, JSON, WebSocket, setTimeout) { url += "/" + virtualFolderName + "/Paths"; - url = self.getUrl(url, { path: mediaPath }); + url = self.getUrl(url, { + + refreshLibrary: refreshLibrary ? true : false, + path: mediaPath + }); return self.ajax({ type: "POST", @@ -1006,7 +1018,7 @@ MediaBrowser.ApiClient = function ($, navigator, JSON, WebSocket, setTimeout) { * Removes a media path from a virtual folder, within either the default view or a user view * @param {String} name */ - self.removeMediaPath = function (virtualFolderName, mediaPath, userId) { + self.removeMediaPath = function (virtualFolderName, mediaPath, userId, refreshLibrary) { if (!virtualFolderName) { throw new Error("null virtualFolderName"); @@ -1020,7 +1032,11 @@ MediaBrowser.ApiClient = function ($, navigator, JSON, WebSocket, setTimeout) { url += "/" + virtualFolderName + "/Paths"; - url = self.getUrl(url, { path: mediaPath }); + url = self.getUrl(url, { + + refreshLibrary: refreshLibrary ? true : false, + path: mediaPath + }); return self.ajax({ type: "DELETE", diff --git a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj index 96c5deee17..b815ef617a 100644 --- a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj +++ b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj @@ -318,6 +318,12 @@ PreserveNewest + + PreserveNewest + + + PreserveNewest + PreserveNewest diff --git a/MediaBrowser.WebDashboard/packages.config b/MediaBrowser.WebDashboard/packages.config index 49180aa52e..2e19e0a123 100644 --- a/MediaBrowser.WebDashboard/packages.config +++ b/MediaBrowser.WebDashboard/packages.config @@ -1,6 +1,6 @@  - + \ No newline at end of file