add chapters to search index (#2199)
This commit is contained in:
@@ -114,6 +114,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
||||
- `duration`: when the content is live and does not have duration metadata, this must be provided to allow scheduling
|
||||
- The remote stream definition (YAML file) may provide either a `url` or a `script`
|
||||
- If both are provided, `url` will be used
|
||||
- Include number of chapters in search index as `chapters`
|
||||
|
||||
### Changed
|
||||
- Allow `Other Video` libraries and `Image` libraries to use the same folders
|
||||
|
||||
@@ -35,6 +35,8 @@ public class SearchRepository : ISearchRepository
|
||||
.Include(mi => (mi as Movie).MovieMetadata)
|
||||
.ThenInclude(em => em.Guids)
|
||||
.Include(mi => (mi as Movie).MediaVersions)
|
||||
.ThenInclude(mv => mv.Chapters)
|
||||
.Include(mi => (mi as Movie).MediaVersions)
|
||||
.ThenInclude(mm => mm.Streams)
|
||||
.Include(mi => (mi as Episode).EpisodeMetadata)
|
||||
.ThenInclude(em => em.Genres)
|
||||
@@ -51,6 +53,8 @@ public class SearchRepository : ISearchRepository
|
||||
.Include(mi => (mi as Episode).EpisodeMetadata)
|
||||
.ThenInclude(em => em.Guids)
|
||||
.Include(mi => (mi as Episode).MediaVersions)
|
||||
.ThenInclude(mv => mv.Chapters)
|
||||
.Include(mi => (mi as Episode).MediaVersions)
|
||||
.ThenInclude(em => em.Streams)
|
||||
.Include(mi => (mi as Episode).MediaVersions)
|
||||
.ThenInclude(em => em.MediaFiles)
|
||||
@@ -108,6 +112,8 @@ public class SearchRepository : ISearchRepository
|
||||
.Include(mi => (mi as MusicVideo).MusicVideoMetadata)
|
||||
.ThenInclude(mm => mm.Guids)
|
||||
.Include(mi => (mi as MusicVideo).MediaVersions)
|
||||
.ThenInclude(mv => mv.Chapters)
|
||||
.Include(mi => (mi as MusicVideo).MediaVersions)
|
||||
.ThenInclude(mm => mm.Streams)
|
||||
.Include(mi => (mi as Artist).ArtistMetadata)
|
||||
.ThenInclude(mm => mm.Genres)
|
||||
@@ -132,6 +138,8 @@ public class SearchRepository : ISearchRepository
|
||||
.Include(mi => (mi as OtherVideo).OtherVideoMetadata)
|
||||
.ThenInclude(ovm => ovm.Guids)
|
||||
.Include(mi => (mi as OtherVideo).MediaVersions)
|
||||
.ThenInclude(mv => mv.Chapters)
|
||||
.Include(mi => (mi as OtherVideo).MediaVersions)
|
||||
.ThenInclude(ovm => ovm.Streams)
|
||||
.Include(mi => (mi as Song).SongMetadata)
|
||||
.ThenInclude(mm => mm.Tags)
|
||||
@@ -140,6 +148,8 @@ public class SearchRepository : ISearchRepository
|
||||
.Include(mi => (mi as Song).SongMetadata)
|
||||
.ThenInclude(mm => mm.Guids)
|
||||
.Include(mi => (mi as Song).MediaVersions)
|
||||
.ThenInclude(mv => mv.Chapters)
|
||||
.Include(mi => (mi as Song).MediaVersions)
|
||||
.ThenInclude(mm => mm.Streams)
|
||||
.Include(mi => (mi as Image).ImageMetadata)
|
||||
.ThenInclude(mm => mm.Tags)
|
||||
@@ -148,6 +158,8 @@ public class SearchRepository : ISearchRepository
|
||||
.Include(mi => (mi as Image).ImageMetadata)
|
||||
.ThenInclude(mm => mm.Guids)
|
||||
.Include(mi => (mi as Image).MediaVersions)
|
||||
.ThenInclude(mv => mv.Chapters)
|
||||
.Include(mi => (mi as Image).MediaVersions)
|
||||
.ThenInclude(mm => mm.Streams)
|
||||
.Include(mi => (mi as Image).MediaVersions)
|
||||
.ThenInclude(mm => mm.MediaFiles)
|
||||
@@ -158,6 +170,8 @@ public class SearchRepository : ISearchRepository
|
||||
.Include(mi => (mi as RemoteStream).RemoteStreamMetadata)
|
||||
.ThenInclude(mm => mm.Guids)
|
||||
.Include(mi => (mi as RemoteStream).MediaVersions)
|
||||
.ThenInclude(mv => mv.Chapters)
|
||||
.Include(mi => (mi as RemoteStream).MediaVersions)
|
||||
.ThenInclude(mm => mm.Streams)
|
||||
.Include(mi => (mi as RemoteStream).MediaVersions)
|
||||
.ThenInclude(mm => mm.MediaFiles)
|
||||
@@ -271,6 +285,8 @@ public class SearchRepository : ISearchRepository
|
||||
.Include(mi => (mi as Movie).MovieMetadata)
|
||||
.ThenInclude(mm => mm.Guids)
|
||||
.Include(mi => (mi as Movie).MediaVersions)
|
||||
.ThenInclude(mv => mv.Chapters)
|
||||
.Include(mi => (mi as Movie).MediaVersions)
|
||||
.ThenInclude(mm => mm.Streams)
|
||||
.Include(mi => (mi as Episode).EpisodeMetadata)
|
||||
.ThenInclude(em => em.Genres)
|
||||
@@ -287,6 +303,8 @@ public class SearchRepository : ISearchRepository
|
||||
.Include(mi => (mi as Episode).EpisodeMetadata)
|
||||
.ThenInclude(em => em.Guids)
|
||||
.Include(mi => (mi as Episode).MediaVersions)
|
||||
.ThenInclude(mv => mv.Chapters)
|
||||
.Include(mi => (mi as Episode).MediaVersions)
|
||||
.ThenInclude(em => em.Streams)
|
||||
.Include(mi => (mi as Episode).MediaVersions)
|
||||
.ThenInclude(em => em.MediaFiles)
|
||||
@@ -344,6 +362,8 @@ public class SearchRepository : ISearchRepository
|
||||
.Include(mi => (mi as MusicVideo).MusicVideoMetadata)
|
||||
.ThenInclude(mm => mm.Guids)
|
||||
.Include(mi => (mi as MusicVideo).MediaVersions)
|
||||
.ThenInclude(mv => mv.Chapters)
|
||||
.Include(mi => (mi as MusicVideo).MediaVersions)
|
||||
.ThenInclude(mm => mm.Streams)
|
||||
.Include(mi => (mi as Artist).ArtistMetadata)
|
||||
.ThenInclude(mm => mm.Genres)
|
||||
@@ -368,6 +388,8 @@ public class SearchRepository : ISearchRepository
|
||||
.Include(mi => (mi as OtherVideo).OtherVideoMetadata)
|
||||
.ThenInclude(ovm => ovm.Guids)
|
||||
.Include(mi => (mi as OtherVideo).MediaVersions)
|
||||
.ThenInclude(mv => mv.Chapters)
|
||||
.Include(mi => (mi as OtherVideo).MediaVersions)
|
||||
.ThenInclude(ovm => ovm.Streams)
|
||||
.Include(mi => (mi as Song).SongMetadata)
|
||||
.ThenInclude(mm => mm.Tags)
|
||||
@@ -376,6 +398,8 @@ public class SearchRepository : ISearchRepository
|
||||
.Include(mi => (mi as Song).SongMetadata)
|
||||
.ThenInclude(mm => mm.Guids)
|
||||
.Include(mi => (mi as Song).MediaVersions)
|
||||
.ThenInclude(mv => mv.Chapters)
|
||||
.Include(mi => (mi as Song).MediaVersions)
|
||||
.ThenInclude(mm => mm.Streams)
|
||||
.Include(mi => (mi as Image).ImageMetadata)
|
||||
.ThenInclude(mm => mm.Tags)
|
||||
@@ -384,6 +408,8 @@ public class SearchRepository : ISearchRepository
|
||||
.Include(mi => (mi as Image).ImageMetadata)
|
||||
.ThenInclude(mm => mm.Guids)
|
||||
.Include(mi => (mi as Image).MediaVersions)
|
||||
.ThenInclude(mv => mv.Chapters)
|
||||
.Include(mi => (mi as Image).MediaVersions)
|
||||
.ThenInclude(mm => mm.Streams)
|
||||
.Include(mi => (mi as Image).MediaVersions)
|
||||
.ThenInclude(mm => mm.MediaFiles)
|
||||
@@ -394,6 +420,8 @@ public class SearchRepository : ISearchRepository
|
||||
.Include(mi => (mi as RemoteStream).RemoteStreamMetadata)
|
||||
.ThenInclude(mm => mm.Guids)
|
||||
.Include(mi => (mi as RemoteStream).MediaVersions)
|
||||
.ThenInclude(mv => mv.Chapters)
|
||||
.Include(mi => (mi as RemoteStream).MediaVersions)
|
||||
.ThenInclude(mm => mm.Streams)
|
||||
.Include(mi => (mi as RemoteStream).MediaVersions)
|
||||
.ThenInclude(mm => mm.MediaFiles)
|
||||
|
||||
@@ -14,6 +14,7 @@ public class CustomMultiFieldQueryParser : MultiFieldQueryParser
|
||||
{
|
||||
private static readonly List<string> NumericFields =
|
||||
[
|
||||
LuceneSearchIndex.ChaptersField,
|
||||
LuceneSearchIndex.MinutesField,
|
||||
LuceneSearchIndex.SecondsField,
|
||||
LuceneSearchIndex.HeightField,
|
||||
|
||||
@@ -49,7 +49,7 @@ public class ElasticSearchIndex : ISearchIndex
|
||||
return exists.IsValidResponse;
|
||||
}
|
||||
|
||||
public int Version => 47;
|
||||
public int Version => 48;
|
||||
|
||||
public async Task<bool> Initialize(
|
||||
ILocalFileSystem localFileSystem,
|
||||
@@ -926,6 +926,7 @@ public class ElasticSearchIndex : ISearchIndex
|
||||
{
|
||||
foreach (MediaVersion version in mediaVersions.HeadOrNone())
|
||||
{
|
||||
doc.Chapters = (version.Chapters ?? []).Count;
|
||||
doc.Minutes = (int)Math.Ceiling(version.Duration.TotalMinutes);
|
||||
doc.Seconds = (int)Math.Ceiling(version.Duration.TotalSeconds);
|
||||
|
||||
|
||||
@@ -79,6 +79,7 @@ public sealed class LuceneSearchIndex : ISearchIndex
|
||||
internal const string AddedDateField = "added_date";
|
||||
internal const string ReleaseDateField = "release_date";
|
||||
internal const string VideoBitDepthField = "video_bit_depth";
|
||||
internal const string ChaptersField = "chapters";
|
||||
|
||||
public const string MovieType = "movie";
|
||||
public const string ShowType = "show";
|
||||
@@ -118,7 +119,7 @@ public sealed class LuceneSearchIndex : ISearchIndex
|
||||
return Task.FromResult(directoryExists && fileExists);
|
||||
}
|
||||
|
||||
public int Version => 48;
|
||||
public int Version => 49;
|
||||
|
||||
public async Task<bool> Initialize(
|
||||
ILocalFileSystem localFileSystem,
|
||||
@@ -1508,6 +1509,8 @@ public sealed class LuceneSearchIndex : ISearchIndex
|
||||
{
|
||||
foreach (MediaVersion version in mediaVersions)
|
||||
{
|
||||
doc.Add(new Int32Field(ChaptersField, (version.Chapters ?? []).Count, Field.Store.NO));
|
||||
|
||||
doc.Add(new Int32Field(MinutesField, (int)Math.Ceiling(version.Duration.TotalMinutes), Field.Store.NO));
|
||||
doc.Add(new Int32Field(SecondsField, (int)Math.Ceiling(version.Duration.TotalSeconds), Field.Store.NO));
|
||||
|
||||
|
||||
@@ -37,6 +37,9 @@ public class ElasticSearchItem : MinimalElasticSearchItem
|
||||
[JsonPropertyName(LuceneSearchIndex.SubLanguageTagField)]
|
||||
public List<string> SubLanguageTag { get; set; }
|
||||
|
||||
[JsonPropertyName(LuceneSearchIndex.ChaptersField)]
|
||||
public int Chapters { get; set; }
|
||||
|
||||
[JsonPropertyName(LuceneSearchIndex.MinutesField)]
|
||||
public int Minutes { get; set; }
|
||||
|
||||
|
||||
Reference in New Issue
Block a user