Serve post data in apub format, some cleanup
This commit is contained in:
parent
48d237beb2
commit
0cfb0da9cd
5 changed files with 74 additions and 32 deletions
|
@ -1,4 +1,4 @@
|
||||||
use crate::apub::{create_apub_response, make_apub_endpoint};
|
use crate::apub::{create_apub_response, make_apub_endpoint, EndpointType};
|
||||||
use crate::convert_datetime;
|
use crate::convert_datetime;
|
||||||
use crate::db::community::Community;
|
use crate::db::community::Community;
|
||||||
use crate::db::community_view::CommunityFollowerView;
|
use crate::db::community_view::CommunityFollowerView;
|
||||||
|
@ -28,7 +28,7 @@ pub async fn get_apub_community(
|
||||||
db: web::Data<Pool<ConnectionManager<PgConnection>>>,
|
db: web::Data<Pool<ConnectionManager<PgConnection>>>,
|
||||||
) -> Result<HttpResponse<Body>, Error> {
|
) -> Result<HttpResponse<Body>, Error> {
|
||||||
let community = Community::read_from_name(&&db.get()?, info.community_name.to_owned())?;
|
let community = Community::read_from_name(&&db.get()?, info.community_name.to_owned())?;
|
||||||
let base_url = make_apub_endpoint("c", &community.name);
|
let base_url = make_apub_endpoint(EndpointType::Community, &community.name);
|
||||||
|
|
||||||
let mut group = Group::default();
|
let mut group = Group::default();
|
||||||
let oprops: &mut ObjectProperties = group.as_mut();
|
let oprops: &mut ObjectProperties = group.as_mut();
|
||||||
|
@ -38,7 +38,10 @@ pub async fn get_apub_community(
|
||||||
.set_id(base_url.to_owned())?
|
.set_id(base_url.to_owned())?
|
||||||
.set_name_xsd_string(community.title.to_owned())?
|
.set_name_xsd_string(community.title.to_owned())?
|
||||||
.set_published(convert_datetime(community.published))?
|
.set_published(convert_datetime(community.published))?
|
||||||
.set_attributed_to_xsd_any_uri(make_apub_endpoint("u", &community.creator_id))?;
|
.set_attributed_to_xsd_any_uri(make_apub_endpoint(
|
||||||
|
EndpointType::User,
|
||||||
|
&community.creator_id.to_string(),
|
||||||
|
))?;
|
||||||
|
|
||||||
if let Some(u) = community.updated.to_owned() {
|
if let Some(u) = community.updated.to_owned() {
|
||||||
oprops.set_updated(convert_datetime(u))?;
|
oprops.set_updated(convert_datetime(u))?;
|
||||||
|
@ -61,7 +64,7 @@ pub async fn get_apub_community_followers(
|
||||||
db: web::Data<Pool<ConnectionManager<PgConnection>>>,
|
db: web::Data<Pool<ConnectionManager<PgConnection>>>,
|
||||||
) -> Result<HttpResponse<Body>, Error> {
|
) -> Result<HttpResponse<Body>, Error> {
|
||||||
let community = Community::read_from_name(&&db.get()?, info.community_name.to_owned())?;
|
let community = Community::read_from_name(&&db.get()?, info.community_name.to_owned())?;
|
||||||
let base_url = make_apub_endpoint("c", &community.name);
|
let base_url = make_apub_endpoint(EndpointType::Community, &community.name);
|
||||||
|
|
||||||
let connection = establish_unpooled_connection();
|
let connection = establish_unpooled_connection();
|
||||||
//As we are an object, we validated that the community id was valid
|
//As we are an object, we validated that the community id was valid
|
||||||
|
@ -84,7 +87,7 @@ pub async fn get_apub_community_outbox(
|
||||||
db: web::Data<Pool<ConnectionManager<PgConnection>>>,
|
db: web::Data<Pool<ConnectionManager<PgConnection>>>,
|
||||||
) -> Result<HttpResponse<Body>, Error> {
|
) -> Result<HttpResponse<Body>, Error> {
|
||||||
let community = Community::read_from_name(&&db.get()?, info.community_name.to_owned())?;
|
let community = Community::read_from_name(&&db.get()?, info.community_name.to_owned())?;
|
||||||
let base_url = make_apub_endpoint("c", &community.name);
|
let base_url = make_apub_endpoint(EndpointType::Community, &community.name);
|
||||||
|
|
||||||
let connection = establish_unpooled_connection();
|
let connection = establish_unpooled_connection();
|
||||||
//As we are an object, we validated that the community id was valid
|
//As we are an object, we validated that the community id was valid
|
||||||
|
|
|
@ -6,7 +6,6 @@ use crate::Settings;
|
||||||
|
|
||||||
use actix_web::body::Body;
|
use actix_web::body::Body;
|
||||||
use actix_web::HttpResponse;
|
use actix_web::HttpResponse;
|
||||||
use std::fmt::Display;
|
|
||||||
use url::Url;
|
use url::Url;
|
||||||
|
|
||||||
fn create_apub_response(json_data: String) -> HttpResponse<Body> {
|
fn create_apub_response(json_data: String) -> HttpResponse<Body> {
|
||||||
|
@ -15,15 +14,25 @@ fn create_apub_response(json_data: String) -> HttpResponse<Body> {
|
||||||
.body(json_data)
|
.body(json_data)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: this should take an enum community/user/post for `point`
|
enum EndpointType {
|
||||||
// TODO: also not sure what exactly `value` should be (numeric id, name string, ...)
|
Community,
|
||||||
fn make_apub_endpoint<S: Display, T: Display>(point: S, value: T) -> Url {
|
User,
|
||||||
|
Post,
|
||||||
|
}
|
||||||
|
|
||||||
|
fn make_apub_endpoint(endpoint_type: EndpointType, name: &str) -> Url {
|
||||||
|
let point = match endpoint_type {
|
||||||
|
EndpointType::Community => "c",
|
||||||
|
EndpointType::User => "u",
|
||||||
|
EndpointType::Post => "p",
|
||||||
|
};
|
||||||
|
|
||||||
Url::parse(&format!(
|
Url::parse(&format!(
|
||||||
"{}://{}/federation/{}/{}",
|
"{}://{}/federation/{}/{}",
|
||||||
get_apub_protocol_string(),
|
get_apub_protocol_string(),
|
||||||
Settings::get().hostname,
|
Settings::get().hostname,
|
||||||
point,
|
point,
|
||||||
value
|
name
|
||||||
))
|
))
|
||||||
.unwrap()
|
.unwrap()
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,12 +1,35 @@
|
||||||
use crate::apub::make_apub_endpoint;
|
use crate::apub::{create_apub_response, make_apub_endpoint, EndpointType};
|
||||||
use crate::convert_datetime;
|
use crate::convert_datetime;
|
||||||
use crate::db::post_view::PostView;
|
use crate::db::post_view::PostView;
|
||||||
use activitystreams::{object::apub::Page, object::properties::ObjectProperties};
|
use activitystreams::{object::apub::Page, object::properties::ObjectProperties};
|
||||||
|
use actix_web::body::Body;
|
||||||
|
use actix_web::web::Path;
|
||||||
|
use actix_web::{web, HttpResponse};
|
||||||
|
use diesel::r2d2::{ConnectionManager, Pool};
|
||||||
|
use diesel::PgConnection;
|
||||||
use failure::Error;
|
use failure::Error;
|
||||||
|
use serde::Deserialize;
|
||||||
|
|
||||||
|
#[derive(Deserialize)]
|
||||||
|
pub struct PostQuery {
|
||||||
|
post_id: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn get_apub_post(
|
||||||
|
info: Path<PostQuery>,
|
||||||
|
db: web::Data<Pool<ConnectionManager<PgConnection>>>,
|
||||||
|
) -> Result<HttpResponse<Body>, Error> {
|
||||||
|
let id = info.post_id.parse::<i32>()?;
|
||||||
|
// TODO: shows error: missing field `user_name`
|
||||||
|
let post = PostView::read(&&db.get()?, id, None)?;
|
||||||
|
Ok(create_apub_response(serde_json::to_string(
|
||||||
|
&post.as_page()?,
|
||||||
|
)?))
|
||||||
|
}
|
||||||
|
|
||||||
impl PostView {
|
impl PostView {
|
||||||
pub fn as_page(&self) -> Result<Page, Error> {
|
pub fn as_page(&self) -> Result<Page, Error> {
|
||||||
let base_url = make_apub_endpoint("post", self.id);
|
let base_url = make_apub_endpoint(EndpointType::Post, &self.id.to_string());
|
||||||
let mut page = Page::default();
|
let mut page = Page::default();
|
||||||
let oprops: &mut ObjectProperties = page.as_mut();
|
let oprops: &mut ObjectProperties = page.as_mut();
|
||||||
|
|
||||||
|
@ -16,16 +39,20 @@ impl PostView {
|
||||||
.set_id(base_url)?
|
.set_id(base_url)?
|
||||||
.set_name_xsd_string(self.name.to_owned())?
|
.set_name_xsd_string(self.name.to_owned())?
|
||||||
.set_published(convert_datetime(self.published))?
|
.set_published(convert_datetime(self.published))?
|
||||||
.set_attributed_to_xsd_any_uri(make_apub_endpoint("u", &self.creator_id))?;
|
.set_attributed_to_xsd_any_uri(make_apub_endpoint(
|
||||||
|
EndpointType::User,
|
||||||
|
&self.creator_id.to_string(),
|
||||||
|
))?;
|
||||||
|
|
||||||
if let Some(body) = &self.body {
|
if let Some(body) = &self.body {
|
||||||
oprops.set_content_xsd_string(body.to_owned())?;
|
oprops.set_content_xsd_string(body.to_owned())?;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: hacky code because we get self.url == Some("")
|
// TODO: hacky code because we get self.url == Some("")
|
||||||
let url = self.url.as_ref();
|
// https://github.com/dessalines/lemmy/issues/602
|
||||||
if url.is_some() && !url.unwrap().is_empty() {
|
let url = self.url.as_ref().filter(|u| !u.is_empty());
|
||||||
oprops.set_url_xsd_any_uri(url.unwrap().to_owned())?;
|
if let Some(u) = url {
|
||||||
|
oprops.set_url_xsd_any_uri(u.to_owned())?;
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(u) = self.updated {
|
if let Some(u) = self.updated {
|
||||||
|
@ -35,5 +62,3 @@ impl PostView {
|
||||||
Ok(page)
|
Ok(page)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: need to serve this via actix
|
|
||||||
|
|
|
@ -1,15 +1,15 @@
|
||||||
use crate::apub::{make_apub_endpoint, create_apub_response};
|
use crate::apub::{create_apub_response, make_apub_endpoint, EndpointType};
|
||||||
use crate::convert_datetime;
|
use crate::convert_datetime;
|
||||||
use crate::db::user::User_;
|
use crate::db::user::User_;
|
||||||
use activitystreams::{actor::apub::Person, context, object::properties::ObjectProperties};
|
use activitystreams::{actor::apub::Person, context, object::properties::ObjectProperties};
|
||||||
use actix_web::body::Body;
|
use actix_web::body::Body;
|
||||||
use actix_web::web::Path;
|
use actix_web::web::Path;
|
||||||
use actix_web::HttpResponse;
|
use actix_web::HttpResponse;
|
||||||
use failure::Error;
|
use actix_web::{web, Result};
|
||||||
use serde::Deserialize;
|
|
||||||
use diesel::r2d2::{ConnectionManager, Pool};
|
use diesel::r2d2::{ConnectionManager, Pool};
|
||||||
use diesel::PgConnection;
|
use diesel::PgConnection;
|
||||||
use actix_web::{web, Result};
|
use failure::Error;
|
||||||
|
use serde::Deserialize;
|
||||||
|
|
||||||
#[derive(Deserialize)]
|
#[derive(Deserialize)]
|
||||||
pub struct UserQuery {
|
pub struct UserQuery {
|
||||||
|
@ -18,16 +18,17 @@ pub struct UserQuery {
|
||||||
|
|
||||||
pub async fn get_apub_user(
|
pub async fn get_apub_user(
|
||||||
info: Path<UserQuery>,
|
info: Path<UserQuery>,
|
||||||
db: web::Data<Pool<ConnectionManager<PgConnection>>>,) -> Result<HttpResponse<Body>, Error> {
|
db: web::Data<Pool<ConnectionManager<PgConnection>>>,
|
||||||
|
) -> Result<HttpResponse<Body>, Error> {
|
||||||
let user = User_::find_by_email_or_username(&&db.get()?, &info.user_name)?;
|
let user = User_::find_by_email_or_username(&&db.get()?, &info.user_name)?;
|
||||||
let base_url = make_apub_endpoint("u", &user.name);
|
let base_url = make_apub_endpoint(EndpointType::User, &user.name);
|
||||||
|
|
||||||
let mut person = Person::default();
|
let mut person = Person::default();
|
||||||
let oprops: &mut ObjectProperties = person.as_mut();
|
let oprops: &mut ObjectProperties = person.as_mut();
|
||||||
oprops
|
oprops
|
||||||
.set_context_xsd_any_uri(context())?
|
.set_context_xsd_any_uri(context())?
|
||||||
.set_id(base_url.to_string())?
|
.set_id(base_url.to_string())?
|
||||||
.set_published(convert_datetime(user.published))?;
|
.set_published(convert_datetime(user.published))?;
|
||||||
|
|
||||||
if let Some(u) = user.updated {
|
if let Some(u) = user.updated {
|
||||||
oprops.set_updated(convert_datetime(u))?;
|
oprops.set_updated(convert_datetime(u))?;
|
||||||
|
@ -38,11 +39,11 @@ pub async fn get_apub_user(
|
||||||
}
|
}
|
||||||
|
|
||||||
person
|
person
|
||||||
.ap_actor_props
|
.ap_actor_props
|
||||||
.set_inbox(format!("{}/inbox", &base_url))?
|
.set_inbox(format!("{}/inbox", &base_url))?
|
||||||
.set_outbox(format!("{}/outbox", &base_url))?
|
.set_outbox(format!("{}/outbox", &base_url))?
|
||||||
.set_following(format!("{}/following", &base_url))?
|
.set_following(format!("{}/following", &base_url))?
|
||||||
.set_liked(format!("{}/liked", &base_url))?;
|
.set_liked(format!("{}/liked", &base_url))?;
|
||||||
|
|
||||||
Ok(create_apub_response(serde_json::to_string(&person)?))
|
Ok(create_apub_response(serde_json::to_string(&person)?))
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,6 +28,10 @@ pub fn config(cfg: &mut web::ServiceConfig) {
|
||||||
"/federation/u/{user_name}",
|
"/federation/u/{user_name}",
|
||||||
web::get().to(apub::user::get_apub_user),
|
web::get().to(apub::user::get_apub_user),
|
||||||
)
|
)
|
||||||
|
.route(
|
||||||
|
"/federation/p/{post_id}",
|
||||||
|
web::get().to(apub::user::get_apub_user),
|
||||||
|
)
|
||||||
// TODO: we should be able to remove this but somehow that breaks the remote community list
|
// TODO: we should be able to remove this but somehow that breaks the remote community list
|
||||||
.route(
|
.route(
|
||||||
"/api/v1/communities/list",
|
"/api/v1/communities/list",
|
||||||
|
|
Reference in a new issue