Drive-In event ideas: never propose an idea already shown this week
The box's run after 0.108.18 proposed Ealing again in the one free place, because a new run didn't know what the week had already shown. This week's ideas now feed in: never repeated, and their films and evenings are taken. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -3,6 +3,7 @@ package tv.orbit.classic
|
||||
import android.util.Log
|
||||
import org.json.JSONArray
|
||||
import org.json.JSONObject
|
||||
import java.time.LocalDateTime
|
||||
|
||||
internal const val POOL_REFRESH_MS = 7 * 24 * 60 * 60_000L
|
||||
|
||||
@@ -161,8 +162,14 @@ internal class ChannelScheduler(private val store: ScheduleStore, private val cl
|
||||
val checks = try { session.readFilmChecks(bills.flatMap { b -> b.films.map { EventFilm(it.title, it.year ?: 0, it.imdb.orEmpty(), it.id) to null } }) } catch (failure: EmbyCheckException) { emptyMap() }
|
||||
val verified = bills.filter { b -> b.films.all { checks[it.id]?.film != null } }
|
||||
val verifiedSeeds = seeds.filter { s -> verified.any { it.key.startsWith(s.key + "|") } }
|
||||
// This week's ideas already shown, so a new one never repeats one, nor takes its films or its evening.
|
||||
val current = EventIdeaHistory.load(historyFile).filter(::live).map { h ->
|
||||
val ids = h.getJSONArray("films").let { a -> (0 until a.length()).map { a.getString(it) } }
|
||||
EventIdea(h.optString("signature").substringBeforeLast(':'), h.optString("theme"), h.optString("source"), runCatching { IdeaFormat.valueOf(h.optString("format")) }.getOrDefault(IdeaFormat.FridayDouble),
|
||||
h.optString("evening").takeIf { it.isNotEmpty() && it != "null" }?.let { LocalDateTime.parse(it) }, ids.mapNotNull { films[it] }, emptyList(), 0.0)
|
||||
}
|
||||
val ideas = weeklyEventIdeas(verifiedSeeds, films, unavailable, { format, taken -> ideaEvening(format, today.plusDays(1), drivePlanEnd, taken, format.films * 2 * 60 * 60_000L, zone) },
|
||||
EventIdeaHistory.dismissed(historyFile), limit = (EVENT_IDEAS_PER_WEEK - shownThisWeek).coerceAtLeast(0))
|
||||
EventIdeaHistory.dismissed(historyFile), limit = (EVENT_IDEAS_PER_WEEK - shownThisWeek).coerceAtLeast(0), current = current)
|
||||
EventIdeaHistory.record(historyFile, ideas, now)
|
||||
val thisWeek = EventIdeaHistory.load(historyFile).filter(::live)
|
||||
runCatching { file.writeText(JSONObject().put("day", today.toString()).put("rules", EVENT_IDEA_RULES).put("ideas", JSONArray(thisWeek.map { h ->
|
||||
|
||||
@@ -202,9 +202,11 @@ internal fun billFor(seed: IdeaSeed, films: Map<String, IdeaFilm>, unavailable:
|
||||
* worthwhile proposes nothing.
|
||||
*/
|
||||
internal fun weeklyEventIdeas(seeds: List<IdeaSeed>, films: Map<String, IdeaFilm>, unavailable: (IdeaFilm) -> String?, freeEvening: (IdeaFormat, Set<LocalDateTime>) -> LocalDateTime?,
|
||||
dismissed: Set<String>, limit: Int = EVENT_IDEAS_PER_WEEK): List<EventIdea> {
|
||||
val bills = seeds.mapNotNull { billFor(it, films, unavailable).first }.filter { it.signature !in dismissed }.sortedByDescending { it.score }
|
||||
val out = mutableListOf<EventIdea>(); val taken = mutableSetOf<LocalDateTime>(); val used = mutableSetOf<String>()
|
||||
dismissed: Set<String>, limit: Int = EVENT_IDEAS_PER_WEEK,
|
||||
/** Ideas already shown this week: never proposed twice, and their films and evenings are taken. */
|
||||
current: List<EventIdea> = emptyList()): List<EventIdea> {
|
||||
val bills = seeds.mapNotNull { billFor(it, films, unavailable).first }.filter { it.signature !in dismissed && current.none { c -> c.key.substringBefore('|') == it.key.substringBefore('|') } }.sortedByDescending { it.score }
|
||||
val out = mutableListOf<EventIdea>(); val taken = current.mapNotNull { it.evening }.toMutableSet(); val used = current.flatMap { c -> c.films.map { it.id } }.toMutableSet()
|
||||
for (b in bills) {
|
||||
if (out.size >= limit) break
|
||||
if (b.films.any { it.id in used }) continue
|
||||
|
||||
@@ -62,6 +62,9 @@ class EventIdeasTest {
|
||||
assertTrue(weeklyEventIdeas(seeds, films, none, evening, emptySet(), limit = 0).isEmpty())
|
||||
val weak = films.mapValues { (_, f) -> IdeaFilm(f.id, f.title, f.year, f.imdb, f.runtimeMs, f.rating, f.genres, f.studios, community = 6.5, notable = true) }
|
||||
assertTrue(weeklyEventIdeas(seeds, weak, none, evening, emptySet()).isEmpty()) // no filler
|
||||
// Already shown this week: never again, and its evening and films are taken.
|
||||
val more = weeklyEventIdeas(seeds, films, none, evening, emptySet(), limit = 1, current = listOf(week[0]))
|
||||
assertTrue(more.none { it.key == week[0].key }); assertTrue(more.none { it.evening == week[0].evening })
|
||||
val dismissed = setOf(week[0].signature)
|
||||
assertTrue(weeklyEventIdeas(seeds, films, none, evening, dismissed).none { it.signature == week[0].signature })
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user