SergeantPanda
96ff3776ac
Merge pull request #1051 from Dispatcharr:ts-proxy-stream-generator-improvements
...
Enhance Redis chunk management in StreamBuffer and StreamGenerator
2026-03-03 16:00:21 -06:00
SergeantPanda
24c20a2f4a
changelog: Update changelog for proxy changes.
2026-03-03 15:59:49 -06:00
SergeantPanda
0ee8864c06
Merge branch 'dev' of https://github.com/Dispatcharr/Dispatcharr into ts-proxy-stream-generator-improvements
2026-03-03 15:43:56 -06:00
SergeantPanda
b9bfb9f673
Merge pull request #1050 from Dispatcharr/revert-1026-fix-modular-worker-trigger-issue
...
Revert "fix(wsgi): ensure gevent monkey-patching before Django import chain"
2026-03-03 15:34:14 -06:00
SergeantPanda
d487bb5671
Revert "fix(wsgi): ensure gevent monkey-patching before Django import chain"
2026-03-03 15:33:55 -06:00
SergeantPanda
e78c24aad7
Enhance Redis chunk management in StreamBuffer and StreamGenerator
...
- Register Lua scripts for optimized chunk retrieval in StreamBuffer.
- Implement atomic Lua binary search to find the oldest available chunk in Redis.
- Update StreamGenerator to handle expired chunks more efficiently, reducing TOCTOU race conditions.
2026-03-03 15:13:46 -06:00
SergeantPanda
7da7ba97a9
Merge pull request #1026 from endoze/fix-modular-worker-trigger-issue
...
fix(wsgi): ensure gevent monkey-patching before Django import chain
2026-03-03 12:02:07 -06:00
SergeantPanda
dcb3cf8ea8
changelog: Update changelog for monkey patch PR.
2026-03-03 11:56:06 -06:00
SergeantPanda
a8ba2ade18
Merge branch 'dev' of https://github.com/Dispatcharr/Dispatcharr into pr/endoze/1026
2026-03-03 11:52:12 -06:00
SergeantPanda
0db177b937
Merge pull request #1035 from PFalko:fix/stream-ownership-bugs
...
Fix stream ownership bugs causing streams to die after 30-200s
2026-03-03 11:13:55 -06:00
SergeantPanda
d6e4a34f3b
changelog: Update changelog for proxy server pr.
2026-03-03 11:11:50 -06:00
SergeantPanda
cd9d8d5d2a
Merge branch 'dev' of https://github.com/Dispatcharr/Dispatcharr into pr/PFalko/1035
2026-03-03 11:07:10 -06:00
SergeantPanda
6d7130d71e
Bug Fix: fix get_instance deadlock and non-atomic ownership acquisition
...
If ProxyServer() raises during singleton construction, _instance was left
as _INITIALIZING permanently, causing all subsequent get_instance() callers
to spin in an infinite gevent.sleep() loop. Wrap construction in try/except
and reset _instance to None on failure so callers can retry.
Also replace the non-atomic setnx() + expire() pair in try_acquire_ownership()
with a single atomic SET NX EX call, consistent with the approach already used
in extend_ownership() and eliminating the race window where a crash between the
two calls could leave a key with no TTL (permanent ownership lock).
2026-03-03 11:06:52 -06:00
SergeantPanda
6ff62698a2
Merge pull request #1027 from JCBird1012/main
...
feat: filter channels that contain stale streams
2026-03-03 10:29:58 -06:00
SergeantPanda
eb02072431
Renamed "partially-stale-streams-row" to "has-stale-streams-row" for accuracy. Also updated the changelog.
2026-03-03 10:20:37 -06:00
SergeantPanda
1e629d57ec
Refactor ChannelsTable row styling logic to use memoized class mapping for improved performance and readability.
2026-03-03 10:11:45 -06:00
SergeantPanda
c005a48162
Merge branch 'dev' of https://github.com/Dispatcharr/Dispatcharr into pr/JCBird1012/1027
2026-03-03 09:15:31 -06:00
GitHub Actions
24c2fad138
Release v0.20.2
CI Pipeline / prepare (push) Waiting to run
CI Pipeline / docker (amd64, ubuntu-24.04) (push) Blocked by required conditions
CI Pipeline / docker (arm64, ubuntu-24.04-arm) (push) Blocked by required conditions
CI Pipeline / create-manifest (push) Blocked by required conditions
Build and Push Multi-Arch Docker Image / build-and-push (push) Has been cancelled
Frontend Tests / test (push) Has been cancelled
2026-03-03 01:37:58 +00:00
SergeantPanda
cedda3695f
Merge pull request #1048 from Dispatcharr/dev
...
Dispatcharr - v0.20.2
2026-03-02 19:37:28 -06:00
SergeantPanda
7d95e3ceb4
Security: Updated frontend npm dependencies to resolve 2 high-severity vulnerabilities:
...
CI Pipeline / prepare (push) Waiting to run
CI Pipeline / docker (amd64, ubuntu-24.04) (push) Blocked by required conditions
CI Pipeline / docker (arm64, ubuntu-24.04-arm) (push) Blocked by required conditions
CI Pipeline / create-manifest (push) Blocked by required conditions
Build and Push Multi-Arch Docker Image / build-and-push (push) Waiting to run
Frontend Tests / test (push) Has been cancelled
- Updated `minimatch` to ≥10.2.3, resolving **high** ReDoS via matchOne() combinatorial backtracking with multiple non-adjacent GLOBSTAR segments ([GHSA-7r86-cg39-jmmj](https://github.com/advisories/GHSA-7r86-cg39-jmmj ))
- Updated `rollup` to ≥4.58.1, resolving **high** Arbitrary File Write via Path Traversal ([GHSA-mw96-cpmx-2vgc](https://github.com/advisories/GHSA-mw96-cpmx-2vgc ))
2026-03-02 17:36:40 -06:00
SergeantPanda
b098deae76
Got rid of extra api call to query if any channels had no EPG assigned. Moved query to an EXISTS lookup during channel query.
2026-03-02 17:20:55 -06:00
Claude Code
7fed49a334
Address review feedback from CodeBormen
...
- Use atomic SET NX EX instead of separate SETNX + EXPIRE to prevent
zombie locks if the process crashes between the two calls
- Replace time.sleep() with gevent.sleep() in get_instance() spin-wait
to avoid blocking the greenlet hub
- Defer cleanup when ownership is lost but clients are still connected,
giving the new owner time to establish its stream before we tear down
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-02 13:23:45 +00:00
SergeantPanda
565d335403
Bug Fix: The EPG filter dropdown was showing all EPG sources regardless of whether they had any channels assigned, and the "No EPG" option was never displayed. Fixed by annotating EPGSource records with a has_channels flag (via a lightweight EXISTS subquery) so only EPG sources actually in use appear as filter options. "No EPG" now appears only when at least one channel has no EPG assigned, determined via a page_size=1 query against the existing channel filter endpoint.
CI Pipeline / prepare (push) Waiting to run
CI Pipeline / docker (amd64, ubuntu-24.04) (push) Blocked by required conditions
CI Pipeline / docker (arm64, ubuntu-24.04-arm) (push) Blocked by required conditions
CI Pipeline / create-manifest (push) Blocked by required conditions
Build and Push Multi-Arch Docker Image / build-and-push (push) Waiting to run
Frontend Tests / test (push) Waiting to run
2026-03-01 16:54:05 -06:00
Jonathan Caicedo
4dfe172fc4
tweak: label name + CSS class name
2026-02-28 12:30:39 -05:00
Jonathan Caicedo
31fb27dffc
perf: avoid double-calling row.original.streams - reuse hasStreams
...
This is a micro-optimization, but prevents checking row.original.streams twice and also guards checking for stale streams unless we know we have streams. The performance hit before would have been tiny, but every bit counts.
2026-02-28 12:30:28 -05:00
Jonathan Caicedo
a318d919d8
feat: filter channels that contain stale streams
...
closes : #1025
2026-02-28 12:30:21 -05:00
Marcin Olek
a73af3fad5
fix: debian_install build
...
Build and Push Multi-Arch Docker Image / build-and-push (push) Has been cancelled
optimise
2026-02-27 22:35:39 -06:00
SergeantPanda
4a38c16dd2
changelog: debian_install fixes.
CI Pipeline / prepare (push) Has been cancelled
Build and Push Multi-Arch Docker Image / build-and-push (push) Has been cancelled
Frontend Tests / test (push) Has been cancelled
CI Pipeline / docker (amd64, ubuntu-24.04) (push) Has been cancelled
CI Pipeline / docker (arm64, ubuntu-24.04-arm) (push) Has been cancelled
CI Pipeline / create-manifest (push) Has been cancelled
2026-02-27 22:34:04 -06:00
SergeantPanda
ac28d05dbe
Merge pull request #1037 from marcinolek/main
...
fix: debian_install.sh regression after uv migration (pip-less venv + missing gunicorn)
2026-02-27 22:27:26 -06:00
Marcin Olek
83b56a7429
fix: debian_install build
...
optimise
2026-02-28 00:10:28 +01:00
SergeantPanda
cdef94fde4
Bug Fix: Stale streams in the streams table had no hover color change, unlike channels with no streams assigned. Converted the inline backgroundColor style to a CSS class (stale-stream-row) so the :hover rule can apply correctly. Applied the same fix to the channel-streams sub-table, where the teal expanded-row background caused the semi-transparent red tint to visually mismatch; the sub-table now uses a pre-blended solid color via color-mix() to match the appearance of stale rows in the main streams table.
2026-02-27 16:28:06 -06:00
SergeantPanda
03c4ffb4e5
Bug Fix: Applying any filter that temporarily empties the channel list (e.g. switching directly between two channel groups, or typing a search query that matches nothing) caused the guide to show a blank/empty view with no programs visible. The VariableSizeList unmounts when filteredChannels becomes empty, destroying its DOM node and resetting scrollLeft to 0. On remount the scroll position was never restored because initialScrollComplete was still true. Fixed by saving the user's current scroll position when the channel list empties mid-transition, then restoring it once new channels have loaded. On first load the guide still scrolls to the current time as before.
CI Pipeline / prepare (push) Waiting to run
CI Pipeline / docker (amd64, ubuntu-24.04) (push) Blocked by required conditions
CI Pipeline / docker (arm64, ubuntu-24.04-arm) (push) Blocked by required conditions
CI Pipeline / create-manifest (push) Blocked by required conditions
Build and Push Multi-Arch Docker Image / build-and-push (push) Waiting to run
Frontend Tests / test (push) Waiting to run
2026-02-27 15:47:09 -06:00
PFalko
8bd38ad71c
Fix stream ownership bugs causing streams to die after 30-200s
...
Three interrelated bugs cause TS proxy streams to terminate prematurely
in multi-worker uWSGI deployments:
1. Double ProxyServer instantiation: ProxyConfig.ready() in apps/proxy/apps.py
calls TSProxyServer() directly, bypassing get_instance(). The subsequent
TSProxyConfig.ready() call to get_instance() creates a second instance.
Each instance starts its own cleanup thread, but only one holds channel
data — the orphaned cleanup thread cannot extend ownership.
2. Redis flushdb() on every client init: RedisClient.get_client() in
core/utils.py calls flushdb() whenever a new connection is created.
Celery autoscale workers spawning mid-stream nuke all Redis keys
including ownership, client records, and channel metadata.
3. No recovery from expired ownership: get_channel_owner() has a TOCTOU
bug (two separate GET calls in a lambda). extend_ownership() silently
fails when keys expire. Non-owner cleanup unconditionally kills streams
even when the worker holds the stream_manager.
Fixes:
- Use TSProxyServer.get_instance() in ProxyConfig.ready()
- Remove flushdb() from Redis client initialization
- Use sentinel pattern for gevent-safe singleton (threading.Lock does not
work with gevent greenlets)
- Single GET in get_channel_owner() to avoid TOCTOU race
- Re-acquire expired ownership keys in extend_ownership()
- Attempt re-acquisition before cleanup in non-owner path
Relates to #992 , #980
2026-02-27 16:40:28 +01:00
SergeantPanda
8eb24cb945
Bug Fix: The channel store refactor changed to loading only channel IDs instead of full channel objects, leaving Object.keys(channels).length always 0 and incorrectly triggering the onboarding state on any empty filter. Fixed by checking channelIds.length instead.
CI Pipeline / prepare (push) Waiting to run
CI Pipeline / docker (amd64, ubuntu-24.04) (push) Blocked by required conditions
CI Pipeline / docker (arm64, ubuntu-24.04-arm) (push) Blocked by required conditions
CI Pipeline / create-manifest (push) Blocked by required conditions
Build and Push Multi-Arch Docker Image / build-and-push (push) Waiting to run
Frontend Tests / test (push) Waiting to run
2026-02-26 16:38:09 -06:00
GitHub Actions
cb3402147e
Release v0.20.1
Build and Push Multi-Arch Docker Image / build-and-push (push) Has been cancelled
Frontend Tests / test (push) Has been cancelled
2026-02-26 21:35:42 +00:00
SergeantPanda
622c22bac7
Merge pull request #1030 from Dispatcharr/dev
...
Bug fix: Login form disabled after token expiry:
2026-02-26 15:35:11 -06:00
SergeantPanda
94fc91f5e3
Bug fix: Login form disabled after token expiry: The login button was permanently rendered as disabled ("Logging you in...") on page load after a session expired, preventing users from logging back in. A regression in v0.20.0 caused LoginForm to check if (user) to detect an already-authenticated reload, but the Zustand auth store initializes user as a truthy empty object { username: '', email: '', user_level: '' }, so the loading state was set immediately on every mount. Reverted to pre-regression behavior. ( Fixes #1029 )
CI Pipeline / prepare (push) Waiting to run
CI Pipeline / docker (amd64, ubuntu-24.04) (push) Blocked by required conditions
CI Pipeline / docker (arm64, ubuntu-24.04-arm) (push) Blocked by required conditions
CI Pipeline / create-manifest (push) Blocked by required conditions
Build and Push Multi-Arch Docker Image / build-and-push (push) Waiting to run
Frontend Tests / test (push) Waiting to run
2026-02-26 15:27:35 -06:00
GitHub Actions
a26a42f2d4
Release v0.20.0
Build and Push Multi-Arch Docker Image / build-and-push (push) Waiting to run
Frontend Tests / test (push) Waiting to run
2026-02-26 20:09:34 +00:00
SergeantPanda
393bfd384c
Merge pull request #1028 from Dispatcharr/dev
...
Dispatcharr - v0.20.0
2026-02-26 14:05:41 -06:00
SergeantPanda
abba65816b
Migrations: Add missing migrations.
2026-02-26 13:25:51 -06:00
SergeantPanda
eae38ff931
changelog: Update changelog for changes to integrations.
2026-02-26 13:23:46 -06:00
SergeantPanda
216575a411
Merge pull request #1020 from Dispatcharr/enhanced-webhooks
...
enhanced webhooks to support custom headers and payload templates
2026-02-26 13:14:24 -06:00
dekzter
fc3c21e16a
revert settings / system
2026-02-26 14:12:51 -05:00
dekzter
dfe5ec6e94
updated template with example jinja
2026-02-26 14:08:01 -05:00
dekzter
d5349dcf4f
create scripts directory
2026-02-26 14:07:34 -05:00
SergeantPanda
60c165f422
Enhancement: Stats page "Now Playing" EPG lookup updated to use channel_uuids directly (the proxy stats already key active channels by UUID), removing the need for a UUID→integer ID conversion step introduced alongside the lazy channel-fetch refactor. Stream preview sessions (which use a content hash rather than a UUID as their channel ID) are now filtered out before any API call is made, preventing a backend ValidationError on both the current-programs and by-uuids endpoints when a stream preview is active on the Stats page.
2026-02-26 12:00:29 -06:00
Endoze
9b6c793b11
fix(wsgi): ensure gevent monkey-patching before Django import chain
...
Celery's Redis connection pool was silently failing in modular
deployment mode because Django's setup imports celery.py before uWSGI's
gevent plugin reliably patches stdlib sockets. Moving patch_all() to the
top of wsgi.py guarantees all broker connections are gevent-aware
regardless of uWSGI initialization order.
2026-02-26 10:23:50 -05:00
dekzter
b9bda67bc2
indicate on reload if login was already complete and data is loading
2026-02-25 12:52:14 -05:00
dekzter
5e93246b95
fixed swapped settings labels
2026-02-25 11:07:46 -05:00
dekzter
4d6351507f
enhanced webhooks to support custom headers and payload templates
2026-02-25 10:59:45 -05:00