Browse Source

music video nfo multiple artists (#780)

* support multiple artist entries in music video nfo metadata

* clean up other video and song etags
pull/782/head
Jason Dove 4 years ago committed by GitHub
parent
commit
8ba6374165
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 1
      CHANGELOG.md
  2. 2
      ErsatzTV.Core.Tests/Metadata/Nfo/MusicVideoNfoReaderTests.cs
  3. 7
      ErsatzTV.Core/Domain/Metadata/MusicVideoArtist.cs
  4. 1
      ErsatzTV.Core/Domain/Metadata/MusicVideoMetadata.cs
  5. 3
      ErsatzTV.Core/Interfaces/Repositories/ILibraryRepository.cs
  6. 2
      ErsatzTV.Core/Interfaces/Repositories/IMusicVideoRepository.cs
  7. 1
      ErsatzTV.Core/Metadata/FallbackMetadataProvider.cs
  8. 23
      ErsatzTV.Core/Metadata/LocalMetadataProvider.cs
  9. 11
      ErsatzTV.Core/Metadata/MusicVideoFolderScanner.cs
  10. 2
      ErsatzTV.Core/Metadata/Nfo/MusicVideoNfo.cs
  11. 3
      ErsatzTV.Core/Metadata/Nfo/MusicVideoNfoReader.cs
  12. 11
      ErsatzTV.Core/Metadata/OtherVideoFolderScanner.cs
  13. 11
      ErsatzTV.Core/Metadata/SongFolderScanner.cs
  14. 4
      ErsatzTV.Infrastructure/Data/Configurations/Metadata/MusicVideoMetadataConfiguration.cs
  15. 29
      ErsatzTV.Infrastructure/Data/Repositories/LibraryRepository.cs
  16. 8
      ErsatzTV.Infrastructure/Data/Repositories/MetadataRepository.cs
  17. 19
      ErsatzTV.Infrastructure/Data/Repositories/MusicVideoRepository.cs
  18. 4
      ErsatzTV.Infrastructure/Data/Repositories/SearchRepository.cs
  19. 4239
      ErsatzTV.Infrastructure/Migrations/20220502133555_Add_MusicVideoArtists.Designer.cs
  20. 43
      ErsatzTV.Infrastructure/Migrations/20220502133555_Add_MusicVideoArtists.cs
  21. 4239
      ErsatzTV.Infrastructure/Migrations/20220502171259_Reset_MusicVideoLibraries.Designer.cs
  22. 34
      ErsatzTV.Infrastructure/Migrations/20220502171259_Reset_MusicVideoLibraries.cs
  23. 4239
      ErsatzTV.Infrastructure/Migrations/20220502172236_Reset_OtherVideosSongsFolderEtags.Designer.cs
  24. 23
      ErsatzTV.Infrastructure/Migrations/20220502172236_Reset_OtherVideosSongsFolderEtags.cs
  25. 29
      ErsatzTV.Infrastructure/Migrations/TvContextModelSnapshot.cs
  26. 14
      ErsatzTV.Infrastructure/Search/SearchIndex.cs

1
CHANGELOG.md

@ -15,6 +15,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). @@ -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

2
ErsatzTV.Core.Tests/Metadata/Nfo/MusicVideoNfoReaderTests.cs

@ -113,7 +113,7 @@ https://www.themoviedb.org/movie/11-star-wars")); @@ -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(

7
ErsatzTV.Core/Domain/Metadata/MusicVideoArtist.cs

@ -0,0 +1,7 @@ @@ -0,0 +1,7 @@
namespace ErsatzTV.Core.Domain;
public class MusicVideoArtist
{
public int Id { get; set; }
public string Name { get; set; }
}

1
ErsatzTV.Core/Domain/Metadata/MusicVideoMetadata.cs

@ -6,4 +6,5 @@ public class MusicVideoMetadata : Metadata @@ -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; }
}

3
ErsatzTV.Core/Interfaces/Repositories/ILibraryRepository.cs

@ -11,10 +11,7 @@ public interface ILibraryRepository @@ -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);
}

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

@ -12,9 +12,11 @@ public interface IMusicVideoRepository @@ -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);

1
ErsatzTV.Core/Metadata/FallbackMetadataProvider.cs

@ -230,6 +230,7 @@ public class FallbackMetadataProvider : IFallbackMetadataProvider @@ -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>();

23
ErsatzTV.Core/Metadata/LocalMetadataProvider.cs

@ -193,6 +193,7 @@ public class LocalMetadataProvider : ILocalMetadataProvider @@ -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 @@ -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;
}

11
ErsatzTV.Core/Metadata/MusicVideoFolderScanner.cs

@ -307,6 +307,8 @@ public class MusicVideoFolderScanner : LocalFolderScanner, IMusicVideoFolderScan @@ -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 @@ -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 @@ -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;

2
ErsatzTV.Core/Metadata/Nfo/MusicVideoNfo.cs

@ -6,7 +6,7 @@ namespace ErsatzTV.Core.Metadata.Nfo; @@ -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; }

3
ErsatzTV.Core/Metadata/Nfo/MusicVideoNfoReader.cs

@ -30,6 +30,7 @@ public class MusicVideoNfoReader : NfoReader<MusicVideoNfo>, IMusicVideoNfoReade @@ -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 @@ -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);

11
ErsatzTV.Core/Metadata/OtherVideoFolderScanner.cs

@ -136,6 +136,8 @@ public class OtherVideoFolderScanner : LocalFolderScanner, IOtherVideoFolderScan @@ -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 @@ -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 @@ -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))

11
ErsatzTV.Core/Metadata/SongFolderScanner.cs

@ -134,6 +134,8 @@ public class SongFolderScanner : LocalFolderScanner, ISongFolderScanner @@ -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 @@ -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 @@ -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
ErsatzTV.Infrastructure/Data/Configurations/Metadata/MusicVideoMetadataConfiguration.cs

@ -29,5 +29,9 @@ public class MusicVideoMetadataConfiguration : IEntityTypeConfiguration<MusicVid @@ -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);
}
}

29
ErsatzTV.Infrastructure/Data/Repositories/LibraryRepository.cs

@ -82,15 +82,6 @@ public class LibraryRepository : ILibraryRepository @@ -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 @@ -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,

8
ErsatzTV.Infrastructure/Data/Repositories/MetadataRepository.cs

@ -102,6 +102,14 @@ public class MetadataRepository : IMetadataRepository @@ -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;
}

19
ErsatzTV.Infrastructure/Data/Repositories/MusicVideoRepository.cs

@ -26,6 +26,8 @@ public class MusicVideoRepository : IMusicVideoRepository @@ -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 @@ -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 @@ -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();

4
ErsatzTV.Infrastructure/Data/Repositories/SearchRepository.cs

@ -73,6 +73,8 @@ public class SearchRepository : ISearchRepository @@ -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 @@ -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
ErsatzTV.Infrastructure/Migrations/20220502133555_Add_MusicVideoArtists.Designer.cs generated

File diff suppressed because it is too large Load Diff

43
ErsatzTV.Infrastructure/Migrations/20220502133555_Add_MusicVideoArtists.cs

@ -0,0 +1,43 @@ @@ -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
ErsatzTV.Infrastructure/Migrations/20220502171259_Reset_MusicVideoLibraries.Designer.cs generated

File diff suppressed because it is too large Load Diff

34
ErsatzTV.Infrastructure/Migrations/20220502171259_Reset_MusicVideoLibraries.cs

@ -0,0 +1,34 @@ @@ -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)
{
}
}
}

4239
ErsatzTV.Infrastructure/Migrations/20220502172236_Reset_OtherVideosSongsFolderEtags.Designer.cs generated

File diff suppressed because it is too large Load Diff

23
ErsatzTV.Infrastructure/Migrations/20220502172236_Reset_OtherVideosSongsFolderEtags.cs

@ -0,0 +1,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)
{
}
}
}

29
ErsatzTV.Infrastructure/Migrations/TvContextModelSnapshot.cs

@ -1225,6 +1225,25 @@ namespace ErsatzTV.Infrastructure.Migrations @@ -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 @@ -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 @@ -4006,6 +4033,8 @@ namespace ErsatzTV.Infrastructure.Migrations
{
b.Navigation("Actors");
b.Navigation("Artists");
b.Navigation("Artwork");
b.Navigation("Genres");

14
ErsatzTV.Infrastructure/Search/SearchIndex.cs

@ -751,14 +751,26 @@ public sealed class SearchIndex : ISearchIndex @@ -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)

Loading…
Cancel
Save