From d5b7ed325e5930b30fd8ecf54088d1bccdd2e8ba Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Thu, 31 Mar 2016 14:46:03 -0400 Subject: switch from Mono.Nat to Open.Nat --- .../EntryPoints/ExternalPortForwarding.cs | 221 ++++----------------- 1 file changed, 44 insertions(+), 177 deletions(-) (limited to 'MediaBrowser.Server.Implementations/EntryPoints') diff --git a/MediaBrowser.Server.Implementations/EntryPoints/ExternalPortForwarding.cs b/MediaBrowser.Server.Implementations/EntryPoints/ExternalPortForwarding.cs index 95763c43f..c0c626438 100644 --- a/MediaBrowser.Server.Implementations/EntryPoints/ExternalPortForwarding.cs +++ b/MediaBrowser.Server.Implementations/EntryPoints/ExternalPortForwarding.cs @@ -3,7 +3,6 @@ using MediaBrowser.Controller.Configuration; using MediaBrowser.Controller.Dlna; using MediaBrowser.Controller.Plugins; using MediaBrowser.Model.Logging; -using Mono.Nat; using System; using System.Collections.Generic; using System.Globalization; @@ -11,6 +10,9 @@ using System.IO; using System.Net; using System.Text; using MediaBrowser.Common.Threading; +using Open.Nat; +using System.Threading; +using System.Threading.Tasks; namespace MediaBrowser.Server.Implementations.EntryPoints { @@ -20,9 +22,8 @@ namespace MediaBrowser.Server.Implementations.EntryPoints private readonly ILogger _logger; private readonly IServerConfigurationManager _config; private readonly ISsdpHandler _ssdp; - - private PeriodicTimer _timer; - private bool _isStarted; + private CancellationTokenSource _currentCancellationTokenSource; + private TimeSpan _interval = TimeSpan.FromHours(1); public ExternalPortForwarding(ILogManager logmanager, IServerApplicationHost appHost, IServerConfigurationManager config, ISsdpHandler ssdp) { @@ -32,223 +33,89 @@ namespace MediaBrowser.Server.Implementations.EntryPoints _ssdp = ssdp; } - private string _lastConfigIdentifier; - private string GetConfigIdentifier() - { - var values = new List(); - var config = _config.Configuration; - - values.Add(config.EnableUPnP.ToString()); - values.Add(config.PublicPort.ToString(CultureInfo.InvariantCulture)); - values.Add(_appHost.HttpPort.ToString(CultureInfo.InvariantCulture)); - values.Add(_appHost.HttpsPort.ToString(CultureInfo.InvariantCulture)); - values.Add(config.EnableHttps.ToString()); - values.Add(_appHost.EnableHttps.ToString()); - - return string.Join("|", values.ToArray()); - } - - void _config_ConfigurationUpdated(object sender, EventArgs e) - { - _config.ConfigurationUpdated -= _config_ConfigurationUpdated; - - if (!string.Equals(_lastConfigIdentifier, GetConfigIdentifier(), StringComparison.OrdinalIgnoreCase)) - { - if (_isStarted) - { - DisposeNat(); - } - - Run(); - } - } - public void Run() { //NatUtility.Logger = new LogWriter(_logger); if (_config.Configuration.EnableUPnP) { - Start(); + Discover(); } - - _config.ConfigurationUpdated -= _config_ConfigurationUpdated; - _config.ConfigurationUpdated += _config_ConfigurationUpdated; } - private void Start() + private async void Discover() { - _logger.Debug("Starting NAT discovery"); - NatUtility.EnabledProtocols = new List - { - NatProtocol.Pmp - }; - NatUtility.DeviceFound += NatUtility_DeviceFound; - - // Mono.Nat does never rise this event. The event is there however it is useless. - // You could remove it with no risk. - NatUtility.DeviceLost += NatUtility_DeviceLost; - - - // it is hard to say what one should do when an unhandled exception is raised - // because there isn't anything one can do about it. Probably save a log or ignored it. - NatUtility.UnhandledException += NatUtility_UnhandledException; - NatUtility.StartDiscovery(); - - _timer = new PeriodicTimer(s => _createdRules = new List(), null, TimeSpan.FromMinutes(5), TimeSpan.FromMinutes(5)); - - _ssdp.MessageReceived += _ssdp_MessageReceived; + var discoverer = new NatDiscoverer(); - _lastConfigIdentifier = GetConfigIdentifier(); + var cancellationTokenSource = new CancellationTokenSource(10000); + _currentCancellationTokenSource = cancellationTokenSource; - _isStarted = true; - } - - void _ssdp_MessageReceived(object sender, SsdpMessageEventArgs e) - { - var endpoint = e.EndPoint as IPEndPoint; - - if (endpoint != null && e.LocalEndPoint != null) + try { - NatUtility.Handle(e.LocalEndPoint.Address, e.Message, endpoint, NatProtocol.Upnp); - } - } - - void NatUtility_UnhandledException(object sender, UnhandledExceptionEventArgs e) - { - var ex = e.ExceptionObject as Exception; + var device = await discoverer.DiscoverDeviceAsync(PortMapper.Upnp, cancellationTokenSource).ConfigureAwait(false); - if (ex == null) - { - //_logger.Error("Unidentified error reported by Mono.Nat"); + await CreateRules(device).ConfigureAwait(false); } - else + catch (OperationCanceledException) { - // Seeing some blank exceptions coming through here - //_logger.ErrorException("Error reported by Mono.Nat: ", ex); - } - } - - void NatUtility_DeviceFound(object sender, DeviceEventArgs e) - { - try - { - var device = e.Device; - _logger.Debug("NAT device found: {0}", device.LocalAddress.ToString()); - CreateRules(device); } catch (Exception ex) { - // I think it could be a good idea to log the exception because - // you are using permanent portmapping here (never expire) and that means that next time - // CreatePortMap is invoked it can fails with a 718-ConflictInMappingEntry or not. That depends - // on the router's upnp implementation (specs says it should fail however some routers don't do it) - // It also can fail with others like 727-ExternalPortOnlySupportsWildcard, 728-NoPortMapsAvailable - // and those errors (upnp errors) could be useful for diagnosting. - - // Commenting out because users are reporting problems out of our control - //_logger.ErrorException("Error creating port forwarding rules", ex); + _logger.ErrorException("Error discovering NAT devices", ex); } - } - - private List _createdRules = new List(); - private void CreateRules(INatDevice device) - { - // On some systems the device discovered event seems to fire repeatedly - // This check will help ensure we're not trying to port map the same device over and over - - var address = device.LocalAddress.ToString(); - - if (!_createdRules.Contains(address)) + finally { - _createdRules.Add(address); - - CreatePortMap(device, _appHost.HttpPort, _config.Configuration.PublicPort); - CreatePortMap(device, _appHost.HttpsPort, _config.Configuration.PublicHttpsPort); + _currentCancellationTokenSource = null; } - } - private void CreatePortMap(INatDevice device, int privatePort, int publicPort) - { - _logger.Debug("Creating port map on port {0}", privatePort); - device.CreatePortMap(new Mapping(Protocol.Tcp, privatePort, publicPort) + if (_config.Configuration.EnableUPnP) { - Description = _appHost.Name - }); + await Task.Delay(_interval).ConfigureAwait(false); + Discover(); + } } - // As I said before, this method will be never invoked. You can remove it. - void NatUtility_DeviceLost(object sender, DeviceEventArgs e) + private async Task CreateRules(NatDevice device) { - var device = e.Device; - _logger.Debug("NAT device lost: {0}", device.LocalAddress.ToString()); - } + // On some systems the device discovered event seems to fire repeatedly + // This check will help ensure we're not trying to port map the same device over and over - public void Dispose() - { - DisposeNat(); + await CreatePortMap(device, _appHost.HttpPort, _config.Configuration.PublicPort).ConfigureAwait(false); + await CreatePortMap(device, _appHost.HttpsPort, _config.Configuration.PublicHttpsPort).ConfigureAwait(false); } - private void DisposeNat() + private async Task CreatePortMap(NatDevice device, int privatePort, int publicPort) { - _logger.Debug("Stopping NAT discovery"); - - if (_timer != null) - { - _timer.Dispose(); - _timer = null; - } - - _ssdp.MessageReceived -= _ssdp_MessageReceived; + _logger.Debug("Creating port map on port {0}", privatePort); try { - // This is not a significant improvement - NatUtility.StopDiscovery(); - NatUtility.DeviceFound -= NatUtility_DeviceFound; - NatUtility.DeviceLost -= NatUtility_DeviceLost; - NatUtility.UnhandledException -= NatUtility_UnhandledException; + await device.CreatePortMapAsync(new Mapping(Protocol.Tcp, privatePort, publicPort, _appHost.Name)).ConfigureAwait(false); } - // Statements in try-block will no fail because StopDiscovery is a one-line - // method that was no chances to fail. - // public static void StopDiscovery () - // { - // searching.Reset(); - // } - // IMO you could remove the catch-block catch (Exception ex) { - _logger.ErrorException("Error stopping NAT Discovery", ex); - } - finally - { - _isStarted = false; + _logger.ErrorException("Error creating port map", ex); } } - private class LogWriter : TextWriter + public void Dispose() { - private readonly ILogger _logger; - - public LogWriter(ILogger logger) - { - _logger = logger; - } - - public override Encoding Encoding - { - get { return Encoding.UTF8; } - } - - public override void WriteLine(string format, params object[] arg) - { - _logger.Debug(format, arg); - } + DisposeNat(); + } - public override void WriteLine(string value) + private void DisposeNat() + { + if (_currentCancellationTokenSource != null) { - _logger.Debug(value); + try + { + _currentCancellationTokenSource.Cancel(); + } + catch (Exception ex) + { + _logger.ErrorException("Error calling _currentCancellationTokenSource.Cancel", ex); + } } } } -- cgit v1.2.3 From e13fcb3cd42b67374621d7e02961e4bd335a235f Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Thu, 31 Mar 2016 15:22:07 -0400 Subject: update sat/ip --- .../EntryPoints/ExternalPortForwarding.cs | 18 ++- .../LiveTv/TunerHosts/SatIp/SatIpDiscovery.cs | 170 +++++++++------------ .../MediaBrowser.Server.Implementations.csproj | 1 + 3 files changed, 83 insertions(+), 106 deletions(-) (limited to 'MediaBrowser.Server.Implementations/EntryPoints') diff --git a/MediaBrowser.Server.Implementations/EntryPoints/ExternalPortForwarding.cs b/MediaBrowser.Server.Implementations/EntryPoints/ExternalPortForwarding.cs index c0c626438..a7e5396eb 100644 --- a/MediaBrowser.Server.Implementations/EntryPoints/ExternalPortForwarding.cs +++ b/MediaBrowser.Server.Implementations/EntryPoints/ExternalPortForwarding.cs @@ -31,20 +31,26 @@ namespace MediaBrowser.Server.Implementations.EntryPoints _appHost = appHost; _config = config; _ssdp = ssdp; + + _config.ConfigurationUpdated += _config_ConfigurationUpdated; } - public void Run() + private void _config_ConfigurationUpdated(object sender, EventArgs e) { - //NatUtility.Logger = new LogWriter(_logger); + } - if (_config.Configuration.EnableUPnP) - { - Discover(); - } + public void Run() + { + Discover(); } private async void Discover() { + if (!_config.Configuration.EnableUPnP) + { + return; + } + var discoverer = new NatDiscoverer(); var cancellationTokenSource = new CancellationTokenSource(10000); diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/SatIpDiscovery.cs b/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/SatIpDiscovery.cs index da1894bb7..413ce4549 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/SatIpDiscovery.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/SatIpDiscovery.cs @@ -15,6 +15,7 @@ using MediaBrowser.Model.LiveTv; using MediaBrowser.Model.Logging; using MediaBrowser.Model.Serialization; using MediaBrowser.Model.Extensions; +using System.Xml.Linq; namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.SatIp { @@ -171,58 +172,87 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.SatIp public async Task GetInfo(string url, CancellationToken cancellationToken) { + Uri locationUri = new Uri(url); + string devicetype = ""; + string friendlyname = ""; + string uniquedevicename = ""; + string manufacturer = ""; + string manufacturerurl = ""; + string modelname = ""; + string modeldescription = ""; + string modelnumber = ""; + string modelurl = ""; + string serialnumber = ""; + string presentationurl = ""; + string capabilities = ""; + string m3u = ""; + var document = XDocument.Load(locationUri.AbsoluteUri); + var xnm = new XmlNamespaceManager(new NameTable()); + XNamespace n1 = "urn:ses-com:satip"; + XNamespace n0 = "urn:schemas-upnp-org:device-1-0"; + xnm.AddNamespace("root", n0.NamespaceName); + xnm.AddNamespace("satip:", n1.NamespaceName); + if (document.Root != null) + { + var deviceElement = document.Root.Element(n0 + "device"); + if (deviceElement != null) + { + var devicetypeElement = deviceElement.Element(n0 + "deviceType"); + if (devicetypeElement != null) + devicetype = devicetypeElement.Value; + var friendlynameElement = deviceElement.Element(n0 + "friendlyName"); + if (friendlynameElement != null) + friendlyname = friendlynameElement.Value; + var manufactureElement = deviceElement.Element(n0 + "manufacturer"); + if (manufactureElement != null) + manufacturer = manufactureElement.Value; + var manufactureurlElement = deviceElement.Element(n0 + "manufacturerURL"); + if (manufactureurlElement != null) + manufacturerurl = manufactureurlElement.Value; + var modeldescriptionElement = deviceElement.Element(n0 + "modelDescription"); + if (modeldescriptionElement != null) + modeldescription = modeldescriptionElement.Value; + var modelnameElement = deviceElement.Element(n0 + "modelName"); + if (modelnameElement != null) + modelname = modelnameElement.Value; + var modelnumberElement = deviceElement.Element(n0 + "modelNumber"); + if (modelnumberElement != null) + modelnumber = modelnumberElement.Value; + var modelurlElement = deviceElement.Element(n0 + "modelURL"); + if (modelurlElement != null) + modelurl = modelurlElement.Value; + var serialnumberElement = deviceElement.Element(n0 + "serialNumber"); + if (serialnumberElement != null) + serialnumber = serialnumberElement.Value; + var uniquedevicenameElement = deviceElement.Element(n0 + "UDN"); + if (uniquedevicenameElement != null) uniquedevicename = uniquedevicenameElement.Value; + var presentationUrlElement = deviceElement.Element(n0 + "presentationURL"); + if (presentationUrlElement != null) presentationurl = presentationUrlElement.Value; + var capabilitiesElement = deviceElement.Element(n1 + "X_SATIPCAP"); + if (capabilitiesElement != null) capabilities = capabilitiesElement.Value; + var m3uElement = deviceElement.Element(n1 + "X_SATIPM3U"); + if (m3uElement != null) m3u = m3uElement.Value; + } + } + + var result = new SatIpTunerHostInfo { Url = url, + Id = uniquedevicename, IsEnabled = true, Type = SatIpHost.DeviceType, Tuners = 1, - TunersAvailable = 1 + TunersAvailable = 1, + M3UUrl = m3u }; - using (var stream = await _httpClient.Get(url, cancellationToken).ConfigureAwait(false)) - { - using (var streamReader = new StreamReader(stream)) - { - // Use XmlReader for best performance - using (var reader = XmlReader.Create(streamReader)) - { - reader.MoveToContent(); - - // Loop through each element - while (reader.Read()) - { - if (reader.NodeType == XmlNodeType.Element) - { - switch (reader.Name) - { - case "device": - using (var subtree = reader.ReadSubtree()) - { - FillFromDeviceNode(result, subtree); - } - break; - default: - reader.Skip(); - break; - } - } - } - } - } - } - - if (string.IsNullOrWhiteSpace(result.DeviceId)) + result.FriendlyName = friendlyname; + if (string.IsNullOrWhiteSpace(result.Id)) { throw new NotImplementedException(); } - // Device hasn't implemented an m3u list - if (string.IsNullOrWhiteSpace(result.M3UUrl)) - { - result.IsEnabled = false; - } - else if (!result.M3UUrl.StartsWith("http", StringComparison.OrdinalIgnoreCase)) { var fullM3uUrl = url.Substring(0, url.LastIndexOf('/')); @@ -233,66 +263,6 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.SatIp return result; } - - private void FillFromDeviceNode(SatIpTunerHostInfo info, XmlReader reader) - { - reader.MoveToContent(); - - while (reader.Read()) - { - if (reader.NodeType == XmlNodeType.Element) - { - switch (reader.LocalName) - { - case "UDN": - { - info.DeviceId = reader.ReadElementContentAsString(); - break; - } - - case "friendlyName": - { - info.FriendlyName = reader.ReadElementContentAsString(); - break; - } - - case "satip:X_SATIPCAP": - case "X_SATIPCAP": - { - // DVBS2-2 - var value = reader.ReadElementContentAsString() ?? string.Empty; - var parts = value.Split(new[] { '-' }, StringSplitOptions.RemoveEmptyEntries); - if (parts.Length == 2) - { - int intValue; - if (int.TryParse(parts[1], NumberStyles.Any, CultureInfo.InvariantCulture, out intValue)) - { - info.TunersAvailable = intValue; - } - - if (int.TryParse(parts[0].Substring(parts[0].Length - 1), NumberStyles.Any, CultureInfo.InvariantCulture, out intValue)) - { - info.Tuners = intValue; - } - } - break; - } - - case "satip:X_SATIPM3U": - case "X_SATIPM3U": - { - // /channellist.lua?select=m3u - info.M3UUrl = reader.ReadElementContentAsString(); - break; - } - - default: - reader.Skip(); - break; - } - } - } - } } public class SatIpTunerHostInfo : TunerHostInfo diff --git a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj index 84c1cae54..14d275505 100644 --- a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj +++ b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj @@ -103,6 +103,7 @@ ..\ThirdParty\ServiceStack.Text\ServiceStack.Text.dll + ..\ThirdParty\UniversalDetector\UniversalDetector.dll -- cgit v1.2.3 From 132766ff15cd2511ca09be0f2b878ebf5ceb5632 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sat, 2 Apr 2016 00:16:18 -0400 Subject: update ffmpeg --- .../Security/MbAdmin.cs | 4 +- .../Security/PluginSecurityManager.cs | 2 +- MediaBrowser.Dlna/Ssdp/SsdpHandler.cs | 47 +++++++++++++++------- .../EntryPoints/UsageReporter.cs | 2 +- .../ApplicationHost.cs | 2 +- .../FFMpeg/FFMpegDownloadInfo.cs | 16 +++----- .../FFMpeg/FFMpegDownloader.cs | 47 +++++++++++++++------- .../MediaBrowser.ServerApplication.csproj | 2 + .../ffmpeg/ffmpegx64.7z.REMOVED.git-id | 1 + .../ffmpeg/ffmpegx86.7z.REMOVED.git-id | 1 + 10 files changed, 80 insertions(+), 44 deletions(-) create mode 100644 MediaBrowser.ServerApplication/ffmpeg/ffmpegx64.7z.REMOVED.git-id create mode 100644 MediaBrowser.ServerApplication/ffmpeg/ffmpegx86.7z.REMOVED.git-id (limited to 'MediaBrowser.Server.Implementations/EntryPoints') diff --git a/MediaBrowser.Common.Implementations/Security/MbAdmin.cs b/MediaBrowser.Common.Implementations/Security/MbAdmin.cs index ab4a83257..76ff92c2e 100644 --- a/MediaBrowser.Common.Implementations/Security/MbAdmin.cs +++ b/MediaBrowser.Common.Implementations/Security/MbAdmin.cs @@ -3,11 +3,11 @@ namespace MediaBrowser.Common.Implementations.Security { public class MbAdmin { - public const string HttpUrl = "http://www.mb3admin.com/admin/"; + public const string HttpUrl = "https://www.mb3admin.com/admin/"; /// /// Leaving as http for now until we get it squared away /// - public const string HttpsUrl = "http://www.mb3admin.com/admin/"; + public const string HttpsUrl = "https://www.mb3admin.com/admin/"; } } diff --git a/MediaBrowser.Common.Implementations/Security/PluginSecurityManager.cs b/MediaBrowser.Common.Implementations/Security/PluginSecurityManager.cs index af58c3731..4e01041bc 100644 --- a/MediaBrowser.Common.Implementations/Security/PluginSecurityManager.cs +++ b/MediaBrowser.Common.Implementations/Security/PluginSecurityManager.cs @@ -21,7 +21,7 @@ namespace MediaBrowser.Common.Implementations.Security public class PluginSecurityManager : ISecurityManager { private const string MBValidateUrl = MbAdmin.HttpsUrl + "service/registration/validate"; - private const string AppstoreRegUrl = /*MbAdmin.HttpsUrl*/ "http://mb3admin.com/admin/service/appstore/register"; + private const string AppstoreRegUrl = /*MbAdmin.HttpsUrl*/ "https://mb3admin.com/admin/service/appstore/register"; /// /// The _is MB supporter diff --git a/MediaBrowser.Dlna/Ssdp/SsdpHandler.cs b/MediaBrowser.Dlna/Ssdp/SsdpHandler.cs index 2d1ec1273..3cdeb1afd 100644 --- a/MediaBrowser.Dlna/Ssdp/SsdpHandler.cs +++ b/MediaBrowser.Dlna/Ssdp/SsdpHandler.cs @@ -36,7 +36,7 @@ namespace MediaBrowser.Dlna.Ssdp private Timer _notificationTimer; private bool _isDisposed; - private readonly ConcurrentDictionary> _devices = new ConcurrentDictionary>(); + private readonly Dictionary> _devices = new Dictionary>(); private readonly IApplicationHost _appHost; @@ -172,9 +172,12 @@ namespace MediaBrowser.Dlna.Ssdp { get { - var devices = _devices.ToList(); + lock (_devices) + { + var devices = _devices.ToList(); - return devices.SelectMany(i => i.Value).ToList(); + return devices.SelectMany(i => i.Value).ToList(); + } } } @@ -482,26 +485,42 @@ namespace MediaBrowser.Dlna.Ssdp public void RegisterNotification(string uuid, Uri descriptionUri, IPAddress address, IEnumerable services) { - var list = _devices.GetOrAdd(uuid, new List()); + lock (_devices) + { + List list; + List dl; + if (_devices.TryGetValue(uuid, out dl)) + { + list = dl; + } + else + { + list = new List(); + _devices[uuid] = list; + } - list.AddRange(services.Select(i => new UpnpDevice(uuid, i, descriptionUri, address))); + list.AddRange(services.Select(i => new UpnpDevice(uuid, i, descriptionUri, address))); - NotifyAll(); - _logger.Debug("Registered mount {0} at {1}", uuid, descriptionUri); + NotifyAll(); + _logger.Debug("Registered mount {0} at {1}", uuid, descriptionUri); + } } public void UnregisterNotification(string uuid) { - List dl; - if (_devices.TryRemove(uuid, out dl)) + lock (_devices) { - - foreach (var d in dl.ToList()) + List dl; + if (_devices.TryGetValue(uuid, out dl)) { - NotifyDevice(d, "byebye", true); - } + _devices.Remove(uuid); + foreach (var d in dl.ToList()) + { + NotifyDevice(d, "byebye", true); + } - _logger.Debug("Unregistered mount {0}", uuid); + _logger.Debug("Unregistered mount {0}", uuid); + } } } diff --git a/MediaBrowser.Server.Implementations/EntryPoints/UsageReporter.cs b/MediaBrowser.Server.Implementations/EntryPoints/UsageReporter.cs index 7e22efb23..7b3a7a30d 100644 --- a/MediaBrowser.Server.Implementations/EntryPoints/UsageReporter.cs +++ b/MediaBrowser.Server.Implementations/EntryPoints/UsageReporter.cs @@ -18,7 +18,7 @@ namespace MediaBrowser.Server.Implementations.EntryPoints private readonly IHttpClient _httpClient; private readonly IUserManager _userManager; private readonly ILogger _logger; - private const string MbAdminUrl = "http://www.mb3admin.com/admin/"; + private const string MbAdminUrl = "https://www.mb3admin.com/admin/"; public UsageReporter(IApplicationHost applicationHost, IHttpClient httpClient, IUserManager userManager, ILogger logger) { diff --git a/MediaBrowser.Server.Startup.Common/ApplicationHost.cs b/MediaBrowser.Server.Startup.Common/ApplicationHost.cs index dd7e3cc01..b5988b18a 100644 --- a/MediaBrowser.Server.Startup.Common/ApplicationHost.cs +++ b/MediaBrowser.Server.Startup.Common/ApplicationHost.cs @@ -618,7 +618,7 @@ namespace MediaBrowser.Server.Startup.Common /// Task. private async Task RegisterMediaEncoder(IProgress progress) { - var info = await new FFMpegDownloader(Logger, ApplicationPaths, HttpClient, ZipClient, FileSystemManager, NativeApp.Environment) + var info = await new FFMpegDownloader(Logger, ApplicationPaths, HttpClient, ZipClient, FileSystemManager, NativeApp.Environment, NativeApp.GetType().Assembly) .GetFFMpegInfo(NativeApp.Environment, _startupOptions, progress).ConfigureAwait(false); var mediaEncoder = new MediaEncoder(LogManager.GetLogger("MediaEncoder"), diff --git a/MediaBrowser.Server.Startup.Common/FFMpeg/FFMpegDownloadInfo.cs b/MediaBrowser.Server.Startup.Common/FFMpeg/FFMpegDownloadInfo.cs index 60cb50e30..4979ff82b 100644 --- a/MediaBrowser.Server.Startup.Common/FFMpeg/FFMpegDownloadInfo.cs +++ b/MediaBrowser.Server.Startup.Common/FFMpeg/FFMpegDownloadInfo.cs @@ -8,6 +8,7 @@ namespace MediaBrowser.Server.Startup.Common.FFMpeg public string FFProbeFilename { get; set; } public string ArchiveType { get; set; } public string[] DownloadUrls { get; set; } + public bool IsEmbedded { get; set; } public FFMpegDownloadInfo() { @@ -54,8 +55,9 @@ namespace MediaBrowser.Server.Startup.Common.FFMpeg info.FFMpegFilename = "ffmpeg.exe"; info.FFProbeFilename = "ffprobe.exe"; - info.Version = "20160131"; + info.Version = "20160401"; info.ArchiveType = "7z"; + info.IsEmbedded = true; switch (environment.SystemArchitecture) { @@ -81,17 +83,9 @@ namespace MediaBrowser.Server.Startup.Common.FFMpeg switch (environment.SystemArchitecture) { case Architecture.X86_X64: - return new[] - { - "https://github.com/MediaBrowser/Emby.Resources/raw/master/ffmpeg/windows/ffmpeg-20160131-win64.7z", - "http://ffmpeg.zeranoe.com/builds/win64/static/ffmpeg-20151109-git-480bad7-win64-static.7z" - }; + return new string[] { "MediaBrowser.ServerApplication.ffmpeg.ffmpegx64.7z" }; case Architecture.X86: - return new[] - { - "https://github.com/MediaBrowser/Emby.Resources/raw/master/ffmpeg/windows/ffmpeg-20160131-win32.7z", - "http://ffmpeg.zeranoe.com/builds/win32/static/ffmpeg-20151109-git-480bad7-win32-static.7z" - }; + return new string[] { "MediaBrowser.ServerApplication.ffmpeg.ffmpegx86.7z" }; } break; diff --git a/MediaBrowser.Server.Startup.Common/FFMpeg/FFMpegDownloader.cs b/MediaBrowser.Server.Startup.Common/FFMpeg/FFMpegDownloader.cs index 000568c15..c538b81a4 100644 --- a/MediaBrowser.Server.Startup.Common/FFMpeg/FFMpegDownloader.cs +++ b/MediaBrowser.Server.Startup.Common/FFMpeg/FFMpegDownloader.cs @@ -8,6 +8,7 @@ using System; using System.Collections.Generic; using System.IO; using System.Linq; +using System.Reflection; using System.Text; using System.Threading; using System.Threading.Tasks; @@ -23,13 +24,14 @@ namespace MediaBrowser.Server.Startup.Common.FFMpeg private readonly IZipClient _zipClient; private readonly IFileSystem _fileSystem; private readonly NativeEnvironment _environment; + private Assembly _ownerAssembly; private readonly string[] _fontUrls = { "https://github.com/MediaBrowser/MediaBrowser.Resources/raw/master/ffmpeg/ARIALUNI.7z" }; - public FFMpegDownloader(ILogger logger, IApplicationPaths appPaths, IHttpClient httpClient, IZipClient zipClient, IFileSystem fileSystem, NativeEnvironment environment) + public FFMpegDownloader(ILogger logger, IApplicationPaths appPaths, IHttpClient httpClient, IZipClient zipClient, IFileSystem fileSystem, NativeEnvironment environment, Assembly ownerAssembly) { _logger = logger; _appPaths = appPaths; @@ -37,6 +39,7 @@ namespace MediaBrowser.Server.Startup.Common.FFMpeg _zipClient = zipClient; _fileSystem = fileSystem; _environment = environment; + _ownerAssembly = ownerAssembly; } public async Task GetFFMpegInfo(NativeEnvironment environment, StartupOptions options, IProgress progress) @@ -78,11 +81,11 @@ namespace MediaBrowser.Server.Startup.Common.FFMpeg Version = version }; - _fileSystem.CreateDirectory(versionedDirectoryPath); + _fileSystem.CreateDirectory(versionedDirectoryPath); var excludeFromDeletions = new List { versionedDirectoryPath }; - if (!_fileSystem.FileExists(info.ProbePath) || !_fileSystem.FileExists(info.EncoderPath)) + if (!_fileSystem.FileExists(info.ProbePath) || !_fileSystem.FileExists(info.EncoderPath)) { // ffmpeg not present. See if there's an older version we can start with var existingVersion = GetExistingVersion(info, rootEncoderPath); @@ -106,7 +109,10 @@ namespace MediaBrowser.Server.Startup.Common.FFMpeg } } - await DownloadFonts(versionedDirectoryPath).ConfigureAwait(false); + if (_environment.OperatingSystem == OperatingSystem.Windows) + { + await DownloadFonts(versionedDirectoryPath).ConfigureAwait(false); + } DeleteOlderFolders(Path.GetDirectoryName(versionedDirectoryPath), excludeFromDeletions); @@ -189,6 +195,21 @@ namespace MediaBrowser.Server.Startup.Common.FFMpeg private async Task DownloadFFMpeg(FFMpegDownloadInfo downloadinfo, string directory, IProgress progress) { + if (downloadinfo.IsEmbedded) + { + var tempFile = Path.Combine(_appPaths.TempDirectory, Guid.NewGuid().ToString()); + _fileSystem.CreateDirectory(Path.GetDirectoryName(tempFile)); + + using (var stream = _ownerAssembly.GetManifestResourceStream(downloadinfo.DownloadUrls[0])) + { + using (var fs = _fileSystem.GetFileStream(tempFile, FileMode.Create, FileAccess.Write, FileShare.Read, true)) + { + await stream.CopyToAsync(fs).ConfigureAwait(false); + } + } + ExtractFFMpeg(downloadinfo, tempFile, directory); + } + foreach (var url in downloadinfo.DownloadUrls) { progress.Report(0); @@ -216,10 +237,8 @@ namespace MediaBrowser.Server.Startup.Common.FFMpeg { throw new ApplicationException("ffmpeg unvailable. Please install it and start the server with two command line arguments: -ffmpeg \"{PATH}\" and -ffprobe \"{PATH}\""); } - else - { - throw new ApplicationException("Unable to download required components. Please try again later."); - } + + throw new ApplicationException("Unable to download required components. Please try again later."); } private void ExtractFFMpeg(FFMpegDownloadInfo downloadinfo, string tempFile, string targetFolder) @@ -228,7 +247,7 @@ namespace MediaBrowser.Server.Startup.Common.FFMpeg var tempFolder = Path.Combine(_appPaths.TempDirectory, Guid.NewGuid().ToString()); - _fileSystem.CreateDirectory(tempFolder); + _fileSystem.CreateDirectory(tempFolder); try { @@ -247,7 +266,7 @@ namespace MediaBrowser.Server.Startup.Common.FFMpeg })) { var targetFile = Path.Combine(targetFolder, Path.GetFileName(file)); - _fileSystem.CopyFile(file, targetFile, true); + _fileSystem.CopyFile(file, targetFile, true); SetFilePermissions(targetFile); } } @@ -311,13 +330,13 @@ namespace MediaBrowser.Server.Startup.Common.FFMpeg { var fontsDirectory = Path.Combine(targetPath, "fonts"); - _fileSystem.CreateDirectory(fontsDirectory); + _fileSystem.CreateDirectory(fontsDirectory); const string fontFilename = "ARIALUNI.TTF"; var fontFile = Path.Combine(fontsDirectory, fontFilename); - if (_fileSystem.FileExists(fontFile)) + if (_fileSystem.FileExists(fontFile)) { await WriteFontConfigFile(fontsDirectory).ConfigureAwait(false); } @@ -360,7 +379,7 @@ namespace MediaBrowser.Server.Startup.Common.FFMpeg { try { - _fileSystem.CopyFile(existingFile, Path.Combine(fontsDirectory, fontFilename), true); + _fileSystem.CopyFile(existingFile, Path.Combine(fontsDirectory, fontFilename), true); return; } catch (IOException ex) @@ -422,7 +441,7 @@ namespace MediaBrowser.Server.Startup.Common.FFMpeg const string fontConfigFilename = "fonts.conf"; var fontConfigFile = Path.Combine(fontsDirectory, fontConfigFilename); - if (!_fileSystem.FileExists(fontConfigFile)) + if (!_fileSystem.FileExists(fontConfigFile)) { var contents = string.Format("{0}ArialArial Unicode MS", fontsDirectory); diff --git a/MediaBrowser.ServerApplication/MediaBrowser.ServerApplication.csproj b/MediaBrowser.ServerApplication/MediaBrowser.ServerApplication.csproj index 6ba91c06f..d1bf58dda 100644 --- a/MediaBrowser.ServerApplication/MediaBrowser.ServerApplication.csproj +++ b/MediaBrowser.ServerApplication/MediaBrowser.ServerApplication.csproj @@ -144,6 +144,8 @@ + + diff --git a/MediaBrowser.ServerApplication/ffmpeg/ffmpegx64.7z.REMOVED.git-id b/MediaBrowser.ServerApplication/ffmpeg/ffmpegx64.7z.REMOVED.git-id new file mode 100644 index 000000000..b0542b75f --- /dev/null +++ b/MediaBrowser.ServerApplication/ffmpeg/ffmpegx64.7z.REMOVED.git-id @@ -0,0 +1 @@ +9dc10b022537738edce7eb71aa8dd4adbfee2c7b \ No newline at end of file diff --git a/MediaBrowser.ServerApplication/ffmpeg/ffmpegx86.7z.REMOVED.git-id b/MediaBrowser.ServerApplication/ffmpeg/ffmpegx86.7z.REMOVED.git-id new file mode 100644 index 000000000..3939ec44d --- /dev/null +++ b/MediaBrowser.ServerApplication/ffmpeg/ffmpegx86.7z.REMOVED.git-id @@ -0,0 +1 @@ +00fa1afa35fbd0a7e97ad7956e42ae17f6882f64 \ No newline at end of file -- cgit v1.2.3 From 4afc2c9156a266a980d06b6657a74f0f4ad47a65 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sun, 3 Apr 2016 14:23:17 -0400 Subject: set notification info url --- MediaBrowser.Common.Implementations/Updates/GithubUpdater.cs | 3 ++- MediaBrowser.Model/Updates/PackageVersionInfo.cs | 2 ++ .../EntryPoints/Notifications/Notifications.cs | 3 ++- 3 files changed, 6 insertions(+), 2 deletions(-) (limited to 'MediaBrowser.Server.Implementations/EntryPoints') diff --git a/MediaBrowser.Common.Implementations/Updates/GithubUpdater.cs b/MediaBrowser.Common.Implementations/Updates/GithubUpdater.cs index 82ebf92b2..2ffaedc4b 100644 --- a/MediaBrowser.Common.Implementations/Updates/GithubUpdater.cs +++ b/MediaBrowser.Common.Implementations/Updates/GithubUpdater.cs @@ -111,7 +111,8 @@ namespace MediaBrowser.Common.Implementations.Updates targetFilename = targetFilename, versionStr = version.ToString(), requiredVersionStr = "1.0.0", - description = obj.body + description = obj.body, + infoUrl = obj.html_url } }; } diff --git a/MediaBrowser.Model/Updates/PackageVersionInfo.cs b/MediaBrowser.Model/Updates/PackageVersionInfo.cs index b9bf6e7fe..22404b6f6 100644 --- a/MediaBrowser.Model/Updates/PackageVersionInfo.cs +++ b/MediaBrowser.Model/Updates/PackageVersionInfo.cs @@ -87,5 +87,7 @@ namespace MediaBrowser.Model.Updates /// /// The target filename. public string targetFilename { get; set; } + + public string infoUrl { get; set; } } } \ No newline at end of file diff --git a/MediaBrowser.Server.Implementations/EntryPoints/Notifications/Notifications.cs b/MediaBrowser.Server.Implementations/EntryPoints/Notifications/Notifications.cs index 918110226..9e68ce4ef 100644 --- a/MediaBrowser.Server.Implementations/EntryPoints/Notifications/Notifications.cs +++ b/MediaBrowser.Server.Implementations/EntryPoints/Notifications/Notifications.cs @@ -116,7 +116,8 @@ namespace MediaBrowser.Server.Implementations.EntryPoints.Notifications var notification = new NotificationRequest { - NotificationType = type + NotificationType = type, + Url = e.Argument.infoUrl }; notification.Variables["Version"] = e.Argument.versionStr; -- cgit v1.2.3 From ddbf183df59b43e5b9f47c81e923b2669b4e26cf Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Mon, 4 Apr 2016 15:07:43 -0400 Subject: update edge playback --- .../EntryPoints/ExternalPortForwarding.cs | 202 +++++++++++++++------ .../MediaBrowser.Server.Implementations.csproj | 4 - .../packages.config | 1 - 3 files changed, 151 insertions(+), 56 deletions(-) (limited to 'MediaBrowser.Server.Implementations/EntryPoints') diff --git a/MediaBrowser.Server.Implementations/EntryPoints/ExternalPortForwarding.cs b/MediaBrowser.Server.Implementations/EntryPoints/ExternalPortForwarding.cs index a7e5396eb..5777a0af7 100644 --- a/MediaBrowser.Server.Implementations/EntryPoints/ExternalPortForwarding.cs +++ b/MediaBrowser.Server.Implementations/EntryPoints/ExternalPortForwarding.cs @@ -3,6 +3,7 @@ using MediaBrowser.Controller.Configuration; using MediaBrowser.Controller.Dlna; using MediaBrowser.Controller.Plugins; using MediaBrowser.Model.Logging; +using Mono.Nat; using System; using System.Collections.Generic; using System.Globalization; @@ -10,9 +11,6 @@ using System.IO; using System.Net; using System.Text; using MediaBrowser.Common.Threading; -using Open.Nat; -using System.Threading; -using System.Threading.Tasks; namespace MediaBrowser.Server.Implementations.EntryPoints { @@ -22,8 +20,9 @@ namespace MediaBrowser.Server.Implementations.EntryPoints private readonly ILogger _logger; private readonly IServerConfigurationManager _config; private readonly ISsdpHandler _ssdp; - private CancellationTokenSource _currentCancellationTokenSource; - private TimeSpan _interval = TimeSpan.FromHours(1); + + private PeriodicTimer _timer; + private bool _isStarted; public ExternalPortForwarding(ILogManager logmanager, IServerApplicationHost appHost, IServerConfigurationManager config, ISsdpHandler ssdp) { @@ -31,78 +30,157 @@ namespace MediaBrowser.Server.Implementations.EntryPoints _appHost = appHost; _config = config; _ssdp = ssdp; + } - _config.ConfigurationUpdated += _config_ConfigurationUpdated; + private string _lastConfigIdentifier; + private string GetConfigIdentifier() + { + var values = new List(); + var config = _config.Configuration; + + values.Add(config.EnableUPnP.ToString()); + values.Add(config.PublicPort.ToString(CultureInfo.InvariantCulture)); + values.Add(_appHost.HttpPort.ToString(CultureInfo.InvariantCulture)); + values.Add(_appHost.HttpsPort.ToString(CultureInfo.InvariantCulture)); + values.Add(config.EnableHttps.ToString()); + values.Add(_appHost.EnableHttps.ToString()); + + return string.Join("|", values.ToArray()); } - private void _config_ConfigurationUpdated(object sender, EventArgs e) + void _config_ConfigurationUpdated(object sender, EventArgs e) { + if (!string.Equals(_lastConfigIdentifier, GetConfigIdentifier(), StringComparison.OrdinalIgnoreCase)) + { + if (_isStarted) + { + DisposeNat(); + } + + Run(); + } } public void Run() { - Discover(); + //NatUtility.Logger = new LogWriter(_logger); + + if (_config.Configuration.EnableUPnP) + { + Start(); + } + + _config.ConfigurationUpdated -= _config_ConfigurationUpdated; + _config.ConfigurationUpdated += _config_ConfigurationUpdated; } - private async void Discover() + private void Start() { - if (!_config.Configuration.EnableUPnP) + _logger.Debug("Starting NAT discovery"); + NatUtility.EnabledProtocols = new List { - return; - } + NatProtocol.Pmp + }; + NatUtility.DeviceFound += NatUtility_DeviceFound; - var discoverer = new NatDiscoverer(); + // Mono.Nat does never rise this event. The event is there however it is useless. + // You could remove it with no risk. + NatUtility.DeviceLost += NatUtility_DeviceLost; - var cancellationTokenSource = new CancellationTokenSource(10000); - _currentCancellationTokenSource = cancellationTokenSource; - try - { - var device = await discoverer.DiscoverDeviceAsync(PortMapper.Upnp, cancellationTokenSource).ConfigureAwait(false); + // it is hard to say what one should do when an unhandled exception is raised + // because there isn't anything one can do about it. Probably save a log or ignored it. + NatUtility.UnhandledException += NatUtility_UnhandledException; + NatUtility.StartDiscovery(); - await CreateRules(device).ConfigureAwait(false); - } - catch (OperationCanceledException) - { + _timer = new PeriodicTimer(s => _createdRules = new List(), null, TimeSpan.FromMinutes(5), TimeSpan.FromMinutes(5)); + + _ssdp.MessageReceived += _ssdp_MessageReceived; + + _lastConfigIdentifier = GetConfigIdentifier(); + + _isStarted = true; + } + + void _ssdp_MessageReceived(object sender, SsdpMessageEventArgs e) + { + var endpoint = e.EndPoint as IPEndPoint; + if (endpoint != null && e.LocalEndPoint != null) + { + NatUtility.Handle(e.LocalEndPoint.Address, e.Message, endpoint, NatProtocol.Upnp); } - catch (Exception ex) + } + + void NatUtility_UnhandledException(object sender, UnhandledExceptionEventArgs e) + { + var ex = e.ExceptionObject as Exception; + + if (ex == null) { - _logger.ErrorException("Error discovering NAT devices", ex); + //_logger.Error("Unidentified error reported by Mono.Nat"); } - finally + else { - _currentCancellationTokenSource = null; + // Seeing some blank exceptions coming through here + //_logger.ErrorException("Error reported by Mono.Nat: ", ex); } + } - if (_config.Configuration.EnableUPnP) + void NatUtility_DeviceFound(object sender, DeviceEventArgs e) + { + try { - await Task.Delay(_interval).ConfigureAwait(false); - Discover(); + var device = e.Device; + _logger.Debug("NAT device found: {0}", device.LocalAddress.ToString()); + + CreateRules(device); + } + catch (Exception ex) + { + // I think it could be a good idea to log the exception because + // you are using permanent portmapping here (never expire) and that means that next time + // CreatePortMap is invoked it can fails with a 718-ConflictInMappingEntry or not. That depends + // on the router's upnp implementation (specs says it should fail however some routers don't do it) + // It also can fail with others like 727-ExternalPortOnlySupportsWildcard, 728-NoPortMapsAvailable + // and those errors (upnp errors) could be useful for diagnosting. + + // Commenting out because users are reporting problems out of our control + //_logger.ErrorException("Error creating port forwarding rules", ex); } } - private async Task CreateRules(NatDevice device) + private List _createdRules = new List(); + private void CreateRules(INatDevice device) { // On some systems the device discovered event seems to fire repeatedly // This check will help ensure we're not trying to port map the same device over and over - await CreatePortMap(device, _appHost.HttpPort, _config.Configuration.PublicPort).ConfigureAwait(false); - await CreatePortMap(device, _appHost.HttpsPort, _config.Configuration.PublicHttpsPort).ConfigureAwait(false); + var address = device.LocalAddress.ToString(); + + if (!_createdRules.Contains(address)) + { + _createdRules.Add(address); + + CreatePortMap(device, _appHost.HttpPort, _config.Configuration.PublicPort); + CreatePortMap(device, _appHost.HttpsPort, _config.Configuration.PublicHttpsPort); + } } - private async Task CreatePortMap(NatDevice device, int privatePort, int publicPort) + private void CreatePortMap(INatDevice device, int privatePort, int publicPort) { _logger.Debug("Creating port map on port {0}", privatePort); - - try + device.CreatePortMap(new Mapping(Protocol.Tcp, privatePort, publicPort) { - await device.CreatePortMapAsync(new Mapping(Protocol.Tcp, privatePort, publicPort, _appHost.Name)).ConfigureAwait(false); - } - catch (Exception ex) - { - _logger.ErrorException("Error creating port map", ex); - } + Description = _appHost.Name + }); + } + + // As I said before, this method will be never invoked. You can remove it. + void NatUtility_DeviceLost(object sender, DeviceEventArgs e) + { + var device = e.Device; + _logger.Debug("NAT device lost: {0}", device.LocalAddress.ToString()); } public void Dispose() @@ -112,17 +190,39 @@ namespace MediaBrowser.Server.Implementations.EntryPoints private void DisposeNat() { - if (_currentCancellationTokenSource != null) + _logger.Debug("Stopping NAT discovery"); + + if (_timer != null) { - try - { - _currentCancellationTokenSource.Cancel(); - } - catch (Exception ex) - { - _logger.ErrorException("Error calling _currentCancellationTokenSource.Cancel", ex); - } + _timer.Dispose(); + _timer = null; + } + + _ssdp.MessageReceived -= _ssdp_MessageReceived; + + try + { + // This is not a significant improvement + NatUtility.StopDiscovery(); + NatUtility.DeviceFound -= NatUtility_DeviceFound; + NatUtility.DeviceLost -= NatUtility_DeviceLost; + NatUtility.UnhandledException -= NatUtility_UnhandledException; + } + // Statements in try-block will no fail because StopDiscovery is a one-line + // method that was no chances to fail. + // public static void StopDiscovery () + // { + // searching.Reset(); + // } + // IMO you could remove the catch-block + catch (Exception ex) + { + _logger.ErrorException("Error stopping NAT Discovery", ex); + } + finally + { + _isStarted = false; } } } -} +} \ No newline at end of file diff --git a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj index ae39d3eb9..60d8f737f 100644 --- a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj +++ b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj @@ -62,10 +62,6 @@ ..\packages\morelinq.1.4.0\lib\net35\MoreLinq.dll - - ..\packages\Open.NAT.2.0.15.0\lib\net45\Open.Nat.dll - True - ..\packages\Patterns.Logging.1.0.0.2\lib\portable-net45+sl4+wp71+win8+wpa81\Patterns.Logging.dll diff --git a/MediaBrowser.Server.Implementations/packages.config b/MediaBrowser.Server.Implementations/packages.config index 814a67643..66aede029 100644 --- a/MediaBrowser.Server.Implementations/packages.config +++ b/MediaBrowser.Server.Implementations/packages.config @@ -7,7 +7,6 @@ - \ No newline at end of file -- cgit v1.2.3 From 4ac4e4a0f5d224b7eeecad2002f96b088315597f Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sat, 9 Apr 2016 17:16:17 -0400 Subject: update components --- .../EntryPoints/Notifications/Notifications.cs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'MediaBrowser.Server.Implementations/EntryPoints') diff --git a/MediaBrowser.Server.Implementations/EntryPoints/Notifications/Notifications.cs b/MediaBrowser.Server.Implementations/EntryPoints/Notifications/Notifications.cs index 9e68ce4ef..c7a5e3b18 100644 --- a/MediaBrowser.Server.Implementations/EntryPoints/Notifications/Notifications.cs +++ b/MediaBrowser.Server.Implementations/EntryPoints/Notifications/Notifications.cs @@ -335,12 +335,17 @@ namespace MediaBrowser.Server.Implementations.EntryPoints.Notifications private bool FilterItem(BaseItem item) { - if (!item.IsFolder && item.LocationType == LocationType.Virtual) + if (item.IsFolder) { return false; } - if (item is IItemByName && !(item is MusicArtist)) + if (item.LocationType == LocationType.Virtual) + { + return false; + } + + if (item is IItemByName) { return false; } -- cgit v1.2.3 From 41ee4600fd2b5af9732b363790d6b0f44dc272e5 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Wed, 13 Apr 2016 12:17:52 -0400 Subject: fix tabs --- MediaBrowser.Api/TvShowsService.cs | 22 ++++++++++++++++++++-- .../EntryPoints/Notifications/Notifications.cs | 13 +++++++++++++ 2 files changed, 33 insertions(+), 2 deletions(-) (limited to 'MediaBrowser.Server.Implementations/EntryPoints') diff --git a/MediaBrowser.Api/TvShowsService.cs b/MediaBrowser.Api/TvShowsService.cs index 5b5b0a902..3c32232ac 100644 --- a/MediaBrowser.Api/TvShowsService.cs +++ b/MediaBrowser.Api/TvShowsService.cs @@ -123,7 +123,7 @@ namespace MediaBrowser.Api } [Route("/Shows/{Id}/Episodes", "GET", Summary = "Gets episodes for a tv season")] - public class GetEpisodes : IReturn, IHasItemFields + public class GetEpisodes : IReturn, IHasItemFields, IHasDtoOptions { /// /// Gets or sets the user id. @@ -173,10 +173,19 @@ namespace MediaBrowser.Api /// The limit. [ApiMember(Name = "Limit", Description = "Optional. The maximum number of records to return", IsRequired = false, DataType = "int", ParameterType = "query", Verb = "GET")] public int? Limit { get; set; } + + [ApiMember(Name = "EnableImages", Description = "Optional, include image information in output", IsRequired = false, DataType = "boolean", ParameterType = "query", Verb = "GET")] + public bool? EnableImages { get; set; } + + [ApiMember(Name = "ImageTypeLimit", Description = "Optional, the max number of images to return, per image type", IsRequired = false, DataType = "int", ParameterType = "query", Verb = "GET")] + public int? ImageTypeLimit { get; set; } + + [ApiMember(Name = "EnableImageTypes", Description = "Optional. The image types to include in the output.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")] + public string EnableImageTypes { get; set; } } [Route("/Shows/{Id}/Seasons", "GET", Summary = "Gets seasons for a tv series")] - public class GetSeasons : IReturn, IHasItemFields + public class GetSeasons : IReturn, IHasItemFields, IHasDtoOptions { /// /// Gets or sets the user id. @@ -206,6 +215,15 @@ namespace MediaBrowser.Api [ApiMember(Name = "AdjacentTo", Description = "Optional. Return items that are siblings of a supplied item.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")] public string AdjacentTo { get; set; } + + [ApiMember(Name = "EnableImages", Description = "Optional, include image information in output", IsRequired = false, DataType = "boolean", ParameterType = "query", Verb = "GET")] + public bool? EnableImages { get; set; } + + [ApiMember(Name = "ImageTypeLimit", Description = "Optional, the max number of images to return, per image type", IsRequired = false, DataType = "int", ParameterType = "query", Verb = "GET")] + public int? ImageTypeLimit { get; set; } + + [ApiMember(Name = "EnableImageTypes", Description = "Optional. The image types to include in the output.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")] + public string EnableImageTypes { get; set; } } /// diff --git a/MediaBrowser.Server.Implementations/EntryPoints/Notifications/Notifications.cs b/MediaBrowser.Server.Implementations/EntryPoints/Notifications/Notifications.cs index c7a5e3b18..71019e0ad 100644 --- a/MediaBrowser.Server.Implementations/EntryPoints/Notifications/Notifications.cs +++ b/MediaBrowser.Server.Implementations/EntryPoints/Notifications/Notifications.cs @@ -22,6 +22,7 @@ using System.Globalization; using System.Linq; using System.Threading; using System.Threading.Tasks; +using MediaBrowser.Controller.Entities.TV; namespace MediaBrowser.Server.Implementations.EntryPoints.Notifications { @@ -393,6 +394,18 @@ namespace MediaBrowser.Server.Implementations.EntryPoints.Notifications public static string GetItemName(BaseItem item) { var name = item.Name; + var episode = item as Episode; + if (episode != null) + { + if (episode.IndexNumber.HasValue) + { + name = string.Format("Ep{0} - {1}", episode.IndexNumber.Value.ToString(CultureInfo.InvariantCulture), name); + } + if (episode.ParentIndexNumber.HasValue) + { + name = string.Format("S{0}, {1}", episode.ParentIndexNumber.Value.ToString(CultureInfo.InvariantCulture), name); + } + } var hasSeries = item as IHasSeries; -- cgit v1.2.3 From 371cbc0c1d712b702d5a792a0f2ddb05dbe7af2d Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Tue, 26 Apr 2016 22:59:43 -0400 Subject: support headroom with guide --- MediaBrowser.Controller/Entities/BaseItem.cs | 2 +- .../EntryPoints/Notifications/Notifications.cs | 12 ++++++++++++ MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj | 3 +++ 3 files changed, 16 insertions(+), 1 deletion(-) (limited to 'MediaBrowser.Server.Implementations/EntryPoints') diff --git a/MediaBrowser.Controller/Entities/BaseItem.cs b/MediaBrowser.Controller/Entities/BaseItem.cs index f5fb72de5..f9f03a9c5 100644 --- a/MediaBrowser.Controller/Entities/BaseItem.cs +++ b/MediaBrowser.Controller/Entities/BaseItem.cs @@ -1546,7 +1546,7 @@ namespace MediaBrowser.Controller.Entities if (itemByPath == null) { - Logger.Warn("Unable to find linked item at path {0}", info.Path); + //Logger.Warn("Unable to find linked item at path {0}", info.Path); } return itemByPath; diff --git a/MediaBrowser.Server.Implementations/EntryPoints/Notifications/Notifications.cs b/MediaBrowser.Server.Implementations/EntryPoints/Notifications/Notifications.cs index 71019e0ad..e84b66c5a 100644 --- a/MediaBrowser.Server.Implementations/EntryPoints/Notifications/Notifications.cs +++ b/MediaBrowser.Server.Implementations/EntryPoints/Notifications/Notifications.cs @@ -215,6 +215,12 @@ namespace MediaBrowser.Server.Implementations.EntryPoints.Notifications return; } + var video = e.Item as Video; + if (video != null && video.IsThemeMedia) + { + return; + } + var type = GetPlaybackNotificationType(item.MediaType); SendPlaybackNotification(type, e); @@ -230,6 +236,12 @@ namespace MediaBrowser.Server.Implementations.EntryPoints.Notifications return; } + var video = e.Item as Video; + if (video != null && video.IsThemeMedia) + { + return; + } + var type = GetPlaybackStoppedNotificationType(item.MediaType); SendPlaybackNotification(type, e); diff --git a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj index 5534b95a9..bfa4995cf 100644 --- a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj +++ b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj @@ -1712,6 +1712,9 @@ PreserveNewest + + PreserveNewest + PreserveNewest -- cgit v1.2.3 From cc173bfc28952407423798532772e9e5ee93e3e5 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Wed, 8 Jun 2016 02:21:13 -0400 Subject: add recording web socket events --- MediaBrowser.Controller/LiveTv/ILiveTvManager.cs | 6 ++ MediaBrowser.Controller/LiveTv/TimerEventInfo.cs | 14 ++++ .../MediaBrowser.Controller.csproj | 1 + .../EntryPoints/RecordingNotifier.cs | 83 ++++++++++++++++++++++ .../LiveTv/LiveTvManager.cs | 39 ++++++++++ .../MediaBrowser.Server.Implementations.csproj | 1 + 6 files changed, 144 insertions(+) create mode 100644 MediaBrowser.Controller/LiveTv/TimerEventInfo.cs create mode 100644 MediaBrowser.Server.Implementations/EntryPoints/RecordingNotifier.cs (limited to 'MediaBrowser.Server.Implementations/EntryPoints') diff --git a/MediaBrowser.Controller/LiveTv/ILiveTvManager.cs b/MediaBrowser.Controller/LiveTv/ILiveTvManager.cs index 763652c95..15fc9350b 100644 --- a/MediaBrowser.Controller/LiveTv/ILiveTvManager.cs +++ b/MediaBrowser.Controller/LiveTv/ILiveTvManager.cs @@ -8,6 +8,7 @@ using MediaBrowser.Model.Querying; using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; +using MediaBrowser.Model.Events; namespace MediaBrowser.Controller.LiveTv { @@ -387,5 +388,10 @@ namespace MediaBrowser.Controller.LiveTv Task> GetSatChannelScanResult(TunerHostInfo info, CancellationToken cancellationToken); Task> GetChannelsFromListingsProvider(string id, CancellationToken cancellationToken); + + event EventHandler> SeriesTimerCancelled; + event EventHandler> TimerCancelled; + event EventHandler> TimerCreated; + event EventHandler> SeriesTimerCreated; } } diff --git a/MediaBrowser.Controller/LiveTv/TimerEventInfo.cs b/MediaBrowser.Controller/LiveTv/TimerEventInfo.cs new file mode 100644 index 000000000..0e1a05475 --- /dev/null +++ b/MediaBrowser.Controller/LiveTv/TimerEventInfo.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace MediaBrowser.Controller.LiveTv +{ + public class TimerEventInfo + { + public string Id { get; set; } + public string ProgramId { get; set; } + } +} diff --git a/MediaBrowser.Controller/MediaBrowser.Controller.csproj b/MediaBrowser.Controller/MediaBrowser.Controller.csproj index 4cfdc641c..9b4c35c41 100644 --- a/MediaBrowser.Controller/MediaBrowser.Controller.csproj +++ b/MediaBrowser.Controller/MediaBrowser.Controller.csproj @@ -218,6 +218,7 @@ + diff --git a/MediaBrowser.Server.Implementations/EntryPoints/RecordingNotifier.cs b/MediaBrowser.Server.Implementations/EntryPoints/RecordingNotifier.cs new file mode 100644 index 000000000..dd3145d57 --- /dev/null +++ b/MediaBrowser.Server.Implementations/EntryPoints/RecordingNotifier.cs @@ -0,0 +1,83 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading; +using System.Threading.Tasks; +using MediaBrowser.Controller.Library; +using MediaBrowser.Controller.LiveTv; +using MediaBrowser.Controller.Plugins; +using MediaBrowser.Controller.Session; +using MediaBrowser.Model.Logging; + +namespace MediaBrowser.Server.Implementations.EntryPoints +{ + public class RecordingNotifier : IServerEntryPoint + { + private readonly ILiveTvManager _liveTvManager; + private readonly ISessionManager _sessionManager; + private readonly IUserManager _userManager; + private readonly ILogger _logger; + + public RecordingNotifier(ISessionManager sessionManager, IUserManager userManager, ILogger logger, ILiveTvManager liveTvManager) + { + _sessionManager = sessionManager; + _userManager = userManager; + _logger = logger; + _liveTvManager = liveTvManager; + } + + public void Run() + { + _liveTvManager.TimerCancelled += _liveTvManager_TimerCancelled; + _liveTvManager.SeriesTimerCancelled += _liveTvManager_SeriesTimerCancelled; + _liveTvManager.TimerCreated += _liveTvManager_TimerCreated; + _liveTvManager.SeriesTimerCreated += _liveTvManager_SeriesTimerCreated; + } + + private void _liveTvManager_SeriesTimerCreated(object sender, Model.Events.GenericEventArgs e) + { + SendMessage("seriestimercreated", e.Argument); + } + + private void _liveTvManager_TimerCreated(object sender, Model.Events.GenericEventArgs e) + { + SendMessage("timercreated", e.Argument); + } + + private void _liveTvManager_SeriesTimerCancelled(object sender, Model.Events.GenericEventArgs e) + { + SendMessage("seriestimercancelled", e.Argument); + } + + private void _liveTvManager_TimerCancelled(object sender, Model.Events.GenericEventArgs e) + { + SendMessage("timercancelled", e.Argument); + } + + private async void SendMessage(string name, TimerEventInfo info) + { + var users = _userManager.Users.Where(i => i.Policy.EnableLiveTvAccess).ToList(); + + foreach (var user in users) + { + try + { + await _sessionManager.SendMessageToUserSessions(user.Id.ToString("N"), name, info, CancellationToken.None); + } + catch (Exception ex) + { + _logger.ErrorException("Error sending message", ex); + } + } + } + + public void Dispose() + { + _liveTvManager.TimerCancelled -= _liveTvManager_TimerCancelled; + _liveTvManager.SeriesTimerCancelled -= _liveTvManager_SeriesTimerCancelled; + _liveTvManager.TimerCreated -= _liveTvManager_TimerCreated; + _liveTvManager.SeriesTimerCreated -= _liveTvManager_SeriesTimerCreated; + } + } +} diff --git a/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs b/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs index 0bff6b71d..46f7a8f30 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs @@ -30,6 +30,8 @@ using System.Threading.Tasks; using CommonIO; using IniParser; using IniParser.Model; +using MediaBrowser.Common.Events; +using MediaBrowser.Model.Events; namespace MediaBrowser.Server.Implementations.LiveTv { @@ -64,6 +66,11 @@ namespace MediaBrowser.Server.Implementations.LiveTv private readonly List _listingProviders = new List(); private readonly IFileSystem _fileSystem; + public event EventHandler> SeriesTimerCancelled; + public event EventHandler> TimerCancelled; + public event EventHandler> TimerCreated; + public event EventHandler> SeriesTimerCreated; + public LiveTvManager(IApplicationHost appHost, IServerConfigurationManager config, ILogger logger, IItemRepository itemRepo, IImageProcessor imageProcessor, IUserDataManager userDataManager, IDtoService dtoService, IUserManager userManager, ILibraryManager libraryManager, ITaskManager taskManager, ILocalizationManager localization, IJsonSerializer jsonSerializer, IProviderManager providerManager, IFileSystem fileSystem) { _config = config; @@ -1759,6 +1766,14 @@ namespace MediaBrowser.Server.Implementations.LiveTv await service.CancelTimerAsync(timer.ExternalId, CancellationToken.None).ConfigureAwait(false); _lastRecordingRefreshTime = DateTime.MinValue; + + EventHelper.QueueEventIfNotNull(TimerCancelled, this, new GenericEventArgs + { + Argument = new TimerEventInfo + { + Id = id + } + }, _logger); } public async Task CancelSeriesTimer(string id) @@ -1774,6 +1789,14 @@ namespace MediaBrowser.Server.Implementations.LiveTv await service.CancelSeriesTimerAsync(timer.ExternalId, CancellationToken.None).ConfigureAwait(false); _lastRecordingRefreshTime = DateTime.MinValue; + + EventHelper.QueueEventIfNotNull(SeriesTimerCancelled, this, new GenericEventArgs + { + Argument = new TimerEventInfo + { + Id = id + } + }, _logger); } public async Task GetRecording(string id, DtoOptions options, CancellationToken cancellationToken, User user = null) @@ -1993,6 +2016,14 @@ namespace MediaBrowser.Server.Implementations.LiveTv await service.CreateTimerAsync(info, cancellationToken).ConfigureAwait(false); _lastRecordingRefreshTime = DateTime.MinValue; _logger.Info("New recording scheduled"); + + EventHelper.QueueEventIfNotNull(TimerCreated, this, new GenericEventArgs + { + Argument = new TimerEventInfo + { + ProgramId = info.ProgramId + } + }, _logger); } public async Task CreateSeriesTimer(SeriesTimerInfoDto timer, CancellationToken cancellationToken) @@ -2007,6 +2038,14 @@ namespace MediaBrowser.Server.Implementations.LiveTv await service.CreateSeriesTimerAsync(info, cancellationToken).ConfigureAwait(false); _lastRecordingRefreshTime = DateTime.MinValue; + + EventHelper.QueueEventIfNotNull(SeriesTimerCreated, this, new GenericEventArgs + { + Argument = new TimerEventInfo + { + ProgramId = info.ProgramId + } + }, _logger); } public async Task UpdateTimer(TimerInfoDto timer, CancellationToken cancellationToken) diff --git a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj index 52ffe3a4b..cc78656be 100644 --- a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj +++ b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj @@ -142,6 +142,7 @@ + -- cgit v1.2.3 From 26ff2882e7b9dea4be55c50f571e64aea88c2004 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Wed, 8 Jun 2016 11:22:10 -0400 Subject: update recording events --- .../EntryPoints/RecordingNotifier.cs | 8 ++++---- MediaBrowser.Server.Startup.Common/ApplicationHost.cs | 3 ++- 2 files changed, 6 insertions(+), 5 deletions(-) (limited to 'MediaBrowser.Server.Implementations/EntryPoints') diff --git a/MediaBrowser.Server.Implementations/EntryPoints/RecordingNotifier.cs b/MediaBrowser.Server.Implementations/EntryPoints/RecordingNotifier.cs index dd3145d57..cc4ef1972 100644 --- a/MediaBrowser.Server.Implementations/EntryPoints/RecordingNotifier.cs +++ b/MediaBrowser.Server.Implementations/EntryPoints/RecordingNotifier.cs @@ -37,22 +37,22 @@ namespace MediaBrowser.Server.Implementations.EntryPoints private void _liveTvManager_SeriesTimerCreated(object sender, Model.Events.GenericEventArgs e) { - SendMessage("seriestimercreated", e.Argument); + SendMessage("SeriesTimerCreated", e.Argument); } private void _liveTvManager_TimerCreated(object sender, Model.Events.GenericEventArgs e) { - SendMessage("timercreated", e.Argument); + SendMessage("TimerCreated", e.Argument); } private void _liveTvManager_SeriesTimerCancelled(object sender, Model.Events.GenericEventArgs e) { - SendMessage("seriestimercancelled", e.Argument); + SendMessage("SeriesTimerCancelled", e.Argument); } private void _liveTvManager_TimerCancelled(object sender, Model.Events.GenericEventArgs e) { - SendMessage("timercancelled", e.Argument); + SendMessage("TimerCancelled", e.Argument); } private async void SendMessage(string name, TimerEventInfo info) diff --git a/MediaBrowser.Server.Startup.Common/ApplicationHost.cs b/MediaBrowser.Server.Startup.Common/ApplicationHost.cs index 9acb3bea2..f344e6f1c 100644 --- a/MediaBrowser.Server.Startup.Common/ApplicationHost.cs +++ b/MediaBrowser.Server.Startup.Common/ApplicationHost.cs @@ -381,7 +381,8 @@ namespace MediaBrowser.Server.Startup.Common new OmdbEpisodeProviderMigration(ServerConfigurationManager), new MovieDbEpisodeProviderMigration(ServerConfigurationManager), new DbMigration(ServerConfigurationManager, TaskManager), - new FolderViewSettingMigration(ServerConfigurationManager, UserManager) + new FolderViewSettingMigration(ServerConfigurationManager, UserManager), + new CollectionGroupingMigration(ServerConfigurationManager, UserManager) }; foreach (var task in migrations) -- cgit v1.2.3 From dc5c15c60b598a58c924daa350dfaf9f6b7d1c17 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sat, 11 Jun 2016 11:56:15 -0400 Subject: update elements --- MediaBrowser.Dlna/PlayTo/PlayToManager.cs | 2 + .../Activity/ActivityRepository.cs | 248 ++++++++++----------- .../EntryPoints/ExternalPortForwarding.cs | 36 ++- .../IO/FileRefresher.cs | 11 +- MediaBrowser.Server.Mono/Native/DbConnector.cs | 4 +- .../ApplicationHost.cs | 34 +-- .../Native/DbConnector.cs | 13 +- MediaBrowser.WebDashboard/Api/DashboardService.cs | 4 +- 8 files changed, 183 insertions(+), 169 deletions(-) (limited to 'MediaBrowser.Server.Implementations/EntryPoints') diff --git a/MediaBrowser.Dlna/PlayTo/PlayToManager.cs b/MediaBrowser.Dlna/PlayTo/PlayToManager.cs index bbb9bf6de..cd9a7b1f0 100644 --- a/MediaBrowser.Dlna/PlayTo/PlayToManager.cs +++ b/MediaBrowser.Dlna/PlayTo/PlayToManager.cs @@ -101,6 +101,7 @@ namespace MediaBrowser.Dlna.PlayTo } var uri = new Uri(location); + _logger.Debug("Attempting to create PlayToController from location {0}", location); var device = await Device.CreateuPnpDeviceAsync(uri, _httpClient, _config, _logger).ConfigureAwait(false); if (device.RendererCommands == null) @@ -112,6 +113,7 @@ namespace MediaBrowser.Dlna.PlayTo } } + _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); diff --git a/MediaBrowser.Server.Implementations/Activity/ActivityRepository.cs b/MediaBrowser.Server.Implementations/Activity/ActivityRepository.cs index b0e05a5bc..d6ae381e9 100644 --- a/MediaBrowser.Server.Implementations/Activity/ActivityRepository.cs +++ b/MediaBrowser.Server.Implementations/Activity/ActivityRepository.cs @@ -15,25 +15,19 @@ namespace MediaBrowser.Server.Implementations.Activity { public class ActivityRepository : BaseSqliteRepository, IActivityRepository { - private IDbConnection _connection; - private readonly IServerApplicationPaths _appPaths; private readonly CultureInfo _usCulture = new CultureInfo("en-US"); - private IDbCommand _saveActivityCommand; - - public ActivityRepository(ILogManager logManager, IServerApplicationPaths appPaths) - : base(logManager) + public ActivityRepository(ILogManager logManager, IServerApplicationPaths appPaths, IDbConnector connector) + : base(logManager, connector) { - _appPaths = appPaths; + DbFilePath = Path.Combine(appPaths.DataPath, "activitylog.db"); } - public async Task Initialize(IDbConnector dbConnector) + public async Task Initialize() { - var dbFile = Path.Combine(_appPaths.DataPath, "activitylog.db"); - - _connection = await dbConnector.Connect(dbFile).ConfigureAwait(false); - - string[] queries = { + using (var connection = await CreateConnection().ConfigureAwait(false)) + { + string[] queries = { "create table if not exists ActivityLogEntries (Id GUID PRIMARY KEY, Name TEXT, Overview TEXT, ShortOverview TEXT, Type TEXT, ItemId TEXT, UserId TEXT, DateCreated DATETIME, LogSeverity TEXT)", "create index if not exists idx_ActivityLogEntries on ActivityLogEntries(Id)", @@ -44,25 +38,8 @@ namespace MediaBrowser.Server.Implementations.Activity "pragma shrink_memory" }; - _connection.RunQueries(queries, Logger); - - PrepareStatements(); - } - - private void PrepareStatements() - { - _saveActivityCommand = _connection.CreateCommand(); - _saveActivityCommand.CommandText = "replace into ActivityLogEntries (Id, Name, Overview, ShortOverview, Type, ItemId, UserId, DateCreated, LogSeverity) values (@Id, @Name, @Overview, @ShortOverview, @Type, @ItemId, @UserId, @DateCreated, @LogSeverity)"; - - _saveActivityCommand.Parameters.Add(_saveActivityCommand, "@Id"); - _saveActivityCommand.Parameters.Add(_saveActivityCommand, "@Name"); - _saveActivityCommand.Parameters.Add(_saveActivityCommand, "@Overview"); - _saveActivityCommand.Parameters.Add(_saveActivityCommand, "@ShortOverview"); - _saveActivityCommand.Parameters.Add(_saveActivityCommand, "@Type"); - _saveActivityCommand.Parameters.Add(_saveActivityCommand, "@ItemId"); - _saveActivityCommand.Parameters.Add(_saveActivityCommand, "@UserId"); - _saveActivityCommand.Parameters.Add(_saveActivityCommand, "@DateCreated"); - _saveActivityCommand.Parameters.Add(_saveActivityCommand, "@LogSeverity"); + connection.RunQueries(queries, Logger); + } } private const string BaseActivitySelectText = "select Id, Name, Overview, ShortOverview, Type, ItemId, UserId, DateCreated, LogSeverity from ActivityLogEntries"; @@ -79,128 +56,145 @@ namespace MediaBrowser.Server.Implementations.Activity throw new ArgumentNullException("entry"); } - await WriteLock.WaitAsync().ConfigureAwait(false); + using (var connection = await CreateConnection().ConfigureAwait(false)) + { + using (var saveActivityCommand = connection.CreateCommand()) + { + saveActivityCommand.CommandText = "replace into ActivityLogEntries (Id, Name, Overview, ShortOverview, Type, ItemId, UserId, DateCreated, LogSeverity) values (@Id, @Name, @Overview, @ShortOverview, @Type, @ItemId, @UserId, @DateCreated, @LogSeverity)"; - IDbTransaction transaction = null; + saveActivityCommand.Parameters.Add(saveActivityCommand, "@Id"); + saveActivityCommand.Parameters.Add(saveActivityCommand, "@Name"); + saveActivityCommand.Parameters.Add(saveActivityCommand, "@Overview"); + saveActivityCommand.Parameters.Add(saveActivityCommand, "@ShortOverview"); + saveActivityCommand.Parameters.Add(saveActivityCommand, "@Type"); + saveActivityCommand.Parameters.Add(saveActivityCommand, "@ItemId"); + saveActivityCommand.Parameters.Add(saveActivityCommand, "@UserId"); + saveActivityCommand.Parameters.Add(saveActivityCommand, "@DateCreated"); + saveActivityCommand.Parameters.Add(saveActivityCommand, "@LogSeverity"); - try - { - transaction = _connection.BeginTransaction(); + IDbTransaction transaction = null; - var index = 0; + try + { + transaction = connection.BeginTransaction(); - _saveActivityCommand.GetParameter(index++).Value = new Guid(entry.Id); - _saveActivityCommand.GetParameter(index++).Value = entry.Name; - _saveActivityCommand.GetParameter(index++).Value = entry.Overview; - _saveActivityCommand.GetParameter(index++).Value = entry.ShortOverview; - _saveActivityCommand.GetParameter(index++).Value = entry.Type; - _saveActivityCommand.GetParameter(index++).Value = entry.ItemId; - _saveActivityCommand.GetParameter(index++).Value = entry.UserId; - _saveActivityCommand.GetParameter(index++).Value = entry.Date; - _saveActivityCommand.GetParameter(index++).Value = entry.Severity.ToString(); + var index = 0; - _saveActivityCommand.Transaction = transaction; + saveActivityCommand.GetParameter(index++).Value = new Guid(entry.Id); + saveActivityCommand.GetParameter(index++).Value = entry.Name; + saveActivityCommand.GetParameter(index++).Value = entry.Overview; + saveActivityCommand.GetParameter(index++).Value = entry.ShortOverview; + saveActivityCommand.GetParameter(index++).Value = entry.Type; + saveActivityCommand.GetParameter(index++).Value = entry.ItemId; + saveActivityCommand.GetParameter(index++).Value = entry.UserId; + saveActivityCommand.GetParameter(index++).Value = entry.Date; + saveActivityCommand.GetParameter(index++).Value = entry.Severity.ToString(); - _saveActivityCommand.ExecuteNonQuery(); + saveActivityCommand.Transaction = transaction; - transaction.Commit(); - } - catch (OperationCanceledException) - { - if (transaction != null) - { - transaction.Rollback(); - } + saveActivityCommand.ExecuteNonQuery(); - throw; - } - catch (Exception e) - { - Logger.ErrorException("Failed to save record:", e); + transaction.Commit(); + } + catch (OperationCanceledException) + { + if (transaction != null) + { + transaction.Rollback(); + } - if (transaction != null) - { - transaction.Rollback(); - } + throw; + } + catch (Exception e) + { + Logger.ErrorException("Failed to save record:", e); - throw; - } - finally - { - if (transaction != null) - { - transaction.Dispose(); - } + if (transaction != null) + { + transaction.Rollback(); + } - WriteLock.Release(); + throw; + } + finally + { + if (transaction != null) + { + transaction.Dispose(); + } + } + } } } public QueryResult GetActivityLogEntries(DateTime? minDate, int? startIndex, int? limit) { - using (var cmd = _connection.CreateCommand()) + using (var connection = CreateConnection(true).Result) { - cmd.CommandText = BaseActivitySelectText; - - var whereClauses = new List(); - - if (minDate.HasValue) + using (var cmd = connection.CreateCommand()) { - whereClauses.Add("DateCreated>=@DateCreated"); - cmd.Parameters.Add(cmd, "@DateCreated", DbType.Date).Value = minDate.Value; - } + cmd.CommandText = BaseActivitySelectText; - var whereTextWithoutPaging = whereClauses.Count == 0 ? - string.Empty : - " where " + string.Join(" AND ", whereClauses.ToArray()); + var whereClauses = new List(); - if (startIndex.HasValue && startIndex.Value > 0) - { - var pagingWhereText = whereClauses.Count == 0 ? + if (minDate.HasValue) + { + whereClauses.Add("DateCreated>=@DateCreated"); + cmd.Parameters.Add(cmd, "@DateCreated", DbType.Date).Value = minDate.Value; + } + + var whereTextWithoutPaging = whereClauses.Count == 0 ? string.Empty : " where " + string.Join(" AND ", whereClauses.ToArray()); - - whereClauses.Add(string.Format("Id NOT IN (SELECT Id FROM ActivityLogEntries {0} ORDER BY DateCreated DESC LIMIT {1})", - pagingWhereText, - startIndex.Value.ToString(_usCulture))); - } - - var whereText = whereClauses.Count == 0 ? - string.Empty : - " where " + string.Join(" AND ", whereClauses.ToArray()); - cmd.CommandText += whereText; + if (startIndex.HasValue && startIndex.Value > 0) + { + var pagingWhereText = whereClauses.Count == 0 ? + string.Empty : + " where " + string.Join(" AND ", whereClauses.ToArray()); - cmd.CommandText += " ORDER BY DateCreated DESC"; + whereClauses.Add(string.Format("Id NOT IN (SELECT Id FROM ActivityLogEntries {0} ORDER BY DateCreated DESC LIMIT {1})", + pagingWhereText, + startIndex.Value.ToString(_usCulture))); + } - if (limit.HasValue) - { - cmd.CommandText += " LIMIT " + limit.Value.ToString(_usCulture); - } + var whereText = whereClauses.Count == 0 ? + string.Empty : + " where " + string.Join(" AND ", whereClauses.ToArray()); - cmd.CommandText += "; select count (Id) from ActivityLogEntries" + whereTextWithoutPaging; + cmd.CommandText += whereText; - var list = new List(); - var count = 0; + cmd.CommandText += " ORDER BY DateCreated DESC"; - using (var reader = cmd.ExecuteReader(CommandBehavior.SequentialAccess)) - { - while (reader.Read()) + if (limit.HasValue) { - list.Add(GetEntry(reader)); + cmd.CommandText += " LIMIT " + limit.Value.ToString(_usCulture); } - if (reader.NextResult() && reader.Read()) + cmd.CommandText += "; select count (Id) from ActivityLogEntries" + whereTextWithoutPaging; + + var list = new List(); + var count = 0; + + using (var reader = cmd.ExecuteReader(CommandBehavior.SequentialAccess)) { - count = reader.GetInt32(0); + while (reader.Read()) + { + list.Add(GetEntry(reader)); + } + + if (reader.NextResult() && reader.Read()) + { + count = reader.GetInt32(0); + } } - } - return new QueryResult() - { - Items = list.ToArray(), - TotalRecordCount = count - }; + return new QueryResult() + { + Items = list.ToArray(), + TotalRecordCount = count + }; + } } } @@ -260,19 +254,5 @@ namespace MediaBrowser.Server.Implementations.Activity return info; } - - protected override void CloseConnection() - { - if (_connection != null) - { - if (_connection.IsOpen()) - { - _connection.Close(); - } - - _connection.Dispose(); - _connection = null; - } - } } } diff --git a/MediaBrowser.Server.Implementations/EntryPoints/ExternalPortForwarding.cs b/MediaBrowser.Server.Implementations/EntryPoints/ExternalPortForwarding.cs index 5777a0af7..50ad3cfbc 100644 --- a/MediaBrowser.Server.Implementations/EntryPoints/ExternalPortForwarding.cs +++ b/MediaBrowser.Server.Implementations/EntryPoints/ExternalPortForwarding.cs @@ -93,7 +93,7 @@ namespace MediaBrowser.Server.Implementations.EntryPoints NatUtility.UnhandledException += NatUtility_UnhandledException; NatUtility.StartDiscovery(); - _timer = new PeriodicTimer(s => _createdRules = new List(), null, TimeSpan.FromMinutes(5), TimeSpan.FromMinutes(5)); + _timer = new PeriodicTimer(ClearCreatedRules, null, TimeSpan.FromMinutes(5), TimeSpan.FromMinutes(5)); _ssdp.MessageReceived += _ssdp_MessageReceived; @@ -102,12 +102,43 @@ namespace MediaBrowser.Server.Implementations.EntryPoints _isStarted = true; } + private void ClearCreatedRules(object state) + { + _createdRules = new List(); + _usnsHandled = new List(); + } + void _ssdp_MessageReceived(object sender, SsdpMessageEventArgs e) { var endpoint = e.EndPoint as IPEndPoint; - if (endpoint != null && e.LocalEndPoint != null) + if (endpoint == null || e.LocalEndPoint == null) { + return; + } + + string usn; + if (!e.Headers.TryGetValue("USN", out usn)) usn = string.Empty; + + string nt; + if (!e.Headers.TryGetValue("NT", out nt)) nt = string.Empty; + + // Filter device type + if (usn.IndexOf("WANIPConnection:", StringComparison.OrdinalIgnoreCase) == -1 && + nt.IndexOf("WANIPConnection:", StringComparison.OrdinalIgnoreCase) == -1 && + usn.IndexOf("WANPPPConnection:", StringComparison.OrdinalIgnoreCase) == -1 && + nt.IndexOf("WANPPPConnection:", StringComparison.OrdinalIgnoreCase) == -1) + { + return; + } + + var identifier = string.IsNullOrWhiteSpace(usn) ? nt : usn; + + if (!_usnsHandled.Contains(identifier)) + { + _usnsHandled.Add(identifier); + + _logger.Debug("Calling Nat.Handle on " + identifier); NatUtility.Handle(e.LocalEndPoint.Address, e.Message, endpoint, NatProtocol.Upnp); } } @@ -151,6 +182,7 @@ namespace MediaBrowser.Server.Implementations.EntryPoints } private List _createdRules = new List(); + private List _usnsHandled = new List(); private void CreateRules(INatDevice device) { // On some systems the device discovered event seems to fire repeatedly diff --git a/MediaBrowser.Server.Implementations/IO/FileRefresher.cs b/MediaBrowser.Server.Implementations/IO/FileRefresher.cs index 18c52ab29..4bea6ad34 100644 --- a/MediaBrowser.Server.Implementations/IO/FileRefresher.cs +++ b/MediaBrowser.Server.Implementations/IO/FileRefresher.cs @@ -93,8 +93,15 @@ namespace MediaBrowser.Server.Implementations.IO private async void OnTimerCallback(object state) { + List paths; + + lock (_timerLock) + { + paths = _affectedPaths.ToList(); + } + // Extend the timer as long as any of the paths are still being written to. - if (_affectedPaths.Any(IsFileLocked)) + if (paths.Any(IsFileLocked)) { Logger.Info("Timer extended."); RestartTimer(); @@ -108,7 +115,7 @@ namespace MediaBrowser.Server.Implementations.IO try { - await ProcessPathChanges(_affectedPaths.ToList()).ConfigureAwait(false); + await ProcessPathChanges(paths.ToList()).ConfigureAwait(false); } catch (Exception ex) { diff --git a/MediaBrowser.Server.Mono/Native/DbConnector.cs b/MediaBrowser.Server.Mono/Native/DbConnector.cs index 7553dbe1a..5ad3ecfef 100644 --- a/MediaBrowser.Server.Mono/Native/DbConnector.cs +++ b/MediaBrowser.Server.Mono/Native/DbConnector.cs @@ -16,9 +16,9 @@ namespace MediaBrowser.Server.Mono.Native _logger = logger; } - public Task Connect(string dbPath, int? cacheSize = null) + public Task Connect(string dbPath, bool isReadOnly, bool enablePooling = false, int? cacheSize = null) { - return SqliteExtensions.ConnectToDb(dbPath, cacheSize, _logger); + return SqliteExtensions.ConnectToDb(dbPath, isReadOnly, enablePooling, cacheSize, _logger); } } } \ No newline at end of file diff --git a/MediaBrowser.Server.Startup.Common/ApplicationHost.cs b/MediaBrowser.Server.Startup.Common/ApplicationHost.cs index f344e6f1c..9e869478c 100644 --- a/MediaBrowser.Server.Startup.Common/ApplicationHost.cs +++ b/MediaBrowser.Server.Startup.Common/ApplicationHost.cs @@ -424,11 +424,11 @@ namespace MediaBrowser.Server.Startup.Common UserRepository = await GetUserRepository().ConfigureAwait(false); RegisterSingleInstance(UserRepository); - var displayPreferencesRepo = new SqliteDisplayPreferencesRepository(LogManager, JsonSerializer, ApplicationPaths); + var displayPreferencesRepo = new SqliteDisplayPreferencesRepository(LogManager, JsonSerializer, ApplicationPaths, NativeApp.GetDbConnector()); DisplayPreferencesRepository = displayPreferencesRepo; RegisterSingleInstance(DisplayPreferencesRepository); - var itemRepo = new SqliteItemRepository(ServerConfigurationManager, JsonSerializer, LogManager); + var itemRepo = new SqliteItemRepository(ServerConfigurationManager, JsonSerializer, LogManager, NativeApp.GetDbConnector()); ItemRepository = itemRepo; RegisterSingleInstance(ItemRepository); @@ -553,8 +553,8 @@ namespace MediaBrowser.Server.Startup.Common RegisterSingleInstance(NativeApp.GetPowerManagement()); - var sharingRepo = new SharingRepository(LogManager, ApplicationPaths); - await sharingRepo.Initialize(NativeApp.GetDbConnector()).ConfigureAwait(false); + var sharingRepo = new SharingRepository(LogManager, ApplicationPaths, NativeApp.GetDbConnector()); + await sharingRepo.Initialize().ConfigureAwait(false); RegisterSingleInstance(new SharingManager(sharingRepo, ServerConfigurationManager, LibraryManager, this)); RegisterSingleInstance(new SsdpHandler(LogManager.GetLogger("SsdpHandler"), ServerConfigurationManager, this)); @@ -571,7 +571,7 @@ namespace MediaBrowser.Server.Startup.Common SubtitleEncoder = new SubtitleEncoder(LibraryManager, LogManager.GetLogger("SubtitleEncoder"), ApplicationPaths, FileSystemManager, MediaEncoder, JsonSerializer, HttpClient, MediaSourceManager); RegisterSingleInstance(SubtitleEncoder); - await displayPreferencesRepo.Initialize(NativeApp.GetDbConnector()).ConfigureAwait(false); + await displayPreferencesRepo.Initialize().ConfigureAwait(false); await ConfigureUserDataRepositories().ConfigureAwait(false); await itemRepo.Initialize(NativeApp.GetDbConnector()).ConfigureAwait(false); ((LibraryManager)LibraryManager).ItemRepository = ItemRepository; @@ -670,9 +670,9 @@ namespace MediaBrowser.Server.Startup.Common { try { - var repo = new SqliteUserRepository(LogManager, ApplicationPaths, JsonSerializer); + var repo = new SqliteUserRepository(LogManager, ApplicationPaths, JsonSerializer, NativeApp.GetDbConnector()); - await repo.Initialize(NativeApp.GetDbConnector()).ConfigureAwait(false); + await repo.Initialize().ConfigureAwait(false); return repo; } @@ -689,7 +689,7 @@ namespace MediaBrowser.Server.Startup.Common /// Task{IUserRepository}. private async Task GetFileOrganizationRepository() { - var repo = new SqliteFileOrganizationRepository(LogManager, ServerConfigurationManager.ApplicationPaths); + var repo = new SqliteFileOrganizationRepository(LogManager, ServerConfigurationManager.ApplicationPaths, NativeApp.GetDbConnector()); await repo.Initialize(NativeApp.GetDbConnector()).ConfigureAwait(false); @@ -698,27 +698,27 @@ namespace MediaBrowser.Server.Startup.Common private async Task GetAuthenticationRepository() { - var repo = new AuthenticationRepository(LogManager, ServerConfigurationManager.ApplicationPaths); + var repo = new AuthenticationRepository(LogManager, ServerConfigurationManager.ApplicationPaths, NativeApp.GetDbConnector()); - await repo.Initialize(NativeApp.GetDbConnector()).ConfigureAwait(false); + await repo.Initialize().ConfigureAwait(false); return repo; } private async Task GetActivityLogRepository() { - var repo = new ActivityRepository(LogManager, ServerConfigurationManager.ApplicationPaths); + var repo = new ActivityRepository(LogManager, ServerConfigurationManager.ApplicationPaths, NativeApp.GetDbConnector()); - await repo.Initialize(NativeApp.GetDbConnector()).ConfigureAwait(false); + await repo.Initialize().ConfigureAwait(false); return repo; } private async Task GetSyncRepository() { - var repo = new SyncRepository(LogManager, JsonSerializer, ServerConfigurationManager.ApplicationPaths); + var repo = new SyncRepository(LogManager, JsonSerializer, ServerConfigurationManager.ApplicationPaths, NativeApp.GetDbConnector()); - await repo.Initialize(NativeApp.GetDbConnector()).ConfigureAwait(false); + await repo.Initialize().ConfigureAwait(false); return repo; } @@ -729,9 +729,9 @@ namespace MediaBrowser.Server.Startup.Common /// Task. private async Task ConfigureNotificationsRepository() { - var repo = new SqliteNotificationsRepository(LogManager, ApplicationPaths); + var repo = new SqliteNotificationsRepository(LogManager, ApplicationPaths, NativeApp.GetDbConnector()); - await repo.Initialize(NativeApp.GetDbConnector()).ConfigureAwait(false); + await repo.Initialize().ConfigureAwait(false); NotificationsRepository = repo; @@ -744,7 +744,7 @@ namespace MediaBrowser.Server.Startup.Common /// Task. private async Task ConfigureUserDataRepositories() { - var repo = new SqliteUserDataRepository(LogManager, ApplicationPaths); + var repo = new SqliteUserDataRepository(LogManager, ApplicationPaths, NativeApp.GetDbConnector()); await repo.Initialize(NativeApp.GetDbConnector()).ConfigureAwait(false); diff --git a/MediaBrowser.ServerApplication/Native/DbConnector.cs b/MediaBrowser.ServerApplication/Native/DbConnector.cs index 6001ac3c0..9aaa96a80 100644 --- a/MediaBrowser.ServerApplication/Native/DbConnector.cs +++ b/MediaBrowser.ServerApplication/Native/DbConnector.cs @@ -16,18 +16,9 @@ namespace MediaBrowser.ServerApplication.Native _logger = logger; } - public async Task Connect(string dbPath, int? cacheSize = null) + public Task Connect(string dbPath, bool isReadOnly, bool enablePooling = false, int? cacheSize = null) { - try - { - return await SqliteExtensions.ConnectToDb(dbPath, cacheSize, _logger).ConfigureAwait(false); - } - catch (Exception ex) - { - _logger.ErrorException("Error opening database {0}", ex, dbPath); - - throw; - } + return SqliteExtensions.ConnectToDb(dbPath, isReadOnly, enablePooling, cacheSize, _logger); } } } \ No newline at end of file diff --git a/MediaBrowser.WebDashboard/Api/DashboardService.cs b/MediaBrowser.WebDashboard/Api/DashboardService.cs index 904953cfc..809c3f1a5 100644 --- a/MediaBrowser.WebDashboard/Api/DashboardService.cs +++ b/MediaBrowser.WebDashboard/Api/DashboardService.cs @@ -342,7 +342,9 @@ namespace MediaBrowser.WebDashboard.Api if (string.Equals(mode, "cordova", StringComparison.OrdinalIgnoreCase)) { - DeleteFoldersByName(Path.Combine(bowerPath, "emby-webcomponents"), "fonts"); + DeleteFoldersByName(Path.Combine(bowerPath, "emby-webcomponents", "fonts"), "montserrat"); + DeleteFoldersByName(Path.Combine(bowerPath, "emby-webcomponents", "fonts"), "opensans"); + DeleteFoldersByName(Path.Combine(bowerPath, "emby-webcomponents", "fonts"), "roboto"); } _fileSystem.DeleteDirectory(Path.Combine(bowerPath, "jquery", "src"), true); -- cgit v1.2.3 From 01c7dba742530e1274350bc9f8ea38a6ebc8e8f5 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Tue, 14 Jun 2016 02:40:21 -0400 Subject: don't auto-restart during recordings --- .../EntryPoints/AutomaticRestartEntryPoint.cs | 24 +++++++++++++++++++-- .../LiveTv/EmbyTV/EncodedRecorder.cs | 2 +- .../LiveTv/Listings/XmlTvListingsProvider.cs | 25 +++++++++++++--------- 3 files changed, 38 insertions(+), 13 deletions(-) (limited to 'MediaBrowser.Server.Implementations/EntryPoints') diff --git a/MediaBrowser.Server.Implementations/EntryPoints/AutomaticRestartEntryPoint.cs b/MediaBrowser.Server.Implementations/EntryPoints/AutomaticRestartEntryPoint.cs index df6a9e654..f520316bc 100644 --- a/MediaBrowser.Server.Implementations/EntryPoints/AutomaticRestartEntryPoint.cs +++ b/MediaBrowser.Server.Implementations/EntryPoints/AutomaticRestartEntryPoint.cs @@ -8,6 +8,8 @@ using MediaBrowser.Model.Tasks; using System; using System.Linq; using System.Threading; +using MediaBrowser.Controller.LiveTv; +using MediaBrowser.Model.LiveTv; namespace MediaBrowser.Server.Implementations.EntryPoints { @@ -18,16 +20,18 @@ namespace MediaBrowser.Server.Implementations.EntryPoints private readonly ITaskManager _iTaskManager; private readonly ISessionManager _sessionManager; private readonly IServerConfigurationManager _config; + private readonly ILiveTvManager _liveTvManager; private Timer _timer; - public AutomaticRestartEntryPoint(IServerApplicationHost appHost, ILogger logger, ITaskManager iTaskManager, ISessionManager sessionManager, IServerConfigurationManager config) + public AutomaticRestartEntryPoint(IServerApplicationHost appHost, ILogger logger, ITaskManager iTaskManager, ISessionManager sessionManager, IServerConfigurationManager config, ILiveTvManager liveTvManager) { _appHost = appHost; _logger = logger; _iTaskManager = iTaskManager; _sessionManager = sessionManager; _config = config; + _liveTvManager = liveTvManager; } public void Run() @@ -44,7 +48,7 @@ namespace MediaBrowser.Server.Implementations.EntryPoints if (_appHost.HasPendingRestart) { - _timer = new Timer(TimerCallback, null, TimeSpan.FromMinutes(5), TimeSpan.FromMinutes(5)); + _timer = new Timer(TimerCallback, null, TimeSpan.FromMinutes(10), TimeSpan.FromMinutes(10)); } } @@ -72,6 +76,22 @@ namespace MediaBrowser.Server.Implementations.EntryPoints return false; } + if (_liveTvManager.Services.Count == 1) + { + try + { + var timers = _liveTvManager.GetTimers(new TimerQuery(), CancellationToken.None).Result; + if (timers.Items.Any(i => i.Status == RecordingStatus.InProgress)) + { + return false; + } + } + catch (Exception ex) + { + _logger.ErrorException("Error getting timers", ex); + } + } + var now = DateTime.UtcNow; return !_sessionManager.Sessions.Any(i => (now - i.LastActivityDate).TotalMinutes < 30); diff --git a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EncodedRecorder.cs b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EncodedRecorder.cs index 4022252ac..ffd5b65e4 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EncodedRecorder.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EncodedRecorder.cs @@ -145,7 +145,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV videoArgs = "-codec:v:0 copy"; } - var commandLineArgs = "-fflags +genpts -async 1 -vsync -1 -i \"{0}\" -t {4} -sn {2} -map_metadata -1 -threads 0 {3} -y \"{1}\""; + var commandLineArgs = "-fflags +genpts -async 1 -vsync -1 -re -i \"{0}\" -t {4} -sn {2} -map_metadata -1 -threads 0 {3} -y \"{1}\""; if (mediaSource.ReadAtNativeFramerate) { diff --git a/MediaBrowser.Server.Implementations/LiveTv/Listings/XmlTvListingsProvider.cs b/MediaBrowser.Server.Implementations/LiveTv/Listings/XmlTvListingsProvider.cs index 46794714c..1628ddc01 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/Listings/XmlTvListingsProvider.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/Listings/XmlTvListingsProvider.cs @@ -8,10 +8,10 @@ using System.IO; using System.Linq; using System.Threading; using System.Threading.Tasks; - using Emby.XmlTv.Classes; using MediaBrowser.Common.Net; using MediaBrowser.Controller.Configuration; +using MediaBrowser.Model.Logging; namespace MediaBrowser.Server.Implementations.LiveTv.Listings { @@ -19,11 +19,13 @@ namespace MediaBrowser.Server.Implementations.LiveTv.Listings { private readonly IServerConfigurationManager _config; private readonly IHttpClient _httpClient; + private readonly ILogger _logger; - public XmlTvListingsProvider(IServerConfigurationManager config, IHttpClient httpClient) + public XmlTvListingsProvider(IServerConfigurationManager config, IHttpClient httpClient, ILogger logger) { _config = config; _httpClient = httpClient; + _logger = logger; } public string Name @@ -55,6 +57,8 @@ namespace MediaBrowser.Server.Implementations.LiveTv.Listings return cacheFile; } + _logger.Info("Downloading xmltv listings from {0}", path); + var tempFile = await _httpClient.GetTempFile(new HttpRequestOptions { CancellationToken = cancellationToken, @@ -101,10 +105,11 @@ namespace MediaBrowser.Server.Implementations.LiveTv.Listings }); } - public Task AddMetadata(ListingsProviderInfo info, List channels, CancellationToken cancellationToken) + public async Task AddMetadata(ListingsProviderInfo info, List channels, CancellationToken cancellationToken) { // Add the channel image url - var reader = new XmlTvReader(info.Path, GetLanguage(), null); + var path = await GetXml(info.Path, cancellationToken).ConfigureAwait(false); + var reader = new XmlTvReader(path, GetLanguage(), null); var results = reader.GetChannels().ToList(); if (channels != null) @@ -120,8 +125,6 @@ namespace MediaBrowser.Server.Implementations.LiveTv.Listings } }); } - - return Task.FromResult(true); } public Task Validate(ListingsProviderInfo info, bool validateLogin, bool validateListings) @@ -135,20 +138,22 @@ namespace MediaBrowser.Server.Implementations.LiveTv.Listings return Task.FromResult(true); } - public Task> GetLineups(ListingsProviderInfo info, string country, string location) + public async Task> GetLineups(ListingsProviderInfo info, string country, string location) { // In theory this should never be called because there is always only one lineup - var reader = new XmlTvReader(info.Path, GetLanguage(), null); + var path = await GetXml(info.Path, CancellationToken.None).ConfigureAwait(false); + var reader = new XmlTvReader(path, GetLanguage(), null); var results = reader.GetChannels(); // Should this method be async? - return Task.FromResult(results.Select(c => new NameIdPair() { Id = c.Id, Name = c.DisplayName }).ToList()); + return results.Select(c => new NameIdPair() { Id = c.Id, Name = c.DisplayName }).ToList(); } public async Task> GetChannels(ListingsProviderInfo info, CancellationToken cancellationToken) { // In theory this should never be called because there is always only one lineup - var reader = new XmlTvReader(info.Path, GetLanguage(), null); + var path = await GetXml(info.Path, cancellationToken).ConfigureAwait(false); + var reader = new XmlTvReader(path, GetLanguage(), null); var results = reader.GetChannels(); // Should this method be async? -- cgit v1.2.3 From 759f5a856064450acdb4c26839d6d890afb99a17 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sun, 19 Jun 2016 02:18:29 -0400 Subject: update task results --- Emby.Drawing/ImageMagick/ImageMagickEncoder.cs | 11 --- MediaBrowser.Api/BaseApiService.cs | 2 +- MediaBrowser.Api/GamesService.cs | 9 +- MediaBrowser.Api/Images/ImageService.cs | 10 +-- MediaBrowser.Api/Images/RemoteImageService.cs | 10 +-- MediaBrowser.Api/ItemLookupService.cs | 36 ++++---- MediaBrowser.Api/Library/LibraryService.cs | 6 +- MediaBrowser.Api/LiveTv/LiveTvService.cs | 2 +- MediaBrowser.Api/Movies/MoviesService.cs | 18 ++-- MediaBrowser.Api/Music/AlbumsService.cs | 13 +-- MediaBrowser.Api/Music/InstantMixService.cs | 21 ++--- MediaBrowser.Api/PackageReviewService.cs | 12 +-- MediaBrowser.Api/Playback/Hls/BaseHlsService.cs | 4 +- MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs | 2 +- MediaBrowser.Api/Playback/Hls/HlsSegmentService.cs | 9 +- .../Playback/Progressive/AudioService.cs | 5 +- .../Progressive/BaseProgressiveStreamingService.cs | 28 ++++--- .../Playback/Progressive/VideoService.cs | 5 +- MediaBrowser.Api/PlaylistService.cs | 4 +- MediaBrowser.Api/SimilarItemsHelper.cs | 12 +-- MediaBrowser.Api/Subtitles/SubtitleService.cs | 10 +-- MediaBrowser.Api/Sync/SyncService.cs | 14 ++-- MediaBrowser.Api/System/SystemService.cs | 2 +- MediaBrowser.Api/TvShowsService.cs | 25 +++--- MediaBrowser.Api/UserLibrary/ItemsService.cs | 2 +- MediaBrowser.Api/UserLibrary/PlaystateService.cs | 6 +- MediaBrowser.Api/UserLibrary/UserLibraryService.cs | 12 +-- MediaBrowser.Controller/Dto/IDtoService.cs | 3 +- MediaBrowser.Controller/Entities/BaseItem.cs | 4 +- MediaBrowser.Controller/Entities/Folder.cs | 24 ++++-- MediaBrowser.Controller/Entities/IHasUserData.cs | 3 +- MediaBrowser.Controller/IServerApplicationHost.cs | 5 +- .../Library/IUserDataManager.cs | 4 +- MediaBrowser.Controller/Net/IHttpResultFactory.cs | 8 +- MediaBrowser.Dlna/Didl/DidlBuilder.cs | 4 +- MediaBrowser.Dlna/Main/DlnaEntryPoint.cs | 13 +-- MediaBrowser.Dlna/PlayTo/PlayToController.cs | 35 ++++---- MediaBrowser.Dlna/Ssdp/DeviceDiscovery.cs | 4 +- MediaBrowser.MediaEncoding/Encoder/AudioEncoder.cs | 7 +- MediaBrowser.MediaEncoding/Encoder/BaseEncoder.cs | 29 +++---- MediaBrowser.MediaEncoding/Encoder/VideoEncoder.cs | 11 ++- .../Channels/ChannelManager.cs | 8 +- .../Connect/ConnectManager.cs | 14 ++-- .../Dto/DtoService.cs | 95 ++++++++++------------ .../EntryPoints/AutomaticRestartEntryPoint.cs | 28 ++++--- .../EntryPoints/UserDataChangeNotifier.cs | 2 +- .../HttpServer/HttpResultFactory.cs | 10 +-- .../HttpServer/SwaggerService.cs | 2 +- .../Library/LibraryManager.cs | 2 +- .../Library/UserDataManager.cs | 13 ++- .../Library/UserManager.cs | 2 +- .../LiveTv/LiveTvManager.cs | 6 +- .../LiveTv/LiveTvMediaSourceProvider.cs | 2 +- .../Session/SessionManager.cs | 29 ++++--- .../Sync/SyncJobProcessor.cs | 32 ++++++-- .../Udp/UdpServer.cs | 12 +-- .../ApplicationHost.cs | 49 +++++------ MediaBrowser.WebDashboard/Api/DashboardService.cs | 9 +- 58 files changed, 404 insertions(+), 355 deletions(-) (limited to 'MediaBrowser.Server.Implementations/EntryPoints') diff --git a/Emby.Drawing/ImageMagick/ImageMagickEncoder.cs b/Emby.Drawing/ImageMagick/ImageMagickEncoder.cs index 180f797e3..3dbe7239d 100644 --- a/Emby.Drawing/ImageMagick/ImageMagickEncoder.cs +++ b/Emby.Drawing/ImageMagick/ImageMagickEncoder.cs @@ -111,7 +111,6 @@ namespace Emby.Drawing.ImageMagick wand.CurrentImage.TrimImage(10); wand.SaveImage(outputPath); } - SaveDelay(); } public ImageSize GetImageSize(string path) @@ -189,7 +188,6 @@ namespace Emby.Drawing.ImageMagick } } } - SaveDelay(); } private void AddForegroundLayer(MagickWand wand, ImageProcessingOptions options) @@ -294,15 +292,6 @@ namespace Emby.Drawing.ImageMagick { new StripCollageBuilder(_appPaths, _fileSystem).BuildPosterCollage(options.InputPaths.ToList(), options.OutputPath, options.Width, options.Height); } - - SaveDelay(); - } - - private void SaveDelay() - { - // For some reason the images are not always getting released right away - //var task = Task.Delay(300); - //Task.WaitAll(task); } public string Name diff --git a/MediaBrowser.Api/BaseApiService.cs b/MediaBrowser.Api/BaseApiService.cs index 44d459a01..44a367be0 100644 --- a/MediaBrowser.Api/BaseApiService.cs +++ b/MediaBrowser.Api/BaseApiService.cs @@ -115,7 +115,7 @@ namespace MediaBrowser.Api /// System.Object. protected object ToStaticFileResult(string path) { - return ResultFactory.GetStaticFileResult(Request, path); + return ResultFactory.GetStaticFileResult(Request, path).Result; } protected DtoOptions GetDtoOptions(object request) diff --git a/MediaBrowser.Api/GamesService.cs b/MediaBrowser.Api/GamesService.cs index cb77e62ad..4758b0186 100644 --- a/MediaBrowser.Api/GamesService.cs +++ b/MediaBrowser.Api/GamesService.cs @@ -10,6 +10,7 @@ using System.Collections.Generic; using System.Globalization; using System.IO; using System.Linq; +using System.Threading.Tasks; using MediaBrowser.Model.Querying; namespace MediaBrowser.Api @@ -186,14 +187,14 @@ namespace MediaBrowser.Api /// /// The request. /// System.Object. - public object Get(GetSimilarGames request) + public async Task Get(GetSimilarGames request) { - var result = GetSimilarItemsResult(request); + var result = await GetSimilarItemsResult(request).ConfigureAwait(false); return ToOptimizedSerializedResultUsingCache(result); } - private QueryResult GetSimilarItemsResult(BaseGetSimilarItemsFromItem request) + private async Task> GetSimilarItemsResult(BaseGetSimilarItemsFromItem request) { var user = !string.IsNullOrWhiteSpace(request.UserId) ? _userManager.GetUserById(request.UserId) : null; @@ -216,7 +217,7 @@ namespace MediaBrowser.Api var result = new QueryResult { - Items = _dtoService.GetBaseItemDtos(itemsResult, dtoOptions, user).ToArray(), + Items = (await _dtoService.GetBaseItemDtos(itemsResult, dtoOptions, user).ConfigureAwait(false)).ToArray(), TotalRecordCount = itemsResult.Count }; diff --git a/MediaBrowser.Api/Images/ImageService.cs b/MediaBrowser.Api/Images/ImageService.cs index e5fe5bd68..a511f8c72 100644 --- a/MediaBrowser.Api/Images/ImageService.cs +++ b/MediaBrowser.Api/Images/ImageService.cs @@ -514,7 +514,7 @@ namespace MediaBrowser.Api.Images /// if set to true [is head request]. /// System.Object. /// - public object GetImage(ImageRequest request, IHasImages item, bool isHeadRequest) + public Task GetImage(ImageRequest request, IHasImages item, bool isHeadRequest) { if (request.PercentPlayed.HasValue) { @@ -594,8 +594,7 @@ namespace MediaBrowser.Api.Images supportedImageEnhancers, cacheDuration, responseHeaders, - isHeadRequest) - .Result; + isHeadRequest); } private async Task GetImageResult(IHasImages item, @@ -632,7 +631,7 @@ namespace MediaBrowser.Api.Images headers["Vary"] = "Accept"; - return ResultFactory.GetStaticFileResult(Request, new StaticFileResultOptions + return await ResultFactory.GetStaticFileResult(Request, new StaticFileResultOptions { CacheDuration = cacheDuration, ResponseHeaders = headers, @@ -643,7 +642,8 @@ namespace MediaBrowser.Api.Images // Sometimes imagemagick keeps a hold on the file briefly even after it's done writing to it. // I'd rather do this than add a delay after saving the file FileShare = FileShare.ReadWrite - }); + + }).ConfigureAwait(false); } private List GetOutputFormats(ImageRequest request, ItemImageInfo image, bool cropwhitespace, List enhancers) diff --git a/MediaBrowser.Api/Images/RemoteImageService.cs b/MediaBrowser.Api/Images/RemoteImageService.cs index 02d1cdbe2..b21e54495 100644 --- a/MediaBrowser.Api/Images/RemoteImageService.cs +++ b/MediaBrowser.Api/Images/RemoteImageService.cs @@ -238,9 +238,9 @@ namespace MediaBrowser.Api.Images } if (_fileSystem.FileExists(contentPath)) - { - return ToStaticFileResult(contentPath); - } + { + return await ResultFactory.GetStaticFileResult(Request, contentPath).ConfigureAwait(false); + } } catch (DirectoryNotFoundException) { @@ -259,9 +259,9 @@ namespace MediaBrowser.Api.Images contentPath = await reader.ReadToEndAsync().ConfigureAwait(false); } - return ToStaticFileResult(contentPath); + return await ResultFactory.GetStaticFileResult(Request, contentPath).ConfigureAwait(false); } - + /// /// Downloads the image. /// diff --git a/MediaBrowser.Api/ItemLookupService.cs b/MediaBrowser.Api/ItemLookupService.cs index 41bfd9da2..30cde4883 100644 --- a/MediaBrowser.Api/ItemLookupService.cs +++ b/MediaBrowser.Api/ItemLookupService.cs @@ -132,58 +132,58 @@ namespace MediaBrowser.Api return ToOptimizedResult(infos); } - public object Post(GetMovieRemoteSearchResults request) + public async Task Post(GetMovieRemoteSearchResults request) { - var result = _providerManager.GetRemoteSearchResults(request, CancellationToken.None).Result; + var result = await _providerManager.GetRemoteSearchResults(request, CancellationToken.None).ConfigureAwait(false); return ToOptimizedResult(result); } - public object Post(GetSeriesRemoteSearchResults request) + public async Task Post(GetSeriesRemoteSearchResults request) { - var result = _providerManager.GetRemoteSearchResults(request, CancellationToken.None).Result; + var result = await _providerManager.GetRemoteSearchResults(request, CancellationToken.None).ConfigureAwait(false); return ToOptimizedResult(result); } - public object Post(GetGameRemoteSearchResults request) + public async Task Post(GetGameRemoteSearchResults request) { - var result = _providerManager.GetRemoteSearchResults(request, CancellationToken.None).Result; + var result = await _providerManager.GetRemoteSearchResults(request, CancellationToken.None).ConfigureAwait(false); return ToOptimizedResult(result); } - public object Post(GetBoxSetRemoteSearchResults request) + public async Task Post(GetBoxSetRemoteSearchResults request) { - var result = _providerManager.GetRemoteSearchResults(request, CancellationToken.None).Result; + var result = await _providerManager.GetRemoteSearchResults(request, CancellationToken.None).ConfigureAwait(false); return ToOptimizedResult(result); } - public object Post(GetPersonRemoteSearchResults request) + public async Task Post(GetPersonRemoteSearchResults request) { - var result = _providerManager.GetRemoteSearchResults(request, CancellationToken.None).Result; + var result = await _providerManager.GetRemoteSearchResults(request, CancellationToken.None).ConfigureAwait(false); return ToOptimizedResult(result); } - public object Post(GetMusicAlbumRemoteSearchResults request) + public async Task Post(GetMusicAlbumRemoteSearchResults request) { - var result = _providerManager.GetRemoteSearchResults(request, CancellationToken.None).Result; + var result = await _providerManager.GetRemoteSearchResults(request, CancellationToken.None).ConfigureAwait(false); return ToOptimizedResult(result); } - public object Post(GetMusicArtistRemoteSearchResults request) + public async Task Post(GetMusicArtistRemoteSearchResults request) { - var result = _providerManager.GetRemoteSearchResults(request, CancellationToken.None).Result; + var result = await _providerManager.GetRemoteSearchResults(request, CancellationToken.None).ConfigureAwait(false); return ToOptimizedResult(result); } - public object Get(GetRemoteSearchImage request) + public async Task Get(GetRemoteSearchImage request) { - var result = GetRemoteImage(request).Result; + var result = GetRemoteImage(request).ConfigureAwait(false); return result; } @@ -241,7 +241,7 @@ namespace MediaBrowser.Api if (_fileSystem.FileExists(contentPath)) { - return ToStaticFileResult(contentPath); + return await ResultFactory.GetStaticFileResult(Request, contentPath).ConfigureAwait(false); } } catch (DirectoryNotFoundException) @@ -261,7 +261,7 @@ namespace MediaBrowser.Api contentPath = await reader.ReadToEndAsync().ConfigureAwait(false); } - return ToStaticFileResult(contentPath); + return await ResultFactory.GetStaticFileResult(Request, contentPath).ConfigureAwait(false); } /// diff --git a/MediaBrowser.Api/Library/LibraryService.cs b/MediaBrowser.Api/Library/LibraryService.cs index f9b3def97..4cd6a66ef 100644 --- a/MediaBrowser.Api/Library/LibraryService.cs +++ b/MediaBrowser.Api/Library/LibraryService.cs @@ -493,7 +493,7 @@ namespace MediaBrowser.Api.Library } } - public object Get(GetDownload request) + public Task Get(GetDownload request) { var item = _libraryManager.GetItemById(request.Id); var auth = _authContext.GetAuthorizationInfo(Request); @@ -552,7 +552,7 @@ namespace MediaBrowser.Api.Library } } - public object Get(GetFile request) + public Task Get(GetFile request) { var item = _libraryManager.GetItemById(request.Id); var locationType = item.LocationType; @@ -565,7 +565,7 @@ namespace MediaBrowser.Api.Library throw new ArgumentException("This command cannot be used for directories."); } - return ToStaticFileResult(item.Path); + return ResultFactory.GetStaticFileResult(Request, item.Path); } /// diff --git a/MediaBrowser.Api/LiveTv/LiveTvService.cs b/MediaBrowser.Api/LiveTv/LiveTvService.cs index 41c0c39ea..48f7cd62e 100644 --- a/MediaBrowser.Api/LiveTv/LiveTvService.cs +++ b/MediaBrowser.Api/LiveTv/LiveTvService.cs @@ -785,7 +785,7 @@ namespace MediaBrowser.Api.LiveTv var user = string.IsNullOrEmpty(request.UserId) ? null : _userManager.GetUserById(request.UserId); - var returnArray = _dtoService.GetBaseItemDtos(channelResult.Items, GetDtoOptions(Request), user).ToArray(); + var returnArray = (await _dtoService.GetBaseItemDtos(channelResult.Items, GetDtoOptions(Request), user).ConfigureAwait(false)).ToArray(); var result = new QueryResult { diff --git a/MediaBrowser.Api/Movies/MoviesService.cs b/MediaBrowser.Api/Movies/MoviesService.cs index ff18d440c..a2a935b12 100644 --- a/MediaBrowser.Api/Movies/MoviesService.cs +++ b/MediaBrowser.Api/Movies/MoviesService.cs @@ -111,16 +111,16 @@ namespace MediaBrowser.Api.Movies /// /// The request. /// System.Object. - public object Get(GetSimilarMovies request) + public async Task Get(GetSimilarMovies request) { - var result = GetSimilarItemsResult(request); + var result = await GetSimilarItemsResult(request).ConfigureAwait(false); return ToOptimizedSerializedResultUsingCache(result); } - public object Get(GetSimilarTrailers request) + public async Task Get(GetSimilarTrailers request) { - var result = GetSimilarItemsResult(request); + var result = await GetSimilarItemsResult(request).ConfigureAwait(false); return ToOptimizedSerializedResultUsingCache(result); } @@ -138,7 +138,7 @@ namespace MediaBrowser.Api.Movies return ToOptimizedResult(result); } - private QueryResult GetSimilarItemsResult(BaseGetSimilarItemsFromItem request) + private async Task> GetSimilarItemsResult(BaseGetSimilarItemsFromItem request) { var user = !string.IsNullOrWhiteSpace(request.UserId) ? _userManager.GetUserById(request.UserId) : null; @@ -163,7 +163,7 @@ namespace MediaBrowser.Api.Movies var result = new QueryResult { - Items = _dtoService.GetBaseItemDtos(itemsResult, dtoOptions, user).ToArray(), + Items = (await _dtoService.GetBaseItemDtos(itemsResult, dtoOptions, user).ConfigureAwait(false)).ToArray(), TotalRecordCount = itemsResult.Count }; @@ -296,7 +296,7 @@ namespace MediaBrowser.Api.Movies BaselineItemName = name, CategoryId = name.GetMD5().ToString("N"), RecommendationType = type, - Items = _dtoService.GetBaseItemDtos(items, dtoOptions, user).ToArray() + Items = _dtoService.GetBaseItemDtos(items, dtoOptions, user).Result.ToArray() }; } } @@ -330,7 +330,7 @@ namespace MediaBrowser.Api.Movies BaselineItemName = name, CategoryId = name.GetMD5().ToString("N"), RecommendationType = type, - Items = _dtoService.GetBaseItemDtos(items, dtoOptions, user).ToArray() + Items = _dtoService.GetBaseItemDtos(items, dtoOptions, user).Result.ToArray() }; } } @@ -361,7 +361,7 @@ namespace MediaBrowser.Api.Movies BaselineItemName = item.Name, CategoryId = item.Id.ToString("N"), RecommendationType = type, - Items = _dtoService.GetBaseItemDtos(similar, dtoOptions, user).ToArray() + Items = _dtoService.GetBaseItemDtos(similar, dtoOptions, user).Result.ToArray() }; } } diff --git a/MediaBrowser.Api/Music/AlbumsService.cs b/MediaBrowser.Api/Music/AlbumsService.cs index e774c3077..2d7e909bf 100644 --- a/MediaBrowser.Api/Music/AlbumsService.cs +++ b/MediaBrowser.Api/Music/AlbumsService.cs @@ -8,6 +8,7 @@ using ServiceStack; using System; using System.Collections.Generic; using System.Linq; +using System.Threading.Tasks; namespace MediaBrowser.Api.Music { @@ -49,18 +50,18 @@ namespace MediaBrowser.Api.Music _dtoService = dtoService; } - public object Get(GetSimilarArtists request) + public async Task Get(GetSimilarArtists request) { var dtoOptions = GetDtoOptions(request); - var result = SimilarItemsHelper.GetSimilarItemsResult(dtoOptions, _userManager, + var result = await SimilarItemsHelper.GetSimilarItemsResult(dtoOptions, _userManager, _itemRepo, _libraryManager, _userDataRepository, _dtoService, Logger, request, new[] { typeof(MusicArtist) }, - SimilarItemsHelper.GetSimiliarityScore); + SimilarItemsHelper.GetSimiliarityScore).ConfigureAwait(false); return ToOptimizedSerializedResultUsingCache(result); } @@ -70,18 +71,18 @@ namespace MediaBrowser.Api.Music /// /// The request. /// System.Object. - public object Get(GetSimilarAlbums request) + public async Task Get(GetSimilarAlbums request) { var dtoOptions = GetDtoOptions(request); - var result = SimilarItemsHelper.GetSimilarItemsResult(dtoOptions, _userManager, + var result = await SimilarItemsHelper.GetSimilarItemsResult(dtoOptions, _userManager, _itemRepo, _libraryManager, _userDataRepository, _dtoService, Logger, request, new[] { typeof(MusicAlbum) }, - GetAlbumSimilarityScore); + GetAlbumSimilarityScore).ConfigureAwait(false); return ToOptimizedSerializedResultUsingCache(result); } diff --git a/MediaBrowser.Api/Music/InstantMixService.cs b/MediaBrowser.Api/Music/InstantMixService.cs index d2a4aa60c..19265408b 100644 --- a/MediaBrowser.Api/Music/InstantMixService.cs +++ b/MediaBrowser.Api/Music/InstantMixService.cs @@ -8,6 +8,7 @@ using MediaBrowser.Model.Querying; using ServiceStack; using System.Collections.Generic; using System.Linq; +using System.Threading.Tasks; namespace MediaBrowser.Api.Music { @@ -76,7 +77,7 @@ namespace MediaBrowser.Api.Music _libraryManager = libraryManager; } - public object Get(GetInstantMixFromItem request) + public Task Get(GetInstantMixFromItem request) { var item = _libraryManager.GetItemById(request.Id); @@ -87,7 +88,7 @@ namespace MediaBrowser.Api.Music return GetResult(items, user, request); } - public object Get(GetInstantMixFromArtistId request) + public Task Get(GetInstantMixFromArtistId request) { var item = _libraryManager.GetItemById(request.Id); @@ -98,7 +99,7 @@ namespace MediaBrowser.Api.Music return GetResult(items, user, request); } - public object Get(GetInstantMixFromMusicGenreId request) + public Task Get(GetInstantMixFromMusicGenreId request) { var item = _libraryManager.GetItemById(request.Id); @@ -109,7 +110,7 @@ namespace MediaBrowser.Api.Music return GetResult(items, user, request); } - public object Get(GetInstantMixFromSong request) + public Task Get(GetInstantMixFromSong request) { var item = _libraryManager.GetItemById(request.Id); @@ -120,7 +121,7 @@ namespace MediaBrowser.Api.Music return GetResult(items, user, request); } - public object Get(GetInstantMixFromAlbum request) + public Task Get(GetInstantMixFromAlbum request) { var album = _libraryManager.GetItemById(request.Id); @@ -131,7 +132,7 @@ namespace MediaBrowser.Api.Music return GetResult(items, user, request); } - public object Get(GetInstantMixFromPlaylist request) + public Task Get(GetInstantMixFromPlaylist request) { var playlist = (Playlist)_libraryManager.GetItemById(request.Id); @@ -142,7 +143,7 @@ namespace MediaBrowser.Api.Music return GetResult(items, user, request); } - public object Get(GetInstantMixFromMusicGenre request) + public Task Get(GetInstantMixFromMusicGenre request) { var user = _userManager.GetUserById(request.UserId); @@ -151,7 +152,7 @@ namespace MediaBrowser.Api.Music return GetResult(items, user, request); } - public object Get(GetInstantMixFromArtist request) + public Task Get(GetInstantMixFromArtist request) { var user = _userManager.GetUserById(request.UserId); var artist = _libraryManager.GetArtist(request.Name); @@ -161,7 +162,7 @@ namespace MediaBrowser.Api.Music return GetResult(items, user, request); } - private object GetResult(IEnumerable