Add InterstitialGroups service and enhance SlotWriter and related components for interstitial handling
Introduced the InterstitialGroups service to manage interstitial group logic, preventing their inclusion in slots and fallback groups. Updated the SlotWriter class to utilize this service, ensuring proper validation during slot creation and updates. Enhanced error handling for interstitial groups in the ImportGridCommandHandler and UpdateTemplateCommandHandler, providing warnings instead of failures when interstitials are detected. Updated related tests to verify the correct behavior of these changes, ensuring robust handling of interstitials in the scheduling process.
This commit is contained in:
+23
-2
@@ -131,7 +131,7 @@ public sealed class BuildGridPromptQueryHandler(IAppDbContext dbContext, GroupCa
|
||||
Culture,
|
||||
$"| {group.Name} | {KindName(group.DominantKind)} | {group.UnitCount} | "
|
||||
+ $"{(int)Math.Round(group.AverageUnitMinutes)} мин | "
|
||||
+ $"{group.Strictest?.ToString() ?? "—"} | {genre ?? "—"} |"
|
||||
+ $"{AudienceName(group.Strictest)} | {genre ?? "—"} |"
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -164,7 +164,7 @@ public sealed class BuildGridPromptQueryHandler(IAppDbContext dbContext, GroupCa
|
||||
Culture,
|
||||
$"| {show.Name} | {KindName(show.Kind)} | {show.Year?.ToString(Culture) ?? "—"} | "
|
||||
+ $"{show.Units} | {show.AverageMinutes} мин | "
|
||||
+ $"{show.Audience?.ToString() ?? "—"} | {genre ?? "—"} |"
|
||||
+ $"{AudienceName(show.Audience)} | {genre ?? "—"} |"
|
||||
);
|
||||
}
|
||||
|
||||
@@ -186,6 +186,22 @@ public sealed class BuildGridPromptQueryHandler(IAppDbContext dbContext, GroupCa
|
||||
text.AppendLine(names.Count == 0 ? empty : string.Join(", ", names));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Рейтинг ровно так, как он пишется в файле обмена («PG-13», не «Pg13»). Модель переписывает
|
||||
/// в ответ то, что увидела в таблице, а формат читает написание с провода: разойдись эти два
|
||||
/// написания — и правило детского времени из ответа не разберётся вовсе.
|
||||
/// </summary>
|
||||
private static string AudienceName(ShowAudience? audience) =>
|
||||
audience switch
|
||||
{
|
||||
ShowAudience.G => "G",
|
||||
ShowAudience.Pg => "PG",
|
||||
ShowAudience.Pg13 => "PG-13",
|
||||
ShowAudience.R => "R",
|
||||
ShowAudience.Nc17 => "NC-17",
|
||||
_ => "—",
|
||||
};
|
||||
|
||||
/// <summary>Тип контента словами: «сериал», «полный метр» — так его читает модель.</summary>
|
||||
private static string KindName(ShowKind kind) =>
|
||||
kind switch
|
||||
@@ -198,11 +214,16 @@ public sealed class BuildGridPromptQueryHandler(IAppDbContext dbContext, GroupCa
|
||||
/// <summary>
|
||||
/// Шоу, у которых есть что показывать. Считается по готовым медиа: шоу без обработанного файла
|
||||
/// в эфир не пойдёт, и предлагать его модели значит получить сетку под несуществующий контент.
|
||||
///
|
||||
/// Ролики в список не идут: их бывают сотни, они съедают потолок перечисления, а главное —
|
||||
/// поимённый список рекламы читается моделью как материал для слотов, и она честно собирает
|
||||
/// из него группу. В эфире это полоса рекламы, подписанная как программа.
|
||||
/// </summary>
|
||||
private async Task<List<ShowFact>> LoadShowsAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
var shows = await dbContext
|
||||
.Shows.AsNoTracking()
|
||||
.Where(s => s.Kind != ShowKind.Interstitial)
|
||||
.Include(s => s.Episodes)
|
||||
.ToListAsync(cancellationToken);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user