Browse Source

add show_content_rating to search index (#1647)

pull/1648/head
Jason Dove 2 years ago committed by GitHub
parent
commit
b21d16b0f1
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 2
      CHANGELOG.md
  2. 7
      ErsatzTV.Infrastructure/Search/ElasticSearchIndex.cs
  3. 37
      ErsatzTV.Infrastructure/Search/LuceneSearchIndex.cs
  4. 3
      ErsatzTV.Infrastructure/Search/Models/ElasticSearchItem.cs

2
CHANGELOG.md

@ -5,7 +5,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
## [Unreleased] ## [Unreleased]
### Added ### Added
- Add `show_studio` to search index for seasons and episodes - Add `show_studio` and `show_content_rating` to search index for seasons and episodes
- Add two new global subtitle settings: - Add two new global subtitle settings:
- `Use embedded subtitles` - `Use embedded subtitles`
- Default value: `true` - Default value: `true`

7
ErsatzTV.Infrastructure/Search/ElasticSearchIndex.cs

@ -46,7 +46,7 @@ public class ElasticSearchIndex : ISearchIndex
return exists.IsValidResponse; return exists.IsValidResponse;
} }
public int Version => 41; public int Version => 42;
public async Task<bool> Initialize( public async Task<bool> Initialize(
ILocalFileSystem localFileSystem, ILocalFileSystem localFileSystem,
@ -162,7 +162,7 @@ public class ElasticSearchIndex : ISearchIndex
var items = new List<MinimalElasticSearchItem>(); var items = new List<MinimalElasticSearchItem>();
var totalCount = 0; var totalCount = 0;
Query parsedQuery = LuceneSearchIndex.ParseQuery(query); Query parsedQuery = LuceneSearchIndex.ParseQuery(query, false);
SearchResponse<MinimalElasticSearchItem> response = await _client.SearchAsync<MinimalElasticSearchItem>( SearchResponse<MinimalElasticSearchItem> response = await _client.SearchAsync<MinimalElasticSearchItem>(
s => s.Index(IndexName) s => s.Index(IndexName)
@ -238,6 +238,7 @@ public class ElasticSearchIndex : ISearchIndex
.Text(t => t.ShowGenre, t => t.Store(false)) .Text(t => t.ShowGenre, t => t.Store(false))
.Text(t => t.ShowTag, t => t.Store(false)) .Text(t => t.ShowTag, t => t.Store(false))
.Text(t => t.ShowStudio, t => t.Store(false)) .Text(t => t.ShowStudio, t => t.Store(false))
.Keyword(t => t.ShowContentRating, t => t.Store(false))
.Text(t => t.Style, t => t.Store(false)) .Text(t => t.Style, t => t.Store(false))
.Text(t => t.Mood, t => t.Store(false)) .Text(t => t.Mood, t => t.Store(false))
.Text(t => t.Album, t => t.Store(false)) .Text(t => t.Album, t => t.Store(false))
@ -413,6 +414,7 @@ public class ElasticSearchIndex : ISearchIndex
ShowGenre = showMetadata.Genres.Map(g => g.Name).ToList(), ShowGenre = showMetadata.Genres.Map(g => g.Name).ToList(),
ShowTag = showMetadata.Tags.Map(t => t.Name).ToList(), ShowTag = showMetadata.Tags.Map(t => t.Name).ToList(),
ShowStudio = showMetadata.Studios.Map(s => s.Name).ToList(), ShowStudio = showMetadata.Studios.Map(s => s.Name).ToList(),
ShowContentRating = GetContentRatings(showMetadata.ContentRating),
Language = await GetLanguages( Language = await GetLanguages(
searchRepository, searchRepository,
await searchRepository.GetLanguagesForSeason(season)), await searchRepository.GetLanguagesForSeason(season)),
@ -614,6 +616,7 @@ public class ElasticSearchIndex : ISearchIndex
doc.ShowGenre = showMetadata.Genres.Map(g => g.Name).ToList(); doc.ShowGenre = showMetadata.Genres.Map(g => g.Name).ToList();
doc.ShowTag = showMetadata.Tags.Map(t => t.Name).ToList(); doc.ShowTag = showMetadata.Tags.Map(t => t.Name).ToList();
doc.ShowStudio = showMetadata.Studios.Map(s => s.Name).ToList(); doc.ShowStudio = showMetadata.Studios.Map(s => s.Name).ToList();
doc.ShowContentRating = GetContentRatings(showMetadata.ContentRating);
} }
AddStatistics(doc, episode.MediaVersions); AddStatistics(doc, episode.MediaVersions);

37
ErsatzTV.Infrastructure/Search/LuceneSearchIndex.cs

@ -64,6 +64,7 @@ public sealed class LuceneSearchIndex : ISearchIndex
internal const string ShowGenreField = "show_genre"; internal const string ShowGenreField = "show_genre";
internal const string ShowTagField = "show_tag"; internal const string ShowTagField = "show_tag";
internal const string ShowStudioField = "show_studio"; internal const string ShowStudioField = "show_studio";
internal const string ShowContentRatingField = "show_content_rating";
internal const string MetadataKindField = "metadata_kind"; internal const string MetadataKindField = "metadata_kind";
internal const string VideoCodecField = "video_codec"; internal const string VideoCodecField = "video_codec";
internal const string VideoDynamicRange = "video_dynamic_range"; internal const string VideoDynamicRange = "video_dynamic_range";
@ -113,7 +114,7 @@ public sealed class LuceneSearchIndex : ISearchIndex
return Task.FromResult(directoryExists && fileExists); return Task.FromResult(directoryExists && fileExists);
} }
public int Version => 41; public int Version => 42;
public async Task<bool> Initialize( public async Task<bool> Initialize(
ILocalFileSystem localFileSystem, ILocalFileSystem localFileSystem,
@ -736,6 +737,15 @@ public sealed class LuceneSearchIndex : ISearchIndex
doc.Add(new TextField(ShowStudioField, studio.Name, Field.Store.NO)); doc.Add(new TextField(ShowStudioField, studio.Name, Field.Store.NO));
} }
if (!string.IsNullOrWhiteSpace(showMetadata.ContentRating))
{
foreach (string contentRating in (showMetadata.ContentRating ?? string.Empty).Split("/")
.Map(x => x.Trim()).Where(x => !string.IsNullOrWhiteSpace(x)))
{
doc.Add(new StringField(ShowContentRatingField, contentRating, Field.Store.NO));
}
}
List<string> languages = await searchRepository.GetLanguagesForSeason(season); List<string> languages = await searchRepository.GetLanguagesForSeason(season);
await AddLanguages(searchRepository, doc, languages); await AddLanguages(searchRepository, doc, languages);
@ -1017,6 +1027,15 @@ public sealed class LuceneSearchIndex : ISearchIndex
{ {
doc.Add(new TextField(ShowStudioField, studio.Name, Field.Store.NO)); doc.Add(new TextField(ShowStudioField, studio.Name, Field.Store.NO));
} }
if (!string.IsNullOrWhiteSpace(showMetadata.ContentRating))
{
foreach (string contentRating in (showMetadata.ContentRating ?? string.Empty).Split("/")
.Map(x => x.Trim()).Where(x => !string.IsNullOrWhiteSpace(x)))
{
doc.Add(new StringField(ShowContentRatingField, contentRating, Field.Store.NO));
}
}
} }
if (!string.IsNullOrWhiteSpace(metadata.Title)) if (!string.IsNullOrWhiteSpace(metadata.Title))
@ -1353,16 +1372,20 @@ public sealed class LuceneSearchIndex : ISearchIndex
doc.Get(TypeField, CultureInfo.InvariantCulture), doc.Get(TypeField, CultureInfo.InvariantCulture),
Convert.ToInt32(doc.Get(IdField, CultureInfo.InvariantCulture), CultureInfo.InvariantCulture)); Convert.ToInt32(doc.Get(IdField, CultureInfo.InvariantCulture), CultureInfo.InvariantCulture));
internal static Query ParseQuery(string query) internal static Query ParseQuery(string query, bool useCustomAnalyzers = true)
{ {
using var analyzer = new StandardAnalyzer(AppLuceneVersion); using var analyzer = new StandardAnalyzer(AppLuceneVersion);
var customAnalyzers = new Dictionary<string, Analyzer> var customAnalyzers = new Dictionary<string, Analyzer>();
if (useCustomAnalyzers)
{ {
{ ContentRatingField, new KeywordAnalyzer() }, customAnalyzers.Add(ShowContentRatingField, new KeywordAnalyzer());
{ StateField, new KeywordAnalyzer() } customAnalyzers.Add(ContentRatingField, new KeywordAnalyzer());
}; customAnalyzers.Add(StateField, new KeywordAnalyzer());
}
using var analyzerWrapper = new PerFieldAnalyzerWrapper(analyzer, customAnalyzers); using var analyzerWrapper = new PerFieldAnalyzerWrapper(analyzer, customAnalyzers);
QueryParser parser = new CustomMultiFieldQueryParser(AppLuceneVersion, new[] { TitleField }, analyzerWrapper); QueryParser parser = new CustomMultiFieldQueryParser(AppLuceneVersion, [TitleField], analyzerWrapper);
parser.AllowLeadingWildcard = true; parser.AllowLeadingWildcard = true;
return ParseQuery(query, parser); return ParseQuery(query, parser);
} }

3
ErsatzTV.Infrastructure/Search/Models/ElasticSearchItem.cs

@ -118,6 +118,9 @@ public class ElasticSearchItem : MinimalElasticSearchItem
[JsonPropertyName(LuceneSearchIndex.ShowStudioField)] [JsonPropertyName(LuceneSearchIndex.ShowStudioField)]
public List<string> ShowStudio { get; set; } public List<string> ShowStudio { get; set; }
[JsonPropertyName(LuceneSearchIndex.ShowContentRatingField)]
public List<string> ShowContentRating { get; set; }
[JsonPropertyName(LuceneSearchIndex.StyleField)] [JsonPropertyName(LuceneSearchIndex.StyleField)]
public List<string> Style { get; set; } public List<string> Style { get; set; }

Loading…
Cancel
Save