diff options
54 files changed, 615 insertions, 582 deletions
diff --git a/MediaBrowser.Api/ItemUpdateService.cs b/MediaBrowser.Api/ItemUpdateService.cs index 2778cfe29c..cda7ce0c67 100644 --- a/MediaBrowser.Api/ItemUpdateService.cs +++ b/MediaBrowser.Api/ItemUpdateService.cs @@ -70,12 +70,13 @@ namespace MediaBrowser.Api Cultures = _localizationManager.GetCultures().ToList() }; - if (!item.IsVirtualItem && !(item is ICollectionFolder) && !(item is UserView) && !(item is AggregateFolder) && !(item is LiveTvChannel) && !(item is IItemByName)) + if (!item.IsVirtualItem && !(item is ICollectionFolder) && !(item is UserView) && !(item is AggregateFolder) && !(item is LiveTvChannel) && !(item is IItemByName) && + item.SourceType == SourceType.Library) { var inheritedContentType = _libraryManager.GetInheritedContentType(item); var configuredContentType = _libraryManager.GetConfiguredContentType(item); - if (string.IsNullOrWhiteSpace(inheritedContentType) || string.Equals(inheritedContentType, CollectionType.TvShows, StringComparison.OrdinalIgnoreCase) || !string.IsNullOrWhiteSpace(configuredContentType)) + if (string.IsNullOrWhiteSpace(inheritedContentType) || !string.IsNullOrWhiteSpace(configuredContentType)) { info.ContentTypeOptions = GetContentTypeOptions(true); info.ContentType = configuredContentType; diff --git a/MediaBrowser.Controller/IServerApplicationHost.cs b/MediaBrowser.Controller/IServerApplicationHost.cs index f4c0e76581..d6744e8043 100644 --- a/MediaBrowser.Controller/IServerApplicationHost.cs +++ b/MediaBrowser.Controller/IServerApplicationHost.cs @@ -89,5 +89,7 @@ namespace MediaBrowser.Controller string GetLocalApiUrl(IPAddress ipAddress); void LaunchUrl(string url); + + void EnableLoopback(string appName); } } diff --git a/MediaBrowser.Controller/Providers/BaseItemXmlParser.cs b/MediaBrowser.Controller/Providers/BaseItemXmlParser.cs index 75da3b67a5..4484adb1db 100644 --- a/MediaBrowser.Controller/Providers/BaseItemXmlParser.cs +++ b/MediaBrowser.Controller/Providers/BaseItemXmlParser.cs @@ -23,14 +23,18 @@ namespace MediaBrowser.Controller.Providers /// The logger /// </summary> protected ILogger Logger { get; private set; } + protected IProviderManager ProviderManager { get; private set; } + + private Dictionary<string, string> _validProviderIds; /// <summary> /// Initializes a new instance of the <see cref="BaseItemXmlParser{T}" /> class. /// </summary> /// <param name="logger">The logger.</param> - public BaseItemXmlParser(ILogger logger) + public BaseItemXmlParser(ILogger logger, IProviderManager providerManager) { Logger = logger; + ProviderManager = providerManager; } /// <summary> @@ -60,6 +64,22 @@ namespace MediaBrowser.Controller.Providers ValidationType = ValidationType.None }; + _validProviderIds = _validProviderIds = new Dictionary<string, string>(StringComparer.InvariantCultureIgnoreCase); + + var idInfos = ProviderManager.GetExternalIdInfos(item.Item); + + foreach (var info in idInfos) + { + var id = info.Key + "Id"; + if (!_validProviderIds.ContainsKey(id)) + { + _validProviderIds.Add(id, info.Key); + } + } + + //Additional Mappings + _validProviderIds.Add("IMDB", "Imdb"); + //Fetch(item, metadataFile, settings, Encoding.GetEncoding("ISO-8859-1"), cancellationToken); Fetch(item, metadataFile, settings, Encoding.UTF8, cancellationToken); } @@ -657,14 +677,6 @@ namespace MediaBrowser.Controller.Providers break; } - case "TvDbId": - var tvdbId = reader.ReadElementContentAsString(); - if (!string.IsNullOrWhiteSpace(tvdbId)) - { - item.SetProviderId(MetadataProviders.Tvdb, tvdbId); - } - break; - case "VoteCount": { var val = reader.ReadElementContentAsString(); @@ -679,95 +691,6 @@ namespace MediaBrowser.Controller.Providers } break; } - case "MusicBrainzAlbumId": - { - var mbz = reader.ReadElementContentAsString(); - if (!string.IsNullOrWhiteSpace(mbz)) - { - item.SetProviderId(MetadataProviders.MusicBrainzAlbum, mbz); - } - break; - } - case "MusicBrainzAlbumArtistId": - { - var mbz = reader.ReadElementContentAsString(); - if (!string.IsNullOrWhiteSpace(mbz)) - { - item.SetProviderId(MetadataProviders.MusicBrainzAlbumArtist, mbz); - } - break; - } - case "MusicBrainzArtistId": - { - var mbz = reader.ReadElementContentAsString(); - if (!string.IsNullOrWhiteSpace(mbz)) - { - item.SetProviderId(MetadataProviders.MusicBrainzArtist, mbz); - } - break; - } - case "MusicBrainzReleaseGroupId": - { - var mbz = reader.ReadElementContentAsString(); - if (!string.IsNullOrWhiteSpace(mbz)) - { - item.SetProviderId(MetadataProviders.MusicBrainzReleaseGroup, mbz); - } - break; - } - case "TVRageId": - { - var id = reader.ReadElementContentAsString(); - if (!string.IsNullOrWhiteSpace(id)) - { - item.SetProviderId(MetadataProviders.TvRage, id); - } - break; - } - case "TvMazeId": - { - var id = reader.ReadElementContentAsString(); - if (!string.IsNullOrWhiteSpace(id)) - { - item.SetProviderId(MetadataProviders.TvMaze, id); - } - break; - } - case "AudioDbArtistId": - { - var id = reader.ReadElementContentAsString(); - if (!string.IsNullOrWhiteSpace(id)) - { - item.SetProviderId(MetadataProviders.AudioDbArtist, id); - } - break; - } - case "AudioDbAlbumId": - { - var id = reader.ReadElementContentAsString(); - if (!string.IsNullOrWhiteSpace(id)) - { - item.SetProviderId(MetadataProviders.AudioDbAlbum, id); - } - break; - } - case "RottenTomatoesId": - var rtId = reader.ReadElementContentAsString(); - if (!string.IsNullOrWhiteSpace(rtId)) - { - item.SetProviderId(MetadataProviders.RottenTomatoes, rtId); - } - break; - - case "TMDbId": - var tmdb = reader.ReadElementContentAsString(); - if (!string.IsNullOrWhiteSpace(tmdb)) - { - item.SetProviderId(MetadataProviders.Tmdb, tmdb); - } - break; - - case "TMDbCollectionId": case "CollectionNumber": var tmdbCollection = reader.ReadElementContentAsString(); if (!string.IsNullOrWhiteSpace(tmdbCollection)) @@ -776,30 +699,6 @@ namespace MediaBrowser.Controller.Providers } break; - case "TVcomId": - var TVcomId = reader.ReadElementContentAsString(); - if (!string.IsNullOrWhiteSpace(TVcomId)) - { - item.SetProviderId(MetadataProviders.Tvcom, TVcomId); - } - break; - - case "Zap2ItId": - var zap2ItId = reader.ReadElementContentAsString(); - if (!string.IsNullOrWhiteSpace(zap2ItId)) - { - item.SetProviderId(MetadataProviders.Zap2It, zap2ItId); - } - break; - - case "IMDB": - var imDbId = reader.ReadElementContentAsString(); - if (!string.IsNullOrWhiteSpace(imDbId)) - { - item.SetProviderId(MetadataProviders.Imdb, imDbId); - } - break; - case "Genres": { using (var subtree = reader.ReadSubtree()) @@ -891,7 +790,19 @@ namespace MediaBrowser.Controller.Providers } default: - reader.Skip(); + if (_validProviderIds.ContainsKey(reader.Name)) + { + var id = reader.ReadElementContentAsString(); + if (!string.IsNullOrWhiteSpace(id)) + { + item.SetProviderId(_validProviderIds[reader.Name], id); + } + } + else + { + reader.Skip(); + } + break; } } diff --git a/MediaBrowser.LocalMetadata/MediaBrowser.LocalMetadata.csproj b/MediaBrowser.LocalMetadata/MediaBrowser.LocalMetadata.csproj index 134385765a..ac127458e3 100644 --- a/MediaBrowser.LocalMetadata/MediaBrowser.LocalMetadata.csproj +++ b/MediaBrowser.LocalMetadata/MediaBrowser.LocalMetadata.csproj @@ -63,7 +63,6 @@ <Compile Include="Parsers\MovieXmlParser.cs" /> <Compile Include="Parsers\MusicVideoXmlParser.cs" /> <Compile Include="Parsers\PlaylistXmlParser.cs" /> - <Compile Include="Parsers\SeasonXmlParser.cs" /> <Compile Include="Parsers\SeriesXmlParser.cs" /> <Compile Include="Properties\AssemblyInfo.cs" /> <Compile Include="Providers\BoxSetXmlProvider.cs" /> @@ -75,7 +74,6 @@ <Compile Include="Providers\MusicVideoXmlProvider.cs" /> <Compile Include="Providers\PersonXmlProvider.cs" /> <Compile Include="Providers\PlaylistXmlProvider.cs" /> - <Compile Include="Providers\SeasonXmlProvider.cs" /> <Compile Include="Providers\SeriesXmlProvider.cs" /> <Compile Include="Providers\VideoXmlProvider.cs" /> <Compile Include="Savers\BoxSetXmlSaver.cs" /> diff --git a/MediaBrowser.LocalMetadata/Parsers/BoxSetXmlParser.cs b/MediaBrowser.LocalMetadata/Parsers/BoxSetXmlParser.cs index 772af06737..9ebb357c6c 100644 --- a/MediaBrowser.LocalMetadata/Parsers/BoxSetXmlParser.cs +++ b/MediaBrowser.LocalMetadata/Parsers/BoxSetXmlParser.cs @@ -9,8 +9,8 @@ namespace MediaBrowser.LocalMetadata.Parsers { public class BoxSetXmlParser : BaseItemXmlParser<BoxSet> { - public BoxSetXmlParser(ILogger logger) - : base(logger) + public BoxSetXmlParser(ILogger logger, IProviderManager providerManager) + : base(logger, providerManager) { } diff --git a/MediaBrowser.LocalMetadata/Parsers/EpisodeXmlParser.cs b/MediaBrowser.LocalMetadata/Parsers/EpisodeXmlParser.cs index d2ef014653..71f6d3fe9f 100644 --- a/MediaBrowser.LocalMetadata/Parsers/EpisodeXmlParser.cs +++ b/MediaBrowser.LocalMetadata/Parsers/EpisodeXmlParser.cs @@ -20,8 +20,8 @@ namespace MediaBrowser.LocalMetadata.Parsers private List<LocalImageInfo> _imagesFound; private readonly IFileSystem _fileSystem; - public EpisodeXmlParser(ILogger logger, IFileSystem fileSystem) - : base(logger) + public EpisodeXmlParser(ILogger logger, IFileSystem fileSystem, IProviderManager providerManager) + : base(logger, providerManager) { _fileSystem = fileSystem; } diff --git a/MediaBrowser.LocalMetadata/Parsers/GameSystemXmlParser.cs b/MediaBrowser.LocalMetadata/Parsers/GameSystemXmlParser.cs index 09cc1fdd7a..75df539587 100644 --- a/MediaBrowser.LocalMetadata/Parsers/GameSystemXmlParser.cs +++ b/MediaBrowser.LocalMetadata/Parsers/GameSystemXmlParser.cs @@ -10,8 +10,8 @@ namespace MediaBrowser.LocalMetadata.Parsers { public class GameSystemXmlParser : BaseItemXmlParser<GameSystem> { - public GameSystemXmlParser(ILogger logger) - : base(logger) + public GameSystemXmlParser(ILogger logger, IProviderManager providerManager) + : base(logger, providerManager) { } diff --git a/MediaBrowser.LocalMetadata/Parsers/GameXmlParser.cs b/MediaBrowser.LocalMetadata/Parsers/GameXmlParser.cs index 4bfcae44ff..956b8baef9 100644 --- a/MediaBrowser.LocalMetadata/Parsers/GameXmlParser.cs +++ b/MediaBrowser.LocalMetadata/Parsers/GameXmlParser.cs @@ -16,8 +16,8 @@ namespace MediaBrowser.LocalMetadata.Parsers { private readonly CultureInfo _usCulture = new CultureInfo("en-US"); - public GameXmlParser(ILogger logger) - : base(logger) + public GameXmlParser(ILogger logger, IProviderManager providerManager) + : base(logger, providerManager) { } diff --git a/MediaBrowser.LocalMetadata/Parsers/MovieXmlParser.cs b/MediaBrowser.LocalMetadata/Parsers/MovieXmlParser.cs index 1c1bbe71e1..6e78d365ed 100644 --- a/MediaBrowser.LocalMetadata/Parsers/MovieXmlParser.cs +++ b/MediaBrowser.LocalMetadata/Parsers/MovieXmlParser.cs @@ -12,8 +12,8 @@ namespace MediaBrowser.LocalMetadata.Parsers public class BaseVideoXmlParser<T> : BaseItemXmlParser<T> where T : Video { - public BaseVideoXmlParser(ILogger logger) - : base(logger) + public BaseVideoXmlParser(ILogger logger, IProviderManager providerManager) + : base(logger, providerManager) { } @@ -50,15 +50,15 @@ namespace MediaBrowser.LocalMetadata.Parsers public class MovieXmlParser : BaseVideoXmlParser<Movie> { - public MovieXmlParser(ILogger logger) : base(logger) + public MovieXmlParser(ILogger logger, IProviderManager providerManager) : base(logger, providerManager) { } } public class VideoXmlParser : BaseVideoXmlParser<Video> { - public VideoXmlParser(ILogger logger) - : base(logger) + public VideoXmlParser(ILogger logger, IProviderManager providerManager) + : base(logger, providerManager) { } } diff --git a/MediaBrowser.LocalMetadata/Parsers/MusicVideoXmlParser.cs b/MediaBrowser.LocalMetadata/Parsers/MusicVideoXmlParser.cs index d93746aa08..5f0b447e87 100644 --- a/MediaBrowser.LocalMetadata/Parsers/MusicVideoXmlParser.cs +++ b/MediaBrowser.LocalMetadata/Parsers/MusicVideoXmlParser.cs @@ -12,8 +12,8 @@ namespace MediaBrowser.LocalMetadata.Parsers /// Initializes a new instance of the <see cref="BaseItemXmlParser{T}" /> class. /// </summary> /// <param name="logger">The logger.</param> - public MusicVideoXmlParser(ILogger logger) - : base(logger) + public MusicVideoXmlParser(ILogger logger, IProviderManager providerManager) + : base(logger, providerManager) { } diff --git a/MediaBrowser.LocalMetadata/Parsers/PlaylistXmlParser.cs b/MediaBrowser.LocalMetadata/Parsers/PlaylistXmlParser.cs index d4552fe126..de46c0a86d 100644 --- a/MediaBrowser.LocalMetadata/Parsers/PlaylistXmlParser.cs +++ b/MediaBrowser.LocalMetadata/Parsers/PlaylistXmlParser.cs @@ -11,8 +11,8 @@ namespace MediaBrowser.LocalMetadata.Parsers { public class PlaylistXmlParser : BaseItemXmlParser<Playlist> { - public PlaylistXmlParser(ILogger logger) - : base(logger) + public PlaylistXmlParser(ILogger logger, IProviderManager providerManager) + : base(logger, providerManager) { } diff --git a/MediaBrowser.LocalMetadata/Parsers/SeasonXmlParser.cs b/MediaBrowser.LocalMetadata/Parsers/SeasonXmlParser.cs deleted file mode 100644 index 7fd60d3f73..0000000000 --- a/MediaBrowser.LocalMetadata/Parsers/SeasonXmlParser.cs +++ /dev/null @@ -1,48 +0,0 @@ -using System.Xml; -using MediaBrowser.Controller.Entities.TV; -using MediaBrowser.Controller.Providers; -using MediaBrowser.Model.Logging; - -namespace MediaBrowser.LocalMetadata.Parsers -{ - public class SeasonXmlParser : BaseItemXmlParser<Season> - { - public SeasonXmlParser(ILogger logger) - : base(logger) - { - } - - /// <summary> - /// Fetches the data from XML node. - /// </summary> - /// <param name="reader">The reader.</param> - /// <param name="result">The result.</param> - protected override void FetchDataFromXmlNode(XmlReader reader, MetadataResult<Season> result) - { - var item = result.Item; - - switch (reader.Name) - { - case "SeasonNumber": - { - var number = reader.ReadElementContentAsString(); - - if (!string.IsNullOrWhiteSpace(number)) - { - int num; - - if (int.TryParse(number, out num)) - { - item.IndexNumber = num; - } - } - break; - } - - default: - base.FetchDataFromXmlNode(reader, result); - break; - } - } - } -} diff --git a/MediaBrowser.LocalMetadata/Parsers/SeriesXmlParser.cs b/MediaBrowser.LocalMetadata/Parsers/SeriesXmlParser.cs index 8133bd9fec..7b7fb4751b 100644 --- a/MediaBrowser.LocalMetadata/Parsers/SeriesXmlParser.cs +++ b/MediaBrowser.LocalMetadata/Parsers/SeriesXmlParser.cs @@ -17,8 +17,8 @@ namespace MediaBrowser.LocalMetadata.Parsers /// Initializes a new instance of the <see cref="BaseItemXmlParser{T}" /> class. /// </summary> /// <param name="logger">The logger.</param> - public SeriesXmlParser(ILogger logger) - : base(logger) + public SeriesXmlParser(ILogger logger, IProviderManager providerManager) + : base(logger, providerManager) { } diff --git a/MediaBrowser.LocalMetadata/Providers/BoxSetXmlProvider.cs b/MediaBrowser.LocalMetadata/Providers/BoxSetXmlProvider.cs index 217a5f3554..3acb2b74cb 100644 --- a/MediaBrowser.LocalMetadata/Providers/BoxSetXmlProvider.cs +++ b/MediaBrowser.LocalMetadata/Providers/BoxSetXmlProvider.cs @@ -14,16 +14,18 @@ namespace MediaBrowser.LocalMetadata.Providers public class BoxSetXmlProvider : BaseXmlProvider<BoxSet> { private readonly ILogger _logger; + private readonly IProviderManager _providerManager; - public BoxSetXmlProvider(IFileSystem fileSystem, ILogger logger) + public BoxSetXmlProvider(IFileSystem fileSystem, ILogger logger, IProviderManager providerManager) : base(fileSystem) { _logger = logger; + _providerManager = providerManager; } protected override void Fetch(MetadataResult<BoxSet> result, string path, CancellationToken cancellationToken) { - new BoxSetXmlParser(_logger).Fetch(result, path, cancellationToken); + new BoxSetXmlParser(_logger, _providerManager).Fetch(result, path, cancellationToken); } protected override FileSystemMetadata GetXmlFile(ItemInfo info, IDirectoryService directoryService) diff --git a/MediaBrowser.LocalMetadata/Providers/EpisodeXmlProvider.cs b/MediaBrowser.LocalMetadata/Providers/EpisodeXmlProvider.cs index d3e3658389..493df8c6a1 100644 --- a/MediaBrowser.LocalMetadata/Providers/EpisodeXmlProvider.cs +++ b/MediaBrowser.LocalMetadata/Providers/EpisodeXmlProvider.cs @@ -13,11 +13,13 @@ namespace MediaBrowser.LocalMetadata.Providers public class EpisodeXmlProvider : BaseXmlProvider<Episode> { private readonly ILogger _logger; + private readonly IProviderManager _providerManager; - public EpisodeXmlProvider(IFileSystem fileSystem, ILogger logger) + public EpisodeXmlProvider(IFileSystem fileSystem, ILogger logger, IProviderManager providerManager) : base(fileSystem) { _logger = logger; + _providerManager = providerManager; } protected override void Fetch(MetadataResult<Episode> result, string path, CancellationToken cancellationToken) @@ -25,7 +27,7 @@ namespace MediaBrowser.LocalMetadata.Providers var images = new List<LocalImageInfo>(); var chapters = new List<ChapterInfo>(); - new EpisodeXmlParser(_logger, FileSystem).Fetch(result, images, path, cancellationToken); + new EpisodeXmlParser(_logger, FileSystem, _providerManager).Fetch(result, images, path, cancellationToken); result.Images = images; } diff --git a/MediaBrowser.LocalMetadata/Providers/FolderXmlProvider.cs b/MediaBrowser.LocalMetadata/Providers/FolderXmlProvider.cs index 248fad3631..7ac41e5cc0 100644 --- a/MediaBrowser.LocalMetadata/Providers/FolderXmlProvider.cs +++ b/MediaBrowser.LocalMetadata/Providers/FolderXmlProvider.cs @@ -13,16 +13,18 @@ namespace MediaBrowser.LocalMetadata.Providers public class FolderXmlProvider : BaseXmlProvider<Folder> { private readonly ILogger _logger; + private readonly IProviderManager _providerManager; - public FolderXmlProvider(IFileSystem fileSystem, ILogger logger) + public FolderXmlProvider(IFileSystem fileSystem, ILogger logger, IProviderManager providerManager) : base(fileSystem) { _logger = logger; + _providerManager = providerManager; } protected override void Fetch(MetadataResult<Folder> result, string path, CancellationToken cancellationToken) { - new BaseItemXmlParser<Folder>(_logger).Fetch(result, path, cancellationToken); + new BaseItemXmlParser<Folder>(_logger, _providerManager).Fetch(result, path, cancellationToken); } protected override FileSystemMetadata GetXmlFile(ItemInfo info, IDirectoryService directoryService) diff --git a/MediaBrowser.LocalMetadata/Providers/GameSystemXmlProvider.cs b/MediaBrowser.LocalMetadata/Providers/GameSystemXmlProvider.cs index 646fce8055..942befb83d 100644 --- a/MediaBrowser.LocalMetadata/Providers/GameSystemXmlProvider.cs +++ b/MediaBrowser.LocalMetadata/Providers/GameSystemXmlProvider.cs @@ -11,16 +11,18 @@ namespace MediaBrowser.LocalMetadata.Providers public class GameSystemXmlProvider : BaseXmlProvider<GameSystem> { private readonly ILogger _logger; + private readonly IProviderManager _providerManager; - public GameSystemXmlProvider(IFileSystem fileSystem, ILogger logger) + public GameSystemXmlProvider(IFileSystem fileSystem, ILogger logger, IProviderManager providerManager) : base(fileSystem) { _logger = logger; + _providerManager = providerManager; } protected override void Fetch(MetadataResult<GameSystem> result, string path, CancellationToken cancellationToken) { - new GameSystemXmlParser(_logger).Fetch(result, path, cancellationToken); + new GameSystemXmlParser(_logger, _providerManager).Fetch(result, path, cancellationToken); } protected override FileSystemMetadata GetXmlFile(ItemInfo info, IDirectoryService directoryService) diff --git a/MediaBrowser.LocalMetadata/Providers/GameXmlProvider.cs b/MediaBrowser.LocalMetadata/Providers/GameXmlProvider.cs index 28736eddda..c562df7fb2 100644 --- a/MediaBrowser.LocalMetadata/Providers/GameXmlProvider.cs +++ b/MediaBrowser.LocalMetadata/Providers/GameXmlProvider.cs @@ -11,16 +11,18 @@ namespace MediaBrowser.LocalMetadata.Providers public class GameXmlProvider : BaseXmlProvider<Game> { private readonly ILogger _logger; + private readonly IProviderManager _providerManager; - public GameXmlProvider(IFileSystem fileSystem, ILogger logger) + public GameXmlProvider(IFileSystem fileSystem, ILogger logger, IProviderManager providerManager) : base(fileSystem) { _logger = logger; + _providerManager = providerManager; } protected override void Fetch(MetadataResult<Game> result, string path, CancellationToken cancellationToken) { - new GameXmlParser(_logger).Fetch(result, path, cancellationToken); + new GameXmlParser(_logger, _providerManager).Fetch(result, path, cancellationToken); } protected override FileSystemMetadata GetXmlFile(ItemInfo info, IDirectoryService directoryService) diff --git a/MediaBrowser.LocalMetadata/Providers/MovieXmlProvider.cs b/MediaBrowser.LocalMetadata/Providers/MovieXmlProvider.cs index e4f83dd1fc..333ea28230 100644 --- a/MediaBrowser.LocalMetadata/Providers/MovieXmlProvider.cs +++ b/MediaBrowser.LocalMetadata/Providers/MovieXmlProvider.cs @@ -11,16 +11,18 @@ namespace MediaBrowser.LocalMetadata.Providers public class MovieXmlProvider : BaseXmlProvider<Movie> { private readonly ILogger _logger; + private readonly IProviderManager _providerManager; - public MovieXmlProvider(IFileSystem fileSystem, ILogger logger) + public MovieXmlProvider(IFileSystem fileSystem, ILogger logger, IProviderManager providerManager) : base(fileSystem) { _logger = logger; + _providerManager = providerManager; } protected override void Fetch(MetadataResult<Movie> result, string path, CancellationToken cancellationToken) { - new MovieXmlParser(_logger).Fetch(result, path, cancellationToken); + new MovieXmlParser(_logger, _providerManager).Fetch(result, path, cancellationToken); } protected override FileSystemMetadata GetXmlFile(ItemInfo info, IDirectoryService directoryService) diff --git a/MediaBrowser.LocalMetadata/Providers/MusicVideoXmlProvider.cs b/MediaBrowser.LocalMetadata/Providers/MusicVideoXmlProvider.cs index 1060fe895e..49d8c09cca 100644 --- a/MediaBrowser.LocalMetadata/Providers/MusicVideoXmlProvider.cs +++ b/MediaBrowser.LocalMetadata/Providers/MusicVideoXmlProvider.cs @@ -10,16 +10,18 @@ namespace MediaBrowser.LocalMetadata.Providers class MusicVideoXmlProvider : BaseXmlProvider<MusicVideo> { private readonly ILogger _logger; + private readonly IProviderManager _providerManager; - public MusicVideoXmlProvider(IFileSystem fileSystem, ILogger logger) + public MusicVideoXmlProvider(IFileSystem fileSystem, ILogger logger, IProviderManager providerManager) : base(fileSystem) { _logger = logger; + _providerManager = providerManager; } protected override void Fetch(MetadataResult<MusicVideo> result, string path, CancellationToken cancellationToken) { - new MusicVideoXmlParser(_logger).Fetch(result, path, cancellationToken); + new MusicVideoXmlParser(_logger, _providerManager).Fetch(result, path, cancellationToken); } protected override FileSystemMetadata GetXmlFile(ItemInfo info, IDirectoryService directoryService) diff --git a/MediaBrowser.LocalMetadata/Providers/PersonXmlProvider.cs b/MediaBrowser.LocalMetadata/Providers/PersonXmlProvider.cs index b65977c8e3..2ccb8968b3 100644 --- a/MediaBrowser.LocalMetadata/Providers/PersonXmlProvider.cs +++ b/MediaBrowser.LocalMetadata/Providers/PersonXmlProvider.cs @@ -10,16 +10,18 @@ namespace MediaBrowser.LocalMetadata.Providers public class PersonXmlProvider : BaseXmlProvider<Person> { private readonly ILogger _logger; + private readonly IProviderManager _providerManager; - public PersonXmlProvider(IFileSystem fileSystem, ILogger logger) + public PersonXmlProvider(IFileSystem fileSystem, ILogger logger, IProviderManager providerManager) : base(fileSystem) { _logger = logger; + _providerManager = providerManager; } protected override void Fetch(MetadataResult<Person> result, string path, CancellationToken cancellationToken) { - new BaseItemXmlParser<Person>(_logger).Fetch(result, path, cancellationToken); + new BaseItemXmlParser<Person>(_logger, _providerManager).Fetch(result, path, cancellationToken); } protected override FileSystemMetadata GetXmlFile(ItemInfo info, IDirectoryService directoryService) diff --git a/MediaBrowser.LocalMetadata/Providers/PlaylistXmlProvider.cs b/MediaBrowser.LocalMetadata/Providers/PlaylistXmlProvider.cs index eb9e9a6605..149a3142de 100644 --- a/MediaBrowser.LocalMetadata/Providers/PlaylistXmlProvider.cs +++ b/MediaBrowser.LocalMetadata/Providers/PlaylistXmlProvider.cs @@ -11,16 +11,18 @@ namespace MediaBrowser.LocalMetadata.Providers class PlaylistXmlProvider : BaseXmlProvider<Playlist> { private readonly ILogger _logger; + private readonly IProviderManager _providerManager; - public PlaylistXmlProvider(IFileSystem fileSystem, ILogger logger) + public PlaylistXmlProvider(IFileSystem fileSystem, ILogger logger, IProviderManager providerManager) : base(fileSystem) { _logger = logger; + _providerManager = providerManager; } protected override void Fetch(MetadataResult<Playlist> result, string path, CancellationToken cancellationToken) { - new PlaylistXmlParser(_logger).Fetch(result, path, cancellationToken); + new PlaylistXmlParser(_logger, _providerManager).Fetch(result, path, cancellationToken); } protected override FileSystemMetadata GetXmlFile(ItemInfo info, IDirectoryService directoryService) diff --git a/MediaBrowser.LocalMetadata/Providers/SeasonXmlProvider.cs b/MediaBrowser.LocalMetadata/Providers/SeasonXmlProvider.cs deleted file mode 100644 index 7c82d98110..0000000000 --- a/MediaBrowser.LocalMetadata/Providers/SeasonXmlProvider.cs +++ /dev/null @@ -1,44 +0,0 @@ -using System.IO; -using System.Threading; -using CommonIO; -using MediaBrowser.Controller.Entities.TV; -using MediaBrowser.Controller.Providers; -using MediaBrowser.LocalMetadata.Parsers; -using MediaBrowser.Model.Logging; - -namespace MediaBrowser.LocalMetadata.Providers -{ - /// <summary> - /// Class SeriesProviderFromXml - /// </summary> - public class SeasonXmlProvider : BaseXmlProvider<Season>, IHasOrder - { - private readonly ILogger _logger; - - public SeasonXmlProvider(IFileSystem fileSystem, ILogger logger) - : base(fileSystem) - { - _logger = logger; - } - - protected override void Fetch(MetadataResult<Season> result, string path, CancellationToken cancellationToken) - { - new SeasonXmlParser(_logger).Fetch(result, path, cancellationToken); - } - - protected override FileSystemMetadata GetXmlFile(ItemInfo info, IDirectoryService directoryService) - { - return directoryService.GetFile(Path.Combine(info.Path, "season.xml")); - } - - public int Order - { - get - { - // After Xbmc - return 1; - } - } - } -} - diff --git a/MediaBrowser.LocalMetadata/Providers/SeriesXmlProvider.cs b/MediaBrowser.LocalMetadata/Providers/SeriesXmlProvider.cs index 0893f192fa..26d3c75391 100644 --- a/MediaBrowser.LocalMetadata/Providers/SeriesXmlProvider.cs +++ b/MediaBrowser.LocalMetadata/Providers/SeriesXmlProvider.cs @@ -14,16 +14,18 @@ namespace MediaBrowser.LocalMetadata.Providers public class SeriesXmlProvider : BaseXmlProvider<Series>, IHasOrder { private readonly ILogger _logger; + private readonly IProviderManager _providerManager; - public SeriesXmlProvider(IFileSystem fileSystem, ILogger logger) + public SeriesXmlProvider(IFileSystem fileSystem, ILogger logger, IProviderManager providerManager) : base(fileSystem) { _logger = logger; + _providerManager = providerManager; } protected override void Fetch(MetadataResult<Series> result, string path, CancellationToken cancellationToken) { - new SeriesXmlParser(_logger).Fetch(result, path, cancellationToken); + new SeriesXmlParser(_logger, _providerManager).Fetch(result, path, cancellationToken); } protected override FileSystemMetadata GetXmlFile(ItemInfo info, IDirectoryService directoryService) diff --git a/MediaBrowser.LocalMetadata/Providers/VideoXmlProvider.cs b/MediaBrowser.LocalMetadata/Providers/VideoXmlProvider.cs index c7bde4fa85..50f3bcda40 100644 --- a/MediaBrowser.LocalMetadata/Providers/VideoXmlProvider.cs +++ b/MediaBrowser.LocalMetadata/Providers/VideoXmlProvider.cs @@ -10,16 +10,18 @@ namespace MediaBrowser.LocalMetadata.Providers class VideoXmlProvider : BaseXmlProvider<Video> { private readonly ILogger _logger; + private readonly IProviderManager _providerManager; - public VideoXmlProvider(IFileSystem fileSystem, ILogger logger) + public VideoXmlProvider(IFileSystem fileSystem, ILogger logger, IProviderManager providerManager) : base(fileSystem) { _logger = logger; + _providerManager = providerManager; } protected override void Fetch(MetadataResult<Video> result, string path, CancellationToken cancellationToken) { - new VideoXmlParser(_logger).Fetch(result, path, cancellationToken); + new VideoXmlParser(_logger, _providerManager).Fetch(result, path, cancellationToken); } protected override FileSystemMetadata GetXmlFile(ItemInfo info, IDirectoryService directoryService) diff --git a/MediaBrowser.LocalMetadata/Savers/XmlSaverHelpers.cs b/MediaBrowser.LocalMetadata/Savers/XmlSaverHelpers.cs index d472d48121..ac4ebbefe8 100644 --- a/MediaBrowser.LocalMetadata/Savers/XmlSaverHelpers.cs +++ b/MediaBrowser.LocalMetadata/Savers/XmlSaverHelpers.cs @@ -133,7 +133,7 @@ namespace MediaBrowser.LocalMetadata.Savers /// <param name="xmlTagsUsed">The XML tags used.</param> public static void Save(StringBuilder xml, string path, List<string> xmlTagsUsed, IServerConfigurationManager config, IFileSystem fileSystem) { - if (fileSystem.FileExists(path)) + if (fileSystem.FileExists(path)) { var position = xml.ToString().LastIndexOf("</", StringComparison.OrdinalIgnoreCase); xml.Insert(position, GetCustomTags(path, xmlTagsUsed)); @@ -145,7 +145,7 @@ namespace MediaBrowser.LocalMetadata.Savers //Add the new node to the document. xmlDocument.InsertBefore(xmlDocument.CreateXmlDeclaration("1.0", "UTF-8", "yes"), xmlDocument.DocumentElement); - fileSystem.CreateDirectory(Path.GetDirectoryName(path)); + fileSystem.CreateDirectory(Path.GetDirectoryName(path)); var wasHidden = false; @@ -445,121 +445,18 @@ namespace MediaBrowser.LocalMetadata.Savers builder.Append("<RunningTime>" + Convert.ToInt32(timespan.TotalMinutes).ToString(UsCulture) + "</RunningTime>"); } - var imdb = item.GetProviderId(MetadataProviders.Imdb); - - if (!string.IsNullOrEmpty(imdb)) - { - builder.Append("<IMDB>" + SecurityElement.Escape(imdb) + "</IMDB>"); - } - - var tmdb = item.GetProviderId(MetadataProviders.Tmdb); - - if (!string.IsNullOrEmpty(tmdb)) - { - builder.Append("<TMDbId>" + SecurityElement.Escape(tmdb) + "</TMDbId>"); - } - - if (!(item is Series)) + if (item.ProviderIds != null) { - var tvdb = item.GetProviderId(MetadataProviders.Tvdb); - - if (!string.IsNullOrEmpty(tvdb)) + foreach (var providerKey in item.ProviderIds.Keys) { - builder.Append("<TvDbId>" + SecurityElement.Escape(tvdb) + "</TvDbId>"); + var providerId = item.ProviderIds[providerKey]; + if (!string.IsNullOrEmpty(providerId)) + { + builder.Append(string.Format("<{0}>{1}</{0}>", providerKey + "Id", SecurityElement.Escape(providerId))); + } } } - var externalId = item.GetProviderId(MetadataProviders.Tvcom); - - if (!string.IsNullOrEmpty(externalId)) - { - builder.Append("<TVcomId>" + SecurityElement.Escape(externalId) + "</TVcomId>"); - } - - externalId = item.GetProviderId(MetadataProviders.RottenTomatoes); - - if (!string.IsNullOrEmpty(externalId)) - { - builder.Append("<RottenTomatoesId>" + SecurityElement.Escape(externalId) + "</RottenTomatoesId>"); - } - - externalId = item.GetProviderId(MetadataProviders.Zap2It); - - if (!string.IsNullOrEmpty(externalId)) - { - builder.Append("<Zap2ItId>" + SecurityElement.Escape(externalId) + "</Zap2ItId>"); - } - - externalId = item.GetProviderId(MetadataProviders.MusicBrainzAlbum); - - if (!string.IsNullOrEmpty(externalId)) - { - builder.Append("<MusicBrainzAlbumId>" + SecurityElement.Escape(externalId) + "</MusicBrainzAlbumId>"); - } - - externalId = item.GetProviderId(MetadataProviders.MusicBrainzAlbumArtist); - - if (!string.IsNullOrEmpty(externalId)) - { - builder.Append("<MusicBrainzAlbumArtistId>" + SecurityElement.Escape(externalId) + "</MusicBrainzAlbumArtistId>"); - } - - externalId = item.GetProviderId(MetadataProviders.MusicBrainzArtist); - - if (!string.IsNullOrEmpty(externalId)) - { - builder.Append("<MusicBrainzArtistId>" + SecurityElement.Escape(externalId) + "</MusicBrainzArtistId>"); - } - - externalId = item.GetProviderId(MetadataProviders.MusicBrainzReleaseGroup); - - if (!string.IsNullOrEmpty(externalId)) - { - builder.Append("<MusicBrainzReleaseGroupId>" + SecurityElement.Escape(externalId) + "</MusicBrainzReleaseGroupId>"); - } - - externalId = item.GetProviderId(MetadataProviders.Gamesdb); - - if (!string.IsNullOrEmpty(externalId)) - { - builder.Append("<GamesDbId>" + SecurityElement.Escape(externalId) + "</GamesDbId>"); - } - - externalId = item.GetProviderId(MetadataProviders.TmdbCollection); - - if (!string.IsNullOrEmpty(externalId)) - { - builder.Append("<TMDbCollectionId>" + SecurityElement.Escape(externalId) + "</TMDbCollectionId>"); - } - - externalId = item.GetProviderId(MetadataProviders.AudioDbArtist); - - if (!string.IsNullOrEmpty(externalId)) - { - builder.Append("<AudioDbArtistId>" + SecurityElement.Escape(externalId) + "</AudioDbArtistId>"); - } - - externalId = item.GetProviderId(MetadataProviders.AudioDbAlbum); - - if (!string.IsNullOrEmpty(externalId)) - { - builder.Append("<AudioDbAlbumId>" + SecurityElement.Escape(externalId) + "</AudioDbAlbumId>"); - } - - externalId = item.GetProviderId(MetadataProviders.TvRage); - - if (!string.IsNullOrEmpty(externalId)) - { - builder.Append("<TVRageId>" + SecurityElement.Escape(externalId) + "</TVRageId>"); - } - - externalId = item.GetProviderId(MetadataProviders.TvMaze); - - if (!string.IsNullOrEmpty(externalId)) - { - builder.Append("<TvMazeId>" + SecurityElement.Escape(externalId) + "</TvMazeId>"); - } - var hasTagline = item as IHasTaglines; if (hasTagline != null) { diff --git a/MediaBrowser.MediaEncoding/Subtitles/SubtitleEncoder.cs b/MediaBrowser.MediaEncoding/Subtitles/SubtitleEncoder.cs index a63aca11b3..dc5e69283f 100644 --- a/MediaBrowser.MediaEncoding/Subtitles/SubtitleEncoder.cs +++ b/MediaBrowser.MediaEncoding/Subtitles/SubtitleEncoder.cs @@ -818,14 +818,17 @@ namespace MediaBrowser.MediaEncoding.Subtitles public string GetSubtitleFileCharacterSetFromLanguage(string language) { + // https://developer.xamarin.com/api/type/System.Text.Encoding/ + switch (language.ToLower()) { + case "hun": + return "windows-1252"; case "pol": case "cze": case "ces": case "slo": case "slk": - case "hun": case "slv": case "srp": case "hrv": diff --git a/MediaBrowser.Model/ApiClient/ServerCredentials.cs b/MediaBrowser.Model/ApiClient/ServerCredentials.cs index 19f68445e2..ddeb7e5461 100644 --- a/MediaBrowser.Model/ApiClient/ServerCredentials.cs +++ b/MediaBrowser.Model/ApiClient/ServerCredentials.cs @@ -67,7 +67,7 @@ namespace MediaBrowser.Model.ApiClient } if (!string.IsNullOrEmpty(server.ManualAddress)) { - existing.LocalAddress = server.ManualAddress; + existing.ManualAddress = server.ManualAddress; } if (!string.IsNullOrEmpty(server.Name)) { diff --git a/MediaBrowser.Server.Implementations/Library/Resolvers/TV/SeriesResolver.cs b/MediaBrowser.Server.Implementations/Library/Resolvers/TV/SeriesResolver.cs index aefb29f1a6..4c6254330e 100644 --- a/MediaBrowser.Server.Implementations/Library/Resolvers/TV/SeriesResolver.cs +++ b/MediaBrowser.Server.Implementations/Library/Resolvers/TV/SeriesResolver.cs @@ -54,14 +54,14 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers.TV { if (args.IsDirectory) { + if (args.HasParent<Series>()) + { + return null; + } + var collectionType = args.GetCollectionType(); if (string.Equals(collectionType, CollectionType.TvShows, StringComparison.OrdinalIgnoreCase)) { - if (args.HasParent<Series>()) - { - return null; - } - var configuredContentType = _libraryManager.GetConfiguredContentType(args.Path); if (!string.Equals(configuredContentType, CollectionType.TvShows, StringComparison.OrdinalIgnoreCase)) { @@ -76,11 +76,6 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers.TV { if (string.IsNullOrWhiteSpace(collectionType)) { - if (args.HasParent<Series>()) - { - return null; - } - if (args.Parent.IsRoot) { return null; diff --git a/MediaBrowser.Server.Implementations/Udp/UdpServer.cs b/MediaBrowser.Server.Implementations/Udp/UdpServer.cs index 32992b9b27..241ceaf659 100644 --- a/MediaBrowser.Server.Implementations/Udp/UdpServer.cs +++ b/MediaBrowser.Server.Implementations/Udp/UdpServer.cs @@ -30,7 +30,7 @@ namespace MediaBrowser.Server.Implementations.Udp private bool _isDisposed; - private readonly List<Tuple<string, byte[], Action<string, Encoding>>> _responders = new List<Tuple<string, byte[], Action<string, Encoding>>>(); + private readonly List<Tuple<string, bool, Func<string, string, Encoding, Task>>> _responders = new List<Tuple<string, bool, Func<string, string, Encoding, Task>>>(); private readonly IServerApplicationHost _appHost; private readonly IJsonSerializer _json; @@ -49,43 +49,35 @@ namespace MediaBrowser.Server.Implementations.Udp _appHost = appHost; _json = json; - AddMessageResponder("who is EmbyServer?", RespondToV2Message); - AddMessageResponder("who is MediaBrowserServer_v2?", RespondToV2Message); - AddMessageResponder("who is MediaBrowserServer?", RespondToV1Message); + AddMessageResponder("who is EmbyServer?", true, RespondToV2Message); + AddMessageResponder("who is MediaBrowserServer_v2?", false, RespondToV2Message); } - private void AddMessageResponder(string message, Action<string, Encoding> responder) + private void AddMessageResponder(string message, bool isSubstring, Func<string, string, Encoding, Task> responder) { - var expectedMessageBytes = Encoding.UTF8.GetBytes(message); - - _responders.Add(new Tuple<string, byte[], Action<string, Encoding>>(message, expectedMessageBytes, responder)); + _responders.Add(new Tuple<string, bool, Func<string, string, Encoding, Task>>(message, isSubstring, responder)); } /// <summary> /// Raises the <see cref="E:MessageReceived" /> event. /// </summary> /// <param name="e">The <see cref="UdpMessageReceivedEventArgs"/> instance containing the event data.</param> - private void OnMessageReceived(UdpMessageReceivedEventArgs e) + private async void OnMessageReceived(UdpMessageReceivedEventArgs e) { - var responder = _responders.FirstOrDefault(i => i.Item2.SequenceEqual(e.Bytes)); var encoding = Encoding.UTF8; + var responder = GetResponder(e.Bytes, encoding); if (responder == null) { - var text = Encoding.Unicode.GetString(e.Bytes); - responder = _responders.FirstOrDefault(i => string.Equals(i.Item1, text, StringComparison.OrdinalIgnoreCase)); - - if (responder != null) - { - encoding = Encoding.Unicode; - } + encoding = Encoding.Unicode; + responder = GetResponder(e.Bytes, encoding); } if (responder != null) { try { - responder.Item3(e.RemoteEndPoint, encoding); + await responder.Item2.Item3(responder.Item1, e.RemoteEndPoint, encoding).ConfigureAwait(false); } catch (Exception ex) { @@ -94,33 +86,34 @@ namespace MediaBrowser.Server.Implementations.Udp } } - private async void RespondToV1Message(string endpoint, Encoding encoding) + private Tuple<string, Tuple<string, bool, Func<string, string, Encoding, Task>>> GetResponder(byte[] bytes, Encoding encoding) { - var localUrl = await _appHost.GetLocalApiUrl().ConfigureAwait(false); - - if (!string.IsNullOrEmpty(localUrl)) + var text = encoding.GetString(bytes); + var responder = _responders.FirstOrDefault(i => { - // This is how we did the old v1 search, so need to strip off the protocol - var index = localUrl.IndexOf("://", StringComparison.OrdinalIgnoreCase); - - if (index != -1) + if (i.Item2) { - localUrl = localUrl.Substring(index + 3); + return text.IndexOf(i.Item1, StringComparison.OrdinalIgnoreCase) != -1; } + return string.Equals(i.Item1, text, StringComparison.OrdinalIgnoreCase); + }); - // Send a response back with our ip address and port - var response = String.Format("MediaBrowserServer|{0}", localUrl); - - await SendAsync(Encoding.UTF8.GetBytes(response), endpoint); - } - else + if (responder == null) { - _logger.Warn("Unable to respond to udp request because the local ip address could not be determined."); + return null; } + return new Tuple<string, Tuple<string, bool, Func<string, string, Encoding, Task>>>(text, responder); } - private async void RespondToV2Message(string endpoint, Encoding encoding) + private async Task RespondToV2Message(string messageText, string endpoint, Encoding encoding) { + var parts = messageText.Split('|'); + + if (parts.Length > 1) + { + _appHost.EnableLoopback(parts[1]); + } + var localUrl = await _appHost.GetLocalApiUrl().ConfigureAwait(false); if (!string.IsNullOrEmpty(localUrl)) @@ -132,7 +125,7 @@ namespace MediaBrowser.Server.Implementations.Udp Name = _appHost.FriendlyName }; - await SendAsync(encoding.GetBytes(_json.SerializeToString(response)), endpoint); + await SendAsync(encoding.GetBytes(_json.SerializeToString(response)), endpoint).ConfigureAwait(false); } else { diff --git a/MediaBrowser.Server.Mono/Native/BaseMonoApp.cs b/MediaBrowser.Server.Mono/Native/BaseMonoApp.cs index faf3ba37ea..2185f48047 100644 --- a/MediaBrowser.Server.Mono/Native/BaseMonoApp.cs +++ b/MediaBrowser.Server.Mono/Native/BaseMonoApp.cs @@ -278,6 +278,11 @@ namespace MediaBrowser.Server.Mono.Native return info; } + + public void EnableLoopback(string appName) + { + + } } public class NullPowerManagement : IPowerManagement diff --git a/MediaBrowser.Server.Startup.Common/ApplicationHost.cs b/MediaBrowser.Server.Startup.Common/ApplicationHost.cs index 170719b0fa..a25bd38123 100644 --- a/MediaBrowser.Server.Startup.Common/ApplicationHost.cs +++ b/MediaBrowser.Server.Startup.Common/ApplicationHost.cs @@ -1392,5 +1392,10 @@ namespace MediaBrowser.Server.Startup.Common { NativeApp.LaunchUrl(url); } + + public void EnableLoopback(string appName) + { + NativeApp.EnableLoopback(appName); + } } } diff --git a/MediaBrowser.Server.Startup.Common/INativeApp.cs b/MediaBrowser.Server.Startup.Common/INativeApp.cs index c13d3624e3..d2e278a3bb 100644 --- a/MediaBrowser.Server.Startup.Common/INativeApp.cs +++ b/MediaBrowser.Server.Startup.Common/INativeApp.cs @@ -107,5 +107,7 @@ namespace MediaBrowser.Server.Startup.Common void LaunchUrl(string url); IDbConnector GetDbConnector(); + + void EnableLoopback(string appName); } } diff --git a/MediaBrowser.ServerApplication/MainStartup.cs b/MediaBrowser.ServerApplication/MainStartup.cs index 8f153f33fe..8fb0e8f46b 100644 --- a/MediaBrowser.ServerApplication/MainStartup.cs +++ b/MediaBrowser.ServerApplication/MainStartup.cs @@ -292,7 +292,6 @@ namespace MediaBrowser.ServerApplication ErrorModes.SEM_NOGPFAULTERRORBOX | ErrorModes.SEM_NOOPENFILEERRORBOX); } - var task = _appHost.Init(initProgress); Task.WaitAll(task); diff --git a/MediaBrowser.ServerApplication/MediaBrowser.ServerApplication.csproj b/MediaBrowser.ServerApplication/MediaBrowser.ServerApplication.csproj index 9c5470358e..a323124933 100644 --- a/MediaBrowser.ServerApplication/MediaBrowser.ServerApplication.csproj +++ b/MediaBrowser.ServerApplication/MediaBrowser.ServerApplication.csproj @@ -119,6 +119,7 @@ <Compile Include="MainStartup.cs" /> <Compile Include="Native\LnkShortcutHandler.cs" /> <Compile Include="Native\DbConnector.cs" /> + <Compile Include="Native\LoopbackUtil.cs" /> <Compile Include="Native\Standby.cs" /> <Compile Include="Native\ServerAuthorization.cs" /> <Compile Include="Native\WindowsApp.cs" /> diff --git a/MediaBrowser.ServerApplication/Native/LoopbackUtil.cs b/MediaBrowser.ServerApplication/Native/LoopbackUtil.cs new file mode 100644 index 0000000000..5b260685b6 --- /dev/null +++ b/MediaBrowser.ServerApplication/Native/LoopbackUtil.cs @@ -0,0 +1,358 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Runtime.InteropServices; +using System.Text; +using System.Threading.Tasks; + +namespace MediaBrowser.ServerApplication.Native +{ + /// <summary> + /// http://blogs.msdn.com/b/fiddler/archive/2011/12/10/fiddler-windows-8-apps-enable-LoopUtil-network-isolation-exemption.aspx + /// </summary> + public class LoopUtil + { + //http://msdn.microsoft.com/en-us/library/windows/desktop/aa379595(v=vs.85).aspx + [StructLayout(LayoutKind.Sequential)] + internal struct SID_AND_ATTRIBUTES + { + public IntPtr Sid; + public uint Attributes; + } + + [StructLayoutAttribute(LayoutKind.Sequential)] + internal struct INET_FIREWALL_AC_CAPABILITIES + { + public uint count; + public IntPtr capabilities; //SID_AND_ATTRIBUTES + } + + [StructLayoutAttribute(LayoutKind.Sequential)] + internal struct INET_FIREWALL_AC_BINARIES + { + public uint count; + public IntPtr binaries; + } + + [StructLayoutAttribute(LayoutKind.Sequential)] + internal struct INET_FIREWALL_APP_CONTAINER + { + internal IntPtr appContainerSid; + internal IntPtr userSid; + [MarshalAs(UnmanagedType.LPWStr)] + public string appContainerName; + [MarshalAs(UnmanagedType.LPWStr)] + public string displayName; + [MarshalAs(UnmanagedType.LPWStr)] + public string description; + internal INET_FIREWALL_AC_CAPABILITIES capabilities; + internal INET_FIREWALL_AC_BINARIES binaries; + [MarshalAs(UnmanagedType.LPWStr)] + public string workingDirectory; + [MarshalAs(UnmanagedType.LPWStr)] + public string packageFullName; + } + + + // Call this API to free the memory returned by the Enumeration API + [DllImport("FirewallAPI.dll")] + internal static extern void NetworkIsolationFreeAppContainers(IntPtr pACs); + + // Call this API to load the current list of LoopUtil-enabled AppContainers + [DllImport("FirewallAPI.dll")] + internal static extern uint NetworkIsolationGetAppContainerConfig(out uint pdwCntACs, out IntPtr appContainerSids); + + // Call this API to set the LoopUtil-exemption list + [DllImport("FirewallAPI.dll")] + private static extern uint NetworkIsolationSetAppContainerConfig(uint pdwCntACs, SID_AND_ATTRIBUTES[] appContainerSids); + + + // Use this API to convert a string SID into an actual SID + [DllImport("advapi32.dll", SetLastError = true)] + internal static extern bool ConvertStringSidToSid(string strSid, out IntPtr pSid); + + [DllImport("advapi32", CharSet = CharSet.Auto, SetLastError = true)] + static extern bool ConvertSidToStringSid( + [MarshalAs(UnmanagedType.LPArray)] byte[] pSID, + out IntPtr ptrSid); + + [DllImport("advapi32", CharSet = CharSet.Auto, SetLastError = true)] + static extern bool ConvertSidToStringSid(IntPtr pSid, out string strSid); + + // Use this API to convert a string reference (e.g. "@{blah.pri?ms-resource://whatever}") into a plain string + [DllImport("shlwapi.dll", CharSet = CharSet.Unicode, ExactSpelling = true)] + internal static extern int SHLoadIndirectString(string pszSource, StringBuilder pszOutBuf); + + // Call this API to enumerate all of the AppContainers on the system + [DllImport("FirewallAPI.dll")] + internal static extern uint NetworkIsolationEnumAppContainers(uint Flags, out uint pdwCntPublicACs, out IntPtr ppACs); + // DWORD NetworkIsolationEnumAppContainers( + // _In_ DWORD Flags, + // _Out_ DWORD *pdwNumPublicAppCs, + // _Out_ PINET_FIREWALL_APP_CONTAINER *ppPublicAppCs + //); + + //http://msdn.microsoft.com/en-gb/library/windows/desktop/hh968116.aspx + enum NETISO_FLAG + { + NETISO_FLAG_FORCE_COMPUTE_BINARIES = 0x1, + NETISO_FLAG_MAX = 0x2 + } + + + public class AppContainer + { + public String appContainerName { get; set; } + public String displayName { get; set; } + public String workingDirectory { get; set; } + public String StringSid { get; set; } + public List<uint> capabilities { get; set; } + public bool LoopUtil { get; set; } + + public AppContainer(String _appContainerName, String _displayName, String _workingDirectory, IntPtr _sid) + { + this.appContainerName = _appContainerName; + this.displayName = _displayName; + this.workingDirectory = _workingDirectory; + String tempSid; + ConvertSidToStringSid(_sid, out tempSid); + this.StringSid = tempSid; + } + } + + internal List<LoopUtil.INET_FIREWALL_APP_CONTAINER> _AppList; + internal List<LoopUtil.SID_AND_ATTRIBUTES> _AppListConfig; + public List<AppContainer> Apps = new List<AppContainer>(); + internal IntPtr _pACs; + + public LoopUtil() + { + LoadApps(); + } + + public void LoadApps() + { + Apps.Clear(); + _pACs = IntPtr.Zero; + //Full List of Apps + _AppList = PI_NetworkIsolationEnumAppContainers(); + //List of Apps that have LoopUtil enabled. + _AppListConfig = PI_NetworkIsolationGetAppContainerConfig(); + foreach (var PI_app in _AppList) + { + AppContainer app = new AppContainer(PI_app.appContainerName, PI_app.displayName, PI_app.workingDirectory, PI_app.appContainerSid); + + var app_capabilities = LoopUtil.getCapabilites(PI_app.capabilities); + if (app_capabilities.Count > 0) + { + //var sid = new SecurityIdentifier(app_capabilities[0], 0); + + IntPtr arrayValue = IntPtr.Zero; + //var b = LoopUtil.ConvertStringSidToSid(app_capabilities[0].Sid, out arrayValue); + //string mysid; + //var b = LoopUtil.ConvertSidToStringSid(app_capabilities[0].Sid, out mysid); + } + app.LoopUtil = CheckLoopback(PI_app.appContainerSid); + Apps.Add(app); + } + } + private bool CheckLoopback(IntPtr intPtr) + { + foreach (SID_AND_ATTRIBUTES item in _AppListConfig) + { + string left, right; + ConvertSidToStringSid(item.Sid, out left); + ConvertSidToStringSid(intPtr, out right); + + if (left == right) + { + return true; + } + } + return false; + } + + private bool CreateExcemptions(string appName) + { + var hasChanges = false; + + foreach (var app in Apps) + { + if ((app.appContainerName ?? string.Empty).IndexOf(appName, StringComparison.OrdinalIgnoreCase) != -1 || + (app.displayName ?? string.Empty).IndexOf(appName, StringComparison.OrdinalIgnoreCase) != -1) + { + if (!app.LoopUtil) + { + app.LoopUtil = true; + hasChanges = true; + } + } + } + + return hasChanges; + } + + public static void Run(string appName) + { + var util = new LoopUtil(); + util.LoadApps(); + + var hasChanges = util.CreateExcemptions(appName); + + if (hasChanges) + { + util.SaveLoopbackState(); + } + util.SaveLoopbackState(); + } + + private static List<SID_AND_ATTRIBUTES> getCapabilites(INET_FIREWALL_AC_CAPABILITIES cap) + { + List<SID_AND_ATTRIBUTES> mycap = new List<SID_AND_ATTRIBUTES>(); + + IntPtr arrayValue = cap.capabilities; + + var structSize = Marshal.SizeOf(typeof(SID_AND_ATTRIBUTES)); + for (var i = 0; i < cap.count; i++) + { + var cur = (SID_AND_ATTRIBUTES)Marshal.PtrToStructure(arrayValue, typeof(SID_AND_ATTRIBUTES)); + mycap.Add(cur); + arrayValue = new IntPtr((long)(arrayValue) + (long)(structSize)); + } + + return mycap; + + } + + private static List<SID_AND_ATTRIBUTES> getContainerSID(INET_FIREWALL_AC_CAPABILITIES cap) + { + List<SID_AND_ATTRIBUTES> mycap = new List<SID_AND_ATTRIBUTES>(); + + IntPtr arrayValue = cap.capabilities; + + var structSize = Marshal.SizeOf(typeof(SID_AND_ATTRIBUTES)); + for (var i = 0; i < cap.count; i++) + { + var cur = (SID_AND_ATTRIBUTES)Marshal.PtrToStructure(arrayValue, typeof(SID_AND_ATTRIBUTES)); + mycap.Add(cur); + arrayValue = new IntPtr((long)(arrayValue) + (long)(structSize)); + } + + return mycap; + + } + + private static List<SID_AND_ATTRIBUTES> PI_NetworkIsolationGetAppContainerConfig() + { + + IntPtr arrayValue = IntPtr.Zero; + uint size = 0; + var list = new List<SID_AND_ATTRIBUTES>(); + + // Pin down variables + GCHandle handle_pdwCntPublicACs = GCHandle.Alloc(size, GCHandleType.Pinned); + GCHandle handle_ppACs = GCHandle.Alloc(arrayValue, GCHandleType.Pinned); + + uint retval = NetworkIsolationGetAppContainerConfig(out size, out arrayValue); + + var structSize = Marshal.SizeOf(typeof(SID_AND_ATTRIBUTES)); + for (var i = 0; i < size; i++) + { + var cur = (SID_AND_ATTRIBUTES)Marshal.PtrToStructure(arrayValue, typeof(SID_AND_ATTRIBUTES)); + list.Add(cur); + arrayValue = new IntPtr((long)(arrayValue) + (long)(structSize)); + } + + //release pinned variables. + handle_pdwCntPublicACs.Free(); + handle_ppACs.Free(); + + return list; + + + } + + private List<INET_FIREWALL_APP_CONTAINER> PI_NetworkIsolationEnumAppContainers() + { + + IntPtr arrayValue = IntPtr.Zero; + uint size = 0; + var list = new List<INET_FIREWALL_APP_CONTAINER>(); + + // Pin down variables + GCHandle handle_pdwCntPublicACs = GCHandle.Alloc(size, GCHandleType.Pinned); + GCHandle handle_ppACs = GCHandle.Alloc(arrayValue, GCHandleType.Pinned); + + //uint retval2 = NetworkIsolationGetAppContainerConfig( out size, out arrayValue); + + uint retval = NetworkIsolationEnumAppContainers((Int32)NETISO_FLAG.NETISO_FLAG_MAX, out size, out arrayValue); + _pACs = arrayValue; //store the pointer so it can be freed when we close the form + + var structSize = Marshal.SizeOf(typeof(INET_FIREWALL_APP_CONTAINER)); + for (var i = 0; i < size; i++) + { + var cur = (INET_FIREWALL_APP_CONTAINER)Marshal.PtrToStructure(arrayValue, typeof(INET_FIREWALL_APP_CONTAINER)); + list.Add(cur); + arrayValue = new IntPtr((long)(arrayValue) + (long)(structSize)); + } + + //release pinned variables. + handle_pdwCntPublicACs.Free(); + handle_ppACs.Free(); + + return list; + + + } + + public bool SaveLoopbackState() + { + var countEnabled = CountEnabledLoopUtil(); + SID_AND_ATTRIBUTES[] arr = new SID_AND_ATTRIBUTES[countEnabled]; + int count = 0; + + for (int i = 0; i < Apps.Count; i++) + { + if (Apps[i].LoopUtil) + { + arr[count].Attributes = 0; + //TO DO: + IntPtr ptr; + ConvertStringSidToSid(Apps[i].StringSid, out ptr); + arr[count].Sid = ptr; + count++; + } + + } + + + if (NetworkIsolationSetAppContainerConfig((uint)countEnabled, arr) == 0) + { + return true; + } + else + { return false; } + + } + + private int CountEnabledLoopUtil() + { + var count = 0; + for (int i = 0; i < Apps.Count; i++) + { + if (Apps[i].LoopUtil) + { + count++; + } + + } + return count; + } + + public void FreeResources() + { + NetworkIsolationFreeAppContainers(_pACs); + } + + } +} diff --git a/MediaBrowser.ServerApplication/Native/WindowsApp.cs b/MediaBrowser.ServerApplication/Native/WindowsApp.cs index 3c9c04acbf..139471f11b 100644 --- a/MediaBrowser.ServerApplication/Native/WindowsApp.cs +++ b/MediaBrowser.ServerApplication/Native/WindowsApp.cs @@ -203,5 +203,10 @@ namespace MediaBrowser.ServerApplication.Native { ((Process)sender).Dispose(); } + + public void EnableLoopback(string appName) + { + LoopUtil.Run(appName); + } } }
\ No newline at end of file diff --git a/MediaBrowser.XbmcMetadata/Parsers/BaseNfoParser.cs b/MediaBrowser.XbmcMetadata/Parsers/BaseNfoParser.cs index f777ae16bc..1f222e75cd 100644 --- a/MediaBrowser.XbmcMetadata/Parsers/BaseNfoParser.cs +++ b/MediaBrowser.XbmcMetadata/Parsers/BaseNfoParser.cs @@ -25,19 +25,22 @@ namespace MediaBrowser.XbmcMetadata.Parsers /// The logger /// </summary> protected ILogger Logger { get; private set; } + protected IProviderManager ProviderManager { get; private set; } private readonly CultureInfo _usCulture = new CultureInfo("en-US"); private readonly IConfigurationManager _config; + private Dictionary<string, string> _validProviderIds; /// <summary> /// Initializes a new instance of the <see cref="BaseNfoParser{T}" /> class. /// </summary> /// <param name="logger">The logger.</param> /// <param name="config">The configuration.</param> - public BaseNfoParser(ILogger logger, IConfigurationManager config) + public BaseNfoParser(ILogger logger, IConfigurationManager config, IProviderManager providerManager) { Logger = logger; _config = config; + ProviderManager = providerManager; } /// <summary> @@ -68,6 +71,24 @@ namespace MediaBrowser.XbmcMetadata.Parsers ValidationType = ValidationType.None }; + _validProviderIds = _validProviderIds = new Dictionary<string, string>(StringComparer.InvariantCultureIgnoreCase); + + var idInfos = ProviderManager.GetExternalIdInfos(item.Item); + + foreach (var info in idInfos) + { + var id = info.Key + "Id"; + if (!_validProviderIds.ContainsKey(id)) + { + _validProviderIds.Add(id, info.Key); + } + } + + //Additional Mappings + _validProviderIds.Add("collectionnumber", "TmdbCollection"); + _validProviderIds.Add("tmdbcolid", "TmdbCollection"); + _validProviderIds.Add("imdb_id", "Imdb"); + Fetch(item, metadataFile, settings, cancellationToken); } @@ -760,14 +781,6 @@ namespace MediaBrowser.XbmcMetadata.Parsers break; } - case "tvdbid": - var tvdbId = reader.ReadElementContentAsString(); - if (!string.IsNullOrWhiteSpace(tvdbId)) - { - item.SetProviderId(MetadataProviders.Tvdb, tvdbId); - } - break; - case "votes": { var val = reader.ReadElementContentAsString(); @@ -782,127 +795,6 @@ namespace MediaBrowser.XbmcMetadata.Parsers } break; } - case "musicbrainzalbumid": - { - var mbz = reader.ReadElementContentAsString(); - if (!string.IsNullOrWhiteSpace(mbz)) - { - item.SetProviderId(MetadataProviders.MusicBrainzAlbum, mbz); - } - break; - } - case "musicbrainzalbumartistid": - { - var mbz = reader.ReadElementContentAsString(); - if (!string.IsNullOrWhiteSpace(mbz)) - { - item.SetProviderId(MetadataProviders.MusicBrainzAlbumArtist, mbz); - } - break; - } - case "musicbrainzartistid": - { - var mbz = reader.ReadElementContentAsString(); - if (!string.IsNullOrWhiteSpace(mbz)) - { - item.SetProviderId(MetadataProviders.MusicBrainzArtist, mbz); - } - break; - } - case "musicbrainzreleasegroupid": - { - var mbz = reader.ReadElementContentAsString(); - if (!string.IsNullOrWhiteSpace(mbz)) - { - item.SetProviderId(MetadataProviders.MusicBrainzReleaseGroup, mbz); - } - break; - } - case "tvrageid": - { - var id = reader.ReadElementContentAsString(); - if (!string.IsNullOrWhiteSpace(id)) - { - item.SetProviderId(MetadataProviders.TvRage, id); - } - break; - } - case "tvmazeid": - { - var id = reader.ReadElementContentAsString(); - if (!string.IsNullOrWhiteSpace(id)) - { - item.SetProviderId(MetadataProviders.TvMaze, id); - } - break; - } - case "audiodbartistid": - { - var id = reader.ReadElementContentAsString(); - if (!string.IsNullOrWhiteSpace(id)) - { - item.SetProviderId(MetadataProviders.AudioDbArtist, id); - } - break; - } - case "audiodbalbumid": - { - var id = reader.ReadElementContentAsString(); - if (!string.IsNullOrWhiteSpace(id)) - { - item.SetProviderId(MetadataProviders.AudioDbAlbum, id); - } - break; - } - case "rottentomatoesid": - var rtId = reader.ReadElementContentAsString(); - if (!string.IsNullOrWhiteSpace(rtId)) - { - item.SetProviderId(MetadataProviders.RottenTomatoes, rtId); - } - break; - - case "tmdbid": - var tmdb = reader.ReadElementContentAsString(); - if (!string.IsNullOrWhiteSpace(tmdb)) - { - item.SetProviderId(MetadataProviders.Tmdb, tmdb); - } - break; - - case "collectionnumber": - case "tmdbcolid": - var tmdbCollection = reader.ReadElementContentAsString(); - if (!string.IsNullOrWhiteSpace(tmdbCollection)) - { - item.SetProviderId(MetadataProviders.TmdbCollection, tmdbCollection); - } - break; - - case "tvcomid": - var TVcomId = reader.ReadElementContentAsString(); - if (!string.IsNullOrWhiteSpace(TVcomId)) - { - item.SetProviderId(MetadataProviders.Tvcom, TVcomId); - } - break; - - case "zap2itid": - var zap2ItId = reader.ReadElementContentAsString(); - if (!string.IsNullOrWhiteSpace(zap2ItId)) - { - item.SetProviderId(MetadataProviders.Zap2It, zap2ItId); - } - break; - - case "imdb_id": - case "imdbid": - var imDbId = reader.ReadElementContentAsString(); - if (!string.IsNullOrWhiteSpace(imDbId)) - { - item.SetProviderId(MetadataProviders.Imdb, imDbId); - } - break; case "genre": { diff --git a/MediaBrowser.XbmcMetadata/Parsers/EpisodeNfoParser.cs b/MediaBrowser.XbmcMetadata/Parsers/EpisodeNfoParser.cs index dfa5c1b71a..a5a86fc581 100644 --- a/MediaBrowser.XbmcMetadata/Parsers/EpisodeNfoParser.cs +++ b/MediaBrowser.XbmcMetadata/Parsers/EpisodeNfoParser.cs @@ -12,7 +12,7 @@ namespace MediaBrowser.XbmcMetadata.Parsers { public class EpisodeNfoParser : BaseNfoParser<Episode> { - public EpisodeNfoParser(ILogger logger, IConfigurationManager config) : base(logger, config) + public EpisodeNfoParser(ILogger logger, IConfigurationManager config, IProviderManager providerManager) : base(logger, config, providerManager) { } diff --git a/MediaBrowser.XbmcMetadata/Parsers/MovieNfoParser.cs b/MediaBrowser.XbmcMetadata/Parsers/MovieNfoParser.cs index dfe88cd3fe..3e6196238c 100644 --- a/MediaBrowser.XbmcMetadata/Parsers/MovieNfoParser.cs +++ b/MediaBrowser.XbmcMetadata/Parsers/MovieNfoParser.cs @@ -10,8 +10,8 @@ namespace MediaBrowser.XbmcMetadata.Parsers { class MovieNfoParser : BaseNfoParser<Video> { - public MovieNfoParser(ILogger logger, IConfigurationManager config) - : base(logger, config) + public MovieNfoParser(ILogger logger, IConfigurationManager config, IProviderManager providerManager) + : base(logger, config, providerManager) { } diff --git a/MediaBrowser.XbmcMetadata/Parsers/SeasonNfoParser.cs b/MediaBrowser.XbmcMetadata/Parsers/SeasonNfoParser.cs index 1164040fd5..c051ad4f81 100644 --- a/MediaBrowser.XbmcMetadata/Parsers/SeasonNfoParser.cs +++ b/MediaBrowser.XbmcMetadata/Parsers/SeasonNfoParser.cs @@ -9,7 +9,7 @@ namespace MediaBrowser.XbmcMetadata.Parsers { public class SeasonNfoParser : BaseNfoParser<Season> { - public SeasonNfoParser(ILogger logger, IConfigurationManager config) : base(logger, config) + public SeasonNfoParser(ILogger logger, IConfigurationManager config, IProviderManager providerManager) : base(logger, config, providerManager) { } diff --git a/MediaBrowser.XbmcMetadata/Parsers/SeriesNfoParser.cs b/MediaBrowser.XbmcMetadata/Parsers/SeriesNfoParser.cs index 4dd2e1759e..8b7deebf23 100644 --- a/MediaBrowser.XbmcMetadata/Parsers/SeriesNfoParser.cs +++ b/MediaBrowser.XbmcMetadata/Parsers/SeriesNfoParser.cs @@ -11,7 +11,7 @@ namespace MediaBrowser.XbmcMetadata.Parsers { public class SeriesNfoParser : BaseNfoParser<Series> { - public SeriesNfoParser(ILogger logger, IConfigurationManager config) : base(logger, config) + public SeriesNfoParser(ILogger logger, IConfigurationManager config, IProviderManager providerManager) : base(logger, config, providerManager) { } diff --git a/MediaBrowser.XbmcMetadata/Providers/AlbumNfoProvider.cs b/MediaBrowser.XbmcMetadata/Providers/AlbumNfoProvider.cs index d0b1b142cb..a90cb20fdc 100644 --- a/MediaBrowser.XbmcMetadata/Providers/AlbumNfoProvider.cs +++ b/MediaBrowser.XbmcMetadata/Providers/AlbumNfoProvider.cs @@ -13,17 +13,19 @@ namespace MediaBrowser.XbmcMetadata.Providers { private readonly ILogger _logger; private readonly IConfigurationManager _config; + private readonly IProviderManager _providerManager; - public AlbumNfoProvider(IFileSystem fileSystem, ILogger logger, IConfigurationManager config) + public AlbumNfoProvider(IFileSystem fileSystem, ILogger logger, IConfigurationManager config, IProviderManager providerManager) : base(fileSystem) { _logger = logger; _config = config; + _providerManager = providerManager; } protected override void Fetch(MetadataResult<MusicAlbum> result, string path, CancellationToken cancellationToken) { - new BaseNfoParser<MusicAlbum>(_logger, _config).Fetch(result, path, cancellationToken); + new BaseNfoParser<MusicAlbum>(_logger, _config, _providerManager).Fetch(result, path, cancellationToken); } protected override FileSystemMetadata GetXmlFile(ItemInfo info, IDirectoryService directoryService) diff --git a/MediaBrowser.XbmcMetadata/Providers/ArtistNfoProvider.cs b/MediaBrowser.XbmcMetadata/Providers/ArtistNfoProvider.cs index 81c6b1c288..391eb459ac 100644 --- a/MediaBrowser.XbmcMetadata/Providers/ArtistNfoProvider.cs +++ b/MediaBrowser.XbmcMetadata/Providers/ArtistNfoProvider.cs @@ -13,17 +13,19 @@ namespace MediaBrowser.XbmcMetadata.Providers { private readonly ILogger _logger; private readonly IConfigurationManager _config; + private readonly IProviderManager _providerManager; - public ArtistNfoProvider(IFileSystem fileSystem, ILogger logger, IConfigurationManager config) + public ArtistNfoProvider(IFileSystem fileSystem, ILogger logger, IConfigurationManager config, IProviderManager providerManager) : base(fileSystem) { _logger = logger; _config = config; + _providerManager = providerManager; } protected override void Fetch(MetadataResult<MusicArtist> result, string path, CancellationToken cancellationToken) { - new BaseNfoParser<MusicArtist>(_logger, _config).Fetch(result, path, cancellationToken); + new BaseNfoParser<MusicArtist>(_logger, _config, _providerManager).Fetch(result, path, cancellationToken); } protected override FileSystemMetadata GetXmlFile(ItemInfo info, IDirectoryService directoryService) diff --git a/MediaBrowser.XbmcMetadata/Providers/BaseVideoNfoProvider.cs b/MediaBrowser.XbmcMetadata/Providers/BaseVideoNfoProvider.cs index 26ffc9a19c..0a268e8e27 100644 --- a/MediaBrowser.XbmcMetadata/Providers/BaseVideoNfoProvider.cs +++ b/MediaBrowser.XbmcMetadata/Providers/BaseVideoNfoProvider.cs @@ -15,12 +15,14 @@ namespace MediaBrowser.XbmcMetadata.Providers { private readonly ILogger _logger; private readonly IConfigurationManager _config; + private readonly IProviderManager _providerManager; - public BaseVideoNfoProvider(IFileSystem fileSystem, ILogger logger, IConfigurationManager config) + public BaseVideoNfoProvider(IFileSystem fileSystem, ILogger logger, IConfigurationManager config, IProviderManager providerManager) : base(fileSystem) { _logger = logger; _config = config; + _providerManager = providerManager; } protected override void Fetch(MetadataResult<T> result, string path, CancellationToken cancellationToken) @@ -29,7 +31,7 @@ namespace MediaBrowser.XbmcMetadata.Providers { Item = result.Item }; - new MovieNfoParser(_logger, _config).Fetch(tmpItem, path, cancellationToken); + new MovieNfoParser(_logger, _config, _providerManager).Fetch(tmpItem, path, cancellationToken); result.Item = (T)tmpItem.Item; result.People = tmpItem.People; diff --git a/MediaBrowser.XbmcMetadata/Providers/EpisodeNfoProvider.cs b/MediaBrowser.XbmcMetadata/Providers/EpisodeNfoProvider.cs index 5587c75159..d8f3f1a21e 100644 --- a/MediaBrowser.XbmcMetadata/Providers/EpisodeNfoProvider.cs +++ b/MediaBrowser.XbmcMetadata/Providers/EpisodeNfoProvider.cs @@ -14,19 +14,21 @@ namespace MediaBrowser.XbmcMetadata.Providers { private readonly ILogger _logger; private readonly IConfigurationManager _config; + private readonly IProviderManager _providerManager; - public EpisodeNfoProvider(IFileSystem fileSystem, ILogger logger, IConfigurationManager config) + public EpisodeNfoProvider(IFileSystem fileSystem, ILogger logger, IConfigurationManager config, IProviderManager providerManager) : base(fileSystem) { _logger = logger; _config = config; + _providerManager = providerManager; } protected override void Fetch(MetadataResult<Episode> result, string path, CancellationToken cancellationToken) { var images = new List<LocalImageInfo>(); - new EpisodeNfoParser(_logger, _config).Fetch(result, images, path, cancellationToken); + new EpisodeNfoParser(_logger, _config, _providerManager).Fetch(result, images, path, cancellationToken); result.Images = images; } diff --git a/MediaBrowser.XbmcMetadata/Providers/MovieNfoProvider.cs b/MediaBrowser.XbmcMetadata/Providers/MovieNfoProvider.cs index bba4010dc7..5a759f81e5 100644 --- a/MediaBrowser.XbmcMetadata/Providers/MovieNfoProvider.cs +++ b/MediaBrowser.XbmcMetadata/Providers/MovieNfoProvider.cs @@ -2,27 +2,28 @@ using MediaBrowser.Common.Configuration; using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Entities.Movies; +using MediaBrowser.Controller.Providers; using MediaBrowser.Model.Logging; namespace MediaBrowser.XbmcMetadata.Providers { public class MovieNfoProvider : BaseVideoNfoProvider<Movie> { - public MovieNfoProvider(IFileSystem fileSystem, ILogger logger, IConfigurationManager config) : base(fileSystem, logger, config) + public MovieNfoProvider(IFileSystem fileSystem, ILogger logger, IConfigurationManager config, IProviderManager providerManager) : base(fileSystem, logger, config, providerManager) { } } public class MusicVideoNfoProvider : BaseVideoNfoProvider<MusicVideo> { - public MusicVideoNfoProvider(IFileSystem fileSystem, ILogger logger, IConfigurationManager config) : base(fileSystem, logger, config) + public MusicVideoNfoProvider(IFileSystem fileSystem, ILogger logger, IConfigurationManager config, IProviderManager providerManager) : base(fileSystem, logger, config, providerManager) { } } public class VideoNfoProvider : BaseVideoNfoProvider<Video> { - public VideoNfoProvider(IFileSystem fileSystem, ILogger logger, IConfigurationManager config) : base(fileSystem, logger, config) + public VideoNfoProvider(IFileSystem fileSystem, ILogger logger, IConfigurationManager config, IProviderManager providerManager) : base(fileSystem, logger, config, providerManager) { } } diff --git a/MediaBrowser.XbmcMetadata/Providers/SeasonNfoProvider.cs b/MediaBrowser.XbmcMetadata/Providers/SeasonNfoProvider.cs index 3dac0a531b..7e116b2c5d 100644 --- a/MediaBrowser.XbmcMetadata/Providers/SeasonNfoProvider.cs +++ b/MediaBrowser.XbmcMetadata/Providers/SeasonNfoProvider.cs @@ -13,17 +13,19 @@ namespace MediaBrowser.XbmcMetadata.Providers { private readonly ILogger _logger; private readonly IConfigurationManager _config; + private readonly IProviderManager _providerManager; - public SeasonNfoProvider(IFileSystem fileSystem, ILogger logger, IConfigurationManager config) + public SeasonNfoProvider(IFileSystem fileSystem, ILogger logger, IConfigurationManager config, IProviderManager providerManager) : base(fileSystem) { _logger = logger; _config = config; + _providerManager = providerManager; } protected override void Fetch(MetadataResult<Season> result, string path, CancellationToken cancellationToken) { - new SeasonNfoParser(_logger, _config).Fetch(result, path, cancellationToken); + new SeasonNfoParser(_logger, _config, _providerManager).Fetch(result, path, cancellationToken); } protected override FileSystemMetadata GetXmlFile(ItemInfo info, IDirectoryService directoryService) diff --git a/MediaBrowser.XbmcMetadata/Providers/SeriesNfoProvider.cs b/MediaBrowser.XbmcMetadata/Providers/SeriesNfoProvider.cs index 4bab8d75bc..f03c209545 100644 --- a/MediaBrowser.XbmcMetadata/Providers/SeriesNfoProvider.cs +++ b/MediaBrowser.XbmcMetadata/Providers/SeriesNfoProvider.cs @@ -13,17 +13,19 @@ namespace MediaBrowser.XbmcMetadata.Providers { private readonly ILogger _logger; private readonly IConfigurationManager _config; + private readonly IProviderManager _providerManager; - public SeriesNfoProvider(IFileSystem fileSystem, ILogger logger, IConfigurationManager config) + public SeriesNfoProvider(IFileSystem fileSystem, ILogger logger, IConfigurationManager config, IProviderManager providerManager) : base(fileSystem) { _logger = logger; _config = config; + _providerManager = providerManager; } protected override void Fetch(MetadataResult<Series> result, string path, CancellationToken cancellationToken) { - new SeriesNfoParser(_logger, _config).Fetch(result, path, cancellationToken); + new SeriesNfoParser(_logger, _config, _providerManager).Fetch(result, path, cancellationToken); } protected override FileSystemMetadata GetXmlFile(ItemInfo info, IDirectoryService directoryService) diff --git a/MediaBrowser.XbmcMetadata/Savers/BaseNfoSaver.cs b/MediaBrowser.XbmcMetadata/Savers/BaseNfoSaver.cs index c28a15a939..290ea588eb 100644 --- a/MediaBrowser.XbmcMetadata/Savers/BaseNfoSaver.cs +++ b/MediaBrowser.XbmcMetadata/Savers/BaseNfoSaver.cs @@ -27,8 +27,8 @@ namespace MediaBrowser.XbmcMetadata.Savers { private static readonly CultureInfo UsCulture = new CultureInfo("en-US"); - private static readonly Dictionary<string, string> CommonTags = new[] { - + private static readonly Dictionary<string, string> CommonTags = new[] { + "plot", "customrating", "lockdata", @@ -428,6 +428,8 @@ namespace MediaBrowser.XbmcMetadata.Savers /// <returns>Task.</returns> public static void AddCommonNodes(BaseItem item, XmlWriter writer, ILibraryManager libraryManager, IUserManager userManager, IUserDataManager userDataRepo, IFileSystem fileSystem, IServerConfigurationManager config) { + var writtenProviderIds = new HashSet<string>(StringComparer.InvariantCultureIgnoreCase); + var overview = (item.Overview ?? string.Empty) .StripHtml() .Replace(""", "'"); @@ -572,6 +574,7 @@ namespace MediaBrowser.XbmcMetadata.Savers if (!string.IsNullOrEmpty(rt)) { writer.WriteElementString("rottentomatoesid", rt); + writtenProviderIds.Add(MetadataProviders.RottenTomatoes.ToString()); } var tmdbCollection = item.GetProviderId(MetadataProviders.TmdbCollection); @@ -579,6 +582,7 @@ namespace MediaBrowser.XbmcMetadata.Savers if (!string.IsNullOrEmpty(tmdbCollection)) { writer.WriteElementString("collectionnumber", tmdbCollection); + writtenProviderIds.Add(MetadataProviders.TmdbCollection.ToString()); } var imdb = item.GetProviderId(MetadataProviders.Imdb); @@ -592,6 +596,7 @@ namespace MediaBrowser.XbmcMetadata.Savers { writer.WriteElementString("imdbid", imdb); } + writtenProviderIds.Add(MetadataProviders.Imdb.ToString()); } // Series xml saver already saves this @@ -601,6 +606,7 @@ namespace MediaBrowser.XbmcMetadata.Savers if (!string.IsNullOrEmpty(tvdb)) { writer.WriteElementString("tvdbid", tvdb); + writtenProviderIds.Add(MetadataProviders.Tvdb.ToString()); } } @@ -608,12 +614,14 @@ namespace MediaBrowser.XbmcMetadata.Savers if (!string.IsNullOrEmpty(tmdb)) { writer.WriteElementString("tmdbid", tmdb); + writtenProviderIds.Add(MetadataProviders.Tmdb.ToString()); } var tvcom = item.GetProviderId(MetadataProviders.Tvcom); if (!string.IsNullOrEmpty(tvcom)) { writer.WriteElementString("tvcomid", tvcom); + writtenProviderIds.Add(MetadataProviders.Tvcom.ToString()); } if (!string.IsNullOrEmpty(item.PreferredMetadataLanguage)) @@ -766,6 +774,7 @@ namespace MediaBrowser.XbmcMetadata.Savers if (!string.IsNullOrEmpty(externalId)) { writer.WriteElementString("audiodbartistid", externalId); + writtenProviderIds.Add(MetadataProviders.AudioDbArtist.ToString()); } externalId = item.GetProviderId(MetadataProviders.AudioDbAlbum); @@ -773,6 +782,7 @@ namespace MediaBrowser.XbmcMetadata.Savers if (!string.IsNullOrEmpty(externalId)) { writer.WriteElementString("audiodbalbumid", externalId); + writtenProviderIds.Add(MetadataProviders.AudioDbAlbum.ToString()); } externalId = item.GetProviderId(MetadataProviders.Zap2It); @@ -780,6 +790,7 @@ namespace MediaBrowser.XbmcMetadata.Savers if (!string.IsNullOrEmpty(externalId)) { writer.WriteElementString("zap2itid", externalId); + writtenProviderIds.Add(MetadataProviders.Zap2It.ToString()); } externalId = item.GetProviderId(MetadataProviders.MusicBrainzAlbum); @@ -787,6 +798,7 @@ namespace MediaBrowser.XbmcMetadata.Savers if (!string.IsNullOrEmpty(externalId)) { writer.WriteElementString("musicbrainzalbumid", externalId); + writtenProviderIds.Add(MetadataProviders.MusicBrainzAlbum.ToString()); } externalId = item.GetProviderId(MetadataProviders.MusicBrainzAlbumArtist); @@ -794,6 +806,7 @@ namespace MediaBrowser.XbmcMetadata.Savers if (!string.IsNullOrEmpty(externalId)) { writer.WriteElementString("musicbrainzalbumartistid", externalId); + writtenProviderIds.Add(MetadataProviders.MusicBrainzAlbumArtist.ToString()); } externalId = item.GetProviderId(MetadataProviders.MusicBrainzArtist); @@ -801,6 +814,7 @@ namespace MediaBrowser.XbmcMetadata.Savers if (!string.IsNullOrEmpty(externalId)) { writer.WriteElementString("musicbrainzartistid", externalId); + writtenProviderIds.Add(MetadataProviders.MusicBrainzArtist.ToString()); } externalId = item.GetProviderId(MetadataProviders.MusicBrainzReleaseGroup); @@ -808,24 +822,33 @@ namespace MediaBrowser.XbmcMetadata.Savers if (!string.IsNullOrEmpty(externalId)) { writer.WriteElementString("musicbrainzreleasegroupid", externalId); + writtenProviderIds.Add(MetadataProviders.MusicBrainzReleaseGroup.ToString()); } externalId = item.GetProviderId(MetadataProviders.Gamesdb); if (!string.IsNullOrEmpty(externalId)) { writer.WriteElementString("gamesdbid", externalId); + writtenProviderIds.Add(MetadataProviders.Gamesdb.ToString()); } externalId = item.GetProviderId(MetadataProviders.TvRage); if (!string.IsNullOrEmpty(externalId)) { writer.WriteElementString("tvrageid", externalId); + writtenProviderIds.Add(MetadataProviders.TvRage.ToString()); } - externalId = item.GetProviderId(MetadataProviders.TvMaze); - if (!string.IsNullOrEmpty(externalId)) + if (item.ProviderIds != null) { - writer.WriteElementString("tvmazeid", externalId); + foreach (var providerKey in item.ProviderIds.Keys) + { + var providerId = item.ProviderIds[providerKey]; + if (!string.IsNullOrEmpty(providerId) && !writtenProviderIds.Contains(providerKey)) + { + writer.WriteElementString(providerKey.ToLower() + "id", providerId); + } + } } if (options.SaveImagePathsInNfo) diff --git a/MediaBrowser.sln b/MediaBrowser.sln index c6068f5364..0b9dd90cde 100644 --- a/MediaBrowser.sln +++ b/MediaBrowser.sln @@ -1,7 +1,7 @@ Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 14 -VisualStudioVersion = 14.0.24720.0 +VisualStudioVersion = 14.0.25420.1 MinimumVisualStudioVersion = 10.0.40219.1 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".nuget", ".nuget", "{F0E0E64C-2A6F-4E35-9533-D53AC07C2CD1}" EndProject diff --git a/Nuget/MediaBrowser.Common.Internal.nuspec b/Nuget/MediaBrowser.Common.Internal.nuspec index cfdfc7ef0b..06159dadb6 100644 --- a/Nuget/MediaBrowser.Common.Internal.nuspec +++ b/Nuget/MediaBrowser.Common.Internal.nuspec @@ -2,7 +2,7 @@ <package xmlns="http://schemas.microsoft.com/packaging/2011/08/nuspec.xsd"> <metadata> <id>MediaBrowser.Common.Internal</id> - <version>3.0.656</version> + <version>3.0.657</version> <title>MediaBrowser.Common.Internal</title> <authors>Luke</authors> <owners>ebr,Luke,scottisafool</owners> @@ -12,7 +12,7 @@ <description>Contains common components shared by Emby Theater and Emby Server. Not intended for plugin developer consumption.</description> <copyright>Copyright © Emby 2013</copyright> <dependencies> - <dependency id="MediaBrowser.Common" version="3.0.656" /> + <dependency id="MediaBrowser.Common" version="3.0.657" /> <dependency id="NLog" version="4.3.6" /> <dependency id="SimpleInjector" version="3.2.0" /> </dependencies> diff --git a/Nuget/MediaBrowser.Common.nuspec b/Nuget/MediaBrowser.Common.nuspec index 1ebf4d0529..de1af036d5 100644 --- a/Nuget/MediaBrowser.Common.nuspec +++ b/Nuget/MediaBrowser.Common.nuspec @@ -2,7 +2,7 @@ <package xmlns="http://schemas.microsoft.com/packaging/2011/08/nuspec.xsd"> <metadata> <id>MediaBrowser.Common</id> - <version>3.0.656</version> + <version>3.0.657</version> <title>MediaBrowser.Common</title> <authors>Emby Team</authors> <owners>ebr,Luke,scottisafool</owners> diff --git a/Nuget/MediaBrowser.Server.Core.nuspec b/Nuget/MediaBrowser.Server.Core.nuspec index 630ff8fd2b..d21fefc86c 100644 --- a/Nuget/MediaBrowser.Server.Core.nuspec +++ b/Nuget/MediaBrowser.Server.Core.nuspec @@ -2,7 +2,7 @@ <package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd"> <metadata> <id>MediaBrowser.Server.Core</id> - <version>3.0.656</version> + <version>3.0.657</version> <title>Media Browser.Server.Core</title> <authors>Emby Team</authors> <owners>ebr,Luke,scottisafool</owners> @@ -12,7 +12,7 @@ <description>Contains core components required to build plugins for Emby Server.</description> <copyright>Copyright © Emby 2013</copyright> <dependencies> - <dependency id="MediaBrowser.Common" version="3.0.656" /> + <dependency id="MediaBrowser.Common" version="3.0.657" /> <dependency id="Interfaces.IO" version="1.0.0.5" /> </dependencies> </metadata> |
