@ -3,6 +3,7 @@ using System.Collections.Generic;
@@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Linq ;
using System.Threading.Tasks ;
using ErsatzTV.Core.Domain ;
using ErsatzTV.Core.Interfaces.Metadata ;
using ErsatzTV.Core.Interfaces.Plex ;
using ErsatzTV.Core.Interfaces.Repositories ;
using ErsatzTV.Core.Interfaces.Search ;
@ -18,9 +19,12 @@ namespace ErsatzTV.Core.Plex
@@ -18,9 +19,12 @@ namespace ErsatzTV.Core.Plex
{
public class PlexTelevisionLibraryScanner : PlexLibraryScanner , IPlexTelevisionLibraryScanner
{
private readonly ILocalFileSystem _l ocalFileSystem ;
private readonly ILogger < PlexTelevisionLibraryScanner > _l ogger ;
private readonly IMediaSourceRepository _ mediaSourceRepository ;
private readonly IMediator _ mediator ;
private readonly IMetadataRepository _ metadataRepository ;
private readonly IPlexPathReplacementService _ plexPathReplacementService ;
private readonly IPlexServerApiClient _ plexServerApiClient ;
private readonly ISearchIndex _ searchIndex ;
private readonly ISearchRepository _ searchRepository ;
@ -33,6 +37,9 @@ namespace ErsatzTV.Core.Plex
@@ -33,6 +37,9 @@ namespace ErsatzTV.Core.Plex
ISearchIndex searchIndex ,
ISearchRepository searchRepository ,
IMediator mediator ,
IMediaSourceRepository mediaSourceRepository ,
IPlexPathReplacementService plexPathReplacementService ,
ILocalFileSystem localFileSystem ,
ILogger < PlexTelevisionLibraryScanner > logger )
: base ( metadataRepository , logger )
{
@ -42,6 +49,9 @@ namespace ErsatzTV.Core.Plex
@@ -42,6 +49,9 @@ namespace ErsatzTV.Core.Plex
_ searchIndex = searchIndex ;
_ searchRepository = searchRepository ;
_ mediator = mediator ;
_ mediaSourceRepository = mediaSourceRepository ;
_ plexPathReplacementService = plexPathReplacementService ;
_l ocalFileSystem = localFileSystem ;
_l ogger = logger ;
}
@ -50,6 +60,9 @@ namespace ErsatzTV.Core.Plex
@@ -50,6 +60,9 @@ namespace ErsatzTV.Core.Plex
PlexServerAuthToken token ,
PlexLibrary library )
{
List < PlexPathReplacement > pathReplacements = await _ mediaSourceRepository
. GetPlexPathReplacements ( library . MediaSourceId ) ;
Either < BaseError , List < PlexShow > > entries = await _ plexServerApiClient . GetShowLibraryContents (
library ,
connection ,
@ -72,7 +85,7 @@ namespace ErsatzTV.Core.Plex
@@ -72,7 +85,7 @@ namespace ErsatzTV.Core.Plex
await maybeShow . Match (
async result = >
{
await ScanSeasons ( library , result . Item , connection , token ) ;
await ScanSeasons ( library , pathReplacements , result . Item , connection , token ) ;
if ( result . IsAdded )
{
@ -271,13 +284,14 @@ namespace ErsatzTV.Core.Plex
@@ -271,13 +284,14 @@ namespace ErsatzTV.Core.Plex
}
private async Task < Either < BaseError , Unit > > ScanSeasons (
PlexLibrary plexMediaSourceLibrary ,
PlexLibrary library ,
List < PlexPathReplacement > pathReplacements ,
PlexShow show ,
PlexConnection connection ,
PlexServerAuthToken token )
{
Either < BaseError , List < PlexSeason > > entries = await _ plexServerApiClient . GetShowSeasons (
p lexMediaSourceL ibrary,
library ,
show ,
connection ,
token ) ;
@ -291,11 +305,11 @@ namespace ErsatzTV.Core.Plex
@@ -291,11 +305,11 @@ namespace ErsatzTV.Core.Plex
// TODO: figure out how to rebuild playlists
Either < BaseError , PlexSeason > maybeSeason = await _ televisionRepository
. GetOrAddPlexSeason ( p lexMediaSourceL ibrary, incoming )
. GetOrAddPlexSeason ( library , incoming )
. BindT ( existing = > UpdateMetadataAndArtwork ( existing , incoming ) ) ;
await maybeSeason . Match (
async season = > await ScanEpisodes ( plexMediaSourceLibrary , season , connection , token ) ,
async season = > await ScanEpisodes ( library , pathReplacements , season , connection , token ) ,
error = >
{
_l ogger . LogWarning (
@ -315,7 +329,7 @@ namespace ErsatzTV.Core.Plex
@@ -315,7 +329,7 @@ namespace ErsatzTV.Core.Plex
{
_l ogger . LogWarning (
"Error synchronizing plex library {Path}: {Error}" ,
p lexMediaSourceL ibrary. Name ,
library . Name ,
error . Value ) ;
return Left < BaseError , Unit > ( error ) . AsTask ( ) ;
@ -355,13 +369,14 @@ namespace ErsatzTV.Core.Plex
@@ -355,13 +369,14 @@ namespace ErsatzTV.Core.Plex
}
private async Task < Either < BaseError , Unit > > ScanEpisodes (
PlexLibrary plexMediaSourceLibrary ,
PlexLibrary library ,
List < PlexPathReplacement > pathReplacements ,
PlexSeason season ,
PlexConnection connection ,
PlexServerAuthToken token )
{
Either < BaseError , List < PlexEpisode > > entries = await _ plexServerApiClient . GetSeasonEpisodes (
p lexMediaSourceL ibrary,
library ,
season ,
connection ,
token ) ;
@ -369,19 +384,39 @@ namespace ErsatzTV.Core.Plex
@@ -369,19 +384,39 @@ namespace ErsatzTV.Core.Plex
return await entries . Match < Task < Either < BaseError , Unit > > > (
async episodeEntries = >
{
foreach ( PlexEpisode incoming in episodeEntries )
var validEpisodes = new List < PlexEpisode > ( ) ;
foreach ( PlexEpisode episode in episodeEntries )
{
string localPath = _ plexPathReplacementService . GetReplacementPlexPath (
pathReplacements ,
episode . MediaVersions . Head ( ) . MediaFiles . Head ( ) . Path ,
false ) ;
if ( ! _l ocalFileSystem . FileExists ( localPath ) )
{
_l ogger . LogWarning (
"Skipping plex episode that does not exist at {Path}" ,
localPath ) ;
}
else
{
validEpisodes . Add ( episode ) ;
}
}
foreach ( PlexEpisode incoming in validEpisodes )
{
incoming . SeasonId = season . Id ;
// TODO: figure out how to rebuild playlists
Either < BaseError , PlexEpisode > maybeEpisode = await _ televisionRepository
. GetOrAddPlexEpisode ( plexMediaSourceLibrary , incoming )
. GetOrAddPlexEpisode ( library , incoming )
. BindT ( existing = > UpdateMetadata ( existing , incoming ) )
. BindT (
existing = > UpdateStatistics (
existing ,
incoming ,
plexMediaSourceLibrary ,
library ,
connection ,
token ) )
. BindT ( existing = > UpdateArtwork ( existing , incoming ) ) ;
@ -401,7 +436,7 @@ namespace ErsatzTV.Core.Plex
@@ -401,7 +436,7 @@ namespace ErsatzTV.Core.Plex
} ) ;
}
var episodeKeys = episodeEntri es. Map ( s = > s . Key ) . ToList ( ) ;
var episodeKeys = validEpisod es. Map ( s = > s . Key ) . ToList ( ) ;
List < int > ids = await _ televisionRepository . RemoveMissingPlexEpisodes ( season . Key , episodeKeys ) ;
await _ searchIndex . RemoveItems ( ids ) ;
_ searchIndex . Commit ( ) ;
@ -412,7 +447,7 @@ namespace ErsatzTV.Core.Plex
@@ -412,7 +447,7 @@ namespace ErsatzTV.Core.Plex
{
_l ogger . LogWarning (
"Error synchronizing plex library {Path}: {Error}" ,
p lexMediaSourceL ibrary. Name ,
library . Name ,
error . Value ) ;
return Left < BaseError , Unit > ( error ) . AsTask ( ) ;