]> Untitled Git - lemmy.git/commitdiff
Add cargo feature for building lemmy_api_common with mininum deps (#2243)
authorNutomic <me@nutomic.com>
Tue, 3 May 2022 17:44:13 +0000 (19:44 +0200)
committerGitHub <noreply@github.com>
Tue, 3 May 2022 17:44:13 +0000 (17:44 +0000)
238 files changed:
.drone.yml
Cargo.lock
crates/api/Cargo.toml
crates/api/src/comment/like.rs
crates/api/src/comment/mark_as_read.rs
crates/api/src/comment/save.rs
crates/api/src/comment_report/create.rs
crates/api/src/comment_report/list.rs
crates/api/src/comment_report/resolve.rs
crates/api/src/community/add_mod.rs
crates/api/src/community/ban.rs
crates/api/src/community/block.rs
crates/api/src/community/follow.rs
crates/api/src/community/hide.rs
crates/api/src/community/transfer.rs
crates/api/src/lib.rs
crates/api/src/local_user/add_admin.rs
crates/api/src/local_user/ban_person.rs
crates/api/src/local_user/block.rs
crates/api/src/local_user/change_password.rs
crates/api/src/local_user/change_password_after_reset.rs
crates/api/src/local_user/get_captcha.rs
crates/api/src/local_user/list_banned.rs
crates/api/src/local_user/login.rs
crates/api/src/local_user/notifications/list_mentions.rs
crates/api/src/local_user/notifications/list_replies.rs
crates/api/src/local_user/notifications/mark_all_read.rs
crates/api/src/local_user/notifications/mark_mention_read.rs
crates/api/src/local_user/notifications/unread_count.rs
crates/api/src/local_user/report_count.rs
crates/api/src/local_user/reset_password.rs
crates/api/src/local_user/save_settings.rs
crates/api/src/local_user/verify_email.rs
crates/api/src/post/get_link_metadata.rs
crates/api/src/post/like.rs
crates/api/src/post/lock.rs
crates/api/src/post/mark_read.rs
crates/api/src/post/save.rs
crates/api/src/post/sticky.rs
crates/api/src/post_report/create.rs
crates/api/src/post_report/list.rs
crates/api/src/post_report/resolve.rs
crates/api/src/private_message/mark_read.rs
crates/api/src/site/config/read.rs
crates/api/src/site/config/update.rs
crates/api/src/site/leave_admin.rs
crates/api/src/site/mod_log.rs
crates/api/src/site/registration_applications/approve.rs
crates/api/src/site/registration_applications/list.rs
crates/api/src/site/registration_applications/unread_count.rs
crates/api/src/site/resolve_object.rs
crates/api/src/site/search.rs
crates/api/src/websocket.rs
crates/api_common/Cargo.toml
crates/api_common/src/comment.rs
crates/api_common/src/community.rs
crates/api_common/src/lib.rs
crates/api_common/src/person.rs
crates/api_common/src/post.rs
crates/api_common/src/request.rs [new file with mode: 0644]
crates/api_common/src/sensitive.rs [moved from crates/utils/src/sensitive.rs with 90% similarity]
crates/api_common/src/site.rs
crates/api_common/src/utils.rs [new file with mode: 0644]
crates/api_common/src/websocket.rs
crates/api_crud/Cargo.toml
crates/api_crud/src/comment/create.rs
crates/api_crud/src/comment/delete.rs
crates/api_crud/src/comment/list.rs
crates/api_crud/src/comment/mod.rs
crates/api_crud/src/comment/read.rs
crates/api_crud/src/comment/remove.rs [new file with mode: 0644]
crates/api_crud/src/comment/update.rs
crates/api_crud/src/community/create.rs
crates/api_crud/src/community/delete.rs
crates/api_crud/src/community/list.rs
crates/api_crud/src/community/mod.rs
crates/api_crud/src/community/read.rs
crates/api_crud/src/community/remove.rs [new file with mode: 0644]
crates/api_crud/src/community/update.rs
crates/api_crud/src/post/create.rs
crates/api_crud/src/post/delete.rs
crates/api_crud/src/post/list.rs
crates/api_crud/src/post/mod.rs
crates/api_crud/src/post/read.rs
crates/api_crud/src/post/remove.rs [new file with mode: 0644]
crates/api_crud/src/post/update.rs
crates/api_crud/src/private_message/create.rs
crates/api_crud/src/private_message/delete.rs
crates/api_crud/src/private_message/read.rs
crates/api_crud/src/private_message/update.rs
crates/api_crud/src/site/create.rs
crates/api_crud/src/site/read.rs
crates/api_crud/src/site/update.rs
crates/api_crud/src/user/create.rs
crates/api_crud/src/user/delete.rs
crates/api_crud/src/user/read.rs
crates/apub/Cargo.toml
crates/apub/src/activities/block/block_user.rs
crates/apub/src/activities/block/mod.rs
crates/apub/src/activities/block/undo_block_user.rs
crates/apub/src/activities/community/add_mod.rs
crates/apub/src/activities/community/remove_mod.rs
crates/apub/src/activities/community/report.rs
crates/apub/src/activities/community/update.rs
crates/apub/src/activities/create_or_update/comment.rs
crates/apub/src/activities/create_or_update/mod.rs
crates/apub/src/activities/create_or_update/post.rs
crates/apub/src/activities/create_or_update/private_message.rs
crates/apub/src/activities/deletion/delete.rs
crates/apub/src/activities/deletion/delete_user.rs
crates/apub/src/activities/deletion/mod.rs
crates/apub/src/activities/deletion/undo_delete.rs
crates/apub/src/activities/following/accept.rs
crates/apub/src/activities/following/follow.rs
crates/apub/src/activities/following/undo_follow.rs
crates/apub/src/activities/mod.rs
crates/apub/src/activities/voting/mod.rs
crates/apub/src/activities/voting/undo_vote.rs
crates/apub/src/activities/voting/vote.rs
crates/apub/src/collections/community_moderators.rs
crates/apub/src/collections/community_outbox.rs
crates/apub/src/fetcher/deletable_apub_object.rs
crates/apub/src/fetcher/mod.rs
crates/apub/src/fetcher/webfinger.rs
crates/apub/src/http/comment.rs
crates/apub/src/http/community.rs
crates/apub/src/http/mod.rs
crates/apub/src/http/person.rs
crates/apub/src/http/post.rs
crates/apub/src/http/site.rs
crates/apub/src/lib.rs
crates/apub/src/mentions.rs
crates/apub/src/migrations.rs [deleted file]
crates/apub/src/objects/comment.rs
crates/apub/src/objects/community.rs
crates/apub/src/objects/instance.rs
crates/apub/src/objects/mod.rs
crates/apub/src/objects/person.rs
crates/apub/src/objects/post.rs
crates/apub/src/objects/private_message.rs
crates/apub/src/protocol/collections/group_followers.rs
crates/apub/src/protocol/objects/group.rs
crates/apub/src/protocol/objects/note.rs
crates/apub_lib/Cargo.toml
crates/db_schema/Cargo.toml
crates/db_schema/src/aggregates/comment_aggregates.rs
crates/db_schema/src/aggregates/community_aggregates.rs
crates/db_schema/src/aggregates/mod.rs
crates/db_schema/src/aggregates/person_aggregates.rs
crates/db_schema/src/aggregates/post_aggregates.rs
crates/db_schema/src/aggregates/site_aggregates.rs
crates/db_schema/src/aggregates/structs.rs [new file with mode: 0644]
crates/db_schema/src/impls/activity.rs
crates/db_schema/src/impls/comment.rs
crates/db_schema/src/impls/comment_report.rs
crates/db_schema/src/impls/community.rs
crates/db_schema/src/impls/local_user.rs
crates/db_schema/src/impls/moderator.rs
crates/db_schema/src/impls/password_reset_request.rs
crates/db_schema/src/impls/person.rs
crates/db_schema/src/impls/person_mention.rs
crates/db_schema/src/impls/post.rs
crates/db_schema/src/impls/post_report.rs
crates/db_schema/src/impls/private_message.rs
crates/db_schema/src/impls/site.rs
crates/db_schema/src/lib.rs
crates/db_schema/src/newtypes.rs
crates/db_schema/src/source/activity.rs
crates/db_schema/src/source/comment.rs
crates/db_schema/src/source/comment_report.rs
crates/db_schema/src/source/community.rs
crates/db_schema/src/source/community_block.rs
crates/db_schema/src/source/email_verification.rs
crates/db_schema/src/source/local_user.rs
crates/db_schema/src/source/mod.rs
crates/db_schema/src/source/moderator.rs
crates/db_schema/src/source/password_reset_request.rs
crates/db_schema/src/source/person.rs
crates/db_schema/src/source/person_block.rs
crates/db_schema/src/source/person_mention.rs
crates/db_schema/src/source/post.rs
crates/db_schema/src/source/post_report.rs
crates/db_schema/src/source/private_message.rs
crates/db_schema/src/source/registration_application.rs
crates/db_schema/src/source/secret.rs
crates/db_schema/src/source/site.rs
crates/db_schema/src/traits.rs
crates/db_schema/src/utils.rs [new file with mode: 0644]
crates/db_views/Cargo.toml
crates/db_views/src/comment_report_view.rs
crates/db_views/src/comment_view.rs
crates/db_views/src/lib.rs
crates/db_views/src/local_user_view.rs
crates/db_views/src/post_report_view.rs
crates/db_views/src/post_view.rs
crates/db_views/src/private_message_view.rs
crates/db_views/src/registration_application_view.rs
crates/db_views/src/site_view.rs
crates/db_views/src/structs.rs [new file with mode: 0644]
crates/db_views_actor/Cargo.toml
crates/db_views_actor/src/community_block_view.rs
crates/db_views_actor/src/community_follower_view.rs
crates/db_views_actor/src/community_moderator_view.rs
crates/db_views_actor/src/community_person_ban_view.rs
crates/db_views_actor/src/community_view.rs
crates/db_views_actor/src/lib.rs
crates/db_views_actor/src/person_block_view.rs
crates/db_views_actor/src/person_mention_view.rs
crates/db_views_actor/src/person_view.rs
crates/db_views_actor/src/structs.rs [new file with mode: 0644]
crates/db_views_moderator/Cargo.toml
crates/db_views_moderator/src/lib.rs
crates/db_views_moderator/src/mod_add_community_view.rs
crates/db_views_moderator/src/mod_add_view.rs
crates/db_views_moderator/src/mod_ban_from_community_view.rs
crates/db_views_moderator/src/mod_ban_view.rs
crates/db_views_moderator/src/mod_hide_community_view.rs
crates/db_views_moderator/src/mod_lock_post_view.rs
crates/db_views_moderator/src/mod_remove_comment_view.rs
crates/db_views_moderator/src/mod_remove_community_view.rs
crates/db_views_moderator/src/mod_remove_post_view.rs
crates/db_views_moderator/src/mod_sticky_post_view.rs
crates/db_views_moderator/src/mod_transfer_community_view.rs
crates/db_views_moderator/src/structs.rs [new file with mode: 0644]
crates/routes/Cargo.toml
crates/routes/src/feeds.rs
crates/routes/src/nodeinfo.rs
crates/routes/src/webfinger.rs
crates/utils/Cargo.toml
crates/utils/src/lib.rs
crates/utils/src/request.rs
crates/websocket/Cargo.toml
crates/websocket/src/handlers.rs
crates/websocket/src/lib.rs
crates/websocket/src/send.rs
src/code_migrations.rs
src/main.rs
src/scheduled_tasks.rs

index 2b4ce8941a88649a513d587df64ae5c3293b0f8d..7b909482ad41aa211d42a762e45077c5b0212f37 100644 (file)
@@ -22,6 +22,11 @@ steps:
     commands:
       - /root/.cargo/bin/cargo fmt -- --check
 
+  - name: check lemmy_api_common with minimal deps
+    image: clux/muslrust:1.56.0
+    commands:
+      - cargo check -p lemmy_api_common
+
   - name: cargo clippy
     image: clux/muslrust:1.56.0
     commands:
index 2d8136477e4ee95bfbe1b8822f2b2e5d953ff764..da568355311408b5a1c2d7cfc8a881c304eb5d57 100644 (file)
@@ -1831,18 +1831,24 @@ dependencies = [
 name = "lemmy_api_common"
 version = "0.16.3"
 dependencies = [
+ "actix-rt",
  "actix-web",
  "chrono",
  "diesel",
+ "encoding",
  "lemmy_db_schema",
  "lemmy_db_views",
  "lemmy_db_views_actor",
  "lemmy_db_views_moderator",
  "lemmy_utils",
+ "percent-encoding",
+ "reqwest",
+ "reqwest-middleware",
  "rosetta-i18n",
  "serde",
  "tracing",
  "url",
+ "webpage",
 ]
 
 [[package]]
@@ -2062,7 +2068,6 @@ dependencies = [
 name = "lemmy_utils"
 version = "0.16.3"
 dependencies = [
- "actix-rt",
  "actix-web",
  "anyhow",
  "chrono",
@@ -2070,7 +2075,6 @@ dependencies = [
  "deser-hjson",
  "diesel",
  "doku",
- "encoding",
  "futures",
  "html2text",
  "http",
@@ -2080,10 +2084,8 @@ dependencies = [
  "once_cell",
  "openssl",
  "parking_lot 0.12.0",
- "percent-encoding",
  "rand 0.8.5",
  "regex",
- "reqwest",
  "reqwest-middleware",
  "rosetta-build",
  "rosetta-i18n",
@@ -2092,12 +2094,10 @@ dependencies = [
  "smart-default",
  "strum",
  "strum_macros",
- "thiserror",
  "tracing",
  "tracing-error",
  "url",
  "uuid",
- "webpage",
 ]
 
 [[package]]
index 4cf4f17d26a92cf37f098039e00c033f5917e29c..dfad36fcdac15725e30e5d7382fc656152e26736 100644 (file)
@@ -16,15 +16,15 @@ doctest = false
 lemmy_apub = { version = "=0.16.3", path = "../apub" }
 lemmy_apub_lib = { version = "=0.16.3", path = "../apub_lib" }
 lemmy_utils = { version = "=0.16.3", path = "../utils" }
-lemmy_db_schema = { version = "=0.16.3", path = "../db_schema" }
-lemmy_db_views = { version = "=0.16.3", path = "../db_views" }
-lemmy_db_views_moderator = { version = "=0.16.3", path = "../db_views_moderator" }
-lemmy_db_views_actor = { version = "=0.16.3", path = "../db_views_actor" }
-lemmy_api_common = { version = "=0.16.3", path = "../api_common" }
+lemmy_db_schema = { version = "=0.16.3", path = "../db_schema", features = ["full"] }
+lemmy_db_views = { version = "=0.16.3", path = "../db_views", features = ["full"] }
+lemmy_db_views_moderator = { version = "=0.16.3", path = "../db_views_moderator", features = ["full"] }
+lemmy_db_views_actor = { version = "=0.16.3", path = "../db_views_actor", features = ["full"] }
+lemmy_api_common = { version = "=0.16.3", path = "../api_common", features = ["full"] }
 lemmy_websocket = { version = "=0.16.3", path = "../websocket" }
 diesel = "1.4.8"
 bcrypt = "0.12.1"
-chrono = { version = "0.4.19", features = ["serde"] }
+chrono = { version = "0.4.19", features = ["serde"], default-features = false }
 serde_json = { version = "1.0.79", features = ["preserve_order"] }
 serde = { version = "1.0.136", features = ["derive"] }
 actix-web = { version = "4.0.1", default-features = false }
index a5bb368a91bf75b4d3411231750c0c57bd92b5ad..cc97ebc485ab467dc16cbd1bb3234e17c910b590 100644 (file)
@@ -1,11 +1,8 @@
 use crate::Perform;
 use actix_web::web::Data;
 use lemmy_api_common::{
-  blocking,
-  check_community_ban,
-  check_downvotes_enabled,
   comment::{CommentResponse, CreateCommentLike},
-  get_local_user_view_from_jwt,
+  utils::{blocking, check_community_ban, check_downvotes_enabled, get_local_user_view_from_jwt},
 };
 use lemmy_apub::{
   fetcher::post_or_comment::PostOrComment,
@@ -19,7 +16,7 @@ use lemmy_db_schema::{
   source::comment::{CommentLike, CommentLikeForm},
   traits::Likeable,
 };
-use lemmy_db_views::{comment_view::CommentView, local_user_view::LocalUserView};
+use lemmy_db_views::structs::{CommentView, LocalUserView};
 use lemmy_utils::{ConnectionId, LemmyError};
 use lemmy_websocket::{send::send_comment_ws_message, LemmyContext, UserOperation};
 use std::convert::TryInto;
index 25c4fb4344a0096775210d75e3120ef833cd40dd..a0dc6dd74e9b3f956eed7059f600d310deb39e61 100644 (file)
@@ -1,12 +1,11 @@
 use crate::Perform;
 use actix_web::web::Data;
 use lemmy_api_common::{
-  blocking,
   comment::{CommentResponse, MarkCommentAsRead},
-  get_local_user_view_from_jwt,
+  utils::{blocking, get_local_user_view_from_jwt},
 };
 use lemmy_db_schema::source::comment::Comment;
-use lemmy_db_views::comment_view::CommentView;
+use lemmy_db_views::structs::CommentView;
 use lemmy_utils::{ConnectionId, LemmyError};
 use lemmy_websocket::LemmyContext;
 
index 6fc0f49883faff4f799613e11f9b5bd6bde1e3b0..1ece524a8a41080e19c742996c9e2c431de62155 100644 (file)
@@ -1,15 +1,14 @@
 use crate::Perform;
 use actix_web::web::Data;
 use lemmy_api_common::{
-  blocking,
   comment::{CommentResponse, SaveComment},
-  get_local_user_view_from_jwt,
+  utils::{blocking, get_local_user_view_from_jwt},
 };
 use lemmy_db_schema::{
   source::comment::{CommentSaved, CommentSavedForm},
   traits::Saveable,
 };
-use lemmy_db_views::comment_view::CommentView;
+use lemmy_db_views::structs::CommentView;
 use lemmy_utils::{ConnectionId, LemmyError};
 use lemmy_websocket::LemmyContext;
 
index 4f4ef3bb80499b25f92425798110a24dc18abaf9..75e1323ab0c5a779b04ba7914787d1e6656d5a10 100644 (file)
@@ -1,10 +1,8 @@
 use crate::Perform;
 use actix_web::web::Data;
 use lemmy_api_common::{
-  blocking,
-  check_community_ban,
   comment::{CommentReportResponse, CreateCommentReport},
-  get_local_user_view_from_jwt,
+  utils::{blocking, check_community_ban, get_local_user_view_from_jwt},
 };
 use lemmy_apub::protocol::activities::community::report::Report;
 use lemmy_apub_lib::object_id::ObjectId;
@@ -12,7 +10,7 @@ use lemmy_db_schema::{
   source::comment_report::{CommentReport, CommentReportForm},
   traits::Reportable,
 };
-use lemmy_db_views::{comment_report_view::CommentReportView, comment_view::CommentView};
+use lemmy_db_views::structs::{CommentReportView, CommentView};
 use lemmy_utils::{ConnectionId, LemmyError};
 use lemmy_websocket::{messages::SendModRoomMessage, LemmyContext, UserOperation};
 
index b88aced700b7e2f20bf6e67d97f75b816e920f9e..296cb8322facf4a58a8af020dd15873d1df7ba88 100644 (file)
@@ -1,9 +1,8 @@
 use crate::Perform;
 use actix_web::web::Data;
 use lemmy_api_common::{
-  blocking,
   comment::{ListCommentReports, ListCommentReportsResponse},
-  get_local_user_view_from_jwt,
+  utils::{blocking, get_local_user_view_from_jwt},
 };
 use lemmy_db_views::comment_report_view::CommentReportQueryBuilder;
 use lemmy_utils::{ConnectionId, LemmyError};
index 9446fb3659a23825398c9c24502132dbbb9defe7..95481ace7e70ae2896a67344c78589dffc10e95d 100644 (file)
@@ -1,13 +1,11 @@
 use crate::Perform;
 use actix_web::web::Data;
 use lemmy_api_common::{
-  blocking,
   comment::{CommentReportResponse, ResolveCommentReport},
-  get_local_user_view_from_jwt,
-  is_mod_or_admin,
+  utils::{blocking, get_local_user_view_from_jwt, is_mod_or_admin},
 };
 use lemmy_db_schema::{source::comment_report::CommentReport, traits::Reportable};
-use lemmy_db_views::comment_report_view::CommentReportView;
+use lemmy_db_views::structs::CommentReportView;
 use lemmy_utils::{ConnectionId, LemmyError};
 use lemmy_websocket::{messages::SendModRoomMessage, LemmyContext, UserOperation};
 
index 6e790a0c52bb2a4bbb5077ed85a3e98fa70bef3b..9ea9361a9c87954048bad0937f6c84d0e492828e 100644 (file)
@@ -1,10 +1,8 @@
 use crate::Perform;
 use actix_web::web::Data;
 use lemmy_api_common::{
-  blocking,
   community::{AddModToCommunity, AddModToCommunityResponse},
-  get_local_user_view_from_jwt,
-  is_mod_or_admin,
+  utils::{blocking, get_local_user_view_from_jwt, is_mod_or_admin},
 };
 use lemmy_apub::{
   objects::{community::ApubCommunity, person::ApubPerson},
@@ -18,7 +16,7 @@ use lemmy_db_schema::{
   },
   traits::{Crud, Joinable},
 };
-use lemmy_db_views_actor::community_moderator_view::CommunityModeratorView;
+use lemmy_db_views_actor::structs::CommunityModeratorView;
 use lemmy_utils::{ConnectionId, LemmyError};
 use lemmy_websocket::{messages::SendCommunityRoomMessage, LemmyContext, UserOperation};
 
index ccdc1b9b75fab5bc46799c7a37606393abd9bd38..60fd32270f76ae7db7022ea0fa32bbe2e2ba4477 100644 (file)
@@ -1,11 +1,8 @@
 use crate::Perform;
 use actix_web::web::Data;
 use lemmy_api_common::{
-  blocking,
   community::{BanFromCommunity, BanFromCommunityResponse},
-  get_local_user_view_from_jwt,
-  is_mod_or_admin,
-  remove_user_data_in_community,
+  utils::{blocking, get_local_user_view_from_jwt, is_mod_or_admin, remove_user_data_in_community},
 };
 use lemmy_apub::{
   activities::block::SiteOrCommunity,
@@ -26,7 +23,7 @@ use lemmy_db_schema::{
   },
   traits::{Bannable, Crud, Followable},
 };
-use lemmy_db_views_actor::person_view::PersonViewSafe;
+use lemmy_db_views_actor::structs::PersonViewSafe;
 use lemmy_utils::{utils::naive_from_unix, ConnectionId, LemmyError};
 use lemmy_websocket::{messages::SendCommunityRoomMessage, LemmyContext, UserOperation};
 
index 02ece47f5f3a93e25f668bf9f2cd20b934bde4f1..4f740c916971182931600786dcfcbb24f000a5e2 100644 (file)
@@ -1,9 +1,8 @@
 use crate::Perform;
 use actix_web::web::Data;
 use lemmy_api_common::{
-  blocking,
   community::{BlockCommunity, BlockCommunityResponse},
-  get_local_user_view_from_jwt,
+  utils::{blocking, get_local_user_view_from_jwt},
 };
 use lemmy_apub::protocol::activities::following::undo_follow::UndoFollowCommunity;
 use lemmy_db_schema::{
@@ -13,7 +12,7 @@ use lemmy_db_schema::{
   },
   traits::{Blockable, Crud, Followable},
 };
-use lemmy_db_views_actor::community_view::CommunityView;
+use lemmy_db_views_actor::structs::CommunityView;
 use lemmy_utils::{ConnectionId, LemmyError};
 use lemmy_websocket::LemmyContext;
 
index 62eb34bb91b6df194bc8510d265bd767a26f766e..aab21a9c217a7361daa0f6395ba2ceebaa2f2cf0 100644 (file)
@@ -1,11 +1,13 @@
 use crate::Perform;
 use actix_web::web::Data;
 use lemmy_api_common::{
-  blocking,
-  check_community_ban,
-  check_community_deleted_or_removed,
   community::{CommunityResponse, FollowCommunity},
-  get_local_user_view_from_jwt,
+  utils::{
+    blocking,
+    check_community_ban,
+    check_community_deleted_or_removed,
+    get_local_user_view_from_jwt,
+  },
 };
 use lemmy_apub::{
   objects::community::ApubCommunity,
@@ -18,7 +20,7 @@ use lemmy_db_schema::{
   source::community::{Community, CommunityFollower, CommunityFollowerForm},
   traits::{Crud, Followable},
 };
-use lemmy_db_views_actor::community_view::CommunityView;
+use lemmy_db_views_actor::structs::CommunityView;
 use lemmy_utils::{ConnectionId, LemmyError};
 use lemmy_websocket::LemmyContext;
 
index a3910010024b53e130cb341364bd28c367169519..ddf4f49a152fa460422ec2b47117c01955709f10 100644 (file)
@@ -1,19 +1,17 @@
 use crate::Perform;
 use actix_web::web::Data;
 use lemmy_api_common::{
-  blocking,
   community::{CommunityResponse, HideCommunity},
-  get_local_user_view_from_jwt,
-  is_admin,
+  utils::{blocking, get_local_user_view_from_jwt, is_admin},
 };
 use lemmy_apub::protocol::activities::community::update::UpdateCommunity;
 use lemmy_db_schema::{
-  naive_now,
   source::{
     community::{Community, CommunityForm},
     moderator::{ModHideCommunity, ModHideCommunityForm},
   },
   traits::Crud,
+  utils::naive_now,
 };
 use lemmy_utils::{ConnectionId, LemmyError};
 use lemmy_websocket::{send::send_community_ws_message, LemmyContext, UserOperationCrud};
index 05282f457d4939edb78a8baac433e185d674b1f1..9d8044e3d8394951329b0b43978abd7e69ae7c90 100644 (file)
@@ -2,9 +2,8 @@ use crate::Perform;
 use actix_web::web::Data;
 use anyhow::Context;
 use lemmy_api_common::{
-  blocking,
   community::{GetCommunityResponse, TransferCommunity},
-  get_local_user_view_from_jwt,
+  utils::{blocking, get_local_user_view_from_jwt},
 };
 use lemmy_db_schema::{
   source::{
@@ -13,11 +12,7 @@ use lemmy_db_schema::{
   },
   traits::{Crud, Joinable},
 };
-use lemmy_db_views_actor::{
-  community_moderator_view::CommunityModeratorView,
-  community_view::CommunityView,
-  person_view::PersonViewSafe,
-};
+use lemmy_db_views_actor::structs::{CommunityModeratorView, CommunityView, PersonViewSafe};
 use lemmy_utils::{location_info, ConnectionId, LemmyError};
 use lemmy_websocket::LemmyContext;
 
index d6de25ccb22c4b49786f0750ea3df32b50e1bf86..0c36890bc6c6c1f9c1e4a86028580342b1b49166 100644 (file)
@@ -206,15 +206,15 @@ pub(crate) fn captcha_as_wav_base64(captcha: &Captcha) -> String {
 
 #[cfg(test)]
 mod tests {
-  use lemmy_api_common::check_validator_time;
+  use lemmy_api_common::utils::check_validator_time;
   use lemmy_db_schema::{
-    establish_unpooled_connection,
     source::{
       local_user::{LocalUser, LocalUserForm},
       person::{Person, PersonForm},
       secret::Secret,
     },
     traits::Crud,
+    utils::establish_unpooled_connection,
   };
   use lemmy_utils::{claims::Claims, settings::structs::Settings};
 
index 0630e241781773577ede7a641c52d40d2206078e..3834dbbef3b5946b700eeb310ce7554941fb21ab 100644 (file)
@@ -1,10 +1,8 @@
 use crate::Perform;
 use actix_web::web::Data;
 use lemmy_api_common::{
-  blocking,
-  get_local_user_view_from_jwt,
-  is_admin,
   person::{AddAdmin, AddAdminResponse},
+  utils::{blocking, get_local_user_view_from_jwt, is_admin},
 };
 use lemmy_db_schema::{
   source::{
@@ -13,7 +11,7 @@ use lemmy_db_schema::{
   },
   traits::Crud,
 };
-use lemmy_db_views_actor::person_view::PersonViewSafe;
+use lemmy_db_views_actor::structs::PersonViewSafe;
 use lemmy_utils::{ConnectionId, LemmyError};
 use lemmy_websocket::{messages::SendAllMessage, LemmyContext, UserOperation};
 
index 0397d09045a00d6de0f5c9efae426932e6465a74..d357e8eb9e466ac0bdc6443907cfd678e0e40371 100644 (file)
@@ -1,11 +1,8 @@
 use crate::Perform;
 use actix_web::web::Data;
 use lemmy_api_common::{
-  blocking,
-  get_local_user_view_from_jwt,
-  is_admin,
   person::{BanPerson, BanPersonResponse},
-  remove_user_data,
+  utils::{blocking, get_local_user_view_from_jwt, is_admin, remove_user_data},
 };
 use lemmy_apub::{
   activities::block::SiteOrCommunity,
@@ -19,7 +16,7 @@ use lemmy_db_schema::{
   },
   traits::Crud,
 };
-use lemmy_db_views_actor::person_view::PersonViewSafe;
+use lemmy_db_views_actor::structs::PersonViewSafe;
 use lemmy_utils::{utils::naive_from_unix, ConnectionId, LemmyError};
 use lemmy_websocket::{messages::SendAllMessage, LemmyContext, UserOperation};
 
index 5dc68dddc1bf5a2e8ae1c21d14e22e23b9c93fe0..d0812fd970e29e3f685f081f4396faea96b3a087 100644 (file)
@@ -1,15 +1,14 @@
 use crate::Perform;
 use actix_web::web::Data;
 use lemmy_api_common::{
-  blocking,
-  get_local_user_view_from_jwt,
   person::{BlockPerson, BlockPersonResponse},
+  utils::{blocking, get_local_user_view_from_jwt},
 };
 use lemmy_db_schema::{
   source::person_block::{PersonBlock, PersonBlockForm},
   traits::Blockable,
 };
-use lemmy_db_views_actor::person_view::PersonViewSafe;
+use lemmy_db_views_actor::structs::PersonViewSafe;
 use lemmy_utils::{ConnectionId, LemmyError};
 use lemmy_websocket::LemmyContext;
 
index 2b66f2ea99b64f502874edbf5a77e161aacf652d..714659980a77f67c71088b85cae6a035054bb262 100644 (file)
@@ -2,10 +2,8 @@ use crate::Perform;
 use actix_web::web::Data;
 use bcrypt::verify;
 use lemmy_api_common::{
-  blocking,
-  get_local_user_view_from_jwt,
-  password_length_check,
   person::{ChangePassword, LoginResponse},
+  utils::{blocking, get_local_user_view_from_jwt, password_length_check},
 };
 use lemmy_db_schema::source::local_user::LocalUser;
 use lemmy_utils::{claims::Claims, ConnectionId, LemmyError};
index 533a0d19374673e5b4f65fd98e0df86d2151f44b..92e4f6ba544b595baf87f9adee96dace5b312c30 100644 (file)
@@ -1,9 +1,8 @@
 use crate::Perform;
 use actix_web::web::Data;
 use lemmy_api_common::{
-  blocking,
-  password_length_check,
   person::{LoginResponse, PasswordChangeAfterReset},
+  utils::{blocking, password_length_check},
 };
 use lemmy_db_schema::source::{
   local_user::LocalUser,
index efcb6689c672a51b8fa15dc0a4f644171e5840e9..5c691b8ca1c7badcf5bbe19a71e765497291c46b 100644 (file)
@@ -3,7 +3,7 @@ use actix_web::web::Data;
 use captcha::{gen, Difficulty};
 use chrono::Duration;
 use lemmy_api_common::person::{CaptchaResponse, GetCaptcha, GetCaptchaResponse};
-use lemmy_db_schema::naive_now;
+use lemmy_db_schema::utils::naive_now;
 use lemmy_utils::{ConnectionId, LemmyError};
 use lemmy_websocket::{messages::CaptchaItem, LemmyContext};
 
index 1fef55936dda2b6708ef43b6f0f05d3a1d24014d..4c39d0cd20aff2a5268f6c624911799821f4ca39 100644 (file)
@@ -1,12 +1,10 @@
 use crate::Perform;
 use actix_web::web::Data;
 use lemmy_api_common::{
-  blocking,
-  get_local_user_view_from_jwt,
-  is_admin,
   person::{BannedPersonsResponse, GetBannedPersons},
+  utils::{blocking, get_local_user_view_from_jwt, is_admin},
 };
-use lemmy_db_views_actor::person_view::PersonViewSafe;
+use lemmy_db_views_actor::structs::PersonViewSafe;
 use lemmy_utils::{ConnectionId, LemmyError};
 use lemmy_websocket::LemmyContext;
 
index 5455b867deffe9193cea1c48535b1fd3e32a428a..e1931d5a479026e301f1b361faa08a27a59edb9f 100644 (file)
@@ -2,12 +2,11 @@ use crate::Perform;
 use actix_web::web::Data;
 use bcrypt::verify;
 use lemmy_api_common::{
-  blocking,
-  check_registration_application,
   person::{Login, LoginResponse},
+  utils::{blocking, check_registration_application},
 };
 use lemmy_db_schema::source::site::Site;
-use lemmy_db_views::local_user_view::LocalUserView;
+use lemmy_db_views::structs::LocalUserView;
 use lemmy_utils::{claims::Claims, ConnectionId, LemmyError};
 use lemmy_websocket::LemmyContext;
 
index f47d3cc77c82a13fde9755c85b36c2a18dcf45b3..91409b6d35e6fd2a650d007cf4d4c8f6287f89db 100644 (file)
@@ -1,11 +1,10 @@
 use crate::Perform;
 use actix_web::web::Data;
 use lemmy_api_common::{
-  blocking,
-  get_local_user_view_from_jwt,
   person::{GetPersonMentions, GetPersonMentionsResponse},
+  utils::{blocking, get_local_user_view_from_jwt},
 };
-use lemmy_db_schema::{from_opt_str_to_opt_enum, SortType};
+use lemmy_db_schema::utils::{from_opt_str_to_opt_enum, SortType};
 use lemmy_db_views_actor::person_mention_view::PersonMentionQueryBuilder;
 use lemmy_utils::{ConnectionId, LemmyError};
 use lemmy_websocket::LemmyContext;
index 9199421c236377391d7e3f0c0ff18f731098b546..1d9aaa2f0e222b9d0d90ae9155dcf31490c008e1 100644 (file)
@@ -1,11 +1,10 @@
 use crate::Perform;
 use actix_web::web::Data;
 use lemmy_api_common::{
-  blocking,
-  get_local_user_view_from_jwt,
   person::{GetReplies, GetRepliesResponse},
+  utils::{blocking, get_local_user_view_from_jwt},
 };
-use lemmy_db_schema::{from_opt_str_to_opt_enum, SortType};
+use lemmy_db_schema::utils::{from_opt_str_to_opt_enum, SortType};
 use lemmy_db_views::comment_view::CommentQueryBuilder;
 use lemmy_utils::{ConnectionId, LemmyError};
 use lemmy_websocket::LemmyContext;
index dc3b00d1c40c3f3b5d1b0eceb2f5d69c96937488..d5caa02d5365cc2efe4eac07b36a54d4bd04fefb 100644 (file)
@@ -1,9 +1,8 @@
 use crate::Perform;
 use actix_web::web::Data;
 use lemmy_api_common::{
-  blocking,
-  get_local_user_view_from_jwt,
   person::{GetRepliesResponse, MarkAllAsRead},
+  utils::{blocking, get_local_user_view_from_jwt},
 };
 use lemmy_db_schema::source::{
   comment::Comment,
index 33e427a6647cfcb1f2b463ffc562c90339d7e100..4c9d06014fd34cfc44326494ef255745e7dc09a7 100644 (file)
@@ -1,12 +1,11 @@
 use crate::Perform;
 use actix_web::web::Data;
 use lemmy_api_common::{
-  blocking,
-  get_local_user_view_from_jwt,
   person::{MarkPersonMentionAsRead, PersonMentionResponse},
+  utils::{blocking, get_local_user_view_from_jwt},
 };
 use lemmy_db_schema::{source::person_mention::PersonMention, traits::Crud};
-use lemmy_db_views_actor::person_mention_view::PersonMentionView;
+use lemmy_db_views_actor::structs::PersonMentionView;
 use lemmy_utils::{ConnectionId, LemmyError};
 use lemmy_websocket::LemmyContext;
 
index be8055636071ba5b780b01aafdef87725676652f..a9c06ffc73ef83203f960aa076c241b9cdaa2eed 100644 (file)
@@ -1,12 +1,11 @@
 use crate::Perform;
 use actix_web::web::Data;
 use lemmy_api_common::{
-  blocking,
-  get_local_user_view_from_jwt,
   person::{GetUnreadCount, GetUnreadCountResponse},
+  utils::{blocking, get_local_user_view_from_jwt},
 };
-use lemmy_db_views::{comment_view::CommentView, private_message_view::PrivateMessageView};
-use lemmy_db_views_actor::person_mention_view::PersonMentionView;
+use lemmy_db_views::structs::{CommentView, PrivateMessageView};
+use lemmy_db_views_actor::structs::PersonMentionView;
 use lemmy_utils::{ConnectionId, LemmyError};
 use lemmy_websocket::LemmyContext;
 
index 5aa2f46d9e4dbd7427cff796bb7dde9ac2a33992..a07f8c055fa903f0a166da06f059747ba647dd4f 100644 (file)
@@ -1,11 +1,10 @@
 use crate::Perform;
 use actix_web::web::Data;
 use lemmy_api_common::{
-  blocking,
-  get_local_user_view_from_jwt,
   person::{GetReportCount, GetReportCountResponse},
+  utils::{blocking, get_local_user_view_from_jwt},
 };
-use lemmy_db_views::{comment_report_view::CommentReportView, post_report_view::PostReportView};
+use lemmy_db_views::structs::{CommentReportView, PostReportView};
 use lemmy_utils::{ConnectionId, LemmyError};
 use lemmy_websocket::LemmyContext;
 
index 78b0364cd748593e3b1993938de6adb9dc9cd8b8..6903a8b8e770bdba55f8f80910ab9cd42ff71afe 100644 (file)
@@ -1,11 +1,10 @@
 use crate::Perform;
 use actix_web::web::Data;
 use lemmy_api_common::{
-  blocking,
   person::{PasswordReset, PasswordResetResponse},
-  send_password_reset_email,
+  utils::{blocking, send_password_reset_email},
 };
-use lemmy_db_views::local_user_view::LocalUserView;
+use lemmy_db_views::structs::LocalUserView;
 use lemmy_utils::{ConnectionId, LemmyError};
 use lemmy_websocket::LemmyContext;
 
index 15a65b01b93ce62ff23255c88357c95d42637c1f..cd34d6ddd0fcda153d04a8210f7e1538f77b770e 100644 (file)
@@ -1,22 +1,22 @@
 use crate::Perform;
 use actix_web::web::Data;
 use lemmy_api_common::{
-  blocking,
-  check_image_has_local_domain,
-  get_local_user_view_from_jwt,
   person::{LoginResponse, SaveUserSettings},
-  send_verification_email,
+  utils::{
+    blocking,
+    check_image_has_local_domain,
+    get_local_user_view_from_jwt,
+    send_verification_email,
+  },
 };
 use lemmy_db_schema::{
-  diesel_option_overwrite,
-  diesel_option_overwrite_to_url,
-  naive_now,
   source::{
     local_user::{LocalUser, LocalUserForm},
     person::{Person, PersonForm},
     site::Site,
   },
   traits::Crud,
+  utils::{diesel_option_overwrite, diesel_option_overwrite_to_url, naive_now},
 };
 use lemmy_utils::{
   claims::Claims,
index 852e1cfa65283b55850e3126d50fbc7f53c035c9..c4af8e34ebaf63cfdc88eab33dbdd8df141bab7e 100644 (file)
@@ -1,9 +1,8 @@
 use crate::Perform;
 use actix_web::web::Data;
 use lemmy_api_common::{
-  blocking,
   person::{VerifyEmail, VerifyEmailResponse},
-  send_email_verification_success,
+  utils::{blocking, send_email_verification_success},
 };
 use lemmy_db_schema::{
   source::{
@@ -12,7 +11,7 @@ use lemmy_db_schema::{
   },
   traits::Crud,
 };
-use lemmy_db_views::local_user_view::LocalUserView;
+use lemmy_db_views::structs::LocalUserView;
 use lemmy_utils::LemmyError;
 use lemmy_websocket::LemmyContext;
 
index a016bd2f7e8a19d449f07bbc553591f1ad42aeb5..db1213324166e5be77309936b81e36f6618ad1bb 100644 (file)
@@ -1,7 +1,10 @@
 use crate::Perform;
 use actix_web::web::Data;
-use lemmy_api_common::post::{GetSiteMetadata, GetSiteMetadataResponse};
-use lemmy_utils::{request::fetch_site_metadata, ConnectionId, LemmyError};
+use lemmy_api_common::{
+  post::{GetSiteMetadata, GetSiteMetadataResponse},
+  request::fetch_site_metadata,
+};
+use lemmy_utils::{ConnectionId, LemmyError};
 use lemmy_websocket::LemmyContext;
 
 #[async_trait::async_trait(?Send)]
index 22eb4775444bb73fa58a4530c201929aa40fecff..24d9337c279037ce05fd94d28f2820be3716bf8b 100644 (file)
@@ -1,13 +1,15 @@
 use crate::Perform;
 use actix_web::web::Data;
 use lemmy_api_common::{
-  blocking,
-  check_community_ban,
-  check_community_deleted_or_removed,
-  check_downvotes_enabled,
-  get_local_user_view_from_jwt,
-  mark_post_as_read,
   post::{CreatePostLike, PostResponse},
+  utils::{
+    blocking,
+    check_community_ban,
+    check_community_deleted_or_removed,
+    check_downvotes_enabled,
+    get_local_user_view_from_jwt,
+    mark_post_as_read,
+  },
 };
 use lemmy_apub::{
   fetcher::post_or_comment::PostOrComment,
index 7210d44305bd5dfa043deaa9589d4f98f3bf3496..965e506fc7dbda51affa9956521c885fedc15873 100644 (file)
@@ -1,12 +1,14 @@
 use crate::Perform;
 use actix_web::web::Data;
 use lemmy_api_common::{
-  blocking,
-  check_community_ban,
-  check_community_deleted_or_removed,
-  get_local_user_view_from_jwt,
-  is_mod_or_admin,
   post::{LockPost, PostResponse},
+  utils::{
+    blocking,
+    check_community_ban,
+    check_community_deleted_or_removed,
+    get_local_user_view_from_jwt,
+    is_mod_or_admin,
+  },
 };
 use lemmy_apub::{
   objects::post::ApubPost,
index 927fc65158077f089bf7b7db2a2bc27555ec11bc..8777ebced832a1f9b15be2046e03b1ce5907aa65 100644 (file)
@@ -1,13 +1,10 @@
 use crate::Perform;
 use actix_web::web::Data;
 use lemmy_api_common::{
-  blocking,
-  get_local_user_view_from_jwt,
-  mark_post_as_read,
-  mark_post_as_unread,
   post::{MarkPostAsRead, PostResponse},
+  utils::{blocking, get_local_user_view_from_jwt, mark_post_as_read, mark_post_as_unread},
 };
-use lemmy_db_views::post_view::PostView;
+use lemmy_db_views::structs::PostView;
 use lemmy_utils::{ConnectionId, LemmyError};
 use lemmy_websocket::LemmyContext;
 
index 973b99de9e422638b2d08361b68e8bf0f9557898..09baec988355db340c655514b06759fba45e704a 100644 (file)
@@ -1,16 +1,14 @@
 use crate::Perform;
 use actix_web::web::Data;
 use lemmy_api_common::{
-  blocking,
-  get_local_user_view_from_jwt,
-  mark_post_as_read,
   post::{PostResponse, SavePost},
+  utils::{blocking, get_local_user_view_from_jwt, mark_post_as_read},
 };
 use lemmy_db_schema::{
   source::post::{PostSaved, PostSavedForm},
   traits::Saveable,
 };
-use lemmy_db_views::post_view::PostView;
+use lemmy_db_views::structs::PostView;
 use lemmy_utils::{ConnectionId, LemmyError};
 use lemmy_websocket::LemmyContext;
 
index db6692529cb99dc13ec1ef888e30e379aa657c6a..dffe67e3394fe8344cf9fa55d4eece84bdfdf8b8 100644 (file)
@@ -1,12 +1,14 @@
 use crate::Perform;
 use actix_web::web::Data;
 use lemmy_api_common::{
-  blocking,
-  check_community_ban,
-  check_community_deleted_or_removed,
-  get_local_user_view_from_jwt,
-  is_mod_or_admin,
   post::{PostResponse, StickyPost},
+  utils::{
+    blocking,
+    check_community_ban,
+    check_community_deleted_or_removed,
+    get_local_user_view_from_jwt,
+    is_mod_or_admin,
+  },
 };
 use lemmy_apub::{
   objects::post::ApubPost,
index a85aa9a95dbf47b4392d578ff8c5932fcfdcb45a..a960e2c5332c977ca9e583b216b51bce192c6f9e 100644 (file)
@@ -1,10 +1,8 @@
 use crate::Perform;
 use actix_web::web::Data;
 use lemmy_api_common::{
-  blocking,
-  check_community_ban,
-  get_local_user_view_from_jwt,
   post::{CreatePostReport, PostReportResponse},
+  utils::{blocking, check_community_ban, get_local_user_view_from_jwt},
 };
 use lemmy_apub::protocol::activities::community::report::Report;
 use lemmy_apub_lib::object_id::ObjectId;
@@ -12,7 +10,7 @@ use lemmy_db_schema::{
   source::post_report::{PostReport, PostReportForm},
   traits::Reportable,
 };
-use lemmy_db_views::{post_report_view::PostReportView, post_view::PostView};
+use lemmy_db_views::structs::{PostReportView, PostView};
 use lemmy_utils::{ConnectionId, LemmyError};
 use lemmy_websocket::{messages::SendModRoomMessage, LemmyContext, UserOperation};
 
index 7dfbb107760f3ecd8429f2f0ca9febb70e784e0b..7ae0a5ee978a16c7e25da4bd13acce9f1b3f809e 100644 (file)
@@ -1,9 +1,8 @@
 use crate::Perform;
 use actix_web::web::Data;
 use lemmy_api_common::{
-  blocking,
-  get_local_user_view_from_jwt,
   post::{ListPostReports, ListPostReportsResponse},
+  utils::{blocking, get_local_user_view_from_jwt},
 };
 use lemmy_db_views::post_report_view::PostReportQueryBuilder;
 use lemmy_utils::{ConnectionId, LemmyError};
index f0eb3fdb8d4b22e563becf319463a6abf5e0976f..0b50999d261849a6035f875782622c1a0ba20181 100644 (file)
@@ -1,13 +1,11 @@
 use crate::Perform;
 use actix_web::web::Data;
 use lemmy_api_common::{
-  blocking,
-  get_local_user_view_from_jwt,
-  is_mod_or_admin,
   post::{PostReportResponse, ResolvePostReport},
+  utils::{blocking, get_local_user_view_from_jwt, is_mod_or_admin},
 };
 use lemmy_db_schema::{source::post_report::PostReport, traits::Reportable};
-use lemmy_db_views::post_report_view::PostReportView;
+use lemmy_db_views::structs::PostReportView;
 use lemmy_utils::{ConnectionId, LemmyError};
 use lemmy_websocket::{messages::SendModRoomMessage, LemmyContext, UserOperation};
 
index d46280bdebdec1e19bde4f62bc4f96723fafffb7..5789678365d9990a8512edd0c27bccf7386147d6 100644 (file)
@@ -1,9 +1,8 @@
 use crate::Perform;
 use actix_web::web::Data;
 use lemmy_api_common::{
-  blocking,
-  get_local_user_view_from_jwt,
   person::{MarkPrivateMessageAsRead, PrivateMessageResponse},
+  utils::{blocking, get_local_user_view_from_jwt},
 };
 use lemmy_db_schema::{source::private_message::PrivateMessage, traits::Crud};
 use lemmy_utils::{ConnectionId, LemmyError};
index 76117d49da21084be28122465540b156e079eae6..8626fd5f49f511b1d2ff693b6ef25ff74ce2aea4 100644 (file)
@@ -1,9 +1,8 @@
 use crate::Perform;
 use actix_web::web::Data;
 use lemmy_api_common::{
-  get_local_user_view_from_jwt,
-  is_admin,
   site::{GetSiteConfig, GetSiteConfigResponse},
+  utils::{get_local_user_view_from_jwt, is_admin},
 };
 use lemmy_utils::{settings::structs::Settings, ConnectionId, LemmyError};
 use lemmy_websocket::LemmyContext;
index b36c69ce77b2e1f8aebffac2dd7821e172ce4805..98f2b1f349cd1de5dff508ed2603867ff3ab502a 100644 (file)
@@ -1,9 +1,8 @@
 use crate::Perform;
 use actix_web::web::Data;
 use lemmy_api_common::{
-  get_local_user_view_from_jwt,
-  is_admin,
   site::{GetSiteConfigResponse, SaveSiteConfig},
+  utils::{get_local_user_view_from_jwt, is_admin},
 };
 use lemmy_utils::{settings::structs::Settings, ConnectionId, LemmyError};
 use lemmy_websocket::LemmyContext;
index ee714e86d99e8d6ef297f340a8528ad45181805f..10a3adc4718d734df9f2ab03d32111b707d6b633 100644 (file)
@@ -1,11 +1,8 @@
 use crate::Perform;
 use actix_web::web::Data;
 use lemmy_api_common::{
-  blocking,
-  build_federated_instances,
-  get_local_user_view_from_jwt,
-  is_admin,
   site::{GetSiteResponse, LeaveAdmin},
+  utils::{blocking, build_federated_instances, get_local_user_view_from_jwt, is_admin},
 };
 use lemmy_db_schema::{
   source::{
@@ -14,8 +11,8 @@ use lemmy_db_schema::{
   },
   traits::Crud,
 };
-use lemmy_db_views::site_view::SiteView;
-use lemmy_db_views_actor::person_view::PersonViewSafe;
+use lemmy_db_views::structs::SiteView;
+use lemmy_db_views_actor::structs::PersonViewSafe;
 use lemmy_utils::{version, ConnectionId, LemmyError};
 use lemmy_websocket::LemmyContext;
 
index 6dd06c1640a702dfe4b93d00458eead8a1a98ca5..45335d5d383140f169281998d7034bd6d1a737e9 100644 (file)
@@ -1,23 +1,21 @@
 use crate::Perform;
 use actix_web::web::Data;
 use lemmy_api_common::{
-  blocking,
-  check_private_instance,
-  get_local_user_view_from_jwt_opt,
   site::{GetModlog, GetModlogResponse},
+  utils::{blocking, check_private_instance, get_local_user_view_from_jwt_opt},
 };
-use lemmy_db_views_moderator::{
-  mod_add_community_view::ModAddCommunityView,
-  mod_add_view::ModAddView,
-  mod_ban_from_community_view::ModBanFromCommunityView,
-  mod_ban_view::ModBanView,
-  mod_hide_community_view::ModHideCommunityView,
-  mod_lock_post_view::ModLockPostView,
-  mod_remove_comment_view::ModRemoveCommentView,
-  mod_remove_community_view::ModRemoveCommunityView,
-  mod_remove_post_view::ModRemovePostView,
-  mod_sticky_post_view::ModStickyPostView,
-  mod_transfer_community_view::ModTransferCommunityView,
+use lemmy_db_views_moderator::structs::{
+  ModAddCommunityView,
+  ModAddView,
+  ModBanFromCommunityView,
+  ModBanView,
+  ModHideCommunityView,
+  ModLockPostView,
+  ModRemoveCommentView,
+  ModRemoveCommunityView,
+  ModRemovePostView,
+  ModStickyPostView,
+  ModTransferCommunityView,
 };
 use lemmy_utils::{ConnectionId, LemmyError};
 use lemmy_websocket::LemmyContext;
index 238da7e517c1d11e5bed53c02f30bcf0ea2bd1f2..2e3577de082a6929e69950d57ec39b94952c807b 100644 (file)
@@ -1,24 +1,18 @@
 use crate::Perform;
 use actix_web::web::Data;
 use lemmy_api_common::{
-  blocking,
-  get_local_user_view_from_jwt,
-  is_admin,
-  send_application_approved_email,
-  site::*,
+  site::{ApproveRegistrationApplication, RegistrationApplicationResponse},
+  utils::{blocking, get_local_user_view_from_jwt, is_admin, send_application_approved_email},
 };
 use lemmy_db_schema::{
-  diesel_option_overwrite,
   source::{
     local_user::{LocalUser, LocalUserForm},
     registration_application::{RegistrationApplication, RegistrationApplicationForm},
   },
   traits::Crud,
+  utils::diesel_option_overwrite,
 };
-use lemmy_db_views::{
-  local_user_view::LocalUserView,
-  registration_application_view::RegistrationApplicationView,
-};
+use lemmy_db_views::structs::{LocalUserView, RegistrationApplicationView};
 use lemmy_utils::{ConnectionId, LemmyError};
 use lemmy_websocket::LemmyContext;
 
index bd5170d6a2db1159078d9d856514e8cce1955890..27633aa64abdbe6763aabf5e33886898c045ef11 100644 (file)
@@ -1,10 +1,8 @@
 use crate::Perform;
 use actix_web::web::Data;
 use lemmy_api_common::{
-  blocking,
-  get_local_user_view_from_jwt,
-  is_admin,
   site::{ListRegistrationApplications, ListRegistrationApplicationsResponse},
+  utils::{blocking, get_local_user_view_from_jwt, is_admin},
 };
 use lemmy_db_schema::source::site::Site;
 use lemmy_db_views::registration_application_view::RegistrationApplicationQueryBuilder;
index 03584baf9bd4ab37db3f04bab5383f3463d73858..06f995234958ed5f302b44b436685c8cd29c7179 100644 (file)
@@ -1,13 +1,11 @@
 use crate::Perform;
 use actix_web::web::Data;
 use lemmy_api_common::{
-  blocking,
-  get_local_user_view_from_jwt,
-  is_admin,
   site::{GetUnreadRegistrationApplicationCount, GetUnreadRegistrationApplicationCountResponse},
+  utils::{blocking, get_local_user_view_from_jwt, is_admin},
 };
 use lemmy_db_schema::source::site::Site;
-use lemmy_db_views::registration_application_view::RegistrationApplicationView;
+use lemmy_db_views::structs::RegistrationApplicationView;
 use lemmy_utils::{ConnectionId, LemmyError};
 use lemmy_websocket::LemmyContext;
 
index 87f3c859a22646592d976d28eb79c186efb7bfc1..4e84e162f3be6340670e12c47d8d8cc0b4be0349 100644 (file)
@@ -2,15 +2,13 @@ use crate::Perform;
 use actix_web::web::Data;
 use diesel::NotFound;
 use lemmy_api_common::{
-  blocking,
-  check_private_instance,
-  get_local_user_view_from_jwt_opt,
   site::{ResolveObject, ResolveObjectResponse},
+  utils::{blocking, check_private_instance, get_local_user_view_from_jwt_opt},
 };
 use lemmy_apub::fetcher::search::{search_by_apub_id, SearchableObjects};
-use lemmy_db_schema::{newtypes::PersonId, DbPool};
-use lemmy_db_views::{comment_view::CommentView, post_view::PostView};
-use lemmy_db_views_actor::{community_view::CommunityView, person_view::PersonViewSafe};
+use lemmy_db_schema::{newtypes::PersonId, utils::DbPool};
+use lemmy_db_views::structs::{CommentView, PostView};
+use lemmy_db_views_actor::structs::{CommunityView, PersonViewSafe};
 use lemmy_utils::{ConnectionId, LemmyError};
 use lemmy_websocket::LemmyContext;
 
index f4f998d5343f21baa6ab77d1895164966b2f5402..b4d2069c35be718becc69c6d853d8c7249f1f75c 100644 (file)
@@ -1,19 +1,14 @@
 use crate::Perform;
 use actix_web::web::Data;
 use lemmy_api_common::{
-  blocking,
-  check_private_instance,
-  get_local_user_view_from_jwt_opt,
   site::{Search, SearchResponse},
+  utils::{blocking, check_private_instance, get_local_user_view_from_jwt_opt},
 };
 use lemmy_apub::{fetcher::resolve_actor_identifier, objects::community::ApubCommunity};
 use lemmy_db_schema::{
-  from_opt_str_to_opt_enum,
   source::community::Community,
   traits::DeleteableOrRemoveable,
-  ListingType,
-  SearchType,
-  SortType,
+  utils::{from_opt_str_to_opt_enum, ListingType, SearchType, SortType},
 };
 use lemmy_db_views::{comment_view::CommentQueryBuilder, post_view::PostQueryBuilder};
 use lemmy_db_views_actor::{
index 00a7e6867f77e1c0531486ff4b87936abc6d9e8e..aea443a96d57825b27cfb23ef8fcfc427d704db4 100644 (file)
@@ -1,6 +1,6 @@
 use crate::Perform;
 use actix_web::web::Data;
-use lemmy_api_common::{get_local_user_view_from_jwt, websocket::*};
+use lemmy_api_common::{utils::get_local_user_view_from_jwt, websocket::*};
 use lemmy_utils::{ConnectionId, LemmyError};
 use lemmy_websocket::{
   messages::{JoinCommunityRoom, JoinModRoom, JoinPostRoom, JoinUserRoom},
index 40cd753bcf3080e5e4315bf09c6e36dd22d44b3b..2ff49922722612620606459797293b760d1cf0e6 100644 (file)
@@ -12,16 +12,29 @@ name = "lemmy_api_common"
 path = "src/lib.rs"
 doctest = false
 
+[features]
+full = ["diesel", "tracing", "rosetta-i18n", "chrono", "actix-web", "lemmy_utils",
+    "lemmy_db_views/full", "lemmy_db_views_actor/full", "lemmy_db_views_moderator/full",
+    "percent-encoding", "encoding", "reqwest-middleware", "webpage"]
+
 [dependencies]
 lemmy_db_views = { version = "=0.16.3", path = "../db_views" }
 lemmy_db_views_moderator = { version = "=0.16.3", path = "../db_views_moderator" }
 lemmy_db_views_actor = { version = "=0.16.3", path = "../db_views_actor" }
-lemmy_db_schema = { version = "=0.16.3", path = "../db_schema" }
-lemmy_utils = { version = "=0.16.3", path = "../utils" }
+lemmy_db_schema = { version = "=0.16.3", path = "../db_schema", default-features = false }
+lemmy_utils = { version = "=0.16.3", path = "../utils", optional = true }
 serde = { version = "1.0.136", features = ["derive"] }
-diesel = "1.4.8"
-actix-web = { version = "4.0.1", default-features = false, features = ["cookies"] }
-chrono = { version = "0.4.19", features = ["serde"] }
-tracing = "0.1.32"
 url = "2.2.2"
-rosetta-i18n = "0.1.2"
+actix-web = { version = "4.0.1", default-features = false, features = ["cookies"], optional = true }
+chrono = { version = "0.4.19", features = ["serde"], optional = true }
+diesel = { version = "1.4.8", optional = true }
+tracing = { version = "0.1.32", optional = true }
+rosetta-i18n = { version = "0.1.2", optional = true }
+percent-encoding = { version = "2.1.0", optional = true }
+encoding = { version = "0.2.33", optional = true }
+reqwest-middleware = { version = "0.1.5", optional = true }
+webpage = { version = "1.4.0", default-features = false, features = ["serde"], optional = true }
+
+[dev-dependencies]
+actix-rt = { version = "2.7.0", default-features = false }
+reqwest = { version = "0.11.10", features = ["json"] }
index 847178000d1a7e77f043bd26ce171f9bda3ba766..048a3439943093030ffd131682d9de7c1c53b890 100644 (file)
@@ -1,6 +1,6 @@
+use crate::sensitive::Sensitive;
 use lemmy_db_schema::newtypes::{CommentId, CommentReportId, CommunityId, LocalUserId, PostId};
-use lemmy_db_views::{comment_report_view::CommentReportView, comment_view::CommentView};
-use lemmy_utils::Sensitive;
+use lemmy_db_views::structs::{CommentReportView, CommentView};
 use serde::{Deserialize, Serialize};
 
 #[derive(Debug, Serialize, Deserialize)]
index 49df41fae93a06144bab518d463d3e216dbba09a..0635b9fa0f772d28553730a7908caf6334bb4439 100644 (file)
@@ -1,13 +1,9 @@
+use crate::sensitive::Sensitive;
 use lemmy_db_schema::{
   newtypes::{CommunityId, PersonId},
   source::site::Site,
 };
-use lemmy_db_views_actor::{
-  community_moderator_view::CommunityModeratorView,
-  community_view::CommunityView,
-  person_view::PersonViewSafe,
-};
-use lemmy_utils::Sensitive;
+use lemmy_db_views_actor::structs::{CommunityModeratorView, CommunityView, PersonViewSafe};
 use serde::{Deserialize, Serialize};
 
 #[derive(Debug, Serialize, Deserialize)]
index 330c75bd0bbd3ebc549d8def92c5f511dd5c7300..0dda34ec5a06a01bf8e9e6347cbfcc38c15e156f 100644 (file)
@@ -2,612 +2,10 @@ pub mod comment;
 pub mod community;
 pub mod person;
 pub mod post;
+#[cfg(feature = "full")]
+pub mod request;
+mod sensitive;
 pub mod site;
+#[cfg(feature = "full")]
+pub mod utils;
 pub mod websocket;
-
-use crate::site::FederatedInstances;
-use lemmy_db_schema::{
-  newtypes::{CommunityId, DbUrl, LocalUserId, PersonId, PostId},
-  source::{
-    comment::Comment,
-    community::Community,
-    email_verification::{EmailVerification, EmailVerificationForm},
-    password_reset_request::PasswordResetRequest,
-    person::Person,
-    person_block::PersonBlock,
-    post::{Post, PostRead, PostReadForm},
-    registration_application::RegistrationApplication,
-    secret::Secret,
-    site::Site,
-  },
-  traits::{Crud, Readable},
-  DbPool,
-};
-use lemmy_db_views::{
-  comment_view::CommentQueryBuilder,
-  local_user_view::{LocalUserSettingsView, LocalUserView},
-};
-use lemmy_db_views_actor::{
-  community_moderator_view::CommunityModeratorView,
-  community_person_ban_view::CommunityPersonBanView,
-  community_view::CommunityView,
-};
-use lemmy_utils::{
-  claims::Claims,
-  email::{send_email, translations::Lang},
-  settings::structs::Settings,
-  utils::generate_random_string,
-  LemmyError,
-  Sensitive,
-};
-use rosetta_i18n::{Language, LanguageId};
-use tracing::warn;
-
-pub async fn blocking<F, T>(pool: &DbPool, f: F) -> Result<T, LemmyError>
-where
-  F: FnOnce(&diesel::PgConnection) -> T + Send + 'static,
-  T: Send + 'static,
-{
-  let pool = pool.clone();
-  let blocking_span = tracing::info_span!("blocking operation");
-  let res = actix_web::web::block(move || {
-    let entered = blocking_span.enter();
-    let conn = pool.get()?;
-    let res = (f)(&conn);
-    drop(entered);
-    Ok(res) as Result<T, LemmyError>
-  })
-  .await?;
-
-  res
-}
-
-#[tracing::instrument(skip_all)]
-pub async fn is_mod_or_admin(
-  pool: &DbPool,
-  person_id: PersonId,
-  community_id: CommunityId,
-) -> Result<(), LemmyError> {
-  let is_mod_or_admin = blocking(pool, move |conn| {
-    CommunityView::is_mod_or_admin(conn, person_id, community_id)
-  })
-  .await?;
-  if !is_mod_or_admin {
-    return Err(LemmyError::from_message("not_a_mod_or_admin"));
-  }
-  Ok(())
-}
-
-pub fn is_admin(local_user_view: &LocalUserView) -> Result<(), LemmyError> {
-  if !local_user_view.person.admin {
-    return Err(LemmyError::from_message("not_an_admin"));
-  }
-  Ok(())
-}
-
-#[tracing::instrument(skip_all)]
-pub async fn get_post(post_id: PostId, pool: &DbPool) -> Result<Post, LemmyError> {
-  blocking(pool, move |conn| Post::read(conn, post_id))
-    .await?
-    .map_err(|e| LemmyError::from_error_message(e, "couldnt_find_post"))
-}
-
-#[tracing::instrument(skip_all)]
-pub async fn mark_post_as_read(
-  person_id: PersonId,
-  post_id: PostId,
-  pool: &DbPool,
-) -> Result<PostRead, LemmyError> {
-  let post_read_form = PostReadForm { post_id, person_id };
-
-  blocking(pool, move |conn| {
-    PostRead::mark_as_read(conn, &post_read_form)
-  })
-  .await?
-  .map_err(|e| LemmyError::from_error_message(e, "couldnt_mark_post_as_read"))
-}
-
-#[tracing::instrument(skip_all)]
-pub async fn mark_post_as_unread(
-  person_id: PersonId,
-  post_id: PostId,
-  pool: &DbPool,
-) -> Result<usize, LemmyError> {
-  let post_read_form = PostReadForm { post_id, person_id };
-
-  blocking(pool, move |conn| {
-    PostRead::mark_as_unread(conn, &post_read_form)
-  })
-  .await?
-  .map_err(|e| LemmyError::from_error_message(e, "couldnt_mark_post_as_read"))
-}
-
-#[tracing::instrument(skip_all)]
-pub async fn get_local_user_view_from_jwt(
-  jwt: &str,
-  pool: &DbPool,
-  secret: &Secret,
-) -> Result<LocalUserView, LemmyError> {
-  let claims = Claims::decode(jwt, &secret.jwt_secret)
-    .map_err(|e| e.with_message("not_logged_in"))?
-    .claims;
-  let local_user_id = LocalUserId(claims.sub);
-  let local_user_view =
-    blocking(pool, move |conn| LocalUserView::read(conn, local_user_id)).await??;
-  // Check for a site ban
-  if local_user_view.person.is_banned() {
-    return Err(LemmyError::from_message("site_ban"));
-  }
-
-  // Check for user deletion
-  if local_user_view.person.deleted {
-    return Err(LemmyError::from_message("deleted"));
-  }
-
-  check_validator_time(&local_user_view.local_user.validator_time, &claims)?;
-
-  Ok(local_user_view)
-}
-
-/// Checks if user's token was issued before user's password reset.
-pub fn check_validator_time(
-  validator_time: &chrono::NaiveDateTime,
-  claims: &Claims,
-) -> Result<(), LemmyError> {
-  let user_validation_time = validator_time.timestamp();
-  if user_validation_time > claims.iat {
-    Err(LemmyError::from_message("not_logged_in"))
-  } else {
-    Ok(())
-  }
-}
-
-#[tracing::instrument(skip_all)]
-pub async fn get_local_user_view_from_jwt_opt(
-  jwt: Option<&Sensitive<String>>,
-  pool: &DbPool,
-  secret: &Secret,
-) -> Result<Option<LocalUserView>, LemmyError> {
-  match jwt {
-    Some(jwt) => Ok(Some(get_local_user_view_from_jwt(jwt, pool, secret).await?)),
-    None => Ok(None),
-  }
-}
-
-#[tracing::instrument(skip_all)]
-pub async fn get_local_user_settings_view_from_jwt(
-  jwt: &Sensitive<String>,
-  pool: &DbPool,
-  secret: &Secret,
-) -> Result<LocalUserSettingsView, LemmyError> {
-  let claims = Claims::decode(jwt.as_ref(), &secret.jwt_secret)
-    .map_err(|e| e.with_message("not_logged_in"))?
-    .claims;
-  let local_user_id = LocalUserId(claims.sub);
-  let local_user_view = blocking(pool, move |conn| {
-    LocalUserSettingsView::read(conn, local_user_id)
-  })
-  .await??;
-  // Check for a site ban
-  if local_user_view.person.is_banned() {
-    return Err(LemmyError::from_message("site_ban"));
-  }
-
-  check_validator_time(&local_user_view.local_user.validator_time, &claims)?;
-
-  Ok(local_user_view)
-}
-
-#[tracing::instrument(skip_all)]
-pub async fn get_local_user_settings_view_from_jwt_opt(
-  jwt: Option<&Sensitive<String>>,
-  pool: &DbPool,
-  secret: &Secret,
-) -> Result<Option<LocalUserSettingsView>, LemmyError> {
-  match jwt {
-    Some(jwt) => Ok(Some(
-      get_local_user_settings_view_from_jwt(jwt, pool, secret).await?,
-    )),
-    None => Ok(None),
-  }
-}
-
-#[tracing::instrument(skip_all)]
-pub async fn check_community_ban(
-  person_id: PersonId,
-  community_id: CommunityId,
-  pool: &DbPool,
-) -> Result<(), LemmyError> {
-  let is_banned =
-    move |conn: &'_ _| CommunityPersonBanView::get(conn, person_id, community_id).is_ok();
-  if blocking(pool, is_banned).await? {
-    Err(LemmyError::from_message("community_ban"))
-  } else {
-    Ok(())
-  }
-}
-
-#[tracing::instrument(skip_all)]
-pub async fn check_community_deleted_or_removed(
-  community_id: CommunityId,
-  pool: &DbPool,
-) -> Result<(), LemmyError> {
-  let community = blocking(pool, move |conn| Community::read(conn, community_id))
-    .await?
-    .map_err(|e| LemmyError::from_error_message(e, "couldnt_find_community"))?;
-  if community.deleted || community.removed {
-    Err(LemmyError::from_message("deleted"))
-  } else {
-    Ok(())
-  }
-}
-
-pub fn check_post_deleted_or_removed(post: &Post) -> Result<(), LemmyError> {
-  if post.deleted || post.removed {
-    Err(LemmyError::from_message("deleted"))
-  } else {
-    Ok(())
-  }
-}
-
-#[tracing::instrument(skip_all)]
-pub async fn check_person_block(
-  my_id: PersonId,
-  potential_blocker_id: PersonId,
-  pool: &DbPool,
-) -> Result<(), LemmyError> {
-  let is_blocked = move |conn: &'_ _| PersonBlock::read(conn, potential_blocker_id, my_id).is_ok();
-  if blocking(pool, is_blocked).await? {
-    Err(LemmyError::from_message("person_block"))
-  } else {
-    Ok(())
-  }
-}
-
-#[tracing::instrument(skip_all)]
-pub async fn check_downvotes_enabled(score: i16, pool: &DbPool) -> Result<(), LemmyError> {
-  if score == -1 {
-    let site = blocking(pool, Site::read_local_site).await??;
-    if !site.enable_downvotes {
-      return Err(LemmyError::from_message("downvotes_disabled"));
-    }
-  }
-  Ok(())
-}
-
-#[tracing::instrument(skip_all)]
-pub async fn check_private_instance(
-  local_user_view: &Option<LocalUserView>,
-  pool: &DbPool,
-) -> Result<(), LemmyError> {
-  if local_user_view.is_none() {
-    let site = blocking(pool, Site::read_local_site).await?;
-
-    // The site might not be set up yet
-    if let Ok(site) = site {
-      if site.private_instance {
-        return Err(LemmyError::from_message("instance_is_private"));
-      }
-    }
-  }
-  Ok(())
-}
-
-#[tracing::instrument(skip_all)]
-pub async fn build_federated_instances(
-  pool: &DbPool,
-  settings: &Settings,
-) -> Result<Option<FederatedInstances>, LemmyError> {
-  let federation_config = &settings.federation;
-  let hostname = &settings.hostname;
-  let federation = federation_config.to_owned();
-  if federation.enabled {
-    let distinct_communities = blocking(pool, move |conn| {
-      Community::distinct_federated_communities(conn)
-    })
-    .await??;
-
-    let allowed = federation.allowed_instances;
-    let blocked = federation.blocked_instances;
-
-    let mut linked = distinct_communities
-      .iter()
-      .map(|actor_id| Ok(actor_id.host_str().unwrap_or("").to_string()))
-      .collect::<Result<Vec<String>, LemmyError>>()?;
-
-    if let Some(allowed) = allowed.as_ref() {
-      linked.extend_from_slice(allowed);
-    }
-
-    if let Some(blocked) = blocked.as_ref() {
-      linked.retain(|a| !blocked.contains(a) && !a.eq(hostname));
-    }
-
-    // Sort and remove dupes
-    linked.sort_unstable();
-    linked.dedup();
-
-    Ok(Some(FederatedInstances {
-      linked,
-      allowed,
-      blocked,
-    }))
-  } else {
-    Ok(None)
-  }
-}
-
-/// Checks the password length
-pub fn password_length_check(pass: &str) -> Result<(), LemmyError> {
-  if !(10..=60).contains(&pass.len()) {
-    Err(LemmyError::from_message("invalid_password"))
-  } else {
-    Ok(())
-  }
-}
-
-/// Checks the site description length
-pub fn site_description_length_check(description: &str) -> Result<(), LemmyError> {
-  if description.len() > 150 {
-    Err(LemmyError::from_message("site_description_length_overflow"))
-  } else {
-    Ok(())
-  }
-}
-
-/// Checks for a honeypot. If this field is filled, fail the rest of the function
-pub fn honeypot_check(honeypot: &Option<String>) -> Result<(), LemmyError> {
-  if honeypot.is_some() {
-    Err(LemmyError::from_message("honeypot_fail"))
-  } else {
-    Ok(())
-  }
-}
-
-pub fn send_email_to_user(
-  local_user_view: &LocalUserView,
-  subject: &str,
-  body: &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 {
-    match send_email(
-      subject,
-      user_email,
-      &local_user_view.person.name,
-      body,
-      settings,
-    ) {
-      Ok(_o) => _o,
-      Err(e) => warn!("{}", e),
-    };
-  }
-}
-
-pub async fn send_password_reset_email(
-  user: &LocalUserView,
-  pool: &DbPool,
-  settings: &Settings,
-) -> Result<(), LemmyError> {
-  // Generate a random token
-  let token = generate_random_string();
-
-  // Insert the row
-  let token2 = token.clone();
-  let local_user_id = user.local_user.id;
-  blocking(pool, move |conn| {
-    PasswordResetRequest::create_token(conn, local_user_id, &token2)
-  })
-  .await??;
-
-  let email = &user.local_user.email.to_owned().expect("email");
-  let lang = get_user_lang(user);
-  let subject = &lang.password_reset_subject(&user.person.name);
-  let protocol_and_hostname = settings.get_protocol_and_hostname();
-  let reset_link = format!("{}/password_change/{}", protocol_and_hostname, &token);
-  let body = &lang.password_reset_body(&user.person.name, reset_link);
-  send_email(subject, email, &user.person.name, body, settings)
-}
-
-/// Send a verification email
-pub async fn send_verification_email(
-  user: &LocalUserView,
-  new_email: &str,
-  pool: &DbPool,
-  settings: &Settings,
-) -> Result<(), LemmyError> {
-  let form = EmailVerificationForm {
-    local_user_id: user.local_user.id,
-    email: new_email.to_string(),
-    verification_token: generate_random_string(),
-  };
-  let verify_link = format!(
-    "{}/verify_email/{}",
-    settings.get_protocol_and_hostname(),
-    &form.verification_token
-  );
-  blocking(pool, move |conn| EmailVerification::create(conn, &form)).await??;
-
-  let lang = get_user_lang(user);
-  let subject = lang.verify_email_subject(&settings.hostname);
-  let body = lang.verify_email_body(&user.person.name, &settings.hostname, verify_link);
-  send_email(&subject, new_email, &user.person.name, &body, settings)?;
-
-  Ok(())
-}
-
-pub fn send_email_verification_success(
-  user: &LocalUserView,
-  settings: &Settings,
-) -> Result<(), LemmyError> {
-  let email = &user.local_user.email.to_owned().expect("email");
-  let lang = get_user_lang(user);
-  let subject = &lang.email_verified_subject(&user.person.actor_id);
-  let body = &lang.email_verified_body();
-  send_email(subject, email, &user.person.name, body, settings)
-}
-
-pub fn get_user_lang(user: &LocalUserView) -> Lang {
-  let user_lang = LanguageId::new(user.local_user.lang.clone());
-  Lang::from_language_id(&user_lang).unwrap_or_else(|| {
-    let en = LanguageId::new("en");
-    Lang::from_language_id(&en).expect("default language")
-  })
-}
-
-pub fn send_application_approved_email(
-  user: &LocalUserView,
-  settings: &Settings,
-) -> Result<(), LemmyError> {
-  let email = &user.local_user.email.to_owned().expect("email");
-  let lang = get_user_lang(user);
-  let subject = lang.registration_approved_subject(&user.person.actor_id);
-  let body = lang.registration_approved_body(&settings.hostname);
-  send_email(&subject, email, &user.person.name, &body, settings)
-}
-
-pub async fn check_registration_application(
-  site: &Site,
-  local_user_view: &LocalUserView,
-  pool: &DbPool,
-) -> Result<(), LemmyError> {
-  if site.require_application
-    && !local_user_view.local_user.accepted_application
-    && !local_user_view.person.admin
-  {
-    // Fetch the registration, see if its denied
-    let local_user_id = local_user_view.local_user.id;
-    let registration = blocking(pool, move |conn| {
-      RegistrationApplication::find_by_local_user_id(conn, local_user_id)
-    })
-    .await??;
-    if let Some(deny_reason) = registration.deny_reason {
-      let lang = get_user_lang(local_user_view);
-      let registration_denied_message = format!("{}: {}", lang.registration_denied(), &deny_reason);
-      return Err(LemmyError::from_message(&registration_denied_message));
-    } else {
-      return Err(LemmyError::from_message("registration_application_pending"));
-    }
-  }
-  Ok(())
-}
-
-/// TODO this check should be removed after https://github.com/LemmyNet/lemmy/issues/868 is done.
-pub async fn check_private_instance_and_federation_enabled(
-  pool: &DbPool,
-  settings: &Settings,
-) -> Result<(), LemmyError> {
-  let site_opt = blocking(pool, Site::read_local_site).await?;
-
-  if let Ok(site) = site_opt {
-    if site.private_instance && settings.federation.enabled {
-      return Err(LemmyError::from_message(
-        "Cannot have both private instance and federation enabled.",
-      ));
-    }
-  }
-  Ok(())
-}
-
-pub async fn remove_user_data(banned_person_id: PersonId, pool: &DbPool) -> Result<(), LemmyError> {
-  // Posts
-  blocking(pool, move |conn: &'_ _| {
-    Post::update_removed_for_creator(conn, banned_person_id, None, true)
-  })
-  .await??;
-
-  // Communities
-  // Remove all communities where they're the top mod
-  // for now, remove the communities manually
-  let first_mod_communities = blocking(pool, move |conn: &'_ _| {
-    CommunityModeratorView::get_community_first_mods(conn)
-  })
-  .await??;
-
-  // Filter to only this banned users top communities
-  let banned_user_first_communities: Vec<CommunityModeratorView> = first_mod_communities
-    .into_iter()
-    .filter(|fmc| fmc.moderator.id == banned_person_id)
-    .collect();
-
-  for first_mod_community in banned_user_first_communities {
-    blocking(pool, move |conn: &'_ _| {
-      Community::update_removed(conn, first_mod_community.community.id, true)
-    })
-    .await??;
-  }
-
-  // Comments
-  blocking(pool, move |conn: &'_ _| {
-    Comment::update_removed_for_creator(conn, banned_person_id, true)
-  })
-  .await??;
-
-  Ok(())
-}
-
-pub async fn remove_user_data_in_community(
-  community_id: CommunityId,
-  banned_person_id: PersonId,
-  pool: &DbPool,
-) -> Result<(), LemmyError> {
-  // Posts
-  blocking(pool, move |conn| {
-    Post::update_removed_for_creator(conn, banned_person_id, Some(community_id), true)
-  })
-  .await??;
-
-  // Comments
-  // TODO Diesel doesn't allow updates with joins, so this has to be a loop
-  let comments = blocking(pool, move |conn| {
-    CommentQueryBuilder::create(conn)
-      .creator_id(banned_person_id)
-      .community_id(community_id)
-      .limit(std::i64::MAX)
-      .list()
-  })
-  .await??;
-
-  for comment_view in &comments {
-    let comment_id = comment_view.comment.id;
-    blocking(pool, move |conn| {
-      Comment::update_removed(conn, comment_id, true)
-    })
-    .await??;
-  }
-
-  Ok(())
-}
-
-pub async fn delete_user_account(person_id: PersonId, pool: &DbPool) -> Result<(), LemmyError> {
-  // Comments
-  let permadelete = move |conn: &'_ _| Comment::permadelete_for_creator(conn, person_id);
-  blocking(pool, permadelete)
-    .await?
-    .map_err(|e| LemmyError::from_error_message(e, "couldnt_update_comment"))?;
-
-  // Posts
-  let permadelete = move |conn: &'_ _| Post::permadelete_for_creator(conn, person_id);
-  blocking(pool, permadelete)
-    .await?
-    .map_err(|e| LemmyError::from_error_message(e, "couldnt_update_post"))?;
-
-  blocking(pool, move |conn| Person::delete_account(conn, person_id)).await??;
-
-  Ok(())
-}
-
-pub fn check_image_has_local_domain(url: &Option<DbUrl>) -> Result<(), LemmyError> {
-  if let Some(url) = url {
-    let settings = Settings::get();
-    let domain = url.domain().expect("url has domain");
-    if domain != settings.hostname {
-      return Err(LemmyError::from_message("image_not_local"));
-    }
-  }
-  Ok(())
-}
index 898efbf5d3dbf18b8eb223864a75538c7e36aa69..3bc09f774cd06f4392ee38fa0c8ccb6881176619 100644 (file)
@@ -1,14 +1,6 @@
-use lemmy_db_views::{
-  comment_view::CommentView,
-  post_view::PostView,
-  private_message_view::PrivateMessageView,
-};
-use lemmy_db_views_actor::{
-  community_moderator_view::CommunityModeratorView,
-  person_mention_view::PersonMentionView,
-  person_view::PersonViewSafe,
-};
-use lemmy_utils::Sensitive;
+use crate::sensitive::Sensitive;
+use lemmy_db_views::structs::{CommentView, PostView, PrivateMessageView};
+use lemmy_db_views_actor::structs::{CommunityModeratorView, PersonMentionView, PersonViewSafe};
 use serde::{Deserialize, Serialize};
 
 #[derive(Debug, Serialize, Deserialize)]
index 7f8ea31995165fb971055343255fd2165303b2ec..afab5e3054a5d55f4103798275d184338179e6b7 100644 (file)
@@ -1,14 +1,7 @@
+use crate::sensitive::Sensitive;
 use lemmy_db_schema::newtypes::{CommunityId, PostId, PostReportId};
-use lemmy_db_views::{
-  comment_view::CommentView,
-  post_report_view::PostReportView,
-  post_view::PostView,
-};
-use lemmy_db_views_actor::{
-  community_moderator_view::CommunityModeratorView,
-  community_view::CommunityView,
-};
-use lemmy_utils::{request::SiteMetadata, Sensitive};
+use lemmy_db_views::structs::{CommentView, PostReportView, PostView};
+use lemmy_db_views_actor::structs::{CommunityModeratorView, CommunityView};
 use serde::{Deserialize, Serialize};
 use url::Url;
 
@@ -164,3 +157,11 @@ pub struct GetSiteMetadata {
 pub struct GetSiteMetadataResponse {
   pub metadata: SiteMetadata,
 }
+
+#[derive(Deserialize, Serialize, Debug, PartialEq, Clone)]
+pub struct SiteMetadata {
+  pub title: Option<String>,
+  pub description: Option<String>,
+  pub(crate) image: Option<Url>,
+  pub html: Option<String>,
+}
diff --git a/crates/api_common/src/request.rs b/crates/api_common/src/request.rs
new file mode 100644 (file)
index 0000000..7e3b215
--- /dev/null
@@ -0,0 +1,274 @@
+use crate::post::SiteMetadata;
+use encoding::{all::encodings, DecoderTrap};
+use lemmy_utils::{settings::structs::Settings, version::VERSION, LemmyError, REQWEST_TIMEOUT};
+use percent_encoding::{utf8_percent_encode, NON_ALPHANUMERIC};
+use reqwest_middleware::ClientWithMiddleware;
+use serde::Deserialize;
+use tracing::info;
+use url::Url;
+use webpage::HTML;
+
+/// Fetches the post link html tags (like title, description, image, etc)
+#[tracing::instrument(skip_all)]
+pub async fn fetch_site_metadata(
+  client: &ClientWithMiddleware,
+  url: &Url,
+) -> Result<SiteMetadata, LemmyError> {
+  info!("Fetching site metadata for url: {}", url);
+  let response = client
+    .get(url.as_str())
+    .timeout(REQWEST_TIMEOUT)
+    .send()
+    .await?;
+
+  // Can't use .text() here, because it only checks the content header, not the actual bytes
+  // https://github.com/LemmyNet/lemmy/issues/1964
+  let html_bytes = response.bytes().await.map_err(LemmyError::from)?.to_vec();
+
+  let tags = html_to_site_metadata(&html_bytes)?;
+
+  Ok(tags)
+}
+
+fn html_to_site_metadata(html_bytes: &[u8]) -> Result<SiteMetadata, LemmyError> {
+  let html = String::from_utf8_lossy(html_bytes);
+
+  // Make sure the first line is doctype html
+  let first_line = html
+    .trim_start()
+    .lines()
+    .into_iter()
+    .next()
+    .ok_or_else(|| LemmyError::from_message("No lines in html"))?
+    .to_lowercase();
+
+  if !first_line.starts_with("<!doctype html>") {
+    return Err(LemmyError::from_message(
+      "Site metadata page fetch is not DOCTYPE html",
+    ));
+  }
+
+  let mut page = HTML::from_string(html.to_string(), None)?;
+
+  // If the web page specifies that it isn't actually UTF-8, re-decode the received bytes with the
+  // proper encoding. If the specified encoding cannot be found, fall back to the original UTF-8
+  // version.
+  if let Some(charset) = page.meta.get("charset") {
+    if charset.to_lowercase() != "utf-8" {
+      if let Some(encoding_ref) = encodings().iter().find(|e| e.name() == charset) {
+        if let Ok(html_with_encoding) = encoding_ref.decode(html_bytes, DecoderTrap::Replace) {
+          page = HTML::from_string(html_with_encoding, None)?;
+        }
+      }
+    }
+  }
+
+  let page_title = page.title;
+  let page_description = page.description;
+
+  let og_description = page
+    .opengraph
+    .properties
+    .get("description")
+    .map(|t| t.to_string());
+  let og_title = page
+    .opengraph
+    .properties
+    .get("title")
+    .map(|t| t.to_string());
+  let og_image = page
+    .opengraph
+    .images
+    .get(0)
+    .and_then(|ogo| Url::parse(&ogo.url).ok());
+
+  let title = og_title.or(page_title);
+  let description = og_description.or(page_description);
+  let image = og_image;
+
+  Ok(SiteMetadata {
+    title,
+    description,
+    image,
+    html: None,
+  })
+}
+
+#[derive(Deserialize, Debug, Clone)]
+pub(crate) struct PictrsResponse {
+  files: Vec<PictrsFile>,
+  msg: String,
+}
+
+#[derive(Deserialize, Debug, Clone)]
+pub(crate) struct PictrsFile {
+  file: String,
+  #[allow(dead_code)]
+  delete_token: String,
+}
+
+#[tracing::instrument(skip_all)]
+pub(crate) async fn fetch_pictrs(
+  client: &ClientWithMiddleware,
+  settings: &Settings,
+  image_url: &Url,
+) -> Result<PictrsResponse, LemmyError> {
+  if let Some(pictrs_url) = settings.pictrs_url.to_owned() {
+    is_image_content_type(client, image_url).await?;
+
+    let fetch_url = format!(
+      "{}/image/download?url={}",
+      pictrs_url,
+      utf8_percent_encode(image_url.as_str(), NON_ALPHANUMERIC) // TODO this might not be needed
+    );
+
+    let response = client
+      .get(&fetch_url)
+      .timeout(REQWEST_TIMEOUT)
+      .send()
+      .await?;
+
+    let response: PictrsResponse = response.json().await.map_err(LemmyError::from)?;
+
+    if response.msg == "ok" {
+      Ok(response)
+    } else {
+      Err(LemmyError::from_message(&response.msg))
+    }
+  } else {
+    Err(LemmyError::from_message("pictrs_url not set up in config"))
+  }
+}
+
+/// Both are options, since the URL might be either an html page, or an image
+/// Returns the SiteMetadata, and a Pictrs URL, if there is a picture associated
+#[tracing::instrument(skip_all)]
+pub async fn fetch_site_data(
+  client: &ClientWithMiddleware,
+  settings: &Settings,
+  url: Option<&Url>,
+) -> (Option<SiteMetadata>, Option<Url>) {
+  match &url {
+    Some(url) => {
+      // Fetch metadata
+      // Ignore errors, since it may be an image, or not have the data.
+      // Warning, this may ignore SSL errors
+      let metadata_option = fetch_site_metadata(client, url).await.ok();
+
+      // Fetch pictrs thumbnail
+      let pictrs_hash = match &metadata_option {
+        Some(metadata_res) => match &metadata_res.image {
+          // Metadata, with image
+          // Try to generate a small thumbnail if there's a full sized one from post-links
+          Some(metadata_image) => fetch_pictrs(client, settings, metadata_image)
+            .await
+            .map(|r| r.files[0].file.to_owned()),
+          // Metadata, but no image
+          None => fetch_pictrs(client, settings, url)
+            .await
+            .map(|r| r.files[0].file.to_owned()),
+        },
+        // No metadata, try to fetch the URL as an image
+        None => fetch_pictrs(client, settings, url)
+          .await
+          .map(|r| r.files[0].file.to_owned()),
+      };
+
+      // The full urls are necessary for federation
+      let pictrs_thumbnail = pictrs_hash
+        .map(|p| {
+          Url::parse(&format!(
+            "{}/pictrs/image/{}",
+            settings.get_protocol_and_hostname(),
+            p
+          ))
+          .ok()
+        })
+        .ok()
+        .flatten();
+
+      (metadata_option, pictrs_thumbnail)
+    }
+    None => (None, None),
+  }
+}
+
+#[tracing::instrument(skip_all)]
+async fn is_image_content_type(client: &ClientWithMiddleware, url: &Url) -> Result<(), LemmyError> {
+  let response = client
+    .get(url.as_str())
+    .timeout(REQWEST_TIMEOUT)
+    .send()
+    .await?;
+  if response
+    .headers()
+    .get("Content-Type")
+    .ok_or_else(|| LemmyError::from_message("No Content-Type header"))?
+    .to_str()?
+    .starts_with("image/")
+  {
+    Ok(())
+  } else {
+    Err(LemmyError::from_message("Not an image type."))
+  }
+}
+
+pub fn build_user_agent(settings: &Settings) -> String {
+  format!(
+    "Lemmy/{}; +{}",
+    VERSION,
+    settings.get_protocol_and_hostname()
+  )
+}
+
+#[cfg(test)]
+mod tests {
+  use crate::request::{build_user_agent, fetch_site_metadata, SiteMetadata};
+  use lemmy_utils::settings::structs::Settings;
+  use url::Url;
+
+  // These helped with testing
+  #[actix_rt::test]
+  async fn test_site_metadata() {
+    let settings = Settings::init().unwrap();
+    let client = reqwest::Client::builder()
+      .user_agent(build_user_agent(&settings))
+      .build()
+      .unwrap()
+      .into();
+    let sample_url = Url::parse("https://gitlab.com/IzzyOnDroid/repo/-/wikis/FAQ").unwrap();
+    let sample_res = fetch_site_metadata(&client, &sample_url).await.unwrap();
+    assert_eq!(
+      SiteMetadata {
+        title: Some("FAQ · Wiki · IzzyOnDroid / repo · GitLab".to_string()),
+        description: Some(
+          "The F-Droid compatible repo at https://apt.izzysoft.de/fdroid/".to_string()
+        ),
+        image: Some(
+          Url::parse("https://gitlab.com/uploads/-/system/project/avatar/4877469/iod_logo.png")
+            .unwrap()
+        ),
+        html: None,
+      },
+      sample_res
+    );
+
+    let youtube_url = Url::parse("https://www.youtube.com/watch?v=IquO_TcMZIQ").unwrap();
+    let youtube_res = fetch_site_metadata(&client, &youtube_url).await.unwrap();
+    assert_eq!(
+      SiteMetadata {
+        title: Some("A Hard Look at Rent and Rent Seeking with Michael Hudson & Pepe Escobar".to_string()),
+        description: Some("An interactive discussion on wealth inequality and the “Great Game” on the control of natural resources.In this webinar organized jointly by the Henry George...".to_string()),
+        image: Some(Url::parse("https://i.ytimg.com/vi/IquO_TcMZIQ/maxresdefault.jpg").unwrap()),
+        html: None,
+      }, youtube_res);
+  }
+
+  // #[test]
+  // fn test_pictshare() {
+  //   let res = fetch_pictshare("https://upload.wikimedia.org/wikipedia/en/2/27/The_Mandalorian_logo.jpg");
+  //   assert!(res.is_ok());
+  //   let res_other = fetch_pictshare("https://upload.wikimedia.org/wikipedia/en/2/27/The_Mandalorian_logo.jpgaoeu");
+  //   assert!(res_other.is_err());
+  // }
+}
similarity index 90%
rename from crates/utils/src/sensitive.rs
rename to crates/api_common/src/sensitive.rs
index c71f357e27f68addaec425799ca051c62c3d2ecf..7713bc8261ae0fe7617df45a4e5d01be29de0638 100644 (file)
@@ -1,9 +1,10 @@
+use serde::{Deserialize, Serialize};
 use std::{
   borrow::Borrow,
   ops::{Deref, DerefMut},
 };
 
-#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, serde::Deserialize, serde::Serialize)]
+#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Deserialize, Serialize)]
 #[serde(transparent)]
 pub struct Sensitive<T>(T);
 
@@ -12,8 +13,8 @@ impl<T> Sensitive<T> {
     Sensitive(item)
   }
 
-  pub fn into_inner(this: Self) -> T {
-    this.0
+  pub fn into_inner(self) -> T {
+    self.0
   }
 }
 
index f7329822ba25e74c191b9f08a6f5fceb6a5dfdcb..da17eb050ff276da7332894a1e798b0f3a52eb05 100644 (file)
@@ -1,33 +1,33 @@
+use crate::sensitive::Sensitive;
 use lemmy_db_schema::newtypes::{CommunityId, PersonId};
-use lemmy_db_views::{
-  comment_view::CommentView,
-  local_user_view::LocalUserSettingsView,
-  post_view::PostView,
-  registration_application_view::RegistrationApplicationView,
-  site_view::SiteView,
+use lemmy_db_views::structs::{
+  CommentView,
+  LocalUserSettingsView,
+  PostView,
+  RegistrationApplicationView,
+  SiteView,
 };
-use lemmy_db_views_actor::{
-  community_block_view::CommunityBlockView,
-  community_follower_view::CommunityFollowerView,
-  community_moderator_view::CommunityModeratorView,
-  community_view::CommunityView,
-  person_block_view::PersonBlockView,
-  person_view::PersonViewSafe,
+use lemmy_db_views_actor::structs::{
+  CommunityBlockView,
+  CommunityFollowerView,
+  CommunityModeratorView,
+  CommunityView,
+  PersonBlockView,
+  PersonViewSafe,
 };
-use lemmy_db_views_moderator::{
-  mod_add_community_view::ModAddCommunityView,
-  mod_add_view::ModAddView,
-  mod_ban_from_community_view::ModBanFromCommunityView,
-  mod_ban_view::ModBanView,
-  mod_hide_community_view::ModHideCommunityView,
-  mod_lock_post_view::ModLockPostView,
-  mod_remove_comment_view::ModRemoveCommentView,
-  mod_remove_community_view::ModRemoveCommunityView,
-  mod_remove_post_view::ModRemovePostView,
-  mod_sticky_post_view::ModStickyPostView,
-  mod_transfer_community_view::ModTransferCommunityView,
+use lemmy_db_views_moderator::structs::{
+  ModAddCommunityView,
+  ModAddView,
+  ModBanFromCommunityView,
+  ModBanView,
+  ModHideCommunityView,
+  ModLockPostView,
+  ModRemoveCommentView,
+  ModRemoveCommunityView,
+  ModRemovePostView,
+  ModStickyPostView,
+  ModTransferCommunityView,
 };
-use lemmy_utils::Sensitive;
 use serde::{Deserialize, Serialize};
 
 #[derive(Serialize, Deserialize, Debug)]
diff --git a/crates/api_common/src/utils.rs b/crates/api_common/src/utils.rs
new file mode 100644 (file)
index 0000000..38ea9a8
--- /dev/null
@@ -0,0 +1,605 @@
+use crate::{sensitive::Sensitive, site::FederatedInstances};
+use lemmy_db_schema::{
+  newtypes::{CommunityId, DbUrl, LocalUserId, PersonId, PostId},
+  source::{
+    comment::Comment,
+    community::Community,
+    email_verification::{EmailVerification, EmailVerificationForm},
+    password_reset_request::PasswordResetRequest,
+    person::Person,
+    person_block::PersonBlock,
+    post::{Post, PostRead, PostReadForm},
+    registration_application::RegistrationApplication,
+    secret::Secret,
+    site::Site,
+  },
+  traits::{Crud, Readable},
+  utils::DbPool,
+};
+use lemmy_db_views::{
+  comment_view::CommentQueryBuilder,
+  structs::{LocalUserSettingsView, LocalUserView},
+};
+use lemmy_db_views_actor::structs::{
+  CommunityModeratorView,
+  CommunityPersonBanView,
+  CommunityView,
+};
+use lemmy_utils::{
+  claims::Claims,
+  email::{send_email, translations::Lang},
+  settings::structs::Settings,
+  utils::generate_random_string,
+  LemmyError,
+};
+use rosetta_i18n::{Language, LanguageId};
+use tracing::warn;
+
+pub async fn blocking<F, T>(pool: &DbPool, f: F) -> Result<T, LemmyError>
+where
+  F: FnOnce(&diesel::PgConnection) -> T + Send + 'static,
+  T: Send + 'static,
+{
+  let pool = pool.clone();
+  let blocking_span = tracing::info_span!("blocking operation");
+  let res = actix_web::web::block(move || {
+    let entered = blocking_span.enter();
+    let conn = pool.get()?;
+    let res = (f)(&conn);
+    drop(entered);
+    Ok(res) as Result<T, LemmyError>
+  })
+  .await?;
+
+  res
+}
+
+#[tracing::instrument(skip_all)]
+pub async fn is_mod_or_admin(
+  pool: &DbPool,
+  person_id: PersonId,
+  community_id: CommunityId,
+) -> Result<(), LemmyError> {
+  let is_mod_or_admin = blocking(pool, move |conn| {
+    CommunityView::is_mod_or_admin(conn, person_id, community_id)
+  })
+  .await?;
+  if !is_mod_or_admin {
+    return Err(LemmyError::from_message("not_a_mod_or_admin"));
+  }
+  Ok(())
+}
+
+pub fn is_admin(local_user_view: &LocalUserView) -> Result<(), LemmyError> {
+  if !local_user_view.person.admin {
+    return Err(LemmyError::from_message("not_an_admin"));
+  }
+  Ok(())
+}
+
+#[tracing::instrument(skip_all)]
+pub async fn get_post(post_id: PostId, pool: &DbPool) -> Result<Post, LemmyError> {
+  blocking(pool, move |conn| Post::read(conn, post_id))
+    .await?
+    .map_err(|e| LemmyError::from_error_message(e, "couldnt_find_post"))
+}
+
+#[tracing::instrument(skip_all)]
+pub async fn mark_post_as_read(
+  person_id: PersonId,
+  post_id: PostId,
+  pool: &DbPool,
+) -> Result<PostRead, LemmyError> {
+  let post_read_form = PostReadForm { post_id, person_id };
+
+  blocking(pool, move |conn| {
+    PostRead::mark_as_read(conn, &post_read_form)
+  })
+  .await?
+  .map_err(|e| LemmyError::from_error_message(e, "couldnt_mark_post_as_read"))
+}
+
+#[tracing::instrument(skip_all)]
+pub async fn mark_post_as_unread(
+  person_id: PersonId,
+  post_id: PostId,
+  pool: &DbPool,
+) -> Result<usize, LemmyError> {
+  let post_read_form = PostReadForm { post_id, person_id };
+
+  blocking(pool, move |conn| {
+    PostRead::mark_as_unread(conn, &post_read_form)
+  })
+  .await?
+  .map_err(|e| LemmyError::from_error_message(e, "couldnt_mark_post_as_read"))
+}
+
+#[tracing::instrument(skip_all)]
+pub async fn get_local_user_view_from_jwt(
+  jwt: &str,
+  pool: &DbPool,
+  secret: &Secret,
+) -> Result<LocalUserView, LemmyError> {
+  let claims = Claims::decode(jwt, &secret.jwt_secret)
+    .map_err(|e| e.with_message("not_logged_in"))?
+    .claims;
+  let local_user_id = LocalUserId(claims.sub);
+  let local_user_view =
+    blocking(pool, move |conn| LocalUserView::read(conn, local_user_id)).await??;
+  // Check for a site ban
+  if local_user_view.person.is_banned() {
+    return Err(LemmyError::from_message("site_ban"));
+  }
+
+  // Check for user deletion
+  if local_user_view.person.deleted {
+    return Err(LemmyError::from_message("deleted"));
+  }
+
+  check_validator_time(&local_user_view.local_user.validator_time, &claims)?;
+
+  Ok(local_user_view)
+}
+
+/// Checks if user's token was issued before user's password reset.
+pub fn check_validator_time(
+  validator_time: &chrono::NaiveDateTime,
+  claims: &Claims,
+) -> Result<(), LemmyError> {
+  let user_validation_time = validator_time.timestamp();
+  if user_validation_time > claims.iat {
+    Err(LemmyError::from_message("not_logged_in"))
+  } else {
+    Ok(())
+  }
+}
+
+#[tracing::instrument(skip_all)]
+pub async fn get_local_user_view_from_jwt_opt(
+  jwt: Option<&Sensitive<String>>,
+  pool: &DbPool,
+  secret: &Secret,
+) -> Result<Option<LocalUserView>, LemmyError> {
+  match jwt {
+    Some(jwt) => Ok(Some(get_local_user_view_from_jwt(jwt, pool, secret).await?)),
+    None => Ok(None),
+  }
+}
+
+#[tracing::instrument(skip_all)]
+pub async fn get_local_user_settings_view_from_jwt(
+  jwt: &Sensitive<String>,
+  pool: &DbPool,
+  secret: &Secret,
+) -> Result<LocalUserSettingsView, LemmyError> {
+  let claims = Claims::decode(jwt.as_ref(), &secret.jwt_secret)
+    .map_err(|e| e.with_message("not_logged_in"))?
+    .claims;
+  let local_user_id = LocalUserId(claims.sub);
+  let local_user_view = blocking(pool, move |conn| {
+    LocalUserSettingsView::read(conn, local_user_id)
+  })
+  .await??;
+  // Check for a site ban
+  if local_user_view.person.is_banned() {
+    return Err(LemmyError::from_message("site_ban"));
+  }
+
+  check_validator_time(&local_user_view.local_user.validator_time, &claims)?;
+
+  Ok(local_user_view)
+}
+
+#[tracing::instrument(skip_all)]
+pub async fn get_local_user_settings_view_from_jwt_opt(
+  jwt: Option<&Sensitive<String>>,
+  pool: &DbPool,
+  secret: &Secret,
+) -> Result<Option<LocalUserSettingsView>, LemmyError> {
+  match jwt {
+    Some(jwt) => Ok(Some(
+      get_local_user_settings_view_from_jwt(jwt, pool, secret).await?,
+    )),
+    None => Ok(None),
+  }
+}
+
+#[tracing::instrument(skip_all)]
+pub async fn check_community_ban(
+  person_id: PersonId,
+  community_id: CommunityId,
+  pool: &DbPool,
+) -> Result<(), LemmyError> {
+  let is_banned =
+    move |conn: &'_ _| CommunityPersonBanView::get(conn, person_id, community_id).is_ok();
+  if blocking(pool, is_banned).await? {
+    Err(LemmyError::from_message("community_ban"))
+  } else {
+    Ok(())
+  }
+}
+
+#[tracing::instrument(skip_all)]
+pub async fn check_community_deleted_or_removed(
+  community_id: CommunityId,
+  pool: &DbPool,
+) -> Result<(), LemmyError> {
+  let community = blocking(pool, move |conn| Community::read(conn, community_id))
+    .await?
+    .map_err(|e| LemmyError::from_error_message(e, "couldnt_find_community"))?;
+  if community.deleted || community.removed {
+    Err(LemmyError::from_message("deleted"))
+  } else {
+    Ok(())
+  }
+}
+
+pub fn check_post_deleted_or_removed(post: &Post) -> Result<(), LemmyError> {
+  if post.deleted || post.removed {
+    Err(LemmyError::from_message("deleted"))
+  } else {
+    Ok(())
+  }
+}
+
+#[tracing::instrument(skip_all)]
+pub async fn check_person_block(
+  my_id: PersonId,
+  potential_blocker_id: PersonId,
+  pool: &DbPool,
+) -> Result<(), LemmyError> {
+  let is_blocked = move |conn: &'_ _| PersonBlock::read(conn, potential_blocker_id, my_id).is_ok();
+  if blocking(pool, is_blocked).await? {
+    Err(LemmyError::from_message("person_block"))
+  } else {
+    Ok(())
+  }
+}
+
+#[tracing::instrument(skip_all)]
+pub async fn check_downvotes_enabled(score: i16, pool: &DbPool) -> Result<(), LemmyError> {
+  if score == -1 {
+    let site = blocking(pool, Site::read_local_site).await??;
+    if !site.enable_downvotes {
+      return Err(LemmyError::from_message("downvotes_disabled"));
+    }
+  }
+  Ok(())
+}
+
+#[tracing::instrument(skip_all)]
+pub async fn check_private_instance(
+  local_user_view: &Option<LocalUserView>,
+  pool: &DbPool,
+) -> Result<(), LemmyError> {
+  if local_user_view.is_none() {
+    let site = blocking(pool, Site::read_local_site).await?;
+
+    // The site might not be set up yet
+    if let Ok(site) = site {
+      if site.private_instance {
+        return Err(LemmyError::from_message("instance_is_private"));
+      }
+    }
+  }
+  Ok(())
+}
+
+#[tracing::instrument(skip_all)]
+pub async fn build_federated_instances(
+  pool: &DbPool,
+  settings: &Settings,
+) -> Result<Option<FederatedInstances>, LemmyError> {
+  let federation_config = &settings.federation;
+  let hostname = &settings.hostname;
+  let federation = federation_config.to_owned();
+  if federation.enabled {
+    let distinct_communities = blocking(pool, move |conn| {
+      Community::distinct_federated_communities(conn)
+    })
+    .await??;
+
+    let allowed = federation.allowed_instances;
+    let blocked = federation.blocked_instances;
+
+    let mut linked = distinct_communities
+      .iter()
+      .map(|actor_id| Ok(actor_id.host_str().unwrap_or("").to_string()))
+      .collect::<Result<Vec<String>, LemmyError>>()?;
+
+    if let Some(allowed) = allowed.as_ref() {
+      linked.extend_from_slice(allowed);
+    }
+
+    if let Some(blocked) = blocked.as_ref() {
+      linked.retain(|a| !blocked.contains(a) && !a.eq(hostname));
+    }
+
+    // Sort and remove dupes
+    linked.sort_unstable();
+    linked.dedup();
+
+    Ok(Some(FederatedInstances {
+      linked,
+      allowed,
+      blocked,
+    }))
+  } else {
+    Ok(None)
+  }
+}
+
+/// Checks the password length
+pub fn password_length_check(pass: &str) -> Result<(), LemmyError> {
+  if !(10..=60).contains(&pass.len()) {
+    Err(LemmyError::from_message("invalid_password"))
+  } else {
+    Ok(())
+  }
+}
+
+/// Checks the site description length
+pub fn site_description_length_check(description: &str) -> Result<(), LemmyError> {
+  if description.len() > 150 {
+    Err(LemmyError::from_message("site_description_length_overflow"))
+  } else {
+    Ok(())
+  }
+}
+
+/// Checks for a honeypot. If this field is filled, fail the rest of the function
+pub fn honeypot_check(honeypot: &Option<String>) -> Result<(), LemmyError> {
+  if honeypot.is_some() {
+    Err(LemmyError::from_message("honeypot_fail"))
+  } else {
+    Ok(())
+  }
+}
+
+pub fn send_email_to_user(
+  local_user_view: &LocalUserView,
+  subject: &str,
+  body: &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 {
+    match send_email(
+      subject,
+      user_email,
+      &local_user_view.person.name,
+      body,
+      settings,
+    ) {
+      Ok(_o) => _o,
+      Err(e) => warn!("{}", e),
+    };
+  }
+}
+
+pub async fn send_password_reset_email(
+  user: &LocalUserView,
+  pool: &DbPool,
+  settings: &Settings,
+) -> Result<(), LemmyError> {
+  // Generate a random token
+  let token = generate_random_string();
+
+  // Insert the row
+  let token2 = token.clone();
+  let local_user_id = user.local_user.id;
+  blocking(pool, move |conn| {
+    PasswordResetRequest::create_token(conn, local_user_id, &token2)
+  })
+  .await??;
+
+  let email = &user.local_user.email.to_owned().expect("email");
+  let lang = get_user_lang(user);
+  let subject = &lang.password_reset_subject(&user.person.name);
+  let protocol_and_hostname = settings.get_protocol_and_hostname();
+  let reset_link = format!("{}/password_change/{}", protocol_and_hostname, &token);
+  let body = &lang.password_reset_body(&user.person.name, reset_link);
+  send_email(subject, email, &user.person.name, body, settings)
+}
+
+/// Send a verification email
+pub async fn send_verification_email(
+  user: &LocalUserView,
+  new_email: &str,
+  pool: &DbPool,
+  settings: &Settings,
+) -> Result<(), LemmyError> {
+  let form = EmailVerificationForm {
+    local_user_id: user.local_user.id,
+    email: new_email.to_string(),
+    verification_token: generate_random_string(),
+  };
+  let verify_link = format!(
+    "{}/verify_email/{}",
+    settings.get_protocol_and_hostname(),
+    &form.verification_token
+  );
+  blocking(pool, move |conn| EmailVerification::create(conn, &form)).await??;
+
+  let lang = get_user_lang(user);
+  let subject = lang.verify_email_subject(&settings.hostname);
+  let body = lang.verify_email_body(&user.person.name, &settings.hostname, verify_link);
+  send_email(&subject, new_email, &user.person.name, &body, settings)?;
+
+  Ok(())
+}
+
+pub fn send_email_verification_success(
+  user: &LocalUserView,
+  settings: &Settings,
+) -> Result<(), LemmyError> {
+  let email = &user.local_user.email.to_owned().expect("email");
+  let lang = get_user_lang(user);
+  let subject = &lang.email_verified_subject(&user.person.actor_id);
+  let body = &lang.email_verified_body();
+  send_email(subject, email, &user.person.name, body, settings)
+}
+
+pub fn get_user_lang(user: &LocalUserView) -> Lang {
+  let user_lang = LanguageId::new(user.local_user.lang.clone());
+  Lang::from_language_id(&user_lang).unwrap_or_else(|| {
+    let en = LanguageId::new("en");
+    Lang::from_language_id(&en).expect("default language")
+  })
+}
+
+pub fn send_application_approved_email(
+  user: &LocalUserView,
+  settings: &Settings,
+) -> Result<(), LemmyError> {
+  let email = &user.local_user.email.to_owned().expect("email");
+  let lang = get_user_lang(user);
+  let subject = lang.registration_approved_subject(&user.person.actor_id);
+  let body = lang.registration_approved_body(&settings.hostname);
+  send_email(&subject, email, &user.person.name, &body, settings)
+}
+
+pub async fn check_registration_application(
+  site: &Site,
+  local_user_view: &LocalUserView,
+  pool: &DbPool,
+) -> Result<(), LemmyError> {
+  if site.require_application
+    && !local_user_view.local_user.accepted_application
+    && !local_user_view.person.admin
+  {
+    // Fetch the registration, see if its denied
+    let local_user_id = local_user_view.local_user.id;
+    let registration = blocking(pool, move |conn| {
+      RegistrationApplication::find_by_local_user_id(conn, local_user_id)
+    })
+    .await??;
+    if let Some(deny_reason) = registration.deny_reason {
+      let lang = get_user_lang(local_user_view);
+      let registration_denied_message = format!("{}: {}", lang.registration_denied(), &deny_reason);
+      return Err(LemmyError::from_message(&registration_denied_message));
+    } else {
+      return Err(LemmyError::from_message("registration_application_pending"));
+    }
+  }
+  Ok(())
+}
+
+/// TODO this check should be removed after https://github.com/LemmyNet/lemmy/issues/868 is done.
+pub async fn check_private_instance_and_federation_enabled(
+  pool: &DbPool,
+  settings: &Settings,
+) -> Result<(), LemmyError> {
+  let site_opt = blocking(pool, Site::read_local_site).await?;
+
+  if let Ok(site) = site_opt {
+    if site.private_instance && settings.federation.enabled {
+      return Err(LemmyError::from_message(
+        "Cannot have both private instance and federation enabled.",
+      ));
+    }
+  }
+  Ok(())
+}
+
+pub async fn remove_user_data(banned_person_id: PersonId, pool: &DbPool) -> Result<(), LemmyError> {
+  // Posts
+  blocking(pool, move |conn: &'_ _| {
+    Post::update_removed_for_creator(conn, banned_person_id, None, true)
+  })
+  .await??;
+
+  // Communities
+  // Remove all communities where they're the top mod
+  // for now, remove the communities manually
+  let first_mod_communities = blocking(pool, move |conn: &'_ _| {
+    CommunityModeratorView::get_community_first_mods(conn)
+  })
+  .await??;
+
+  // Filter to only this banned users top communities
+  let banned_user_first_communities: Vec<CommunityModeratorView> = first_mod_communities
+    .into_iter()
+    .filter(|fmc| fmc.moderator.id == banned_person_id)
+    .collect();
+
+  for first_mod_community in banned_user_first_communities {
+    blocking(pool, move |conn: &'_ _| {
+      Community::update_removed(conn, first_mod_community.community.id, true)
+    })
+    .await??;
+  }
+
+  // Comments
+  blocking(pool, move |conn: &'_ _| {
+    Comment::update_removed_for_creator(conn, banned_person_id, true)
+  })
+  .await??;
+
+  Ok(())
+}
+
+pub async fn remove_user_data_in_community(
+  community_id: CommunityId,
+  banned_person_id: PersonId,
+  pool: &DbPool,
+) -> Result<(), LemmyError> {
+  // Posts
+  blocking(pool, move |conn| {
+    Post::update_removed_for_creator(conn, banned_person_id, Some(community_id), true)
+  })
+  .await??;
+
+  // Comments
+  // TODO Diesel doesn't allow updates with joins, so this has to be a loop
+  let comments = blocking(pool, move |conn| {
+    CommentQueryBuilder::create(conn)
+      .creator_id(banned_person_id)
+      .community_id(community_id)
+      .limit(std::i64::MAX)
+      .list()
+  })
+  .await??;
+
+  for comment_view in &comments {
+    let comment_id = comment_view.comment.id;
+    blocking(pool, move |conn| {
+      Comment::update_removed(conn, comment_id, true)
+    })
+    .await??;
+  }
+
+  Ok(())
+}
+
+pub async fn delete_user_account(person_id: PersonId, pool: &DbPool) -> Result<(), LemmyError> {
+  // Comments
+  let permadelete = move |conn: &'_ _| Comment::permadelete_for_creator(conn, person_id);
+  blocking(pool, permadelete)
+    .await?
+    .map_err(|e| LemmyError::from_error_message(e, "couldnt_update_comment"))?;
+
+  // Posts
+  let permadelete = move |conn: &'_ _| Post::permadelete_for_creator(conn, person_id);
+  blocking(pool, permadelete)
+    .await?
+    .map_err(|e| LemmyError::from_error_message(e, "couldnt_update_post"))?;
+
+  blocking(pool, move |conn| Person::delete_account(conn, person_id)).await??;
+
+  Ok(())
+}
+
+pub fn check_image_has_local_domain(url: &Option<DbUrl>) -> Result<(), LemmyError> {
+  if let Some(url) = url {
+    let settings = Settings::get();
+    let domain = url.domain().expect("url has domain");
+    if domain != settings.hostname {
+      return Err(LemmyError::from_message("image_not_local"));
+    }
+  }
+  Ok(())
+}
index 066655124b7cc79a322c6d21a005c72229fdb45c..80729fcc70d96d86c2d068ce39c1d76e554a1a17 100644 (file)
@@ -1,5 +1,5 @@
+use crate::sensitive::Sensitive;
 use lemmy_db_schema::newtypes::{CommunityId, PostId};
-use lemmy_utils::Sensitive;
 use serde::{Deserialize, Serialize};
 
 #[derive(Serialize, Deserialize, Debug)]
index 523da0ac8dfc495daa716c964ee9098175361fca..f808ea63b5753e01835de31920f86361d426a079 100644 (file)
@@ -11,10 +11,10 @@ documentation = "https://join-lemmy.org/docs/en/index.html"
 lemmy_apub = { version = "=0.16.3", path = "../apub" }
 lemmy_apub_lib = { version = "=0.16.3", path = "../apub_lib" }
 lemmy_utils = { version = "=0.16.3", path = "../utils" }
-lemmy_db_schema = { version = "=0.16.3", path = "../db_schema" }
-lemmy_db_views = { version = "=0.16.3", path = "../db_views" }
-lemmy_db_views_actor = { version = "=0.16.3", path = "../db_views_actor" }
-lemmy_api_common = { version = "=0.16.3", path = "../api_common" }
+lemmy_db_schema = { version = "=0.16.3", path = "../db_schema", features = ["full"] }
+lemmy_db_views = { version = "=0.16.3", path = "../db_views", features = ["full"] }
+lemmy_db_views_actor = { version = "=0.16.3", path = "../db_views_actor", features = ["full"] }
+lemmy_api_common = { version = "=0.16.3", path = "../api_common", features = ["full"] }
 lemmy_websocket = { version = "=0.16.3", path = "../websocket" }
 bcrypt = "0.12.1"
 serde_json = { version = "1.0.79", features = ["preserve_order"] }
index ac3744661ab993eda692eba154adc512320b5c32..12e208e8c7f97096622df40075a308cba181e745 100644 (file)
@@ -1,13 +1,15 @@
 use crate::PerformCrud;
 use actix_web::web::Data;
 use lemmy_api_common::{
-  blocking,
-  check_community_ban,
-  check_community_deleted_or_removed,
-  check_post_deleted_or_removed,
-  comment::*,
-  get_local_user_view_from_jwt,
-  get_post,
+  comment::{CommentResponse, CreateComment},
+  utils::{
+    blocking,
+    check_community_ban,
+    check_community_deleted_or_removed,
+    check_post_deleted_or_removed,
+    get_local_user_view_from_jwt,
+    get_post,
+  },
 };
 use lemmy_apub::{
   generate_local_apub_endpoint,
@@ -22,7 +24,7 @@ use lemmy_db_schema::{
   },
   traits::{Crud, Likeable},
 };
-use lemmy_db_views::comment_view::CommentView;
+use lemmy_db_views::structs::CommentView;
 use lemmy_utils::{
   utils::{remove_slurs, scrape_text_for_mentions},
   ConnectionId,
index 9ed58946d86f352e761c7fece3e07ca35902ef21..f4fb5d405aecd58f48d96f6c0934f9e9ab0f8e21 100644 (file)
@@ -1,23 +1,15 @@
 use crate::PerformCrud;
 use actix_web::web::Data;
 use lemmy_api_common::{
-  blocking,
-  check_community_ban,
-  comment::*,
-  get_local_user_view_from_jwt,
-  is_mod_or_admin,
+  comment::{CommentResponse, DeleteComment},
+  utils::{blocking, check_community_ban, get_local_user_view_from_jwt},
 };
 use lemmy_apub::activities::deletion::{send_apub_delete_in_community, DeletableObjects};
 use lemmy_db_schema::{
-  source::{
-    comment::Comment,
-    community::Community,
-    moderator::{ModRemoveComment, ModRemoveCommentForm},
-    post::Post,
-  },
+  source::{comment::Comment, community::Community, post::Post},
   traits::Crud,
 };
-use lemmy_db_views::comment_view::CommentView;
+use lemmy_db_views::structs::CommentView;
 use lemmy_utils::{ConnectionId, LemmyError};
 use lemmy_websocket::{
   send::{send_comment_ws_message, send_local_notifs},
@@ -112,101 +104,3 @@ impl PerformCrud for DeleteComment {
     Ok(res)
   }
 }
-
-#[async_trait::async_trait(?Send)]
-impl PerformCrud for RemoveComment {
-  type Response = CommentResponse;
-
-  #[tracing::instrument(skip(context, websocket_id))]
-  async fn perform(
-    &self,
-    context: &Data<LemmyContext>,
-    websocket_id: Option<ConnectionId>,
-  ) -> Result<CommentResponse, LemmyError> {
-    let data: &RemoveComment = self;
-    let local_user_view =
-      get_local_user_view_from_jwt(&data.auth, context.pool(), context.secret()).await?;
-
-    let comment_id = data.comment_id;
-    let orig_comment = blocking(context.pool(), move |conn| {
-      CommentView::read(conn, comment_id, None)
-    })
-    .await??;
-
-    check_community_ban(
-      local_user_view.person.id,
-      orig_comment.community.id,
-      context.pool(),
-    )
-    .await?;
-
-    // Verify that only a mod or admin can remove
-    is_mod_or_admin(
-      context.pool(),
-      local_user_view.person.id,
-      orig_comment.community.id,
-    )
-    .await?;
-
-    // Do the remove
-    let removed = data.removed;
-    let updated_comment = blocking(context.pool(), move |conn| {
-      Comment::update_removed(conn, comment_id, removed)
-    })
-    .await?
-    .map_err(|e| LemmyError::from_error_message(e, "couldnt_update_comment"))?;
-
-    // Mod tables
-    let form = ModRemoveCommentForm {
-      mod_person_id: local_user_view.person.id,
-      comment_id: data.comment_id,
-      removed: Some(removed),
-      reason: data.reason.to_owned(),
-    };
-    blocking(context.pool(), move |conn| {
-      ModRemoveComment::create(conn, &form)
-    })
-    .await??;
-
-    let post_id = updated_comment.post_id;
-    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,
-      false,
-      context,
-    )
-    .await?;
-
-    let res = send_comment_ws_message(
-      data.comment_id,
-      UserOperationCrud::RemoveComment,
-      websocket_id,
-      None, // TODO maybe this might clear other forms
-      Some(local_user_view.person.id),
-      recipient_ids,
-      context,
-    )
-    .await?;
-
-    // Send the apub message
-    let community = blocking(context.pool(), move |conn| {
-      Community::read(conn, orig_comment.post.community_id)
-    })
-    .await??;
-    let deletable = DeletableObjects::Comment(Box::new(updated_comment.clone().into()));
-    send_apub_delete_in_community(
-      local_user_view.person,
-      community,
-      deletable,
-      data.reason.clone().or_else(|| Some("".to_string())),
-      removed,
-      context,
-    )
-    .await?;
-
-    Ok(res)
-  }
-}
index cd91a3b0b6a289ab1fe1c6570bd8e13adaba52c7..ab9e25f1575c635130a5be1e069931da32e78467 100644 (file)
@@ -1,18 +1,14 @@
 use crate::PerformCrud;
 use actix_web::web::Data;
 use lemmy_api_common::{
-  blocking,
-  check_private_instance,
-  comment::*,
-  get_local_user_view_from_jwt_opt,
+  comment::{GetComments, GetCommentsResponse},
+  utils::{blocking, check_private_instance, get_local_user_view_from_jwt_opt},
 };
 use lemmy_apub::{fetcher::resolve_actor_identifier, objects::community::ApubCommunity};
 use lemmy_db_schema::{
-  from_opt_str_to_opt_enum,
   source::community::Community,
   traits::DeleteableOrRemoveable,
-  ListingType,
-  SortType,
+  utils::{from_opt_str_to_opt_enum, ListingType, SortType},
 };
 use lemmy_db_views::comment_view::CommentQueryBuilder;
 use lemmy_utils::{ConnectionId, LemmyError};
index 7003bdd860e421f5daa5769ae538bbc5da3e74b2..1e8328034d89d61d25e563985ddb8618a153f58b 100644 (file)
@@ -2,4 +2,5 @@ mod create;
 mod delete;
 mod list;
 mod read;
+mod remove;
 mod update;
index 5b2155da01880c84b6ea90a793ef9407efe9718f..fd248cafe6ffe8800063a6a157be9f96f2de5112 100644 (file)
@@ -1,12 +1,10 @@
 use crate::PerformCrud;
 use actix_web::web::Data;
 use lemmy_api_common::{
-  blocking,
-  check_private_instance,
-  comment::*,
-  get_local_user_view_from_jwt_opt,
+  comment::{CommentResponse, GetComment},
+  utils::{blocking, check_private_instance, get_local_user_view_from_jwt_opt},
 };
-use lemmy_db_views::comment_view::CommentView;
+use lemmy_db_views::structs::CommentView;
 use lemmy_utils::{ConnectionId, LemmyError};
 use lemmy_websocket::LemmyContext;
 
diff --git a/crates/api_crud/src/comment/remove.rs b/crates/api_crud/src/comment/remove.rs
new file mode 100644 (file)
index 0000000..837407c
--- /dev/null
@@ -0,0 +1,121 @@
+use crate::PerformCrud;
+use actix_web::web::Data;
+use lemmy_api_common::{
+  comment::{CommentResponse, RemoveComment},
+  utils::{blocking, check_community_ban, get_local_user_view_from_jwt, is_mod_or_admin},
+};
+use lemmy_apub::activities::deletion::{send_apub_delete_in_community, DeletableObjects};
+use lemmy_db_schema::{
+  source::{
+    comment::Comment,
+    community::Community,
+    moderator::{ModRemoveComment, ModRemoveCommentForm},
+    post::Post,
+  },
+  traits::Crud,
+};
+use lemmy_db_views::structs::CommentView;
+use lemmy_utils::{ConnectionId, LemmyError};
+use lemmy_websocket::{
+  send::{send_comment_ws_message, send_local_notifs},
+  LemmyContext,
+  UserOperationCrud,
+};
+
+#[async_trait::async_trait(?Send)]
+impl PerformCrud for RemoveComment {
+  type Response = CommentResponse;
+
+  #[tracing::instrument(skip(context, websocket_id))]
+  async fn perform(
+    &self,
+    context: &Data<LemmyContext>,
+    websocket_id: Option<ConnectionId>,
+  ) -> Result<CommentResponse, LemmyError> {
+    let data: &RemoveComment = self;
+    let local_user_view =
+      get_local_user_view_from_jwt(&data.auth, context.pool(), context.secret()).await?;
+
+    let comment_id = data.comment_id;
+    let orig_comment = blocking(context.pool(), move |conn| {
+      CommentView::read(conn, comment_id, None)
+    })
+    .await??;
+
+    check_community_ban(
+      local_user_view.person.id,
+      orig_comment.community.id,
+      context.pool(),
+    )
+    .await?;
+
+    // Verify that only a mod or admin can remove
+    is_mod_or_admin(
+      context.pool(),
+      local_user_view.person.id,
+      orig_comment.community.id,
+    )
+    .await?;
+
+    // Do the remove
+    let removed = data.removed;
+    let updated_comment = blocking(context.pool(), move |conn| {
+      Comment::update_removed(conn, comment_id, removed)
+    })
+    .await?
+    .map_err(|e| LemmyError::from_error_message(e, "couldnt_update_comment"))?;
+
+    // Mod tables
+    let form = ModRemoveCommentForm {
+      mod_person_id: local_user_view.person.id,
+      comment_id: data.comment_id,
+      removed: Some(removed),
+      reason: data.reason.to_owned(),
+    };
+    blocking(context.pool(), move |conn| {
+      ModRemoveComment::create(conn, &form)
+    })
+    .await??;
+
+    let post_id = updated_comment.post_id;
+    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,
+      false,
+      context,
+    )
+    .await?;
+
+    let res = send_comment_ws_message(
+      data.comment_id,
+      UserOperationCrud::RemoveComment,
+      websocket_id,
+      None, // TODO maybe this might clear other forms
+      Some(local_user_view.person.id),
+      recipient_ids,
+      context,
+    )
+    .await?;
+
+    // Send the apub message
+    let community = blocking(context.pool(), move |conn| {
+      Community::read(conn, orig_comment.post.community_id)
+    })
+    .await??;
+    let deletable = DeletableObjects::Comment(Box::new(updated_comment.clone().into()));
+    send_apub_delete_in_community(
+      local_user_view.person,
+      community,
+      deletable,
+      data.reason.clone().or_else(|| Some("".to_string())),
+      removed,
+      context,
+    )
+    .await?;
+
+    Ok(res)
+  }
+}
index 4fede14548e5f21a249c7e3c15e8e07e81c37436..06065c89ad521f77b2b9cacb2a0532600f702cf8 100644 (file)
@@ -1,19 +1,20 @@
 use actix_web::web::Data;
-
 use lemmy_api_common::{
-  blocking,
-  check_community_ban,
-  check_community_deleted_or_removed,
-  check_post_deleted_or_removed,
-  comment::*,
-  get_local_user_view_from_jwt,
+  comment::{CommentResponse, EditComment},
+  utils::{
+    blocking,
+    check_community_ban,
+    check_community_deleted_or_removed,
+    check_post_deleted_or_removed,
+    get_local_user_view_from_jwt,
+  },
 };
 use lemmy_apub::protocol::activities::{
   create_or_update::comment::CreateOrUpdateComment,
   CreateOrUpdateType,
 };
 use lemmy_db_schema::source::comment::Comment;
-use lemmy_db_views::comment_view::CommentView;
+use lemmy_db_views::structs::CommentView;
 use lemmy_utils::{
   utils::{remove_slurs, scrape_text_for_mentions},
   ConnectionId,
index 8d68d554d712daa8f61c9355cd3ae621eb7fb5a3..6838216ffab8af2c1114290f9d6542f0f97ab72d 100644 (file)
@@ -1,11 +1,8 @@
 use crate::PerformCrud;
 use actix_web::web::Data;
 use lemmy_api_common::{
-  blocking,
-  check_image_has_local_domain,
   community::{CommunityResponse, CreateCommunity},
-  get_local_user_view_from_jwt,
-  is_admin,
+  utils::{blocking, check_image_has_local_domain, get_local_user_view_from_jwt, is_admin},
 };
 use lemmy_apub::{
   generate_followers_url,
@@ -17,7 +14,6 @@ use lemmy_apub::{
 };
 use lemmy_apub_lib::object_id::ObjectId;
 use lemmy_db_schema::{
-  diesel_option_overwrite_to_url,
   source::{
     community::{
       Community,
@@ -30,8 +26,9 @@ use lemmy_db_schema::{
     site::Site,
   },
   traits::{Crud, Followable, Joinable},
+  utils::diesel_option_overwrite_to_url,
 };
-use lemmy_db_views_actor::community_view::CommunityView;
+use lemmy_db_views_actor::structs::CommunityView;
 use lemmy_utils::{
   apub::generate_actor_keypair,
   utils::{check_slurs, check_slurs_opt, is_valid_actor_name},
index b8a2f2309ecc268002ab29bcef74637f385dd338..f42e9b01da83c8b2f732d7c8399f06960592249b 100644 (file)
@@ -1,16 +1,13 @@
 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_in_community, DeletableObjects};
-use lemmy_db_schema::{
-  source::{
-    community::Community,
-    moderator::{ModRemoveCommunity, ModRemoveCommunityForm},
-  },
-  traits::Crud,
+use lemmy_api_common::{
+  community::{CommunityResponse, DeleteCommunity},
+  utils::{blocking, get_local_user_view_from_jwt},
 };
-use lemmy_db_views_actor::community_moderator_view::CommunityModeratorView;
-use lemmy_utils::{utils::naive_from_unix, ConnectionId, LemmyError};
+use lemmy_apub::activities::deletion::{send_apub_delete_in_community, DeletableObjects};
+use lemmy_db_schema::source::community::Community;
+use lemmy_db_views_actor::structs::CommunityModeratorView;
+use lemmy_utils::{ConnectionId, LemmyError};
 use lemmy_websocket::{send::send_community_ws_message, LemmyContext, UserOperationCrud};
 
 #[async_trait::async_trait(?Send)]
@@ -72,67 +69,3 @@ impl PerformCrud for DeleteCommunity {
     Ok(res)
   }
 }
-
-#[async_trait::async_trait(?Send)]
-impl PerformCrud for RemoveCommunity {
-  type Response = CommunityResponse;
-
-  #[tracing::instrument(skip(context, websocket_id))]
-  async fn perform(
-    &self,
-    context: &Data<LemmyContext>,
-    websocket_id: Option<ConnectionId>,
-  ) -> Result<CommunityResponse, LemmyError> {
-    let data: &RemoveCommunity = self;
-    let local_user_view =
-      get_local_user_view_from_jwt(&data.auth, context.pool(), context.secret()).await?;
-
-    // Verify its an admin (only an admin can remove a community)
-    is_admin(&local_user_view)?;
-
-    // Do the remove
-    let community_id = data.community_id;
-    let removed = data.removed;
-    let updated_community = blocking(context.pool(), move |conn| {
-      Community::update_removed(conn, community_id, removed)
-    })
-    .await?
-    .map_err(|e| LemmyError::from_error_message(e, "couldnt_update_community"))?;
-
-    // Mod tables
-    let expires = data.expires.map(naive_from_unix);
-    let form = ModRemoveCommunityForm {
-      mod_person_id: local_user_view.person.id,
-      community_id: data.community_id,
-      removed: Some(removed),
-      reason: data.reason.to_owned(),
-      expires,
-    };
-    blocking(context.pool(), move |conn| {
-      ModRemoveCommunity::create(conn, &form)
-    })
-    .await??;
-
-    let res = send_community_ws_message(
-      data.community_id,
-      UserOperationCrud::RemoveCommunity,
-      websocket_id,
-      Some(local_user_view.person.id),
-      context,
-    )
-    .await?;
-
-    // Apub messages
-    let deletable = DeletableObjects::Community(Box::new(updated_community.clone().into()));
-    send_apub_delete_in_community(
-      local_user_view.person,
-      updated_community,
-      deletable,
-      data.reason.clone().or_else(|| Some("".to_string())),
-      removed,
-      context,
-    )
-    .await?;
-    Ok(res)
-  }
-}
index 24c154ad2a2ffbcb58bcdc313ae6714a2daa2471..fac41c66fa774b1a9222c59db67ded470954dd85 100644 (file)
@@ -1,16 +1,12 @@
 use crate::PerformCrud;
 use actix_web::web::Data;
 use lemmy_api_common::{
-  blocking,
-  check_private_instance,
-  community::*,
-  get_local_user_view_from_jwt_opt,
+  community::{ListCommunities, ListCommunitiesResponse},
+  utils::{blocking, check_private_instance, get_local_user_view_from_jwt_opt},
 };
 use lemmy_db_schema::{
-  from_opt_str_to_opt_enum,
   traits::DeleteableOrRemoveable,
-  ListingType,
-  SortType,
+  utils::{from_opt_str_to_opt_enum, ListingType, SortType},
 };
 use lemmy_db_views_actor::community_view::CommunityQueryBuilder;
 use lemmy_utils::{ConnectionId, LemmyError};
index 7003bdd860e421f5daa5769ae538bbc5da3e74b2..1e8328034d89d61d25e563985ddb8618a153f58b 100644 (file)
@@ -2,4 +2,5 @@ mod create;
 mod delete;
 mod list;
 mod read;
+mod remove;
 mod update;
index 9c4ba333cce55439e59d43c1eadd0b9234925d42..16eee46920f653d4f483441808230f3e916d20d5 100644 (file)
@@ -1,10 +1,8 @@
 use crate::PerformCrud;
 use actix_web::web::Data;
 use lemmy_api_common::{
-  blocking,
-  check_private_instance,
-  community::*,
-  get_local_user_view_from_jwt_opt,
+  community::{GetCommunity, GetCommunityResponse},
+  utils::{blocking, check_private_instance, get_local_user_view_from_jwt_opt},
 };
 use lemmy_apub::{
   fetcher::resolve_actor_identifier,
@@ -14,10 +12,7 @@ use lemmy_db_schema::{
   source::{community::Community, site::Site},
   traits::DeleteableOrRemoveable,
 };
-use lemmy_db_views_actor::{
-  community_moderator_view::CommunityModeratorView,
-  community_view::CommunityView,
-};
+use lemmy_db_views_actor::structs::{CommunityModeratorView, CommunityView};
 use lemmy_utils::{ConnectionId, LemmyError};
 use lemmy_websocket::{messages::GetCommunityUsersOnline, LemmyContext};
 
diff --git a/crates/api_crud/src/community/remove.rs b/crates/api_crud/src/community/remove.rs
new file mode 100644 (file)
index 0000000..7ca9b73
--- /dev/null
@@ -0,0 +1,80 @@
+use crate::PerformCrud;
+use actix_web::web::Data;
+use lemmy_api_common::{
+  community::{CommunityResponse, RemoveCommunity},
+  utils::{blocking, get_local_user_view_from_jwt, is_admin},
+};
+use lemmy_apub::activities::deletion::{send_apub_delete_in_community, DeletableObjects};
+use lemmy_db_schema::{
+  source::{
+    community::Community,
+    moderator::{ModRemoveCommunity, ModRemoveCommunityForm},
+  },
+  traits::Crud,
+};
+use lemmy_utils::{utils::naive_from_unix, ConnectionId, LemmyError};
+use lemmy_websocket::{send::send_community_ws_message, LemmyContext, UserOperationCrud};
+
+#[async_trait::async_trait(?Send)]
+impl PerformCrud for RemoveCommunity {
+  type Response = CommunityResponse;
+
+  #[tracing::instrument(skip(context, websocket_id))]
+  async fn perform(
+    &self,
+    context: &Data<LemmyContext>,
+    websocket_id: Option<ConnectionId>,
+  ) -> Result<CommunityResponse, LemmyError> {
+    let data: &RemoveCommunity = self;
+    let local_user_view =
+      get_local_user_view_from_jwt(&data.auth, context.pool(), context.secret()).await?;
+
+    // Verify its an admin (only an admin can remove a community)
+    is_admin(&local_user_view)?;
+
+    // Do the remove
+    let community_id = data.community_id;
+    let removed = data.removed;
+    let updated_community = blocking(context.pool(), move |conn| {
+      Community::update_removed(conn, community_id, removed)
+    })
+    .await?
+    .map_err(|e| LemmyError::from_error_message(e, "couldnt_update_community"))?;
+
+    // Mod tables
+    let expires = data.expires.map(naive_from_unix);
+    let form = ModRemoveCommunityForm {
+      mod_person_id: local_user_view.person.id,
+      community_id: data.community_id,
+      removed: Some(removed),
+      reason: data.reason.to_owned(),
+      expires,
+    };
+    blocking(context.pool(), move |conn| {
+      ModRemoveCommunity::create(conn, &form)
+    })
+    .await??;
+
+    let res = send_community_ws_message(
+      data.community_id,
+      UserOperationCrud::RemoveCommunity,
+      websocket_id,
+      Some(local_user_view.person.id),
+      context,
+    )
+    .await?;
+
+    // Apub messages
+    let deletable = DeletableObjects::Community(Box::new(updated_community.clone().into()));
+    send_apub_delete_in_community(
+      local_user_view.person,
+      updated_community,
+      deletable,
+      data.reason.clone().or_else(|| Some("".to_string())),
+      removed,
+      context,
+    )
+    .await?;
+    Ok(res)
+  }
+}
index 4df708fcc8e803e1496fc77790e43d265a439eca..4c7fa8ce608618c84f755a429cfbc575acf8358f 100644 (file)
@@ -1,20 +1,17 @@
 use crate::PerformCrud;
 use actix_web::web::Data;
 use lemmy_api_common::{
-  blocking,
-  check_image_has_local_domain,
   community::{CommunityResponse, EditCommunity},
-  get_local_user_view_from_jwt,
+  utils::{blocking, check_image_has_local_domain, get_local_user_view_from_jwt},
 };
 use lemmy_apub::protocol::activities::community::update::UpdateCommunity;
 use lemmy_db_schema::{
-  diesel_option_overwrite_to_url,
-  naive_now,
   newtypes::PersonId,
   source::community::{Community, CommunityForm},
   traits::Crud,
+  utils::{diesel_option_overwrite_to_url, naive_now},
 };
-use lemmy_db_views_actor::community_moderator_view::CommunityModeratorView;
+use lemmy_db_views_actor::structs::CommunityModeratorView;
 use lemmy_utils::{utils::check_slurs_opt, ConnectionId, LemmyError};
 use lemmy_websocket::{send::send_community_ws_message, LemmyContext, UserOperationCrud};
 
index eb162e01310c9a049bb39c0c52649036c4c65a78..353e186add69ea4919462815b80e66a567cdd5ed 100644 (file)
@@ -1,13 +1,16 @@
 use crate::PerformCrud;
 use actix_web::web::Data;
 use lemmy_api_common::{
-  blocking,
-  check_community_ban,
-  check_community_deleted_or_removed,
-  get_local_user_view_from_jwt,
-  honeypot_check,
-  mark_post_as_read,
-  post::*,
+  post::{CreatePost, PostResponse},
+  request::fetch_site_data,
+  utils::{
+    blocking,
+    check_community_ban,
+    check_community_deleted_or_removed,
+    get_local_user_view_from_jwt,
+    honeypot_check,
+    mark_post_as_read,
+  },
 };
 use lemmy_apub::{
   generate_local_apub_endpoint,
@@ -22,9 +25,8 @@ use lemmy_db_schema::{
   },
   traits::{Crud, Likeable},
 };
-use lemmy_db_views_actor::community_view::CommunityView;
+use lemmy_db_views_actor::structs::CommunityView;
 use lemmy_utils::{
-  request::fetch_site_data,
   utils::{
     check_slurs,
     check_slurs_opt,
index 05c395b5b3dcf5cdc6be9bc77363ee8ccf0b2fb0..f880b4b5d22c228eb7e542ad775898716445dd07 100644 (file)
@@ -1,20 +1,17 @@
 use crate::PerformCrud;
 use actix_web::web::Data;
 use lemmy_api_common::{
-  blocking,
-  check_community_ban,
-  check_community_deleted_or_removed,
-  get_local_user_view_from_jwt,
-  is_mod_or_admin,
-  post::*,
+  post::{DeletePost, PostResponse},
+  utils::{
+    blocking,
+    check_community_ban,
+    check_community_deleted_or_removed,
+    get_local_user_view_from_jwt,
+  },
 };
 use lemmy_apub::activities::deletion::{send_apub_delete_in_community, DeletableObjects};
 use lemmy_db_schema::{
-  source::{
-    community::Community,
-    moderator::{ModRemovePost, ModRemovePostForm},
-    post::Post,
-  },
+  source::{community::Community, post::Post},
   traits::Crud,
 };
 use lemmy_utils::{ConnectionId, LemmyError};
@@ -90,83 +87,3 @@ impl PerformCrud for DeletePost {
     Ok(res)
   }
 }
-
-#[async_trait::async_trait(?Send)]
-impl PerformCrud for RemovePost {
-  type Response = PostResponse;
-
-  #[tracing::instrument(skip(context, websocket_id))]
-  async fn perform(
-    &self,
-    context: &Data<LemmyContext>,
-    websocket_id: Option<ConnectionId>,
-  ) -> Result<PostResponse, LemmyError> {
-    let data: &RemovePost = self;
-    let local_user_view =
-      get_local_user_view_from_jwt(&data.auth, context.pool(), context.secret()).await?;
-
-    let post_id = data.post_id;
-    let orig_post = blocking(context.pool(), move |conn| Post::read(conn, post_id)).await??;
-
-    check_community_ban(
-      local_user_view.person.id,
-      orig_post.community_id,
-      context.pool(),
-    )
-    .await?;
-
-    // Verify that only the mods can remove
-    is_mod_or_admin(
-      context.pool(),
-      local_user_view.person.id,
-      orig_post.community_id,
-    )
-    .await?;
-
-    // Update the post
-    let post_id = data.post_id;
-    let removed = data.removed;
-    let updated_post = blocking(context.pool(), move |conn| {
-      Post::update_removed(conn, post_id, removed)
-    })
-    .await??;
-
-    // Mod tables
-    let form = ModRemovePostForm {
-      mod_person_id: local_user_view.person.id,
-      post_id: data.post_id,
-      removed: Some(removed),
-      reason: data.reason.to_owned(),
-    };
-    blocking(context.pool(), move |conn| {
-      ModRemovePost::create(conn, &form)
-    })
-    .await??;
-
-    let res = send_post_ws_message(
-      data.post_id,
-      UserOperationCrud::RemovePost,
-      websocket_id,
-      Some(local_user_view.person.id),
-      context,
-    )
-    .await?;
-
-    // apub updates
-    let community = blocking(context.pool(), move |conn| {
-      Community::read(conn, orig_post.community_id)
-    })
-    .await??;
-    let deletable = DeletableObjects::Post(Box::new(updated_post.into()));
-    send_apub_delete_in_community(
-      local_user_view.person,
-      community,
-      deletable,
-      data.reason.clone().or_else(|| Some("".to_string())),
-      removed,
-      context,
-    )
-    .await?;
-    Ok(res)
-  }
-}
index 154faaaafedf9dcc6ea0c8b5f709655516ccf5ed..4b871e54f86490e1c85bc08fca3d7d4f14467359 100644 (file)
@@ -1,18 +1,14 @@
 use crate::PerformCrud;
 use actix_web::web::Data;
 use lemmy_api_common::{
-  blocking,
-  check_private_instance,
-  get_local_user_view_from_jwt_opt,
   post::{GetPosts, GetPostsResponse},
+  utils::{blocking, check_private_instance, get_local_user_view_from_jwt_opt},
 };
 use lemmy_apub::{fetcher::resolve_actor_identifier, objects::community::ApubCommunity};
 use lemmy_db_schema::{
-  from_opt_str_to_opt_enum,
   source::{community::Community, site::Site},
   traits::DeleteableOrRemoveable,
-  ListingType,
-  SortType,
+  utils::{from_opt_str_to_opt_enum, ListingType, SortType},
 };
 use lemmy_db_views::post_view::PostQueryBuilder;
 use lemmy_utils::{ConnectionId, LemmyError};
index 7003bdd860e421f5daa5769ae538bbc5da3e74b2..1e8328034d89d61d25e563985ddb8618a153f58b 100644 (file)
@@ -2,4 +2,5 @@ mod create;
 mod delete;
 mod list;
 mod read;
+mod remove;
 mod update;
index 03507ba4db8cb4677ef06a48de6c1368743c7e88..a5ca262fa9eb0860d17fc47ef8199618dd439844 100644 (file)
@@ -1,18 +1,12 @@
 use crate::PerformCrud;
 use actix_web::web::Data;
 use lemmy_api_common::{
-  blocking,
-  check_private_instance,
-  get_local_user_view_from_jwt_opt,
-  mark_post_as_read,
   post::{GetPost, GetPostResponse},
+  utils::{blocking, check_private_instance, get_local_user_view_from_jwt_opt, mark_post_as_read},
 };
 use lemmy_db_schema::traits::DeleteableOrRemoveable;
-use lemmy_db_views::{comment_view::CommentQueryBuilder, post_view::PostView};
-use lemmy_db_views_actor::{
-  community_moderator_view::CommunityModeratorView,
-  community_view::CommunityView,
-};
+use lemmy_db_views::{comment_view::CommentQueryBuilder, structs::PostView};
+use lemmy_db_views_actor::structs::{CommunityModeratorView, CommunityView};
 use lemmy_utils::{ConnectionId, LemmyError};
 use lemmy_websocket::{messages::GetPostUsersOnline, LemmyContext};
 
diff --git a/crates/api_crud/src/post/remove.rs b/crates/api_crud/src/post/remove.rs
new file mode 100644 (file)
index 0000000..7e50159
--- /dev/null
@@ -0,0 +1,97 @@
+use crate::PerformCrud;
+use actix_web::web::Data;
+use lemmy_api_common::{
+  post::{PostResponse, RemovePost},
+  utils::{blocking, check_community_ban, get_local_user_view_from_jwt, is_mod_or_admin},
+};
+use lemmy_apub::activities::deletion::{send_apub_delete_in_community, DeletableObjects};
+use lemmy_db_schema::{
+  source::{
+    community::Community,
+    moderator::{ModRemovePost, ModRemovePostForm},
+    post::Post,
+  },
+  traits::Crud,
+};
+use lemmy_utils::{ConnectionId, LemmyError};
+use lemmy_websocket::{send::send_post_ws_message, LemmyContext, UserOperationCrud};
+
+#[async_trait::async_trait(?Send)]
+impl PerformCrud for RemovePost {
+  type Response = PostResponse;
+
+  #[tracing::instrument(skip(context, websocket_id))]
+  async fn perform(
+    &self,
+    context: &Data<LemmyContext>,
+    websocket_id: Option<ConnectionId>,
+  ) -> Result<PostResponse, LemmyError> {
+    let data: &RemovePost = self;
+    let local_user_view =
+      get_local_user_view_from_jwt(&data.auth, context.pool(), context.secret()).await?;
+
+    let post_id = data.post_id;
+    let orig_post = blocking(context.pool(), move |conn| Post::read(conn, post_id)).await??;
+
+    check_community_ban(
+      local_user_view.person.id,
+      orig_post.community_id,
+      context.pool(),
+    )
+    .await?;
+
+    // Verify that only the mods can remove
+    is_mod_or_admin(
+      context.pool(),
+      local_user_view.person.id,
+      orig_post.community_id,
+    )
+    .await?;
+
+    // Update the post
+    let post_id = data.post_id;
+    let removed = data.removed;
+    let updated_post = blocking(context.pool(), move |conn| {
+      Post::update_removed(conn, post_id, removed)
+    })
+    .await??;
+
+    // Mod tables
+    let form = ModRemovePostForm {
+      mod_person_id: local_user_view.person.id,
+      post_id: data.post_id,
+      removed: Some(removed),
+      reason: data.reason.to_owned(),
+    };
+    blocking(context.pool(), move |conn| {
+      ModRemovePost::create(conn, &form)
+    })
+    .await??;
+
+    let res = send_post_ws_message(
+      data.post_id,
+      UserOperationCrud::RemovePost,
+      websocket_id,
+      Some(local_user_view.person.id),
+      context,
+    )
+    .await?;
+
+    // apub updates
+    let community = blocking(context.pool(), move |conn| {
+      Community::read(conn, orig_post.community_id)
+    })
+    .await??;
+    let deletable = DeletableObjects::Post(Box::new(updated_post.into()));
+    send_apub_delete_in_community(
+      local_user_view.person,
+      community,
+      deletable,
+      data.reason.clone().or_else(|| Some("".to_string())),
+      removed,
+      context,
+    )
+    .await?;
+    Ok(res)
+  }
+}
index fa19c2c9bddd396b176872ff58691e3c8469716d..16f2fea40dd8cda9f7667785ce8da0cc4e17c526 100644 (file)
@@ -1,23 +1,24 @@
 use actix_web::web::Data;
-
 use lemmy_api_common::{
-  blocking,
-  check_community_ban,
-  check_community_deleted_or_removed,
-  get_local_user_view_from_jwt,
-  post::*,
+  post::{EditPost, PostResponse},
+  request::fetch_site_data,
+  utils::{
+    blocking,
+    check_community_ban,
+    check_community_deleted_or_removed,
+    get_local_user_view_from_jwt,
+  },
 };
 use lemmy_apub::protocol::activities::{
   create_or_update::post::CreateOrUpdatePost,
   CreateOrUpdateType,
 };
 use lemmy_db_schema::{
-  naive_now,
   source::post::{Post, PostForm},
   traits::Crud,
+  utils::naive_now,
 };
 use lemmy_utils::{
-  request::fetch_site_data,
   utils::{check_slurs_opt, clean_optional_text, clean_url_params, is_valid_post_title},
   ConnectionId,
   LemmyError,
index 44999cf0058d40db934ed72543a9414452c0e951..de711128d4124fb956f497a7fb1bf96bb03ed9e8 100644 (file)
@@ -1,12 +1,14 @@
 use crate::PerformCrud;
 use actix_web::web::Data;
 use lemmy_api_common::{
-  blocking,
-  check_person_block,
-  get_local_user_view_from_jwt,
-  get_user_lang,
   person::{CreatePrivateMessage, PrivateMessageResponse},
-  send_email_to_user,
+  utils::{
+    blocking,
+    check_person_block,
+    get_local_user_view_from_jwt,
+    get_user_lang,
+    send_email_to_user,
+  },
 };
 use lemmy_apub::{
   generate_local_apub_endpoint,
@@ -20,7 +22,7 @@ use lemmy_db_schema::{
   source::private_message::{PrivateMessage, PrivateMessageForm},
   traits::Crud,
 };
-use lemmy_db_views::local_user_view::LocalUserView;
+use lemmy_db_views::structs::LocalUserView;
 use lemmy_utils::{utils::remove_slurs, ConnectionId, LemmyError};
 use lemmy_websocket::{send::send_pm_ws_message, LemmyContext, UserOperationCrud};
 
index 00b3ff50e681e5e77991f63322e76ad4c06ccf93..af06094eb59a2ac5ed92d91e2cfd4cf172a6c7cc 100644 (file)
@@ -1,9 +1,8 @@
 use crate::PerformCrud;
 use actix_web::web::Data;
 use lemmy_api_common::{
-  blocking,
-  get_local_user_view_from_jwt,
   person::{DeletePrivateMessage, PrivateMessageResponse},
+  utils::{blocking, get_local_user_view_from_jwt},
 };
 use lemmy_apub::activities::deletion::send_apub_delete_private_message;
 use lemmy_db_schema::{source::private_message::PrivateMessage, traits::Crud};
index 48ff239c7f2647704c2118009e52792486437366..ce03200c6e817f348e6fa2f5355e73afbde8fb1f 100644 (file)
@@ -1,9 +1,8 @@
 use crate::PerformCrud;
 use actix_web::web::Data;
 use lemmy_api_common::{
-  blocking,
-  get_local_user_view_from_jwt,
   person::{GetPrivateMessages, PrivateMessagesResponse},
+  utils::{blocking, get_local_user_view_from_jwt},
 };
 use lemmy_db_schema::traits::DeleteableOrRemoveable;
 use lemmy_db_views::private_message_view::PrivateMessageQueryBuilder;
index 5f23f1bcd4da3fc5879444e2be01a3dcae7fab2d..aebd5b8be13a8baf489db4393790903eaf6edf59 100644 (file)
@@ -1,9 +1,8 @@
 use crate::PerformCrud;
 use actix_web::web::Data;
 use lemmy_api_common::{
-  blocking,
-  get_local_user_view_from_jwt,
   person::{EditPrivateMessage, PrivateMessageResponse},
+  utils::{blocking, get_local_user_view_from_jwt},
 };
 use lemmy_apub::protocol::activities::{
   create_or_update::private_message::CreateOrUpdatePrivateMessage,
index 7ec772b91d61874fe09fe7f2dc008cce087b5cc8..b9b3b601378ff2014afe9ca328abfbb6ddb755be 100644 (file)
@@ -1,23 +1,23 @@
 use crate::PerformCrud;
 use actix_web::web::Data;
 use lemmy_api_common::{
-  blocking,
-  check_image_has_local_domain,
-  get_local_user_view_from_jwt,
-  is_admin,
-  site::*,
-  site_description_length_check,
+  site::{CreateSite, SiteResponse},
+  utils::{
+    blocking,
+    check_image_has_local_domain,
+    get_local_user_view_from_jwt,
+    is_admin,
+    site_description_length_check,
+  },
 };
 use lemmy_apub::generate_site_inbox_url;
 use lemmy_db_schema::{
-  diesel_option_overwrite,
-  diesel_option_overwrite_to_url,
-  naive_now,
   newtypes::DbUrl,
   source::site::{Site, SiteForm},
   traits::Crud,
+  utils::{diesel_option_overwrite, diesel_option_overwrite_to_url, naive_now},
 };
-use lemmy_db_views::site_view::SiteView;
+use lemmy_db_views::structs::SiteView;
 use lemmy_utils::{
   apub::generate_actor_keypair,
   settings::structs::Settings,
index 17c838964d3d6d14178875dc20a891f30ffef50b..f9fe75c73b1237bbbf246b3f985fbe86d62b44d9 100644 (file)
@@ -1,19 +1,17 @@
 use crate::PerformCrud;
 use actix_web::web::Data;
 use lemmy_api_common::{
-  blocking,
-  build_federated_instances,
-  get_local_user_settings_view_from_jwt_opt,
   person::Register,
-  site::*,
+  site::{CreateSite, GetSite, GetSiteResponse, MyUserInfo},
+  utils::{blocking, build_federated_instances, get_local_user_settings_view_from_jwt_opt},
 };
-use lemmy_db_views::site_view::SiteView;
-use lemmy_db_views_actor::{
-  community_block_view::CommunityBlockView,
-  community_follower_view::CommunityFollowerView,
-  community_moderator_view::CommunityModeratorView,
-  person_block_view::PersonBlockView,
-  person_view::PersonViewSafe,
+use lemmy_db_views::structs::SiteView;
+use lemmy_db_views_actor::structs::{
+  CommunityBlockView,
+  CommunityFollowerView,
+  CommunityModeratorView,
+  PersonBlockView,
+  PersonViewSafe,
 };
 use lemmy_utils::{version, ConnectionId, LemmyError};
 use lemmy_websocket::{messages::GetUsersOnline, LemmyContext};
index a6890d266a78da67797060268c18e6c0246ab816..ace19fd728e544b969ccf9e4e604142d137a86bb 100644 (file)
@@ -1,25 +1,24 @@
 use crate::PerformCrud;
 use actix_web::web::Data;
 use lemmy_api_common::{
-  blocking,
-  check_image_has_local_domain,
-  get_local_user_view_from_jwt,
-  is_admin,
   site::{EditSite, SiteResponse},
-  site_description_length_check,
+  utils::{
+    blocking,
+    check_image_has_local_domain,
+    get_local_user_view_from_jwt,
+    is_admin,
+    site_description_length_check,
+  },
 };
 use lemmy_db_schema::{
-  diesel_option_overwrite,
-  diesel_option_overwrite_to_url,
-  naive_now,
   source::{
     local_user::LocalUser,
     site::{Site, SiteForm},
   },
   traits::Crud,
-  ListingType,
+  utils::{diesel_option_overwrite, diesel_option_overwrite_to_url, naive_now, ListingType},
 };
-use lemmy_db_views::site_view::SiteView;
+use lemmy_db_views::structs::SiteView;
 use lemmy_utils::{utils::check_slurs_opt, ConnectionId, LemmyError};
 use lemmy_websocket::{messages::SendAllMessage, LemmyContext, UserOperationCrud};
 use std::{default::Default, str::FromStr};
index 00ef7db64fe12431beac3006285f119f228e0712..456617043d7675bb7ae67723d3a008302f575258 100644 (file)
@@ -1,11 +1,8 @@
 use crate::PerformCrud;
 use actix_web::web::Data;
 use lemmy_api_common::{
-  blocking,
-  honeypot_check,
-  password_length_check,
-  person::*,
-  send_verification_email,
+  person::{LoginResponse, Register},
+  utils::{blocking, honeypot_check, password_length_check, send_verification_email},
 };
 use lemmy_apub::{
   generate_followers_url,
@@ -15,7 +12,7 @@ use lemmy_apub::{
   EndpointType,
 };
 use lemmy_db_schema::{
-  aggregates::person_aggregates::PersonAggregates,
+  aggregates::structs::PersonAggregates,
   newtypes::CommunityId,
   source::{
     community::{
@@ -33,8 +30,8 @@ use lemmy_db_schema::{
   },
   traits::{Crud, Followable, Joinable},
 };
-use lemmy_db_views::local_user_view::LocalUserView;
-use lemmy_db_views_actor::person_view::PersonViewSafe;
+use lemmy_db_views::structs::LocalUserView;
+use lemmy_db_views_actor::structs::PersonViewSafe;
 use lemmy_utils::{
   apub::generate_actor_keypair,
   claims::Claims,
index ea1cbcff5fca744b6e1b208ed47764348c976798..c5e0e2197eeb25577beee8458b07bba3b023246b 100644 (file)
@@ -1,7 +1,10 @@
 use crate::PerformCrud;
 use actix_web::web::Data;
 use bcrypt::verify;
-use lemmy_api_common::{delete_user_account, get_local_user_view_from_jwt, person::*};
+use lemmy_api_common::{
+  person::{DeleteAccount, DeleteAccountResponse},
+  utils::{delete_user_account, get_local_user_view_from_jwt},
+};
 use lemmy_apub::protocol::activities::deletion::delete_user::DeleteUser;
 use lemmy_utils::{ConnectionId, LemmyError};
 use lemmy_websocket::LemmyContext;
index 839f46f2c547c9bf9c32ce6268be55db4b54e045..4b54430daac07b11dcb72554707bdec2e95cf0fc 100644 (file)
@@ -1,18 +1,16 @@
 use crate::PerformCrud;
 use actix_web::web::Data;
 use lemmy_api_common::{
-  blocking,
-  check_private_instance,
-  get_local_user_view_from_jwt_opt,
-  person::*,
+  person::{GetPersonDetails, GetPersonDetailsResponse},
+  utils::{blocking, check_private_instance, get_local_user_view_from_jwt_opt},
 };
 use lemmy_apub::{fetcher::resolve_actor_identifier, objects::person::ApubPerson};
-use lemmy_db_schema::{from_opt_str_to_opt_enum, source::person::Person, SortType};
-use lemmy_db_views::{comment_view::CommentQueryBuilder, post_view::PostQueryBuilder};
-use lemmy_db_views_actor::{
-  community_moderator_view::CommunityModeratorView,
-  person_view::PersonViewSafe,
+use lemmy_db_schema::{
+  source::person::Person,
+  utils::{from_opt_str_to_opt_enum, SortType},
 };
+use lemmy_db_views::{comment_view::CommentQueryBuilder, post_view::PostQueryBuilder};
+use lemmy_db_views_actor::structs::{CommunityModeratorView, PersonViewSafe};
 use lemmy_utils::{ConnectionId, LemmyError};
 use lemmy_websocket::LemmyContext;
 
index 7fa3e175e4b3ca3fe861280cd306108be4b7c368..999964e2b143c9869fa395625376623f55745d68 100644 (file)
@@ -15,14 +15,14 @@ doctest = false
 [dependencies]
 lemmy_utils = { version = "=0.16.3", path = "../utils" }
 lemmy_apub_lib = { version = "=0.16.3", path = "../apub_lib" }
-lemmy_db_schema = { version = "=0.16.3", path = "../db_schema" }
-lemmy_db_views = { version = "=0.16.3", path = "../db_views" }
-lemmy_db_views_actor = { version = "=0.16.3", path = "../db_views_actor" }
-lemmy_api_common = { version = "=0.16.3", path = "../api_common" }
+lemmy_db_schema = { version = "=0.16.3", path = "../db_schema", features = ["full"] }
+lemmy_db_views = { version = "=0.16.3", path = "../db_views", features = ["full"] }
+lemmy_db_views_actor = { version = "=0.16.3", path = "../db_views_actor", features = ["full"] }
+lemmy_api_common = { version = "=0.16.3", path = "../api_common", features = ["full"] }
 lemmy_websocket = { version = "=0.16.3", path = "../websocket" }
 diesel = "1.4.8"
 activitystreams-kinds = "0.2.1"
-chrono = { version = "0.4.19", features = ["serde"] }
+chrono = { version = "0.4.19", features = ["serde"], default-features = false }
 serde_json = { version = "1.0.79", features = ["preserve_order"] }
 serde = { version = "1.0.136", features = ["derive"] }
 serde_with = "1.12.0"
index d21c038bee6713b3f01e52c5f27885ae3e43f627..bcab3148ac8b594b0e0e87180a7c28663d00ef44 100644 (file)
@@ -16,7 +16,7 @@ use crate::{
 use activitystreams_kinds::{activity::BlockType, public};
 use anyhow::anyhow;
 use chrono::NaiveDateTime;
-use lemmy_api_common::{blocking, remove_user_data, remove_user_data_in_community};
+use lemmy_api_common::utils::{blocking, remove_user_data, remove_user_data_in_community};
 use lemmy_apub_lib::{
   data::Data,
   object_id::ObjectId,
index f41e352f601afd12f53b152829d416a8da739cbf..bb35d7d211621d2492a493f8eacb89a477cd7b6c 100644 (file)
@@ -3,12 +3,12 @@ use crate::{
   protocol::objects::{group::Group, instance::Instance},
 };
 use chrono::NaiveDateTime;
-use lemmy_api_common::blocking;
+use lemmy_api_common::utils::blocking;
 use lemmy_apub_lib::{
   object_id::ObjectId,
   traits::{ActorType, ApubObject},
 };
-use lemmy_db_schema::{source::site::Site, DbPool};
+use lemmy_db_schema::{source::site::Site, utils::DbPool};
 use lemmy_utils::LemmyError;
 use lemmy_websocket::LemmyContext;
 use serde::Deserialize;
index 29c9cd10e0440053d232427688ab54917cfc633a..130b1eb506d796b7ffd60dc2713fee3ec94bfe22 100644 (file)
@@ -12,7 +12,7 @@ use crate::{
   protocol::activities::block::{block_user::BlockUser, undo_block_user::UndoBlockUser},
 };
 use activitystreams_kinds::{activity::UndoType, public};
-use lemmy_api_common::blocking;
+use lemmy_api_common::utils::blocking;
 use lemmy_apub_lib::{
   data::Data,
   object_id::ObjectId,
index a86c8ac3158c6e5d2b1d73acac5d085598691802..2aa7989ee177398f62080d3682fc0075a8cedbc7 100644 (file)
@@ -18,7 +18,7 @@ use crate::{
   protocol::activities::community::add_mod::AddMod,
 };
 use activitystreams_kinds::{activity::AddType, public};
-use lemmy_api_common::blocking;
+use lemmy_api_common::utils::blocking;
 use lemmy_apub_lib::{
   data::Data,
   object_id::ObjectId,
index 7e43fcbf7b48198ed4699322d169ba9028264760..f42d47f63dc630e21d1b08968598c3319588b181 100644 (file)
@@ -18,7 +18,7 @@ use crate::{
   protocol::activities::community::remove_mod::RemoveMod,
 };
 use activitystreams_kinds::{activity::RemoveType, public};
-use lemmy_api_common::blocking;
+use lemmy_api_common::utils::blocking;
 use lemmy_apub_lib::{
   data::Data,
   object_id::ObjectId,
index 5ebbd9d7de7ad20b49a98eb8fcaeb0639e29396b..0069aa6e663257214de9ada592e2e76c8bcb2108 100644 (file)
@@ -10,7 +10,7 @@ use crate::{
   PostOrComment,
 };
 use activitystreams_kinds::activity::FlagType;
-use lemmy_api_common::{blocking, comment::CommentReportResponse, post::PostReportResponse};
+use lemmy_api_common::{comment::CommentReportResponse, post::PostReportResponse, utils::blocking};
 use lemmy_apub_lib::{
   data::Data,
   object_id::ObjectId,
@@ -23,7 +23,7 @@ use lemmy_db_schema::{
   },
   traits::Reportable,
 };
-use lemmy_db_views::{comment_report_view::CommentReportView, post_report_view::PostReportView};
+use lemmy_db_views::structs::{CommentReportView, PostReportView};
 use lemmy_utils::LemmyError;
 use lemmy_websocket::{messages::SendModRoomMessage, LemmyContext, UserOperation};
 
index f260363bb8470e840e6557e912d8dcb7103303b0..e6676b8bf3b40426e5d17d09f40b5c1ce30b39d7 100644 (file)
@@ -12,7 +12,7 @@ use crate::{
   protocol::activities::community::update::UpdateCommunity,
 };
 use activitystreams_kinds::{activity::UpdateType, public};
-use lemmy_api_common::blocking;
+use lemmy_api_common::utils::blocking;
 use lemmy_apub_lib::{
   data::Data,
   object_id::ObjectId,
index ed95b931b171026bc524a931d91f554b33d13999..c0e53a6075eafc46d928a72c114eebe23f49be3c 100644 (file)
@@ -14,7 +14,7 @@ use crate::{
   protocol::activities::{create_or_update::comment::CreateOrUpdateComment, CreateOrUpdateType},
 };
 use activitystreams_kinds::public;
-use lemmy_api_common::{blocking, check_post_deleted_or_removed};
+use lemmy_api_common::utils::{blocking, check_post_deleted_or_removed};
 use lemmy_apub_lib::{
   data::Data,
   object_id::ObjectId,
index 3cdac71b29293f70c7c5b763b8aeda4e87fe7c6a..99305f24cd65026c6a8d7ae8827051664597b79b 100644 (file)
@@ -1,5 +1,5 @@
 use crate::objects::person::ApubPerson;
-use lemmy_api_common::blocking;
+use lemmy_api_common::utils::blocking;
 use lemmy_apub_lib::object_id::ObjectId;
 use lemmy_db_schema::{
   newtypes::LocalUserId,
index ddbe0981b03415241e877e3055ccdd36c78766fb..70c59c35c205958630935041d9856d85baf24b82 100644 (file)
@@ -13,7 +13,7 @@ use crate::{
   protocol::activities::{create_or_update::post::CreateOrUpdatePost, CreateOrUpdateType},
 };
 use activitystreams_kinds::public;
-use lemmy_api_common::blocking;
+use lemmy_api_common::utils::blocking;
 use lemmy_apub_lib::{
   data::Data,
   object_id::ObjectId,
index bae430475a9358ea1baa0659bfa4a41f230719af..295e5b4f16269ed719760f5d5bf0a332744bdaa2 100644 (file)
@@ -6,7 +6,7 @@ use crate::{
     CreateOrUpdateType,
   },
 };
-use lemmy_api_common::blocking;
+use lemmy_api_common::utils::blocking;
 use lemmy_apub_lib::{
   data::Data,
   object_id::ObjectId,
index 275683a379c71ba88a04dfb3184ccfb79e8e2a88..3f02158750665ce58944f11c7e81539d1fcb7b9c 100644 (file)
@@ -10,7 +10,7 @@ use crate::{
 };
 use activitystreams_kinds::activity::DeleteType;
 use anyhow::anyhow;
-use lemmy_api_common::blocking;
+use lemmy_api_common::utils::blocking;
 use lemmy_apub_lib::{data::Data, object_id::ObjectId, traits::ActivityHandler};
 use lemmy_db_schema::{
   source::{
index 0cd2c5010b1279ac06feb8fd12c7545c8e113e05..a96333d5e315363b9e5f2297230dc7792eedb7e9 100644 (file)
@@ -4,7 +4,7 @@ use crate::{
   protocol::activities::deletion::delete_user::DeleteUser,
 };
 use activitystreams_kinds::{activity::DeleteType, public};
-use lemmy_api_common::{blocking, delete_user_account};
+use lemmy_api_common::utils::{blocking, delete_user_account};
 use lemmy_apub_lib::{
   data::Data,
   object_id::ObjectId,
index 1ff8429aa9a74a7ef7ad16b711a3f7466afe8172..123e87fbd551565462cfce13b905d469022f5129 100644 (file)
@@ -18,7 +18,7 @@ use crate::{
   protocol::activities::deletion::{delete::Delete, undo_delete::UndoDelete},
 };
 use activitystreams_kinds::public;
-use lemmy_api_common::blocking;
+use lemmy_api_common::utils::blocking;
 use lemmy_apub_lib::{
   object_id::ObjectId,
   traits::{ActorType, ApubObject},
index 6dced43959f38b65afa64670515a194f6c83f134..34e8974796649c0db4de151ead24aad96079f64d 100644 (file)
@@ -9,7 +9,7 @@ use crate::{
   protocol::activities::deletion::{delete::Delete, undo_delete::UndoDelete},
 };
 use activitystreams_kinds::activity::UndoType;
-use lemmy_api_common::blocking;
+use lemmy_api_common::utils::blocking;
 use lemmy_apub_lib::{data::Data, object_id::ObjectId, traits::ActivityHandler};
 use lemmy_db_schema::{
   source::{
index 690bec28f918bb7638cfa0309425fe9b99f1cd17..dfc008a94e489f3cb6f078e3c800c3598cd3e23d 100644 (file)
@@ -3,7 +3,7 @@ use crate::{
   protocol::activities::following::{accept::AcceptFollowCommunity, follow::FollowCommunity},
 };
 use activitystreams_kinds::activity::AcceptType;
-use lemmy_api_common::blocking;
+use lemmy_api_common::utils::blocking;
 use lemmy_apub_lib::{
   data::Data,
   object_id::ObjectId,
index fb35b0d3239335a8f778bed85c404dd6577cbff6..d46b3dc20f130049faa1ff97259d05bc0dae7a7b 100644 (file)
@@ -10,7 +10,7 @@ use crate::{
   protocol::activities::following::{accept::AcceptFollowCommunity, follow::FollowCommunity},
 };
 use activitystreams_kinds::activity::FollowType;
-use lemmy_api_common::blocking;
+use lemmy_api_common::utils::blocking;
 use lemmy_apub_lib::{
   data::Data,
   object_id::ObjectId,
index 73b0366bc2867c41de511e1d17e69f70e10eb221..f70acdf2725912ebd57cbf041bd3b20ee13accb6 100644 (file)
@@ -4,7 +4,7 @@ use crate::{
   protocol::activities::following::{follow::FollowCommunity, undo_follow::UndoFollowCommunity},
 };
 use activitystreams_kinds::activity::UndoType;
-use lemmy_api_common::blocking;
+use lemmy_api_common::utils::blocking;
 use lemmy_apub_lib::{
   data::Data,
   object_id::ObjectId,
index 77d4883f00a764dc5e8aab9697da45ad1a5f9038..2c8b0921cef2305e25fd8e374eb08de224a5c894 100644 (file)
@@ -7,7 +7,7 @@ use crate::{
 };
 use activitystreams_kinds::public;
 use anyhow::anyhow;
-use lemmy_api_common::blocking;
+use lemmy_api_common::utils::blocking;
 use lemmy_apub_lib::{
   activity_queue::send_activity,
   object_id::ObjectId,
@@ -15,10 +15,7 @@ use lemmy_apub_lib::{
   verify::verify_domains_match,
 };
 use lemmy_db_schema::source::community::Community;
-use lemmy_db_views_actor::{
-  community_person_ban_view::CommunityPersonBanView,
-  community_view::CommunityView,
-};
+use lemmy_db_views_actor::structs::{CommunityPersonBanView, CommunityView};
 use lemmy_utils::{settings::structs::Settings, LemmyError};
 use lemmy_websocket::LemmyContext;
 use serde::Serialize;
index c82b4efd495e91af7e56706836f6e347db7ad189..f2e3f24f8c0025709b1873ba02f1262bd8fd657c 100644 (file)
@@ -1,4 +1,4 @@
-use lemmy_api_common::blocking;
+use lemmy_api_common::utils::blocking;
 use lemmy_db_schema::{
   source::{
     comment::{CommentLike, CommentLikeForm},
index 16ea64e00e4fab4ab18acbd0da9be2a910915a20..eb350770ed22bf33be79a6dd120ea4ef2e3dd460 100644 (file)
@@ -16,7 +16,7 @@ use crate::{
   PostOrComment,
 };
 use activitystreams_kinds::{activity::UndoType, public};
-use lemmy_api_common::blocking;
+use lemmy_api_common::utils::blocking;
 use lemmy_apub_lib::{
   data::Data,
   object_id::ObjectId,
index ce6dee28f36562ee6082eb643d26d0709d54f510..a851e28f4e543ee115ec91da46a3b8690e65c340 100644 (file)
@@ -14,7 +14,7 @@ use crate::{
 };
 use activitystreams_kinds::public;
 use anyhow::anyhow;
-use lemmy_api_common::blocking;
+use lemmy_api_common::utils::blocking;
 use lemmy_apub_lib::{
   data::Data,
   object_id::ObjectId,
index b0182bdf2e1fb27502e7f8da5f7ae04d1c2c5a1a..4e084a16573f215ea7eb7a3bed29bc5ef327c266 100644 (file)
@@ -6,13 +6,13 @@ use crate::{
 };
 use activitystreams_kinds::collection::OrderedCollectionType;
 use chrono::NaiveDateTime;
-use lemmy_api_common::blocking;
+use lemmy_api_common::utils::blocking;
 use lemmy_apub_lib::{object_id::ObjectId, traits::ApubObject, verify::verify_domains_match};
 use lemmy_db_schema::{
   source::community::{CommunityModerator, CommunityModeratorForm},
   traits::Joinable,
 };
-use lemmy_db_views_actor::community_moderator_view::CommunityModeratorView;
+use lemmy_db_views_actor::structs::CommunityModeratorView;
 use lemmy_utils::LemmyError;
 use url::Url;
 
index 769e9bb2f6da086b05723f75016978959c96484b..098471c260b7f08da920c6941c4ef1f8b850b125 100644 (file)
@@ -11,7 +11,7 @@ use crate::{
 use activitystreams_kinds::collection::OrderedCollectionType;
 use chrono::NaiveDateTime;
 use futures::future::join_all;
-use lemmy_api_common::blocking;
+use lemmy_api_common::utils::blocking;
 use lemmy_apub_lib::{
   data::Data,
   traits::{ActivityHandler, ApubObject},
index ccb409e8d3fc9d530225e3bc26410f08af769177..2eb4f88492d7645341ec8f96ec1ea99587d8adfb 100644 (file)
@@ -1,5 +1,5 @@
 use crate::fetcher::post_or_comment::PostOrComment;
-use lemmy_api_common::blocking;
+use lemmy_api_common::utils::blocking;
 use lemmy_db_queries::source::{
   comment::Comment_,
   community::Community_,
index 16173568ee6c6d7e0b2204b571c8945b1ca99634..cd889ccc6106a43104ee2f96359c031316f9aa2c 100644 (file)
@@ -1,6 +1,6 @@
 use crate::fetcher::webfinger::webfinger_resolve_actor;
 use itertools::Itertools;
-use lemmy_api_common::blocking;
+use lemmy_api_common::utils::blocking;
 use lemmy_apub_lib::traits::{ActorType, ApubObject};
 use lemmy_db_schema::traits::ApubActor;
 use lemmy_utils::{settings::structs::Settings, LemmyError};
index e2370c329819e086c6578204666a18585382f031..da516b1da4e42a46d703fa7b244545048316d730 100644 (file)
@@ -5,10 +5,7 @@ use lemmy_apub_lib::{
   traits::{ActorType, ApubObject},
 };
 use lemmy_db_schema::newtypes::DbUrl;
-use lemmy_utils::{
-  request::{retry, RecvError},
-  LemmyError,
-};
+use lemmy_utils::{request::retry, LemmyError};
 use lemmy_websocket::LemmyContext;
 use serde::{Deserialize, Serialize};
 use tracing::debug;
@@ -58,10 +55,7 @@ where
 
   let response = retry(|| context.client().get(&fetch_url).send()).await?;
 
-  let res: WebfingerResponse = response
-    .json()
-    .await
-    .map_err(|e| RecvError(e.to_string()))?;
+  let res: WebfingerResponse = response.json().await.map_err(LemmyError::from)?;
 
   let links: Vec<Url> = res
     .links
index 6a72434353dbae8805a5d62eb1585ec9dc7560de..1918a38e8ceb3495223b09d3d88484091965d0c8 100644 (file)
@@ -4,7 +4,7 @@ use crate::{
 };
 use actix_web::{web, web::Path, HttpResponse};
 use diesel::result::Error::NotFound;
-use lemmy_api_common::blocking;
+use lemmy_api_common::utils::blocking;
 use lemmy_apub_lib::traits::ApubObject;
 use lemmy_db_schema::{newtypes::CommentId, source::comment::Comment, traits::Crud};
 use lemmy_utils::LemmyError;
index c049c6aef16dea14a7af31bc5723cc9407965082..41f6d1c0ba515b34100c6f822211eadaf64643d8 100644 (file)
@@ -22,7 +22,7 @@ use crate::{
   },
 };
 use actix_web::{web, web::Payload, HttpRequest, HttpResponse};
-use lemmy_api_common::blocking;
+use lemmy_api_common::utils::blocking;
 use lemmy_apub_lib::{object_id::ObjectId, traits::ApubObject};
 use lemmy_db_schema::{source::community::Community, traits::ApubActor};
 use lemmy_utils::LemmyError;
index 477357e045ee726f3a2283c9cc59b45a5a990abc..0112d2056d5554b75065ab5492d3d3b5626765c9 100644 (file)
@@ -15,7 +15,7 @@ use actix_web::{
 use anyhow::{anyhow, Context};
 use futures::StreamExt;
 use http::StatusCode;
-use lemmy_api_common::blocking;
+use lemmy_api_common::utils::blocking;
 use lemmy_apub_lib::{
   data::Data,
   object_id::ObjectId,
index 9081d5a554dc7d27250442112379c8810acde490..f0540268ae60446dce82794a133e184ce4a5fcde 100644 (file)
@@ -13,7 +13,7 @@ use crate::{
   protocol::collections::empty_outbox::EmptyOutbox,
 };
 use actix_web::{web, web::Payload, HttpRequest, HttpResponse};
-use lemmy_api_common::blocking;
+use lemmy_api_common::utils::blocking;
 use lemmy_apub_lib::traits::ApubObject;
 use lemmy_db_schema::{source::person::Person, traits::ApubActor};
 use lemmy_utils::LemmyError;
index 3f180a0c88581d8cd270cba2dddce902be386bd8..845803b906b2657855950c767c50783bc3bb7013 100644 (file)
@@ -4,7 +4,7 @@ use crate::{
 };
 use actix_web::{web, HttpResponse};
 use diesel::result::Error::NotFound;
-use lemmy_api_common::blocking;
+use lemmy_api_common::utils::blocking;
 use lemmy_apub_lib::traits::ApubObject;
 use lemmy_db_schema::{newtypes::PostId, source::post::Post, traits::Crud};
 use lemmy_utils::LemmyError;
index 894622ad623621432499d0d494b3730e0909f70e..e4811066379e53cd424231c97b3861e793b81fe8 100644 (file)
@@ -6,7 +6,7 @@ use crate::{
   protocol::collections::empty_outbox::EmptyOutbox,
 };
 use actix_web::{web, web::Payload, HttpRequest, HttpResponse};
-use lemmy_api_common::blocking;
+use lemmy_api_common::utils::blocking;
 use lemmy_apub_lib::traits::ApubObject;
 use lemmy_db_schema::source::site::Site;
 use lemmy_utils::{settings::structs::Settings, LemmyError};
index 80116a8f87d136715f2086b41b5d1dbfe339215a..b7f1912d8a072d6c7053e2d7f992574e76c135f7 100644 (file)
@@ -1,7 +1,7 @@
 use crate::fetcher::post_or_comment::PostOrComment;
 use anyhow::{anyhow, Context};
-use lemmy_api_common::blocking;
-use lemmy_db_schema::{newtypes::DbUrl, source::activity::Activity, DbPool};
+use lemmy_api_common::utils::blocking;
+use lemmy_db_schema::{newtypes::DbUrl, source::activity::Activity, utils::DbPool};
 use lemmy_utils::{location_info, settings::structs::Settings, LemmyError};
 use serde::{Deserialize, Deserializer};
 use std::net::IpAddr;
@@ -14,7 +14,6 @@ mod context;
 pub mod fetcher;
 pub mod http;
 pub(crate) mod mentions;
-pub mod migrations;
 pub mod objects;
 pub mod protocol;
 
index 78d568e5151510075024fc33a798ff6b776e73a2..b68391a983eafa2d30669fbea44378c9baa1060a 100644 (file)
@@ -3,12 +3,12 @@ use crate::{
   objects::{comment::ApubComment, community::ApubCommunity, person::ApubPerson},
 };
 use activitystreams_kinds::link::MentionType;
-use lemmy_api_common::blocking;
+use lemmy_api_common::utils::blocking;
 use lemmy_apub_lib::{object_id::ObjectId, traits::ActorType};
 use lemmy_db_schema::{
   source::{comment::Comment, person::Person, post::Post},
   traits::Crud,
-  DbPool,
+  utils::DbPool,
 };
 use lemmy_utils::{
   utils::{scrape_text_for_mentions, MentionData},
diff --git a/crates/apub/src/migrations.rs b/crates/apub/src/migrations.rs
deleted file mode 100644 (file)
index 8b13789..0000000
+++ /dev/null
@@ -1 +0,0 @@
-
index 40aef9197f38dbd7bb7aa27af1025cefa5a5f6ee..c987ff8bdbfcd43d05fc80a440f3557c4985eaec 100644 (file)
@@ -11,7 +11,7 @@ use crate::{
 };
 use activitystreams_kinds::{object::NoteType, public};
 use chrono::NaiveDateTime;
-use lemmy_api_common::blocking;
+use lemmy_api_common::utils::blocking;
 use lemmy_apub_lib::{
   object_id::ObjectId,
   traits::ApubObject,
index 59489d3e4795cd91a3737f84416b58a771c533f1..a8904ac58bf86daa049f3b87eabe2cd400baaf5f 100644 (file)
@@ -13,13 +13,13 @@ use crate::{
 use activitystreams_kinds::actor::GroupType;
 use chrono::NaiveDateTime;
 use itertools::Itertools;
-use lemmy_api_common::blocking;
+use lemmy_api_common::utils::blocking;
 use lemmy_apub_lib::{
   object_id::ObjectId,
   traits::{ActorType, ApubObject},
 };
 use lemmy_db_schema::{source::community::Community, traits::ApubActor};
-use lemmy_db_views_actor::community_follower_view::CommunityFollowerView;
+use lemmy_db_views_actor::structs::CommunityFollowerView;
 use lemmy_utils::{
   utils::{convert_datetime, markdown_to_html},
   LemmyError,
index c3641fca923be50fd0654441feefac459db8541d..225a10912cec882b58a13a9091b4050348006484 100644 (file)
@@ -8,7 +8,7 @@ use crate::{
   },
 };
 use chrono::NaiveDateTime;
-use lemmy_api_common::blocking;
+use lemmy_api_common::utils::blocking;
 use lemmy_apub_lib::{
   object_id::ObjectId,
   traits::{ActorType, ApubObject},
@@ -16,8 +16,8 @@ use lemmy_apub_lib::{
   verify::verify_domains_match,
 };
 use lemmy_db_schema::{
-  naive_now,
   source::site::{Site, SiteForm},
+  utils::naive_now,
 };
 use lemmy_utils::{
   utils::{check_slurs, check_slurs_opt, convert_datetime, markdown_to_html},
index e7155b4b14d144c7d2e8d7ecc07f074cb79f7843..0e55c49da96b4e386721ebb7cdaa20790d622885 100644 (file)
@@ -62,15 +62,14 @@ pub(crate) mod tests {
     r2d2::{ConnectionManager, Pool},
     PgConnection,
   };
+  use lemmy_api_common::request::build_user_agent;
   use lemmy_apub_lib::activity_queue::create_activity_queue;
   use lemmy_db_schema::{
-    establish_unpooled_connection,
-    get_database_url_from_env,
     source::secret::Secret,
+    utils::{establish_unpooled_connection, get_database_url_from_env},
   };
   use lemmy_utils::{
     rate_limit::{rate_limiter::RateLimiter, RateLimit},
-    request::build_user_agent,
     settings::structs::Settings,
     LemmyError,
   };
index 039dbbb131c538d19a817eb93263e2576352afd3..e1938ed3d927244ea740598d052f3b53dff5f3b8 100644 (file)
@@ -16,16 +16,16 @@ use crate::{
   },
 };
 use chrono::NaiveDateTime;
-use lemmy_api_common::blocking;
+use lemmy_api_common::utils::blocking;
 use lemmy_apub_lib::{
   object_id::ObjectId,
   traits::{ActorType, ApubObject},
   verify::verify_domains_match,
 };
 use lemmy_db_schema::{
-  naive_now,
   source::person::{Person as DbPerson, PersonForm},
   traits::ApubActor,
+  utils::naive_now,
 };
 use lemmy_utils::{
   utils::{check_slurs, check_slurs_opt, convert_datetime, markdown_to_html},
index 88ca1ceb03c8ab471729d7a42db9c1cfadcb6cbd..f6938dd6e3f53b511a877a3850d6f3871b82e87c 100644 (file)
@@ -13,7 +13,7 @@ use crate::{
 };
 use activitystreams_kinds::public;
 use chrono::NaiveDateTime;
-use lemmy_api_common::blocking;
+use lemmy_api_common::{request::fetch_site_data, utils::blocking};
 use lemmy_apub_lib::{
   object_id::ObjectId,
   traits::ApubObject,
@@ -31,7 +31,6 @@ use lemmy_db_schema::{
   traits::Crud,
 };
 use lemmy_utils::{
-  request::fetch_site_data,
   utils::{check_slurs, convert_datetime, markdown_to_html, remove_slurs},
   LemmyError,
 };
index 560059865cbdd54243e818fca131f00293379200..7a638af32eda776613d027287a692fe604a72076 100644 (file)
@@ -6,7 +6,7 @@ use crate::{
   },
 };
 use chrono::NaiveDateTime;
-use lemmy_api_common::blocking;
+use lemmy_api_common::utils::blocking;
 use lemmy_apub_lib::{
   object_id::ObjectId,
   traits::ApubObject,
index 032731b739ea21a4191031baea15f0be9261b552..777d19803b61ff66c6a49527b50ae8410c8b0362 100644 (file)
@@ -1,8 +1,8 @@
 use crate::generate_followers_url;
 use activitystreams_kinds::collection::CollectionType;
-use lemmy_api_common::blocking;
+use lemmy_api_common::utils::blocking;
 use lemmy_db_schema::source::community::Community;
-use lemmy_db_views_actor::community_follower_view::CommunityFollowerView;
+use lemmy_db_views_actor::structs::CommunityFollowerView;
 use lemmy_utils::LemmyError;
 use lemmy_websocket::LemmyContext;
 use serde::{Deserialize, Serialize};
index 57d0ae157a6daff0a2ddaf197eeedd97479a25de..c0b544f37a523463246ab6419bef5ab4d146c00d 100644 (file)
@@ -14,7 +14,7 @@ use crate::{
 use activitystreams_kinds::actor::GroupType;
 use chrono::{DateTime, FixedOffset};
 use lemmy_apub_lib::{object_id::ObjectId, signatures::PublicKey, verify::verify_domains_match};
-use lemmy_db_schema::{naive_now, source::community::CommunityForm};
+use lemmy_db_schema::{source::community::CommunityForm, utils::naive_now};
 use lemmy_utils::{
   utils::{check_slurs, check_slurs_opt},
   LemmyError,
index b1c4b5d073674a35ea7f42716c9ead53ad8433e6..779675cc1bdd280abe5b56e5b5885b1d2cc884ec 100644 (file)
@@ -6,7 +6,7 @@ use crate::{
 };
 use activitystreams_kinds::object::NoteType;
 use chrono::{DateTime, FixedOffset};
-use lemmy_api_common::blocking;
+use lemmy_api_common::utils::blocking;
 use lemmy_apub_lib::{object_id::ObjectId, values::MediaTypeHtml};
 use lemmy_db_schema::{newtypes::CommentId, source::post::Post, traits::Crud};
 use lemmy_utils::LemmyError;
index 1b2cabbf4566d778cdd5f74a60be7e90fad90aa4..366ee7a0f27406e7c6555857dd566823e960f085 100644 (file)
@@ -10,7 +10,7 @@ documentation = "https://join-lemmy.org/docs/en/index.html"
 [dependencies]
 lemmy_utils = { version = "=0.16.3", path = "../utils" }
 lemmy_apub_lib_derive = { version = "=0.16.3", path = "../apub_lib_derive" }
-chrono = "0.4.19"
+chrono = { version = "0.4.19", default-features = false }
 serde = { version = "1.0.136", features = ["derive"] }
 async-trait = "0.1.53"
 url = { version = "2.2.2", features = ["serde"] }
index 0ee7dd5ad7c9ac94f7337a068d5f514e5475efe5..b2e40ed8eb987231e2648cc1f58268c32a916107 100644 (file)
@@ -12,22 +12,26 @@ name = "lemmy_db_schema"
 path = "src/lib.rs"
 doctest = false
 
+[features]
+full = ["diesel", "diesel-derive-newtype", "diesel_migrations", "bcrypt", "lemmy_utils",
+    "lemmy_apub_lib", "strum", "strum_macros", "sha2", "regex", "once_cell", "serde_json"]
+
 [dependencies]
-lemmy_utils = { version = "=0.16.3", path = "../utils" }
-lemmy_apub_lib = { version = "=0.16.3", 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"] }
+chrono = { version = "0.4.19", features = ["serde"], default-features = false }
 serde = { version = "1.0.136", features = ["derive"] }
-serde_json = { version = "1.0.79", features = ["preserve_order"] }
 url = { version = "2.2.2", features = ["serde"] }
-diesel-derive-newtype = "0.1.2"
-regex = "1.5.5"
-once_cell = "1.10.0"
-strum = "0.24.0"
-strum_macros = "0.24.0"
-sha2 = "0.10.2"
-bcrypt = "0.12.1"
+serde_json = { version = "1.0.79", features = ["preserve_order"], optional = true }
+lemmy_apub_lib = { version = "=0.16.3", path = "../apub_lib", optional = true }
+lemmy_utils = { version = "=0.16.3", path = "../utils", optional = true }
+bcrypt = { version = "0.12.1", optional = true }
+diesel = { version = "1.4.8", features = ["postgres","chrono","r2d2","serde_json"], optional = true }
+diesel-derive-newtype = { version = "0.1.2", optional = true }
+diesel_migrations = { version = "1.4.0", optional = true }
+strum = { version = "0.24.0", optional = true }
+strum_macros = { version = "0.24.0", optional = true }
+sha2 = { version = "0.10.2", optional = true }
+regex = { version = "1.5.5", optional = true }
+once_cell = { version = "1.10.0", optional = true }
 
 [dev-dependencies]
 serial_test = "0.6.0"
index d47899bbffb11f766008faa19ba9b8b401c27011..5e70bcc5f0f1afacd190e64a0d61d643d199c74b 100644 (file)
@@ -1,19 +1,9 @@
-use crate::{newtypes::CommentId, schema::comment_aggregates};
+use crate::{
+  aggregates::structs::CommentAggregates,
+  newtypes::CommentId,
+  schema::comment_aggregates,
+};
 use diesel::{result::Error, *};
-use serde::{Deserialize, Serialize};
-
-#[derive(
-  Queryable, Associations, Identifiable, PartialEq, Debug, Serialize, Deserialize, Clone,
-)]
-#[table_name = "comment_aggregates"]
-pub struct CommentAggregates {
-  pub id: i32,
-  pub comment_id: CommentId,
-  pub score: i64,
-  pub upvotes: i64,
-  pub downvotes: i64,
-  pub published: chrono::NaiveDateTime,
-}
 
 impl CommentAggregates {
   pub fn read(conn: &PgConnection, comment_id: CommentId) -> Result<Self, Error> {
@@ -27,7 +17,6 @@ impl CommentAggregates {
 mod tests {
   use crate::{
     aggregates::comment_aggregates::CommentAggregates,
-    establish_unpooled_connection,
     source::{
       comment::{Comment, CommentForm, CommentLike, CommentLikeForm},
       community::{Community, CommunityForm},
@@ -35,6 +24,7 @@ mod tests {
       post::{Post, PostForm},
     },
     traits::{Crud, Likeable},
+    utils::establish_unpooled_connection,
   };
   use serial_test::serial;
 
index d80425e1731245b7daf92071573fb75a69ff9418..950e68d3738a121ada292b373c8128af40afd9a9 100644 (file)
@@ -1,23 +1,9 @@
-use crate::{newtypes::CommunityId, schema::community_aggregates};
+use crate::{
+  aggregates::structs::CommunityAggregates,
+  newtypes::CommunityId,
+  schema::community_aggregates,
+};
 use diesel::{result::Error, *};
-use serde::{Deserialize, Serialize};
-
-#[derive(
-  Queryable, Associations, Identifiable, PartialEq, Debug, Serialize, Deserialize, Clone,
-)]
-#[table_name = "community_aggregates"]
-pub struct CommunityAggregates {
-  pub id: i32,
-  pub community_id: CommunityId,
-  pub subscribers: i64,
-  pub posts: i64,
-  pub comments: i64,
-  pub published: chrono::NaiveDateTime,
-  pub users_active_day: i64,
-  pub users_active_week: i64,
-  pub users_active_month: i64,
-  pub users_active_half_year: i64,
-}
 
 impl CommunityAggregates {
   pub fn read(conn: &PgConnection, community_id: CommunityId) -> Result<Self, Error> {
@@ -31,7 +17,6 @@ impl CommunityAggregates {
 mod tests {
   use crate::{
     aggregates::community_aggregates::CommunityAggregates,
-    establish_unpooled_connection,
     source::{
       comment::{Comment, CommentForm},
       community::{Community, CommunityFollower, CommunityFollowerForm, CommunityForm},
@@ -39,6 +24,7 @@ mod tests {
       post::{Post, PostForm},
     },
     traits::{Crud, Followable},
+    utils::establish_unpooled_connection,
   };
   use serial_test::serial;
 
index ad20f8a668d07a94e8d8ad2e7b4405e60bcf1370..03ab1b89a0dc991d460a86add4fd14589b61adf1 100644 (file)
@@ -1,5 +1,11 @@
+#[cfg(feature = "full")]
 pub mod comment_aggregates;
+#[cfg(feature = "full")]
 pub mod community_aggregates;
+#[cfg(feature = "full")]
 pub mod person_aggregates;
+#[cfg(feature = "full")]
 pub mod post_aggregates;
+#[cfg(feature = "full")]
 pub mod site_aggregates;
+pub mod structs;
index e0fc0734c39467ac58e29556a95bd1e192d8298f..0f270f9cb8f4a31df13153eccba0c2c68eea4424 100644 (file)
@@ -1,19 +1,5 @@
-use crate::{newtypes::PersonId, schema::person_aggregates};
+use crate::{aggregates::structs::PersonAggregates, newtypes::PersonId, schema::person_aggregates};
 use diesel::{result::Error, *};
-use serde::{Deserialize, Serialize};
-
-#[derive(
-  Queryable, Associations, Identifiable, PartialEq, Debug, Serialize, Deserialize, Clone, Default,
-)]
-#[table_name = "person_aggregates"]
-pub struct PersonAggregates {
-  pub id: i32,
-  pub person_id: PersonId,
-  pub post_count: i64,
-  pub post_score: i64,
-  pub comment_count: i64,
-  pub comment_score: i64,
-}
 
 impl PersonAggregates {
   pub fn read(conn: &PgConnection, person_id: PersonId) -> Result<Self, Error> {
@@ -27,7 +13,6 @@ impl PersonAggregates {
 mod tests {
   use crate::{
     aggregates::person_aggregates::PersonAggregates,
-    establish_unpooled_connection,
     source::{
       comment::{Comment, CommentForm, CommentLike, CommentLikeForm},
       community::{Community, CommunityForm},
@@ -35,6 +20,7 @@ mod tests {
       post::{Post, PostForm, PostLike, PostLikeForm},
     },
     traits::{Crud, Likeable},
+    utils::establish_unpooled_connection,
   };
   use serial_test::serial;
 
index cb8aba26eca10822bee2c9d398b70a3eb72c28d0..3d1a272901792d44ec2610d4aced16b5f0006826 100644 (file)
@@ -1,23 +1,5 @@
-use crate::{newtypes::PostId, schema::post_aggregates};
+use crate::{aggregates::structs::PostAggregates, newtypes::PostId, schema::post_aggregates};
 use diesel::{result::Error, *};
-use serde::{Deserialize, Serialize};
-
-#[derive(
-  Queryable, Associations, Identifiable, PartialEq, Debug, Serialize, Deserialize, Clone,
-)]
-#[table_name = "post_aggregates"]
-pub struct PostAggregates {
-  pub id: i32,
-  pub post_id: PostId,
-  pub comments: i64,
-  pub score: i64,
-  pub upvotes: i64,
-  pub downvotes: i64,
-  pub stickied: bool,
-  pub published: chrono::NaiveDateTime,
-  pub newest_comment_time_necro: chrono::NaiveDateTime, // A newest comment time, limited to 2 days, to prevent necrobumping
-  pub newest_comment_time: chrono::NaiveDateTime,
-}
 
 impl PostAggregates {
   pub fn read(conn: &PgConnection, post_id: PostId) -> Result<Self, Error> {
@@ -31,7 +13,6 @@ impl PostAggregates {
 mod tests {
   use crate::{
     aggregates::post_aggregates::PostAggregates,
-    establish_unpooled_connection,
     source::{
       comment::{Comment, CommentForm},
       community::{Community, CommunityForm},
@@ -39,6 +20,7 @@ mod tests {
       post::{Post, PostForm, PostLike, PostLikeForm},
     },
     traits::{Crud, Likeable},
+    utils::establish_unpooled_connection,
   };
   use serial_test::serial;
 
index 745097dfeb9c3d0952d5e197274ebf9a10ae81de..8cf57dfd8b2f99de9235d4ee3d757dddc3347883 100644 (file)
@@ -1,23 +1,5 @@
-use crate::schema::site_aggregates;
+use crate::{aggregates::structs::SiteAggregates, schema::site_aggregates};
 use diesel::{result::Error, *};
-use serde::{Deserialize, Serialize};
-
-#[derive(
-  Queryable, Associations, Identifiable, PartialEq, Debug, Serialize, Deserialize, Clone,
-)]
-#[table_name = "site_aggregates"]
-pub struct SiteAggregates {
-  pub id: i32,
-  pub site_id: i32,
-  pub users: i64,
-  pub posts: i64,
-  pub comments: i64,
-  pub communities: i64,
-  pub users_active_day: i64,
-  pub users_active_week: i64,
-  pub users_active_month: i64,
-  pub users_active_half_year: i64,
-}
 
 impl SiteAggregates {
   pub fn read(conn: &PgConnection) -> Result<Self, Error> {
@@ -29,7 +11,6 @@ impl SiteAggregates {
 mod tests {
   use crate::{
     aggregates::site_aggregates::SiteAggregates,
-    establish_unpooled_connection,
     source::{
       comment::{Comment, CommentForm},
       community::{Community, CommunityForm},
@@ -38,6 +19,7 @@ mod tests {
       site::{Site, SiteForm},
     },
     traits::Crud,
+    utils::establish_unpooled_connection,
   };
   use serial_test::serial;
 
diff --git a/crates/db_schema/src/aggregates/structs.rs b/crates/db_schema/src/aggregates/structs.rs
new file mode 100644 (file)
index 0000000..2f635b9
--- /dev/null
@@ -0,0 +1,83 @@
+use crate::newtypes::{CommentId, CommunityId, PersonId, PostId};
+use serde::{Deserialize, Serialize};
+
+#[cfg(feature = "full")]
+use crate::schema::{
+  comment_aggregates,
+  community_aggregates,
+  person_aggregates,
+  post_aggregates,
+  site_aggregates,
+};
+
+#[derive(PartialEq, Debug, Serialize, Deserialize, Clone)]
+#[cfg_attr(feature = "full", derive(Queryable, Associations, Identifiable))]
+#[cfg_attr(feature = "full", table_name = "comment_aggregates")]
+pub struct CommentAggregates {
+  pub id: i32,
+  pub comment_id: CommentId,
+  pub score: i64,
+  pub upvotes: i64,
+  pub downvotes: i64,
+  pub published: chrono::NaiveDateTime,
+}
+
+#[derive(PartialEq, Debug, Serialize, Deserialize, Clone)]
+#[cfg_attr(feature = "full", derive(Queryable, Associations, Identifiable))]
+#[cfg_attr(feature = "full", table_name = "community_aggregates")]
+pub struct CommunityAggregates {
+  pub id: i32,
+  pub community_id: CommunityId,
+  pub subscribers: i64,
+  pub posts: i64,
+  pub comments: i64,
+  pub published: chrono::NaiveDateTime,
+  pub users_active_day: i64,
+  pub users_active_week: i64,
+  pub users_active_month: i64,
+  pub users_active_half_year: i64,
+}
+
+#[derive(PartialEq, Debug, Serialize, Deserialize, Clone, Default)]
+#[cfg_attr(feature = "full", derive(Queryable, Associations, Identifiable))]
+#[cfg_attr(feature = "full", table_name = "person_aggregates")]
+pub struct PersonAggregates {
+  pub id: i32,
+  pub person_id: PersonId,
+  pub post_count: i64,
+  pub post_score: i64,
+  pub comment_count: i64,
+  pub comment_score: i64,
+}
+
+#[derive(PartialEq, Debug, Serialize, Deserialize, Clone)]
+#[cfg_attr(feature = "full", derive(Queryable, Associations, Identifiable))]
+#[cfg_attr(feature = "full", table_name = "post_aggregates")]
+pub struct PostAggregates {
+  pub id: i32,
+  pub post_id: PostId,
+  pub comments: i64,
+  pub score: i64,
+  pub upvotes: i64,
+  pub downvotes: i64,
+  pub stickied: bool,
+  pub published: chrono::NaiveDateTime,
+  pub newest_comment_time_necro: chrono::NaiveDateTime, // A newest comment time, limited to 2 days, to prevent necrobumping
+  pub newest_comment_time: chrono::NaiveDateTime,
+}
+
+#[derive(PartialEq, Debug, Serialize, Deserialize, Clone)]
+#[cfg_attr(feature = "full", derive(Queryable, Associations, Identifiable))]
+#[cfg_attr(feature = "full", table_name = "site_aggregates")]
+pub struct SiteAggregates {
+  pub id: i32,
+  pub site_id: i32,
+  pub users: i64,
+  pub posts: i64,
+  pub comments: i64,
+  pub communities: i64,
+  pub users_active_day: i64,
+  pub users_active_week: i64,
+  pub users_active_month: i64,
+  pub users_active_half_year: i64,
+}
index 261a89cbee6b00334c2f043ed6929f587e250957..48429315eb6ad8161e876da76c6e5c392eabc5fe 100644 (file)
@@ -79,12 +79,12 @@ impl Activity {
 mod tests {
   use super::*;
   use crate::{
-    establish_unpooled_connection,
     newtypes::DbUrl,
     source::{
       activity::{Activity, ActivityForm},
       person::{Person, PersonForm},
     },
+    utils::establish_unpooled_connection,
   };
   use serde_json::Value;
   use serial_test::serial;
index 09389aad81f4c909ec84d96e4917e31d933704fe..5fb3280c9b5c88c0e286aa1971d29f9f8e2b0d96 100644 (file)
@@ -1,5 +1,4 @@
 use crate::{
-  naive_now,
   newtypes::{CommentId, DbUrl, PersonId},
   source::comment::{
     Comment,
@@ -10,6 +9,7 @@ use crate::{
     CommentSavedForm,
   },
   traits::{Crud, DeleteableOrRemoveable, Likeable, Saveable},
+  utils::naive_now,
 };
 use diesel::{dsl::*, result::Error, *};
 use url::Url;
@@ -209,7 +209,6 @@ impl DeleteableOrRemoveable for Comment {
 #[cfg(test)]
 mod tests {
   use crate::{
-    establish_unpooled_connection,
     source::{
       comment::*,
       community::{Community, CommunityForm},
@@ -217,6 +216,7 @@ mod tests {
       post::*,
     },
     traits::{Crud, Likeable, Saveable},
+    utils::establish_unpooled_connection,
   };
   use serial_test::serial;
 
index d32f3ef4025e684b7babb618e8a672267fbd6faa..56e917e028f0135effae2521ef156ff9fc20f8d8 100644 (file)
@@ -1,8 +1,8 @@
 use crate::{
-  naive_now,
   newtypes::{CommentReportId, PersonId},
   source::comment_report::{CommentReport, CommentReportForm},
   traits::Reportable,
+  utils::naive_now,
 };
 use diesel::{dsl::*, result::Error, *};
 
index fb8bd6e4a1cbdb6d8be34bcf16a2d6a6218d0fd3..14a670f51c58ad1c7e33263b582fd8a678f879cc 100644 (file)
@@ -1,6 +1,4 @@
 use crate::{
-  functions::lower,
-  naive_now,
   newtypes::{CommunityId, DbUrl, PersonId},
   source::community::{
     Community,
@@ -14,6 +12,7 @@ use crate::{
     CommunitySafe,
   },
   traits::{ApubActor, Bannable, Crud, DeleteableOrRemoveable, Followable, Joinable},
+  utils::{functions::lower, naive_now},
 };
 use diesel::{
   dsl::*,
@@ -327,9 +326,9 @@ impl ApubActor for Community {
 #[cfg(test)]
 mod tests {
   use crate::{
-    establish_unpooled_connection,
     source::{community::*, person::*},
     traits::{Bannable, Crud, Followable, Joinable},
+    utils::establish_unpooled_connection,
   };
   use serial_test::serial;
 
index 833d6bdb9d7a042d9cdefc198de0bcff90295982..419ab7928947de937fd67aee201c0c634d946db4 100644 (file)
@@ -1,9 +1,9 @@
 use crate::{
-  naive_now,
   newtypes::LocalUserId,
   schema::local_user::dsl::*,
   source::local_user::{LocalUser, LocalUserForm},
   traits::Crud,
+  utils::naive_now,
 };
 use bcrypt::{hash, DEFAULT_COST};
 use diesel::{dsl::*, result::Error, *};
index 696dbe0a44d7a051cb0ccd2d33163a8b0048e6b0..36582d109bdcf5caf8ca7079112ea092f2350264 100644 (file)
@@ -266,9 +266,9 @@ impl Crud for ModAdd {
 #[cfg(test)]
 mod tests {
   use crate::{
-    establish_unpooled_connection,
     source::{comment::*, community::*, moderator::*, person::*, post::*},
     traits::Crud,
+    utils::establish_unpooled_connection,
   };
   use serial_test::serial;
 
index 808f0ac01c4bcaff15c80790b9e3fabab082f549..576e2673955fbe2c355b73f9fe095f58e6429e7a 100644 (file)
@@ -70,13 +70,13 @@ fn bytes_to_hex(bytes: Vec<u8>) -> String {
 #[cfg(test)]
 mod tests {
   use crate::{
-    establish_unpooled_connection,
     source::{
       local_user::{LocalUser, LocalUserForm},
       password_reset_request::PasswordResetRequest,
       person::*,
     },
     traits::Crud,
+    utils::establish_unpooled_connection,
   };
   use serial_test::serial;
 
index 165d9308e45bfb1e8f0653f81e29a1f6b858b7ec..c59126c32298a2205528e0fee06cc67da84389fd 100644 (file)
@@ -1,10 +1,9 @@
 use crate::{
-  functions::lower,
-  naive_now,
   newtypes::{DbUrl, PersonId},
   schema::person::dsl::*,
   source::person::{Person, PersonForm, PersonSafe},
   traits::{ApubActor, Crud},
+  utils::{functions::lower, naive_now},
 };
 use diesel::{
   dsl::*,
@@ -318,7 +317,7 @@ impl ApubActor for Person {
 
 #[cfg(test)]
 mod tests {
-  use crate::{establish_unpooled_connection, source::person::*, traits::Crud};
+  use crate::{source::person::*, traits::Crud, utils::establish_unpooled_connection};
 
   #[test]
   fn test_crud() {
index df0e55edeb23481990a6eb522fb39baca7958cda..c8fb6cc0966c0f14f0ac5f4acbf04797d5db299b 100644 (file)
@@ -78,7 +78,6 @@ impl PersonMention {
 #[cfg(test)]
 mod tests {
   use crate::{
-    establish_unpooled_connection,
     source::{
       comment::*,
       community::{Community, CommunityForm},
@@ -87,6 +86,7 @@ mod tests {
       post::*,
     },
     traits::Crud,
+    utils::establish_unpooled_connection,
   };
   use serial_test::serial;
 
index 9a8bbcece80fd7b1eaf0c72d5990b1537cbdaba2..c878931a1ea2a470fdcc3572000063d9130e32ef 100644 (file)
@@ -1,5 +1,4 @@
 use crate::{
-  naive_now,
   newtypes::{CommunityId, DbUrl, PersonId, PostId},
   source::post::{
     Post,
@@ -12,6 +11,7 @@ use crate::{
     PostSavedForm,
   },
   traits::{Crud, DeleteableOrRemoveable, Likeable, Readable, Saveable},
+  utils::naive_now,
 };
 use diesel::{dsl::*, result::Error, ExpressionMethods, PgConnection, QueryDsl, RunQueryDsl};
 use url::Url;
@@ -261,13 +261,13 @@ impl DeleteableOrRemoveable for Post {
 #[cfg(test)]
 mod tests {
   use crate::{
-    establish_unpooled_connection,
     source::{
       community::{Community, CommunityForm},
       person::*,
       post::*,
     },
     traits::{Crud, Likeable, Readable, Saveable},
+    utils::establish_unpooled_connection,
   };
   use serial_test::serial;
 
index d049fbced7abf890a5b292ed266f90d4267b82e2..58e2f44b0adb26f1ec07b962ce4c831702f1d357 100644 (file)
@@ -1,8 +1,8 @@
 use crate::{
-  naive_now,
   newtypes::{PersonId, PostReportId},
   source::post_report::*,
   traits::Reportable,
+  utils::naive_now,
 };
 use diesel::{dsl::*, result::Error, *};
 
index 6a2e9ee8496ff9608c00d86cf6fad405271bbd23..e90ae5248567099cf4be4772a4bd9a6319ddfe4a 100644 (file)
@@ -1,8 +1,8 @@
 use crate::{
-  naive_now,
   newtypes::{DbUrl, PersonId, PrivateMessageId},
   source::private_message::*,
   traits::{Crud, DeleteableOrRemoveable},
+  utils::naive_now,
 };
 use diesel::{dsl::*, result::Error, *};
 use lemmy_utils::LemmyError;
@@ -138,9 +138,9 @@ impl DeleteableOrRemoveable for PrivateMessage {
 #[cfg(test)]
 mod tests {
   use crate::{
-    establish_unpooled_connection,
     source::{person::*, private_message::*},
     traits::Crud,
+    utils::establish_unpooled_connection,
   };
   use serial_test::serial;
 
index 60d2c013c2059fe8c3b4b21d2fadf0fbfaa386da..6c71f076ed1ab6665dc66c6c01f39901081f9da8 100644 (file)
@@ -1,4 +1,4 @@
-use crate::{source::site::*, traits::Crud, DbUrl};
+use crate::{newtypes::DbUrl, source::site::*, traits::Crud};
 use diesel::{dsl::*, result::Error, *};
 use url::Url;
 
index bd6e0d1906cf07551de105cdad5c6eb48d311925..e6dee1993fbd111fb375adbbc4db3b4f876f2f88 100644 (file)
+#[cfg(feature = "full")]
+#[macro_use]
+extern crate strum_macros;
+#[cfg(feature = "full")]
 #[macro_use]
 extern crate diesel;
+#[cfg(feature = "full")]
 #[macro_use]
 extern crate diesel_derive_newtype;
 // this is used in tests
+#[cfg(feature = "full")]
 #[allow(unused_imports)]
 #[macro_use]
 extern crate diesel_migrations;
-#[macro_use]
-extern crate strum_macros;
 
 pub mod aggregates;
+#[cfg(feature = "full")]
 pub mod impls;
 pub mod newtypes;
+#[cfg(feature = "full")]
 pub mod schema;
 pub mod source;
+#[cfg(feature = "full")]
 pub mod traits;
-
-pub type DbPool = diesel::r2d2::Pool<diesel::r2d2::ConnectionManager<diesel::PgConnection>>;
-
-use crate::newtypes::DbUrl;
-use chrono::NaiveDateTime;
-use diesel::{Connection, PgConnection};
-use lemmy_utils::LemmyError;
-use once_cell::sync::Lazy;
-use regex::Regex;
-use serde::{Deserialize, Serialize};
-use std::{env, env::VarError};
-use url::Url;
-
-pub fn get_database_url_from_env() -> Result<String, VarError> {
-  env::var("LEMMY_DATABASE_URL")
-}
-
-#[derive(EnumString, Display, Debug, Serialize, Deserialize, Clone, Copy)]
-pub enum SortType {
-  Active,
-  Hot,
-  New,
-  TopDay,
-  TopWeek,
-  TopMonth,
-  TopYear,
-  TopAll,
-  MostComments,
-  NewComments,
-}
-
-#[derive(EnumString, Display, Debug, Serialize, Deserialize, Clone, Copy, PartialEq)]
-pub enum ListingType {
-  All,
-  Local,
-  Subscribed,
-  Community,
-}
-
-#[derive(EnumString, Display, Debug, Serialize, Deserialize, Clone, Copy)]
-pub enum SearchType {
-  All,
-  Comments,
-  Posts,
-  Communities,
-  Users,
-  Url,
-}
-
-pub fn from_opt_str_to_opt_enum<T: std::str::FromStr>(opt: &Option<String>) -> Option<T> {
-  opt.as_ref().and_then(|t| T::from_str(t).ok())
-}
-
-pub fn fuzzy_search(q: &str) -> String {
-  let replaced = q.replace('%', "\\%").replace('_', "\\_").replace(' ', "%");
-  format!("%{}%", replaced)
-}
-
-pub fn limit_and_offset(page: Option<i64>, limit: Option<i64>) -> (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<String>) -> Option<Option<String>> {
-  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<String>,
-) -> Result<Option<Option<DbUrl>>, LemmyError> {
-  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(LemmyError::from_error_message(e, "invalid_url")),
-    },
-    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
-}
-
-pub fn naive_now() -> NaiveDateTime {
-  chrono::prelude::Utc::now().naive_utc()
-}
-
-static EMAIL_REGEX: Lazy<Regex> = Lazy::new(|| {
-  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;
-  }
-
-  sql_function!(fn lower(x: Text) -> Text);
-}
-
-#[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()
-    ));
-  }
-}
+#[cfg(feature = "full")]
+pub mod utils;
index 3e68768bcb9b02a0628c1b88007ebc48d280b7f3..946007a3f47d644dd459369d66bf7d93a91b7ca6 100644 (file)
@@ -1,22 +1,13 @@
-use diesel::{
-  backend::Backend,
-  deserialize::FromSql,
-  serialize::{Output, ToSql},
-  sql_types::Text,
-};
-use lemmy_apub_lib::{object_id::ObjectId, traits::ApubObject};
 use serde::{Deserialize, Serialize};
 use std::{
   fmt,
   fmt::{Display, Formatter},
-  io::Write,
   ops::Deref,
 };
 use url::Url;
 
-#[derive(
-  Debug, Copy, Clone, Hash, Eq, PartialEq, Default, Serialize, Deserialize, DieselNewType,
-)]
+#[derive(Debug, Copy, Clone, Hash, Eq, PartialEq, Default, Serialize, Deserialize)]
+#[cfg_attr(feature = "full", derive(DieselNewType))]
 pub struct PostId(pub i32);
 
 impl fmt::Display for PostId {
@@ -25,12 +16,12 @@ impl fmt::Display for PostId {
   }
 }
 
-#[derive(
-  Debug, Copy, Clone, Hash, Eq, PartialEq, Default, Serialize, Deserialize, DieselNewType,
-)]
+#[derive(Debug, Copy, Clone, Hash, Eq, PartialEq, Default, Serialize, Deserialize)]
+#[cfg_attr(feature = "full", derive(DieselNewType))]
 pub struct PersonId(pub i32);
 
-#[derive(Debug, Copy, Clone, Hash, Eq, PartialEq, Serialize, Deserialize, DieselNewType)]
+#[derive(Debug, Copy, Clone, Hash, Eq, PartialEq, Serialize, Deserialize)]
+#[cfg_attr(feature = "full", derive(DieselNewType))]
 pub struct CommentId(pub i32);
 
 impl fmt::Display for CommentId {
@@ -39,17 +30,16 @@ impl fmt::Display for CommentId {
   }
 }
 
-#[derive(
-  Debug, Copy, Clone, Hash, Eq, PartialEq, Default, Serialize, Deserialize, DieselNewType,
-)]
+#[derive(Debug, Copy, Clone, Hash, Eq, PartialEq, Default, Serialize, Deserialize)]
+#[cfg_attr(feature = "full", derive(DieselNewType))]
 pub struct CommunityId(pub i32);
 
-#[derive(
-  Debug, Copy, Clone, Hash, Eq, PartialEq, Default, Serialize, Deserialize, DieselNewType,
-)]
+#[derive(Debug, Copy, Clone, Hash, Eq, PartialEq, Default, Serialize, Deserialize)]
+#[cfg_attr(feature = "full", derive(DieselNewType))]
 pub struct LocalUserId(pub i32);
 
-#[derive(Debug, Copy, Clone, Hash, Eq, PartialEq, Serialize, Deserialize, DieselNewType)]
+#[derive(Debug, Copy, Clone, Hash, Eq, PartialEq, Serialize, Deserialize)]
+#[cfg_attr(feature = "full", derive(DieselNewType))]
 pub struct PrivateMessageId(i32);
 
 impl fmt::Display for PrivateMessageId {
@@ -58,44 +48,31 @@ impl fmt::Display for PrivateMessageId {
   }
 }
 
-#[derive(Debug, Copy, Clone, Hash, Eq, PartialEq, Serialize, Deserialize, DieselNewType)]
+#[derive(Debug, Copy, Clone, Hash, Eq, PartialEq, Serialize, Deserialize)]
+#[cfg_attr(feature = "full", derive(DieselNewType))]
 pub struct PersonMentionId(i32);
 
-#[derive(Debug, Copy, Clone, Hash, Eq, PartialEq, Serialize, Deserialize, DieselNewType)]
+#[derive(Debug, Copy, Clone, Hash, Eq, PartialEq, Serialize, Deserialize)]
+#[cfg_attr(feature = "full", derive(DieselNewType))]
 pub struct PersonBlockId(i32);
 
-#[derive(Debug, Copy, Clone, Hash, Eq, PartialEq, Serialize, Deserialize, DieselNewType)]
+#[derive(Debug, Copy, Clone, Hash, Eq, PartialEq, Serialize, Deserialize)]
+#[cfg_attr(feature = "full", derive(DieselNewType))]
 pub struct CommunityBlockId(i32);
 
-#[derive(Debug, Copy, Clone, Hash, Eq, PartialEq, Serialize, Deserialize, DieselNewType)]
+#[derive(Debug, Copy, Clone, Hash, Eq, PartialEq, Serialize, Deserialize)]
+#[cfg_attr(feature = "full", derive(DieselNewType))]
 pub struct CommentReportId(i32);
 
-#[derive(Debug, Copy, Clone, Hash, Eq, PartialEq, Serialize, Deserialize, DieselNewType)]
+#[derive(Debug, Copy, Clone, Hash, Eq, PartialEq, Serialize, Deserialize)]
+#[cfg_attr(feature = "full", derive(DieselNewType))]
 pub struct PostReportId(i32);
 
 #[repr(transparent)]
-#[derive(Clone, PartialEq, Serialize, Deserialize, Debug, AsExpression, FromSqlRow)]
-#[sql_type = "Text"]
-pub struct DbUrl(Url);
-
-impl<DB: Backend> ToSql<Text, DB> for DbUrl
-where
-  String: ToSql<Text, DB>,
-{
-  fn to_sql<W: Write>(&self, out: &mut Output<W, DB>) -> diesel::serialize::Result {
-    self.0.to_string().to_sql(out)
-  }
-}
-
-impl<DB: Backend> FromSql<Text, DB> for DbUrl
-where
-  String: FromSql<Text, DB>,
-{
-  fn from_sql(bytes: Option<&DB::RawValue>) -> diesel::deserialize::Result<Self> {
-    let str = String::from_sql(bytes)?;
-    Ok(DbUrl(Url::parse(&str)?))
-  }
-}
+#[derive(Clone, PartialEq, Serialize, Deserialize, Debug)]
+#[cfg_attr(feature = "full", derive(AsExpression, FromSqlRow))]
+#[cfg_attr(feature = "full", sql_type = "diesel::sql_types::Text")]
+pub struct DbUrl(pub(crate) Url);
 
 impl Display for DbUrl {
   fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
@@ -117,16 +94,6 @@ impl Into<Url> for DbUrl {
   }
 }
 
-impl<Kind> From<ObjectId<Kind>> for DbUrl
-where
-  Kind: ApubObject + Send + 'static,
-  for<'de2> <Kind as ApubObject>::ApubType: serde::Deserialize<'de2>,
-{
-  fn from(id: ObjectId<Kind>) -> Self {
-    DbUrl(id.into())
-  }
-}
-
 impl Deref for DbUrl {
   type Target = Url;
 
index 5bdeb1db27b2ffc99ffc251911fe5362a409593e..5d09ebfd5893315a6c3eaa568ac90240d8a1aeba 100644 (file)
@@ -2,7 +2,7 @@ use crate::{newtypes::DbUrl, schema::activity};
 use serde_json::Value;
 use std::fmt::Debug;
 
-#[derive(Queryable, Identifiable, PartialEq, Debug)]
+#[derive(PartialEq, Debug, Queryable, Identifiable)]
 #[table_name = "activity"]
 pub struct Activity {
   pub id: i32,
index 46242fc738ba67b74d07fd339a24e236a0eb2bfe..33fd72c545c0320c00f75ea4a0bb222c75d3eef8 100644 (file)
@@ -1,10 +1,9 @@
-use crate::{
-  newtypes::{CommentId, DbUrl, PersonId, PostId},
-  schema::{comment, comment_alias_1, comment_like, comment_saved},
-  source::post::Post,
-};
+use crate::newtypes::{CommentId, DbUrl, PersonId, PostId};
 use serde::{Deserialize, Serialize};
 
+#[cfg(feature = "full")]
+use crate::schema::{comment, comment_alias_1, comment_like, comment_saved};
+
 // WITH RECURSIVE MyTree AS (
 //     SELECT * FROM comment WHERE parent_id IS NULL
 //     UNION ALL
@@ -12,11 +11,10 @@ use serde::{Deserialize, Serialize};
 // )
 // SELECT * FROM MyTree;
 
-#[derive(
-  Clone, Queryable, Associations, Identifiable, PartialEq, Debug, Serialize, Deserialize,
-)]
-#[belongs_to(Post)]
-#[table_name = "comment"]
+#[derive(Clone, PartialEq, Debug, Serialize, Deserialize)]
+#[cfg_attr(feature = "full", derive(Queryable, Associations, Identifiable))]
+#[cfg_attr(feature = "full", belongs_to(crate::source::post::Post))]
+#[cfg_attr(feature = "full", table_name = "comment")]
 pub struct Comment {
   pub id: CommentId,
   pub creator_id: PersonId,
@@ -32,11 +30,10 @@ pub struct Comment {
   pub local: bool,
 }
 
-#[derive(
-  Clone, Queryable, Associations, Identifiable, PartialEq, Debug, Serialize, Deserialize,
-)]
-#[belongs_to(Post)]
-#[table_name = "comment_alias_1"]
+#[derive(Clone, PartialEq, Debug, Serialize, Deserialize)]
+#[cfg_attr(feature = "full", derive(Queryable, Associations, Identifiable))]
+#[cfg_attr(feature = "full", belongs_to(crate::source::post::Post))]
+#[cfg_attr(feature = "full", table_name = "comment_alias_1")]
 pub struct CommentAlias1 {
   pub id: CommentId,
   pub creator_id: PersonId,
@@ -52,8 +49,9 @@ pub struct CommentAlias1 {
   pub local: bool,
 }
 
-#[derive(Insertable, AsChangeset, Clone, Default)]
-#[table_name = "comment"]
+#[derive(Clone, Default)]
+#[cfg_attr(feature = "full", derive(Insertable, AsChangeset))]
+#[cfg_attr(feature = "full", table_name = "comment")]
 pub struct CommentForm {
   pub creator_id: PersonId,
   pub post_id: PostId,
@@ -68,9 +66,10 @@ pub struct CommentForm {
   pub local: Option<bool>,
 }
 
-#[derive(Identifiable, Queryable, Associations, PartialEq, Debug, Clone)]
-#[belongs_to(Comment)]
-#[table_name = "comment_like"]
+#[derive(PartialEq, Debug, Clone)]
+#[cfg_attr(feature = "full", derive(Identifiable, Queryable, Associations))]
+#[cfg_attr(feature = "full", belongs_to(Comment))]
+#[cfg_attr(feature = "full", table_name = "comment_like")]
 pub struct CommentLike {
   pub id: i32,
   pub person_id: PersonId,
@@ -80,8 +79,9 @@ pub struct CommentLike {
   pub published: chrono::NaiveDateTime,
 }
 
-#[derive(Insertable, AsChangeset, Clone)]
-#[table_name = "comment_like"]
+#[derive(Clone)]
+#[cfg_attr(feature = "full", derive(Insertable, AsChangeset))]
+#[cfg_attr(feature = "full", table_name = "comment_like")]
 pub struct CommentLikeForm {
   pub person_id: PersonId,
   pub comment_id: CommentId,
@@ -89,9 +89,10 @@ pub struct CommentLikeForm {
   pub score: i16,
 }
 
-#[derive(Identifiable, Queryable, Associations, PartialEq, Debug)]
-#[belongs_to(Comment)]
-#[table_name = "comment_saved"]
+#[derive(PartialEq, Debug)]
+#[cfg_attr(feature = "full", derive(Identifiable, Queryable, Associations))]
+#[cfg_attr(feature = "full", belongs_to(Comment))]
+#[cfg_attr(feature = "full", table_name = "comment_saved")]
 pub struct CommentSaved {
   pub id: i32,
   pub comment_id: CommentId,
@@ -99,8 +100,8 @@ pub struct CommentSaved {
   pub published: chrono::NaiveDateTime,
 }
 
-#[derive(Insertable, AsChangeset)]
-#[table_name = "comment_saved"]
+#[cfg_attr(feature = "full", derive(Insertable, AsChangeset))]
+#[cfg_attr(feature = "full", table_name = "comment_saved")]
 pub struct CommentSavedForm {
   pub comment_id: CommentId,
   pub person_id: PersonId,
index 3c265ed09fc1d927538b1d6f4ccc0ab86ba2a166..256895760c89edefdb1370c74e117add1e21e679 100644 (file)
@@ -1,15 +1,13 @@
-use crate::{
-  newtypes::{CommentId, CommentReportId, PersonId},
-  schema::comment_report,
-  source::comment::Comment,
-};
+use crate::newtypes::{CommentId, CommentReportId, PersonId};
 use serde::{Deserialize, Serialize};
 
-#[derive(
-  Identifiable, Queryable, Associations, PartialEq, Serialize, Deserialize, Debug, Clone,
-)]
-#[belongs_to(Comment)]
-#[table_name = "comment_report"]
+#[cfg(feature = "full")]
+use crate::schema::comment_report;
+
+#[derive(PartialEq, Serialize, Deserialize, Debug, Clone)]
+#[cfg_attr(feature = "full", derive(Queryable, Associations, Identifiable))]
+#[cfg_attr(feature = "full", belongs_to(crate::source::comment::Comment))]
+#[cfg_attr(feature = "full", table_name = "comment_report")]
 pub struct CommentReport {
   pub id: CommentReportId,
   pub creator_id: PersonId,
@@ -22,8 +20,9 @@ pub struct CommentReport {
   pub updated: Option<chrono::NaiveDateTime>,
 }
 
-#[derive(Insertable, AsChangeset, Clone)]
-#[table_name = "comment_report"]
+#[derive(Clone)]
+#[cfg_attr(feature = "full", derive(Insertable, AsChangeset))]
+#[cfg_attr(feature = "full", table_name = "comment_report")]
 pub struct CommentReportForm {
   pub creator_id: PersonId,
   pub comment_id: CommentId,
index 3e8bbf17122c19e7b0aee6959e71d1ab74a03fe8..7693f2f419c8d88ac335930632873e333d32bed2 100644 (file)
@@ -1,11 +1,12 @@
-use crate::{
-  newtypes::{CommunityId, DbUrl, PersonId},
-  schema::{community, community_follower, community_moderator, community_person_ban},
-};
+use crate::newtypes::{CommunityId, DbUrl, PersonId};
 use serde::{Deserialize, Serialize};
 
-#[derive(Clone, Queryable, Identifiable, PartialEq, Debug, Serialize, Deserialize)]
-#[table_name = "community"]
+#[cfg(feature = "full")]
+use crate::schema::{community, community_follower, community_moderator, community_person_ban};
+
+#[derive(Clone, PartialEq, Debug, Serialize, Deserialize)]
+#[cfg_attr(feature = "full", derive(Queryable, Identifiable))]
+#[cfg_attr(feature = "full", table_name = "community")]
 pub struct Community {
   pub id: CommunityId,
   pub name: String,
@@ -31,8 +32,9 @@ pub struct Community {
 }
 
 /// A safe representation of community, without the sensitive info
-#[derive(Clone, Queryable, Identifiable, PartialEq, Debug, Serialize, Deserialize)]
-#[table_name = "community"]
+#[derive(Clone, PartialEq, Debug, Serialize, Deserialize)]
+#[cfg_attr(feature = "full", derive(Queryable, Identifiable))]
+#[cfg_attr(feature = "full", table_name = "community")]
 pub struct CommunitySafe {
   pub id: CommunityId,
   pub name: String,
@@ -51,8 +53,9 @@ pub struct CommunitySafe {
   pub posting_restricted_to_mods: bool,
 }
 
-#[derive(Insertable, AsChangeset, Debug, Default)]
-#[table_name = "community"]
+#[derive(Debug, Default)]
+#[cfg_attr(feature = "full", derive(Insertable, AsChangeset))]
+#[cfg_attr(feature = "full", table_name = "community")]
 pub struct CommunityForm {
   pub name: String,
   pub title: String,
@@ -76,9 +79,10 @@ pub struct CommunityForm {
   pub posting_restricted_to_mods: Option<bool>,
 }
 
-#[derive(Identifiable, Queryable, Associations, PartialEq, Debug)]
-#[belongs_to(Community)]
-#[table_name = "community_moderator"]
+#[derive(PartialEq, Debug)]
+#[cfg_attr(feature = "full", derive(Identifiable, Queryable, Associations))]
+#[cfg_attr(feature = "full", belongs_to(Community))]
+#[cfg_attr(feature = "full", table_name = "community_moderator")]
 pub struct CommunityModerator {
   pub id: i32,
   pub community_id: CommunityId,
@@ -86,16 +90,18 @@ pub struct CommunityModerator {
   pub published: chrono::NaiveDateTime,
 }
 
-#[derive(Insertable, AsChangeset, Clone)]
-#[table_name = "community_moderator"]
+#[derive(Clone)]
+#[cfg_attr(feature = "full", derive(Insertable, AsChangeset))]
+#[cfg_attr(feature = "full", table_name = "community_moderator")]
 pub struct CommunityModeratorForm {
   pub community_id: CommunityId,
   pub person_id: PersonId,
 }
 
-#[derive(Identifiable, Queryable, Associations, PartialEq, Debug)]
-#[belongs_to(Community)]
-#[table_name = "community_person_ban"]
+#[derive(PartialEq, Debug)]
+#[cfg_attr(feature = "full", derive(Identifiable, Queryable, Associations))]
+#[cfg_attr(feature = "full", belongs_to(Community))]
+#[cfg_attr(feature = "full", table_name = "community_person_ban")]
 pub struct CommunityPersonBan {
   pub id: i32,
   pub community_id: CommunityId,
@@ -104,17 +110,19 @@ pub struct CommunityPersonBan {
   pub expires: Option<chrono::NaiveDateTime>,
 }
 
-#[derive(Insertable, AsChangeset, Clone)]
-#[table_name = "community_person_ban"]
+#[derive(Clone)]
+#[cfg_attr(feature = "full", derive(Insertable, AsChangeset))]
+#[cfg_attr(feature = "full", table_name = "community_person_ban")]
 pub struct CommunityPersonBanForm {
   pub community_id: CommunityId,
   pub person_id: PersonId,
   pub expires: Option<Option<chrono::NaiveDateTime>>,
 }
 
-#[derive(Identifiable, Queryable, Associations, PartialEq, Debug)]
-#[belongs_to(Community)]
-#[table_name = "community_follower"]
+#[derive(PartialEq, Debug)]
+#[cfg_attr(feature = "full", derive(Identifiable, Queryable, Associations))]
+#[cfg_attr(feature = "full", belongs_to(Community))]
+#[cfg_attr(feature = "full", table_name = "community_follower")]
 pub struct CommunityFollower {
   pub id: i32,
   pub community_id: CommunityId,
@@ -123,8 +131,9 @@ pub struct CommunityFollower {
   pub pending: Option<bool>,
 }
 
-#[derive(Insertable, AsChangeset, Clone)]
-#[table_name = "community_follower"]
+#[derive(Clone)]
+#[cfg_attr(feature = "full", derive(Insertable, AsChangeset))]
+#[cfg_attr(feature = "full", table_name = "community_follower")]
 pub struct CommunityFollowerForm {
   pub community_id: CommunityId,
   pub person_id: PersonId,
index f5cc545e83988874caa3e8f5262320d74e5c7b15..d2c40a3369001dc38771b1b54f30962eb62567de 100644 (file)
@@ -1,15 +1,13 @@
-use crate::{
-  newtypes::{CommunityBlockId, CommunityId, PersonId},
-  schema::community_block,
-  source::community::Community,
-};
+use crate::newtypes::{CommunityBlockId, CommunityId, PersonId};
 use serde::{Deserialize, Serialize};
 
-#[derive(
-  Clone, Queryable, Associations, Identifiable, PartialEq, Debug, Serialize, Deserialize,
-)]
-#[table_name = "community_block"]
-#[belongs_to(Community)]
+#[cfg(feature = "full")]
+use crate::schema::community_block;
+
+#[derive(Clone, PartialEq, Debug, Serialize, Deserialize)]
+#[cfg_attr(feature = "full", derive(Queryable, Associations, Identifiable))]
+#[cfg_attr(feature = "full", belongs_to(crate::source::community::Community))]
+#[cfg_attr(feature = "full", table_name = "community_block")]
 pub struct CommunityBlock {
   pub id: CommunityBlockId,
   pub person_id: PersonId,
@@ -17,8 +15,8 @@ pub struct CommunityBlock {
   pub published: chrono::NaiveDateTime,
 }
 
-#[derive(Insertable, AsChangeset)]
-#[table_name = "community_block"]
+#[cfg_attr(feature = "full", derive(Insertable, AsChangeset))]
+#[cfg_attr(feature = "full", table_name = "community_block")]
 pub struct CommunityBlockForm {
   pub person_id: PersonId,
   pub community_id: CommunityId,
index e36f29012ab73b2e3f153d67a3a49270e781de78..8d63670f2dc8354a869da39d4e901423bb3004b2 100644 (file)
@@ -1,7 +1,11 @@
-use crate::{newtypes::LocalUserId, schema::email_verification};
+use crate::newtypes::LocalUserId;
 
-#[derive(Queryable, Identifiable, Clone)]
-#[table_name = "email_verification"]
+#[cfg(feature = "full")]
+use crate::schema::email_verification;
+
+#[derive(Clone)]
+#[cfg_attr(feature = "full", derive(Queryable, Identifiable))]
+#[cfg_attr(feature = "full", table_name = "email_verification")]
 pub struct EmailVerification {
   pub id: i32,
   pub local_user_id: LocalUserId,
@@ -10,8 +14,8 @@ pub struct EmailVerification {
   pub published: chrono::NaiveDateTime,
 }
 
-#[derive(Insertable, AsChangeset)]
-#[table_name = "email_verification"]
+#[cfg_attr(feature = "full", derive(Insertable, AsChangeset))]
+#[cfg_attr(feature = "full", table_name = "email_verification")]
 pub struct EmailVerificationForm {
   pub local_user_id: LocalUserId,
   pub email: String,
index 88defa6db856b2229685c171db9af9d859492815..57767bb179700fc49156f78950c57b659d671699 100644 (file)
@@ -1,11 +1,12 @@
-use crate::{
-  newtypes::{LocalUserId, PersonId},
-  schema::local_user,
-};
+use crate::newtypes::{LocalUserId, PersonId};
 use serde::{Deserialize, Serialize};
 
-#[derive(Clone, Queryable, Identifiable, PartialEq, Debug, Serialize, Deserialize)]
-#[table_name = "local_user"]
+#[cfg(feature = "full")]
+use crate::schema::local_user;
+
+#[derive(Clone, PartialEq, Debug, Serialize, Deserialize)]
+#[cfg_attr(feature = "full", derive(Queryable, Identifiable))]
+#[cfg_attr(feature = "full", table_name = "local_user")]
 pub struct LocalUser {
   pub id: LocalUserId,
   pub person_id: PersonId,
@@ -28,8 +29,9 @@ pub struct LocalUser {
 }
 
 // TODO redo these, check table defaults
-#[derive(Insertable, AsChangeset, Clone, Default)]
-#[table_name = "local_user"]
+#[derive(Clone, Default)]
+#[cfg_attr(feature = "full", derive(Insertable, AsChangeset))]
+#[cfg_attr(feature = "full", table_name = "local_user")]
 pub struct LocalUserForm {
   pub person_id: Option<PersonId>,
   pub password_encrypted: Option<String>,
@@ -50,8 +52,9 @@ pub struct LocalUserForm {
 }
 
 /// A local user view that removes password encrypted
-#[derive(Clone, Queryable, Identifiable, PartialEq, Debug, Serialize, Deserialize)]
-#[table_name = "local_user"]
+#[derive(Clone, PartialEq, Debug, Serialize, Deserialize)]
+#[cfg_attr(feature = "full", derive(Queryable, Identifiable))]
+#[cfg_attr(feature = "full", table_name = "local_user")]
 pub struct LocalUserSettings {
   pub id: LocalUserId,
   pub person_id: PersonId,
index c96e3a6231fc1280273e26c1ec33031a1703ec64..f2ff5f78e7efad1324e489d5d408f812f1cf1be3 100644 (file)
@@ -1,3 +1,4 @@
+#[cfg(feature = "full")]
 pub mod activity;
 pub mod comment;
 pub mod comment_report;
index 84121f9a457e64e8aea430a9fa1e55f6dc18ce21..b617564b357bf02bda9e2203518bc767fc364d03 100644 (file)
@@ -1,23 +1,24 @@
-use crate::{
-  newtypes::{CommentId, CommunityId, PersonId, PostId},
-  schema::{
-    mod_add,
-    mod_add_community,
-    mod_ban,
-    mod_ban_from_community,
-    mod_hide_community,
-    mod_lock_post,
-    mod_remove_comment,
-    mod_remove_community,
-    mod_remove_post,
-    mod_sticky_post,
-    mod_transfer_community,
-  },
-};
+use crate::newtypes::{CommentId, CommunityId, PersonId, PostId};
 use serde::{Deserialize, Serialize};
 
-#[derive(Clone, Queryable, Identifiable, PartialEq, Debug, Serialize, Deserialize)]
-#[table_name = "mod_remove_post"]
+#[cfg(feature = "full")]
+use crate::schema::{
+  mod_add,
+  mod_add_community,
+  mod_ban,
+  mod_ban_from_community,
+  mod_hide_community,
+  mod_lock_post,
+  mod_remove_comment,
+  mod_remove_community,
+  mod_remove_post,
+  mod_sticky_post,
+  mod_transfer_community,
+};
+
+#[derive(Clone, PartialEq, Debug, Serialize, Deserialize)]
+#[cfg_attr(feature = "full", derive(Queryable, Identifiable))]
+#[cfg_attr(feature = "full", table_name = "mod_remove_post")]
 pub struct ModRemovePost {
   pub id: i32,
   pub mod_person_id: PersonId,
@@ -27,8 +28,8 @@ pub struct ModRemovePost {
   pub when_: chrono::NaiveDateTime,
 }
 
-#[derive(Insertable, AsChangeset)]
-#[table_name = "mod_remove_post"]
+#[cfg_attr(feature = "full", derive(Insertable, AsChangeset))]
+#[cfg_attr(feature = "full", table_name = "mod_remove_post")]
 pub struct ModRemovePostForm {
   pub mod_person_id: PersonId,
   pub post_id: PostId,
@@ -36,8 +37,9 @@ pub struct ModRemovePostForm {
   pub removed: Option<bool>,
 }
 
-#[derive(Clone, Queryable, Identifiable, PartialEq, Debug, Serialize, Deserialize)]
-#[table_name = "mod_lock_post"]
+#[derive(Clone, PartialEq, Debug, Serialize, Deserialize)]
+#[cfg_attr(feature = "full", derive(Queryable, Identifiable))]
+#[cfg_attr(feature = "full", table_name = "mod_lock_post")]
 pub struct ModLockPost {
   pub id: i32,
   pub mod_person_id: PersonId,
@@ -46,16 +48,17 @@ pub struct ModLockPost {
   pub when_: chrono::NaiveDateTime,
 }
 
-#[derive(Insertable, AsChangeset)]
-#[table_name = "mod_lock_post"]
+#[cfg_attr(feature = "full", derive(Insertable, AsChangeset))]
+#[cfg_attr(feature = "full", table_name = "mod_lock_post")]
 pub struct ModLockPostForm {
   pub mod_person_id: PersonId,
   pub post_id: PostId,
   pub locked: Option<bool>,
 }
 
-#[derive(Clone, Queryable, Identifiable, PartialEq, Debug, Serialize, Deserialize)]
-#[table_name = "mod_sticky_post"]
+#[derive(Clone, PartialEq, Debug, Serialize, Deserialize)]
+#[cfg_attr(feature = "full", derive(Queryable, Identifiable))]
+#[cfg_attr(feature = "full", table_name = "mod_sticky_post")]
 pub struct ModStickyPost {
   pub id: i32,
   pub mod_person_id: PersonId,
@@ -64,16 +67,17 @@ pub struct ModStickyPost {
   pub when_: chrono::NaiveDateTime,
 }
 
-#[derive(Insertable, AsChangeset)]
-#[table_name = "mod_sticky_post"]
+#[cfg_attr(feature = "full", derive(Insertable, AsChangeset))]
+#[cfg_attr(feature = "full", table_name = "mod_sticky_post")]
 pub struct ModStickyPostForm {
   pub mod_person_id: PersonId,
   pub post_id: PostId,
   pub stickied: Option<bool>,
 }
 
-#[derive(Clone, Queryable, Identifiable, PartialEq, Debug, Serialize, Deserialize)]
-#[table_name = "mod_remove_comment"]
+#[derive(Clone, PartialEq, Debug, Serialize, Deserialize)]
+#[cfg_attr(feature = "full", derive(Queryable, Identifiable))]
+#[cfg_attr(feature = "full", table_name = "mod_remove_comment")]
 pub struct ModRemoveComment {
   pub id: i32,
   pub mod_person_id: PersonId,
@@ -83,8 +87,8 @@ pub struct ModRemoveComment {
   pub when_: chrono::NaiveDateTime,
 }
 
-#[derive(Insertable, AsChangeset)]
-#[table_name = "mod_remove_comment"]
+#[cfg_attr(feature = "full", derive(Insertable, AsChangeset))]
+#[cfg_attr(feature = "full", table_name = "mod_remove_comment")]
 pub struct ModRemoveCommentForm {
   pub mod_person_id: PersonId,
   pub comment_id: CommentId,
@@ -92,8 +96,9 @@ pub struct ModRemoveCommentForm {
   pub removed: Option<bool>,
 }
 
-#[derive(Clone, Queryable, Identifiable, PartialEq, Debug, Serialize, Deserialize)]
-#[table_name = "mod_remove_community"]
+#[derive(Clone, PartialEq, Debug, Serialize, Deserialize)]
+#[cfg_attr(feature = "full", derive(Queryable, Identifiable))]
+#[cfg_attr(feature = "full", table_name = "mod_remove_community")]
 pub struct ModRemoveCommunity {
   pub id: i32,
   pub mod_person_id: PersonId,
@@ -104,8 +109,8 @@ pub struct ModRemoveCommunity {
   pub when_: chrono::NaiveDateTime,
 }
 
-#[derive(Insertable, AsChangeset)]
-#[table_name = "mod_remove_community"]
+#[cfg_attr(feature = "full", derive(Insertable, AsChangeset))]
+#[cfg_attr(feature = "full", table_name = "mod_remove_community")]
 pub struct ModRemoveCommunityForm {
   pub mod_person_id: PersonId,
   pub community_id: CommunityId,
@@ -114,8 +119,9 @@ pub struct ModRemoveCommunityForm {
   pub expires: Option<chrono::NaiveDateTime>,
 }
 
-#[derive(Clone, Queryable, Identifiable, PartialEq, Debug, Serialize, Deserialize)]
-#[table_name = "mod_ban_from_community"]
+#[derive(Clone, PartialEq, Debug, Serialize, Deserialize)]
+#[cfg_attr(feature = "full", derive(Queryable, Identifiable))]
+#[cfg_attr(feature = "full", table_name = "mod_ban_from_community")]
 pub struct ModBanFromCommunity {
   pub id: i32,
   pub mod_person_id: PersonId,
@@ -127,8 +133,8 @@ pub struct ModBanFromCommunity {
   pub when_: chrono::NaiveDateTime,
 }
 
-#[derive(Insertable, AsChangeset)]
-#[table_name = "mod_ban_from_community"]
+#[cfg_attr(feature = "full", derive(Insertable, AsChangeset))]
+#[cfg_attr(feature = "full", table_name = "mod_ban_from_community")]
 pub struct ModBanFromCommunityForm {
   pub mod_person_id: PersonId,
   pub other_person_id: PersonId,
@@ -138,8 +144,9 @@ pub struct ModBanFromCommunityForm {
   pub expires: Option<chrono::NaiveDateTime>,
 }
 
-#[derive(Clone, Queryable, Identifiable, PartialEq, Debug, Serialize, Deserialize)]
-#[table_name = "mod_ban"]
+#[derive(Clone, PartialEq, Debug, Serialize, Deserialize)]
+#[cfg_attr(feature = "full", derive(Queryable, Identifiable))]
+#[cfg_attr(feature = "full", table_name = "mod_ban")]
 pub struct ModBan {
   pub id: i32,
   pub mod_person_id: PersonId,
@@ -150,16 +157,17 @@ pub struct ModBan {
   pub when_: chrono::NaiveDateTime,
 }
 
-#[derive(Insertable, AsChangeset)]
-#[table_name = "mod_hide_community"]
+#[cfg_attr(feature = "full", derive(Insertable, AsChangeset))]
+#[cfg_attr(feature = "full", table_name = "mod_hide_community")]
 pub struct ModHideCommunityForm {
   pub community_id: CommunityId,
   pub mod_person_id: PersonId,
   pub hidden: Option<bool>,
   pub reason: Option<String>,
 }
-#[derive(Clone, Queryable, Identifiable, PartialEq, Debug, Serialize, Deserialize)]
-#[table_name = "mod_hide_community"]
+#[derive(Clone, PartialEq, Debug, Serialize, Deserialize)]
+#[cfg_attr(feature = "full", derive(Queryable, Identifiable))]
+#[cfg_attr(feature = "full", table_name = "mod_hide_community")]
 pub struct ModHideCommunity {
   pub id: i32,
   pub community_id: CommunityId,
@@ -169,8 +177,8 @@ pub struct ModHideCommunity {
   pub when_: chrono::NaiveDateTime,
 }
 
-#[derive(Insertable, AsChangeset)]
-#[table_name = "mod_ban"]
+#[cfg_attr(feature = "full", derive(Insertable, AsChangeset))]
+#[cfg_attr(feature = "full", table_name = "mod_ban")]
 pub struct ModBanForm {
   pub mod_person_id: PersonId,
   pub other_person_id: PersonId,
@@ -179,8 +187,9 @@ pub struct ModBanForm {
   pub expires: Option<chrono::NaiveDateTime>,
 }
 
-#[derive(Clone, Queryable, Identifiable, PartialEq, Debug, Serialize, Deserialize)]
-#[table_name = "mod_add_community"]
+#[derive(Clone, PartialEq, Debug, Serialize, Deserialize)]
+#[cfg_attr(feature = "full", derive(Queryable, Identifiable))]
+#[cfg_attr(feature = "full", table_name = "mod_add_community")]
 pub struct ModAddCommunity {
   pub id: i32,
   pub mod_person_id: PersonId,
@@ -190,8 +199,8 @@ pub struct ModAddCommunity {
   pub when_: chrono::NaiveDateTime,
 }
 
-#[derive(Insertable, AsChangeset)]
-#[table_name = "mod_add_community"]
+#[cfg_attr(feature = "full", derive(Insertable, AsChangeset))]
+#[cfg_attr(feature = "full", table_name = "mod_add_community")]
 pub struct ModAddCommunityForm {
   pub mod_person_id: PersonId,
   pub other_person_id: PersonId,
@@ -199,8 +208,9 @@ pub struct ModAddCommunityForm {
   pub removed: Option<bool>,
 }
 
-#[derive(Clone, Queryable, Identifiable, PartialEq, Debug, Serialize, Deserialize)]
-#[table_name = "mod_transfer_community"]
+#[derive(Clone, PartialEq, Debug, Serialize, Deserialize)]
+#[cfg_attr(feature = "full", derive(Queryable, Identifiable))]
+#[cfg_attr(feature = "full", table_name = "mod_transfer_community")]
 pub struct ModTransferCommunity {
   pub id: i32,
   pub mod_person_id: PersonId,
@@ -210,8 +220,8 @@ pub struct ModTransferCommunity {
   pub when_: chrono::NaiveDateTime,
 }
 
-#[derive(Insertable, AsChangeset)]
-#[table_name = "mod_transfer_community"]
+#[cfg_attr(feature = "full", derive(Insertable, AsChangeset))]
+#[cfg_attr(feature = "full", table_name = "mod_transfer_community")]
 pub struct ModTransferCommunityForm {
   pub mod_person_id: PersonId,
   pub other_person_id: PersonId,
@@ -219,8 +229,9 @@ pub struct ModTransferCommunityForm {
   pub removed: Option<bool>,
 }
 
-#[derive(Clone, Queryable, Identifiable, PartialEq, Debug, Serialize, Deserialize)]
-#[table_name = "mod_add"]
+#[derive(Clone, PartialEq, Debug, Serialize, Deserialize)]
+#[cfg_attr(feature = "full", derive(Queryable, Identifiable))]
+#[cfg_attr(feature = "full", table_name = "mod_add")]
 pub struct ModAdd {
   pub id: i32,
   pub mod_person_id: PersonId,
@@ -229,8 +240,8 @@ pub struct ModAdd {
   pub when_: chrono::NaiveDateTime,
 }
 
-#[derive(Insertable, AsChangeset)]
-#[table_name = "mod_add"]
+#[cfg_attr(feature = "full", derive(Insertable, AsChangeset))]
+#[cfg_attr(feature = "full", table_name = "mod_add")]
 pub struct ModAddForm {
   pub mod_person_id: PersonId,
   pub other_person_id: PersonId,
index 0d461049f7b1c78424a4f9669024db2c6e273978..3df7fab0fbbd3e5f7c02cc359a2971a4ea8cbfb2 100644 (file)
@@ -1,7 +1,11 @@
-use crate::{newtypes::LocalUserId, schema::password_reset_request};
+use crate::newtypes::LocalUserId;
 
-#[derive(Queryable, Identifiable, PartialEq, Debug)]
-#[table_name = "password_reset_request"]
+#[cfg(feature = "full")]
+use crate::schema::password_reset_request;
+
+#[derive(PartialEq, Debug)]
+#[cfg_attr(feature = "full", derive(Queryable, Identifiable))]
+#[cfg_attr(feature = "full", table_name = "password_reset_request")]
 pub struct PasswordResetRequest {
   pub id: i32,
   pub token_encrypted: String,
@@ -9,8 +13,8 @@ pub struct PasswordResetRequest {
   pub local_user_id: LocalUserId,
 }
 
-#[derive(Insertable, AsChangeset)]
-#[table_name = "password_reset_request"]
+#[cfg_attr(feature = "full", derive(Insertable, AsChangeset))]
+#[cfg_attr(feature = "full", table_name = "password_reset_request")]
 pub struct PasswordResetRequestForm {
   pub local_user_id: LocalUserId,
   pub token_encrypted: String,
index 978298307d5235282aa02af5d9b7bbba8840d7fa..7c301c99881afc392a1871d4067e4caa398bb4b4 100644 (file)
@@ -1,11 +1,12 @@
-use crate::{
-  newtypes::{DbUrl, PersonId},
-  schema::{person, person_alias_1, person_alias_2},
-};
+use crate::newtypes::{DbUrl, PersonId};
 use serde::{Deserialize, Serialize};
 
-#[derive(Clone, Queryable, Identifiable, PartialEq, Debug, Serialize, Deserialize)]
-#[table_name = "person"]
+#[cfg(feature = "full")]
+use crate::schema::{person, person_alias_1, person_alias_2};
+
+#[derive(Clone, PartialEq, Debug, Serialize, Deserialize)]
+#[cfg_attr(feature = "full", derive(Queryable, Identifiable))]
+#[cfg_attr(feature = "full", table_name = "person")]
 pub struct Person {
   pub id: PersonId,
   pub name: String,
@@ -31,8 +32,9 @@ pub struct Person {
 }
 
 /// A safe representation of person, without the sensitive info
-#[derive(Clone, Queryable, Identifiable, PartialEq, Debug, Serialize, Deserialize)]
-#[table_name = "person"]
+#[derive(Clone, PartialEq, Debug, Serialize, Deserialize)]
+#[cfg_attr(feature = "full", derive(Queryable, Identifiable))]
+#[cfg_attr(feature = "full", table_name = "person")]
 pub struct PersonSafe {
   pub id: PersonId,
   pub name: String,
@@ -54,8 +56,9 @@ pub struct PersonSafe {
   pub ban_expires: Option<chrono::NaiveDateTime>,
 }
 
-#[derive(Clone, Queryable, Identifiable, PartialEq, Debug, Serialize, Deserialize)]
-#[table_name = "person_alias_1"]
+#[derive(Clone, PartialEq, Debug, Serialize, Deserialize)]
+#[cfg_attr(feature = "full", derive(Queryable, Identifiable))]
+#[cfg_attr(feature = "full", table_name = "person_alias_1")]
 pub struct PersonAlias1 {
   pub id: PersonId,
   pub name: String,
@@ -80,8 +83,9 @@ pub struct PersonAlias1 {
   pub ban_expires: Option<chrono::NaiveDateTime>,
 }
 
-#[derive(Clone, Queryable, Identifiable, PartialEq, Debug, Serialize, Deserialize)]
-#[table_name = "person_alias_1"]
+#[derive(Clone, PartialEq, Debug, Serialize, Deserialize)]
+#[cfg_attr(feature = "full", derive(Queryable, Identifiable))]
+#[cfg_attr(feature = "full", table_name = "person_alias_1")]
 pub struct PersonSafeAlias1 {
   pub id: PersonId,
   pub name: String,
@@ -103,8 +107,9 @@ pub struct PersonSafeAlias1 {
   pub ban_expires: Option<chrono::NaiveDateTime>,
 }
 
-#[derive(Clone, Queryable, Identifiable, PartialEq, Debug, Serialize, Deserialize)]
-#[table_name = "person_alias_2"]
+#[derive(Clone, PartialEq, Debug, Serialize, Deserialize)]
+#[cfg_attr(feature = "full", derive(Queryable, Identifiable))]
+#[cfg_attr(feature = "full", table_name = "person_alias_2")]
 pub struct PersonAlias2 {
   pub id: PersonId,
   pub name: String,
@@ -129,8 +134,9 @@ pub struct PersonAlias2 {
   pub ban_expires: Option<chrono::NaiveDateTime>,
 }
 
-#[derive(Clone, Queryable, Identifiable, PartialEq, Debug, Serialize, Deserialize)]
-#[table_name = "person_alias_1"]
+#[derive(Clone, PartialEq, Debug, Serialize, Deserialize)]
+#[cfg_attr(feature = "full", derive(Queryable, Identifiable))]
+#[cfg_attr(feature = "full", table_name = "person_alias_1")]
 pub struct PersonSafeAlias2 {
   pub id: PersonId,
   pub name: String,
@@ -152,8 +158,9 @@ pub struct PersonSafeAlias2 {
   pub ban_expires: Option<chrono::NaiveDateTime>,
 }
 
-#[derive(Insertable, AsChangeset, Clone, Default)]
-#[table_name = "person"]
+#[derive(Clone, Default)]
+#[cfg_attr(feature = "full", derive(Insertable, AsChangeset))]
+#[cfg_attr(feature = "full", table_name = "person")]
 pub struct PersonForm {
   pub name: String,
   pub display_name: Option<Option<String>>,
index ff55872f195912f2909286268e4a58322e06ca83..46920acbf77698bbe7ba4dc3ff6d8926362f1625 100644 (file)
@@ -1,13 +1,12 @@
-use crate::{
-  newtypes::{PersonBlockId, PersonId},
-  schema::person_block,
-};
+use crate::newtypes::{PersonBlockId, PersonId};
 use serde::{Deserialize, Serialize};
 
-#[derive(
-  Clone, Queryable, Associations, Identifiable, PartialEq, Debug, Serialize, Deserialize,
-)]
-#[table_name = "person_block"]
+#[cfg(feature = "full")]
+use crate::schema::person_block;
+
+#[derive(Clone, PartialEq, Debug, Serialize, Deserialize)]
+#[cfg_attr(feature = "full", derive(Queryable, Associations, Identifiable))]
+#[cfg_attr(feature = "full", table_name = "person_block")]
 pub struct PersonBlock {
   pub id: PersonBlockId,
   pub person_id: PersonId,
@@ -15,8 +14,8 @@ pub struct PersonBlock {
   pub published: chrono::NaiveDateTime,
 }
 
-#[derive(Insertable, AsChangeset)]
-#[table_name = "person_block"]
+#[cfg_attr(feature = "full", derive(Insertable, AsChangeset))]
+#[cfg_attr(feature = "full", table_name = "person_block")]
 pub struct PersonBlockForm {
   pub person_id: PersonId,
   pub target_id: PersonId,
index 795799c7e2a026102b6896548fd21418f3c2d189..5716cb8c8360585a1084f991b7699f3841f87605 100644 (file)
@@ -1,15 +1,13 @@
-use crate::{
-  newtypes::{CommentId, PersonId, PersonMentionId},
-  schema::person_mention,
-  source::comment::Comment,
-};
+use crate::newtypes::{CommentId, PersonId, PersonMentionId};
 use serde::{Deserialize, Serialize};
 
-#[derive(
-  Clone, Queryable, Associations, Identifiable, PartialEq, Debug, Serialize, Deserialize,
-)]
-#[belongs_to(Comment)]
-#[table_name = "person_mention"]
+#[cfg(feature = "full")]
+use crate::schema::person_mention;
+
+#[derive(Clone, PartialEq, Debug, Serialize, Deserialize)]
+#[cfg_attr(feature = "full", derive(Queryable, Associations, Identifiable))]
+#[cfg_attr(feature = "full", belongs_to(crate::source::comment::Comment))]
+#[cfg_attr(feature = "full", table_name = "person_mention")]
 pub struct PersonMention {
   pub id: PersonMentionId,
   pub recipient_id: PersonId,
@@ -18,8 +16,8 @@ pub struct PersonMention {
   pub published: chrono::NaiveDateTime,
 }
 
-#[derive(Insertable, AsChangeset)]
-#[table_name = "person_mention"]
+#[cfg_attr(feature = "full", derive(Insertable, AsChangeset))]
+#[cfg_attr(feature = "full", table_name = "person_mention")]
 pub struct PersonMentionForm {
   pub recipient_id: PersonId,
   pub comment_id: CommentId,
index cc9325361005c2df336dc5ed04b23101f55e0604..a3054e4080650755181c3387c6469b573976ef50 100644 (file)
@@ -1,10 +1,12 @@
-use crate::{
-  newtypes::{CommunityId, DbUrl, PersonId, PostId},
-  schema::{post, post_like, post_read, post_saved},
-};
+use crate::newtypes::{CommunityId, DbUrl, PersonId, PostId};
 use serde::{Deserialize, Serialize};
-#[derive(Clone, Queryable, Identifiable, PartialEq, Debug, Serialize, Deserialize)]
-#[table_name = "post"]
+
+#[cfg(feature = "full")]
+use crate::schema::{post, post_like, post_read, post_saved};
+
+#[derive(Clone, PartialEq, Debug, Serialize, Deserialize)]
+#[cfg_attr(feature = "full", derive(Queryable, Identifiable))]
+#[cfg_attr(feature = "full", table_name = "post")]
 pub struct Post {
   pub id: PostId,
   pub name: String,
@@ -27,8 +29,9 @@ pub struct Post {
   pub local: bool,
 }
 
-#[derive(Insertable, AsChangeset, Default)]
-#[table_name = "post"]
+#[derive(Default)]
+#[cfg_attr(feature = "full", derive(Insertable, AsChangeset))]
+#[cfg_attr(feature = "full", table_name = "post")]
 pub struct PostForm {
   pub name: String,
   pub creator_id: PersonId,
@@ -50,9 +53,10 @@ pub struct PostForm {
   pub local: Option<bool>,
 }
 
-#[derive(Identifiable, Queryable, Associations, PartialEq, Debug)]
-#[belongs_to(Post)]
-#[table_name = "post_like"]
+#[derive(PartialEq, Debug)]
+#[cfg_attr(feature = "full", derive(Identifiable, Queryable, Associations))]
+#[cfg_attr(feature = "full", belongs_to(Post))]
+#[cfg_attr(feature = "full", table_name = "post_like")]
 pub struct PostLike {
   pub id: i32,
   pub post_id: PostId,
@@ -61,17 +65,19 @@ pub struct PostLike {
   pub published: chrono::NaiveDateTime,
 }
 
-#[derive(Insertable, AsChangeset, Clone)]
-#[table_name = "post_like"]
+#[derive(Clone)]
+#[cfg_attr(feature = "full", derive(Insertable, AsChangeset))]
+#[cfg_attr(feature = "full", table_name = "post_like")]
 pub struct PostLikeForm {
   pub post_id: PostId,
   pub person_id: PersonId,
   pub score: i16,
 }
 
-#[derive(Identifiable, Queryable, Associations, PartialEq, Debug)]
-#[belongs_to(Post)]
-#[table_name = "post_saved"]
+#[derive(PartialEq, Debug)]
+#[cfg_attr(feature = "full", derive(Identifiable, Queryable, Associations))]
+#[cfg_attr(feature = "full", belongs_to(Post))]
+#[cfg_attr(feature = "full", table_name = "post_saved")]
 pub struct PostSaved {
   pub id: i32,
   pub post_id: PostId,
@@ -79,16 +85,17 @@ pub struct PostSaved {
   pub published: chrono::NaiveDateTime,
 }
 
-#[derive(Insertable, AsChangeset)]
-#[table_name = "post_saved"]
+#[cfg_attr(feature = "full", derive(Insertable, AsChangeset))]
+#[cfg_attr(feature = "full", table_name = "post_saved")]
 pub struct PostSavedForm {
   pub post_id: PostId,
   pub person_id: PersonId,
 }
 
-#[derive(Identifiable, Queryable, Associations, PartialEq, Debug)]
-#[belongs_to(Post)]
-#[table_name = "post_read"]
+#[derive(PartialEq, Debug)]
+#[cfg_attr(feature = "full", derive(Identifiable, Queryable, Associations))]
+#[cfg_attr(feature = "full", belongs_to(Post))]
+#[cfg_attr(feature = "full", table_name = "post_read")]
 pub struct PostRead {
   pub id: i32,
   pub post_id: PostId,
@@ -96,8 +103,8 @@ pub struct PostRead {
   pub published: chrono::NaiveDateTime,
 }
 
-#[derive(Insertable, AsChangeset)]
-#[table_name = "post_read"]
+#[cfg_attr(feature = "full", derive(Insertable, AsChangeset))]
+#[cfg_attr(feature = "full", table_name = "post_read")]
 pub struct PostReadForm {
   pub post_id: PostId,
   pub person_id: PersonId,
index 6e711782b88c0c6ad093567328dbd4d50d97e96a..afb3346984894354e5f6c729d9240d39820c6198 100644 (file)
@@ -1,15 +1,13 @@
-use crate::{
-  newtypes::{DbUrl, PersonId, PostId, PostReportId},
-  schema::post_report,
-  source::post::Post,
-};
+use crate::newtypes::{DbUrl, PersonId, PostId, PostReportId};
 use serde::{Deserialize, Serialize};
 
-#[derive(
-  Identifiable, Queryable, Associations, PartialEq, Serialize, Deserialize, Debug, Clone,
-)]
-#[belongs_to(Post)]
-#[table_name = "post_report"]
+#[cfg(feature = "full")]
+use crate::schema::post_report;
+
+#[derive(PartialEq, Serialize, Deserialize, Debug, Clone)]
+#[cfg_attr(feature = "full", derive(Identifiable, Queryable, Associations))]
+#[cfg_attr(feature = "full", belongs_to(crate::source::post::Post))]
+#[cfg_attr(feature = "full", table_name = "post_report")]
 pub struct PostReport {
   pub id: PostReportId,
   pub creator_id: PersonId,
@@ -24,8 +22,9 @@ pub struct PostReport {
   pub updated: Option<chrono::NaiveDateTime>,
 }
 
-#[derive(Insertable, AsChangeset, Clone)]
-#[table_name = "post_report"]
+#[derive(Clone)]
+#[cfg_attr(feature = "full", derive(Insertable, AsChangeset))]
+#[cfg_attr(feature = "full", table_name = "post_report")]
 pub struct PostReportForm {
   pub creator_id: PersonId,
   pub post_id: PostId,
index 7facccaacd3ac5f247061e35b56b3d47eb0590bc..fa697a51fa11c3b907d9fa6d8b3ea4e33d4603c3 100644 (file)
@@ -1,13 +1,12 @@
-use crate::{
-  newtypes::{DbUrl, PersonId, PrivateMessageId},
-  schema::private_message,
-};
+use crate::newtypes::{DbUrl, PersonId, PrivateMessageId};
 use serde::{Deserialize, Serialize};
 
-#[derive(
-  Clone, Queryable, Associations, Identifiable, PartialEq, Debug, Serialize, Deserialize,
-)]
-#[table_name = "private_message"]
+#[cfg(feature = "full")]
+use crate::schema::private_message;
+
+#[derive(Clone, PartialEq, Debug, Serialize, Deserialize)]
+#[cfg_attr(feature = "full", derive(Queryable, Associations, Identifiable))]
+#[cfg_attr(feature = "full", table_name = "private_message")]
 pub struct PrivateMessage {
   pub id: PrivateMessageId,
   pub creator_id: PersonId,
@@ -21,8 +20,9 @@ pub struct PrivateMessage {
   pub local: bool,
 }
 
-#[derive(Insertable, AsChangeset, Default)]
-#[table_name = "private_message"]
+#[derive(Default)]
+#[cfg_attr(feature = "full", derive(Insertable, AsChangeset))]
+#[cfg_attr(feature = "full", table_name = "private_message")]
 pub struct PrivateMessageForm {
   pub creator_id: PersonId,
   pub recipient_id: PersonId,
index 01f702d8183f6b6d0a6468ff7994ab6c52d1b9c4..c874427af6f9211970ab569c6d7555cf440893bc 100644 (file)
@@ -1,11 +1,12 @@
-use crate::{
-  newtypes::{LocalUserId, PersonId},
-  schema::registration_application,
-};
+use crate::newtypes::{LocalUserId, PersonId};
 use serde::{Deserialize, Serialize};
 
-#[derive(Clone, Queryable, Identifiable, PartialEq, Debug, Serialize, Deserialize)]
-#[table_name = "registration_application"]
+#[cfg(feature = "full")]
+use crate::schema::registration_application;
+
+#[derive(Clone, PartialEq, Debug, Serialize, Deserialize)]
+#[cfg_attr(feature = "full", derive(Queryable, Identifiable))]
+#[cfg_attr(feature = "full", table_name = "registration_application")]
 pub struct RegistrationApplication {
   pub id: i32,
   pub local_user_id: LocalUserId,
@@ -15,8 +16,9 @@ pub struct RegistrationApplication {
   pub published: chrono::NaiveDateTime,
 }
 
-#[derive(Insertable, AsChangeset, Default)]
-#[table_name = "registration_application"]
+#[derive(Default)]
+#[cfg_attr(feature = "full", derive(Insertable, AsChangeset))]
+#[cfg_attr(feature = "full", table_name = "registration_application")]
 pub struct RegistrationApplicationForm {
   pub local_user_id: Option<LocalUserId>,
   pub answer: Option<String>,
index 1a8b30185b5b97efafbf934f5f8b91ac70d6a499..d32a3ac73dc3dfb7fcb97175a8861a54a5645000 100644 (file)
@@ -1,7 +1,9 @@
+#[cfg(feature = "full")]
 use crate::schema::secret;
 
-#[derive(Queryable, Identifiable, Clone)]
-#[table_name = "secret"]
+#[derive(Clone)]
+#[cfg_attr(feature = "full", derive(Queryable, Identifiable))]
+#[cfg_attr(feature = "full", table_name = "secret")]
 pub struct Secret {
   pub id: i32,
   pub jwt_secret: String,
index 8e73cca41b411fb78e1a9a60dd2e8f78d4e69a1d..b43783669af3f0c454b66c49ed3be8293c7c95be 100644 (file)
@@ -1,8 +1,12 @@
-use crate::{newtypes::DbUrl, schema::site};
+use crate::newtypes::DbUrl;
 use serde::{Deserialize, Serialize};
 
-#[derive(Queryable, Identifiable, PartialEq, Debug, Clone, Serialize, Deserialize)]
-#[table_name = "site"]
+#[cfg(feature = "full")]
+use crate::schema::site;
+
+#[derive(PartialEq, Debug, Clone, Serialize, Deserialize)]
+#[cfg_attr(feature = "full", derive(Queryable, Identifiable))]
+#[cfg_attr(feature = "full", table_name = "site")]
 pub struct Site {
   pub id: i32,
   pub name: String,
@@ -29,8 +33,9 @@ pub struct Site {
   pub default_post_listing_type: String,
 }
 
-#[derive(Insertable, AsChangeset, Default)]
-#[table_name = "site"]
+#[derive(Default)]
+#[cfg_attr(feature = "full", derive(Insertable, AsChangeset))]
+#[cfg_attr(feature = "full", table_name = "site")]
 pub struct SiteForm {
   pub name: String,
   pub sidebar: Option<Option<String>>,
index 98f97327341df42249c86dc334893fb95140f93a..2b8e3422e15a38cda2baa7e3c130764ed0807f0e 100644 (file)
@@ -1,7 +1,4 @@
-use crate::{
-  newtypes::{CommunityId, PersonId},
-  DbUrl,
-};
+use crate::newtypes::{CommunityId, DbUrl, PersonId};
 use diesel::{result::Error, PgConnection};
 
 pub trait Crud {
diff --git a/crates/db_schema/src/utils.rs b/crates/db_schema/src/utils.rs
new file mode 100644 (file)
index 0000000..5854305
--- /dev/null
@@ -0,0 +1,216 @@
+use crate::newtypes::DbUrl;
+use chrono::NaiveDateTime;
+use diesel::{
+  backend::Backend,
+  deserialize::FromSql,
+  serialize::{Output, ToSql},
+  sql_types::Text,
+  Connection,
+  PgConnection,
+};
+use lemmy_apub_lib::{object_id::ObjectId, traits::ApubObject};
+use lemmy_utils::LemmyError;
+use once_cell::sync::Lazy;
+use regex::Regex;
+use serde::{Deserialize, Serialize};
+use std::{env, env::VarError, io::Write};
+use url::Url;
+
+pub type DbPool = diesel::r2d2::Pool<diesel::r2d2::ConnectionManager<diesel::PgConnection>>;
+
+pub fn get_database_url_from_env() -> Result<String, VarError> {
+  env::var("LEMMY_DATABASE_URL")
+}
+
+#[derive(EnumString, Display, Debug, Serialize, Deserialize, Clone, Copy)]
+pub enum SortType {
+  Active,
+  Hot,
+  New,
+  TopDay,
+  TopWeek,
+  TopMonth,
+  TopYear,
+  TopAll,
+  MostComments,
+  NewComments,
+}
+
+#[derive(EnumString, Display, Debug, Serialize, Deserialize, Clone, Copy, PartialEq)]
+pub enum ListingType {
+  All,
+  Local,
+  Subscribed,
+  Community,
+}
+
+#[derive(EnumString, Display, Debug, Serialize, Deserialize, Clone, Copy)]
+pub enum SearchType {
+  All,
+  Comments,
+  Posts,
+  Communities,
+  Users,
+  Url,
+}
+
+pub fn from_opt_str_to_opt_enum<T: std::str::FromStr>(opt: &Option<String>) -> Option<T> {
+  opt.as_ref().and_then(|t| T::from_str(t).ok())
+}
+
+pub fn fuzzy_search(q: &str) -> String {
+  let replaced = q.replace('%', "\\%").replace('_', "\\_").replace(' ', "%");
+  format!("%{}%", replaced)
+}
+
+pub fn limit_and_offset(page: Option<i64>, limit: Option<i64>) -> (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<String>) -> Option<Option<String>> {
+  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<String>,
+) -> Result<Option<Option<DbUrl>>, LemmyError> {
+  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(LemmyError::from_error_message(e, "invalid_url")),
+    },
+    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
+}
+
+pub fn naive_now() -> NaiveDateTime {
+  chrono::prelude::Utc::now().naive_utc()
+}
+
+static EMAIL_REGEX: Lazy<Regex> = Lazy::new(|| {
+  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;
+  }
+
+  sql_function!(fn lower(x: Text) -> Text);
+}
+
+impl<DB: Backend> ToSql<Text, DB> for DbUrl
+where
+  String: ToSql<Text, DB>,
+{
+  fn to_sql<W: Write>(&self, out: &mut Output<W, DB>) -> diesel::serialize::Result {
+    self.0.to_string().to_sql(out)
+  }
+}
+
+impl<DB: Backend> FromSql<Text, DB> for DbUrl
+where
+  String: FromSql<Text, DB>,
+{
+  fn from_sql(bytes: Option<&DB::RawValue>) -> diesel::deserialize::Result<Self> {
+    let str = String::from_sql(bytes)?;
+    Ok(DbUrl(Url::parse(&str)?))
+  }
+}
+
+impl<Kind> From<ObjectId<Kind>> for DbUrl
+where
+  Kind: ApubObject + Send + 'static,
+  for<'de2> <Kind as ApubObject>::ApubType: serde::Deserialize<'de2>,
+{
+  fn from(id: ObjectId<Kind>) -> Self {
+    DbUrl(id.into())
+  }
+}
+
+#[cfg(test)]
+mod tests {
+  use super::{fuzzy_search, *};
+  use crate::utils::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()
+    ));
+  }
+}
index 4753b38dfefab6d0b471090ceaa5f59e41269d9a..e43113717ea5b65c04538035f297b6f3e7865baf 100644 (file)
@@ -10,11 +10,14 @@ documentation = "https://join-lemmy.org/docs/en/index.html"
 [lib]
 doctest = false
 
+[features]
+full = ["lemmy_db_schema/full", "diesel", "tracing"]
+
 [dependencies]
 lemmy_db_schema = { version = "=0.16.3", path = "../db_schema" }
-diesel = { version = "1.4.8", features = ["postgres","chrono","r2d2","serde_json"] }
+diesel = { version = "1.4.8", features = ["postgres","chrono","r2d2","serde_json"], optional = true }
 serde = { version = "1.0.136", features = ["derive"] }
-tracing = "0.1.32"
+tracing = { version = "0.1.32", optional = true }
 
 [dev-dependencies]
 serial_test = "0.6.0"
index 73224be599394dba7b321f902f0c0dc8fc105c1d..bca8afdc007293e68f87d1655faac0ae73070982 100644 (file)
@@ -1,7 +1,7 @@
+use crate::structs::CommentReportView;
 use diesel::{dsl::*, result::Error, *};
 use lemmy_db_schema::{
-  aggregates::comment_aggregates::CommentAggregates,
-  limit_and_offset,
+  aggregates::structs::CommentAggregates,
   newtypes::{CommentReportId, CommunityId, PersonId},
   schema::{
     comment,
@@ -24,22 +24,8 @@ use lemmy_db_schema::{
     post::Post,
   },
   traits::{MaybeOptional, ToSafe, ViewToVec},
+  utils::limit_and_offset,
 };
-use serde::{Deserialize, Serialize};
-
-#[derive(Debug, PartialEq, Serialize, Deserialize, Clone)]
-pub struct CommentReportView {
-  pub comment_report: CommentReport,
-  pub comment: Comment,
-  pub post: Post,
-  pub community: CommunitySafe,
-  pub creator: PersonSafe,
-  pub comment_creator: PersonSafeAlias1,
-  pub counts: CommentAggregates,
-  pub creator_banned_from_community: bool, // Left Join to CommunityPersonBan
-  pub my_vote: Option<i16>,                // Left join to CommentLike
-  pub resolver: Option<PersonSafeAlias2>,
-}
 
 type CommentReportViewTuple = (
   CommentReport,
@@ -321,10 +307,10 @@ impl ViewToVec for CommentReportView {
 mod tests {
   use crate::comment_report_view::{CommentReportQueryBuilder, CommentReportView};
   use lemmy_db_schema::{
-    aggregates::comment_aggregates::CommentAggregates,
-    establish_unpooled_connection,
+    aggregates::structs::CommentAggregates,
     source::{comment::*, comment_report::*, community::*, person::*, post::*},
     traits::{Crud, Joinable, Reportable},
+    utils::establish_unpooled_connection,
   };
   use serial_test::serial;
 
index da42bb134db2a6880a223c82b0f85f3fc52ab1fe..c8b4d387e58e7a40a39dae3ea6f966ec3e2e391c 100644 (file)
@@ -1,9 +1,7 @@
+use crate::structs::CommentView;
 use diesel::{dsl::*, result::Error, *};
 use lemmy_db_schema::{
-  aggregates::comment_aggregates::CommentAggregates,
-  functions::hot_rank,
-  fuzzy_search,
-  limit_and_offset,
+  aggregates::structs::CommentAggregates,
   newtypes::{CommentId, CommunityId, DbUrl, PersonId, PostId},
   schema::{
     comment,
@@ -28,25 +26,8 @@ use lemmy_db_schema::{
     post::Post,
   },
   traits::{MaybeOptional, ToSafe, ViewToVec},
-  ListingType,
-  SortType,
+  utils::{functions::hot_rank, fuzzy_search, limit_and_offset, ListingType, SortType},
 };
-use serde::{Deserialize, Serialize};
-
-#[derive(Debug, PartialEq, Serialize, Deserialize, Clone)]
-pub struct CommentView {
-  pub comment: Comment,
-  pub creator: PersonSafe,
-  pub recipient: Option<PersonSafeAlias1>, // Left joins to comment and person
-  pub post: Post,
-  pub community: CommunitySafe,
-  pub counts: CommentAggregates,
-  pub creator_banned_from_community: bool, // Left Join to CommunityPersonBan
-  pub subscribed: bool,                    // Left join to CommunityFollower
-  pub saved: bool,                         // Left join to CommentSaved
-  pub creator_blocked: bool,               // Left join to PersonBlock
-  pub my_vote: Option<i16>,                // Left join to CommentLike
-}
 
 type CommentViewTuple = (
   Comment,
@@ -544,10 +525,10 @@ impl ViewToVec for CommentView {
 mod tests {
   use crate::comment_view::*;
   use lemmy_db_schema::{
-    aggregates::comment_aggregates::CommentAggregates,
-    establish_unpooled_connection,
+    aggregates::structs::CommentAggregates,
     source::{comment::*, community::*, person::*, person_block::PersonBlockForm, post::*},
     traits::{Blockable, Crud, Likeable},
+    utils::establish_unpooled_connection,
   };
   use serial_test::serial;
 
index cb9fefcfd8c5877c50ec55d3b52c42f2b3e98514..b5567f87bb1edb1b9a353895216fb01d02b482cb 100644 (file)
@@ -1,11 +1,20 @@
 #[cfg(test)]
 extern crate serial_test;
 
+#[cfg(feature = "full")]
 pub mod comment_report_view;
+#[cfg(feature = "full")]
 pub mod comment_view;
+#[cfg(feature = "full")]
 pub mod local_user_view;
+#[cfg(feature = "full")]
 pub mod post_report_view;
+#[cfg(feature = "full")]
 pub mod post_view;
+#[cfg(feature = "full")]
 pub mod private_message_view;
+#[cfg(feature = "full")]
 pub mod registration_application_view;
+#[cfg(feature = "full")]
 pub mod site_view;
+pub mod structs;
index e2453a40d39634d63c8a068cfc6066da053510e4..12c26df6d0987f24d31662d116d50143f8f62096 100644 (file)
@@ -1,7 +1,7 @@
+use crate::structs::{LocalUserSettingsView, LocalUserView};
 use diesel::{result::Error, *};
 use lemmy_db_schema::{
-  aggregates::person_aggregates::PersonAggregates,
-  functions::lower,
+  aggregates::structs::PersonAggregates,
   newtypes::{LocalUserId, PersonId},
   schema::{local_user, person, person_aggregates},
   source::{
@@ -9,15 +9,8 @@ use lemmy_db_schema::{
     person::{Person, PersonSafe},
   },
   traits::{ToSafe, ToSafeSettings},
+  utils::functions::lower,
 };
-use serde::{Deserialize, Serialize};
-
-#[derive(Debug, Serialize, Deserialize, Clone)]
-pub struct LocalUserView {
-  pub local_user: LocalUser,
-  pub person: Person,
-  pub counts: PersonAggregates,
-}
 
 type LocalUserViewTuple = (LocalUser, Person, PersonAggregates);
 
@@ -118,13 +111,6 @@ impl LocalUserView {
   }
 }
 
-#[derive(Debug, Serialize, Deserialize, Clone)]
-pub struct LocalUserSettingsView {
-  pub local_user: LocalUserSettings,
-  pub person: PersonSafe,
-  pub counts: PersonAggregates,
-}
-
 type LocalUserSettingsViewTuple = (LocalUserSettings, PersonSafe, PersonAggregates);
 
 impl LocalUserSettingsView {
index 0f56c2620b6ee8cd707be871d33006515b433b35..9769ec02106085b01720a80dd9b6598be9c0dc03 100644 (file)
@@ -1,7 +1,7 @@
+use crate::structs::PostReportView;
 use diesel::{dsl::*, result::Error, *};
 use lemmy_db_schema::{
-  aggregates::post_aggregates::PostAggregates,
-  limit_and_offset,
+  aggregates::structs::PostAggregates,
   newtypes::{CommunityId, PersonId, PostReportId},
   schema::{
     community,
@@ -22,21 +22,8 @@ use lemmy_db_schema::{
     post_report::PostReport,
   },
   traits::{MaybeOptional, ToSafe, ViewToVec},
+  utils::limit_and_offset,
 };
-use serde::{Deserialize, Serialize};
-
-#[derive(Debug, PartialEq, Serialize, Deserialize, Clone)]
-pub struct PostReportView {
-  pub post_report: PostReport,
-  pub post: Post,
-  pub community: CommunitySafe,
-  pub creator: PersonSafe,
-  pub post_creator: PersonSafeAlias1,
-  pub creator_banned_from_community: bool,
-  pub my_vote: Option<i16>,
-  pub counts: PostAggregates,
-  pub resolver: Option<PersonSafeAlias2>,
-}
 
 type PostReportViewTuple = (
   PostReport,
@@ -304,8 +291,7 @@ impl ViewToVec for PostReportView {
 mod tests {
   use crate::post_report_view::{PostReportQueryBuilder, PostReportView};
   use lemmy_db_schema::{
-    aggregates::post_aggregates::PostAggregates,
-    establish_unpooled_connection,
+    aggregates::structs::PostAggregates,
     source::{
       community::*,
       person::*,
@@ -313,6 +299,7 @@ mod tests {
       post_report::{PostReport, PostReportForm},
     },
     traits::{Crud, Joinable, Reportable},
+    utils::establish_unpooled_connection,
   };
   use serial_test::serial;
 
index dd97cd8d493b344f0ead38f98ace9b70c4c4a18b..2fac5ade38329ba6cde1cad9f046cc74c08ff6df 100644 (file)
@@ -1,9 +1,7 @@
+use crate::structs::PostView;
 use diesel::{dsl::*, pg::Pg, result::Error, *};
 use lemmy_db_schema::{
-  aggregates::post_aggregates::PostAggregates,
-  functions::hot_rank,
-  fuzzy_search,
-  limit_and_offset,
+  aggregates::structs::PostAggregates,
   newtypes::{CommunityId, DbUrl, PersonId, PostId},
   schema::{
     community,
@@ -25,26 +23,10 @@ use lemmy_db_schema::{
     post::{Post, PostRead, PostSaved},
   },
   traits::{MaybeOptional, ToSafe, ViewToVec},
-  ListingType,
-  SortType,
+  utils::{functions::hot_rank, fuzzy_search, limit_and_offset, ListingType, SortType},
 };
-use serde::{Deserialize, Serialize};
 use tracing::debug;
 
-#[derive(Debug, PartialEq, Serialize, Deserialize, Clone)]
-pub struct PostView {
-  pub post: Post,
-  pub creator: PersonSafe,
-  pub community: CommunitySafe,
-  pub creator_banned_from_community: bool, // Left Join to CommunityPersonBan
-  pub counts: PostAggregates,
-  pub subscribed: bool,      // Left join to CommunityFollower
-  pub saved: bool,           // Left join to PostSaved
-  pub read: bool,            // Left join to PostRead
-  pub creator_blocked: bool, // Left join to PersonBlock
-  pub my_vote: Option<i16>,  // Left join to PostLike
-}
-
 type PostViewTuple = (
   Post,
   PersonSafe,
@@ -514,8 +496,7 @@ impl ViewToVec for PostView {
 mod tests {
   use crate::post_view::{PostQueryBuilder, PostView};
   use lemmy_db_schema::{
-    aggregates::post_aggregates::PostAggregates,
-    establish_unpooled_connection,
+    aggregates::structs::PostAggregates,
     source::{
       community::*,
       community_block::{CommunityBlock, CommunityBlockForm},
@@ -524,8 +505,7 @@ mod tests {
       post::*,
     },
     traits::{Blockable, Crud, Likeable},
-    ListingType,
-    SortType,
+    utils::{establish_unpooled_connection, ListingType, SortType},
   };
   use serial_test::serial;
 
index 8996f229233fe30fe5c6b5359c09bbb55c70f5ac..fdf5b8e1471c231da63da86da6987341b041910f 100644 (file)
@@ -1,6 +1,6 @@
+use crate::structs::PrivateMessageView;
 use diesel::{pg::Pg, result::Error, *};
 use lemmy_db_schema::{
-  limit_and_offset,
   newtypes::{PersonId, PrivateMessageId},
   schema::{person, person_alias_1, private_message},
   source::{
@@ -8,17 +8,10 @@ use lemmy_db_schema::{
     private_message::PrivateMessage,
   },
   traits::{MaybeOptional, ToSafe, ViewToVec},
+  utils::limit_and_offset,
 };
-use serde::{Deserialize, Serialize};
 use tracing::debug;
 
-#[derive(Debug, PartialEq, Serialize, Deserialize, Clone)]
-pub struct PrivateMessageView {
-  pub private_message: PrivateMessage,
-  pub creator: PersonSafe,
-  pub recipient: PersonSafeAlias1,
-}
-
 type PrivateMessageViewTuple = (PrivateMessage, PersonSafe, PersonSafeAlias1);
 
 impl PrivateMessageView {
index 2eab1535717aadeef730efdc3ab8edbcffb0fe4b..00c79323b91196d837b746636e4e949ce3c6406e 100644 (file)
@@ -1,6 +1,6 @@
+use crate::structs::RegistrationApplicationView;
 use diesel::{dsl::count, result::Error, *};
 use lemmy_db_schema::{
-  limit_and_offset,
   schema::{local_user, person, person_alias_1, registration_application},
   source::{
     local_user::{LocalUser, LocalUserSettings},
@@ -8,16 +8,8 @@ use lemmy_db_schema::{
     registration_application::RegistrationApplication,
   },
   traits::{MaybeOptional, ToSafe, ToSafeSettings, ViewToVec},
+  utils::limit_and_offset,
 };
-use serde::{Deserialize, Serialize};
-
-#[derive(Debug, PartialEq, Serialize, Deserialize, Clone)]
-pub struct RegistrationApplicationView {
-  pub registration_application: RegistrationApplication,
-  pub creator_local_user: LocalUserSettings,
-  pub creator: PersonSafe,
-  pub admin: Option<PersonSafeAlias1>,
-}
 
 type RegistrationApplicationViewTuple = (
   RegistrationApplication,
@@ -177,13 +169,13 @@ mod tests {
     RegistrationApplicationView,
   };
   use lemmy_db_schema::{
-    establish_unpooled_connection,
     source::{
       local_user::{LocalUser, LocalUserForm, LocalUserSettings},
       person::*,
       registration_application::{RegistrationApplication, RegistrationApplicationForm},
     },
     traits::Crud,
+    utils::establish_unpooled_connection,
   };
   use serial_test::serial;
 
index e3a55c6b5c4d7528feb6193096abe9d58d9be759..c630216f91ccb56e65447029a544da3a2ee535f8 100644 (file)
@@ -1,16 +1,10 @@
+use crate::structs::SiteView;
 use diesel::{result::Error, *};
 use lemmy_db_schema::{
-  aggregates::site_aggregates::SiteAggregates,
+  aggregates::structs::SiteAggregates,
   schema::{site, site_aggregates},
   source::site::Site,
 };
-use serde::{Deserialize, Serialize};
-
-#[derive(Debug, Serialize, Deserialize, Clone)]
-pub struct SiteView {
-  pub site: Site,
-  pub counts: SiteAggregates,
-}
 
 impl SiteView {
   pub fn read_local(conn: &PgConnection) -> Result<Self, Error> {
diff --git a/crates/db_views/src/structs.rs b/crates/db_views/src/structs.rs
new file mode 100644 (file)
index 0000000..59a5f0f
--- /dev/null
@@ -0,0 +1,107 @@
+use lemmy_db_schema::{
+  aggregates::structs::{CommentAggregates, PersonAggregates, PostAggregates, SiteAggregates},
+  source::{
+    comment::Comment,
+    comment_report::CommentReport,
+    community::CommunitySafe,
+    local_user::{LocalUser, LocalUserSettings},
+    person::{Person, PersonSafe, PersonSafeAlias1, PersonSafeAlias2},
+    post::Post,
+    post_report::PostReport,
+    private_message::PrivateMessage,
+    registration_application::RegistrationApplication,
+    site::Site,
+  },
+};
+use serde::{Deserialize, Serialize};
+
+#[derive(Debug, PartialEq, Serialize, Deserialize, Clone)]
+pub struct CommentReportView {
+  pub comment_report: CommentReport,
+  pub comment: Comment,
+  pub post: Post,
+  pub community: CommunitySafe,
+  pub creator: PersonSafe,
+  pub comment_creator: PersonSafeAlias1,
+  pub counts: CommentAggregates,
+  pub creator_banned_from_community: bool, // Left Join to CommunityPersonBan
+  pub my_vote: Option<i16>,                // Left join to CommentLike
+  pub resolver: Option<PersonSafeAlias2>,
+}
+
+#[derive(Debug, PartialEq, Serialize, Deserialize, Clone)]
+pub struct CommentView {
+  pub comment: Comment,
+  pub creator: PersonSafe,
+  pub recipient: Option<PersonSafeAlias1>, // Left joins to comment and person
+  pub post: Post,
+  pub community: CommunitySafe,
+  pub counts: CommentAggregates,
+  pub creator_banned_from_community: bool, // Left Join to CommunityPersonBan
+  pub subscribed: bool,                    // Left join to CommunityFollower
+  pub saved: bool,                         // Left join to CommentSaved
+  pub creator_blocked: bool,               // Left join to PersonBlock
+  pub my_vote: Option<i16>,                // Left join to CommentLike
+}
+
+#[derive(Debug, Serialize, Deserialize, Clone)]
+pub struct LocalUserView {
+  pub local_user: LocalUser,
+  pub person: Person,
+  pub counts: PersonAggregates,
+}
+
+#[derive(Debug, Serialize, Deserialize, Clone)]
+pub struct LocalUserSettingsView {
+  pub local_user: LocalUserSettings,
+  pub person: PersonSafe,
+  pub counts: PersonAggregates,
+}
+
+#[derive(Debug, PartialEq, Serialize, Deserialize, Clone)]
+pub struct PostReportView {
+  pub post_report: PostReport,
+  pub post: Post,
+  pub community: CommunitySafe,
+  pub creator: PersonSafe,
+  pub post_creator: PersonSafeAlias1,
+  pub creator_banned_from_community: bool,
+  pub my_vote: Option<i16>,
+  pub counts: PostAggregates,
+  pub resolver: Option<PersonSafeAlias2>,
+}
+
+#[derive(Debug, PartialEq, Serialize, Deserialize, Clone)]
+pub struct PostView {
+  pub post: Post,
+  pub creator: PersonSafe,
+  pub community: CommunitySafe,
+  pub creator_banned_from_community: bool, // Left Join to CommunityPersonBan
+  pub counts: PostAggregates,
+  pub subscribed: bool,      // Left join to CommunityFollower
+  pub saved: bool,           // Left join to PostSaved
+  pub read: bool,            // Left join to PostRead
+  pub creator_blocked: bool, // Left join to PersonBlock
+  pub my_vote: Option<i16>,  // Left join to PostLike
+}
+
+#[derive(Debug, PartialEq, Serialize, Deserialize, Clone)]
+pub struct PrivateMessageView {
+  pub private_message: PrivateMessage,
+  pub creator: PersonSafe,
+  pub recipient: PersonSafeAlias1,
+}
+
+#[derive(Debug, PartialEq, Serialize, Deserialize, Clone)]
+pub struct RegistrationApplicationView {
+  pub registration_application: RegistrationApplication,
+  pub creator_local_user: LocalUserSettings,
+  pub creator: PersonSafe,
+  pub admin: Option<PersonSafeAlias1>,
+}
+
+#[derive(Debug, Serialize, Deserialize, Clone)]
+pub struct SiteView {
+  pub site: Site,
+  pub counts: SiteAggregates,
+}
index 81c837619cb1ae790728a7397ebf386237028dfd..b8810064fc136d41c08e6e1689aab7d5310bb7a3 100644 (file)
@@ -10,7 +10,10 @@ documentation = "https://join-lemmy.org/docs/en/index.html"
 [lib]
 doctest = false
 
+[features]
+full = ["lemmy_db_schema/full", "diesel"]
+
 [dependencies]
 lemmy_db_schema = { version = "=0.16.3", path = "../db_schema" }
-diesel = { version = "1.4.8", features = ["postgres","chrono","r2d2","serde_json"] }
+diesel = { version = "1.4.8", features = ["postgres","chrono","r2d2","serde_json"], optional = true }
 serde = { version = "1.0.136", features = ["derive"] }
index 8f0cfca76342b5f5b5b0c88003ea95bb22b7c4fd..7c753cd20a4d97737c372025138a41df9129871e 100644 (file)
@@ -1,3 +1,4 @@
+use crate::structs::CommunityBlockView;
 use diesel::{result::Error, *};
 use lemmy_db_schema::{
   newtypes::PersonId,
@@ -8,13 +9,6 @@ use lemmy_db_schema::{
   },
   traits::{ToSafe, ViewToVec},
 };
-use serde::{Deserialize, Serialize};
-
-#[derive(Debug, Serialize, Deserialize, Clone)]
-pub struct CommunityBlockView {
-  pub person: PersonSafe,
-  pub community: CommunitySafe,
-}
 
 type CommunityBlockViewTuple = (PersonSafe, CommunitySafe);
 
index 581d9b57cc630830ca8f5d54e6278973be07d593..6d5d94a596cb30c338ad2a8dea0a4ce2cc840973 100644 (file)
@@ -1,3 +1,4 @@
+use crate::structs::CommunityFollowerView;
 use diesel::{result::Error, *};
 use lemmy_db_schema::{
   newtypes::{CommunityId, PersonId},
@@ -8,13 +9,6 @@ use lemmy_db_schema::{
   },
   traits::{ToSafe, ViewToVec},
 };
-use serde::{Deserialize, Serialize};
-
-#[derive(Debug, Serialize, Deserialize, Clone)]
-pub struct CommunityFollowerView {
-  pub community: CommunitySafe,
-  pub follower: PersonSafe,
-}
 
 type CommunityFollowerViewTuple = (CommunitySafe, PersonSafe);
 
index 1e48ad0ab92a505713170797ab064e68834087e4..13e7d8cfdbfe380dc19cce590249a82775d4a64b 100644 (file)
@@ -1,3 +1,4 @@
+use crate::structs::CommunityModeratorView;
 use diesel::{result::Error, *};
 use lemmy_db_schema::{
   newtypes::{CommunityId, PersonId},
@@ -8,13 +9,6 @@ use lemmy_db_schema::{
   },
   traits::{ToSafe, ViewToVec},
 };
-use serde::{Deserialize, Serialize};
-
-#[derive(Debug, Serialize, Deserialize, Clone)]
-pub struct CommunityModeratorView {
-  pub community: CommunitySafe,
-  pub moderator: PersonSafe,
-}
 
 type CommunityModeratorViewTuple = (CommunitySafe, PersonSafe);
 
index 6c67bd82a12b711fdbbe3f514adf1effd284ed72..6d765e07caefe8cd6d2259507883ba2e9426fbe5 100644 (file)
@@ -1,3 +1,4 @@
+use crate::structs::CommunityPersonBanView;
 use diesel::{dsl::*, result::Error, *};
 use lemmy_db_schema::{
   newtypes::{CommunityId, PersonId},
@@ -8,13 +9,6 @@ use lemmy_db_schema::{
   },
   traits::ToSafe,
 };
-use serde::{Deserialize, Serialize};
-
-#[derive(Debug, Serialize, Deserialize, Clone)]
-pub struct CommunityPersonBanView {
-  pub community: CommunitySafe,
-  pub person: PersonSafe,
-}
 
 impl CommunityPersonBanView {
   pub fn get(
index 2063fb14fb7cf90160aae4d16742036a0ec8f806..637a2d905010b6bf273c0f2a010f73815e07a4ba 100644 (file)
@@ -1,10 +1,7 @@
-use crate::{community_moderator_view::CommunityModeratorView, person_view::PersonViewSafe};
+use crate::structs::{CommunityModeratorView, CommunityView, PersonViewSafe};
 use diesel::{result::Error, *};
 use lemmy_db_schema::{
-  aggregates::community_aggregates::CommunityAggregates,
-  functions::hot_rank,
-  fuzzy_search,
-  limit_and_offset,
+  aggregates::structs::CommunityAggregates,
   newtypes::{CommunityId, PersonId},
   schema::{community, community_aggregates, community_block, community_follower, local_user},
   source::{
@@ -12,18 +9,8 @@ use lemmy_db_schema::{
     community_block::CommunityBlock,
   },
   traits::{MaybeOptional, ToSafe, ViewToVec},
-  ListingType,
-  SortType,
+  utils::{functions::hot_rank, fuzzy_search, limit_and_offset, ListingType, SortType},
 };
-use serde::{Deserialize, Serialize};
-
-#[derive(Debug, Serialize, Deserialize, Clone)]
-pub struct CommunityView {
-  pub community: CommunitySafe,
-  pub subscribed: bool,
-  pub blocked: bool,
-  pub counts: CommunityAggregates,
-}
 
 type CommunityViewTuple = (
   CommunitySafe,
index 6411feeedd32ca1f52659f66cfaa3a400c6e665d..878979f7d54cc593948f1c458df0e5037cf04a33 100644 (file)
@@ -1,8 +1,17 @@
+#[cfg(feature = "full")]
 pub mod community_block_view;
+#[cfg(feature = "full")]
 pub mod community_follower_view;
+#[cfg(feature = "full")]
 pub mod community_moderator_view;
+#[cfg(feature = "full")]
 pub mod community_person_ban_view;
+#[cfg(feature = "full")]
 pub mod community_view;
+#[cfg(feature = "full")]
 pub mod person_block_view;
+#[cfg(feature = "full")]
 pub mod person_mention_view;
+#[cfg(feature = "full")]
 pub mod person_view;
+pub mod structs;
index 2ca2077cbfd72f61ac706ddc411b08429d142119..b93f8167257c4800de29f440854625aae224581c 100644 (file)
@@ -1,3 +1,4 @@
+use crate::structs::PersonBlockView;
 use diesel::{result::Error, *};
 use lemmy_db_schema::{
   newtypes::PersonId,
@@ -5,13 +6,6 @@ use lemmy_db_schema::{
   source::person::{Person, PersonAlias1, PersonSafe, PersonSafeAlias1},
   traits::{ToSafe, ViewToVec},
 };
-use serde::{Deserialize, Serialize};
-
-#[derive(Debug, Serialize, Deserialize, Clone)]
-pub struct PersonBlockView {
-  pub person: PersonSafe,
-  pub target: PersonSafeAlias1,
-}
 
 type PersonBlockViewTuple = (PersonSafe, PersonSafeAlias1);
 
index 0be446a919ff8530de76b369656965d50b35baa8..59e9011388ebc321d5569094181fd6539da270b4 100644 (file)
@@ -1,8 +1,7 @@
+use crate::structs::PersonMentionView;
 use diesel::{dsl::*, result::Error, *};
 use lemmy_db_schema::{
-  aggregates::comment_aggregates::CommentAggregates,
-  functions::hot_rank,
-  limit_and_offset,
+  aggregates::structs::CommentAggregates,
   newtypes::{PersonId, PersonMentionId},
   schema::{
     comment,
@@ -27,25 +26,8 @@ use lemmy_db_schema::{
     post::Post,
   },
   traits::{MaybeOptional, ToSafe, ViewToVec},
-  SortType,
+  utils::{functions::hot_rank, limit_and_offset, SortType},
 };
-use serde::{Deserialize, Serialize};
-
-#[derive(Debug, PartialEq, Serialize, Deserialize, Clone)]
-pub struct PersonMentionView {
-  pub person_mention: PersonMention,
-  pub comment: Comment,
-  pub creator: PersonSafe,
-  pub post: Post,
-  pub community: CommunitySafe,
-  pub recipient: PersonSafeAlias1,
-  pub counts: CommentAggregates,
-  pub creator_banned_from_community: bool, // Left Join to CommunityPersonBan
-  pub subscribed: bool,                    // Left join to CommunityFollower
-  pub saved: bool,                         // Left join to CommentSaved
-  pub creator_blocked: bool,               // Left join to PersonBlock
-  pub my_vote: Option<i16>,                // Left join to CommentLike
-}
 
 type PersonMentionViewTuple = (
   PersonMention,
index d4be058544cbe727eed6cee6ba346500423bdf5b..1849f80b16f61a7f03c5297e4266105ef4db613d 100644 (file)
@@ -1,21 +1,13 @@
+use crate::structs::PersonViewSafe;
 use diesel::{dsl::*, result::Error, *};
 use lemmy_db_schema::{
-  aggregates::person_aggregates::PersonAggregates,
-  fuzzy_search,
-  limit_and_offset,
+  aggregates::structs::PersonAggregates,
   newtypes::PersonId,
   schema::{person, person_aggregates},
   source::person::{Person, PersonSafe},
   traits::{MaybeOptional, ToSafe, ViewToVec},
-  SortType,
+  utils::{fuzzy_search, limit_and_offset, SortType},
 };
-use serde::{Deserialize, Serialize};
-
-#[derive(Debug, Serialize, Deserialize, Clone)]
-pub struct PersonViewSafe {
-  pub person: PersonSafe,
-  pub counts: PersonAggregates,
-}
 
 type PersonViewSafeTuple = (PersonSafe, PersonAggregates);
 
diff --git a/crates/db_views_actor/src/structs.rs b/crates/db_views_actor/src/structs.rs
new file mode 100644 (file)
index 0000000..a6ec971
--- /dev/null
@@ -0,0 +1,71 @@
+use lemmy_db_schema::{
+  aggregates::structs::{CommentAggregates, CommunityAggregates, PersonAggregates},
+  source::{
+    comment::Comment,
+    community::CommunitySafe,
+    person::{PersonSafe, PersonSafeAlias1},
+    person_mention::PersonMention,
+    post::Post,
+  },
+};
+use serde::{Deserialize, Serialize};
+
+#[derive(Debug, Serialize, Deserialize, Clone)]
+pub struct CommunityBlockView {
+  pub person: PersonSafe,
+  pub community: CommunitySafe,
+}
+
+#[derive(Debug, Serialize, Deserialize, Clone)]
+pub struct CommunityFollowerView {
+  pub community: CommunitySafe,
+  pub follower: PersonSafe,
+}
+
+#[derive(Debug, Serialize, Deserialize, Clone)]
+pub struct CommunityModeratorView {
+  pub community: CommunitySafe,
+  pub moderator: PersonSafe,
+}
+
+#[derive(Debug, Serialize, Deserialize, Clone)]
+pub struct CommunityPersonBanView {
+  pub community: CommunitySafe,
+  pub person: PersonSafe,
+}
+
+#[derive(Debug, Serialize, Deserialize, Clone)]
+pub struct CommunityView {
+  pub community: CommunitySafe,
+  pub subscribed: bool,
+  pub blocked: bool,
+  pub counts: CommunityAggregates,
+}
+
+#[derive(Debug, Serialize, Deserialize, Clone)]
+pub struct PersonBlockView {
+  pub person: PersonSafe,
+  pub target: PersonSafeAlias1,
+}
+
+#[derive(Debug, PartialEq, Serialize, Deserialize, Clone)]
+pub struct PersonMentionView {
+  pub person_mention: PersonMention,
+  pub comment: Comment,
+  pub creator: PersonSafe,
+  pub post: Post,
+  pub community: CommunitySafe,
+  pub recipient: PersonSafeAlias1,
+  pub counts: CommentAggregates,
+  pub creator_banned_from_community: bool, // Left Join to CommunityPersonBan
+  pub subscribed: bool,                    // Left join to CommunityFollower
+  pub saved: bool,                         // Left join to CommentSaved
+  pub creator_blocked: bool,               // Left join to PersonBlock
+  pub my_vote: Option<i16>,                // Left join to CommentLike
+}
+
+#[derive(Debug, Serialize, Deserialize, Clone)]
+pub struct PersonViewSafe {
+  pub person: PersonSafe,
+  pub counts: PersonAggregates,
+}
index 2e5493922cb6415ef65cbff4f5a7e59944fb052f..110baaeb572f9746a6116445bcf511936fbd6a84 100644 (file)
@@ -10,7 +10,10 @@ documentation = "https://join-lemmy.org/docs/en/index.html"
 [lib]
 doctest = false
 
+[features]
+full = ["lemmy_db_schema/full", "diesel"]
+
 [dependencies]
 lemmy_db_schema = { version = "=0.16.3", path = "../db_schema" }
-diesel = { version = "1.4.8", features = ["postgres","chrono","r2d2","serde_json"] }
+diesel = { version = "1.4.8", features = ["postgres","chrono","r2d2","serde_json"], optional = true }
 serde = { version = "1.0.136", features = ["derive"] }
index ce51617ceba5c3db7e098fdb77967330c93e496d..c6f32426b72cc353e55b2fcb611f48891f975823 100644 (file)
@@ -1,11 +1,23 @@
+#[cfg(feature = "full")]
 pub mod mod_add_community_view;
+#[cfg(feature = "full")]
 pub mod mod_add_view;
+#[cfg(feature = "full")]
 pub mod mod_ban_from_community_view;
+#[cfg(feature = "full")]
 pub mod mod_ban_view;
+#[cfg(feature = "full")]
 pub mod mod_hide_community_view;
+#[cfg(feature = "full")]
 pub mod mod_lock_post_view;
+#[cfg(feature = "full")]
 pub mod mod_remove_comment_view;
+#[cfg(feature = "full")]
 pub mod mod_remove_community_view;
+#[cfg(feature = "full")]
 pub mod mod_remove_post_view;
+#[cfg(feature = "full")]
 pub mod mod_sticky_post_view;
+#[cfg(feature = "full")]
 pub mod mod_transfer_community_view;
+pub mod structs;
index b0d72d21a0eff4a305443742cfbb423fd8d70579..55bb9d99b33a2c2480ca0c5512ee5e2e88dd2611 100644 (file)
@@ -1,6 +1,6 @@
+use crate::structs::ModAddCommunityView;
 use diesel::{result::Error, *};
 use lemmy_db_schema::{
-  limit_and_offset,
   newtypes::{CommunityId, PersonId},
   schema::{community, mod_add_community, person, person_alias_1},
   source::{
@@ -9,16 +9,8 @@ use lemmy_db_schema::{
     person::{Person, PersonAlias1, PersonSafe, PersonSafeAlias1},
   },
   traits::{ToSafe, ViewToVec},
+  utils::limit_and_offset,
 };
-use serde::{Deserialize, Serialize};
-
-#[derive(Debug, Serialize, Deserialize, Clone)]
-pub struct ModAddCommunityView {
-  pub mod_add_community: ModAddCommunity,
-  pub moderator: PersonSafe,
-  pub community: CommunitySafe,
-  pub modded_person: PersonSafeAlias1,
-}
 
 type ModAddCommunityViewTuple = (ModAddCommunity, PersonSafe, CommunitySafe, PersonSafeAlias1);
 
index bd4e388b3c8bf3151e2672674e7bd297f225501e..5b48d006682a614ea7b9ac43ea3288262a8a648d 100644 (file)
@@ -1,6 +1,6 @@
+use crate::structs::ModAddView;
 use diesel::{result::Error, *};
 use lemmy_db_schema::{
-  limit_and_offset,
   newtypes::PersonId,
   schema::{mod_add, person, person_alias_1},
   source::{
@@ -8,15 +8,8 @@ use lemmy_db_schema::{
     person::{Person, PersonAlias1, PersonSafe, PersonSafeAlias1},
   },
   traits::{ToSafe, ViewToVec},
+  utils::limit_and_offset,
 };
-use serde::{Deserialize, Serialize};
-
-#[derive(Debug, Serialize, Deserialize, Clone)]
-pub struct ModAddView {
-  pub mod_add: ModAdd,
-  pub moderator: PersonSafe,
-  pub modded_person: PersonSafeAlias1,
-}
 
 type ModAddViewTuple = (ModAdd, PersonSafe, PersonSafeAlias1);
 
index a5a37cce1c9e9861feedfa69abaf45e2738ed912..9e44e4797a5560b112e1b8f0fb1604cb0062e4b8 100644 (file)
@@ -1,6 +1,6 @@
+use crate::structs::ModBanFromCommunityView;
 use diesel::{result::Error, *};
 use lemmy_db_schema::{
-  limit_and_offset,
   newtypes::{CommunityId, PersonId},
   schema::{community, mod_ban_from_community, person, person_alias_1},
   source::{
@@ -9,16 +9,8 @@ use lemmy_db_schema::{
     person::{Person, PersonAlias1, PersonSafe, PersonSafeAlias1},
   },
   traits::{ToSafe, ViewToVec},
+  utils::limit_and_offset,
 };
-use serde::{Deserialize, Serialize};
-
-#[derive(Debug, Serialize, Deserialize, Clone)]
-pub struct ModBanFromCommunityView {
-  pub mod_ban_from_community: ModBanFromCommunity,
-  pub moderator: PersonSafe,
-  pub community: CommunitySafe,
-  pub banned_person: PersonSafeAlias1,
-}
 
 type ModBanFromCommunityViewTuple = (
   ModBanFromCommunity,
index fabb56ca986dc1adba993f704d090c97c73532aa..a36adaad074b093449c027ad9ef97cafe9d277e3 100644 (file)
@@ -1,6 +1,6 @@
+use crate::structs::ModBanView;
 use diesel::{result::Error, *};
 use lemmy_db_schema::{
-  limit_and_offset,
   newtypes::PersonId,
   schema::{mod_ban, person, person_alias_1},
   source::{
@@ -8,15 +8,8 @@ use lemmy_db_schema::{
     person::{Person, PersonAlias1, PersonSafe, PersonSafeAlias1},
   },
   traits::{ToSafe, ViewToVec},
+  utils::limit_and_offset,
 };
-use serde::{Deserialize, Serialize};
-
-#[derive(Debug, Serialize, Deserialize, Clone)]
-pub struct ModBanView {
-  pub mod_ban: ModBan,
-  pub moderator: PersonSafe,
-  pub banned_person: PersonSafeAlias1,
-}
 
 type ModBanViewTuple = (ModBan, PersonSafe, PersonSafeAlias1);
 
index c7aba772df43a9e0fc3913d86642d7a577415d32..a838056227a4d5157e5c99c1a4e086016fe01498 100644 (file)
@@ -1,6 +1,6 @@
+use crate::structs::ModHideCommunityView;
 use diesel::{result::Error, *};
 use lemmy_db_schema::{
-  limit_and_offset,
   newtypes::{CommunityId, PersonId},
   schema::{community, mod_hide_community, person},
   source::{
@@ -9,15 +9,8 @@ use lemmy_db_schema::{
     person::{Person, PersonSafe},
   },
   traits::{ToSafe, ViewToVec},
+  utils::limit_and_offset,
 };
-use serde::{Deserialize, Serialize};
-
-#[derive(Debug, Serialize, Deserialize, Clone)]
-pub struct ModHideCommunityView {
-  pub mod_hide_community: ModHideCommunity,
-  pub admin: PersonSafe,
-  pub community: CommunitySafe,
-}
 
 type ModHideCommunityViewTuple = (ModHideCommunity, PersonSafe, CommunitySafe);
 
index 5ec355791342c6042216944c2387cf8e2418dfce..e9ec5f6679de72778ba45892f4d92a7d27fe1f2a 100644 (file)
@@ -1,6 +1,6 @@
+use crate::structs::ModLockPostView;
 use diesel::{result::Error, *};
 use lemmy_db_schema::{
-  limit_and_offset,
   newtypes::{CommunityId, PersonId},
   schema::{community, mod_lock_post, person, post},
   source::{
@@ -10,16 +10,8 @@ use lemmy_db_schema::{
     post::Post,
   },
   traits::{ToSafe, ViewToVec},
+  utils::limit_and_offset,
 };
-use serde::{Deserialize, Serialize};
-
-#[derive(Debug, Serialize, Deserialize, Clone)]
-pub struct ModLockPostView {
-  pub mod_lock_post: ModLockPost,
-  pub moderator: PersonSafe,
-  pub post: Post,
-  pub community: CommunitySafe,
-}
 
 type ModLockPostViewTuple = (ModLockPost, PersonSafe, Post, CommunitySafe);
 
index abb88020a56a841c9a83a198274614ea207fb1de..b2b14f220403bbd75c98b7cce24fae2f95f0006e 100644 (file)
@@ -1,6 +1,6 @@
+use crate::structs::ModRemoveCommentView;
 use diesel::{result::Error, *};
 use lemmy_db_schema::{
-  limit_and_offset,
   newtypes::{CommunityId, PersonId},
   schema::{comment, community, mod_remove_comment, person, person_alias_1, post},
   source::{
@@ -11,18 +11,8 @@ use lemmy_db_schema::{
     post::Post,
   },
   traits::{ToSafe, ViewToVec},
+  utils::limit_and_offset,
 };
-use serde::{Deserialize, Serialize};
-
-#[derive(Debug, Serialize, Deserialize, Clone)]
-pub struct ModRemoveCommentView {
-  pub mod_remove_comment: ModRemoveComment,
-  pub moderator: PersonSafe,
-  pub comment: Comment,
-  pub commenter: PersonSafeAlias1,
-  pub post: Post,
-  pub community: CommunitySafe,
-}
 
 type ModRemoveCommentViewTuple = (
   ModRemoveComment,
index 6634b2ff8bd84438207fdb55ee27c63f7f4f5441..29aad7f92d18f6c57f7342c49dbcafe0199b3a6d 100644 (file)
@@ -1,6 +1,6 @@
+use crate::structs::ModRemoveCommunityView;
 use diesel::{result::Error, *};
 use lemmy_db_schema::{
-  limit_and_offset,
   newtypes::PersonId,
   schema::{community, mod_remove_community, person},
   source::{
@@ -9,15 +9,8 @@ use lemmy_db_schema::{
     person::{Person, PersonSafe},
   },
   traits::{ToSafe, ViewToVec},
+  utils::limit_and_offset,
 };
-use serde::{Deserialize, Serialize};
-
-#[derive(Debug, Serialize, Deserialize, Clone)]
-pub struct ModRemoveCommunityView {
-  pub mod_remove_community: ModRemoveCommunity,
-  pub moderator: PersonSafe,
-  pub community: CommunitySafe,
-}
 
 type ModRemoveCommunityTuple = (ModRemoveCommunity, PersonSafe, CommunitySafe);
 
index c92191610249f4af4628c86ade82f0033df912ed..849b563912330e1d183f1ee8abdbb29a899c359f 100644 (file)
@@ -1,6 +1,6 @@
+use crate::structs::ModRemovePostView;
 use diesel::{result::Error, *};
 use lemmy_db_schema::{
-  limit_and_offset,
   newtypes::{CommunityId, PersonId},
   schema::{community, mod_remove_post, person, post},
   source::{
@@ -10,16 +10,8 @@ use lemmy_db_schema::{
     post::Post,
   },
   traits::{ToSafe, ViewToVec},
+  utils::limit_and_offset,
 };
-use serde::{Deserialize, Serialize};
-
-#[derive(Debug, Serialize, Deserialize, Clone)]
-pub struct ModRemovePostView {
-  pub mod_remove_post: ModRemovePost,
-  pub moderator: PersonSafe,
-  pub post: Post,
-  pub community: CommunitySafe,
-}
 
 type ModRemovePostViewTuple = (ModRemovePost, PersonSafe, Post, CommunitySafe);
 
index 55593e4fc8de4b90b6558dfee2b281e82a8163d3..8b2383ee5ffd1816fd7090db4f038580c48fbcdf 100644 (file)
@@ -1,6 +1,6 @@
+use crate::structs::ModStickyPostView;
 use diesel::{result::Error, *};
 use lemmy_db_schema::{
-  limit_and_offset,
   newtypes::{CommunityId, PersonId},
   schema::{community, mod_sticky_post, person, post},
   source::{
@@ -10,16 +10,8 @@ use lemmy_db_schema::{
     post::Post,
   },
   traits::{ToSafe, ViewToVec},
+  utils::limit_and_offset,
 };
-use serde::{Deserialize, Serialize};
-
-#[derive(Debug, Serialize, Deserialize, Clone)]
-pub struct ModStickyPostView {
-  pub mod_sticky_post: ModStickyPost,
-  pub moderator: PersonSafe,
-  pub post: Post,
-  pub community: CommunitySafe,
-}
 
 type ModStickyPostViewTuple = (ModStickyPost, PersonSafe, Post, CommunitySafe);
 
index 2fbacbb831e3aee5428e224513bfacee44efb296..c944a9a10ba685373d2d88ab330242a40f74737d 100644 (file)
@@ -1,6 +1,6 @@
+use crate::structs::ModTransferCommunityView;
 use diesel::{result::Error, *};
 use lemmy_db_schema::{
-  limit_and_offset,
   newtypes::{CommunityId, PersonId},
   schema::{community, mod_transfer_community, person, person_alias_1},
   source::{
@@ -9,16 +9,8 @@ use lemmy_db_schema::{
     person::{Person, PersonAlias1, PersonSafe, PersonSafeAlias1},
   },
   traits::{ToSafe, ViewToVec},
+  utils::limit_and_offset,
 };
-use serde::{Deserialize, Serialize};
-
-#[derive(Debug, Serialize, Deserialize, Clone)]
-pub struct ModTransferCommunityView {
-  pub mod_transfer_community: ModTransferCommunity,
-  pub moderator: PersonSafe,
-  pub community: CommunitySafe,
-  pub modded_person: PersonSafeAlias1,
-}
 
 type ModTransferCommunityViewTuple = (
   ModTransferCommunity,
diff --git a/crates/db_views_moderator/src/structs.rs b/crates/db_views_moderator/src/structs.rs
new file mode 100644 (file)
index 0000000..9d525b5
--- /dev/null
@@ -0,0 +1,106 @@
+use lemmy_db_schema::source::{
+  comment::Comment,
+  community::CommunitySafe,
+  moderator::{
+    ModAdd,
+    ModAddCommunity,
+    ModBan,
+    ModBanFromCommunity,
+    ModHideCommunity,
+    ModLockPost,
+    ModRemoveComment,
+    ModRemoveCommunity,
+    ModRemovePost,
+    ModStickyPost,
+    ModTransferCommunity,
+  },
+  person::{PersonSafe, PersonSafeAlias1},
+  post::Post,
+};
+use serde::{Deserialize, Serialize};
+
+#[derive(Debug, Serialize, Deserialize, Clone)]
+pub struct ModAddCommunityView {
+  pub mod_add_community: ModAddCommunity,
+  pub moderator: PersonSafe,
+  pub community: CommunitySafe,
+  pub modded_person: PersonSafeAlias1,
+}
+
+#[derive(Debug, Serialize, Deserialize, Clone)]
+pub struct ModAddView {
+  pub mod_add: ModAdd,
+  pub moderator: PersonSafe,
+  pub modded_person: PersonSafeAlias1,
+}
+
+#[derive(Debug, Serialize, Deserialize, Clone)]
+pub struct ModBanFromCommunityView {
+  pub mod_ban_from_community: ModBanFromCommunity,
+  pub moderator: PersonSafe,
+  pub community: CommunitySafe,
+  pub banned_person: PersonSafeAlias1,
+}
+
+#[derive(Debug, Serialize, Deserialize, Clone)]
+pub struct ModBanView {
+  pub mod_ban: ModBan,
+  pub moderator: PersonSafe,
+  pub banned_person: PersonSafeAlias1,
+}
+
+#[derive(Debug, Serialize, Deserialize, Clone)]
+pub struct ModHideCommunityView {
+  pub mod_hide_community: ModHideCommunity,
+  pub admin: PersonSafe,
+  pub community: CommunitySafe,
+}
+
+#[derive(Debug, Serialize, Deserialize, Clone)]
+pub struct ModLockPostView {
+  pub mod_lock_post: ModLockPost,
+  pub moderator: PersonSafe,
+  pub post: Post,
+  pub community: CommunitySafe,
+}
+
+#[derive(Debug, Serialize, Deserialize, Clone)]
+pub struct ModRemoveCommentView {
+  pub mod_remove_comment: ModRemoveComment,
+  pub moderator: PersonSafe,
+  pub comment: Comment,
+  pub commenter: PersonSafeAlias1,
+  pub post: Post,
+  pub community: CommunitySafe,
+}
+
+#[derive(Debug, Serialize, Deserialize, Clone)]
+pub struct ModRemoveCommunityView {
+  pub mod_remove_community: ModRemoveCommunity,
+  pub moderator: PersonSafe,
+  pub community: CommunitySafe,
+}
+
+#[derive(Debug, Serialize, Deserialize, Clone)]
+pub struct ModRemovePostView {
+  pub mod_remove_post: ModRemovePost,
+  pub moderator: PersonSafe,
+  pub post: Post,
+  pub community: CommunitySafe,
+}
+
+#[derive(Debug, Serialize, Deserialize, Clone)]
+pub struct ModStickyPostView {
+  pub mod_sticky_post: ModStickyPost,
+  pub moderator: PersonSafe,
+  pub post: Post,
+  pub community: CommunitySafe,
+}
+
+#[derive(Debug, Serialize, Deserialize, Clone)]
+pub struct ModTransferCommunityView {
+  pub mod_transfer_community: ModTransferCommunity,
+  pub moderator: PersonSafe,
+  pub community: CommunitySafe,
+  pub modded_person: PersonSafeAlias1,
+}
index f1bf6edcafb5de9e9712268de44d63b0af27af36..2ade2385fbd86387938f8d813452e7ec71dba909 100644 (file)
@@ -21,7 +21,7 @@ lemmy_apub = { version = "=0.16.3", path = "../apub" }
 diesel = "1.4.8"
 actix-web = { version = "4.0.1", default-features = false, features = ["rustls"] }
 anyhow = "1.0.56"
-chrono = { version = "0.4.19", features = ["serde"] }
+chrono = { version = "0.4.19", features = ["serde"], default-features = false }
 futures = "0.3.21"
 reqwest = { version = "0.11.10", features = ["stream"] }
 reqwest-middleware = "0.1.5"
index bfe49fbdb81a0c595db9be0e40b211344c70185b..1bcfc6c3efbd7d9cde50e97222b898dffefbfd62 100644 (file)
@@ -2,20 +2,22 @@ use actix_web::{error::ErrorBadRequest, *};
 use anyhow::anyhow;
 use chrono::{DateTime, NaiveDateTime, Utc};
 use diesel::PgConnection;
-use lemmy_api_common::blocking;
+use lemmy_api_common::utils::blocking;
 use lemmy_db_schema::{
   newtypes::LocalUserId,
   source::{community::Community, local_user::LocalUser, person::Person},
   traits::{ApubActor, Crud},
-  ListingType,
-  SortType,
+  utils::{ListingType, SortType},
 };
 use lemmy_db_views::{
-  comment_view::{CommentQueryBuilder, CommentView},
-  post_view::{PostQueryBuilder, PostView},
-  site_view::SiteView,
+  comment_view::CommentQueryBuilder,
+  post_view::PostQueryBuilder,
+  structs::{CommentView, PostView, SiteView},
+};
+use lemmy_db_views_actor::{
+  person_mention_view::PersonMentionQueryBuilder,
+  structs::PersonMentionView,
 };
-use lemmy_db_views_actor::person_mention_view::{PersonMentionQueryBuilder, PersonMentionView};
 use lemmy_utils::{claims::Claims, utils::markdown_to_html, LemmyError};
 use lemmy_websocket::LemmyContext;
 use once_cell::sync::Lazy;
index 6e216f4415682f698a9b6ccbfc6c47fbc32b380d..6ca2114e4b8348ed88b5059ffb70b3505688cb64 100644 (file)
@@ -1,7 +1,7 @@
 use actix_web::{error::ErrorBadRequest, *};
 use anyhow::anyhow;
-use lemmy_api_common::blocking;
-use lemmy_db_views::site_view::SiteView;
+use lemmy_api_common::utils::blocking;
+use lemmy_db_views::structs::SiteView;
 use lemmy_utils::{version, LemmyError};
 use lemmy_websocket::LemmyContext;
 use serde::{Deserialize, Serialize};
index a95902b270baad0e7230f74517181c328a4105f5..01ed2bc00a242082409041d8fd8a920cd34b9f04 100644 (file)
@@ -1,6 +1,6 @@
 use actix_web::{web, web::Query, HttpResponse};
 use anyhow::Context;
-use lemmy_api_common::blocking;
+use lemmy_api_common::utils::blocking;
 use lemmy_apub::fetcher::webfinger::{WebfingerLink, WebfingerResponse};
 use lemmy_db_schema::{
   source::{community::Community, person::Person},
index 3984b897856a5150e143998f89d981268c0b415f..18968897123f2cd07a1ea83a11a4142c72180f5d 100644 (file)
@@ -14,24 +14,20 @@ doctest = false
 
 [dependencies]
 regex = "1.5.5"
-chrono = { version = "0.4.19", features = ["serde"] }
+chrono = { version = "0.4.19", features = ["serde"], default-features = false }
 lettre = "0.10.0-rc.4"
 tracing = "0.1.32"
 tracing-error = "0.2.0"
 itertools = "0.10.3"
 rand = "0.8.5"
-percent-encoding = "2.1.0"
 serde = { version = "1.0.136", features = ["derive"] }
 serde_json = { version = "1.0.79", features = ["preserve_order"] }
-thiserror = "1.0.30"
 comrak = { version = "0.12.1", default-features = false }
 once_cell = "1.10.0"
 openssl = "0.10.38"
 url = { version = "2.2.2", features = ["serde"] }
 actix-web = { version = "4.0.1", default-features = false, features = ["rustls"] }
-actix-rt = { version = "2.7.0", default-features = false }
 anyhow = "1.0.56"
-reqwest = { version = "0.11.10", features = ["json"] }
 reqwest-middleware = "0.1.5"
 strum = "0.24.0"
 strum_macros = "0.24.0"
@@ -40,11 +36,9 @@ diesel = "1.4.8"
 http = "0.2.6"
 deser-hjson = "1.0.2"
 smart-default = "0.6.0"
-webpage = { version = "1.4.0", default-features = false, features = ["serde"] }
 jsonwebtoken = "8.0.1"
 doku = "0.11.0"
 uuid = { version = "0.8.2", features = ["serde", "v4"] }
-encoding = "0.2.33"
 html2text = "0.3.1"
 rosetta-i18n = "0.1.2"
 parking_lot = "0.12.0"
index 1dbfb25bc1f835ffc91deb41b89b987419bb9e28..b8e301bd906fc6342e1e568f67b2307f64e4eae3 100644 (file)
@@ -6,19 +6,15 @@ extern crate smart_default;
 pub mod apub;
 pub mod email;
 pub mod rate_limit;
-pub mod request;
 pub mod settings;
 
 pub mod claims;
+pub mod request;
 #[cfg(test)]
 mod test;
 pub mod utils;
 pub mod version;
 
-mod sensitive;
-
-pub use sensitive::Sensitive;
-
 use actix_web::HttpResponse;
 use http::StatusCode;
 use std::{fmt, fmt::Display, time::Duration};
index fb4949bd0fb8963876c53d1400862d50ca6c6d9b..e98e0e8a54414a1ec299c0430cc44e075d00a1eb 100644 (file)
@@ -1,22 +1,4 @@
-use crate::{settings::structs::Settings, version::VERSION, LemmyError, REQWEST_TIMEOUT};
-use anyhow::anyhow;
-use encoding::{all::encodings, DecoderTrap};
-use percent_encoding::{utf8_percent_encode, NON_ALPHANUMERIC};
-use reqwest_middleware::ClientWithMiddleware;
-use serde::{Deserialize, Serialize};
 use std::future::Future;
-use thiserror::Error;
-use tracing::{error, info};
-use url::Url;
-use webpage::HTML;
-
-#[derive(Clone, Debug, Error)]
-#[error("Error sending request, {0}")]
-struct SendError(pub String);
-
-#[derive(Clone, Debug, Error)]
-#[error("Error receiving response, {0}")]
-pub struct RecvError(pub String);
 
 #[tracing::instrument(skip_all)]
 pub async fn retry<F, Fut, T>(f: F) -> Result<T, reqwest_middleware::Error>
@@ -53,285 +35,3 @@ where
 
   response.expect("retry http request")
 }
-
-#[derive(Deserialize, Serialize, Debug, PartialEq, Clone)]
-pub struct SiteMetadata {
-  pub title: Option<String>,
-  pub description: Option<String>,
-  image: Option<Url>,
-  pub html: Option<String>,
-}
-
-/// Fetches the post link html tags (like title, description, image, etc)
-#[tracing::instrument(skip_all)]
-pub async fn fetch_site_metadata(
-  client: &ClientWithMiddleware,
-  url: &Url,
-) -> Result<SiteMetadata, LemmyError> {
-  info!("Fetching site metadata for url: {}", url);
-  let response = client
-    .get(url.as_str())
-    .timeout(REQWEST_TIMEOUT)
-    .send()
-    .await?;
-
-  // Can't use .text() here, because it only checks the content header, not the actual bytes
-  // https://github.com/LemmyNet/lemmy/issues/1964
-  let html_bytes = response
-    .bytes()
-    .await
-    .map_err(|e| RecvError(e.to_string()))?
-    .to_vec();
-
-  let tags = html_to_site_metadata(&html_bytes)?;
-
-  Ok(tags)
-}
-
-fn html_to_site_metadata(html_bytes: &[u8]) -> Result<SiteMetadata, LemmyError> {
-  let html = String::from_utf8_lossy(html_bytes);
-
-  // Make sure the first line is doctype html
-  let first_line = html
-    .trim_start()
-    .lines()
-    .into_iter()
-    .next()
-    .ok_or_else(|| LemmyError::from_message("No lines in html"))?
-    .to_lowercase();
-
-  if !first_line.starts_with("<!doctype html>") {
-    return Err(LemmyError::from_message(
-      "Site metadata page fetch is not DOCTYPE html",
-    ));
-  }
-
-  let mut page = HTML::from_string(html.to_string(), None)?;
-
-  // If the web page specifies that it isn't actually UTF-8, re-decode the received bytes with the
-  // proper encoding. If the specified encoding cannot be found, fall back to the original UTF-8
-  // version.
-  if let Some(charset) = page.meta.get("charset") {
-    if charset.to_lowercase() != "utf-8" {
-      if let Some(encoding_ref) = encodings().iter().find(|e| e.name() == charset) {
-        if let Ok(html_with_encoding) = encoding_ref.decode(html_bytes, DecoderTrap::Replace) {
-          page = HTML::from_string(html_with_encoding, None)?;
-        }
-      }
-    }
-  }
-
-  let page_title = page.title;
-  let page_description = page.description;
-
-  let og_description = page
-    .opengraph
-    .properties
-    .get("description")
-    .map(|t| t.to_string());
-  let og_title = page
-    .opengraph
-    .properties
-    .get("title")
-    .map(|t| t.to_string());
-  let og_image = page
-    .opengraph
-    .images
-    .get(0)
-    .and_then(|ogo| Url::parse(&ogo.url).ok());
-
-  let title = og_title.or(page_title);
-  let description = og_description.or(page_description);
-  let image = og_image;
-
-  Ok(SiteMetadata {
-    title,
-    description,
-    image,
-    html: None,
-  })
-}
-
-#[derive(Deserialize, Debug, Clone)]
-pub(crate) struct PictrsResponse {
-  files: Vec<PictrsFile>,
-  msg: String,
-}
-
-#[derive(Deserialize, Debug, Clone)]
-pub(crate) struct PictrsFile {
-  file: String,
-  #[allow(dead_code)]
-  delete_token: String,
-}
-
-#[tracing::instrument(skip_all)]
-pub(crate) async fn fetch_pictrs(
-  client: &ClientWithMiddleware,
-  settings: &Settings,
-  image_url: &Url,
-) -> Result<PictrsResponse, LemmyError> {
-  if let Some(pictrs_url) = settings.pictrs_url.to_owned() {
-    is_image_content_type(client, image_url).await?;
-
-    let fetch_url = format!(
-      "{}/image/download?url={}",
-      pictrs_url,
-      utf8_percent_encode(image_url.as_str(), NON_ALPHANUMERIC) // TODO this might not be needed
-    );
-
-    let response = client
-      .get(&fetch_url)
-      .timeout(REQWEST_TIMEOUT)
-      .send()
-      .await?;
-
-    let response: PictrsResponse = response
-      .json()
-      .await
-      .map_err(|e| RecvError(e.to_string()))?;
-
-    if response.msg == "ok" {
-      Ok(response)
-    } else {
-      Err(anyhow!("{}", &response.msg).into())
-    }
-  } else {
-    Err(anyhow!("pictrs_url not set up in config").into())
-  }
-}
-
-/// Both are options, since the URL might be either an html page, or an image
-/// Returns the SiteMetadata, and a Pictrs URL, if there is a picture associated
-#[tracing::instrument(skip_all)]
-pub async fn fetch_site_data(
-  client: &ClientWithMiddleware,
-  settings: &Settings,
-  url: Option<&Url>,
-) -> (Option<SiteMetadata>, Option<Url>) {
-  match &url {
-    Some(url) => {
-      // Fetch metadata
-      // Ignore errors, since it may be an image, or not have the data.
-      // Warning, this may ignore SSL errors
-      let metadata_option = fetch_site_metadata(client, url).await.ok();
-
-      // Fetch pictrs thumbnail
-      let pictrs_hash = match &metadata_option {
-        Some(metadata_res) => match &metadata_res.image {
-          // Metadata, with image
-          // Try to generate a small thumbnail if there's a full sized one from post-links
-          Some(metadata_image) => fetch_pictrs(client, settings, metadata_image)
-            .await
-            .map(|r| r.files[0].file.to_owned()),
-          // Metadata, but no image
-          None => fetch_pictrs(client, settings, url)
-            .await
-            .map(|r| r.files[0].file.to_owned()),
-        },
-        // No metadata, try to fetch the URL as an image
-        None => fetch_pictrs(client, settings, url)
-          .await
-          .map(|r| r.files[0].file.to_owned()),
-      };
-
-      // The full urls are necessary for federation
-      let pictrs_thumbnail = pictrs_hash
-        .map(|p| {
-          Url::parse(&format!(
-            "{}/pictrs/image/{}",
-            settings.get_protocol_and_hostname(),
-            p
-          ))
-          .ok()
-        })
-        .ok()
-        .flatten();
-
-      (metadata_option, pictrs_thumbnail)
-    }
-    None => (None, None),
-  }
-}
-
-#[tracing::instrument(skip_all)]
-async fn is_image_content_type(client: &ClientWithMiddleware, url: &Url) -> Result<(), LemmyError> {
-  let response = client
-    .get(url.as_str())
-    .timeout(REQWEST_TIMEOUT)
-    .send()
-    .await?;
-  if response
-    .headers()
-    .get("Content-Type")
-    .ok_or_else(|| anyhow!("No Content-Type header"))?
-    .to_str()?
-    .starts_with("image/")
-  {
-    Ok(())
-  } else {
-    Err(anyhow!("Not an image type.").into())
-  }
-}
-
-pub fn build_user_agent(settings: &Settings) -> String {
-  format!(
-    "Lemmy/{}; +{}",
-    VERSION,
-    settings.get_protocol_and_hostname()
-  )
-}
-
-#[cfg(test)]
-mod tests {
-  use crate::request::{build_user_agent, fetch_site_metadata};
-  use url::Url;
-
-  use super::SiteMetadata;
-  use crate::settings::structs::Settings;
-
-  // These helped with testing
-  #[actix_rt::test]
-  async fn test_site_metadata() {
-    let settings = Settings::init().unwrap();
-    let client = reqwest::Client::builder()
-      .user_agent(build_user_agent(&settings))
-      .build()
-      .unwrap()
-      .into();
-    let sample_url = Url::parse("https://gitlab.com/IzzyOnDroid/repo/-/wikis/FAQ").unwrap();
-    let sample_res = fetch_site_metadata(&client, &sample_url).await.unwrap();
-    assert_eq!(
-      SiteMetadata {
-        title: Some("FAQ · Wiki · IzzyOnDroid / repo · GitLab".to_string()),
-        description: Some(
-          "The F-Droid compatible repo at https://apt.izzysoft.de/fdroid/".to_string()
-        ),
-        image: Some(
-          Url::parse("https://gitlab.com/uploads/-/system/project/avatar/4877469/iod_logo.png")
-            .unwrap()
-        ),
-        html: None,
-      },
-      sample_res
-    );
-
-    let youtube_url = Url::parse("https://www.youtube.com/watch?v=IquO_TcMZIQ").unwrap();
-    let youtube_res = fetch_site_metadata(&client, &youtube_url).await.unwrap();
-    assert_eq!(
-      SiteMetadata {
-        title: Some("A Hard Look at Rent and Rent Seeking with Michael Hudson & Pepe Escobar".to_string()),
-        description: Some("An interactive discussion on wealth inequality and the “Great Game” on the control of natural resources.In this webinar organized jointly by the Henry George...".to_string()),
-        image: Some(Url::parse("https://i.ytimg.com/vi/IquO_TcMZIQ/maxresdefault.jpg").unwrap()),
-        html: None,
-      }, youtube_res);
-  }
-
-  // #[test]
-  // fn test_pictshare() {
-  //   let res = fetch_pictshare("https://upload.wikimedia.org/wikipedia/en/2/27/The_Mandalorian_logo.jpg");
-  //   assert!(res.is_ok());
-  //   let res_other = fetch_pictshare("https://upload.wikimedia.org/wikipedia/en/2/27/The_Mandalorian_logo.jpgaoeu");
-  //   assert!(res_other.is_err());
-  // }
-}
index 01c985bcb1a8a1af6046deff09d0978a34617364..79f51eb3c602896342edc62c10c189b3409a1db1 100644 (file)
@@ -15,9 +15,9 @@ doctest = false
 [dependencies]
 lemmy_utils = { version = "=0.16.3", path = "../utils" }
 lemmy_api_common = { version = "=0.16.3", path = "../api_common" }
-lemmy_db_schema = { version = "=0.16.3", path = "../db_schema" }
-lemmy_db_views = { version = "=0.16.3", path = "../db_views" }
-lemmy_db_views_actor = { version = "=0.16.3", path = "../db_views_actor" }
+lemmy_db_schema = { version = "=0.16.3", path = "../db_schema", features = ["full"] }
+lemmy_db_views = { version = "=0.16.3", path = "../db_views", features = ["full"] }
+lemmy_db_views_actor = { version = "=0.16.3", path = "../db_views_actor", features = ["full"] }
 reqwest-middleware = "0.1.5"
 tracing = "0.1.32"
 rand = "0.8.5"
@@ -30,7 +30,7 @@ background-jobs = "0.12.0"
 tokio = "1.17.0"
 strum = "0.24.0"
 strum_macros = "0.24.0"
-chrono = { version = "0.4.19", features = ["serde"] }
+chrono = { version = "0.4.19", features = ["serde"], default-features = false }
 actix-web = { version = "4.0.1", default-features = false, features = ["rustls"] }
 actix-web-actors = { version = "4.1.0", default-features = false }
 opentelemetry = "0.17.0"
index 6085e2450607853b9a5fd8800d081299cf5bb2ac..7fc7b4f63986f70afffe41551a2b999ed0441dab 100644 (file)
@@ -4,7 +4,7 @@ use crate::{
   OperationType,
 };
 use actix::{Actor, Context, Handler, ResponseFuture};
-use lemmy_db_schema::naive_now;
+use lemmy_db_schema::utils::naive_now;
 use lemmy_utils::ConnectionId;
 use opentelemetry::trace::TraceContextExt;
 use rand::Rng;
index 324562180b0854d9ff897a5ce5ece6f8de0e1219..12f9783abc29350ee8ffb2eea026d41fa871dc63 100644 (file)
@@ -4,7 +4,7 @@ extern crate strum_macros;
 use crate::chat_server::ChatServer;
 use actix::Addr;
 use background_jobs::QueueHandle;
-use lemmy_db_schema::{source::secret::Secret, DbPool};
+use lemmy_db_schema::{source::secret::Secret, utils::DbPool};
 use lemmy_utils::{settings::structs::Settings, LemmyError};
 use reqwest_middleware::ClientWithMiddleware;
 use serde::Serialize;
index 1f0677d7d666a5cd550826bdb65a378d88889077..d3a1ed254d5a7175782829c2c2c41a97f4e33bca 100644 (file)
@@ -4,14 +4,11 @@ use crate::{
   OperationType,
 };
 use lemmy_api_common::{
-  blocking,
-  check_person_block,
   comment::CommentResponse,
   community::CommunityResponse,
-  get_user_lang,
   person::PrivateMessageResponse,
   post::PostResponse,
-  send_email_to_user,
+  utils::{blocking, check_person_block, get_user_lang, send_email_to_user},
 };
 use lemmy_db_schema::{
   newtypes::{CommentId, CommunityId, LocalUserId, PersonId, PostId, PrivateMessageId},
@@ -23,13 +20,8 @@ use lemmy_db_schema::{
   },
   traits::{Crud, DeleteableOrRemoveable},
 };
-use lemmy_db_views::{
-  comment_view::CommentView,
-  local_user_view::LocalUserView,
-  post_view::PostView,
-  private_message_view::PrivateMessageView,
-};
-use lemmy_db_views_actor::community_view::CommunityView;
+use lemmy_db_views::structs::{CommentView, LocalUserView, PostView, PrivateMessageView};
+use lemmy_db_views_actor::structs::CommunityView;
 use lemmy_utils::{utils::MentionData, ConnectionId, LemmyError};
 
 #[tracing::instrument(skip_all)]
index 69e419161648456d9961e54c68d2ac7a7dc9b80d..5a0b9eb6decf2539fe867e1a547e393bb3902ee4 100644 (file)
@@ -12,7 +12,6 @@ use lemmy_apub::{
   EndpointType,
 };
 use lemmy_db_schema::{
-  naive_now,
   source::{
     comment::Comment,
     community::{Community, CommunityForm},
@@ -22,6 +21,7 @@ use lemmy_db_schema::{
     site::{Site, SiteForm},
   },
   traits::Crud,
+  utils::naive_now,
 };
 use lemmy_utils::{apub::generate_actor_keypair, LemmyError};
 use tracing::info;
index 9297334e58ceea1c352e986631467c40cc500df1..f304a5fcc8649eabf91998e1ba677ef2a3326917 100644 (file)
@@ -9,10 +9,13 @@ use diesel::{
 };
 use doku::json::{AutoComments, Formatting};
 use lemmy_api::match_websocket_operation;
-use lemmy_api_common::{blocking, check_private_instance_and_federation_enabled};
+use lemmy_api_common::{
+  request::build_user_agent,
+  utils::{blocking, check_private_instance_and_federation_enabled},
+};
 use lemmy_api_crud::match_websocket_operation_crud;
 use lemmy_apub_lib::activity_queue::create_activity_queue;
-use lemmy_db_schema::{get_database_url_from_env, source::secret::Secret};
+use lemmy_db_schema::{source::secret::Secret, utils::get_database_url_from_env};
 use lemmy_routes::{feeds, images, nodeinfo, webfinger};
 use lemmy_server::{
   api_routes,
@@ -23,7 +26,6 @@ use lemmy_server::{
 };
 use lemmy_utils::{
   rate_limit::{rate_limiter::RateLimiter, RateLimit},
-  request::build_user_agent,
   settings::structs::Settings,
   LemmyError,
   REQWEST_TIMEOUT,
index 30e553b5683877b8df949198acde50e0cbe84bd6..32bfd5e8caf4bce452635682438853f463714d28 100644 (file)
@@ -2,7 +2,7 @@
 use clokwerk::{Scheduler, TimeUnits};
 // Import week days and WeekDay
 use diesel::{sql_query, PgConnection, RunQueryDsl};
-use lemmy_db_schema::{source::activity::Activity, DbPool};
+use lemmy_db_schema::{source::activity::Activity, utils::DbPool};
 use lemmy_utils::LemmyError;
 use std::{thread, time::Duration};
 use tracing::info;