From d7fc8c45760db5ddbfc7da440cd6b78321e8f334 Mon Sep 17 00:00:00 2001 From: nose Date: Wed, 24 Dec 2025 05:34:56 -0800 Subject: [PATCH] fg --- cmdlet/search_provider.py | 180 ++++++++++++++++++++------------------ 1 file changed, 97 insertions(+), 83 deletions(-) diff --git a/cmdlet/search_provider.py b/cmdlet/search_provider.py index b045f02..80359fb 100644 --- a/cmdlet/search_provider.py +++ b/cmdlet/search_provider.py @@ -148,108 +148,122 @@ class Search_Provider(Cmdlet): log(f" - {name}", file=sys.stderr) return 1 - from API.folder import API_folder_store worker_id = str(uuid.uuid4()) - library_root = get_local_storage_path(config or {}) - if not library_root: - log("No library root configured", file=sys.stderr) - return 1 + library_root = get_local_storage_path(config or {}) if get_local_storage_path else None - # Use context manager to ensure database is always closed - with API_folder_store(library_root) as db: + db = None + if library_root: try: + from API.folder import API_folder_store + db = API_folder_store(library_root) + except Exception: + db = None + + try: + # Use the worker DB if available; otherwise, run as a stateless one-off. + if db is not None: + db.__enter__() db.insert_worker( worker_id, "search-provider", title=f"Search: {query}", description=f"Provider: {provider_name}, Query: {query}", - pipe=ctx.get_current_command_text() + pipe=ctx.get_current_command_text(), ) - results_list = [] - import result_table - importlib.reload(result_table) - from result_table import ResultTable + results_list = [] + import result_table + importlib.reload(result_table) + from result_table import ResultTable - provider_text = str(provider_name or "").strip() - provider_lower = provider_text.lower() - if provider_lower == "youtube": - provider_label = "Youtube" - elif provider_lower == "openlibrary": - provider_label = "OpenLibrary" - else: - provider_label = provider_text[:1].upper() + provider_text[1:] if provider_text else "Provider" + provider_text = str(provider_name or "").strip() + provider_lower = provider_text.lower() + if provider_lower == "youtube": + provider_label = "Youtube" + elif provider_lower == "openlibrary": + provider_label = "OpenLibrary" + else: + provider_label = provider_text[:1].upper() + provider_text[1:] if provider_text else "Provider" - if provider_lower == "alldebrid" and open_id is not None: - table_title = f"{provider_label} Files: {open_id}".strip().rstrip(":") - else: - table_title = f"{provider_label}: {query}".strip().rstrip(":") - preserve_order = provider_name.lower() in ('youtube', 'openlibrary') - table = ResultTable(table_title).set_preserve_order(preserve_order) - table.set_table(provider_name) - table.set_source_command("search-provider", list(args)) + if provider_lower == "alldebrid" and open_id is not None: + table_title = f"{provider_label} Files: {open_id}".strip().rstrip(":") + else: + table_title = f"{provider_label}: {query}".strip().rstrip(":") + preserve_order = provider_name.lower() in ("youtube", "openlibrary") + table = ResultTable(table_title).set_preserve_order(preserve_order) + table.set_table(provider_name) + table.set_source_command("search-provider", list(args)) - debug(f"[search-provider] Calling {provider_name}.search()") - if provider_lower == "alldebrid": - if open_id is not None: - # Second-stage: show files for selected folder/magnet. - results = provider.search(query, limit=limit, filters={"view": "files", "magnet_id": open_id}) - else: - # Default: show folders (magnets) so user can select @N. - results = provider.search(query, limit=limit, filters={"view": "folders"}) + debug(f"[search-provider] Calling {provider_name}.search()") + if provider_lower == "alldebrid": + if open_id is not None: + # Second-stage: show files for selected folder/magnet. + results = provider.search(query, limit=limit, filters={"view": "files", "magnet_id": open_id}) else: - results = provider.search(query, limit=limit) - debug(f"[search-provider] Got {len(results)} results") - - if not results: - log(f"No results found for query: {query}", file=sys.stderr) + # Default: show folders (magnets) so user can select @N. + results = provider.search(query, limit=limit, filters={"view": "folders"}) + else: + results = provider.search(query, limit=limit) + debug(f"[search-provider] Got {len(results)} results") + + if not results: + log(f"No results found for query: {query}", file=sys.stderr) + if db is not None: db.append_worker_stdout(worker_id, json.dumps([], indent=2)) - db.update_worker_status(worker_id, 'completed') - return 0 - - # Emit results for pipeline - for search_result in results: - item_dict = search_result.to_dict() if hasattr(search_result, 'to_dict') else dict(search_result) - - # Ensure table field is set (should be by provider, but just in case) - if 'table' not in item_dict: - item_dict['table'] = provider_name - - row_index = len(table.rows) - table.add_result(search_result) # ResultTable handles SearchResult objects - - # For AllDebrid folder rows, allow @N to open and show files. - try: - if provider_lower == "alldebrid" and getattr(search_result, "media_kind", "") == "folder": - magnet_id = None - meta = getattr(search_result, "full_metadata", None) - if isinstance(meta, dict): - magnet_id = meta.get("magnet_id") - if magnet_id is not None: - table.set_row_selection_args(row_index, ["-open", str(magnet_id), "-query", "*"]) - except Exception: - pass - results_list.append(item_dict) - ctx.emit(item_dict) - - ctx.set_last_result_table(table, results_list) - # Ensure @N selection expands against this newly displayed table. - ctx.set_current_stage_table(table) - db.append_worker_stdout(worker_id, json.dumps(results_list, indent=2)) - db.update_worker_status(worker_id, 'completed') - - ##log(f"Found {len(results)} result(s) from {provider_name}", file=sys.stderr) + db.update_worker_status(worker_id, "completed") return 0 - - except Exception as e: - log(f"Error searching {provider_name}: {e}", file=sys.stderr) - import traceback - debug(traceback.format_exc()) + + # Emit results for pipeline + for search_result in results: + item_dict = search_result.to_dict() if hasattr(search_result, "to_dict") else dict(search_result) + + # Ensure table field is set (should be by provider, but just in case) + if "table" not in item_dict: + item_dict["table"] = provider_name + + row_index = len(table.rows) + table.add_result(search_result) # ResultTable handles SearchResult objects + + # For AllDebrid folder rows, allow @N to open and show files. try: - db.update_worker_status(worker_id, 'error') + if provider_lower == "alldebrid" and getattr(search_result, "media_kind", "") == "folder": + magnet_id = None + meta = getattr(search_result, "full_metadata", None) + if isinstance(meta, dict): + magnet_id = meta.get("magnet_id") + if magnet_id is not None: + table.set_row_selection_args(row_index, ["-open", str(magnet_id), "-query", "*"]) + except Exception: + pass + results_list.append(item_dict) + ctx.emit(item_dict) + + ctx.set_last_result_table(table, results_list) + # Ensure @N selection expands against this newly displayed table. + ctx.set_current_stage_table(table) + if db is not None: + db.append_worker_stdout(worker_id, json.dumps(results_list, indent=2)) + db.update_worker_status(worker_id, "completed") + + return 0 + + except Exception as e: + log(f"Error searching {provider_name}: {e}", file=sys.stderr) + import traceback + + debug(traceback.format_exc()) + if db is not None: + try: + db.update_worker_status(worker_id, "error") + except Exception: + pass + return 1 + finally: + if db is not None: + try: + db.__exit__(None, None, None) except Exception: pass - return 1 # Register cmdlet instance (catalog + REPL autocomplete expects module-level CMDLET)