Merge pull request #2137 from MediaBrowser/dev

Dev
pull/702/head
Luke 8 years ago committed by GitHub
commit c9ba91d7a5

@ -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;

@ -89,5 +89,7 @@ namespace MediaBrowser.Controller
string GetLocalApiUrl(IPAddress ipAddress);
void LaunchUrl(string url);
void EnableLoopback(string appName);
}
}

@ -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;
}
}

@ -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" />

@ -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)
{
}

@ -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;
}

@ -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)
{
}

@ -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)
{
}

@ -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)
{
}
}

@ -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)
{
}

@ -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)
{
}

@ -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;
}
}
}
}

@ -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)
{
}

@ -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)

@ -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;
}

@ -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)

@ -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)

@ -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)

@ -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)

@ -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)

@ -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)

@ -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)

@ -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;
}
}
}
}

@ -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)

@ -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)

@ -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)
{

@ -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":

@ -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))
{

@ -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;

@ -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
{

@ -278,6 +278,11 @@ namespace MediaBrowser.Server.Mono.Native
return info;
}
public void EnableLoopback(string appName)
{
}
}
public class NullPowerManagement : IPowerManagement

@ -1392,5 +1392,10 @@ namespace MediaBrowser.Server.Startup.Common
{
NativeApp.LaunchUrl(url);
}
public void EnableLoopback(string appName)
{
NativeApp.EnableLoopback(appName);
}
}
}

@ -107,5 +107,7 @@ namespace MediaBrowser.Server.Startup.Common
void LaunchUrl(string url);
IDbConnector GetDbConnector();
void EnableLoopback(string appName);
}
}

@ -292,7 +292,6 @@ namespace MediaBrowser.ServerApplication
ErrorModes.SEM_NOGPFAULTERRORBOX | ErrorModes.SEM_NOOPENFILEERRORBOX);
}
var task = _appHost.Init(initProgress);
Task.WaitAll(task);

@ -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" />

@ -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);
}
}
}

@ -203,5 +203,10 @@ namespace MediaBrowser.ServerApplication.Native
{
((Process)sender).Dispose();
}
public void EnableLoopback(string appName)
{
LoopUtil.Run(appName);
}
}
}

@ -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":
{

@ -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)
{
}

@ -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)
{
}

@ -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)
{
}

@ -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)
{
}

@ -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)

@ -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)

@ -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;

@ -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;
}

@ -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)
{
}
}

@ -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)

@ -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)

@ -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("&quot;", "'");
@ -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)

@ -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

@ -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>

@ -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>

@ -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>

Loading…
Cancel
Save