From f8b76758e67acc1dec673a03589e847fa561919b Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Fri, 19 Aug 2016 18:56:32 -0400 Subject: remove fingerprintjs --- .../MediaBrowser.Server.Implementations.csproj | 1 + .../Sync/SyncNotificationEntryPoint.cs | 48 ++++++++++++++++++++++ 2 files changed, 49 insertions(+) create mode 100644 MediaBrowser.Server.Implementations/Sync/SyncNotificationEntryPoint.cs (limited to 'MediaBrowser.Server.Implementations') diff --git a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj index 7fa9ee32c2..b4fd7b279f 100644 --- a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj +++ b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj @@ -271,6 +271,7 @@ + diff --git a/MediaBrowser.Server.Implementations/Sync/SyncNotificationEntryPoint.cs b/MediaBrowser.Server.Implementations/Sync/SyncNotificationEntryPoint.cs new file mode 100644 index 0000000000..7017b422ee --- /dev/null +++ b/MediaBrowser.Server.Implementations/Sync/SyncNotificationEntryPoint.cs @@ -0,0 +1,48 @@ +using System.Threading; +using MediaBrowser.Controller.Plugins; +using MediaBrowser.Controller.Session; +using MediaBrowser.Controller.Sync; +using MediaBrowser.Model.Events; +using MediaBrowser.Model.Sync; + +namespace MediaBrowser.Server.Implementations.Sync +{ + public class SyncNotificationEntryPoint : IServerEntryPoint + { + private readonly ISessionManager _sessionManager; + private readonly ISyncManager _syncManager; + + public SyncNotificationEntryPoint(ISyncManager syncManager, ISessionManager sessionManager) + { + _syncManager = syncManager; + _sessionManager = sessionManager; + } + + public void Run() + { + _syncManager.SyncJobItemUpdated += _syncManager_SyncJobItemUpdated; + } + + private async void _syncManager_SyncJobItemUpdated(object sender, GenericEventArgs e) + { + var item = e.Argument; + + if (item.Status == SyncJobItemStatus.ReadyToTransfer) + { + try + { + await _sessionManager.SendMessageToUserDeviceSessions(item.TargetId, "SyncJobItemReady", item, CancellationToken.None).ConfigureAwait(false); + } + catch + { + + } + } + } + + public void Dispose() + { + _syncManager.SyncJobItemUpdated -= _syncManager_SyncJobItemUpdated; + } + } +} -- cgit v1.2.3 From 751febc1de65c9f2811deca66d093503968dd514 Mon Sep 17 00:00:00 2001 From: softworkz Date: Fri, 19 Aug 2016 03:00:04 +0200 Subject: Auto-Organize: Async operation and instant feedback UI (reworked) This commit includes changes to enable and stabilize asyncronous operation in the auto-organize area. Here are the key points: - The auto-organize correction dialog is now closed (almost) instantly. This means that the user does not have to wait until the file copy/move operation is completed in order to continue. (even with local HDs the copy/move process can take several minutes or even much longer with network destination). - This commit also implements locking of files to be organized in order to prevent parallel processing of the same item. In effect, there can be 2 or more manual organization operations active even while the normal auto-organization task is running without causing any problems - The items that are currently being processed are indicated as such in the log with an orange color and a spinner graphic - The client display is refreshed through websocket messages - A side effect of this is that other clients showing the auto-organize log at the same time are always up-to-date as well --- .../Library/FileOrganizationService.cs | 14 +-- .../FileOrganization/IFileOrganizationService.cs | 24 ++++- MediaBrowser.Controller/Session/ISessionManager.cs | 10 +++ .../FileOrganization/FileOrganizationResult.cs | 6 ++ .../FileOrganization/EpisodeFileOrganizer.cs | 16 ++++ .../FileOrganization/FileOrganizationNotifier.cs | 68 ++++++++++++++ .../FileOrganization/FileOrganizationService.cs | 100 +++++++++++++++++++-- .../MediaBrowser.Server.Implementations.csproj | 1 + .../Session/SessionManager.cs | 21 +++++ .../MediaBrowser.WebDashboard.csproj | 3 + MediaBrowser.sln | 5 +- 11 files changed, 251 insertions(+), 17 deletions(-) create mode 100644 MediaBrowser.Server.Implementations/FileOrganization/FileOrganizationNotifier.cs (limited to 'MediaBrowser.Server.Implementations') diff --git a/MediaBrowser.Api/Library/FileOrganizationService.cs b/MediaBrowser.Api/Library/FileOrganizationService.cs index 0ed08a8607..ca391bef08 100644 --- a/MediaBrowser.Api/Library/FileOrganizationService.cs +++ b/MediaBrowser.Api/Library/FileOrganizationService.cs @@ -154,9 +154,12 @@ namespace MediaBrowser.Api.Library public void Post(PerformOrganization request) { + // Don't await this var task = _iFileOrganizationService.PerformOrganization(request.Id); - Task.WaitAll(task); + // Async processing (close dialog early instead of waiting until the file has been copied) + // Wait 2s for exceptions that may occur to have them forwarded to the client for immediate error display + task.Wait(2000); } public void Post(OrganizeEpisode request) @@ -168,6 +171,7 @@ namespace MediaBrowser.Api.Library dicNewProviderIds = request.NewSeriesProviderIds; } + // Don't await this var task = _iFileOrganizationService.PerformEpisodeOrganization(new EpisodeFileOrganizationRequest { EndingEpisodeNumber = request.EndingEpisodeNumber, @@ -182,11 +186,9 @@ namespace MediaBrowser.Api.Library TargetFolder = request.TargetFolder }); - // For async processing (close dialog early instead of waiting until the file has been copied) - //var tasks = new Task[] { task }; - //Task.WaitAll(tasks, 8000); - - Task.WaitAll(task); + // Async processing (close dialog early instead of waiting until the file has been copied) + // Wait 2s for exceptions that may occur to have them forwarded to the client for immediate error display + task.Wait(2000); } public object Get(GetSmartMatchInfos request) diff --git a/MediaBrowser.Controller/FileOrganization/IFileOrganizationService.cs b/MediaBrowser.Controller/FileOrganization/IFileOrganizationService.cs index daa670d836..9a5b96a241 100644 --- a/MediaBrowser.Controller/FileOrganization/IFileOrganizationService.cs +++ b/MediaBrowser.Controller/FileOrganization/IFileOrganizationService.cs @@ -1,5 +1,7 @@ -using MediaBrowser.Model.FileOrganization; +using MediaBrowser.Model.Events; +using MediaBrowser.Model.FileOrganization; using MediaBrowser.Model.Querying; +using System; using System.Threading; using System.Threading.Tasks; @@ -7,6 +9,11 @@ namespace MediaBrowser.Controller.FileOrganization { public interface IFileOrganizationService { + event EventHandler> ItemAdded; + event EventHandler> ItemUpdated; + event EventHandler> ItemRemoved; + event EventHandler LogReset; + /// /// Processes the new files. /// @@ -81,5 +88,20 @@ namespace MediaBrowser.Controller.FileOrganization /// Item name. /// The match string to delete. void DeleteSmartMatchEntry(string ItemName, string matchString); + + /// + /// Attempts to add a an item to the list of currently processed items. + /// + /// The result item. + /// Passing true will notify the client to reload all items, otherwise only a single item will be refreshed. + /// True if the item was added, False if the item is already contained in the list. + bool AddToInProgressList(FileOrganizationResult result, bool fullClientRefresh); + + /// + /// Removes an item from the list of currently processed items. + /// + /// The result item. + /// True if the item was removed, False if the item was not contained in the list. + bool RemoveFromInprogressList(FileOrganizationResult result); } } diff --git a/MediaBrowser.Controller/Session/ISessionManager.cs b/MediaBrowser.Controller/Session/ISessionManager.cs index 6659d15530..e63fc60e1a 100644 --- a/MediaBrowser.Controller/Session/ISessionManager.cs +++ b/MediaBrowser.Controller/Session/ISessionManager.cs @@ -171,6 +171,16 @@ namespace MediaBrowser.Controller.Session /// Task. Task SendPlaystateCommand(string controllingSessionId, string sessionId, PlaystateRequest command, CancellationToken cancellationToken); + /// + /// Sends the message to admin sessions. + /// + /// + /// The name. + /// The data. + /// The cancellation token. + /// Task. + Task SendMessageToAdminSessions(string name, T data, CancellationToken cancellationToken); + /// /// Sends the message to user sessions. /// diff --git a/MediaBrowser.Model/FileOrganization/FileOrganizationResult.cs b/MediaBrowser.Model/FileOrganization/FileOrganizationResult.cs index ef9d0ca2ae..caf99183dc 100644 --- a/MediaBrowser.Model/FileOrganization/FileOrganizationResult.cs +++ b/MediaBrowser.Model/FileOrganization/FileOrganizationResult.cs @@ -95,6 +95,12 @@ namespace MediaBrowser.Model.FileOrganization /// The size of the file. public long FileSize { get; set; } + /// + /// Indicates if the item is currently being processed. + /// + /// Runtime property not persisted to the store. + public bool IsInProgress { get; set; } + public FileOrganizationResult() { DuplicatePaths = new List(); diff --git a/MediaBrowser.Server.Implementations/FileOrganization/EpisodeFileOrganizer.cs b/MediaBrowser.Server.Implementations/FileOrganization/EpisodeFileOrganizer.cs index 39992b65dd..5e01666a9a 100644 --- a/MediaBrowser.Server.Implementations/FileOrganization/EpisodeFileOrganizer.cs +++ b/MediaBrowser.Server.Implementations/FileOrganization/EpisodeFileOrganizer.cs @@ -272,6 +272,18 @@ namespace MediaBrowser.Server.Implementations.FileOrganization var originalExtractedSeriesString = result.ExtractedName; + bool isNew = string.IsNullOrWhiteSpace(result.Id); + + if (isNew) + { + await _organizationService.SaveResult(result, cancellationToken); + } + + if (!_organizationService.AddToInProgressList(result, isNew)) + { + throw new Exception("File is currently processed otherwise. Please try again later."); + } + try { // Proceed to sort the file @@ -363,6 +375,10 @@ namespace MediaBrowser.Server.Implementations.FileOrganization _logger.Warn(ex.Message); return; } + finally + { + _organizationService.RemoveFromInprogressList(result); + } if (rememberCorrection) { diff --git a/MediaBrowser.Server.Implementations/FileOrganization/FileOrganizationNotifier.cs b/MediaBrowser.Server.Implementations/FileOrganization/FileOrganizationNotifier.cs new file mode 100644 index 0000000000..38b90647c1 --- /dev/null +++ b/MediaBrowser.Server.Implementations/FileOrganization/FileOrganizationNotifier.cs @@ -0,0 +1,68 @@ +using MediaBrowser.Controller.FileOrganization; +using MediaBrowser.Controller.Plugins; +using MediaBrowser.Model.Logging; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using MediaBrowser.Model.Events; +using MediaBrowser.Model.FileOrganization; +using MediaBrowser.Controller.Session; +using System.Threading; + +namespace MediaBrowser.Server.Implementations.FileOrganization +{ + /// + /// Class SessionInfoWebSocketListener + /// + class FileOrganizationNotifier : IServerEntryPoint + { + private readonly IFileOrganizationService _organizationService; + private readonly ISessionManager _sessionManager; + + public FileOrganizationNotifier(ILogger logger, IFileOrganizationService organizationService, ISessionManager sessionManager) + { + _organizationService = organizationService; + _sessionManager = sessionManager; + } + + public void Run() + { + _organizationService.ItemAdded += _organizationService_ItemAdded; + _organizationService.ItemRemoved += _organizationService_ItemRemoved; + _organizationService.ItemUpdated += _organizationService_ItemUpdated; + _organizationService.LogReset += _organizationService_LogReset; + } + + private void _organizationService_LogReset(object sender, EventArgs e) + { + _sessionManager.SendMessageToAdminSessions("AutoOrganizeUpdate", (FileOrganizationResult)null, CancellationToken.None); + } + + private void _organizationService_ItemUpdated(object sender, GenericEventArgs e) + { + _sessionManager.SendMessageToAdminSessions("AutoOrganizeUpdate", e.Argument, CancellationToken.None); + } + + private void _organizationService_ItemRemoved(object sender, GenericEventArgs e) + { + _sessionManager.SendMessageToAdminSessions("AutoOrganizeUpdate", (FileOrganizationResult)null, CancellationToken.None); + } + + private void _organizationService_ItemAdded(object sender, GenericEventArgs e) + { + _sessionManager.SendMessageToAdminSessions("AutoOrganizeUpdate", (FileOrganizationResult)null, CancellationToken.None); + } + + public void Dispose() + { + _organizationService.ItemAdded -= _organizationService_ItemAdded; + _organizationService.ItemRemoved -= _organizationService_ItemRemoved; + _organizationService.ItemUpdated -= _organizationService_ItemUpdated; + _organizationService.LogReset -= _organizationService_LogReset; + } + + + } +} diff --git a/MediaBrowser.Server.Implementations/FileOrganization/FileOrganizationService.cs b/MediaBrowser.Server.Implementations/FileOrganization/FileOrganizationService.cs index 9e16613e62..a42eba6cae 100644 --- a/MediaBrowser.Server.Implementations/FileOrganization/FileOrganizationService.cs +++ b/MediaBrowser.Server.Implementations/FileOrganization/FileOrganizationService.cs @@ -3,16 +3,21 @@ using MediaBrowser.Common.ScheduledTasks; using MediaBrowser.Controller.Configuration; using MediaBrowser.Controller.FileOrganization; using MediaBrowser.Controller.Library; +using MediaBrowser.Controller.Net; using MediaBrowser.Controller.Persistence; using MediaBrowser.Controller.Providers; using MediaBrowser.Model.FileOrganization; using MediaBrowser.Model.Logging; using MediaBrowser.Model.Querying; using System; +using System.Collections.Concurrent; using System.Linq; using System.Threading; using System.Threading.Tasks; using CommonIO; +using MediaBrowser.Controller.Session; +using MediaBrowser.Model.Events; +using MediaBrowser.Common.Events; namespace MediaBrowser.Server.Implementations.FileOrganization { @@ -26,6 +31,12 @@ namespace MediaBrowser.Server.Implementations.FileOrganization private readonly IServerConfigurationManager _config; private readonly IFileSystem _fileSystem; private readonly IProviderManager _providerManager; + private readonly ConcurrentDictionary _inProgressItemIds = new ConcurrentDictionary(); + + public event EventHandler> ItemAdded; + public event EventHandler> ItemUpdated; + public event EventHandler> ItemRemoved; + public event EventHandler LogReset; public FileOrganizationService(ITaskManager taskManager, IFileOrganizationRepository repo, ILogger logger, ILibraryMonitor libraryMonitor, ILibraryManager libraryManager, IServerConfigurationManager config, IFileSystem fileSystem, IProviderManager providerManager) { @@ -58,12 +69,26 @@ namespace MediaBrowser.Server.Implementations.FileOrganization public QueryResult GetResults(FileOrganizationResultQuery query) { - return _repo.GetResults(query); + var results = _repo.GetResults(query); + + foreach (var result in results.Items) + { + result.IsInProgress = _inProgressItemIds.ContainsKey(result.Id); + } + + return results; } public FileOrganizationResult GetResult(string id) { - return _repo.GetResult(id); + var result = _repo.GetResult(id); + + if (result != null) + { + result.IsInProgress = _inProgressItemIds.ContainsKey(result.Id); + } + + return result; } public FileOrganizationResult GetResultBySourcePath(string path) @@ -78,11 +103,17 @@ namespace MediaBrowser.Server.Implementations.FileOrganization return GetResult(id); } - public Task DeleteOriginalFile(string resultId) + public async Task DeleteOriginalFile(string resultId) { var result = _repo.GetResult(resultId); _logger.Info("Requested to delete {0}", result.OriginalPath); + + if (!AddToInProgressList(result, false)) + { + throw new Exception("Path is currently processed otherwise. Please try again later."); + } + try { _fileSystem.DeleteFile(result.OriginalPath); @@ -91,8 +122,14 @@ namespace MediaBrowser.Server.Implementations.FileOrganization { _logger.ErrorException("Error deleting {0}", ex, result.OriginalPath); } + finally + { + RemoveFromInprogressList(result); + } - return _repo.Delete(resultId); + await _repo.Delete(resultId); + + EventHelper.FireEventIfNotNull(ItemRemoved, this, new GenericEventArgs(result), _logger); } private AutoOrganizeOptions GetAutoOrganizeOptions() @@ -121,9 +158,10 @@ namespace MediaBrowser.Server.Implementations.FileOrganization } } - public Task ClearLog() + public async Task ClearLog() { - return _repo.DeleteAll(); + await _repo.DeleteAll(); + EventHelper.FireEventIfNotNull(LogReset, this, EventArgs.Empty, _logger); } public async Task PerformEpisodeOrganization(EpisodeFileOrganizationRequest request) @@ -189,5 +227,55 @@ namespace MediaBrowser.Server.Implementations.FileOrganization _config.SaveAutoOrganizeOptions(options); } } + + /// + /// Attempts to add a an item to the list of currently processed items. + /// + /// The result item. + /// Passing true will notify the client to reload all items, otherwise only a single item will be refreshed. + /// True if the item was added, False if the item is already contained in the list. + public bool AddToInProgressList(FileOrganizationResult result, bool isNewItem) + { + if (string.IsNullOrWhiteSpace(result.Id)) + { + result.Id = result.OriginalPath.GetMD5().ToString("N"); + } + + if (!_inProgressItemIds.TryAdd(result.Id, false)) + { + return false; + } + + result.IsInProgress = true; + + if (isNewItem) + { + EventHelper.FireEventIfNotNull(ItemAdded, this, new GenericEventArgs(result), _logger); + } + else + { + EventHelper.FireEventIfNotNull(ItemUpdated, this, new GenericEventArgs(result), _logger); + } + + return true; + } + + /// + /// Removes an item from the list of currently processed items. + /// + /// The result item. + /// True if the item was removed, False if the item was not contained in the list. + public bool RemoveFromInprogressList(FileOrganizationResult result) + { + bool itemValue; + var retval = _inProgressItemIds.TryRemove(result.Id, out itemValue); + + result.IsInProgress = false; + + EventHelper.FireEventIfNotNull(ItemUpdated, this, new GenericEventArgs(result), _logger); + + return retval; + } + } } diff --git a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj index 7fa9ee32c2..72324b061c 100644 --- a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj +++ b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj @@ -149,6 +149,7 @@ + diff --git a/MediaBrowser.Server.Implementations/Session/SessionManager.cs b/MediaBrowser.Server.Implementations/Session/SessionManager.cs index f495e557a3..9d07f2169e 100644 --- a/MediaBrowser.Server.Implementations/Session/SessionManager.cs +++ b/MediaBrowser.Server.Implementations/Session/SessionManager.cs @@ -1869,6 +1869,27 @@ namespace MediaBrowser.Server.Implementations.Session return GetSessionByAuthenticationToken(info, deviceId, remoteEndpoint, null); } + public Task SendMessageToAdminSessions(string name, T data, CancellationToken cancellationToken) + { + // TODO: How to identify admin sessions? + var sessions = Sessions.Where(i => i.IsActive && i.SessionController != null).ToList(); + + var tasks = sessions.Select(session => Task.Run(async () => + { + try + { + await session.SessionController.SendMessage(name, data, cancellationToken).ConfigureAwait(false); + } + catch (Exception ex) + { + _logger.ErrorException("Error sending message", ex); + } + + }, cancellationToken)); + + return Task.WhenAll(tasks); + } + public Task SendMessageToUserSessions(string userId, string name, T data, CancellationToken cancellationToken) { diff --git a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj index 61facf8ec4..706b78a8f3 100644 --- a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj +++ b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj @@ -182,6 +182,9 @@ PreserveNewest + + PreserveNewest + PreserveNewest diff --git a/MediaBrowser.sln b/MediaBrowser.sln index c6068f5364..90b318492f 100644 --- a/MediaBrowser.sln +++ b/MediaBrowser.sln @@ -1,7 +1,7 @@  Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 14 -VisualStudioVersion = 14.0.24720.0 +VisualStudioVersion = 14.0.25420.1 MinimumVisualStudioVersion = 10.0.40219.1 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".nuget", ".nuget", "{F0E0E64C-2A6F-4E35-9533-D53AC07C2CD1}" EndProject @@ -65,9 +65,6 @@ EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Emby.Drawing", "Emby.Drawing\Emby.Drawing.csproj", "{08FFF49B-F175-4807-A2B5-73B0EBD9F716}" EndProject Global - GlobalSection(Performance) = preSolution - HasPerformanceSessions = true - EndGlobalSection GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU Debug|Mixed Platforms = Debug|Mixed Platforms -- cgit v1.2.3 From acd60f1d85f88e19b114ba0cc59af3fb98589064 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sat, 20 Aug 2016 14:43:13 -0400 Subject: update admin session filter --- MediaBrowser.Controller/Session/ISessionManager.cs | 6 +----- .../EntryPoints/RecordingNotifier.cs | 17 +++++++---------- .../EntryPoints/ServerEventNotifier.cs | 3 ++- .../Session/SessionManager.cs | 22 ++++------------------ MediaBrowser.sln | 5 ++++- 5 files changed, 18 insertions(+), 35 deletions(-) (limited to 'MediaBrowser.Server.Implementations') diff --git a/MediaBrowser.Controller/Session/ISessionManager.cs b/MediaBrowser.Controller/Session/ISessionManager.cs index e63fc60e1a..3871952450 100644 --- a/MediaBrowser.Controller/Session/ISessionManager.cs +++ b/MediaBrowser.Controller/Session/ISessionManager.cs @@ -185,12 +185,8 @@ namespace MediaBrowser.Controller.Session /// Sends the message to user sessions. /// /// - /// The user identifier. - /// The name. - /// The data. - /// The cancellation token. /// Task. - Task SendMessageToUserSessions(string userId, string name, T data, CancellationToken cancellationToken); + Task SendMessageToUserSessions(List userIds, string name, T data, CancellationToken cancellationToken); /// /// Sends the message to user device sessions. diff --git a/MediaBrowser.Server.Implementations/EntryPoints/RecordingNotifier.cs b/MediaBrowser.Server.Implementations/EntryPoints/RecordingNotifier.cs index 620eea774e..414fda400b 100644 --- a/MediaBrowser.Server.Implementations/EntryPoints/RecordingNotifier.cs +++ b/MediaBrowser.Server.Implementations/EntryPoints/RecordingNotifier.cs @@ -54,18 +54,15 @@ namespace MediaBrowser.Server.Implementations.EntryPoints private async void SendMessage(string name, TimerEventInfo info) { - var users = _userManager.Users.Where(i => i.Policy.EnableLiveTvAccess).ToList(); + var users = _userManager.Users.Where(i => i.Policy.EnableLiveTvAccess).Select(i => i.Id.ToString("N")).ToList(); - foreach (var user in users) + try { - try - { - await _sessionManager.SendMessageToUserSessions(user.Id.ToString("N"), name, info, CancellationToken.None); - } - catch (Exception ex) - { - _logger.ErrorException("Error sending message", ex); - } + await _sessionManager.SendMessageToUserSessions(users, name, info, CancellationToken.None); + } + catch (Exception ex) + { + _logger.ErrorException("Error sending message", ex); } } diff --git a/MediaBrowser.Server.Implementations/EntryPoints/ServerEventNotifier.cs b/MediaBrowser.Server.Implementations/EntryPoints/ServerEventNotifier.cs index b5624625f2..3ea8417f86 100644 --- a/MediaBrowser.Server.Implementations/EntryPoints/ServerEventNotifier.cs +++ b/MediaBrowser.Server.Implementations/EntryPoints/ServerEventNotifier.cs @@ -11,6 +11,7 @@ using MediaBrowser.Controller.Sync; using MediaBrowser.Model.Events; using MediaBrowser.Model.Sync; using System; +using System.Collections.Generic; using System.Threading; namespace MediaBrowser.Server.Implementations.EntryPoints @@ -164,7 +165,7 @@ namespace MediaBrowser.Server.Implementations.EntryPoints private async void SendMessageToUserSession(User user, string name, T data) { - await _sessionManager.SendMessageToUserSessions(user.Id.ToString("N"), name, data, CancellationToken.None); + await _sessionManager.SendMessageToUserSessions(new List { user.Id.ToString("N") }, name, data, CancellationToken.None); } /// diff --git a/MediaBrowser.Server.Implementations/Session/SessionManager.cs b/MediaBrowser.Server.Implementations/Session/SessionManager.cs index 9d07f2169e..b21fcddd41 100644 --- a/MediaBrowser.Server.Implementations/Session/SessionManager.cs +++ b/MediaBrowser.Server.Implementations/Session/SessionManager.cs @@ -1871,29 +1871,15 @@ namespace MediaBrowser.Server.Implementations.Session public Task SendMessageToAdminSessions(string name, T data, CancellationToken cancellationToken) { - // TODO: How to identify admin sessions? - var sessions = Sessions.Where(i => i.IsActive && i.SessionController != null).ToList(); + var adminUserIds = _userManager.Users.Where(i => i.Policy.IsAdministrator).Select(i => i.Id.ToString("N")).ToList(); - var tasks = sessions.Select(session => Task.Run(async () => - { - try - { - await session.SessionController.SendMessage(name, data, cancellationToken).ConfigureAwait(false); - } - catch (Exception ex) - { - _logger.ErrorException("Error sending message", ex); - } - - }, cancellationToken)); - - return Task.WhenAll(tasks); + return SendMessageToUserSessions(adminUserIds, name, data, cancellationToken); } - public Task SendMessageToUserSessions(string userId, string name, T data, + public Task SendMessageToUserSessions(List userIds, string name, T data, CancellationToken cancellationToken) { - var sessions = Sessions.Where(i => i.IsActive && i.SessionController != null && i.ContainsUser(userId)).ToList(); + var sessions = Sessions.Where(i => i.IsActive && i.SessionController != null && userIds.Any(i.ContainsUser)).ToList(); var tasks = sessions.Select(session => Task.Run(async () => { diff --git a/MediaBrowser.sln b/MediaBrowser.sln index 90b318492f..c6068f5364 100644 --- a/MediaBrowser.sln +++ b/MediaBrowser.sln @@ -1,7 +1,7 @@  Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 14 -VisualStudioVersion = 14.0.25420.1 +VisualStudioVersion = 14.0.24720.0 MinimumVisualStudioVersion = 10.0.40219.1 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".nuget", ".nuget", "{F0E0E64C-2A6F-4E35-9533-D53AC07C2CD1}" EndProject @@ -65,6 +65,9 @@ EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Emby.Drawing", "Emby.Drawing\Emby.Drawing.csproj", "{08FFF49B-F175-4807-A2B5-73B0EBD9F716}" EndProject Global + GlobalSection(Performance) = preSolution + HasPerformanceSessions = true + EndGlobalSection GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU Debug|Mixed Platforms = Debug|Mixed Platforms -- cgit v1.2.3 From ce637a27938f603cb16bdd255735198abade6b96 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sat, 20 Aug 2016 17:58:44 -0400 Subject: add null check when updating images --- .../Persistence/SqliteItemRepository.cs | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'MediaBrowser.Server.Implementations') diff --git a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs index c3eee6d354..b9befb531e 100644 --- a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs +++ b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs @@ -4286,6 +4286,12 @@ namespace MediaBrowser.Server.Implementations.Persistence var index = 0; foreach (var image in images) { + if (string.IsNullOrWhiteSpace(image.Path)) + { + // Invalid + continue; + } + _saveImagesCommand.GetParameter(0).Value = itemId; _saveImagesCommand.GetParameter(1).Value = image.Type; _saveImagesCommand.GetParameter(2).Value = image.Path; -- cgit v1.2.3 From 430b187ef6b7d550e9ade89dd0254c5d1448a77a Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Mon, 22 Aug 2016 14:28:24 -0400 Subject: start a dashboard folder --- .../Updates/GithubUpdater.cs | 1 - .../Configuration/ServerConfiguration.cs | 2 + .../HttpServer/HttpListenerHost.cs | 20 ++++- .../ApplicationHost.cs | 1 + .../MediaBrowser.Server.Startup.Common.csproj | 1 + .../Migrations/UpdateLevelMigration.cs | 97 ++++++++++++++++++++++ MediaBrowser.WebDashboard/Api/DashboardService.cs | 62 ++++++++------ .../MediaBrowser.WebDashboard.csproj | 34 ++++---- .../Savers/EpisodeNfoSaver.cs | 4 +- 9 files changed, 180 insertions(+), 42 deletions(-) create mode 100644 MediaBrowser.Server.Startup.Common/Migrations/UpdateLevelMigration.cs (limited to 'MediaBrowser.Server.Implementations') diff --git a/MediaBrowser.Common.Implementations/Updates/GithubUpdater.cs b/MediaBrowser.Common.Implementations/Updates/GithubUpdater.cs index d1ec30210e..a118f7c265 100644 --- a/MediaBrowser.Common.Implementations/Updates/GithubUpdater.cs +++ b/MediaBrowser.Common.Implementations/Updates/GithubUpdater.cs @@ -33,7 +33,6 @@ namespace MediaBrowser.Common.Implementations.Updates EnableKeepAlive = false, CancellationToken = cancellationToken, UserAgent = "Emby/3.0" - }; if (_cacheLength.Ticks > 0) diff --git a/MediaBrowser.Model/Configuration/ServerConfiguration.cs b/MediaBrowser.Model/Configuration/ServerConfiguration.cs index 63d452bcee..a891a422a5 100644 --- a/MediaBrowser.Model/Configuration/ServerConfiguration.cs +++ b/MediaBrowser.Model/Configuration/ServerConfiguration.cs @@ -74,6 +74,8 @@ namespace MediaBrowser.Model.Configuration /// The metadata path. public string MetadataPath { get; set; } + public string LastVersion { get; set; } + /// /// Gets or sets the display name of the season zero. /// diff --git a/MediaBrowser.Server.Implementations/HttpServer/HttpListenerHost.cs b/MediaBrowser.Server.Implementations/HttpServer/HttpListenerHost.cs index 6332087391..51a53fe211 100644 --- a/MediaBrowser.Server.Implementations/HttpServer/HttpListenerHost.cs +++ b/MediaBrowser.Server.Implementations/HttpServer/HttpListenerHost.cs @@ -428,8 +428,24 @@ namespace MediaBrowser.Server.Implementations.HttpServer if (string.Equals(localPath, "/mediabrowser/", StringComparison.OrdinalIgnoreCase) || string.Equals(localPath, "/mediabrowser", StringComparison.OrdinalIgnoreCase) || - localPath.IndexOf("mediabrowser/web", StringComparison.OrdinalIgnoreCase) != -1 || - localPath.IndexOf("dashboard/", StringComparison.OrdinalIgnoreCase) != -1) + localPath.IndexOf("mediabrowser/web", StringComparison.OrdinalIgnoreCase) != -1) + { + httpRes.StatusCode = 200; + httpRes.ContentType = "text/html"; + var newUrl = urlString.Replace("mediabrowser", "emby", StringComparison.OrdinalIgnoreCase) + .Replace("/dashboard/", "/web/", StringComparison.OrdinalIgnoreCase); + + if (!string.Equals(newUrl, urlString, StringComparison.OrdinalIgnoreCase)) + { + httpRes.Write("EmbyPlease update your Emby bookmark to " + newUrl + ""); + + httpRes.Close(); + return; + } + } + + if (localPath.IndexOf("dashboard/", StringComparison.OrdinalIgnoreCase) != -1 && + localPath.IndexOf("web/dashboard", StringComparison.OrdinalIgnoreCase) == -1) { httpRes.StatusCode = 200; httpRes.ContentType = "text/html"; diff --git a/MediaBrowser.Server.Startup.Common/ApplicationHost.cs b/MediaBrowser.Server.Startup.Common/ApplicationHost.cs index 8cb1d4f0db..8516e54ee9 100644 --- a/MediaBrowser.Server.Startup.Common/ApplicationHost.cs +++ b/MediaBrowser.Server.Startup.Common/ApplicationHost.cs @@ -385,6 +385,7 @@ namespace MediaBrowser.Server.Startup.Common new OmdbEpisodeProviderMigration(ServerConfigurationManager), new MovieDbEpisodeProviderMigration(ServerConfigurationManager), new DbMigration(ServerConfigurationManager, TaskManager), + new UpdateLevelMigration(ServerConfigurationManager, this, HttpClient, JsonSerializer, _releaseAssetFilename), new FolderViewSettingMigration(ServerConfigurationManager, UserManager), new CollectionGroupingMigration(ServerConfigurationManager, UserManager), new CollectionsViewMigration(ServerConfigurationManager, UserManager) diff --git a/MediaBrowser.Server.Startup.Common/MediaBrowser.Server.Startup.Common.csproj b/MediaBrowser.Server.Startup.Common/MediaBrowser.Server.Startup.Common.csproj index 808d25fc9c..979a3a3577 100644 --- a/MediaBrowser.Server.Startup.Common/MediaBrowser.Server.Startup.Common.csproj +++ b/MediaBrowser.Server.Startup.Common/MediaBrowser.Server.Startup.Common.csproj @@ -77,6 +77,7 @@ + diff --git a/MediaBrowser.Server.Startup.Common/Migrations/UpdateLevelMigration.cs b/MediaBrowser.Server.Startup.Common/Migrations/UpdateLevelMigration.cs new file mode 100644 index 0000000000..fa354065c3 --- /dev/null +++ b/MediaBrowser.Server.Startup.Common/Migrations/UpdateLevelMigration.cs @@ -0,0 +1,97 @@ +using System; +using System.Threading; +using System.Threading.Tasks; +using MediaBrowser.Common.Implementations.Updates; +using MediaBrowser.Common.Net; +using MediaBrowser.Controller; +using MediaBrowser.Controller.Configuration; +using MediaBrowser.Model.Serialization; +using MediaBrowser.Model.Updates; + +namespace MediaBrowser.Server.Startup.Common.Migrations +{ + public class UpdateLevelMigration : IVersionMigration + { + private readonly IServerConfigurationManager _config; + private readonly IServerApplicationHost _appHost; + private readonly IHttpClient _httpClient; + private readonly IJsonSerializer _jsonSerializer; + private readonly string _releaseAssetFilename; + + public UpdateLevelMigration(IServerConfigurationManager config, IServerApplicationHost appHost, IHttpClient httpClient, IJsonSerializer jsonSerializer, string releaseAssetFilename) + { + _config = config; + _appHost = appHost; + _httpClient = httpClient; + _jsonSerializer = jsonSerializer; + _releaseAssetFilename = releaseAssetFilename; + } + + public async void Run() + { + var lastVersion = _config.Configuration.LastVersion; + var currentVersion = _appHost.ApplicationVersion; + + if (string.Equals(lastVersion, currentVersion.ToString(), StringComparison.OrdinalIgnoreCase)) + { + return; + } + + try + { + var updateLevel = _config.Configuration.SystemUpdateLevel; + + // Go down a level + if (updateLevel == PackageVersionClass.Release) + { + updateLevel = PackageVersionClass.Beta; + } + else if (updateLevel == PackageVersionClass.Beta) + { + updateLevel = PackageVersionClass.Dev; + } + else if (updateLevel == PackageVersionClass.Dev) + { + // It's already dev, there's nothing to check + return; + } + + await CheckVersion(currentVersion, updateLevel, CancellationToken.None).ConfigureAwait(false); + } + catch + { + + } + } + + private async Task CheckVersion(Version currentVersion, PackageVersionClass updateLevel, CancellationToken cancellationToken) + { + var result = await new GithubUpdater(_httpClient, _jsonSerializer, TimeSpan.FromMinutes(5)) + .CheckForUpdateResult("MediaBrowser", "Emby", currentVersion, PackageVersionClass.Beta, _releaseAssetFilename, "MBServer", "Mbserver.zip", + cancellationToken).ConfigureAwait(false); + + if (result != null && result.IsUpdateAvailable) + { + _config.Configuration.SystemUpdateLevel = updateLevel; + _config.SaveConfiguration(); + return; + } + + // Go down a level + if (updateLevel == PackageVersionClass.Release) + { + updateLevel = PackageVersionClass.Beta; + } + else if (updateLevel == PackageVersionClass.Beta) + { + updateLevel = PackageVersionClass.Dev; + } + else + { + return; + } + + await CheckVersion(currentVersion, updateLevel, cancellationToken).ConfigureAwait(false); + } + } +} diff --git a/MediaBrowser.WebDashboard/Api/DashboardService.cs b/MediaBrowser.WebDashboard/Api/DashboardService.cs index 12e1eb5eaf..aec4632ae8 100644 --- a/MediaBrowser.WebDashboard/Api/DashboardService.cs +++ b/MediaBrowser.WebDashboard/Api/DashboardService.cs @@ -157,11 +157,21 @@ namespace MediaBrowser.WebDashboard.Api var creator = GetPackageCreator(); var directory = creator.DashboardUIPath; - var skipExtensions = GetUndeployedExtensions(); + var skipExtensions = GetDeployIgnoreExtensions(); + var skipNames = GetDeployIgnoreFilenames(); return Directory.GetFiles(directory, "*", SearchOption.AllDirectories) .Where(i => !skipExtensions.Contains(Path.GetExtension(i) ?? string.Empty, StringComparer.OrdinalIgnoreCase)) + .Where(i => !skipNames.Any(s => + { + if (s.Item2) + { + return string.Equals(s.Item1, Path.GetFileName(i), StringComparison.OrdinalIgnoreCase); + } + + return (Path.GetFileName(i) ?? string.Empty).IndexOf(s.Item1, StringComparison.OrdinalIgnoreCase) != -1; + })) .Select(i => i.Replace(directory, string.Empty, StringComparison.OrdinalIgnoreCase).Replace("\\", "/").TrimStart('/') + "?v=" + _appHost.ApplicationVersion.ToString()) .ToList(); } @@ -300,7 +310,7 @@ namespace MediaBrowser.WebDashboard.Api return new PackageCreator(_fileSystem, _localization, Logger, _serverConfigurationManager, _jsonSerializer); } - private List GetUndeployedExtensions() + private List GetDeployIgnoreExtensions() { var list = new List(); @@ -315,6 +325,28 @@ namespace MediaBrowser.WebDashboard.Api return list; } + private List> GetDeployIgnoreFilenames() + { + var list = new List>(); + + list.Add(new Tuple("copying", true)); + list.Add(new Tuple("license", true)); + list.Add(new Tuple("license-mit", true)); + list.Add(new Tuple("gitignore", false)); + list.Add(new Tuple("npmignore", false)); + list.Add(new Tuple("jshintrc", false)); + list.Add(new Tuple("gruntfile", false)); + list.Add(new Tuple("bowerrc", false)); + list.Add(new Tuple("jscsrc", false)); + list.Add(new Tuple("hero.svg", false)); + list.Add(new Tuple("travis.yml", false)); + list.Add(new Tuple("build.js", false)); + list.Add(new Tuple("editorconfig", false)); + list.Add(new Tuple("gitattributes", false)); + + return list; + } + public async Task Get(GetDashboardPackage request) { var path = Path.Combine(_serverConfigurationManager.ApplicationPaths.ProgramDataPath, @@ -344,30 +376,12 @@ namespace MediaBrowser.WebDashboard.Api // Try to trim the output size a bit var bowerPath = Path.Combine(path, "bower_components"); - if (!string.Equals(mode, "cordova", StringComparison.OrdinalIgnoreCase)) - { - //var versionedBowerPath = Path.Combine(Path.GetDirectoryName(bowerPath), "bower_components" + _appHost.ApplicationVersion); - //Directory.Move(bowerPath, versionedBowerPath); - //bowerPath = versionedBowerPath; - } - - GetUndeployedExtensions().ForEach(i => DeleteFilesByExtension(bowerPath, i)); + GetDeployIgnoreExtensions().ForEach(i => DeleteFilesByExtension(bowerPath, i)); DeleteFilesByExtension(bowerPath, ".json", "strings\\"); - DeleteFilesByName(bowerPath, "copying", true); - DeleteFilesByName(bowerPath, "license", true); - DeleteFilesByName(bowerPath, "license-mit", true); - DeleteFilesByName(bowerPath, "gitignore"); - DeleteFilesByName(bowerPath, "npmignore"); - DeleteFilesByName(bowerPath, "jshintrc"); - DeleteFilesByName(bowerPath, "gruntfile"); - DeleteFilesByName(bowerPath, "bowerrc"); - DeleteFilesByName(bowerPath, "jscsrc"); - DeleteFilesByName(bowerPath, "hero.svg"); - DeleteFilesByName(bowerPath, "travis.yml"); - DeleteFilesByName(bowerPath, "build.js"); - DeleteFilesByName(bowerPath, "editorconfig"); - DeleteFilesByName(bowerPath, "gitattributes"); + + GetDeployIgnoreFilenames().ForEach(i => DeleteFilesByName(bowerPath, i.Item1, i.Item2)); + DeleteFoldersByName(bowerPath, "demo"); DeleteFoldersByName(bowerPath, "test"); DeleteFoldersByName(bowerPath, "guides"); diff --git a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj index 54dd52fb7a..b2eb34526c 100644 --- a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj +++ b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj @@ -101,6 +101,9 @@ PreserveNewest + + PreserveNewest + PreserveNewest @@ -185,6 +188,9 @@ PreserveNewest + + PreserveNewest + PreserveNewest @@ -326,7 +332,7 @@ PreserveNewest - + PreserveNewest @@ -338,7 +344,7 @@ PreserveNewest - + PreserveNewest @@ -356,7 +362,7 @@ PreserveNewest - + PreserveNewest @@ -377,7 +383,7 @@ PreserveNewest - + PreserveNewest @@ -503,7 +509,7 @@ PreserveNewest - + PreserveNewest @@ -863,13 +869,13 @@ PreserveNewest - + PreserveNewest PreserveNewest - + PreserveNewest @@ -881,7 +887,7 @@ PreserveNewest - + PreserveNewest @@ -896,10 +902,10 @@ PreserveNewest - + PreserveNewest - + PreserveNewest @@ -1089,7 +1095,7 @@ PreserveNewest - + PreserveNewest @@ -1356,7 +1362,7 @@ - + PreserveNewest @@ -1429,7 +1435,7 @@ - + PreserveNewest @@ -1441,7 +1447,7 @@ PreserveNewest - + PreserveNewest diff --git a/MediaBrowser.XbmcMetadata/Savers/EpisodeNfoSaver.cs b/MediaBrowser.XbmcMetadata/Savers/EpisodeNfoSaver.cs index 7523ce6bf1..6380b9f53b 100644 --- a/MediaBrowser.XbmcMetadata/Savers/EpisodeNfoSaver.cs +++ b/MediaBrowser.XbmcMetadata/Savers/EpisodeNfoSaver.cs @@ -118,7 +118,9 @@ namespace MediaBrowser.XbmcMetadata.Savers "airsbefore_season", "DVD_episodenumber", "DVD_season", - "absolute_number" + "absolute_number", + "displayseason", + "displayepisode" }; return list; -- cgit v1.2.3 From 17e1c8c22b8ee09a363cfd76ed315b3af9cc09c8 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Tue, 23 Aug 2016 01:08:07 -0400 Subject: update sync settings --- MediaBrowser.Api/Playback/BaseStreamingService.cs | 14 ++------- MediaBrowser.Api/Playback/Hls/BaseHlsService.cs | 5 ---- MediaBrowser.Api/Playback/StreamRequest.cs | 2 -- MediaBrowser.Api/Sync/SyncHelper.cs | 13 ++++++++ MediaBrowser.Api/Sync/SyncService.cs | 3 +- .../MediaEncoding/MediaEncoderHelpers.cs | 7 ++++- MediaBrowser.Dlna/Profiles/DefaultProfile.cs | 1 - MediaBrowser.Dlna/Profiles/KodiProfile.cs | 2 -- MediaBrowser.Model/Dlna/AudioOptions.cs | 6 +++- MediaBrowser.Model/Dlna/DeviceProfile.cs | 3 +- MediaBrowser.Model/Dlna/StreamBuilder.cs | 35 +++++++++++++--------- MediaBrowser.Model/Dlna/StreamInfo.cs | 4 +-- MediaBrowser.Model/Dlna/TranscodingProfile.cs | 3 -- .../MediaEncoder/EncodingManager.cs | 2 +- .../Sync/AppSyncProvider.cs | 5 ++++ 15 files changed, 58 insertions(+), 47 deletions(-) (limited to 'MediaBrowser.Server.Implementations') diff --git a/MediaBrowser.Api/Playback/BaseStreamingService.cs b/MediaBrowser.Api/Playback/BaseStreamingService.cs index f52505c04b..bff6ec2ffa 100644 --- a/MediaBrowser.Api/Playback/BaseStreamingService.cs +++ b/MediaBrowser.Api/Playback/BaseStreamingService.cs @@ -1589,13 +1589,6 @@ namespace MediaBrowser.Api.Playback } } else if (i == 25) - { - if (videoRequest != null) - { - videoRequest.ForceLiveStream = string.Equals("true", val, StringComparison.OrdinalIgnoreCase); - } - } - else if (i == 26) { if (!string.IsNullOrWhiteSpace(val) && videoRequest != null) { @@ -1606,18 +1599,18 @@ namespace MediaBrowser.Api.Playback } } } - else if (i == 27) + else if (i == 26) { request.TranscodingMaxAudioChannels = int.Parse(val, UsCulture); } - else if (i == 28) + else if (i == 27) { if (videoRequest != null) { videoRequest.EnableSubtitlesInManifest = string.Equals("true", val, StringComparison.OrdinalIgnoreCase); } } - else if (i == 29) + else if (i == 28) { request.Tag = val; } @@ -2218,7 +2211,6 @@ namespace MediaBrowser.Api.Playback if (state.VideoRequest != null) { state.VideoRequest.CopyTimestamps = transcodingProfile.CopyTimestamps; - state.VideoRequest.ForceLiveStream = transcodingProfile.ForceLiveStream; state.VideoRequest.EnableSubtitlesInManifest = transcodingProfile.EnableSubtitlesInManifest; } } diff --git a/MediaBrowser.Api/Playback/Hls/BaseHlsService.cs b/MediaBrowser.Api/Playback/Hls/BaseHlsService.cs index 4ec14c96cb..a0ac96b9d2 100644 --- a/MediaBrowser.Api/Playback/Hls/BaseHlsService.cs +++ b/MediaBrowser.Api/Playback/Hls/BaseHlsService.cs @@ -281,11 +281,6 @@ namespace MediaBrowser.Api.Playback.Hls { var isLiveStream = (state.RunTimeTicks ?? 0) == 0; - if (state.VideoRequest.ForceLiveStream) - { - return true; - } - return isLiveStream; } } diff --git a/MediaBrowser.Api/Playback/StreamRequest.cs b/MediaBrowser.Api/Playback/StreamRequest.cs index e1a577f525..8cdf846ed5 100644 --- a/MediaBrowser.Api/Playback/StreamRequest.cs +++ b/MediaBrowser.Api/Playback/StreamRequest.cs @@ -193,8 +193,6 @@ namespace MediaBrowser.Api.Playback [ApiMember(Name = "CopyTimestamps", Description = "Whether or not to copy timestamps when transcoding with an offset. Defaults to false.", IsRequired = false, DataType = "bool", ParameterType = "query", Verb = "GET")] public bool CopyTimestamps { get; set; } - public bool ForceLiveStream { get; set; } - public bool EnableSubtitlesInManifest { get; set; } public VideoStreamRequest() diff --git a/MediaBrowser.Api/Sync/SyncHelper.cs b/MediaBrowser.Api/Sync/SyncHelper.cs index 2f857000c0..60df2bb1e9 100644 --- a/MediaBrowser.Api/Sync/SyncHelper.cs +++ b/MediaBrowser.Api/Sync/SyncHelper.cs @@ -24,6 +24,19 @@ namespace MediaBrowser.Api.Sync } break; } + if (item.IsAudio) + { + options.Add(SyncJobOption.Quality); + options.Add(SyncJobOption.Profile); + break; + } + if (item.IsMusicGenre || item.IsArtist|| item.IsType("musicalbum")) + { + options.Add(SyncJobOption.Quality); + options.Add(SyncJobOption.Profile); + options.Add(SyncJobOption.ItemLimit); + break; + } if (item.IsFolderItem && !item.IsMusicGenre && !item.IsArtist && !item.IsType("musicalbum") && !item.IsGameGenre) { options.Add(SyncJobOption.Quality); diff --git a/MediaBrowser.Api/Sync/SyncService.cs b/MediaBrowser.Api/Sync/SyncService.cs index b9544d71ba..821591dc4e 100644 --- a/MediaBrowser.Api/Sync/SyncService.cs +++ b/MediaBrowser.Api/Sync/SyncService.cs @@ -291,7 +291,8 @@ namespace MediaBrowser.Api.Sync { Fields = new List { - ItemFields.SyncInfo + ItemFields.SyncInfo, + ItemFields.BasicSyncInfo } }; diff --git a/MediaBrowser.Controller/MediaEncoding/MediaEncoderHelpers.cs b/MediaBrowser.Controller/MediaEncoding/MediaEncoderHelpers.cs index 66a9fa60b8..96a3753e19 100644 --- a/MediaBrowser.Controller/MediaEncoding/MediaEncoderHelpers.cs +++ b/MediaBrowser.Controller/MediaEncoding/MediaEncoderHelpers.cs @@ -36,8 +36,13 @@ namespace MediaBrowser.Controller.MediaEncoding return new[] {videoPath}; } - public static List GetPlayableStreamFiles(IFileSystem fileSystem, string rootPath, IEnumerable filenames) + private static List GetPlayableStreamFiles(IFileSystem fileSystem, string rootPath, List filenames) { + if (filenames.Count == 0) + { + return new List(); + } + var allFiles = fileSystem .GetFilePaths(rootPath, true) .ToList(); diff --git a/MediaBrowser.Dlna/Profiles/DefaultProfile.cs b/MediaBrowser.Dlna/Profiles/DefaultProfile.cs index e4f6d337fe..5f60e8306d 100644 --- a/MediaBrowser.Dlna/Profiles/DefaultProfile.cs +++ b/MediaBrowser.Dlna/Profiles/DefaultProfile.cs @@ -33,7 +33,6 @@ namespace MediaBrowser.Dlna.Profiles MaxStreamingBitrate = 20000000; MaxStaticBitrate = 20000000; MusicStreamingTranscodingBitrate = 192000; - MusicSyncBitrate = 192000; EnableAlbumArtInDidl = false; diff --git a/MediaBrowser.Dlna/Profiles/KodiProfile.cs b/MediaBrowser.Dlna/Profiles/KodiProfile.cs index 184923b70d..5e1ac57608 100644 --- a/MediaBrowser.Dlna/Profiles/KodiProfile.cs +++ b/MediaBrowser.Dlna/Profiles/KodiProfile.cs @@ -11,9 +11,7 @@ namespace MediaBrowser.Dlna.Profiles Name = "Kodi"; MaxStreamingBitrate = 100000000; - MaxStaticBitrate = 100000000; MusicStreamingTranscodingBitrate = 1280000; - MusicSyncBitrate = 1280000; TimelineOffsetSeconds = 5; diff --git a/MediaBrowser.Model/Dlna/AudioOptions.cs b/MediaBrowser.Model/Dlna/AudioOptions.cs index c208e8ab0b..f3b6df861d 100644 --- a/MediaBrowser.Model/Dlna/AudioOptions.cs +++ b/MediaBrowser.Model/Dlna/AudioOptions.cs @@ -59,7 +59,7 @@ namespace MediaBrowser.Model.Dlna /// Gets the maximum bitrate. /// /// System.Nullable<System.Int32>. - public int? GetMaxBitrate() + public int? GetMaxBitrate(bool isAudio) { if (MaxBitrate.HasValue) { @@ -70,6 +70,10 @@ namespace MediaBrowser.Model.Dlna { if (Context == EncodingContext.Static) { + if (isAudio && Profile.MaxStaticMusicBitrate.HasValue) + { + return Profile.MaxStaticMusicBitrate; + } return Profile.MaxStaticBitrate; } diff --git a/MediaBrowser.Model/Dlna/DeviceProfile.cs b/MediaBrowser.Model/Dlna/DeviceProfile.cs index 423928f620..d6a3223227 100644 --- a/MediaBrowser.Model/Dlna/DeviceProfile.cs +++ b/MediaBrowser.Model/Dlna/DeviceProfile.cs @@ -55,7 +55,7 @@ namespace MediaBrowser.Model.Dlna public int? MaxStaticBitrate { get; set; } public int? MusicStreamingTranscodingBitrate { get; set; } - public int? MusicSyncBitrate { get; set; } + public int? MaxStaticMusicBitrate { get; set; } /// /// Controls the content of the X_DLNADOC element in the urn:schemas-dlna-org:device-1-0 namespace. @@ -115,7 +115,6 @@ namespace MediaBrowser.Model.Dlna MaxStreamingBitrate = 8000000; MaxStaticBitrate = 8000000; MusicStreamingTranscodingBitrate = 128000; - MusicSyncBitrate = 128000; } public List GetSupportedMediaTypes() diff --git a/MediaBrowser.Model/Dlna/StreamBuilder.cs b/MediaBrowser.Model/Dlna/StreamBuilder.cs index 0710417c85..f1b3e7bab5 100644 --- a/MediaBrowser.Model/Dlna/StreamBuilder.cs +++ b/MediaBrowser.Model/Dlna/StreamBuilder.cs @@ -55,7 +55,7 @@ namespace MediaBrowser.Model.Dlna stream.DeviceProfileId = options.Profile.Id; } - return GetOptimalStream(streams, options.GetMaxBitrate()); + return GetOptimalStream(streams, options.GetMaxBitrate(true)); } public StreamInfo BuildVideoItem(VideoOptions options) @@ -88,7 +88,7 @@ namespace MediaBrowser.Model.Dlna stream.DeviceProfileId = options.Profile.Id; } - return GetOptimalStream(streams, options.GetMaxBitrate()); + return GetOptimalStream(streams, options.GetMaxBitrate(false)); } private StreamInfo GetOptimalStream(List streams, int? maxBitrate) @@ -275,24 +275,32 @@ namespace MediaBrowser.Model.Dlna playlistItem.MaxAudioChannels = Math.Min(options.MaxAudioChannels.Value, currentValue); } - int configuredBitrate = options.AudioTranscodingBitrate ?? - (options.Context == EncodingContext.Static ? options.Profile.MusicSyncBitrate : options.Profile.MusicStreamingTranscodingBitrate) ?? + int transcodingBitrate = options.AudioTranscodingBitrate ?? + options.Profile.MusicStreamingTranscodingBitrate ?? 128000; - playlistItem.AudioBitrate = Math.Min(configuredBitrate, playlistItem.AudioBitrate ?? configuredBitrate); + int? configuredBitrate = options.GetMaxBitrate(true); + + if (configuredBitrate.HasValue) + { + transcodingBitrate = Math.Min(configuredBitrate.Value, transcodingBitrate); + } + + playlistItem.AudioBitrate = Math.Min(transcodingBitrate, playlistItem.AudioBitrate ?? transcodingBitrate); + } return playlistItem; } - private int? GetBitrateForDirectPlayCheck(MediaSourceInfo item, AudioOptions options) + private int? GetBitrateForDirectPlayCheck(MediaSourceInfo item, AudioOptions options, bool isAudio) { if (item.Protocol == MediaProtocol.File) { return options.Profile.MaxStaticBitrate; } - return options.GetMaxBitrate(); + return options.GetMaxBitrate(isAudio); } private List GetAudioDirectPlayMethods(MediaSourceInfo item, MediaStream audioStream, AudioOptions options) @@ -312,7 +320,7 @@ namespace MediaBrowser.Model.Dlna if (directPlayProfile != null) { // While options takes the network and other factors into account. Only applies to direct stream - if (item.SupportsDirectStream && IsAudioEligibleForDirectPlay(item, options.GetMaxBitrate()) && options.EnableDirectStream) + if (item.SupportsDirectStream && IsAudioEligibleForDirectPlay(item, options.GetMaxBitrate(true)) && options.EnableDirectStream) { playMethods.Add(PlayMethod.DirectStream); } @@ -320,7 +328,7 @@ namespace MediaBrowser.Model.Dlna // The profile describes what the device supports // If device requirements are satisfied then allow both direct stream and direct play if (item.SupportsDirectPlay && - IsAudioEligibleForDirectPlay(item, GetBitrateForDirectPlayCheck(item, options)) && options.EnableDirectPlay) + IsAudioEligibleForDirectPlay(item, GetBitrateForDirectPlayCheck(item, options, true)) && options.EnableDirectPlay) { playMethods.Add(PlayMethod.DirectPlay); } @@ -403,8 +411,8 @@ namespace MediaBrowser.Model.Dlna MediaStream videoStream = item.VideoStream; // TODO: This doesn't accout for situation of device being able to handle media bitrate, but wifi connection not fast enough - bool isEligibleForDirectPlay = options.EnableDirectPlay && (options.ForceDirectPlay || IsEligibleForDirectPlay(item, GetBitrateForDirectPlayCheck(item, options), subtitleStream, options, PlayMethod.DirectPlay)); - bool isEligibleForDirectStream = options.EnableDirectStream && (options.ForceDirectStream || IsEligibleForDirectPlay(item, options.GetMaxBitrate(), subtitleStream, options, PlayMethod.DirectStream)); + bool isEligibleForDirectPlay = options.EnableDirectPlay && (options.ForceDirectPlay || IsEligibleForDirectPlay(item, GetBitrateForDirectPlayCheck(item, options, true), subtitleStream, options, PlayMethod.DirectPlay)); + bool isEligibleForDirectStream = options.EnableDirectStream && (options.ForceDirectStream || IsEligibleForDirectPlay(item, options.GetMaxBitrate(false), subtitleStream, options, PlayMethod.DirectStream)); _logger.Info("Profile: {0}, Path: {1}, isEligibleForDirectPlay: {2}, isEligibleForDirectStream: {3}", options.Profile.Name ?? "Unknown Profile", @@ -469,7 +477,6 @@ namespace MediaBrowser.Model.Dlna playlistItem.VideoCodec = transcodingProfile.VideoCodec; playlistItem.CopyTimestamps = transcodingProfile.CopyTimestamps; - playlistItem.ForceLiveStream = transcodingProfile.ForceLiveStream; playlistItem.EnableSubtitlesInManifest = transcodingProfile.EnableSubtitlesInManifest; if (!string.IsNullOrEmpty(transcodingProfile.MaxAudioChannels)) @@ -570,10 +577,10 @@ namespace MediaBrowser.Model.Dlna playlistItem.MaxAudioChannels = Math.Min(options.MaxAudioChannels.Value, currentValue); } - int audioBitrate = GetAudioBitrate(playlistItem.SubProtocol, options.GetMaxBitrate(), playlistItem.TargetAudioChannels, playlistItem.TargetAudioCodec, audioStream); + int audioBitrate = GetAudioBitrate(playlistItem.SubProtocol, options.GetMaxBitrate(false), playlistItem.TargetAudioChannels, playlistItem.TargetAudioCodec, audioStream); playlistItem.AudioBitrate = Math.Min(playlistItem.AudioBitrate ?? audioBitrate, audioBitrate); - int? maxBitrateSetting = options.GetMaxBitrate(); + int? maxBitrateSetting = options.GetMaxBitrate(false); // Honor max rate if (maxBitrateSetting.HasValue) { diff --git a/MediaBrowser.Model/Dlna/StreamInfo.cs b/MediaBrowser.Model/Dlna/StreamInfo.cs index 02239aa484..ac024f00b9 100644 --- a/MediaBrowser.Model/Dlna/StreamInfo.cs +++ b/MediaBrowser.Model/Dlna/StreamInfo.cs @@ -36,7 +36,6 @@ namespace MediaBrowser.Model.Dlna public string VideoProfile { get; set; } public bool CopyTimestamps { get; set; } - public bool ForceLiveStream { get; set; } public bool EnableSubtitlesInManifest { get; set; } public string[] AudioCodecs { get; set; } @@ -216,7 +215,7 @@ namespace MediaBrowser.Model.Dlna list.Add(new NameValuePair("MaxWidth", item.MaxWidth.HasValue ? StringHelper.ToStringCultureInvariant(item.MaxWidth.Value) : string.Empty)); list.Add(new NameValuePair("MaxHeight", item.MaxHeight.HasValue ? StringHelper.ToStringCultureInvariant(item.MaxHeight.Value) : string.Empty)); - if (StringHelper.EqualsIgnoreCase(item.SubProtocol, "hls") && !item.ForceLiveStream) + if (StringHelper.EqualsIgnoreCase(item.SubProtocol, "hls")) { list.Add(new NameValuePair("StartTimeTicks", string.Empty)); } @@ -246,7 +245,6 @@ namespace MediaBrowser.Model.Dlna } list.Add(new NameValuePair("CopyTimestamps", item.CopyTimestamps.ToString().ToLower())); - list.Add(new NameValuePair("ForceLiveStream", item.ForceLiveStream.ToString().ToLower())); list.Add(new NameValuePair("SubtitleMethod", item.SubtitleStreamIndex.HasValue && item.SubtitleDeliveryMethod != SubtitleDeliveryMethod.External ? item.SubtitleDeliveryMethod.ToString() : string.Empty)); list.Add(new NameValuePair("TranscodingMaxAudioChannels", item.TranscodingMaxAudioChannels.HasValue ? StringHelper.ToStringCultureInvariant(item.TranscodingMaxAudioChannels.Value) : string.Empty)); diff --git a/MediaBrowser.Model/Dlna/TranscodingProfile.cs b/MediaBrowser.Model/Dlna/TranscodingProfile.cs index 19caf85eb2..beb83b053b 100644 --- a/MediaBrowser.Model/Dlna/TranscodingProfile.cs +++ b/MediaBrowser.Model/Dlna/TranscodingProfile.cs @@ -35,9 +35,6 @@ namespace MediaBrowser.Model.Dlna [XmlAttribute("context")] public EncodingContext Context { get; set; } - [XmlAttribute("forceLiveStream")] - public bool ForceLiveStream { get; set; } - [XmlAttribute("enableSubtitlesInManifest")] public bool EnableSubtitlesInManifest { get; set; } diff --git a/MediaBrowser.Server.Implementations/MediaEncoder/EncodingManager.cs b/MediaBrowser.Server.Implementations/MediaEncoder/EncodingManager.cs index 7f709d084f..46ba7d2e74 100644 --- a/MediaBrowser.Server.Implementations/MediaEncoder/EncodingManager.cs +++ b/MediaBrowser.Server.Implementations/MediaEncoder/EncodingManager.cs @@ -123,7 +123,7 @@ namespace MediaBrowser.Server.Implementations.MediaEncoder { if (extractImages) { - if (video.VideoType == VideoType.HdDvd || video.VideoType == VideoType.Iso || video.VideoType == VideoType.BluRay) + if (video.VideoType == VideoType.HdDvd || video.VideoType == VideoType.Iso || video.VideoType == VideoType.BluRay || video.VideoType == VideoType.Dvd) { continue; } diff --git a/MediaBrowser.Server.Implementations/Sync/AppSyncProvider.cs b/MediaBrowser.Server.Implementations/Sync/AppSyncProvider.cs index 03485012f0..408ec717eb 100644 --- a/MediaBrowser.Server.Implementations/Sync/AppSyncProvider.cs +++ b/MediaBrowser.Server.Implementations/Sync/AppSyncProvider.cs @@ -85,6 +85,11 @@ namespace MediaBrowser.Server.Implementations.Sync { Name = "Low", Id = "low" + }, + new SyncQualityOption + { + Name = "Custom", + Id = "custom" } }; } -- cgit v1.2.3 From e4851e1b25e7a51d5e950978c2e0ccc2e44a07c5 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Wed, 24 Aug 2016 02:13:15 -0400 Subject: reduce rescanning due to IsOffline --- MediaBrowser.Api/Playback/BaseStreamingService.cs | 9 +++-- MediaBrowser.Controller/Entities/BaseItem.cs | 22 +++++++++--- MediaBrowser.Controller/Entities/Folder.cs | 15 ++------ .../MediaEncoding/IMediaEncoder.cs | 1 + .../Encoder/EncodingJobFactory.cs | 2 +- MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs | 16 ++++----- .../Configuration/UserConfiguration.cs | 1 - .../MediaInfo/AudioImageProvider.cs | 9 +++-- .../MediaInfo/FFProbeProvider.cs | 2 +- .../MediaInfo/VideoImageProvider.cs | 2 +- MediaBrowser.Providers/Photos/PhotoProvider.cs | 9 +++-- .../Persistence/CleanDatabaseScheduledTask.cs | 3 +- .../Persistence/SqliteItemRepository.cs | 3 -- .../ApplicationHost.cs | 1 - .../MediaBrowser.Server.Startup.Common.csproj | 1 - .../Migrations/FolderViewSettingMigration.cs | 40 ---------------------- 16 files changed, 51 insertions(+), 85 deletions(-) delete mode 100644 MediaBrowser.Server.Startup.Common/Migrations/FolderViewSettingMigration.cs (limited to 'MediaBrowser.Server.Implementations') diff --git a/MediaBrowser.Api/Playback/BaseStreamingService.cs b/MediaBrowser.Api/Playback/BaseStreamingService.cs index 4c8b918c6a..6f4b6323d6 100644 --- a/MediaBrowser.Api/Playback/BaseStreamingService.cs +++ b/MediaBrowser.Api/Playback/BaseStreamingService.cs @@ -298,7 +298,8 @@ namespace MediaBrowser.Api.Playback // Since transcoding of folder rips is expiremental anyway, it's not worth adding additional variables such as this. if (state.VideoType == VideoType.VideoFile) { - var hwType = ApiEntryPoint.Instance.GetEncodingOptions().HardwareAccelerationType; + var encodingOptions = ApiEntryPoint.Instance.GetEncodingOptions(); + var hwType = encodingOptions.HardwareAccelerationType; if (string.Equals(hwType, "qsv", StringComparison.OrdinalIgnoreCase) || string.Equals(hwType, "h264_qsv", StringComparison.OrdinalIgnoreCase)) @@ -314,7 +315,7 @@ namespace MediaBrowser.Api.Playback { return GetAvailableEncoder("h264_omx", defaultEncoder); } - if (string.Equals(hwType, "vaapi", StringComparison.OrdinalIgnoreCase)) + if (string.Equals(hwType, "vaapi", StringComparison.OrdinalIgnoreCase) && !string.IsNullOrWhiteSpace(encodingOptions.VaapiDevice)) { return GetAvailableEncoder("h264_vaapi", defaultEncoder); } @@ -988,6 +989,8 @@ namespace MediaBrowser.Api.Playback } } + arg += string.Format(" -ss {0}", MediaEncoder.GetTimeParameter(TimeSpan.FromSeconds(1).Ticks)); + return arg.Trim(); } @@ -2289,7 +2292,7 @@ namespace MediaBrowser.Api.Playback return Task.FromResult(true); } - if (!string.Equals(MediaEncoder.EncoderLocationType, "Default", StringComparison.OrdinalIgnoreCase)) + if (!MediaEncoder.IsDefaultEncoderPath) { return Task.FromResult(true); } diff --git a/MediaBrowser.Controller/Entities/BaseItem.cs b/MediaBrowser.Controller/Entities/BaseItem.cs index cbbb9a89a3..984374a499 100644 --- a/MediaBrowser.Controller/Entities/BaseItem.cs +++ b/MediaBrowser.Controller/Entities/BaseItem.cs @@ -281,6 +281,20 @@ namespace MediaBrowser.Controller.Entities } } + public Task UpdateIsOffline(bool newValue) + { + var item = this; + + if (item.IsOffline != newValue) + { + item.IsOffline = newValue; + // this is creating too many repeated db updates + //return item.UpdateToRepository(ItemUpdateType.None, CancellationToken.None); + } + + return Task.FromResult(true); + } + /// /// Gets or sets the type of the location. /// @@ -290,10 +304,10 @@ namespace MediaBrowser.Controller.Entities { get { - if (IsOffline) - { - return LocationType.Offline; - } + //if (IsOffline) + //{ + // return LocationType.Offline; + //} if (string.IsNullOrWhiteSpace(Path)) { diff --git a/MediaBrowser.Controller/Entities/Folder.cs b/MediaBrowser.Controller/Entities/Folder.cs index b5c76c0ebc..bea648a3d3 100644 --- a/MediaBrowser.Controller/Entities/Folder.cs +++ b/MediaBrowser.Controller/Entities/Folder.cs @@ -375,7 +375,7 @@ namespace MediaBrowser.Controller.Entities if (currentChildren.TryGetValue(child.Id, out currentChild) && IsValidFromResolver(currentChild, child)) { - await UpdateIsOffline(currentChild, false).ConfigureAwait(false); + await currentChild.UpdateIsOffline(false).ConfigureAwait(false); validChildren.Add(currentChild); continue; @@ -404,7 +404,7 @@ namespace MediaBrowser.Controller.Entities else if (!string.IsNullOrEmpty(item.Path) && IsPathOffline(item.Path)) { - await UpdateIsOffline(item, true).ConfigureAwait(false); + await item.UpdateIsOffline(true).ConfigureAwait(false); } else { @@ -461,17 +461,6 @@ namespace MediaBrowser.Controller.Entities progress.Report(100); } - private Task UpdateIsOffline(BaseItem item, bool newValue) - { - if (item.IsOffline != newValue) - { - item.IsOffline = newValue; - return item.UpdateToRepository(ItemUpdateType.None, CancellationToken.None); - } - - return Task.FromResult(true); - } - private async Task RefreshMetadataRecursive(MetadataRefreshOptions refreshOptions, bool recursive, IProgress progress, CancellationToken cancellationToken) { var children = ActualChildren.ToList(); diff --git a/MediaBrowser.Controller/MediaEncoding/IMediaEncoder.cs b/MediaBrowser.Controller/MediaEncoding/IMediaEncoder.cs index 1fef8bead7..7fdbf020ce 100644 --- a/MediaBrowser.Controller/MediaEncoding/IMediaEncoder.cs +++ b/MediaBrowser.Controller/MediaEncoding/IMediaEncoder.cs @@ -134,5 +134,6 @@ namespace MediaBrowser.Controller.MediaEncoding Task UpdateEncoderPath(string path, string pathType); bool SupportsEncoder(string encoder); + bool IsDefaultEncoderPath { get; } } } diff --git a/MediaBrowser.MediaEncoding/Encoder/EncodingJobFactory.cs b/MediaBrowser.MediaEncoding/Encoder/EncodingJobFactory.cs index b5e97f09a1..c725326691 100644 --- a/MediaBrowser.MediaEncoding/Encoder/EncodingJobFactory.cs +++ b/MediaBrowser.MediaEncoding/Encoder/EncodingJobFactory.cs @@ -586,7 +586,7 @@ namespace MediaBrowser.MediaEncoding.Encoder { return GetAvailableEncoder(mediaEncoder, "h264_omx", defaultEncoder); } - if (string.Equals(hwType, "vaapi", StringComparison.OrdinalIgnoreCase)) + if (string.Equals(hwType, "vaapi", StringComparison.OrdinalIgnoreCase) && !string.IsNullOrWhiteSpace(options.VaapiDevice)) { return GetAvailableEncoder(mediaEncoder, "h264_vaapi", defaultEncoder); } diff --git a/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs b/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs index f488be11a7..ad84ffee82 100644 --- a/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs +++ b/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs @@ -123,20 +123,20 @@ namespace MediaBrowser.MediaEncoding.Encoder return "System"; } - if (IsDefaultPath(FFMpegPath)) - { - return "Default"; - } - return "Custom"; } } - private bool IsDefaultPath(string path) + public bool IsDefaultEncoderPath { - var parentPath = Path.Combine(ConfigurationManager.ApplicationPaths.ProgramDataPath, "ffmpeg", "20160410"); + get + { + var path = FFMpegPath; + + var parentPath = Path.Combine(ConfigurationManager.ApplicationPaths.ProgramDataPath, "ffmpeg", "20160410"); - return FileSystem.ContainsSubPath(parentPath, path); + return FileSystem.ContainsSubPath(parentPath, path); + } } private bool IsSystemInstalledPath(string path) diff --git a/MediaBrowser.Model/Configuration/UserConfiguration.cs b/MediaBrowser.Model/Configuration/UserConfiguration.cs index 69dc23b21c..b081e29737 100644 --- a/MediaBrowser.Model/Configuration/UserConfiguration.cs +++ b/MediaBrowser.Model/Configuration/UserConfiguration.cs @@ -48,7 +48,6 @@ namespace MediaBrowser.Model.Configuration public bool RememberAudioSelections { get; set; } public bool RememberSubtitleSelections { get; set; } public bool EnableNextEpisodeAutoPlay { get; set; } - public bool DisplayFoldersView { get; set; } /// /// Initializes a new instance of the class. diff --git a/MediaBrowser.Providers/MediaInfo/AudioImageProvider.cs b/MediaBrowser.Providers/MediaInfo/AudioImageProvider.cs index 6c79189887..027341ee6a 100644 --- a/MediaBrowser.Providers/MediaInfo/AudioImageProvider.cs +++ b/MediaBrowser.Providers/MediaInfo/AudioImageProvider.cs @@ -167,10 +167,13 @@ namespace MediaBrowser.Providers.MediaInfo public bool HasChanged(IHasMetadata item, IDirectoryService directoryService) { - var file = directoryService.GetFile(item.Path); - if (file != null && file.LastWriteTimeUtc != item.DateModified) + if (item.EnableRefreshOnDateModifiedChange && !string.IsNullOrWhiteSpace(item.Path) && item.LocationType == LocationType.FileSystem) { - return true; + var file = directoryService.GetFile(item.Path); + if (file != null && file.LastWriteTimeUtc != item.DateModified) + { + return true; + } } return false; diff --git a/MediaBrowser.Providers/MediaInfo/FFProbeProvider.cs b/MediaBrowser.Providers/MediaInfo/FFProbeProvider.cs index 0df8b6c4b7..d255110fb7 100644 --- a/MediaBrowser.Providers/MediaInfo/FFProbeProvider.cs +++ b/MediaBrowser.Providers/MediaInfo/FFProbeProvider.cs @@ -171,7 +171,7 @@ namespace MediaBrowser.Providers.MediaInfo public bool HasChanged(IHasMetadata item, IDirectoryService directoryService) { - if (item.EnableRefreshOnDateModifiedChange && !string.IsNullOrWhiteSpace(item.Path)) + if (item.EnableRefreshOnDateModifiedChange && !string.IsNullOrWhiteSpace(item.Path) && item.LocationType == LocationType.FileSystem) { var file = directoryService.GetFile(item.Path); if (file != null && file.LastWriteTimeUtc != item.DateModified) diff --git a/MediaBrowser.Providers/MediaInfo/VideoImageProvider.cs b/MediaBrowser.Providers/MediaInfo/VideoImageProvider.cs index 280e92beb9..2ad02da2ef 100644 --- a/MediaBrowser.Providers/MediaInfo/VideoImageProvider.cs +++ b/MediaBrowser.Providers/MediaInfo/VideoImageProvider.cs @@ -194,7 +194,7 @@ namespace MediaBrowser.Providers.MediaInfo public bool HasChanged(IHasMetadata item, IDirectoryService directoryService) { - if (item.EnableRefreshOnDateModifiedChange) + if (item.EnableRefreshOnDateModifiedChange && !string.IsNullOrWhiteSpace(item.Path) && item.LocationType == LocationType.FileSystem) { var file = directoryService.GetFile(item.Path); if (file != null && file.LastWriteTimeUtc != item.DateModified) diff --git a/MediaBrowser.Providers/Photos/PhotoProvider.cs b/MediaBrowser.Providers/Photos/PhotoProvider.cs index 619b726368..c48c3d09be 100644 --- a/MediaBrowser.Providers/Photos/PhotoProvider.cs +++ b/MediaBrowser.Providers/Photos/PhotoProvider.cs @@ -154,10 +154,13 @@ namespace MediaBrowser.Providers.Photos public bool HasChanged(IHasMetadata item, IDirectoryService directoryService) { - var file = directoryService.GetFile(item.Path); - if (file != null && file.LastWriteTimeUtc != item.DateModified) + if (item.EnableRefreshOnDateModifiedChange && !string.IsNullOrWhiteSpace(item.Path) && item.LocationType == LocationType.FileSystem) { - return true; + var file = directoryService.GetFile(item.Path); + if (file != null && file.LastWriteTimeUtc != item.DateModified) + { + return true; + } } return false; diff --git a/MediaBrowser.Server.Implementations/Persistence/CleanDatabaseScheduledTask.cs b/MediaBrowser.Server.Implementations/Persistence/CleanDatabaseScheduledTask.cs index bf2afb5ace..c1394ee1c3 100644 --- a/MediaBrowser.Server.Implementations/Persistence/CleanDatabaseScheduledTask.cs +++ b/MediaBrowser.Server.Implementations/Persistence/CleanDatabaseScheduledTask.cs @@ -313,8 +313,7 @@ namespace MediaBrowser.Server.Implementations.Persistence if (Folder.IsPathOffline(path)) { - libraryItem.IsOffline = true; - await libraryItem.UpdateToRepository(ItemUpdateType.None, cancellationToken).ConfigureAwait(false); + await libraryItem.UpdateIsOffline(true).ConfigureAwait(false); continue; } diff --git a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs index b9befb531e..5c94d589dc 100644 --- a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs +++ b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs @@ -211,7 +211,6 @@ namespace MediaBrowser.Server.Implementations.Persistence _connection.AddColumn(Logger, "TypedBaseItems", "ProductionYear", "INT"); _connection.AddColumn(Logger, "TypedBaseItems", "ParentId", "GUID"); _connection.AddColumn(Logger, "TypedBaseItems", "Genres", "Text"); - _connection.AddColumn(Logger, "TypedBaseItems", "ParentalRatingValue", "INT"); _connection.AddColumn(Logger, "TypedBaseItems", "SchemaVersion", "INT"); _connection.AddColumn(Logger, "TypedBaseItems", "SortName", "Text"); _connection.AddColumn(Logger, "TypedBaseItems", "RunTimeTicks", "BIGINT"); @@ -488,7 +487,6 @@ namespace MediaBrowser.Server.Implementations.Persistence "ProductionYear", "ParentId", "Genres", - "ParentalRatingValue", "InheritedParentalRatingValue", "SchemaVersion", "SortName", @@ -795,7 +793,6 @@ namespace MediaBrowser.Server.Implementations.Persistence } _saveItemCommand.GetParameter(index++).Value = string.Join("|", item.Genres.ToArray()); - _saveItemCommand.GetParameter(index++).Value = item.GetParentalRatingValue() ?? 0; _saveItemCommand.GetParameter(index++).Value = item.GetInheritedParentalRatingValue() ?? 0; _saveItemCommand.GetParameter(index++).Value = LatestSchemaVersion; diff --git a/MediaBrowser.Server.Startup.Common/ApplicationHost.cs b/MediaBrowser.Server.Startup.Common/ApplicationHost.cs index 8516e54ee9..75f2d24270 100644 --- a/MediaBrowser.Server.Startup.Common/ApplicationHost.cs +++ b/MediaBrowser.Server.Startup.Common/ApplicationHost.cs @@ -386,7 +386,6 @@ namespace MediaBrowser.Server.Startup.Common new MovieDbEpisodeProviderMigration(ServerConfigurationManager), new DbMigration(ServerConfigurationManager, TaskManager), new UpdateLevelMigration(ServerConfigurationManager, this, HttpClient, JsonSerializer, _releaseAssetFilename), - new FolderViewSettingMigration(ServerConfigurationManager, UserManager), new CollectionGroupingMigration(ServerConfigurationManager, UserManager), new CollectionsViewMigration(ServerConfigurationManager, UserManager) }; diff --git a/MediaBrowser.Server.Startup.Common/MediaBrowser.Server.Startup.Common.csproj b/MediaBrowser.Server.Startup.Common/MediaBrowser.Server.Startup.Common.csproj index 979a3a3577..bbef5caeae 100644 --- a/MediaBrowser.Server.Startup.Common/MediaBrowser.Server.Startup.Common.csproj +++ b/MediaBrowser.Server.Startup.Common/MediaBrowser.Server.Startup.Common.csproj @@ -72,7 +72,6 @@ - diff --git a/MediaBrowser.Server.Startup.Common/Migrations/FolderViewSettingMigration.cs b/MediaBrowser.Server.Startup.Common/Migrations/FolderViewSettingMigration.cs deleted file mode 100644 index 12054864b3..0000000000 --- a/MediaBrowser.Server.Startup.Common/Migrations/FolderViewSettingMigration.cs +++ /dev/null @@ -1,40 +0,0 @@ -using System.Linq; -using MediaBrowser.Controller.Configuration; -using MediaBrowser.Controller.Library; - -namespace MediaBrowser.Server.Startup.Common.Migrations -{ - public class FolderViewSettingMigration : IVersionMigration - { - private readonly IServerConfigurationManager _config; - private readonly IUserManager _userManager; - - public FolderViewSettingMigration(IServerConfigurationManager config, IUserManager userManager) - { - _config = config; - _userManager = userManager; - } - - public void Run() - { - var migrationKey = this.GetType().Name; - var migrationKeyList = _config.Configuration.Migrations.ToList(); - - if (!migrationKeyList.Contains(migrationKey)) - { - if (_config.Configuration.IsStartupWizardCompleted) - { - if (_userManager.Users.Any(i => i.Configuration.DisplayFoldersView)) - { - _config.Configuration.EnableFolderView = true; - } - } - - migrationKeyList.Add(migrationKey); - _config.Configuration.Migrations = migrationKeyList.ToArray(); - _config.SaveConfiguration(); - } - - } - } -} -- cgit v1.2.3 From c46e38725e40171639d6b1fec930081be129a1bc Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Wed, 24 Aug 2016 16:46:26 -0400 Subject: support realtime monitor per library --- .../Entities/CollectionFolder.cs | 1 + MediaBrowser.Model/Configuration/LibraryOptions.cs | 3 ++ .../IO/LibraryMonitor.cs | 40 ++++++++++++---------- 3 files changed, 25 insertions(+), 19 deletions(-) (limited to 'MediaBrowser.Server.Implementations') diff --git a/MediaBrowser.Controller/Entities/CollectionFolder.cs b/MediaBrowser.Controller/Entities/CollectionFolder.cs index e120f2e23d..597ecf973a 100644 --- a/MediaBrowser.Controller/Entities/CollectionFolder.cs +++ b/MediaBrowser.Controller/Entities/CollectionFolder.cs @@ -106,6 +106,7 @@ namespace MediaBrowser.Controller.Entities { LibraryOptions[path] = options; + options.SchemaVersion = 1; XmlSerializer.SerializeToFile(options, GetLibraryOptionsPath(path)); } } diff --git a/MediaBrowser.Model/Configuration/LibraryOptions.cs b/MediaBrowser.Model/Configuration/LibraryOptions.cs index e15df37c1a..3fe694553a 100644 --- a/MediaBrowser.Model/Configuration/LibraryOptions.cs +++ b/MediaBrowser.Model/Configuration/LibraryOptions.cs @@ -4,10 +4,13 @@ { public bool EnableArchiveMediaFiles { get; set; } public bool EnablePhotos { get; set; } + public bool EnableRealtimeMonitor { get; set; } + public int SchemaVersion { get; set; } public LibraryOptions() { EnablePhotos = true; + EnableRealtimeMonitor = true; } } } diff --git a/MediaBrowser.Server.Implementations/IO/LibraryMonitor.cs b/MediaBrowser.Server.Implementations/IO/LibraryMonitor.cs index ea9e58ee47..7ed4dc71ef 100644 --- a/MediaBrowser.Server.Implementations/IO/LibraryMonitor.cs +++ b/MediaBrowser.Server.Implementations/IO/LibraryMonitor.cs @@ -172,27 +172,29 @@ namespace MediaBrowser.Server.Implementations.IO } } - public void Start() + private bool IsLibraryMonitorEnabaled(BaseItem item) { - if (EnableLibraryMonitor) + var options = LibraryManager.GetLibraryOptions(item); + + if (options != null && options.SchemaVersion >= 1) { - StartInternal(); + return options.EnableRealtimeMonitor; } + + return EnableLibraryMonitor; } - /// - /// Starts this instance. - /// - private void StartInternal() + public void Start() { LibraryManager.ItemAdded += LibraryManager_ItemAdded; LibraryManager.ItemRemoved += LibraryManager_ItemRemoved; - var pathsToWatch = new List { LibraryManager.RootFolder.Path }; + var pathsToWatch = new List { }; var paths = LibraryManager .RootFolder .Children + .Where(IsLibraryMonitorEnabaled) .OfType() .SelectMany(f => f.PhysicalLocations) .Distinct(StringComparer.OrdinalIgnoreCase) @@ -213,6 +215,14 @@ namespace MediaBrowser.Server.Implementations.IO } } + private void StartWatching(BaseItem item) + { + if (IsLibraryMonitorEnabaled(item)) + { + StartWatchingPath(item.Path); + } + } + /// /// Handles the ItemRemoved event of the LibraryManager control. /// @@ -235,7 +245,7 @@ namespace MediaBrowser.Server.Implementations.IO { if (e.Item.GetParent() is AggregateFolder) { - StartWatchingPath(e.Item.Path); + StartWatching(e.Item); } } @@ -382,14 +392,6 @@ namespace MediaBrowser.Server.Implementations.IO Logger.ErrorException("Error in Directory watcher for: " + dw.Path, ex); DisposeWatcher(dw); - - if (ConfigurationManager.Configuration.EnableLibraryMonitor == AutoOnOff.Auto) - { - Logger.Info("Disabling realtime monitor to prevent future instability"); - - ConfigurationManager.Configuration.EnableLibraryMonitor = AutoOnOff.Disabled; - Stop(); - } } /// @@ -420,8 +422,8 @@ namespace MediaBrowser.Server.Implementations.IO var filename = Path.GetFileName(path); - var monitorPath = !string.IsNullOrEmpty(filename) && - !_alwaysIgnoreFiles.Contains(filename, StringComparer.OrdinalIgnoreCase) && + var monitorPath = !string.IsNullOrEmpty(filename) && + !_alwaysIgnoreFiles.Contains(filename, StringComparer.OrdinalIgnoreCase) && !_alwaysIgnoreExtensions.Contains(Path.GetExtension(path) ?? string.Empty, StringComparer.OrdinalIgnoreCase); // Ignore certain files -- cgit v1.2.3 From 93a05271c21496c4df213f1761ddbfae6ffa0b34 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Thu, 25 Aug 2016 12:55:57 -0400 Subject: fix notifications query --- MediaBrowser.Api/Reports/ReportsService.cs | 2 -- .../UserLibrary/BaseItemsByNameService.cs | 2 -- MediaBrowser.Api/UserLibrary/ItemsService.cs | 20 -------------------- MediaBrowser.Controller/Entities/Folder.cs | 6 +++--- MediaBrowser.Model/Querying/ItemFilter.cs | 4 ---- .../Library/Resolvers/Movies/MovieResolver.cs | 6 ------ 6 files changed, 3 insertions(+), 37 deletions(-) (limited to 'MediaBrowser.Server.Implementations') diff --git a/MediaBrowser.Api/Reports/ReportsService.cs b/MediaBrowser.Api/Reports/ReportsService.cs index d0b6d6e787..cb03d93822 100644 --- a/MediaBrowser.Api/Reports/ReportsService.cs +++ b/MediaBrowser.Api/Reports/ReportsService.cs @@ -275,8 +275,6 @@ namespace MediaBrowser.Api.Reports case ItemFilter.IsPlayed: query.IsPlayed = true; break; - case ItemFilter.IsRecentlyAdded: - break; case ItemFilter.IsResumable: query.IsResumable = true; break; diff --git a/MediaBrowser.Api/UserLibrary/BaseItemsByNameService.cs b/MediaBrowser.Api/UserLibrary/BaseItemsByNameService.cs index 94a6a7ef13..5381f9004c 100644 --- a/MediaBrowser.Api/UserLibrary/BaseItemsByNameService.cs +++ b/MediaBrowser.Api/UserLibrary/BaseItemsByNameService.cs @@ -164,8 +164,6 @@ namespace MediaBrowser.Api.UserLibrary case ItemFilter.IsPlayed: query.IsPlayed = true; break; - case ItemFilter.IsRecentlyAdded: - break; case ItemFilter.IsResumable: query.IsResumable = true; break; diff --git a/MediaBrowser.Api/UserLibrary/ItemsService.cs b/MediaBrowser.Api/UserLibrary/ItemsService.cs index ce7905b42f..681624ba22 100644 --- a/MediaBrowser.Api/UserLibrary/ItemsService.cs +++ b/MediaBrowser.Api/UserLibrary/ItemsService.cs @@ -149,24 +149,6 @@ namespace MediaBrowser.Api.UserLibrary item = user == null ? _libraryManager.RootFolder : user.RootFolder; } - if (!string.IsNullOrEmpty(request.Ids)) - { - var query = GetItemsQuery(request, user); - var specificItems = _libraryManager.GetItemList(query).ToArray(); - if (query.SortBy.Length == 0) - { - var ids = query.ItemIds.ToList(); - - // Try to preserve order - specificItems = specificItems.OrderBy(i => ids.IndexOf(i.Id.ToString("N"))).ToArray(); - } - return new QueryResult - { - Items = specificItems.ToArray(), - TotalRecordCount = specificItems.Length - }; - } - // Default list type = children var folder = item as Folder; @@ -289,8 +271,6 @@ namespace MediaBrowser.Api.UserLibrary case ItemFilter.IsPlayed: query.IsPlayed = true; break; - case ItemFilter.IsRecentlyAdded: - break; case ItemFilter.IsResumable: query.IsResumable = true; break; diff --git a/MediaBrowser.Controller/Entities/Folder.cs b/MediaBrowser.Controller/Entities/Folder.cs index bea648a3d3..bf47ada0dc 100644 --- a/MediaBrowser.Controller/Entities/Folder.cs +++ b/MediaBrowser.Controller/Entities/Folder.cs @@ -891,16 +891,16 @@ namespace MediaBrowser.Controller.Entities { if (query.ItemIds.Length > 0) { - var specificItems = query.ItemIds.Select(LibraryManager.GetItemById).Where(i => i != null).ToList(); + var result = LibraryManager.GetItemsResult(query); if (query.SortBy.Length == 0) { var ids = query.ItemIds.ToList(); // Try to preserve order - specificItems = specificItems.OrderBy(i => ids.IndexOf(i.Id.ToString("N"))).ToList(); + result.Items = result.Items.OrderBy(i => ids.IndexOf(i.Id.ToString("N"))).ToArray(); } - return Task.FromResult(PostFilterAndSort(specificItems, query, true, true)); + return Task.FromResult(result); } return GetItemsInternal(query); diff --git a/MediaBrowser.Model/Querying/ItemFilter.cs b/MediaBrowser.Model/Querying/ItemFilter.cs index 83d61ae514..ff28bd08c4 100644 --- a/MediaBrowser.Model/Querying/ItemFilter.cs +++ b/MediaBrowser.Model/Querying/ItemFilter.cs @@ -27,10 +27,6 @@ namespace MediaBrowser.Model.Querying /// IsFavorite = 5, /// - /// The is recently added - /// - IsRecentlyAdded = 6, - /// /// The item is resumable /// IsResumable = 7, diff --git a/MediaBrowser.Server.Implementations/Library/Resolvers/Movies/MovieResolver.cs b/MediaBrowser.Server.Implementations/Library/Resolvers/Movies/MovieResolver.cs index 6558407538..ee9533d2ac 100644 --- a/MediaBrowser.Server.Implementations/Library/Resolvers/Movies/MovieResolver.cs +++ b/MediaBrowser.Server.Implementations/Library/Resolvers/Movies/MovieResolver.cs @@ -203,12 +203,6 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers.Movies /// Video. protected override Video Resolve(ItemResolveArgs args) { - if (args.Path != null && args.Path.IndexOf("disney", StringComparison.OrdinalIgnoreCase) != -1) - { - var b = true; - var a = b; - } - var collectionType = args.GetCollectionType(); if (IsInvalid(args.Parent, collectionType)) -- cgit v1.2.3