This commit is contained in:
parent
ecc05a2812
commit
c0bff03120
1 changed files with 103 additions and 53 deletions
291
src/lemmy.rs
Normal file
291
src/lemmy.rs
Normal file
|
@ -0,0 +1,291 @@
|
|||
use std::collections::HashMap;
|
||||
use lemmy_api_common::community::{ListCommunities, ListCommunitiesResponse};
|
||||
use lemmy_api_common::lemmy_db_views::structs::PostView;
|
||||
use lemmy_api_common::person::{Login, LoginResponse};
|
||||
use lemmy_api_common::post::{CreatePost, FeaturePost, GetPosts, GetPostsResponse};
|
||||
use lemmy_api_common::sensitive::Sensitive;
|
||||
use lemmy_db_schema::newtypes::{CommunityId, PostId};
|
||||
use lemmy_db_schema::{ListingType, PostFeatureType};
|
||||
use reqwest::StatusCode;
|
||||
use crate::config::Config;
|
||||
use crate::{HTTP_CLIENT, write_error};
|
||||
|
||||
pub(crate) struct Lemmy {
|
||||
jwt_token: Sensitive<String>,
|
||||
instance: String,
|
||||
}
|
||||
|
||||
pub(crate) async fn login(config: &Config) -> Result<Lemmy, ()> {
|
||||
let login_params = Login {
|
||||
username_or_email: config.get_username(),
|
||||
password: config.get_password(),
|
||||
totp_2fa_token: None,
|
||||
};
|
||||
|
||||
let response = match HTTP_CLIENT
|
||||
.post(config.instance.to_owned() + "/api/v3/user/login")
|
||||
.json(&login_params)
|
||||
.send()
|
||||
.await {
|
||||
Ok(data) => data,
|
||||
Err(e) => {
|
||||
let err_msg = format!("{e}");
|
||||
write_error(err_msg);
|
||||
return Err(())
|
||||
}
|
||||
};
|
||||
|
||||
match response.status() {
|
||||
StatusCode::OK => {
|
||||
let data: LoginResponse = response.json().await.expect("Successful Login Request should return JSON");
|
||||
match data.jwt {
|
||||
Some(token) => Ok(Lemmy {
|
||||
jwt_token: token.clone(),
|
||||
instance: config.instance.to_owned(),
|
||||
}),
|
||||
None => {
|
||||
let err_msg = "Login did not return JWT token. Are the credentials valid?".to_owned();
|
||||
write_error(err_msg);
|
||||
return Err(())
|
||||
}
|
||||
}
|
||||
},
|
||||
status => {
|
||||
let err_msg = format!("Unexpected HTTP Status '{}' during Login", status);
|
||||
write_error(err_msg);
|
||||
return Err(())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Lemmy {
|
||||
pub(crate) async fn post(&self, post: CreatePost) -> Result<PostId, ()> {
|
||||
let response = match HTTP_CLIENT
|
||||
.post(format!("{}/api/v3/post", &self.instance))
|
||||
.bearer_auth(&self.jwt_token.to_string())
|
||||
.json(&post)
|
||||
.send()
|
||||
.await {
|
||||
Ok(data) => {
|
||||
match data.text().await {
|
||||
Ok(data) => data,
|
||||
Err(e) => {
|
||||
let err_msg = format!("{e}");
|
||||
write_error(err_msg);
|
||||
return Err(())
|
||||
}
|
||||
}
|
||||
},
|
||||
Err(e) => {
|
||||
let err_msg = format!("{e}");
|
||||
write_error(err_msg);
|
||||
return Err(())
|
||||
}
|
||||
};
|
||||
|
||||
let json_data = match serde_json::from_str::<HashMap<&str, PostView>>(&response) {
|
||||
Ok(mut data) => data.remove("post_view").expect("Element should be present"),
|
||||
Err(e) => {
|
||||
let err_msg = format!("{e}");
|
||||
write_error(err_msg);
|
||||
return Err(())
|
||||
}
|
||||
};
|
||||
|
||||
Ok(json_data.post.id)
|
||||
}
|
||||
|
||||
async fn feature(&self, params: FeaturePost) -> Result<PostView, ()> {
|
||||
let response = match HTTP_CLIENT
|
||||
.post(format!("{}/api/v3/post/feature", &self.instance))
|
||||
.bearer_auth(&self.jwt_token.to_string())
|
||||
.json(¶ms)
|
||||
.send()
|
||||
.await {
|
||||
Ok(data) => {
|
||||
match data.text().await {
|
||||
Ok(data) => data,
|
||||
Err(e) => {
|
||||
let err_msg = format!("{e}");
|
||||
write_error(err_msg);
|
||||
return Err(())
|
||||
}
|
||||
}
|
||||
},
|
||||
Err(e) => {
|
||||
let err_msg = format!("{e}");
|
||||
write_error(err_msg);
|
||||
return Err(())
|
||||
}
|
||||
};
|
||||
|
||||
let json_data = match serde_json::from_str::<HashMap<&str, PostView>>(&response) {
|
||||
Ok(mut data) => data.remove("post_view").expect("Element should be present"),
|
||||
Err(e) => {
|
||||
let err_msg = format!("{e}");
|
||||
write_error(err_msg);
|
||||
return Err(())
|
||||
}
|
||||
};
|
||||
|
||||
Ok(json_data)
|
||||
}
|
||||
|
||||
pub(crate) async fn unpin(&self, post_id: PostId, location: PostFeatureType) -> Result<PostView, ()> {
|
||||
let pin_params = FeaturePost {
|
||||
post_id,
|
||||
featured: false,
|
||||
feature_type: location,
|
||||
};
|
||||
self.feature(pin_params).await
|
||||
}
|
||||
|
||||
pub(crate) async fn pin(&self, post_id: PostId, location: PostFeatureType) -> Result<PostView, ()> {
|
||||
let pin_params = FeaturePost {
|
||||
post_id,
|
||||
featured: true,
|
||||
feature_type: location,
|
||||
};
|
||||
self.feature(pin_params).await
|
||||
}
|
||||
|
||||
pub(crate) async fn get_community_pinned(&self, community: CommunityId) -> Result<Vec<PostView>, ()> {
|
||||
let list_params = GetPosts {
|
||||
community_id: Some(community),
|
||||
type_: Some(ListingType::Local),
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
let response = match HTTP_CLIENT
|
||||
.get(format!("{}/api/v3/post/list", &self.instance))
|
||||
.bearer_auth(&self.jwt_token.to_string())
|
||||
.query(&list_params)
|
||||
.send()
|
||||
.await {
|
||||
Ok(data) => {
|
||||
match data.text().await {
|
||||
Ok(data) => data,
|
||||
Err(e) => {
|
||||
let err_msg = format!("{e}");
|
||||
write_error(err_msg);
|
||||
return Err(())
|
||||
}
|
||||
}
|
||||
},
|
||||
Err(e) => {
|
||||
let err_msg = format!("{e}");
|
||||
write_error(err_msg);
|
||||
return Err(())
|
||||
}
|
||||
};
|
||||
|
||||
let json_data: GetPostsResponse = match serde_json::from_str(&response) {
|
||||
Ok(data) => data,
|
||||
Err(e) => {
|
||||
let err_msg = format!("{e}");
|
||||
write_error(err_msg);
|
||||
return Err(())
|
||||
}
|
||||
};
|
||||
|
||||
Ok(json_data.posts.iter().filter(|post| {
|
||||
post.post.featured_community
|
||||
})
|
||||
.cloned()
|
||||
.collect()
|
||||
)
|
||||
}
|
||||
|
||||
pub(crate) async fn get_local_pinned(&self) -> Result<Vec<PostView>, ()> {
|
||||
let list_params = GetPosts {
|
||||
type_: Some(ListingType::Local),
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
let response = match HTTP_CLIENT
|
||||
.get(format!("{}/api/v3/post/list", &self.instance))
|
||||
.bearer_auth(&self.jwt_token.to_string())
|
||||
.query(&list_params)
|
||||
.send()
|
||||
.await {
|
||||
Ok(data) => {
|
||||
match data.text().await {
|
||||
Ok(data) => data,
|
||||
Err(e) => {
|
||||
let err_msg = format!("{e}");
|
||||
write_error(err_msg);
|
||||
return Err(())
|
||||
}
|
||||
}
|
||||
},
|
||||
Err(e) => {
|
||||
let err_msg = format!("{e}");
|
||||
write_error(err_msg);
|
||||
return Err(())
|
||||
}
|
||||
};
|
||||
|
||||
let json_data: GetPostsResponse = match serde_json::from_str(&response) {
|
||||
Ok(data) => data,
|
||||
Err(e) => {
|
||||
let err_msg = format!("{e}");
|
||||
write_error(err_msg);
|
||||
return Err(())
|
||||
}
|
||||
};
|
||||
|
||||
Ok(json_data.posts.iter().filter(|post| {
|
||||
post.post.featured_local
|
||||
})
|
||||
.cloned()
|
||||
.collect()
|
||||
)
|
||||
}
|
||||
|
||||
pub(crate) async fn get_communities(&self) -> Result<HashMap<String, CommunityId>, ()> {
|
||||
let list_params = ListCommunities {
|
||||
type_: Some(ListingType::Local),
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
let response = match HTTP_CLIENT
|
||||
.get(format!("{}/api/v3/community/list", &self.instance))
|
||||
.bearer_auth(&self.jwt_token.to_string())
|
||||
.query(&list_params)
|
||||
.send()
|
||||
.await {
|
||||
Ok(data) => {
|
||||
match data.text().await {
|
||||
Ok(data) => data,
|
||||
Err(e) => {
|
||||
let err_msg = format!("{e}");
|
||||
write_error(err_msg);
|
||||
return Err(())
|
||||
}
|
||||
}
|
||||
},
|
||||
Err(e) => {
|
||||
let err_msg = format!("{e}");
|
||||
write_error(err_msg);
|
||||
return Err(())
|
||||
}
|
||||
};
|
||||
|
||||
let json_data: ListCommunitiesResponse = match serde_json::from_str(&response) {
|
||||
Ok(data) => data,
|
||||
Err(e) => {
|
||||
let err_msg = format!("{e}");
|
||||
write_error(err_msg);
|
||||
return Err(())
|
||||
}
|
||||
};
|
||||
|
||||
let mut communities: HashMap<String, CommunityId> = HashMap::new();
|
||||
for community_view in json_data.communities {
|
||||
let community = community_view.community;
|
||||
communities.insert(community.name, community.id);
|
||||
}
|
||||
|
||||
Ok(communities)
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue