@ -13,6 +13,7 @@ using MediaBrowser.Common.Providers;
using MediaBrowser.Controller.Entities ;
using MediaBrowser.Controller.Entities.Movies ;
using MediaBrowser.Controller.Entities.TV ;
using MediaBrowser.Controller.Extensions ;
using MediaBrowser.Controller.Library ;
using MediaBrowser.Controller.Providers ;
using MediaBrowser.Model.Entities ;
@ -261,158 +262,84 @@ namespace MediaBrowser.XbmcMetadata.Parsers
protected virtual void FetchDataFromXmlNode ( XmlReader reader , MetadataResult < T > itemResult )
{
var item = itemResult . Item ;
var nfoConfiguration = _config . GetNfoConfiguration ( ) ;
UserItemData ? userData = null ;
UserItemData ? userData ;
switch ( reader . Name )
{
// DateCreated
case "dateadded" :
if ( reader . TryReadDateTime ( out var dateCreated ) )
{
var val = reader . ReadElementContentAsString ( ) ;
if ( DateTime . TryParse ( val , CultureInfo . InvariantCulture , DateTimeStyles . AssumeUniversal | DateTimeStyles . AdjustToUniversal , out var added ) )
{
item . DateCreated = added ;
}
else
{
Logger . LogWarning ( "Invalid Added value found: {Value}" , val ) ;
item . DateCreated = dateCreated ;
}
break ;
}
case "originaltitle" :
{
var val = reader . ReadElementContentAsString ( ) ;
if ( ! string . IsNullOrEmpty ( val ) )
{
item . OriginalTitle = val ;
}
item . OriginalTitle = reader . ReadNormalizedString ( ) ;
break ;
}
case "name" :
case "title" :
case "localtitle" :
item . Name = reader . Read ElementContentAs String( ) ;
item . Name = reader . ReadNormalizedString ( ) ;
break ;
case "sortname" :
item . SortName = reader . Read ElementContentAs String( ) ;
item . SortName = reader . Read Normalized String( ) ;
break ;
case "criticrating" :
{
var text = reader . ReadElementContentAsString ( ) ;
if ( float . TryParse ( text , CultureInfo . InvariantCulture , out var value ) )
var criticRatingText = reader . ReadElementContentAsString ( ) ;
if ( float . TryParse ( criticRatingText , CultureInfo . InvariantCulture , out var value ) )
{
item . CriticRating = value ;
}
break ;
}
case "sorttitle" :
{
var val = reader . ReadElementContentAsString ( ) ;
if ( ! string . IsNullOrWhiteSpace ( val ) )
{
item . ForcedSortName = val ;
}
item . ForcedSortName = reader . ReadNormalizedString ( ) ;
break ;
}
case "biography" :
case "plot" :
case "review" :
{
var val = reader . ReadElementContentAsString ( ) ;
if ( ! string . IsNullOrWhiteSpace ( val ) )
{
item . Overview = val ;
}
item . Overview = reader . ReadNormalizedString ( ) ;
break ;
}
case "language" :
{
var val = reader . ReadElementContentAsString ( ) ;
item . PreferredMetadataLanguage = val ;
item . PreferredMetadataLanguage = reader . ReadNormalizedString ( ) ;
break ;
}
case "watched" :
{
var val = reader . ReadElementContentAsBoolean ( ) ;
var played = reader . ReadElementContentAsBoolean ( ) ;
if ( ! string . IsNullOrWhiteSpace ( nfoConfiguration . UserId ) )
{
var user = _userManager . GetUserById ( Guid . Parse ( nfoConfiguration . UserId ) ) ;
userData = _userDataManager . GetUserData ( user , item ) ;
userData . Played = val ;
userData . Played = played ;
_userDataManager . SaveUserData ( user , item , userData , UserDataSaveReason . Import , CancellationToken . None ) ;
}
break ;
}
case "playcount" :
if ( reader . TryReadInt ( out var count )
& & Guid . TryParse ( nfoConfiguration . UserId , out var playCountUserId ) )
{
var val = reader . ReadElementContentAsString ( ) ;
if ( int . TryParse ( val , NumberStyles . Integer , CultureInfo . InvariantCulture , out var count )
& & Guid . TryParse ( nfoConfiguration . UserId , out var guid ) )
{
var user = _userManager . GetUserById ( guid ) ;
var user = _userManager . GetUserById ( playCountUserId ) ;
userData = _userDataManager . GetUserData ( user , item ) ;
userData . PlayCount = count ;
_userDataManager . SaveUserData ( user , item , userData , UserDataSaveReason . Import , CancellationToken . None ) ;
}
break ;
}
case "lastplayed" :
if ( reader . TryReadDateTime ( out var lastPlayed )
& & Guid . TryParse ( nfoConfiguration . UserId , out var lastPlayedUserId ) )
{
var val = reader . ReadElementContentAsString ( ) ;
if ( Guid . TryParse ( nfoConfiguration . UserId , out var guid ) )
{
if ( DateTime . TryParse ( val , CultureInfo . InvariantCulture , DateTimeStyles . AssumeUniversal | DateTimeStyles . AdjustToUniversal , out var added ) )
{
var user = _userManager . GetUserById ( guid ) ;
var user = _userManager . GetUserById ( lastPlayedUserId ) ;
userData = _userDataManager . GetUserData ( user , item ) ;
userData . LastPlayedDate = add ed;
userData . LastPlayedDate = lastPlayed ;
_userDataManager . SaveUserData ( user , item , userData , UserDataSaveReason . Import , CancellationToken . None ) ;
}
else
{
Logger . LogWarning ( "Invalid lastplayed value found: {Value}" , val ) ;
}
}
break ;
}
case "countrycode" :
{
var val = reader . ReadElementContentAsString ( ) ;
item . PreferredMetadataCountryCode = val ;
item . PreferredMetadataCountryCode = reader . ReadNormalizedString ( ) ;
break ;
}
case "lockedfields" :
{
var val = reader . ReadElementContentAsString ( ) ;
@ -434,9 +361,8 @@ namespace MediaBrowser.XbmcMetadata.Parsers
}
case "tagline" :
item . Tagline = reader . Read ElementContentAs String( ) ;
item . Tagline = reader . Read Normalized String( ) ;
break ;
case "country" :
{
var val = reader . ReadElementContentAsString ( ) ;
@ -453,94 +379,45 @@ namespace MediaBrowser.XbmcMetadata.Parsers
}
case "mpaa" :
{
var rating = reader . ReadElementContentAsString ( ) ;
if ( ! string . IsNullOrWhiteSpace ( rating ) )
{
item . OfficialRating = rating ;
}
item . OfficialRating = reader . ReadNormalizedString ( ) ;
break ;
}
case "customrating" :
{
var val = reader . ReadElementContentAsString ( ) ;
if ( ! string . IsNullOrWhiteSpace ( val ) )
{
item . CustomRating = val ;
}
item . CustomRating = reader . ReadNormalizedString ( ) ;
break ;
}
case "runtime" :
{
var text = reader . ReadElementContentAsString ( ) ;
if ( int . TryParse ( text . AsSpan ( ) . LeftPart ( ' ' ) , NumberStyles . Integer , CultureInfo . InvariantCulture , out var runtime ) )
var runtimeText = reader . ReadElementContentAsString ( ) ;
if ( int . TryParse ( runtimeText . AsSpan ( ) . LeftPart ( ' ' ) , NumberStyles . Integer , CultureInfo . InvariantCulture , out var runtime ) )
{
item . RunTimeTicks = TimeSpan . FromMinutes ( runtime ) . Ticks ;
}
break ;
}
case "aspectratio" :
var aspectRatio = reader . ReadNormalizedString ( ) ;
if ( ! string . IsNullOrEmpty ( aspectRatio ) & & item is IHasAspectRatio hasAspectRatio )
{
var val = reader . ReadElementContentAsString ( ) ;
if ( ! string . IsNullOrWhiteSpace ( val )
& & item is IHasAspectRatio hasAspectRatio )
{
hasAspectRatio . AspectRatio = val ;
hasAspectRatio . AspectRatio = aspectRatio ;
}
break ;
}
case "lockdata" :
{
var val = reader . ReadElementContentAsString ( ) ;
if ( ! string . IsNullOrWhiteSpace ( val ) )
{
item . IsLocked = string . Equals ( "true" , val , StringComparison . OrdinalIgnoreCase ) ;
}
item . IsLocked = string . Equals ( reader . ReadElementContentAsString ( ) , "true" , StringComparison . OrdinalIgnoreCase ) ;
break ;
}
case "studio" :
var studio = reader . ReadNormalizedString ( ) ;
if ( ! string . IsNullOrEmpty ( studio ) )
{
var val = reader . ReadElementContentAsString ( ) ;
if ( ! string . IsNullOrWhiteSpace ( val ) )
{
item . AddStudio ( val ) ;
item . AddStudio ( studio ) ;
}
break ;
}
case "director" :
foreach ( var director in reader . GetPersonArray ( PersonKind . Director ) )
{
var val = reader . ReadElementContentAsString ( ) ;
foreach ( var p in SplitNames ( val ) . Select ( v = > new PersonInfo { Name = v . Trim ( ) , Type = PersonKind . Director } ) )
{
if ( string . IsNullOrWhiteSpace ( p . Name ) )
{
continue ;
}
itemResult . AddPerson ( p ) ;
itemResult . AddPerson ( director ) ;
}
break ;
}
case "credits" :
{
var val = reader . ReadElementContentAsString ( ) ;
@ -565,141 +442,76 @@ namespace MediaBrowser.XbmcMetadata.Parsers
}
case "writer" :
foreach ( var writer in reader . GetPersonArray ( PersonKind . Writer ) )
{
var val = reader . ReadElementContentAsString ( ) ;
foreach ( var p in SplitNames ( val ) . Select ( v = > new PersonInfo { Name = v . Trim ( ) , Type = PersonKind . Writer } ) )
{
if ( string . IsNullOrWhiteSpace ( p . Name ) )
{
continue ;
}
itemResult . AddPerson ( p ) ;
itemResult . AddPerson ( writer ) ;
}
break ;
}
case "actor" :
{
if ( ! reader . IsEmptyElement )
{
using ( var subtree = reader . ReadSubtree ( ) )
{
var person = GetPersonFromXmlNode ( subtree ) ;
if ( ! string . IsNullOrWhiteSpace ( person . Name ) )
var person = reader . GetPersonFromXmlNode ( ) ;
if ( person is not null )
{
itemResult . AddPerson ( person ) ;
}
}
}
else
{
reader . Read ( ) ;
}
break ;
}
case "trailer" :
var trailer = reader . ReadNormalizedString ( ) ;
if ( ! string . IsNullOrEmpty ( trailer ) )
{
var val = reader . ReadElementContentAsString ( ) ;
if ( ! string . IsNullOrWhiteSpace ( val ) )
{
val = val . Replace ( "plugin://plugin.video.youtube/?action=play_video&videoid=" , BaseNfoSaver . YouTubeWatchUrl , StringComparison . OrdinalIgnoreCase ) ;
item . AddTrailerUrl ( val ) ;
item . AddTrailerUrl ( trailer . Replace (
"plugin://plugin.video.youtube/?action=play_video&videoid=" ,
BaseNfoSaver . YouTubeWatchUrl ,
StringComparison . OrdinalIgnoreCase ) ) ;
}
break ;
}
case "displayorder" :
var displayOrder = reader . ReadNormalizedString ( ) ;
if ( ! string . IsNullOrEmpty ( displayOrder ) & & item is IHasDisplayOrder hasDisplayOrder )
{
var val = reader . ReadElementContentAsString ( ) ;
if ( item is IHasDisplayOrder hasDisplayOrder & & ! string . IsNullOrWhiteSpace ( val ) )
{
hasDisplayOrder . DisplayOrder = val ;
hasDisplayOrder . DisplayOrder = displayOrder ;
}
break ;
}
case "year" :
{
var val = reader . ReadElementContentAsString ( ) ;
if ( int . TryParse ( val , out var productionYear ) & & productionYear > 1850 )
if ( reader . TryReadInt ( out var productionYear ) & & productionYear > 1850 )
{
item . ProductionYear = productionYear ;
}
break ;
}
case "rating" :
{
var rating = reader . ReadElementContentAsString ( ) ;
var rating = reader . ReadElementContentAsString ( ) . Replace ( ',' , '.' ) ;
// 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 var val ) )
if ( float . TryParse ( rating , NumberStyles . AllowDecimalPoint , CultureInfo . InvariantCulture , out var communityRating ) )
{
item . CommunityRating = val ;
item . CommunityRating = communityRating ;
}
break ;
}
case "ratings" :
{
if ( ! reader . IsEmptyElement )
{
using var subtree = reader . ReadSubtree ( ) ;
FetchFromRatingsNode ( subtree , item ) ;
}
else
{
reader . Read ( ) ;
}
FetchFromRatingsNode ( reader , item ) ;
break ;
}
case "aired" :
case "formed" :
case "premiered" :
case "releasedate" :
if ( reader . TryReadDateTimeExact ( nfoConfiguration . ReleaseDateFormat , out var releaseDate ) )
{
var formatString = nfoConfiguration . ReleaseDateFormat ;
var val = reader . ReadElementContentAsString ( ) ;
if ( DateTime . TryParseExact ( val , formatString , CultureInfo . InvariantCulture , DateTimeStyles . AssumeUniversal | DateTimeStyles . AdjustToUniversal , out var date ) & & date . Year > 1850 )
{
item . PremiereDate = date ;
item . ProductionYear = date . Year ;
item . PremiereDate = releaseDate ;
item . ProductionYear = releaseDate . Year ;
}
break ;
}
case "enddate" :
if ( reader . TryReadDateTimeExact ( nfoConfiguration . ReleaseDateFormat , out var endDate ) )
{
var formatString = nfoConfiguration . ReleaseDateFormat ;
var val = reader . ReadElementContentAsString ( ) ;
if ( DateTime . TryParseExact ( val , formatString , CultureInfo . InvariantCulture , DateTimeStyles . AssumeUniversal | DateTimeStyles . AdjustToUniversal , out var date ) & & date . Year > 1850 )
{
item . EndDate = date ;
item . EndDate = endDate ;
}
break ;
}
case "genre" :
{
var val = reader . ReadElementContentAsString ( ) ;
@ -721,35 +533,17 @@ namespace MediaBrowser.XbmcMetadata.Parsers
case "style" :
case "tag" :
var tag = reader . ReadNormalizedString ( ) ;
if ( ! string . IsNullOrEmpty ( tag ) )
{
var val = reader . ReadElementContentAsString ( ) ;
if ( ! string . IsNullOrWhiteSpace ( val ) )
{
item . AddTag ( val ) ;
item . AddTag ( tag ) ;
}
break ;
}
case "fileinfo" :
{
if ( ! reader . IsEmptyElement )
{
using ( var subtree = reader . ReadSubtree ( ) )
{
FetchFromFileInfoNode ( subtree , item ) ;
}
}
else
{
reader . Read ( ) ;
}
FetchFromFileInfoNode ( reader , item ) ;
break ;
}
case "uniqueid" :
{
if ( reader . IsEmptyElement )
{
reader . Read ( ) ;
@ -757,21 +551,16 @@ namespace MediaBrowser.XbmcMetadata.Parsers
}
var provider = reader . GetAttribute ( "type" ) ;
var id = reader . ReadElementContentAsString ( ) ;
if ( ! string . IsNullOrWhiteSpace ( provider ) & & ! string . IsNullOrWhiteSpace ( id) )
var prov iderI d = reader . ReadElementContentAsString ( ) ;
if ( ! string . IsNullOrWhiteSpace ( provider ) & & ! string . IsNullOrWhiteSpace ( prov iderI d) )
{
item . SetProviderId ( provider , id) ;
item . SetProviderId ( provider , prov iderI d) ;
}
break ;
}
case "thumb" :
{
FetchThumbNode ( reader , itemResult , "thumb" ) ;
break ;
}
case "fanart" :
{
if ( reader . IsEmptyElement )
@ -876,217 +665,162 @@ namespace MediaBrowser.XbmcMetadata.Parsers
}
}
private void FetchFromFileInfoNode ( XmlReader reader , T item )
private void FetchFromFileInfoNode ( XmlReader parentReader , T item )
{
if ( parentReader . IsEmptyElement )
{
parentReader . Read ( ) ;
return ;
}
using var reader = parentReader . ReadSubtree ( ) ;
reader . MoveToContent ( ) ;
reader . Read ( ) ;
// Loop through each element
while ( ! reader . EOF & & reader . ReadState = = ReadState . Interactive )
{
if ( reader . NodeType = = XmlNodeType . Element )
{
switch ( reader . Name )
{
case "streamdetails" :
{
if ( reader . IsEmptyElement )
if ( reader . NodeType ! = XmlNodeType . Element )
{
reader . Read ( ) ;
continue ;
}
using ( var subtree = reader . ReadSubtree ( ) )
switch ( reader . Name )
{
FetchFromStreamDetailsNode ( subtree , item ) ;
}
case "streamdetails" :
FetchFromStreamDetailsNode ( reader , item ) ;
break ;
}
default :
reader . Skip ( ) ;
break ;
}
}
else
{
reader . Read ( ) ;
}
}
}
private void FetchFromStreamDetailsNode ( XmlReader reader , T item )
private void FetchFromStreamDetailsNode ( XmlReader parentReader , T item )
{
if ( parentReader . IsEmptyElement )
{
parentReader . Read ( ) ;
return ;
}
using var reader = parentReader . ReadSubtree ( ) ;
reader . MoveToContent ( ) ;
reader . Read ( ) ;
// Loop through each element
while ( ! reader . EOF & & reader . ReadState = = ReadState . Interactive )
{
if ( reader . NodeType = = XmlNodeType . Element )
{
switch ( reader . Name )
{
case "video" :
{
if ( reader . IsEmptyElement )
if ( reader . NodeType ! = XmlNodeType . Element )
{
reader . Read ( ) ;
continue ;
}
using ( var subtree = reader . ReadSubtree ( ) )
switch ( reader . Name )
{
FetchFromVideoNode ( subtree , item ) ;
}
case "video" :
FetchFromVideoNode ( reader , item ) ;
break ;
}
case "subtitle" :
{
if ( reader . IsEmptyElement )
{
reader . Read ( ) ;
continue ;
}
using ( var subtree = reader . ReadSubtree ( ) )
{
FetchFromSubtitleNode ( subtree , item ) ;
}
FetchFromSubtitleNode ( reader , item ) ;
break ;
}
default :
reader . Skip ( ) ;
break ;
}
}
else
{
reader . Read ( ) ;
}
}
}
private void FetchFromVideoNode ( XmlReader reader, T item )
private void FetchFromVideoNode ( XmlReader parentReader , T item )
{
if ( parentReader . IsEmptyElement )
{
parentReader . Read ( ) ;
return ;
}
using var reader = parentReader . ReadSubtree ( ) ;
reader . MoveToContent ( ) ;
reader . Read ( ) ;
// Loop through each element
while ( ! reader . EOF & & reader . ReadState = = ReadState . Interactive )
{
if ( reader . NodeType = = XmlNodeType . Element )
if ( reader . NodeType ! = XmlNodeType . Element | | item is not Video video )
{
reader . Read ( ) ;
continue ;
}
switch ( reader . Name )
{
case "format3d" :
{
var val = reader . ReadElementContentAsString ( ) ;
var video = item as Video ;
if ( video is not null )
{
if ( string . Equals ( "HSBS" , val , StringComparison . OrdinalIgnoreCase ) )
var format = reader . ReadElementContentAsString ( ) ;
if ( string . Equals ( "HSBS" , format , StringComparison . OrdinalIgnoreCase ) )
{
video . Video3DFormat = Video3DFormat . HalfSideBySide ;
}
else if ( string . Equals ( "HTAB" , val , StringComparison . OrdinalIgnoreCase ) )
else if ( string . Equals ( "HTAB" , format , StringComparison . OrdinalIgnoreCase ) )
{
video . Video3DFormat = Video3DFormat . HalfTopAndBottom ;
}
else if ( string . Equals ( "FTAB" , val , StringComparison . OrdinalIgnoreCase ) )
else if ( string . Equals ( "FTAB" , format , StringComparison . OrdinalIgnoreCase ) )
{
video . Video3DFormat = Video3DFormat . FullTopAndBottom ;
}
else if ( string . Equals ( "FSBS" , val , StringComparison . OrdinalIgnoreCase ) )
else if ( string . Equals ( "FSBS" , format , StringComparison . OrdinalIgnoreCase ) )
{
video . Video3DFormat = Video3DFormat . FullSideBySide ;
}
else if ( string . Equals ( "MVC" , val , StringComparison . OrdinalIgnoreCase ) )
else if ( string . Equals ( "MVC" , format , StringComparison . OrdinalIgnoreCase ) )
{
video . Video3DFormat = Video3DFormat . MVC ;
}
}
break ;
}
case "aspect" :
{
var val = reader . ReadElementContentAsString ( ) ;
if ( item is Video video )
{
video . AspectRatio = val ;
}
video . AspectRatio = reader . ReadNormalizedString ( ) ;
break ;
}
case "width" :
{
var val = reader . ReadElementContentAsInt ( ) ;
if ( item is Video video )
{
video . Width = val ;
}
video . Width = reader . ReadElementContentAsInt ( ) ;
break ;
}
case "height" :
{
var val = reader . ReadElementContentAsInt ( ) ;
if ( item is Video video )
{
video . Height = val ;
}
video . Height = reader . ReadElementContentAsInt ( ) ;
break ;
}
case "durationinseconds" :
{
var val = reader . ReadElementContentAsInt ( ) ;
if ( item is Video video )
{
video . RunTimeTicks = new TimeSpan ( 0 , 0 , val ) . Ticks ;
}
video . RunTimeTicks = new TimeSpan ( 0 , 0 , reader . ReadElementContentAsInt ( ) ) . Ticks ;
break ;
}
default :
reader . Skip ( ) ;
break ;
}
}
else
{
reader . Read ( ) ;
}
}
}
private void FetchFromSubtitleNode ( XmlReader reader, T item )
private void FetchFromSubtitleNode ( XmlReader parentReader , T item )
{
if ( parentReader . IsEmptyElement )
{
parentReader . Read ( ) ;
return ;
}
using var reader = parentReader . ReadSubtree ( ) ;
reader . MoveToContent ( ) ;
reader . Read ( ) ;
// Loop through each element
while ( ! reader . EOF & & reader . ReadState = = ReadState . Interactive )
{
if ( reader . NodeType = = XmlNodeType . Element )
if ( reader . NodeType ! = XmlNodeType . Element )
{
reader . Read ( ) ;
continue ;
}
switch ( reader . Name )
{
case "language" :
@ -1097,21 +831,22 @@ namespace MediaBrowser.XbmcMetadata.Parsers
}
break ;
default :
reader . Skip ( ) ;
break ;
}
}
else
{
reader . Read ( ) ;
}
}
}
private void FetchFromRatingsNode ( XmlReader reader , T item )
private void FetchFromRatingsNode ( XmlReader parentReader , T item )
{
if ( parentReader . IsEmptyElement )
{
parentReader . Read ( ) ;
return ;
}
using var reader = parentReader . ReadSubtree ( ) ;
reader . MoveToContent ( ) ;
reader . Read ( ) ;
@ -1196,102 +931,6 @@ namespace MediaBrowser.XbmcMetadata.Parsers
}
}
/// <summary>
/// Gets the persons from a XML node.
/// </summary>
/// <param name="reader">The <see cref="XmlReader"/>.</param>
/// <returns>IEnumerable{PersonInfo}.</returns>
private PersonInfo GetPersonFromXmlNode ( XmlReader reader )
{
var name = string . Empty ;
var type = PersonKind . Actor ; // If type is not specified assume actor
var role = string . Empty ;
int? sortOrder = null ;
string? imageUrl = null ;
reader . MoveToContent ( ) ;
reader . Read ( ) ;
// Loop through each element
while ( ! reader . EOF & & reader . ReadState = = ReadState . Interactive )
{
if ( reader . NodeType = = XmlNodeType . Element )
{
switch ( reader . Name )
{
case "name" :
name = reader . ReadElementContentAsString ( ) ;
break ;
case "role" :
{
var val = reader . ReadElementContentAsString ( ) ;
if ( ! string . IsNullOrWhiteSpace ( val ) )
{
role = val ;
}
break ;
}
case "type" :
{
var val = reader . ReadElementContentAsString ( ) ;
if ( ! Enum . TryParse ( val , true , out type ) )
{
type = PersonKind . Actor ;
}
break ;
}
case "order" :
case "sortorder" :
{
var val = reader . ReadElementContentAsString ( ) ;
if ( int . TryParse ( val , NumberStyles . Integer , CultureInfo . InvariantCulture , out var intVal ) )
{
sortOrder = intVal ;
}
break ;
}
case "thumb" :
{
var val = reader . ReadElementContentAsString ( ) ;
if ( ! string . IsNullOrWhiteSpace ( val ) )
{
imageUrl = val ;
}
break ;
}
default :
reader . Skip ( ) ;
break ;
}
}
else
{
reader . Read ( ) ;
}
}
return new PersonInfo
{
Name = name . Trim ( ) ,
Role = role ,
Type = type ,
SortOrder = sortOrder ,
ImageUrl = imageUrl
} ;
}
internal XmlReaderSettings GetXmlReaderSettings ( )
= > new XmlReaderSettings ( )
{
@ -1301,24 +940,6 @@ namespace MediaBrowser.XbmcMetadata.Parsers
IgnoreComments = true
} ;
/// <summary>
/// Used to split names of comma or pipe delimited genres and people.
/// </summary>
/// <param name="value">The value.</param>
/// <returns>IEnumerable{System.String}.</returns>
private IEnumerable < string > SplitNames ( string value )
{
// 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 . Contains ( '|' , StringComparison . Ordinal ) & & ! value . Contains ( ';' , StringComparison . Ordinal )
? new [ ] { ',' }
: new [ ] { '|' , ';' } ;
value = value . Trim ( ) . Trim ( separator ) ;
return string . IsNullOrWhiteSpace ( value ) ? Array . Empty < string > ( ) : value . Split ( separator , StringSplitOptions . RemoveEmptyEntries ) ;
}
/// <summary>
/// Parses the <see cref="ImageType"/> from the NFO aspect property.
/// </summary>