add movie and show genres (#61)

* load movie genres from sidecar metadata

* search movie and tv show genres

* rebuild all playouts (needed after time zone fix)

* code cleanup

* fix duplicate tv show search results
This commit is contained in:
Jason Dove
2021-03-11 02:42:04 +00:00
committed by GitHub
parent c016cac8d4
commit 76d6725dd5
25 changed files with 5037 additions and 22 deletions
@@ -13,6 +13,10 @@ namespace ErsatzTV.Infrastructure.Data.Configurations
builder.HasMany(mm => mm.Artwork)
.WithOne()
.OnDelete(DeleteBehavior.Cascade);
builder.HasMany(mm => mm.Genres)
.WithOne()
.OnDelete(DeleteBehavior.Cascade);
}
}
}
@@ -13,6 +13,10 @@ namespace ErsatzTV.Infrastructure.Data.Configurations
builder.HasMany(sm => sm.Artwork)
.WithOne()
.OnDelete(DeleteBehavior.Cascade);
builder.HasMany(mm => mm.Genres)
.WithOne()
.OnDelete(DeleteBehavior.Cascade);
}
}
}
@@ -35,6 +35,8 @@ namespace ErsatzTV.Infrastructure.Data.Repositories
return await dbContext.Movies
.Include(m => m.MovieMetadata)
.ThenInclude(m => m.Artwork)
.Include(m => m.MovieMetadata)
.ThenInclude(m => m.Genres)
.OrderBy(m => m.Id)
.SingleOrDefaultAsync(m => m.Id == movieId)
.Map(Optional);
@@ -45,6 +47,8 @@ namespace ErsatzTV.Infrastructure.Data.Repositories
Option<Movie> maybeExisting = await _dbContext.Movies
.Include(i => i.MovieMetadata)
.ThenInclude(mm => mm.Artwork)
.Include(i => i.MovieMetadata)
.ThenInclude(mm => mm.Genres)
.Include(i => i.LibraryPath)
.Include(i => i.MediaVersions)
.ThenInclude(mv => mv.MediaFiles)
@@ -21,7 +21,7 @@ namespace ErsatzTV.Infrastructure.Data.Repositories
_dbConnection = dbConnection;
}
public async Task<List<MediaItem>> SearchMediaItems(string query)
public async Task<List<MediaItem>> SearchMediaItemsByTitle(string query)
{
List<int> ids = await _dbConnection.QueryAsync<int>(
@"SELECT M.Id FROM Movie M
@@ -30,7 +30,8 @@ namespace ErsatzTV.Infrastructure.Data.Repositories
UNION
SELECT S.Id FROM Show S
INNER JOIN ShowMetadata SM on S.Id = SM.ShowId
WHERE SM.Title LIKE @Query",
WHERE SM.Title LIKE @Query
GROUP BY SM.Title, SM.Year",
new { Query = $"%{query}%" })
.Map(results => results.ToList());
@@ -44,5 +45,32 @@ namespace ErsatzTV.Infrastructure.Data.Repositories
.OfType<MediaItem>()
.ToListAsync();
}
public async Task<List<MediaItem>> SearchMediaItemsByGenre(string genre)
{
List<int> ids = await _dbConnection.QueryAsync<int>(
@"SELECT M.Id FROM Movie M
INNER JOIN MovieMetadata MM on M.Id = MM.MovieId
INNER JOIN Genre G on MM.Id = G.MovieMetadataId
WHERE G.Name LIKE @Query
UNION
SELECT S.Id FROM Show S
INNER JOIN ShowMetadata SM on S.Id = SM.ShowId
INNER JOIN Genre G2 on SM.Id = G2.ShowMetadataId
WHERE G2.Name LIKE @Query
GROUP BY SM.Title, SM.Year",
new { Query = genre })
.Map(results => results.ToList());
await using TvContext context = _dbContextFactory.CreateDbContext();
return await context.MediaItems
.Filter(m => ids.Contains(m.Id))
.Include(m => (m as Movie).MovieMetadata)
.ThenInclude(mm => mm.Artwork)
.Include(m => (m as Show).ShowMetadata)
.ThenInclude(mm => mm.Artwork)
.OfType<MediaItem>()
.ToListAsync();
}
}
}
@@ -55,6 +55,8 @@ namespace ErsatzTV.Infrastructure.Data.Repositories
.Filter(s => s.Id == showId)
.Include(s => s.ShowMetadata)
.ThenInclude(sm => sm.Artwork)
.Include(s => s.ShowMetadata)
.ThenInclude(sm => sm.Genres)
.OrderBy(s => s.Id)
.SingleOrDefaultAsync()
.Map(Optional);
@@ -171,6 +173,8 @@ namespace ErsatzTV.Infrastructure.Data.Repositories
return _dbContext.Shows
.Include(s => s.ShowMetadata)
.ThenInclude(sm => sm.Artwork)
.Include(s => s.ShowMetadata)
.ThenInclude(sm => sm.Genres)
.OrderBy(s => s.Id)
.SingleOrDefaultAsync(s => s.Id == id)
.Map(Optional);
@@ -183,6 +187,7 @@ namespace ErsatzTV.Infrastructure.Data.Repositories
try
{
metadata.DateAdded = DateTime.UtcNow;
metadata.Genres ??= new List<Genre>();
var show = new Show
{
LibraryPathId = libraryPathId,