diff --git a/VERIFICATION-0.66.0.md b/VERIFICATION-0.66.0.md new file mode 100644 index 0000000..0f11c50 --- /dev/null +++ b/VERIFICATION-0.66.0.md @@ -0,0 +1,9 @@ +# Orbit TV 0.66.0: the full lineup + +Adds the last 11 channels from the programming bible, with the approved logos from Orbit-Channel-Designs: Orbit 2 (104), Wonder (126), PixelZ (127), Orbit VHS (131), Sci-Fi (132), Horror (133), Action (134), Romance (135), Premiere (136), Odyssey (144) and Ring X (150). Numbers are placeholders. + +Eight are film channels with a 7-day rest. Ring X follows the bible's weeknights (Monday Raw and Nitro, Tuesday Impact, Wednesday AEW, the whole vault otherwise), and a night with nothing in the library falls back to the vault. Optional review rules added for VHS, Sci-Fi, Horror, Action, Romance, Premiere and Odyssey. + +Checked: build, lint and 254 unit tests pass. Logos checked by eye on a contact sheet. + +Not checked: what the library actually holds for each list, which only shows once a channel is switched on. Wrestling titles are my best guess at how they're named in Emby. Sci-Fi is films only for now, though the bible says films and series. diff --git a/android/app/build.gradle.kts b/android/app/build.gradle.kts index 2db47cd..2e17f2d 100644 --- a/android/app/build.gradle.kts +++ b/android/app/build.gradle.kts @@ -9,8 +9,8 @@ android { applicationId = "tv.orbit.classic" minSdk = 26 targetSdk = 36 - versionCode = 66 - versionName = "0.65.0-now-marker-new-icons" + versionCode = 67 + versionName = "0.66.0-full-lineup" } buildFeatures { compose = true } compileOptions { sourceCompatibility = JavaVersion.VERSION_17; targetCompatibility = JavaVersion.VERSION_17 } diff --git a/android/app/src/main/java/tv/orbit/classic/ChannelBranding.kt b/android/app/src/main/java/tv/orbit/classic/ChannelBranding.kt index 601990f..7fead54 100644 --- a/android/app/src/main/java/tv/orbit/classic/ChannelBranding.kt +++ b/android/app/src/main/java/tv/orbit/classic/ChannelBranding.kt @@ -15,6 +15,17 @@ internal object ChannelBrands { 115 to ChannelBranding("orbit-britx", "Orbit BritX", R.drawable.orbit_britx_epg, R.drawable.orbit_one_background, R.drawable.orbit_britx_bug, ChannelCategory.Movies), 125 to ChannelBranding("orbit-junior", "Orbit Junior", R.drawable.orbit_junior_epg, R.drawable.orbit_one_background, R.drawable.orbit_junior_bug, ChannelCategory.Kids), 143 to ChannelBranding("orbit-wild", "Orbit Wild", R.drawable.orbit_wild_epg, R.drawable.orbit_one_background, R.drawable.orbit_wild_bug, ChannelCategory.Documentaries), + 104 to ChannelBranding("orbit-2", "Orbit 2", R.drawable.orbit_2_epg, R.drawable.orbit_one_background, R.drawable.orbit_2_bug, ChannelCategory.Entertainment), + 126 to ChannelBranding("wonder", "Orbit Wonder", R.drawable.wonder_epg, R.drawable.orbit_one_background, R.drawable.wonder_bug, ChannelCategory.Kids), + 127 to ChannelBranding("orbit-pixelz", "Orbit PixelZ", R.drawable.orbit_pixelz_epg, R.drawable.orbit_one_background, R.drawable.orbit_pixelz_bug, ChannelCategory.Kids), + 131 to ChannelBranding("orbit-vhs", "Orbit VHS", R.drawable.orbit_vhs_epg, R.drawable.orbit_one_background, R.drawable.orbit_vhs_bug, ChannelCategory.Movies), + 132 to ChannelBranding("orbit-sci-fi", "Orbit Sci-Fi", R.drawable.orbit_sci_fi_epg, R.drawable.orbit_one_background, R.drawable.orbit_sci_fi_bug, ChannelCategory.Movies), + 133 to ChannelBranding("orbit-horror", "Orbit Horror", R.drawable.orbit_horror_epg, R.drawable.orbit_one_background, R.drawable.orbit_horror_bug, ChannelCategory.Movies), + 134 to ChannelBranding("orbit-action", "Orbit Action", R.drawable.orbit_action_epg, R.drawable.orbit_one_background, R.drawable.orbit_action_bug, ChannelCategory.Movies), + 135 to ChannelBranding("orbit-romance", "Orbit Romance", R.drawable.orbit_romance_epg, R.drawable.orbit_one_background, R.drawable.orbit_romance_bug, ChannelCategory.Movies), + 136 to ChannelBranding("orbit-premiere", "Orbit Premiere", R.drawable.orbit_premiere_epg, R.drawable.orbit_one_background, R.drawable.orbit_premiere_bug, ChannelCategory.Movies), + 144 to ChannelBranding("orbit-odyssey", "Orbit Odyssey", R.drawable.orbit_odyssey_epg, R.drawable.orbit_one_background, R.drawable.orbit_odyssey_bug, ChannelCategory.Documentaries), + 150 to ChannelBranding("orbit-ring-x", "Orbit Ring X", R.drawable.orbit_ring_x_epg, R.drawable.orbit_one_background, R.drawable.orbit_ring_x_bug, ChannelCategory.Sport), 121 to ChannelBranding("heroes", "Orbit Heroes", R.drawable.heroes_epg, R.drawable.heroes_background, R.drawable.heroes_bug, ChannelCategory.Cartoons), 122 to ChannelBranding("toonz", "Orbit ToonZ", R.drawable.toonz_epg, R.drawable.toonz_background, R.drawable.toonz_bug, ChannelCategory.Cartoons), 123 to ChannelBranding("rewind", "Orbit Rewind", R.drawable.rewind_epg, R.drawable.rewind_background, R.drawable.rewind_bug, ChannelCategory.Cartoons), diff --git a/android/app/src/main/java/tv/orbit/classic/ChannelPresets.kt b/android/app/src/main/java/tv/orbit/classic/ChannelPresets.kt index bb991b1..ecedabb 100644 --- a/android/app/src/main/java/tv/orbit/classic/ChannelPresets.kt +++ b/android/app/src/main/java/tv/orbit/classic/ChannelPresets.kt @@ -15,6 +15,11 @@ internal val DarkFilesMysteries = listOf("Unsolved Mysteries", "Wild Wild Countr internal val DarkFilesParanormal = listOf("Paranormal Witness", "Most Haunted", "Ghost Adventures", "Ghost Hunters", "Hellier", "A Haunting", "The Dead Files", "Paranormal State", "Ghost Brothers", "Kindred Spirits", "Haunted", "Ghost Stories", "Celebrity Ghost Stories", "Ghost Asylum", "My Ghost Story") +internal val RingXMondayNight = listOf("WWE Monday Night RAW", "WWF Monday Night RAW", "WWE Raw", "WWF Raw", "WWF RAW is WAR", "WCW Monday Nitro", "WCW Nitro") +internal val RingXImpact = listOf("TNA iMPACT!", "TNA Impact!", "TNA Impact Wrestling", "Impact Wrestling", "TNA Wrestling") +internal val RingXAew = listOf("AEW Dynamite", "All Elite Wrestling: Dynamite", "AEW Rampage", "All Elite Wrestling: Rampage", "AEW Collision", "AEW Dark") +internal val RingXVault = listOf("WWE SmackDown", "WWF SmackDown", "WWE Friday Night SmackDown", "ECW Hardcore TV", "ECW on TNN", "WWE ECW", "WCW Thunder", "WCW Saturday Night", "WWE NXT", "WWF Superstars", "WWF Attitude", "WrestleMania", "WWE WrestleMania", "WWE Pay-Per-View", "WWF Pay-Per-View", "WCW Pay-Per-View", "ECW Pay-Per-View", "The Monday Night War", "Dark Side of the Ring", "WWE Legends' House") + internal val ChannelPresets = listOf( ChannelPreset(140, "Terra", listOf("Blue Planet", "Planet Earth", "Frozen Planet", "Life", "Our Planet")), ChannelPreset(152, "Paradox", listOf("X-Files", "Buffy the Vampire Slayer", "Supernatural", "Fringe", "Doctor Who")), @@ -51,7 +56,23 @@ internal val ChannelPresets = listOf( 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", "Pingu in the City", "Peppa Pig", "Bluey", "Bagpuss", "The Clangers", "Camberwick Green", "Trumpton", "Button Moon", "Rainbow", "Balamory", "Fimbles"), smartOnly = true), ChannelPreset(143, "Orbit Wild", listOf("The Crocodile Hunter", "Crocodile Hunter Diaries", "Deadliest Catch", "River Monsters", "Man vs. Wild", "Running Wild with Bear Grylls", "Survivorman", "Dual Survival", "Naked and Afraid", "Ice Road Truckers", - "Swamp People", "Wild Things with Dominic Monaghan", "Lone Star Law", "Alone", "Ax Men", "Monster Fish", "Dirty Jobs", "Shark Week", "Whale Wars", "Dangerous Encounters with Brady Barr"), smartOnly = true)) + "Swamp People", "Wild Things with Dominic Monaghan", "Lone Star Law", "Alone", "Ax Men", "Monster Fish", "Dirty Jobs", "Shark Week", "Whale Wars", "Dangerous Encounters with Brady Barr"), smartOnly = true), + ChannelPreset(104, "Orbit 2", listOf("Twin Peaks", "Quantum Leap", "The Twilight Zone", "The Outer Limits", "Tales from the Crypt", "Eerie, Indiana", "Are You Afraid of the Dark?", "Goosebumps", "Sliders", "Knight Rider", "The A-Team", "Airwolf", "MacGyver", + "Red Dwarf", "The Crystal Maze", "Robot Wars", "Gladiators", "Takeshi's Castle", "Gadget Show", "Top Gear", "Time Team", "Scrapheap Challenge", "Countdown", "Have I Got News for You", "QI", "Would I Lie to You?", "Pointless", "Mastermind", "University Challenge", "Mythbusters", "How It's Made"), smartOnly = true), + ChannelPreset(126, "Wonder", listOf("Snow White and the Seven Dwarfs", "Pinocchio", "Dumbo", "Bambi", "Cinderella", "Alice in Wonderland", "Peter Pan", "Lady and the Tramp", "Sleeping Beauty", "One Hundred and One Dalmatians", "The Jungle Book", "The Aristocats", "Robin Hood", + "The Fox and the Hound", "The Little Mermaid", "Beauty and the Beast", "Aladdin", "The Lion King", "Pocahontas", "The Hunchback of Notre Dame", "Hercules", "Mulan", "Tarzan", "The Emperor's New Groove", "Atlantis: The Lost Empire", "Lilo & Stitch", "Treasure Planet", "Brother Bear", "The Princess and the Frog", + "An American Tail", "The Land Before Time", "All Dogs Go to Heaven", "Anastasia", "The Secret of NIMH", "Thumbelina", "The Iron Giant", "The Prince of Egypt", "Spirited Away", "My Neighbor Totoro", "Kiki's Delivery Service", "Howl's Moving Castle", "Ponyo", "Princess Mononoke", "Castle in the Sky"), smartOnly = true, films = true), + ChannelPreset(127, "PixelZ", listOf("Toy Story", "Toy Story 2", "Toy Story 3", "Toy Story 4", "A Bug's Life", "Monsters, Inc.", "Monsters University", "Finding Nemo", "Finding Dory", "The Incredibles", "Incredibles 2", "Cars", "Cars 2", "Cars 3", "Ratatouille", "WALL·E", "Up", "Brave", "Inside Out", "Coco", "Luca", "Soul", + "Shrek", "Shrek 2", "Shrek the Third", "Shrek Forever After", "Puss in Boots", "Madagascar", "Madagascar: Escape 2 Africa", "Kung Fu Panda", "Kung Fu Panda 2", "How to Train Your Dragon", "How to Train Your Dragon 2", "Megamind", "Antz", "Ice Age", "Ice Age: The Meltdown", "Despicable Me", "Despicable Me 2", "Minions", "The Lego Movie", "Tangled", "Frozen", "Moana", "Zootopia", "Big Hero 6", "Wreck-It Ralph", "Rio", "Robots"), smartOnly = true, films = true), + ChannelPreset(131, "Orbit VHS", listOf("Back to the Future", "Back to the Future Part II", "Back to the Future Part III", "The Goonies", "Gremlins", "Gremlins 2: The New Batch", "Ghostbusters", "Ghostbusters II", "E.T. the Extra-Terrestrial", "Honey, I Shrunk the Kids", "Flight of the Navigator", "The NeverEnding Story", "Labyrinth", "Willow", "The Princess Bride", "Short Circuit", "Batteries Not Included", "Explorers", "Stand by Me", "The Karate Kid", "The Karate Kid Part II", + "Ferris Bueller's Day Off", "The Breakfast Club", "Weird Science", "Teen Wolf", "Bill & Ted's Excellent Adventure", "Bill & Ted's Bogus Journey", "Wayne's World", "Big", "Home Alone", "Home Alone 2: Lost in New York", "Beetlejuice", "Hook", "Jumanji", "Mrs. Doubtfire", "Mac and Me", "Police Academy", "Top Gun", "Crocodile Dundee", "Who Framed Roger Rabbit", "Howard the Duck", "Masters of the Universe", "Innerspace", "Big Trouble in Little China", "Three Amigos", "Spaceballs"), smartOnly = true, films = true), + ChannelPreset(132, "Orbit Sci-Fi", listOf("2001: A Space Odyssey", "Star Wars", "The Empire Strikes Back", "Return of the Jedi", "Alien", "Aliens", "Blade Runner", "The Terminator", "Terminator 2: Judgment Day", "RoboCop", "Total Recall", "Predator", "Stargate", "Starship Troopers", "The Fifth Element", "Contact", "Gattaca", "Dark City", "The Matrix", "Pitch Black", "Event Horizon", "Sunshine", "Moon", "District 9", "Inception", "Interstellar", "Gravity", "The Martian", "Arrival", "Ex Machina", "Dune", "Edge of Tomorrow", "Minority Report", "Looper", "Children of Men", "Star Trek II: The Wrath of Khan", "Star Trek: First Contact", "Star Trek", "Tron", "Close Encounters of the Third Kind", "The Abyss", "Independence Day", "Men in Black", "Serenity", "Planet of the Apes", "Soylent Green", "Logan's Run", "Primer"), smartOnly = true, films = true), + ChannelPreset(133, "Orbit Horror", listOf("A Nightmare on Elm Street", "Friday the 13th", "The Texas Chain Saw Massacre", "Night of the Living Dead", "Dawn of the Dead", "The Exorcist", "The Omen", "The Shining", "Carrie", "Pet Sematary", "It", "Misery", "Child's Play", "Candyman", "Jaws", "The Blair Witch Project", "The Ring", "Saw", "Hostel", "The Descent", "Insidious", "The Conjuring", "Sinister", "Hereditary", "Midsommar", "The Witch", "It Follows", "Get Out", "A Quiet Place", "Rosemary's Baby", "Psycho", "The Birds", "Black Christmas", "Sleepaway Camp", "Maniac", "The Hills Have Eyes", "Critters", "Leprechaun", "Pumpkinhead", "Army of Darkness", "Evil Dead II", "Braindead", "The Mist", "Drag Me to Hell", "The Babadook", "Train to Busan", "Ringu", "Barbarian"), smartOnly = true, films = true), + ChannelPreset(134, "Orbit Action", listOf("Die Hard", "Die Hard 2", "Die Hard with a Vengeance", "Lethal Weapon", "Lethal Weapon 2", "Commando", "Rambo: First Blood", "First Blood", "Rocky", "Cobra", "Tango & Cash", "Demolition Man", "Speed", "The Rock", "Con Air", "Face/Off", "Heat", "Point Break", "Bad Boys", "Enter the Dragon", "Rush Hour", "Police Story", "Bloodsport", "Kickboxer", "Under Siege", "Hard Target", "Mortal Kombat", "Blade", "John Wick", "John Wick: Chapter 2", "Taken", "The Raid", "Mad Max", "Mad Max 2", "Mad Max: Fury Road", "The Bourne Identity", "The Bourne Supremacy", "The Bourne Ultimatum", "Casino Royale", "GoldenEye", "Mission: Impossible", "Gladiator", "The Fast and the Furious", "The Transporter", "Crank", "Kill Bill: Vol. 1", "Kill Bill: Vol. 2", "The Expendables", "Dredd", "Sicario"), smartOnly = true, films = true), + ChannelPreset(135, "Orbit Romance", listOf("Pretty Woman", "When Harry Met Sally...", "Sleepless in Seattle", "You've Got Mail", "Notting Hill", "Four Weddings and a Funeral", "Love Actually", "Bridget Jones's Diary", "About Time", "Titanic", "Ghost", "Dirty Dancing", "The Notebook", "Crazy, Stupid, Love.", "10 Things I Hate About You", "She's All That", "Clueless", "The Holiday", "The Proposal", "Hitch", "Maid in Manhattan", "Runaway Bride", "My Best Friend's Wedding", "While You Were Sleeping", "Serendipity", "How to Lose a Guy in 10 Days", "13 Going on 30", "The Wedding Singer", "50 First Dates", "There's Something About Mary", "La La Land", "The Princess Diaries", "Mamma Mia!", "Grease", "Casablanca", "Roman Holiday", "Breakfast at Tiffany's", "Amélie", "Pride & Prejudice", "Sense and Sensibility", "Crazy Rich Asians", "Me Before You", "Forrest Gump", "Jerry Maguire", "Shakespeare in Love"), smartOnly = true, films = true), + ChannelPreset(136, "Orbit Premiere", listOf("Jurassic Park", "The Lost World: Jurassic Park", "Raiders of the Lost Ark", "Indiana Jones and the Temple of Doom", "Indiana Jones and the Last Crusade", "Superman", "Batman", "Batman Returns", "Batman Begins", "The Dark Knight", "The Dark Knight Rises", "Spider-Man", "Spider-Man 2", "X-Men", "X2", "Iron Man", "The Avengers", "Avengers: Infinity War", "Avengers: Endgame", "Black Panther", "Guardians of the Galaxy", "The Lord of the Rings: The Fellowship of the Ring", "The Lord of the Rings: The Two Towers", "The Lord of the Rings: The Return of the King", "Harry Potter and the Philosopher's Stone", "Pirates of the Caribbean: The Curse of the Black Pearl", "Avatar", "Transformers", "Armageddon", "Twister", "Top Gun: Maverick", "The Mummy", "The Mask of Zorro", "Braveheart", "Skyfall", "Mission: Impossible - Fallout", "King Kong", "Godzilla", "Pacific Rim", "Wonder Woman", "Oppenheimer"), smartOnly = true, films = true), + ChannelPreset(144, "Odyssey", listOf("Cosmos", "Cosmos: A Spacetime Odyssey", "Wonders of the Universe", "Wonders of the Solar System", "The Universe", "How the Universe Works", "Civilisation", "Civilizations", "Connections", "The Ascent of Man", "The World at War", "Band of Brothers", "The Vietnam War", "The Civil War", "Apollo 11", "Horizon", "Seconds from Disaster", "Air Crash Investigation", "Mayday", "Engineering the Impossible", "Impossible Engineering", "Extreme Engineering", "Big Bigger Biggest", "Ancient Apocalypse", "Rome's Greatest Battles", "The Story of India", "Egypt's Lost Cities", "Long Way Round", "Long Way Down", "Parts Unknown", "An Idiot Abroad", "Michael Palin's Himalaya", "Pole to Pole", "Around the World in 80 Days", "James May's Man Lab", "The Story of Maths", "Walking with Dinosaurs"), smartOnly = true), + ChannelPreset(150, "Ring X", RingXMondayNight + RingXImpact + RingXAew + RingXVault, smartOnly = true)) /** A fallback for a channel with no old loop: its first episodes, in turn. Used only outside its plan. */ internal fun loopFromPool(pool: List, programming: ChannelProgramming): SampleChannel? { diff --git a/android/app/src/main/java/tv/orbit/classic/ChannelSchedule.kt b/android/app/src/main/java/tv/orbit/classic/ChannelSchedule.kt index 1c71548..6ee88b2 100644 --- a/android/app/src/main/java/tv/orbit/classic/ChannelSchedule.kt +++ b/android/app/src/main/java/tv/orbit/classic/ChannelSchedule.kt @@ -65,7 +65,10 @@ internal val SmartChannels = listOf( /** Dark Files, from the programming bible: crime by day, mysteries early evening, the paranormal late. */ private val SmartChannelParts: Map> get() = mapOf(142 to listOf( - DayPart(6, 18, DarkFilesCrime, group = "day"), DayPart(18, 21, DarkFilesMysteries, group = "evening"), DayPart(21, 6, DarkFilesParanormal, group = "late"))) + DayPart(6, 18, DarkFilesCrime, group = "day"), DayPart(18, 21, DarkFilesMysteries, group = "evening"), DayPart(21, 6, DarkFilesParanormal, group = "late")), + // Ring X, from the bible: each weeknight's own show, and the whole vault the rest of the week. + 150 to listOf(DayPart(0, 24, RingXMondayNight, days = setOf(java.time.DayOfWeek.MONDAY)), DayPart(0, 24, RingXImpact, days = setOf(java.time.DayOfWeek.TUESDAY)), + DayPart(0, 24, RingXAew, days = setOf(java.time.DayOfWeek.WEDNESDAY)))) /** Optional bigger pools, only used once reviewed. No rule for Orbit Gold or Orbit Three: nothing in the library's details can tell a British sitcom apart. */ private val SmartChannelRules: Map> get() = mapOf( @@ -76,6 +79,14 @@ private val SmartChannelRules: Map> get() = mapOf( 142 to listOf(SuggestionRule("day", "Crime documentary", "Series", listOf("Documentary", "Crime"), 1990..2024, 7f, emptySet(), 40, setOf("Animation")), SuggestionRule("evening", "Mystery documentary", "Series", listOf("Documentary", "Mystery"), 1985..2024, 6.5f, emptySet(), 30, setOf("Animation"))), 113 to listOf(SuggestionRule("all", "Adult animation", "Series", listOf("Animation", "Comedy"), 1990..2024, 7.5f, emptySet(), 30, setOf("Anime", "Family", "Children"))), + 131 to listOf(SuggestionRule("all", "80s and 90s adventure", "Movie", listOf("Adventure"), 1980..1999, 6.5f, setOf("NC-17", "X"), 40, setOf("Documentary"), 70), + SuggestionRule("all", "80s and 90s comedy", "Movie", listOf("Comedy"), 1980..1999, 7f, setOf("NC-17", "X"), 40, setOf("Documentary", "Horror"), 70)), + 132 to listOf(SuggestionRule("all", "Science fiction", "Movie", listOf("Science Fiction"), 1968..2025, 6.5f, emptySet(), 60, setOf("Animation", "Documentary", "Family"), 70)), + 133 to listOf(SuggestionRule("all", "Horror", "Movie", listOf("Horror"), 1970..2025, 6f, emptySet(), 60, setOf("Animation", "Documentary"), 70)), + 134 to listOf(SuggestionRule("all", "Action", "Movie", listOf("Action"), 1980..2025, 6.5f, emptySet(), 60, setOf("Animation", "Documentary", "Family", "Horror"), 70)), + 135 to listOf(SuggestionRule("all", "Romantic comedy", "Movie", listOf("Romance", "Comedy"), 1985..2025, 6.5f, emptySet(), 60, setOf("Animation", "Documentary", "Horror"), 70)), + 136 to listOf(SuggestionRule("all", "Big event films", "Movie", listOf("Adventure", "Action"), 1975..2025, 7.5f, emptySet(), 40, setOf("Animation", "Documentary"), 80)), + 144 to listOf(SuggestionRule("all", "History and science", "Series", listOf("Documentary", "History"), 1970..2025, 7f, emptySet(), 30, setOf("Crime", "Animation"))), 141 to listOf(SuggestionRule("all", "Crime drama", "Series", listOf("Crime", "Drama"), 1985..2022, 7f, emptySet(), 40, setOf("Documentary", "Animation")))) internal data class EpisodeMark(val season: Int, val episode: Int) : Comparable { diff --git a/android/app/src/main/java/tv/orbit/classic/EmbyClient.kt b/android/app/src/main/java/tv/orbit/classic/EmbyClient.kt index 7b84b1f..f4efed3 100644 --- a/android/app/src/main/java/tv/orbit/classic/EmbyClient.kt +++ b/android/app/src/main/java/tv/orbit/classic/EmbyClient.kt @@ -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.65.0\"") + connection.setRequestProperty("X-Emby-Authorization", "Emby Client=\"Orbit TV\", Device=\"Orbit TV\", DeviceId=\"$deviceId\", Version=\"0.66.0\"") request.token?.let { connection.setRequestProperty("X-Emby-Token", it) } if (request.method == "POST") { val bytes = request.body.orEmpty().toByteArray(Charsets.UTF_8) diff --git a/android/app/src/main/java/tv/orbit/classic/SecureMediaDataSource.kt b/android/app/src/main/java/tv/orbit/classic/SecureMediaDataSource.kt index 30d83dc..68e34da 100644 --- a/android/app/src/main/java/tv/orbit/classic/SecureMediaDataSource.kt +++ b/android/app/src/main/java/tv/orbit/classic/SecureMediaDataSource.kt @@ -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.65.0") + next.setRequestProperty("User-Agent", "OrbitTV/0.66.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()) { diff --git a/android/app/src/main/res/drawable-nodpi/orbit_2_bug.webp b/android/app/src/main/res/drawable-nodpi/orbit_2_bug.webp new file mode 100644 index 0000000..6a0a909 Binary files /dev/null and b/android/app/src/main/res/drawable-nodpi/orbit_2_bug.webp differ diff --git a/android/app/src/main/res/drawable-nodpi/orbit_2_epg.webp b/android/app/src/main/res/drawable-nodpi/orbit_2_epg.webp new file mode 100644 index 0000000..1f33d0b Binary files /dev/null and b/android/app/src/main/res/drawable-nodpi/orbit_2_epg.webp differ diff --git a/android/app/src/main/res/drawable-nodpi/orbit_action_bug.webp b/android/app/src/main/res/drawable-nodpi/orbit_action_bug.webp new file mode 100644 index 0000000..0e6a477 Binary files /dev/null and b/android/app/src/main/res/drawable-nodpi/orbit_action_bug.webp differ diff --git a/android/app/src/main/res/drawable-nodpi/orbit_action_epg.webp b/android/app/src/main/res/drawable-nodpi/orbit_action_epg.webp new file mode 100644 index 0000000..f1813e1 Binary files /dev/null and b/android/app/src/main/res/drawable-nodpi/orbit_action_epg.webp differ diff --git a/android/app/src/main/res/drawable-nodpi/orbit_horror_bug.webp b/android/app/src/main/res/drawable-nodpi/orbit_horror_bug.webp new file mode 100644 index 0000000..5809ae1 Binary files /dev/null and b/android/app/src/main/res/drawable-nodpi/orbit_horror_bug.webp differ diff --git a/android/app/src/main/res/drawable-nodpi/orbit_horror_epg.webp b/android/app/src/main/res/drawable-nodpi/orbit_horror_epg.webp new file mode 100644 index 0000000..1db44a6 Binary files /dev/null and b/android/app/src/main/res/drawable-nodpi/orbit_horror_epg.webp differ diff --git a/android/app/src/main/res/drawable-nodpi/orbit_odyssey_bug.webp b/android/app/src/main/res/drawable-nodpi/orbit_odyssey_bug.webp new file mode 100644 index 0000000..7af7379 Binary files /dev/null and b/android/app/src/main/res/drawable-nodpi/orbit_odyssey_bug.webp differ diff --git a/android/app/src/main/res/drawable-nodpi/orbit_odyssey_epg.webp b/android/app/src/main/res/drawable-nodpi/orbit_odyssey_epg.webp new file mode 100644 index 0000000..e0d542e Binary files /dev/null and b/android/app/src/main/res/drawable-nodpi/orbit_odyssey_epg.webp differ diff --git a/android/app/src/main/res/drawable-nodpi/orbit_pixelz_bug.webp b/android/app/src/main/res/drawable-nodpi/orbit_pixelz_bug.webp new file mode 100644 index 0000000..d90eb59 Binary files /dev/null and b/android/app/src/main/res/drawable-nodpi/orbit_pixelz_bug.webp differ diff --git a/android/app/src/main/res/drawable-nodpi/orbit_pixelz_epg.webp b/android/app/src/main/res/drawable-nodpi/orbit_pixelz_epg.webp new file mode 100644 index 0000000..7ecc205 Binary files /dev/null and b/android/app/src/main/res/drawable-nodpi/orbit_pixelz_epg.webp differ diff --git a/android/app/src/main/res/drawable-nodpi/orbit_premiere_bug.webp b/android/app/src/main/res/drawable-nodpi/orbit_premiere_bug.webp new file mode 100644 index 0000000..4a0d4ae Binary files /dev/null and b/android/app/src/main/res/drawable-nodpi/orbit_premiere_bug.webp differ diff --git a/android/app/src/main/res/drawable-nodpi/orbit_premiere_epg.webp b/android/app/src/main/res/drawable-nodpi/orbit_premiere_epg.webp new file mode 100644 index 0000000..76df953 Binary files /dev/null and b/android/app/src/main/res/drawable-nodpi/orbit_premiere_epg.webp differ diff --git a/android/app/src/main/res/drawable-nodpi/orbit_ring_x_bug.webp b/android/app/src/main/res/drawable-nodpi/orbit_ring_x_bug.webp new file mode 100644 index 0000000..e11be3d Binary files /dev/null and b/android/app/src/main/res/drawable-nodpi/orbit_ring_x_bug.webp differ diff --git a/android/app/src/main/res/drawable-nodpi/orbit_ring_x_epg.webp b/android/app/src/main/res/drawable-nodpi/orbit_ring_x_epg.webp new file mode 100644 index 0000000..be35b7e Binary files /dev/null and b/android/app/src/main/res/drawable-nodpi/orbit_ring_x_epg.webp differ diff --git a/android/app/src/main/res/drawable-nodpi/orbit_romance_bug.webp b/android/app/src/main/res/drawable-nodpi/orbit_romance_bug.webp new file mode 100644 index 0000000..8e90654 Binary files /dev/null and b/android/app/src/main/res/drawable-nodpi/orbit_romance_bug.webp differ diff --git a/android/app/src/main/res/drawable-nodpi/orbit_romance_epg.webp b/android/app/src/main/res/drawable-nodpi/orbit_romance_epg.webp new file mode 100644 index 0000000..146ebc8 Binary files /dev/null and b/android/app/src/main/res/drawable-nodpi/orbit_romance_epg.webp differ diff --git a/android/app/src/main/res/drawable-nodpi/orbit_sci_fi_bug.webp b/android/app/src/main/res/drawable-nodpi/orbit_sci_fi_bug.webp new file mode 100644 index 0000000..84575c5 Binary files /dev/null and b/android/app/src/main/res/drawable-nodpi/orbit_sci_fi_bug.webp differ diff --git a/android/app/src/main/res/drawable-nodpi/orbit_sci_fi_epg.webp b/android/app/src/main/res/drawable-nodpi/orbit_sci_fi_epg.webp new file mode 100644 index 0000000..5fae36d Binary files /dev/null and b/android/app/src/main/res/drawable-nodpi/orbit_sci_fi_epg.webp differ diff --git a/android/app/src/main/res/drawable-nodpi/orbit_vhs_bug.webp b/android/app/src/main/res/drawable-nodpi/orbit_vhs_bug.webp new file mode 100644 index 0000000..b1f19f1 Binary files /dev/null and b/android/app/src/main/res/drawable-nodpi/orbit_vhs_bug.webp differ diff --git a/android/app/src/main/res/drawable-nodpi/orbit_vhs_epg.webp b/android/app/src/main/res/drawable-nodpi/orbit_vhs_epg.webp new file mode 100644 index 0000000..f7d76a3 Binary files /dev/null and b/android/app/src/main/res/drawable-nodpi/orbit_vhs_epg.webp differ diff --git a/android/app/src/main/res/drawable-nodpi/wonder_bug.webp b/android/app/src/main/res/drawable-nodpi/wonder_bug.webp new file mode 100644 index 0000000..b0ace4b Binary files /dev/null and b/android/app/src/main/res/drawable-nodpi/wonder_bug.webp differ diff --git a/android/app/src/main/res/drawable-nodpi/wonder_epg.webp b/android/app/src/main/res/drawable-nodpi/wonder_epg.webp new file mode 100644 index 0000000..6b34103 Binary files /dev/null and b/android/app/src/main/res/drawable-nodpi/wonder_epg.webp differ diff --git a/android/app/src/test/java/tv/orbit/classic/ChannelPresetsTest.kt b/android/app/src/test/java/tv/orbit/classic/ChannelPresetsTest.kt index c8f6f9c..07ba90f 100644 --- a/android/app/src/test/java/tv/orbit/classic/ChannelPresetsTest.kt +++ b/android/app/src/test/java/tv/orbit/classic/ChannelPresetsTest.kt @@ -155,4 +155,27 @@ class ChannelPresetsTest { assertEquals(listOf("Movie", "Movie"), loop.lineup.map { it.item.type }) assertEquals("Film a", loop.lineup.first().item.title) } + + @Test fun theLastChannelsAreConfiguredAndBranded() { + listOf(104, 126, 127, 131, 132, 133, 134, 135, 136, 144, 150).forEach { number -> + assertNotNull(ChannelBrands.forNumber(number)) + assertTrue(SmartChannels.any { it.number == number && it.exactTitles }) + } + listOf(126, 127, 131, 132, 133, 134, 135, 136).forEach { assertNotNull(SmartChannels.first { channel -> channel.number == it }.filmRestMs) } + assertEquals(ChannelCategory.Sport, ChannelBrands.forNumber(150)!!.category) + assertEquals(28, SmartChannels.size) + } + + @Test fun ringXKeepsItsWeeknightsAndFallsBackToTheVault() { + val ringX = SmartChannels.first { it.number == 150 } + val london = java.time.ZoneId.of("Europe/London") + fun show(title: String) = PoolSeries(title, title, listOf(PoolEpisode("$title-1", "s", EpisodeMark(1, 1), "E1", 60_000))) + val pool = listOf(show("WCW Monday Nitro"), show("AEW Dynamite"), show("WrestleMania")) + fun on(day: Int) = java.time.ZonedDateTime.of(2026, 11, day, 21, 0, 0, 0, london).toInstant().toEpochMilli() + assertEquals(listOf("WCW Monday Nitro"), dayPartPool(pool, ringX.dayParts, on(2), london).map { it.title }) + assertEquals(listOf("AEW Dynamite"), dayPartPool(pool, ringX.dayParts, on(4), london).map { it.title }) + assertEquals(3, dayPartPool(pool, ringX.dayParts, on(7), london).size) + // No Impact in this library, so Tuesday isn't left empty. + assertEquals(3, dayPartPool(pool, ringX.dayParts, on(3), london).size) + } }