use clap::Subcommand;
use tail_fin_common::TailFinError;
use crate::session::{print_json, print_list, require_browser_session, Ctx};
#[derive(Subcommand)]
pub enum InstagramAction {
Profile { username: String },
Search {
query: String,
#[arg(long, default_value_t = 10)]
count: usize,
},
User {
username: String,
#[arg(long, default_value_t = 12)]
count: usize,
},
Explore {
#[arg(long, default_value_t = 20)]
count: usize,
},
Followers {
username: String,
#[arg(long, default_value_t = 20)]
count: usize,
},
Following {
username: String,
#[arg(long, default_value_t = 20)]
count: usize,
},
Saved {
#[arg(long, default_value_t = 20)]
count: usize,
},
Like { shortcode: String },
Unlike { shortcode: String },
Follow { username: String },
Unfollow { username: String },
Save { shortcode: String },
Unsave { shortcode: String },
Comment { shortcode: String, text: String },
}
pub async fn run(action: InstagramAction, ctx: &Ctx) -> Result<(), TailFinError> {
let session = require_browser_session(ctx, "instagram").await?;
let client = tail_fin_instagram::InstagramClient::new(session);
match action {
InstagramAction::Profile { username } => {
let result = client.profile(&username).await?;
print_json(&result)?;
}
InstagramAction::Search { query, count } => {
let users = client.search(&query, count).await?;
print_list("users", &users, users.len())?;
}
InstagramAction::User { username, count } => {
let posts = client.user_posts(&username, count).await?;
print_list("posts", &posts, posts.len())?;
}
InstagramAction::Explore { count } => {
let posts = client.explore(count).await?;
print_list("posts", &posts, posts.len())?;
}
InstagramAction::Followers { username, count } => {
let users = client.followers(&username, count).await?;
print_list("followers", &users, users.len())?;
}
InstagramAction::Following { username, count } => {
let users = client.following(&username, count).await?;
print_list("following", &users, users.len())?;
}
InstagramAction::Saved { count } => {
let posts = client.saved(count).await?;
print_list("saved", &posts, posts.len())?;
}
InstagramAction::Like { shortcode } => {
let result = client.like(&shortcode).await?;
print_json(&result)?;
}
InstagramAction::Unlike { shortcode } => {
let result = client.unlike(&shortcode).await?;
print_json(&result)?;
}
InstagramAction::Follow { username } => {
let result = client.follow(&username).await?;
print_json(&result)?;
}
InstagramAction::Unfollow { username } => {
let result = client.unfollow(&username).await?;
print_json(&result)?;
}
InstagramAction::Save { shortcode } => {
let result = client.save(&shortcode).await?;
print_json(&result)?;
}
InstagramAction::Unsave { shortcode } => {
let result = client.unsave(&shortcode).await?;
print_json(&result)?;
}
InstagramAction::Comment { shortcode, text } => {
let result = client.comment(&shortcode, &text).await?;
print_json(&result)?;
}
}
Ok(())
}
pub struct Adapter;
impl crate::adapter::CliAdapter for Adapter {
fn name(&self) -> &'static str {
"instagram"
}
fn about(&self) -> &'static str {
"Instagram operations"
}
fn command(&self) -> clap::Command {
<InstagramAction as clap::Subcommand>::augment_subcommands(
clap::Command::new("instagram").about("Instagram operations"),
)
}
fn dispatch<'a>(
&'a self,
matches: &'a clap::ArgMatches,
ctx: &'a crate::session::Ctx,
) -> std::pin::Pin<
Box<
dyn std::future::Future<Output = Result<(), tail_fin_common::TailFinError>> + Send + 'a,
>,
> {
Box::pin(async move {
let action = <InstagramAction as clap::FromArgMatches>::from_arg_matches(matches)
.map_err(|e| tail_fin_common::TailFinError::Api(e.to_string()))?;
run(action, ctx).await
})
}
}