Browse Source

mysql media server library scan fixes (#1491)

* fix some mysql movie library updates

* fix some mysql show library updates

* update dependencies
pull/1492/head
Jason Dove 2 years ago committed by GitHub
parent
commit
8f5b181372
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 1
      CHANGELOG.md
  2. 2
      ErsatzTV.Application/ErsatzTV.Application.csproj
  3. 2
      ErsatzTV.Core.Tests/ErsatzTV.Core.Tests.csproj
  4. 4
      ErsatzTV.Core/ErsatzTV.Core.csproj
  5. 2
      ErsatzTV.Core/Interfaces/Repositories/IMediaServerMovieRepository.cs
  6. 6
      ErsatzTV.Core/Interfaces/Repositories/IMediaServerTelevisionRepository.cs
  7. 2
      ErsatzTV.FFmpeg/ErsatzTV.FFmpeg.csproj
  8. 2
      ErsatzTV.Infrastructure.MySql/ErsatzTV.Infrastructure.MySql.csproj
  9. 6
      ErsatzTV.Infrastructure.Sqlite/ErsatzTV.Infrastructure.Sqlite.csproj
  10. 2
      ErsatzTV.Infrastructure.Tests/ErsatzTV.Infrastructure.Tests.csproj
  11. 24
      ErsatzTV.Infrastructure/Data/Repositories/EmbyMovieRepository.cs
  12. 64
      ErsatzTV.Infrastructure/Data/Repositories/EmbyTelevisionRepository.cs
  13. 24
      ErsatzTV.Infrastructure/Data/Repositories/JellyfinMovieRepository.cs
  14. 66
      ErsatzTV.Infrastructure/Data/Repositories/JellyfinTelevisionRepository.cs
  15. 24
      ErsatzTV.Infrastructure/Data/Repositories/PlexMovieRepository.cs
  16. 62
      ErsatzTV.Infrastructure/Data/Repositories/PlexTelevisionRepository.cs
  17. 10
      ErsatzTV.Infrastructure/ErsatzTV.Infrastructure.csproj
  18. 4
      ErsatzTV.Scanner.Tests/ErsatzTV.Scanner.Tests.csproj
  19. 3
      ErsatzTV.Scanner/Core/Metadata/MediaServerMovieLibraryScanner.cs
  20. 9
      ErsatzTV.Scanner/Core/Metadata/MediaServerTelevisionLibraryScanner.cs
  21. 2
      ErsatzTV.Scanner/ErsatzTV.Scanner.csproj
  22. 20
      ErsatzTV/ErsatzTV.csproj

1
CHANGELOG.md

@ -32,6 +32,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). @@ -32,6 +32,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
- Fix QSV HLS segment duration
- This behavior caused extremely slow QSV stream starts
- Fix displaying multiple languages in UI for movies, artists, shows
- Fix MySQL queries that could fail during media server library scans
### Changed
- Upgrade ffmpeg to 6.1, which is now *required* for all installs

2
ErsatzTV.Application/ErsatzTV.Application.csproj

@ -21,7 +21,7 @@ @@ -21,7 +21,7 @@
</PackageReference>
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
<PackageReference Include="Serilog.Formatting.Compact.Reader" Version="2.0.0" />
<PackageReference Include="Winista.MimeDetect" Version="1.0.1" />
<PackageReference Include="Winista.MimeDetect" Version="1.1.0" />
</ItemGroup>
<ItemGroup>

2
ErsatzTV.Core.Tests/ErsatzTV.Core.Tests.csproj

@ -10,7 +10,7 @@ @@ -10,7 +10,7 @@
<PackageReference Include="Bugsnag" Version="3.1.0" />
<PackageReference Include="CliWrap" Version="3.6.4" />
<PackageReference Include="FluentAssertions" Version="6.12.0" />
<PackageReference Include="LanguageExt.Core" Version="4.4.6" />
<PackageReference Include="LanguageExt.Core" Version="4.4.7" />
<PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="7.0.0" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="7.0.0" />
<PackageReference Include="Microsoft.Extensions.Logging" Version="7.0.0" />

4
ErsatzTV.Core/ErsatzTV.Core.csproj

@ -12,8 +12,8 @@ @@ -12,8 +12,8 @@
<PackageReference Include="Bugsnag" Version="3.1.0" />
<PackageReference Include="Destructurama.Attributed" Version="3.1.0" />
<PackageReference Include="Flurl" Version="3.0.7" />
<PackageReference Include="LanguageExt.Core" Version="4.4.6" />
<PackageReference Include="LanguageExt.Transformers" Version="4.4.6" />
<PackageReference Include="LanguageExt.Core" Version="4.4.7" />
<PackageReference Include="LanguageExt.Transformers" Version="4.4.7" />
<PackageReference Include="MediatR" Version="12.1.1" />
<PackageReference Include="Microsoft.Extensions.Caching.Abstractions" Version="7.0.0" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="7.0.0" />

2
ErsatzTV.Core/Interfaces/Repositories/IMediaServerMovieRepository.cs

@ -8,7 +8,7 @@ public interface IMediaServerMovieRepository<in TLibrary, TMovie, TEtag> where T @@ -8,7 +8,7 @@ public interface IMediaServerMovieRepository<in TLibrary, TMovie, TEtag> where T
where TEtag : MediaServerItemEtag
{
Task<List<TEtag>> GetExistingMovies(TLibrary library);
Task<bool> FlagNormal(TLibrary library, TMovie movie);
Task<Option<int>> FlagNormal(TLibrary library, TMovie movie);
Task<Option<int>> FlagUnavailable(TLibrary library, TMovie movie);
Task<Option<int>> FlagRemoteOnly(TLibrary library, TMovie movie);
Task<List<int>> FlagFileNotFound(TLibrary library, List<string> movieItemIds);

6
ErsatzTV.Core/Interfaces/Repositories/IMediaServerTelevisionRepository.cs

@ -18,9 +18,9 @@ public interface IMediaServerTelevisionRepository<in TLibrary, TShow, TSeason, T @@ -18,9 +18,9 @@ public interface IMediaServerTelevisionRepository<in TLibrary, TShow, TSeason, T
Task<Unit> SetEtag(TShow show, string etag);
Task<Unit> SetEtag(TSeason season, string etag);
Task<Unit> SetEtag(TEpisode episode, string etag);
Task<bool> FlagNormal(TLibrary library, TEpisode episode);
Task<bool> FlagNormal(TLibrary library, TSeason season);
Task<bool> FlagNormal(TLibrary library, TShow show);
Task<Option<int>> FlagNormal(TLibrary library, TEpisode episode);
Task<Option<int>> FlagNormal(TLibrary library, TSeason season);
Task<Option<int>> FlagNormal(TLibrary library, TShow show);
Task<List<int>> FlagFileNotFoundShows(TLibrary library, List<string> showItemIds);
Task<List<int>> FlagFileNotFoundSeasons(TLibrary library, List<string> seasonItemIds);
Task<List<int>> FlagFileNotFoundEpisodes(TLibrary library, List<string> episodeItemIds);

2
ErsatzTV.FFmpeg/ErsatzTV.FFmpeg.csproj

@ -10,7 +10,7 @@ @@ -10,7 +10,7 @@
<ItemGroup>
<PackageReference Include="CliWrap" Version="3.6.4" />
<PackageReference Include="LanguageExt.Core" Version="4.4.6" />
<PackageReference Include="LanguageExt.Core" Version="4.4.7" />
<PackageReference Include="Microsoft.Extensions.Caching.Abstractions" Version="7.0.0" />
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="7.0.1" />
</ItemGroup>

2
ErsatzTV.Infrastructure.MySql/ErsatzTV.Infrastructure.MySql.csproj

@ -18,7 +18,7 @@ @@ -18,7 +18,7 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="7.0.11" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="7.0.13" />
<PackageReference Include="Pomelo.EntityFrameworkCore.MySql" Version="7.0.0" />
</ItemGroup>

6
ErsatzTV.Infrastructure.Sqlite/ErsatzTV.Infrastructure.Sqlite.csproj

@ -14,9 +14,9 @@ @@ -14,9 +14,9 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="Dapper" Version="2.1.4" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="7.0.11" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="7.0.11" />
<PackageReference Include="Dapper" Version="2.1.15" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="7.0.13" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="7.0.13" />
</ItemGroup>

2
ErsatzTV.Infrastructure.Tests/ErsatzTV.Infrastructure.Tests.csproj

@ -14,7 +14,7 @@ @@ -14,7 +14,7 @@
<PackageReference Include="NSubstitute" Version="5.1.0" />
<PackageReference Include="NUnit" Version="3.13.3" />
<PackageReference Include="NUnit3TestAdapter" Version="4.5.0" />
<PackageReference Include="NUnit.Analyzers" Version="3.8.0">
<PackageReference Include="NUnit.Analyzers" Version="3.9.0">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>

24
ErsatzTV.Infrastructure/Data/Repositories/EmbyMovieRepository.cs

@ -35,19 +35,27 @@ public class EmbyMovieRepository : IEmbyMovieRepository @@ -35,19 +35,27 @@ public class EmbyMovieRepository : IEmbyMovieRepository
.Map(result => result.ToList());
}
public async Task<bool> FlagNormal(EmbyLibrary library, EmbyMovie movie)
public async Task<Option<int>> FlagNormal(EmbyLibrary library, EmbyMovie movie)
{
await using TvContext dbContext = await _dbContextFactory.CreateDbContextAsync();
movie.State = MediaItemState.Normal;
return await dbContext.Connection.ExecuteAsync(
@"UPDATE MediaItem SET State = 0 WHERE Id IN
(SELECT EmbyMovie.Id FROM EmbyMovie
INNER JOIN MediaItem MI ON MI.Id = EmbyMovie.Id
INNER JOIN LibraryPath LP on MI.LibraryPathId = LP.Id AND LibraryId = @LibraryId
WHERE EmbyMovie.ItemId = @ItemId)",
new { LibraryId = library.Id, movie.ItemId }).Map(count => count > 0);
Option<int> maybeId = await dbContext.Connection.ExecuteScalarAsync<int>(
@"SELECT EmbyMovie.Id FROM EmbyMovie
INNER JOIN MediaItem MI ON MI.Id = EmbyMovie.Id
INNER JOIN LibraryPath LP on MI.LibraryPathId = LP.Id AND LibraryId = @LibraryId
WHERE EmbyMovie.ItemId = @ItemId",
new { LibraryId = library.Id, movie.ItemId });
foreach (int id in maybeId)
{
return await dbContext.Connection.ExecuteAsync(
@"UPDATE MediaItem SET State = 0 WHERE Id = @Id",
new { Id = id }).Map(count => count > 0 ? Some(id) : None);
}
return None;
}
public async Task<Option<int>> FlagUnavailable(EmbyLibrary library, EmbyMovie movie)

64
ErsatzTV.Infrastructure/Data/Repositories/EmbyTelevisionRepository.cs

@ -205,49 +205,73 @@ public class EmbyTelevisionRepository : IEmbyTelevisionRepository @@ -205,49 +205,73 @@ public class EmbyTelevisionRepository : IEmbyTelevisionRepository
new { Etag = etag, episode.Id }).Map(_ => Unit.Default);
}
public async Task<bool> FlagNormal(EmbyLibrary library, EmbyEpisode episode)
public async Task<Option<int>> FlagNormal(EmbyLibrary library, EmbyEpisode episode)
{
await using TvContext dbContext = await _dbContextFactory.CreateDbContextAsync();
episode.State = MediaItemState.Normal;
return await dbContext.Connection.ExecuteAsync(
@"UPDATE MediaItem SET State = 0 WHERE Id IN
(SELECT EmbyEpisode.Id FROM EmbyEpisode
Option<int> maybeId = await dbContext.Connection.ExecuteScalarAsync<int>(
@"SELECT EmbyEpisode.Id FROM EmbyEpisode
INNER JOIN MediaItem MI ON MI.Id = EmbyEpisode.Id
INNER JOIN LibraryPath LP on MI.LibraryPathId = LP.Id AND LibraryId = @LibraryId
WHERE EmbyEpisode.ItemId = @ItemId)",
new { LibraryId = library.Id, episode.ItemId }).Map(count => count > 0);
WHERE EmbyEpisode.ItemId = @ItemId",
new { LibraryId = library.Id, episode.ItemId });
foreach (int id in maybeId)
{
return await dbContext.Connection.ExecuteAsync(
@"UPDATE MediaItem SET State = 0 WHERE Id = @Id",
new { Id = id }).Map(count => count > 0 ? Some(id) : None);
}
return None;
}
public async Task<bool> FlagNormal(EmbyLibrary library, EmbySeason season)
public async Task<Option<int>> FlagNormal(EmbyLibrary library, EmbySeason season)
{
await using TvContext dbContext = await _dbContextFactory.CreateDbContextAsync();
season.State = MediaItemState.Normal;
return await dbContext.Connection.ExecuteAsync(
@"UPDATE MediaItem SET State = 0 WHERE Id IN
(SELECT EmbySeason.Id FROM EmbySeason
Option<int> maybeId = await dbContext.Connection.ExecuteScalarAsync<int>(
@"SELECT EmbySeason.Id FROM EmbySeason
INNER JOIN MediaItem MI ON MI.Id = EmbySeason.Id
INNER JOIN LibraryPath LP on MI.LibraryPathId = LP.Id AND LibraryId = @LibraryId
WHERE EmbySeason.ItemId = @ItemId)",
new { LibraryId = library.Id, season.ItemId }).Map(count => count > 0);
WHERE EmbySeason.ItemId = @ItemId",
new { LibraryId = library.Id, season.ItemId });
foreach (int id in maybeId)
{
return await dbContext.Connection.ExecuteAsync(
@"UPDATE MediaItem SET State = 0 WHERE Id = @Id",
new { Id = id }).Map(count => count > 0 ? Some(id) : None);
}
return None;
}
public async Task<bool> FlagNormal(EmbyLibrary library, EmbyShow show)
public async Task<Option<int>> FlagNormal(EmbyLibrary library, EmbyShow show)
{
await using TvContext dbContext = await _dbContextFactory.CreateDbContextAsync();
show.State = MediaItemState.Normal;
return await dbContext.Connection.ExecuteAsync(
@"UPDATE MediaItem SET State = 0 WHERE Id IN
(SELECT EmbyShow.Id FROM EmbyShow
Option<int> maybeId = await dbContext.Connection.ExecuteScalarAsync<int>(
@"SELECT EmbyShow.Id FROM EmbyShow
INNER JOIN MediaItem MI ON MI.Id = EmbyShow.Id
INNER JOIN LibraryPath LP on MI.LibraryPathId = LP.Id AND LibraryId = @LibraryId
WHERE EmbyShow.ItemId = @ItemId)",
new { LibraryId = library.Id, show.ItemId }).Map(count => count > 0);
WHERE EmbyShow.ItemId = @ItemId",
new { LibraryId = library.Id, show.ItemId });
foreach (int id in maybeId)
{
return await dbContext.Connection.ExecuteAsync(
@"UPDATE MediaItem SET State = 0 WHERE Id = @Id",
new { Id = id }).Map(count => count > 0 ? Some(id) : None);
}
return None;
}
public async Task<List<int>> FlagFileNotFoundShows(EmbyLibrary library, List<string> showItemIds)

24
ErsatzTV.Infrastructure/Data/Repositories/JellyfinMovieRepository.cs

@ -37,19 +37,27 @@ public class JellyfinMovieRepository : IJellyfinMovieRepository @@ -37,19 +37,27 @@ public class JellyfinMovieRepository : IJellyfinMovieRepository
.Map(result => result.ToList());
}
public async Task<bool> FlagNormal(JellyfinLibrary library, JellyfinMovie movie)
public async Task<Option<int>> FlagNormal(JellyfinLibrary library, JellyfinMovie movie)
{
await using TvContext dbContext = await _dbContextFactory.CreateDbContextAsync();
movie.State = MediaItemState.Normal;
return await dbContext.Connection.ExecuteAsync(
@"UPDATE MediaItem SET State = 0 WHERE Id IN
(SELECT JellyfinMovie.Id FROM JellyfinMovie
INNER JOIN MediaItem MI ON MI.Id = JellyfinMovie.Id
INNER JOIN LibraryPath LP on MI.LibraryPathId = LP.Id AND LibraryId = @LibraryId
WHERE JellyfinMovie.ItemId = @ItemId)",
new { LibraryId = library.Id, movie.ItemId }).Map(count => count > 0);
Option<int> maybeId = await dbContext.Connection.ExecuteScalarAsync<int>(
@"SELECT JellyfinMovie.Id FROM JellyfinMovie
INNER JOIN MediaItem MI ON MI.Id = JellyfinMovie.Id
INNER JOIN LibraryPath LP on MI.LibraryPathId = LP.Id AND LibraryId = @LibraryId
WHERE JellyfinMovie.ItemId = @ItemId",
new { LibraryId = library.Id, movie.ItemId });
foreach (int id in maybeId)
{
return await dbContext.Connection.ExecuteAsync(
@"UPDATE MediaItem SET State = 0 WHERE Id = @Id",
new { Id = id }).Map(count => count > 0 ? Some(id) : None);
}
return None;
}
public async Task<Option<int>> FlagUnavailable(JellyfinLibrary library, JellyfinMovie movie)

66
ErsatzTV.Infrastructure/Data/Repositories/JellyfinTelevisionRepository.cs

@ -209,49 +209,73 @@ public class JellyfinTelevisionRepository : IJellyfinTelevisionRepository @@ -209,49 +209,73 @@ public class JellyfinTelevisionRepository : IJellyfinTelevisionRepository
new { Etag = etag, episode.Id }).Map(_ => Unit.Default);
}
public async Task<bool> FlagNormal(JellyfinLibrary library, JellyfinEpisode episode)
public async Task<Option<int>> FlagNormal(JellyfinLibrary library, JellyfinEpisode episode)
{
await using TvContext dbContext = await _dbContextFactory.CreateDbContextAsync();
episode.State = MediaItemState.Normal;
return await dbContext.Connection.ExecuteAsync(
@"UPDATE MediaItem SET State = 0 WHERE Id IN
(SELECT JellyfinEpisode.Id FROM JellyfinEpisode
Option<int> maybeId = await dbContext.Connection.ExecuteScalarAsync<int>(
@"SELECT JellyfinEpisode.Id FROM JellyfinEpisode
INNER JOIN MediaItem MI ON MI.Id = JellyfinEpisode.Id
INNER JOIN LibraryPath LP on MI.LibraryPathId = LP.Id AND LibraryId = @LibraryId
WHERE JellyfinEpisode.ItemId = @ItemId)",
new { LibraryId = library.Id, episode.ItemId }).Map(count => count > 0);
WHERE JellyfinEpisode.ItemId = @ItemId",
new { LibraryId = library.Id, episode.ItemId });
foreach (int id in maybeId)
{
return await dbContext.Connection.ExecuteAsync(
@"UPDATE MediaItem SET State = 0 WHERE Id = @Id",
new { Id = id }).Map(count => count > 0 ? Some(id) : None);
}
return None;
}
public async Task<bool> FlagNormal(JellyfinLibrary library, JellyfinSeason season)
public async Task<Option<int>> FlagNormal(JellyfinLibrary library, JellyfinSeason season)
{
await using TvContext dbContext = await _dbContextFactory.CreateDbContextAsync();
season.State = MediaItemState.Normal;
return await dbContext.Connection.ExecuteAsync(
@"UPDATE MediaItem SET State = 0 WHERE Id IN
(SELECT JellyfinSeason.Id FROM JellyfinSeason
Option<int> maybeId = await dbContext.Connection.ExecuteScalarAsync<int>(
@"SELECT JellyfinSeason.Id FROM JellyfinSeason
INNER JOIN MediaItem MI ON MI.Id = JellyfinSeason.Id
INNER JOIN LibraryPath LP on MI.LibraryPathId = LP.Id AND LibraryId = @LibraryId
WHERE JellyfinSeason.ItemId = @ItemId)",
new { LibraryId = library.Id, season.ItemId }).Map(count => count > 0);
WHERE JellyfinSeason.ItemId = @ItemId",
new { LibraryId = library.Id, season.ItemId });
foreach (int id in maybeId)
{
return await dbContext.Connection.ExecuteAsync(
@"UPDATE MediaItem SET State = 0 WHERE Id = @Id",
new { Id = id }).Map(count => count > 0 ? Some(id) : None);
}
return None;
}
public async Task<bool> FlagNormal(JellyfinLibrary library, JellyfinShow show)
public async Task<Option<int>> FlagNormal(JellyfinLibrary library, JellyfinShow show)
{
await using TvContext dbContext = await _dbContextFactory.CreateDbContextAsync();
show.State = MediaItemState.Normal;
return await dbContext.Connection.ExecuteAsync(
@"UPDATE MediaItem SET State = 0 WHERE Id IN
(SELECT JellyfinShow.Id FROM JellyfinShow
Option<int> maybeId = await dbContext.Connection.ExecuteScalarAsync<int>(
@"SELECT JellyfinShow.Id FROM JellyfinShow
INNER JOIN MediaItem MI ON MI.Id = JellyfinShow.Id
INNER JOIN LibraryPath LP on MI.LibraryPathId = LP.Id AND LibraryId = @LibraryId
WHERE JellyfinShow.ItemId = @ItemId)",
new { LibraryId = library.Id, show.ItemId }).Map(count => count > 0);
WHERE JellyfinShow.ItemId = @ItemId",
new { LibraryId = library.Id, show.ItemId });
foreach (int id in maybeId)
{
return await dbContext.Connection.ExecuteAsync(
@"UPDATE MediaItem SET State = 0 WHERE Id = @Id",
new { Id = id }).Map(count => count > 0 ? Some(id) : None);
}
return None;
}
public async Task<List<int>> FlagFileNotFoundShows(JellyfinLibrary library, List<string> showItemIds)

24
ErsatzTV.Infrastructure/Data/Repositories/PlexMovieRepository.cs

@ -35,19 +35,27 @@ public class PlexMovieRepository : IPlexMovieRepository @@ -35,19 +35,27 @@ public class PlexMovieRepository : IPlexMovieRepository
.Map(result => result.ToList());
}
public async Task<bool> FlagNormal(PlexLibrary library, PlexMovie movie)
public async Task<Option<int>> FlagNormal(PlexLibrary library, PlexMovie movie)
{
await using TvContext dbContext = await _dbContextFactory.CreateDbContextAsync();
movie.State = MediaItemState.Normal;
return await dbContext.Connection.ExecuteAsync(
@"UPDATE MediaItem SET State = 0 WHERE Id IN
(SELECT PlexMovie.Id FROM PlexMovie
INNER JOIN MediaItem MI ON MI.Id = PlexMovie.Id
INNER JOIN LibraryPath LP on MI.LibraryPathId = LP.Id AND LibraryId = @LibraryId
WHERE PlexMovie.Key = @Key)",
new { LibraryId = library.Id, movie.Key }).Map(count => count > 0);
Option<int> maybeId = await dbContext.Connection.ExecuteScalarAsync<int>(
@"SELECT PlexMovie.Id FROM PlexMovie
INNER JOIN MediaItem MI ON MI.Id = PlexMovie.Id
INNER JOIN LibraryPath LP on MI.LibraryPathId = LP.Id AND LibraryId = @LibraryId
WHERE PlexMovie.Key = @Key",
new { LibraryId = library.Id, movie.Key });
foreach (int id in maybeId)
{
return await dbContext.Connection.ExecuteAsync(
@"UPDATE MediaItem SET State = 0 WHERE Id = @Id",
new { Id = id }).Map(count => count > 0 ? Some(id) : None);
}
return None;
}
public async Task<Option<int>> FlagUnavailable(PlexLibrary library, PlexMovie movie)

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

@ -24,49 +24,73 @@ public class PlexTelevisionRepository : IPlexTelevisionRepository @@ -24,49 +24,73 @@ public class PlexTelevisionRepository : IPlexTelevisionRepository
_logger = logger;
}
public async Task<bool> FlagNormal(PlexLibrary library, PlexEpisode episode)
public async Task<Option<int>> FlagNormal(PlexLibrary library, PlexEpisode episode)
{
await using TvContext dbContext = await _dbContextFactory.CreateDbContextAsync();
episode.State = MediaItemState.Normal;
return await dbContext.Connection.ExecuteAsync(
@"UPDATE MediaItem SET State = 0 WHERE Id IN
(SELECT PlexEpisode.Id FROM PlexEpisode
Option<int> maybeId = await dbContext.Connection.ExecuteScalarAsync<int>(
@"SELECT PlexEpisode.Id FROM PlexEpisode
INNER JOIN MediaItem MI ON MI.Id = PlexEpisode.Id
INNER JOIN LibraryPath LP on MI.LibraryPathId = LP.Id AND LibraryId = @LibraryId
WHERE PlexEpisode.Key = @Key)",
new { LibraryId = library.Id, episode.Key }).Map(count => count > 0);
WHERE PlexEpisode.Key = @Key",
new { LibraryId = library.Id, episode.Key });
foreach (int id in maybeId)
{
return await dbContext.Connection.ExecuteAsync(
@"UPDATE MediaItem SET State = 0 WHERE Id = @Id",
new { Id = id }).Map(count => count > 0 ? Some(id) : None);
}
return None;
}
public async Task<bool> FlagNormal(PlexLibrary library, PlexSeason season)
public async Task<Option<int>> FlagNormal(PlexLibrary library, PlexSeason season)
{
await using TvContext dbContext = await _dbContextFactory.CreateDbContextAsync();
season.State = MediaItemState.Normal;
return await dbContext.Connection.ExecuteAsync(
@"UPDATE MediaItem SET State = 0 WHERE Id IN
(SELECT PlexSeason.Id FROM PlexSeason
Option<int> maybeId = await dbContext.Connection.ExecuteScalarAsync<int>(
@"SELECT PlexSeason.Id FROM PlexSeason
INNER JOIN MediaItem MI ON MI.Id = PlexSeason.Id
INNER JOIN LibraryPath LP on MI.LibraryPathId = LP.Id AND LibraryId = @LibraryId
WHERE PlexSeason.Key = @Key)",
new { LibraryId = library.Id, season.Key }).Map(count => count > 0);
WHERE PlexSeason.Key = @Key",
new { LibraryId = library.Id, season.Key });
foreach (int id in maybeId)
{
return await dbContext.Connection.ExecuteAsync(
@"UPDATE MediaItem SET State = 0 WHERE Id = @Id",
new { Id = id }).Map(count => count > 0 ? Some(id) : None);
}
return None;
}
public async Task<bool> FlagNormal(PlexLibrary library, PlexShow show)
public async Task<Option<int>> FlagNormal(PlexLibrary library, PlexShow show)
{
await using TvContext dbContext = await _dbContextFactory.CreateDbContextAsync();
show.State = MediaItemState.Normal;
return await dbContext.Connection.ExecuteAsync(
@"UPDATE MediaItem SET State = 0 WHERE Id IN
(SELECT PlexShow.Id FROM PlexShow
Option<int> maybeId = await dbContext.Connection.ExecuteScalarAsync<int>(
@"SELECT PlexShow.Id FROM PlexShow
INNER JOIN MediaItem MI ON MI.Id = PlexShow.Id
INNER JOIN LibraryPath LP on MI.LibraryPathId = LP.Id AND LibraryId = @LibraryId
WHERE PlexShow.Key = @Key)",
new { LibraryId = library.Id, show.Key }).Map(count => count > 0);
WHERE PlexShow.Key = @Key",
new { LibraryId = library.Id, show.Key });
foreach (int id in maybeId)
{
return await dbContext.Connection.ExecuteAsync(
@"UPDATE MediaItem SET State = 0 WHERE Id = @Id",
new { Id = id }).Map(count => count > 0 ? Some(id) : None);
}
return None;
}
public async Task<Option<int>> FlagUnavailable(PlexLibrary library, PlexEpisode episode)

10
ErsatzTV.Infrastructure/ErsatzTV.Infrastructure.csproj

@ -12,18 +12,18 @@ @@ -12,18 +12,18 @@
<ItemGroup>
<PackageReference Include="Blurhash.ImageSharp" Version="3.0.0" />
<PackageReference Include="CliWrap" Version="3.6.4" />
<PackageReference Include="Dapper" Version="2.1.4" />
<PackageReference Include="Dapper" Version="2.1.15" />
<PackageReference Include="Elastic.Clients.Elasticsearch" Version="8.10.0" />
<PackageReference Include="Jint" Version="3.0.0-beta-2052" />
<PackageReference Include="Jint" Version="3.0.0-beta-2053" />
<PackageReference Include="Lucene.Net" Version="4.8.0-beta00016" />
<PackageReference Include="Lucene.Net.Analysis.Common" Version="4.8.0-beta00016" />
<PackageReference Include="Lucene.Net.QueryParser" Version="4.8.0-beta00016" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="7.0.11" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="7.0.11">
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="7.0.13" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="7.0.13">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="7.0.11" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="7.0.13" />
<PackageReference Include="Microsoft.VisualStudio.Threading.Analyzers" Version="17.7.30">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>

4
ErsatzTV.Scanner.Tests/ErsatzTV.Scanner.Tests.csproj

@ -10,12 +10,12 @@ @@ -10,12 +10,12 @@
<ItemGroup>
<PackageReference Include="FluentAssertions" Version="6.12.0" />
<PackageReference Include="LanguageExt.Core" Version="4.4.6" />
<PackageReference Include="LanguageExt.Core" Version="4.4.7" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.7.2" />
<PackageReference Include="NSubstitute" Version="5.1.0" />
<PackageReference Include="NUnit" Version="3.13.3" />
<PackageReference Include="NUnit3TestAdapter" Version="4.5.0" />
<PackageReference Include="NUnit.Analyzers" Version="3.8.0">
<PackageReference Include="NUnit.Analyzers" Version="3.9.0">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>

3
ErsatzTV.Scanner/Core/Metadata/MediaServerMovieLibraryScanner.cs

@ -178,7 +178,8 @@ public abstract class MediaServerMovieLibraryScanner<TConnectionParameters, TLib @@ -178,7 +178,8 @@ public abstract class MediaServerMovieLibraryScanner<TConnectionParameters, TLib
if (_localFileSystem.FileExists(result.LocalPath))
{
if (await movieRepository.FlagNormal(library, result.Item))
Option<int> flagResult = await movieRepository.FlagNormal(library, result.Item);
if (flagResult.IsSome)
{
result.IsUpdated = true;
}

9
ErsatzTV.Scanner/Core/Metadata/MediaServerTelevisionLibraryScanner.cs

@ -180,7 +180,8 @@ public abstract class MediaServerTelevisionLibraryScanner<TConnectionParameters, @@ -180,7 +180,8 @@ public abstract class MediaServerTelevisionLibraryScanner<TConnectionParameters,
await televisionRepository.SetEtag(result.Item, MediaServerEtag(incoming));
if (await televisionRepository.FlagNormal(library, result.Item))
Option<int> flagResult = await televisionRepository.FlagNormal(library, result.Item);
if (flagResult.IsSome)
{
result.IsUpdated = true;
}
@ -364,7 +365,8 @@ public abstract class MediaServerTelevisionLibraryScanner<TConnectionParameters, @@ -364,7 +365,8 @@ public abstract class MediaServerTelevisionLibraryScanner<TConnectionParameters,
await televisionRepository.SetEtag(result.Item, MediaServerEtag(incoming));
if (await televisionRepository.FlagNormal(library, result.Item))
Option<int> flagResult = await televisionRepository.FlagNormal(library, result.Item);
if (flagResult.IsSome)
{
result.IsUpdated = true;
}
@ -498,7 +500,8 @@ public abstract class MediaServerTelevisionLibraryScanner<TConnectionParameters, @@ -498,7 +500,8 @@ public abstract class MediaServerTelevisionLibraryScanner<TConnectionParameters,
if (_localFileSystem.FileExists(result.LocalPath))
{
if (await televisionRepository.FlagNormal(library, result.Item))
Option<int> flagResult = await televisionRepository.FlagNormal(library, result.Item);
if (flagResult.IsSome)
{
result.IsUpdated = true;
}

2
ErsatzTV.Scanner/ErsatzTV.Scanner.csproj

@ -22,7 +22,7 @@ @@ -22,7 +22,7 @@
<ItemGroup>
<PackageReference Include="CliWrap" Version="3.6.4" />
<PackageReference Include="Humanizer.Core" Version="2.14.1" />
<PackageReference Include="LanguageExt.Core" Version="4.4.6" />
<PackageReference Include="LanguageExt.Core" Version="4.4.7" />
<PackageReference Include="MediatR" Version="12.1.1" />
<PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="7.0.0" />
<PackageReference Include="Microsoft.Extensions.Configuration" Version="7.0.0" />

20
ErsatzTV/ErsatzTV.csproj

@ -57,17 +57,17 @@ @@ -57,17 +57,17 @@
<ItemGroup>
<PackageReference Include="Blazored.FluentValidation" Version="2.1.0" />
<PackageReference Include="Bugsnag.AspNet.Core" Version="3.1.0" />
<PackageReference Include="FluentValidation" Version="11.7.1" />
<PackageReference Include="FluentValidation" Version="11.8.0" />
<PackageReference Include="FluentValidation.AspNetCore" Version="11.3.0" />
<PackageReference Include="HtmlSanitizer" Version="8.0.723" />
<PackageReference Include="LanguageExt.Core" Version="4.4.6" />
<PackageReference Include="HtmlSanitizer" Version="8.0.746" />
<PackageReference Include="LanguageExt.Core" Version="4.4.7" />
<PackageReference Include="Markdig" Version="0.33.0" />
<PackageReference Include="MediatR.Courier.DependencyInjection" Version="5.0.0" />
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="7.0.11" />
<PackageReference Include="Microsoft.AspNetCore.Authentication.OpenIdConnect" Version="7.0.11" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="7.0.11" />
<PackageReference Include="Microsoft.AspNetCore.SpaServices.Extensions" Version="7.0.11" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="7.0.11">
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="7.0.13" />
<PackageReference Include="Microsoft.AspNetCore.Authentication.OpenIdConnect" Version="7.0.13" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="7.0.13" />
<PackageReference Include="Microsoft.AspNetCore.SpaServices.Extensions" Version="7.0.13" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="7.0.13">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
@ -75,8 +75,8 @@ @@ -75,8 +75,8 @@
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="MudBlazor" Version="6.10.0" />
<PackageReference Include="NaturalSort.Extension" Version="4.0.0" />
<PackageReference Include="MudBlazor" Version="6.11.0" />
<PackageReference Include="NaturalSort.Extension" Version="4.1.0" />
<PackageReference Include="Refit.HttpClientFactory" Version="7.0.0" />
<PackageReference Include="Serilog" Version="3.0.1" />
<PackageReference Include="Serilog.AspNetCore" Version="7.0.0" />

Loading…
Cancel
Save