mirror of
https://github.com/Nutomic/ibis.git
synced 2024-11-22 11:31:08 +00:00
add basic api call with test
This commit is contained in:
parent
df9da3784b
commit
1098ecd4a1
8 changed files with 108 additions and 48 deletions
1
Cargo.lock
generated
1
Cargo.lock
generated
|
@ -464,6 +464,7 @@ dependencies = [
|
|||
"enum_delegate",
|
||||
"env_logger",
|
||||
"rand",
|
||||
"reqwest",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"tokio",
|
||||
|
|
|
@ -18,3 +18,6 @@ serde_json = "1.0.108"
|
|||
tokio = { version = "1.34.0", features = ["full"] }
|
||||
tracing = "0.1.40"
|
||||
url = "2.4.1"
|
||||
|
||||
[dev-dependencies]
|
||||
reqwest = "0.11.22"
|
||||
|
|
13
src/api.rs
Normal file
13
src/api.rs
Normal file
|
@ -0,0 +1,13 @@
|
|||
use crate::error::MyResult;
|
||||
use crate::federation::objects::article::DbArticle;
|
||||
use crate::federation::objects::instance::DbInstance;
|
||||
use axum::extract::Path;
|
||||
use axum::Json;
|
||||
use axum_macros::debug_handler;
|
||||
|
||||
#[debug_handler]
|
||||
pub async fn api_get_article(Path(title): Path<String>) -> MyResult<Json<DbArticle>> {
|
||||
let instance = DbInstance::new("localhost")?;
|
||||
let article = DbArticle::new(title, "dummy".to_string(), instance.ap_id)?;
|
||||
Ok(Json(article))
|
||||
}
|
|
@ -11,8 +11,9 @@ use activitypub_federation::{
|
|||
use serde::{Deserialize, Serialize};
|
||||
use url::Url;
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||
pub struct DbArticle {
|
||||
pub title: String,
|
||||
pub text: String,
|
||||
pub ap_id: ObjectId<DbArticle>,
|
||||
pub instance: ObjectId<DbInstance>,
|
||||
|
@ -20,9 +21,14 @@ pub struct DbArticle {
|
|||
}
|
||||
|
||||
impl DbArticle {
|
||||
pub fn new(text: String, attributed_to: ObjectId<DbInstance>) -> Result<DbArticle, Error> {
|
||||
pub fn new(
|
||||
title: String,
|
||||
text: String,
|
||||
attributed_to: ObjectId<DbInstance>,
|
||||
) -> Result<DbArticle, Error> {
|
||||
let ap_id = generate_object_id(attributed_to.inner())?.into();
|
||||
Ok(DbArticle {
|
||||
title,
|
||||
text,
|
||||
ap_id,
|
||||
instance: attributed_to,
|
||||
|
@ -41,6 +47,7 @@ pub struct Article {
|
|||
#[serde(deserialize_with = "deserialize_one_or_many")]
|
||||
pub(crate) to: Vec<Url>,
|
||||
content: String,
|
||||
name: String,
|
||||
}
|
||||
|
||||
#[async_trait::async_trait]
|
||||
|
@ -69,6 +76,7 @@ impl Object for DbArticle {
|
|||
attributed_to: self.instance,
|
||||
to: vec![public(), instance.followers_url()?],
|
||||
content: self.text,
|
||||
name: self.title,
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -83,6 +91,7 @@ impl Object for DbArticle {
|
|||
|
||||
async fn from_json(json: Self::Kind, data: &Data<Self::DataType>) -> Result<Self, Self::Error> {
|
||||
let post = DbArticle {
|
||||
title: json.name,
|
||||
text: json.content,
|
||||
ap_id: json.id,
|
||||
instance: json.attributed_to,
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use crate::database::DatabaseHandle;
|
||||
use crate::error::Error;
|
||||
use crate::error::MyResult;
|
||||
use crate::federation::objects::person::{DbUser, Person, PersonAcceptedActivities};
|
||||
use activitypub_federation::axum::inbox::{receive_activity, ActivityData};
|
||||
use activitypub_federation::axum::json::FederationJson;
|
||||
|
@ -14,7 +14,7 @@ use axum_macros::debug_handler;
|
|||
pub async fn http_get_user(
|
||||
Path(name): Path<String>,
|
||||
data: Data<DatabaseHandle>,
|
||||
) -> Result<FederationJson<WithContext<Person>>, Error> {
|
||||
) -> MyResult<FederationJson<WithContext<Person>>> {
|
||||
let db_user = data.read_user(&name)?;
|
||||
let json_user = db_user.into_json(&data).await?;
|
||||
Ok(FederationJson(WithContext::new_default(json_user)))
|
||||
|
|
52
src/lib.rs
Normal file
52
src/lib.rs
Normal file
|
@ -0,0 +1,52 @@
|
|||
use crate::utils::generate_object_id;
|
||||
use tracing::log::LevelFilter;
|
||||
|
||||
use activitypub_federation::config::FederationMiddleware;
|
||||
use axum::{
|
||||
routing::{get, post},
|
||||
Router, Server,
|
||||
};
|
||||
|
||||
use crate::api::api_get_article;
|
||||
use crate::error::MyResult;
|
||||
use crate::federation::routes::http_get_user;
|
||||
use crate::federation::routes::http_post_user_inbox;
|
||||
use federation::federation_config;
|
||||
use std::net::ToSocketAddrs;
|
||||
use tracing::info;
|
||||
|
||||
mod api;
|
||||
mod database;
|
||||
pub mod error;
|
||||
pub mod federation;
|
||||
mod utils;
|
||||
|
||||
pub async fn start(hostname: &str) -> MyResult<()> {
|
||||
env_logger::builder()
|
||||
.filter_level(LevelFilter::Warn)
|
||||
.filter_module("activitypub_federation", LevelFilter::Info)
|
||||
.filter_module("fediwiki", LevelFilter::Info)
|
||||
.init();
|
||||
|
||||
let config = federation_config(hostname).await?;
|
||||
|
||||
info!("Listening with axum on {hostname}");
|
||||
let config = config.clone();
|
||||
let app = Router::new()
|
||||
// federation routes
|
||||
.route("/:user/inbox", post(http_post_user_inbox))
|
||||
.route("/:user", get(http_get_user))
|
||||
// api routes
|
||||
.route("/api/v1/article/:title", get(api_get_article))
|
||||
.layer(FederationMiddleware::new(config));
|
||||
|
||||
let addr = hostname
|
||||
.to_socket_addrs()?
|
||||
.next()
|
||||
.expect("Failed to lookup domain name");
|
||||
let server = Server::bind(&addr).serve(app.into_make_service());
|
||||
|
||||
tokio::spawn(server);
|
||||
|
||||
Ok(())
|
||||
}
|
48
src/main.rs
48
src/main.rs
|
@ -1,48 +1,8 @@
|
|||
use crate::utils::generate_object_id;
|
||||
use error::Error;
|
||||
use tracing::log::LevelFilter;
|
||||
|
||||
use activitypub_federation::config::FederationMiddleware;
|
||||
use axum::{
|
||||
routing::{get, post},
|
||||
Router, Server,
|
||||
};
|
||||
|
||||
use crate::federation::routes::http_get_user;
|
||||
use crate::federation::routes::http_post_user_inbox;
|
||||
use federation::federation_config;
|
||||
use std::net::ToSocketAddrs;
|
||||
use tracing::info;
|
||||
|
||||
mod database;
|
||||
mod error;
|
||||
mod federation;
|
||||
mod utils;
|
||||
use fediwiki::error::MyResult;
|
||||
use fediwiki::start;
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() -> Result<(), Error> {
|
||||
env_logger::builder()
|
||||
.filter_level(LevelFilter::Warn)
|
||||
.filter_module("activitypub_federation", LevelFilter::Info)
|
||||
.filter_module("fediwiki", LevelFilter::Info)
|
||||
.init();
|
||||
|
||||
let config = federation_config("localhost:8001").await?;
|
||||
|
||||
let hostname = config.domain();
|
||||
info!("Listening with axum on {hostname}");
|
||||
let config = config.clone();
|
||||
let app = Router::new()
|
||||
.route("/:user/inbox", post(http_post_user_inbox))
|
||||
.route("/:user", get(http_get_user))
|
||||
.layer(FederationMiddleware::new(config));
|
||||
|
||||
let addr = hostname
|
||||
.to_socket_addrs()?
|
||||
.next()
|
||||
.expect("Failed to lookup domain name");
|
||||
let server = Server::bind(&addr).serve(app.into_make_service());
|
||||
|
||||
tokio::spawn(server);
|
||||
pub async fn main() -> MyResult<()> {
|
||||
start("localhost:8131").await?;
|
||||
Ok(())
|
||||
}
|
||||
|
|
22
tests/test.rs
Normal file
22
tests/test.rs
Normal file
|
@ -0,0 +1,22 @@
|
|||
extern crate fediwiki;
|
||||
use fediwiki::federation::objects::article::DbArticle;
|
||||
use fediwiki::start;
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_get_article() {
|
||||
let hostname = "localhost:8131";
|
||||
let join = tokio::task::spawn(async {
|
||||
start(hostname).await.unwrap();
|
||||
});
|
||||
|
||||
let title = "Manu_Chao";
|
||||
let res: DbArticle = reqwest::get(format!("http://{hostname}/api/v1/article/{title}"))
|
||||
.await
|
||||
.unwrap()
|
||||
.json()
|
||||
.await
|
||||
.unwrap();
|
||||
assert_eq!(title, res.title);
|
||||
assert!(res.local);
|
||||
join.abort();
|
||||
}
|
Loading…
Reference in a new issue