diff options
author | Dessalines <tyhou13@gmx.com> | 2020-04-24 10:04:36 -0400 |
---|---|---|
committer | Dessalines <tyhou13@gmx.com> | 2020-04-24 10:04:36 -0400 |
commit | 66a2c4a2c38fdc90295c0ee2d599e0acecf8ad3f (patch) | |
tree | 92d48945d0d0f32d970b875e2ccc8c786e4a565b /server/src/apub/fetcher.rs | |
parent | e5497edd5c12b1355c82b224111bf7ce5bb1fd1e (diff) |
Some fed fixes.
Diffstat (limited to 'server/src/apub/fetcher.rs')
-rw-r--r-- | server/src/apub/fetcher.rs | 145 |
1 files changed, 85 insertions, 60 deletions
diff --git a/server/src/apub/fetcher.rs b/server/src/apub/fetcher.rs index 71453a2a..b4af70c9 100644 --- a/server/src/apub/fetcher.rs +++ b/server/src/apub/fetcher.rs @@ -1,23 +1,4 @@ -use crate::api::site::SearchResponse; -use crate::apub::*; -use crate::db::community::{Community, CommunityForm}; -use crate::db::community_view::CommunityView; -use crate::db::post::{Post, PostForm}; -use crate::db::post_view::PostView; -use crate::db::user::{UserForm, User_}; -use crate::db::user_view::UserView; -use crate::db::{Crud, SearchType}; -use crate::routes::nodeinfo::{NodeInfo, NodeInfoWellKnown}; -use activitystreams::collection::OrderedCollection; -use activitystreams::object::Page; -use activitystreams::BaseBox; -use diesel::result::Error::NotFound; -use diesel::PgConnection; -use failure::Error; -use isahc::prelude::*; -use serde::Deserialize; -use std::time::Duration; -use url::Url; +use super::*; // Fetch nodeinfo metadata from a remote instance. fn _fetch_node_info(domain: &str) -> Result<NodeInfo, Error> { @@ -30,26 +11,27 @@ fn _fetch_node_info(domain: &str) -> Result<NodeInfo, Error> { Ok(fetch_remote_object::<NodeInfo>(&well_known.links.href)?) } -// TODO: move these to db -fn upsert_community( - community_form: &CommunityForm, - conn: &PgConnection, -) -> Result<Community, Error> { - let existing = Community::read_from_actor_id(conn, &community_form.actor_id); - match existing { - Err(NotFound {}) => Ok(Community::create(conn, &community_form)?), - Ok(c) => Ok(Community::update(conn, c.id, &community_form)?), - Err(e) => Err(Error::from(e)), - } -} -fn upsert_user(user_form: &UserForm, conn: &PgConnection) -> Result<User_, Error> { - let existing = User_::read_from_apub_id(conn, &user_form.actor_id); - Ok(match existing { - Err(NotFound {}) => User_::create(conn, &user_form)?, - Ok(u) => User_::update(conn, u.id, &user_form)?, - Err(e) => return Err(Error::from(e)), - }) -} +// // TODO: move these to db +// // TODO use the last_refreshed_at +// fn upsert_community( +// community_form: &CommunityForm, +// conn: &PgConnection, +// ) -> Result<Community, Error> { +// let existing = Community::read_from_actor_id(conn, &community_form.actor_id); +// match existing { +// Err(NotFound {}) => Ok(Community::create(conn, &community_form)?), +// Ok(c) => Ok(Community::update(conn, c.id, &community_form)?), +// Err(e) => Err(Error::from(e)), +// } +// } +// fn upsert_user(user_form: &UserForm, conn: &PgConnection) -> Result<User_, Error> { +// let existing = User_::read_from_actor_id(conn, &user_form.actor_id); +// Ok(match existing { +// Err(NotFound {}) => User_::create(conn, &user_form)?, +// Ok(u) => User_::update(conn, u.id, &user_form)?, +// Err(e) => return Err(Error::from(e)), +// }) +// } fn upsert_post(post_form: &PostForm, conn: &PgConnection) -> Result<Post, Error> { let existing = Post::read_from_apub_id(conn, &post_form.ap_id); @@ -89,7 +71,7 @@ where pub enum SearchAcceptedObjects { Person(Box<PersonExt>), Group(Box<GroupExt>), - Page(Box<Page>), + // Page(Box<Page>), } /// Attempt to parse the query as URL, and fetch an ActivityPub object from it. @@ -109,22 +91,27 @@ pub fn search_by_apub_id(query: &str, conn: &PgConnection) -> Result<SearchRespo }; match fetch_remote_object::<SearchAcceptedObjects>(&query_url)? { SearchAcceptedObjects::Person(p) => { - let u = upsert_user(&UserForm::from_person(&p)?, conn)?; - response.users = vec![UserView::read(conn, u.id)?]; + let user = get_or_fetch_and_upsert_remote_user(query, &conn)?; + response.users = vec![UserView::read(conn, user.id)?]; } SearchAcceptedObjects::Group(g) => { - let c = upsert_community(&CommunityForm::from_group(&g, conn)?, conn)?; - fetch_community_outbox(&c, conn)?; - response.communities = vec![CommunityView::read(conn, c.id, None)?]; - } - SearchAcceptedObjects::Page(p) => { - let p = upsert_post(&PostForm::from_page(&p, conn)?, conn)?; - response.posts = vec![PostView::read(conn, p.id, None)?]; + let community = get_or_fetch_and_upsert_remote_community(query, &conn)?; + // fetch_community_outbox(&c, conn)?; + response.communities = vec![CommunityView::read(conn, community.id, None)?]; } + // SearchAcceptedObjects::Page(p) => { + // let p = upsert_post(&PostForm::from_page(&p, conn)?, conn)?; + // response.posts = vec![PostView::read(conn, p.id, None)?]; + // } } Ok(response) } +// 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())?; @@ -143,16 +130,54 @@ fn fetch_community_outbox(community: &Community, conn: &PgConnection) -> Result< ) } -/// Fetch a user, insert/update it in the database and return the user. -pub fn fetch_remote_user(apub_id: &Url, conn: &PgConnection) -> Result<User_, Error> { - let person = fetch_remote_object::<PersonExt>(apub_id)?; - let uf = UserForm::from_person(&person)?; - upsert_user(&uf, conn) +/// Check if a remote user exists, create if not found, if its too old update it.Fetch a user, insert/update it in the database and return the user. +pub fn get_or_fetch_and_upsert_remote_user(apub_id: &str, conn: &PgConnection) -> Result<User_, Error> { + match User_::read_from_actor_id(&conn, &apub_id) { + Ok(u) => { + // If its older than a day, re-fetch it + // TODO the less than needs to be tested + if u.last_refreshed_at.lt(&(naive_now() - chrono::Duration::days(1))) { + debug!("Fetching and updating from remote user: {}", apub_id); + let person = fetch_remote_object::<PersonExt>(&Url::parse(apub_id)?)?; + let uf = UserForm::from_person(&person)?; + uf.last_refreshed_at = Some(naive_now()); + Ok(User_::update(&conn, u.id, &uf)?) + } else { + Ok(u) + } + }, + Err(NotFound {}) => { + debug!("Fetching and creating remote user: {}", apub_id); + let person = fetch_remote_object::<PersonExt>(&Url::parse(apub_id)?)?; + let uf = UserForm::from_person(&person)?; + Ok(User_::create(conn, &uf)?) + } + Err(e) => Err(Error::from(e)), + } } -/// Fetch a community, insert/update it in the database and return the community. -pub fn fetch_remote_community(apub_id: &Url, conn: &PgConnection) -> Result<Community, Error> { - let group = fetch_remote_object::<GroupExt>(apub_id)?; - let cf = CommunityForm::from_group(&group, conn)?; - upsert_community(&cf, conn) +/// Check if a remote community exists, create if not found, if its too old update it.Fetch a community, insert/update it in the database and return the community. +pub fn get_or_fetch_and_upsert_remote_community(apub_id: &str, conn: &PgConnection) -> Result<Community, Error> { + match Community::read_from_actor_id(&conn, &apub_id) { + Ok(c) => { + // If its older than a day, re-fetch it + // TODO the less than needs to be tested + if c.last_refreshed_at.lt(&(naive_now() - chrono::Duration::days(1))) { + debug!("Fetching and updating from remote community: {}", apub_id); + let group = fetch_remote_object::<GroupExt>(&Url::parse(apub_id)?)?; + let cf = CommunityForm::from_group(&group, conn)?; + cf.last_refreshed_at = Some(naive_now()); + Ok(Community::update(&conn, c.id, &cf)?) + } else { + Ok(c) + } + }, + Err(NotFound {}) => { + debug!("Fetching and creating remote community: {}", apub_id); + let group = fetch_remote_object::<GroupExt>(&Url::parse(apub_id)?)?; + let cf = CommunityForm::from_group(&group, conn)?; + Ok(Community::create(conn, &cf)?) + } + Err(e) => Err(Error::from(e)), + } } |