From f13ca8f343c3e7b782facbaa4e42b7f8a26246b5 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Wed, 17 Feb 2016 16:24:01 -0500 Subject: update device discovery --- .../LiveTv/TunerHosts/SatIp/SatIpDiscovery.cs | 7 ++++++- .../MediaBrowser.Server.Implementations.csproj | 4 ++-- MediaBrowser.Server.Implementations/packages.config | 2 +- 3 files changed, 9 insertions(+), 4 deletions(-) (limited to 'MediaBrowser.Server.Implementations') diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/SatIpDiscovery.cs b/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/SatIpDiscovery.cs index 08c42bb46..852b86467 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/SatIpDiscovery.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/SatIpDiscovery.cs @@ -42,7 +42,12 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.SatIp void _deviceDiscovery_DeviceDiscovered(object sender, SsdpMessageEventArgs e) { string st = null; - if (e.Headers.TryGetValue("ST", out st) && string.Equals(st, "urn:ses-com:device:SatIPServer:1", StringComparison.OrdinalIgnoreCase)) + string nt = null; + e.Headers.TryGetValue("ST", out st); + e.Headers.TryGetValue("NT", out nt); + + if (string.Equals(st, "urn:ses-com:device:SatIPServer:1", StringComparison.OrdinalIgnoreCase) || + string.Equals(nt, "urn:ses-com:device:SatIPServer:1", StringComparison.OrdinalIgnoreCase)) { string location; if (e.Headers.TryGetValue("Location", out location) && !string.IsNullOrWhiteSpace(location)) diff --git a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj index 5f2fab457..80592c724 100644 --- a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj +++ b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj @@ -52,9 +52,9 @@ ..\packages\Interfaces.IO.1.0.0.5\lib\portable-net45+sl4+wp71+win8+wpa81\Interfaces.IO.dll - + False - ..\packages\MediaBrowser.Naming.1.0.0.47\lib\portable-net45+sl4+wp71+win8+wpa81\MediaBrowser.Naming.dll + ..\packages\MediaBrowser.Naming.1.0.0.48\lib\portable-net45+sl4+wp71+win8+wpa81\MediaBrowser.Naming.dll ..\packages\morelinq.1.4.0\lib\net35\MoreLinq.dll diff --git a/MediaBrowser.Server.Implementations/packages.config b/MediaBrowser.Server.Implementations/packages.config index 816f85b42..4f163f8a4 100644 --- a/MediaBrowser.Server.Implementations/packages.config +++ b/MediaBrowser.Server.Implementations/packages.config @@ -3,7 +3,7 @@ - + -- cgit v1.2.3 From eea19c3adcdc47e894d8e557cfc5db42032302b2 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Thu, 18 Feb 2016 13:27:46 -0500 Subject: update authentication --- MediaBrowser.Model/Configuration/ServerConfiguration.cs | 7 ------- .../HttpServer/Security/AuthService.cs | 9 +++------ 2 files changed, 3 insertions(+), 13 deletions(-) (limited to 'MediaBrowser.Server.Implementations') diff --git a/MediaBrowser.Model/Configuration/ServerConfiguration.cs b/MediaBrowser.Model/Configuration/ServerConfiguration.cs index 3cb543e5d..bc102bd40 100644 --- a/MediaBrowser.Model/Configuration/ServerConfiguration.cs +++ b/MediaBrowser.Model/Configuration/ServerConfiguration.cs @@ -182,8 +182,6 @@ namespace MediaBrowser.Model.Configuration public PeopleMetadataOptions PeopleMetadataOptions { get; set; } public bool FindInternetTrailers { get; set; } - public string[] InsecureApps9 { get; set; } - public bool SaveMetadataHidden { get; set; } public NameValuePair[] ContentTypes { get; set; } @@ -256,11 +254,6 @@ namespace MediaBrowser.Model.Configuration PeopleMetadataOptions = new PeopleMetadataOptions(); - InsecureApps9 = new[] - { - "Windows Phone" - }; - MetadataOptions = new[] { new MetadataOptions(1, 1280) {ItemType = "Book"}, diff --git a/MediaBrowser.Server.Implementations/HttpServer/Security/AuthService.cs b/MediaBrowser.Server.Implementations/HttpServer/Security/AuthService.cs index f6b14fcab..d8f7d889c 100644 --- a/MediaBrowser.Server.Implementations/HttpServer/Security/AuthService.cs +++ b/MediaBrowser.Server.Implementations/HttpServer/Security/AuthService.cs @@ -134,20 +134,17 @@ namespace MediaBrowser.Server.Implementations.HttpServer.Security private bool IsExemptFromAuthenticationToken(AuthorizationInfo auth, IAuthenticationAttributes authAttribtues) { - if (!_config.Configuration.IsStartupWizardCompleted && - authAttribtues.AllowBeforeStartupWizard) + if (!_config.Configuration.IsStartupWizardCompleted && authAttribtues.AllowBeforeStartupWizard) { return true; } - return _config.Configuration.InsecureApps9.Contains(auth.Client ?? string.Empty, - StringComparer.OrdinalIgnoreCase); + return false; } private bool IsExemptFromRoles(AuthorizationInfo auth, IAuthenticationAttributes authAttribtues, AuthenticationInfo tokenInfo) { - if (!_config.Configuration.IsStartupWizardCompleted && - authAttribtues.AllowBeforeStartupWizard) + if (!_config.Configuration.IsStartupWizardCompleted && authAttribtues.AllowBeforeStartupWizard) { return true; } -- cgit v1.2.3 From bc6e47c30a456a2cb461ced0598675acfc5a6f62 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Thu, 18 Feb 2016 14:15:26 -0500 Subject: removed dead code --- MediaBrowser.Api/ConnectService.cs | 55 +------------- MediaBrowser.Controller/Connect/IConnectManager.cs | 20 ----- .../Connect/ConnectManager.cs | 88 +--------------------- 3 files changed, 3 insertions(+), 160 deletions(-) (limited to 'MediaBrowser.Server.Implementations') diff --git a/MediaBrowser.Api/ConnectService.cs b/MediaBrowser.Api/ConnectService.cs index bdd2eeaad..4bcd33d9e 100644 --- a/MediaBrowser.Api/ConnectService.cs +++ b/MediaBrowser.Api/ConnectService.cs @@ -1,10 +1,8 @@ -using System; -using MediaBrowser.Common.Extensions; +using MediaBrowser.Common.Extensions; using MediaBrowser.Controller.Connect; using MediaBrowser.Controller.Library; using MediaBrowser.Controller.Net; using MediaBrowser.Model.Connect; -using MediaBrowser.Model.Dto; using ServiceStack; using System.Collections.Generic; using System.Linq; @@ -75,28 +73,6 @@ namespace MediaBrowser.Api public string ConnectUserId { get; set; } } - [Route("/Connect/Supporters", "GET")] - [Authenticated(Roles = "Admin")] - public class GetConnectSupporterSummary : IReturn - { - } - - [Route("/Connect/Supporters", "DELETE")] - [Authenticated(Roles = "Admin")] - public class RemoveConnectSupporter : IReturnVoid - { - [ApiMember(Name = "Id", Description = "User Id", IsRequired = true, DataType = "string", ParameterType = "query", Verb = "DELETE")] - public string Id { get; set; } - } - - [Route("/Connect/Supporters", "POST")] - [Authenticated(Roles = "Admin")] - public class AddConnectSupporter : IReturnVoid - { - [ApiMember(Name = "Id", Description = "User Id", IsRequired = true, DataType = "string", ParameterType = "query", Verb = "POST")] - public string Id { get; set; } - } - public class ConnectService : BaseApiService { private readonly IConnectManager _connectManager; @@ -108,35 +84,6 @@ namespace MediaBrowser.Api _userManager = userManager; } - public async Task Get(GetConnectSupporterSummary request) - { - var result = await _connectManager.GetConnectSupporterSummary().ConfigureAwait(false); - var existingConnectUserIds = result.Users.Select(i => i.Id).ToList(); - - result.EligibleUsers = _userManager.Users - .Where(i => !string.IsNullOrWhiteSpace(i.ConnectUserId)) - .Where(i => !existingConnectUserIds.Contains(i.ConnectUserId, StringComparer.OrdinalIgnoreCase)) - .OrderBy(i => i.Name) - .Select(i => _userManager.GetUserDto(i)) - .ToList(); - - return ToOptimizedResult(result); - } - - public void Delete(RemoveConnectSupporter request) - { - var task = _connectManager.RemoveConnectSupporter(request.Id); - - Task.WaitAll(task); - } - - public void Post(AddConnectSupporter request) - { - var task = _connectManager.AddConnectSupporter(request.Id); - - Task.WaitAll(task); - } - public object Post(CreateConnectLink request) { return _connectManager.LinkUser(request.Id, request.ConnectUsername); diff --git a/MediaBrowser.Controller/Connect/IConnectManager.cs b/MediaBrowser.Controller/Connect/IConnectManager.cs index 1f7652221..e004eaccf 100644 --- a/MediaBrowser.Controller/Connect/IConnectManager.cs +++ b/MediaBrowser.Controller/Connect/IConnectManager.cs @@ -76,25 +76,5 @@ namespace MediaBrowser.Controller.Connect /// The token. /// true if [is authorization token valid] [the specified token]; otherwise, false. bool IsAuthorizationTokenValid(string token); - - /// - /// Gets the connect supporter summary. - /// - /// Task<ConnectSupporterSummary>. - Task GetConnectSupporterSummary(); - - /// - /// Removes the connect supporter. - /// - /// The identifier. - /// Task. - Task RemoveConnectSupporter(string id); - - /// - /// Adds the connect supporter. - /// - /// The identifier. - /// Task. - Task AddConnectSupporter(string id); } } diff --git a/MediaBrowser.Server.Implementations/Connect/ConnectManager.cs b/MediaBrowser.Server.Implementations/Connect/ConnectManager.cs index fdc7e9ee2..cff95b184 100644 --- a/MediaBrowser.Server.Implementations/Connect/ConnectManager.cs +++ b/MediaBrowser.Server.Implementations/Connect/ConnectManager.cs @@ -1071,90 +1071,6 @@ namespace MediaBrowser.Server.Implementations.Connect } } - public async Task GetConnectSupporterSummary() - { - var url = GetConnectUrl("keyAssociation"); - - var options = new HttpRequestOptions - { - Url = url, - CancellationToken = CancellationToken.None - }; - - var postData = new Dictionary - { - {"serverId", ConnectServerId}, - {"supporterKey", _securityManager.SupporterKey} - }; - - options.SetPostData(postData); - - SetServerAccessToken(options); - SetApplicationHeader(options); - - // No need to examine the response - using (var stream = (await _httpClient.SendAsync(options, "POST").ConfigureAwait(false)).Content) - { - return _json.DeserializeFromStream(stream); - } - } - - public async Task AddConnectSupporter(string id) - { - var url = GetConnectUrl("keyAssociation"); - - var options = new HttpRequestOptions - { - Url = url, - CancellationToken = CancellationToken.None - }; - - var postData = new Dictionary - { - {"serverId", ConnectServerId}, - {"supporterKey", _securityManager.SupporterKey}, - {"userId", id} - }; - - options.SetPostData(postData); - - SetServerAccessToken(options); - SetApplicationHeader(options); - - // No need to examine the response - using (var stream = (await _httpClient.SendAsync(options, "POST").ConfigureAwait(false)).Content) - { - } - } - - public async Task RemoveConnectSupporter(string id) - { - var url = GetConnectUrl("keyAssociation"); - - var options = new HttpRequestOptions - { - Url = url, - CancellationToken = CancellationToken.None - }; - - var postData = new Dictionary - { - {"serverId", ConnectServerId}, - {"supporterKey", _securityManager.SupporterKey}, - {"userId", id} - }; - - options.SetPostData(postData); - - SetServerAccessToken(options); - SetApplicationHeader(options); - - // No need to examine the response - using (var stream = (await _httpClient.SendAsync(options, "DELETE").ConfigureAwait(false)).Content) - { - } - } - public async Task Authenticate(string username, string passwordMd5) { if (string.IsNullOrWhiteSpace(username)) @@ -1188,9 +1104,9 @@ namespace MediaBrowser.Server.Implementations.Connect async void _userManager_UserConfigurationUpdated(object sender, GenericEventArgs e) { - var user = e.Argument; + //var user = e.Argument; - await TryUploadUserPreferences(user, CancellationToken.None).ConfigureAwait(false); + //await TryUploadUserPreferences(user, CancellationToken.None).ConfigureAwait(false); } private async Task TryUploadUserPreferences(User user, CancellationToken cancellationToken) -- cgit v1.2.3 From e096a400cd6b5aa4105a008ada82834a5afd7d16 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Fri, 19 Feb 2016 01:20:18 -0500 Subject: update sat discovery --- MediaBrowser.Controller/LiveTv/ITunerHost.cs | 3 + .../LiveTv/LiveTvManager.cs | 6 +- .../LiveTv/TunerHosts/BaseTunerHost.cs | 2 +- .../LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs | 2 +- .../LiveTv/TunerHosts/M3UTunerHost.cs | 81 +--------- .../LiveTv/TunerHosts/M3uParser.cs | 102 ++++++++++++ .../LiveTv/TunerHosts/SatIp/SatIpDiscovery.cs | 168 +++++++++++++++----- .../LiveTv/TunerHosts/SatIp/SatIpHost.cs | 171 +++++++++++++++++---- .../MediaBrowser.Server.Implementations.csproj | 1 + 9 files changed, 385 insertions(+), 151 deletions(-) create mode 100644 MediaBrowser.Server.Implementations/LiveTv/TunerHosts/M3uParser.cs (limited to 'MediaBrowser.Server.Implementations') diff --git a/MediaBrowser.Controller/LiveTv/ITunerHost.cs b/MediaBrowser.Controller/LiveTv/ITunerHost.cs index 2e3a71f70..498602ddf 100644 --- a/MediaBrowser.Controller/LiveTv/ITunerHost.cs +++ b/MediaBrowser.Controller/LiveTv/ITunerHost.cs @@ -46,6 +46,9 @@ namespace MediaBrowser.Controller.LiveTv /// The cancellation token. /// Task<List<MediaSourceInfo>>. Task> GetChannelStreamMediaSources(string channelId, CancellationToken cancellationToken); + } + public interface IConfigurableTunerHost + { /// /// Validates the specified information. /// diff --git a/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs b/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs index 14bfcba27..7c26f5675 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs @@ -2343,7 +2343,11 @@ namespace MediaBrowser.Server.Implementations.LiveTv throw new ResourceNotFoundException(); } - await provider.Validate(info).ConfigureAwait(false); + var configurable = provider as IConfigurableTunerHost; + if (configurable != null) + { + await configurable.Validate(info).ConfigureAwait(false); + } var config = GetConfiguration(); diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/BaseTunerHost.cs b/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/BaseTunerHost.cs index 4ebc173b5..fb27631e5 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/BaseTunerHost.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/BaseTunerHost.cs @@ -64,7 +64,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts return list; } - private List GetTunerHosts() + protected virtual List GetTunerHosts() { return GetConfiguration().TunerHosts .Where(i => i.IsEnabled && string.Equals(i.Type, Type, StringComparison.OrdinalIgnoreCase)) diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs b/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs index 0671a9b56..013dabe26 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs @@ -20,7 +20,7 @@ using MediaBrowser.Model.Dlna; namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.HdHomerun { - public class HdHomerunHost : BaseTunerHost, ITunerHost + public class HdHomerunHost : BaseTunerHost, ITunerHost, IConfigurableTunerHost { private readonly IHttpClient _httpClient; diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/M3UTunerHost.cs b/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/M3UTunerHost.cs index f87d4f43f..17e52fb8e 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/M3UTunerHost.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/M3UTunerHost.cs @@ -8,19 +8,17 @@ using MediaBrowser.Model.Logging; using MediaBrowser.Model.MediaInfo; using System; using System.Collections.Generic; -using System.IO; using System.Linq; using System.Threading; using System.Threading.Tasks; using CommonIO; -using MediaBrowser.Common.IO; using MediaBrowser.Common.Net; using MediaBrowser.Controller.MediaEncoding; using MediaBrowser.Model.Serialization; namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts { - public class M3UTunerHost : BaseTunerHost, ITunerHost + public class M3UTunerHost : BaseTunerHost, ITunerHost, IConfigurableTunerHost { private readonly IFileSystem _fileSystem; private readonly IHttpClient _httpClient; @@ -46,65 +44,12 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts protected override async Task> GetChannelsInternal(TunerHostInfo info, CancellationToken cancellationToken) { - var urlHash = info.Url.GetMD5().ToString("N"); - - // Read the file and display it line by line. - using (var reader = new StreamReader(await GetListingsStream(info, cancellationToken).ConfigureAwait(false))) - { - return GetChannels(reader, urlHash); - } - } - - private List GetChannels(StreamReader reader, string urlHash) - { - var channels = new List(); - - string channnelName = null; - string channelNumber = null; - string line; - - while ((line = reader.ReadLine()) != null) - { - line = line.Trim(); - if (string.IsNullOrWhiteSpace(line)) - { - continue; - } - - if (line.StartsWith("#EXTM3U", StringComparison.OrdinalIgnoreCase)) - { - continue; - } - - if (line.StartsWith("#EXTINF:", StringComparison.OrdinalIgnoreCase)) - { - line = line.Substring(8); - Logger.Info("Found m3u channel: {0}", line); - var parts = line.Split(new[] { ',' }, 2); - channelNumber = parts[0]; - channnelName = parts[1]; - } - else if (!string.IsNullOrWhiteSpace(channelNumber)) - { - channels.Add(new M3UChannel - { - Name = channnelName, - Number = channelNumber, - Id = ChannelIdPrefix + urlHash + line.GetMD5().ToString("N"), - Path = line - }); - - channelNumber = null; - channnelName = null; - } - } - return channels; + return await new M3uParser(Logger, _fileSystem, _httpClient).Parse(info.Url, ChannelIdPrefix, cancellationToken).ConfigureAwait(false); } public Task> GetTunerInfos(CancellationToken cancellationToken) { - var list = GetConfiguration().TunerHosts - .Where(i => i.IsEnabled && string.Equals(i.Type, Type, StringComparison.OrdinalIgnoreCase)) + var list = GetTunerHosts() .Select(i => new LiveTvTunerInfo() { Name = Name, @@ -125,18 +70,9 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts return sources.First(); } - class M3UChannel : ChannelInfo - { - public string Path { get; set; } - - public M3UChannel() - { - } - } - public async Task Validate(TunerHostInfo info) { - using (var stream = await GetListingsStream(info, CancellationToken.None).ConfigureAwait(false)) + using (var stream = await new M3uParser(Logger, _fileSystem, _httpClient).GetListingsStream(info.Url, CancellationToken.None).ConfigureAwait(false)) { } @@ -147,15 +83,6 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts return channelId.StartsWith(ChannelIdPrefix, StringComparison.OrdinalIgnoreCase); } - private Task GetListingsStream(TunerHostInfo info, CancellationToken cancellationToken) - { - if (info.Url.StartsWith("http", StringComparison.OrdinalIgnoreCase)) - { - return _httpClient.Get(info.Url, cancellationToken); - } - return Task.FromResult(_fileSystem.OpenRead(info.Url)); - } - protected override async Task> GetChannelStreamMediaSources(TunerHostInfo info, string channelId, CancellationToken cancellationToken) { var urlHash = info.Url.GetMD5().ToString("N"); diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/M3uParser.cs b/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/M3uParser.cs new file mode 100644 index 000000000..8f5a4a095 --- /dev/null +++ b/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/M3uParser.cs @@ -0,0 +1,102 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Threading; +using System.Threading.Tasks; +using CommonIO; +using MediaBrowser.Common.Extensions; +using MediaBrowser.Common.Net; +using MediaBrowser.Controller.LiveTv; +using MediaBrowser.Model.Logging; + +namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts +{ + public class M3uParser + { + private readonly ILogger _logger; + private readonly IFileSystem _fileSystem; + private readonly IHttpClient _httpClient; + + public M3uParser(ILogger logger, IFileSystem fileSystem, IHttpClient httpClient) + { + _logger = logger; + _fileSystem = fileSystem; + _httpClient = httpClient; + } + + public async Task> Parse(string url, string channelIdPrefix, CancellationToken cancellationToken) + { + var urlHash = url.GetMD5().ToString("N"); + + // Read the file and display it line by line. + using (var reader = new StreamReader(await GetListingsStream(url, cancellationToken).ConfigureAwait(false))) + { + return GetChannels(reader, urlHash, channelIdPrefix); + } + } + + public Task GetListingsStream(string url, CancellationToken cancellationToken) + { + if (url.StartsWith("http", StringComparison.OrdinalIgnoreCase)) + { + return _httpClient.Get(url, cancellationToken); + } + return Task.FromResult(_fileSystem.OpenRead(url)); + } + + private List GetChannels(StreamReader reader, string urlHash, string channelIdPrefix) + { + var channels = new List(); + + string channnelName = null; + string channelNumber = null; + string line; + + while ((line = reader.ReadLine()) != null) + { + line = line.Trim(); + if (string.IsNullOrWhiteSpace(line)) + { + continue; + } + + if (line.StartsWith("#EXTM3U", StringComparison.OrdinalIgnoreCase)) + { + continue; + } + + if (line.StartsWith("#EXTINF:", StringComparison.OrdinalIgnoreCase)) + { + line = line.Substring(8); + _logger.Info("Found m3u channel: {0}", line); + var parts = line.Split(new[] { ',' }, 2); + channelNumber = parts[0]; + channnelName = parts[1]; + } + else if (!string.IsNullOrWhiteSpace(channelNumber)) + { + channels.Add(new M3UChannel + { + Name = channnelName, + Number = channelNumber, + Id = channelIdPrefix + urlHash + line.GetMD5().ToString("N"), + Path = line + }); + + channelNumber = null; + channnelName = null; + } + } + return channels; + } + } + + public class M3UChannel : ChannelInfo + { + public string Path { get; set; } + + public M3UChannel() + { + } + } +} diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/SatIpDiscovery.cs b/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/SatIpDiscovery.cs index 852b86467..233b27c3d 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/SatIpDiscovery.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/SatIpDiscovery.cs @@ -1,10 +1,13 @@ using System; using System.Collections.Generic; +using System.IO; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; +using System.Xml; using MediaBrowser.Common.Configuration; +using MediaBrowser.Common.Extensions; using MediaBrowser.Common.Net; using MediaBrowser.Controller.Configuration; using MediaBrowser.Controller.Dlna; @@ -13,6 +16,7 @@ using MediaBrowser.Controller.Plugins; using MediaBrowser.Model.Extensions; using MediaBrowser.Model.LiveTv; using MediaBrowser.Model.Logging; +using MediaBrowser.Model.Serialization; namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.SatIp { @@ -24,14 +28,26 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.SatIp private readonly ILiveTvManager _liveTvManager; private readonly SemaphoreSlim _semaphore = new SemaphoreSlim(1, 1); private readonly IHttpClient _httpClient; + private readonly IJsonSerializer _json; - public SatIpDiscovery(IDeviceDiscovery deviceDiscovery, IServerConfigurationManager config, ILogger logger, ILiveTvManager liveTvManager, IHttpClient httpClient) + public static SatIpDiscovery Current; + + private readonly List _discoveredHosts = new List(); + + public List DiscoveredHosts + { + get { return _discoveredHosts.ToList(); } + } + + public SatIpDiscovery(IDeviceDiscovery deviceDiscovery, IServerConfigurationManager config, ILogger logger, ILiveTvManager liveTvManager, IHttpClient httpClient, IJsonSerializer json) { _deviceDiscovery = deviceDiscovery; _config = config; _logger = logger; _liveTvManager = liveTvManager; _httpClient = httpClient; + _json = json; + Current = this; } public void Run() @@ -66,26 +82,23 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.SatIp try { - var options = GetConfiguration(); - - //if (options.TunerHosts.Any(i => - // string.Equals(i.Type, SatIpHost.DeviceType, StringComparison.OrdinalIgnoreCase) && - // UriEquals(i.Url, url))) - //{ - // return; - //} - - //// Strip off the port - //url = new Uri(url).GetComponents(UriComponents.AbsoluteUri & ~UriComponents.Port, UriFormat.UriEscaped).TrimEnd('/'); + if (_discoveredHosts.Any(i => string.Equals(i.Type, SatIpHost.DeviceType, StringComparison.OrdinalIgnoreCase) && string.Equals(location, i.Url, StringComparison.OrdinalIgnoreCase))) + { + return; + } - //await TestUrl(url).ConfigureAwait(false); + _logger.Debug("Will attempt to add SAT device {0}", location); + var info = await GetInfo(location, CancellationToken.None).ConfigureAwait(false); - //await _liveTvManager.SaveTunerHost(new TunerHostInfo - //{ - // Type = SatIpHost.DeviceType, - // Url = url + _discoveredHosts.Add(info); + } + catch (OperationCanceledException) + { - //}).ConfigureAwait(false); + } + catch (NotImplementedException) + { + } catch (Exception ex) { @@ -97,43 +110,116 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.SatIp } } - private async Task TestUrl(string url) + public void Dispose() { - // Test it by pulling down the lineup - using (await _httpClient.Get(new HttpRequestOptions + } + + public async Task GetInfo(string url, CancellationToken cancellationToken) + { + var result = new SatIpTunerHostInfo { - Url = string.Format("{0}/lineup.json", url), - CancellationToken = CancellationToken.None - })) + Url = url, + IsEnabled = true, + Type = SatIpHost.DeviceType, + Tuners = 1, + TunersAvailable = 1 + }; + + 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.Id)) { + throw new NotImplementedException(); } - } - private bool UriEquals(string savedUri, string location) - { - return string.Equals(NormalizeUrl(location), NormalizeUrl(savedUri), StringComparison.OrdinalIgnoreCase); - } + if (string.IsNullOrWhiteSpace(result.M3UUrl)) + { + throw new NotImplementedException(); + } - private string NormalizeUrl(string url) - { - if (!url.StartsWith("http", StringComparison.OrdinalIgnoreCase)) + if (!result.M3UUrl.StartsWith("http", StringComparison.OrdinalIgnoreCase)) { - url = "http://" + url; + var fullM3uUrl = url.Substring(0, url.LastIndexOf('/')); + result.M3UUrl = fullM3uUrl + "/" + result.M3UUrl.TrimStart('/'); } - url = url.TrimEnd('/'); + _logger.Debug("SAT device result: {0}", _json.SerializeToString(result)); - // Strip off the port - return new Uri(url).GetComponents(UriComponents.AbsoluteUri & ~UriComponents.Port, UriFormat.UriEscaped); + return result; } - private LiveTvOptions GetConfiguration() + private void FillFromDeviceNode(SatIpTunerHostInfo info, XmlReader reader) { - return _config.GetConfiguration("livetv"); - } + reader.MoveToContent(); - public void Dispose() - { + while (reader.Read()) + { + if (reader.NodeType == XmlNodeType.Element) + { + switch (reader.Name) + { + case "UDN": + { + info.Id = reader.ReadElementContentAsString(); + break; + } + + case "X_SATIPCAP": + { + var value = reader.ReadElementContentAsString(); + // TODO + break; + } + + case "X_SATIPM3U": + { + info.M3UUrl = reader.ReadElementContentAsString(); + break; + } + + default: + reader.Skip(); + break; + } + } + } } } + + public class SatIpTunerHostInfo : TunerHostInfo + { + public int Tuners { get; set; } + public int TunersAvailable { get; set; } + public string M3UUrl { get; set; } + } } diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/SatIpHost.cs b/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/SatIpHost.cs index 205cdf74e..480f0edd0 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/SatIpHost.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/SatIpHost.cs @@ -1,45 +1,156 @@ -namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.SatIp +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; +using CommonIO; +using MediaBrowser.Common.Configuration; +using MediaBrowser.Common.Extensions; +using MediaBrowser.Common.Net; +using MediaBrowser.Controller.LiveTv; +using MediaBrowser.Controller.MediaEncoding; +using MediaBrowser.Model.Dto; +using MediaBrowser.Model.Entities; +using MediaBrowser.Model.LiveTv; +using MediaBrowser.Model.Logging; +using MediaBrowser.Model.MediaInfo; +using MediaBrowser.Model.Serialization; + +namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.SatIp { - public class SatIpHost /*: BaseTunerHost*/ + public class SatIpHost : BaseTunerHost, ITunerHost { - //public SatIpHost(IConfigurationManager config, ILogger logger, IJsonSerializer jsonSerializer, IMediaEncoder mediaEncoder) - // : base(config, logger, jsonSerializer, mediaEncoder) - //{ - //} + private readonly IFileSystem _fileSystem; + private readonly IHttpClient _httpClient; + + public SatIpHost(IConfigurationManager config, ILogger logger, IJsonSerializer jsonSerializer, IMediaEncoder mediaEncoder, IFileSystem fileSystem, IHttpClient httpClient) + : base(config, logger, jsonSerializer, mediaEncoder) + { + _fileSystem = fileSystem; + _httpClient = httpClient; + } + + private const string ChannelIdPrefix = "sat_"; + + protected override async Task> GetChannelsInternal(TunerHostInfo tuner, CancellationToken cancellationToken) + { + var satInfo = (SatIpTunerHostInfo) tuner; - //protected override Task> GetChannelsInternal(TunerHostInfo tuner, CancellationToken cancellationToken) - //{ - // throw new NotImplementedException(); - //} + return await new M3uParser(Logger, _fileSystem, _httpClient).Parse(satInfo.M3UUrl, ChannelIdPrefix, cancellationToken).ConfigureAwait(false); + } public static string DeviceType { get { return "satip"; } } - //public override string Type - //{ - // get { return DeviceType; } - //} + public override string Type + { + get { return DeviceType; } + } + + protected override async Task> GetChannelStreamMediaSources(TunerHostInfo tuner, string channelId, CancellationToken cancellationToken) + { + var urlHash = tuner.Url.GetMD5().ToString("N"); + var prefix = ChannelIdPrefix + urlHash; + if (!channelId.StartsWith(prefix, StringComparison.OrdinalIgnoreCase)) + { + return null; + } + + var channels = await GetChannels(tuner, true, cancellationToken).ConfigureAwait(false); + var m3uchannels = channels.Cast(); + var channel = m3uchannels.FirstOrDefault(c => string.Equals(c.Id, channelId, StringComparison.OrdinalIgnoreCase)); + if (channel != null) + { + var path = channel.Path; + MediaProtocol protocol = MediaProtocol.File; + if (path.StartsWith("http", StringComparison.OrdinalIgnoreCase)) + { + protocol = MediaProtocol.Http; + } + else if (path.StartsWith("rtmp", StringComparison.OrdinalIgnoreCase)) + { + protocol = MediaProtocol.Rtmp; + } + else if (path.StartsWith("rtsp", StringComparison.OrdinalIgnoreCase)) + { + protocol = MediaProtocol.Rtsp; + } + + var mediaSource = new MediaSourceInfo + { + Path = channel.Path, + Protocol = protocol, + MediaStreams = new List + { + new MediaStream + { + Type = MediaStreamType.Video, + // Set the index to -1 because we don't know the exact index of the video stream within the container + Index = -1, + IsInterlaced = true + }, + new MediaStream + { + Type = MediaStreamType.Audio, + // Set the index to -1 because we don't know the exact index of the audio stream within the container + Index = -1 + + } + }, + RequiresOpening = false, + RequiresClosing = false + }; + + return new List { mediaSource }; + } + return new List { }; + } + + protected override async Task GetChannelStream(TunerHostInfo tuner, string channelId, string streamId, CancellationToken cancellationToken) + { + var sources = await GetChannelStreamMediaSources(tuner, channelId, cancellationToken).ConfigureAwait(false); + + return sources.First(); + } + + protected override async Task IsAvailableInternal(TunerHostInfo tuner, string channelId, CancellationToken cancellationToken) + { + var updatedInfo = await SatIpDiscovery.Current.GetInfo(tuner.Url, cancellationToken).ConfigureAwait(false); + + return updatedInfo.TunersAvailable > 0; + } + + protected override bool IsValidChannelId(string channelId) + { + return channelId.StartsWith(ChannelIdPrefix, StringComparison.OrdinalIgnoreCase); + } - //protected override Task> GetChannelStreamMediaSources(TunerHostInfo tuner, string channelId, CancellationToken cancellationToken) - //{ - // throw new NotImplementedException(); - //} + protected override List GetTunerHosts() + { + return SatIpDiscovery.Current.DiscoveredHosts; + } - //protected override Task GetChannelStream(TunerHostInfo tuner, string channelId, string streamId, CancellationToken cancellationToken) - //{ - // throw new NotImplementedException(); - //} + public string Name + { + get { return "Sat IP"; } + } - //protected override Task IsAvailableInternal(TunerHostInfo tuner, string channelId, CancellationToken cancellationToken) - //{ - // throw new NotImplementedException(); - //} + public Task> GetTunerInfos(CancellationToken cancellationToken) + { + var list = GetTunerHosts() + .Select(i => new LiveTvTunerInfo() + { + Name = Name, + SourceType = Type, + Status = LiveTvTunerStatus.Available, + Id = i.Url.GetMD5().ToString("N"), + Url = i.Url + }) + .ToList(); - //protected override bool IsValidChannelId(string channelId) - //{ - // throw new NotImplementedException(); - //} + return Task.FromResult(list); + } } } diff --git a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj index 80592c724..21066a9f4 100644 --- a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj +++ b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj @@ -234,6 +234,7 @@ + -- cgit v1.2.3 From 3c2cb7701f0885bb2209de0fc9eee4dde328750e Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Fri, 19 Feb 2016 01:23:59 -0500 Subject: comments --- .../LiveTv/TunerHosts/SatIp/SatIpDiscovery.cs | 2 ++ 1 file changed, 2 insertions(+) (limited to 'MediaBrowser.Server.Implementations') diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/SatIpDiscovery.cs b/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/SatIpDiscovery.cs index 233b27c3d..2681ec4c4 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/SatIpDiscovery.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/SatIpDiscovery.cs @@ -196,6 +196,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.SatIp case "X_SATIPCAP": { + // DVBS2-2 var value = reader.ReadElementContentAsString(); // TODO break; @@ -203,6 +204,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.SatIp case "X_SATIPM3U": { + // /channellist.lua?select=m3u info.M3UUrl = reader.ReadElementContentAsString(); break; } -- cgit v1.2.3 From d2e62c5ba88ad46c7f6af21a8f338b95ed19381c Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Fri, 19 Feb 2016 12:14:42 -0500 Subject: update satip discovery --- .../Connect/ConnectManager.cs | 61 ---------------------- .../HttpServer/Security/AuthorizationContext.cs | 5 -- .../LiveTv/TunerHosts/SatIp/SatIpDiscovery.cs | 7 ++- 3 files changed, 5 insertions(+), 68 deletions(-) (limited to 'MediaBrowser.Server.Implementations') diff --git a/MediaBrowser.Server.Implementations/Connect/ConnectManager.cs b/MediaBrowser.Server.Implementations/Connect/ConnectManager.cs index cff95b184..d7477225c 100644 --- a/MediaBrowser.Server.Implementations/Connect/ConnectManager.cs +++ b/MediaBrowser.Server.Implementations/Connect/ConnectManager.cs @@ -10,7 +10,6 @@ using MediaBrowser.Controller.Providers; using MediaBrowser.Controller.Security; using MediaBrowser.Model.Connect; using MediaBrowser.Model.Entities; -using MediaBrowser.Model.Events; using MediaBrowser.Model.Logging; using MediaBrowser.Model.Net; using MediaBrowser.Model.Serialization; @@ -24,7 +23,6 @@ using System.Text; using System.Threading; using System.Threading.Tasks; using CommonIO; -using MediaBrowser.Common.IO; namespace MediaBrowser.Server.Implementations.Connect { @@ -121,7 +119,6 @@ namespace MediaBrowser.Server.Implementations.Connect _securityManager = securityManager; _fileSystem = fileSystem; - _userManager.UserConfigurationUpdated += _userManager_UserConfigurationUpdated; _config.ConfigurationUpdated += _config_ConfigurationUpdated; LoadCachedData(); @@ -1102,64 +1099,6 @@ namespace MediaBrowser.Server.Implementations.Connect } } - async void _userManager_UserConfigurationUpdated(object sender, GenericEventArgs e) - { - //var user = e.Argument; - - //await TryUploadUserPreferences(user, CancellationToken.None).ConfigureAwait(false); - } - - private async Task TryUploadUserPreferences(User user, CancellationToken cancellationToken) - { - if (user == null) - { - throw new ArgumentNullException("user"); - } - - if (string.IsNullOrEmpty(user.ConnectUserId)) - { - return; - } - if (string.IsNullOrEmpty(ConnectAccessKey)) - { - return; - } - - var url = GetConnectUrl("user/preferences"); - url += "?userId=" + user.ConnectUserId; - url += "&key=userpreferences"; - - var options = new HttpRequestOptions - { - Url = url, - CancellationToken = cancellationToken - }; - - var postData = new Dictionary(); - postData["data"] = _json.SerializeToString(ConnectUserPreferences.FromUserConfiguration(user.Configuration)); - options.SetPostData(postData); - - SetServerAccessToken(options); - SetApplicationHeader(options); - - try - { - // No need to examine the response - using (var stream = (await _httpClient.SendAsync(options, "POST").ConfigureAwait(false)).Content) - { - } - } - catch (Exception ex) - { - _logger.ErrorException("Error uploading user preferences", ex); - } - } - - private async Task DownloadUserPreferences(User user, CancellationToken cancellationToken) - { - - } - public async Task GetLocalUser(string connectUserId) { var user = _userManager.Users diff --git a/MediaBrowser.Server.Implementations/HttpServer/Security/AuthorizationContext.cs b/MediaBrowser.Server.Implementations/HttpServer/Security/AuthorizationContext.cs index 75d54a80a..357f5c976 100644 --- a/MediaBrowser.Server.Implementations/HttpServer/Security/AuthorizationContext.cs +++ b/MediaBrowser.Server.Implementations/HttpServer/Security/AuthorizationContext.cs @@ -45,7 +45,6 @@ namespace MediaBrowser.Server.Implementations.HttpServer.Security { var auth = GetAuthorizationDictionary(httpReq); - string userId = null; string deviceId = null; string device = null; string client = null; @@ -53,9 +52,6 @@ namespace MediaBrowser.Server.Implementations.HttpServer.Security if (auth != null) { - // TODO: Remove this - auth.TryGetValue("UserId", out userId); - auth.TryGetValue("DeviceId", out deviceId); auth.TryGetValue("Device", out device); auth.TryGetValue("Client", out client); @@ -78,7 +74,6 @@ namespace MediaBrowser.Server.Implementations.HttpServer.Security Client = client, Device = device, DeviceId = deviceId, - UserId = userId, Version = version, Token = token }; diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/SatIpDiscovery.cs b/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/SatIpDiscovery.cs index 2681ec4c4..53f97f76f 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/SatIpDiscovery.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/SatIpDiscovery.cs @@ -162,12 +162,13 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.SatIp throw new NotImplementedException(); } + // Device hasn't implemented an m3u list if (string.IsNullOrWhiteSpace(result.M3UUrl)) { - throw new NotImplementedException(); + result.IsEnabled = false; } - if (!result.M3UUrl.StartsWith("http", StringComparison.OrdinalIgnoreCase)) + else if (!result.M3UUrl.StartsWith("http", StringComparison.OrdinalIgnoreCase)) { var fullM3uUrl = url.Substring(0, url.LastIndexOf('/')); result.M3UUrl = fullM3uUrl + "/" + result.M3UUrl.TrimStart('/'); @@ -194,6 +195,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.SatIp break; } + case "satip:X_SATIPCAP": case "X_SATIPCAP": { // DVBS2-2 @@ -202,6 +204,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.SatIp break; } + case "satip:X_SATIPM3U": case "X_SATIPM3U": { // /channellist.lua?select=m3u -- cgit v1.2.3 From fe0f3e28a0d2ee330cdcbe77c244c59e0ec08e88 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Fri, 19 Feb 2016 13:09:38 -0500 Subject: add audio sync to recordings --- MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EncodedRecorder.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'MediaBrowser.Server.Implementations') diff --git a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EncodedRecorder.cs b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EncodedRecorder.cs index 5f4d32732..38f35f4cc 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EncodedRecorder.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EncodedRecorder.cs @@ -116,7 +116,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV videoArgs = "-codec:v:0 copy"; } - var commandLineArgs = "-fflags +genpts -i \"{0}\" -sn {2} -map_metadata -1 -threads 0 {3} -y \"{1}\""; + var commandLineArgs = "-fflags +genpts -async 1 -vsync -1 -i \"{0}\" -sn {2} -map_metadata -1 -threads 0 {3} -y \"{1}\""; if (mediaSource.ReadAtNativeFramerate) { -- cgit v1.2.3 From 2002b0ef39d59184fd2d30aa4e5f409591ca8671 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Fri, 19 Feb 2016 21:45:12 -0500 Subject: update sat discovery --- .../LiveTv/TunerHosts/SatIp/SatIpDiscovery.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'MediaBrowser.Server.Implementations') diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/SatIpDiscovery.cs b/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/SatIpDiscovery.cs index 53f97f76f..48337b923 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/SatIpDiscovery.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/SatIpDiscovery.cs @@ -187,7 +187,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.SatIp { if (reader.NodeType == XmlNodeType.Element) { - switch (reader.Name) + switch (reader.LocalName) { case "UDN": { -- cgit v1.2.3 From e700aff047816e26666856614b89c2ea4a014907 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sat, 20 Feb 2016 18:06:57 -0500 Subject: remember user audio/subtitle selections --- .../Entities/IHasMediaSources.cs | 2 +- MediaBrowser.Controller/Entities/UserItemData.cs | 12 ++++- .../Dto/DtoService.cs | 2 + .../Library/MediaSourceManager.cs | 60 ++++++++++++++++++---- .../Persistence/SqliteUserDataRepository.cs | 25 +++++++-- .../Session/SessionManager.cs | 14 ++++- .../ApplicationHost.cs | 2 +- 7 files changed, 97 insertions(+), 20 deletions(-) (limited to 'MediaBrowser.Server.Implementations') diff --git a/MediaBrowser.Controller/Entities/IHasMediaSources.cs b/MediaBrowser.Controller/Entities/IHasMediaSources.cs index 85ce3c781..832b9f6c1 100644 --- a/MediaBrowser.Controller/Entities/IHasMediaSources.cs +++ b/MediaBrowser.Controller/Entities/IHasMediaSources.cs @@ -3,7 +3,7 @@ using System.Collections.Generic; namespace MediaBrowser.Controller.Entities { - public interface IHasMediaSources : IHasId + public interface IHasMediaSources : IHasUserData { /// /// Gets the media sources. diff --git a/MediaBrowser.Controller/Entities/UserItemData.cs b/MediaBrowser.Controller/Entities/UserItemData.cs index 5f0e62537..16c37e7d3 100644 --- a/MediaBrowser.Controller/Entities/UserItemData.cs +++ b/MediaBrowser.Controller/Entities/UserItemData.cs @@ -78,7 +78,17 @@ namespace MediaBrowser.Controller.Entities /// /// true if played; otherwise, false. public bool Played { get; set; } - + /// + /// Gets or sets the index of the audio stream. + /// + /// The index of the audio stream. + public int? AudioStreamIndex { get; set; } + /// + /// Gets or sets the index of the subtitle stream. + /// + /// The index of the subtitle stream. + public int? SubtitleStreamIndex { get; set; } + /// /// This is an interpreted property to indicate likes or dislikes /// This should never be serialized. diff --git a/MediaBrowser.Server.Implementations/Dto/DtoService.cs b/MediaBrowser.Server.Implementations/Dto/DtoService.cs index 590c5fd3f..07686e91c 100644 --- a/MediaBrowser.Server.Implementations/Dto/DtoService.cs +++ b/MediaBrowser.Server.Implementations/Dto/DtoService.cs @@ -639,6 +639,8 @@ namespace MediaBrowser.Server.Implementations.Dto private IEnumerable GetCacheTags(BaseItem item, ImageType type, int limit) { return item.GetImages(type) + // Convert to a list now in case GetImageCacheTag is slow + .ToList() .Select(p => GetImageCacheTag(item, p)) .Where(i => i != null) .Take(limit) diff --git a/MediaBrowser.Server.Implementations/Library/MediaSourceManager.cs b/MediaBrowser.Server.Implementations/Library/MediaSourceManager.cs index b132eedec..caddeec0d 100644 --- a/MediaBrowser.Server.Implementations/Library/MediaSourceManager.cs +++ b/MediaBrowser.Server.Implementations/Library/MediaSourceManager.cs @@ -30,8 +30,9 @@ namespace MediaBrowser.Server.Implementations.Library private IMediaSourceProvider[] _providers; private readonly ILogger _logger; + private readonly IUserDataManager _userDataManager; - public MediaSourceManager(IItemRepository itemRepo, IUserManager userManager, ILibraryManager libraryManager, ILogger logger, IJsonSerializer jsonSerializer, IFileSystem fileSystem) + public MediaSourceManager(IItemRepository itemRepo, IUserManager userManager, ILibraryManager libraryManager, ILogger logger, IJsonSerializer jsonSerializer, IFileSystem fileSystem, IUserDataManager userDataManager) { _itemRepo = itemRepo; _userManager = userManager; @@ -39,6 +40,7 @@ namespace MediaBrowser.Server.Implementations.Library _logger = logger; _jsonSerializer = jsonSerializer; _fileSystem = fileSystem; + _userDataManager = userDataManager; } public void AddParts(IEnumerable providers) @@ -140,7 +142,7 @@ namespace MediaBrowser.Server.Implementations.Library { if (user != null) { - SetUserProperties(source, user); + SetUserProperties(hasMediaSources, source, user); } if (source.Protocol == MediaProtocol.File) { @@ -257,25 +259,38 @@ namespace MediaBrowser.Server.Implementations.Library { foreach (var source in sources) { - SetUserProperties(source, user); + SetUserProperties(item, source, user); } } return sources; } - private void SetUserProperties(MediaSourceInfo source, User user) + private void SetUserProperties(IHasUserData item, MediaSourceInfo source, User user) { - var preferredAudio = string.IsNullOrEmpty(user.Configuration.AudioLanguagePreference) - ? new string[] { } - : new[] { user.Configuration.AudioLanguagePreference }; + var userData = item == null ? new UserItemData() : _userDataManager.GetUserData(user.Id, item.GetUserDataKey()); + + SetDefaultAudioStreamIndex(source, userData, user); + SetDefaultSubtitleStreamIndex(source, userData, user); + } + private void SetDefaultSubtitleStreamIndex(MediaSourceInfo source, UserItemData userData, User user) + { + if (userData.SubtitleStreamIndex.HasValue) + { + var index = userData.SubtitleStreamIndex.Value; + // Make sure the saved index is still valid + if (index == -1 || source.MediaStreams.Any(i => i.Type == MediaStreamType.Subtitle && i.Index == index)) + { + source.DefaultSubtitleStreamIndex = index; + return; + } + } + var preferredSubs = string.IsNullOrEmpty(user.Configuration.SubtitleLanguagePreference) ? new List { } : new List { user.Configuration.SubtitleLanguagePreference }; - source.DefaultAudioStreamIndex = MediaStreamSelector.GetDefaultAudioStreamIndex(source.MediaStreams, preferredAudio, user.Configuration.PlayDefaultAudioTrack); - var defaultAudioIndex = source.DefaultAudioStreamIndex; var audioLangage = defaultAudioIndex == null ? null @@ -290,6 +305,26 @@ namespace MediaBrowser.Server.Implementations.Library user.Configuration.SubtitleMode, audioLangage); } + private void SetDefaultAudioStreamIndex(MediaSourceInfo source, UserItemData userData, User user) + { + if (userData.AudioStreamIndex.HasValue) + { + var index = userData.AudioStreamIndex.Value; + // Make sure the saved index is still valid + if (source.MediaStreams.Any(i => i.Type == MediaStreamType.Audio && i.Index == index)) + { + source.DefaultAudioStreamIndex = index; + return; + } + } + + var preferredAudio = string.IsNullOrEmpty(user.Configuration.AudioLanguagePreference) + ? new string[] { } + : new[] { user.Configuration.AudioLanguagePreference }; + + source.DefaultAudioStreamIndex = MediaStreamSelector.GetDefaultAudioStreamIndex(source.MediaStreams, preferredAudio, user.Configuration.PlayDefaultAudioTrack); + } + private IEnumerable SortMediaSources(IEnumerable sources) { return sources.OrderBy(i => @@ -349,11 +384,14 @@ namespace MediaBrowser.Server.Implementations.Library var json = _jsonSerializer.SerializeToString(mediaSource); _logger.Debug("Live stream opened: " + json); var clone = _jsonSerializer.DeserializeFromString(json); - + if (!string.IsNullOrWhiteSpace(request.UserId)) { var user = _userManager.GetUserById(request.UserId); - SetUserProperties(clone, user); + var item = string.IsNullOrWhiteSpace(request.ItemId) + ? null + : _libraryManager.GetItemById(request.ItemId); + SetUserProperties(item, clone, user); } return new LiveStreamResponse diff --git a/MediaBrowser.Server.Implementations/Persistence/SqliteUserDataRepository.cs b/MediaBrowser.Server.Implementations/Persistence/SqliteUserDataRepository.cs index 8b86d19a2..63c41c71f 100644 --- a/MediaBrowser.Server.Implementations/Persistence/SqliteUserDataRepository.cs +++ b/MediaBrowser.Server.Implementations/Persistence/SqliteUserDataRepository.cs @@ -56,6 +56,9 @@ namespace MediaBrowser.Server.Implementations.Persistence }; _connection.RunQueries(queries, Logger); + + _connection.AddColumn(Logger, "userdata", "AudioStreamIndex", "int"); + _connection.AddColumn(Logger, "userdata", "SubtitleStreamIndex", "int"); } /// @@ -127,7 +130,7 @@ namespace MediaBrowser.Server.Implementations.Persistence using (var cmd = _connection.CreateCommand()) { - cmd.CommandText = "replace into userdata (key, userId, rating,played,playCount,isFavorite,playbackPositionTicks,lastPlayedDate) values (@key, @userId, @rating,@played,@playCount,@isFavorite,@playbackPositionTicks,@lastPlayedDate)"; + cmd.CommandText = "replace into userdata (key, userId, rating,played,playCount,isFavorite,playbackPositionTicks,lastPlayedDate,AudioStreamIndex,SubtitleStreamIndex) values (@key, @userId, @rating,@played,@playCount,@isFavorite,@playbackPositionTicks,@lastPlayedDate,@AudioStreamIndex,@SubtitleStreamIndex)"; cmd.Parameters.Add(cmd, "@key", DbType.String).Value = key; cmd.Parameters.Add(cmd, "@userId", DbType.Guid).Value = userId; @@ -137,6 +140,8 @@ namespace MediaBrowser.Server.Implementations.Persistence cmd.Parameters.Add(cmd, "@isFavorite", DbType.Boolean).Value = userData.IsFavorite; cmd.Parameters.Add(cmd, "@playbackPositionTicks", DbType.Int64).Value = userData.PlaybackPositionTicks; cmd.Parameters.Add(cmd, "@lastPlayedDate", DbType.DateTime).Value = userData.LastPlayedDate; + cmd.Parameters.Add(cmd, "@AudioStreamIndex", DbType.Int32).Value = userData.AudioStreamIndex; + cmd.Parameters.Add(cmd, "@SubtitleStreamIndex", DbType.Int32).Value = userData.SubtitleStreamIndex; cmd.Transaction = transaction; @@ -199,7 +204,7 @@ namespace MediaBrowser.Server.Implementations.Persistence { using (var cmd = _connection.CreateCommand()) { - cmd.CommandText = "replace into userdata (key, userId, rating,played,playCount,isFavorite,playbackPositionTicks,lastPlayedDate) values (@key, @userId, @rating,@played,@playCount,@isFavorite,@playbackPositionTicks,@lastPlayedDate)"; + cmd.CommandText = "replace into userdata (key, userId, rating,played,playCount,isFavorite,playbackPositionTicks,lastPlayedDate,AudioStreamIndex,SubtitleStreamIndex) values (@key, @userId, @rating,@played,@playCount,@isFavorite,@playbackPositionTicks,@lastPlayedDate,@AudioStreamIndex,@SubtitleStreamIndex)"; cmd.Parameters.Add(cmd, "@key", DbType.String).Value = userItemData.Key; cmd.Parameters.Add(cmd, "@userId", DbType.Guid).Value = userId; @@ -209,6 +214,8 @@ namespace MediaBrowser.Server.Implementations.Persistence cmd.Parameters.Add(cmd, "@isFavorite", DbType.Boolean).Value = userItemData.IsFavorite; cmd.Parameters.Add(cmd, "@playbackPositionTicks", DbType.Int64).Value = userItemData.PlaybackPositionTicks; cmd.Parameters.Add(cmd, "@lastPlayedDate", DbType.DateTime).Value = userItemData.LastPlayedDate; + cmd.Parameters.Add(cmd, "@AudioStreamIndex", DbType.Int32).Value = userItemData.AudioStreamIndex; + cmd.Parameters.Add(cmd, "@SubtitleStreamIndex", DbType.Int32).Value = userItemData.SubtitleStreamIndex; cmd.Transaction = transaction; @@ -275,7 +282,7 @@ namespace MediaBrowser.Server.Implementations.Persistence using (var cmd = _connection.CreateCommand()) { - cmd.CommandText = "select key,userid,rating,played,playCount,isFavorite,playbackPositionTicks,lastPlayedDate from userdata where key = @key and userId=@userId"; + cmd.CommandText = "select key,userid,rating,played,playCount,isFavorite,playbackPositionTicks,lastPlayedDate,AudioStreamIndex,SubtitleStreamIndex from userdata where key = @key and userId=@userId"; cmd.Parameters.Add(cmd, "@key", DbType.String).Value = key; cmd.Parameters.Add(cmd, "@userId", DbType.Guid).Value = userId; @@ -310,7 +317,7 @@ namespace MediaBrowser.Server.Implementations.Persistence using (var cmd = _connection.CreateCommand()) { - cmd.CommandText = "select key,userid,rating,played,playCount,isFavorite,playbackPositionTicks,lastPlayedDate from userdata where userId=@userId"; + cmd.CommandText = "select key,userid,rating,played,playCount,isFavorite,playbackPositionTicks,lastPlayedDate,AudioStreamIndex,SubtitleStreamIndex from userdata where userId=@userId"; cmd.Parameters.Add(cmd, "@userId", DbType.Guid).Value = userId; @@ -350,6 +357,16 @@ namespace MediaBrowser.Server.Implementations.Persistence userData.LastPlayedDate = reader.GetDateTime(7).ToUniversalTime(); } + if (!reader.IsDBNull(8)) + { + userData.AudioStreamIndex = reader.GetInt32(8); + } + + if (!reader.IsDBNull(9)) + { + userData.SubtitleStreamIndex = reader.GetInt32(9); + } + return userData; } diff --git a/MediaBrowser.Server.Implementations/Session/SessionManager.cs b/MediaBrowser.Server.Implementations/Session/SessionManager.cs index a9ce5ba54..7e2f41ef9 100644 --- a/MediaBrowser.Server.Implementations/Session/SessionManager.cs +++ b/MediaBrowser.Server.Implementations/Session/SessionManager.cs @@ -680,7 +680,7 @@ namespace MediaBrowser.Server.Implementations.Session foreach (var user in users) { - await OnPlaybackProgress(user.Id, key, libraryItem, info.PositionTicks).ConfigureAwait(false); + await OnPlaybackProgress(user.Id, key, libraryItem, info).ConfigureAwait(false); } } @@ -712,18 +712,28 @@ namespace MediaBrowser.Server.Implementations.Session StartIdleCheckTimer(); } - private async Task OnPlaybackProgress(Guid userId, string userDataKey, BaseItem item, long? positionTicks) + private async Task OnPlaybackProgress(Guid userId, string userDataKey, BaseItem item, PlaybackProgressInfo info) { var data = _userDataRepository.GetUserData(userId, userDataKey); + var positionTicks = info.PositionTicks; + if (positionTicks.HasValue) { _userDataRepository.UpdatePlayState(item, data, positionTicks.Value); + UpdatePlaybackSettings(info, data); + await _userDataRepository.SaveUserData(userId, item, data, UserDataSaveReason.PlaybackProgress, CancellationToken.None).ConfigureAwait(false); } } + private void UpdatePlaybackSettings(PlaybackProgressInfo info, UserItemData data) + { + data.AudioStreamIndex = info.AudioStreamIndex; + data.SubtitleStreamIndex = info.SubtitleStreamIndex; + } + /// /// Used to report that playback has ended for an item /// diff --git a/MediaBrowser.Server.Startup.Common/ApplicationHost.cs b/MediaBrowser.Server.Startup.Common/ApplicationHost.cs index e61a64646..a54380850 100644 --- a/MediaBrowser.Server.Startup.Common/ApplicationHost.cs +++ b/MediaBrowser.Server.Startup.Common/ApplicationHost.cs @@ -490,7 +490,7 @@ namespace MediaBrowser.Server.Startup.Common ChannelManager = new ChannelManager(UserManager, DtoService, LibraryManager, LogManager.GetLogger("ChannelManager"), ServerConfigurationManager, FileSystemManager, UserDataManager, JsonSerializer, LocalizationManager, HttpClient, ProviderManager); RegisterSingleInstance(ChannelManager); - MediaSourceManager = new MediaSourceManager(ItemRepository, UserManager, LibraryManager, LogManager.GetLogger("MediaSourceManager"), JsonSerializer, FileSystemManager); + MediaSourceManager = new MediaSourceManager(ItemRepository, UserManager, LibraryManager, LogManager.GetLogger("MediaSourceManager"), JsonSerializer, FileSystemManager, UserDataManager); RegisterSingleInstance(MediaSourceManager); SessionManager = new SessionManager(UserDataManager, LogManager.GetLogger("SessionManager"), UserRepository, LibraryManager, UserManager, musicManager, DtoService, ImageProcessor, JsonSerializer, this, HttpClient, AuthenticationRepository, DeviceManager, MediaSourceManager); -- cgit v1.2.3 From ad8b43cc3d04ce17139976ec91a45f4a2004a0c3 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sun, 21 Feb 2016 01:25:25 -0500 Subject: update local pin feature --- MediaBrowser.Api/PinLoginService.cs | 85 ++++++++++++++++------ MediaBrowser.Api/UserService.cs | 17 ----- MediaBrowser.Controller/Session/ISessionManager.cs | 7 ++ .../HttpServer/HttpListenerHost.cs | 6 ++ .../LiveTv/EmbyTV/EncodedRecorder.cs | 2 +- .../Session/SessionManager.cs | 28 +++++-- .../MediaBrowser.WebDashboard.csproj | 6 ++ 7 files changed, 104 insertions(+), 47 deletions(-) (limited to 'MediaBrowser.Server.Implementations') diff --git a/MediaBrowser.Api/PinLoginService.cs b/MediaBrowser.Api/PinLoginService.cs index 8b63de10a..a4957651f 100644 --- a/MediaBrowser.Api/PinLoginService.cs +++ b/MediaBrowser.Api/PinLoginService.cs @@ -1,9 +1,14 @@ using System; using System.Collections.Concurrent; using System.Globalization; +using System.Threading.Tasks; using MediaBrowser.Common.Extensions; +using MediaBrowser.Controller.Library; using MediaBrowser.Controller.Net; +using MediaBrowser.Controller.Session; using MediaBrowser.Model.Connect; +using MediaBrowser.Model.Dto; +using MediaBrowser.Model.Session; using ServiceStack; namespace MediaBrowser.Api @@ -13,6 +18,8 @@ namespace MediaBrowser.Api { [ApiMember(Name = "DeviceId", IsRequired = true, DataType = "string", ParameterType = "query", Verb = "POST")] public string DeviceId { get; set; } + [ApiMember(Name = "AppName", IsRequired = true, DataType = "string", ParameterType = "query", Verb = "POST")] + public string AppName { get; set; } } [Route("/Auth/Pin", "GET", Summary = "Gets pin status")] @@ -35,7 +42,7 @@ namespace MediaBrowser.Api [Route("/Auth/Pin/Validate", "POST", Summary = "Validates a pin")] [Authenticated] - public class ValidatePinRequest : IReturnVoid + public class ValidatePinRequest : IReturn { [ApiMember(Name = "Pin", IsRequired = true, DataType = "string", ParameterType = "query", Verb = "POST")] public string Pin { get; set; } @@ -43,10 +50,27 @@ namespace MediaBrowser.Api public class PinLoginService : BaseApiService { - private readonly ConcurrentDictionary _activeRequests = new ConcurrentDictionary(StringComparer.OrdinalIgnoreCase); + private static readonly ConcurrentDictionary _activeRequests = new ConcurrentDictionary(StringComparer.OrdinalIgnoreCase); + private readonly ISessionManager _sessionManager; + private readonly IUserManager _userManager; + + public PinLoginService(ISessionManager sessionManager, IUserManager userManager) + { + _sessionManager = sessionManager; + _userManager = userManager; + } public object Post(CreatePinRequest request) { + if (string.IsNullOrWhiteSpace(request.DeviceId)) + { + throw new ArgumentNullException("DeviceId"); + } + if (string.IsNullOrWhiteSpace(request.AppName)) + { + throw new ArgumentNullException("AppName"); + } + var pin = GetNewPin(); var value = new MyPinStatus @@ -55,7 +79,8 @@ namespace MediaBrowser.Api IsConfirmed = false, IsExpired = false, Pin = pin, - DeviceId = request.DeviceId + DeviceId = request.DeviceId, + AppName = request.AppName }; _activeRequests.AddOrUpdate(pin, value, (k, v) => value); @@ -75,6 +100,7 @@ namespace MediaBrowser.Api if (!_activeRequests.TryGetValue(request.Pin, out status)) { + Logger.Debug("Pin {0} not found.", request.Pin); throw new ResourceNotFoundException(); } @@ -88,12 +114,13 @@ namespace MediaBrowser.Api }); } - public object Post(ExchangePinRequest request) + public async Task Post(ExchangePinRequest request) { MyPinStatus status; if (!_activeRequests.TryGetValue(request.Pin, out status)) { + Logger.Debug("Pin {0} not found.", request.Pin); throw new ResourceNotFoundException(); } @@ -104,14 +131,24 @@ namespace MediaBrowser.Api throw new ResourceNotFoundException(); } - return ToOptimizedResult(new PinExchangeResult + var auth = AuthorizationContext.GetAuthorizationInfo(Request); + var user = _userManager.GetUserById(status.UserId); + + var result = await _sessionManager.CreateNewSession(new AuthenticationRequest { - // TODO: Add access token - UserId = status.UserId - }); + App = auth.Client, + AppVersion = auth.Version, + DeviceId = auth.DeviceId, + DeviceName = auth.Device, + RemoteEndPoint = Request.RemoteIp, + Username = user.Name + + }).ConfigureAwait(false); + + return ToOptimizedResult(result); } - public void Post(ValidatePinRequest request) + public object Post(ValidatePinRequest request) { MyPinStatus status; @@ -124,12 +161,18 @@ namespace MediaBrowser.Api status.IsConfirmed = true; status.UserId = AuthorizationContext.GetAuthorizationInfo(Request).UserId; + + return ToOptimizedResult(new ValidatePinResult + { + AppName = status.AppName + }); } private void EnsureValid(string requestedDeviceId, MyPinStatus status) { if (!string.Equals(requestedDeviceId, status.DeviceId, StringComparison.OrdinalIgnoreCase)) { + Logger.Debug("Pin device Id's do not match. requestedDeviceId: {0}, status.DeviceId: {1}", requestedDeviceId, status.DeviceId); throw new ResourceNotFoundException(); } @@ -145,6 +188,7 @@ namespace MediaBrowser.Api if (status.IsExpired) { + Logger.Debug("Pin {0} is expired", status.Pin); throw new ResourceNotFoundException(); } } @@ -163,16 +207,7 @@ namespace MediaBrowser.Api private string GetNewPinInternal() { - var length = 5; - var pin = string.Empty; - - while (pin.Length < length) - { - var digit = new Random().Next(0, 9); - pin += digit.ToString(CultureInfo.InvariantCulture); - } - - return pin; + return new Random().Next(10000, 99999).ToString(CultureInfo.InvariantCulture); } private bool IsPinActive(string pin) @@ -181,15 +216,15 @@ namespace MediaBrowser.Api if (!_activeRequests.TryGetValue(pin, out status)) { - return true; + return false; } if (status.IsExpired) { - return true; + return false; } - return false; + return true; } public class MyPinStatus : PinStatusResult @@ -197,6 +232,12 @@ namespace MediaBrowser.Api public DateTime CreationTimeUtc { get; set; } public string DeviceId { get; set; } public string UserId { get; set; } + public string AppName { get; set; } } } + + public class ValidatePinResult + { + public string AppName { get; set; } + } } diff --git a/MediaBrowser.Api/UserService.cs b/MediaBrowser.Api/UserService.cs index 3996a0311..a35a1c3a2 100644 --- a/MediaBrowser.Api/UserService.cs +++ b/MediaBrowser.Api/UserService.cs @@ -415,23 +415,6 @@ namespace MediaBrowser.Api { var auth = AuthorizationContext.GetAuthorizationInfo(Request); - if (string.IsNullOrWhiteSpace(auth.Client)) - { - auth.Client = "Unknown app"; - } - if (string.IsNullOrWhiteSpace(auth.Device)) - { - auth.Device = "Unknown device"; - } - if (string.IsNullOrWhiteSpace(auth.Version)) - { - auth.Version = "Unknown version"; - } - if (string.IsNullOrWhiteSpace(auth.DeviceId)) - { - auth.DeviceId = "Unknown device id"; - } - var result = await _sessionMananger.AuthenticateNewSession(new AuthenticationRequest { App = auth.Client, diff --git a/MediaBrowser.Controller/Session/ISessionManager.cs b/MediaBrowser.Controller/Session/ISessionManager.cs index dc9612c84..fa74c5749 100644 --- a/MediaBrowser.Controller/Session/ISessionManager.cs +++ b/MediaBrowser.Controller/Session/ISessionManager.cs @@ -250,6 +250,13 @@ namespace MediaBrowser.Controller.Session /// Task{SessionInfo}. Task AuthenticateNewSession(AuthenticationRequest request); + /// + /// Creates the new session. + /// + /// The request. + /// Task<AuthenticationResult>. + Task CreateNewSession(AuthenticationRequest request); + /// /// Reports the capabilities. /// diff --git a/MediaBrowser.Server.Implementations/HttpServer/HttpListenerHost.cs b/MediaBrowser.Server.Implementations/HttpServer/HttpListenerHost.cs index e69ff367a..c284007f7 100644 --- a/MediaBrowser.Server.Implementations/HttpServer/HttpListenerHost.cs +++ b/MediaBrowser.Server.Implementations/HttpServer/HttpListenerHost.cs @@ -348,6 +348,12 @@ namespace MediaBrowser.Server.Implementations.HttpServer return Task.FromResult(true); } + if (string.Equals(localPath, "/emby/pin", StringComparison.OrdinalIgnoreCase)) + { + httpRes.RedirectToUrl("web/pin.html"); + return Task.FromResult(true); + } + if (!string.IsNullOrWhiteSpace(GlobalResponse)) { httpRes.StatusCode = 503; diff --git a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EncodedRecorder.cs b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EncodedRecorder.cs index 38f35f4cc..ac5cda95e 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EncodedRecorder.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EncodedRecorder.cs @@ -143,7 +143,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV { audioChannels = audioStream.Channels ?? audioChannels; } - return "-codec:a:0 aac -strict experimental -ab 320000 -ac " + audioChannels.ToString(CultureInfo.InvariantCulture); + return "-codec:a:0 aac -strict experimental -ab 320000"; } private bool EncodeVideo(MediaSourceInfo mediaSource) diff --git a/MediaBrowser.Server.Implementations/Session/SessionManager.cs b/MediaBrowser.Server.Implementations/Session/SessionManager.cs index 7e2f41ef9..70f60f31a 100644 --- a/MediaBrowser.Server.Implementations/Session/SessionManager.cs +++ b/MediaBrowser.Server.Implementations/Session/SessionManager.cs @@ -1278,7 +1278,17 @@ namespace MediaBrowser.Server.Implementations.Session /// /// The request. /// Task{SessionInfo}. - public async Task AuthenticateNewSession(AuthenticationRequest request) + public Task AuthenticateNewSession(AuthenticationRequest request) + { + return AuthenticateNewSessionInternal(request, true); + } + + public Task CreateNewSession(AuthenticationRequest request) + { + return AuthenticateNewSessionInternal(request, false); + } + + private async Task AuthenticateNewSessionInternal(AuthenticationRequest request, bool enforcePassword) { var user = _userManager.Users .FirstOrDefault(i => string.Equals(request.Username, i.Name, StringComparison.OrdinalIgnoreCase)); @@ -1291,13 +1301,16 @@ namespace MediaBrowser.Server.Implementations.Session } } - var result = await _userManager.AuthenticateUser(request.Username, request.PasswordSha1, request.PasswordMd5, request.RemoteEndPoint).ConfigureAwait(false); - - if (!result) + if (enforcePassword) { - EventHelper.FireEventIfNotNull(AuthenticationFailed, this, new GenericEventArgs(request), _logger); + var result = await _userManager.AuthenticateUser(request.Username, request.PasswordSha1, request.PasswordMd5, request.RemoteEndPoint).ConfigureAwait(false); + + if (!result) + { + EventHelper.FireEventIfNotNull(AuthenticationFailed, this, new GenericEventArgs(request), _logger); - throw new SecurityException("Invalid user or password entered."); + throw new SecurityException("Invalid user or password entered."); + } } var token = await GetAuthorizationToken(user.Id.ToString("N"), request.DeviceId, request.App, request.AppVersion, request.DeviceName).ConfigureAwait(false); @@ -1320,7 +1333,8 @@ namespace MediaBrowser.Server.Implementations.Session ServerId = _appHost.SystemId }; } - + + private async Task GetAuthorizationToken(string userId, string deviceId, string app, string appVersion, string deviceName) { var existing = _authRepo.Get(new AuthenticationInfoQuery diff --git a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj index d4d8be7f1..832944aad 100644 --- a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj +++ b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj @@ -275,6 +275,9 @@ PreserveNewest + + PreserveNewest + PreserveNewest @@ -317,6 +320,9 @@ PreserveNewest + + PreserveNewest + PreserveNewest -- cgit v1.2.3 From fd3c6f7eccec2c10cdbadedc979042949b58f9a7 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sun, 21 Feb 2016 12:22:13 -0500 Subject: support additional m3u fields --- .../LiveTv/TunerHosts/M3uParser.cs | 31 +++++++++++++++------- 1 file changed, 22 insertions(+), 9 deletions(-) (limited to 'MediaBrowser.Server.Implementations') diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/M3uParser.cs b/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/M3uParser.cs index 8f5a4a095..9ec5809a9 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/M3uParser.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/M3uParser.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.IO; +using System.Text.RegularExpressions; using System.Threading; using System.Threading.Tasks; using CommonIO; @@ -51,7 +52,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts string channnelName = null; string channelNumber = null; string line; - + string imageUrl = null; while ((line = reader.ReadLine()) != null) { line = line.Trim(); @@ -70,8 +71,9 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts line = line.Substring(8); _logger.Info("Found m3u channel: {0}", line); var parts = line.Split(new[] { ',' }, 2); - channelNumber = parts[0]; - channnelName = parts[1]; + channelNumber = parts[0].Trim().Split(' ')[0] ?? "0"; + channnelName = FindProperty("tvg-name", line, parts[1]); + imageUrl = FindProperty("tvg-logo", line, null); } else if (!string.IsNullOrWhiteSpace(channelNumber)) { @@ -80,23 +82,34 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts Name = channnelName, Number = channelNumber, Id = channelIdPrefix + urlHash + line.GetMD5().ToString("N"), - Path = line + ImageUrl = imageUrl }); + imageUrl = null; channelNumber = null; channnelName = null; } } return channels; } + public string FindProperty(string property, string properties, string defaultResult = "") + { + var reg = new Regex(@"([a-z0-9\-_]+)=\""([^""]+)\""", RegexOptions.IgnoreCase); + var matches = reg.Matches(properties); + foreach (Match match in matches) + { + if (match.Groups[1].Value == property) + { + return match.Groups[2].Value; + } + } + return defaultResult; + } } + public class M3UChannel : ChannelInfo { public string Path { get; set; } - - public M3UChannel() - { - } } -} +} \ No newline at end of file -- cgit v1.2.3 From 119c4f143570958aae94f14adca1104a72dfb7ca Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sun, 21 Feb 2016 12:22:31 -0500 Subject: fix official rating description --- MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs | 8 +++++++- .../LiveTv/LiveTvManager.cs | 14 ++++++++++++-- .../Persistence/SqliteItemRepository.cs | 2 +- .../Sync/SyncJobProcessor.cs | 21 +++++++++++++++++++-- 4 files changed, 39 insertions(+), 6 deletions(-) (limited to 'MediaBrowser.Server.Implementations') diff --git a/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs b/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs index ced36f3aa..8d1b4057b 100644 --- a/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs +++ b/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs @@ -934,7 +934,13 @@ namespace MediaBrowser.MediaEncoding.Encoder _mediaEncoder._runningProcesses.Remove(this); } - process.Dispose(); + try + { + process.Dispose(); + } + catch (Exception ex) + { + } } private bool _disposed; diff --git a/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs b/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs index 7c26f5675..cd21dc21a 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs @@ -801,11 +801,21 @@ namespace MediaBrowser.Server.Implementations.LiveTv { if (!string.IsNullOrWhiteSpace(info.ImagePath)) { - item.SetImagePath(ImageType.Primary, info.ImagePath); + item.SetImage(new ItemImageInfo + { + Path = info.ImagePath, + Type = ImageType.Primary, + IsPlaceholder = true + }, 0); } else if (!string.IsNullOrWhiteSpace(info.ImageUrl)) { - item.SetImagePath(ImageType.Primary, info.ImageUrl); + item.SetImage(new ItemImageInfo + { + Path = info.ImageUrl, + Type = ImageType.Primary, + IsPlaceholder = true + }, 0); } } diff --git a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs index a85872951..697ec2271 100644 --- a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs +++ b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs @@ -1014,7 +1014,7 @@ namespace MediaBrowser.Server.Implementations.Persistence if (!reader.IsDBNull(31)) { - item.OfficialRating = reader.GetString(31); + item.OfficialRatingDescription = reader.GetString(31); } if (!reader.IsDBNull(32)) diff --git a/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs b/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs index 95934908d..39779ecf2 100644 --- a/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs +++ b/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs @@ -19,6 +19,7 @@ using MediaBrowser.Model.Sync; using MoreLinq; using System; using System.Collections.Generic; +using System.Globalization; using System.IO; using System.Linq; using System.Threading; @@ -125,7 +126,23 @@ namespace MediaBrowser.Server.Implementations.Sync private string GetSyncJobItemName(BaseItem item) { - return item.Name; + var name = item.Name; + var episode = item as Episode; + + if (episode != null) + { + if (episode.IndexNumber.HasValue) + { + name = "E" + episode.IndexNumber.Value.ToString(CultureInfo.InvariantCulture) + " - " + name; + } + + if (episode.ParentIndexNumber.HasValue) + { + name = "S" + episode.ParentIndexNumber.Value.ToString(CultureInfo.InvariantCulture) + ", " + name; + } + } + + return name; } public Task UpdateJobStatus(string id) @@ -699,7 +716,7 @@ namespace MediaBrowser.Server.Implementations.Sync var path = Path.Combine(temporaryPath, filename); - _fileSystem.CreateDirectory(Path.GetDirectoryName(path)); + _fileSystem.CreateDirectory(Path.GetDirectoryName(path)); using (var stream = await _subtitleEncoder.GetSubtitles(streamInfo.ItemId, streamInfo.MediaSourceId, subtitleStreamIndex, subtitleStreamInfo.Format, 0, null, cancellationToken).ConfigureAwait(false)) { -- cgit v1.2.3 From e22a1a7857b88285a129e7ab7bb03b4256a3d5db Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sun, 21 Feb 2016 12:37:57 -0500 Subject: grab more sat fields --- MediaBrowser.Controller/LiveTv/LiveTvTunerInfo.cs | 6 +++++ MediaBrowser.Model/LiveTv/LiveTvTunerInfoDto.cs | 6 +++++ .../LiveTv/LiveTvDtoService.cs | 3 ++- .../LiveTv/TunerHosts/SatIp/SatIpDiscovery.cs | 27 ++++++++++++++++--- .../LiveTv/TunerHosts/SatIp/SatIpHost.cs | 31 ++++++++++++++++------ 5 files changed, 61 insertions(+), 12 deletions(-) (limited to 'MediaBrowser.Server.Implementations') diff --git a/MediaBrowser.Controller/LiveTv/LiveTvTunerInfo.cs b/MediaBrowser.Controller/LiveTv/LiveTvTunerInfo.cs index 46cf4dd98..2b1e2f21d 100644 --- a/MediaBrowser.Controller/LiveTv/LiveTvTunerInfo.cs +++ b/MediaBrowser.Controller/LiveTv/LiveTvTunerInfo.cs @@ -59,6 +59,12 @@ namespace MediaBrowser.Controller.LiveTv /// The clients. public List Clients { get; set; } + /// + /// Gets or sets a value indicating whether this instance can reset. + /// + /// true if this instance can reset; otherwise, false. + public bool CanReset { get; set; } + public LiveTvTunerInfo() { Clients = new List(); diff --git a/MediaBrowser.Model/LiveTv/LiveTvTunerInfoDto.cs b/MediaBrowser.Model/LiveTv/LiveTvTunerInfoDto.cs index fcb19427b..9af96df43 100644 --- a/MediaBrowser.Model/LiveTv/LiveTvTunerInfoDto.cs +++ b/MediaBrowser.Model/LiveTv/LiveTvTunerInfoDto.cs @@ -64,6 +64,12 @@ namespace MediaBrowser.Model.LiveTv /// The clients. public List Clients { get; set; } + /// + /// Gets or sets a value indicating whether this instance can reset. + /// + /// true if this instance can reset; otherwise, false. + public bool CanReset { get; set; } + public LiveTvTunerInfoDto() { Clients = new List(); diff --git a/MediaBrowser.Server.Implementations/LiveTv/LiveTvDtoService.cs b/MediaBrowser.Server.Implementations/LiveTv/LiveTvDtoService.cs index 04f99cdce..81ad6a387 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/LiveTvDtoService.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/LiveTvDtoService.cs @@ -178,7 +178,8 @@ namespace MediaBrowser.Server.Implementations.LiveTv SourceType = info.SourceType, Status = info.Status, ChannelName = channelName, - Url = info.Url + Url = info.Url, + CanReset = info.CanReset }; if (!string.IsNullOrEmpty(info.ChannelId)) diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/SatIpDiscovery.cs b/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/SatIpDiscovery.cs index 48337b923..6781e498a 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/SatIpDiscovery.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/SatIpDiscovery.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Globalization; using System.IO; using System.Linq; using System.Text; @@ -98,7 +99,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.SatIp } catch (NotImplementedException) { - + } catch (Exception ex) { @@ -195,12 +196,31 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.SatIp break; } + case "friendlyName": + { + info.FriendlyName = reader.ReadElementContentAsString(); + break; + } + case "satip:X_SATIPCAP": case "X_SATIPCAP": { // DVBS2-2 - var value = reader.ReadElementContentAsString(); - // TODO + 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; } @@ -226,5 +246,6 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.SatIp public int Tuners { get; set; } public int TunersAvailable { get; set; } public string M3UUrl { get; set; } + public string FriendlyName { get; set; } } } diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/SatIpHost.cs b/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/SatIpHost.cs index 480f0edd0..976041bcc 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/SatIpHost.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/SatIpHost.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Globalization; using System.Linq; using System.Threading; using System.Threading.Tasks; @@ -140,17 +141,31 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.SatIp public Task> GetTunerInfos(CancellationToken cancellationToken) { var list = GetTunerHosts() - .Select(i => new LiveTvTunerInfo() - { - Name = Name, - SourceType = Type, - Status = LiveTvTunerStatus.Available, - Id = i.Url.GetMD5().ToString("N"), - Url = i.Url - }) + .SelectMany(i => GetTunerInfos(i, cancellationToken)) .ToList(); return Task.FromResult(list); } + + public List GetTunerInfos(TunerHostInfo info, CancellationToken cancellationToken) + { + var satInfo = (SatIpTunerHostInfo) info; + + var list = new List(); + + for (var i = 0; i < satInfo.Tuners; i++) + { + list.Add(new LiveTvTunerInfo + { + Name = satInfo.FriendlyName ?? Name, + SourceType = Type, + Status = LiveTvTunerStatus.Available, + Id = info.Url.GetMD5().ToString("N") + i.ToString(CultureInfo.InvariantCulture), + Url = info.Url + }); + } + + return list; + } } } -- cgit v1.2.3 From 299ac388b3c6ef0c66c36b13e30ea9c16d394aff Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sun, 21 Feb 2016 16:15:36 -0500 Subject: stub out config setting to remember tracks --- .../Configuration/UserConfiguration.cs | 6 +++++ .../Library/MediaSourceManager.cs | 4 +-- .../Session/SessionManager.cs | 31 ++++++++++++++++------ 3 files changed, 31 insertions(+), 10 deletions(-) (limited to 'MediaBrowser.Server.Implementations') diff --git a/MediaBrowser.Model/Configuration/UserConfiguration.cs b/MediaBrowser.Model/Configuration/UserConfiguration.cs index d59974a2e..57d9e0f1b 100644 --- a/MediaBrowser.Model/Configuration/UserConfiguration.cs +++ b/MediaBrowser.Model/Configuration/UserConfiguration.cs @@ -48,11 +48,17 @@ namespace MediaBrowser.Model.Configuration public bool HidePlayedInLatest { get; set; } public bool DisplayChannelsInline { get; set; } + public bool RememberAudioSelections { get; set; } + public bool RememberSubtitleSelections { get; set; } + /// /// Initializes a new instance of the class. /// public UserConfiguration() { + RememberAudioSelections = true; + RememberSubtitleSelections = true; + HidePlayedInLatest = true; PlayDefaultAudioTrack = true; diff --git a/MediaBrowser.Server.Implementations/Library/MediaSourceManager.cs b/MediaBrowser.Server.Implementations/Library/MediaSourceManager.cs index caddeec0d..e4a085f42 100644 --- a/MediaBrowser.Server.Implementations/Library/MediaSourceManager.cs +++ b/MediaBrowser.Server.Implementations/Library/MediaSourceManager.cs @@ -276,7 +276,7 @@ namespace MediaBrowser.Server.Implementations.Library private void SetDefaultSubtitleStreamIndex(MediaSourceInfo source, UserItemData userData, User user) { - if (userData.SubtitleStreamIndex.HasValue) + if (userData.SubtitleStreamIndex.HasValue && user.Configuration.RememberSubtitleSelections) { var index = userData.SubtitleStreamIndex.Value; // Make sure the saved index is still valid @@ -307,7 +307,7 @@ namespace MediaBrowser.Server.Implementations.Library private void SetDefaultAudioStreamIndex(MediaSourceInfo source, UserItemData userData, User user) { - if (userData.AudioStreamIndex.HasValue) + if (userData.AudioStreamIndex.HasValue && user.Configuration.RememberAudioSelections) { var index = userData.AudioStreamIndex.Value; // Make sure the saved index is still valid diff --git a/MediaBrowser.Server.Implementations/Session/SessionManager.cs b/MediaBrowser.Server.Implementations/Session/SessionManager.cs index 70f60f31a..1074796c0 100644 --- a/MediaBrowser.Server.Implementations/Session/SessionManager.cs +++ b/MediaBrowser.Server.Implementations/Session/SessionManager.cs @@ -680,7 +680,7 @@ namespace MediaBrowser.Server.Implementations.Session foreach (var user in users) { - await OnPlaybackProgress(user.Id, key, libraryItem, info).ConfigureAwait(false); + await OnPlaybackProgress(user, key, libraryItem, info).ConfigureAwait(false); } } @@ -712,9 +712,9 @@ namespace MediaBrowser.Server.Implementations.Session StartIdleCheckTimer(); } - private async Task OnPlaybackProgress(Guid userId, string userDataKey, BaseItem item, PlaybackProgressInfo info) + private async Task OnPlaybackProgress(User user, string userDataKey, BaseItem item, PlaybackProgressInfo info) { - var data = _userDataRepository.GetUserData(userId, userDataKey); + var data = _userDataRepository.GetUserData(user.Id, userDataKey); var positionTicks = info.PositionTicks; @@ -722,16 +722,31 @@ namespace MediaBrowser.Server.Implementations.Session { _userDataRepository.UpdatePlayState(item, data, positionTicks.Value); - UpdatePlaybackSettings(info, data); + UpdatePlaybackSettings(user, info, data); - await _userDataRepository.SaveUserData(userId, item, data, UserDataSaveReason.PlaybackProgress, CancellationToken.None).ConfigureAwait(false); + await _userDataRepository.SaveUserData(user.Id, item, data, UserDataSaveReason.PlaybackProgress, CancellationToken.None).ConfigureAwait(false); } } - private void UpdatePlaybackSettings(PlaybackProgressInfo info, UserItemData data) + private void UpdatePlaybackSettings(User user, PlaybackProgressInfo info, UserItemData data) { - data.AudioStreamIndex = info.AudioStreamIndex; - data.SubtitleStreamIndex = info.SubtitleStreamIndex; + if (user.Configuration.RememberAudioSelections) + { + data.AudioStreamIndex = info.AudioStreamIndex; + } + else + { + data.AudioStreamIndex = null; + } + + if (user.Configuration.RememberSubtitleSelections) + { + data.SubtitleStreamIndex = info.SubtitleStreamIndex; + } + else + { + data.SubtitleStreamIndex = null; + } } /// -- cgit v1.2.3 From c3361458adfd9fcdbf1431de52826f05feaf1d11 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sun, 21 Feb 2016 17:31:50 -0500 Subject: remove defaulting of new series --- .../FileOrganization/EpisodeFileOrganizer.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'MediaBrowser.Server.Implementations') diff --git a/MediaBrowser.Server.Implementations/FileOrganization/EpisodeFileOrganizer.cs b/MediaBrowser.Server.Implementations/FileOrganization/EpisodeFileOrganizer.cs index 9d43dabcd..51642cf5d 100644 --- a/MediaBrowser.Server.Implementations/FileOrganization/EpisodeFileOrganizer.cs +++ b/MediaBrowser.Server.Implementations/FileOrganization/EpisodeFileOrganizer.cs @@ -502,7 +502,7 @@ namespace MediaBrowser.Server.Implementations.FileOrganization } } - return series ?? new Series(); + return series; } /// -- cgit v1.2.3 From 0e6f4e510ebb668d836dbc579f4f7094996dfe08 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Mon, 22 Feb 2016 11:00:17 -0500 Subject: update action sheet --- MediaBrowser.Model/Configuration/UserConfiguration.cs | 4 +++- MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs | 4 ++++ 2 files changed, 7 insertions(+), 1 deletion(-) (limited to 'MediaBrowser.Server.Implementations') diff --git a/MediaBrowser.Model/Configuration/UserConfiguration.cs b/MediaBrowser.Model/Configuration/UserConfiguration.cs index 57d9e0f1b..c2f21ed73 100644 --- a/MediaBrowser.Model/Configuration/UserConfiguration.cs +++ b/MediaBrowser.Model/Configuration/UserConfiguration.cs @@ -50,12 +50,14 @@ namespace MediaBrowser.Model.Configuration public bool RememberAudioSelections { get; set; } public bool RememberSubtitleSelections { get; set; } - + public bool EnableEpisodeAutoQueue { get; set; } + /// /// Initializes a new instance of the class. /// public UserConfiguration() { + EnableEpisodeAutoQueue = true; RememberAudioSelections = true; RememberSubtitleSelections = true; diff --git a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs index 9e4cb66a8..6071fd18b 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs @@ -771,6 +771,8 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV recordPath = Path.ChangeExtension(recordPath, ".mp4"); } + _libraryMonitor.ReportFileSystemChangeBeginning(recordPath); + recording.Path = recordPath; recording.Status = RecordingStatus.InProgress; recording.DateLastUpdated = DateTime.UtcNow; @@ -801,6 +803,8 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV { result.Item2.Release(); } + + _libraryMonitor.ReportFileSystemChangeComplete(recordPath, false); } } catch (OperationCanceledException) -- cgit v1.2.3 From b01780a9b7b55bb4f90984f16c2b841ad805f44e Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Mon, 22 Feb 2016 14:32:35 -0500 Subject: update action sheet --- .../Photos/BaseDynamicImageProvider.cs | 42 +++++++++++++++++++--- 1 file changed, 38 insertions(+), 4 deletions(-) (limited to 'MediaBrowser.Server.Implementations') diff --git a/MediaBrowser.Server.Implementations/Photos/BaseDynamicImageProvider.cs b/MediaBrowser.Server.Implementations/Photos/BaseDynamicImageProvider.cs index c30d35ed2..4a69646f8 100644 --- a/MediaBrowser.Server.Implementations/Photos/BaseDynamicImageProvider.cs +++ b/MediaBrowser.Server.Implementations/Photos/BaseDynamicImageProvider.cs @@ -1,6 +1,5 @@ using MediaBrowser.Common.Configuration; using MediaBrowser.Common.Extensions; -using MediaBrowser.Common.IO; using MediaBrowser.Controller.Drawing; using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Library; @@ -14,6 +13,7 @@ using System.Linq; using System.Threading; using System.Threading.Tasks; using CommonIO; +using MediaBrowser.Model.Configuration; namespace MediaBrowser.Server.Implementations.Photos { @@ -47,6 +47,41 @@ namespace MediaBrowser.Server.Implementations.Photos }; } + private IEnumerable GetEnabledImages(IHasImages item) + { + //var options = ProviderManager.GetMetadataOptions(item); + + return GetSupportedImages(item); + //return GetSupportedImages(item).Where(i => IsEnabled(options, i, item)).ToList(); + } + + private bool IsEnabled(MetadataOptions options, ImageType type, IHasImages item) + { + if (type == ImageType.Backdrop) + { + if (item.LockedFields.Contains(MetadataFields.Backdrops)) + { + return false; + } + } + else if (type == ImageType.Screenshot) + { + if (item.LockedFields.Contains(MetadataFields.Screenshots)) + { + return false; + } + } + else + { + if (item.LockedFields.Contains(MetadataFields.Images)) + { + return false; + } + } + + return options.IsEnabled(type); + } + public async Task FetchAsync(T item, MetadataRefreshOptions options, CancellationToken cancellationToken) { if (!Supports(item)) @@ -55,7 +90,7 @@ namespace MediaBrowser.Server.Implementations.Photos } var updateType = ItemUpdateType.None; - var supportedImages = GetSupportedImages(item).ToList(); + var supportedImages = GetEnabledImages(item).ToList(); if (supportedImages.Contains(ImageType.Primary)) { @@ -69,7 +104,6 @@ namespace MediaBrowser.Server.Implementations.Photos updateType = updateType | thumbResult; } - return updateType; } @@ -220,7 +254,7 @@ namespace MediaBrowser.Server.Implementations.Photos return false; } - var supportedImages = GetSupportedImages(item).ToList(); + var supportedImages = GetEnabledImages(item).ToList(); if (supportedImages.Contains(ImageType.Primary) && HasChanged(item, ImageType.Primary)) { -- cgit v1.2.3 From 05db0cde889c9f42f5b001f314aeb135e26f9284 Mon Sep 17 00:00:00 2001 From: Jose Alacan Date: Mon, 22 Feb 2016 19:48:30 -0500 Subject: Update M3U Parser Update parser to get correct info for SatIp M3U playlist. --- .../LiveTv/TunerHosts/M3uParser.cs | 63 +++++++++++++--------- 1 file changed, 39 insertions(+), 24 deletions(-) (limited to 'MediaBrowser.Server.Implementations') diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/M3uParser.cs b/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/M3uParser.cs index 9ec5809a9..ccca6a7fe 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/M3uParser.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/M3uParser.cs @@ -48,12 +48,9 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts private List GetChannels(StreamReader reader, string urlHash, string channelIdPrefix) { var channels = new List(); - - string channnelName = null; - string channelNumber = null; string line; - string imageUrl = null; - while ((line = reader.ReadLine()) != null) + string extInf = ""; + while ((line = reader.ReadLine()) != null) { line = line.Trim(); if (string.IsNullOrWhiteSpace(line)) @@ -68,30 +65,48 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts if (line.StartsWith("#EXTINF:", StringComparison.OrdinalIgnoreCase)) { - line = line.Substring(8); - _logger.Info("Found m3u channel: {0}", line); - var parts = line.Split(new[] { ',' }, 2); - channelNumber = parts[0].Trim().Split(' ')[0] ?? "0"; - channnelName = FindProperty("tvg-name", line, parts[1]); - imageUrl = FindProperty("tvg-logo", line, null); + extInf = line.Substring(8).Trim(); + _logger.Info("Found m3u channel: {0}", extInf); } - else if (!string.IsNullOrWhiteSpace(channelNumber)) - { - channels.Add(new M3UChannel - { - Name = channnelName, - Number = channelNumber, - Id = channelIdPrefix + urlHash + line.GetMD5().ToString("N"), - ImageUrl = imageUrl - }); - - imageUrl = null; - channelNumber = null; - channnelName = null; + else if (!string.IsNullOrWhiteSpace(extInf)) + { + var channel = GetChannelnfo(extInf); + channel.Id = line; + channels.Add(channel); + extInf = ""; } } return channels; } + public M3UChannel GetChannelnfo(string extInf) + { + var titleIndex = extInf.LastIndexOf(','); + var channel = new M3UChannel(); + + channel.Number = extInf.Trim().Split(' ')[0] ?? "0"; + channel.Name = extInf.Substring(titleIndex + 1); + + if(channel.Number == "-1") { channel.Number = "0"; } + + //Check for channel number with the format from SatIp + int number; + var numberIndex = channel.Name.IndexOf('.'); + if (numberIndex > 0) + { + if (int.TryParse(channel.Name.Substring(0, numberIndex), out number)) + { + channel.Number = number.ToString(); + channel.Name = channel.Name.Substring(numberIndex + 1); + } + } + channel.ImageUrl = FindProperty("tvg-logo", extInf, null); + channel.Number = FindProperty("tvg-id", extInf, channel.Number); + channel.Number = FindProperty("channel-id", extInf, channel.Number); + channel.Name = FindProperty("tvg-name", extInf, channel.Name); + channel.Name = FindProperty("tvg-id", extInf, channel.Name); + return channel; + + } public string FindProperty(string property, string properties, string defaultResult = "") { var reg = new Regex(@"([a-z0-9\-_]+)=\""([^""]+)\""", RegexOptions.IgnoreCase); -- cgit v1.2.3 From caaa10e2d6d01cc5d086e1848e17ec8022ad6fd5 Mon Sep 17 00:00:00 2001 From: Jose Alacan Date: Mon, 22 Feb 2016 20:09:08 -0500 Subject: Make to work with current channel id values --- MediaBrowser.Server.Implementations/LiveTv/TunerHosts/M3uParser.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'MediaBrowser.Server.Implementations') diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/M3uParser.cs b/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/M3uParser.cs index ccca6a7fe..51c35caf4 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/M3uParser.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/M3uParser.cs @@ -71,7 +71,8 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts else if (!string.IsNullOrWhiteSpace(extInf)) { var channel = GetChannelnfo(extInf); - channel.Id = line; + channel.Id = channelIdPrefix + urlHash + line.GetMD5().ToString("N"); + channel.Path = line; channels.Add(channel); extInf = ""; } -- cgit v1.2.3 From 7393570c4baee987963c1baa9e785a36183e9855 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Tue, 23 Feb 2016 11:25:17 -0500 Subject: add error handling to library changed notifier --- MediaBrowser.Providers/People/MovieDbPersonProvider.cs | 2 +- .../EntryPoints/LibraryChangedNotifier.cs | 14 ++++++++++++-- 2 files changed, 13 insertions(+), 3 deletions(-) (limited to 'MediaBrowser.Server.Implementations') diff --git a/MediaBrowser.Providers/People/MovieDbPersonProvider.cs b/MediaBrowser.Providers/People/MovieDbPersonProvider.cs index 5525b547f..43302dd89 100644 --- a/MediaBrowser.Providers/People/MovieDbPersonProvider.cs +++ b/MediaBrowser.Providers/People/MovieDbPersonProvider.cs @@ -99,7 +99,7 @@ namespace MediaBrowser.Providers.People var requestCount = _requestCount; - if (requestCount >= 10) + if (requestCount >= 20) { //_logger.Debug("Throttling Tmdb people"); diff --git a/MediaBrowser.Server.Implementations/EntryPoints/LibraryChangedNotifier.cs b/MediaBrowser.Server.Implementations/EntryPoints/LibraryChangedNotifier.cs index 51a104241..703096a2b 100644 --- a/MediaBrowser.Server.Implementations/EntryPoints/LibraryChangedNotifier.cs +++ b/MediaBrowser.Server.Implementations/EntryPoints/LibraryChangedNotifier.cs @@ -213,8 +213,18 @@ namespace MediaBrowser.Server.Implementations.EntryPoints if (userSessions.Count > 0) { - var info = GetLibraryUpdateInfo(itemsAdded, itemsUpdated, itemsRemoved, foldersAddedTo, - foldersRemovedFrom, id); + LibraryUpdateInfo info; + + try + { + info = GetLibraryUpdateInfo(itemsAdded, itemsUpdated, itemsRemoved, foldersAddedTo, + foldersRemovedFrom, id); + } + catch (Exception ex) + { + _logger.ErrorException("Error in GetLibraryUpdateInfo", ex); + return; + } foreach (var userSession in userSessions) { -- cgit v1.2.3 From 82457e602c6307dd05a3b0781c3c05dddedc1857 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Tue, 23 Feb 2016 12:53:13 -0500 Subject: update people --- .../Library/Validators/PeopleValidator.cs | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) (limited to 'MediaBrowser.Server.Implementations') diff --git a/MediaBrowser.Server.Implementations/Library/Validators/PeopleValidator.cs b/MediaBrowser.Server.Implementations/Library/Validators/PeopleValidator.cs index 2161c1454..adb5d6d44 100644 --- a/MediaBrowser.Server.Implementations/Library/Validators/PeopleValidator.cs +++ b/MediaBrowser.Server.Implementations/Library/Validators/PeopleValidator.cs @@ -125,10 +125,21 @@ namespace MediaBrowser.Server.Implementations.Library.Validators validIds.Add(item.Id); + var hasMetdata = !string.IsNullOrWhiteSpace(item.Overview); + var performFullRefresh = !hasMetdata && (DateTime.UtcNow - item.DateLastRefreshed).TotalDays >= 7; + + var defaultMetadataRefreshMode = performFullRefresh + ? MetadataRefreshMode.FullRefresh + : MetadataRefreshMode.Default; + + var imageRefreshMode = performFullRefresh + ? ImageRefreshMode.FullRefresh + : ImageRefreshMode.Default; + var options = new MetadataRefreshOptions(_fileSystem) { - MetadataRefreshMode = person.Value ? MetadataRefreshMode.Default : MetadataRefreshMode.ValidationOnly, - ImageRefreshMode = person.Value ? ImageRefreshMode.Default : ImageRefreshMode.ValidationOnly + MetadataRefreshMode = person.Value ? defaultMetadataRefreshMode : MetadataRefreshMode.ValidationOnly, + ImageRefreshMode = person.Value ? imageRefreshMode : ImageRefreshMode.ValidationOnly }; await item.RefreshMetadata(options, cancellationToken).ConfigureAwait(false); -- cgit v1.2.3 From 2817f52a5d475cf6035ec68e0a6bb41f94ee13a1 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Tue, 23 Feb 2016 13:48:26 -0500 Subject: add text track label --- .../Library/Validators/PeopleValidator.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'MediaBrowser.Server.Implementations') diff --git a/MediaBrowser.Server.Implementations/Library/Validators/PeopleValidator.cs b/MediaBrowser.Server.Implementations/Library/Validators/PeopleValidator.cs index adb5d6d44..884e1e322 100644 --- a/MediaBrowser.Server.Implementations/Library/Validators/PeopleValidator.cs +++ b/MediaBrowser.Server.Implementations/Library/Validators/PeopleValidator.cs @@ -126,7 +126,7 @@ namespace MediaBrowser.Server.Implementations.Library.Validators validIds.Add(item.Id); var hasMetdata = !string.IsNullOrWhiteSpace(item.Overview); - var performFullRefresh = !hasMetdata && (DateTime.UtcNow - item.DateLastRefreshed).TotalDays >= 7; + var performFullRefresh = !hasMetdata && (DateTime.UtcNow - item.DateLastRefreshed).TotalDays >= 30; var defaultMetadataRefreshMode = performFullRefresh ? MetadataRefreshMode.FullRefresh -- cgit v1.2.3 From ae8060d4aded662197f25d4312f18d0534edb15a Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Tue, 23 Feb 2016 13:50:22 -0500 Subject: update auto-organize --- .../FileOrganization/EpisodeFileOrganizer.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'MediaBrowser.Server.Implementations') diff --git a/MediaBrowser.Server.Implementations/FileOrganization/EpisodeFileOrganizer.cs b/MediaBrowser.Server.Implementations/FileOrganization/EpisodeFileOrganizer.cs index 51642cf5d..2d3c203a2 100644 --- a/MediaBrowser.Server.Implementations/FileOrganization/EpisodeFileOrganizer.cs +++ b/MediaBrowser.Server.Implementations/FileOrganization/EpisodeFileOrganizer.cs @@ -135,7 +135,7 @@ namespace MediaBrowser.Server.Implementations.FileOrganization if (previousResult != null) { // Don't keep saving the same result over and over if nothing has changed - if (previousResult.Status == result.Status && result.Status != FileSortingStatus.Success) + if (previousResult.Status == result.Status && previousResult.StatusMessage == result.StatusMessage && result.Status != FileSortingStatus.Success) { return previousResult; } -- cgit v1.2.3 From f5df8253aef6ca4a32d2efa56064219beed0df6c Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Wed, 24 Feb 2016 00:36:58 -0500 Subject: update locking --- .../Networking/BaseNetworkManager.cs | 24 +++++++++------------ .../ScheduledTasks/ScheduledTaskWorker.cs | 25 +++++++--------------- .../LiveTv/EmbyTV/ItemDataProvider.cs | 13 +++++------ 3 files changed, 23 insertions(+), 39 deletions(-) (limited to 'MediaBrowser.Server.Implementations') diff --git a/MediaBrowser.Common.Implementations/Networking/BaseNetworkManager.cs b/MediaBrowser.Common.Implementations/Networking/BaseNetworkManager.cs index ff11c889a..1b5e260d7 100644 --- a/MediaBrowser.Common.Implementations/Networking/BaseNetworkManager.cs +++ b/MediaBrowser.Common.Implementations/Networking/BaseNetworkManager.cs @@ -20,7 +20,7 @@ namespace MediaBrowser.Common.Implementations.Networking Logger = logger; } - private volatile List _localIpAddresses; + private List _localIpAddresses; private readonly object _localIpAddressSyncLock = new object(); /// @@ -29,24 +29,20 @@ namespace MediaBrowser.Common.Implementations.Networking /// IPAddress. public IEnumerable GetLocalIpAddresses() { - const int cacheMinutes = 3; - var forceRefresh = (DateTime.UtcNow - _lastRefresh).TotalMinutes >= cacheMinutes; + const int cacheMinutes = 5; - if (_localIpAddresses == null || forceRefresh) + lock (_localIpAddressSyncLock) { - lock (_localIpAddressSyncLock) - { - forceRefresh = (DateTime.UtcNow - _lastRefresh).TotalMinutes >= cacheMinutes; + var forceRefresh = (DateTime.UtcNow - _lastRefresh).TotalMinutes >= cacheMinutes; - if (_localIpAddresses == null || forceRefresh) - { - var addresses = GetLocalIpAddressesInternal().ToList(); + if (_localIpAddresses == null || forceRefresh) + { + var addresses = GetLocalIpAddressesInternal().ToList(); - _localIpAddresses = addresses; - _lastRefresh = DateTime.UtcNow; + _localIpAddresses = addresses; + _lastRefresh = DateTime.UtcNow; - return addresses; - } + return addresses; } } diff --git a/MediaBrowser.Common.Implementations/ScheduledTasks/ScheduledTaskWorker.cs b/MediaBrowser.Common.Implementations/ScheduledTasks/ScheduledTaskWorker.cs index a4ccbb6f8..8d727a112 100644 --- a/MediaBrowser.Common.Implementations/ScheduledTasks/ScheduledTaskWorker.cs +++ b/MediaBrowser.Common.Implementations/ScheduledTasks/ScheduledTaskWorker.cs @@ -103,7 +103,7 @@ namespace MediaBrowser.Common.Implementations.ScheduledTasks Logger = logger; _fileSystem = fileSystem; - ReloadTriggerEvents(true); + InitTriggerEvents(); } /// @@ -233,11 +233,7 @@ namespace MediaBrowser.Common.Implementations.ScheduledTasks /// /// The _triggers /// - private volatile List _triggers; - /// - /// The _triggers sync lock - /// - private readonly object _triggersSyncLock = new object(); + private List _triggers; /// /// Gets the triggers that define when the task will run /// @@ -247,17 +243,6 @@ namespace MediaBrowser.Common.Implementations.ScheduledTasks { get { - if (_triggers == null) - { - lock (_triggersSyncLock) - { - if (_triggers == null) - { - _triggers = LoadTriggers(); - } - } - } - return _triggers; } set @@ -303,6 +288,12 @@ namespace MediaBrowser.Common.Implementations.ScheduledTasks } } + private void InitTriggerEvents() + { + _triggers = LoadTriggers(); + ReloadTriggerEvents(true); + } + public void ReloadTriggerEvents() { ReloadTriggerEvents(false); diff --git a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/ItemDataProvider.cs b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/ItemDataProvider.cs index b29a7562c..68b3f1f71 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/ItemDataProvider.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/ItemDataProvider.cs @@ -13,7 +13,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV where T : class { private readonly object _fileDataLock = new object(); - private volatile List _items; + private List _items; private readonly IJsonSerializer _jsonSerializer; protected readonly ILogger Logger; private readonly string _dataPath; @@ -31,17 +31,14 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV public IReadOnlyList GetAll() { - if (_items == null) + lock (_fileDataLock) { - lock (_fileDataLock) + if (_items == null) { - if (_items == null) - { - _items = GetItemsFromFile(_dataPath); - } + _items = GetItemsFromFile(_dataPath); } + return _items; } - return _items; } private List GetItemsFromFile(string path) -- cgit v1.2.3 From 1b4dbe88948f9b7103bbdd51427c4a93b102037e Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Wed, 24 Feb 2016 13:45:11 -0500 Subject: update channel ids --- MediaBrowser.Model/LiveTv/LiveTvOptions.cs | 2 -- .../LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs | 26 +++++++++++++--------- 2 files changed, 16 insertions(+), 12 deletions(-) (limited to 'MediaBrowser.Server.Implementations') diff --git a/MediaBrowser.Model/LiveTv/LiveTvOptions.cs b/MediaBrowser.Model/LiveTv/LiveTvOptions.cs index 50c41fd21..095fa95e1 100644 --- a/MediaBrowser.Model/LiveTv/LiveTvOptions.cs +++ b/MediaBrowser.Model/LiveTv/LiveTvOptions.cs @@ -31,7 +31,6 @@ namespace MediaBrowser.Model.LiveTv public string Type { get; set; } public bool ImportFavoritesOnly { get; set; } public bool IsEnabled { get; set; } - public string GuideGroup { get; set; } public TunerHostInfo() { @@ -49,6 +48,5 @@ namespace MediaBrowser.Model.LiveTv public string ZipCode { get; set; } public string Country { get; set; } public string Path { get; set; } - public string GuideGroup { get; set; } } } \ No newline at end of file diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs b/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs index 013dabe26..ca7d0e119 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs @@ -14,6 +14,7 @@ using System.IO; using System.Linq; using System.Threading; using System.Threading.Tasks; +using MediaBrowser.Common.Extensions; using MediaBrowser.Controller.MediaEncoding; using MediaBrowser.Model.Configuration; using MediaBrowser.Model.Dlna; @@ -64,7 +65,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.HdHomerun { Name = i.GuideName, Number = i.GuideNumber.ToString(CultureInfo.InvariantCulture), - Id = ChannelIdPrefix + i.GuideNumber.ToString(CultureInfo.InvariantCulture), + Id = ChannelIdPrefix + i.GuideNumber.ToString(CultureInfo.InvariantCulture) + '_' + (i.GuideName ?? string.Empty).GetMD5().ToString("N"), IsFavorite = i.Favorite }); @@ -347,6 +348,11 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.HdHomerun return Config.GetConfiguration("encoding"); } + private string GetHdHrIdFromChannelId(string channelId) + { + return channelId.Split('_')[1]; + } + protected override async Task> GetChannelStreamMediaSources(TunerHostInfo info, string channelId, CancellationToken cancellationToken) { var list = new List(); @@ -355,9 +361,9 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.HdHomerun { return list; } - channelId = channelId.Substring(ChannelIdPrefix.Length); + var hdhrId = GetHdHrIdFromChannelId(channelId); - list.Add(GetMediaSource(info, channelId, "native")); + list.Add(GetMediaSource(info, hdhrId, "native")); try { @@ -366,12 +372,12 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.HdHomerun if (model.IndexOf("hdtc", StringComparison.OrdinalIgnoreCase) != -1) { - list.Insert(0, GetMediaSource(info, channelId, "heavy")); + list.Insert(0, GetMediaSource(info, hdhrId, "heavy")); - list.Add(GetMediaSource(info, channelId, "internet480")); - list.Add(GetMediaSource(info, channelId, "internet360")); - list.Add(GetMediaSource(info, channelId, "internet240")); - list.Add(GetMediaSource(info, channelId, "mobile")); + list.Add(GetMediaSource(info, hdhrId, "internet480")); + list.Add(GetMediaSource(info, hdhrId, "internet360")); + list.Add(GetMediaSource(info, hdhrId, "internet240")); + list.Add(GetMediaSource(info, hdhrId, "mobile")); } } catch (Exception ex) @@ -400,9 +406,9 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.HdHomerun { throw new ArgumentException("Channel not found"); } - channelId = channelId.Substring(ChannelIdPrefix.Length); + var hdhrId = GetHdHrIdFromChannelId(channelId); - return GetMediaSource(info, channelId, streamId); + return GetMediaSource(info, hdhrId, streamId); } public async Task Validate(TunerHostInfo info) -- cgit v1.2.3 From 10d4ad98d9fe2e11cc6de78eb0f68307162974fe Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Wed, 24 Feb 2016 13:45:20 -0500 Subject: create notion of locked path --- MediaBrowser.Controller/Library/ILibraryMonitor.cs | 7 +++++++ .../FileOrganization/EpisodeFileOrganizer.cs | 7 +++++++ MediaBrowser.Server.Implementations/IO/LibraryMonitor.cs | 6 ++++++ 3 files changed, 20 insertions(+) (limited to 'MediaBrowser.Server.Implementations') diff --git a/MediaBrowser.Controller/Library/ILibraryMonitor.cs b/MediaBrowser.Controller/Library/ILibraryMonitor.cs index 918382f04..e965e47d6 100644 --- a/MediaBrowser.Controller/Library/ILibraryMonitor.cs +++ b/MediaBrowser.Controller/Library/ILibraryMonitor.cs @@ -32,5 +32,12 @@ namespace MediaBrowser.Controller.Library /// /// The path. void ReportFileSystemChanged(string path); + + /// + /// Determines whether [is path locked] [the specified path]. + /// + /// The path. + /// true if [is path locked] [the specified path]; otherwise, false. + bool IsPathLocked(string path); } } \ No newline at end of file diff --git a/MediaBrowser.Server.Implementations/FileOrganization/EpisodeFileOrganizer.cs b/MediaBrowser.Server.Implementations/FileOrganization/EpisodeFileOrganizer.cs index 2d3c203a2..42f88a5c0 100644 --- a/MediaBrowser.Server.Implementations/FileOrganization/EpisodeFileOrganizer.cs +++ b/MediaBrowser.Server.Implementations/FileOrganization/EpisodeFileOrganizer.cs @@ -64,6 +64,13 @@ namespace MediaBrowser.Server.Implementations.FileOrganization FileSize = new FileInfo(path).Length }; + if (_libraryMonitor.IsPathLocked(path)) + { + result.Status = FileSortingStatus.Failure; + result.StatusMessage = "Path is locked by other processes. Please try again later."; + return result; + } + var namingOptions = ((LibraryManager)_libraryManager).GetNamingOptions(); var resolver = new Naming.TV.EpisodeResolver(namingOptions, new PatternsLogger()); diff --git a/MediaBrowser.Server.Implementations/IO/LibraryMonitor.cs b/MediaBrowser.Server.Implementations/IO/LibraryMonitor.cs index 764eb7c68..25fda3ac1 100644 --- a/MediaBrowser.Server.Implementations/IO/LibraryMonitor.cs +++ b/MediaBrowser.Server.Implementations/IO/LibraryMonitor.cs @@ -78,6 +78,12 @@ namespace MediaBrowser.Server.Implementations.IO TemporarilyIgnore(path); } + public bool IsPathLocked(string path) + { + var lockedPaths = _tempIgnoredPaths.Keys.ToList(); + return lockedPaths.Any(i => string.Equals(i, path, StringComparison.OrdinalIgnoreCase) || _fileSystem.ContainsSubPath(i, path)); + } + public async void ReportFileSystemChangeComplete(string path, bool refreshPath) { if (string.IsNullOrEmpty(path)) -- cgit v1.2.3 From ae859fd56f569217458e438a357f432bb35e9f0c Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Wed, 24 Feb 2016 14:06:26 -0500 Subject: update listing providers --- MediaBrowser.Controller/LiveTv/ChannelInfo.cs | 6 ++++++ MediaBrowser.Model/LiveTv/LiveTvOptions.cs | 11 ++++++++++- .../LiveTv/EmbyTV/EmbyTV.cs | 19 +++++++++++++++++-- .../LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs | 3 ++- .../LiveTv/TunerHosts/M3UTunerHost.cs | 2 +- .../LiveTv/TunerHosts/M3uParser.cs | 15 ++++++++------- .../LiveTv/TunerHosts/SatIp/SatIpHost.cs | 2 +- 7 files changed, 45 insertions(+), 13 deletions(-) (limited to 'MediaBrowser.Server.Implementations') diff --git a/MediaBrowser.Controller/LiveTv/ChannelInfo.cs b/MediaBrowser.Controller/LiveTv/ChannelInfo.cs index 32b8abdc5..7d8df96ed 100644 --- a/MediaBrowser.Controller/LiveTv/ChannelInfo.cs +++ b/MediaBrowser.Controller/LiveTv/ChannelInfo.cs @@ -25,6 +25,12 @@ namespace MediaBrowser.Controller.LiveTv /// The id of the channel. public string Id { get; set; } + /// + /// Gets or sets the tuner host identifier. + /// + /// The tuner host identifier. + public string TunerHostId { get; set; } + /// /// Gets or sets the type of the channel. /// diff --git a/MediaBrowser.Model/LiveTv/LiveTvOptions.cs b/MediaBrowser.Model/LiveTv/LiveTvOptions.cs index 095fa95e1..14bcfe342 100644 --- a/MediaBrowser.Model/LiveTv/LiveTvOptions.cs +++ b/MediaBrowser.Model/LiveTv/LiveTvOptions.cs @@ -15,7 +15,7 @@ namespace MediaBrowser.Model.LiveTv public int PrePaddingSeconds { get; set; } public int PostPaddingSeconds { get; set; } - + public LiveTvOptions() { EnableMovieProviders = true; @@ -48,5 +48,14 @@ namespace MediaBrowser.Model.LiveTv public string ZipCode { get; set; } public string Country { get; set; } public string Path { get; set; } + + public string[] EnabledTuners { get; set; } + public bool EnableAllTuners { get; set; } + + public ListingsProviderInfo() + { + EnabledTuners = new string[] { }; + EnableAllTuners = true; + } } } \ No newline at end of file diff --git a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs index 6071fd18b..29cb1e70d 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs @@ -210,9 +210,13 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV } } - if (list.Count > 0) + foreach (var provider in GetListingProviders()) { - foreach (var provider in GetListingProviders()) + var enabledChannels = list + .Where(i => IsListingProviderEnabledForTuner(provider.Item2, i.TunerHostId)) + .ToList(); + + if (enabledChannels.Count > 0) { try { @@ -228,6 +232,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV } } } + _channelCache = list; return list; } @@ -489,6 +494,11 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV } } + private bool IsListingProviderEnabledForTuner(ListingsProviderInfo info, string tunerHostId) + { + return info.EnableAllTuners || info.EnabledTuners.Contains(tunerHostId ?? string.Empty, StringComparer.OrdinalIgnoreCase); + } + private async Task> GetProgramsAsyncInternal(string channelId, DateTime startDateUtc, DateTime endDateUtc, CancellationToken cancellationToken) { var channels = await GetChannelsAsync(true, cancellationToken).ConfigureAwait(false); @@ -496,6 +506,11 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV foreach (var provider in GetListingProviders()) { + if (!IsListingProviderEnabledForTuner(provider.Item2, channel.TunerHostId)) + { + continue; + } + var programs = await provider.Item1.GetProgramsAsync(provider.Item2, channel.Number, channel.Name, startDateUtc, endDateUtc, cancellationToken) .ConfigureAwait(false); diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs b/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs index ca7d0e119..f59abe1d5 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs @@ -66,7 +66,8 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.HdHomerun Name = i.GuideName, Number = i.GuideNumber.ToString(CultureInfo.InvariantCulture), Id = ChannelIdPrefix + i.GuideNumber.ToString(CultureInfo.InvariantCulture) + '_' + (i.GuideName ?? string.Empty).GetMD5().ToString("N"), - IsFavorite = i.Favorite + IsFavorite = i.Favorite, + TunerHostId = info.Id }); diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/M3UTunerHost.cs b/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/M3UTunerHost.cs index 17e52fb8e..523f14dfc 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/M3UTunerHost.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/M3UTunerHost.cs @@ -44,7 +44,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts protected override async Task> GetChannelsInternal(TunerHostInfo info, CancellationToken cancellationToken) { - return await new M3uParser(Logger, _fileSystem, _httpClient).Parse(info.Url, ChannelIdPrefix, cancellationToken).ConfigureAwait(false); + return await new M3uParser(Logger, _fileSystem, _httpClient).Parse(info.Url, ChannelIdPrefix, info.Id, cancellationToken).ConfigureAwait(false); } public Task> GetTunerInfos(CancellationToken cancellationToken) diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/M3uParser.cs b/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/M3uParser.cs index 51c35caf4..f8f003fa1 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/M3uParser.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/M3uParser.cs @@ -25,14 +25,14 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts _httpClient = httpClient; } - public async Task> Parse(string url, string channelIdPrefix, CancellationToken cancellationToken) + public async Task> Parse(string url, string channelIdPrefix, string tunerHostId, CancellationToken cancellationToken) { var urlHash = url.GetMD5().ToString("N"); // Read the file and display it line by line. using (var reader = new StreamReader(await GetListingsStream(url, cancellationToken).ConfigureAwait(false))) { - return GetChannels(reader, urlHash, channelIdPrefix); + return GetChannels(reader, urlHash, channelIdPrefix, tunerHostId); } } @@ -45,7 +45,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts return Task.FromResult(_fileSystem.OpenRead(url)); } - private List GetChannels(StreamReader reader, string urlHash, string channelIdPrefix) + private List GetChannels(StreamReader reader, string urlHash, string channelIdPrefix, string tunerHostId) { var channels = new List(); string line; @@ -69,8 +69,8 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts _logger.Info("Found m3u channel: {0}", extInf); } else if (!string.IsNullOrWhiteSpace(extInf)) - { - var channel = GetChannelnfo(extInf); + { + var channel = GetChannelnfo(extInf, tunerHostId); channel.Id = channelIdPrefix + urlHash + line.GetMD5().ToString("N"); channel.Path = line; channels.Add(channel); @@ -79,10 +79,11 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts } return channels; } - public M3UChannel GetChannelnfo(string extInf) + private M3UChannel GetChannelnfo(string extInf, string tunerHostId) { var titleIndex = extInf.LastIndexOf(','); var channel = new M3UChannel(); + channel.TunerHostId = tunerHostId; channel.Number = extInf.Trim().Split(' ')[0] ?? "0"; channel.Name = extInf.Substring(titleIndex + 1); @@ -108,7 +109,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts return channel; } - public string FindProperty(string property, string properties, string defaultResult = "") + private string FindProperty(string property, string properties, string defaultResult = "") { var reg = new Regex(@"([a-z0-9\-_]+)=\""([^""]+)\""", RegexOptions.IgnoreCase); var matches = reg.Matches(properties); diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/SatIpHost.cs b/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/SatIpHost.cs index 976041bcc..181169e9a 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/SatIpHost.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/SatIpHost.cs @@ -37,7 +37,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.SatIp { var satInfo = (SatIpTunerHostInfo) tuner; - return await new M3uParser(Logger, _fileSystem, _httpClient).Parse(satInfo.M3UUrl, ChannelIdPrefix, cancellationToken).ConfigureAwait(false); + return await new M3uParser(Logger, _fileSystem, _httpClient).Parse(satInfo.M3UUrl, ChannelIdPrefix, tuner.Id, cancellationToken).ConfigureAwait(false); } public static string DeviceType -- cgit v1.2.3 From cd144bc6f532e6e2981eaca68f28caa4c603a360 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Thu, 25 Feb 2016 10:12:22 -0500 Subject: update photo resolver --- Emby.Drawing/Emby.Drawing.csproj | 2 +- Emby.Drawing/packages.config | 2 +- MediaBrowser.Api/MediaBrowser.Api.csproj | 2 +- MediaBrowser.Api/packages.config | 2 +- .../MediaBrowser.Common.Implementations.csproj | 2 +- .../packages.config | 2 +- .../MediaBrowser.Controller.csproj | 2 +- MediaBrowser.Controller/packages.config | 2 +- MediaBrowser.Dlna/MediaBrowser.Dlna.csproj | 2 +- MediaBrowser.Dlna/packages.config | 2 +- .../MediaBrowser.LocalMetadata.csproj | 2 +- MediaBrowser.LocalMetadata/packages.config | 2 +- .../MediaBrowser.MediaEncoding.csproj | 2 +- MediaBrowser.MediaEncoding/packages.config | 2 +- .../MediaBrowser.Providers.csproj | 2 +- MediaBrowser.Providers/packages.config | 2 +- .../Library/Resolvers/Movies/MovieResolver.cs | 23 ++++++++++++++++++++-- .../MediaBrowser.Server.Implementations.csproj | 2 +- .../packages.config | 2 +- .../MediaBrowser.Server.Mono.csproj | 2 +- MediaBrowser.Server.Mono/packages.config | 2 +- .../MediaBrowser.Server.Startup.Common.csproj | 2 +- MediaBrowser.Server.Startup.Common/packages.config | 2 +- .../MediaBrowser.ServerApplication.csproj | 2 +- MediaBrowser.ServerApplication/packages.config | 2 +- .../MediaBrowser.WebDashboard.csproj | 2 +- MediaBrowser.WebDashboard/packages.config | 2 +- .../MediaBrowser.XbmcMetadata.csproj | 2 +- MediaBrowser.XbmcMetadata/packages.config | 2 +- 29 files changed, 49 insertions(+), 30 deletions(-) (limited to 'MediaBrowser.Server.Implementations') diff --git a/Emby.Drawing/Emby.Drawing.csproj b/Emby.Drawing/Emby.Drawing.csproj index 06e042d74..4ebbbfd0a 100644 --- a/Emby.Drawing/Emby.Drawing.csproj +++ b/Emby.Drawing/Emby.Drawing.csproj @@ -33,7 +33,7 @@ False - ..\packages\CommonIO.1.0.0.7\lib\net45\CommonIO.dll + ..\packages\CommonIO.1.0.0.8\lib\net45\CommonIO.dll False diff --git a/Emby.Drawing/packages.config b/Emby.Drawing/packages.config index 62a241f1f..fab573efc 100644 --- a/Emby.Drawing/packages.config +++ b/Emby.Drawing/packages.config @@ -1,6 +1,6 @@  - + \ No newline at end of file diff --git a/MediaBrowser.Api/MediaBrowser.Api.csproj b/MediaBrowser.Api/MediaBrowser.Api.csproj index 7e55446ae..be79f4d74 100644 --- a/MediaBrowser.Api/MediaBrowser.Api.csproj +++ b/MediaBrowser.Api/MediaBrowser.Api.csproj @@ -47,7 +47,7 @@ False - ..\packages\CommonIO.1.0.0.7\lib\net45\CommonIO.dll + ..\packages\CommonIO.1.0.0.8\lib\net45\CommonIO.dll ..\packages\morelinq.1.4.0\lib\net35\MoreLinq.dll diff --git a/MediaBrowser.Api/packages.config b/MediaBrowser.Api/packages.config index 83890e697..ecb1109ca 100644 --- a/MediaBrowser.Api/packages.config +++ b/MediaBrowser.Api/packages.config @@ -1,6 +1,6 @@  - + \ No newline at end of file diff --git a/MediaBrowser.Common.Implementations/MediaBrowser.Common.Implementations.csproj b/MediaBrowser.Common.Implementations/MediaBrowser.Common.Implementations.csproj index cb3a284c1..4bee8c042 100644 --- a/MediaBrowser.Common.Implementations/MediaBrowser.Common.Implementations.csproj +++ b/MediaBrowser.Common.Implementations/MediaBrowser.Common.Implementations.csproj @@ -49,7 +49,7 @@ False - ..\packages\CommonIO.1.0.0.7\lib\net45\CommonIO.dll + ..\packages\CommonIO.1.0.0.8\lib\net45\CommonIO.dll ..\packages\morelinq.1.4.0\lib\net35\MoreLinq.dll diff --git a/MediaBrowser.Common.Implementations/packages.config b/MediaBrowser.Common.Implementations/packages.config index 14f0f4719..814927228 100644 --- a/MediaBrowser.Common.Implementations/packages.config +++ b/MediaBrowser.Common.Implementations/packages.config @@ -1,6 +1,6 @@  - + diff --git a/MediaBrowser.Controller/MediaBrowser.Controller.csproj b/MediaBrowser.Controller/MediaBrowser.Controller.csproj index 9c17c8d9b..f74d82caa 100644 --- a/MediaBrowser.Controller/MediaBrowser.Controller.csproj +++ b/MediaBrowser.Controller/MediaBrowser.Controller.csproj @@ -46,7 +46,7 @@ False - ..\packages\CommonIO.1.0.0.7\lib\net45\CommonIO.dll + ..\packages\CommonIO.1.0.0.8\lib\net45\CommonIO.dll ..\packages\Interfaces.IO.1.0.0.5\lib\portable-net45+sl4+wp71+win8+wpa81\Interfaces.IO.dll diff --git a/MediaBrowser.Controller/packages.config b/MediaBrowser.Controller/packages.config index 8439bee10..34e16d2ad 100644 --- a/MediaBrowser.Controller/packages.config +++ b/MediaBrowser.Controller/packages.config @@ -1,6 +1,6 @@  - + diff --git a/MediaBrowser.Dlna/MediaBrowser.Dlna.csproj b/MediaBrowser.Dlna/MediaBrowser.Dlna.csproj index 2d672ee87..78dde72c5 100644 --- a/MediaBrowser.Dlna/MediaBrowser.Dlna.csproj +++ b/MediaBrowser.Dlna/MediaBrowser.Dlna.csproj @@ -42,7 +42,7 @@ False - ..\packages\CommonIO.1.0.0.7\lib\net45\CommonIO.dll + ..\packages\CommonIO.1.0.0.8\lib\net45\CommonIO.dll ..\packages\morelinq.1.4.0\lib\net35\MoreLinq.dll diff --git a/MediaBrowser.Dlna/packages.config b/MediaBrowser.Dlna/packages.config index 83890e697..ecb1109ca 100644 --- a/MediaBrowser.Dlna/packages.config +++ b/MediaBrowser.Dlna/packages.config @@ -1,6 +1,6 @@  - + \ No newline at end of file diff --git a/MediaBrowser.LocalMetadata/MediaBrowser.LocalMetadata.csproj b/MediaBrowser.LocalMetadata/MediaBrowser.LocalMetadata.csproj index c673c01df..0ecb1e007 100644 --- a/MediaBrowser.LocalMetadata/MediaBrowser.LocalMetadata.csproj +++ b/MediaBrowser.LocalMetadata/MediaBrowser.LocalMetadata.csproj @@ -33,7 +33,7 @@ False - ..\packages\CommonIO.1.0.0.7\lib\net45\CommonIO.dll + ..\packages\CommonIO.1.0.0.8\lib\net45\CommonIO.dll ..\packages\Patterns.Logging.1.0.0.2\lib\portable-net45+sl4+wp71+win8+wpa81\Patterns.Logging.dll diff --git a/MediaBrowser.LocalMetadata/packages.config b/MediaBrowser.LocalMetadata/packages.config index 28556744d..0639208dd 100644 --- a/MediaBrowser.LocalMetadata/packages.config +++ b/MediaBrowser.LocalMetadata/packages.config @@ -1,5 +1,5 @@  - + \ No newline at end of file diff --git a/MediaBrowser.MediaEncoding/MediaBrowser.MediaEncoding.csproj b/MediaBrowser.MediaEncoding/MediaBrowser.MediaEncoding.csproj index 69f6186c7..89138592a 100644 --- a/MediaBrowser.MediaEncoding/MediaBrowser.MediaEncoding.csproj +++ b/MediaBrowser.MediaEncoding/MediaBrowser.MediaEncoding.csproj @@ -41,7 +41,7 @@ False - ..\packages\CommonIO.1.0.0.7\lib\net45\CommonIO.dll + ..\packages\CommonIO.1.0.0.8\lib\net45\CommonIO.dll ..\packages\MediaBrowser.BdInfo.1.0.0.10\lib\net35\DvdLib.dll diff --git a/MediaBrowser.MediaEncoding/packages.config b/MediaBrowser.MediaEncoding/packages.config index d6a4fc90f..0a8dd0adc 100644 --- a/MediaBrowser.MediaEncoding/packages.config +++ b/MediaBrowser.MediaEncoding/packages.config @@ -1,6 +1,6 @@  - + \ No newline at end of file diff --git a/MediaBrowser.Providers/MediaBrowser.Providers.csproj b/MediaBrowser.Providers/MediaBrowser.Providers.csproj index 24397dd5a..d316d2cd8 100644 --- a/MediaBrowser.Providers/MediaBrowser.Providers.csproj +++ b/MediaBrowser.Providers/MediaBrowser.Providers.csproj @@ -50,7 +50,7 @@ False - ..\packages\CommonIO.1.0.0.7\lib\net45\CommonIO.dll + ..\packages\CommonIO.1.0.0.8\lib\net45\CommonIO.dll False diff --git a/MediaBrowser.Providers/packages.config b/MediaBrowser.Providers/packages.config index 08f8ef3b0..89172044a 100644 --- a/MediaBrowser.Providers/packages.config +++ b/MediaBrowser.Providers/packages.config @@ -1,6 +1,6 @@  - + diff --git a/MediaBrowser.Server.Implementations/Library/Resolvers/Movies/MovieResolver.cs b/MediaBrowser.Server.Implementations/Library/Resolvers/Movies/MovieResolver.cs index 23424bf3c..c73470b51 100644 --- a/MediaBrowser.Server.Implementations/Library/Resolvers/Movies/MovieResolver.cs +++ b/MediaBrowser.Server.Implementations/Library/Resolvers/Movies/MovieResolver.cs @@ -78,7 +78,7 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers.Movies } if (string.Equals(collectionType, CollectionType.HomeVideos, StringComparison.OrdinalIgnoreCase) || - string.Equals(collectionType, CollectionType.Photos, StringComparison.OrdinalIgnoreCase)) + string.Equals(collectionType, CollectionType.Photos, StringComparison.OrdinalIgnoreCase)) { return ResolveVideos /// true if this instance can reset; otherwise, false. public bool CanReset { get; set; } - + public LiveTvTunerInfo() { Clients = new List(); diff --git a/MediaBrowser.Model/LiveTv/LiveTvOptions.cs b/MediaBrowser.Model/LiveTv/LiveTvOptions.cs index 14bcfe342..e705102db 100644 --- a/MediaBrowser.Model/LiveTv/LiveTvOptions.cs +++ b/MediaBrowser.Model/LiveTv/LiveTvOptions.cs @@ -32,6 +32,8 @@ namespace MediaBrowser.Model.LiveTv public bool ImportFavoritesOnly { get; set; } public bool IsEnabled { get; set; } + public int DataVersion { get; set; } + public TunerHostInfo() { IsEnabled = true; diff --git a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs index 29cb1e70d..f0c7a34d9 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs @@ -87,7 +87,6 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV _timerProvider.RestartTimers(); SystemEvents.PowerModeChanged += SystemEvents_PowerModeChanged; - } void SystemEvents_PowerModeChanged(object sender, PowerModeChangedEventArgs e) diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs b/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs index f59abe1d5..35988df9c 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs @@ -48,6 +48,18 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.HdHomerun private const string ChannelIdPrefix = "hdhr_"; + private string GetChannelId(TunerHostInfo info, Channels i) + { + var id = ChannelIdPrefix + i.GuideNumber.ToString(CultureInfo.InvariantCulture); + + if (info.DataVersion >= 1) + { + id += '_' + (i.GuideName ?? string.Empty).GetMD5().ToString("N"); + } + + return id; + } + protected override async Task> GetChannelsInternal(TunerHostInfo info, CancellationToken cancellationToken) { var options = new HttpRequestOptions @@ -65,7 +77,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.HdHomerun { Name = i.GuideName, Number = i.GuideNumber.ToString(CultureInfo.InvariantCulture), - Id = ChannelIdPrefix + i.GuideNumber.ToString(CultureInfo.InvariantCulture) + '_' + (i.GuideName ?? string.Empty).GetMD5().ToString("N"), + Id = GetChannelId(info, i), IsFavorite = i.Favorite, TunerHostId = info.Id -- cgit v1.2.3 From 1661c211528db1241974cb0efaf818d6d07a5d7d Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Thu, 25 Feb 2016 21:41:43 -0500 Subject: handle recordings with null paths --- .../LiveTv/EmbyTV/EmbyTV.cs | 19 +++++++++------- .../TunerHosts/HdHomerun/HdHomerunDiscovery.cs | 3 ++- .../Sync/SyncJobProcessor.cs | 25 ++++++++++++++++++++++ .../Sync/SyncManager.cs | 14 ++++++------ 4 files changed, 45 insertions(+), 16 deletions(-) (limited to 'MediaBrowser.Server.Implementations') diff --git a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs index f0c7a34d9..ba3998262 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs @@ -300,17 +300,20 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV } } - try - { - _fileSystem.DeleteFile(remove.Path); - } - catch (DirectoryNotFoundException) + if (!string.IsNullOrWhiteSpace(remove.Path)) { + try + { + _fileSystem.DeleteFile(remove.Path); + } + catch (DirectoryNotFoundException) + { - } - catch (FileNotFoundException) - { + } + catch (FileNotFoundException) + { + } } _recordingProvider.Delete(remove); } diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunDiscovery.cs b/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunDiscovery.cs index 92a33993a..0a03e60fa 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunDiscovery.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunDiscovery.cs @@ -90,7 +90,8 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.HdHomerun await _liveTvManager.SaveTunerHost(new TunerHostInfo { Type = HdHomerunHost.DeviceType, - Url = url + Url = url, + DataVersion = 1 }).ConfigureAwait(false); } diff --git a/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs b/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs index 39779ecf2..03e654281 100644 --- a/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs +++ b/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs @@ -377,6 +377,9 @@ namespace MediaBrowser.Server.Implementations.Sync { await EnsureSyncJobItems(null, cancellationToken).ConfigureAwait(false); + // Look job items that are supposedly transfering, but need to be requeued because the synced files have been deleted somehow + await HandleDeletedSyncFiles(cancellationToken).ConfigureAwait(false); + // If it already has a converting status then is must have been aborted during conversion var result = _syncManager.GetJobItems(new SyncJobItemQuery { @@ -389,6 +392,28 @@ namespace MediaBrowser.Server.Implementations.Sync CleanDeadSyncFiles(); } + private async Task HandleDeletedSyncFiles(CancellationToken cancellationToken) + { + // Look job items that are supposedly transfering, but need to be requeued because the synced files have been deleted somehow + var result = _syncManager.GetJobItems(new SyncJobItemQuery + { + Statuses = new[] { SyncJobItemStatus.ReadyToTransfer, SyncJobItemStatus.Transferring }, + AddMetadata = false + }); + + foreach (var item in result.Items) + { + cancellationToken.ThrowIfCancellationRequested(); + + if (string.IsNullOrWhiteSpace(item.OutputPath) || !_fileSystem.FileExists(item.OutputPath)) + { + item.Status = SyncJobItemStatus.Queued; + await _syncManager.UpdateSyncJobItemInternal(item).ConfigureAwait(false); + await UpdateJobStatus(item.JobId).ConfigureAwait(false); + } + } + } + private void CleanDeadSyncFiles() { // TODO diff --git a/MediaBrowser.Server.Implementations/Sync/SyncManager.cs b/MediaBrowser.Server.Implementations/Sync/SyncManager.cs index 50a960956..8ebc8d91e 100644 --- a/MediaBrowser.Server.Implementations/Sync/SyncManager.cs +++ b/MediaBrowser.Server.Implementations/Sync/SyncManager.cs @@ -559,6 +559,12 @@ namespace MediaBrowser.Server.Implementations.Sync jobItem.Status = SyncJobItemStatus.Synced; jobItem.Progress = 100; + await UpdateSyncJobItemInternal(jobItem).ConfigureAwait(false); + + var processor = GetSyncJobProcessor(); + + await processor.UpdateJobStatus(jobItem.JobId).ConfigureAwait(false); + if (!string.IsNullOrWhiteSpace(jobItem.TemporaryPath)) { try @@ -573,12 +579,6 @@ namespace MediaBrowser.Server.Implementations.Sync _logger.ErrorException("Error deleting temporary job file: {0}", ex, jobItem.OutputPath); } } - - await UpdateSyncJobItemInternal(jobItem).ConfigureAwait(false); - - var processor = GetSyncJobProcessor(); - - await processor.UpdateJobStatus(jobItem.JobId).ConfigureAwait(false); } private SyncJobProcessor GetSyncJobProcessor() @@ -1015,7 +1015,7 @@ namespace MediaBrowser.Server.Implementations.Sync { var jobItem = _repo.GetJobItem(id); - if (jobItem.Status != SyncJobItemStatus.Queued && jobItem.Status != SyncJobItemStatus.ReadyToTransfer && jobItem.Status != SyncJobItemStatus.Converting && jobItem.Status != SyncJobItemStatus.Failed && jobItem.Status != SyncJobItemStatus.Synced) + if (jobItem.Status != SyncJobItemStatus.Queued && jobItem.Status != SyncJobItemStatus.ReadyToTransfer && jobItem.Status != SyncJobItemStatus.Converting && jobItem.Status != SyncJobItemStatus.Failed && jobItem.Status != SyncJobItemStatus.Synced && jobItem.Status != SyncJobItemStatus.Transferring) { throw new ArgumentException("Operation is not valid for this job item"); } -- cgit v1.2.3 From 2c3113ced75cfb95ccb11745069402b69eb16224 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Thu, 25 Feb 2016 23:09:42 -0500 Subject: add image download setting --- .../Configuration/ServerConfiguration.cs | 2 ++ .../Manager/ItemImageProvider.cs | 11 ++++++++++ MediaBrowser.Providers/Manager/MetadataService.cs | 24 ++++++++++++++++------ .../LiveTv/EmbyTV/EmbyTV.cs | 19 +++++++++++++++++ 4 files changed, 50 insertions(+), 6 deletions(-) (limited to 'MediaBrowser.Server.Implementations') diff --git a/MediaBrowser.Model/Configuration/ServerConfiguration.cs b/MediaBrowser.Model/Configuration/ServerConfiguration.cs index bc102bd40..5527c1646 100644 --- a/MediaBrowser.Model/Configuration/ServerConfiguration.cs +++ b/MediaBrowser.Model/Configuration/ServerConfiguration.cs @@ -204,6 +204,8 @@ namespace MediaBrowser.Model.Configuration public int MigrationVersion { get; set; } + public bool DownloadImagesInAdvance { get; set; } + /// /// Initializes a new instance of the class. /// diff --git a/MediaBrowser.Providers/Manager/ItemImageProvider.cs b/MediaBrowser.Providers/Manager/ItemImageProvider.cs index 370187801..73e09c1e6 100644 --- a/MediaBrowser.Providers/Manager/ItemImageProvider.cs +++ b/MediaBrowser.Providers/Manager/ItemImageProvider.cs @@ -18,6 +18,7 @@ using System.Threading; using System.Threading.Tasks; using CommonIO; using MediaBrowser.Controller.Entities.Audio; +using MediaBrowser.Controller.LiveTv; using MediaBrowser.Model.MediaInfo; namespace MediaBrowser.Providers.Manager @@ -520,6 +521,16 @@ namespace MediaBrowser.Providers.Manager private bool EnableImageStub(IHasImages item, ImageType type) { + if (item is LiveTvProgram) + { + return true; + } + + if (_config.Configuration.DownloadImagesInAdvance) + { + return false; + } + if (item.LocationType == LocationType.Remote || item.LocationType == LocationType.Virtual) { return true; diff --git a/MediaBrowser.Providers/Manager/MetadataService.cs b/MediaBrowser.Providers/Manager/MetadataService.cs index e18da565d..416cc51bd 100644 --- a/MediaBrowser.Providers/Manager/MetadataService.cs +++ b/MediaBrowser.Providers/Manager/MetadataService.cs @@ -283,12 +283,7 @@ namespace MediaBrowser.Providers.Manager if (!string.IsNullOrWhiteSpace(person.ImageUrl) && !personEntity.HasImage(ImageType.Primary)) { - personEntity.SetImage(new ItemImageInfo - { - Path = person.ImageUrl, - Type = ImageType.Primary, - IsPlaceholder = true - }, 0); + await AddPersonImage(personEntity, person.ImageUrl, cancellationToken).ConfigureAwait(false); saveEntity = true; updateType = updateType | ItemUpdateType.ImageUpdate; @@ -302,6 +297,23 @@ namespace MediaBrowser.Providers.Manager } } + private async Task AddPersonImage(Person personEntity, string imageUrl, CancellationToken cancellationToken) + { + if (ServerConfigurationManager.Configuration.DownloadImagesInAdvance) + { + await ProviderManager.SaveImage(personEntity, imageUrl, null, ImageType.Primary, null, cancellationToken).ConfigureAwait(false); + } + else + { + personEntity.SetImage(new ItemImageInfo + { + Path = imageUrl, + Type = ImageType.Primary, + IsPlaceholder = true + }, 0); + } + } + private readonly Task _cachedTask = Task.FromResult(true); protected virtual Task AfterMetadataRefresh(TItemType item, MetadataRefreshOptions refreshOptions, CancellationToken cancellationToken) { diff --git a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs index ba3998262..1fbd3cb3e 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs @@ -729,6 +729,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV var recordingFileName = _fileSystem.GetValidFilename(RecordingHelper.GetRecordingName(timer, info)).Trim() + ".ts"; recordPath = Path.Combine(recordPath, recordingFileName); + recordPath = EnsureFileUnique(recordPath); _fileSystem.CreateDirectory(Path.GetDirectoryName(recordPath)); var recordingId = info.Id.GetMD5().ToString("N"); @@ -862,6 +863,24 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV } } + private string EnsureFileUnique(string path) + { + var originalPath = path; + var index = 1; + + while (_fileSystem.FileExists(path)) + { + var parent = Path.GetDirectoryName(originalPath); + var name = Path.GetFileNameWithoutExtension(originalPath); + name += "-" + index.ToString(CultureInfo.InvariantCulture); + + path = Path.ChangeExtension(Path.Combine(parent, name), Path.GetExtension(originalPath)); + index++; + } + + return path; + } + private async Task GetRecorder() { if (GetConfiguration().EnableRecordingEncoding) -- cgit v1.2.3 From 78f5152ddbf21fa5434af9831ec9909428ec9b79 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Fri, 26 Feb 2016 01:38:29 -0500 Subject: sync fixes --- MediaBrowser.Controller/Entities/TV/Season.cs | 28 +++++++++++++++++++++- MediaBrowser.Controller/Entities/TV/Series.cs | 26 ++++++++++++++++++++ .../Sync/SyncJobProcessor.cs | 6 +++++ 3 files changed, 59 insertions(+), 1 deletion(-) (limited to 'MediaBrowser.Server.Implementations') diff --git a/MediaBrowser.Controller/Entities/TV/Season.cs b/MediaBrowser.Controller/Entities/TV/Season.cs index 93eac058d..9efa609ef 100644 --- a/MediaBrowser.Controller/Entities/TV/Season.cs +++ b/MediaBrowser.Controller/Entities/TV/Season.cs @@ -1,4 +1,5 @@ -using MediaBrowser.Controller.Providers; +using System; +using MediaBrowser.Controller.Providers; using MediaBrowser.Model.Entities; using MediaBrowser.Model.Querying; using MediaBrowser.Model.Users; @@ -6,6 +7,7 @@ using MoreLinq; using System.Collections.Generic; using System.Linq; using System.Runtime.Serialization; +using System.Threading.Tasks; using MediaBrowser.Model.Configuration; namespace MediaBrowser.Controller.Entities.TV @@ -127,6 +129,30 @@ namespace MediaBrowser.Controller.Entities.TV get { return (IndexNumber ?? -1) == 0; } } + public override Task> GetItems(InternalItemsQuery query) + { + var user = query.User; + + Func filter = i => UserViewBuilder.Filter(i, user, query, UserDataManager, LibraryManager); + + IEnumerable items; + + if (query.User == null) + { + items = query.Recursive + ? GetRecursiveChildren(filter) + : Children.Where(filter); + } + else + { + items = GetEpisodes(query.User).Where(filter); + } + + var result = PostFilterAndSort(items, query); + + return Task.FromResult(result); + } + /// /// Gets the episodes. /// diff --git a/MediaBrowser.Controller/Entities/TV/Series.cs b/MediaBrowser.Controller/Entities/TV/Series.cs index 420b3c313..aa07ab378 100644 --- a/MediaBrowser.Controller/Entities/TV/Series.cs +++ b/MediaBrowser.Controller/Entities/TV/Series.cs @@ -157,6 +157,32 @@ namespace MediaBrowser.Controller.Entities.TV return GetSeasons(user, config.DisplayMissingEpisodes, config.DisplayUnairedEpisodes); } + public override Task> GetItems(InternalItemsQuery query) + { + var user = query.User; + + Func filter = i => UserViewBuilder.Filter(i, user, query, UserDataManager, LibraryManager); + + IEnumerable items; + + if (query.User == null) + { + items = query.Recursive + ? GetRecursiveChildren(filter) + : Children.Where(filter); + } + else + { + items = query.Recursive + ? GetRecursiveChildren(user, filter) + : GetSeasons(user).Where(filter); + } + + var result = PostFilterAndSort(items, query); + + return Task.FromResult(result); + } + public IEnumerable GetSeasons(User user, bool includeMissingSeasons, bool includeVirtualUnaired) { var seasons = base.GetChildren(user, true) diff --git a/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs b/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs index 03e654281..e2e54e056 100644 --- a/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs +++ b/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs @@ -338,6 +338,12 @@ namespace MediaBrowser.Server.Implementations.Sync return series.GetEpisodes(user, false, false); } + var season = item as Season; + if (season != null) + { + return season.GetEpisodes(user, false, false); + } + if (item.IsFolder) { var folder = (Folder)item; -- cgit v1.2.3 From 612986e4ae46d7c98001e7b8b7fd9b770c6646e6 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Fri, 26 Feb 2016 09:50:44 -0500 Subject: handle library monitor error --- MediaBrowser.Server.Implementations/IO/LibraryMonitor.cs | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) (limited to 'MediaBrowser.Server.Implementations') diff --git a/MediaBrowser.Server.Implementations/IO/LibraryMonitor.cs b/MediaBrowser.Server.Implementations/IO/LibraryMonitor.cs index 25fda3ac1..5d0c90ccf 100644 --- a/MediaBrowser.Server.Implementations/IO/LibraryMonitor.cs +++ b/MediaBrowser.Server.Implementations/IO/LibraryMonitor.cs @@ -696,8 +696,21 @@ namespace MediaBrowser.Server.Implementations.IO foreach (var watcher in _fileSystemWatchers.Values.ToList()) { + watcher.Created -= watcher_Changed; + watcher.Deleted -= watcher_Changed; + watcher.Renamed -= watcher_Changed; watcher.Changed -= watcher_Changed; - watcher.EnableRaisingEvents = false; + + try + { + watcher.EnableRaisingEvents = false; + } + catch (InvalidOperationException) + { + // Seeing this under mono on linux sometimes + // Collection was modified; enumeration operation may not execute. + } + watcher.Dispose(); } -- cgit v1.2.3 From 5caa63367af888234ab14bdfb74872d911eebec2 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Fri, 26 Feb 2016 09:50:58 -0500 Subject: support autoplay with dlna --- .../Session/SessionManager.cs | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) (limited to 'MediaBrowser.Server.Implementations') diff --git a/MediaBrowser.Server.Implementations/Session/SessionManager.cs b/MediaBrowser.Server.Implementations/Session/SessionManager.cs index 1074796c0..08953b0be 100644 --- a/MediaBrowser.Server.Implementations/Session/SessionManager.cs +++ b/MediaBrowser.Server.Implementations/Session/SessionManager.cs @@ -983,6 +983,26 @@ namespace MediaBrowser.Server.Implementations.Session } } + if (user != null && command.ItemIds.Length == 1 && user.Configuration.EnableNextEpisodeAutoPlay) + { + var episode = _libraryManager.GetItemById(command.ItemIds[0]) as Episode; + if (episode != null) + { + var series = episode.Series; + if (series != null) + { + var episodes = series.GetEpisodes(user, false, false) + .SkipWhile(i => i.Id != episode.Id) + .ToList(); + + if (episodes.Count > 0) + { + command.ItemIds = episodes.Select(i => i.Id.ToString("N")).ToArray(); + } + } + } + } + var controllingSession = GetSession(controllingSessionId); AssertCanControl(session, controllingSession); if (controllingSession.UserId.HasValue) -- cgit v1.2.3 From fccff2154d20b0c99cc2f75df95049c971f11f6b Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Fri, 26 Feb 2016 13:22:41 -0500 Subject: update SocketHttpListener --- .../MediaBrowser.Server.Implementations.csproj | 4 ++-- MediaBrowser.Server.Implementations/packages.config | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'MediaBrowser.Server.Implementations') diff --git a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj index 3be39bb5e..8e1f42608 100644 --- a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj +++ b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj @@ -65,9 +65,9 @@ ..\ThirdParty\ServiceStack\ServiceStack.Api.Swagger.dll - + False - ..\packages\SocketHttpListener.1.0.0.25\lib\net45\SocketHttpListener.dll + ..\packages\SocketHttpListener.1.0.0.26\lib\net45\SocketHttpListener.dll diff --git a/MediaBrowser.Server.Implementations/packages.config b/MediaBrowser.Server.Implementations/packages.config index 6341e50ba..495bd058b 100644 --- a/MediaBrowser.Server.Implementations/packages.config +++ b/MediaBrowser.Server.Implementations/packages.config @@ -7,5 +7,5 @@ - + \ No newline at end of file -- cgit v1.2.3 From 5bc708999061efc66761a41f6fc9212be91110b5 Mon Sep 17 00:00:00 2001 From: softworkz Date: Sat, 27 Feb 2016 00:52:00 +0100 Subject: Create new series backend implementation --- .../Library/FileOrganizationService.cs | 24 ++++++++++++-- .../EpisodeFileOrganizationRequest.cs | 37 ++++++++++++++++++++- .../FileOrganization/EpisodeFileOrganizer.cs | 38 +++++++++++++++++++++- 3 files changed, 95 insertions(+), 4 deletions(-) (limited to 'MediaBrowser.Server.Implementations') diff --git a/MediaBrowser.Api/Library/FileOrganizationService.cs b/MediaBrowser.Api/Library/FileOrganizationService.cs index 1224fa957..3e40bc5da 100644 --- a/MediaBrowser.Api/Library/FileOrganizationService.cs +++ b/MediaBrowser.Api/Library/FileOrganizationService.cs @@ -54,7 +54,7 @@ namespace MediaBrowser.Api.Library public string Id { get; set; } } - [Route("/Library/FileOrganizations/{Id}/Episode/Organize", "POST", Summary = "Performs an organization")] + [Route("/Library/FileOrganizations/{Id}/Episode/Organize", "POST", Summary = "Performs organization of a tv episode")] public class OrganizeEpisode { [ApiMember(Name = "Id", Description = "Result Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "POST")] @@ -74,6 +74,18 @@ namespace MediaBrowser.Api.Library [ApiMember(Name = "RememberCorrection", Description = "Whether or not to apply the same correction to future episodes of the same series.", IsRequired = false, DataType = "bool", ParameterType = "query", Verb = "POST")] public bool RememberCorrection { get; set; } + + [ApiMember(Name = "NewSeriesProviderIds", Description = "A list of provider IDs identifying a new series.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "POST")] + public string NewSeriesProviderIds { get; set; } + + [ApiMember(Name = "NewSeriesName", Description = "Name of a series to add.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "POST")] + public string NewSeriesName { get; set; } + + [ApiMember(Name = "NewSeriesYear", Description = "Year of a series to add.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "POST")] + public string NewSeriesYear { get; set; } + + [ApiMember(Name = "TargetFolder", Description = "Target Folder", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "POST")] + public string TargetFolder { get; set; } } [Route("/Library/FileOrganizations/SmartMatches", "GET", Summary = "Gets smart match entries")] @@ -152,9 +164,17 @@ namespace MediaBrowser.Api.Library RememberCorrection = request.RememberCorrection, ResultId = request.Id, SeasonNumber = request.SeasonNumber, - SeriesId = request.SeriesId + SeriesId = request.SeriesId, + NewSeriesName = request.NewSeriesName, + NewSeriesYear = request.NewSeriesYear, + NewSeriesProviderIds = request.NewSeriesProviderIds, + TargetFolder = request.TargetFolder }); + // For async processing (close dialog early instead of waiting until the file has been copied) + //var tasks = new Task[] { task }; + //Task.WaitAll(tasks, 8000); + Task.WaitAll(task); } diff --git a/MediaBrowser.Model/FileOrganization/EpisodeFileOrganizationRequest.cs b/MediaBrowser.Model/FileOrganization/EpisodeFileOrganizationRequest.cs index 0b12ebc51..6a3e6c30d 100644 --- a/MediaBrowser.Model/FileOrganization/EpisodeFileOrganizationRequest.cs +++ b/MediaBrowser.Model/FileOrganization/EpisodeFileOrganizationRequest.cs @@ -1,4 +1,6 @@ -namespace MediaBrowser.Model.FileOrganization +using System.Collections.Generic; + +namespace MediaBrowser.Model.FileOrganization { public class EpisodeFileOrganizationRequest { @@ -13,5 +15,38 @@ public int? EndingEpisodeNumber { get; set; } public bool RememberCorrection { get; set; } + public string NewSeriesName { get; set; } + + public string NewSeriesYear { get; set; } + + public string NewSeriesProviderIds { get; set; } + + public string TargetFolder { get; set; } + + public Dictionary NewSeriesProviderIdsDictionary + { + get + { + var dic = new Dictionary(); + + if (!string.IsNullOrEmpty(NewSeriesProviderIds)) + { + var str = NewSeriesProviderIds.Replace("{", "").Replace("}", "").Replace("\"", ""); + + foreach (var item in str.Split(',')) + { + var itemArr = item.Split(':'); + if (itemArr.Length > 1) + { + var key = itemArr[0].Trim(); + var val = itemArr[1].Trim(); + dic.Add(key, val); + } + } + } + + return dic; + } + } } } \ No newline at end of file diff --git a/MediaBrowser.Server.Implementations/FileOrganization/EpisodeFileOrganizer.cs b/MediaBrowser.Server.Implementations/FileOrganization/EpisodeFileOrganizer.cs index 42f88a5c0..43eea4773 100644 --- a/MediaBrowser.Server.Implementations/FileOrganization/EpisodeFileOrganizer.cs +++ b/MediaBrowser.Server.Implementations/FileOrganization/EpisodeFileOrganizer.cs @@ -157,7 +157,43 @@ namespace MediaBrowser.Server.Implementations.FileOrganization { var result = _organizationService.GetResult(request.ResultId); - var series = (Series)_libraryManager.GetItemById(new Guid(request.SeriesId)); + Series series = null; + + if (request.NewSeriesProviderIdsDictionary.Count > 0) + { + // We're having a new series here + SeriesInfo seriesRequest = new SeriesInfo(); + seriesRequest.ProviderIds = request.NewSeriesProviderIdsDictionary; + + var refreshOptions = new MetadataRefreshOptions(_fileSystem); + series = new Series(); + series.Id = Guid.NewGuid(); + series.Name = request.NewSeriesName; + + int year; + if (int.TryParse(request.NewSeriesYear, out year)) + { + series.ProductionYear = year; + } + + var seriesFolderName = series.Name; + if (series.ProductionYear.HasValue) + { + seriesFolderName = string.Format("{0} ({1})", seriesFolderName, series.ProductionYear); + } + + series.Path = Path.Combine(request.TargetFolder, seriesFolderName); + + series.ProviderIds = request.NewSeriesProviderIdsDictionary; + + await series.RefreshMetadata(refreshOptions, cancellationToken); + } + + if (series == null) + { + // Existing Series + series = (Series)_libraryManager.GetItemById(new Guid(request.SeriesId)); + } await OrganizeEpisode(result.OriginalPath, series, -- cgit v1.2.3 From e44d6cffeaa648245324115fd8ae4f14281d707d Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Fri, 26 Feb 2016 23:38:30 -0500 Subject: update components --- .../MediaBrowser.Server.Implementations.csproj | 4 ++-- MediaBrowser.Server.Implementations/packages.config | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'MediaBrowser.Server.Implementations') diff --git a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj index 8e1f42608..a511d31b5 100644 --- a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj +++ b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj @@ -65,9 +65,9 @@ ..\ThirdParty\ServiceStack\ServiceStack.Api.Swagger.dll - + False - ..\packages\SocketHttpListener.1.0.0.26\lib\net45\SocketHttpListener.dll + ..\packages\SocketHttpListener.1.0.0.27\lib\net45\SocketHttpListener.dll diff --git a/MediaBrowser.Server.Implementations/packages.config b/MediaBrowser.Server.Implementations/packages.config index 495bd058b..772790f37 100644 --- a/MediaBrowser.Server.Implementations/packages.config +++ b/MediaBrowser.Server.Implementations/packages.config @@ -7,5 +7,5 @@ - + \ No newline at end of file -- cgit v1.2.3 From accafddbbb7042fd7d4278aa2df4282c6fd983b2 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sat, 27 Feb 2016 12:41:28 -0500 Subject: update live tv playback --- .../LiveTv/LiveTvManager.cs | 17 ++++++++++++----- MediaBrowser.WebDashboard/Api/PackageCreator.cs | 2 +- 2 files changed, 13 insertions(+), 6 deletions(-) (limited to 'MediaBrowser.Server.Implementations') diff --git a/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs b/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs index cd21dc21a..442ab76f6 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs @@ -350,7 +350,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv foreach (var source in list) { - Normalize(source, item.ChannelType == ChannelType.TV); + Normalize(source, service, item.ChannelType == ChannelType.TV); } return list; @@ -379,12 +379,13 @@ namespace MediaBrowser.Server.Implementations.LiveTv { MediaSourceInfo info; bool isVideo; + ILiveTvService service; if (isChannel) { var channel = GetInternalChannel(id); isVideo = channel.ChannelType == ChannelType.TV; - var service = GetService(channel); + service = GetService(channel); _logger.Info("Opening channel stream from {0}, external channel Id: {1}", service.Name, channel.ExternalId); info = await service.GetChannelStream(channel.ExternalId, mediaSourceId, cancellationToken).ConfigureAwait(false); info.RequiresClosing = true; @@ -400,7 +401,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv { var recording = await GetInternalRecording(id, cancellationToken).ConfigureAwait(false); isVideo = !string.Equals(recording.MediaType, MediaType.Audio, StringComparison.OrdinalIgnoreCase); - var service = GetService(recording); + service = GetService(recording); _logger.Info("Opening recording stream from {0}, external recording Id: {1}", service.Name, recording.ExternalId); info = await service.GetRecordingStream(recording.ExternalId, null, cancellationToken).ConfigureAwait(false); @@ -415,7 +416,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv } _logger.Info("Live stream info: {0}", _jsonSerializer.SerializeToString(info)); - Normalize(info, isVideo); + Normalize(info, service, isVideo); var data = new LiveStreamData { @@ -440,7 +441,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv } } - private void Normalize(MediaSourceInfo mediaSource, bool isVideo) + private void Normalize(MediaSourceInfo mediaSource, ILiveTvService service, bool isVideo) { if (mediaSource.MediaStreams.Count == 0) { @@ -537,6 +538,12 @@ namespace MediaBrowser.Server.Implementations.LiveTv mediaSource.Bitrate = total; } } + + if (!(service is EmbyTV.EmbyTV)) + { + // We can't trust that we'll be able to direct stream it through emby server, no matter what the provider says + mediaSource.SupportsDirectStream = true; + } } private async Task GetChannel(ChannelInfo channelInfo, string serviceName, Guid parentFolderId, CancellationToken cancellationToken) diff --git a/MediaBrowser.WebDashboard/Api/PackageCreator.cs b/MediaBrowser.WebDashboard/Api/PackageCreator.cs index 67eb3d53b..c3db09457 100644 --- a/MediaBrowser.WebDashboard/Api/PackageCreator.cs +++ b/MediaBrowser.WebDashboard/Api/PackageCreator.cs @@ -354,7 +354,7 @@ namespace MediaBrowser.WebDashboard.Api if (string.Equals(mode, "cordova", StringComparison.OrdinalIgnoreCase)) { - sb.Append(""); + sb.Append(""); } sb.Append(""); -- cgit v1.2.3 From 719f675fe5729aecbf651e19d87e5c16f5b8b49f Mon Sep 17 00:00:00 2001 From: softworkz Date: Sat, 27 Feb 2016 23:09:14 +0100 Subject: Rename NewSeriesProviderIdsDictionary to NewSeriesProviderIds --- MediaBrowser.Api/Library/FileOrganizationService.cs | 2 +- .../FileOrganization/EpisodeFileOrganizationRequest.cs | 2 +- .../FileOrganization/EpisodeFileOrganizer.cs | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-) (limited to 'MediaBrowser.Server.Implementations') diff --git a/MediaBrowser.Api/Library/FileOrganizationService.cs b/MediaBrowser.Api/Library/FileOrganizationService.cs index f636b723e..dba705ba3 100644 --- a/MediaBrowser.Api/Library/FileOrganizationService.cs +++ b/MediaBrowser.Api/Library/FileOrganizationService.cs @@ -185,7 +185,7 @@ namespace MediaBrowser.Api.Library SeriesId = request.SeriesId, NewSeriesName = request.NewSeriesName, NewSeriesYear = request.NewSeriesYear, - NewSeriesProviderIdsDictionary = dicNewProviderIds, + NewSeriesProviderIds = dicNewProviderIds, TargetFolder = request.TargetFolder }); diff --git a/MediaBrowser.Model/FileOrganization/EpisodeFileOrganizationRequest.cs b/MediaBrowser.Model/FileOrganization/EpisodeFileOrganizationRequest.cs index 307088b63..b20e43e54 100644 --- a/MediaBrowser.Model/FileOrganization/EpisodeFileOrganizationRequest.cs +++ b/MediaBrowser.Model/FileOrganization/EpisodeFileOrganizationRequest.cs @@ -21,6 +21,6 @@ namespace MediaBrowser.Model.FileOrganization public string TargetFolder { get; set; } - public Dictionary NewSeriesProviderIdsDictionary { get; set; } + public Dictionary NewSeriesProviderIds { get; set; } } } \ No newline at end of file diff --git a/MediaBrowser.Server.Implementations/FileOrganization/EpisodeFileOrganizer.cs b/MediaBrowser.Server.Implementations/FileOrganization/EpisodeFileOrganizer.cs index 43eea4773..24e8c7137 100644 --- a/MediaBrowser.Server.Implementations/FileOrganization/EpisodeFileOrganizer.cs +++ b/MediaBrowser.Server.Implementations/FileOrganization/EpisodeFileOrganizer.cs @@ -159,11 +159,11 @@ namespace MediaBrowser.Server.Implementations.FileOrganization Series series = null; - if (request.NewSeriesProviderIdsDictionary.Count > 0) + if (request.NewSeriesProviderIds.Count > 0) { // We're having a new series here SeriesInfo seriesRequest = new SeriesInfo(); - seriesRequest.ProviderIds = request.NewSeriesProviderIdsDictionary; + seriesRequest.ProviderIds = request.NewSeriesProviderIds; var refreshOptions = new MetadataRefreshOptions(_fileSystem); series = new Series(); @@ -184,7 +184,7 @@ namespace MediaBrowser.Server.Implementations.FileOrganization series.Path = Path.Combine(request.TargetFolder, seriesFolderName); - series.ProviderIds = request.NewSeriesProviderIdsDictionary; + series.ProviderIds = request.NewSeriesProviderIds; await series.RefreshMetadata(refreshOptions, cancellationToken); } -- cgit v1.2.3 From a9804ed2ef200d37aa999485aba4148386584e2f Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sun, 28 Feb 2016 16:31:54 -0500 Subject: use discover.json --- .../LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs | 31 +++++++++++----------- 1 file changed, 16 insertions(+), 15 deletions(-) (limited to 'MediaBrowser.Server.Implementations') diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs b/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs index 35988df9c..bdfbee521 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs @@ -96,30 +96,19 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.HdHomerun private async Task GetModelInfo(TunerHostInfo info, CancellationToken cancellationToken) { - string model = null; - using (var stream = await _httpClient.Get(new HttpRequestOptions() { - Url = string.Format("{0}/", GetApiUrl(info, false)), + Url = string.Format("{0}/discover.json", GetApiUrl(info, false)), CancellationToken = cancellationToken, CacheLength = TimeSpan.FromDays(1), CacheMode = CacheMode.Unconditional, TimeoutMs = Convert.ToInt32(TimeSpan.FromSeconds(5).TotalMilliseconds) })) { - using (var sr = new StreamReader(stream, System.Text.Encoding.UTF8)) - { - while (!sr.EndOfStream) - { - string line = StripXML(sr.ReadLine()); - if (line.StartsWith("Model:")) { model = line.Replace("Model: ", ""); } - //if (line.StartsWith("Device ID:")) { deviceID = line.Replace("Device ID: ", ""); } - //if (line.StartsWith("Firmware:")) { firmware = line.Replace("Firmware: ", ""); } - } - } - } + var response = JsonSerializer.DeserializeFromStream(stream); - return model; + return response.ModelNumber; + } } public async Task> GetTunerInfos(TunerHostInfo info, CancellationToken cancellationToken) @@ -438,5 +427,17 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.HdHomerun return info.Any(i => i.Status == LiveTvTunerStatus.Available); } + + public class DiscoverResponse + { + public string FriendlyName { get; set; } + public string ModelNumber { get; set; } + public string FirmwareName { get; set; } + public string FirmwareVersion { get; set; } + public string DeviceID { get; set; } + public string DeviceAuth { get; set; } + public string BaseURL { get; set; } + public string LineupURL { get; set; } + } } } -- cgit v1.2.3 From bd38cb7a8b3bb8dcb9cf44d75aae60930a0dedf1 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Mon, 29 Feb 2016 11:25:09 -0500 Subject: update EpisodeFileOrganizer --- .../FileOrganization/EpisodeFileOrganizer.cs | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) (limited to 'MediaBrowser.Server.Implementations') diff --git a/MediaBrowser.Server.Implementations/FileOrganization/EpisodeFileOrganizer.cs b/MediaBrowser.Server.Implementations/FileOrganization/EpisodeFileOrganizer.cs index 24e8c7137..f9e167a8f 100644 --- a/MediaBrowser.Server.Implementations/FileOrganization/EpisodeFileOrganizer.cs +++ b/MediaBrowser.Server.Implementations/FileOrganization/EpisodeFileOrganizer.cs @@ -286,16 +286,29 @@ namespace MediaBrowser.Server.Implementations.FileOrganization { if (options.TvOptions.CopyOriginalFile && fileExists && IsSameEpisode(sourcePath, newPath)) { - _logger.Info("File {0} already copied to new path {1}, stopping organization", sourcePath, newPath); + var msg = string.Format("File '{0}' already copied to new path '{1}', stopping organization", sourcePath, newPath); + _logger.Info(msg); result.Status = FileSortingStatus.SkippedExisting; - result.StatusMessage = string.Empty; + result.StatusMessage = msg; + return; + } + + if (fileExists) + { + var msg = string.Format("File '{0}' already exists as '{1}', stopping organization", sourcePath, newPath); + _logger.Info(msg); + result.Status = FileSortingStatus.SkippedExisting; + result.StatusMessage = msg; + result.TargetPath = newPath; return; } - if (fileExists || otherDuplicatePaths.Count > 0) + if (otherDuplicatePaths.Count > 0) { + var msg = string.Format("File '{0}' already exists as '{1}', stopping organization", sourcePath, otherDuplicatePaths); + _logger.Info(msg); result.Status = FileSortingStatus.SkippedExisting; - result.StatusMessage = string.Empty; + result.StatusMessage = msg; result.DuplicatePaths = otherDuplicatePaths; return; } -- cgit v1.2.3 From 6da57c86cd0b0955b5fc9a4426762cc83328eeff Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Mon, 29 Feb 2016 11:25:21 -0500 Subject: update recordings --- MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs | 2 +- MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EncodedRecorder.cs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'MediaBrowser.Server.Implementations') diff --git a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs index 1fbd3cb3e..e534d8c67 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs @@ -778,7 +778,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV try { // HDHR doesn't seem to release the tuner right away after first probing with ffmpeg - await Task.Delay(3000, cancellationToken).ConfigureAwait(false); + //await Task.Delay(3000, cancellationToken).ConfigureAwait(false); var duration = recordingEndDate - DateTime.UtcNow; diff --git a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EncodedRecorder.cs b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EncodedRecorder.cs index ac5cda95e..8b7bd897b 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EncodedRecorder.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EncodedRecorder.cs @@ -88,11 +88,11 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV // MUST read both stdout and stderr asynchronously or a deadlock may occurr process.BeginOutputReadLine(); + onStarted(); + // Important - don't await the log task or we won't be able to kill ffmpeg when the user stops playback StartStreamingLog(process.StandardError.BaseStream, _logFileStream); - onStarted(); - // Wait for the file to exist before proceeeding while (!_hasExited) { -- cgit v1.2.3 From 156a047cfefaffedc11d35f758f3f92720b30a91 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Mon, 29 Feb 2016 23:23:58 -0500 Subject: add null check to ScheduleDirect --- .../LiveTv/Listings/SchedulesDirect.cs | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'MediaBrowser.Server.Implementations') diff --git a/MediaBrowser.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs b/MediaBrowser.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs index 87d7ff3eb..449943229 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs @@ -951,6 +951,11 @@ namespace MediaBrowser.Server.Implementations.LiveTv.Listings public string stationID { get; set; } public List programs { get; set; } public MetadataSchedule metadata { get; set; } + + public Day() + { + programs = new List(); + } } // -- cgit v1.2.3 From c3eb571d1de4c06ded892284a79047deb5c567f7 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Mon, 29 Feb 2016 23:24:14 -0500 Subject: add null check to SyncJobProcessor --- MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'MediaBrowser.Server.Implementations') diff --git a/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs b/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs index e2e54e056..7086735c0 100644 --- a/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs +++ b/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs @@ -308,6 +308,11 @@ namespace MediaBrowser.Server.Implementations.Sync throw new ArgumentException("Unrecognized category: " + category); } + if (parent == null) + { + return new List(); + } + query.User = user; var result = await parent.GetItems(query).ConfigureAwait(false); -- cgit v1.2.3 From 2eb492f86597bf9e19368b59426ac2805522603c Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Mon, 29 Feb 2016 23:24:42 -0500 Subject: update recording stoppage --- .../LiveTv/EmbyTV/DirectRecorder.cs | 7 ++- .../LiveTv/EmbyTV/EmbyTV.cs | 69 +++++++++++++++------- .../LiveTv/EmbyTV/EncodedRecorder.cs | 10 ++-- .../LiveTv/EmbyTV/IRecorder.cs | 11 +++- .../LiveTv/EmbyTV/RecordingHelper.cs | 10 ++-- 5 files changed, 72 insertions(+), 35 deletions(-) (limited to 'MediaBrowser.Server.Implementations') diff --git a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/DirectRecorder.cs b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/DirectRecorder.cs index 9ac96165f..d33b2c51d 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/DirectRecorder.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/DirectRecorder.cs @@ -23,7 +23,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV _fileSystem = fileSystem; } - public async Task Record(MediaSourceInfo mediaSource, string targetFile, Action onStarted, CancellationToken cancellationToken) + public async Task Record(MediaSourceInfo mediaSource, string targetFile, TimeSpan duration, Action onStarted, CancellationToken cancellationToken) { var httpRequestOptions = new HttpRequestOptions() { @@ -42,7 +42,10 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV _logger.Info("Copying recording stream to file stream"); - await response.Content.CopyToAsync(output, StreamDefaults.DefaultCopyToBufferSize, cancellationToken).ConfigureAwait(false); + var durationToken = new CancellationTokenSource(duration); + var linkedToken = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken, durationToken.Token).Token; + + await response.Content.CopyToAsync(output, StreamDefaults.DefaultCopyToBufferSize, linkedToken).ConfigureAwait(false); } } } diff --git a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs index e534d8c67..3ab08274c 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs @@ -103,8 +103,8 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV public event EventHandler RecordingStatusChanged; - private readonly ConcurrentDictionary _activeRecordings = - new ConcurrentDictionary(StringComparer.OrdinalIgnoreCase); + private readonly ConcurrentDictionary _activeRecordings = + new ConcurrentDictionary(StringComparer.OrdinalIgnoreCase); public string Name { @@ -268,11 +268,11 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV { _timerProvider.Delete(remove); } - CancellationTokenSource cancellationTokenSource; + ActiveRecordingInfo activeRecordingInfo; - if (_activeRecordings.TryGetValue(timerId, out cancellationTokenSource)) + if (_activeRecordings.TryGetValue(timerId, out activeRecordingInfo)) { - cancellationTokenSource.Cancel(); + activeRecordingInfo.CancellationTokenSource.Cancel(); } } @@ -653,11 +653,15 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV return; } - var cancellationTokenSource = new CancellationTokenSource(); + var activeRecordingInfo = new ActiveRecordingInfo + { + CancellationTokenSource = new CancellationTokenSource(), + TimerId = timer.Id + }; - if (_activeRecordings.TryAdd(timer.Id, cancellationTokenSource)) + if (_activeRecordings.TryAdd(timer.Id, activeRecordingInfo)) { - await RecordStream(timer, recordingEndDate, cancellationTokenSource.Token).ConfigureAwait(false); + await RecordStream(timer, recordingEndDate, activeRecordingInfo, activeRecordingInfo.CancellationTokenSource.Token).ConfigureAwait(false); } else { @@ -674,7 +678,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV } } - private async Task RecordStream(TimerInfo timer, DateTime recordingEndDate, CancellationToken cancellationToken) + private async Task RecordStream(TimerInfo timer, DateTime recordingEndDate, ActiveRecordingInfo activeRecordingInfo, CancellationToken cancellationToken) { if (timer == null) { @@ -729,8 +733,6 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV var recordingFileName = _fileSystem.GetValidFilename(RecordingHelper.GetRecordingName(timer, info)).Trim() + ".ts"; recordPath = Path.Combine(recordPath, recordingFileName); - recordPath = EnsureFileUnique(recordPath); - _fileSystem.CreateDirectory(Path.GetDirectoryName(recordPath)); var recordingId = info.Id.GetMD5().ToString("N"); var recording = _recordingProvider.GetAll().FirstOrDefault(x => string.Equals(x.Id, recordingId, StringComparison.OrdinalIgnoreCase)); @@ -788,6 +790,9 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV { recordPath = Path.ChangeExtension(recordPath, ".mp4"); } + recordPath = EnsureFileUnique(recordPath, timer.Id); + _fileSystem.CreateDirectory(Path.GetDirectoryName(recordPath)); + activeRecordingInfo.Path = recordPath; _libraryMonitor.ReportFileSystemChangeBeginning(recordPath); @@ -798,9 +803,6 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV _logger.Info("Beginning recording. Will record for {0} minutes.", duration.TotalMinutes.ToString(CultureInfo.InvariantCulture)); - var durationToken = new CancellationTokenSource(duration); - var linkedToken = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken, durationToken.Token).Token; - _logger.Info("Writing file to path: " + recordPath); _logger.Info("Opening recording stream from tuner provider"); @@ -810,10 +812,10 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV isResourceOpen = false; }; - await recorder.Record(mediaStreamInfo, recordPath, onStarted, linkedToken).ConfigureAwait(false); + await recorder.Record(mediaStreamInfo, recordPath, duration, onStarted, cancellationToken).ConfigureAwait(false); recording.Status = RecordingStatus.Completed; - _logger.Info("Recording completed"); + _logger.Info("Recording completed: {0}", recordPath); } finally { @@ -827,17 +829,17 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV } catch (OperationCanceledException) { - _logger.Info("Recording stopped"); + _logger.Info("Recording stopped: {0}", recordPath); recording.Status = RecordingStatus.Completed; } catch (Exception ex) { - _logger.ErrorException("Error recording", ex); + _logger.ErrorException("Error recording to {0}", ex, recordPath); recording.Status = RecordingStatus.Error; } finally { - CancellationTokenSource removed; + ActiveRecordingInfo removed; _activeRecordings.TryRemove(timer.Id, out removed); } @@ -863,12 +865,12 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV } } - private string EnsureFileUnique(string path) + private string EnsureFileUnique(string path, string timerId) { var originalPath = path; var index = 1; - while (_fileSystem.FileExists(path)) + while (FileExists(path, timerId)) { var parent = Path.GetDirectoryName(originalPath); var name = Path.GetFileNameWithoutExtension(originalPath); @@ -881,6 +883,22 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV return path; } + private bool FileExists(string path, string timerId) + { + if (_fileSystem.FileExists(path)) + { + return true; + } + + var hasRecordingAtPath = _activeRecordings.Values.ToList().Any(i => string.Equals(i.Path, path, StringComparison.OrdinalIgnoreCase) && !string.Equals(i.TimerId, timerId, StringComparison.OrdinalIgnoreCase)); + + if (hasRecordingAtPath) + { + return true; + } + return false; + } + private async Task GetRecorder() { if (GetConfiguration().EnableRecordingEncoding) @@ -1064,7 +1082,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV { foreach (var pair in _activeRecordings.ToList()) { - pair.Value.Cancel(); + pair.Value.CancellationTokenSource.Cancel(); } } @@ -1081,5 +1099,12 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV IsRegistered = true }); } + + class ActiveRecordingInfo + { + public string Path { get; set; } + public string TimerId { get; set; } + public CancellationTokenSource CancellationTokenSource { get; set; } + } } } \ No newline at end of file diff --git a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EncodedRecorder.cs b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EncodedRecorder.cs index 8b7bd897b..62c9cd171 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EncodedRecorder.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EncodedRecorder.cs @@ -38,7 +38,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV _json = json; } - public async Task Record(MediaSourceInfo mediaSource, string targetFile, Action onStarted, CancellationToken cancellationToken) + public async Task Record(MediaSourceInfo mediaSource, string targetFile, TimeSpan duration, Action onStarted, CancellationToken cancellationToken) { _targetPath = targetFile; _fileSystem.CreateDirectory(Path.GetDirectoryName(targetFile)); @@ -56,7 +56,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV RedirectStandardInput = true, FileName = _mediaEncoder.EncoderPath, - Arguments = GetCommandLineArgs(mediaSource, targetFile), + Arguments = GetCommandLineArgs(mediaSource, targetFile, duration), WindowStyle = ProcessWindowStyle.Hidden, ErrorDialog = false @@ -100,7 +100,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV } } - private string GetCommandLineArgs(MediaSourceInfo mediaSource, string targetFile) + private string GetCommandLineArgs(MediaSourceInfo mediaSource, string targetFile, TimeSpan duration) { string videoArgs; if (EncodeVideo(mediaSource)) @@ -116,14 +116,14 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV videoArgs = "-codec:v:0 copy"; } - var commandLineArgs = "-fflags +genpts -async 1 -vsync -1 -i \"{0}\" -sn {2} -map_metadata -1 -threads 0 {3} -y \"{1}\""; + var commandLineArgs = "-fflags +genpts -async 1 -vsync -1 -i \"{0}\" -t {4} -sn {2} -map_metadata -1 -threads 0 {3} -y \"{1}\""; if (mediaSource.ReadAtNativeFramerate) { commandLineArgs = "-re " + commandLineArgs; } - commandLineArgs = string.Format(commandLineArgs, mediaSource.Path, targetFile, videoArgs, GetAudioArgs(mediaSource)); + commandLineArgs = string.Format(commandLineArgs, mediaSource.Path, targetFile, videoArgs, GetAudioArgs(mediaSource), _mediaEncoder.GetTimeParameter(duration.Ticks)); return commandLineArgs; } diff --git a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/IRecorder.cs b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/IRecorder.cs index 12e73c1f3..268a4f751 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/IRecorder.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/IRecorder.cs @@ -7,6 +7,15 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV { public interface IRecorder { - Task Record(MediaSourceInfo mediaSource, string targetFile, Action onStarted, CancellationToken cancellationToken); + /// + /// Records the specified media source. + /// + /// The media source. + /// The target file. + /// The duration. + /// The on started. + /// The cancellation token. + /// Task. + Task Record(MediaSourceInfo mediaSource, string targetFile, TimeSpan duration, Action onStarted, CancellationToken cancellationToken); } } diff --git a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/RecordingHelper.cs b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/RecordingHelper.cs index a5c869d45..37e10d925 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/RecordingHelper.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/RecordingHelper.cs @@ -56,13 +56,13 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV name += " " + info.OriginalAirDate.Value.ToString("yyyy-MM-dd"); } - if (addHyphen) - { - name += " -"; - } - if (!string.IsNullOrWhiteSpace(info.EpisodeTitle)) { + if (addHyphen) + { + name += " -"; + } + name += " " + info.EpisodeTitle; } } -- cgit v1.2.3 From 9d20e298e12103604e851c99c7041025fc01c631 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Tue, 1 Mar 2016 01:02:55 -0500 Subject: exclude recordings from CleanDatabaseScheduledTask --- .../Persistence/CleanDatabaseScheduledTask.cs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'MediaBrowser.Server.Implementations') diff --git a/MediaBrowser.Server.Implementations/Persistence/CleanDatabaseScheduledTask.cs b/MediaBrowser.Server.Implementations/Persistence/CleanDatabaseScheduledTask.cs index 6ca1bae6d..5f1bf0216 100644 --- a/MediaBrowser.Server.Implementations/Persistence/CleanDatabaseScheduledTask.cs +++ b/MediaBrowser.Server.Implementations/Persistence/CleanDatabaseScheduledTask.cs @@ -239,7 +239,11 @@ namespace MediaBrowser.Server.Implementations.Persistence typeof(Year).Name, typeof(Channel).Name, typeof(AggregateFolder).Name, - typeof(CollectionFolder).Name + typeof(CollectionFolder).Name, + + // LiveTVManager handles recordings + typeof(LiveTvAudioRecording).Name, + typeof(LiveTvVideoRecording).Name } }); -- cgit v1.2.3 From 076a07a54661da993b7ecefd5e294b11b8d90873 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Tue, 1 Mar 2016 14:39:46 -0500 Subject: optimize FindByPath --- MediaBrowser.Api/Playback/Progressive/VideoService.cs | 5 +++++ MediaBrowser.Controller/Entities/BaseItem.cs | 2 +- MediaBrowser.Controller/Entities/InternalItemsQuery.cs | 2 ++ MediaBrowser.Controller/Library/ILibraryManager.cs | 7 +++++++ .../IO/LibraryMonitor.cs | 2 +- .../Library/LibraryManager.cs | 17 +++++++++++++++++ .../Persistence/SqliteItemRepository.cs | 7 +++++++ 7 files changed, 40 insertions(+), 2 deletions(-) (limited to 'MediaBrowser.Server.Implementations') diff --git a/MediaBrowser.Api/Playback/Progressive/VideoService.cs b/MediaBrowser.Api/Playback/Progressive/VideoService.cs index f13058924..b7e180eca 100644 --- a/MediaBrowser.Api/Playback/Progressive/VideoService.cs +++ b/MediaBrowser.Api/Playback/Progressive/VideoService.cs @@ -148,6 +148,11 @@ namespace MediaBrowser.Api.Playback.Progressive args += " -bsf:v h264_mp4toannexb"; } + if (state.RunTimeTicks.HasValue && state.VideoRequest.CopyTimestamps) + { + args += " -copyts -avoid_negative_ts disabled -start_at_zero"; + } + return args; } diff --git a/MediaBrowser.Controller/Entities/BaseItem.cs b/MediaBrowser.Controller/Entities/BaseItem.cs index d52e2b37f..3dfbdec56 100644 --- a/MediaBrowser.Controller/Entities/BaseItem.cs +++ b/MediaBrowser.Controller/Entities/BaseItem.cs @@ -1359,7 +1359,7 @@ namespace MediaBrowser.Controller.Entities { if (!string.IsNullOrEmpty(info.Path)) { - var itemByPath = LibraryManager.RootFolder.FindByPath(info.Path); + var itemByPath = LibraryManager.FindByPath(info.Path); if (itemByPath == null) { diff --git a/MediaBrowser.Controller/Entities/InternalItemsQuery.cs b/MediaBrowser.Controller/Entities/InternalItemsQuery.cs index f6af12369..8b623d64e 100644 --- a/MediaBrowser.Controller/Entities/InternalItemsQuery.cs +++ b/MediaBrowser.Controller/Entities/InternalItemsQuery.cs @@ -45,6 +45,8 @@ namespace MediaBrowser.Controller.Entities public string NameLessThan { get; set; } public string NameContains { get; set; } + public string Path { get; set; } + public string Person { get; set; } public string[] PersonIds { get; set; } public string[] ItemIds { get; set; } diff --git a/MediaBrowser.Controller/Library/ILibraryManager.cs b/MediaBrowser.Controller/Library/ILibraryManager.cs index 1c515edd5..ff44953ef 100644 --- a/MediaBrowser.Controller/Library/ILibraryManager.cs +++ b/MediaBrowser.Controller/Library/ILibraryManager.cs @@ -56,6 +56,13 @@ namespace MediaBrowser.Controller.Library /// Task{Person}. Person GetPerson(string name); + /// + /// Finds the by path. + /// + /// The path. + /// BaseItem. + BaseItem FindByPath(string path); + /// /// Gets the artist. /// diff --git a/MediaBrowser.Server.Implementations/IO/LibraryMonitor.cs b/MediaBrowser.Server.Implementations/IO/LibraryMonitor.cs index 5d0c90ccf..0559e08ea 100644 --- a/MediaBrowser.Server.Implementations/IO/LibraryMonitor.cs +++ b/MediaBrowser.Server.Implementations/IO/LibraryMonitor.cs @@ -664,7 +664,7 @@ namespace MediaBrowser.Server.Implementations.IO while (item == null && !string.IsNullOrEmpty(path)) { - item = LibraryManager.RootFolder.FindByPath(path); + item = LibraryManager.FindByPath(path); path = Path.GetDirectoryName(path); } diff --git a/MediaBrowser.Server.Implementations/Library/LibraryManager.cs b/MediaBrowser.Server.Implementations/Library/LibraryManager.cs index 333b1fbe9..f0ee364b4 100644 --- a/MediaBrowser.Server.Implementations/Library/LibraryManager.cs +++ b/MediaBrowser.Server.Implementations/Library/LibraryManager.cs @@ -788,6 +788,23 @@ namespace MediaBrowser.Server.Implementations.Library return _userRootFolder; } + public BaseItem FindByPath(string path) + { + var query = new InternalItemsQuery + { + Path = path + }; + + var items = GetItemIds(query).Select(GetItemById).Where(i => i != null).ToArray(); + + if (items.Length == 1) + { + return items[0]; + } + + return RootFolder.FindByPath(path); + } + /// /// Gets a Person /// diff --git a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs index 697ec2271..cd439d1f2 100644 --- a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs +++ b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs @@ -130,6 +130,7 @@ namespace MediaBrowser.Server.Implementations.Persistence "create table if not exists TypedBaseItems (guid GUID primary key, type TEXT, data BLOB, ParentId GUID)", "create index if not exists idx_TypedBaseItems on TypedBaseItems(guid)", + "create index if not exists idx_PathTypedBaseItems on TypedBaseItems(Path)", "create index if not exists idx_ParentIdTypedBaseItems on TypedBaseItems(ParentId)", "create table if not exists AncestorIds (ItemId GUID, AncestorId GUID, AncestorIdText TEXT, PRIMARY KEY (ItemId, AncestorId))", @@ -1804,6 +1805,12 @@ namespace MediaBrowser.Server.Implementations.Persistence cmd.Parameters.Add(cmd, "@ParentId", DbType.Guid).Value = query.ParentId.Value; } + if (!string.IsNullOrWhiteSpace(query.Path)) + { + whereClauses.Add("Path=@Path"); + cmd.Parameters.Add(cmd, "@Path", DbType.String).Value = query.Path; + } + if (query.MinEndDate.HasValue) { whereClauses.Add("EndDate>=@MinEndDate"); -- cgit v1.2.3 From 6b1f786a445ae9e44d4d5c247c541892840ce8c1 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Tue, 1 Mar 2016 14:43:03 -0500 Subject: update FindByPath --- MediaBrowser.Server.Implementations/Library/LibraryManager.cs | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'MediaBrowser.Server.Implementations') diff --git a/MediaBrowser.Server.Implementations/Library/LibraryManager.cs b/MediaBrowser.Server.Implementations/Library/LibraryManager.cs index f0ee364b4..721603efe 100644 --- a/MediaBrowser.Server.Implementations/Library/LibraryManager.cs +++ b/MediaBrowser.Server.Implementations/Library/LibraryManager.cs @@ -795,12 +795,18 @@ namespace MediaBrowser.Server.Implementations.Library Path = path }; + // Only use the database result if there's exactly one item, otherwise we run the risk of returning old data that hasn't been cleaned yet. var items = GetItemIds(query).Select(GetItemById).Where(i => i != null).ToArray(); if (items.Length == 1) { return items[0]; } + + if (items.Length == 0) + { + return null; + } return RootFolder.FindByPath(path); } -- cgit v1.2.3 From e52eb2219b1410fa2fe2343cc4f1e26fcc0af98b Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Tue, 1 Mar 2016 23:46:10 -0500 Subject: use shared usersettings --- MediaBrowser.Server.Implementations/Sync/SyncHelper.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'MediaBrowser.Server.Implementations') diff --git a/MediaBrowser.Server.Implementations/Sync/SyncHelper.cs b/MediaBrowser.Server.Implementations/Sync/SyncHelper.cs index b6242950f..fb4e0c6be 100644 --- a/MediaBrowser.Server.Implementations/Sync/SyncHelper.cs +++ b/MediaBrowser.Server.Implementations/Sync/SyncHelper.cs @@ -10,11 +10,11 @@ namespace MediaBrowser.Server.Implementations.Sync { if (string.Equals(quality, "medium", StringComparison.OrdinalIgnoreCase)) { - profileBitrate = Math.Min(Convert.ToInt32(profileBitrate.Value * .7), 4000000); + profileBitrate = Math.Min(profileBitrate.Value, 4000000); } else if (string.Equals(quality, "low", StringComparison.OrdinalIgnoreCase)) { - profileBitrate = Math.Min(Convert.ToInt32(profileBitrate.Value * .5), 1500000); + profileBitrate = Math.Min(profileBitrate.Value, 1500000); } } -- cgit v1.2.3 From 11a5bbf9b53f9462b66e5ff1ead51d04eed460ea Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Wed, 2 Mar 2016 13:42:39 -0500 Subject: update recording data --- MediaBrowser.Controller/LiveTv/ILiveTvManager.cs | 9 +- .../Dto/DtoService.cs | 25 ++++- .../EntryPoints/UsageReporter.cs | 8 +- .../LiveTv/LiveTvManager.cs | 107 +++++++++++---------- 4 files changed, 89 insertions(+), 60 deletions(-) (limited to 'MediaBrowser.Server.Implementations') diff --git a/MediaBrowser.Controller/LiveTv/ILiveTvManager.cs b/MediaBrowser.Controller/LiveTv/ILiveTvManager.cs index 05c7448c3..501e48a74 100644 --- a/MediaBrowser.Controller/LiveTv/ILiveTvManager.cs +++ b/MediaBrowser.Controller/LiveTv/ILiveTvManager.cs @@ -1,4 +1,5 @@ -using MediaBrowser.Controller.Channels; +using System; +using MediaBrowser.Controller.Channels; using MediaBrowser.Controller.Dto; using MediaBrowser.Controller.Entities; using MediaBrowser.Model.Dto; @@ -343,11 +344,11 @@ namespace MediaBrowser.Controller.LiveTv /// /// Adds the information to program dto. /// - /// The item. - /// The dto. + /// The programs. /// The fields. /// The user. - void AddInfoToProgramDto(BaseItem item, BaseItemDto dto, List fields, User user = null); + /// Task. + Task AddInfoToProgramDto(List> programs, List fields, User user = null); /// /// Saves the tuner host. /// diff --git a/MediaBrowser.Server.Implementations/Dto/DtoService.cs b/MediaBrowser.Server.Implementations/Dto/DtoService.cs index 07686e91c..a19a122c3 100644 --- a/MediaBrowser.Server.Implementations/Dto/DtoService.cs +++ b/MediaBrowser.Server.Implementations/Dto/DtoService.cs @@ -26,6 +26,7 @@ using System; using System.Collections.Generic; using System.IO; using System.Linq; +using System.Threading.Tasks; using CommonIO; namespace MediaBrowser.Server.Implementations.Dto @@ -92,11 +93,17 @@ namespace MediaBrowser.Server.Implementations.Dto var syncDictionary = GetSyncedItemProgressDictionary(syncJobItems); var list = new List(); + var programTuples = new List> { }; foreach (var item in items) { var dto = GetBaseItemDtoInternal(item, options, syncDictionary, user, owner); + if (item is LiveTvProgram) + { + programTuples.Add(new Tuple(item, dto)); + } + var byName = item as IItemByName; if (byName != null) @@ -118,6 +125,12 @@ namespace MediaBrowser.Server.Implementations.Dto list.Add(dto); } + if (programTuples.Count > 0) + { + var task = _livetvManager().AddInfoToProgramDto(programTuples, options.Fields, user); + Task.WaitAll(task); + } + return list; } @@ -139,6 +152,13 @@ namespace MediaBrowser.Server.Implementations.Dto var dto = GetBaseItemDtoInternal(item, options, GetSyncedItemProgressDictionary(syncProgress), user, owner); + if (item is LiveTvProgram) + { + var list = new List> { new Tuple(item, dto) }; + var task = _livetvManager().AddInfoToProgramDto(list, options.Fields, user); + Task.WaitAll(task); + } + var byName = item as IItemByName; if (byName != null) @@ -393,11 +413,6 @@ namespace MediaBrowser.Server.Implementations.Dto _livetvManager().AddInfoToRecordingDto(item, dto, user); } - else if (item is LiveTvProgram) - { - _livetvManager().AddInfoToProgramDto(item, dto, fields, user); - } - return dto; } diff --git a/MediaBrowser.Server.Implementations/EntryPoints/UsageReporter.cs b/MediaBrowser.Server.Implementations/EntryPoints/UsageReporter.cs index be2817fd2..2473f3af6 100644 --- a/MediaBrowser.Server.Implementations/EntryPoints/UsageReporter.cs +++ b/MediaBrowser.Server.Implementations/EntryPoints/UsageReporter.cs @@ -57,7 +57,9 @@ namespace MediaBrowser.Server.Implementations.EntryPoints CancellationToken = cancellationToken, // Seeing block length errors - EnableHttpCompression = false + EnableHttpCompression = false, + + LogRequest = false }; options.SetPostData(data); @@ -99,7 +101,9 @@ namespace MediaBrowser.Server.Implementations.EntryPoints CancellationToken = cancellationToken, // Seeing block length errors - EnableHttpCompression = false + EnableHttpCompression = false, + + LogRequest = false }; options.SetPostData(data); diff --git a/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs b/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs index 442ab76f6..abb2710e7 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs @@ -1489,70 +1489,79 @@ namespace MediaBrowser.Server.Implementations.LiveTv }; } - public void AddInfoToProgramDto(BaseItem item, BaseItemDto dto, List fields, User user = null) + public async Task AddInfoToProgramDto(List> tuples, List fields, User user = null) { - var program = (LiveTvProgram)item; + var recordingTuples = new List>(); - dto.StartDate = program.StartDate; - dto.EpisodeTitle = program.EpisodeTitle; - - if (program.IsRepeat) - { - dto.IsRepeat = program.IsRepeat; - } - if (program.IsMovie) - { - dto.IsMovie = program.IsMovie; - } - if (program.IsSeries) - { - dto.IsSeries = program.IsSeries; - } - if (program.IsSports) - { - dto.IsSports = program.IsSports; - } - if (program.IsLive) - { - dto.IsLive = program.IsLive; - } - if (program.IsNews) - { - dto.IsNews = program.IsNews; - } - if (program.IsKids) + foreach (var tuple in tuples) { - dto.IsKids = program.IsKids; - } - if (program.IsPremiere) - { - dto.IsPremiere = program.IsPremiere; - } + var program = (LiveTvProgram)tuple.Item1; + var dto = tuple.Item2; - if (fields.Contains(ItemFields.ChannelInfo)) - { - var channel = GetInternalChannel(program.ChannelId); + dto.StartDate = program.StartDate; + dto.EpisodeTitle = program.EpisodeTitle; + + if (program.IsRepeat) + { + dto.IsRepeat = program.IsRepeat; + } + if (program.IsMovie) + { + dto.IsMovie = program.IsMovie; + } + if (program.IsSeries) + { + dto.IsSeries = program.IsSeries; + } + if (program.IsSports) + { + dto.IsSports = program.IsSports; + } + if (program.IsLive) + { + dto.IsLive = program.IsLive; + } + if (program.IsNews) + { + dto.IsNews = program.IsNews; + } + if (program.IsKids) + { + dto.IsKids = program.IsKids; + } + if (program.IsPremiere) + { + dto.IsPremiere = program.IsPremiere; + } - if (channel != null) + if (fields.Contains(ItemFields.ChannelInfo)) { - dto.ChannelName = channel.Name; - dto.MediaType = channel.MediaType; + var channel = GetInternalChannel(program.ChannelId); - if (channel.HasImage(ImageType.Primary)) + if (channel != null) { - dto.ChannelPrimaryImageTag = _tvDtoService.GetImageTag(channel); + dto.ChannelName = channel.Name; + dto.MediaType = channel.MediaType; + + if (channel.HasImage(ImageType.Primary)) + { + dto.ChannelPrimaryImageTag = _tvDtoService.GetImageTag(channel); + } } } - } - if (fields.Contains(ItemFields.ServiceName)) - { var service = GetService(program); - if (service != null) + var serviceName = service == null ? null : service.Name; + + if (fields.Contains(ItemFields.ServiceName)) { - dto.ServiceName = service.Name; + dto.ServiceName = serviceName; } + + recordingTuples.Add(new Tuple(dto, serviceName, program.ExternalId)); } + + await AddRecordingInfo(recordingTuples, CancellationToken.None).ConfigureAwait(false); } public void AddInfoToRecordingDto(BaseItem item, BaseItemDto dto, User user = null) -- cgit v1.2.3