Keep the no-overlap rule when a film pool is too small for its rest (0.64.0)
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -16,3 +16,7 @@ English sound, four more channels and a subtitles and audio panel.
|
||||
- Not yet run on the box. Which titles Paul's library has, and the panel on a real remote, can only be seen there.
|
||||
- Orbit Junior is hand-picked but isn't age-locked, as profiles don't exist yet.
|
||||
- I filled out Junior's and Wild's lists myself beyond Paul's named shows.
|
||||
|
||||
## Checked on the box with 0.63, 2 November 2026
|
||||
- Detour 26 films, 102 programmes, shortest repeat 43.1 h. BritX 35 films, 98 programmes, shortest repeat 60.7 h. Orbit Junior 16 shows, 2,831 episodes, no repeats. Orbit Wild 17 shows, 2,349 episodes, no repeats.
|
||||
- catalogue.db fingerprint unchanged. Across 17 smart channels, one overlap: Shaun of the Dead on After Dark and BritX. A film pool too small for its rest skipped the no-overlap rule. 0.64 fixes that for future planning, and adds other names for Van Wilder and Green Street.
|
||||
|
||||
@@ -9,8 +9,8 @@ android {
|
||||
applicationId = "tv.orbit.classic"
|
||||
minSdk = 26
|
||||
targetSdk = 36
|
||||
versionCode = 64
|
||||
versionName = "0.63.0-four-more-channels"
|
||||
versionCode = 65
|
||||
versionName = "0.64.0-film-clash-fix"
|
||||
}
|
||||
buildFeatures { compose = true }
|
||||
compileOptions { sourceCompatibility = JavaVersion.VERSION_17; targetCompatibility = JavaVersion.VERSION_17 }
|
||||
|
||||
@@ -43,9 +43,9 @@ internal val ChannelPresets = listOf(
|
||||
"Dalziel and Pascoe", "Happy Valley", "The Wire", "Hawaii Five-0", "Blue Bloods"), smartOnly = true),
|
||||
ChannelPreset(142, "Dark Files", DarkFilesCrime + DarkFilesMysteries + DarkFilesParanormal, smartOnly = true),
|
||||
ChannelPreset(114, "Detour", listOf("American Pie", "American Pie 2", "American Wedding", "American Reunion", "Road Trip", "EuroTrip", "Harold & Kumar Go to White Castle", "Harold & Kumar Escape from Guantanamo Bay",
|
||||
"A Very Harold & Kumar Christmas", "The Hangover", "The Hangover Part II", "The Hangover Part III", "Van Wilder", "Van Wilder: The Rise of Taj", "Old School", "Sex Drive", "Accepted", "Superbad", "Pineapple Express",
|
||||
"A Very Harold & Kumar Christmas", "The Hangover", "The Hangover Part II", "The Hangover Part III", "Van Wilder", "National Lampoon's Van Wilder", "Van Wilder: The Rise of Taj", "Van Wilder 2: The Rise of Taj", "Old School", "Sex Drive", "Accepted", "Superbad", "Pineapple Express",
|
||||
"Dude, Where's My Car?", "Without a Paddle", "The Girl Next Door", "Not Another Teen Movie", "Project X", "21 & Over", "Beerfest", "Grandma's Boy", "Waiting..."), smartOnly = true, films = true),
|
||||
ChannelPreset(115, "BritX", listOf("Shaun of the Dead", "Hot Fuzz", "The World's End", "Lock, Stock and Two Smoking Barrels", "Snatch", "RocknRolla", "Layer Cake", "Trainspotting", "T2 Trainspotting", "Green Street",
|
||||
ChannelPreset(115, "BritX", listOf("Shaun of the Dead", "Hot Fuzz", "The World's End", "Lock, Stock and Two Smoking Barrels", "Snatch", "RocknRolla", "Layer Cake", "Trainspotting", "T2 Trainspotting", "Green Street", "Green Street Hooligans",
|
||||
"The Football Factory", "Dog Soldiers", "Dead Man's Shoes", "28 Days Later", "28 Weeks Later", "This Is England", "The Gentlemen", "The Business", "The Firm", "Rise of the Footsoldier", "The 51st State", "Sexy Beast",
|
||||
"The Bank Job", "The Long Good Friday", "Human Traffic", "Twin Town", "Shallow Grave", "Four Lions", "Severance", "Attack the Block", "The Descent", "In Bruges", "Filth", "Calibre", "Sightseers", "Sweet Sixteen"), smartOnly = true, films = true),
|
||||
ChannelPreset(125, "Orbit Junior", listOf("Thomas the Tank Engine & Friends", "Thomas & Friends", "Fireman Sam", "Postman Pat", "Brum", "Rosie and Jim", "Bob the Builder", "Pingu", "Noddy", "Teletubbies", "Tweenies", "Tots TV",
|
||||
|
||||
@@ -160,7 +160,7 @@ internal fun nextFilm(pool: List<PoolSeries>, shown: Map<String, Long>, startMs:
|
||||
val rested = pool.filter { film -> shown[film.id]?.let { startMs - it >= restMs } ?: true }.let { films ->
|
||||
films.filter { !avoid(it, startMs, startMs + it.episodes.first().durationMs) }.ifEmpty { films } }
|
||||
return if (rested.isNotEmpty()) rested[java.util.Random(startMs).nextInt(rested.size)]
|
||||
else pool.minBy { shown[it.id] ?: Long.MIN_VALUE }
|
||||
else pool.filter { !avoid(it, startMs, startMs + it.episodes.first().durationMs) }.ifEmpty { pool }.minBy { shown[it.id] ?: Long.MIN_VALUE }
|
||||
}
|
||||
|
||||
/** Films by their rest period, back to back from [fromMs] until [untilMs] is covered. */
|
||||
|
||||
@@ -66,7 +66,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.63.0\"")
|
||||
connection.setRequestProperty("X-Emby-Authorization", "Emby Client=\"Orbit TV\", Device=\"Orbit TV\", DeviceId=\"$deviceId\", Version=\"0.64.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.63.0")
|
||||
next.setRequestProperty("User-Agent", "OrbitTV/0.64.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()) {
|
||||
|
||||
@@ -538,4 +538,11 @@ class ChannelScheduleTest {
|
||||
assertFalse(SmartChannels.first { it.number == 103 }.englishAudio)
|
||||
assertTrue(SmartChannels.first { it.number == 123 }.englishAudio)
|
||||
}
|
||||
|
||||
@Test fun aSmallFilmPoolStillAvoidsClashesWhileItsRestIsBroken() {
|
||||
val small = (1..6).map { film("s$it") }
|
||||
val other = extendSchedule(small, ScheduleCursor(), now, now + 7 * day, 7 * day)
|
||||
val mine = extendSchedule(small, ScheduleCursor(), now, now + 7 * day, 7 * day, avoid = clashesWith(listOf(other)))
|
||||
assertEquals(0, programmeOverlaps(other.entries, mine.entries))
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user