diff --git a/.drone.yml b/.drone.yml index 18db1fad7..f4818556d 100644 --- a/.drone.yml +++ b/.drone.yml @@ -8,11 +8,12 @@ platform: steps: - - name: chown repo + - name: prepare repo image: ekidd/rust-musl-builder:1.50.0 user: root commands: - chown 1000:1000 . -R + - git fetch --tags - name: check formatting image: rustdocker/rust:nightly @@ -34,7 +35,7 @@ steps: RUST_TEST_THREADS: 1 commands: - sudo apt-get update - - sudo apt-get -y install --no-install-recommends espeak postgresql-client + - sudo apt-get -y install --no-install-recommends postgresql-client - cargo test --workspace --no-fail-fast - name: cargo build @@ -136,6 +137,15 @@ platform: steps: + - name: prepare repo + image: rust:1.50-slim-buster + user: root + commands: + - chown 1000:1000 . -R + - apt update + - apt install --no-install-recommends --yes git + - git fetch --tags + - name: cargo test image: rust:1.50-slim-buster environment: @@ -145,7 +155,7 @@ steps: RUST_TEST_THREADS: 1 commands: - apt-get update - - apt-get -y install --no-install-recommends espeak postgresql-client libssl-dev pkg-config libpq-dev + - apt-get -y install --no-install-recommends postgresql-client libssl-dev pkg-config libpq-dev - cargo test --workspace --no-fail-fast - cargo build diff --git a/crates/api/src/community.rs b/crates/api/src/community.rs index fec943343..b00160538 100644 --- a/crates/api/src/community.rs +++ b/crates/api/src/community.rs @@ -171,7 +171,7 @@ impl Perform for BanFromCommunity { } // Remove/Restore their data if that's desired - if data.remove_data { + if data.remove_data.unwrap_or(false) { // Posts blocking(context.pool(), move |conn: &'_ _| { Post::update_removed_for_creator(conn, banned_person_id, Some(community_id), true) diff --git a/crates/api/src/local_user.rs b/crates/api/src/local_user.rs index c0ca8e32e..7fb4b83f9 100644 --- a/crates/api/src/local_user.rs +++ b/crates/api/src/local_user.rs @@ -16,6 +16,7 @@ use lemmy_api_common::{ use lemmy_db_queries::{ diesel_option_overwrite, diesel_option_overwrite_to_url, + from_opt_str_to_opt_enum, source::{ comment::Comment_, local_user::LocalUser_, @@ -68,7 +69,6 @@ use lemmy_websocket::{ LemmyContext, UserOperation, }; -use std::str::FromStr; #[async_trait::async_trait(?Send)] impl Perform for Login { @@ -398,7 +398,7 @@ impl Perform for BanPerson { } // Remove their data if that's desired - if data.remove_data { + if data.remove_data.unwrap_or(false) { // Posts blocking(context.pool(), move |conn: &'_ _| { Post::update_removed_for_creator(conn, banned_person_id, None, true) @@ -463,7 +463,7 @@ impl Perform for GetReplies { let data: &GetReplies = &self; let local_user_view = get_local_user_view_from_jwt(&data.auth, context.pool()).await?; - let sort = SortType::from_str(&data.sort)?; + let sort: Option = from_opt_str_to_opt_enum(&data.sort); let page = data.page; let limit = data.limit; @@ -473,7 +473,7 @@ impl Perform for GetReplies { let replies = blocking(context.pool(), move |conn| { CommentQueryBuilder::create(conn) - .sort(&sort) + .sort(sort) .unread_only(unread_only) .recipient_id(person_id) .show_bot_accounts(show_bot_accounts) @@ -500,7 +500,7 @@ impl Perform for GetPersonMentions { let data: &GetPersonMentions = &self; let local_user_view = get_local_user_view_from_jwt(&data.auth, context.pool()).await?; - let sort = SortType::from_str(&data.sort)?; + let sort: Option = from_opt_str_to_opt_enum(&data.sort); let page = data.page; let limit = data.limit; @@ -510,7 +510,7 @@ impl Perform for GetPersonMentions { PersonMentionQueryBuilder::create(conn) .recipient_id(person_id) .my_person_id(person_id) - .sort(&sort) + .sort(sort) .unread_only(unread_only) .page(page) .limit(limit) diff --git a/crates/api/src/site.rs b/crates/api/src/site.rs index fa8dd5e4c..dab458304 100644 --- a/crates/api/src/site.rs +++ b/crates/api/src/site.rs @@ -9,12 +9,16 @@ use lemmy_api_common::{ get_local_user_view_from_jwt_opt, is_admin, site::*, - user_show_bot_accounts, - user_show_nsfw, - user_show_read_posts, }; use lemmy_apub::fetcher::search::search_by_apub_id; -use lemmy_db_queries::{source::site::Site_, Crud, SearchType, SortType}; +use lemmy_db_queries::{ + from_opt_str_to_opt_enum, + source::site::Site_, + Crud, + ListingType, + SearchType, + SortType, +}; use lemmy_db_schema::source::{moderator::*, site::Site}; use lemmy_db_views::{ comment_view::CommentQueryBuilder, @@ -46,7 +50,6 @@ use lemmy_utils::{ }; use lemmy_websocket::LemmyContext; use log::debug; -use std::str::FromStr; #[async_trait::async_trait(?Send)] impl Perform for GetModlog { @@ -140,14 +143,16 @@ impl Perform for Search { let local_user_view = get_local_user_view_from_jwt_opt(&data.auth, context.pool()).await?; - let show_nsfw = user_show_nsfw(&local_user_view); - let show_bot_accounts = user_show_bot_accounts(&local_user_view); - let show_read_posts = user_show_read_posts(&local_user_view); + let show_nsfw = local_user_view.as_ref().map(|t| t.local_user.show_nsfw); + let show_bot_accounts = local_user_view + .as_ref() + .map(|t| t.local_user.show_bot_accounts); + let show_read_posts = local_user_view + .as_ref() + .map(|t| t.local_user.show_read_posts); let person_id = local_user_view.map(|u| u.person.id); - let type_ = SearchType::from_str(&data.type_)?; - let mut posts = Vec::new(); let mut comments = Vec::new(); let mut communities = Vec::new(); @@ -158,19 +163,24 @@ impl Perform for Search { let q = data.q.to_owned(); let page = data.page; let limit = data.limit; - let sort = SortType::from_str(&data.sort)?; + let sort: Option = from_opt_str_to_opt_enum(&data.sort); + let listing_type: Option = from_opt_str_to_opt_enum(&data.listing_type); + let search_type: SearchType = from_opt_str_to_opt_enum(&data.type_).unwrap_or(SearchType::All); let community_id = data.community_id; let community_name = data.community_name.to_owned(); - match type_ { + let creator_id = data.creator_id; + match search_type { SearchType::Posts => { posts = blocking(context.pool(), move |conn| { PostQueryBuilder::create(conn) - .sort(&sort) + .sort(sort) .show_nsfw(show_nsfw) .show_bot_accounts(show_bot_accounts) .show_read_posts(show_read_posts) + .listing_type(listing_type) .community_id(community_id) .community_name(community_name) + .creator_id(creator_id) .my_person_id(person_id) .search_term(q) .page(page) @@ -182,9 +192,13 @@ impl Perform for Search { SearchType::Comments => { comments = blocking(context.pool(), move |conn| { CommentQueryBuilder::create(&conn) - .sort(&sort) + .sort(sort) + .listing_type(listing_type) .search_term(q) .show_bot_accounts(show_bot_accounts) + .community_id(community_id) + .community_name(community_name) + .creator_id(creator_id) .my_person_id(person_id) .page(page) .limit(limit) @@ -195,7 +209,8 @@ impl Perform for Search { SearchType::Communities => { communities = blocking(context.pool(), move |conn| { CommunityQueryBuilder::create(conn) - .sort(&sort) + .sort(sort) + .listing_type(listing_type) .search_term(q) .my_person_id(person_id) .page(page) @@ -207,7 +222,7 @@ impl Perform for Search { SearchType::Users => { users = blocking(context.pool(), move |conn| { PersonQueryBuilder::create(conn) - .sort(&sort) + .sort(sort) .search_term(q) .page(page) .limit(limit) @@ -216,14 +231,20 @@ impl Perform for Search { .await??; } SearchType::All => { + // If the community or creator is included, dont search communities or users + let community_or_creator_included = + data.community_id.is_some() || data.community_name.is_some() || data.creator_id.is_some(); + posts = blocking(context.pool(), move |conn| { PostQueryBuilder::create(conn) - .sort(&sort) + .sort(sort) .show_nsfw(show_nsfw) .show_bot_accounts(show_bot_accounts) .show_read_posts(show_read_posts) + .listing_type(listing_type) .community_id(community_id) .community_name(community_name) + .creator_id(creator_id) .my_person_id(person_id) .search_term(q) .page(page) @@ -233,13 +254,17 @@ impl Perform for Search { .await??; let q = data.q.to_owned(); - let sort = SortType::from_str(&data.sort)?; + let community_name = data.community_name.to_owned(); comments = blocking(context.pool(), move |conn| { CommentQueryBuilder::create(conn) - .sort(&sort) + .sort(sort) + .listing_type(listing_type) .search_term(q) .show_bot_accounts(show_bot_accounts) + .community_id(community_id) + .community_name(community_name) + .creator_id(creator_id) .my_person_id(person_id) .page(page) .limit(limit) @@ -248,42 +273,51 @@ impl Perform for Search { .await??; let q = data.q.to_owned(); - let sort = SortType::from_str(&data.sort)?; - communities = blocking(context.pool(), move |conn| { - CommunityQueryBuilder::create(conn) - .sort(&sort) - .search_term(q) - .my_person_id(person_id) - .page(page) - .limit(limit) - .list() - }) - .await??; + communities = if community_or_creator_included { + vec![] + } else { + blocking(context.pool(), move |conn| { + CommunityQueryBuilder::create(conn) + .sort(sort) + .listing_type(listing_type) + .search_term(q) + .my_person_id(person_id) + .page(page) + .limit(limit) + .list() + }) + .await?? + }; let q = data.q.to_owned(); - let sort = SortType::from_str(&data.sort)?; - users = blocking(context.pool(), move |conn| { - PersonQueryBuilder::create(conn) - .sort(&sort) - .search_term(q) - .page(page) - .limit(limit) - .list() - }) - .await??; + users = if community_or_creator_included { + vec![] + } else { + blocking(context.pool(), move |conn| { + PersonQueryBuilder::create(conn) + .sort(sort) + .search_term(q) + .page(page) + .limit(limit) + .list() + }) + .await?? + }; } SearchType::Url => { posts = blocking(context.pool(), move |conn| { PostQueryBuilder::create(conn) - .sort(&sort) + .sort(sort) .show_nsfw(show_nsfw) .show_bot_accounts(show_bot_accounts) .show_read_posts(show_read_posts) + .listing_type(listing_type) .my_person_id(person_id) .community_id(community_id) .community_name(community_name) + .creator_id(creator_id) .url_search(q) .page(page) .limit(limit) @@ -295,7 +329,7 @@ impl Perform for Search { // Return the jwt Ok(SearchResponse { - type_: data.type_.to_owned(), + type_: search_type.to_string(), comments, posts, communities, diff --git a/crates/api_common/src/comment.rs b/crates/api_common/src/comment.rs index 1457f181a..ce5182cf3 100644 --- a/crates/api_common/src/comment.rs +++ b/crates/api_common/src/comment.rs @@ -5,8 +5,8 @@ use serde::{Deserialize, Serialize}; #[derive(Deserialize)] pub struct CreateComment { pub content: String, - pub parent_id: Option, pub post_id: PostId, + pub parent_id: Option, pub form_id: Option, pub auth: String, } @@ -64,13 +64,13 @@ pub struct CreateCommentLike { #[derive(Deserialize)] pub struct GetComments { - pub type_: String, - pub sort: String, + pub type_: Option, + pub sort: Option, pub page: Option, pub limit: Option, pub community_id: Option, pub community_name: Option, - pub saved_only: bool, + pub saved_only: Option, pub auth: Option, } diff --git a/crates/api_common/src/community.rs b/crates/api_common/src/community.rs index a03440447..129b149ad 100644 --- a/crates/api_common/src/community.rs +++ b/crates/api_common/src/community.rs @@ -39,8 +39,8 @@ pub struct CommunityResponse { #[derive(Deserialize, Debug)] pub struct ListCommunities { - pub type_: String, - pub sort: String, + pub type_: Option, + pub sort: Option, pub page: Option, pub limit: Option, pub auth: Option, @@ -56,7 +56,7 @@ pub struct BanFromCommunity { pub community_id: CommunityId, pub person_id: PersonId, pub ban: bool, - pub remove_data: bool, + pub remove_data: Option, pub reason: Option, pub expires: Option, pub auth: String, @@ -84,7 +84,7 @@ pub struct AddModToCommunityResponse { #[derive(Deserialize)] pub struct EditCommunity { pub community_id: CommunityId, - pub title: String, + pub title: Option, pub description: Option, pub icon: Option, pub banner: Option, diff --git a/crates/api_common/src/lib.rs b/crates/api_common/src/lib.rs index 47f4752dd..f2b41be50 100644 --- a/crates/api_common/src/lib.rs +++ b/crates/api_common/src/lib.rs @@ -237,30 +237,6 @@ pub fn is_admin(local_user_view: &LocalUserView) -> Result<(), LemmyError> { Ok(()) } -/// A helper method for showing the bot account -pub fn user_show_bot_accounts(local_user_view: &Option) -> bool { - match local_user_view { - Some(uv) => uv.to_owned().local_user.show_bot_accounts, - None => true, - } -} - -/// A helper method for showing nsfw -pub fn user_show_nsfw(local_user_view: &Option) -> bool { - match &local_user_view { - Some(uv) => uv.local_user.show_nsfw, - None => false, - } -} - -/// A helper method for showing read posts -pub fn user_show_read_posts(local_user_view: &Option) -> bool { - match local_user_view { - Some(uv) => uv.to_owned().local_user.show_read_posts, - None => true, - } -} - pub async fn get_post(post_id: PostId, pool: &DbPool) -> Result { blocking(pool, move |conn| Post::read(conn, post_id)) .await? diff --git a/crates/api_common/src/person.rs b/crates/api_common/src/person.rs index f8fbe5d0d..12cc5deeb 100644 --- a/crates/api_common/src/person.rs +++ b/crates/api_common/src/person.rs @@ -21,10 +21,10 @@ use lemmy_db_schema::{CommunityId, PersonId, PersonMentionId, PrivateMessageId}; #[derive(Deserialize)] pub struct Register { pub username: String, - pub email: Option, pub password: String, pub password_verify: String, pub show_nsfw: bool, + pub email: Option, pub captcha_uuid: Option, pub captcha_answer: Option, } @@ -81,13 +81,13 @@ pub struct LoginResponse { #[derive(Deserialize)] pub struct GetPersonDetails { - pub person_id: Option, + pub person_id: Option, // One of these two are required pub username: Option, - pub sort: String, + pub sort: Option, pub page: Option, pub limit: Option, pub community_id: Option, - pub saved_only: bool, + pub saved_only: Option, pub auth: Option, } @@ -131,7 +131,7 @@ pub struct AddAdminResponse { pub struct BanPerson { pub person_id: PersonId, pub ban: bool, - pub remove_data: bool, + pub remove_data: Option, pub reason: Option, pub expires: Option, pub auth: String, @@ -145,19 +145,19 @@ pub struct BanPersonResponse { #[derive(Deserialize)] pub struct GetReplies { - pub sort: String, + pub sort: Option, pub page: Option, pub limit: Option, - pub unread_only: bool, + pub unread_only: Option, pub auth: String, } #[derive(Deserialize)] pub struct GetPersonMentions { - pub sort: String, + pub sort: Option, pub page: Option, pub limit: Option, - pub unread_only: bool, + pub unread_only: Option, pub auth: String, } @@ -224,7 +224,7 @@ pub struct MarkPrivateMessageAsRead { #[derive(Deserialize)] pub struct GetPrivateMessages { - pub unread_only: bool, + pub unread_only: Option, pub page: Option, pub limit: Option, pub auth: String, diff --git a/crates/api_common/src/post.rs b/crates/api_common/src/post.rs index 727859bc4..bb6b36249 100644 --- a/crates/api_common/src/post.rs +++ b/crates/api_common/src/post.rs @@ -14,10 +14,10 @@ use url::Url; #[derive(Deserialize, Debug)] pub struct CreatePost { pub name: String, + pub community_id: CommunityId, pub url: Option, pub body: Option, - pub nsfw: bool, - pub community_id: CommunityId, + pub nsfw: Option, pub auth: String, } @@ -43,13 +43,13 @@ pub struct GetPostResponse { #[derive(Deserialize, Debug)] pub struct GetPosts { - pub type_: String, - pub sort: String, + pub type_: Option, + pub sort: Option, pub page: Option, pub limit: Option, pub community_id: Option, pub community_name: Option, - pub saved_only: bool, + pub saved_only: Option, pub auth: Option, } @@ -68,10 +68,10 @@ pub struct CreatePostLike { #[derive(Deserialize)] pub struct EditPost { pub post_id: PostId, - pub name: String, + pub name: Option, pub url: Option, pub body: Option, - pub nsfw: bool, + pub nsfw: Option, pub auth: String, } diff --git a/crates/api_common/src/site.rs b/crates/api_common/src/site.rs index ffee7ba86..e5c167f42 100644 --- a/crates/api_common/src/site.rs +++ b/crates/api_common/src/site.rs @@ -22,10 +22,12 @@ use serde::{Deserialize, Serialize}; #[derive(Deserialize, Debug)] pub struct Search { pub q: String, - pub type_: String, pub community_id: Option, pub community_name: Option, - pub sort: String, + pub creator_id: Option, + pub type_: Option, + pub sort: Option, + pub listing_type: Option, pub page: Option, pub limit: Option, pub auth: Option, @@ -68,23 +70,23 @@ pub struct CreateSite { pub description: Option, pub icon: Option, pub banner: Option, - pub enable_downvotes: bool, - pub open_registration: bool, - pub enable_nsfw: bool, - pub community_creation_admin_only: bool, + pub enable_downvotes: Option, + pub open_registration: Option, + pub enable_nsfw: Option, + pub community_creation_admin_only: Option, pub auth: String, } #[derive(Deserialize)] pub struct EditSite { - pub name: String, + pub name: Option, pub sidebar: Option, pub description: Option, pub icon: Option, pub banner: Option, - pub enable_downvotes: bool, - pub open_registration: bool, - pub enable_nsfw: bool, + pub enable_downvotes: Option, + pub open_registration: Option, + pub enable_nsfw: Option, pub community_creation_admin_only: Option, pub auth: String, } diff --git a/crates/api_crud/src/comment/read.rs b/crates/api_crud/src/comment/read.rs index 4d1443820..12ccbd5a1 100644 --- a/crates/api_crud/src/comment/read.rs +++ b/crates/api_crud/src/comment/read.rs @@ -1,16 +1,10 @@ use crate::PerformCrud; use actix_web::web::Data; -use lemmy_api_common::{ - blocking, - comment::*, - get_local_user_view_from_jwt_opt, - user_show_bot_accounts, -}; -use lemmy_db_queries::{ListingType, SortType}; +use lemmy_api_common::{blocking, comment::*, get_local_user_view_from_jwt_opt}; +use lemmy_db_queries::{from_opt_str_to_opt_enum, ListingType, SortType}; use lemmy_db_views::comment_view::CommentQueryBuilder; use lemmy_utils::{ApiError, ConnectionId, LemmyError}; use lemmy_websocket::LemmyContext; -use std::str::FromStr; #[async_trait::async_trait(?Send)] impl PerformCrud for GetComments { @@ -24,11 +18,13 @@ impl PerformCrud for GetComments { let data: &GetComments = &self; let local_user_view = get_local_user_view_from_jwt_opt(&data.auth, context.pool()).await?; - let show_bot_accounts = user_show_bot_accounts(&local_user_view); + let show_bot_accounts = local_user_view + .as_ref() + .map(|t| t.local_user.show_bot_accounts); let person_id = local_user_view.map(|u| u.person.id); - let type_ = ListingType::from_str(&data.type_)?; - let sort = SortType::from_str(&data.sort)?; + let sort: Option = from_opt_str_to_opt_enum(&data.sort); + let listing_type: Option = from_opt_str_to_opt_enum(&data.type_); let community_id = data.community_id; let community_name = data.community_name.to_owned(); @@ -37,8 +33,8 @@ impl PerformCrud for GetComments { let limit = data.limit; let comments = blocking(context.pool(), move |conn| { CommentQueryBuilder::create(conn) - .listing_type(type_) - .sort(&sort) + .listing_type(listing_type) + .sort(sort) .saved_only(saved_only) .community_id(community_id) .community_name(community_name) diff --git a/crates/api_crud/src/community/read.rs b/crates/api_crud/src/community/read.rs index 422161ae1..7836878e9 100644 --- a/crates/api_crud/src/community/read.rs +++ b/crates/api_crud/src/community/read.rs @@ -1,7 +1,12 @@ use crate::PerformCrud; use actix_web::web::Data; use lemmy_api_common::{blocking, community::*, get_local_user_view_from_jwt_opt}; -use lemmy_db_queries::{source::community::Community_, ListingType, SortType}; +use lemmy_db_queries::{ + from_opt_str_to_opt_enum, + source::community::Community_, + ListingType, + SortType, +}; use lemmy_db_schema::source::community::*; use lemmy_db_views_actor::{ community_moderator_view::CommunityModeratorView, @@ -9,7 +14,6 @@ use lemmy_db_views_actor::{ }; use lemmy_utils::{ApiError, ConnectionId, LemmyError}; use lemmy_websocket::{messages::GetCommunityUsersOnline, LemmyContext}; -use std::str::FromStr; #[async_trait::async_trait(?Send)] impl PerformCrud for GetCommunity { @@ -86,15 +90,15 @@ impl PerformCrud for ListCommunities { None => false, }; - let type_ = ListingType::from_str(&data.type_)?; - let sort = SortType::from_str(&data.sort)?; + let sort: Option = from_opt_str_to_opt_enum(&data.sort); + let listing_type: Option = from_opt_str_to_opt_enum(&data.type_); let page = data.page; let limit = data.limit; let communities = blocking(context.pool(), move |conn| { CommunityQueryBuilder::create(conn) - .listing_type(&type_) - .sort(&sort) + .listing_type(listing_type) + .sort(sort) .show_nsfw(show_nsfw) .my_person_id(person_id) .page(page) diff --git a/crates/api_crud/src/community/update.rs b/crates/api_crud/src/community/update.rs index 644581a5d..f28f77119 100644 --- a/crates/api_crud/src/community/update.rs +++ b/crates/api_crud/src/community/update.rs @@ -16,12 +16,7 @@ use lemmy_db_views_actor::{ community_moderator_view::CommunityModeratorView, community_view::CommunityView, }; -use lemmy_utils::{ - utils::{check_slurs, check_slurs_opt}, - ApiError, - ConnectionId, - LemmyError, -}; +use lemmy_utils::{utils::check_slurs_opt, ApiError, ConnectionId, LemmyError}; use lemmy_websocket::{LemmyContext, UserOperationCrud}; #[async_trait::async_trait(?Send)] @@ -36,7 +31,7 @@ impl PerformCrud for EditCommunity { let data: &EditCommunity = &self; let local_user_view = get_local_user_view_from_jwt(&data.auth, context.pool()).await?; - check_slurs(&data.title)?; + check_slurs_opt(&data.title)?; check_slurs_opt(&data.description)?; // Verify its a mod (only mods can edit it) @@ -61,7 +56,7 @@ impl PerformCrud for EditCommunity { let community_form = CommunityForm { name: read_community.name, - title: data.title.to_owned(), + title: data.title.to_owned().unwrap_or(read_community.title), description: data.description.to_owned(), icon, banner, diff --git a/crates/api_crud/src/post/read.rs b/crates/api_crud/src/post/read.rs index d44f029a0..d49764bba 100644 --- a/crates/api_crud/src/post/read.rs +++ b/crates/api_crud/src/post/read.rs @@ -1,15 +1,7 @@ use crate::PerformCrud; use actix_web::web::Data; -use lemmy_api_common::{ - blocking, - get_local_user_view_from_jwt_opt, - mark_post_as_read, - post::*, - user_show_bot_accounts, - user_show_nsfw, - user_show_read_posts, -}; -use lemmy_db_queries::{ListingType, SortType}; +use lemmy_api_common::{blocking, get_local_user_view_from_jwt_opt, mark_post_as_read, post::*}; +use lemmy_db_queries::{from_opt_str_to_opt_enum, ListingType, SortType}; use lemmy_db_views::{ comment_view::CommentQueryBuilder, post_view::{PostQueryBuilder, PostView}, @@ -20,7 +12,6 @@ use lemmy_db_views_actor::{ }; use lemmy_utils::{ApiError, ConnectionId, LemmyError}; use lemmy_websocket::{messages::GetPostUsersOnline, LemmyContext}; -use std::str::FromStr; #[async_trait::async_trait(?Send)] impl PerformCrud for GetPost { @@ -34,8 +25,9 @@ impl PerformCrud for GetPost { let data: &GetPost = &self; let local_user_view = get_local_user_view_from_jwt_opt(&data.auth, context.pool()).await?; - let show_bot_accounts = user_show_bot_accounts(&local_user_view); - + let show_bot_accounts = local_user_view + .as_ref() + .map(|t| t.local_user.show_bot_accounts); let person_id = local_user_view.map(|u| u.person.id); let id = data.id; @@ -105,12 +97,16 @@ impl PerformCrud for GetPosts { let person_id = local_user_view.to_owned().map(|l| l.person.id); - let show_nsfw = user_show_nsfw(&local_user_view); - let show_bot_accounts = user_show_bot_accounts(&local_user_view); - let show_read_posts = user_show_read_posts(&local_user_view); + let show_nsfw = local_user_view.as_ref().map(|t| t.local_user.show_nsfw); + let show_bot_accounts = local_user_view + .as_ref() + .map(|t| t.local_user.show_bot_accounts); + let show_read_posts = local_user_view + .as_ref() + .map(|t| t.local_user.show_read_posts); - let type_ = ListingType::from_str(&data.type_)?; - let sort = SortType::from_str(&data.sort)?; + let sort: Option = from_opt_str_to_opt_enum(&data.sort); + let listing_type: Option = from_opt_str_to_opt_enum(&data.type_); let page = data.page; let limit = data.limit; @@ -120,8 +116,8 @@ impl PerformCrud for GetPosts { let posts = blocking(context.pool(), move |conn| { PostQueryBuilder::create(conn) - .listing_type(&type_) - .sort(&sort) + .listing_type(listing_type) + .sort(sort) .show_nsfw(show_nsfw) .show_bot_accounts(show_bot_accounts) .show_read_posts(show_read_posts) diff --git a/crates/api_crud/src/post/update.rs b/crates/api_crud/src/post/update.rs index 8ca0dcd1d..ca7634d5a 100644 --- a/crates/api_crud/src/post/update.rs +++ b/crates/api_crud/src/post/update.rs @@ -7,7 +7,7 @@ use lemmy_db_schema::{naive_now, source::post::*}; use lemmy_db_views::post_view::PostView; use lemmy_utils::{ request::fetch_iframely_and_pictrs_data, - utils::{check_slurs, check_slurs_opt, is_valid_post_title}, + utils::{check_slurs_opt, is_valid_post_title}, ApiError, ConnectionId, LemmyError, @@ -26,11 +26,13 @@ impl PerformCrud for EditPost { let data: &EditPost = &self; let local_user_view = get_local_user_view_from_jwt(&data.auth, context.pool()).await?; - check_slurs(&data.name)?; + check_slurs_opt(&data.name)?; check_slurs_opt(&data.body)?; - if !is_valid_post_title(&data.name) { - return Err(ApiError::err("invalid_post_title").into()); + if let Some(name) = &data.name { + if !is_valid_post_title(name) { + return Err(ApiError::err("invalid_post_title").into()); + } } let post_id = data.post_id; @@ -56,7 +58,7 @@ impl PerformCrud for EditPost { let post_form = PostForm { creator_id: orig_post.creator_id.to_owned(), community_id: orig_post.community_id, - name: data.name.trim().to_owned(), + name: data.name.to_owned().unwrap_or(orig_post.name), url: data_url.map(|u| u.to_owned().into()), body: data.body.to_owned(), nsfw: data.nsfw, diff --git a/crates/api_crud/src/site/create.rs b/crates/api_crud/src/site/create.rs index dc6e649d6..2b876c2ff 100644 --- a/crates/api_crud/src/site/create.rs +++ b/crates/api_crud/src/site/create.rs @@ -67,7 +67,7 @@ impl PerformCrud for CreateSite { open_registration: data.open_registration, enable_nsfw: data.enable_nsfw, updated: None, - community_creation_admin_only: Some(data.community_creation_admin_only), + community_creation_admin_only: data.community_creation_admin_only, }; let create_site = move |conn: &'_ _| Site::create(conn, &site_form); diff --git a/crates/api_crud/src/site/read.rs b/crates/api_crud/src/site/read.rs index e378b26b0..9b73c12f8 100644 --- a/crates/api_crud/src/site/read.rs +++ b/crates/api_crud/src/site/read.rs @@ -47,11 +47,11 @@ impl PerformCrud for GetSite { description: None, icon: None, banner: None, - enable_downvotes: true, - open_registration: true, - enable_nsfw: true, + enable_downvotes: None, + open_registration: None, + enable_nsfw: None, auth: login_response.jwt, - community_creation_admin_only: false, + community_creation_admin_only: None, }; create_site.perform(context, websocket_id).await?; info!("Site {} created", setup.site_name); diff --git a/crates/api_crud/src/site/update.rs b/crates/api_crud/src/site/update.rs index 58f408492..14716e782 100644 --- a/crates/api_crud/src/site/update.rs +++ b/crates/api_crud/src/site/update.rs @@ -18,12 +18,7 @@ use lemmy_db_schema::{ source::site::{Site, SiteForm}, }; use lemmy_db_views::site_view::SiteView; -use lemmy_utils::{ - utils::{check_slurs, check_slurs_opt}, - ApiError, - ConnectionId, - LemmyError, -}; +use lemmy_utils::{utils::check_slurs_opt, ApiError, ConnectionId, LemmyError}; use lemmy_websocket::{messages::SendAllMessage, LemmyContext, UserOperationCrud}; #[async_trait::async_trait(?Send)] @@ -37,7 +32,7 @@ impl PerformCrud for EditSite { let data: &EditSite = &self; let local_user_view = get_local_user_view_from_jwt(&data.auth, context.pool()).await?; - check_slurs(&data.name)?; + check_slurs_opt(&data.name)?; check_slurs_opt(&data.description)?; // Make sure user is an admin @@ -55,12 +50,12 @@ impl PerformCrud for EditSite { } let site_form = SiteForm { - name: data.name.to_owned(), + creator_id: found_site.creator_id, + name: data.name.to_owned().unwrap_or(found_site.name), sidebar, description, icon, banner, - creator_id: found_site.creator_id, updated: Some(naive_now()), enable_downvotes: data.enable_downvotes, open_registration: data.open_registration, diff --git a/crates/api_crud/src/user/read.rs b/crates/api_crud/src/user/read.rs index e0e3808c1..132bdd78f 100644 --- a/crates/api_crud/src/user/read.rs +++ b/crates/api_crud/src/user/read.rs @@ -1,14 +1,7 @@ use crate::PerformCrud; use actix_web::web::Data; -use lemmy_api_common::{ - blocking, - get_local_user_view_from_jwt_opt, - person::*, - user_show_bot_accounts, - user_show_nsfw, - user_show_read_posts, -}; -use lemmy_db_queries::{source::person::Person_, SortType}; +use lemmy_api_common::{blocking, get_local_user_view_from_jwt_opt, person::*}; +use lemmy_db_queries::{from_opt_str_to_opt_enum, source::person::Person_, SortType}; use lemmy_db_schema::source::person::*; use lemmy_db_views::{comment_view::CommentQueryBuilder, post_view::PostQueryBuilder}; use lemmy_db_views_actor::{ @@ -18,7 +11,6 @@ use lemmy_db_views_actor::{ }; use lemmy_utils::{ApiError, ConnectionId, LemmyError}; use lemmy_websocket::LemmyContext; -use std::str::FromStr; #[async_trait::async_trait(?Send)] impl PerformCrud for GetPersonDetails { @@ -32,11 +24,15 @@ impl PerformCrud for GetPersonDetails { let data: &GetPersonDetails = &self; let local_user_view = get_local_user_view_from_jwt_opt(&data.auth, context.pool()).await?; - let show_nsfw = user_show_nsfw(&local_user_view); - let show_bot_accounts = user_show_bot_accounts(&local_user_view); - let show_read_posts = user_show_read_posts(&local_user_view); + let show_nsfw = local_user_view.as_ref().map(|t| t.local_user.show_nsfw); + let show_bot_accounts = local_user_view + .as_ref() + .map(|t| t.local_user.show_bot_accounts); + let show_read_posts = local_user_view + .as_ref() + .map(|t| t.local_user.show_read_posts); - let sort = SortType::from_str(&data.sort)?; + let sort: Option = from_opt_str_to_opt_enum(&data.sort); let username = data .username @@ -71,7 +67,7 @@ impl PerformCrud for GetPersonDetails { let (posts, comments) = blocking(context.pool(), move |conn| { let mut posts_query = PostQueryBuilder::create(conn) - .sort(&sort) + .sort(sort) .show_nsfw(show_nsfw) .show_bot_accounts(show_bot_accounts) .show_read_posts(show_read_posts) @@ -84,7 +80,7 @@ impl PerformCrud for GetPersonDetails { let mut comments_query = CommentQueryBuilder::create(conn) .my_person_id(person_id) .show_bot_accounts(show_bot_accounts) - .sort(&sort) + .sort(sort) .saved_only(saved_only) .community_id(community_id) .page(page) @@ -92,7 +88,7 @@ impl PerformCrud for GetPersonDetails { // If its saved only, you don't care what creator it was // Or, if its not saved, then you only want it for that specific creator - if !saved_only { + if !saved_only.unwrap_or(false) { posts_query = posts_query.creator_id(person_details_id); comments_query = comments_query.creator_id(person_details_id); } diff --git a/crates/apub/src/objects/post.rs b/crates/apub/src/objects/post.rs index 8bbc07605..1c984d84d 100644 --- a/crates/apub/src/objects/post.rs +++ b/crates/apub/src/objects/post.rs @@ -230,8 +230,8 @@ impl FromApubToForm for PostForm { .as_ref() .map(|u| u.to_owned().naive_local()), deleted: None, - nsfw: ext.sensitive.unwrap_or(false), - stickied: ext.stickied.or(Some(false)), + nsfw: ext.sensitive, + stickied: ext.stickied, embed_title: iframely_title, embed_description: iframely_description, embed_html: iframely_html, diff --git a/crates/db_queries/src/aggregates/site_aggregates.rs b/crates/db_queries/src/aggregates/site_aggregates.rs index 934a73051..109e4bd65 100644 --- a/crates/db_queries/src/aggregates/site_aggregates.rs +++ b/crates/db_queries/src/aggregates/site_aggregates.rs @@ -49,14 +49,14 @@ mod tests { let site_form = SiteForm { name: "test_site".into(), + creator_id: inserted_person.id, sidebar: None, description: None, icon: None, banner: None, - creator_id: inserted_person.id, - enable_downvotes: true, - open_registration: true, - enable_nsfw: true, + enable_downvotes: None, + open_registration: None, + enable_nsfw: None, updated: None, community_creation_admin_only: Some(false), }; diff --git a/crates/db_queries/src/lib.rs b/crates/db_queries/src/lib.rs index 285ba3323..0665ac95d 100644 --- a/crates/db_queries/src/lib.rs +++ b/crates/db_queries/src/lib.rs @@ -163,7 +163,7 @@ pub fn get_database_url_from_env() -> Result { env::var("LEMMY_DATABASE_URL") } -#[derive(EnumString, ToString, Debug, Serialize, Deserialize)] +#[derive(EnumString, ToString, Debug, Serialize, Deserialize, Clone, Copy)] pub enum SortType { Active, Hot, @@ -177,7 +177,7 @@ pub enum SortType { NewComments, } -#[derive(EnumString, ToString, Debug, Serialize, Deserialize, Clone)] +#[derive(EnumString, ToString, Debug, Serialize, Deserialize, Clone, Copy)] pub enum ListingType { All, Local, @@ -185,7 +185,7 @@ pub enum ListingType { Community, } -#[derive(EnumString, ToString, Debug, Serialize, Deserialize)] +#[derive(EnumString, ToString, Debug, Serialize, Deserialize, Clone, Copy)] pub enum SearchType { All, Comments, @@ -195,6 +195,10 @@ pub enum SearchType { Url, } +pub fn from_opt_str_to_opt_enum(opt: &Option) -> Option { + opt.as_ref().map(|t| T::from_str(t).ok()).flatten() +} + pub fn fuzzy_search(q: &str) -> String { let replaced = q.replace(" ", "%"); format!("%{}%", replaced) diff --git a/crates/db_schema/src/source/post.rs b/crates/db_schema/src/source/post.rs index 2581db95c..536dd9606 100644 --- a/crates/db_schema/src/source/post.rs +++ b/crates/db_schema/src/source/post.rs @@ -37,7 +37,7 @@ pub struct PostForm { pub name: String, pub creator_id: PersonId, pub community_id: CommunityId, - pub nsfw: bool, + pub nsfw: Option, pub url: Option, pub body: Option, pub removed: Option, diff --git a/crates/db_schema/src/source/site.rs b/crates/db_schema/src/source/site.rs index 67bba9933..19c41bf73 100644 --- a/crates/db_schema/src/source/site.rs +++ b/crates/db_schema/src/source/site.rs @@ -23,12 +23,12 @@ pub struct Site { #[table_name = "site"] pub struct SiteForm { pub name: String, - pub sidebar: Option>, pub creator_id: PersonId, + pub sidebar: Option>, pub updated: Option, - pub enable_downvotes: bool, - pub open_registration: bool, - pub enable_nsfw: bool, + pub enable_downvotes: Option, + pub open_registration: Option, + pub enable_nsfw: Option, // when you want to null out a column, you have to send Some(None)), since sending None means you just don't want to update that column. pub icon: Option>, pub banner: Option>, diff --git a/crates/db_views/src/comment_view.rs b/crates/db_views/src/comment_view.rs index b85b1c77a..fbb2b7f7d 100644 --- a/crates/db_views/src/comment_view.rs +++ b/crates/db_views/src/comment_view.rs @@ -172,8 +172,8 @@ impl CommentView { pub struct CommentQueryBuilder<'a> { conn: &'a PgConnection, - listing_type: ListingType, - sort: &'a SortType, + listing_type: Option, + sort: Option, community_id: Option, community_name: Option, post_id: Option, @@ -181,9 +181,9 @@ pub struct CommentQueryBuilder<'a> { recipient_id: Option, my_person_id: Option, search_term: Option, - saved_only: bool, - unread_only: bool, - show_bot_accounts: bool, + saved_only: Option, + unread_only: Option, + show_bot_accounts: Option, page: Option, limit: Option, } @@ -192,8 +192,8 @@ impl<'a> CommentQueryBuilder<'a> { pub fn create(conn: &'a PgConnection) -> Self { CommentQueryBuilder { conn, - listing_type: ListingType::All, - sort: &SortType::New, + listing_type: None, + sort: None, community_id: None, community_name: None, post_id: None, @@ -201,21 +201,21 @@ impl<'a> CommentQueryBuilder<'a> { recipient_id: None, my_person_id: None, search_term: None, - saved_only: false, - unread_only: false, - show_bot_accounts: true, + saved_only: None, + unread_only: None, + show_bot_accounts: None, page: None, limit: None, } } - pub fn listing_type(mut self, listing_type: ListingType) -> Self { - self.listing_type = listing_type; + pub fn listing_type>(mut self, listing_type: T) -> Self { + self.listing_type = listing_type.get_optional(); self } - pub fn sort(mut self, sort: &'a SortType) -> Self { - self.sort = sort; + pub fn sort>(mut self, sort: T) -> Self { + self.sort = sort.get_optional(); self } @@ -254,18 +254,18 @@ impl<'a> CommentQueryBuilder<'a> { self } - pub fn saved_only(mut self, saved_only: bool) -> Self { - self.saved_only = saved_only; + pub fn saved_only>(mut self, saved_only: T) -> Self { + self.saved_only = saved_only.get_optional(); self } - pub fn unread_only(mut self, unread_only: bool) -> Self { - self.unread_only = unread_only; + pub fn unread_only>(mut self, unread_only: T) -> Self { + self.unread_only = unread_only.get_optional(); self } - pub fn show_bot_accounts(mut self, show_bot_accounts: bool) -> Self { - self.show_bot_accounts = show_bot_accounts; + pub fn show_bot_accounts>(mut self, show_bot_accounts: T) -> Self { + self.show_bot_accounts = show_bot_accounts.get_optional(); self } @@ -350,7 +350,7 @@ impl<'a> CommentQueryBuilder<'a> { .filter(comment::removed.eq(false)); } - if self.unread_only { + if self.unread_only.unwrap_or(false) { query = query.filter(comment::read.eq(false)); } @@ -376,22 +376,23 @@ impl<'a> CommentQueryBuilder<'a> { query = query.filter(comment::content.ilike(fuzzy_search(&search_term))); }; - query = match self.listing_type { - // ListingType::Subscribed => query.filter(community_follower::subscribed.eq(true)), - ListingType::Subscribed => query.filter(community_follower::person_id.is_not_null()), // TODO could be this: and(community_follower::person_id.eq(person_id_join)), - ListingType::Local => query.filter(community::local.eq(true)), - _ => query, - }; + if let Some(listing_type) = self.listing_type { + query = match listing_type { + ListingType::Subscribed => query.filter(community_follower::person_id.is_not_null()), // TODO could be this: and(community_follower::person_id.eq(person_id_join)), + ListingType::Local => query.filter(community::local.eq(true)), + _ => query, + }; + } - if self.saved_only { + if self.saved_only.unwrap_or(false) { query = query.filter(comment_saved::id.is_not_null()); } - if !self.show_bot_accounts { + if !self.show_bot_accounts.unwrap_or(true) { query = query.filter(person::bot_account.eq(false)); }; - query = match self.sort { + query = match self.sort.unwrap_or(SortType::New) { SortType::Hot | SortType::Active => query .order_by(hot_rank(comment_aggregates::score, comment_aggregates::published).desc()) .then_order_by(comment_aggregates::published.desc()), diff --git a/crates/db_views/src/post_view.rs b/crates/db_views/src/post_view.rs index 8a533412f..1d8ea80e6 100644 --- a/crates/db_views/src/post_view.rs +++ b/crates/db_views/src/post_view.rs @@ -155,18 +155,18 @@ impl PostView { pub struct PostQueryBuilder<'a> { conn: &'a PgConnection, - listing_type: &'a ListingType, - sort: &'a SortType, + listing_type: Option, + sort: Option, creator_id: Option, community_id: Option, community_name: Option, my_person_id: Option, search_term: Option, url_search: Option, - show_nsfw: bool, - show_bot_accounts: bool, - show_read_posts: bool, - saved_only: bool, + show_nsfw: Option, + show_bot_accounts: Option, + show_read_posts: Option, + saved_only: Option, page: Option, limit: Option, } @@ -175,30 +175,30 @@ impl<'a> PostQueryBuilder<'a> { pub fn create(conn: &'a PgConnection) -> Self { PostQueryBuilder { conn, - listing_type: &ListingType::All, - sort: &SortType::Hot, + listing_type: None, + sort: None, creator_id: None, community_id: None, community_name: None, my_person_id: None, search_term: None, url_search: None, - show_nsfw: true, - show_bot_accounts: true, - show_read_posts: true, - saved_only: false, + show_nsfw: None, + show_bot_accounts: None, + show_read_posts: None, + saved_only: None, page: None, limit: None, } } - pub fn listing_type(mut self, listing_type: &'a ListingType) -> Self { - self.listing_type = listing_type; + pub fn listing_type>(mut self, listing_type: T) -> Self { + self.listing_type = listing_type.get_optional(); self } - pub fn sort(mut self, sort: &'a SortType) -> Self { - self.sort = sort; + pub fn sort>(mut self, sort: T) -> Self { + self.sort = sort.get_optional(); self } @@ -232,23 +232,23 @@ impl<'a> PostQueryBuilder<'a> { self } - pub fn show_nsfw(mut self, show_nsfw: bool) -> Self { - self.show_nsfw = show_nsfw; + pub fn show_nsfw>(mut self, show_nsfw: T) -> Self { + self.show_nsfw = show_nsfw.get_optional(); self } - pub fn show_bot_accounts(mut self, show_bot_accounts: bool) -> Self { - self.show_bot_accounts = show_bot_accounts; + pub fn show_bot_accounts>(mut self, show_bot_accounts: T) -> Self { + self.show_bot_accounts = show_bot_accounts.get_optional(); self } - pub fn show_read_posts(mut self, show_read_posts: bool) -> Self { - self.show_read_posts = show_read_posts; + pub fn show_read_posts>(mut self, show_read_posts: T) -> Self { + self.show_read_posts = show_read_posts.get_optional(); self } - pub fn saved_only(mut self, saved_only: bool) -> Self { - self.saved_only = saved_only; + pub fn saved_only>(mut self, saved_only: T) -> Self { + self.saved_only = saved_only.get_optional(); self } @@ -320,11 +320,13 @@ impl<'a> PostQueryBuilder<'a> { )) .into_boxed(); - query = match self.listing_type { - ListingType::Subscribed => query.filter(community_follower::person_id.is_not_null()), // TODO could be this: and(community_follower::person_id.eq(person_id_join)), - ListingType::Local => query.filter(community::local.eq(true)), - _ => query, - }; + if let Some(listing_type) = self.listing_type { + query = match listing_type { + ListingType::Subscribed => query.filter(community_follower::person_id.is_not_null()), + ListingType::Local => query.filter(community::local.eq(true)), + _ => query, + }; + } if let Some(community_id) = self.community_id { query = query @@ -357,25 +359,25 @@ impl<'a> PostQueryBuilder<'a> { query = query.filter(post::creator_id.eq(creator_id)); } - if !self.show_nsfw { + if !self.show_nsfw.unwrap_or(true) { query = query .filter(post::nsfw.eq(false)) .filter(community::nsfw.eq(false)); }; - if !self.show_bot_accounts { + if !self.show_bot_accounts.unwrap_or(true) { query = query.filter(person::bot_account.eq(false)); }; - if self.saved_only { - query = query.filter(post_saved::id.is_not_null()); + if !self.show_read_posts.unwrap_or(true) { + query = query.filter(post_read::id.is_null()); }; - if !self.show_read_posts { - query = query.filter(post_read::id.is_null()); + if self.saved_only.unwrap_or(false) { + query = query.filter(post_saved::id.is_not_null()); }; - query = match self.sort { + query = match self.sort.unwrap_or(SortType::Hot) { SortType::Active => query .then_order_by( hot_rank( @@ -526,8 +528,8 @@ mod tests { }; let read_post_listings_with_person = PostQueryBuilder::create(&conn) - .listing_type(&ListingType::Community) - .sort(&SortType::New) + .listing_type(ListingType::Community) + .sort(SortType::New) .show_bot_accounts(false) .community_id(inserted_community.id) .my_person_id(inserted_person.id) @@ -535,8 +537,8 @@ mod tests { .unwrap(); let read_post_listings_no_person = PostQueryBuilder::create(&conn) - .listing_type(&ListingType::Community) - .sort(&SortType::New) + .listing_type(ListingType::Community) + .sort(SortType::New) .community_id(inserted_community.id) .list() .unwrap(); diff --git a/crates/db_views/src/private_message_view.rs b/crates/db_views/src/private_message_view.rs index 5cef7364e..8fee2fc9b 100644 --- a/crates/db_views/src/private_message_view.rs +++ b/crates/db_views/src/private_message_view.rs @@ -46,7 +46,7 @@ impl PrivateMessageView { pub struct PrivateMessageQueryBuilder<'a> { conn: &'a PgConnection, recipient_id: PersonId, - unread_only: bool, + unread_only: Option, page: Option, limit: Option, } @@ -56,14 +56,14 @@ impl<'a> PrivateMessageQueryBuilder<'a> { PrivateMessageQueryBuilder { conn, recipient_id, - unread_only: false, + unread_only: None, page: None, limit: None, } } - pub fn unread_only(mut self, unread_only: bool) -> Self { - self.unread_only = unread_only; + pub fn unread_only>(mut self, unread_only: T) -> Self { + self.unread_only = unread_only.get_optional(); self } @@ -89,7 +89,7 @@ impl<'a> PrivateMessageQueryBuilder<'a> { .into_boxed(); // If its unread, I only want the ones to me - if self.unread_only { + if self.unread_only.unwrap_or(false) { query = query .filter(private_message::read.eq(false)) .filter(private_message::recipient_id.eq(self.recipient_id)); diff --git a/crates/db_views_actor/src/community_view.rs b/crates/db_views_actor/src/community_view.rs index 0ee503a71..63e529412 100644 --- a/crates/db_views_actor/src/community_view.rs +++ b/crates/db_views_actor/src/community_view.rs @@ -94,10 +94,10 @@ impl CommunityView { pub struct CommunityQueryBuilder<'a> { conn: &'a PgConnection, - listing_type: &'a ListingType, - sort: &'a SortType, + listing_type: Option, + sort: Option, my_person_id: Option, - show_nsfw: bool, + show_nsfw: Option, search_term: Option, page: Option, limit: Option, @@ -108,27 +108,27 @@ impl<'a> CommunityQueryBuilder<'a> { CommunityQueryBuilder { conn, my_person_id: None, - listing_type: &ListingType::All, - sort: &SortType::Hot, - show_nsfw: true, + listing_type: None, + sort: None, + show_nsfw: None, search_term: None, page: None, limit: None, } } - pub fn listing_type(mut self, listing_type: &'a ListingType) -> Self { - self.listing_type = listing_type; + pub fn listing_type>(mut self, listing_type: T) -> Self { + self.listing_type = listing_type.get_optional(); self } - pub fn sort(mut self, sort: &'a SortType) -> Self { - self.sort = sort; + pub fn sort>(mut self, sort: T) -> Self { + self.sort = sort.get_optional(); self } - pub fn show_nsfw(mut self, show_nsfw: bool) -> Self { - self.show_nsfw = show_nsfw; + pub fn show_nsfw>(mut self, show_nsfw: T) -> Self { + self.show_nsfw = show_nsfw.get_optional(); self } @@ -180,7 +180,7 @@ impl<'a> CommunityQueryBuilder<'a> { .or_filter(community::description.ilike(searcher)); }; - match self.sort { + match self.sort.unwrap_or(SortType::Hot) { SortType::New => query = query.order_by(community::published.desc()), SortType::TopAll => query = query.order_by(community_aggregates::subscribers.desc()), SortType::TopMonth => query = query.order_by(community_aggregates::users_active_month.desc()), @@ -198,15 +198,17 @@ impl<'a> CommunityQueryBuilder<'a> { } }; - if !self.show_nsfw { + if !self.show_nsfw.unwrap_or(true) { query = query.filter(community::nsfw.eq(false)); }; - query = match self.listing_type { - ListingType::Subscribed => query.filter(community_follower::person_id.is_not_null()), // TODO could be this: and(community_follower::person_id.eq(person_id_join)), - ListingType::Local => query.filter(community::local.eq(true)), - _ => query, - }; + if let Some(listing_type) = self.listing_type { + query = match listing_type { + ListingType::Subscribed => query.filter(community_follower::person_id.is_not_null()), // TODO could be this: and(community_follower::person_id.eq(person_id_join)), + ListingType::Local => query.filter(community::local.eq(true)), + _ => query, + }; + } let (limit, offset) = limit_and_offset(self.page, self.limit); let res = query diff --git a/crates/db_views_actor/src/person_mention_view.rs b/crates/db_views_actor/src/person_mention_view.rs index 958d084be..b391345ff 100644 --- a/crates/db_views_actor/src/person_mention_view.rs +++ b/crates/db_views_actor/src/person_mention_view.rs @@ -155,8 +155,8 @@ pub struct PersonMentionQueryBuilder<'a> { conn: &'a PgConnection, my_person_id: Option, recipient_id: Option, - sort: &'a SortType, - unread_only: bool, + sort: Option, + unread_only: Option, page: Option, limit: Option, } @@ -167,20 +167,20 @@ impl<'a> PersonMentionQueryBuilder<'a> { conn, my_person_id: None, recipient_id: None, - sort: &SortType::New, - unread_only: false, + sort: None, + unread_only: None, page: None, limit: None, } } - pub fn sort(mut self, sort: &'a SortType) -> Self { - self.sort = sort; + pub fn sort>(mut self, sort: T) -> Self { + self.sort = sort.get_optional(); self } - pub fn unread_only(mut self, unread_only: bool) -> Self { - self.unread_only = unread_only; + pub fn unread_only>(mut self, unread_only: T) -> Self { + self.unread_only = unread_only.get_optional(); self } @@ -264,11 +264,11 @@ impl<'a> PersonMentionQueryBuilder<'a> { query = query.filter(person_mention::recipient_id.eq(recipient_id)); } - if self.unread_only { + if self.unread_only.unwrap_or(false) { query = query.filter(person_mention::read.eq(false)); } - query = match self.sort { + query = match self.sort.unwrap_or(SortType::Hot) { SortType::Hot | SortType::Active => query .order_by(hot_rank(comment_aggregates::score, comment_aggregates::published).desc()) .then_order_by(comment_aggregates::published.desc()), diff --git a/crates/db_views_actor/src/person_view.rs b/crates/db_views_actor/src/person_view.rs index 8e292c3fc..861d333fe 100644 --- a/crates/db_views_actor/src/person_view.rs +++ b/crates/db_views_actor/src/person_view.rs @@ -57,7 +57,7 @@ impl PersonViewSafe { pub struct PersonQueryBuilder<'a> { conn: &'a PgConnection, - sort: &'a SortType, + sort: Option, search_term: Option, page: Option, limit: Option, @@ -68,14 +68,14 @@ impl<'a> PersonQueryBuilder<'a> { PersonQueryBuilder { conn, search_term: None, - sort: &SortType::Hot, + sort: None, page: None, limit: None, } } - pub fn sort(mut self, sort: &'a SortType) -> Self { - self.sort = sort; + pub fn sort>(mut self, sort: T) -> Self { + self.sort = sort.get_optional(); self } @@ -104,7 +104,7 @@ impl<'a> PersonQueryBuilder<'a> { query = query.filter(person::name.ilike(fuzzy_search(&search_term))); } - query = match self.sort { + query = match self.sort.unwrap_or(SortType::Hot) { SortType::Hot => query .order_by(person_aggregates::comment_score.desc()) .then_order_by(person::published.desc()), diff --git a/crates/routes/src/feeds.rs b/crates/routes/src/feeds.rs index 2ed586737..06b9ac13a 100644 --- a/crates/routes/src/feeds.rs +++ b/crates/routes/src/feeds.rs @@ -90,11 +90,10 @@ async fn get_feed_data( ) -> Result { let site_view = blocking(context.pool(), move |conn| SiteView::read(&conn)).await??; - let listing_type_ = listing_type.clone(); let posts = blocking(context.pool(), move |conn| { PostQueryBuilder::create(&conn) - .listing_type(&listing_type_) - .sort(&sort_type) + .listing_type(listing_type) + .sort(sort_type) .list() }) .await??; @@ -174,8 +173,8 @@ fn get_feed_user( let person = Person::find_by_name(&conn, &user_name)?; let posts = PostQueryBuilder::create(&conn) - .listing_type(&ListingType::All) - .sort(sort_type) + .listing_type(ListingType::All) + .sort(*sort_type) .creator_id(person.id) .list()?; @@ -200,8 +199,8 @@ fn get_feed_community( let community = Community::read_from_name(&conn, &community_name)?; let posts = PostQueryBuilder::create(&conn) - .listing_type(&ListingType::All) - .sort(sort_type) + .listing_type(ListingType::All) + .sort(*sort_type) .community_id(community.id) .list()?; @@ -234,11 +233,11 @@ fn get_feed_front( let show_read_posts = local_user.show_read_posts; let posts = PostQueryBuilder::create(&conn) - .listing_type(&ListingType::Subscribed) + .listing_type(ListingType::Subscribed) .my_person_id(person_id) .show_bot_accounts(show_bot_accounts) .show_read_posts(show_read_posts) - .sort(sort_type) + .sort(*sort_type) .list()?; let items = create_post_items(posts)?; @@ -270,13 +269,13 @@ fn get_feed_inbox(conn: &PgConnection, jwt: String) -> Result