From 614086566055263d7d2590d2a4fa6f9348b66b3f Mon Sep 17 00:00:00 2001 From: Bat Date: Sat, 23 Jun 2018 12:14:03 +0100 Subject: [PATCH] Make Post::from_activity a bit more complete --- src/models/blogs.rs | 2 +- src/models/posts.rs | 38 +++++++++++++++++++++++++++++++------- src/models/users.rs | 2 +- 3 files changed, 33 insertions(+), 9 deletions(-) diff --git a/src/models/blogs.rs b/src/models/blogs.rs index fd5ec9b5..2d972c9e 100644 --- a/src/models/blogs.rs +++ b/src/models/blogs.rs @@ -229,7 +229,7 @@ impl Blog { // The requested user was not in the DB // We try to fetch it if it is remote if Url::parse(url.as_ref()).unwrap().host_str().unwrap() != BASE_URL.as_str() { - Some(Blog::fetch_from_url(conn, url).unwrap()) + Blog::fetch_from_url(conn, url) } else { None } diff --git a/src/models/posts.rs b/src/models/posts.rs index a15b0a10..81927154 100644 --- a/src/models/posts.rs +++ b/src/models/posts.rs @@ -5,6 +5,7 @@ use activitypub::{ }; use chrono::{NaiveDateTime, TimeZone, Utc}; use diesel::{self, PgConnection, RunQueryDsl, QueryDsl, ExpressionMethods, BelongingToDsl, dsl::any}; +use heck::KebabCase; use serde_json; use BASE_URL; @@ -17,7 +18,7 @@ use models::{ instance::Instance, likes::Like, mentions::Mention, - post_authors::PostAuthor, + post_authors::*, reshares::Reshare, users::User }; @@ -185,16 +186,39 @@ impl Post { impl FromActivity
for Post { fn from_activity(conn: &PgConnection, article: Article, _actor: Id) -> Post { + let (blog, authors) = article.object_props.attributed_to_link_vec::() + .expect("Post::from_activity: attributedTo error") + .into_iter() + .fold((None, vec![]), |(blog, mut authors), link| { + let url: String = link.into(); + match User::from_url(conn, url.clone()) { + Some(user) => { + authors.push(user); + (blog, authors) + }, + None => (blog.or_else(|| Blog::from_url(conn, url)), authors) + } + }); + + let title = article.object_props.name_string().expect("Post::from_activity: title error"); let post = Post::insert(conn, NewPost { - blog_id: 0, // TODO - slug: String::from(""), // TODO - title: article.object_props.name_string().unwrap(), - content: SafeString::new(&article.object_props.content_string().unwrap()), + blog_id: blog.expect("Received a new Article without a blog").id, + slug: title.to_kebab_case(), + title: title, + content: SafeString::new(&article.object_props.content_string().expect("Post::from_activity: content error")), published: true, - license: String::from("CC-0"), - ap_url: article.object_props.url_string().unwrap_or(String::from("")) + license: String::from("CC-0"), // TODO + // FIXME: This is wrong: with this logic, we may use the display URL as the AP ID. We need two different fields + ap_url: article.object_props.url_string().unwrap_or(article.object_props.id_string().expect("Post::from_activity: url + id error")) }); + for author in authors.into_iter() { + PostAuthor::insert(conn, NewPostAuthor { + post_id: post.id, + author_id: author.id + }); + } + // save mentions if let Some(serde_json::Value::Array(tags)) = article.object_props.tag.clone() { for tag in tags.into_iter() { diff --git a/src/models/users.rs b/src/models/users.rs index 4d036eb7..09be8e87 100644 --- a/src/models/users.rs +++ b/src/models/users.rs @@ -378,7 +378,7 @@ impl User { // The requested user was not in the DB // We try to fetch it if it is remote if Url::parse(url.as_ref()).unwrap().host_str().unwrap() != BASE_URL.as_str() { - Some(User::fetch_from_url(conn, url).unwrap()) + User::fetch_from_url(conn, url) } else { None }