From 107f124ee2f9270d375019de057dc0f27187c16e Mon Sep 17 00:00:00 2001 From: Simon Date: Mon, 26 Jan 2026 22:35:30 +0700 Subject: [PATCH 1/7] add membership socket connection status --- backend/appsettings/serializers_mb.py | 1 + .../src/components/MembershipAppsettings.tsx | 21 +++++++++++++++++++ 2 files changed, 22 insertions(+) diff --git a/backend/appsettings/serializers_mb.py b/backend/appsettings/serializers_mb.py index 18bbba4f..330fc96d 100644 --- a/backend/appsettings/serializers_mb.py +++ b/backend/appsettings/serializers_mb.py @@ -29,3 +29,4 @@ class MembershipProfileSerializer(serializers.Serializer): sponsor_tier = SponsortierSerializer() subscription_count = serializers.IntegerField() subscription_is_max = serializers.BooleanField() + is_connected = serializers.BooleanField() diff --git a/frontend/src/components/MembershipAppsettings.tsx b/frontend/src/components/MembershipAppsettings.tsx index 9474c689..d2899da0 100644 --- a/frontend/src/components/MembershipAppsettings.tsx +++ b/frontend/src/components/MembershipAppsettings.tsx @@ -24,6 +24,7 @@ type ProfileResponseType = { sponsor_tier: SponsorTierType; subscription_count: number; subscription_is_max: boolean; + is_connected: boolean; }; export default function MembershipAppsettings({ show_help_text }: { show_help_text: boolean }) { @@ -136,6 +137,13 @@ export default function MembershipAppsettings({ show_help_text }: { show_help_te .
  • Click on validate to verify everything is working.
  • +
  • + Setup the{' '} + + Client Container + + . +
  • If you are subscribed to less channels than your sponsor tier allows, you can directly sync all your subscriptions here. @@ -206,6 +214,19 @@ export default function MembershipAppsettings({ show_help_text }: { show_help_te
    Subscriptions: {profileResponse.subscription_count}/ {profileResponse.sponsor_tier.max_subs} +
    + Socket:{' '} + {profileResponse.is_connected ? ( + 'Established' + ) : ( + <> + Not established. Make sure the{' '} + + Client Container + {' '} + is connected. + + )}

    )} From d7ba4bc9241c986f78ea4b276c7df016883f01fb Mon Sep 17 00:00:00 2001 From: Simon Date: Fri, 30 Jan 2026 17:25:44 +0700 Subject: [PATCH 2/7] update yt-dlp --- backend/requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/requirements.txt b/backend/requirements.txt index 6408e29f..6f73909b 100644 --- a/backend/requirements.txt +++ b/backend/requirements.txt @@ -13,4 +13,4 @@ redis==7.1.0 requests==2.32.5 ryd-client==0.0.6 uvicorn==0.40.0 -yt-dlp[default] @ git+https://github.com/yt-dlp/yt-dlp@23b846506378a6a9c9a0958382d37f943f7cfa51 +yt-dlp[default]==2026.1.29 From 9badd3b0732f217704c887ba5be868211e2bb0f1 Mon Sep 17 00:00:00 2001 From: Simon Date: Fri, 30 Jan 2026 17:43:03 +0700 Subject: [PATCH 3/7] add timeout overwrite in es get, extend in zip backups --- backend/appsettings/src/backup.py | 3 ++- backend/common/src/es_connect.py | 7 ++++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/backend/appsettings/src/backup.py b/backend/appsettings/src/backup.py index 702acd99..c4569196 100644 --- a/backend/appsettings/src/backup.py +++ b/backend/appsettings/src/backup.py @@ -21,7 +21,7 @@ class ElasticBackup: """dump index to nd-json files for later bulk import""" INDEX_SIZE_CONF = { - "comment": 200, + "comment": 100, "subtitle": 10000, } CACHE_DIR = EnvironmentSettings.CACHE_DIR @@ -64,6 +64,7 @@ class ElasticBackup: "callback": BackupCallback, "task": self.task, "total": self._get_total(index_name), + "timeout": 30, } if size_overwrite := self.INDEX_SIZE_CONF.get(index_name): diff --git a/backend/common/src/es_connect.py b/backend/common/src/es_connect.py index ecd46661..6638ffc8 100644 --- a/backend/common/src/es_connect.py +++ b/backend/common/src/es_connect.py @@ -148,6 +148,7 @@ class IndexPaginate: - callback: obj, Class implementing run method callback for every loop - task: task object to send notification - total: int, total items in index for progress message + - timeout: int, overwrite timeout in get request """ DEFAULT_SIZE = 500 @@ -191,7 +192,11 @@ class IndexPaginate: all_results = [] counter = 0 while True: - response, _ = ElasticWrap("_search").get(data=self.data) + get_kwargs = {"data": self.data} + if timeout_overwrite := self.kwargs.get("timeout"): + get_kwargs.update({"timeout": timeout_overwrite}) + + response, _ = ElasticWrap("_search").get(**get_kwargs) all_hits = response["hits"]["hits"] if not all_hits: break From 5f593ada731c1a785d5c6318c6b7d5b3ea9a5a13 Mon Sep 17 00:00:00 2001 From: Simon Date: Fri, 30 Jan 2026 17:46:05 +0700 Subject: [PATCH 4/7] fix nested update query in artwork migration --- backend/config/management/commands/ta_startup.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/backend/config/management/commands/ta_startup.py b/backend/config/management/commands/ta_startup.py index dc5e8aa2..57b1691e 100644 --- a/backend/config/management/commands/ta_startup.py +++ b/backend/config/management/commands/ta_startup.py @@ -376,14 +376,15 @@ class Command(BaseCommand): "lang": "painless", }, ) + source = f""" + if (ctx._source.containsKey('channel')) + {{ctx._source.channel.remove('{field}');}} + """ self._run_migration( index_name="ta_video", desc=f"fix missing data type for field channel.{field}", query={"term": {f"channel.{field}": {"value": False}}}, - script={ - "source": f"ctx._source.remove('channel.{field}')", - "lang": "painless", - }, + script={"source": source, "lang": "painless"}, ) def _mig_fix_channel_description(self) -> None: From e667591af89b1021045a2aa4ca167fddd6c4a505 Mon Sep 17 00:00:00 2001 From: Simon Date: Fri, 30 Jan 2026 19:25:56 +0700 Subject: [PATCH 5/7] handle pot plugin noop --- backend/download/src/yt_dlp_base.py | 11 +++++++++++ backend/requirements.txt | 2 +- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/backend/download/src/yt_dlp_base.py b/backend/download/src/yt_dlp_base.py index 212401d2..383d9166 100644 --- a/backend/download/src/yt_dlp_base.py +++ b/backend/download/src/yt_dlp_base.py @@ -89,6 +89,17 @@ class YtWrap: } }, ) + return + + # https://github.com/Brainicism/bgutil-ytdlp-pot-provider/pull/185 + deep_merge( + self.obs, + { + "extractor_args": { + "youtubepot-bgutilhttp": {"disable": ["True"]} + } + }, + ) def download(self, url): """make download request""" diff --git a/backend/requirements.txt b/backend/requirements.txt index 6f73909b..5bde3ac0 100644 --- a/backend/requirements.txt +++ b/backend/requirements.txt @@ -1,5 +1,5 @@ apprise==1.9.7 -bgutil-ytdlp-pot-provider==1.2.2 +bgutil-ytdlp-pot-provider @ git+https://github.com/bbilly1/bgutil-ytdlp-pot-provider@c3f7bf4c99f8eb62015cb1c4142324f3d681cf07#subdirectory=plugin celery==5.6.2 deepdiff==8.6.1 django-auth-ldap==5.3.0 From ff26c4c713f07b580b0eed7ff0c13b8058559d70 Mon Sep 17 00:00:00 2001 From: Simon Date: Fri, 30 Jan 2026 19:36:15 +0700 Subject: [PATCH 6/7] add a note about dev env contributions --- CONTRIBUTING.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index d9311fd8..ea60d380 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -134,6 +134,7 @@ The documentation available at [docs.tubearchivist.com](https://docs.tubearchivi This codebase is set up to be developed natively outside of docker as well as in a docker container. Developing outside of a docker container can be convenient, as IDE and hot reload usually works out of the box. But testing inside of a container is still essential, as there are subtle differences, especially when working with the filesystem and networking between containers. Note: +- This project doesn't look for contributions to this to cover additional dev setup environments from new contributors. If you are a regular contributor and you see ways to improve this, please reach out on Discord first. - Subtitles currently fail to load with `DJANGO_DEBUG=True`, that is due to incorrect `Content-Type` error set by Django's static file implementation. That's only if you run the Django dev server, Nginx sets the correct headers in the container. ### Native Instruction From 67b0bf333918e60f0473986d9bdc30c1f8d645c8 Mon Sep 17 00:00:00 2001 From: Isaac Sanders <651597+isaacsanders@users.noreply.github.com> Date: Fri, 30 Jan 2026 06:37:41 -0600 Subject: [PATCH 7/7] fix: Handles floats in more places (#1110) --- backend/common/src/helper.py | 4 +++- backend/common/tests/test_src/test_helper.py | 7 +++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/backend/common/src/helper.py b/backend/common/src/helper.py index 0bb43aca..c6f0f06c 100644 --- a/backend/common/src/helper.py +++ b/backend/common/src/helper.py @@ -103,13 +103,15 @@ def requests_headers() -> dict[str, str]: return {"User-Agent": template} -def date_parser(timestamp: int | str | None) -> str | None: +def date_parser(timestamp: int | float | str | None) -> str | None: """return formatted date string""" if timestamp is None: return None if isinstance(timestamp, int): date_obj = datetime.fromtimestamp(timestamp, tz=timezone.utc) + elif isinstance(timestamp, float): + date_obj = datetime.fromtimestamp(int(timestamp), tz=timezone.utc) elif isinstance(timestamp, str) and timestamp.isdigit(): date_obj = datetime.fromtimestamp(int(timestamp), tz=timezone.utc) elif isinstance(timestamp, str): diff --git a/backend/common/tests/test_src/test_helper.py b/backend/common/tests/test_src/test_helper.py index 73578a76..acc81e46 100644 --- a/backend/common/tests/test_src/test_helper.py +++ b/backend/common/tests/test_src/test_helper.py @@ -33,6 +33,13 @@ def test_date_parser_with_digit(): assert date_parser(timestamp) == expected_date +def test_date_parser_with_float(): + """iso timestamp""" + date_float = 1766210400.0 + expected_date = "2025-12-20T06:00:00+00:00" + assert date_parser(date_float) == expected_date + + def test_date_parser_with_str(): """iso timestamp""" date_str = "2021-05-21"