add custom title option to schedule items (#116)
This commit is contained in:
@@ -9,6 +9,8 @@ namespace ErsatzTV.Core.Domain
|
||||
public MediaItem MediaItem { get; set; }
|
||||
public DateTime Start { get; set; }
|
||||
public DateTime Finish { get; set; }
|
||||
public string CustomTitle { get; set; }
|
||||
public bool CustomGroup { get; set; }
|
||||
public int PlayoutId { get; set; }
|
||||
public Playout Playout { get; set; }
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@ namespace ErsatzTV.Core.Domain
|
||||
public StartType StartType => StartTime.HasValue ? StartType.Fixed : StartType.Dynamic;
|
||||
public TimeSpan? StartTime { get; set; }
|
||||
public ProgramScheduleItemCollectionType CollectionType { get; set; }
|
||||
public string CustomTitle { get; set; }
|
||||
public int ProgramScheduleId { get; set; }
|
||||
public ProgramSchedule ProgramSchedule { get; set; }
|
||||
public int? CollectionId { get; set; }
|
||||
|
||||
@@ -57,49 +57,36 @@ namespace ErsatzTV.Core.Iptv
|
||||
|
||||
foreach (Channel channel in _channels.OrderBy(c => c.Number))
|
||||
{
|
||||
foreach (PlayoutItem playoutItem in channel.Playouts.Collect(p => p.Items).OrderBy(i => i.Start))
|
||||
var sorted = channel.Playouts.Collect(p => p.Items).OrderBy(x => x.Start).ToList();
|
||||
var i = 0;
|
||||
while (i < sorted.Count)
|
||||
{
|
||||
string start = playoutItem.StartOffset.ToString("yyyyMMddHHmmss zzz").Replace(":", string.Empty);
|
||||
string stop = playoutItem.FinishOffset.ToString("yyyyMMddHHmmss zzz").Replace(":", string.Empty);
|
||||
PlayoutItem startItem = sorted[i];
|
||||
bool hasCustomTitle = !string.IsNullOrWhiteSpace(startItem.CustomTitle);
|
||||
|
||||
string title = playoutItem.MediaItem switch
|
||||
int finishIndex = i;
|
||||
while (hasCustomTitle && finishIndex + 1 < sorted.Count && sorted[finishIndex + 1].CustomGroup)
|
||||
{
|
||||
Movie m => m.MovieMetadata.HeadOrNone().Map(mm => mm.Title ?? string.Empty)
|
||||
.IfNone("[unknown movie]"),
|
||||
Episode e => e.Season.Show.ShowMetadata.HeadOrNone().Map(em => em.Title ?? string.Empty)
|
||||
.IfNone("[unknown show]"),
|
||||
_ => "[unknown]"
|
||||
};
|
||||
finishIndex++;
|
||||
}
|
||||
|
||||
string subtitle = playoutItem.MediaItem switch
|
||||
{
|
||||
Episode e => e.EpisodeMetadata.HeadOrNone().Match(
|
||||
em => em.Title ?? string.Empty,
|
||||
() => string.Empty),
|
||||
_ => string.Empty
|
||||
};
|
||||
PlayoutItem finishItem = sorted[finishIndex];
|
||||
i = finishIndex;
|
||||
|
||||
string description = playoutItem.MediaItem switch
|
||||
{
|
||||
Movie m => m.MovieMetadata.HeadOrNone().Map(mm => mm.Plot ?? string.Empty).IfNone(string.Empty),
|
||||
Episode e => e.EpisodeMetadata.HeadOrNone().Map(em => em.Plot ?? string.Empty)
|
||||
.IfNone(string.Empty),
|
||||
_ => string.Empty
|
||||
};
|
||||
string start = startItem.StartOffset.ToString("yyyyMMddHHmmss zzz").Replace(":", string.Empty);
|
||||
string stop = finishItem.FinishOffset.ToString("yyyyMMddHHmmss zzz").Replace(":", string.Empty);
|
||||
|
||||
string contentRating = playoutItem.MediaItem switch
|
||||
{
|
||||
// TODO: re-implement content rating
|
||||
// Movie m => m.MovieMetadata.HeadOrNone().Map(mm => mm.ContentRating).IfNone(string.Empty),
|
||||
_ => string.Empty
|
||||
};
|
||||
string title = GetTitle(startItem);
|
||||
string subtitle = GetSubtitle(startItem);
|
||||
string description = GetDescription(startItem);
|
||||
string contentRating = string.Empty;
|
||||
|
||||
xml.WriteStartElement("programme");
|
||||
xml.WriteAttributeString("start", start);
|
||||
xml.WriteAttributeString("stop", stop);
|
||||
xml.WriteAttributeString("channel", channel.Number);
|
||||
|
||||
if (playoutItem.MediaItem is Movie movie)
|
||||
if (!hasCustomTitle && startItem.MediaItem is Movie movie)
|
||||
{
|
||||
xml.WriteStartElement("category");
|
||||
xml.WriteAttributeString("lang", "en");
|
||||
@@ -150,7 +137,7 @@ namespace ErsatzTV.Core.Iptv
|
||||
xml.WriteStartElement("previously-shown");
|
||||
xml.WriteEndElement(); // previously-shown
|
||||
|
||||
if (playoutItem.MediaItem is Episode episode)
|
||||
if (!hasCustomTitle && startItem.MediaItem is Episode episode)
|
||||
{
|
||||
Option<ShowMetadata> maybeMetadata =
|
||||
Optional(episode.Season?.Show?.ShowMetadata.HeadOrNone()).Flatten();
|
||||
@@ -209,6 +196,8 @@ namespace ErsatzTV.Core.Iptv
|
||||
}
|
||||
|
||||
xml.WriteEndElement(); // programme
|
||||
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -218,5 +207,54 @@ namespace ErsatzTV.Core.Iptv
|
||||
xml.Flush();
|
||||
return Encoding.UTF8.GetString(ms.ToArray());
|
||||
}
|
||||
|
||||
private static string GetTitle(PlayoutItem playoutItem)
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(playoutItem.CustomTitle))
|
||||
{
|
||||
return playoutItem.CustomTitle;
|
||||
}
|
||||
|
||||
return playoutItem.MediaItem switch
|
||||
{
|
||||
Movie m => m.MovieMetadata.HeadOrNone().Map(mm => mm.Title ?? string.Empty)
|
||||
.IfNone("[unknown movie]"),
|
||||
Episode e => e.Season.Show.ShowMetadata.HeadOrNone().Map(em => em.Title ?? string.Empty)
|
||||
.IfNone("[unknown show]"),
|
||||
_ => "[unknown]"
|
||||
};
|
||||
}
|
||||
|
||||
private static string GetSubtitle(PlayoutItem playoutItem)
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(playoutItem.CustomTitle))
|
||||
{
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
return playoutItem.MediaItem switch
|
||||
{
|
||||
Episode e => e.EpisodeMetadata.HeadOrNone().Match(
|
||||
em => em.Title ?? string.Empty,
|
||||
() => string.Empty),
|
||||
_ => string.Empty
|
||||
};
|
||||
}
|
||||
|
||||
private static string GetDescription(PlayoutItem playoutItem)
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(playoutItem.CustomTitle))
|
||||
{
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
return playoutItem.MediaItem switch
|
||||
{
|
||||
Movie m => m.MovieMetadata.HeadOrNone().Map(mm => mm.Plot ?? string.Empty).IfNone(string.Empty),
|
||||
Episode e => e.EpisodeMetadata.HeadOrNone().Map(em => em.Plot ?? string.Empty)
|
||||
.IfNone(string.Empty),
|
||||
_ => string.Empty
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -149,6 +149,8 @@ namespace ErsatzTV.Core.Scheduling
|
||||
Option<int> multipleRemaining = Optional(startAnchor.MultipleRemaining);
|
||||
Option<DateTimeOffset> durationFinish = startAnchor.DurationFinishOffset;
|
||||
|
||||
bool customGroup = multipleRemaining.IsSome || durationFinish.IsSome;
|
||||
|
||||
// loop until we're done filling the desired amount of time
|
||||
while (currentTime < playoutFinish)
|
||||
{
|
||||
@@ -185,9 +187,15 @@ namespace ErsatzTV.Core.Scheduling
|
||||
{
|
||||
MediaItemId = mediaItem.Id,
|
||||
Start = itemStartTime.UtcDateTime,
|
||||
Finish = itemStartTime.UtcDateTime + version.Duration
|
||||
Finish = itemStartTime.UtcDateTime + version.Duration,
|
||||
CustomGroup = customGroup
|
||||
};
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(scheduleItem.CustomTitle))
|
||||
{
|
||||
playoutItem.CustomTitle = scheduleItem.CustomTitle;
|
||||
}
|
||||
|
||||
currentTime = itemStartTime + version.Duration;
|
||||
enumerator.MoveNext();
|
||||
|
||||
@@ -201,11 +209,13 @@ namespace ErsatzTV.Core.Scheduling
|
||||
"Advancing to next schedule item after playout mode {PlayoutMode}",
|
||||
"One");
|
||||
index++;
|
||||
customGroup = false;
|
||||
break;
|
||||
case ProgramScheduleItemMultiple multiple:
|
||||
if (multipleRemaining.IsNone)
|
||||
{
|
||||
multipleRemaining = multiple.Count;
|
||||
customGroup = true;
|
||||
}
|
||||
|
||||
multipleRemaining = multipleRemaining.Map(i => i - 1);
|
||||
@@ -216,6 +226,7 @@ namespace ErsatzTV.Core.Scheduling
|
||||
"Multiple");
|
||||
index++;
|
||||
multipleRemaining = None;
|
||||
customGroup = false;
|
||||
}
|
||||
|
||||
break;
|
||||
@@ -223,6 +234,8 @@ namespace ErsatzTV.Core.Scheduling
|
||||
enumerator.Current.Do(
|
||||
peekMediaItem =>
|
||||
{
|
||||
customGroup = true;
|
||||
|
||||
MediaVersion peekVersion = peekMediaItem switch
|
||||
{
|
||||
Movie m => m.MediaVersions.Head(),
|
||||
@@ -249,6 +262,7 @@ namespace ErsatzTV.Core.Scheduling
|
||||
"Advancing to next schedule item after playout mode {PlayoutMode}",
|
||||
"Flood");
|
||||
index++;
|
||||
customGroup = false;
|
||||
}
|
||||
});
|
||||
break;
|
||||
@@ -267,6 +281,7 @@ namespace ErsatzTV.Core.Scheduling
|
||||
if (durationFinish.IsNone)
|
||||
{
|
||||
durationFinish = itemStartTime + duration.PlayoutDuration;
|
||||
customGroup = true;
|
||||
}
|
||||
|
||||
bool willNotFinishInTime =
|
||||
@@ -279,6 +294,7 @@ namespace ErsatzTV.Core.Scheduling
|
||||
"Advancing to next schedule item after playout mode {PlayoutMode}",
|
||||
"Duration");
|
||||
index++;
|
||||
customGroup = false;
|
||||
|
||||
if (duration.OfflineTail)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user