0.103.0: story grouping on Heroes (Stage E, first channel)
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -9,8 +9,8 @@ android {
|
||||
applicationId = "tv.orbit.classic"
|
||||
minSdk = 26
|
||||
targetSdk = 36
|
||||
versionCode = 151
|
||||
versionName = "0.102.0-vortex-idents"
|
||||
versionCode = 152
|
||||
versionName = "0.103.0-heroes-stories"
|
||||
}
|
||||
buildFeatures { compose = true }
|
||||
compileOptions { sourceCompatibility = JavaVersion.VERSION_17; targetCompatibility = JavaVersion.VERSION_17 }
|
||||
|
||||
@@ -199,7 +199,10 @@ internal val SmartChannels = listOf(
|
||||
suggestionRules = SmartChannelRules[it.number].orEmpty(), dayParts = SmartChannelParts[it.number].orEmpty(), shuffleTitles = SmartChannelMixed[it.number].orEmpty(),
|
||||
channelFilms = if (it.number == 401) PpvSunday else emptyList(), tierWeights = SmartChannelTiers[it.number], adaptiveFilmRest = it.number in AdaptiveFilmRestChannels,
|
||||
catalogueScaleHours = if (it.number in CatalogueScaledChannels) CATALOGUE_SCALE_HOURS else null,
|
||||
catalogueScaleFloor = CatalogueScaleFloors[it.number] ?: MIN_CATALOGUE_SCALE) }
|
||||
catalogueScaleFloor = CatalogueScaleFloors[it.number] ?: MIN_CATALOGUE_SCALE, storyGrouping = it.number in StoryGroupingChannels) }
|
||||
|
||||
/** Living Network Stage E: story grouping beyond Paradox, one channel at a time. Heroes first (4 November 2026): 119 story parts a week, none booked together. */
|
||||
private val StoryGroupingChannels get() = setOf(602)
|
||||
|
||||
/**
|
||||
* Where a short series must keep at least half its tier's weight, so the hybrid trims its weekly repeats without cutting its
|
||||
|
||||
@@ -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.102.0\"")
|
||||
connection.setRequestProperty("X-Emby-Authorization", "Emby Client=\"Orbit TV\", Device=\"Orbit TV\", DeviceId=\"$deviceId\", Version=\"0.103.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.102.0")
|
||||
next.setRequestProperty("User-Agent", "OrbitTV/0.103.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()) {
|
||||
|
||||
@@ -128,8 +128,9 @@ class StoryGroupingTest {
|
||||
assertEquals(run(pool = unmarked, stories = false), run(pool = unmarked, stories = true))
|
||||
}
|
||||
|
||||
@Test fun onlyParadoxGroupsStories() {
|
||||
assertEquals(listOf(106), SmartChannels.filter { it.storyGrouping }.map { it.number })
|
||||
assertTrue(SmartChannels.first { it.number == 106 }.tierWeights != null)
|
||||
@Test fun onlyApprovedChannelsGroupStories() {
|
||||
// Paradox (Stage A), then Heroes (Stage E, one channel at a time). Grouping works through weighted rotation.
|
||||
assertEquals(listOf(106, 602), SmartChannels.filter { it.storyGrouping }.map { it.number }.sorted())
|
||||
assertTrue(SmartChannels.filter { it.storyGrouping }.all { it.tierWeights != null })
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
# 0.103.0: story grouping on Heroes (Living Network Stage E, first channel)
|
||||
|
||||
Step 3 of Paul's agreed order: story grouping on more channels, one at a time.
|
||||
|
||||
**Why Heroes first:** of the weighted channels, Heroes had the most broken stories. Its committed week has 119 story parts and none of them sit next to their other parts.
|
||||
|
||||
| Weighted channel | Stories in its pool | Story parts this week | Parts aired together |
|
||||
|---|---|---|---|
|
||||
| Heroes 602 | 84 | 119 | 0 |
|
||||
| Orbit X 603 | 158 | 46 | 0 |
|
||||
| Vortex 601 | 169 | 36 | 0 |
|
||||
| Orbit 1 101 | 144 | 21 | 0 |
|
||||
| Evidence 107 | 190 | 11 | 0 |
|
||||
|
||||
**The change:** `storyGrouping = true` for 602, through `StoryGroupingChannels`. The rule is the same one Paradox uses since 0.99.13, and is described in StoryGroups.kt.
|
||||
|
||||
## Checks
|
||||
|
||||
- 467 unit tests run, 0 failures; lint clean.
|
||||
- **Four-week replay** from the box's plans and pools at 18:27 today. Every fingerprint is identical to 0.102.0 except Heroes, and Heroes' committed bookings are unchanged (`kept=true`).
|
||||
- **Heroes over the four weeks** (1,807 new programmes):
|
||||
|
||||
| | 0.102.0 | 0.103.0 |
|
||||
|---|---|---|
|
||||
| Story openers followed by part 2 | 0 | 157 |
|
||||
| Openers left hanging | 160 | 6 |
|
||||
| Later parts aired alone | 194 | 5 |
|
||||
| Same episode again within 7 days | 91 | 88 |
|
||||
|
||||
The show mix barely moves (Justice League 150 → 152, Teen Titans 151 → 149).
|
||||
|
||||
**The 11 parts left apart are the library's own numbering, not the rule:**
|
||||
- **Batman: The Animated Series:** The Cat and the Claw is numbered E1 and E8, and Robin's Reckoning E51 and E53. They aren't consecutive, so the rule correctly won't treat them as stories.
|
||||
- **Spider-Man:** Six Forgotten Warriors (1) has no part 2 next to it in the library.
|
||||
- **Justice League:** one part 2 continues a part 1 that was already booked before the replay.
|
||||
|
||||
APK: `outputs/revision-0.103.0`, signed. Not installed.
|
||||
Reference in New Issue
Block a user