You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
91 lines
3.0 KiB
91 lines
3.0 KiB
use crate::{Result, streaming};
|
|
use crate::entities::card::Card;
|
|
use crate::entities::context::Context;
|
|
use crate::entities::status::Status;
|
|
use crate::helpers::deserialise_response;
|
|
use crate::streaming::EventReader;
|
|
|
|
/// Client that can make unauthenticated calls to a mastodon instance
|
|
#[derive(Clone, Debug)]
|
|
pub struct FediClient {
|
|
http_client: reqwest::Client,
|
|
base: url::Url,
|
|
}
|
|
|
|
impl FediClient {
|
|
/// Create a new unauthenticated client
|
|
pub fn new(base: &str) -> Result<FediClient> {
|
|
let base = if base.starts_with("https://") {
|
|
base.to_string()
|
|
} else {
|
|
format!("https://{}", base)
|
|
};
|
|
Ok(FediClient {
|
|
http_client: reqwest::Client::new(),
|
|
base: url::Url::parse(&base)?,
|
|
})
|
|
}
|
|
}
|
|
|
|
impl FediClient {
|
|
/// # Low-level API for extending
|
|
/// Create a route with the given path fragment
|
|
pub fn route(&self, url: &str) -> Result<url::Url> {
|
|
Ok(self.base.join(url)?)
|
|
}
|
|
|
|
/// # Low-level API for extending
|
|
/// Send a request
|
|
pub async fn send(&self, req: reqwest::RequestBuilder) -> Result<reqwest::Response> {
|
|
let req = req.build()?;
|
|
Ok(self.http_client.execute(req).await?)
|
|
}
|
|
|
|
// TODO verify if this really works without auth
|
|
|
|
/// Get a stream of the public timeline
|
|
pub async fn streaming_public(&self) -> Result<EventReader> {
|
|
let mut url: url::Url = self.route("/api/v1/streaming")?;
|
|
{
|
|
let mut qpm = url.query_pairs_mut();
|
|
qpm.append_pair("stream", "public");
|
|
}
|
|
streaming::do_open_streaming(url.as_str()).await
|
|
}
|
|
|
|
/// Get a stream of the local timeline
|
|
pub async fn streaming_local(&self) -> Result<EventReader> {
|
|
let mut url: url::Url = self.route("/api/v1/streaming/public")?;
|
|
{
|
|
let mut qpm = url.query_pairs_mut();
|
|
qpm.append_pair("stream", "public:local");
|
|
}
|
|
streaming::do_open_streaming(url.as_str()).await
|
|
}
|
|
|
|
/// GET /api/v1/statuses/:id
|
|
pub async fn get_status(&self, id: &str) -> Result<Status> {
|
|
let route = self.route("/api/v1/statuses")?;
|
|
let route = route.join(id)?;
|
|
let response = self.send(self.http_client.get(route)).await?;
|
|
deserialise_response(response).await
|
|
}
|
|
|
|
/// GET /api/v1/statuses/:id/context
|
|
pub async fn get_context(&self, id: &str) -> Result<Context> {
|
|
let route = self.route("/api/v1/statuses")?;
|
|
let route = route.join(id)?;
|
|
let route = route.join("context")?;
|
|
let response = self.send(self.http_client.get(route)).await?;
|
|
deserialise_response(response).await
|
|
}
|
|
|
|
/// GET /api/v1/statuses/:id/card
|
|
pub async fn get_card(&self, id: &str) -> Result<Card> {
|
|
let route = self.route("/api/v1/statuses")?;
|
|
let route = route.join(id)?;
|
|
let route = route.join("card")?;
|
|
let response = self.send(self.http_client.get(route)).await?;
|
|
deserialise_response(response).await
|
|
}
|
|
}
|
|
|