From d206aad282ac1bc1266b087a963c7024a4b54e27 Mon Sep 17 00:00:00 2001 From: Felix Ableitner Date: Sat, 16 Oct 2021 13:14:02 +0200 Subject: [PATCH 1/3] Remove DeletableApubObject trait --- .../apub/src/fetcher/deletable_apub_object.rs | 99 ------------------- crates/apub/src/fetcher/mod.rs | 1 - crates/apub/src/fetcher/object_id.rs | 17 ++-- crates/apub/src/fetcher/post_or_comment.rs | 7 ++ crates/apub/src/fetcher/search.rs | 23 ++--- crates/apub_lib/src/traits.rs | 2 + crates/db_schema/src/source/comment.rs | 11 +++ crates/db_schema/src/source/community.rs | 9 ++ crates/db_schema/src/source/person.rs | 9 ++ crates/db_schema/src/source/post.rs | 9 ++ .../db_schema/src/source/private_message.rs | 5 + 11 files changed, 69 insertions(+), 123 deletions(-) delete mode 100644 crates/apub/src/fetcher/deletable_apub_object.rs diff --git a/crates/apub/src/fetcher/deletable_apub_object.rs b/crates/apub/src/fetcher/deletable_apub_object.rs deleted file mode 100644 index 503949e10..000000000 --- a/crates/apub/src/fetcher/deletable_apub_object.rs +++ /dev/null @@ -1,99 +0,0 @@ -use crate::fetcher::post_or_comment::PostOrComment; -use lemmy_api_common::blocking; -use lemmy_db_queries::source::{ - comment::Comment_, - community::Community_, - person::Person_, - post::Post_, -}; -use lemmy_db_schema::source::{ - comment::Comment, - community::Community, - person::Person, - post::Post, - private_message::PrivateMessage, -}; -use lemmy_utils::LemmyError; -use lemmy_websocket::LemmyContext; - -// TODO: merge this trait with ApubObject (means that db_schema needs to depend on apub_lib) -#[async_trait::async_trait(?Send)] -pub trait DeletableApubObject { - // TODO: pass in tombstone with summary field, to decide between remove/delete - async fn delete(self, context: &LemmyContext) -> Result<(), LemmyError>; -} - -#[async_trait::async_trait(?Send)] -impl DeletableApubObject for Community { - async fn delete(self, context: &LemmyContext) -> Result<(), LemmyError> { - let id = self.id; - blocking(context.pool(), move |conn| { - Community::update_deleted(conn, id, true) - }) - .await??; - Ok(()) - } -} - -#[async_trait::async_trait(?Send)] -impl DeletableApubObject for Person { - async fn delete(self, context: &LemmyContext) -> Result<(), LemmyError> { - let id = self.id; - blocking(context.pool(), move |conn| Person::delete_account(conn, id)).await??; - Ok(()) - } -} - -#[async_trait::async_trait(?Send)] -impl DeletableApubObject for Post { - async fn delete(self, context: &LemmyContext) -> Result<(), LemmyError> { - let id = self.id; - blocking(context.pool(), move |conn| { - Post::update_deleted(conn, id, true) - }) - .await??; - Ok(()) - } -} - -#[async_trait::async_trait(?Send)] -impl DeletableApubObject for Comment { - async fn delete(self, context: &LemmyContext) -> Result<(), LemmyError> { - let id = self.id; - blocking(context.pool(), move |conn| { - Comment::update_deleted(conn, id, true) - }) - .await??; - Ok(()) - } -} - -#[async_trait::async_trait(?Send)] -impl DeletableApubObject for PostOrComment { - async fn delete(self, context: &LemmyContext) -> Result<(), LemmyError> { - match self { - PostOrComment::Comment(c) => { - blocking(context.pool(), move |conn| { - Comment::update_deleted(conn, c.id, true) - }) - .await??; - } - PostOrComment::Post(p) => { - blocking(context.pool(), move |conn| { - Post::update_deleted(conn, p.id, true) - }) - .await??; - } - } - - Ok(()) - } -} - -#[async_trait::async_trait(?Send)] -impl DeletableApubObject for PrivateMessage { - async fn delete(self, _context: &LemmyContext) -> Result<(), LemmyError> { - // do nothing, because pm can't be fetched over http - unimplemented!() - } -} diff --git a/crates/apub/src/fetcher/mod.rs b/crates/apub/src/fetcher/mod.rs index b1b9e9ad4..641d59f02 100644 --- a/crates/apub/src/fetcher/mod.rs +++ b/crates/apub/src/fetcher/mod.rs @@ -1,5 +1,4 @@ pub mod community; -pub mod deletable_apub_object; mod fetch; pub mod object_id; pub mod post_or_comment; diff --git a/crates/apub/src/fetcher/object_id.rs b/crates/apub/src/fetcher/object_id.rs index 69d7c0289..14e983bb3 100644 --- a/crates/apub/src/fetcher/object_id.rs +++ b/crates/apub/src/fetcher/object_id.rs @@ -1,7 +1,4 @@ -use crate::{ - fetcher::{deletable_apub_object::DeletableApubObject, should_refetch_actor}, - objects::FromApub, -}; +use crate::{fetcher::should_refetch_actor, objects::FromApub}; use anyhow::anyhow; use diesel::{NotFound, PgConnection}; use lemmy_api_common::blocking; @@ -26,12 +23,12 @@ static REQUEST_LIMIT: i32 = 25; #[derive(Clone, PartialEq, Serialize, Deserialize, Debug)] pub struct ObjectId(Url, #[serde(skip)] PhantomData) where - Kind: FromApub + ApubObject + DeletableApubObject + Send + 'static, + Kind: FromApub + ApubObject + Send + 'static, for<'de2> ::ApubType: serde::Deserialize<'de2>; impl ObjectId where - Kind: FromApub + ApubObject + DeletableApubObject + Send + 'static, + Kind: FromApub + ApubObject + Send + 'static, for<'de> ::ApubType: serde::Deserialize<'de>, { pub fn new(url: T) -> Self @@ -117,7 +114,7 @@ where if res.status() == StatusCode::GONE { if let Some(db_object) = db_object { - db_object.delete(context).await?; + blocking(context.pool(), move |conn| db_object.delete(conn)).await??; } return Err(anyhow!("Fetched remote object {} which was deleted", self).into()); } @@ -130,7 +127,7 @@ where impl Display for ObjectId where - Kind: FromApub + ApubObject + DeletableApubObject + Send + 'static, + Kind: FromApub + ApubObject + Send + 'static, for<'de> ::ApubType: serde::Deserialize<'de>, { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { @@ -140,7 +137,7 @@ where impl From> for Url where - Kind: FromApub + ApubObject + DeletableApubObject + Send + 'static, + Kind: FromApub + ApubObject + Send + 'static, for<'de> ::ApubType: serde::Deserialize<'de>, { fn from(id: ObjectId) -> Self { @@ -150,7 +147,7 @@ where impl From> for DbUrl where - Kind: FromApub + ApubObject + DeletableApubObject + Send + 'static, + Kind: FromApub + ApubObject + Send + 'static, for<'de> ::ApubType: serde::Deserialize<'de>, { fn from(id: ObjectId) -> Self { diff --git a/crates/apub/src/fetcher/post_or_comment.rs b/crates/apub/src/fetcher/post_or_comment.rs index 23fc709d6..9d700c960 100644 --- a/crates/apub/src/fetcher/post_or_comment.rs +++ b/crates/apub/src/fetcher/post_or_comment.rs @@ -48,6 +48,13 @@ impl ApubObject for PostOrComment { None => Comment::read_from_apub_id(conn, object_id)?.map(PostOrComment::Comment), }) } + + fn delete(self, data: &Self::DataType) -> Result<(), LemmyError> { + match self { + PostOrComment::Post(p) => p.delete(data), + PostOrComment::Comment(c) => c.delete(data), + } + } } #[async_trait::async_trait(?Send)] diff --git a/crates/apub/src/fetcher/search.rs b/crates/apub/src/fetcher/search.rs index c8ac0d925..9fcf5a79c 100644 --- a/crates/apub/src/fetcher/search.rs +++ b/crates/apub/src/fetcher/search.rs @@ -1,5 +1,5 @@ use crate::{ - fetcher::{deletable_apub_object::DeletableApubObject, object_id::ObjectId}, + fetcher::object_id::ObjectId, objects::{comment::Note, community::Group, person::Person as ApubPerson, post::Page, FromApub}, }; use activitystreams::chrono::NaiveDateTime; @@ -136,6 +136,15 @@ impl ApubObject for SearchableObjects { } Ok(None) } + + fn delete(self, conn: &Self::DataType) -> Result<(), LemmyError> { + match self { + SearchableObjects::Person(p) => p.delete(conn), + SearchableObjects::Community(c) => c.delete(conn), + SearchableObjects::Post(p) => p.delete(conn), + SearchableObjects::Comment(c) => c.delete(conn), + } + } } #[async_trait::async_trait(?Send)] @@ -158,15 +167,3 @@ impl FromApub for SearchableObjects { }) } } - -#[async_trait::async_trait(?Send)] -impl DeletableApubObject for SearchableObjects { - async fn delete(self, context: &LemmyContext) -> Result<(), LemmyError> { - match self { - SearchableObjects::Person(p) => p.delete(context).await, - SearchableObjects::Community(c) => c.delete(context).await, - SearchableObjects::Post(p) => p.delete(context).await, - SearchableObjects::Comment(c) => c.delete(context).await, - } - } -} diff --git a/crates/apub_lib/src/traits.rs b/crates/apub_lib/src/traits.rs index f8cdba0a0..16fb3f8e3 100644 --- a/crates/apub_lib/src/traits.rs +++ b/crates/apub_lib/src/traits.rs @@ -36,6 +36,8 @@ pub trait ApubObject { fn read_from_apub_id(data: &Self::DataType, object_id: Url) -> Result, LemmyError> where Self: Sized; + /// Marks the object as deleted in local db. Called when a tombstone is received. + fn delete(self, data: &Self::DataType) -> Result<(), LemmyError>; } /// Common methods provided by ActivityPub actors (community and person). Not all methods are diff --git a/crates/db_schema/src/source/comment.rs b/crates/db_schema/src/source/comment.rs index 63062d1dd..54e8221f9 100644 --- a/crates/db_schema/src/source/comment.rs +++ b/crates/db_schema/src/source/comment.rs @@ -1,4 +1,5 @@ use crate::{ + naive_now, schema::{comment, comment_alias_1, comment_like, comment_saved}, source::post::Post, CommentId, @@ -126,4 +127,14 @@ impl ApubObject for Comment { let object_id: DbUrl = object_id.into(); Ok(comment.filter(ap_id.eq(object_id)).first::(conn).ok()) } + + // TODO: duplicate code from Comment::update_deleted(), we should really move all impls to + // this crate so we can call that function from here + fn delete(self, conn: &PgConnection) -> Result<(), LemmyError> { + use crate::schema::comment::dsl::*; + diesel::update(comment.find(self.id)) + .set((deleted.eq(true), updated.eq(naive_now()))) + .get_result::(conn)?; + Ok(()) + } } diff --git a/crates/db_schema/src/source/community.rs b/crates/db_schema/src/source/community.rs index f90bab13d..365ddba7f 100644 --- a/crates/db_schema/src/source/community.rs +++ b/crates/db_schema/src/source/community.rs @@ -1,4 +1,5 @@ use crate::{ + naive_now, schema::{community, community_follower, community_moderator, community_person_ban}, CommunityId, DbUrl, @@ -147,6 +148,14 @@ impl ApubObject for Community { .ok(), ) } + + fn delete(self, conn: &PgConnection) -> Result<(), LemmyError> { + use crate::schema::community::dsl::*; + diesel::update(community.find(self.id)) + .set((deleted.eq(true), updated.eq(naive_now()))) + .get_result::(conn)?; + Ok(()) + } } impl ActorType for Community { diff --git a/crates/db_schema/src/source/person.rs b/crates/db_schema/src/source/person.rs index 03fb821fa..f71f39dc9 100644 --- a/crates/db_schema/src/source/person.rs +++ b/crates/db_schema/src/source/person.rs @@ -1,4 +1,5 @@ use crate::{ + naive_now, schema::{person, person_alias_1, person_alias_2}, DbUrl, PersonId, @@ -194,6 +195,14 @@ impl ApubObject for Person { .ok(), ) } + + fn delete(self, conn: &PgConnection) -> Result<(), LemmyError> { + use crate::schema::person::dsl::*; + diesel::update(person.find(self.id)) + .set((deleted.eq(true), updated.eq(naive_now()))) + .get_result::(conn)?; + Ok(()) + } } impl ActorType for Person { diff --git a/crates/db_schema/src/source/post.rs b/crates/db_schema/src/source/post.rs index a09e88395..d28599c59 100644 --- a/crates/db_schema/src/source/post.rs +++ b/crates/db_schema/src/source/post.rs @@ -1,4 +1,5 @@ use crate::{ + naive_now, schema::{post, post_like, post_read, post_saved}, CommunityId, DbUrl, @@ -124,4 +125,12 @@ impl ApubObject for Post { let object_id: DbUrl = object_id.into(); Ok(post.filter(ap_id.eq(object_id)).first::(conn).ok()) } + + fn delete(self, conn: &PgConnection) -> Result<(), LemmyError> { + use crate::schema::post::dsl::*; + diesel::update(post.find(self.id)) + .set((deleted.eq(true), updated.eq(naive_now()))) + .get_result::(conn)?; + Ok(()) + } } diff --git a/crates/db_schema/src/source/private_message.rs b/crates/db_schema/src/source/private_message.rs index a867ce93e..6247cb955 100644 --- a/crates/db_schema/src/source/private_message.rs +++ b/crates/db_schema/src/source/private_message.rs @@ -54,4 +54,9 @@ impl ApubObject for PrivateMessage { .ok(), ) } + + fn delete(self, _conn: &PgConnection) -> Result<(), LemmyError> { + // do nothing, because pm can't be fetched over http + unimplemented!() + } } From f24999027e26fc77cc3808674f4f37fb1883c20f Mon Sep 17 00:00:00 2001 From: Felix Ableitner Date: Sat, 16 Oct 2021 15:33:38 +0200 Subject: [PATCH 2/3] Merge crates db_schema and db_queries --- Cargo.lock | 30 +- Cargo.toml | 2 - ansible/templates/docker-compose.yml | 2 +- api_tests/prepare-drone-federation-test.sh | 2 +- crates/api/Cargo.toml | 1 - crates/api/src/comment.rs | 7 +- crates/api/src/comment_report.rs | 3 +- crates/api/src/community.rs | 42 ++- crates/api/src/lib.rs | 15 +- crates/api/src/local_user.rs | 19 +- crates/api/src/post.rs | 6 +- crates/api/src/post_report.rs | 6 +- crates/api/src/private_message.rs | 3 +- crates/api/src/site.rs | 14 +- crates/api_common/Cargo.toml | 1 - crates/api_common/src/comment.rs | 2 +- crates/api_common/src/community.rs | 2 +- crates/api_common/src/lib.rs | 15 +- crates/api_common/src/person.rs | 2 +- crates/api_common/src/post.rs | 2 +- crates/api_common/src/site.rs | 2 +- crates/api_common/src/websocket.rs | 2 +- crates/api_crud/Cargo.toml | 1 - crates/api_crud/src/comment/create.rs | 11 +- crates/api_crud/src/comment/delete.rs | 11 +- crates/api_crud/src/comment/read.rs | 7 +- crates/api_crud/src/comment/update.rs | 3 +- crates/api_crud/src/community/create.rs | 23 +- crates/api_crud/src/community/delete.rs | 10 +- crates/api_crud/src/community/read.rs | 9 +- crates/api_crud/src/community/update.rs | 5 +- crates/api_crud/src/post/create.rs | 6 +- crates/api_crud/src/post/delete.rs | 10 +- crates/api_crud/src/post/read.rs | 7 +- crates/api_crud/src/post/update.rs | 7 +- crates/api_crud/src/private_message/create.rs | 6 +- crates/api_crud/src/private_message/delete.rs | 6 +- crates/api_crud/src/private_message/read.rs | 2 +- crates/api_crud/src/private_message/update.rs | 3 +- crates/api_crud/src/site/create.rs | 9 +- crates/api_crud/src/site/update.rs | 9 +- crates/api_crud/src/user/create.rs | 32 +- crates/api_crud/src/user/delete.rs | 3 +- crates/api_crud/src/user/read.rs | 3 +- crates/apub/Cargo.toml | 1 - .../activities/comment/create_or_update.rs | 6 +- crates/apub/src/activities/comment/mod.rs | 5 +- .../apub/src/activities/community/add_mod.rs | 10 +- .../src/activities/community/block_user.rs | 20 +- .../src/activities/community/remove_mod.rs | 10 +- .../activities/community/undo_block_user.rs | 10 +- .../apub/src/activities/community/update.rs | 10 +- crates/apub/src/activities/deletion/delete.rs | 31 +- crates/apub/src/activities/deletion/mod.rs | 1 - .../src/activities/deletion/undo_delete.rs | 1 - .../apub/src/activities/following/accept.rs | 10 +- .../apub/src/activities/following/follow.rs | 10 +- crates/apub/src/activities/following/undo.rs | 10 +- .../src/activities/post/create_or_update.rs | 6 +- .../private_message/create_or_update.rs | 6 +- .../src/activities/private_message/delete.rs | 6 +- .../activities/private_message/undo_delete.rs | 6 +- crates/apub/src/activities/report.rs | 4 +- crates/apub/src/activities/voting/mod.rs | 12 +- .../apub/src/activities/voting/undo_vote.rs | 4 +- crates/apub/src/activities/voting/vote.rs | 4 +- crates/apub/src/fetcher/community.rs | 10 +- crates/apub/src/fetcher/object_id.rs | 3 +- crates/apub/src/fetcher/search.rs | 5 +- crates/apub/src/http/comment.rs | 3 +- crates/apub/src/http/community.rs | 1 - crates/apub/src/http/mod.rs | 3 +- crates/apub/src/http/person.rs | 1 - crates/apub/src/http/post.rs | 3 +- crates/apub/src/lib.rs | 5 +- crates/apub/src/objects/comment.rs | 5 +- crates/apub/src/objects/community.rs | 2 +- crates/apub/src/objects/mod.rs | 2 +- crates/apub/src/objects/person.rs | 2 +- crates/apub/src/objects/post.rs | 3 +- crates/apub/src/objects/private_message.rs | 11 +- crates/db_queries/Cargo.toml | 33 -- crates/db_queries/src/lib.rs | 348 ------------------ crates/db_queries/src/source/secret.rs | 19 - crates/db_schema/Cargo.toml | 10 + .../src/aggregates/comment_aggregates.rs | 17 +- .../src/aggregates/community_aggregates.rs | 17 +- .../src/aggregates/mod.rs | 0 .../src/aggregates/person_aggregates.rs | 17 +- .../src/aggregates/post_aggregates.rs | 17 +- .../src/aggregates/site_aggregates.rs | 20 +- .../src/impls}/activity.rs | 59 +-- .../source => db_schema/src/impls}/comment.rs | 136 +++---- .../src/impls}/comment_report.rs | 15 +- .../src/impls}/community.rs | 168 +++++---- .../src/impls}/community_block.rs | 10 +- .../src/impls}/local_user.rs | 32 +- .../src/source => db_schema/src/impls}/mod.rs | 0 .../src/impls}/moderator.rs | 70 ++-- .../src/impls}/password_reset_request.rs | 36 +- .../source => db_schema/src/impls}/person.rs | 104 ++++-- .../src/impls}/person_block.rs | 26 +- .../src/impls}/person_mention.rs | 61 ++- .../source => db_schema/src/impls}/post.rs | 144 ++++---- .../src/impls}/post_report.rs | 14 +- .../src/impls}/private_message.rs | 106 +++--- crates/db_schema/src/impls/secret.rs | 15 + .../source => db_schema/src/impls}/site.rs | 26 +- crates/db_schema/src/lib.rs | 286 ++++++++------ crates/db_schema/src/newtypes.rs | 119 ++++++ crates/db_schema/src/source/activity.rs | 2 +- crates/db_schema/src/source/comment.rs | 35 +- crates/db_schema/src/source/comment_report.rs | 4 +- crates/db_schema/src/source/community.rs | 63 +--- .../db_schema/src/source/community_block.rs | 4 +- crates/db_schema/src/source/local_user.rs | 5 +- crates/db_schema/src/source/moderator.rs | 5 +- .../src/source/password_reset_request.rs | 2 +- crates/db_schema/src/source/person.rs | 65 +--- crates/db_schema/src/source/person_block.rs | 5 +- crates/db_schema/src/source/person_mention.rs | 4 +- crates/db_schema/src/source/post.rs | 34 +- crates/db_schema/src/source/post_report.rs | 6 +- .../db_schema/src/source/private_message.rs | 34 +- crates/db_schema/src/source/site.rs | 5 +- crates/db_schema/src/traits.rs | 164 +++++++++ crates/db_views/Cargo.toml | 1 - crates/db_views/src/comment_report_view.rs | 20 +- crates/db_views/src/comment_view.rs | 32 +- crates/db_views/src/local_user_view.rs | 6 +- crates/db_views/src/post_report_view.rs | 30 +- crates/db_views/src/post_view.rs | 37 +- crates/db_views/src/private_message_view.rs | 6 +- crates/db_views/src/site_view.rs | 3 +- crates/db_views_actor/Cargo.toml | 1 - .../src/community_block_view.rs | 4 +- .../src/community_follower_view.rs | 5 +- .../src/community_moderator_view.rs | 5 +- .../src/community_person_ban_view.rs | 5 +- crates/db_views_actor/src/community_view.rs | 15 +- .../db_views_actor/src/person_block_view.rs | 4 +- .../db_views_actor/src/person_mention_view.rs | 13 +- crates/db_views_actor/src/person_view.rs | 12 +- crates/db_views_moderator/Cargo.toml | 1 - .../src/mod_add_community_view.rs | 6 +- crates/db_views_moderator/src/mod_add_view.rs | 5 +- .../src/mod_ban_from_community_view.rs | 6 +- crates/db_views_moderator/src/mod_ban_view.rs | 5 +- .../src/mod_lock_post_view.rs | 6 +- .../src/mod_remove_comment_view.rs | 6 +- .../src/mod_remove_community_view.rs | 5 +- .../src/mod_remove_post_view.rs | 6 +- .../src/mod_sticky_post_view.rs | 6 +- .../src/mod_transfer_community_view.rs | 6 +- crates/routes/Cargo.toml | 1 - crates/routes/src/feeds.rs | 11 +- crates/routes/src/webfinger.rs | 1 - crates/utils/src/settings/mod.rs | 2 +- crates/websocket/Cargo.toml | 1 - crates/websocket/src/chat_server.rs | 5 +- crates/websocket/src/lib.rs | 3 +- crates/websocket/src/messages.rs | 2 +- crates/websocket/src/send.rs | 6 +- docker/dev/docker-compose.yml | 2 +- docker/federation/docker-compose.yml | 10 +- docker/prod/docker-compose.yml | 2 +- src/code_migrations.rs | 5 +- src/main.rs | 3 +- src/scheduled_tasks.rs | 3 +- 169 files changed, 1504 insertions(+), 1777 deletions(-) delete mode 100644 crates/db_queries/Cargo.toml delete mode 100644 crates/db_queries/src/lib.rs delete mode 100644 crates/db_queries/src/source/secret.rs rename crates/{db_queries => db_schema}/src/aggregates/comment_aggregates.rs (93%) rename crates/{db_queries => db_schema}/src/aggregates/community_aggregates.rs (94%) rename crates/{db_queries => db_schema}/src/aggregates/mod.rs (100%) rename crates/{db_queries => db_schema}/src/aggregates/person_aggregates.rs (94%) rename crates/{db_queries => db_schema}/src/aggregates/post_aggregates.rs (94%) rename crates/{db_queries => db_schema}/src/aggregates/site_aggregates.rs (91%) rename crates/{db_queries/src/source => db_schema/src/impls}/activity.rs (75%) rename crates/{db_queries/src/source => db_schema/src/impls}/comment.rs (77%) rename crates/{db_queries/src/source => db_schema/src/impls}/comment_report.rs (86%) rename crates/{db_queries/src/source => db_schema/src/impls}/community.rs (75%) rename crates/{db_queries/src/source => db_schema/src/impls}/community_block.rs (76%) rename crates/{db_queries/src/source => db_schema/src/impls}/local_user.rs (81%) rename crates/{db_queries/src/source => db_schema/src/impls}/mod.rs (100%) rename crates/{db_queries/src/source => db_schema/src/impls}/moderator.rs (87%) rename crates/{db_queries/src/source => db_schema/src/impls}/password_reset_request.rs (82%) rename crates/{db_queries/src/source => db_schema/src/impls}/person.rs (68%) rename crates/{db_queries/src/source => db_schema/src/impls}/person_block.rs (70%) rename crates/{db_queries/src/source => db_schema/src/impls}/person_mention.rs (77%) rename crates/{db_queries/src/source => db_schema/src/impls}/post.rs (75%) rename crates/{db_queries/src/source => db_schema/src/impls}/post_report.rs (85%) rename crates/{db_queries/src/source => db_schema/src/impls}/private_message.rs (72%) create mode 100644 crates/db_schema/src/impls/secret.rs rename crates/{db_queries/src/source => db_schema/src/impls}/site.rs (55%) create mode 100644 crates/db_schema/src/newtypes.rs create mode 100644 crates/db_schema/src/traits.rs diff --git a/Cargo.lock b/Cargo.lock index d8204367a..06361214f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1668,7 +1668,6 @@ dependencies = [ "lazy_static", "lemmy_api_common", "lemmy_apub", - "lemmy_db_queries", "lemmy_db_schema", "lemmy_db_views", "lemmy_db_views_actor", @@ -1697,7 +1696,6 @@ dependencies = [ "actix-web", "chrono", "diesel", - "lemmy_db_queries", "lemmy_db_schema", "lemmy_db_views", "lemmy_db_views_actor", @@ -1732,7 +1730,6 @@ dependencies = [ "lemmy_api_common", "lemmy_apub", "lemmy_apub_lib", - "lemmy_db_queries", "lemmy_db_schema", "lemmy_db_views", "lemmy_db_views_actor", @@ -1776,7 +1773,6 @@ dependencies = [ "itertools", "lemmy_api_common", "lemmy_apub_lib", - "lemmy_db_queries", "lemmy_db_schema", "lemmy_db_views", "lemmy_db_views_actor", @@ -1834,15 +1830,16 @@ dependencies = [ ] [[package]] -name = "lemmy_db_queries" +name = "lemmy_db_schema" version = "0.13.0" dependencies = [ "bcrypt", "chrono", "diesel", + "diesel-derive-newtype", "diesel_migrations", "lazy_static", - "lemmy_db_schema", + "lemmy_apub_lib", "lemmy_utils", "log", "regex", @@ -1855,27 +1852,11 @@ dependencies = [ "url", ] -[[package]] -name = "lemmy_db_schema" -version = "0.13.0" -dependencies = [ - "chrono", - "diesel", - "diesel-derive-newtype", - "lemmy_apub_lib", - "lemmy_utils", - "log", - "serde", - "serde_json", - "url", -] - [[package]] name = "lemmy_db_views" version = "0.13.0" dependencies = [ "diesel", - "lemmy_db_queries", "lemmy_db_schema", "log", "serde", @@ -1888,7 +1869,6 @@ name = "lemmy_db_views_actor" version = "0.13.0" dependencies = [ "diesel", - "lemmy_db_queries", "lemmy_db_schema", "serde", ] @@ -1898,7 +1878,6 @@ name = "lemmy_db_views_moderator" version = "0.13.0" dependencies = [ "diesel", - "lemmy_db_queries", "lemmy_db_schema", "serde", ] @@ -1918,7 +1897,6 @@ dependencies = [ "lazy_static", "lemmy_api_common", "lemmy_apub_lib", - "lemmy_db_queries", "lemmy_db_schema", "lemmy_db_views", "lemmy_db_views_actor", @@ -1954,7 +1932,6 @@ dependencies = [ "lemmy_api_crud", "lemmy_apub", "lemmy_apub_lib", - "lemmy_db_queries", "lemmy_db_schema", "lemmy_db_views", "lemmy_db_views_actor", @@ -2020,7 +1997,6 @@ dependencies = [ "chrono", "diesel", "lemmy_api_common", - "lemmy_db_queries", "lemmy_db_schema", "lemmy_db_views", "lemmy_db_views_actor", diff --git a/Cargo.toml b/Cargo.toml index 153d9072f..c306f762a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -22,7 +22,6 @@ members = [ "crates/apub_lib_derive", "crates/apub", "crates/utils", - "crates/db_queries", "crates/db_schema", "crates/db_views", "crates/db_views_actor", @@ -38,7 +37,6 @@ lemmy_apub = { version = "=0.13.0", path = "./crates/apub" } lemmy_apub_lib = { version = "=0.13.0", path = "./crates/apub_lib" } lemmy_utils = { version = "=0.13.0", path = "./crates/utils" } lemmy_db_schema = { version = "=0.13.0", path = "./crates/db_schema" } -lemmy_db_queries = { version = "=0.13.0", path = "./crates/db_queries" } lemmy_db_views = { version = "=0.13.0", path = "./crates/db_views" } lemmy_db_views_moderator = { version = "=0.13.0", path = "./crates/db_views_moderator" } lemmy_db_views_actor = { version = "=0.13.0", path = "./crates/db_views_actor" } diff --git a/ansible/templates/docker-compose.yml b/ansible/templates/docker-compose.yml index 5b04c28d4..0cf89a2be 100644 --- a/ansible/templates/docker-compose.yml +++ b/ansible/templates/docker-compose.yml @@ -7,7 +7,7 @@ services: - "127.0.0.1:8536:8536" restart: always environment: - - RUST_LOG="warn,lemmy_server=info,lemmy_api=info,lemmy_api_common=info,lemmy_api_crud=info,lemmy_apub=info,lemmy_db_queries=info,lemmy_db_schema=info,lemmy_db_views=info,lemmy_db_views_actor=info,lemmy_db_views_moderator=info,lemmy_routes=info,lemmy_utils=info,lemmy_websocket=info" + - RUST_LOG="warn,lemmy_server=info,lemmy_api=info,lemmy_api_common=info,lemmy_api_crud=info,lemmy_apub=info,lemmy_db_schema=info,lemmy_db_views=info,lemmy_db_views_actor=info,lemmy_db_views_moderator=info,lemmy_routes=info,lemmy_utils=info,lemmy_websocket=info" volumes: - ./lemmy.hjson:/config/config.hjson:ro depends_on: diff --git a/api_tests/prepare-drone-federation-test.sh b/api_tests/prepare-drone-federation-test.sh index 6e08ad359..2dbfbe251 100755 --- a/api_tests/prepare-drone-federation-test.sh +++ b/api_tests/prepare-drone-federation-test.sh @@ -3,7 +3,7 @@ set -e export APUB_TESTING_SEND_SYNC=1 export RUST_BACKTRACE=1 -export RUST_LOG="warn,lemmy_server=debug,lemmy_api=debug,lemmy_api_common=debug,lemmy_api_crud=debug,lemmy_apub=debug,lemmy_db_queries=debug,lemmy_db_schema=debug,lemmy_db_views=debug,lemmy_db_views_actor=debug,lemmy_db_views_moderator=debug,lemmy_routes=debug,lemmy_utils=debug,lemmy_websocket=debug" +export RUST_LOG="warn,lemmy_server=debug,lemmy_api=debug,lemmy_api_common=debug,lemmy_api_crud=debug,lemmy_apub=debug,lemmy_db_schema=debug,lemmy_db_views=debug,lemmy_db_views_actor=debug,lemmy_db_views_moderator=debug,lemmy_routes=debug,lemmy_utils=debug,lemmy_websocket=debug" for INSTANCE in lemmy_alpha lemmy_beta lemmy_gamma lemmy_delta lemmy_epsilon; do psql "${LEMMY_DATABASE_URL}/lemmy" -c "DROP DATABASE IF EXISTS $INSTANCE" diff --git a/crates/api/Cargo.toml b/crates/api/Cargo.toml index 04dd87e05..8d389308c 100644 --- a/crates/api/Cargo.toml +++ b/crates/api/Cargo.toml @@ -15,7 +15,6 @@ doctest = false [dependencies] lemmy_apub = { version = "=0.13.0", path = "../apub" } lemmy_utils = { version = "=0.13.0", path = "../utils" } -lemmy_db_queries = { version = "=0.13.0", path = "../db_queries" } lemmy_db_schema = { version = "=0.13.0", path = "../db_schema" } lemmy_db_views = { version = "=0.13.0", path = "../db_views" } lemmy_db_views_moderator = { version = "=0.13.0", path = "../db_views_moderator" } diff --git a/crates/api/src/comment.rs b/crates/api/src/comment.rs index 9311d7dc2..d626c2eae 100644 --- a/crates/api/src/comment.rs +++ b/crates/api/src/comment.rs @@ -15,8 +15,11 @@ use lemmy_apub::{ }, fetcher::post_or_comment::PostOrComment, }; -use lemmy_db_queries::{source::comment::Comment_, Likeable, Saveable}; -use lemmy_db_schema::{source::comment::*, LocalUserId}; +use lemmy_db_schema::{ + newtypes::LocalUserId, + source::comment::*, + traits::{Likeable, Saveable}, +}; use lemmy_db_views::{comment_view::CommentView, local_user_view::LocalUserView}; use lemmy_utils::{ApiError, ConnectionId, LemmyError}; use lemmy_websocket::{send::send_comment_ws_message, LemmyContext, UserOperation}; diff --git a/crates/api/src/comment_report.rs b/crates/api/src/comment_report.rs index 5d2561dd9..86f636a6b 100644 --- a/crates/api/src/comment_report.rs +++ b/crates/api/src/comment_report.rs @@ -8,8 +8,7 @@ use lemmy_api_common::{ is_mod_or_admin, }; use lemmy_apub::{activities::report::Report, fetcher::object_id::ObjectId}; -use lemmy_db_queries::Reportable; -use lemmy_db_schema::source::comment_report::*; +use lemmy_db_schema::{source::comment_report::*, traits::Reportable}; use lemmy_db_views::{ comment_report_view::{CommentReportQueryBuilder, CommentReportView}, comment_view::CommentView, diff --git a/crates/api/src/community.rs b/crates/api/src/community.rs index ccf0edbfd..5d7317b2a 100644 --- a/crates/api/src/community.rs +++ b/crates/api/src/community.rs @@ -18,22 +18,32 @@ use lemmy_apub::activities::{ }, following::{follow::FollowCommunity as FollowCommunityApub, undo::UndoFollowCommunity}, }; -use lemmy_db_queries::{ - source::{comment::Comment_, community::CommunityModerator_, post::Post_}, - Bannable, - Blockable, - Crud, - Followable, - Joinable, -}; -use lemmy_db_schema::source::{ - comment::Comment, - community::*, - community_block::{CommunityBlock, CommunityBlockForm}, - moderator::*, - person::Person, - post::Post, - site::*, +use lemmy_db_schema::{ + source::{ + comment::Comment, + community::{ + Community, + CommunityFollower, + CommunityFollowerForm, + CommunityModerator, + CommunityModeratorForm, + CommunityPersonBan, + CommunityPersonBanForm, + }, + community_block::{CommunityBlock, CommunityBlockForm}, + moderator::{ + ModAddCommunity, + ModAddCommunityForm, + ModBanFromCommunity, + ModBanFromCommunityForm, + ModTransferCommunity, + ModTransferCommunityForm, + }, + person::Person, + post::Post, + site::Site, + }, + traits::{Bannable, Blockable, Crud, Followable, Joinable}, }; use lemmy_db_views::comment_view::CommentQueryBuilder; use lemmy_db_views_actor::{ diff --git a/crates/api/src/lib.rs b/crates/api/src/lib.rs index ccc817616..74a3d3037 100644 --- a/crates/api/src/lib.rs +++ b/crates/api/src/lib.rs @@ -191,15 +191,14 @@ pub(crate) fn captcha_as_wav_base64(captcha: &Captcha) -> String { #[cfg(test)] mod tests { use lemmy_api_common::check_validator_time; - use lemmy_db_queries::{ + use lemmy_db_schema::{ establish_unpooled_connection, - source::{local_user::LocalUser_, secret::Secret_}, - Crud, - }; - use lemmy_db_schema::source::{ - local_user::{LocalUser, LocalUserForm}, - person::{Person, PersonForm}, - secret::Secret, + source::{ + local_user::{LocalUser, LocalUserForm}, + person::{Person, PersonForm}, + secret::Secret, + }, + traits::Crud, }; use lemmy_utils::{claims::Claims, settings::structs::Settings}; diff --git a/crates/api/src/local_user.rs b/crates/api/src/local_user.rs index d5a1533f9..727dd1a5c 100644 --- a/crates/api/src/local_user.rs +++ b/crates/api/src/local_user.rs @@ -11,25 +11,10 @@ use lemmy_api_common::{ password_length_check, person::*, }; -use lemmy_db_queries::{ +use lemmy_db_schema::{ diesel_option_overwrite, diesel_option_overwrite_to_url, from_opt_str_to_opt_enum, - source::{ - comment::Comment_, - community::Community_, - local_user::LocalUser_, - password_reset_request::PasswordResetRequest_, - person::Person_, - person_mention::PersonMention_, - post::Post_, - private_message::PrivateMessage_, - }, - Blockable, - Crud, - SortType, -}; -use lemmy_db_schema::{ naive_now, source::{ comment::Comment, @@ -44,6 +29,8 @@ use lemmy_db_schema::{ private_message::PrivateMessage, site::*, }, + traits::{Blockable, Crud}, + SortType, }; use lemmy_db_views::{ comment_report_view::CommentReportView, diff --git a/crates/api/src/post.rs b/crates/api/src/post.rs index a79a4bb5e..60cdafb9a 100644 --- a/crates/api/src/post.rs +++ b/crates/api/src/post.rs @@ -22,8 +22,10 @@ use lemmy_apub::{ }, fetcher::post_or_comment::PostOrComment, }; -use lemmy_db_queries::{source::post::Post_, Crud, Likeable, Saveable}; -use lemmy_db_schema::source::{moderator::*, post::*}; +use lemmy_db_schema::{ + source::{moderator::*, post::*}, + traits::{Crud, Likeable, Saveable}, +}; use lemmy_db_views::post_view::PostView; use lemmy_utils::{request::fetch_site_metadata, ApiError, ConnectionId, LemmyError}; use lemmy_websocket::{send::send_post_ws_message, LemmyContext, UserOperation}; diff --git a/crates/api/src/post_report.rs b/crates/api/src/post_report.rs index 5b8b0b656..35a734d44 100644 --- a/crates/api/src/post_report.rs +++ b/crates/api/src/post_report.rs @@ -14,8 +14,10 @@ use lemmy_api_common::{ }, }; use lemmy_apub::{activities::report::Report, fetcher::object_id::ObjectId}; -use lemmy_db_queries::Reportable; -use lemmy_db_schema::source::post_report::{PostReport, PostReportForm}; +use lemmy_db_schema::{ + source::post_report::{PostReport, PostReportForm}, + traits::Reportable, +}; use lemmy_db_views::{ post_report_view::{PostReportQueryBuilder, PostReportView}, post_view::PostView, diff --git a/crates/api/src/private_message.rs b/crates/api/src/private_message.rs index 6be6ba05b..1c80f44f4 100644 --- a/crates/api/src/private_message.rs +++ b/crates/api/src/private_message.rs @@ -5,8 +5,7 @@ use lemmy_api_common::{ get_local_user_view_from_jwt, person::{MarkPrivateMessageAsRead, PrivateMessageResponse}, }; -use lemmy_db_queries::{source::private_message::PrivateMessage_, Crud}; -use lemmy_db_schema::source::private_message::PrivateMessage; +use lemmy_db_schema::{source::private_message::PrivateMessage, traits::Crud}; use lemmy_utils::{ApiError, ConnectionId, LemmyError}; use lemmy_websocket::{send::send_pm_ws_message, LemmyContext, UserOperation}; diff --git a/crates/api/src/site.rs b/crates/api/src/site.rs index a80dfe66c..105412b0e 100644 --- a/crates/api/src/site.rs +++ b/crates/api/src/site.rs @@ -15,20 +15,16 @@ use lemmy_apub::{ fetcher::search::{search_by_apub_id, SearchableObjects}, EndpointType, }; -use lemmy_db_queries::{ +use lemmy_db_schema::{ from_opt_str_to_opt_enum, - source::site::Site_, - Crud, + newtypes::PersonId, + source::{moderator::*, site::Site}, + traits::{Crud, DeleteableOrRemoveable}, DbPool, - DeleteableOrRemoveable, ListingType, SearchType, SortType, }; -use lemmy_db_schema::{ - source::{moderator::*, site::Site}, - PersonId, -}; use lemmy_db_views::{ comment_view::{CommentQueryBuilder, CommentView}, post_view::{PostQueryBuilder, PostView}, @@ -450,7 +446,7 @@ impl Perform for TransferSite { is_admin(&local_user_view)?; - let read_site = blocking(context.pool(), move |conn| Site::read_simple(conn)).await??; + let read_site = blocking(context.pool(), Site::read_simple).await??; // Make sure user is the creator if read_site.creator_id != local_user_view.person.id { diff --git a/crates/api_common/Cargo.toml b/crates/api_common/Cargo.toml index 261c061c5..5672b583e 100644 --- a/crates/api_common/Cargo.toml +++ b/crates/api_common/Cargo.toml @@ -13,7 +13,6 @@ path = "src/lib.rs" doctest = false [dependencies] -lemmy_db_queries = { version = "=0.13.0", path = "../db_queries" } lemmy_db_views = { version = "=0.13.0", path = "../db_views" } lemmy_db_views_moderator = { version = "=0.13.0", path = "../db_views_moderator" } lemmy_db_views_actor = { version = "=0.13.0", path = "../db_views_actor" } diff --git a/crates/api_common/src/comment.rs b/crates/api_common/src/comment.rs index 2739b9555..eadbceb2b 100644 --- a/crates/api_common/src/comment.rs +++ b/crates/api_common/src/comment.rs @@ -1,4 +1,4 @@ -use lemmy_db_schema::{CommentId, CommentReportId, CommunityId, LocalUserId, PostId}; +use lemmy_db_schema::newtypes::{CommentId, CommentReportId, CommunityId, LocalUserId, PostId}; use lemmy_db_views::{comment_report_view::CommentReportView, comment_view::CommentView}; use serde::{Deserialize, Serialize}; diff --git a/crates/api_common/src/community.rs b/crates/api_common/src/community.rs index eea4bc7b3..1f32267f3 100644 --- a/crates/api_common/src/community.rs +++ b/crates/api_common/src/community.rs @@ -1,4 +1,4 @@ -use lemmy_db_schema::{CommunityId, PersonId}; +use lemmy_db_schema::newtypes::{CommunityId, PersonId}; use lemmy_db_views_actor::{ community_moderator_view::CommunityModeratorView, community_view::CommunityView, diff --git a/crates/api_common/src/lib.rs b/crates/api_common/src/lib.rs index c4b1dd6f5..f28c34b01 100644 --- a/crates/api_common/src/lib.rs +++ b/crates/api_common/src/lib.rs @@ -7,13 +7,8 @@ pub mod websocket; use crate::site::FederatedInstances; use diesel::PgConnection; -use lemmy_db_queries::{ - source::{community::Community_, person_block::PersonBlock_, site::Site_}, - Crud, - DbPool, - Readable, -}; use lemmy_db_schema::{ + newtypes::{CommunityId, LocalUserId, PersonId, PostId}, source::{ comment::Comment, community::Community, @@ -24,10 +19,8 @@ use lemmy_db_schema::{ secret::Secret, site::Site, }, - CommunityId, - LocalUserId, - PersonId, - PostId, + traits::{Crud, Readable}, + DbPool, }; use lemmy_db_views::local_user_view::{LocalUserSettingsView, LocalUserView}; use lemmy_db_views_actor::{ @@ -394,7 +387,7 @@ pub async fn check_person_block( pub async fn check_downvotes_enabled(score: i16, pool: &DbPool) -> Result<(), LemmyError> { if score == -1 { - let site = blocking(pool, move |conn| Site::read_simple(conn)).await??; + let site = blocking(pool, Site::read_simple).await??; if !site.enable_downvotes { return Err(ApiError::err_plain("downvotes_disabled").into()); } diff --git a/crates/api_common/src/person.rs b/crates/api_common/src/person.rs index ce0c1bf80..b93d47eae 100644 --- a/crates/api_common/src/person.rs +++ b/crates/api_common/src/person.rs @@ -15,7 +15,7 @@ pub struct Login { pub username_or_email: String, pub password: String, } -use lemmy_db_schema::{CommunityId, PersonId, PersonMentionId, PrivateMessageId}; +use lemmy_db_schema::newtypes::{CommunityId, PersonId, PersonMentionId, PrivateMessageId}; #[derive(Serialize, Deserialize)] pub struct Register { diff --git a/crates/api_common/src/post.rs b/crates/api_common/src/post.rs index 1a53ef587..d4a8c3f52 100644 --- a/crates/api_common/src/post.rs +++ b/crates/api_common/src/post.rs @@ -1,4 +1,4 @@ -use lemmy_db_schema::{CommunityId, PostId, PostReportId}; +use lemmy_db_schema::newtypes::{CommunityId, PostId, PostReportId}; use lemmy_db_views::{ comment_view::CommentView, post_report_view::PostReportView, diff --git a/crates/api_common/src/site.rs b/crates/api_common/src/site.rs index e1e75f9ea..db81fce46 100644 --- a/crates/api_common/src/site.rs +++ b/crates/api_common/src/site.rs @@ -1,4 +1,4 @@ -use lemmy_db_schema::{CommunityId, PersonId}; +use lemmy_db_schema::newtypes::{CommunityId, PersonId}; use lemmy_db_views::{ comment_view::CommentView, local_user_view::LocalUserSettingsView, diff --git a/crates/api_common/src/websocket.rs b/crates/api_common/src/websocket.rs index f88819cdc..5ab94d92d 100644 --- a/crates/api_common/src/websocket.rs +++ b/crates/api_common/src/websocket.rs @@ -1,4 +1,4 @@ -use lemmy_db_schema::{CommunityId, PostId}; +use lemmy_db_schema::newtypes::{CommunityId, PostId}; use serde::{Deserialize, Serialize}; #[derive(Serialize, Deserialize, Debug)] diff --git a/crates/api_crud/Cargo.toml b/crates/api_crud/Cargo.toml index 15438aa2e..c73591e3e 100644 --- a/crates/api_crud/Cargo.toml +++ b/crates/api_crud/Cargo.toml @@ -11,7 +11,6 @@ documentation = "https://join-lemmy.org/docs/en/index.html" lemmy_apub = { version = "=0.13.0", path = "../apub" } lemmy_apub_lib = { version = "=0.13.0", path = "../apub_lib" } lemmy_utils = { version = "=0.13.0", path = "../utils" } -lemmy_db_queries = { version = "=0.13.0", path = "../db_queries" } lemmy_db_schema = { version = "=0.13.0", path = "../db_schema" } lemmy_db_views = { version = "=0.13.0", path = "../db_views" } lemmy_db_views_moderator = { version = "=0.13.0", path = "../db_views_moderator" } diff --git a/crates/api_crud/src/comment/create.rs b/crates/api_crud/src/comment/create.rs index 37ecb2f05..ff2442b15 100644 --- a/crates/api_crud/src/comment/create.rs +++ b/crates/api_crud/src/comment/create.rs @@ -21,12 +21,13 @@ use lemmy_apub::{ generate_apub_endpoint, EndpointType, }; -use lemmy_db_queries::{ - source::{comment::Comment_, person_mention::PersonMention_}, - Crud, - Likeable, +use lemmy_db_schema::{ + source::{ + comment::{Comment, CommentForm, CommentLike, CommentLikeForm}, + person_mention::PersonMention, + }, + traits::{Crud, Likeable}, }; -use lemmy_db_schema::source::{comment::*, person_mention::PersonMention}; use lemmy_db_views::comment_view::CommentView; use lemmy_utils::{ utils::{remove_slurs, scrape_text_for_mentions}, diff --git a/crates/api_crud/src/comment/delete.rs b/crates/api_crud/src/comment/delete.rs index 96e8063d8..07c920f7c 100644 --- a/crates/api_crud/src/comment/delete.rs +++ b/crates/api_crud/src/comment/delete.rs @@ -9,8 +9,15 @@ use lemmy_api_common::{ send_local_notifs, }; use lemmy_apub::activities::deletion::{send_apub_delete, send_apub_remove}; -use lemmy_db_queries::{source::comment::Comment_, Crud}; -use lemmy_db_schema::source::{comment::*, community::Community, moderator::*, post::Post}; +use lemmy_db_schema::{ + source::{ + comment::Comment, + community::Community, + moderator::{ModRemoveComment, ModRemoveCommentForm}, + post::Post, + }, + traits::Crud, +}; use lemmy_db_views::comment_view::CommentView; use lemmy_utils::{ApiError, ConnectionId, LemmyError}; use lemmy_websocket::{send::send_comment_ws_message, LemmyContext, UserOperationCrud}; diff --git a/crates/api_crud/src/comment/read.rs b/crates/api_crud/src/comment/read.rs index c4d0c394b..490c9670f 100644 --- a/crates/api_crud/src/comment/read.rs +++ b/crates/api_crud/src/comment/read.rs @@ -2,7 +2,12 @@ use crate::PerformCrud; use actix_web::web::Data; use lemmy_api_common::{blocking, comment::*, get_local_user_view_from_jwt_opt}; use lemmy_apub::{build_actor_id_from_shortname, EndpointType}; -use lemmy_db_queries::{from_opt_str_to_opt_enum, DeleteableOrRemoveable, ListingType, SortType}; +use lemmy_db_schema::{ + from_opt_str_to_opt_enum, + traits::DeleteableOrRemoveable, + ListingType, + SortType, +}; use lemmy_db_views::comment_view::CommentQueryBuilder; use lemmy_utils::{ApiError, ConnectionId, LemmyError}; use lemmy_websocket::LemmyContext; diff --git a/crates/api_crud/src/comment/update.rs b/crates/api_crud/src/comment/update.rs index b0892c58c..7d45b9403 100644 --- a/crates/api_crud/src/comment/update.rs +++ b/crates/api_crud/src/comment/update.rs @@ -13,8 +13,7 @@ use lemmy_apub::activities::{ comment::create_or_update::CreateOrUpdateComment, CreateOrUpdateType, }; -use lemmy_db_queries::source::comment::Comment_; -use lemmy_db_schema::source::comment::*; +use lemmy_db_schema::source::comment::Comment; use lemmy_db_views::comment_view::CommentView; use lemmy_utils::{ utils::{remove_slurs, scrape_text_for_mentions}, diff --git a/crates/api_crud/src/community/create.rs b/crates/api_crud/src/community/create.rs index 56d04ce54..cc0e62db4 100644 --- a/crates/api_crud/src/community/create.rs +++ b/crates/api_crud/src/community/create.rs @@ -14,17 +14,20 @@ use lemmy_apub::{ generate_shared_inbox_url, EndpointType, }; -use lemmy_db_queries::{diesel_option_overwrite_to_url, Crud, Followable, Joinable}; -use lemmy_db_schema::source::{ - community::{ - Community, - CommunityFollower, - CommunityFollowerForm, - CommunityForm, - CommunityModerator, - CommunityModeratorForm, +use lemmy_db_schema::{ + diesel_option_overwrite_to_url, + source::{ + community::{ + Community, + CommunityFollower, + CommunityFollowerForm, + CommunityForm, + CommunityModerator, + CommunityModeratorForm, + }, + site::Site, }, - site::Site, + traits::{Crud, Followable, Joinable}, }; use lemmy_db_views_actor::community_view::CommunityView; use lemmy_utils::{ diff --git a/crates/api_crud/src/community/delete.rs b/crates/api_crud/src/community/delete.rs index ea1890402..5f9fbb44e 100644 --- a/crates/api_crud/src/community/delete.rs +++ b/crates/api_crud/src/community/delete.rs @@ -2,10 +2,12 @@ use crate::PerformCrud; use actix_web::web::Data; use lemmy_api_common::{blocking, community::*, get_local_user_view_from_jwt, is_admin}; use lemmy_apub::activities::deletion::{send_apub_delete, send_apub_remove}; -use lemmy_db_queries::{source::community::Community_, Crud}; -use lemmy_db_schema::source::{ - community::*, - moderator::{ModRemoveCommunity, ModRemoveCommunityForm}, +use lemmy_db_schema::{ + source::{ + community::Community, + moderator::{ModRemoveCommunity, ModRemoveCommunityForm}, + }, + traits::Crud, }; use lemmy_db_views_actor::community_moderator_view::CommunityModeratorView; use lemmy_utils::{utils::naive_from_unix, ApiError, ConnectionId, LemmyError}; diff --git a/crates/api_crud/src/community/read.rs b/crates/api_crud/src/community/read.rs index 9d9bdce00..3b9405aff 100644 --- a/crates/api_crud/src/community/read.rs +++ b/crates/api_crud/src/community/read.rs @@ -2,8 +2,13 @@ use crate::PerformCrud; use actix_web::web::Data; use lemmy_api_common::{blocking, community::*, get_local_user_view_from_jwt_opt}; use lemmy_apub::{build_actor_id_from_shortname, fetcher::object_id::ObjectId, EndpointType}; -use lemmy_db_queries::{from_opt_str_to_opt_enum, DeleteableOrRemoveable, ListingType, SortType}; -use lemmy_db_schema::source::community::*; +use lemmy_db_schema::{ + from_opt_str_to_opt_enum, + source::community::Community, + traits::DeleteableOrRemoveable, + ListingType, + SortType, +}; use lemmy_db_views_actor::{ community_moderator_view::CommunityModeratorView, community_view::{CommunityQueryBuilder, CommunityView}, diff --git a/crates/api_crud/src/community/update.rs b/crates/api_crud/src/community/update.rs index 56fe72838..f269807b5 100644 --- a/crates/api_crud/src/community/update.rs +++ b/crates/api_crud/src/community/update.rs @@ -6,11 +6,12 @@ use lemmy_api_common::{ get_local_user_view_from_jwt, }; use lemmy_apub::activities::community::update::UpdateCommunity; -use lemmy_db_queries::{diesel_option_overwrite_to_url, Crud}; use lemmy_db_schema::{ + diesel_option_overwrite_to_url, naive_now, + newtypes::PersonId, source::community::{Community, CommunityForm}, - PersonId, + traits::Crud, }; use lemmy_db_views_actor::community_moderator_view::CommunityModeratorView; use lemmy_utils::{utils::check_slurs_opt, ApiError, ConnectionId, LemmyError}; diff --git a/crates/api_crud/src/post/create.rs b/crates/api_crud/src/post/create.rs index 108205b7c..e75999e59 100644 --- a/crates/api_crud/src/post/create.rs +++ b/crates/api_crud/src/post/create.rs @@ -19,8 +19,10 @@ use lemmy_apub::{ generate_apub_endpoint, EndpointType, }; -use lemmy_db_queries::{source::post::Post_, Crud, Likeable}; -use lemmy_db_schema::source::post::*; +use lemmy_db_schema::{ + source::post::{Post, PostForm, PostLike, PostLikeForm}, + traits::{Crud, Likeable}, +}; use lemmy_utils::{ request::fetch_site_data, utils::{check_slurs, check_slurs_opt, clean_url_params, is_valid_post_title}, diff --git a/crates/api_crud/src/post/delete.rs b/crates/api_crud/src/post/delete.rs index 01fa0575b..1a9044c37 100644 --- a/crates/api_crud/src/post/delete.rs +++ b/crates/api_crud/src/post/delete.rs @@ -9,8 +9,14 @@ use lemmy_api_common::{ post::*, }; use lemmy_apub::activities::deletion::{send_apub_delete, send_apub_remove}; -use lemmy_db_queries::{source::post::Post_, Crud}; -use lemmy_db_schema::source::{community::Community, moderator::*, post::*}; +use lemmy_db_schema::{ + source::{ + community::Community, + moderator::{ModRemovePost, ModRemovePostForm}, + post::Post, + }, + traits::Crud, +}; use lemmy_utils::{ApiError, ConnectionId, LemmyError}; use lemmy_websocket::{send::send_post_ws_message, LemmyContext, UserOperationCrud}; diff --git a/crates/api_crud/src/post/read.rs b/crates/api_crud/src/post/read.rs index 76e9548ed..ee05b7231 100644 --- a/crates/api_crud/src/post/read.rs +++ b/crates/api_crud/src/post/read.rs @@ -2,7 +2,12 @@ use crate::PerformCrud; use actix_web::web::Data; use lemmy_api_common::{blocking, get_local_user_view_from_jwt_opt, mark_post_as_read, post::*}; use lemmy_apub::{build_actor_id_from_shortname, EndpointType}; -use lemmy_db_queries::{from_opt_str_to_opt_enum, DeleteableOrRemoveable, ListingType, SortType}; +use lemmy_db_schema::{ + from_opt_str_to_opt_enum, + traits::DeleteableOrRemoveable, + ListingType, + SortType, +}; use lemmy_db_views::{ comment_view::CommentQueryBuilder, post_view::{PostQueryBuilder, PostView}, diff --git a/crates/api_crud/src/post/update.rs b/crates/api_crud/src/post/update.rs index c84901cc8..8c346b882 100644 --- a/crates/api_crud/src/post/update.rs +++ b/crates/api_crud/src/post/update.rs @@ -8,8 +8,11 @@ use lemmy_api_common::{ post::*, }; use lemmy_apub::activities::{post::create_or_update::CreateOrUpdatePost, CreateOrUpdateType}; -use lemmy_db_queries::{source::post::Post_, Crud}; -use lemmy_db_schema::{naive_now, source::post::*}; +use lemmy_db_schema::{ + naive_now, + source::post::{Post, PostForm}, + traits::Crud, +}; use lemmy_utils::{ request::fetch_site_data, utils::{check_slurs_opt, clean_url_params, is_valid_post_title}, diff --git a/crates/api_crud/src/private_message/create.rs b/crates/api_crud/src/private_message/create.rs index d04412f60..9e3351252 100644 --- a/crates/api_crud/src/private_message/create.rs +++ b/crates/api_crud/src/private_message/create.rs @@ -15,8 +15,10 @@ use lemmy_apub::{ generate_apub_endpoint, EndpointType, }; -use lemmy_db_queries::{source::private_message::PrivateMessage_, Crud}; -use lemmy_db_schema::source::private_message::{PrivateMessage, PrivateMessageForm}; +use lemmy_db_schema::{ + source::private_message::{PrivateMessage, PrivateMessageForm}, + traits::Crud, +}; use lemmy_db_views::local_user_view::LocalUserView; use lemmy_utils::{utils::remove_slurs, ApiError, ConnectionId, LemmyError}; use lemmy_websocket::{send::send_pm_ws_message, LemmyContext, UserOperationCrud}; diff --git a/crates/api_crud/src/private_message/delete.rs b/crates/api_crud/src/private_message/delete.rs index 70efc903a..0c61a09b0 100644 --- a/crates/api_crud/src/private_message/delete.rs +++ b/crates/api_crud/src/private_message/delete.rs @@ -9,8 +9,10 @@ use lemmy_apub::activities::private_message::{ delete::DeletePrivateMessage as DeletePrivateMessageApub, undo_delete::UndoDeletePrivateMessage, }; -use lemmy_db_queries::{source::private_message::PrivateMessage_, Crud, DeleteableOrRemoveable}; -use lemmy_db_schema::source::private_message::PrivateMessage; +use lemmy_db_schema::{ + source::private_message::PrivateMessage, + traits::{Crud, DeleteableOrRemoveable}, +}; use lemmy_utils::{ApiError, ConnectionId, LemmyError}; use lemmy_websocket::{send::send_pm_ws_message, LemmyContext, UserOperationCrud}; diff --git a/crates/api_crud/src/private_message/read.rs b/crates/api_crud/src/private_message/read.rs index bf119d75c..ae2dc203f 100644 --- a/crates/api_crud/src/private_message/read.rs +++ b/crates/api_crud/src/private_message/read.rs @@ -5,7 +5,7 @@ use lemmy_api_common::{ get_local_user_view_from_jwt, person::{GetPrivateMessages, PrivateMessagesResponse}, }; -use lemmy_db_queries::DeleteableOrRemoveable; +use lemmy_db_schema::traits::DeleteableOrRemoveable; use lemmy_db_views::private_message_view::PrivateMessageQueryBuilder; use lemmy_utils::{ConnectionId, LemmyError}; use lemmy_websocket::LemmyContext; diff --git a/crates/api_crud/src/private_message/update.rs b/crates/api_crud/src/private_message/update.rs index 7ef2d71da..026a047e2 100644 --- a/crates/api_crud/src/private_message/update.rs +++ b/crates/api_crud/src/private_message/update.rs @@ -9,8 +9,7 @@ use lemmy_apub::activities::{ private_message::create_or_update::CreateOrUpdatePrivateMessage, CreateOrUpdateType, }; -use lemmy_db_queries::{source::private_message::PrivateMessage_, Crud}; -use lemmy_db_schema::source::private_message::PrivateMessage; +use lemmy_db_schema::{source::private_message::PrivateMessage, traits::Crud}; use lemmy_utils::{utils::remove_slurs, ApiError, ConnectionId, LemmyError}; use lemmy_websocket::{send::send_pm_ws_message, LemmyContext, UserOperationCrud}; diff --git a/crates/api_crud/src/site/create.rs b/crates/api_crud/src/site/create.rs index 7fdf4d3c8..865ade77f 100644 --- a/crates/api_crud/src/site/create.rs +++ b/crates/api_crud/src/site/create.rs @@ -7,13 +7,12 @@ use lemmy_api_common::{ site::*, site_description_length_check, }; -use lemmy_db_queries::{ +use lemmy_db_schema::{ diesel_option_overwrite, diesel_option_overwrite_to_url, - source::site::Site_, - Crud, + source::site::{Site, SiteForm}, + traits::Crud, }; -use lemmy_db_schema::source::site::{Site, *}; use lemmy_db_views::site_view::SiteView; use lemmy_utils::{ utils::{check_slurs, check_slurs_opt}, @@ -34,7 +33,7 @@ impl PerformCrud for CreateSite { ) -> Result { let data: &CreateSite = self; - let read_site = move |conn: &'_ _| Site::read_simple(conn); + let read_site = Site::read_simple; if blocking(context.pool(), read_site).await?.is_ok() { return Err(ApiError::err_plain("site_already_exists").into()); }; diff --git a/crates/api_crud/src/site/update.rs b/crates/api_crud/src/site/update.rs index 192fa669f..b6f06e3ad 100644 --- a/crates/api_crud/src/site/update.rs +++ b/crates/api_crud/src/site/update.rs @@ -7,15 +7,12 @@ use lemmy_api_common::{ site::{EditSite, SiteResponse}, site_description_length_check, }; -use lemmy_db_queries::{ +use lemmy_db_schema::{ diesel_option_overwrite, diesel_option_overwrite_to_url, - source::site::Site_, - Crud, -}; -use lemmy_db_schema::{ naive_now, source::site::{Site, SiteForm}, + traits::Crud, }; use lemmy_db_views::site_view::SiteView; use lemmy_utils::{utils::check_slurs_opt, ApiError, ConnectionId, LemmyError}; @@ -39,7 +36,7 @@ impl PerformCrud for EditSite { // Make sure user is an admin is_admin(&local_user_view)?; - let found_site = blocking(context.pool(), move |conn| Site::read_simple(conn)).await??; + let found_site = blocking(context.pool(), Site::read_simple).await??; let sidebar = diesel_option_overwrite(&data.sidebar); let description = diesel_option_overwrite(&data.description); diff --git a/crates/api_crud/src/user/create.rs b/crates/api_crud/src/user/create.rs index b2beeb8ed..ce37cd6a0 100644 --- a/crates/api_crud/src/user/create.rs +++ b/crates/api_crud/src/user/create.rs @@ -8,23 +8,25 @@ use lemmy_apub::{ generate_shared_inbox_url, EndpointType, }; -use lemmy_db_queries::{ - source::{local_user::LocalUser_, site::Site_}, - Crud, - Followable, - Joinable, +use lemmy_db_schema::{ + newtypes::CommunityId, + source::{ + community::{ + Community, + CommunityFollower, + CommunityFollowerForm, + CommunityForm, + CommunityModerator, + CommunityModeratorForm, + }, + local_user::{LocalUser, LocalUserForm}, + person::{Person, PersonForm}, + site::Site, + }, + traits::{Crud, Followable, Joinable}, ListingType, SortType, }; -use lemmy_db_schema::{ - source::{ - community::*, - local_user::{LocalUser, LocalUserForm}, - person::*, - site::*, - }, - CommunityId, -}; use lemmy_db_views_actor::person_view::PersonViewSafe; use lemmy_utils::{ apub::generate_actor_keypair, @@ -48,7 +50,7 @@ impl PerformCrud for Register { let data: &Register = self; // Make sure site has open registration - if let Ok(site) = blocking(context.pool(), move |conn| Site::read_simple(conn)).await? { + if let Ok(site) = blocking(context.pool(), Site::read_simple).await? { if !site.open_registration { return Err(ApiError::err_plain("registration_closed").into()); } diff --git a/crates/api_crud/src/user/delete.rs b/crates/api_crud/src/user/delete.rs index 050f54116..28f42831e 100644 --- a/crates/api_crud/src/user/delete.rs +++ b/crates/api_crud/src/user/delete.rs @@ -2,8 +2,7 @@ use crate::PerformCrud; use actix_web::web::Data; use bcrypt::verify; use lemmy_api_common::{blocking, get_local_user_view_from_jwt, person::*}; -use lemmy_db_queries::source::{comment::Comment_, person::Person_, post::Post_}; -use lemmy_db_schema::source::{comment::Comment, person::*, post::Post}; +use lemmy_db_schema::source::{comment::Comment, person::Person, post::Post}; use lemmy_utils::{ApiError, ConnectionId, LemmyError}; use lemmy_websocket::LemmyContext; diff --git a/crates/api_crud/src/user/read.rs b/crates/api_crud/src/user/read.rs index 7082d5231..4eb6771ee 100644 --- a/crates/api_crud/src/user/read.rs +++ b/crates/api_crud/src/user/read.rs @@ -2,8 +2,7 @@ use crate::PerformCrud; use actix_web::web::Data; use lemmy_api_common::{blocking, get_local_user_view_from_jwt_opt, person::*}; use lemmy_apub::{build_actor_id_from_shortname, fetcher::object_id::ObjectId, EndpointType}; -use lemmy_db_queries::{from_opt_str_to_opt_enum, SortType}; -use lemmy_db_schema::source::person::*; +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_actor::{ community_moderator_view::CommunityModeratorView, diff --git a/crates/apub/Cargo.toml b/crates/apub/Cargo.toml index 002f842d1..2bc69c4a6 100644 --- a/crates/apub/Cargo.toml +++ b/crates/apub/Cargo.toml @@ -15,7 +15,6 @@ doctest = false [dependencies] lemmy_utils = { version = "=0.13.0", path = "../utils" } lemmy_apub_lib = { version = "=0.13.0", path = "../apub_lib" } -lemmy_db_queries = { version = "=0.13.0", path = "../db_queries" } lemmy_db_schema = { version = "=0.13.0", path = "../db_schema" } lemmy_db_views = { version = "=0.13.0", path = "../db_views" } lemmy_db_views_actor = { version = "=0.13.0", path = "../db_views_actor" } diff --git a/crates/apub/src/activities/comment/create_or_update.rs b/crates/apub/src/activities/comment/create_or_update.rs index b22c240e6..c9b111837 100644 --- a/crates/apub/src/activities/comment/create_or_update.rs +++ b/crates/apub/src/activities/comment/create_or_update.rs @@ -21,8 +21,10 @@ use lemmy_apub_lib::{ values::PublicUrl, verify::verify_domains_match, }; -use lemmy_db_queries::Crud; -use lemmy_db_schema::source::{comment::Comment, community::Community, person::Person, post::Post}; +use lemmy_db_schema::{ + source::{comment::Comment, community::Community, person::Person, post::Post}, + traits::Crud, +}; use lemmy_utils::LemmyError; use lemmy_websocket::{send::send_comment_ws_message, LemmyContext, UserOperationCrud}; use serde::{Deserialize, Serialize}; diff --git a/crates/apub/src/activities/comment/mod.rs b/crates/apub/src/activities/comment/mod.rs index d24ff35de..1ac320cb9 100644 --- a/crates/apub/src/activities/comment/mod.rs +++ b/crates/apub/src/activities/comment/mod.rs @@ -7,10 +7,11 @@ use anyhow::anyhow; use itertools::Itertools; use lemmy_api_common::{blocking, send_local_notifs}; use lemmy_apub_lib::{traits::ActorType, webfinger::WebfingerResponse}; -use lemmy_db_queries::{Crud, DbPool}; use lemmy_db_schema::{ + newtypes::LocalUserId, source::{comment::Comment, community::Community, person::Person, post::Post}, - LocalUserId, + traits::Crud, + DbPool, }; use lemmy_utils::{ request::{retry, RecvError}, diff --git a/crates/apub/src/activities/community/add_mod.rs b/crates/apub/src/activities/community/add_mod.rs index 6544976b5..149b92cd2 100644 --- a/crates/apub/src/activities/community/add_mod.rs +++ b/crates/apub/src/activities/community/add_mod.rs @@ -23,10 +23,12 @@ use lemmy_apub_lib::{ traits::{ActivityFields, ActivityHandler, ActorType}, values::PublicUrl, }; -use lemmy_db_queries::{source::community::CommunityModerator_, Joinable}; -use lemmy_db_schema::source::{ - community::{Community, CommunityModerator, CommunityModeratorForm}, - person::Person, +use lemmy_db_schema::{ + source::{ + community::{Community, CommunityModerator, CommunityModeratorForm}, + person::Person, + }, + traits::Joinable, }; use lemmy_utils::LemmyError; use lemmy_websocket::LemmyContext; diff --git a/crates/apub/src/activities/community/block_user.rs b/crates/apub/src/activities/community/block_user.rs index f01c4133b..9b4c3e813 100644 --- a/crates/apub/src/activities/community/block_user.rs +++ b/crates/apub/src/activities/community/block_user.rs @@ -21,16 +21,18 @@ use lemmy_apub_lib::{ traits::{ActivityFields, ActivityHandler, ActorType}, values::PublicUrl, }; -use lemmy_db_queries::{Bannable, Followable}; -use lemmy_db_schema::source::{ - community::{ - Community, - CommunityFollower, - CommunityFollowerForm, - CommunityPersonBan, - CommunityPersonBanForm, +use lemmy_db_schema::{ + source::{ + community::{ + Community, + CommunityFollower, + CommunityFollowerForm, + CommunityPersonBan, + CommunityPersonBanForm, + }, + person::Person, }, - person::Person, + traits::{Bannable, Followable}, }; use lemmy_utils::LemmyError; use lemmy_websocket::LemmyContext; diff --git a/crates/apub/src/activities/community/remove_mod.rs b/crates/apub/src/activities/community/remove_mod.rs index 34db3c443..4f980d01a 100644 --- a/crates/apub/src/activities/community/remove_mod.rs +++ b/crates/apub/src/activities/community/remove_mod.rs @@ -24,10 +24,12 @@ use lemmy_apub_lib::{ traits::{ActivityFields, ActivityHandler, ActorType}, values::PublicUrl, }; -use lemmy_db_queries::Joinable; -use lemmy_db_schema::source::{ - community::{Community, CommunityModerator, CommunityModeratorForm}, - person::Person, +use lemmy_db_schema::{ + source::{ + community::{Community, CommunityModerator, CommunityModeratorForm}, + person::Person, + }, + traits::Joinable, }; use lemmy_utils::LemmyError; use lemmy_websocket::LemmyContext; diff --git a/crates/apub/src/activities/community/undo_block_user.rs b/crates/apub/src/activities/community/undo_block_user.rs index 1aadc9634..47cace42c 100644 --- a/crates/apub/src/activities/community/undo_block_user.rs +++ b/crates/apub/src/activities/community/undo_block_user.rs @@ -25,10 +25,12 @@ use lemmy_apub_lib::{ traits::{ActivityFields, ActivityHandler, ActorType}, values::PublicUrl, }; -use lemmy_db_queries::Bannable; -use lemmy_db_schema::source::{ - community::{Community, CommunityPersonBan, CommunityPersonBanForm}, - person::Person, +use lemmy_db_schema::{ + source::{ + community::{Community, CommunityPersonBan, CommunityPersonBanForm}, + person::Person, + }, + traits::Bannable, }; use lemmy_utils::LemmyError; use lemmy_websocket::LemmyContext; diff --git a/crates/apub/src/activities/community/update.rs b/crates/apub/src/activities/community/update.rs index b71dcc71b..02b7126ad 100644 --- a/crates/apub/src/activities/community/update.rs +++ b/crates/apub/src/activities/community/update.rs @@ -22,10 +22,12 @@ use lemmy_apub_lib::{ traits::{ActivityFields, ActivityHandler, ActorType}, values::PublicUrl, }; -use lemmy_db_queries::Crud; -use lemmy_db_schema::source::{ - community::{Community, CommunityForm}, - person::Person, +use lemmy_db_schema::{ + source::{ + community::{Community, CommunityForm}, + person::Person, + }, + traits::Crud, }; use lemmy_utils::LemmyError; use lemmy_websocket::{send::send_community_ws_message, LemmyContext, UserOperationCrud}; diff --git a/crates/apub/src/activities/deletion/delete.rs b/crates/apub/src/activities/deletion/delete.rs index 5c0051d79..251a3ffa4 100644 --- a/crates/apub/src/activities/deletion/delete.rs +++ b/crates/apub/src/activities/deletion/delete.rs @@ -26,23 +26,22 @@ use lemmy_apub_lib::{ traits::{ActivityFields, ActivityHandler, ActorType}, values::PublicUrl, }; -use lemmy_db_queries::{ - source::{comment::Comment_, community::Community_, post::Post_}, - Crud, -}; -use lemmy_db_schema::source::{ - comment::Comment, - community::Community, - moderator::{ - ModRemoveComment, - ModRemoveCommentForm, - ModRemoveCommunity, - ModRemoveCommunityForm, - ModRemovePost, - ModRemovePostForm, +use lemmy_db_schema::{ + source::{ + comment::Comment, + community::Community, + moderator::{ + ModRemoveComment, + ModRemoveCommentForm, + ModRemoveCommunity, + ModRemoveCommunityForm, + ModRemovePost, + ModRemovePostForm, + }, + person::Person, + post::Post, }, - person::Person, - post::Post, + traits::Crud, }; use lemmy_utils::LemmyError; use lemmy_websocket::{ diff --git a/crates/apub/src/activities/deletion/mod.rs b/crates/apub/src/activities/deletion/mod.rs index 7f5dfe386..3a38f2a22 100644 --- a/crates/apub/src/activities/deletion/mod.rs +++ b/crates/apub/src/activities/deletion/mod.rs @@ -12,7 +12,6 @@ use lemmy_apub_lib::{ traits::{ActivityFields, ActorType, ApubObject}, verify::verify_domains_match, }; -use lemmy_db_queries::source::{comment::Comment_, community::Community_, post::Post_}; use lemmy_db_schema::source::{comment::Comment, community::Community, person::Person, post::Post}; use lemmy_utils::LemmyError; use lemmy_websocket::{ diff --git a/crates/apub/src/activities/deletion/undo_delete.rs b/crates/apub/src/activities/deletion/undo_delete.rs index 37c2afdcb..7a96d4301 100644 --- a/crates/apub/src/activities/deletion/undo_delete.rs +++ b/crates/apub/src/activities/deletion/undo_delete.rs @@ -27,7 +27,6 @@ use lemmy_apub_lib::{ traits::{ActivityFields, ActivityHandler, ActorType}, values::PublicUrl, }; -use lemmy_db_queries::source::{comment::Comment_, community::Community_, post::Post_}; use lemmy_db_schema::source::{comment::Comment, community::Community, person::Person, post::Post}; use lemmy_utils::LemmyError; use lemmy_websocket::{ diff --git a/crates/apub/src/activities/following/accept.rs b/crates/apub/src/activities/following/accept.rs index b70b4b219..bfc9ba315 100644 --- a/crates/apub/src/activities/following/accept.rs +++ b/crates/apub/src/activities/following/accept.rs @@ -21,10 +21,12 @@ use lemmy_apub_lib::{ traits::{ActivityFields, ActivityHandler, ActorType}, verify::verify_urls_match, }; -use lemmy_db_queries::Followable; -use lemmy_db_schema::source::{ - community::{Community, CommunityFollower}, - person::Person, +use lemmy_db_schema::{ + source::{ + community::{Community, CommunityFollower}, + person::Person, + }, + traits::Followable, }; use lemmy_utils::LemmyError; use lemmy_websocket::LemmyContext; diff --git a/crates/apub/src/activities/following/follow.rs b/crates/apub/src/activities/following/follow.rs index 7e0640a1b..c75a08cd1 100644 --- a/crates/apub/src/activities/following/follow.rs +++ b/crates/apub/src/activities/following/follow.rs @@ -21,10 +21,12 @@ use lemmy_apub_lib::{ traits::{ActivityFields, ActivityHandler, ActorType}, verify::verify_urls_match, }; -use lemmy_db_queries::Followable; -use lemmy_db_schema::source::{ - community::{Community, CommunityFollower, CommunityFollowerForm}, - person::Person, +use lemmy_db_schema::{ + source::{ + community::{Community, CommunityFollower, CommunityFollowerForm}, + person::Person, + }, + traits::Followable, }; use lemmy_utils::LemmyError; use lemmy_websocket::LemmyContext; diff --git a/crates/apub/src/activities/following/undo.rs b/crates/apub/src/activities/following/undo.rs index 0c4e4a8bc..2699a98c1 100644 --- a/crates/apub/src/activities/following/undo.rs +++ b/crates/apub/src/activities/following/undo.rs @@ -21,10 +21,12 @@ use lemmy_apub_lib::{ traits::{ActivityFields, ActivityHandler, ActorType}, verify::verify_urls_match, }; -use lemmy_db_queries::Followable; -use lemmy_db_schema::source::{ - community::{Community, CommunityFollower, CommunityFollowerForm}, - person::Person, +use lemmy_db_schema::{ + source::{ + community::{Community, CommunityFollower, CommunityFollowerForm}, + person::Person, + }, + traits::Followable, }; use lemmy_utils::LemmyError; use lemmy_websocket::LemmyContext; diff --git a/crates/apub/src/activities/post/create_or_update.rs b/crates/apub/src/activities/post/create_or_update.rs index f1a336680..7a1ddc406 100644 --- a/crates/apub/src/activities/post/create_or_update.rs +++ b/crates/apub/src/activities/post/create_or_update.rs @@ -21,8 +21,10 @@ use lemmy_apub_lib::{ values::PublicUrl, verify::{verify_domains_match, verify_urls_match}, }; -use lemmy_db_queries::Crud; -use lemmy_db_schema::source::{community::Community, person::Person, post::Post}; +use lemmy_db_schema::{ + source::{community::Community, person::Person, post::Post}, + traits::Crud, +}; use lemmy_utils::LemmyError; use lemmy_websocket::{send::send_post_ws_message, LemmyContext, UserOperationCrud}; use serde::{Deserialize, Serialize}; diff --git a/crates/apub/src/activities/private_message/create_or_update.rs b/crates/apub/src/activities/private_message/create_or_update.rs index a5f14d52f..6b3bc2b62 100644 --- a/crates/apub/src/activities/private_message/create_or_update.rs +++ b/crates/apub/src/activities/private_message/create_or_update.rs @@ -12,8 +12,10 @@ use lemmy_apub_lib::{ traits::{ActivityFields, ActivityHandler, ActorType}, verify::verify_domains_match, }; -use lemmy_db_queries::Crud; -use lemmy_db_schema::source::{person::Person, private_message::PrivateMessage}; +use lemmy_db_schema::{ + source::{person::Person, private_message::PrivateMessage}, + traits::Crud, +}; use lemmy_utils::LemmyError; use lemmy_websocket::{send::send_pm_ws_message, LemmyContext, UserOperationCrud}; use serde::{Deserialize, Serialize}; diff --git a/crates/apub/src/activities/private_message/delete.rs b/crates/apub/src/activities/private_message/delete.rs index 865cc785b..ded3b3ad4 100644 --- a/crates/apub/src/activities/private_message/delete.rs +++ b/crates/apub/src/activities/private_message/delete.rs @@ -16,8 +16,10 @@ use lemmy_apub_lib::{ traits::{ActivityFields, ActivityHandler, ActorType}, verify::verify_domains_match, }; -use lemmy_db_queries::{source::private_message::PrivateMessage_, Crud}; -use lemmy_db_schema::source::{person::Person, private_message::PrivateMessage}; +use lemmy_db_schema::{ + source::{person::Person, private_message::PrivateMessage}, + traits::Crud, +}; use lemmy_utils::LemmyError; use lemmy_websocket::{send::send_pm_ws_message, LemmyContext, UserOperationCrud}; use serde::{Deserialize, Serialize}; diff --git a/crates/apub/src/activities/private_message/undo_delete.rs b/crates/apub/src/activities/private_message/undo_delete.rs index e609b1e44..2c5fd0e72 100644 --- a/crates/apub/src/activities/private_message/undo_delete.rs +++ b/crates/apub/src/activities/private_message/undo_delete.rs @@ -21,8 +21,10 @@ use lemmy_apub_lib::{ traits::{ActivityFields, ActivityHandler, ActorType}, verify::{verify_domains_match, verify_urls_match}, }; -use lemmy_db_queries::{source::private_message::PrivateMessage_, Crud}; -use lemmy_db_schema::source::{person::Person, private_message::PrivateMessage}; +use lemmy_db_schema::{ + source::{person::Person, private_message::PrivateMessage}, + traits::Crud, +}; use lemmy_utils::LemmyError; use lemmy_websocket::{send::send_pm_ws_message, LemmyContext, UserOperationCrud}; use serde::{Deserialize, Serialize}; diff --git a/crates/apub/src/activities/report.rs b/crates/apub/src/activities/report.rs index c08210b3d..aee673cfa 100644 --- a/crates/apub/src/activities/report.rs +++ b/crates/apub/src/activities/report.rs @@ -16,15 +16,15 @@ use lemmy_apub_lib::{ data::Data, traits::{ActivityFields, ActivityHandler, ActorType}, }; -use lemmy_db_queries::{Crud, Reportable}; use lemmy_db_schema::{ + newtypes::CommunityId, source::{ comment_report::{CommentReport, CommentReportForm}, community::Community, person::Person, post_report::{PostReport, PostReportForm}, }, - CommunityId, + traits::{Crud, Reportable}, }; use lemmy_db_views::{comment_report_view::CommentReportView, post_report_view::PostReportView}; use lemmy_utils::LemmyError; diff --git a/crates/apub/src/activities/voting/mod.rs b/crates/apub/src/activities/voting/mod.rs index 48d44c0ee..90757eebf 100644 --- a/crates/apub/src/activities/voting/mod.rs +++ b/crates/apub/src/activities/voting/mod.rs @@ -1,10 +1,12 @@ use crate::activities::voting::vote::VoteType; use lemmy_api_common::blocking; -use lemmy_db_queries::Likeable; -use lemmy_db_schema::source::{ - comment::{Comment, CommentLike, CommentLikeForm}, - person::Person, - post::{Post, PostLike, PostLikeForm}, +use lemmy_db_schema::{ + source::{ + comment::{Comment, CommentLike, CommentLikeForm}, + person::Person, + post::{Post, PostLike, PostLikeForm}, + }, + traits::Likeable, }; use lemmy_utils::LemmyError; use lemmy_websocket::{ diff --git a/crates/apub/src/activities/voting/undo_vote.rs b/crates/apub/src/activities/voting/undo_vote.rs index bfb74371d..2c87aa899 100644 --- a/crates/apub/src/activities/voting/undo_vote.rs +++ b/crates/apub/src/activities/voting/undo_vote.rs @@ -27,10 +27,10 @@ use lemmy_apub_lib::{ values::PublicUrl, verify::verify_urls_match, }; -use lemmy_db_queries::Crud; use lemmy_db_schema::{ + newtypes::CommunityId, source::{community::Community, person::Person}, - CommunityId, + traits::Crud, }; use lemmy_utils::LemmyError; use lemmy_websocket::LemmyContext; diff --git a/crates/apub/src/activities/voting/vote.rs b/crates/apub/src/activities/voting/vote.rs index 4d8537546..2463cbc02 100644 --- a/crates/apub/src/activities/voting/vote.rs +++ b/crates/apub/src/activities/voting/vote.rs @@ -18,10 +18,10 @@ use lemmy_apub_lib::{ traits::{ActivityFields, ActivityHandler, ActorType}, values::PublicUrl, }; -use lemmy_db_queries::Crud; use lemmy_db_schema::{ + newtypes::CommunityId, source::{community::Community, person::Person}, - CommunityId, + traits::Crud, }; use lemmy_utils::LemmyError; use lemmy_websocket::LemmyContext; diff --git a/crates/apub/src/fetcher/community.rs b/crates/apub/src/fetcher/community.rs index 62749f6e3..646f8fcad 100644 --- a/crates/apub/src/fetcher/community.rs +++ b/crates/apub/src/fetcher/community.rs @@ -7,10 +7,12 @@ use activitystreams::collection::{CollectionExt, OrderedCollection}; use anyhow::Context; use lemmy_api_common::blocking; use lemmy_apub_lib::{data::Data, traits::ActivityHandler}; -use lemmy_db_queries::Joinable; -use lemmy_db_schema::source::{ - community::{Community, CommunityModerator, CommunityModeratorForm}, - person::Person, +use lemmy_db_schema::{ + source::{ + community::{Community, CommunityModerator, CommunityModeratorForm}, + person::Person, + }, + traits::Joinable, }; use lemmy_db_views_actor::community_moderator_view::CommunityModeratorView; use lemmy_utils::{location_info, LemmyError}; diff --git a/crates/apub/src/fetcher/object_id.rs b/crates/apub/src/fetcher/object_id.rs index 14e983bb3..771c276a5 100644 --- a/crates/apub/src/fetcher/object_id.rs +++ b/crates/apub/src/fetcher/object_id.rs @@ -3,8 +3,7 @@ use anyhow::anyhow; use diesel::{NotFound, PgConnection}; use lemmy_api_common::blocking; use lemmy_apub_lib::{traits::ApubObject, APUB_JSON_CONTENT_TYPE}; -use lemmy_db_queries::DbPool; -use lemmy_db_schema::DbUrl; +use lemmy_db_schema::{newtypes::DbUrl, DbPool}; use lemmy_utils::{request::retry, settings::structs::Settings, LemmyError}; use lemmy_websocket::LemmyContext; use reqwest::StatusCode; diff --git a/crates/apub/src/fetcher/search.rs b/crates/apub/src/fetcher/search.rs index 9fcf5a79c..d7b9a0bfd 100644 --- a/crates/apub/src/fetcher/search.rs +++ b/crates/apub/src/fetcher/search.rs @@ -11,11 +11,10 @@ use lemmy_apub_lib::{ traits::ApubObject, webfinger::{webfinger_resolve_actor, WebfingerType}, }; -use lemmy_db_queries::{ - source::{community::Community_, person::Person_}, +use lemmy_db_schema::{ + source::{comment::Comment, community::Community, person::Person, post::Post}, DbPool, }; -use lemmy_db_schema::source::{comment::Comment, community::Community, person::Person, post::Post}; use lemmy_utils::LemmyError; use lemmy_websocket::LemmyContext; use serde::Deserialize; diff --git a/crates/apub/src/http/comment.rs b/crates/apub/src/http/comment.rs index 4f63d89d3..769a9dd85 100644 --- a/crates/apub/src/http/comment.rs +++ b/crates/apub/src/http/comment.rs @@ -5,8 +5,7 @@ use crate::{ use actix_web::{body::Body, web, web::Path, HttpResponse}; use diesel::result::Error::NotFound; use lemmy_api_common::blocking; -use lemmy_db_queries::Crud; -use lemmy_db_schema::{source::comment::Comment, CommentId}; +use lemmy_db_schema::{newtypes::CommentId, source::comment::Comment, traits::Crud}; use lemmy_utils::LemmyError; use lemmy_websocket::LemmyContext; use serde::Deserialize; diff --git a/crates/apub/src/http/community.rs b/crates/apub/src/http/community.rs index 3f74b622a..2094d15d3 100644 --- a/crates/apub/src/http/community.rs +++ b/crates/apub/src/http/community.rs @@ -24,7 +24,6 @@ use activitystreams::{ use actix_web::{body::Body, web, web::Payload, HttpRequest, HttpResponse}; use lemmy_api_common::blocking; use lemmy_apub_lib::traits::{ActivityFields, ActivityHandler}; -use lemmy_db_queries::source::{activity::Activity_, community::Community_}; use lemmy_db_schema::source::{activity::Activity, community::Community}; use lemmy_db_views_actor::{ community_follower_view::CommunityFollowerView, diff --git a/crates/apub/src/http/mod.rs b/crates/apub/src/http/mod.rs index f9c0d2740..b82a6d890 100644 --- a/crates/apub/src/http/mod.rs +++ b/crates/apub/src/http/mod.rs @@ -24,8 +24,7 @@ use lemmy_apub_lib::{ traits::{ActivityFields, ActivityHandler}, APUB_JSON_CONTENT_TYPE, }; -use lemmy_db_queries::{source::activity::Activity_, DbPool}; -use lemmy_db_schema::source::activity::Activity; +use lemmy_db_schema::{source::activity::Activity, DbPool}; use lemmy_utils::{location_info, LemmyError}; use lemmy_websocket::LemmyContext; use log::{info, trace}; diff --git a/crates/apub/src/http/person.rs b/crates/apub/src/http/person.rs index e84ab2de0..36b6b7d9d 100644 --- a/crates/apub/src/http/person.rs +++ b/crates/apub/src/http/person.rs @@ -25,7 +25,6 @@ use activitystreams::{ use actix_web::{body::Body, web, web::Payload, HttpRequest, HttpResponse}; use lemmy_api_common::blocking; use lemmy_apub_lib::traits::{ActivityFields, ActivityHandler}; -use lemmy_db_queries::source::person::Person_; use lemmy_db_schema::source::person::Person; use lemmy_utils::LemmyError; use lemmy_websocket::LemmyContext; diff --git a/crates/apub/src/http/post.rs b/crates/apub/src/http/post.rs index 324bb7da9..c5f22d01c 100644 --- a/crates/apub/src/http/post.rs +++ b/crates/apub/src/http/post.rs @@ -5,8 +5,7 @@ use crate::{ use actix_web::{body::Body, web, HttpResponse}; use diesel::result::Error::NotFound; use lemmy_api_common::blocking; -use lemmy_db_queries::Crud; -use lemmy_db_schema::{source::post::Post, PostId}; +use lemmy_db_schema::{newtypes::PostId, source::post::Post, traits::Crud}; use lemmy_utils::LemmyError; use lemmy_websocket::LemmyContext; use serde::Deserialize; diff --git a/crates/apub/src/lib.rs b/crates/apub/src/lib.rs index 2162b644c..cc9d5f487 100644 --- a/crates/apub/src/lib.rs +++ b/crates/apub/src/lib.rs @@ -9,11 +9,10 @@ use crate::fetcher::post_or_comment::PostOrComment; use anyhow::{anyhow, Context}; use lemmy_api_common::blocking; use lemmy_apub_lib::{activity_queue::send_activity, traits::ActorType}; -use lemmy_db_queries::{source::activity::Activity_, DbPool}; use lemmy_db_schema::{ + newtypes::{CommunityId, DbUrl}, source::{activity::Activity, person::Person}, - CommunityId, - DbUrl, + DbPool, }; use lemmy_db_views_actor::community_person_ban_view::CommunityPersonBanView; use lemmy_utils::{location_info, settings::structs::Settings, LemmyError}; diff --git a/crates/apub/src/objects/comment.rs b/crates/apub/src/objects/comment.rs index f47c11bfb..1748af791 100644 --- a/crates/apub/src/objects/comment.rs +++ b/crates/apub/src/objects/comment.rs @@ -20,15 +20,16 @@ use lemmy_apub_lib::{ values::{MediaTypeHtml, MediaTypeMarkdown, PublicUrl}, verify::verify_domains_match, }; -use lemmy_db_queries::{source::comment::Comment_, Crud, DbPool}; use lemmy_db_schema::{ + newtypes::CommentId, source::{ comment::{Comment, CommentForm}, community::Community, person::Person, post::Post, }, - CommentId, + traits::Crud, + DbPool, }; use lemmy_utils::{ location_info, diff --git a/crates/apub/src/objects/community.rs b/crates/apub/src/objects/community.rs index 4087383ab..324ae259c 100644 --- a/crates/apub/src/objects/community.rs +++ b/crates/apub/src/objects/community.rs @@ -23,10 +23,10 @@ use lemmy_apub_lib::{ values::{MediaTypeHtml, MediaTypeMarkdown}, verify::verify_domains_match, }; -use lemmy_db_queries::{source::community::Community_, DbPool}; use lemmy_db_schema::{ naive_now, source::community::{Community, CommunityForm}, + DbPool, }; use lemmy_db_views_actor::community_follower_view::CommunityFollowerView; use lemmy_utils::{ diff --git a/crates/apub/src/objects/mod.rs b/crates/apub/src/objects/mod.rs index b05a944cd..b558902fa 100644 --- a/crates/apub/src/objects/mod.rs +++ b/crates/apub/src/objects/mod.rs @@ -5,7 +5,7 @@ use activitystreams::{ use anyhow::anyhow; use chrono::NaiveDateTime; use lemmy_apub_lib::values::MediaTypeMarkdown; -use lemmy_db_queries::DbPool; +use lemmy_db_schema::DbPool; use lemmy_utils::{utils::convert_datetime, LemmyError}; use lemmy_websocket::LemmyContext; use url::Url; diff --git a/crates/apub/src/objects/person.rs b/crates/apub/src/objects/person.rs index 73e34794f..45c67f443 100644 --- a/crates/apub/src/objects/person.rs +++ b/crates/apub/src/objects/person.rs @@ -19,10 +19,10 @@ use lemmy_apub_lib::{ values::{MediaTypeHtml, MediaTypeMarkdown}, verify::verify_domains_match, }; -use lemmy_db_queries::{source::person::Person_, DbPool}; use lemmy_db_schema::{ naive_now, source::person::{Person as DbPerson, PersonForm}, + DbPool, }; use lemmy_utils::{ utils::{check_slurs, check_slurs_opt, convert_datetime, markdown_to_html}, diff --git a/crates/apub/src/objects/post.rs b/crates/apub/src/objects/post.rs index c18647dd1..bb3010380 100644 --- a/crates/apub/src/objects/post.rs +++ b/crates/apub/src/objects/post.rs @@ -21,7 +21,6 @@ use lemmy_apub_lib::{ values::{MediaTypeHtml, MediaTypeMarkdown}, verify::verify_domains_match, }; -use lemmy_db_queries::{source::post::Post_, Crud, DbPool}; use lemmy_db_schema::{ self, source::{ @@ -29,6 +28,8 @@ use lemmy_db_schema::{ person::Person, post::{Post, PostForm}, }, + traits::Crud, + DbPool, }; use lemmy_utils::{ request::fetch_site_data, diff --git a/crates/apub/src/objects/private_message.rs b/crates/apub/src/objects/private_message.rs index 0a3822772..8cf40c9e4 100644 --- a/crates/apub/src/objects/private_message.rs +++ b/crates/apub/src/objects/private_message.rs @@ -16,10 +16,13 @@ use lemmy_apub_lib::{ values::{MediaTypeHtml, MediaTypeMarkdown}, verify::verify_domains_match, }; -use lemmy_db_queries::{source::private_message::PrivateMessage_, Crud, DbPool}; -use lemmy_db_schema::source::{ - person::Person, - private_message::{PrivateMessage, PrivateMessageForm}, +use lemmy_db_schema::{ + source::{ + person::Person, + private_message::{PrivateMessage, PrivateMessageForm}, + }, + traits::Crud, + DbPool, }; use lemmy_utils::{utils::convert_datetime, LemmyError}; use lemmy_websocket::LemmyContext; diff --git a/crates/db_queries/Cargo.toml b/crates/db_queries/Cargo.toml deleted file mode 100644 index 6fcd1f8d0..000000000 --- a/crates/db_queries/Cargo.toml +++ /dev/null @@ -1,33 +0,0 @@ -[package] -name = "lemmy_db_queries" -version = "0.13.0" -edition = "2018" -description = "A link aggregator for the fediverse" -license = "AGPL-3.0" -homepage = "https://join-lemmy.org/" -documentation = "https://join-lemmy.org/docs/en/index.html" - -[lib] -name = "lemmy_db_queries" -path = "src/lib.rs" -doctest = false - -[dependencies] -lemmy_utils = { version = "=0.13.0", path = "../utils" } -lemmy_db_schema = { version = "=0.13.0", path = "../db_schema" } -diesel = { version = "1.4.8", features = ["postgres","chrono","r2d2","serde_json"] } -diesel_migrations = "1.4.0" -chrono = { version = "0.4.19", features = ["serde"] } -serde = { version = "1.0.130", features = ["derive"] } -serde_json = { version = "1.0.68", features = ["preserve_order"] } -strum = "0.21.0" -strum_macros = "0.21.1" -log = "0.4.14" -sha2 = "0.9.8" -url = { version = "2.2.2", features = ["serde"] } -lazy_static = "1.4.0" -regex = "1.5.4" -bcrypt = "0.10.1" - -[dev-dependencies] -serial_test = "0.5.1" diff --git a/crates/db_queries/src/lib.rs b/crates/db_queries/src/lib.rs deleted file mode 100644 index aa3c06da1..000000000 --- a/crates/db_queries/src/lib.rs +++ /dev/null @@ -1,348 +0,0 @@ -#[macro_use] -extern crate diesel; -#[macro_use] -extern crate strum_macros; -#[macro_use] -extern crate lazy_static; -// this is used in tests -#[allow(unused_imports)] -#[macro_use] -extern crate diesel_migrations; - -#[cfg(test)] -extern crate serial_test; - -use diesel::{result::Error, *}; -use lemmy_db_schema::{CommunityId, DbUrl, PersonId}; -use lemmy_utils::ApiError; -use regex::Regex; -use serde::{Deserialize, Serialize}; -use std::{env, env::VarError}; -use url::Url; - -pub mod aggregates; -pub mod source; - -pub type DbPool = diesel::r2d2::Pool>; - -pub trait Crud { - type Form; - type IdType; - fn create(conn: &PgConnection, form: &Self::Form) -> Result - where - Self: Sized; - fn read(conn: &PgConnection, id: Self::IdType) -> Result - where - Self: Sized; - fn update(conn: &PgConnection, id: Self::IdType, form: &Self::Form) -> Result - where - Self: Sized; - fn delete(_conn: &PgConnection, _id: Self::IdType) -> Result - where - Self: Sized, - { - unimplemented!() - } -} - -pub trait Followable { - type Form; - fn follow(conn: &PgConnection, form: &Self::Form) -> Result - where - Self: Sized; - fn follow_accepted( - conn: &PgConnection, - community_id: CommunityId, - person_id: PersonId, - ) -> Result - where - Self: Sized; - fn unfollow(conn: &PgConnection, form: &Self::Form) -> Result - where - Self: Sized; - fn has_local_followers(conn: &PgConnection, community_id: CommunityId) -> Result; -} - -pub trait Joinable { - type Form; - fn join(conn: &PgConnection, form: &Self::Form) -> Result - where - Self: Sized; - fn leave(conn: &PgConnection, form: &Self::Form) -> Result - where - Self: Sized; -} - -pub trait Likeable { - type Form; - type IdType; - fn like(conn: &PgConnection, form: &Self::Form) -> Result - where - Self: Sized; - fn remove( - conn: &PgConnection, - person_id: PersonId, - item_id: Self::IdType, - ) -> Result - where - Self: Sized; -} - -pub trait Bannable { - type Form; - fn ban(conn: &PgConnection, form: &Self::Form) -> Result - where - Self: Sized; - fn unban(conn: &PgConnection, form: &Self::Form) -> Result - where - Self: Sized; -} - -pub trait Saveable { - type Form; - fn save(conn: &PgConnection, form: &Self::Form) -> Result - where - Self: Sized; - fn unsave(conn: &PgConnection, form: &Self::Form) -> Result - where - Self: Sized; -} - -pub trait Blockable { - type Form; - fn block(conn: &PgConnection, form: &Self::Form) -> Result - where - Self: Sized; - fn unblock(conn: &PgConnection, form: &Self::Form) -> Result - where - Self: Sized; -} - -pub trait Readable { - type Form; - fn mark_as_read(conn: &PgConnection, form: &Self::Form) -> Result - where - Self: Sized; - fn mark_as_unread(conn: &PgConnection, form: &Self::Form) -> Result - where - Self: Sized; -} - -pub trait Reportable { - type Form; - type IdType; - fn report(conn: &PgConnection, form: &Self::Form) -> Result - where - Self: Sized; - fn resolve( - conn: &PgConnection, - report_id: Self::IdType, - resolver_id: PersonId, - ) -> Result - where - Self: Sized; - fn unresolve( - conn: &PgConnection, - report_id: Self::IdType, - resolver_id: PersonId, - ) -> Result - where - Self: Sized; -} - -pub trait DeleteableOrRemoveable { - fn blank_out_deleted_or_removed_info(self) -> Self; -} - -pub trait MaybeOptional { - fn get_optional(self) -> Option; -} - -impl MaybeOptional for T { - fn get_optional(self) -> Option { - Some(self) - } -} - -impl MaybeOptional for Option { - fn get_optional(self) -> Option { - self - } -} - -pub trait ToSafe { - type SafeColumns; - fn safe_columns_tuple() -> Self::SafeColumns; -} - -pub trait ToSafeSettings { - type SafeSettingsColumns; - fn safe_settings_columns_tuple() -> Self::SafeSettingsColumns; -} - -pub trait ViewToVec { - type DbTuple; - fn from_tuple_to_vec(tuple: Vec) -> Vec - where - Self: Sized; -} - -pub fn get_database_url_from_env() -> Result { - env::var("LEMMY_DATABASE_URL") -} - -#[derive(EnumString, ToString, Debug, Serialize, Deserialize, Clone, Copy)] -pub enum SortType { - Active, - Hot, - New, - TopDay, - TopWeek, - TopMonth, - TopYear, - TopAll, - MostComments, - NewComments, -} - -#[derive(EnumString, ToString, Debug, Serialize, Deserialize, Clone, Copy)] -pub enum ListingType { - All, - Local, - Subscribed, - Community, -} - -#[derive(EnumString, ToString, Debug, Serialize, Deserialize, Clone, Copy)] -pub enum SearchType { - All, - Comments, - Posts, - Communities, - Users, - Url, -} - -pub fn from_opt_str_to_opt_enum(opt: &Option) -> Option { - opt.as_ref().map(|t| T::from_str(t).ok()).flatten() -} - -pub fn fuzzy_search(q: &str) -> String { - let replaced = q.replace(" ", "%"); - format!("%{}%", replaced) -} - -pub fn limit_and_offset(page: Option, limit: Option) -> (i64, i64) { - let page = page.unwrap_or(1); - let limit = limit.unwrap_or(10); - let offset = limit * (page - 1); - (limit, offset) -} - -pub fn is_email_regex(test: &str) -> bool { - EMAIL_REGEX.is_match(test) -} - -pub fn diesel_option_overwrite(opt: &Option) -> Option> { - match opt { - // An empty string is an erase - Some(unwrapped) => { - if !unwrapped.eq("") { - Some(Some(unwrapped.to_owned())) - } else { - Some(None) - } - } - None => None, - } -} - -pub fn diesel_option_overwrite_to_url( - opt: &Option, -) -> Result>, ApiError> { - match opt.as_ref().map(|s| s.as_str()) { - // An empty string is an erase - Some("") => Ok(Some(None)), - Some(str_url) => match Url::parse(str_url) { - Ok(url) => Ok(Some(Some(url.into()))), - Err(e) => Err(ApiError::err("invalid_url", e)), - }, - None => Ok(None), - } -} - -embed_migrations!(); - -pub fn establish_unpooled_connection() -> PgConnection { - let db_url = match get_database_url_from_env() { - Ok(url) => url, - Err(e) => panic!( - "Failed to read database URL from env var LEMMY_DATABASE_URL: {}", - e - ), - }; - let conn = - PgConnection::establish(&db_url).unwrap_or_else(|_| panic!("Error connecting to {}", db_url)); - embedded_migrations::run(&conn).expect("load migrations"); - conn -} - -lazy_static! { - static ref EMAIL_REGEX: Regex = - Regex::new(r"^[a-zA-Z0-9.!#$%&’*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*$") - .expect("compile email regex"); -} - -pub mod functions { - use diesel::sql_types::*; - - sql_function! { - fn hot_rank(score: BigInt, time: Timestamp) -> Integer; - } -} - -#[cfg(test)] -mod tests { - use super::{fuzzy_search, *}; - use crate::is_email_regex; - - #[test] - fn test_fuzzy_search() { - let test = "This is a fuzzy search"; - assert_eq!(fuzzy_search(test), "%This%is%a%fuzzy%search%".to_string()); - } - - #[test] - fn test_email() { - assert!(is_email_regex("gush@gmail.com")); - assert!(!is_email_regex("nada_neutho")); - } - - #[test] - fn test_diesel_option_overwrite() { - assert_eq!(diesel_option_overwrite(&None), None); - assert_eq!(diesel_option_overwrite(&Some("".to_string())), Some(None)); - assert_eq!( - diesel_option_overwrite(&Some("test".to_string())), - Some(Some("test".to_string())) - ); - } - - #[test] - fn test_diesel_option_overwrite_to_url() { - assert!(matches!(diesel_option_overwrite_to_url(&None), Ok(None))); - assert!(matches!( - diesel_option_overwrite_to_url(&Some("".to_string())), - Ok(Some(None)) - )); - assert!(matches!( - diesel_option_overwrite_to_url(&Some("invalid_url".to_string())), - Err(_) - )); - let example_url = "https://example.com"; - assert!(matches!( - diesel_option_overwrite_to_url(&Some(example_url.to_string())), - Ok(Some(Some(url))) if url == Url::parse(example_url).unwrap().into() - )); - } -} diff --git a/crates/db_queries/src/source/secret.rs b/crates/db_queries/src/source/secret.rs deleted file mode 100644 index 6181549fe..000000000 --- a/crates/db_queries/src/source/secret.rs +++ /dev/null @@ -1,19 +0,0 @@ -use diesel::{result::Error, *}; -use lemmy_db_schema::source::secret::Secret; - -pub trait Secret_ { - fn init(conn: &PgConnection) -> Result; -} - -impl Secret_ for Secret { - /// Initialize the Secrets from the DB. - /// Warning: You should only call this once. - fn init(conn: &PgConnection) -> Result { - read_secrets(conn) - } -} - -fn read_secrets(conn: &PgConnection) -> Result { - use lemmy_db_schema::schema::secret::dsl::*; - secret.first::(conn) -} diff --git a/crates/db_schema/Cargo.toml b/crates/db_schema/Cargo.toml index 66b0a293d..a05aed47d 100644 --- a/crates/db_schema/Cargo.toml +++ b/crates/db_schema/Cargo.toml @@ -14,9 +14,19 @@ doctest = false lemmy_utils = { version = "=0.13.0", path = "../utils" } lemmy_apub_lib = { version = "=0.13.0", path = "../apub_lib" } diesel = { version = "1.4.8", features = ["postgres","chrono","r2d2","serde_json"] } +diesel_migrations = "1.4.0" chrono = { version = "0.4.19", features = ["serde"] } serde = { version = "1.0.130", features = ["derive"] } serde_json = { version = "1.0.68", features = ["preserve_order"] } log = "0.4.14" url = { version = "2.2.2", features = ["serde"] } diesel-derive-newtype = "0.1.2" +regex = "1.5.4" +lazy_static = "1.4.0" +strum = "0.21.0" +strum_macros = "0.21.1" +sha2 = "0.9.8" +bcrypt = "0.10.1" + +[dev-dependencies] +serial_test = "0.5.1" \ No newline at end of file diff --git a/crates/db_queries/src/aggregates/comment_aggregates.rs b/crates/db_schema/src/aggregates/comment_aggregates.rs similarity index 93% rename from crates/db_queries/src/aggregates/comment_aggregates.rs rename to crates/db_schema/src/aggregates/comment_aggregates.rs index 4fbc646b1..d47899bbf 100644 --- a/crates/db_queries/src/aggregates/comment_aggregates.rs +++ b/crates/db_schema/src/aggregates/comment_aggregates.rs @@ -1,5 +1,5 @@ +use crate::{newtypes::CommentId, schema::comment_aggregates}; use diesel::{result::Error, *}; -use lemmy_db_schema::{schema::comment_aggregates, CommentId}; use serde::{Deserialize, Serialize}; #[derive( @@ -28,14 +28,13 @@ mod tests { use crate::{ aggregates::comment_aggregates::CommentAggregates, establish_unpooled_connection, - Crud, - Likeable, - }; - use lemmy_db_schema::source::{ - comment::{Comment, CommentForm, CommentLike, CommentLikeForm}, - community::{Community, CommunityForm}, - person::{Person, PersonForm}, - post::{Post, PostForm}, + source::{ + comment::{Comment, CommentForm, CommentLike, CommentLikeForm}, + community::{Community, CommunityForm}, + person::{Person, PersonForm}, + post::{Post, PostForm}, + }, + traits::{Crud, Likeable}, }; use serial_test::serial; diff --git a/crates/db_queries/src/aggregates/community_aggregates.rs b/crates/db_schema/src/aggregates/community_aggregates.rs similarity index 94% rename from crates/db_queries/src/aggregates/community_aggregates.rs rename to crates/db_schema/src/aggregates/community_aggregates.rs index d8865d409..d80425e17 100644 --- a/crates/db_queries/src/aggregates/community_aggregates.rs +++ b/crates/db_schema/src/aggregates/community_aggregates.rs @@ -1,5 +1,5 @@ +use crate::{newtypes::CommunityId, schema::community_aggregates}; use diesel::{result::Error, *}; -use lemmy_db_schema::{schema::community_aggregates, CommunityId}; use serde::{Deserialize, Serialize}; #[derive( @@ -32,14 +32,13 @@ mod tests { use crate::{ aggregates::community_aggregates::CommunityAggregates, establish_unpooled_connection, - Crud, - Followable, - }; - use lemmy_db_schema::source::{ - comment::{Comment, CommentForm}, - community::{Community, CommunityFollower, CommunityFollowerForm, CommunityForm}, - person::{Person, PersonForm}, - post::{Post, PostForm}, + source::{ + comment::{Comment, CommentForm}, + community::{Community, CommunityFollower, CommunityFollowerForm, CommunityForm}, + person::{Person, PersonForm}, + post::{Post, PostForm}, + }, + traits::{Crud, Followable}, }; use serial_test::serial; diff --git a/crates/db_queries/src/aggregates/mod.rs b/crates/db_schema/src/aggregates/mod.rs similarity index 100% rename from crates/db_queries/src/aggregates/mod.rs rename to crates/db_schema/src/aggregates/mod.rs diff --git a/crates/db_queries/src/aggregates/person_aggregates.rs b/crates/db_schema/src/aggregates/person_aggregates.rs similarity index 94% rename from crates/db_queries/src/aggregates/person_aggregates.rs rename to crates/db_schema/src/aggregates/person_aggregates.rs index 16d480dec..344ec27d9 100644 --- a/crates/db_queries/src/aggregates/person_aggregates.rs +++ b/crates/db_schema/src/aggregates/person_aggregates.rs @@ -1,5 +1,5 @@ +use crate::{newtypes::PersonId, schema::person_aggregates}; use diesel::{result::Error, *}; -use lemmy_db_schema::{schema::person_aggregates, PersonId}; use serde::{Deserialize, Serialize}; #[derive( @@ -28,14 +28,13 @@ mod tests { use crate::{ aggregates::person_aggregates::PersonAggregates, establish_unpooled_connection, - Crud, - Likeable, - }; - use lemmy_db_schema::source::{ - comment::{Comment, CommentForm, CommentLike, CommentLikeForm}, - community::{Community, CommunityForm}, - person::{Person, PersonForm}, - post::{Post, PostForm, PostLike, PostLikeForm}, + source::{ + comment::{Comment, CommentForm, CommentLike, CommentLikeForm}, + community::{Community, CommunityForm}, + person::{Person, PersonForm}, + post::{Post, PostForm, PostLike, PostLikeForm}, + }, + traits::{Crud, Likeable}, }; use serial_test::serial; diff --git a/crates/db_queries/src/aggregates/post_aggregates.rs b/crates/db_schema/src/aggregates/post_aggregates.rs similarity index 94% rename from crates/db_queries/src/aggregates/post_aggregates.rs rename to crates/db_schema/src/aggregates/post_aggregates.rs index 323b55ab6..cb8aba26e 100644 --- a/crates/db_queries/src/aggregates/post_aggregates.rs +++ b/crates/db_schema/src/aggregates/post_aggregates.rs @@ -1,5 +1,5 @@ +use crate::{newtypes::PostId, schema::post_aggregates}; use diesel::{result::Error, *}; -use lemmy_db_schema::{schema::post_aggregates, PostId}; use serde::{Deserialize, Serialize}; #[derive( @@ -32,14 +32,13 @@ mod tests { use crate::{ aggregates::post_aggregates::PostAggregates, establish_unpooled_connection, - Crud, - Likeable, - }; - use lemmy_db_schema::source::{ - comment::{Comment, CommentForm}, - community::{Community, CommunityForm}, - person::{Person, PersonForm}, - post::{Post, PostForm, PostLike, PostLikeForm}, + source::{ + comment::{Comment, CommentForm}, + community::{Community, CommunityForm}, + person::{Person, PersonForm}, + post::{Post, PostForm, PostLike, PostLikeForm}, + }, + traits::{Crud, Likeable}, }; use serial_test::serial; diff --git a/crates/db_queries/src/aggregates/site_aggregates.rs b/crates/db_schema/src/aggregates/site_aggregates.rs similarity index 91% rename from crates/db_queries/src/aggregates/site_aggregates.rs rename to crates/db_schema/src/aggregates/site_aggregates.rs index af0f7cb4d..4b4b6c432 100644 --- a/crates/db_queries/src/aggregates/site_aggregates.rs +++ b/crates/db_schema/src/aggregates/site_aggregates.rs @@ -1,5 +1,5 @@ +use crate::schema::site_aggregates; use diesel::{result::Error, *}; -use lemmy_db_schema::schema::site_aggregates; use serde::{Deserialize, Serialize}; #[derive( @@ -27,13 +27,17 @@ impl SiteAggregates { #[cfg(test)] mod tests { - use crate::{aggregates::site_aggregates::SiteAggregates, establish_unpooled_connection, Crud}; - use lemmy_db_schema::source::{ - comment::{Comment, CommentForm}, - community::{Community, CommunityForm}, - person::{Person, PersonForm}, - post::{Post, PostForm}, - site::{Site, SiteForm}, + use crate::{ + aggregates::site_aggregates::SiteAggregates, + establish_unpooled_connection, + source::{ + comment::{Comment, CommentForm}, + community::{Community, CommunityForm}, + person::{Person, PersonForm}, + post::{Post, PostForm}, + site::{Site, SiteForm}, + }, + traits::Crud, }; use serial_test::serial; diff --git a/crates/db_queries/src/source/activity.rs b/crates/db_schema/src/impls/activity.rs similarity index 75% rename from crates/db_queries/src/source/activity.rs rename to crates/db_schema/src/impls/activity.rs index 3008c38f8..4f1cfd2dd 100644 --- a/crates/db_queries/src/source/activity.rs +++ b/crates/db_schema/src/impls/activity.rs @@ -1,6 +1,5 @@ -use crate::Crud; +use crate::{newtypes::DbUrl, source::activity::*, traits::Crud}; use diesel::{dsl::*, result::Error, sql_types::Text, *}; -use lemmy_db_schema::{source::activity::*, DbUrl}; use serde::Serialize; use serde_json::Value; use std::{ @@ -12,12 +11,12 @@ impl Crud for Activity { type Form = ActivityForm; type IdType = i32; fn read(conn: &PgConnection, activity_id: i32) -> Result { - use lemmy_db_schema::schema::activity::dsl::*; + use crate::schema::activity::dsl::*; activity.find(activity_id).first::(conn) } fn create(conn: &PgConnection, new_activity: &ActivityForm) -> Result { - use lemmy_db_schema::schema::activity::dsl::*; + use crate::schema::activity::dsl::*; insert_into(activity) .values(new_activity) .get_result::(conn) @@ -28,40 +27,19 @@ impl Crud for Activity { activity_id: i32, new_activity: &ActivityForm, ) -> Result { - use lemmy_db_schema::schema::activity::dsl::*; + use crate::schema::activity::dsl::*; diesel::update(activity.find(activity_id)) .set(new_activity) .get_result::(conn) } fn delete(conn: &PgConnection, activity_id: i32) -> Result { - use lemmy_db_schema::schema::activity::dsl::*; + use crate::schema::activity::dsl::*; diesel::delete(activity.find(activity_id)).execute(conn) } } -pub trait Activity_ { - fn insert( - conn: &PgConnection, - ap_id: DbUrl, - data: &T, - local: bool, - sensitive: bool, - ) -> Result - where - T: Serialize + Debug; - - fn read_from_apub_id(conn: &PgConnection, object_id: &DbUrl) -> Result; - fn delete_olds(conn: &PgConnection) -> Result; - - /// Returns up to 20 activities of type `Announce/Create/Page` from the community - fn read_community_outbox( - conn: &PgConnection, - community_actor_id: &DbUrl, - ) -> Result, Error>; -} - -impl Activity_ for Activity { - fn insert( +impl Activity { + pub fn insert( conn: &PgConnection, ap_id: DbUrl, data: &T, @@ -88,21 +66,21 @@ impl Activity_ for Activity { } } - fn read_from_apub_id(conn: &PgConnection, object_id: &DbUrl) -> Result { - use lemmy_db_schema::schema::activity::dsl::*; + pub fn read_from_apub_id(conn: &PgConnection, object_id: &DbUrl) -> Result { + use crate::schema::activity::dsl::*; activity.filter(ap_id.eq(object_id)).first::(conn) } - fn delete_olds(conn: &PgConnection) -> Result { - use lemmy_db_schema::schema::activity::dsl::*; + pub fn delete_olds(conn: &PgConnection) -> Result { + use crate::schema::activity::dsl::*; diesel::delete(activity.filter(published.lt(now - 6.months()))).execute(conn) } - fn read_community_outbox( + pub fn read_community_outbox( conn: &PgConnection, community_actor_id: &DbUrl, ) -> Result, Error> { - use lemmy_db_schema::schema::activity::dsl::*; + use crate::schema::activity::dsl::*; let res: Vec = activity .select(data) .filter( @@ -122,10 +100,13 @@ impl Activity_ for Activity { #[cfg(test)] mod tests { use super::*; - use crate::{establish_unpooled_connection, source::activity::Activity_}; - use lemmy_db_schema::source::{ - activity::{Activity, ActivityForm}, - person::{Person, PersonForm}, + use crate::{ + establish_unpooled_connection, + newtypes::DbUrl, + source::{ + activity::{Activity, ActivityForm}, + person::{Person, PersonForm}, + }, }; use serde_json::Value; use serial_test::serial; diff --git a/crates/db_queries/src/source/comment.rs b/crates/db_schema/src/impls/comment.rs similarity index 77% rename from crates/db_queries/src/source/comment.rs rename to crates/db_schema/src/impls/comment.rs index 8031131c5..aa7e25b28 100644 --- a/crates/db_queries/src/source/comment.rs +++ b/crates/db_schema/src/impls/comment.rs @@ -1,7 +1,6 @@ -use crate::{Crud, DeleteableOrRemoveable, Likeable, Saveable}; -use diesel::{dsl::*, result::Error, *}; -use lemmy_db_schema::{ +use crate::{ naive_now, + newtypes::{CommentId, DbUrl, PersonId}, source::comment::{ Comment, CommentForm, @@ -10,67 +9,32 @@ use lemmy_db_schema::{ CommentSaved, CommentSavedForm, }, - CommentId, - DbUrl, - PersonId, + traits::{Crud, DeleteableOrRemoveable, Likeable, Saveable}, }; +use chrono::NaiveDateTime; +use diesel::{dsl::*, result::Error, *}; +use lemmy_apub_lib::traits::ApubObject; +use lemmy_utils::LemmyError; +use url::Url; -pub trait Comment_ { - fn update_ap_id( - conn: &PgConnection, - comment_id: CommentId, - apub_id: DbUrl, - ) -> Result; - fn permadelete_for_creator( - conn: &PgConnection, - for_creator_id: PersonId, - ) -> Result, Error>; - fn update_deleted( - conn: &PgConnection, - comment_id: CommentId, - new_deleted: bool, - ) -> Result; - fn update_removed( - conn: &PgConnection, - comment_id: CommentId, - new_removed: bool, - ) -> Result; - fn update_removed_for_creator( - conn: &PgConnection, - for_creator_id: PersonId, - new_removed: bool, - ) -> Result, Error>; - fn update_read( - conn: &PgConnection, - comment_id: CommentId, - new_read: bool, - ) -> Result; - fn update_content( - conn: &PgConnection, - comment_id: CommentId, - new_content: &str, - ) -> Result; - fn upsert(conn: &PgConnection, comment_form: &CommentForm) -> Result; -} - -impl Comment_ for Comment { - fn update_ap_id( +impl Comment { + pub fn update_ap_id( conn: &PgConnection, comment_id: CommentId, apub_id: DbUrl, ) -> Result { - use lemmy_db_schema::schema::comment::dsl::*; + use crate::schema::comment::dsl::*; diesel::update(comment.find(comment_id)) .set(ap_id.eq(apub_id)) .get_result::(conn) } - fn permadelete_for_creator( + pub fn permadelete_for_creator( conn: &PgConnection, for_creator_id: PersonId, ) -> Result, Error> { - use lemmy_db_schema::schema::comment::dsl::*; + use crate::schema::comment::dsl::*; diesel::update(comment.filter(creator_id.eq(for_creator_id))) .set(( content.eq("*Permananently Deleted*"), @@ -80,63 +44,63 @@ impl Comment_ for Comment { .get_results::(conn) } - fn update_deleted( + pub fn update_deleted( conn: &PgConnection, comment_id: CommentId, new_deleted: bool, ) -> Result { - use lemmy_db_schema::schema::comment::dsl::*; + use crate::schema::comment::dsl::*; diesel::update(comment.find(comment_id)) .set((deleted.eq(new_deleted), updated.eq(naive_now()))) .get_result::(conn) } - fn update_removed( + pub fn update_removed( conn: &PgConnection, comment_id: CommentId, new_removed: bool, ) -> Result { - use lemmy_db_schema::schema::comment::dsl::*; + use crate::schema::comment::dsl::*; diesel::update(comment.find(comment_id)) .set((removed.eq(new_removed), updated.eq(naive_now()))) .get_result::(conn) } - fn update_removed_for_creator( + pub fn update_removed_for_creator( conn: &PgConnection, for_creator_id: PersonId, new_removed: bool, ) -> Result, Error> { - use lemmy_db_schema::schema::comment::dsl::*; + use crate::schema::comment::dsl::*; diesel::update(comment.filter(creator_id.eq(for_creator_id))) .set((removed.eq(new_removed), updated.eq(naive_now()))) .get_results::(conn) } - fn update_read( + pub fn update_read( conn: &PgConnection, comment_id: CommentId, new_read: bool, ) -> Result { - use lemmy_db_schema::schema::comment::dsl::*; + use crate::schema::comment::dsl::*; diesel::update(comment.find(comment_id)) .set(read.eq(new_read)) .get_result::(conn) } - fn update_content( + pub fn update_content( conn: &PgConnection, comment_id: CommentId, new_content: &str, ) -> Result { - use lemmy_db_schema::schema::comment::dsl::*; + use crate::schema::comment::dsl::*; diesel::update(comment.find(comment_id)) .set((content.eq(new_content), updated.eq(naive_now()))) .get_result::(conn) } - fn upsert(conn: &PgConnection, comment_form: &CommentForm) -> Result { - use lemmy_db_schema::schema::comment::dsl::*; + pub fn upsert(conn: &PgConnection, comment_form: &CommentForm) -> Result { + use crate::schema::comment::dsl::*; insert_into(comment) .values(comment_form) .on_conflict(ap_id) @@ -150,17 +114,17 @@ impl Crud for Comment { type Form = CommentForm; type IdType = CommentId; fn read(conn: &PgConnection, comment_id: CommentId) -> Result { - use lemmy_db_schema::schema::comment::dsl::*; + use crate::schema::comment::dsl::*; comment.find(comment_id).first::(conn) } fn delete(conn: &PgConnection, comment_id: CommentId) -> Result { - use lemmy_db_schema::schema::comment::dsl::*; + use crate::schema::comment::dsl::*; diesel::delete(comment.find(comment_id)).execute(conn) } fn create(conn: &PgConnection, comment_form: &CommentForm) -> Result { - use lemmy_db_schema::schema::comment::dsl::*; + use crate::schema::comment::dsl::*; insert_into(comment) .values(comment_form) .get_result::(conn) @@ -171,7 +135,7 @@ impl Crud for Comment { comment_id: CommentId, comment_form: &CommentForm, ) -> Result { - use lemmy_db_schema::schema::comment::dsl::*; + use crate::schema::comment::dsl::*; diesel::update(comment.find(comment_id)) .set(comment_form) .get_result::(conn) @@ -182,7 +146,7 @@ impl Likeable for CommentLike { type Form = CommentLikeForm; type IdType = CommentId; fn like(conn: &PgConnection, comment_like_form: &CommentLikeForm) -> Result { - use lemmy_db_schema::schema::comment_like::dsl::*; + use crate::schema::comment_like::dsl::*; insert_into(comment_like) .values(comment_like_form) .on_conflict((comment_id, person_id)) @@ -195,7 +159,7 @@ impl Likeable for CommentLike { person_id: PersonId, comment_id: CommentId, ) -> Result { - use lemmy_db_schema::schema::comment_like::dsl; + use crate::schema::comment_like::dsl; diesel::delete( dsl::comment_like .filter(dsl::comment_id.eq(comment_id)) @@ -208,7 +172,7 @@ impl Likeable for CommentLike { impl Saveable for CommentSaved { type Form = CommentSavedForm; fn save(conn: &PgConnection, comment_saved_form: &CommentSavedForm) -> Result { - use lemmy_db_schema::schema::comment_saved::dsl::*; + use crate::schema::comment_saved::dsl::*; insert_into(comment_saved) .values(comment_saved_form) .on_conflict((comment_id, person_id)) @@ -217,7 +181,7 @@ impl Saveable for CommentSaved { .get_result::(conn) } fn unsave(conn: &PgConnection, comment_saved_form: &CommentSavedForm) -> Result { - use lemmy_db_schema::schema::comment_saved::dsl::*; + use crate::schema::comment_saved::dsl::*; diesel::delete( comment_saved .filter(comment_id.eq(comment_saved_form.comment_id)) @@ -234,14 +198,36 @@ impl DeleteableOrRemoveable for Comment { } } +impl ApubObject for Comment { + type DataType = PgConnection; + + fn last_refreshed_at(&self) -> Option { + None + } + + fn read_from_apub_id(conn: &PgConnection, object_id: Url) -> Result, LemmyError> { + use crate::schema::comment::dsl::*; + let object_id: DbUrl = object_id.into(); + Ok(comment.filter(ap_id.eq(object_id)).first::(conn).ok()) + } + + fn delete(self, conn: &PgConnection) -> Result<(), LemmyError> { + Comment::update_deleted(conn, self.id, true)?; + Ok(()) + } +} + #[cfg(test)] mod tests { - use crate::{establish_unpooled_connection, Crud, Likeable, Saveable}; - use lemmy_db_schema::source::{ - comment::*, - community::{Community, CommunityForm}, - person::{Person, PersonForm}, - post::*, + use crate::{ + establish_unpooled_connection, + source::{ + comment::*, + community::{Community, CommunityForm}, + person::{Person, PersonForm}, + post::*, + }, + traits::{Crud, Likeable, Saveable}, }; use serial_test::serial; diff --git a/crates/db_queries/src/source/comment_report.rs b/crates/db_schema/src/impls/comment_report.rs similarity index 86% rename from crates/db_queries/src/source/comment_report.rs rename to crates/db_schema/src/impls/comment_report.rs index 10b9d43e8..d32f3ef40 100644 --- a/crates/db_queries/src/source/comment_report.rs +++ b/crates/db_schema/src/impls/comment_report.rs @@ -1,11 +1,10 @@ -use crate::Reportable; -use diesel::{dsl::*, result::Error, *}; -use lemmy_db_schema::{ +use crate::{ naive_now, + newtypes::{CommentReportId, PersonId}, source::comment_report::{CommentReport, CommentReportForm}, - CommentReportId, - PersonId, + traits::Reportable, }; +use diesel::{dsl::*, result::Error, *}; impl Reportable for CommentReport { type Form = CommentReportForm; @@ -15,7 +14,7 @@ impl Reportable for CommentReport { /// * `conn` - the postgres connection /// * `comment_report_form` - the filled CommentReportForm to insert fn report(conn: &PgConnection, comment_report_form: &CommentReportForm) -> Result { - use lemmy_db_schema::schema::comment_report::dsl::*; + use crate::schema::comment_report::dsl::*; insert_into(comment_report) .values(comment_report_form) .get_result::(conn) @@ -31,7 +30,7 @@ impl Reportable for CommentReport { report_id: Self::IdType, by_resolver_id: PersonId, ) -> Result { - use lemmy_db_schema::schema::comment_report::dsl::*; + use crate::schema::comment_report::dsl::*; update(comment_report.find(report_id)) .set(( resolved.eq(true), @@ -51,7 +50,7 @@ impl Reportable for CommentReport { report_id: Self::IdType, by_resolver_id: PersonId, ) -> Result { - use lemmy_db_schema::schema::comment_report::dsl::*; + use crate::schema::comment_report::dsl::*; update(comment_report.find(report_id)) .set(( resolved.eq(false), diff --git a/crates/db_queries/src/source/community.rs b/crates/db_schema/src/impls/community.rs similarity index 75% rename from crates/db_queries/src/source/community.rs rename to crates/db_schema/src/impls/community.rs index 26e33380a..8acce790c 100644 --- a/crates/db_queries/src/source/community.rs +++ b/crates/db_schema/src/impls/community.rs @@ -1,7 +1,6 @@ -use crate::{Bannable, Crud, DeleteableOrRemoveable, Followable, Joinable}; -use diesel::{dsl::*, result::Error, *}; -use lemmy_db_schema::{ +use crate::{ naive_now, + newtypes::{CommunityId, DbUrl, PersonId}, source::community::{ Community, CommunityFollower, @@ -13,14 +12,16 @@ use lemmy_db_schema::{ CommunityPersonBanForm, CommunitySafe, }, - CommunityId, - DbUrl, - PersonId, + traits::{Bannable, Crud, DeleteableOrRemoveable, Followable, Joinable}, }; +use chrono::NaiveDateTime; +use diesel::{dsl::*, result::Error, ExpressionMethods, PgConnection, QueryDsl, RunQueryDsl}; +use lemmy_apub_lib::traits::{ActorType, ApubObject}; +use lemmy_utils::LemmyError; +use url::Url; mod safe_type { - use crate::{source::community::Community, ToSafe}; - use lemmy_db_schema::schema::community::*; + use crate::{schema::community::*, source::community::Community, traits::ToSafe}; type Columns = ( id, @@ -64,17 +65,17 @@ impl Crud for Community { type Form = CommunityForm; type IdType = CommunityId; fn read(conn: &PgConnection, community_id: CommunityId) -> Result { - use lemmy_db_schema::schema::community::dsl::*; + use crate::schema::community::dsl::*; community.find(community_id).first::(conn) } fn delete(conn: &PgConnection, community_id: CommunityId) -> Result { - use lemmy_db_schema::schema::community::dsl::*; + use crate::schema::community::dsl::*; diesel::delete(community.find(community_id)).execute(conn) } fn create(conn: &PgConnection, new_community: &CommunityForm) -> Result { - use lemmy_db_schema::schema::community::dsl::*; + use crate::schema::community::dsl::*; insert_into(community) .values(new_community) .get_result::(conn) @@ -85,81 +86,61 @@ impl Crud for Community { community_id: CommunityId, new_community: &CommunityForm, ) -> Result { - use lemmy_db_schema::schema::community::dsl::*; + use crate::schema::community::dsl::*; diesel::update(community.find(community_id)) .set(new_community) .get_result::(conn) } } -pub trait Community_ { - fn read_from_name(conn: &PgConnection, community_name: &str) -> Result; - fn update_deleted( - conn: &PgConnection, - community_id: CommunityId, - new_deleted: bool, - ) -> Result; - fn update_removed( - conn: &PgConnection, - community_id: CommunityId, - new_removed: bool, - ) -> Result; - fn distinct_federated_communities(conn: &PgConnection) -> Result, Error>; - fn read_from_followers_url( - conn: &PgConnection, - followers_url: &DbUrl, - ) -> Result; - fn upsert(conn: &PgConnection, community_form: &CommunityForm) -> Result; -} - -impl Community_ for Community { - fn read_from_name(conn: &PgConnection, community_name: &str) -> Result { - use lemmy_db_schema::schema::community::dsl::*; +impl Community { + pub fn read_from_name(conn: &PgConnection, community_name: &str) -> Result { + use crate::schema::community::dsl::*; community .filter(local.eq(true)) .filter(name.eq(community_name)) .first::(conn) } - fn update_deleted( + pub fn update_deleted( conn: &PgConnection, community_id: CommunityId, new_deleted: bool, ) -> Result { - use lemmy_db_schema::schema::community::dsl::*; + use crate::schema::community::dsl::*; diesel::update(community.find(community_id)) .set((deleted.eq(new_deleted), updated.eq(naive_now()))) .get_result::(conn) } - fn update_removed( + pub fn update_removed( conn: &PgConnection, community_id: CommunityId, new_removed: bool, ) -> Result { - use lemmy_db_schema::schema::community::dsl::*; + use crate::schema::community::dsl::*; diesel::update(community.find(community_id)) .set((removed.eq(new_removed), updated.eq(naive_now()))) .get_result::(conn) } - fn distinct_federated_communities(conn: &PgConnection) -> Result, Error> { - use lemmy_db_schema::schema::community::dsl::*; + pub fn distinct_federated_communities(conn: &PgConnection) -> Result, Error> { + use crate::schema::community::dsl::*; community.select(actor_id).distinct().load::(conn) } - fn read_from_followers_url( + pub fn read_from_followers_url( conn: &PgConnection, followers_url_: &DbUrl, ) -> Result { - use lemmy_db_schema::schema::community::dsl::*; + use crate::schema::community::dsl::*; community .filter(followers_url.eq(followers_url_)) .first::(conn) } - fn upsert(conn: &PgConnection, community_form: &CommunityForm) -> Result { - use lemmy_db_schema::schema::community::dsl::*; + pub fn upsert(conn: &PgConnection, community_form: &CommunityForm) -> Result { + use crate::schema::community::dsl::*; insert_into(community) .values(community_form) .on_conflict(actor_id) @@ -175,7 +156,7 @@ impl Joinable for CommunityModerator { conn: &PgConnection, community_moderator_form: &CommunityModeratorForm, ) -> Result { - use lemmy_db_schema::schema::community_moderator::dsl::*; + use crate::schema::community_moderator::dsl::*; insert_into(community_moderator) .values(community_moderator_form) .get_result::(conn) @@ -185,7 +166,7 @@ impl Joinable for CommunityModerator { conn: &PgConnection, community_moderator_form: &CommunityModeratorForm, ) -> Result { - use lemmy_db_schema::schema::community_moderator::dsl::*; + use crate::schema::community_moderator::dsl::*; diesel::delete( community_moderator .filter(community_id.eq(community_moderator_form.community_id)) @@ -215,31 +196,20 @@ impl DeleteableOrRemoveable for Community { } } -pub trait CommunityModerator_ { - fn delete_for_community( - conn: &PgConnection, - for_community_id: CommunityId, - ) -> Result; - fn get_person_moderated_communities( - conn: &PgConnection, - for_person_id: PersonId, - ) -> Result, Error>; -} - -impl CommunityModerator_ for CommunityModerator { - fn delete_for_community( +impl CommunityModerator { + pub fn delete_for_community( conn: &PgConnection, for_community_id: CommunityId, ) -> Result { - use lemmy_db_schema::schema::community_moderator::dsl::*; + use crate::schema::community_moderator::dsl::*; diesel::delete(community_moderator.filter(community_id.eq(for_community_id))).execute(conn) } - fn get_person_moderated_communities( + pub fn get_person_moderated_communities( conn: &PgConnection, for_person_id: PersonId, ) -> Result, Error> { - use lemmy_db_schema::schema::community_moderator::dsl::*; + use crate::schema::community_moderator::dsl::*; community_moderator .filter(person_id.eq(for_person_id)) .select(community_id) @@ -253,7 +223,7 @@ impl Bannable for CommunityPersonBan { conn: &PgConnection, community_person_ban_form: &CommunityPersonBanForm, ) -> Result { - use lemmy_db_schema::schema::community_person_ban::dsl::*; + use crate::schema::community_person_ban::dsl::*; insert_into(community_person_ban) .values(community_person_ban_form) .get_result::(conn) @@ -263,7 +233,7 @@ impl Bannable for CommunityPersonBan { conn: &PgConnection, community_person_ban_form: &CommunityPersonBanForm, ) -> Result { - use lemmy_db_schema::schema::community_person_ban::dsl::*; + use crate::schema::community_person_ban::dsl::*; diesel::delete( community_person_ban .filter(community_id.eq(community_person_ban_form.community_id)) @@ -279,7 +249,7 @@ impl Followable for CommunityFollower { conn: &PgConnection, community_follower_form: &CommunityFollowerForm, ) -> Result { - use lemmy_db_schema::schema::community_follower::dsl::*; + use crate::schema::community_follower::dsl::*; insert_into(community_follower) .values(community_follower_form) .on_conflict((community_id, person_id)) @@ -295,7 +265,7 @@ impl Followable for CommunityFollower { where Self: Sized, { - use lemmy_db_schema::schema::community_follower::dsl::*; + use crate::schema::community_follower::dsl::*; diesel::update( community_follower .filter(community_id.eq(community_id_)) @@ -308,7 +278,7 @@ impl Followable for CommunityFollower { conn: &PgConnection, community_follower_form: &CommunityFollowerForm, ) -> Result { - use lemmy_db_schema::schema::community_follower::dsl::*; + use crate::schema::community_follower::dsl::*; diesel::delete( community_follower .filter(community_id.eq(&community_follower_form.community_id)) @@ -319,7 +289,7 @@ impl Followable for CommunityFollower { // TODO: this function name only makes sense if you call it with a remote community. for a local // community, it will also return true if only remote followers exist fn has_local_followers(conn: &PgConnection, community_id_: CommunityId) -> Result { - use lemmy_db_schema::schema::community_follower::dsl::*; + use crate::schema::community_follower::dsl::*; diesel::select(exists( community_follower.filter(community_id.eq(community_id_)), )) @@ -327,10 +297,66 @@ impl Followable for CommunityFollower { } } +impl ApubObject for Community { + type DataType = PgConnection; + + fn last_refreshed_at(&self) -> Option { + Some(self.last_refreshed_at) + } + + fn read_from_apub_id(conn: &PgConnection, object_id: Url) -> Result, LemmyError> { + use crate::schema::community::dsl::*; + let object_id: DbUrl = object_id.into(); + Ok( + community + .filter(actor_id.eq(object_id)) + .first::(conn) + .ok(), + ) + } + + fn delete(self, conn: &PgConnection) -> Result<(), LemmyError> { + use crate::schema::community::dsl::*; + diesel::update(community.find(self.id)) + .set((deleted.eq(true), updated.eq(naive_now()))) + .get_result::(conn)?; + Ok(()) + } +} + +impl ActorType for Community { + fn is_local(&self) -> bool { + self.local + } + fn actor_id(&self) -> Url { + self.actor_id.to_owned().into() + } + fn name(&self) -> String { + self.name.clone() + } + fn public_key(&self) -> Option { + self.public_key.to_owned() + } + fn private_key(&self) -> Option { + self.private_key.to_owned() + } + + fn inbox_url(&self) -> Url { + self.inbox_url.clone().into() + } + + fn shared_inbox_url(&self) -> Option { + self.shared_inbox_url.clone().map(|s| s.into_inner()) + } +} + #[cfg(test)] mod tests { - use crate::{establish_unpooled_connection, Bannable, Crud, Followable, Joinable}; - use lemmy_db_schema::source::{community::*, person::*}; + use crate::{ + establish_unpooled_connection, + source::{community::*, person::*}, + traits::{Bannable, Crud, Followable, Joinable}, + }; use serial_test::serial; #[test] diff --git a/crates/db_queries/src/source/community_block.rs b/crates/db_schema/src/impls/community_block.rs similarity index 76% rename from crates/db_queries/src/source/community_block.rs rename to crates/db_schema/src/impls/community_block.rs index 346e7f3ac..bbad2f122 100644 --- a/crates/db_queries/src/source/community_block.rs +++ b/crates/db_schema/src/impls/community_block.rs @@ -1,11 +1,13 @@ -use crate::Blockable; +use crate::{ + source::community_block::{CommunityBlock, CommunityBlockForm}, + traits::Blockable, +}; use diesel::{dsl::*, result::Error, *}; -use lemmy_db_schema::source::community_block::{CommunityBlock, CommunityBlockForm}; impl Blockable for CommunityBlock { type Form = CommunityBlockForm; fn block(conn: &PgConnection, community_block_form: &Self::Form) -> Result { - use lemmy_db_schema::schema::community_block::dsl::*; + use crate::schema::community_block::dsl::*; insert_into(community_block) .values(community_block_form) .on_conflict((person_id, community_id)) @@ -14,7 +16,7 @@ impl Blockable for CommunityBlock { .get_result::(conn) } fn unblock(conn: &PgConnection, community_block_form: &Self::Form) -> Result { - use lemmy_db_schema::schema::community_block::dsl::*; + use crate::schema::community_block::dsl::*; diesel::delete( community_block .filter(person_id.eq(community_block_form.person_id)) diff --git a/crates/db_queries/src/source/local_user.rs b/crates/db_schema/src/impls/local_user.rs similarity index 81% rename from crates/db_queries/src/source/local_user.rs rename to crates/db_schema/src/impls/local_user.rs index 91eac3308..3a2d57695 100644 --- a/crates/db_queries/src/source/local_user.rs +++ b/crates/db_schema/src/impls/local_user.rs @@ -1,16 +1,19 @@ -use crate::Crud; -use bcrypt::{hash, DEFAULT_COST}; -use diesel::{dsl::*, result::Error, *}; -use lemmy_db_schema::{ +use crate::{ naive_now, + newtypes::LocalUserId, schema::local_user::dsl::*, source::local_user::{LocalUser, LocalUserForm}, - LocalUserId, + traits::Crud, }; +use bcrypt::{hash, DEFAULT_COST}; +use diesel::{dsl::*, result::Error, *}; mod safe_settings_type { - use crate::ToSafeSettings; - use lemmy_db_schema::{schema::local_user::columns::*, source::local_user::LocalUser}; + use crate::{ + schema::local_user::columns::*, + source::local_user::LocalUser, + traits::ToSafeSettings, + }; type Columns = ( id, @@ -56,17 +59,8 @@ mod safe_settings_type { } } -pub trait LocalUser_ { - fn register(conn: &PgConnection, form: &LocalUserForm) -> Result; - fn update_password( - conn: &PgConnection, - local_user_id: LocalUserId, - new_password: &str, - ) -> Result; -} - -impl LocalUser_ for LocalUser { - fn register(conn: &PgConnection, form: &LocalUserForm) -> Result { +impl LocalUser { + pub fn register(conn: &PgConnection, form: &LocalUserForm) -> Result { let mut edited_user = form.clone(); let password_hash = hash(&form.password_encrypted, DEFAULT_COST).expect("Couldn't hash password"); @@ -75,7 +69,7 @@ impl LocalUser_ for LocalUser { Self::create(conn, &edited_user) } - fn update_password( + pub fn update_password( conn: &PgConnection, local_user_id: LocalUserId, new_password: &str, diff --git a/crates/db_queries/src/source/mod.rs b/crates/db_schema/src/impls/mod.rs similarity index 100% rename from crates/db_queries/src/source/mod.rs rename to crates/db_schema/src/impls/mod.rs diff --git a/crates/db_queries/src/source/moderator.rs b/crates/db_schema/src/impls/moderator.rs similarity index 87% rename from crates/db_queries/src/source/moderator.rs rename to crates/db_schema/src/impls/moderator.rs index eee5d5e9f..952bab40e 100644 --- a/crates/db_queries/src/source/moderator.rs +++ b/crates/db_schema/src/impls/moderator.rs @@ -1,24 +1,23 @@ -use crate::Crud; +use crate::{source::moderator::*, traits::Crud}; use diesel::{dsl::*, result::Error, *}; -use lemmy_db_schema::source::moderator::*; impl Crud for ModRemovePost { type Form = ModRemovePostForm; type IdType = i32; fn read(conn: &PgConnection, from_id: i32) -> Result { - use lemmy_db_schema::schema::mod_remove_post::dsl::*; + use crate::schema::mod_remove_post::dsl::*; mod_remove_post.find(from_id).first::(conn) } fn create(conn: &PgConnection, form: &ModRemovePostForm) -> Result { - use lemmy_db_schema::schema::mod_remove_post::dsl::*; + use crate::schema::mod_remove_post::dsl::*; insert_into(mod_remove_post) .values(form) .get_result::(conn) } fn update(conn: &PgConnection, from_id: i32, form: &ModRemovePostForm) -> Result { - use lemmy_db_schema::schema::mod_remove_post::dsl::*; + use crate::schema::mod_remove_post::dsl::*; diesel::update(mod_remove_post.find(from_id)) .set(form) .get_result::(conn) @@ -29,19 +28,19 @@ impl Crud for ModLockPost { type Form = ModLockPostForm; type IdType = i32; fn read(conn: &PgConnection, from_id: i32) -> Result { - use lemmy_db_schema::schema::mod_lock_post::dsl::*; + use crate::schema::mod_lock_post::dsl::*; mod_lock_post.find(from_id).first::(conn) } fn create(conn: &PgConnection, form: &ModLockPostForm) -> Result { - use lemmy_db_schema::schema::mod_lock_post::dsl::*; + use crate::schema::mod_lock_post::dsl::*; insert_into(mod_lock_post) .values(form) .get_result::(conn) } fn update(conn: &PgConnection, from_id: i32, form: &ModLockPostForm) -> Result { - use lemmy_db_schema::schema::mod_lock_post::dsl::*; + use crate::schema::mod_lock_post::dsl::*; diesel::update(mod_lock_post.find(from_id)) .set(form) .get_result::(conn) @@ -52,19 +51,19 @@ impl Crud for ModStickyPost { type Form = ModStickyPostForm; type IdType = i32; fn read(conn: &PgConnection, from_id: i32) -> Result { - use lemmy_db_schema::schema::mod_sticky_post::dsl::*; + use crate::schema::mod_sticky_post::dsl::*; mod_sticky_post.find(from_id).first::(conn) } fn create(conn: &PgConnection, form: &ModStickyPostForm) -> Result { - use lemmy_db_schema::schema::mod_sticky_post::dsl::*; + use crate::schema::mod_sticky_post::dsl::*; insert_into(mod_sticky_post) .values(form) .get_result::(conn) } fn update(conn: &PgConnection, from_id: i32, form: &ModStickyPostForm) -> Result { - use lemmy_db_schema::schema::mod_sticky_post::dsl::*; + use crate::schema::mod_sticky_post::dsl::*; diesel::update(mod_sticky_post.find(from_id)) .set(form) .get_result::(conn) @@ -75,19 +74,19 @@ impl Crud for ModRemoveComment { type Form = ModRemoveCommentForm; type IdType = i32; fn read(conn: &PgConnection, from_id: i32) -> Result { - use lemmy_db_schema::schema::mod_remove_comment::dsl::*; + use crate::schema::mod_remove_comment::dsl::*; mod_remove_comment.find(from_id).first::(conn) } fn create(conn: &PgConnection, form: &ModRemoveCommentForm) -> Result { - use lemmy_db_schema::schema::mod_remove_comment::dsl::*; + use crate::schema::mod_remove_comment::dsl::*; insert_into(mod_remove_comment) .values(form) .get_result::(conn) } fn update(conn: &PgConnection, from_id: i32, form: &ModRemoveCommentForm) -> Result { - use lemmy_db_schema::schema::mod_remove_comment::dsl::*; + use crate::schema::mod_remove_comment::dsl::*; diesel::update(mod_remove_comment.find(from_id)) .set(form) .get_result::(conn) @@ -98,12 +97,12 @@ impl Crud for ModRemoveCommunity { type Form = ModRemoveCommunityForm; type IdType = i32; fn read(conn: &PgConnection, from_id: i32) -> Result { - use lemmy_db_schema::schema::mod_remove_community::dsl::*; + use crate::schema::mod_remove_community::dsl::*; mod_remove_community.find(from_id).first::(conn) } fn create(conn: &PgConnection, form: &ModRemoveCommunityForm) -> Result { - use lemmy_db_schema::schema::mod_remove_community::dsl::*; + use crate::schema::mod_remove_community::dsl::*; insert_into(mod_remove_community) .values(form) .get_result::(conn) @@ -114,7 +113,7 @@ impl Crud for ModRemoveCommunity { from_id: i32, form: &ModRemoveCommunityForm, ) -> Result { - use lemmy_db_schema::schema::mod_remove_community::dsl::*; + use crate::schema::mod_remove_community::dsl::*; diesel::update(mod_remove_community.find(from_id)) .set(form) .get_result::(conn) @@ -125,12 +124,12 @@ impl Crud for ModBanFromCommunity { type Form = ModBanFromCommunityForm; type IdType = i32; fn read(conn: &PgConnection, from_id: i32) -> Result { - use lemmy_db_schema::schema::mod_ban_from_community::dsl::*; + use crate::schema::mod_ban_from_community::dsl::*; mod_ban_from_community.find(from_id).first::(conn) } fn create(conn: &PgConnection, form: &ModBanFromCommunityForm) -> Result { - use lemmy_db_schema::schema::mod_ban_from_community::dsl::*; + use crate::schema::mod_ban_from_community::dsl::*; insert_into(mod_ban_from_community) .values(form) .get_result::(conn) @@ -141,7 +140,7 @@ impl Crud for ModBanFromCommunity { from_id: i32, form: &ModBanFromCommunityForm, ) -> Result { - use lemmy_db_schema::schema::mod_ban_from_community::dsl::*; + use crate::schema::mod_ban_from_community::dsl::*; diesel::update(mod_ban_from_community.find(from_id)) .set(form) .get_result::(conn) @@ -152,17 +151,17 @@ impl Crud for ModBan { type Form = ModBanForm; type IdType = i32; fn read(conn: &PgConnection, from_id: i32) -> Result { - use lemmy_db_schema::schema::mod_ban::dsl::*; + use crate::schema::mod_ban::dsl::*; mod_ban.find(from_id).first::(conn) } fn create(conn: &PgConnection, form: &ModBanForm) -> Result { - use lemmy_db_schema::schema::mod_ban::dsl::*; + use crate::schema::mod_ban::dsl::*; insert_into(mod_ban).values(form).get_result::(conn) } fn update(conn: &PgConnection, from_id: i32, form: &ModBanForm) -> Result { - use lemmy_db_schema::schema::mod_ban::dsl::*; + use crate::schema::mod_ban::dsl::*; diesel::update(mod_ban.find(from_id)) .set(form) .get_result::(conn) @@ -173,19 +172,19 @@ impl Crud for ModAddCommunity { type Form = ModAddCommunityForm; type IdType = i32; fn read(conn: &PgConnection, from_id: i32) -> Result { - use lemmy_db_schema::schema::mod_add_community::dsl::*; + use crate::schema::mod_add_community::dsl::*; mod_add_community.find(from_id).first::(conn) } fn create(conn: &PgConnection, form: &ModAddCommunityForm) -> Result { - use lemmy_db_schema::schema::mod_add_community::dsl::*; + use crate::schema::mod_add_community::dsl::*; insert_into(mod_add_community) .values(form) .get_result::(conn) } fn update(conn: &PgConnection, from_id: i32, form: &ModAddCommunityForm) -> Result { - use lemmy_db_schema::schema::mod_add_community::dsl::*; + use crate::schema::mod_add_community::dsl::*; diesel::update(mod_add_community.find(from_id)) .set(form) .get_result::(conn) @@ -196,12 +195,12 @@ impl Crud for ModTransferCommunity { type Form = ModTransferCommunityForm; type IdType = i32; fn read(conn: &PgConnection, from_id: i32) -> Result { - use lemmy_db_schema::schema::mod_transfer_community::dsl::*; + use crate::schema::mod_transfer_community::dsl::*; mod_transfer_community.find(from_id).first::(conn) } fn create(conn: &PgConnection, form: &ModTransferCommunityForm) -> Result { - use lemmy_db_schema::schema::mod_transfer_community::dsl::*; + use crate::schema::mod_transfer_community::dsl::*; insert_into(mod_transfer_community) .values(form) .get_result::(conn) @@ -212,7 +211,7 @@ impl Crud for ModTransferCommunity { from_id: i32, form: &ModTransferCommunityForm, ) -> Result { - use lemmy_db_schema::schema::mod_transfer_community::dsl::*; + use crate::schema::mod_transfer_community::dsl::*; diesel::update(mod_transfer_community.find(from_id)) .set(form) .get_result::(conn) @@ -223,17 +222,17 @@ impl Crud for ModAdd { type Form = ModAddForm; type IdType = i32; fn read(conn: &PgConnection, from_id: i32) -> Result { - use lemmy_db_schema::schema::mod_add::dsl::*; + use crate::schema::mod_add::dsl::*; mod_add.find(from_id).first::(conn) } fn create(conn: &PgConnection, form: &ModAddForm) -> Result { - use lemmy_db_schema::schema::mod_add::dsl::*; + use crate::schema::mod_add::dsl::*; insert_into(mod_add).values(form).get_result::(conn) } fn update(conn: &PgConnection, from_id: i32, form: &ModAddForm) -> Result { - use lemmy_db_schema::schema::mod_add::dsl::*; + use crate::schema::mod_add::dsl::*; diesel::update(mod_add.find(from_id)) .set(form) .get_result::(conn) @@ -242,8 +241,11 @@ impl Crud for ModAdd { #[cfg(test)] mod tests { - use crate::{establish_unpooled_connection, Crud}; - use lemmy_db_schema::source::{comment::*, community::*, moderator::*, person::*, post::*}; + use crate::{ + establish_unpooled_connection, + source::{comment::*, community::*, moderator::*, person::*, post::*}, + traits::Crud, + }; use serial_test::serial; // use Crud; diff --git a/crates/db_queries/src/source/password_reset_request.rs b/crates/db_schema/src/impls/password_reset_request.rs similarity index 82% rename from crates/db_queries/src/source/password_reset_request.rs rename to crates/db_schema/src/impls/password_reset_request.rs index a71cdae26..c5debd926 100644 --- a/crates/db_queries/src/source/password_reset_request.rs +++ b/crates/db_schema/src/impls/password_reset_request.rs @@ -1,10 +1,10 @@ -use crate::Crud; -use diesel::{dsl::*, result::Error, PgConnection, *}; -use lemmy_db_schema::{ +use crate::{ + newtypes::LocalUserId, schema::password_reset_request::dsl::*, source::password_reset_request::*, - LocalUserId, + traits::Crud, }; +use diesel::{dsl::*, result::Error, PgConnection, *}; use sha2::{Digest, Sha256}; impl Crud for PasswordResetRequest { @@ -31,17 +31,8 @@ impl Crud for PasswordResetRequest { } } -pub trait PasswordResetRequest_ { - fn create_token( - conn: &PgConnection, - from_local_user_id: LocalUserId, - token: &str, - ) -> Result; - fn read_from_token(conn: &PgConnection, token: &str) -> Result; -} - -impl PasswordResetRequest_ for PasswordResetRequest { - fn create_token( +impl PasswordResetRequest { + pub fn create_token( conn: &PgConnection, from_local_user_id: LocalUserId, token: &str, @@ -57,7 +48,7 @@ impl PasswordResetRequest_ for PasswordResetRequest { Self::create(conn, &form) } - fn read_from_token(conn: &PgConnection, token: &str) -> Result { + pub fn read_from_token(conn: &PgConnection, token: &str) -> Result { let mut hasher = Sha256::new(); hasher.update(token); let token_hash: String = bytes_to_hex(hasher.finalize().to_vec()); @@ -80,13 +71,12 @@ fn bytes_to_hex(bytes: Vec) -> String { mod tests { use crate::{ establish_unpooled_connection, - source::password_reset_request::PasswordResetRequest_, - Crud, - }; - use lemmy_db_schema::source::{ - local_user::{LocalUser, LocalUserForm}, - password_reset_request::PasswordResetRequest, - person::*, + source::{ + local_user::{LocalUser, LocalUserForm}, + password_reset_request::PasswordResetRequest, + person::*, + }, + traits::Crud, }; use serial_test::serial; diff --git a/crates/db_queries/src/source/person.rs b/crates/db_schema/src/impls/person.rs similarity index 68% rename from crates/db_queries/src/source/person.rs rename to crates/db_schema/src/impls/person.rs index 3f0c6f867..5b7cb9416 100644 --- a/crates/db_queries/src/source/person.rs +++ b/crates/db_schema/src/impls/person.rs @@ -1,15 +1,18 @@ -use crate::Crud; -use diesel::{dsl::*, result::Error, *}; -use lemmy_db_schema::{ +use crate::{ naive_now, + newtypes::{DbUrl, PersonId}, schema::person::dsl::*, source::person::{Person, PersonForm}, - PersonId, + traits::Crud, }; +use chrono::NaiveDateTime; +use diesel::{dsl::*, result::Error, ExpressionMethods, PgConnection, QueryDsl, RunQueryDsl, *}; +use lemmy_apub_lib::traits::{ActorType, ApubObject}; +use lemmy_utils::LemmyError; +use url::Url; mod safe_type { - use crate::ToSafe; - use lemmy_db_schema::{schema::person::columns::*, source::person::Person}; + use crate::{schema::person::columns::*, source::person::Person, traits::ToSafe}; type Columns = ( id, @@ -58,8 +61,7 @@ mod safe_type { } mod safe_type_alias_1 { - use crate::ToSafe; - use lemmy_db_schema::{schema::person_alias_1::columns::*, source::person::PersonAlias1}; + use crate::{schema::person_alias_1::columns::*, source::person::PersonAlias1, traits::ToSafe}; type Columns = ( id, @@ -108,8 +110,7 @@ mod safe_type_alias_1 { } mod safe_type_alias_2 { - use crate::ToSafe; - use lemmy_db_schema::{schema::person_alias_2::columns::*, source::person::PersonAlias2}; + use crate::{schema::person_alias_2::columns::*, source::person::PersonAlias2, traits::ToSafe}; type Columns = ( id, @@ -179,29 +180,20 @@ impl Crud for Person { } } -pub trait Person_ { - fn ban_person(conn: &PgConnection, person_id: PersonId, ban: bool) -> Result; - fn add_admin(conn: &PgConnection, person_id: PersonId, added: bool) -> Result; - fn find_by_name(conn: &PgConnection, name: &str) -> Result; - fn mark_as_updated(conn: &PgConnection, person_id: PersonId) -> Result; - fn delete_account(conn: &PgConnection, person_id: PersonId) -> Result; - fn upsert(conn: &PgConnection, person_form: &PersonForm) -> Result; -} - -impl Person_ for Person { - fn ban_person(conn: &PgConnection, person_id: PersonId, ban: bool) -> Result { +impl Person { + pub fn ban_person(conn: &PgConnection, person_id: PersonId, ban: bool) -> Result { diesel::update(person.find(person_id)) .set(banned.eq(ban)) .get_result::(conn) } - fn add_admin(conn: &PgConnection, person_id: PersonId, added: bool) -> Result { + pub fn add_admin(conn: &PgConnection, person_id: PersonId, added: bool) -> Result { diesel::update(person.find(person_id)) .set(admin.eq(added)) .get_result::(conn) } - fn find_by_name(conn: &PgConnection, from_name: &str) -> Result { + pub fn find_by_name(conn: &PgConnection, from_name: &str) -> Result { person .filter(deleted.eq(false)) .filter(local.eq(true)) @@ -209,14 +201,14 @@ impl Person_ for Person { .first::(conn) } - fn mark_as_updated(conn: &PgConnection, person_id: PersonId) -> Result { + pub fn mark_as_updated(conn: &PgConnection, person_id: PersonId) -> Result { diesel::update(person.find(person_id)) .set((last_refreshed_at.eq(naive_now()),)) .get_result::(conn) } - fn delete_account(conn: &PgConnection, person_id: PersonId) -> Result { - use lemmy_db_schema::schema::local_user; + pub fn delete_account(conn: &PgConnection, person_id: PersonId) -> Result { + use crate::schema::local_user; // Set the local user info to none diesel::update(local_user::table.filter(local_user::person_id.eq(person_id))) @@ -237,7 +229,7 @@ impl Person_ for Person { .get_result::(conn) } - fn upsert(conn: &PgConnection, person_form: &PersonForm) -> Result { + pub fn upsert(conn: &PgConnection, person_form: &PersonForm) -> Result { insert_into(person) .values(person_form) .on_conflict(actor_id) @@ -247,9 +239,65 @@ impl Person_ for Person { } } +impl ApubObject for Person { + type DataType = PgConnection; + + fn last_refreshed_at(&self) -> Option { + Some(self.last_refreshed_at) + } + + fn read_from_apub_id(conn: &PgConnection, object_id: Url) -> Result, LemmyError> { + use crate::schema::person::dsl::*; + let object_id: DbUrl = object_id.into(); + Ok( + person + .filter(deleted.eq(false)) + .filter(actor_id.eq(object_id)) + .first::(conn) + .ok(), + ) + } + + fn delete(self, conn: &PgConnection) -> Result<(), LemmyError> { + use crate::schema::person::dsl::*; + diesel::update(person.find(self.id)) + .set((deleted.eq(true), updated.eq(naive_now()))) + .get_result::(conn)?; + Ok(()) + } +} + +impl ActorType for Person { + fn is_local(&self) -> bool { + self.local + } + fn actor_id(&self) -> Url { + self.actor_id.to_owned().into_inner() + } + fn name(&self) -> String { + self.name.clone() + } + + fn public_key(&self) -> Option { + self.public_key.to_owned() + } + + fn private_key(&self) -> Option { + self.private_key.to_owned() + } + + fn inbox_url(&self) -> Url { + self.inbox_url.clone().into() + } + + fn shared_inbox_url(&self) -> Option { + self.shared_inbox_url.clone().map(|s| s.into_inner()) + } +} + #[cfg(test)] mod tests { - use crate::{establish_unpooled_connection, source::person::*}; + use crate::{establish_unpooled_connection, source::person::*, traits::Crud}; #[test] fn test_crud() { diff --git a/crates/db_queries/src/source/person_block.rs b/crates/db_schema/src/impls/person_block.rs similarity index 70% rename from crates/db_queries/src/source/person_block.rs rename to crates/db_schema/src/impls/person_block.rs index d4505519c..d1b776805 100644 --- a/crates/db_queries/src/source/person_block.rs +++ b/crates/db_schema/src/impls/person_block.rs @@ -1,25 +1,17 @@ -use crate::Blockable; -use diesel::{dsl::*, result::Error, *}; -use lemmy_db_schema::{ +use crate::{ + newtypes::PersonId, source::person_block::{PersonBlock, PersonBlockForm}, - PersonId, + traits::Blockable, }; +use diesel::{dsl::*, result::Error, *}; -pub trait PersonBlock_ { - fn read( - conn: &PgConnection, - person_id: PersonId, - target_id: PersonId, - ) -> Result; -} - -impl PersonBlock_ for PersonBlock { - fn read( +impl PersonBlock { + pub fn read( conn: &PgConnection, for_person_id: PersonId, for_recipient_id: PersonId, ) -> Result { - use lemmy_db_schema::schema::person_block::dsl::*; + use crate::schema::person_block::dsl::*; person_block .filter(person_id.eq(for_person_id)) .filter(target_id.eq(for_recipient_id)) @@ -30,7 +22,7 @@ impl PersonBlock_ for PersonBlock { impl Blockable for PersonBlock { type Form = PersonBlockForm; fn block(conn: &PgConnection, person_block_form: &PersonBlockForm) -> Result { - use lemmy_db_schema::schema::person_block::dsl::*; + use crate::schema::person_block::dsl::*; insert_into(person_block) .values(person_block_form) .on_conflict((person_id, target_id)) @@ -39,7 +31,7 @@ impl Blockable for PersonBlock { .get_result::(conn) } fn unblock(conn: &PgConnection, person_block_form: &Self::Form) -> Result { - use lemmy_db_schema::schema::person_block::dsl::*; + use crate::schema::person_block::dsl::*; diesel::delete( person_block .filter(person_id.eq(person_block_form.person_id)) diff --git a/crates/db_queries/src/source/person_mention.rs b/crates/db_schema/src/impls/person_mention.rs similarity index 77% rename from crates/db_queries/src/source/person_mention.rs rename to crates/db_schema/src/impls/person_mention.rs index 1adcc3c98..df0e55ede 100644 --- a/crates/db_queries/src/source/person_mention.rs +++ b/crates/db_schema/src/impls/person_mention.rs @@ -1,17 +1,20 @@ -use crate::Crud; +use crate::{ + newtypes::{CommentId, PersonId, PersonMentionId}, + source::person_mention::*, + traits::Crud, +}; use diesel::{dsl::*, result::Error, *}; -use lemmy_db_schema::{source::person_mention::*, CommentId, PersonId, PersonMentionId}; impl Crud for PersonMention { type Form = PersonMentionForm; type IdType = PersonMentionId; fn read(conn: &PgConnection, person_mention_id: PersonMentionId) -> Result { - use lemmy_db_schema::schema::person_mention::dsl::*; + use crate::schema::person_mention::dsl::*; person_mention.find(person_mention_id).first::(conn) } fn create(conn: &PgConnection, person_mention_form: &PersonMentionForm) -> Result { - use lemmy_db_schema::schema::person_mention::dsl::*; + use crate::schema::person_mention::dsl::*; // since the return here isnt utilized, we dont need to do an update // but get_result doesnt return the existing row here insert_into(person_mention) @@ -27,47 +30,30 @@ impl Crud for PersonMention { person_mention_id: PersonMentionId, person_mention_form: &PersonMentionForm, ) -> Result { - use lemmy_db_schema::schema::person_mention::dsl::*; + use crate::schema::person_mention::dsl::*; diesel::update(person_mention.find(person_mention_id)) .set(person_mention_form) .get_result::(conn) } } -pub trait PersonMention_ { - fn update_read( - conn: &PgConnection, - person_mention_id: PersonMentionId, - new_read: bool, - ) -> Result; - fn mark_all_as_read( - conn: &PgConnection, - for_recipient_id: PersonId, - ) -> Result, Error>; - fn read_by_comment_and_person( - conn: &PgConnection, - for_comment_id: CommentId, - for_recipient_id: PersonId, - ) -> Result; -} - -impl PersonMention_ for PersonMention { - fn update_read( +impl PersonMention { + pub fn update_read( conn: &PgConnection, person_mention_id: PersonMentionId, new_read: bool, ) -> Result { - use lemmy_db_schema::schema::person_mention::dsl::*; + use crate::schema::person_mention::dsl::*; diesel::update(person_mention.find(person_mention_id)) .set(read.eq(new_read)) .get_result::(conn) } - fn mark_all_as_read( + pub fn mark_all_as_read( conn: &PgConnection, for_recipient_id: PersonId, ) -> Result, Error> { - use lemmy_db_schema::schema::person_mention::dsl::*; + use crate::schema::person_mention::dsl::*; diesel::update( person_mention .filter(recipient_id.eq(for_recipient_id)) @@ -76,12 +62,12 @@ impl PersonMention_ for PersonMention { .set(read.eq(true)) .get_results::(conn) } - fn read_by_comment_and_person( + pub fn read_by_comment_and_person( conn: &PgConnection, for_comment_id: CommentId, for_recipient_id: PersonId, ) -> Result { - use lemmy_db_schema::schema::person_mention::dsl::*; + use crate::schema::person_mention::dsl::*; person_mention .filter(comment_id.eq(for_comment_id)) .filter(recipient_id.eq(for_recipient_id)) @@ -91,13 +77,16 @@ impl PersonMention_ for PersonMention { #[cfg(test)] mod tests { - use crate::{establish_unpooled_connection, Crud}; - use lemmy_db_schema::source::{ - comment::*, - community::{Community, CommunityForm}, - person::*, - person_mention::*, - post::*, + use crate::{ + establish_unpooled_connection, + source::{ + comment::*, + community::{Community, CommunityForm}, + person::*, + person_mention::*, + post::*, + }, + traits::Crud, }; use serial_test::serial; diff --git a/crates/db_queries/src/source/post.rs b/crates/db_schema/src/impls/post.rs similarity index 75% rename from crates/db_queries/src/source/post.rs rename to crates/db_schema/src/impls/post.rs index f9c34be83..2b71c663f 100644 --- a/crates/db_queries/src/source/post.rs +++ b/crates/db_schema/src/impls/post.rs @@ -1,7 +1,6 @@ -use crate::{Crud, DeleteableOrRemoveable, Likeable, Readable, Saveable}; -use diesel::{dsl::*, result::Error, *}; -use lemmy_db_schema::{ +use crate::{ naive_now, + newtypes::{CommunityId, DbUrl, PersonId, PostId}, source::post::{ Post, PostForm, @@ -12,75 +11,46 @@ use lemmy_db_schema::{ PostSaved, PostSavedForm, }, - CommunityId, - DbUrl, - PersonId, - PostId, + traits::{Crud, DeleteableOrRemoveable, Likeable, Readable, Saveable}, }; +use chrono::NaiveDateTime; +use diesel::{dsl::*, result::Error, ExpressionMethods, PgConnection, QueryDsl, RunQueryDsl}; +use lemmy_apub_lib::traits::ApubObject; +use lemmy_utils::LemmyError; +use url::Url; impl Crud for Post { type Form = PostForm; type IdType = PostId; fn read(conn: &PgConnection, post_id: PostId) -> Result { - use lemmy_db_schema::schema::post::dsl::*; + use crate::schema::post::dsl::*; post.find(post_id).first::(conn) } fn delete(conn: &PgConnection, post_id: PostId) -> Result { - use lemmy_db_schema::schema::post::dsl::*; + use crate::schema::post::dsl::*; diesel::delete(post.find(post_id)).execute(conn) } fn create(conn: &PgConnection, new_post: &PostForm) -> Result { - use lemmy_db_schema::schema::post::dsl::*; + use crate::schema::post::dsl::*; insert_into(post).values(new_post).get_result::(conn) } fn update(conn: &PgConnection, post_id: PostId, new_post: &PostForm) -> Result { - use lemmy_db_schema::schema::post::dsl::*; + use crate::schema::post::dsl::*; diesel::update(post.find(post_id)) .set(new_post) .get_result::(conn) } } -pub trait Post_ { - //fn read(conn: &PgConnection, post_id: i32) -> Result; - fn list_for_community( - conn: &PgConnection, - the_community_id: CommunityId, - ) -> Result, Error>; - fn update_ap_id(conn: &PgConnection, post_id: PostId, apub_id: DbUrl) -> Result; - fn permadelete_for_creator( - conn: &PgConnection, - for_creator_id: PersonId, - ) -> Result, Error>; - fn update_deleted(conn: &PgConnection, post_id: PostId, new_deleted: bool) - -> Result; - fn update_removed(conn: &PgConnection, post_id: PostId, new_removed: bool) - -> Result; - fn update_removed_for_creator( - conn: &PgConnection, - for_creator_id: PersonId, - for_community_id: Option, - new_removed: bool, - ) -> Result, Error>; - fn update_locked(conn: &PgConnection, post_id: PostId, new_locked: bool) -> Result; - fn update_stickied( - conn: &PgConnection, - post_id: PostId, - new_stickied: bool, - ) -> Result; - fn is_post_creator(person_id: PersonId, post_creator_id: PersonId) -> bool; - fn upsert(conn: &PgConnection, post_form: &PostForm) -> Result; -} - -impl Post_ for Post { - fn list_for_community( +impl Post { + pub fn list_for_community( conn: &PgConnection, the_community_id: CommunityId, ) -> Result, Error> { - use lemmy_db_schema::schema::post::dsl::*; + use crate::schema::post::dsl::*; post .filter(community_id.eq(the_community_id)) .then_order_by(published.desc()) @@ -89,19 +59,19 @@ impl Post_ for Post { .load::(conn) } - fn update_ap_id(conn: &PgConnection, post_id: PostId, apub_id: DbUrl) -> Result { - use lemmy_db_schema::schema::post::dsl::*; + pub fn update_ap_id(conn: &PgConnection, post_id: PostId, apub_id: DbUrl) -> Result { + use crate::schema::post::dsl::*; diesel::update(post.find(post_id)) .set(ap_id.eq(apub_id)) .get_result::(conn) } - fn permadelete_for_creator( + pub fn permadelete_for_creator( conn: &PgConnection, for_creator_id: PersonId, ) -> Result, Error> { - use lemmy_db_schema::schema::post::dsl::*; + use crate::schema::post::dsl::*; let perma_deleted = "*Permananently Deleted*"; let perma_deleted_url = "https://deleted.com"; @@ -117,35 +87,35 @@ impl Post_ for Post { .get_results::(conn) } - fn update_deleted( + pub fn update_deleted( conn: &PgConnection, post_id: PostId, new_deleted: bool, ) -> Result { - use lemmy_db_schema::schema::post::dsl::*; + use crate::schema::post::dsl::*; diesel::update(post.find(post_id)) .set((deleted.eq(new_deleted), updated.eq(naive_now()))) .get_result::(conn) } - fn update_removed( + pub fn update_removed( conn: &PgConnection, post_id: PostId, new_removed: bool, ) -> Result { - use lemmy_db_schema::schema::post::dsl::*; + use crate::schema::post::dsl::*; diesel::update(post.find(post_id)) .set((removed.eq(new_removed), updated.eq(naive_now()))) .get_result::(conn) } - fn update_removed_for_creator( + pub fn update_removed_for_creator( conn: &PgConnection, for_creator_id: PersonId, for_community_id: Option, new_removed: bool, ) -> Result, Error> { - use lemmy_db_schema::schema::post::dsl::*; + use crate::schema::post::dsl::*; let mut update = diesel::update(post).into_boxed(); update = update.filter(creator_id.eq(for_creator_id)); @@ -159,30 +129,34 @@ impl Post_ for Post { .get_results::(conn) } - fn update_locked(conn: &PgConnection, post_id: PostId, new_locked: bool) -> Result { - use lemmy_db_schema::schema::post::dsl::*; + pub fn update_locked( + conn: &PgConnection, + post_id: PostId, + new_locked: bool, + ) -> Result { + use crate::schema::post::dsl::*; diesel::update(post.find(post_id)) .set(locked.eq(new_locked)) .get_result::(conn) } - fn update_stickied( + pub fn update_stickied( conn: &PgConnection, post_id: PostId, new_stickied: bool, ) -> Result { - use lemmy_db_schema::schema::post::dsl::*; + use crate::schema::post::dsl::*; diesel::update(post.find(post_id)) .set(stickied.eq(new_stickied)) .get_result::(conn) } - fn is_post_creator(person_id: PersonId, post_creator_id: PersonId) -> bool { + pub fn is_post_creator(person_id: PersonId, post_creator_id: PersonId) -> bool { person_id == post_creator_id } - fn upsert(conn: &PgConnection, post_form: &PostForm) -> Result { - use lemmy_db_schema::schema::post::dsl::*; + pub fn upsert(conn: &PgConnection, post_form: &PostForm) -> Result { + use crate::schema::post::dsl::*; insert_into(post) .values(post_form) .on_conflict(ap_id) @@ -196,7 +170,7 @@ impl Likeable for PostLike { type Form = PostLikeForm; type IdType = PostId; fn like(conn: &PgConnection, post_like_form: &PostLikeForm) -> Result { - use lemmy_db_schema::schema::post_like::dsl::*; + use crate::schema::post_like::dsl::*; insert_into(post_like) .values(post_like_form) .on_conflict((post_id, person_id)) @@ -205,7 +179,7 @@ impl Likeable for PostLike { .get_result::(conn) } fn remove(conn: &PgConnection, person_id: PersonId, post_id: PostId) -> Result { - use lemmy_db_schema::schema::post_like::dsl; + use crate::schema::post_like::dsl; diesel::delete( dsl::post_like .filter(dsl::post_id.eq(post_id)) @@ -218,7 +192,7 @@ impl Likeable for PostLike { impl Saveable for PostSaved { type Form = PostSavedForm; fn save(conn: &PgConnection, post_saved_form: &PostSavedForm) -> Result { - use lemmy_db_schema::schema::post_saved::dsl::*; + use crate::schema::post_saved::dsl::*; insert_into(post_saved) .values(post_saved_form) .on_conflict((post_id, person_id)) @@ -227,7 +201,7 @@ impl Saveable for PostSaved { .get_result::(conn) } fn unsave(conn: &PgConnection, post_saved_form: &PostSavedForm) -> Result { - use lemmy_db_schema::schema::post_saved::dsl::*; + use crate::schema::post_saved::dsl::*; diesel::delete( post_saved .filter(post_id.eq(post_saved_form.post_id)) @@ -240,7 +214,7 @@ impl Saveable for PostSaved { impl Readable for PostRead { type Form = PostReadForm; fn mark_as_read(conn: &PgConnection, post_read_form: &PostReadForm) -> Result { - use lemmy_db_schema::schema::post_read::dsl::*; + use crate::schema::post_read::dsl::*; insert_into(post_read) .values(post_read_form) .on_conflict((post_id, person_id)) @@ -250,7 +224,7 @@ impl Readable for PostRead { } fn mark_as_unread(conn: &PgConnection, post_read_form: &PostReadForm) -> Result { - use lemmy_db_schema::schema::post_read::dsl::*; + use crate::schema::post_read::dsl::*; diesel::delete( post_read .filter(post_id.eq(post_read_form.post_id)) @@ -274,12 +248,38 @@ impl DeleteableOrRemoveable for Post { } } +impl ApubObject for Post { + type DataType = PgConnection; + + fn last_refreshed_at(&self) -> Option { + None + } + + fn read_from_apub_id(conn: &PgConnection, object_id: Url) -> Result, LemmyError> { + use crate::schema::post::dsl::*; + let object_id: DbUrl = object_id.into(); + Ok(post.filter(ap_id.eq(object_id)).first::(conn).ok()) + } + + fn delete(self, conn: &PgConnection) -> Result<(), LemmyError> { + use crate::schema::post::dsl::*; + diesel::update(post.find(self.id)) + .set((deleted.eq(true), updated.eq(naive_now()))) + .get_result::(conn)?; + Ok(()) + } +} + #[cfg(test)] mod tests { - use crate::{establish_unpooled_connection, source::post::*}; - use lemmy_db_schema::source::{ - community::{Community, CommunityForm}, - person::*, + use crate::{ + establish_unpooled_connection, + source::{ + community::{Community, CommunityForm}, + person::*, + post::*, + }, + traits::{Crud, Likeable, Readable, Saveable}, }; use serial_test::serial; diff --git a/crates/db_queries/src/source/post_report.rs b/crates/db_schema/src/impls/post_report.rs similarity index 85% rename from crates/db_queries/src/source/post_report.rs rename to crates/db_schema/src/impls/post_report.rs index e787fed4c..d049fbced 100644 --- a/crates/db_queries/src/source/post_report.rs +++ b/crates/db_schema/src/impls/post_report.rs @@ -1,6 +1,10 @@ -use crate::Reportable; +use crate::{ + naive_now, + newtypes::{PersonId, PostReportId}, + source::post_report::*, + traits::Reportable, +}; use diesel::{dsl::*, result::Error, *}; -use lemmy_db_schema::{naive_now, source::post_report::*, PersonId, PostReportId}; impl Reportable for PostReport { type Form = PostReportForm; @@ -11,7 +15,7 @@ impl Reportable for PostReport { /// * `conn` - the postgres connection /// * `post_report_form` - the filled CommentReportForm to insert fn report(conn: &PgConnection, post_report_form: &PostReportForm) -> Result { - use lemmy_db_schema::schema::post_report::dsl::*; + use crate::schema::post_report::dsl::*; insert_into(post_report) .values(post_report_form) .get_result::(conn) @@ -27,7 +31,7 @@ impl Reportable for PostReport { report_id: Self::IdType, by_resolver_id: PersonId, ) -> Result { - use lemmy_db_schema::schema::post_report::dsl::*; + use crate::schema::post_report::dsl::*; update(post_report.find(report_id)) .set(( resolved.eq(true), @@ -47,7 +51,7 @@ impl Reportable for PostReport { report_id: Self::IdType, by_resolver_id: PersonId, ) -> Result { - use lemmy_db_schema::schema::post_report::dsl::*; + use crate::schema::post_report::dsl::*; update(post_report.find(report_id)) .set(( resolved.eq(false), diff --git a/crates/db_queries/src/source/private_message.rs b/crates/db_schema/src/impls/private_message.rs similarity index 72% rename from crates/db_queries/src/source/private_message.rs rename to crates/db_schema/src/impls/private_message.rs index 3aa279b2c..f252a0c03 100644 --- a/crates/db_queries/src/source/private_message.rs +++ b/crates/db_schema/src/impls/private_message.rs @@ -1,17 +1,25 @@ -use crate::{Crud, DeleteableOrRemoveable}; +use crate::{ + naive_now, + newtypes::{DbUrl, PersonId, PrivateMessageId}, + source::private_message::*, + traits::{Crud, DeleteableOrRemoveable}, +}; +use chrono::NaiveDateTime; use diesel::{dsl::*, result::Error, *}; -use lemmy_db_schema::{naive_now, source::private_message::*, DbUrl, PersonId, PrivateMessageId}; +use lemmy_apub_lib::traits::ApubObject; +use lemmy_utils::LemmyError; +use url::Url; impl Crud for PrivateMessage { type Form = PrivateMessageForm; type IdType = PrivateMessageId; fn read(conn: &PgConnection, private_message_id: PrivateMessageId) -> Result { - use lemmy_db_schema::schema::private_message::dsl::*; + use crate::schema::private_message::dsl::*; private_message.find(private_message_id).first::(conn) } fn create(conn: &PgConnection, private_message_form: &PrivateMessageForm) -> Result { - use lemmy_db_schema::schema::private_message::dsl::*; + use crate::schema::private_message::dsl::*; insert_into(private_message) .values(private_message_form) .get_result::(conn) @@ -22,95 +30,64 @@ impl Crud for PrivateMessage { private_message_id: PrivateMessageId, private_message_form: &PrivateMessageForm, ) -> Result { - use lemmy_db_schema::schema::private_message::dsl::*; + use crate::schema::private_message::dsl::*; diesel::update(private_message.find(private_message_id)) .set(private_message_form) .get_result::(conn) } } -pub trait PrivateMessage_ { - fn update_ap_id( - conn: &PgConnection, - private_message_id: PrivateMessageId, - apub_id: DbUrl, - ) -> Result; - fn update_content( - conn: &PgConnection, - private_message_id: PrivateMessageId, - new_content: &str, - ) -> Result; - fn update_deleted( - conn: &PgConnection, - private_message_id: PrivateMessageId, - new_deleted: bool, - ) -> Result; - fn update_read( - conn: &PgConnection, - private_message_id: PrivateMessageId, - new_read: bool, - ) -> Result; - fn mark_all_as_read( - conn: &PgConnection, - for_recipient_id: PersonId, - ) -> Result, Error>; - fn upsert( - conn: &PgConnection, - private_message_form: &PrivateMessageForm, - ) -> Result; -} - -impl PrivateMessage_ for PrivateMessage { - fn update_ap_id( +impl PrivateMessage { + pub fn update_ap_id( conn: &PgConnection, private_message_id: PrivateMessageId, apub_id: DbUrl, ) -> Result { - use lemmy_db_schema::schema::private_message::dsl::*; + use crate::schema::private_message::dsl::*; diesel::update(private_message.find(private_message_id)) .set(ap_id.eq(apub_id)) .get_result::(conn) } - fn update_content( + pub fn update_content( conn: &PgConnection, private_message_id: PrivateMessageId, new_content: &str, ) -> Result { - use lemmy_db_schema::schema::private_message::dsl::*; + use crate::schema::private_message::dsl::*; diesel::update(private_message.find(private_message_id)) .set((content.eq(new_content), updated.eq(naive_now()))) .get_result::(conn) } - fn update_deleted( + pub fn update_deleted( conn: &PgConnection, private_message_id: PrivateMessageId, new_deleted: bool, ) -> Result { - use lemmy_db_schema::schema::private_message::dsl::*; + use crate::schema::private_message::dsl::*; diesel::update(private_message.find(private_message_id)) .set(deleted.eq(new_deleted)) .get_result::(conn) } - fn update_read( + pub fn update_read( conn: &PgConnection, private_message_id: PrivateMessageId, new_read: bool, ) -> Result { - use lemmy_db_schema::schema::private_message::dsl::*; + use crate::schema::private_message::dsl::*; diesel::update(private_message.find(private_message_id)) .set(read.eq(new_read)) .get_result::(conn) } - fn mark_all_as_read( + pub fn mark_all_as_read( conn: &PgConnection, for_recipient_id: PersonId, ) -> Result, Error> { - use lemmy_db_schema::schema::private_message::dsl::*; + use crate::schema::private_message::dsl::*; diesel::update( private_message .filter(recipient_id.eq(for_recipient_id)) @@ -120,11 +97,11 @@ impl PrivateMessage_ for PrivateMessage { .get_results::(conn) } - fn upsert( + pub fn upsert( conn: &PgConnection, private_message_form: &PrivateMessageForm, ) -> Result { - use lemmy_db_schema::schema::private_message::dsl::*; + use crate::schema::private_message::dsl::*; insert_into(private_message) .values(private_message_form) .on_conflict(ap_id) @@ -141,10 +118,37 @@ impl DeleteableOrRemoveable for PrivateMessage { } } +impl ApubObject for PrivateMessage { + type DataType = PgConnection; + + fn last_refreshed_at(&self) -> Option { + None + } + + fn read_from_apub_id(conn: &PgConnection, object_id: Url) -> Result, LemmyError> { + use crate::schema::private_message::dsl::*; + let object_id: DbUrl = object_id.into(); + Ok( + private_message + .filter(ap_id.eq(object_id)) + .first::(conn) + .ok(), + ) + } + + fn delete(self, _conn: &PgConnection) -> Result<(), LemmyError> { + // do nothing, because pm can't be fetched over http + unimplemented!() + } +} + #[cfg(test)] mod tests { - use crate::{establish_unpooled_connection, source::private_message::PrivateMessage_, Crud}; - use lemmy_db_schema::source::{person::*, private_message::*}; + use crate::{ + establish_unpooled_connection, + source::{person::*, private_message::*}, + traits::Crud, + }; use serial_test::serial; #[test] diff --git a/crates/db_schema/src/impls/secret.rs b/crates/db_schema/src/impls/secret.rs new file mode 100644 index 000000000..3fb9b32bd --- /dev/null +++ b/crates/db_schema/src/impls/secret.rs @@ -0,0 +1,15 @@ +use crate::source::secret::Secret; +use diesel::{result::Error, *}; + +impl Secret { + /// Initialize the Secrets from the DB. + /// Warning: You should only call this once. + pub fn init(conn: &PgConnection) -> Result { + read_secrets(conn) + } +} + +fn read_secrets(conn: &PgConnection) -> Result { + use crate::schema::secret::dsl::*; + secret.first::(conn) +} diff --git a/crates/db_queries/src/source/site.rs b/crates/db_schema/src/impls/site.rs similarity index 55% rename from crates/db_queries/src/source/site.rs rename to crates/db_schema/src/impls/site.rs index b2bad7138..af0e8153d 100644 --- a/crates/db_queries/src/source/site.rs +++ b/crates/db_schema/src/impls/site.rs @@ -1,47 +1,41 @@ -use crate::Crud; +use crate::{naive_now, newtypes::PersonId, source::site::*, traits::Crud}; use diesel::{dsl::*, result::Error, *}; -use lemmy_db_schema::{naive_now, source::site::*, PersonId}; impl Crud for Site { type Form = SiteForm; type IdType = i32; fn read(conn: &PgConnection, _site_id: i32) -> Result { - use lemmy_db_schema::schema::site::dsl::*; + use crate::schema::site::dsl::*; site.first::(conn) } fn create(conn: &PgConnection, new_site: &SiteForm) -> Result { - use lemmy_db_schema::schema::site::dsl::*; + use crate::schema::site::dsl::*; insert_into(site).values(new_site).get_result::(conn) } fn update(conn: &PgConnection, site_id: i32, new_site: &SiteForm) -> Result { - use lemmy_db_schema::schema::site::dsl::*; + use crate::schema::site::dsl::*; diesel::update(site.find(site_id)) .set(new_site) .get_result::(conn) } fn delete(conn: &PgConnection, site_id: i32) -> Result { - use lemmy_db_schema::schema::site::dsl::*; + use crate::schema::site::dsl::*; diesel::delete(site.find(site_id)).execute(conn) } } -pub trait Site_ { - fn transfer(conn: &PgConnection, new_creator_id: PersonId) -> Result; - fn read_simple(conn: &PgConnection) -> Result; -} - -impl Site_ for Site { - fn transfer(conn: &PgConnection, new_creator_id: PersonId) -> Result { - use lemmy_db_schema::schema::site::dsl::*; +impl Site { + pub fn transfer(conn: &PgConnection, new_creator_id: PersonId) -> Result { + use crate::schema::site::dsl::*; diesel::update(site.find(1)) .set((creator_id.eq(new_creator_id), updated.eq(naive_now()))) .get_result::(conn) } - fn read_simple(conn: &PgConnection) -> Result { - use lemmy_db_schema::schema::site::dsl::*; + pub fn read_simple(conn: &PgConnection) -> Result { + use crate::schema::site::dsl::*; site.first::(conn) } } diff --git a/crates/db_schema/src/lib.rs b/crates/db_schema/src/lib.rs index cc29848de..f30f0bd80 100644 --- a/crates/db_schema/src/lib.rs +++ b/crates/db_schema/src/lib.rs @@ -1,134 +1,194 @@ #[macro_use] extern crate diesel; - #[macro_use] extern crate diesel_derive_newtype; +#[macro_use] +extern crate lazy_static; +// this is used in tests +#[allow(unused_imports)] +#[macro_use] +extern crate diesel_migrations; +#[macro_use] +extern crate strum_macros; -use chrono::NaiveDateTime; -use diesel::{ - backend::Backend, - deserialize::FromSql, - serialize::{Output, ToSql}, - sql_types::Text, -}; -use serde::{Deserialize, Serialize}; -use std::{ - fmt, - fmt::{Display, Formatter}, - io::Write, -}; -use url::Url; - +pub mod aggregates; +pub mod impls; +pub mod newtypes; pub mod schema; pub mod source; +pub mod traits; -#[derive( - Debug, Copy, Clone, Hash, Eq, PartialEq, Default, Serialize, Deserialize, DieselNewType, -)] -pub struct PostId(pub i32); +pub type DbPool = diesel::r2d2::Pool>; -impl fmt::Display for PostId { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "{}", self.0) +use crate::newtypes::DbUrl; +use chrono::NaiveDateTime; +use diesel::{Connection, PgConnection}; +use lemmy_utils::ApiError; +use regex::Regex; +use serde::{Deserialize, Serialize}; +use std::{env, env::VarError}; +use url::Url; + +pub fn get_database_url_from_env() -> Result { + env::var("LEMMY_DATABASE_URL") +} + +#[derive(EnumString, ToString, Debug, Serialize, Deserialize, Clone, Copy)] +pub enum SortType { + Active, + Hot, + New, + TopDay, + TopWeek, + TopMonth, + TopYear, + TopAll, + MostComments, + NewComments, +} + +#[derive(EnumString, ToString, Debug, Serialize, Deserialize, Clone, Copy)] +pub enum ListingType { + All, + Local, + Subscribed, + Community, +} + +#[derive(EnumString, ToString, Debug, Serialize, Deserialize, Clone, Copy)] +pub enum SearchType { + All, + Comments, + Posts, + Communities, + Users, + Url, +} + +pub fn from_opt_str_to_opt_enum(opt: &Option) -> Option { + opt.as_ref().map(|t| T::from_str(t).ok()).flatten() +} + +pub fn fuzzy_search(q: &str) -> String { + let replaced = q.replace(" ", "%"); + format!("%{}%", replaced) +} + +pub fn limit_and_offset(page: Option, limit: Option) -> (i64, i64) { + let page = page.unwrap_or(1); + let limit = limit.unwrap_or(10); + let offset = limit * (page - 1); + (limit, offset) +} + +pub fn is_email_regex(test: &str) -> bool { + EMAIL_REGEX.is_match(test) +} + +pub fn diesel_option_overwrite(opt: &Option) -> Option> { + match opt { + // An empty string is an erase + Some(unwrapped) => { + if !unwrapped.eq("") { + Some(Some(unwrapped.to_owned())) + } else { + Some(None) + } + } + None => None, } } -#[derive( - Debug, Copy, Clone, Hash, Eq, PartialEq, Default, Serialize, Deserialize, DieselNewType, -)] -pub struct PersonId(pub i32); - -#[derive(Debug, Copy, Clone, Hash, Eq, PartialEq, Serialize, Deserialize, DieselNewType)] -pub struct CommentId(pub i32); - -impl fmt::Display for CommentId { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "{}", self.0) +pub fn diesel_option_overwrite_to_url( + opt: &Option, +) -> Result>, ApiError> { + match opt.as_ref().map(|s| s.as_str()) { + // An empty string is an erase + Some("") => Ok(Some(None)), + Some(str_url) => match Url::parse(str_url) { + Ok(url) => Ok(Some(Some(url.into()))), + Err(e) => Err(ApiError::err("invalid_url", e)), + }, + None => Ok(None), } } -#[derive( - Debug, Copy, Clone, Hash, Eq, PartialEq, Default, Serialize, Deserialize, DieselNewType, -)] -pub struct CommunityId(pub i32); +embed_migrations!(); -#[derive(Debug, Copy, Clone, Hash, Eq, PartialEq, Serialize, Deserialize, DieselNewType)] -pub struct LocalUserId(pub i32); - -#[derive(Debug, Copy, Clone, Hash, Eq, PartialEq, Serialize, Deserialize, DieselNewType)] -pub struct PrivateMessageId(i32); - -impl fmt::Display for PrivateMessageId { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "{}", self.0) - } +pub fn establish_unpooled_connection() -> PgConnection { + let db_url = match get_database_url_from_env() { + Ok(url) => url, + Err(e) => panic!( + "Failed to read database URL from env var LEMMY_DATABASE_URL: {}", + e + ), + }; + let conn = + PgConnection::establish(&db_url).unwrap_or_else(|_| panic!("Error connecting to {}", db_url)); + embedded_migrations::run(&conn).expect("load migrations"); + conn } -#[derive(Debug, Copy, Clone, Hash, Eq, PartialEq, Serialize, Deserialize, DieselNewType)] -pub struct PersonMentionId(i32); - -#[derive(Debug, Copy, Clone, Hash, Eq, PartialEq, Serialize, Deserialize, DieselNewType)] -pub struct PersonBlockId(i32); - -#[derive(Debug, Copy, Clone, Hash, Eq, PartialEq, Serialize, Deserialize, DieselNewType)] -pub struct CommunityBlockId(i32); - -#[derive(Debug, Copy, Clone, Hash, Eq, PartialEq, Serialize, Deserialize, DieselNewType)] -pub struct CommentReportId(i32); - -#[derive(Debug, Copy, Clone, Hash, Eq, PartialEq, Serialize, Deserialize, DieselNewType)] -pub struct PostReportId(i32); - -#[repr(transparent)] -#[derive(Clone, PartialEq, Serialize, Deserialize, Debug, AsExpression, FromSqlRow)] -#[sql_type = "Text"] -pub struct DbUrl(Url); - -impl ToSql for DbUrl -where - String: ToSql, -{ - fn to_sql(&self, out: &mut Output) -> diesel::serialize::Result { - self.0.to_string().to_sql(out) - } -} - -impl FromSql for DbUrl -where - String: FromSql, -{ - fn from_sql(bytes: Option<&DB::RawValue>) -> diesel::deserialize::Result { - let str = String::from_sql(bytes)?; - Ok(DbUrl(Url::parse(&str)?)) - } -} - -impl DbUrl { - // TODO: remove this method and just use into() - pub fn into_inner(self) -> Url { - self.0 - } -} - -impl Display for DbUrl { - fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { - self.to_owned().0.fmt(f) - } -} - -impl From for Url { - fn from(url: DbUrl) -> Self { - url.0 - } -} - -impl From for DbUrl { - fn from(url: Url) -> Self { - DbUrl(url) - } -} - -// TODO: can probably move this back to lemmy_db_queries pub fn naive_now() -> NaiveDateTime { chrono::prelude::Utc::now().naive_utc() } + +lazy_static! { + static ref EMAIL_REGEX: Regex = + Regex::new(r"^[a-zA-Z0-9.!#$%&’*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*$") + .expect("compile email regex"); +} + +pub mod functions { + use diesel::sql_types::*; + + sql_function! { + fn hot_rank(score: BigInt, time: Timestamp) -> Integer; + } +} + +#[cfg(test)] +mod tests { + use super::{fuzzy_search, *}; + use crate::is_email_regex; + + #[test] + fn test_fuzzy_search() { + let test = "This is a fuzzy search"; + assert_eq!(fuzzy_search(test), "%This%is%a%fuzzy%search%".to_string()); + } + + #[test] + fn test_email() { + assert!(is_email_regex("gush@gmail.com")); + assert!(!is_email_regex("nada_neutho")); + } + + #[test] + fn test_diesel_option_overwrite() { + assert_eq!(diesel_option_overwrite(&None), None); + assert_eq!(diesel_option_overwrite(&Some("".to_string())), Some(None)); + assert_eq!( + diesel_option_overwrite(&Some("test".to_string())), + Some(Some("test".to_string())) + ); + } + + #[test] + fn test_diesel_option_overwrite_to_url() { + assert!(matches!(diesel_option_overwrite_to_url(&None), Ok(None))); + assert!(matches!( + diesel_option_overwrite_to_url(&Some("".to_string())), + Ok(Some(None)) + )); + assert!(matches!( + diesel_option_overwrite_to_url(&Some("invalid_url".to_string())), + Err(_) + )); + let example_url = "https://example.com"; + assert!(matches!( + diesel_option_overwrite_to_url(&Some(example_url.to_string())), + Ok(Some(Some(url))) if url == Url::parse(example_url).unwrap().into() + )); + } +} diff --git a/crates/db_schema/src/newtypes.rs b/crates/db_schema/src/newtypes.rs new file mode 100644 index 000000000..3042d35e7 --- /dev/null +++ b/crates/db_schema/src/newtypes.rs @@ -0,0 +1,119 @@ +use diesel::{ + backend::Backend, + deserialize::FromSql, + serialize::{Output, ToSql}, + sql_types::Text, +}; +use serde::{Deserialize, Serialize}; +use std::{ + fmt, + fmt::{Display, Formatter}, + io::Write, +}; +use url::Url; + +#[derive( + Debug, Copy, Clone, Hash, Eq, PartialEq, Default, Serialize, Deserialize, DieselNewType, +)] +pub struct PostId(pub i32); + +impl fmt::Display for PostId { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "{}", self.0) + } +} + +#[derive( + Debug, Copy, Clone, Hash, Eq, PartialEq, Default, Serialize, Deserialize, DieselNewType, +)] +pub struct PersonId(pub i32); + +#[derive(Debug, Copy, Clone, Hash, Eq, PartialEq, Serialize, Deserialize, DieselNewType)] +pub struct CommentId(pub i32); + +impl fmt::Display for CommentId { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "{}", self.0) + } +} + +#[derive( + Debug, Copy, Clone, Hash, Eq, PartialEq, Default, Serialize, Deserialize, DieselNewType, +)] +pub struct CommunityId(pub i32); + +#[derive(Debug, Copy, Clone, Hash, Eq, PartialEq, Serialize, Deserialize, DieselNewType)] +pub struct LocalUserId(pub i32); + +#[derive(Debug, Copy, Clone, Hash, Eq, PartialEq, Serialize, Deserialize, DieselNewType)] +pub struct PrivateMessageId(i32); + +impl fmt::Display for PrivateMessageId { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "{}", self.0) + } +} + +#[derive(Debug, Copy, Clone, Hash, Eq, PartialEq, Serialize, Deserialize, DieselNewType)] +pub struct PersonMentionId(i32); + +#[derive(Debug, Copy, Clone, Hash, Eq, PartialEq, Serialize, Deserialize, DieselNewType)] +pub struct PersonBlockId(i32); + +#[derive(Debug, Copy, Clone, Hash, Eq, PartialEq, Serialize, Deserialize, DieselNewType)] +pub struct CommunityBlockId(i32); + +#[derive(Debug, Copy, Clone, Hash, Eq, PartialEq, Serialize, Deserialize, DieselNewType)] +pub struct CommentReportId(i32); + +#[derive(Debug, Copy, Clone, Hash, Eq, PartialEq, Serialize, Deserialize, DieselNewType)] +pub struct PostReportId(i32); + +#[repr(transparent)] +#[derive(Clone, PartialEq, Serialize, Deserialize, Debug, AsExpression, FromSqlRow)] +#[sql_type = "Text"] +pub struct DbUrl(Url); + +impl ToSql for DbUrl +where + String: ToSql, +{ + fn to_sql(&self, out: &mut Output) -> diesel::serialize::Result { + self.0.to_string().to_sql(out) + } +} + +impl FromSql for DbUrl +where + String: FromSql, +{ + fn from_sql(bytes: Option<&DB::RawValue>) -> diesel::deserialize::Result { + let str = String::from_sql(bytes)?; + Ok(DbUrl(Url::parse(&str)?)) + } +} + +impl DbUrl { + // TODO: remove this method and just use into() + pub fn into_inner(self) -> Url { + self.0 + } +} + +impl Display for DbUrl { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + self.to_owned().0.fmt(f) + } +} + +impl From for Url { + fn from(url: DbUrl) -> Self { + url.0 + } +} + +impl From for DbUrl { + fn from(url: Url) -> Self { + DbUrl(url) + } +} diff --git a/crates/db_schema/src/source/activity.rs b/crates/db_schema/src/source/activity.rs index ced8f3be4..c5ac833ed 100644 --- a/crates/db_schema/src/source/activity.rs +++ b/crates/db_schema/src/source/activity.rs @@ -1,4 +1,4 @@ -use crate::{schema::activity, DbUrl}; +use crate::{newtypes::DbUrl, schema::activity}; use serde_json::Value; use std::fmt::Debug; diff --git a/crates/db_schema/src/source/comment.rs b/crates/db_schema/src/source/comment.rs index 54e8221f9..46242fc73 100644 --- a/crates/db_schema/src/source/comment.rs +++ b/crates/db_schema/src/source/comment.rs @@ -1,18 +1,9 @@ use crate::{ - naive_now, + newtypes::{CommentId, DbUrl, PersonId, PostId}, schema::{comment, comment_alias_1, comment_like, comment_saved}, source::post::Post, - CommentId, - DbUrl, - PersonId, - PostId, }; -use chrono::NaiveDateTime; -use diesel::{ExpressionMethods, PgConnection, QueryDsl, RunQueryDsl}; -use lemmy_apub_lib::traits::ApubObject; -use lemmy_utils::LemmyError; use serde::{Deserialize, Serialize}; -use url::Url; // WITH RECURSIVE MyTree AS ( // SELECT * FROM comment WHERE parent_id IS NULL @@ -114,27 +105,3 @@ pub struct CommentSavedForm { pub comment_id: CommentId, pub person_id: PersonId, } - -impl ApubObject for Comment { - type DataType = PgConnection; - - fn last_refreshed_at(&self) -> Option { - None - } - - fn read_from_apub_id(conn: &PgConnection, object_id: Url) -> Result, LemmyError> { - use crate::schema::comment::dsl::*; - let object_id: DbUrl = object_id.into(); - Ok(comment.filter(ap_id.eq(object_id)).first::(conn).ok()) - } - - // TODO: duplicate code from Comment::update_deleted(), we should really move all impls to - // this crate so we can call that function from here - fn delete(self, conn: &PgConnection) -> Result<(), LemmyError> { - use crate::schema::comment::dsl::*; - diesel::update(comment.find(self.id)) - .set((deleted.eq(true), updated.eq(naive_now()))) - .get_result::(conn)?; - Ok(()) - } -} diff --git a/crates/db_schema/src/source/comment_report.rs b/crates/db_schema/src/source/comment_report.rs index 57ca961de..3c265ed09 100644 --- a/crates/db_schema/src/source/comment_report.rs +++ b/crates/db_schema/src/source/comment_report.rs @@ -1,9 +1,7 @@ use crate::{ + newtypes::{CommentId, CommentReportId, PersonId}, schema::comment_report, source::comment::Comment, - CommentId, - CommentReportId, - PersonId, }; use serde::{Deserialize, Serialize}; diff --git a/crates/db_schema/src/source/community.rs b/crates/db_schema/src/source/community.rs index 365ddba7f..4c351b886 100644 --- a/crates/db_schema/src/source/community.rs +++ b/crates/db_schema/src/source/community.rs @@ -1,16 +1,8 @@ use crate::{ - naive_now, + newtypes::{CommunityId, DbUrl, PersonId}, schema::{community, community_follower, community_moderator, community_person_ban}, - CommunityId, - DbUrl, - PersonId, }; -use chrono::NaiveDateTime; -use diesel::{ExpressionMethods, PgConnection, QueryDsl, RunQueryDsl}; -use lemmy_apub_lib::traits::{ActorType, ApubObject}; -use lemmy_utils::LemmyError; use serde::{Deserialize, Serialize}; -use url::Url; #[derive(Clone, Queryable, Identifiable, PartialEq, Debug, Serialize, Deserialize)] #[table_name = "community"] @@ -130,56 +122,3 @@ pub struct CommunityFollowerForm { pub person_id: PersonId, pub pending: bool, } - -impl ApubObject for Community { - type DataType = PgConnection; - - fn last_refreshed_at(&self) -> Option { - Some(self.last_refreshed_at) - } - - fn read_from_apub_id(conn: &PgConnection, object_id: Url) -> Result, LemmyError> { - use crate::schema::community::dsl::*; - let object_id: DbUrl = object_id.into(); - Ok( - community - .filter(actor_id.eq(object_id)) - .first::(conn) - .ok(), - ) - } - - fn delete(self, conn: &PgConnection) -> Result<(), LemmyError> { - use crate::schema::community::dsl::*; - diesel::update(community.find(self.id)) - .set((deleted.eq(true), updated.eq(naive_now()))) - .get_result::(conn)?; - Ok(()) - } -} - -impl ActorType for Community { - fn is_local(&self) -> bool { - self.local - } - fn actor_id(&self) -> Url { - self.actor_id.to_owned().into() - } - fn name(&self) -> String { - self.name.clone() - } - fn public_key(&self) -> Option { - self.public_key.to_owned() - } - fn private_key(&self) -> Option { - self.private_key.to_owned() - } - - fn inbox_url(&self) -> Url { - self.inbox_url.clone().into() - } - - fn shared_inbox_url(&self) -> Option { - self.shared_inbox_url.clone().map(|s| s.into_inner()) - } -} diff --git a/crates/db_schema/src/source/community_block.rs b/crates/db_schema/src/source/community_block.rs index 35dfbd8a9..f5cc545e8 100644 --- a/crates/db_schema/src/source/community_block.rs +++ b/crates/db_schema/src/source/community_block.rs @@ -1,9 +1,7 @@ use crate::{ + newtypes::{CommunityBlockId, CommunityId, PersonId}, schema::community_block, source::community::Community, - CommunityBlockId, - CommunityId, - PersonId, }; use serde::{Deserialize, Serialize}; diff --git a/crates/db_schema/src/source/local_user.rs b/crates/db_schema/src/source/local_user.rs index d9fce8da9..34dd26f76 100644 --- a/crates/db_schema/src/source/local_user.rs +++ b/crates/db_schema/src/source/local_user.rs @@ -1,4 +1,7 @@ -use crate::{schema::local_user, LocalUserId, PersonId}; +use crate::{ + newtypes::{LocalUserId, PersonId}, + schema::local_user, +}; use serde::{Deserialize, Serialize}; #[derive(Clone, Queryable, Identifiable, PartialEq, Debug, Serialize, Deserialize)] diff --git a/crates/db_schema/src/source/moderator.rs b/crates/db_schema/src/source/moderator.rs index adde70351..ee8bc693f 100644 --- a/crates/db_schema/src/source/moderator.rs +++ b/crates/db_schema/src/source/moderator.rs @@ -1,4 +1,5 @@ use crate::{ + newtypes::{CommentId, CommunityId, PersonId, PostId}, schema::{ mod_add, mod_add_community, @@ -11,10 +12,6 @@ use crate::{ mod_sticky_post, mod_transfer_community, }, - CommentId, - CommunityId, - PersonId, - PostId, }; use serde::{Deserialize, Serialize}; diff --git a/crates/db_schema/src/source/password_reset_request.rs b/crates/db_schema/src/source/password_reset_request.rs index 0af2d024d..0d461049f 100644 --- a/crates/db_schema/src/source/password_reset_request.rs +++ b/crates/db_schema/src/source/password_reset_request.rs @@ -1,4 +1,4 @@ -use crate::{schema::password_reset_request, LocalUserId}; +use crate::{newtypes::LocalUserId, schema::password_reset_request}; #[derive(Queryable, Identifiable, PartialEq, Debug)] #[table_name = "password_reset_request"] diff --git a/crates/db_schema/src/source/person.rs b/crates/db_schema/src/source/person.rs index f71f39dc9..c9ffad7b3 100644 --- a/crates/db_schema/src/source/person.rs +++ b/crates/db_schema/src/source/person.rs @@ -1,15 +1,8 @@ use crate::{ - naive_now, + newtypes::{DbUrl, PersonId}, schema::{person, person_alias_1, person_alias_2}, - DbUrl, - PersonId, }; -use chrono::NaiveDateTime; -use diesel::{ExpressionMethods, PgConnection, QueryDsl, RunQueryDsl}; -use lemmy_apub_lib::traits::{ActorType, ApubObject}; -use lemmy_utils::LemmyError; use serde::{Deserialize, Serialize}; -use url::Url; #[derive(Clone, Queryable, Identifiable, PartialEq, Debug, Serialize, Deserialize)] #[table_name = "person"] @@ -176,59 +169,3 @@ pub struct PersonForm { pub admin: Option, pub bot_account: Option, } - -impl ApubObject for Person { - type DataType = PgConnection; - - fn last_refreshed_at(&self) -> Option { - Some(self.last_refreshed_at) - } - - fn read_from_apub_id(conn: &PgConnection, object_id: Url) -> Result, LemmyError> { - use crate::schema::person::dsl::*; - let object_id: DbUrl = object_id.into(); - Ok( - person - .filter(deleted.eq(false)) - .filter(actor_id.eq(object_id)) - .first::(conn) - .ok(), - ) - } - - fn delete(self, conn: &PgConnection) -> Result<(), LemmyError> { - use crate::schema::person::dsl::*; - diesel::update(person.find(self.id)) - .set((deleted.eq(true), updated.eq(naive_now()))) - .get_result::(conn)?; - Ok(()) - } -} - -impl ActorType for Person { - fn is_local(&self) -> bool { - self.local - } - fn actor_id(&self) -> Url { - self.actor_id.to_owned().into_inner() - } - fn name(&self) -> String { - self.name.clone() - } - - fn public_key(&self) -> Option { - self.public_key.to_owned() - } - - fn private_key(&self) -> Option { - self.private_key.to_owned() - } - - fn inbox_url(&self) -> Url { - self.inbox_url.clone().into() - } - - fn shared_inbox_url(&self) -> Option { - self.shared_inbox_url.clone().map(|s| s.into_inner()) - } -} diff --git a/crates/db_schema/src/source/person_block.rs b/crates/db_schema/src/source/person_block.rs index c0ad15ca9..ff55872f1 100644 --- a/crates/db_schema/src/source/person_block.rs +++ b/crates/db_schema/src/source/person_block.rs @@ -1,4 +1,7 @@ -use crate::{schema::person_block, PersonBlockId, PersonId}; +use crate::{ + newtypes::{PersonBlockId, PersonId}, + schema::person_block, +}; use serde::{Deserialize, Serialize}; #[derive( diff --git a/crates/db_schema/src/source/person_mention.rs b/crates/db_schema/src/source/person_mention.rs index d65a13b9d..795799c7e 100644 --- a/crates/db_schema/src/source/person_mention.rs +++ b/crates/db_schema/src/source/person_mention.rs @@ -1,9 +1,7 @@ use crate::{ + newtypes::{CommentId, PersonId, PersonMentionId}, schema::person_mention, source::comment::Comment, - CommentId, - PersonId, - PersonMentionId, }; use serde::{Deserialize, Serialize}; diff --git a/crates/db_schema/src/source/post.rs b/crates/db_schema/src/source/post.rs index d28599c59..cc9325361 100644 --- a/crates/db_schema/src/source/post.rs +++ b/crates/db_schema/src/source/post.rs @@ -1,18 +1,8 @@ use crate::{ - naive_now, + newtypes::{CommunityId, DbUrl, PersonId, PostId}, schema::{post, post_like, post_read, post_saved}, - CommunityId, - DbUrl, - PersonId, - PostId, }; -use chrono::NaiveDateTime; -use diesel::{ExpressionMethods, PgConnection, QueryDsl, RunQueryDsl}; -use lemmy_apub_lib::traits::ApubObject; -use lemmy_utils::LemmyError; use serde::{Deserialize, Serialize}; -use url::Url; - #[derive(Clone, Queryable, Identifiable, PartialEq, Debug, Serialize, Deserialize)] #[table_name = "post"] pub struct Post { @@ -112,25 +102,3 @@ pub struct PostReadForm { pub post_id: PostId, pub person_id: PersonId, } - -impl ApubObject for Post { - type DataType = PgConnection; - - fn last_refreshed_at(&self) -> Option { - None - } - - fn read_from_apub_id(conn: &PgConnection, object_id: Url) -> Result, LemmyError> { - use crate::schema::post::dsl::*; - let object_id: DbUrl = object_id.into(); - Ok(post.filter(ap_id.eq(object_id)).first::(conn).ok()) - } - - fn delete(self, conn: &PgConnection) -> Result<(), LemmyError> { - use crate::schema::post::dsl::*; - diesel::update(post.find(self.id)) - .set((deleted.eq(true), updated.eq(naive_now()))) - .get_result::(conn)?; - Ok(()) - } -} diff --git a/crates/db_schema/src/source/post_report.rs b/crates/db_schema/src/source/post_report.rs index a146a4bef..6e711782b 100644 --- a/crates/db_schema/src/source/post_report.rs +++ b/crates/db_schema/src/source/post_report.rs @@ -1,4 +1,8 @@ -use crate::{schema::post_report, source::post::Post, DbUrl, PersonId, PostId, PostReportId}; +use crate::{ + newtypes::{DbUrl, PersonId, PostId, PostReportId}, + schema::post_report, + source::post::Post, +}; use serde::{Deserialize, Serialize}; #[derive( diff --git a/crates/db_schema/src/source/private_message.rs b/crates/db_schema/src/source/private_message.rs index 6247cb955..7facccaac 100644 --- a/crates/db_schema/src/source/private_message.rs +++ b/crates/db_schema/src/source/private_message.rs @@ -1,10 +1,8 @@ -use crate::{schema::private_message, DbUrl, PersonId, PrivateMessageId}; -use chrono::NaiveDateTime; -use diesel::{ExpressionMethods, PgConnection, QueryDsl, RunQueryDsl}; -use lemmy_apub_lib::traits::ApubObject; -use lemmy_utils::LemmyError; +use crate::{ + newtypes::{DbUrl, PersonId, PrivateMessageId}, + schema::private_message, +}; use serde::{Deserialize, Serialize}; -use url::Url; #[derive( Clone, Queryable, Associations, Identifiable, PartialEq, Debug, Serialize, Deserialize, @@ -36,27 +34,3 @@ pub struct PrivateMessageForm { pub ap_id: Option, pub local: Option, } - -impl ApubObject for PrivateMessage { - type DataType = PgConnection; - - fn last_refreshed_at(&self) -> Option { - None - } - - fn read_from_apub_id(conn: &PgConnection, object_id: Url) -> Result, LemmyError> { - use crate::schema::private_message::dsl::*; - let object_id: DbUrl = object_id.into(); - Ok( - private_message - .filter(ap_id.eq(object_id)) - .first::(conn) - .ok(), - ) - } - - fn delete(self, _conn: &PgConnection) -> Result<(), LemmyError> { - // do nothing, because pm can't be fetched over http - unimplemented!() - } -} diff --git a/crates/db_schema/src/source/site.rs b/crates/db_schema/src/source/site.rs index ec9dee84e..dd273f9da 100644 --- a/crates/db_schema/src/source/site.rs +++ b/crates/db_schema/src/source/site.rs @@ -1,4 +1,7 @@ -use crate::{schema::site, DbUrl, PersonId}; +use crate::{ + newtypes::{DbUrl, PersonId}, + schema::site, +}; use serde::{Deserialize, Serialize}; #[derive(Queryable, Identifiable, PartialEq, Debug, Clone, Serialize, Deserialize)] diff --git a/crates/db_schema/src/traits.rs b/crates/db_schema/src/traits.rs new file mode 100644 index 000000000..aea36ed87 --- /dev/null +++ b/crates/db_schema/src/traits.rs @@ -0,0 +1,164 @@ +use crate::newtypes::{CommunityId, PersonId}; +use diesel::{result::Error, PgConnection}; + +pub trait Crud { + type Form; + type IdType; + fn create(conn: &PgConnection, form: &Self::Form) -> Result + where + Self: Sized; + fn read(conn: &PgConnection, id: Self::IdType) -> Result + where + Self: Sized; + fn update(conn: &PgConnection, id: Self::IdType, form: &Self::Form) -> Result + where + Self: Sized; + fn delete(_conn: &PgConnection, _id: Self::IdType) -> Result + where + Self: Sized, + { + unimplemented!() + } +} + +pub trait Followable { + type Form; + fn follow(conn: &PgConnection, form: &Self::Form) -> Result + where + Self: Sized; + fn follow_accepted( + conn: &PgConnection, + community_id: CommunityId, + person_id: PersonId, + ) -> Result + where + Self: Sized; + fn unfollow(conn: &PgConnection, form: &Self::Form) -> Result + where + Self: Sized; + fn has_local_followers(conn: &PgConnection, community_id: CommunityId) -> Result; +} + +pub trait Joinable { + type Form; + fn join(conn: &PgConnection, form: &Self::Form) -> Result + where + Self: Sized; + fn leave(conn: &PgConnection, form: &Self::Form) -> Result + where + Self: Sized; +} + +pub trait Likeable { + type Form; + type IdType; + fn like(conn: &PgConnection, form: &Self::Form) -> Result + where + Self: Sized; + fn remove( + conn: &PgConnection, + person_id: PersonId, + item_id: Self::IdType, + ) -> Result + where + Self: Sized; +} + +pub trait Bannable { + type Form; + fn ban(conn: &PgConnection, form: &Self::Form) -> Result + where + Self: Sized; + fn unban(conn: &PgConnection, form: &Self::Form) -> Result + where + Self: Sized; +} + +pub trait Saveable { + type Form; + fn save(conn: &PgConnection, form: &Self::Form) -> Result + where + Self: Sized; + fn unsave(conn: &PgConnection, form: &Self::Form) -> Result + where + Self: Sized; +} + +pub trait Blockable { + type Form; + fn block(conn: &PgConnection, form: &Self::Form) -> Result + where + Self: Sized; + fn unblock(conn: &PgConnection, form: &Self::Form) -> Result + where + Self: Sized; +} + +pub trait Readable { + type Form; + fn mark_as_read(conn: &PgConnection, form: &Self::Form) -> Result + where + Self: Sized; + fn mark_as_unread(conn: &PgConnection, form: &Self::Form) -> Result + where + Self: Sized; +} + +pub trait Reportable { + type Form; + type IdType; + fn report(conn: &PgConnection, form: &Self::Form) -> Result + where + Self: Sized; + fn resolve( + conn: &PgConnection, + report_id: Self::IdType, + resolver_id: PersonId, + ) -> Result + where + Self: Sized; + fn unresolve( + conn: &PgConnection, + report_id: Self::IdType, + resolver_id: PersonId, + ) -> Result + where + Self: Sized; +} + +pub trait DeleteableOrRemoveable { + fn blank_out_deleted_or_removed_info(self) -> Self; +} + +pub trait MaybeOptional { + fn get_optional(self) -> Option; +} + +impl MaybeOptional for T { + fn get_optional(self) -> Option { + Some(self) + } +} + +impl MaybeOptional for Option { + fn get_optional(self) -> Option { + self + } +} + +pub trait ToSafe { + type SafeColumns; + fn safe_columns_tuple() -> Self::SafeColumns; +} + +pub trait ToSafeSettings { + type SafeSettingsColumns; + fn safe_settings_columns_tuple() -> Self::SafeSettingsColumns; +} + +pub trait ViewToVec { + type DbTuple; + fn from_tuple_to_vec(tuple: Vec) -> Vec + where + Self: Sized; +} diff --git a/crates/db_views/Cargo.toml b/crates/db_views/Cargo.toml index 85afe569e..fbea19878 100644 --- a/crates/db_views/Cargo.toml +++ b/crates/db_views/Cargo.toml @@ -11,7 +11,6 @@ documentation = "https://join-lemmy.org/docs/en/index.html" doctest = false [dependencies] -lemmy_db_queries = { version = "=0.13.0", path = "../db_queries" } lemmy_db_schema = { version = "=0.13.0", path = "../db_schema" } diesel = { version = "1.4.8", features = ["postgres","chrono","r2d2","serde_json"] } serde = { version = "1.0.130", features = ["derive"] } diff --git a/crates/db_views/src/comment_report_view.rs b/crates/db_views/src/comment_report_view.rs index 7c2f99579..1469e42d0 100644 --- a/crates/db_views/src/comment_report_view.rs +++ b/crates/db_views/src/comment_report_view.rs @@ -1,12 +1,8 @@ use diesel::{result::Error, *}; -use lemmy_db_queries::{ +use lemmy_db_schema::{ aggregates::comment_aggregates::CommentAggregates, limit_and_offset, - MaybeOptional, - ToSafe, - ViewToVec, -}; -use lemmy_db_schema::{ + newtypes::{CommentReportId, CommunityId, PersonId}, schema::{ comment, comment_aggregates, @@ -27,9 +23,7 @@ use lemmy_db_schema::{ person::{Person, PersonAlias1, PersonAlias2, PersonSafe, PersonSafeAlias1, PersonSafeAlias2}, post::Post, }, - CommentReportId, - CommunityId, - PersonId, + traits::{MaybeOptional, ToSafe, ViewToVec}, }; use serde::{Deserialize, Serialize}; @@ -309,14 +303,12 @@ impl ViewToVec for CommentReportView { #[cfg(test)] mod tests { use crate::comment_report_view::{CommentReportQueryBuilder, CommentReportView}; - use lemmy_db_queries::{ + use lemmy_db_schema::{ aggregates::comment_aggregates::CommentAggregates, establish_unpooled_connection, - Crud, - Joinable, - Reportable, + source::{comment::*, comment_report::*, community::*, person::*, post::*}, + traits::{Crud, Joinable, Reportable}, }; - use lemmy_db_schema::source::{comment::*, comment_report::*, community::*, person::*, post::*}; use serial_test::serial; #[test] diff --git a/crates/db_views/src/comment_view.rs b/crates/db_views/src/comment_view.rs index 2468c6536..4fdd40970 100644 --- a/crates/db_views/src/comment_view.rs +++ b/crates/db_views/src/comment_view.rs @@ -1,16 +1,10 @@ use diesel::{result::Error, *}; -use lemmy_db_queries::{ +use lemmy_db_schema::{ aggregates::comment_aggregates::CommentAggregates, functions::hot_rank, fuzzy_search, limit_and_offset, - ListingType, - MaybeOptional, - SortType, - ToSafe, - ViewToVec, -}; -use lemmy_db_schema::{ + newtypes::{CommentId, CommunityId, DbUrl, PersonId, PostId}, schema::{ comment, comment_aggregates, @@ -33,11 +27,9 @@ use lemmy_db_schema::{ person_block::PersonBlock, post::Post, }, - CommentId, - CommunityId, - DbUrl, - PersonId, - PostId, + traits::{MaybeOptional, ToSafe, ViewToVec}, + ListingType, + SortType, }; use serde::{Deserialize, Serialize}; @@ -526,19 +518,11 @@ impl ViewToVec for CommentView { #[cfg(test)] mod tests { use crate::comment_view::*; - use lemmy_db_queries::{ + use lemmy_db_schema::{ aggregates::comment_aggregates::CommentAggregates, establish_unpooled_connection, - Blockable, - Crud, - Likeable, - }; - use lemmy_db_schema::source::{ - comment::*, - community::*, - person::*, - person_block::PersonBlockForm, - post::*, + source::{comment::*, community::*, person::*, person_block::PersonBlockForm, post::*}, + traits::{Blockable, Crud, Likeable}, }; use serial_test::serial; diff --git a/crates/db_views/src/local_user_view.rs b/crates/db_views/src/local_user_view.rs index 0e4d872ac..f697aba65 100644 --- a/crates/db_views/src/local_user_view.rs +++ b/crates/db_views/src/local_user_view.rs @@ -1,13 +1,13 @@ use diesel::{result::Error, *}; -use lemmy_db_queries::{aggregates::person_aggregates::PersonAggregates, ToSafe, ToSafeSettings}; use lemmy_db_schema::{ + aggregates::person_aggregates::PersonAggregates, + newtypes::{LocalUserId, PersonId}, schema::{local_user, person, person_aggregates}, source::{ local_user::{LocalUser, LocalUserSettings}, person::{Person, PersonSafe}, }, - LocalUserId, - PersonId, + traits::{ToSafe, ToSafeSettings}, }; use serde::{Deserialize, Serialize}; diff --git a/crates/db_views/src/post_report_view.rs b/crates/db_views/src/post_report_view.rs index a8604ea9c..f27ba50aa 100644 --- a/crates/db_views/src/post_report_view.rs +++ b/crates/db_views/src/post_report_view.rs @@ -1,12 +1,8 @@ use diesel::{result::Error, *}; -use lemmy_db_queries::{ +use lemmy_db_schema::{ aggregates::post_aggregates::PostAggregates, limit_and_offset, - MaybeOptional, - ToSafe, - ViewToVec, -}; -use lemmy_db_schema::{ + newtypes::{CommunityId, PersonId, PostReportId}, schema::{ community, community_moderator, @@ -25,9 +21,7 @@ use lemmy_db_schema::{ post::Post, post_report::PostReport, }, - CommunityId, - PersonId, - PostReportId, + traits::{MaybeOptional, ToSafe, ViewToVec}, }; use serde::{Deserialize, Serialize}; @@ -288,18 +282,16 @@ impl ViewToVec for PostReportView { #[cfg(test)] mod tests { use crate::post_report_view::{PostReportQueryBuilder, PostReportView}; - use lemmy_db_queries::{ + use lemmy_db_schema::{ aggregates::post_aggregates::PostAggregates, establish_unpooled_connection, - Crud, - Joinable, - Reportable, - }; - use lemmy_db_schema::source::{ - community::*, - person::*, - post::*, - post_report::{PostReport, PostReportForm}, + source::{ + community::*, + person::*, + post::*, + post_report::{PostReport, PostReportForm}, + }, + traits::{Crud, Joinable, Reportable}, }; use serial_test::serial; diff --git a/crates/db_views/src/post_view.rs b/crates/db_views/src/post_view.rs index f42a16599..897a78e00 100644 --- a/crates/db_views/src/post_view.rs +++ b/crates/db_views/src/post_view.rs @@ -1,16 +1,10 @@ use diesel::{pg::Pg, result::Error, *}; -use lemmy_db_queries::{ +use lemmy_db_schema::{ aggregates::post_aggregates::PostAggregates, functions::hot_rank, fuzzy_search, limit_and_offset, - ListingType, - MaybeOptional, - SortType, - ToSafe, - ViewToVec, -}; -use lemmy_db_schema::{ + newtypes::{CommunityId, DbUrl, PersonId, PostId}, schema::{ community, community_block, @@ -30,10 +24,9 @@ use lemmy_db_schema::{ person_block::PersonBlock, post::{Post, PostRead, PostSaved}, }, - CommunityId, - DbUrl, - PersonId, - PostId, + traits::{MaybeOptional, ToSafe, ViewToVec}, + ListingType, + SortType, }; use log::debug; use serde::{Deserialize, Serialize}; @@ -487,22 +480,20 @@ impl ViewToVec for PostView { #[cfg(test)] mod tests { use crate::post_view::{PostQueryBuilder, PostView}; - use lemmy_db_queries::{ + use lemmy_db_schema::{ aggregates::post_aggregates::PostAggregates, establish_unpooled_connection, - Blockable, - Crud, - Likeable, + source::{ + community::*, + community_block::{CommunityBlock, CommunityBlockForm}, + person::*, + person_block::{PersonBlock, PersonBlockForm}, + post::*, + }, + traits::{Blockable, Crud, Likeable}, ListingType, SortType, }; - use lemmy_db_schema::source::{ - community::*, - community_block::{CommunityBlock, CommunityBlockForm}, - person::*, - person_block::{PersonBlock, PersonBlockForm}, - post::*, - }; use serial_test::serial; #[test] diff --git a/crates/db_views/src/private_message_view.rs b/crates/db_views/src/private_message_view.rs index 7e322bbc7..940dbd366 100644 --- a/crates/db_views/src/private_message_view.rs +++ b/crates/db_views/src/private_message_view.rs @@ -1,13 +1,13 @@ use diesel::{pg::Pg, result::Error, *}; -use lemmy_db_queries::{limit_and_offset, MaybeOptional, ToSafe, ViewToVec}; use lemmy_db_schema::{ + limit_and_offset, + newtypes::{PersonId, PrivateMessageId}, schema::{person, person_alias_1, private_message}, source::{ person::{Person, PersonAlias1, PersonSafe, PersonSafeAlias1}, private_message::PrivateMessage, }, - PersonId, - PrivateMessageId, + traits::{MaybeOptional, ToSafe, ViewToVec}, }; use log::debug; use serde::{Deserialize, Serialize}; diff --git a/crates/db_views/src/site_view.rs b/crates/db_views/src/site_view.rs index d0c2ee82d..3c94975aa 100644 --- a/crates/db_views/src/site_view.rs +++ b/crates/db_views/src/site_view.rs @@ -1,11 +1,12 @@ use diesel::{result::Error, *}; -use lemmy_db_queries::{aggregates::site_aggregates::SiteAggregates, ToSafe}; use lemmy_db_schema::{ + aggregates::site_aggregates::SiteAggregates, schema::{person, site, site_aggregates}, source::{ person::{Person, PersonSafe}, site::Site, }, + traits::ToSafe, }; use serde::{Deserialize, Serialize}; diff --git a/crates/db_views_actor/Cargo.toml b/crates/db_views_actor/Cargo.toml index fa21bf87b..ced1e8a28 100644 --- a/crates/db_views_actor/Cargo.toml +++ b/crates/db_views_actor/Cargo.toml @@ -11,7 +11,6 @@ documentation = "https://join-lemmy.org/docs/en/index.html" doctest = false [dependencies] -lemmy_db_queries = { version = "=0.13.0", path = "../db_queries" } lemmy_db_schema = { version = "=0.13.0", path = "../db_schema" } diesel = { version = "1.4.8", features = ["postgres","chrono","r2d2","serde_json"] } serde = { version = "1.0.130", features = ["derive"] } diff --git a/crates/db_views_actor/src/community_block_view.rs b/crates/db_views_actor/src/community_block_view.rs index 3046b0c2d..8f0cfca76 100644 --- a/crates/db_views_actor/src/community_block_view.rs +++ b/crates/db_views_actor/src/community_block_view.rs @@ -1,12 +1,12 @@ use diesel::{result::Error, *}; -use lemmy_db_queries::{ToSafe, ViewToVec}; use lemmy_db_schema::{ + newtypes::PersonId, schema::{community, community_block, person}, source::{ community::{Community, CommunitySafe}, person::{Person, PersonSafe}, }, - PersonId, + traits::{ToSafe, ViewToVec}, }; use serde::{Deserialize, Serialize}; diff --git a/crates/db_views_actor/src/community_follower_view.rs b/crates/db_views_actor/src/community_follower_view.rs index d3b11e4d2..379d70958 100644 --- a/crates/db_views_actor/src/community_follower_view.rs +++ b/crates/db_views_actor/src/community_follower_view.rs @@ -1,13 +1,12 @@ use diesel::{result::Error, *}; -use lemmy_db_queries::{ToSafe, ViewToVec}; use lemmy_db_schema::{ + newtypes::{CommunityId, PersonId}, schema::{community, community_follower, person}, source::{ community::{Community, CommunitySafe}, person::{Person, PersonSafe}, }, - CommunityId, - PersonId, + traits::{ToSafe, ViewToVec}, }; use serde::{Deserialize, Serialize}; diff --git a/crates/db_views_actor/src/community_moderator_view.rs b/crates/db_views_actor/src/community_moderator_view.rs index 071fc1075..1e48ad0ab 100644 --- a/crates/db_views_actor/src/community_moderator_view.rs +++ b/crates/db_views_actor/src/community_moderator_view.rs @@ -1,13 +1,12 @@ use diesel::{result::Error, *}; -use lemmy_db_queries::{ToSafe, ViewToVec}; use lemmy_db_schema::{ + newtypes::{CommunityId, PersonId}, schema::{community, community_moderator, person}, source::{ community::{Community, CommunitySafe}, person::{Person, PersonSafe}, }, - CommunityId, - PersonId, + traits::{ToSafe, ViewToVec}, }; use serde::{Deserialize, Serialize}; diff --git a/crates/db_views_actor/src/community_person_ban_view.rs b/crates/db_views_actor/src/community_person_ban_view.rs index b08549211..bffbacb12 100644 --- a/crates/db_views_actor/src/community_person_ban_view.rs +++ b/crates/db_views_actor/src/community_person_ban_view.rs @@ -1,13 +1,12 @@ use diesel::{result::Error, *}; -use lemmy_db_queries::ToSafe; use lemmy_db_schema::{ + newtypes::{CommunityId, PersonId}, schema::{community, community_person_ban, person}, source::{ community::{Community, CommunitySafe}, person::{Person, PersonSafe}, }, - CommunityId, - PersonId, + traits::ToSafe, }; use serde::{Deserialize, Serialize}; diff --git a/crates/db_views_actor/src/community_view.rs b/crates/db_views_actor/src/community_view.rs index 8ce3b7e6f..48270c25c 100644 --- a/crates/db_views_actor/src/community_view.rs +++ b/crates/db_views_actor/src/community_view.rs @@ -1,24 +1,19 @@ use crate::{community_moderator_view::CommunityModeratorView, person_view::PersonViewSafe}; use diesel::{result::Error, *}; -use lemmy_db_queries::{ +use lemmy_db_schema::{ aggregates::community_aggregates::CommunityAggregates, functions::hot_rank, fuzzy_search, limit_and_offset, - ListingType, - MaybeOptional, - SortType, - ToSafe, - ViewToVec, -}; -use lemmy_db_schema::{ + newtypes::{CommunityId, PersonId}, schema::{community, community_aggregates, community_block, community_follower}, source::{ community::{Community, CommunityFollower, CommunitySafe}, community_block::CommunityBlock, }, - CommunityId, - PersonId, + traits::{MaybeOptional, ToSafe, ViewToVec}, + ListingType, + SortType, }; use serde::{Deserialize, Serialize}; diff --git a/crates/db_views_actor/src/person_block_view.rs b/crates/db_views_actor/src/person_block_view.rs index d4a528603..2ca2077cb 100644 --- a/crates/db_views_actor/src/person_block_view.rs +++ b/crates/db_views_actor/src/person_block_view.rs @@ -1,9 +1,9 @@ use diesel::{result::Error, *}; -use lemmy_db_queries::{ToSafe, ViewToVec}; use lemmy_db_schema::{ + newtypes::PersonId, schema::{person, person_alias_1, person_block}, source::person::{Person, PersonAlias1, PersonSafe, PersonSafeAlias1}, - PersonId, + traits::{ToSafe, ViewToVec}, }; use serde::{Deserialize, Serialize}; diff --git a/crates/db_views_actor/src/person_mention_view.rs b/crates/db_views_actor/src/person_mention_view.rs index 1de01491f..5e6e3df3f 100644 --- a/crates/db_views_actor/src/person_mention_view.rs +++ b/crates/db_views_actor/src/person_mention_view.rs @@ -1,14 +1,9 @@ use diesel::{result::Error, *}; -use lemmy_db_queries::{ +use lemmy_db_schema::{ aggregates::comment_aggregates::CommentAggregates, functions::hot_rank, limit_and_offset, - MaybeOptional, - SortType, - ToSafe, - ViewToVec, -}; -use lemmy_db_schema::{ + newtypes::{PersonId, PersonMentionId}, schema::{ comment, comment_aggregates, @@ -31,8 +26,8 @@ use lemmy_db_schema::{ person_mention::PersonMention, post::Post, }, - PersonId, - PersonMentionId, + traits::{MaybeOptional, ToSafe, ViewToVec}, + SortType, }; use serde::{Deserialize, Serialize}; diff --git a/crates/db_views_actor/src/person_view.rs b/crates/db_views_actor/src/person_view.rs index 496ac672f..b6585196b 100644 --- a/crates/db_views_actor/src/person_view.rs +++ b/crates/db_views_actor/src/person_view.rs @@ -1,17 +1,13 @@ use diesel::{dsl::*, result::Error, *}; -use lemmy_db_queries::{ +use lemmy_db_schema::{ aggregates::person_aggregates::PersonAggregates, fuzzy_search, limit_and_offset, - MaybeOptional, - SortType, - ToSafe, - ViewToVec, -}; -use lemmy_db_schema::{ + newtypes::PersonId, schema::{person, person_aggregates}, source::person::{Person, PersonSafe}, - PersonId, + traits::{MaybeOptional, ToSafe, ViewToVec}, + SortType, }; use serde::{Deserialize, Serialize}; diff --git a/crates/db_views_moderator/Cargo.toml b/crates/db_views_moderator/Cargo.toml index 3511d07d3..3a0b707cf 100644 --- a/crates/db_views_moderator/Cargo.toml +++ b/crates/db_views_moderator/Cargo.toml @@ -11,7 +11,6 @@ documentation = "https://join-lemmy.org/docs/en/index.html" doctest = false [dependencies] -lemmy_db_queries = { version = "=0.13.0", path = "../db_queries" } lemmy_db_schema = { version = "=0.13.0", path = "../db_schema" } diesel = { version = "1.4.8", features = ["postgres","chrono","r2d2","serde_json"] } serde = { version = "1.0.130", features = ["derive"] } diff --git a/crates/db_views_moderator/src/mod_add_community_view.rs b/crates/db_views_moderator/src/mod_add_community_view.rs index f5fe8af11..b0d72d21a 100644 --- a/crates/db_views_moderator/src/mod_add_community_view.rs +++ b/crates/db_views_moderator/src/mod_add_community_view.rs @@ -1,14 +1,14 @@ use diesel::{result::Error, *}; -use lemmy_db_queries::{limit_and_offset, ToSafe, ViewToVec}; use lemmy_db_schema::{ + limit_and_offset, + newtypes::{CommunityId, PersonId}, schema::{community, mod_add_community, person, person_alias_1}, source::{ community::{Community, CommunitySafe}, moderator::ModAddCommunity, person::{Person, PersonAlias1, PersonSafe, PersonSafeAlias1}, }, - CommunityId, - PersonId, + traits::{ToSafe, ViewToVec}, }; use serde::{Deserialize, Serialize}; diff --git a/crates/db_views_moderator/src/mod_add_view.rs b/crates/db_views_moderator/src/mod_add_view.rs index 0ac915539..bd4e388b3 100644 --- a/crates/db_views_moderator/src/mod_add_view.rs +++ b/crates/db_views_moderator/src/mod_add_view.rs @@ -1,12 +1,13 @@ use diesel::{result::Error, *}; -use lemmy_db_queries::{limit_and_offset, ToSafe, ViewToVec}; use lemmy_db_schema::{ + limit_and_offset, + newtypes::PersonId, schema::{mod_add, person, person_alias_1}, source::{ moderator::ModAdd, person::{Person, PersonAlias1, PersonSafe, PersonSafeAlias1}, }, - PersonId, + traits::{ToSafe, ViewToVec}, }; use serde::{Deserialize, Serialize}; diff --git a/crates/db_views_moderator/src/mod_ban_from_community_view.rs b/crates/db_views_moderator/src/mod_ban_from_community_view.rs index d67f82dfe..a5a37cce1 100644 --- a/crates/db_views_moderator/src/mod_ban_from_community_view.rs +++ b/crates/db_views_moderator/src/mod_ban_from_community_view.rs @@ -1,14 +1,14 @@ use diesel::{result::Error, *}; -use lemmy_db_queries::{limit_and_offset, ToSafe, ViewToVec}; use lemmy_db_schema::{ + limit_and_offset, + newtypes::{CommunityId, PersonId}, schema::{community, mod_ban_from_community, person, person_alias_1}, source::{ community::{Community, CommunitySafe}, moderator::ModBanFromCommunity, person::{Person, PersonAlias1, PersonSafe, PersonSafeAlias1}, }, - CommunityId, - PersonId, + traits::{ToSafe, ViewToVec}, }; use serde::{Deserialize, Serialize}; diff --git a/crates/db_views_moderator/src/mod_ban_view.rs b/crates/db_views_moderator/src/mod_ban_view.rs index 79a199cb0..fabb56ca9 100644 --- a/crates/db_views_moderator/src/mod_ban_view.rs +++ b/crates/db_views_moderator/src/mod_ban_view.rs @@ -1,12 +1,13 @@ use diesel::{result::Error, *}; -use lemmy_db_queries::{limit_and_offset, ToSafe, ViewToVec}; use lemmy_db_schema::{ + limit_and_offset, + newtypes::PersonId, schema::{mod_ban, person, person_alias_1}, source::{ moderator::ModBan, person::{Person, PersonAlias1, PersonSafe, PersonSafeAlias1}, }, - PersonId, + traits::{ToSafe, ViewToVec}, }; use serde::{Deserialize, Serialize}; diff --git a/crates/db_views_moderator/src/mod_lock_post_view.rs b/crates/db_views_moderator/src/mod_lock_post_view.rs index 8774bfbd4..5ec355791 100644 --- a/crates/db_views_moderator/src/mod_lock_post_view.rs +++ b/crates/db_views_moderator/src/mod_lock_post_view.rs @@ -1,6 +1,7 @@ use diesel::{result::Error, *}; -use lemmy_db_queries::{limit_and_offset, ToSafe, ViewToVec}; use lemmy_db_schema::{ + limit_and_offset, + newtypes::{CommunityId, PersonId}, schema::{community, mod_lock_post, person, post}, source::{ community::{Community, CommunitySafe}, @@ -8,8 +9,7 @@ use lemmy_db_schema::{ person::{Person, PersonSafe}, post::Post, }, - CommunityId, - PersonId, + traits::{ToSafe, ViewToVec}, }; use serde::{Deserialize, Serialize}; diff --git a/crates/db_views_moderator/src/mod_remove_comment_view.rs b/crates/db_views_moderator/src/mod_remove_comment_view.rs index 9cf9862e1..abb88020a 100644 --- a/crates/db_views_moderator/src/mod_remove_comment_view.rs +++ b/crates/db_views_moderator/src/mod_remove_comment_view.rs @@ -1,6 +1,7 @@ use diesel::{result::Error, *}; -use lemmy_db_queries::{limit_and_offset, ToSafe, ViewToVec}; use lemmy_db_schema::{ + limit_and_offset, + newtypes::{CommunityId, PersonId}, schema::{comment, community, mod_remove_comment, person, person_alias_1, post}, source::{ comment::Comment, @@ -9,8 +10,7 @@ use lemmy_db_schema::{ person::{Person, PersonAlias1, PersonSafe, PersonSafeAlias1}, post::Post, }, - CommunityId, - PersonId, + traits::{ToSafe, ViewToVec}, }; use serde::{Deserialize, Serialize}; diff --git a/crates/db_views_moderator/src/mod_remove_community_view.rs b/crates/db_views_moderator/src/mod_remove_community_view.rs index 7196aec6b..6634b2ff8 100644 --- a/crates/db_views_moderator/src/mod_remove_community_view.rs +++ b/crates/db_views_moderator/src/mod_remove_community_view.rs @@ -1,13 +1,14 @@ use diesel::{result::Error, *}; -use lemmy_db_queries::{limit_and_offset, ToSafe, ViewToVec}; use lemmy_db_schema::{ + limit_and_offset, + newtypes::PersonId, schema::{community, mod_remove_community, person}, source::{ community::{Community, CommunitySafe}, moderator::ModRemoveCommunity, person::{Person, PersonSafe}, }, - PersonId, + traits::{ToSafe, ViewToVec}, }; use serde::{Deserialize, Serialize}; diff --git a/crates/db_views_moderator/src/mod_remove_post_view.rs b/crates/db_views_moderator/src/mod_remove_post_view.rs index d83f95b46..c92191610 100644 --- a/crates/db_views_moderator/src/mod_remove_post_view.rs +++ b/crates/db_views_moderator/src/mod_remove_post_view.rs @@ -1,6 +1,7 @@ use diesel::{result::Error, *}; -use lemmy_db_queries::{limit_and_offset, ToSafe, ViewToVec}; use lemmy_db_schema::{ + limit_and_offset, + newtypes::{CommunityId, PersonId}, schema::{community, mod_remove_post, person, post}, source::{ community::{Community, CommunitySafe}, @@ -8,8 +9,7 @@ use lemmy_db_schema::{ person::{Person, PersonSafe}, post::Post, }, - CommunityId, - PersonId, + traits::{ToSafe, ViewToVec}, }; use serde::{Deserialize, Serialize}; diff --git a/crates/db_views_moderator/src/mod_sticky_post_view.rs b/crates/db_views_moderator/src/mod_sticky_post_view.rs index f1dfcb144..55593e4fc 100644 --- a/crates/db_views_moderator/src/mod_sticky_post_view.rs +++ b/crates/db_views_moderator/src/mod_sticky_post_view.rs @@ -1,6 +1,7 @@ use diesel::{result::Error, *}; -use lemmy_db_queries::{limit_and_offset, ToSafe, ViewToVec}; use lemmy_db_schema::{ + limit_and_offset, + newtypes::{CommunityId, PersonId}, schema::{community, mod_sticky_post, person, post}, source::{ community::{Community, CommunitySafe}, @@ -8,8 +9,7 @@ use lemmy_db_schema::{ person::{Person, PersonSafe}, post::Post, }, - CommunityId, - PersonId, + traits::{ToSafe, ViewToVec}, }; use serde::{Deserialize, Serialize}; diff --git a/crates/db_views_moderator/src/mod_transfer_community_view.rs b/crates/db_views_moderator/src/mod_transfer_community_view.rs index 9fcc481be..2fbacbb83 100644 --- a/crates/db_views_moderator/src/mod_transfer_community_view.rs +++ b/crates/db_views_moderator/src/mod_transfer_community_view.rs @@ -1,14 +1,14 @@ use diesel::{result::Error, *}; -use lemmy_db_queries::{limit_and_offset, ToSafe, ViewToVec}; use lemmy_db_schema::{ + limit_and_offset, + newtypes::{CommunityId, PersonId}, schema::{community, mod_transfer_community, person, person_alias_1}, source::{ community::{Community, CommunitySafe}, moderator::ModTransferCommunity, person::{Person, PersonAlias1, PersonSafe, PersonSafeAlias1}, }, - CommunityId, - PersonId, + traits::{ToSafe, ViewToVec}, }; use serde::{Deserialize, Serialize}; diff --git a/crates/routes/Cargo.toml b/crates/routes/Cargo.toml index dfa8c9482..65dcb8cda 100644 --- a/crates/routes/Cargo.toml +++ b/crates/routes/Cargo.toml @@ -13,7 +13,6 @@ doctest = false [dependencies] lemmy_utils = { version = "=0.13.0", path = "../utils" } lemmy_websocket = { version = "=0.13.0", path = "../websocket" } -lemmy_db_queries = { version = "=0.13.0", path = "../db_queries" } lemmy_db_views = { version = "=0.13.0", path = "../db_views" } lemmy_db_views_actor = { version = "=0.13.0", path = "../db_views_actor" } lemmy_db_schema = { version = "=0.13.0", path = "../db_schema" } diff --git a/crates/routes/src/feeds.rs b/crates/routes/src/feeds.rs index a02b5fe33..1a85a10ac 100644 --- a/crates/routes/src/feeds.rs +++ b/crates/routes/src/feeds.rs @@ -3,16 +3,13 @@ use anyhow::anyhow; use chrono::{DateTime, NaiveDateTime, Utc}; use diesel::PgConnection; use lemmy_api_common::blocking; -use lemmy_db_queries::{ - source::{community::Community_, person::Person_}, - Crud, +use lemmy_db_schema::{ + newtypes::LocalUserId, + source::{community::Community, local_user::LocalUser, person::Person}, + traits::Crud, ListingType, SortType, }; -use lemmy_db_schema::{ - source::{community::Community, local_user::LocalUser, person::Person}, - LocalUserId, -}; use lemmy_db_views::{ comment_view::{CommentQueryBuilder, CommentView}, post_view::{PostQueryBuilder, PostView}, diff --git a/crates/routes/src/webfinger.rs b/crates/routes/src/webfinger.rs index 798636da5..ef0afd990 100644 --- a/crates/routes/src/webfinger.rs +++ b/crates/routes/src/webfinger.rs @@ -2,7 +2,6 @@ use actix_web::{error::ErrorBadRequest, web::Query, *}; use anyhow::anyhow; use lemmy_api_common::blocking; use lemmy_apub_lib::webfinger::{WebfingerLink, WebfingerResponse}; -use lemmy_db_queries::source::{community::Community_, person::Person_}; use lemmy_db_schema::source::{community::Community, person::Person}; use lemmy_utils::{settings::structs::Settings, LemmyError}; use lemmy_websocket::LemmyContext; diff --git a/crates/utils/src/settings/mod.rs b/crates/utils/src/settings/mod.rs index 6678b91f5..40dd91664 100644 --- a/crates/utils/src/settings/mod.rs +++ b/crates/utils/src/settings/mod.rs @@ -27,7 +27,7 @@ impl Settings { /// Reads config from configuration file. /// /// Note: The env var `LEMMY_DATABASE_URL` is parsed in - /// `lemmy_db_queries/src/lib.rs::get_database_url_from_env()` + /// `lemmy_db_schema/src/lib.rs::get_database_url_from_env()` /// Warning: Only call this once. pub fn init() -> Result { // Read the config file diff --git a/crates/websocket/Cargo.toml b/crates/websocket/Cargo.toml index cab4da439..c7d5f3a60 100644 --- a/crates/websocket/Cargo.toml +++ b/crates/websocket/Cargo.toml @@ -15,7 +15,6 @@ doctest = false [dependencies] lemmy_utils = { version = "=0.13.0", path = "../utils" } lemmy_api_common = { version = "=0.13.0", path = "../api_common" } -lemmy_db_queries = { version = "=0.13.0", path = "../db_queries" } lemmy_db_schema = { version = "=0.13.0", path = "../db_schema" } lemmy_db_views = { version = "=0.13.0", path = "../db_views" } lemmy_db_views_actor = { version = "=0.13.0", path = "../db_views_actor" } diff --git a/crates/websocket/src/chat_server.rs b/crates/websocket/src/chat_server.rs index db09ac95e..3e17b6262 100644 --- a/crates/websocket/src/chat_server.rs +++ b/crates/websocket/src/chat_server.rs @@ -14,7 +14,10 @@ use diesel::{ PgConnection, }; use lemmy_api_common::{comment::*, post::*}; -use lemmy_db_schema::{source::secret::Secret, CommunityId, LocalUserId, PostId}; +use lemmy_db_schema::{ + newtypes::{CommunityId, LocalUserId, PostId}, + source::secret::Secret, +}; use lemmy_utils::{ location_info, rate_limit::RateLimit, diff --git a/crates/websocket/src/lib.rs b/crates/websocket/src/lib.rs index e9f488741..fbf9d25a3 100644 --- a/crates/websocket/src/lib.rs +++ b/crates/websocket/src/lib.rs @@ -4,8 +4,7 @@ extern crate strum_macros; use crate::chat_server::ChatServer; use actix::Addr; use background_jobs::QueueHandle; -use lemmy_db_queries::DbPool; -use lemmy_db_schema::source::secret::Secret; +use lemmy_db_schema::{source::secret::Secret, DbPool}; use lemmy_utils::{settings::structs::Settings, LemmyError}; use reqwest::Client; use serde::Serialize; diff --git a/crates/websocket/src/messages.rs b/crates/websocket/src/messages.rs index 3c16ec273..4192b5402 100644 --- a/crates/websocket/src/messages.rs +++ b/crates/websocket/src/messages.rs @@ -1,7 +1,7 @@ use crate::UserOperation; use actix::{prelude::*, Recipient}; use lemmy_api_common::{comment::CommentResponse, post::PostResponse}; -use lemmy_db_schema::{CommunityId, LocalUserId, PostId}; +use lemmy_db_schema::newtypes::{CommunityId, LocalUserId, PostId}; use lemmy_utils::{ConnectionId, IpAddr}; use serde::{Deserialize, Serialize}; diff --git a/crates/websocket/src/send.rs b/crates/websocket/src/send.rs index a49759d63..5982e24ce 100644 --- a/crates/websocket/src/send.rs +++ b/crates/websocket/src/send.rs @@ -10,8 +10,10 @@ use lemmy_api_common::{ person::PrivateMessageResponse, post::PostResponse, }; -use lemmy_db_queries::DeleteableOrRemoveable; -use lemmy_db_schema::{CommentId, CommunityId, LocalUserId, PersonId, PostId, PrivateMessageId}; +use lemmy_db_schema::{ + newtypes::{CommentId, CommunityId, LocalUserId, PersonId, PostId, PrivateMessageId}, + traits::DeleteableOrRemoveable, +}; use lemmy_db_views::{ comment_view::CommentView, local_user_view::LocalUserView, diff --git a/docker/dev/docker-compose.yml b/docker/dev/docker-compose.yml index 2474c74d6..e1ea333ad 100644 --- a/docker/dev/docker-compose.yml +++ b/docker/dev/docker-compose.yml @@ -18,7 +18,7 @@ services: - "8536:8536" restart: always environment: - - RUST_LOG="warn,lemmy_server=debug,lemmy_api=debug,lemmy_api_common=debug,lemmy_api_crud=debug,lemmy_apub=debug,lemmy_db_queries=debug,lemmy_db_schema=debug,lemmy_db_views=debug,lemmy_db_views_actor=debug,lemmy_db_views_moderator=debug,lemmy_routes=debug,lemmy_utils=debug,lemmy_websocket=debug" + - RUST_LOG="warn,lemmy_server=debug,lemmy_api=debug,lemmy_api_common=debug,lemmy_api_crud=debug,lemmy_apub=debug,lemmy_db_schema=debug,lemmy_db_views=debug,lemmy_db_views_actor=debug,lemmy_db_views_moderator=debug,lemmy_routes=debug,lemmy_utils=debug,lemmy_websocket=debug" volumes: - ../lemmy.hjson:/config/config.hjson depends_on: diff --git a/docker/federation/docker-compose.yml b/docker/federation/docker-compose.yml index 55b3877cc..3a8447c1a 100644 --- a/docker/federation/docker-compose.yml +++ b/docker/federation/docker-compose.yml @@ -42,7 +42,7 @@ services: environment: - APUB_TESTING_SEND_SYNC - RUST_BACKTRACE=1 - - RUST_LOG="warn,lemmy_server=debug,lemmy_api=debug,lemmy_api_common=debug,lemmy_api_crud=debug,lemmy_apub=debug,lemmy_db_queries=debug,lemmy_db_schema=debug,lemmy_db_views=debug,lemmy_db_views_actor=debug,lemmy_db_views_moderator=debug,lemmy_routes=debug,lemmy_utils=debug,lemmy_websocket=debug" + - RUST_LOG="warn,lemmy_server=debug,lemmy_api=debug,lemmy_api_common=debug,lemmy_api_crud=debug,lemmy_apub=debug,lemmy_db_schema=debug,lemmy_db_views=debug,lemmy_db_views_actor=debug,lemmy_db_views_moderator=debug,lemmy_routes=debug,lemmy_utils=debug,lemmy_websocket=debug" depends_on: - postgres_alpha ports: @@ -71,7 +71,7 @@ services: environment: - APUB_TESTING_SEND_SYNC - RUST_BACKTRACE=1 - - RUST_LOG="warn,lemmy_server=debug,lemmy_api=debug,lemmy_api_common=debug,lemmy_api_crud=debug,lemmy_apub=debug,lemmy_db_queries=debug,lemmy_db_schema=debug,lemmy_db_views=debug,lemmy_db_views_actor=debug,lemmy_db_views_moderator=debug,lemmy_routes=debug,lemmy_utils=debug,lemmy_websocket=debug" + - RUST_LOG="warn,lemmy_server=debug,lemmy_api=debug,lemmy_api_common=debug,lemmy_api_crud=debug,lemmy_apub=debug,lemmy_db_schema=debug,lemmy_db_views=debug,lemmy_db_views_actor=debug,lemmy_db_views_moderator=debug,lemmy_routes=debug,lemmy_utils=debug,lemmy_websocket=debug" depends_on: - postgres_beta ports: @@ -100,7 +100,7 @@ services: environment: - APUB_TESTING_SEND_SYNC - RUST_BACKTRACE=1 - - RUST_LOG="warn,lemmy_server=debug,lemmy_api=debug,lemmy_api_common=debug,lemmy_api_crud=debug,lemmy_apub=debug,lemmy_db_queries=debug,lemmy_db_schema=debug,lemmy_db_views=debug,lemmy_db_views_actor=debug,lemmy_db_views_moderator=debug,lemmy_routes=debug,lemmy_utils=debug,lemmy_websocket=debug" + - RUST_LOG="warn,lemmy_server=debug,lemmy_api=debug,lemmy_api_common=debug,lemmy_api_crud=debug,lemmy_apub=debug,lemmy_db_schema=debug,lemmy_db_views=debug,lemmy_db_views_actor=debug,lemmy_db_views_moderator=debug,lemmy_routes=debug,lemmy_utils=debug,lemmy_websocket=debug" depends_on: - postgres_gamma ports: @@ -130,7 +130,7 @@ services: environment: - APUB_TESTING_SEND_SYNC - RUST_BACKTRACE=1 - - RUST_LOG="warn,lemmy_server=debug,lemmy_api=debug,lemmy_api_common=debug,lemmy_api_crud=debug,lemmy_apub=debug,lemmy_db_queries=debug,lemmy_db_schema=debug,lemmy_db_views=debug,lemmy_db_views_actor=debug,lemmy_db_views_moderator=debug,lemmy_routes=debug,lemmy_utils=debug,lemmy_websocket=debug" + - RUST_LOG="warn,lemmy_server=debug,lemmy_api=debug,lemmy_api_common=debug,lemmy_api_crud=debug,lemmy_apub=debug,lemmy_db_schema=debug,lemmy_db_views=debug,lemmy_db_views_actor=debug,lemmy_db_views_moderator=debug,lemmy_routes=debug,lemmy_utils=debug,lemmy_websocket=debug" depends_on: - postgres_delta ports: @@ -160,7 +160,7 @@ services: environment: - APUB_TESTING_SEND_SYNC - RUST_BACKTRACE=1 - - RUST_LOG="warn,lemmy_server=debug,lemmy_api=debug,lemmy_api_common=debug,lemmy_api_crud=debug,lemmy_apub=debug,lemmy_db_queries=debug,lemmy_db_schema=debug,lemmy_db_views=debug,lemmy_db_views_actor=debug,lemmy_db_views_moderator=debug,lemmy_routes=debug,lemmy_utils=debug,lemmy_websocket=debug" + - RUST_LOG="warn,lemmy_server=debug,lemmy_api=debug,lemmy_api_common=debug,lemmy_api_crud=debug,lemmy_apub=debug,lemmy_db_schema=debug,lemmy_db_views=debug,lemmy_db_views_actor=debug,lemmy_db_views_moderator=debug,lemmy_routes=debug,lemmy_utils=debug,lemmy_websocket=debug" depends_on: - postgres_epsilon ports: diff --git a/docker/prod/docker-compose.yml b/docker/prod/docker-compose.yml index a9d7e613f..2b39ab18a 100644 --- a/docker/prod/docker-compose.yml +++ b/docker/prod/docker-compose.yml @@ -17,7 +17,7 @@ services: - "127.0.0.1:8536:8536" restart: always environment: - - RUST_LOG="warn,lemmy_server=info,lemmy_api=info,lemmy_api_common=info,lemmy_api_crud=info,lemmy_apub=info,lemmy_db_queries=info,lemmy_db_schema=info,lemmy_db_views=info,lemmy_db_views_actor=info,lemmy_db_views_moderator=info,lemmy_routes=info,lemmy_utils=info,lemmy_websocket=info" + - RUST_LOG="warn,lemmy_server=info,lemmy_api=info,lemmy_api_common=info,lemmy_api_crud=info,lemmy_apub=info,lemmy_db_schema=info,lemmy_db_views=info,lemmy_db_views_actor=info,lemmy_db_views_moderator=info,lemmy_routes=info,lemmy_utils=info,lemmy_websocket=info" volumes: - ./lemmy.hjson:/config/config.hjson depends_on: diff --git a/src/code_migrations.rs b/src/code_migrations.rs index 1f9381986..8910733a5 100644 --- a/src/code_migrations.rs +++ b/src/code_migrations.rs @@ -10,10 +10,6 @@ use lemmy_apub::{ generate_shared_inbox_url, EndpointType, }; -use lemmy_db_queries::{ - source::{comment::Comment_, post::Post_, private_message::PrivateMessage_}, - Crud, -}; use lemmy_db_schema::{ naive_now, source::{ @@ -23,6 +19,7 @@ use lemmy_db_schema::{ post::Post, private_message::PrivateMessage, }, + traits::Crud, }; use lemmy_utils::{apub::generate_actor_keypair, LemmyError}; use log::info; diff --git a/src/main.rs b/src/main.rs index 483b17415..c078e7860 100644 --- a/src/main.rs +++ b/src/main.rs @@ -12,8 +12,7 @@ use lemmy_api::match_websocket_operation; use lemmy_api_common::blocking; use lemmy_api_crud::match_websocket_operation_crud; use lemmy_apub_lib::activity_queue::create_activity_queue; -use lemmy_db_queries::{get_database_url_from_env, source::secret::Secret_}; -use lemmy_db_schema::source::secret::Secret; +use lemmy_db_schema::{get_database_url_from_env, source::secret::Secret}; use lemmy_routes::{feeds, images, nodeinfo, webfinger}; use lemmy_server::{api_routes, code_migrations::run_advanced_migrations, scheduled_tasks}; use lemmy_utils::{ diff --git a/src/scheduled_tasks.rs b/src/scheduled_tasks.rs index 5c406ff6d..396c7b675 100644 --- a/src/scheduled_tasks.rs +++ b/src/scheduled_tasks.rs @@ -2,8 +2,7 @@ use clokwerk::{Scheduler, TimeUnits}; // Import week days and WeekDay use diesel::{sql_query, PgConnection, RunQueryDsl}; -use lemmy_db_queries::{source::activity::Activity_, DbPool}; -use lemmy_db_schema::source::activity::Activity; +use lemmy_db_schema::{source::activity::Activity, DbPool}; use log::info; use std::{thread, time::Duration}; From 1aa0e1997bd8e3c9a4849c485bdddb804f19692e Mon Sep 17 00:00:00 2001 From: Felix Ableitner Date: Mon, 18 Oct 2021 23:36:44 +0200 Subject: [PATCH 3/3] Major refactor, adding newtypes for apub crate - this allows moving FromApub/ToApub traits into apub lib --- Cargo.lock | 1 - crates/api/src/comment.rs | 6 +- crates/api/src/comment_report.rs | 4 +- crates/api/src/community.rs | 77 +++++--- crates/api/src/post.rs | 23 ++- crates/api/src/post_report.rs | 4 +- crates/api_common/src/lib.rs | 168 +----------------- crates/api_crud/src/comment/create.rs | 24 +-- crates/api_crud/src/comment/delete.rs | 33 ++-- crates/api_crud/src/comment/update.rs | 20 ++- crates/api_crud/src/community/create.rs | 3 +- crates/api_crud/src/community/delete.rs | 8 +- crates/api_crud/src/community/read.rs | 10 +- crates/api_crud/src/community/update.rs | 7 +- crates/api_crud/src/post/create.rs | 8 +- crates/api_crud/src/post/delete.rs | 8 +- crates/api_crud/src/post/update.rs | 4 +- crates/api_crud/src/private_message/create.rs | 11 +- crates/api_crud/src/private_message/delete.rs | 14 +- crates/api_crud/src/private_message/update.rs | 4 +- crates/api_crud/src/user/read.rs | 11 +- .../activities/comment/create_or_update.rs | 23 ++- crates/apub/src/activities/comment/mod.rs | 42 +++-- .../apub/src/activities/community/add_mod.rs | 20 +-- .../apub/src/activities/community/announce.rs | 6 +- .../src/activities/community/block_user.rs | 35 ++-- crates/apub/src/activities/community/mod.rs | 6 +- .../src/activities/community/remove_mod.rs | 20 +-- .../activities/community/undo_block_user.rs | 18 +- .../apub/src/activities/community/update.rs | 22 +-- crates/apub/src/activities/deletion/delete.rs | 16 +- crates/apub/src/activities/deletion/mod.rs | 54 ++---- .../src/activities/deletion/undo_delete.rs | 11 +- .../apub/src/activities/following/accept.rs | 15 +- .../apub/src/activities/following/follow.rs | 20 +-- crates/apub/src/activities/following/undo.rs | 14 +- crates/apub/src/activities/mod.rs | 22 +-- .../src/activities/post/create_or_update.rs | 31 ++-- .../private_message/create_or_update.rs | 29 +-- .../src/activities/private_message/delete.rs | 19 +- .../activities/private_message/undo_delete.rs | 15 +- crates/apub/src/activities/report.rs | 27 ++- crates/apub/src/activities/undo_remove.rs | 6 +- crates/apub/src/activities/voting/mod.rs | 26 +-- .../apub/src/activities/voting/undo_vote.rs | 18 +- crates/apub/src/activities/voting/vote.rs | 20 +-- crates/apub/src/fetcher/community.rs | 9 +- crates/apub/src/fetcher/mod.rs | 14 +- crates/apub/src/fetcher/object_id.rs | 32 ++-- crates/apub/src/fetcher/post_or_comment.rs | 41 +++-- crates/apub/src/fetcher/search.rs | 65 ++++--- crates/apub/src/http/comment.rs | 7 +- crates/apub/src/http/community.rs | 14 +- crates/apub/src/http/person.rs | 9 +- crates/apub/src/http/post.rs | 7 +- crates/apub/src/objects/comment.rs | 77 ++++++-- crates/apub/src/objects/community.rs | 89 +++++++++- crates/apub/src/objects/mod.rs | 39 +--- crates/apub/src/objects/person.rs | 93 +++++++++- crates/apub/src/objects/post.rs | 69 ++++++- crates/apub/src/objects/private_message.rs | 72 ++++++-- crates/apub_lib/src/traits.rs | 40 ++++- crates/db_schema/Cargo.toml | 1 - crates/db_schema/src/impls/comment.rs | 33 ++-- crates/db_schema/src/impls/community.rs | 67 ++----- crates/db_schema/src/impls/person.rs | 59 ++---- crates/db_schema/src/impls/post.rs | 36 ++-- crates/db_schema/src/impls/private_message.rs | 41 ++--- crates/websocket/src/send.rs | 163 ++++++++++++++++- 69 files changed, 1156 insertions(+), 904 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 06361214f..120f68278 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1839,7 +1839,6 @@ dependencies = [ "diesel-derive-newtype", "diesel_migrations", "lazy_static", - "lemmy_apub_lib", "lemmy_utils", "log", "regex", diff --git a/crates/api/src/comment.rs b/crates/api/src/comment.rs index d626c2eae..62b01b33f 100644 --- a/crates/api/src/comment.rs +++ b/crates/api/src/comment.rs @@ -191,7 +191,7 @@ impl Perform for CreateCommentLike { // Only add the like if the score isnt 0 let comment = orig_comment.comment; - let object = PostOrComment::Comment(comment); + let object = PostOrComment::Comment(comment.into()); let do_add = like_form.score != 0 && (like_form.score == 1 || like_form.score == -1); if do_add { let like_form2 = like_form.clone(); @@ -202,7 +202,7 @@ impl Perform for CreateCommentLike { Vote::send( &object, - &local_user_view.person, + &local_user_view.person.clone().into(), orig_comment.community.id, like_form.score.try_into()?, context, @@ -212,7 +212,7 @@ impl Perform for CreateCommentLike { // API doesn't distinguish between Undo/Like and Undo/Dislike UndoVote::send( &object, - &local_user_view.person, + &local_user_view.person.clone().into(), orig_comment.community.id, VoteType::Like, context, diff --git a/crates/api/src/comment_report.rs b/crates/api/src/comment_report.rs index 86f636a6b..a7299b7ae 100644 --- a/crates/api/src/comment_report.rs +++ b/crates/api/src/comment_report.rs @@ -79,8 +79,8 @@ impl Perform for CreateCommentReport { Report::send( ObjectId::new(comment_view.comment.ap_id), - &local_user_view.person, - comment_view.community.id, + &local_user_view.person.into(), + ObjectId::new(comment_view.community.actor_id), reason.to_string(), context, ) diff --git a/crates/api/src/community.rs b/crates/api/src/community.rs index 5d7317b2a..ac39751c8 100644 --- a/crates/api/src/community.rs +++ b/crates/api/src/community.rs @@ -9,14 +9,17 @@ use lemmy_api_common::{ get_local_user_view_from_jwt, is_mod_or_admin, }; -use lemmy_apub::activities::{ - community::{ - add_mod::AddMod, - block_user::BlockUserFromCommunity, - remove_mod::RemoveMod, - undo_block_user::UndoBlockUserFromCommunity, +use lemmy_apub::{ + activities::{ + community::{ + add_mod::AddMod, + block_user::BlockUserFromCommunity, + remove_mod::RemoveMod, + undo_block_user::UndoBlockUserFromCommunity, + }, + following::{follow::FollowCommunity as FollowCommunityApub, undo::UndoFollowCommunity}, }, - following::{follow::FollowCommunity as FollowCommunityApub, undo::UndoFollowCommunity}, + objects::{community::ApubCommunity, person::ApubPerson}, }; use lemmy_db_schema::{ source::{ @@ -68,10 +71,11 @@ impl Perform for FollowCommunity { get_local_user_view_from_jwt(&data.auth, context.pool(), context.secret()).await?; let community_id = data.community_id; - let community = blocking(context.pool(), move |conn| { + let community: ApubCommunity = blocking(context.pool(), move |conn| { Community::read(conn, community_id) }) - .await??; + .await?? + .into(); let community_follower_form = CommunityFollowerForm { community_id: data.community_id, person_id: local_user_view.person.id, @@ -97,9 +101,11 @@ impl Perform for FollowCommunity { } else if data.follow { // Dont actually add to the community followers here, because you need // to wait for the accept - FollowCommunityApub::send(&local_user_view.person, &community, context).await?; + FollowCommunityApub::send(&local_user_view.person.clone().into(), &community, context) + .await?; } else { - UndoFollowCommunity::send(&local_user_view.person, &community, context).await?; + UndoFollowCommunity::send(&local_user_view.person.clone().into(), &community, context) + .await?; let unfollow = move |conn: &'_ _| CommunityFollower::unfollow(conn, &community_follower_form); blocking(context.pool(), unfollow) .await? @@ -165,7 +171,7 @@ impl Perform for BlockCommunity { Community::read(conn, community_id) }) .await??; - UndoFollowCommunity::send(&local_user_view.person, &community, context).await?; + UndoFollowCommunity::send(&local_user_view.person.into(), &community.into(), context).await?; } else { let unblock = move |conn: &'_ _| CommunityBlock::unblock(conn, &community_block_form); blocking(context.pool(), unblock) @@ -209,14 +215,16 @@ impl Perform for BanFromCommunity { person_id: data.person_id, }; - let community = blocking(context.pool(), move |conn: &'_ _| { + let community: ApubCommunity = blocking(context.pool(), move |conn: &'_ _| { Community::read(conn, community_id) }) - .await??; - let banned_person = blocking(context.pool(), move |conn: &'_ _| { + .await?? + .into(); + let banned_person: ApubPerson = blocking(context.pool(), move |conn: &'_ _| { Person::read(conn, banned_person_id) }) - .await??; + .await?? + .into(); if data.ban { let ban = move |conn: &'_ _| CommunityPersonBan::ban(conn, &community_user_ban_form); @@ -236,8 +244,13 @@ impl Perform for BanFromCommunity { .await? .ok(); - BlockUserFromCommunity::send(&community, &banned_person, &local_user_view.person, context) - .await?; + BlockUserFromCommunity::send( + &community, + &banned_person, + &local_user_view.person.clone().into(), + context, + ) + .await?; } else { let unban = move |conn: &'_ _| CommunityPersonBan::unban(conn, &community_user_ban_form); blocking(context.pool(), unban) @@ -246,7 +259,7 @@ impl Perform for BanFromCommunity { UndoBlockUserFromCommunity::send( &community, &banned_person, - &local_user_view.person, + &local_user_view.person.clone().into(), context, ) .await?; @@ -368,18 +381,32 @@ impl Perform for AddModToCommunity { // Send to federated instances let updated_mod_id = data.person_id; - let updated_mod = blocking(context.pool(), move |conn| { + let updated_mod: ApubPerson = blocking(context.pool(), move |conn| { Person::read(conn, updated_mod_id) }) - .await??; - let community = blocking(context.pool(), move |conn| { + .await?? + .into(); + let community: ApubCommunity = blocking(context.pool(), move |conn| { Community::read(conn, community_id) }) - .await??; + .await?? + .into(); if data.added { - AddMod::send(&community, &updated_mod, &local_user_view.person, context).await?; + AddMod::send( + &community, + &updated_mod, + &local_user_view.person.into(), + context, + ) + .await?; } else { - RemoveMod::send(&community, &updated_mod, &local_user_view.person, context).await?; + RemoveMod::send( + &community, + &updated_mod, + &local_user_view.person.into(), + context, + ) + .await?; } // Note: in case a remote mod is added, this returns the old moderators list, it will only get diff --git a/crates/api/src/post.rs b/crates/api/src/post.rs index 60cdafb9a..488c8f590 100644 --- a/crates/api/src/post.rs +++ b/crates/api/src/post.rs @@ -21,6 +21,7 @@ use lemmy_apub::{ CreateOrUpdateType, }, fetcher::post_or_comment::PostOrComment, + objects::post::ApubPost, }; use lemmy_db_schema::{ source::{moderator::*, post::*}, @@ -49,7 +50,9 @@ impl Perform for CreatePostLike { // Check for a community ban let post_id = data.post_id; - let post = blocking(context.pool(), move |conn| Post::read(conn, post_id)).await??; + let post: ApubPost = blocking(context.pool(), move |conn| Post::read(conn, post_id)) + .await?? + .into(); check_community_ban(local_user_view.person.id, post.community_id, context.pool()).await?; check_community_deleted_or_removed(post.community_id, context.pool()).await?; @@ -83,7 +86,7 @@ impl Perform for CreatePostLike { Vote::send( &object, - &local_user_view.person, + &local_user_view.person.clone().into(), community_id, like_form.score.try_into()?, context, @@ -93,7 +96,7 @@ impl Perform for CreatePostLike { // API doesn't distinguish between Undo/Like and Undo/Dislike UndoVote::send( &object, - &local_user_view.person, + &local_user_view.person.clone().into(), community_id, VoteType::Like, context, @@ -150,10 +153,11 @@ impl Perform for LockPost { // Update the post let post_id = data.post_id; let locked = data.locked; - let updated_post = blocking(context.pool(), move |conn| { + let updated_post: ApubPost = blocking(context.pool(), move |conn| { Post::update_locked(conn, post_id, locked) }) - .await??; + .await?? + .into(); // Mod tables let form = ModLockPostForm { @@ -166,7 +170,7 @@ impl Perform for LockPost { // apub updates CreateOrUpdatePost::send( &updated_post, - &local_user_view.person, + &local_user_view.person.clone().into(), CreateOrUpdateType::Update, context, ) @@ -218,10 +222,11 @@ impl Perform for StickyPost { // Update the post let post_id = data.post_id; let stickied = data.stickied; - let updated_post = blocking(context.pool(), move |conn| { + let updated_post: ApubPost = blocking(context.pool(), move |conn| { Post::update_stickied(conn, post_id, stickied) }) - .await??; + .await?? + .into(); // Mod tables let form = ModStickyPostForm { @@ -238,7 +243,7 @@ impl Perform for StickyPost { // TODO stickied should pry work like locked for ease of use CreateOrUpdatePost::send( &updated_post, - &local_user_view.person, + &local_user_view.person.clone().into(), CreateOrUpdateType::Update, context, ) diff --git a/crates/api/src/post_report.rs b/crates/api/src/post_report.rs index 35a734d44..3e610bff8 100644 --- a/crates/api/src/post_report.rs +++ b/crates/api/src/post_report.rs @@ -88,8 +88,8 @@ impl Perform for CreatePostReport { Report::send( ObjectId::new(post_view.post.ap_id), - &local_user_view.person, - post_view.community.id, + &local_user_view.person.into(), + ObjectId::new(post_view.community.actor_id), reason.to_string(), context, ) diff --git a/crates/api_common/src/lib.rs b/crates/api_common/src/lib.rs index f28c34b01..bf6246a0d 100644 --- a/crates/api_common/src/lib.rs +++ b/crates/api_common/src/lib.rs @@ -6,15 +6,11 @@ pub mod site; pub mod websocket; use crate::site::FederatedInstances; -use diesel::PgConnection; use lemmy_db_schema::{ newtypes::{CommunityId, LocalUserId, PersonId, PostId}, source::{ - comment::Comment, community::Community, - person::Person, person_block::PersonBlock, - person_mention::{PersonMention, PersonMentionForm}, post::{Post, PostRead, PostReadForm}, secret::Secret, site::Site, @@ -27,15 +23,7 @@ use lemmy_db_views_actor::{ community_person_ban_view::CommunityPersonBanView, community_view::CommunityView, }; -use lemmy_utils::{ - claims::Claims, - email::send_email, - settings::structs::{FederationConfig, Settings}, - utils::MentionData, - ApiError, - LemmyError, -}; -use log::error; +use lemmy_utils::{claims::Claims, settings::structs::FederationConfig, ApiError, LemmyError}; use url::Url; pub async fn blocking(pool: &DbPool, f: F) -> Result @@ -54,160 +42,6 @@ where res } -pub async fn send_local_notifs( - mentions: Vec, - comment: Comment, - person: Person, - post: Post, - pool: &DbPool, - do_send_email: bool, - settings: &Settings, -) -> Result, LemmyError> { - let settings = settings.to_owned(); - let ids = blocking(pool, move |conn| { - do_send_local_notifs( - conn, - &mentions, - &comment, - &person, - &post, - do_send_email, - &settings, - ) - }) - .await?; - - Ok(ids) -} - -fn do_send_local_notifs( - conn: &PgConnection, - mentions: &[MentionData], - comment: &Comment, - person: &Person, - post: &Post, - do_send_email: bool, - settings: &Settings, -) -> Vec { - let mut recipient_ids = Vec::new(); - - // Send the local mentions - for mention in mentions - .iter() - .filter(|m| m.is_local(&settings.hostname) && m.name.ne(&person.name)) - .collect::>() - { - if let Ok(mention_user_view) = LocalUserView::read_from_name(conn, &mention.name) { - // TODO - // At some point, make it so you can't tag the parent creator either - // This can cause two notifications, one for reply and the other for mention - recipient_ids.push(mention_user_view.local_user.id); - - let user_mention_form = PersonMentionForm { - recipient_id: mention_user_view.person.id, - comment_id: comment.id, - read: None, - }; - - // Allow this to fail softly, since comment edits might re-update or replace it - // Let the uniqueness handle this fail - PersonMention::create(conn, &user_mention_form).ok(); - - // Send an email to those local users that have notifications on - if do_send_email { - send_email_to_user( - &mention_user_view, - "Mentioned by", - "Person Mention", - &comment.content, - settings, - ) - } - } - } - - // Send notifs to the parent commenter / poster - match comment.parent_id { - Some(parent_id) => { - if let Ok(parent_comment) = Comment::read(conn, parent_id) { - // Don't send a notif to yourself - if parent_comment.creator_id != person.id { - // Get the parent commenter local_user - if let Ok(parent_user_view) = LocalUserView::read_person(conn, parent_comment.creator_id) - { - recipient_ids.push(parent_user_view.local_user.id); - - if do_send_email { - send_email_to_user( - &parent_user_view, - "Reply from", - "Comment Reply", - &comment.content, - settings, - ) - } - } - } - } - } - // Its a post - None => { - if post.creator_id != person.id { - if let Ok(parent_user_view) = LocalUserView::read_person(conn, post.creator_id) { - recipient_ids.push(parent_user_view.local_user.id); - - if do_send_email { - send_email_to_user( - &parent_user_view, - "Reply from", - "Post Reply", - &comment.content, - settings, - ) - } - } - } - } - }; - recipient_ids -} - -pub fn send_email_to_user( - local_user_view: &LocalUserView, - subject_text: &str, - body_text: &str, - comment_content: &str, - settings: &Settings, -) { - if local_user_view.person.banned || !local_user_view.local_user.send_notifications_to_email { - return; - } - - if let Some(user_email) = &local_user_view.local_user.email { - let subject = &format!( - "{} - {} {}", - subject_text, settings.hostname, local_user_view.person.name, - ); - let html = &format!( - "

{}


{} - {}

inbox", - body_text, - local_user_view.person.name, - comment_content, - settings.get_protocol_and_hostname() - ); - match send_email( - subject, - user_email, - &local_user_view.person.name, - html, - settings, - ) { - Ok(_o) => _o, - Err(e) => error!("{}", e), - }; - } -} - pub async fn is_mod_or_admin( pool: &DbPool, person_id: PersonId, diff --git a/crates/api_crud/src/comment/create.rs b/crates/api_crud/src/comment/create.rs index ff2442b15..690a50820 100644 --- a/crates/api_crud/src/comment/create.rs +++ b/crates/api_crud/src/comment/create.rs @@ -9,7 +9,6 @@ use lemmy_api_common::{ comment::*, get_local_user_view_from_jwt, get_post, - send_local_notifs, }; use lemmy_apub::{ activities::{ @@ -35,7 +34,11 @@ use lemmy_utils::{ ConnectionId, LemmyError, }; -use lemmy_websocket::{send::send_comment_ws_message, LemmyContext, UserOperationCrud}; +use lemmy_websocket::{ + send::{send_comment_ws_message, send_local_notifs}, + LemmyContext, + UserOperationCrud, +}; #[async_trait::async_trait(?Send)] impl PerformCrud for CreateComment { @@ -117,8 +120,8 @@ impl PerformCrud for CreateComment { .map_err(|e| ApiError::err("couldnt_create_comment", e))?; CreateOrUpdateComment::send( - &updated_comment, - &local_user_view.person, + &updated_comment.clone().into(), + &local_user_view.person.clone().into(), CreateOrUpdateType::Create, context, ) @@ -129,12 +132,11 @@ impl PerformCrud for CreateComment { let mentions = scrape_text_for_mentions(&comment_form.content); let recipient_ids = send_local_notifs( mentions, - updated_comment.clone(), - local_user_view.person.clone(), - post, - context.pool(), + &updated_comment, + &local_user_view.person, + &post, true, - &context.settings(), + context, ) .await?; @@ -151,10 +153,10 @@ impl PerformCrud for CreateComment { .await? .map_err(|e| ApiError::err("couldnt_like_comment", e))?; - let object = PostOrComment::Comment(updated_comment); + let object = PostOrComment::Comment(updated_comment.into()); Vote::send( &object, - &local_user_view.person, + &local_user_view.person.clone().into(), community_id, VoteType::Like, context, diff --git a/crates/api_crud/src/comment/delete.rs b/crates/api_crud/src/comment/delete.rs index 07c920f7c..19851f0c0 100644 --- a/crates/api_crud/src/comment/delete.rs +++ b/crates/api_crud/src/comment/delete.rs @@ -6,7 +6,6 @@ use lemmy_api_common::{ comment::*, get_local_user_view_from_jwt, is_mod_or_admin, - send_local_notifs, }; use lemmy_apub::activities::deletion::{send_apub_delete, send_apub_remove}; use lemmy_db_schema::{ @@ -20,7 +19,11 @@ use lemmy_db_schema::{ }; use lemmy_db_views::comment_view::CommentView; use lemmy_utils::{ApiError, ConnectionId, LemmyError}; -use lemmy_websocket::{send::send_comment_ws_message, LemmyContext, UserOperationCrud}; +use lemmy_websocket::{ + send::{send_comment_ws_message, send_local_notifs}, + LemmyContext, + UserOperationCrud, +}; #[async_trait::async_trait(?Send)] impl PerformCrud for DeleteComment { @@ -67,8 +70,8 @@ impl PerformCrud for DeleteComment { }) .await??; send_apub_delete( - &local_user_view.person, - &community, + &local_user_view.person.clone().into(), + &community.clone().into(), updated_comment.ap_id.clone().into(), deleted, context, @@ -79,12 +82,11 @@ impl PerformCrud for DeleteComment { let post = blocking(context.pool(), move |conn| Post::read(conn, post_id)).await??; let recipient_ids = send_local_notifs( vec![], - updated_comment, - local_user_view.person.clone(), - post, - context.pool(), + &updated_comment, + &local_user_view.person, + &post, false, - &context.settings(), + context, ) .await?; @@ -161,8 +163,8 @@ impl PerformCrud for RemoveComment { }) .await??; send_apub_remove( - &local_user_view.person, - &community, + &local_user_view.person.clone().into(), + &community.into(), updated_comment.ap_id.clone().into(), data.reason.clone().unwrap_or_else(|| "".to_string()), removed, @@ -174,12 +176,11 @@ impl PerformCrud for RemoveComment { let post = blocking(context.pool(), move |conn| Post::read(conn, post_id)).await??; let recipient_ids = send_local_notifs( vec![], - updated_comment, - local_user_view.person.clone(), - post, - context.pool(), + &updated_comment, + &local_user_view.person.clone(), + &post, false, - &context.settings(), + context, ) .await?; diff --git a/crates/api_crud/src/comment/update.rs b/crates/api_crud/src/comment/update.rs index 7d45b9403..9a164fc3f 100644 --- a/crates/api_crud/src/comment/update.rs +++ b/crates/api_crud/src/comment/update.rs @@ -7,7 +7,6 @@ use lemmy_api_common::{ check_post_deleted_or_removed, comment::*, get_local_user_view_from_jwt, - send_local_notifs, }; use lemmy_apub::activities::{ comment::create_or_update::CreateOrUpdateComment, @@ -21,7 +20,11 @@ use lemmy_utils::{ ConnectionId, LemmyError, }; -use lemmy_websocket::{send::send_comment_ws_message, LemmyContext, UserOperationCrud}; +use lemmy_websocket::{ + send::{send_comment_ws_message, send_local_notifs}, + LemmyContext, + UserOperationCrud, +}; #[async_trait::async_trait(?Send)] impl PerformCrud for EditComment { @@ -69,8 +72,8 @@ impl PerformCrud for EditComment { // Send the apub update CreateOrUpdateComment::send( - &updated_comment, - &local_user_view.person, + &updated_comment.clone().into(), + &local_user_view.person.clone().into(), CreateOrUpdateType::Update, context, ) @@ -81,12 +84,11 @@ impl PerformCrud for EditComment { let mentions = scrape_text_for_mentions(&updated_comment_content); let recipient_ids = send_local_notifs( mentions, - updated_comment, - local_user_view.person.clone(), - orig_comment.post, - context.pool(), + &updated_comment, + &local_user_view.person, + &orig_comment.post, false, - &context.settings(), + context, ) .await?; diff --git a/crates/api_crud/src/community/create.rs b/crates/api_crud/src/community/create.rs index cc0e62db4..8b7daeb7b 100644 --- a/crates/api_crud/src/community/create.rs +++ b/crates/api_crud/src/community/create.rs @@ -12,6 +12,7 @@ use lemmy_apub::{ generate_followers_url, generate_inbox_url, generate_shared_inbox_url, + objects::community::ApubCommunity, EndpointType, }; use lemmy_db_schema::{ @@ -71,7 +72,7 @@ impl PerformCrud for CreateCommunity { &data.name, &context.settings().get_protocol_and_hostname(), )?; - let community_actor_id_wrapped = ObjectId::::new(community_actor_id.clone()); + let community_actor_id_wrapped = ObjectId::::new(community_actor_id.clone()); let community_dupe = community_actor_id_wrapped.dereference_local(context).await; if community_dupe.is_ok() { return Err(ApiError::err_plain("community_already_exists").into()); diff --git a/crates/api_crud/src/community/delete.rs b/crates/api_crud/src/community/delete.rs index 5f9fbb44e..bf59e786f 100644 --- a/crates/api_crud/src/community/delete.rs +++ b/crates/api_crud/src/community/delete.rs @@ -49,8 +49,8 @@ impl PerformCrud for DeleteCommunity { // Send apub messages send_apub_delete( - &local_user_view.person, - &updated_community, + &local_user_view.person.clone().into(), + &updated_community.clone().into(), updated_community.actor_id.clone().into(), deleted, context, @@ -109,8 +109,8 @@ impl PerformCrud for RemoveCommunity { // Apub messages send_apub_remove( - &local_user_view.person, - &updated_community, + &local_user_view.person.clone().into(), + &updated_community.clone().into(), updated_community.actor_id.clone().into(), data.reason.clone().unwrap_or_else(|| "".to_string()), removed, diff --git a/crates/api_crud/src/community/read.rs b/crates/api_crud/src/community/read.rs index 3b9405aff..d18ef99f6 100644 --- a/crates/api_crud/src/community/read.rs +++ b/crates/api_crud/src/community/read.rs @@ -1,10 +1,14 @@ use crate::PerformCrud; use actix_web::web::Data; use lemmy_api_common::{blocking, community::*, get_local_user_view_from_jwt_opt}; -use lemmy_apub::{build_actor_id_from_shortname, fetcher::object_id::ObjectId, EndpointType}; +use lemmy_apub::{ + build_actor_id_from_shortname, + fetcher::object_id::ObjectId, + objects::community::ApubCommunity, + EndpointType, +}; use lemmy_db_schema::{ from_opt_str_to_opt_enum, - source::community::Community, traits::DeleteableOrRemoveable, ListingType, SortType, @@ -37,7 +41,7 @@ impl PerformCrud for GetCommunity { let community_actor_id = build_actor_id_from_shortname(EndpointType::Community, &name, &context.settings())?; - ObjectId::::new(community_actor_id) + ObjectId::::new(community_actor_id) .dereference(context, &mut 0) .await .map_err(|e| ApiError::err("couldnt_find_community", e))? diff --git a/crates/api_crud/src/community/update.rs b/crates/api_crud/src/community/update.rs index f269807b5..97722a98b 100644 --- a/crates/api_crud/src/community/update.rs +++ b/crates/api_crud/src/community/update.rs @@ -71,7 +71,12 @@ impl PerformCrud for EditCommunity { .await? .map_err(|e| ApiError::err("couldnt_update_community", e))?; - UpdateCommunity::send(&updated_community, &local_user_view.person, context).await?; + UpdateCommunity::send( + &updated_community.into(), + &local_user_view.person.into(), + context, + ) + .await?; let op = UserOperationCrud::EditCommunity; send_community_ws_message(data.community_id, op, websocket_id, None, context).await diff --git a/crates/api_crud/src/post/create.rs b/crates/api_crud/src/post/create.rs index e75999e59..3e5fb41e1 100644 --- a/crates/api_crud/src/post/create.rs +++ b/crates/api_crud/src/post/create.rs @@ -109,8 +109,8 @@ impl PerformCrud for CreatePost { .map_err(|e| ApiError::err("couldnt_create_post", e))?; CreateOrUpdatePost::send( - &updated_post, - &local_user_view.person, + &updated_post.clone().into(), + &local_user_view.person.clone().into(), CreateOrUpdateType::Create, context, ) @@ -146,10 +146,10 @@ impl PerformCrud for CreatePost { } } - let object = PostOrComment::Post(Box::new(updated_post)); + let object = PostOrComment::Post(Box::new(updated_post.into())); Vote::send( &object, - &local_user_view.person, + &local_user_view.person.clone().into(), inserted_post.community_id, VoteType::Like, context, diff --git a/crates/api_crud/src/post/delete.rs b/crates/api_crud/src/post/delete.rs index 1a9044c37..a701e8355 100644 --- a/crates/api_crud/src/post/delete.rs +++ b/crates/api_crud/src/post/delete.rs @@ -63,8 +63,8 @@ impl PerformCrud for DeletePost { }) .await??; send_apub_delete( - &local_user_view.person, - &community, + &local_user_view.person.clone().into(), + &community.into(), updated_post.ap_id.into(), deleted, context, @@ -139,8 +139,8 @@ impl PerformCrud for RemovePost { }) .await??; send_apub_remove( - &local_user_view.person, - &community, + &local_user_view.person.clone().into(), + &community.into(), updated_post.ap_id.into(), data.reason.clone().unwrap_or_else(|| "".to_string()), removed, diff --git a/crates/api_crud/src/post/update.rs b/crates/api_crud/src/post/update.rs index 8c346b882..96e4400a5 100644 --- a/crates/api_crud/src/post/update.rs +++ b/crates/api_crud/src/post/update.rs @@ -104,8 +104,8 @@ impl PerformCrud for EditPost { // Send apub update CreateOrUpdatePost::send( - &updated_post, - &local_user_view.person, + &updated_post.into(), + &local_user_view.person.clone().into(), CreateOrUpdateType::Update, context, ) diff --git a/crates/api_crud/src/private_message/create.rs b/crates/api_crud/src/private_message/create.rs index 9e3351252..d6560be25 100644 --- a/crates/api_crud/src/private_message/create.rs +++ b/crates/api_crud/src/private_message/create.rs @@ -5,7 +5,6 @@ use lemmy_api_common::{ check_person_block, get_local_user_view_from_jwt, person::{CreatePrivateMessage, PrivateMessageResponse}, - send_email_to_user, }; use lemmy_apub::{ activities::{ @@ -21,7 +20,11 @@ use lemmy_db_schema::{ }; use lemmy_db_views::local_user_view::LocalUserView; use lemmy_utils::{utils::remove_slurs, ApiError, ConnectionId, LemmyError}; -use lemmy_websocket::{send::send_pm_ws_message, LemmyContext, UserOperationCrud}; +use lemmy_websocket::{ + send::{send_email_to_user, send_pm_ws_message}, + LemmyContext, + UserOperationCrud, +}; #[async_trait::async_trait(?Send)] impl PerformCrud for CreatePrivateMessage { @@ -80,8 +83,8 @@ impl PerformCrud for CreatePrivateMessage { .map_err(|e| ApiError::err("couldnt_create_private_message", e))?; CreateOrUpdatePrivateMessage::send( - &updated_private_message, - &local_user_view.person, + &updated_private_message.into(), + &local_user_view.person.into(), CreateOrUpdateType::Create, context, ) diff --git a/crates/api_crud/src/private_message/delete.rs b/crates/api_crud/src/private_message/delete.rs index 0c61a09b0..f369f82b1 100644 --- a/crates/api_crud/src/private_message/delete.rs +++ b/crates/api_crud/src/private_message/delete.rs @@ -51,14 +51,20 @@ impl PerformCrud for DeletePrivateMessage { // Send the apub update if data.deleted { DeletePrivateMessageApub::send( - &local_user_view.person, - &updated_private_message.blank_out_deleted_or_removed_info(), + &local_user_view.person.into(), + &updated_private_message + .blank_out_deleted_or_removed_info() + .into(), context, ) .await?; } else { - UndoDeletePrivateMessage::send(&local_user_view.person, &updated_private_message, context) - .await?; + UndoDeletePrivateMessage::send( + &local_user_view.person.into(), + &updated_private_message.into(), + context, + ) + .await?; } let op = UserOperationCrud::DeletePrivateMessage; diff --git a/crates/api_crud/src/private_message/update.rs b/crates/api_crud/src/private_message/update.rs index 026a047e2..d72e3b137 100644 --- a/crates/api_crud/src/private_message/update.rs +++ b/crates/api_crud/src/private_message/update.rs @@ -47,8 +47,8 @@ impl PerformCrud for EditPrivateMessage { // Send the apub update CreateOrUpdatePrivateMessage::send( - &updated_private_message, - &local_user_view.person, + &updated_private_message.into(), + &local_user_view.person.into(), CreateOrUpdateType::Update, context, ) diff --git a/crates/api_crud/src/user/read.rs b/crates/api_crud/src/user/read.rs index 4eb6771ee..a5b69ba45 100644 --- a/crates/api_crud/src/user/read.rs +++ b/crates/api_crud/src/user/read.rs @@ -1,8 +1,13 @@ use crate::PerformCrud; use actix_web::web::Data; use lemmy_api_common::{blocking, get_local_user_view_from_jwt_opt, person::*}; -use lemmy_apub::{build_actor_id_from_shortname, fetcher::object_id::ObjectId, EndpointType}; -use lemmy_db_schema::{from_opt_str_to_opt_enum, source::person::Person, SortType}; +use lemmy_apub::{ + build_actor_id_from_shortname, + fetcher::object_id::ObjectId, + objects::person::ApubPerson, + EndpointType, +}; +use lemmy_db_schema::{from_opt_str_to_opt_enum, SortType}; use lemmy_db_views::{comment_view::CommentQueryBuilder, post_view::PostQueryBuilder}; use lemmy_db_views_actor::{ community_moderator_view::CommunityModeratorView, @@ -44,7 +49,7 @@ impl PerformCrud for GetPersonDetails { let actor_id = build_actor_id_from_shortname(EndpointType::Person, &name, &context.settings())?; - let person = ObjectId::::new(actor_id) + let person = ObjectId::::new(actor_id) .dereference(context, &mut 0) .await; person diff --git a/crates/apub/src/activities/comment/create_or_update.rs b/crates/apub/src/activities/comment/create_or_update.rs index c9b111837..c4591c7c8 100644 --- a/crates/apub/src/activities/comment/create_or_update.rs +++ b/crates/apub/src/activities/comment/create_or_update.rs @@ -11,18 +11,22 @@ use crate::{ }, context::lemmy_context, fetcher::object_id::ObjectId, - objects::{comment::Note, FromApub, ToApub}, + objects::{ + comment::{ApubComment, Note}, + community::ApubCommunity, + person::ApubPerson, + }, }; use activitystreams::{base::AnyBase, link::Mention, primitives::OneOrMany, unparsed::Unparsed}; use lemmy_api_common::{blocking, check_post_deleted_or_removed}; use lemmy_apub_lib::{ data::Data, - traits::{ActivityFields, ActivityHandler, ActorType}, + traits::{ActivityFields, ActivityHandler, ActorType, FromApub, ToApub}, values::PublicUrl, verify::verify_domains_match, }; use lemmy_db_schema::{ - source::{comment::Comment, community::Community, person::Person, post::Post}, + source::{community::Community, post::Post}, traits::Crud, }; use lemmy_utils::LemmyError; @@ -33,7 +37,7 @@ use url::Url; #[derive(Clone, Debug, Deserialize, Serialize, ActivityFields)] #[serde(rename_all = "camelCase")] pub struct CreateOrUpdateComment { - actor: ObjectId, + actor: ObjectId, to: [PublicUrl; 1], object: Note, cc: Vec, @@ -49,8 +53,8 @@ pub struct CreateOrUpdateComment { impl CreateOrUpdateComment { pub async fn send( - comment: &Comment, - actor: &Person, + comment: &ApubComment, + actor: &ApubPerson, kind: CreateOrUpdateType, context: &LemmyContext, ) -> Result<(), LemmyError> { @@ -58,10 +62,11 @@ impl CreateOrUpdateComment { let post_id = comment.post_id; let post = blocking(context.pool(), move |conn| Post::read(conn, post_id)).await??; let community_id = post.community_id; - let community = blocking(context.pool(), move |conn| { + let community: ApubCommunity = blocking(context.pool(), move |conn| { Community::read(conn, community_id) }) - .await??; + .await?? + .into(); let id = generate_activity_id( kind.clone(), @@ -117,7 +122,7 @@ impl ActivityHandler for CreateOrUpdateComment { request_counter: &mut i32, ) -> Result<(), LemmyError> { let comment = - Comment::from_apub(&self.object, context, self.actor.inner(), request_counter).await?; + ApubComment::from_apub(&self.object, context, self.actor.inner(), request_counter).await?; let recipients = get_notif_recipients(&self.actor, &comment, context, request_counter).await?; let notif_type = match self.kind { CreateOrUpdateType::Create => UserOperationCrud::CreateComment, diff --git a/crates/apub/src/activities/comment/mod.rs b/crates/apub/src/activities/comment/mod.rs index 1ac320cb9..9eb2bb447 100644 --- a/crates/apub/src/activities/comment/mod.rs +++ b/crates/apub/src/activities/comment/mod.rs @@ -1,15 +1,18 @@ -use crate::fetcher::object_id::ObjectId; +use crate::{ + fetcher::object_id::ObjectId, + objects::{comment::ApubComment, community::ApubCommunity, person::ApubPerson}, +}; use activitystreams::{ base::BaseExt, link::{LinkExt, Mention}, }; use anyhow::anyhow; use itertools::Itertools; -use lemmy_api_common::{blocking, send_local_notifs}; +use lemmy_api_common::blocking; use lemmy_apub_lib::{traits::ActorType, webfinger::WebfingerResponse}; use lemmy_db_schema::{ newtypes::LocalUserId, - source::{comment::Comment, community::Community, person::Person, post::Post}, + source::{comment::Comment, person::Person, post::Post}, traits::Crud, DbPool, }; @@ -18,14 +21,14 @@ use lemmy_utils::{ utils::{scrape_text_for_mentions, MentionData}, LemmyError, }; -use lemmy_websocket::LemmyContext; +use lemmy_websocket::{send::send_local_notifs, LemmyContext}; use log::debug; use url::Url; pub mod create_or_update; async fn get_notif_recipients( - actor: &ObjectId, + actor: &ObjectId, comment: &Comment, context: &LemmyContext, request_counter: &mut i32, @@ -40,16 +43,7 @@ async fn get_notif_recipients( // anyway. // TODO: for compatibility with other projects, it would be much better to read this from cc or tags let mentions = scrape_text_for_mentions(&comment.content); - send_local_notifs( - mentions, - comment.clone(), - actor, - post, - context.pool(), - true, - &context.settings(), - ) - .await + send_local_notifs(mentions, comment, &*actor, &post, true, context).await } pub struct MentionsAndAddresses { @@ -62,12 +56,12 @@ pub struct MentionsAndAddresses { /// and mention tags, so they know where to be sent to. /// Addresses are the persons / addresses that go in the cc field. pub async fn collect_non_local_mentions( - comment: &Comment, - community: &Community, + comment: &ApubComment, + community: &ApubCommunity, context: &LemmyContext, ) -> Result { let parent_creator = get_comment_parent_creator(context.pool(), comment).await?; - let mut addressed_ccs = vec![community.actor_id(), parent_creator.actor_id()]; + let mut addressed_ccs: Vec = vec![community.actor_id(), parent_creator.actor_id()]; // Note: dont include community inbox here, as we send to it separately with `send_to_community()` let mut inboxes = vec![parent_creator.shared_inbox_or_inbox_url()]; @@ -84,9 +78,9 @@ pub async fn collect_non_local_mentions( for mention in &mentions { // TODO should it be fetching it every time? if let Ok(actor_id) = fetch_webfinger_url(mention, context).await { - let actor_id: ObjectId = ObjectId::new(actor_id); + let actor_id: ObjectId = ObjectId::new(actor_id); debug!("mention actor_id: {}", actor_id); - addressed_ccs.push(actor_id.to_owned().to_string().parse()?); + addressed_ccs.push(actor_id.to_string().parse()?); let mention_person = actor_id.dereference(context, &mut 0).await?; inboxes.push(mention_person.shared_inbox_or_inbox_url()); @@ -113,7 +107,7 @@ pub async fn collect_non_local_mentions( async fn get_comment_parent_creator( pool: &DbPool, comment: &Comment, -) -> Result { +) -> Result { let parent_creator_id = if let Some(parent_comment_id) = comment.parent_id { let parent_comment = blocking(pool, move |conn| Comment::read(conn, parent_comment_id)).await??; @@ -123,7 +117,11 @@ async fn get_comment_parent_creator( let parent_post = blocking(pool, move |conn| Post::read(conn, parent_post_id)).await??; parent_post.creator_id }; - Ok(blocking(pool, move |conn| Person::read(conn, parent_creator_id)).await??) + Ok( + blocking(pool, move |conn| Person::read(conn, parent_creator_id)) + .await?? + .into(), + ) } /// Turns a person id like `@name@example.com` into an apub ID, like `https://example.com/user/name`, diff --git a/crates/apub/src/activities/community/add_mod.rs b/crates/apub/src/activities/community/add_mod.rs index 149b92cd2..e1cf03e0d 100644 --- a/crates/apub/src/activities/community/add_mod.rs +++ b/crates/apub/src/activities/community/add_mod.rs @@ -10,6 +10,7 @@ use crate::{ context::lemmy_context, fetcher::object_id::ObjectId, generate_moderators_url, + objects::{community::ApubCommunity, person::ApubPerson}, }; use activitystreams::{ activity::kind::AddType, @@ -24,10 +25,7 @@ use lemmy_apub_lib::{ values::PublicUrl, }; use lemmy_db_schema::{ - source::{ - community::{Community, CommunityModerator, CommunityModeratorForm}, - person::Person, - }, + source::community::{CommunityModerator, CommunityModeratorForm}, traits::Joinable, }; use lemmy_utils::LemmyError; @@ -38,11 +36,11 @@ use url::Url; #[derive(Clone, Debug, Deserialize, Serialize, ActivityFields)] #[serde(rename_all = "camelCase")] pub struct AddMod { - actor: ObjectId, + actor: ObjectId, to: [PublicUrl; 1], - object: ObjectId, + object: ObjectId, target: Url, - cc: [ObjectId; 1], + cc: [ObjectId; 1], #[serde(rename = "type")] kind: AddType, id: Url, @@ -54,9 +52,9 @@ pub struct AddMod { impl AddMod { pub async fn send( - community: &Community, - added_mod: &Person, - actor: &Person, + community: &ApubCommunity, + added_mod: &ApubPerson, + actor: &ApubPerson, context: &LemmyContext, ) -> Result<(), LemmyError> { let id = generate_activity_id( @@ -92,7 +90,7 @@ impl ActivityHandler for AddMod { ) -> Result<(), LemmyError> { verify_activity(self, &context.settings())?; verify_person_in_community(&self.actor, &self.cc[0], context, request_counter).await?; - verify_mod_action(&self.actor, self.cc[0].clone(), context, request_counter).await?; + verify_mod_action(&self.actor, &self.cc[0], context, request_counter).await?; verify_add_remove_moderator_target(&self.target, &self.cc[0])?; Ok(()) } diff --git a/crates/apub/src/activities/community/announce.rs b/crates/apub/src/activities/community/announce.rs index ec72b8429..183dbfd5f 100644 --- a/crates/apub/src/activities/community/announce.rs +++ b/crates/apub/src/activities/community/announce.rs @@ -21,6 +21,7 @@ use crate::{ fetcher::object_id::ObjectId, http::is_activity_already_known, insert_activity, + objects::community::ApubCommunity, send_lemmy_activity, CommunityType, }; @@ -35,7 +36,6 @@ use lemmy_apub_lib::{ traits::{ActivityFields, ActivityHandler, ActorType}, values::PublicUrl, }; -use lemmy_db_schema::source::community::Community; use lemmy_utils::LemmyError; use lemmy_websocket::LemmyContext; use serde::{Deserialize, Serialize}; @@ -62,7 +62,7 @@ pub enum AnnouncableActivities { #[derive(Clone, Debug, Deserialize, Serialize, ActivityFields)] #[serde(rename_all = "camelCase")] pub struct AnnounceActivity { - actor: ObjectId, + actor: ObjectId, to: [PublicUrl; 1], object: AnnouncableActivities, cc: Vec, @@ -78,7 +78,7 @@ pub struct AnnounceActivity { impl AnnounceActivity { pub async fn send( object: AnnouncableActivities, - community: &Community, + community: &ApubCommunity, additional_inboxes: Vec, context: &LemmyContext, ) -> Result<(), LemmyError> { diff --git a/crates/apub/src/activities/community/block_user.rs b/crates/apub/src/activities/community/block_user.rs index 9b4c3e813..a1c76c23b 100644 --- a/crates/apub/src/activities/community/block_user.rs +++ b/crates/apub/src/activities/community/block_user.rs @@ -8,6 +8,7 @@ use crate::{ }, context::lemmy_context, fetcher::object_id::ObjectId, + objects::{community::ApubCommunity, person::ApubPerson}, }; use activitystreams::{ activity::kind::BlockType, @@ -22,15 +23,11 @@ use lemmy_apub_lib::{ values::PublicUrl, }; use lemmy_db_schema::{ - source::{ - community::{ - Community, - CommunityFollower, - CommunityFollowerForm, - CommunityPersonBan, - CommunityPersonBanForm, - }, - person::Person, + source::community::{ + CommunityFollower, + CommunityFollowerForm, + CommunityPersonBan, + CommunityPersonBanForm, }, traits::{Bannable, Followable}, }; @@ -42,10 +39,10 @@ use url::Url; #[derive(Clone, Debug, Deserialize, Serialize, ActivityFields)] #[serde(rename_all = "camelCase")] pub struct BlockUserFromCommunity { - actor: ObjectId, + actor: ObjectId, to: [PublicUrl; 1], - pub(in crate::activities::community) object: ObjectId, - cc: [ObjectId; 1], + pub(in crate::activities::community) object: ObjectId, + cc: [ObjectId; 1], #[serde(rename = "type")] kind: BlockType, id: Url, @@ -57,9 +54,9 @@ pub struct BlockUserFromCommunity { impl BlockUserFromCommunity { pub(in crate::activities::community) fn new( - community: &Community, - target: &Person, - actor: &Person, + community: &ApubCommunity, + target: &ApubPerson, + actor: &ApubPerson, context: &LemmyContext, ) -> Result { Ok(BlockUserFromCommunity { @@ -78,9 +75,9 @@ impl BlockUserFromCommunity { } pub async fn send( - community: &Community, - target: &Person, - actor: &Person, + community: &ApubCommunity, + target: &ApubPerson, + actor: &ApubPerson, context: &LemmyContext, ) -> Result<(), LemmyError> { let block = BlockUserFromCommunity::new(community, target, actor, context)?; @@ -102,7 +99,7 @@ impl ActivityHandler for BlockUserFromCommunity { ) -> Result<(), LemmyError> { verify_activity(self, &context.settings())?; verify_person_in_community(&self.actor, &self.cc[0], context, request_counter).await?; - verify_mod_action(&self.actor, self.cc[0].clone(), context, request_counter).await?; + verify_mod_action(&self.actor, &self.cc[0], context, request_counter).await?; Ok(()) } diff --git a/crates/apub/src/activities/community/mod.rs b/crates/apub/src/activities/community/mod.rs index dd6ccb7ff..f69ee026e 100644 --- a/crates/apub/src/activities/community/mod.rs +++ b/crates/apub/src/activities/community/mod.rs @@ -2,12 +2,12 @@ use crate::{ activities::community::announce::{AnnouncableActivities, AnnounceActivity}, check_is_apub_id_valid, insert_activity, + objects::community::ApubCommunity, send_lemmy_activity, CommunityType, }; use itertools::Itertools; use lemmy_apub_lib::traits::ActorType; -use lemmy_db_schema::source::community::Community; use lemmy_utils::LemmyError; use lemmy_websocket::LemmyContext; use url::Url; @@ -20,7 +20,7 @@ pub mod undo_block_user; pub mod update; async fn list_community_follower_inboxes( - community: &Community, + community: &ApubCommunity, additional_inboxes: Vec, context: &LemmyContext, ) -> Result, LemmyError> { @@ -45,7 +45,7 @@ pub(crate) async fn send_to_community( activity: AnnouncableActivities, activity_id: &Url, actor: &T, - community: &Community, + community: &ApubCommunity, additional_inboxes: Vec, context: &LemmyContext, ) -> Result<(), LemmyError> { diff --git a/crates/apub/src/activities/community/remove_mod.rs b/crates/apub/src/activities/community/remove_mod.rs index 4f980d01a..b145e7171 100644 --- a/crates/apub/src/activities/community/remove_mod.rs +++ b/crates/apub/src/activities/community/remove_mod.rs @@ -11,6 +11,7 @@ use crate::{ context::lemmy_context, fetcher::object_id::ObjectId, generate_moderators_url, + objects::{community::ApubCommunity, person::ApubPerson}, }; use activitystreams::{ activity::kind::RemoveType, @@ -25,10 +26,7 @@ use lemmy_apub_lib::{ values::PublicUrl, }; use lemmy_db_schema::{ - source::{ - community::{Community, CommunityModerator, CommunityModeratorForm}, - person::Person, - }, + source::community::{CommunityModerator, CommunityModeratorForm}, traits::Joinable, }; use lemmy_utils::LemmyError; @@ -39,10 +37,10 @@ use url::Url; #[derive(Clone, Debug, Deserialize, Serialize, ActivityFields)] #[serde(rename_all = "camelCase")] pub struct RemoveMod { - actor: ObjectId, + actor: ObjectId, to: [PublicUrl; 1], - pub(in crate::activities) object: ObjectId, - cc: [ObjectId; 1], + pub(in crate::activities) object: ObjectId, + cc: [ObjectId; 1], #[serde(rename = "type")] kind: RemoveType, // if target is set, this is means remove mod from community @@ -56,9 +54,9 @@ pub struct RemoveMod { impl RemoveMod { pub async fn send( - community: &Community, - removed_mod: &Person, - actor: &Person, + community: &ApubCommunity, + removed_mod: &ApubPerson, + actor: &ApubPerson, context: &LemmyContext, ) -> Result<(), LemmyError> { let id = generate_activity_id( @@ -94,7 +92,7 @@ impl ActivityHandler for RemoveMod { verify_activity(self, &context.settings())?; if let Some(target) = &self.target { verify_person_in_community(&self.actor, &self.cc[0], context, request_counter).await?; - verify_mod_action(&self.actor, self.cc[0].clone(), context, request_counter).await?; + verify_mod_action(&self.actor, &self.cc[0], context, request_counter).await?; verify_add_remove_moderator_target(target, &self.cc[0])?; } else { verify_delete_activity( diff --git a/crates/apub/src/activities/community/undo_block_user.rs b/crates/apub/src/activities/community/undo_block_user.rs index 47cace42c..1614de672 100644 --- a/crates/apub/src/activities/community/undo_block_user.rs +++ b/crates/apub/src/activities/community/undo_block_user.rs @@ -12,6 +12,7 @@ use crate::{ }, context::lemmy_context, fetcher::object_id::ObjectId, + objects::{community::ApubCommunity, person::ApubPerson}, }; use activitystreams::{ activity::kind::UndoType, @@ -26,10 +27,7 @@ use lemmy_apub_lib::{ values::PublicUrl, }; use lemmy_db_schema::{ - source::{ - community::{Community, CommunityPersonBan, CommunityPersonBanForm}, - person::Person, - }, + source::community::{CommunityPersonBan, CommunityPersonBanForm}, traits::Bannable, }; use lemmy_utils::LemmyError; @@ -40,10 +38,10 @@ use url::Url; #[derive(Clone, Debug, Deserialize, Serialize, ActivityFields)] #[serde(rename_all = "camelCase")] pub struct UndoBlockUserFromCommunity { - actor: ObjectId, + actor: ObjectId, to: [PublicUrl; 1], object: BlockUserFromCommunity, - cc: [ObjectId; 1], + cc: [ObjectId; 1], #[serde(rename = "type")] kind: UndoType, id: Url, @@ -55,9 +53,9 @@ pub struct UndoBlockUserFromCommunity { impl UndoBlockUserFromCommunity { pub async fn send( - community: &Community, - target: &Person, - actor: &Person, + community: &ApubCommunity, + target: &ApubPerson, + actor: &ApubPerson, context: &LemmyContext, ) -> Result<(), LemmyError> { let block = BlockUserFromCommunity::new(community, target, actor, context)?; @@ -93,7 +91,7 @@ impl ActivityHandler for UndoBlockUserFromCommunity { ) -> Result<(), LemmyError> { verify_activity(self, &context.settings())?; verify_person_in_community(&self.actor, &self.cc[0], context, request_counter).await?; - verify_mod_action(&self.actor, self.cc[0].clone(), context, request_counter).await?; + verify_mod_action(&self.actor, &self.cc[0], context, request_counter).await?; self.object.verify(context, request_counter).await?; Ok(()) } diff --git a/crates/apub/src/activities/community/update.rs b/crates/apub/src/activities/community/update.rs index 02b7126ad..1120bd8bb 100644 --- a/crates/apub/src/activities/community/update.rs +++ b/crates/apub/src/activities/community/update.rs @@ -8,7 +8,10 @@ use crate::{ }, context::lemmy_context, fetcher::object_id::ObjectId, - objects::{community::Group, ToApub}, + objects::{ + community::{ApubCommunity, Group}, + person::ApubPerson, + }, }; use activitystreams::{ activity::kind::UpdateType, @@ -19,14 +22,11 @@ use activitystreams::{ use lemmy_api_common::blocking; use lemmy_apub_lib::{ data::Data, - traits::{ActivityFields, ActivityHandler, ActorType}, + traits::{ActivityFields, ActivityHandler, ActorType, ToApub}, values::PublicUrl, }; use lemmy_db_schema::{ - source::{ - community::{Community, CommunityForm}, - person::Person, - }, + source::community::{Community, CommunityForm}, traits::Crud, }; use lemmy_utils::LemmyError; @@ -39,11 +39,11 @@ use url::Url; #[derive(Clone, Debug, Deserialize, Serialize, ActivityFields)] #[serde(rename_all = "camelCase")] pub struct UpdateCommunity { - actor: ObjectId, + actor: ObjectId, to: [PublicUrl; 1], // TODO: would be nice to use a separate struct here, which only contains the fields updated here object: Group, - cc: [ObjectId; 1], + cc: [ObjectId; 1], #[serde(rename = "type")] kind: UpdateType, id: Url, @@ -55,8 +55,8 @@ pub struct UpdateCommunity { impl UpdateCommunity { pub async fn send( - community: &Community, - actor: &Person, + community: &ApubCommunity, + actor: &ApubPerson, context: &LemmyContext, ) -> Result<(), LemmyError> { let id = generate_activity_id( @@ -89,7 +89,7 @@ impl ActivityHandler for UpdateCommunity { ) -> Result<(), LemmyError> { verify_activity(self, &context.settings())?; verify_person_in_community(&self.actor, &self.cc[0], context, request_counter).await?; - verify_mod_action(&self.actor, self.cc[0].clone(), context, request_counter).await?; + verify_mod_action(&self.actor, &self.cc[0], context, request_counter).await?; Ok(()) } diff --git a/crates/apub/src/activities/deletion/delete.rs b/crates/apub/src/activities/deletion/delete.rs index 251a3ffa4..02df7dc38 100644 --- a/crates/apub/src/activities/deletion/delete.rs +++ b/crates/apub/src/activities/deletion/delete.rs @@ -12,6 +12,7 @@ use crate::{ }, context::lemmy_context, fetcher::object_id::ObjectId, + objects::{community::ApubCommunity, person::ApubPerson}, }; use activitystreams::{ activity::kind::DeleteType, @@ -38,7 +39,6 @@ use lemmy_db_schema::{ ModRemovePost, ModRemovePostForm, }, - person::Person, post::Post, }, traits::Crud, @@ -65,10 +65,10 @@ use url::Url; #[derive(Clone, Debug, Deserialize, Serialize, ActivityFields)] #[serde(rename_all = "camelCase")] pub struct Delete { - actor: ObjectId, + actor: ObjectId, to: [PublicUrl; 1], pub(in crate::activities::deletion) object: Url, - pub(in crate::activities::deletion) cc: [ObjectId; 1], + pub(in crate::activities::deletion) cc: [ObjectId; 1], #[serde(rename = "type")] kind: DeleteType, /// If summary is present, this is a mod action (Remove in Lemmy terms). Otherwise, its a user @@ -136,8 +136,8 @@ impl ActivityHandler for Delete { impl Delete { pub(in crate::activities::deletion) fn new( - actor: &Person, - community: &Community, + actor: &ApubPerson, + community: &ApubCommunity, object_id: Url, summary: Option, context: &LemmyContext, @@ -158,8 +158,8 @@ impl Delete { }) } pub(in crate::activities::deletion) async fn send( - actor: &Person, - community: &Community, + actor: &ApubPerson, + community: &ApubCommunity, object_id: Url, summary: Option, context: &LemmyContext, @@ -173,7 +173,7 @@ impl Delete { } pub(in crate::activities) async fn receive_remove_action( - actor: &ObjectId, + actor: &ObjectId, object: &Url, reason: Option, context: &LemmyContext, diff --git a/crates/apub/src/activities/deletion/mod.rs b/crates/apub/src/activities/deletion/mod.rs index 3a38f2a22..4352afe87 100644 --- a/crates/apub/src/activities/deletion/mod.rs +++ b/crates/apub/src/activities/deletion/mod.rs @@ -5,14 +5,14 @@ use crate::{ verify_person_in_community, }, fetcher::object_id::ObjectId, + objects::{comment::ApubComment, community::ApubCommunity, person::ApubPerson, post::ApubPost}, }; -use diesel::PgConnection; use lemmy_api_common::blocking; use lemmy_apub_lib::{ traits::{ActivityFields, ActorType, ApubObject}, verify::verify_domains_match, }; -use lemmy_db_schema::source::{comment::Comment, community::Community, person::Person, post::Post}; +use lemmy_db_schema::source::{comment::Comment, community::Community, post::Post}; use lemmy_utils::LemmyError; use lemmy_websocket::{ send::{send_comment_ws_message_simple, send_community_ws_message, send_post_ws_message}, @@ -25,8 +25,8 @@ pub mod delete; pub mod undo_delete; pub async fn send_apub_delete( - actor: &Person, - community: &Community, + actor: &ApubPerson, + community: &ApubCommunity, object_id: Url, deleted: bool, context: &LemmyContext, @@ -41,8 +41,8 @@ pub async fn send_apub_delete( // TODO: remove reason is actually optional in lemmy. we set an empty string in that case, but its // ugly pub async fn send_apub_remove( - actor: &Person, - community: &Community, + actor: &ApubPerson, + community: &ApubCommunity, object_id: Url, reason: String, removed: bool, @@ -56,9 +56,9 @@ pub async fn send_apub_remove( } pub enum DeletableObjects { - Community(Box), - Comment(Box), - Post(Box), + Community(Box), + Comment(Box), + Post(Box), } impl DeletableObjects { @@ -66,39 +66,23 @@ impl DeletableObjects { ap_id: &Url, context: &LemmyContext, ) -> Result { - if let Some(c) = - DeletableObjects::read_type_from_db::(ap_id.clone(), context).await? - { + if let Some(c) = ApubCommunity::read_from_apub_id(ap_id.clone(), context).await? { return Ok(DeletableObjects::Community(Box::new(c))); } - if let Some(p) = DeletableObjects::read_type_from_db::(ap_id.clone(), context).await? { + if let Some(p) = ApubPost::read_from_apub_id(ap_id.clone(), context).await? { return Ok(DeletableObjects::Post(Box::new(p))); } - if let Some(c) = DeletableObjects::read_type_from_db::(ap_id.clone(), context).await? { + if let Some(c) = ApubComment::read_from_apub_id(ap_id.clone(), context).await? { return Ok(DeletableObjects::Comment(Box::new(c))); } Err(diesel::NotFound.into()) } - - // TODO: a method like this should be provided by fetcher module - async fn read_type_from_db( - ap_id: Url, - context: &LemmyContext, - ) -> Result, LemmyError> - where - Type: ApubObject + Send + 'static, - { - blocking(context.pool(), move |conn| { - Type::read_from_apub_id(conn, ap_id) - }) - .await? - } } pub(in crate::activities) async fn verify_delete_activity( object: &Url, activity: &dyn ActivityFields, - community_id: &ObjectId, + community_id: &ObjectId, is_mod_action: bool, context: &LemmyContext, request_counter: &mut i32, @@ -115,7 +99,7 @@ pub(in crate::activities) async fn verify_delete_activity( // community deletion is always a mod (or admin) action verify_mod_action( &actor, - ObjectId::new(c.actor_id()), + &ObjectId::new(c.actor_id()), context, request_counter, ) @@ -124,7 +108,7 @@ pub(in crate::activities) async fn verify_delete_activity( DeletableObjects::Post(p) => { verify_delete_activity_post_or_comment( activity, - &p.ap_id.into(), + &p.ap_id.clone().into(), community_id, is_mod_action, context, @@ -135,7 +119,7 @@ pub(in crate::activities) async fn verify_delete_activity( DeletableObjects::Comment(c) => { verify_delete_activity_post_or_comment( activity, - &c.ap_id.into(), + &c.ap_id.clone().into(), community_id, is_mod_action, context, @@ -150,7 +134,7 @@ pub(in crate::activities) async fn verify_delete_activity( async fn verify_delete_activity_post_or_comment( activity: &dyn ActivityFields, object_id: &Url, - community_id: &ObjectId, + community_id: &ObjectId, is_mod_action: bool, context: &LemmyContext, request_counter: &mut i32, @@ -158,7 +142,7 @@ async fn verify_delete_activity_post_or_comment( let actor = ObjectId::new(activity.actor().clone()); verify_person_in_community(&actor, community_id, context, request_counter).await?; if is_mod_action { - verify_mod_action(&actor, community_id.clone(), context, request_counter).await?; + verify_mod_action(&actor, community_id, context, request_counter).await?; } else { // domain of post ap_id and post.creator ap_id are identical, so we just check the former verify_domains_match(activity.actor(), object_id)?; @@ -177,7 +161,7 @@ struct WebsocketMessages { /// because of the mod log async fn receive_delete_action( object: &Url, - actor: &ObjectId, + actor: &ObjectId, ws_messages: WebsocketMessages, deleted: bool, context: &LemmyContext, diff --git a/crates/apub/src/activities/deletion/undo_delete.rs b/crates/apub/src/activities/deletion/undo_delete.rs index 7a96d4301..327bf86c0 100644 --- a/crates/apub/src/activities/deletion/undo_delete.rs +++ b/crates/apub/src/activities/deletion/undo_delete.rs @@ -13,6 +13,7 @@ use crate::{ }, context::lemmy_context, fetcher::object_id::ObjectId, + objects::{community::ApubCommunity, person::ApubPerson}, }; use activitystreams::{ activity::kind::UndoType, @@ -27,7 +28,7 @@ use lemmy_apub_lib::{ traits::{ActivityFields, ActivityHandler, ActorType}, values::PublicUrl, }; -use lemmy_db_schema::source::{comment::Comment, community::Community, person::Person, post::Post}; +use lemmy_db_schema::source::{comment::Comment, community::Community, post::Post}; use lemmy_utils::LemmyError; use lemmy_websocket::{ send::{send_comment_ws_message_simple, send_community_ws_message, send_post_ws_message}, @@ -40,10 +41,10 @@ use url::Url; #[derive(Clone, Debug, Deserialize, Serialize, ActivityFields)] #[serde(rename_all = "camelCase")] pub struct UndoDelete { - actor: ObjectId, + actor: ObjectId, to: [PublicUrl; 1], object: Delete, - cc: [ObjectId; 1], + cc: [ObjectId; 1], #[serde(rename = "type")] kind: UndoType, id: Url, @@ -102,8 +103,8 @@ impl ActivityHandler for UndoDelete { impl UndoDelete { pub(in crate::activities::deletion) async fn send( - actor: &Person, - community: &Community, + actor: &ApubPerson, + community: &ApubCommunity, object_id: Url, summary: Option, context: &LemmyContext, diff --git a/crates/apub/src/activities/following/accept.rs b/crates/apub/src/activities/following/accept.rs index bfc9ba315..6fa65e7b1 100644 --- a/crates/apub/src/activities/following/accept.rs +++ b/crates/apub/src/activities/following/accept.rs @@ -7,6 +7,7 @@ use crate::{ }, context::lemmy_context, fetcher::object_id::ObjectId, + objects::{community::ApubCommunity, person::ApubPerson}, send_lemmy_activity, }; use activitystreams::{ @@ -21,13 +22,7 @@ use lemmy_apub_lib::{ traits::{ActivityFields, ActivityHandler, ActorType}, verify::verify_urls_match, }; -use lemmy_db_schema::{ - source::{ - community::{Community, CommunityFollower}, - person::Person, - }, - traits::Followable, -}; +use lemmy_db_schema::{source::community::CommunityFollower, traits::Followable}; use lemmy_utils::LemmyError; use lemmy_websocket::LemmyContext; use serde::{Deserialize, Serialize}; @@ -36,8 +31,8 @@ use url::Url; #[derive(Clone, Debug, Deserialize, Serialize, ActivityFields)] #[serde(rename_all = "camelCase")] pub struct AcceptFollowCommunity { - actor: ObjectId, - to: ObjectId, + actor: ObjectId, + to: ObjectId, object: FollowCommunity, #[serde(rename = "type")] kind: AcceptType, @@ -72,7 +67,7 @@ impl AcceptFollowCommunity { context: lemmy_context(), unparsed: Default::default(), }; - let inbox = vec![person.inbox_url.into()]; + let inbox = vec![person.inbox_url()]; send_lemmy_activity(context, &accept, &accept.id, &community, inbox, true).await } } diff --git a/crates/apub/src/activities/following/follow.rs b/crates/apub/src/activities/following/follow.rs index c75a08cd1..144243812 100644 --- a/crates/apub/src/activities/following/follow.rs +++ b/crates/apub/src/activities/following/follow.rs @@ -7,6 +7,7 @@ use crate::{ }, context::lemmy_context, fetcher::object_id::ObjectId, + objects::{community::ApubCommunity, person::ApubPerson}, send_lemmy_activity, }; use activitystreams::{ @@ -22,10 +23,7 @@ use lemmy_apub_lib::{ verify::verify_urls_match, }; use lemmy_db_schema::{ - source::{ - community::{Community, CommunityFollower, CommunityFollowerForm}, - person::Person, - }, + source::community::{CommunityFollower, CommunityFollowerForm}, traits::Followable, }; use lemmy_utils::LemmyError; @@ -36,10 +34,10 @@ use url::Url; #[derive(Clone, Debug, Deserialize, Serialize, ActivityFields)] #[serde(rename_all = "camelCase")] pub struct FollowCommunity { - pub(in crate::activities::following) actor: ObjectId, + pub(in crate::activities::following) actor: ObjectId, // TODO: is there any reason to put the same community id twice, in to and object? - pub(in crate::activities::following) to: ObjectId, - pub(in crate::activities::following) object: ObjectId, + pub(in crate::activities::following) to: ObjectId, + pub(in crate::activities::following) object: ObjectId, #[serde(rename = "type")] kind: FollowType, id: Url, @@ -51,8 +49,8 @@ pub struct FollowCommunity { impl FollowCommunity { pub(in crate::activities::following) fn new( - actor: &Person, - community: &Community, + actor: &ApubPerson, + community: &ApubCommunity, context: &LemmyContext, ) -> Result { Ok(FollowCommunity { @@ -69,8 +67,8 @@ impl FollowCommunity { }) } pub async fn send( - actor: &Person, - community: &Community, + actor: &ApubPerson, + community: &ApubCommunity, context: &LemmyContext, ) -> Result<(), LemmyError> { let community_follower_form = CommunityFollowerForm { diff --git a/crates/apub/src/activities/following/undo.rs b/crates/apub/src/activities/following/undo.rs index 2699a98c1..5c548ae48 100644 --- a/crates/apub/src/activities/following/undo.rs +++ b/crates/apub/src/activities/following/undo.rs @@ -7,6 +7,7 @@ use crate::{ }, context::lemmy_context, fetcher::object_id::ObjectId, + objects::{community::ApubCommunity, person::ApubPerson}, send_lemmy_activity, }; use activitystreams::{ @@ -22,10 +23,7 @@ use lemmy_apub_lib::{ verify::verify_urls_match, }; use lemmy_db_schema::{ - source::{ - community::{Community, CommunityFollower, CommunityFollowerForm}, - person::Person, - }, + source::community::{CommunityFollower, CommunityFollowerForm}, traits::Followable, }; use lemmy_utils::LemmyError; @@ -36,8 +34,8 @@ use url::Url; #[derive(Clone, Debug, Deserialize, Serialize, ActivityFields)] #[serde(rename_all = "camelCase")] pub struct UndoFollowCommunity { - actor: ObjectId, - to: ObjectId, + actor: ObjectId, + to: ObjectId, object: FollowCommunity, #[serde(rename = "type")] kind: UndoType, @@ -50,8 +48,8 @@ pub struct UndoFollowCommunity { impl UndoFollowCommunity { pub async fn send( - actor: &Person, - community: &Community, + actor: &ApubPerson, + community: &ApubCommunity, context: &LemmyContext, ) -> Result<(), LemmyError> { let object = FollowCommunity::new(actor, community, context)?; diff --git a/crates/apub/src/activities/mod.rs b/crates/apub/src/activities/mod.rs index 618c14f50..0832a85c8 100644 --- a/crates/apub/src/activities/mod.rs +++ b/crates/apub/src/activities/mod.rs @@ -3,15 +3,17 @@ use crate::{ check_is_apub_id_valid, fetcher::object_id::ObjectId, generate_moderators_url, + objects::{community::ApubCommunity, person::ApubPerson}, }; use anyhow::anyhow; use lemmy_api_common::blocking; use lemmy_apub_lib::{traits::ActivityFields, verify::verify_domains_match}; -use lemmy_db_schema::source::{community::Community, person::Person}; +use lemmy_db_schema::source::community::Community; use lemmy_db_views_actor::community_view::CommunityView; use lemmy_utils::{settings::structs::Settings, LemmyError}; use lemmy_websocket::LemmyContext; use serde::{Deserialize, Serialize}; +use std::ops::Deref; use strum_macros::ToString; use url::{ParseError, Url}; use uuid::Uuid; @@ -35,7 +37,7 @@ pub enum CreateOrUpdateType { /// Checks that the specified Url actually identifies a Person (by fetching it), and that the person /// doesn't have a site ban. async fn verify_person( - person_id: &ObjectId, + person_id: &ObjectId, context: &LemmyContext, request_counter: &mut i32, ) -> Result<(), LemmyError> { @@ -50,7 +52,7 @@ pub(crate) async fn extract_community( cc: &[Url], context: &LemmyContext, request_counter: &mut i32, -) -> Result { +) -> Result { let mut cc_iter = cc.iter(); loop { if let Some(cid) = cc_iter.next() { @@ -67,19 +69,19 @@ pub(crate) async fn extract_community( /// Fetches the person and community to verify their type, then checks if person is banned from site /// or community. pub(crate) async fn verify_person_in_community( - person_id: &ObjectId, - community_id: &ObjectId, + person_id: &ObjectId, + community_id: &ObjectId, context: &LemmyContext, request_counter: &mut i32, ) -> Result<(), LemmyError> { let community = community_id.dereference(context, request_counter).await?; let person = person_id.dereference(context, request_counter).await?; - check_community_or_site_ban(&person, community.id, context.pool()).await + check_community_or_site_ban(person.deref(), community.id, context.pool()).await } /// Simply check that the url actually refers to a valid group. async fn verify_community( - community_id: &ObjectId, + community_id: &ObjectId, context: &LemmyContext, request_counter: &mut i32, ) -> Result<(), LemmyError> { @@ -97,8 +99,8 @@ fn verify_activity(activity: &dyn ActivityFields, settings: &Settings) -> Result /// because in case of remote communities, admins can also perform mod actions. As admin status /// is not federated, we cant verify their actions remotely. pub(crate) async fn verify_mod_action( - actor_id: &ObjectId, - community_id: ObjectId, + actor_id: &ObjectId, + community_id: &ObjectId, context: &LemmyContext, request_counter: &mut i32, ) -> Result<(), LemmyError> { @@ -126,7 +128,7 @@ pub(crate) async fn verify_mod_action( /// /c/community/moderators. Any different values are unsupported. fn verify_add_remove_moderator_target( target: &Url, - community: &ObjectId, + community: &ObjectId, ) -> Result<(), LemmyError> { if target != &generate_moderators_url(&community.clone().into())?.into_inner() { return Err(anyhow!("Unkown target url").into()); diff --git a/crates/apub/src/activities/post/create_or_update.rs b/crates/apub/src/activities/post/create_or_update.rs index 7a1ddc406..cc7ef5c97 100644 --- a/crates/apub/src/activities/post/create_or_update.rs +++ b/crates/apub/src/activities/post/create_or_update.rs @@ -10,21 +10,22 @@ use crate::{ }, context::lemmy_context, fetcher::object_id::ObjectId, - objects::{post::Page, FromApub, ToApub}, + objects::{ + community::ApubCommunity, + person::ApubPerson, + post::{ApubPost, Page}, + }, }; use activitystreams::{base::AnyBase, primitives::OneOrMany, unparsed::Unparsed}; use anyhow::anyhow; use lemmy_api_common::blocking; use lemmy_apub_lib::{ data::Data, - traits::{ActivityFields, ActivityHandler, ActorType}, + traits::{ActivityFields, ActivityHandler, ActorType, FromApub, ToApub}, values::PublicUrl, verify::{verify_domains_match, verify_urls_match}, }; -use lemmy_db_schema::{ - source::{community::Community, person::Person, post::Post}, - traits::Crud, -}; +use lemmy_db_schema::{source::community::Community, traits::Crud}; use lemmy_utils::LemmyError; use lemmy_websocket::{send::send_post_ws_message, LemmyContext, UserOperationCrud}; use serde::{Deserialize, Serialize}; @@ -33,10 +34,10 @@ use url::Url; #[derive(Clone, Debug, Deserialize, Serialize, ActivityFields)] #[serde(rename_all = "camelCase")] pub struct CreateOrUpdatePost { - actor: ObjectId, + actor: ObjectId, to: [PublicUrl; 1], object: Page, - cc: [ObjectId; 1], + cc: [ObjectId; 1], #[serde(rename = "type")] kind: CreateOrUpdateType, id: Url, @@ -48,16 +49,17 @@ pub struct CreateOrUpdatePost { impl CreateOrUpdatePost { pub async fn send( - post: &Post, - actor: &Person, + post: &ApubPost, + actor: &ApubPerson, kind: CreateOrUpdateType, context: &LemmyContext, ) -> Result<(), LemmyError> { let community_id = post.community_id; - let community = blocking(context.pool(), move |conn| { + let community: ApubCommunity = blocking(context.pool(), move |conn| { Community::read(conn, community_id) }) - .await??; + .await?? + .into(); let id = generate_activity_id( kind.clone(), @@ -109,7 +111,7 @@ impl ActivityHandler for CreateOrUpdatePost { CreateOrUpdateType::Update => { let is_mod_action = self.object.is_mod_action(context).await?; if is_mod_action { - verify_mod_action(&self.actor, self.cc[0].clone(), context, request_counter).await?; + verify_mod_action(&self.actor, &self.cc[0], context, request_counter).await?; } else { verify_domains_match(self.actor.inner(), self.object.id_unchecked())?; verify_urls_match(self.actor(), self.object.attributed_to.inner())?; @@ -126,7 +128,8 @@ impl ActivityHandler for CreateOrUpdatePost { request_counter: &mut i32, ) -> Result<(), LemmyError> { let actor = self.actor.dereference(context, request_counter).await?; - let post = Post::from_apub(&self.object, context, &actor.actor_id(), request_counter).await?; + let post = + ApubPost::from_apub(&self.object, context, &actor.actor_id(), request_counter).await?; let notif_type = match self.kind { CreateOrUpdateType::Create => UserOperationCrud::CreatePost, diff --git a/crates/apub/src/activities/private_message/create_or_update.rs b/crates/apub/src/activities/private_message/create_or_update.rs index 6b3bc2b62..a1ee5598e 100644 --- a/crates/apub/src/activities/private_message/create_or_update.rs +++ b/crates/apub/src/activities/private_message/create_or_update.rs @@ -2,20 +2,20 @@ use crate::{ activities::{generate_activity_id, verify_activity, verify_person, CreateOrUpdateType}, context::lemmy_context, fetcher::object_id::ObjectId, - objects::{private_message::Note, FromApub, ToApub}, + objects::{ + person::ApubPerson, + private_message::{ApubPrivateMessage, Note}, + }, send_lemmy_activity, }; use activitystreams::{base::AnyBase, primitives::OneOrMany, unparsed::Unparsed}; use lemmy_api_common::blocking; use lemmy_apub_lib::{ data::Data, - traits::{ActivityFields, ActivityHandler, ActorType}, + traits::{ActivityFields, ActivityHandler, ActorType, FromApub, ToApub}, verify::verify_domains_match, }; -use lemmy_db_schema::{ - source::{person::Person, private_message::PrivateMessage}, - traits::Crud, -}; +use lemmy_db_schema::{source::person::Person, traits::Crud}; use lemmy_utils::LemmyError; use lemmy_websocket::{send::send_pm_ws_message, LemmyContext, UserOperationCrud}; use serde::{Deserialize, Serialize}; @@ -27,8 +27,8 @@ pub struct CreateOrUpdatePrivateMessage { #[serde(rename = "@context")] pub context: OneOrMany, id: Url, - actor: ObjectId, - to: ObjectId, + actor: ObjectId, + to: ObjectId, object: Note, #[serde(rename = "type")] kind: CreateOrUpdateType, @@ -38,14 +38,16 @@ pub struct CreateOrUpdatePrivateMessage { impl CreateOrUpdatePrivateMessage { pub async fn send( - private_message: &PrivateMessage, - actor: &Person, + private_message: &ApubPrivateMessage, + actor: &ApubPerson, kind: CreateOrUpdateType, context: &LemmyContext, ) -> Result<(), LemmyError> { let recipient_id = private_message.recipient_id; - let recipient = - blocking(context.pool(), move |conn| Person::read(conn, recipient_id)).await??; + let recipient: ApubPerson = + blocking(context.pool(), move |conn| Person::read(conn, recipient_id)) + .await?? + .into(); let id = generate_activity_id( kind.clone(), @@ -85,7 +87,8 @@ impl ActivityHandler for CreateOrUpdatePrivateMessage { request_counter: &mut i32, ) -> Result<(), LemmyError> { let private_message = - PrivateMessage::from_apub(&self.object, context, self.actor.inner(), request_counter).await?; + ApubPrivateMessage::from_apub(&self.object, context, self.actor.inner(), request_counter) + .await?; let notif_type = match self.kind { CreateOrUpdateType::Create => UserOperationCrud::CreatePrivateMessage, diff --git a/crates/apub/src/activities/private_message/delete.rs b/crates/apub/src/activities/private_message/delete.rs index ded3b3ad4..bb374eb47 100644 --- a/crates/apub/src/activities/private_message/delete.rs +++ b/crates/apub/src/activities/private_message/delete.rs @@ -2,6 +2,7 @@ use crate::{ activities::{generate_activity_id, verify_activity, verify_person}, context::lemmy_context, fetcher::object_id::ObjectId, + objects::{person::ApubPerson, private_message::ApubPrivateMessage}, send_lemmy_activity, }; use activitystreams::{ @@ -28,9 +29,9 @@ use url::Url; #[derive(Clone, Debug, Deserialize, Serialize, ActivityFields)] #[serde(rename_all = "camelCase")] pub struct DeletePrivateMessage { - actor: ObjectId, - to: ObjectId, - pub(in crate::activities::private_message) object: ObjectId, + actor: ObjectId, + to: ObjectId, + pub(in crate::activities::private_message) object: ObjectId, #[serde(rename = "type")] kind: DeleteType, id: Url, @@ -42,7 +43,7 @@ pub struct DeletePrivateMessage { impl DeletePrivateMessage { pub(in crate::activities::private_message) fn new( - actor: &Person, + actor: &ApubPerson, pm: &PrivateMessage, context: &LemmyContext, ) -> Result { @@ -60,16 +61,18 @@ impl DeletePrivateMessage { }) } pub async fn send( - actor: &Person, - pm: &PrivateMessage, + actor: &ApubPerson, + pm: &ApubPrivateMessage, context: &LemmyContext, ) -> Result<(), LemmyError> { let delete = DeletePrivateMessage::new(actor, pm, context)?; let delete_id = delete.id.clone(); let recipient_id = pm.recipient_id; - let recipient = - blocking(context.pool(), move |conn| Person::read(conn, recipient_id)).await??; + let recipient: ApubPerson = + blocking(context.pool(), move |conn| Person::read(conn, recipient_id)) + .await?? + .into(); let inbox = vec![recipient.shared_inbox_or_inbox_url()]; send_lemmy_activity(context, &delete, &delete_id, actor, inbox, true).await } diff --git a/crates/apub/src/activities/private_message/undo_delete.rs b/crates/apub/src/activities/private_message/undo_delete.rs index 2c5fd0e72..0263b8115 100644 --- a/crates/apub/src/activities/private_message/undo_delete.rs +++ b/crates/apub/src/activities/private_message/undo_delete.rs @@ -7,6 +7,7 @@ use crate::{ }, context::lemmy_context, fetcher::object_id::ObjectId, + objects::{person::ApubPerson, private_message::ApubPrivateMessage}, send_lemmy_activity, }; use activitystreams::{ @@ -33,8 +34,8 @@ use url::Url; #[derive(Clone, Debug, Deserialize, Serialize, ActivityFields)] #[serde(rename_all = "camelCase")] pub struct UndoDeletePrivateMessage { - actor: ObjectId, - to: ObjectId, + actor: ObjectId, + to: ObjectId, object: DeletePrivateMessage, #[serde(rename = "type")] kind: UndoType, @@ -47,13 +48,15 @@ pub struct UndoDeletePrivateMessage { impl UndoDeletePrivateMessage { pub async fn send( - actor: &Person, - pm: &PrivateMessage, + actor: &ApubPerson, + pm: &ApubPrivateMessage, context: &LemmyContext, ) -> Result<(), LemmyError> { let recipient_id = pm.recipient_id; - let recipient = - blocking(context.pool(), move |conn| Person::read(conn, recipient_id)).await??; + let recipient: ApubPerson = + blocking(context.pool(), move |conn| Person::read(conn, recipient_id)) + .await?? + .into(); let object = DeletePrivateMessage::new(actor, pm, context)?; let id = generate_activity_id( diff --git a/crates/apub/src/activities/report.rs b/crates/apub/src/activities/report.rs index aee673cfa..d0b1f971c 100644 --- a/crates/apub/src/activities/report.rs +++ b/crates/apub/src/activities/report.rs @@ -2,6 +2,7 @@ use crate::{ activities::{generate_activity_id, verify_activity, verify_person_in_community}, context::lemmy_context, fetcher::object_id::ObjectId, + objects::{community::ApubCommunity, person::ApubPerson}, send_lemmy_activity, PostOrComment, }; @@ -17,14 +18,11 @@ use lemmy_apub_lib::{ traits::{ActivityFields, ActivityHandler, ActorType}, }; use lemmy_db_schema::{ - newtypes::CommunityId, source::{ comment_report::{CommentReport, CommentReportForm}, - community::Community, - person::Person, post_report::{PostReport, PostReportForm}, }, - traits::{Crud, Reportable}, + traits::Reportable, }; use lemmy_db_views::{comment_report_view::CommentReportView, post_report_view::PostReportView}; use lemmy_utils::LemmyError; @@ -35,8 +33,8 @@ use url::Url; #[derive(Clone, Debug, Deserialize, Serialize, ActivityFields)] #[serde(rename_all = "camelCase")] pub struct Report { - actor: ObjectId, - to: [ObjectId; 1], + actor: ObjectId, + to: [ObjectId; 1], object: ObjectId, summary: String, #[serde(rename = "type")] @@ -51,15 +49,12 @@ pub struct Report { impl Report { pub async fn send( object_id: ObjectId, - actor: &Person, - community_id: CommunityId, + actor: &ApubPerson, + community_id: ObjectId, reason: String, context: &LemmyContext, ) -> Result<(), LemmyError> { - let community = blocking(context.pool(), move |conn| { - Community::read(conn, community_id) - }) - .await??; + let community = community_id.dereference_local(context).await?; let kind = FlagType::Flag; let id = generate_activity_id( kind.clone(), @@ -111,10 +106,10 @@ impl ActivityHandler for Report { let report_form = PostReportForm { creator_id: actor.id, post_id: post.id, - original_post_name: post.name, - original_post_url: post.url, + original_post_name: post.name.clone(), + original_post_url: post.url.clone(), reason: self.summary, - original_post_body: post.body, + original_post_body: post.body.clone(), }; let report = blocking(context.pool(), move |conn| { @@ -138,7 +133,7 @@ impl ActivityHandler for Report { let report_form = CommentReportForm { creator_id: actor.id, comment_id: comment.id, - original_comment_text: comment.content, + original_comment_text: comment.content.clone(), reason: self.summary, }; diff --git a/crates/apub/src/activities/undo_remove.rs b/crates/apub/src/activities/undo_remove.rs index 10305466c..5b41e0868 100644 --- a/crates/apub/src/activities/undo_remove.rs +++ b/crates/apub/src/activities/undo_remove.rs @@ -5,6 +5,7 @@ use crate::{ verify_activity, }, fetcher::object_id::ObjectId, + objects::{community::ApubCommunity, person::ApubPerson}, }; use activitystreams::{ activity::kind::UndoType, @@ -17,7 +18,6 @@ use lemmy_apub_lib::{ traits::{ActivityFields, ActivityHandler}, values::PublicUrl, }; -use lemmy_db_schema::source::{community::Community, person::Person}; use lemmy_utils::LemmyError; use lemmy_websocket::LemmyContext; use serde::{Deserialize, Serialize}; @@ -26,11 +26,11 @@ use url::Url; #[derive(Clone, Debug, Deserialize, Serialize, ActivityFields)] #[serde(rename_all = "camelCase")] pub struct UndoRemovePostCommentOrCommunity { - actor: ObjectId, + actor: ObjectId, to: [PublicUrl; 1], // Note, there is no such thing as Undo/Remove/Mod, so we ignore that object: RemoveMod, - cc: [ObjectId; 1], + cc: [ObjectId; 1], #[serde(rename = "type")] kind: UndoType, id: Url, diff --git a/crates/apub/src/activities/voting/mod.rs b/crates/apub/src/activities/voting/mod.rs index 90757eebf..829553d35 100644 --- a/crates/apub/src/activities/voting/mod.rs +++ b/crates/apub/src/activities/voting/mod.rs @@ -1,10 +1,12 @@ -use crate::activities::voting::vote::VoteType; +use crate::{ + activities::voting::vote::VoteType, + objects::{comment::ApubComment, person::ApubPerson, post::ApubPost}, +}; use lemmy_api_common::blocking; use lemmy_db_schema::{ source::{ - comment::{Comment, CommentLike, CommentLikeForm}, - person::Person, - post::{Post, PostLike, PostLikeForm}, + comment::{CommentLike, CommentLikeForm}, + post::{PostLike, PostLikeForm}, }, traits::Likeable, }; @@ -20,8 +22,8 @@ pub mod vote; async fn vote_comment( vote_type: &VoteType, - actor: Person, - comment: &Comment, + actor: ApubPerson, + comment: &ApubComment, context: &LemmyContext, ) -> Result<(), LemmyError> { let comment_id = comment.id; @@ -44,8 +46,8 @@ async fn vote_comment( async fn vote_post( vote_type: &VoteType, - actor: Person, - post: &Post, + actor: ApubPerson, + post: &ApubPost, context: &LemmyContext, ) -> Result<(), LemmyError> { let post_id = post.id; @@ -66,8 +68,8 @@ async fn vote_post( } async fn undo_vote_comment( - actor: Person, - comment: &Comment, + actor: ApubPerson, + comment: &ApubComment, context: &LemmyContext, ) -> Result<(), LemmyError> { let comment_id = comment.id; @@ -82,8 +84,8 @@ async fn undo_vote_comment( } async fn undo_vote_post( - actor: Person, - post: &Post, + actor: ApubPerson, + post: &ApubPost, context: &LemmyContext, ) -> Result<(), LemmyError> { let post_id = post.id; diff --git a/crates/apub/src/activities/voting/undo_vote.rs b/crates/apub/src/activities/voting/undo_vote.rs index 2c87aa899..d72b5245d 100644 --- a/crates/apub/src/activities/voting/undo_vote.rs +++ b/crates/apub/src/activities/voting/undo_vote.rs @@ -12,6 +12,7 @@ use crate::{ }, context::lemmy_context, fetcher::object_id::ObjectId, + objects::{community::ApubCommunity, person::ApubPerson}, PostOrComment, }; use activitystreams::{ @@ -27,11 +28,7 @@ use lemmy_apub_lib::{ values::PublicUrl, verify::verify_urls_match, }; -use lemmy_db_schema::{ - newtypes::CommunityId, - source::{community::Community, person::Person}, - traits::Crud, -}; +use lemmy_db_schema::{newtypes::CommunityId, source::community::Community, traits::Crud}; use lemmy_utils::LemmyError; use lemmy_websocket::LemmyContext; use serde::{Deserialize, Serialize}; @@ -41,10 +38,10 @@ use url::Url; #[derive(Clone, Debug, Deserialize, Serialize, ActivityFields)] #[serde(rename_all = "camelCase")] pub struct UndoVote { - actor: ObjectId, + actor: ObjectId, to: [PublicUrl; 1], object: Vote, - cc: [ObjectId; 1], + cc: [ObjectId; 1], #[serde(rename = "type")] kind: UndoType, id: Url, @@ -57,15 +54,16 @@ pub struct UndoVote { impl UndoVote { pub async fn send( object: &PostOrComment, - actor: &Person, + actor: &ApubPerson, community_id: CommunityId, kind: VoteType, context: &LemmyContext, ) -> Result<(), LemmyError> { - let community = blocking(context.pool(), move |conn| { + let community: ApubCommunity = blocking(context.pool(), move |conn| { Community::read(conn, community_id) }) - .await??; + .await?? + .into(); let object = Vote::new(object, actor, &community, kind.clone(), context)?; let id = generate_activity_id( diff --git a/crates/apub/src/activities/voting/vote.rs b/crates/apub/src/activities/voting/vote.rs index 2463cbc02..5d4c9066e 100644 --- a/crates/apub/src/activities/voting/vote.rs +++ b/crates/apub/src/activities/voting/vote.rs @@ -8,6 +8,7 @@ use crate::{ }, context::lemmy_context, fetcher::object_id::ObjectId, + objects::{community::ApubCommunity, person::ApubPerson}, PostOrComment, }; use activitystreams::{base::AnyBase, primitives::OneOrMany, unparsed::Unparsed}; @@ -18,11 +19,7 @@ use lemmy_apub_lib::{ traits::{ActivityFields, ActivityHandler, ActorType}, values::PublicUrl, }; -use lemmy_db_schema::{ - newtypes::CommunityId, - source::{community::Community, person::Person}, - traits::Crud, -}; +use lemmy_db_schema::{newtypes::CommunityId, source::community::Community, traits::Crud}; use lemmy_utils::LemmyError; use lemmy_websocket::LemmyContext; use serde::{Deserialize, Serialize}; @@ -60,10 +57,10 @@ impl From<&VoteType> for i16 { #[derive(Clone, Debug, Deserialize, Serialize, ActivityFields)] #[serde(rename_all = "camelCase")] pub struct Vote { - actor: ObjectId, + actor: ObjectId, to: [PublicUrl; 1], pub(in crate::activities::voting) object: ObjectId, - cc: [ObjectId; 1], + cc: [ObjectId; 1], #[serde(rename = "type")] pub(in crate::activities::voting) kind: VoteType, id: Url, @@ -76,8 +73,8 @@ pub struct Vote { impl Vote { pub(in crate::activities::voting) fn new( object: &PostOrComment, - actor: &Person, - community: &Community, + actor: &ApubPerson, + community: &ApubCommunity, kind: VoteType, context: &LemmyContext, ) -> Result { @@ -95,7 +92,7 @@ impl Vote { pub async fn send( object: &PostOrComment, - actor: &Person, + actor: &ApubPerson, community_id: CommunityId, kind: VoteType, context: &LemmyContext, @@ -103,7 +100,8 @@ impl Vote { let community = blocking(context.pool(), move |conn| { Community::read(conn, community_id) }) - .await??; + .await?? + .into(); let vote = Vote::new(object, actor, &community, kind, context)?; let vote_id = vote.id.clone(); diff --git a/crates/apub/src/fetcher/community.rs b/crates/apub/src/fetcher/community.rs index 646f8fcad..aff571b70 100644 --- a/crates/apub/src/fetcher/community.rs +++ b/crates/apub/src/fetcher/community.rs @@ -1,17 +1,14 @@ use crate::{ activities::community::announce::AnnounceActivity, fetcher::{fetch::fetch_remote_object, object_id::ObjectId}, - objects::community::Group, + objects::{community::Group, person::ApubPerson}, }; use activitystreams::collection::{CollectionExt, OrderedCollection}; use anyhow::Context; use lemmy_api_common::blocking; use lemmy_apub_lib::{data::Data, traits::ActivityHandler}; use lemmy_db_schema::{ - source::{ - community::{Community, CommunityModerator, CommunityModeratorForm}, - person::Person, - }, + source::community::{Community, CommunityModerator, CommunityModeratorForm}, traits::Joinable, }; use lemmy_db_views_actor::community_moderator_view::CommunityModeratorView; @@ -48,7 +45,7 @@ pub(crate) async fn update_community_mods( // Add new mods to database which have been added to moderators collection for mod_id in new_moderators { let mod_id = ObjectId::new(mod_id); - let mod_user: Person = mod_id.dereference(context, request_counter).await?; + let mod_user: ApubPerson = mod_id.dereference(context, request_counter).await?; if !current_moderators .clone() diff --git a/crates/apub/src/fetcher/mod.rs b/crates/apub/src/fetcher/mod.rs index 641d59f02..fd6b982c3 100644 --- a/crates/apub/src/fetcher/mod.rs +++ b/crates/apub/src/fetcher/mod.rs @@ -4,13 +4,13 @@ pub mod object_id; pub mod post_or_comment; pub mod search; -use crate::fetcher::object_id::ObjectId; +use crate::{ + fetcher::object_id::ObjectId, + objects::{community::ApubCommunity, person::ApubPerson}, +}; use chrono::NaiveDateTime; use lemmy_apub_lib::traits::ActorType; -use lemmy_db_schema::{ - naive_now, - source::{community::Community, person::Person}, -}; +use lemmy_db_schema::naive_now; use lemmy_utils::LemmyError; use lemmy_websocket::LemmyContext; use url::Url; @@ -28,13 +28,13 @@ pub(crate) async fn get_or_fetch_and_upsert_actor( context: &LemmyContext, recursion_counter: &mut i32, ) -> Result, LemmyError> { - let community_id = ObjectId::::new(apub_id.clone()); + let community_id = ObjectId::::new(apub_id.clone()); let community = community_id.dereference(context, recursion_counter).await; let actor: Box = match community { Ok(c) => Box::new(c), Err(_) => { let person_id = ObjectId::new(apub_id); - let person: Person = person_id.dereference(context, recursion_counter).await?; + let person: ApubPerson = person_id.dereference(context, recursion_counter).await?; Box::new(person) } }; diff --git a/crates/apub/src/fetcher/object_id.rs b/crates/apub/src/fetcher/object_id.rs index 771c276a5..4e439fb7f 100644 --- a/crates/apub/src/fetcher/object_id.rs +++ b/crates/apub/src/fetcher/object_id.rs @@ -1,9 +1,11 @@ -use crate::{fetcher::should_refetch_actor, objects::FromApub}; +use crate::fetcher::should_refetch_actor; use anyhow::anyhow; -use diesel::{NotFound, PgConnection}; -use lemmy_api_common::blocking; -use lemmy_apub_lib::{traits::ApubObject, APUB_JSON_CONTENT_TYPE}; -use lemmy_db_schema::{newtypes::DbUrl, DbPool}; +use diesel::NotFound; +use lemmy_apub_lib::{ + traits::{ApubObject, FromApub}, + APUB_JSON_CONTENT_TYPE, +}; +use lemmy_db_schema::newtypes::DbUrl; use lemmy_utils::{request::retry, settings::structs::Settings, LemmyError}; use lemmy_websocket::LemmyContext; use reqwest::StatusCode; @@ -22,12 +24,12 @@ static REQUEST_LIMIT: i32 = 25; #[derive(Clone, PartialEq, Serialize, Deserialize, Debug)] pub struct ObjectId(Url, #[serde(skip)] PhantomData) where - Kind: FromApub + ApubObject + Send + 'static, + Kind: FromApub + ApubObject + Send + 'static, for<'de2> ::ApubType: serde::Deserialize<'de2>; impl ObjectId where - Kind: FromApub + ApubObject + Send + 'static, + Kind: FromApub + ApubObject + Send + 'static, for<'de> ::ApubType: serde::Deserialize<'de>, { pub fn new(url: T) -> Self @@ -47,7 +49,7 @@ where context: &LemmyContext, request_counter: &mut i32, ) -> Result { - let db_object = self.dereference_from_db(context.pool()).await?; + let db_object = self.dereference_from_db(context).await?; // if its a local object, only fetch it from the database and not over http if self.0.domain() == Some(&Settings::get().get_hostname_without_port()?) { @@ -77,14 +79,14 @@ where /// Fetch an object from the local db. Instead of falling back to http, this throws an error if /// the object is not found in the database. pub async fn dereference_local(&self, context: &LemmyContext) -> Result { - let object = self.dereference_from_db(context.pool()).await?; + let object = self.dereference_from_db(context).await?; object.ok_or_else(|| anyhow!("object not found in database {}", self).into()) } /// returning none means the object was not found in local db - async fn dereference_from_db(&self, pool: &DbPool) -> Result, LemmyError> { + async fn dereference_from_db(&self, context: &LemmyContext) -> Result, LemmyError> { let id = self.0.clone(); - blocking(pool, move |conn| ApubObject::read_from_apub_id(conn, id)).await? + ApubObject::read_from_apub_id(id, context).await } async fn dereference_from_http( @@ -113,7 +115,7 @@ where if res.status() == StatusCode::GONE { if let Some(db_object) = db_object { - blocking(context.pool(), move |conn| db_object.delete(conn)).await??; + db_object.delete(context).await?; } return Err(anyhow!("Fetched remote object {} which was deleted", self).into()); } @@ -126,7 +128,7 @@ where impl Display for ObjectId where - Kind: FromApub + ApubObject + Send + 'static, + Kind: FromApub + ApubObject + Send + 'static, for<'de> ::ApubType: serde::Deserialize<'de>, { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { @@ -136,7 +138,7 @@ where impl From> for Url where - Kind: FromApub + ApubObject + Send + 'static, + Kind: FromApub + ApubObject + Send + 'static, for<'de> ::ApubType: serde::Deserialize<'de>, { fn from(id: ObjectId) -> Self { @@ -146,7 +148,7 @@ where impl From> for DbUrl where - Kind: FromApub + ApubObject + Send + 'static, + Kind: FromApub + ApubObject + Send + 'static, for<'de> ::ApubType: serde::Deserialize<'de>, { fn from(id: ObjectId) -> Self { diff --git a/crates/apub/src/fetcher/post_or_comment.rs b/crates/apub/src/fetcher/post_or_comment.rs index 9d700c960..fd78ad79a 100644 --- a/crates/apub/src/fetcher/post_or_comment.rs +++ b/crates/apub/src/fetcher/post_or_comment.rs @@ -1,11 +1,10 @@ -use crate::objects::{comment::Note, post::Page, FromApub}; -use activitystreams::chrono::NaiveDateTime; -use diesel::PgConnection; -use lemmy_apub_lib::traits::ApubObject; -use lemmy_db_schema::source::{ - comment::{Comment, CommentForm}, - post::{Post, PostForm}, +use crate::objects::{ + comment::{ApubComment, Note}, + post::{ApubPost, Page}, }; +use activitystreams::chrono::NaiveDateTime; +use lemmy_apub_lib::traits::{ApubObject, FromApub}; +use lemmy_db_schema::source::{comment::CommentForm, post::PostForm}; use lemmy_utils::LemmyError; use lemmy_websocket::LemmyContext; use serde::Deserialize; @@ -13,8 +12,8 @@ use url::Url; #[derive(Clone, Debug)] pub enum PostOrComment { - Post(Box), - Comment(Comment), + Post(Box), + Comment(ApubComment), } pub enum PostOrCommentForm { @@ -31,28 +30,33 @@ pub enum PageOrNote { #[async_trait::async_trait(?Send)] impl ApubObject for PostOrComment { - type DataType = PgConnection; + type DataType = LemmyContext; fn last_refreshed_at(&self) -> Option { None } // TODO: this can probably be implemented using a single sql query - fn read_from_apub_id(conn: &PgConnection, object_id: Url) -> Result, LemmyError> + async fn read_from_apub_id( + object_id: Url, + data: &Self::DataType, + ) -> Result, LemmyError> where Self: Sized, { - let post = Post::read_from_apub_id(conn, object_id.clone())?; + let post = ApubPost::read_from_apub_id(object_id.clone(), data).await?; Ok(match post { Some(o) => Some(PostOrComment::Post(Box::new(o))), - None => Comment::read_from_apub_id(conn, object_id)?.map(PostOrComment::Comment), + None => ApubComment::read_from_apub_id(object_id, data) + .await? + .map(PostOrComment::Comment), }) } - fn delete(self, data: &Self::DataType) -> Result<(), LemmyError> { + async fn delete(self, data: &Self::DataType) -> Result<(), LemmyError> { match self { - PostOrComment::Post(p) => p.delete(data), - PostOrComment::Comment(c) => c.delete(data), + PostOrComment::Post(p) => p.delete(data).await, + PostOrComment::Comment(c) => c.delete(data).await, } } } @@ -60,6 +64,7 @@ impl ApubObject for PostOrComment { #[async_trait::async_trait(?Send)] impl FromApub for PostOrComment { type ApubType = PageOrNote; + type DataType = LemmyContext; async fn from_apub( apub: &PageOrNote, @@ -72,10 +77,10 @@ impl FromApub for PostOrComment { { Ok(match apub { PageOrNote::Page(p) => PostOrComment::Post(Box::new( - Post::from_apub(p, context, expected_domain, request_counter).await?, + ApubPost::from_apub(p, context, expected_domain, request_counter).await?, )), PageOrNote::Note(n) => PostOrComment::Comment( - Comment::from_apub(n, context, expected_domain, request_counter).await?, + ApubComment::from_apub(n, context, expected_domain, request_counter).await?, ), }) } diff --git a/crates/apub/src/fetcher/search.rs b/crates/apub/src/fetcher/search.rs index d7b9a0bfd..c67eaa0ff 100644 --- a/crates/apub/src/fetcher/search.rs +++ b/crates/apub/src/fetcher/search.rs @@ -1,18 +1,22 @@ use crate::{ fetcher::object_id::ObjectId, - objects::{comment::Note, community::Group, person::Person as ApubPerson, post::Page, FromApub}, + objects::{ + comment::{ApubComment, Note}, + community::{ApubCommunity, Group}, + person::{ApubPerson, Person}, + post::{ApubPost, Page}, + }, }; use activitystreams::chrono::NaiveDateTime; use anyhow::anyhow; -use diesel::PgConnection; use itertools::Itertools; use lemmy_api_common::blocking; use lemmy_apub_lib::{ - traits::ApubObject, + traits::{ApubObject, FromApub}, webfinger::{webfinger_resolve_actor, WebfingerType}, }; use lemmy_db_schema::{ - source::{comment::Comment, community::Community, person::Person, post::Post}, + source::{community::Community, person::Person as DbPerson}, DbPool, }; use lemmy_utils::LemmyError; @@ -73,10 +77,14 @@ async fn find_local_actor_by_name( let name: String = name.into(); Ok(match kind { WebfingerType::Group => SearchableObjects::Community( - blocking(pool, move |conn| Community::read_from_name(conn, &name)).await??, + blocking(pool, move |conn| Community::read_from_name(conn, &name)) + .await?? + .into(), ), WebfingerType::Person => SearchableObjects::Person( - blocking(pool, move |conn| Person::find_by_name(conn, &name)).await??, + blocking(pool, move |conn| DbPerson::find_by_name(conn, &name)) + .await?? + .into(), ), }) } @@ -84,23 +92,24 @@ async fn find_local_actor_by_name( /// The types of ActivityPub objects that can be fetched directly by searching for their ID. #[derive(Debug)] pub enum SearchableObjects { - Person(Person), - Community(Community), - Post(Post), - Comment(Comment), + Person(ApubPerson), + Community(ApubCommunity), + Post(ApubPost), + Comment(ApubComment), } #[derive(Deserialize)] #[serde(untagged)] pub enum SearchableApubTypes { Group(Group), - Person(ApubPerson), + Person(Person), Page(Page), Note(Note), } +#[async_trait::async_trait(?Send)] impl ApubObject for SearchableObjects { - type DataType = PgConnection; + type DataType = LemmyContext; fn last_refreshed_at(&self) -> Option { match self { @@ -116,32 +125,35 @@ impl ApubObject for SearchableObjects { // a single query. // we could skip this and always return an error, but then it would always fetch objects // over http, and not be able to mark objects as deleted that were deleted by remote server. - fn read_from_apub_id(conn: &PgConnection, object_id: Url) -> Result, LemmyError> { - let c = Community::read_from_apub_id(conn, object_id.clone())?; + async fn read_from_apub_id( + object_id: Url, + context: &LemmyContext, + ) -> Result, LemmyError> { + let c = ApubCommunity::read_from_apub_id(object_id.clone(), context).await?; if let Some(c) = c { return Ok(Some(SearchableObjects::Community(c))); } - let p = Person::read_from_apub_id(conn, object_id.clone())?; + let p = ApubPerson::read_from_apub_id(object_id.clone(), context).await?; if let Some(p) = p { return Ok(Some(SearchableObjects::Person(p))); } - let p = Post::read_from_apub_id(conn, object_id.clone())?; + let p = ApubPost::read_from_apub_id(object_id.clone(), context).await?; if let Some(p) = p { return Ok(Some(SearchableObjects::Post(p))); } - let c = Comment::read_from_apub_id(conn, object_id)?; + let c = ApubComment::read_from_apub_id(object_id, context).await?; if let Some(c) = c { return Ok(Some(SearchableObjects::Comment(c))); } Ok(None) } - fn delete(self, conn: &Self::DataType) -> Result<(), LemmyError> { + async fn delete(self, data: &Self::DataType) -> Result<(), LemmyError> { match self { - SearchableObjects::Person(p) => p.delete(conn), - SearchableObjects::Community(c) => c.delete(conn), - SearchableObjects::Post(p) => p.delete(conn), - SearchableObjects::Comment(c) => c.delete(conn), + SearchableObjects::Person(p) => p.delete(data).await, + SearchableObjects::Community(c) => c.delete(data).await, + SearchableObjects::Post(p) => p.delete(data).await, + SearchableObjects::Comment(c) => c.delete(data).await, } } } @@ -149,6 +161,7 @@ impl ApubObject for SearchableObjects { #[async_trait::async_trait(?Send)] impl FromApub for SearchableObjects { type ApubType = SearchableApubTypes; + type DataType = LemmyContext; async fn from_apub( apub: &Self::ApubType, @@ -159,10 +172,10 @@ impl FromApub for SearchableObjects { use SearchableApubTypes as SAT; use SearchableObjects as SO; Ok(match apub { - SAT::Group(g) => SO::Community(Community::from_apub(g, context, ed, rc).await?), - SAT::Person(p) => SO::Person(Person::from_apub(p, context, ed, rc).await?), - SAT::Page(p) => SO::Post(Post::from_apub(p, context, ed, rc).await?), - SAT::Note(n) => SO::Comment(Comment::from_apub(n, context, ed, rc).await?), + SAT::Group(g) => SO::Community(ApubCommunity::from_apub(g, context, ed, rc).await?), + SAT::Person(p) => SO::Person(ApubPerson::from_apub(p, context, ed, rc).await?), + SAT::Page(p) => SO::Post(ApubPost::from_apub(p, context, ed, rc).await?), + SAT::Note(n) => SO::Comment(ApubComment::from_apub(n, context, ed, rc).await?), }) } } diff --git a/crates/apub/src/http/comment.rs b/crates/apub/src/http/comment.rs index 769a9dd85..58543a5bb 100644 --- a/crates/apub/src/http/comment.rs +++ b/crates/apub/src/http/comment.rs @@ -1,10 +1,11 @@ use crate::{ http::{create_apub_response, create_apub_tombstone_response}, - objects::ToApub, + objects::comment::ApubComment, }; use actix_web::{body::Body, web, web::Path, HttpResponse}; use diesel::result::Error::NotFound; use lemmy_api_common::blocking; +use lemmy_apub_lib::traits::ToApub; use lemmy_db_schema::{newtypes::CommentId, source::comment::Comment, traits::Crud}; use lemmy_utils::LemmyError; use lemmy_websocket::LemmyContext; @@ -21,7 +22,9 @@ pub(crate) async fn get_apub_comment( context: web::Data, ) -> Result, LemmyError> { let id = CommentId(info.comment_id.parse::()?); - let comment = blocking(context.pool(), move |conn| Comment::read(conn, id)).await??; + let comment: ApubComment = blocking(context.pool(), move |conn| Comment::read(conn, id)) + .await?? + .into(); if !comment.local { return Err(NotFound.into()); } diff --git a/crates/apub/src/http/community.rs b/crates/apub/src/http/community.rs index 2094d15d3..7c66ca9db 100644 --- a/crates/apub/src/http/community.rs +++ b/crates/apub/src/http/community.rs @@ -14,7 +14,7 @@ use crate::{ payload_to_string, receive_activity, }, - objects::ToApub, + objects::community::ApubCommunity, }; use activitystreams::{ base::{AnyBase, BaseExt}, @@ -23,7 +23,7 @@ use activitystreams::{ }; use actix_web::{body::Body, web, web::Payload, HttpRequest, HttpResponse}; use lemmy_api_common::blocking; -use lemmy_apub_lib::traits::{ActivityFields, ActivityHandler}; +use lemmy_apub_lib::traits::{ActivityFields, ActivityHandler, ToApub}; use lemmy_db_schema::source::{activity::Activity, community::Community}; use lemmy_db_views_actor::{ community_follower_view::CommunityFollowerView, @@ -44,10 +44,11 @@ pub(crate) async fn get_apub_community_http( info: web::Path, context: web::Data, ) -> Result, LemmyError> { - let community = blocking(context.pool(), move |conn| { + let community: ApubCommunity = blocking(context.pool(), move |conn| { Community::read_from_name(conn, &info.community_name) }) - .await??; + .await?? + .into(); if !community.deleted { let apub = community.to_apub(context.pool()).await?; @@ -173,10 +174,11 @@ pub(crate) async fn get_apub_community_moderators( info: web::Path, context: web::Data, ) -> Result, LemmyError> { - let community = blocking(context.pool(), move |conn| { + let community: ApubCommunity = blocking(context.pool(), move |conn| { Community::read_from_name(conn, &info.community_name) }) - .await??; + .await?? + .into(); // The attributed to, is an ordered vector with the creator actor_ids first, // then the rest of the moderators diff --git a/crates/apub/src/http/person.rs b/crates/apub/src/http/person.rs index 36b6b7d9d..16f1bc5c4 100644 --- a/crates/apub/src/http/person.rs +++ b/crates/apub/src/http/person.rs @@ -16,7 +16,7 @@ use crate::{ payload_to_string, receive_activity, }, - objects::ToApub, + objects::person::ApubPerson, }; use activitystreams::{ base::BaseExt, @@ -24,7 +24,7 @@ use activitystreams::{ }; use actix_web::{body::Body, web, web::Payload, HttpRequest, HttpResponse}; use lemmy_api_common::blocking; -use lemmy_apub_lib::traits::{ActivityFields, ActivityHandler}; +use lemmy_apub_lib::traits::{ActivityFields, ActivityHandler, ToApub}; use lemmy_db_schema::source::person::Person; use lemmy_utils::LemmyError; use lemmy_websocket::LemmyContext; @@ -44,10 +44,11 @@ pub(crate) async fn get_apub_person_http( ) -> Result, LemmyError> { let user_name = info.into_inner().user_name; // TODO: this needs to be able to read deleted persons, so that it can send tombstones - let person = blocking(context.pool(), move |conn| { + let person: ApubPerson = blocking(context.pool(), move |conn| { Person::find_by_name(conn, &user_name) }) - .await??; + .await?? + .into(); if !person.deleted { let apub = person.to_apub(context.pool()).await?; diff --git a/crates/apub/src/http/post.rs b/crates/apub/src/http/post.rs index c5f22d01c..2ce712bc9 100644 --- a/crates/apub/src/http/post.rs +++ b/crates/apub/src/http/post.rs @@ -1,10 +1,11 @@ use crate::{ http::{create_apub_response, create_apub_tombstone_response}, - objects::ToApub, + objects::post::ApubPost, }; use actix_web::{body::Body, web, HttpResponse}; use diesel::result::Error::NotFound; use lemmy_api_common::blocking; +use lemmy_apub_lib::traits::ToApub; use lemmy_db_schema::{newtypes::PostId, source::post::Post, traits::Crud}; use lemmy_utils::LemmyError; use lemmy_websocket::LemmyContext; @@ -21,7 +22,9 @@ pub(crate) async fn get_apub_post( context: web::Data, ) -> Result, LemmyError> { let id = PostId(info.post_id.parse::()?); - let post = blocking(context.pool(), move |conn| Post::read(conn, id)).await??; + let post: ApubPost = blocking(context.pool(), move |conn| Post::read(conn, id)) + .await?? + .into(); if !post.local { return Err(NotFound.into()); } diff --git a/crates/apub/src/objects/comment.rs b/crates/apub/src/objects/comment.rs index 1748af791..5745778c7 100644 --- a/crates/apub/src/objects/comment.rs +++ b/crates/apub/src/objects/comment.rs @@ -3,11 +3,12 @@ use crate::{ context::lemmy_context, fetcher::object_id::ObjectId, migrations::CommentInReplyToMigration, - objects::{create_tombstone, FromApub, Source, ToApub}, + objects::{create_tombstone, person::ApubPerson, post::ApubPost, Source}, PostOrComment, }; use activitystreams::{ base::AnyBase, + chrono::NaiveDateTime, object::{kind::NoteType, Tombstone}, primitives::OneOrMany, unparsed::Unparsed, @@ -16,7 +17,7 @@ use anyhow::{anyhow, Context}; use chrono::{DateTime, FixedOffset}; use lemmy_api_common::blocking; use lemmy_apub_lib::{ - traits::ActorType, + traits::{ApubObject, FromApub, ToApub}, values::{MediaTypeHtml, MediaTypeMarkdown, PublicUrl}, verify::verify_domains_match, }; @@ -50,7 +51,7 @@ pub struct Note { context: OneOrMany, r#type: NoteType, id: Url, - pub(crate) attributed_to: ObjectId, + pub(crate) attributed_to: ObjectId, /// Indicates that the object is publicly readable. Unlike [`Post.to`], this one doesn't contain /// the community ID, as it would be incompatible with Pleroma (and we can get the community from /// the post in [`in_reply_to`]). @@ -78,7 +79,7 @@ impl Note { &self, context: &LemmyContext, request_counter: &mut i32, - ) -> Result<(Post, Option), LemmyError> { + ) -> Result<(ApubPost, Option), LemmyError> { match &self.in_reply_to { CommentInReplyToMigration::Old(in_reply_to) => { // This post, or the parent comment might not yet exist on this server yet, fetch them. @@ -90,7 +91,7 @@ impl Note { // Nested comments will automatically get fetched recursively let parent_id: Option = match in_reply_to.get(1) { Some(comment_id) => { - let comment_id = ObjectId::::new(comment_id.clone()); + let comment_id = ObjectId::::new(comment_id.clone()); let parent_comment = Box::pin(comment_id.dereference(context, request_counter)).await?; Some(parent_comment.id) @@ -104,16 +105,16 @@ impl Note { let parent = Box::pin(in_reply_to.dereference(context, request_counter).await?); match parent.deref() { PostOrComment::Post(p) => { - // Workaround because I cant figure ut how to get the post out of the box (and we dont + // Workaround because I cant figure out how to get the post out of the box (and we dont // want to stackoverflow in a deep comment hierarchy). let post_id = p.id; let post = blocking(context.pool(), move |conn| Post::read(conn, post_id)).await??; - Ok((post, None)) + Ok((post.into(), None)) } PostOrComment::Comment(c) => { let post_id = c.post_id; let post = blocking(context.pool(), move |conn| Post::read(conn, post_id)).await??; - Ok((post, Some(c.id))) + Ok((post.into(), Some(c.id))) } } } @@ -138,7 +139,7 @@ impl Note { verify_domains_match(self.attributed_to.inner(), &self.id)?; verify_person_in_community( &self.attributed_to, - &ObjectId::new(community.actor_id()), + &ObjectId::new(community.actor_id), context, request_counter, ) @@ -147,9 +148,57 @@ impl Note { } } +#[derive(Clone, Debug)] +pub struct ApubComment(Comment); + +impl Deref for ApubComment { + type Target = Comment; + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +impl From for ApubComment { + fn from(c: Comment) -> Self { + ApubComment { 0: c } + } +} + #[async_trait::async_trait(?Send)] -impl ToApub for Comment { +impl ApubObject for ApubComment { + type DataType = LemmyContext; + + fn last_refreshed_at(&self) -> Option { + None + } + + async fn read_from_apub_id( + object_id: Url, + context: &LemmyContext, + ) -> Result, LemmyError> { + Ok( + blocking(context.pool(), move |conn| { + Comment::read_from_apub_id(conn, object_id) + }) + .await?? + .map(Into::into), + ) + } + + async fn delete(self, context: &LemmyContext) -> Result<(), LemmyError> { + blocking(context.pool(), move |conn| { + Comment::update_deleted(conn, self.id, true) + }) + .await??; + Ok(()) + } +} + +#[async_trait::async_trait(?Send)] +impl ToApub for ApubComment { type ApubType = Note; + type TombstoneType = Tombstone; + type DataType = DbPool; async fn to_apub(&self, pool: &DbPool) -> Result { let creator_id = self.creator_id; @@ -200,8 +249,9 @@ impl ToApub for Comment { } #[async_trait::async_trait(?Send)] -impl FromApub for Comment { +impl FromApub for ApubComment { type ApubType = Note; + type DataType = LemmyContext; /// Converts a `Note` to `Comment`. /// @@ -211,7 +261,7 @@ impl FromApub for Comment { context: &LemmyContext, expected_domain: &Url, request_counter: &mut i32, - ) -> Result { + ) -> Result { let ap_id = Some(note.id(expected_domain)?.clone().into()); let creator = note .attributed_to @@ -238,6 +288,7 @@ impl FromApub for Comment { ap_id, local: Some(false), }; - Ok(blocking(context.pool(), move |conn| Comment::upsert(conn, &form)).await??) + let comment = blocking(context.pool(), move |conn| Comment::upsert(conn, &form)).await??; + Ok(comment.into()) } } diff --git a/crates/apub/src/objects/community.rs b/crates/apub/src/objects/community.rs index 324ae259c..56a86cc85 100644 --- a/crates/apub/src/objects/community.rs +++ b/crates/apub/src/objects/community.rs @@ -4,12 +4,13 @@ use crate::{ fetcher::community::{fetch_community_outbox, update_community_mods}, generate_moderators_url, generate_outbox_url, - objects::{create_tombstone, FromApub, ImageObject, Source, ToApub}, + objects::{create_tombstone, ImageObject, Source}, CommunityType, }; use activitystreams::{ actor::{kind::GroupType, Endpoints}, base::AnyBase, + chrono::NaiveDateTime, object::{kind::ImageType, Tombstone}, primitives::OneOrMany, unparsed::Unparsed, @@ -19,7 +20,7 @@ use itertools::Itertools; use lemmy_api_common::blocking; use lemmy_apub_lib::{ signatures::PublicKey, - traits::ActorType, + traits::{ActorType, ApubObject, FromApub, ToApub}, values::{MediaTypeHtml, MediaTypeMarkdown}, verify::verify_domains_match, }; @@ -37,6 +38,7 @@ use lemmy_utils::{ use lemmy_websocket::LemmyContext; use serde::{Deserialize, Serialize}; use serde_with::skip_serializing_none; +use std::ops::Deref; use url::Url; #[skip_serializing_none] @@ -117,9 +119,83 @@ impl Group { } } +#[derive(Clone, Debug)] +pub struct ApubCommunity(Community); + +impl Deref for ApubCommunity { + type Target = Community; + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +impl From for ApubCommunity { + fn from(c: Community) -> Self { + ApubCommunity { 0: c } + } +} + #[async_trait::async_trait(?Send)] -impl ToApub for Community { +impl ApubObject for ApubCommunity { + type DataType = LemmyContext; + + fn last_refreshed_at(&self) -> Option { + Some(self.last_refreshed_at) + } + + async fn read_from_apub_id( + object_id: Url, + context: &LemmyContext, + ) -> Result, LemmyError> { + Ok( + blocking(context.pool(), move |conn| { + Community::read_from_apub_id(conn, object_id) + }) + .await?? + .map(Into::into), + ) + } + + async fn delete(self, context: &LemmyContext) -> Result<(), LemmyError> { + blocking(context.pool(), move |conn| { + Community::update_deleted(conn, self.id, true) + }) + .await??; + Ok(()) + } +} + +impl ActorType for ApubCommunity { + fn is_local(&self) -> bool { + self.local + } + fn actor_id(&self) -> Url { + self.actor_id.to_owned().into() + } + fn name(&self) -> String { + self.name.clone() + } + fn public_key(&self) -> Option { + self.public_key.to_owned() + } + fn private_key(&self) -> Option { + self.private_key.to_owned() + } + + fn inbox_url(&self) -> Url { + self.inbox_url.clone().into() + } + + fn shared_inbox_url(&self) -> Option { + self.shared_inbox_url.clone().map(|s| s.into_inner()) + } +} + +#[async_trait::async_trait(?Send)] +impl ToApub for ApubCommunity { type ApubType = Group; + type TombstoneType = Tombstone; + type DataType = DbPool; async fn to_apub(&self, _pool: &DbPool) -> Result { let source = self.description.clone().map(|bio| Source { @@ -174,8 +250,9 @@ impl ToApub for Community { } #[async_trait::async_trait(?Send)] -impl FromApub for Community { +impl FromApub for ApubCommunity { type ApubType = Group; + type DataType = LemmyContext; /// Converts a `Group` to `Community`, inserts it into the database and updates moderators. async fn from_apub( @@ -183,7 +260,7 @@ impl FromApub for Community { context: &LemmyContext, expected_domain: &Url, request_counter: &mut i32, - ) -> Result { + ) -> Result { let form = Group::from_apub_to_form(group, expected_domain, &context.settings()).await?; let community = blocking(context.pool(), move |conn| Community::upsert(conn, &form)).await??; @@ -192,7 +269,7 @@ impl FromApub for Community { // TODO: doing this unconditionally might cause infinite loop for some reason fetch_community_outbox(context, &group.outbox, request_counter).await?; - Ok(community) + Ok(community.into()) } } diff --git a/crates/apub/src/objects/mod.rs b/crates/apub/src/objects/mod.rs index b558902fa..c5f20c292 100644 --- a/crates/apub/src/objects/mod.rs +++ b/crates/apub/src/objects/mod.rs @@ -5,43 +5,14 @@ use activitystreams::{ use anyhow::anyhow; use chrono::NaiveDateTime; use lemmy_apub_lib::values::MediaTypeMarkdown; -use lemmy_db_schema::DbPool; use lemmy_utils::{utils::convert_datetime, LemmyError}; -use lemmy_websocket::LemmyContext; use url::Url; -pub(crate) mod comment; -pub(crate) mod community; -pub(crate) mod person; -pub(crate) mod post; -pub(crate) mod private_message; - -/// Trait for converting an object or actor into the respective ActivityPub type. -#[async_trait::async_trait(?Send)] -pub(crate) trait ToApub { - type ApubType; - async fn to_apub(&self, pool: &DbPool) -> Result; - fn to_tombstone(&self) -> Result; -} - -#[async_trait::async_trait(?Send)] -pub trait FromApub { - type ApubType; - /// Converts an object from ActivityPub type to Lemmy internal type. - /// - /// * `apub` The object to read from - /// * `context` LemmyContext which holds DB pool, HTTP client etc - /// * `expected_domain` Domain where the object was received from. None in case of mod action. - /// * `mod_action_allowed` True if the object can be a mod activity, ignore `expected_domain` in this case - async fn from_apub( - apub: &Self::ApubType, - context: &LemmyContext, - expected_domain: &Url, - request_counter: &mut i32, - ) -> Result - where - Self: Sized; -} +pub mod comment; +pub mod community; +pub mod person; +pub mod post; +pub mod private_message; #[derive(Clone, Debug, serde::Deserialize, serde::Serialize)] #[serde(rename_all = "camelCase")] diff --git a/crates/apub/src/objects/person.rs b/crates/apub/src/objects/person.rs index 45c67f443..53503d007 100644 --- a/crates/apub/src/objects/person.rs +++ b/crates/apub/src/objects/person.rs @@ -2,20 +2,21 @@ use crate::{ check_is_apub_id_valid, context::lemmy_context, generate_outbox_url, - objects::{FromApub, ImageObject, Source, ToApub}, + objects::{ImageObject, Source}, }; use activitystreams::{ actor::Endpoints, base::AnyBase, - chrono::{DateTime, FixedOffset}, + chrono::NaiveDateTime, object::{kind::ImageType, Tombstone}, primitives::OneOrMany, unparsed::Unparsed, }; +use chrono::{DateTime, FixedOffset}; use lemmy_api_common::blocking; use lemmy_apub_lib::{ signatures::PublicKey, - traits::ActorType, + traits::{ActorType, ApubObject, FromApub, ToApub}, values::{MediaTypeHtml, MediaTypeMarkdown}, verify::verify_domains_match, }; @@ -31,6 +32,7 @@ use lemmy_utils::{ use lemmy_websocket::LemmyContext; use serde::{Deserialize, Serialize}; use serde_with::skip_serializing_none; +use std::ops::Deref; use url::Url; #[derive(Clone, Copy, Debug, Deserialize, Serialize, PartialEq)] @@ -79,9 +81,85 @@ impl Person { } } +#[derive(Clone, Debug)] +pub struct ApubPerson(DbPerson); + +impl Deref for ApubPerson { + type Target = DbPerson; + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +impl From for ApubPerson { + fn from(p: DbPerson) -> Self { + ApubPerson { 0: p } + } +} + #[async_trait::async_trait(?Send)] -impl ToApub for DbPerson { +impl ApubObject for ApubPerson { + type DataType = LemmyContext; + + fn last_refreshed_at(&self) -> Option { + Some(self.last_refreshed_at) + } + + async fn read_from_apub_id( + object_id: Url, + context: &LemmyContext, + ) -> Result, LemmyError> { + Ok( + blocking(context.pool(), move |conn| { + DbPerson::read_from_apub_id(conn, object_id) + }) + .await?? + .map(Into::into), + ) + } + + async fn delete(self, context: &LemmyContext) -> Result<(), LemmyError> { + blocking(context.pool(), move |conn| { + DbPerson::update_deleted(conn, self.id, true) + }) + .await??; + Ok(()) + } +} + +impl ActorType for ApubPerson { + fn is_local(&self) -> bool { + self.local + } + fn actor_id(&self) -> Url { + self.actor_id.to_owned().into_inner() + } + fn name(&self) -> String { + self.name.clone() + } + + fn public_key(&self) -> Option { + self.public_key.to_owned() + } + + fn private_key(&self) -> Option { + self.private_key.to_owned() + } + + fn inbox_url(&self) -> Url { + self.inbox_url.clone().into() + } + + fn shared_inbox_url(&self) -> Option { + self.shared_inbox_url.clone().map(|s| s.into_inner()) + } +} + +#[async_trait::async_trait(?Send)] +impl ToApub for ApubPerson { type ApubType = Person; + type TombstoneType = Tombstone; + type DataType = DbPool; async fn to_apub(&self, _pool: &DbPool) -> Result { let kind = if self.bot_account { @@ -133,15 +211,16 @@ impl ToApub for DbPerson { } #[async_trait::async_trait(?Send)] -impl FromApub for DbPerson { +impl FromApub for ApubPerson { type ApubType = Person; + type DataType = LemmyContext; async fn from_apub( person: &Person, context: &LemmyContext, expected_domain: &Url, _request_counter: &mut i32, - ) -> Result { + ) -> Result { let actor_id = Some(person.id(expected_domain)?.clone().into()); let name = person.preferred_username.clone(); let display_name: Option = person.name.clone(); @@ -184,6 +263,6 @@ impl FromApub for DbPerson { DbPerson::upsert(conn, &person_form) }) .await??; - Ok(person) + Ok(person.into()) } } diff --git a/crates/apub/src/objects/post.rs b/crates/apub/src/objects/post.rs index bb3010380..dc6d96518 100644 --- a/crates/apub/src/objects/post.rs +++ b/crates/apub/src/objects/post.rs @@ -2,7 +2,7 @@ use crate::{ activities::{extract_community, verify_person_in_community}, context::lemmy_context, fetcher::object_id::ObjectId, - objects::{create_tombstone, FromApub, ImageObject, Source, ToApub}, + objects::{create_tombstone, person::ApubPerson, ImageObject, Source}, }; use activitystreams::{ base::AnyBase, @@ -14,10 +14,10 @@ use activitystreams::{ public, unparsed::Unparsed, }; -use chrono::{DateTime, FixedOffset}; +use chrono::{DateTime, FixedOffset, NaiveDateTime}; use lemmy_api_common::blocking; use lemmy_apub_lib::{ - traits::ActorType, + traits::{ActorType, ApubObject, FromApub, ToApub}, values::{MediaTypeHtml, MediaTypeMarkdown}, verify::verify_domains_match, }; @@ -39,6 +39,7 @@ use lemmy_utils::{ use lemmy_websocket::LemmyContext; use serde::{Deserialize, Serialize}; use serde_with::skip_serializing_none; +use std::ops::Deref; use url::Url; #[skip_serializing_none] @@ -49,7 +50,7 @@ pub struct Page { context: OneOrMany, r#type: PageType, id: Url, - pub(crate) attributed_to: ObjectId, + pub(crate) attributed_to: ObjectId, to: [Url; 2], name: String, content: Option, @@ -80,7 +81,7 @@ impl Page { /// /// Both stickied and locked need to be false on a newly created post (verified in [[CreatePost]]. pub(crate) async fn is_mod_action(&self, context: &LemmyContext) -> Result { - let old_post = ObjectId::::new(self.id.clone()) + let old_post = ObjectId::::new(self.id.clone()) .dereference_local(context) .await; @@ -112,9 +113,57 @@ impl Page { } } +#[derive(Clone, Debug)] +pub struct ApubPost(Post); + +impl Deref for ApubPost { + type Target = Post; + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +impl From for ApubPost { + fn from(p: Post) -> Self { + ApubPost { 0: p } + } +} + #[async_trait::async_trait(?Send)] -impl ToApub for Post { +impl ApubObject for ApubPost { + type DataType = LemmyContext; + + fn last_refreshed_at(&self) -> Option { + None + } + + async fn read_from_apub_id( + object_id: Url, + context: &LemmyContext, + ) -> Result, LemmyError> { + Ok( + blocking(context.pool(), move |conn| { + Post::read_from_apub_id(conn, object_id) + }) + .await?? + .map(Into::into), + ) + } + + async fn delete(self, context: &LemmyContext) -> Result<(), LemmyError> { + blocking(context.pool(), move |conn| { + Post::update_deleted(conn, self.id, true) + }) + .await??; + Ok(()) + } +} + +#[async_trait::async_trait(?Send)] +impl ToApub for ApubPost { type ApubType = Page; + type TombstoneType = Tombstone; + type DataType = DbPool; // Turn a Lemmy post into an ActivityPub page that can be sent out over the network. async fn to_apub(&self, pool: &DbPool) -> Result { @@ -165,15 +214,16 @@ impl ToApub for Post { } #[async_trait::async_trait(?Send)] -impl FromApub for Post { +impl FromApub for ApubPost { type ApubType = Page; + type DataType = LemmyContext; async fn from_apub( page: &Page, context: &LemmyContext, expected_domain: &Url, request_counter: &mut i32, - ) -> Result { + ) -> Result { // We can't verify the domain in case of mod action, because the mod may be on a different // instance from the post author. let ap_id = if page.is_mod_action(context).await? { @@ -222,6 +272,7 @@ impl FromApub for Post { ap_id, local: Some(false), }; - Ok(blocking(context.pool(), move |conn| Post::upsert(conn, &form)).await??) + let post = blocking(context.pool(), move |conn| Post::upsert(conn, &form)).await??; + Ok(post.into()) } } diff --git a/crates/apub/src/objects/private_message.rs b/crates/apub/src/objects/private_message.rs index 8cf40c9e4..cde1966ed 100644 --- a/crates/apub/src/objects/private_message.rs +++ b/crates/apub/src/objects/private_message.rs @@ -1,10 +1,11 @@ use crate::{ context::lemmy_context, fetcher::object_id::ObjectId, - objects::{create_tombstone, FromApub, Source, ToApub}, + objects::{create_tombstone, person::ApubPerson, Source}, }; use activitystreams::{ base::AnyBase, + chrono::NaiveDateTime, object::{kind::NoteType, Tombstone}, primitives::OneOrMany, unparsed::Unparsed, @@ -13,6 +14,7 @@ use anyhow::anyhow; use chrono::{DateTime, FixedOffset}; use lemmy_api_common::blocking; use lemmy_apub_lib::{ + traits::{ApubObject, FromApub, ToApub}, values::{MediaTypeHtml, MediaTypeMarkdown}, verify::verify_domains_match, }; @@ -28,6 +30,7 @@ use lemmy_utils::{utils::convert_datetime, LemmyError}; use lemmy_websocket::LemmyContext; use serde::{Deserialize, Serialize}; use serde_with::skip_serializing_none; +use std::ops::Deref; use url::Url; #[skip_serializing_none] @@ -38,8 +41,8 @@ pub struct Note { context: OneOrMany, r#type: NoteType, id: Url, - pub(crate) attributed_to: ObjectId, - to: ObjectId, + pub(crate) attributed_to: ObjectId, + to: ObjectId, content: String, media_type: MediaTypeHtml, source: Source, @@ -75,9 +78,54 @@ impl Note { } } +#[derive(Clone, Debug)] +pub struct ApubPrivateMessage(PrivateMessage); + +impl Deref for ApubPrivateMessage { + type Target = PrivateMessage; + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +impl From for ApubPrivateMessage { + fn from(pm: PrivateMessage) -> Self { + ApubPrivateMessage { 0: pm } + } +} + #[async_trait::async_trait(?Send)] -impl ToApub for PrivateMessage { +impl ApubObject for ApubPrivateMessage { + type DataType = LemmyContext; + + fn last_refreshed_at(&self) -> Option { + None + } + + async fn read_from_apub_id( + object_id: Url, + context: &LemmyContext, + ) -> Result, LemmyError> { + Ok( + blocking(context.pool(), move |conn| { + PrivateMessage::read_from_apub_id(conn, object_id) + }) + .await?? + .map(Into::into), + ) + } + + async fn delete(self, _context: &LemmyContext) -> Result<(), LemmyError> { + // do nothing, because pm can't be fetched over http + unimplemented!() + } +} + +#[async_trait::async_trait(?Send)] +impl ToApub for ApubPrivateMessage { type ApubType = Note; + type TombstoneType = Tombstone; + type DataType = DbPool; async fn to_apub(&self, pool: &DbPool) -> Result { let creator_id = self.creator_id; @@ -116,15 +164,16 @@ impl ToApub for PrivateMessage { } #[async_trait::async_trait(?Send)] -impl FromApub for PrivateMessage { +impl FromApub for ApubPrivateMessage { type ApubType = Note; + type DataType = LemmyContext; async fn from_apub( note: &Note, context: &LemmyContext, expected_domain: &Url, request_counter: &mut i32, - ) -> Result { + ) -> Result { let ap_id = Some(note.id(expected_domain)?.clone().into()); let creator = note .attributed_to @@ -143,11 +192,10 @@ impl FromApub for PrivateMessage { ap_id, local: Some(false), }; - Ok( - blocking(context.pool(), move |conn| { - PrivateMessage::upsert(conn, &form) - }) - .await??, - ) + let pm = blocking(context.pool(), move |conn| { + PrivateMessage::upsert(conn, &form) + }) + .await??; + Ok(pm.into()) } } diff --git a/crates/apub_lib/src/traits.rs b/crates/apub_lib/src/traits.rs index 16fb3f8e3..c2c1d02a3 100644 --- a/crates/apub_lib/src/traits.rs +++ b/crates/apub_lib/src/traits.rs @@ -27,17 +27,21 @@ pub trait ActivityHandler { ) -> Result<(), LemmyError>; } +#[async_trait::async_trait(?Send)] pub trait ApubObject { type DataType; /// If this object should be refetched after a certain interval, it should return the last refresh /// time here. This is mainly used to update remote actors. fn last_refreshed_at(&self) -> Option; /// Try to read the object with given ID from local database. Returns Ok(None) if it doesn't exist. - fn read_from_apub_id(data: &Self::DataType, object_id: Url) -> Result, LemmyError> + async fn read_from_apub_id( + object_id: Url, + data: &Self::DataType, + ) -> Result, LemmyError> where Self: Sized; /// Marks the object as deleted in local db. Called when a tombstone is received. - fn delete(self, data: &Self::DataType) -> Result<(), LemmyError>; + async fn delete(self, data: &Self::DataType) -> Result<(), LemmyError>; } /// Common methods provided by ActivityPub actors (community and person). Not all methods are @@ -67,3 +71,35 @@ pub trait ActorType { }) } } + +/// Trait for converting an object or actor into the respective ActivityPub type. +#[async_trait::async_trait(?Send)] +pub trait ToApub { + type ApubType; + type TombstoneType; + type DataType; + + async fn to_apub(&self, data: &Self::DataType) -> Result; + fn to_tombstone(&self) -> Result; +} + +#[async_trait::async_trait(?Send)] +pub trait FromApub { + type ApubType; + type DataType; + + /// Converts an object from ActivityPub type to Lemmy internal type. + /// + /// * `apub` The object to read from + /// * `context` LemmyContext which holds DB pool, HTTP client etc + /// * `expected_domain` Domain where the object was received from. None in case of mod action. + /// * `mod_action_allowed` True if the object can be a mod activity, ignore `expected_domain` in this case + async fn from_apub( + apub: &Self::ApubType, + data: &Self::DataType, + expected_domain: &Url, + request_counter: &mut i32, + ) -> Result + where + Self: Sized; +} diff --git a/crates/db_schema/Cargo.toml b/crates/db_schema/Cargo.toml index a05aed47d..dc53d82bd 100644 --- a/crates/db_schema/Cargo.toml +++ b/crates/db_schema/Cargo.toml @@ -12,7 +12,6 @@ doctest = false [dependencies] lemmy_utils = { version = "=0.13.0", path = "../utils" } -lemmy_apub_lib = { version = "=0.13.0", path = "../apub_lib" } diesel = { version = "1.4.8", features = ["postgres","chrono","r2d2","serde_json"] } diesel_migrations = "1.4.0" chrono = { version = "0.4.19", features = ["serde"] } diff --git a/crates/db_schema/src/impls/comment.rs b/crates/db_schema/src/impls/comment.rs index aa7e25b28..09389aad8 100644 --- a/crates/db_schema/src/impls/comment.rs +++ b/crates/db_schema/src/impls/comment.rs @@ -11,10 +11,7 @@ use crate::{ }, traits::{Crud, DeleteableOrRemoveable, Likeable, Saveable}, }; -use chrono::NaiveDateTime; use diesel::{dsl::*, result::Error, *}; -use lemmy_apub_lib::traits::ApubObject; -use lemmy_utils::LemmyError; use url::Url; impl Comment { @@ -108,6 +105,17 @@ impl Comment { .set(comment_form) .get_result::(conn) } + pub fn read_from_apub_id(conn: &PgConnection, object_id: Url) -> Result, Error> { + use crate::schema::comment::dsl::*; + let object_id: DbUrl = object_id.into(); + Ok( + comment + .filter(ap_id.eq(object_id)) + .first::(conn) + .ok() + .map(Into::into), + ) + } } impl Crud for Comment { @@ -198,25 +206,6 @@ impl DeleteableOrRemoveable for Comment { } } -impl ApubObject for Comment { - type DataType = PgConnection; - - fn last_refreshed_at(&self) -> Option { - None - } - - fn read_from_apub_id(conn: &PgConnection, object_id: Url) -> Result, LemmyError> { - use crate::schema::comment::dsl::*; - let object_id: DbUrl = object_id.into(); - Ok(comment.filter(ap_id.eq(object_id)).first::(conn).ok()) - } - - fn delete(self, conn: &PgConnection) -> Result<(), LemmyError> { - Comment::update_deleted(conn, self.id, true)?; - Ok(()) - } -} - #[cfg(test)] mod tests { use crate::{ diff --git a/crates/db_schema/src/impls/community.rs b/crates/db_schema/src/impls/community.rs index 8acce790c..b2ebb3a0a 100644 --- a/crates/db_schema/src/impls/community.rs +++ b/crates/db_schema/src/impls/community.rs @@ -14,10 +14,7 @@ use crate::{ }, traits::{Bannable, Crud, DeleteableOrRemoveable, Followable, Joinable}, }; -use chrono::NaiveDateTime; use diesel::{dsl::*, result::Error, ExpressionMethods, PgConnection, QueryDsl, RunQueryDsl}; -use lemmy_apub_lib::traits::{ActorType, ApubObject}; -use lemmy_utils::LemmyError; use url::Url; mod safe_type { @@ -148,6 +145,17 @@ impl Community { .set(community_form) .get_result::(conn) } + pub fn read_from_apub_id(conn: &PgConnection, object_id: Url) -> Result, Error> { + use crate::schema::community::dsl::*; + let object_id: DbUrl = object_id.into(); + Ok( + community + .filter(actor_id.eq(object_id)) + .first::(conn) + .ok() + .map(Into::into), + ) + } } impl Joinable for CommunityModerator { @@ -297,59 +305,6 @@ impl Followable for CommunityFollower { } } -impl ApubObject for Community { - type DataType = PgConnection; - - fn last_refreshed_at(&self) -> Option { - Some(self.last_refreshed_at) - } - - fn read_from_apub_id(conn: &PgConnection, object_id: Url) -> Result, LemmyError> { - use crate::schema::community::dsl::*; - let object_id: DbUrl = object_id.into(); - Ok( - community - .filter(actor_id.eq(object_id)) - .first::(conn) - .ok(), - ) - } - - fn delete(self, conn: &PgConnection) -> Result<(), LemmyError> { - use crate::schema::community::dsl::*; - diesel::update(community.find(self.id)) - .set((deleted.eq(true), updated.eq(naive_now()))) - .get_result::(conn)?; - Ok(()) - } -} - -impl ActorType for Community { - fn is_local(&self) -> bool { - self.local - } - fn actor_id(&self) -> Url { - self.actor_id.to_owned().into() - } - fn name(&self) -> String { - self.name.clone() - } - fn public_key(&self) -> Option { - self.public_key.to_owned() - } - fn private_key(&self) -> Option { - self.private_key.to_owned() - } - - fn inbox_url(&self) -> Url { - self.inbox_url.clone().into() - } - - fn shared_inbox_url(&self) -> Option { - self.shared_inbox_url.clone().map(|s| s.into_inner()) - } -} - #[cfg(test)] mod tests { use crate::{ diff --git a/crates/db_schema/src/impls/person.rs b/crates/db_schema/src/impls/person.rs index 5b7cb9416..a9ba1d2e9 100644 --- a/crates/db_schema/src/impls/person.rs +++ b/crates/db_schema/src/impls/person.rs @@ -5,10 +5,7 @@ use crate::{ source::person::{Person, PersonForm}, traits::Crud, }; -use chrono::NaiveDateTime; use diesel::{dsl::*, result::Error, ExpressionMethods, PgConnection, QueryDsl, RunQueryDsl, *}; -use lemmy_apub_lib::traits::{ActorType, ApubObject}; -use lemmy_utils::LemmyError; use url::Url; mod safe_type { @@ -237,61 +234,29 @@ impl Person { .set(person_form) .get_result::(conn) } -} -impl ApubObject for Person { - type DataType = PgConnection; - - fn last_refreshed_at(&self) -> Option { - Some(self.last_refreshed_at) - } - - fn read_from_apub_id(conn: &PgConnection, object_id: Url) -> Result, LemmyError> { + pub fn read_from_apub_id(conn: &PgConnection, object_id: Url) -> Result, Error> { use crate::schema::person::dsl::*; let object_id: DbUrl = object_id.into(); Ok( person .filter(deleted.eq(false)) .filter(actor_id.eq(object_id)) - .first::(conn) - .ok(), + .first::(conn) + .ok() + .map(Into::into), ) } - fn delete(self, conn: &PgConnection) -> Result<(), LemmyError> { + pub fn update_deleted( + conn: &PgConnection, + person_id: PersonId, + new_deleted: bool, + ) -> Result { use crate::schema::person::dsl::*; - diesel::update(person.find(self.id)) - .set((deleted.eq(true), updated.eq(naive_now()))) - .get_result::(conn)?; - Ok(()) - } -} - -impl ActorType for Person { - fn is_local(&self) -> bool { - self.local - } - fn actor_id(&self) -> Url { - self.actor_id.to_owned().into_inner() - } - fn name(&self) -> String { - self.name.clone() - } - - fn public_key(&self) -> Option { - self.public_key.to_owned() - } - - fn private_key(&self) -> Option { - self.private_key.to_owned() - } - - fn inbox_url(&self) -> Url { - self.inbox_url.clone().into() - } - - fn shared_inbox_url(&self) -> Option { - self.shared_inbox_url.clone().map(|s| s.into_inner()) + diesel::update(person.find(person_id)) + .set(deleted.eq(new_deleted)) + .get_result::(conn) } } diff --git a/crates/db_schema/src/impls/post.rs b/crates/db_schema/src/impls/post.rs index 2b71c663f..c1f0fcbf2 100644 --- a/crates/db_schema/src/impls/post.rs +++ b/crates/db_schema/src/impls/post.rs @@ -13,10 +13,7 @@ use crate::{ }, traits::{Crud, DeleteableOrRemoveable, Likeable, Readable, Saveable}, }; -use chrono::NaiveDateTime; use diesel::{dsl::*, result::Error, ExpressionMethods, PgConnection, QueryDsl, RunQueryDsl}; -use lemmy_apub_lib::traits::ApubObject; -use lemmy_utils::LemmyError; use url::Url; impl Crud for Post { @@ -164,6 +161,17 @@ impl Post { .set(post_form) .get_result::(conn) } + pub fn read_from_apub_id(conn: &PgConnection, object_id: Url) -> Result, Error> { + use crate::schema::post::dsl::*; + let object_id: DbUrl = object_id.into(); + Ok( + post + .filter(ap_id.eq(object_id)) + .first::(conn) + .ok() + .map(Into::into), + ) + } } impl Likeable for PostLike { @@ -248,28 +256,6 @@ impl DeleteableOrRemoveable for Post { } } -impl ApubObject for Post { - type DataType = PgConnection; - - fn last_refreshed_at(&self) -> Option { - None - } - - fn read_from_apub_id(conn: &PgConnection, object_id: Url) -> Result, LemmyError> { - use crate::schema::post::dsl::*; - let object_id: DbUrl = object_id.into(); - Ok(post.filter(ap_id.eq(object_id)).first::(conn).ok()) - } - - fn delete(self, conn: &PgConnection) -> Result<(), LemmyError> { - use crate::schema::post::dsl::*; - diesel::update(post.find(self.id)) - .set((deleted.eq(true), updated.eq(naive_now()))) - .get_result::(conn)?; - Ok(()) - } -} - #[cfg(test)] mod tests { use crate::{ diff --git a/crates/db_schema/src/impls/private_message.rs b/crates/db_schema/src/impls/private_message.rs index f252a0c03..735c775e0 100644 --- a/crates/db_schema/src/impls/private_message.rs +++ b/crates/db_schema/src/impls/private_message.rs @@ -4,9 +4,7 @@ use crate::{ source::private_message::*, traits::{Crud, DeleteableOrRemoveable}, }; -use chrono::NaiveDateTime; use diesel::{dsl::*, result::Error, *}; -use lemmy_apub_lib::traits::ApubObject; use lemmy_utils::LemmyError; use url::Url; @@ -109,6 +107,21 @@ impl PrivateMessage { .set(private_message_form) .get_result::(conn) } + + pub fn read_from_apub_id( + conn: &PgConnection, + object_id: Url, + ) -> Result, LemmyError> { + use crate::schema::private_message::dsl::*; + let object_id: DbUrl = object_id.into(); + Ok( + private_message + .filter(ap_id.eq(object_id)) + .first::(conn) + .ok() + .map(Into::into), + ) + } } impl DeleteableOrRemoveable for PrivateMessage { @@ -118,30 +131,6 @@ impl DeleteableOrRemoveable for PrivateMessage { } } -impl ApubObject for PrivateMessage { - type DataType = PgConnection; - - fn last_refreshed_at(&self) -> Option { - None - } - - fn read_from_apub_id(conn: &PgConnection, object_id: Url) -> Result, LemmyError> { - use crate::schema::private_message::dsl::*; - let object_id: DbUrl = object_id.into(); - Ok( - private_message - .filter(ap_id.eq(object_id)) - .first::(conn) - .ok(), - ) - } - - fn delete(self, _conn: &PgConnection) -> Result<(), LemmyError> { - // do nothing, because pm can't be fetched over http - unimplemented!() - } -} - #[cfg(test)] mod tests { use crate::{ diff --git a/crates/websocket/src/send.rs b/crates/websocket/src/send.rs index 5982e24ce..95780c329 100644 --- a/crates/websocket/src/send.rs +++ b/crates/websocket/src/send.rs @@ -12,7 +12,13 @@ use lemmy_api_common::{ }; use lemmy_db_schema::{ newtypes::{CommentId, CommunityId, LocalUserId, PersonId, PostId, PrivateMessageId}, - traits::DeleteableOrRemoveable, + source::{ + comment::Comment, + person::Person, + person_mention::{PersonMention, PersonMentionForm}, + post::Post, + }, + traits::{Crud, DeleteableOrRemoveable}, }; use lemmy_db_views::{ comment_view::CommentView, @@ -21,7 +27,14 @@ use lemmy_db_views::{ private_message_view::PrivateMessageView, }; use lemmy_db_views_actor::community_view::CommunityView; -use lemmy_utils::{ConnectionId, LemmyError}; +use lemmy_utils::{ + email::send_email, + settings::structs::Settings, + utils::MentionData, + ConnectionId, + LemmyError, +}; +use log::error; pub async fn send_post_ws_message( post_id: PostId, @@ -167,3 +180,149 @@ pub async fn send_pm_ws_message( Ok(res) } + +pub async fn send_local_notifs( + mentions: Vec, + comment: &Comment, + person: &Person, + post: &Post, + do_send_email: bool, + context: &LemmyContext, +) -> Result, LemmyError> { + let mut recipient_ids = Vec::new(); + + // Send the local mentions + for mention in mentions + .iter() + .filter(|m| m.is_local(&context.settings().hostname) && m.name.ne(&person.name)) + .collect::>() + { + let mention_name = mention.name.clone(); + let user_view = blocking(context.pool(), move |conn| { + LocalUserView::read_from_name(conn, &mention_name) + }) + .await?; + if let Ok(mention_user_view) = user_view { + // TODO + // At some point, make it so you can't tag the parent creator either + // This can cause two notifications, one for reply and the other for mention + recipient_ids.push(mention_user_view.local_user.id); + + let user_mention_form = PersonMentionForm { + recipient_id: mention_user_view.person.id, + comment_id: comment.id, + read: None, + }; + + // Allow this to fail softly, since comment edits might re-update or replace it + // Let the uniqueness handle this fail + blocking(context.pool(), move |conn| { + PersonMention::create(conn, &user_mention_form) + }) + .await? + .ok(); + + // Send an email to those local users that have notifications on + if do_send_email { + send_email_to_user( + &mention_user_view, + "Mentioned by", + "Person Mention", + &comment.content, + &context.settings(), + ) + } + } + } + + // Send notifs to the parent commenter / poster + match comment.parent_id { + Some(parent_id) => { + let parent_comment = + blocking(context.pool(), move |conn| Comment::read(conn, parent_id)).await?; + if let Ok(parent_comment) = parent_comment { + // Don't send a notif to yourself + if parent_comment.creator_id != person.id { + // Get the parent commenter local_user + let user_view = blocking(context.pool(), move |conn| { + LocalUserView::read_person(conn, parent_comment.creator_id) + }) + .await?; + if let Ok(parent_user_view) = user_view { + recipient_ids.push(parent_user_view.local_user.id); + + if do_send_email { + send_email_to_user( + &parent_user_view, + "Reply from", + "Comment Reply", + &comment.content, + &context.settings(), + ) + } + } + } + } + } + // Its a post + None => { + if post.creator_id != person.id { + let creator_id = post.creator_id; + let parent_user = blocking(context.pool(), move |conn| { + LocalUserView::read_person(conn, creator_id) + }) + .await?; + if let Ok(parent_user_view) = parent_user { + recipient_ids.push(parent_user_view.local_user.id); + + if do_send_email { + send_email_to_user( + &parent_user_view, + "Reply from", + "Post Reply", + &comment.content, + &context.settings(), + ) + } + } + } + } + }; + Ok(recipient_ids) +} + +pub fn send_email_to_user( + local_user_view: &LocalUserView, + subject_text: &str, + body_text: &str, + comment_content: &str, + settings: &Settings, +) { + if local_user_view.person.banned || !local_user_view.local_user.send_notifications_to_email { + return; + } + + if let Some(user_email) = &local_user_view.local_user.email { + let subject = &format!( + "{} - {} {}", + subject_text, settings.hostname, local_user_view.person.name, + ); + let html = &format!( + "

{}


{} - {}

inbox", + body_text, + local_user_view.person.name, + comment_content, + settings.get_protocol_and_hostname() + ); + match send_email( + subject, + user_email, + &local_user_view.person.name, + html, + settings, + ) { + Ok(_o) => _o, + Err(e) => error!("{}", e), + }; + } +}