Browse Source

fix building playouts in timezones with positive offsets (#368)

pull/370/head
Jason Dove 4 years ago committed by GitHub
parent
commit
e718cb0faf
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 1
      CHANGELOG.md
  2. 2
      ErsatzTV.Application/Emby/Commands/SynchronizeEmbyLibraryByIdHandler.cs
  3. 2
      ErsatzTV.Application/Jellyfin/Commands/SynchronizeJellyfinLibraryByIdHandler.cs
  4. 3
      ErsatzTV.Application/MediaCards/Mapper.cs
  5. 2
      ErsatzTV.Application/MediaSources/Commands/ScanLocalLibraryHandler.cs
  6. 2
      ErsatzTV.Application/Plex/Commands/SynchronizePlexLibraryByIdHandler.cs
  7. 2
      ErsatzTV.Core.Tests/Fakes/FakeFileEntry.cs
  8. 2
      ErsatzTV.Core.Tests/Fakes/FakeLocalFileSystem.cs
  9. 2
      ErsatzTV.Core/Metadata/LocalFileSystem.cs
  10. 10
      ErsatzTV.Core/Metadata/LocalMetadataProvider.cs
  11. 2
      ErsatzTV.Core/Metadata/TelevisionFolderScanner.cs
  12. 4
      ErsatzTV.Core/Scheduling/PlayoutBuilder.cs
  13. 9
      ErsatzTV.Core/SystemTime.cs
  14. 2
      ErsatzTV.Infrastructure/Data/Repositories/TelevisionRepository.cs
  15. 3
      ErsatzTV.Infrastructure/Search/CustomQueryParser.cs

1
CHANGELOG.md

@ -16,6 +16,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
- Use fake image extension (`.jpg`) for artwork in M3U and XMLTV since Kodi detects MIME type from URL - Use fake image extension (`.jpg`) for artwork in M3U and XMLTV since Kodi detects MIME type from URL
- Enable HEAD requests for IPTV image paths since Kodi requires those - Enable HEAD requests for IPTV image paths since Kodi requires those
- Properly display watermark when no other video filters (like scaling or padding) are required - Properly display watermark when no other video filters (like scaling or padding) are required
- Fix building some playouts in timezones with positive offsets (like UTC+2)
## [0.0.56-alpha] - 2021-09-10 ## [0.0.56-alpha] - 2021-09-10
### Added ### Added

2
ErsatzTV.Application/Emby/Commands/SynchronizeEmbyLibraryByIdHandler.cs

@ -67,7 +67,7 @@ namespace ErsatzTV.Application.Emby.Commands
private async Task<Unit> Synchronize(RequestParameters parameters) private async Task<Unit> Synchronize(RequestParameters parameters)
{ {
var lastScan = new DateTimeOffset(parameters.Library.LastScan ?? DateTime.MinValue, TimeSpan.Zero); var lastScan = new DateTimeOffset(parameters.Library.LastScan ?? SystemTime.MinValueUtc, TimeSpan.Zero);
DateTimeOffset nextScan = lastScan + TimeSpan.FromHours(parameters.LibraryRefreshInterval); DateTimeOffset nextScan = lastScan + TimeSpan.FromHours(parameters.LibraryRefreshInterval);
if (parameters.ForceScan || nextScan < DateTimeOffset.Now) if (parameters.ForceScan || nextScan < DateTimeOffset.Now)
{ {

2
ErsatzTV.Application/Jellyfin/Commands/SynchronizeJellyfinLibraryByIdHandler.cs

@ -67,7 +67,7 @@ namespace ErsatzTV.Application.Jellyfin.Commands
private async Task<Unit> Synchronize(RequestParameters parameters) private async Task<Unit> Synchronize(RequestParameters parameters)
{ {
var lastScan = new DateTimeOffset(parameters.Library.LastScan ?? DateTime.MinValue, TimeSpan.Zero); var lastScan = new DateTimeOffset(parameters.Library.LastScan ?? SystemTime.MinValueUtc, TimeSpan.Zero);
DateTimeOffset nextScan = lastScan + TimeSpan.FromHours(parameters.LibraryRefreshInterval); DateTimeOffset nextScan = lastScan + TimeSpan.FromHours(parameters.LibraryRefreshInterval);
if (parameters.ForceScan || nextScan < DateTimeOffset.Now) if (parameters.ForceScan || nextScan < DateTimeOffset.Now)
{ {

3
ErsatzTV.Application/MediaCards/Mapper.cs

@ -1,5 +1,6 @@
using System; using System;
using System.Linq; using System.Linq;
using ErsatzTV.Core;
using ErsatzTV.Core.Domain; using ErsatzTV.Core.Domain;
using ErsatzTV.Core.Emby; using ErsatzTV.Core.Emby;
using ErsatzTV.Core.Jellyfin; using ErsatzTV.Core.Jellyfin;
@ -43,7 +44,7 @@ namespace ErsatzTV.Application.MediaCards
bool isSearchResult) => bool isSearchResult) =>
new( new(
episodeMetadata.EpisodeId, episodeMetadata.EpisodeId,
episodeMetadata.ReleaseDate ?? DateTime.MinValue, episodeMetadata.ReleaseDate ?? SystemTime.MinValueUtc,
episodeMetadata.Episode.Season.Show.ShowMetadata.HeadOrNone().Match( episodeMetadata.Episode.Season.Show.ShowMetadata.HeadOrNone().Match(
m => m.Title ?? string.Empty, m => m.Title ?? string.Empty,
() => string.Empty), () => string.Empty),

2
ErsatzTV.Application/MediaSources/Commands/ScanLocalLibraryHandler.cs

@ -78,7 +78,7 @@ namespace ErsatzTV.Application.MediaSources.Commands
decimal progressMin = (decimal) i / localLibrary.Paths.Count; decimal progressMin = (decimal) i / localLibrary.Paths.Count;
decimal progressMax = (decimal) (i + 1) / localLibrary.Paths.Count; decimal progressMax = (decimal) (i + 1) / localLibrary.Paths.Count;
var lastScan = new DateTimeOffset(libraryPath.LastScan ?? DateTime.MinValue, TimeSpan.Zero); var lastScan = new DateTimeOffset(libraryPath.LastScan ?? SystemTime.MinValueUtc, TimeSpan.Zero);
DateTimeOffset nextScan = lastScan + TimeSpan.FromHours(libraryRefreshInterval); DateTimeOffset nextScan = lastScan + TimeSpan.FromHours(libraryRefreshInterval);
if (forceScan || nextScan < DateTimeOffset.Now) if (forceScan || nextScan < DateTimeOffset.Now)
{ {

2
ErsatzTV.Application/Plex/Commands/SynchronizePlexLibraryByIdHandler.cs

@ -65,7 +65,7 @@ namespace ErsatzTV.Application.Plex.Commands
private async Task<Unit> Synchronize(RequestParameters parameters) private async Task<Unit> Synchronize(RequestParameters parameters)
{ {
var lastScan = new DateTimeOffset(parameters.Library.LastScan ?? DateTime.MinValue, TimeSpan.Zero); var lastScan = new DateTimeOffset(parameters.Library.LastScan ?? SystemTime.MinValueUtc, TimeSpan.Zero);
DateTimeOffset nextScan = lastScan + TimeSpan.FromHours(parameters.LibraryRefreshInterval); DateTimeOffset nextScan = lastScan + TimeSpan.FromHours(parameters.LibraryRefreshInterval);
if (parameters.ForceScan || nextScan < DateTimeOffset.Now) if (parameters.ForceScan || nextScan < DateTimeOffset.Now)
{ {

2
ErsatzTV.Core.Tests/Fakes/FakeFileEntry.cs

@ -4,6 +4,6 @@ namespace ErsatzTV.Core.Tests.Fakes
{ {
public record FakeFileEntry(string Path) public record FakeFileEntry(string Path)
{ {
public DateTime LastWriteTime { get; set; } = DateTime.MinValue; public DateTime LastWriteTime { get; set; } = SystemTime.MinValueUtc;
} }
} }

2
ErsatzTV.Core.Tests/Fakes/FakeLocalFileSystem.cs

@ -41,7 +41,7 @@ namespace ErsatzTV.Core.Tests.Fakes
public DateTime GetLastWriteTime(string path) => public DateTime GetLastWriteTime(string path) =>
Optional(_files.SingleOrDefault(f => f.Path == path)) Optional(_files.SingleOrDefault(f => f.Path == path))
.Map(f => f.LastWriteTime) .Map(f => f.LastWriteTime)
.IfNone(DateTime.MinValue); .IfNone(SystemTime.MinValueUtc);
public bool IsLibraryPathAccessible(LibraryPath libraryPath) => public bool IsLibraryPathAccessible(LibraryPath libraryPath) =>
_files.Any(f => f.Path.StartsWith(libraryPath.Path + Path.DirectorySeparatorChar)); _files.Any(f => f.Path.StartsWith(libraryPath.Path + Path.DirectorySeparatorChar));

2
ErsatzTV.Core/Metadata/LocalFileSystem.cs

@ -22,7 +22,7 @@ namespace ErsatzTV.Core.Metadata
} }
public DateTime GetLastWriteTime(string path) => public DateTime GetLastWriteTime(string path) =>
Try(File.GetLastWriteTimeUtc(path)).IfFail(() => DateTime.MinValue); Try(File.GetLastWriteTimeUtc(path)).IfFail(() => SystemTime.MinValueUtc);
public bool IsLibraryPathAccessible(LibraryPath libraryPath) => public bool IsLibraryPathAccessible(LibraryPath libraryPath) =>
Directory.Exists(libraryPath.Path); Directory.Exists(libraryPath.Path);

10
ErsatzTV.Core/Metadata/LocalMetadataProvider.cs

@ -218,7 +218,7 @@ namespace ErsatzTV.Core.Metadata
existing.Tagline = metadata.Tagline; existing.Tagline = metadata.Tagline;
existing.Title = metadata.Title; existing.Title = metadata.Title;
if (existing.DateAdded == DateTime.MinValue) if (existing.DateAdded == SystemTime.MinValueUtc)
{ {
existing.DateAdded = metadata.DateAdded; existing.DateAdded = metadata.DateAdded;
} }
@ -318,7 +318,7 @@ namespace ErsatzTV.Core.Metadata
existing.Tagline = metadata.Tagline; existing.Tagline = metadata.Tagline;
existing.Title = metadata.Title; existing.Title = metadata.Title;
if (existing.DateAdded == DateTime.MinValue) if (existing.DateAdded == SystemTime.MinValueUtc)
{ {
existing.DateAdded = metadata.DateAdded; existing.DateAdded = metadata.DateAdded;
} }
@ -423,7 +423,7 @@ namespace ErsatzTV.Core.Metadata
existing.Tagline = metadata.Tagline; existing.Tagline = metadata.Tagline;
existing.Title = metadata.Title; existing.Title = metadata.Title;
if (existing.DateAdded == DateTime.MinValue) if (existing.DateAdded == SystemTime.MinValueUtc)
{ {
existing.DateAdded = metadata.DateAdded; existing.DateAdded = metadata.DateAdded;
} }
@ -486,7 +486,7 @@ namespace ErsatzTV.Core.Metadata
existing.Disambiguation = metadata.Disambiguation; existing.Disambiguation = metadata.Disambiguation;
existing.Biography = metadata.Biography; existing.Biography = metadata.Biography;
if (existing.DateAdded == DateTime.MinValue) if (existing.DateAdded == SystemTime.MinValueUtc)
{ {
existing.DateAdded = metadata.DateAdded; existing.DateAdded = metadata.DateAdded;
} }
@ -581,7 +581,7 @@ namespace ErsatzTV.Core.Metadata
existing.Plot = metadata.Plot; existing.Plot = metadata.Plot;
existing.Album = metadata.Album; existing.Album = metadata.Album;
if (existing.DateAdded == DateTime.MinValue) if (existing.DateAdded == SystemTime.MinValueUtc)
{ {
existing.DateAdded = metadata.DateAdded; existing.DateAdded = metadata.DateAdded;
} }

2
ErsatzTV.Core/Metadata/TelevisionFolderScanner.cs

@ -322,7 +322,7 @@ namespace ErsatzTV.Core.Metadata
async () => async () =>
{ {
bool shouldUpdate = Optional(episode.EpisodeMetadata).Flatten().HeadOrNone().Match( bool shouldUpdate = Optional(episode.EpisodeMetadata).Flatten().HeadOrNone().Match(
m => m.DateUpdated == DateTime.MinValue, m => m.DateUpdated == SystemTime.MinValueUtc,
true); true);
if (shouldUpdate) if (shouldUpdate)

4
ErsatzTV.Core/Scheduling/PlayoutBuilder.cs

@ -374,9 +374,9 @@ namespace ErsatzTV.Core.Scheduling
} }
bool willNotFinishInTime = bool willNotFinishInTime =
currentTime <= durationFinish.IfNone(DateTime.MinValue) && currentTime <= durationFinish.IfNone(SystemTime.MinValueUtc) &&
currentTime + peekVersion.Duration > currentTime + peekVersion.Duration >
durationFinish.IfNone(DateTime.MinValue); durationFinish.IfNone(SystemTime.MinValueUtc);
if (willNotFinishInTime) if (willNotFinishInTime)
{ {
_logger.LogDebug( _logger.LogDebug(

9
ErsatzTV.Core/SystemTime.cs

@ -0,0 +1,9 @@
using System;
namespace ErsatzTV.Core
{
public static class SystemTime
{
public static DateTime MinValueUtc = new(0, DateTimeKind.Utc);
}
}

2
ErsatzTV.Infrastructure/Data/Repositories/TelevisionRepository.cs

@ -703,7 +703,7 @@ namespace ErsatzTV.Infrastructure.Data.Repositories
new() new()
{ {
DateAdded = DateTime.UtcNow, DateAdded = DateTime.UtcNow,
DateUpdated = DateTime.MinValue, DateUpdated = SystemTime.MinValueUtc,
MetadataKind = MetadataKind.Fallback, MetadataKind = MetadataKind.Fallback,
Actors = new List<Actor>(), Actors = new List<Actor>(),
Guids = new List<MetadataGuid>(), Guids = new List<MetadataGuid>(),

3
ErsatzTV.Infrastructure/Search/CustomQueryParser.cs

@ -1,4 +1,5 @@
using System; using System;
using ErsatzTV.Core;
using Lucene.Net.Analysis; using Lucene.Net.Analysis;
using Lucene.Net.QueryParsers.Classic; using Lucene.Net.QueryParsers.Classic;
using Lucene.Net.Search; using Lucene.Net.Search;
@ -53,7 +54,7 @@ namespace ErsatzTV.Infrastructure.Search
internal static bool ParseStart(string text, out DateTime start) internal static bool ParseStart(string text, out DateTime start)
{ {
start = DateTime.MinValue; start = SystemTime.MinValueUtc;
try try
{ {

Loading…
Cancel
Save