use clap::Parser;
use night_fury_daemon_core::cli::make_req;
use night_fury_daemon_core::client;
use serde_json::json;
use tail_fin_daemon::cli::{expand_home, Cli, Commands, DaemonCmd, SessionCmd};
use tail_fin_daemon::driver::SiteEntry;
use tail_fin_daemon::handlers::{
bloomberg::BloombergHandler, grok::GrokHandler, sa::SaHandler, twitter::TwitterHandler,
};
use tail_fin_daemon::spawn::ensure_daemon_safe;
fn register_all_sites() {
tail_fin_daemon::driver::register_sites(vec![
SiteEntry::new(tail_fin_sa::SeekingAlphaSite, |s| {
Box::new(SaHandler::new(s))
}),
SiteEntry::new(tail_fin_twitter::TwitterSite, |s| {
Box::new(TwitterHandler::new(s))
}),
SiteEntry::new(tail_fin_grok::GrokSite, |s| Box::new(GrokHandler::new(s))),
SiteEntry::stateless(tail_fin_reddit::RedditSite),
SiteEntry::stateless(tail_fin_instagram::InstagramSite),
SiteEntry::stateless(tail_fin_xhs::XhsSite),
SiteEntry::stateless(tail_fin_coupang::CoupangSite),
SiteEntry::stateless(tail_fin_shopee::ShopeeSite(
tail_fin_shopee::ShopeeRegion::Tw,
)),
SiteEntry::stateless(tail_fin_shopee::ShopeeSite(
tail_fin_shopee::ShopeeRegion::Sg,
)),
SiteEntry::stateless(tail_fin_shopee::ShopeeSite(
tail_fin_shopee::ShopeeRegion::My,
)),
SiteEntry::stateless(tail_fin_shopee::ShopeeSite(
tail_fin_shopee::ShopeeRegion::Id,
)),
SiteEntry::stateless(tail_fin_shopee::ShopeeSite(
tail_fin_shopee::ShopeeRegion::Vn,
)),
SiteEntry::stateless(tail_fin_shopee::ShopeeSite(
tail_fin_shopee::ShopeeRegion::Ph,
)),
SiteEntry::stateless(tail_fin_shopee::ShopeeSite(
tail_fin_shopee::ShopeeRegion::Th,
)),
SiteEntry::stateless(tail_fin_shopee::ShopeeSite(
tail_fin_shopee::ShopeeRegion::Br,
)),
SiteEntry::stateless(tail_fin_spotify::SpotifySite),
SiteEntry::stateless(tail_fin_youtube::YoutubeSite),
SiteEntry::new(tail_fin_bloomberg::BloombergSite, |s| {
Box::new(BloombergHandler::new(s))
}),
SiteEntry::stateless(tail_fin_591::FiveNineOneSite),
SiteEntry::stateless(tail_fin_pcc::PccSite),
SiteEntry::stateless(tail_fin_tradingview::TradingViewSite),
]);
}
#[tokio::main]
async fn main() -> anyhow::Result<()> {
tracing_subscriber::fmt()
.with_env_filter(
tracing_subscriber::EnvFilter::try_from_env("TFD_LOG")
.unwrap_or_else(|_| tracing_subscriber::EnvFilter::new("info")),
)
.with_writer(std::io::stderr)
.init();
let cli = Cli::parse();
let socket = expand_home(&cli.socket);
if let Some(parent) = std::path::Path::new(&socket).parent() {
let _ = std::fs::create_dir_all(parent);
}
match cli.command {
Commands::Daemon { cmd } => match cmd {
DaemonCmd::Start {
idle_timeout,
daemon_idle,
max_sessions,
detach,
} => {
if detach {
tail_fin_daemon::spawn::start_detached_and_wait(
&socket,
idle_timeout,
daemon_idle,
max_sessions,
)
.await?;
} else {
register_all_sites();
tail_fin_daemon::server::serve(
&socket,
idle_timeout,
daemon_idle,
max_sessions,
)
.await?;
}
}
DaemonCmd::Stop => {
let req = make_req("daemon.shutdown", None, json!({}));
let resp = client::send(&socket, &req).await?;
tail_fin_daemon::dispatch::print_and_check(&resp);
}
DaemonCmd::Status => {
ensure_daemon_safe(&socket).await?;
let req = make_req("daemon.status", None, json!({}));
let resp = client::send(&socket, &req).await?;
tail_fin_daemon::dispatch::print_and_check(&resp);
}
},
Commands::Session { cmd } => match cmd {
SessionCmd::Acquire { site, host } => {
ensure_daemon_safe(&socket).await?;
let req = make_req(
"session.acquire",
None,
json!({"site": site, "host": host, "mode": "acquired"}),
);
let resp = client::send(&socket, &req).await?;
tail_fin_daemon::dispatch::print_and_check(&resp);
}
SessionCmd::Release { session_id } => {
ensure_daemon_safe(&socket).await?;
let req = make_req("session.release", Some(&session_id), json!({}));
let resp = client::send(&socket, &req).await?;
tail_fin_daemon::dispatch::print_and_check(&resp);
}
SessionCmd::List => {
ensure_daemon_safe(&socket).await?;
let req = make_req("session.list", None, json!({}));
let resp = client::send(&socket, &req).await?;
tail_fin_daemon::dispatch::print_and_check(&resp);
}
SessionCmd::Destroy { session_id } => {
ensure_daemon_safe(&socket).await?;
let req = make_req("session.destroy", Some(&session_id), json!({}));
let resp = client::send(&socket, &req).await?;
tail_fin_daemon::dispatch::print_and_check(&resp);
}
},
Commands::Start {
idle_timeout,
daemon_idle,
max_sessions,
detach: _,
} => {
register_all_sites();
tail_fin_daemon::server::serve(&socket, idle_timeout, daemon_idle, max_sessions)
.await?;
}
Commands::Sa { cmd } => {
tail_fin_daemon::dispatch::sa::run(cmd, &socket, &cli.host, cli.session.clone())
.await?;
}
Commands::Twitter { cmd } => {
tail_fin_daemon::dispatch::twitter::run(cmd, &socket, &cli.host, cli.session.clone())
.await?;
}
Commands::Grok { cmd } => {
tail_fin_daemon::dispatch::grok::run(cmd, &socket, &cli.host, cli.session.clone())
.await?;
}
Commands::Bloomberg { cmd } => {
tail_fin_daemon::dispatch::bloomberg::run(cmd, &socket, &cli.host, cli.session.clone())
.await?;
}
}
Ok(())
}