From 77695f8abed3156de04c6bb2496c14a2ab3d90a8 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Tue, 21 Nov 2017 17:14:56 -0500 Subject: 3.2.40.1 --- .../EntryPoints/StartupWizard.cs | 25 +++++++++------------- 1 file changed, 10 insertions(+), 15 deletions(-) (limited to 'Emby.Server.Implementations/EntryPoints') diff --git a/Emby.Server.Implementations/EntryPoints/StartupWizard.cs b/Emby.Server.Implementations/EntryPoints/StartupWizard.cs index 614c04fd22..8d13557952 100644 --- a/Emby.Server.Implementations/EntryPoints/StartupWizard.cs +++ b/Emby.Server.Implementations/EntryPoints/StartupWizard.cs @@ -3,6 +3,7 @@ using Emby.Server.Implementations.Browser; using MediaBrowser.Controller; using MediaBrowser.Controller.Plugins; using MediaBrowser.Model.Logging; +using MediaBrowser.Controller.Configuration; namespace Emby.Server.Implementations.EntryPoints { @@ -20,15 +21,13 @@ namespace Emby.Server.Implementations.EntryPoints /// private readonly ILogger _logger; - /// - /// Initializes a new instance of the class. - /// - /// The app host. - /// The logger. - public StartupWizard(IServerApplicationHost appHost, ILogger logger) + private IServerConfigurationManager _config; + + public StartupWizard(IServerApplicationHost appHost, ILogger logger, IServerConfigurationManager config) { _appHost = appHost; _logger = logger; + _config = config; } /// @@ -38,16 +37,12 @@ namespace Emby.Server.Implementations.EntryPoints { if (_appHost.IsFirstRun) { - LaunchStartupWizard(); + BrowserLauncher.OpenDashboardPage("wizardstart.html", _appHost); + } + else if (_config.Configuration.IsStartupWizardCompleted) + { + BrowserLauncher.OpenDashboardPage("index.html", _appHost); } - } - - /// - /// Launches the startup wizard. - /// - private void LaunchStartupWizard() - { - BrowserLauncher.OpenDashboardPage("wizardstart.html", _appHost); } /// -- cgit v1.2.3 From 4f09c1e06dab7cc8b260129648f5a54c77b8a4f9 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Thu, 23 Nov 2017 10:46:16 -0500 Subject: reduce dlna chatter --- Emby.Dlna/Main/DlnaEntryPoint.cs | 3 +- Emby.Dlna/PlayTo/Device.cs | 16 +- Emby.Dlna/PlayTo/PlayToManager.cs | 194 +++++++++++---------- Emby.Dlna/PlayTo/SsdpHttpClient.cs | 7 +- Emby.Server.Implementations/ApplicationHost.cs | 22 ++- .../EntryPoints/ExternalPortForwarding.cs | 3 +- .../Library/SearchEngine.cs | 3 +- Emby.Server.Implementations/Library/UserManager.cs | 2 +- .../LiveTv/LiveTvMediaSourceProvider.cs | 2 +- .../Networking/NetworkManager.cs | 10 +- .../Session/SessionManager.cs | 2 +- .../Social/SharingManager.cs | 5 +- Emby.Server.Implementations/Udp/UdpServer.cs | 28 +-- .../ScheduledTasksWebSocketListener.cs | 5 +- MediaBrowser.Api/SearchService.cs | 13 +- .../Session/SessionInfoWebSocketListener.cs | 5 +- .../System/ActivityLogWebSocketListener.cs | 3 +- .../System/SystemInfoWebSocketListener.cs | 5 +- MediaBrowser.Api/System/SystemService.cs | 5 +- MediaBrowser.Controller/IServerApplicationHost.cs | 7 +- .../Net/BasePeriodicWebSocketListener.cs | 8 +- MediaBrowser.Controller/Sync/ISyncManager.cs | 2 +- MediaBrowser.Model/Dlna/StreamBuilder.cs | 2 +- MediaBrowser.Model/Search/SearchHint.cs | 1 + MediaBrowser.WebDashboard/Api/PackageCreator.cs | 11 +- SharedVersion.cs | 2 +- 26 files changed, 215 insertions(+), 151 deletions(-) (limited to 'Emby.Server.Implementations/EntryPoints') diff --git a/Emby.Dlna/Main/DlnaEntryPoint.cs b/Emby.Dlna/Main/DlnaEntryPoint.cs index 3dd36a27bc..5eeab3decf 100644 --- a/Emby.Dlna/Main/DlnaEntryPoint.cs +++ b/Emby.Dlna/Main/DlnaEntryPoint.cs @@ -24,6 +24,7 @@ using MediaBrowser.Model.System; using MediaBrowser.Model.Threading; using Rssdp; using Rssdp.Infrastructure; +using System.Threading; namespace Emby.Dlna.Main { @@ -252,7 +253,7 @@ namespace Emby.Dlna.Main var cacheLength = _config.GetDlnaConfiguration().BlastAliveMessageIntervalSeconds; _Publisher.SupportPnpRootDevice = false; - var addresses = (await _appHost.GetLocalIpAddresses().ConfigureAwait(false)).ToList(); + var addresses = (await _appHost.GetLocalIpAddresses(CancellationToken.None).ConfigureAwait(false)).ToList(); var udn = CreateUuid(_appHost.SystemId); diff --git a/Emby.Dlna/PlayTo/Device.cs b/Emby.Dlna/PlayTo/Device.cs index 165f123f17..a617117f3c 100644 --- a/Emby.Dlna/PlayTo/Device.cs +++ b/Emby.Dlna/PlayTo/Device.cs @@ -831,7 +831,7 @@ namespace Emby.Dlna.PlayTo #region From XML - private async Task GetAVProtocolAsync() + private async Task GetAVProtocolAsync(CancellationToken cancellationToken) { if (_disposed) { @@ -845,12 +845,12 @@ namespace Emby.Dlna.PlayTo string url = NormalizeUrl(Properties.BaseUrl, avService.ScpdUrl); var httpClient = new SsdpHttpClient(_httpClient, _config); - var document = await httpClient.GetDataAsync(url).ConfigureAwait(false); + var document = await httpClient.GetDataAsync(url, cancellationToken).ConfigureAwait(false); AvCommands = TransportCommands.Create(document); } - private async Task GetRenderingProtocolAsync() + private async Task GetRenderingProtocolAsync(CancellationToken cancellationToken) { if (_disposed) { @@ -864,7 +864,7 @@ namespace Emby.Dlna.PlayTo string url = NormalizeUrl(Properties.BaseUrl, avService.ScpdUrl); var httpClient = new SsdpHttpClient(_httpClient, _config); - var document = await httpClient.GetDataAsync(url).ConfigureAwait(false); + var document = await httpClient.GetDataAsync(url, cancellationToken).ConfigureAwait(false); RendererCommands = TransportCommands.Create(document); } @@ -897,11 +897,11 @@ namespace Emby.Dlna.PlayTo set; } - public static async Task CreateuPnpDeviceAsync(Uri url, IHttpClient httpClient, IServerConfigurationManager config, ILogger logger, ITimerFactory timerFactory) + public static async Task CreateuPnpDeviceAsync(Uri url, IHttpClient httpClient, IServerConfigurationManager config, ILogger logger, ITimerFactory timerFactory, CancellationToken cancellationToken) { var ssdpHttpClient = new SsdpHttpClient(httpClient, config); - var document = await ssdpHttpClient.GetDataAsync(url.ToString()).ConfigureAwait(false); + var document = await ssdpHttpClient.GetDataAsync(url.ToString(), cancellationToken).ConfigureAwait(false); var deviceProperties = new DeviceInfo(); @@ -987,8 +987,8 @@ namespace Emby.Dlna.PlayTo if (device.GetAvTransportService() != null) { - await device.GetRenderingProtocolAsync().ConfigureAwait(false); - await device.GetAVProtocolAsync().ConfigureAwait(false); + await device.GetRenderingProtocolAsync(cancellationToken).ConfigureAwait(false); + await device.GetAVProtocolAsync(cancellationToken).ConfigureAwait(false); } return device; diff --git a/Emby.Dlna/PlayTo/PlayToManager.cs b/Emby.Dlna/PlayTo/PlayToManager.cs index dd30dfc3d9..f1b7181dda 100644 --- a/Emby.Dlna/PlayTo/PlayToManager.cs +++ b/Emby.Dlna/PlayTo/PlayToManager.cs @@ -18,6 +18,7 @@ using MediaBrowser.Model.Events; using MediaBrowser.Model.Globalization; using MediaBrowser.Model.Net; using MediaBrowser.Model.Threading; +using System.Threading; namespace Emby.Dlna.PlayTo { @@ -44,6 +45,8 @@ namespace Emby.Dlna.PlayTo private readonly List _nonRendererUrls = new List(); private DateTime _lastRendererClear; private bool _disposed; + private SemaphoreSlim _sessionLock = new SemaphoreSlim(1, 1); + private CancellationTokenSource _disposeCancellationTokenSource = new CancellationTokenSource(); public PlayToManager(ILogger logger, ISessionManager sessionManager, ILibraryManager libraryManager, IUserManager userManager, IDlnaManager dlnaManager, IServerApplicationHost appHost, IImageProcessor imageProcessor, IDeviceDiscovery deviceDiscovery, IHttpClient httpClient, IServerConfigurationManager config, IUserDataManager userDataManager, ILocalizationManager localization, IMediaSourceManager mediaSourceManager, IMediaEncoder mediaEncoder, ITimerFactory timerFactory) { @@ -98,92 +101,104 @@ namespace Emby.Dlna.PlayTo return; } + var cancellationToken = _disposeCancellationTokenSource.Token; + + await _sessionLock.WaitAsync(cancellationToken).ConfigureAwait(false); + try { - lock (_nonRendererUrls) + if (_disposed) { - if ((DateTime.UtcNow - _lastRendererClear).TotalMinutes >= 10) - { - _nonRendererUrls.Clear(); - _lastRendererClear = DateTime.UtcNow; - } - - if (_nonRendererUrls.Contains(location, StringComparer.OrdinalIgnoreCase)) - { - return; - } + return; } - var uri = info.Location; - _logger.Debug("Attempting to create PlayToController from location {0}", location); - var device = await Device.CreateuPnpDeviceAsync(uri, _httpClient, _config, _logger, _timerFactory).ConfigureAwait(false); + await AddDevice(info, location, cancellationToken).ConfigureAwait(false); + } + catch (OperationCanceledException) + { + + } + catch (Exception ex) + { + _logger.ErrorException("Error creating PlayTo device.", ex); + + _nonRendererUrls.Add(location); + } + finally + { + _sessionLock.Release(); + } + } + + private async Task AddDevice(UpnpDeviceInfo info, string location, CancellationToken cancellationToken) + { + if ((DateTime.UtcNow - _lastRendererClear).TotalMinutes >= 10) + { + _nonRendererUrls.Clear(); + _lastRendererClear = DateTime.UtcNow; + } + + if (_nonRendererUrls.Contains(location, StringComparer.OrdinalIgnoreCase)) + { + return; + } + + var uri = info.Location; + _logger.Debug("Attempting to create PlayToController from location {0}", location); + var device = await Device.CreateuPnpDeviceAsync(uri, _httpClient, _config, _logger, _timerFactory, cancellationToken).ConfigureAwait(false); + + if (device.RendererCommands == null) + { + _nonRendererUrls.Add(location); + return; + } + + _logger.Debug("Logging session activity from location {0}", location); + var sessionInfo = await _sessionManager.LogSessionActivity(device.Properties.ClientType, _appHost.ApplicationVersion.ToString(), device.Properties.UUID, device.Properties.Name, uri.OriginalString, null).ConfigureAwait(false); + + var controller = sessionInfo.SessionController as PlayToController; - if (device.RendererCommands == null) + if (controller == null) + { + string serverAddress; + if (info.LocalIpAddress == null || info.LocalIpAddress.Equals(IpAddressInfo.Any) || info.LocalIpAddress.Equals(IpAddressInfo.IPv6Loopback)) { - lock (_nonRendererUrls) - { - _nonRendererUrls.Add(location); - return; - } + serverAddress = await GetServerAddress(null, cancellationToken).ConfigureAwait(false); } - - if (_disposed) + else { - return; + serverAddress = await GetServerAddress(info.LocalIpAddress, cancellationToken).ConfigureAwait(false); } - _logger.Debug("Logging session activity from location {0}", location); - var sessionInfo = await _sessionManager.LogSessionActivity(device.Properties.ClientType, _appHost.ApplicationVersion.ToString(), device.Properties.UUID, device.Properties.Name, uri.OriginalString, null) - .ConfigureAwait(false); - - var controller = sessionInfo.SessionController as PlayToController; - - if (controller == null) + string accessToken = null; + + sessionInfo.SessionController = controller = new PlayToController(sessionInfo, + _sessionManager, + _libraryManager, + _logger, + _dlnaManager, + _userManager, + _imageProcessor, + serverAddress, + accessToken, + _deviceDiscovery, + _userDataManager, + _localization, + _mediaSourceManager, + _config, + _mediaEncoder); + + controller.Init(device); + + var profile = _dlnaManager.GetProfile(device.Properties.ToDeviceIdentification()) ?? + _dlnaManager.GetDefaultProfile(); + + _sessionManager.ReportCapabilities(sessionInfo.Id, new ClientCapabilities { - if (_disposed) - { - return; - } + PlayableMediaTypes = profile.GetSupportedMediaTypes(), - string serverAddress; - if (info.LocalIpAddress == null || info.LocalIpAddress.Equals(IpAddressInfo.Any) || info.LocalIpAddress.Equals(IpAddressInfo.IPv6Loopback)) + SupportedCommands = new string[] { - serverAddress = await GetServerAddress(null).ConfigureAwait(false); - } - else - { - serverAddress = await GetServerAddress(info.LocalIpAddress).ConfigureAwait(false); - } - - string accessToken = null; - - sessionInfo.SessionController = controller = new PlayToController(sessionInfo, - _sessionManager, - _libraryManager, - _logger, - _dlnaManager, - _userManager, - _imageProcessor, - serverAddress, - accessToken, - _deviceDiscovery, - _userDataManager, - _localization, - _mediaSourceManager, - _config, - _mediaEncoder); - - controller.Init(device); - - var profile = _dlnaManager.GetProfile(device.Properties.ToDeviceIdentification()) ?? - _dlnaManager.GetDefaultProfile(); - - _sessionManager.ReportCapabilities(sessionInfo.Id, new ClientCapabilities - { - PlayableMediaTypes = profile.GetSupportedMediaTypes(), - - SupportedCommands = new string[] - { GeneralCommandType.VolumeDown.ToString(), GeneralCommandType.VolumeUp.ToString(), GeneralCommandType.Mute.ToString(), @@ -192,33 +207,23 @@ namespace Emby.Dlna.PlayTo GeneralCommandType.SetVolume.ToString(), GeneralCommandType.SetAudioStreamIndex.ToString(), GeneralCommandType.SetSubtitleStreamIndex.ToString() - }, + }, - SupportsMediaControl = true, + SupportsMediaControl = true, - // xbox one creates a new uuid everytime it restarts - SupportsPersistentIdentifier = (device.Properties.ModelName ?? string.Empty).IndexOf("xbox", StringComparison.OrdinalIgnoreCase) == -1 - }); + // xbox one creates a new uuid everytime it restarts + SupportsPersistentIdentifier = (device.Properties.ModelName ?? string.Empty).IndexOf("xbox", StringComparison.OrdinalIgnoreCase) == -1 + }); - _logger.Info("DLNA Session created for {0} - {1}", device.Properties.Name, device.Properties.ModelName); - } - } - catch (Exception ex) - { - _logger.ErrorException("Error creating PlayTo device.", ex); - - lock (_nonRendererUrls) - { - _nonRendererUrls.Add(location); - } + _logger.Info("DLNA Session created for {0} - {1}", device.Properties.Name, device.Properties.ModelName); } } - private Task GetServerAddress(IpAddressInfo address) + private Task GetServerAddress(IpAddressInfo address, CancellationToken cancellationToken) { if (address == null) { - return _appHost.GetLocalApiUrl(); + return _appHost.GetLocalApiUrl(cancellationToken); } return Task.FromResult(_appHost.GetLocalApiUrl(address)); @@ -226,6 +231,15 @@ namespace Emby.Dlna.PlayTo public void Dispose() { + try + { + _disposeCancellationTokenSource.Cancel(); + } + catch + { + + } + _disposed = true; _deviceDiscovery.DeviceDiscovered -= _deviceDiscovery_DeviceDiscovered; GC.SuppressFinalize(this); diff --git a/Emby.Dlna/PlayTo/SsdpHttpClient.cs b/Emby.Dlna/PlayTo/SsdpHttpClient.cs index 78b688d92a..d4b5943674 100644 --- a/Emby.Dlna/PlayTo/SsdpHttpClient.cs +++ b/Emby.Dlna/PlayTo/SsdpHttpClient.cs @@ -7,6 +7,7 @@ using System.IO; using System.Text; using System.Threading.Tasks; using System.Xml.Linq; +using System.Threading; namespace Emby.Dlna.PlayTo { @@ -89,7 +90,7 @@ namespace Emby.Dlna.PlayTo } } - public async Task GetDataAsync(string url) + public async Task GetDataAsync(string url, CancellationToken cancellationToken) { var options = new HttpRequestOptions { @@ -99,7 +100,9 @@ namespace Emby.Dlna.PlayTo BufferContent = false, // The periodic requests may keep some devices awake - LogRequestAsDebug = true + LogRequestAsDebug = true, + + CancellationToken = cancellationToken }; options.RequestHeaders["FriendlyName.DLNA.ORG"] = FriendlyName; diff --git a/Emby.Server.Implementations/ApplicationHost.cs b/Emby.Server.Implementations/ApplicationHost.cs index 531e13123a..2e5c4be907 100644 --- a/Emby.Server.Implementations/ApplicationHost.cs +++ b/Emby.Server.Implementations/ApplicationHost.cs @@ -1901,9 +1901,9 @@ namespace Emby.Server.Implementations /// Gets the system status. /// /// SystemInfo. - public async Task GetSystemInfo() + public async Task GetSystemInfo(CancellationToken cancellationToken) { - var localAddress = await GetLocalApiUrl().ConfigureAwait(false); + var localAddress = await GetLocalApiUrl(cancellationToken).ConfigureAwait(false); return new SystemInfo { @@ -1955,12 +1955,12 @@ namespace Emby.Server.Implementations get { return Certificate != null || ServerConfigurationManager.Configuration.IsBehindProxy; } } - public async Task GetLocalApiUrl() + public async Task GetLocalApiUrl(CancellationToken cancellationToken) { try { // Return the first matched address, if found, or the first known local address - var address = (await GetLocalIpAddresses().ConfigureAwait(false)).FirstOrDefault(i => !i.Equals(IpAddressInfo.Loopback) && !i.Equals(IpAddressInfo.IPv6Loopback)); + var address = (await GetLocalIpAddresses(cancellationToken).ConfigureAwait(false)).FirstOrDefault(i => !i.Equals(IpAddressInfo.Loopback) && !i.Equals(IpAddressInfo.IPv6Loopback)); if (address != null) { @@ -1994,7 +1994,7 @@ namespace Emby.Server.Implementations HttpPort.ToString(CultureInfo.InvariantCulture)); } - public async Task> GetLocalIpAddresses() + public async Task> GetLocalIpAddresses(CancellationToken cancellationToken) { var addresses = ServerConfigurationManager .Configuration @@ -2011,7 +2011,7 @@ namespace Emby.Server.Implementations foreach (var address in addresses) { - var valid = await IsIpAddressValidAsync(address).ConfigureAwait(false); + var valid = await IsIpAddressValidAsync(address, cancellationToken).ConfigureAwait(false); if (valid) { list.Add(address); @@ -2043,7 +2043,7 @@ namespace Emby.Server.Implementations private readonly ConcurrentDictionary _validAddressResults = new ConcurrentDictionary(StringComparer.OrdinalIgnoreCase); private DateTime _lastAddressCacheClear; - private async Task IsIpAddressValidAsync(IpAddressInfo address) + private async Task IsIpAddressValidAsync(IpAddressInfo address, CancellationToken cancellationToken) { if (address.Equals(IpAddressInfo.Loopback) || address.Equals(IpAddressInfo.IPv6Loopback)) @@ -2075,7 +2075,9 @@ namespace Emby.Server.Implementations LogErrors = false, LogRequest = false, TimeoutMs = 30000, - BufferContent = false + BufferContent = false, + + CancellationToken = cancellationToken }, "POST").ConfigureAwait(false)) { @@ -2090,6 +2092,10 @@ namespace Emby.Server.Implementations } } } + catch (OperationCanceledException) + { + throw; + } catch { //Logger.Debug("Ping test result to {0}. Success: {1}", apiUrl, false); diff --git a/Emby.Server.Implementations/EntryPoints/ExternalPortForwarding.cs b/Emby.Server.Implementations/EntryPoints/ExternalPortForwarding.cs index 2cef468394..903bb0ff46 100644 --- a/Emby.Server.Implementations/EntryPoints/ExternalPortForwarding.cs +++ b/Emby.Server.Implementations/EntryPoints/ExternalPortForwarding.cs @@ -13,6 +13,7 @@ using MediaBrowser.Model.Logging; using MediaBrowser.Model.Threading; using Mono.Nat; using MediaBrowser.Model.Extensions; +using System.Threading; namespace Emby.Server.Implementations.EntryPoints { @@ -158,7 +159,7 @@ namespace Emby.Server.Implementations.EntryPoints try { - var localAddressString = await _appHost.GetLocalApiUrl().ConfigureAwait(false); + var localAddressString = await _appHost.GetLocalApiUrl(CancellationToken.None).ConfigureAwait(false); Uri uri; if (Uri.TryCreate(localAddressString, UriKind.Absolute, out uri)) diff --git a/Emby.Server.Implementations/Library/SearchEngine.cs b/Emby.Server.Implementations/Library/SearchEngine.cs index df21c14091..8021399bd8 100644 --- a/Emby.Server.Implementations/Library/SearchEngine.cs +++ b/Emby.Server.Implementations/Library/SearchEngine.cs @@ -191,7 +191,8 @@ namespace Emby.Server.Implementations.Library { ItemFields.AirTime, ItemFields.DateCreated, - ItemFields.ChannelInfo + ItemFields.ChannelInfo, + ItemFields.ParentId } } }; diff --git a/Emby.Server.Implementations/Library/UserManager.cs b/Emby.Server.Implementations/Library/UserManager.cs index c4e75add89..71c953b2cc 100644 --- a/Emby.Server.Implementations/Library/UserManager.cs +++ b/Emby.Server.Implementations/Library/UserManager.cs @@ -815,7 +815,7 @@ namespace Emby.Server.Implementations.Library var text = new StringBuilder(); - var localAddress = _appHost.GetLocalApiUrl().Result ?? string.Empty; + var localAddress = _appHost.GetLocalApiUrl(CancellationToken.None).Result ?? string.Empty; text.AppendLine("Use your web browser to visit:"); text.AppendLine(string.Empty); diff --git a/Emby.Server.Implementations/LiveTv/LiveTvMediaSourceProvider.cs b/Emby.Server.Implementations/LiveTv/LiveTvMediaSourceProvider.cs index ed8b3074b0..29b7c41ef2 100644 --- a/Emby.Server.Implementations/LiveTv/LiveTvMediaSourceProvider.cs +++ b/Emby.Server.Implementations/LiveTv/LiveTvMediaSourceProvider.cs @@ -95,7 +95,7 @@ namespace Emby.Server.Implementations.LiveTv } var list = sources.ToList(); - var serverUrl = await _appHost.GetLocalApiUrl().ConfigureAwait(false); + var serverUrl = await _appHost.GetLocalApiUrl(cancellationToken).ConfigureAwait(false); foreach (var source in list) { diff --git a/Emby.Server.Implementations/Networking/NetworkManager.cs b/Emby.Server.Implementations/Networking/NetworkManager.cs index fbdb5c128c..d938359e9e 100644 --- a/Emby.Server.Implementations/Networking/NetworkManager.cs +++ b/Emby.Server.Implementations/Networking/NetworkManager.cs @@ -11,6 +11,7 @@ using MediaBrowser.Model.Extensions; using MediaBrowser.Model.IO; using MediaBrowser.Model.Logging; using MediaBrowser.Model.Net; +using System.Threading; namespace Emby.Server.Implementations.Networking { @@ -37,7 +38,7 @@ namespace Emby.Server.Implementations.Networking if (_localIpAddresses == null || forceRefresh) { - var addresses = GetLocalIpAddressesInternal().Select(ToIpAddressInfo).ToList(); + var addresses = GetLocalIpAddressesInternal().Result.Select(ToIpAddressInfo).ToList(); _localIpAddresses = addresses; _lastRefresh = DateTime.UtcNow; @@ -49,14 +50,14 @@ namespace Emby.Server.Implementations.Networking return _localIpAddresses; } - private IEnumerable GetLocalIpAddressesInternal() + private async Task> GetLocalIpAddressesInternal() { var list = GetIPsDefault() .ToList(); if (list.Count == 0) { - list.AddRange(GetLocalIpAddressesFallback().Result); + list.AddRange(await GetLocalIpAddressesFallback().ConfigureAwait(false)); } var listClone = list.ToList(); @@ -65,7 +66,8 @@ namespace Emby.Server.Implementations.Networking .OrderBy(i => i.AddressFamily == AddressFamily.InterNetwork ? 0 : 1) .ThenBy(i => listClone.IndexOf(i)) .Where(FilterIpAddress) - .DistinctBy(i => i.ToString()); + .DistinctBy(i => i.ToString()) + .ToList(); } private bool FilterIpAddress(IPAddress address) diff --git a/Emby.Server.Implementations/Session/SessionManager.cs b/Emby.Server.Implementations/Session/SessionManager.cs index 411781b259..f49251da53 100644 --- a/Emby.Server.Implementations/Session/SessionManager.cs +++ b/Emby.Server.Implementations/Session/SessionManager.cs @@ -1182,7 +1182,7 @@ namespace Emby.Server.Implementations.Session { var sessions = Sessions.Where(i => i.IsActive && i.SessionController != null).ToList(); - var info = await _appHost.GetSystemInfo().ConfigureAwait(false); + var info = await _appHost.GetSystemInfo(cancellationToken).ConfigureAwait(false); var tasks = sessions.Select(session => Task.Run(async () => { diff --git a/Emby.Server.Implementations/Social/SharingManager.cs b/Emby.Server.Implementations/Social/SharingManager.cs index 57cf93948d..e94b9100a3 100644 --- a/Emby.Server.Implementations/Social/SharingManager.cs +++ b/Emby.Server.Implementations/Social/SharingManager.cs @@ -5,6 +5,7 @@ using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Library; using MediaBrowser.Model.Social; using System; +using System.Threading; using System.Threading.Tasks; namespace Emby.Server.Implementations.Social @@ -42,7 +43,7 @@ namespace Emby.Server.Implementations.Social throw new ResourceNotFoundException(); } - var externalUrl = (await _appHost.GetSystemInfo().ConfigureAwait(false)).WanAddress; + var externalUrl = (await _appHost.GetSystemInfo(CancellationToken.None).ConfigureAwait(false)).WanAddress; if (string.IsNullOrWhiteSpace(externalUrl)) { @@ -73,7 +74,7 @@ namespace Emby.Server.Implementations.Social { var info = _repository.GetShareInfo(id); - AddShareInfo(info, _appHost.GetSystemInfo().Result.WanAddress); + AddShareInfo(info, _appHost.GetSystemInfo(CancellationToken.None).Result.WanAddress); return info; } diff --git a/Emby.Server.Implementations/Udp/UdpServer.cs b/Emby.Server.Implementations/Udp/UdpServer.cs index 8dc1fae4be..28de80da16 100644 --- a/Emby.Server.Implementations/Udp/UdpServer.cs +++ b/Emby.Server.Implementations/Udp/UdpServer.cs @@ -25,7 +25,7 @@ namespace Emby.Server.Implementations.Udp private bool _isDisposed; - private readonly List>> _responders = new List>>(); + private readonly List>> _responders = new List>>(); private readonly IServerApplicationHost _appHost; private readonly IJsonSerializer _json; @@ -44,9 +44,9 @@ namespace Emby.Server.Implementations.Udp AddMessageResponder("who is MediaBrowserServer_v2?", false, RespondToV2Message); } - private void AddMessageResponder(string message, bool isSubstring, Func responder) + private void AddMessageResponder(string message, bool isSubstring, Func responder) { - _responders.Add(new Tuple>(message, isSubstring, responder)); + _responders.Add(new Tuple>(message, isSubstring, responder)); } /// @@ -67,9 +67,15 @@ namespace Emby.Server.Implementations.Udp if (responder != null) { + var cancellationToken = CancellationToken.None; + try { - await responder.Item2.Item3(responder.Item1, message.RemoteEndPoint, encoding).ConfigureAwait(false); + await responder.Item2.Item3(responder.Item1, message.RemoteEndPoint, encoding, cancellationToken).ConfigureAwait(false); + } + catch (OperationCanceledException) + { + } catch (Exception ex) { @@ -78,7 +84,7 @@ namespace Emby.Server.Implementations.Udp } } - private Tuple>> GetResponder(byte[] buffer, int bytesReceived, Encoding encoding) + private Tuple>> GetResponder(byte[] buffer, int bytesReceived, Encoding encoding) { var text = encoding.GetString(buffer, 0, bytesReceived); var responder = _responders.FirstOrDefault(i => @@ -94,14 +100,14 @@ namespace Emby.Server.Implementations.Udp { return null; } - return new Tuple>>(text, responder); + return new Tuple>>(text, responder); } - private async Task RespondToV2Message(string messageText, IpEndPointInfo endpoint, Encoding encoding) + private async Task RespondToV2Message(string messageText, IpEndPointInfo endpoint, Encoding encoding, CancellationToken cancellationToken) { var parts = messageText.Split('|'); - var localUrl = await _appHost.GetLocalApiUrl().ConfigureAwait(false); + var localUrl = await _appHost.GetLocalApiUrl(cancellationToken).ConfigureAwait(false); if (!string.IsNullOrEmpty(localUrl)) { @@ -112,7 +118,7 @@ namespace Emby.Server.Implementations.Udp Name = _appHost.FriendlyName }; - await SendAsync(encoding.GetBytes(_json.SerializeToString(response)), endpoint).ConfigureAwait(false); + await SendAsync(encoding.GetBytes(_json.SerializeToString(response)), endpoint, cancellationToken).ConfigureAwait(false); if (parts.Length > 1) { @@ -248,7 +254,7 @@ namespace Emby.Server.Implementations.Udp } } - public async Task SendAsync(byte[] bytes, IpEndPointInfo remoteEndPoint) + public async Task SendAsync(byte[] bytes, IpEndPointInfo remoteEndPoint, CancellationToken cancellationToken) { if (_isDisposed) { @@ -267,7 +273,7 @@ namespace Emby.Server.Implementations.Udp try { - await _udpClient.SendToAsync(bytes, 0, bytes.Length, remoteEndPoint, CancellationToken.None).ConfigureAwait(false); + await _udpClient.SendToAsync(bytes, 0, bytes.Length, remoteEndPoint, cancellationToken).ConfigureAwait(false); _logger.Info("Udp message sent to {0}", remoteEndPoint); } diff --git a/MediaBrowser.Api/ScheduledTasks/ScheduledTasksWebSocketListener.cs b/MediaBrowser.Api/ScheduledTasks/ScheduledTasksWebSocketListener.cs index 69ce6a385d..2d30625a98 100644 --- a/MediaBrowser.Api/ScheduledTasks/ScheduledTasksWebSocketListener.cs +++ b/MediaBrowser.Api/ScheduledTasks/ScheduledTasksWebSocketListener.cs @@ -3,9 +3,10 @@ using MediaBrowser.Model.Logging; using MediaBrowser.Model.Tasks; using System.Collections.Generic; using System.Linq; -using System.Threading.Tasks; +using System.Threading; using MediaBrowser.Controller.Net; using MediaBrowser.Model.Threading; +using System.Threading.Tasks; namespace MediaBrowser.Api.ScheduledTasks { @@ -63,7 +64,7 @@ namespace MediaBrowser.Api.ScheduledTasks /// /// The state. /// Task{IEnumerable{TaskInfo}}. - protected override Task> GetDataToSend(WebSocketListenerState state) + protected override Task> GetDataToSend(WebSocketListenerState state, CancellationToken cancellationToken) { return Task.FromResult(TaskManager.ScheduledTasks .OrderBy(i => i.Name) diff --git a/MediaBrowser.Api/SearchService.cs b/MediaBrowser.Api/SearchService.cs index ad79ea57b9..50033eee82 100644 --- a/MediaBrowser.Api/SearchService.cs +++ b/MediaBrowser.Api/SearchService.cs @@ -248,9 +248,20 @@ namespace MediaBrowser.Api if (song != null) { - result.Album = song.Album; result.AlbumArtist = song.AlbumArtists.FirstOrDefault(); result.Artists = song.Artists; + + album = song.AlbumEntity; + + if (album != null) + { + result.Album = album.Name; + result.AlbumId = album.Id.ToString("N"); + } + else + { + result.Album = song.Album; + } } if (!string.IsNullOrWhiteSpace(item.ChannelId)) diff --git a/MediaBrowser.Api/Session/SessionInfoWebSocketListener.cs b/MediaBrowser.Api/Session/SessionInfoWebSocketListener.cs index e133a88a1f..65c69fc7de 100644 --- a/MediaBrowser.Api/Session/SessionInfoWebSocketListener.cs +++ b/MediaBrowser.Api/Session/SessionInfoWebSocketListener.cs @@ -5,8 +5,9 @@ using MediaBrowser.Model.Logging; using MediaBrowser.Model.Session; using System.Collections.Generic; using System.Linq; -using System.Threading.Tasks; +using System.Threading; using MediaBrowser.Model.Threading; +using System.Threading.Tasks; namespace MediaBrowser.Api.Session { @@ -86,7 +87,7 @@ namespace MediaBrowser.Api.Session /// /// The state. /// Task{SystemInfo}. - protected override Task> GetDataToSend(WebSocketListenerState state) + protected override Task> GetDataToSend(WebSocketListenerState state, CancellationToken cancellationToken) { return Task.FromResult(_sessionManager.Sessions.Where(i => i.IsActive).Select(_sessionManager.GetSessionInfoDto)); } diff --git a/MediaBrowser.Api/System/ActivityLogWebSocketListener.cs b/MediaBrowser.Api/System/ActivityLogWebSocketListener.cs index 793f745713..f9cac7389d 100644 --- a/MediaBrowser.Api/System/ActivityLogWebSocketListener.cs +++ b/MediaBrowser.Api/System/ActivityLogWebSocketListener.cs @@ -5,6 +5,7 @@ using System.Collections.Generic; using System.Threading.Tasks; using MediaBrowser.Controller.Net; using MediaBrowser.Model.Threading; +using System.Threading; namespace MediaBrowser.Api.System { @@ -43,7 +44,7 @@ namespace MediaBrowser.Api.System /// /// The state. /// Task{SystemInfo}. - protected override Task> GetDataToSend(WebSocketListenerState state) + protected override Task> GetDataToSend(WebSocketListenerState state, CancellationToken CancellationToken) { return Task.FromResult(new List()); } diff --git a/MediaBrowser.Api/System/SystemInfoWebSocketListener.cs b/MediaBrowser.Api/System/SystemInfoWebSocketListener.cs index 8d74cc66c0..63847f2b52 100644 --- a/MediaBrowser.Api/System/SystemInfoWebSocketListener.cs +++ b/MediaBrowser.Api/System/SystemInfoWebSocketListener.cs @@ -4,6 +4,7 @@ using MediaBrowser.Model.Logging; using MediaBrowser.Model.System; using System.Threading.Tasks; using MediaBrowser.Model.Threading; +using System.Threading; namespace MediaBrowser.Api.System { @@ -40,9 +41,9 @@ namespace MediaBrowser.Api.System /// /// The state. /// Task{SystemInfo}. - protected override Task GetDataToSend(WebSocketListenerState state) + protected override Task GetDataToSend(WebSocketListenerState state, CancellationToken cancellationToken) { - return _appHost.GetSystemInfo(); + return _appHost.GetSystemInfo(cancellationToken); } } } diff --git a/MediaBrowser.Api/System/SystemService.cs b/MediaBrowser.Api/System/SystemService.cs index d850b2ce72..6de7dd98ba 100644 --- a/MediaBrowser.Api/System/SystemService.cs +++ b/MediaBrowser.Api/System/SystemService.cs @@ -14,6 +14,7 @@ using MediaBrowser.Controller.IO; using MediaBrowser.Model.IO; using MediaBrowser.Model.Net; using MediaBrowser.Model.Services; +using System.Threading; namespace MediaBrowser.Api.System { @@ -164,14 +165,14 @@ namespace MediaBrowser.Api.System /// System.Object. public async Task Get(GetSystemInfo request) { - var result = await _appHost.GetSystemInfo().ConfigureAwait(false); + var result = await _appHost.GetSystemInfo(CancellationToken.None).ConfigureAwait(false); return ToOptimizedResult(result); } public async Task Get(GetPublicSystemInfo request) { - var result = await _appHost.GetSystemInfo().ConfigureAwait(false); + var result = await _appHost.GetSystemInfo(CancellationToken.None).ConfigureAwait(false); var publicInfo = new PublicSystemInfo { diff --git a/MediaBrowser.Controller/IServerApplicationHost.cs b/MediaBrowser.Controller/IServerApplicationHost.cs index e9f7d59321..380be068e5 100644 --- a/MediaBrowser.Controller/IServerApplicationHost.cs +++ b/MediaBrowser.Controller/IServerApplicationHost.cs @@ -5,6 +5,7 @@ using System.Collections.Generic; using System.Net; using System.Threading.Tasks; using MediaBrowser.Model.Net; +using System.Threading; namespace MediaBrowser.Controller { @@ -19,7 +20,7 @@ namespace MediaBrowser.Controller /// Gets the system info. /// /// SystemInfo. - Task GetSystemInfo(); + Task GetSystemInfo(CancellationToken cancellationToken); /// /// Gets a value indicating whether [supports automatic run at startup]. @@ -61,13 +62,13 @@ namespace MediaBrowser.Controller /// Gets the local ip address. /// /// The local ip address. - Task> GetLocalIpAddresses(); + Task> GetLocalIpAddresses(CancellationToken cancellationToken); /// /// Gets the local API URL. /// /// The local API URL. - Task GetLocalApiUrl(); + Task GetLocalApiUrl(CancellationToken cancellationToken); /// /// Gets the local API URL. diff --git a/MediaBrowser.Controller/Net/BasePeriodicWebSocketListener.cs b/MediaBrowser.Controller/Net/BasePeriodicWebSocketListener.cs index 6be94e7e6e..17b82b3cae 100644 --- a/MediaBrowser.Controller/Net/BasePeriodicWebSocketListener.cs +++ b/MediaBrowser.Controller/Net/BasePeriodicWebSocketListener.cs @@ -36,7 +36,7 @@ namespace MediaBrowser.Controller.Net /// /// The state. /// Task{`1}. - protected abstract Task GetDataToSend(TStateType state); + protected abstract Task GetDataToSend(TStateType state, CancellationToken cancellationToken); /// /// The logger @@ -209,7 +209,9 @@ namespace MediaBrowser.Controller.Net { var state = tuple.Item4; - var data = await GetDataToSend(state).ConfigureAwait(false); + var cancellationToken = tuple.Item2.Token; + + var data = await GetDataToSend(state, cancellationToken).ConfigureAwait(false); if (data != null) { @@ -218,7 +220,7 @@ namespace MediaBrowser.Controller.Net MessageType = Name, Data = data - }, tuple.Item2.Token).ConfigureAwait(false); + }, cancellationToken).ConfigureAwait(false); state.DateLastSendUtc = DateTime.UtcNow; } diff --git a/MediaBrowser.Controller/Sync/ISyncManager.cs b/MediaBrowser.Controller/Sync/ISyncManager.cs index 0bf4b914f1..5e9085a402 100644 --- a/MediaBrowser.Controller/Sync/ISyncManager.cs +++ b/MediaBrowser.Controller/Sync/ISyncManager.cs @@ -29,7 +29,7 @@ namespace MediaBrowser.Controller.Sync /// Gets the jobs. /// /// QueryResult<SyncJob>. - Task> GetJobs(SyncJobQuery query); + QueryResult GetJobs(SyncJobQuery query); /// /// Gets the job items. diff --git a/MediaBrowser.Model/Dlna/StreamBuilder.cs b/MediaBrowser.Model/Dlna/StreamBuilder.cs index 37d266ac09..2da6f1c81c 100644 --- a/MediaBrowser.Model/Dlna/StreamBuilder.cs +++ b/MediaBrowser.Model/Dlna/StreamBuilder.cs @@ -1343,7 +1343,7 @@ namespace MediaBrowser.Model.Dlna if (itemBitrate > requestedMaxBitrate) { - _logger.Info("Bitrate exceeds " + playMethod + " limit: media bitrate: {0}, max bitrate: {1}", item.Bitrate.Value.ToString(CultureInfo.InvariantCulture), requestedMaxBitrate.ToString(CultureInfo.InvariantCulture)); + _logger.Info("Bitrate exceeds " + playMethod + " limit: media bitrate: {0}, max bitrate: {1}", itemBitrate.ToString(CultureInfo.InvariantCulture), requestedMaxBitrate.ToString(CultureInfo.InvariantCulture)); return false; } diff --git a/MediaBrowser.Model/Search/SearchHint.cs b/MediaBrowser.Model/Search/SearchHint.cs index 5c56374819..f2617c9095 100644 --- a/MediaBrowser.Model/Search/SearchHint.cs +++ b/MediaBrowser.Model/Search/SearchHint.cs @@ -107,6 +107,7 @@ namespace MediaBrowser.Model.Search /// /// The album. public string Album { get; set; } + public string AlbumId { get; set; } /// /// Gets or sets the album artist. diff --git a/MediaBrowser.WebDashboard/Api/PackageCreator.cs b/MediaBrowser.WebDashboard/Api/PackageCreator.cs index f55d95a2e7..5fd94e0d76 100644 --- a/MediaBrowser.WebDashboard/Api/PackageCreator.cs +++ b/MediaBrowser.WebDashboard/Api/PackageCreator.cs @@ -200,7 +200,16 @@ namespace MediaBrowser.WebDashboard.Api sb.Append(""); sb.Append(""); sb.Append(""); - sb.Append(""); + + if (string.Equals(mode, "cordova", StringComparison.OrdinalIgnoreCase)) + { + sb.Append(""); + } + else + { + sb.Append(""); + } + sb.Append(""); sb.Append(""); sb.Append(""); diff --git a/SharedVersion.cs b/SharedVersion.cs index 99dc764dfd..463ec3ae3c 100644 --- a/SharedVersion.cs +++ b/SharedVersion.cs @@ -1,3 +1,3 @@ using System.Reflection; -[assembly: AssemblyVersion("3.2.40.1")] +[assembly: AssemblyVersion("3.2.40.2")] -- cgit v1.2.3 From 58a7829ecd773dbc3c875d3f0d4438b847fd54b5 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sat, 25 Nov 2017 23:48:12 -0500 Subject: update library changed notifier --- .../EntryPoints/LibraryChangedNotifier.cs | 36 ++++++++++++++++++++-- Emby.Server.Implementations/IO/LibraryMonitor.cs | 7 +++-- .../IO/ManagedFileSystem.cs | 15 +++++++++ .../Library/LibraryManager.cs | 21 +++++++++---- .../LiveTv/EmbyTV/EmbyTV.cs | 19 ++++++++++++ .../LiveTv/LiveTvManager.cs | 2 +- MediaBrowser.Controller/Entities/BaseItem.cs | 2 +- MediaBrowser.Controller/Entities/Folder.cs | 4 +-- MediaBrowser.Controller/Library/ILibraryManager.cs | 9 ++---- .../Library/ItemChangeEventArgs.cs | 2 ++ MediaBrowser.Model/Entities/LibraryUpdateInfo.cs | 3 ++ SharedVersion.cs | 2 +- 12 files changed, 98 insertions(+), 24 deletions(-) (limited to 'Emby.Server.Implementations/EntryPoints') diff --git a/Emby.Server.Implementations/EntryPoints/LibraryChangedNotifier.cs b/Emby.Server.Implementations/EntryPoints/LibraryChangedNotifier.cs index 299da07445..0e771cbecc 100644 --- a/Emby.Server.Implementations/EntryPoints/LibraryChangedNotifier.cs +++ b/Emby.Server.Implementations/EntryPoints/LibraryChangedNotifier.cs @@ -260,7 +260,7 @@ namespace Emby.Server.Implementations.EntryPoints LibraryUpdateTimer.Change(LibraryUpdateDuration, Timeout.Infinite); } - var parent = e.Item.GetParent() as Folder; + var parent = e.Parent as Folder; if (parent != null) { _foldersRemovedFrom.Add(parent); @@ -363,10 +363,16 @@ namespace Emby.Server.Implementations.EntryPoints /// The folders removed from. /// The user id. /// LibraryUpdateInfo. - private LibraryUpdateInfo GetLibraryUpdateInfo(IEnumerable itemsAdded, IEnumerable itemsUpdated, IEnumerable itemsRemoved, IEnumerable foldersAddedTo, IEnumerable foldersRemovedFrom, Guid userId) + private LibraryUpdateInfo GetLibraryUpdateInfo(List itemsAdded, List itemsUpdated, List itemsRemoved, List foldersAddedTo, List foldersRemovedFrom, Guid userId) { var user = _userManager.GetUserById(userId); + var newAndRemoved = new List(); + newAndRemoved.AddRange(foldersAddedTo); + newAndRemoved.AddRange(foldersRemovedFrom); + + var allUserRootChildren = _libraryManager.GetUserRootFolder().GetChildren(user, true).OfType().ToList(); + return new LibraryUpdateInfo { ItemsAdded = itemsAdded.SelectMany(i => TranslatePhysicalItemToUserLibrary(i, user)).Select(i => i.Id.ToString("N")).Distinct().ToArray(), @@ -377,7 +383,9 @@ namespace Emby.Server.Implementations.EntryPoints FoldersAddedTo = foldersAddedTo.SelectMany(i => TranslatePhysicalItemToUserLibrary(i, user)).Select(i => i.Id.ToString("N")).Distinct().ToArray(), - FoldersRemovedFrom = foldersRemovedFrom.SelectMany(i => TranslatePhysicalItemToUserLibrary(i, user)).Select(i => i.Id.ToString("N")).Distinct().ToArray() + FoldersRemovedFrom = foldersRemovedFrom.SelectMany(i => TranslatePhysicalItemToUserLibrary(i, user)).Select(i => i.Id.ToString("N")).Distinct().ToArray(), + + CollectionFolders = GetTopParentIds(newAndRemoved, user, allUserRootChildren).ToArray() }; } @@ -396,6 +404,28 @@ namespace Emby.Server.Implementations.EntryPoints return item.SourceType == SourceType.Library; } + private IEnumerable GetTopParentIds(List items, User user, List allUserRootChildren) + { + var list = new List(); + + foreach (var item in items) + { + // If the physical root changed, return the user root + if (item is AggregateFolder) + { + continue; + } + + var collectionFolders = _libraryManager.GetCollectionFolders(item, allUserRootChildren); + foreach (var folder in allUserRootChildren) + { + list.Add(folder.Id.ToString("N")); + } + } + + return list.Distinct(StringComparer.Ordinal); + } + /// /// Translates the physical item to user library. /// diff --git a/Emby.Server.Implementations/IO/LibraryMonitor.cs b/Emby.Server.Implementations/IO/LibraryMonitor.cs index c99b601c90..a2abb2a5c9 100644 --- a/Emby.Server.Implementations/IO/LibraryMonitor.cs +++ b/Emby.Server.Implementations/IO/LibraryMonitor.cs @@ -237,7 +237,7 @@ namespace Emby.Server.Implementations.IO /// The instance containing the event data. void LibraryManager_ItemRemoved(object sender, ItemChangeEventArgs e) { - if (e.Item.GetParent() is AggregateFolder) + if (e.Parent is AggregateFolder) { StopWatchingPath(e.Item.Path); } @@ -250,7 +250,7 @@ namespace Emby.Server.Implementations.IO /// The instance containing the event data. void LibraryManager_ItemAdded(object sender, ItemChangeEventArgs e) { - if (e.Item.GetParent() is AggregateFolder) + if (e.Parent is AggregateFolder) { StartWatching(e.Item); } @@ -320,7 +320,8 @@ namespace Emby.Server.Implementations.IO IncludeSubdirectories = true }; - if (_environmentInfo.OperatingSystem == MediaBrowser.Model.System.OperatingSystem.Windows) + if (_environmentInfo.OperatingSystem == MediaBrowser.Model.System.OperatingSystem.Windows || + _environmentInfo.OperatingSystem == MediaBrowser.Model.System.OperatingSystem.OSX) { newWatcher.InternalBufferSize = 32767; } diff --git a/Emby.Server.Implementations/IO/ManagedFileSystem.cs b/Emby.Server.Implementations/IO/ManagedFileSystem.cs index 125d9e980f..c8e4031a90 100644 --- a/Emby.Server.Implementations/IO/ManagedFileSystem.cs +++ b/Emby.Server.Implementations/IO/ManagedFileSystem.cs @@ -473,6 +473,11 @@ namespace Emby.Server.Implementations.IO public void SetHidden(string path, bool isHidden) { + if (_environmentInfo.OperatingSystem != MediaBrowser.Model.System.OperatingSystem.Windows) + { + return; + } + if (_sharpCifsFileSystem.IsEnabledForPath(path)) { _sharpCifsFileSystem.SetHidden(path, isHidden); @@ -498,6 +503,11 @@ namespace Emby.Server.Implementations.IO public void SetReadOnly(string path, bool isReadOnly) { + if (_environmentInfo.OperatingSystem != MediaBrowser.Model.System.OperatingSystem.Windows) + { + return; + } + if (_sharpCifsFileSystem.IsEnabledForPath(path)) { _sharpCifsFileSystem.SetReadOnly(path, isReadOnly); @@ -523,6 +533,11 @@ namespace Emby.Server.Implementations.IO public void SetAttributes(string path, bool isHidden, bool isReadOnly) { + if (_environmentInfo.OperatingSystem != MediaBrowser.Model.System.OperatingSystem.Windows) + { + return; + } + if (_sharpCifsFileSystem.IsEnabledForPath(path)) { _sharpCifsFileSystem.SetAttributes(path, isHidden, isReadOnly); diff --git a/Emby.Server.Implementations/Library/LibraryManager.cs b/Emby.Server.Implementations/Library/LibraryManager.cs index f71e2714ac..2934a51479 100644 --- a/Emby.Server.Implementations/Library/LibraryManager.cs +++ b/Emby.Server.Implementations/Library/LibraryManager.cs @@ -443,7 +443,7 @@ namespace Emby.Server.Implementations.Library BaseItem removed; _libraryItemsCache.TryRemove(item.Id, out removed); - ReportItemRemoved(item); + ReportItemRemoved(item, parent); } private IEnumerable GetMetadataPaths(BaseItem item, IEnumerable children) @@ -1804,7 +1804,7 @@ namespace Emby.Server.Implementations.Library /// Task. public void CreateItem(BaseItem item, CancellationToken cancellationToken) { - CreateItems(new[] { item }, cancellationToken); + CreateItems(new[] { item }, item.GetParent(), cancellationToken); } /// @@ -1813,7 +1813,7 @@ namespace Emby.Server.Implementations.Library /// The items. /// The cancellation token. /// Task. - public void CreateItems(IEnumerable items, CancellationToken cancellationToken) + public void CreateItems(IEnumerable items, BaseItem parent, CancellationToken cancellationToken) { var list = items.ToList(); @@ -1830,7 +1830,11 @@ namespace Emby.Server.Implementations.Library { try { - ItemAdded(this, new ItemChangeEventArgs { Item = item }); + ItemAdded(this, new ItemChangeEventArgs + { + Item = item, + Parent = parent ?? item.GetParent() + }); } catch (Exception ex) { @@ -1878,6 +1882,7 @@ namespace Emby.Server.Implementations.Library ItemUpdated(this, new ItemChangeEventArgs { Item = item, + Parent = item.GetParent(), UpdateReason = updateReason }); } @@ -1892,13 +1897,17 @@ namespace Emby.Server.Implementations.Library /// Reports the item removed. /// /// The item. - public void ReportItemRemoved(BaseItem item) + public void ReportItemRemoved(BaseItem item, BaseItem parent) { if (ItemRemoved != null) { try { - ItemRemoved(this, new ItemChangeEventArgs { Item = item }); + ItemRemoved(this, new ItemChangeEventArgs + { + Item = item, + Parent = parent + }); } catch (Exception ex) { diff --git a/Emby.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs b/Emby.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs index a4c5645e74..35d2d3c0ab 100644 --- a/Emby.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs +++ b/Emby.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs @@ -1512,6 +1512,8 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV } } + DeleteFileIfEmpty(recordPath); + TriggerRefresh(recordPath); _libraryMonitor.ReportFileSystemChangeComplete(recordPath, false); @@ -1542,6 +1544,23 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV } } + private void DeleteFileIfEmpty(string path) + { + var file = _fileSystem.GetFileInfo(path); + + if (file.Exists && file.Length == 0) + { + try + { + _fileSystem.DeleteFile(path); + } + catch (Exception ex) + { + _logger.ErrorException("Error deleting 0-byte failed recording file {0}", ex, path); + } + } + } + private void TriggerRefresh(string path) { _logger.Info("Triggering refresh on {0}", path); diff --git a/Emby.Server.Implementations/LiveTv/LiveTvManager.cs b/Emby.Server.Implementations/LiveTv/LiveTvManager.cs index 7e72d1b1a1..7e27877e7c 100644 --- a/Emby.Server.Implementations/LiveTv/LiveTvManager.cs +++ b/Emby.Server.Implementations/LiveTv/LiveTvManager.cs @@ -1421,7 +1421,7 @@ namespace Emby.Server.Implementations.LiveTv if (newPrograms.Count > 0) { - _libraryManager.CreateItems(newPrograms, cancellationToken); + _libraryManager.CreateItems(newPrograms, null, cancellationToken); } // TODO: Do this in bulk diff --git a/MediaBrowser.Controller/Entities/BaseItem.cs b/MediaBrowser.Controller/Entities/BaseItem.cs index f6a8f1d5a4..98899253e1 100644 --- a/MediaBrowser.Controller/Entities/BaseItem.cs +++ b/MediaBrowser.Controller/Entities/BaseItem.cs @@ -2236,7 +2236,7 @@ namespace MediaBrowser.Controller.Entities } var filename = System.IO.Path.GetFileNameWithoutExtension(Path); - var extensions = new List { ".nfo", ".xml", ".srt" }; + var extensions = new List { ".nfo", ".xml", ".srt", ".vtt", ".sub", ".idx", ".txt", ".edl" }; extensions.AddRange(SupportedImageExtensions); return FileSystem.GetFiles(FileSystem.GetDirectoryName(Path), extensions.ToArray(extensions.Count), false, false) diff --git a/MediaBrowser.Controller/Entities/Folder.cs b/MediaBrowser.Controller/Entities/Folder.cs index 504d03a276..08b6a123d9 100644 --- a/MediaBrowser.Controller/Entities/Folder.cs +++ b/MediaBrowser.Controller/Entities/Folder.cs @@ -466,11 +466,11 @@ namespace MediaBrowser.Controller.Entities item.SetParent(null); await LibraryManager.DeleteItem(item, new DeleteOptions { DeleteFileLocation = false }).ConfigureAwait(false); - LibraryManager.ReportItemRemoved(item); + LibraryManager.ReportItemRemoved(item, this); } } - LibraryManager.CreateItems(newItems, cancellationToken); + LibraryManager.CreateItems(newItems, this, cancellationToken); } } else diff --git a/MediaBrowser.Controller/Library/ILibraryManager.cs b/MediaBrowser.Controller/Library/ILibraryManager.cs index 37e0d56616..9ef372eb66 100644 --- a/MediaBrowser.Controller/Library/ILibraryManager.cs +++ b/MediaBrowser.Controller/Library/ILibraryManager.cs @@ -195,16 +195,12 @@ namespace MediaBrowser.Controller.Library /// /// Creates the item. /// - /// The item. - /// The cancellation token. void CreateItem(BaseItem item, CancellationToken cancellationToken); /// /// Creates the items. /// - /// The items. - /// The cancellation token. - void CreateItems(IEnumerable items, CancellationToken cancellationToken); + void CreateItems(IEnumerable items, BaseItem parent, CancellationToken cancellationToken); /// /// Updates the item. @@ -237,8 +233,7 @@ namespace MediaBrowser.Controller.Library /// /// Reports the item removed. /// - /// The item. - void ReportItemRemoved(BaseItem item); + void ReportItemRemoved(BaseItem item, BaseItem parent); /// /// Finds the type of the collection. diff --git a/MediaBrowser.Controller/Library/ItemChangeEventArgs.cs b/MediaBrowser.Controller/Library/ItemChangeEventArgs.cs index a2951f548e..e671490d3c 100644 --- a/MediaBrowser.Controller/Library/ItemChangeEventArgs.cs +++ b/MediaBrowser.Controller/Library/ItemChangeEventArgs.cs @@ -13,6 +13,8 @@ namespace MediaBrowser.Controller.Library /// The item. public BaseItem Item { get; set; } + public BaseItem Parent { get; set; } + /// /// Gets or sets the item. /// diff --git a/MediaBrowser.Model/Entities/LibraryUpdateInfo.cs b/MediaBrowser.Model/Entities/LibraryUpdateInfo.cs index b3d3be70e8..8995e08883 100644 --- a/MediaBrowser.Model/Entities/LibraryUpdateInfo.cs +++ b/MediaBrowser.Model/Entities/LibraryUpdateInfo.cs @@ -35,6 +35,8 @@ namespace MediaBrowser.Model.Entities /// The items updated. public string[] ItemsUpdated { get; set; } + public string[] CollectionFolders { get; set; } + /// /// Initializes a new instance of the class. /// @@ -45,6 +47,7 @@ namespace MediaBrowser.Model.Entities ItemsAdded = new string[] { }; ItemsRemoved = new string[] { }; ItemsUpdated = new string[] { }; + CollectionFolders = new string[] { }; } } } diff --git a/SharedVersion.cs b/SharedVersion.cs index 463ec3ae3c..90e6929e2a 100644 --- a/SharedVersion.cs +++ b/SharedVersion.cs @@ -1,3 +1,3 @@ using System.Reflection; -[assembly: AssemblyVersion("3.2.40.2")] +[assembly: AssemblyVersion("3.2.40.3")] -- cgit v1.2.3 From d7a1a87009eed638d28d070e6a47c8a5bee38c2e Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Fri, 1 Dec 2017 12:03:40 -0500 Subject: reduce work done by system info endpoints --- Emby.Server.Implementations/ApplicationHost.cs | 17 ++++++++++++++++- .../EntryPoints/StartupWizard.cs | 7 ++++++- .../Networking/NetworkManager.cs | 19 ++++++------------- .../Session/HttpSessionController.cs | 2 +- Emby.Server.Implementations/Session/SessionManager.cs | 4 +--- .../Session/WebSocketController.cs | 6 +++--- MediaBrowser.Api/System/SystemService.cs | 14 ++------------ MediaBrowser.Controller/IServerApplicationHost.cs | 2 ++ MediaBrowser.Controller/Session/ISessionController.cs | 5 +---- 9 files changed, 38 insertions(+), 38 deletions(-) (limited to 'Emby.Server.Implementations/EntryPoints') diff --git a/Emby.Server.Implementations/ApplicationHost.cs b/Emby.Server.Implementations/ApplicationHost.cs index 9a159194ee..abc6c35666 100644 --- a/Emby.Server.Implementations/ApplicationHost.cs +++ b/Emby.Server.Implementations/ApplicationHost.cs @@ -361,7 +361,7 @@ namespace Emby.Server.Implementations protected IAuthService AuthService { get; private set; } - protected readonly StartupOptions StartupOptions; + public StartupOptions StartupOptions { get; private set; } protected readonly string ReleaseAssetFilename; internal IPowerManagement PowerManagement { get; private set; } @@ -1950,6 +1950,21 @@ namespace Emby.Server.Implementations }; } + public async Task GetPublicSystemInfo(CancellationToken cancellationToken) + { + var localAddress = await GetLocalApiUrl(cancellationToken).ConfigureAwait(false); + + return new PublicSystemInfo + { + Version = ApplicationVersion.ToString(), + Id = SystemId, + OperatingSystem = EnvironmentInfo.OperatingSystem.ToString(), + WanAddress = ConnectManager.WanApiAddress, + ServerName = FriendlyName, + LocalAddress = localAddress + }; + } + public bool EnableHttps { get diff --git a/Emby.Server.Implementations/EntryPoints/StartupWizard.cs b/Emby.Server.Implementations/EntryPoints/StartupWizard.cs index 8d13557952..746edf9e7b 100644 --- a/Emby.Server.Implementations/EntryPoints/StartupWizard.cs +++ b/Emby.Server.Implementations/EntryPoints/StartupWizard.cs @@ -41,7 +41,12 @@ namespace Emby.Server.Implementations.EntryPoints } else if (_config.Configuration.IsStartupWizardCompleted) { - BrowserLauncher.OpenDashboardPage("index.html", _appHost); + var options = ((ApplicationHost)_appHost).StartupOptions; + + if (!options.ContainsOption("-service") && !options.ContainsOption("-nobrowser")) + { + BrowserLauncher.OpenDashboardPage("index.html", _appHost); + } } } diff --git a/Emby.Server.Implementations/Networking/NetworkManager.cs b/Emby.Server.Implementations/Networking/NetworkManager.cs index 30a3ff9e86..60da8a0124 100644 --- a/Emby.Server.Implementations/Networking/NetworkManager.cs +++ b/Emby.Server.Implementations/Networking/NetworkManager.cs @@ -11,15 +11,12 @@ using MediaBrowser.Model.Extensions; using MediaBrowser.Model.IO; using MediaBrowser.Model.Logging; using MediaBrowser.Model.Net; -using System.Threading; namespace Emby.Server.Implementations.Networking { public class NetworkManager : INetworkManager { protected ILogger Logger { get; private set; } - private DateTime _lastRefresh; - private int NetworkCacheMinutes = 720; public event EventHandler NetworkChanged; @@ -33,7 +30,6 @@ namespace Emby.Server.Implementations.Networking } catch (Exception ex) { - NetworkCacheMinutes = 15; Logger.ErrorException("Error binding to NetworkAddressChanged event", ex); } @@ -43,7 +39,6 @@ namespace Emby.Server.Implementations.Networking } catch (Exception ex) { - NetworkCacheMinutes = 15; Logger.ErrorException("Error binding to NetworkChange_NetworkAvailabilityChanged event", ex); } } @@ -51,19 +46,21 @@ namespace Emby.Server.Implementations.Networking private void NetworkChange_NetworkAvailabilityChanged(object sender, NetworkAvailabilityEventArgs e) { Logger.Debug("NetworkAvailabilityChanged"); - _lastRefresh = DateTime.MinValue; OnNetworkChanged(); } private void NetworkChange_NetworkAddressChanged(object sender, EventArgs e) { Logger.Debug("NetworkAddressChanged"); - _lastRefresh = DateTime.MinValue; OnNetworkChanged(); } private void OnNetworkChanged() { + lock (_localIpAddressSyncLock) + { + _localIpAddresses = null; + } if (NetworkChanged != null) { NetworkChanged(this, EventArgs.Empty); @@ -77,20 +74,16 @@ namespace Emby.Server.Implementations.Networking { lock (_localIpAddressSyncLock) { - var forceRefresh = (DateTime.UtcNow - _lastRefresh).TotalMinutes >= NetworkCacheMinutes; - - if (_localIpAddresses == null || forceRefresh) + if (_localIpAddresses == null) { var addresses = GetLocalIpAddressesInternal().Result.Select(ToIpAddressInfo).ToList(); _localIpAddresses = addresses; - _lastRefresh = DateTime.UtcNow; return addresses; } + return _localIpAddresses; } - - return _localIpAddresses; } private async Task> GetLocalIpAddressesInternal() diff --git a/Emby.Server.Implementations/Session/HttpSessionController.cs b/Emby.Server.Implementations/Session/HttpSessionController.cs index e852544204..6725cd7af6 100644 --- a/Emby.Server.Implementations/Session/HttpSessionController.cs +++ b/Emby.Server.Implementations/Session/HttpSessionController.cs @@ -151,7 +151,7 @@ namespace Emby.Server.Implementations.Session return SendMessage("LibraryChanged", info, cancellationToken); } - public Task SendRestartRequiredNotification(SystemInfo info, CancellationToken cancellationToken) + public Task SendRestartRequiredNotification(CancellationToken cancellationToken) { return SendMessage("RestartRequired", cancellationToken); } diff --git a/Emby.Server.Implementations/Session/SessionManager.cs b/Emby.Server.Implementations/Session/SessionManager.cs index f49251da53..6b70f2cda3 100644 --- a/Emby.Server.Implementations/Session/SessionManager.cs +++ b/Emby.Server.Implementations/Session/SessionManager.cs @@ -1182,13 +1182,11 @@ namespace Emby.Server.Implementations.Session { var sessions = Sessions.Where(i => i.IsActive && i.SessionController != null).ToList(); - var info = await _appHost.GetSystemInfo(cancellationToken).ConfigureAwait(false); - var tasks = sessions.Select(session => Task.Run(async () => { try { - await session.SessionController.SendRestartRequiredNotification(info, cancellationToken).ConfigureAwait(false); + await session.SessionController.SendRestartRequiredNotification(cancellationToken).ConfigureAwait(false); } catch (Exception ex) { diff --git a/Emby.Server.Implementations/Session/WebSocketController.cs b/Emby.Server.Implementations/Session/WebSocketController.cs index ee9ee8969e..b13eb6116d 100644 --- a/Emby.Server.Implementations/Session/WebSocketController.cs +++ b/Emby.Server.Implementations/Session/WebSocketController.cs @@ -145,12 +145,12 @@ namespace Emby.Server.Implementations.Session /// The information. /// The cancellation token. /// Task. - public Task SendRestartRequiredNotification(SystemInfo info, CancellationToken cancellationToken) + public Task SendRestartRequiredNotification(CancellationToken cancellationToken) { - return SendMessagesInternal(new WebSocketMessage + return SendMessagesInternal(new WebSocketMessage { MessageType = "RestartRequired", - Data = info + Data = string.Empty }, cancellationToken); } diff --git a/MediaBrowser.Api/System/SystemService.cs b/MediaBrowser.Api/System/SystemService.cs index 6de7dd98ba..c0bbf70ead 100644 --- a/MediaBrowser.Api/System/SystemService.cs +++ b/MediaBrowser.Api/System/SystemService.cs @@ -172,19 +172,9 @@ namespace MediaBrowser.Api.System public async Task Get(GetPublicSystemInfo request) { - var result = await _appHost.GetSystemInfo(CancellationToken.None).ConfigureAwait(false); + var result = await _appHost.GetPublicSystemInfo(CancellationToken.None).ConfigureAwait(false); - var publicInfo = new PublicSystemInfo - { - Id = result.Id, - ServerName = result.ServerName, - Version = result.Version, - LocalAddress = result.LocalAddress, - WanAddress = result.WanAddress, - OperatingSystem = result.OperatingSystem - }; - - return ToOptimizedResult(publicInfo); + return ToOptimizedResult(result); } /// diff --git a/MediaBrowser.Controller/IServerApplicationHost.cs b/MediaBrowser.Controller/IServerApplicationHost.cs index 380be068e5..89ae85b508 100644 --- a/MediaBrowser.Controller/IServerApplicationHost.cs +++ b/MediaBrowser.Controller/IServerApplicationHost.cs @@ -22,6 +22,8 @@ namespace MediaBrowser.Controller /// SystemInfo. Task GetSystemInfo(CancellationToken cancellationToken); + Task GetPublicSystemInfo(CancellationToken cancellationToken); + /// /// Gets a value indicating whether [supports automatic run at startup]. /// diff --git a/MediaBrowser.Controller/Session/ISessionController.cs b/MediaBrowser.Controller/Session/ISessionController.cs index f8a6ed1fc1..0d8c207b61 100644 --- a/MediaBrowser.Controller/Session/ISessionController.cs +++ b/MediaBrowser.Controller/Session/ISessionController.cs @@ -55,10 +55,7 @@ namespace MediaBrowser.Controller.Session /// /// Sends the restart required message. /// - /// The information. - /// The cancellation token. - /// Task. - Task SendRestartRequiredNotification(SystemInfo info, CancellationToken cancellationToken); + Task SendRestartRequiredNotification(CancellationToken cancellationToken); /// /// Sends the user data change info. -- cgit v1.2.3 From 8717f81bf406fb4f78adf117fd380f37bd6a98fc Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sun, 3 Dec 2017 17:14:35 -0500 Subject: Add setting to auto-run web app when server starts --- Emby.Server.Implementations/ApplicationHost.cs | 37 ++++++++++++++++++---- .../EntryPoints/StartupWizard.cs | 9 ++++-- MediaBrowser.Api/StartupWizardService.cs | 1 + MediaBrowser.Controller/IServerApplicationHost.cs | 4 ++- .../Configuration/ServerConfiguration.cs | 2 ++ MediaBrowser.Model/System/SystemInfo.cs | 2 ++ 6 files changed, 45 insertions(+), 10 deletions(-) (limited to 'Emby.Server.Implementations/EntryPoints') diff --git a/Emby.Server.Implementations/ApplicationHost.cs b/Emby.Server.Implementations/ApplicationHost.cs index abc6c35666..26450c06ca 100644 --- a/Emby.Server.Implementations/ApplicationHost.cs +++ b/Emby.Server.Implementations/ApplicationHost.cs @@ -148,6 +148,34 @@ namespace Emby.Server.Implementations } } + public virtual bool CanLaunchWebBrowser + { + get + { + if (!Environment.UserInteractive) + { + return false; + } + + if (StartupOptions.ContainsOption("-service")) + { + return false; + } + + if (EnvironmentInfo.OperatingSystem == MediaBrowser.Model.System.OperatingSystem.Windows) + { + return true; + } + + if (EnvironmentInfo.OperatingSystem == MediaBrowser.Model.System.OperatingSystem.OSX) + { + return true; + } + + return false; + } + } + /// /// Occurs when [has pending restart changed]. /// @@ -1936,6 +1964,7 @@ namespace Emby.Server.Implementations OperatingSystemDisplayName = OperatingSystemDisplayName, CanSelfRestart = CanSelfRestart, CanSelfUpdate = CanSelfUpdate, + CanLaunchWebBrowser = CanLaunchWebBrowser, WanAddress = ConnectManager.WanApiAddress, HasUpdateAvailable = HasUpdateAvailable, SupportsAutoRunAtStartup = SupportsAutoRunAtStartup, @@ -2358,13 +2387,7 @@ namespace Emby.Server.Implementations public virtual void LaunchUrl(string url) { - if (EnvironmentInfo.OperatingSystem != MediaBrowser.Model.System.OperatingSystem.Windows && - EnvironmentInfo.OperatingSystem != MediaBrowser.Model.System.OperatingSystem.OSX) - { - throw new NotSupportedException(); - } - - if (!Environment.UserInteractive) + if (!CanLaunchWebBrowser) { throw new NotSupportedException(); } diff --git a/Emby.Server.Implementations/EntryPoints/StartupWizard.cs b/Emby.Server.Implementations/EntryPoints/StartupWizard.cs index 746edf9e7b..103b4b321e 100644 --- a/Emby.Server.Implementations/EntryPoints/StartupWizard.cs +++ b/Emby.Server.Implementations/EntryPoints/StartupWizard.cs @@ -35,15 +35,20 @@ namespace Emby.Server.Implementations.EntryPoints /// public void Run() { + if (!_appHost.CanLaunchWebBrowser) + { + return; + } + if (_appHost.IsFirstRun) { BrowserLauncher.OpenDashboardPage("wizardstart.html", _appHost); } - else if (_config.Configuration.IsStartupWizardCompleted) + else if (_config.Configuration.IsStartupWizardCompleted && _config.Configuration.AutoRunWebApp) { var options = ((ApplicationHost)_appHost).StartupOptions; - if (!options.ContainsOption("-service") && !options.ContainsOption("-nobrowser")) + if (!options.ContainsOption("-noautorunwebapp")) { BrowserLauncher.OpenDashboardPage("index.html", _appHost); } diff --git a/MediaBrowser.Api/StartupWizardService.cs b/MediaBrowser.Api/StartupWizardService.cs index 54e4657c11..c6345c17f4 100644 --- a/MediaBrowser.Api/StartupWizardService.cs +++ b/MediaBrowser.Api/StartupWizardService.cs @@ -67,6 +67,7 @@ namespace MediaBrowser.Api public void Post(ReportStartupWizardComplete request) { _config.Configuration.IsStartupWizardCompleted = true; + _config.Configuration.AutoRunWebApp = true; _config.SetOptimalValues(); _config.SaveConfiguration(); diff --git a/MediaBrowser.Controller/IServerApplicationHost.cs b/MediaBrowser.Controller/IServerApplicationHost.cs index 89ae85b508..3f7f8248b5 100644 --- a/MediaBrowser.Controller/IServerApplicationHost.cs +++ b/MediaBrowser.Controller/IServerApplicationHost.cs @@ -29,7 +29,9 @@ namespace MediaBrowser.Controller /// /// true if [supports automatic run at startup]; otherwise, false. bool SupportsAutoRunAtStartup { get; } - + + bool CanLaunchWebBrowser { get; } + /// /// Gets the HTTP server port. /// diff --git a/MediaBrowser.Model/Configuration/ServerConfiguration.cs b/MediaBrowser.Model/Configuration/ServerConfiguration.cs index f2c3b7cc8a..41ed0648a6 100644 --- a/MediaBrowser.Model/Configuration/ServerConfiguration.cs +++ b/MediaBrowser.Model/Configuration/ServerConfiguration.cs @@ -61,6 +61,8 @@ namespace MediaBrowser.Model.Configuration /// true if this instance is port authorized; otherwise, false. public bool IsPortAuthorized { get; set; } + public bool AutoRunWebApp { get; set; } + /// /// Gets or sets a value indicating whether [enable case sensitive item ids]. /// diff --git a/MediaBrowser.Model/System/SystemInfo.cs b/MediaBrowser.Model/System/SystemInfo.cs index b61d637293..9ed0f904f0 100644 --- a/MediaBrowser.Model/System/SystemInfo.cs +++ b/MediaBrowser.Model/System/SystemInfo.cs @@ -68,6 +68,8 @@ namespace MediaBrowser.Model.System /// true if this instance can self update; otherwise, false. public bool CanSelfUpdate { get; set; } + public bool CanLaunchWebBrowser { get; set; } + /// /// Gets or sets plugin assemblies that failed to load. /// -- cgit v1.2.3