diff --git a/.drone.yml b/.drone.yml index 2b4ce8941..7b909482a 100644 --- a/.drone.yml +++ b/.drone.yml @@ -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: diff --git a/Cargo.lock b/Cargo.lock index 2d8136477..da5683553 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -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]] diff --git a/crates/api/Cargo.toml b/crates/api/Cargo.toml index 4cf4f17d2..dfad36fcd 100644 --- a/crates/api/Cargo.toml +++ b/crates/api/Cargo.toml @@ -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 } diff --git a/crates/api/src/comment/like.rs b/crates/api/src/comment/like.rs index a5bb368a9..cc97ebc48 100644 --- a/crates/api/src/comment/like.rs +++ b/crates/api/src/comment/like.rs @@ -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; diff --git a/crates/api/src/comment/mark_as_read.rs b/crates/api/src/comment/mark_as_read.rs index 25c4fb434..a0dc6dd74 100644 --- a/crates/api/src/comment/mark_as_read.rs +++ b/crates/api/src/comment/mark_as_read.rs @@ -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; diff --git a/crates/api/src/comment/save.rs b/crates/api/src/comment/save.rs index 6fc0f4988..1ece524a8 100644 --- a/crates/api/src/comment/save.rs +++ b/crates/api/src/comment/save.rs @@ -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; diff --git a/crates/api/src/comment_report/create.rs b/crates/api/src/comment_report/create.rs index 4f4ef3bb8..75e1323ab 100644 --- a/crates/api/src/comment_report/create.rs +++ b/crates/api/src/comment_report/create.rs @@ -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}; diff --git a/crates/api/src/comment_report/list.rs b/crates/api/src/comment_report/list.rs index b88aced70..296cb8322 100644 --- a/crates/api/src/comment_report/list.rs +++ b/crates/api/src/comment_report/list.rs @@ -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}; diff --git a/crates/api/src/comment_report/resolve.rs b/crates/api/src/comment_report/resolve.rs index 9446fb365..95481ace7 100644 --- a/crates/api/src/comment_report/resolve.rs +++ b/crates/api/src/comment_report/resolve.rs @@ -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}; diff --git a/crates/api/src/community/add_mod.rs b/crates/api/src/community/add_mod.rs index 6e790a0c5..9ea9361a9 100644 --- a/crates/api/src/community/add_mod.rs +++ b/crates/api/src/community/add_mod.rs @@ -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}; diff --git a/crates/api/src/community/ban.rs b/crates/api/src/community/ban.rs index ccdc1b9b7..60fd32270 100644 --- a/crates/api/src/community/ban.rs +++ b/crates/api/src/community/ban.rs @@ -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}; diff --git a/crates/api/src/community/block.rs b/crates/api/src/community/block.rs index 02ece47f5..4f740c916 100644 --- a/crates/api/src/community/block.rs +++ b/crates/api/src/community/block.rs @@ -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; diff --git a/crates/api/src/community/follow.rs b/crates/api/src/community/follow.rs index 62eb34bb9..aab21a9c2 100644 --- a/crates/api/src/community/follow.rs +++ b/crates/api/src/community/follow.rs @@ -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; diff --git a/crates/api/src/community/hide.rs b/crates/api/src/community/hide.rs index a39100100..ddf4f49a1 100644 --- a/crates/api/src/community/hide.rs +++ b/crates/api/src/community/hide.rs @@ -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}; diff --git a/crates/api/src/community/transfer.rs b/crates/api/src/community/transfer.rs index 05282f457..9d8044e3d 100644 --- a/crates/api/src/community/transfer.rs +++ b/crates/api/src/community/transfer.rs @@ -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; diff --git a/crates/api/src/lib.rs b/crates/api/src/lib.rs index d6de25ccb..0c36890bc 100644 --- a/crates/api/src/lib.rs +++ b/crates/api/src/lib.rs @@ -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}; diff --git a/crates/api/src/local_user/add_admin.rs b/crates/api/src/local_user/add_admin.rs index 0630e2417..3834dbbef 100644 --- a/crates/api/src/local_user/add_admin.rs +++ b/crates/api/src/local_user/add_admin.rs @@ -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}; diff --git a/crates/api/src/local_user/ban_person.rs b/crates/api/src/local_user/ban_person.rs index 0397d0904..d357e8eb9 100644 --- a/crates/api/src/local_user/ban_person.rs +++ b/crates/api/src/local_user/ban_person.rs @@ -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}; diff --git a/crates/api/src/local_user/block.rs b/crates/api/src/local_user/block.rs index 5dc68dddc..d0812fd97 100644 --- a/crates/api/src/local_user/block.rs +++ b/crates/api/src/local_user/block.rs @@ -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; diff --git a/crates/api/src/local_user/change_password.rs b/crates/api/src/local_user/change_password.rs index 2b66f2ea9..714659980 100644 --- a/crates/api/src/local_user/change_password.rs +++ b/crates/api/src/local_user/change_password.rs @@ -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}; diff --git a/crates/api/src/local_user/change_password_after_reset.rs b/crates/api/src/local_user/change_password_after_reset.rs index 533a0d193..92e4f6ba5 100644 --- a/crates/api/src/local_user/change_password_after_reset.rs +++ b/crates/api/src/local_user/change_password_after_reset.rs @@ -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, diff --git a/crates/api/src/local_user/get_captcha.rs b/crates/api/src/local_user/get_captcha.rs index efcb6689c..5c691b8ca 100644 --- a/crates/api/src/local_user/get_captcha.rs +++ b/crates/api/src/local_user/get_captcha.rs @@ -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}; diff --git a/crates/api/src/local_user/list_banned.rs b/crates/api/src/local_user/list_banned.rs index 1fef55936..4c39d0cd2 100644 --- a/crates/api/src/local_user/list_banned.rs +++ b/crates/api/src/local_user/list_banned.rs @@ -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; diff --git a/crates/api/src/local_user/login.rs b/crates/api/src/local_user/login.rs index 5455b867d..e1931d5a4 100644 --- a/crates/api/src/local_user/login.rs +++ b/crates/api/src/local_user/login.rs @@ -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; diff --git a/crates/api/src/local_user/notifications/list_mentions.rs b/crates/api/src/local_user/notifications/list_mentions.rs index f47d3cc77..91409b6d3 100644 --- a/crates/api/src/local_user/notifications/list_mentions.rs +++ b/crates/api/src/local_user/notifications/list_mentions.rs @@ -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; diff --git a/crates/api/src/local_user/notifications/list_replies.rs b/crates/api/src/local_user/notifications/list_replies.rs index 9199421c2..1d9aaa2f0 100644 --- a/crates/api/src/local_user/notifications/list_replies.rs +++ b/crates/api/src/local_user/notifications/list_replies.rs @@ -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; diff --git a/crates/api/src/local_user/notifications/mark_all_read.rs b/crates/api/src/local_user/notifications/mark_all_read.rs index dc3b00d1c..d5caa02d5 100644 --- a/crates/api/src/local_user/notifications/mark_all_read.rs +++ b/crates/api/src/local_user/notifications/mark_all_read.rs @@ -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, diff --git a/crates/api/src/local_user/notifications/mark_mention_read.rs b/crates/api/src/local_user/notifications/mark_mention_read.rs index 33e427a66..4c9d06014 100644 --- a/crates/api/src/local_user/notifications/mark_mention_read.rs +++ b/crates/api/src/local_user/notifications/mark_mention_read.rs @@ -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; diff --git a/crates/api/src/local_user/notifications/unread_count.rs b/crates/api/src/local_user/notifications/unread_count.rs index be8055636..a9c06ffc7 100644 --- a/crates/api/src/local_user/notifications/unread_count.rs +++ b/crates/api/src/local_user/notifications/unread_count.rs @@ -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; diff --git a/crates/api/src/local_user/report_count.rs b/crates/api/src/local_user/report_count.rs index 5aa2f46d9..a07f8c055 100644 --- a/crates/api/src/local_user/report_count.rs +++ b/crates/api/src/local_user/report_count.rs @@ -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; diff --git a/crates/api/src/local_user/reset_password.rs b/crates/api/src/local_user/reset_password.rs index 78b0364cd..6903a8b8e 100644 --- a/crates/api/src/local_user/reset_password.rs +++ b/crates/api/src/local_user/reset_password.rs @@ -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; diff --git a/crates/api/src/local_user/save_settings.rs b/crates/api/src/local_user/save_settings.rs index 15a65b01b..cd34d6ddd 100644 --- a/crates/api/src/local_user/save_settings.rs +++ b/crates/api/src/local_user/save_settings.rs @@ -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, diff --git a/crates/api/src/local_user/verify_email.rs b/crates/api/src/local_user/verify_email.rs index 852e1cfa6..c4af8e34e 100644 --- a/crates/api/src/local_user/verify_email.rs +++ b/crates/api/src/local_user/verify_email.rs @@ -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; diff --git a/crates/api/src/post/get_link_metadata.rs b/crates/api/src/post/get_link_metadata.rs index a016bd2f7..db1213324 100644 --- a/crates/api/src/post/get_link_metadata.rs +++ b/crates/api/src/post/get_link_metadata.rs @@ -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)] diff --git a/crates/api/src/post/like.rs b/crates/api/src/post/like.rs index 22eb47754..24d9337c2 100644 --- a/crates/api/src/post/like.rs +++ b/crates/api/src/post/like.rs @@ -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, diff --git a/crates/api/src/post/lock.rs b/crates/api/src/post/lock.rs index 7210d4430..965e506fc 100644 --- a/crates/api/src/post/lock.rs +++ b/crates/api/src/post/lock.rs @@ -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, diff --git a/crates/api/src/post/mark_read.rs b/crates/api/src/post/mark_read.rs index 927fc6515..8777ebced 100644 --- a/crates/api/src/post/mark_read.rs +++ b/crates/api/src/post/mark_read.rs @@ -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; diff --git a/crates/api/src/post/save.rs b/crates/api/src/post/save.rs index 973b99de9..09baec988 100644 --- a/crates/api/src/post/save.rs +++ b/crates/api/src/post/save.rs @@ -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; diff --git a/crates/api/src/post/sticky.rs b/crates/api/src/post/sticky.rs index db6692529..dffe67e33 100644 --- a/crates/api/src/post/sticky.rs +++ b/crates/api/src/post/sticky.rs @@ -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, diff --git a/crates/api/src/post_report/create.rs b/crates/api/src/post_report/create.rs index a85aa9a95..a960e2c53 100644 --- a/crates/api/src/post_report/create.rs +++ b/crates/api/src/post_report/create.rs @@ -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}; diff --git a/crates/api/src/post_report/list.rs b/crates/api/src/post_report/list.rs index 7dfbb1077..7ae0a5ee9 100644 --- a/crates/api/src/post_report/list.rs +++ b/crates/api/src/post_report/list.rs @@ -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}; diff --git a/crates/api/src/post_report/resolve.rs b/crates/api/src/post_report/resolve.rs index f0eb3fdb8..0b50999d2 100644 --- a/crates/api/src/post_report/resolve.rs +++ b/crates/api/src/post_report/resolve.rs @@ -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}; diff --git a/crates/api/src/private_message/mark_read.rs b/crates/api/src/private_message/mark_read.rs index d46280bde..578967836 100644 --- a/crates/api/src/private_message/mark_read.rs +++ b/crates/api/src/private_message/mark_read.rs @@ -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}; diff --git a/crates/api/src/site/config/read.rs b/crates/api/src/site/config/read.rs index 76117d49d..8626fd5f4 100644 --- a/crates/api/src/site/config/read.rs +++ b/crates/api/src/site/config/read.rs @@ -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; diff --git a/crates/api/src/site/config/update.rs b/crates/api/src/site/config/update.rs index b36c69ce7..98f2b1f34 100644 --- a/crates/api/src/site/config/update.rs +++ b/crates/api/src/site/config/update.rs @@ -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; diff --git a/crates/api/src/site/leave_admin.rs b/crates/api/src/site/leave_admin.rs index ee714e86d..10a3adc47 100644 --- a/crates/api/src/site/leave_admin.rs +++ b/crates/api/src/site/leave_admin.rs @@ -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; diff --git a/crates/api/src/site/mod_log.rs b/crates/api/src/site/mod_log.rs index 6dd06c164..45335d5d3 100644 --- a/crates/api/src/site/mod_log.rs +++ b/crates/api/src/site/mod_log.rs @@ -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; diff --git a/crates/api/src/site/registration_applications/approve.rs b/crates/api/src/site/registration_applications/approve.rs index 238da7e51..2e3577de0 100644 --- a/crates/api/src/site/registration_applications/approve.rs +++ b/crates/api/src/site/registration_applications/approve.rs @@ -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; diff --git a/crates/api/src/site/registration_applications/list.rs b/crates/api/src/site/registration_applications/list.rs index bd5170d6a..27633aa64 100644 --- a/crates/api/src/site/registration_applications/list.rs +++ b/crates/api/src/site/registration_applications/list.rs @@ -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; diff --git a/crates/api/src/site/registration_applications/unread_count.rs b/crates/api/src/site/registration_applications/unread_count.rs index 03584baf9..06f995234 100644 --- a/crates/api/src/site/registration_applications/unread_count.rs +++ b/crates/api/src/site/registration_applications/unread_count.rs @@ -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; diff --git a/crates/api/src/site/resolve_object.rs b/crates/api/src/site/resolve_object.rs index 87f3c859a..4e84e162f 100644 --- a/crates/api/src/site/resolve_object.rs +++ b/crates/api/src/site/resolve_object.rs @@ -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; diff --git a/crates/api/src/site/search.rs b/crates/api/src/site/search.rs index f4f998d53..b4d2069c3 100644 --- a/crates/api/src/site/search.rs +++ b/crates/api/src/site/search.rs @@ -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::{ diff --git a/crates/api/src/websocket.rs b/crates/api/src/websocket.rs index 00a7e6867..aea443a96 100644 --- a/crates/api/src/websocket.rs +++ b/crates/api/src/websocket.rs @@ -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}, diff --git a/crates/api_common/Cargo.toml b/crates/api_common/Cargo.toml index 40cd753bc..2ff499227 100644 --- a/crates/api_common/Cargo.toml +++ b/crates/api_common/Cargo.toml @@ -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"] } diff --git a/crates/api_common/src/comment.rs b/crates/api_common/src/comment.rs index 847178000..048a34399 100644 --- a/crates/api_common/src/comment.rs +++ b/crates/api_common/src/comment.rs @@ -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)] diff --git a/crates/api_common/src/community.rs b/crates/api_common/src/community.rs index 49df41fae..0635b9fa0 100644 --- a/crates/api_common/src/community.rs +++ b/crates/api_common/src/community.rs @@ -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)] diff --git a/crates/api_common/src/lib.rs b/crates/api_common/src/lib.rs index 330c75bd0..0dda34ec5 100644 --- a/crates/api_common/src/lib.rs +++ b/crates/api_common/src/lib.rs @@ -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(pool: &DbPool, f: F) -> Result -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 - }) - .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 { - 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 { - 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 { - 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 { - 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>, - pool: &DbPool, - secret: &Secret, -) -> Result, 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, - pool: &DbPool, - secret: &Secret, -) -> Result { - 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>, - pool: &DbPool, - secret: &Secret, -) -> Result, 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, - 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, 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::, 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) -> 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(®istration_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 = 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) -> 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(()) -} diff --git a/crates/api_common/src/person.rs b/crates/api_common/src/person.rs index 898efbf5d..3bc09f774 100644 --- a/crates/api_common/src/person.rs +++ b/crates/api_common/src/person.rs @@ -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)] diff --git a/crates/api_common/src/post.rs b/crates/api_common/src/post.rs index 7f8ea3199..afab5e305 100644 --- a/crates/api_common/src/post.rs +++ b/crates/api_common/src/post.rs @@ -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, + pub description: Option, + pub(crate) image: Option, + pub html: Option, +} diff --git a/crates/api_common/src/request.rs b/crates/api_common/src/request.rs new file mode 100644 index 000000000..7e3b2152c --- /dev/null +++ b/crates/api_common/src/request.rs @@ -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 { + 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 { + 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("") { + 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, + 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 { + 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, Option) { + 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()); + // } +} diff --git a/crates/utils/src/sensitive.rs b/crates/api_common/src/sensitive.rs similarity index 90% rename from crates/utils/src/sensitive.rs rename to crates/api_common/src/sensitive.rs index c71f357e2..7713bc826 100644 --- a/crates/utils/src/sensitive.rs +++ b/crates/api_common/src/sensitive.rs @@ -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); @@ -12,8 +13,8 @@ impl Sensitive { Sensitive(item) } - pub fn into_inner(this: Self) -> T { - this.0 + pub fn into_inner(self) -> T { + self.0 } } diff --git a/crates/api_common/src/site.rs b/crates/api_common/src/site.rs index f7329822b..da17eb050 100644 --- a/crates/api_common/src/site.rs +++ b/crates/api_common/src/site.rs @@ -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 index 000000000..38ea9a865 --- /dev/null +++ b/crates/api_common/src/utils.rs @@ -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(pool: &DbPool, f: F) -> Result +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 + }) + .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 { + 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 { + 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 { + 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 { + 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>, + pool: &DbPool, + secret: &Secret, +) -> Result, 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, + pool: &DbPool, + secret: &Secret, +) -> Result { + 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>, + pool: &DbPool, + secret: &Secret, +) -> Result, 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, + 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, 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::, 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) -> 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(®istration_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 = 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) -> 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(()) +} diff --git a/crates/api_common/src/websocket.rs b/crates/api_common/src/websocket.rs index 066655124..80729fcc7 100644 --- a/crates/api_common/src/websocket.rs +++ b/crates/api_common/src/websocket.rs @@ -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)] diff --git a/crates/api_crud/Cargo.toml b/crates/api_crud/Cargo.toml index 523da0ac8..f808ea63b 100644 --- a/crates/api_crud/Cargo.toml +++ b/crates/api_crud/Cargo.toml @@ -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"] } diff --git a/crates/api_crud/src/comment/create.rs b/crates/api_crud/src/comment/create.rs index ac3744661..12e208e8c 100644 --- a/crates/api_crud/src/comment/create.rs +++ b/crates/api_crud/src/comment/create.rs @@ -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, diff --git a/crates/api_crud/src/comment/delete.rs b/crates/api_crud/src/comment/delete.rs index 9ed58946d..f4fb5d405 100644 --- a/crates/api_crud/src/comment/delete.rs +++ b/crates/api_crud/src/comment/delete.rs @@ -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, - websocket_id: Option, - ) -> Result { - 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) - } -} diff --git a/crates/api_crud/src/comment/list.rs b/crates/api_crud/src/comment/list.rs index cd91a3b0b..ab9e25f15 100644 --- a/crates/api_crud/src/comment/list.rs +++ b/crates/api_crud/src/comment/list.rs @@ -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}; diff --git a/crates/api_crud/src/comment/mod.rs b/crates/api_crud/src/comment/mod.rs index 7003bdd86..1e8328034 100644 --- a/crates/api_crud/src/comment/mod.rs +++ b/crates/api_crud/src/comment/mod.rs @@ -2,4 +2,5 @@ mod create; mod delete; mod list; mod read; +mod remove; mod update; diff --git a/crates/api_crud/src/comment/read.rs b/crates/api_crud/src/comment/read.rs index 5b2155da0..fd248cafe 100644 --- a/crates/api_crud/src/comment/read.rs +++ b/crates/api_crud/src/comment/read.rs @@ -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 index 000000000..837407c56 --- /dev/null +++ b/crates/api_crud/src/comment/remove.rs @@ -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, + websocket_id: Option, + ) -> Result { + 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) + } +} diff --git a/crates/api_crud/src/comment/update.rs b/crates/api_crud/src/comment/update.rs index 4fede1454..06065c89a 100644 --- a/crates/api_crud/src/comment/update.rs +++ b/crates/api_crud/src/comment/update.rs @@ -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, diff --git a/crates/api_crud/src/community/create.rs b/crates/api_crud/src/community/create.rs index 8d68d554d..6838216ff 100644 --- a/crates/api_crud/src/community/create.rs +++ b/crates/api_crud/src/community/create.rs @@ -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}, diff --git a/crates/api_crud/src/community/delete.rs b/crates/api_crud/src/community/delete.rs index b8a2f2309..f42e9b01d 100644 --- a/crates/api_crud/src/community/delete.rs +++ b/crates/api_crud/src/community/delete.rs @@ -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, - websocket_id: Option, - ) -> Result { - 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) - } -} diff --git a/crates/api_crud/src/community/list.rs b/crates/api_crud/src/community/list.rs index 24c154ad2..fac41c66f 100644 --- a/crates/api_crud/src/community/list.rs +++ b/crates/api_crud/src/community/list.rs @@ -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}; diff --git a/crates/api_crud/src/community/mod.rs b/crates/api_crud/src/community/mod.rs index 7003bdd86..1e8328034 100644 --- a/crates/api_crud/src/community/mod.rs +++ b/crates/api_crud/src/community/mod.rs @@ -2,4 +2,5 @@ mod create; mod delete; mod list; mod read; +mod remove; mod update; diff --git a/crates/api_crud/src/community/read.rs b/crates/api_crud/src/community/read.rs index 9c4ba333c..16eee4692 100644 --- a/crates/api_crud/src/community/read.rs +++ b/crates/api_crud/src/community/read.rs @@ -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 index 000000000..7ca9b73fa --- /dev/null +++ b/crates/api_crud/src/community/remove.rs @@ -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, + websocket_id: Option, + ) -> Result { + 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) + } +} diff --git a/crates/api_crud/src/community/update.rs b/crates/api_crud/src/community/update.rs index 4df708fcc..4c7fa8ce6 100644 --- a/crates/api_crud/src/community/update.rs +++ b/crates/api_crud/src/community/update.rs @@ -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}; diff --git a/crates/api_crud/src/post/create.rs b/crates/api_crud/src/post/create.rs index eb162e013..353e186ad 100644 --- a/crates/api_crud/src/post/create.rs +++ b/crates/api_crud/src/post/create.rs @@ -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, diff --git a/crates/api_crud/src/post/delete.rs b/crates/api_crud/src/post/delete.rs index 05c395b5b..f880b4b5d 100644 --- a/crates/api_crud/src/post/delete.rs +++ b/crates/api_crud/src/post/delete.rs @@ -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, - websocket_id: Option, - ) -> Result { - 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) - } -} diff --git a/crates/api_crud/src/post/list.rs b/crates/api_crud/src/post/list.rs index 154faaaaf..4b871e54f 100644 --- a/crates/api_crud/src/post/list.rs +++ b/crates/api_crud/src/post/list.rs @@ -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}; diff --git a/crates/api_crud/src/post/mod.rs b/crates/api_crud/src/post/mod.rs index 7003bdd86..1e8328034 100644 --- a/crates/api_crud/src/post/mod.rs +++ b/crates/api_crud/src/post/mod.rs @@ -2,4 +2,5 @@ mod create; mod delete; mod list; mod read; +mod remove; mod update; diff --git a/crates/api_crud/src/post/read.rs b/crates/api_crud/src/post/read.rs index 03507ba4d..a5ca262fa 100644 --- a/crates/api_crud/src/post/read.rs +++ b/crates/api_crud/src/post/read.rs @@ -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 index 000000000..7e50159c9 --- /dev/null +++ b/crates/api_crud/src/post/remove.rs @@ -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, + websocket_id: Option, + ) -> Result { + 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) + } +} diff --git a/crates/api_crud/src/post/update.rs b/crates/api_crud/src/post/update.rs index fa19c2c9b..16f2fea40 100644 --- a/crates/api_crud/src/post/update.rs +++ b/crates/api_crud/src/post/update.rs @@ -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, diff --git a/crates/api_crud/src/private_message/create.rs b/crates/api_crud/src/private_message/create.rs index 44999cf00..de711128d 100644 --- a/crates/api_crud/src/private_message/create.rs +++ b/crates/api_crud/src/private_message/create.rs @@ -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}; diff --git a/crates/api_crud/src/private_message/delete.rs b/crates/api_crud/src/private_message/delete.rs index 00b3ff50e..af06094eb 100644 --- a/crates/api_crud/src/private_message/delete.rs +++ b/crates/api_crud/src/private_message/delete.rs @@ -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}; diff --git a/crates/api_crud/src/private_message/read.rs b/crates/api_crud/src/private_message/read.rs index 48ff239c7..ce03200c6 100644 --- a/crates/api_crud/src/private_message/read.rs +++ b/crates/api_crud/src/private_message/read.rs @@ -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; diff --git a/crates/api_crud/src/private_message/update.rs b/crates/api_crud/src/private_message/update.rs index 5f23f1bcd..aebd5b8be 100644 --- a/crates/api_crud/src/private_message/update.rs +++ b/crates/api_crud/src/private_message/update.rs @@ -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, diff --git a/crates/api_crud/src/site/create.rs b/crates/api_crud/src/site/create.rs index 7ec772b91..b9b3b6013 100644 --- a/crates/api_crud/src/site/create.rs +++ b/crates/api_crud/src/site/create.rs @@ -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, diff --git a/crates/api_crud/src/site/read.rs b/crates/api_crud/src/site/read.rs index 17c838964..f9fe75c73 100644 --- a/crates/api_crud/src/site/read.rs +++ b/crates/api_crud/src/site/read.rs @@ -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}; diff --git a/crates/api_crud/src/site/update.rs b/crates/api_crud/src/site/update.rs index a6890d266..ace19fd72 100644 --- a/crates/api_crud/src/site/update.rs +++ b/crates/api_crud/src/site/update.rs @@ -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}; diff --git a/crates/api_crud/src/user/create.rs b/crates/api_crud/src/user/create.rs index 00ef7db64..456617043 100644 --- a/crates/api_crud/src/user/create.rs +++ b/crates/api_crud/src/user/create.rs @@ -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, diff --git a/crates/api_crud/src/user/delete.rs b/crates/api_crud/src/user/delete.rs index ea1cbcff5..c5e0e2197 100644 --- a/crates/api_crud/src/user/delete.rs +++ b/crates/api_crud/src/user/delete.rs @@ -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; diff --git a/crates/api_crud/src/user/read.rs b/crates/api_crud/src/user/read.rs index 839f46f2c..4b54430da 100644 --- a/crates/api_crud/src/user/read.rs +++ b/crates/api_crud/src/user/read.rs @@ -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; diff --git a/crates/apub/Cargo.toml b/crates/apub/Cargo.toml index 7fa3e175e..999964e2b 100644 --- a/crates/apub/Cargo.toml +++ b/crates/apub/Cargo.toml @@ -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" diff --git a/crates/apub/src/activities/block/block_user.rs b/crates/apub/src/activities/block/block_user.rs index d21c038be..bcab3148a 100644 --- a/crates/apub/src/activities/block/block_user.rs +++ b/crates/apub/src/activities/block/block_user.rs @@ -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, diff --git a/crates/apub/src/activities/block/mod.rs b/crates/apub/src/activities/block/mod.rs index f41e352f6..bb35d7d21 100644 --- a/crates/apub/src/activities/block/mod.rs +++ b/crates/apub/src/activities/block/mod.rs @@ -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; diff --git a/crates/apub/src/activities/block/undo_block_user.rs b/crates/apub/src/activities/block/undo_block_user.rs index 29c9cd10e..130b1eb50 100644 --- a/crates/apub/src/activities/block/undo_block_user.rs +++ b/crates/apub/src/activities/block/undo_block_user.rs @@ -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, diff --git a/crates/apub/src/activities/community/add_mod.rs b/crates/apub/src/activities/community/add_mod.rs index a86c8ac31..2aa7989ee 100644 --- a/crates/apub/src/activities/community/add_mod.rs +++ b/crates/apub/src/activities/community/add_mod.rs @@ -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, diff --git a/crates/apub/src/activities/community/remove_mod.rs b/crates/apub/src/activities/community/remove_mod.rs index 7e43fcbf7..f42d47f63 100644 --- a/crates/apub/src/activities/community/remove_mod.rs +++ b/crates/apub/src/activities/community/remove_mod.rs @@ -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, diff --git a/crates/apub/src/activities/community/report.rs b/crates/apub/src/activities/community/report.rs index 5ebbd9d7d..0069aa6e6 100644 --- a/crates/apub/src/activities/community/report.rs +++ b/crates/apub/src/activities/community/report.rs @@ -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}; diff --git a/crates/apub/src/activities/community/update.rs b/crates/apub/src/activities/community/update.rs index f260363bb..e6676b8bf 100644 --- a/crates/apub/src/activities/community/update.rs +++ b/crates/apub/src/activities/community/update.rs @@ -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, diff --git a/crates/apub/src/activities/create_or_update/comment.rs b/crates/apub/src/activities/create_or_update/comment.rs index ed95b931b..c0e53a607 100644 --- a/crates/apub/src/activities/create_or_update/comment.rs +++ b/crates/apub/src/activities/create_or_update/comment.rs @@ -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, diff --git a/crates/apub/src/activities/create_or_update/mod.rs b/crates/apub/src/activities/create_or_update/mod.rs index 3cdac71b2..99305f24c 100644 --- a/crates/apub/src/activities/create_or_update/mod.rs +++ b/crates/apub/src/activities/create_or_update/mod.rs @@ -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, diff --git a/crates/apub/src/activities/create_or_update/post.rs b/crates/apub/src/activities/create_or_update/post.rs index ddbe0981b..70c59c35c 100644 --- a/crates/apub/src/activities/create_or_update/post.rs +++ b/crates/apub/src/activities/create_or_update/post.rs @@ -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, diff --git a/crates/apub/src/activities/create_or_update/private_message.rs b/crates/apub/src/activities/create_or_update/private_message.rs index bae430475..295e5b4f1 100644 --- a/crates/apub/src/activities/create_or_update/private_message.rs +++ b/crates/apub/src/activities/create_or_update/private_message.rs @@ -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, diff --git a/crates/apub/src/activities/deletion/delete.rs b/crates/apub/src/activities/deletion/delete.rs index 275683a37..3f0215875 100644 --- a/crates/apub/src/activities/deletion/delete.rs +++ b/crates/apub/src/activities/deletion/delete.rs @@ -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::{ diff --git a/crates/apub/src/activities/deletion/delete_user.rs b/crates/apub/src/activities/deletion/delete_user.rs index 0cd2c5010..a96333d5e 100644 --- a/crates/apub/src/activities/deletion/delete_user.rs +++ b/crates/apub/src/activities/deletion/delete_user.rs @@ -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, diff --git a/crates/apub/src/activities/deletion/mod.rs b/crates/apub/src/activities/deletion/mod.rs index 1ff8429aa..123e87fbd 100644 --- a/crates/apub/src/activities/deletion/mod.rs +++ b/crates/apub/src/activities/deletion/mod.rs @@ -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}, diff --git a/crates/apub/src/activities/deletion/undo_delete.rs b/crates/apub/src/activities/deletion/undo_delete.rs index 6dced4395..34e897479 100644 --- a/crates/apub/src/activities/deletion/undo_delete.rs +++ b/crates/apub/src/activities/deletion/undo_delete.rs @@ -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::{ diff --git a/crates/apub/src/activities/following/accept.rs b/crates/apub/src/activities/following/accept.rs index 690bec28f..dfc008a94 100644 --- a/crates/apub/src/activities/following/accept.rs +++ b/crates/apub/src/activities/following/accept.rs @@ -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, diff --git a/crates/apub/src/activities/following/follow.rs b/crates/apub/src/activities/following/follow.rs index fb35b0d32..d46b3dc20 100644 --- a/crates/apub/src/activities/following/follow.rs +++ b/crates/apub/src/activities/following/follow.rs @@ -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, diff --git a/crates/apub/src/activities/following/undo_follow.rs b/crates/apub/src/activities/following/undo_follow.rs index 73b0366bc..f70acdf27 100644 --- a/crates/apub/src/activities/following/undo_follow.rs +++ b/crates/apub/src/activities/following/undo_follow.rs @@ -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, diff --git a/crates/apub/src/activities/mod.rs b/crates/apub/src/activities/mod.rs index 77d4883f0..2c8b0921c 100644 --- a/crates/apub/src/activities/mod.rs +++ b/crates/apub/src/activities/mod.rs @@ -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; diff --git a/crates/apub/src/activities/voting/mod.rs b/crates/apub/src/activities/voting/mod.rs index c82b4efd4..f2e3f24f8 100644 --- a/crates/apub/src/activities/voting/mod.rs +++ b/crates/apub/src/activities/voting/mod.rs @@ -1,4 +1,4 @@ -use lemmy_api_common::blocking; +use lemmy_api_common::utils::blocking; use lemmy_db_schema::{ source::{ comment::{CommentLike, CommentLikeForm}, diff --git a/crates/apub/src/activities/voting/undo_vote.rs b/crates/apub/src/activities/voting/undo_vote.rs index 16ea64e00..eb350770e 100644 --- a/crates/apub/src/activities/voting/undo_vote.rs +++ b/crates/apub/src/activities/voting/undo_vote.rs @@ -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, diff --git a/crates/apub/src/activities/voting/vote.rs b/crates/apub/src/activities/voting/vote.rs index ce6dee28f..a851e28f4 100644 --- a/crates/apub/src/activities/voting/vote.rs +++ b/crates/apub/src/activities/voting/vote.rs @@ -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, diff --git a/crates/apub/src/collections/community_moderators.rs b/crates/apub/src/collections/community_moderators.rs index b0182bdf2..4e084a165 100644 --- a/crates/apub/src/collections/community_moderators.rs +++ b/crates/apub/src/collections/community_moderators.rs @@ -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; diff --git a/crates/apub/src/collections/community_outbox.rs b/crates/apub/src/collections/community_outbox.rs index 769e9bb2f..098471c26 100644 --- a/crates/apub/src/collections/community_outbox.rs +++ b/crates/apub/src/collections/community_outbox.rs @@ -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}, diff --git a/crates/apub/src/fetcher/deletable_apub_object.rs b/crates/apub/src/fetcher/deletable_apub_object.rs index ccb409e8d..2eb4f8849 100644 --- a/crates/apub/src/fetcher/deletable_apub_object.rs +++ b/crates/apub/src/fetcher/deletable_apub_object.rs @@ -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_, diff --git a/crates/apub/src/fetcher/mod.rs b/crates/apub/src/fetcher/mod.rs index 16173568e..cd889ccc6 100644 --- a/crates/apub/src/fetcher/mod.rs +++ b/crates/apub/src/fetcher/mod.rs @@ -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}; diff --git a/crates/apub/src/fetcher/webfinger.rs b/crates/apub/src/fetcher/webfinger.rs index e2370c329..da516b1da 100644 --- a/crates/apub/src/fetcher/webfinger.rs +++ b/crates/apub/src/fetcher/webfinger.rs @@ -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 = res .links diff --git a/crates/apub/src/http/comment.rs b/crates/apub/src/http/comment.rs index 6a7243435..1918a38e8 100644 --- a/crates/apub/src/http/comment.rs +++ b/crates/apub/src/http/comment.rs @@ -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; diff --git a/crates/apub/src/http/community.rs b/crates/apub/src/http/community.rs index c049c6aef..41f6d1c0b 100644 --- a/crates/apub/src/http/community.rs +++ b/crates/apub/src/http/community.rs @@ -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; diff --git a/crates/apub/src/http/mod.rs b/crates/apub/src/http/mod.rs index 477357e04..0112d2056 100644 --- a/crates/apub/src/http/mod.rs +++ b/crates/apub/src/http/mod.rs @@ -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, diff --git a/crates/apub/src/http/person.rs b/crates/apub/src/http/person.rs index 9081d5a55..f0540268a 100644 --- a/crates/apub/src/http/person.rs +++ b/crates/apub/src/http/person.rs @@ -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; diff --git a/crates/apub/src/http/post.rs b/crates/apub/src/http/post.rs index 3f180a0c8..845803b90 100644 --- a/crates/apub/src/http/post.rs +++ b/crates/apub/src/http/post.rs @@ -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; diff --git a/crates/apub/src/http/site.rs b/crates/apub/src/http/site.rs index 894622ad6..e48110663 100644 --- a/crates/apub/src/http/site.rs +++ b/crates/apub/src/http/site.rs @@ -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}; diff --git a/crates/apub/src/lib.rs b/crates/apub/src/lib.rs index 80116a8f8..b7f1912d8 100644 --- a/crates/apub/src/lib.rs +++ b/crates/apub/src/lib.rs @@ -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; diff --git a/crates/apub/src/mentions.rs b/crates/apub/src/mentions.rs index 78d568e51..b68391a98 100644 --- a/crates/apub/src/mentions.rs +++ b/crates/apub/src/mentions.rs @@ -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 index 8b1378917..000000000 --- a/crates/apub/src/migrations.rs +++ /dev/null @@ -1 +0,0 @@ - diff --git a/crates/apub/src/objects/comment.rs b/crates/apub/src/objects/comment.rs index 40aef9197..c987ff8bd 100644 --- a/crates/apub/src/objects/comment.rs +++ b/crates/apub/src/objects/comment.rs @@ -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, diff --git a/crates/apub/src/objects/community.rs b/crates/apub/src/objects/community.rs index 59489d3e4..a8904ac58 100644 --- a/crates/apub/src/objects/community.rs +++ b/crates/apub/src/objects/community.rs @@ -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, diff --git a/crates/apub/src/objects/instance.rs b/crates/apub/src/objects/instance.rs index c3641fca9..225a10912 100644 --- a/crates/apub/src/objects/instance.rs +++ b/crates/apub/src/objects/instance.rs @@ -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}, diff --git a/crates/apub/src/objects/mod.rs b/crates/apub/src/objects/mod.rs index e7155b4b1..0e55c49da 100644 --- a/crates/apub/src/objects/mod.rs +++ b/crates/apub/src/objects/mod.rs @@ -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, }; diff --git a/crates/apub/src/objects/person.rs b/crates/apub/src/objects/person.rs index 039dbbb13..e1938ed3d 100644 --- a/crates/apub/src/objects/person.rs +++ b/crates/apub/src/objects/person.rs @@ -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}, diff --git a/crates/apub/src/objects/post.rs b/crates/apub/src/objects/post.rs index 88ca1ceb0..f6938dd6e 100644 --- a/crates/apub/src/objects/post.rs +++ b/crates/apub/src/objects/post.rs @@ -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, }; diff --git a/crates/apub/src/objects/private_message.rs b/crates/apub/src/objects/private_message.rs index 560059865..7a638af32 100644 --- a/crates/apub/src/objects/private_message.rs +++ b/crates/apub/src/objects/private_message.rs @@ -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, diff --git a/crates/apub/src/protocol/collections/group_followers.rs b/crates/apub/src/protocol/collections/group_followers.rs index 032731b73..777d19803 100644 --- a/crates/apub/src/protocol/collections/group_followers.rs +++ b/crates/apub/src/protocol/collections/group_followers.rs @@ -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}; diff --git a/crates/apub/src/protocol/objects/group.rs b/crates/apub/src/protocol/objects/group.rs index 57d0ae157..c0b544f37 100644 --- a/crates/apub/src/protocol/objects/group.rs +++ b/crates/apub/src/protocol/objects/group.rs @@ -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, diff --git a/crates/apub/src/protocol/objects/note.rs b/crates/apub/src/protocol/objects/note.rs index b1c4b5d07..779675cc1 100644 --- a/crates/apub/src/protocol/objects/note.rs +++ b/crates/apub/src/protocol/objects/note.rs @@ -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; diff --git a/crates/apub_lib/Cargo.toml b/crates/apub_lib/Cargo.toml index 1b2cabbf4..366ee7a0f 100644 --- a/crates/apub_lib/Cargo.toml +++ b/crates/apub_lib/Cargo.toml @@ -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"] } diff --git a/crates/db_schema/Cargo.toml b/crates/db_schema/Cargo.toml index 0ee7dd5ad..b2e40ed8e 100644 --- a/crates/db_schema/Cargo.toml +++ b/crates/db_schema/Cargo.toml @@ -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" diff --git a/crates/db_schema/src/aggregates/comment_aggregates.rs b/crates/db_schema/src/aggregates/comment_aggregates.rs index d47899bbf..5e70bcc5f 100644 --- a/crates/db_schema/src/aggregates/comment_aggregates.rs +++ b/crates/db_schema/src/aggregates/comment_aggregates.rs @@ -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 { @@ -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; diff --git a/crates/db_schema/src/aggregates/community_aggregates.rs b/crates/db_schema/src/aggregates/community_aggregates.rs index d80425e17..950e68d37 100644 --- a/crates/db_schema/src/aggregates/community_aggregates.rs +++ b/crates/db_schema/src/aggregates/community_aggregates.rs @@ -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 { @@ -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; diff --git a/crates/db_schema/src/aggregates/mod.rs b/crates/db_schema/src/aggregates/mod.rs index ad20f8a66..03ab1b89a 100644 --- a/crates/db_schema/src/aggregates/mod.rs +++ b/crates/db_schema/src/aggregates/mod.rs @@ -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; diff --git a/crates/db_schema/src/aggregates/person_aggregates.rs b/crates/db_schema/src/aggregates/person_aggregates.rs index e0fc0734c..0f270f9cb 100644 --- a/crates/db_schema/src/aggregates/person_aggregates.rs +++ b/crates/db_schema/src/aggregates/person_aggregates.rs @@ -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 { @@ -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; diff --git a/crates/db_schema/src/aggregates/post_aggregates.rs b/crates/db_schema/src/aggregates/post_aggregates.rs index cb8aba26e..3d1a27290 100644 --- a/crates/db_schema/src/aggregates/post_aggregates.rs +++ b/crates/db_schema/src/aggregates/post_aggregates.rs @@ -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 { @@ -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; diff --git a/crates/db_schema/src/aggregates/site_aggregates.rs b/crates/db_schema/src/aggregates/site_aggregates.rs index 745097dfe..8cf57dfd8 100644 --- a/crates/db_schema/src/aggregates/site_aggregates.rs +++ b/crates/db_schema/src/aggregates/site_aggregates.rs @@ -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 { @@ -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 index 000000000..2f635b9e6 --- /dev/null +++ b/crates/db_schema/src/aggregates/structs.rs @@ -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, +} diff --git a/crates/db_schema/src/impls/activity.rs b/crates/db_schema/src/impls/activity.rs index 261a89cbe..48429315e 100644 --- a/crates/db_schema/src/impls/activity.rs +++ b/crates/db_schema/src/impls/activity.rs @@ -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; diff --git a/crates/db_schema/src/impls/comment.rs b/crates/db_schema/src/impls/comment.rs index 09389aad8..5fb3280c9 100644 --- a/crates/db_schema/src/impls/comment.rs +++ b/crates/db_schema/src/impls/comment.rs @@ -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; diff --git a/crates/db_schema/src/impls/comment_report.rs b/crates/db_schema/src/impls/comment_report.rs index d32f3ef40..56e917e02 100644 --- a/crates/db_schema/src/impls/comment_report.rs +++ b/crates/db_schema/src/impls/comment_report.rs @@ -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, *}; diff --git a/crates/db_schema/src/impls/community.rs b/crates/db_schema/src/impls/community.rs index fb8bd6e4a..14a670f51 100644 --- a/crates/db_schema/src/impls/community.rs +++ b/crates/db_schema/src/impls/community.rs @@ -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; diff --git a/crates/db_schema/src/impls/local_user.rs b/crates/db_schema/src/impls/local_user.rs index 833d6bdb9..419ab7928 100644 --- a/crates/db_schema/src/impls/local_user.rs +++ b/crates/db_schema/src/impls/local_user.rs @@ -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, *}; diff --git a/crates/db_schema/src/impls/moderator.rs b/crates/db_schema/src/impls/moderator.rs index 696dbe0a4..36582d109 100644 --- a/crates/db_schema/src/impls/moderator.rs +++ b/crates/db_schema/src/impls/moderator.rs @@ -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; diff --git a/crates/db_schema/src/impls/password_reset_request.rs b/crates/db_schema/src/impls/password_reset_request.rs index 808f0ac01..576e26739 100644 --- a/crates/db_schema/src/impls/password_reset_request.rs +++ b/crates/db_schema/src/impls/password_reset_request.rs @@ -70,13 +70,13 @@ fn bytes_to_hex(bytes: Vec) -> 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; diff --git a/crates/db_schema/src/impls/person.rs b/crates/db_schema/src/impls/person.rs index 165d9308e..c59126c32 100644 --- a/crates/db_schema/src/impls/person.rs +++ b/crates/db_schema/src/impls/person.rs @@ -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() { diff --git a/crates/db_schema/src/impls/person_mention.rs b/crates/db_schema/src/impls/person_mention.rs index df0e55ede..c8fb6cc09 100644 --- a/crates/db_schema/src/impls/person_mention.rs +++ b/crates/db_schema/src/impls/person_mention.rs @@ -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; diff --git a/crates/db_schema/src/impls/post.rs b/crates/db_schema/src/impls/post.rs index 9a8bbcece..c878931a1 100644 --- a/crates/db_schema/src/impls/post.rs +++ b/crates/db_schema/src/impls/post.rs @@ -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; diff --git a/crates/db_schema/src/impls/post_report.rs b/crates/db_schema/src/impls/post_report.rs index d049fbced..58e2f44b0 100644 --- a/crates/db_schema/src/impls/post_report.rs +++ b/crates/db_schema/src/impls/post_report.rs @@ -1,8 +1,8 @@ use crate::{ - naive_now, newtypes::{PersonId, PostReportId}, source::post_report::*, traits::Reportable, + utils::naive_now, }; use diesel::{dsl::*, result::Error, *}; diff --git a/crates/db_schema/src/impls/private_message.rs b/crates/db_schema/src/impls/private_message.rs index 6a2e9ee84..e90ae5248 100644 --- a/crates/db_schema/src/impls/private_message.rs +++ b/crates/db_schema/src/impls/private_message.rs @@ -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; diff --git a/crates/db_schema/src/impls/site.rs b/crates/db_schema/src/impls/site.rs index 60d2c013c..6c71f076e 100644 --- a/crates/db_schema/src/impls/site.rs +++ b/crates/db_schema/src/impls/site.rs @@ -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; diff --git a/crates/db_schema/src/lib.rs b/crates/db_schema/src/lib.rs index bd6e0d190..e6dee1993 100644 --- a/crates/db_schema/src/lib.rs +++ b/crates/db_schema/src/lib.rs @@ -1,197 +1,26 @@ +#[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>; - -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 { - 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(opt: &Option) -> Option { - 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, limit: Option) -> (i64, i64) { - let page = page.unwrap_or(1); - let limit = limit.unwrap_or(10); - let offset = limit * (page - 1); - (limit, offset) -} - -pub fn is_email_regex(test: &str) -> bool { - EMAIL_REGEX.is_match(test) -} - -pub fn diesel_option_overwrite(opt: &Option) -> Option> { - match opt { - // An empty string is an erase - Some(unwrapped) => { - if !unwrapped.eq("") { - Some(Some(unwrapped.to_owned())) - } else { - Some(None) - } - } - None => None, - } -} - -pub fn diesel_option_overwrite_to_url( - opt: &Option, -) -> Result>, 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 = 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; diff --git a/crates/db_schema/src/newtypes.rs b/crates/db_schema/src/newtypes.rs index 3e68768bc..946007a3f 100644 --- a/crates/db_schema/src/newtypes.rs +++ b/crates/db_schema/src/newtypes.rs @@ -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 ToSql for DbUrl -where - String: ToSql, -{ - fn to_sql(&self, out: &mut Output) -> diesel::serialize::Result { - self.0.to_string().to_sql(out) - } -} - -impl FromSql for DbUrl -where - String: FromSql, -{ - fn from_sql(bytes: Option<&DB::RawValue>) -> diesel::deserialize::Result { - let str = String::from_sql(bytes)?; - Ok(DbUrl(Url::parse(&str)?)) - } -} +#[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 for DbUrl { } } -impl From> for DbUrl -where - Kind: ApubObject + Send + 'static, - for<'de2> ::ApubType: serde::Deserialize<'de2>, -{ - fn from(id: ObjectId) -> Self { - DbUrl(id.into()) - } -} - impl Deref for DbUrl { type Target = Url; diff --git a/crates/db_schema/src/source/activity.rs b/crates/db_schema/src/source/activity.rs index 5bdeb1db2..5d09ebfd5 100644 --- a/crates/db_schema/src/source/activity.rs +++ b/crates/db_schema/src/source/activity.rs @@ -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, diff --git a/crates/db_schema/src/source/comment.rs b/crates/db_schema/src/source/comment.rs index 46242fc73..33fd72c54 100644 --- a/crates/db_schema/src/source/comment.rs +++ b/crates/db_schema/src/source/comment.rs @@ -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, } -#[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, diff --git a/crates/db_schema/src/source/comment_report.rs b/crates/db_schema/src/source/comment_report.rs index 3c265ed09..256895760 100644 --- a/crates/db_schema/src/source/comment_report.rs +++ b/crates/db_schema/src/source/comment_report.rs @@ -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, } -#[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, diff --git a/crates/db_schema/src/source/community.rs b/crates/db_schema/src/source/community.rs index 3e8bbf171..7693f2f41 100644 --- a/crates/db_schema/src/source/community.rs +++ b/crates/db_schema/src/source/community.rs @@ -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, } -#[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, } -#[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>, } -#[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, } -#[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, diff --git a/crates/db_schema/src/source/community_block.rs b/crates/db_schema/src/source/community_block.rs index f5cc545e8..d2c40a336 100644 --- a/crates/db_schema/src/source/community_block.rs +++ b/crates/db_schema/src/source/community_block.rs @@ -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, diff --git a/crates/db_schema/src/source/email_verification.rs b/crates/db_schema/src/source/email_verification.rs index e36f29012..8d63670f2 100644 --- a/crates/db_schema/src/source/email_verification.rs +++ b/crates/db_schema/src/source/email_verification.rs @@ -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, diff --git a/crates/db_schema/src/source/local_user.rs b/crates/db_schema/src/source/local_user.rs index 88defa6db..57767bb17 100644 --- a/crates/db_schema/src/source/local_user.rs +++ b/crates/db_schema/src/source/local_user.rs @@ -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, pub password_encrypted: Option, @@ -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, diff --git a/crates/db_schema/src/source/mod.rs b/crates/db_schema/src/source/mod.rs index c96e3a623..f2ff5f78e 100644 --- a/crates/db_schema/src/source/mod.rs +++ b/crates/db_schema/src/source/mod.rs @@ -1,3 +1,4 @@ +#[cfg(feature = "full")] pub mod activity; pub mod comment; pub mod comment_report; diff --git a/crates/db_schema/src/source/moderator.rs b/crates/db_schema/src/source/moderator.rs index 84121f9a4..b617564b3 100644 --- a/crates/db_schema/src/source/moderator.rs +++ b/crates/db_schema/src/source/moderator.rs @@ -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, } -#[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, } -#[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, } -#[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, } -#[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, } -#[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, } -#[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, pub reason: Option, } -#[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, } -#[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, } -#[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, } -#[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, diff --git a/crates/db_schema/src/source/password_reset_request.rs b/crates/db_schema/src/source/password_reset_request.rs index 0d461049f..3df7fab0f 100644 --- a/crates/db_schema/src/source/password_reset_request.rs +++ b/crates/db_schema/src/source/password_reset_request.rs @@ -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, diff --git a/crates/db_schema/src/source/person.rs b/crates/db_schema/src/source/person.rs index 978298307..7c301c998 100644 --- a/crates/db_schema/src/source/person.rs +++ b/crates/db_schema/src/source/person.rs @@ -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, } -#[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, } -#[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, } -#[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, } -#[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, } -#[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>, diff --git a/crates/db_schema/src/source/person_block.rs b/crates/db_schema/src/source/person_block.rs index ff55872f1..46920acbf 100644 --- a/crates/db_schema/src/source/person_block.rs +++ b/crates/db_schema/src/source/person_block.rs @@ -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, diff --git a/crates/db_schema/src/source/person_mention.rs b/crates/db_schema/src/source/person_mention.rs index 795799c7e..5716cb8c8 100644 --- a/crates/db_schema/src/source/person_mention.rs +++ b/crates/db_schema/src/source/person_mention.rs @@ -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, diff --git a/crates/db_schema/src/source/post.rs b/crates/db_schema/src/source/post.rs index cc9325361..a3054e408 100644 --- a/crates/db_schema/src/source/post.rs +++ b/crates/db_schema/src/source/post.rs @@ -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, } -#[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, diff --git a/crates/db_schema/src/source/post_report.rs b/crates/db_schema/src/source/post_report.rs index 6e711782b..afb334698 100644 --- a/crates/db_schema/src/source/post_report.rs +++ b/crates/db_schema/src/source/post_report.rs @@ -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, } -#[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, diff --git a/crates/db_schema/src/source/private_message.rs b/crates/db_schema/src/source/private_message.rs index 7facccaac..fa697a51f 100644 --- a/crates/db_schema/src/source/private_message.rs +++ b/crates/db_schema/src/source/private_message.rs @@ -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, diff --git a/crates/db_schema/src/source/registration_application.rs b/crates/db_schema/src/source/registration_application.rs index 01f702d81..c874427af 100644 --- a/crates/db_schema/src/source/registration_application.rs +++ b/crates/db_schema/src/source/registration_application.rs @@ -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, pub answer: Option, diff --git a/crates/db_schema/src/source/secret.rs b/crates/db_schema/src/source/secret.rs index 1a8b30185..d32a3ac73 100644 --- a/crates/db_schema/src/source/secret.rs +++ b/crates/db_schema/src/source/secret.rs @@ -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, diff --git a/crates/db_schema/src/source/site.rs b/crates/db_schema/src/source/site.rs index 8e73cca41..b43783669 100644 --- a/crates/db_schema/src/source/site.rs +++ b/crates/db_schema/src/source/site.rs @@ -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>, diff --git a/crates/db_schema/src/traits.rs b/crates/db_schema/src/traits.rs index 98f973273..2b8e3422e 100644 --- a/crates/db_schema/src/traits.rs +++ b/crates/db_schema/src/traits.rs @@ -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 index 000000000..585430572 --- /dev/null +++ b/crates/db_schema/src/utils.rs @@ -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>; + +pub fn get_database_url_from_env() -> Result { + 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(opt: &Option) -> Option { + 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, limit: Option) -> (i64, i64) { + let page = page.unwrap_or(1); + let limit = limit.unwrap_or(10); + let offset = limit * (page - 1); + (limit, offset) +} + +pub fn is_email_regex(test: &str) -> bool { + EMAIL_REGEX.is_match(test) +} + +pub fn diesel_option_overwrite(opt: &Option) -> Option> { + match opt { + // An empty string is an erase + Some(unwrapped) => { + if !unwrapped.eq("") { + Some(Some(unwrapped.to_owned())) + } else { + Some(None) + } + } + None => None, + } +} + +pub fn diesel_option_overwrite_to_url( + opt: &Option, +) -> Result>, 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 = 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 ToSql for DbUrl +where + String: ToSql, +{ + fn to_sql(&self, out: &mut Output) -> diesel::serialize::Result { + self.0.to_string().to_sql(out) + } +} + +impl FromSql for DbUrl +where + String: FromSql, +{ + fn from_sql(bytes: Option<&DB::RawValue>) -> diesel::deserialize::Result { + let str = String::from_sql(bytes)?; + Ok(DbUrl(Url::parse(&str)?)) + } +} + +impl From> for DbUrl +where + Kind: ApubObject + Send + 'static, + for<'de2> ::ApubType: serde::Deserialize<'de2>, +{ + fn from(id: ObjectId) -> 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() + )); + } +} diff --git a/crates/db_views/Cargo.toml b/crates/db_views/Cargo.toml index 4753b38df..e43113717 100644 --- a/crates/db_views/Cargo.toml +++ b/crates/db_views/Cargo.toml @@ -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" diff --git a/crates/db_views/src/comment_report_view.rs b/crates/db_views/src/comment_report_view.rs index 73224be59..bca8afdc0 100644 --- a/crates/db_views/src/comment_report_view.rs +++ b/crates/db_views/src/comment_report_view.rs @@ -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, // Left join to CommentLike - pub resolver: Option, -} 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; diff --git a/crates/db_views/src/comment_view.rs b/crates/db_views/src/comment_view.rs index da42bb134..c8b4d387e 100644 --- a/crates/db_views/src/comment_view.rs +++ b/crates/db_views/src/comment_view.rs @@ -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, // 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, // 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; diff --git a/crates/db_views/src/lib.rs b/crates/db_views/src/lib.rs index cb9fefcfd..b5567f87b 100644 --- a/crates/db_views/src/lib.rs +++ b/crates/db_views/src/lib.rs @@ -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; diff --git a/crates/db_views/src/local_user_view.rs b/crates/db_views/src/local_user_view.rs index e2453a40d..12c26df6d 100644 --- a/crates/db_views/src/local_user_view.rs +++ b/crates/db_views/src/local_user_view.rs @@ -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 { diff --git a/crates/db_views/src/post_report_view.rs b/crates/db_views/src/post_report_view.rs index 0f56c2620..9769ec021 100644 --- a/crates/db_views/src/post_report_view.rs +++ b/crates/db_views/src/post_report_view.rs @@ -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, - pub counts: PostAggregates, - pub resolver: Option, -} 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; diff --git a/crates/db_views/src/post_view.rs b/crates/db_views/src/post_view.rs index dd97cd8d4..2fac5ade3 100644 --- a/crates/db_views/src/post_view.rs +++ b/crates/db_views/src/post_view.rs @@ -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, // 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; diff --git a/crates/db_views/src/private_message_view.rs b/crates/db_views/src/private_message_view.rs index 8996f2292..fdf5b8e14 100644 --- a/crates/db_views/src/private_message_view.rs +++ b/crates/db_views/src/private_message_view.rs @@ -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 { diff --git a/crates/db_views/src/registration_application_view.rs b/crates/db_views/src/registration_application_view.rs index 2eab15357..00c79323b 100644 --- a/crates/db_views/src/registration_application_view.rs +++ b/crates/db_views/src/registration_application_view.rs @@ -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, -} 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; diff --git a/crates/db_views/src/site_view.rs b/crates/db_views/src/site_view.rs index e3a55c6b5..c630216f9 100644 --- a/crates/db_views/src/site_view.rs +++ b/crates/db_views/src/site_view.rs @@ -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 { diff --git a/crates/db_views/src/structs.rs b/crates/db_views/src/structs.rs new file mode 100644 index 000000000..59a5f0fe3 --- /dev/null +++ b/crates/db_views/src/structs.rs @@ -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, // Left join to CommentLike + pub resolver: Option, +} + +#[derive(Debug, PartialEq, Serialize, Deserialize, Clone)] +pub struct CommentView { + pub comment: Comment, + pub creator: PersonSafe, + pub recipient: Option, // 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, // 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, + pub counts: PostAggregates, + pub resolver: Option, +} + +#[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, // 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, +} + +#[derive(Debug, Serialize, Deserialize, Clone)] +pub struct SiteView { + pub site: Site, + pub counts: SiteAggregates, +} diff --git a/crates/db_views_actor/Cargo.toml b/crates/db_views_actor/Cargo.toml index 81c837619..b8810064f 100644 --- a/crates/db_views_actor/Cargo.toml +++ b/crates/db_views_actor/Cargo.toml @@ -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"] } diff --git a/crates/db_views_actor/src/community_block_view.rs b/crates/db_views_actor/src/community_block_view.rs index 8f0cfca76..7c753cd20 100644 --- a/crates/db_views_actor/src/community_block_view.rs +++ b/crates/db_views_actor/src/community_block_view.rs @@ -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); diff --git a/crates/db_views_actor/src/community_follower_view.rs b/crates/db_views_actor/src/community_follower_view.rs index 581d9b57c..6d5d94a59 100644 --- a/crates/db_views_actor/src/community_follower_view.rs +++ b/crates/db_views_actor/src/community_follower_view.rs @@ -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); diff --git a/crates/db_views_actor/src/community_moderator_view.rs b/crates/db_views_actor/src/community_moderator_view.rs index 1e48ad0ab..13e7d8cfd 100644 --- a/crates/db_views_actor/src/community_moderator_view.rs +++ b/crates/db_views_actor/src/community_moderator_view.rs @@ -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); diff --git a/crates/db_views_actor/src/community_person_ban_view.rs b/crates/db_views_actor/src/community_person_ban_view.rs index 6c67bd82a..6d765e07c 100644 --- a/crates/db_views_actor/src/community_person_ban_view.rs +++ b/crates/db_views_actor/src/community_person_ban_view.rs @@ -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( diff --git a/crates/db_views_actor/src/community_view.rs b/crates/db_views_actor/src/community_view.rs index 2063fb14f..637a2d905 100644 --- a/crates/db_views_actor/src/community_view.rs +++ b/crates/db_views_actor/src/community_view.rs @@ -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, diff --git a/crates/db_views_actor/src/lib.rs b/crates/db_views_actor/src/lib.rs index 6411feeed..878979f7d 100644 --- a/crates/db_views_actor/src/lib.rs +++ b/crates/db_views_actor/src/lib.rs @@ -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; diff --git a/crates/db_views_actor/src/person_block_view.rs b/crates/db_views_actor/src/person_block_view.rs index 2ca2077cb..b93f81672 100644 --- a/crates/db_views_actor/src/person_block_view.rs +++ b/crates/db_views_actor/src/person_block_view.rs @@ -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); diff --git a/crates/db_views_actor/src/person_mention_view.rs b/crates/db_views_actor/src/person_mention_view.rs index 0be446a91..59e901138 100644 --- a/crates/db_views_actor/src/person_mention_view.rs +++ b/crates/db_views_actor/src/person_mention_view.rs @@ -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, // Left join to CommentLike -} type PersonMentionViewTuple = ( PersonMention, diff --git a/crates/db_views_actor/src/person_view.rs b/crates/db_views_actor/src/person_view.rs index d4be05854..1849f80b1 100644 --- a/crates/db_views_actor/src/person_view.rs +++ b/crates/db_views_actor/src/person_view.rs @@ -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 index 000000000..a6ec9710e --- /dev/null +++ b/crates/db_views_actor/src/structs.rs @@ -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, // Left join to CommentLike +} + +#[derive(Debug, Serialize, Deserialize, Clone)] +pub struct PersonViewSafe { + pub person: PersonSafe, + pub counts: PersonAggregates, +} diff --git a/crates/db_views_moderator/Cargo.toml b/crates/db_views_moderator/Cargo.toml index 2e5493922..110baaeb5 100644 --- a/crates/db_views_moderator/Cargo.toml +++ b/crates/db_views_moderator/Cargo.toml @@ -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"] } diff --git a/crates/db_views_moderator/src/lib.rs b/crates/db_views_moderator/src/lib.rs index ce51617ce..c6f32426b 100644 --- a/crates/db_views_moderator/src/lib.rs +++ b/crates/db_views_moderator/src/lib.rs @@ -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; diff --git a/crates/db_views_moderator/src/mod_add_community_view.rs b/crates/db_views_moderator/src/mod_add_community_view.rs index b0d72d21a..55bb9d99b 100644 --- a/crates/db_views_moderator/src/mod_add_community_view.rs +++ b/crates/db_views_moderator/src/mod_add_community_view.rs @@ -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); diff --git a/crates/db_views_moderator/src/mod_add_view.rs b/crates/db_views_moderator/src/mod_add_view.rs index bd4e388b3..5b48d0066 100644 --- a/crates/db_views_moderator/src/mod_add_view.rs +++ b/crates/db_views_moderator/src/mod_add_view.rs @@ -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); diff --git a/crates/db_views_moderator/src/mod_ban_from_community_view.rs b/crates/db_views_moderator/src/mod_ban_from_community_view.rs index a5a37cce1..9e44e4797 100644 --- a/crates/db_views_moderator/src/mod_ban_from_community_view.rs +++ b/crates/db_views_moderator/src/mod_ban_from_community_view.rs @@ -1,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, diff --git a/crates/db_views_moderator/src/mod_ban_view.rs b/crates/db_views_moderator/src/mod_ban_view.rs index fabb56ca9..a36adaad0 100644 --- a/crates/db_views_moderator/src/mod_ban_view.rs +++ b/crates/db_views_moderator/src/mod_ban_view.rs @@ -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); diff --git a/crates/db_views_moderator/src/mod_hide_community_view.rs b/crates/db_views_moderator/src/mod_hide_community_view.rs index c7aba772d..a83805622 100644 --- a/crates/db_views_moderator/src/mod_hide_community_view.rs +++ b/crates/db_views_moderator/src/mod_hide_community_view.rs @@ -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); diff --git a/crates/db_views_moderator/src/mod_lock_post_view.rs b/crates/db_views_moderator/src/mod_lock_post_view.rs index 5ec355791..e9ec5f667 100644 --- a/crates/db_views_moderator/src/mod_lock_post_view.rs +++ b/crates/db_views_moderator/src/mod_lock_post_view.rs @@ -1,6 +1,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); diff --git a/crates/db_views_moderator/src/mod_remove_comment_view.rs b/crates/db_views_moderator/src/mod_remove_comment_view.rs index abb88020a..b2b14f220 100644 --- a/crates/db_views_moderator/src/mod_remove_comment_view.rs +++ b/crates/db_views_moderator/src/mod_remove_comment_view.rs @@ -1,6 +1,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, diff --git a/crates/db_views_moderator/src/mod_remove_community_view.rs b/crates/db_views_moderator/src/mod_remove_community_view.rs index 6634b2ff8..29aad7f92 100644 --- a/crates/db_views_moderator/src/mod_remove_community_view.rs +++ b/crates/db_views_moderator/src/mod_remove_community_view.rs @@ -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); diff --git a/crates/db_views_moderator/src/mod_remove_post_view.rs b/crates/db_views_moderator/src/mod_remove_post_view.rs index c92191610..849b56391 100644 --- a/crates/db_views_moderator/src/mod_remove_post_view.rs +++ b/crates/db_views_moderator/src/mod_remove_post_view.rs @@ -1,6 +1,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); diff --git a/crates/db_views_moderator/src/mod_sticky_post_view.rs b/crates/db_views_moderator/src/mod_sticky_post_view.rs index 55593e4fc..8b2383ee5 100644 --- a/crates/db_views_moderator/src/mod_sticky_post_view.rs +++ b/crates/db_views_moderator/src/mod_sticky_post_view.rs @@ -1,6 +1,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); diff --git a/crates/db_views_moderator/src/mod_transfer_community_view.rs b/crates/db_views_moderator/src/mod_transfer_community_view.rs index 2fbacbb83..c944a9a10 100644 --- a/crates/db_views_moderator/src/mod_transfer_community_view.rs +++ b/crates/db_views_moderator/src/mod_transfer_community_view.rs @@ -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 index 000000000..9d525b57b --- /dev/null +++ b/crates/db_views_moderator/src/structs.rs @@ -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, +} diff --git a/crates/routes/Cargo.toml b/crates/routes/Cargo.toml index f1bf6edca..2ade2385f 100644 --- a/crates/routes/Cargo.toml +++ b/crates/routes/Cargo.toml @@ -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" diff --git a/crates/routes/src/feeds.rs b/crates/routes/src/feeds.rs index bfe49fbdb..1bcfc6c3e 100644 --- a/crates/routes/src/feeds.rs +++ b/crates/routes/src/feeds.rs @@ -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; diff --git a/crates/routes/src/nodeinfo.rs b/crates/routes/src/nodeinfo.rs index 6e216f441..6ca2114e4 100644 --- a/crates/routes/src/nodeinfo.rs +++ b/crates/routes/src/nodeinfo.rs @@ -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}; diff --git a/crates/routes/src/webfinger.rs b/crates/routes/src/webfinger.rs index a95902b27..01ed2bc00 100644 --- a/crates/routes/src/webfinger.rs +++ b/crates/routes/src/webfinger.rs @@ -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}, diff --git a/crates/utils/Cargo.toml b/crates/utils/Cargo.toml index 3984b8978..189688971 100644 --- a/crates/utils/Cargo.toml +++ b/crates/utils/Cargo.toml @@ -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" diff --git a/crates/utils/src/lib.rs b/crates/utils/src/lib.rs index 1dbfb25bc..b8e301bd9 100644 --- a/crates/utils/src/lib.rs +++ b/crates/utils/src/lib.rs @@ -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}; diff --git a/crates/utils/src/request.rs b/crates/utils/src/request.rs index fb4949bd0..e98e0e8a5 100644 --- a/crates/utils/src/request.rs +++ b/crates/utils/src/request.rs @@ -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: F) -> Result @@ -53,285 +35,3 @@ where response.expect("retry http request") } - -#[derive(Deserialize, Serialize, Debug, PartialEq, Clone)] -pub struct SiteMetadata { - pub title: Option, - pub description: Option, - image: Option, - pub html: Option, -} - -/// 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 { - 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 { - 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("") { - 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, - 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 { - 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, Option) { - 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()); - // } -} diff --git a/crates/websocket/Cargo.toml b/crates/websocket/Cargo.toml index 01c985bcb..79f51eb3c 100644 --- a/crates/websocket/Cargo.toml +++ b/crates/websocket/Cargo.toml @@ -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" diff --git a/crates/websocket/src/handlers.rs b/crates/websocket/src/handlers.rs index 6085e2450..7fc7b4f63 100644 --- a/crates/websocket/src/handlers.rs +++ b/crates/websocket/src/handlers.rs @@ -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; diff --git a/crates/websocket/src/lib.rs b/crates/websocket/src/lib.rs index 324562180..12f9783ab 100644 --- a/crates/websocket/src/lib.rs +++ b/crates/websocket/src/lib.rs @@ -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; diff --git a/crates/websocket/src/send.rs b/crates/websocket/src/send.rs index 1f0677d7d..d3a1ed254 100644 --- a/crates/websocket/src/send.rs +++ b/crates/websocket/src/send.rs @@ -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)] diff --git a/src/code_migrations.rs b/src/code_migrations.rs index 69e419161..5a0b9eb6d 100644 --- a/src/code_migrations.rs +++ b/src/code_migrations.rs @@ -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; diff --git a/src/main.rs b/src/main.rs index 9297334e5..f304a5fcc 100644 --- a/src/main.rs +++ b/src/main.rs @@ -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, diff --git a/src/scheduled_tasks.rs b/src/scheduled_tasks.rs index 30e553b56..32bfd5e8c 100644 --- a/src/scheduled_tasks.rs +++ b/src/scheduled_tasks.rs @@ -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;