filler rework (#449)
* add chapter statistics and new filler options * refactor playout builder * more refactor prep for filler * rewrite schedulers * refactor collectionkey * add tail filler kind * migrate tail filler to filler preset * optionally show filler * fix playout detail row count * remove duration tail filler options * implement tail and fallback in flood scheduler * implement tail and fallback in one scheduler * implement tail and fallback in multiple scheduler * implement looping fallback filler * more duration tests * start to add post-roll filler to flood * rework playoutitem filler tagging * rework scheduler logging * calculate whether configured filler will fit * implement pre-roll and post-roll duration and count filler * improve duration filler calculation * add minutes to search index * update channel guide to work with new filler * add mid-roll filler * don't clone enumerators for filler calculations * support pre-roll and post-roll pad filler * implement mid-roll pad filler * allow clearing filler selections in schedule editor * fix tests * filler config validation * use consistent time zone for tests
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Lucene.Net.Analysis;
|
||||
using Lucene.Net.Index;
|
||||
using Lucene.Net.QueryParsers.Classic;
|
||||
using Lucene.Net.Search;
|
||||
using Lucene.Net.Util;
|
||||
@@ -31,6 +32,13 @@ namespace ErsatzTV.Infrastructure.Search
|
||||
var todayString = DateTime.Today.ToString("*MMdd");
|
||||
return base.GetWildcardQuery("release_date", todayString);
|
||||
}
|
||||
|
||||
if (field == "minutes" && int.TryParse(queryText, out int val))
|
||||
{
|
||||
var bytesRef = new BytesRef();
|
||||
NumericUtils.Int32ToPrefixCoded(val, 0, bytesRef);
|
||||
return NewTermQuery(new Term("minutes", bytesRef));
|
||||
}
|
||||
|
||||
return base.GetFieldQuery(field, queryText, quoted);
|
||||
}
|
||||
@@ -51,8 +59,18 @@ namespace ErsatzTV.Infrastructure.Search
|
||||
|
||||
return base.GetRangeQuery("release_date", "00000000", dateString, false, false);
|
||||
}
|
||||
|
||||
|
||||
return base.GetFieldQuery(field, queryText, slop);
|
||||
}
|
||||
|
||||
protected override Query GetRangeQuery(string field, string part1, string part2, bool startInclusive, bool endInclusive)
|
||||
{
|
||||
if (field == "minutes" && int.TryParse(part1, out int min) && int.TryParse(part2, out int max))
|
||||
{
|
||||
return NumericRangeQuery.NewInt32Range(field, min, max, startInclusive, endInclusive);
|
||||
}
|
||||
|
||||
return base.GetRangeQuery(field, part1, part2, startInclusive, endInclusive);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using ErsatzTV.Core;
|
||||
using Lucene.Net.Analysis;
|
||||
using Lucene.Net.Index;
|
||||
using Lucene.Net.QueryParsers.Classic;
|
||||
using Lucene.Net.Search;
|
||||
using Lucene.Net.Util;
|
||||
@@ -28,6 +29,13 @@ namespace ErsatzTV.Infrastructure.Search
|
||||
var todayString = DateTime.Today.ToString("*MMdd");
|
||||
return base.GetWildcardQuery("release_date", todayString);
|
||||
}
|
||||
|
||||
if (field == "minutes" && int.TryParse(queryText, out int val))
|
||||
{
|
||||
var bytesRef = new BytesRef();
|
||||
NumericUtils.Int32ToPrefixCoded(val, 0, bytesRef);
|
||||
return NewTermQuery(new Term("minutes", bytesRef));
|
||||
}
|
||||
|
||||
return base.GetFieldQuery(field, queryText, quoted);
|
||||
}
|
||||
@@ -52,6 +60,16 @@ namespace ErsatzTV.Infrastructure.Search
|
||||
return base.GetFieldQuery(field, queryText, slop);
|
||||
}
|
||||
|
||||
protected override Query GetRangeQuery(string field, string part1, string part2, bool startInclusive, bool endInclusive)
|
||||
{
|
||||
if (field == "minutes" && int.TryParse(part1, out int min) && int.TryParse(part2, out int max))
|
||||
{
|
||||
return NumericRangeQuery.NewInt32Range(field, 1, min, max, startInclusive, endInclusive);
|
||||
}
|
||||
|
||||
return base.GetRangeQuery(field, part1, part2, startInclusive, endInclusive);
|
||||
}
|
||||
|
||||
internal static bool ParseStart(string text, out DateTime start)
|
||||
{
|
||||
start = SystemTime.MinValueUtc;
|
||||
|
||||
@@ -53,6 +53,7 @@ namespace ErsatzTV.Infrastructure.Search
|
||||
private const string WriterField = "writer";
|
||||
private const string TraktListField = "trakt_list";
|
||||
private const string AlbumField = "album";
|
||||
private const string MinutesField = "minutes";
|
||||
|
||||
public const string MovieType = "movie";
|
||||
public const string ShowType = "show";
|
||||
@@ -76,7 +77,7 @@ namespace ErsatzTV.Infrastructure.Search
|
||||
_initialized = false;
|
||||
}
|
||||
|
||||
public int Version => 17;
|
||||
public int Version => 18;
|
||||
|
||||
public Task<bool> Initialize(ILocalFileSystem localFileSystem)
|
||||
{
|
||||
@@ -301,6 +302,11 @@ namespace ErsatzTV.Infrastructure.Search
|
||||
};
|
||||
|
||||
await AddLanguages(searchRepository, doc, movie.MediaVersions);
|
||||
|
||||
foreach (MediaVersion version in movie.MediaVersions.HeadOrNone())
|
||||
{
|
||||
doc.Add(new Int32Field(MinutesField, (int)Math.Ceiling(version.Duration.TotalMinutes), Field.Store.NO));
|
||||
}
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(metadata.ContentRating))
|
||||
{
|
||||
@@ -574,7 +580,7 @@ namespace ErsatzTV.Infrastructure.Search
|
||||
|
||||
List<string> languages = await searchRepository.GetLanguagesForArtist(artist);
|
||||
await AddLanguages(searchRepository, doc, languages);
|
||||
|
||||
|
||||
foreach (Genre genre in metadata.Genres)
|
||||
{
|
||||
doc.Add(new TextField(GenreField, genre.Name, Field.Store.NO));
|
||||
@@ -622,6 +628,11 @@ namespace ErsatzTV.Infrastructure.Search
|
||||
};
|
||||
|
||||
await AddLanguages(searchRepository, doc, musicVideo.MediaVersions);
|
||||
|
||||
foreach (MediaVersion version in musicVideo.MediaVersions.HeadOrNone())
|
||||
{
|
||||
doc.Add(new Int32Field(MinutesField, (int)Math.Ceiling(version.Duration.TotalMinutes), Field.Store.NO));
|
||||
}
|
||||
|
||||
if (metadata.ReleaseDate.HasValue)
|
||||
{
|
||||
@@ -684,17 +695,24 @@ namespace ErsatzTV.Infrastructure.Search
|
||||
continue;
|
||||
}
|
||||
|
||||
var doc = new Document();
|
||||
doc.Add(new StringField(IdField, episode.Id.ToString(), Field.Store.YES));
|
||||
doc.Add(new StringField(TypeField, EpisodeType, Field.Store.YES));
|
||||
doc.Add(new TextField(TitleField, metadata.Title, Field.Store.NO));
|
||||
doc.Add(new StringField(SortTitleField, metadata.SortTitle.ToLowerInvariant(), Field.Store.NO));
|
||||
doc.Add(new TextField(LibraryNameField, episode.LibraryPath.Library.Name, Field.Store.NO));
|
||||
doc.Add(new StringField(LibraryIdField, episode.LibraryPath.Library.Id.ToString(), Field.Store.NO));
|
||||
doc.Add(new StringField(TitleAndYearField, GetTitleAndYear(metadata), Field.Store.NO));
|
||||
doc.Add(new StringField(JumpLetterField, GetJumpLetter(metadata), Field.Store.YES));
|
||||
var doc = new Document
|
||||
{
|
||||
new StringField(IdField, episode.Id.ToString(), Field.Store.YES),
|
||||
new StringField(TypeField, EpisodeType, Field.Store.YES),
|
||||
new TextField(TitleField, metadata.Title, Field.Store.NO),
|
||||
new StringField(SortTitleField, metadata.SortTitle.ToLowerInvariant(), Field.Store.NO),
|
||||
new TextField(LibraryNameField, episode.LibraryPath.Library.Name, Field.Store.NO),
|
||||
new StringField(LibraryIdField, episode.LibraryPath.Library.Id.ToString(), Field.Store.NO),
|
||||
new StringField(TitleAndYearField, GetTitleAndYear(metadata), Field.Store.NO),
|
||||
new StringField(JumpLetterField, GetJumpLetter(metadata), Field.Store.YES)
|
||||
};
|
||||
|
||||
await AddLanguages(searchRepository, doc, episode.MediaVersions);
|
||||
|
||||
foreach (MediaVersion version in episode.MediaVersions.HeadOrNone())
|
||||
{
|
||||
doc.Add(new Int32Field(MinutesField, (int)Math.Ceiling(version.Duration.TotalMinutes), Field.Store.NO));
|
||||
}
|
||||
|
||||
if (metadata.ReleaseDate.HasValue)
|
||||
{
|
||||
@@ -773,10 +791,15 @@ namespace ErsatzTV.Infrastructure.Search
|
||||
new TextField(LibraryNameField, otherVideo.LibraryPath.Library.Name, Field.Store.NO),
|
||||
new StringField(LibraryIdField, otherVideo.LibraryPath.Library.Id.ToString(), Field.Store.NO),
|
||||
new StringField(TitleAndYearField, GetTitleAndYear(metadata), Field.Store.NO),
|
||||
new StringField(JumpLetterField, GetJumpLetter(metadata), Field.Store.YES)
|
||||
new StringField(JumpLetterField, GetJumpLetter(metadata), Field.Store.YES),
|
||||
};
|
||||
|
||||
await AddLanguages(searchRepository, doc, otherVideo.MediaVersions);
|
||||
|
||||
foreach (MediaVersion version in otherVideo.MediaVersions.HeadOrNone())
|
||||
{
|
||||
doc.Add(new Int32Field(MinutesField, (int)Math.Ceiling(version.Duration.TotalMinutes), Field.Store.NO));
|
||||
}
|
||||
|
||||
foreach (Tag tag in metadata.Tags)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user