Files
Agent-Reach/agent_eyes/channels/__init__.py
T
Panniantong 1b8b202e1e feat: complete channel menu install flow + XiaoHongShu channel
Major install flow polish:
- Channels organized by setup difficulty:
  🟢 Zero-config (Web, GitHub, RSS) — works immediately
  🔵 Cookie-based (Twitter, YouTube, Bilibili, XiaoHongShu) — free, ~2min
  🟡 Free API key (Exa Search) — one key, 30 seconds
  🟠 Proxy-based (Reddit, Bilibili on server) — $1/month
- Every channel explains: what it does, what's needed, what you miss without it
- Server vs local affects which channels need proxy

New: XiaoHongShu channel (cookie-based, falls back to Jina Reader)
New configure commands: twitter-cookies, xhs-cookie, youtube-cookies
Each command auto-tests after saving.
2026-02-24 06:31:48 +01:00

70 lines
1.8 KiB
Python

# -*- coding: utf-8 -*-
"""
Channel registry — routes URLs to the right channel.
This is the core of Agent Eyes' pluggable architecture.
Add a new channel: just create a file and register it here.
Swap a backend: just change the implementation inside the channel file.
"""
from typing import Dict, List, Optional
from .base import Channel, ReadResult, SearchResult
# Import all channels
from .web import WebChannel
from .github import GitHubChannel
from .twitter import TwitterChannel
from .youtube import YouTubeChannel
from .reddit import RedditChannel
from .rss import RSSChannel
from .bilibili import BilibiliChannel
from .exa_search import ExaSearchChannel
from .xiaohongshu import XiaoHongShuChannel
# Channel registry — order matters (first match wins, web is last as fallback)
ALL_CHANNELS: List[Channel] = [
GitHubChannel(),
TwitterChannel(),
YouTubeChannel(),
RedditChannel(),
BilibiliChannel(),
XiaoHongShuChannel(),
RSSChannel(),
ExaSearchChannel(),
WebChannel(), # Fallback — handles any URL
]
# Search-capable channels
SEARCH_CHANNELS: Dict[str, Channel] = {
ch.name: ch for ch in ALL_CHANNELS if ch.can_search()
}
def get_channel_for_url(url: str) -> Channel:
"""Find the right channel for a URL."""
for channel in ALL_CHANNELS:
if channel.can_handle(url):
return channel
return WebChannel() # Should never reach here, but just in case
def get_channel(name: str) -> Optional[Channel]:
"""Get a channel by name."""
for ch in ALL_CHANNELS:
if ch.name == name:
return ch
return None
def get_all_channels() -> List[Channel]:
"""Get all registered channels."""
return ALL_CHANNELS
__all__ = [
"Channel", "ReadResult", "SearchResult",
"ALL_CHANNELS", "SEARCH_CHANNELS",
"get_channel_for_url", "get_channel", "get_all_channels",
]