diff --git a/backend/config/management/commands/ta_startup.py b/backend/config/management/commands/ta_startup.py index 3dc55e83..e80af6b7 100644 --- a/backend/config/management/commands/ta_startup.py +++ b/backend/config/management/commands/ta_startup.py @@ -55,6 +55,7 @@ class Command(BaseCommand): self._init_app_config() self._mig_channel_tags() self._mig_video_channel_tags() + self._mig_fix_download_channel_indexed() def _make_folders(self): """make expected cache folders""" @@ -347,3 +348,37 @@ class Command(BaseCommand): self.stdout.write(response) sleep(60) raise CommandError(message) + + def _mig_fix_download_channel_indexed(self) -> None: + """migrate from v0.5.2 to 0.5.3, fix missing channel_indexed""" + self.stdout.write("[MIGRATION] fix incorrect video channel tags types") + path = "ta_download/_update_by_query" + data = { + "query": { + "bool": { + "must_not": [{"exists": {"field": "channel_indexed"}}] + } + }, + "script": { + "source": "ctx._source.channel_indexed = false", + "lang": "painless", + }, + } + response, status_code = ElasticWrap(path).post(data) + if status_code in [200, 201]: + updated = response.get("updated") + if updated: + self.stdout.write( + self.style.SUCCESS(f" ✓ fixed {updated} queued videos") + ) + else: + self.stdout.write( + self.style.SUCCESS(" no queued videos to fix") + ) + return + + message = " 🗙 failed to fix video channel tags" + self.stdout.write(self.style.ERROR(message)) + self.stdout.write(response) + sleep(60) + raise CommandError(message) diff --git a/backend/config/settings.py b/backend/config/settings.py index 3ffb6afd..5b51647e 100644 --- a/backend/config/settings.py +++ b/backend/config/settings.py @@ -294,7 +294,7 @@ CORS_ALLOW_HEADERS = list(default_headers) + [ # TA application settings TA_UPSTREAM = "https://github.com/tubearchivist/tubearchivist" -TA_VERSION = "v0.5.2" +TA_VERSION = "v0.5.3-unstable" # API REST_FRAMEWORK = { diff --git a/backend/download/src/queue.py b/backend/download/src/queue.py index e4238c18..eae697d5 100644 --- a/backend/download/src/queue.py +++ b/backend/download/src/queue.py @@ -344,11 +344,8 @@ class PendingList(PendingIndex): "duration": get_duration_str(vid["duration"]), "published": published, "timestamp": int(datetime.now().timestamp()), - # Pulling enum value out so it is serializable "vid_type": vid_type.value, + "channel_indexed": vid["channel_id"] in self.all_channels, } - if self.all_channels: - youtube_details.update( - {"channel_indexed": vid["channel_id"] in self.all_channels} - ) + return youtube_details diff --git a/backend/requirements-dev.txt b/backend/requirements-dev.txt index d7f785a9..871caba6 100644 --- a/backend/requirements-dev.txt +++ b/backend/requirements-dev.txt @@ -7,4 +7,4 @@ pytest-django==4.11.1 pytest==8.3.5 python-dotenv==1.1.0 requirementscheck==0.0.6 -types-requests==2.32.0.20250328 +types-requests==2.32.0.20250515 diff --git a/backend/requirements.txt b/backend/requirements.txt index 2d98106d..0edecd4c 100644 --- a/backend/requirements.txt +++ b/backend/requirements.txt @@ -7,9 +7,9 @@ Django==5.2.1 djangorestframework==3.16.0 drf-spectacular==0.28.0 Pillow==11.2.1 -redis==6.0.0 +redis==6.1.0 requests==2.32.3 ryd-client==0.0.6 uvicorn==0.34.2 whitenoise==6.9.0 -yt-dlp[default]==2025.4.30 +yt-dlp[default]==2025.5.22 diff --git a/frontend/src/pages/SettingsScheduling.tsx b/frontend/src/pages/SettingsScheduling.tsx index b56f7697..b2d064b5 100644 --- a/frontend/src/pages/SettingsScheduling.tsx +++ b/frontend/src/pages/SettingsScheduling.tsx @@ -15,6 +15,32 @@ import createAppriseNotificationUrl, { import deleteAppriseNotificationUrl from '../api/actions/deleteAppriseNotificationUrl'; import { ApiError, ApiResponseType } from '../functions/APIClient'; +const getGroupedSchedule = ( + scheduleResponse: ApiResponseType | undefined, +) => { + const { data: scheduleResponseData } = scheduleResponse ?? {}; + + const groupedSchedules = Object.groupBy(scheduleResponseData || [], ({ name }) => name); + + const { update_subscribed, download_pending, run_backup, check_reindex, thumbnail_check } = + groupedSchedules; + + const updateSubscribedSchedule = update_subscribed?.pop(); + const downloadPendingSchedule = download_pending?.pop(); + const runBackup = run_backup?.pop(); + const checkReindexSchedule = check_reindex?.pop(); + const thumbnailCheckSchedule = thumbnail_check?.pop(); + + return { + updateSubscribedSchedule, + downloadPendingSchedule, + runBackup, + checkReindexSchedule, + thumbnailCheckSchedule, + download_pending, + }; +}; + const SettingsScheduling = () => { const [refresh, setRefresh] = useState(false); @@ -37,7 +63,6 @@ const SettingsScheduling = () => { const [thumnailCheckError, setThumnailCheckError] = useState(null); const [zipBackupError, setZipBackupError] = useState(null); - const { data: scheduleResponseData } = scheduleResponse ?? {}; const { data: appriseNotificationData } = appriseNotification ?? {}; useEffect(() => { @@ -49,6 +74,22 @@ const SettingsScheduling = () => { setScheduleResponse(scheduleResponse); setAppriseNotification(appriseNotificationResponse); + const { + checkReindexSchedule, + downloadPendingSchedule, + runBackup, + thumbnailCheckSchedule, + updateSubscribedSchedule, + } = getGroupedSchedule(scheduleResponse); + + setUpdateSubscribed(updateSubscribedSchedule?.schedule || ''); + setDownloadPending(downloadPendingSchedule?.schedule || ''); + setCheckReindex(checkReindexSchedule?.schedule || ''); + setCheckReindexDays(checkReindexSchedule?.config?.days || 0); + setThumbnailCheck(thumbnailCheckSchedule?.schedule || ''); + setZipBackup(runBackup?.schedule || ''); + setZipBackupDays(runBackup?.config?.rotate || 0); + setRefresh(false); } })(); @@ -58,18 +99,14 @@ const SettingsScheduling = () => { setRefresh(true); }, []); - const groupedSchedules = Object.groupBy(scheduleResponseData || [], ({ name }) => name); - - console.log(groupedSchedules); - - const { update_subscribed, download_pending, run_backup, check_reindex, thumbnail_check } = - groupedSchedules; - - const updateSubscribedSchedule = update_subscribed?.pop(); - const downloadPendingSchedule = download_pending?.pop(); - const runBackup = run_backup?.pop(); - const checkReindexSchedule = check_reindex?.pop(); - const thumbnailCheckSchedule = thumbnail_check?.pop(); + const { + checkReindexSchedule, + downloadPendingSchedule, + runBackup, + thumbnailCheckSchedule, + updateSubscribedSchedule, + download_pending, + } = getGroupedSchedule(scheduleResponse); return ( <> @@ -146,7 +183,7 @@ const SettingsScheduling = () => { { setUpdateSubscribed(e.currentTarget.value); }} @@ -201,7 +238,7 @@ const SettingsScheduling = () => { { setDownloadPending(e.currentTarget.value); }} @@ -257,7 +294,7 @@ const SettingsScheduling = () => { { setCheckReindex(e.currentTarget.value); }} @@ -293,7 +330,7 @@ const SettingsScheduling = () => { { setCheckReindexDays(Number(e.currentTarget.value)); }} @@ -342,7 +379,7 @@ const SettingsScheduling = () => { { setThumbnailCheck(e.currentTarget.value); }} @@ -404,7 +441,7 @@ const SettingsScheduling = () => { { setZipBackup(e.currentTarget.value); }} @@ -440,7 +477,7 @@ const SettingsScheduling = () => { { setZipBackupDays(Number(e.currentTarget.value)); }} @@ -525,7 +562,7 @@ const SettingsScheduling = () => { { setNotificationUrl(e.currentTarget.value); }}