Compare commits
7
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e515df93fd | ||
|
|
fedc18f7db | ||
|
|
59d75fe08f | ||
|
|
49d9b1c714 | ||
|
|
2f066d5b62 | ||
|
|
63db2edb99 | ||
|
|
5d01276ef3 |
@@ -98,7 +98,7 @@ namespace ErsatzTV.Core.Metadata
|
||||
continue;
|
||||
}
|
||||
|
||||
if (_localFileSystem.GetLastWriteTime(movieFolder) < lastScan)
|
||||
if (allFiles.All(file => _localFileSystem.GetLastWriteTime(file) < lastScan))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -156,7 +156,7 @@ namespace ErsatzTV.Core.Plex
|
||||
PlexMovie existing = result.Item;
|
||||
MovieMetadata existingMetadata = existing.MovieMetadata.Head();
|
||||
|
||||
if (incoming.MovieMetadata.Head().DateUpdated > existingMetadata.DateUpdated)
|
||||
if (result.IsAdded || incoming.MovieMetadata.Head().DateUpdated > existingMetadata.DateUpdated)
|
||||
{
|
||||
_logger.LogDebug(
|
||||
"Refreshing {Attribute} from {Path}",
|
||||
@@ -218,7 +218,9 @@ namespace ErsatzTV.Core.Plex
|
||||
}
|
||||
|
||||
foreach (Actor actor in existingMetadata.Actors
|
||||
.Filter(a => fullMetadata.Actors.All(a2 => a2.Name != a.Name))
|
||||
.Filter(
|
||||
a => fullMetadata.Actors.All(
|
||||
a2 => a2.Name != a.Name || a.Artwork == null && a2.Artwork != null))
|
||||
.ToList())
|
||||
{
|
||||
existingMetadata.Actors.Remove(actor);
|
||||
|
||||
@@ -124,7 +124,7 @@ namespace ErsatzTV.Core.Plex
|
||||
PlexShow existing = result.Item;
|
||||
ShowMetadata existingMetadata = existing.ShowMetadata.Head();
|
||||
|
||||
if (incoming.ShowMetadata.Head().DateUpdated > existingMetadata.DateUpdated)
|
||||
if (result.IsAdded || incoming.ShowMetadata.Head().DateUpdated > existingMetadata.DateUpdated)
|
||||
{
|
||||
Either<BaseError, ShowMetadata> maybeMetadata =
|
||||
await _plexServerApiClient.GetShowMetadata(
|
||||
@@ -181,7 +181,9 @@ namespace ErsatzTV.Core.Plex
|
||||
}
|
||||
|
||||
foreach (Actor actor in existingMetadata.Actors
|
||||
.Filter(a => fullMetadata.Actors.All(a2 => a2.Name != a.Name))
|
||||
.Filter(
|
||||
a => fullMetadata.Actors.All(
|
||||
a2 => a2.Name != a.Name || a.Artwork == null && a2.Artwork != null))
|
||||
.ToList())
|
||||
{
|
||||
existingMetadata.Actors.Remove(actor);
|
||||
|
||||
@@ -67,6 +67,7 @@ namespace ErsatzTV.Infrastructure.Data.Repositories
|
||||
.ThenInclude(mm => mm.Studios)
|
||||
.Include(i => i.MovieMetadata)
|
||||
.ThenInclude(mm => mm.Actors)
|
||||
.ThenInclude(a => a.Artwork)
|
||||
.Include(i => i.LibraryPath)
|
||||
.ThenInclude(lp => lp.Library)
|
||||
.Include(i => i.MediaVersions)
|
||||
@@ -98,6 +99,7 @@ namespace ErsatzTV.Infrastructure.Data.Repositories
|
||||
.ThenInclude(mm => mm.Studios)
|
||||
.Include(i => i.MovieMetadata)
|
||||
.ThenInclude(mm => mm.Actors)
|
||||
.ThenInclude(a => a.Artwork)
|
||||
.Include(i => i.MovieMetadata)
|
||||
.ThenInclude(mm => mm.Artwork)
|
||||
.Include(i => i.MediaVersions)
|
||||
@@ -112,7 +114,7 @@ namespace ErsatzTV.Infrastructure.Data.Repositories
|
||||
return await maybeExisting.Match(
|
||||
plexMovie =>
|
||||
Right<BaseError, MediaItemScanResult<PlexMovie>>(
|
||||
new MediaItemScanResult<PlexMovie>(plexMovie) { IsAdded = true }).AsTask(),
|
||||
new MediaItemScanResult<PlexMovie>(plexMovie) { IsAdded = false }).AsTask(),
|
||||
async () => await AddPlexMovie(context, library, item));
|
||||
}
|
||||
|
||||
|
||||
@@ -192,6 +192,7 @@ namespace ErsatzTV.Infrastructure.Data.Repositories
|
||||
.ThenInclude(s => s.Show)
|
||||
.ThenInclude(s => s.ShowMetadata)
|
||||
.ThenInclude(sm => sm.Actors)
|
||||
.ThenInclude(a => a.Artwork)
|
||||
.OrderBy(em => em.Episode.EpisodeNumber)
|
||||
.Skip((pageNumber - 1) * pageSize)
|
||||
.Take(pageSize)
|
||||
@@ -293,6 +294,7 @@ namespace ErsatzTV.Infrastructure.Data.Repositories
|
||||
.ThenInclude(em => em.Artwork)
|
||||
.Include(i => i.EpisodeMetadata)
|
||||
.ThenInclude(em => em.Actors)
|
||||
.ThenInclude(a => a.Artwork)
|
||||
.Include(i => i.MediaVersions)
|
||||
.ThenInclude(mv => mv.MediaFiles)
|
||||
.Include(i => i.MediaVersions)
|
||||
@@ -393,6 +395,7 @@ namespace ErsatzTV.Infrastructure.Data.Repositories
|
||||
.ThenInclude(sm => sm.Studios)
|
||||
.Include(i => i.ShowMetadata)
|
||||
.ThenInclude(sm => sm.Actors)
|
||||
.ThenInclude(a => a.Artwork)
|
||||
.Include(i => i.ShowMetadata)
|
||||
.ThenInclude(sm => sm.Artwork)
|
||||
.Include(i => i.LibraryPath)
|
||||
@@ -402,7 +405,7 @@ namespace ErsatzTV.Infrastructure.Data.Repositories
|
||||
|
||||
return await maybeExisting.Match(
|
||||
plexShow => Right<BaseError, MediaItemScanResult<PlexShow>>(
|
||||
new MediaItemScanResult<PlexShow>(plexShow) { IsAdded = true }).AsTask(),
|
||||
new MediaItemScanResult<PlexShow>(plexShow) { IsAdded = false }).AsTask(),
|
||||
async () => await AddPlexShow(dbContext, library, item));
|
||||
}
|
||||
|
||||
@@ -434,6 +437,7 @@ namespace ErsatzTV.Infrastructure.Data.Repositories
|
||||
.ThenInclude(mv => mv.Streams)
|
||||
.Include(e => e.EpisodeMetadata)
|
||||
.ThenInclude(em => em.Actors)
|
||||
.ThenInclude(a => a.Artwork)
|
||||
.OrderBy(i => i.Key)
|
||||
.SingleOrDefaultAsync(i => i.Key == item.Key);
|
||||
|
||||
|
||||
@@ -32,6 +32,7 @@ namespace ErsatzTV.Infrastructure.Plex
|
||||
await service.GetLibraries(token.AuthToken).Map(r => r.MediaContainer.Directory);
|
||||
return directory
|
||||
// .Filter(l => l.Hidden == 0)
|
||||
.Filter(l => l.Type.ToLowerInvariant() is "movie" or "show")
|
||||
.Map(Project)
|
||||
.Somes()
|
||||
.ToList();
|
||||
|
||||
@@ -36,6 +36,7 @@ namespace ErsatzTV.Infrastructure.Search
|
||||
private const string TagField = "tag";
|
||||
private const string PlotField = "plot";
|
||||
private const string LibraryNameField = "library_name";
|
||||
private const string LibraryIdField = "library_id";
|
||||
private const string TitleAndYearField = "title_and_year";
|
||||
private const string JumpLetterField = "jump_letter";
|
||||
private const string ReleaseDateField = "release_date";
|
||||
@@ -62,7 +63,7 @@ namespace ErsatzTV.Infrastructure.Search
|
||||
_cultureInfos = CultureInfo.GetCultures(CultureTypes.NeutralCultures).ToList();
|
||||
}
|
||||
|
||||
public int Version => 7;
|
||||
public int Version => 9;
|
||||
|
||||
public Task<bool> Initialize(ILocalFileSystem localFileSystem)
|
||||
{
|
||||
@@ -252,6 +253,7 @@ namespace ErsatzTV.Infrastructure.Search
|
||||
new TextField(TitleField, metadata.Title, Field.Store.NO),
|
||||
new StringField(SortTitleField, metadata.SortTitle.ToLowerInvariant(), Field.Store.NO),
|
||||
new TextField(LibraryNameField, movie.LibraryPath.Library.Name, Field.Store.NO),
|
||||
new StringField(LibraryIdField, movie.LibraryPath.Library.Id.ToString(), Field.Store.NO),
|
||||
new StringField(TitleAndYearField, GetTitleAndYear(metadata), Field.Store.NO),
|
||||
new StringField(JumpLetterField, GetJumpLetter(metadata), Field.Store.YES)
|
||||
};
|
||||
@@ -339,6 +341,7 @@ namespace ErsatzTV.Infrastructure.Search
|
||||
new TextField(TitleField, metadata.Title, Field.Store.NO),
|
||||
new StringField(SortTitleField, metadata.SortTitle.ToLowerInvariant(), Field.Store.NO),
|
||||
new TextField(LibraryNameField, show.LibraryPath.Library.Name, Field.Store.NO),
|
||||
new StringField(LibraryIdField, show.LibraryPath.Library.Id.ToString(), Field.Store.NO),
|
||||
new StringField(TitleAndYearField, GetTitleAndYear(metadata), Field.Store.NO),
|
||||
new StringField(JumpLetterField, GetJumpLetter(metadata), Field.Store.YES)
|
||||
};
|
||||
@@ -419,6 +422,7 @@ namespace ErsatzTV.Infrastructure.Search
|
||||
new TextField(TitleField, metadata.Title, Field.Store.NO),
|
||||
new StringField(SortTitleField, metadata.SortTitle.ToLowerInvariant(), Field.Store.NO),
|
||||
new TextField(LibraryNameField, artist.LibraryPath.Library.Name, Field.Store.NO),
|
||||
new StringField(LibraryIdField, artist.LibraryPath.Library.Id.ToString(), Field.Store.NO),
|
||||
new StringField(TitleAndYearField, GetTitleAndYear(metadata), Field.Store.NO),
|
||||
new StringField(JumpLetterField, GetJumpLetter(metadata), Field.Store.YES)
|
||||
};
|
||||
@@ -480,6 +484,7 @@ namespace ErsatzTV.Infrastructure.Search
|
||||
new TextField(TitleField, metadata.Title, Field.Store.NO),
|
||||
new StringField(SortTitleField, metadata.SortTitle.ToLowerInvariant(), Field.Store.NO),
|
||||
new TextField(LibraryNameField, musicVideo.LibraryPath.Library.Name, Field.Store.NO),
|
||||
new StringField(LibraryIdField, musicVideo.LibraryPath.Library.Id.ToString(), Field.Store.NO),
|
||||
new StringField(TitleAndYearField, GetTitleAndYear(metadata), Field.Store.NO),
|
||||
new StringField(JumpLetterField, GetJumpLetter(metadata), Field.Store.YES)
|
||||
};
|
||||
@@ -543,7 +548,7 @@ namespace ErsatzTV.Infrastructure.Search
|
||||
}
|
||||
|
||||
private static string GetTitleAndYear(Metadata metadata) =>
|
||||
$"{metadata.Title}_{metadata.Year}";
|
||||
$"{metadata.Title}_{metadata.Year}".ToLowerInvariant();
|
||||
|
||||
private static string GetJumpLetter(Metadata metadata)
|
||||
{
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
<col/>
|
||||
<col/>
|
||||
<col/>
|
||||
<col style="width: 180px;"/>
|
||||
<col style="width: 240px;"/>
|
||||
</ColGroup>
|
||||
<HeaderContent>
|
||||
<MudTh>Library Kind</MudTh>
|
||||
@@ -60,6 +60,11 @@
|
||||
</MudIconButton>
|
||||
</MudTooltip>
|
||||
}
|
||||
<MudTooltip Text="Search Library">
|
||||
<MudIconButton Icon="@Icons.Material.Filled.Search"
|
||||
Link="@($"/search?query=library_id%3a{context.Id}")">
|
||||
</MudIconButton>
|
||||
</MudTooltip>
|
||||
@if (context is LocalLibraryViewModel)
|
||||
{
|
||||
<MudTooltip Text="Edit Library">
|
||||
|
||||
+48
-11
@@ -6,21 +6,58 @@ Movies, Shows, Artists and Music Videos can be searched using the search box nex
|
||||
|
||||
## Search Fields
|
||||
|
||||
The following fields are available for searching:
|
||||
The `title` field of all media types is searched by default if no other field is specified.
|
||||
|
||||
- `title`: The movie, show, artist or music video name/title
|
||||
- `genre`: The movie, show, or artist genre
|
||||
- `tag`: The movie or show tag (not available with Plex metadata)
|
||||
### Movies
|
||||
|
||||
The following fields are available for searching movies:
|
||||
|
||||
- `title`: The movie title
|
||||
- `genre`: The movie genre
|
||||
- `tag`: The movie tag (not available with Plex metadata)
|
||||
- `plot`: The movie plot
|
||||
- `studio`: The movie studio
|
||||
- `actor`: An actor from the movie
|
||||
- `library_name`: The name of the library that contains the movie
|
||||
- `language`: The movie audio stream language
|
||||
- `release_date`: The movie release date (YYYYMMDD)
|
||||
- `type`: Always `movie`
|
||||
|
||||
### Shows
|
||||
|
||||
The following fields are available for searching shows:
|
||||
|
||||
- `title`: The show title
|
||||
- `genre`: The show genre
|
||||
- `tag`: The show tag (not available with Plex metadata)
|
||||
- `plot`: The show plot
|
||||
- `studio`: The show studio
|
||||
- `actor`: An actor from the show
|
||||
- `library_name`: The name of the library that contains the show
|
||||
- `language`: The show audio stream language
|
||||
- `release_date`: The show release date (YYYYMMDD)
|
||||
- `type`: Always `show`
|
||||
|
||||
### Artists
|
||||
|
||||
The following fields are available for searching artists:
|
||||
|
||||
- `title`: The artist name
|
||||
- `genre`: The artist genre
|
||||
- `style`: The artist style
|
||||
- `mood`: The artist mood
|
||||
- `plot`: The movie or show plot
|
||||
- `studio`: The movie or show studio
|
||||
- `library_name`: The name of the library
|
||||
- `language`: The movie, show or music video audio stream language
|
||||
- `release_date`: The movie or show release date (YYYYMMDD)
|
||||
- `type`: The media item type: `movie`, `show`, `artist` or `music_video`
|
||||
- `library_name`: The name of the library that contains the artist
|
||||
- `type`: Always `artist`
|
||||
|
||||
Note that the `title` field is searched by default if no other field is specified.
|
||||
### Music Videos
|
||||
|
||||
The following fields are available for searching music videos:
|
||||
|
||||
- `title`: The music video title
|
||||
- `genre`: The music video genre
|
||||
- `library_name`: The name of the library that contains the music video
|
||||
- `language`: The music video audio stream language
|
||||
- `type`: Always `music_video`
|
||||
|
||||
## Sample Searches
|
||||
|
||||
|
||||
Reference in New Issue
Block a user