fixes #795 - Support reading Xbmc nfo's
This commit is contained in:
parent
1a5a75854b
commit
3d47b495a9
|
@ -1447,6 +1447,16 @@ namespace MediaBrowser.Api.Playback
|
|||
state.MediaPath = mediaUrl;
|
||||
state.InputProtocol = MediaProtocol.Http;
|
||||
}
|
||||
else
|
||||
{
|
||||
// No media info, so this is probably needed
|
||||
state.DeInterlace = true;
|
||||
}
|
||||
|
||||
if (recording.RecordingInfo.Status == RecordingStatus.InProgress)
|
||||
{
|
||||
state.ReadInputAtNativeFramerate = true;
|
||||
}
|
||||
|
||||
state.RunTimeTicks = recording.RunTimeTicks;
|
||||
|
||||
|
@ -1455,9 +1465,7 @@ namespace MediaBrowser.Api.Playback
|
|||
await Task.Delay(1000, cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
state.ReadInputAtNativeFramerate = recording.RecordingInfo.Status == RecordingStatus.InProgress;
|
||||
state.OutputAudioSync = "1000";
|
||||
state.DeInterlace = true;
|
||||
state.InputVideoSync = "-1";
|
||||
state.InputAudioSync = "1";
|
||||
state.InputContainer = recording.Container;
|
||||
|
@ -1524,7 +1532,9 @@ namespace MediaBrowser.Api.Playback
|
|||
state.RunTimeTicks = mediaSource.RunTimeTicks;
|
||||
}
|
||||
|
||||
if (string.Equals(state.InputContainer, "wtv", StringComparison.OrdinalIgnoreCase))
|
||||
// If it's a wtv and we don't have media info, we will probably need to deinterlace
|
||||
if (string.Equals(state.InputContainer, "wtv", StringComparison.OrdinalIgnoreCase) &&
|
||||
mediaStreams.Count == 0)
|
||||
{
|
||||
state.DeInterlace = true;
|
||||
}
|
||||
|
|
|
@ -72,6 +72,11 @@ namespace MediaBrowser.Api.Playback
|
|||
|
||||
try
|
||||
{
|
||||
if (File.Exists(path))
|
||||
{
|
||||
return path;
|
||||
}
|
||||
|
||||
await _mediaEncoder.ExtractVideoImagesOnInterval(inputPath, protocol, mediaSource.Video3DFormat,
|
||||
TimeSpan.FromSeconds(10), Path.GetDirectoryName(path), "img_", request.MaxWidth, CancellationToken.None)
|
||||
.ConfigureAwait(false);
|
||||
|
|
|
@ -144,7 +144,8 @@ namespace MediaBrowser.Api.Playback.Progressive
|
|||
return state.VideoStream != null && IsH264(state.VideoStream) ? args + " -bsf h264_mp4toannexb" : args;
|
||||
}
|
||||
|
||||
const string keyFrameArg = " -force_key_frames expr:if(isnan(prev_forced_t),gte(t,.1),gte(t,prev_forced_t+5))";
|
||||
var keyFrameArg = string.Format(" -force_key_frames expr:gte(t,n_forced*{0})",
|
||||
5.ToString(UsCulture));
|
||||
|
||||
args += keyFrameArg;
|
||||
|
||||
|
|
|
@ -445,11 +445,6 @@ namespace MediaBrowser.Controller.Entities
|
|||
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
|
||||
if (this is UserRootFolder)
|
||||
{
|
||||
var b = true;
|
||||
}
|
||||
|
||||
foreach (var child in nonCachedChildren)
|
||||
{
|
||||
BaseItem currentChild;
|
||||
|
|
|
@ -80,7 +80,7 @@ namespace MediaBrowser.Dlna.PlayTo
|
|||
_updateTimer = new Timer(updateTimer_Elapsed, null, 60000, 60000);
|
||||
}
|
||||
|
||||
private async void updateTimer_Elapsed(object state)
|
||||
private void updateTimer_Elapsed(object state)
|
||||
{
|
||||
if (DateTime.UtcNow >= _device.DateLastActivity.AddSeconds(120))
|
||||
{
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
using MediaBrowser.Common.IO;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Controller.Providers;
|
||||
using MediaBrowser.Model.Logging;
|
||||
using System;
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using MediaBrowser.Common.IO;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Controller.Providers;
|
||||
using MediaBrowser.Model.Logging;
|
||||
|
||||
namespace MediaBrowser.Providers
|
||||
namespace MediaBrowser.LocalMetadata
|
||||
{
|
||||
public abstract class BaseXmlProvider<T> : ILocalMetadataProvider<T>, IHasChangeMonitor
|
||||
where T : IHasMetadata, new()
|
|
@ -1,10 +1,8 @@
|
|||
using MediaBrowser.Controller.Entities;
|
||||
using System.Collections.Generic;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Controller.Providers;
|
||||
using MediaBrowser.Model.Entities;
|
||||
using MediaBrowser.Providers.All;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace MediaBrowser.Providers.Folders
|
||||
namespace MediaBrowser.LocalMetadata.Images
|
||||
{
|
||||
public class CollectionFolderLocalImageProvider : ILocalImageFileProvider, IHasOrder
|
||||
{
|
|
@ -1,13 +1,13 @@
|
|||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Controller.Entities.TV;
|
||||
using MediaBrowser.Controller.Providers;
|
||||
using MediaBrowser.Model.Entities;
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Controller.Entities.TV;
|
||||
using MediaBrowser.Controller.Providers;
|
||||
using MediaBrowser.Model.Entities;
|
||||
|
||||
namespace MediaBrowser.Providers.TV
|
||||
namespace MediaBrowser.LocalMetadata.Images
|
||||
{
|
||||
public class EpisodeLocalLocalImageProvider : ILocalImageFileProvider
|
||||
{
|
|
@ -1,12 +1,11 @@
|
|||
using MediaBrowser.Common.IO;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using MediaBrowser.Common.IO;
|
||||
using MediaBrowser.Controller.Configuration;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Controller.Providers;
|
||||
using MediaBrowser.Providers.All;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
|
||||
namespace MediaBrowser.Providers.Folders
|
||||
namespace MediaBrowser.LocalMetadata.Images
|
||||
{
|
||||
public class ImagesByNameImageProvider : ILocalImageFileProvider, IHasOrder
|
||||
{
|
|
@ -1,11 +1,11 @@
|
|||
using MediaBrowser.Controller.Configuration;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using MediaBrowser.Controller.Configuration;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Controller.Entities.Audio;
|
||||
using MediaBrowser.Controller.Providers;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
|
||||
namespace MediaBrowser.Providers.All
|
||||
namespace MediaBrowser.LocalMetadata.Images
|
||||
{
|
||||
public class InternalMetadataFolderImageProvider : ILocalImageFileProvider, IHasOrder
|
||||
{
|
|
@ -1,16 +1,16 @@
|
|||
using MediaBrowser.Controller.Entities;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Controller.Entities.Audio;
|
||||
using MediaBrowser.Controller.Entities.Movies;
|
||||
using MediaBrowser.Controller.Entities.TV;
|
||||
using MediaBrowser.Controller.Providers;
|
||||
using MediaBrowser.Model.Entities;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
|
||||
namespace MediaBrowser.Providers.All
|
||||
namespace MediaBrowser.LocalMetadata.Images
|
||||
{
|
||||
public class LocalImageProvider : ILocalImageFileProvider
|
||||
{
|
110
MediaBrowser.LocalMetadata/MediaBrowser.LocalMetadata.csproj
Normal file
110
MediaBrowser.LocalMetadata/MediaBrowser.LocalMetadata.csproj
Normal file
|
@ -0,0 +1,110 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProjectGuid>{7EF9F3E0-697D-42F3-A08F-19DEB5F84392}</ProjectGuid>
|
||||
<OutputType>Library</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>MediaBrowser.LocalMetadata</RootNamespace>
|
||||
<AssemblyName>MediaBrowser.LocalMetadata</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>bin\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>bin\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.Xml.Linq" />
|
||||
<Reference Include="System.Data.DataSetExtensions" />
|
||||
<Reference Include="Microsoft.CSharp" />
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="BaseXmlProvider.cs" />
|
||||
<Compile Include="Images\CollectionFolderImageProvider.cs" />
|
||||
<Compile Include="Images\EpisodeLocalImageProvider.cs" />
|
||||
<Compile Include="Images\ImagesByNameImageProvider.cs" />
|
||||
<Compile Include="Images\InternalMetadataFolderImageProvider.cs" />
|
||||
<Compile Include="Images\LocalImageProvider.cs" />
|
||||
<Compile Include="Parsers\BoxSetXmlParser.cs" />
|
||||
<Compile Include="Parsers\EpisodeXmlParser.cs" />
|
||||
<Compile Include="Parsers\GameSystemXmlParser.cs" />
|
||||
<Compile Include="Parsers\GameXmlParser.cs" />
|
||||
<Compile Include="Parsers\MovieXmlParser.cs" />
|
||||
<Compile Include="Parsers\MusicVideoXmlParser.cs" />
|
||||
<Compile Include="Parsers\SeasonXmlParser.cs" />
|
||||
<Compile Include="Parsers\SeriesXmlParser.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="Providers\AdultVideoXmlProvider.cs" />
|
||||
<Compile Include="Providers\AlbumXmlProvider.cs" />
|
||||
<Compile Include="Providers\ArtistXmlProvider.cs" />
|
||||
<Compile Include="Providers\BoxSetXmlProvider.cs" />
|
||||
<Compile Include="Providers\ChannelXmlProvider.cs" />
|
||||
<Compile Include="Providers\EpisodeXmlProvider.cs" />
|
||||
<Compile Include="Providers\FolderXmlProvider.cs" />
|
||||
<Compile Include="Providers\GameSystemXmlProvider.cs" />
|
||||
<Compile Include="Providers\GameXmlProvider.cs" />
|
||||
<Compile Include="Providers\MovieXmlProvider.cs" />
|
||||
<Compile Include="Providers\MusicVideoXmlProvider.cs" />
|
||||
<Compile Include="Providers\PersonXmlProvider.cs" />
|
||||
<Compile Include="Providers\SeasonXmlProvider.cs" />
|
||||
<Compile Include="Providers\SeriesXmlProvider.cs" />
|
||||
<Compile Include="Providers\TrailerXmlProvider.cs" />
|
||||
<Compile Include="Providers\VideoXmlProvider.cs" />
|
||||
<Compile Include="Savers\AlbumXmlSaver.cs" />
|
||||
<Compile Include="Savers\ArtistXmlSaver.cs" />
|
||||
<Compile Include="Savers\BoxSetXmlSaver.cs" />
|
||||
<Compile Include="Savers\ChannelXmlSaver.cs" />
|
||||
<Compile Include="Savers\EpisodeXmlSaver.cs" />
|
||||
<Compile Include="Savers\FolderXmlSaver.cs" />
|
||||
<Compile Include="Savers\GameSystemXmlSaver.cs" />
|
||||
<Compile Include="Savers\GameXmlSaver.cs" />
|
||||
<Compile Include="Savers\MovieXmlSaver.cs" />
|
||||
<Compile Include="Savers\PersonXmlSaver.cs" />
|
||||
<Compile Include="Savers\SeasonXmlSaver.cs" />
|
||||
<Compile Include="Savers\SeriesXmlSaver.cs" />
|
||||
<Compile Include="Savers\XmlSaverHelpers.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\MediaBrowser.Common\MediaBrowser.Common.csproj">
|
||||
<Project>{9142eefa-7570-41e1-bfcc-468bb571af2f}</Project>
|
||||
<Name>MediaBrowser.Common</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\MediaBrowser.Controller\MediaBrowser.Controller.csproj">
|
||||
<Project>{17e1f4e6-8abd-4fe5-9ecf-43d4b6087ba2}</Project>
|
||||
<Name>MediaBrowser.Controller</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\MediaBrowser.Model\MediaBrowser.Model.csproj">
|
||||
<Project>{7eeeb4bb-f3e8-48fc-b4c5-70f0fff8329b}</Project>
|
||||
<Name>MediaBrowser.Model</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup />
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
<Target Name="BeforeBuild">
|
||||
</Target>
|
||||
<Target Name="AfterBuild">
|
||||
</Target>
|
||||
-->
|
||||
</Project>
|
|
@ -1,12 +1,12 @@
|
|||
using MediaBrowser.Controller.Entities;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Xml;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Controller.Entities.Movies;
|
||||
using MediaBrowser.Controller.Providers;
|
||||
using MediaBrowser.Model.Logging;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Xml;
|
||||
|
||||
namespace MediaBrowser.Providers.BoxSets
|
||||
namespace MediaBrowser.LocalMetadata.Parsers
|
||||
{
|
||||
public class BoxSetXmlParser : BaseItemXmlParser<BoxSet>
|
||||
{
|
|
@ -1,15 +1,15 @@
|
|||
using MediaBrowser.Controller.Entities.TV;
|
||||
using MediaBrowser.Controller.Providers;
|
||||
using MediaBrowser.Model.Entities;
|
||||
using MediaBrowser.Model.Logging;
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Threading;
|
||||
using System.Xml;
|
||||
using MediaBrowser.Controller.Entities.TV;
|
||||
using MediaBrowser.Controller.Providers;
|
||||
using MediaBrowser.Model.Entities;
|
||||
using MediaBrowser.Model.Logging;
|
||||
|
||||
namespace MediaBrowser.Providers.TV
|
||||
namespace MediaBrowser.LocalMetadata.Parsers
|
||||
{
|
||||
/// <summary>
|
||||
/// Class EpisodeXmlParser
|
|
@ -1,12 +1,12 @@
|
|||
using MediaBrowser.Controller.Entities;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using System.Xml;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Controller.Providers;
|
||||
using MediaBrowser.Model.Entities;
|
||||
using MediaBrowser.Model.Logging;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using System.Xml;
|
||||
|
||||
namespace MediaBrowser.Providers.Games
|
||||
namespace MediaBrowser.LocalMetadata.Parsers
|
||||
{
|
||||
public class GameSystemXmlParser : BaseItemXmlParser<GameSystem>
|
||||
{
|
|
@ -1,13 +1,13 @@
|
|||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Controller.Providers;
|
||||
using MediaBrowser.Model.Entities;
|
||||
using MediaBrowser.Model.Logging;
|
||||
using System.Globalization;
|
||||
using System.Globalization;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using System.Xml;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Controller.Providers;
|
||||
using MediaBrowser.Model.Entities;
|
||||
using MediaBrowser.Model.Logging;
|
||||
|
||||
namespace MediaBrowser.Providers.Games
|
||||
namespace MediaBrowser.LocalMetadata.Parsers
|
||||
{
|
||||
/// <summary>
|
||||
/// Class EpisodeXmlParser
|
|
@ -1,13 +1,13 @@
|
|||
using MediaBrowser.Controller.Entities;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using System.Xml;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Controller.Entities.Movies;
|
||||
using MediaBrowser.Controller.Providers;
|
||||
using MediaBrowser.Model.Entities;
|
||||
using MediaBrowser.Model.Logging;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using System.Xml;
|
||||
|
||||
namespace MediaBrowser.Providers.Movies
|
||||
namespace MediaBrowser.LocalMetadata.Parsers
|
||||
{
|
||||
/// <summary>
|
||||
/// Class EpisodeXmlParser
|
|
@ -1,10 +1,9 @@
|
|||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Controller.Entities.Audio;
|
||||
using System.Xml;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Controller.Providers;
|
||||
using MediaBrowser.Model.Logging;
|
||||
using System.Xml;
|
||||
|
||||
namespace MediaBrowser.Providers.Music
|
||||
namespace MediaBrowser.LocalMetadata.Parsers
|
||||
{
|
||||
public class MusicVideoXmlParser : BaseItemXmlParser<MusicVideo>
|
||||
{
|
|
@ -1,9 +1,9 @@
|
|||
using MediaBrowser.Controller.Entities.TV;
|
||||
using System.Xml;
|
||||
using MediaBrowser.Controller.Entities.TV;
|
||||
using MediaBrowser.Controller.Providers;
|
||||
using MediaBrowser.Model.Logging;
|
||||
using System.Xml;
|
||||
|
||||
namespace MediaBrowser.Providers.TV
|
||||
namespace MediaBrowser.LocalMetadata.Parsers
|
||||
{
|
||||
public class SeasonXmlParser : BaseItemXmlParser<Season>
|
||||
{
|
|
@ -1,12 +1,12 @@
|
|||
using MediaBrowser.Controller.Entities.TV;
|
||||
using System;
|
||||
using System.Xml;
|
||||
using MediaBrowser.Controller.Entities.TV;
|
||||
using MediaBrowser.Controller.Library;
|
||||
using MediaBrowser.Controller.Providers;
|
||||
using MediaBrowser.Model.Entities;
|
||||
using MediaBrowser.Model.Logging;
|
||||
using System;
|
||||
using System.Xml;
|
||||
|
||||
namespace MediaBrowser.Providers.TV
|
||||
namespace MediaBrowser.LocalMetadata.Parsers
|
||||
{
|
||||
/// <summary>
|
||||
/// Class SeriesXmlParser
|
36
MediaBrowser.LocalMetadata/Properties/AssemblyInfo.cs
Normal file
36
MediaBrowser.LocalMetadata/Properties/AssemblyInfo.cs
Normal file
|
@ -0,0 +1,36 @@
|
|||
using System.Reflection;
|
||||
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.LocalMetadata")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("")]
|
||||
[assembly: AssemblyProduct("MediaBrowser.LocalMetadata")]
|
||||
[assembly: AssemblyCopyright("Copyright © 2014")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
// 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)]
|
||||
|
||||
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
||||
[assembly: Guid("1c669501-2113-493a-b0ed-f8fd26311941")]
|
||||
|
||||
// Version information for an assembly consists of the following four values:
|
||||
//
|
||||
// Major Version
|
||||
// Minor Version
|
||||
// Build Number
|
||||
// Revision
|
||||
//
|
||||
// You can specify all the values or you can default the Build and Revision Numbers
|
||||
// by using the '*' as shown below:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
|
@ -1,14 +1,14 @@
|
|||
using MediaBrowser.Common.IO;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Controller.Providers;
|
||||
using MediaBrowser.Model.Entities;
|
||||
using MediaBrowser.Model.Logging;
|
||||
using MediaBrowser.Providers.Movies;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Threading;
|
||||
using MediaBrowser.Common.IO;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Controller.Providers;
|
||||
using MediaBrowser.LocalMetadata.Parsers;
|
||||
using MediaBrowser.Model.Entities;
|
||||
using MediaBrowser.Model.Logging;
|
||||
|
||||
namespace MediaBrowser.Providers.AdultVideos
|
||||
namespace MediaBrowser.LocalMetadata.Providers
|
||||
{
|
||||
class AdultVideoXmlProvider : BaseXmlProvider<AdultVideo>
|
||||
{
|
|
@ -1,13 +1,13 @@
|
|||
using MediaBrowser.Common.IO;
|
||||
using System.IO;
|
||||
using System.Threading;
|
||||
using MediaBrowser.Common.IO;
|
||||
using MediaBrowser.Controller.Entities.Audio;
|
||||
using MediaBrowser.Controller.Providers;
|
||||
using MediaBrowser.Model.Logging;
|
||||
using System.IO;
|
||||
using System.Threading;
|
||||
|
||||
namespace MediaBrowser.Providers.Music
|
||||
namespace MediaBrowser.LocalMetadata.Providers
|
||||
{
|
||||
class AlbumXmlProvider : BaseXmlProvider<MusicAlbum>
|
||||
public class AlbumXmlProvider : BaseXmlProvider<MusicAlbum>
|
||||
{
|
||||
private readonly ILogger _logger;
|
||||
|
|
@ -1,11 +1,11 @@
|
|||
using MediaBrowser.Common.IO;
|
||||
using System.IO;
|
||||
using System.Threading;
|
||||
using MediaBrowser.Common.IO;
|
||||
using MediaBrowser.Controller.Entities.Audio;
|
||||
using MediaBrowser.Controller.Providers;
|
||||
using MediaBrowser.Model.Logging;
|
||||
using System.IO;
|
||||
using System.Threading;
|
||||
|
||||
namespace MediaBrowser.Providers.Music
|
||||
namespace MediaBrowser.LocalMetadata.Providers
|
||||
{
|
||||
class ArtistXmlProvider : BaseXmlProvider<MusicArtist>
|
||||
{
|
|
@ -1,11 +1,12 @@
|
|||
using MediaBrowser.Common.IO;
|
||||
using System.IO;
|
||||
using System.Threading;
|
||||
using MediaBrowser.Common.IO;
|
||||
using MediaBrowser.Controller.Entities.Movies;
|
||||
using MediaBrowser.Controller.Providers;
|
||||
using MediaBrowser.LocalMetadata.Parsers;
|
||||
using MediaBrowser.Model.Logging;
|
||||
using System.IO;
|
||||
using System.Threading;
|
||||
|
||||
namespace MediaBrowser.Providers.BoxSets
|
||||
namespace MediaBrowser.LocalMetadata.Providers
|
||||
{
|
||||
/// <summary>
|
||||
/// Class BoxSetXmlProvider.
|
|
@ -1,11 +1,11 @@
|
|||
using MediaBrowser.Common.IO;
|
||||
using System.IO;
|
||||
using System.Threading;
|
||||
using MediaBrowser.Common.IO;
|
||||
using MediaBrowser.Controller.LiveTv;
|
||||
using MediaBrowser.Controller.Providers;
|
||||
using MediaBrowser.Model.Logging;
|
||||
using System.IO;
|
||||
using System.Threading;
|
||||
|
||||
namespace MediaBrowser.Providers.LiveTv
|
||||
namespace MediaBrowser.LocalMetadata.Providers
|
||||
{
|
||||
public class ChannelXmlProvider : BaseXmlProvider<LiveTvChannel>
|
||||
{
|
|
@ -1,15 +1,16 @@
|
|||
using MediaBrowser.Common.IO;
|
||||
using MediaBrowser.Controller.Entities.TV;
|
||||
using MediaBrowser.Controller.Providers;
|
||||
using MediaBrowser.Model.Entities;
|
||||
using MediaBrowser.Model.Logging;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Threading;
|
||||
using MediaBrowser.Common.IO;
|
||||
using MediaBrowser.Controller.Entities.TV;
|
||||
using MediaBrowser.Controller.Providers;
|
||||
using MediaBrowser.LocalMetadata.Parsers;
|
||||
using MediaBrowser.Model.Entities;
|
||||
using MediaBrowser.Model.Logging;
|
||||
|
||||
namespace MediaBrowser.Providers.TV
|
||||
namespace MediaBrowser.LocalMetadata.Providers
|
||||
{
|
||||
public class EpisodeXmlProvider : BaseXmlProvider<Episode>
|
||||
public class EpisodeXmlProvider : BaseXmlProvider<Episode>, IHasOrder
|
||||
{
|
||||
private readonly ILogger _logger;
|
||||
|
||||
|
@ -39,5 +40,14 @@ namespace MediaBrowser.Providers.TV
|
|||
|
||||
return directoryService.GetFile(metadataFile);
|
||||
}
|
||||
|
||||
public int Order
|
||||
{
|
||||
get
|
||||
{
|
||||
// After Xbmc
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,11 +1,11 @@
|
|||
using MediaBrowser.Common.IO;
|
||||
using System.IO;
|
||||
using System.Threading;
|
||||
using MediaBrowser.Common.IO;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Controller.Providers;
|
||||
using MediaBrowser.Model.Logging;
|
||||
using System.IO;
|
||||
using System.Threading;
|
||||
|
||||
namespace MediaBrowser.Providers.Folders
|
||||
namespace MediaBrowser.LocalMetadata.Providers
|
||||
{
|
||||
/// <summary>
|
||||
/// Provides metadata for Folders and all subclasses by parsing folder.xml
|
|
@ -1,11 +1,12 @@
|
|||
using MediaBrowser.Common.IO;
|
||||
using System.IO;
|
||||
using System.Threading;
|
||||
using MediaBrowser.Common.IO;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Controller.Providers;
|
||||
using MediaBrowser.LocalMetadata.Parsers;
|
||||
using MediaBrowser.Model.Logging;
|
||||
using System.IO;
|
||||
using System.Threading;
|
||||
|
||||
namespace MediaBrowser.Providers.Games
|
||||
namespace MediaBrowser.LocalMetadata.Providers
|
||||
{
|
||||
public class GameSystemXmlProvider : BaseXmlProvider<GameSystem>
|
||||
{
|
|
@ -1,11 +1,12 @@
|
|||
using MediaBrowser.Common.IO;
|
||||
using System.IO;
|
||||
using System.Threading;
|
||||
using MediaBrowser.Common.IO;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Controller.Providers;
|
||||
using MediaBrowser.LocalMetadata.Parsers;
|
||||
using MediaBrowser.Model.Logging;
|
||||
using System.IO;
|
||||
using System.Threading;
|
||||
|
||||
namespace MediaBrowser.Providers.Games
|
||||
namespace MediaBrowser.LocalMetadata.Providers
|
||||
{
|
||||
public class GameXmlProvider : BaseXmlProvider<Game>
|
||||
{
|
|
@ -1,13 +1,14 @@
|
|||
using MediaBrowser.Common.IO;
|
||||
using MediaBrowser.Controller.Entities.Movies;
|
||||
using MediaBrowser.Controller.Providers;
|
||||
using MediaBrowser.Model.Entities;
|
||||
using MediaBrowser.Model.Logging;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Threading;
|
||||
using MediaBrowser.Common.IO;
|
||||
using MediaBrowser.Controller.Entities.Movies;
|
||||
using MediaBrowser.Controller.Providers;
|
||||
using MediaBrowser.LocalMetadata.Parsers;
|
||||
using MediaBrowser.Model.Entities;
|
||||
using MediaBrowser.Model.Logging;
|
||||
|
||||
namespace MediaBrowser.Providers.Movies
|
||||
namespace MediaBrowser.LocalMetadata.Providers
|
||||
{
|
||||
public class MovieXmlProvider : BaseXmlProvider<Movie>
|
||||
{
|
|
@ -1,13 +1,12 @@
|
|||
using MediaBrowser.Common.IO;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Controller.Entities.Audio;
|
||||
using MediaBrowser.Controller.Providers;
|
||||
using MediaBrowser.Model.Logging;
|
||||
using MediaBrowser.Providers.Movies;
|
||||
using System.IO;
|
||||
using System.IO;
|
||||
using System.Threading;
|
||||
using MediaBrowser.Common.IO;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Controller.Providers;
|
||||
using MediaBrowser.LocalMetadata.Parsers;
|
||||
using MediaBrowser.Model.Logging;
|
||||
|
||||
namespace MediaBrowser.Providers.Music
|
||||
namespace MediaBrowser.LocalMetadata.Providers
|
||||
{
|
||||
class MusicVideoXmlProvider : BaseXmlProvider<MusicVideo>
|
||||
{
|
|
@ -1,11 +1,11 @@
|
|||
using MediaBrowser.Common.IO;
|
||||
using System.IO;
|
||||
using System.Threading;
|
||||
using MediaBrowser.Common.IO;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Controller.Providers;
|
||||
using MediaBrowser.Model.Logging;
|
||||
using System.IO;
|
||||
using System.Threading;
|
||||
|
||||
namespace MediaBrowser.Providers.People
|
||||
namespace MediaBrowser.LocalMetadata.Providers
|
||||
{
|
||||
public class PersonXmlProvider : BaseXmlProvider<Person>
|
||||
{
|
|
@ -1,16 +1,17 @@
|
|||
using MediaBrowser.Common.IO;
|
||||
using System.IO;
|
||||
using System.Threading;
|
||||
using MediaBrowser.Common.IO;
|
||||
using MediaBrowser.Controller.Entities.TV;
|
||||
using MediaBrowser.Controller.Providers;
|
||||
using MediaBrowser.LocalMetadata.Parsers;
|
||||
using MediaBrowser.Model.Logging;
|
||||
using System.IO;
|
||||
using System.Threading;
|
||||
|
||||
namespace MediaBrowser.Providers.TV
|
||||
namespace MediaBrowser.LocalMetadata.Providers
|
||||
{
|
||||
/// <summary>
|
||||
/// Class SeriesProviderFromXml
|
||||
/// </summary>
|
||||
public class SeasonXmlProvider : BaseXmlProvider<Season>
|
||||
public class SeasonXmlProvider : BaseXmlProvider<Season>, IHasOrder
|
||||
{
|
||||
private readonly ILogger _logger;
|
||||
|
||||
|
@ -29,6 +30,15 @@ namespace MediaBrowser.Providers.TV
|
|||
{
|
||||
return directoryService.GetFile(Path.Combine(info.Path, "season.xml"));
|
||||
}
|
||||
|
||||
public int Order
|
||||
{
|
||||
get
|
||||
{
|
||||
// After Xbmc
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,16 +1,17 @@
|
|||
using MediaBrowser.Common.IO;
|
||||
using System.IO;
|
||||
using System.Threading;
|
||||
using MediaBrowser.Common.IO;
|
||||
using MediaBrowser.Controller.Entities.TV;
|
||||
using MediaBrowser.Controller.Providers;
|
||||
using MediaBrowser.LocalMetadata.Parsers;
|
||||
using MediaBrowser.Model.Logging;
|
||||
using System.IO;
|
||||
using System.Threading;
|
||||
|
||||
namespace MediaBrowser.Providers.TV
|
||||
namespace MediaBrowser.LocalMetadata.Providers
|
||||
{
|
||||
/// <summary>
|
||||
/// Class SeriesProviderFromXml
|
||||
/// </summary>
|
||||
public class SeriesXmlProvider : BaseXmlProvider<Series>
|
||||
public class SeriesXmlProvider : BaseXmlProvider<Series>, IHasOrder
|
||||
{
|
||||
private readonly ILogger _logger;
|
||||
|
||||
|
@ -29,5 +30,14 @@ namespace MediaBrowser.Providers.TV
|
|||
{
|
||||
return directoryService.GetFile(Path.Combine(info.Path, "series.xml"));
|
||||
}
|
||||
|
||||
public int Order
|
||||
{
|
||||
get
|
||||
{
|
||||
// After Xbmc
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,13 +1,14 @@
|
|||
using MediaBrowser.Common.IO;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Controller.Providers;
|
||||
using MediaBrowser.Model.Entities;
|
||||
using MediaBrowser.Model.Logging;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Threading;
|
||||
using MediaBrowser.Common.IO;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Controller.Providers;
|
||||
using MediaBrowser.LocalMetadata.Parsers;
|
||||
using MediaBrowser.Model.Entities;
|
||||
using MediaBrowser.Model.Logging;
|
||||
|
||||
namespace MediaBrowser.Providers.Movies
|
||||
namespace MediaBrowser.LocalMetadata.Providers
|
||||
{
|
||||
public class TrailerXmlProvider : BaseXmlProvider<Trailer>
|
||||
{
|
|
@ -1,14 +1,14 @@
|
|||
using MediaBrowser.Common.IO;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Controller.Providers;
|
||||
using MediaBrowser.Model.Entities;
|
||||
using MediaBrowser.Model.Logging;
|
||||
using MediaBrowser.Providers.Movies;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Threading;
|
||||
using MediaBrowser.Common.IO;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Controller.Providers;
|
||||
using MediaBrowser.LocalMetadata.Parsers;
|
||||
using MediaBrowser.Model.Entities;
|
||||
using MediaBrowser.Model.Logging;
|
||||
|
||||
namespace MediaBrowser.Providers.Videos
|
||||
namespace MediaBrowser.LocalMetadata.Providers
|
||||
{
|
||||
class VideoXmlProvider : BaseXmlProvider<Video>
|
||||
{
|
|
@ -1,12 +1,12 @@
|
|||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Controller.Entities.Audio;
|
||||
using MediaBrowser.Controller.Library;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Controller.Entities.Audio;
|
||||
using MediaBrowser.Controller.Library;
|
||||
|
||||
namespace MediaBrowser.Providers.Savers
|
||||
namespace MediaBrowser.LocalMetadata.Savers
|
||||
{
|
||||
class AlbumXmlSaver : IMetadataFileSaver
|
||||
{
|
|
@ -1,12 +1,12 @@
|
|||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Controller.Entities.Audio;
|
||||
using MediaBrowser.Controller.Library;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Controller.Entities.Audio;
|
||||
using MediaBrowser.Controller.Library;
|
||||
|
||||
namespace MediaBrowser.Providers.Savers
|
||||
namespace MediaBrowser.LocalMetadata.Savers
|
||||
{
|
||||
class ArtistXmlSaver : IMetadataFileSaver
|
||||
{
|
|
@ -1,13 +1,12 @@
|
|||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Controller.Entities.Movies;
|
||||
using MediaBrowser.Controller.Library;
|
||||
using MediaBrowser.Model.Entities;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Controller.Entities.Movies;
|
||||
using MediaBrowser.Controller.Library;
|
||||
|
||||
namespace MediaBrowser.Providers.Savers
|
||||
namespace MediaBrowser.LocalMetadata.Savers
|
||||
{
|
||||
public class BoxSetXmlSaver : IMetadataFileSaver
|
||||
{
|
|
@ -1,13 +1,12 @@
|
|||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Controller.Library;
|
||||
using MediaBrowser.Controller.LiveTv;
|
||||
using MediaBrowser.Model.Entities;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Controller.Library;
|
||||
using MediaBrowser.Controller.LiveTv;
|
||||
|
||||
namespace MediaBrowser.Providers.Savers
|
||||
namespace MediaBrowser.LocalMetadata.Savers
|
||||
{
|
||||
/// <summary>
|
||||
/// Class PersonXmlSaver
|
|
@ -1,15 +1,15 @@
|
|||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Controller.Entities.TV;
|
||||
using MediaBrowser.Controller.Library;
|
||||
using MediaBrowser.Controller.Persistence;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Security;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Controller.Entities.TV;
|
||||
using MediaBrowser.Controller.Library;
|
||||
using MediaBrowser.Controller.Persistence;
|
||||
|
||||
namespace MediaBrowser.Providers.Savers
|
||||
namespace MediaBrowser.LocalMetadata.Savers
|
||||
{
|
||||
public class EpisodeXmlSaver : IMetadataFileSaver
|
||||
{
|
|
@ -1,15 +1,14 @@
|
|||
using MediaBrowser.Controller.Entities;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Controller.Entities.Audio;
|
||||
using MediaBrowser.Controller.Entities.Movies;
|
||||
using MediaBrowser.Controller.Entities.TV;
|
||||
using MediaBrowser.Controller.Library;
|
||||
using MediaBrowser.Model.Entities;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
|
||||
namespace MediaBrowser.Providers.Savers
|
||||
namespace MediaBrowser.LocalMetadata.Savers
|
||||
{
|
||||
public class FolderXmlSaver : IMetadataFileSaver
|
||||
{
|
|
@ -1,12 +1,12 @@
|
|||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Controller.Library;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Security;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Controller.Library;
|
||||
|
||||
namespace MediaBrowser.Providers.Savers
|
||||
namespace MediaBrowser.LocalMetadata.Savers
|
||||
{
|
||||
public class GameSystemXmlSaver : IMetadataFileSaver
|
||||
{
|
|
@ -1,14 +1,14 @@
|
|||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Controller.Library;
|
||||
using MediaBrowser.Model.Entities;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Security;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Controller.Library;
|
||||
using MediaBrowser.Model.Entities;
|
||||
|
||||
namespace MediaBrowser.Providers.Savers
|
||||
namespace MediaBrowser.LocalMetadata.Savers
|
||||
{
|
||||
/// <summary>
|
||||
/// Saves game.xml for games
|
|
@ -1,16 +1,15 @@
|
|||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Controller.Entities.Movies;
|
||||
using MediaBrowser.Controller.Entities.TV;
|
||||
using MediaBrowser.Controller.Library;
|
||||
using MediaBrowser.Controller.Persistence;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Security;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Controller.Entities.Movies;
|
||||
using MediaBrowser.Controller.Entities.TV;
|
||||
using MediaBrowser.Controller.Library;
|
||||
using MediaBrowser.Controller.Persistence;
|
||||
|
||||
namespace MediaBrowser.Providers.Savers
|
||||
namespace MediaBrowser.LocalMetadata.Savers
|
||||
{
|
||||
/// <summary>
|
||||
/// Saves movie.xml for movies, trailers and music videos
|
|
@ -1,14 +1,12 @@
|
|||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Controller.Library;
|
||||
using MediaBrowser.Controller.Providers;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Security;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using MediaBrowser.Model.Entities;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Controller.Library;
|
||||
|
||||
namespace MediaBrowser.Providers.Savers
|
||||
namespace MediaBrowser.LocalMetadata.Savers
|
||||
{
|
||||
/// <summary>
|
||||
/// Class PersonXmlSaver
|
|
@ -1,14 +1,14 @@
|
|||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Controller.Entities.TV;
|
||||
using MediaBrowser.Controller.Library;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Security;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Controller.Entities.TV;
|
||||
using MediaBrowser.Controller.Library;
|
||||
|
||||
namespace MediaBrowser.Providers.Savers
|
||||
namespace MediaBrowser.LocalMetadata.Savers
|
||||
{
|
||||
public class SeasonXmlSaver : IMetadataFileSaver
|
||||
{
|
|
@ -1,15 +1,15 @@
|
|||
using System.Globalization;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Controller.Entities.TV;
|
||||
using MediaBrowser.Controller.Library;
|
||||
using MediaBrowser.Model.Entities;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Security;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Controller.Entities.TV;
|
||||
using MediaBrowser.Controller.Library;
|
||||
using MediaBrowser.Model.Entities;
|
||||
|
||||
namespace MediaBrowser.Providers.Savers
|
||||
namespace MediaBrowser.LocalMetadata.Savers
|
||||
{
|
||||
public class SeriesXmlSaver : IMetadataFileSaver
|
||||
{
|
|
@ -1,9 +1,4 @@
|
|||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Controller.Entities.Movies;
|
||||
using MediaBrowser.Controller.Entities.TV;
|
||||
using MediaBrowser.Controller.Persistence;
|
||||
using MediaBrowser.Model.Entities;
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
|
@ -11,8 +6,13 @@ using System.Linq;
|
|||
using System.Security;
|
||||
using System.Text;
|
||||
using System.Xml;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Controller.Entities.Movies;
|
||||
using MediaBrowser.Controller.Entities.TV;
|
||||
using MediaBrowser.Controller.Persistence;
|
||||
using MediaBrowser.Model.Entities;
|
||||
|
||||
namespace MediaBrowser.Providers.Savers
|
||||
namespace MediaBrowser.LocalMetadata.Savers
|
||||
{
|
||||
/// <summary>
|
||||
/// Class XmlHelpers
|
|
@ -170,6 +170,9 @@
|
|||
<Compile Include="..\MediaBrowser.Model\Configuration\UserConfiguration.cs">
|
||||
<Link>Configuration\UserConfiguration.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\MediaBrowser.Model\Configuration\XbmcMetadataOptions.cs">
|
||||
<Link>Configuration\XbmcMetadataOptions.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\MediaBrowser.Model\Dlna\AudioOptions.cs">
|
||||
<Link>Dlna\AudioOptions.cs</Link>
|
||||
</Compile>
|
||||
|
|
|
@ -157,6 +157,9 @@
|
|||
<Compile Include="..\MediaBrowser.Model\Configuration\UserConfiguration.cs">
|
||||
<Link>Configuration\UserConfiguration.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\MediaBrowser.Model\Configuration\XbmcMetadataOptions.cs">
|
||||
<Link>Configuration\XbmcMetadataOptions.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\MediaBrowser.Model\Dlna\AudioOptions.cs">
|
||||
<Link>Dlna\AudioOptions.cs</Link>
|
||||
</Compile>
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
using MediaBrowser.Model.Weather;
|
||||
using System.Linq;
|
||||
using MediaBrowser.Model.Weather;
|
||||
using System;
|
||||
|
||||
namespace MediaBrowser.Model.Configuration
|
||||
|
@ -68,24 +69,12 @@ namespace MediaBrowser.Model.Configuration
|
|||
/// <value>The display name of the season zero.</value>
|
||||
public string SeasonZeroDisplayName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the metadata refresh days.
|
||||
/// </summary>
|
||||
/// <value>The metadata refresh days.</value>
|
||||
public int MetadataRefreshDays { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether [save local meta].
|
||||
/// </summary>
|
||||
/// <value><c>true</c> if [save local meta]; otherwise, <c>false</c>.</value>
|
||||
public bool SaveLocalMeta { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether [refresh item images].
|
||||
/// </summary>
|
||||
/// <value><c>true</c> if [refresh item images]; otherwise, <c>false</c>.</value>
|
||||
public bool RefreshItemImages { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the preferred metadata language.
|
||||
/// </summary>
|
||||
|
@ -227,6 +216,9 @@ namespace MediaBrowser.Model.Configuration
|
|||
[Obsolete]
|
||||
public ChapterOptions ChapterOptions { get; set; }
|
||||
|
||||
[Obsolete]
|
||||
public bool DefaultMetadataSettingsApplied { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ServerConfiguration" /> class.
|
||||
/// </summary>
|
||||
|
@ -258,7 +250,6 @@ namespace MediaBrowser.Model.Configuration
|
|||
|
||||
PathSubstitutions = new PathSubstitution[] { };
|
||||
|
||||
MetadataRefreshDays = 30;
|
||||
PreferredMetadataLanguage = "en";
|
||||
MetadataCountryCode = "US";
|
||||
|
||||
|
|
21
MediaBrowser.Model/Configuration/XbmcMetadataOptions.cs
Normal file
21
MediaBrowser.Model/Configuration/XbmcMetadataOptions.cs
Normal file
|
@ -0,0 +1,21 @@
|
|||
|
||||
namespace MediaBrowser.Model.Configuration
|
||||
{
|
||||
public class XbmcMetadataOptions
|
||||
{
|
||||
public string UserId { get; set; }
|
||||
|
||||
public string ReleaseDateFormat { get; set; }
|
||||
|
||||
public bool SaveImagePathsInNfo { get; set; }
|
||||
public bool EnablePathSubstitution { get; set; }
|
||||
|
||||
public XbmcMetadataOptions()
|
||||
{
|
||||
ReleaseDateFormat = "yyyy-MM-dd";
|
||||
|
||||
SaveImagePathsInNfo = true;
|
||||
EnablePathSubstitution = true;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -75,6 +75,7 @@
|
|||
<Compile Include="Chapters\RemoteChapterResult.cs" />
|
||||
<Compile Include="Configuration\ChannelOptions.cs" />
|
||||
<Compile Include="Configuration\ChapterOptions.cs" />
|
||||
<Compile Include="Configuration\XbmcMetadataOptions.cs" />
|
||||
<Compile Include="Configuration\SubtitlePlaybackMode.cs" />
|
||||
<Compile Include="Configuration\TvFileOrganizationOptions.cs" />
|
||||
<Compile Include="Configuration\BaseApplicationConfiguration.cs" />
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
using MediaBrowser.Common.IO;
|
||||
using System.Collections.Generic;
|
||||
using MediaBrowser.Common.IO;
|
||||
using MediaBrowser.Controller.Channels;
|
||||
using MediaBrowser.Controller.Configuration;
|
||||
using MediaBrowser.Controller.Providers;
|
||||
using MediaBrowser.Model.Entities;
|
||||
using MediaBrowser.Model.Logging;
|
||||
using MediaBrowser.Providers.Manager;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace MediaBrowser.Providers.GameGenres
|
||||
namespace MediaBrowser.Providers.Channels
|
||||
{
|
||||
public class AudioChannelItemMetadataService : MetadataService<ChannelAudioItem, ItemLookupInfo>
|
||||
{
|
|
@ -1,13 +1,13 @@
|
|||
using MediaBrowser.Common.IO;
|
||||
using System.Collections.Generic;
|
||||
using MediaBrowser.Common.IO;
|
||||
using MediaBrowser.Controller.Channels;
|
||||
using MediaBrowser.Controller.Configuration;
|
||||
using MediaBrowser.Controller.Providers;
|
||||
using MediaBrowser.Model.Entities;
|
||||
using MediaBrowser.Model.Logging;
|
||||
using MediaBrowser.Providers.Manager;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace MediaBrowser.Providers.GameGenres
|
||||
namespace MediaBrowser.Providers.Channels
|
||||
{
|
||||
public class VideoChannelItemMetadataService : MetadataService<ChannelVideoItem, ItemLookupInfo>
|
||||
{
|
|
@ -70,41 +70,28 @@
|
|||
<Link>Properties\SharedVersion.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="AdultVideos\AdultVideoMetadataService.cs" />
|
||||
<Compile Include="AdultVideos\AdultVideoXmlProvider.cs" />
|
||||
<Compile Include="All\InternalMetadataFolderImageProvider.cs" />
|
||||
<Compile Include="All\LocalImageProvider.cs" />
|
||||
<Compile Include="Books\BookMetadataService.cs" />
|
||||
<Compile Include="BoxSets\BoxSetMetadataService.cs" />
|
||||
<Compile Include="BoxSets\BoxSetXmlParser.cs" />
|
||||
<Compile Include="BoxSets\MovieDbBoxSetImageProvider.cs" />
|
||||
<Compile Include="BoxSets\MovieDbBoxSetProvider.cs" />
|
||||
<Compile Include="Channels\ChannelMetadataService.cs" />
|
||||
<Compile Include="Chapters\ChapterManager.cs" />
|
||||
<Compile Include="FolderImages\DefaultImageProvider.cs" />
|
||||
<Compile Include="Folders\CollectionFolderImageProvider.cs" />
|
||||
<Compile Include="Folders\FolderMetadataService.cs" />
|
||||
<Compile Include="Folders\ImagesByNameImageProvider.cs" />
|
||||
<Compile Include="GameGenres\AudioChannelItemMetadataService.cs" />
|
||||
<Compile Include="Channels\AudioChannelItemMetadataService.cs" />
|
||||
<Compile Include="GameGenres\GameGenreMetadataService.cs" />
|
||||
<Compile Include="GameGenres\VideoChannelItemMetadataService.cs" />
|
||||
<Compile Include="Channels\VideoChannelItemMetadataService.cs" />
|
||||
<Compile Include="Games\GameMetadataService.cs" />
|
||||
<Compile Include="Games\GameSystemMetadataService.cs" />
|
||||
<Compile Include="Games\GameSystemXmlParser.cs" />
|
||||
<Compile Include="Genres\GenreMetadataService.cs" />
|
||||
<Compile Include="LiveTv\AudioRecordingService.cs" />
|
||||
<Compile Include="LiveTv\ChannelMetadataService.cs" />
|
||||
<Compile Include="LiveTv\ChannelXmlProvider.cs" />
|
||||
<Compile Include="LiveTv\ProgramMetadataService.cs" />
|
||||
<Compile Include="LiveTv\VideoRecordingService.cs" />
|
||||
<Compile Include="Manager\ImageSaver.cs" />
|
||||
<Compile Include="Manager\ItemImageProvider.cs" />
|
||||
<Compile Include="Manager\ProviderManager.cs" />
|
||||
<Compile Include="Manager\MetadataService.cs" />
|
||||
<Compile Include="BaseXmlProvider.cs" />
|
||||
<Compile Include="Folders\FolderXmlProvider.cs" />
|
||||
<Compile Include="Games\GameXmlParser.cs" />
|
||||
<Compile Include="Games\GameXmlProvider.cs" />
|
||||
<Compile Include="Games\GameSystemXmlProvider.cs" />
|
||||
<Compile Include="Manager\SeriesOrderManager.cs" />
|
||||
<Compile Include="MediaInfo\FFProbeAudioInfo.cs" />
|
||||
<Compile Include="MediaInfo\FFProbeHelpers.cs" />
|
||||
|
@ -118,16 +105,13 @@
|
|||
<Compile Include="Movies\GenericMovieDbInfo.cs" />
|
||||
<Compile Include="Movies\MovieDbSearch.cs" />
|
||||
<Compile Include="Movies\MovieMetadataService.cs" />
|
||||
<Compile Include="Movies\MovieXmlProvider.cs" />
|
||||
<Compile Include="Movies\TmdbSettings.cs" />
|
||||
<Compile Include="Movies\TrailerXmlProvider.cs" />
|
||||
<Compile Include="MusicGenres\MusicGenreImageProvider.cs" />
|
||||
<Compile Include="GameGenres\GameGenreImageProvider.cs" />
|
||||
<Compile Include="Genres\GenreImageProvider.cs" />
|
||||
<Compile Include="ImagesByName\ImageUtils.cs" />
|
||||
<Compile Include="MediaInfo\AudioImageProvider.cs" />
|
||||
<Compile Include="MediaInfo\VideoImageProvider.cs" />
|
||||
<Compile Include="BoxSets\BoxSetXmlProvider.cs" />
|
||||
<Compile Include="Movies\MovieDbImageProvider.cs" />
|
||||
<Compile Include="Movies\FanartMovieImageProvider.cs" />
|
||||
<Compile Include="MusicGenres\MusicGenreMetadataService.cs" />
|
||||
|
@ -146,16 +130,12 @@
|
|||
<Compile Include="Music\MusicBrainzArtistProvider.cs" />
|
||||
<Compile Include="Music\MusicExternalIds.cs" />
|
||||
<Compile Include="Music\MusicVideoMetadataService.cs" />
|
||||
<Compile Include="Music\MusicVideoXmlProvider.cs" />
|
||||
<Compile Include="Omdb\OmdbProvider.cs" />
|
||||
<Compile Include="Omdb\OmdbItemProvider.cs" />
|
||||
<Compile Include="People\MovieDbPersonImageProvider.cs" />
|
||||
<Compile Include="Movies\MovieUpdatesPrescanTask.cs" />
|
||||
<Compile Include="Movies\MovieXmlParser.cs" />
|
||||
<Compile Include="Movies\FanArtMovieUpdatesPostScanTask.cs" />
|
||||
<Compile Include="Movies\MovieDbProvider.cs" />
|
||||
<Compile Include="Music\AlbumXmlProvider.cs" />
|
||||
<Compile Include="Music\ArtistXmlProvider.cs" />
|
||||
<Compile Include="Music\FanArtUpdatesPostScanTask.cs" />
|
||||
<Compile Include="Music\LastfmAlbumProvider.cs" />
|
||||
<Compile Include="Music\LastfmHelper.cs" />
|
||||
|
@ -163,10 +143,8 @@
|
|||
<Compile Include="Music\FanArtArtistProvider.cs" />
|
||||
<Compile Include="Music\LastFmImageProvider.cs" />
|
||||
<Compile Include="Music\MusicBrainzAlbumProvider.cs" />
|
||||
<Compile Include="Music\MusicVideoXmlParser.cs" />
|
||||
<Compile Include="Music\SoundtrackPostScanTask.cs" />
|
||||
<Compile Include="People\PersonMetadataService.cs" />
|
||||
<Compile Include="People\PersonXmlProvider.cs" />
|
||||
<Compile Include="People\MovieDbPersonProvider.cs" />
|
||||
<Compile Include="Photos\ExifReader.cs" />
|
||||
<Compile Include="Photos\ExifTags.cs" />
|
||||
|
@ -175,34 +153,17 @@
|
|||
<Compile Include="Photos\PhotoProvider.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="Manager\ProviderUtils.cs" />
|
||||
<Compile Include="Savers\AlbumXmlSaver.cs" />
|
||||
<Compile Include="Savers\ArtistXmlSaver.cs" />
|
||||
<Compile Include="Savers\BoxSetXmlSaver.cs" />
|
||||
<Compile Include="Savers\ChannelXmlSaver.cs" />
|
||||
<Compile Include="Savers\EpisodeXmlSaver.cs" />
|
||||
<Compile Include="Savers\FolderXmlSaver.cs" />
|
||||
<Compile Include="Savers\GameSystemXmlSaver.cs" />
|
||||
<Compile Include="Savers\GameXmlSaver.cs" />
|
||||
<Compile Include="Savers\MovieXmlSaver.cs" />
|
||||
<Compile Include="Savers\PersonXmlSaver.cs" />
|
||||
<Compile Include="Savers\SeasonXmlSaver.cs" />
|
||||
<Compile Include="Savers\SeriesXmlSaver.cs" />
|
||||
<Compile Include="Savers\XmlSaverHelpers.cs" />
|
||||
<Compile Include="Studios\StudiosImageProvider.cs" />
|
||||
<Compile Include="Studios\StudioMetadataService.cs" />
|
||||
<Compile Include="Subtitles\OpenSubtitleDownloader.cs" />
|
||||
<Compile Include="Subtitles\SubtitleManager.cs" />
|
||||
<Compile Include="TV\EpisodeLocalImageProvider.cs" />
|
||||
<Compile Include="TV\EpisodeMetadataService.cs" />
|
||||
<Compile Include="TV\EpisodeXmlProvider.cs" />
|
||||
<Compile Include="TV\EpisodeXmlParser.cs" />
|
||||
<Compile Include="TV\FanArtTvUpdatesPostScanTask.cs" />
|
||||
<Compile Include="TV\FanArtSeasonProvider.cs" />
|
||||
<Compile Include="TV\FanartSeriesProvider.cs" />
|
||||
<Compile Include="TV\MissingEpisodeProvider.cs" />
|
||||
<Compile Include="TV\MovieDbSeriesImageProvider.cs" />
|
||||
<Compile Include="TV\MovieDbSeriesProvider.cs" />
|
||||
<Compile Include="TV\SeasonXmlParser.cs" />
|
||||
<Compile Include="TV\SeriesMetadataService.cs" />
|
||||
<Compile Include="TV\TvdbEpisodeImageProvider.cs" />
|
||||
<Compile Include="People\TvdbPersonImageProvider.cs" />
|
||||
|
@ -212,16 +173,11 @@
|
|||
<Compile Include="TV\SeasonMetadataService.cs" />
|
||||
<Compile Include="TV\TvdbEpisodeProvider.cs" />
|
||||
<Compile Include="TV\TvdbSeriesProvider.cs" />
|
||||
<Compile Include="TV\SeasonXmlProvider.cs" />
|
||||
<Compile Include="TV\SeriesPostScanTask.cs" />
|
||||
<Compile Include="TV\SeriesXmlProvider.cs" />
|
||||
<Compile Include="TV\SeriesXmlParser.cs" />
|
||||
<Compile Include="TV\TvdbPrescanTask.cs" />
|
||||
<Compile Include="TV\TvExternalIds.cs" />
|
||||
<Compile Include="Users\UserMetadataService.cs" />
|
||||
<Compile Include="Videos\VideoMetadataService.cs" />
|
||||
<Compile Include="Videos\VideoXmlProvider.cs" />
|
||||
<Compile Include="Xbmc\XbmcImageSaver.cs" />
|
||||
<Compile Include="Years\YearMetadataService.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
@ -248,6 +204,7 @@
|
|||
<ItemGroup>
|
||||
<EmbeddedResource Include="MediaInfo\whitelist.txt" />
|
||||
</ItemGroup>
|
||||
<ItemGroup />
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<Import Project="$(SolutionDir)\.nuget\NuGet.targets" Condition=" '$(ConfigurationName)' != 'Release Mono' " />
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
|
|
|
@ -835,5 +835,16 @@
|
|||
"TitleRemoteControl": "Remote Control",
|
||||
"OptionLatestTvRecordings": "Latest recordings",
|
||||
"LabelProtocolInfo": "Protocol info:",
|
||||
"LabelProtocolInfoHelp": "The value that will be used when responding to GetProtocolInfo requests from the device."
|
||||
"LabelProtocolInfoHelp": "The value that will be used when responding to GetProtocolInfo requests from the device.",
|
||||
"TabXbmcMetadata": "Xbmc",
|
||||
"HeaderXbmcMetadataHelp": "Media Browser includes native support for Xbmc Nfo metadata and images. To enable or disable Xbmc metadata, use the Advanced tab to configure options for your media types.",
|
||||
"LabelXbmcMetadataUser": "Add user watch data to nfo's for:",
|
||||
"LabelXbmcMetadataUserHelp": "Enable this to keep watch data in sync between Media Browser and Xbmc.",
|
||||
"LabelXbmcMetadataDateFormat": "Release date format:",
|
||||
"LabelXbmcMetadataDateFormatHelp": "All dates within nfo's will be read and written to using this format.",
|
||||
"LabelXbmcMetadataSaveImagePaths": "Save image paths within nfo files",
|
||||
"LabelXbmcMetadataSaveImagePathsHelp": "This is recommended if you have image file names that don't conform to Xbmc guidelines.",
|
||||
"LabelXbmcMetadataEnablePathSubstitution": "Enable path substitution",
|
||||
"LabelXbmcMetadataEnablePathSubstitutionHelp": "Enables path substitution of image paths using the server's path substitution settings.",
|
||||
"LabelXbmcMetadataEnablePathSubstitutionHelp2": "See path substitution."
|
||||
}
|
|
@ -17,6 +17,9 @@ using MediaBrowser.Controller.Dlna;
|
|||
using MediaBrowser.Controller.Drawing;
|
||||
using MediaBrowser.Controller.Dto;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Controller.Entities.Audio;
|
||||
using MediaBrowser.Controller.Entities.Movies;
|
||||
using MediaBrowser.Controller.Entities.TV;
|
||||
using MediaBrowser.Controller.FileOrganization;
|
||||
using MediaBrowser.Controller.Library;
|
||||
using MediaBrowser.Controller.LiveTv;
|
||||
|
@ -38,9 +41,11 @@ using MediaBrowser.Dlna;
|
|||
using MediaBrowser.Dlna.ConnectionManager;
|
||||
using MediaBrowser.Dlna.ContentDirectory;
|
||||
using MediaBrowser.Dlna.Main;
|
||||
using MediaBrowser.LocalMetadata.Providers;
|
||||
using MediaBrowser.MediaEncoding.BdInfo;
|
||||
using MediaBrowser.MediaEncoding.Encoder;
|
||||
using MediaBrowser.MediaEncoding.Subtitles;
|
||||
using MediaBrowser.Model.Configuration;
|
||||
using MediaBrowser.Model.Logging;
|
||||
using MediaBrowser.Model.MediaInfo;
|
||||
using MediaBrowser.Model.System;
|
||||
|
@ -75,6 +80,7 @@ using MediaBrowser.ServerApplication.IO;
|
|||
using MediaBrowser.ServerApplication.Native;
|
||||
using MediaBrowser.ServerApplication.Networking;
|
||||
using MediaBrowser.WebDashboard.Api;
|
||||
using MediaBrowser.XbmcMetadata.Providers;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
|
@ -283,6 +289,7 @@ namespace MediaBrowser.ServerApplication
|
|||
DeleteDeprecatedModules();
|
||||
|
||||
MigrateModularConfigurations();
|
||||
ApplyDefaultXbmcSettings();
|
||||
}
|
||||
|
||||
private void MigrateModularConfigurations()
|
||||
|
@ -309,6 +316,68 @@ namespace MediaBrowser.ServerApplication
|
|||
}
|
||||
}
|
||||
|
||||
private void ApplyDefaultXbmcSettings()
|
||||
{
|
||||
if (!ServerConfigurationManager.Configuration.DefaultMetadataSettingsApplied)
|
||||
{
|
||||
// Make sure xbmc metadata is disabled for existing users.
|
||||
// New users can just take the defaults.
|
||||
var service = ServerConfigurationManager.Configuration.IsStartupWizardCompleted
|
||||
? "Xbmc Nfo"
|
||||
: "Media Browser Xml";
|
||||
|
||||
DisableMetadataService(typeof(Movie), ServerConfigurationManager.Configuration, service);
|
||||
DisableMetadataService(typeof(MusicAlbum), ServerConfigurationManager.Configuration, service);
|
||||
DisableMetadataService(typeof(MusicArtist), ServerConfigurationManager.Configuration, service);
|
||||
DisableMetadataService(typeof(Episode), ServerConfigurationManager.Configuration, service);
|
||||
DisableMetadataService(typeof(Season), ServerConfigurationManager.Configuration, service);
|
||||
DisableMetadataService(typeof(Series), ServerConfigurationManager.Configuration, service);
|
||||
DisableMetadataService(typeof(MusicVideo), ServerConfigurationManager.Configuration, service);
|
||||
DisableMetadataService(typeof(Trailer), ServerConfigurationManager.Configuration, service);
|
||||
DisableMetadataService(typeof(AdultVideo), ServerConfigurationManager.Configuration, service);
|
||||
DisableMetadataService(typeof(Video), ServerConfigurationManager.Configuration, service);
|
||||
}
|
||||
|
||||
ServerConfigurationManager.Configuration.DefaultMetadataSettingsApplied = true;
|
||||
ServerConfigurationManager.SaveConfiguration();
|
||||
}
|
||||
|
||||
private void DisableMetadataService(Type type, ServerConfiguration config, string service)
|
||||
{
|
||||
var options = GetMetadataOptions(type, config);
|
||||
|
||||
if (!options.DisabledMetadataSavers.Contains(service, StringComparer.OrdinalIgnoreCase))
|
||||
{
|
||||
var list = options.DisabledMetadataSavers.ToList();
|
||||
|
||||
list.Add(service);
|
||||
|
||||
options.DisabledMetadataSavers = list.ToArray();
|
||||
}
|
||||
}
|
||||
|
||||
private MetadataOptions GetMetadataOptions(Type type, ServerConfiguration config)
|
||||
{
|
||||
var options = config.MetadataOptions
|
||||
.FirstOrDefault(i => string.Equals(i.ItemType, type.Name, StringComparison.OrdinalIgnoreCase));
|
||||
|
||||
if (options == null)
|
||||
{
|
||||
var list = config.MetadataOptions.ToList();
|
||||
|
||||
options = new MetadataOptions
|
||||
{
|
||||
ItemType = type.Name
|
||||
};
|
||||
|
||||
list.Add(options);
|
||||
|
||||
config.MetadataOptions = list.ToArray();
|
||||
}
|
||||
|
||||
return options;
|
||||
}
|
||||
|
||||
private void DeleteDeprecatedModules()
|
||||
{
|
||||
try
|
||||
|
@ -328,6 +397,15 @@ namespace MediaBrowser.ServerApplication
|
|||
// Not there, no big deal
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
File.Delete(Path.Combine(ApplicationPaths.PluginsPath, "MediaBrowser.Plugins.XbmcMetadata.dll"));
|
||||
}
|
||||
catch (IOException)
|
||||
{
|
||||
// Not there, no big deal
|
||||
}
|
||||
|
||||
Task.Run(() =>
|
||||
{
|
||||
try
|
||||
|
@ -912,6 +990,12 @@ namespace MediaBrowser.ServerApplication
|
|||
// Dlna
|
||||
list.Add(typeof(DlnaEntryPoint).Assembly);
|
||||
|
||||
// Local metadata
|
||||
list.Add(typeof(AlbumXmlProvider).Assembly);
|
||||
|
||||
// Xbmc
|
||||
list.Add(typeof(ArtistNfoProvider).Assembly);
|
||||
|
||||
list.AddRange(Assemblies.GetAssembliesWithParts());
|
||||
|
||||
// Include composable parts in the running assembly
|
||||
|
|
|
@ -198,6 +198,10 @@
|
|||
<Project>{734098eb-6dc1-4dd0-a1ca-3140dcd2737c}</Project>
|
||||
<Name>MediaBrowser.Dlna</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\MediaBrowser.LocalMetadata\MediaBrowser.LocalMetadata.csproj">
|
||||
<Project>{7ef9f3e0-697d-42f3-a08f-19deb5f84392}</Project>
|
||||
<Name>MediaBrowser.LocalMetadata</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\MediaBrowser.MediaEncoding\MediaBrowser.MediaEncoding.csproj">
|
||||
<Project>{0bd82fa6-eb8a-4452-8af5-74f9c3849451}</Project>
|
||||
<Name>MediaBrowser.MediaEncoding</Name>
|
||||
|
@ -218,6 +222,10 @@
|
|||
<Project>{5624b7b5-b5a7-41d8-9f10-cc5611109619}</Project>
|
||||
<Name>MediaBrowser.WebDashboard</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\MediaBrowser.XbmcMetadata\MediaBrowser.XbmcMetadata.csproj">
|
||||
<Project>{23499896-b135-4527-8574-c26e926ea99e}</Project>
|
||||
<Name>MediaBrowser.XbmcMetadata</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<Import Project="$(SolutionDir)\.nuget\NuGet.targets" Condition="Exists('$(SolutionDir)\.nuget\NuGet.targets')" />
|
||||
|
|
|
@ -594,6 +594,7 @@ namespace MediaBrowser.WebDashboard.Api
|
|||
"metadataimagespage.js",
|
||||
"metadatasubtitles.js",
|
||||
"metadatachapters.js",
|
||||
"metadataxbmc.js",
|
||||
"moviegenres.js",
|
||||
"moviecollections.js",
|
||||
"movies.js",
|
||||
|
|
|
@ -338,6 +338,9 @@
|
|||
<Content Include="dashboard-ui\metadatachapters.html">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="dashboard-ui\metadataxbmc.html">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="dashboard-ui\mypreferencesdisplay.html">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
|
@ -683,6 +686,9 @@
|
|||
<Content Include="dashboard-ui\scripts\metadatachapters.js">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="dashboard-ui\scripts\metadataxbmc.js">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="dashboard-ui\scripts\mypreferencesdisplay.js">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
|
|
29
MediaBrowser.XbmcMetadata/Configuration/NfoOptions.cs
Normal file
29
MediaBrowser.XbmcMetadata/Configuration/NfoOptions.cs
Normal file
|
@ -0,0 +1,29 @@
|
|||
using MediaBrowser.Common.Configuration;
|
||||
using MediaBrowser.Model.Configuration;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace MediaBrowser.XbmcMetadata.Configuration
|
||||
{
|
||||
public class ConfigurationFactory : IConfigurationFactory
|
||||
{
|
||||
public IEnumerable<ConfigurationStore> GetConfigurations()
|
||||
{
|
||||
return new[]
|
||||
{
|
||||
new ConfigurationStore
|
||||
{
|
||||
ConfigurationType = typeof(XbmcMetadataOptions),
|
||||
Key = "xbmcmetadata"
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
public static class ConfigurationExtension
|
||||
{
|
||||
public static XbmcMetadataOptions GetNfoConfiguration(this IConfigurationManager manager)
|
||||
{
|
||||
return manager.GetConfiguration<XbmcMetadataOptions>("xbmcmetadata");
|
||||
}
|
||||
}
|
||||
}
|
99
MediaBrowser.XbmcMetadata/EntryPoint.cs
Normal file
99
MediaBrowser.XbmcMetadata/EntryPoint.cs
Normal file
|
@ -0,0 +1,99 @@
|
|||
using MediaBrowser.Common.Configuration;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Controller.Library;
|
||||
using MediaBrowser.Controller.Plugins;
|
||||
using MediaBrowser.Controller.Providers;
|
||||
using MediaBrowser.Model.Entities;
|
||||
using MediaBrowser.Model.Logging;
|
||||
using MediaBrowser.XbmcMetadata.Configuration;
|
||||
using System;
|
||||
using System.Linq;
|
||||
|
||||
namespace MediaBrowser.XbmcMetadata
|
||||
{
|
||||
public class EntryPoint : IServerEntryPoint
|
||||
{
|
||||
private readonly IUserDataManager _userDataManager;
|
||||
private readonly ILogger _logger;
|
||||
private readonly ILibraryManager _libraryManager;
|
||||
private readonly IProviderManager _providerManager;
|
||||
private readonly IConfigurationManager _config;
|
||||
|
||||
public EntryPoint(IUserDataManager userDataManager, ILibraryManager libraryManager, ILogger logger, IProviderManager providerManager, IConfigurationManager config)
|
||||
{
|
||||
_userDataManager = userDataManager;
|
||||
_libraryManager = libraryManager;
|
||||
_logger = logger;
|
||||
_providerManager = providerManager;
|
||||
_config = config;
|
||||
}
|
||||
|
||||
public void Run()
|
||||
{
|
||||
_userDataManager.UserDataSaved += _userDataManager_UserDataSaved;
|
||||
_libraryManager.ItemUpdated += _libraryManager_ItemUpdated;
|
||||
}
|
||||
|
||||
void _libraryManager_ItemUpdated(object sender, ItemChangeEventArgs e)
|
||||
{
|
||||
if (e.UpdateReason == ItemUpdateType.ImageUpdate && e.Item is Person)
|
||||
{
|
||||
var person = e.Item.Name;
|
||||
|
||||
var items = _libraryManager.RootFolder
|
||||
.GetRecursiveChildren(i => !i.IsFolder && i.People.Any(p => string.Equals(p.Name, person, StringComparison.OrdinalIgnoreCase)));
|
||||
|
||||
foreach (var item in items)
|
||||
{
|
||||
SaveMetadataForItem(item, ItemUpdateType.MetadataEdit);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void _userDataManager_UserDataSaved(object sender, UserDataSaveEventArgs e)
|
||||
{
|
||||
if (e.SaveReason == UserDataSaveReason.PlaybackFinished || e.SaveReason == UserDataSaveReason.TogglePlayed)
|
||||
{
|
||||
var item = e.Item as BaseItem;
|
||||
|
||||
if (item != null)
|
||||
{
|
||||
if (!item.IsFolder && !(item is IItemByName))
|
||||
{
|
||||
SaveMetadataForItem(item, ItemUpdateType.MetadataEdit);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
_userDataManager.UserDataSaved -= _userDataManager_UserDataSaved;
|
||||
}
|
||||
|
||||
private async void SaveMetadataForItem(BaseItem item, ItemUpdateType updateReason)
|
||||
{
|
||||
var userId = _config.GetNfoConfiguration().UserId;
|
||||
if (string.IsNullOrWhiteSpace(userId))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var locationType = item.LocationType;
|
||||
if (locationType == LocationType.Remote ||
|
||||
locationType == LocationType.Virtual)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
await _providerManager.SaveMetadata(item, updateReason).ConfigureAwait(false);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.ErrorException("Error saving metadata for {0}", ex, item.Path ?? item.Name);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -10,7 +10,7 @@ using System.Globalization;
|
|||
using System.IO;
|
||||
using System.Linq;
|
||||
|
||||
namespace MediaBrowser.Providers.Xbmc
|
||||
namespace MediaBrowser.XbmcMetadata.Images
|
||||
{
|
||||
public class XbmcImageSaver : IImageFileSaver
|
||||
{
|
89
MediaBrowser.XbmcMetadata/MediaBrowser.XbmcMetadata.csproj
Normal file
89
MediaBrowser.XbmcMetadata/MediaBrowser.XbmcMetadata.csproj
Normal file
|
@ -0,0 +1,89 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProjectGuid>{23499896-B135-4527-8574-C26E926EA99E}</ProjectGuid>
|
||||
<OutputType>Library</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>MediaBrowser.XbmcMetadata</RootNamespace>
|
||||
<AssemblyName>MediaBrowser.XbmcMetadata</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>bin\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>bin\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.Xml.Linq" />
|
||||
<Reference Include="System.Data.DataSetExtensions" />
|
||||
<Reference Include="Microsoft.CSharp" />
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Configuration\NfoOptions.cs" />
|
||||
<Compile Include="EntryPoint.cs" />
|
||||
<Compile Include="Images\XbmcImageSaver.cs" />
|
||||
<Compile Include="Parsers\BaseNfoParser.cs" />
|
||||
<Compile Include="Parsers\EpisodeNfoParser.cs" />
|
||||
<Compile Include="Parsers\MovieNfoParser.cs" />
|
||||
<Compile Include="Parsers\SeasonNfoParser.cs" />
|
||||
<Compile Include="Parsers\SeriesNfoParser.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="Providers\AlbumNfoProvider.cs" />
|
||||
<Compile Include="Providers\ArtistNfoProvider.cs" />
|
||||
<Compile Include="Providers\BaseNfoProvider.cs" />
|
||||
<Compile Include="Providers\BaseVideoNfoProvider.cs" />
|
||||
<Compile Include="Providers\EpisodeNfoProvider.cs" />
|
||||
<Compile Include="Providers\MovieNfoProvider.cs" />
|
||||
<Compile Include="Providers\SeasonNfoProvider.cs" />
|
||||
<Compile Include="Providers\SeriesNfoProvider.cs" />
|
||||
<Compile Include="Savers\AlbumXmlSaver.cs" />
|
||||
<Compile Include="Savers\ArtistXmlSaver.cs" />
|
||||
<Compile Include="Savers\EpisodeXmlSaver.cs" />
|
||||
<Compile Include="Savers\MovieXmlSaver.cs" />
|
||||
<Compile Include="Savers\SeasonXmlSaver.cs" />
|
||||
<Compile Include="Savers\SeriesXmlSaver.cs" />
|
||||
<Compile Include="Savers\XmlSaverHelpers.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\MediaBrowser.Common\MediaBrowser.Common.csproj">
|
||||
<Project>{9142eefa-7570-41e1-bfcc-468bb571af2f}</Project>
|
||||
<Name>MediaBrowser.Common</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\MediaBrowser.Controller\MediaBrowser.Controller.csproj">
|
||||
<Project>{17e1f4e6-8abd-4fe5-9ecf-43d4b6087ba2}</Project>
|
||||
<Name>MediaBrowser.Controller</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\MediaBrowser.Model\MediaBrowser.Model.csproj">
|
||||
<Project>{7eeeb4bb-f3e8-48fc-b4c5-70f0fff8329b}</Project>
|
||||
<Name>MediaBrowser.Model</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
<Target Name="BeforeBuild">
|
||||
</Target>
|
||||
<Target Name="AfterBuild">
|
||||
</Target>
|
||||
-->
|
||||
</Project>
|
992
MediaBrowser.XbmcMetadata/Parsers/BaseNfoParser.cs
Normal file
992
MediaBrowser.XbmcMetadata/Parsers/BaseNfoParser.cs
Normal file
|
@ -0,0 +1,992 @@
|
|||
using MediaBrowser.Common.Configuration;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Model.Entities;
|
||||
using MediaBrowser.Model.Logging;
|
||||
using MediaBrowser.XbmcMetadata.Configuration;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Xml;
|
||||
|
||||
namespace MediaBrowser.XbmcMetadata.Parsers
|
||||
{
|
||||
public class BaseNfoParser<T>
|
||||
where T : BaseItem
|
||||
{
|
||||
/// <summary>
|
||||
/// The logger
|
||||
/// </summary>
|
||||
protected ILogger Logger { get; private set; }
|
||||
|
||||
private readonly CultureInfo _usCulture = new CultureInfo("en-US");
|
||||
private readonly IConfigurationManager _config;
|
||||
|
||||
/// <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)
|
||||
{
|
||||
Logger = logger;
|
||||
_config = config;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Fetches metadata for an item from one xml file
|
||||
/// </summary>
|
||||
/// <param name="item">The item.</param>
|
||||
/// <param name="metadataFile">The metadata file.</param>
|
||||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
/// <exception cref="System.ArgumentNullException"></exception>
|
||||
public void Fetch(T item, string metadataFile, CancellationToken cancellationToken)
|
||||
{
|
||||
if (item == null)
|
||||
{
|
||||
throw new ArgumentNullException();
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(metadataFile))
|
||||
{
|
||||
throw new ArgumentNullException();
|
||||
}
|
||||
|
||||
var settings = new XmlReaderSettings
|
||||
{
|
||||
CheckCharacters = false,
|
||||
IgnoreProcessingInstructions = true,
|
||||
IgnoreComments = true,
|
||||
ValidationType = ValidationType.None
|
||||
};
|
||||
|
||||
//Fetch(item, metadataFile, settings, Encoding.GetEncoding("ISO-8859-1"), cancellationToken);
|
||||
Fetch(item, metadataFile, settings, Encoding.UTF8, cancellationToken);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Fetches the specified item.
|
||||
/// </summary>
|
||||
/// <param name="item">The item.</param>
|
||||
/// <param name="metadataFile">The metadata file.</param>
|
||||
/// <param name="settings">The settings.</param>
|
||||
/// <param name="encoding">The encoding.</param>
|
||||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
private void Fetch(T item, string metadataFile, XmlReaderSettings settings, Encoding encoding, CancellationToken cancellationToken)
|
||||
{
|
||||
using (var streamReader = new StreamReader(metadataFile, encoding))
|
||||
{
|
||||
// Use XmlReader for best performance
|
||||
using (var reader = XmlReader.Create(streamReader, settings))
|
||||
{
|
||||
reader.MoveToContent();
|
||||
|
||||
// Loop through each element
|
||||
while (reader.Read())
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
|
||||
if (reader.NodeType == XmlNodeType.Element)
|
||||
{
|
||||
FetchDataFromXmlNode(reader, item);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual void FetchDataFromXmlNode(XmlReader reader, T item)
|
||||
{
|
||||
switch (reader.Name)
|
||||
{
|
||||
// DateCreated
|
||||
case "dateadded":
|
||||
{
|
||||
var val = reader.ReadElementContentAsString();
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(val))
|
||||
{
|
||||
DateTime added;
|
||||
if (DateTime.TryParse(val, out added))
|
||||
{
|
||||
item.DateCreated = added.ToUniversalTime();
|
||||
}
|
||||
else
|
||||
{
|
||||
Logger.Warn("Invalid Added value found: " + val);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case "title":
|
||||
case "localtitle":
|
||||
item.Name = reader.ReadElementContentAsString();
|
||||
break;
|
||||
|
||||
case "criticrating":
|
||||
{
|
||||
var text = reader.ReadElementContentAsString();
|
||||
|
||||
var hasCriticRating = item as IHasCriticRating;
|
||||
|
||||
if (hasCriticRating != null && !string.IsNullOrEmpty(text))
|
||||
{
|
||||
float value;
|
||||
if (float.TryParse(text, NumberStyles.Any, _usCulture, out value))
|
||||
{
|
||||
hasCriticRating.CriticRating = value;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case "budget":
|
||||
{
|
||||
var text = reader.ReadElementContentAsString();
|
||||
var hasBudget = item as IHasBudget;
|
||||
if (hasBudget != null)
|
||||
{
|
||||
double value;
|
||||
if (double.TryParse(text, NumberStyles.Any, _usCulture, out value))
|
||||
{
|
||||
hasBudget.Budget = value;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case "revenue":
|
||||
{
|
||||
var text = reader.ReadElementContentAsString();
|
||||
var hasBudget = item as IHasBudget;
|
||||
if (hasBudget != null)
|
||||
{
|
||||
double value;
|
||||
if (double.TryParse(text, NumberStyles.Any, _usCulture, out value))
|
||||
{
|
||||
hasBudget.Revenue = value;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case "metascore":
|
||||
{
|
||||
var text = reader.ReadElementContentAsString();
|
||||
var hasMetascore = item as IHasMetascore;
|
||||
if (hasMetascore != null)
|
||||
{
|
||||
float value;
|
||||
if (float.TryParse(text, NumberStyles.Any, _usCulture, out value))
|
||||
{
|
||||
hasMetascore.Metascore = value;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case "awardsummary":
|
||||
{
|
||||
var text = reader.ReadElementContentAsString();
|
||||
var hasAwards = item as IHasAwards;
|
||||
if (hasAwards != null)
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(text))
|
||||
{
|
||||
hasAwards.AwardSummary = text;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case "sorttitle":
|
||||
{
|
||||
var val = reader.ReadElementContentAsString();
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(val))
|
||||
{
|
||||
item.ForcedSortName = val;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case "outline":
|
||||
{
|
||||
var val = reader.ReadElementContentAsString();
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(val))
|
||||
{
|
||||
var hasShortOverview = item as IHasShortOverview;
|
||||
|
||||
if (hasShortOverview != null)
|
||||
{
|
||||
hasShortOverview.ShortOverview = val;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case "biography":
|
||||
case "plot":
|
||||
case "review":
|
||||
{
|
||||
var val = reader.ReadElementContentAsString();
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(val))
|
||||
{
|
||||
item.Overview = val;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case "criticratingsummary":
|
||||
{
|
||||
var val = reader.ReadElementContentAsString();
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(val))
|
||||
{
|
||||
var hasCriticRating = item as IHasCriticRating;
|
||||
|
||||
if (hasCriticRating != null)
|
||||
{
|
||||
hasCriticRating.CriticRatingSummary = val;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case "language":
|
||||
{
|
||||
var val = reader.ReadElementContentAsString();
|
||||
|
||||
var hasLanguage = item as IHasPreferredMetadataLanguage;
|
||||
if (hasLanguage != null)
|
||||
{
|
||||
hasLanguage.PreferredMetadataLanguage = val;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case "website":
|
||||
{
|
||||
var val = reader.ReadElementContentAsString();
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(val))
|
||||
{
|
||||
item.HomePageUrl = val;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case "lockedfields":
|
||||
{
|
||||
var fields = new List<MetadataFields>();
|
||||
|
||||
var val = reader.ReadElementContentAsString();
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(val))
|
||||
{
|
||||
var list = val.Split('|').Select(i =>
|
||||
{
|
||||
MetadataFields field;
|
||||
|
||||
if (Enum.TryParse<MetadataFields>(i, true, out field))
|
||||
{
|
||||
return (MetadataFields?)field;
|
||||
}
|
||||
|
||||
return null;
|
||||
|
||||
}).Where(i => i.HasValue).Select(i => i.Value);
|
||||
|
||||
fields.AddRange(list);
|
||||
}
|
||||
|
||||
item.LockedFields = fields;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case "tagline":
|
||||
{
|
||||
var val = reader.ReadElementContentAsString();
|
||||
|
||||
var hasTagline = item as IHasTaglines;
|
||||
if (hasTagline != null)
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(val))
|
||||
{
|
||||
hasTagline.AddTagline(val);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case "country":
|
||||
{
|
||||
var val = reader.ReadElementContentAsString();
|
||||
|
||||
var hasProductionLocations = item as IHasProductionLocations;
|
||||
if (hasProductionLocations != null)
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(val))
|
||||
{
|
||||
hasProductionLocations.AddProductionLocation(val);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case "mpaa":
|
||||
{
|
||||
var rating = reader.ReadElementContentAsString();
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(rating))
|
||||
{
|
||||
item.OfficialRating = rating;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case "mpaadescription":
|
||||
{
|
||||
var rating = reader.ReadElementContentAsString();
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(rating))
|
||||
{
|
||||
item.OfficialRatingDescription = rating;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case "customrating":
|
||||
{
|
||||
var val = reader.ReadElementContentAsString();
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(val))
|
||||
{
|
||||
item.CustomRating = val;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case "runtime":
|
||||
{
|
||||
var text = reader.ReadElementContentAsString();
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(text))
|
||||
{
|
||||
int runtime;
|
||||
if (int.TryParse(text.Split(' ')[0], NumberStyles.Integer, _usCulture, out runtime))
|
||||
{
|
||||
item.RunTimeTicks = TimeSpan.FromMinutes(runtime).Ticks;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case "aspectratio":
|
||||
{
|
||||
var val = reader.ReadElementContentAsString();
|
||||
|
||||
var hasAspectRatio = item as IHasAspectRatio;
|
||||
if (!string.IsNullOrWhiteSpace(val) && hasAspectRatio != null)
|
||||
{
|
||||
hasAspectRatio.AspectRatio = val;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case "lockdata":
|
||||
{
|
||||
var val = reader.ReadElementContentAsString();
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(val))
|
||||
{
|
||||
item.IsLocked = string.Equals("true", val, StringComparison.OrdinalIgnoreCase);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case "studio":
|
||||
{
|
||||
var val = reader.ReadElementContentAsString();
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(val))
|
||||
{
|
||||
item.AddStudio(val);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case "director":
|
||||
{
|
||||
foreach (var p in SplitNames(reader.ReadElementContentAsString()).Select(v => new PersonInfo { Name = v.Trim(), Type = PersonType.Director }))
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(p.Name))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
item.AddPerson(p);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "credits":
|
||||
{
|
||||
var val = reader.ReadElementContentAsString();
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(val))
|
||||
{
|
||||
var parts = val.Split('/').Select(i => i.Trim())
|
||||
.Where(i => !string.IsNullOrEmpty(i));
|
||||
|
||||
foreach (var p in parts.Select(v => new PersonInfo { Name = v.Trim(), Type = PersonType.Writer }))
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(p.Name))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
item.AddPerson(p);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case "writer":
|
||||
{
|
||||
foreach (var p in SplitNames(reader.ReadElementContentAsString()).Select(v => new PersonInfo { Name = v.Trim(), Type = PersonType.Writer }))
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(p.Name))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
item.AddPerson(p);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case "actor":
|
||||
{
|
||||
using (var subtree = reader.ReadSubtree())
|
||||
{
|
||||
var person = GetPersonFromXmlNode(subtree);
|
||||
|
||||
item.AddPerson(person);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case "trailer":
|
||||
{
|
||||
var val = reader.ReadElementContentAsString();
|
||||
|
||||
var hasTrailer = item as IHasTrailers;
|
||||
if (hasTrailer != null)
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(val))
|
||||
{
|
||||
hasTrailer.AddTrailerUrl(val, false);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case "displayorder":
|
||||
{
|
||||
var val = reader.ReadElementContentAsString();
|
||||
|
||||
var hasDisplayOrder = item as IHasDisplayOrder;
|
||||
if (hasDisplayOrder != null)
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(val))
|
||||
{
|
||||
hasDisplayOrder.DisplayOrder = val;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case "year":
|
||||
{
|
||||
var val = reader.ReadElementContentAsString();
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(val))
|
||||
{
|
||||
int productionYear;
|
||||
if (int.TryParse(val, out productionYear) && productionYear > 1850)
|
||||
{
|
||||
item.ProductionYear = productionYear;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case "rating":
|
||||
{
|
||||
|
||||
var rating = reader.ReadElementContentAsString();
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(rating))
|
||||
{
|
||||
float val;
|
||||
// All external meta is saving this as '.' for decimal I believe...but just to be sure
|
||||
if (float.TryParse(rating.Replace(',', '.'), NumberStyles.AllowDecimalPoint, CultureInfo.InvariantCulture, out val))
|
||||
{
|
||||
item.CommunityRating = val;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case "aired":
|
||||
case "formed":
|
||||
case "premiered":
|
||||
case "releasedate":
|
||||
{
|
||||
var formatString = _config.GetNfoConfiguration().ReleaseDateFormat;
|
||||
|
||||
var val = reader.ReadElementContentAsString();
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(val))
|
||||
{
|
||||
DateTime date;
|
||||
|
||||
if (DateTime.TryParseExact(val, formatString, CultureInfo.InvariantCulture, DateTimeStyles.AssumeLocal, out date) && date.Year > 1850)
|
||||
{
|
||||
item.PremiereDate = date.ToUniversalTime();
|
||||
item.ProductionYear = date.Year;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case "enddate":
|
||||
{
|
||||
var formatString = _config.GetNfoConfiguration().ReleaseDateFormat;
|
||||
|
||||
var val = reader.ReadElementContentAsString();
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(val))
|
||||
{
|
||||
DateTime date;
|
||||
|
||||
if (DateTime.TryParseExact(val, formatString, CultureInfo.InvariantCulture, DateTimeStyles.AssumeLocal, out date) && date.Year > 1850)
|
||||
{
|
||||
item.EndDate = date.ToUniversalTime();
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case "tvdbid":
|
||||
var tvdbId = reader.ReadElementContentAsString();
|
||||
if (!string.IsNullOrWhiteSpace(tvdbId))
|
||||
{
|
||||
item.SetProviderId(MetadataProviders.Tvdb, tvdbId);
|
||||
}
|
||||
break;
|
||||
|
||||
case "votes":
|
||||
{
|
||||
var val = reader.ReadElementContentAsString();
|
||||
if (!string.IsNullOrWhiteSpace(val))
|
||||
{
|
||||
int num;
|
||||
|
||||
if (int.TryParse(val, NumberStyles.Integer, _usCulture, out num))
|
||||
{
|
||||
item.VoteCount = num;
|
||||
}
|
||||
}
|
||||
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 "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":
|
||||
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":
|
||||
{
|
||||
var val = reader.ReadElementContentAsString();
|
||||
if (!string.IsNullOrWhiteSpace(val))
|
||||
{
|
||||
item.AddGenre(val);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case "style":
|
||||
case "tag":
|
||||
{
|
||||
var val = reader.ReadElementContentAsString();
|
||||
if (!string.IsNullOrWhiteSpace(val))
|
||||
{
|
||||
var hasTags = item as IHasTags;
|
||||
if (hasTags != null)
|
||||
{
|
||||
hasTags.AddTag(val);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case "plotkeyword":
|
||||
{
|
||||
var val = reader.ReadElementContentAsString();
|
||||
|
||||
var hasKeywords = item as IHasKeywords;
|
||||
if (hasKeywords != null)
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(val))
|
||||
{
|
||||
hasKeywords.AddKeyword(val);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case "fileinfo":
|
||||
{
|
||||
using (var subtree = reader.ReadSubtree())
|
||||
{
|
||||
FetchFromFileInfoNode(subtree, item);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
reader.Skip();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void FetchFromFileInfoNode(XmlReader reader, T item)
|
||||
{
|
||||
reader.MoveToContent();
|
||||
|
||||
while (reader.Read())
|
||||
{
|
||||
if (reader.NodeType == XmlNodeType.Element)
|
||||
{
|
||||
switch (reader.Name)
|
||||
{
|
||||
case "streamdetails":
|
||||
{
|
||||
using (var subtree = reader.ReadSubtree())
|
||||
{
|
||||
FetchFromStreamDetailsNode(subtree, item);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
reader.Skip();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void FetchFromStreamDetailsNode(XmlReader reader, T item)
|
||||
{
|
||||
reader.MoveToContent();
|
||||
|
||||
while (reader.Read())
|
||||
{
|
||||
if (reader.NodeType == XmlNodeType.Element)
|
||||
{
|
||||
switch (reader.Name)
|
||||
{
|
||||
case "video":
|
||||
{
|
||||
using (var subtree = reader.ReadSubtree())
|
||||
{
|
||||
FetchFromVideoNode(subtree, item);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
reader.Skip();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void FetchFromVideoNode(XmlReader reader, T item)
|
||||
{
|
||||
reader.MoveToContent();
|
||||
|
||||
while (reader.Read())
|
||||
{
|
||||
if (reader.NodeType == XmlNodeType.Element)
|
||||
{
|
||||
switch (reader.Name)
|
||||
{
|
||||
case "format3d":
|
||||
{
|
||||
var video = item as Video;
|
||||
|
||||
if (video != null)
|
||||
{
|
||||
var val = reader.ReadElementContentAsString();
|
||||
|
||||
if (string.Equals("HSBS", val, StringComparison.CurrentCulture))
|
||||
{
|
||||
video.Video3DFormat = Video3DFormat.HalfSideBySide;
|
||||
}
|
||||
else if (string.Equals("HTAB", val, StringComparison.CurrentCulture))
|
||||
{
|
||||
video.Video3DFormat = Video3DFormat.HalfTopAndBottom;
|
||||
}
|
||||
else if (string.Equals("FTAB", val, StringComparison.CurrentCulture))
|
||||
{
|
||||
video.Video3DFormat = Video3DFormat.FullTopAndBottom;
|
||||
}
|
||||
else if (string.Equals("FSBS", val, StringComparison.CurrentCulture))
|
||||
{
|
||||
video.Video3DFormat = Video3DFormat.FullSideBySide;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
reader.Skip();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the persons from XML node.
|
||||
/// </summary>
|
||||
/// <param name="reader">The reader.</param>
|
||||
/// <returns>IEnumerable{PersonInfo}.</returns>
|
||||
private PersonInfo GetPersonFromXmlNode(XmlReader reader)
|
||||
{
|
||||
var name = string.Empty;
|
||||
var type = PersonType.Actor; // If type is not specified assume actor
|
||||
var role = string.Empty;
|
||||
int? sortOrder = null;
|
||||
|
||||
reader.MoveToContent();
|
||||
|
||||
while (reader.Read())
|
||||
{
|
||||
if (reader.NodeType == XmlNodeType.Element)
|
||||
{
|
||||
switch (reader.Name)
|
||||
{
|
||||
case "name":
|
||||
name = reader.ReadElementContentAsString() ?? string.Empty;
|
||||
break;
|
||||
|
||||
case "type":
|
||||
{
|
||||
var val = reader.ReadElementContentAsString();
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(val))
|
||||
{
|
||||
type = val;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case "role":
|
||||
{
|
||||
var val = reader.ReadElementContentAsString();
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(val))
|
||||
{
|
||||
role = val;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "sortorder":
|
||||
{
|
||||
var val = reader.ReadElementContentAsString();
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(val))
|
||||
{
|
||||
int intVal;
|
||||
if (int.TryParse(val, NumberStyles.Integer, _usCulture, out intVal))
|
||||
{
|
||||
sortOrder = intVal;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
reader.Skip();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return new PersonInfo
|
||||
{
|
||||
Name = name.Trim(),
|
||||
Role = role,
|
||||
Type = type,
|
||||
SortOrder = sortOrder
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Used to split names of comma or pipe delimeted genres and people
|
||||
/// </summary>
|
||||
/// <param name="value">The value.</param>
|
||||
/// <returns>IEnumerable{System.String}.</returns>
|
||||
private IEnumerable<string> SplitNames(string value)
|
||||
{
|
||||
value = value ?? string.Empty;
|
||||
|
||||
// Only split by comma if there is no pipe in the string
|
||||
// We have to be careful to not split names like Matthew, Jr.
|
||||
var separator = value.IndexOf('|') == -1 && value.IndexOf(';') == -1 ? new[] { ',' } : new[] { '|', ';' };
|
||||
|
||||
value = value.Trim().Trim(separator);
|
||||
|
||||
return string.IsNullOrWhiteSpace(value) ? new string[] { } : Split(value, separator, StringSplitOptions.RemoveEmptyEntries);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Provides an additional overload for string.split
|
||||
/// </summary>
|
||||
/// <param name="val">The val.</param>
|
||||
/// <param name="separators">The separators.</param>
|
||||
/// <param name="options">The options.</param>
|
||||
/// <returns>System.String[][].</returns>
|
||||
private static string[] Split(string val, char[] separators, StringSplitOptions options)
|
||||
{
|
||||
return val.Split(separators, options);
|
||||
}
|
||||
}
|
||||
}
|
211
MediaBrowser.XbmcMetadata/Parsers/EpisodeNfoParser.cs
Normal file
211
MediaBrowser.XbmcMetadata/Parsers/EpisodeNfoParser.cs
Normal file
|
@ -0,0 +1,211 @@
|
|||
using MediaBrowser.Common.Configuration;
|
||||
using MediaBrowser.Controller.Entities.TV;
|
||||
using MediaBrowser.Controller.Providers;
|
||||
using MediaBrowser.Model.Entities;
|
||||
using MediaBrowser.Model.Logging;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Threading;
|
||||
using System.Xml;
|
||||
|
||||
namespace MediaBrowser.XbmcMetadata.Parsers
|
||||
{
|
||||
public class EpisodeNfoParser : BaseNfoParser<Episode>
|
||||
{
|
||||
private List<LocalImageInfo> _imagesFound;
|
||||
private List<ChapterInfo> _chaptersFound;
|
||||
private string _xmlPath;
|
||||
|
||||
public EpisodeNfoParser(ILogger logger, IConfigurationManager config) : base(logger, config)
|
||||
{
|
||||
}
|
||||
|
||||
public void Fetch(Episode item,
|
||||
List<LocalImageInfo> images,
|
||||
List<ChapterInfo> chapters,
|
||||
string metadataFile,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
_imagesFound = images;
|
||||
_chaptersFound = chapters;
|
||||
_xmlPath = metadataFile;
|
||||
|
||||
Fetch(item, metadataFile, cancellationToken);
|
||||
}
|
||||
|
||||
private static readonly CultureInfo UsCulture = new CultureInfo("en-US");
|
||||
|
||||
/// <summary>
|
||||
/// Fetches the data from XML node.
|
||||
/// </summary>
|
||||
/// <param name="reader">The reader.</param>
|
||||
/// <param name="item">The item.</param>
|
||||
protected override void FetchDataFromXmlNode(XmlReader reader, Episode item)
|
||||
{
|
||||
switch (reader.Name)
|
||||
{
|
||||
//case "Chapters":
|
||||
|
||||
// _chaptersFound.AddRange(FetchChaptersFromXmlNode(item, reader.ReadSubtree()));
|
||||
// break;
|
||||
|
||||
case "season":
|
||||
{
|
||||
var number = reader.ReadElementContentAsString();
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(number))
|
||||
{
|
||||
int num;
|
||||
|
||||
if (int.TryParse(number, out num))
|
||||
{
|
||||
item.ParentIndexNumber = num;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case "episode":
|
||||
{
|
||||
var number = reader.ReadElementContentAsString();
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(number))
|
||||
{
|
||||
int num;
|
||||
|
||||
if (int.TryParse(number, out num))
|
||||
{
|
||||
item.IndexNumber = num;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case "episodenumberend":
|
||||
{
|
||||
var number = reader.ReadElementContentAsString();
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(number))
|
||||
{
|
||||
int num;
|
||||
|
||||
if (int.TryParse(number, out num))
|
||||
{
|
||||
item.IndexNumberEnd = num;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case "absolute_number":
|
||||
{
|
||||
var val = reader.ReadElementContentAsString();
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(val))
|
||||
{
|
||||
int rval;
|
||||
|
||||
// int.TryParse is local aware, so it can be probamatic, force us culture
|
||||
if (int.TryParse(val, NumberStyles.Integer, UsCulture, out rval))
|
||||
{
|
||||
item.AbsoluteEpisodeNumber = rval;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case "DVD_episodenumber":
|
||||
{
|
||||
var number = reader.ReadElementContentAsString();
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(number))
|
||||
{
|
||||
float num;
|
||||
|
||||
if (float.TryParse(number, NumberStyles.Any, UsCulture, out num))
|
||||
{
|
||||
item.DvdEpisodeNumber = num;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case "DVD_season":
|
||||
{
|
||||
var number = reader.ReadElementContentAsString();
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(number))
|
||||
{
|
||||
float num;
|
||||
|
||||
if (float.TryParse(number, NumberStyles.Any, UsCulture, out num))
|
||||
{
|
||||
item.DvdSeasonNumber = Convert.ToInt32(num);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case "airsbefore_episode":
|
||||
{
|
||||
var val = reader.ReadElementContentAsString();
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(val))
|
||||
{
|
||||
int rval;
|
||||
|
||||
// int.TryParse is local aware, so it can be probamatic, force us culture
|
||||
if (int.TryParse(val, NumberStyles.Integer, UsCulture, out rval))
|
||||
{
|
||||
item.AirsBeforeEpisodeNumber = rval;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case "airsafter_season":
|
||||
{
|
||||
var val = reader.ReadElementContentAsString();
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(val))
|
||||
{
|
||||
int rval;
|
||||
|
||||
// int.TryParse is local aware, so it can be probamatic, force us culture
|
||||
if (int.TryParse(val, NumberStyles.Integer, UsCulture, out rval))
|
||||
{
|
||||
item.AirsAfterSeasonNumber = rval;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case "airsbefore_season":
|
||||
{
|
||||
var val = reader.ReadElementContentAsString();
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(val))
|
||||
{
|
||||
int rval;
|
||||
|
||||
// int.TryParse is local aware, so it can be probamatic, force us culture
|
||||
if (int.TryParse(val, NumberStyles.Integer, UsCulture, out rval))
|
||||
{
|
||||
item.AirsBeforeSeasonNumber = rval;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
default:
|
||||
base.FetchDataFromXmlNode(reader, item);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
97
MediaBrowser.XbmcMetadata/Parsers/MovieNfoParser.cs
Normal file
97
MediaBrowser.XbmcMetadata/Parsers/MovieNfoParser.cs
Normal file
|
@ -0,0 +1,97 @@
|
|||
using MediaBrowser.Common.Configuration;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Controller.Entities.Movies;
|
||||
using MediaBrowser.Model.Entities;
|
||||
using MediaBrowser.Model.Logging;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using System.Xml;
|
||||
|
||||
namespace MediaBrowser.XbmcMetadata.Parsers
|
||||
{
|
||||
class MovieNfoParser : BaseNfoParser<Video>
|
||||
{
|
||||
private List<ChapterInfo> _chaptersFound;
|
||||
|
||||
public MovieNfoParser(ILogger logger, IConfigurationManager config) : base(logger, config)
|
||||
{
|
||||
}
|
||||
|
||||
public void Fetch(Video item,
|
||||
List<ChapterInfo> chapters,
|
||||
string metadataFile,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
_chaptersFound = chapters;
|
||||
|
||||
Fetch(item, metadataFile, cancellationToken);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Fetches the data from XML node.
|
||||
/// </summary>
|
||||
/// <param name="reader">The reader.</param>
|
||||
/// <param name="item">The item.</param>
|
||||
protected override void FetchDataFromXmlNode(XmlReader reader, Video item)
|
||||
{
|
||||
switch (reader.Name)
|
||||
{
|
||||
case "id":
|
||||
var id = reader.ReadElementContentAsString();
|
||||
if (!string.IsNullOrWhiteSpace(id))
|
||||
{
|
||||
item.SetProviderId(MetadataProviders.Imdb, id);
|
||||
}
|
||||
break;
|
||||
|
||||
case "set":
|
||||
{
|
||||
var val = reader.ReadElementContentAsString();
|
||||
var movie = item as Movie;
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(val) && movie != null)
|
||||
{
|
||||
movie.TmdbCollectionName = val;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case "artist":
|
||||
{
|
||||
var val = reader.ReadElementContentAsString();
|
||||
var movie = item as MusicVideo;
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(val) && movie != null)
|
||||
{
|
||||
movie.Artist = val;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case "album":
|
||||
{
|
||||
var val = reader.ReadElementContentAsString();
|
||||
var movie = item as MusicVideo;
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(val) && movie != null)
|
||||
{
|
||||
movie.Album = val;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
//case "chapter":
|
||||
|
||||
// _chaptersFound.AddRange(FetchChaptersFromXmlNode(item, reader.ReadSubtree()));
|
||||
// break;
|
||||
|
||||
default:
|
||||
base.FetchDataFromXmlNode(reader, item);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
45
MediaBrowser.XbmcMetadata/Parsers/SeasonNfoParser.cs
Normal file
45
MediaBrowser.XbmcMetadata/Parsers/SeasonNfoParser.cs
Normal file
|
@ -0,0 +1,45 @@
|
|||
using MediaBrowser.Common.Configuration;
|
||||
using MediaBrowser.Controller.Entities.TV;
|
||||
using MediaBrowser.Model.Logging;
|
||||
using System.Xml;
|
||||
|
||||
namespace MediaBrowser.XbmcMetadata.Parsers
|
||||
{
|
||||
public class SeasonNfoParser : BaseNfoParser<Season>
|
||||
{
|
||||
public SeasonNfoParser(ILogger logger, IConfigurationManager config) : base(logger, config)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Fetches the data from XML node.
|
||||
/// </summary>
|
||||
/// <param name="reader">The reader.</param>
|
||||
/// <param name="item">The item.</param>
|
||||
protected override void FetchDataFromXmlNode(XmlReader reader, Season 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, item);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
93
MediaBrowser.XbmcMetadata/Parsers/SeriesNfoParser.cs
Normal file
93
MediaBrowser.XbmcMetadata/Parsers/SeriesNfoParser.cs
Normal file
|
@ -0,0 +1,93 @@
|
|||
using MediaBrowser.Common.Configuration;
|
||||
using MediaBrowser.Controller.Entities.TV;
|
||||
using MediaBrowser.Controller.Library;
|
||||
using MediaBrowser.Model.Entities;
|
||||
using MediaBrowser.Model.Logging;
|
||||
using System;
|
||||
using System.Xml;
|
||||
|
||||
namespace MediaBrowser.XbmcMetadata.Parsers
|
||||
{
|
||||
public class SeriesNfoParser : BaseNfoParser<Series>
|
||||
{
|
||||
public SeriesNfoParser(ILogger logger, IConfigurationManager config) : base(logger, config)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Fetches the data from XML node.
|
||||
/// </summary>
|
||||
/// <param name="reader">The reader.</param>
|
||||
/// <param name="item">The item.</param>
|
||||
protected override void FetchDataFromXmlNode(XmlReader reader, Series item)
|
||||
{
|
||||
switch (reader.Name)
|
||||
{
|
||||
case "id":
|
||||
string id = reader.ReadElementContentAsString();
|
||||
if (!string.IsNullOrWhiteSpace(id))
|
||||
{
|
||||
item.SetProviderId(MetadataProviders.Tvdb, id);
|
||||
}
|
||||
break;
|
||||
|
||||
case "airs_dayofweek":
|
||||
{
|
||||
item.AirDays = TVUtils.GetAirDays(reader.ReadElementContentAsString());
|
||||
break;
|
||||
}
|
||||
|
||||
case "airs_time":
|
||||
{
|
||||
var val = reader.ReadElementContentAsString();
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(val))
|
||||
{
|
||||
item.AirTime = val;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case "animeseriesindex":
|
||||
{
|
||||
var number = reader.ReadElementContentAsString();
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(number))
|
||||
{
|
||||
int num;
|
||||
|
||||
if (int.TryParse(number, out num))
|
||||
{
|
||||
item.AnimeSeriesIndex = num;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case "status":
|
||||
{
|
||||
var status = reader.ReadElementContentAsString();
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(status))
|
||||
{
|
||||
SeriesStatus seriesStatus;
|
||||
if (Enum.TryParse(status, true, out seriesStatus))
|
||||
{
|
||||
item.Status = seriesStatus;
|
||||
}
|
||||
else
|
||||
{
|
||||
Logger.Info("Unrecognized series status: " + status);
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
base.FetchDataFromXmlNode(reader, item);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
36
MediaBrowser.XbmcMetadata/Properties/AssemblyInfo.cs
Normal file
36
MediaBrowser.XbmcMetadata/Properties/AssemblyInfo.cs
Normal file
|
@ -0,0 +1,36 @@
|
|||
using System.Reflection;
|
||||
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("")]
|
||||
[assembly: AssemblyProduct("MediaBrowser.XbmcMetadata")]
|
||||
[assembly: AssemblyCopyright("Copyright © 2014")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
// 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)]
|
||||
|
||||
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
||||
[assembly: Guid("bbdf434b-65f1-4178-8ddf-067447df3e20")]
|
||||
|
||||
// Version information for an assembly consists of the following four values:
|
||||
//
|
||||
// Major Version
|
||||
// Minor Version
|
||||
// Build Number
|
||||
// Revision
|
||||
//
|
||||
// You can specify all the values or you can default the Build and Revision Numbers
|
||||
// by using the '*' as shown below:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
34
MediaBrowser.XbmcMetadata/Providers/AlbumNfoProvider.cs
Normal file
34
MediaBrowser.XbmcMetadata/Providers/AlbumNfoProvider.cs
Normal file
|
@ -0,0 +1,34 @@
|
|||
using MediaBrowser.Common.Configuration;
|
||||
using MediaBrowser.Common.IO;
|
||||
using MediaBrowser.Controller.Entities.Audio;
|
||||
using MediaBrowser.Controller.Providers;
|
||||
using MediaBrowser.Model.Logging;
|
||||
using MediaBrowser.XbmcMetadata.Parsers;
|
||||
using System.IO;
|
||||
using System.Threading;
|
||||
|
||||
namespace MediaBrowser.XbmcMetadata.Providers
|
||||
{
|
||||
public class AlbumNfoProvider : BaseNfoProvider<MusicAlbum>
|
||||
{
|
||||
private readonly ILogger _logger;
|
||||
private readonly IConfigurationManager _config;
|
||||
|
||||
public AlbumNfoProvider(IFileSystem fileSystem, ILogger logger, IConfigurationManager config)
|
||||
: base(fileSystem)
|
||||
{
|
||||
_logger = logger;
|
||||
_config = config;
|
||||
}
|
||||
|
||||
protected override void Fetch(LocalMetadataResult<MusicAlbum> result, string path, CancellationToken cancellationToken)
|
||||
{
|
||||
new BaseNfoParser<MusicAlbum>(_logger, _config).Fetch(result.Item, path, cancellationToken);
|
||||
}
|
||||
|
||||
protected override FileSystemInfo GetXmlFile(ItemInfo info, IDirectoryService directoryService)
|
||||
{
|
||||
return directoryService.GetFile(Path.Combine(info.Path, "album.nfo"));
|
||||
}
|
||||
}
|
||||
}
|
34
MediaBrowser.XbmcMetadata/Providers/ArtistNfoProvider.cs
Normal file
34
MediaBrowser.XbmcMetadata/Providers/ArtistNfoProvider.cs
Normal file
|
@ -0,0 +1,34 @@
|
|||
using MediaBrowser.Common.Configuration;
|
||||
using MediaBrowser.Common.IO;
|
||||
using MediaBrowser.Controller.Entities.Audio;
|
||||
using MediaBrowser.Controller.Providers;
|
||||
using MediaBrowser.Model.Logging;
|
||||
using MediaBrowser.XbmcMetadata.Parsers;
|
||||
using System.IO;
|
||||
using System.Threading;
|
||||
|
||||
namespace MediaBrowser.XbmcMetadata.Providers
|
||||
{
|
||||
public class ArtistNfoProvider : BaseNfoProvider<MusicArtist>
|
||||
{
|
||||
private readonly ILogger _logger;
|
||||
private readonly IConfigurationManager _config;
|
||||
|
||||
public ArtistNfoProvider(IFileSystem fileSystem, ILogger logger, IConfigurationManager config)
|
||||
: base(fileSystem)
|
||||
{
|
||||
_logger = logger;
|
||||
_config = config;
|
||||
}
|
||||
|
||||
protected override void Fetch(LocalMetadataResult<MusicArtist> result, string path, CancellationToken cancellationToken)
|
||||
{
|
||||
new BaseNfoParser<MusicArtist>(_logger, _config).Fetch(result.Item, path, cancellationToken);
|
||||
}
|
||||
|
||||
protected override FileSystemInfo GetXmlFile(ItemInfo info, IDirectoryService directoryService)
|
||||
{
|
||||
return directoryService.GetFile(Path.Combine(info.Path, "artist.nfo"));
|
||||
}
|
||||
}
|
||||
}
|
89
MediaBrowser.XbmcMetadata/Providers/BaseNfoProvider.cs
Normal file
89
MediaBrowser.XbmcMetadata/Providers/BaseNfoProvider.cs
Normal file
|
@ -0,0 +1,89 @@
|
|||
using MediaBrowser.Common.IO;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Controller.Providers;
|
||||
using MediaBrowser.Model.Logging;
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace MediaBrowser.XbmcMetadata.Providers
|
||||
{
|
||||
public abstract class BaseNfoProvider<T> : ILocalMetadataProvider<T>, IHasChangeMonitor
|
||||
where T : IHasMetadata, new()
|
||||
{
|
||||
protected IFileSystem FileSystem;
|
||||
|
||||
public async Task<LocalMetadataResult<T>> GetMetadata(ItemInfo info, CancellationToken cancellationToken)
|
||||
{
|
||||
var result = new LocalMetadataResult<T>();
|
||||
|
||||
var file = GetXmlFile(info, new DirectoryService(new NullLogger()));
|
||||
|
||||
if (file == null)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
var path = file.FullName;
|
||||
|
||||
await XmlProviderUtils.XmlParsingResourcePool.WaitAsync(cancellationToken).ConfigureAwait(false);
|
||||
|
||||
try
|
||||
{
|
||||
result.Item = new T();
|
||||
|
||||
Fetch(result, path, cancellationToken);
|
||||
result.HasMetadata = true;
|
||||
}
|
||||
catch (FileNotFoundException)
|
||||
{
|
||||
result.HasMetadata = false;
|
||||
}
|
||||
catch (DirectoryNotFoundException)
|
||||
{
|
||||
result.HasMetadata = false;
|
||||
}
|
||||
finally
|
||||
{
|
||||
XmlProviderUtils.XmlParsingResourcePool.Release();
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
protected abstract void Fetch(LocalMetadataResult<T> result, string path, CancellationToken cancellationToken);
|
||||
|
||||
protected BaseNfoProvider(IFileSystem fileSystem)
|
||||
{
|
||||
FileSystem = fileSystem;
|
||||
}
|
||||
|
||||
protected abstract FileSystemInfo GetXmlFile(ItemInfo info, IDirectoryService directoryService);
|
||||
|
||||
public bool HasChanged(IHasMetadata item, IDirectoryService directoryService, DateTime date)
|
||||
{
|
||||
var file = GetXmlFile(new ItemInfo { IsInMixedFolder = item.IsInMixedFolder, Path = item.Path }, directoryService);
|
||||
|
||||
if (file == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return file.Exists && FileSystem.GetLastWriteTimeUtc(file) > date;
|
||||
}
|
||||
|
||||
public string Name
|
||||
{
|
||||
get
|
||||
{
|
||||
return "Xbmc Nfo";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static class XmlProviderUtils
|
||||
{
|
||||
internal static readonly SemaphoreSlim XmlParsingResourcePool = new SemaphoreSlim(4, 4);
|
||||
}
|
||||
}
|
55
MediaBrowser.XbmcMetadata/Providers/BaseVideoNfoProvider.cs
Normal file
55
MediaBrowser.XbmcMetadata/Providers/BaseVideoNfoProvider.cs
Normal file
|
@ -0,0 +1,55 @@
|
|||
using MediaBrowser.Common.Configuration;
|
||||
using MediaBrowser.Common.IO;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Controller.Providers;
|
||||
using MediaBrowser.Model.Entities;
|
||||
using MediaBrowser.Model.Logging;
|
||||
using MediaBrowser.XbmcMetadata.Parsers;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Threading;
|
||||
|
||||
namespace MediaBrowser.XbmcMetadata.Providers
|
||||
{
|
||||
public class BaseVideoNfoProvider<T> : BaseNfoProvider<T>
|
||||
where T : Video, new ()
|
||||
{
|
||||
private readonly ILogger _logger;
|
||||
private readonly IConfigurationManager _config;
|
||||
|
||||
public BaseVideoNfoProvider(IFileSystem fileSystem, ILogger logger, IConfigurationManager config)
|
||||
: base(fileSystem)
|
||||
{
|
||||
_logger = logger;
|
||||
_config = config;
|
||||
}
|
||||
|
||||
protected override void Fetch(LocalMetadataResult<T> result, string path, CancellationToken cancellationToken)
|
||||
{
|
||||
var chapters = new List<ChapterInfo>();
|
||||
|
||||
new MovieNfoParser(_logger, _config).Fetch(result.Item, chapters, path, cancellationToken);
|
||||
|
||||
result.Chapters = chapters;
|
||||
}
|
||||
|
||||
protected override FileSystemInfo GetXmlFile(ItemInfo info, IDirectoryService directoryService)
|
||||
{
|
||||
var path = GetMovieSavePath(info);
|
||||
|
||||
return directoryService.GetFile(path);
|
||||
}
|
||||
|
||||
public static string GetMovieSavePath(ItemInfo item)
|
||||
{
|
||||
if (Directory.Exists(item.Path))
|
||||
{
|
||||
var path = item.Path;
|
||||
|
||||
return Path.Combine(path, Path.GetFileNameWithoutExtension(path) + ".nfo");
|
||||
}
|
||||
|
||||
return Path.ChangeExtension(item.Path, ".nfo");
|
||||
}
|
||||
}
|
||||
}
|
44
MediaBrowser.XbmcMetadata/Providers/EpisodeNfoProvider.cs
Normal file
44
MediaBrowser.XbmcMetadata/Providers/EpisodeNfoProvider.cs
Normal file
|
@ -0,0 +1,44 @@
|
|||
using MediaBrowser.Common.Configuration;
|
||||
using MediaBrowser.Common.IO;
|
||||
using MediaBrowser.Controller.Entities.TV;
|
||||
using MediaBrowser.Controller.Providers;
|
||||
using MediaBrowser.Model.Entities;
|
||||
using MediaBrowser.Model.Logging;
|
||||
using MediaBrowser.XbmcMetadata.Parsers;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Threading;
|
||||
|
||||
namespace MediaBrowser.XbmcMetadata.Providers
|
||||
{
|
||||
public class EpisodeNfoProvider : BaseNfoProvider<Episode>
|
||||
{
|
||||
private readonly ILogger _logger;
|
||||
private readonly IConfigurationManager _config;
|
||||
|
||||
public EpisodeNfoProvider(IFileSystem fileSystem, ILogger logger, IConfigurationManager config)
|
||||
: base(fileSystem)
|
||||
{
|
||||
_logger = logger;
|
||||
_config = config;
|
||||
}
|
||||
|
||||
protected override void Fetch(LocalMetadataResult<Episode> result, string path, CancellationToken cancellationToken)
|
||||
{
|
||||
var images = new List<LocalImageInfo>();
|
||||
var chapters = new List<ChapterInfo>();
|
||||
|
||||
new EpisodeNfoParser(_logger, _config).Fetch(result.Item, images, chapters, path, cancellationToken);
|
||||
|
||||
result.Images = images;
|
||||
result.Chapters = chapters;
|
||||
}
|
||||
|
||||
protected override FileSystemInfo GetXmlFile(ItemInfo info, IDirectoryService directoryService)
|
||||
{
|
||||
var path = Path.ChangeExtension(info.Path, ".nfo");
|
||||
|
||||
return directoryService.GetFile(path);
|
||||
}
|
||||
}
|
||||
}
|
45
MediaBrowser.XbmcMetadata/Providers/MovieNfoProvider.cs
Normal file
45
MediaBrowser.XbmcMetadata/Providers/MovieNfoProvider.cs
Normal file
|
@ -0,0 +1,45 @@
|
|||
using MediaBrowser.Common.Configuration;
|
||||
using MediaBrowser.Common.IO;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Controller.Entities.Movies;
|
||||
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 class MusicVideoNfoProvider : BaseVideoNfoProvider<MusicVideo>
|
||||
{
|
||||
public MusicVideoNfoProvider(IFileSystem fileSystem, ILogger logger, IConfigurationManager config) : base(fileSystem, logger, config)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
public class AdultVideoNfoProvider : BaseVideoNfoProvider<AdultVideo>
|
||||
{
|
||||
public AdultVideoNfoProvider(IFileSystem fileSystem, ILogger logger, IConfigurationManager config) : base(fileSystem, logger, config)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
public class VideoNfoProvider : BaseVideoNfoProvider<Video>
|
||||
{
|
||||
public VideoNfoProvider(IFileSystem fileSystem, ILogger logger, IConfigurationManager config) : base(fileSystem, logger, config)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
public class TrailerNfoProvider : BaseVideoNfoProvider<Trailer>
|
||||
{
|
||||
public TrailerNfoProvider(IFileSystem fileSystem, ILogger logger, IConfigurationManager config)
|
||||
: base(fileSystem, logger, config)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
}
|
35
MediaBrowser.XbmcMetadata/Providers/SeasonNfoProvider.cs
Normal file
35
MediaBrowser.XbmcMetadata/Providers/SeasonNfoProvider.cs
Normal file
|
@ -0,0 +1,35 @@
|
|||
using MediaBrowser.Common.Configuration;
|
||||
using MediaBrowser.Common.IO;
|
||||
using MediaBrowser.Controller.Entities.TV;
|
||||
using MediaBrowser.Controller.Providers;
|
||||
using MediaBrowser.Model.Logging;
|
||||
using MediaBrowser.XbmcMetadata.Parsers;
|
||||
using System.IO;
|
||||
using System.Threading;
|
||||
|
||||
namespace MediaBrowser.XbmcMetadata.Providers
|
||||
{
|
||||
public class SeasonNfoProvider : BaseNfoProvider<Season>
|
||||
{
|
||||
private readonly ILogger _logger;
|
||||
private readonly IConfigurationManager _config;
|
||||
|
||||
public SeasonNfoProvider(IFileSystem fileSystem, ILogger logger, IConfigurationManager config)
|
||||
: base(fileSystem)
|
||||
{
|
||||
_logger = logger;
|
||||
_config = config;
|
||||
}
|
||||
|
||||
protected override void Fetch(LocalMetadataResult<Season> result, string path, CancellationToken cancellationToken)
|
||||
{
|
||||
new SeasonNfoParser(_logger, _config).Fetch(result.Item, path, cancellationToken);
|
||||
}
|
||||
|
||||
protected override FileSystemInfo GetXmlFile(ItemInfo info, IDirectoryService directoryService)
|
||||
{
|
||||
return directoryService.GetFile(Path.Combine(info.Path, "season.nfo"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
34
MediaBrowser.XbmcMetadata/Providers/SeriesNfoProvider.cs
Normal file
34
MediaBrowser.XbmcMetadata/Providers/SeriesNfoProvider.cs
Normal file
|
@ -0,0 +1,34 @@
|
|||
using MediaBrowser.Common.Configuration;
|
||||
using MediaBrowser.Common.IO;
|
||||
using MediaBrowser.Controller.Entities.TV;
|
||||
using MediaBrowser.Controller.Providers;
|
||||
using MediaBrowser.Model.Logging;
|
||||
using MediaBrowser.XbmcMetadata.Parsers;
|
||||
using System.IO;
|
||||
using System.Threading;
|
||||
|
||||
namespace MediaBrowser.XbmcMetadata.Providers
|
||||
{
|
||||
public class SeriesNfoProvider : BaseNfoProvider<Series>
|
||||
{
|
||||
private readonly ILogger _logger;
|
||||
private readonly IConfigurationManager _config;
|
||||
|
||||
public SeriesNfoProvider(IFileSystem fileSystem, ILogger logger, IConfigurationManager config)
|
||||
: base(fileSystem)
|
||||
{
|
||||
_logger = logger;
|
||||
_config = config;
|
||||
}
|
||||
|
||||
protected override void Fetch(LocalMetadataResult<Series> result, string path, CancellationToken cancellationToken)
|
||||
{
|
||||
new SeriesNfoParser(_logger, _config).Fetch(result.Item, path, cancellationToken);
|
||||
}
|
||||
|
||||
protected override FileSystemInfo GetXmlFile(ItemInfo info, IDirectoryService directoryService)
|
||||
{
|
||||
return directoryService.GetFile(Path.Combine(info.Path, "series.nfo"));
|
||||
}
|
||||
}
|
||||
}
|
143
MediaBrowser.XbmcMetadata/Savers/AlbumXmlSaver.cs
Normal file
143
MediaBrowser.XbmcMetadata/Savers/AlbumXmlSaver.cs
Normal file
|
@ -0,0 +1,143 @@
|
|||
using MediaBrowser.Common.IO;
|
||||
using MediaBrowser.Controller.Configuration;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Controller.Entities.Audio;
|
||||
using MediaBrowser.Controller.Library;
|
||||
using MediaBrowser.Model.Entities;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Security;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
|
||||
namespace MediaBrowser.XbmcMetadata.Savers
|
||||
{
|
||||
public class AlbumXmlSaver : IMetadataFileSaver
|
||||
{
|
||||
private readonly ILibraryManager _libraryManager;
|
||||
private readonly IUserManager _userManager;
|
||||
private readonly IUserDataManager _userDataRepo;
|
||||
|
||||
private readonly IFileSystem _fileSystem;
|
||||
private readonly IServerConfigurationManager _config;
|
||||
|
||||
public AlbumXmlSaver(ILibraryManager libraryManager, IUserManager userManager, IUserDataManager userDataRepo, IFileSystem fileSystem, IServerConfigurationManager config)
|
||||
{
|
||||
_libraryManager = libraryManager;
|
||||
_userManager = userManager;
|
||||
_userDataRepo = userDataRepo;
|
||||
_fileSystem = fileSystem;
|
||||
_config = config;
|
||||
}
|
||||
|
||||
public string Name
|
||||
{
|
||||
get
|
||||
{
|
||||
return "Xbmc Nfo";
|
||||
}
|
||||
}
|
||||
|
||||
public string GetSavePath(IHasMetadata item)
|
||||
{
|
||||
return Path.Combine(item.Path, "album.nfo");
|
||||
}
|
||||
|
||||
public void Save(IHasMetadata item, CancellationToken cancellationToken)
|
||||
{
|
||||
var album = (MusicAlbum)item;
|
||||
|
||||
var builder = new StringBuilder();
|
||||
|
||||
builder.Append("<album>");
|
||||
|
||||
XmlSaverHelpers.AddCommonNodes(album, builder, _libraryManager, _userManager, _userDataRepo, _fileSystem, _config);
|
||||
|
||||
var tracks = album.RecursiveChildren
|
||||
.OfType<Audio>()
|
||||
.ToList();
|
||||
|
||||
var artists = tracks
|
||||
.SelectMany(i =>
|
||||
{
|
||||
var list = new List<string>();
|
||||
|
||||
if (!string.IsNullOrEmpty(i.AlbumArtist))
|
||||
{
|
||||
list.Add(i.AlbumArtist);
|
||||
}
|
||||
list.AddRange(i.Artists);
|
||||
|
||||
return list;
|
||||
})
|
||||
.Distinct(StringComparer.OrdinalIgnoreCase);
|
||||
|
||||
foreach (var artist in artists)
|
||||
{
|
||||
builder.Append("<artist>" + SecurityElement.Escape(artist) + "</artist>");
|
||||
}
|
||||
|
||||
AddTracks(tracks, builder);
|
||||
|
||||
builder.Append("</album>");
|
||||
|
||||
var xmlFilePath = GetSavePath(item);
|
||||
|
||||
XmlSaverHelpers.Save(builder, xmlFilePath, new List<string>
|
||||
{
|
||||
"track",
|
||||
"artist"
|
||||
});
|
||||
}
|
||||
|
||||
public bool IsEnabledFor(IHasMetadata item, ItemUpdateType updateType)
|
||||
{
|
||||
var locationType = item.LocationType;
|
||||
if (locationType == LocationType.Remote || locationType == LocationType.Virtual)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// If new metadata has been downloaded or metadata was manually edited, proceed
|
||||
if ((updateType & ItemUpdateType.MetadataDownload) == ItemUpdateType.MetadataDownload
|
||||
|| (updateType & ItemUpdateType.MetadataEdit) == ItemUpdateType.MetadataEdit)
|
||||
{
|
||||
return item is MusicAlbum;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private static readonly CultureInfo UsCulture = new CultureInfo("en-US");
|
||||
|
||||
private void AddTracks(IEnumerable<Audio> tracks, StringBuilder builder)
|
||||
{
|
||||
foreach (var track in tracks.OrderBy(i => i.ParentIndexNumber ?? 0).ThenBy(i => i.IndexNumber ?? 0))
|
||||
{
|
||||
builder.Append("<track>");
|
||||
|
||||
if (track.IndexNumber.HasValue)
|
||||
{
|
||||
builder.Append("<position>" + SecurityElement.Escape(track.IndexNumber.Value.ToString(UsCulture)) + "</position>");
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(track.Name))
|
||||
{
|
||||
builder.Append("<title>" + SecurityElement.Escape(track.Name) + "</title>");
|
||||
}
|
||||
|
||||
if (track.RunTimeTicks.HasValue)
|
||||
{
|
||||
var time = TimeSpan.FromTicks(track.RunTimeTicks.Value).ToString(@"mm\:ss");
|
||||
|
||||
builder.Append("<duration>" + SecurityElement.Escape(time) + "</duration>");
|
||||
}
|
||||
|
||||
builder.Append("</track>");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
124
MediaBrowser.XbmcMetadata/Savers/ArtistXmlSaver.cs
Normal file
124
MediaBrowser.XbmcMetadata/Savers/ArtistXmlSaver.cs
Normal file
|
@ -0,0 +1,124 @@
|
|||
using MediaBrowser.Common.IO;
|
||||
using MediaBrowser.Controller.Configuration;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Controller.Entities.Audio;
|
||||
using MediaBrowser.Controller.Library;
|
||||
using MediaBrowser.Model.Entities;
|
||||
using MediaBrowser.XbmcMetadata.Configuration;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Security;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
|
||||
namespace MediaBrowser.XbmcMetadata.Savers
|
||||
{
|
||||
public class ArtistXmlSaver : IMetadataFileSaver
|
||||
{
|
||||
private readonly ILibraryManager _libraryManager;
|
||||
private readonly IUserManager _userManager;
|
||||
private readonly IUserDataManager _userDataRepo;
|
||||
|
||||
private readonly IFileSystem _fileSystem;
|
||||
private readonly IServerConfigurationManager _config;
|
||||
|
||||
private static readonly CultureInfo UsCulture = new CultureInfo("en-US");
|
||||
|
||||
public ArtistXmlSaver(ILibraryManager libraryManager, IUserManager userManager, IUserDataManager userDataRepo, IFileSystem fileSystem, IServerConfigurationManager config)
|
||||
{
|
||||
_libraryManager = libraryManager;
|
||||
_userManager = userManager;
|
||||
_userDataRepo = userDataRepo;
|
||||
_fileSystem = fileSystem;
|
||||
_config = config;
|
||||
}
|
||||
|
||||
public string GetSavePath(IHasMetadata item)
|
||||
{
|
||||
return Path.Combine(item.Path, "artist.nfo");
|
||||
}
|
||||
|
||||
public string Name
|
||||
{
|
||||
get
|
||||
{
|
||||
return "Xbmc Nfo";
|
||||
}
|
||||
}
|
||||
|
||||
public void Save(IHasMetadata item, CancellationToken cancellationToken)
|
||||
{
|
||||
var artist = (MusicArtist)item;
|
||||
|
||||
var builder = new StringBuilder();
|
||||
|
||||
builder.Append("<artist>");
|
||||
|
||||
XmlSaverHelpers.AddCommonNodes(artist, builder, _libraryManager, _userManager, _userDataRepo, _fileSystem, _config);
|
||||
|
||||
if (artist.EndDate.HasValue)
|
||||
{
|
||||
var formatString = _config.GetNfoConfiguration().ReleaseDateFormat;
|
||||
|
||||
builder.Append("<disbanded>" + SecurityElement.Escape(artist.EndDate.Value.ToString(formatString)) + "</disbanded>");
|
||||
}
|
||||
|
||||
var albums = artist
|
||||
.RecursiveChildren
|
||||
.OfType<MusicAlbum>()
|
||||
.ToList();
|
||||
|
||||
AddAlbums(albums, builder);
|
||||
|
||||
builder.Append("</artist>");
|
||||
|
||||
var xmlFilePath = GetSavePath(item);
|
||||
|
||||
XmlSaverHelpers.Save(builder, xmlFilePath, new List<string>
|
||||
{
|
||||
"album",
|
||||
"disbanded"
|
||||
});
|
||||
}
|
||||
|
||||
public bool IsEnabledFor(IHasMetadata item, ItemUpdateType updateType)
|
||||
{
|
||||
var locationType = item.LocationType;
|
||||
if (locationType == LocationType.Remote || locationType == LocationType.Virtual)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// If new metadata has been downloaded or metadata was manually edited, proceed
|
||||
if ((updateType & ItemUpdateType.MetadataDownload) == ItemUpdateType.MetadataDownload
|
||||
|| (updateType & ItemUpdateType.MetadataEdit) == ItemUpdateType.MetadataEdit)
|
||||
{
|
||||
return item is MusicArtist;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private void AddAlbums(IEnumerable<MusicAlbum> albums, StringBuilder builder)
|
||||
{
|
||||
foreach (var album in albums)
|
||||
{
|
||||
builder.Append("<album>");
|
||||
|
||||
if (!string.IsNullOrEmpty(album.Name))
|
||||
{
|
||||
builder.Append("<title>" + SecurityElement.Escape(album.Name) + "</title>");
|
||||
}
|
||||
|
||||
if (album.ProductionYear.HasValue)
|
||||
{
|
||||
builder.Append("<year>" + SecurityElement.Escape(album.ProductionYear.Value.ToString(UsCulture)) + "</year>");
|
||||
}
|
||||
|
||||
builder.Append("</album>");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
149
MediaBrowser.XbmcMetadata/Savers/EpisodeXmlSaver.cs
Normal file
149
MediaBrowser.XbmcMetadata/Savers/EpisodeXmlSaver.cs
Normal file
|
@ -0,0 +1,149 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Security;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using MediaBrowser.Common.IO;
|
||||
using MediaBrowser.Controller.Configuration;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Controller.Entities.TV;
|
||||
using MediaBrowser.Controller.Library;
|
||||
using MediaBrowser.Model.Entities;
|
||||
using MediaBrowser.XbmcMetadata.Configuration;
|
||||
|
||||
namespace MediaBrowser.XbmcMetadata.Savers
|
||||
{
|
||||
public class EpisodeXmlSaver : IMetadataFileSaver
|
||||
{
|
||||
private readonly ILibraryManager _libraryManager;
|
||||
private readonly IUserManager _userManager;
|
||||
private readonly IUserDataManager _userDataRepo;
|
||||
|
||||
private readonly CultureInfo _usCulture = new CultureInfo("en-US");
|
||||
|
||||
private readonly IFileSystem _fileSystem;
|
||||
private readonly IServerConfigurationManager _config;
|
||||
|
||||
public EpisodeXmlSaver(ILibraryManager libraryManager, IUserManager userManager, IUserDataManager userDataRepo, IFileSystem fileSystem, IServerConfigurationManager config)
|
||||
{
|
||||
_libraryManager = libraryManager;
|
||||
_userManager = userManager;
|
||||
_userDataRepo = userDataRepo;
|
||||
_fileSystem = fileSystem;
|
||||
_config = config;
|
||||
}
|
||||
|
||||
public string Name
|
||||
{
|
||||
get
|
||||
{
|
||||
return "Xbmc Nfo";
|
||||
}
|
||||
}
|
||||
|
||||
public string GetSavePath(IHasMetadata item)
|
||||
{
|
||||
return Path.ChangeExtension(item.Path, ".nfo");
|
||||
}
|
||||
|
||||
public void Save(IHasMetadata item, CancellationToken cancellationToken)
|
||||
{
|
||||
var episode = (Episode)item;
|
||||
|
||||
var builder = new StringBuilder();
|
||||
|
||||
builder.Append("<episodedetails>");
|
||||
|
||||
XmlSaverHelpers.AddCommonNodes(episode, builder, _libraryManager, _userManager, _userDataRepo, _fileSystem, _config);
|
||||
|
||||
if (episode.IndexNumber.HasValue)
|
||||
{
|
||||
builder.Append("<episode>" + episode.IndexNumber.Value.ToString(_usCulture) + "</episode>");
|
||||
}
|
||||
|
||||
if (episode.IndexNumberEnd.HasValue)
|
||||
{
|
||||
builder.Append("<episodenumberend>" + SecurityElement.Escape(episode.IndexNumberEnd.Value.ToString(_usCulture)) + "</episodenumberend>");
|
||||
}
|
||||
|
||||
if (episode.ParentIndexNumber.HasValue)
|
||||
{
|
||||
builder.Append("<season>" + episode.ParentIndexNumber.Value.ToString(_usCulture) + "</season>");
|
||||
}
|
||||
|
||||
if (episode.PremiereDate.HasValue)
|
||||
{
|
||||
var formatString = _config.GetNfoConfiguration().ReleaseDateFormat;
|
||||
|
||||
builder.Append("<aired>" + SecurityElement.Escape(episode.PremiereDate.Value.ToString(formatString)) + "</aired>");
|
||||
}
|
||||
|
||||
if (episode.AirsAfterSeasonNumber.HasValue)
|
||||
{
|
||||
builder.Append("<airsafter_season>" + SecurityElement.Escape(episode.AirsAfterSeasonNumber.Value.ToString(_usCulture)) + "</airsafter_season>");
|
||||
}
|
||||
if (episode.AirsBeforeEpisodeNumber.HasValue)
|
||||
{
|
||||
builder.Append("<airsbefore_episode>" + SecurityElement.Escape(episode.AirsBeforeEpisodeNumber.Value.ToString(_usCulture)) + "</airsbefore_episode>");
|
||||
}
|
||||
if (episode.AirsBeforeSeasonNumber.HasValue)
|
||||
{
|
||||
builder.Append("<airsbefore_season>" + SecurityElement.Escape(episode.AirsBeforeSeasonNumber.Value.ToString(_usCulture)) + "</airsbefore_season>");
|
||||
}
|
||||
|
||||
if (episode.DvdEpisodeNumber.HasValue)
|
||||
{
|
||||
builder.Append("<DVD_episodenumber>" + SecurityElement.Escape(episode.DvdEpisodeNumber.Value.ToString(_usCulture)) + "</DVD_episodenumber>");
|
||||
}
|
||||
|
||||
if (episode.DvdSeasonNumber.HasValue)
|
||||
{
|
||||
builder.Append("<DVD_season>" + SecurityElement.Escape(episode.DvdSeasonNumber.Value.ToString(_usCulture)) + "</DVD_season>");
|
||||
}
|
||||
|
||||
if (episode.AbsoluteEpisodeNumber.HasValue)
|
||||
{
|
||||
builder.Append("<absolute_number>" + SecurityElement.Escape(episode.AbsoluteEpisodeNumber.Value.ToString(_usCulture)) + "</absolute_number>");
|
||||
}
|
||||
|
||||
XmlSaverHelpers.AddMediaInfo((Episode)item, builder);
|
||||
|
||||
builder.Append("</episodedetails>");
|
||||
|
||||
var xmlFilePath = GetSavePath(item);
|
||||
|
||||
XmlSaverHelpers.Save(builder, xmlFilePath, new List<string>
|
||||
{
|
||||
"aired",
|
||||
"season",
|
||||
"episode",
|
||||
"episodenumberend",
|
||||
"airsafter_season",
|
||||
"airsbefore_episode",
|
||||
"airsbefore_season",
|
||||
"DVD_episodenumber",
|
||||
"DVD_season",
|
||||
"absolute_number"
|
||||
});
|
||||
}
|
||||
|
||||
public bool IsEnabledFor(IHasMetadata item, ItemUpdateType updateType)
|
||||
{
|
||||
var locationType = item.LocationType;
|
||||
if (locationType == LocationType.Remote || locationType == LocationType.Virtual)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// If new metadata has been downloaded or metadata was manually edited, proceed
|
||||
if ((updateType & ItemUpdateType.MetadataDownload) == ItemUpdateType.MetadataDownload
|
||||
|| (updateType & ItemUpdateType.MetadataEdit) == ItemUpdateType.MetadataEdit)
|
||||
{
|
||||
return item is Episode;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
143
MediaBrowser.XbmcMetadata/Savers/MovieXmlSaver.cs
Normal file
143
MediaBrowser.XbmcMetadata/Savers/MovieXmlSaver.cs
Normal file
|
@ -0,0 +1,143 @@
|
|||
using MediaBrowser.Common.IO;
|
||||
using MediaBrowser.Controller.Configuration;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Controller.Entities.Movies;
|
||||
using MediaBrowser.Controller.Entities.TV;
|
||||
using MediaBrowser.Controller.Library;
|
||||
using MediaBrowser.Model.Entities;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Security;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
|
||||
namespace MediaBrowser.XbmcMetadata.Savers
|
||||
{
|
||||
public class MovieXmlSaver : IMetadataFileSaver
|
||||
{
|
||||
private readonly ILibraryManager _libraryManager;
|
||||
private readonly IUserManager _userManager;
|
||||
private readonly IUserDataManager _userDataRepo;
|
||||
|
||||
private readonly IFileSystem _fileSystem;
|
||||
private readonly IServerConfigurationManager _config;
|
||||
|
||||
public MovieXmlSaver(ILibraryManager libraryManager, IUserManager userManager, IUserDataManager userDataRepo, IFileSystem fileSystem, IServerConfigurationManager config)
|
||||
{
|
||||
_libraryManager = libraryManager;
|
||||
_userManager = userManager;
|
||||
_userDataRepo = userDataRepo;
|
||||
_fileSystem = fileSystem;
|
||||
_config = config;
|
||||
}
|
||||
|
||||
public string Name
|
||||
{
|
||||
get
|
||||
{
|
||||
return "Xbmc Nfo";
|
||||
}
|
||||
}
|
||||
|
||||
public string GetSavePath(IHasMetadata item)
|
||||
{
|
||||
return GetMovieSavePath(item);
|
||||
}
|
||||
|
||||
public static string GetMovieSavePath(IHasMetadata item)
|
||||
{
|
||||
var video = (Video)item;
|
||||
|
||||
if (video.VideoType == VideoType.Dvd || video.VideoType == VideoType.BluRay || video.VideoType == VideoType.HdDvd)
|
||||
{
|
||||
var path = item.ContainingFolderPath;
|
||||
|
||||
return Path.Combine(path, Path.GetFileNameWithoutExtension(path) + ".nfo");
|
||||
}
|
||||
|
||||
return Path.ChangeExtension(item.Path, ".nfo");
|
||||
}
|
||||
|
||||
public void Save(IHasMetadata item, CancellationToken cancellationToken)
|
||||
{
|
||||
var video = (Video)item;
|
||||
|
||||
var builder = new StringBuilder();
|
||||
|
||||
var tag = item is MusicVideo ? "musicvideo" : "movie";
|
||||
|
||||
builder.Append("<" + tag + ">");
|
||||
|
||||
XmlSaverHelpers.AddCommonNodes(video, builder, _libraryManager, _userManager, _userDataRepo, _fileSystem, _config);
|
||||
|
||||
var imdb = item.GetProviderId(MetadataProviders.Imdb);
|
||||
|
||||
if (!string.IsNullOrEmpty(imdb))
|
||||
{
|
||||
builder.Append("<id>" + SecurityElement.Escape(imdb) + "</id>");
|
||||
}
|
||||
|
||||
var musicVideo = item as MusicVideo;
|
||||
|
||||
if (musicVideo != null)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(musicVideo.Artist))
|
||||
{
|
||||
builder.Append("<artist>" + SecurityElement.Escape(musicVideo.Artist) + "</artist>");
|
||||
}
|
||||
if (!string.IsNullOrEmpty(musicVideo.Album))
|
||||
{
|
||||
builder.Append("<album>" + SecurityElement.Escape(musicVideo.Album) + "</album>");
|
||||
}
|
||||
}
|
||||
|
||||
var movie = item as Movie;
|
||||
|
||||
if (movie != null)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(movie.TmdbCollectionName))
|
||||
{
|
||||
builder.Append("<set>" + SecurityElement.Escape(movie.TmdbCollectionName) + "</set>");
|
||||
}
|
||||
}
|
||||
|
||||
XmlSaverHelpers.AddMediaInfo((Video)item, builder);
|
||||
|
||||
builder.Append("</" + tag + ">");
|
||||
|
||||
var xmlFilePath = GetSavePath(item);
|
||||
|
||||
XmlSaverHelpers.Save(builder, xmlFilePath, new List<string>
|
||||
{
|
||||
"album",
|
||||
"artist",
|
||||
"set",
|
||||
"id"
|
||||
});
|
||||
}
|
||||
|
||||
public bool IsEnabledFor(IHasMetadata item, ItemUpdateType updateType)
|
||||
{
|
||||
var locationType = item.LocationType;
|
||||
if (locationType == LocationType.Remote || locationType == LocationType.Virtual)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// If new metadata has been downloaded or metadata was manually edited, proceed
|
||||
if ((updateType & ItemUpdateType.MetadataDownload) == ItemUpdateType.MetadataDownload
|
||||
|| (updateType & ItemUpdateType.MetadataEdit) == ItemUpdateType.MetadataEdit)
|
||||
{
|
||||
var video = item as Video;
|
||||
|
||||
// Check parent for null to avoid running this against things like video backdrops
|
||||
if (video != null && !(item is Episode) && !video.IsOwnedItem)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
90
MediaBrowser.XbmcMetadata/Savers/SeasonXmlSaver.cs
Normal file
90
MediaBrowser.XbmcMetadata/Savers/SeasonXmlSaver.cs
Normal file
|
@ -0,0 +1,90 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Security;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using MediaBrowser.Common.IO;
|
||||
using MediaBrowser.Controller.Configuration;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Controller.Entities.TV;
|
||||
using MediaBrowser.Controller.Library;
|
||||
using MediaBrowser.Model.Entities;
|
||||
|
||||
namespace MediaBrowser.XbmcMetadata.Savers
|
||||
{
|
||||
public class SeasonXmlSaver : IMetadataFileSaver
|
||||
{
|
||||
private readonly ILibraryManager _libraryManager;
|
||||
private readonly IUserManager _userManager;
|
||||
private readonly IUserDataManager _userDataRepo;
|
||||
|
||||
private readonly IFileSystem _fileSystem;
|
||||
private readonly IServerConfigurationManager _config;
|
||||
|
||||
public SeasonXmlSaver(ILibraryManager libraryManager, IUserManager userManager, IUserDataManager userDataRepo, IFileSystem fileSystem, IServerConfigurationManager config)
|
||||
{
|
||||
_libraryManager = libraryManager;
|
||||
_userManager = userManager;
|
||||
_userDataRepo = userDataRepo;
|
||||
_fileSystem = fileSystem;
|
||||
_config = config;
|
||||
}
|
||||
|
||||
public string Name
|
||||
{
|
||||
get
|
||||
{
|
||||
return "Xbmc Nfo";
|
||||
}
|
||||
}
|
||||
|
||||
public string GetSavePath(IHasMetadata item)
|
||||
{
|
||||
return Path.Combine(item.Path, "season.nfo");
|
||||
}
|
||||
|
||||
public void Save(IHasMetadata item, CancellationToken cancellationToken)
|
||||
{
|
||||
var builder = new StringBuilder();
|
||||
|
||||
builder.Append("<season>");
|
||||
|
||||
var season = (Season)item;
|
||||
|
||||
if (season.IndexNumber.HasValue)
|
||||
{
|
||||
builder.Append("<seasonnumber>" + SecurityElement.Escape(season.IndexNumber.Value.ToString(CultureInfo.InvariantCulture)) + "</seasonnumber>");
|
||||
}
|
||||
|
||||
XmlSaverHelpers.AddCommonNodes((Season)item, builder, _libraryManager, _userManager, _userDataRepo, _fileSystem, _config);
|
||||
|
||||
builder.Append("</season>");
|
||||
|
||||
var xmlFilePath = GetSavePath(item);
|
||||
|
||||
XmlSaverHelpers.Save(builder, xmlFilePath, new List<string>
|
||||
{
|
||||
"seasonnumber"
|
||||
});
|
||||
}
|
||||
|
||||
public bool IsEnabledFor(IHasMetadata item, ItemUpdateType updateType)
|
||||
{
|
||||
var locationType = item.LocationType;
|
||||
if (locationType == LocationType.Remote || locationType == LocationType.Virtual)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// If new metadata has been downloaded or metadata was manually edited, proceed
|
||||
if ((updateType & ItemUpdateType.MetadataDownload) == ItemUpdateType.MetadataDownload
|
||||
|| (updateType & ItemUpdateType.MetadataEdit) == ItemUpdateType.MetadataEdit)
|
||||
{
|
||||
return item is Season;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
130
MediaBrowser.XbmcMetadata/Savers/SeriesXmlSaver.cs
Normal file
130
MediaBrowser.XbmcMetadata/Savers/SeriesXmlSaver.cs
Normal file
|
@ -0,0 +1,130 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Security;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using MediaBrowser.Common.IO;
|
||||
using MediaBrowser.Controller.Configuration;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Controller.Entities.TV;
|
||||
using MediaBrowser.Controller.Library;
|
||||
using MediaBrowser.Model.Entities;
|
||||
|
||||
namespace MediaBrowser.XbmcMetadata.Savers
|
||||
{
|
||||
public class SeriesXmlSaver : IMetadataFileSaver
|
||||
{
|
||||
private readonly ILibraryManager _libraryManager;
|
||||
private readonly IUserManager _userManager;
|
||||
private readonly IUserDataManager _userDataRepo;
|
||||
|
||||
private readonly IFileSystem _fileSystem;
|
||||
private readonly IServerConfigurationManager _config;
|
||||
|
||||
public SeriesXmlSaver(IServerConfigurationManager config, ILibraryManager libraryManager, IUserManager userManager, IUserDataManager userDataRepo, IFileSystem fileSystem)
|
||||
{
|
||||
_config = config;
|
||||
_libraryManager = libraryManager;
|
||||
_userManager = userManager;
|
||||
_userDataRepo = userDataRepo;
|
||||
_fileSystem = fileSystem;
|
||||
}
|
||||
|
||||
public string Name
|
||||
{
|
||||
get
|
||||
{
|
||||
return "Xbmc Nfo";
|
||||
}
|
||||
}
|
||||
|
||||
public string GetSavePath(IHasMetadata item)
|
||||
{
|
||||
return Path.Combine(item.Path, "tvshow.nfo");
|
||||
}
|
||||
|
||||
public void Save(IHasMetadata item, CancellationToken cancellationToken)
|
||||
{
|
||||
var series = (Series)item;
|
||||
|
||||
var builder = new StringBuilder();
|
||||
|
||||
builder.Append("<tvshow>");
|
||||
|
||||
XmlSaverHelpers.AddCommonNodes(series, builder, _libraryManager, _userManager, _userDataRepo, _fileSystem, _config);
|
||||
|
||||
var tvdb = item.GetProviderId(MetadataProviders.Tvdb);
|
||||
|
||||
if (!string.IsNullOrEmpty(tvdb))
|
||||
{
|
||||
builder.Append("<id>" + SecurityElement.Escape(tvdb) + "</id>");
|
||||
|
||||
builder.AppendFormat("<episodeguide><url cache=\"{0}.xml\">http://www.thetvdb.com/api/1D62F2F90030C444/series/{0}/all/{1}.zip</url></episodeguide>",
|
||||
tvdb,
|
||||
string.IsNullOrEmpty(_config.Configuration.PreferredMetadataLanguage) ? "en" : _config.Configuration.PreferredMetadataLanguage);
|
||||
}
|
||||
|
||||
builder.Append("<season>-1</season>");
|
||||
builder.Append("<episode>-1</episode>");
|
||||
|
||||
if (series.Status.HasValue)
|
||||
{
|
||||
builder.Append("<status>" + SecurityElement.Escape(series.Status.Value.ToString()) + "</status>");
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(series.AirTime))
|
||||
{
|
||||
builder.Append("<airs_time>" + SecurityElement.Escape(series.AirTime) + "</airs_time>");
|
||||
}
|
||||
|
||||
if (series.AirDays.Count == 7)
|
||||
{
|
||||
builder.Append("<airs_dayofweek>" + SecurityElement.Escape("Daily") + "</airs_dayofweek>");
|
||||
}
|
||||
else if (series.AirDays.Count > 0)
|
||||
{
|
||||
builder.Append("<airs_dayofweek>" + SecurityElement.Escape(series.AirDays[0].ToString()) + "</airs_dayofweek>");
|
||||
}
|
||||
|
||||
if (series.AnimeSeriesIndex.HasValue)
|
||||
{
|
||||
builder.Append("<animeseriesindex>" + SecurityElement.Escape(series.AnimeSeriesIndex.Value.ToString(CultureInfo.InvariantCulture)) + "</animeseriesindex>");
|
||||
}
|
||||
|
||||
builder.Append("</tvshow>");
|
||||
|
||||
var xmlFilePath = GetSavePath(item);
|
||||
|
||||
XmlSaverHelpers.Save(builder, xmlFilePath, new List<string>
|
||||
{
|
||||
"id",
|
||||
"episodeguide",
|
||||
"season",
|
||||
"episode",
|
||||
"status",
|
||||
"airs_time",
|
||||
"airs_dayofweek",
|
||||
"animeseriesindex"
|
||||
});
|
||||
}
|
||||
|
||||
public bool IsEnabledFor(IHasMetadata item, ItemUpdateType updateType)
|
||||
{
|
||||
var locationType = item.LocationType;
|
||||
if (locationType == LocationType.Remote || locationType == LocationType.Virtual)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// If new metadata has been downloaded or metadata was manually edited, proceed
|
||||
if ((updateType & ItemUpdateType.MetadataDownload) == ItemUpdateType.MetadataDownload
|
||||
|| (updateType & ItemUpdateType.MetadataEdit) == ItemUpdateType.MetadataEdit)
|
||||
{
|
||||
return item is Series;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
906
MediaBrowser.XbmcMetadata/Savers/XmlSaverHelpers.cs
Normal file
906
MediaBrowser.XbmcMetadata/Savers/XmlSaverHelpers.cs
Normal file
|
@ -0,0 +1,906 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Security;
|
||||
using System.Text;
|
||||
using System.Xml;
|
||||
using MediaBrowser.Common.Extensions;
|
||||
using MediaBrowser.Common.IO;
|
||||
using MediaBrowser.Controller.Configuration;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Controller.Entities.Audio;
|
||||
using MediaBrowser.Controller.Entities.Movies;
|
||||
using MediaBrowser.Controller.Entities.TV;
|
||||
using MediaBrowser.Controller.Library;
|
||||
using MediaBrowser.Controller.Persistence;
|
||||
using MediaBrowser.Model.Configuration;
|
||||
using MediaBrowser.Model.Entities;
|
||||
using MediaBrowser.XbmcMetadata.Configuration;
|
||||
|
||||
namespace MediaBrowser.XbmcMetadata.Savers
|
||||
{
|
||||
public static class XmlSaverHelpers
|
||||
{
|
||||
private static readonly CultureInfo UsCulture = new CultureInfo("en-US");
|
||||
|
||||
private static readonly Dictionary<string, string> CommonTags = new[] {
|
||||
|
||||
"plot",
|
||||
"customrating",
|
||||
"lockdata",
|
||||
"type",
|
||||
"dateadded",
|
||||
"title",
|
||||
"rating",
|
||||
"year",
|
||||
"sorttitle",
|
||||
"mpaa",
|
||||
"mpaadescription",
|
||||
"aspectratio",
|
||||
"website",
|
||||
"collectionnumber",
|
||||
"tmdbid",
|
||||
"rottentomatoesid",
|
||||
"language",
|
||||
"tvcomid",
|
||||
"budget",
|
||||
"revenue",
|
||||
"tagline",
|
||||
"studio",
|
||||
"genre",
|
||||
"tag",
|
||||
"runtime",
|
||||
"actor",
|
||||
"criticratingsummary",
|
||||
"criticrating",
|
||||
"fileinfo",
|
||||
"director",
|
||||
"writer",
|
||||
"trailer",
|
||||
"premiered",
|
||||
"releasedate",
|
||||
"outline",
|
||||
"id",
|
||||
"votes",
|
||||
"credits",
|
||||
"originaltitle",
|
||||
"watched",
|
||||
"playcount",
|
||||
"lastplayed",
|
||||
"art",
|
||||
"resume",
|
||||
"biography",
|
||||
"formed",
|
||||
"review",
|
||||
"style",
|
||||
"imdbid",
|
||||
"imdb_id",
|
||||
"plotkeyword",
|
||||
"country",
|
||||
"audiodbalbumid",
|
||||
"audiodbartistid",
|
||||
"awardsummary",
|
||||
"enddate",
|
||||
"lockedfields",
|
||||
"metascore",
|
||||
"zap2itid",
|
||||
"tvrageid",
|
||||
"gamesdbid",
|
||||
|
||||
"musicbrainzartistid",
|
||||
"musicbrainzalbumartistid",
|
||||
"musicbrainzalbumid",
|
||||
"musicbrainzreleasegroupid",
|
||||
"tvdbid",
|
||||
"collectionitem"
|
||||
|
||||
}.ToDictionary(i => i, StringComparer.OrdinalIgnoreCase);
|
||||
|
||||
/// <summary>
|
||||
/// Saves the specified XML.
|
||||
/// </summary>
|
||||
/// <param name="xml">The XML.</param>
|
||||
/// <param name="path">The path.</param>
|
||||
/// <param name="xmlTagsUsed">The XML tags used.</param>
|
||||
public static void Save(StringBuilder xml, string path, List<string> xmlTagsUsed)
|
||||
{
|
||||
if (File.Exists(path))
|
||||
{
|
||||
var tags = xmlTagsUsed.ToList();
|
||||
|
||||
var position = xml.ToString().LastIndexOf("</", StringComparison.OrdinalIgnoreCase);
|
||||
xml.Insert(position, GetCustomTags(path, tags));
|
||||
}
|
||||
|
||||
var xmlDocument = new XmlDocument();
|
||||
xmlDocument.LoadXml(xml.ToString());
|
||||
|
||||
//Add the new node to the document.
|
||||
xmlDocument.InsertBefore(xmlDocument.CreateXmlDeclaration("1.0", "UTF-8", "yes"), xmlDocument.DocumentElement);
|
||||
|
||||
Directory.CreateDirectory(Path.GetDirectoryName(path));
|
||||
|
||||
var wasHidden = false;
|
||||
|
||||
var file = new FileInfo(path);
|
||||
|
||||
// This will fail if the file is hidden
|
||||
if (file.Exists)
|
||||
{
|
||||
if ((file.Attributes & FileAttributes.Hidden) == FileAttributes.Hidden)
|
||||
{
|
||||
file.Attributes &= ~FileAttributes.Hidden;
|
||||
|
||||
wasHidden = true;
|
||||
}
|
||||
}
|
||||
|
||||
using (var filestream = new FileStream(path, FileMode.Create, FileAccess.Write, FileShare.Read))
|
||||
{
|
||||
using (var streamWriter = new StreamWriter(filestream, Encoding.UTF8))
|
||||
{
|
||||
xmlDocument.Save(streamWriter);
|
||||
}
|
||||
}
|
||||
|
||||
if (wasHidden)
|
||||
{
|
||||
file.Refresh();
|
||||
|
||||
// Add back the attribute
|
||||
file.Attributes |= FileAttributes.Hidden;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the custom tags.
|
||||
/// </summary>
|
||||
/// <param name="path">The path.</param>
|
||||
/// <param name="xmlTagsUsed">The XML tags used.</param>
|
||||
/// <returns>System.String.</returns>
|
||||
private static string GetCustomTags(string path, List<string> xmlTagsUsed)
|
||||
{
|
||||
var settings = new XmlReaderSettings
|
||||
{
|
||||
CheckCharacters = false,
|
||||
IgnoreProcessingInstructions = true,
|
||||
IgnoreComments = true,
|
||||
ValidationType = ValidationType.None
|
||||
};
|
||||
|
||||
var builder = new StringBuilder();
|
||||
|
||||
using (var streamReader = new StreamReader(path, Encoding.UTF8))
|
||||
{
|
||||
// Use XmlReader for best performance
|
||||
using (var reader = XmlReader.Create(streamReader, settings))
|
||||
{
|
||||
reader.MoveToContent();
|
||||
|
||||
// Loop through each element
|
||||
while (reader.Read())
|
||||
{
|
||||
if (reader.NodeType == XmlNodeType.Element)
|
||||
{
|
||||
var name = reader.Name;
|
||||
|
||||
if (!CommonTags.ContainsKey(name) && !xmlTagsUsed.Contains(name, StringComparer.OrdinalIgnoreCase))
|
||||
{
|
||||
builder.AppendLine(reader.ReadOuterXml());
|
||||
}
|
||||
else
|
||||
{
|
||||
reader.Skip();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return builder.ToString();
|
||||
}
|
||||
|
||||
public static void AddMediaInfo<T>(T item, StringBuilder builder)
|
||||
where T : BaseItem, IHasMediaSources
|
||||
{
|
||||
builder.Append("<fileinfo>");
|
||||
builder.Append("<streamdetails>");
|
||||
|
||||
foreach (var stream in item.GetMediaSources(false).First().MediaStreams)
|
||||
{
|
||||
builder.Append("<" + stream.Type.ToString().ToLower() + ">");
|
||||
|
||||
if (!string.IsNullOrEmpty(stream.Codec))
|
||||
{
|
||||
builder.Append("<codec>" + SecurityElement.Escape(stream.Codec) + "</codec>");
|
||||
builder.Append("<micodec>" + SecurityElement.Escape(stream.Codec) + "</micodec>");
|
||||
}
|
||||
|
||||
if (stream.BitRate.HasValue)
|
||||
{
|
||||
builder.Append("<bitrate>" + stream.BitRate.Value.ToString(UsCulture) + "</bitrate>");
|
||||
}
|
||||
|
||||
if (stream.Width.HasValue)
|
||||
{
|
||||
builder.Append("<width>" + stream.Width.Value.ToString(UsCulture) + "</width>");
|
||||
}
|
||||
|
||||
if (stream.Height.HasValue)
|
||||
{
|
||||
builder.Append("<height>" + stream.Height.Value.ToString(UsCulture) + "</height>");
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(stream.AspectRatio))
|
||||
{
|
||||
builder.Append("<aspect>" + SecurityElement.Escape(stream.AspectRatio) + "</aspect>");
|
||||
builder.Append("<aspectratio>" + SecurityElement.Escape(stream.AspectRatio) + "</aspectratio>");
|
||||
}
|
||||
|
||||
var framerate = stream.AverageFrameRate ?? stream.RealFrameRate;
|
||||
|
||||
if (framerate.HasValue)
|
||||
{
|
||||
builder.Append("<framerate>" + framerate.Value.ToString(UsCulture) + "</framerate>");
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(stream.Language))
|
||||
{
|
||||
builder.Append("<language>" + SecurityElement.Escape(stream.Language) + "</language>");
|
||||
}
|
||||
|
||||
var scanType = stream.IsInterlaced ? "interlaced" : "progressive";
|
||||
if (!string.IsNullOrEmpty(scanType))
|
||||
{
|
||||
builder.Append("<scantype>" + SecurityElement.Escape(scanType) + "</scantype>");
|
||||
}
|
||||
|
||||
if (stream.Channels.HasValue)
|
||||
{
|
||||
builder.Append("<channels>" + stream.Channels.Value.ToString(UsCulture) + "</channels>");
|
||||
}
|
||||
|
||||
if (stream.SampleRate.HasValue)
|
||||
{
|
||||
builder.Append("<samplingrate>" + stream.SampleRate.Value.ToString(UsCulture) + "</samplingrate>");
|
||||
}
|
||||
|
||||
builder.Append("<default>" + SecurityElement.Escape(stream.IsDefault.ToString()) + "</default>");
|
||||
builder.Append("<forced>" + SecurityElement.Escape(stream.IsForced.ToString()) + "</forced>");
|
||||
|
||||
if (stream.Type == MediaStreamType.Video)
|
||||
{
|
||||
if (item.RunTimeTicks.HasValue)
|
||||
{
|
||||
var timespan = TimeSpan.FromTicks(item.RunTimeTicks.Value);
|
||||
|
||||
builder.Append("<duration>" + Convert.ToInt32(timespan.TotalMinutes).ToString(UsCulture) + "</duration>");
|
||||
builder.Append("<durationinseconds>" + Convert.ToInt32(timespan.TotalSeconds).ToString(UsCulture) + "</durationinseconds>");
|
||||
}
|
||||
|
||||
var video = item as Video;
|
||||
|
||||
if (video != null)
|
||||
{
|
||||
//AddChapters(video, builder, itemRepository);
|
||||
|
||||
if (video.Video3DFormat.HasValue)
|
||||
{
|
||||
switch (video.Video3DFormat.Value)
|
||||
{
|
||||
case Video3DFormat.FullSideBySide:
|
||||
builder.Append("<format3d>FSBS</format3d>");
|
||||
break;
|
||||
case Video3DFormat.FullTopAndBottom:
|
||||
builder.Append("<format3d>FTAB</format3d>");
|
||||
break;
|
||||
case Video3DFormat.HalfSideBySide:
|
||||
builder.Append("<format3d>HSBS</format3d>");
|
||||
break;
|
||||
case Video3DFormat.HalfTopAndBottom:
|
||||
builder.Append("<format3d>HTAB</format3d>");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
builder.Append("</" + stream.Type.ToString().ToLower() + ">");
|
||||
}
|
||||
|
||||
builder.Append("</streamdetails>");
|
||||
builder.Append("</fileinfo>");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds the common nodes.
|
||||
/// </summary>
|
||||
/// <returns>Task.</returns>
|
||||
public static void AddCommonNodes(BaseItem item, StringBuilder builder, ILibraryManager libraryManager, IUserManager userManager, IUserDataManager userDataRepo, IFileSystem fileSystem, IServerConfigurationManager config)
|
||||
{
|
||||
var overview = (item.Overview ?? string.Empty)
|
||||
.StripHtml()
|
||||
.Replace(""", "'");
|
||||
|
||||
var options = config.GetNfoConfiguration();
|
||||
|
||||
if (item is MusicArtist)
|
||||
{
|
||||
builder.Append("<biography><![CDATA[" + overview + "]]></biography>");
|
||||
}
|
||||
else if (item is MusicAlbum)
|
||||
{
|
||||
builder.Append("<review><![CDATA[" + overview + "]]></review>");
|
||||
}
|
||||
else
|
||||
{
|
||||
builder.Append("<plot><![CDATA[" + overview + "]]></plot>");
|
||||
}
|
||||
|
||||
var hasShortOverview = item as IHasShortOverview;
|
||||
if (hasShortOverview != null)
|
||||
{
|
||||
var outline = (hasShortOverview.ShortOverview ?? string.Empty)
|
||||
.StripHtml()
|
||||
.Replace(""", "'");
|
||||
|
||||
builder.Append("<outline><![CDATA[" + outline + "]]></outline>");
|
||||
}
|
||||
else
|
||||
{
|
||||
builder.Append("<outline><![CDATA[" + overview + "]]></outline>");
|
||||
}
|
||||
|
||||
builder.Append("<customrating>" + SecurityElement.Escape(item.CustomRating ?? string.Empty) + "</customrating>");
|
||||
builder.Append("<lockdata>" + item.IsLocked.ToString().ToLower() + "</lockdata>");
|
||||
|
||||
if (item.LockedFields.Count > 0)
|
||||
{
|
||||
builder.Append("<lockedfields>" + string.Join("|", item.LockedFields.Select(i => i.ToString()).ToArray()) + "</lockedfields>");
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(item.DisplayMediaType))
|
||||
{
|
||||
builder.Append("<type>" + SecurityElement.Escape(item.DisplayMediaType) + "</type>");
|
||||
}
|
||||
|
||||
builder.Append("<dateadded>" + SecurityElement.Escape(item.DateCreated.ToString("yyyy-MM-dd HH:mm:ss")) + "</dateadded>");
|
||||
|
||||
builder.Append("<title>" + SecurityElement.Escape(item.Name ?? string.Empty) + "</title>");
|
||||
builder.Append("<originaltitle>" + SecurityElement.Escape(item.Name ?? string.Empty) + "</originaltitle>");
|
||||
|
||||
var directors = item.People
|
||||
.Where(i => IsPersonType(i, PersonType.Director))
|
||||
.Select(i => i.Name)
|
||||
.ToList();
|
||||
|
||||
foreach (var person in directors)
|
||||
{
|
||||
builder.Append("<director>" + SecurityElement.Escape(person) + "</director>");
|
||||
}
|
||||
|
||||
var writers = item.People
|
||||
.Where(i => IsPersonType(i, PersonType.Director))
|
||||
.Select(i => i.Name)
|
||||
.ToList();
|
||||
|
||||
foreach (var person in writers)
|
||||
{
|
||||
builder.Append("<writer>" + SecurityElement.Escape(person) + "</writer>");
|
||||
}
|
||||
|
||||
var credits = writers.Distinct(StringComparer.OrdinalIgnoreCase).ToList();
|
||||
|
||||
if (credits.Count > 0)
|
||||
{
|
||||
builder.Append("<credits>" + SecurityElement.Escape(string.Join(" / ", credits.ToArray())) + "</credits>");
|
||||
}
|
||||
|
||||
var hasTrailer = item as IHasTrailers;
|
||||
if (hasTrailer != null)
|
||||
{
|
||||
foreach (var trailer in hasTrailer.RemoteTrailers)
|
||||
{
|
||||
builder.Append("<trailer>" + SecurityElement.Escape(GetOutputTrailerUrl(trailer.Url)) + "</trailer>");
|
||||
}
|
||||
}
|
||||
|
||||
if (item.CommunityRating.HasValue)
|
||||
{
|
||||
builder.Append("<rating>" + SecurityElement.Escape(item.CommunityRating.Value.ToString(UsCulture)) + "</rating>");
|
||||
}
|
||||
|
||||
if (item.ProductionYear.HasValue)
|
||||
{
|
||||
builder.Append("<year>" + SecurityElement.Escape(item.ProductionYear.Value.ToString(UsCulture)) + "</year>");
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(item.ForcedSortName))
|
||||
{
|
||||
builder.Append("<sorttitle>" + SecurityElement.Escape(item.ForcedSortName) + "</sorttitle>");
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(item.OfficialRating))
|
||||
{
|
||||
builder.Append("<mpaa>" + SecurityElement.Escape(item.OfficialRating) + "</mpaa>");
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(item.OfficialRatingDescription))
|
||||
{
|
||||
builder.Append("<mpaadescription>" + SecurityElement.Escape(item.OfficialRatingDescription) + "</mpaadescription>");
|
||||
}
|
||||
|
||||
var hasAspectRatio = item as IHasAspectRatio;
|
||||
if (hasAspectRatio != null)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(hasAspectRatio.AspectRatio))
|
||||
{
|
||||
builder.Append("<aspectratio>" + SecurityElement.Escape(hasAspectRatio.AspectRatio) + "</aspectratio>");
|
||||
}
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(item.HomePageUrl))
|
||||
{
|
||||
builder.Append("<website>" + SecurityElement.Escape(item.HomePageUrl) + "</website>");
|
||||
}
|
||||
|
||||
var rt = item.GetProviderId(MetadataProviders.RottenTomatoes);
|
||||
|
||||
if (!string.IsNullOrEmpty(rt))
|
||||
{
|
||||
builder.Append("<rottentomatoesid>" + SecurityElement.Escape(rt) + "</rottentomatoesid>");
|
||||
}
|
||||
|
||||
var tmdbCollection = item.GetProviderId(MetadataProviders.TmdbCollection);
|
||||
|
||||
if (!string.IsNullOrEmpty(tmdbCollection))
|
||||
{
|
||||
builder.Append("<collectionnumber>" + SecurityElement.Escape(tmdbCollection) + "</collectionnumber>");
|
||||
}
|
||||
|
||||
var imdb = item.GetProviderId(MetadataProviders.Imdb);
|
||||
if (!string.IsNullOrEmpty(imdb))
|
||||
{
|
||||
if (item is Series)
|
||||
{
|
||||
builder.Append("<imdb_id>" + SecurityElement.Escape(imdb) + "</imdb_id>");
|
||||
}
|
||||
else
|
||||
{
|
||||
builder.Append("<imdbid>" + SecurityElement.Escape(imdb) + "</imdbid>");
|
||||
}
|
||||
}
|
||||
|
||||
// Series xml saver already saves this
|
||||
if (!(item is Series))
|
||||
{
|
||||
var tvdb = item.GetProviderId(MetadataProviders.Tvdb);
|
||||
if (!string.IsNullOrEmpty(tvdb))
|
||||
{
|
||||
builder.Append("<tvdbid>" + SecurityElement.Escape(tvdb) + "</tvdbid>");
|
||||
}
|
||||
}
|
||||
|
||||
var tmdb = item.GetProviderId(MetadataProviders.Tmdb);
|
||||
if (!string.IsNullOrEmpty(tmdb))
|
||||
{
|
||||
builder.Append("<tmdbid>" + SecurityElement.Escape(tmdb) + "</tmdbid>");
|
||||
}
|
||||
|
||||
var tvcom = item.GetProviderId(MetadataProviders.Tvcom);
|
||||
if (!string.IsNullOrEmpty(tvcom))
|
||||
{
|
||||
builder.Append("<tvcomid>" + SecurityElement.Escape(tvcom) + "</tvcomid>");
|
||||
}
|
||||
|
||||
var hasLanguage = item as IHasPreferredMetadataLanguage;
|
||||
if (hasLanguage != null)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(hasLanguage.PreferredMetadataLanguage))
|
||||
{
|
||||
builder.Append("<language>" + SecurityElement.Escape(hasLanguage.PreferredMetadataLanguage) + "</language>");
|
||||
}
|
||||
}
|
||||
|
||||
if (item.PremiereDate.HasValue && !(item is Episode))
|
||||
{
|
||||
var formatString = options.ReleaseDateFormat;
|
||||
|
||||
if (item is MusicArtist)
|
||||
{
|
||||
builder.Append("<formed>" + SecurityElement.Escape(item.PremiereDate.Value.ToString(formatString)) + "</formed>");
|
||||
}
|
||||
else
|
||||
{
|
||||
builder.Append("<premiered>" + SecurityElement.Escape(item.PremiereDate.Value.ToString(formatString)) + "</premiered>");
|
||||
builder.Append("<releasedate>" + SecurityElement.Escape(item.PremiereDate.Value.ToString(formatString)) + "</releasedate>");
|
||||
}
|
||||
}
|
||||
|
||||
if (item.EndDate.HasValue)
|
||||
{
|
||||
if (!(item is Episode))
|
||||
{
|
||||
var formatString = options.ReleaseDateFormat;
|
||||
|
||||
builder.Append("<enddate>" + SecurityElement.Escape(item.EndDate.Value.ToString(formatString)) + "</enddate>");
|
||||
}
|
||||
}
|
||||
|
||||
var hasCriticRating = item as IHasCriticRating;
|
||||
|
||||
if (hasCriticRating != null)
|
||||
{
|
||||
if (hasCriticRating.CriticRating.HasValue)
|
||||
{
|
||||
builder.Append("<criticrating>" + SecurityElement.Escape(hasCriticRating.CriticRating.Value.ToString(UsCulture)) + "</criticrating>");
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(hasCriticRating.CriticRatingSummary))
|
||||
{
|
||||
builder.Append("<criticratingsummary><![CDATA[" + hasCriticRating.CriticRatingSummary + "]]></criticratingsummary>");
|
||||
}
|
||||
}
|
||||
|
||||
var hasDisplayOrder = item as IHasDisplayOrder;
|
||||
|
||||
if (hasDisplayOrder != null)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(hasDisplayOrder.DisplayOrder))
|
||||
{
|
||||
builder.Append("<displayorder>" + SecurityElement.Escape(hasDisplayOrder.DisplayOrder) + "</displayorder>");
|
||||
}
|
||||
}
|
||||
|
||||
if (item.VoteCount.HasValue)
|
||||
{
|
||||
builder.Append("<votes>" + SecurityElement.Escape(item.VoteCount.Value.ToString(UsCulture)) + "</votes>");
|
||||
}
|
||||
|
||||
var hasBudget = item as IHasBudget;
|
||||
if (hasBudget != null)
|
||||
{
|
||||
if (hasBudget.Budget.HasValue)
|
||||
{
|
||||
builder.Append("<budget>" + SecurityElement.Escape(hasBudget.Budget.Value.ToString(UsCulture)) + "</budget>");
|
||||
}
|
||||
|
||||
if (hasBudget.Revenue.HasValue)
|
||||
{
|
||||
builder.Append("<revenue>" + SecurityElement.Escape(hasBudget.Revenue.Value.ToString(UsCulture)) + "</revenue>");
|
||||
}
|
||||
}
|
||||
|
||||
var hasMetascore = item as IHasMetascore;
|
||||
if (hasMetascore != null && hasMetascore.Metascore.HasValue)
|
||||
{
|
||||
builder.Append("<metascore>" + SecurityElement.Escape(hasMetascore.Metascore.Value.ToString(UsCulture)) + "</metascore>");
|
||||
}
|
||||
|
||||
// Use original runtime here, actual file runtime later in MediaInfo
|
||||
var runTimeTicks = item.RunTimeTicks;
|
||||
|
||||
if (runTimeTicks.HasValue)
|
||||
{
|
||||
var timespan = TimeSpan.FromTicks(runTimeTicks.Value);
|
||||
|
||||
builder.Append("<runtime>" + Convert.ToInt32(timespan.TotalMinutes).ToString(UsCulture) + "</runtime>");
|
||||
}
|
||||
|
||||
var hasTaglines = item as IHasTaglines;
|
||||
if (hasTaglines != null)
|
||||
{
|
||||
foreach (var tagline in hasTaglines.Taglines)
|
||||
{
|
||||
builder.Append("<tagline>" + SecurityElement.Escape(tagline) + "</tagline>");
|
||||
}
|
||||
}
|
||||
|
||||
var hasProductionLocations = item as IHasProductionLocations;
|
||||
if (hasProductionLocations != null)
|
||||
{
|
||||
foreach (var country in hasProductionLocations.ProductionLocations)
|
||||
{
|
||||
builder.Append("<country>" + SecurityElement.Escape(country) + "</country>");
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var genre in item.Genres)
|
||||
{
|
||||
builder.Append("<genre>" + SecurityElement.Escape(genre) + "</genre>");
|
||||
}
|
||||
|
||||
foreach (var studio in item.Studios)
|
||||
{
|
||||
builder.Append("<studio>" + SecurityElement.Escape(studio) + "</studio>");
|
||||
}
|
||||
|
||||
var hasTags = item as IHasTags;
|
||||
if (hasTags != null)
|
||||
{
|
||||
foreach (var tag in hasTags.Tags)
|
||||
{
|
||||
if (item is MusicAlbum || item is MusicArtist)
|
||||
{
|
||||
builder.Append("<style>" + SecurityElement.Escape(tag) + "</style>");
|
||||
}
|
||||
else
|
||||
{
|
||||
builder.Append("<tag>" + SecurityElement.Escape(tag) + "</tag>");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var hasKeywords = item as IHasKeywords;
|
||||
if (hasKeywords != null)
|
||||
{
|
||||
foreach (var tag in hasKeywords.Keywords)
|
||||
{
|
||||
builder.Append("<plotkeyword>" + SecurityElement.Escape(tag) + "</plotkeyword>");
|
||||
}
|
||||
}
|
||||
|
||||
var hasAwards = item as IHasAwards;
|
||||
if (hasAwards != null && !string.IsNullOrEmpty(hasAwards.AwardSummary))
|
||||
{
|
||||
builder.Append("<awardsummary>" + SecurityElement.Escape(hasAwards.AwardSummary) + "</awardsummary>");
|
||||
}
|
||||
|
||||
var 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.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.TvRage);
|
||||
if (!string.IsNullOrEmpty(externalId))
|
||||
{
|
||||
builder.Append("<tvrageid>" + SecurityElement.Escape(externalId) + "</tvrageid>");
|
||||
}
|
||||
|
||||
if (options.SaveImagePathsInNfo)
|
||||
{
|
||||
AddImages(item, builder, fileSystem, config);
|
||||
}
|
||||
|
||||
AddUserData(item, builder, userManager, userDataRepo, options);
|
||||
|
||||
AddActors(item, builder, libraryManager, fileSystem, config);
|
||||
|
||||
var folder = item as BoxSet;
|
||||
if (folder != null)
|
||||
{
|
||||
AddCollectionItems(folder, builder);
|
||||
}
|
||||
}
|
||||
|
||||
public static void AddChapters(Video item, StringBuilder builder, IItemRepository repository)
|
||||
{
|
||||
var chapters = repository.GetChapters(item.Id);
|
||||
|
||||
foreach (var chapter in chapters)
|
||||
{
|
||||
builder.Append("<chapter>");
|
||||
builder.Append("<name>" + SecurityElement.Escape(chapter.Name) + "</name>");
|
||||
|
||||
var time = TimeSpan.FromTicks(chapter.StartPositionTicks);
|
||||
var ms = Convert.ToInt64(time.TotalMilliseconds);
|
||||
|
||||
builder.Append("<startpositionms>" + SecurityElement.Escape(ms.ToString(UsCulture)) + "</startpositionms>");
|
||||
builder.Append("</chapter>");
|
||||
}
|
||||
}
|
||||
|
||||
public static void AddCollectionItems(Folder item, StringBuilder builder)
|
||||
{
|
||||
var items = item.LinkedChildren
|
||||
.Where(i => i.Type == LinkedChildType.Manual && !string.IsNullOrWhiteSpace(i.ItemName))
|
||||
.ToList();
|
||||
|
||||
foreach (var link in items)
|
||||
{
|
||||
builder.Append("<collectionitem>");
|
||||
|
||||
builder.Append("<name>" + SecurityElement.Escape(link.ItemName) + "</name>");
|
||||
builder.Append("<type>" + SecurityElement.Escape(link.ItemType) + "</type>");
|
||||
|
||||
if (link.ItemYear.HasValue)
|
||||
{
|
||||
builder.Append("<year>" + SecurityElement.Escape(link.ItemYear.Value.ToString(UsCulture)) + "</year>");
|
||||
}
|
||||
|
||||
builder.Append("</collectionitem>");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the output trailer URL.
|
||||
/// </summary>
|
||||
/// <param name="url">The URL.</param>
|
||||
/// <returns>System.String.</returns>
|
||||
private static string GetOutputTrailerUrl(string url)
|
||||
{
|
||||
// This is what xbmc expects
|
||||
|
||||
return url.Replace("http://www.youtube.com/watch?v=",
|
||||
"plugin://plugin.video.youtube/?action=play_video&videoid=",
|
||||
StringComparison.OrdinalIgnoreCase);
|
||||
}
|
||||
|
||||
private static void AddImages(BaseItem item, StringBuilder builder, IFileSystem fileSystem, IServerConfigurationManager config)
|
||||
{
|
||||
builder.Append("<art>");
|
||||
|
||||
var poster = item.PrimaryImagePath;
|
||||
|
||||
if (!string.IsNullOrEmpty(poster))
|
||||
{
|
||||
builder.Append("<poster>" + SecurityElement.Escape(GetPathToSave(item.PrimaryImagePath, fileSystem, config)) + "</poster>");
|
||||
}
|
||||
|
||||
foreach (var backdrop in item.GetImages(ImageType.Backdrop))
|
||||
{
|
||||
builder.Append("<fanart>" + SecurityElement.Escape(GetPathToSave(backdrop.Path, fileSystem, config)) + "</fanart>");
|
||||
}
|
||||
|
||||
builder.Append("</art>");
|
||||
}
|
||||
|
||||
private static void AddUserData(BaseItem item, StringBuilder builder, IUserManager userManager, IUserDataManager userDataRepo, XbmcMetadataOptions options)
|
||||
{
|
||||
var userId = options.UserId;
|
||||
if (string.IsNullOrWhiteSpace(userId))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var user = userManager.GetUserById(new Guid(userId));
|
||||
|
||||
if (user == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (item.IsFolder)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var userdata = userDataRepo.GetUserData(user.Id, item.GetUserDataKey());
|
||||
|
||||
builder.Append("<playcount>" + userdata.PlayCount.ToString(UsCulture) + "</playcount>");
|
||||
builder.Append("<watched>" + userdata.Played.ToString().ToLower() + "</watched>");
|
||||
|
||||
if (userdata.LastPlayedDate.HasValue)
|
||||
{
|
||||
builder.Append("<lastplayed>" + SecurityElement.Escape(userdata.LastPlayedDate.Value.ToString("yyyy-MM-dd HH:mm:ss")) + "</lastplayed>");
|
||||
}
|
||||
|
||||
builder.Append("<resume>");
|
||||
|
||||
var runTimeTicks = item.RunTimeTicks ?? 0;
|
||||
|
||||
builder.Append("<position>" + TimeSpan.FromTicks(userdata.PlaybackPositionTicks).TotalSeconds.ToString(UsCulture) + "</position>");
|
||||
builder.Append("<total>" + TimeSpan.FromTicks(runTimeTicks).TotalSeconds.ToString(UsCulture) + "</total>");
|
||||
|
||||
builder.Append("</resume>");
|
||||
}
|
||||
|
||||
public static void AddActors(BaseItem item, StringBuilder builder, ILibraryManager libraryManager, IFileSystem fileSystem, IServerConfigurationManager config)
|
||||
{
|
||||
var actors = item.People
|
||||
.Where(i => !IsPersonType(i, PersonType.Director) && !IsPersonType(i, PersonType.Writer))
|
||||
.ToList();
|
||||
|
||||
foreach (var person in actors)
|
||||
{
|
||||
builder.Append("<actor>");
|
||||
builder.Append("<name>" + SecurityElement.Escape(person.Name ?? string.Empty) + "</name>");
|
||||
builder.Append("<role>" + SecurityElement.Escape(person.Role ?? string.Empty) + "</role>");
|
||||
builder.Append("<type>" + SecurityElement.Escape(person.Type ?? string.Empty) + "</type>");
|
||||
|
||||
try
|
||||
{
|
||||
var personEntity = libraryManager.GetPerson(person.Name);
|
||||
|
||||
if (!string.IsNullOrEmpty(personEntity.PrimaryImagePath))
|
||||
{
|
||||
builder.Append("<thumb>" + SecurityElement.Escape(GetPathToSave(personEntity.PrimaryImagePath, fileSystem, config)) + "</thumb>");
|
||||
}
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
// Already logged in core
|
||||
}
|
||||
|
||||
builder.Append("</actor>");
|
||||
}
|
||||
}
|
||||
|
||||
private static bool IsPersonType(PersonInfo person, string type)
|
||||
{
|
||||
return string.Equals(person.Type, type, StringComparison.OrdinalIgnoreCase) || string.Equals(person.Role, type, StringComparison.OrdinalIgnoreCase);
|
||||
}
|
||||
|
||||
private static string GetPathToSave(string path, IFileSystem fileSystem, IServerConfigurationManager config)
|
||||
{
|
||||
foreach (var map in config.Configuration.PathSubstitutions)
|
||||
{
|
||||
path = fileSystem.SubstitutePath(path, map.From, map.To);
|
||||
}
|
||||
|
||||
return path;
|
||||
}
|
||||
|
||||
public static string ReplaceString(string str, string oldValue, string newValue, StringComparison comparison)
|
||||
{
|
||||
var sb = new StringBuilder();
|
||||
|
||||
int previousIndex = 0;
|
||||
int index = str.IndexOf(oldValue, comparison);
|
||||
while (index != -1)
|
||||
{
|
||||
sb.Append(str.Substring(previousIndex, index - previousIndex));
|
||||
sb.Append(newValue);
|
||||
index += oldValue.Length;
|
||||
|
||||
previousIndex = index;
|
||||
index = str.IndexOf(oldValue, index, comparison);
|
||||
}
|
||||
sb.Append(str.Substring(previousIndex));
|
||||
|
||||
return sb.ToString();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,8 +1,6 @@
|
|||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio 2013
|
||||
VisualStudioVersion = 12.0.21005.1
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
# Visual Studio 2012
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MediaBrowser.Controller", "MediaBrowser.Controller\MediaBrowser.Controller.csproj", "{17E1F4E6-8ABD-4FE5-9ECF-43D4B6087BA2}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MediaBrowser.Api", "MediaBrowser.Api\MediaBrowser.Api.csproj", "{4FD51AC5-2C16-4308-A993-C3A84F3B4582}"
|
||||
|
@ -47,6 +45,10 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MediaBrowser.MediaEncoding"
|
|||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OpenSubtitlesHandler", "OpenSubtitlesHandler\OpenSubtitlesHandler.csproj", "{4A4402D4-E910-443B-B8FC-2C18286A2CA0}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MediaBrowser.XbmcMetadata", "MediaBrowser.XbmcMetadata\MediaBrowser.XbmcMetadata.csproj", "{23499896-B135-4527-8574-C26E926EA99E}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MediaBrowser.LocalMetadata", "MediaBrowser.LocalMetadata\MediaBrowser.LocalMetadata.csproj", "{7EF9F3E0-697D-42F3-A08F-19DEB5F84392}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
|
@ -281,6 +283,34 @@ Global
|
|||
{4A4402D4-E910-443B-B8FC-2C18286A2CA0}.Release|Win32.ActiveCfg = Release|Any CPU
|
||||
{4A4402D4-E910-443B-B8FC-2C18286A2CA0}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{4A4402D4-E910-443B-B8FC-2C18286A2CA0}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{23499896-B135-4527-8574-C26E926EA99E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{23499896-B135-4527-8574-C26E926EA99E}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{23499896-B135-4527-8574-C26E926EA99E}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
|
||||
{23499896-B135-4527-8574-C26E926EA99E}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
|
||||
{23499896-B135-4527-8574-C26E926EA99E}.Debug|Win32.ActiveCfg = Debug|Any CPU
|
||||
{23499896-B135-4527-8574-C26E926EA99E}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{23499896-B135-4527-8574-C26E926EA99E}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{23499896-B135-4527-8574-C26E926EA99E}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{23499896-B135-4527-8574-C26E926EA99E}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{23499896-B135-4527-8574-C26E926EA99E}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
|
||||
{23499896-B135-4527-8574-C26E926EA99E}.Release|Mixed Platforms.Build.0 = Release|Any CPU
|
||||
{23499896-B135-4527-8574-C26E926EA99E}.Release|Win32.ActiveCfg = Release|Any CPU
|
||||
{23499896-B135-4527-8574-C26E926EA99E}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{23499896-B135-4527-8574-C26E926EA99E}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{7EF9F3E0-697D-42F3-A08F-19DEB5F84392}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{7EF9F3E0-697D-42F3-A08F-19DEB5F84392}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{7EF9F3E0-697D-42F3-A08F-19DEB5F84392}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
|
||||
{7EF9F3E0-697D-42F3-A08F-19DEB5F84392}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
|
||||
{7EF9F3E0-697D-42F3-A08F-19DEB5F84392}.Debug|Win32.ActiveCfg = Debug|Any CPU
|
||||
{7EF9F3E0-697D-42F3-A08F-19DEB5F84392}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{7EF9F3E0-697D-42F3-A08F-19DEB5F84392}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{7EF9F3E0-697D-42F3-A08F-19DEB5F84392}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{7EF9F3E0-697D-42F3-A08F-19DEB5F84392}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{7EF9F3E0-697D-42F3-A08F-19DEB5F84392}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
|
||||
{7EF9F3E0-697D-42F3-A08F-19DEB5F84392}.Release|Mixed Platforms.Build.0 = Release|Any CPU
|
||||
{7EF9F3E0-697D-42F3-A08F-19DEB5F84392}.Release|Win32.ActiveCfg = Release|Any CPU
|
||||
{7EF9F3E0-697D-42F3-A08F-19DEB5F84392}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{7EF9F3E0-697D-42F3-A08F-19DEB5F84392}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
|
Loading…
Reference in New Issue
Block a user