use aired for music video release date (#784)
This commit is contained in:
@@ -12,6 +12,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
|||||||
|
|
||||||
### Added
|
### Added
|
||||||
- Add `show_genre` and `show_tag` to search index for seasons and episodes
|
- Add `show_genre` and `show_tag` to search index for seasons and episodes
|
||||||
|
- Use `aired` value to source release date from music video nfo metadata
|
||||||
|
|
||||||
## [0.5.5-beta] - 2022-05-03
|
## [0.5.5-beta] - 2022-05-03
|
||||||
### Fixed
|
### Fixed
|
||||||
|
|||||||
@@ -122,6 +122,7 @@ https://www.themoviedb.org/movie/11-star-wars"));
|
|||||||
Le groupe a également enregistré une version espagnole de ce titre, La reina del baile, pour le marché d'Amérique latine. On peut retrouver ces versions en espagnol des succès de ABBA sur l'abum Oro. Le 18 juin 1976, ABBA a interprété cette chanson lors d'un spectacle télévisé organisé en l'honneur du roi Charles XVI Gustave de Suède, qui venait de se marier. Le titre sera repris en 2011 par Glee dans la saison 2, épisode 20."));
|
Le groupe a également enregistré une version espagnole de ce titre, La reina del baile, pour le marché d'Amérique latine. On peut retrouver ces versions en espagnol des succès de ABBA sur l'abum Oro. Le 18 juin 1976, ABBA a interprété cette chanson lors d'un spectacle télévisé organisé en l'honneur du roi Charles XVI Gustave de Suède, qui venait de se marier. Le titre sera repris en 2011 par Glee dans la saison 2, épisode 20."));
|
||||||
|
|
||||||
nfo.Year.Should().Be(1976);
|
nfo.Year.Should().Be(1976);
|
||||||
|
nfo.Aired.IsNone.Should().BeTrue();
|
||||||
nfo.Genres.Should().BeEquivalentTo(new List<string> { "Pop" });
|
nfo.Genres.Should().BeEquivalentTo(new List<string> { "Pop" });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -141,6 +142,25 @@ Le groupe a également enregistré une version espagnole de ce titre, La reina d
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public async Task MetadataNfo_With_Aired_Should_Return_Nfo()
|
||||||
|
{
|
||||||
|
await using var stream = new MemoryStream(
|
||||||
|
Encoding.UTF8.GetBytes(@"<musicvideo><aired>2022-02-03</aired></musicvideo>"));
|
||||||
|
|
||||||
|
Either<BaseError, MusicVideoNfo> result = await _musicVideoNfoReader.Read(stream);
|
||||||
|
|
||||||
|
result.IsRight.Should().BeTrue();
|
||||||
|
foreach (MusicVideoNfo nfo in result.RightToSeq())
|
||||||
|
{
|
||||||
|
nfo.Aired.IsSome.Should().BeTrue();
|
||||||
|
foreach (DateTime aired in nfo.Aired)
|
||||||
|
{
|
||||||
|
aired.Should().Be(new DateTime(2022, 02, 03));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public async Task MetadataNfo_With_Studios_Should_Return_Nfo()
|
public async Task MetadataNfo_With_Studios_Should_Return_Nfo()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -191,8 +191,8 @@ public class LocalMetadataProvider : ILocalMetadataProvider
|
|||||||
Album = nfo.Album,
|
Album = nfo.Album,
|
||||||
Title = nfo.Title,
|
Title = nfo.Title,
|
||||||
Plot = nfo.Plot,
|
Plot = nfo.Plot,
|
||||||
Year = GetYear(nfo.Year, string.Empty),
|
Year = GetYear(nfo.Year, nfo.Aired),
|
||||||
ReleaseDate = GetAired(nfo.Year, string.Empty),
|
ReleaseDate = GetAired(nfo.Year, nfo.Aired),
|
||||||
Artists = nfo.Artists.Map(a => new MusicVideoArtist { Name = a }).ToList(),
|
Artists = nfo.Artists.Map(a => new MusicVideoArtist { Name = a }).ToList(),
|
||||||
Genres = nfo.Genres.Map(g => new Genre { Name = g }).ToList(),
|
Genres = nfo.Genres.Map(g => new Genre { Name = g }).ToList(),
|
||||||
Tags = nfo.Tags.Map(t => new Tag { Name = t }).ToList(),
|
Tags = nfo.Tags.Map(t => new Tag { Name = t }).ToList(),
|
||||||
@@ -1068,26 +1068,6 @@ public class LocalMetadataProvider : ILocalMetadataProvider
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int? GetYear(int? year, string premiered)
|
|
||||||
{
|
|
||||||
if (year is > 1000)
|
|
||||||
{
|
|
||||||
return year;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (string.IsNullOrWhiteSpace(premiered))
|
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (DateTime.TryParse(premiered, out DateTime parsed))
|
|
||||||
{
|
|
||||||
return parsed.Year;
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static int? GetYear(int? year, Option<DateTime> premiered)
|
private static int? GetYear(int? year, Option<DateTime> premiered)
|
||||||
{
|
{
|
||||||
if (year is > 1000)
|
if (year is > 1000)
|
||||||
@@ -1103,18 +1083,6 @@ public class LocalMetadataProvider : ILocalMetadataProvider
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static DateTime? GetAired(int? year, string aired)
|
|
||||||
{
|
|
||||||
DateTime? fallback = year is > 1000 ? new DateTime(year.Value, 1, 1) : null;
|
|
||||||
|
|
||||||
if (string.IsNullOrWhiteSpace(aired))
|
|
||||||
{
|
|
||||||
return fallback;
|
|
||||||
}
|
|
||||||
|
|
||||||
return DateTime.TryParse(aired, out DateTime parsed) ? parsed : fallback;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static DateTime? GetAired(int? year, Option<DateTime> aired)
|
private static DateTime? GetAired(int? year, Option<DateTime> aired)
|
||||||
{
|
{
|
||||||
DateTime? fallback = year is > 1000 ? new DateTime(year.Value, 1, 1) : null;
|
DateTime? fallback = year is > 1000 ? new DateTime(year.Value, 1, 1) : null;
|
||||||
|
|||||||
@@ -17,6 +17,9 @@ public class MusicVideoNfo
|
|||||||
[XmlElement("plot")]
|
[XmlElement("plot")]
|
||||||
public string Plot { get; set; }
|
public string Plot { get; set; }
|
||||||
|
|
||||||
|
[XmlElement("aired")]
|
||||||
|
public Option<DateTime> Aired { get; set; }
|
||||||
|
|
||||||
[XmlElement("year")]
|
[XmlElement("year")]
|
||||||
public int Year { get; set; }
|
public int Year { get; set; }
|
||||||
|
|
||||||
|
|||||||
@@ -54,6 +54,9 @@ public class MusicVideoNfoReader : NfoReader<MusicVideoNfo>, IMusicVideoNfoReade
|
|||||||
case "year":
|
case "year":
|
||||||
await ReadIntContent(reader, nfo, (musicVideo, year) => musicVideo.Year = year);
|
await ReadIntContent(reader, nfo, (musicVideo, year) => musicVideo.Year = year);
|
||||||
break;
|
break;
|
||||||
|
case "aired":
|
||||||
|
await ReadDateTimeContent(reader, nfo, (show, aired) => show.Aired = aired);
|
||||||
|
break;
|
||||||
case "genre":
|
case "genre":
|
||||||
await ReadStringContent(
|
await ReadStringContent(
|
||||||
reader,
|
reader,
|
||||||
|
|||||||
@@ -28,7 +28,6 @@ WHERE L.MediaKind = 3)");
|
|||||||
|
|
||||||
protected override void Down(MigrationBuilder migrationBuilder)
|
protected override void Down(MigrationBuilder migrationBuilder)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Generated
+4239
File diff suppressed because it is too large
Load Diff
+33
@@ -0,0 +1,33 @@
|
|||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
|
||||||
|
#nullable disable
|
||||||
|
|
||||||
|
namespace ErsatzTV.Infrastructure.Migrations
|
||||||
|
{
|
||||||
|
public partial class Reset_MusicVideoLibraries20220504 : 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)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -29,7 +29,7 @@ public class CustomMultiFieldQueryParser : MultiFieldQueryParser
|
|||||||
if (field == "released_onthisday")
|
if (field == "released_onthisday")
|
||||||
{
|
{
|
||||||
var todayString = DateTime.Today.ToString("*MMdd");
|
var todayString = DateTime.Today.ToString("*MMdd");
|
||||||
return base.GetWildcardQuery("release_date", todayString);
|
return base.GetWildcardQuery(SearchIndex.ReleaseDateField, todayString);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (CustomQueryParser.NumericFields.Contains(field) && int.TryParse(queryText, out int val))
|
if (CustomQueryParser.NumericFields.Contains(field) && int.TryParse(queryText, out int val))
|
||||||
@@ -49,14 +49,14 @@ public class CustomMultiFieldQueryParser : MultiFieldQueryParser
|
|||||||
var todayString = DateTime.UtcNow.ToString("yyyyMMdd");
|
var todayString = DateTime.UtcNow.ToString("yyyyMMdd");
|
||||||
var dateString = start.ToString("yyyyMMdd");
|
var dateString = start.ToString("yyyyMMdd");
|
||||||
|
|
||||||
return base.GetRangeQuery("release_date", dateString, todayString, true, true);
|
return base.GetRangeQuery(SearchIndex.ReleaseDateField, dateString, todayString, true, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (field == "released_notinthelast" && CustomQueryParser.ParseStart(queryText, out DateTime finish))
|
if (field == "released_notinthelast" && CustomQueryParser.ParseStart(queryText, out DateTime finish))
|
||||||
{
|
{
|
||||||
var dateString = finish.ToString("yyyyMMdd");
|
var dateString = finish.ToString("yyyyMMdd");
|
||||||
|
|
||||||
return base.GetRangeQuery("release_date", "00000000", dateString, false, false);
|
return base.GetRangeQuery(SearchIndex.ReleaseDateField, "00000000", dateString, false, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (field == "added_inthelast" && CustomQueryParser.ParseStart(queryText, out DateTime addedStart))
|
if (field == "added_inthelast" && CustomQueryParser.ParseStart(queryText, out DateTime addedStart))
|
||||||
@@ -64,14 +64,14 @@ public class CustomMultiFieldQueryParser : MultiFieldQueryParser
|
|||||||
var todayString = DateTime.UtcNow.ToString("yyyyMMdd");
|
var todayString = DateTime.UtcNow.ToString("yyyyMMdd");
|
||||||
var dateString = addedStart.ToString("yyyyMMdd");
|
var dateString = addedStart.ToString("yyyyMMdd");
|
||||||
|
|
||||||
return base.GetRangeQuery("added_date", dateString, todayString, true, true);
|
return base.GetRangeQuery(SearchIndex.AddedDateField, dateString, todayString, true, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (field == "added_notinthelast" && CustomQueryParser.ParseStart(queryText, out DateTime addedFinish))
|
if (field == "added_notinthelast" && CustomQueryParser.ParseStart(queryText, out DateTime addedFinish))
|
||||||
{
|
{
|
||||||
var dateString = addedFinish.ToString("yyyyMMdd");
|
var dateString = addedFinish.ToString("yyyyMMdd");
|
||||||
|
|
||||||
return base.GetRangeQuery("added_date", "00000000", dateString, false, false);
|
return base.GetRangeQuery(SearchIndex.AddedDateField, "00000000", dateString, false, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
return base.GetFieldQuery(field, queryText, slop);
|
return base.GetFieldQuery(field, queryText, slop);
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ public class CustomQueryParser : QueryParser
|
|||||||
if (field == "released_onthisday")
|
if (field == "released_onthisday")
|
||||||
{
|
{
|
||||||
var todayString = DateTime.Today.ToString("*MMdd");
|
var todayString = DateTime.Today.ToString("*MMdd");
|
||||||
return base.GetWildcardQuery("release_date", todayString);
|
return base.GetWildcardQuery(SearchIndex.ReleaseDateField, todayString);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (NumericFields.Contains(field) && int.TryParse(queryText, out int val))
|
if (NumericFields.Contains(field) && int.TryParse(queryText, out int val))
|
||||||
@@ -56,14 +56,14 @@ public class CustomQueryParser : QueryParser
|
|||||||
var todayString = DateTime.UtcNow.ToString("yyyyMMdd");
|
var todayString = DateTime.UtcNow.ToString("yyyyMMdd");
|
||||||
var dateString = start.ToString("yyyyMMdd");
|
var dateString = start.ToString("yyyyMMdd");
|
||||||
|
|
||||||
return base.GetRangeQuery("release_date", dateString, todayString, true, true);
|
return base.GetRangeQuery(SearchIndex.ReleaseDateField, dateString, todayString, true, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (field == "released_notinthelast" && ParseStart(queryText, out DateTime finish))
|
if (field == "released_notinthelast" && ParseStart(queryText, out DateTime finish))
|
||||||
{
|
{
|
||||||
var dateString = finish.ToString("yyyyMMdd");
|
var dateString = finish.ToString("yyyyMMdd");
|
||||||
|
|
||||||
return base.GetRangeQuery("release_date", "00000000", dateString, false, false);
|
return base.GetRangeQuery(SearchIndex.ReleaseDateField, "00000000", dateString, false, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (field == "added_inthelast" && ParseStart(queryText, out DateTime addedStart))
|
if (field == "added_inthelast" && ParseStart(queryText, out DateTime addedStart))
|
||||||
@@ -71,14 +71,14 @@ public class CustomQueryParser : QueryParser
|
|||||||
var todayString = DateTime.UtcNow.ToString("yyyyMMdd");
|
var todayString = DateTime.UtcNow.ToString("yyyyMMdd");
|
||||||
var dateString = addedStart.ToString("yyyyMMdd");
|
var dateString = addedStart.ToString("yyyyMMdd");
|
||||||
|
|
||||||
return base.GetRangeQuery("added_date", dateString, todayString, true, true);
|
return base.GetRangeQuery(SearchIndex.AddedDateField, dateString, todayString, true, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (field == "added_notinthelast" && ParseStart(queryText, out DateTime addedFinish))
|
if (field == "added_notinthelast" && ParseStart(queryText, out DateTime addedFinish))
|
||||||
{
|
{
|
||||||
var dateString = addedFinish.ToString("yyyyMMdd");
|
var dateString = addedFinish.ToString("yyyyMMdd");
|
||||||
|
|
||||||
return base.GetRangeQuery("added_date", "00000000", dateString, false, false);
|
return base.GetRangeQuery(SearchIndex.AddedDateField, "00000000", dateString, false, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
return base.GetFieldQuery(field, queryText, slop);
|
return base.GetFieldQuery(field, queryText, slop);
|
||||||
|
|||||||
@@ -38,8 +38,6 @@ public sealed class SearchIndex : ISearchIndex
|
|||||||
private const string LibraryIdField = "library_id";
|
private const string LibraryIdField = "library_id";
|
||||||
private const string TitleAndYearField = "title_and_year";
|
private const string TitleAndYearField = "title_and_year";
|
||||||
private const string JumpLetterField = "jump_letter";
|
private const string JumpLetterField = "jump_letter";
|
||||||
private const string ReleaseDateField = "release_date";
|
|
||||||
private const string AddedDateField = "added_date";
|
|
||||||
private const string StudioField = "studio";
|
private const string StudioField = "studio";
|
||||||
private const string LanguageField = "language";
|
private const string LanguageField = "language";
|
||||||
private const string StyleField = "style";
|
private const string StyleField = "style";
|
||||||
@@ -62,6 +60,8 @@ public sealed class SearchIndex : ISearchIndex
|
|||||||
internal const string WidthField = "width";
|
internal const string WidthField = "width";
|
||||||
internal const string SeasonNumberField = "season_number";
|
internal const string SeasonNumberField = "season_number";
|
||||||
internal const string EpisodeNumberField = "episode_number";
|
internal const string EpisodeNumberField = "episode_number";
|
||||||
|
internal const string AddedDateField = "added_date";
|
||||||
|
internal const string ReleaseDateField = "release_date";
|
||||||
|
|
||||||
public const string MovieType = "movie";
|
public const string MovieType = "movie";
|
||||||
public const string ShowType = "show";
|
public const string ShowType = "show";
|
||||||
|
|||||||
Reference in New Issue
Block a user