timothyandClaude Fable 5.1 131c63f7f4 fix(568): one ordinal identity predicate for the built-in element, applied in memory at both sites
The branch moved the `builtIn` discriminator from a bare filename to the full
seeded path, but split how the two sites evaluate it: the API handler compares
in memory (ordinal) while GetBuiltInElementId's new `.Where(e => e.Path ==
OnNowNextSeededPath)` compares in SQL. GraphicsElement.Path takes no explicit
collation -- TvContext.OnModelCreating pins one only on the listed name/title
columns -- so SQLite answers that case-sensitively and MySQL uses the server
default, which is normally case-INsensitive. On MySQL the two discriminators
could therefore disagree about the same row: AttachOnNowNextByDefault would
resolve a case-variant user element as the built-in one while the API reported
builtIn:false for it.

Collapse both onto GraphicsElementDefaults.IsOnNowNext, ordinal, applied in
memory. GetBuiltInElementId goes back to loading the Text candidates and
filtering in memory (the shape it had before this branch), keeping only the
`Kind` enum filter in SQL.

The prose claimed more than the code did. "A filename-only comparison is
case-sensitive-by-accident" appeared in four places as a defect the full-path
fix removed; a full-path comparison is exactly as case-sensitive, so the clause
said nothing and implied a fix that had not happened. Case sensitivity is now
deliberate and stated as such -- the built-in element is the exact file the
seeder wrote, at the exact path it wrote it to -- and the reason the comparison
is kept out of SQL is recorded where the predicate lives.

docs/decisions/records/graphics/channel-level-attachment.md said BuiltIn was
"computed by comparing the row's `Path` to GraphicsElementDefaults.
OnNowNextFileName", which was true of neither the pre-#568 rule (filename to
filename) nor the current one; an active record resolved by key now states the
current predicate in its own sentence rather than in a parenthetical.

Two tests pin the ordinal rule against a loosening to OrdinalIgnoreCase, one
per site. Measured: OrdinalIgnoreCase reddens exactly
GetAllGraphicsElementsForApi_Should_Not_Mark_A_Case_Variant_Of_The_Seeded_Path_As_BuiltIn
and Ignores_A_Case_Variant_Of_The_Seeded_Path, 2 failed / 77 passed of the 79
graphics tests. They do NOT pin provider independence -- under SQLite's BINARY
collation an equivalent SQL comparison answers identically, so no test in this
suite can distinguish the two. That is stated at each site rather than left for
a reader to assume the tests cover it.

Decisions-Edit: yes

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015QqCpYFsKgnAnx6jVwrKiV
2026-09-05 21:35:14 +02:00
2022-04-28 06:56:01 -05:00
2025-11-11 06:12:46 -06:00
2021-02-08 21:13:53 -06:00
2023-08-13 09:33:33 -05:00
2025-11-26 10:49:01 -06:00
2026-02-24 15:27:51 -06:00

ErsatzTV

ErsatzTV lets you transform your media library into a personalized, live TV experience - complete with EPG, channel scheduling, and seamless streaming to all your devices. Rediscover your content, your way.

contact features community

epg-example

How It Works

  1. Install ErsatzTV: Download and set up the server on your system.
  2. Add Your Media: Connect your media libraries and collections.
  3. Create Channels: Design and schedule your own live channels.
  4. Stream Anywhere: Watch on any device with IPTV and EPG support.

Key Features

  • Custom channels: Create and schedule your own live TV channels.
  • IPTV & EPG: Stream with IPTV and Electronic Program Guide support.
  • Hardware Transcoding: High-performance streaming with hardware acceleration (NVENC, QSV, VAAPI, AMF, VideoToolbox)
  • Media Server Integration: Connect Plex, Jellyfin, Emby and more.
  • Music & Subtitles: Mix music videos and enjoy subtitle support.
  • Open Source: Free, open, and community-driven project.

Documentation

Documentation is available at ersatztv.org.

License

This project is inspired by pseudotv-plex and the dizquetv fork and is released under the zlib license.

S
Description
Fork of ErsatzTV - custom IPTV channel server (upstream archived Feb 2026)
Readme Zlib
74 MiB
v26.11.0
Latest
2026-07-20 22:22:04 +02:00
Languages
C# 64.5%
TypeScript 15.8%
Python 10.1%
JavaScript 5.8%
Shell 2.5%
Other 1.2%