repo creation with initial code after cloning public repo
This commit is contained in:
@@ -0,0 +1,15 @@
|
||||
#pragma warning disable CS1591
|
||||
|
||||
using MediaBrowser.Common.Configuration;
|
||||
using MediaBrowser.Model.Configuration;
|
||||
|
||||
namespace MediaBrowser.XbmcMetadata.Configuration
|
||||
{
|
||||
public static class NfoConfigurationExtension
|
||||
{
|
||||
public static XbmcMetadataOptions GetNfoConfiguration(this IConfigurationManager manager)
|
||||
{
|
||||
return manager.GetConfiguration<XbmcMetadataOptions>("xbmcmetadata");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
#pragma warning disable CS1591
|
||||
|
||||
using System.Collections.Generic;
|
||||
using MediaBrowser.Common.Configuration;
|
||||
using MediaBrowser.Model.Configuration;
|
||||
|
||||
namespace MediaBrowser.XbmcMetadata.Configuration
|
||||
{
|
||||
public class NfoConfigurationFactory : IConfigurationFactory
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public IEnumerable<ConfigurationStore> GetConfigurations()
|
||||
{
|
||||
return new[]
|
||||
{
|
||||
new ConfigurationStore
|
||||
{
|
||||
ConfigurationType = typeof(XbmcMetadataOptions),
|
||||
Key = "xbmcmetadata"
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<!-- ProjectGuid is only included as a requirement for SonarQube analysis -->
|
||||
<PropertyGroup>
|
||||
<ProjectGuid>{23499896-B135-4527-8574-C26E926EA99E}</ProjectGuid>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\MediaBrowser.Model\MediaBrowser.Model.csproj" />
|
||||
<ProjectReference Include="..\MediaBrowser.Controller\MediaBrowser.Controller.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Include="..\SharedVersion.cs" />
|
||||
</ItemGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net10.0</TargetFramework>
|
||||
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
|
||||
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
||||
</PropertyGroup>
|
||||
|
||||
<!-- Code Analyzers-->
|
||||
<ItemGroup Condition=" '$(Configuration)' == 'Debug' ">
|
||||
<PackageReference Include="IDisposableAnalyzers">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Microsoft.CodeAnalysis.BannedApiAnalyzers">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="SerilogAnalyzer" PrivateAssets="All" />
|
||||
<PackageReference Include="StyleCop.Analyzers" PrivateAssets="All" />
|
||||
<PackageReference Include="SmartAnalyzers.MultithreadingAnalyzer" PrivateAssets="All" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
@@ -0,0 +1,87 @@
|
||||
using System;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using MediaBrowser.Common.Configuration;
|
||||
using MediaBrowser.Controller.Library;
|
||||
using MediaBrowser.Controller.Providers;
|
||||
using MediaBrowser.Model.Entities;
|
||||
using MediaBrowser.XbmcMetadata.Configuration;
|
||||
using MediaBrowser.XbmcMetadata.Savers;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace MediaBrowser.XbmcMetadata;
|
||||
|
||||
/// <summary>
|
||||
/// <see cref="IHostedService"/> responsible for updating NFO files' user data.
|
||||
/// </summary>
|
||||
public sealed class NfoUserDataSaver : IHostedService
|
||||
{
|
||||
private readonly ILogger<NfoUserDataSaver> _logger;
|
||||
private readonly IConfigurationManager _config;
|
||||
private readonly IUserDataManager _userDataManager;
|
||||
private readonly IProviderManager _providerManager;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="NfoUserDataSaver"/> class.
|
||||
/// </summary>
|
||||
/// <param name="logger">The <see cref="ILogger"/>.</param>
|
||||
/// <param name="config">The <see cref="IConfigurationManager"/>.</param>
|
||||
/// <param name="userDataManager">The <see cref="IUserDataManager"/>.</param>
|
||||
/// <param name="providerManager">The <see cref="IProviderManager"/>.</param>
|
||||
public NfoUserDataSaver(
|
||||
ILogger<NfoUserDataSaver> logger,
|
||||
IConfigurationManager config,
|
||||
IUserDataManager userDataManager,
|
||||
IProviderManager providerManager)
|
||||
{
|
||||
_logger = logger;
|
||||
_config = config;
|
||||
_userDataManager = userDataManager;
|
||||
_providerManager = providerManager;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public Task StartAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
_userDataManager.UserDataSaved += OnUserDataSaved;
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public Task StopAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
_userDataManager.UserDataSaved -= OnUserDataSaved;
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
private async void OnUserDataSaved(object? sender, UserDataSaveEventArgs e)
|
||||
{
|
||||
if (e.SaveReason is not (UserDataSaveReason.PlaybackFinished
|
||||
or UserDataSaveReason.TogglePlayed or UserDataSaveReason.UpdateUserRating))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (string.IsNullOrWhiteSpace(_config.GetNfoConfiguration().UserId))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var item = e.Item;
|
||||
if (!item.IsFileProtocol || !item.SupportsLocalMetadata)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
await _providerManager.SaveMetadataAsync(item, ItemUpdateType.MetadataDownload, [BaseNfoSaver.SaverName])
|
||||
.ConfigureAwait(false);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "Error saving metadata for {Path}", item.Path ?? item.Name);
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,202 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Xml;
|
||||
using MediaBrowser.Common.Configuration;
|
||||
using MediaBrowser.Controller.Entities.TV;
|
||||
using MediaBrowser.Controller.Extensions;
|
||||
using MediaBrowser.Controller.Library;
|
||||
using MediaBrowser.Controller.Providers;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace MediaBrowser.XbmcMetadata.Parsers
|
||||
{
|
||||
/// <summary>
|
||||
/// Nfo parser for episodes.
|
||||
/// </summary>
|
||||
public class EpisodeNfoParser : BaseNfoParser<Episode>
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="EpisodeNfoParser"/> class.
|
||||
/// </summary>
|
||||
/// <param name="logger">Instance of the <see cref="ILogger{BaseNfoParser}"/> interface.</param>
|
||||
/// <param name="config">Instance of the <see cref="IConfigurationManager"/> interface.</param>
|
||||
/// <param name="providerManager">Instance of the <see cref="IProviderManager"/> interface.</param>
|
||||
/// <param name="userManager">Instance of the <see cref="IUserManager"/> interface.</param>
|
||||
/// <param name="userDataManager">Instance of the <see cref="IUserDataManager"/> interface.</param>
|
||||
/// <param name="directoryService">Instance of the <see cref="IDirectoryService"/> interface.</param>
|
||||
public EpisodeNfoParser(
|
||||
ILogger logger,
|
||||
IConfigurationManager config,
|
||||
IProviderManager providerManager,
|
||||
IUserManager userManager,
|
||||
IUserDataManager userDataManager,
|
||||
IDirectoryService directoryService)
|
||||
: base(logger, config, providerManager, userManager, userDataManager, directoryService)
|
||||
{
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Fetch(MetadataResult<Episode> item, string metadataFile, XmlReaderSettings settings, CancellationToken cancellationToken)
|
||||
{
|
||||
item.ResetPeople();
|
||||
|
||||
var xmlFile = File.ReadAllText(metadataFile);
|
||||
|
||||
var srch = "</episodedetails>";
|
||||
var index = xmlFile.IndexOf(srch, StringComparison.OrdinalIgnoreCase);
|
||||
|
||||
var xml = xmlFile;
|
||||
|
||||
if (index != -1)
|
||||
{
|
||||
xml = xmlFile.Substring(0, index + srch.Length);
|
||||
xmlFile = xmlFile.Substring(index + srch.Length);
|
||||
}
|
||||
|
||||
// These are not going to be valid xml so no sense in causing the provider to fail and spamming the log with exceptions
|
||||
try
|
||||
{
|
||||
// Extract episode details from the first episodedetails block
|
||||
ReadEpisodeDetailsFromXml(item, xml, settings, cancellationToken);
|
||||
|
||||
// Extract the last episode number from nfo
|
||||
// Retrieves all additional episodedetails blocks from the rest of the nfo and concatenates the name, originalTitle and overview tags with the first episode
|
||||
// This is needed because XBMC metadata uses multiple episodedetails blocks instead of episodenumberend tag
|
||||
var name = new StringBuilder(item.Item.Name);
|
||||
var originalTitle = new StringBuilder(item.Item.OriginalTitle);
|
||||
var overview = new StringBuilder(item.Item.Overview);
|
||||
while ((index = xmlFile.IndexOf(srch, StringComparison.OrdinalIgnoreCase)) != -1)
|
||||
{
|
||||
xml = xmlFile.Substring(0, index + srch.Length);
|
||||
xmlFile = xmlFile.Substring(index + srch.Length);
|
||||
|
||||
var additionalEpisode = new MetadataResult<Episode>()
|
||||
{
|
||||
Item = new Episode()
|
||||
};
|
||||
|
||||
// Extract episode details from additional episodedetails block
|
||||
ReadEpisodeDetailsFromXml(additionalEpisode, xml, settings, cancellationToken);
|
||||
|
||||
if (!string.IsNullOrEmpty(additionalEpisode.Item.Name))
|
||||
{
|
||||
name.Append(" / ").Append(additionalEpisode.Item.Name);
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(additionalEpisode.Item.Overview))
|
||||
{
|
||||
overview.Append(" / ").Append(additionalEpisode.Item.Overview);
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(additionalEpisode.Item.OriginalTitle))
|
||||
{
|
||||
originalTitle.Append(" / ").Append(additionalEpisode.Item.OriginalTitle);
|
||||
}
|
||||
|
||||
if (additionalEpisode.Item.IndexNumber is not null)
|
||||
{
|
||||
item.Item.IndexNumberEnd = Math.Max((int)additionalEpisode.Item.IndexNumber, item.Item.IndexNumberEnd ?? (int)additionalEpisode.Item.IndexNumber);
|
||||
}
|
||||
}
|
||||
|
||||
item.Item.Name = name.ToString();
|
||||
item.Item.OriginalTitle = originalTitle.ToString();
|
||||
item.Item.Overview = overview.ToString();
|
||||
}
|
||||
catch (XmlException)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void FetchDataFromXmlNode(XmlReader reader, MetadataResult<Episode> itemResult)
|
||||
{
|
||||
var item = itemResult.Item;
|
||||
|
||||
switch (reader.Name)
|
||||
{
|
||||
case "season":
|
||||
if (reader.TryReadInt(out var seasonNumber))
|
||||
{
|
||||
item.ParentIndexNumber = seasonNumber;
|
||||
}
|
||||
|
||||
break;
|
||||
case "episode":
|
||||
if (reader.TryReadInt(out var episodeNumber))
|
||||
{
|
||||
item.IndexNumber = episodeNumber;
|
||||
}
|
||||
|
||||
break;
|
||||
case "episodenumberend":
|
||||
if (reader.TryReadInt(out var episodeNumberEnd))
|
||||
{
|
||||
item.IndexNumberEnd = episodeNumberEnd;
|
||||
}
|
||||
|
||||
break;
|
||||
case "airsbefore_episode":
|
||||
case "displayepisode":
|
||||
if (reader.TryReadInt(out var airsBeforeEpisode))
|
||||
{
|
||||
item.AirsBeforeEpisodeNumber = airsBeforeEpisode;
|
||||
}
|
||||
|
||||
break;
|
||||
case "airsafter_season":
|
||||
case "displayafterseason":
|
||||
if (reader.TryReadInt(out var airsAfterSeason))
|
||||
{
|
||||
item.AirsAfterSeasonNumber = airsAfterSeason;
|
||||
}
|
||||
|
||||
break;
|
||||
case "airsbefore_season":
|
||||
case "displayseason":
|
||||
if (reader.TryReadInt(out var airsBeforeSeason))
|
||||
{
|
||||
item.AirsBeforeSeasonNumber = airsBeforeSeason;
|
||||
}
|
||||
|
||||
break;
|
||||
case "showtitle":
|
||||
item.SeriesName = reader.ReadNormalizedString();
|
||||
break;
|
||||
default:
|
||||
base.FetchDataFromXmlNode(reader, itemResult);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reads the episode details from the given xml and saves the result in the provided result item.
|
||||
/// </summary>
|
||||
private void ReadEpisodeDetailsFromXml(MetadataResult<Episode> item, string xml, XmlReaderSettings settings, CancellationToken cancellationToken)
|
||||
{
|
||||
using (var stringReader = new StringReader(xml))
|
||||
using (var reader = XmlReader.Create(stringReader, settings))
|
||||
{
|
||||
reader.MoveToContent();
|
||||
reader.Read();
|
||||
|
||||
// Loop through each element
|
||||
while (!reader.EOF && reader.ReadState == ReadState.Interactive)
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
|
||||
if (reader.NodeType == XmlNodeType.Element)
|
||||
{
|
||||
FetchDataFromXmlNode(reader, item);
|
||||
}
|
||||
else
|
||||
{
|
||||
reader.Read();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,160 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Xml;
|
||||
using MediaBrowser.Common.Configuration;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Controller.Entities.Movies;
|
||||
using MediaBrowser.Controller.Extensions;
|
||||
using MediaBrowser.Controller.Library;
|
||||
using MediaBrowser.Controller.Providers;
|
||||
using MediaBrowser.Model.Entities;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace MediaBrowser.XbmcMetadata.Parsers
|
||||
{
|
||||
/// <summary>
|
||||
/// Nfo parser for movies.
|
||||
/// </summary>
|
||||
public class MovieNfoParser : BaseNfoParser<Video>
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="MovieNfoParser"/> class.
|
||||
/// </summary>
|
||||
/// <param name="logger">Instance of the <see cref="ILogger"/> interface.</param>
|
||||
/// <param name="config">Instance of the <see cref="IConfigurationManager"/> interface.</param>
|
||||
/// <param name="providerManager">Instance of the <see cref="IProviderManager"/> interface.</param>
|
||||
/// <param name="userManager">Instance of the <see cref="IUserManager"/> interface.</param>
|
||||
/// <param name="userDataManager">Instance of the <see cref="IUserDataManager"/> interface.</param>
|
||||
/// <param name="directoryService">Instance of the <see cref="DirectoryService"/> interface.</param>
|
||||
public MovieNfoParser(
|
||||
ILogger logger,
|
||||
IConfigurationManager config,
|
||||
IProviderManager providerManager,
|
||||
IUserManager userManager,
|
||||
IUserDataManager userDataManager,
|
||||
IDirectoryService directoryService)
|
||||
: base(logger, config, providerManager, userManager, userDataManager, directoryService)
|
||||
{
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override bool SupportsUrlAfterClosingXmlTag => true;
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void FetchDataFromXmlNode(XmlReader reader, MetadataResult<Video> itemResult)
|
||||
{
|
||||
var item = itemResult.Item;
|
||||
|
||||
switch (reader.Name)
|
||||
{
|
||||
case "id":
|
||||
{
|
||||
// Get ids from attributes
|
||||
item.TrySetProviderId(MetadataProvider.Tmdb, reader.GetAttribute("TMDB"));
|
||||
item.TrySetProviderId(MetadataProvider.Tvdb, reader.GetAttribute("TVDB"));
|
||||
string? imdbId = reader.GetAttribute("IMDB");
|
||||
|
||||
// Read id from content
|
||||
// Content can be arbitrary according to Kodi wiki, so only parse if we are sure it matches a provider-specific schema
|
||||
var contentId = reader.ReadElementContentAsString();
|
||||
if (string.IsNullOrEmpty(imdbId) && contentId.StartsWith("tt", StringComparison.Ordinal))
|
||||
{
|
||||
imdbId = contentId;
|
||||
}
|
||||
|
||||
item.TrySetProviderId(MetadataProvider.Imdb, imdbId);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case "set":
|
||||
{
|
||||
var movie = item as Movie;
|
||||
|
||||
var tmdbcolid = reader.GetAttribute("tmdbcolid");
|
||||
movie?.TrySetProviderId(MetadataProvider.TmdbCollection, tmdbcolid);
|
||||
|
||||
var val = reader.ReadInnerXml();
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(val) && movie is not null)
|
||||
{
|
||||
try
|
||||
{
|
||||
ParseSetXml(val, movie);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.LogError(ex, "Error parsing set node");
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case "artist":
|
||||
var artist = reader.ReadNormalizedString();
|
||||
if (!string.IsNullOrEmpty(artist) && item is MusicVideo artistVideo)
|
||||
{
|
||||
artistVideo.Artists = [..artistVideo.Artists, artist];
|
||||
}
|
||||
|
||||
break;
|
||||
case "album":
|
||||
var album = reader.ReadNormalizedString();
|
||||
if (!string.IsNullOrEmpty(album) && item is MusicVideo albumVideo)
|
||||
{
|
||||
albumVideo.Album = album;
|
||||
}
|
||||
|
||||
break;
|
||||
default:
|
||||
base.FetchDataFromXmlNode(reader, itemResult);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void ParseSetXml(string xml, Movie movie)
|
||||
{
|
||||
// These are not going to be valid xml so no sense in causing the provider to fail and spamming the log with exceptions
|
||||
try
|
||||
{
|
||||
using (var stringReader = new StringReader("<set>" + xml + "</set>"))
|
||||
using (var reader = XmlReader.Create(stringReader, GetXmlReaderSettings()))
|
||||
{
|
||||
reader.MoveToContent();
|
||||
reader.Read();
|
||||
|
||||
// Loop through each element
|
||||
while (!reader.EOF && reader.ReadState == ReadState.Interactive)
|
||||
{
|
||||
if (reader.NodeType == XmlNodeType.Text && reader.Depth == 1)
|
||||
{
|
||||
movie.CollectionName = reader.Value;
|
||||
break;
|
||||
}
|
||||
else if (reader.NodeType == XmlNodeType.Element)
|
||||
{
|
||||
switch (reader.Name)
|
||||
{
|
||||
case "name":
|
||||
movie.CollectionName = reader.ReadElementContentAsString();
|
||||
break;
|
||||
default:
|
||||
reader.Skip();
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
reader.Read();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (XmlException)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
using System.Xml;
|
||||
using MediaBrowser.Common.Configuration;
|
||||
using MediaBrowser.Controller.Entities.TV;
|
||||
using MediaBrowser.Controller.Extensions;
|
||||
using MediaBrowser.Controller.Library;
|
||||
using MediaBrowser.Controller.Providers;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace MediaBrowser.XbmcMetadata.Parsers
|
||||
{
|
||||
/// <summary>
|
||||
/// Nfo parser for seasons.
|
||||
/// </summary>
|
||||
public class SeasonNfoParser : BaseNfoParser<Season>
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="SeasonNfoParser"/> class.
|
||||
/// </summary>
|
||||
/// <param name="logger">Instance of the <see cref="ILogger"/> interface.</param>
|
||||
/// <param name="config">Instance of the <see cref="IConfigurationManager"/> interface.</param>
|
||||
/// <param name="providerManager">Instance of the <see cref="IProviderManager"/> interface.</param>
|
||||
/// <param name="userManager">Instance of the <see cref="IUserManager"/> interface.</param>
|
||||
/// <param name="userDataManager">Instance of the <see cref="IUserDataManager"/> interface.</param>
|
||||
/// <param name="directoryService">Instance of the <see cref="DirectoryService"/> interface.</param>
|
||||
public SeasonNfoParser(
|
||||
ILogger logger,
|
||||
IConfigurationManager config,
|
||||
IProviderManager providerManager,
|
||||
IUserManager userManager,
|
||||
IUserDataManager userDataManager,
|
||||
IDirectoryService directoryService)
|
||||
: base(logger, config, providerManager, userManager, userDataManager, directoryService)
|
||||
{
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void FetchDataFromXmlNode(XmlReader reader, MetadataResult<Season> itemResult)
|
||||
{
|
||||
var item = itemResult.Item;
|
||||
|
||||
switch (reader.Name)
|
||||
{
|
||||
case "seasonnumber":
|
||||
if (reader.TryReadInt(out var seasonNumber))
|
||||
{
|
||||
item.IndexNumber = seasonNumber;
|
||||
}
|
||||
|
||||
break;
|
||||
case "seasonname":
|
||||
item.Name = reader.ReadNormalizedString();
|
||||
break;
|
||||
default:
|
||||
base.FetchDataFromXmlNode(reader, itemResult);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,105 @@
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.Xml;
|
||||
using Emby.Naming.TV;
|
||||
using MediaBrowser.Common.Configuration;
|
||||
using MediaBrowser.Controller.Entities.TV;
|
||||
using MediaBrowser.Controller.Extensions;
|
||||
using MediaBrowser.Controller.Library;
|
||||
using MediaBrowser.Controller.Providers;
|
||||
using MediaBrowser.Model.Entities;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace MediaBrowser.XbmcMetadata.Parsers
|
||||
{
|
||||
/// <summary>
|
||||
/// Nfo parser for series.
|
||||
/// </summary>
|
||||
public class SeriesNfoParser : BaseNfoParser<Series>
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="SeriesNfoParser"/> class.
|
||||
/// </summary>
|
||||
/// <param name="logger">Instance of the <see cref="ILogger"/> interface.</param>
|
||||
/// <param name="config">Instance of the <see cref="IConfigurationManager"/> interface.</param>
|
||||
/// <param name="providerManager">Instance of the <see cref="IProviderManager"/> interface.</param>
|
||||
/// <param name="userManager">Instance of the <see cref="IUserManager"/> interface.</param>
|
||||
/// <param name="userDataManager">Instance of the <see cref="IUserDataManager"/> interface.</param>
|
||||
/// <param name="directoryService">Instance of the <see cref="IDirectoryService"/> interface.</param>
|
||||
public SeriesNfoParser(
|
||||
ILogger logger,
|
||||
IConfigurationManager config,
|
||||
IProviderManager providerManager,
|
||||
IUserManager userManager,
|
||||
IUserDataManager userDataManager,
|
||||
IDirectoryService directoryService)
|
||||
: base(logger, config, providerManager, userManager, userDataManager, directoryService)
|
||||
{
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override bool SupportsUrlAfterClosingXmlTag => true;
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void FetchDataFromXmlNode(XmlReader reader, MetadataResult<Series> itemResult)
|
||||
{
|
||||
var item = itemResult.Item;
|
||||
|
||||
switch (reader.Name)
|
||||
{
|
||||
case "id":
|
||||
{
|
||||
// Get ids from attributes
|
||||
item.TrySetProviderId(MetadataProvider.Tmdb, reader.GetAttribute("TMDB"));
|
||||
item.TrySetProviderId(MetadataProvider.Tvdb, reader.GetAttribute("TVDB"));
|
||||
string? imdbId = reader.GetAttribute("IMDB");
|
||||
|
||||
// Read id from content
|
||||
// Content can be arbitrary according to Kodi wiki, so only parse if we are sure it matches a provider-specific schema
|
||||
var contentId = reader.ReadElementContentAsString();
|
||||
if (string.IsNullOrEmpty(imdbId) && contentId.StartsWith("tt", StringComparison.Ordinal))
|
||||
{
|
||||
imdbId = contentId;
|
||||
}
|
||||
|
||||
item.TrySetProviderId(MetadataProvider.Imdb, imdbId);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case "airs_dayofweek":
|
||||
item.AirDays = TVUtils.GetAirDays(reader.ReadElementContentAsString());
|
||||
break;
|
||||
case "airs_time":
|
||||
item.AirTime = reader.ReadNormalizedString();
|
||||
break;
|
||||
case "status":
|
||||
{
|
||||
var status = reader.ReadElementContentAsString();
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(status))
|
||||
{
|
||||
if (TvParserHelpers.TryParseSeriesStatus(status, out var seriesStatus))
|
||||
{
|
||||
item.Status = seriesStatus;
|
||||
}
|
||||
else
|
||||
{
|
||||
Logger.LogInformation("Unrecognized series status: {Status}", status);
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
// Season names are processed by SeriesNfoSeasonParser
|
||||
case "namedseason":
|
||||
reader.Skip();
|
||||
break;
|
||||
default:
|
||||
base.FetchDataFromXmlNode(reader, itemResult);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
using System.Globalization;
|
||||
using System.Xml;
|
||||
using MediaBrowser.Common.Configuration;
|
||||
using MediaBrowser.Controller.Entities.TV;
|
||||
using MediaBrowser.Controller.Library;
|
||||
using MediaBrowser.Controller.Providers;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace MediaBrowser.XbmcMetadata.Parsers
|
||||
{
|
||||
/// <summary>
|
||||
/// NFO parser for seasons based on series NFO.
|
||||
/// </summary>
|
||||
public class SeriesNfoSeasonParser : BaseNfoParser<Season>
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="SeriesNfoSeasonParser"/> class.
|
||||
/// </summary>
|
||||
/// <param name="logger">Instance of the <see cref="ILogger"/> interface.</param>
|
||||
/// <param name="config">Instance of the <see cref="IConfigurationManager"/> interface.</param>
|
||||
/// <param name="providerManager">Instance of the <see cref="IProviderManager"/> interface.</param>
|
||||
/// <param name="userManager">Instance of the <see cref="IUserManager"/> interface.</param>
|
||||
/// <param name="userDataManager">Instance of the <see cref="IUserDataManager"/> interface.</param>
|
||||
/// <param name="directoryService">Instance of the <see cref="IDirectoryService"/> interface.</param>
|
||||
public SeriesNfoSeasonParser(
|
||||
ILogger logger,
|
||||
IConfigurationManager config,
|
||||
IProviderManager providerManager,
|
||||
IUserManager userManager,
|
||||
IUserDataManager userDataManager,
|
||||
IDirectoryService directoryService)
|
||||
: base(logger, config, providerManager, userManager, userDataManager, directoryService)
|
||||
{
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override bool SupportsUrlAfterClosingXmlTag => true;
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void FetchDataFromXmlNode(XmlReader reader, MetadataResult<Season> itemResult)
|
||||
{
|
||||
var item = itemResult.Item;
|
||||
|
||||
if (reader.Name == "namedseason")
|
||||
{
|
||||
var parsed = int.TryParse(reader.GetAttribute("number"), NumberStyles.Integer, CultureInfo.InvariantCulture, out var seasonNumber);
|
||||
var name = reader.ReadElementContentAsString();
|
||||
|
||||
if (parsed && !string.IsNullOrWhiteSpace(name) && item.IndexNumber.HasValue && seasonNumber == item.IndexNumber.Value)
|
||||
{
|
||||
item.Name = name;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
reader.Skip();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
using System.Reflection;
|
||||
using System.Resources;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// General Information about an assembly is controlled through the following
|
||||
// set of attributes. Change these attribute values to modify the information
|
||||
// associated with an assembly.
|
||||
[assembly: AssemblyTitle("MediaBrowser.XbmcMetadata")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("Jellyfin Project")]
|
||||
[assembly: AssemblyProduct("Jellyfin Server")]
|
||||
[assembly: AssemblyCopyright("Copyright © 2019 Jellyfin Contributors. Code released under the GNU General Public License")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
[assembly: NeutralResourcesLanguage("en")]
|
||||
[assembly: InternalsVisibleTo("Jellyfin.XbmcMetadata.Tests")]
|
||||
|
||||
// Setting ComVisible to false makes the types in this assembly not visible
|
||||
// to COM components. If you need to access a type in this assembly from
|
||||
// COM, set the ComVisible attribute to true on that type.
|
||||
[assembly: ComVisible(false)]
|
||||
@@ -0,0 +1,63 @@
|
||||
using System.IO;
|
||||
using System.Threading;
|
||||
using MediaBrowser.Common.Configuration;
|
||||
using MediaBrowser.Controller.Entities.Audio;
|
||||
using MediaBrowser.Controller.Library;
|
||||
using MediaBrowser.Controller.Providers;
|
||||
using MediaBrowser.Model.IO;
|
||||
using MediaBrowser.XbmcMetadata.Parsers;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace MediaBrowser.XbmcMetadata.Providers
|
||||
{
|
||||
/// <summary>
|
||||
/// Nfo provider for albums.
|
||||
/// </summary>
|
||||
public class AlbumNfoProvider : BaseNfoProvider<MusicAlbum>
|
||||
{
|
||||
private readonly ILogger<AlbumNfoProvider> _logger;
|
||||
private readonly IConfigurationManager _config;
|
||||
private readonly IProviderManager _providerManager;
|
||||
private readonly IUserManager _userManager;
|
||||
private readonly IUserDataManager _userDataManager;
|
||||
private readonly IDirectoryService _directoryService;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="AlbumNfoProvider"/> class.
|
||||
/// </summary>
|
||||
/// <param name="logger">Instance of the <see cref="ILogger{AlbumNfoProvider}"/> interface.</param>
|
||||
/// <param name="fileSystem">Instance of the <see cref="IFileSystem"/> interface.</param>
|
||||
/// <param name="config">Instance of the <see cref="IConfigurationManager"/> interface.</param>
|
||||
/// <param name="providerManager">Instance of the <see cref="IProviderManager"/> interface.</param>
|
||||
/// <param name="userManager">Instance of the <see cref="IUserManager"/> interface.</param>
|
||||
/// <param name="userDataManager">Instance of the <see cref="IUserDataManager"/> interface.</param>
|
||||
/// <param name="directoryService">Instance of the <see cref="IDirectoryService"/> interface.</param>
|
||||
public AlbumNfoProvider(
|
||||
ILogger<AlbumNfoProvider> logger,
|
||||
IFileSystem fileSystem,
|
||||
IConfigurationManager config,
|
||||
IProviderManager providerManager,
|
||||
IUserManager userManager,
|
||||
IUserDataManager userDataManager,
|
||||
IDirectoryService directoryService)
|
||||
: base(fileSystem)
|
||||
{
|
||||
_logger = logger;
|
||||
_config = config;
|
||||
_providerManager = providerManager;
|
||||
_userManager = userManager;
|
||||
_userDataManager = userDataManager;
|
||||
_directoryService = directoryService;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Fetch(MetadataResult<MusicAlbum> result, string path, CancellationToken cancellationToken)
|
||||
{
|
||||
new BaseNfoParser<MusicAlbum>(_logger, _config, _providerManager, _userManager, _userDataManager, _directoryService).Fetch(result, path, cancellationToken);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override FileSystemMetadata? GetXmlFile(ItemInfo info, IDirectoryService directoryService)
|
||||
=> directoryService.GetFile(Path.Combine(info.Path, "album.nfo"));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
using System.IO;
|
||||
using System.Threading;
|
||||
using MediaBrowser.Common.Configuration;
|
||||
using MediaBrowser.Controller.Entities.Audio;
|
||||
using MediaBrowser.Controller.Library;
|
||||
using MediaBrowser.Controller.Providers;
|
||||
using MediaBrowser.Model.IO;
|
||||
using MediaBrowser.XbmcMetadata.Parsers;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace MediaBrowser.XbmcMetadata.Providers
|
||||
{
|
||||
/// <summary>
|
||||
/// Nfo provider for artists.
|
||||
/// </summary>
|
||||
public class ArtistNfoProvider : BaseNfoProvider<MusicArtist>
|
||||
{
|
||||
private readonly ILogger<ArtistNfoProvider> _logger;
|
||||
private readonly IConfigurationManager _config;
|
||||
private readonly IProviderManager _providerManager;
|
||||
private readonly IUserManager _userManager;
|
||||
private readonly IUserDataManager _userDataManager;
|
||||
private readonly IDirectoryService _directoryService;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ArtistNfoProvider"/> class.
|
||||
/// </summary>
|
||||
/// <param name="logger">Instance of the <see cref="ILogger{ArtistNfoProvider}"/> interface.</param>
|
||||
/// <param name="fileSystem">Instance of the <see cref="IFileSystem"/> interface.</param>
|
||||
/// <param name="config">Instance of the <see cref="IConfigurationManager"/> interface.</param>
|
||||
/// <param name="providerManager">Instance of the <see cref="IProviderManager"/> interface.</param>
|
||||
/// <param name="userManager">Instance of the <see cref="IUserManager"/> interface.</param>
|
||||
/// <param name="userDataManager">Instance of the <see cref="IUserDataManager"/> interface.</param>
|
||||
/// <param name="directoryService">Instance of the <see cref="IDirectoryService"/> interface.</param>
|
||||
public ArtistNfoProvider(
|
||||
IFileSystem fileSystem,
|
||||
ILogger<ArtistNfoProvider> logger,
|
||||
IConfigurationManager config,
|
||||
IProviderManager providerManager,
|
||||
IUserManager userManager,
|
||||
IUserDataManager userDataManager,
|
||||
IDirectoryService directoryService)
|
||||
: base(fileSystem)
|
||||
{
|
||||
_logger = logger;
|
||||
_config = config;
|
||||
_providerManager = providerManager;
|
||||
_userManager = userManager;
|
||||
_userDataManager = userDataManager;
|
||||
_directoryService = directoryService;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Fetch(MetadataResult<MusicArtist> result, string path, CancellationToken cancellationToken)
|
||||
{
|
||||
new BaseNfoParser<MusicArtist>(_logger, _config, _providerManager, _userManager, _userDataManager, _directoryService).Fetch(result, path, cancellationToken);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override FileSystemMetadata? GetXmlFile(ItemInfo info, IDirectoryService directoryService)
|
||||
=> directoryService.GetFile(Path.Combine(info.Path, "artist.nfo"));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
#pragma warning disable CS1591
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Controller.Providers;
|
||||
using MediaBrowser.Model.IO;
|
||||
using MediaBrowser.XbmcMetadata.Savers;
|
||||
|
||||
namespace MediaBrowser.XbmcMetadata.Providers
|
||||
{
|
||||
public abstract class BaseNfoProvider<T> : ILocalMetadataProvider<T>, IHasItemChangeMonitor
|
||||
where T : BaseItem, new()
|
||||
{
|
||||
private readonly IFileSystem _fileSystem;
|
||||
|
||||
protected BaseNfoProvider(IFileSystem fileSystem)
|
||||
{
|
||||
_fileSystem = fileSystem;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public string Name => BaseNfoSaver.SaverName;
|
||||
|
||||
/// <inheritdoc />
|
||||
public Task<MetadataResult<T>> GetMetadata(
|
||||
ItemInfo info,
|
||||
IDirectoryService directoryService,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
var result = new MetadataResult<T>();
|
||||
|
||||
var file = GetXmlFile(info, directoryService);
|
||||
|
||||
if (file is null)
|
||||
{
|
||||
return Task.FromResult(result);
|
||||
}
|
||||
|
||||
var path = file.FullName;
|
||||
|
||||
try
|
||||
{
|
||||
result.Item = new T
|
||||
{
|
||||
IndexNumber = info.IndexNumber
|
||||
};
|
||||
|
||||
Fetch(result, path, cancellationToken);
|
||||
result.HasMetadata = true;
|
||||
}
|
||||
catch (FileNotFoundException)
|
||||
{
|
||||
result.HasMetadata = false;
|
||||
}
|
||||
catch (IOException)
|
||||
{
|
||||
result.HasMetadata = false;
|
||||
}
|
||||
|
||||
return Task.FromResult(result);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool HasChanged(BaseItem item, IDirectoryService directoryService)
|
||||
{
|
||||
var file = GetXmlFile(new ItemInfo(item), directoryService);
|
||||
|
||||
if (file?.Exists is not true)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var fileTime = _fileSystem.GetLastWriteTimeUtc(file);
|
||||
|
||||
// 1 minute tolerance to avoid detecting our own file writes
|
||||
return (fileTime - item.DateLastSaved) > TimeSpan.FromMinutes(1);
|
||||
}
|
||||
|
||||
protected abstract void Fetch(MetadataResult<T> result, string path, CancellationToken cancellationToken);
|
||||
|
||||
protected abstract FileSystemMetadata? GetXmlFile(ItemInfo info, IDirectoryService directoryService);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
#pragma warning disable CS1591
|
||||
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using MediaBrowser.Common.Configuration;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Controller.Library;
|
||||
using MediaBrowser.Controller.Providers;
|
||||
using MediaBrowser.Model.IO;
|
||||
using MediaBrowser.XbmcMetadata.Parsers;
|
||||
using MediaBrowser.XbmcMetadata.Savers;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace MediaBrowser.XbmcMetadata.Providers
|
||||
{
|
||||
public abstract class BaseVideoNfoProvider<T> : BaseNfoProvider<T>
|
||||
where T : Video, new()
|
||||
{
|
||||
private readonly ILogger<BaseVideoNfoProvider<T>> _logger;
|
||||
private readonly IConfigurationManager _config;
|
||||
private readonly IProviderManager _providerManager;
|
||||
private readonly IUserManager _userManager;
|
||||
private readonly IUserDataManager _userDataManager;
|
||||
private readonly IDirectoryService _directoryService;
|
||||
|
||||
protected BaseVideoNfoProvider(
|
||||
ILogger<BaseVideoNfoProvider<T>> logger,
|
||||
IFileSystem fileSystem,
|
||||
IConfigurationManager config,
|
||||
IProviderManager providerManager,
|
||||
IUserManager userManager,
|
||||
IUserDataManager userDataManager,
|
||||
IDirectoryService directoryService)
|
||||
: base(fileSystem)
|
||||
{
|
||||
_logger = logger;
|
||||
_config = config;
|
||||
_providerManager = providerManager;
|
||||
_userManager = userManager;
|
||||
_userDataManager = userDataManager;
|
||||
_directoryService = directoryService;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Fetch(MetadataResult<T> result, string path, CancellationToken cancellationToken)
|
||||
{
|
||||
var tmpItem = new MetadataResult<Video>
|
||||
{
|
||||
Item = result.Item
|
||||
};
|
||||
new MovieNfoParser(_logger, _config, _providerManager, _userManager, _userDataManager, _directoryService).Fetch(tmpItem, path, cancellationToken);
|
||||
|
||||
result.Item = (T)tmpItem.Item;
|
||||
result.People = tmpItem.People;
|
||||
result.Images = tmpItem.Images;
|
||||
result.RemoteImages = tmpItem.RemoteImages;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override FileSystemMetadata? GetXmlFile(ItemInfo info, IDirectoryService directoryService)
|
||||
{
|
||||
return MovieNfoSaver.GetMovieSavePaths(info)
|
||||
.Select(directoryService.GetFile)
|
||||
.FirstOrDefault(i => i is not null);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
using System.IO;
|
||||
using System.Threading;
|
||||
using MediaBrowser.Common.Configuration;
|
||||
using MediaBrowser.Controller.Entities.TV;
|
||||
using MediaBrowser.Controller.Library;
|
||||
using MediaBrowser.Controller.Providers;
|
||||
using MediaBrowser.Model.IO;
|
||||
using MediaBrowser.XbmcMetadata.Parsers;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace MediaBrowser.XbmcMetadata.Providers
|
||||
{
|
||||
/// <summary>
|
||||
/// Nfo provider for episodes.
|
||||
/// </summary>
|
||||
public class EpisodeNfoProvider : BaseNfoProvider<Episode>
|
||||
{
|
||||
private readonly ILogger<EpisodeNfoProvider> _logger;
|
||||
private readonly IConfigurationManager _config;
|
||||
private readonly IProviderManager _providerManager;
|
||||
private readonly IUserManager _userManager;
|
||||
private readonly IUserDataManager _userDataManager;
|
||||
private readonly IDirectoryService _directoryService;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="EpisodeNfoProvider"/> class.
|
||||
/// </summary>
|
||||
/// <param name="logger">Instance of the <see cref="ILogger{EpisodeNfoProvider}"/> interface.</param>
|
||||
/// <param name="fileSystem">Instance of the <see cref="IFileSystem"/> interface.</param>
|
||||
/// <param name="config">Instance of the <see cref="IConfigurationManager"/> interface.</param>
|
||||
/// <param name="providerManager">Instance of the <see cref="IProviderManager"/> interface.</param>
|
||||
/// <param name="userManager">Instance of the <see cref="IUserManager"/> interface.</param>
|
||||
/// <param name="userDataManager">Instance of the <see cref="IUserDataManager"/> interface.</param>
|
||||
/// <param name="directoryService">Instance of the <see cref="IDirectoryService"/> interface.</param>
|
||||
public EpisodeNfoProvider(
|
||||
ILogger<EpisodeNfoProvider> logger,
|
||||
IFileSystem fileSystem,
|
||||
IConfigurationManager config,
|
||||
IProviderManager providerManager,
|
||||
IUserManager userManager,
|
||||
IUserDataManager userDataManager,
|
||||
IDirectoryService directoryService)
|
||||
: base(fileSystem)
|
||||
{
|
||||
_logger = logger;
|
||||
_config = config;
|
||||
_providerManager = providerManager;
|
||||
_userManager = userManager;
|
||||
_userDataManager = userDataManager;
|
||||
_directoryService = directoryService;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Fetch(MetadataResult<Episode> result, string path, CancellationToken cancellationToken)
|
||||
{
|
||||
new EpisodeNfoParser(_logger, _config, _providerManager, _userManager, _userDataManager, _directoryService).Fetch(result, path, cancellationToken);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override FileSystemMetadata? GetXmlFile(ItemInfo info, IDirectoryService directoryService)
|
||||
{
|
||||
var path = Path.ChangeExtension(info.Path, ".nfo");
|
||||
|
||||
return directoryService.GetFile(path);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
using MediaBrowser.Common.Configuration;
|
||||
using MediaBrowser.Controller.Entities.Movies;
|
||||
using MediaBrowser.Controller.Library;
|
||||
using MediaBrowser.Controller.Providers;
|
||||
using MediaBrowser.Model.IO;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace MediaBrowser.XbmcMetadata.Providers
|
||||
{
|
||||
/// <summary>
|
||||
/// Nfo provider for movies.
|
||||
/// </summary>
|
||||
public class MovieNfoProvider : BaseVideoNfoProvider<Movie>
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="MovieNfoProvider"/> class.
|
||||
/// </summary>
|
||||
/// <param name="logger">Instance of the <see cref="ILogger{MovieNfoProvider}"/> interface.</param>
|
||||
/// <param name="fileSystem">Instance of the <see cref="IFileSystem"/> interface.</param>
|
||||
/// <param name="config">Instance of the <see cref="IConfigurationManager"/> interface.</param>
|
||||
/// <param name="providerManager">Instance of the <see cref="IProviderManager"/> interface.</param>
|
||||
/// <param name="userManager">Instance of the <see cref="IUserManager"/> interface.</param>
|
||||
/// <param name="userDataManager">Instance of the <see cref="IUserDataManager"/> interface.</param>
|
||||
/// <param name="directoryService">Instance of the <see cref="IDirectoryService"/> interface.</param>
|
||||
public MovieNfoProvider(
|
||||
ILogger<MovieNfoProvider> logger,
|
||||
IFileSystem fileSystem,
|
||||
IConfigurationManager config,
|
||||
IProviderManager providerManager,
|
||||
IUserManager userManager,
|
||||
IUserDataManager userDataManager,
|
||||
IDirectoryService directoryService)
|
||||
: base(logger, fileSystem, config, providerManager, userManager, userDataManager, directoryService)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
using MediaBrowser.Common.Configuration;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Controller.Library;
|
||||
using MediaBrowser.Controller.Providers;
|
||||
using MediaBrowser.Model.IO;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace MediaBrowser.XbmcMetadata.Providers
|
||||
{
|
||||
/// <summary>
|
||||
/// Nfo provider for music videos.
|
||||
/// </summary>
|
||||
public class MusicVideoNfoProvider : BaseVideoNfoProvider<MusicVideo>
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="MusicVideoNfoProvider"/> class.
|
||||
/// </summary>
|
||||
/// <param name="logger">Instance of the <see cref="ILogger{SeasonNfoProvider}"/> interface.</param>
|
||||
/// <param name="fileSystem">Instance of the <see cref="IFileSystem"/> interface.</param>
|
||||
/// <param name="config">Instance of the <see cref="IConfigurationManager"/> interface.</param>
|
||||
/// <param name="providerManager">Instance of the <see cref="IProviderManager"/> interface.</param>
|
||||
/// <param name="userManager">Instance of the <see cref="IUserManager"/> interface.</param>
|
||||
/// <param name="userDataManager">Instance of the <see cref="IUserDataManager"/> interface.</param>
|
||||
/// <param name="directoryService">Instance of the <see cref="IDirectoryService"/> interface.</param>
|
||||
public MusicVideoNfoProvider(
|
||||
ILogger<MusicVideoNfoProvider> logger,
|
||||
IFileSystem fileSystem,
|
||||
IConfigurationManager config,
|
||||
IProviderManager providerManager,
|
||||
IUserManager userManager,
|
||||
IUserDataManager userDataManager,
|
||||
IDirectoryService directoryService)
|
||||
: base(logger, fileSystem, config, providerManager, userManager, userDataManager, directoryService)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
using System.IO;
|
||||
using System.Threading;
|
||||
using MediaBrowser.Common.Configuration;
|
||||
using MediaBrowser.Controller.Entities.TV;
|
||||
using MediaBrowser.Controller.Library;
|
||||
using MediaBrowser.Controller.Providers;
|
||||
using MediaBrowser.Model.IO;
|
||||
using MediaBrowser.XbmcMetadata.Parsers;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace MediaBrowser.XbmcMetadata.Providers
|
||||
{
|
||||
/// <summary>
|
||||
/// Nfo provider for seasons.
|
||||
/// </summary>
|
||||
public class SeasonNfoProvider : BaseNfoProvider<Season>
|
||||
{
|
||||
private readonly ILogger<SeasonNfoProvider> _logger;
|
||||
private readonly IConfigurationManager _config;
|
||||
private readonly IProviderManager _providerManager;
|
||||
private readonly IUserManager _userManager;
|
||||
private readonly IUserDataManager _userDataManager;
|
||||
private readonly IDirectoryService _directoryService;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="SeasonNfoProvider"/> class.
|
||||
/// </summary>
|
||||
/// <param name="logger">Instance of the <see cref="ILogger{SeasonNfoProvider}"/> interface.</param>
|
||||
/// <param name="fileSystem">Instance of the <see cref="IFileSystem"/> interface.</param>
|
||||
/// <param name="config">Instance of the <see cref="IConfigurationManager"/> interface.</param>
|
||||
/// <param name="providerManager">Instance of the <see cref="IProviderManager"/> interface.</param>
|
||||
/// <param name="userManager">Instance of the <see cref="IUserManager"/> interface.</param>
|
||||
/// <param name="userDataManager">Instance of the <see cref="IUserDataManager"/> interface.</param>
|
||||
/// <param name="directoryService">Instance of the <see cref="IDirectoryService"/> interface.</param>
|
||||
public SeasonNfoProvider(
|
||||
ILogger<SeasonNfoProvider> logger,
|
||||
IFileSystem fileSystem,
|
||||
IConfigurationManager config,
|
||||
IProviderManager providerManager,
|
||||
IUserManager userManager,
|
||||
IUserDataManager userDataManager,
|
||||
IDirectoryService directoryService)
|
||||
: base(fileSystem)
|
||||
{
|
||||
_logger = logger;
|
||||
_config = config;
|
||||
_providerManager = providerManager;
|
||||
_userManager = userManager;
|
||||
_userDataManager = userDataManager;
|
||||
_directoryService = directoryService;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Fetch(MetadataResult<Season> result, string path, CancellationToken cancellationToken)
|
||||
{
|
||||
new SeasonNfoParser(_logger, _config, _providerManager, _userManager, _userDataManager, _directoryService).Fetch(result, path, cancellationToken);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override FileSystemMetadata? GetXmlFile(ItemInfo info, IDirectoryService directoryService)
|
||||
=> directoryService.GetFile(Path.Combine(info.Path, "season.nfo"));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
using System.IO;
|
||||
using System.Threading;
|
||||
using MediaBrowser.Common.Configuration;
|
||||
using MediaBrowser.Controller.Entities.TV;
|
||||
using MediaBrowser.Controller.Library;
|
||||
using MediaBrowser.Controller.Providers;
|
||||
using MediaBrowser.Model.IO;
|
||||
using MediaBrowser.XbmcMetadata.Parsers;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace MediaBrowser.XbmcMetadata.Providers
|
||||
{
|
||||
/// <summary>
|
||||
/// Nfo provider for series.
|
||||
/// </summary>
|
||||
public class SeriesNfoProvider : BaseNfoProvider<Series>
|
||||
{
|
||||
private readonly ILogger<SeriesNfoProvider> _logger;
|
||||
private readonly IConfigurationManager _config;
|
||||
private readonly IProviderManager _providerManager;
|
||||
private readonly IUserManager _userManager;
|
||||
private readonly IUserDataManager _userDataManager;
|
||||
private readonly IDirectoryService _directoryService;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="SeriesNfoProvider"/> class.
|
||||
/// </summary>
|
||||
/// <param name="logger">Instance of the <see cref="ILogger{SeriesNfoProvider}"/> interface.</param>
|
||||
/// <param name="fileSystem">Instance of the <see cref="IFileSystem"/> interface.</param>
|
||||
/// <param name="config">Instance of the <see cref="IConfigurationManager"/> interface.</param>
|
||||
/// <param name="providerManager">Instance of the <see cref="IProviderManager"/> interface.</param>
|
||||
/// <param name="userManager">Instance of the <see cref="IUserManager"/> interface.</param>
|
||||
/// <param name="userDataManager">Instance of the <see cref="IUserDataManager"/> interface.</param>
|
||||
/// <param name="directoryService">Instance of the <see cref="IDirectoryService"/> interface.</param>
|
||||
public SeriesNfoProvider(
|
||||
ILogger<SeriesNfoProvider> logger,
|
||||
IFileSystem fileSystem,
|
||||
IConfigurationManager config,
|
||||
IProviderManager providerManager,
|
||||
IUserManager userManager,
|
||||
IUserDataManager userDataManager,
|
||||
IDirectoryService directoryService)
|
||||
: base(fileSystem)
|
||||
{
|
||||
_logger = logger;
|
||||
_config = config;
|
||||
_providerManager = providerManager;
|
||||
_userManager = userManager;
|
||||
_userDataManager = userDataManager;
|
||||
_directoryService = directoryService;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Fetch(MetadataResult<Series> result, string path, CancellationToken cancellationToken)
|
||||
{
|
||||
new SeriesNfoParser(_logger, _config, _providerManager, _userManager, _userDataManager, _directoryService).Fetch(result, path, cancellationToken);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override FileSystemMetadata? GetXmlFile(ItemInfo info, IDirectoryService directoryService)
|
||||
=> directoryService.GetFile(Path.Combine(info.Path, "tvshow.nfo"));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
using System.IO;
|
||||
using System.Threading;
|
||||
using MediaBrowser.Common.Configuration;
|
||||
using MediaBrowser.Controller.Entities.TV;
|
||||
using MediaBrowser.Controller.Library;
|
||||
using MediaBrowser.Controller.Providers;
|
||||
using MediaBrowser.Model.IO;
|
||||
using MediaBrowser.XbmcMetadata.Parsers;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace MediaBrowser.XbmcMetadata.Providers
|
||||
{
|
||||
/// <summary>
|
||||
/// NFO provider for seasons based on series NFO.
|
||||
/// </summary>
|
||||
public class SeriesNfoSeasonProvider : BaseNfoProvider<Season>
|
||||
{
|
||||
private readonly ILogger<SeriesNfoSeasonProvider> _logger;
|
||||
private readonly IConfigurationManager _config;
|
||||
private readonly IProviderManager _providerManager;
|
||||
private readonly IUserManager _userManager;
|
||||
private readonly IUserDataManager _userDataManager;
|
||||
private readonly IDirectoryService _directoryService;
|
||||
private readonly ILibraryManager _libraryManager;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="SeriesNfoSeasonProvider"/> class.
|
||||
/// </summary>
|
||||
/// <param name="logger">Instance of the <see cref="ILogger{SeasonFromSeriesNfoProvider}"/> interface.</param>
|
||||
/// <param name="fileSystem">Instance of the <see cref="IFileSystem"/> interface.</param>
|
||||
/// <param name="config">Instance of the <see cref="IConfigurationManager"/> interface.</param>
|
||||
/// <param name="providerManager">Instance of the <see cref="IProviderManager"/> interface.</param>
|
||||
/// <param name="userManager">Instance of the <see cref="IUserManager"/> interface.</param>
|
||||
/// <param name="userDataManager">Instance of the <see cref="IUserDataManager"/> interface.</param>
|
||||
/// <param name="directoryService">Instance of the <see cref="IDirectoryService"/> interface.</param>
|
||||
/// <param name="libraryManager">Instance of the <see cref="ILibraryManager"/> interface.</param>
|
||||
public SeriesNfoSeasonProvider(
|
||||
ILogger<SeriesNfoSeasonProvider> logger,
|
||||
IFileSystem fileSystem,
|
||||
IConfigurationManager config,
|
||||
IProviderManager providerManager,
|
||||
IUserManager userManager,
|
||||
IUserDataManager userDataManager,
|
||||
IDirectoryService directoryService,
|
||||
ILibraryManager libraryManager)
|
||||
: base(fileSystem)
|
||||
{
|
||||
_logger = logger;
|
||||
_config = config;
|
||||
_providerManager = providerManager;
|
||||
_userManager = userManager;
|
||||
_userDataManager = userDataManager;
|
||||
_directoryService = directoryService;
|
||||
_libraryManager = libraryManager;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Fetch(MetadataResult<Season> result, string path, CancellationToken cancellationToken)
|
||||
{
|
||||
new SeriesNfoSeasonParser(_logger, _config, _providerManager, _userManager, _userDataManager, _directoryService).Fetch(result, path, cancellationToken);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override FileSystemMetadata? GetXmlFile(ItemInfo info, IDirectoryService directoryService)
|
||||
{
|
||||
var seasonPath = info.Path;
|
||||
if (seasonPath is not null)
|
||||
{
|
||||
var path = Path.Combine(seasonPath, "tvshow.nfo");
|
||||
if (Path.Exists(path))
|
||||
{
|
||||
return directoryService.GetFile(path);
|
||||
}
|
||||
}
|
||||
|
||||
var seriesPath = _libraryManager.GetItemById(info.ParentId)?.Path;
|
||||
if (seriesPath is not null)
|
||||
{
|
||||
var path = Path.Combine(seriesPath, "tvshow.nfo");
|
||||
if (Path.Exists(path))
|
||||
{
|
||||
return directoryService.GetFile(path);
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
using MediaBrowser.Common.Configuration;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Controller.Library;
|
||||
using MediaBrowser.Controller.Providers;
|
||||
using MediaBrowser.Model.IO;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace MediaBrowser.XbmcMetadata.Providers
|
||||
{
|
||||
/// <summary>
|
||||
/// Nfo provider for videos.
|
||||
/// </summary>
|
||||
public class VideoNfoProvider : BaseVideoNfoProvider<Video>
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="VideoNfoProvider"/> class.
|
||||
/// </summary>
|
||||
/// <param name="logger">Instance of the <see cref="ILogger{VideoNfoProvider}"/> interface.</param>
|
||||
/// <param name="fileSystem">Instance of the <see cref="IFileSystem"/> interface.</param>
|
||||
/// <param name="config">Instance of the <see cref="IConfigurationManager"/> interface.</param>
|
||||
/// <param name="providerManager">Instance of the <see cref="IProviderManager"/> interface.</param>
|
||||
/// <param name="userManager">Instance of the <see cref="IUserManager"/> interface.</param>
|
||||
/// <param name="userDataManager">Instance of the <see cref="IUserDataManager"/> interface.</param>
|
||||
/// <param name="directoryService">Instance of the <see cref="IDirectoryService"/> interface.</param>
|
||||
public VideoNfoProvider(
|
||||
ILogger<VideoNfoProvider> logger,
|
||||
IFileSystem fileSystem,
|
||||
IConfigurationManager config,
|
||||
IProviderManager providerManager,
|
||||
IUserManager userManager,
|
||||
IUserDataManager userDataManager,
|
||||
IDirectoryService directoryService)
|
||||
: base(logger, fileSystem, config, providerManager, userManager, userDataManager, directoryService)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,121 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Xml;
|
||||
using Jellyfin.Extensions;
|
||||
using MediaBrowser.Controller.Configuration;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Controller.Entities.Audio;
|
||||
using MediaBrowser.Controller.Library;
|
||||
using MediaBrowser.Model.IO;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace MediaBrowser.XbmcMetadata.Savers
|
||||
{
|
||||
/// <summary>
|
||||
/// Nfo saver for albums.
|
||||
/// </summary>
|
||||
public class AlbumNfoSaver : BaseNfoSaver
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="AlbumNfoSaver"/> class.
|
||||
/// </summary>
|
||||
/// <param name="fileSystem">The file system.</param>
|
||||
/// <param name="configurationManager">the server configuration manager.</param>
|
||||
/// <param name="libraryManager">The library manager.</param>
|
||||
/// <param name="userManager">The user manager.</param>
|
||||
/// <param name="userDataManager">The user data manager.</param>
|
||||
/// <param name="logger">The logger.</param>
|
||||
public AlbumNfoSaver(
|
||||
IFileSystem fileSystem,
|
||||
IServerConfigurationManager configurationManager,
|
||||
ILibraryManager libraryManager,
|
||||
IUserManager userManager,
|
||||
IUserDataManager userDataManager,
|
||||
ILogger<AlbumNfoSaver> logger)
|
||||
: base(fileSystem, configurationManager, libraryManager, userManager, userDataManager, logger)
|
||||
{
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override string GetLocalSavePath(BaseItem item)
|
||||
=> Path.Combine(item.Path, "album.nfo");
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override string GetRootElementName(BaseItem item)
|
||||
=> "album";
|
||||
|
||||
/// <inheritdoc />
|
||||
public override bool IsEnabledFor(BaseItem item, ItemUpdateType updateType)
|
||||
=> item.SupportsLocalMetadata && item is MusicAlbum && updateType >= MinimumUpdateType;
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void WriteCustomElements(BaseItem item, XmlWriter writer)
|
||||
{
|
||||
var album = (MusicAlbum)item;
|
||||
|
||||
foreach (var artist in album.Artists.Trimmed().OrderBy(artist => artist))
|
||||
{
|
||||
writer.WriteElementString("artist", artist);
|
||||
}
|
||||
|
||||
foreach (var artist in album.AlbumArtists.Trimmed().OrderBy(artist => artist))
|
||||
{
|
||||
writer.WriteElementString("albumartist", artist);
|
||||
}
|
||||
|
||||
AddTracks(album.Tracks, writer);
|
||||
}
|
||||
|
||||
private void AddTracks(IEnumerable<BaseItem> tracks, XmlWriter writer)
|
||||
{
|
||||
foreach (var track in tracks
|
||||
.OrderBy(i => i.ParentIndexNumber ?? 0)
|
||||
.ThenBy(i => i.IndexNumber ?? 0)
|
||||
.ThenBy(i => SortNameOrName(i))
|
||||
.ThenBy(i => i.Name?.Trim()))
|
||||
{
|
||||
writer.WriteStartElement("track");
|
||||
|
||||
if (track.ParentIndexNumber.HasValue && track.ParentIndexNumber.Value != 0)
|
||||
{
|
||||
writer.WriteElementString("disc", track.ParentIndexNumber.Value.ToString(CultureInfo.InvariantCulture));
|
||||
}
|
||||
|
||||
if (track.IndexNumber.HasValue && track.IndexNumber.Value != 0)
|
||||
{
|
||||
writer.WriteElementString("position", track.IndexNumber.Value.ToString(CultureInfo.InvariantCulture));
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(track.Name))
|
||||
{
|
||||
writer.WriteElementString("title", track.Name);
|
||||
}
|
||||
|
||||
if (track.RunTimeTicks.HasValue)
|
||||
{
|
||||
var time = TimeSpan.FromTicks(track.RunTimeTicks.Value).ToString(@"mm\:ss", CultureInfo.InvariantCulture);
|
||||
|
||||
writer.WriteElementString("duration", time);
|
||||
}
|
||||
|
||||
writer.WriteEndElement();
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override IEnumerable<string> GetTagsUsed(BaseItem item)
|
||||
{
|
||||
foreach (var tag in base.GetTagsUsed(item))
|
||||
{
|
||||
yield return tag;
|
||||
}
|
||||
|
||||
yield return "track";
|
||||
yield return "artist";
|
||||
yield return "albumartist";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,106 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Xml;
|
||||
using MediaBrowser.Controller.Configuration;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Controller.Entities.Audio;
|
||||
using MediaBrowser.Controller.Library;
|
||||
using MediaBrowser.Model.IO;
|
||||
using MediaBrowser.XbmcMetadata.Configuration;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace MediaBrowser.XbmcMetadata.Savers
|
||||
{
|
||||
/// <summary>
|
||||
/// Nfo saver for artist.
|
||||
/// </summary>
|
||||
public class ArtistNfoSaver : BaseNfoSaver
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ArtistNfoSaver"/> class.
|
||||
/// </summary>
|
||||
/// <param name="fileSystem">The file system.</param>
|
||||
/// <param name="configurationManager">the server configuration manager.</param>
|
||||
/// <param name="libraryManager">The library manager.</param>
|
||||
/// <param name="userManager">The user manager.</param>
|
||||
/// <param name="userDataManager">The user data manager.</param>
|
||||
/// <param name="logger">The logger.</param>
|
||||
public ArtistNfoSaver(
|
||||
IFileSystem fileSystem,
|
||||
IServerConfigurationManager configurationManager,
|
||||
ILibraryManager libraryManager,
|
||||
IUserManager userManager,
|
||||
IUserDataManager userDataManager,
|
||||
ILogger<ArtistNfoSaver> logger)
|
||||
: base(fileSystem, configurationManager, libraryManager, userManager, userDataManager, logger)
|
||||
{
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override string GetLocalSavePath(BaseItem item)
|
||||
=> Path.Combine(item.Path, "artist.nfo");
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override string GetRootElementName(BaseItem item)
|
||||
=> "artist";
|
||||
|
||||
/// <inheritdoc />
|
||||
public override bool IsEnabledFor(BaseItem item, ItemUpdateType updateType)
|
||||
=> item.SupportsLocalMetadata && item is MusicArtist && updateType >= MinimumUpdateType;
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void WriteCustomElements(BaseItem item, XmlWriter writer)
|
||||
{
|
||||
var artist = (MusicArtist)item;
|
||||
|
||||
if (artist.EndDate.HasValue)
|
||||
{
|
||||
var formatString = ConfigurationManager.GetNfoConfiguration().ReleaseDateFormat;
|
||||
|
||||
writer.WriteElementString("disbanded", artist.EndDate.Value.ToString(formatString, CultureInfo.InvariantCulture));
|
||||
}
|
||||
|
||||
var albums = artist
|
||||
.GetRecursiveChildren(i => i is MusicAlbum);
|
||||
|
||||
AddAlbums(albums, writer);
|
||||
}
|
||||
|
||||
private void AddAlbums(IReadOnlyList<BaseItem> albums, XmlWriter writer)
|
||||
{
|
||||
foreach (var album in albums
|
||||
.OrderBy(album => album.ProductionYear ?? 0)
|
||||
.ThenBy(album => SortNameOrName(album))
|
||||
.ThenBy(album => album.Name?.Trim()))
|
||||
{
|
||||
writer.WriteStartElement("album");
|
||||
|
||||
if (!string.IsNullOrEmpty(album.Name))
|
||||
{
|
||||
writer.WriteElementString("title", album.Name);
|
||||
}
|
||||
|
||||
if (album.ProductionYear.HasValue)
|
||||
{
|
||||
writer.WriteElementString("year", album.ProductionYear.Value.ToString(CultureInfo.InvariantCulture));
|
||||
}
|
||||
|
||||
writer.WriteEndElement();
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override IEnumerable<string> GetTagsUsed(BaseItem item)
|
||||
{
|
||||
foreach (var tag in base.GetTagsUsed(item))
|
||||
{
|
||||
yield return tag;
|
||||
}
|
||||
|
||||
yield return "album";
|
||||
yield return "disbanded";
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,131 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Xml;
|
||||
using MediaBrowser.Controller.Configuration;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Controller.Entities.TV;
|
||||
using MediaBrowser.Controller.Library;
|
||||
using MediaBrowser.Model.IO;
|
||||
using MediaBrowser.XbmcMetadata.Configuration;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace MediaBrowser.XbmcMetadata.Savers
|
||||
{
|
||||
/// <summary>
|
||||
/// Nfo saver for episodes.
|
||||
/// </summary>
|
||||
public class EpisodeNfoSaver : BaseNfoSaver
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="EpisodeNfoSaver"/> class.
|
||||
/// </summary>
|
||||
/// <param name="fileSystem">The file system.</param>
|
||||
/// <param name="configurationManager">the server configuration manager.</param>
|
||||
/// <param name="libraryManager">The library manager.</param>
|
||||
/// <param name="userManager">The user manager.</param>
|
||||
/// <param name="userDataManager">The user data manager.</param>
|
||||
/// <param name="logger">The logger.</param>
|
||||
public EpisodeNfoSaver(
|
||||
IFileSystem fileSystem,
|
||||
IServerConfigurationManager configurationManager,
|
||||
ILibraryManager libraryManager,
|
||||
IUserManager userManager,
|
||||
IUserDataManager userDataManager,
|
||||
ILogger<EpisodeNfoSaver> logger)
|
||||
: base(fileSystem, configurationManager, libraryManager, userManager, userDataManager, logger)
|
||||
{
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override string GetLocalSavePath(BaseItem item)
|
||||
=> Path.ChangeExtension(item.Path, ".nfo");
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override string GetRootElementName(BaseItem item)
|
||||
=> "episodedetails";
|
||||
|
||||
/// <inheritdoc />
|
||||
public override bool IsEnabledFor(BaseItem item, ItemUpdateType updateType)
|
||||
=> item.SupportsLocalMetadata && item is Episode && updateType >= MinimumUpdateType;
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void WriteCustomElements(BaseItem item, XmlWriter writer)
|
||||
{
|
||||
var episode = (Episode)item;
|
||||
|
||||
writer.WriteElementString("showtitle", episode.SeriesName);
|
||||
|
||||
if (episode.IndexNumber.HasValue)
|
||||
{
|
||||
writer.WriteElementString("episode", episode.IndexNumber.Value.ToString(CultureInfo.InvariantCulture));
|
||||
}
|
||||
|
||||
if (episode.IndexNumberEnd.HasValue)
|
||||
{
|
||||
writer.WriteElementString("episodenumberend", episode.IndexNumberEnd.Value.ToString(CultureInfo.InvariantCulture));
|
||||
}
|
||||
|
||||
if (episode.ParentIndexNumber.HasValue)
|
||||
{
|
||||
writer.WriteElementString("season", episode.ParentIndexNumber.Value.ToString(CultureInfo.InvariantCulture));
|
||||
}
|
||||
|
||||
if (episode.PremiereDate.HasValue)
|
||||
{
|
||||
var formatString = ConfigurationManager.GetNfoConfiguration().ReleaseDateFormat;
|
||||
|
||||
writer.WriteElementString("aired", episode.PremiereDate.Value.ToString(formatString, CultureInfo.InvariantCulture));
|
||||
}
|
||||
|
||||
if (!episode.ParentIndexNumber.HasValue || episode.ParentIndexNumber.Value == 0)
|
||||
{
|
||||
if (episode.AirsAfterSeasonNumber.HasValue && episode.AirsAfterSeasonNumber.Value != -1)
|
||||
{
|
||||
writer.WriteElementString("airsafter_season", episode.AirsAfterSeasonNumber.Value.ToString(CultureInfo.InvariantCulture));
|
||||
}
|
||||
|
||||
if (episode.AirsBeforeEpisodeNumber.HasValue && episode.AirsBeforeEpisodeNumber.Value != -1)
|
||||
{
|
||||
writer.WriteElementString("airsbefore_episode", episode.AirsBeforeEpisodeNumber.Value.ToString(CultureInfo.InvariantCulture));
|
||||
}
|
||||
|
||||
if (episode.AirsBeforeSeasonNumber.HasValue && episode.AirsBeforeSeasonNumber.Value != -1)
|
||||
{
|
||||
writer.WriteElementString("airsbefore_season", episode.AirsBeforeSeasonNumber.Value.ToString(CultureInfo.InvariantCulture));
|
||||
}
|
||||
|
||||
if (episode.AirsBeforeEpisodeNumber.HasValue && episode.AirsBeforeEpisodeNumber.Value != -1)
|
||||
{
|
||||
writer.WriteElementString("displayepisode", episode.AirsBeforeEpisodeNumber.Value.ToString(CultureInfo.InvariantCulture));
|
||||
}
|
||||
|
||||
var specialSeason = episode.AiredSeasonNumber;
|
||||
if (specialSeason.HasValue && specialSeason.Value != -1)
|
||||
{
|
||||
writer.WriteElementString("displayseason", specialSeason.Value.ToString(CultureInfo.InvariantCulture));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override IEnumerable<string> GetTagsUsed(BaseItem item)
|
||||
{
|
||||
foreach (var tag in base.GetTagsUsed(item))
|
||||
{
|
||||
yield return tag;
|
||||
}
|
||||
|
||||
yield return "aired";
|
||||
yield return "season";
|
||||
yield return "episode";
|
||||
yield return "episodenumberend";
|
||||
yield return "airsafter_season";
|
||||
yield return "airsbefore_episode";
|
||||
yield return "airsbefore_season";
|
||||
yield return "displayseason";
|
||||
yield return "displayepisode";
|
||||
yield return "showtitle";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,138 @@
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Xml;
|
||||
using Jellyfin.Extensions;
|
||||
using MediaBrowser.Controller.Configuration;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Controller.Entities.Movies;
|
||||
using MediaBrowser.Controller.Entities.TV;
|
||||
using MediaBrowser.Controller.Library;
|
||||
using MediaBrowser.Controller.Providers;
|
||||
using MediaBrowser.Model.Entities;
|
||||
using MediaBrowser.Model.IO;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace MediaBrowser.XbmcMetadata.Savers
|
||||
{
|
||||
/// <summary>
|
||||
/// Nfo saver for movies.
|
||||
/// </summary>
|
||||
public class MovieNfoSaver : BaseNfoSaver
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="MovieNfoSaver"/> class.
|
||||
/// </summary>
|
||||
/// <param name="fileSystem">The file system.</param>
|
||||
/// <param name="configurationManager">the server configuration manager.</param>
|
||||
/// <param name="libraryManager">The library manager.</param>
|
||||
/// <param name="userManager">The user manager.</param>
|
||||
/// <param name="userDataManager">The user data manager.</param>
|
||||
/// <param name="logger">The logger.</param>
|
||||
public MovieNfoSaver(
|
||||
IFileSystem fileSystem,
|
||||
IServerConfigurationManager configurationManager,
|
||||
ILibraryManager libraryManager,
|
||||
IUserManager userManager,
|
||||
IUserDataManager userDataManager,
|
||||
ILogger<MovieNfoSaver> logger)
|
||||
: base(fileSystem, configurationManager, libraryManager, userManager, userDataManager, logger)
|
||||
{
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override string GetLocalSavePath(BaseItem item)
|
||||
=> GetMovieSavePaths(new ItemInfo(item)).FirstOrDefault() ?? Path.ChangeExtension(item.Path, ".nfo");
|
||||
|
||||
internal static IEnumerable<string> GetMovieSavePaths(ItemInfo item)
|
||||
{
|
||||
var path = item.ContainingFolderPath;
|
||||
if (item.VideoType == VideoType.Dvd && !item.IsPlaceHolder)
|
||||
{
|
||||
yield return Path.Combine(path, "VIDEO_TS", "VIDEO_TS.nfo");
|
||||
}
|
||||
|
||||
// only allow movie object to read movie.nfo, not owned videos (which will be itemtype video, not movie)
|
||||
if (!item.IsInMixedFolder && item.ItemType == typeof(Movie))
|
||||
{
|
||||
yield return Path.Combine(path, "movie.nfo");
|
||||
}
|
||||
|
||||
if (!item.IsPlaceHolder && (item.VideoType == VideoType.Dvd || item.VideoType == VideoType.BluRay))
|
||||
{
|
||||
yield return Path.Combine(path, Path.GetFileName(path) + ".nfo");
|
||||
}
|
||||
else
|
||||
{
|
||||
yield return Path.ChangeExtension(item.Path, ".nfo");
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override string GetRootElementName(BaseItem item)
|
||||
=> item is MusicVideo ? "musicvideo" : "movie";
|
||||
|
||||
/// <inheritdoc />
|
||||
public override bool IsEnabledFor(BaseItem item, ItemUpdateType updateType)
|
||||
{
|
||||
if (!item.SupportsLocalMetadata)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check parent for null to avoid running this against things like video backdrops
|
||||
if (item is Video video && item is not Episode && !video.ExtraType.HasValue)
|
||||
{
|
||||
return updateType >= MinimumUpdateType;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void WriteCustomElements(BaseItem item, XmlWriter writer)
|
||||
{
|
||||
if (item.TryGetProviderId(MetadataProvider.Imdb, out var imdb))
|
||||
{
|
||||
writer.WriteElementString("id", imdb);
|
||||
}
|
||||
|
||||
if (item is MusicVideo musicVideo)
|
||||
{
|
||||
foreach (var artist in musicVideo.Artists.Trimmed().OrderBy(artist => artist))
|
||||
{
|
||||
writer.WriteElementString("artist", artist);
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(musicVideo.Album))
|
||||
{
|
||||
writer.WriteElementString("album", musicVideo.Album);
|
||||
}
|
||||
}
|
||||
|
||||
if (item is Movie movie)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(movie.CollectionName))
|
||||
{
|
||||
writer.WriteStartElement("set");
|
||||
writer.WriteElementString("name", movie.CollectionName);
|
||||
writer.WriteEndElement();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override IEnumerable<string> GetTagsUsed(BaseItem item)
|
||||
{
|
||||
foreach (var tag in base.GetTagsUsed(item))
|
||||
{
|
||||
yield return tag;
|
||||
}
|
||||
|
||||
yield return "album";
|
||||
yield return "artist";
|
||||
yield return "set";
|
||||
yield return "id";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Xml;
|
||||
using MediaBrowser.Controller.Configuration;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Controller.Entities.TV;
|
||||
using MediaBrowser.Controller.Library;
|
||||
using MediaBrowser.Model.IO;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace MediaBrowser.XbmcMetadata.Savers
|
||||
{
|
||||
/// <summary>
|
||||
/// Nfo saver for seasons.
|
||||
/// </summary>
|
||||
public class SeasonNfoSaver : BaseNfoSaver
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="SeasonNfoSaver"/> class.
|
||||
/// </summary>
|
||||
/// <param name="fileSystem">The file system.</param>
|
||||
/// <param name="configurationManager">the server configuration manager.</param>
|
||||
/// <param name="libraryManager">The library manager.</param>
|
||||
/// <param name="userManager">The user manager.</param>
|
||||
/// <param name="userDataManager">The user data manager.</param>
|
||||
/// <param name="logger">The logger.</param>
|
||||
public SeasonNfoSaver(
|
||||
IFileSystem fileSystem,
|
||||
IServerConfigurationManager configurationManager,
|
||||
ILibraryManager libraryManager,
|
||||
IUserManager userManager,
|
||||
IUserDataManager userDataManager,
|
||||
ILogger<SeasonNfoSaver> logger)
|
||||
: base(fileSystem, configurationManager, libraryManager, userManager, userDataManager, logger)
|
||||
{
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override string GetLocalSavePath(BaseItem item)
|
||||
=> Path.Combine(item.Path, "season.nfo");
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override string GetRootElementName(BaseItem item)
|
||||
=> "season";
|
||||
|
||||
/// <inheritdoc />
|
||||
public override bool IsEnabledFor(BaseItem item, ItemUpdateType updateType)
|
||||
{
|
||||
if (!item.SupportsLocalMetadata)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (item is not Season)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return updateType >= MinimumUpdateType || (updateType >= ItemUpdateType.MetadataImport && File.Exists(GetSavePath(item)));
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void WriteCustomElements(BaseItem item, XmlWriter writer)
|
||||
{
|
||||
var season = (Season)item;
|
||||
|
||||
if (season.IndexNumber.HasValue)
|
||||
{
|
||||
writer.WriteElementString("seasonnumber", season.IndexNumber.Value.ToString(CultureInfo.InvariantCulture));
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override IEnumerable<string> GetTagsUsed(BaseItem item)
|
||||
{
|
||||
foreach (var tag in base.GetTagsUsed(item))
|
||||
{
|
||||
yield return tag;
|
||||
}
|
||||
|
||||
yield return "seasonnumber";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,106 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Xml;
|
||||
using MediaBrowser.Controller.Configuration;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Controller.Entities.TV;
|
||||
using MediaBrowser.Controller.Library;
|
||||
using MediaBrowser.Model.Entities;
|
||||
using MediaBrowser.Model.IO;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace MediaBrowser.XbmcMetadata.Savers
|
||||
{
|
||||
/// <summary>
|
||||
/// Nfo saver for series.
|
||||
/// </summary>
|
||||
public class SeriesNfoSaver : BaseNfoSaver
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="SeriesNfoSaver"/> class.
|
||||
/// </summary>
|
||||
/// <param name="fileSystem">The file system.</param>
|
||||
/// <param name="configurationManager">the server configuration manager.</param>
|
||||
/// <param name="libraryManager">The library manager.</param>
|
||||
/// <param name="userManager">The user manager.</param>
|
||||
/// <param name="userDataManager">The user data manager.</param>
|
||||
/// <param name="logger">The logger.</param>
|
||||
public SeriesNfoSaver(
|
||||
IFileSystem fileSystem,
|
||||
IServerConfigurationManager configurationManager,
|
||||
ILibraryManager libraryManager,
|
||||
IUserManager userManager,
|
||||
IUserDataManager userDataManager,
|
||||
ILogger<SeriesNfoSaver> logger)
|
||||
: base(fileSystem, configurationManager, libraryManager, userManager, userDataManager, logger)
|
||||
{
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override string GetLocalSavePath(BaseItem item)
|
||||
=> Path.Combine(item.Path, "tvshow.nfo");
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override string GetRootElementName(BaseItem item)
|
||||
=> "tvshow";
|
||||
|
||||
/// <inheritdoc />
|
||||
public override bool IsEnabledFor(BaseItem item, ItemUpdateType updateType)
|
||||
=> item.SupportsLocalMetadata && item is Series && updateType >= MinimumUpdateType;
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void WriteCustomElements(BaseItem item, XmlWriter writer)
|
||||
{
|
||||
var series = (Series)item;
|
||||
|
||||
if (item.TryGetProviderId(MetadataProvider.Tvdb, out var tvdb))
|
||||
{
|
||||
writer.WriteElementString("id", tvdb);
|
||||
|
||||
writer.WriteStartElement("episodeguide");
|
||||
|
||||
var language = item.GetPreferredMetadataLanguage();
|
||||
language = string.IsNullOrEmpty(language)
|
||||
? "en"
|
||||
: language;
|
||||
|
||||
writer.WriteStartElement("url");
|
||||
writer.WriteAttributeString("cache", tvdb + ".xml");
|
||||
writer.WriteString(
|
||||
string.Format(
|
||||
CultureInfo.InvariantCulture,
|
||||
"http://www.thetvdb.com/api/1D62F2F90030C444/series/{0}/all/{1}.zip",
|
||||
tvdb,
|
||||
language));
|
||||
writer.WriteEndElement();
|
||||
|
||||
writer.WriteEndElement();
|
||||
}
|
||||
|
||||
writer.WriteElementString("season", "-1");
|
||||
writer.WriteElementString("episode", "-1");
|
||||
|
||||
if (series.Status.HasValue)
|
||||
{
|
||||
writer.WriteElementString("status", series.Status.Value.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override IEnumerable<string> GetTagsUsed(BaseItem item)
|
||||
{
|
||||
foreach (var tag in base.GetTagsUsed(item))
|
||||
{
|
||||
yield return tag;
|
||||
}
|
||||
|
||||
yield return "id";
|
||||
yield return "episodeguide";
|
||||
yield return "season";
|
||||
yield return "episode";
|
||||
yield return "status";
|
||||
yield return "displayorder";
|
||||
}
|
||||
}
|
||||
}
|
||||
+4
@@ -0,0 +1,4 @@
|
||||
// <autogenerated />
|
||||
using System;
|
||||
using System.Reflection;
|
||||
[assembly: global::System.Runtime.Versioning.TargetFrameworkAttribute(".NETCoreApp,Version=v10.0", FrameworkDisplayName = ".NET 10.0")]
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
is_global = true
|
||||
build_property.TargetFramework = net10.0
|
||||
build_property.TargetFramework = net10.0
|
||||
build_property.TargetFrameworkIdentifier = .NETCoreApp
|
||||
build_property.TargetFrameworkIdentifier = .NETCoreApp
|
||||
build_property.TargetFrameworkVersion = v10.0
|
||||
build_property.TargetFrameworkVersion = v10.0
|
||||
build_property.TargetPlatformMinVersion =
|
||||
build_property.TargetPlatformMinVersion =
|
||||
build_property.UsingMicrosoftNETSdkWeb =
|
||||
build_property.UsingMicrosoftNETSdkWeb =
|
||||
build_property.ProjectTypeGuids =
|
||||
build_property.ProjectTypeGuids =
|
||||
build_property.InvariantGlobalization =
|
||||
build_property.InvariantGlobalization =
|
||||
build_property.PlatformNeutralAssembly =
|
||||
build_property.PlatformNeutralAssembly =
|
||||
build_property.EnforceExtendedAnalyzerRules =
|
||||
build_property.EnforceExtendedAnalyzerRules =
|
||||
build_property._SupportedPlatformList = Linux,macOS,Windows
|
||||
build_property._SupportedPlatformList = Linux,macOS,Windows
|
||||
build_property.RootNamespace = MediaBrowser.XbmcMetadata
|
||||
build_property.ProjectDir = /srv/common_drive/Projects/pgsql-jellyfin/MediaBrowser.XbmcMetadata/
|
||||
build_property.EnableComHosting =
|
||||
build_property.EnableGeneratedComInterfaceComImportInterop =
|
||||
build_property.EffectiveAnalysisLevelStyle = 10.0
|
||||
build_property.EnableCodeStyleSeverity =
|
||||
Binary file not shown.
BIN
Binary file not shown.
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,26 @@
|
||||
<?xml version="1.0" encoding="utf-8" standalone="no"?>
|
||||
<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup Condition=" '$(ExcludeRestorePackageImports)' != 'true' ">
|
||||
<RestoreSuccess Condition=" '$(RestoreSuccess)' == '' ">True</RestoreSuccess>
|
||||
<RestoreTool Condition=" '$(RestoreTool)' == '' ">NuGet</RestoreTool>
|
||||
<ProjectAssetsFile Condition=" '$(ProjectAssetsFile)' == '' ">$(MSBuildThisFileDirectory)project.assets.json</ProjectAssetsFile>
|
||||
<NuGetPackageRoot Condition=" '$(NuGetPackageRoot)' == '' ">/home/wjones/.nuget/packages/</NuGetPackageRoot>
|
||||
<NuGetPackageFolders Condition=" '$(NuGetPackageFolders)' == '' ">/home/wjones/.nuget/packages/</NuGetPackageFolders>
|
||||
<NuGetProjectStyle Condition=" '$(NuGetProjectStyle)' == '' ">PackageReference</NuGetProjectStyle>
|
||||
<NuGetToolVersion Condition=" '$(NuGetToolVersion)' == '' ">7.0.0</NuGetToolVersion>
|
||||
</PropertyGroup>
|
||||
<ItemGroup Condition=" '$(ExcludeRestorePackageImports)' != 'true' ">
|
||||
<SourceRoot Include="/home/wjones/.nuget/packages/" />
|
||||
</ItemGroup>
|
||||
<ImportGroup Condition=" '$(ExcludeRestorePackageImports)' != 'true' ">
|
||||
<Import Project="$(NuGetPackageRoot)microsoft.entityframeworkcore/10.0.3/buildTransitive/net10.0/Microsoft.EntityFrameworkCore.props" Condition="Exists('$(NuGetPackageRoot)microsoft.entityframeworkcore/10.0.3/buildTransitive/net10.0/Microsoft.EntityFrameworkCore.props')" />
|
||||
<Import Project="$(NuGetPackageRoot)microsoft.codeanalysis.bannedapianalyzers/4.14.0/buildTransitive/Microsoft.CodeAnalysis.BannedApiAnalyzers.props" Condition="Exists('$(NuGetPackageRoot)microsoft.codeanalysis.bannedapianalyzers/4.14.0/buildTransitive/Microsoft.CodeAnalysis.BannedApiAnalyzers.props')" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Condition=" '$(ExcludeRestorePackageImports)' != 'true' ">
|
||||
<PkgStyleCop_Analyzers_Unstable Condition=" '$(PkgStyleCop_Analyzers_Unstable)' == '' ">/home/wjones/.nuget/packages/stylecop.analyzers.unstable/1.2.0.556</PkgStyleCop_Analyzers_Unstable>
|
||||
<PkgSmartAnalyzers_MultithreadingAnalyzer Condition=" '$(PkgSmartAnalyzers_MultithreadingAnalyzer)' == '' ">/home/wjones/.nuget/packages/smartanalyzers.multithreadinganalyzer/1.1.31</PkgSmartAnalyzers_MultithreadingAnalyzer>
|
||||
<PkgSerilogAnalyzer Condition=" '$(PkgSerilogAnalyzer)' == '' ">/home/wjones/.nuget/packages/seriloganalyzer/0.15.0</PkgSerilogAnalyzer>
|
||||
<PkgMicrosoft_CodeAnalysis_BannedApiAnalyzers Condition=" '$(PkgMicrosoft_CodeAnalysis_BannedApiAnalyzers)' == '' ">/home/wjones/.nuget/packages/microsoft.codeanalysis.bannedapianalyzers/4.14.0</PkgMicrosoft_CodeAnalysis_BannedApiAnalyzers>
|
||||
<PkgIDisposableAnalyzers Condition=" '$(PkgIDisposableAnalyzers)' == '' ">/home/wjones/.nuget/packages/idisposableanalyzers/4.0.8</PkgIDisposableAnalyzers>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
@@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="utf-8" standalone="no"?>
|
||||
<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ImportGroup Condition=" '$(ExcludeRestorePackageImports)' != 'true' ">
|
||||
<Import Project="$(NuGetPackageRoot)microsoft.extensions.options/10.0.3/buildTransitive/net8.0/Microsoft.Extensions.Options.targets" Condition="Exists('$(NuGetPackageRoot)microsoft.extensions.options/10.0.3/buildTransitive/net8.0/Microsoft.Extensions.Options.targets')" />
|
||||
<Import Project="$(NuGetPackageRoot)microsoft.extensions.logging.abstractions/10.0.3/buildTransitive/net8.0/Microsoft.Extensions.Logging.Abstractions.targets" Condition="Exists('$(NuGetPackageRoot)microsoft.extensions.logging.abstractions/10.0.3/buildTransitive/net8.0/Microsoft.Extensions.Logging.Abstractions.targets')" />
|
||||
<Import Project="$(NuGetPackageRoot)microsoft.extensions.configuration.binder/10.0.3/buildTransitive/netstandard2.0/Microsoft.Extensions.Configuration.Binder.targets" Condition="Exists('$(NuGetPackageRoot)microsoft.extensions.configuration.binder/10.0.3/buildTransitive/netstandard2.0/Microsoft.Extensions.Configuration.Binder.targets')" />
|
||||
<Import Project="$(NuGetPackageRoot)microsoft.codeanalysis.bannedapianalyzers/4.14.0/buildTransitive/Microsoft.CodeAnalysis.BannedApiAnalyzers.targets" Condition="Exists('$(NuGetPackageRoot)microsoft.codeanalysis.bannedapianalyzers/4.14.0/buildTransitive/Microsoft.CodeAnalysis.BannedApiAnalyzers.targets')" />
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,38 @@
|
||||
{
|
||||
"version": 2,
|
||||
"dgSpecHash": "v6geFsK8bM4=",
|
||||
"success": true,
|
||||
"projectFilePath": "/srv/common_drive/Projects/pgsql-jellyfin/MediaBrowser.XbmcMetadata/MediaBrowser.XbmcMetadata.csproj",
|
||||
"expectedPackageFiles": [
|
||||
"/home/wjones/.nuget/packages/bitfaster.caching/2.5.4/bitfaster.caching.2.5.4.nupkg.sha512",
|
||||
"/home/wjones/.nuget/packages/diacritics/4.1.4/diacritics.4.1.4.nupkg.sha512",
|
||||
"/home/wjones/.nuget/packages/icu4n/60.1.0-alpha.356/icu4n.60.1.0-alpha.356.nupkg.sha512",
|
||||
"/home/wjones/.nuget/packages/icu4n.transliterator/60.1.0-alpha.356/icu4n.transliterator.60.1.0-alpha.356.nupkg.sha512",
|
||||
"/home/wjones/.nuget/packages/idisposableanalyzers/4.0.8/idisposableanalyzers.4.0.8.nupkg.sha512",
|
||||
"/home/wjones/.nuget/packages/j2n/2.0.0/j2n.2.0.0.nupkg.sha512",
|
||||
"/home/wjones/.nuget/packages/microsoft.codeanalysis.bannedapianalyzers/4.14.0/microsoft.codeanalysis.bannedapianalyzers.4.14.0.nupkg.sha512",
|
||||
"/home/wjones/.nuget/packages/microsoft.entityframeworkcore/10.0.3/microsoft.entityframeworkcore.10.0.3.nupkg.sha512",
|
||||
"/home/wjones/.nuget/packages/microsoft.entityframeworkcore.abstractions/10.0.3/microsoft.entityframeworkcore.abstractions.10.0.3.nupkg.sha512",
|
||||
"/home/wjones/.nuget/packages/microsoft.entityframeworkcore.analyzers/10.0.3/microsoft.entityframeworkcore.analyzers.10.0.3.nupkg.sha512",
|
||||
"/home/wjones/.nuget/packages/microsoft.entityframeworkcore.relational/10.0.3/microsoft.entityframeworkcore.relational.10.0.3.nupkg.sha512",
|
||||
"/home/wjones/.nuget/packages/microsoft.extensions.caching.abstractions/10.0.3/microsoft.extensions.caching.abstractions.10.0.3.nupkg.sha512",
|
||||
"/home/wjones/.nuget/packages/microsoft.extensions.caching.memory/10.0.3/microsoft.extensions.caching.memory.10.0.3.nupkg.sha512",
|
||||
"/home/wjones/.nuget/packages/microsoft.extensions.configuration/10.0.3/microsoft.extensions.configuration.10.0.3.nupkg.sha512",
|
||||
"/home/wjones/.nuget/packages/microsoft.extensions.configuration.abstractions/10.0.3/microsoft.extensions.configuration.abstractions.10.0.3.nupkg.sha512",
|
||||
"/home/wjones/.nuget/packages/microsoft.extensions.configuration.binder/10.0.3/microsoft.extensions.configuration.binder.10.0.3.nupkg.sha512",
|
||||
"/home/wjones/.nuget/packages/microsoft.extensions.dependencyinjection/10.0.3/microsoft.extensions.dependencyinjection.10.0.3.nupkg.sha512",
|
||||
"/home/wjones/.nuget/packages/microsoft.extensions.dependencyinjection.abstractions/10.0.3/microsoft.extensions.dependencyinjection.abstractions.10.0.3.nupkg.sha512",
|
||||
"/home/wjones/.nuget/packages/microsoft.extensions.logging/10.0.3/microsoft.extensions.logging.10.0.3.nupkg.sha512",
|
||||
"/home/wjones/.nuget/packages/microsoft.extensions.logging.abstractions/10.0.3/microsoft.extensions.logging.abstractions.10.0.3.nupkg.sha512",
|
||||
"/home/wjones/.nuget/packages/microsoft.extensions.options/10.0.3/microsoft.extensions.options.10.0.3.nupkg.sha512",
|
||||
"/home/wjones/.nuget/packages/microsoft.extensions.primitives/10.0.3/microsoft.extensions.primitives.10.0.3.nupkg.sha512",
|
||||
"/home/wjones/.nuget/packages/nebml/1.1.0.5/nebml.1.1.0.5.nupkg.sha512",
|
||||
"/home/wjones/.nuget/packages/polly/8.6.5/polly.8.6.5.nupkg.sha512",
|
||||
"/home/wjones/.nuget/packages/polly.core/8.6.5/polly.core.8.6.5.nupkg.sha512",
|
||||
"/home/wjones/.nuget/packages/seriloganalyzer/0.15.0/seriloganalyzer.0.15.0.nupkg.sha512",
|
||||
"/home/wjones/.nuget/packages/smartanalyzers.multithreadinganalyzer/1.1.31/smartanalyzers.multithreadinganalyzer.1.1.31.nupkg.sha512",
|
||||
"/home/wjones/.nuget/packages/stylecop.analyzers/1.2.0-beta.556/stylecop.analyzers.1.2.0-beta.556.nupkg.sha512",
|
||||
"/home/wjones/.nuget/packages/stylecop.analyzers.unstable/1.2.0.556/stylecop.analyzers.unstable.1.2.0.556.nupkg.sha512"
|
||||
],
|
||||
"logs": []
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1 @@
|
||||
17714532066900000
|
||||
@@ -0,0 +1 @@
|
||||
17715044208800000
|
||||
Reference in New Issue
Block a user