From 8ef442c2e8f39307f72bc98d6c79a9b5f09e6d72 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Thu, 3 Nov 2016 18:53:02 -0400 Subject: move classes --- .../TV/SeriesPostScanTask.cs | 241 +++++++++++++++++++++ 1 file changed, 241 insertions(+) create mode 100644 Emby.Server.Implementations/TV/SeriesPostScanTask.cs (limited to 'Emby.Server.Implementations/TV/SeriesPostScanTask.cs') diff --git a/Emby.Server.Implementations/TV/SeriesPostScanTask.cs b/Emby.Server.Implementations/TV/SeriesPostScanTask.cs new file mode 100644 index 0000000000..2e04c883fa --- /dev/null +++ b/Emby.Server.Implementations/TV/SeriesPostScanTask.cs @@ -0,0 +1,241 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; +using MediaBrowser.Controller.Configuration; +using MediaBrowser.Controller.Entities; +using MediaBrowser.Controller.Entities.TV; +using MediaBrowser.Controller.Library; +using MediaBrowser.Controller.Plugins; +using MediaBrowser.Controller.Providers; +using MediaBrowser.Model.Entities; +using MediaBrowser.Model.Globalization; +using MediaBrowser.Model.IO; +using MediaBrowser.Model.Logging; +using MediaBrowser.Model.Tasks; +using MediaBrowser.Model.Threading; +using MediaBrowser.Model.Xml; +using MediaBrowser.Providers.TV; + +namespace Emby.Server.Implementations.TV +{ + class SeriesGroup : List, IGrouping + { + public string Key { get; set; } + } + + class SeriesPostScanTask : ILibraryPostScanTask, IHasOrder + { + /// + /// The _library manager + /// + private readonly ILibraryManager _libraryManager; + private readonly IServerConfigurationManager _config; + private readonly ILogger _logger; + private readonly ILocalizationManager _localization; + private readonly IFileSystem _fileSystem; + private readonly IXmlReaderSettingsFactory _xmlSettings; + + public SeriesPostScanTask(ILibraryManager libraryManager, ILogger logger, IServerConfigurationManager config, ILocalizationManager localization, IFileSystem fileSystem, IXmlReaderSettingsFactory xmlSettings) + { + _libraryManager = libraryManager; + _logger = logger; + _config = config; + _localization = localization; + _fileSystem = fileSystem; + _xmlSettings = xmlSettings; + } + + public Task Run(IProgress progress, CancellationToken cancellationToken) + { + return RunInternal(progress, cancellationToken); + } + + private Task RunInternal(IProgress progress, CancellationToken cancellationToken) + { + var seriesList = _libraryManager.GetItemList(new InternalItemsQuery() + { + IncludeItemTypes = new[] { typeof(Series).Name }, + Recursive = true, + GroupByPresentationUniqueKey = false + + }).Cast().ToList(); + + var seriesGroups = FindSeriesGroups(seriesList).Where(g => !string.IsNullOrEmpty(g.Key)).ToList(); + + return new MissingEpisodeProvider(_logger, _config, _libraryManager, _localization, _fileSystem, _xmlSettings).Run(seriesGroups, true, cancellationToken); + } + + internal static IEnumerable> FindSeriesGroups(List seriesList) + { + var links = seriesList.ToDictionary(s => s, s => seriesList.Where(c => c != s && ShareProviderId(s, c)).ToList()); + + var visited = new HashSet(); + + foreach (var series in seriesList) + { + if (!visited.Contains(series)) + { + var group = new SeriesGroup(); + FindAllLinked(series, visited, links, group); + + group.Key = group.Select(s => s.GetProviderId(MetadataProviders.Tvdb)).FirstOrDefault(id => !string.IsNullOrEmpty(id)); + + yield return group; + } + } + } + + private static void FindAllLinked(Series series, HashSet visited, IDictionary> linksMap, List results) + { + results.Add(series); + visited.Add(series); + + var links = linksMap[series]; + + foreach (var s in links) + { + if (!visited.Contains(s)) + { + FindAllLinked(s, visited, linksMap, results); + } + } + } + + private static bool ShareProviderId(Series a, Series b) + { + return a.ProviderIds.Any(id => + { + string value; + return b.ProviderIds.TryGetValue(id.Key, out value) && id.Value == value; + }); + } + + public int Order + { + get + { + // Run after tvdb update task + return 1; + } + } + } + + public class CleanMissingEpisodesEntryPoint : IServerEntryPoint + { + private readonly ILibraryManager _libraryManager; + private readonly IServerConfigurationManager _config; + private readonly ILogger _logger; + private readonly ILocalizationManager _localization; + private readonly IFileSystem _fileSystem; + private readonly object _libraryChangedSyncLock = new object(); + private const int LibraryUpdateDuration = 180000; + private readonly ITaskManager _taskManager; + private readonly IXmlReaderSettingsFactory _xmlSettings; + private readonly ITimerFactory _timerFactory; + + public CleanMissingEpisodesEntryPoint(ILibraryManager libraryManager, IServerConfigurationManager config, ILogger logger, ILocalizationManager localization, IFileSystem fileSystem, ITaskManager taskManager, IXmlReaderSettingsFactory xmlSettings, ITimerFactory timerFactory) + { + _libraryManager = libraryManager; + _config = config; + _logger = logger; + _localization = localization; + _fileSystem = fileSystem; + _taskManager = taskManager; + _xmlSettings = xmlSettings; + _timerFactory = timerFactory; + } + + private ITimer LibraryUpdateTimer { get; set; } + + public void Run() + { + _libraryManager.ItemAdded += _libraryManager_ItemAdded; + } + + private void _libraryManager_ItemAdded(object sender, ItemChangeEventArgs e) + { + if (!FilterItem(e.Item)) + { + return; + } + + lock (_libraryChangedSyncLock) + { + if (LibraryUpdateTimer == null) + { + LibraryUpdateTimer = _timerFactory.Create(LibraryUpdateTimerCallback, null, LibraryUpdateDuration, Timeout.Infinite); + } + else + { + LibraryUpdateTimer.Change(LibraryUpdateDuration, Timeout.Infinite); + } + } + } + + private async void LibraryUpdateTimerCallback(object state) + { + try + { + if (MissingEpisodeProvider.IsRunning) + { + return; + } + + if (_libraryManager.IsScanRunning) + { + return; + } + + var seriesList = _libraryManager.GetItemList(new InternalItemsQuery() + { + IncludeItemTypes = new[] { typeof(Series).Name }, + Recursive = true, + GroupByPresentationUniqueKey = false + + }).Cast().ToList(); + + var seriesGroups = SeriesPostScanTask.FindSeriesGroups(seriesList).Where(g => !string.IsNullOrEmpty(g.Key)).ToList(); + + await new MissingEpisodeProvider(_logger, _config, _libraryManager, _localization, _fileSystem, _xmlSettings) + .Run(seriesGroups, false, CancellationToken.None).ConfigureAwait(false); + } + catch (Exception ex) + { + _logger.ErrorException("Error in SeriesPostScanTask", ex); + } + } + + private bool FilterItem(BaseItem item) + { + return item is Episode && item.LocationType != LocationType.Virtual; + } + + /// + /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. + /// + public void Dispose() + { + Dispose(true); + } + + /// + /// Releases unmanaged and - optionally - managed resources. + /// + /// true to release both managed and unmanaged resources; false to release only unmanaged resources. + protected virtual void Dispose(bool dispose) + { + if (dispose) + { + if (LibraryUpdateTimer != null) + { + LibraryUpdateTimer.Dispose(); + LibraryUpdateTimer = null; + } + + _libraryManager.ItemAdded -= _libraryManager_ItemAdded; + } + } + } +} -- cgit v1.2.3 From c0491fb56348c63d78b1f694f574e963f9526a9a Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Tue, 15 Nov 2016 14:42:43 -0500 Subject: rework genre views --- Emby.Dlna/Main/DlnaEntryPoint.cs | 2 +- .../TV/SeriesPostScanTask.cs | 8 +-- MediaBrowser.Providers/Omdb/OmdbProvider.cs | 78 +++++++++++----------- .../TV/MissingEpisodeProvider.cs | 2 +- .../Native/RegisterServer.bat | 3 + 5 files changed, 46 insertions(+), 47 deletions(-) (limited to 'Emby.Server.Implementations/TV/SeriesPostScanTask.cs') diff --git a/Emby.Dlna/Main/DlnaEntryPoint.cs b/Emby.Dlna/Main/DlnaEntryPoint.cs index 49bb9a74f2..170b4cee0e 100644 --- a/Emby.Dlna/Main/DlnaEntryPoint.cs +++ b/Emby.Dlna/Main/DlnaEntryPoint.cs @@ -285,7 +285,7 @@ namespace Emby.Dlna.Main { "urn:schemas-upnp-org:service:ContentDirectory:1", "urn:schemas-upnp-org:service:ConnectionManager:1", - "urn:microsoft.com:service:X_MS_MediaReceiverRegistrar:1" + //"urn:microsoft.com:service:X_MS_MediaReceiverRegistrar:1" }; foreach (var subDevice in embeddedDevices) diff --git a/Emby.Server.Implementations/TV/SeriesPostScanTask.cs b/Emby.Server.Implementations/TV/SeriesPostScanTask.cs index 2e04c883fa..3d93561f17 100644 --- a/Emby.Server.Implementations/TV/SeriesPostScanTask.cs +++ b/Emby.Server.Implementations/TV/SeriesPostScanTask.cs @@ -80,7 +80,7 @@ namespace Emby.Server.Implementations.TV var group = new SeriesGroup(); FindAllLinked(series, visited, links, group); - group.Key = group.Select(s => s.GetProviderId(MetadataProviders.Tvdb)).FirstOrDefault(id => !string.IsNullOrEmpty(id)); + group.Key = group.Select(s => s.PresentationUniqueKey).FirstOrDefault(id => !string.IsNullOrEmpty(id)); yield return group; } @@ -105,11 +105,7 @@ namespace Emby.Server.Implementations.TV private static bool ShareProviderId(Series a, Series b) { - return a.ProviderIds.Any(id => - { - string value; - return b.ProviderIds.TryGetValue(id.Key, out value) && id.Value == value; - }); + return string.Equals(a.PresentationUniqueKey, b.PresentationUniqueKey, StringComparison.Ordinal); } public int Order diff --git a/MediaBrowser.Providers/Omdb/OmdbProvider.cs b/MediaBrowser.Providers/Omdb/OmdbProvider.cs index d838de1395..721e31b07e 100644 --- a/MediaBrowser.Providers/Omdb/OmdbProvider.cs +++ b/MediaBrowser.Providers/Omdb/OmdbProvider.cs @@ -37,7 +37,7 @@ namespace MediaBrowser.Providers.Omdb } public async Task Fetch(MetadataResult itemResult, string imdbId, string language, string country, CancellationToken cancellationToken) - where T :BaseItem + where T : BaseItem { if (string.IsNullOrWhiteSpace(imdbId)) { @@ -48,25 +48,25 @@ namespace MediaBrowser.Providers.Omdb var result = await GetRootObject(imdbId, cancellationToken); - // Only take the name and rating if the user's language is set to english, since Omdb has no localization - if (string.Equals(language, "en", StringComparison.OrdinalIgnoreCase)) - { - item.Name = result.Title; + // Only take the name and rating if the user's language is set to english, since Omdb has no localization + if (string.Equals(language, "en", StringComparison.OrdinalIgnoreCase)) + { + item.Name = result.Title; - if (string.Equals(country, "us", StringComparison.OrdinalIgnoreCase)) - { - item.OfficialRating = result.Rated; - } + if (string.Equals(country, "us", StringComparison.OrdinalIgnoreCase)) + { + item.OfficialRating = result.Rated; } + } - int year; + int year; - if (!string.IsNullOrEmpty(result.Year) && result.Year.Length >= 4 - && int.TryParse(result.Year.Substring(0, 4), NumberStyles.Number, _usCulture, out year) - && year >= 0) - { - item.ProductionYear = year; - } + if (!string.IsNullOrEmpty(result.Year) && result.Year.Length >= 4 + && int.TryParse(result.Year.Substring(0, 4), NumberStyles.Number, _usCulture, out year) + && year >= 0) + { + item.ProductionYear = year; + } // Seeing some bogus RT data on omdb for series, so filter it out here // RT doesn't even have tv series @@ -87,33 +87,33 @@ namespace MediaBrowser.Providers.Omdb int voteCount; - if (!string.IsNullOrEmpty(result.imdbVotes) - && int.TryParse(result.imdbVotes, NumberStyles.Number, _usCulture, out voteCount) - && voteCount >= 0) - { - item.VoteCount = voteCount; - } + if (!string.IsNullOrEmpty(result.imdbVotes) + && int.TryParse(result.imdbVotes, NumberStyles.Number, _usCulture, out voteCount) + && voteCount >= 0) + { + item.VoteCount = voteCount; + } - float imdbRating; + float imdbRating; - if (!string.IsNullOrEmpty(result.imdbRating) - && float.TryParse(result.imdbRating, NumberStyles.Any, _usCulture, out imdbRating) - && imdbRating >= 0) - { - item.CommunityRating = imdbRating; - } + if (!string.IsNullOrEmpty(result.imdbRating) + && float.TryParse(result.imdbRating, NumberStyles.Any, _usCulture, out imdbRating) + && imdbRating >= 0) + { + item.CommunityRating = imdbRating; + } - if (!string.IsNullOrEmpty(result.Website)) - { - item.HomePageUrl = result.Website; - } + if (!string.IsNullOrEmpty(result.Website)) + { + item.HomePageUrl = result.Website; + } - if (!string.IsNullOrWhiteSpace(result.imdbID)) - { - item.SetProviderId(MetadataProviders.Imdb, result.imdbID); - } + if (!string.IsNullOrWhiteSpace(result.imdbID)) + { + item.SetProviderId(MetadataProviders.Imdb, result.imdbID); + } - ParseAdditionalMetadata(itemResult, result); + ParseAdditionalMetadata(itemResult, result); } public async Task FetchEpisodeData(MetadataResult itemResult, int episodeNumber, int seasonNumber, string imdbId, string language, string country, CancellationToken cancellationToken) @@ -135,7 +135,7 @@ namespace MediaBrowser.Providers.Omdb RootObject result = null; - foreach (var episode in seasonResult.Episodes) + foreach (var episode in (seasonResult.Episodes ?? new RootObject[] { })) { if (episode.Episode == episodeNumber) { diff --git a/MediaBrowser.Providers/TV/MissingEpisodeProvider.cs b/MediaBrowser.Providers/TV/MissingEpisodeProvider.cs index 3c1bc21183..c93b6c2fd6 100644 --- a/MediaBrowser.Providers/TV/MissingEpisodeProvider.cs +++ b/MediaBrowser.Providers/TV/MissingEpisodeProvider.cs @@ -368,7 +368,7 @@ namespace MediaBrowser.Providers.TV var seasonNumber = i.Season.IndexNumber.Value + i.SeasonOffset; // If there's a physical season with the same number, delete it - if (physicalSeasons.Any(p => p.Season.IndexNumber.HasValue && (p.Season.IndexNumber.Value + p.SeasonOffset) == seasonNumber)) + if (physicalSeasons.Any(p => p.Season.IndexNumber.HasValue && (p.Season.IndexNumber.Value + p.SeasonOffset) == seasonNumber && string.Equals(p.Season.Series.PresentationUniqueKey, i.Season.Series.PresentationUniqueKey, StringComparison.Ordinal))) { return true; } diff --git a/MediaBrowser.ServerApplication/Native/RegisterServer.bat b/MediaBrowser.ServerApplication/Native/RegisterServer.bat index 85baa0d03a..504df21995 100644 --- a/MediaBrowser.ServerApplication/Native/RegisterServer.bat +++ b/MediaBrowser.ServerApplication/Native/RegisterServer.bat @@ -26,6 +26,9 @@ netsh advfirewall firewall delete rule name="Emby Server" netsh advfirewall firewall add rule name="Emby Server" dir=in action=allow protocol=TCP program=%4 enable=yes netsh advfirewall firewall add rule name="Emby Server" dir=in action=allow protocol=UDP program=%4 enable=yes +netsh advfirewall firewall add rule name="mediabrowser.serverapplication.exe" dir=in action=allow protocol=TCP program=%4 enable=yes +netsh advfirewall firewall add rule name="mediabrowser.serverapplication.exe" dir=in action=allow protocol=UDP program=%4 enable=yes + :DONE Exit \ No newline at end of file -- cgit v1.2.3