From 38bf6af1fc526b9b783d6c481fc6f39dbba196a9 Mon Sep 17 00:00:00 2001 From: arabcoders Date: Tue, 3 Jun 2025 22:15:06 +0300 Subject: [PATCH] Improved the testing logic for conditions filter. --- app/library/HttpAPI.py | 43 +++++--- ui/components/ConditionForm.vue | 171 ++++++++++++++++++++++++++---- ui/components/Modal.vue | 35 ++++++ ui/composables/useNotification.ts | 6 +- ui/pages/conditions.vue | 38 ------- 5 files changed, 214 insertions(+), 79 deletions(-) create mode 100644 ui/components/Modal.vue diff --git a/app/library/HttpAPI.py b/app/library/HttpAPI.py index 7d050ac3..b323f713 100644 --- a/app/library/HttpAPI.py +++ b/app/library/HttpAPI.py @@ -883,32 +883,31 @@ class HttpAPI(Common): Response: The response object """ - data = await request.json() + params = await request.json() - if not isinstance(data, dict): + if not isinstance(params, dict): return web.json_response( {"error": "Invalid request body expecting dict."}, status=web.HTTPBadRequest.status_code, ) - url = data.get("url") + url = params.get("url") if not url: return web.json_response({"error": "url is required."}, status=web.HTTPBadRequest.status_code) - cond = data.get("condition") + cond = params.get("condition") if not cond: - return web.json_response({"error": "condition name is required."}, status=web.HTTPBadRequest.status_code) + return web.json_response({"error": "condition is required."}, status=web.HTTPBadRequest.status_code) try: - opts = {} - - if ytdlp_proxy := self.config.get_ytdlp_args().get("proxy", None): - opts["proxy"] = ytdlp_proxy - - preset = data.get("preset", self.config.default_preset) - ytdlp_opts = YTDLPOpts.get_instance().preset(name=preset, with_cookies=True).add(opts).get_all() + preset = params.get("preset", self.config.default_preset) key = self.cache.hash(url + str(preset)) if not self.cache.has(key): + opts = {} + if ytdlp_proxy := self.config.get_ytdlp_args().get("proxy", None): + opts["proxy"] = ytdlp_proxy + ytdlp_opts = YTDLPOpts.get_instance().preset(name=preset, with_cookies=True).add(opts).get_all() + data = extract_info( config=ytdlp_opts, url=url, @@ -917,6 +916,11 @@ class HttpAPI(Common): follow_redirect=True, sanitize_info=True, ) + if not data: + return web.json_response( + data={"error": f"Failed to extract info from '{url!s}'."}, + status=web.HTTPBadRequest.status_code, + ) self.cache.set(key=key, value=data, ttl=600) else: data = self.cache.get(key) @@ -927,16 +931,21 @@ class HttpAPI(Common): status=web.HTTPInternalServerError.status_code, ) - matched = Conditions.get_instance().single_match(name=cond, info=data) - if matched is None: + try: + from yt_dlp.utils import match_str + + status = match_str(cond, data) + except Exception as e: + LOG.exception(e) return web.json_response( - data={"error": f"Condition '{cond}' doesn't match the data from the URL."}, - status=web.HTTPNotFound.status_code, + data={"error": str(e)}, + status=web.HTTPBadRequest.status_code, ) return web.json_response( - data={"message": f"Condition '{cond}' matched the data from the URL."}, + data={"status": status, "condition": cond, "data": data}, status=web.HTTPOk.status_code, + dumps=self.encoder.encode, ) @route("GET", "api/presets") diff --git a/ui/components/ConditionForm.vue b/ui/components/ConditionForm.vue index ea09e06c..4e7b4f7c 100644 --- a/ui/components/ConditionForm.vue +++ b/ui/components/ConditionForm.vue @@ -70,7 +70,7 @@
- The yt-dlp [--match-filters] filter logic. + + The yt-dlp [--match-filters] filter logic. + + Test filter logic + +
@@ -108,29 +113,102 @@ + +
+ +
+
+
+
+ +
+
+
+ +
+
+ +
+
+
+ + + The url to test the filter against. + +
+ +
+ +
+ +
+ + + The yt-dlp [--match-filters] filter logic.
+
+
+ +
+ + + Filter Status: {{ test_data?.data?.status === null ? 'Not tested' : test_data?.data?.status ? + 'Matched' : 'Not matched' }} + +
+ +
+
{{ show_data() }}
+
+ +
+
+ +
+
diff --git a/ui/components/Modal.vue b/ui/components/Modal.vue new file mode 100644 index 00000000..20582c57 --- /dev/null +++ b/ui/components/Modal.vue @@ -0,0 +1,35 @@ + + + diff --git a/ui/composables/useNotification.ts b/ui/composables/useNotification.ts index f24ee24d..1e5872e9 100644 --- a/ui/composables/useNotification.ts +++ b/ui/composables/useNotification.ts @@ -3,14 +3,16 @@ import { useToast } from "vue-toastification" type notificationType = 'info' | 'success' | 'warning' | 'error' type notificationOptions = { - timeout?: number + timeout?: number, + force?: boolean, } const allowToast = useStorage('allow_toasts', true) const toast = useToast() function notify(type: notificationType, message: string, opts?: notificationOptions): void { - if (!allowToast.value) { + let force = opts?.force || false; + if (false === allowToast.value && false === force) { return; } diff --git a/ui/pages/conditions.vue b/ui/pages/conditions.vue index 72694b2a..cbd080dc 100644 --- a/ui/pages/conditions.vue +++ b/ui/pages/conditions.vue @@ -82,13 +82,6 @@ Delete - @@ -267,8 +260,6 @@ const updateItem = async ({ reference, item }) => { resetForm(true) } -const filterItem = i => JSON.stringify(cleanObject(i, remove_keys), null, 2) - const editItem = _item => { item.value = _item itemRef.value = _item.id @@ -297,33 +288,4 @@ const exportItem = item => { return copyText(base64UrlEncode(JSON.stringify(userData))) } - -const TestCondition = async (item) => { - const url = box.prompt("Enter URL to test condition against:") - if (!url) { - return - } - - item.in_progress = true - - try { - const response = await request("/api/conditions/test", { - method: "POST", - headers: { "Content-Type": "application/json" }, - body: JSON.stringify({ url: url, condition: item.id || item.name }), - }) - - const data = await response.json() - if (!response.ok) { - toast.error(`Failed to test condition. ${data.error}`) - return - } - - toast.success(data?.message || "Condition tested successfully.") - } catch (e) { - toast.error(`Failed to test condition. ${e.message}`) - } finally { - item.in_progress = false - } -}