Tighten pool rules further and rest films for a week (0.47.0)
pauljd/davidson-ci: Davidson CI / quality (push) Failing after 1m41s
pauljd/davidson-ci: Davidson CI / ai-review (push) Failing after 1m19s

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-11-02 08:13:35 +00:00
co-authored by Claude Opus 5.5
parent be440df194
commit 149ff3b355
7 changed files with 39 additions and 10 deletions
+26
View File
@@ -0,0 +1,26 @@
# Orbit TV 0.44.0 to 0.47.0 verification
Bigger pools from reviewed suggestions, a Toonami-inspired Vortex and tighter rules.
## Changed
- 0.44: rule-based suggestions from Emby by community rating, with reasons, a review screen, and accepted and rejected choices saved apart from the schedule. Includes 0.43's launch retry.
- 0.45: Vortex lineup of daytime cartoons and evening anime, Toonami-inspired, as Paul asked.
- 0.46: asks Emby for year, age rating and score, which my first version omitted. Leaves out family films, animation, documentaries, music films and films under 70 minutes. Exact titles on Vortex. Saving finishes if you leave the screen.
- 0.47: After Dark sci-fi rule leaves out adventure films, and its thriller rule leaves out science fiction. Vortex's evening rule is action anime only, no TV-MA. After Dark's film rest is 7 days, since the pool is big enough. Failed pool reads are logged.
## Checked on the box with 0.46, 2 November 2026
| Channel | Pool | Your review | Programmes in 7 days | Requests | Read | Plan | Stored | Repeats in the week |
| --- | --- | --- | --- | --- | --- | --- | --- | --- |
| After Dark | 140 films | 107 kept, 32 rejected | 93 | 30 | 35.6 s | 1.8 s | 50 KB | 20, shortest gap 51.3 h |
| Vortex | 75 shows, 4,136 episodes | 50 kept, 0 rejected | 433 | 125 | 42.4 s | 9.6 s | 385 KB | None |
- Suggestion checks: 12 requests in 3.4 s for After Dark, 3 requests in 4.6 s for Vortex.
- catalogue.db fingerprint unchanged (b630828b...).
## Unit tests
- assembleDebug, testDebugUnitTest and lintDebug pass; 210 tests, 0 failures.
## Not checked
- 0.47 hasn't run on the box. Its rules and rest period only show after install and another review.
- Vortex's pool didn't refresh at 07:35 after its list changed, though it did when Paul saved. The cause wasn't found, which is why 0.47 logs read failures.
- How well the suggestions fit is Paul's judgement. Some choices are still marked unsure.
+2 -2
View File
@@ -9,8 +9,8 @@ android {
applicationId = "tv.orbit.classic"
minSdk = 26
targetSdk = 36
versionCode = 47
versionName = "0.46.0-suggestion-rules"
versionCode = 48
versionName = "0.47.0-tighter-pools"
}
buildFeatures { compose = true }
compileOptions { sourceCompatibility = JavaVersion.VERSION_17; targetCompatibility = JavaVersion.VERSION_17 }
@@ -31,21 +31,21 @@ internal val SmartChannels = listOf(
ChannelProgramming(102, "After Dark", listOf("The Thing", "The Evil Dead", "Re-Animator", "Hellraiser", "Videodrome", "An American Werewolf in London",
"Halloween", "Day of the Dead", "They Live", "Escape from New York", "The Fog", "Near Dark", "The Lost Boys", "Fright Night", "Society", "Tremors",
"Basket Case", "Phantasm", "Repo Man", "Donnie Darko", "The Wicker Man", "Suspiria", "Eraserhead", "Blue Velvet", "From Dusk Till Dawn", "Scream",
"Poltergeist", "The Howling", "Creepshow", "Prince of Darkness"), seriesCount = 40, filmRestMs = 48 * 60 * 60_000L,
"Poltergeist", "The Howling", "Creepshow", "Prince of Darkness"), seriesCount = 40, filmRestMs = 7 * 24 * 60 * 60_000L,
dayParts = listOf(DayPart(21, 5), DayPart(5, 21, listOf("The 'Burbs", "'Til Death Do Us Part", "Tremors", "The Lost Boys", "Fright Night", "Poltergeist", "Scream",
"Escape from New York", "They Live", "Repo Man", "Donnie Darko", "From Dusk Till Dawn", "Creepshow", "Near Dark", "Halloween", "The Fog", "Blue Velvet",
"The Wicker Man", "An American Werewolf in London", "Prince of Darkness"), group = "day")),
suggestionRules = listOf(
SuggestionRule("day", "Daytime", "Movie", listOf("Horror", "Comedy"), 1975..2010, 6f, setOf("NC-17", "X"), 40, NotCultCinema, 70),
// Capped so the biggest blockbusters stay out: this channel is cult cinema.
SuggestionRule("day", "Daytime", "Movie", listOf("Science Fiction", "Action"), 1975..2005, 6.5f, setOf("NC-17", "X"), 40, NotCultCinema, 70, 7.9f),
SuggestionRule("day", "Daytime", "Movie", listOf("Thriller", "Mystery"), 1975..2005, 6.5f, setOf("NC-17", "X"), 30, NotCultCinema, 70, 7.9f),
SuggestionRule("day", "Daytime", "Movie", listOf("Science Fiction", "Action"), 1975..2005, 6.5f, setOf("NC-17", "X"), 40, NotCultCinema + "Adventure", 70, 7.9f),
SuggestionRule("day", "Daytime", "Movie", listOf("Thriller", "Mystery"), 1975..2005, 6.5f, setOf("NC-17", "X"), 30, NotCultCinema + "Science Fiction", 70, 7.9f),
SuggestionRule("late", "Late night", "Movie", listOf("Horror"), 1970..2010, 6f, emptySet(), 90, NotCultCinema, 70))),
ChannelProgramming(103, "Vortex", VortexDaytime + VortexEvening, seriesCount = 40, finishTogether = true, exactTitles = true,
dayParts = listOf(DayPart(6, 18, VortexDaytime, group = "day"), DayPart(18, 6, VortexEvening, group = "night")),
suggestionRules = listOf(
SuggestionRule("day", "Daytime", "Series", listOf("Animation", "Action"), 1985..2015, 7f, setOf("TV-MA"), 30),
SuggestionRule("night", "Evening", "Series", listOf("Anime"), 1985..2020, 7.5f, emptySet(), 20))),
SuggestionRule("night", "Evening", "Series", listOf("Anime", "Action"), 1985..2020, 7f, setOf("TV-MA"), 30))),
ChannelProgramming(140, "Terra", listOf("The Blue Planet", "Blue Planet II", "Planet Earth", "Planet Earth II", "Planet Earth III", "Frozen Planet", "Frozen Planet II",
"Life on Earth", "The Living Planet", "The Trials of Life", "Our Planet", "Our Planet II", "Dynasties", "Dynasties II", "Seven Worlds, One Planet", "A Perfect Planet",
"Hostile Planet", "Africa", "Wild China", "South Pacific", "Great Barrier Reef", "The Hunt", "The Life of Mammals", "The Life of Birds", "Nature's Great Events", "Green Planet", "Prehistoric Planet"),
@@ -49,7 +49,10 @@ internal class ChannelScheduler(private val store: ScheduleStore, private val cl
pool = ScheduleStore.SavedPool(read.series, now, signature)
store.savePool(userId, number, pool)
}
} catch (failure: EmbyCheckException) { if (cached == null) throw failure }
} catch (failure: EmbyCheckException) {
Log.w("OrbitSchedule", "channel=$number poolReadFailed status=${failure.httpStatus} retryable=${failure.retryable} keptCache=${cached != null}")
if (cached == null) throw failure
}
}
val started = android.os.SystemClock.elapsedRealtime()
val existing = store.loadPlan(userId, number)
@@ -41,7 +41,7 @@ internal class HttpsEmbyTransport(internal val deviceId: String = UUID.randomUUI
connection.connectTimeout = 10_000
connection.readTimeout = request.readTimeoutMs ?: if (request.path == "/Sessions/Logout") 5_000 else 15_000
connection.setRequestProperty("Accept", "application/json")
connection.setRequestProperty("X-Emby-Authorization", "Emby Client=\"Orbit TV\", Device=\"Orbit TV\", DeviceId=\"$deviceId\", Version=\"0.46.0\"")
connection.setRequestProperty("X-Emby-Authorization", "Emby Client=\"Orbit TV\", Device=\"Orbit TV\", DeviceId=\"$deviceId\", Version=\"0.47.0\"")
request.token?.let { connection.setRequestProperty("X-Emby-Token", it) }
if (request.method == "POST") {
val bytes = request.body.orEmpty().toByteArray(Charsets.UTF_8)
@@ -33,7 +33,7 @@ internal class SecureMediaDataSource(private val session: EmbySampleSession) : B
next.instanceFollowRedirects = false
next.connectTimeout = 10_000
next.readTimeout = 20_000
next.setRequestProperty("User-Agent", "OrbitTV/0.46.0")
next.setRequestProperty("User-Agent", "OrbitTV/0.47.0")
next.setRequestProperty("Accept-Encoding", "identity")
session.mediaHeaders(address).forEach { (key, value) -> next.setRequestProperty(key, value) }
if (dataSpec.position != 0L || dataSpec.length != C.LENGTH_UNSET.toLong()) {
+1 -1
View File
@@ -71,7 +71,7 @@ Audit and phased plan are in review, from `docs/briefs/indexing-programming-engi
## Smart channels status
Phase A of [the Smart Channels Foundation brief](briefs/smart-channels-foundation-2026-11-01.md) passed Paul's review on 2 November 2026, with Paradox on the box (VERIFICATION-0.39.0.md). Phase B (Terra and After Dark, VERIFICATION-0.40.0.md) and Phase C (Vortex, plus fewer repeats on Terra, VERIFICATION-0.41.0.md) are on the box as 0.41, tested and awaiting Paul's review. Day parts are on the box on Vortex and After Dark (VERIFICATION-0.42.0.md). Phase D (the remaining channels) needs separate approval. Pools are the current limit: Paul's library has far more films and shows than the curated lists use, which is the job for the programming director's reviewed suggestions. Animated idents are design files only and aren't in the app yet.
Phase A of [the Smart Channels Foundation brief](briefs/smart-channels-foundation-2026-11-01.md) passed Paul's review on 2 November 2026, with Paradox on the box (VERIFICATION-0.39.0.md). Phase B (Terra and After Dark, VERIFICATION-0.40.0.md) and Phase C (Vortex, plus fewer repeats on Terra, VERIFICATION-0.41.0.md) are on the box as 0.41, tested and awaiting Paul's review. Day parts are on the box on Vortex and After Dark (VERIFICATION-0.42.0.md). Phase D (the remaining channels) needs separate approval. Reviewed suggestions are built and in use on After Dark and Vortex (VERIFICATION-0.47.0.md), the first piece of the programming director. Next: a Vortex Movie Night as the first weekday event, then further channels. Animated idents are design files only and aren't in the app yet.
## Programming director