argontv: the shared line, and whether there is room to sell - #61
Merged
Conversation
Live TV passes are sold against one shared IPTV line, and nothing here could see it. Checking whether the line was healthy, how many of its connections were in use, or when it expired meant opening a browser and reading a panel, which is not a thing that can gate a sale. argontv status, expiry and free connections argontv slots [--json] free now; exit 3 when full argontv catalogue live / films / series counts argontv templates reseller templates (needs the account key) `slots` is the one with a job. A shared line permits a fixed number of simultaneous streams, so how many passes may exist is bounded by hardware rather than by demand -- sell one too many and the buyer who paid is the one told to come back later. The exit code is the interface: 0 there is room, 3 the line is full, 4 it could not be reached. A sale webhook checks that before taking money rather than discovering it afterwards. **Two APIs, kept apart on purpose.** The panel (player_api.php on the line's own server) answers about a line that exists and authenticates with the line's own username and password. The reseller API creates and extends lines, authenticates with an account-wide key, and spends money. Everything that reads is on the panel; everything that spends is on the reseller API, is marked as such, and refuses without an explicit key. A tool that could quietly provision a line because a variable happened to be set is a tool that bills you for a typo. **Sellable is not capacity.** The panel reports what the line permits; the tool reports one fewer as sellable, because selling to the full number means the first person to open a stream to check a complaint takes the slot a paying customer is using -- and the customer is the one who sees it fail. ARGONTV_MAX_PASSES overrides the reserve. Verified against a real line: 6 connections reported, 5 sellable, 1 held back, 30 days remaining, formats ts/m3u8/rtmp. Two things worth recording that came out of building it. The panel answers 200 with `auth: 0` for a wrong password rather than 401, so a check that only read the HTTP status would report a dead line as healthy with every field null; that is a refusal here. And `get_series` counts SHOWS while the M3U counts EPISODES, about twenty-six per show, which is why one line reports 44,790 series and its playlist has 1,152,848 entries for the same catalogue -- the numbers look like they disagree and do not. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0172JWTmsEEEcdAxPdn3UZnm
ThreatCrush Security Scan12 finding(s) HIGH/CRITICAL: 4 | MEDIUM: 4 | LOW: 4
Snippets are redacted; ThreatCrush never prints matched credential material. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Live TV passes are sold against one shared IPTV line, and nothing here could see it. Checking whether the line was healthy, how many connections were in use, or when it expired meant opening a browser — which is not a thing that can gate a sale.
slotsis the one with a job. A shared line permits a fixed number of simultaneous streams, so how many passes may exist is bounded by hardware rather than demand — sell one too many and the buyer who paid is the one told to come back later. The exit code is the interface:0room,3full,4unreachable. A sale webhook checks it before taking money rather than discovering the problem after.Two APIs, kept apart deliberately. The panel (
player_api.php) answers about an existing line and authenticates with that line's own credentials. The reseller API creates and extends lines, authenticates with an account-wide key, and spends money. Everything that reads is on the panel; everything that spends is on the reseller API, marked as such, and refuses without an explicit key. A tool that could quietly provision a line because a variable happened to be set is a tool that bills you for a typo.Sellable is not capacity. The panel reports what the line permits; this reports one fewer, because selling to the full number means the first person opening a stream to check a complaint takes the slot a paying customer is using — and the customer is the one who sees it fail.
ARGONTV_MAX_PASSESoverrides the reserve.Verified against a real line: 6 connections, 5 sellable, 30 days remaining.
Two findings worth recording:
auth: 0for a wrong password rather than 401, so a check reading only the HTTP status would report a dead line as healthy with every field null. Treated as a refusal here.get_seriescounts shows; the M3U counts episodes, ~26 per show. That is why one line reports 44,790 series while its playlist has 1,152,848 entries for the same catalogue — the numbers look like they disagree and don't.Tests: 13 new, covering the reserve arithmetic, the
auth: 0refusal, epoch conversion, per-kind counts and config precedence. Suite 757 pass, 1 pre-existing failure inroot-ubuntu.test.ts(untouched here).🤖 Generated with Claude Code
https://claude.ai/code/session_0172JWTmsEEEcdAxPdn3UZnm