mirror of
https://github.com/LemmyNet/lemmy.git
synced 2024-11-22 14:45:10 +00:00
Merge branch 'federation' into yerba_refactoring
This commit is contained in:
commit
3a4973ad68
|
@ -1,5 +1,24 @@
|
|||
use super::*;
|
||||
|
||||
#[derive(Deserialize)]
|
||||
pub struct CommentQuery {
|
||||
comment_id: String,
|
||||
}
|
||||
|
||||
/// Return the post json over HTTP.
|
||||
pub async fn get_apub_comment(
|
||||
info: Path<CommentQuery>,
|
||||
db: DbPoolParam,
|
||||
) -> Result<HttpResponse<Body>, Error> {
|
||||
let id = info.comment_id.parse::<i32>()?;
|
||||
let comment = Comment::read(&&db.get()?, id)?;
|
||||
if !comment.deleted {
|
||||
Ok(create_apub_response(&comment.to_apub(&db.get().unwrap())?))
|
||||
} else {
|
||||
Ok(create_apub_tombstone_response(&comment.to_tombstone()?))
|
||||
}
|
||||
}
|
||||
|
||||
impl ToApub for Comment {
|
||||
type Response = Note;
|
||||
|
||||
|
|
|
@ -40,6 +40,7 @@ pub enum SearchAcceptedObjects {
|
|||
Person(Box<PersonExt>),
|
||||
Group(Box<GroupExt>),
|
||||
Page(Box<PageExt>),
|
||||
Comment(Box<Note>),
|
||||
}
|
||||
|
||||
/// Attempt to parse the query as URL, and fetch an ActivityPub object from it.
|
||||
|
@ -47,7 +48,8 @@ pub enum SearchAcceptedObjects {
|
|||
/// Some working examples for use with the docker/federation/ setup:
|
||||
/// http://lemmy_alpha:8540/c/main, or !main@lemmy_alpha:8540
|
||||
/// http://lemmy_alpha:8540/u/lemmy_alpha, or @lemmy_alpha@lemmy_alpha:8540
|
||||
/// http://lemmy_alpha:8540/p/3
|
||||
/// http://lemmy_alpha:8540/post/3
|
||||
/// http://lemmy_alpha:8540/comment/2
|
||||
pub fn search_by_apub_id(query: &str, conn: &PgConnection) -> Result<SearchResponse, Error> {
|
||||
// Parse the shorthand query url
|
||||
let query_url = if query.contains('@') {
|
||||
|
@ -99,6 +101,20 @@ pub fn search_by_apub_id(query: &str, conn: &PgConnection) -> Result<SearchRespo
|
|||
let p = upsert_post(&PostForm::from_apub(&p, conn)?, conn)?;
|
||||
response.posts = vec![PostView::read(conn, p.id, None)?];
|
||||
}
|
||||
SearchAcceptedObjects::Comment(c) => {
|
||||
let post_url = c
|
||||
.object_props
|
||||
.get_many_in_reply_to_xsd_any_uris()
|
||||
.unwrap()
|
||||
.next()
|
||||
.unwrap()
|
||||
.to_string();
|
||||
// TODO: also fetch parent comments if any
|
||||
let post = fetch_remote_object(&Url::parse(&post_url)?)?;
|
||||
upsert_post(&PostForm::from_apub(&post, conn)?, conn)?;
|
||||
let c = upsert_comment(&CommentForm::from_apub(&c, conn)?, conn)?;
|
||||
response.comments = vec![CommentView::read(conn, c.id, None)?];
|
||||
}
|
||||
}
|
||||
Ok(response)
|
||||
}
|
||||
|
@ -197,3 +213,35 @@ fn upsert_post(post_form: &PostForm, conn: &PgConnection) -> Result<Post, Error>
|
|||
Err(e) => Err(Error::from(e)),
|
||||
}
|
||||
}
|
||||
|
||||
fn upsert_comment(comment_form: &CommentForm, conn: &PgConnection) -> Result<Comment, Error> {
|
||||
let existing = Comment::read_from_apub_id(conn, &comment_form.ap_id);
|
||||
match existing {
|
||||
Err(NotFound {}) => Ok(Comment::create(conn, &comment_form)?),
|
||||
Ok(p) => Ok(Comment::update(conn, p.id, &comment_form)?),
|
||||
Err(e) => Err(Error::from(e)),
|
||||
}
|
||||
}
|
||||
|
||||
// TODO It should not be fetching data from a community outbox.
|
||||
// All posts, comments, comment likes, etc should be posts to our community_inbox
|
||||
// The only data we should be periodically fetching (if it hasn't been fetched in the last day
|
||||
// maybe), is community and user actors
|
||||
// and user actors
|
||||
// Fetch all posts in the outbox of the given user, and insert them into the database.
|
||||
// fn fetch_community_outbox(community: &Community, conn: &PgConnection) -> Result<Vec<Post>, Error> {
|
||||
// let outbox_url = Url::parse(&community.get_outbox_url())?;
|
||||
// let outbox = fetch_remote_object::<OrderedCollection>(&outbox_url)?;
|
||||
// let items = outbox.collection_props.get_many_items_base_boxes();
|
||||
|
||||
// Ok(
|
||||
// items
|
||||
// .unwrap()
|
||||
// .map(|obox: &BaseBox| -> Result<PostForm, Error> {
|
||||
// let page = obox.clone().to_concrete::<Page>()?;
|
||||
// PostForm::from_page(&page, conn)
|
||||
// })
|
||||
// .map(|pf| upsert_post(&pf?, conn))
|
||||
// .collect::<Result<Vec<Post>, Error>>()?,
|
||||
// )
|
||||
// }
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
use super::*;
|
||||
use crate::apub::comment::get_apub_comment;
|
||||
use crate::apub::community::*;
|
||||
use crate::apub::community_inbox::community_inbox;
|
||||
use crate::apub::post::get_apub_post;
|
||||
|
@ -28,7 +29,8 @@ pub fn config(cfg: &mut web::ServiceConfig) {
|
|||
// web::get().to(get_apub_community_outbox),
|
||||
// )
|
||||
.route("/u/{user_name}", web::get().to(get_apub_user_http))
|
||||
.route("/post/{post_id}", web::get().to(get_apub_post)),
|
||||
.route("/post/{post_id}", web::get().to(get_apub_post))
|
||||
.route("/comment/{comment_id}", web::get().to(get_apub_comment)),
|
||||
)
|
||||
// Inboxes dont work with the header guard for some reason.
|
||||
.route("/c/{community_name}/inbox", web::post().to(community_inbox))
|
||||
|
|
32
ui/src/api_tests/api.spec.ts
vendored
32
ui/src/api_tests/api.spec.ts
vendored
|
@ -68,7 +68,7 @@ describe('main', () => {
|
|||
lemmyBetaAuth = resB.jwt;
|
||||
});
|
||||
|
||||
describe('beta_fetch', () => {
|
||||
describe('post_search', () => {
|
||||
test('Create test post on alpha and fetch it on beta', async () => {
|
||||
let name = 'A jest test post';
|
||||
let postForm: PostForm = {
|
||||
|
@ -1107,6 +1107,36 @@ describe('main', () => {
|
|||
expect(getPrivateMessagesUnDeletedRes.messages[0].deleted).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('comment_search', () => {
|
||||
test('Create comment on alpha and search it', async () => {
|
||||
let content = 'A jest test federated comment for search';
|
||||
let commentForm: CommentForm = {
|
||||
content,
|
||||
post_id: 1,
|
||||
auth: lemmyAlphaAuth,
|
||||
};
|
||||
|
||||
let createResponse: CommentResponse = await fetch(
|
||||
`${lemmyAlphaApiUrl}/comment`,
|
||||
{
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: wrapper(commentForm),
|
||||
}
|
||||
).then(d => d.json());
|
||||
|
||||
let searchUrl = `${lemmyBetaApiUrl}/search?q=${createResponse.comment.ap_id}&type_=All&sort=TopAll`;
|
||||
let searchResponse: SearchResponse = await fetch(searchUrl, {
|
||||
method: 'GET',
|
||||
}).then(d => d.json());
|
||||
|
||||
// TODO: check more fields
|
||||
expect(searchResponse.comments[0].content).toBe(content);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
function wrapper(form: any): string {
|
||||
|
|
Loading…
Reference in a new issue