118 lines
4.8 KiB
Python
118 lines
4.8 KiB
Python
"""search-provider cmdlet: Search external providers (bandcamp, libgen, soulseek, youtube)."""
|
|
from __future__ import annotations
|
|
|
|
from typing import Any, Dict, List, Sequence
|
|
import sys
|
|
|
|
from helper.logger import log, debug
|
|
from helper.provider import get_search_provider, list_search_providers
|
|
|
|
from ._shared import Cmdlet, CmdletArg, should_show_help
|
|
import pipeline as ctx
|
|
|
|
|
|
class Search_Provider(Cmdlet):
|
|
"""Search external content providers."""
|
|
|
|
def __init__(self):
|
|
super().__init__(
|
|
name="search-provider",
|
|
summary="Search external providers (bandcamp, libgen, soulseek, youtube)",
|
|
usage="search-provider <provider> <query> [-limit N]",
|
|
arg=[
|
|
CmdletArg("provider", type="string", required=True, description="Provider name: bandcamp, libgen, soulseek, youtube"),
|
|
CmdletArg("query", type="string", required=True, description="Search query (supports provider-specific syntax)"),
|
|
CmdletArg("limit", type="int", description="Maximum results to return (default: 50)"),
|
|
],
|
|
detail=[
|
|
"Search external content providers:",
|
|
"- bandcamp: Search for music albums/tracks",
|
|
" Example: search-provider bandcamp \"artist:altrusian grace\"",
|
|
"- libgen: Search Library Genesis for books",
|
|
" Example: search-provider libgen \"python programming\"",
|
|
"- soulseek: Search P2P network for music",
|
|
" Example: search-provider soulseek \"pink floyd\"",
|
|
"- youtube: Search YouTube for videos",
|
|
" Example: search-provider youtube \"tutorial\"",
|
|
"",
|
|
"Query syntax:",
|
|
"- bandcamp: Use 'artist:Name' to search by artist",
|
|
"- libgen: Supports isbn:, author:, title: prefixes",
|
|
"- soulseek: Plain text search",
|
|
"- youtube: Plain text search",
|
|
"",
|
|
"Results can be piped to other cmdlets:",
|
|
" search-provider bandcamp \"artist:grace\" | @1 | download-data",
|
|
],
|
|
exec=self.run
|
|
)
|
|
self.register()
|
|
|
|
def run(self, result: Any, args: Sequence[str], config: Dict[str, Any]) -> int:
|
|
"""Execute search-provider cmdlet."""
|
|
if should_show_help(args):
|
|
ctx.emit(self.__dict__)
|
|
return 0
|
|
|
|
# Parse arguments
|
|
if len(args) < 2:
|
|
log("Error: search-provider requires <provider> and <query> arguments", file=sys.stderr)
|
|
log(f"Usage: {self.usage}", file=sys.stderr)
|
|
log("Available providers:", file=sys.stderr)
|
|
providers = list_search_providers(config)
|
|
for name, available in sorted(providers.items()):
|
|
status = "✓" if available else "✗"
|
|
log(f" {status} {name}", file=sys.stderr)
|
|
return 1
|
|
|
|
provider_name = args[0]
|
|
query = args[1]
|
|
|
|
# Parse optional limit
|
|
limit = 50
|
|
if len(args) >= 4 and args[2] in ("-limit", "--limit"):
|
|
try:
|
|
limit = int(args[3])
|
|
except ValueError:
|
|
log(f"Warning: Invalid limit value '{args[3]}', using default 50", file=sys.stderr)
|
|
|
|
debug(f"[search-provider] provider={provider_name}, query={query}, limit={limit}")
|
|
|
|
# Get provider
|
|
provider = get_search_provider(provider_name, config)
|
|
if not provider:
|
|
log(f"Error: Provider '{provider_name}' is not available", file=sys.stderr)
|
|
log("Available providers:", file=sys.stderr)
|
|
providers = list_search_providers(config)
|
|
for name, available in sorted(providers.items()):
|
|
if available:
|
|
log(f" - {name}", file=sys.stderr)
|
|
return 1
|
|
|
|
# Execute search
|
|
try:
|
|
debug(f"[search-provider] Calling {provider_name}.search()")
|
|
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)
|
|
return 0
|
|
|
|
# Emit results for pipeline
|
|
for search_result in results:
|
|
ctx.emit(search_result.to_dict())
|
|
|
|
log(f"Found {len(results)} result(s) from {provider_name}", file=sys.stderr)
|
|
return 0
|
|
|
|
except Exception as e:
|
|
log(f"Error searching {provider_name}: {e}", file=sys.stderr)
|
|
import traceback
|
|
debug(traceback.format_exc())
|
|
return 1
|
|
|
|
|
|
# Register cmdlet instance
|
|
Search_Provider_Instance = Search_Provider()
|