Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Add CLI commands #108

Merged
merged 3 commits into from
Feb 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions atrium-cli/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,11 @@ version = "0.1.0"
authors = ["sugyan <[email protected]>"]
edition.workspace = true
rust-version.workspace = true
description = "CLI application for AT Protocol using ATrium API"
readme = "README.md"
repository.workspace = true
license.workspace = true
keywords.workspace = true

[dependencies]
async-trait.workspace = true
Expand Down
17 changes: 12 additions & 5 deletions atrium-cli/README.md
Original file line number Diff line number Diff line change
@@ -1,16 +1,23 @@
# CLI
# ATrium CLI

CLI application for AT Protocol using ATrium API

```
Usage: atrium-cli [OPTIONS] <COMMAND>

Commands:
login Login (Create an authentication session)
get-timeline Get a view of the actor's home timeline
get-timeline Get a view of an actor's home timeline
get-author-feed Get a view of an actor's feed
get-likes Get the list of likes
get-reposted-by Get a list of reposts
get-follows Get a list of who the actor follows
get-likes Get a list of likes for a given post
get-reposted-by Get a list of reposts for a given post
get-actor-feeds Get a list of feeds created by an actor
get-feed Get a view of a hydrated feed
get-list-feed Get a view of a specified list,
get-follows Get a list of who an actor follows
get-followers Get a list of an actor's followers
get-lists Get a list of the list created by an actor
get-list Get detailed info of a specified list
get-profile Get detailed profile view of an actor
list-notifications Get a list of notifications
create-post Create a new post
Expand Down
24 changes: 19 additions & 5 deletions atrium-cli/src/commands.rs
Original file line number Diff line number Diff line change
@@ -1,23 +1,34 @@
use atrium_api::types::string::AtIdentifier;
use clap::Parser;
use std::path::PathBuf;
use std::str::FromStr;

#[derive(Parser, Debug)]
pub enum Command {
/// Login (Create an authentication session).
Login(LoginArgs),
/// Get a view of the actor's home timeline.
/// Get a view of an actor's home timeline.
GetTimeline,
/// Get a view of an actor's feed.
GetAuthorFeed(ActorArgs),
/// Get the list of likes.
/// Get a list of likes for a given post.
GetLikes(UriArgs),
/// Get a list of reposts.
/// Get a list of reposts for a given post.
GetRepostedBy(UriArgs),
/// Get a list of who the actor follows.
/// Get a list of feeds created by an actor.
GetActorFeeds(ActorArgs),
/// Get a view of a hydrated feed.
GetFeed(UriArgs),
/// Get a view of a specified list,
GetListFeed(UriArgs),
/// Get a list of who an actor follows.
GetFollows(ActorArgs),
/// Get a list of an actor's followers.
GetFollowers(ActorArgs),
/// Get a list of the list created by an actor.
GetLists(ActorArgs),
/// Get detailed info of a specified list.
GetList(UriArgs),
/// Get detailed profile view of an actor.
GetProfile(ActorArgs),
/// Get a list of notifications.
Expand Down Expand Up @@ -55,8 +66,11 @@ pub struct UriArgs {
#[derive(Parser, Debug)]
pub struct CreatePostArgs {
/// Post text
#[arg(short, long, value_parser)]
#[arg(short, long)]
pub(crate) text: String,
/// Images to embed
#[arg(short, long)]
pub(crate) images: Vec<PathBuf>,
}

#[derive(Debug, Clone)]
Expand Down
124 changes: 121 additions & 3 deletions atrium-cli/src/runner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,10 @@ use atrium_api::types::string::{AtIdentifier, Datetime, Handle};
use atrium_api::xrpc::error::{Error, XrpcErrorKind};
use atrium_xrpc_client::reqwest::ReqwestClient;
use serde::Serialize;
use std::ffi::OsStr;
use std::path::PathBuf;
use tokio::fs;
use tokio::fs::{create_dir_all, File};
use tokio::io::AsyncReadExt;

pub struct Runner {
agent: AtpAgent<SimpleJsonFileSessionStore, ReqwestClient>,
Expand All @@ -19,7 +21,7 @@ impl Runner {
pub async fn new(pds_host: String, debug: bool) -> Result<Self, Box<dyn std::error::Error>> {
let config_dir = dirs::config_dir().unwrap();
let dir = config_dir.join("atrium-cli");
fs::create_dir_all(&dir).await?;
create_dir_all(&dir).await?;
let session_path = dir.join("session.json");
let store = SimpleJsonFileSessionStore::new(session_path.clone());
let session = store.get_session().await;
Expand Down Expand Up @@ -119,6 +121,57 @@ impl Runner {
.await,
);
}
Command::GetActorFeeds(args) => {
self.print(
&self
.agent
.api
.app
.bsky
.feed
.get_actor_feeds(atrium_api::app::bsky::feed::get_actor_feeds::Parameters {
actor: args
.actor
.or(self.handle.clone().map(AtIdentifier::Handle))
.unwrap(),
cursor: None,
limit: Some(limit),
})
.await,
);
}
Command::GetFeed(args) => {
self.print(
&self
.agent
.api
.app
.bsky
.feed
.get_feed(atrium_api::app::bsky::feed::get_feed::Parameters {
cursor: None,
feed: args.uri.to_string(),
limit: Some(limit),
})
.await,
);
}
Command::GetListFeed(args) => {
self.print(
&self
.agent
.api
.app
.bsky
.feed
.get_list_feed(atrium_api::app::bsky::feed::get_list_feed::Parameters {
cursor: None,
limit: Some(limit),
list: args.uri.to_string(),
})
.await,
);
}
Command::GetFollows(args) => {
self.print(
&self
Expand Down Expand Up @@ -157,6 +210,41 @@ impl Runner {
.await,
);
}
Command::GetLists(args) => {
self.print(
&self
.agent
.api
.app
.bsky
.graph
.get_lists(atrium_api::app::bsky::graph::get_lists::Parameters {
actor: args
.actor
.or(self.handle.clone().map(AtIdentifier::Handle))
.unwrap(),
cursor: None,
limit: Some(limit),
})
.await,
);
}
Command::GetList(args) => {
self.print(
&self
.agent
.api
.app
.bsky
.graph
.get_list(atrium_api::app::bsky::graph::get_list::Parameters {
cursor: None,
limit: Some(limit),
list: args.uri.to_string(),
})
.await,
);
}
Command::GetProfile(args) => {
self.print(
&self
Expand Down Expand Up @@ -193,6 +281,36 @@ impl Runner {
);
}
Command::CreatePost(args) => {
let mut images = Vec::new();
for image in &args.images {
if let Ok(mut file) = File::open(image).await {
let mut buf = Vec::new();
file.read_to_end(&mut buf).await.expect("read image file");
let output = self
.agent
.api
.com
.atproto
.repo
.upload_blob(buf)
.await
.expect("upload blob");
images.push(atrium_api::app::bsky::embed::images::Image {
alt: image
.file_name()
.map(OsStr::to_string_lossy)
.unwrap_or_default()
.into(),
aspect_ratio: None,
image: output.blob,
})
}
}
let embed = Some(
atrium_api::app::bsky::feed::post::RecordEmbedEnum::AppBskyEmbedImagesMain(
Box::new(atrium_api::app::bsky::embed::images::Main { images }),
),
);
self.print(
&self
.agent
Expand All @@ -205,7 +323,7 @@ impl Runner {
record: atrium_api::records::Record::AppBskyFeedPost(Box::new(
atrium_api::app::bsky::feed::post::Record {
created_at: Datetime::now(),
embed: None,
embed,
entities: None,
facets: None,
labels: None,
Expand Down
7 changes: 7 additions & 0 deletions release-plz.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,13 @@ git_release_enable = true
git_tag_enable = true
changelog_update = true

[[package]]
name = "atrium-cli"
publish = true
git_release_enable = true
git_tag_enable = true
changelog_update = true

[[package]]
name = "atrium-xrpc"
publish = true
Expand Down
Loading