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 --- Emby.Server.Implementations/ApplicationHost.cs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'Emby.Server.Implementations/ApplicationHost.cs') diff --git a/Emby.Server.Implementations/ApplicationHost.cs b/Emby.Server.Implementations/ApplicationHost.cs index 745d83eb5f..531e13123a 100644 --- a/Emby.Server.Implementations/ApplicationHost.cs +++ b/Emby.Server.Implementations/ApplicationHost.cs @@ -2317,12 +2317,17 @@ namespace Emby.Server.Implementations } } - public void LaunchUrl(string url) + public virtual void LaunchUrl(string url) { if (EnvironmentInfo.OperatingSystem != MediaBrowser.Model.System.OperatingSystem.Windows && EnvironmentInfo.OperatingSystem != MediaBrowser.Model.System.OperatingSystem.OSX) { - throw new NotImplementedException(); + throw new NotSupportedException(); + } + + if (!Environment.UserInteractive) + { + throw new NotSupportedException(); } var process = ProcessFactory.Create(new ProcessOptions -- 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/ApplicationHost.cs') 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 5207067811afdd5e4c0f3bbcfcb254bfbb6d7ce9 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Wed, 29 Nov 2017 15:50:18 -0500 Subject: fix live tv over dlna --- Emby.Server.Implementations/ApplicationHost.cs | 56 +++++---- .../Data/SqliteItemRepository.cs | 2 +- .../Emby.Server.Implementations.csproj | 2 + .../LiveTv/TunerHosts/M3UTunerHost.cs | 16 ++- .../LiveTv/TunerHosts/SharedHttpStream.cs | 3 +- .../Localization/Core/ca.json | 126 ++++++++++----------- .../Localization/Core/de.json | 4 +- .../Localization/Core/el.json | 91 +++++++++++++++ .../Localization/Core/es-MX.json | 2 +- .../Localization/Core/gsw.json | 91 +++++++++++++++ .../Localization/Core/pt-BR.json | 2 +- .../Networking/NetworkManager.cs | 14 ++- MediaBrowser.Common/Net/INetworkManager.cs | 4 +- MediaBrowser.Model/Dlna/StreamInfo.cs | 5 + 14 files changed, 327 insertions(+), 91 deletions(-) create mode 100644 Emby.Server.Implementations/Localization/Core/el.json create mode 100644 Emby.Server.Implementations/Localization/Core/gsw.json (limited to 'Emby.Server.Implementations/ApplicationHost.cs') diff --git a/Emby.Server.Implementations/ApplicationHost.cs b/Emby.Server.Implementations/ApplicationHost.cs index 2e5c4be907..9a159194ee 100644 --- a/Emby.Server.Implementations/ApplicationHost.cs +++ b/Emby.Server.Implementations/ApplicationHost.cs @@ -393,6 +393,7 @@ namespace Emby.Server.Implementations ISystemEvents systemEvents, INetworkManager networkManager) { + // hack alert, until common can target .net core BaseExtensions.CryptographyProvider = CryptographyProvider; @@ -423,6 +424,13 @@ namespace Emby.Server.Implementations SetBaseExceptionMessage(); fileSystem.AddShortcutHandler(new MbLinkShortcutHandler(fileSystem)); + + NetworkManager.NetworkChanged += NetworkManager_NetworkChanged; + } + + private void NetworkManager_NetworkChanged(object sender, EventArgs e) + { + _validAddressResults.Clear(); } private Version _version; @@ -1960,9 +1968,9 @@ namespace Emby.Server.Implementations try { // Return the first matched address, if found, or the first known local address - var address = (await GetLocalIpAddresses(cancellationToken).ConfigureAwait(false)).FirstOrDefault(i => !i.Equals(IpAddressInfo.Loopback) && !i.Equals(IpAddressInfo.IPv6Loopback)); + var addresses = await GetLocalIpAddressesInternal(false, 1, cancellationToken).ConfigureAwait(false); - if (address != null) + foreach (var address in addresses) { return GetLocalApiUrl(address); } @@ -1994,7 +2002,12 @@ namespace Emby.Server.Implementations HttpPort.ToString(CultureInfo.InvariantCulture)); } - public async Task> GetLocalIpAddresses(CancellationToken cancellationToken) + public Task> GetLocalIpAddresses(CancellationToken cancellationToken) + { + return GetLocalIpAddressesInternal(true, 0, cancellationToken); + } + + private async Task> GetLocalIpAddressesInternal(bool allowLoopback, int limit, CancellationToken cancellationToken) { var addresses = ServerConfigurationManager .Configuration @@ -2006,22 +2019,33 @@ namespace Emby.Server.Implementations if (addresses.Count == 0) { addresses.AddRange(NetworkManager.GetLocalIpAddresses()); + } - var list = new List(); + var resultList = new List(); - foreach (var address in addresses) + foreach (var address in addresses) + { + if (!allowLoopback) { - var valid = await IsIpAddressValidAsync(address, cancellationToken).ConfigureAwait(false); - if (valid) + if (address.Equals(IpAddressInfo.Loopback) || address.Equals(IpAddressInfo.IPv6Loopback)) { - list.Add(address); + continue; } } - addresses = list; + var valid = await IsIpAddressValidAsync(address, cancellationToken).ConfigureAwait(false); + if (valid) + { + resultList.Add(address); + + if (limit > 0 && resultList.Count >= limit) + { + return resultList; + } + } } - return addresses; + return resultList; } private IpAddressInfo NormalizeConfiguredLocalAddress(string address) @@ -2042,7 +2066,6 @@ namespace Emby.Server.Implementations } private readonly ConcurrentDictionary _validAddressResults = new ConcurrentDictionary(StringComparer.OrdinalIgnoreCase); - private DateTime _lastAddressCacheClear; private async Task IsIpAddressValidAsync(IpAddressInfo address, CancellationToken cancellationToken) { if (address.Equals(IpAddressInfo.Loopback) || @@ -2054,12 +2077,6 @@ namespace Emby.Server.Implementations var apiUrl = GetLocalApiUrl(address); apiUrl += "/system/ping"; - if ((DateTime.UtcNow - _lastAddressCacheClear).TotalMinutes >= 15) - { - _lastAddressCacheClear = DateTime.UtcNow; - _validAddressResults.Clear(); - } - bool cachedResult; if (_validAddressResults.TryGetValue(apiUrl, out cachedResult)) { @@ -2087,18 +2104,19 @@ namespace Emby.Server.Implementations var valid = string.Equals(Name, result, StringComparison.OrdinalIgnoreCase); _validAddressResults.AddOrUpdate(apiUrl, valid, (k, v) => valid); - //Logger.Debug("Ping test result to {0}. Success: {1}", apiUrl, valid); + Logger.Debug("Ping test result to {0}. Success: {1}", apiUrl, valid); return valid; } } } catch (OperationCanceledException) { + Logger.Debug("Ping test result to {0}. Success: {1}", apiUrl, "Cancelled"); throw; } catch { - //Logger.Debug("Ping test result to {0}. Success: {1}", apiUrl, false); + Logger.Debug("Ping test result to {0}. Success: {1}", apiUrl, false); _validAddressResults.AddOrUpdate(apiUrl, false, (k, v) => false); return false; diff --git a/Emby.Server.Implementations/Data/SqliteItemRepository.cs b/Emby.Server.Implementations/Data/SqliteItemRepository.cs index eb0f5150f9..ddead897eb 100644 --- a/Emby.Server.Implementations/Data/SqliteItemRepository.cs +++ b/Emby.Server.Implementations/Data/SqliteItemRepository.cs @@ -4286,7 +4286,7 @@ namespace Emby.Server.Implementations.Data if (query.MinParentalRating.HasValue) { - whereClauses.Add("InheritedParentalRatingValue<=@MinParentalRating"); + whereClauses.Add("InheritedParentalRatingValue>=@MinParentalRating"); if (statement != null) { statement.TryBind("@MinParentalRating", query.MinParentalRating.Value); diff --git a/Emby.Server.Implementations/Emby.Server.Implementations.csproj b/Emby.Server.Implementations/Emby.Server.Implementations.csproj index 7ccf54d20f..cef37910ee 100644 --- a/Emby.Server.Implementations/Emby.Server.Implementations.csproj +++ b/Emby.Server.Implementations/Emby.Server.Implementations.csproj @@ -708,6 +708,8 @@ + + diff --git a/Emby.Server.Implementations/LiveTv/TunerHosts/M3UTunerHost.cs b/Emby.Server.Implementations/LiveTv/TunerHosts/M3UTunerHost.cs index e6c9b184e5..04c5303f11 100644 --- a/Emby.Server.Implementations/LiveTv/TunerHosts/M3UTunerHost.cs +++ b/Emby.Server.Implementations/LiveTv/TunerHosts/M3UTunerHost.cs @@ -17,6 +17,7 @@ using MediaBrowser.Controller.Configuration; using MediaBrowser.Controller.MediaEncoding; using MediaBrowser.Model.Serialization; using MediaBrowser.Model.System; +using System.IO; namespace Emby.Server.Implementations.LiveTv.TunerHosts { @@ -75,6 +76,14 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts return Task.FromResult(list); } + private string[] _disallowedSharedStreamExtensions = new string[] + { + ".mkv", + ".mp4", + ".m3u8", + ".mpd" + }; + protected override async Task GetChannelStream(TunerHostInfo info, string channelId, string streamId, CancellationToken cancellationToken) { var tunerCount = info.TunerCount; @@ -95,7 +104,12 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts if (mediaSource.Protocol == MediaProtocol.Http && !mediaSource.RequiresLooping) { - return new SharedHttpStream(mediaSource, info, streamId, FileSystem, _httpClient, Logger, Config.ApplicationPaths, _appHost, _environment); + var extension = Path.GetExtension(mediaSource.Path) ?? string.Empty; + + if (!_disallowedSharedStreamExtensions.Contains(extension, StringComparer.OrdinalIgnoreCase)) + { + return new SharedHttpStream(mediaSource, info, streamId, FileSystem, _httpClient, Logger, Config.ApplicationPaths, _appHost, _environment); + } } return new LiveStream(mediaSource, info, _environment, FileSystem, Logger, Config.ApplicationPaths); diff --git a/Emby.Server.Implementations/LiveTv/TunerHosts/SharedHttpStream.cs b/Emby.Server.Implementations/LiveTv/TunerHosts/SharedHttpStream.cs index b8c7c7b18e..af7491e862 100644 --- a/Emby.Server.Implementations/LiveTv/TunerHosts/SharedHttpStream.cs +++ b/Emby.Server.Implementations/LiveTv/TunerHosts/SharedHttpStream.cs @@ -71,7 +71,8 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts } else if (contentType.IndexOf("mp4", StringComparison.OrdinalIgnoreCase) != -1 || contentType.IndexOf("dash", StringComparison.OrdinalIgnoreCase) != -1 || - contentType.IndexOf("mpegURL", StringComparison.OrdinalIgnoreCase) != -1) + contentType.IndexOf("mpegURL", StringComparison.OrdinalIgnoreCase) != -1 || + contentType.IndexOf("text/", StringComparison.OrdinalIgnoreCase) != -1) { requiresRemux = true; } diff --git a/Emby.Server.Implementations/Localization/Core/ca.json b/Emby.Server.Implementations/Localization/Core/ca.json index f21a0b2953..7c55540e5b 100644 --- a/Emby.Server.Implementations/Localization/Core/ca.json +++ b/Emby.Server.Implementations/Localization/Core/ca.json @@ -1,74 +1,74 @@ { "Latest": "Darreres", "ValueSpecialEpisodeName": "Especial - {0}", - "Inherit": "Inherit", - "Books": "Books", - "Music": "Music", - "Games": "Games", - "Photos": "Photos", - "MixedContent": "Mixed content", - "MusicVideos": "Music videos", - "HomeVideos": "Home videos", - "Playlists": "Playlists", - "HeaderRecordingGroups": "Recording Groups", + "Inherit": "Heretat", + "Books": "Llibres", + "Music": "M\u00fasica", + "Games": "Jocs", + "Photos": "Fotos", + "MixedContent": "Contingut mesclat", + "MusicVideos": "V\u00eddeos musicals", + "HomeVideos": "V\u00eddeos dom\u00e8stics", + "Playlists": "Llistes de reproducci\u00f3", + "HeaderRecordingGroups": "Grups d'Enregistrament", "HeaderContinueWatching": "Continua Veient", - "HeaderFavoriteArtists": "Favorite Artists", - "HeaderFavoriteSongs": "Favorite Songs", + "HeaderFavoriteArtists": "Artistes Preferits", + "HeaderFavoriteSongs": "Can\u00e7ons Preferides", "HeaderAlbumArtists": "Album Artists", - "HeaderFavoriteAlbums": "Favorite Albums", - "HeaderFavoriteEpisodes": "Favorite Episodes", + "HeaderFavoriteAlbums": "\u00c0lbums Preferits", + "HeaderFavoriteEpisodes": "Episodis Preferits", "HeaderFavoriteShows": "Programes Preferits", "HeaderNextUp": "A continuaci\u00f3", - "Favorites": "Favorites", - "Collections": "Collections", - "Channels": "Channels", - "Movies": "Movies", - "Albums": "Albums", - "Artists": "Artists", - "Folders": "Folders", - "Songs": "Songs", - "TvShows": "TV Shows", - "Shows": "Shows", + "Favorites": "Preferits", + "Collections": "Col\u00b7leccions", + "Channels": "Canals", + "Movies": "Pel\u00b7l\u00edcules", + "Albums": "\u00c0lbums", + "Artists": "Artistes", + "Folders": "Directoris", + "Songs": "Can\u00e7ons", + "TvShows": "Espectacles de TV", + "Shows": "Espectacles", "Genres": "G\u00e8neres", - "NameSeasonNumber": "Season {0}", - "AppDeviceValues": "App: {0}, Device: {1}", - "UserDownloadingItemWithValues": "{0} is downloading {1}", - "HeaderLiveTV": "Live TV", - "ChapterNameValue": "Chapter {0}", - "ScheduledTaskFailedWithName": "{0} failed", - "LabelRunningTimeValue": "Running time: {0}", - "ScheduledTaskStartedWithName": "{0} started", - "VersionNumber": "Version {0}", - "PluginInstalledWithName": "{0} was installed", - "StartupEmbyServerIsLoading": "Emby Server is loading. Please try again shortly.", - "PluginUpdatedWithName": "{0} was updated", - "PluginUninstalledWithName": "{0} was uninstalled", - "ItemAddedWithName": "{0} was added to the library", - "ItemRemovedWithName": "{0} was removed from the library", - "LabelIpAddressValue": "Ip address: {0}", - "DeviceOnlineWithName": "{0} is connected", - "UserOnlineFromDevice": "{0} is online from {1}", - "ProviderValue": "Provider: {0}", - "SubtitlesDownloadedForItem": "Subtitles downloaded for {0}", - "UserCreatedWithName": "User {0} has been created", - "UserPasswordChangedWithName": "Password has been changed for user {0}", - "UserDeletedWithName": "User {0} has been deleted", - "UserConfigurationUpdatedWithName": "User configuration has been updated for {0}", - "MessageServerConfigurationUpdated": "Server configuration has been updated", - "MessageNamedServerConfigurationUpdatedWithValue": "Server configuration section {0} has been updated", - "MessageApplicationUpdated": "Emby Server has been updated", - "FailedLoginAttemptWithUserName": "Failed login attempt from {0}", - "AuthenticationSucceededWithUserName": "{0} successfully authenticated", - "UserOfflineFromDevice": "{0} has disconnected from {1}", - "DeviceOfflineWithName": "{0} has disconnected", - "UserStartedPlayingItemWithValues": "{0} has started playing {1}", - "UserStoppedPlayingItemWithValues": "{0} has stopped playing {1}", - "NotificationOptionPluginError": "Plugin failure", - "NotificationOptionApplicationUpdateAvailable": "Application update available", - "NotificationOptionApplicationUpdateInstalled": "Application update installed", - "NotificationOptionPluginUpdateInstalled": "Plugin update installed", - "NotificationOptionPluginInstalled": "Plugin installed", - "NotificationOptionPluginUninstalled": "Plugin uninstalled", + "NameSeasonNumber": "Temporada {0}", + "AppDeviceValues": "App: {0}, Dispositiu: {1}", + "UserDownloadingItemWithValues": "{0} est\u00e0 descarregant {1}", + "HeaderLiveTV": "TV en Directe", + "ChapterNameValue": "Episodi {0}", + "ScheduledTaskFailedWithName": "{0} ha fallat", + "LabelRunningTimeValue": "Temps en marxa: {0}", + "ScheduledTaskStartedWithName": "{0} iniciat", + "VersionNumber": "Versi\u00f3 {0}", + "PluginInstalledWithName": "{0} ha estat instal\u00b7lat", + "StartupEmbyServerIsLoading": "El Servidor d'Emby està carregant. Si et plau, prova de nou en breus.", + "PluginUpdatedWithName": "{0} ha estat actualitzat", + "PluginUninstalledWithName": "{0} ha estat desinstal\u00b7lat", + "ItemAddedWithName": "{0} afegit a la biblioteca", + "ItemRemovedWithName": "{0} eliminat de la biblioteca", + "LabelIpAddressValue": "Adre\u00e7a IP: {0}", + "DeviceOnlineWithName": "{0} est\u00e0 connectat", + "UserOnlineFromDevice": "{0} est\u00e0 connectat des de {1}", + "ProviderValue": "Prove\u00efdor: {0}", + "SubtitlesDownloadedForItem": "Subt\u00edtols descarregats per a {0}", + "UserCreatedWithName": "S'ha creat l'usuari {0}", + "UserPasswordChangedWithName": "La contrasenya ha estat canviada per a l'usuari {0}", + "UserDeletedWithName": "L'usuari {0} ha estat eliminat", + "UserConfigurationUpdatedWithName": "La configuraci\u00f3 d'usuari ha estat actualitzada per a {0}", + "MessageServerConfigurationUpdated": "S'ha actualitzat la configuraci\u00f3 del servidor", + "MessageNamedServerConfigurationUpdatedWithValue": "La secci\u00f3 de configuraci\u00f3 {0} ha estat actualitzada", + "MessageApplicationUpdated": "El Servidor d'Emby ha estat actualitzat", + "FailedLoginAttemptWithUserName": "Intent de connexi\u00f3 fallit des de {0}", + "AuthenticationSucceededWithUserName": "{0} s'ha autenticat correctament", + "UserOfflineFromDevice": "{0} s'ha desconnectat de {1}", + "DeviceOfflineWithName": "{0} s'ha desconnectat", + "UserStartedPlayingItemWithValues": "{0} ha comen\u00e7at a reproduir {1}", + "UserStoppedPlayingItemWithValues": "{0} ha parat de reproduir {1}", + "NotificationOptionPluginError": "Un component ha fallat", + "NotificationOptionApplicationUpdateAvailable": "Actualitzaci\u00f3 d'aplicaci\u00f3 disponible", + "NotificationOptionApplicationUpdateInstalled": "Actualitzaci\u00f3 d'aplicaci\u00f3 instal\u00b7lada", + "NotificationOptionPluginUpdateInstalled": "Actualitzaci\u00f3 de complement instal\u00b7lada", + "NotificationOptionPluginInstalled": "Complement instal\u00b7lat", + "NotificationOptionPluginUninstalled": "Complement desinstal\u00b7lat", "NotificationOptionVideoPlayback": "Video playback started", "NotificationOptionAudioPlayback": "Audio playback started", "NotificationOptionGamePlayback": "Game playback started", diff --git a/Emby.Server.Implementations/Localization/Core/de.json b/Emby.Server.Implementations/Localization/Core/de.json index 7bab689ebb..bcfadb61c2 100644 --- a/Emby.Server.Implementations/Localization/Core/de.json +++ b/Emby.Server.Implementations/Localization/Core/de.json @@ -7,7 +7,7 @@ "Games": "Spiele", "Photos": "Fotos", "MixedContent": "Gemischte Inhalte", - "MusicVideos": "Musik-Videos", + "MusicVideos": "Musikvideos", "HomeVideos": "Heimvideos", "Playlists": "Wiedergabelisten", "HeaderRecordingGroups": "Aufnahme-Gruppen", @@ -27,7 +27,7 @@ "Artists": "Interpreten", "Folders": "Verzeichnisse", "Songs": "Songs", - "TvShows": "TV Shows", + "TvShows": "TV Sendungen", "Shows": "Serien", "Genres": "Genres", "NameSeasonNumber": "Staffel {0}", diff --git a/Emby.Server.Implementations/Localization/Core/el.json b/Emby.Server.Implementations/Localization/Core/el.json new file mode 100644 index 0000000000..ab229e1118 --- /dev/null +++ b/Emby.Server.Implementations/Localization/Core/el.json @@ -0,0 +1,91 @@ +{ + "Latest": "\u03a4\u03b5\u03bb\u03b5\u03c5\u03c4\u03b1\u03af\u03b1", + "ValueSpecialEpisodeName": "\u0395\u03b9\u03b4\u03b9\u03ba\u03ac - {0} ", + "Inherit": "Inherit", + "Books": "\u0392\u03b9\u03b2\u03bb\u03af\u03b1", + "Music": "\u039c\u03bf\u03c5\u03c3\u03b9\u03ba\u03ae", + "Games": "\u03a0\u03b1\u03b9\u03c7\u03bd\u03af\u03b4\u03b9\u03b1", + "Photos": "\u03a6\u03c9\u03c4\u03bf\u03b3\u03c1\u03b1\u03c6\u03af\u03b5\u03c2", + "MixedContent": "\u0391\u03bd\u03ac\u03bc\u03b5\u03b9\u03ba\u03c4\u03bf \u03a0\u03b5\u03c1\u03b9\u03b5\u03c7\u03cc\u03bc\u03b5\u03bd\u03bf", + "MusicVideos": "\u039c\u03bf\u03c5\u03c3\u03b9\u03ba\u03ac \u03b2\u03af\u03bd\u03c4\u03b5\u03bf", + "HomeVideos": "\u03a0\u03c1\u03bf\u03c3\u03c9\u03c0\u03b9\u03ba\u03ac \u0392\u03af\u03bd\u03c4\u03b5\u03bf", + "Playlists": "\u039b\u03af\u03c3\u03c4\u03b5\u03c2 \u03b1\u03bd\u03b1\u03c0\u03b1\u03c1\u03b1\u03b3\u03c9\u03b3\u03ae\u03c2", + "HeaderRecordingGroups": "\u0393\u03ba\u03c1\u03bf\u03c5\u03c0 \u0395\u03b3\u03b3\u03c1\u03b1\u03c6\u03ce\u03bd", + "HeaderContinueWatching": "\u03a3\u03c5\u03bd\u03b5\u03c7\u03af\u03c3\u03c4\u03b5 \u03c4\u03b7\u03bd \u03c0\u03b1\u03c1\u03b1\u03ba\u03bf\u03bb\u03bf\u03cd\u03b8\u03b7\u03c3\u03b7", + "HeaderFavoriteArtists": "\u0391\u03b3\u03b1\u03c0\u03b7\u03bc\u03ad\u03bd\u03bf\u03b9 \u039a\u03b1\u03bb\u03bb\u03b9\u03c4\u03ad\u03c7\u03bd\u03b5\u03c2", + "HeaderFavoriteSongs": "\u0391\u03b3\u03b1\u03c0\u03b7\u03bc\u03ad\u03bd\u03b1 \u03a4\u03c1\u03b1\u03b3\u03bf\u03cd\u03b4\u03b9\u03b1", + "HeaderAlbumArtists": "\u0386\u03bb\u03bc\u03c0\u03bf\u03c5\u03bc \u039a\u03b1\u03bb\u03bb\u03b9\u03c4\u03b5\u03c7\u03bd\u03ce\u03bd", + "HeaderFavoriteAlbums": "\u0391\u03b3\u03b1\u03c0\u03b7\u03bc\u03ad\u03bd\u03b1 \u0386\u03bb\u03bc\u03c0\u03bf\u03c5\u03bc", + "HeaderFavoriteEpisodes": "\u0391\u03b3\u03b1\u03c0\u03b7\u03bc\u03ad\u03bd\u03b1 \u03b5\u03c0\u03b5\u03b9\u03c3\u03cc\u03b4\u03b9\u03b1", + "HeaderFavoriteShows": "\u0391\u03b3\u03b1\u03c0\u03b7\u03bc\u03ad\u03bd\u03b5\u03c2 \u03a3\u03b5\u03b9\u03c1\u03ad\u03c2", + "HeaderNextUp": "\u0395\u03c0\u03cc\u03bc\u03b5\u03bd\u03bf", + "Favorites": "\u0391\u03b3\u03b1\u03c0\u03b7\u03bc\u03ad\u03bd\u03b1", + "Collections": "\u03a3\u03c5\u03bb\u03bb\u03bf\u03b3\u03ad\u03c2", + "Channels": "\u039a\u03b1\u03bd\u03ac\u03bb\u03b9\u03b1", + "Movies": "\u03a4\u03b1\u03b9\u03bd\u03af\u03b5\u03c2", + "Albums": "\u0386\u03bb\u03bc\u03c0\u03bf\u03c5\u03bc", + "Artists": "\u039a\u03b1\u03bb\u03bb\u03b9\u03c4\u03ad\u03c7\u03bd\u03b5\u03c2", + "Folders": "\u03a6\u03ac\u03ba\u03b5\u03bb\u03bf\u03b9", + "Songs": "\u03a4\u03c1\u03b1\u03b3\u03bf\u03cd\u03b4\u03b9\u03b1", + "TvShows": "\u03a4\u03b7\u03bb\u03b5\u03bf\u03c0\u03c4\u03b9\u03ba\u03ac \u03c0\u03c1\u03bf\u03b3\u03c1\u03ac\u03bc\u03bc\u03b1\u03c4\u03b1", + "Shows": "\u03a3\u03b5\u03b9\u03c1\u03ad\u03c2", + "Genres": "\u0395\u03af\u03b4\u03b7", + "NameSeasonNumber": "\u039a\u03cd\u03ba\u03bb\u03bf\u03c2 {0}", + "AppDeviceValues": "\u0395\u03c6\u03b1\u03c1\u03bc\u03bf\u03b3\u03ae: {0}, \u03a3\u03c5\u03c3\u03ba\u03b5\u03c5\u03ae: {1}", + "UserDownloadingItemWithValues": "{0} \u03ba\u03b1\u03c4\u03b5\u03b2\u03ac\u03b6\u03b5\u03b9 {1}", + "HeaderLiveTV": "\u0396\u03c9\u03bd\u03c4\u03b1\u03bd\u03ae \u03a4\u03b7\u03bb\u03b5\u03cc\u03c1\u03b1\u03c3\u03b7", + "ChapterNameValue": "\u039a\u03b5\u03c6\u03ac\u03bb\u03b1\u03b9\u03bf {0}", + "ScheduledTaskFailedWithName": "{0} \u0391\u03c0\u03bf\u03c4\u03c5\u03c7\u03af\u03b1", + "LabelRunningTimeValue": "\u0394\u03b9\u03ac\u03c1\u03ba\u03b5\u03b9\u03b1: {0}", + "ScheduledTaskStartedWithName": "{0} \u03ad\u03bd\u03b1\u03c1\u03be\u03b7", + "VersionNumber": "\u0388\u03ba\u03b4\u03bf\u03c3\u03b7 {0}", + "PluginInstalledWithName": "{0} \u03b5\u03b3\u03ba\u03b1\u03c4\u03b1\u03c3\u03c4\u03ae\u03b8\u03b7\u03ba\u03b5", + "StartupEmbyServerIsLoading": "\u039f \u03a3\u03ad\u03c1\u03b2\u03b5\u03c1 \u03c6\u03bf\u03c1\u03c4\u03ce\u03bd\u03b5\u03b9. \u03a0\u03b1\u03c1\u03b1\u03ba\u03b1\u03bb\u03ce \u03b4\u03bf\u03ba\u03b9\u03bc\u03ac\u03c3\u03c4\u03b5 \u03c3\u03b5 \u03bb\u03af\u03b3\u03bf", + "PluginUpdatedWithName": "{0} \u03ad\u03c7\u03b5\u03b9 \u03b1\u03bd\u03b1\u03b2\u03b1\u03b8\u03bc\u03b9\u03c3\u03c4\u03b5\u03af", + "PluginUninstalledWithName": "{0} \u03ad\u03c7\u03b5\u03b9 \u03b1\u03c0\u03b5\u03b3\u03ba\u03b1\u03c4\u03b1\u03c3\u03c4\u03b1\u03b8\u03b5\u03af", + "ItemAddedWithName": "{0} \u03c0\u03c1\u03bf\u03c3\u03c4\u03ad\u03b8\u03b7\u03ba\u03b5 \u03c3\u03c4\u03b7 \u03b2\u03b9\u03b2\u03bb\u03b9\u03bf\u03b8\u03ae\u03ba\u03b7", + "ItemRemovedWithName": "{0} \u03b4\u03b9\u03b1\u03b3\u03c1\u03ac\u03c6\u03b7\u03ba\u03b5 \u03b1\u03c0\u03cc \u03c4\u03b7 \u03b2\u03b9\u03b2\u03bb\u03b9\u03bf\u03b8\u03ae\u03ba\u03b7", + "LabelIpAddressValue": "\u0394\u03b9\u03b5\u03cd\u03b8\u03c5\u03bd\u03c3\u03b7 IP: {0}", + "DeviceOnlineWithName": "{0} \u03c3\u03c5\u03bd\u03b4\u03ad\u03b8\u03b7\u03ba\u03b5", + "UserOnlineFromDevice": "{0} \u03b5\u03af\u03bd\u03b1\u03b9 \u03c3\u03c5\u03bd\u03b4\u03b5\u03b4\u03b5\u03bc\u03ad\u03bd\u03bf\u03c2 \u03b1\u03c0\u03bf {1}", + "ProviderValue": "\u03a0\u03ac\u03c1\u03bf\u03c7\u03bf\u03c2: {0}", + "SubtitlesDownloadedForItem": "\u03a5\u03c0\u03cc\u03c4\u03b9\u03c4\u03bb\u03bf\u03b9 \u03bb\u03ae\u03c6\u03b8\u03b7\u03ba\u03b1\u03bd \u03b1\u03c0\u03cc {0}", + "UserCreatedWithName": "\u0394\u03b7\u03bc\u03b9\u03bf\u03c5\u03c1\u03b3\u03ae\u03b8\u03b7\u03ba\u03b5 \u03bf \u03c7\u03c1\u03ae\u03c3\u03c4\u03b7\u03c2 {0}", + "UserPasswordChangedWithName": "\u039f \u03ba\u03c9\u03b4\u03b9\u03ba\u03cc\u03c2 \u03c4\u03bf\u03c5 \u03c7\u03c1\u03ae\u03c3\u03c4\u03b7 {0} \u03b1\u03bb\u03bb\u03ac\u03c7\u03b8\u03b7\u03ba\u03b5", + "UserDeletedWithName": "\u039f \u03c7\u03c1\u03ae\u03c3\u03c4\u03b7\u03c2 {0} \u03b4\u03b9\u03b5\u03b3\u03c1\u03ac\u03c6\u03b5\u03b9", + "UserConfigurationUpdatedWithName": "\u039f\u03b9 \u03c1\u03c5\u03b8\u03bc\u03af\u03c3\u03b5\u03b9\u03c2 \u03c4\u03bf\u03c5 \u03c7\u03c1\u03ae\u03c3\u03c4\u03b7 {0} \u03ad\u03c7\u03bf\u03c5\u03bd \u03b1\u03bb\u03bb\u03ac\u03be\u03b5\u03b9", + "MessageServerConfigurationUpdated": "Server configuration has been updated", + "MessageNamedServerConfigurationUpdatedWithValue": "\u039f\u03b9 \u03c1\u03c5\u03b8\u03bc\u03af\u03c3\u03b5\u03b9\u03c2 \u03c4\u03bf\u03bc\u03ad\u03b1 \u03c4\u03bf\u03c5 \u03b4\u03b9\u03b1\u03ba\u03bf\u03bc\u03b9\u03c3\u03c4\u03ae {0} \u03ad\u03c7\u03bf\u03c5\u03bd \u03b1\u03bb\u03bb\u03ac\u03be\u03b5\u03b9", + "MessageApplicationUpdated": "\u039f \u03a3\u03ad\u03c1\u03b2\u03b5\u03c1 \u03ad\u03c7\u03b5\u03b9 \u03b1\u03bd\u03b1\u03b2\u03b1\u03b8\u03bc\u03b9\u03c3\u03c4\u03b5\u03af", + "FailedLoginAttemptWithUserName": "\u0391\u03c0\u03bf\u03c4\u03c5\u03c7\u03af\u03b1 \u03c0\u03c1\u03bf\u03c3\u03c0\u03ac\u03b8\u03b5\u03b9\u03b1 \u03b5\u03b9\u03c3\u03cc\u03b4\u03bf\u03c5 \u03b1\u03c0\u03cc {0}", + "AuthenticationSucceededWithUserName": "{0} \u03b5\u03c0\u03b9\u03c4\u03c5\u03c7\u03b5\u03af\u03c2 \u03c3\u03cd\u03bd\u03b4\u03b5\u03c3\u03b7", + "UserOfflineFromDevice": "{0} \u03b1\u03c0\u03bf\u03c3\u03c5\u03bd\u03b4\u03ad\u03b8\u03b7\u03ba\u03b5 \u03b1\u03c0\u03cc {1}", + "DeviceOfflineWithName": "{0} \u03b1\u03c0\u03bf\u03c3\u03c5\u03bd\u03b4\u03ad\u03b8\u03b7\u03ba\u03b5", + "UserStartedPlayingItemWithValues": "{0} \u03be\u03b5\u03ba\u03af\u03bd\u03b7\u03c3\u03b5 \u03bd\u03b1 \u03c0\u03b1\u03af\u03b6\u03b5\u03b9 {1}", + "UserStoppedPlayingItemWithValues": "{0} \u03c3\u03c4\u03b1\u03bc\u03ac\u03c4\u03b7\u03c3\u03b5 \u03bd\u03b1 \u03c0\u03b1\u03af\u03b6\u03b5\u03b9 {1}", + "NotificationOptionPluginError": "\u0391\u03c0\u03bf\u03c4\u03c5\u03c7\u03af\u03b1 \u03c0\u03c1\u03bf\u03c3\u03b8\u03ad\u03c4\u03bf\u03c5", + "NotificationOptionApplicationUpdateAvailable": "\u03a5\u03c0\u03ac\u03c1\u03c7\u03b5\u03b9 \u03b1\u03bd\u03b1\u03b2\u03ac\u03b8\u03bc\u03b9\u03c3\u03b7", + "NotificationOptionApplicationUpdateInstalled": "\u0397 \u03b1\u03bd\u03b1\u03b2\u03ac\u03b8\u03bc\u03b9\u03c3\u03b7 \u03bf\u03bb\u03bf\u03ba\u03bb\u03b7\u03c1\u03ce\u03b8\u03b7\u03ba\u03b5", + "NotificationOptionPluginUpdateInstalled": "\u0397 \u03b1\u03bd\u03b1\u03b2\u03ac\u03b8\u03bc\u03b9\u03c3\u03b7 \u03c4\u03bf\u03c5 plugin \u03bf\u03bb\u03bf\u03ba\u03bb\u03b7\u03c1\u03ce\u03b8\u03b7\u03ba\u03b5", + "NotificationOptionPluginInstalled": "\u03a4\u03bf plugin \u03b5\u03b3\u03ba\u03b1\u03c4\u03b1\u03c3\u03c4\u03ac\u03b8\u03b7\u03ba\u03b5", + "NotificationOptionPluginUninstalled": "\u03a4\u03bf plugin \u03b1\u03c0\u03b5\u03b3\u03ba\u03b1\u03c4\u03b1\u03c3\u03c4\u03ac\u03b8\u03b7\u03ba\u03b5", + "NotificationOptionVideoPlayback": "\u03a4\u03bf \u03b2\u03af\u03bd\u03c4\u03b5\u03bf \u03c0\u03c1\u03bf\u03b2\u03ac\u03bb\u03bb\u03b5\u03c4\u03b1\u03b9", + "NotificationOptionAudioPlayback": "\u0397 \u03bc\u03bf\u03c5\u03c3\u03b9\u03ba\u03ae \u03c0\u03b1\u03af\u03b6\u03b5\u03b9", + "NotificationOptionGamePlayback": "\u03a4\u03bf \u03c0\u03b1\u03b9\u03c7\u03bd\u03af\u03b4\u03b9 \u03be\u03b5\u03ba\u03af\u03bd\u03b7\u03c3\u03b5", + "NotificationOptionVideoPlaybackStopped": "\u03a4\u03bf \u03b2\u03af\u03bd\u03c4\u03b5\u03bf \u03c3\u03c4\u03b1\u03bc\u03ac\u03c4\u03b7\u03c3\u03b5", + "NotificationOptionAudioPlaybackStopped": "\u0397 \u03bc\u03bf\u03c5\u03c3\u03b9\u03ba\u03ae \u03c3\u03c4\u03b1\u03bc\u03ac\u03c4\u03b7\u03c3\u03b5", + "NotificationOptionGamePlaybackStopped": "\u03a4\u03bf \u03c0\u03b1\u03b9\u03c7\u03bd\u03af\u03b4\u03b9 \u03c3\u03c4\u03b1\u03bc\u03ac\u03c4\u03b7\u03c3\u03b5", + "NotificationOptionTaskFailed": "\u0391\u03c0\u03bf\u03c4\u03c5\u03c7\u03af\u03b1 \u03c0\u03c1\u03bf\u03b3\u03c1\u03b1\u03bc\u03bc\u03b1\u03c4\u03b9\u03c3\u03bc\u03ad\u03bd\u03b7\u03c2 \u03b5\u03c1\u03b3\u03b1\u03c3\u03af\u03b1\u03c2", + "NotificationOptionInstallationFailed": "\u0391\u03c0\u03bf\u03c4\u03c5\u03c7\u03af\u03b1 \u03b5\u03b3\u03ba\u03b1\u03c4\u03ac\u03c3\u03c4\u03b1\u03c3\u03b7\u03c2", + "NotificationOptionNewLibraryContent": "\u03a0\u03c1\u03bf\u03c3\u03c4\u03ad\u03b8\u03b7\u03ba\u03b5 \u03bd\u03ad\u03bf \u03c0\u03b5\u03c1\u03b9\u03b5\u03c7\u03cc\u03bc\u03b5\u03bd\u03bf", + "NotificationOptionCameraImageUploaded": "Camera image uploaded", + "NotificationOptionUserLockedOut": "\u039f \u03c7\u03c1\u03ae\u03c3\u03c4\u03b7\u03c2 \u03b1\u03c0\u03bf\u03ba\u03bb\u03b5\u03af\u03c3\u03c4\u03b7\u03ba\u03b5", + "NotificationOptionServerRestartRequired": "\u0391\u03c0\u03b1\u03b9\u03c4\u03b5\u03af\u03c4\u03b1\u03b9 \u03b5\u03c0\u03b1\u03bd\u03b5\u03ba\u03ba\u03af\u03bd\u03b7\u03c3\u03b7 \u03c4\u03bf\u03c5 \u03b4\u03b9\u03b1\u03ba\u03bf\u03bc\u03b9\u03c3\u03c4\u03ae", + "UserLockedOutWithName": "\u039f \u03c7\u03c1\u03ae\u03c3\u03c4\u03b7\u03c2 {0} \u03b1\u03c0\u03bf\u03ba\u03bb\u03b5\u03af\u03c3\u03c4\u03b7\u03ba\u03b5", + "SubtitleDownloadFailureForItem": "\u0391\u03b4\u03c5\u03bd\u03b1\u03bc\u03af\u03b1 \u03bb\u03ae\u03c8\u03b7\u03c2 \u03c5\u03c0\u03bf\u03c4\u03af\u03c4\u03bb\u03c9\u03bd \u03b1\u03c0\u03cc {0}", + "Sync": "\u03a3\u03c5\u03b3\u03c7\u03c1\u03bf\u03bd\u03b9\u03c3\u03bc\u03cc\u03c2", + "User": "\u03a7\u03c1\u03ae\u03c3\u03c4\u03b7\u03c2", + "System": "\u03a3\u03cd\u03c3\u03c4\u03b7\u03bc\u03b1", + "Application": "\u0395\u03c6\u03b1\u03c1\u03bc\u03bf\u03b3\u03ae", + "Plugin": "\u03a0\u03c1\u03cc\u03c3\u03b8\u03b5\u03c4\u03bf" +} \ No newline at end of file diff --git a/Emby.Server.Implementations/Localization/Core/es-MX.json b/Emby.Server.Implementations/Localization/Core/es-MX.json index 2cc1dd759d..8bfaffec88 100644 --- a/Emby.Server.Implementations/Localization/Core/es-MX.json +++ b/Emby.Server.Implementations/Localization/Core/es-MX.json @@ -83,7 +83,7 @@ "NotificationOptionServerRestartRequired": "Se necesita reiniciar el Servidor", "UserLockedOutWithName": "El usuario {0} ha sido bloqueado", "SubtitleDownloadFailureForItem": "Fall\u00f3 la descarga de subt\u00edtulos para {0}", - "Sync": "Sinc.", + "Sync": "Sincronizar", "User": "Usuario", "System": "Sistema", "Application": "Aplicaci\u00f3n", diff --git a/Emby.Server.Implementations/Localization/Core/gsw.json b/Emby.Server.Implementations/Localization/Core/gsw.json new file mode 100644 index 0000000000..5c7ff5d6d8 --- /dev/null +++ b/Emby.Server.Implementations/Localization/Core/gsw.json @@ -0,0 +1,91 @@ +{ + "Latest": "Letschte", + "ValueSpecialEpisodeName": "Spezial - {0}", + "Inherit": "Hinzuef\u00fcege", + "Books": "B\u00fcecher", + "Music": "Musig", + "Games": "Spiel", + "Photos": "Fotis", + "MixedContent": "Gmischte Inhalt", + "MusicVideos": "Musigfilm", + "HomeVideos": "Heimfilmli", + "Playlists": "Abspielliste", + "HeaderRecordingGroups": "Ufnahmegruppe", + "HeaderContinueWatching": "Wiiterluege", + "HeaderFavoriteArtists": "Besti Interpret", + "HeaderFavoriteSongs": "Besti Lieder", + "HeaderAlbumArtists": "Albuminterprete", + "HeaderFavoriteAlbums": "Favorite Albums", + "HeaderFavoriteEpisodes": "Favorite Episodes", + "HeaderFavoriteShows": "Favorite Shows", + "HeaderNextUp": "Next Up", + "Favorites": "Favorites", + "Collections": "Collections", + "Channels": "Channels", + "Movies": "Movies", + "Albums": "Albums", + "Artists": "Artists", + "Folders": "Folders", + "Songs": "Songs", + "TvShows": "TV Shows", + "Shows": "Shows", + "Genres": "Genres", + "NameSeasonNumber": "Season {0}", + "AppDeviceValues": "App: {0}, Device: {1}", + "UserDownloadingItemWithValues": "{0} is downloading {1}", + "HeaderLiveTV": "Live TV", + "ChapterNameValue": "Chapter {0}", + "ScheduledTaskFailedWithName": "{0} failed", + "LabelRunningTimeValue": "Running time: {0}", + "ScheduledTaskStartedWithName": "{0} started", + "VersionNumber": "Version {0}", + "PluginInstalledWithName": "{0} was installed", + "StartupEmbyServerIsLoading": "Emby Server is loading. Please try again shortly.", + "PluginUpdatedWithName": "{0} was updated", + "PluginUninstalledWithName": "{0} was uninstalled", + "ItemAddedWithName": "{0} was added to the library", + "ItemRemovedWithName": "{0} was removed from the library", + "LabelIpAddressValue": "Ip address: {0}", + "DeviceOnlineWithName": "{0} is connected", + "UserOnlineFromDevice": "{0} is online from {1}", + "ProviderValue": "Provider: {0}", + "SubtitlesDownloadedForItem": "Subtitles downloaded for {0}", + "UserCreatedWithName": "User {0} has been created", + "UserPasswordChangedWithName": "Password has been changed for user {0}", + "UserDeletedWithName": "User {0} has been deleted", + "UserConfigurationUpdatedWithName": "User configuration has been updated for {0}", + "MessageServerConfigurationUpdated": "Server configuration has been updated", + "MessageNamedServerConfigurationUpdatedWithValue": "Server configuration section {0} has been updated", + "MessageApplicationUpdated": "Emby Server has been updated", + "FailedLoginAttemptWithUserName": "Failed login attempt from {0}", + "AuthenticationSucceededWithUserName": "{0} successfully authenticated", + "UserOfflineFromDevice": "{0} has disconnected from {1}", + "DeviceOfflineWithName": "{0} has disconnected", + "UserStartedPlayingItemWithValues": "{0} has started playing {1}", + "UserStoppedPlayingItemWithValues": "{0} has stopped playing {1}", + "NotificationOptionPluginError": "Plugin failure", + "NotificationOptionApplicationUpdateAvailable": "Application update available", + "NotificationOptionApplicationUpdateInstalled": "Application update installed", + "NotificationOptionPluginUpdateInstalled": "Plugin update installed", + "NotificationOptionPluginInstalled": "Plugin installed", + "NotificationOptionPluginUninstalled": "Plugin uninstalled", + "NotificationOptionVideoPlayback": "Video playback started", + "NotificationOptionAudioPlayback": "Audio playback started", + "NotificationOptionGamePlayback": "Game playback started", + "NotificationOptionVideoPlaybackStopped": "Video playback stopped", + "NotificationOptionAudioPlaybackStopped": "Audio playback stopped", + "NotificationOptionGamePlaybackStopped": "Game playback stopped", + "NotificationOptionTaskFailed": "Scheduled task failure", + "NotificationOptionInstallationFailed": "Installation failure", + "NotificationOptionNewLibraryContent": "New content added", + "NotificationOptionCameraImageUploaded": "Camera image uploaded", + "NotificationOptionUserLockedOut": "User locked out", + "NotificationOptionServerRestartRequired": "Server restart required", + "UserLockedOutWithName": "User {0} has been locked out", + "SubtitleDownloadFailureForItem": "Subtitles failed to download for {0}", + "Sync": "Sync", + "User": "User", + "System": "System", + "Application": "Application", + "Plugin": "Plugin" +} \ No newline at end of file diff --git a/Emby.Server.Implementations/Localization/Core/pt-BR.json b/Emby.Server.Implementations/Localization/Core/pt-BR.json index fa4eac1c49..e0a3751703 100644 --- a/Emby.Server.Implementations/Localization/Core/pt-BR.json +++ b/Emby.Server.Implementations/Localization/Core/pt-BR.json @@ -27,7 +27,7 @@ "Artists": "Artistas", "Folders": "Pastas", "Songs": "M\u00fasicas", - "TvShows": "TV Shows", + "TvShows": "S\u00e9ries de TV", "Shows": "S\u00e9ries", "Genres": "G\u00eaneros", "NameSeasonNumber": "Temporada {0}", diff --git a/Emby.Server.Implementations/Networking/NetworkManager.cs b/Emby.Server.Implementations/Networking/NetworkManager.cs index 50e9135b00..30a3ff9e86 100644 --- a/Emby.Server.Implementations/Networking/NetworkManager.cs +++ b/Emby.Server.Implementations/Networking/NetworkManager.cs @@ -19,7 +19,9 @@ namespace Emby.Server.Implementations.Networking { protected ILogger Logger { get; private set; } private DateTime _lastRefresh; - private int NetworkCacheMinutes = 360; + private int NetworkCacheMinutes = 720; + + public event EventHandler NetworkChanged; public NetworkManager(ILogger logger) { @@ -50,12 +52,22 @@ namespace Emby.Server.Implementations.Networking { 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() + { + if (NetworkChanged != null) + { + NetworkChanged(this, EventArgs.Empty); + } } private List _localIpAddresses; diff --git a/MediaBrowser.Common/Net/INetworkManager.cs b/MediaBrowser.Common/Net/INetworkManager.cs index e2ab47322a..6ddc2e7997 100644 --- a/MediaBrowser.Common/Net/INetworkManager.cs +++ b/MediaBrowser.Common/Net/INetworkManager.cs @@ -1,13 +1,15 @@ using MediaBrowser.Model.IO; using MediaBrowser.Model.Net; using System.Collections.Generic; -using System.Net; +using System; using System.Threading.Tasks; namespace MediaBrowser.Common.Net { public interface INetworkManager { + event EventHandler NetworkChanged; + /// /// Gets a random port number that is currently available /// diff --git a/MediaBrowser.Model/Dlna/StreamInfo.cs b/MediaBrowser.Model/Dlna/StreamInfo.cs index 93a46aaf40..6ded1f6dd9 100644 --- a/MediaBrowser.Model/Dlna/StreamInfo.cs +++ b/MediaBrowser.Model/Dlna/StreamInfo.cs @@ -186,6 +186,11 @@ namespace MediaBrowser.Model.Dlna return MediaSource.Path; } + if (string.IsNullOrWhiteSpace(PlaySessionId)) + { + PlaySessionId = Guid.NewGuid().ToString("N"); + } + string dlnaCommand = BuildDlnaParam(this, accessToken); return GetUrl(baseUrl, dlnaCommand); } -- 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/ApplicationHost.cs') 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/ApplicationHost.cs') 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