From 47d7eaeedbb1675981a6c2f780e13fd44133cba3 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Mon, 20 Nov 2017 15:08:20 -0500 Subject: fixes #1225 - Emby creates bogus seasons from subfolderss --- .../Library/Resolvers/TV/SeasonResolver.cs | 27 ++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) (limited to 'Emby.Server.Implementations/Library') diff --git a/Emby.Server.Implementations/Library/Resolvers/TV/SeasonResolver.cs b/Emby.Server.Implementations/Library/Resolvers/TV/SeasonResolver.cs index a0ff294829..3bad69b562 100644 --- a/Emby.Server.Implementations/Library/Resolvers/TV/SeasonResolver.cs +++ b/Emby.Server.Implementations/Library/Resolvers/TV/SeasonResolver.cs @@ -5,6 +5,7 @@ using MediaBrowser.Controller.Library; using MediaBrowser.Model.Globalization; using Emby.Naming.Common; using Emby.Naming.TV; +using MediaBrowser.Model.Logging; namespace Emby.Server.Implementations.Library.Resolvers.TV { @@ -21,16 +22,18 @@ namespace Emby.Server.Implementations.Library.Resolvers.TV private readonly ILibraryManager _libraryManager; private static readonly CultureInfo UsCulture = new CultureInfo("en-US"); private readonly ILocalizationManager _localization; + private readonly ILogger _logger; /// /// Initializes a new instance of the class. /// /// The config. - public SeasonResolver(IServerConfigurationManager config, ILibraryManager libraryManager, ILocalizationManager localization) + public SeasonResolver(IServerConfigurationManager config, ILibraryManager libraryManager, ILocalizationManager localization, ILogger logger) { _config = config; _libraryManager = libraryManager; _localization = localization; + _logger = logger; } /// @@ -45,20 +48,40 @@ namespace Emby.Server.Implementations.Library.Resolvers.TV var namingOptions = ((LibraryManager)_libraryManager).GetNamingOptions(); var series = ((Series)args.Parent); + var path = args.Path; + var season = new Season { - IndexNumber = new SeasonPathParser(namingOptions, new RegexProvider()).Parse(args.Path, true, true).SeasonNumber, + IndexNumber = new SeasonPathParser(namingOptions, new RegexProvider()).Parse(path, true, true).SeasonNumber, SeriesId = series.Id, SeriesName = series.Name }; if (season.IndexNumber.HasValue) { + var resolver = new Emby.Naming.TV.EpisodeResolver(namingOptions); + + var episodeInfo = resolver.Resolve(path, true); + + if (episodeInfo != null) + { + if (episodeInfo.EpisodeNumber.HasValue && episodeInfo.SeasonNumber.HasValue) + { + _logger.Info("Found folder underneath series with episode number: {0}. Season {1}. Episode {2}", + path, + episodeInfo.SeasonNumber.Value, + episodeInfo.EpisodeNumber.Value); + + return null; + } + } + var seasonNumber = season.IndexNumber.Value; season.Name = seasonNumber == 0 ? args.LibraryOptions.SeasonZeroDisplayName : string.Format(_localization.GetLocalizedString("NameSeasonNumber"), seasonNumber.ToString(UsCulture), args.GetLibraryOptions().PreferredMetadataLanguage); + } return season; -- cgit v1.2.3 From 77695f8abed3156de04c6bb2496c14a2ab3d90a8 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Tue, 21 Nov 2017 17:14:56 -0500 Subject: 3.2.40.1 --- Emby.Dlna/PlayTo/PlayToController.cs | 6 +++ Emby.Drawing.Skia/Emby.Drawing.Skia.csproj | 3 -- Emby.Drawing.Skia/PlayedIndicatorDrawer.cs | 48 +++++----------------- Emby.Drawing.Skia/UnplayedCountIndicator.cs | 2 +- Emby.Server.Implementations/ApplicationHost.cs | 9 +++- .../Browser/BrowserLauncher.cs | 2 +- .../EntryPoints/StartupWizard.cs | 25 +++++------ Emby.Server.Implementations/Library/UserManager.cs | 9 ++-- .../LiveTv/TunerHosts/M3UTunerHost.cs | 5 ++- .../LiveTv/TunerHosts/SharedHttpStream.cs | 22 +++++++--- .../Session/HttpSessionController.cs | 4 ++ .../Session/SessionManager.cs | 2 +- MediaBrowser.Api/UserService.cs | 2 +- MediaBrowser.Controller/Library/IUserManager.cs | 2 +- MediaBrowser.Model/Session/PlayRequest.cs | 1 + SharedVersion.cs | 2 +- 16 files changed, 72 insertions(+), 72 deletions(-) (limited to 'Emby.Server.Implementations/Library') diff --git a/Emby.Dlna/PlayTo/PlayToController.cs b/Emby.Dlna/PlayTo/PlayToController.cs index bd0a9e1f42..9b2c703940 100644 --- a/Emby.Dlna/PlayTo/PlayToController.cs +++ b/Emby.Dlna/PlayTo/PlayToController.cs @@ -321,6 +321,12 @@ namespace Emby.Dlna.PlayTo AddItemFromId(Guid.Parse(id), items); } + var startIndex = command.StartIndex ?? 0; + if (startIndex > 0) + { + items = items.Skip(startIndex).ToList(); + } + var playlist = new List(); var isFirst = true; diff --git a/Emby.Drawing.Skia/Emby.Drawing.Skia.csproj b/Emby.Drawing.Skia/Emby.Drawing.Skia.csproj index f2b32d52cb..2b61561cbc 100644 --- a/Emby.Drawing.Skia/Emby.Drawing.Skia.csproj +++ b/Emby.Drawing.Skia/Emby.Drawing.Skia.csproj @@ -59,9 +59,6 @@ - - - ..\packages\SkiaSharp.1.58.1\lib\portable-net45+win8+wpa81+wp8\SkiaSharp.dll diff --git a/Emby.Drawing.Skia/PlayedIndicatorDrawer.cs b/Emby.Drawing.Skia/PlayedIndicatorDrawer.cs index 48f2da62bc..2417043d60 100644 --- a/Emby.Drawing.Skia/PlayedIndicatorDrawer.cs +++ b/Emby.Drawing.Skia/PlayedIndicatorDrawer.cs @@ -15,7 +15,6 @@ namespace Emby.Drawing.Skia { public class PlayedIndicatorDrawer { - private const int FontSize = 42; private const int OffsetFromTopRightCorner = 38; private readonly IApplicationPaths _appPaths; @@ -44,48 +43,23 @@ namespace Emby.Drawing.Skia { paint.Color = new SKColor(255, 255, 255, 255); paint.Style = SKPaintStyle.Fill; - paint.Typeface = SKTypeface.FromFile(await DownloadFont("webdings.ttf", "https://github.com/MediaBrowser/Emby.Resources/raw/master/fonts/webdings.ttf", - _appPaths, _iHttpClient, _fileSystem).ConfigureAwait(false)); - paint.TextSize = FontSize; - paint.IsAntialias = true; - - canvas.DrawText("a", (float)x-20, OffsetFromTopRightCorner + 12, paint); - } - } - - internal static string ExtractFont(string name, IApplicationPaths paths, IFileSystem fileSystem) - { - var filePath = Path.Combine(paths.ProgramDataPath, "fonts", name); - - if (fileSystem.FileExists(filePath)) - { - return filePath; - } - var namespacePath = typeof(PlayedIndicatorDrawer).Namespace + ".fonts." + name; - var tempPath = Path.Combine(paths.TempDirectory, Guid.NewGuid().ToString("N") + ".ttf"); - fileSystem.CreateDirectory(fileSystem.GetDirectoryName(tempPath)); + paint.TextSize = 30; + paint.IsAntialias = true; - using (var stream = typeof(PlayedIndicatorDrawer).GetTypeInfo().Assembly.GetManifestResourceStream(namespacePath)) - { - using (var fileStream = fileSystem.GetFileStream(tempPath, FileOpenMode.Create, FileAccessMode.Write, FileShareMode.Read)) - { - stream.CopyTo(fileStream); - } - } + var text = "✔️"; + var emojiChar = StringUtilities.GetUnicodeCharacterCode(text, SKTextEncoding.Utf32); + // or: + //var emojiChar = 0x1F680; - fileSystem.CreateDirectory(fileSystem.GetDirectoryName(filePath)); + // ask the font manager for a font with that character + var fontManager = SKFontManager.Default; + var emojiTypeface = fontManager.MatchCharacter(emojiChar); - try - { - fileSystem.CopyFile(tempPath, filePath, false); - } - catch (IOException) - { + paint.Typeface = emojiTypeface; + canvas.DrawText(text, (float)x-20, OffsetFromTopRightCorner + 12, paint); } - - return tempPath; } internal static async Task DownloadFont(string name, string url, IApplicationPaths paths, IHttpClient httpClient, IFileSystem fileSystem) diff --git a/Emby.Drawing.Skia/UnplayedCountIndicator.cs b/Emby.Drawing.Skia/UnplayedCountIndicator.cs index 56a2519a3a..b59bc1026a 100644 --- a/Emby.Drawing.Skia/UnplayedCountIndicator.cs +++ b/Emby.Drawing.Skia/UnplayedCountIndicator.cs @@ -40,7 +40,7 @@ namespace Emby.Drawing.Skia { paint.Color = new SKColor(255, 255, 255, 255); paint.Style = SKPaintStyle.Fill; - paint.Typeface = SKTypeface.FromFile(PlayedIndicatorDrawer.ExtractFont("robotoregular.ttf", _appPaths, _fileSystem)); + paint.TextSize = 24; paint.IsAntialias = true; diff --git a/Emby.Server.Implementations/ApplicationHost.cs b/Emby.Server.Implementations/ApplicationHost.cs index 745d83eb5f..531e13123a 100644 --- a/Emby.Server.Implementations/ApplicationHost.cs +++ b/Emby.Server.Implementations/ApplicationHost.cs @@ -2317,12 +2317,17 @@ namespace Emby.Server.Implementations } } - public void LaunchUrl(string url) + public virtual void LaunchUrl(string url) { if (EnvironmentInfo.OperatingSystem != MediaBrowser.Model.System.OperatingSystem.Windows && EnvironmentInfo.OperatingSystem != MediaBrowser.Model.System.OperatingSystem.OSX) { - throw new NotImplementedException(); + throw new NotSupportedException(); + } + + if (!Environment.UserInteractive) + { + throw new NotSupportedException(); } var process = ProcessFactory.Create(new ProcessOptions diff --git a/Emby.Server.Implementations/Browser/BrowserLauncher.cs b/Emby.Server.Implementations/Browser/BrowserLauncher.cs index 05cde91e22..71497f6bf8 100644 --- a/Emby.Server.Implementations/Browser/BrowserLauncher.cs +++ b/Emby.Server.Implementations/Browser/BrowserLauncher.cs @@ -61,7 +61,7 @@ namespace Emby.Server.Implementations.Browser { appHost.LaunchUrl(url); } - catch (NotImplementedException) + catch (NotSupportedException) { } diff --git a/Emby.Server.Implementations/EntryPoints/StartupWizard.cs b/Emby.Server.Implementations/EntryPoints/StartupWizard.cs index 614c04fd22..8d13557952 100644 --- a/Emby.Server.Implementations/EntryPoints/StartupWizard.cs +++ b/Emby.Server.Implementations/EntryPoints/StartupWizard.cs @@ -3,6 +3,7 @@ using Emby.Server.Implementations.Browser; using MediaBrowser.Controller; using MediaBrowser.Controller.Plugins; using MediaBrowser.Model.Logging; +using MediaBrowser.Controller.Configuration; namespace Emby.Server.Implementations.EntryPoints { @@ -20,15 +21,13 @@ namespace Emby.Server.Implementations.EntryPoints /// private readonly ILogger _logger; - /// - /// Initializes a new instance of the class. - /// - /// The app host. - /// The logger. - public StartupWizard(IServerApplicationHost appHost, ILogger logger) + private IServerConfigurationManager _config; + + public StartupWizard(IServerApplicationHost appHost, ILogger logger, IServerConfigurationManager config) { _appHost = appHost; _logger = logger; + _config = config; } /// @@ -38,16 +37,12 @@ namespace Emby.Server.Implementations.EntryPoints { if (_appHost.IsFirstRun) { - LaunchStartupWizard(); + BrowserLauncher.OpenDashboardPage("wizardstart.html", _appHost); + } + else if (_config.Configuration.IsStartupWizardCompleted) + { + BrowserLauncher.OpenDashboardPage("index.html", _appHost); } - } - - /// - /// Launches the startup wizard. - /// - private void LaunchStartupWizard() - { - BrowserLauncher.OpenDashboardPage("wizardstart.html", _appHost); } /// diff --git a/Emby.Server.Implementations/Library/UserManager.cs b/Emby.Server.Implementations/Library/UserManager.cs index 0f48ff46b8..c4e75add89 100644 --- a/Emby.Server.Implementations/Library/UserManager.cs +++ b/Emby.Server.Implementations/Library/UserManager.cs @@ -218,7 +218,7 @@ namespace Emby.Server.Implementations.Library return builder.ToString(); } - public async Task AuthenticateUser(string username, string password, string hashedPassword, string passwordMd5, string remoteEndPoint) + public async Task AuthenticateUser(string username, string password, string hashedPassword, string passwordMd5, string remoteEndPoint, bool isUserSession) { if (string.IsNullOrWhiteSpace(username)) { @@ -288,8 +288,11 @@ namespace Emby.Server.Implementations.Library // Update LastActivityDate and LastLoginDate, then save if (success) { - user.LastActivityDate = user.LastLoginDate = DateTime.UtcNow; - UpdateUser(user); + if (isUserSession) + { + user.LastActivityDate = user.LastLoginDate = DateTime.UtcNow; + UpdateUser(user); + } UpdateInvalidLoginAttemptCount(user, 0); } else diff --git a/Emby.Server.Implementations/LiveTv/TunerHosts/M3UTunerHost.cs b/Emby.Server.Implementations/LiveTv/TunerHosts/M3UTunerHost.cs index c96d1f3592..e6c9b184e5 100644 --- a/Emby.Server.Implementations/LiveTv/TunerHosts/M3UTunerHost.cs +++ b/Emby.Server.Implementations/LiveTv/TunerHosts/M3UTunerHost.cs @@ -152,6 +152,8 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts isRemote = !_networkManager.IsInLocalNetwork(uri.Host); } + var supportsDirectPlay = !info.EnableStreamLooping && info.TunerCount == 0; + var mediaSource = new MediaSourceInfo { Path = path, @@ -183,7 +185,8 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts IsInfiniteStream = true, IsRemote = isRemote, - IgnoreDts = true + IgnoreDts = true, + SupportsDirectPlay = supportsDirectPlay }; mediaSource.InferTotalBitrate(); diff --git a/Emby.Server.Implementations/LiveTv/TunerHosts/SharedHttpStream.cs b/Emby.Server.Implementations/LiveTv/TunerHosts/SharedHttpStream.cs index cc2cb3e5ee..b8c7c7b18e 100644 --- a/Emby.Server.Implementations/LiveTv/TunerHosts/SharedHttpStream.cs +++ b/Emby.Server.Implementations/LiveTv/TunerHosts/SharedHttpStream.cs @@ -88,6 +88,9 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts SetTempFilePath(extension); var taskCompletionSource = new TaskCompletionSource(); + + var now = DateTime.UtcNow; + StartStreaming(response, taskCompletionSource, LiveStreamCancellationTokenSource.Token); //OpenedMediaSource.Protocol = MediaProtocol.File; @@ -97,11 +100,6 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts OpenedMediaSource.Path = _appHost.GetLocalApiUrl("127.0.0.1") + "/LiveTv/LiveStreamFiles/" + UniqueId + "/stream.ts"; OpenedMediaSource.Protocol = MediaProtocol.Http; - if (OpenedMediaSource.SupportsProbing) - { - await Task.Delay(3000).ConfigureAwait(false); - } - //OpenedMediaSource.Path = TempFilePath; //OpenedMediaSource.Protocol = MediaProtocol.File; @@ -111,6 +109,20 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts //OpenedMediaSource.SupportsDirectStream = true; //OpenedMediaSource.SupportsTranscoding = true; await taskCompletionSource.Task.ConfigureAwait(false); + + if (OpenedMediaSource.SupportsProbing) + { + var elapsed = (DateTime.UtcNow - now).TotalMilliseconds; + + var delay = Convert.ToInt32(3000 - elapsed); + + if (delay > 0) + { + Logger.Info("Delaying shared stream by {0}ms to allow the buffer to build.", delay); + + await Task.Delay(delay).ConfigureAwait(false); + } + } } protected override void CloseInternal() diff --git a/Emby.Server.Implementations/Session/HttpSessionController.cs b/Emby.Server.Implementations/Session/HttpSessionController.cs index e1c1bbe2b8..e852544204 100644 --- a/Emby.Server.Implementations/Session/HttpSessionController.cs +++ b/Emby.Server.Implementations/Session/HttpSessionController.cs @@ -117,6 +117,10 @@ namespace Emby.Server.Implementations.Session { dict["SubtitleStreamIndex"] = command.SubtitleStreamIndex.Value.ToString(CultureInfo.InvariantCulture); } + if (command.StartIndex.HasValue) + { + dict["StartIndex"] = command.StartIndex.Value.ToString(CultureInfo.InvariantCulture); + } if (!string.IsNullOrWhiteSpace(command.MediaSourceId)) { dict["MediaSourceId"] = command.MediaSourceId; diff --git a/Emby.Server.Implementations/Session/SessionManager.cs b/Emby.Server.Implementations/Session/SessionManager.cs index 30f6e65218..411781b259 100644 --- a/Emby.Server.Implementations/Session/SessionManager.cs +++ b/Emby.Server.Implementations/Session/SessionManager.cs @@ -1423,7 +1423,7 @@ namespace Emby.Server.Implementations.Session if (enforcePassword) { - var result = await _userManager.AuthenticateUser(request.Username, request.Password, request.PasswordSha1, request.PasswordMd5, request.RemoteEndPoint).ConfigureAwait(false); + var result = await _userManager.AuthenticateUser(request.Username, request.Password, request.PasswordSha1, request.PasswordMd5, request.RemoteEndPoint, true).ConfigureAwait(false); if (result == null) { diff --git a/MediaBrowser.Api/UserService.cs b/MediaBrowser.Api/UserService.cs index ddefb08dff..66d6a024eb 100644 --- a/MediaBrowser.Api/UserService.cs +++ b/MediaBrowser.Api/UserService.cs @@ -473,7 +473,7 @@ namespace MediaBrowser.Api } else { - var success = await _userManager.AuthenticateUser(user.Name, request.CurrentPw, request.CurrentPassword, null, Request.RemoteIp).ConfigureAwait(false); + var success = await _userManager.AuthenticateUser(user.Name, request.CurrentPw, request.CurrentPassword, null, Request.RemoteIp, false).ConfigureAwait(false); if (success == null) { diff --git a/MediaBrowser.Controller/Library/IUserManager.cs b/MediaBrowser.Controller/Library/IUserManager.cs index d4232c77e0..03e1d352e2 100644 --- a/MediaBrowser.Controller/Library/IUserManager.cs +++ b/MediaBrowser.Controller/Library/IUserManager.cs @@ -143,7 +143,7 @@ namespace MediaBrowser.Controller.Library /// /// Authenticates the user. /// - Task AuthenticateUser(string username, string password, string passwordSha1, string passwordMd5, string remoteEndPoint); + Task AuthenticateUser(string username, string password, string passwordSha1, string passwordMd5, string remoteEndPoint, bool isUserSession); /// /// Starts the forgot password process. diff --git a/MediaBrowser.Model/Session/PlayRequest.cs b/MediaBrowser.Model/Session/PlayRequest.cs index d50cb59533..3477f2e574 100644 --- a/MediaBrowser.Model/Session/PlayRequest.cs +++ b/MediaBrowser.Model/Session/PlayRequest.cs @@ -37,5 +37,6 @@ namespace MediaBrowser.Model.Session public int? SubtitleStreamIndex { get; set; } public int? AudioStreamIndex { get; set; } public string MediaSourceId { get; set; } + public int? StartIndex { get; set; } } } \ No newline at end of file diff --git a/SharedVersion.cs b/SharedVersion.cs index 580bc70016..99dc764dfd 100644 --- a/SharedVersion.cs +++ b/SharedVersion.cs @@ -1,3 +1,3 @@ using System.Reflection; -[assembly: AssemblyVersion("3.2.40.0")] +[assembly: AssemblyVersion("3.2.40.1")] -- cgit v1.2.3 From 4f09c1e06dab7cc8b260129648f5a54c77b8a4f9 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Thu, 23 Nov 2017 10:46:16 -0500 Subject: reduce dlna chatter --- Emby.Dlna/Main/DlnaEntryPoint.cs | 3 +- Emby.Dlna/PlayTo/Device.cs | 16 +- Emby.Dlna/PlayTo/PlayToManager.cs | 194 +++++++++++---------- Emby.Dlna/PlayTo/SsdpHttpClient.cs | 7 +- Emby.Server.Implementations/ApplicationHost.cs | 22 ++- .../EntryPoints/ExternalPortForwarding.cs | 3 +- .../Library/SearchEngine.cs | 3 +- Emby.Server.Implementations/Library/UserManager.cs | 2 +- .../LiveTv/LiveTvMediaSourceProvider.cs | 2 +- .../Networking/NetworkManager.cs | 10 +- .../Session/SessionManager.cs | 2 +- .../Social/SharingManager.cs | 5 +- Emby.Server.Implementations/Udp/UdpServer.cs | 28 +-- .../ScheduledTasksWebSocketListener.cs | 5 +- MediaBrowser.Api/SearchService.cs | 13 +- .../Session/SessionInfoWebSocketListener.cs | 5 +- .../System/ActivityLogWebSocketListener.cs | 3 +- .../System/SystemInfoWebSocketListener.cs | 5 +- MediaBrowser.Api/System/SystemService.cs | 5 +- MediaBrowser.Controller/IServerApplicationHost.cs | 7 +- .../Net/BasePeriodicWebSocketListener.cs | 8 +- MediaBrowser.Controller/Sync/ISyncManager.cs | 2 +- MediaBrowser.Model/Dlna/StreamBuilder.cs | 2 +- MediaBrowser.Model/Search/SearchHint.cs | 1 + MediaBrowser.WebDashboard/Api/PackageCreator.cs | 11 +- SharedVersion.cs | 2 +- 26 files changed, 215 insertions(+), 151 deletions(-) (limited to 'Emby.Server.Implementations/Library') diff --git a/Emby.Dlna/Main/DlnaEntryPoint.cs b/Emby.Dlna/Main/DlnaEntryPoint.cs index 3dd36a27bc..5eeab3decf 100644 --- a/Emby.Dlna/Main/DlnaEntryPoint.cs +++ b/Emby.Dlna/Main/DlnaEntryPoint.cs @@ -24,6 +24,7 @@ using MediaBrowser.Model.System; using MediaBrowser.Model.Threading; using Rssdp; using Rssdp.Infrastructure; +using System.Threading; namespace Emby.Dlna.Main { @@ -252,7 +253,7 @@ namespace Emby.Dlna.Main var cacheLength = _config.GetDlnaConfiguration().BlastAliveMessageIntervalSeconds; _Publisher.SupportPnpRootDevice = false; - var addresses = (await _appHost.GetLocalIpAddresses().ConfigureAwait(false)).ToList(); + var addresses = (await _appHost.GetLocalIpAddresses(CancellationToken.None).ConfigureAwait(false)).ToList(); var udn = CreateUuid(_appHost.SystemId); diff --git a/Emby.Dlna/PlayTo/Device.cs b/Emby.Dlna/PlayTo/Device.cs index 165f123f17..a617117f3c 100644 --- a/Emby.Dlna/PlayTo/Device.cs +++ b/Emby.Dlna/PlayTo/Device.cs @@ -831,7 +831,7 @@ namespace Emby.Dlna.PlayTo #region From XML - private async Task GetAVProtocolAsync() + private async Task GetAVProtocolAsync(CancellationToken cancellationToken) { if (_disposed) { @@ -845,12 +845,12 @@ namespace Emby.Dlna.PlayTo string url = NormalizeUrl(Properties.BaseUrl, avService.ScpdUrl); var httpClient = new SsdpHttpClient(_httpClient, _config); - var document = await httpClient.GetDataAsync(url).ConfigureAwait(false); + var document = await httpClient.GetDataAsync(url, cancellationToken).ConfigureAwait(false); AvCommands = TransportCommands.Create(document); } - private async Task GetRenderingProtocolAsync() + private async Task GetRenderingProtocolAsync(CancellationToken cancellationToken) { if (_disposed) { @@ -864,7 +864,7 @@ namespace Emby.Dlna.PlayTo string url = NormalizeUrl(Properties.BaseUrl, avService.ScpdUrl); var httpClient = new SsdpHttpClient(_httpClient, _config); - var document = await httpClient.GetDataAsync(url).ConfigureAwait(false); + var document = await httpClient.GetDataAsync(url, cancellationToken).ConfigureAwait(false); RendererCommands = TransportCommands.Create(document); } @@ -897,11 +897,11 @@ namespace Emby.Dlna.PlayTo set; } - public static async Task CreateuPnpDeviceAsync(Uri url, IHttpClient httpClient, IServerConfigurationManager config, ILogger logger, ITimerFactory timerFactory) + public static async Task CreateuPnpDeviceAsync(Uri url, IHttpClient httpClient, IServerConfigurationManager config, ILogger logger, ITimerFactory timerFactory, CancellationToken cancellationToken) { var ssdpHttpClient = new SsdpHttpClient(httpClient, config); - var document = await ssdpHttpClient.GetDataAsync(url.ToString()).ConfigureAwait(false); + var document = await ssdpHttpClient.GetDataAsync(url.ToString(), cancellationToken).ConfigureAwait(false); var deviceProperties = new DeviceInfo(); @@ -987,8 +987,8 @@ namespace Emby.Dlna.PlayTo if (device.GetAvTransportService() != null) { - await device.GetRenderingProtocolAsync().ConfigureAwait(false); - await device.GetAVProtocolAsync().ConfigureAwait(false); + await device.GetRenderingProtocolAsync(cancellationToken).ConfigureAwait(false); + await device.GetAVProtocolAsync(cancellationToken).ConfigureAwait(false); } return device; diff --git a/Emby.Dlna/PlayTo/PlayToManager.cs b/Emby.Dlna/PlayTo/PlayToManager.cs index dd30dfc3d9..f1b7181dda 100644 --- a/Emby.Dlna/PlayTo/PlayToManager.cs +++ b/Emby.Dlna/PlayTo/PlayToManager.cs @@ -18,6 +18,7 @@ using MediaBrowser.Model.Events; using MediaBrowser.Model.Globalization; using MediaBrowser.Model.Net; using MediaBrowser.Model.Threading; +using System.Threading; namespace Emby.Dlna.PlayTo { @@ -44,6 +45,8 @@ namespace Emby.Dlna.PlayTo private readonly List _nonRendererUrls = new List(); private DateTime _lastRendererClear; private bool _disposed; + private SemaphoreSlim _sessionLock = new SemaphoreSlim(1, 1); + private CancellationTokenSource _disposeCancellationTokenSource = new CancellationTokenSource(); public PlayToManager(ILogger logger, ISessionManager sessionManager, ILibraryManager libraryManager, IUserManager userManager, IDlnaManager dlnaManager, IServerApplicationHost appHost, IImageProcessor imageProcessor, IDeviceDiscovery deviceDiscovery, IHttpClient httpClient, IServerConfigurationManager config, IUserDataManager userDataManager, ILocalizationManager localization, IMediaSourceManager mediaSourceManager, IMediaEncoder mediaEncoder, ITimerFactory timerFactory) { @@ -98,92 +101,104 @@ namespace Emby.Dlna.PlayTo return; } + var cancellationToken = _disposeCancellationTokenSource.Token; + + await _sessionLock.WaitAsync(cancellationToken).ConfigureAwait(false); + try { - lock (_nonRendererUrls) + if (_disposed) { - if ((DateTime.UtcNow - _lastRendererClear).TotalMinutes >= 10) - { - _nonRendererUrls.Clear(); - _lastRendererClear = DateTime.UtcNow; - } - - if (_nonRendererUrls.Contains(location, StringComparer.OrdinalIgnoreCase)) - { - return; - } + return; } - var uri = info.Location; - _logger.Debug("Attempting to create PlayToController from location {0}", location); - var device = await Device.CreateuPnpDeviceAsync(uri, _httpClient, _config, _logger, _timerFactory).ConfigureAwait(false); + await AddDevice(info, location, cancellationToken).ConfigureAwait(false); + } + catch (OperationCanceledException) + { + + } + catch (Exception ex) + { + _logger.ErrorException("Error creating PlayTo device.", ex); + + _nonRendererUrls.Add(location); + } + finally + { + _sessionLock.Release(); + } + } + + private async Task AddDevice(UpnpDeviceInfo info, string location, CancellationToken cancellationToken) + { + if ((DateTime.UtcNow - _lastRendererClear).TotalMinutes >= 10) + { + _nonRendererUrls.Clear(); + _lastRendererClear = DateTime.UtcNow; + } + + if (_nonRendererUrls.Contains(location, StringComparer.OrdinalIgnoreCase)) + { + return; + } + + var uri = info.Location; + _logger.Debug("Attempting to create PlayToController from location {0}", location); + var device = await Device.CreateuPnpDeviceAsync(uri, _httpClient, _config, _logger, _timerFactory, cancellationToken).ConfigureAwait(false); + + if (device.RendererCommands == null) + { + _nonRendererUrls.Add(location); + return; + } + + _logger.Debug("Logging session activity from location {0}", location); + var sessionInfo = await _sessionManager.LogSessionActivity(device.Properties.ClientType, _appHost.ApplicationVersion.ToString(), device.Properties.UUID, device.Properties.Name, uri.OriginalString, null).ConfigureAwait(false); + + var controller = sessionInfo.SessionController as PlayToController; - if (device.RendererCommands == null) + if (controller == null) + { + string serverAddress; + if (info.LocalIpAddress == null || info.LocalIpAddress.Equals(IpAddressInfo.Any) || info.LocalIpAddress.Equals(IpAddressInfo.IPv6Loopback)) { - lock (_nonRendererUrls) - { - _nonRendererUrls.Add(location); - return; - } + serverAddress = await GetServerAddress(null, cancellationToken).ConfigureAwait(false); } - - if (_disposed) + else { - return; + serverAddress = await GetServerAddress(info.LocalIpAddress, cancellationToken).ConfigureAwait(false); } - _logger.Debug("Logging session activity from location {0}", location); - var sessionInfo = await _sessionManager.LogSessionActivity(device.Properties.ClientType, _appHost.ApplicationVersion.ToString(), device.Properties.UUID, device.Properties.Name, uri.OriginalString, null) - .ConfigureAwait(false); - - var controller = sessionInfo.SessionController as PlayToController; - - if (controller == null) + string accessToken = null; + + sessionInfo.SessionController = controller = new PlayToController(sessionInfo, + _sessionManager, + _libraryManager, + _logger, + _dlnaManager, + _userManager, + _imageProcessor, + serverAddress, + accessToken, + _deviceDiscovery, + _userDataManager, + _localization, + _mediaSourceManager, + _config, + _mediaEncoder); + + controller.Init(device); + + var profile = _dlnaManager.GetProfile(device.Properties.ToDeviceIdentification()) ?? + _dlnaManager.GetDefaultProfile(); + + _sessionManager.ReportCapabilities(sessionInfo.Id, new ClientCapabilities { - if (_disposed) - { - return; - } + PlayableMediaTypes = profile.GetSupportedMediaTypes(), - string serverAddress; - if (info.LocalIpAddress == null || info.LocalIpAddress.Equals(IpAddressInfo.Any) || info.LocalIpAddress.Equals(IpAddressInfo.IPv6Loopback)) + SupportedCommands = new string[] { - serverAddress = await GetServerAddress(null).ConfigureAwait(false); - } - else - { - serverAddress = await GetServerAddress(info.LocalIpAddress).ConfigureAwait(false); - } - - string accessToken = null; - - sessionInfo.SessionController = controller = new PlayToController(sessionInfo, - _sessionManager, - _libraryManager, - _logger, - _dlnaManager, - _userManager, - _imageProcessor, - serverAddress, - accessToken, - _deviceDiscovery, - _userDataManager, - _localization, - _mediaSourceManager, - _config, - _mediaEncoder); - - controller.Init(device); - - var profile = _dlnaManager.GetProfile(device.Properties.ToDeviceIdentification()) ?? - _dlnaManager.GetDefaultProfile(); - - _sessionManager.ReportCapabilities(sessionInfo.Id, new ClientCapabilities - { - PlayableMediaTypes = profile.GetSupportedMediaTypes(), - - SupportedCommands = new string[] - { GeneralCommandType.VolumeDown.ToString(), GeneralCommandType.VolumeUp.ToString(), GeneralCommandType.Mute.ToString(), @@ -192,33 +207,23 @@ namespace Emby.Dlna.PlayTo GeneralCommandType.SetVolume.ToString(), GeneralCommandType.SetAudioStreamIndex.ToString(), GeneralCommandType.SetSubtitleStreamIndex.ToString() - }, + }, - SupportsMediaControl = true, + SupportsMediaControl = true, - // xbox one creates a new uuid everytime it restarts - SupportsPersistentIdentifier = (device.Properties.ModelName ?? string.Empty).IndexOf("xbox", StringComparison.OrdinalIgnoreCase) == -1 - }); + // xbox one creates a new uuid everytime it restarts + SupportsPersistentIdentifier = (device.Properties.ModelName ?? string.Empty).IndexOf("xbox", StringComparison.OrdinalIgnoreCase) == -1 + }); - _logger.Info("DLNA Session created for {0} - {1}", device.Properties.Name, device.Properties.ModelName); - } - } - catch (Exception ex) - { - _logger.ErrorException("Error creating PlayTo device.", ex); - - lock (_nonRendererUrls) - { - _nonRendererUrls.Add(location); - } + _logger.Info("DLNA Session created for {0} - {1}", device.Properties.Name, device.Properties.ModelName); } } - private Task GetServerAddress(IpAddressInfo address) + private Task GetServerAddress(IpAddressInfo address, CancellationToken cancellationToken) { if (address == null) { - return _appHost.GetLocalApiUrl(); + return _appHost.GetLocalApiUrl(cancellationToken); } return Task.FromResult(_appHost.GetLocalApiUrl(address)); @@ -226,6 +231,15 @@ namespace Emby.Dlna.PlayTo public void Dispose() { + try + { + _disposeCancellationTokenSource.Cancel(); + } + catch + { + + } + _disposed = true; _deviceDiscovery.DeviceDiscovered -= _deviceDiscovery_DeviceDiscovered; GC.SuppressFinalize(this); diff --git a/Emby.Dlna/PlayTo/SsdpHttpClient.cs b/Emby.Dlna/PlayTo/SsdpHttpClient.cs index 78b688d92a..d4b5943674 100644 --- a/Emby.Dlna/PlayTo/SsdpHttpClient.cs +++ b/Emby.Dlna/PlayTo/SsdpHttpClient.cs @@ -7,6 +7,7 @@ using System.IO; using System.Text; using System.Threading.Tasks; using System.Xml.Linq; +using System.Threading; namespace Emby.Dlna.PlayTo { @@ -89,7 +90,7 @@ namespace Emby.Dlna.PlayTo } } - public async Task GetDataAsync(string url) + public async Task GetDataAsync(string url, CancellationToken cancellationToken) { var options = new HttpRequestOptions { @@ -99,7 +100,9 @@ namespace Emby.Dlna.PlayTo BufferContent = false, // The periodic requests may keep some devices awake - LogRequestAsDebug = true + LogRequestAsDebug = true, + + CancellationToken = cancellationToken }; options.RequestHeaders["FriendlyName.DLNA.ORG"] = FriendlyName; diff --git a/Emby.Server.Implementations/ApplicationHost.cs b/Emby.Server.Implementations/ApplicationHost.cs index 531e13123a..2e5c4be907 100644 --- a/Emby.Server.Implementations/ApplicationHost.cs +++ b/Emby.Server.Implementations/ApplicationHost.cs @@ -1901,9 +1901,9 @@ namespace Emby.Server.Implementations /// Gets the system status. /// /// SystemInfo. - public async Task GetSystemInfo() + public async Task GetSystemInfo(CancellationToken cancellationToken) { - var localAddress = await GetLocalApiUrl().ConfigureAwait(false); + var localAddress = await GetLocalApiUrl(cancellationToken).ConfigureAwait(false); return new SystemInfo { @@ -1955,12 +1955,12 @@ namespace Emby.Server.Implementations get { return Certificate != null || ServerConfigurationManager.Configuration.IsBehindProxy; } } - public async Task GetLocalApiUrl() + public async Task GetLocalApiUrl(CancellationToken cancellationToken) { try { // Return the first matched address, if found, or the first known local address - var address = (await GetLocalIpAddresses().ConfigureAwait(false)).FirstOrDefault(i => !i.Equals(IpAddressInfo.Loopback) && !i.Equals(IpAddressInfo.IPv6Loopback)); + var address = (await GetLocalIpAddresses(cancellationToken).ConfigureAwait(false)).FirstOrDefault(i => !i.Equals(IpAddressInfo.Loopback) && !i.Equals(IpAddressInfo.IPv6Loopback)); if (address != null) { @@ -1994,7 +1994,7 @@ namespace Emby.Server.Implementations HttpPort.ToString(CultureInfo.InvariantCulture)); } - public async Task> GetLocalIpAddresses() + public async Task> GetLocalIpAddresses(CancellationToken cancellationToken) { var addresses = ServerConfigurationManager .Configuration @@ -2011,7 +2011,7 @@ namespace Emby.Server.Implementations foreach (var address in addresses) { - var valid = await IsIpAddressValidAsync(address).ConfigureAwait(false); + var valid = await IsIpAddressValidAsync(address, cancellationToken).ConfigureAwait(false); if (valid) { list.Add(address); @@ -2043,7 +2043,7 @@ namespace Emby.Server.Implementations private readonly ConcurrentDictionary _validAddressResults = new ConcurrentDictionary(StringComparer.OrdinalIgnoreCase); private DateTime _lastAddressCacheClear; - private async Task IsIpAddressValidAsync(IpAddressInfo address) + private async Task IsIpAddressValidAsync(IpAddressInfo address, CancellationToken cancellationToken) { if (address.Equals(IpAddressInfo.Loopback) || address.Equals(IpAddressInfo.IPv6Loopback)) @@ -2075,7 +2075,9 @@ namespace Emby.Server.Implementations LogErrors = false, LogRequest = false, TimeoutMs = 30000, - BufferContent = false + BufferContent = false, + + CancellationToken = cancellationToken }, "POST").ConfigureAwait(false)) { @@ -2090,6 +2092,10 @@ namespace Emby.Server.Implementations } } } + catch (OperationCanceledException) + { + throw; + } catch { //Logger.Debug("Ping test result to {0}. Success: {1}", apiUrl, false); diff --git a/Emby.Server.Implementations/EntryPoints/ExternalPortForwarding.cs b/Emby.Server.Implementations/EntryPoints/ExternalPortForwarding.cs index 2cef468394..903bb0ff46 100644 --- a/Emby.Server.Implementations/EntryPoints/ExternalPortForwarding.cs +++ b/Emby.Server.Implementations/EntryPoints/ExternalPortForwarding.cs @@ -13,6 +13,7 @@ using MediaBrowser.Model.Logging; using MediaBrowser.Model.Threading; using Mono.Nat; using MediaBrowser.Model.Extensions; +using System.Threading; namespace Emby.Server.Implementations.EntryPoints { @@ -158,7 +159,7 @@ namespace Emby.Server.Implementations.EntryPoints try { - var localAddressString = await _appHost.GetLocalApiUrl().ConfigureAwait(false); + var localAddressString = await _appHost.GetLocalApiUrl(CancellationToken.None).ConfigureAwait(false); Uri uri; if (Uri.TryCreate(localAddressString, UriKind.Absolute, out uri)) diff --git a/Emby.Server.Implementations/Library/SearchEngine.cs b/Emby.Server.Implementations/Library/SearchEngine.cs index df21c14091..8021399bd8 100644 --- a/Emby.Server.Implementations/Library/SearchEngine.cs +++ b/Emby.Server.Implementations/Library/SearchEngine.cs @@ -191,7 +191,8 @@ namespace Emby.Server.Implementations.Library { ItemFields.AirTime, ItemFields.DateCreated, - ItemFields.ChannelInfo + ItemFields.ChannelInfo, + ItemFields.ParentId } } }; diff --git a/Emby.Server.Implementations/Library/UserManager.cs b/Emby.Server.Implementations/Library/UserManager.cs index c4e75add89..71c953b2cc 100644 --- a/Emby.Server.Implementations/Library/UserManager.cs +++ b/Emby.Server.Implementations/Library/UserManager.cs @@ -815,7 +815,7 @@ namespace Emby.Server.Implementations.Library var text = new StringBuilder(); - var localAddress = _appHost.GetLocalApiUrl().Result ?? string.Empty; + var localAddress = _appHost.GetLocalApiUrl(CancellationToken.None).Result ?? string.Empty; text.AppendLine("Use your web browser to visit:"); text.AppendLine(string.Empty); diff --git a/Emby.Server.Implementations/LiveTv/LiveTvMediaSourceProvider.cs b/Emby.Server.Implementations/LiveTv/LiveTvMediaSourceProvider.cs index ed8b3074b0..29b7c41ef2 100644 --- a/Emby.Server.Implementations/LiveTv/LiveTvMediaSourceProvider.cs +++ b/Emby.Server.Implementations/LiveTv/LiveTvMediaSourceProvider.cs @@ -95,7 +95,7 @@ namespace Emby.Server.Implementations.LiveTv } var list = sources.ToList(); - var serverUrl = await _appHost.GetLocalApiUrl().ConfigureAwait(false); + var serverUrl = await _appHost.GetLocalApiUrl(cancellationToken).ConfigureAwait(false); foreach (var source in list) { diff --git a/Emby.Server.Implementations/Networking/NetworkManager.cs b/Emby.Server.Implementations/Networking/NetworkManager.cs index fbdb5c128c..d938359e9e 100644 --- a/Emby.Server.Implementations/Networking/NetworkManager.cs +++ b/Emby.Server.Implementations/Networking/NetworkManager.cs @@ -11,6 +11,7 @@ using MediaBrowser.Model.Extensions; using MediaBrowser.Model.IO; using MediaBrowser.Model.Logging; using MediaBrowser.Model.Net; +using System.Threading; namespace Emby.Server.Implementations.Networking { @@ -37,7 +38,7 @@ namespace Emby.Server.Implementations.Networking if (_localIpAddresses == null || forceRefresh) { - var addresses = GetLocalIpAddressesInternal().Select(ToIpAddressInfo).ToList(); + var addresses = GetLocalIpAddressesInternal().Result.Select(ToIpAddressInfo).ToList(); _localIpAddresses = addresses; _lastRefresh = DateTime.UtcNow; @@ -49,14 +50,14 @@ namespace Emby.Server.Implementations.Networking return _localIpAddresses; } - private IEnumerable GetLocalIpAddressesInternal() + private async Task> GetLocalIpAddressesInternal() { var list = GetIPsDefault() .ToList(); if (list.Count == 0) { - list.AddRange(GetLocalIpAddressesFallback().Result); + list.AddRange(await GetLocalIpAddressesFallback().ConfigureAwait(false)); } var listClone = list.ToList(); @@ -65,7 +66,8 @@ namespace Emby.Server.Implementations.Networking .OrderBy(i => i.AddressFamily == AddressFamily.InterNetwork ? 0 : 1) .ThenBy(i => listClone.IndexOf(i)) .Where(FilterIpAddress) - .DistinctBy(i => i.ToString()); + .DistinctBy(i => i.ToString()) + .ToList(); } private bool FilterIpAddress(IPAddress address) diff --git a/Emby.Server.Implementations/Session/SessionManager.cs b/Emby.Server.Implementations/Session/SessionManager.cs index 411781b259..f49251da53 100644 --- a/Emby.Server.Implementations/Session/SessionManager.cs +++ b/Emby.Server.Implementations/Session/SessionManager.cs @@ -1182,7 +1182,7 @@ namespace Emby.Server.Implementations.Session { var sessions = Sessions.Where(i => i.IsActive && i.SessionController != null).ToList(); - var info = await _appHost.GetSystemInfo().ConfigureAwait(false); + var info = await _appHost.GetSystemInfo(cancellationToken).ConfigureAwait(false); var tasks = sessions.Select(session => Task.Run(async () => { diff --git a/Emby.Server.Implementations/Social/SharingManager.cs b/Emby.Server.Implementations/Social/SharingManager.cs index 57cf93948d..e94b9100a3 100644 --- a/Emby.Server.Implementations/Social/SharingManager.cs +++ b/Emby.Server.Implementations/Social/SharingManager.cs @@ -5,6 +5,7 @@ using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Library; using MediaBrowser.Model.Social; using System; +using System.Threading; using System.Threading.Tasks; namespace Emby.Server.Implementations.Social @@ -42,7 +43,7 @@ namespace Emby.Server.Implementations.Social throw new ResourceNotFoundException(); } - var externalUrl = (await _appHost.GetSystemInfo().ConfigureAwait(false)).WanAddress; + var externalUrl = (await _appHost.GetSystemInfo(CancellationToken.None).ConfigureAwait(false)).WanAddress; if (string.IsNullOrWhiteSpace(externalUrl)) { @@ -73,7 +74,7 @@ namespace Emby.Server.Implementations.Social { var info = _repository.GetShareInfo(id); - AddShareInfo(info, _appHost.GetSystemInfo().Result.WanAddress); + AddShareInfo(info, _appHost.GetSystemInfo(CancellationToken.None).Result.WanAddress); return info; } diff --git a/Emby.Server.Implementations/Udp/UdpServer.cs b/Emby.Server.Implementations/Udp/UdpServer.cs index 8dc1fae4be..28de80da16 100644 --- a/Emby.Server.Implementations/Udp/UdpServer.cs +++ b/Emby.Server.Implementations/Udp/UdpServer.cs @@ -25,7 +25,7 @@ namespace Emby.Server.Implementations.Udp private bool _isDisposed; - private readonly List>> _responders = new List>>(); + private readonly List>> _responders = new List>>(); private readonly IServerApplicationHost _appHost; private readonly IJsonSerializer _json; @@ -44,9 +44,9 @@ namespace Emby.Server.Implementations.Udp AddMessageResponder("who is MediaBrowserServer_v2?", false, RespondToV2Message); } - private void AddMessageResponder(string message, bool isSubstring, Func responder) + private void AddMessageResponder(string message, bool isSubstring, Func responder) { - _responders.Add(new Tuple>(message, isSubstring, responder)); + _responders.Add(new Tuple>(message, isSubstring, responder)); } /// @@ -67,9 +67,15 @@ namespace Emby.Server.Implementations.Udp if (responder != null) { + var cancellationToken = CancellationToken.None; + try { - await responder.Item2.Item3(responder.Item1, message.RemoteEndPoint, encoding).ConfigureAwait(false); + await responder.Item2.Item3(responder.Item1, message.RemoteEndPoint, encoding, cancellationToken).ConfigureAwait(false); + } + catch (OperationCanceledException) + { + } catch (Exception ex) { @@ -78,7 +84,7 @@ namespace Emby.Server.Implementations.Udp } } - private Tuple>> GetResponder(byte[] buffer, int bytesReceived, Encoding encoding) + private Tuple>> GetResponder(byte[] buffer, int bytesReceived, Encoding encoding) { var text = encoding.GetString(buffer, 0, bytesReceived); var responder = _responders.FirstOrDefault(i => @@ -94,14 +100,14 @@ namespace Emby.Server.Implementations.Udp { return null; } - return new Tuple>>(text, responder); + return new Tuple>>(text, responder); } - private async Task RespondToV2Message(string messageText, IpEndPointInfo endpoint, Encoding encoding) + private async Task RespondToV2Message(string messageText, IpEndPointInfo endpoint, Encoding encoding, CancellationToken cancellationToken) { var parts = messageText.Split('|'); - var localUrl = await _appHost.GetLocalApiUrl().ConfigureAwait(false); + var localUrl = await _appHost.GetLocalApiUrl(cancellationToken).ConfigureAwait(false); if (!string.IsNullOrEmpty(localUrl)) { @@ -112,7 +118,7 @@ namespace Emby.Server.Implementations.Udp Name = _appHost.FriendlyName }; - await SendAsync(encoding.GetBytes(_json.SerializeToString(response)), endpoint).ConfigureAwait(false); + await SendAsync(encoding.GetBytes(_json.SerializeToString(response)), endpoint, cancellationToken).ConfigureAwait(false); if (parts.Length > 1) { @@ -248,7 +254,7 @@ namespace Emby.Server.Implementations.Udp } } - public async Task SendAsync(byte[] bytes, IpEndPointInfo remoteEndPoint) + public async Task SendAsync(byte[] bytes, IpEndPointInfo remoteEndPoint, CancellationToken cancellationToken) { if (_isDisposed) { @@ -267,7 +273,7 @@ namespace Emby.Server.Implementations.Udp try { - await _udpClient.SendToAsync(bytes, 0, bytes.Length, remoteEndPoint, CancellationToken.None).ConfigureAwait(false); + await _udpClient.SendToAsync(bytes, 0, bytes.Length, remoteEndPoint, cancellationToken).ConfigureAwait(false); _logger.Info("Udp message sent to {0}", remoteEndPoint); } diff --git a/MediaBrowser.Api/ScheduledTasks/ScheduledTasksWebSocketListener.cs b/MediaBrowser.Api/ScheduledTasks/ScheduledTasksWebSocketListener.cs index 69ce6a385d..2d30625a98 100644 --- a/MediaBrowser.Api/ScheduledTasks/ScheduledTasksWebSocketListener.cs +++ b/MediaBrowser.Api/ScheduledTasks/ScheduledTasksWebSocketListener.cs @@ -3,9 +3,10 @@ using MediaBrowser.Model.Logging; using MediaBrowser.Model.Tasks; using System.Collections.Generic; using System.Linq; -using System.Threading.Tasks; +using System.Threading; using MediaBrowser.Controller.Net; using MediaBrowser.Model.Threading; +using System.Threading.Tasks; namespace MediaBrowser.Api.ScheduledTasks { @@ -63,7 +64,7 @@ namespace MediaBrowser.Api.ScheduledTasks /// /// The state. /// Task{IEnumerable{TaskInfo}}. - protected override Task> GetDataToSend(WebSocketListenerState state) + protected override Task> GetDataToSend(WebSocketListenerState state, CancellationToken cancellationToken) { return Task.FromResult(TaskManager.ScheduledTasks .OrderBy(i => i.Name) diff --git a/MediaBrowser.Api/SearchService.cs b/MediaBrowser.Api/SearchService.cs index ad79ea57b9..50033eee82 100644 --- a/MediaBrowser.Api/SearchService.cs +++ b/MediaBrowser.Api/SearchService.cs @@ -248,9 +248,20 @@ namespace MediaBrowser.Api if (song != null) { - result.Album = song.Album; result.AlbumArtist = song.AlbumArtists.FirstOrDefault(); result.Artists = song.Artists; + + album = song.AlbumEntity; + + if (album != null) + { + result.Album = album.Name; + result.AlbumId = album.Id.ToString("N"); + } + else + { + result.Album = song.Album; + } } if (!string.IsNullOrWhiteSpace(item.ChannelId)) diff --git a/MediaBrowser.Api/Session/SessionInfoWebSocketListener.cs b/MediaBrowser.Api/Session/SessionInfoWebSocketListener.cs index e133a88a1f..65c69fc7de 100644 --- a/MediaBrowser.Api/Session/SessionInfoWebSocketListener.cs +++ b/MediaBrowser.Api/Session/SessionInfoWebSocketListener.cs @@ -5,8 +5,9 @@ using MediaBrowser.Model.Logging; using MediaBrowser.Model.Session; using System.Collections.Generic; using System.Linq; -using System.Threading.Tasks; +using System.Threading; using MediaBrowser.Model.Threading; +using System.Threading.Tasks; namespace MediaBrowser.Api.Session { @@ -86,7 +87,7 @@ namespace MediaBrowser.Api.Session /// /// The state. /// Task{SystemInfo}. - protected override Task> GetDataToSend(WebSocketListenerState state) + protected override Task> GetDataToSend(WebSocketListenerState state, CancellationToken cancellationToken) { return Task.FromResult(_sessionManager.Sessions.Where(i => i.IsActive).Select(_sessionManager.GetSessionInfoDto)); } diff --git a/MediaBrowser.Api/System/ActivityLogWebSocketListener.cs b/MediaBrowser.Api/System/ActivityLogWebSocketListener.cs index 793f745713..f9cac7389d 100644 --- a/MediaBrowser.Api/System/ActivityLogWebSocketListener.cs +++ b/MediaBrowser.Api/System/ActivityLogWebSocketListener.cs @@ -5,6 +5,7 @@ using System.Collections.Generic; using System.Threading.Tasks; using MediaBrowser.Controller.Net; using MediaBrowser.Model.Threading; +using System.Threading; namespace MediaBrowser.Api.System { @@ -43,7 +44,7 @@ namespace MediaBrowser.Api.System /// /// The state. /// Task{SystemInfo}. - protected override Task> GetDataToSend(WebSocketListenerState state) + protected override Task> GetDataToSend(WebSocketListenerState state, CancellationToken CancellationToken) { return Task.FromResult(new List()); } diff --git a/MediaBrowser.Api/System/SystemInfoWebSocketListener.cs b/MediaBrowser.Api/System/SystemInfoWebSocketListener.cs index 8d74cc66c0..63847f2b52 100644 --- a/MediaBrowser.Api/System/SystemInfoWebSocketListener.cs +++ b/MediaBrowser.Api/System/SystemInfoWebSocketListener.cs @@ -4,6 +4,7 @@ using MediaBrowser.Model.Logging; using MediaBrowser.Model.System; using System.Threading.Tasks; using MediaBrowser.Model.Threading; +using System.Threading; namespace MediaBrowser.Api.System { @@ -40,9 +41,9 @@ namespace MediaBrowser.Api.System /// /// The state. /// Task{SystemInfo}. - protected override Task GetDataToSend(WebSocketListenerState state) + protected override Task GetDataToSend(WebSocketListenerState state, CancellationToken cancellationToken) { - return _appHost.GetSystemInfo(); + return _appHost.GetSystemInfo(cancellationToken); } } } diff --git a/MediaBrowser.Api/System/SystemService.cs b/MediaBrowser.Api/System/SystemService.cs index d850b2ce72..6de7dd98ba 100644 --- a/MediaBrowser.Api/System/SystemService.cs +++ b/MediaBrowser.Api/System/SystemService.cs @@ -14,6 +14,7 @@ using MediaBrowser.Controller.IO; using MediaBrowser.Model.IO; using MediaBrowser.Model.Net; using MediaBrowser.Model.Services; +using System.Threading; namespace MediaBrowser.Api.System { @@ -164,14 +165,14 @@ namespace MediaBrowser.Api.System /// System.Object. public async Task Get(GetSystemInfo request) { - var result = await _appHost.GetSystemInfo().ConfigureAwait(false); + var result = await _appHost.GetSystemInfo(CancellationToken.None).ConfigureAwait(false); return ToOptimizedResult(result); } public async Task Get(GetPublicSystemInfo request) { - var result = await _appHost.GetSystemInfo().ConfigureAwait(false); + var result = await _appHost.GetSystemInfo(CancellationToken.None).ConfigureAwait(false); var publicInfo = new PublicSystemInfo { diff --git a/MediaBrowser.Controller/IServerApplicationHost.cs b/MediaBrowser.Controller/IServerApplicationHost.cs index e9f7d59321..380be068e5 100644 --- a/MediaBrowser.Controller/IServerApplicationHost.cs +++ b/MediaBrowser.Controller/IServerApplicationHost.cs @@ -5,6 +5,7 @@ using System.Collections.Generic; using System.Net; using System.Threading.Tasks; using MediaBrowser.Model.Net; +using System.Threading; namespace MediaBrowser.Controller { @@ -19,7 +20,7 @@ namespace MediaBrowser.Controller /// Gets the system info. /// /// SystemInfo. - Task GetSystemInfo(); + Task GetSystemInfo(CancellationToken cancellationToken); /// /// Gets a value indicating whether [supports automatic run at startup]. @@ -61,13 +62,13 @@ namespace MediaBrowser.Controller /// Gets the local ip address. /// /// The local ip address. - Task> GetLocalIpAddresses(); + Task> GetLocalIpAddresses(CancellationToken cancellationToken); /// /// Gets the local API URL. /// /// The local API URL. - Task GetLocalApiUrl(); + Task GetLocalApiUrl(CancellationToken cancellationToken); /// /// Gets the local API URL. diff --git a/MediaBrowser.Controller/Net/BasePeriodicWebSocketListener.cs b/MediaBrowser.Controller/Net/BasePeriodicWebSocketListener.cs index 6be94e7e6e..17b82b3cae 100644 --- a/MediaBrowser.Controller/Net/BasePeriodicWebSocketListener.cs +++ b/MediaBrowser.Controller/Net/BasePeriodicWebSocketListener.cs @@ -36,7 +36,7 @@ namespace MediaBrowser.Controller.Net /// /// The state. /// Task{`1}. - protected abstract Task GetDataToSend(TStateType state); + protected abstract Task GetDataToSend(TStateType state, CancellationToken cancellationToken); /// /// The logger @@ -209,7 +209,9 @@ namespace MediaBrowser.Controller.Net { var state = tuple.Item4; - var data = await GetDataToSend(state).ConfigureAwait(false); + var cancellationToken = tuple.Item2.Token; + + var data = await GetDataToSend(state, cancellationToken).ConfigureAwait(false); if (data != null) { @@ -218,7 +220,7 @@ namespace MediaBrowser.Controller.Net MessageType = Name, Data = data - }, tuple.Item2.Token).ConfigureAwait(false); + }, cancellationToken).ConfigureAwait(false); state.DateLastSendUtc = DateTime.UtcNow; } diff --git a/MediaBrowser.Controller/Sync/ISyncManager.cs b/MediaBrowser.Controller/Sync/ISyncManager.cs index 0bf4b914f1..5e9085a402 100644 --- a/MediaBrowser.Controller/Sync/ISyncManager.cs +++ b/MediaBrowser.Controller/Sync/ISyncManager.cs @@ -29,7 +29,7 @@ namespace MediaBrowser.Controller.Sync /// Gets the jobs. /// /// QueryResult<SyncJob>. - Task> GetJobs(SyncJobQuery query); + QueryResult GetJobs(SyncJobQuery query); /// /// Gets the job items. diff --git a/MediaBrowser.Model/Dlna/StreamBuilder.cs b/MediaBrowser.Model/Dlna/StreamBuilder.cs index 37d266ac09..2da6f1c81c 100644 --- a/MediaBrowser.Model/Dlna/StreamBuilder.cs +++ b/MediaBrowser.Model/Dlna/StreamBuilder.cs @@ -1343,7 +1343,7 @@ namespace MediaBrowser.Model.Dlna if (itemBitrate > requestedMaxBitrate) { - _logger.Info("Bitrate exceeds " + playMethod + " limit: media bitrate: {0}, max bitrate: {1}", item.Bitrate.Value.ToString(CultureInfo.InvariantCulture), requestedMaxBitrate.ToString(CultureInfo.InvariantCulture)); + _logger.Info("Bitrate exceeds " + playMethod + " limit: media bitrate: {0}, max bitrate: {1}", itemBitrate.ToString(CultureInfo.InvariantCulture), requestedMaxBitrate.ToString(CultureInfo.InvariantCulture)); return false; } diff --git a/MediaBrowser.Model/Search/SearchHint.cs b/MediaBrowser.Model/Search/SearchHint.cs index 5c56374819..f2617c9095 100644 --- a/MediaBrowser.Model/Search/SearchHint.cs +++ b/MediaBrowser.Model/Search/SearchHint.cs @@ -107,6 +107,7 @@ namespace MediaBrowser.Model.Search /// /// The album. public string Album { get; set; } + public string AlbumId { get; set; } /// /// Gets or sets the album artist. diff --git a/MediaBrowser.WebDashboard/Api/PackageCreator.cs b/MediaBrowser.WebDashboard/Api/PackageCreator.cs index f55d95a2e7..5fd94e0d76 100644 --- a/MediaBrowser.WebDashboard/Api/PackageCreator.cs +++ b/MediaBrowser.WebDashboard/Api/PackageCreator.cs @@ -200,7 +200,16 @@ namespace MediaBrowser.WebDashboard.Api sb.Append(""); sb.Append(""); sb.Append(""); - sb.Append(""); + + if (string.Equals(mode, "cordova", StringComparison.OrdinalIgnoreCase)) + { + sb.Append(""); + } + else + { + sb.Append(""); + } + sb.Append(""); sb.Append(""); sb.Append(""); diff --git a/SharedVersion.cs b/SharedVersion.cs index 99dc764dfd..463ec3ae3c 100644 --- a/SharedVersion.cs +++ b/SharedVersion.cs @@ -1,3 +1,3 @@ using System.Reflection; -[assembly: AssemblyVersion("3.2.40.1")] +[assembly: AssemblyVersion("3.2.40.2")] -- cgit v1.2.3 From 58a7829ecd773dbc3c875d3f0d4438b847fd54b5 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sat, 25 Nov 2017 23:48:12 -0500 Subject: update library changed notifier --- .../EntryPoints/LibraryChangedNotifier.cs | 36 ++++++++++++++++++++-- Emby.Server.Implementations/IO/LibraryMonitor.cs | 7 +++-- .../IO/ManagedFileSystem.cs | 15 +++++++++ .../Library/LibraryManager.cs | 21 +++++++++---- .../LiveTv/EmbyTV/EmbyTV.cs | 19 ++++++++++++ .../LiveTv/LiveTvManager.cs | 2 +- MediaBrowser.Controller/Entities/BaseItem.cs | 2 +- MediaBrowser.Controller/Entities/Folder.cs | 4 +-- MediaBrowser.Controller/Library/ILibraryManager.cs | 9 ++---- .../Library/ItemChangeEventArgs.cs | 2 ++ MediaBrowser.Model/Entities/LibraryUpdateInfo.cs | 3 ++ SharedVersion.cs | 2 +- 12 files changed, 98 insertions(+), 24 deletions(-) (limited to 'Emby.Server.Implementations/Library') diff --git a/Emby.Server.Implementations/EntryPoints/LibraryChangedNotifier.cs b/Emby.Server.Implementations/EntryPoints/LibraryChangedNotifier.cs index 299da07445..0e771cbecc 100644 --- a/Emby.Server.Implementations/EntryPoints/LibraryChangedNotifier.cs +++ b/Emby.Server.Implementations/EntryPoints/LibraryChangedNotifier.cs @@ -260,7 +260,7 @@ namespace Emby.Server.Implementations.EntryPoints LibraryUpdateTimer.Change(LibraryUpdateDuration, Timeout.Infinite); } - var parent = e.Item.GetParent() as Folder; + var parent = e.Parent as Folder; if (parent != null) { _foldersRemovedFrom.Add(parent); @@ -363,10 +363,16 @@ namespace Emby.Server.Implementations.EntryPoints /// The folders removed from. /// The user id. /// LibraryUpdateInfo. - private LibraryUpdateInfo GetLibraryUpdateInfo(IEnumerable itemsAdded, IEnumerable itemsUpdated, IEnumerable itemsRemoved, IEnumerable foldersAddedTo, IEnumerable foldersRemovedFrom, Guid userId) + private LibraryUpdateInfo GetLibraryUpdateInfo(List itemsAdded, List itemsUpdated, List itemsRemoved, List foldersAddedTo, List foldersRemovedFrom, Guid userId) { var user = _userManager.GetUserById(userId); + var newAndRemoved = new List(); + newAndRemoved.AddRange(foldersAddedTo); + newAndRemoved.AddRange(foldersRemovedFrom); + + var allUserRootChildren = _libraryManager.GetUserRootFolder().GetChildren(user, true).OfType().ToList(); + return new LibraryUpdateInfo { ItemsAdded = itemsAdded.SelectMany(i => TranslatePhysicalItemToUserLibrary(i, user)).Select(i => i.Id.ToString("N")).Distinct().ToArray(), @@ -377,7 +383,9 @@ namespace Emby.Server.Implementations.EntryPoints FoldersAddedTo = foldersAddedTo.SelectMany(i => TranslatePhysicalItemToUserLibrary(i, user)).Select(i => i.Id.ToString("N")).Distinct().ToArray(), - FoldersRemovedFrom = foldersRemovedFrom.SelectMany(i => TranslatePhysicalItemToUserLibrary(i, user)).Select(i => i.Id.ToString("N")).Distinct().ToArray() + FoldersRemovedFrom = foldersRemovedFrom.SelectMany(i => TranslatePhysicalItemToUserLibrary(i, user)).Select(i => i.Id.ToString("N")).Distinct().ToArray(), + + CollectionFolders = GetTopParentIds(newAndRemoved, user, allUserRootChildren).ToArray() }; } @@ -396,6 +404,28 @@ namespace Emby.Server.Implementations.EntryPoints return item.SourceType == SourceType.Library; } + private IEnumerable GetTopParentIds(List items, User user, List allUserRootChildren) + { + var list = new List(); + + foreach (var item in items) + { + // If the physical root changed, return the user root + if (item is AggregateFolder) + { + continue; + } + + var collectionFolders = _libraryManager.GetCollectionFolders(item, allUserRootChildren); + foreach (var folder in allUserRootChildren) + { + list.Add(folder.Id.ToString("N")); + } + } + + return list.Distinct(StringComparer.Ordinal); + } + /// /// Translates the physical item to user library. /// diff --git a/Emby.Server.Implementations/IO/LibraryMonitor.cs b/Emby.Server.Implementations/IO/LibraryMonitor.cs index c99b601c90..a2abb2a5c9 100644 --- a/Emby.Server.Implementations/IO/LibraryMonitor.cs +++ b/Emby.Server.Implementations/IO/LibraryMonitor.cs @@ -237,7 +237,7 @@ namespace Emby.Server.Implementations.IO /// The instance containing the event data. void LibraryManager_ItemRemoved(object sender, ItemChangeEventArgs e) { - if (e.Item.GetParent() is AggregateFolder) + if (e.Parent is AggregateFolder) { StopWatchingPath(e.Item.Path); } @@ -250,7 +250,7 @@ namespace Emby.Server.Implementations.IO /// The instance containing the event data. void LibraryManager_ItemAdded(object sender, ItemChangeEventArgs e) { - if (e.Item.GetParent() is AggregateFolder) + if (e.Parent is AggregateFolder) { StartWatching(e.Item); } @@ -320,7 +320,8 @@ namespace Emby.Server.Implementations.IO IncludeSubdirectories = true }; - if (_environmentInfo.OperatingSystem == MediaBrowser.Model.System.OperatingSystem.Windows) + if (_environmentInfo.OperatingSystem == MediaBrowser.Model.System.OperatingSystem.Windows || + _environmentInfo.OperatingSystem == MediaBrowser.Model.System.OperatingSystem.OSX) { newWatcher.InternalBufferSize = 32767; } diff --git a/Emby.Server.Implementations/IO/ManagedFileSystem.cs b/Emby.Server.Implementations/IO/ManagedFileSystem.cs index 125d9e980f..c8e4031a90 100644 --- a/Emby.Server.Implementations/IO/ManagedFileSystem.cs +++ b/Emby.Server.Implementations/IO/ManagedFileSystem.cs @@ -473,6 +473,11 @@ namespace Emby.Server.Implementations.IO public void SetHidden(string path, bool isHidden) { + if (_environmentInfo.OperatingSystem != MediaBrowser.Model.System.OperatingSystem.Windows) + { + return; + } + if (_sharpCifsFileSystem.IsEnabledForPath(path)) { _sharpCifsFileSystem.SetHidden(path, isHidden); @@ -498,6 +503,11 @@ namespace Emby.Server.Implementations.IO public void SetReadOnly(string path, bool isReadOnly) { + if (_environmentInfo.OperatingSystem != MediaBrowser.Model.System.OperatingSystem.Windows) + { + return; + } + if (_sharpCifsFileSystem.IsEnabledForPath(path)) { _sharpCifsFileSystem.SetReadOnly(path, isReadOnly); @@ -523,6 +533,11 @@ namespace Emby.Server.Implementations.IO public void SetAttributes(string path, bool isHidden, bool isReadOnly) { + if (_environmentInfo.OperatingSystem != MediaBrowser.Model.System.OperatingSystem.Windows) + { + return; + } + if (_sharpCifsFileSystem.IsEnabledForPath(path)) { _sharpCifsFileSystem.SetAttributes(path, isHidden, isReadOnly); diff --git a/Emby.Server.Implementations/Library/LibraryManager.cs b/Emby.Server.Implementations/Library/LibraryManager.cs index f71e2714ac..2934a51479 100644 --- a/Emby.Server.Implementations/Library/LibraryManager.cs +++ b/Emby.Server.Implementations/Library/LibraryManager.cs @@ -443,7 +443,7 @@ namespace Emby.Server.Implementations.Library BaseItem removed; _libraryItemsCache.TryRemove(item.Id, out removed); - ReportItemRemoved(item); + ReportItemRemoved(item, parent); } private IEnumerable GetMetadataPaths(BaseItem item, IEnumerable children) @@ -1804,7 +1804,7 @@ namespace Emby.Server.Implementations.Library /// Task. public void CreateItem(BaseItem item, CancellationToken cancellationToken) { - CreateItems(new[] { item }, cancellationToken); + CreateItems(new[] { item }, item.GetParent(), cancellationToken); } /// @@ -1813,7 +1813,7 @@ namespace Emby.Server.Implementations.Library /// The items. /// The cancellation token. /// Task. - public void CreateItems(IEnumerable items, CancellationToken cancellationToken) + public void CreateItems(IEnumerable items, BaseItem parent, CancellationToken cancellationToken) { var list = items.ToList(); @@ -1830,7 +1830,11 @@ namespace Emby.Server.Implementations.Library { try { - ItemAdded(this, new ItemChangeEventArgs { Item = item }); + ItemAdded(this, new ItemChangeEventArgs + { + Item = item, + Parent = parent ?? item.GetParent() + }); } catch (Exception ex) { @@ -1878,6 +1882,7 @@ namespace Emby.Server.Implementations.Library ItemUpdated(this, new ItemChangeEventArgs { Item = item, + Parent = item.GetParent(), UpdateReason = updateReason }); } @@ -1892,13 +1897,17 @@ namespace Emby.Server.Implementations.Library /// Reports the item removed. /// /// The item. - public void ReportItemRemoved(BaseItem item) + public void ReportItemRemoved(BaseItem item, BaseItem parent) { if (ItemRemoved != null) { try { - ItemRemoved(this, new ItemChangeEventArgs { Item = item }); + ItemRemoved(this, new ItemChangeEventArgs + { + Item = item, + Parent = parent + }); } catch (Exception ex) { diff --git a/Emby.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs b/Emby.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs index a4c5645e74..35d2d3c0ab 100644 --- a/Emby.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs +++ b/Emby.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs @@ -1512,6 +1512,8 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV } } + DeleteFileIfEmpty(recordPath); + TriggerRefresh(recordPath); _libraryMonitor.ReportFileSystemChangeComplete(recordPath, false); @@ -1542,6 +1544,23 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV } } + private void DeleteFileIfEmpty(string path) + { + var file = _fileSystem.GetFileInfo(path); + + if (file.Exists && file.Length == 0) + { + try + { + _fileSystem.DeleteFile(path); + } + catch (Exception ex) + { + _logger.ErrorException("Error deleting 0-byte failed recording file {0}", ex, path); + } + } + } + private void TriggerRefresh(string path) { _logger.Info("Triggering refresh on {0}", path); diff --git a/Emby.Server.Implementations/LiveTv/LiveTvManager.cs b/Emby.Server.Implementations/LiveTv/LiveTvManager.cs index 7e72d1b1a1..7e27877e7c 100644 --- a/Emby.Server.Implementations/LiveTv/LiveTvManager.cs +++ b/Emby.Server.Implementations/LiveTv/LiveTvManager.cs @@ -1421,7 +1421,7 @@ namespace Emby.Server.Implementations.LiveTv if (newPrograms.Count > 0) { - _libraryManager.CreateItems(newPrograms, cancellationToken); + _libraryManager.CreateItems(newPrograms, null, cancellationToken); } // TODO: Do this in bulk diff --git a/MediaBrowser.Controller/Entities/BaseItem.cs b/MediaBrowser.Controller/Entities/BaseItem.cs index f6a8f1d5a4..98899253e1 100644 --- a/MediaBrowser.Controller/Entities/BaseItem.cs +++ b/MediaBrowser.Controller/Entities/BaseItem.cs @@ -2236,7 +2236,7 @@ namespace MediaBrowser.Controller.Entities } var filename = System.IO.Path.GetFileNameWithoutExtension(Path); - var extensions = new List { ".nfo", ".xml", ".srt" }; + var extensions = new List { ".nfo", ".xml", ".srt", ".vtt", ".sub", ".idx", ".txt", ".edl" }; extensions.AddRange(SupportedImageExtensions); return FileSystem.GetFiles(FileSystem.GetDirectoryName(Path), extensions.ToArray(extensions.Count), false, false) diff --git a/MediaBrowser.Controller/Entities/Folder.cs b/MediaBrowser.Controller/Entities/Folder.cs index 504d03a276..08b6a123d9 100644 --- a/MediaBrowser.Controller/Entities/Folder.cs +++ b/MediaBrowser.Controller/Entities/Folder.cs @@ -466,11 +466,11 @@ namespace MediaBrowser.Controller.Entities item.SetParent(null); await LibraryManager.DeleteItem(item, new DeleteOptions { DeleteFileLocation = false }).ConfigureAwait(false); - LibraryManager.ReportItemRemoved(item); + LibraryManager.ReportItemRemoved(item, this); } } - LibraryManager.CreateItems(newItems, cancellationToken); + LibraryManager.CreateItems(newItems, this, cancellationToken); } } else diff --git a/MediaBrowser.Controller/Library/ILibraryManager.cs b/MediaBrowser.Controller/Library/ILibraryManager.cs index 37e0d56616..9ef372eb66 100644 --- a/MediaBrowser.Controller/Library/ILibraryManager.cs +++ b/MediaBrowser.Controller/Library/ILibraryManager.cs @@ -195,16 +195,12 @@ namespace MediaBrowser.Controller.Library /// /// Creates the item. /// - /// The item. - /// The cancellation token. void CreateItem(BaseItem item, CancellationToken cancellationToken); /// /// Creates the items. /// - /// The items. - /// The cancellation token. - void CreateItems(IEnumerable items, CancellationToken cancellationToken); + void CreateItems(IEnumerable items, BaseItem parent, CancellationToken cancellationToken); /// /// Updates the item. @@ -237,8 +233,7 @@ namespace MediaBrowser.Controller.Library /// /// Reports the item removed. /// - /// The item. - void ReportItemRemoved(BaseItem item); + void ReportItemRemoved(BaseItem item, BaseItem parent); /// /// Finds the type of the collection. diff --git a/MediaBrowser.Controller/Library/ItemChangeEventArgs.cs b/MediaBrowser.Controller/Library/ItemChangeEventArgs.cs index a2951f548e..e671490d3c 100644 --- a/MediaBrowser.Controller/Library/ItemChangeEventArgs.cs +++ b/MediaBrowser.Controller/Library/ItemChangeEventArgs.cs @@ -13,6 +13,8 @@ namespace MediaBrowser.Controller.Library /// The item. public BaseItem Item { get; set; } + public BaseItem Parent { get; set; } + /// /// Gets or sets the item. /// diff --git a/MediaBrowser.Model/Entities/LibraryUpdateInfo.cs b/MediaBrowser.Model/Entities/LibraryUpdateInfo.cs index b3d3be70e8..8995e08883 100644 --- a/MediaBrowser.Model/Entities/LibraryUpdateInfo.cs +++ b/MediaBrowser.Model/Entities/LibraryUpdateInfo.cs @@ -35,6 +35,8 @@ namespace MediaBrowser.Model.Entities /// The items updated. public string[] ItemsUpdated { get; set; } + public string[] CollectionFolders { get; set; } + /// /// Initializes a new instance of the class. /// @@ -45,6 +47,7 @@ namespace MediaBrowser.Model.Entities ItemsAdded = new string[] { }; ItemsRemoved = new string[] { }; ItemsUpdated = new string[] { }; + CollectionFolders = new string[] { }; } } } diff --git a/SharedVersion.cs b/SharedVersion.cs index 463ec3ae3c..90e6929e2a 100644 --- a/SharedVersion.cs +++ b/SharedVersion.cs @@ -1,3 +1,3 @@ using System.Reflection; -[assembly: AssemblyVersion("3.2.40.2")] +[assembly: AssemblyVersion("3.2.40.3")] -- cgit v1.2.3 From d06532c6029592e8fe1c0564b9286f086f438a7b Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Mon, 27 Nov 2017 14:09:51 -0500 Subject: update rules for samples --- .../Library/CoreResolutionIgnoreRule.cs | 11 ----------- .../Library/Resolvers/Movies/MovieResolver.cs | 20 -------------------- 2 files changed, 31 deletions(-) (limited to 'Emby.Server.Implementations/Library') diff --git a/Emby.Server.Implementations/Library/CoreResolutionIgnoreRule.cs b/Emby.Server.Implementations/Library/CoreResolutionIgnoreRule.cs index 961f9886c1..5c3e1dab1a 100644 --- a/Emby.Server.Implementations/Library/CoreResolutionIgnoreRule.cs +++ b/Emby.Server.Implementations/Library/CoreResolutionIgnoreRule.cs @@ -141,17 +141,6 @@ namespace Emby.Server.Implementations.Library return true; } } - - // Ignore samples - var sampleFilename = " " + filename.Replace(".", " ", StringComparison.OrdinalIgnoreCase) - .Replace("-", " ", StringComparison.OrdinalIgnoreCase) - .Replace("_", " ", StringComparison.OrdinalIgnoreCase) - .Replace("!", " ", StringComparison.OrdinalIgnoreCase); - - if (sampleFilename.IndexOf(" sample ", StringComparison.OrdinalIgnoreCase) != -1) - { - return true; - } } return false; diff --git a/Emby.Server.Implementations/Library/Resolvers/Movies/MovieResolver.cs b/Emby.Server.Implementations/Library/Resolvers/Movies/MovieResolver.cs index 6676164142..d74235ec7b 100644 --- a/Emby.Server.Implementations/Library/Resolvers/Movies/MovieResolver.cs +++ b/Emby.Server.Implementations/Library/Resolvers/Movies/MovieResolver.cs @@ -125,10 +125,6 @@ namespace Emby.Server.Implementations.Library.Resolvers.Movies if (child.IsDirectory) { leftOver.Add(child); - } - else if (IsIgnored(child.Name)) - { - } else { @@ -298,22 +294,6 @@ namespace Emby.Server.Implementations.Library.Resolvers.Movies return item; } - private bool IsIgnored(string filename) - { - // Ignore samples - var sampleFilename = " " + filename.Replace(".", " ", StringComparison.OrdinalIgnoreCase) - .Replace("-", " ", StringComparison.OrdinalIgnoreCase) - .Replace("_", " ", StringComparison.OrdinalIgnoreCase) - .Replace("!", " ", StringComparison.OrdinalIgnoreCase); - - if (sampleFilename.IndexOf(" sample ", StringComparison.OrdinalIgnoreCase) != -1) - { - return true; - } - - return false; - } - /// /// Sets the initial item values. /// -- cgit v1.2.3