If viewed actor isnt in db, fetch it from other instance (#2145)
This commit is contained in:
parent
0c63dbafb6
commit
8112816e99
23 changed files with 100 additions and 57 deletions
|
@ -8,11 +8,16 @@ use lemmy_api_common::{
|
||||||
get_local_user_view_from_jwt,
|
get_local_user_view_from_jwt,
|
||||||
get_local_user_view_from_jwt_opt,
|
get_local_user_view_from_jwt_opt,
|
||||||
is_admin,
|
is_admin,
|
||||||
resolve_actor_identifier,
|
|
||||||
send_application_approved_email,
|
send_application_approved_email,
|
||||||
site::*,
|
site::*,
|
||||||
};
|
};
|
||||||
use lemmy_apub::fetcher::search::{search_by_apub_id, SearchableObjects};
|
use lemmy_apub::{
|
||||||
|
fetcher::{
|
||||||
|
resolve_actor_identifier,
|
||||||
|
search::{search_by_apub_id, SearchableObjects},
|
||||||
|
},
|
||||||
|
objects::community::ApubCommunity,
|
||||||
|
};
|
||||||
use lemmy_db_schema::{
|
use lemmy_db_schema::{
|
||||||
diesel_option_overwrite,
|
diesel_option_overwrite,
|
||||||
from_opt_str_to_opt_enum,
|
from_opt_str_to_opt_enum,
|
||||||
|
@ -197,7 +202,7 @@ impl Perform for Search {
|
||||||
let search_type: SearchType = from_opt_str_to_opt_enum(&data.type_).unwrap_or(SearchType::All);
|
let search_type: SearchType = from_opt_str_to_opt_enum(&data.type_).unwrap_or(SearchType::All);
|
||||||
let community_id = data.community_id;
|
let community_id = data.community_id;
|
||||||
let community_actor_id = if let Some(name) = &data.community_name {
|
let community_actor_id = if let Some(name) = &data.community_name {
|
||||||
resolve_actor_identifier::<Community>(name, context.pool())
|
resolve_actor_identifier::<ApubCommunity, Community>(name, context)
|
||||||
.await
|
.await
|
||||||
.ok()
|
.ok()
|
||||||
.map(|c| c.actor_id)
|
.map(|c| c.actor_id)
|
||||||
|
|
|
@ -6,7 +6,6 @@ pub mod site;
|
||||||
pub mod websocket;
|
pub mod websocket;
|
||||||
|
|
||||||
use crate::site::FederatedInstances;
|
use crate::site::FederatedInstances;
|
||||||
use itertools::Itertools;
|
|
||||||
use lemmy_db_schema::{
|
use lemmy_db_schema::{
|
||||||
newtypes::{CommunityId, LocalUserId, PersonId, PostId},
|
newtypes::{CommunityId, LocalUserId, PersonId, PostId},
|
||||||
source::{
|
source::{
|
||||||
|
@ -20,7 +19,7 @@ use lemmy_db_schema::{
|
||||||
secret::Secret,
|
secret::Secret,
|
||||||
site::Site,
|
site::Site,
|
||||||
},
|
},
|
||||||
traits::{ApubActor, Crud, Readable},
|
traits::{Crud, Readable},
|
||||||
DbPool,
|
DbPool,
|
||||||
};
|
};
|
||||||
use lemmy_db_views::{
|
use lemmy_db_views::{
|
||||||
|
@ -522,39 +521,6 @@ pub async fn check_private_instance_and_federation_enabled(
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Resolve actor identifier (eg `!news@example.com`) from local database to avoid network requests.
|
|
||||||
/// This only works for local actors, and remote actors which were previously fetched (so it doesnt
|
|
||||||
/// trigger any new fetch).
|
|
||||||
#[tracing::instrument(skip_all)]
|
|
||||||
pub async fn resolve_actor_identifier<Actor>(
|
|
||||||
identifier: &str,
|
|
||||||
pool: &DbPool,
|
|
||||||
) -> Result<Actor, LemmyError>
|
|
||||||
where
|
|
||||||
Actor: ApubActor + Send + 'static,
|
|
||||||
{
|
|
||||||
// remote actor
|
|
||||||
if identifier.contains('@') {
|
|
||||||
let (name, domain) = identifier
|
|
||||||
.splitn(2, '@')
|
|
||||||
.collect_tuple()
|
|
||||||
.expect("invalid query");
|
|
||||||
let name = name.to_string();
|
|
||||||
let domain = format!("{}://{}", Settings::get().get_protocol_string(), domain);
|
|
||||||
Ok(
|
|
||||||
blocking(pool, move |conn| {
|
|
||||||
Actor::read_from_name_and_domain(conn, &name, &domain)
|
|
||||||
})
|
|
||||||
.await??,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
// local actor
|
|
||||||
else {
|
|
||||||
let identifier = identifier.to_string();
|
|
||||||
Ok(blocking(pool, move |conn| Actor::read_from_name(conn, &identifier)).await??)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub async fn remove_user_data(banned_person_id: PersonId, pool: &DbPool) -> Result<(), LemmyError> {
|
pub async fn remove_user_data(banned_person_id: PersonId, pool: &DbPool) -> Result<(), LemmyError> {
|
||||||
// Posts
|
// Posts
|
||||||
blocking(pool, move |conn: &'_ _| {
|
blocking(pool, move |conn: &'_ _| {
|
||||||
|
|
|
@ -5,8 +5,8 @@ use lemmy_api_common::{
|
||||||
check_private_instance,
|
check_private_instance,
|
||||||
comment::*,
|
comment::*,
|
||||||
get_local_user_view_from_jwt_opt,
|
get_local_user_view_from_jwt_opt,
|
||||||
resolve_actor_identifier,
|
|
||||||
};
|
};
|
||||||
|
use lemmy_apub::{fetcher::resolve_actor_identifier, objects::community::ApubCommunity};
|
||||||
use lemmy_db_schema::{
|
use lemmy_db_schema::{
|
||||||
from_opt_str_to_opt_enum,
|
from_opt_str_to_opt_enum,
|
||||||
source::community::Community,
|
source::community::Community,
|
||||||
|
@ -78,7 +78,7 @@ impl PerformCrud for GetComments {
|
||||||
|
|
||||||
let community_id = data.community_id;
|
let community_id = data.community_id;
|
||||||
let community_actor_id = if let Some(name) = &data.community_name {
|
let community_actor_id = if let Some(name) = &data.community_name {
|
||||||
resolve_actor_identifier::<Community>(name, context.pool())
|
resolve_actor_identifier::<ApubCommunity, Community>(name, context)
|
||||||
.await
|
.await
|
||||||
.ok()
|
.ok()
|
||||||
.map(|c| c.actor_id)
|
.map(|c| c.actor_id)
|
||||||
|
|
|
@ -5,8 +5,8 @@ use lemmy_api_common::{
|
||||||
check_private_instance,
|
check_private_instance,
|
||||||
community::*,
|
community::*,
|
||||||
get_local_user_view_from_jwt_opt,
|
get_local_user_view_from_jwt_opt,
|
||||||
resolve_actor_identifier,
|
|
||||||
};
|
};
|
||||||
|
use lemmy_apub::{fetcher::resolve_actor_identifier, objects::community::ApubCommunity};
|
||||||
use lemmy_db_schema::{
|
use lemmy_db_schema::{
|
||||||
from_opt_str_to_opt_enum,
|
from_opt_str_to_opt_enum,
|
||||||
source::community::Community,
|
source::community::Community,
|
||||||
|
@ -44,7 +44,7 @@ impl PerformCrud for GetCommunity {
|
||||||
Some(id) => id,
|
Some(id) => id,
|
||||||
None => {
|
None => {
|
||||||
let name = data.name.to_owned().unwrap_or_else(|| "main".to_string());
|
let name = data.name.to_owned().unwrap_or_else(|| "main".to_string());
|
||||||
resolve_actor_identifier::<Community>(&name, context.pool())
|
resolve_actor_identifier::<ApubCommunity, Community>(&name, context)
|
||||||
.await
|
.await
|
||||||
.map_err(|e| e.with_message("couldnt_find_community"))?
|
.map_err(|e| e.with_message("couldnt_find_community"))?
|
||||||
.id
|
.id
|
||||||
|
|
|
@ -6,8 +6,8 @@ use lemmy_api_common::{
|
||||||
get_local_user_view_from_jwt_opt,
|
get_local_user_view_from_jwt_opt,
|
||||||
mark_post_as_read,
|
mark_post_as_read,
|
||||||
post::*,
|
post::*,
|
||||||
resolve_actor_identifier,
|
|
||||||
};
|
};
|
||||||
|
use lemmy_apub::{fetcher::resolve_actor_identifier, objects::community::ApubCommunity};
|
||||||
use lemmy_db_schema::{
|
use lemmy_db_schema::{
|
||||||
from_opt_str_to_opt_enum,
|
from_opt_str_to_opt_enum,
|
||||||
source::community::Community,
|
source::community::Community,
|
||||||
|
@ -152,7 +152,7 @@ impl PerformCrud for GetPosts {
|
||||||
let limit = data.limit;
|
let limit = data.limit;
|
||||||
let community_id = data.community_id;
|
let community_id = data.community_id;
|
||||||
let community_actor_id = if let Some(name) = &data.community_name {
|
let community_actor_id = if let Some(name) = &data.community_name {
|
||||||
resolve_actor_identifier::<Community>(name, context.pool())
|
resolve_actor_identifier::<ApubCommunity, Community>(name, context)
|
||||||
.await
|
.await
|
||||||
.ok()
|
.ok()
|
||||||
.map(|c| c.actor_id)
|
.map(|c| c.actor_id)
|
||||||
|
|
|
@ -5,8 +5,8 @@ use lemmy_api_common::{
|
||||||
check_private_instance,
|
check_private_instance,
|
||||||
get_local_user_view_from_jwt_opt,
|
get_local_user_view_from_jwt_opt,
|
||||||
person::*,
|
person::*,
|
||||||
resolve_actor_identifier,
|
|
||||||
};
|
};
|
||||||
|
use lemmy_apub::{fetcher::resolve_actor_identifier, objects::person::ApubPerson};
|
||||||
use lemmy_db_schema::{from_opt_str_to_opt_enum, source::person::Person, SortType};
|
use lemmy_db_schema::{from_opt_str_to_opt_enum, source::person::Person, SortType};
|
||||||
use lemmy_db_views::{comment_view::CommentQueryBuilder, post_view::PostQueryBuilder};
|
use lemmy_db_views::{comment_view::CommentQueryBuilder, post_view::PostQueryBuilder};
|
||||||
use lemmy_db_views_actor::{
|
use lemmy_db_views_actor::{
|
||||||
|
@ -51,7 +51,7 @@ impl PerformCrud for GetPersonDetails {
|
||||||
.to_owned()
|
.to_owned()
|
||||||
.unwrap_or_else(|| "admin".to_string());
|
.unwrap_or_else(|| "admin".to_string());
|
||||||
|
|
||||||
resolve_actor_identifier::<Person>(&name, context.pool())
|
resolve_actor_identifier::<ApubPerson, Person>(&name, context)
|
||||||
.await
|
.await
|
||||||
.map_err(|e| e.with_message("couldnt_find_that_username_or_email"))?
|
.map_err(|e| e.with_message("couldnt_find_that_username_or_email"))?
|
||||||
.id
|
.id
|
||||||
|
|
|
@ -34,6 +34,7 @@ pub enum InstanceOrGroup {
|
||||||
impl ApubObject for SiteOrCommunity {
|
impl ApubObject for SiteOrCommunity {
|
||||||
type DataType = LemmyContext;
|
type DataType = LemmyContext;
|
||||||
type ApubType = InstanceOrGroup;
|
type ApubType = InstanceOrGroup;
|
||||||
|
type DbType = ();
|
||||||
type TombstoneType = ();
|
type TombstoneType = ();
|
||||||
|
|
||||||
#[tracing::instrument(skip_all)]
|
#[tracing::instrument(skip_all)]
|
||||||
|
|
|
@ -133,6 +133,8 @@ impl ApubObject for ApubCommunityModerators {
|
||||||
// This return value is unused, so just set an empty vec
|
// This return value is unused, so just set an empty vec
|
||||||
Ok(ApubCommunityModerators { 0: vec![] })
|
Ok(ApubCommunityModerators { 0: vec![] })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type DbType = ();
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
|
|
@ -118,4 +118,6 @@ impl ApubObject for ApubCommunityOutbox {
|
||||||
// This return value is unused, so just set an empty vec
|
// This return value is unused, so just set an empty vec
|
||||||
Ok(ApubCommunityOutbox { 0: vec![] })
|
Ok(ApubCommunityOutbox { 0: vec![] })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type DbType = ();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,63 @@
|
||||||
|
use crate::fetcher::webfinger::webfinger_resolve_actor;
|
||||||
|
use itertools::Itertools;
|
||||||
|
use lemmy_api_common::blocking;
|
||||||
|
use lemmy_apub_lib::traits::{ActorType, ApubObject};
|
||||||
|
use lemmy_db_schema::traits::ApubActor;
|
||||||
|
use lemmy_utils::{settings::structs::Settings, LemmyError};
|
||||||
|
use lemmy_websocket::LemmyContext;
|
||||||
|
|
||||||
pub mod post_or_comment;
|
pub mod post_or_comment;
|
||||||
pub mod search;
|
pub mod search;
|
||||||
pub mod user_or_community;
|
pub mod user_or_community;
|
||||||
pub mod webfinger;
|
pub mod webfinger;
|
||||||
|
|
||||||
|
/// Resolve actor identifier (eg `!news@example.com`) from local database to avoid network requests.
|
||||||
|
/// This only works for local actors, and remote actors which were previously fetched (so it doesnt
|
||||||
|
/// trigger any new fetch).
|
||||||
|
#[tracing::instrument(skip_all)]
|
||||||
|
pub async fn resolve_actor_identifier<Actor, DbActor>(
|
||||||
|
identifier: &str,
|
||||||
|
context: &LemmyContext,
|
||||||
|
) -> Result<DbActor, LemmyError>
|
||||||
|
where
|
||||||
|
Actor:
|
||||||
|
ApubObject<DataType = LemmyContext> + ApubObject<DbType = DbActor> + ActorType + Send + 'static,
|
||||||
|
for<'de2> <Actor as ApubObject>::ApubType: serde::Deserialize<'de2>,
|
||||||
|
DbActor: ApubActor + Send + 'static,
|
||||||
|
{
|
||||||
|
// remote actor
|
||||||
|
if identifier.contains('@') {
|
||||||
|
let (name, domain) = identifier
|
||||||
|
.splitn(2, '@')
|
||||||
|
.collect_tuple()
|
||||||
|
.expect("invalid query");
|
||||||
|
let name = name.to_string();
|
||||||
|
let domain = format!("{}://{}", Settings::get().get_protocol_string(), domain);
|
||||||
|
let actor = blocking(context.pool(), move |conn| {
|
||||||
|
DbActor::read_from_name_and_domain(conn, &name, &domain)
|
||||||
|
})
|
||||||
|
.await?;
|
||||||
|
if actor.is_ok() {
|
||||||
|
Ok(actor?)
|
||||||
|
} else {
|
||||||
|
// Fetch the actor from its home instance using webfinger
|
||||||
|
let id = webfinger_resolve_actor::<Actor>(identifier, context, &mut 0).await?;
|
||||||
|
let actor: DbActor = blocking(context.pool(), move |conn| {
|
||||||
|
DbActor::read_from_apub_id(conn, &id)
|
||||||
|
})
|
||||||
|
.await??
|
||||||
|
.expect("actor exists as we fetched just before");
|
||||||
|
Ok(actor)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// local actor
|
||||||
|
else {
|
||||||
|
let identifier = identifier.to_string();
|
||||||
|
Ok(
|
||||||
|
blocking(context.pool(), move |conn| {
|
||||||
|
DbActor::read_from_name(conn, &identifier)
|
||||||
|
})
|
||||||
|
.await??,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -26,6 +26,7 @@ pub enum PageOrNote {
|
||||||
impl ApubObject for PostOrComment {
|
impl ApubObject for PostOrComment {
|
||||||
type DataType = LemmyContext;
|
type DataType = LemmyContext;
|
||||||
type ApubType = PageOrNote;
|
type ApubType = PageOrNote;
|
||||||
|
type DbType = ();
|
||||||
type TombstoneType = ();
|
type TombstoneType = ();
|
||||||
|
|
||||||
fn last_refreshed_at(&self) -> Option<NaiveDateTime> {
|
fn last_refreshed_at(&self) -> Option<NaiveDateTime> {
|
||||||
|
|
|
@ -78,6 +78,7 @@ pub enum SearchableApubTypes {
|
||||||
impl ApubObject for SearchableObjects {
|
impl ApubObject for SearchableObjects {
|
||||||
type DataType = LemmyContext;
|
type DataType = LemmyContext;
|
||||||
type ApubType = SearchableApubTypes;
|
type ApubType = SearchableApubTypes;
|
||||||
|
type DbType = ();
|
||||||
type TombstoneType = ();
|
type TombstoneType = ();
|
||||||
|
|
||||||
fn last_refreshed_at(&self) -> Option<NaiveDateTime> {
|
fn last_refreshed_at(&self) -> Option<NaiveDateTime> {
|
||||||
|
|
|
@ -26,6 +26,7 @@ pub enum PersonOrGroup {
|
||||||
impl ApubObject for UserOrCommunity {
|
impl ApubObject for UserOrCommunity {
|
||||||
type DataType = LemmyContext;
|
type DataType = LemmyContext;
|
||||||
type ApubType = PersonOrGroup;
|
type ApubType = PersonOrGroup;
|
||||||
|
type DbType = ();
|
||||||
type TombstoneType = ();
|
type TombstoneType = ();
|
||||||
|
|
||||||
fn last_refreshed_at(&self) -> Option<NaiveDateTime> {
|
fn last_refreshed_at(&self) -> Option<NaiveDateTime> {
|
||||||
|
|
|
@ -58,6 +58,7 @@ impl From<Comment> for ApubComment {
|
||||||
impl ApubObject for ApubComment {
|
impl ApubObject for ApubComment {
|
||||||
type DataType = LemmyContext;
|
type DataType = LemmyContext;
|
||||||
type ApubType = Note;
|
type ApubType = Note;
|
||||||
|
type DbType = Comment;
|
||||||
type TombstoneType = Tombstone;
|
type TombstoneType = Tombstone;
|
||||||
|
|
||||||
fn last_refreshed_at(&self) -> Option<NaiveDateTime> {
|
fn last_refreshed_at(&self) -> Option<NaiveDateTime> {
|
||||||
|
|
|
@ -49,6 +49,7 @@ impl From<Community> for ApubCommunity {
|
||||||
impl ApubObject for ApubCommunity {
|
impl ApubObject for ApubCommunity {
|
||||||
type DataType = LemmyContext;
|
type DataType = LemmyContext;
|
||||||
type ApubType = Group;
|
type ApubType = Group;
|
||||||
|
type DbType = Community;
|
||||||
type TombstoneType = Tombstone;
|
type TombstoneType = Tombstone;
|
||||||
|
|
||||||
fn last_refreshed_at(&self) -> Option<NaiveDateTime> {
|
fn last_refreshed_at(&self) -> Option<NaiveDateTime> {
|
||||||
|
@ -62,7 +63,7 @@ impl ApubObject for ApubCommunity {
|
||||||
) -> Result<Option<Self>, LemmyError> {
|
) -> Result<Option<Self>, LemmyError> {
|
||||||
Ok(
|
Ok(
|
||||||
blocking(context.pool(), move |conn| {
|
blocking(context.pool(), move |conn| {
|
||||||
Community::read_from_apub_id(conn, object_id)
|
Community::read_from_apub_id(conn, &object_id.into())
|
||||||
})
|
})
|
||||||
.await??
|
.await??
|
||||||
.map(Into::into),
|
.map(Into::into),
|
||||||
|
|
|
@ -45,6 +45,7 @@ impl From<Site> for ApubSite {
|
||||||
impl ApubObject for ApubSite {
|
impl ApubObject for ApubSite {
|
||||||
type DataType = LemmyContext;
|
type DataType = LemmyContext;
|
||||||
type ApubType = Instance;
|
type ApubType = Instance;
|
||||||
|
type DbType = Site;
|
||||||
type TombstoneType = ();
|
type TombstoneType = ();
|
||||||
|
|
||||||
fn last_refreshed_at(&self) -> Option<NaiveDateTime> {
|
fn last_refreshed_at(&self) -> Option<NaiveDateTime> {
|
||||||
|
|
|
@ -55,6 +55,7 @@ impl From<DbPerson> for ApubPerson {
|
||||||
impl ApubObject for ApubPerson {
|
impl ApubObject for ApubPerson {
|
||||||
type DataType = LemmyContext;
|
type DataType = LemmyContext;
|
||||||
type ApubType = Person;
|
type ApubType = Person;
|
||||||
|
type DbType = DbPerson;
|
||||||
type TombstoneType = ();
|
type TombstoneType = ();
|
||||||
|
|
||||||
fn last_refreshed_at(&self) -> Option<NaiveDateTime> {
|
fn last_refreshed_at(&self) -> Option<NaiveDateTime> {
|
||||||
|
@ -68,7 +69,7 @@ impl ApubObject for ApubPerson {
|
||||||
) -> Result<Option<Self>, LemmyError> {
|
) -> Result<Option<Self>, LemmyError> {
|
||||||
Ok(
|
Ok(
|
||||||
blocking(context.pool(), move |conn| {
|
blocking(context.pool(), move |conn| {
|
||||||
DbPerson::read_from_apub_id(conn, object_id)
|
DbPerson::read_from_apub_id(conn, &object_id.into())
|
||||||
})
|
})
|
||||||
.await??
|
.await??
|
||||||
.map(Into::into),
|
.map(Into::into),
|
||||||
|
|
|
@ -57,6 +57,7 @@ impl From<Post> for ApubPost {
|
||||||
impl ApubObject for ApubPost {
|
impl ApubObject for ApubPost {
|
||||||
type DataType = LemmyContext;
|
type DataType = LemmyContext;
|
||||||
type ApubType = Page;
|
type ApubType = Page;
|
||||||
|
type DbType = Post;
|
||||||
type TombstoneType = Tombstone;
|
type TombstoneType = Tombstone;
|
||||||
|
|
||||||
fn last_refreshed_at(&self) -> Option<NaiveDateTime> {
|
fn last_refreshed_at(&self) -> Option<NaiveDateTime> {
|
||||||
|
|
|
@ -46,6 +46,7 @@ impl From<PrivateMessage> for ApubPrivateMessage {
|
||||||
impl ApubObject for ApubPrivateMessage {
|
impl ApubObject for ApubPrivateMessage {
|
||||||
type DataType = LemmyContext;
|
type DataType = LemmyContext;
|
||||||
type ApubType = ChatMessage;
|
type ApubType = ChatMessage;
|
||||||
|
type DbType = PrivateMessage;
|
||||||
type TombstoneType = ();
|
type TombstoneType = ();
|
||||||
|
|
||||||
fn last_refreshed_at(&self) -> Option<NaiveDateTime> {
|
fn last_refreshed_at(&self) -> Option<NaiveDateTime> {
|
||||||
|
|
|
@ -24,6 +24,7 @@ pub trait ActivityHandler {
|
||||||
pub trait ApubObject {
|
pub trait ApubObject {
|
||||||
type DataType;
|
type DataType;
|
||||||
type ApubType;
|
type ApubType;
|
||||||
|
type DbType;
|
||||||
type TombstoneType;
|
type TombstoneType;
|
||||||
|
|
||||||
/// If this object should be refetched after a certain interval, it should return the last refresh
|
/// If this object should be refetched after a certain interval, it should return the last refresh
|
||||||
|
|
|
@ -24,7 +24,6 @@ use diesel::{
|
||||||
RunQueryDsl,
|
RunQueryDsl,
|
||||||
TextExpressionMethods,
|
TextExpressionMethods,
|
||||||
};
|
};
|
||||||
use url::Url;
|
|
||||||
|
|
||||||
mod safe_type {
|
mod safe_type {
|
||||||
use crate::{schema::community::*, source::community::Community, traits::ToSafe};
|
use crate::{schema::community::*, source::community::Community, traits::ToSafe};
|
||||||
|
@ -291,9 +290,8 @@ impl Followable for CommunityFollower {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ApubActor for Community {
|
impl ApubActor for Community {
|
||||||
fn read_from_apub_id(conn: &PgConnection, object_id: Url) -> Result<Option<Self>, Error> {
|
fn read_from_apub_id(conn: &PgConnection, object_id: &DbUrl) -> Result<Option<Self>, Error> {
|
||||||
use crate::schema::community::dsl::*;
|
use crate::schema::community::dsl::*;
|
||||||
let object_id: DbUrl = object_id.into();
|
|
||||||
Ok(
|
Ok(
|
||||||
community
|
community
|
||||||
.filter(actor_id.eq(object_id))
|
.filter(actor_id.eq(object_id))
|
||||||
|
|
|
@ -15,7 +15,6 @@ use diesel::{
|
||||||
RunQueryDsl,
|
RunQueryDsl,
|
||||||
TextExpressionMethods,
|
TextExpressionMethods,
|
||||||
};
|
};
|
||||||
use url::Url;
|
|
||||||
|
|
||||||
mod safe_type {
|
mod safe_type {
|
||||||
use crate::{schema::person::columns::*, source::person::Person, traits::ToSafe};
|
use crate::{schema::person::columns::*, source::person::Person, traits::ToSafe};
|
||||||
|
@ -284,9 +283,8 @@ fn is_banned(banned_: bool, expires: Option<chrono::NaiveDateTime>) -> bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ApubActor for Person {
|
impl ApubActor for Person {
|
||||||
fn read_from_apub_id(conn: &PgConnection, object_id: Url) -> Result<Option<Self>, Error> {
|
fn read_from_apub_id(conn: &PgConnection, object_id: &DbUrl) -> Result<Option<Self>, Error> {
|
||||||
use crate::schema::person::dsl::*;
|
use crate::schema::person::dsl::*;
|
||||||
let object_id: DbUrl = object_id.into();
|
|
||||||
Ok(
|
Ok(
|
||||||
person
|
person
|
||||||
.filter(deleted.eq(false))
|
.filter(deleted.eq(false))
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
use crate::newtypes::{CommunityId, PersonId};
|
use crate::{
|
||||||
|
newtypes::{CommunityId, PersonId},
|
||||||
|
DbUrl,
|
||||||
|
};
|
||||||
use diesel::{result::Error, PgConnection};
|
use diesel::{result::Error, PgConnection};
|
||||||
use url::Url;
|
|
||||||
|
|
||||||
pub trait Crud {
|
pub trait Crud {
|
||||||
type Form;
|
type Form;
|
||||||
|
@ -166,7 +168,7 @@ pub trait ViewToVec {
|
||||||
|
|
||||||
pub trait ApubActor {
|
pub trait ApubActor {
|
||||||
// TODO: this should be in a trait ApubObject (and implemented for Post, Comment, PrivateMessage as well)
|
// TODO: this should be in a trait ApubObject (and implemented for Post, Comment, PrivateMessage as well)
|
||||||
fn read_from_apub_id(conn: &PgConnection, object_id: Url) -> Result<Option<Self>, Error>
|
fn read_from_apub_id(conn: &PgConnection, object_id: &DbUrl) -> Result<Option<Self>, Error>
|
||||||
where
|
where
|
||||||
Self: Sized;
|
Self: Sized;
|
||||||
fn read_from_name(conn: &PgConnection, actor_name: &str) -> Result<Self, Error>
|
fn read_from_name(conn: &PgConnection, actor_name: &str) -> Result<Self, Error>
|
||||||
|
|
Loading…
Reference in a new issue