Browse Source

fix plex scanner crash (#1192)

pull/1193/head
Jason Dove 3 years ago committed by GitHub
parent
commit
40e79a3a14
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 75
      ErsatzTV.Infrastructure/Data/Repositories/PlexTelevisionRepository.cs
  2. 73
      ErsatzTV.Infrastructure/Plex/PlexServerApiClient.cs

75
ErsatzTV.Infrastructure/Data/Repositories/PlexTelevisionRepository.cs

@ -254,7 +254,11 @@ public class PlexTelevisionRepository : IPlexTelevisionRepository @@ -254,7 +254,11 @@ public class PlexTelevisionRepository : IPlexTelevisionRepository
// deepScan isn't needed here since we create our own plex etags
if (plexEpisode.Etag != item.Etag)
{
await UpdateEpisodePath(dbContext, plexEpisode, item);
foreach (BaseError error in await UpdateEpisodePath(dbContext, plexEpisode, item))
{
return error;
}
result.IsUpdated = true;
}
@ -465,37 +469,48 @@ public class PlexTelevisionRepository : IPlexTelevisionRepository @@ -465,37 +469,48 @@ public class PlexTelevisionRepository : IPlexTelevisionRepository
}
}
private async Task UpdateEpisodePath(TvContext dbContext, PlexEpisode existing, PlexEpisode incoming)
private async Task<Option<BaseError>> UpdateEpisodePath(
TvContext dbContext,
PlexEpisode existing,
PlexEpisode incoming)
{
// library path is used for search indexing later
incoming.LibraryPath = existing.LibraryPath;
incoming.Id = existing.Id;
try
{
// library path is used for search indexing later
incoming.LibraryPath = existing.LibraryPath;
incoming.Id = existing.Id;
// version
MediaVersion version = existing.MediaVersions.Head();
MediaVersion incomingVersion = incoming.MediaVersions.Head();
version.Name = incomingVersion.Name;
version.DateAdded = incomingVersion.DateAdded;
// version
MediaVersion version = existing.MediaVersions.Head();
MediaVersion incomingVersion = incoming.MediaVersions.Head();
version.Name = incomingVersion.Name;
version.DateAdded = incomingVersion.DateAdded;
await dbContext.Connection.ExecuteAsync(
@"UPDATE MediaVersion SET Name = @Name, DateAdded = @DateAdded WHERE Id = @Id",
new { version.Name, version.DateAdded, version.Id });
// media file
MediaFile file = version.MediaFiles.Head();
MediaFile incomingFile = incomingVersion.MediaFiles.Head();
_logger.LogDebug(
"Updating plex episode (key {Key}) path from {Existing} to {Incoming}",
existing.Key,
file.Path,
incomingFile.Path);
file.Path = incomingFile.Path;
await dbContext.Connection.ExecuteAsync(
@"UPDATE MediaFile SET Path = @Path WHERE Id = @Id",
new { file.Path, file.Id });
await dbContext.Connection.ExecuteAsync(
@"UPDATE MediaVersion SET Name = @Name, DateAdded = @DateAdded WHERE Id = @Id",
new { version.Name, version.DateAdded, version.Id });
// media file
MediaFile file = version.MediaFiles.Head();
MediaFile incomingFile = incomingVersion.MediaFiles.Head();
_logger.LogDebug(
"Updating plex episode (key {Key}) path from {Existing} to {Incoming}",
existing.Key,
file.Path,
incomingFile.Path);
file.Path = incomingFile.Path;
await dbContext.Connection.ExecuteAsync(
@"UPDATE MediaFile SET Path = @Path WHERE Id = @Id",
new { file.Path, file.Id });
return Option<BaseError>.None;
}
catch (Exception)
{
return BaseError.New("Failed to update episode path");
}
}
}

73
ErsatzTV.Infrastructure/Plex/PlexServerApiClient.cs

@ -180,7 +180,7 @@ public class PlexServerApiClient : IPlexServerApiClient @@ -180,7 +180,7 @@ public class PlexServerApiClient : IPlexServerApiClient
{
return xmlService.GetSeasonChildren(seasonMetadataKey, skip, pageSize, token.AuthToken)
.Map(r => r.Metadata.Filter(m => m.Media.Count > 0 && m.Media[0].Part.Count > 0))
.Map(list => list.Map(metadata => ProjectToEpisode(metadata, library.MediaSourceId)));
.Map(list => list.Bind(metadata => ProjectToEpisodes(metadata, library.MediaSourceId)));
}
return GetPagedLibraryContents(connection, CountItems, GetItems);
@ -814,45 +814,52 @@ public class PlexServerApiClient : IPlexServerApiClient @@ -814,45 +814,52 @@ public class PlexServerApiClient : IPlexServerApiClient
return season;
}
private PlexEpisode ProjectToEpisode(PlexXmlMetadataResponse response, int mediaSourceId)
private IEnumerable<PlexEpisode> ProjectToEpisodes(PlexXmlMetadataResponse response, int mediaSourceId)
{
PlexMediaResponse<PlexXmlPartResponse> media = response.Media.Head();
PlexXmlPartResponse part = media.Part.Head();
DateTime dateAdded = DateTimeOffset.FromUnixTimeSeconds(response.AddedAt).DateTime;
DateTime lastWriteTime = DateTimeOffset.FromUnixTimeSeconds(response.UpdatedAt).DateTime;
var result = new List<PlexEpisode>();
EpisodeMetadata metadata = ProjectToEpisodeMetadata(response, mediaSourceId);
var version = new MediaVersion
// TODO: actually use all media records
foreach (PlexMediaResponse<PlexXmlPartResponse> media in response.Media.HeadOrNone())
{
Name = "Main",
Duration = TimeSpan.FromMilliseconds(media.Duration),
Width = media.Width,
Height = media.Height,
DateAdded = dateAdded,
DateUpdated = lastWriteTime,
MediaFiles = new List<MediaFile>
PlexXmlPartResponse part = media.Part.Head();
DateTime dateAdded = DateTimeOffset.FromUnixTimeSeconds(response.AddedAt).DateTime;
DateTime lastWriteTime = DateTimeOffset.FromUnixTimeSeconds(response.UpdatedAt).DateTime;
EpisodeMetadata metadata = ProjectToEpisodeMetadata(response, mediaSourceId);
var version = new MediaVersion
{
new PlexMediaFile
Name = "Main",
Duration = TimeSpan.FromMilliseconds(media.Duration),
Width = media.Width,
Height = media.Height,
DateAdded = dateAdded,
DateUpdated = lastWriteTime,
MediaFiles = new List<MediaFile>
{
PlexId = part.Id,
Key = part.Key,
Path = part.File
}
},
// specifically omit stream details
Streams = new List<MediaStream>()
};
new PlexMediaFile
{
PlexId = part.Id,
Key = part.Key,
Path = part.File
}
},
// specifically omit stream details
Streams = new List<MediaStream>()
};
var episode = new PlexEpisode
{
Key = response.Key,
Etag = _plexEtag.ForEpisode(response),
EpisodeMetadata = new List<EpisodeMetadata> { metadata },
MediaVersions = new List<MediaVersion> { version },
TraktListItems = new List<TraktListItem>()
};
var episode = new PlexEpisode
{
Key = response.Key,
Etag = _plexEtag.ForEpisode(response),
EpisodeMetadata = new List<EpisodeMetadata> { metadata },
MediaVersions = new List<MediaVersion> { version },
TraktListItems = new List<TraktListItem>()
};
result.Add(episode);
}
return episode;
return result;
}
private EpisodeMetadata ProjectToEpisodeMetadata(PlexMetadataResponse response, int mediaSourceId)

Loading…
Cancel
Save