diff --git a/BDInfo/BDROM.cs b/BDInfo/BDROM.cs index 95cd1da548..f00d9825a8 100644 --- a/BDInfo/BDROM.cs +++ b/BDInfo/BDROM.cs @@ -75,7 +75,7 @@ public delegate bool OnPlaylistFileScanError( public BDROM( string path, IFileSystem fileSystem, ITextEncoding textEncoding) { - if (string.IsNullOrWhiteSpace(path)) + if (string.IsNullOrEmpty(path)) { throw new ArgumentNullException("path"); } @@ -334,7 +334,7 @@ public void Scan() private FileSystemMetadata GetDirectoryBDMV( string path) { - if (string.IsNullOrWhiteSpace(path)) + if (string.IsNullOrEmpty(path)) { throw new ArgumentNullException("path"); } diff --git a/Emby.Dlna/DlnaManager.cs b/Emby.Dlna/DlnaManager.cs index 8caa086ee2..c0d40d5a47 100644 --- a/Emby.Dlna/DlnaManager.cs +++ b/Emby.Dlna/DlnaManager.cs @@ -132,55 +132,55 @@ private void LogUnmatchedProfile(DeviceIdentification profile) private bool IsMatch(DeviceIdentification deviceInfo, DeviceIdentification profileInfo) { - if (!string.IsNullOrWhiteSpace(profileInfo.DeviceDescription)) + if (!string.IsNullOrEmpty(profileInfo.DeviceDescription)) { if (deviceInfo.DeviceDescription == null || !IsRegexMatch(deviceInfo.DeviceDescription, profileInfo.DeviceDescription)) return false; } - if (!string.IsNullOrWhiteSpace(profileInfo.FriendlyName)) + if (!string.IsNullOrEmpty(profileInfo.FriendlyName)) { if (deviceInfo.FriendlyName == null || !IsRegexMatch(deviceInfo.FriendlyName, profileInfo.FriendlyName)) return false; } - if (!string.IsNullOrWhiteSpace(profileInfo.Manufacturer)) + if (!string.IsNullOrEmpty(profileInfo.Manufacturer)) { if (deviceInfo.Manufacturer == null || !IsRegexMatch(deviceInfo.Manufacturer, profileInfo.Manufacturer)) return false; } - if (!string.IsNullOrWhiteSpace(profileInfo.ManufacturerUrl)) + if (!string.IsNullOrEmpty(profileInfo.ManufacturerUrl)) { if (deviceInfo.ManufacturerUrl == null || !IsRegexMatch(deviceInfo.ManufacturerUrl, profileInfo.ManufacturerUrl)) return false; } - if (!string.IsNullOrWhiteSpace(profileInfo.ModelDescription)) + if (!string.IsNullOrEmpty(profileInfo.ModelDescription)) { if (deviceInfo.ModelDescription == null || !IsRegexMatch(deviceInfo.ModelDescription, profileInfo.ModelDescription)) return false; } - if (!string.IsNullOrWhiteSpace(profileInfo.ModelName)) + if (!string.IsNullOrEmpty(profileInfo.ModelName)) { if (deviceInfo.ModelName == null || !IsRegexMatch(deviceInfo.ModelName, profileInfo.ModelName)) return false; } - if (!string.IsNullOrWhiteSpace(profileInfo.ModelNumber)) + if (!string.IsNullOrEmpty(profileInfo.ModelNumber)) { if (deviceInfo.ModelNumber == null || !IsRegexMatch(deviceInfo.ModelNumber, profileInfo.ModelNumber)) return false; } - if (!string.IsNullOrWhiteSpace(profileInfo.ModelUrl)) + if (!string.IsNullOrEmpty(profileInfo.ModelUrl)) { if (deviceInfo.ModelUrl == null || !IsRegexMatch(deviceInfo.ModelUrl, profileInfo.ModelUrl)) return false; } - if (!string.IsNullOrWhiteSpace(profileInfo.SerialNumber)) + if (!string.IsNullOrEmpty(profileInfo.SerialNumber)) { if (deviceInfo.SerialNumber == null || !IsRegexMatch(deviceInfo.SerialNumber, profileInfo.SerialNumber)) return false; @@ -235,7 +235,7 @@ private bool IsMatch(IDictionary headers, DeviceIdentification p private bool IsMatch(IDictionary headers, HttpHeaderInfo header) { // Handle invalid user setup - if (string.IsNullOrWhiteSpace(header.Name)) + if (string.IsNullOrEmpty(header.Name)) { return false; } @@ -332,7 +332,7 @@ private DeviceProfile ParseProfileFile(string path, DeviceProfileType type) public DeviceProfile GetProfile(string id) { - if (string.IsNullOrWhiteSpace(id)) + if (string.IsNullOrEmpty(id)) { throw new ArgumentNullException("id"); } @@ -429,7 +429,7 @@ public void CreateProfile(DeviceProfile profile) { profile = ReserializeProfile(profile); - if (string.IsNullOrWhiteSpace(profile.Name)) + if (string.IsNullOrEmpty(profile.Name)) { throw new ArgumentException("Profile is missing Name"); } @@ -444,11 +444,11 @@ public void UpdateProfile(DeviceProfile profile) { profile = ReserializeProfile(profile); - if (string.IsNullOrWhiteSpace(profile.Id)) + if (string.IsNullOrEmpty(profile.Id)) { throw new ArgumentException("Profile is missing Id"); } - if (string.IsNullOrWhiteSpace(profile.Name)) + if (string.IsNullOrEmpty(profile.Name)) { throw new ArgumentException("Profile is missing Name"); } diff --git a/Emby.Dlna/Eventing/EventManager.cs b/Emby.Dlna/Eventing/EventManager.cs index 67eac640e1..201ed6d653 100644 --- a/Emby.Dlna/Eventing/EventManager.cs +++ b/Emby.Dlna/Eventing/EventManager.cs @@ -118,7 +118,7 @@ private EventSubscriptionResponse GetEventSubscriptionResponse(string subscripti }; response.Headers["SID"] = subscriptionId; - response.Headers["TIMEOUT"] = string.IsNullOrWhiteSpace(requestedTimeoutString) ? ("SECOND-" + timeoutSeconds.ToString(_usCulture)) : requestedTimeoutString; + response.Headers["TIMEOUT"] = string.IsNullOrEmpty(requestedTimeoutString) ? ("SECOND-" + timeoutSeconds.ToString(_usCulture)) : requestedTimeoutString; return response; } diff --git a/Emby.Dlna/PlayTo/Device.cs b/Emby.Dlna/PlayTo/Device.cs index 8fa81b3bbc..62dc0eed5c 100644 --- a/Emby.Dlna/PlayTo/Device.cs +++ b/Emby.Dlna/PlayTo/Device.cs @@ -106,27 +106,17 @@ public Device(DeviceInfo deviceProperties, IHttpClient httpClient, ILogger logge _timerFactory = timerFactory; } - private int GetPlaybackTimerIntervalMs() - { - return 1000; - } - - private int GetInactiveTimerIntervalMs() - { - return 60000; - } - public void Start() { - _timer = _timerFactory.Create(TimerCallback, null, GetPlaybackTimerIntervalMs(), GetInactiveTimerIntervalMs()); - - _timerActive = false; + _logger.Debug("Dlna Device.Start"); + _timer = _timerFactory.Create(TimerCallback, null, 1000, Timeout.Infinite); } private DateTime _lastVolumeRefresh; + private bool _volumeRefreshActive; private void RefreshVolumeIfNeeded() { - if (!_timerActive) + if (!_volumeRefreshActive) { return; } @@ -155,21 +145,17 @@ private async void RefreshVolume(CancellationToken cancellationToken) } private readonly object _timerLock = new object(); - private bool _timerActive; - private void RestartTimer() + private void RestartTimer(bool immediate = false) { - if (_disposed) - return; - lock (_timerLock) { - if (!_timerActive) - { - _logger.Debug("RestartTimer"); - _timer.Change(10, GetPlaybackTimerIntervalMs()); - } + if (_disposed) + return; - _timerActive = true; + _volumeRefreshActive = true; + + var time = immediate ? 100 : 10000; + _timer.Change(time, Timeout.Infinite); } } @@ -183,18 +169,9 @@ private void RestartTimerInactive() if (_disposed) return; - if (_timerActive) - { - _logger.Debug("RestartTimerInactive"); - var interval = GetInactiveTimerIntervalMs(); + _volumeRefreshActive = false; - if (_timer != null) - { - _timer.Change(interval, interval); - } - } - - _timerActive = false; + _timer.Change(Timeout.Infinite, Timeout.Infinite); } } @@ -331,6 +308,8 @@ public async Task Seek(TimeSpan value, CancellationToken cancellationToken) await new SsdpHttpClient(_httpClient, _config).SendCommandAsync(Properties.BaseUrl, service, command.Name, avCommands.BuildPost(command, service.ServiceType, String.Format("{0:hh}:{0:mm}:{0:ss}", value), "REL_TIME")) .ConfigureAwait(false); + + RestartTimer(true); } public async Task SetAvTransport(string url, string header, string metaData, CancellationToken cancellationToken) @@ -372,7 +351,7 @@ public async Task SetAvTransport(string url, string header, string metaData, Can // Others won't } - RestartTimer(); + RestartTimer(true); } private string CreateDidlMeta(string value) @@ -404,6 +383,8 @@ public async Task SetPlay(CancellationToken cancellationToken) var avCommands = await GetAVProtocolAsync(cancellationToken).ConfigureAwait(false); await SetPlay(avCommands, cancellationToken).ConfigureAwait(false); + + RestartTimer(true); } public async Task SetStop(CancellationToken cancellationToken) @@ -418,6 +399,8 @@ public async Task SetStop(CancellationToken cancellationToken) await new SsdpHttpClient(_httpClient, _config).SendCommandAsync(Properties.BaseUrl, service, command.Name, avCommands.BuildPost(command, service.ServiceType, 1)) .ConfigureAwait(false); + + RestartTimer(true); } public async Task SetPause(CancellationToken cancellationToken) @@ -434,21 +417,20 @@ public async Task SetPause(CancellationToken cancellationToken) .ConfigureAwait(false); TransportState = TRANSPORTSTATE.PAUSED; + + RestartTimer(true); } #endregion #region Get data - private int _successiveStopCount; private int _connectFailureCount; private async void TimerCallback(object sender) { if (_disposed) return; - const int maxSuccessiveStopReturns = 5; - try { var cancellationToken = CancellationToken.None; @@ -496,16 +478,10 @@ private async void TimerCallback(object sender) // If we're not playing anything make sure we don't get data more often than neccessry to keep the Session alive if (transportState.Value == TRANSPORTSTATE.STOPPED) { - _successiveStopCount++; - - if (_successiveStopCount >= maxSuccessiveStopReturns) - { - RestartTimerInactive(); - } + RestartTimerInactive(); } else { - _successiveStopCount = 0; RestartTimer(); } } @@ -514,14 +490,13 @@ private async void TimerCallback(object sender) RestartTimerInactive(); } } - catch (HttpException) + catch (Exception ex) { if (_disposed) return; //_logger.ErrorException("Error updating device info for {0}", ex, Properties.Name); - _successiveStopCount++; _connectFailureCount++; if (_connectFailureCount >= 3) @@ -534,24 +509,7 @@ private async void TimerCallback(object sender) return; } } - if (_successiveStopCount >= maxSuccessiveStopReturns) - { - RestartTimerInactive(); - } - } - catch (Exception ex) - { - if (_disposed) - return; - - _logger.ErrorException("Error updating device info for {0}", ex, Properties.Name); - - _successiveStopCount++; - - if (_successiveStopCount >= maxSuccessiveStopReturns) - { - RestartTimerInactive(); - } + RestartTimerInactive(); } } @@ -885,6 +843,7 @@ private async Task GetAVProtocolAsync(CancellationToken cance string url = NormalizeUrl(Properties.BaseUrl, avService.ScpdUrl); var httpClient = new SsdpHttpClient(_httpClient, _config); + var document = await httpClient.GetDataAsync(url, cancellationToken).ConfigureAwait(false); avCommands = TransportCommands.Create(document); @@ -916,6 +875,7 @@ private async Task GetRenderingProtocolAsync(CancellationToke string url = NormalizeUrl(Properties.BaseUrl, avService.ScpdUrl); var httpClient = new SsdpHttpClient(_httpClient, _config); + _logger.Debug("Dlna Device.GetRenderingProtocolAsync"); var document = await httpClient.GetDataAsync(url, cancellationToken).ConfigureAwait(false); rendererCommands = TransportCommands.Create(document); diff --git a/Emby.Dlna/PlayTo/PlayToController.cs b/Emby.Dlna/PlayTo/PlayToController.cs index 0ef0c10a3b..54942b2e99 100644 --- a/Emby.Dlna/PlayTo/PlayToController.cs +++ b/Emby.Dlna/PlayTo/PlayToController.cs @@ -364,7 +364,7 @@ public async Task SendPlayCommand(PlayRequest command, CancellationToken cancell Playlist.AddRange(playlist); } - if (!String.IsNullOrWhiteSpace(command.ControllingUserId)) + if (!String.IsNullOrEmpty(command.ControllingUserId)) { _sessionManager.LogSessionActivity(_session.Client, _session.ApplicationVersion, _session.DeviceId, _session.DeviceName, _session.RemoteEndPoint, user); @@ -435,26 +435,6 @@ private bool EnableClientSideSeek(StreamInfo info) return info.IsDirectStream; } - public Task SendUserDataChangeInfo(UserDataChangeInfo info, CancellationToken cancellationToken) - { - return Task.FromResult(true); - } - - public Task SendRestartRequiredNotification(CancellationToken cancellationToken) - { - return Task.FromResult(true); - } - - public Task SendServerRestartNotification(CancellationToken cancellationToken) - { - return Task.FromResult(true); - } - - public Task SendSessionEndedNotification(SessionInfoDto sessionInfo, CancellationToken cancellationToken) - { - return Task.FromResult(true); - } - public Task SendPlaybackStartNotification(SessionInfoDto sessionInfo, CancellationToken cancellationToken) { return Task.FromResult(true); @@ -465,16 +445,6 @@ public Task SendPlaybackStoppedNotification(SessionInfoDto sessionInfo, Cancella return Task.FromResult(true); } - public Task SendServerShutdownNotification(CancellationToken cancellationToken) - { - return Task.FromResult(true); - } - - public Task SendLibraryUpdateInfo(LibraryUpdateInfo info, CancellationToken cancellationToken) - { - return Task.FromResult(true); - } - #endregion #region Playlist @@ -880,7 +850,7 @@ public async Task GetMediaSource(CancellationToken cancellation private static string GetItemId(string url) { - if (string.IsNullOrWhiteSpace(url)) + if (string.IsNullOrEmpty(url)) { throw new ArgumentNullException("url"); } @@ -906,7 +876,7 @@ private static string GetItemId(string url) public static StreamParams ParseFromUrl(string url, ILibraryManager libraryManager, IMediaSourceManager mediaSourceManager) { - if (string.IsNullOrWhiteSpace(url)) + if (string.IsNullOrEmpty(url)) { throw new ArgumentNullException("url"); } @@ -973,7 +943,7 @@ public static StreamParams ParseFromUrl(string url, ILibraryManager libraryManag } } - request.Item = string.IsNullOrWhiteSpace(request.ItemId) + request.Item = string.IsNullOrEmpty(request.ItemId) ? null : libraryManager.GetItemById(parsedId); diff --git a/Emby.Dlna/PlayTo/SsdpHttpClient.cs b/Emby.Dlna/PlayTo/SsdpHttpClient.cs index b2942adce0..eaafaa65b1 100644 --- a/Emby.Dlna/PlayTo/SsdpHttpClient.cs +++ b/Emby.Dlna/PlayTo/SsdpHttpClient.cs @@ -149,7 +149,7 @@ private Task PostSoapDataAsync(string url, options.RequestHeaders["Pragma"] = "no-cache"; options.RequestHeaders["FriendlyName.DLNA.ORG"] = FriendlyName; - if (!string.IsNullOrWhiteSpace(header)) + if (!string.IsNullOrEmpty(header)) { options.RequestHeaders["contentFeatures.dlna.org"] = header; } diff --git a/Emby.Dlna/Server/DescriptionXmlBuilder.cs b/Emby.Dlna/Server/DescriptionXmlBuilder.cs index bba4adc5f4..de8552648c 100644 --- a/Emby.Dlna/Server/DescriptionXmlBuilder.cs +++ b/Emby.Dlna/Server/DescriptionXmlBuilder.cs @@ -22,12 +22,12 @@ public class DescriptionXmlBuilder public DescriptionXmlBuilder(DeviceProfile profile, string serverUdn, string serverAddress, string serverName, string serverId) { - if (string.IsNullOrWhiteSpace(serverUdn)) + if (string.IsNullOrEmpty(serverUdn)) { throw new ArgumentNullException("serverUdn"); } - if (string.IsNullOrWhiteSpace(serverAddress)) + if (string.IsNullOrEmpty(serverAddress)) { throw new ArgumentNullException("serverAddress"); } @@ -186,7 +186,7 @@ private void AppendDeviceProperties(StringBuilder builder) builder.Append("" + Escape(_profile.ModelNumber ?? string.Empty) + ""); builder.Append("" + Escape(_profile.ModelUrl ?? string.Empty) + ""); - if (string.IsNullOrWhiteSpace(_profile.SerialNumber)) + if (string.IsNullOrEmpty(_profile.SerialNumber)) { builder.Append("" + Escape(_serverId) + ""); } @@ -203,7 +203,7 @@ private void AppendDeviceProperties(StringBuilder builder) //builder.Append("" + Escape(_serverAddress) + ""); } - if (!string.IsNullOrWhiteSpace(_profile.SonyAggregationFlags)) + if (!string.IsNullOrEmpty(_profile.SonyAggregationFlags)) { builder.Append("" + Escape(_profile.SonyAggregationFlags) + ""); } @@ -211,7 +211,7 @@ private void AppendDeviceProperties(StringBuilder builder) private string GetFriendlyName() { - if (string.IsNullOrWhiteSpace(_profile.FriendlyName)) + if (string.IsNullOrEmpty(_profile.FriendlyName)) { return "Emby - " + _serverName; } @@ -277,7 +277,7 @@ private void AppendServiceList(StringBuilder builder) private string BuildUrl(string url) { - if (string.IsNullOrWhiteSpace(url)) + if (string.IsNullOrEmpty(url)) { return string.Empty; } diff --git a/Emby.Drawing.ImageMagick/ImageMagickEncoder.cs b/Emby.Drawing.ImageMagick/ImageMagickEncoder.cs index 3b3f7cf0ab..004e38facc 100644 --- a/Emby.Drawing.ImageMagick/ImageMagickEncoder.cs +++ b/Emby.Drawing.ImageMagick/ImageMagickEncoder.cs @@ -138,7 +138,7 @@ public string EncodeImage(string inputPath, DateTime dateModified, string output // Even if the caller specified 100, don't use it because it takes forever quality = Math.Min(quality, 99); - if (string.IsNullOrWhiteSpace(options.BackgroundColor) || !HasTransparency(inputPath)) + if (string.IsNullOrEmpty(options.BackgroundColor) || !HasTransparency(inputPath)) { using (var originalImage = new MagickWand(inputPath)) { @@ -216,7 +216,7 @@ public string EncodeImage(string inputPath, DateTime dateModified, string output private void AddForegroundLayer(MagickWand wand, ImageProcessingOptions options) { - if (string.IsNullOrWhiteSpace(options.ForegroundLayer)) + if (string.IsNullOrEmpty(options.ForegroundLayer)) { return; } diff --git a/Emby.Drawing/Common/ImageHeader.cs b/Emby.Drawing/Common/ImageHeader.cs index 8d56d365d9..121e20debd 100644 --- a/Emby.Drawing/Common/ImageHeader.cs +++ b/Emby.Drawing/Common/ImageHeader.cs @@ -52,7 +52,7 @@ public static ImageSize GetDimensions(string path, ILogger logger, IFileSystem f { var extension = Path.GetExtension(path); - if (string.IsNullOrWhiteSpace(extension)) + if (string.IsNullOrEmpty(extension)) { throw new ArgumentException("ImageHeader doesn't support image file"); } diff --git a/Emby.Photos/PhotoProvider.cs b/Emby.Photos/PhotoProvider.cs index aa24e0b442..29b99a096d 100644 --- a/Emby.Photos/PhotoProvider.cs +++ b/Emby.Photos/PhotoProvider.cs @@ -17,7 +17,7 @@ namespace Emby.Photos { - public class PhotoProvider : ICustomMetadataProvider, IForcedProvider + public class PhotoProvider : ICustomMetadataProvider, IForcedProvider, IHasItemChangeMonitor { private readonly ILogger _logger; private readonly IFileSystem _fileSystem; @@ -30,6 +30,20 @@ public PhotoProvider(ILogger logger, IFileSystem fileSystem, IImageProcessor ima _imageProcessor = imageProcessor; } + public bool HasChanged(BaseItem item, IDirectoryService directoryService) + { + if (!string.IsNullOrWhiteSpace(item.Path) && item.LocationType == LocationType.FileSystem) + { + var file = directoryService.GetFile(item.Path); + if (file != null && file.LastWriteTimeUtc != item.DateModified) + { + return true; + } + } + + return false; + } + // These are causing taglib to hang private string[] _includextensions = new string[] { ".jpg", ".jpeg", ".png", ".tiff", ".cr2" }; @@ -108,7 +122,10 @@ public Task FetchAsync(Photo item, MetadataRefreshOptions option if (!string.IsNullOrWhiteSpace(image.ImageTag.Title)) { - item.Name = image.ImageTag.Title; + if (!item.LockedFields.Contains(MetadataFields.Name)) + { + item.Name = image.ImageTag.Title; + } } var dateTaken = image.ImageTag.DateTime; diff --git a/Emby.Server.Implementations/Activity/ActivityLogEntryPoint.cs b/Emby.Server.Implementations/Activity/ActivityLogEntryPoint.cs index af48386393..5405401fbc 100644 --- a/Emby.Server.Implementations/Activity/ActivityLogEntryPoint.cs +++ b/Emby.Server.Implementations/Activity/ActivityLogEntryPoint.cs @@ -183,7 +183,7 @@ void _sessionManager_SessionEnded(object sender, SessionEventArgs e) string name; var session = e.SessionInfo; - if (string.IsNullOrWhiteSpace(session.UserName)) + if (string.IsNullOrEmpty(session.UserName)) { name = string.Format(_localization.GetLocalizedString("DeviceOfflineWithName"), session.DeviceName); @@ -309,7 +309,7 @@ void _sessionManager_SessionStarted(object sender, SessionEventArgs e) string name; var session = e.SessionInfo; - if (string.IsNullOrWhiteSpace(session.UserName)) + if (string.IsNullOrEmpty(session.UserName)) { name = string.Format(_localization.GetLocalizedString("DeviceOnlineWithName"), session.DeviceName); @@ -424,11 +424,11 @@ void _taskManager_TaskCompleted(object sender, TaskCompletionEventArgs e) { var vals = new List(); - if (!string.IsNullOrWhiteSpace(e.Result.ErrorMessage)) + if (!string.IsNullOrEmpty(e.Result.ErrorMessage)) { vals.Add(e.Result.ErrorMessage); } - if (!string.IsNullOrWhiteSpace(e.Result.LongErrorMessage)) + if (!string.IsNullOrEmpty(e.Result.LongErrorMessage)) { vals.Add(e.Result.LongErrorMessage); } diff --git a/Emby.Server.Implementations/Activity/ActivityManager.cs b/Emby.Server.Implementations/Activity/ActivityManager.cs index 9a3f1ae472..35606f5e41 100644 --- a/Emby.Server.Implementations/Activity/ActivityManager.cs +++ b/Emby.Server.Implementations/Activity/ActivityManager.cs @@ -39,7 +39,7 @@ public QueryResult GetActivityLogEntries(DateTime? minDate, in { var result = _repo.GetActivityLogEntries(minDate, startIndex, limit); - foreach (var item in result.Items.Where(i => !string.IsNullOrWhiteSpace(i.UserId))) + foreach (var item in result.Items.Where(i => !string.IsNullOrEmpty(i.UserId))) { var user = _userManager.GetUserById(item.UserId); diff --git a/Emby.Server.Implementations/ApplicationHost.cs b/Emby.Server.Implementations/ApplicationHost.cs index 79dae9292b..fb1cd3ff92 100644 --- a/Emby.Server.Implementations/ApplicationHost.cs +++ b/Emby.Server.Implementations/ApplicationHost.cs @@ -2112,7 +2112,7 @@ public string FriendlyName { get { - return string.IsNullOrWhiteSpace(ServerConfigurationManager.Configuration.ServerName) + return string.IsNullOrEmpty(ServerConfigurationManager.Configuration.ServerName) ? Environment.MachineName : ServerConfigurationManager.Configuration.ServerName; } @@ -2311,7 +2311,7 @@ protected virtual void ConfigureAutoRunInternal(bool autorun) /// The hostname in private static string GetHostnameFromExternalDns(string externalDns) { - if (string.IsNullOrWhiteSpace(externalDns)) + if (string.IsNullOrEmpty(externalDns)) { return "localhost"; } diff --git a/Emby.Server.Implementations/Channels/ChannelConfigurations.cs b/Emby.Server.Implementations/Channels/ChannelConfigurations.cs deleted file mode 100644 index ef0973e7f4..0000000000 --- a/Emby.Server.Implementations/Channels/ChannelConfigurations.cs +++ /dev/null @@ -1,29 +0,0 @@ -using MediaBrowser.Common.Configuration; -using MediaBrowser.Model.Configuration; -using System.Collections.Generic; - -namespace Emby.Server.Implementations.Channels -{ - public static class ChannelConfigurationExtension - { - public static ChannelOptions GetChannelsConfiguration(this IConfigurationManager manager) - { - return manager.GetConfiguration("channels"); - } - } - - public class ChannelConfigurationFactory : IConfigurationFactory - { - public IEnumerable GetConfigurations() - { - return new List - { - new ConfigurationStore - { - Key = "channels", - ConfigurationType = typeof (ChannelOptions) - } - }; - } - } -} diff --git a/Emby.Server.Implementations/Channels/ChannelDynamicMediaSourceProvider.cs b/Emby.Server.Implementations/Channels/ChannelDynamicMediaSourceProvider.cs index 7eb83a63f7..80becf1ee9 100644 --- a/Emby.Server.Implementations/Channels/ChannelDynamicMediaSourceProvider.cs +++ b/Emby.Server.Implementations/Channels/ChannelDynamicMediaSourceProvider.cs @@ -38,7 +38,7 @@ public async Task> GetMediaSources(IHasMediaSources return new List(); } - public Task> OpenMediaSource(string openToken, CancellationToken cancellationToken) + public Task> OpenMediaSource(string openToken, CancellationToken cancellationToken) { throw new NotImplementedException(); } diff --git a/Emby.Server.Implementations/Channels/ChannelManager.cs b/Emby.Server.Implementations/Channels/ChannelManager.cs index c566ca25bd..ff56f8adad 100644 --- a/Emby.Server.Implementations/Channels/ChannelManager.cs +++ b/Emby.Server.Implementations/Channels/ChannelManager.cs @@ -94,7 +94,7 @@ public IEnumerable GetInstalledChannelIds() public Task> GetChannelsInternal(ChannelQuery query, CancellationToken cancellationToken) { - var user = string.IsNullOrWhiteSpace(query.UserId) + var user = string.IsNullOrEmpty(query.UserId) ? null : _userManager.GetUserById(query.UserId); @@ -172,7 +172,7 @@ public Task> GetChannelsInternal(ChannelQuery query, Cancel public async Task> GetChannels(ChannelQuery query, CancellationToken cancellationToken) { - var user = string.IsNullOrWhiteSpace(query.UserId) + var user = string.IsNullOrEmpty(query.UserId) ? null : _userManager.GetUserById(query.UserId); @@ -240,23 +240,23 @@ private Channel GetChannelEntity(IChannel channel) return item; } - private List GetSavedMediaSources(BaseItem item) + private List GetSavedMediaSources(BaseItem item) { - var path = Path.Combine(item.GetInternalMetadataPath(), "channelmediasources.json"); + var path = Path.Combine(item.GetInternalMetadataPath(), "channelmediasourceinfos.json"); try { - return _jsonSerializer.DeserializeFromFile>(path) ?? new List(); + return _jsonSerializer.DeserializeFromFile>(path) ?? new List(); } catch { - return new List(); + return new List(); } } - private void SaveMediaSources(BaseItem item, List mediaSources) + private void SaveMediaSources(BaseItem item, List mediaSources) { - var path = Path.Combine(item.GetInternalMetadataPath(), "channelmediasources.json"); + var path = Path.Combine(item.GetInternalMetadataPath(), "channelmediasourceinfos.json"); if (mediaSources == null || mediaSources.Count == 0) { @@ -278,10 +278,10 @@ private void SaveMediaSources(BaseItem item, List mediaSources public IEnumerable GetStaticMediaSources(BaseItem item, CancellationToken cancellationToken) { - IEnumerable results = GetSavedMediaSources(item); + IEnumerable results = GetSavedMediaSources(item); - return SortMediaInfoResults(results) - .Select(i => GetMediaSource(item, i)) + return results + .Select(i => NormalizeMediaSource(item, i)) .ToList(); } @@ -292,7 +292,7 @@ public async Task> GetDynamicMediaSources(BaseItem var requiresCallback = channelPlugin as IRequiresMediaInfoCallback; - IEnumerable results; + IEnumerable results; if (requiresCallback != null) { @@ -301,20 +301,20 @@ public async Task> GetDynamicMediaSources(BaseItem } else { - results = new List(); + results = new List(); } - return SortMediaInfoResults(results) - .Select(i => GetMediaSource(item, i)) + return results + .Select(i => NormalizeMediaSource(item, i)) .ToList(); } - private readonly ConcurrentDictionary>> _channelItemMediaInfo = - new ConcurrentDictionary>>(); + private readonly ConcurrentDictionary>> _channelItemMediaInfo = + new ConcurrentDictionary>>(); - private async Task> GetChannelItemMediaSourcesInternal(IRequiresMediaInfoCallback channel, string id, CancellationToken cancellationToken) + private async Task> GetChannelItemMediaSourcesInternal(IRequiresMediaInfoCallback channel, string id, CancellationToken cancellationToken) { - Tuple> cachedInfo; + Tuple> cachedInfo; if (_channelItemMediaInfo.TryGetValue(id, out cachedInfo)) { @@ -328,53 +328,22 @@ private async Task> GetChannelItemMediaSourcesInte .ConfigureAwait(false); var list = mediaInfo.ToList(); - var item2 = new Tuple>(DateTime.UtcNow, list); + var item2 = new Tuple>(DateTime.UtcNow, list); _channelItemMediaInfo.AddOrUpdate(id, item2, (key, oldValue) => item2); return list; } - private MediaSourceInfo GetMediaSource(BaseItem item, ChannelMediaInfo info) + private MediaSourceInfo NormalizeMediaSource(BaseItem item, MediaSourceInfo info) { - var source = info.ToMediaSource(item.Id); + info.RunTimeTicks = info.RunTimeTicks ?? item.RunTimeTicks; - source.RunTimeTicks = source.RunTimeTicks ?? item.RunTimeTicks; - - return source; - } - - private IEnumerable SortMediaInfoResults(IEnumerable channelMediaSources) - { - var list = channelMediaSources.ToList(); - - var options = _config.GetChannelsConfiguration(); - - var width = options.PreferredStreamingWidth; - - if (width.HasValue) - { - var val = width.Value; - - var res = list - .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) - .ToList(); - - - return res; - } - - return list - .OrderByDescending(i => i.Width ?? 0) - .ThenBy(list.IndexOf); + return info; } private async Task GetChannel(IChannel channelInfo, CancellationToken cancellationToken) { - var parentFolder = GetInternalChannelFolder(cancellationToken); - var parentFolderId = parentFolder.Id; + var parentFolderId = Guid.Empty; var id = GetInternalChannelId(channelInfo.Name); var idString = id.ToString("N"); @@ -475,7 +444,7 @@ public ChannelFeatures[] GetAllChannelFeatures() public ChannelFeatures GetChannelFeatures(string id) { - if (string.IsNullOrWhiteSpace(id)) + if (string.IsNullOrEmpty(id)) { throw new ArgumentNullException("id"); } @@ -488,7 +457,7 @@ public ChannelFeatures GetChannelFeatures(string id) public bool SupportsSync(string channelId) { - if (string.IsNullOrWhiteSpace(channelId)) + if (string.IsNullOrEmpty(channelId)) { throw new ArgumentNullException("channelId"); } @@ -525,7 +494,7 @@ public ChannelFeatures GetChannelFeaturesDto(Channel channel, private Guid GetInternalChannelId(string name) { - if (string.IsNullOrWhiteSpace(name)) + if (string.IsNullOrEmpty(name)) { throw new ArgumentNullException("name"); } @@ -534,7 +503,7 @@ private Guid GetInternalChannelId(string name) public async Task> GetLatestChannelItems(AllChannelMediaQuery query, CancellationToken cancellationToken) { - var user = string.IsNullOrWhiteSpace(query.UserId) + var user = string.IsNullOrEmpty(query.UserId) ? null : _userManager.GetUserById(query.UserId); @@ -581,11 +550,11 @@ public async Task> GetLatestChannelItems(AllChannelMedi public async Task> GetLatestChannelItemsInternal(AllChannelMediaQuery query, CancellationToken cancellationToken) { - var user = string.IsNullOrWhiteSpace(query.UserId) + var user = string.IsNullOrEmpty(query.UserId) ? null : _userManager.GetUserById(query.UserId); - if (!string.IsNullOrWhiteSpace(query.UserId) && user == null) + if (!string.IsNullOrEmpty(query.UserId) && user == null) { throw new ArgumentException("User not found."); } @@ -816,7 +785,7 @@ public async Task> GetAllMediaInternal(AllChannelMediaQuer public async Task> GetAllMedia(AllChannelMediaQuery query, CancellationToken cancellationToken) { - var user = string.IsNullOrWhiteSpace(query.UserId) + var user = string.IsNullOrEmpty(query.UserId) ? null : _userManager.GetUserById(query.UserId); @@ -924,7 +893,7 @@ public async Task> GetChannelItemsInternal(ChannelItemQuer } } - var user = string.IsNullOrWhiteSpace(query.UserId) + var user = string.IsNullOrEmpty(query.UserId) ? null : _userManager.GetUserById(query.UserId); @@ -968,7 +937,7 @@ public async Task> GetChannelItemsInternal(ChannelItemQuer public async Task> GetChannelItems(ChannelItemQuery query, CancellationToken cancellationToken) { - var user = string.IsNullOrWhiteSpace(query.UserId) + var user = string.IsNullOrEmpty(query.UserId) ? null : _userManager.GetUserById(query.UserId); @@ -1064,7 +1033,7 @@ private async Task GetChannelItems(IChannel channel, SortDescending = sortDescending }; - if (!string.IsNullOrWhiteSpace(folderId)) + if (!string.IsNullOrEmpty(folderId)) { var categoryItem = _libraryManager.GetItemById(new Guid(folderId)); @@ -1121,7 +1090,7 @@ private string GetChannelDataCachePath(IChannel channel, userCacheKey = hasCacheKey.GetCacheKey(userId) ?? string.Empty; } - var filename = string.IsNullOrWhiteSpace(folderId) ? "root" : folderId; + var filename = string.IsNullOrEmpty(folderId) ? "root" : folderId; filename += userCacheKey; var version = (channel.DataVersion ?? string.Empty).GetMD5().ToString("N"); @@ -1363,7 +1332,7 @@ private BaseItem GetChannelItemEntity(ChannelItemInfo info, IChannel channelProv item.Path = mediaSource == null ? null : mediaSource.Path; } - if (!string.IsNullOrWhiteSpace(info.ImageUrl) && !item.HasImage(ImageType.Primary)) + if (!string.IsNullOrEmpty(info.ImageUrl) && !item.HasImage(ImageType.Primary)) { item.SetImagePath(ImageType.Primary, info.ImageUrl); } @@ -1523,22 +1492,6 @@ private IEnumerable ApplyFilter(IEnumerable items, ItemFilte return items; } - - public BaseItemDto GetChannelFolder(string userId, CancellationToken cancellationToken) - { - var user = string.IsNullOrEmpty(userId) ? null : _userManager.GetUserById(userId); - - var folder = GetInternalChannelFolder(cancellationToken); - - return _dtoService.GetBaseItemDto(folder, new DtoOptions(), user); - } - - public Folder GetInternalChannelFolder(CancellationToken cancellationToken) - { - var name = _localization.GetLocalizedString("Channels"); - - return _libraryManager.GetNamedView(name, "channels", "zz_" + name, cancellationToken); - } } public class ChannelsEntryPoint : IServerEntryPoint @@ -1593,7 +1546,7 @@ private void SetSavedLastChannels(string value) { try { - if (string.IsNullOrWhiteSpace(value)) + if (string.IsNullOrEmpty(value)) { _fileSystem.DeleteFile(DataPath); diff --git a/Emby.Server.Implementations/Data/SqliteDisplayPreferencesRepository.cs b/Emby.Server.Implementations/Data/SqliteDisplayPreferencesRepository.cs index e6afcd4102..f33fdab63c 100644 --- a/Emby.Server.Implementations/Data/SqliteDisplayPreferencesRepository.cs +++ b/Emby.Server.Implementations/Data/SqliteDisplayPreferencesRepository.cs @@ -98,7 +98,7 @@ public void SaveDisplayPreferences(DisplayPreferences displayPreferences, Guid u { throw new ArgumentNullException("displayPreferences"); } - if (string.IsNullOrWhiteSpace(displayPreferences.Id)) + if (string.IsNullOrEmpty(displayPreferences.Id)) { throw new ArgumentNullException("displayPreferences.Id"); } @@ -174,7 +174,7 @@ public void SaveAllDisplayPreferences(IEnumerable displayPre /// item public DisplayPreferences GetDisplayPreferences(string displayPreferencesId, Guid userId, string client) { - if (string.IsNullOrWhiteSpace(displayPreferencesId)) + if (string.IsNullOrEmpty(displayPreferencesId)) { throw new ArgumentNullException("displayPreferencesId"); } diff --git a/Emby.Server.Implementations/Devices/DeviceManager.cs b/Emby.Server.Implementations/Devices/DeviceManager.cs index 73f4995216..5ada82f8a1 100644 --- a/Emby.Server.Implementations/Devices/DeviceManager.cs +++ b/Emby.Server.Implementations/Devices/DeviceManager.cs @@ -52,7 +52,7 @@ public DeviceManager(IDeviceRepository repo, IUserManager userManager, IFileSyst public DeviceInfo RegisterDevice(string reportedId, string name, string appName, string appVersion, string usedByUserId, string usedByUserName) { - if (string.IsNullOrWhiteSpace(reportedId)) + if (string.IsNullOrEmpty(reportedId)) { throw new ArgumentNullException("reportedId"); } @@ -85,7 +85,7 @@ public DeviceInfo RegisterDevice(string reportedId, string name, string appName, save = true; } - if (!string.IsNullOrWhiteSpace(usedByUserId)) + if (!string.IsNullOrEmpty(usedByUserId)) { if (!string.Equals(device.LastUserId, usedByUserId, StringComparison.Ordinal) || !string.Equals(device.LastUserName, usedByUserName, StringComparison.Ordinal)) @@ -149,7 +149,7 @@ public QueryResult GetDevices(DeviceQuery query) }); } - if (!string.IsNullOrWhiteSpace(query.UserId)) + if (!string.IsNullOrEmpty(query.UserId)) { var user = _userManager.GetUserById(query.UserId); @@ -265,7 +265,7 @@ public bool CanAccessDevice(User user, string deviceId) { throw new ArgumentException("user not found"); } - if (string.IsNullOrWhiteSpace(deviceId)) + if (string.IsNullOrEmpty(deviceId)) { throw new ArgumentNullException("deviceId"); } diff --git a/Emby.Server.Implementations/Dto/DtoService.cs b/Emby.Server.Implementations/Dto/DtoService.cs index 87c10745d0..9bba223383 100644 --- a/Emby.Server.Implementations/Dto/DtoService.cs +++ b/Emby.Server.Implementations/Dto/DtoService.cs @@ -231,7 +231,7 @@ public Dictionary GetSyncedItemProgress(DtoOptions o } var deviceId = options.DeviceId; - if (string.IsNullOrWhiteSpace(deviceId)) + if (string.IsNullOrEmpty(deviceId)) { return new Dictionary(); } @@ -420,7 +420,7 @@ private BaseItemDto GetBaseItemDtoInternal(BaseItem item, DtoOptions options, Li dto.CanDownload = false; dto.RunTimeTicks = null; - if (!string.IsNullOrWhiteSpace(dto.SeriesName)) + if (!string.IsNullOrEmpty(dto.SeriesName)) { dto.EpisodeTitle = dto.Name; dto.Name = dto.SeriesName; @@ -437,7 +437,7 @@ private void NormalizeMediaSourceContainers(BaseItemDto dto) foreach (var mediaSource in dto.MediaSources) { var container = mediaSource.Container; - if (string.IsNullOrWhiteSpace(container)) + if (string.IsNullOrEmpty(container)) { continue; } @@ -450,17 +450,17 @@ private void NormalizeMediaSourceContainers(BaseItemDto dto) var path = mediaSource.Path; string fileExtensionContainer = null; - if (!string.IsNullOrWhiteSpace(path)) + if (!string.IsNullOrEmpty(path)) { path = Path.GetExtension(path); - if (!string.IsNullOrWhiteSpace(path)) + if (!string.IsNullOrEmpty(path)) { path = Path.GetExtension(path); - if (!string.IsNullOrWhiteSpace(path)) + if (!string.IsNullOrEmpty(path)) { path = path.TrimStart('.'); } - if (!string.IsNullOrWhiteSpace(path) && containers.Contains(path, StringComparer.OrdinalIgnoreCase)) + if (!string.IsNullOrEmpty(path) && containers.Contains(path, StringComparer.OrdinalIgnoreCase)) { fileExtensionContainer = path; } @@ -833,7 +833,7 @@ private void AttachPeople(BaseItemDto dto, BaseItem item) private void AttachStudios(BaseItemDto dto, BaseItem item) { dto.Studios = item.Studios - .Where(i => !string.IsNullOrWhiteSpace(i)) + .Where(i => !string.IsNullOrEmpty(i)) .Select(i => new NameIdPair { Name = i, @@ -845,7 +845,7 @@ private void AttachStudios(BaseItemDto dto, BaseItem item) private void AttachGenreItems(BaseItemDto dto, BaseItem item) { dto.GenreItems = item.Genres - .Where(i => !string.IsNullOrWhiteSpace(i)) + .Where(i => !string.IsNullOrEmpty(i)) .Select(i => new NameIdPair { Name = i, @@ -1102,7 +1102,7 @@ private void AttachBasicFields(BaseItemDto dto, BaseItem item, BaseItem owner, D if (fields.Contains(ItemFields.Taglines)) { - if (!string.IsNullOrWhiteSpace(item.Tagline)) + if (!string.IsNullOrEmpty(item.Tagline)) { dto.Taglines = new string[] { item.Tagline }; } @@ -1180,7 +1180,7 @@ private void AttachBasicFields(BaseItemDto dto, BaseItem item, BaseItem owner, D .Select(i => { // This should not be necessary but we're seeing some cases of it - if (string.IsNullOrWhiteSpace(i)) + if (string.IsNullOrEmpty(i)) { return null; } @@ -1231,7 +1231,7 @@ private void AttachBasicFields(BaseItemDto dto, BaseItem item, BaseItem owner, D .Select(i => { // This should not be necessary but we're seeing some cases of it - if (string.IsNullOrWhiteSpace(i)) + if (string.IsNullOrEmpty(i)) { return null; } @@ -1467,7 +1467,7 @@ private void AttachBasicFields(BaseItemDto dto, BaseItem item, BaseItem owner, D dto.ChannelId = item.ChannelId; - if (item.SourceType == SourceType.Channel && !string.IsNullOrWhiteSpace(item.ChannelId)) + if (item.SourceType == SourceType.Channel && !string.IsNullOrEmpty(item.ChannelId)) { var channel = _libraryManager.GetItemById(item.ChannelId); if (channel != null) diff --git a/Emby.Server.Implementations/Emby.Server.Implementations.csproj b/Emby.Server.Implementations/Emby.Server.Implementations.csproj index 812e10cae2..36f11bba02 100644 --- a/Emby.Server.Implementations/Emby.Server.Implementations.csproj +++ b/Emby.Server.Implementations/Emby.Server.Implementations.csproj @@ -46,7 +46,6 @@ - @@ -416,7 +415,6 @@ - diff --git a/Emby.Server.Implementations/EntryPoints/LibraryChangedNotifier.cs b/Emby.Server.Implementations/EntryPoints/LibraryChangedNotifier.cs index 0e771cbecc..431587f905 100644 --- a/Emby.Server.Implementations/EntryPoints/LibraryChangedNotifier.cs +++ b/Emby.Server.Implementations/EntryPoints/LibraryChangedNotifier.cs @@ -315,41 +315,36 @@ private void LibraryUpdateTimerCallback(object state) /// The cancellation token. private async void SendChangeNotifications(List itemsAdded, List itemsUpdated, List itemsRemoved, List foldersAddedTo, List foldersRemovedFrom, CancellationToken cancellationToken) { - foreach (var user in _userManager.Users.ToList()) + var userIds = _sessionManager.Sessions + .Select(i => i.UserId ?? Guid.Empty) + .Where(i => !i.Equals(Guid.Empty)) + .Distinct() + .ToArray(); + + foreach (var userId in userIds) { - var id = user.Id; - var userSessions = _sessionManager.Sessions - .Where(u => u.UserId.HasValue && u.UserId.Value == id && u.SessionController != null && u.IsActive) - .ToList(); + LibraryUpdateInfo info; - if (userSessions.Count > 0) + try { - LibraryUpdateInfo info; - - try - { - info = GetLibraryUpdateInfo(itemsAdded, itemsUpdated, itemsRemoved, foldersAddedTo, - foldersRemovedFrom, id); - } - catch (Exception ex) - { - _logger.ErrorException("Error in GetLibraryUpdateInfo", ex); - return; - } - - foreach (var userSession in userSessions) - { - try - { - await userSession.SessionController.SendLibraryUpdateInfo(info, cancellationToken).ConfigureAwait(false); - } - catch (Exception ex) - { - _logger.ErrorException("Error sending LibraryChanged message", ex); - } - } + info = GetLibraryUpdateInfo(itemsAdded, itemsUpdated, itemsRemoved, foldersAddedTo, foldersRemovedFrom, userId); + } + catch (Exception ex) + { + _logger.ErrorException("Error in GetLibraryUpdateInfo", ex); + return; } + var userIdString = userId.ToString("N"); + + try + { + await _sessionManager.SendMessageToUserSessions(new List { userIdString }, "LibraryChanged", info, cancellationToken).ConfigureAwait(false); + } + catch (Exception ex) + { + _logger.ErrorException("Error sending LibraryChanged message", ex); + } } } diff --git a/Emby.Server.Implementations/EntryPoints/UsageReporter.cs b/Emby.Server.Implementations/EntryPoints/UsageReporter.cs index deee8d64bd..86b335b773 100644 --- a/Emby.Server.Implementations/EntryPoints/UsageReporter.cs +++ b/Emby.Server.Implementations/EntryPoints/UsageReporter.cs @@ -70,7 +70,7 @@ public async Task ReportServerUsage(CancellationToken cancellationToken) public async Task ReportAppUsage(ClientInfo app, CancellationToken cancellationToken) { - if (string.IsNullOrWhiteSpace(app.DeviceId)) + if (string.IsNullOrEmpty(app.DeviceId)) { throw new ArgumentException("Client info must have a device Id"); } diff --git a/Emby.Server.Implementations/EntryPoints/UserDataChangeNotifier.cs b/Emby.Server.Implementations/EntryPoints/UserDataChangeNotifier.cs index 427aa5b329..59c91174fb 100644 --- a/Emby.Server.Implementations/EntryPoints/UserDataChangeNotifier.cs +++ b/Emby.Server.Implementations/EntryPoints/UserDataChangeNotifier.cs @@ -105,50 +105,43 @@ private void UpdateTimerCallback(object state) } } - private async Task SendNotifications(IEnumerable>> changes, CancellationToken cancellationToken) + private async Task SendNotifications(List>> changes, CancellationToken cancellationToken) { foreach (var pair in changes) { - var userId = pair.Key; - var userSessions = _sessionManager.Sessions - .Where(u => u.ContainsUser(userId) && u.SessionController != null && u.IsActive) - .ToList(); + await SendNotifications(pair.Key, pair.Value, cancellationToken).ConfigureAwait(false); + } + } + + private Task SendNotifications(Guid userId, List changedItems, CancellationToken cancellationToken) + { + var userIdString = userId.ToString("N"); + + return _sessionManager.SendMessageToUserSessions(new List { userIdString }, "UserDataChanged", () => GetUserDataChangeInfo(userId, changedItems), cancellationToken); + } + + private UserDataChangeInfo GetUserDataChangeInfo(Guid userId, List changedItems) + { + var user = _userManager.GetUserById(userId); - if (userSessions.Count > 0) + var dtoList = changedItems + .DistinctBy(i => i.Id) + .Select(i => { - var user = _userManager.GetUserById(userId); - - var dtoList = pair.Value - .DistinctBy(i => i.Id) - .Select(i => - { - var dto = _userDataManager.GetUserDataDto(i, user); - dto.ItemId = i.Id.ToString("N"); - return dto; - }) - .ToArray(); - - var info = new UserDataChangeInfo - { - UserId = userId.ToString("N"), + var dto = _userDataManager.GetUserDataDto(i, user); + dto.ItemId = i.Id.ToString("N"); + return dto; + }) + .ToArray(); - UserDataList = dtoList - }; + var userIdString = userId.ToString("N"); - foreach (var userSession in userSessions) - { - try - { - await userSession.SessionController.SendUserDataChangeInfo(info, cancellationToken).ConfigureAwait(false); - } - catch (Exception ex) - { - _logger.ErrorException("Error sending UserDataChanged message", ex); - } - } - } + return new UserDataChangeInfo + { + UserId = userIdString, - } + UserDataList = dtoList + }; } public void Dispose() diff --git a/Emby.Server.Implementations/HttpServer/HttpListenerHost.cs b/Emby.Server.Implementations/HttpServer/HttpListenerHost.cs index be5de5f127..400a1d3125 100644 --- a/Emby.Server.Implementations/HttpServer/HttpListenerHost.cs +++ b/Emby.Server.Implementations/HttpServer/HttpListenerHost.cs @@ -293,7 +293,7 @@ private void ErrorHandler(Exception ex, IRequest httpReq, bool logException = tr httpRes.StatusCode = statusCode; httpRes.ContentType = "text/html"; - Write(httpRes, ex.Message); + Write(httpRes, NormalizeExceptionMessage(ex.Message)); } catch { @@ -301,6 +301,21 @@ private void ErrorHandler(Exception ex, IRequest httpReq, bool logException = tr } } + private string NormalizeExceptionMessage(string msg) + { + if (msg == null) + { + return string.Empty; + } + + // Strip any information we don't want to reveal + + msg = msg.Replace(_config.ApplicationPaths.ProgramSystemPath, string.Empty, StringComparison.OrdinalIgnoreCase); + msg = msg.Replace(_config.ApplicationPaths.ProgramDataPath, string.Empty, StringComparison.OrdinalIgnoreCase); + + return msg; + } + /// /// Shut down the Web Service /// @@ -329,9 +344,9 @@ private bool EnableLogging(string url, string localPath) { var extension = GetExtension(url); - if (string.IsNullOrWhiteSpace(extension) || !_skipLogExtensions.ContainsKey(extension)) + if (string.IsNullOrEmpty(extension) || !_skipLogExtensions.ContainsKey(extension)) { - if (string.IsNullOrWhiteSpace(localPath) || localPath.IndexOf("system/ping", StringComparison.OrdinalIgnoreCase) == -1) + if (string.IsNullOrEmpty(localPath) || localPath.IndexOf("system/ping", StringComparison.OrdinalIgnoreCase) == -1) { return true; } @@ -599,7 +614,7 @@ protected async Task RequestHandler(IHttpRequest httpReq, string urlString, stri return; } - if (!string.IsNullOrWhiteSpace(GlobalResponse)) + if (!string.IsNullOrEmpty(GlobalResponse)) { httpRes.StatusCode = 503; httpRes.ContentType = "text/html"; diff --git a/Emby.Server.Implementations/HttpServer/HttpResultFactory.cs b/Emby.Server.Implementations/HttpServer/HttpResultFactory.cs index 86deccee12..b6df78721c 100644 --- a/Emby.Server.Implementations/HttpServer/HttpResultFactory.cs +++ b/Emby.Server.Implementations/HttpServer/HttpResultFactory.cs @@ -6,6 +6,7 @@ using System.Collections.Generic; using System.Globalization; using System.IO; +using System.IO.Compression; using System.Net; using System.Runtime.Serialization; using System.Text; @@ -52,7 +53,12 @@ public HttpResultFactory(ILogManager logManager, IFileSystem fileSystem, IJsonSe /// System.Object. public object GetResult(object content, string contentType, IDictionary responseHeaders = null) { - return GetHttpResult(content, contentType, true, responseHeaders); + return GetHttpResult(null, content, contentType, true, responseHeaders); + } + + public object GetResult(IRequest requestContext, object content, string contentType, IDictionary responseHeaders = null) + { + return GetHttpResult(requestContext, content, contentType, true, responseHeaders); } public object GetRedirectResult(string url) @@ -70,7 +76,7 @@ public object GetRedirectResult(string url) /// /// Gets the HTTP result. /// - private IHasHeaders GetHttpResult(object content, string contentType, bool addCachePrevention, IDictionary responseHeaders = null) + private IHasHeaders GetHttpResult(IRequest requestContext, object content, string contentType, bool addCachePrevention, IDictionary responseHeaders = null) { IHasHeaders result; @@ -95,7 +101,18 @@ private IHasHeaders GetHttpResult(object content, string contentType, bool addCa if (text != null) { - result = new StreamWriter(Encoding.UTF8.GetBytes(text), contentType, _logger); + var compressionType = requestContext == null ? null : GetCompressionType(requestContext); + + if (string.IsNullOrEmpty(compressionType)) + { + result = new StreamWriter(Encoding.UTF8.GetBytes(text), contentType, _logger); + } + else + { + var isHeadRequest = string.Equals(requestContext.Verb, "head", StringComparison.OrdinalIgnoreCase); + + result = GetCompressedResult(Encoding.UTF8.GetBytes(text), compressionType, responseHeaders, isHeadRequest, contentType); + } } else { @@ -180,7 +197,7 @@ public static string GetCompressionType(IRequest request) /// public object ToOptimizedResult(IRequest request, T dto) { - return ToOptimizedResultInternal(request, dto, null); + return ToOptimizedResultInternal(request, dto); } private object ToOptimizedResultInternal(IRequest request, T dto, IDictionary responseHeaders = null) @@ -192,27 +209,101 @@ private object ToOptimizedResultInternal(IRequest request, T dto, IDictionary case "application/xml": case "text/xml": case "text/xml; charset=utf-8": //"text/xml; charset=utf-8" also matches xml - return GetHttpResult(SerializeToXmlString(dto), contentType, false, responseHeaders); + return GetHttpResult(request, SerializeToXmlString(dto), contentType, false, responseHeaders); case "application/json": case "text/json": - return GetHttpResult(_jsonSerializer.SerializeToString(dto), contentType, false, responseHeaders); + return GetHttpResult(request, _jsonSerializer.SerializeToString(dto), contentType, false, responseHeaders); default: - { - var ms = new MemoryStream(); - var writerFn = RequestHelper.GetResponseWriter(HttpListenerHost.Instance, contentType); + break; + } - writerFn(dto, ms); + var isHeadRequest = string.Equals(request.Verb, "head", StringComparison.OrdinalIgnoreCase); - ms.Position = 0; + var ms = new MemoryStream(); + var writerFn = RequestHelper.GetResponseWriter(HttpListenerHost.Instance, contentType); - if (string.Equals(request.Verb, "head", StringComparison.OrdinalIgnoreCase)) - { - return GetHttpResult(new byte[] { }, contentType, true, responseHeaders); - } + writerFn(dto, ms); - return GetHttpResult(ms, contentType, true, responseHeaders); - } + ms.Position = 0; + + if (isHeadRequest) + { + return GetHttpResult(request, new byte[] { }, contentType, true, responseHeaders); + } + + return GetHttpResult(request, ms, contentType, true, responseHeaders); + } + + private IHasHeaders GetCompressedResult(byte[] content, + string requestedCompressionType, + IDictionary responseHeaders, + bool isHeadRequest, + string contentType) + { + if (responseHeaders == null) + { + responseHeaders = new Dictionary(StringComparer.OrdinalIgnoreCase); + } + + // Per apple docs, hls manifests must be compressed + if ((contentType ?? string.Empty).IndexOf("application/x-mpegURL") != -1) + { + content = Compress(content, requestedCompressionType); + responseHeaders["Content-Encoding"] = requestedCompressionType; + } + + responseHeaders["Vary"] = "Accept-Encoding"; + responseHeaders["Content-Length"] = content.Length.ToString(UsCulture); + + if (isHeadRequest) + { + var result = new StreamWriter(new byte[] { }, contentType, _logger); + AddResponseHeaders(result, responseHeaders); + return result; + } + else + { + var result = new StreamWriter(content, contentType, _logger); + AddResponseHeaders(result, responseHeaders); + return result; + } + } + + private byte[] Compress(byte[] bytes, string compressionType) + { + if (compressionType == "deflate") + return Deflate(bytes); + + if (compressionType == "gzip") + return GZip(bytes); + + throw new NotSupportedException(compressionType); + } + + private byte[] Deflate(byte[] bytes) + { + // In .NET FX incompat-ville, you can't access compressed bytes without closing DeflateStream + // Which means we must use MemoryStream since you have to use ToArray() on a closed Stream + using (var ms = new MemoryStream()) + using (var zipStream = new DeflateStream(ms, CompressionMode.Compress)) + { + zipStream.Write(bytes, 0, bytes.Length); + zipStream.Dispose(); + + return ms.ToArray(); + } + } + + private byte[] GZip(byte[] buffer) + { + using (var ms = new MemoryStream()) + using (var zipStream = new GZipStream(ms, CompressionMode.Compress)) + { + zipStream.Write(buffer, 0, buffer.Length); + zipStream.Dispose(); + + return ms.ToArray(); } } @@ -338,7 +429,7 @@ public object GetCachedResult(IRequest requestContext, Guid cacheKey, DateTim return hasHeaders; } - return GetHttpResult(result, contentType, false, responseHeaders); + return GetHttpResult(requestContext, result, contentType, false, responseHeaders); } /// @@ -402,7 +493,7 @@ public Task GetStaticFileResult(IRequest requestContext, throw new ArgumentException("FileShare must be either Read or ReadWrite"); } - if (string.IsNullOrWhiteSpace(options.ContentType)) + if (string.IsNullOrEmpty(options.ContentType)) { options.ContentType = MimeTypes.GetMimeType(path); } @@ -484,7 +575,7 @@ public async Task GetStaticResult(IRequest requestContext, StaticResultO var rangeHeader = requestContext.Headers.Get("Range"); - if (!isHeadRequest && !string.IsNullOrWhiteSpace(options.Path)) + if (!isHeadRequest && !string.IsNullOrEmpty(options.Path)) { var hasHeaders = new FileWriter(options.Path, contentType, rangeHeader, _logger, _fileSystem) { @@ -519,7 +610,7 @@ public async Task GetStaticResult(IRequest requestContext, StaticResultO { stream.Dispose(); - return GetHttpResult(new byte[] { }, contentType, true, responseHeaders); + return GetHttpResult(requestContext, new byte[] { }, contentType, true, responseHeaders); } var hasHeaders = new StreamWriter(stream, contentType, _logger) diff --git a/Emby.Server.Implementations/HttpServer/Security/AuthService.cs b/Emby.Server.Implementations/HttpServer/Security/AuthService.cs index 38fb4041ef..63588e8549 100644 --- a/Emby.Server.Implementations/HttpServer/Security/AuthService.cs +++ b/Emby.Server.Implementations/HttpServer/Security/AuthService.cs @@ -60,11 +60,11 @@ private void ValidateUser(IRequest request, } } - var user = string.IsNullOrWhiteSpace(auth.UserId) + var user = string.IsNullOrEmpty(auth.UserId) ? null : UserManager.GetUserById(auth.UserId); - if (user == null & !string.IsNullOrWhiteSpace(auth.UserId)) + if (user == null & !string.IsNullOrEmpty(auth.UserId)) { throw new SecurityException("User with Id " + auth.UserId + " not found"); } @@ -83,9 +83,9 @@ private void ValidateUser(IRequest request, ValidateRoles(roles, user); } - if (!string.IsNullOrWhiteSpace(auth.DeviceId) && - !string.IsNullOrWhiteSpace(auth.Client) && - !string.IsNullOrWhiteSpace(auth.Device)) + if (!string.IsNullOrEmpty(auth.DeviceId) && + !string.IsNullOrEmpty(auth.Client) && + !string.IsNullOrEmpty(auth.Device)) { SessionManager.LogSessionActivity(auth.Client, auth.Version, @@ -120,7 +120,7 @@ private void ValidateUserAccess(User user, IRequest request, }; } - if (!string.IsNullOrWhiteSpace(auth.DeviceId)) + if (!string.IsNullOrEmpty(auth.DeviceId)) { if (!DeviceManager.CanAccessDevice(user, auth.DeviceId)) { @@ -159,12 +159,12 @@ private bool IsExemptFromRoles(AuthorizationInfo auth, IAuthenticationAttributes return true; } - if (string.IsNullOrWhiteSpace(auth.Token)) + if (string.IsNullOrEmpty(auth.Token)) { return true; } - if (tokenInfo != null && string.IsNullOrWhiteSpace(tokenInfo.UserId)) + if (tokenInfo != null && string.IsNullOrEmpty(tokenInfo.UserId)) { return true; } @@ -225,7 +225,7 @@ private bool IsValidConnectKey(string token) private void ValidateSecurityToken(IRequest request, string token) { - if (string.IsNullOrWhiteSpace(token)) + if (string.IsNullOrEmpty(token)) { throw new SecurityException("Access token is required."); } @@ -242,7 +242,7 @@ private void ValidateSecurityToken(IRequest request, string token) throw new SecurityException("Access token has expired."); } - //if (!string.IsNullOrWhiteSpace(info.UserId)) + //if (!string.IsNullOrEmpty(info.UserId)) //{ // var user = _userManager.GetUserById(info.UserId); diff --git a/Emby.Server.Implementations/HttpServer/Security/AuthorizationContext.cs b/Emby.Server.Implementations/HttpServer/Security/AuthorizationContext.cs index a41c51d1a8..e51557fa8a 100644 --- a/Emby.Server.Implementations/HttpServer/Security/AuthorizationContext.cs +++ b/Emby.Server.Implementations/HttpServer/Security/AuthorizationContext.cs @@ -60,16 +60,16 @@ private AuthorizationInfo GetAuthorization(IRequest httpReq) auth.TryGetValue("Token", out token); } - if (string.IsNullOrWhiteSpace(token)) + if (string.IsNullOrEmpty(token)) { token = httpReq.Headers["X-Emby-Token"]; } - if (string.IsNullOrWhiteSpace(token)) + if (string.IsNullOrEmpty(token)) { token = httpReq.Headers["X-MediaBrowser-Token"]; } - if (string.IsNullOrWhiteSpace(token)) + if (string.IsNullOrEmpty(token)) { token = httpReq.QueryString["api_key"]; } @@ -160,7 +160,7 @@ private Dictionary GetAuthorizationDictionary(IRequest httpReq) { var auth = httpReq.Headers["X-Emby-Authorization"]; - if (string.IsNullOrWhiteSpace(auth)) + if (string.IsNullOrEmpty(auth)) { auth = httpReq.Headers["Authorization"]; } @@ -212,7 +212,7 @@ private Dictionary GetAuthorization(string authorizationHeader) private string NormalizeValue(string value) { - if (string.IsNullOrWhiteSpace(value)) + if (string.IsNullOrEmpty(value)) { return value; } diff --git a/Emby.Server.Implementations/HttpServer/Security/SessionContext.cs b/Emby.Server.Implementations/HttpServer/Security/SessionContext.cs index 0ec420f060..841e2167f1 100644 --- a/Emby.Server.Implementations/HttpServer/Security/SessionContext.cs +++ b/Emby.Server.Implementations/HttpServer/Security/SessionContext.cs @@ -25,7 +25,7 @@ public SessionInfo GetSession(IRequest requestContext) { var authorization = _authContext.GetAuthorizationInfo(requestContext); - var user = string.IsNullOrWhiteSpace(authorization.UserId) ? null : _userManager.GetUserById(authorization.UserId); + var user = string.IsNullOrEmpty(authorization.UserId) ? null : _userManager.GetUserById(authorization.UserId); return _sessionManager.LogSessionActivity(authorization.Client, authorization.Version, authorization.DeviceId, authorization.Device, requestContext.RemoteIp, user); } diff --git a/Emby.Server.Implementations/HttpServer/SocketSharp/RequestMono.cs b/Emby.Server.Implementations/HttpServer/SocketSharp/RequestMono.cs index ec14c32c8f..2dc8d99153 100644 --- a/Emby.Server.Implementations/HttpServer/SocketSharp/RequestMono.cs +++ b/Emby.Server.Implementations/HttpServer/SocketSharp/RequestMono.cs @@ -533,7 +533,7 @@ internal sealed class StrUtils { public static bool StartsWith(string str1, string str2, bool ignore_case) { - if (string.IsNullOrWhiteSpace(str1)) + if (string.IsNullOrEmpty(str1)) { return false; } diff --git a/Emby.Server.Implementations/HttpServer/SocketSharp/SharpWebSocket.cs b/Emby.Server.Implementations/HttpServer/SocketSharp/SharpWebSocket.cs index cc7a4557eb..71fee312d1 100644 --- a/Emby.Server.Implementations/HttpServer/SocketSharp/SharpWebSocket.cs +++ b/Emby.Server.Implementations/HttpServer/SocketSharp/SharpWebSocket.cs @@ -60,7 +60,7 @@ void socket_OnClose(object sender, SocketHttpListener.CloseEventArgs e) void socket_OnMessage(object sender, SocketHttpListener.MessageEventArgs e) { - //if (!string.IsNullOrWhiteSpace(e.Data)) + //if (!string.IsNullOrEmpty(e.Data)) //{ // if (OnReceive != null) // { diff --git a/Emby.Server.Implementations/HttpServer/SocketSharp/WebSocketSharpRequest.cs b/Emby.Server.Implementations/HttpServer/SocketSharp/WebSocketSharpRequest.cs index 522377f0cc..abadd6f9e2 100644 --- a/Emby.Server.Implementations/HttpServer/SocketSharp/WebSocketSharpRequest.cs +++ b/Emby.Server.Implementations/HttpServer/SocketSharp/WebSocketSharpRequest.cs @@ -265,33 +265,14 @@ public static string GetResponseContentType(IRequest httpReq) defaultContentType = serverDefaultContentType; } - var preferredContentTypes = new string[] {}; - var acceptsAnything = false; var hasDefaultContentType = !string.IsNullOrEmpty(defaultContentType); if (acceptContentTypes != null) { - var hasPreferredContentTypes = new bool[preferredContentTypes.Length]; foreach (var acceptsType in acceptContentTypes) { var contentType = HttpResultFactory.GetRealContentType(acceptsType); acceptsAnything = acceptsAnything || contentType == "*/*"; - - for (var i = 0; i < preferredContentTypes.Length; i++) - { - if (hasPreferredContentTypes[i]) continue; - var preferredContentType = preferredContentTypes[i]; - hasPreferredContentTypes[i] = contentType.StartsWith(preferredContentType); - - //Prefer Request.ContentType if it is also a preferredContentType - if (hasPreferredContentTypes[i] && preferredContentType == defaultContentType) - return preferredContentType; - } - } - - for (var i = 0; i < preferredContentTypes.Length; i++) - { - if (hasPreferredContentTypes[i]) return preferredContentTypes[i]; } if (acceptsAnything) diff --git a/Emby.Server.Implementations/IO/FileRefresher.cs b/Emby.Server.Implementations/IO/FileRefresher.cs index 85b8bddd28..35e2877a6c 100644 --- a/Emby.Server.Implementations/IO/FileRefresher.cs +++ b/Emby.Server.Implementations/IO/FileRefresher.cs @@ -54,7 +54,7 @@ public FileRefresher(string path, IFileSystem fileSystem, IServerConfigurationMa private void AddAffectedPath(string path) { - if (string.IsNullOrWhiteSpace(path)) + if (string.IsNullOrEmpty(path)) { throw new ArgumentNullException("path"); } @@ -67,7 +67,7 @@ private void AddAffectedPath(string path) public void AddPath(string path) { - if (string.IsNullOrWhiteSpace(path)) + if (string.IsNullOrEmpty(path)) { throw new ArgumentNullException("path"); } @@ -113,7 +113,7 @@ public void ResetPath(string path, string affectedFile) Path = path; AddAffectedPath(path); - if (!string.IsNullOrWhiteSpace(affectedFile)) + if (!string.IsNullOrEmpty(affectedFile)) { AddAffectedPath(affectedFile); } diff --git a/Emby.Server.Implementations/IO/LibraryMonitor.cs b/Emby.Server.Implementations/IO/LibraryMonitor.cs index 6af8c04887..5fa7c00562 100644 --- a/Emby.Server.Implementations/IO/LibraryMonitor.cs +++ b/Emby.Server.Implementations/IO/LibraryMonitor.cs @@ -266,7 +266,7 @@ void LibraryManager_ItemAdded(object sender, ItemChangeEventArgs e) /// path private static bool ContainsParentFolder(IEnumerable lst, string path) { - if (string.IsNullOrWhiteSpace(path)) + if (string.IsNullOrEmpty(path)) { throw new ArgumentNullException("path"); } @@ -485,13 +485,13 @@ public void ReportFileSystemChanged(string path) { if (_fileSystem.AreEqual(i, path)) { - Logger.Debug("Ignoring change to {0}", path); + //Logger.Debug("Ignoring change to {0}", path); return true; } if (_fileSystem.ContainsSubPath(i, path)) { - Logger.Debug("Ignoring change to {0}", path); + //Logger.Debug("Ignoring change to {0}", path); return true; } @@ -501,7 +501,7 @@ public void ReportFileSystemChanged(string path) { if (_fileSystem.AreEqual(parent, path)) { - Logger.Debug("Ignoring change to {0}", path); + //Logger.Debug("Ignoring change to {0}", path); return true; } } diff --git a/Emby.Server.Implementations/IO/ManagedFileSystem.cs b/Emby.Server.Implementations/IO/ManagedFileSystem.cs index 274ea6b3f1..4882d20f55 100644 --- a/Emby.Server.Implementations/IO/ManagedFileSystem.cs +++ b/Emby.Server.Implementations/IO/ManagedFileSystem.cs @@ -56,7 +56,7 @@ public string DefaultDirectory { var value = _defaultDirectory; - if (!string.IsNullOrWhiteSpace(value)) + if (!string.IsNullOrEmpty(value)) { try { @@ -750,7 +750,7 @@ public string GetFileNameWithoutExtension(string path) public bool IsPathFile(string path) { - if (string.IsNullOrWhiteSpace(path)) + if (string.IsNullOrEmpty(path)) { throw new ArgumentNullException("path"); } diff --git a/Emby.Server.Implementations/Images/BaseDynamicImageProvider.cs b/Emby.Server.Implementations/Images/BaseDynamicImageProvider.cs index 547da32636..d7420a8ef4 100644 --- a/Emby.Server.Implementations/Images/BaseDynamicImageProvider.cs +++ b/Emby.Server.Implementations/Images/BaseDynamicImageProvider.cs @@ -106,7 +106,7 @@ protected async Task FetchToFileInternal(BaseItem item, FileSystem.CreateDirectory(FileSystem.GetDirectoryName(outputPathWithoutExtension)); string outputPath = CreateImage(item, itemsWithImages, outputPathWithoutExtension, imageType, 0); - if (string.IsNullOrWhiteSpace(outputPath)) + if (string.IsNullOrEmpty(outputPath)) { return ItemUpdateType.None; } @@ -149,7 +149,7 @@ protected virtual IEnumerable GetStripCollageImagePaths(BaseItem primary } return null; }) - .Where(i => !string.IsNullOrWhiteSpace(i)); + .Where(i => !string.IsNullOrEmpty(i)); } protected string CreatePosterCollage(BaseItem primaryItem, List items, string outputPath) @@ -322,7 +322,7 @@ protected string CreateSingleImage(List itemsWithImages, string output .Select(i => i.GetImagePath(imageType)) .FirstOrDefault(); - if (string.IsNullOrWhiteSpace(image)) + if (string.IsNullOrEmpty(image)) { return null; } diff --git a/Emby.Server.Implementations/Library/LibraryManager.cs b/Emby.Server.Implementations/Library/LibraryManager.cs index 79f4f0eb4a..e97d9acb16 100644 --- a/Emby.Server.Implementations/Library/LibraryManager.cs +++ b/Emby.Server.Implementations/Library/LibraryManager.cs @@ -484,7 +484,7 @@ public Guid GetNewItemId(string key, Type type) private Guid GetNewItemIdInternal(string key, Type type, bool forceCaseInsensitive) { - if (string.IsNullOrWhiteSpace(key)) + if (string.IsNullOrEmpty(key)) { throw new ArgumentNullException("key"); } @@ -531,7 +531,7 @@ private BaseItem ResolvePath(FileSystemMetadata fileInfo, var fullPath = fileInfo.FullName; - if (string.IsNullOrWhiteSpace(collectionType) && parent != null) + if (string.IsNullOrEmpty(collectionType) && parent != null) { collectionType = GetContentTypeOverride(fullPath, true); } @@ -712,7 +712,7 @@ public AggregateFolder CreateRootFolder() { if (folder.Id == Guid.Empty) { - if (string.IsNullOrWhiteSpace(folder.Path)) + if (string.IsNullOrEmpty(folder.Path)) { folder.Id = GetNewItemId(folder.GetType().Name, folder.GetType()); } @@ -785,7 +785,7 @@ public BaseItem FindByPath(string path, bool? isFolder) // If this returns multiple items it could be tricky figuring out which one is correct. // In most cases, the newest one will be and the others obsolete but not yet cleaned up - if (string.IsNullOrWhiteSpace(path)) + if (string.IsNullOrEmpty(path)) { throw new ArgumentNullException("path"); } @@ -1184,7 +1184,7 @@ private string GetCollectionType(string path) { return _fileSystem.GetFilePaths(path, new[] { ".collection" }, true, false) .Select(i => _fileSystem.GetFileNameWithoutExtension(i)) - .FirstOrDefault(i => !string.IsNullOrWhiteSpace(i)); + .FirstOrDefault(i => !string.IsNullOrEmpty(i)); } /// @@ -1488,8 +1488,8 @@ private void AddUserToQuery(InternalItemsQuery query, User user, bool allowExter !query.ParentId.HasValue && query.ChannelIds.Length == 0 && query.TopParentIds.Length == 0 && - string.IsNullOrWhiteSpace(query.AncestorWithPresentationUniqueKey) && - string.IsNullOrWhiteSpace(query.SeriesPresentationUniqueKey) && + string.IsNullOrEmpty(query.AncestorWithPresentationUniqueKey) && + string.IsNullOrEmpty(query.SeriesPresentationUniqueKey) && query.ItemIds.Length == 0) { var userViews = _userviewManager().GetUserViews(new UserViewQuery @@ -1546,12 +1546,12 @@ private IEnumerable GetTopParentIdsForQuery(BaseItem item, User user) } // Handle grouping - if (user != null && !string.IsNullOrWhiteSpace(view.ViewType) && UserView.IsEligibleForGrouping(view.ViewType) && user.Configuration.GroupedFolders.Length > 0) + if (user != null && !string.IsNullOrEmpty(view.ViewType) && UserView.IsEligibleForGrouping(view.ViewType) && user.Configuration.GroupedFolders.Length > 0) { return user.RootFolder .GetChildren(user, true) .OfType() - .Where(i => string.IsNullOrWhiteSpace(i.CollectionType) || string.Equals(i.CollectionType, view.ViewType, StringComparison.OrdinalIgnoreCase)) + .Where(i => string.IsNullOrEmpty(i.CollectionType) || string.Equals(i.CollectionType, view.ViewType, StringComparison.OrdinalIgnoreCase)) .Where(i => user.IsFolderGrouped(i.Id)) .SelectMany(i => GetTopParentIdsForQuery(i, user)); } @@ -2008,12 +2008,12 @@ public LibraryOptions GetLibraryOptions(BaseItem item) public string GetContentType(BaseItem item) { string configuredContentType = GetConfiguredContentType(item, false); - if (!string.IsNullOrWhiteSpace(configuredContentType)) + if (!string.IsNullOrEmpty(configuredContentType)) { return configuredContentType; } configuredContentType = GetConfiguredContentType(item, true); - if (!string.IsNullOrWhiteSpace(configuredContentType)) + if (!string.IsNullOrEmpty(configuredContentType)) { return configuredContentType; } @@ -2024,14 +2024,14 @@ public string GetInheritedContentType(BaseItem item) { var type = GetTopFolderContentType(item); - if (!string.IsNullOrWhiteSpace(type)) + if (!string.IsNullOrEmpty(type)) { return type; } return item.GetParents() .Select(GetConfiguredContentType) - .LastOrDefault(i => !string.IsNullOrWhiteSpace(i)); + .LastOrDefault(i => !string.IsNullOrEmpty(i)); } public string GetConfiguredContentType(BaseItem item) @@ -2056,7 +2056,7 @@ public string GetConfiguredContentType(BaseItem item, bool inheritConfiguredPath private string GetContentTypeOverride(string path, bool inherit) { - var nameValuePair = ConfigurationManager.Configuration.ContentTypes.FirstOrDefault(i => _fileSystem.AreEqual(i.Name, path) || (inherit && !string.IsNullOrWhiteSpace(i.Name) && _fileSystem.ContainsSubPath(i.Name, path))); + var nameValuePair = ConfigurationManager.Configuration.ContentTypes.FirstOrDefault(i => _fileSystem.AreEqual(i.Name, path) || (inherit && !string.IsNullOrEmpty(i.Name) && _fileSystem.ContainsSubPath(i.Name, path))); if (nameValuePair != null) { return nameValuePair.Value; @@ -2080,7 +2080,7 @@ private string GetTopFolderContentType(BaseItem item) .OfType() .Where(i => string.Equals(i.Path, item.Path, StringComparison.OrdinalIgnoreCase) || i.PhysicalLocations.Contains(item.Path)) .Select(i => i.CollectionType) - .FirstOrDefault(i => !string.IsNullOrWhiteSpace(i)); + .FirstOrDefault(i => !string.IsNullOrEmpty(i)); } private readonly TimeSpan _viewRefreshInterval = TimeSpan.FromHours(24); @@ -2181,7 +2181,7 @@ public UserView GetNamedView(User user, UserId = user.Id }; - if (!string.IsNullOrWhiteSpace(parentId)) + if (!string.IsNullOrEmpty(parentId)) { item.DisplayParentId = new Guid(parentId); } @@ -2284,13 +2284,13 @@ public UserView GetNamedView(string name, string uniqueId, CancellationToken cancellationToken) { - if (string.IsNullOrWhiteSpace(name)) + if (string.IsNullOrEmpty(name)) { throw new ArgumentNullException("name"); } var idValues = "37_namedview_" + name + (parentId ?? string.Empty) + (viewType ?? string.Empty); - if (!string.IsNullOrWhiteSpace(uniqueId)) + if (!string.IsNullOrEmpty(uniqueId)) { idValues += uniqueId; } @@ -2317,7 +2317,7 @@ public UserView GetNamedView(string name, ForcedSortName = sortName }; - if (!string.IsNullOrWhiteSpace(parentId)) + if (!string.IsNullOrEmpty(parentId)) { item.DisplayParentId = new Guid(parentId); } @@ -3164,7 +3164,7 @@ private void RemoveContentTypeOverrides(string path) public void RemoveMediaPath(string virtualFolderName, string mediaPath) { - if (string.IsNullOrWhiteSpace(mediaPath)) + if (string.IsNullOrEmpty(mediaPath)) { throw new ArgumentNullException("mediaPath"); } diff --git a/Emby.Server.Implementations/Library/LocalTrailerPostScanTask.cs b/Emby.Server.Implementations/Library/LocalTrailerPostScanTask.cs index 20630261c2..d36a52696b 100644 --- a/Emby.Server.Implementations/Library/LocalTrailerPostScanTask.cs +++ b/Emby.Server.Implementations/Library/LocalTrailerPostScanTask.cs @@ -78,12 +78,12 @@ private void AssignTrailers(IHasTrailers item, IEnumerable channelTrai var trailers = channelTrailers.Where(i => { - if (!string.IsNullOrWhiteSpace(imdbId) && + if (!string.IsNullOrEmpty(imdbId) && string.Equals(imdbId, i.GetProviderId(MetadataProviders.Imdb), StringComparison.OrdinalIgnoreCase)) { return true; } - if (!string.IsNullOrWhiteSpace(tmdbId) && + if (!string.IsNullOrEmpty(tmdbId) && string.Equals(tmdbId, i.GetProviderId(MetadataProviders.Tmdb), StringComparison.OrdinalIgnoreCase)) { return true; diff --git a/Emby.Server.Implementations/Library/MediaSourceManager.cs b/Emby.Server.Implementations/Library/MediaSourceManager.cs index 757a3e8b6c..13a97670bf 100644 --- a/Emby.Server.Implementations/Library/MediaSourceManager.cs +++ b/Emby.Server.Implementations/Library/MediaSourceManager.cs @@ -119,7 +119,7 @@ public async Task> GetPlayackMediaSources(string id var hasMediaSources = (IHasMediaSources)item; User user = null; - if (!string.IsNullOrWhiteSpace(userId)) + if (!string.IsNullOrEmpty(userId)) { user = _userManager.GetUserById(userId); } @@ -201,12 +201,12 @@ private void SetKeyProperties(IMediaSourceProvider provider, MediaSourceInfo med { var prefix = provider.GetType().FullName.GetMD5().ToString("N") + LiveStreamIdDelimeter; - if (!string.IsNullOrWhiteSpace(mediaSource.OpenToken) && !mediaSource.OpenToken.StartsWith(prefix, StringComparison.OrdinalIgnoreCase)) + if (!string.IsNullOrEmpty(mediaSource.OpenToken) && !mediaSource.OpenToken.StartsWith(prefix, StringComparison.OrdinalIgnoreCase)) { mediaSource.OpenToken = prefix + mediaSource.OpenToken; } - if (!string.IsNullOrWhiteSpace(mediaSource.LiveStreamId) && !mediaSource.LiveStreamId.StartsWith(prefix, StringComparison.OrdinalIgnoreCase)) + if (!string.IsNullOrEmpty(mediaSource.LiveStreamId) && !mediaSource.LiveStreamId.StartsWith(prefix, StringComparison.OrdinalIgnoreCase)) { mediaSource.LiveStreamId = prefix + mediaSource.LiveStreamId; } @@ -214,7 +214,7 @@ private void SetKeyProperties(IMediaSourceProvider provider, MediaSourceInfo med public async Task GetMediaSource(IHasMediaSources item, string mediaSourceId, string liveStreamId, bool enablePathSubstitution, CancellationToken cancellationToken) { - if (!string.IsNullOrWhiteSpace(liveStreamId)) + if (!string.IsNullOrEmpty(liveStreamId)) { return await GetLiveStream(liveStreamId, cancellationToken).ConfigureAwait(false); } @@ -347,7 +347,7 @@ public async Task OpenLiveStream(LiveStreamRequest request, var mediaSource = mediaSourceTuple.Item1; - if (string.IsNullOrWhiteSpace(mediaSource.LiveStreamId)) + if (string.IsNullOrEmpty(mediaSource.LiveStreamId)) { throw new InvalidOperationException(string.Format("{0} returned null LiveStreamId", provider.GetType().Name)); } @@ -358,7 +358,8 @@ public async Task OpenLiveStream(LiveStreamRequest request, { Id = mediaSource.LiveStreamId, MediaSource = mediaSource, - DirectStreamProvider = mediaSourceTuple.Item2 + DirectStreamProvider = mediaSourceTuple.Item2, + AllowLiveMediaInfoProbe = mediaSourceTuple.Item3 }; _openStreams[mediaSource.LiveStreamId] = info; @@ -367,10 +368,10 @@ public async Task OpenLiveStream(LiveStreamRequest request, _logger.Debug("Live stream opened: " + json); var clone = _jsonSerializer.DeserializeFromString(json); - if (!string.IsNullOrWhiteSpace(request.UserId)) + if (!string.IsNullOrEmpty(request.UserId)) { var user = _userManager.GetUserById(request.UserId); - var item = string.IsNullOrWhiteSpace(request.ItemId) + var item = string.IsNullOrEmpty(request.ItemId) ? null : _libraryManager.GetItemById(request.ItemId); SetUserProperties(item, clone, user); @@ -389,11 +390,11 @@ public async Task OpenLiveStream(LiveStreamRequest request, public async Task GetLiveStreamMediaInfo(string id, CancellationToken cancellationToken) { - var liveStreamInfo = await GetLiveStreamWithDirectStreamProvider(id, cancellationToken).ConfigureAwait(false); + var liveStreamInfo = await GetLiveStreamInfo(id, cancellationToken).ConfigureAwait(false); - var mediaSource = liveStreamInfo.Item1; + var mediaSource = liveStreamInfo.MediaSource; - if (liveStreamInfo.Item2 != null) + if (liveStreamInfo.AllowLiveMediaInfoProbe) { var info = await _mediaEncoder().GetMediaInfo(new MediaInfoRequest { @@ -413,7 +414,18 @@ public async Task GetLiveStreamMediaInfo(string id, Cancellatio public async Task> GetLiveStreamWithDirectStreamProvider(string id, CancellationToken cancellationToken) { - if (string.IsNullOrWhiteSpace(id)) + if (string.IsNullOrEmpty(id)) + { + throw new ArgumentNullException("id"); + } + + var info = await GetLiveStreamInfo(id, cancellationToken).ConfigureAwait(false); + return new Tuple(info.MediaSource, info.DirectStreamProvider); + } + + private async Task GetLiveStreamInfo(string id, CancellationToken cancellationToken) + { + if (string.IsNullOrEmpty(id)) { throw new ArgumentNullException("id"); } @@ -425,7 +437,7 @@ public async Task> GetLiveStreamWi LiveStreamInfo info; if (_openStreams.TryGetValue(id, out info)) { - return new Tuple(info.MediaSource, info.DirectStreamProvider); + return info; } else { @@ -463,7 +475,7 @@ private async Task CloseLiveStreamWithProvider(IMediaSourceProvider provider, st public async Task CloseLiveStream(string id) { - if (string.IsNullOrWhiteSpace(id)) + if (string.IsNullOrEmpty(id)) { throw new ArgumentNullException("id"); } @@ -498,7 +510,7 @@ public async Task CloseLiveStream(string id) private Tuple GetProvider(string key) { - if (string.IsNullOrWhiteSpace(key)) + if (string.IsNullOrEmpty(key)) { throw new ArgumentException("key"); } @@ -549,6 +561,7 @@ private class LiveStreamInfo public bool Closed; public MediaSourceInfo MediaSource; public IDirectStreamProvider DirectStreamProvider; + public bool AllowLiveMediaInfoProbe { get; set; } } } } \ No newline at end of file diff --git a/Emby.Server.Implementations/Library/ResolverHelper.cs b/Emby.Server.Implementations/Library/ResolverHelper.cs index c18dc1eaee..251ef978df 100644 --- a/Emby.Server.Implementations/Library/ResolverHelper.cs +++ b/Emby.Server.Implementations/Library/ResolverHelper.cs @@ -26,7 +26,7 @@ public static class ResolverHelper public static void SetInitialItemValues(BaseItem item, Folder parent, IFileSystem fileSystem, ILibraryManager libraryManager, IDirectoryService directoryService) { // This version of the below method has no ItemResolveArgs, so we have to require the path already being set - if (string.IsNullOrWhiteSpace(item.Path)) + if (string.IsNullOrEmpty(item.Path)) { throw new ArgumentException("Item must have a Path"); } diff --git a/Emby.Server.Implementations/Library/Resolvers/Audio/AudioResolver.cs b/Emby.Server.Implementations/Library/Resolvers/Audio/AudioResolver.cs index d30aaa133b..9fe9f982bf 100644 --- a/Emby.Server.Implementations/Library/Resolvers/Audio/AudioResolver.cs +++ b/Emby.Server.Implementations/Library/Resolvers/Audio/AudioResolver.cs @@ -107,7 +107,7 @@ protected override MediaBrowser.Controller.Entities.Audio.Audio Resolve(ItemReso return null; } - var isMixedCollectionType = string.IsNullOrWhiteSpace(collectionType); + var isMixedCollectionType = string.IsNullOrEmpty(collectionType); // For conflicting extensions, give priority to videos if (isMixedCollectionType && LibraryManager.IsVideoFile(args.Path, libraryOptions)) diff --git a/Emby.Server.Implementations/Library/Resolvers/Movies/MovieResolver.cs b/Emby.Server.Implementations/Library/Resolvers/Movies/MovieResolver.cs index d74235ec7b..4eb6f8f966 100644 --- a/Emby.Server.Implementations/Library/Resolvers/Movies/MovieResolver.cs +++ b/Emby.Server.Implementations/Library/Resolvers/Movies/MovieResolver.cs @@ -78,7 +78,7 @@ private MultiItemResolverResult ResolveMultipleInternal(Folder parent, return ResolveVideos private async Task UpdateNowPlayingItem(SessionInfo session, PlaybackProgressInfo info, BaseItem libraryItem, bool updateLastCheckInTime) { - if (string.IsNullOrWhiteSpace(info.MediaSourceId)) + if (string.IsNullOrEmpty(info.MediaSourceId)) { info.MediaSourceId = info.ItemId; } - if (!string.IsNullOrWhiteSpace(info.ItemId) && info.Item == null && libraryItem != null) + if (!string.IsNullOrEmpty(info.ItemId) && info.Item == null && libraryItem != null) { var current = session.NowPlayingItem; @@ -427,7 +427,7 @@ private SessionInfo GetSessionInfo(string appName, string appVersion, string dev { CheckDisposed(); - if (string.IsNullOrWhiteSpace(deviceId)) + if (string.IsNullOrEmpty(deviceId)) { throw new ArgumentNullException("deviceId"); } @@ -479,7 +479,7 @@ private SessionInfo CreateSession(string key, string appName, string appVersion, sessionInfo.UserName = username; sessionInfo.RemoteEndPoint = remoteEndPoint; - if (string.IsNullOrWhiteSpace(deviceName)) + if (string.IsNullOrEmpty(deviceName)) { deviceName = "Network Device"; } @@ -623,7 +623,7 @@ public async Task OnPlaybackStart(PlaybackStartInfo info) var session = GetSession(info.SessionId); - var libraryItem = string.IsNullOrWhiteSpace(info.ItemId) + var libraryItem = string.IsNullOrEmpty(info.ItemId) ? null : GetNowPlayingItem(session, info.ItemId); @@ -711,7 +711,7 @@ public async Task OnPlaybackProgress(PlaybackProgressInfo info, bool isAutomated var session = GetSession(info.SessionId); - var libraryItem = string.IsNullOrWhiteSpace(info.ItemId) + var libraryItem = string.IsNullOrEmpty(info.ItemId) ? null : GetNowPlayingItem(session, info.ItemId); @@ -814,17 +814,17 @@ public async Task OnPlaybackStopped(PlaybackStopInfo info) session.StopAutomaticProgress(); - var libraryItem = string.IsNullOrWhiteSpace(info.ItemId) + var libraryItem = string.IsNullOrEmpty(info.ItemId) ? null : GetNowPlayingItem(session, info.ItemId); // Normalize - if (string.IsNullOrWhiteSpace(info.MediaSourceId)) + if (string.IsNullOrEmpty(info.MediaSourceId)) { info.MediaSourceId = info.ItemId; } - if (!string.IsNullOrWhiteSpace(info.ItemId) && info.Item == null && libraryItem != null) + if (!string.IsNullOrEmpty(info.ItemId) && info.Item == null && libraryItem != null) { var current = session.NowPlayingItem; @@ -870,7 +870,7 @@ public async Task OnPlaybackStopped(PlaybackStopInfo info) } } - if (!string.IsNullOrWhiteSpace(info.LiveStreamId)) + if (!string.IsNullOrEmpty(info.LiveStreamId)) { try { @@ -984,7 +984,7 @@ public Task SendGeneralCommand(string controllingSessionId, string sessionId, Ge var session = GetSessionToRemoteControl(sessionId); - if (!string.IsNullOrWhiteSpace(controllingSessionId)) + if (!string.IsNullOrEmpty(controllingSessionId)) { var controllingSession = GetSession(controllingSessionId); AssertCanControl(session, controllingSession); @@ -1067,7 +1067,7 @@ public async Task SendPlayCommand(string controllingSessionId, string sessionId, } } - if (!string.IsNullOrWhiteSpace(controllingSessionId)) + if (!string.IsNullOrEmpty(controllingSessionId)) { var controllingSession = GetSession(controllingSessionId); AssertCanControl(session, controllingSession); @@ -1169,7 +1169,7 @@ public Task SendPlaystateCommand(string controllingSessionId, string sessionId, var session = GetSessionToRemoteControl(sessionId); - if (!string.IsNullOrWhiteSpace(controllingSessionId)) + if (!string.IsNullOrEmpty(controllingSessionId)) { var controllingSession = GetSession(controllingSessionId); AssertCanControl(session, controllingSession); @@ -1209,7 +1209,7 @@ public async Task SendRestartRequiredNotification(CancellationToken cancellation { try { - await session.SessionController.SendRestartRequiredNotification(cancellationToken).ConfigureAwait(false); + await session.SessionController.SendMessage("RestartRequired", string.Empty, cancellationToken).ConfigureAwait(false); } catch (Exception ex) { @@ -1236,7 +1236,7 @@ public Task SendServerShutdownNotification(CancellationToken cancellationToken) { try { - await session.SessionController.SendServerShutdownNotification(cancellationToken).ConfigureAwait(false); + await session.SessionController.SendMessage("ServerShuttingDown", string.Empty, cancellationToken).ConfigureAwait(false); } catch (Exception ex) { @@ -1265,7 +1265,7 @@ public Task SendServerRestartNotification(CancellationToken cancellationToken) { try { - await session.SessionController.SendServerRestartNotification(cancellationToken).ConfigureAwait(false); + await session.SessionController.SendMessage("ServerRestarting", string.Empty, cancellationToken).ConfigureAwait(false); } catch (Exception ex) { @@ -1286,7 +1286,7 @@ private Task SendSessionEndedNotification(SessionInfo sessionInfo, CancellationT { try { - await session.SessionController.SendSessionEndedNotification(dto, cancellationToken).ConfigureAwait(false); + await session.SessionController.SendMessage("SessionEnded", dto, cancellationToken).ConfigureAwait(false); } catch (Exception ex) { @@ -1423,7 +1423,7 @@ private async Task AuthenticateNewSessionInternal(Authenti CheckDisposed(); User user = null; - if (!string.IsNullOrWhiteSpace(request.UserId)) + if (!string.IsNullOrEmpty(request.UserId)) { var idGuid = new Guid(request.UserId); user = _userManager.Users @@ -1443,7 +1443,7 @@ private async Task AuthenticateNewSessionInternal(Authenti throw new SecurityException("User is not allowed access at this time."); } - if (!string.IsNullOrWhiteSpace(request.DeviceId)) + if (!string.IsNullOrEmpty(request.DeviceId)) { if (!_deviceManager.CanAccessDevice(user, request.DeviceId)) { @@ -1526,7 +1526,7 @@ public void Logout(string accessToken) { CheckDisposed(); - if (string.IsNullOrWhiteSpace(accessToken)) + if (string.IsNullOrEmpty(accessToken)) { throw new ArgumentNullException("accessToken"); } @@ -1608,7 +1608,7 @@ private void ReportCapabilities(SessionInfo session, { session.Capabilities = capabilities; - if (!string.IsNullOrWhiteSpace(capabilities.MessageCallbackUrl)) + if (!string.IsNullOrEmpty(capabilities.MessageCallbackUrl)) { var controller = session.SessionController as HttpSessionController; @@ -1774,7 +1774,7 @@ private string GetDtoId(BaseItem item) public void ReportNowViewingItem(string sessionId, string itemId) { - if (string.IsNullOrWhiteSpace(itemId)) + if (string.IsNullOrEmpty(itemId)) { throw new ArgumentNullException("itemId"); } @@ -1821,18 +1821,18 @@ public SessionInfo GetSessionByAuthenticationToken(AuthenticationInfo info, stri throw new ArgumentNullException("info"); } - var user = string.IsNullOrWhiteSpace(info.UserId) + var user = string.IsNullOrEmpty(info.UserId) ? null : _userManager.GetUserById(info.UserId); - appVersion = string.IsNullOrWhiteSpace(appVersion) + appVersion = string.IsNullOrEmpty(appVersion) ? info.AppVersion : appVersion; var deviceName = info.DeviceName; var appName = info.AppName; - if (!string.IsNullOrWhiteSpace(deviceId)) + if (!string.IsNullOrEmpty(deviceId)) { // Replace the info from the token with more recent info var device = _deviceManager.GetDevice(deviceId); @@ -1841,7 +1841,7 @@ public SessionInfo GetSessionByAuthenticationToken(AuthenticationInfo info, stri deviceName = device.Name; appName = device.AppName; - if (!string.IsNullOrWhiteSpace(device.AppVersion)) + if (!string.IsNullOrEmpty(device.AppVersion)) { appVersion = device.AppVersion; } @@ -1853,7 +1853,7 @@ public SessionInfo GetSessionByAuthenticationToken(AuthenticationInfo info, stri } // Prevent argument exception - if (string.IsNullOrWhiteSpace(appVersion)) + if (string.IsNullOrEmpty(appVersion)) { appVersion = "1"; } @@ -1887,8 +1887,36 @@ public Task SendMessageToAdminSessions(string name, T data, CancellationToken return SendMessageToUserSessions(adminUserIds, name, data, cancellationToken); } - public Task SendMessageToUserSessions(List userIds, string name, T data, - CancellationToken cancellationToken) + public Task SendMessageToUserSessions(List userIds, string name, Func dataFn, CancellationToken cancellationToken) + { + CheckDisposed(); + + var sessions = Sessions.Where(i => i.IsActive && i.SessionController != null && userIds.Any(i.ContainsUser)).ToList(); + + if (sessions.Count == 0) + { + return Task.CompletedTask; + } + + var data = dataFn(); + + var tasks = sessions.Select(session => Task.Run(async () => + { + try + { + await session.SessionController.SendMessage(name, data, cancellationToken).ConfigureAwait(false); + } + catch (Exception ex) + { + _logger.ErrorException("Error sending message", ex); + } + + }, cancellationToken)); + + return Task.WhenAll(tasks); + } + + public Task SendMessageToUserSessions(List userIds, string name, T data, CancellationToken cancellationToken) { CheckDisposed(); diff --git a/Emby.Server.Implementations/Session/WebSocketController.cs b/Emby.Server.Implementations/Session/WebSocketController.cs index b13eb6116d..b07291567f 100644 --- a/Emby.Server.Implementations/Session/WebSocketController.cs +++ b/Emby.Server.Implementations/Session/WebSocketController.cs @@ -129,79 +129,6 @@ public Task SendPlaystateCommand(PlaystateRequest command, CancellationToken can }, cancellationToken); } - public Task SendLibraryUpdateInfo(LibraryUpdateInfo info, CancellationToken cancellationToken) - { - return SendMessagesInternal(new WebSocketMessage - { - MessageType = "LibraryChanged", - Data = info - - }, cancellationToken); - } - - /// - /// Sends the restart required message. - /// - /// The information. - /// The cancellation token. - /// Task. - public Task SendRestartRequiredNotification(CancellationToken cancellationToken) - { - return SendMessagesInternal(new WebSocketMessage - { - MessageType = "RestartRequired", - Data = string.Empty - - }, cancellationToken); - } - - - /// - /// Sends the user data change info. - /// - /// The info. - /// The cancellation token. - /// Task. - public Task SendUserDataChangeInfo(UserDataChangeInfo info, CancellationToken cancellationToken) - { - return SendMessagesInternal(new WebSocketMessage - { - MessageType = "UserDataChanged", - Data = info - - }, cancellationToken); - } - - /// - /// Sends the server shutdown notification. - /// - /// The cancellation token. - /// Task. - public Task SendServerShutdownNotification(CancellationToken cancellationToken) - { - return SendMessagesInternal(new WebSocketMessage - { - MessageType = "ServerShuttingDown", - Data = string.Empty - - }, cancellationToken); - } - - /// - /// Sends the server restart notification. - /// - /// The cancellation token. - /// Task. - public Task SendServerRestartNotification(CancellationToken cancellationToken) - { - return SendMessagesInternal(new WebSocketMessage - { - MessageType = "ServerRestarting", - Data = string.Empty - - }, cancellationToken); - } - public Task SendGeneralCommand(GeneralCommand command, CancellationToken cancellationToken) { return SendMessageInternal(new WebSocketMessage @@ -212,16 +139,6 @@ public Task SendGeneralCommand(GeneralCommand command, CancellationToken cancell }, cancellationToken); } - public Task SendSessionEndedNotification(SessionInfoDto sessionInfo, CancellationToken cancellationToken) - { - return SendMessagesInternal(new WebSocketMessage - { - MessageType = "SessionEnded", - Data = sessionInfo - - }, cancellationToken); - } - public Task SendPlaybackStartNotification(SessionInfoDto sessionInfo, CancellationToken cancellationToken) { return SendMessagesInternal(new WebSocketMessage diff --git a/Emby.Server.Implementations/SystemEvents.cs b/Emby.Server.Implementations/SystemEvents.cs index dfff92f1ef..c1e6dc1da9 100644 --- a/Emby.Server.Implementations/SystemEvents.cs +++ b/Emby.Server.Implementations/SystemEvents.cs @@ -17,34 +17,6 @@ public class SystemEvents : ISystemEvents public SystemEvents(ILogger logger) { _logger = logger; - Microsoft.Win32.SystemEvents.PowerModeChanged += SystemEvents_PowerModeChanged; - Microsoft.Win32.SystemEvents.SessionEnding += SystemEvents_SessionEnding; - } - - private void SystemEvents_SessionEnding(object sender, Microsoft.Win32.SessionEndingEventArgs e) - { - switch (e.Reason) - { - case Microsoft.Win32.SessionEndReasons.Logoff: - EventHelper.FireEventIfNotNull(SessionLogoff, this, EventArgs.Empty, _logger); - break; - case Microsoft.Win32.SessionEndReasons.SystemShutdown: - EventHelper.FireEventIfNotNull(SystemShutdown, this, EventArgs.Empty, _logger); - break; - } - } - - private void SystemEvents_PowerModeChanged(object sender, Microsoft.Win32.PowerModeChangedEventArgs e) - { - switch (e.Mode) - { - case Microsoft.Win32.PowerModes.Resume: - EventHelper.FireEventIfNotNull(Resume, this, EventArgs.Empty, _logger); - break; - case Microsoft.Win32.PowerModes.Suspend: - EventHelper.FireEventIfNotNull(Suspend, this, EventArgs.Empty, _logger); - break; - } } } } diff --git a/Emby.Server.Implementations/TV/TVSeriesManager.cs b/Emby.Server.Implementations/TV/TVSeriesManager.cs index d92245a677..f48d152920 100644 --- a/Emby.Server.Implementations/TV/TVSeriesManager.cs +++ b/Emby.Server.Implementations/TV/TVSeriesManager.cs @@ -38,7 +38,7 @@ public QueryResult GetNextUp(NextUpQuery request, DtoOptions dtoOption string presentationUniqueKey = null; int? limit = null; - if (!string.IsNullOrWhiteSpace(request.SeriesId)) + if (!string.IsNullOrEmpty(request.SeriesId)) { var series = _libraryManager.GetItemById(request.SeriesId) as Series; @@ -49,12 +49,12 @@ public QueryResult GetNextUp(NextUpQuery request, DtoOptions dtoOption } } - if (!string.IsNullOrWhiteSpace(presentationUniqueKey)) + if (!string.IsNullOrEmpty(presentationUniqueKey)) { return GetResult(GetNextUpEpisodes(request, user, new[] { presentationUniqueKey }, dtoOptions), request); } - var parentIdGuid = string.IsNullOrWhiteSpace(request.ParentId) ? (Guid?)null : new Guid(request.ParentId); + var parentIdGuid = string.IsNullOrEmpty(request.ParentId) ? (Guid?)null : new Guid(request.ParentId); List parents; @@ -89,7 +89,7 @@ public QueryResult GetNextUp(NextUpQuery request, List paren string presentationUniqueKey = null; int? limit = null; - if (!string.IsNullOrWhiteSpace(request.SeriesId)) + if (!string.IsNullOrEmpty(request.SeriesId)) { var series = _libraryManager.GetItemById(request.SeriesId) as Series; @@ -100,7 +100,7 @@ public QueryResult GetNextUp(NextUpQuery request, List paren } } - if (!string.IsNullOrWhiteSpace(presentationUniqueKey)) + if (!string.IsNullOrEmpty(presentationUniqueKey)) { return GetResult(GetNextUpEpisodes(request, user, new[] { presentationUniqueKey }, dtoOptions), request); } @@ -146,7 +146,7 @@ public IEnumerable GetNextUpEpisodes(NextUpQuery request, User user, IE // If viewing all next up for all series, remove first episodes // But if that returns empty, keep those first episodes (avoid completely empty view) - var alwaysEnableFirstEpisode = !string.IsNullOrWhiteSpace(request.SeriesId); + var alwaysEnableFirstEpisode = !string.IsNullOrEmpty(request.SeriesId); var anyFound = false; return allNextUp diff --git a/Emby.Server.Implementations/Updates/InstallationManager.cs b/Emby.Server.Implementations/Updates/InstallationManager.cs index 51acfee881..7b3059b4d7 100644 --- a/Emby.Server.Implementations/Updates/InstallationManager.cs +++ b/Emby.Server.Implementations/Updates/InstallationManager.cs @@ -304,12 +304,12 @@ protected List FilterPackages(IEnumerable packages) var versions = new List(); foreach (var version in package.versions) { - if (string.IsNullOrWhiteSpace(version.sourceUrl)) + if (string.IsNullOrEmpty(version.sourceUrl)) { continue; } - if (string.IsNullOrWhiteSpace(version.runtimes) || version.runtimes.IndexOf(_packageRuntime, StringComparison.OrdinalIgnoreCase) == -1) + if (string.IsNullOrEmpty(version.runtimes) || version.runtimes.IndexOf(_packageRuntime, StringComparison.OrdinalIgnoreCase) == -1) { continue; } @@ -339,7 +339,7 @@ protected List FilterPackages(IEnumerable packages, st var returnList = new List(); - var filterOnPackageType = !string.IsNullOrWhiteSpace(packageType); + var filterOnPackageType = !string.IsNullOrEmpty(packageType); foreach (var p in packagesList) { @@ -465,7 +465,7 @@ public async Task> GetAvailablePluginUpdates(Ver return latestPluginInfo != null && GetPackageVersion(latestPluginInfo) > p.Version ? latestPluginInfo : null; }).Where(i => i != null) - .Where(p => !string.IsNullOrWhiteSpace(p.sourceUrl) && !CompletedInstallations.Any(i => string.Equals(i.AssemblyGuid, p.guid, StringComparison.OrdinalIgnoreCase))); + .Where(p => !string.IsNullOrEmpty(p.sourceUrl) && !CompletedInstallations.Any(i => string.Equals(i.AssemblyGuid, p.guid, StringComparison.OrdinalIgnoreCase))); } /// diff --git a/MediaBrowser.Api/ChannelService.cs b/MediaBrowser.Api/ChannelService.cs index 2e8eb9e07d..44991f9da6 100644 --- a/MediaBrowser.Api/ChannelService.cs +++ b/MediaBrowser.Api/ChannelService.cs @@ -178,13 +178,6 @@ public IEnumerable GetFilters() } } - [Route("/Channels/Folder", "GET", Summary = "Gets the users channel folder, along with configured images")] - public class GetChannelFolder : IReturn - { - [ApiMember(Name = "UserId", Description = "Optional attach user data.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")] - public string UserId { get; set; } - } - [Authenticated] public class ChannelService : BaseApiService { @@ -209,11 +202,6 @@ public object Get(GetChannelFeatures request) return ToOptimizedResult(result); } - public object Get(GetChannelFolder request) - { - return ToOptimizedResult(_channelManager.GetChannelFolder(request.UserId, CancellationToken.None)); - } - public async Task Get(GetChannels request) { var result = await _channelManager.GetChannels(new ChannelQuery diff --git a/MediaBrowser.Api/MediaBrowser.Api.csproj b/MediaBrowser.Api/MediaBrowser.Api.csproj index 60b2d51870..dabc4d14be 100644 --- a/MediaBrowser.Api/MediaBrowser.Api.csproj +++ b/MediaBrowser.Api/MediaBrowser.Api.csproj @@ -84,7 +84,6 @@ - diff --git a/MediaBrowser.Api/System/ActivityLogWebSocketListener.cs b/MediaBrowser.Api/System/ActivityLogWebSocketListener.cs deleted file mode 100644 index f9cac7389d..0000000000 --- a/MediaBrowser.Api/System/ActivityLogWebSocketListener.cs +++ /dev/null @@ -1,67 +0,0 @@ -using MediaBrowser.Model.Activity; -using MediaBrowser.Model.Events; -using MediaBrowser.Model.Logging; -using System.Collections.Generic; -using System.Threading.Tasks; -using MediaBrowser.Controller.Net; -using MediaBrowser.Model.Threading; -using System.Threading; - -namespace MediaBrowser.Api.System -{ - /// - /// Class SessionInfoWebSocketListener - /// - class ActivityLogWebSocketListener : BasePeriodicWebSocketListener, WebSocketListenerState> - { - /// - /// Gets the name. - /// - /// The name. - protected override string Name - { - get { return "ActivityLogEntry"; } - } - - /// - /// The _kernel - /// - private readonly IActivityManager _activityManager; - - public ActivityLogWebSocketListener(ILogger logger, ITimerFactory timerFactory, IActivityManager activityManager) : base(logger, timerFactory) - { - _activityManager = activityManager; - _activityManager.EntryCreated += _activityManager_EntryCreated; - } - - void _activityManager_EntryCreated(object sender, GenericEventArgs e) - { - SendData(true); - } - - /// - /// Gets the data to send. - /// - /// The state. - /// Task{SystemInfo}. - protected override Task> GetDataToSend(WebSocketListenerState state, CancellationToken CancellationToken) - { - return Task.FromResult(new List()); - } - - protected override bool SendOnTimer - { - get - { - return false; - } - } - - protected override void Dispose(bool dispose) - { - _activityManager.EntryCreated -= _activityManager_EntryCreated; - - base.Dispose(dispose); - } - } -} diff --git a/MediaBrowser.Controller/Channels/ChannelItemInfo.cs b/MediaBrowser.Controller/Channels/ChannelItemInfo.cs index 57c2f1f7fd..5d8944e3d8 100644 --- a/MediaBrowser.Controller/Channels/ChannelItemInfo.cs +++ b/MediaBrowser.Controller/Channels/ChannelItemInfo.cs @@ -3,6 +3,7 @@ using MediaBrowser.Model.Entities; using System; using System.Collections.Generic; +using MediaBrowser.Model.Dto; namespace MediaBrowser.Controller.Channels { @@ -49,7 +50,7 @@ public class ChannelItemInfo : IHasProviderIds public int? IndexNumber { get; set; } public int? ParentIndexNumber { get; set; } - public List MediaSources { get; set; } + public List MediaSources { get; set; } public bool IsInfiniteStream { get; set; } @@ -61,7 +62,7 @@ public class ChannelItemInfo : IHasProviderIds public ChannelItemInfo() { - MediaSources = new List(); + MediaSources = new List(); TrailerTypes = new List(); Genres = new List(); Studios = new List(); diff --git a/MediaBrowser.Controller/Channels/IChannelManager.cs b/MediaBrowser.Controller/Channels/IChannelManager.cs index 37fc892b36..0b9c3b6da8 100644 --- a/MediaBrowser.Controller/Channels/IChannelManager.cs +++ b/MediaBrowser.Controller/Channels/IChannelManager.cs @@ -111,19 +111,5 @@ public interface IChannelManager /// The cancellation token. /// Task{IEnumerable{MediaSourceInfo}}. IEnumerable GetStaticMediaSources(BaseItem item, CancellationToken cancellationToken); - - /// - /// Gets the channel folder. - /// - /// The cancellation token. - /// BaseItemDto. - Folder GetInternalChannelFolder(CancellationToken cancellationToken); - - /// - /// Gets the channel folder. - /// - /// The user identifier. - /// The cancellation token. - BaseItemDto GetChannelFolder(string userId, CancellationToken cancellationToken); } } diff --git a/MediaBrowser.Controller/Channels/IRequiresMediaInfoCallback.cs b/MediaBrowser.Controller/Channels/IRequiresMediaInfoCallback.cs index b4b6be9baf..a2c63586b1 100644 --- a/MediaBrowser.Controller/Channels/IRequiresMediaInfoCallback.cs +++ b/MediaBrowser.Controller/Channels/IRequiresMediaInfoCallback.cs @@ -1,6 +1,7 @@ using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; +using MediaBrowser.Model.Dto; namespace MediaBrowser.Controller.Channels { @@ -9,9 +10,6 @@ public interface IRequiresMediaInfoCallback /// /// Gets the channel item media information. /// - /// The identifier. - /// The cancellation token. - /// Task{IEnumerable{ChannelMediaInfo}}. - Task> GetChannelItemMediaInfo(string id, CancellationToken cancellationToken); + Task> GetChannelItemMediaInfo(string id, CancellationToken cancellationToken); } } \ No newline at end of file diff --git a/MediaBrowser.Controller/Entities/Audio/Audio.cs b/MediaBrowser.Controller/Entities/Audio/Audio.cs index a3d8ad8cc9..b126209bc0 100644 --- a/MediaBrowser.Controller/Entities/Audio/Audio.cs +++ b/MediaBrowser.Controller/Entities/Audio/Audio.cs @@ -34,12 +34,6 @@ public class Audio : BaseItem, [IgnoreDataMember] public string[] AlbumArtists { get; set; } - [IgnoreDataMember] - public override bool EnableRefreshOnDateModifiedChange - { - get { return true; } - } - public Audio() { Artists = EmptyStringArray; @@ -169,13 +163,13 @@ public override List GetUserDataKeys() } songKey += Name; - if (!string.IsNullOrWhiteSpace(Album)) + if (!string.IsNullOrEmpty(Album)) { songKey = Album + "-" + songKey; } var albumArtist = AlbumArtists.Length == 0 ? null : AlbumArtists[0]; - if (!string.IsNullOrWhiteSpace(albumArtist)) + if (!string.IsNullOrEmpty(albumArtist)) { songKey = albumArtist + "-" + songKey; } @@ -241,7 +235,7 @@ public virtual List GetMediaSources(bool enablePathSubstitution foreach (var mediaSource in list) { - if (string.IsNullOrWhiteSpace(mediaSource.Path)) + if (string.IsNullOrEmpty(mediaSource.Path)) { mediaSource.Type = MediaSourceType.Placeholder; } @@ -281,7 +275,7 @@ private MediaSourceInfo GetVersionInfo(Audio i, bool enablePathSubstituion) if (string.IsNullOrEmpty(info.Container)) { - if (!string.IsNullOrWhiteSpace(i.Path) && locationType != LocationType.Remote && locationType != LocationType.Virtual) + if (!string.IsNullOrEmpty(i.Path) && locationType != LocationType.Remote && locationType != LocationType.Virtual) { info.Container = System.IO.Path.GetExtension(i.Path).TrimStart('.'); } diff --git a/MediaBrowser.Controller/Entities/Audio/MusicAlbum.cs b/MediaBrowser.Controller/Entities/Audio/MusicAlbum.cs index acda9ae02b..8a8a364d22 100644 --- a/MediaBrowser.Controller/Entities/Audio/MusicAlbum.cs +++ b/MediaBrowser.Controller/Entities/Audio/MusicAlbum.cs @@ -58,7 +58,7 @@ public MusicArtist GetMusicArtist(DtoOptions options) } var name = AlbumArtist; - if (!string.IsNullOrWhiteSpace(name)) + if (!string.IsNullOrEmpty(name)) { return LibraryManager.GetArtist(name, options); } @@ -146,21 +146,21 @@ public override List GetUserDataKeys() var list = base.GetUserDataKeys(); var albumArtist = AlbumArtist; - if (!string.IsNullOrWhiteSpace(albumArtist)) + if (!string.IsNullOrEmpty(albumArtist)) { list.Insert(0, albumArtist + "-" + Name); } var id = this.GetProviderId(MetadataProviders.MusicBrainzAlbum); - if (!string.IsNullOrWhiteSpace(id)) + if (!string.IsNullOrEmpty(id)) { list.Insert(0, "MusicAlbum-Musicbrainz-" + id); } id = this.GetProviderId(MetadataProviders.MusicBrainzReleaseGroup); - if (!string.IsNullOrWhiteSpace(id)) + if (!string.IsNullOrEmpty(id)) { list.Insert(0, "MusicAlbum-MusicBrainzReleaseGroup-" + id); } @@ -198,9 +198,9 @@ public AlbumInfo GetLookupInfo() var album = id.SongInfos .Select(i => i.Album) - .FirstOrDefault(i => !string.IsNullOrWhiteSpace(i)); + .FirstOrDefault(i => !string.IsNullOrEmpty(i)); - if (!string.IsNullOrWhiteSpace(album)) + if (!string.IsNullOrEmpty(album)) { id.Name = album; } @@ -253,7 +253,7 @@ private async Task RefreshArtists(MetadataRefreshOptions refreshOptions, Cancell foreach (var i in all) { // This should not be necessary but we're seeing some cases of it - if (string.IsNullOrWhiteSpace(i)) + if (string.IsNullOrEmpty(i)) { continue; } diff --git a/MediaBrowser.Controller/Entities/BaseItem.cs b/MediaBrowser.Controller/Entities/BaseItem.cs index 03c01bbee1..f59e8f1595 100644 --- a/MediaBrowser.Controller/Entities/BaseItem.cs +++ b/MediaBrowser.Controller/Entities/BaseItem.cs @@ -260,7 +260,7 @@ public virtual SourceType SourceType { get { - if (!string.IsNullOrWhiteSpace(ChannelId)) + if (!string.IsNullOrEmpty(ChannelId)) { return SourceType.Channel; } @@ -363,7 +363,7 @@ public virtual LocationType LocationType // return LocationType.Offline; //} - if (string.IsNullOrWhiteSpace(Path)) + if (string.IsNullOrEmpty(Path)) { if (SourceType == SourceType.Channel) { @@ -544,12 +544,6 @@ public bool CanDownload(User user) [IgnoreDataMember] public DateTime DateLastRefreshed { get; set; } - [IgnoreDataMember] - public virtual bool EnableRefreshOnDateModifiedChange - { - get { return false; } - } - /// /// The logger /// @@ -640,7 +634,7 @@ public string SortName { if (_sortName == null) { - if (!string.IsNullOrWhiteSpace(ForcedSortName)) + if (!string.IsNullOrEmpty(ForcedSortName)) { // Need the ToLower because that's what CreateSortName does _sortName = ModifySortChunks(ForcedSortName).ToLower(); @@ -960,7 +954,7 @@ public string OfficialRatingForComparison get { var officialRating = OfficialRating; - if (!string.IsNullOrWhiteSpace(officialRating)) + if (!string.IsNullOrEmpty(officialRating)) { return officialRating; } @@ -981,7 +975,7 @@ public string CustomRatingForComparison get { var customRating = CustomRating; - if (!string.IsNullOrWhiteSpace(customRating)) + if (!string.IsNullOrEmpty(customRating)) { return customRating; } @@ -1366,7 +1360,7 @@ public virtual List GetUserDataKeys() if (SourceType == SourceType.Channel) { - if (!string.IsNullOrWhiteSpace(ExternalId)) + if (!string.IsNullOrEmpty(ExternalId)) { list.Add(ExternalId); } @@ -1402,26 +1396,26 @@ public string GetPreferredMetadataLanguage() { string lang = PreferredMetadataLanguage; - if (string.IsNullOrWhiteSpace(lang)) + if (string.IsNullOrEmpty(lang)) { lang = GetParents() .Select(i => i.PreferredMetadataLanguage) - .FirstOrDefault(i => !string.IsNullOrWhiteSpace(i)); + .FirstOrDefault(i => !string.IsNullOrEmpty(i)); } - if (string.IsNullOrWhiteSpace(lang)) + if (string.IsNullOrEmpty(lang)) { lang = LibraryManager.GetCollectionFolders(this) .Select(i => i.PreferredMetadataLanguage) - .FirstOrDefault(i => !string.IsNullOrWhiteSpace(i)); + .FirstOrDefault(i => !string.IsNullOrEmpty(i)); } - if (string.IsNullOrWhiteSpace(lang)) + if (string.IsNullOrEmpty(lang)) { lang = LibraryManager.GetLibraryOptions(this).PreferredMetadataLanguage; } - if (string.IsNullOrWhiteSpace(lang)) + if (string.IsNullOrEmpty(lang)) { lang = ConfigurationManager.Configuration.PreferredMetadataLanguage; } @@ -1437,26 +1431,26 @@ public string GetPreferredMetadataCountryCode() { string lang = PreferredMetadataCountryCode; - if (string.IsNullOrWhiteSpace(lang)) + if (string.IsNullOrEmpty(lang)) { lang = GetParents() .Select(i => i.PreferredMetadataCountryCode) - .FirstOrDefault(i => !string.IsNullOrWhiteSpace(i)); + .FirstOrDefault(i => !string.IsNullOrEmpty(i)); } - if (string.IsNullOrWhiteSpace(lang)) + if (string.IsNullOrEmpty(lang)) { lang = LibraryManager.GetCollectionFolders(this) .Select(i => i.PreferredMetadataCountryCode) - .FirstOrDefault(i => !string.IsNullOrWhiteSpace(i)); + .FirstOrDefault(i => !string.IsNullOrEmpty(i)); } - if (string.IsNullOrWhiteSpace(lang)) + if (string.IsNullOrEmpty(lang)) { lang = LibraryManager.GetLibraryOptions(this).MetadataCountryCode; } - if (string.IsNullOrWhiteSpace(lang)) + if (string.IsNullOrEmpty(lang)) { lang = ConfigurationManager.Configuration.MetadataCountryCode; } @@ -1503,12 +1497,12 @@ public bool IsParentalAllowed(User user) var rating = CustomRatingForComparison; - if (string.IsNullOrWhiteSpace(rating)) + if (string.IsNullOrEmpty(rating)) { rating = OfficialRatingForComparison; } - if (string.IsNullOrWhiteSpace(rating)) + if (string.IsNullOrEmpty(rating)) { return !GetBlockUnratedValue(user.Policy); } @@ -1535,12 +1529,12 @@ public bool IsParentalAllowed(User user) { var rating = CustomRating; - if (string.IsNullOrWhiteSpace(rating)) + if (string.IsNullOrEmpty(rating)) { rating = OfficialRating; } - if (string.IsNullOrWhiteSpace(rating)) + if (string.IsNullOrEmpty(rating)) { return null; } @@ -1552,12 +1546,12 @@ public bool IsParentalAllowed(User user) { var rating = CustomRatingForComparison; - if (string.IsNullOrWhiteSpace(rating)) + if (string.IsNullOrEmpty(rating)) { rating = OfficialRatingForComparison; } - if (string.IsNullOrWhiteSpace(rating)) + if (string.IsNullOrEmpty(rating)) { return null; } @@ -1674,7 +1668,7 @@ protected bool IsVisibleStandaloneInternal(User user, bool checkFolders) { var topParent = GetParents().LastOrDefault() ?? this; - if (string.IsNullOrWhiteSpace(topParent.Path)) + if (string.IsNullOrEmpty(topParent.Path)) { return true; } @@ -1768,7 +1762,7 @@ protected BaseItem GetLinkedChild(LinkedChild info) private BaseItem FindLinkedChild(LinkedChild info) { - if (!string.IsNullOrWhiteSpace(info.Path)) + if (!string.IsNullOrEmpty(info.Path)) { var itemByPath = LibraryManager.FindByPath(info.Path, null); @@ -1780,7 +1774,7 @@ private BaseItem FindLinkedChild(LinkedChild info) return itemByPath; } - if (!string.IsNullOrWhiteSpace(info.LibraryItemId)) + if (!string.IsNullOrEmpty(info.LibraryItemId)) { var item = LibraryManager.GetItemById(info.LibraryItemId); @@ -1811,7 +1805,7 @@ public virtual bool EnableRememberingTrackSelections /// public void AddStudio(string name) { - if (string.IsNullOrWhiteSpace(name)) + if (string.IsNullOrEmpty(name)) { throw new ArgumentNullException("name"); } @@ -1845,7 +1839,7 @@ public void SetStudios(IEnumerable names) /// public void AddGenre(string name) { - if (string.IsNullOrWhiteSpace(name)) + if (string.IsNullOrEmpty(name)) { throw new ArgumentNullException("name"); } @@ -2102,7 +2096,7 @@ public ItemImageInfo GetImageInfo(ImageType imageType, int imageIndex) var path = chapter.ImagePath; - if (string.IsNullOrWhiteSpace(path)) + if (string.IsNullOrEmpty(path)) { return null; } diff --git a/MediaBrowser.Controller/Entities/Extensions.cs b/MediaBrowser.Controller/Entities/Extensions.cs index 36855a86c1..869b051e5e 100644 --- a/MediaBrowser.Controller/Entities/Extensions.cs +++ b/MediaBrowser.Controller/Entities/Extensions.cs @@ -15,7 +15,7 @@ public static class Extensions /// public static void AddTrailerUrl(this IHasTrailers item, string url) { - if (string.IsNullOrWhiteSpace(url)) + if (string.IsNullOrEmpty(url)) { throw new ArgumentNullException("url"); } diff --git a/MediaBrowser.Controller/Entities/Folder.cs b/MediaBrowser.Controller/Entities/Folder.cs index f5ffd12616..406bcdd64b 100644 --- a/MediaBrowser.Controller/Entities/Folder.cs +++ b/MediaBrowser.Controller/Entities/Folder.cs @@ -660,7 +660,7 @@ public bool IsPathOffline(string path, List allLibraryPaths) var originalPath = path; // Depending on whether the path is local or unc, it may return either null or '\' at the top - while (!string.IsNullOrWhiteSpace(path) && path.Length > 1) + while (!string.IsNullOrEmpty(path) && path.Length > 1) { if (FileSystem.DirectoryExists(path)) { @@ -913,7 +913,7 @@ private bool RequiresPostFiltering(InternalItemsQuery query) return true; } - if (!string.IsNullOrWhiteSpace(query.AdjacentTo)) + if (!string.IsNullOrEmpty(query.AdjacentTo)) { Logger.Debug("Query requires post-filtering due to AdjacentTo"); return true; diff --git a/MediaBrowser.Controller/Entities/LinkedChild.cs b/MediaBrowser.Controller/Entities/LinkedChild.cs index 707bda5fa2..363a3d6fdb 100644 --- a/MediaBrowser.Controller/Entities/LinkedChild.cs +++ b/MediaBrowser.Controller/Entities/LinkedChild.cs @@ -27,7 +27,7 @@ public static LinkedChild Create(BaseItem item) Type = LinkedChildType.Manual }; - if (string.IsNullOrWhiteSpace(child.Path)) + if (string.IsNullOrEmpty(child.Path)) { child.LibraryItemId = item.Id.ToString("N"); } diff --git a/MediaBrowser.Controller/Entities/Movies/BoxSet.cs b/MediaBrowser.Controller/Entities/Movies/BoxSet.cs index 26a386d49f..b37f2edbab 100644 --- a/MediaBrowser.Controller/Entities/Movies/BoxSet.cs +++ b/MediaBrowser.Controller/Entities/Movies/BoxSet.cs @@ -109,7 +109,7 @@ private bool IsLegacyBoxSet { get { - if (string.IsNullOrWhiteSpace(Path)) + if (string.IsNullOrEmpty(Path)) { return false; } diff --git a/MediaBrowser.Controller/Entities/Movies/Movie.cs b/MediaBrowser.Controller/Entities/Movies/Movie.cs index 2e0e019443..b4d996b3c8 100644 --- a/MediaBrowser.Controller/Entities/Movies/Movie.cs +++ b/MediaBrowser.Controller/Entities/Movies/Movie.cs @@ -172,7 +172,7 @@ public override List GetRelatedUrls() var list = base.GetRelatedUrls(); var imdbId = this.GetProviderId(MetadataProviders.Imdb); - if (!string.IsNullOrWhiteSpace(imdbId)) + if (!string.IsNullOrEmpty(imdbId)) { list.Add(new ExternalUrl { diff --git a/MediaBrowser.Controller/Entities/PeopleHelper.cs b/MediaBrowser.Controller/Entities/PeopleHelper.cs index 412eb94998..9f85b2aea6 100644 --- a/MediaBrowser.Controller/Entities/PeopleHelper.cs +++ b/MediaBrowser.Controller/Entities/PeopleHelper.cs @@ -14,7 +14,7 @@ public static void AddPerson(List people, PersonInfo person) throw new ArgumentNullException("person"); } - if (string.IsNullOrWhiteSpace(person.Name)) + if (string.IsNullOrEmpty(person.Name)) { throw new ArgumentNullException(); } @@ -62,7 +62,7 @@ public static void AddPerson(List people, PersonInfo person) else { // Was there, if no role and we have one - fill it in - if (string.IsNullOrWhiteSpace(existing.Role) && !string.IsNullOrWhiteSpace(person.Role)) + if (string.IsNullOrEmpty(existing.Role) && !string.IsNullOrEmpty(person.Role)) { existing.Role = person.Role; } @@ -101,7 +101,7 @@ private static void MergeExisting(PersonInfo existing, PersonInfo person) public static bool ContainsPerson(List people, string name) { - if (string.IsNullOrWhiteSpace(name)) + if (string.IsNullOrEmpty(name)) { throw new ArgumentNullException("name"); } diff --git a/MediaBrowser.Controller/Entities/Photo.cs b/MediaBrowser.Controller/Entities/Photo.cs index 11db633bad..bdce89b4a5 100644 --- a/MediaBrowser.Controller/Entities/Photo.cs +++ b/MediaBrowser.Controller/Entities/Photo.cs @@ -51,12 +51,6 @@ public PhotoAlbum AlbumEntity } } - [IgnoreDataMember] - public override bool EnableRefreshOnDateModifiedChange - { - get { return true; } - } - public override bool CanDownload() { return true; diff --git a/MediaBrowser.Controller/Entities/TV/Series.cs b/MediaBrowser.Controller/Entities/TV/Series.cs index b8f0c8276a..592ec08347 100644 --- a/MediaBrowser.Controller/Entities/TV/Series.cs +++ b/MediaBrowser.Controller/Entities/TV/Series.cs @@ -112,7 +112,7 @@ public override string CreatePresentationUniqueKey() private string AddLibrariesToPresentationUniqueKey(string key) { var lang = GetPreferredMetadataLanguage(); - if (!string.IsNullOrWhiteSpace(lang)) + if (!string.IsNullOrEmpty(lang)) { key += "-" + lang; } @@ -188,13 +188,13 @@ public override List GetUserDataKeys() var list = base.GetUserDataKeys(); var key = this.GetProviderId(MetadataProviders.Imdb); - if (!string.IsNullOrWhiteSpace(key)) + if (!string.IsNullOrEmpty(key)) { list.Insert(0, key); } key = this.GetProviderId(MetadataProviders.Tvdb); - if (!string.IsNullOrWhiteSpace(key)) + if (!string.IsNullOrEmpty(key)) { list.Insert(0, key); } @@ -518,7 +518,7 @@ public override List GetRelatedUrls() var list = base.GetRelatedUrls(); var imdbId = this.GetProviderId(MetadataProviders.Imdb); - if (!string.IsNullOrWhiteSpace(imdbId)) + if (!string.IsNullOrEmpty(imdbId)) { list.Add(new ExternalUrl { diff --git a/MediaBrowser.Controller/Entities/Trailer.cs b/MediaBrowser.Controller/Entities/Trailer.cs index c5144aadf4..0c52997565 100644 --- a/MediaBrowser.Controller/Entities/Trailer.cs +++ b/MediaBrowser.Controller/Entities/Trailer.cs @@ -96,7 +96,7 @@ public override List GetRelatedUrls() var list = base.GetRelatedUrls(); var imdbId = this.GetProviderId(MetadataProviders.Imdb); - if (!string.IsNullOrWhiteSpace(imdbId)) + if (!string.IsNullOrEmpty(imdbId)) { list.Add(new ExternalUrl { diff --git a/MediaBrowser.Controller/Entities/UserView.cs b/MediaBrowser.Controller/Entities/UserView.cs index 2152e65cfb..ee8cee936c 100644 --- a/MediaBrowser.Controller/Entities/UserView.cs +++ b/MediaBrowser.Controller/Entities/UserView.cs @@ -84,8 +84,8 @@ protected override QueryResult GetItemsInternal(InternalItemsQuery que parent = LibraryManager.GetItemById(ParentId) as Folder ?? parent; } - return new UserViewBuilder(UserViewManager, LiveTvManager, ChannelManager, LibraryManager, Logger, UserDataManager, TVSeriesManager, ConfigurationManager, PlaylistManager) - .GetUserItems(parent, this, ViewType, query).Result; + return new UserViewBuilder(UserViewManager, LibraryManager, Logger, UserDataManager, TVSeriesManager, ConfigurationManager, PlaylistManager) + .GetUserItems(parent, this, ViewType, query); } public override List GetChildren(User user, bool includeLinkedChildren) @@ -113,19 +113,12 @@ public override bool IsSaveLocalMetadataEnabled() public override IEnumerable GetRecursiveChildren(User user, InternalItemsQuery query) { - var result = GetItemList(new InternalItemsQuery - { - User = user, - Recursive = true, - EnableTotalRecordCount = false, - - ForceDirect = true, - - DtoOptions = query.DtoOptions - - }); + query.SetUser(user); + query.Recursive = true; + query.EnableTotalRecordCount = false; + query.ForceDirect = true; - return result.Where(i => UserViewBuilder.FilterItem(i, query)); + return GetItemList(query); } protected override IEnumerable GetEligibleChildrenForRecursiveChildren(User user) diff --git a/MediaBrowser.Controller/Entities/UserViewBuilder.cs b/MediaBrowser.Controller/Entities/UserViewBuilder.cs index aa12f71ae0..22519eb945 100644 --- a/MediaBrowser.Controller/Entities/UserViewBuilder.cs +++ b/MediaBrowser.Controller/Entities/UserViewBuilder.cs @@ -1,14 +1,10 @@ -using MediaBrowser.Controller.Channels; -using MediaBrowser.Controller.Entities.Audio; +using MediaBrowser.Controller.Entities.Audio; using MediaBrowser.Controller.Entities.Movies; using MediaBrowser.Controller.Entities.TV; using MediaBrowser.Controller.Library; -using MediaBrowser.Controller.LiveTv; using MediaBrowser.Controller.Playlists; using MediaBrowser.Controller.TV; -using MediaBrowser.Model.Channels; using MediaBrowser.Model.Entities; -using MediaBrowser.Model.LiveTv; using MediaBrowser.Model.Logging; using MediaBrowser.Model.Querying; using System; @@ -24,8 +20,6 @@ namespace MediaBrowser.Controller.Entities { public class UserViewBuilder { - private readonly IChannelManager _channelManager; - private readonly ILiveTvManager _liveTvManager; private readonly IUserViewManager _userViewManager; private readonly ILibraryManager _libraryManager; private readonly ILogger _logger; @@ -34,11 +28,9 @@ public class UserViewBuilder private readonly IServerConfigurationManager _config; private readonly IPlaylistManager _playlistManager; - public UserViewBuilder(IUserViewManager userViewManager, ILiveTvManager liveTvManager, IChannelManager channelManager, ILibraryManager libraryManager, ILogger logger, IUserDataManager userDataManager, ITVSeriesManager tvSeriesManager, IServerConfigurationManager config, IPlaylistManager playlistManager) + public UserViewBuilder(IUserViewManager userViewManager, ILibraryManager libraryManager, ILogger logger, IUserDataManager userDataManager, ITVSeriesManager tvSeriesManager, IServerConfigurationManager config, IPlaylistManager playlistManager) { _userViewManager = userViewManager; - _liveTvManager = liveTvManager; - _channelManager = channelManager; _libraryManager = libraryManager; _logger = logger; _userDataManager = userDataManager; @@ -47,7 +39,7 @@ public UserViewBuilder(IUserViewManager userViewManager, ILiveTvManager liveTvMa _playlistManager = playlistManager; } - public async Task> GetUserItems(Folder queryParent, Folder displayParent, string viewType, InternalItemsQuery query) + public QueryResult GetUserItems(Folder queryParent, Folder displayParent, string viewType, InternalItemsQuery query) { var user = query.User; @@ -63,64 +55,6 @@ public async Task> GetUserItems(Folder queryParent, Folder switch (viewType) { - case CollectionType.Channels: - { - var result = await _channelManager.GetChannelsInternal(new ChannelQuery - { - UserId = user == null ? null : user.Id.ToString("N"), - Limit = query.Limit, - StartIndex = query.StartIndex - - }, CancellationToken.None).ConfigureAwait(false); - - return GetResult(result); - } - - case SpecialFolder.LiveTvChannels: - { - var result = _liveTvManager.GetInternalChannels(new LiveTvChannelQuery - { - UserId = query.User.Id.ToString("N"), - Limit = query.Limit, - StartIndex = query.StartIndex - - }, new DtoOptions(), CancellationToken.None); - - return GetResult(result); - } - - case SpecialFolder.LiveTvNowPlaying: - { - var result = _liveTvManager.GetRecommendedProgramsInternal(new RecommendedProgramQuery - { - UserId = query.User.Id.ToString("N"), - Limit = query.Limit, - IsAiring = true - - }, new Dto.DtoOptions(), CancellationToken.None); - - return GetResult(result); - } - - case SpecialFolder.LiveTvRecordingGroups: - { - var result = await _liveTvManager.GetInternalRecordings(new RecordingQuery - { - UserId = query.User.Id.ToString("N"), - Status = RecordingStatus.Completed, - Limit = query.Limit, - StartIndex = query.StartIndex - - }, new DtoOptions(), CancellationToken.None).ConfigureAwait(false); - - return GetResult(result); - } - - case CollectionType.LiveTv: - { - return await GetLiveTvView(queryParent, user, query).ConfigureAwait(false); - } - case CollectionType.Photos: case CollectionType.Books: case CollectionType.HomeVideos: @@ -1624,28 +1558,6 @@ private List GetMediaFolders(Folder parent, User user, IEnumerable { parent }; } - private async Task> GetLiveTvView(Folder queryParent, User user, InternalItemsQuery query) - { - if (query.Recursive) - { - return await _liveTvManager.GetInternalRecordings(new RecordingQuery - { - IsInProgress = false, - Status = RecordingStatus.Completed, - UserId = user.Id.ToString("N") - - }, new DtoOptions(), CancellationToken.None).ConfigureAwait(false); - } - - var list = new List(); - - //list.Add(await GetUserSubView(SpecialFolder.LiveTvNowPlaying, user, "0", parent).ConfigureAwait(false)); - list.Add(GetUserView(SpecialFolder.LiveTvChannels, "Channels", string.Empty, user.RootFolder)); - list.Add(GetUserView(SpecialFolder.LiveTvRecordingGroups, "HeaderRecordingGroups", string.Empty, user.RootFolder)); - - return GetResult(list, queryParent, query); - } - private UserView GetUserViewWithName(string name, string type, string sortName, BaseItem parent) { return _userViewManager.GetUserSubView(name, parent.Id.ToString("N"), type, sortName, CancellationToken.None); diff --git a/MediaBrowser.Controller/Entities/Video.cs b/MediaBrowser.Controller/Entities/Video.cs index 24a0d7c18c..3a89d3c347 100644 --- a/MediaBrowser.Controller/Entities/Video.cs +++ b/MediaBrowser.Controller/Entities/Video.cs @@ -86,7 +86,7 @@ public override bool SupportsPositionTicksResume public void SetPrimaryVersionId(string id) { - if (string.IsNullOrWhiteSpace(id)) + if (string.IsNullOrEmpty(id)) { PrimaryVersionId = null; } @@ -100,7 +100,7 @@ public void SetPrimaryVersionId(string id) public override string CreatePresentationUniqueKey() { - if (!string.IsNullOrWhiteSpace(PrimaryVersionId)) + if (!string.IsNullOrEmpty(PrimaryVersionId)) { return PrimaryVersionId; } @@ -108,15 +108,6 @@ public override string CreatePresentationUniqueKey() return base.CreatePresentationUniqueKey(); } - [IgnoreDataMember] - public override bool EnableRefreshOnDateModifiedChange - { - get - { - return VideoType == VideoType.VideoFile || VideoType == VideoType.Iso; - } - } - [IgnoreDataMember] public override bool SupportsThemeMedia { @@ -225,7 +216,7 @@ public int MediaSourceCount { get { - if (!string.IsNullOrWhiteSpace(PrimaryVersionId)) + if (!string.IsNullOrEmpty(PrimaryVersionId)) { var item = LibraryManager.GetItemById(PrimaryVersionId) as Video; if (item != null) @@ -312,13 +303,13 @@ public override List GetUserDataKeys() if (ExtraType.HasValue) { var key = this.GetProviderId(MetadataProviders.Tmdb); - if (!string.IsNullOrWhiteSpace(key)) + if (!string.IsNullOrEmpty(key)) { list.Insert(0, GetUserDataKey(key)); } key = this.GetProviderId(MetadataProviders.Imdb); - if (!string.IsNullOrWhiteSpace(key)) + if (!string.IsNullOrEmpty(key)) { list.Insert(0, GetUserDataKey(key)); } @@ -326,13 +317,13 @@ public override List GetUserDataKeys() else { var key = this.GetProviderId(MetadataProviders.Imdb); - if (!string.IsNullOrWhiteSpace(key)) + if (!string.IsNullOrEmpty(key)) { list.Insert(0, key); } key = this.GetProviderId(MetadataProviders.Tmdb); - if (!string.IsNullOrWhiteSpace(key)) + if (!string.IsNullOrEmpty(key)) { list.Insert(0, key); } @@ -603,7 +594,7 @@ private List> GetAllVideosForMediaSources() list.Add(new Tuple(this, MediaSourceType.Default)); list.AddRange(GetLinkedAlternateVersions().Select(i => new Tuple(i, MediaSourceType.Grouping))); - if (!string.IsNullOrWhiteSpace(PrimaryVersionId)) + if (!string.IsNullOrEmpty(PrimaryVersionId)) { var primary = LibraryManager.GetItemById(PrimaryVersionId) as Video; if (primary != null) @@ -711,7 +702,7 @@ private MediaSourceInfo GetVersionInfo(bool enablePathSubstitution, Video media, { info.Path = media.ShortcutPath; - if (!string.IsNullOrWhiteSpace(info.Path)) + if (!string.IsNullOrEmpty(info.Path)) { if (info.Path.StartsWith("Http", StringComparison.OrdinalIgnoreCase)) { @@ -739,7 +730,7 @@ private MediaSourceInfo GetVersionInfo(bool enablePathSubstitution, Video media, { if (media.VideoType == VideoType.VideoFile || media.VideoType == VideoType.Iso) { - if (!string.IsNullOrWhiteSpace(media.Path) && locationType != LocationType.Remote && locationType != LocationType.Virtual) + if (!string.IsNullOrEmpty(media.Path) && locationType != LocationType.Remote && locationType != LocationType.Virtual) { info.Container = System.IO.Path.GetExtension(media.Path).TrimStart('.'); } @@ -758,7 +749,7 @@ private string GetMediaSourceName(Video video) var locationType = video.LocationType; var path = video.Path; - if ((locationType == LocationType.FileSystem || locationType == LocationType.Offline) && !string.IsNullOrWhiteSpace(path)) + if ((locationType == LocationType.FileSystem || locationType == LocationType.Offline) && !string.IsNullOrEmpty(path)) { terms.Add(System.IO.Path.GetFileName(path)); } diff --git a/MediaBrowser.Controller/IO/FileData.cs b/MediaBrowser.Controller/IO/FileData.cs index 880b3a0ce6..6949bf7b2d 100644 --- a/MediaBrowser.Controller/IO/FileData.cs +++ b/MediaBrowser.Controller/IO/FileData.cs @@ -73,7 +73,7 @@ public static FileSystemMetadata[] GetFilteredFileSystemEntries(IDirectoryServic { var newPath = fileSystem.ResolveShortcut(fullName); - if (string.IsNullOrWhiteSpace(newPath)) + if (string.IsNullOrEmpty(newPath)) { //invalid shortcut - could be old or target could just be unavailable logger.Warn("Encountered invalid shortcut: " + fullName); diff --git a/MediaBrowser.Controller/Library/IMediaSourceProvider.cs b/MediaBrowser.Controller/Library/IMediaSourceProvider.cs index df085d4bcb..73cd8bc02c 100644 --- a/MediaBrowser.Controller/Library/IMediaSourceProvider.cs +++ b/MediaBrowser.Controller/Library/IMediaSourceProvider.cs @@ -20,7 +20,7 @@ public interface IMediaSourceProvider /// /// Opens the media source. /// - Task> OpenMediaSource(string openToken, CancellationToken cancellationToken); + Task> OpenMediaSource(string openToken, CancellationToken cancellationToken); /// /// Closes the media source. diff --git a/MediaBrowser.Controller/Library/ItemResolveArgs.cs b/MediaBrowser.Controller/Library/ItemResolveArgs.cs index 56392eee7b..7197425f3f 100644 --- a/MediaBrowser.Controller/Library/ItemResolveArgs.cs +++ b/MediaBrowser.Controller/Library/ItemResolveArgs.cs @@ -177,7 +177,7 @@ public string[] PhysicalLocations { get { - var paths = string.IsNullOrWhiteSpace(Path) ? new string[] { } : new[] { Path }; + var paths = string.IsNullOrEmpty(Path) ? new string[] { } : new[] { Path }; return AdditionalLocations == null ? paths : paths.Concat(AdditionalLocations).ToArray(); } } diff --git a/MediaBrowser.Controller/Library/TVUtils.cs b/MediaBrowser.Controller/Library/TVUtils.cs index 86e1beef85..dc95ba1127 100644 --- a/MediaBrowser.Controller/Library/TVUtils.cs +++ b/MediaBrowser.Controller/Library/TVUtils.cs @@ -25,9 +25,9 @@ public static class TVUtils /// List{DayOfWeek}. public static DayOfWeek[] GetAirDays(string day) { - if (!string.IsNullOrWhiteSpace(day)) + if (!string.IsNullOrEmpty(day)) { - if (day.Equals("Daily", StringComparison.OrdinalIgnoreCase)) + if (string.Equals(day, "Daily", StringComparison.OrdinalIgnoreCase)) { return new DayOfWeek[] { diff --git a/MediaBrowser.Controller/LiveTv/ILiveTvManager.cs b/MediaBrowser.Controller/LiveTv/ILiveTvManager.cs index 4934cc1ca8..cbd7119b25 100644 --- a/MediaBrowser.Controller/LiveTv/ILiveTvManager.cs +++ b/MediaBrowser.Controller/LiveTv/ILiveTvManager.cs @@ -147,7 +147,7 @@ public interface ILiveTvManager /// The media source identifier. /// The cancellation token. /// Task{StreamResponseInfo}. - Task> GetChannelStream(string id, string mediaSourceId, CancellationToken cancellationToken); + Task> GetChannelStream(string id, string mediaSourceId, CancellationToken cancellationToken); /// /// Gets the program. diff --git a/MediaBrowser.Controller/LiveTv/ILiveTvService.cs b/MediaBrowser.Controller/LiveTv/ILiveTvService.cs index aa26d9de22..9d4815e732 100644 --- a/MediaBrowser.Controller/LiveTv/ILiveTvService.cs +++ b/MediaBrowser.Controller/LiveTv/ILiveTvService.cs @@ -224,7 +224,7 @@ public interface ISupportsNewTimerIds public interface ISupportsDirectStreamProvider { - Task> GetChannelStreamWithDirectStreamProvider(string channelId, string streamId, CancellationToken cancellationToken); + Task> GetChannelStreamWithDirectStreamProvider(string channelId, string streamId, CancellationToken cancellationToken); } public interface ISupportsUpdatingDefaults diff --git a/MediaBrowser.Controller/LiveTv/LiveTvAudioRecording.cs b/MediaBrowser.Controller/LiveTv/LiveTvAudioRecording.cs index 4ee7cbe21b..25eef375a7 100644 --- a/MediaBrowser.Controller/LiveTv/LiveTvAudioRecording.cs +++ b/MediaBrowser.Controller/LiveTv/LiveTvAudioRecording.cs @@ -145,7 +145,7 @@ public override List GetMediaSources(bool enablePathSubstitutio foreach (var mediaSource in list) { - if (string.IsNullOrWhiteSpace(mediaSource.Path)) + if (string.IsNullOrEmpty(mediaSource.Path)) { mediaSource.Type = MediaSourceType.Placeholder; } diff --git a/MediaBrowser.Controller/LiveTv/LiveTvProgram.cs b/MediaBrowser.Controller/LiveTv/LiveTvProgram.cs index 9dff18690e..e9a5c77d20 100644 --- a/MediaBrowser.Controller/LiveTv/LiveTvProgram.cs +++ b/MediaBrowser.Controller/LiveTv/LiveTvProgram.cs @@ -26,18 +26,18 @@ public override List GetUserDataKeys() if (!IsSeries) { var key = this.GetProviderId(MetadataProviders.Imdb); - if (!string.IsNullOrWhiteSpace(key)) + if (!string.IsNullOrEmpty(key)) { list.Insert(0, key); } key = this.GetProviderId(MetadataProviders.Tmdb); - if (!string.IsNullOrWhiteSpace(key)) + if (!string.IsNullOrEmpty(key)) { list.Insert(0, key); } } - else if (!string.IsNullOrWhiteSpace(EpisodeTitle)) + else if (!string.IsNullOrEmpty(EpisodeTitle)) { var name = GetClientTypeName(); @@ -296,7 +296,7 @@ private ListingsProviderInfo GetListingsProviderInfo() { var config = GetConfiguration(); - return config.ListingProviders.FirstOrDefault(i => !string.IsNullOrWhiteSpace(i.MoviePrefix)); + return config.ListingProviders.FirstOrDefault(i => !string.IsNullOrEmpty(i.MoviePrefix)); } return null; @@ -310,7 +310,7 @@ protected override string GetNameForMetadataLookup() if (listings != null) { - if (!string.IsNullOrWhiteSpace(listings.MoviePrefix) && name.StartsWith(listings.MoviePrefix, StringComparison.OrdinalIgnoreCase)) + if (!string.IsNullOrEmpty(listings.MoviePrefix) && name.StartsWith(listings.MoviePrefix, StringComparison.OrdinalIgnoreCase)) { name = name.Substring(listings.MoviePrefix.Length).Trim(); } @@ -324,7 +324,7 @@ public override List GetRelatedUrls() var list = base.GetRelatedUrls(); var imdbId = this.GetProviderId(MetadataProviders.Imdb); - if (!string.IsNullOrWhiteSpace(imdbId)) + if (!string.IsNullOrEmpty(imdbId)) { if (IsMovie) { diff --git a/MediaBrowser.Controller/LiveTv/LiveTvVideoRecording.cs b/MediaBrowser.Controller/LiveTv/LiveTvVideoRecording.cs index ce67f07a8d..43a3fa356c 100644 --- a/MediaBrowser.Controller/LiveTv/LiveTvVideoRecording.cs +++ b/MediaBrowser.Controller/LiveTv/LiveTvVideoRecording.cs @@ -144,7 +144,7 @@ public override List GetMediaSources(bool enablePathSubstitutio foreach (var mediaSource in list) { - if (string.IsNullOrWhiteSpace(mediaSource.Path)) + if (string.IsNullOrEmpty(mediaSource.Path)) { mediaSource.Type = MediaSourceType.Placeholder; } diff --git a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs index 1625329b4e..da36bf0d25 100644 --- a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs +++ b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs @@ -64,7 +64,7 @@ public string GetH264Encoder(EncodingJobInfo state, EncodingOptions encodingOpti { return GetAvailableEncoder("h264_v4l2m2m", defaultEncoder); } - if (string.Equals(hwType, "vaapi", StringComparison.OrdinalIgnoreCase) && !string.IsNullOrWhiteSpace(encodingOptions.VaapiDevice)) + if (string.Equals(hwType, "vaapi", StringComparison.OrdinalIgnoreCase) && !string.IsNullOrEmpty(encodingOptions.VaapiDevice)) { if (IsVaapiSupported(state)) { @@ -144,7 +144,7 @@ public string GetUserAgentParam(EncodingJobInfo state) state.RemoteHttpHeaders.TryGetValue("User-Agent", out useragent); - if (!string.IsNullOrWhiteSpace(useragent)) + if (!string.IsNullOrEmpty(useragent)) { return "-user_agent \"" + useragent + "\""; } @@ -154,7 +154,7 @@ public string GetUserAgentParam(EncodingJobInfo state) public string GetInputFormat(string container) { - if (string.IsNullOrWhiteSpace(container)) + if (string.IsNullOrEmpty(container)) { return null; } @@ -606,7 +606,7 @@ public string GetVideoQualityParam(EncodingJobInfo state, string videoEncoder, E if (string.Equals(videoEncoder, "libx264", StringComparison.OrdinalIgnoreCase)) { - if (!string.IsNullOrWhiteSpace(encodingOptions.H264Preset)) + if (!string.IsNullOrEmpty(encodingOptions.H264Preset)) { param += "-preset " + encodingOptions.H264Preset; } @@ -836,7 +836,7 @@ public bool CanStreamCopyVideo(EncodingJobInfo state, MediaStream videoStream) } // Source and target codecs must match - if (string.IsNullOrWhiteSpace(videoStream.Codec) || !state.SupportedVideoCodecs.Contains(videoStream.Codec, StringComparer.OrdinalIgnoreCase)) + if (string.IsNullOrEmpty(videoStream.Codec) || !state.SupportedVideoCodecs.Contains(videoStream.Codec, StringComparer.OrdinalIgnoreCase)) { return false; } @@ -846,14 +846,14 @@ public bool CanStreamCopyVideo(EncodingJobInfo state, MediaStream videoStream) // If client is requesting a specific video profile, it must match the source if (requestedProfiles.Length > 0) { - if (string.IsNullOrWhiteSpace(videoStream.Profile)) + if (string.IsNullOrEmpty(videoStream.Profile)) { //return false; } var requestedProfile = requestedProfiles[0]; // strip spaces because they may be stripped out on the query string as well - if (!string.IsNullOrWhiteSpace(videoStream.Profile) && !requestedProfiles.Contains(videoStream.Profile.Replace(" ", ""), StringComparer.OrdinalIgnoreCase)) + if (!string.IsNullOrEmpty(videoStream.Profile) && !requestedProfiles.Contains(videoStream.Profile.Replace(" ", ""), StringComparer.OrdinalIgnoreCase)) { var currentScore = GetVideoProfileScore(videoStream.Profile); var requestedScore = GetVideoProfileScore(requestedProfile); @@ -1634,12 +1634,12 @@ public string GetInputModifier(EncodingJobInfo state, EncodingOptions encodingOp analyzeDurationArgument = GetAnalyzeDurationArgument(numInputFiles); } - if (!string.IsNullOrWhiteSpace(probeSizeArgument)) + if (!string.IsNullOrEmpty(probeSizeArgument)) { inputModifier += " " + probeSizeArgument; } - if (!string.IsNullOrWhiteSpace(analyzeDurationArgument)) + if (!string.IsNullOrEmpty(analyzeDurationArgument)) { inputModifier += " " + analyzeDurationArgument; } @@ -1648,7 +1648,7 @@ public string GetInputModifier(EncodingJobInfo state, EncodingOptions encodingOp var userAgentParam = GetUserAgentParam(state); - if (!string.IsNullOrWhiteSpace(userAgentParam)) + if (!string.IsNullOrEmpty(userAgentParam)) { inputModifier += " " + userAgentParam; } @@ -1706,7 +1706,7 @@ public string GetInputModifier(EncodingJobInfo state, EncodingOptions encodingOp } var videoDecoder = GetVideoDecoder(state, encodingOptions); - if (!string.IsNullOrWhiteSpace(videoDecoder)) + if (!string.IsNullOrEmpty(videoDecoder)) { inputModifier += " " + videoDecoder; } @@ -1723,10 +1723,10 @@ public string GetInputModifier(EncodingJobInfo state, EncodingOptions encodingOp inputModifier += " -noaccurate_seek"; } - if (!string.IsNullOrWhiteSpace(state.InputContainer) && state.VideoType == VideoType.VideoFile && string.IsNullOrWhiteSpace(encodingOptions.HardwareAccelerationType)) + if (!string.IsNullOrEmpty(state.InputContainer) && state.VideoType == VideoType.VideoFile && string.IsNullOrEmpty(encodingOptions.HardwareAccelerationType)) { var inputFormat = GetInputFormat(state.InputContainer); - if (!string.IsNullOrWhiteSpace(inputFormat)) + if (!string.IsNullOrEmpty(inputFormat)) { inputModifier += " -f " + inputFormat; } @@ -1758,7 +1758,7 @@ public void AttachMediaSourceInfo(EncodingJobInfo state, var path = mediaSource.Path; var protocol = mediaSource.Protocol; - if (!string.IsNullOrWhiteSpace(mediaSource.EncoderPath) && mediaSource.EncoderProtocol.HasValue) + if (!string.IsNullOrEmpty(mediaSource.EncoderPath) && mediaSource.EncoderProtocol.HasValue) { path = mediaSource.EncoderPath; protocol = mediaSource.EncoderProtocol.Value; @@ -1829,7 +1829,7 @@ public void AttachMediaSourceInfo(EncodingJobInfo state, if (string.IsNullOrEmpty(videoRequest.VideoCodec)) { - if (string.IsNullOrWhiteSpace(requestedUrl)) + if (string.IsNullOrEmpty(requestedUrl)) { requestedUrl = "test." + videoRequest.OutputContainer; } @@ -1898,8 +1898,8 @@ public string GetVideoDecoder(VideoType videoType, MediaStream videoStream, Enco } if (videoStream != null && - !string.IsNullOrWhiteSpace(videoStream.Codec) && - !string.IsNullOrWhiteSpace(encodingOptions.HardwareAccelerationType)) + !string.IsNullOrEmpty(videoStream.Codec) && + !string.IsNullOrEmpty(encodingOptions.HardwareAccelerationType)) { if (string.Equals(encodingOptions.HardwareAccelerationType, "qsv", StringComparison.OrdinalIgnoreCase)) { @@ -2013,7 +2013,7 @@ public string GetSubtitleEmbedArguments(EncodingJobInfo state) var format = state.SupportedSubtitleCodecs.FirstOrDefault(); string codec; - if (string.IsNullOrWhiteSpace(format) || string.Equals(format, state.SubtitleStream.Codec, StringComparison.OrdinalIgnoreCase)) + if (string.IsNullOrEmpty(format) || string.Equals(format, state.SubtitleStream.Codec, StringComparison.OrdinalIgnoreCase)) { codec = "copy"; } @@ -2235,7 +2235,7 @@ public string GetProgressiveAudioFullCommandLine(EncodingJobInfo state, Encoding var metadata = string.Empty; var vn = string.Empty; - var hasArt = !string.IsNullOrWhiteSpace(state.AlbumCoverPath); + var hasArt = !string.IsNullOrEmpty(state.AlbumCoverPath); hasArt = false; if (hasArt) diff --git a/MediaBrowser.Controller/MediaEncoding/EncodingJobInfo.cs b/MediaBrowser.Controller/MediaEncoding/EncodingJobInfo.cs index ad131064c3..0f17933f68 100644 --- a/MediaBrowser.Controller/MediaEncoding/EncodingJobInfo.cs +++ b/MediaBrowser.Controller/MediaEncoding/EncodingJobInfo.cs @@ -51,7 +51,7 @@ public TranscodeReason[] TranscodeReasons { _transcodeReasons = (BaseRequest.TranscodeReasons ?? string.Empty) .Split(',') - .Where(i => !string.IsNullOrWhiteSpace(i)) + .Where(i => !string.IsNullOrEmpty(i)) .Select(v => (TranscodeReason)Enum.Parse(typeof(TranscodeReason), v, true)) .ToArray(); } @@ -172,7 +172,7 @@ public bool DeInterlace(string videoCodec, bool forceDeinterlaceIfSourceIsInterl return true; } - if (!string.IsNullOrWhiteSpace(videoCodec)) + if (!string.IsNullOrEmpty(videoCodec)) { if (string.Equals(BaseRequest.GetOption(videoCodec, "deinterlace"), "true", StringComparison.OrdinalIgnoreCase)) { @@ -193,16 +193,16 @@ public bool DeInterlace(string videoCodec, bool forceDeinterlaceIfSourceIsInterl public string[] GetRequestedProfiles(string codec) { - if (!string.IsNullOrWhiteSpace(BaseRequest.Profile)) + if (!string.IsNullOrEmpty(BaseRequest.Profile)) { return BaseRequest.Profile.Split(new[] { '|', ',' }, StringSplitOptions.RemoveEmptyEntries); } - if (!string.IsNullOrWhiteSpace(codec)) + if (!string.IsNullOrEmpty(codec)) { var profile = BaseRequest.GetOption(codec, "profile"); - if (!string.IsNullOrWhiteSpace(profile)) + if (!string.IsNullOrEmpty(profile)) { return profile.Split(new[] { '|', ',' }, StringSplitOptions.RemoveEmptyEntries); } @@ -213,12 +213,12 @@ public string[] GetRequestedProfiles(string codec) public string GetRequestedLevel(string codec) { - if (!string.IsNullOrWhiteSpace(BaseRequest.Level)) + if (!string.IsNullOrEmpty(BaseRequest.Level)) { return BaseRequest.Level; } - if (!string.IsNullOrWhiteSpace(codec)) + if (!string.IsNullOrEmpty(codec)) { return BaseRequest.GetOption(codec, "level"); } @@ -228,16 +228,16 @@ public string GetRequestedLevel(string codec) public int? GetRequestedMaxRefFrames(string codec) { - if (!string.IsNullOrWhiteSpace(BaseRequest.Level)) + if (!string.IsNullOrEmpty(BaseRequest.Level)) { return BaseRequest.MaxRefFrames; } - if (!string.IsNullOrWhiteSpace(codec)) + if (!string.IsNullOrEmpty(codec)) { var value = BaseRequest.GetOption(codec, "maxrefframes"); int result; - if (!string.IsNullOrWhiteSpace(value) && int.TryParse(value, NumberStyles.Any, CultureInfo.InvariantCulture, out result)) + if (!string.IsNullOrEmpty(value) && int.TryParse(value, NumberStyles.Any, CultureInfo.InvariantCulture, out result)) { return result; } @@ -404,14 +404,14 @@ public double? TargetVideoLevel { get { - if (BaseRequest.Static) + if (BaseRequest.Static || string.Equals(OutputVideoCodec, "copy", StringComparison.OrdinalIgnoreCase)) { return VideoStream == null ? null : VideoStream.Level; } var level = GetRequestedLevel(ActualOutputVideoCodec); double result; - if (!string.IsNullOrWhiteSpace(level) && double.TryParse(level, NumberStyles.Any, CultureInfo.InvariantCulture, out result)) + if (!string.IsNullOrEmpty(level) && double.TryParse(level, NumberStyles.Any, CultureInfo.InvariantCulture, out result)) { return result; } @@ -427,8 +427,12 @@ public int? TargetVideoBitDepth { get { - var stream = VideoStream; - return stream == null || !BaseRequest.Static ? null : stream.BitDepth; + if (BaseRequest.Static || string.Equals(OutputVideoCodec, "copy", StringComparison.OrdinalIgnoreCase)) + { + return VideoStream == null ? null : VideoStream.BitDepth; + } + + return null; } } @@ -440,7 +444,7 @@ public int? TargetRefFrames { get { - if (BaseRequest.Static) + if (BaseRequest.Static || string.Equals(OutputVideoCodec, "copy", StringComparison.OrdinalIgnoreCase)) { return VideoStream == null ? null : VideoStream.RefFrames; } @@ -456,12 +460,12 @@ public float? TargetFramerate { get { - var stream = VideoStream; - var requestedFramerate = BaseRequest.MaxFramerate ?? BaseRequest.Framerate; + if (BaseRequest.Static || string.Equals(OutputVideoCodec, "copy", StringComparison.OrdinalIgnoreCase)) + { + return VideoStream == null ? null : (VideoStream.AverageFrameRate ?? VideoStream.RealFrameRate); + } - return requestedFramerate.HasValue && !BaseRequest.Static - ? requestedFramerate - : stream == null ? null : stream.AverageFrameRate ?? stream.RealFrameRate; + return BaseRequest.MaxFramerate ?? BaseRequest.Framerate; } } @@ -486,10 +490,12 @@ public int? TargetPacketLength { get { - var stream = VideoStream; - return !BaseRequest.Static - ? null - : stream == null ? null : stream.PacketLength; + if (BaseRequest.Static || string.Equals(OutputVideoCodec, "copy", StringComparison.OrdinalIgnoreCase)) + { + return VideoStream == null ? null : VideoStream.PacketLength; + } + + return null; } } @@ -500,13 +506,13 @@ public string TargetVideoProfile { get { - if (BaseRequest.Static) + if (BaseRequest.Static || string.Equals(OutputVideoCodec, "copy", StringComparison.OrdinalIgnoreCase)) { return VideoStream == null ? null : VideoStream.Profile; } var requestedProfile = GetRequestedProfiles(ActualOutputVideoCodec).FirstOrDefault(); - if (!string.IsNullOrWhiteSpace(requestedProfile)) + if (!string.IsNullOrEmpty(requestedProfile)) { return requestedProfile; } @@ -515,14 +521,29 @@ public string TargetVideoProfile } } + public string TargetAudioProfile + { + get + { + if (BaseRequest.Static || string.Equals(OutputAudioCodec, "copy", StringComparison.OrdinalIgnoreCase)) + { + return AudioStream == null ? null : AudioStream.Profile; + } + + return null; + } + } + public string TargetVideoCodecTag { get { - var stream = VideoStream; - return !BaseRequest.Static - ? null - : stream == null ? null : stream.CodecTag; + if (BaseRequest.Static || string.Equals(OutputVideoCodec, "copy", StringComparison.OrdinalIgnoreCase)) + { + return VideoStream == null ? null : VideoStream.CodecTag; + } + + return null; } } @@ -530,7 +551,7 @@ public bool? IsTargetAnamorphic { get { - if (BaseRequest.Static) + if (BaseRequest.Static || string.Equals(OutputVideoCodec, "copy", StringComparison.OrdinalIgnoreCase)) { return VideoStream == null ? null : VideoStream.IsAnamorphic; } @@ -565,7 +586,7 @@ public bool? IsTargetInterlaced { get { - if (BaseRequest.Static) + if (BaseRequest.Static || string.Equals(OutputVideoCodec, "copy", StringComparison.OrdinalIgnoreCase)) { return VideoStream == null ? (bool?)null : VideoStream.IsInterlaced; } @@ -583,7 +604,7 @@ public bool? IsTargetAVC { get { - if (BaseRequest.Static) + if (BaseRequest.Static || string.Equals(OutputVideoCodec, "copy", StringComparison.OrdinalIgnoreCase)) { return VideoStream == null ? null : VideoStream.IsAVC; } diff --git a/MediaBrowser.Controller/Net/IHttpResultFactory.cs b/MediaBrowser.Controller/Net/IHttpResultFactory.cs index b885246919..5dae85c7fb 100644 --- a/MediaBrowser.Controller/Net/IHttpResultFactory.cs +++ b/MediaBrowser.Controller/Net/IHttpResultFactory.cs @@ -22,6 +22,8 @@ public interface IHttpResultFactory /// System.Object. object GetResult(object content, string contentType, IDictionary responseHeaders = null); + object GetResult(IRequest requestContext, object content, string contentType, IDictionary responseHeaders = null); + object GetRedirectResult(string url); /// diff --git a/MediaBrowser.Controller/Net/LoggedAttribute.cs b/MediaBrowser.Controller/Net/LoggedAttribute.cs index eb57392e2e..3d434a1cf9 100644 --- a/MediaBrowser.Controller/Net/LoggedAttribute.cs +++ b/MediaBrowser.Controller/Net/LoggedAttribute.cs @@ -37,7 +37,7 @@ public void Filter(IRequest request, IResponse response, object requestDto) { User user = null; - if (!string.IsNullOrWhiteSpace(auth.UserId)) + if (!string.IsNullOrEmpty(auth.UserId)) { var userId = auth.UserId; diff --git a/MediaBrowser.Controller/Providers/DirectoryService.cs b/MediaBrowser.Controller/Providers/DirectoryService.cs index d673198fdc..205346d5c6 100644 --- a/MediaBrowser.Controller/Providers/DirectoryService.cs +++ b/MediaBrowser.Controller/Providers/DirectoryService.cs @@ -33,11 +33,6 @@ public DirectoryService(IFileSystem fileSystem) public FileSystemMetadata[] GetFileSystemEntries(string path) { - if (string.IsNullOrWhiteSpace(path)) - { - throw new ArgumentNullException("path"); - } - FileSystemMetadata[] entries; if (!_cache.TryGetValue(path, out entries)) diff --git a/MediaBrowser.Controller/Session/ISessionController.cs b/MediaBrowser.Controller/Session/ISessionController.cs index 0d8c207b61..87e25bd12b 100644 --- a/MediaBrowser.Controller/Session/ISessionController.cs +++ b/MediaBrowser.Controller/Session/ISessionController.cs @@ -43,42 +43,6 @@ public interface ISessionController /// The cancellation token. /// Task. Task SendGeneralCommand(GeneralCommand command, CancellationToken cancellationToken); - - /// - /// Sends the library update info. - /// - /// The info. - /// The cancellation token. - /// Task. - Task SendLibraryUpdateInfo(LibraryUpdateInfo info, CancellationToken cancellationToken); - - /// - /// Sends the restart required message. - /// - Task SendRestartRequiredNotification(CancellationToken cancellationToken); - - /// - /// Sends the user data change info. - /// - /// The info. - /// The cancellation token. - /// Task. - Task SendUserDataChangeInfo(UserDataChangeInfo info, CancellationToken cancellationToken); - - /// - /// Sends the server shutdown notification. - /// - /// The cancellation token. - /// Task. - Task SendServerShutdownNotification(CancellationToken cancellationToken); - - /// - /// Sends the session ended notification. - /// - /// The session information. - /// The cancellation token. - /// Task. - Task SendSessionEndedNotification(SessionInfoDto sessionInfo, CancellationToken cancellationToken); /// /// Sends the playback start notification. @@ -95,13 +59,6 @@ public interface ISessionController /// The cancellation token. /// Task. Task SendPlaybackStoppedNotification(SessionInfoDto sessionInfo, CancellationToken cancellationToken); - - /// - /// Sends the server restart notification. - /// - /// The cancellation token. - /// Task. - Task SendServerRestartNotification(CancellationToken cancellationToken); /// /// Sends the message. diff --git a/MediaBrowser.Controller/Session/ISessionManager.cs b/MediaBrowser.Controller/Session/ISessionManager.cs index d256ca05aa..0a3f1ba717 100644 --- a/MediaBrowser.Controller/Session/ISessionManager.cs +++ b/MediaBrowser.Controller/Session/ISessionManager.cs @@ -190,6 +190,8 @@ public interface ISessionManager /// Task. Task SendMessageToUserSessions(List userIds, string name, T data, CancellationToken cancellationToken); + Task SendMessageToUserSessions(List userIds, string name, Func dataFn, CancellationToken cancellationToken); + /// /// Sends the message to user device sessions. /// @@ -199,8 +201,7 @@ public interface ISessionManager /// The data. /// The cancellation token. /// Task. - Task SendMessageToUserDeviceSessions(string deviceId, string name, T data, - CancellationToken cancellationToken); + Task SendMessageToUserDeviceSessions(string deviceId, string name, T data, CancellationToken cancellationToken); /// /// Sends the restart required message. diff --git a/MediaBrowser.Model/Configuration/ChannelOptions.cs b/MediaBrowser.Model/Configuration/ChannelOptions.cs deleted file mode 100644 index 9bd0ef9c5c..0000000000 --- a/MediaBrowser.Model/Configuration/ChannelOptions.cs +++ /dev/null @@ -1,8 +0,0 @@ -namespace MediaBrowser.Model.Configuration -{ - public class ChannelOptions - { - public int? PreferredStreamingWidth { get; set; } - public string DownloadPath { get; set; } - } -} \ No newline at end of file diff --git a/MediaBrowser.Model/Configuration/ServerConfiguration.cs b/MediaBrowser.Model/Configuration/ServerConfiguration.cs index b0b7c23a06..c068ad3da8 100644 --- a/MediaBrowser.Model/Configuration/ServerConfiguration.cs +++ b/MediaBrowser.Model/Configuration/ServerConfiguration.cs @@ -180,7 +180,6 @@ public class ServerConfiguration : BaseApplicationConfiguration public string[] LocalNetworkSubnets { get; set; } public string[] LocalNetworkAddresses { get; set; } public string[] CodecsUsed { get; set; } - public bool EnableChannelView { get; set; } public bool EnableExternalContentInSuggestions { get; set; } public bool RequireHttps { get; set; } public bool IsBehindProxy { get; set; } diff --git a/MediaBrowser.Model/Dlna/ContainerProfile.cs b/MediaBrowser.Model/Dlna/ContainerProfile.cs index 23bbf01939..97d190a623 100644 --- a/MediaBrowser.Model/Dlna/ContainerProfile.cs +++ b/MediaBrowser.Model/Dlna/ContainerProfile.cs @@ -29,7 +29,7 @@ public string[] GetContainers() public static string[] SplitValue(string value) { - if (string.IsNullOrWhiteSpace(value)) + if (string.IsNullOrEmpty(value)) { return EmptyStringArray; } diff --git a/MediaBrowser.Model/Dlna/StreamBuilder.cs b/MediaBrowser.Model/Dlna/StreamBuilder.cs index 3c276aabd6..4fb2e50a00 100644 --- a/MediaBrowser.Model/Dlna/StreamBuilder.cs +++ b/MediaBrowser.Model/Dlna/StreamBuilder.cs @@ -248,7 +248,7 @@ private StreamInfo[] SortMediaSources(List streams, long? maxBitrate public static string NormalizeMediaSourceFormatIntoSingleContainer(string inputContainer, DeviceProfile profile, DlnaProfileType type) { - if (string.IsNullOrWhiteSpace(inputContainer)) + if (string.IsNullOrEmpty(inputContainer)) { return null; } @@ -1290,7 +1290,7 @@ public static SubtitleProfile GetSubtitleProfile(MediaSourceInfo mediaSource, Me private static bool IsSubtitleEmbedSupported(MediaStream subtitleStream, SubtitleProfile subtitleProfile, string transcodingSubProtocol, string transcodingContainer) { - if (!string.IsNullOrWhiteSpace(transcodingContainer)) + if (!string.IsNullOrEmpty(transcodingContainer)) { var normalizedContainers = ContainerProfile.SplitValue(transcodingContainer); @@ -1542,7 +1542,7 @@ private void ApplyTranscodingConditions(StreamInfo item, IEnumerable BuildParams(StreamInfo item, string accessTok { foreach (var pair in item.StreamOptions) { - if (string.IsNullOrWhiteSpace(pair.Value)) + if (string.IsNullOrEmpty(pair.Value)) { continue; } @@ -595,7 +595,7 @@ public int? TargetRefFrames var targetVideoCodecs = TargetVideoCodec; var videoCodec = targetVideoCodecs.Length == 0 ? null : targetVideoCodecs[0]; - if (!string.IsNullOrWhiteSpace(videoCodec)) + if (!string.IsNullOrEmpty(videoCodec)) { return GetTargetRefFrames(videoCodec); } @@ -632,7 +632,7 @@ public double? TargetVideoLevel var targetVideoCodecs = TargetVideoCodec; var videoCodec = targetVideoCodecs.Length == 0 ? null : targetVideoCodecs[0]; - if (!string.IsNullOrWhiteSpace(videoCodec)) + if (!string.IsNullOrEmpty(videoCodec)) { return GetTargetVideoLevel(videoCodec); } @@ -644,7 +644,7 @@ public double? TargetVideoLevel public double? GetTargetVideoLevel(string codec) { var value = GetOption(codec, "level"); - if (string.IsNullOrWhiteSpace(value)) + if (string.IsNullOrEmpty(value)) { return null; } @@ -661,7 +661,7 @@ public double? TargetVideoLevel public int? GetTargetRefFrames(string codec) { var value = GetOption(codec, "maxrefframes"); - if (string.IsNullOrWhiteSpace(value)) + if (string.IsNullOrEmpty(value)) { return null; } @@ -703,7 +703,7 @@ public string TargetVideoProfile var targetVideoCodecs = TargetVideoCodec; var videoCodec = targetVideoCodecs.Length == 0 ? null : targetVideoCodecs[0]; - if (!string.IsNullOrWhiteSpace(videoCodec)) + if (!string.IsNullOrEmpty(videoCodec)) { return GetOption(videoCodec, "profile"); } @@ -778,14 +778,14 @@ public string[] TargetAudioCodec if (IsDirectStream) { - return string.IsNullOrWhiteSpace(inputCodec) ? new string[] { } : new[] { inputCodec }; + return string.IsNullOrEmpty(inputCodec) ? new string[] { } : new[] { inputCodec }; } foreach (string codec in AudioCodecs) { if (StringHelper.EqualsIgnoreCase(codec, inputCodec)) { - return string.IsNullOrWhiteSpace(codec) ? new string[] { } : new[] { codec }; + return string.IsNullOrEmpty(codec) ? new string[] { } : new[] { codec }; } } @@ -803,14 +803,14 @@ public string[] TargetVideoCodec if (IsDirectStream) { - return string.IsNullOrWhiteSpace(inputCodec) ? new string[] { } : new[] { inputCodec }; + return string.IsNullOrEmpty(inputCodec) ? new string[] { } : new[] { inputCodec }; } foreach (string codec in VideoCodecs) { if (StringHelper.EqualsIgnoreCase(codec, inputCodec)) { - return string.IsNullOrWhiteSpace(codec) ? new string[] { } : new[] { codec }; + return string.IsNullOrEmpty(codec) ? new string[] { } : new[] { codec }; } } @@ -907,7 +907,7 @@ public bool? IsTargetInterlaced var targetVideoCodecs = TargetVideoCodec; var videoCodec = targetVideoCodecs.Length == 0 ? null : targetVideoCodecs[0]; - if (!string.IsNullOrWhiteSpace(videoCodec)) + if (!string.IsNullOrEmpty(videoCodec)) { if (string.Equals(GetOption(videoCodec, "deinterlace"), "true", StringComparison.OrdinalIgnoreCase)) { diff --git a/MediaBrowser.Model/Entities/CollectionType.cs b/MediaBrowser.Model/Entities/CollectionType.cs index b1cbb9ac39..f6c43adf3a 100644 --- a/MediaBrowser.Model/Entities/CollectionType.cs +++ b/MediaBrowser.Model/Entities/CollectionType.cs @@ -27,10 +27,6 @@ public static class CollectionType public static class SpecialFolder { - public const string LiveTvNowPlaying = "LiveTvNowPlaying"; - public const string LiveTvChannels = "LiveTvChannels"; - public const string LiveTvRecordingGroups = "LiveTvRecordingGroups"; - public const string TvShowSeries = "TvShowSeries"; public const string TvGenres = "TvGenres"; public const string TvGenre = "TvGenre"; diff --git a/MediaBrowser.Model/MediaBrowser.Model.csproj b/MediaBrowser.Model/MediaBrowser.Model.csproj index f2355ef19b..97f44b4003 100644 --- a/MediaBrowser.Model/MediaBrowser.Model.csproj +++ b/MediaBrowser.Model/MediaBrowser.Model.csproj @@ -54,7 +54,6 @@ - diff --git a/MediaBrowser.Model/Net/IAcceptSocket.cs b/MediaBrowser.Model/Net/IAcceptSocket.cs index 343e12ab62..af5a1fcfbe 100644 --- a/MediaBrowser.Model/Net/IAcceptSocket.cs +++ b/MediaBrowser.Model/Net/IAcceptSocket.cs @@ -2,18 +2,6 @@ namespace MediaBrowser.Model.Net { - public interface IAcceptSocket : IDisposable - { - bool DualMode { get; } - IpEndPointInfo LocalEndPoint { get; } - IpEndPointInfo RemoteEndPoint { get; } - void Close(); - void Shutdown(bool both); - void Listen(int backlog); - void Bind(IpEndPointInfo endpoint); - void Connect(IpEndPointInfo endPoint); - } - public class SocketCreateException : Exception { public SocketCreateException(string errorCode, Exception originalException) diff --git a/MediaBrowser.Model/Net/ISocketFactory.cs b/MediaBrowser.Model/Net/ISocketFactory.cs index bf2424660b..6a4b996007 100644 --- a/MediaBrowser.Model/Net/ISocketFactory.cs +++ b/MediaBrowser.Model/Net/ISocketFactory.cs @@ -34,8 +34,6 @@ public interface ISocketFactory /// A implementation. ISocket CreateUdpMulticastSocket(string ipAddress, int multicastTimeToLive, int localPort); - IAcceptSocket CreateSocket(IpAddressFamily family, SocketType socketType, ProtocolType protocolType, bool dualMode); - Stream CreateNetworkStream(ISocket socket, bool ownsSocket); } diff --git a/MediaBrowser.Model/Net/IpAddressInfo.cs b/MediaBrowser.Model/Net/IpAddressInfo.cs index 57a0039c43..520f8fb545 100644 --- a/MediaBrowser.Model/Net/IpAddressInfo.cs +++ b/MediaBrowser.Model/Net/IpAddressInfo.cs @@ -14,11 +14,6 @@ public class IpAddressInfo public IpAddressInfo(string address, IpAddressFamily addressFamily) { - if (string.IsNullOrWhiteSpace(address)) - { - throw new ArgumentNullException("address"); - } - Address = address; AddressFamily = addressFamily; } diff --git a/MediaBrowser.Model/Services/QueryParamCollection.cs b/MediaBrowser.Model/Services/QueryParamCollection.cs index e13e5fecac..6f8a765988 100644 --- a/MediaBrowser.Model/Services/QueryParamCollection.cs +++ b/MediaBrowser.Model/Services/QueryParamCollection.cs @@ -56,7 +56,7 @@ public virtual void Add(string key, string value) public virtual void Set(string key, string value) { - if (string.IsNullOrWhiteSpace(value)) + if (string.IsNullOrEmpty(value)) { var parameters = GetItems(key); diff --git a/MediaBrowser.Providers/Manager/MetadataService.cs b/MediaBrowser.Providers/Manager/MetadataService.cs index 3f1e58fc48..8a68b73e4e 100644 --- a/MediaBrowser.Providers/Manager/MetadataService.cs +++ b/MediaBrowser.Providers/Manager/MetadataService.cs @@ -27,7 +27,6 @@ public abstract class MetadataService : IMetadataService protected readonly IFileSystem FileSystem; protected readonly IUserDataManager UserDataManager; protected readonly ILibraryManager LibraryManager; - private readonly SubtitleResolver _subtitleResolver; protected MetadataService(IServerConfigurationManager serverConfigurationManager, ILogger logger, IProviderManager providerManager, IFileSystem fileSystem, IUserDataManager userDataManager, ILibraryManager libraryManager) { @@ -37,8 +36,6 @@ protected MetadataService(IServerConfigurationManager serverConfigurationManager FileSystem = fileSystem; UserDataManager = userDataManager; LibraryManager = libraryManager; - - _subtitleResolver = new SubtitleResolver(BaseItem.LocalizationManager, fileSystem); } private FileSystemMetadata TryGetFile(string path, IDirectoryService directoryService) @@ -69,35 +66,6 @@ public async Task RefreshMetadata(BaseItem item, MetadataRefresh requiresRefresh = true; } - DateTime? newDateModified = null; - if (item.LocationType == LocationType.FileSystem) - { - var file = TryGetFile(item.Path, refreshOptions.DirectoryService); - if (file != null) - { - newDateModified = file.LastWriteTimeUtc; - if (item.EnableRefreshOnDateModifiedChange) - { - if (newDateModified != item.DateModified) - { - Logger.Debug("Date modified for {0}. Old date {1} new date {2} Id {3}", item.Path, item.DateModified, newDateModified, item.Id); - requiresRefresh = true; - } - } - - if (!requiresRefresh && item.SupportsLocalMetadata) - { - var video = item as Video; - - if (video != null && !video.IsPlaceHolder) - { - requiresRefresh = !video.SubtitleFiles - .SequenceEqual(_subtitleResolver.GetExternalSubtitleFiles(video, refreshOptions.DirectoryService, false), StringComparer.Ordinal); - } - } - } - } - if (!requiresRefresh && refreshOptions.MetadataRefreshMode != MetadataRefreshMode.None) { // TODO: If this returns true, should we instead just change metadata refresh mode to Full? @@ -189,14 +157,18 @@ public async Task RefreshMetadata(BaseItem item, MetadataRefresh var beforeSaveResult = BeforeSave(itemOfType, isFirstRefresh || refreshOptions.ReplaceAllMetadata || refreshOptions.MetadataRefreshMode == MetadataRefreshMode.FullRefresh || requiresRefresh || refreshOptions.ForceSave, updateType); updateType = updateType | beforeSaveResult; - if (newDateModified.HasValue) - { - item.DateModified = newDateModified.Value; - } - // Save if changes were made, or it's never been saved before if (refreshOptions.ForceSave || updateType > ItemUpdateType.None || isFirstRefresh || refreshOptions.ReplaceAllMetadata || requiresRefresh) { + if (item.LocationType == LocationType.FileSystem) + { + var file = TryGetFile(item.Path, refreshOptions.DirectoryService); + if (file != null) + { + item.DateModified = file.LastWriteTimeUtc; + } + } + // If any of these properties are set then make sure the updateType is not None, just to force everything to save if (refreshOptions.ForceSave || refreshOptions.ReplaceAllMetadata) { diff --git a/MediaBrowser.Providers/Manager/ProviderUtils.cs b/MediaBrowser.Providers/Manager/ProviderUtils.cs index b727e13546..d12a92b6a7 100644 --- a/MediaBrowser.Providers/Manager/ProviderUtils.cs +++ b/MediaBrowser.Providers/Manager/ProviderUtils.cs @@ -189,16 +189,13 @@ public static void MergeBaseItemData(MetadataResult sourceResult, MergeVideoInfo(source, target, lockedFields, replaceData); MergeDisplayOrder(source, target, lockedFields, replaceData); - //if (!lockedFields.Contains(MetadataFields.SortName)) + if (replaceData || string.IsNullOrEmpty(target.ForcedSortName)) { - if (replaceData || string.IsNullOrEmpty(target.ForcedSortName)) - { - var forcedSortName = source.ForcedSortName; + var forcedSortName = source.ForcedSortName; - if (!string.IsNullOrWhiteSpace(forcedSortName)) - { - target.ForcedSortName = forcedSortName; - } + if (!string.IsNullOrWhiteSpace(forcedSortName)) + { + target.ForcedSortName = forcedSortName; } } diff --git a/MediaBrowser.Providers/MediaInfo/FFProbeProvider.cs b/MediaBrowser.Providers/MediaInfo/FFProbeProvider.cs index 6a2677b433..6e3f0bd88f 100644 --- a/MediaBrowser.Providers/MediaInfo/FFProbeProvider.cs +++ b/MediaBrowser.Providers/MediaInfo/FFProbeProvider.cs @@ -36,7 +36,8 @@ public class FFProbeProvider : ICustomMetadataProvider, ICustomMetadataProvider, IHasOrder, IForcedProvider, - IPreRefreshProvider + IPreRefreshProvider, + IHasItemChangeMonitor { private readonly ILogger _logger; private readonly IIsoManager _isoManager; @@ -58,6 +59,33 @@ public string Name get { return "ffprobe"; } } + public bool HasChanged(BaseItem item, IDirectoryService directoryService) + { + var video = item as Video; + if (video == null || video.VideoType == VideoType.VideoFile || video.VideoType == VideoType.Iso) + { + if (!string.IsNullOrWhiteSpace(item.Path) && item.LocationType == LocationType.FileSystem) + { + var file = directoryService.GetFile(item.Path); + if (file != null && file.LastWriteTimeUtc != item.DateModified) + { + return true; + } + } + } + + if (item.SupportsLocalMetadata) + { + if (video != null && !video.IsPlaceHolder) + { + return !video.SubtitleFiles + .SequenceEqual(_subtitleResolver.GetExternalSubtitleFiles(video, directoryService, false), StringComparer.Ordinal); + } + } + + return false; + } + public Task FetchAsync(Episode item, MetadataRefreshOptions options, CancellationToken cancellationToken) { return FetchVideoInfo(item, options, cancellationToken); @@ -108,6 +136,7 @@ public Task FetchAsync(AudioBook item, MetadataRefreshOptions op return FetchAudioInfo(item, cancellationToken); } + private SubtitleResolver _subtitleResolver; public FFProbeProvider(ILogger logger, IIsoManager isoManager, IMediaEncoder mediaEncoder, IItemRepository itemRepo, IBlurayExaminer blurayExaminer, ILocalizationManager localization, IApplicationPaths appPaths, IJsonSerializer json, IEncodingManager encodingManager, IFileSystem fileSystem, IServerConfigurationManager config, ISubtitleManager subtitleManager, IChapterManager chapterManager, ILibraryManager libraryManager) { _logger = logger; @@ -124,6 +153,8 @@ public FFProbeProvider(ILogger logger, IIsoManager isoManager, IMediaEncoder med _subtitleManager = subtitleManager; _chapterManager = chapterManager; _libraryManager = libraryManager; + + _subtitleResolver = new SubtitleResolver(BaseItem.LocalizationManager, fileSystem); } private readonly Task _cachedTask = Task.FromResult(ItemUpdateType.None); @@ -160,15 +191,21 @@ public Task FetchVideoInfo(T item, MetadataRefreshOptions opt return prober.ProbeVideo(item, options, cancellationToken); } - private void FetchShortcutInfo(Video video) + private string NormalizeStrmLine(string line) { - video.ShortcutPath = _fileSystem.ReadAllText(video.Path) - .Replace("\t", string.Empty) + return line.Replace("\t", string.Empty) .Replace("\r", string.Empty) .Replace("\n", string.Empty) .Trim(); } + private void FetchShortcutInfo(Video video) + { + video.ShortcutPath = _fileSystem.ReadAllLines(video.Path) + .Select(NormalizeStrmLine) + .FirstOrDefault(i => !string.IsNullOrWhiteSpace(i) && !i.StartsWith("#", StringComparison.OrdinalIgnoreCase)); + } + public Task FetchAudioInfo(T item, CancellationToken cancellationToken) where T : Audio { diff --git a/MediaBrowser.Providers/MediaInfo/SubtitleResolver.cs b/MediaBrowser.Providers/MediaInfo/SubtitleResolver.cs index 4e264bd223..8673853fd6 100644 --- a/MediaBrowser.Providers/MediaInfo/SubtitleResolver.cs +++ b/MediaBrowser.Providers/MediaInfo/SubtitleResolver.cs @@ -131,6 +131,7 @@ private void GetExternalSubtitleStreams(List streams, string folder var language = fileNameWithoutExtension .Replace(".forced", string.Empty, StringComparison.OrdinalIgnoreCase) .Replace(".foreign", string.Empty, StringComparison.OrdinalIgnoreCase) + .Replace(".default", string.Empty, StringComparison.OrdinalIgnoreCase) .Split('.') .LastOrDefault(); diff --git a/RSSDP/SsdpCommunicationsServer.cs b/RSSDP/SsdpCommunicationsServer.cs index dc5b21b9b9..574cf36f0a 100644 --- a/RSSDP/SsdpCommunicationsServer.cs +++ b/RSSDP/SsdpCommunicationsServer.cs @@ -286,7 +286,7 @@ public void StopListeningForResponses() foreach (var socket in sockets) { - _logger.Info("{0} disposing sendSocket", GetType().Name); + _logger.Info("{0} disposing sendSocket from {1}", GetType().Name, socket.LocalIPAddress); socket.Dispose(); } } diff --git a/ThirdParty/emby/Emby.Server.CinemaMode.dll b/ThirdParty/emby/Emby.Server.CinemaMode.dll index 025db31efe..524e4060e5 100644 Binary files a/ThirdParty/emby/Emby.Server.CinemaMode.dll and b/ThirdParty/emby/Emby.Server.CinemaMode.dll differ diff --git a/ThirdParty/emby/Emby.Server.Connect.dll b/ThirdParty/emby/Emby.Server.Connect.dll index eae200ab99..a1119c31d0 100644 Binary files a/ThirdParty/emby/Emby.Server.Connect.dll and b/ThirdParty/emby/Emby.Server.Connect.dll differ diff --git a/ThirdParty/emby/Emby.Server.MediaEncoding.dll b/ThirdParty/emby/Emby.Server.MediaEncoding.dll index 65038881d4..ad0aad662c 100644 Binary files a/ThirdParty/emby/Emby.Server.MediaEncoding.dll and b/ThirdParty/emby/Emby.Server.MediaEncoding.dll differ diff --git a/ThirdParty/emby/Emby.Server.Sync.dll b/ThirdParty/emby/Emby.Server.Sync.dll index 562b913b25..a99de39df0 100644 Binary files a/ThirdParty/emby/Emby.Server.Sync.dll and b/ThirdParty/emby/Emby.Server.Sync.dll differ