Season Check: series card, study guide, next-season handover and unseasoned-script checks; v2.20.1
Publish Container / build (push) Has been cancelled
Publish Container / build (push) Has been cancelled
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
50b0e83c2b
commit
35d3c9ca33
6 files changed
+66
-7
No files matched your search
@@ -225,6 +225,7 @@ export function register(app) {
|
||||
total: c.total,
|
||||
errors: c.errors,
|
||||
warnings: c.warnings,
|
||||
general: c.general.length,
|
||||
lanes: c.lanes.map(l => ({ lane: l.lane, title: l.title, season: l.season, errors: l.errors, warnings: l.warnings })),
|
||||
}))
|
||||
.catch(() => null)
|
||||
|
||||
+43
-2
@@ -17,6 +17,11 @@ function laneConfig(content, lane) {
|
||||
title: String(content.seriesTitle ?? '').trim(),
|
||||
studySlug: String(content.seriesStudySlug ?? '').trim(),
|
||||
highlightLane: 'primary',
|
||||
description: String(content.seriesDescription ?? '').trim(),
|
||||
imageUrl: String(content.seriesImageUrl ?? '').trim(),
|
||||
listenUrl: String(content.seriesListenUrl ?? '').trim(),
|
||||
hasGuide: Boolean(String(content.studyGuideTitle ?? '').trim() && (content.studyGuideDownloadUrl || content.studyGuideUrl || content.studyGuideAppleBooksUrl)),
|
||||
transition: content.scheduledSeriesTransition,
|
||||
}
|
||||
}
|
||||
const second = content.secondSeries ?? {}
|
||||
@@ -24,6 +29,11 @@ function laneConfig(content, lane) {
|
||||
title: String(second.title ?? '').trim(),
|
||||
studySlug: String(second.studySlug ?? '').trim(),
|
||||
highlightLane: 'second',
|
||||
description: String(second.description ?? '').trim(),
|
||||
imageUrl: String(second.imageUrl ?? '').trim(),
|
||||
listenUrl: String(second.listenUrl ?? '').trim(),
|
||||
hasGuide: Boolean(String(second.guide?.title ?? '').trim() && (second.guide?.downloadUrl || second.guide?.amazonUrl || second.guide?.appleBooksUrl)),
|
||||
transition: content.scheduledSecondSeriesTransition,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -68,6 +78,24 @@ export async function buildSeasonCheck() {
|
||||
problems.push(warn(`${noHighlightNumber.length} highlight${noHighlightNumber.length === 1 ? '' : 's'} in Lane ${lane} ${noHighlightNumber.length === 1 ? 'has' : 'have'} no episode number.`, 'podcast:highlights'))
|
||||
}
|
||||
|
||||
// Series card
|
||||
if (!cfg.imageUrl) problems.push(warn(`Lane ${lane} has no cover image.`, 'podcast:current-series'))
|
||||
if (!cfg.description) problems.push(warn(`Lane ${lane} has no series description.`, 'podcast:current-series'))
|
||||
if (!cfg.listenUrl) problems.push(warn(`Lane ${lane} has no listen link.`, 'podcast:current-series'))
|
||||
if (!cfg.hasGuide) problems.push(warn(`Lane ${lane} has no companion study guide (title plus a download or purchase link).`, 'podcast:current-series'))
|
||||
|
||||
// Handover to the next season
|
||||
const t = cfg.transition
|
||||
if (t) {
|
||||
if (!String(t.newTitle ?? '').trim() || !t.newSeason) {
|
||||
problems.push(warn(`The next-season handover for Lane ${lane} is scheduled but is missing its title or season number.`, 'podcast:current-series'))
|
||||
} else if (season && String(t.newSeason) === season) {
|
||||
problems.push(warn(`The next-season handover for Lane ${lane} uses the same season number (${season}) as the current one.`, 'podcast:current-series'))
|
||||
}
|
||||
} else if (study && sections.length > 0 && sections.every(x => x.releasedAt && new Date(x.releasedAt) <= new Date())) {
|
||||
problems.push(warn(`Every lesson in "${study.title}" is released, but no next season is scheduled for Lane ${lane}.`, 'podcast:current-series'))
|
||||
}
|
||||
|
||||
// Episode numbers to show: every number any part of the season mentions, plus 1..lesson count
|
||||
const numbers = new Set()
|
||||
for (let n = 1; n <= sections.length; n++) numbers.add(n)
|
||||
@@ -117,8 +145,21 @@ export async function buildSeasonCheck() {
|
||||
})
|
||||
}
|
||||
|
||||
const total = lanes.reduce((n, l) => n + l.problems.length, 0)
|
||||
return { lanes, total, errors: lanes.reduce((n, l) => n + l.errors, 0), warnings: lanes.reduce((n, l) => n + l.warnings, 0) }
|
||||
// Scripts are filed by season + episode, so one with no season can't be matched to an episode
|
||||
const general = []
|
||||
const unseasoned = Object.entries(state.episodeScripts ?? {}).filter(([, entry]) => !String(entry?.season ?? '').trim())
|
||||
if (unseasoned.length > 0) {
|
||||
general.push(warn(`${unseasoned.length} episode script${unseasoned.length === 1 ? ' has' : 's have'} no season number, so ${unseasoned.length === 1 ? 'it' : 'they'} can't be matched to an episode. Use the season backfill in Episode Scripts.`, 'podcast:scripts'))
|
||||
}
|
||||
|
||||
const all = [...lanes.flatMap(l => l.problems), ...general]
|
||||
return {
|
||||
lanes,
|
||||
general,
|
||||
total: all.length,
|
||||
errors: all.filter(p => p.severity === 'error').length,
|
||||
warnings: all.filter(p => p.severity === 'warn').length,
|
||||
}
|
||||
}
|
||||
|
||||
export function register(app) {
|
||||
|
||||
Reference in new issue
Block a user