music video nfo multiple artists (#780)
* support multiple artist entries in music video nfo metadata * clean up other video and song etags
This commit is contained in:
@@ -15,6 +15,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
||||
|
||||
### Added
|
||||
- Use `Sort Title` from Movie NFO metadata if available
|
||||
- Support multiple `Artist` entries in music video NFO metadata
|
||||
|
||||
## [0.5.3-beta] - 2022-04-29
|
||||
### Fixed
|
||||
|
||||
@@ -113,7 +113,7 @@ https://www.themoviedb.org/movie/11-star-wars"));
|
||||
|
||||
foreach (MusicVideoNfo nfo in result.RightToSeq())
|
||||
{
|
||||
nfo.Artist.Should().Be("ABBA");
|
||||
nfo.Artists.Should().BeEquivalentTo(new List<string> { "ABBA" });
|
||||
nfo.Title.Should().Be("Dancing Queen");
|
||||
nfo.Album.Should().Be("Arrival");
|
||||
nfo.Plot.Should().Be(
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
namespace ErsatzTV.Core.Domain;
|
||||
|
||||
public class MusicVideoArtist
|
||||
{
|
||||
public int Id { get; set; }
|
||||
public string Name { get; set; }
|
||||
}
|
||||
@@ -6,4 +6,5 @@ public class MusicVideoMetadata : Metadata
|
||||
public string Plot { get; set; }
|
||||
public int MusicVideoId { get; set; }
|
||||
public MusicVideo MusicVideo { get; set; }
|
||||
public List<MusicVideoArtist> Artists { get; set; }
|
||||
}
|
||||
|
||||
@@ -11,10 +11,7 @@ public interface ILibraryRepository
|
||||
Task<Unit> UpdateLastScan(Library library);
|
||||
Task<Unit> UpdateLastScan(LibraryPath libraryPath);
|
||||
Task<List<LibraryPath>> GetLocalPaths(int libraryId);
|
||||
Task<Option<LibraryPath>> GetPath(int libraryPathId);
|
||||
Task<int> CountMediaItemsByPath(int libraryPathId);
|
||||
Task<List<int>> GetMediaIdsByLocalPath(int libraryPathId);
|
||||
Task DeleteLocalPath(int libraryPathId);
|
||||
Task<Unit> SetEtag(LibraryPath libraryPath, Option<LibraryFolder> knownFolder, string path, string etag);
|
||||
Task<Unit> CleanEtagsForLibraryPath(LibraryPath libraryPath);
|
||||
}
|
||||
|
||||
@@ -12,9 +12,11 @@ public interface IMusicVideoRepository
|
||||
|
||||
Task<IEnumerable<string>> FindMusicVideoPaths(LibraryPath libraryPath);
|
||||
Task<List<int>> DeleteByPath(LibraryPath libraryPath, string path);
|
||||
Task<bool> AddArtist(MusicVideoMetadata metadata, MusicVideoArtist artist);
|
||||
Task<bool> AddGenre(MusicVideoMetadata metadata, Genre genre);
|
||||
Task<bool> AddTag(MusicVideoMetadata metadata, Tag tag);
|
||||
Task<bool> AddStudio(MusicVideoMetadata metadata, Studio studio);
|
||||
Task<bool> RemoveArtist(MusicVideoArtist artist);
|
||||
Task<List<MusicVideoMetadata>> GetMusicVideosForCards(List<int> ids);
|
||||
Task<IEnumerable<string>> FindOrphanPaths(LibraryPath libraryPath);
|
||||
Task<int> GetMusicVideoCount(int artistId);
|
||||
|
||||
@@ -230,6 +230,7 @@ public class FallbackMetadataProvider : IFallbackMetadataProvider
|
||||
metadata.Title = match.Success
|
||||
? match.Groups[2].Value.Trim()
|
||||
: Path.GetFileNameWithoutExtension(fileName);
|
||||
metadata.Artists = new List<MusicVideoArtist>();
|
||||
metadata.Genres = new List<Genre>();
|
||||
metadata.Tags = new List<Tag>();
|
||||
metadata.Studios = new List<Studio>();
|
||||
|
||||
@@ -193,6 +193,7 @@ public class LocalMetadataProvider : ILocalMetadataProvider
|
||||
Plot = nfo.Plot,
|
||||
Year = GetYear(nfo.Year, string.Empty),
|
||||
ReleaseDate = GetAired(nfo.Year, string.Empty),
|
||||
Artists = nfo.Artists.Map(a => new MusicVideoArtist { Name = a }).ToList(),
|
||||
Genres = nfo.Genres.Map(g => new Genre { Name = g }).ToList(),
|
||||
Tags = nfo.Tags.Map(t => new Tag { Name = t }).ToList(),
|
||||
Studios = nfo.Studios.Map(s => new Studio { Name = s }).ToList()
|
||||
@@ -727,6 +728,28 @@ public class LocalMetadataProvider : ILocalMetadataProvider
|
||||
_musicVideoRepository.AddStudio,
|
||||
(_, _) => Task.FromResult(false));
|
||||
|
||||
foreach (MusicVideoArtist artist in existing.Artists
|
||||
.Filter(g => metadata.Artists.All(g2 => g2.Name != g.Name))
|
||||
.ToList())
|
||||
{
|
||||
existing.Artists.Remove(artist);
|
||||
if (await _musicVideoRepository.RemoveArtist(artist))
|
||||
{
|
||||
updated = true;
|
||||
}
|
||||
}
|
||||
|
||||
foreach (MusicVideoArtist artist in metadata.Artists
|
||||
.Filter(g => existing.Artists.All(g2 => g2.Name != g.Name))
|
||||
.ToList())
|
||||
{
|
||||
existing.Artists.Add(artist);
|
||||
if (await _musicVideoRepository.AddArtist(existing, artist))
|
||||
{
|
||||
updated = true;
|
||||
}
|
||||
}
|
||||
|
||||
return await _metadataRepository.Update(existing) || updated;
|
||||
}
|
||||
|
||||
|
||||
@@ -307,6 +307,8 @@ public class MusicVideoFolderScanner : LocalFolderScanner, IMusicVideoFolderScan
|
||||
continue;
|
||||
}
|
||||
|
||||
var hasErrors = false;
|
||||
|
||||
foreach (string file in allFiles.OrderBy(identity))
|
||||
{
|
||||
// TODO: figure out how to rebuild playouts
|
||||
@@ -321,6 +323,7 @@ public class MusicVideoFolderScanner : LocalFolderScanner, IMusicVideoFolderScan
|
||||
foreach (BaseError error in maybeMusicVideo.LeftToSeq())
|
||||
{
|
||||
_logger.LogWarning("Error processing music video at {Path}: {Error}", file, error.Value);
|
||||
hasErrors = true;
|
||||
}
|
||||
|
||||
foreach (MediaItemScanResult<MusicVideo> result in maybeMusicVideo.RightToSeq())
|
||||
@@ -329,10 +332,14 @@ public class MusicVideoFolderScanner : LocalFolderScanner, IMusicVideoFolderScan
|
||||
{
|
||||
await _searchIndex.RebuildItems(_searchRepository, new List<int> { result.Item.Id });
|
||||
}
|
||||
|
||||
await _libraryRepository.SetEtag(libraryPath, knownFolder, musicVideoFolder, etag);
|
||||
}
|
||||
}
|
||||
|
||||
// only do this once per folder and only if all files processed successfully
|
||||
if (!hasErrors)
|
||||
{
|
||||
await _libraryRepository.SetEtag(libraryPath, knownFolder, musicVideoFolder, etag);
|
||||
}
|
||||
}
|
||||
|
||||
return Unit.Default;
|
||||
|
||||
@@ -6,7 +6,7 @@ namespace ErsatzTV.Core.Metadata.Nfo;
|
||||
public class MusicVideoNfo
|
||||
{
|
||||
[XmlElement("artist")]
|
||||
public string Artist { get; set; }
|
||||
public List<string> Artists { get; set; }
|
||||
|
||||
[XmlElement("title")]
|
||||
public string Title { get; set; }
|
||||
|
||||
@@ -30,6 +30,7 @@ public class MusicVideoNfoReader : NfoReader<MusicVideoNfo>, IMusicVideoNfoReade
|
||||
case "musicvideo":
|
||||
nfo = new MusicVideoNfo
|
||||
{
|
||||
Artists = new List<string>(),
|
||||
Genres = new List<string>(),
|
||||
Tags = new List<string>(),
|
||||
Studios = new List<string>()
|
||||
@@ -39,7 +40,7 @@ public class MusicVideoNfoReader : NfoReader<MusicVideoNfo>, IMusicVideoNfoReade
|
||||
await ReadStringContent(
|
||||
reader,
|
||||
nfo,
|
||||
(musicVideo, artist) => musicVideo.Artist = artist);
|
||||
(musicVideo, artist) => musicVideo.Artists.Add(artist));
|
||||
break;
|
||||
case "title":
|
||||
await ReadStringContent(reader, nfo, (musicVideo, title) => musicVideo.Title = title);
|
||||
|
||||
@@ -136,6 +136,8 @@ public class OtherVideoFolderScanner : LocalFolderScanner, IOtherVideoFolderScan
|
||||
"UPDATE: Etag has changed for folder {Folder}",
|
||||
otherVideoFolder);
|
||||
|
||||
var hasErrors = false;
|
||||
|
||||
foreach (string file in allFiles.OrderBy(identity))
|
||||
{
|
||||
Either<BaseError, MediaItemScanResult<OtherVideo>> maybeVideo = await _otherVideoRepository
|
||||
@@ -148,6 +150,7 @@ public class OtherVideoFolderScanner : LocalFolderScanner, IOtherVideoFolderScan
|
||||
foreach (BaseError error in maybeVideo.LeftToSeq())
|
||||
{
|
||||
_logger.LogWarning("Error processing other video at {Path}: {Error}", file, error.Value);
|
||||
hasErrors = true;
|
||||
}
|
||||
|
||||
foreach (MediaItemScanResult<OtherVideo> result in maybeVideo.RightToSeq())
|
||||
@@ -156,10 +159,14 @@ public class OtherVideoFolderScanner : LocalFolderScanner, IOtherVideoFolderScan
|
||||
{
|
||||
await _searchIndex.RebuildItems(_searchRepository, new List<int> { result.Item.Id });
|
||||
}
|
||||
|
||||
await _libraryRepository.SetEtag(libraryPath, knownFolder, otherVideoFolder, etag);
|
||||
}
|
||||
}
|
||||
|
||||
// only do this once per folder and only if all files processed successfully
|
||||
if (!hasErrors)
|
||||
{
|
||||
await _libraryRepository.SetEtag(libraryPath, knownFolder, otherVideoFolder, etag);
|
||||
}
|
||||
}
|
||||
|
||||
foreach (string path in await _otherVideoRepository.FindOtherVideoPaths(libraryPath))
|
||||
|
||||
@@ -134,6 +134,8 @@ public class SongFolderScanner : LocalFolderScanner, ISongFolderScanner
|
||||
"UPDATE: Etag has changed for folder {Folder}",
|
||||
songFolder);
|
||||
|
||||
var hasErrors = false;
|
||||
|
||||
foreach (string file in allFiles.OrderBy(identity))
|
||||
{
|
||||
Either<BaseError, MediaItemScanResult<Song>> maybeSong = await _songRepository
|
||||
@@ -146,6 +148,7 @@ public class SongFolderScanner : LocalFolderScanner, ISongFolderScanner
|
||||
foreach (BaseError error in maybeSong.LeftToSeq())
|
||||
{
|
||||
_logger.LogWarning("Error processing song at {Path}: {Error}", file, error.Value);
|
||||
hasErrors = true;
|
||||
}
|
||||
|
||||
foreach (MediaItemScanResult<Song> result in maybeSong.RightToSeq())
|
||||
@@ -154,10 +157,14 @@ public class SongFolderScanner : LocalFolderScanner, ISongFolderScanner
|
||||
{
|
||||
await _searchIndex.RebuildItems(_searchRepository, new List<int> { result.Item.Id });
|
||||
}
|
||||
|
||||
await _libraryRepository.SetEtag(libraryPath, knownFolder, songFolder, etag);
|
||||
}
|
||||
}
|
||||
|
||||
// only do this once per folder and only if all files processed successfully
|
||||
if (!hasErrors)
|
||||
{
|
||||
await _libraryRepository.SetEtag(libraryPath, knownFolder, songFolder, etag);
|
||||
}
|
||||
}
|
||||
|
||||
foreach (string path in await _songRepository.FindSongPaths(libraryPath))
|
||||
|
||||
+4
@@ -29,5 +29,9 @@ public class MusicVideoMetadataConfiguration : IEntityTypeConfiguration<MusicVid
|
||||
builder.HasMany(mvm => mvm.Subtitles)
|
||||
.WithOne()
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
|
||||
builder.HasMany(mvm => mvm.Artists)
|
||||
.WithOne()
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -82,15 +82,6 @@ public class LibraryRepository : ILibraryRepository
|
||||
.Match(l => l.Paths, () => new List<LibraryPath>());
|
||||
}
|
||||
|
||||
public async Task<Option<LibraryPath>> GetPath(int libraryPathId)
|
||||
{
|
||||
await using TvContext dbContext = await _dbContextFactory.CreateDbContextAsync();
|
||||
return await dbContext.LibraryPaths
|
||||
.OrderBy(lp => lp.Id)
|
||||
.SingleOrDefaultAsync(lp => lp.Id == libraryPathId)
|
||||
.Map(Optional);
|
||||
}
|
||||
|
||||
public async Task<int> CountMediaItemsByPath(int libraryPathId)
|
||||
{
|
||||
await using TvContext dbContext = await _dbContextFactory.CreateDbContextAsync();
|
||||
@@ -99,26 +90,6 @@ public class LibraryRepository : ILibraryRepository
|
||||
new { LibraryPathId = libraryPathId });
|
||||
}
|
||||
|
||||
public async Task<List<int>> GetMediaIdsByLocalPath(int libraryPathId)
|
||||
{
|
||||
await using TvContext dbContext = await _dbContextFactory.CreateDbContextAsync();
|
||||
return await dbContext.Connection.QueryAsync<int>(
|
||||
@"SELECT Id FROM MediaItem WHERE LibraryPathId = @LibraryPathId",
|
||||
new { LibraryPathId = libraryPathId })
|
||||
.Map(result => result.ToList());
|
||||
}
|
||||
|
||||
public async Task DeleteLocalPath(int libraryPathId)
|
||||
{
|
||||
await using TvContext context = await _dbContextFactory.CreateDbContextAsync();
|
||||
LibraryPath libraryPath = await context.LibraryPaths.FindAsync(libraryPathId);
|
||||
if (libraryPath != null)
|
||||
{
|
||||
context.LibraryPaths.Remove(libraryPath);
|
||||
await context.SaveChangesAsync();
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<Unit> SetEtag(
|
||||
LibraryPath libraryPath,
|
||||
Option<LibraryFolder> knownFolder,
|
||||
|
||||
@@ -102,6 +102,14 @@ public class MetadataRepository : IMetadataRepository
|
||||
}
|
||||
}
|
||||
|
||||
if (metadata is MusicVideoMetadata musicVideoMetadata)
|
||||
{
|
||||
foreach (MusicVideoArtist artist in Optional(musicVideoMetadata.Artists).Flatten())
|
||||
{
|
||||
dbContext.Entry(artist).State = EntityState.Added;
|
||||
}
|
||||
}
|
||||
|
||||
return await dbContext.SaveChangesAsync() > 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -26,6 +26,8 @@ public class MusicVideoRepository : IMusicVideoRepository
|
||||
.Include(mv => mv.MusicVideoMetadata)
|
||||
.ThenInclude(mvm => mvm.Artwork)
|
||||
.Include(mv => mv.MusicVideoMetadata)
|
||||
.ThenInclude(mvm => mvm.Artists)
|
||||
.Include(mv => mv.MusicVideoMetadata)
|
||||
.ThenInclude(mvm => mvm.Genres)
|
||||
.Include(mv => mv.MusicVideoMetadata)
|
||||
.ThenInclude(mvm => mvm.Tags)
|
||||
@@ -100,6 +102,14 @@ public class MusicVideoRepository : IMusicVideoRepository
|
||||
return ids;
|
||||
}
|
||||
|
||||
public async Task<bool> AddArtist(MusicVideoMetadata metadata, MusicVideoArtist artist)
|
||||
{
|
||||
await using TvContext dbContext = await _dbContextFactory.CreateDbContextAsync();
|
||||
return await dbContext.Connection.ExecuteAsync(
|
||||
"INSERT INTO MusicVideoArtist (Name, MusicVideoMetadataId) VALUES (@Name, @MetadataId)",
|
||||
new { artist.Name, MetadataId = metadata.Id }).Map(result => result > 0);
|
||||
}
|
||||
|
||||
public async Task<bool> AddGenre(MusicVideoMetadata metadata, Genre genre)
|
||||
{
|
||||
await using TvContext dbContext = await _dbContextFactory.CreateDbContextAsync();
|
||||
@@ -124,6 +134,15 @@ public class MusicVideoRepository : IMusicVideoRepository
|
||||
new { studio.Name, MetadataId = metadata.Id }).Map(result => result > 0);
|
||||
}
|
||||
|
||||
public async Task<bool> RemoveArtist(MusicVideoArtist artist)
|
||||
{
|
||||
await using TvContext dbContext = await _dbContextFactory.CreateDbContextAsync();
|
||||
return await dbContext.Connection.ExecuteAsync(
|
||||
"DELETE FROM MusicVideoArtist WHERE Id = @Id",
|
||||
new { artist.Id })
|
||||
.Map(result => result > 0);
|
||||
}
|
||||
|
||||
public async Task<List<MusicVideoMetadata>> GetMusicVideosForCards(List<int> ids)
|
||||
{
|
||||
await using TvContext dbContext = await _dbContextFactory.CreateDbContextAsync();
|
||||
|
||||
@@ -73,6 +73,8 @@ public class SearchRepository : ISearchRepository
|
||||
.Include(mi => (mi as MusicVideo).Artist)
|
||||
.ThenInclude(mm => mm.ArtistMetadata)
|
||||
.Include(mi => (mi as MusicVideo).MusicVideoMetadata)
|
||||
.ThenInclude(mm => mm.Artists)
|
||||
.Include(mi => (mi as MusicVideo).MusicVideoMetadata)
|
||||
.ThenInclude(mm => mm.Genres)
|
||||
.Include(mi => (mi as MusicVideo).MusicVideoMetadata)
|
||||
.ThenInclude(mm => mm.Tags)
|
||||
@@ -206,6 +208,8 @@ public class SearchRepository : ISearchRepository
|
||||
.Include(mi => (mi as MusicVideo).Artist)
|
||||
.ThenInclude(mm => mm.ArtistMetadata)
|
||||
.Include(mi => (mi as MusicVideo).MusicVideoMetadata)
|
||||
.ThenInclude(mm => mm.Artists)
|
||||
.Include(mi => (mi as MusicVideo).MusicVideoMetadata)
|
||||
.ThenInclude(mm => mm.Genres)
|
||||
.Include(mi => (mi as MusicVideo).MusicVideoMetadata)
|
||||
.ThenInclude(mm => mm.Tags)
|
||||
|
||||
+4239
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,43 @@
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace ErsatzTV.Infrastructure.Migrations
|
||||
{
|
||||
public partial class Add_MusicVideoArtists : Migration
|
||||
{
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.CreateTable(
|
||||
name: "MusicVideoArtist",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<int>(type: "INTEGER", nullable: false)
|
||||
.Annotation("Sqlite:Autoincrement", true),
|
||||
Name = table.Column<string>(type: "TEXT", nullable: true),
|
||||
MusicVideoMetadataId = table.Column<int>(type: "INTEGER", nullable: true)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_MusicVideoArtist", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_MusicVideoArtist_MusicVideoMetadata_MusicVideoMetadataId",
|
||||
column: x => x.MusicVideoMetadataId,
|
||||
principalTable: "MusicVideoMetadata",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_MusicVideoArtist_MusicVideoMetadataId",
|
||||
table: "MusicVideoArtist",
|
||||
column: "MusicVideoMetadataId");
|
||||
}
|
||||
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropTable(
|
||||
name: "MusicVideoArtist");
|
||||
}
|
||||
}
|
||||
}
|
||||
+4239
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,34 @@
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace ErsatzTV.Infrastructure.Migrations
|
||||
{
|
||||
public partial class Reset_MusicVideoLibraries : Migration
|
||||
{
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.Sql(
|
||||
@"UPDATE LibraryPath SET LastScan = '0001-01-01 00:00:00' WHERE Id IN
|
||||
(SELECT LP.Id FROM LibraryPath LP INNER JOIN Library L on L.Id = LP.LibraryId WHERE MediaKind = 3)");
|
||||
|
||||
migrationBuilder.Sql(
|
||||
@"UPDATE Library SET LastScan = '0001-01-01 00:00:00' WHERE MediaKind = 3");
|
||||
|
||||
migrationBuilder.Sql(
|
||||
@"UPDATE MusicVideoMetadata SET DateUpdated = '0001-01-01 00:00:00'");
|
||||
|
||||
migrationBuilder.Sql(
|
||||
@"DELETE FROM LibraryFolder WHERE Id IN
|
||||
(SELECT LF.Id FROM LibraryFolder LF
|
||||
INNER JOIN LibraryPath LP on LP.Id = LF.LibraryPathId
|
||||
INNER JOIN Library L on L.Id = LP.LibraryId
|
||||
WHERE L.MediaKind = 3)");
|
||||
}
|
||||
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
Generated
+4239
File diff suppressed because it is too large
Load Diff
+23
@@ -0,0 +1,23 @@
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace ErsatzTV.Infrastructure.Migrations
|
||||
{
|
||||
public partial class Reset_OtherVideosSongsFolderEtags : Migration
|
||||
{
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.Sql(
|
||||
@"DELETE FROM LibraryFolder WHERE Id IN
|
||||
(SELECT LF.Id FROM LibraryFolder LF
|
||||
INNER JOIN LibraryPath LP on LP.Id = LF.LibraryPathId
|
||||
INNER JOIN Library L on L.Id = LP.LibraryId
|
||||
WHERE L.MediaKind IN (4, 5))");
|
||||
}
|
||||
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1225,6 +1225,25 @@ namespace ErsatzTV.Infrastructure.Migrations
|
||||
b.ToTable("MultiCollectionSmartItem");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("ErsatzTV.Core.Domain.MusicVideoArtist", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int?>("MusicVideoMetadataId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("MusicVideoMetadataId");
|
||||
|
||||
b.ToTable("MusicVideoArtist");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("ErsatzTV.Core.Domain.MusicVideoMetadata", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
@@ -3056,6 +3075,14 @@ namespace ErsatzTV.Infrastructure.Migrations
|
||||
b.Navigation("SmartCollection");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("ErsatzTV.Core.Domain.MusicVideoArtist", b =>
|
||||
{
|
||||
b.HasOne("ErsatzTV.Core.Domain.MusicVideoMetadata", null)
|
||||
.WithMany("Artists")
|
||||
.HasForeignKey("MusicVideoMetadataId")
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("ErsatzTV.Core.Domain.MusicVideoMetadata", b =>
|
||||
{
|
||||
b.HasOne("ErsatzTV.Core.Domain.MusicVideo", "MusicVideo")
|
||||
@@ -4006,6 +4033,8 @@ namespace ErsatzTV.Infrastructure.Migrations
|
||||
{
|
||||
b.Navigation("Actors");
|
||||
|
||||
b.Navigation("Artists");
|
||||
|
||||
b.Navigation("Artwork");
|
||||
|
||||
b.Navigation("Genres");
|
||||
|
||||
@@ -751,14 +751,26 @@ public sealed class SearchIndex : ISearchIndex
|
||||
doc.Add(new TextField(StudioField, studio.Name, Field.Store.NO));
|
||||
}
|
||||
|
||||
var artists = new System.Collections.Generic.HashSet<string>();
|
||||
|
||||
if (musicVideo.Artist != null)
|
||||
{
|
||||
foreach (ArtistMetadata artistMetadata in musicVideo.Artist.ArtistMetadata)
|
||||
{
|
||||
doc.Add(new TextField(ArtistField, artistMetadata.Title, Field.Store.NO));
|
||||
artists.Add(artistMetadata.Title);
|
||||
}
|
||||
}
|
||||
|
||||
foreach (MusicVideoArtist artist in metadata.Artists)
|
||||
{
|
||||
artists.Add(artist.Name);
|
||||
}
|
||||
|
||||
foreach (string artist in artists)
|
||||
{
|
||||
doc.Add(new TextField(ArtistField, artist, Field.Store.NO));
|
||||
}
|
||||
|
||||
_writer.UpdateDocument(new Term(IdField, musicVideo.Id.ToString()), doc);
|
||||
}
|
||||
catch (Exception ex)
|
||||
|
||||
Reference in New Issue
Block a user