diff options
| author | Luke <luke.pulverenti@gmail.com> | 2016-04-16 15:26:00 -0400 |
|---|---|---|
| committer | Luke <luke.pulverenti@gmail.com> | 2016-04-16 15:26:00 -0400 |
| commit | 18dbdb194b6db75c1acb5457e9797d8b37150c07 (patch) | |
| tree | f23d3d169ba1d6befcee6b0262133e778e815323 /MediaBrowser.Server.Implementations | |
| parent | 007f4e193af99036b250a8323f92b753a9b74797 (diff) | |
| parent | ed6d8ae87f95acecc4636004574b551e3dc5b0fe (diff) | |
Merge pull request #1653 from MediaBrowser/beta
Beta
Diffstat (limited to 'MediaBrowser.Server.Implementations')
104 files changed, 2039 insertions, 576 deletions
diff --git a/MediaBrowser.Server.Implementations/Activity/ActivityRepository.cs b/MediaBrowser.Server.Implementations/Activity/ActivityRepository.cs index 3a89d6928..85ab76182 100644 --- a/MediaBrowser.Server.Implementations/Activity/ActivityRepository.cs +++ b/MediaBrowser.Server.Implementations/Activity/ActivityRepository.cs @@ -9,7 +9,6 @@ using System.Collections.Generic; using System.Data; using System.Globalization; using System.IO; -using System.Threading; using System.Threading.Tasks; namespace MediaBrowser.Server.Implementations.Activity diff --git a/MediaBrowser.Server.Implementations/Channels/ChannelImageProvider.cs b/MediaBrowser.Server.Implementations/Channels/ChannelImageProvider.cs index f13c71c6d..c98f71ce2 100644 --- a/MediaBrowser.Server.Implementations/Channels/ChannelImageProvider.cs +++ b/MediaBrowser.Server.Implementations/Channels/ChannelImageProvider.cs @@ -47,7 +47,7 @@ namespace MediaBrowser.Server.Implementations.Channels return ((ChannelManager)_channelManager).GetChannelProvider(channel); } - public bool HasChanged(IHasMetadata item, MetadataStatus status, IDirectoryService directoryService) + public bool HasChanged(IHasMetadata item, IDirectoryService directoryService) { return GetSupportedImages(item).Any(i => !item.HasImage(i)); } diff --git a/MediaBrowser.Server.Implementations/Channels/ChannelManager.cs b/MediaBrowser.Server.Implementations/Channels/ChannelManager.cs index d849ce7bd..c9956c68a 100644 --- a/MediaBrowser.Server.Implementations/Channels/ChannelManager.cs +++ b/MediaBrowser.Server.Implementations/Channels/ChannelManager.cs @@ -1,5 +1,4 @@ using MediaBrowser.Common.Extensions; -using MediaBrowser.Common.IO; using MediaBrowser.Common.Net; using MediaBrowser.Controller.Channels; using MediaBrowser.Controller.Configuration; @@ -122,7 +121,7 @@ namespace MediaBrowser.Server.Implementations.Channels { try { - return (GetChannelProvider(i) is ISupportsLatestMedia) == val; + return GetChannelProvider(i) is ISupportsLatestMedia == val; } catch { @@ -403,7 +402,7 @@ namespace MediaBrowser.Server.Implementations.Channels var val = width.Value; var res = list - .OrderBy(i => (i.Width.HasValue && i.Width.Value <= val ? 0 : 1)) + .OrderBy(i => i.Width.HasValue && i.Width.Value <= val ? 0 : 1) .ThenBy(i => Math.Abs((i.Width ?? 0) - val)) .ThenByDescending(i => i.Width ?? 0) .ThenBy(list.IndexOf) @@ -1407,7 +1406,8 @@ namespace MediaBrowser.Server.Implementations.Channels throw new ArgumentNullException("channel"); } - var result = GetAllChannels().FirstOrDefault(i => string.Equals(GetInternalChannelId(i.Name).ToString("N"), channel.ChannelId, StringComparison.OrdinalIgnoreCase) || string.Equals(i.Name, channel.Name, StringComparison.OrdinalIgnoreCase)); + var result = GetAllChannels() + .FirstOrDefault(i => string.Equals(GetInternalChannelId(i.Name).ToString("N"), channel.ChannelId, StringComparison.OrdinalIgnoreCase) || string.Equals(i.Name, channel.Name, StringComparison.OrdinalIgnoreCase)); if (result == null) { diff --git a/MediaBrowser.Server.Implementations/Channels/ChannelPostScanTask.cs b/MediaBrowser.Server.Implementations/Channels/ChannelPostScanTask.cs index 08783ae8d..b25c9c818 100644 --- a/MediaBrowser.Server.Implementations/Channels/ChannelPostScanTask.cs +++ b/MediaBrowser.Server.Implementations/Channels/ChannelPostScanTask.cs @@ -44,7 +44,7 @@ namespace MediaBrowser.Server.Implementations.Channels var startingPercent = numComplete * percentPerUser * 100; var innerProgress = new ActionableProgress<double>(); - innerProgress.RegisterAction(p => progress.Report(startingPercent + (percentPerUser * p))); + innerProgress.RegisterAction(p => progress.Report(startingPercent + percentPerUser * p)); await DownloadContent(user, cancellationToken, innerProgress).ConfigureAwait(false); @@ -97,7 +97,7 @@ namespace MediaBrowser.Server.Implementations.Channels innerProgress.RegisterAction(p => { double innerPercent = startingNumberComplete; - innerPercent += (p / 100); + innerPercent += p / 100; innerPercent /= numItems; progress.Report(innerPercent * 100); }); @@ -232,9 +232,9 @@ namespace MediaBrowser.Server.Implementations.Channels innerProgress.RegisterAction(p => { double innerPercent = startingNumberComplete; - innerPercent += (p / 100); + innerPercent += p / 100; innerPercent /= numItems; - progress.Report((innerPercent * 50) + 50); + progress.Report(innerPercent * 50 + 50); }); await GetAllItems(user, channelId, folder, currentRefreshLevel + 1, maxRefreshLevel, innerProgress, cancellationToken).ConfigureAwait(false); @@ -247,7 +247,7 @@ namespace MediaBrowser.Server.Implementations.Channels numComplete++; double percent = numComplete; percent /= numItems; - progress.Report((percent * 50) + 50); + progress.Report(percent * 50 + 50); } } diff --git a/MediaBrowser.Server.Implementations/Collections/CollectionImageProvider.cs b/MediaBrowser.Server.Implementations/Collections/CollectionImageProvider.cs index 7ed0d43b1..25393d30f 100644 --- a/MediaBrowser.Server.Implementations/Collections/CollectionImageProvider.cs +++ b/MediaBrowser.Server.Implementations/Collections/CollectionImageProvider.cs @@ -1,5 +1,4 @@ using MediaBrowser.Common.Configuration; -using MediaBrowser.Common.IO; using MediaBrowser.Controller.Drawing; using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Entities.Audio; @@ -10,7 +9,6 @@ using MediaBrowser.Model.Entities; using MediaBrowser.Server.Implementations.Photos; using MoreLinq; using System.Collections.Generic; -using System.IO; using System.Linq; using System.Threading.Tasks; using CommonIO; diff --git a/MediaBrowser.Server.Implementations/Collections/CollectionManager.cs b/MediaBrowser.Server.Implementations/Collections/CollectionManager.cs index 4e742ca7a..1b6c44c5e 100644 --- a/MediaBrowser.Server.Implementations/Collections/CollectionManager.cs +++ b/MediaBrowser.Server.Implementations/Collections/CollectionManager.cs @@ -1,5 +1,4 @@ using MediaBrowser.Common.Events; -using MediaBrowser.Common.IO; using MediaBrowser.Controller.Collections; using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Entities.Movies; diff --git a/MediaBrowser.Server.Implementations/Collections/CollectionsDynamicFolder.cs b/MediaBrowser.Server.Implementations/Collections/CollectionsDynamicFolder.cs index 85b143a40..cb95bfd14 100644 --- a/MediaBrowser.Server.Implementations/Collections/CollectionsDynamicFolder.cs +++ b/MediaBrowser.Server.Implementations/Collections/CollectionsDynamicFolder.cs @@ -2,7 +2,6 @@ using MediaBrowser.Controller.Entities; using System.IO; using CommonIO; -using MediaBrowser.Common.IO; namespace MediaBrowser.Server.Implementations.Collections { diff --git a/MediaBrowser.Server.Implementations/Collections/ManualCollectionsFolder.cs b/MediaBrowser.Server.Implementations/Collections/ManualCollectionsFolder.cs index 7a1d86047..561d46229 100644 --- a/MediaBrowser.Server.Implementations/Collections/ManualCollectionsFolder.cs +++ b/MediaBrowser.Server.Implementations/Collections/ManualCollectionsFolder.cs @@ -1,5 +1,4 @@ using MediaBrowser.Controller.Entities; -using System.Linq; namespace MediaBrowser.Server.Implementations.Collections { diff --git a/MediaBrowser.Server.Implementations/Connect/ConnectEntryPoint.cs b/MediaBrowser.Server.Implementations/Connect/ConnectEntryPoint.cs index 1b951374e..ea12e332d 100644 --- a/MediaBrowser.Server.Implementations/Connect/ConnectEntryPoint.cs +++ b/MediaBrowser.Server.Implementations/Connect/ConnectEntryPoint.cs @@ -10,10 +10,8 @@ using System.IO; using System.Net; using System.Net.Sockets; using System.Text; -using System.Threading; using System.Threading.Tasks; using CommonIO; -using MediaBrowser.Common.IO; using MediaBrowser.Common.Threading; namespace MediaBrowser.Server.Implementations.Connect diff --git a/MediaBrowser.Server.Implementations/Connect/ConnectManager.cs b/MediaBrowser.Server.Implementations/Connect/ConnectManager.cs index ac0d2c569..f3d545492 100644 --- a/MediaBrowser.Server.Implementations/Connect/ConnectManager.cs +++ b/MediaBrowser.Server.Implementations/Connect/ConnectManager.cs @@ -24,6 +24,7 @@ using System.Text; using System.Threading; using System.Threading.Tasks; using CommonIO; +using MediaBrowser.Common.Extensions; namespace MediaBrowser.Server.Implementations.Connect { @@ -62,6 +63,17 @@ namespace MediaBrowser.Server.Implementations.Connect { var address = _config.Configuration.WanDdns; + if (!string.IsNullOrWhiteSpace(address)) + { + try + { + address = new Uri(address).Host; + } + catch + { + } + } + if (string.IsNullOrWhiteSpace(address) && DiscoveredWanIpAddress != null) { if (DiscoveredWanIpAddress.AddressFamily == AddressFamily.InterNetworkV6) @@ -237,8 +249,8 @@ namespace MediaBrowser.Server.Implementations.Connect var postData = new Dictionary<string, string> { - {"name", _appHost.FriendlyName}, - {"url", wanApiAddress}, + {"name", _appHost.FriendlyName}, + {"url", wanApiAddress}, {"systemId", _appHost.SystemId} }; @@ -544,9 +556,22 @@ namespace MediaBrowser.Server.Implementations.Connect } catch (HttpException ex) { - if (!ex.StatusCode.HasValue || - ex.StatusCode.Value != HttpStatusCode.NotFound || - !Validator.EmailIsValid(connectUsername)) + if (!ex.StatusCode.HasValue) + { + throw; + } + + // If they entered a username, then whatever the error is just throw it, for example, user not found + if (!Validator.EmailIsValid(connectUsername)) + { + if (ex.StatusCode.Value == HttpStatusCode.NotFound) + { + throw new ResourceNotFoundException(); + } + throw; + } + + if (ex.StatusCode.Value != HttpStatusCode.NotFound) { throw; } @@ -891,8 +916,7 @@ namespace MediaBrowser.Server.Implementations.Connect private async Task RefreshGuestNames(List<ServerUserAuthorizationResponse> list, bool refreshImages) { var users = _userManager.Users - .Where(i => !string.IsNullOrEmpty(i.ConnectUserId) && - (i.ConnectLinkType.HasValue && i.ConnectLinkType.Value == UserLinkType.Guest)) + .Where(i => !string.IsNullOrEmpty(i.ConnectUserId) && i.ConnectLinkType.HasValue && i.ConnectLinkType.Value == UserLinkType.Guest) .ToList(); foreach (var user in users) diff --git a/MediaBrowser.Server.Implementations/Devices/DeviceRepository.cs b/MediaBrowser.Server.Implementations/Devices/DeviceRepository.cs index 9e4a45253..368d21322 100644 --- a/MediaBrowser.Server.Implementations/Devices/DeviceRepository.cs +++ b/MediaBrowser.Server.Implementations/Devices/DeviceRepository.cs @@ -1,13 +1,11 @@ using MediaBrowser.Common.Configuration; using MediaBrowser.Common.Extensions; -using MediaBrowser.Common.IO; using MediaBrowser.Controller.Devices; using MediaBrowser.Model.Devices; using MediaBrowser.Model.Logging; using MediaBrowser.Model.Serialization; using MediaBrowser.Model.Session; using System; -using System.Collections.Concurrent; using System.Collections.Generic; using System.IO; using System.Linq; diff --git a/MediaBrowser.Server.Implementations/Dto/DtoService.cs b/MediaBrowser.Server.Implementations/Dto/DtoService.cs index 61465e1d7..50ae19580 100644 --- a/MediaBrowser.Server.Implementations/Dto/DtoService.cs +++ b/MediaBrowser.Server.Implementations/Dto/DtoService.cs @@ -1,5 +1,4 @@ using MediaBrowser.Common; -using MediaBrowser.Common.IO; using MediaBrowser.Controller.Channels; using MediaBrowser.Controller.Configuration; using MediaBrowser.Controller.Devices; @@ -1150,10 +1149,10 @@ namespace MediaBrowser.Server.Implementations.Dto if (fields.Contains(ItemFields.ParentId)) { - var displayParent = item.DisplayParent; - if (displayParent != null) + var displayParentId = item.DisplayParentId; + if (displayParentId.HasValue) { - dto.ParentId = GetDtoId(displayParent); + dto.ParentId = displayParentId.Value.ToString("N"); } } diff --git a/MediaBrowser.Server.Implementations/EntryPoints/ActivityLogEntryPoint.cs b/MediaBrowser.Server.Implementations/EntryPoints/ActivityLogEntryPoint.cs index dfaedbc9d..46ddf3dd8 100644 --- a/MediaBrowser.Server.Implementations/EntryPoints/ActivityLogEntryPoint.cs +++ b/MediaBrowser.Server.Implementations/EntryPoints/ActivityLogEntryPoint.cs @@ -5,11 +5,9 @@ using MediaBrowser.Common.ScheduledTasks; using MediaBrowser.Common.Updates; using MediaBrowser.Controller; using MediaBrowser.Controller.Activity; -using MediaBrowser.Controller.Channels; using MediaBrowser.Controller.Configuration; using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Library; -using MediaBrowser.Controller.LiveTv; using MediaBrowser.Controller.Localization; using MediaBrowser.Controller.Plugins; using MediaBrowser.Controller.Session; @@ -206,7 +204,7 @@ namespace MediaBrowser.Server.Implementations.EntryPoints Name = name, Type = "SessionEnded", ShortOverview = string.Format(_localization.GetLocalizedString("LabelIpAddressValue"), session.RemoteEndPoint), - UserId = (session.UserId.HasValue ? session.UserId.Value.ToString("N") : null) + UserId = session.UserId.HasValue ? session.UserId.Value.ToString("N") : null }); } @@ -336,7 +334,7 @@ namespace MediaBrowser.Server.Implementations.EntryPoints Name = name, Type = "SessionStarted", ShortOverview = string.Format(_localization.GetLocalizedString("LabelIpAddressValue"), session.RemoteEndPoint), - UserId = (session.UserId.HasValue ? session.UserId.Value.ToString("N") : null) + UserId = session.UserId.HasValue ? session.UserId.Value.ToString("N") : null }); } @@ -518,16 +516,16 @@ namespace MediaBrowser.Server.Implementations.EntryPoints int days = span.Days; if (days >= DaysInYear) { - int years = (days / DaysInYear); + int years = days / DaysInYear; values.Add(CreateValueString(years, "year")); - days = (days % DaysInYear); + days = days % DaysInYear; } // Number of months if (days >= DaysInMonth) { - int months = (days / DaysInMonth); + int months = days / DaysInMonth; values.Add(CreateValueString(months, "month")); - days = (days % DaysInMonth); + days = days % DaysInMonth; } // Number of days if (days >= 1) @@ -547,7 +545,7 @@ namespace MediaBrowser.Server.Implementations.EntryPoints for (int i = 0; i < values.Count; i++) { if (builder.Length > 0) - builder.Append((i == (values.Count - 1)) ? " and " : ", "); + builder.Append(i == values.Count - 1 ? " and " : ", "); builder.Append(values[i]); } // Return result @@ -562,7 +560,7 @@ namespace MediaBrowser.Server.Implementations.EntryPoints private static string CreateValueString(int value, string description) { return String.Format("{0:#,##0} {1}", - value, (value == 1) ? description : String.Format("{0}s", description)); + value, value == 1 ? description : String.Format("{0}s", description)); } } } diff --git a/MediaBrowser.Server.Implementations/EntryPoints/ExternalPortForwarding.cs b/MediaBrowser.Server.Implementations/EntryPoints/ExternalPortForwarding.cs index 2b2c338dd..5777a0af7 100644 --- a/MediaBrowser.Server.Implementations/EntryPoints/ExternalPortForwarding.cs +++ b/MediaBrowser.Server.Implementations/EntryPoints/ExternalPortForwarding.cs @@ -10,7 +10,6 @@ using System.Globalization; using System.IO; using System.Net; using System.Text; -using System.Threading; using MediaBrowser.Common.Threading; namespace MediaBrowser.Server.Implementations.EntryPoints @@ -51,8 +50,6 @@ namespace MediaBrowser.Server.Implementations.EntryPoints void _config_ConfigurationUpdated(object sender, EventArgs e) { - _config.ConfigurationUpdated -= _config_ConfigurationUpdated; - if (!string.Equals(_lastConfigIdentifier, GetConfigIdentifier(), StringComparison.OrdinalIgnoreCase)) { if (_isStarted) @@ -227,30 +224,5 @@ namespace MediaBrowser.Server.Implementations.EntryPoints _isStarted = false; } } - - private class LogWriter : TextWriter - { - private readonly ILogger _logger; - - public LogWriter(ILogger logger) - { - _logger = logger; - } - - public override Encoding Encoding - { - get { return Encoding.UTF8; } - } - - public override void WriteLine(string format, params object[] arg) - { - _logger.Debug(format, arg); - } - - public override void WriteLine(string value) - { - _logger.Debug(value); - } - } } -} +}
\ No newline at end of file diff --git a/MediaBrowser.Server.Implementations/EntryPoints/LibraryChangedNotifier.cs b/MediaBrowser.Server.Implementations/EntryPoints/LibraryChangedNotifier.cs index 237c7157b..afc4e9702 100644 --- a/MediaBrowser.Server.Implementations/EntryPoints/LibraryChangedNotifier.cs +++ b/MediaBrowser.Server.Implementations/EntryPoints/LibraryChangedNotifier.cs @@ -1,5 +1,4 @@ -using MediaBrowser.Controller.Channels; -using MediaBrowser.Controller.Entities; +using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Library; using MediaBrowser.Controller.Plugins; using MediaBrowser.Controller.Session; @@ -11,7 +10,6 @@ using System.Collections.Generic; using System.Linq; using System.Threading; using MediaBrowser.Controller.Entities.Audio; -using MediaBrowser.Controller.LiveTv; namespace MediaBrowser.Server.Implementations.EntryPoints { diff --git a/MediaBrowser.Server.Implementations/EntryPoints/LoadRegistrations.cs b/MediaBrowser.Server.Implementations/EntryPoints/LoadRegistrations.cs index efda36821..f41d81137 100644 --- a/MediaBrowser.Server.Implementations/EntryPoints/LoadRegistrations.cs +++ b/MediaBrowser.Server.Implementations/EntryPoints/LoadRegistrations.cs @@ -2,7 +2,6 @@ using MediaBrowser.Controller.Plugins; using MediaBrowser.Model.Logging; using System; -using System.Threading; using System.Threading.Tasks; using MediaBrowser.Common.Threading; diff --git a/MediaBrowser.Server.Implementations/EntryPoints/Notifications/Notifications.cs b/MediaBrowser.Server.Implementations/EntryPoints/Notifications/Notifications.cs index ca430eda9..71019e0ad 100644 --- a/MediaBrowser.Server.Implementations/EntryPoints/Notifications/Notifications.cs +++ b/MediaBrowser.Server.Implementations/EntryPoints/Notifications/Notifications.cs @@ -22,8 +22,7 @@ using System.Globalization; using System.Linq; using System.Threading; using System.Threading.Tasks; -using MediaBrowser.Controller.Channels; -using MediaBrowser.Controller.LiveTv; +using MediaBrowser.Controller.Entities.TV; namespace MediaBrowser.Server.Implementations.EntryPoints.Notifications { @@ -337,12 +336,17 @@ namespace MediaBrowser.Server.Implementations.EntryPoints.Notifications private bool FilterItem(BaseItem item) { - if (!item.IsFolder && item.LocationType == LocationType.Virtual) + if (item.IsFolder) { return false; } - if (item is IItemByName && !(item is MusicArtist)) + if (item.LocationType == LocationType.Virtual) + { + return false; + } + + if (item is IItemByName) { return false; } @@ -390,6 +394,18 @@ namespace MediaBrowser.Server.Implementations.EntryPoints.Notifications public static string GetItemName(BaseItem item) { var name = item.Name; + var episode = item as Episode; + if (episode != null) + { + if (episode.IndexNumber.HasValue) + { + name = string.Format("Ep{0} - {1}", episode.IndexNumber.Value.ToString(CultureInfo.InvariantCulture), name); + } + if (episode.ParentIndexNumber.HasValue) + { + name = string.Format("S{0}, {1}", episode.ParentIndexNumber.Value.ToString(CultureInfo.InvariantCulture), name); + } + } var hasSeries = item as IHasSeries; diff --git a/MediaBrowser.Server.Implementations/EntryPoints/UsageReporter.cs b/MediaBrowser.Server.Implementations/EntryPoints/UsageReporter.cs index cbec91679..7b3a7a30d 100644 --- a/MediaBrowser.Server.Implementations/EntryPoints/UsageReporter.cs +++ b/MediaBrowser.Server.Implementations/EntryPoints/UsageReporter.cs @@ -8,7 +8,6 @@ using System.Globalization; using System.Linq; using System.Threading; using System.Threading.Tasks; -using MediaBrowser.Controller.Configuration; using MediaBrowser.Model.Logging; namespace MediaBrowser.Server.Implementations.EntryPoints @@ -19,7 +18,7 @@ namespace MediaBrowser.Server.Implementations.EntryPoints private readonly IHttpClient _httpClient; private readonly IUserManager _userManager; private readonly ILogger _logger; - private const string MbAdminUrl = "http://www.mb3admin.com/admin/"; + private const string MbAdminUrl = "https://www.mb3admin.com/admin/"; public UsageReporter(IApplicationHost applicationHost, IHttpClient httpClient, IUserManager userManager, ILogger logger) { diff --git a/MediaBrowser.Server.Implementations/FileOrganization/EpisodeFileOrganizer.cs b/MediaBrowser.Server.Implementations/FileOrganization/EpisodeFileOrganizer.cs index 349e31907..e45df3f4a 100644 --- a/MediaBrowser.Server.Implementations/FileOrganization/EpisodeFileOrganizer.cs +++ b/MediaBrowser.Server.Implementations/FileOrganization/EpisodeFileOrganizer.cs @@ -1,5 +1,4 @@ -using MediaBrowser.Common.IO; -using MediaBrowser.Controller.Configuration; +using MediaBrowser.Controller.Configuration; using MediaBrowser.Controller.Entities.TV; using MediaBrowser.Controller.FileOrganization; using MediaBrowser.Controller.Library; diff --git a/MediaBrowser.Server.Implementations/FileOrganization/FileOrganizationService.cs b/MediaBrowser.Server.Implementations/FileOrganization/FileOrganizationService.cs index cf1387b0e..0e8a60612 100644 --- a/MediaBrowser.Server.Implementations/FileOrganization/FileOrganizationService.cs +++ b/MediaBrowser.Server.Implementations/FileOrganization/FileOrganizationService.cs @@ -1,5 +1,4 @@ using MediaBrowser.Common.Extensions; -using MediaBrowser.Common.IO; using MediaBrowser.Common.ScheduledTasks; using MediaBrowser.Controller.Configuration; using MediaBrowser.Controller.FileOrganization; @@ -10,7 +9,6 @@ using MediaBrowser.Model.FileOrganization; using MediaBrowser.Model.Logging; using MediaBrowser.Model.Querying; using System; -using System.IO; using System.Linq; using System.Threading; using System.Threading.Tasks; diff --git a/MediaBrowser.Server.Implementations/FileOrganization/OrganizerScheduledTask.cs b/MediaBrowser.Server.Implementations/FileOrganization/OrganizerScheduledTask.cs index ace3b5af7..de98b83ef 100644 --- a/MediaBrowser.Server.Implementations/FileOrganization/OrganizerScheduledTask.cs +++ b/MediaBrowser.Server.Implementations/FileOrganization/OrganizerScheduledTask.cs @@ -1,5 +1,4 @@ -using MediaBrowser.Common.IO; -using MediaBrowser.Common.ScheduledTasks; +using MediaBrowser.Common.ScheduledTasks; using MediaBrowser.Controller.Configuration; using MediaBrowser.Controller.FileOrganization; using MediaBrowser.Controller.Library; diff --git a/MediaBrowser.Server.Implementations/FileOrganization/TvFolderOrganizer.cs b/MediaBrowser.Server.Implementations/FileOrganization/TvFolderOrganizer.cs index 43bd2f29c..4f42d8a20 100644 --- a/MediaBrowser.Server.Implementations/FileOrganization/TvFolderOrganizer.cs +++ b/MediaBrowser.Server.Implementations/FileOrganization/TvFolderOrganizer.cs @@ -1,5 +1,4 @@ -using MediaBrowser.Common.IO; -using MediaBrowser.Controller.Configuration; +using MediaBrowser.Controller.Configuration; using MediaBrowser.Controller.FileOrganization; using MediaBrowser.Controller.Library; using MediaBrowser.Controller.Providers; @@ -91,7 +90,7 @@ namespace MediaBrowser.Server.Implementations.FileOrganization double percent = numComplete; percent /= eligibleFiles.Count; - progress.Report(10 + (89 * percent)); + progress.Report(10 + 89 * percent); } } diff --git a/MediaBrowser.Server.Implementations/HttpServer/HttpResultFactory.cs b/MediaBrowser.Server.Implementations/HttpServer/HttpResultFactory.cs index 4252d7aa8..6cedaa6a9 100644 --- a/MediaBrowser.Server.Implementations/HttpServer/HttpResultFactory.cs +++ b/MediaBrowser.Server.Implementations/HttpServer/HttpResultFactory.cs @@ -1,5 +1,4 @@ using MediaBrowser.Common.Extensions; -using MediaBrowser.Common.IO; using MediaBrowser.Controller.Net; using MediaBrowser.Model.Logging; using MediaBrowser.Model.Serialization; diff --git a/MediaBrowser.Server.Implementations/HttpServer/LoggerUtils.cs b/MediaBrowser.Server.Implementations/HttpServer/LoggerUtils.cs index 0b8caaa6e..ce8100025 100644 --- a/MediaBrowser.Server.Implementations/HttpServer/LoggerUtils.cs +++ b/MediaBrowser.Server.Implementations/HttpServer/LoggerUtils.cs @@ -1,7 +1,6 @@ using MediaBrowser.Model.Logging; using System; using System.Globalization; -using System.IO; using SocketHttpListener.Net; namespace MediaBrowser.Server.Implementations.HttpServer @@ -17,12 +16,12 @@ namespace MediaBrowser.Server.Implementations.HttpServer { var url = request.Url.ToString(); - logger.Info("{0} {1}. UserAgent: {2}", (request.IsWebSocketRequest ? "WS" : "HTTP " + request.HttpMethod), url, request.UserAgent ?? string.Empty); + logger.Info("{0} {1}. UserAgent: {2}", request.IsWebSocketRequest ? "WS" : "HTTP " + request.HttpMethod, url, request.UserAgent ?? string.Empty); } public static void LogRequest(ILogger logger, string url, string method, string userAgent) { - logger.Info("{0} {1}. UserAgent: {2}", ("HTTP " + method), url, userAgent ?? string.Empty); + logger.Info("{0} {1}. UserAgent: {2}", "HTTP " + method, url, userAgent ?? string.Empty); } /// <summary> diff --git a/MediaBrowser.Server.Implementations/HttpServer/RangeRequestWriter.cs b/MediaBrowser.Server.Implementations/HttpServer/RangeRequestWriter.cs index 9106fa059..020856886 100644 --- a/MediaBrowser.Server.Implementations/HttpServer/RangeRequestWriter.cs +++ b/MediaBrowser.Server.Implementations/HttpServer/RangeRequestWriter.cs @@ -5,8 +5,6 @@ using System.Collections.Generic; using System.Globalization; using System.IO; using System.Net; -using System.Threading; -using System.Threading.Tasks; namespace MediaBrowser.Server.Implementations.HttpServer { diff --git a/MediaBrowser.Server.Implementations/HttpServer/SocketSharp/RequestMono.cs b/MediaBrowser.Server.Implementations/HttpServer/SocketSharp/RequestMono.cs index 2c8413f5e..ed9e17b6b 100644 --- a/MediaBrowser.Server.Implementations/HttpServer/SocketSharp/RequestMono.cs +++ b/MediaBrowser.Server.Implementations/HttpServer/SocketSharp/RequestMono.cs @@ -26,7 +26,7 @@ namespace MediaBrowser.Server.Implementations.HttpServer.SocketSharp int end = header.IndexOf(ending, ap + 1); if (end == -1) - return (ending == '"') ? null : header.Substring(ap); + return ending == '"' ? null : header.Substring(ap); return header.Substring(ap + 1, end - ap - 1); } @@ -529,7 +529,7 @@ namespace MediaBrowser.Server.Implementations.HttpServer.SocketSharp { get { - return (content_type); + return content_type; } } @@ -545,7 +545,7 @@ namespace MediaBrowser.Server.Implementations.HttpServer.SocketSharp { get { - return (name); + return name; } } @@ -553,7 +553,7 @@ namespace MediaBrowser.Server.Implementations.HttpServer.SocketSharp { get { - return (stream); + return stream; } } } @@ -582,7 +582,7 @@ namespace MediaBrowser.Server.Implementations.HttpServer.SocketSharp if (l2 > l1) return false; - return (0 == String.Compare(str1, 0, str2, 0, l2, ignore_case, Helpers.InvariantCulture)); + return 0 == String.Compare(str1, 0, str2, 0, l2, ignore_case, Helpers.InvariantCulture); } public static bool EndsWith(string str1, string str2) @@ -600,7 +600,7 @@ namespace MediaBrowser.Server.Implementations.HttpServer.SocketSharp if (l2 > l1) return false; - return (0 == String.Compare(str1, l1 - l2, str2, 0, l2, ignore_case, Helpers.InvariantCulture)); + return 0 == String.Compare(str1, l1 - l2, str2, 0, l2, ignore_case, Helpers.InvariantCulture); } } @@ -676,7 +676,7 @@ namespace MediaBrowser.Server.Implementations.HttpServer.SocketSharp { break; } - got_cr = (b == CR); + got_cr = b == CR; sb.Append((char)b); } @@ -781,7 +781,7 @@ namespace MediaBrowser.Server.Implementations.HttpServer.SocketSharp } else if (state == 0) { - got_cr = (c == CR); + got_cr = c == CR; c = data.ReadByte(); } else if (state == 1 && c == '-') diff --git a/MediaBrowser.Server.Implementations/HttpServer/SocketSharp/SharpWebSocket.cs b/MediaBrowser.Server.Implementations/HttpServer/SocketSharp/SharpWebSocket.cs index a8b3bc10b..d363c4de6 100644 --- a/MediaBrowser.Server.Implementations/HttpServer/SocketSharp/SharpWebSocket.cs +++ b/MediaBrowser.Server.Implementations/HttpServer/SocketSharp/SharpWebSocket.cs @@ -2,7 +2,6 @@ using MediaBrowser.Controller.Net; using MediaBrowser.Model.Logging; using System; -using System.IO; using System.Threading; using System.Threading.Tasks; using WebSocketState = MediaBrowser.Model.Net.WebSocketState; diff --git a/MediaBrowser.Server.Implementations/HttpServer/SocketSharp/WebSocketSharpListener.cs b/MediaBrowser.Server.Implementations/HttpServer/SocketSharp/WebSocketSharpListener.cs index a029e0955..bcc081eb1 100644 --- a/MediaBrowser.Server.Implementations/HttpServer/SocketSharp/WebSocketSharpListener.cs +++ b/MediaBrowser.Server.Implementations/HttpServer/SocketSharp/WebSocketSharpListener.cs @@ -7,9 +7,7 @@ using ServiceStack.Web; using SocketHttpListener.Net; using System; using System.Collections.Generic; -using System.IO; using System.Linq; -using System.Text; using System.Threading.Tasks; namespace MediaBrowser.Server.Implementations.HttpServer.SocketSharp diff --git a/MediaBrowser.Server.Implementations/HttpServer/SocketSharp/WebSocketSharpRequest.cs b/MediaBrowser.Server.Implementations/HttpServer/SocketSharp/WebSocketSharpRequest.cs index 5df37118d..30849d441 100644 --- a/MediaBrowser.Server.Implementations/HttpServer/SocketSharp/WebSocketSharpRequest.cs +++ b/MediaBrowser.Server.Implementations/HttpServer/SocketSharp/WebSocketSharpRequest.cs @@ -2,7 +2,6 @@ using System.Collections.Generic; using System.IO; using System.Text; -using System.Web; using Funq; using MediaBrowser.Model.Logging; using ServiceStack; @@ -137,7 +136,7 @@ namespace MediaBrowser.Server.Implementations.HttpServer.SocketSharp return remoteIp ?? (remoteIp = XForwardedFor ?? (NormalizeIp(XRealIp) ?? - ((request.RemoteEndPoint != null) ? NormalizeIp(request.RemoteEndPoint.Address.ToString()) : null))); + (request.RemoteEndPoint != null ? NormalizeIp(request.RemoteEndPoint.Address.ToString()) : null))); } } diff --git a/MediaBrowser.Server.Implementations/IO/LibraryMonitor.cs b/MediaBrowser.Server.Implementations/IO/LibraryMonitor.cs index 0559e08ea..13a06afc2 100644 --- a/MediaBrowser.Server.Implementations/IO/LibraryMonitor.cs +++ b/MediaBrowser.Server.Implementations/IO/LibraryMonitor.cs @@ -1,5 +1,4 @@ -using MediaBrowser.Common.IO; -using MediaBrowser.Common.ScheduledTasks; +using MediaBrowser.Common.ScheduledTasks; using MediaBrowser.Controller.Configuration; using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Library; @@ -252,7 +251,7 @@ namespace MediaBrowser.Server.Implementations.IO /// <exception cref="System.ArgumentNullException">path</exception> private static bool ContainsParentFolder(IEnumerable<string> lst, string path) { - if (string.IsNullOrEmpty(path)) + if (string.IsNullOrWhiteSpace(path)) { throw new ArgumentNullException("path"); } @@ -264,7 +263,7 @@ namespace MediaBrowser.Server.Implementations.IO //this should be a little quicker than examining each actual parent folder... var compare = str.TrimEnd(Path.DirectorySeparatorChar); - return (path.Equals(compare, StringComparison.OrdinalIgnoreCase) || (path.StartsWith(compare, StringComparison.OrdinalIgnoreCase) && path[compare.Length] == Path.DirectorySeparatorChar)); + return path.Equals(compare, StringComparison.OrdinalIgnoreCase) || (path.StartsWith(compare, StringComparison.OrdinalIgnoreCase) && path[compare.Length] == Path.DirectorySeparatorChar); }); } diff --git a/MediaBrowser.Server.Implementations/Intros/DefaultIntroProvider.cs b/MediaBrowser.Server.Implementations/Intros/DefaultIntroProvider.cs index 2755a476c..9ebae5d91 100644 --- a/MediaBrowser.Server.Implementations/Intros/DefaultIntroProvider.cs +++ b/MediaBrowser.Server.Implementations/Intros/DefaultIntroProvider.cs @@ -1,22 +1,18 @@ using MediaBrowser.Common.Configuration; using MediaBrowser.Common.Security; -using MediaBrowser.Controller.Channels; using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Entities.Movies; using MediaBrowser.Controller.Entities.TV; using MediaBrowser.Controller.Library; using MediaBrowser.Controller.Localization; -using MediaBrowser.Model.Channels; using MediaBrowser.Model.Configuration; using MediaBrowser.Model.Entities; 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 MoreLinq; namespace MediaBrowser.Server.Implementations.Intros @@ -106,10 +102,15 @@ namespace MediaBrowser.Server.Implementations.Intros if (trailerTypes.Count > 0) { + var excludeTrailerTypes = Enum.GetNames(typeof(TrailerType)) + .Select(i => (TrailerType)Enum.Parse(typeof(TrailerType), i, true)) + .Except(trailerTypes) + .ToArray(); + var trailerResult = _libraryManager.GetItemList(new InternalItemsQuery { IncludeItemTypes = new[] { typeof(Trailer).Name }, - TrailerTypes = trailerTypes.ToArray() + ExcludeTrailerTypes = excludeTrailerTypes }); candidates.AddRange(trailerResult.Select(i => new ItemWithTrailer @@ -156,7 +157,7 @@ namespace MediaBrowser.Server.Implementations.Intros }) .OrderByDescending(i => i.Score) .ThenBy(i => Guid.NewGuid()) - .ThenByDescending(i => (i.IsPlayed ? 0 : 1)) + .ThenByDescending(i => i.IsPlayed ? 0 : 1) .Select(i => i.IntroInfo) .Take(trailerLimit) .Concat(customIntros.Take(1)) diff --git a/MediaBrowser.Server.Implementations/Library/CoreResolutionIgnoreRule.cs b/MediaBrowser.Server.Implementations/Library/CoreResolutionIgnoreRule.cs index 402fa439d..ba7e33890 100644 --- a/MediaBrowser.Server.Implementations/Library/CoreResolutionIgnoreRule.cs +++ b/MediaBrowser.Server.Implementations/Library/CoreResolutionIgnoreRule.cs @@ -1,5 +1,4 @@ using MediaBrowser.Model.Extensions; -using MediaBrowser.Common.IO; using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Library; using MediaBrowser.Controller.Resolvers; diff --git a/MediaBrowser.Server.Implementations/Library/LibraryManager.cs b/MediaBrowser.Server.Implementations/Library/LibraryManager.cs index 0e61f2969..ccba293a3 100644 --- a/MediaBrowser.Server.Implementations/Library/LibraryManager.cs +++ b/MediaBrowser.Server.Implementations/Library/LibraryManager.cs @@ -1,16 +1,13 @@ using Interfaces.IO; using MediaBrowser.Common.Extensions; -using MediaBrowser.Common.IO; using MediaBrowser.Common.Progress; using MediaBrowser.Common.ScheduledTasks; -using MediaBrowser.Controller.Channels; using MediaBrowser.Controller.Configuration; using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Entities.Audio; using MediaBrowser.Controller.Entities.TV; using MediaBrowser.Controller.IO; using MediaBrowser.Controller.Library; -using MediaBrowser.Controller.LiveTv; using MediaBrowser.Controller.Persistence; using MediaBrowser.Controller.Providers; using MediaBrowser.Controller.Resolvers; @@ -27,7 +24,6 @@ using MediaBrowser.Server.Implementations.Library.Validators; using MediaBrowser.Server.Implementations.Logging; using MediaBrowser.Server.Implementations.ScheduledTasks; using System; -using System.Collections; using System.Collections.Concurrent; using System.Collections.Generic; using System.Globalization; @@ -1183,7 +1179,7 @@ namespace MediaBrowser.Server.Implementations.Library innerProgress.RegisterAction(pct => { - double innerPercent = (currentNumComplete * 100) + pct; + double innerPercent = currentNumComplete * 100 + pct; innerPercent /= numTasks; progress.Report(innerPercent); }); @@ -1395,7 +1391,7 @@ namespace MediaBrowser.Server.Implementations.Library { if (parents.All(i => { - if ((i is ICollectionFolder) || (i is UserView)) + if (i is ICollectionFolder || i is UserView) { return true; } @@ -1498,7 +1494,7 @@ namespace MediaBrowser.Server.Implementations.Library public async Task<IEnumerable<Video>> GetIntros(BaseItem item, User user) { var tasks = IntroProviders - .OrderBy(i => (i.GetType().Name.IndexOf("Default", StringComparison.OrdinalIgnoreCase) == -1 ? 0 : 1)) + .OrderBy(i => i.GetType().Name.IndexOf("Default", StringComparison.OrdinalIgnoreCase) == -1 ? 0 : 1) .Take(1) .Select(i => GetIntros(i, item, user)); @@ -1926,7 +1922,7 @@ namespace MediaBrowser.Server.Implementations.Library if (!refresh) { - refresh = (DateTime.UtcNow - item.DateLastRefreshed) >= _viewRefreshInterval; + refresh = DateTime.UtcNow - item.DateLastRefreshed >= _viewRefreshInterval; } if (!refresh && item.DisplayParentId != Guid.Empty) @@ -1991,7 +1987,7 @@ namespace MediaBrowser.Server.Implementations.Library isNew = true; } - var refresh = isNew || (DateTime.UtcNow - item.DateLastRefreshed) >= _viewRefreshInterval; + var refresh = isNew || DateTime.UtcNow - item.DateLastRefreshed >= _viewRefreshInterval; if (!refresh && item.DisplayParentId != Guid.Empty) { @@ -2055,7 +2051,7 @@ namespace MediaBrowser.Server.Implementations.Library isNew = true; } - var refresh = isNew || (DateTime.UtcNow - item.DateLastRefreshed) >= _viewRefreshInterval; + var refresh = isNew || DateTime.UtcNow - item.DateLastRefreshed >= _viewRefreshInterval; if (!refresh && item.DisplayParentId != Guid.Empty) { @@ -2131,7 +2127,7 @@ namespace MediaBrowser.Server.Implementations.Library await item.UpdateToRepository(ItemUpdateType.MetadataEdit, cancellationToken).ConfigureAwait(false); } - var refresh = isNew || (DateTime.UtcNow - item.DateLastRefreshed) >= _viewRefreshInterval; + var refresh = isNew || DateTime.UtcNow - item.DateLastRefreshed >= _viewRefreshInterval; if (!refresh && item.DisplayParentId != Guid.Empty) { @@ -2336,7 +2332,7 @@ namespace MediaBrowser.Server.Implementations.Library var videos = videoListResolver.Resolve(fileSystemChildren.Select(i => new FileMetadata { Id = i.FullName, - IsFolder = ((i.Attributes & FileAttributes.Directory) == FileAttributes.Directory) + IsFolder = (i.Attributes & FileAttributes.Directory) == FileAttributes.Directory }).ToList()); @@ -2365,6 +2361,7 @@ namespace MediaBrowser.Server.Implementations.Library } video.ExtraType = ExtraType.Trailer; + video.TrailerTypes = new List<TrailerType> { TrailerType.LocalTrailer }; return video; @@ -2384,7 +2381,7 @@ namespace MediaBrowser.Server.Implementations.Library var videos = videoListResolver.Resolve(fileSystemChildren.Select(i => new FileMetadata { Id = i.FullName, - IsFolder = ((i.Attributes & FileAttributes.Directory) == FileAttributes.Directory) + IsFolder = (i.Attributes & FileAttributes.Directory) == FileAttributes.Directory }).ToList()); diff --git a/MediaBrowser.Server.Implementations/Library/LocalTrailerPostScanTask.cs b/MediaBrowser.Server.Implementations/Library/LocalTrailerPostScanTask.cs index 4e23b5e93..96d570ef9 100644 --- a/MediaBrowser.Server.Implementations/Library/LocalTrailerPostScanTask.cs +++ b/MediaBrowser.Server.Implementations/Library/LocalTrailerPostScanTask.cs @@ -1,10 +1,8 @@ using MediaBrowser.Controller.Channels; using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Library; -using MediaBrowser.Model.Channels; using MediaBrowser.Model.Entities; using System; -using System.Collections.Generic; using System.Linq; using System.Threading; using System.Threading.Tasks; diff --git a/MediaBrowser.Server.Implementations/Library/MediaSourceManager.cs b/MediaBrowser.Server.Implementations/Library/MediaSourceManager.cs index dfc6fc125..95f5cb0e1 100644 --- a/MediaBrowser.Server.Implementations/Library/MediaSourceManager.cs +++ b/MediaBrowser.Server.Implementations/Library/MediaSourceManager.cs @@ -11,12 +11,10 @@ using MediaBrowser.Model.Serialization; using System; using System.Collections.Concurrent; 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.Model.Configuration; namespace MediaBrowser.Server.Implementations.Library @@ -536,7 +534,7 @@ namespace MediaBrowser.Server.Implementations.Library { var infos = _openStreams .Values - .Where(i => i.EnableCloseTimer && (DateTime.UtcNow - i.Date) > _openStreamMaxAge) + .Where(i => i.EnableCloseTimer && DateTime.UtcNow - i.Date > _openStreamMaxAge) .ToList(); foreach (var info in infos) diff --git a/MediaBrowser.Server.Implementations/Library/ResolverHelper.cs b/MediaBrowser.Server.Implementations/Library/ResolverHelper.cs index 83fdd3da2..60e7e2df3 100644 --- a/MediaBrowser.Server.Implementations/Library/ResolverHelper.cs +++ b/MediaBrowser.Server.Implementations/Library/ResolverHelper.cs @@ -1,5 +1,4 @@ -using MediaBrowser.Common.IO; -using MediaBrowser.Controller.Entities; +using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Library; using MediaBrowser.Controller.Providers; using System; diff --git a/MediaBrowser.Server.Implementations/Library/Resolvers/Audio/MusicAlbumResolver.cs b/MediaBrowser.Server.Implementations/Library/Resolvers/Audio/MusicAlbumResolver.cs index 26e767c20..9f8293cb5 100644 --- a/MediaBrowser.Server.Implementations/Library/Resolvers/Audio/MusicAlbumResolver.cs +++ b/MediaBrowser.Server.Implementations/Library/Resolvers/Audio/MusicAlbumResolver.cs @@ -1,5 +1,4 @@ -using MediaBrowser.Common.IO; -using MediaBrowser.Controller.Entities.Audio; +using MediaBrowser.Controller.Entities.Audio; using MediaBrowser.Controller.Library; using MediaBrowser.Controller.Providers; using MediaBrowser.Controller.Resolvers; diff --git a/MediaBrowser.Server.Implementations/Library/Resolvers/Audio/MusicArtistResolver.cs b/MediaBrowser.Server.Implementations/Library/Resolvers/Audio/MusicArtistResolver.cs index 97a31990e..e3c991e7e 100644 --- a/MediaBrowser.Server.Implementations/Library/Resolvers/Audio/MusicArtistResolver.cs +++ b/MediaBrowser.Server.Implementations/Library/Resolvers/Audio/MusicArtistResolver.cs @@ -1,7 +1,4 @@ -using MediaBrowser.Common.IO; -using MediaBrowser.Controller.Entities.Audio; -using MediaBrowser.Controller.Entities.Movies; -using MediaBrowser.Controller.Entities.TV; +using MediaBrowser.Controller.Entities.Audio; using MediaBrowser.Controller.Library; using MediaBrowser.Controller.Resolvers; using MediaBrowser.Model.Entities; diff --git a/MediaBrowser.Server.Implementations/Library/Resolvers/Movies/MovieResolver.cs b/MediaBrowser.Server.Implementations/Library/Resolvers/Movies/MovieResolver.cs index c73470b51..37d1e163f 100644 --- a/MediaBrowser.Server.Implementations/Library/Resolvers/Movies/MovieResolver.cs +++ b/MediaBrowser.Server.Implementations/Library/Resolvers/Movies/MovieResolver.cs @@ -14,7 +14,6 @@ using System.Collections.Generic; using System.IO; using System.Linq; using CommonIO; -using MediaBrowser.Common.IO; namespace MediaBrowser.Server.Implementations.Library.Resolvers.Movies { diff --git a/MediaBrowser.Server.Implementations/Library/Resolvers/SpecialFolderResolver.cs b/MediaBrowser.Server.Implementations/Library/Resolvers/SpecialFolderResolver.cs index cde44122e..144f788a7 100644 --- a/MediaBrowser.Server.Implementations/Library/Resolvers/SpecialFolderResolver.cs +++ b/MediaBrowser.Server.Implementations/Library/Resolvers/SpecialFolderResolver.cs @@ -1,5 +1,4 @@ -using MediaBrowser.Common.IO; -using MediaBrowser.Controller; +using MediaBrowser.Controller; using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Library; using MediaBrowser.Controller.Resolvers; diff --git a/MediaBrowser.Server.Implementations/Library/Resolvers/TV/SeriesResolver.cs b/MediaBrowser.Server.Implementations/Library/Resolvers/TV/SeriesResolver.cs index 19bd4a1a3..45ba2ddbb 100644 --- a/MediaBrowser.Server.Implementations/Library/Resolvers/TV/SeriesResolver.cs +++ b/MediaBrowser.Server.Implementations/Library/Resolvers/TV/SeriesResolver.cs @@ -1,5 +1,4 @@ -using MediaBrowser.Common.IO; -using MediaBrowser.Controller.Entities.TV; +using MediaBrowser.Controller.Entities.TV; using MediaBrowser.Controller.Library; using MediaBrowser.Controller.Providers; using MediaBrowser.Controller.Resolvers; diff --git a/MediaBrowser.Server.Implementations/Library/SearchEngine.cs b/MediaBrowser.Server.Implementations/Library/SearchEngine.cs index 276fc329f..61a5d98a3 100644 --- a/MediaBrowser.Server.Implementations/Library/SearchEngine.cs +++ b/MediaBrowser.Server.Implementations/Library/SearchEngine.cs @@ -92,7 +92,7 @@ namespace MediaBrowser.Server.Implementations.Library throw new ArgumentNullException("searchTerm"); } - searchTerm = searchTerm.RemoveDiacritics(); + searchTerm = searchTerm.Trim().RemoveDiacritics(); var terms = GetWords(searchTerm); diff --git a/MediaBrowser.Server.Implementations/Library/UserManager.cs b/MediaBrowser.Server.Implementations/Library/UserManager.cs index bf09a8205..5ba83d6c7 100644 --- a/MediaBrowser.Server.Implementations/Library/UserManager.cs +++ b/MediaBrowser.Server.Implementations/Library/UserManager.cs @@ -1,6 +1,4 @@ using MediaBrowser.Common.Events; -using MediaBrowser.Common.Extensions; -using MediaBrowser.Common.IO; using MediaBrowser.Common.Net; using MediaBrowser.Controller; using MediaBrowser.Controller.Configuration; @@ -18,7 +16,6 @@ using MediaBrowser.Model.Dto; using MediaBrowser.Model.Entities; using MediaBrowser.Model.Events; using MediaBrowser.Model.Logging; -using MediaBrowser.Model.Querying; using MediaBrowser.Model.Serialization; using MediaBrowser.Model.Users; using System; @@ -263,7 +260,7 @@ namespace MediaBrowser.Server.Implementations.Library await UpdateInvalidLoginAttemptCount(user, user.Policy.InvalidLoginAttemptCount + 1).ConfigureAwait(false); } - _logger.Info("Authentication request for {0} {1}.", user.Name, (success ? "has succeeded" : "has been denied")); + _logger.Info("Authentication request for {0} {1}.", user.Name, success ? "has succeeded" : "has been denied"); return success; } diff --git a/MediaBrowser.Server.Implementations/Library/UserViewManager.cs b/MediaBrowser.Server.Implementations/Library/UserViewManager.cs index de9bec2d7..1bba20ec5 100644 --- a/MediaBrowser.Server.Implementations/Library/UserViewManager.cs +++ b/MediaBrowser.Server.Implementations/Library/UserViewManager.cs @@ -1,16 +1,13 @@ using MediaBrowser.Controller.Channels; -using MediaBrowser.Controller.Collections; using MediaBrowser.Controller.Configuration; using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Library; using MediaBrowser.Controller.LiveTv; using MediaBrowser.Controller.Localization; -using MediaBrowser.Controller.Playlists; using MediaBrowser.Model.Channels; using MediaBrowser.Model.Entities; using MediaBrowser.Model.Library; using MediaBrowser.Model.Querying; -using MoreLinq; using System; using System.Collections.Generic; using System.Linq; @@ -124,7 +121,7 @@ namespace MediaBrowser.Server.Implementations.Library var channels = channelResult.Items; - if (!user.Configuration.DisplayChannelsInline && channels.Length > 0) + if (user.Configuration.EnableChannelView && channels.Length > 0) { list.Add(await _channelManager.GetInternalChannelFolder(cancellationToken).ConfigureAwait(false)); } diff --git a/MediaBrowser.Server.Implementations/Library/Validators/ArtistsValidator.cs b/MediaBrowser.Server.Implementations/Library/Validators/ArtistsValidator.cs index 68d351b44..2b68f98ca 100644 --- a/MediaBrowser.Server.Implementations/Library/Validators/ArtistsValidator.cs +++ b/MediaBrowser.Server.Implementations/Library/Validators/ArtistsValidator.cs @@ -44,7 +44,7 @@ namespace MediaBrowser.Server.Implementations.Library.Validators public async Task Run(IProgress<double> progress, CancellationToken cancellationToken) { var allSongs = _libraryManager.RootFolder - .GetRecursiveChildren(i => !i.IsFolder && (i is IHasArtist)) + .GetRecursiveChildren(i => !i.IsFolder && i is IHasArtist) .Cast<IHasArtist>() .ToList(); diff --git a/MediaBrowser.Server.Implementations/Library/Validators/GameGenresValidator.cs b/MediaBrowser.Server.Implementations/Library/Validators/GameGenresValidator.cs index b57e128d3..826154fac 100644 --- a/MediaBrowser.Server.Implementations/Library/Validators/GameGenresValidator.cs +++ b/MediaBrowser.Server.Implementations/Library/Validators/GameGenresValidator.cs @@ -35,7 +35,7 @@ namespace MediaBrowser.Server.Implementations.Library.Validators /// <returns>Task.</returns> public async Task Run(IProgress<double> progress, CancellationToken cancellationToken) { - var items = _libraryManager.RootFolder.GetRecursiveChildren(i => (i is Game)) + var items = _libraryManager.RootFolder.GetRecursiveChildren(i => i is Game) .SelectMany(i => i.Genres) .DistinctNames() .ToList(); diff --git a/MediaBrowser.Server.Implementations/Library/Validators/MusicGenresValidator.cs b/MediaBrowser.Server.Implementations/Library/Validators/MusicGenresValidator.cs index 0a66b4b41..0c8c56f5a 100644 --- a/MediaBrowser.Server.Implementations/Library/Validators/MusicGenresValidator.cs +++ b/MediaBrowser.Server.Implementations/Library/Validators/MusicGenresValidator.cs @@ -36,7 +36,7 @@ namespace MediaBrowser.Server.Implementations.Library.Validators /// <returns>Task.</returns> public async Task Run(IProgress<double> progress, CancellationToken cancellationToken) { - var items = _libraryManager.RootFolder.GetRecursiveChildren(i => (i is IHasMusicGenres)) + var items = _libraryManager.RootFolder.GetRecursiveChildren(i => i is IHasMusicGenres) .SelectMany(i => i.Genres) .DistinctNames() .ToList(); diff --git a/MediaBrowser.Server.Implementations/Library/Validators/PeopleValidator.cs b/MediaBrowser.Server.Implementations/Library/Validators/PeopleValidator.cs index 884e1e322..5c43f2e13 100644 --- a/MediaBrowser.Server.Implementations/Library/Validators/PeopleValidator.cs +++ b/MediaBrowser.Server.Implementations/Library/Validators/PeopleValidator.cs @@ -12,7 +12,6 @@ using System.Linq; using System.Threading; using System.Threading.Tasks; using CommonIO; -using MediaBrowser.Common.IO; namespace MediaBrowser.Server.Implementations.Library.Validators { diff --git a/MediaBrowser.Server.Implementations/LiveTv/ChannelImageProvider.cs b/MediaBrowser.Server.Implementations/LiveTv/ChannelImageProvider.cs index 24d38a63e..dccc7aa93 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/ChannelImageProvider.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/ChannelImageProvider.cs @@ -77,7 +77,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv get { return 0; } } - public bool HasChanged(IHasMetadata item, MetadataStatus status, IDirectoryService directoryService) + public bool HasChanged(IHasMetadata item, IDirectoryService directoryService) { return GetSupportedImages(item).Any(i => !item.HasImage(i)); } diff --git a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs index 75186c1e1..60ff23b04 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs @@ -1,6 +1,5 @@ using MediaBrowser.Common; using MediaBrowser.Common.Configuration; -using MediaBrowser.Common.IO; using MediaBrowser.Common.Net; using MediaBrowser.Common.Security; using MediaBrowser.Controller.Configuration; @@ -10,7 +9,6 @@ using MediaBrowser.Controller.Library; using MediaBrowser.Controller.LiveTv; using MediaBrowser.Controller.MediaEncoding; using MediaBrowser.Controller.Providers; -using MediaBrowser.Model.Dlna; using MediaBrowser.Model.Dto; using MediaBrowser.Model.Entities; using MediaBrowser.Model.Events; diff --git a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EncodedRecorder.cs b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EncodedRecorder.cs index 69cc8ebf7..442f151dd 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EncodedRecorder.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EncodedRecorder.cs @@ -175,9 +175,6 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV //process.Kill(); _process.StandardInput.WriteLine("q"); - - // Need to wait because killing is asynchronous - _process.WaitForExit(5000); } catch (Exception ex) { diff --git a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/SeriesTimerManager.cs b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/SeriesTimerManager.cs index 6d88c7c0a..40e532c4e 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/SeriesTimerManager.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/SeriesTimerManager.cs @@ -3,7 +3,6 @@ using MediaBrowser.Model.Logging; using MediaBrowser.Model.Serialization; using System; using CommonIO; -using MediaBrowser.Common.IO; namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV { diff --git a/MediaBrowser.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs b/MediaBrowser.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs index 70638a8bd..ae2a85090 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs @@ -302,7 +302,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.Listings } if (string.IsNullOrWhiteSpace(channelNumber)) { - channelNumber = (map.atscMajor + "." + map.atscMinor); + channelNumber = map.atscMajor + "." + map.atscMinor; } channelNumber = channelNumber.TrimStart('0'); @@ -343,7 +343,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.Listings DateTime endAt = startAt.AddSeconds(programInfo.duration); ProgramAudio audioType = ProgramAudio.Stereo; - bool repeat = (programInfo.@new == null); + bool repeat = programInfo.@new == null; string newID = programInfo.programID + "T" + startAt.Ticks + "C" + channel; if (programInfo.audioProperties != null) @@ -633,7 +633,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.Listings if (long.TryParse(savedToken.Value, NumberStyles.Any, CultureInfo.InvariantCulture, out ticks)) { // If it's under 24 hours old we can still use it - if ((DateTime.UtcNow.Ticks - ticks) < TimeSpan.FromHours(20).Ticks) + if (DateTime.UtcNow.Ticks - ticks < TimeSpan.FromHours(20).Ticks) { return savedToken.Name; } diff --git a/MediaBrowser.Server.Implementations/LiveTv/LiveTvDtoService.cs b/MediaBrowser.Server.Implementations/LiveTv/LiveTvDtoService.cs index 7fe486de7..683377c61 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/LiveTvDtoService.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/LiveTvDtoService.cs @@ -8,10 +8,8 @@ using MediaBrowser.Controller.LiveTv; using MediaBrowser.Model.Entities; using MediaBrowser.Model.LiveTv; using MediaBrowser.Model.Logging; -using MediaBrowser.Model.Querying; using System; using System.Collections.Generic; -using System.Linq; using System.Threading; using System.Threading.Tasks; diff --git a/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs b/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs index 526de62c8..d40f2a141 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs @@ -1,7 +1,6 @@ using MediaBrowser.Common; using MediaBrowser.Common.Configuration; using MediaBrowser.Common.Extensions; -using MediaBrowser.Common.IO; using MediaBrowser.Common.Progress; using MediaBrowser.Common.ScheduledTasks; using MediaBrowser.Controller.Configuration; @@ -14,7 +13,6 @@ using MediaBrowser.Controller.Localization; using MediaBrowser.Controller.Persistence; using MediaBrowser.Controller.Providers; using MediaBrowser.Controller.Sorting; -using MediaBrowser.Model.Configuration; using MediaBrowser.Model.Dto; using MediaBrowser.Model.Entities; using MediaBrowser.Model.LiveTv; @@ -514,6 +512,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv { // 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; + mediaSource.SupportsTranscoding = true; } } @@ -1001,7 +1000,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv var channelUserdata = _userDataManager.GetUserData(userId, channel.GetUserDataKey()); - if ((channelUserdata.Likes ?? false)) + if (channelUserdata.Likes ?? false) { score += 2; } @@ -1032,7 +1031,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv { var genreUserdata = _userDataManager.GetUserData(userId, genre.GetUserDataKey()); - if ((genreUserdata.Likes ?? false)) + if (genreUserdata.Likes ?? false) { score++; } @@ -1311,7 +1310,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv const int maxPrograms = 24000; - var days = Math.Round(((double)maxPrograms) / programsPerDay); + var days = Math.Round((double)maxPrograms / programsPerDay); return Math.Max(3, Math.Min(days, MaxGuideDays)); } @@ -1415,13 +1414,13 @@ namespace MediaBrowser.Server.Implementations.LiveTv if (query.IsInProgress.HasValue) { var val = query.IsInProgress.Value; - recordings = recordings.Where(i => (i.Status == RecordingStatus.InProgress) == val); + recordings = recordings.Where(i => i.Status == RecordingStatus.InProgress == val); } if (query.Status.HasValue) { var val = query.Status.Value; - recordings = recordings.Where(i => (i.Status == val)); + recordings = recordings.Where(i => i.Status == val); } if (!string.IsNullOrEmpty(query.SeriesTimerId)) @@ -2451,7 +2450,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv public List<NameValuePair> GetSatIniMappings() { - var names = GetType().Assembly.GetManifestResourceNames().Where(i => i.IndexOf("SatIp.ini.satellite", StringComparison.OrdinalIgnoreCase) != -1).ToList(); + var names = GetType().Assembly.GetManifestResourceNames().Where(i => i.IndexOf("SatIp.ini", StringComparison.OrdinalIgnoreCase) != -1).ToList(); return names.Select(GetSatIniMappings).Where(i => i != null).DistinctBy(i => i.Value.Split('|')[0]).ToList(); } @@ -2473,13 +2472,21 @@ namespace MediaBrowser.Server.Implementations.LiveTv return null; } + var srch = "SatIp.ini."; + var filename = Path.GetFileName(resource); + return new NameValuePair { Name = satType1 + " " + satType2, - Value = satType2 + "|" + Path.GetFileName(resource) + Value = satType2 + "|" + filename.Substring(filename.IndexOf(srch) + srch.Length) }; } } } + + public Task<List<ChannelInfo>> GetSatChannelScanResult(TunerHostInfo info, CancellationToken cancellationToken) + { + return new TunerHosts.SatIp.ChannelScan(_logger).Scan(info, cancellationToken); + } } }
\ No newline at end of file diff --git a/MediaBrowser.Server.Implementations/LiveTv/ProgramImageProvider.cs b/MediaBrowser.Server.Implementations/LiveTv/ProgramImageProvider.cs index ab8ec720b..3f0538bd0 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/ProgramImageProvider.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/ProgramImageProvider.cs @@ -74,7 +74,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv } } - public bool HasChanged(IHasMetadata item, MetadataStatus status, IDirectoryService directoryService) + public bool HasChanged(IHasMetadata item, IDirectoryService directoryService) { var liveTvItem = item as LiveTvProgram; diff --git a/MediaBrowser.Server.Implementations/LiveTv/RecordingImageProvider.cs b/MediaBrowser.Server.Implementations/LiveTv/RecordingImageProvider.cs index fce3223ea..25678c29d 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/RecordingImageProvider.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/RecordingImageProvider.cs @@ -68,7 +68,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv get { return 0; } } - public bool HasChanged(IHasMetadata item, MetadataStatus status, IDirectoryService directoryService) + public bool HasChanged(IHasMetadata item, IDirectoryService directoryService) { var liveTvItem = item as ILiveTvRecording; diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/BaseTunerHost.cs b/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/BaseTunerHost.cs index fb27631e5..02a8d6938 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/BaseTunerHost.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/BaseTunerHost.cs @@ -43,7 +43,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts if (enableCache && !string.IsNullOrWhiteSpace(key) && _channelCache.TryGetValue(key, out cache)) { - if ((DateTime.UtcNow - cache.Date) < TimeSpan.FromMinutes(60)) + if (DateTime.UtcNow - cache.Date < TimeSpan.FromMinutes(60)) { return cache.Channels.ToList(); } diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs b/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs index 1995fc311..4c140602d 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs @@ -17,7 +17,6 @@ using System.Threading.Tasks; using MediaBrowser.Common.Extensions; using MediaBrowser.Controller.MediaEncoding; using MediaBrowser.Model.Configuration; -using MediaBrowser.Model.Dlna; namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.HdHomerun { @@ -60,7 +59,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.HdHomerun return id; } - protected override async Task<IEnumerable<ChannelInfo>> GetChannelsInternal(TunerHostInfo info, CancellationToken cancellationToken) + private async Task<IEnumerable<Channels>> GetLineup(TunerHostInfo info, CancellationToken cancellationToken) { var options = new HttpRequestOptions { @@ -69,29 +68,32 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.HdHomerun }; using (var stream = await _httpClient.Get(options)) { - var root = JsonSerializer.DeserializeFromStream<List<Channels>>(stream); + var lineup = JsonSerializer.DeserializeFromStream<List<Channels>>(stream) ?? new List<Channels>(); - if (root != null) + if (info.ImportFavoritesOnly) { - var result = root.Select(i => new ChannelInfo - { - Name = i.GuideName, - Number = i.GuideNumber.ToString(CultureInfo.InvariantCulture), - Id = GetChannelId(info, i), - IsFavorite = i.Favorite, - TunerHostId = info.Id + lineup = lineup.Where(i => i.Favorite).ToList(); + } - }); + return lineup.Where(i => !i.DRM).ToList(); + } + } - if (info.ImportFavoritesOnly) - { - result = result.Where(i => (i.IsFavorite ?? true)).ToList(); - } + protected override async Task<IEnumerable<ChannelInfo>> GetChannelsInternal(TunerHostInfo info, CancellationToken cancellationToken) + { + var lineup = await GetLineup(info, cancellationToken).ConfigureAwait(false); - return result; - } - return new List<ChannelInfo>(); - } + return lineup.Select(i => new ChannelInfo + { + Name = i.GuideName, + Number = i.GuideNumber.ToString(CultureInfo.InvariantCulture), + Id = GetChannelId(info, i), + IsFavorite = i.Favorite, + TunerHostId = info.Id, + IsHD = i.HD == 1, + AudioCodec = i.AudioCodec, + VideoCodec = i.VideoCodec + }); } private async Task<string> GetModelInfo(TunerHostInfo info, CancellationToken cancellationToken) @@ -227,19 +229,24 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.HdHomerun { public string GuideNumber { get; set; } public string GuideName { get; set; } + public string VideoCodec { get; set; } + public string AudioCodec { get; set; } public string URL { get; set; } public bool Favorite { get; set; } public bool DRM { get; set; } + public int HD { get; set; } } - private MediaSourceInfo GetMediaSource(TunerHostInfo info, string channelId, string profile) + private async Task<MediaSourceInfo> GetMediaSource(TunerHostInfo info, string channelId, string profile) { int? width = null; int? height = null; bool isInterlaced = true; - var videoCodec = !string.IsNullOrWhiteSpace(GetEncodingOptions().HardwareAccelerationType) ? null : "mpeg2video"; + string videoCodec = null; + string audioCodec = "ac3"; int? videoBitrate = null; + int? audioBitrate = null; if (string.Equals(profile, "mobile", StringComparison.OrdinalIgnoreCase)) { @@ -257,18 +264,10 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.HdHomerun videoCodec = "h264"; videoBitrate = 15000000; } - else if (string.Equals(profile, "internet720", StringComparison.OrdinalIgnoreCase)) - { - width = 1280; - height = 720; - isInterlaced = false; - videoCodec = "h264"; - videoBitrate = 8000000; - } else if (string.Equals(profile, "internet540", StringComparison.OrdinalIgnoreCase)) { - width = 1280; - height = 720; + width = 960; + height = 546; isInterlaced = false; videoCodec = "h264"; videoBitrate = 2500000; @@ -298,6 +297,26 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.HdHomerun videoBitrate = 1000000; } + if (string.IsNullOrWhiteSpace(videoCodec)) + { + var channels = await GetChannels(info, true, CancellationToken.None).ConfigureAwait(false); + var channel = channels.FirstOrDefault(i => string.Equals(i.Number, channelId, StringComparison.OrdinalIgnoreCase)); + if (channel != null) + { + videoCodec = channel.VideoCodec; + audioCodec = channel.AudioCodec; + + videoBitrate = (channel.IsHD ?? true) ? 15000000 : 2000000; + audioBitrate = (channel.IsHD ?? true) ? 448000 : 192000; + } + } + + // normalize + if (string.Equals(videoCodec, "mpeg2", StringComparison.OrdinalIgnoreCase)) + { + videoCodec = "mpeg2video"; + } + var url = GetApiUrl(info, true) + "/auto/v" + channelId; if (!string.IsNullOrWhiteSpace(profile) && !string.Equals(profile, "native", StringComparison.OrdinalIgnoreCase)) @@ -321,15 +340,15 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.HdHomerun Width = width, Height = height, BitRate = videoBitrate - + }, 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, - Codec = "ac3", - BitRate = 192000 + Codec = audioCodec, + BitRate = audioBitrate } }, RequiresOpening = false, @@ -338,7 +357,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.HdHomerun Container = "ts", Id = profile, SupportsDirectPlay = true, - SupportsDirectStream = true, + SupportsDirectStream = false, SupportsTranscoding = true }; @@ -365,21 +384,22 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.HdHomerun } var hdhrId = GetHdHrIdFromChannelId(channelId); - list.Add(GetMediaSource(info, hdhrId, "native")); + list.Add(await GetMediaSource(info, hdhrId, "native").ConfigureAwait(false)); try { string model = await GetModelInfo(info, cancellationToken).ConfigureAwait(false); model = model ?? string.Empty; - if (model.IndexOf("hdtc", StringComparison.OrdinalIgnoreCase) != -1) + if (info.AllowHWTranscoding && (model.IndexOf("hdtc", StringComparison.OrdinalIgnoreCase) != -1)) { - list.Insert(0, GetMediaSource(info, hdhrId, "heavy")); + list.Add(await GetMediaSource(info, hdhrId, "heavy").ConfigureAwait(false)); - list.Add(GetMediaSource(info, hdhrId, "internet480")); - list.Add(GetMediaSource(info, hdhrId, "internet360")); - list.Add(GetMediaSource(info, hdhrId, "internet240")); - list.Add(GetMediaSource(info, hdhrId, "mobile")); + list.Add(await GetMediaSource(info, hdhrId, "internet540").ConfigureAwait(false)); + list.Add(await GetMediaSource(info, hdhrId, "internet480").ConfigureAwait(false)); + list.Add(await GetMediaSource(info, hdhrId, "internet360").ConfigureAwait(false)); + list.Add(await GetMediaSource(info, hdhrId, "internet240").ConfigureAwait(false)); + list.Add(await GetMediaSource(info, hdhrId, "mobile").ConfigureAwait(false)); } } catch (Exception ex) @@ -410,7 +430,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.HdHomerun } var hdhrId = GetHdHrIdFromChannelId(channelId); - return GetMediaSource(info, hdhrId, streamId); + return await GetMediaSource(info, hdhrId, streamId).ConfigureAwait(false); } public async Task Validate(TunerHostInfo info) diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ChannelScan.cs b/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ChannelScan.cs new file mode 100644 index 000000000..fdeae25b0 --- /dev/null +++ b/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/ChannelScan.cs @@ -0,0 +1,105 @@ +using System; +using System.Collections.Generic; +using System.Globalization; +using System.IO; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; +using IniParser; +using IniParser.Model; +using MediaBrowser.Controller.LiveTv; +using MediaBrowser.Model.LiveTv; +using MediaBrowser.Model.Logging; +using MediaBrowser.Server.Implementations.LiveTv.TunerHosts.SatIp.Rtsp; + +namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.SatIp +{ + public class ChannelScan + { + private readonly ILogger _logger; + + public ChannelScan(ILogger logger) + { + _logger = logger; + } + + public async Task<List<ChannelInfo>> Scan(TunerHostInfo info, CancellationToken cancellationToken) + { + var ini = info.SourceA.Split('|')[1]; + var resource = GetType().Assembly.GetManifestResourceNames().FirstOrDefault(i => i.EndsWith(ini, StringComparison.OrdinalIgnoreCase)); + + _logger.Info("Opening ini file {0}", resource); + var list = new List<ChannelInfo>(); + + using (var stream = GetType().Assembly.GetManifestResourceStream(resource)) + { + using (var reader = new StreamReader(stream)) + { + var parser = new StreamIniDataParser(); + var data = parser.ReadData(reader); + + var count = GetInt(data, "DVB", "0", 0); + + _logger.Info("DVB Count: {0}", count); + + var index = 1; + var source = "1"; + + while (index <= count) + { + cancellationToken.ThrowIfCancellationRequested(); + + using (var rtspSession = new RtspSession(info.Url, _logger)) + { + float percent = count == 0 ? 0 : (float)(index) / count; + percent = Math.Max(percent * 100, 100); + + //SetControlPropertyThreadSafe(pgbSearchResult, "Value", (int)percent); + var strArray = data["DVB"][index.ToString(CultureInfo.InvariantCulture)].Split(','); + + string tuning; + if (strArray[4] == "S2") + { + tuning = string.Format("src={0}&freq={1}&pol={2}&sr={3}&fec={4}&msys=dvbs2&mtype={5}&plts=on&ro=0.35&pids=0,16,17,18,20", source, strArray[0], strArray[1].ToLower(), strArray[2].ToLower(), strArray[3], strArray[5].ToLower()); + } + else + { + tuning = string.Format("src={0}&freq={1}&pol={2}&sr={3}&fec={4}&msys=dvbs&mtype={5}&pids=0,16,17,18,20", source, strArray[0], strArray[1].ToLower(), strArray[2], strArray[3], strArray[5].ToLower()); + } + + rtspSession.Setup(tuning, "unicast"); + + rtspSession.Play(string.Empty); + + int signallevel; + int signalQuality; + rtspSession.Describe(out signallevel, out signalQuality); + + await Task.Delay(500).ConfigureAwait(false); + index++; + } + } + } + } + + return list; + } + + private int GetInt(IniData data, string s1, string s2, int defaultValue) + { + var value = data[s1][s2]; + int numericValue; + if (int.TryParse(value, NumberStyles.Any, CultureInfo.InvariantCulture, out numericValue)) + { + return numericValue; + } + + return defaultValue; + } + } + + public class SatChannel + { + // TODO: Add properties + } +} diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/Rtsp/RtspMethod.cs b/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/Rtsp/RtspMethod.cs new file mode 100644 index 000000000..5f286f1db --- /dev/null +++ b/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/Rtsp/RtspMethod.cs @@ -0,0 +1,88 @@ +/* + Copyright (C) <2007-2016> <Kay Diefenthal> + + SatIp.RtspSample is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + SatIp.RtspSample is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with SatIp.RtspSample. If not, see <http://www.gnu.org/licenses/>. +*/ + +using System.Collections.Generic; + +namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.SatIp.Rtsp +{ + /// <summary> + /// Standard RTSP request methods. + /// </summary> + public sealed class RtspMethod + { + public override int GetHashCode() + { + return (_name != null ? _name.GetHashCode() : 0); + } + + private readonly string _name; + private static readonly IDictionary<string, RtspMethod> _values = new Dictionary<string, RtspMethod>(); + + public static readonly RtspMethod Describe = new RtspMethod("DESCRIBE"); + public static readonly RtspMethod Announce = new RtspMethod("ANNOUNCE"); + public static readonly RtspMethod GetParameter = new RtspMethod("GET_PARAMETER"); + public static readonly RtspMethod Options = new RtspMethod("OPTIONS"); + public static readonly RtspMethod Pause = new RtspMethod("PAUSE"); + public static readonly RtspMethod Play = new RtspMethod("PLAY"); + public static readonly RtspMethod Record = new RtspMethod("RECORD"); + public static readonly RtspMethod Redirect = new RtspMethod("REDIRECT"); + public static readonly RtspMethod Setup = new RtspMethod("SETUP"); + public static readonly RtspMethod SetParameter = new RtspMethod("SET_PARAMETER"); + public static readonly RtspMethod Teardown = new RtspMethod("TEARDOWN"); + + private RtspMethod(string name) + { + _name = name; + _values.Add(name, this); + } + + public override string ToString() + { + return _name; + } + + public override bool Equals(object obj) + { + var method = obj as RtspMethod; + if (method != null && this == method) + { + return true; + } + return false; + } + + public static ICollection<RtspMethod> Values + { + get { return _values.Values; } + } + + public static explicit operator RtspMethod(string name) + { + RtspMethod value; + if (!_values.TryGetValue(name, out value)) + { + return null; + } + return value; + } + + public static implicit operator string(RtspMethod method) + { + return method._name; + } + } +} diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/Rtsp/RtspRequest.cs b/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/Rtsp/RtspRequest.cs new file mode 100644 index 000000000..600eda02d --- /dev/null +++ b/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/Rtsp/RtspRequest.cs @@ -0,0 +1,140 @@ +/* + Copyright (C) <2007-2016> <Kay Diefenthal> + + SatIp.RtspSample is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + SatIp.RtspSample is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with SatIp.RtspSample. If not, see <http://www.gnu.org/licenses/>. +*/ + +using System.Collections.Generic; +using System.Text; + +namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.SatIp.Rtsp +{ + /// <summary> + /// A simple class that can be used to serialise RTSP requests. + /// </summary> + public class RtspRequest + { + private readonly RtspMethod _method; + private readonly string _uri; + private readonly int _majorVersion; + private readonly int _minorVersion; + private IDictionary<string, string> _headers = new Dictionary<string, string>(); + private string _body = string.Empty; + + /// <summary> + /// Initialise a new instance of the <see cref="RtspRequest"/> class. + /// </summary> + /// <param name="method">The request method.</param> + /// <param name="uri">The request URI</param> + /// <param name="majorVersion">The major version number.</param> + /// <param name="minorVersion">The minor version number.</param> + public RtspRequest(RtspMethod method, string uri, int majorVersion, int minorVersion) + { + _method = method; + _uri = uri; + _majorVersion = majorVersion; + _minorVersion = minorVersion; + } + + /// <summary> + /// Get the request method. + /// </summary> + public RtspMethod Method + { + get + { + return _method; + } + } + + /// <summary> + /// Get the request URI. + /// </summary> + public string Uri + { + get + { + return _uri; + } + } + + /// <summary> + /// Get the request major version number. + /// </summary> + public int MajorVersion + { + get + { + return _majorVersion; + } + } + + /// <summary> + /// Get the request minor version number. + /// </summary> + public int MinorVersion + { + get + { + return _minorVersion; + } + } + + /// <summary> + /// Get or set the request headers. + /// </summary> + public IDictionary<string, string> Headers + { + get + { + return _headers; + } + set + { + _headers = value; + } + } + + /// <summary> + /// Get or set the request body. + /// </summary> + public string Body + { + get + { + return _body; + } + set + { + _body = value; + } + } + + /// <summary> + /// Serialise this request. + /// </summary> + /// <returns>raw request bytes</returns> + public byte[] Serialise() + { + var request = new StringBuilder(); + request.AppendFormat("{0} {1} RTSP/{2}.{3}\r\n", _method, _uri, _majorVersion, _minorVersion); + foreach (var header in _headers) + { + request.AppendFormat("{0}: {1}\r\n", header.Key, header.Value); + } + request.AppendFormat("\r\n{0}", _body); + return Encoding.UTF8.GetBytes(request.ToString()); + } + } +} diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/Rtsp/RtspResponse.cs b/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/Rtsp/RtspResponse.cs new file mode 100644 index 000000000..97290623b --- /dev/null +++ b/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/Rtsp/RtspResponse.cs @@ -0,0 +1,149 @@ +/* + Copyright (C) <2007-2016> <Kay Diefenthal> + + SatIp.RtspSample is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + SatIp.RtspSample is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with SatIp.RtspSample. If not, see <http://www.gnu.org/licenses/>. +*/ + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Text.RegularExpressions; + +namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.SatIp.Rtsp +{ + /// <summary> + /// A simple class that can be used to deserialise RTSP responses. + /// </summary> + public class RtspResponse + { + private static readonly Regex RegexStatusLine = new Regex(@"RTSP/(\d+)\.(\d+)\s+(\d+)\s+([^.]+?)\r\n(.*)", RegexOptions.Singleline); + + private int _majorVersion = 1; + private int _minorVersion; + private RtspStatusCode _statusCode; + private string _reasonPhrase; + private IDictionary<string, string> _headers; + private string _body; + + /// <summary> + /// Initialise a new instance of the <see cref="RtspResponse"/> class. + /// </summary> + private RtspResponse() + { + } + + /// <summary> + /// Get the response major version number. + /// </summary> + public int MajorVersion + { + get + { + return _majorVersion; + } + } + + /// <summary> + /// Get the response minor version number. + /// </summary> + public int MinorVersion + { + get + { + return _minorVersion; + } + } + + /// <summary> + /// Get the response status code. + /// </summary> + public RtspStatusCode StatusCode + { + get + { + return _statusCode; + } + } + + /// <summary> + /// Get the response reason phrase. + /// </summary> + public string ReasonPhrase + { + get + { + return _reasonPhrase; + } + } + + /// <summary> + /// Get the response headers. + /// </summary> + public IDictionary<string, string> Headers + { + get + { + return _headers; + } + } + + /// <summary> + /// Get the response body. + /// </summary> + public string Body + { + get + { + return _body; + } + set + { + _body = value; + } + } + + /// <summary> + /// Deserialise/parse an RTSP response. + /// </summary> + /// <param name="responseBytes">The raw response bytes.</param> + /// <param name="responseByteCount">The number of valid bytes in the response.</param> + /// <returns>a response object</returns> + public static RtspResponse Deserialise(byte[] responseBytes, int responseByteCount) + { + var response = new RtspResponse(); + var responseString = Encoding.UTF8.GetString(responseBytes, 0, responseByteCount); + + var m = RegexStatusLine.Match(responseString); + if (m.Success) + { + response._majorVersion = int.Parse(m.Groups[1].Captures[0].Value); + response._minorVersion = int.Parse(m.Groups[2].Captures[0].Value); + response._statusCode = (RtspStatusCode)int.Parse(m.Groups[3].Captures[0].Value); + response._reasonPhrase = m.Groups[4].Captures[0].Value; + responseString = m.Groups[5].Captures[0].Value; + } + + var sections = responseString.Split(new[] { "\r\n\r\n" }, StringSplitOptions.None); + response._body = sections[1]; + var headers = sections[0].Split(new[] { "\r\n" }, StringSplitOptions.None); + response._headers = new Dictionary<string, string>(); + foreach (var headerInfo in headers.Select(header => header.Split(':'))) + { + response._headers.Add(headerInfo[0], headerInfo[1].Trim()); + } + return response; + } + } +} diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/Rtsp/RtspSession.cs b/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/Rtsp/RtspSession.cs new file mode 100644 index 000000000..71b3f8a18 --- /dev/null +++ b/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/Rtsp/RtspSession.cs @@ -0,0 +1,688 @@ +/* + Copyright (C) <2007-2016> <Kay Diefenthal> + + SatIp.RtspSample is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + SatIp.RtspSample is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with SatIp.RtspSample. If not, see <http://www.gnu.org/licenses/>. +*/ + +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Linq; +using System.Net; +using System.Net.NetworkInformation; +using System.Net.Sockets; +using System.Text.RegularExpressions; +using MediaBrowser.Model.Logging; + +namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.SatIp.Rtsp +{ + public class RtspSession : IDisposable + { + #region Private Fields + private static readonly Regex RegexRtspSessionHeader = new Regex(@"\s*([^\s;]+)(;timeout=(\d+))?"); + private const int DefaultRtspSessionTimeout = 30; // unit = s + private static readonly Regex RegexDescribeResponseSignalInfo = new Regex(@";tuner=\d+,(\d+),(\d+),(\d+),", RegexOptions.Singleline | RegexOptions.IgnoreCase); + private string _address; + private string _rtspSessionId; + + public string RtspSessionId + { + get { return _rtspSessionId; } + set { _rtspSessionId = value; } + } + private int _rtspSessionTimeToLive = 0; + private string _rtspStreamId; + private int _clientRtpPort; + private int _clientRtcpPort; + private int _serverRtpPort; + private int _serverRtcpPort; + private int _rtpPort; + private int _rtcpPort; + private string _rtspStreamUrl; + private string _destination; + private string _source; + private string _transport; + private int _signalLevel; + private int _signalQuality; + private Socket _rtspSocket; + private int _rtspSequenceNum = 1; + private bool _disposed = false; + private readonly ILogger _logger; + #endregion + + #region Constructor + + public RtspSession(string address, ILogger logger) + { + if (string.IsNullOrWhiteSpace(address)) + { + throw new ArgumentNullException("address"); + } + + _address = address; + _logger = logger; + + _logger.Info("Creating RtspSession with url {0}", address); + } + ~RtspSession() + { + Dispose(false); + } + #endregion + + #region Properties + + #region Rtsp + + public string RtspStreamId + { + get { return _rtspStreamId; } + set { if (_rtspStreamId != value) { _rtspStreamId = value; OnPropertyChanged("RtspStreamId"); } } + } + public string RtspStreamUrl + { + get { return _rtspStreamUrl; } + set { if (_rtspStreamUrl != value) { _rtspStreamUrl = value; OnPropertyChanged("RtspStreamUrl"); } } + } + + public int RtspSessionTimeToLive + { + get + { + if (_rtspSessionTimeToLive == 0) + _rtspSessionTimeToLive = DefaultRtspSessionTimeout; + return _rtspSessionTimeToLive * 1000 - 20; + } + set { if (_rtspSessionTimeToLive != value) { _rtspSessionTimeToLive = value; OnPropertyChanged("RtspSessionTimeToLive"); } } + } + + #endregion + + #region Rtp Rtcp + + /// <summary> + /// The LocalEndPoint Address + /// </summary> + public string Destination + { + get + { + if (string.IsNullOrEmpty(_destination)) + { + var result = ""; + var host = Dns.GetHostName(); + var hostentry = Dns.GetHostEntry(host); + foreach (var ip in hostentry.AddressList.Where(ip => ip.AddressFamily == AddressFamily.InterNetwork)) + { + result = ip.ToString(); + } + + _destination = result; + } + return _destination; + } + set + { + if (_destination != value) + { + _destination = value; + OnPropertyChanged("Destination"); + } + } + } + + /// <summary> + /// The RemoteEndPoint Address + /// </summary> + public string Source + { + get { return _source; } + set + { + if (_source != value) + { + _source = value; + OnPropertyChanged("Source"); + } + } + } + + /// <summary> + /// The Media Data Delivery RemoteEndPoint Port if we use Unicast + /// </summary> + public int ServerRtpPort + { + get + { + return _serverRtpPort; + } + set { if (_serverRtpPort != value) { _serverRtpPort = value; OnPropertyChanged("ServerRtpPort"); } } + } + + /// <summary> + /// The Media Metadata Delivery RemoteEndPoint Port if we use Unicast + /// </summary> + public int ServerRtcpPort + { + get { return _serverRtcpPort; } + set { if (_serverRtcpPort != value) { _serverRtcpPort = value; OnPropertyChanged("ServerRtcpPort"); } } + } + + /// <summary> + /// The Media Data Delivery LocalEndPoint Port if we use Unicast + /// </summary> + public int ClientRtpPort + { + get { return _clientRtpPort; } + set { if (_clientRtpPort != value) { _clientRtpPort = value; OnPropertyChanged("ClientRtpPort"); } } + } + + /// <summary> + /// The Media Metadata Delivery LocalEndPoint Port if we use Unicast + /// </summary> + public int ClientRtcpPort + { + get { return _clientRtcpPort; } + set { if (_clientRtcpPort != value) { _clientRtcpPort = value; OnPropertyChanged("ClientRtcpPort"); } } + } + + /// <summary> + /// The Media Data Delivery RemoteEndPoint Port if we use Multicast + /// </summary> + public int RtpPort + { + get { return _rtpPort; } + set { if (_rtpPort != value) { _rtpPort = value; OnPropertyChanged("RtpPort"); } } + } + + /// <summary> + /// The Media Meta Delivery RemoteEndPoint Port if we use Multicast + /// </summary> + public int RtcpPort + { + get { return _rtcpPort; } + set { if (_rtcpPort != value) { _rtcpPort = value; OnPropertyChanged("RtcpPort"); } } + } + + #endregion + + public string Transport + { + get + { + if (string.IsNullOrEmpty(_transport)) + { + _transport = "unicast"; + } + return _transport; + } + set + { + if (_transport != value) + { + _transport = value; + OnPropertyChanged("Transport"); + } + } + } + public int SignalLevel + { + get { return _signalLevel; } + set { if (_signalLevel != value) { _signalLevel = value; OnPropertyChanged("SignalLevel"); } } + } + public int SignalQuality + { + get { return _signalQuality; } + set { if (_signalQuality != value) { _signalQuality = value; OnPropertyChanged("SignalQuality"); } } + } + + #endregion + + #region Private Methods + + private void ProcessSessionHeader(string sessionHeader, string response) + { + if (!string.IsNullOrEmpty(sessionHeader)) + { + var m = RegexRtspSessionHeader.Match(sessionHeader); + if (!m.Success) + { + _logger.Error("Failed to tune, RTSP {0} response session header {1} format not recognised", response, sessionHeader); + } + _rtspSessionId = m.Groups[1].Captures[0].Value; + _rtspSessionTimeToLive = m.Groups[3].Captures.Count == 1 ? int.Parse(m.Groups[3].Captures[0].Value) : DefaultRtspSessionTimeout; + } + } + private void ProcessTransportHeader(string transportHeader) + { + if (!string.IsNullOrEmpty(transportHeader)) + { + var transports = transportHeader.Split(','); + foreach (var transport in transports) + { + if (transport.Trim().StartsWith("RTP/AVP")) + { + var sections = transport.Split(';'); + foreach (var section in sections) + { + var parts = section.Split('='); + if (parts[0].Equals("server_port")) + { + var ports = parts[1].Split('-'); + _serverRtpPort = int.Parse(ports[0]); + _serverRtcpPort = int.Parse(ports[1]); + } + else if (parts[0].Equals("destination")) + { + _destination = parts[1]; + } + else if (parts[0].Equals("port")) + { + var ports = parts[1].Split('-'); + _rtpPort = int.Parse(ports[0]); + _rtcpPort = int.Parse(ports[1]); + } + else if (parts[0].Equals("ttl")) + { + _rtspSessionTimeToLive = int.Parse(parts[1]); + } + else if (parts[0].Equals("source")) + { + _source = parts[1]; + } + else if (parts[0].Equals("client_port")) + { + var ports = parts[1].Split('-'); + var rtp = int.Parse(ports[0]); + var rtcp = int.Parse(ports[1]); + //if (!rtp.Equals(_rtpPort)) + //{ + // Logger.Error("SAT>IP base: server specified RTP client port {0} instead of {1}", rtp, _rtpPort); + //} + //if (!rtcp.Equals(_rtcpPort)) + //{ + // Logger.Error("SAT>IP base: server specified RTCP client port {0} instead of {1}", rtcp, _rtcpPort); + //} + _rtpPort = rtp; + _rtcpPort = rtcp; + } + } + } + } + } + } + private void Connect() + { + _rtspSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); + var ip = IPAddress.Parse(_address); + var rtspEndpoint = new IPEndPoint(ip, 554); + _rtspSocket.Connect(rtspEndpoint); + } + private void Disconnect() + { + if (_rtspSocket != null && _rtspSocket.Connected) + { + _rtspSocket.Shutdown(SocketShutdown.Both); + _rtspSocket.Close(); + } + } + private void SendRequest(RtspRequest request) + { + if (_rtspSocket == null) + { + Connect(); + } + try + { + request.Headers.Add("CSeq", _rtspSequenceNum.ToString()); + _rtspSequenceNum++; + byte[] requestBytes = request.Serialise(); + if (_rtspSocket != null) + { + var requestBytesCount = _rtspSocket.Send(requestBytes, requestBytes.Length, SocketFlags.None); + if (requestBytesCount < 1) + { + + } + } + } + catch (Exception e) + { + _logger.Error(e.Message); + } + } + private void ReceiveResponse(out RtspResponse response) + { + response = null; + var responseBytesCount = 0; + byte[] responseBytes = new byte[1024]; + try + { + responseBytesCount = _rtspSocket.Receive(responseBytes, responseBytes.Length, SocketFlags.None); + response = RtspResponse.Deserialise(responseBytes, responseBytesCount); + string contentLengthString; + int contentLength = 0; + if (response.Headers.TryGetValue("Content-Length", out contentLengthString)) + { + contentLength = int.Parse(contentLengthString); + if ((string.IsNullOrEmpty(response.Body) && contentLength > 0) || response.Body.Length < contentLength) + { + if (response.Body == null) + { + response.Body = string.Empty; + } + while (responseBytesCount > 0 && response.Body.Length < contentLength) + { + responseBytesCount = _rtspSocket.Receive(responseBytes, responseBytes.Length, SocketFlags.None); + response.Body += System.Text.Encoding.UTF8.GetString(responseBytes, 0, responseBytesCount); + } + } + } + } + catch (SocketException) + { + } + } + + #endregion + + #region Public Methods + + public RtspStatusCode Setup(string query, string transporttype) + { + + RtspRequest request; + RtspResponse response; + //_rtspClient = new RtspClient(_rtspDevice.ServerAddress); + if ((_rtspSocket == null)) + { + Connect(); + } + if (string.IsNullOrEmpty(_rtspSessionId)) + { + request = new RtspRequest(RtspMethod.Setup, string.Format("rtsp://{0}:{1}/?{2}", _address, 554, query), 1, 0); + switch (transporttype) + { + case "multicast": + request.Headers.Add("Transport", string.Format("RTP/AVP;multicast")); + break; + case "unicast": + var activeTcpConnections = IPGlobalProperties.GetIPGlobalProperties().GetActiveTcpConnections(); + var usedPorts = new HashSet<int>(); + foreach (var connection in activeTcpConnections) + { + usedPorts.Add(connection.LocalEndPoint.Port); + } + for (var port = 40000; port <= 65534; port += 2) + { + if (!usedPorts.Contains(port) && !usedPorts.Contains(port + 1)) + { + + _clientRtpPort = port; + _clientRtcpPort = port + 1; + break; + } + } + request.Headers.Add("Transport", string.Format("RTP/AVP;unicast;client_port={0}-{1}", _clientRtpPort, _clientRtcpPort)); + break; + } + } + else + { + request = new RtspRequest(RtspMethod.Setup, string.Format("rtsp://{0}:{1}/?{2}", _address, 554, query), 1, 0); + switch (transporttype) + { + case "multicast": + request.Headers.Add("Transport", string.Format("RTP/AVP;multicast")); + break; + case "unicast": + request.Headers.Add("Transport", string.Format("RTP/AVP;unicast;client_port={0}-{1}", _clientRtpPort, _clientRtcpPort)); + break; + } + + } + SendRequest(request); + ReceiveResponse(out response); + + //if (_rtspClient.SendRequest(request, out response) != RtspStatusCode.Ok) + //{ + // Logger.Error("Failed to tune, non-OK RTSP SETUP status code {0} {1}", response.StatusCode, response.ReasonPhrase); + //} + if (!response.Headers.TryGetValue("com.ses.streamID", out _rtspStreamId)) + { + _logger.Error(string.Format("Failed to tune, not able to locate Stream ID header in RTSP SETUP response")); + } + string sessionHeader; + if (!response.Headers.TryGetValue("Session", out sessionHeader)) + { + _logger.Error(string.Format("Failed to tune, not able to locate Session header in RTSP SETUP response")); + } + ProcessSessionHeader(sessionHeader, "Setup"); + string transportHeader; + if (!response.Headers.TryGetValue("Transport", out transportHeader)) + { + _logger.Error(string.Format("Failed to tune, not able to locate Transport header in RTSP SETUP response")); + } + ProcessTransportHeader(transportHeader); + return response.StatusCode; + } + + public RtspStatusCode Play(string query) + { + if ((_rtspSocket == null)) + { + Connect(); + } + //_rtspClient = new RtspClient(_rtspDevice.ServerAddress); + RtspResponse response; + string data; + if (string.IsNullOrEmpty(query)) + { + data = string.Format("rtsp://{0}:{1}/stream={2}", _address, + 554, _rtspStreamId); + } + else + { + data = string.Format("rtsp://{0}:{1}/stream={2}?{3}", _address, + 554, _rtspStreamId, query); + } + var request = new RtspRequest(RtspMethod.Play, data, 1, 0); + request.Headers.Add("Session", _rtspSessionId); + SendRequest(request); + ReceiveResponse(out response); + //if (_rtspClient.SendRequest(request, out response) != RtspStatusCode.Ok) + //{ + // Logger.Error("Failed to tune, non-OK RTSP SETUP status code {0} {1}", response.StatusCode, response.ReasonPhrase); + //} + //Logger.Info("RtspSession-Play : \r\n {0}", response); + string sessionHeader; + if (!response.Headers.TryGetValue("Session", out sessionHeader)) + { + _logger.Error(string.Format("Failed to tune, not able to locate Session header in RTSP Play response")); + } + ProcessSessionHeader(sessionHeader, "Play"); + string rtpinfoHeader; + if (!response.Headers.TryGetValue("RTP-Info", out rtpinfoHeader)) + { + _logger.Error(string.Format("Failed to tune, not able to locate Rtp-Info header in RTSP Play response")); + } + return response.StatusCode; + } + + public RtspStatusCode Options() + { + if ((_rtspSocket == null)) + { + Connect(); + } + //_rtspClient = new RtspClient(_rtspDevice.ServerAddress); + RtspRequest request; + RtspResponse response; + + + if (string.IsNullOrEmpty(_rtspSessionId)) + { + request = new RtspRequest(RtspMethod.Options, string.Format("rtsp://{0}:{1}/", _address, 554), 1, 0); + } + else + { + request = new RtspRequest(RtspMethod.Options, string.Format("rtsp://{0}:{1}/", _address, 554), 1, 0); + request.Headers.Add("Session", _rtspSessionId); + } + SendRequest(request); + ReceiveResponse(out response); + //if (_rtspClient.SendRequest(request, out response) != RtspStatusCode.Ok) + //{ + // Logger.Error("Failed to tune, non-OK RTSP SETUP status code {0} {1}", response.StatusCode, response.ReasonPhrase); + //} + //Logger.Info("RtspSession-Options : \r\n {0}", response); + string sessionHeader; + if (!response.Headers.TryGetValue("Session", out sessionHeader)) + { + _logger.Error(string.Format("Failed to tune, not able to locate session header in RTSP Options response")); + } + ProcessSessionHeader(sessionHeader, "Options"); + string optionsHeader; + if (!response.Headers.TryGetValue("Public", out optionsHeader)) + { + _logger.Error(string.Format("Failed to tune, not able to Options header in RTSP Options response")); + } + return response.StatusCode; + } + + public RtspStatusCode Describe(out int level, out int quality) + { + if ((_rtspSocket == null)) + { + Connect(); + } + //_rtspClient = new RtspClient(_rtspDevice.ServerAddress); + RtspRequest request; + RtspResponse response; + level = 0; + quality = 0; + + if (string.IsNullOrEmpty(_rtspSessionId)) + { + request = new RtspRequest(RtspMethod.Describe, string.Format("rtsp://{0}:{1}/", _address, 554), 1, 0); + request.Headers.Add("Accept", "application/sdp"); + + } + else + { + request = new RtspRequest(RtspMethod.Describe, string.Format("rtsp://{0}:{1}/stream={2}", _address, 554, _rtspStreamId), 1, 0); + request.Headers.Add("Accept", "application/sdp"); + request.Headers.Add("Session", _rtspSessionId); + } + SendRequest(request); + ReceiveResponse(out response); + //if (_rtspClient.SendRequest(request, out response) != RtspStatusCode.Ok) + //{ + // Logger.Error("Failed to tune, non-OK RTSP Describe status code {0} {1}", response.StatusCode, response.ReasonPhrase); + //} + //Logger.Info("RtspSession-Describe : \r\n {0}", response); + string sessionHeader; + if (!response.Headers.TryGetValue("Session", out sessionHeader)) + { + _logger.Error(string.Format("Failed to tune, not able to locate session header in RTSP Describe response")); + } + ProcessSessionHeader(sessionHeader, "Describe"); + var m = RegexDescribeResponseSignalInfo.Match(response.Body); + if (m.Success) + { + + //isSignalLocked = m.Groups[2].Captures[0].Value.Equals("1"); + level = int.Parse(m.Groups[1].Captures[0].Value) * 100 / 255; // level: 0..255 => 0..100 + quality = int.Parse(m.Groups[3].Captures[0].Value) * 100 / 15; // quality: 0..15 => 0..100 + + } + /* + v=0 + o=- 1378633020884883 1 IN IP4 192.168.2.108 + s=SatIPServer:1 4 + t=0 0 + a=tool:idl4k + m=video 52780 RTP/AVP 33 + c=IN IP4 0.0.0.0 + b=AS:5000 + a=control:stream=4 + a=fmtp:33 ver=1.0;tuner=1,0,0,0,12344,h,dvbs2,,off,,22000,34;pids=0,100,101,102,103,106 + =sendonly + */ + + + return response.StatusCode; + } + + public RtspStatusCode TearDown() + { + if ((_rtspSocket == null)) + { + Connect(); + } + //_rtspClient = new RtspClient(_rtspDevice.ServerAddress); + RtspResponse response; + + var request = new RtspRequest(RtspMethod.Teardown, string.Format("rtsp://{0}:{1}/stream={2}", _address, 554, _rtspStreamId), 1, 0); + request.Headers.Add("Session", _rtspSessionId); + SendRequest(request); + ReceiveResponse(out response); + //if (_rtspClient.SendRequest(request, out response) != RtspStatusCode.Ok) + //{ + // Logger.Error("Failed to tune, non-OK RTSP Teardown status code {0} {1}", response.StatusCode, response.ReasonPhrase); + //} + return response.StatusCode; + } + + #endregion + + #region Public Events + + public event PropertyChangedEventHandler PropertyChanged; + + #endregion + + #region Protected Methods + + protected void OnPropertyChanged(string name) + { + //var handler = PropertyChanged; + //if (handler != null) + //{ + // handler(this, new PropertyChangedEventArgs(name)); + //} + } + + #endregion + + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this);//Disconnect(); + } + + protected virtual void Dispose(bool disposing) + { + if (!_disposed) + { + if (disposing) + { + TearDown(); + Disconnect(); + } + } + _disposed = true; + } + } +} diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/Rtsp/RtspStatusCode.cs b/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/Rtsp/RtspStatusCode.cs new file mode 100644 index 000000000..6d6d50623 --- /dev/null +++ b/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/Rtsp/RtspStatusCode.cs @@ -0,0 +1,251 @@ +/* + Copyright (C) <2007-2016> <Kay Diefenthal> + + SatIp.RtspSample is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + SatIp.RtspSample is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with SatIp.RtspSample. If not, see <http://www.gnu.org/licenses/>. +*/ + +using System.ComponentModel; + +namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.SatIp.Rtsp +{ + /// <summary> + /// Standard RTSP status codes. + /// </summary> + public enum RtspStatusCode + { + /// <summary> + /// 100 continue + /// </summary> + Continue = 100, + + /// <summary> + /// 200 OK + /// </summary> + [Description("Okay")] + Ok = 200, + /// <summary> + /// 201 created + /// </summary> + Created = 201, + + /// <summary> + /// 250 low on storage space + /// </summary> + [Description("Low On Storage Space")] + LowOnStorageSpace = 250, + + /// <summary> + /// 300 multiple choices + /// </summary> + [Description("Multiple Choices")] + MultipleChoices = 300, + /// <summary> + /// 301 moved permanently + /// </summary> + [Description("Moved Permanently")] + MovedPermanently = 301, + /// <summary> + /// 302 moved temporarily + /// </summary> + [Description("Moved Temporarily")] + MovedTemporarily = 302, + /// <summary> + /// 303 see other + /// </summary> + [Description("See Other")] + SeeOther = 303, + /// <summary> + /// 304 not modified + /// </summary> + [Description("Not Modified")] + NotModified = 304, + /// <summary> + /// 305 use proxy + /// </summary> + [Description("Use Proxy")] + UseProxy = 305, + + /// <summary> + /// 400 bad request + /// </summary> + [Description("Bad Request")] + BadRequest = 400, + /// <summary> + /// 401 unauthorised + /// </summary> + Unauthorised = 401, + /// <summary> + /// 402 payment required + /// </summary> + [Description("Payment Required")] + PaymentRequired = 402, + /// <summary> + /// 403 forbidden + /// </summary> + Forbidden = 403, + /// <summary> + /// 404 not found + /// </summary> + [Description("Not Found")] + NotFound = 404, + /// <summary> + /// 405 method not allowed + /// </summary> + [Description("Method Not Allowed")] + MethodNotAllowed = 405, + /// <summary> + /// 406 not acceptable + /// </summary> + [Description("Not Acceptable")] + NotAcceptable = 406, + /// <summary> + /// 407 proxy authentication required + /// </summary> + [Description("Proxy Authentication Required")] + ProxyAuthenticationRequred = 407, + /// <summary> + /// 408 request time-out + /// </summary> + [Description("Request Time-Out")] + RequestTimeOut = 408, + + /// <summary> + /// 410 gone + /// </summary> + Gone = 410, + /// <summary> + /// 411 length required + /// </summary> + [Description("Length Required")] + LengthRequired = 411, + /// <summary> + /// 412 precondition failed + /// </summary> + [Description("Precondition Failed")] + PreconditionFailed = 412, + /// <summary> + /// 413 request entity too large + /// </summary> + [Description("Request Entity Too Large")] + RequestEntityTooLarge = 413, + /// <summary> + /// 414 request URI too large + /// </summary> + [Description("Request URI Too Large")] + RequestUriTooLarge = 414, + /// <summary> + /// 415 unsupported media type + /// </summary> + [Description("Unsupported Media Type")] + UnsupportedMediaType = 415, + + /// <summary> + /// 451 parameter not understood + /// </summary> + [Description("Parameter Not Understood")] + ParameterNotUnderstood = 451, + /// <summary> + /// 452 conference not found + /// </summary> + [Description("Conference Not Found")] + ConferenceNotFound = 452, + /// <summary> + /// 453 not enough bandwidth + /// </summary> + [Description("Not Enough Bandwidth")] + NotEnoughBandwidth = 453, + /// <summary> + /// 454 session not found + /// </summary> + [Description("Session Not Found")] + SessionNotFound = 454, + /// <summary> + /// 455 method not valid in this state + /// </summary> + [Description("Method Not Valid In This State")] + MethodNotValidInThisState = 455, + /// <summary> + /// 456 header field not valid for this resource + /// </summary> + [Description("Header Field Not Valid For This Resource")] + HeaderFieldNotValidForThisResource = 456, + /// <summary> + /// 457 invalid range + /// </summary> + [Description("Invalid Range")] + InvalidRange = 457, + /// <summary> + /// 458 parameter is read-only + /// </summary> + [Description("Parameter Is Read-Only")] + ParameterIsReadOnly = 458, + /// <summary> + /// 459 aggregate operation not allowed + /// </summary> + [Description("Aggregate Operation Not Allowed")] + AggregateOperationNotAllowed = 459, + /// <summary> + /// 460 only aggregate operation allowed + /// </summary> + [Description("Only Aggregate Operation Allowed")] + OnlyAggregateOperationAllowed = 460, + /// <summary> + /// 461 unsupported transport + /// </summary> + [Description("Unsupported Transport")] + UnsupportedTransport = 461, + /// <summary> + /// 462 destination unreachable + /// </summary> + [Description("Destination Unreachable")] + DestinationUnreachable = 462, + + /// <summary> + /// 500 internal server error + /// </summary> + [Description("Internal Server Error")] + InternalServerError = 500, + /// <summary> + /// 501 not implemented + /// </summary> + [Description("Not Implemented")] + NotImplemented = 501, + /// <summary> + /// 502 bad gateway + /// </summary> + [Description("Bad Gateway")] + BadGateway = 502, + /// <summary> + /// 503 service unavailable + /// </summary> + [Description("Service Unavailable")] + ServiceUnavailable = 503, + /// <summary> + /// 504 gateway time-out + /// </summary> + [Description("Gateway Time-Out")] + GatewayTimeOut = 504, + /// <summary> + /// 505 RTSP version not supported + /// </summary> + [Description("RTSP Version Not Supported")] + RtspVersionNotSupported = 505, + + /// <summary> + /// 551 option not supported + /// </summary> + [Description("Option Not Supported")] + OptionNotSupported = 551 + } +} diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/SatIpDiscovery.cs b/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/SatIpDiscovery.cs index cdeb6dfa8..d0a55966f 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/SatIpDiscovery.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/SatIpDiscovery.cs @@ -1,14 +1,11 @@ using System; -using System.Collections.Generic; using System.Globalization; 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; @@ -18,6 +15,7 @@ using MediaBrowser.Model.LiveTv; using MediaBrowser.Model.Logging; using MediaBrowser.Model.Serialization; using MediaBrowser.Model.Extensions; +using System.Xml.Linq; namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.SatIp { @@ -98,10 +96,10 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.SatIp if (existing == null) { - if (string.IsNullOrWhiteSpace(info.M3UUrl)) - { - return; - } + //if (string.IsNullOrWhiteSpace(info.M3UUrl)) + //{ + // return; + //} await _liveTvManager.SaveTunerHost(new TunerHostInfo { @@ -174,58 +172,86 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.SatIp public async Task<SatIpTunerHostInfo> GetInfo(string url, CancellationToken cancellationToken) { + Uri locationUri = new Uri(url); + string devicetype = ""; + string friendlyname = ""; + string uniquedevicename = ""; + string manufacturer = ""; + string manufacturerurl = ""; + string modelname = ""; + string modeldescription = ""; + string modelnumber = ""; + string modelurl = ""; + string serialnumber = ""; + string presentationurl = ""; + string capabilities = ""; + string m3u = ""; + var document = XDocument.Load(locationUri.AbsoluteUri); + var xnm = new XmlNamespaceManager(new NameTable()); + XNamespace n1 = "urn:ses-com:satip"; + XNamespace n0 = "urn:schemas-upnp-org:device-1-0"; + xnm.AddNamespace("root", n0.NamespaceName); + xnm.AddNamespace("satip:", n1.NamespaceName); + if (document.Root != null) + { + var deviceElement = document.Root.Element(n0 + "device"); + if (deviceElement != null) + { + var devicetypeElement = deviceElement.Element(n0 + "deviceType"); + if (devicetypeElement != null) + devicetype = devicetypeElement.Value; + var friendlynameElement = deviceElement.Element(n0 + "friendlyName"); + if (friendlynameElement != null) + friendlyname = friendlynameElement.Value; + var manufactureElement = deviceElement.Element(n0 + "manufacturer"); + if (manufactureElement != null) + manufacturer = manufactureElement.Value; + var manufactureurlElement = deviceElement.Element(n0 + "manufacturerURL"); + if (manufactureurlElement != null) + manufacturerurl = manufactureurlElement.Value; + var modeldescriptionElement = deviceElement.Element(n0 + "modelDescription"); + if (modeldescriptionElement != null) + modeldescription = modeldescriptionElement.Value; + var modelnameElement = deviceElement.Element(n0 + "modelName"); + if (modelnameElement != null) + modelname = modelnameElement.Value; + var modelnumberElement = deviceElement.Element(n0 + "modelNumber"); + if (modelnumberElement != null) + modelnumber = modelnumberElement.Value; + var modelurlElement = deviceElement.Element(n0 + "modelURL"); + if (modelurlElement != null) + modelurl = modelurlElement.Value; + var serialnumberElement = deviceElement.Element(n0 + "serialNumber"); + if (serialnumberElement != null) + serialnumber = serialnumberElement.Value; + var uniquedevicenameElement = deviceElement.Element(n0 + "UDN"); + if (uniquedevicenameElement != null) uniquedevicename = uniquedevicenameElement.Value; + var presentationUrlElement = deviceElement.Element(n0 + "presentationURL"); + if (presentationUrlElement != null) presentationurl = presentationUrlElement.Value; + var capabilitiesElement = deviceElement.Element(n1 + "X_SATIPCAP"); + if (capabilitiesElement != null) capabilities = capabilitiesElement.Value; + var m3uElement = deviceElement.Element(n1 + "X_SATIPM3U"); + if (m3uElement != null) m3u = m3uElement.Value; + } + } + var result = new SatIpTunerHostInfo { Url = url, + Id = uniquedevicename, IsEnabled = true, Type = SatIpHost.DeviceType, Tuners = 1, - TunersAvailable = 1 + TunersAvailable = 1, + M3UUrl = m3u }; - using (var stream = await _httpClient.Get(url, cancellationToken).ConfigureAwait(false)) - { - using (var streamReader = new StreamReader(stream)) - { - // Use XmlReader for best performance - using (var reader = XmlReader.Create(streamReader)) - { - reader.MoveToContent(); - - // Loop through each element - while (reader.Read()) - { - if (reader.NodeType == XmlNodeType.Element) - { - switch (reader.Name) - { - case "device": - using (var subtree = reader.ReadSubtree()) - { - FillFromDeviceNode(result, subtree); - } - break; - default: - reader.Skip(); - break; - } - } - } - } - } - } - - if (string.IsNullOrWhiteSpace(result.DeviceId)) + result.FriendlyName = friendlyname; + if (string.IsNullOrWhiteSpace(result.Id)) { throw new NotImplementedException(); } - // Device hasn't implemented an m3u list - if (string.IsNullOrWhiteSpace(result.M3UUrl)) - { - result.IsEnabled = false; - } - else if (!result.M3UUrl.StartsWith("http", StringComparison.OrdinalIgnoreCase)) { var fullM3uUrl = url.Substring(0, url.LastIndexOf('/')); @@ -236,66 +262,6 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.SatIp return result; } - - private void FillFromDeviceNode(SatIpTunerHostInfo info, XmlReader reader) - { - reader.MoveToContent(); - - while (reader.Read()) - { - if (reader.NodeType == XmlNodeType.Element) - { - switch (reader.LocalName) - { - case "UDN": - { - info.DeviceId = reader.ReadElementContentAsString(); - break; - } - - case "friendlyName": - { - info.FriendlyName = reader.ReadElementContentAsString(); - break; - } - - case "satip:X_SATIPCAP": - case "X_SATIPCAP": - { - // <satip:X_SATIPCAP xmlns:satip="urn:ses-com:satip">DVBS2-2</satip:X_SATIPCAP> - var value = reader.ReadElementContentAsString() ?? string.Empty; - var parts = value.Split(new[] { '-' }, StringSplitOptions.RemoveEmptyEntries); - if (parts.Length == 2) - { - int intValue; - if (int.TryParse(parts[1], NumberStyles.Any, CultureInfo.InvariantCulture, out intValue)) - { - info.TunersAvailable = intValue; - } - - if (int.TryParse(parts[0].Substring(parts[0].Length - 1), NumberStyles.Any, CultureInfo.InvariantCulture, out intValue)) - { - info.Tuners = intValue; - } - } - break; - } - - case "satip:X_SATIPM3U": - case "X_SATIPM3U": - { - // <satip:X_SATIPM3U xmlns:satip="urn:ses-com:satip">/channellist.lua?select=m3u</satip:X_SATIPM3U> - info.M3UUrl = reader.ReadElementContentAsString(); - break; - } - - default: - reader.Skip(); - break; - } - } - } - } } public class SatIpTunerHostInfo : TunerHostInfo diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/SatIpHost.cs b/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/SatIpHost.cs index 46a2a8524..ffd85fd18 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/SatIpHost.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/SatIpHost.cs @@ -40,7 +40,8 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.SatIp return await new M3uParser(Logger, _fileSystem, _httpClient).Parse(tuner.M3UUrl, ChannelIdPrefix, tuner.Id, cancellationToken).ConfigureAwait(false); } - return new List<ChannelInfo>(); + var channels = await new ChannelScan(Logger).Scan(tuner, cancellationToken).ConfigureAwait(false); + return channels; } public static string DeviceType diff --git a/MediaBrowser.Server.Implementations/Localization/Core/ca.json b/MediaBrowser.Server.Implementations/Localization/Core/ca.json index 7cec213d3..7ca8e1553 100644 --- a/MediaBrowser.Server.Implementations/Localization/Core/ca.json +++ b/MediaBrowser.Server.Implementations/Localization/Core/ca.json @@ -1,5 +1,5 @@ { - "DbUpgradeMessage": "Please wait while your Emby Server database is upgraded. {0}% complete.", + "DbUpgradeMessage": "Si et plau espera mentre la teva base de dades del Servidor Emby \u00e9s actualitzada. {0}% completat.", "AppDeviceValues": "App: {0}, Dispositiu: {1}", "UserDownloadingItemWithValues": "{0} est\u00e0 descarregant {1}", "FolderTypeMixed": "Contingut barrejat", @@ -19,11 +19,11 @@ "LabelChapterName": "Cap\u00edtol {0}", "NameSeasonNumber": "Temporada {0}", "LabelExit": "Sortir", - "LabelVisitCommunity": "Visita la comunitat", + "LabelVisitCommunity": "Visita la Comunitat", "LabelGithub": "Github", "LabelApiDocumentation": "Documentaci\u00f3 de l'API", - "LabelDeveloperResources": "Recursos per a programadors", - "LabelBrowseLibrary": "Examina la biblioteca", + "LabelDeveloperResources": "Recursos per a Desenvolupadors", + "LabelBrowseLibrary": "Examina la Biblioteca", "LabelConfigureServer": "Configura Emby", "LabelRestartServer": "Reiniciar Servidor", "CategorySync": "Sync", @@ -131,7 +131,7 @@ "HeaderType": "Type", "HeaderSeverity": "Severity", "HeaderUser": "Usuari", - "HeaderName": "Name", + "HeaderName": "Nom", "HeaderDate": "Data", "HeaderPremiereDate": "Premiere Date", "HeaderDateAdded": "Data afegida", diff --git a/MediaBrowser.Server.Implementations/Localization/Core/es.json b/MediaBrowser.Server.Implementations/Localization/Core/es.json index 2a715a5b3..d1a56240d 100644 --- a/MediaBrowser.Server.Implementations/Localization/Core/es.json +++ b/MediaBrowser.Server.Implementations/Localization/Core/es.json @@ -1,7 +1,7 @@ { - "DbUpgradeMessage": "Please wait while your Emby Server database is upgraded. {0}% complete.", - "AppDeviceValues": "App: {0}, Device: {1}", - "UserDownloadingItemWithValues": "{0} is downloading {1}", + "DbUpgradeMessage": "Por favor espere mientras la base de datos de su servidor Emby se actualiza. {0}% completado.", + "AppDeviceValues": "Aplicaci\u00f3n: {0}, Dispositivo: {1}", + "UserDownloadingItemWithValues": "{0} est\u00e1 descargando {1}", "FolderTypeMixed": "Contenido mezclado", "FolderTypeMovies": "Peliculas", "FolderTypeMusic": "Musica", @@ -14,10 +14,10 @@ "FolderTypeTvShows": "TV", "FolderTypeInherit": "Heredado", "HeaderCastCrew": "Reparto y equipo t\u00e9cnico", - "HeaderPeople": "People", - "ValueSpecialEpisodeName": "Special - {0}", + "HeaderPeople": "Gente", + "ValueSpecialEpisodeName": "Especial - {0}", "LabelChapterName": "Cap\u00edtulo {0}", - "NameSeasonNumber": "Season {0}", + "NameSeasonNumber": "Temporada {0}", "LabelExit": "Salir", "LabelVisitCommunity": "Visitar la comunidad", "LabelGithub": "Github", @@ -50,77 +50,77 @@ "NotificationOptionCameraImageUploaded": "Imagen de camara se a carcado", "NotificationOptionUserLockedOut": "Usuario bloqueado", "NotificationOptionServerRestartRequired": "Se requiere el reinicio del servidor", - "ViewTypePlaylists": "Playlists", + "ViewTypePlaylists": "Listas de reproducci\u00f3n", "ViewTypeMovies": "Pel\u00edculas", "ViewTypeTvShows": "TV", "ViewTypeGames": "Juegos", "ViewTypeMusic": "M\u00fasica", - "ViewTypeMusicGenres": "Genres", - "ViewTypeMusicArtists": "Artists", + "ViewTypeMusicGenres": "G\u00e9neros", + "ViewTypeMusicArtists": "Artistas", "ViewTypeBoxSets": "Colecciones", "ViewTypeChannels": "Canales", "ViewTypeLiveTV": "Tv en vivo", - "ViewTypeLiveTvNowPlaying": "Now Airing", - "ViewTypeLatestGames": "Latest Games", - "ViewTypeRecentlyPlayedGames": "Recently Played", - "ViewTypeGameFavorites": "Favorites", - "ViewTypeGameSystems": "Game Systems", - "ViewTypeGameGenres": "Genres", - "ViewTypeTvResume": "Resume", - "ViewTypeTvNextUp": "Next Up", - "ViewTypeTvLatest": "Latest", + "ViewTypeLiveTvNowPlaying": "Transmiti\u00e9ndose ahora", + "ViewTypeLatestGames": "\u00daltimos juegos", + "ViewTypeRecentlyPlayedGames": "Reproducido recientemente", + "ViewTypeGameFavorites": "Favoritos", + "ViewTypeGameSystems": "Sistemas de juego", + "ViewTypeGameGenres": "G\u00e9neros", + "ViewTypeTvResume": "Reanudar", + "ViewTypeTvNextUp": "Pr\u00f3ximamente", + "ViewTypeTvLatest": "\u00daltimas", "ViewTypeTvShowSeries": "Series", - "ViewTypeTvGenres": "Genres", - "ViewTypeTvFavoriteSeries": "Favorite Series", - "ViewTypeTvFavoriteEpisodes": "Favorite Episodes", - "ViewTypeMovieResume": "Resume", - "ViewTypeMovieLatest": "Latest", - "ViewTypeMovieMovies": "Movies", - "ViewTypeMovieCollections": "Collections", - "ViewTypeMovieFavorites": "Favorites", - "ViewTypeMovieGenres": "Genres", - "ViewTypeMusicLatest": "Latest", - "ViewTypeMusicPlaylists": "Playlists", - "ViewTypeMusicAlbums": "Albums", - "ViewTypeMusicAlbumArtists": "Album Artists", + "ViewTypeTvGenres": "G\u00e9neros", + "ViewTypeTvFavoriteSeries": "Series favoritas", + "ViewTypeTvFavoriteEpisodes": "Episodios favoritos", + "ViewTypeMovieResume": "Reanudar", + "ViewTypeMovieLatest": "\u00daltimas", + "ViewTypeMovieMovies": "Pel\u00edculas", + "ViewTypeMovieCollections": "Colecciones", + "ViewTypeMovieFavorites": "Favoritos", + "ViewTypeMovieGenres": "G\u00e9neros", + "ViewTypeMusicLatest": "\u00daltimas", + "ViewTypeMusicPlaylists": "Lista", + "ViewTypeMusicAlbums": "\u00c1lbumes", + "ViewTypeMusicAlbumArtists": "\u00c1lbumes de artistas", "HeaderOtherDisplaySettings": "Configuraci\u00f3n de pantalla", - "ViewTypeMusicSongs": "Songs", - "ViewTypeMusicFavorites": "Favorites", - "ViewTypeMusicFavoriteAlbums": "Favorite Albums", - "ViewTypeMusicFavoriteArtists": "Favorite Artists", - "ViewTypeMusicFavoriteSongs": "Favorite Songs", - "ViewTypeFolders": "Folders", - "ViewTypeLiveTvRecordingGroups": "Recordings", - "ViewTypeLiveTvChannels": "Channels", - "ScheduledTaskFailedWithName": "{0} failed", - "LabelRunningTimeValue": "Running time: {0}", - "ScheduledTaskStartedWithName": "{0} started", + "ViewTypeMusicSongs": "Canciones", + "ViewTypeMusicFavorites": "Favoritos", + "ViewTypeMusicFavoriteAlbums": "\u00c1lbumes favoritos", + "ViewTypeMusicFavoriteArtists": "Artistas favoritos", + "ViewTypeMusicFavoriteSongs": "Canciones favoritas", + "ViewTypeFolders": "Carpetas", + "ViewTypeLiveTvRecordingGroups": "Grabaciones", + "ViewTypeLiveTvChannels": "Canales", + "ScheduledTaskFailedWithName": "{0} fall\u00f3", + "LabelRunningTimeValue": "Tiempo de ejecuci\u00f3n: {0}", + "ScheduledTaskStartedWithName": "{0} iniciado", "VersionNumber": "Versi\u00f3n {0}", - "PluginInstalledWithName": "{0} was installed", - "PluginUpdatedWithName": "{0} was updated", - "PluginUninstalledWithName": "{0} was uninstalled", - "ItemAddedWithName": "{0} was added to the library", - "ItemRemovedWithName": "{0} was removed from the library", - "LabelIpAddressValue": "Ip address: {0}", - "DeviceOnlineWithName": "{0} is connected", - "UserOnlineFromDevice": "{0} is online from {1}", - "ProviderValue": "Provider: {0}", - "SubtitlesDownloadedForItem": "Subtitles downloaded for {0}", - "UserConfigurationUpdatedWithName": "User configuration has been updated for {0}", - "UserCreatedWithName": "User {0} has been created", - "UserPasswordChangedWithName": "Password has been changed for user {0}", - "UserDeletedWithName": "User {0} has been deleted", - "MessageServerConfigurationUpdated": "Server configuration has been updated", - "MessageNamedServerConfigurationUpdatedWithValue": "Server configuration section {0} has been updated", - "MessageApplicationUpdated": "Emby Server has been updated", - "FailedLoginAttemptWithUserName": "Failed login attempt from {0}", - "AuthenticationSucceededWithUserName": "{0} successfully authenticated", - "DeviceOfflineWithName": "{0} has disconnected", - "UserLockedOutWithName": "User {0} has been locked out", - "UserOfflineFromDevice": "{0} has disconnected from {1}", - "UserStartedPlayingItemWithValues": "{0} has started playing {1}", - "UserStoppedPlayingItemWithValues": "{0} has stopped playing {1}", - "SubtitleDownloadFailureForItem": "Subtitles failed to download for {0}", + "PluginInstalledWithName": "{0} ha sido instalado", + "PluginUpdatedWithName": "{0} ha sido actualizado", + "PluginUninstalledWithName": "{0} ha sido desinstalado", + "ItemAddedWithName": "{0} ha sido a\u00f1adido a la biblioteca", + "ItemRemovedWithName": "{0} se ha eliminado de la biblioteca", + "LabelIpAddressValue": "Direcci\u00f3n IP: {0}", + "DeviceOnlineWithName": "{0} est\u00e1 conectado", + "UserOnlineFromDevice": "{0} est\u00e1 conectado desde {1}", + "ProviderValue": "Proveedor: {0}", + "SubtitlesDownloadedForItem": "Subt\u00edtulos descargados para {0}", + "UserConfigurationUpdatedWithName": "Se ha actualizado la configuraci\u00f3n de usuario para {0}", + "UserCreatedWithName": "Se ha creado el usuario {0}", + "UserPasswordChangedWithName": "Contrase\u00f1a cambiada al usuario {0}", + "UserDeletedWithName": "El usuario {0} ha sido eliminado", + "MessageServerConfigurationUpdated": "Se ha actualizado la configuraci\u00f3n del servidor", + "MessageNamedServerConfigurationUpdatedWithValue": "Se ha actualizado la secci\u00f3n {0} de la configuraci\u00f3n del servidor", + "MessageApplicationUpdated": "Se ha actualizado el servidor Emby", + "FailedLoginAttemptWithUserName": "Intento de inicio de sesi\u00f3n fallido desde {0}", + "AuthenticationSucceededWithUserName": "{0} se ha autenticado satisfactoriamente", + "DeviceOfflineWithName": "{0} se ha desconectado", + "UserLockedOutWithName": "El usuario {0} ha sido bloqueado", + "UserOfflineFromDevice": "{0} se ha desconectado de {1}", + "UserStartedPlayingItemWithValues": "{0} ha empezado a reproducir {1}", + "UserStoppedPlayingItemWithValues": "{0} ha parado de reproducir {1}", + "SubtitleDownloadFailureForItem": "Fallo en la descarga de subt\u00edtulos para {0}", "HeaderUnidentified": "Unidentified", "HeaderImagePrimary": "Primary", "HeaderImageBackdrop": "Backdrop", @@ -159,20 +159,20 @@ "HeaderEmbeddedImage": "Embedded image", "HeaderResolution": "Resolution", "HeaderSubtitles": "Subt\u00edtulos", - "HeaderGenres": "Genres", - "HeaderCountries": "Countries", + "HeaderGenres": "G\u00e9neros", + "HeaderCountries": "Paises", "HeaderStatus": "Estado", "HeaderTracks": "Tracks", "HeaderMusicArtist": "Music artist", "HeaderLocked": "Locked", - "HeaderStudios": "Studios", + "HeaderStudios": "Estudios", "HeaderActor": "Actors", "HeaderComposer": "Composers", "HeaderDirector": "Directors", "HeaderGuestStar": "Guest star", "HeaderProducer": "Producers", "HeaderWriter": "Writers", - "HeaderParentalRatings": "Parental Ratings", + "HeaderParentalRatings": "Clasificaci\u00f3n parental", "HeaderCommunityRatings": "Community ratings", "StartupEmbyServerIsLoading": "Emby Server is loading. Please try again shortly." }
\ No newline at end of file diff --git a/MediaBrowser.Server.Implementations/Localization/Core/hu.json b/MediaBrowser.Server.Implementations/Localization/Core/hu.json index b175ae6c1..2b9d28d8c 100644 --- a/MediaBrowser.Server.Implementations/Localization/Core/hu.json +++ b/MediaBrowser.Server.Implementations/Localization/Core/hu.json @@ -33,10 +33,10 @@ "CategoryPlugin": "B\u0151v\u00edtm\u00e9ny", "NotificationOptionPluginError": "B\u0151v\u00edtm\u00e9ny hiba", "NotificationOptionApplicationUpdateAvailable": "Friss\u00edt\u00e9s el\u00e9rhet\u0151", - "NotificationOptionApplicationUpdateInstalled": "Friss\u00edt\u00e9s telep\u00edtve", - "NotificationOptionPluginUpdateInstalled": "B\u0151v\u00edtm\u00e9ny friss\u00edtve", + "NotificationOptionApplicationUpdateInstalled": "Program friss\u00edt\u00e9s telep\u00edtve", + "NotificationOptionPluginUpdateInstalled": "B\u0151v\u00edtm\u00e9ny friss\u00edt\u00e9s telep\u00edtve", "NotificationOptionPluginInstalled": "B\u0151v\u00edtm\u00e9ny telep\u00edtve", - "NotificationOptionPluginUninstalled": "B\u0151v\u00edtm\u00e9ny t\u00f6r\u00f6lve", + "NotificationOptionPluginUninstalled": "B\u0151v\u00edtm\u00e9ny elt\u00e1vol\u00edtva", "NotificationOptionVideoPlayback": "Vide\u00f3 elind\u00edtva", "NotificationOptionAudioPlayback": "Zene elind\u00edtva", "NotificationOptionGamePlayback": "J\u00e1t\u00e9k elind\u00edtva", @@ -169,8 +169,8 @@ "HeaderActor": "Sz\u00edn\u00e9szek", "HeaderComposer": "Zeneszerz\u0151k", "HeaderDirector": "Rendez\u0151k", - "HeaderGuestStar": "Guest star", - "HeaderProducer": "Producers", + "HeaderGuestStar": "Vend\u00e9g szt\u00e1r", + "HeaderProducer": "Producerek", "HeaderWriter": "\u00cdr\u00f3k", "HeaderParentalRatings": "Korhat\u00e1r besorol\u00e1s", "HeaderCommunityRatings": "K\u00f6z\u00f6ss\u00e9gi \u00e9rt\u00e9kel\u00e9sek", diff --git a/MediaBrowser.Server.Implementations/Localization/Core/nl.json b/MediaBrowser.Server.Implementations/Localization/Core/nl.json index a83182ee8..2818fbf6a 100644 --- a/MediaBrowser.Server.Implementations/Localization/Core/nl.json +++ b/MediaBrowser.Server.Implementations/Localization/Core/nl.json @@ -1,5 +1,5 @@ { - "DbUpgradeMessage": "Even geduld svp terwijl de Emby Server database ge-upgrade wordt. {0}% gereed.", + "DbUpgradeMessage": "Een ogenblik geduld terwijl uw Emby Server-database wordt bijgewerkt. {0}% voltooid.", "AppDeviceValues": "App: {0}, Apparaat: {1}", "UserDownloadingItemWithValues": "{0} download {1}", "FolderTypeMixed": "Gemengde inhoud", diff --git a/MediaBrowser.Server.Implementations/Localization/Core/ru.json b/MediaBrowser.Server.Implementations/Localization/Core/ru.json index fa68aadb9..62fe3b496 100644 --- a/MediaBrowser.Server.Implementations/Localization/Core/ru.json +++ b/MediaBrowser.Server.Implementations/Localization/Core/ru.json @@ -2,17 +2,17 @@ "DbUpgradeMessage": "\u041f\u043e\u0434\u043e\u0436\u0434\u0438\u0442\u0435, \u043f\u043e\u043a\u0430 \u0431\u0430\u0437\u0430 \u0434\u0430\u043d\u043d\u044b\u0445 \u043d\u0430 \u0432\u0430\u0448\u0435\u043c Emby Server \u043c\u043e\u0434\u0435\u0440\u043d\u0438\u0437\u0438\u0440\u0443\u0435\u0442\u0441\u044f. {0} % \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u043e.", "AppDeviceValues": "\u041f\u0440\u0438\u043b.: {0}, \u0423\u0441\u0442\u0440.: {1}", "UserDownloadingItemWithValues": "{0} \u0437\u0430\u0433\u0440\u0443\u0436\u0430\u0435\u0442 {1}", - "FolderTypeMixed": "\u0420\u0430\u0437\u043d\u043e\u0442\u0438\u043f\u043d\u043e\u0435 \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u043d\u0438\u0435", + "FolderTypeMixed": "\u0421\u043c\u0435\u0448\u0430\u043d\u043d\u043e\u0435 \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u043d\u0438\u0435", "FolderTypeMovies": "\u041a\u0438\u043d\u043e", "FolderTypeMusic": "\u041c\u0443\u0437\u044b\u043a\u0430", - "FolderTypeAdultVideos": "\u0412\u0438\u0434\u0435\u043e \u0434\u043b\u044f \u0432\u0437\u0440\u043e\u0441\u043b\u044b\u0445", - "FolderTypePhotos": "\u0424\u043e\u0442\u043e\u0433\u0440\u0430\u0444\u0438\u0438", - "FolderTypeMusicVideos": "\u041c\u0443\u0437\u044b\u043a\u0430\u043b\u044c\u043d\u044b\u0435 \u0432\u0438\u0434\u0435\u043e", - "FolderTypeHomeVideos": "\u0414\u043e\u043c\u0430\u0448\u043d\u0438\u0435 \u0432\u0438\u0434\u0435\u043e", + "FolderTypeAdultVideos": "\u0414\u043b\u044f \u0432\u0437\u0440\u043e\u0441\u043b\u044b\u0445", + "FolderTypePhotos": "\u0424\u043e\u0442\u043e", + "FolderTypeMusicVideos": "\u041c\u0443\u0437. \u0432\u0438\u0434\u0435\u043e", + "FolderTypeHomeVideos": "\u0414\u043e\u043c. \u0432\u0438\u0434\u0435\u043e", "FolderTypeGames": "\u0418\u0433\u0440\u044b", - "FolderTypeBooks": "\u041a\u043d\u0438\u0433\u0438", + "FolderTypeBooks": "\u041b\u0438\u0442\u0435\u0440\u0430\u0442\u0443\u0440\u0430", "FolderTypeTvShows": "\u0422\u0412", - "FolderTypeInherit": "\u041d\u0430\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u043d\u0438\u0435", + "FolderTypeInherit": "\u041d\u0430\u0441\u043b\u0435\u0434\u0443\u0435\u043c\u044b\u0439", "HeaderCastCrew": "\u0421\u043d\u0438\u043c\u0430\u043b\u0438\u0441\u044c \u0438 \u0441\u043d\u0438\u043c\u0430\u043b\u0438", "HeaderPeople": "\u041b\u044e\u0434\u0438", "ValueSpecialEpisodeName": "\u0421\u043f\u0435\u0446\u044d\u043f\u0438\u0437\u043e\u0434 - {0}", @@ -163,7 +163,7 @@ "HeaderCountries": "\u0421\u0442\u0440\u0430\u043d\u044b", "HeaderStatus": "\u0421\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435", "HeaderTracks": "\u0414\u043e\u0440-\u043a\u0438", - "HeaderMusicArtist": "\u0418\u0441\u043f. \u043c\u0443\u0437\u044b\u043a\u0438", + "HeaderMusicArtist": "\u041c\u0443\u0437. \u0438\u0441\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c", "HeaderLocked": "\u0417\u0430\u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u0430\u043d\u043e", "HeaderStudios": "\u0421\u0442\u0443\u0434\u0438\u0438", "HeaderActor": "\u0410\u043a\u0442\u0451\u0440\u044b", diff --git a/MediaBrowser.Server.Implementations/Localization/Core/sv.json b/MediaBrowser.Server.Implementations/Localization/Core/sv.json index f52f656d4..4a6565aff 100644 --- a/MediaBrowser.Server.Implementations/Localization/Core/sv.json +++ b/MediaBrowser.Server.Implementations/Localization/Core/sv.json @@ -1,7 +1,7 @@ { - "DbUpgradeMessage": "Please wait while your Emby Server database is upgraded. {0}% complete.", + "DbUpgradeMessage": "V\u00e4nligen v\u00e4nta medan databasen p\u00e5 din Emby Server uppgraderas. {0}% klar", "AppDeviceValues": "App: {0}, enhet: {1}", - "UserDownloadingItemWithValues": "{0} is downloading {1}", + "UserDownloadingItemWithValues": "{0} laddar ned {1}", "FolderTypeMixed": "Blandat inneh\u00e5ll", "FolderTypeMovies": "Filmer", "FolderTypeMusic": "Musik", @@ -15,18 +15,18 @@ "FolderTypeInherit": "\u00c4rv", "HeaderCastCrew": "Rollista & bes\u00e4ttning", "HeaderPeople": "Personer", - "ValueSpecialEpisodeName": "Special - {0}", + "ValueSpecialEpisodeName": "Specialavsnitt - {0}", "LabelChapterName": "Kapitel {0}", - "NameSeasonNumber": "Season {0}", + "NameSeasonNumber": "S\u00e4song {0}", "LabelExit": "Avsluta", "LabelVisitCommunity": "Bes\u00f6k v\u00e5rt diskussionsforum", "LabelGithub": "Github", - "LabelApiDocumentation": "Api Dokumentation", + "LabelApiDocumentation": "Api-dokumentation", "LabelDeveloperResources": "Resurser f\u00f6r utvecklare", "LabelBrowseLibrary": "Bl\u00e4ddra i biblioteket", - "LabelConfigureServer": "Configure Emby", + "LabelConfigureServer": "Konfigurera Emby", "LabelRestartServer": "Starta om servern", - "CategorySync": "Sync", + "CategorySync": "Synkronisera", "CategoryUser": "Anv\u00e4ndare", "CategorySystem": "System", "CategoryApplication": "App", @@ -47,10 +47,10 @@ "NotificationOptionInstallationFailed": "Fel vid installation", "NotificationOptionNewLibraryContent": "Nytt inneh\u00e5ll har tillkommit", "NotificationOptionNewLibraryContentMultiple": "Nytillkommet inneh\u00e5ll finns (flera objekt)", - "NotificationOptionCameraImageUploaded": "Camera image uploaded", - "NotificationOptionUserLockedOut": "User locked out", + "NotificationOptionCameraImageUploaded": "Kaberabild uppladdad", + "NotificationOptionUserLockedOut": "Anv\u00e4ndare har l\u00e5sts ute", "NotificationOptionServerRestartRequired": "Servern m\u00e5ste startas om", - "ViewTypePlaylists": "Playlists", + "ViewTypePlaylists": "Spellistor", "ViewTypeMovies": "Filmer", "ViewTypeTvShows": "TV", "ViewTypeGames": "Spel", @@ -80,10 +80,10 @@ "ViewTypeMovieFavorites": "Favoriter", "ViewTypeMovieGenres": "Genrer", "ViewTypeMusicLatest": "Nytillkommet", - "ViewTypeMusicPlaylists": "Playlists", + "ViewTypeMusicPlaylists": "Spellistor", "ViewTypeMusicAlbums": "Album", "ViewTypeMusicAlbumArtists": "Albumartister", - "HeaderOtherDisplaySettings": "Visningsinst\u00e4llningar", + "HeaderOtherDisplaySettings": "Visningsalternativ", "ViewTypeMusicSongs": "L\u00e5tar", "ViewTypeMusicFavorites": "Favoriter", "ViewTypeMusicFavoriteAlbums": "Favoritalbum", @@ -112,45 +112,45 @@ "UserDeletedWithName": "Anv\u00e4ndaren {0} har tagits bort", "MessageServerConfigurationUpdated": "Server konfigurationen har uppdaterats", "MessageNamedServerConfigurationUpdatedWithValue": "Serverinst\u00e4llningarnas del {0} ar uppdaterats", - "MessageApplicationUpdated": "Emby Server has been updated", + "MessageApplicationUpdated": "Emby Server har uppdaterats", "FailedLoginAttemptWithUserName": "Misslyckat inloggningsf\u00f6rs\u00f6k fr\u00e5n {0}", "AuthenticationSucceededWithUserName": "{0} har autentiserats", "DeviceOfflineWithName": "{0} har avbrutit anslutningen", - "UserLockedOutWithName": "User {0} has been locked out", - "UserOfflineFromDevice": "{0} har kopplats bort fr\u00e5n {1}", + "UserLockedOutWithName": "Anv\u00e4ndare {0} har l\u00e5sts ute", + "UserOfflineFromDevice": "{0} har avbrutit anslutningen fr\u00e5n {1}", "UserStartedPlayingItemWithValues": "{0} har p\u00e5b\u00f6rjat uppspelning av {1}", "UserStoppedPlayingItemWithValues": "{0} har avslutat uppspelning av {1}", "SubtitleDownloadFailureForItem": "Nerladdning av undertexter f\u00f6r {0} misslyckades", - "HeaderUnidentified": "Unidentified", - "HeaderImagePrimary": "Primary", - "HeaderImageBackdrop": "Backdrop", - "HeaderImageLogo": "Logo", - "HeaderUserPrimaryImage": "User Image", - "HeaderOverview": "Overview", - "HeaderShortOverview": "Short Overview", - "HeaderType": "Type", + "HeaderUnidentified": "Oidentifierad", + "HeaderImagePrimary": "Huvudbild", + "HeaderImageBackdrop": "Bakgrundsbild", + "HeaderImageLogo": "Logotyp", + "HeaderUserPrimaryImage": "Anv\u00e4ndarbild", + "HeaderOverview": "\u00d6versikt", + "HeaderShortOverview": "Kort \u00f6versikt", + "HeaderType": "Typ", "HeaderSeverity": "Severity", "HeaderUser": "Anv\u00e4ndare", "HeaderName": "Namn", "HeaderDate": "Datum", - "HeaderPremiereDate": "Premiere Date", + "HeaderPremiereDate": "Premi\u00e4rdatum", "HeaderDateAdded": "Date Added", "HeaderReleaseDate": "Premi\u00e4rdatum:", "HeaderRuntime": "Speltid", - "HeaderPlayCount": "Play Count", + "HeaderPlayCount": "Antal spelningar", "HeaderSeason": "S\u00e4song", "HeaderSeasonNumber": "S\u00e4songsnummer:", - "HeaderSeries": "Series:", + "HeaderSeries": "Serie:", "HeaderNetwork": "TV-bolag", - "HeaderYear": "Year:", - "HeaderYears": "Years:", + "HeaderYear": "\u00c5r:", + "HeaderYears": "\u00c5r:", "HeaderParentalRating": "Parental Rating", "HeaderCommunityRating": "Anv\u00e4ndaromd\u00f6me", "HeaderTrailers": "Trailers", - "HeaderSpecials": "Specialer", + "HeaderSpecials": "Specialavsnitt", "HeaderGameSystems": "Game Systems", - "HeaderPlayers": "Players:", - "HeaderAlbumArtists": "Album Artists", + "HeaderPlayers": "Spelare:", + "HeaderAlbumArtists": "Albumartister", "HeaderAlbums": "Album", "HeaderDisc": "Skiva", "HeaderTrack": "Sp\u00e5r", @@ -163,16 +163,16 @@ "HeaderCountries": "L\u00e4nder", "HeaderStatus": "Status", "HeaderTracks": "Sp\u00e5r", - "HeaderMusicArtist": "Music artist", - "HeaderLocked": "Locked", + "HeaderMusicArtist": "Musikartist", + "HeaderLocked": "L\u00e5st", "HeaderStudios": "Studior", - "HeaderActor": "Actors", - "HeaderComposer": "Composers", - "HeaderDirector": "Directors", - "HeaderGuestStar": "Guest star", - "HeaderProducer": "Producers", - "HeaderWriter": "Writers", + "HeaderActor": "Sk\u00e5despelare", + "HeaderComposer": "Komposit\u00f6rer", + "HeaderDirector": "Regiss\u00f6r", + "HeaderGuestStar": "G\u00e4startist", + "HeaderProducer": "Producenter", + "HeaderWriter": "F\u00f6rfattare", "HeaderParentalRatings": "Parental Ratings", "HeaderCommunityRatings": "Community ratings", - "StartupEmbyServerIsLoading": "Emby Server is loading. Please try again shortly." + "StartupEmbyServerIsLoading": "Emby Server startar. V\u00e4nligen f\u00f6rs\u00f6k igen om en kort stund." }
\ No newline at end of file diff --git a/MediaBrowser.Server.Implementations/Localization/Core/zh-TW.json b/MediaBrowser.Server.Implementations/Localization/Core/zh-TW.json index 7f289fc1f..b711aab1f 100644 --- a/MediaBrowser.Server.Implementations/Localization/Core/zh-TW.json +++ b/MediaBrowser.Server.Implementations/Localization/Core/zh-TW.json @@ -1,5 +1,5 @@ { - "DbUpgradeMessage": "Please wait while your Emby Server database is upgraded. {0}% complete.", + "DbUpgradeMessage": "\u8acb\u7a0d\u5019\uff0cEmby\u4f3a\u670d\u5668\u8cc7\u6599\u5eab\u6b63\u5728\u66f4\u65b0...\uff08\u5df2\u5b8c\u6210{0}%\uff09", "AppDeviceValues": "App: {0}, Device: {1}", "UserDownloadingItemWithValues": "{0} is downloading {1}", "FolderTypeMixed": "Mixed content", @@ -19,13 +19,13 @@ "LabelChapterName": "Chapter {0}", "NameSeasonNumber": "Season {0}", "LabelExit": "\u96e2\u958b", - "LabelVisitCommunity": "\u8a2a\u554f\u793e\u5340", - "LabelGithub": "Github", - "LabelApiDocumentation": "Api Documentation", - "LabelDeveloperResources": "Developer Resources", - "LabelBrowseLibrary": "\u700f\u89bd\u5a92\u9ad4\u5eab", - "LabelConfigureServer": "Configure Emby", - "LabelRestartServer": "\u91cd\u65b0\u555f\u52d5\u4f3a\u5668\u670d", + "LabelVisitCommunity": "\u8a2a\u554f\u793e\u7fa4", + "LabelGithub": "GitHub", + "LabelApiDocumentation": "API\u8aaa\u660e\u6587\u4ef6", + "LabelDeveloperResources": "\u958b\u767c\u4eba\u54e1\u5c08\u5340", + "LabelBrowseLibrary": "\u700f\u89bd\u5a92\u9ad4\u6ac3", + "LabelConfigureServer": "Emby\u8a2d\u5b9a", + "LabelRestartServer": "\u91cd\u65b0\u555f\u52d5\u4f3a\u670d\u5668", "CategorySync": "Sync", "CategoryUser": "User", "CategorySystem": "System", @@ -59,7 +59,7 @@ "ViewTypeMusicArtists": "Artists", "ViewTypeBoxSets": "Collections", "ViewTypeChannels": "Channels", - "ViewTypeLiveTV": "Live TV", + "ViewTypeLiveTV": "\u96fb\u8996", "ViewTypeLiveTvNowPlaying": "Now Airing", "ViewTypeLatestGames": "Latest Games", "ViewTypeRecentlyPlayedGames": "Recently Played", diff --git a/MediaBrowser.Server.Implementations/Localization/LocalizationManager.cs b/MediaBrowser.Server.Implementations/Localization/LocalizationManager.cs index 40c1ac003..0c627d751 100644 --- a/MediaBrowser.Server.Implementations/Localization/LocalizationManager.cs +++ b/MediaBrowser.Server.Implementations/Localization/LocalizationManager.cs @@ -1,5 +1,4 @@ using MediaBrowser.Model.Extensions; -using MediaBrowser.Common.IO; using MediaBrowser.Controller.Configuration; using MediaBrowser.Controller.Localization; using MediaBrowser.Model.Entities; diff --git a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj index 97f090ab2..60d8f737f 100644 --- a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj +++ b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj @@ -99,6 +99,7 @@ <Reference Include="ServiceStack.Text"> <HintPath>..\ThirdParty\ServiceStack.Text\ServiceStack.Text.dll</HintPath> </Reference> + <Reference Include="System.Xml.Linq" /> <Reference Include="UniversalDetector"> <HintPath>..\ThirdParty\UniversalDetector\UniversalDetector.dll</HintPath> </Reference> @@ -242,6 +243,12 @@ <Compile Include="LiveTv\ProgramImageProvider.cs" /> <Compile Include="LiveTv\RecordingImageProvider.cs" /> <Compile Include="LiveTv\RefreshChannelsScheduledTask.cs" /> + <Compile Include="LiveTv\TunerHosts\SatIp\ChannelScan.cs" /> + <Compile Include="LiveTv\TunerHosts\SatIp\Rtsp\RtspMethod.cs" /> + <Compile Include="LiveTv\TunerHosts\SatIp\Rtsp\RtspRequest.cs" /> + <Compile Include="LiveTv\TunerHosts\SatIp\Rtsp\RtspResponse.cs" /> + <Compile Include="LiveTv\TunerHosts\SatIp\Rtsp\RtspSession.cs" /> + <Compile Include="LiveTv\TunerHosts\SatIp\Rtsp\RtspStatusCode.cs" /> <Compile Include="LiveTv\TunerHosts\SatIp\SatIpHost.cs" /> <Compile Include="LiveTv\TunerHosts\SatIp\SatIpDiscovery.cs" /> <Compile Include="Localization\LocalizationManager.cs" /> diff --git a/MediaBrowser.Server.Implementations/MediaEncoder/EncodingManager.cs b/MediaBrowser.Server.Implementations/MediaEncoder/EncodingManager.cs index ac0f2c69d..a7b0d61c7 100644 --- a/MediaBrowser.Server.Implementations/MediaEncoder/EncodingManager.cs +++ b/MediaBrowser.Server.Implementations/MediaEncoder/EncodingManager.cs @@ -1,5 +1,4 @@ -using MediaBrowser.Common.IO; -using MediaBrowser.Controller.Chapters; +using MediaBrowser.Controller.Chapters; using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Entities.Movies; using MediaBrowser.Controller.Entities.TV; @@ -153,7 +152,7 @@ namespace MediaBrowser.Server.Implementations.MediaEncoder } catch (Exception ex) { - _logger.ErrorException("Error extraching chapter images for {0}", ex, string.Join(",", inputPath)); + _logger.ErrorException("Error extracting chapter images for {0}", ex, string.Join(",", inputPath)); success = false; break; } diff --git a/MediaBrowser.Server.Implementations/Notifications/IConfigurableNotificationService.cs b/MediaBrowser.Server.Implementations/Notifications/IConfigurableNotificationService.cs index 5c4f400b0..cdfd0f640 100644 --- a/MediaBrowser.Server.Implementations/Notifications/IConfigurableNotificationService.cs +++ b/MediaBrowser.Server.Implementations/Notifications/IConfigurableNotificationService.cs @@ -1,10 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace MediaBrowser.Server.Implementations.Notifications +namespace MediaBrowser.Server.Implementations.Notifications { public interface IConfigurableNotificationService { diff --git a/MediaBrowser.Server.Implementations/Persistence/CleanDatabaseScheduledTask.cs b/MediaBrowser.Server.Implementations/Persistence/CleanDatabaseScheduledTask.cs index bec105b0a..031333f2c 100644 --- a/MediaBrowser.Server.Implementations/Persistence/CleanDatabaseScheduledTask.cs +++ b/MediaBrowser.Server.Implementations/Persistence/CleanDatabaseScheduledTask.cs @@ -3,7 +3,6 @@ using MediaBrowser.Common.ScheduledTasks; using MediaBrowser.Controller.Configuration; using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Library; -using MediaBrowser.Controller.LiveTv; using MediaBrowser.Controller.Persistence; using MediaBrowser.Model.Entities; using MediaBrowser.Model.Logging; @@ -33,7 +32,7 @@ namespace MediaBrowser.Server.Implementations.Persistence private readonly ILocalizationManager _localization; private readonly ITaskManager _taskManager; - public const int MigrationVersion = 20; + public const int MigrationVersion = 23; public static bool EnableUnavailableMessage = false; public CleanDatabaseScheduledTask(ILibraryManager libraryManager, IItemRepository itemRepo, ILogger logger, IServerConfigurationManager config, IFileSystem fileSystem, IHttpServer httpServer, ILocalizationManager localization, ITaskManager taskManager) @@ -86,7 +85,7 @@ namespace MediaBrowser.Server.Implementations.Persistence innerProgress = new ActionableProgress<double>(); innerProgress.RegisterAction(p => { - double newPercentCommplete = 40 + (.05 * p); + double newPercentCommplete = 40 + .05 * p; OnProgress(newPercentCommplete); progress.Report(newPercentCommplete); }); @@ -96,7 +95,7 @@ namespace MediaBrowser.Server.Implementations.Persistence innerProgress = new ActionableProgress<double>(); innerProgress.RegisterAction(p => { - double newPercentCommplete = 45 + (.55 * p); + double newPercentCommplete = 45 + .55 * p; OnProgress(newPercentCommplete); progress.Report(newPercentCommplete); }); diff --git a/MediaBrowser.Server.Implementations/Persistence/MediaStreamColumns.cs b/MediaBrowser.Server.Implementations/Persistence/MediaStreamColumns.cs index 7e46db5a7..211c77107 100644 --- a/MediaBrowser.Server.Implementations/Persistence/MediaStreamColumns.cs +++ b/MediaBrowser.Server.Implementations/Persistence/MediaStreamColumns.cs @@ -1,9 +1,6 @@ using System; -using System.Collections.Generic; using System.Data; -using System.Linq; using System.Text; -using System.Threading.Tasks; using MediaBrowser.Model.Logging; namespace MediaBrowser.Server.Implementations.Persistence diff --git a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs index 3264abd22..212be2849 100644 --- a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs +++ b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs @@ -78,8 +78,9 @@ namespace MediaBrowser.Server.Implementations.Persistence private IDbCommand _saveAncestorCommand; private IDbCommand _updateInheritedRatingCommand; + private IDbCommand _updateInheritedTagsCommand; - private const int LatestSchemaVersion = 55; + private const int LatestSchemaVersion = 62; /// <summary> /// Initializes a new instance of the <see cref="SqliteItemRepository"/> class. @@ -135,7 +136,7 @@ namespace MediaBrowser.Server.Implementations.Persistence "create table if not exists AncestorIds (ItemId GUID, AncestorId GUID, AncestorIdText TEXT, PRIMARY KEY (ItemId, AncestorId))", "create index if not exists idx_AncestorIds1 on AncestorIds(AncestorId)", "create index if not exists idx_AncestorIds2 on AncestorIds(AncestorIdText)", - + "create table if not exists People (ItemId GUID, Name TEXT NOT NULL, Role TEXT, PersonType TEXT, SortOrder int, ListOrder int)", "create index if not exists idxPeopleItemId on People(ItemId)", "create index if not exists idxPeopleName on People(Name)", @@ -223,6 +224,8 @@ namespace MediaBrowser.Server.Implementations.Persistence _connection.AddColumn(Logger, "TypedBaseItems", "TrailerTypes", "Text"); _connection.AddColumn(Logger, "TypedBaseItems", "CriticRating", "Float"); _connection.AddColumn(Logger, "TypedBaseItems", "CriticRatingSummary", "Text"); + _connection.AddColumn(Logger, "TypedBaseItems", "DateModifiedDuringLastRefresh", "DATETIME"); + _connection.AddColumn(Logger, "TypedBaseItems", "InheritedTags", "Text"); PrepareStatements(); @@ -355,7 +358,8 @@ namespace MediaBrowser.Server.Implementations.Persistence "Studios", "Tags", "SourceType", - "TrailerTypes" + "TrailerTypes", + "DateModifiedDuringLastRefresh" }; private readonly string[] _mediaStreamSaveColumns = @@ -400,7 +404,7 @@ namespace MediaBrowser.Server.Implementations.Persistence "guid", "type", "data", - "Path", + "Path", "StartDate", "EndDate", "ChannelId", @@ -459,7 +463,9 @@ namespace MediaBrowser.Server.Implementations.Persistence "SourceType", "TrailerTypes", "CriticRating", - "CriticRatingSummary" + "CriticRatingSummary", + "DateModifiedDuringLastRefresh", + "InheritedTags" }; _saveItemCommand = _connection.CreateCommand(); _saveItemCommand.CommandText = "replace into TypedBaseItems (" + string.Join(",", saveColumns.ToArray()) + ") values ("; @@ -537,8 +543,13 @@ namespace MediaBrowser.Server.Implementations.Persistence _updateInheritedRatingCommand = _connection.CreateCommand(); _updateInheritedRatingCommand.CommandText = "Update TypedBaseItems set InheritedParentalRatingValue=@InheritedParentalRatingValue where Guid=@Guid"; - _updateInheritedRatingCommand.Parameters.Add(_updateInheritedRatingCommand, "@InheritedParentalRatingValue"); _updateInheritedRatingCommand.Parameters.Add(_updateInheritedRatingCommand, "@Guid"); + _updateInheritedRatingCommand.Parameters.Add(_updateInheritedRatingCommand, "@InheritedParentalRatingValue"); + + _updateInheritedTagsCommand = _connection.CreateCommand(); + _updateInheritedTagsCommand.CommandText = "Update TypedBaseItems set InheritedTags=@InheritedTags where Guid=@Guid"; + _updateInheritedTagsCommand.Parameters.Add(_updateInheritedTagsCommand, "@Guid"); + _updateInheritedTagsCommand.Parameters.Add(_updateInheritedTagsCommand, "@InheritedTags"); } /// <summary> @@ -712,7 +723,15 @@ namespace MediaBrowser.Server.Implementations.Persistence _saveItemCommand.GetParameter(index++).Value = item.ServiceName; - _saveItemCommand.GetParameter(index++).Value = string.Join("|", item.Tags.ToArray()); + if (item.Tags.Count > 0) + { + _saveItemCommand.GetParameter(index++).Value = string.Join("|", item.Tags.ToArray()); + } + else + { + _saveItemCommand.GetParameter(index++).Value = null; + } + _saveItemCommand.GetParameter(index++).Value = item.IsFolder; _saveItemCommand.GetParameter(index++).Value = item.GetBlockUnratedType().ToString(); @@ -752,7 +771,26 @@ namespace MediaBrowser.Server.Implementations.Persistence _saveItemCommand.GetParameter(index++).Value = item.CriticRating; _saveItemCommand.GetParameter(index++).Value = item.CriticRatingSummary; - + + if (!item.DateModifiedDuringLastRefresh.HasValue || item.DateModifiedDuringLastRefresh.Value == default(DateTime)) + { + _saveItemCommand.GetParameter(index++).Value = null; + } + else + { + _saveItemCommand.GetParameter(index++).Value = item.DateModifiedDuringLastRefresh.Value; + } + + var inheritedTags = item.GetInheritedTags(); + if (inheritedTags.Count > 0) + { + _saveItemCommand.GetParameter(index++).Value = string.Join("|", inheritedTags.ToArray()); + } + else + { + _saveItemCommand.GetParameter(index++).Value = null; + } + _saveItemCommand.Transaction = transaction; _saveItemCommand.ExecuteNonQuery(); @@ -1125,6 +1163,11 @@ namespace MediaBrowser.Server.Implementations.Persistence } } + if (!reader.IsDBNull(51)) + { + item.DateModifiedDuringLastRefresh = reader.GetDateTime(51).ToUniversalTime(); + } + return item; } @@ -2148,6 +2191,14 @@ namespace MediaBrowser.Server.Implementations.Persistence excludeTagIndex++; } + excludeTagIndex = 0; + foreach (var excludeTag in query.ExcludeInheritedTags) + { + whereClauses.Add("InheritedTags not like @excludeInheritedTag" + excludeTagIndex); + cmd.Parameters.Add(cmd, "@excludeInheritedTag" + excludeTagIndex, DbType.String).Value = "%" + excludeTag + "%"; + excludeTagIndex++; + } + if (addPaging) { if (query.StartIndex.HasValue && query.StartIndex.Value > 0) @@ -2208,6 +2259,88 @@ namespace MediaBrowser.Server.Implementations.Persistence public async Task UpdateInheritedValues(CancellationToken cancellationToken) { + await UpdateInheritedParentalRating(cancellationToken).ConfigureAwait(false); + await UpdateInheritedTags(cancellationToken).ConfigureAwait(false); + } + + private async Task UpdateInheritedTags(CancellationToken cancellationToken) + { + var newValues = new List<Tuple<Guid, string>>(); + + using (var cmd = _connection.CreateCommand()) + { + cmd.CommandText = "select Guid,InheritedTags,(select group_concat(Tags, '|') from TypedBaseItems where (guid=outer.guid) OR (guid in (Select AncestorId from AncestorIds where ItemId=Outer.guid))) as NewInheritedTags from typedbaseitems as Outer where NewInheritedTags <> InheritedTags"; + + using (var reader = cmd.ExecuteReader(CommandBehavior.SequentialAccess | CommandBehavior.SingleResult)) + { + while (reader.Read()) + { + var id = reader.GetGuid(0); + string value = reader.IsDBNull(2) ? null : reader.GetString(2); + + newValues.Add(new Tuple<Guid, string>(id, value)); + } + } + } + + Logger.Debug("UpdateInheritedTags - {0} rows", newValues.Count); + if (newValues.Count == 0) + { + return; + } + + await WriteLock.WaitAsync(cancellationToken).ConfigureAwait(false); + + IDbTransaction transaction = null; + + try + { + transaction = _connection.BeginTransaction(); + + foreach (var item in newValues) + { + _updateInheritedTagsCommand.GetParameter(0).Value = item.Item1; + _updateInheritedTagsCommand.GetParameter(1).Value = item.Item2; + + _updateInheritedTagsCommand.Transaction = transaction; + _updateInheritedTagsCommand.ExecuteNonQuery(); + } + + transaction.Commit(); + } + catch (OperationCanceledException) + { + if (transaction != null) + { + transaction.Rollback(); + } + + throw; + } + catch (Exception e) + { + Logger.ErrorException("Error running query:", e); + + if (transaction != null) + { + transaction.Rollback(); + } + + throw; + } + finally + { + if (transaction != null) + { + transaction.Dispose(); + } + + WriteLock.Release(); + } + } + + private async Task UpdateInheritedParentalRating(CancellationToken cancellationToken) + { var newValues = new List<Tuple<Guid, int>>(); using (var cmd = _connection.CreateCommand()) @@ -2226,6 +2359,7 @@ namespace MediaBrowser.Server.Implementations.Persistence } } + Logger.Debug("UpdateInheritedParentalRatings - {0} rows", newValues.Count); if (newValues.Count == 0) { return; @@ -2755,7 +2889,7 @@ namespace MediaBrowser.Server.Implementations.Persistence _saveStreamCommand.GetParameter(index++).Value = stream.BitDepth; _saveStreamCommand.GetParameter(index++).Value = stream.IsAnamorphic; _saveStreamCommand.GetParameter(index++).Value = stream.RefFrames; - _saveStreamCommand.GetParameter(index++).Value = stream.IsCabac; + _saveStreamCommand.GetParameter(index++).Value = null; _saveStreamCommand.GetParameter(index++).Value = stream.CodecTag; _saveStreamCommand.GetParameter(index++).Value = stream.Comment; @@ -2907,10 +3041,7 @@ namespace MediaBrowser.Server.Implementations.Persistence item.RefFrames = reader.GetInt32(24); } - if (!reader.IsDBNull(25)) - { - item.IsCabac = reader.GetBoolean(25); - } + // cabac no longer used if (!reader.IsDBNull(26)) { diff --git a/MediaBrowser.Server.Implementations/Photos/PhotoAlbumImageProvider.cs b/MediaBrowser.Server.Implementations/Photos/PhotoAlbumImageProvider.cs index 56a174756..fafb2f268 100644 --- a/MediaBrowser.Server.Implementations/Photos/PhotoAlbumImageProvider.cs +++ b/MediaBrowser.Server.Implementations/Photos/PhotoAlbumImageProvider.cs @@ -3,7 +3,6 @@ using MediaBrowser.Controller.Drawing; using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Providers; using System.Collections.Generic; -using System.IO; using System.Linq; using System.Threading.Tasks; using CommonIO; diff --git a/MediaBrowser.Server.Implementations/Playlists/ManualPlaylistsFolder.cs b/MediaBrowser.Server.Implementations/Playlists/ManualPlaylistsFolder.cs index fbf514423..20324215b 100644 --- a/MediaBrowser.Server.Implementations/Playlists/ManualPlaylistsFolder.cs +++ b/MediaBrowser.Server.Implementations/Playlists/ManualPlaylistsFolder.cs @@ -5,7 +5,6 @@ using System.Collections.Generic; using System.IO; using System.Linq; using CommonIO; -using MediaBrowser.Common.IO; namespace MediaBrowser.Server.Implementations.Playlists { diff --git a/MediaBrowser.Server.Implementations/Playlists/PlaylistImageProvider.cs b/MediaBrowser.Server.Implementations/Playlists/PlaylistImageProvider.cs index 4413a7ddf..bdb73ea38 100644 --- a/MediaBrowser.Server.Implementations/Playlists/PlaylistImageProvider.cs +++ b/MediaBrowser.Server.Implementations/Playlists/PlaylistImageProvider.cs @@ -1,5 +1,4 @@ using MediaBrowser.Common.Configuration; -using MediaBrowser.Common.IO; using MediaBrowser.Controller.Drawing; using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Entities.Audio; diff --git a/MediaBrowser.Server.Implementations/Playlists/PlaylistManager.cs b/MediaBrowser.Server.Implementations/Playlists/PlaylistManager.cs index 048e2bf8d..06ef05951 100644 --- a/MediaBrowser.Server.Implementations/Playlists/PlaylistManager.cs +++ b/MediaBrowser.Server.Implementations/Playlists/PlaylistManager.cs @@ -1,5 +1,4 @@ -using MediaBrowser.Common.IO; -using MediaBrowser.Controller.Entities; +using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Entities.Audio; using MediaBrowser.Controller.Library; using MediaBrowser.Controller.Playlists; diff --git a/MediaBrowser.Server.Implementations/ScheduledTasks/ChapterImagesTask.cs b/MediaBrowser.Server.Implementations/ScheduledTasks/ChapterImagesTask.cs index e5249d4f2..e50de7bac 100644 --- a/MediaBrowser.Server.Implementations/ScheduledTasks/ChapterImagesTask.cs +++ b/MediaBrowser.Server.Implementations/ScheduledTasks/ChapterImagesTask.cs @@ -12,7 +12,6 @@ using System.Linq; using System.Threading; using System.Threading.Tasks; using CommonIO; -using MediaBrowser.Common.IO; namespace MediaBrowser.Server.Implementations.ScheduledTasks { diff --git a/MediaBrowser.Server.Implementations/ScheduledTasks/PluginUpdateTask.cs b/MediaBrowser.Server.Implementations/ScheduledTasks/PluginUpdateTask.cs index 457f5a33d..ff0960259 100644 --- a/MediaBrowser.Server.Implementations/ScheduledTasks/PluginUpdateTask.cs +++ b/MediaBrowser.Server.Implementations/ScheduledTasks/PluginUpdateTask.cs @@ -98,7 +98,7 @@ namespace MediaBrowser.Server.Implementations.ScheduledTasks double percent = numComplete; percent /= packagesToInstall.Count; - progress.Report((90 * percent) + 10); + progress.Report(90 * percent + 10); } })); diff --git a/MediaBrowser.Server.Implementations/ScheduledTasks/RefreshIntrosTask.cs b/MediaBrowser.Server.Implementations/ScheduledTasks/RefreshIntrosTask.cs index 90682d5b0..3192c91f4 100644 --- a/MediaBrowser.Server.Implementations/ScheduledTasks/RefreshIntrosTask.cs +++ b/MediaBrowser.Server.Implementations/ScheduledTasks/RefreshIntrosTask.cs @@ -1,5 +1,4 @@ -using MediaBrowser.Common.IO; -using MediaBrowser.Controller.Library; +using MediaBrowser.Controller.Library; using MediaBrowser.Model.Logging; using System; using System.Linq; diff --git a/MediaBrowser.Server.Implementations/ScheduledTasks/SystemUpdateTask.cs b/MediaBrowser.Server.Implementations/ScheduledTasks/SystemUpdateTask.cs index fa3cd6be7..0ba9d4f32 100644 --- a/MediaBrowser.Server.Implementations/ScheduledTasks/SystemUpdateTask.cs +++ b/MediaBrowser.Server.Implementations/ScheduledTasks/SystemUpdateTask.cs @@ -96,7 +96,7 @@ namespace MediaBrowser.Server.Implementations.ScheduledTasks { Logger.Info("Update Revision {0} available. Updating...", updateInfo.AvailableVersion); - innerProgressHandler = (sender, e) => progress.Report((e * .9) + .1); + innerProgressHandler = (sender, e) => progress.Report(e * .9 + .1); innerProgress = new Progress<double>(); innerProgress.ProgressChanged += innerProgressHandler; diff --git a/MediaBrowser.Server.Implementations/Session/SessionManager.cs b/MediaBrowser.Server.Implementations/Session/SessionManager.cs index 98127d39a..88f11c368 100644 --- a/MediaBrowser.Server.Implementations/Session/SessionManager.cs +++ b/MediaBrowser.Server.Implementations/Session/SessionManager.cs @@ -547,9 +547,9 @@ namespace MediaBrowser.Server.Implementations.Session await OnPlaybackStopped(new PlaybackStopInfo { Item = session.NowPlayingItem, - ItemId = (session.NowPlayingItem == null ? null : session.NowPlayingItem.Id), + ItemId = session.NowPlayingItem == null ? null : session.NowPlayingItem.Id, SessionId = session.Id, - MediaSourceId = (session.PlayState == null ? null : session.PlayState.MediaSourceId), + MediaSourceId = session.PlayState == null ? null : session.PlayState.MediaSourceId, PositionTicks = session.PlayState == null ? null : session.PlayState.PositionTicks }); } diff --git a/MediaBrowser.Server.Implementations/Sorting/AiredEpisodeOrderComparer.cs b/MediaBrowser.Server.Implementations/Sorting/AiredEpisodeOrderComparer.cs index c7bbca060..70cf805cf 100644 --- a/MediaBrowser.Server.Implementations/Sorting/AiredEpisodeOrderComparer.cs +++ b/MediaBrowser.Server.Implementations/Sorting/AiredEpisodeOrderComparer.cs @@ -142,8 +142,8 @@ namespace MediaBrowser.Server.Implementations.Sorting private int CompareEpisodes(Episode x, Episode y) { - var xValue = ((x.PhysicalSeasonNumber ?? -1) * 1000) + (x.IndexNumber ?? -1); - var yValue = ((y.PhysicalSeasonNumber ?? -1) * 1000) + (y.IndexNumber ?? -1); + var xValue = (x.PhysicalSeasonNumber ?? -1) * 1000 + (x.IndexNumber ?? -1); + var yValue = (y.PhysicalSeasonNumber ?? -1) * 1000 + (y.IndexNumber ?? -1); return xValue.CompareTo(yValue); } diff --git a/MediaBrowser.Server.Implementations/Sorting/OfficialRatingComparer.cs b/MediaBrowser.Server.Implementations/Sorting/OfficialRatingComparer.cs index e9ba3b5d3..dd31109da 100644 --- a/MediaBrowser.Server.Implementations/Sorting/OfficialRatingComparer.cs +++ b/MediaBrowser.Server.Implementations/Sorting/OfficialRatingComparer.cs @@ -1,5 +1,4 @@ -using System; -using MediaBrowser.Controller.Entities; +using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Localization; using MediaBrowser.Controller.Sorting; using MediaBrowser.Model.Querying; diff --git a/MediaBrowser.Server.Implementations/Sorting/PlayCountComparer.cs b/MediaBrowser.Server.Implementations/Sorting/PlayCountComparer.cs index 0d10c459f..1bc5261b4 100644 --- a/MediaBrowser.Server.Implementations/Sorting/PlayCountComparer.cs +++ b/MediaBrowser.Server.Implementations/Sorting/PlayCountComparer.cs @@ -1,6 +1,5 @@ using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Library; -using MediaBrowser.Controller.Persistence; using MediaBrowser.Controller.Sorting; using MediaBrowser.Model.Querying; diff --git a/MediaBrowser.Server.Implementations/Sync/MediaSync.cs b/MediaBrowser.Server.Implementations/Sync/MediaSync.cs index 1a02fcd3a..3218ac5e7 100644 --- a/MediaBrowser.Server.Implementations/Sync/MediaSync.cs +++ b/MediaBrowser.Server.Implementations/Sync/MediaSync.cs @@ -1,5 +1,4 @@ using MediaBrowser.Common.Configuration; -using MediaBrowser.Common.IO; using MediaBrowser.Common.Progress; using MediaBrowser.Controller; using MediaBrowser.Controller.IO; diff --git a/MediaBrowser.Server.Implementations/Sync/MultiProviderSync.cs b/MediaBrowser.Server.Implementations/Sync/MultiProviderSync.cs index dca831f73..97b2b1eb8 100644 --- a/MediaBrowser.Server.Implementations/Sync/MultiProviderSync.cs +++ b/MediaBrowser.Server.Implementations/Sync/MultiProviderSync.cs @@ -1,5 +1,4 @@ using MediaBrowser.Common.Configuration; -using MediaBrowser.Common.IO; using MediaBrowser.Common.Progress; using MediaBrowser.Controller; using MediaBrowser.Controller.Sync; diff --git a/MediaBrowser.Server.Implementations/Sync/ServerSyncScheduledTask.cs b/MediaBrowser.Server.Implementations/Sync/ServerSyncScheduledTask.cs index 52c9f9cee..28813c715 100644 --- a/MediaBrowser.Server.Implementations/Sync/ServerSyncScheduledTask.cs +++ b/MediaBrowser.Server.Implementations/Sync/ServerSyncScheduledTask.cs @@ -1,5 +1,4 @@ using MediaBrowser.Common.Configuration; -using MediaBrowser.Common.IO; using MediaBrowser.Common.ScheduledTasks; using MediaBrowser.Controller; using MediaBrowser.Controller.Sync; diff --git a/MediaBrowser.Server.Implementations/Sync/SyncConvertScheduledTask.cs b/MediaBrowser.Server.Implementations/Sync/SyncConvertScheduledTask.cs index 2efed7992..3f9eb7691 100644 --- a/MediaBrowser.Server.Implementations/Sync/SyncConvertScheduledTask.cs +++ b/MediaBrowser.Server.Implementations/Sync/SyncConvertScheduledTask.cs @@ -1,5 +1,4 @@ using MediaBrowser.Common.Configuration; -using MediaBrowser.Common.IO; using MediaBrowser.Common.ScheduledTasks; using MediaBrowser.Controller.Library; using MediaBrowser.Controller.MediaEncoding; diff --git a/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs b/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs index f553c8ea8..33874b4d4 100644 --- a/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs +++ b/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs @@ -98,7 +98,7 @@ namespace MediaBrowser.Server.Implementations.Sync var index = jobItems.Count == 0 ? 0 : - (jobItems.Select(i => i.JobItemIndex).Max() + 1); + jobItems.Select(i => i.JobItemIndex).Max() + 1; jobItem = new SyncJobItem { @@ -149,16 +149,6 @@ namespace MediaBrowser.Server.Implementations.Sync { var job = _syncRepo.GetJob(id); - return UpdateJobStatus(job); - } - - private Task UpdateJobStatus(SyncJob job) - { - if (job == null) - { - throw new ArgumentNullException("job"); - } - var result = _syncManager.GetJobItems(new SyncJobItemQuery { JobId = job.Id, @@ -469,21 +459,19 @@ namespace MediaBrowser.Server.Implementations.Sync var startingPercent = numComplete * percentPerItem * 100; var innerProgress = new ActionableProgress<double>(); - innerProgress.RegisterAction(p => progress.Report(startingPercent + (percentPerItem * p))); + innerProgress.RegisterAction(p => progress.Report(startingPercent + percentPerItem * p)); // Pull it fresh from the db just to make sure it wasn't deleted or cancelled while another item was converting var jobItem = enableConversion ? _syncRepo.GetJobItem(item.Id) : item; if (jobItem != null) { - var job = _syncRepo.GetJob(jobItem.JobId); if (jobItem.Status != SyncJobItemStatus.Cancelled) { - await ProcessJobItem(job, jobItem, enableConversion, innerProgress, cancellationToken).ConfigureAwait(false); + await ProcessJobItem(jobItem, enableConversion, innerProgress, cancellationToken).ConfigureAwait(false); } - job = _syncRepo.GetJob(jobItem.JobId); - await UpdateJobStatus(job).ConfigureAwait(false); + await UpdateJobStatus(jobItem.JobId).ConfigureAwait(false); } numComplete++; @@ -493,7 +481,7 @@ namespace MediaBrowser.Server.Implementations.Sync } } - private async Task ProcessJobItem(SyncJob job, SyncJobItem jobItem, bool enableConversion, IProgress<double> progress, CancellationToken cancellationToken) + private async Task ProcessJobItem(SyncJobItem jobItem, bool enableConversion, IProgress<double> progress, CancellationToken cancellationToken) { var item = _libraryManager.GetItemById(jobItem.ItemId); if (item == null) @@ -507,6 +495,7 @@ namespace MediaBrowser.Server.Implementations.Sync jobItem.Progress = 0; var syncOptions = _config.GetSyncOptions(); + var job = _syncManager.GetJob(jobItem.JobId); var user = _userManager.GetUserById(job.UserId); if (user == null) { @@ -521,7 +510,7 @@ namespace MediaBrowser.Server.Implementations.Sync { AddMetadata = false, ItemId = jobItem.ItemId, - TargetId = job.TargetId, + TargetId = jobItem.TargetId, Statuses = new[] { SyncJobItemStatus.Converting, SyncJobItemStatus.Queued, SyncJobItemStatus.ReadyToTransfer, SyncJobItemStatus.Synced, SyncJobItemStatus.Transferring } }); @@ -531,7 +520,7 @@ namespace MediaBrowser.Server.Implementations.Sync if (duplicateJobItems.Count > 0) { - var syncProvider = _syncManager.GetSyncProvider(jobItem, job) as IHasDuplicateCheck; + var syncProvider = _syncManager.GetSyncProvider(jobItem) as IHasDuplicateCheck; if (!duplicateJobItems.Any(i => AllowDuplicateJobItem(syncProvider, i, jobItem))) { @@ -545,12 +534,12 @@ namespace MediaBrowser.Server.Implementations.Sync var video = item as Video; if (video != null) { - await Sync(jobItem, job, video, user, enableConversion, syncOptions, progress, cancellationToken).ConfigureAwait(false); + await Sync(jobItem, video, user, enableConversion, syncOptions, progress, cancellationToken).ConfigureAwait(false); } else if (item is Audio) { - await Sync(jobItem, job, (Audio)item, user, enableConversion, syncOptions, progress, cancellationToken).ConfigureAwait(false); + await Sync(jobItem, (Audio)item, user, enableConversion, syncOptions, progress, cancellationToken).ConfigureAwait(false); } else if (item is Photo) @@ -574,8 +563,9 @@ namespace MediaBrowser.Server.Implementations.Sync return true; } - private async Task Sync(SyncJobItem jobItem, SyncJob job, Video item, User user, bool enableConversion, SyncOptions syncOptions, IProgress<double> progress, CancellationToken cancellationToken) + private async Task Sync(SyncJobItem jobItem, Video item, User user, bool enableConversion, SyncOptions syncOptions, IProgress<double> progress, CancellationToken cancellationToken) { + var job = _syncManager.GetJob(jobItem.JobId); var jobOptions = _syncManager.GetVideoOptions(jobItem, job); var conversionOptions = new VideoOptions { @@ -616,7 +606,7 @@ namespace MediaBrowser.Server.Implementations.Sync { // Save the job item now since conversion could take a while await _syncManager.UpdateSyncJobItemInternal(jobItem).ConfigureAwait(false); - await UpdateJobStatus(job).ConfigureAwait(false); + await UpdateJobStatus(jobItem.JobId).ConfigureAwait(false); try { @@ -630,7 +620,7 @@ namespace MediaBrowser.Server.Implementations.Sync { jobItem.Progress = pct / 2; await _syncManager.UpdateSyncJobItemInternal(jobItem).ConfigureAwait(false); - await UpdateJobStatus(job).ConfigureAwait(false); + await UpdateJobStatus(jobItem.JobId).ConfigureAwait(false); } }); @@ -642,7 +632,7 @@ namespace MediaBrowser.Server.Implementations.Sync }, innerProgress, cancellationToken); - _syncManager.OnConversionComplete(jobItem, job); + _syncManager.OnConversionComplete(jobItem); } catch (OperationCanceledException) { @@ -716,7 +706,7 @@ namespace MediaBrowser.Server.Implementations.Sync var startingIndex = mediaStreams.Count == 0 ? 0 : - (mediaStreams.Select(i => i.Index).Max() + 1); + mediaStreams.Select(i => i.Index).Max() + 1; foreach (var subtitle in subtitles) { @@ -775,8 +765,9 @@ namespace MediaBrowser.Server.Implementations.Sync private const int DatabaseProgressUpdateIntervalSeconds = 2; - private async Task Sync(SyncJobItem jobItem, SyncJob job, Audio item, User user, bool enableConversion, SyncOptions syncOptions, IProgress<double> progress, CancellationToken cancellationToken) + private async Task Sync(SyncJobItem jobItem, Audio item, User user, bool enableConversion, SyncOptions syncOptions, IProgress<double> progress, CancellationToken cancellationToken) { + var job = _syncManager.GetJob(jobItem.JobId); var jobOptions = _syncManager.GetAudioOptions(jobItem, job); var conversionOptions = new AudioOptions { @@ -803,7 +794,7 @@ namespace MediaBrowser.Server.Implementations.Sync jobItem.Status = SyncJobItemStatus.Converting; await _syncManager.UpdateSyncJobItemInternal(jobItem).ConfigureAwait(false); - await UpdateJobStatus(job).ConfigureAwait(false); + await UpdateJobStatus(jobItem.JobId).ConfigureAwait(false); try { @@ -817,7 +808,7 @@ namespace MediaBrowser.Server.Implementations.Sync { jobItem.Progress = pct / 2; await _syncManager.UpdateSyncJobItemInternal(jobItem).ConfigureAwait(false); - await UpdateJobStatus(job).ConfigureAwait(false); + await UpdateJobStatus(jobItem.JobId).ConfigureAwait(false); } }); @@ -828,7 +819,7 @@ namespace MediaBrowser.Server.Implementations.Sync }, innerProgress, cancellationToken); - _syncManager.OnConversionComplete(jobItem, job); + _syncManager.OnConversionComplete(jobItem); } catch (OperationCanceledException) { diff --git a/MediaBrowser.Server.Implementations/Sync/SyncManager.cs b/MediaBrowser.Server.Implementations/Sync/SyncManager.cs index fbbc6082a..044c8b93a 100644 --- a/MediaBrowser.Server.Implementations/Sync/SyncManager.cs +++ b/MediaBrowser.Server.Implementations/Sync/SyncManager.cs @@ -1,17 +1,14 @@ using MediaBrowser.Common.Configuration; using MediaBrowser.Common.Events; using MediaBrowser.Common.Extensions; -using MediaBrowser.Common.IO; using MediaBrowser.Common.ScheduledTasks; using MediaBrowser.Controller; -using MediaBrowser.Controller.Channels; using MediaBrowser.Controller.Drawing; using MediaBrowser.Controller.Dto; using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Entities.Audio; using MediaBrowser.Controller.Entities.TV; using MediaBrowser.Controller.Library; -using MediaBrowser.Controller.LiveTv; using MediaBrowser.Controller.MediaEncoding; using MediaBrowser.Controller.Playlists; using MediaBrowser.Controller.Sync; @@ -486,7 +483,7 @@ namespace MediaBrowser.Server.Implementations.Sync private string GetSyncProviderId(ISyncProvider provider) { - return (provider.GetType().Name).GetMD5().ToString("N"); + return provider.GetType().Name.GetMD5().ToString("N"); } public bool SupportsSync(BaseItem item) @@ -1120,7 +1117,7 @@ namespace MediaBrowser.Server.Implementations.Sync public SyncJobOptions GetAudioOptions(SyncJobItem jobItem, SyncJob job) { var options = GetSyncJobOptions(jobItem.TargetId, null, null); - + if (job.Bitrate.HasValue) { options.DeviceProfile.MaxStaticBitrate = job.Bitrate.Value; @@ -1129,7 +1126,7 @@ namespace MediaBrowser.Server.Implementations.Sync return options; } - public ISyncProvider GetSyncProvider(SyncJobItem jobItem, SyncJob job) + public ISyncProvider GetSyncProvider(SyncJobItem jobItem) { foreach (var provider in _providers) { @@ -1326,9 +1323,9 @@ namespace MediaBrowser.Server.Implementations.Sync return list; } - protected internal void OnConversionComplete(SyncJobItem item, SyncJob job) + protected internal void OnConversionComplete(SyncJobItem item) { - var syncProvider = GetSyncProvider(item, job); + var syncProvider = GetSyncProvider(item); if (syncProvider is AppSyncProvider) { return; diff --git a/MediaBrowser.Server.Implementations/Sync/SyncRepository.cs b/MediaBrowser.Server.Implementations/Sync/SyncRepository.cs index 7a1f276f9..464e8aa58 100644 --- a/MediaBrowser.Server.Implementations/Sync/SyncRepository.cs +++ b/MediaBrowser.Server.Implementations/Sync/SyncRepository.cs @@ -12,7 +12,6 @@ using System.Data; using System.Globalization; using System.IO; using System.Linq; -using System.Threading; using System.Threading.Tasks; namespace MediaBrowser.Server.Implementations.Sync @@ -105,7 +104,7 @@ namespace MediaBrowser.Server.Implementations.Sync // _updateJobCommand _updateJobCommand = _connection.CreateCommand(); - _updateJobCommand.CommandText = "update SyncJobs set TargetId=@TargetId,Name=@Name,Profile=@Profile,Quality=@Quality,Bitrate=@Bitrate,Status=@Status,Progress=@Progress,UserId=@UserId,ItemIds=@ItemIds,Category=@Category,ParentId=@ParentId,UnwatchedOnly=@UnwatchedOnly,ItemLimit=@ItemLimit,SyncNewContent=@SyncNewContent,DateCreated=@DateCreated,DateLastModified=@DateLastModified,ItemCount=@ItemCount where Id=@ID"; + _updateJobCommand.CommandText = "update SyncJobs set TargetId=@TargetId,Name=@Name,Profile=@Profile,Quality=@Quality,Bitrate=@Bitrate,Status=@Status,Progress=@Progress,UserId=@UserId,ItemIds=@ItemIds,Category=@Category,ParentId=@ParentId,UnwatchedOnly=@UnwatchedOnly,ItemLimit=@ItemLimit,SyncNewContent=@SyncNewContent,DateCreated=@DateCreated,DateLastModified=@DateLastModified,ItemCount=@ItemCount where Id=@Id"; _updateJobCommand.Parameters.Add(_updateJobCommand, "@Id"); _updateJobCommand.Parameters.Add(_updateJobCommand, "@TargetId"); diff --git a/MediaBrowser.Server.Implementations/Sync/SyncedMediaSourceProvider.cs b/MediaBrowser.Server.Implementations/Sync/SyncedMediaSourceProvider.cs index 456a1fcc1..efd37fa00 100644 --- a/MediaBrowser.Server.Implementations/Sync/SyncedMediaSourceProvider.cs +++ b/MediaBrowser.Server.Implementations/Sync/SyncedMediaSourceProvider.cs @@ -11,7 +11,6 @@ using System.Collections.Generic; using System.Linq; using System.Threading; using System.Threading.Tasks; -using MediaBrowser.Model.MediaInfo; namespace MediaBrowser.Server.Implementations.Sync { diff --git a/MediaBrowser.Server.Implementations/Sync/TargetDataProvider.cs b/MediaBrowser.Server.Implementations/Sync/TargetDataProvider.cs index 24c62a58f..106dc9115 100644 --- a/MediaBrowser.Server.Implementations/Sync/TargetDataProvider.cs +++ b/MediaBrowser.Server.Implementations/Sync/TargetDataProvider.cs @@ -1,5 +1,4 @@ using MediaBrowser.Common.Configuration; -using MediaBrowser.Common.IO; using MediaBrowser.Controller; using MediaBrowser.Controller.Sync; using MediaBrowser.Model.Logging; diff --git a/MediaBrowser.Server.Implementations/UserViews/CollectionFolderImageProvider.cs b/MediaBrowser.Server.Implementations/UserViews/CollectionFolderImageProvider.cs index de0b0e758..a66884f89 100644 --- a/MediaBrowser.Server.Implementations/UserViews/CollectionFolderImageProvider.cs +++ b/MediaBrowser.Server.Implementations/UserViews/CollectionFolderImageProvider.cs @@ -1,5 +1,4 @@ using MediaBrowser.Common.Configuration; -using MediaBrowser.Common.IO; using MediaBrowser.Controller.Drawing; using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Entities.Audio; diff --git a/MediaBrowser.Server.Implementations/UserViews/DynamicImageProvider.cs b/MediaBrowser.Server.Implementations/UserViews/DynamicImageProvider.cs index 167b5706e..911dbb0cb 100644 --- a/MediaBrowser.Server.Implementations/UserViews/DynamicImageProvider.cs +++ b/MediaBrowser.Server.Implementations/UserViews/DynamicImageProvider.cs @@ -1,5 +1,4 @@ using MediaBrowser.Common.Configuration; -using MediaBrowser.Common.IO; using MediaBrowser.Controller.Drawing; using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Entities.Audio; @@ -70,7 +69,7 @@ namespace MediaBrowser.Server.Implementations.UserViews var result = await view.GetItems(new InternalItemsQuery { - User = (view.UserId.HasValue ? _userManager.GetUserById(view.UserId.Value) : null), + User = view.UserId.HasValue ? _userManager.GetUserById(view.UserId.Value) : null, CollapseBoxSetItems = false, Recursive = recursive, ExcludeItemTypes = new[] { "UserView", "CollectionFolder" } @@ -135,7 +134,7 @@ namespace MediaBrowser.Server.Implementations.UserViews var view = item as UserView; if (view != null) { - return (IsUsingCollectionStrip(view)); + return IsUsingCollectionStrip(view); } return false; |
