Repository navigation
Releases: datbird/couchelephant
Release list
CouchElephant 1.5.0
Added
-
A scheduled recording now says what settings are in force on it. Open any
recording, from the guide, the agenda, the calendar or the recordings list,
and the panel lists the padding, the quality and the rest in plain words:
"Ends 60 minutes late", notendOffsetMinutes 60.Read from Plex's own copy of the recording rather than from what the pass
asked for, because the point is to confirm the setting took effect. It works
for recordings Plex scheduled by its own rule too. Opening the panel never
waits on Plex: the values come from the copy every sync refreshes.A setting CouchElephant has no words for is shown with its own name and value
rather than hidden, so a server offering something new cannot disappear from
the one screen that exists to say what is in force.
Changed
- The fake Plex server used by the tests answers a setting by its declared
type. It used to return "true" for any value of1, so a one-minute padding
read back astrue, and the panel would have said "Starts true". A fake that
differs from the real server is as useless as one that is more permissive.
CouchElephant 1.4.0
The second cleanup review, over the routes, the alerts and the rest of the app.
Fixed
-
Alert times ignored the timezone setting. Every "a pass booked a
recording at ..." line was formatted with the container's clock rather than
the zone the app is set to. It is the one time the product quotes outside its
own pages, and it was the one time that did not honour the setting. -
The useful error message was on the path nobody takes. Sending and the
Test button each carried their own list of what a destination needs, worded
differently, and the better sentence was on the button you press once. The
settings page renders the error from the hourly send, so the sentence you
read when something is actually broken was the worse of the two. A bot with
no channel now says where to find the channel id, wherever you meet it. -
A smart pass with no name read as blank in the schedule row, the guide
panel and the failure panel. Four places spelled the label out instead of
calling the helper that describes the filter when there is no name. -
The announced search wrote to the passes table directly, bypassing the
one function whose docstring calls itself the only place a pass is written,
after the previous three had drifted apart. It was the fourth. -
One route answered a failure with HTTP 200, leaving the client to work it
out from the body alone. -
A fault code was raised as a bare string rather than its constant. Correct
today, silently broken on a rename, and now checked by a test.
Performance
Measured against the live scale: 16,700 programmes, 22,800 airings, and a
60-day history.
- The schedule is about four times faster. It ran the most expensive query
in the app twice, the second time to count rows for a number no page renders.
One row more than asked for answers the same question. The failure half also
sorted the whole history to answer a question about broadcasts that have not
aired yet. - The filter panel counted genres and teams by parsing every programme's JSON
in Python. SQLite reads it directly, guarded so one malformed row cannot take
the panel down, which is the behaviour the Python version had. - Guide search folded each title once per broadcast rather than once per
programme.
Removed
Four pieces of dead code: a route nothing calls, an unused import, a helper
that only its own recursion used, and a function written for a provider that
was rejected and deleted. The sports source also asked its API twice for one
row, against a rate-limited free tier.
CouchElephant 1.3.1
Fixed
-
Upgrading to 1.3.0 announced bookings that had already been announced.
1.3.0 re-keys existing bookings onto the new airing id. The alert state is
keyed on that same id, and it was not re-keyed with them, so the next
dispatch read a booking nobody had heard about and said so again. Seen on a
live install: two recordings booked days earlier were announced a second time
at the moment of the upgrade.The whole rule
notify_stateruns on is that a row exists means this
destination has been told, and the migration broke the key that rule depends
on. Both are now re-keyed together, state first.Nothing was booked twice and no recording was affected. Only the messages
were duplicated.
CouchElephant 1.3.0
A cleanup review of sync.py and passes.py found the cause under four fixes
that shipped this week, two silences, and two bugs nobody had reached yet.
Fixed
-
A broadcast's id is now minted from the broadcast. It used to prefer
Plex's ownMedia.id, which is the one value in the payload that moves: a
guide refresh renumbers airings without changing anything about them, and one
game here collected nine ids over three weeks. Every lookup keyed on the id
had to be taught to resolve a retired one, and four of them were taught one at
a time, each after failing in front of somebody.An id is now the programme, the channel and the start time. A renumber
produces the same id. A re-time still changes it, which is correct: that is a
different broadcast and the app has to notice. Bookings made before this are
re-keyed when the app starts.Two more places had the same fault and nobody had reached them. The guide's
"Being recorded" filter stopped matching a booked game after a refresh, and
cancelling a recording by hand answered "CouchElephant did not schedule this"
for a recording CouchElephant had scheduled. -
A re-point that Plex refused was counted and never mentioned. It
incremented the failure count without adding to the list the notices are
built from, so nothing was raised. That is the silence this whole check
exists to remove. -
A booking could be trapped in a permanent failure. Plex was asked about
the subscription before our own guide was consulted, so a booking whose
subscription Plex had lost and whose broadcast had left the guide went to the
re-book path. There is nothing to re-book from, so it failed and raised a
notice on every sync, for ever, while the branch that exists to cancel
exactly that booking was unreachable for it. -
A repaired booking's history row could name two broadcasts at once,
recording the old airing id beside the new channel and start time.
Changed
- One re-book path instead of two. They had already disagreed about when to
forget the old booking and whether to write down a failure. - Guide and schedule pulls share one prune helper rather than two copies.
- The booking check counts in one place, so a new outcome cannot be counted in
one half and forgotten in the other.
Performance
Measured against the live install: about 16,700 programmes and 22,800 airings
per sync, hourly.
- A channel is written once per sync instead of once per broadcast: about
22,700 redundant writes and the same number of redundant title parses, gone. - Two indexes on
plex_grabs, which holds the whole DVR schedule and was
scanned in full by three hot questions, one of them once per airing of a
programme. - Asking whether a team pass matches anything now stops at the first match
instead of hydrating every match in the window. - Re-pointing a booking asks for one programme in SQL rather than the pass's
whole thirty-day window, and reads the pass rows once per check rather than
once per booking. - A pass run reads the last sync time once rather than once per game.
CouchElephant 1.2.12
Fixed
-
Clicking a recording could open a panel reading "not found". A booking
stores the airing id it was made against, and the schedule row carried that
id straight through. A guide refresh mints new ids for broadcasts that have
not changed at all, so the stored one retires and the row points at nothing.
The recording was perfectly fine; only the link was stale, and refreshing the
page did not help because the row was rebuilt from the same stored id.A row now names the broadcast the guide holds now. A broadcast that really
has gone says so in words, rather than "not found", because that reads as a
broken page and the usual cause is not a broken page.
CouchElephant 1.2.11
Changed
-
A settings change is now made on the recording Plex already holds, so it
has no deadline. Changing a pass used to cancel each recording it had
booked and make it again, even to move one number. That has a moment in the
middle with nothing scheduled, so it was refused within two sync intervals of
the broadcast. The result was that the padding could not be corrected at the
one time somebody usually notices it is wrong, which is shortly before the
game.Plex takes a partial update on a subscription that exists:
PUT /media/subscriptions/<key>with the settings to change. The pin is
untouched and the scheduled recording survives, verified against a live
server. Only the settings that actually differ are sent, and they can only be
settings the server itself reported, so nothing here can send a setting the
booking will not take.Booking again is still what happens when the guide has moved the broadcast
under a booking, when Plex has lost the subscription, or when it has
scheduled nothing against it. Those keep the timing guard, because they are
the ones with a gap. An edit that somehow leaves nothing scheduled falls back
to booking again as well.
CouchElephant 1.2.10
Fixed
-
A booking stopped being checked the first time Plex renumbered its guide.
A guide refresh mints new airing ids for broadcasts that have not changed at
all: same channel, same time, new id. One game here collected nine ids over
three weeks. A booking was read only by the id it had stored, so after a
renumber it was quietly skipped, and every later change to its pass missed it
with nothing said. Found on a live DVR with one of two recordings already in
that state.A booking is now looked up by its id first and by the broadcast it was made
against second, and a repair re-books from whichever id the guide holds now.
CouchElephant 1.2.9
Fixed
-
Changing a pass did not change the recordings it had already booked.
Saving a pass booked any new games and stopped there, so a recording already
on the DVR kept the settings it was made with until the next sync, up to an
hour later. The page said one thing and the DVR did another, and a game
inside that hour was never corrected at all: by then it is too close to
kickoff to re-book safely.The booking check now runs when a pass is saved as well as on every sync. It
refreshes the copy of Plex's schedule first, so a recording booked minutes
ago is not read as one Plex has scheduled nothing for and cancelled. The
reply says how many existing recordings were updated, and how many were left
alone for being too close to their broadcast.The pass is saved whatever Plex is doing. A server unreachable for a moment
never fails the save, and the next sync carries the change.
CouchElephant 1.2.8
Changed
- The Notifications page says what a relay is for, and the documentation
screenshots show one. A destination nobody can tell apart from the others is
a destination nobody picks.
CouchElephant 1.2.7
Added
-
A relay on your own network as an alert destination, speaking timmyd's
/notify. It is the only destination that names no channel. It is handed the
severity and decides for itself, so a fault lands in the channel you watch
while a recording that started, a pass that booked something, or a fault that
cleared lands in the one you read later. Nothing is configured twice and this
end never learns which channels exist.The address is checked as an ordinary http or https address with a host and no
credentials in it, and deliberately not against a host allowlist: a relay is a
service you run, usually on the same network as this container, so there is
nothing to pin it to. Plain http is allowed for the same reason.The relay answers 202 once it has queued a message and 503 when its queue is
full, both withokin the body. Queued is not delivered, and it is the
strongest thing a relay can honestly say, but a 2xx alone still proves
nothing, so the body is what is believed and a refusal is never recorded as
sent.
Changed
- A destination's address is only masked when the address is itself the
credential. A Discord webhook URL still is, so it stays masked. A relay's
address is a machine on your network, and masking it only hid which relay a
destination pointed at.
Fixed
- A subscription this app had just cancelled survived in its copy of Plex's
schedule. Our copy was pruned by timestamp, so two pulls inside one second
kept every row the first one wrote. A stale row then read as a live booking,
and a pass would skip a game nothing was recording. Both the subscription and
the grab lists are now pruned by what the pull actually saw. Same fault as the
guide prune in 1.2.6, in the other mirror.