"lazy_static",
"lemmy_apub",
"lemmy_db",
+ "lemmy_db_schema",
"lemmy_rate_limit",
"lemmy_structs",
"lemmy_utils",
"itertools",
"lazy_static",
"lemmy_db",
+ "lemmy_db_schema",
"lemmy_structs",
"lemmy_utils",
"lemmy_websocket",
"bcrypt",
"chrono",
"diesel",
+ "diesel_migrations",
"lazy_static",
+ "lemmy_db_schema",
"lemmy_utils",
"log",
"regex",
"url",
]
+ [[package]]
+ name = "lemmy_db_schema"
+ version = "0.1.0"
+ dependencies = [
+ "chrono",
+ "diesel",
+ "log",
+ "serde 1.0.118",
+ "serde_json",
+ "url",
+ ]
+
[[package]]
name = "lemmy_rate_limit"
version = "0.1.0"
"lemmy_api",
"lemmy_apub",
"lemmy_db",
+ "lemmy_db_schema",
"lemmy_rate_limit",
"lemmy_structs",
"lemmy_utils",
"chrono",
"diesel",
"lemmy_db",
+ "lemmy_db_schema",
"lemmy_utils",
"log",
"serde 1.0.118",
"chrono",
"diesel",
"lemmy_db",
+ "lemmy_db_schema",
"lemmy_rate_limit",
"lemmy_structs",
"lemmy_utils",
version = "0.0.1"
edition = "2018"
-[profile.release]
-lto = true
+#[profile.release]
+#lto = true
[workspace]
members = [
"lemmy_apub",
"lemmy_utils",
"lemmy_db",
+ "lemmy_db_schema",
"lemmy_structs",
"lemmy_rate_limit",
"lemmy_websocket",
lemmy_api = { path = "./lemmy_api" }
lemmy_apub = { path = "./lemmy_apub" }
lemmy_utils = { path = "./lemmy_utils" }
+ lemmy_db_schema = { path = "./lemmy_db_schema" }
lemmy_db = { path = "./lemmy_db" }
lemmy_structs = { path = "./lemmy_structs" }
lemmy_rate_limit = { path = "./lemmy_rate_limit" }
use crate::{
check_community_ban,
+ check_downvotes_enabled,
collect_moderated_communities,
get_post,
get_user_from_jwt,
use actix_web::web::Data;
use lemmy_apub::{ApubLikeableType, ApubObjectType};
use lemmy_db::{
- source::{
- comment::{Comment, CommentForm, CommentLike, CommentLikeForm, CommentSaved, CommentSavedForm},
- comment_report::{CommentReport, CommentReportForm},
- moderator::{ModRemoveComment, ModRemoveCommentForm},
- },
+ source::comment::Comment_,
views::{
comment_report_view::{CommentReportQueryBuilder, CommentReportView},
comment_view::{CommentQueryBuilder, CommentView},
- site_view::SiteView,
},
Crud,
Likeable,
Saveable,
SortType,
};
-use lemmy_db_schema::source::{comment::*, comment_report::*, moderator::*, post::Post, user::*};
++use lemmy_db_schema::source::{comment::*, comment_report::*, moderator::*};
use lemmy_structs::{blocking, comment::*, send_local_notifs};
use lemmy_utils::{
apub::{make_apub_endpoint, EndpointType},
updated_comment.send_create(&user, context).await?;
// Scan the comment for user mentions, add those rows
+ let post_id = post.id;
let mentions = scrape_text_for_mentions(&comment_form.content);
let recipient_ids = send_local_notifs(
mentions,
// You like your own comment by default
let like_form = CommentLikeForm {
comment_id: inserted_comment.id,
- post_id: data.post_id,
+ post_id,
user_id: user.id,
score: 1,
};
// strip out the recipient_ids, so that
// users don't get double notifs
+ // TODO Do this in a different way
res.recipient_ids = Vec::new();
Ok(res)
updated_comment.send_update(&user, context).await?;
// Do the mentions / recipients
- let post_id = orig_comment.post.id;
- let post = get_post(post_id, context.pool()).await?;
-
let updated_comment_content = updated_comment.content.to_owned();
let mentions = scrape_text_for_mentions(&updated_comment_content);
let recipient_ids = send_local_notifs(
mentions,
updated_comment,
&user,
- post,
+ orig_comment.post,
context.pool(),
false,
)
// strip out the recipient_ids, so that
// users don't get double notifs
+ // TODO again
res.recipient_ids = Vec::new();
Ok(res)
.await??;
// Build the recipients
- let post_id = comment_view.post.id;
- let post = get_post(post_id, context.pool()).await?;
+ let comment_view_2 = comment_view.clone();
let mentions = vec![];
let recipient_ids = send_local_notifs(
mentions,
updated_comment,
&user,
- post,
+ comment_view_2.post,
context.pool(),
false,
)
let mut res = CommentResponse {
comment_view,
recipient_ids,
- form_id: None,
+ form_id: None, // TODO a comment delete might clear forms?
};
context.chat_server().do_send(SendComment {
// strip out the recipient_ids, so that
// users don't get double notifs
+ // TODO again
res.recipient_ids = Vec::new();
Ok(res)
.await??;
// Build the recipients
- let post_id = comment_view.post.id;
- let post = get_post(post_id, context.pool()).await?;
+ let comment_view_2 = comment_view.clone();
+
let mentions = vec![];
let recipient_ids = send_local_notifs(
mentions,
updated_comment,
&user,
- post,
+ comment_view_2.post,
context.pool(),
false,
)
let mut res = CommentResponse {
comment_view,
recipient_ids,
- form_id: None,
+ form_id: None, // TODO maybe this might clear other forms
};
context.chat_server().do_send(SendComment {
// strip out the recipient_ids, so that
// users don't get double notifs
+ // TODO again
res.recipient_ids = Vec::new();
Ok(res)
let data: &MarkCommentAsRead = &self;
let user = get_user_from_jwt(&data.auth, context.pool()).await?;
- let edit_id = data.edit_id;
+ let comment_id = data.comment_id;
let orig_comment = blocking(context.pool(), move |conn| {
- CommentView::read(&conn, edit_id, None)
+ CommentView::read(&conn, comment_id, None)
})
.await??;
check_community_ban(user.id, orig_comment.community.id, context.pool()).await?;
// Verify that only the recipient can mark as read
- // Needs to fetch the parent comment / post to get the recipient
- let parent_id = orig_comment.comment.parent_id;
- match parent_id {
- Some(pid) => {
- let parent_comment = blocking(context.pool(), move |conn| {
- CommentView::read(&conn, pid, None)
- })
- .await??;
- if user.id != parent_comment.creator.id {
- return Err(APIError::err("no_comment_edit_allowed").into());
- }
- }
- None => {
- let parent_post_id = orig_comment.post.id;
- let parent_post =
- blocking(context.pool(), move |conn| Post::read(conn, parent_post_id)).await??;
- if user.id != parent_post.creator_id {
- return Err(APIError::err("no_comment_edit_allowed").into());
- }
- }
+ if user.id != orig_comment.get_recipient_id() {
+ return Err(APIError::err("no_comment_edit_allowed").into());
}
// Do the mark as read
let read = data.read;
match blocking(context.pool(), move |conn| {
- Comment::update_read(conn, edit_id, read)
+ Comment::update_read(conn, comment_id, read)
})
.await?
{
};
// Refetch it
- let edit_id = data.edit_id;
+ let edit_id = data.comment_id;
let user_id = user.id;
let comment_view = blocking(context.pool(), move |conn| {
CommentView::read(conn, edit_id, Some(user_id))
let mut recipient_ids = Vec::new();
// Don't do a downvote if site has downvotes disabled
- if data.score == -1 {
- let site_view = blocking(context.pool(), move |conn| SiteView::read(conn)).await??;
- if !site_view.site.enable_downvotes {
- return Err(APIError::err("downvotes_disabled").into());
- }
- }
+ check_downvotes_enabled(data.score, context.pool()).await?;
let comment_id = data.comment_id;
let orig_comment = blocking(context.pool(), move |conn| {
})
.await??;
- let post_id = orig_comment.post.id;
- let post = get_post(post_id, context.pool()).await?;
- check_community_ban(user.id, post.community_id, context.pool()).await?;
+ check_community_ban(user.id, orig_comment.community.id, context.pool()).await?;
- let comment_id = data.comment_id;
- let comment = blocking(context.pool(), move |conn| Comment::read(conn, comment_id)).await??;
-
- // Add to recipient ids
- match comment.parent_id {
- Some(parent_id) => {
- let parent_comment =
- blocking(context.pool(), move |conn| Comment::read(conn, parent_id)).await??;
- if parent_comment.creator_id != user.id {
- let parent_user = blocking(context.pool(), move |conn| {
- User_::read(conn, parent_comment.creator_id)
- })
- .await??;
- recipient_ids.push(parent_user.id);
- }
- }
- None => {
- recipient_ids.push(post.creator_id);
- }
- }
+ // Add parent user to recipients
+ recipient_ids.push(orig_comment.get_recipient_id());
let like_form = CommentLikeForm {
comment_id: data.comment_id,
- post_id,
+ post_id: orig_comment.post.id,
user_id: user.id,
score: data.score,
};
.await??;
// Only add the like if the score isnt 0
+ let comment = orig_comment.comment;
let do_add = like_form.score != 0 && (like_form.score == 1 || like_form.score == -1);
if do_add {
let like_form2 = like_form.clone();
// strip out the recipient_ids, so that
// users don't get double notifs
res.recipient_ids = Vec::new();
+ // TODO why
Ok(res)
}
use lemmy_apub::ActorType;
use lemmy_db::{
diesel_option_overwrite,
- naive_now,
- source::{comment::Comment, community::*, moderator::*, post::Post, site::*},
+ source::{
+ comment::Comment_,
+ community::{CommunityModerator_, Community_},
+ post::Post_,
+ },
views::{
comment_view::CommentQueryBuilder,
community::{
Joinable,
SortType,
};
+ use lemmy_db_schema::{
+ naive_now,
+ source::{comment::Comment, community::*, moderator::*, post::Post, site::*},
+ };
use lemmy_structs::{blocking, community::*};
use lemmy_utils::{
apub::{generate_actor_keypair, make_apub_endpoint, EndpointType},
let user = get_user_from_jwt_opt(&data.auth, context.pool()).await?;
let user_id = user.map(|u| u.id);
- let name = data.name.to_owned().unwrap_or_else(|| "main".to_string());
- let community = match data.id {
- Some(id) => blocking(context.pool(), move |conn| Community::read(conn, id)).await??,
- None => match blocking(context.pool(), move |conn| {
- Community::read_from_name(conn, &name)
- })
- .await?
- {
- Ok(community) => community,
- Err(_e) => return Err(APIError::err("couldnt_find_community").into()),
- },
+ let community_id = match data.id {
+ Some(id) => id,
+ None => {
+ let name = data.name.to_owned().unwrap_or_else(|| "main".to_string());
+ match blocking(context.pool(), move |conn| {
+ Community::read_from_name(conn, &name)
+ })
+ .await?
+ {
+ Ok(community) => community,
+ Err(_e) => return Err(APIError::err("couldnt_find_community").into()),
+ }
+ .id
+ }
};
- let community_id = community.id;
let community_view = match blocking(context.pool(), move |conn| {
CommunityView::read(conn, community_id, user_id)
})
Err(_e) => return Err(APIError::err("couldnt_find_community").into()),
};
- let community_id = community.id;
let moderators: Vec<CommunityModeratorView> = match blocking(context.pool(), move |conn| {
CommunityModeratorView::for_community(conn, community_id)
})
Err(_e) => return Err(APIError::err("community_already_exists").into()),
};
+ // The community creator becomes a moderator
let community_moderator_form = CommunityModeratorForm {
community_id: inserted_community.id,
user_id: user.id,
return Err(APIError::err("community_moderator_already_exists").into());
}
+ // Follow your own community
let community_follower_form = CommunityFollowerForm {
community_id: inserted_community.id,
user_id: user.id,
}
// Remove/Restore their data if that's desired
- if let Some(remove_data) = data.remove_data {
+ if data.remove_data {
// Posts
blocking(context.pool(), move |conn: &'_ _| {
- Post::update_removed_for_creator(conn, banned_user_id, Some(community_id), remove_data)
+ Post::update_removed_for_creator(conn, banned_user_id, Some(community_id), true)
})
.await??;
// Comments
- // Diesel doesn't allow updates with joins, so this has to be a loop
+ // TODO Diesel doesn't allow updates with joins, so this has to be a loop
let comments = blocking(context.pool(), move |conn| {
CommentQueryBuilder::create(conn)
.creator_id(banned_user_id)
for comment_view in &comments {
let comment_id = comment_view.comment.id;
blocking(context.pool(), move |conn: &'_ _| {
- Comment::update_removed(conn, comment_id, remove_data)
+ Comment::update_removed(conn, comment_id, true)
})
.await??;
}
let mut admins = blocking(context.pool(), move |conn| UserViewSafe::admins(conn)).await??;
+ // Making sure the creator, if an admin, is at the top
let creator_index = admins
.iter()
.position(|r| r.user.id == site_creator_id)
use crate::claims::Claims;
use actix_web::{web, web::Data};
use lemmy_db::{
- source::community::{CommunityModerator_, Community_},
+ source::{
- community::{Community, CommunityModerator},
- post::Post,
- site::Site,
- user::User_,
++ community::{CommunityModerator_, Community_},
++ site::Site_,
+ },
views::community::community_user_ban_view::CommunityUserBanView,
Crud,
DbPool,
};
+ use lemmy_db_schema::source::{
+ community::{Community, CommunityModerator},
+ post::Post,
++ site::Site,
+ user::User_,
+ };
use lemmy_structs::{blocking, comment::*, community::*, post::*, site::*, user::*};
use lemmy_utils::{settings::Settings, APIError, ConnectionId, LemmyError};
use lemmy_websocket::{serialize_websocket_message, LemmyContext, UserOperation};
}
}
+pub(crate) async fn check_downvotes_enabled(score: i16, pool: &DbPool) -> Result<(), LemmyError> {
+ if score == -1 {
+ let site = blocking(pool, move |conn| Site::read_simple(conn)).await??;
+ if !site.enable_downvotes {
+ return Err(APIError::err("downvotes_disabled").into());
+ }
+ }
+ Ok(())
+}
+
/// Returns a list of communities that the user moderates
/// or if a community_id is supplied validates the user is a moderator
/// of that community and returns the community id in a vec
use crate::{
check_community_ban,
+ check_downvotes_enabled,
check_optional_url,
collect_moderated_communities,
get_user_from_jwt,
use actix_web::web::Data;
use lemmy_apub::{ApubLikeableType, ApubObjectType};
use lemmy_db::{
- naive_now,
- source::{
- moderator::*,
- post::*,
- post_report::{PostReport, PostReportForm},
- },
+ source::post::Post_,
views::{
comment_view::CommentQueryBuilder,
- community::{community_moderator_view::CommunityModeratorView, community_view::CommunityView},
+ community::community_moderator_view::CommunityModeratorView,
post_report_view::{PostReportQueryBuilder, PostReportView},
post_view::{PostQueryBuilder, PostView},
- site_view::SiteView,
},
Crud,
Likeable,
Saveable,
SortType,
};
+ use lemmy_db_schema::{
+ naive_now,
+ source::{
+ moderator::*,
+ post::*,
+ post_report::{PostReport, PostReportForm},
+ },
+ };
use lemmy_structs::{blocking, post::*};
use lemmy_utils::{
apub::{make_apub_endpoint, EndpointType},
})
.await??;
- let community_id = post_view.community.id;
- let community = blocking(context.pool(), move |conn| {
- CommunityView::read(conn, community_id, user_id)
- })
- .await??;
-
let community_id = post_view.community.id;
let moderators = blocking(context.pool(), move |conn| {
CommunityModeratorView::for_community(conn, community_id)
Ok(GetPostResponse {
post_view,
comments,
- community,
moderators,
online,
})
let user = get_user_from_jwt(&data.auth, context.pool()).await?;
// Don't do a downvote if site has downvotes disabled
- if data.score == -1 {
- let site_view = blocking(context.pool(), move |conn| SiteView::read(conn)).await??;
- if !site_view.site.enable_downvotes {
- return Err(APIError::err("downvotes_disabled").into());
- }
- }
+ check_downvotes_enabled(data.score, context.pool()).await?;
// Check for a community ban
let post_id = data.post_id;
use anyhow::Context;
use lemmy_apub::fetcher::search_by_apub_id;
use lemmy_db::{
- aggregates::site_aggregates::SiteAggregates,
diesel_option_overwrite,
- naive_now,
- source::{category::*, moderator::*, site::*},
+ source::{category::Category_, site::Site_},
views::{
comment_view::CommentQueryBuilder,
community::community_view::CommunityQueryBuilder,
SearchType,
SortType,
};
+ use lemmy_db_schema::{
+ naive_now,
+ source::{
+ category::Category,
+ moderator::*,
+ site::{Site, *},
+ },
+ };
use lemmy_structs::{blocking, site::*, user::Register};
use lemmy_utils::{
location_info,
) -> Result<SiteResponse, LemmyError> {
let data: &CreateSite = &self;
- let read_site = move |conn: &'_ _| Site::read(conn, 1);
+ let read_site = move |conn: &'_ _| Site::read_simple(conn);
if blocking(context.pool(), read_site).await?.is_ok() {
return Err(APIError::err("site_already_exists").into());
};
let site_view = blocking(context.pool(), move |conn| SiteView::read(conn)).await??;
- Ok(SiteResponse { site: site_view })
+ Ok(SiteResponse { site_view })
}
}
// Make sure user is an admin
is_admin(context.pool(), user.id).await?;
- let found_site = blocking(context.pool(), move |conn| Site::read(conn, 1)).await??;
+ let found_site = blocking(context.pool(), move |conn| Site::read_simple(conn)).await??;
let icon = diesel_option_overwrite(&data.icon);
let banner = diesel_option_overwrite(&data.banner);
let site_view = blocking(context.pool(), move |conn| SiteView::read(conn)).await??;
- let res = SiteResponse { site: site_view };
+ let res = SiteResponse { site_view };
context.chat_server().do_send(SendAllMessage {
op: UserOperation::EditSite,
) -> Result<GetSiteResponse, LemmyError> {
let data: &GetSite = &self;
- // TODO refactor this a little
- let res = blocking(context.pool(), move |conn| Site::read(conn, 1)).await?;
- let site_view = if res.is_ok() {
- Some(blocking(context.pool(), move |conn| SiteView::read(conn)).await??)
- } else if let Some(setup) = Settings::get().setup.as_ref() {
- let register = Register {
- username: setup.admin_username.to_owned(),
- email: setup.admin_email.to_owned(),
- password: setup.admin_password.to_owned(),
- password_verify: setup.admin_password.to_owned(),
- admin: true,
- show_nsfw: true,
- captcha_uuid: None,
- captcha_answer: None,
- };
- let login_response = register.perform(context, websocket_id).await?;
- info!("Admin {} created", setup.admin_username);
-
- let create_site = CreateSite {
- name: setup.site_name.to_owned(),
- description: None,
- icon: None,
- banner: None,
- enable_downvotes: true,
- open_registration: true,
- enable_nsfw: true,
- auth: login_response.jwt,
- };
- create_site.perform(context, websocket_id).await?;
- info!("Site {} created", setup.site_name);
- Some(blocking(context.pool(), move |conn| SiteView::read(conn)).await??)
- } else {
- None
+ let site_view = match blocking(context.pool(), move |conn| SiteView::read(conn)).await? {
+ Ok(site_view) => Some(site_view),
+ // If the site isn't created yet, check the setup
+ Err(_) => {
+ if let Some(setup) = Settings::get().setup.as_ref() {
+ let register = Register {
+ username: setup.admin_username.to_owned(),
+ email: setup.admin_email.to_owned(),
+ password: setup.admin_password.to_owned(),
+ password_verify: setup.admin_password.to_owned(),
+ admin: true,
+ show_nsfw: true,
+ captcha_uuid: None,
+ captcha_answer: None,
+ };
+ let login_response = register.perform(context, websocket_id).await?;
+ info!("Admin {} created", setup.admin_username);
+
+ let create_site = CreateSite {
+ name: setup.site_name.to_owned(),
+ description: None,
+ icon: None,
+ banner: None,
+ enable_downvotes: true,
+ open_registration: true,
+ enable_nsfw: true,
+ auth: login_response.jwt,
+ };
+ create_site.perform(context, websocket_id).await?;
+ info!("Site {} created", setup.site_name);
+ Some(blocking(context.pool(), move |conn| SiteView::read(conn)).await??)
+ } else {
+ None
+ }
+ }
};
let mut admins = blocking(context.pool(), move |conn| UserViewSafe::admins(conn)).await??;
u
});
- let counts = blocking(context.pool(), move |conn| SiteAggregates::read(conn)).await??;
-
Ok(GetSiteResponse {
- site: site_view,
+ site_view,
admins,
banned,
online,
version: version::VERSION.to_string(),
my_user,
federated_instances: linked_instances(context.pool()).await?,
- counts,
})
}
}
user.private_key = None;
user.public_key = None;
- let read_site = blocking(context.pool(), move |conn| Site::read(conn, 1)).await??;
+ let read_site = blocking(context.pool(), move |conn| Site::read_simple(conn)).await??;
// Make sure user is the creator
if read_site.creator_id != user.id {
let banned = blocking(context.pool(), move |conn| UserViewSafe::banned(conn)).await??;
- let counts = blocking(context.pool(), move |conn| SiteAggregates::read(conn)).await??;
-
Ok(GetSiteResponse {
- site: Some(site_view),
+ site_view: Some(site_view),
admins,
banned,
online: 0,
version: version::VERSION.to_string(),
my_user: Some(user),
federated_instances: linked_instances(context.pool()).await?,
- counts,
})
}
}
let user = get_user_from_jwt(&data.auth, context.pool()).await?;
// Only let admins read this
- let admins = blocking(context.pool(), move |conn| UserViewSafe::admins(conn)).await??;
- let admin_ids: Vec<i32> = admins.into_iter().map(|m| m.user.id).collect();
-
- if !admin_ids.contains(&user.id) {
- return Err(APIError::err("not_an_admin").into());
- }
+ let user_id = user.id;
+ is_admin(context.pool(), user_id).await?;
// Make sure docker doesn't have :ro at the end of the volume, so its not a read-only filesystem
let config_hjson = match Settings::save_config_file(&data.config_hjson) {
use lemmy_apub::ApubObjectType;
use lemmy_db::{
diesel_option_overwrite,
- naive_now,
source::{
- comment::*,
- community::*,
- moderator::*,
- password_reset_request::*,
- post::*,
- private_message::*,
- site::*,
- user::*,
- user_mention::*,
+ comment::Comment_,
+ community::Community_,
+ password_reset_request::PasswordResetRequest_,
+ post::Post_,
+ private_message::PrivateMessage_,
++ site::Site_,
+ user::User,
+ user_mention::UserMention_,
},
views::{
comment_report_view::CommentReportView,
post_report_view::PostReportView,
post_view::PostQueryBuilder,
private_message_view::{PrivateMessageQueryBuilder, PrivateMessageView},
- site_view::SiteView,
user_mention_view::{UserMentionQueryBuilder, UserMentionView},
user_view::{UserViewDangerous, UserViewSafe},
},
ListingType,
SortType,
};
+ use lemmy_db_schema::{
+ naive_now,
+ source::{
+ comment::Comment,
+ community::*,
+ moderator::*,
+ password_reset_request::*,
+ post::Post,
+ private_message::*,
+ site::*,
+ user::*,
+ user_mention::*,
+ },
+ };
use lemmy_structs::{blocking, send_email_to_user, user::*};
use lemmy_utils::{
apub::{generate_actor_keypair, make_apub_endpoint, EndpointType},
let data: &Register = &self;
// Make sure site has open registration
- if let Ok(site_view) = blocking(context.pool(), move |conn| SiteView::read(conn)).await? {
- if !site_view.site.open_registration {
+ if let Ok(site) = blocking(context.pool(), move |conn| Site::read_simple(conn)).await? {
+ if !site.open_registration {
return Err(APIError::err("registration_closed").into());
}
}
let data: &SaveUserSettings = &self;
let user = get_user_from_jwt(&data.auth, context.pool()).await?;
- let user_id = user.id;
- let read_user = blocking(context.pool(), move |conn| User_::read(conn, user_id)).await??;
-
let avatar = diesel_option_overwrite(&data.avatar);
let banner = diesel_option_overwrite(&data.banner);
let email = diesel_option_overwrite(&data.email);
}
}
+ let user_id = user.id;
let password_encrypted = match &data.new_password {
Some(new_password) => {
match &data.new_password_verify {
// Check the old password
match &data.old_password {
Some(old_password) => {
- let valid: bool =
- verify(old_password, &read_user.password_encrypted).unwrap_or(false);
+ let valid: bool = verify(old_password, &user.password_encrypted).unwrap_or(false);
if !valid {
return Err(APIError::err("password_incorrect").into());
}
None => return Err(APIError::err("passwords_dont_match").into()),
}
}
- None => read_user.password_encrypted,
+ None => user.password_encrypted,
};
+ let default_listing_type = ListingType::from_str(&data.default_listing_type)? as i16;
+ let default_sort_type = SortType::from_str(&data.default_sort_type)? as i16;
+
let user_form = UserForm {
- name: read_user.name,
+ name: user.name,
email,
matrix_user_id,
avatar,
banner,
password_encrypted,
preferred_username,
- published: Some(read_user.published),
+ published: Some(user.published),
updated: Some(naive_now()),
- admin: read_user.admin,
- banned: Some(read_user.banned),
+ admin: user.admin,
+ banned: Some(user.banned),
show_nsfw: data.show_nsfw,
theme: data.theme.to_owned(),
- default_sort_type: data.default_sort_type,
- default_listing_type: data.default_listing_type,
+ default_sort_type,
+ default_listing_type,
lang: data.lang.to_owned(),
show_avatars: data.show_avatars,
send_notifications_to_email: data.send_notifications_to_email,
- actor_id: Some(read_user.actor_id),
+ actor_id: Some(user.actor_id),
bio,
- local: read_user.local,
- private_key: read_user.private_key,
- public_key: read_user.public_key,
+ local: user.local,
+ private_key: user.private_key,
+ public_key: user.public_key,
last_refreshed_at: None,
};
// Return the jwt
Ok(GetUserDetailsResponse {
- // TODO need to figure out dangerous user view here
- user: user_view,
- user_dangerous,
+ user_view,
+ user_view_dangerous: user_dangerous,
follows,
moderates,
comments,
}
// Remove their data if that's desired
- if let Some(remove_data) = data.remove_data {
+ if data.remove_data {
// Posts
blocking(context.pool(), move |conn: &'_ _| {
- Post::update_removed_for_creator(conn, banned_user_id, None, remove_data)
+ Post::update_removed_for_creator(conn, banned_user_id, None, true)
})
.await??;
// Communities
blocking(context.pool(), move |conn: &'_ _| {
- Community::update_removed_for_creator(conn, banned_user_id, remove_data)
+ Community::update_removed_for_creator(conn, banned_user_id, true)
})
.await??;
// Comments
blocking(context.pool(), move |conn: &'_ _| {
- Comment::update_removed_for_creator(conn, banned_user_id, remove_data)
+ Comment::update_removed_for_creator(conn, banned_user_id, true)
})
.await??;
}
.await??;
let res = BanUserResponse {
- user: user_view,
+ user_view,
banned: data.ban,
};
})
.await??;
- let res = PrivateMessageResponse { message };
+ let res = PrivateMessageResponse {
+ private_message_view: message,
+ };
context.chat_server().do_send(SendUserRoomMessage {
op: UserOperation::CreatePrivateMessage,
.await??;
let recipient_id = message.recipient.id;
- let res = PrivateMessageResponse { message };
+ let res = PrivateMessageResponse {
+ private_message_view: message,
+ };
context.chat_server().do_send(SendUserRoomMessage {
op: UserOperation::EditPrivateMessage,
.await??;
let recipient_id = message.recipient.id;
- let res = PrivateMessageResponse { message };
+ let res = PrivateMessageResponse {
+ private_message_view: message,
+ };
context.chat_server().do_send(SendUserRoomMessage {
op: UserOperation::DeletePrivateMessage,
.await??;
let recipient_id = message.recipient.id;
- let res = PrivateMessageResponse { message };
+ let res = PrivateMessageResponse {
+ private_message_view: message,
+ };
context.chat_server().do_send(SendUserRoomMessage {
op: UserOperation::MarkPrivateMessageAsRead,
})
.await??;
- Ok(PrivateMessagesResponse { messages })
+ Ok(PrivateMessagesResponse {
+ private_messages: messages,
+ })
}
}
};
use anyhow::{anyhow, Context};
use lemmy_db::{
- source::private_message::PrivateMessage,
+ source::private_message::PrivateMessage_,
views::private_message_view::PrivateMessageView,
};
+ use lemmy_db_schema::source::private_message::PrivateMessage;
use lemmy_structs::{blocking, user::PrivateMessageResponse};
use lemmy_utils::{location_info, LemmyError};
use lemmy_websocket::{messages::SendUserRoomMessage, LemmyContext, UserOperation};
})
.await??;
- let res = PrivateMessageResponse { message };
+ let res = PrivateMessageResponse {
+ private_message_view: message,
+ };
- let recipient_id = res.message.recipient.id;
+ let recipient_id = res.private_message_view.recipient.id;
context.chat_server().do_send(SendUserRoomMessage {
op: UserOperation::CreatePrivateMessage,
})
.await??;
- let res = PrivateMessageResponse { message };
+ let res = PrivateMessageResponse {
+ private_message_view: message,
+ };
- let recipient_id = res.message.recipient.id;
+ let recipient_id = res.private_message_view.recipient.id;
context.chat_server().do_send(SendUserRoomMessage {
op: UserOperation::EditPrivateMessage,
})
.await??;
- let res = PrivateMessageResponse { message };
- let recipient_id = res.message.recipient.id;
+ let res = PrivateMessageResponse {
+ private_message_view: message,
+ };
+ let recipient_id = res.private_message_view.recipient.id;
context.chat_server().do_send(SendUserRoomMessage {
op: UserOperation::EditPrivateMessage,
response: res,
})
.await??;
- let res = PrivateMessageResponse { message };
- let recipient_id = res.message.recipient.id;
+ let res = PrivateMessageResponse {
+ private_message_view: message,
+ };
+ let recipient_id = res.private_message_view.recipient.id;
context.chat_server().do_send(SendUserRoomMessage {
op: UserOperation::EditPrivateMessage,
response: res,
WorkerConfig,
};
use itertools::Itertools;
- use lemmy_db::{
- source::{community::Community, user::User_},
- DbPool,
- };
+ use lemmy_db::DbPool;
+ use lemmy_db_schema::source::{community::Community, user::User_};
use lemmy_utils::{location_info, settings::Settings, LemmyError};
use lemmy_websocket::LemmyContext;
use log::{debug, warn};
use reqwest::Client;
use serde::{export::fmt::Debug, Deserialize, Serialize};
-use std::{collections::BTreeMap, future::Future, pin::Pin};
+use std::{collections::BTreeMap, env, future::Future, pin::Pin};
use url::Url;
/// Sends a local activity to a single, remote actor.
actor_id: actor.actor_id()?,
private_key: actor.private_key().context(location_info!())?,
};
- activity_sender.queue::<SendActivityTask>(message)?;
+ if env::var("LEMMY_TEST_SEND_SYNC").is_ok() {
+ do_send(message, &Client::default()).await?;
+ } else {
+ activity_sender.queue::<SendActivityTask>(message)?;
+ }
}
Ok(())
const BACKOFF: Backoff = Backoff::Exponential(2);
fn run(self, state: Self::State) -> Self::Future {
- Box::pin(async move {
- let mut headers = BTreeMap::<String, String>::new();
- headers.insert("Content-Type".into(), "application/json".into());
- let result = sign_and_send(
- &state.client,
- headers,
- &self.inbox,
- self.activity.clone(),
- &self.actor_id,
- self.private_key.to_owned(),
- )
- .await;
+ Box::pin(async move { do_send(self, &state.client).await })
+ }
+}
- if let Err(e) = result {
- warn!("{}", e);
- return Err(anyhow!(
- "Failed to send activity {} to {}",
- &self.activity,
- self.inbox
- ));
- }
- Ok(())
- })
+async fn do_send(task: SendActivityTask, client: &Client) -> Result<(), Error> {
+ let mut headers = BTreeMap::<String, String>::new();
+ headers.insert("Content-Type".into(), "application/json".into());
+ let result = sign_and_send(
+ client,
+ headers,
+ &task.inbox,
+ task.activity.clone(),
+ &task.actor_id,
+ task.private_key.to_owned(),
+ )
+ .await;
+
+ if let Err(e) = result {
+ warn!("{}", e);
+ return Err(anyhow!(
+ "Failed to send activity {} to {}",
+ &task.activity,
+ task.inbox
+ ));
}
+ Ok(())
}
pub fn create_activity_queue() -> QueueHandle {
use actix_web::{web, HttpRequest, HttpResponse};
use anyhow::{anyhow, Context};
use lemmy_db::{
- source::{
- community::{Community, CommunityFollower, CommunityFollowerForm},
- user::User_,
- },
+ source::community::Community_,
views::community::community_user_ban_view::CommunityUserBanView,
ApubObject,
DbPool,
Followable,
};
+ use lemmy_db_schema::source::{
+ community::{Community, CommunityFollower, CommunityFollowerForm},
+ user::User_,
+ };
use lemmy_structs::blocking;
use lemmy_utils::{location_info, LemmyError};
use lemmy_websocket::LemmyContext;
.await?;
}
- return Ok(HttpResponse::Ok().finish());
+ Ok(HttpResponse::Ok().finish())
}
/// Handle a follow request from a remote user, adding the user as follower and returning an
};
use anyhow::Context;
use diesel::result::Error::NotFound;
- use lemmy_db::{
- source::{comment::Comment, post::Post, site::Site},
- ApubObject,
- Crud,
- };
+ use lemmy_db::{ApubObject, Crud};
+ use lemmy_db_schema::source::{comment::Comment, post::Post, site::Site};
use lemmy_structs::blocking;
use lemmy_utils::{location_info, LemmyError};
use lemmy_websocket::LemmyContext;
return Ok(PostOrComment::Comment(c));
}
- return Err(NotFound.into());
+ Err(NotFound.into())
}
async fn fetch_post_or_comment_by_id(
return Ok(PostOrComment::Comment(comment));
}
- return Err(NotFound.into());
+ Err(NotFound.into())
}
fn get_like_object_id<Activity>(like_or_dislike: &Activity) -> Result<Url, LemmyError>
use actix_web::{web, HttpRequest, HttpResponse};
use anyhow::{anyhow, Context};
use diesel::NotFound;
- use lemmy_db::{
- source::{
- community::{Community, CommunityFollower},
- private_message::PrivateMessage,
- user::User_,
- },
- ApubObject,
- Followable,
+ use lemmy_db::{source::user::User, ApubObject, Followable};
+ use lemmy_db_schema::source::{
+ community::{Community, CommunityFollower},
+ private_message::PrivateMessage,
+ user::User_,
};
use lemmy_structs::blocking;
use lemmy_utils::{location_info, LemmyError};
return Ok(CommunityOrPrivateMessage::PrivateMessage(p));
}
- return Err(NotFound.into());
+ Err(NotFound.into())
}
prelude::*,
};
use anyhow::{anyhow, Context};
- use lemmy_db::{
- source::{
- comment::{Comment, CommentForm},
- community::Community,
- post::Post,
- user::User_,
- },
- Crud,
- DbPool,
+ use lemmy_db::{Crud, DbPool};
+ use lemmy_db_schema::source::{
+ comment::{Comment, CommentForm},
+ community::Community,
+ post::Post,
+ user::User_,
};
use lemmy_structs::blocking;
use lemmy_utils::{
Comment::delete(conn, comment.id)
})
.await??;
- return Err(anyhow!("Post is locked").into());
+ Err(anyhow!("Post is locked").into())
} else {
Ok(comment)
}
[dependencies]
lemmy_utils = { path = "../lemmy_utils" }
+ lemmy_db_schema = { path = "../lemmy_db_schema" }
diesel = { version = "1.4.5", features = ["postgres","chrono","r2d2","serde_json"] }
+diesel_migrations = "1.4.0"
chrono = { version = "0.4.19", features = ["serde"] }
serde = { version = "1.0.118", features = ["derive"] }
serde_json = { version = "1.0.60", features = ["preserve_order"] }
strum_macros = "0.20.1"
log = "0.4.11"
sha2 = "0.9.2"
- bcrypt = "0.9.0"
url = { version = "2.2.0", features = ["serde"] }
lazy_static = "1.4.0"
regex = "1.4.2"
+ bcrypt = "0.9.0"
- use crate::schema::comment_aggregates;
use diesel::{result::Error, *};
+ use lemmy_db_schema::schema::comment_aggregates;
use serde::Serialize;
#[derive(Queryable, Associations, Identifiable, PartialEq, Debug, Serialize, Clone)]
}
}
-// TODO add tests here
+#[cfg(test)]
+mod tests {
+ use crate::{
+ aggregates::comment_aggregates::CommentAggregates,
+ source::{
+ comment::{Comment, CommentForm, CommentLike, CommentLikeForm},
+ community::{Community, CommunityForm},
+ post::{Post, PostForm},
+ user::{UserForm, User_},
+ },
+ tests::establish_unpooled_connection,
+ Crud,
+ Likeable,
+ ListingType,
+ SortType,
+ };
+
+ #[test]
+ fn test_crud() {
+ let conn = establish_unpooled_connection();
+
+ let new_user = UserForm {
+ name: "thommy_comment_agg".into(),
+ preferred_username: None,
+ password_encrypted: "nope".into(),
+ email: None,
+ matrix_user_id: None,
+ avatar: None,
+ banner: None,
+ admin: false,
+ banned: Some(false),
+ published: None,
+ updated: None,
+ show_nsfw: false,
+ theme: "browser".into(),
+ default_sort_type: SortType::Hot as i16,
+ default_listing_type: ListingType::Subscribed as i16,
+ lang: "browser".into(),
+ show_avatars: true,
+ send_notifications_to_email: false,
+ actor_id: None,
+ bio: None,
+ local: true,
+ private_key: None,
+ public_key: None,
+ last_refreshed_at: None,
+ };
+
+ let inserted_user = User_::create(&conn, &new_user).unwrap();
+
+ let another_user = UserForm {
+ name: "jerry_comment_agg".into(),
+ preferred_username: None,
+ password_encrypted: "nope".into(),
+ email: None,
+ matrix_user_id: None,
+ avatar: None,
+ banner: None,
+ admin: false,
+ banned: Some(false),
+ published: None,
+ updated: None,
+ show_nsfw: false,
+ theme: "browser".into(),
+ default_sort_type: SortType::Hot as i16,
+ default_listing_type: ListingType::Subscribed as i16,
+ lang: "browser".into(),
+ show_avatars: true,
+ send_notifications_to_email: false,
+ actor_id: None,
+ bio: None,
+ local: true,
+ private_key: None,
+ public_key: None,
+ last_refreshed_at: None,
+ };
+
+ let another_inserted_user = User_::create(&conn, &another_user).unwrap();
+
+ let new_community = CommunityForm {
+ name: "TIL_comment_agg".into(),
+ creator_id: inserted_user.id,
+ title: "nada".to_owned(),
+ description: None,
+ category_id: 1,
+ nsfw: false,
+ removed: None,
+ deleted: None,
+ updated: None,
+ actor_id: None,
+ local: true,
+ private_key: None,
+ public_key: None,
+ last_refreshed_at: None,
+ published: None,
+ icon: None,
+ banner: None,
+ };
+
+ let inserted_community = Community::create(&conn, &new_community).unwrap();
+
+ let new_post = PostForm {
+ name: "A test post".into(),
+ url: None,
+ body: None,
+ creator_id: inserted_user.id,
+ community_id: inserted_community.id,
+ removed: None,
+ deleted: None,
+ locked: None,
+ stickied: None,
+ nsfw: false,
+ updated: None,
+ embed_title: None,
+ embed_description: None,
+ embed_html: None,
+ thumbnail_url: None,
+ ap_id: None,
+ local: true,
+ published: None,
+ };
+
+ let inserted_post = Post::create(&conn, &new_post).unwrap();
+
+ let comment_form = CommentForm {
+ content: "A test comment".into(),
+ creator_id: inserted_user.id,
+ post_id: inserted_post.id,
+ removed: None,
+ deleted: None,
+ read: None,
+ parent_id: None,
+ published: None,
+ updated: None,
+ ap_id: None,
+ local: true,
+ };
+
+ let inserted_comment = Comment::create(&conn, &comment_form).unwrap();
+
+ let child_comment_form = CommentForm {
+ content: "A test comment".into(),
+ creator_id: inserted_user.id,
+ post_id: inserted_post.id,
+ removed: None,
+ deleted: None,
+ read: None,
+ parent_id: Some(inserted_comment.id),
+ published: None,
+ updated: None,
+ ap_id: None,
+ local: true,
+ };
+
+ let _inserted_child_comment = Comment::create(&conn, &child_comment_form).unwrap();
+
+ let comment_like = CommentLikeForm {
+ comment_id: inserted_comment.id,
+ post_id: inserted_post.id,
+ user_id: inserted_user.id,
+ score: 1,
+ };
+
+ CommentLike::like(&conn, &comment_like).unwrap();
+
+ let comment_aggs_before_delete = CommentAggregates::read(&conn, inserted_comment.id).unwrap();
+
+ assert_eq!(1, comment_aggs_before_delete.score);
+ assert_eq!(1, comment_aggs_before_delete.upvotes);
+ assert_eq!(0, comment_aggs_before_delete.downvotes);
+
+ // Add a post dislike from the other user
+ let comment_dislike = CommentLikeForm {
+ comment_id: inserted_comment.id,
+ post_id: inserted_post.id,
+ user_id: another_inserted_user.id,
+ score: -1,
+ };
+
+ CommentLike::like(&conn, &comment_dislike).unwrap();
+
+ let comment_aggs_after_dislike = CommentAggregates::read(&conn, inserted_comment.id).unwrap();
+
+ assert_eq!(0, comment_aggs_after_dislike.score);
+ assert_eq!(1, comment_aggs_after_dislike.upvotes);
+ assert_eq!(1, comment_aggs_after_dislike.downvotes);
+
+ // Remove the first comment like
+ CommentLike::remove(&conn, inserted_user.id, inserted_comment.id).unwrap();
+ let after_like_remove = CommentAggregates::read(&conn, inserted_comment.id).unwrap();
+ assert_eq!(-1, after_like_remove.score);
+ assert_eq!(0, after_like_remove.upvotes);
+ assert_eq!(1, after_like_remove.downvotes);
+
+ // Remove the parent post
+ Post::delete(&conn, inserted_post.id).unwrap();
+
+ // Should be none found, since the post was deleted
+ let after_delete = CommentAggregates::read(&conn, inserted_comment.id);
+ assert!(after_delete.is_err());
+
+ // This should delete all the associated rows, and fire triggers
+ User_::delete(&conn, another_inserted_user.id).unwrap();
+ let user_num_deleted = User_::delete(&conn, inserted_user.id).unwrap();
+ assert_eq!(1, user_num_deleted);
+ }
+}
- use crate::schema::site_aggregates;
use diesel::{result::Error, *};
+ use lemmy_db_schema::schema::site_aggregates;
use serde::Serialize;
-#[derive(Queryable, Associations, Identifiable, PartialEq, Debug, Serialize)]
+#[derive(Queryable, Associations, Identifiable, PartialEq, Debug, Serialize, Clone)]
#[table_name = "site_aggregates"]
pub struct SiteAggregates {
pub id: i32,
+ pub site_id: i32,
pub users: i64,
pub posts: i64,
pub comments: i64,
mod tests {
use crate::{
aggregates::site_aggregates::SiteAggregates,
- source::{
- comment::{Comment, CommentForm},
- community::{Community, CommunityForm},
- post::{Post, PostForm},
- site::{Site, SiteForm},
- user::{UserForm, User_},
- },
tests::establish_unpooled_connection,
Crud,
ListingType,
SortType,
};
+ use lemmy_db_schema::source::{
+ comment::{Comment, CommentForm},
+ community::{Community, CommunityForm},
+ post::{Post, PostForm},
+ user::{UserForm, User_},
+ };
#[test]
fn test_crud() {
let inserted_user = User_::create(&conn, &new_user).unwrap();
+ let site_form = SiteForm {
+ name: "test_site".into(),
+ description: None,
+ icon: None,
+ banner: None,
+ creator_id: inserted_user.id,
+ enable_downvotes: true,
+ open_registration: true,
+ enable_nsfw: true,
+ updated: None,
+ };
+
+ Site::create(&conn, &site_form).unwrap();
+
let new_community = CommunityForm {
name: "TIL_site_agg".into(),
creator_id: inserted_user.id,
let user_num_deleted = User_::delete(&conn, inserted_user.id).unwrap();
assert_eq!(1, user_num_deleted);
- let site_aggregates_after_delete = SiteAggregates::read(&conn).unwrap();
- assert_eq!(0, site_aggregates_after_delete.users);
- assert_eq!(0, site_aggregates_after_delete.communities);
- assert_eq!(0, site_aggregates_after_delete.posts);
- assert_eq!(0, site_aggregates_after_delete.comments);
+ let after_delete = SiteAggregates::read(&conn);
+ assert!(after_delete.is_err());
}
}
extern crate strum_macros;
#[macro_use]
extern crate lazy_static;
+// this is used in tests
+#[allow(unused_imports)]
+#[macro_use]
+extern crate diesel_migrations;
- use chrono::NaiveDateTime;
use diesel::{result::Error, *};
use regex::Regex;
use serde::{Deserialize, Serialize};
use std::{env, env::VarError};
pub mod aggregates;
- pub mod schema;
pub mod source;
pub mod views;
(limit, offset)
}
- pub fn naive_now() -> NaiveDateTime {
- chrono::prelude::Utc::now().naive_utc()
- }
-
pub fn is_email_regex(test: &str) -> bool {
EMAIL_REGEX.is_match(test)
}
use crate::{get_database_url_from_env, is_email_regex};
use diesel::{Connection, PgConnection};
+ embed_migrations!();
+
pub fn establish_unpooled_connection() -> PgConnection {
let db_url = match get_database_url_from_env() {
Ok(url) => url,
e
),
};
- PgConnection::establish(&db_url).unwrap_or_else(|_| panic!("Error connecting to {}", db_url))
+ let conn =
+ PgConnection::establish(&db_url).unwrap_or_else(|_| panic!("Error connecting to {}", db_url));
+ embedded_migrations::run(&conn).unwrap();
+ conn
}
#[test]
- use crate::{
+ use crate::{ApubObject, Crud, Likeable, Readable, Saveable};
+ use diesel::{dsl::*, result::Error, *};
+ use lemmy_db_schema::{
naive_now,
- schema::{post, post_like, post_read, post_saved},
- ApubObject,
- Crud,
- Likeable,
- Readable,
- Saveable,
+ source::post::{
+ Post,
+ PostForm,
+ PostLike,
+ PostLikeForm,
+ PostRead,
+ PostReadForm,
+ PostSaved,
+ PostSavedForm,
+ },
};
- use diesel::{dsl::*, result::Error, *};
- use serde::Serialize;
- use url::{ParseError, Url};
-
- #[derive(Clone, Queryable, Identifiable, PartialEq, Debug, Serialize)]
- #[table_name = "post"]
- pub struct Post {
- pub id: i32,
- pub name: String,
- pub url: Option<String>,
- pub body: Option<String>,
- pub creator_id: i32,
- pub community_id: i32,
- pub removed: bool,
- pub locked: bool,
- pub published: chrono::NaiveDateTime,
- pub updated: Option<chrono::NaiveDateTime>,
- pub deleted: bool,
- pub nsfw: bool,
- pub stickied: bool,
- pub embed_title: Option<String>,
- pub embed_description: Option<String>,
- pub embed_html: Option<String>,
- pub thumbnail_url: Option<String>,
- pub ap_id: String,
- pub local: bool,
- }
-
- #[derive(Insertable, AsChangeset)]
- #[table_name = "post"]
- pub struct PostForm {
- pub name: String,
- pub url: Option<String>,
- pub body: Option<String>,
- pub creator_id: i32,
- pub community_id: i32,
- pub removed: Option<bool>,
- pub locked: Option<bool>,
- pub published: Option<chrono::NaiveDateTime>,
- pub updated: Option<chrono::NaiveDateTime>,
- pub deleted: Option<bool>,
- pub nsfw: bool,
- pub stickied: Option<bool>,
- pub embed_title: Option<String>,
- pub embed_description: Option<String>,
- pub embed_html: Option<String>,
- pub thumbnail_url: Option<String>,
- pub ap_id: Option<String>,
- pub local: bool,
- }
-
- impl PostForm {
- pub fn get_ap_id(&self) -> Result<Url, ParseError> {
- Url::parse(&self.ap_id.as_ref().unwrap_or(&"not_a_url".to_string()))
- }
- }
impl Crud<PostForm> for Post {
fn read(conn: &PgConnection, post_id: i32) -> Result<Self, Error> {
- use crate::schema::post::dsl::*;
+ use lemmy_db_schema::schema::post::dsl::*;
post.find(post_id).first::<Self>(conn)
}
fn delete(conn: &PgConnection, post_id: i32) -> Result<usize, Error> {
- use crate::schema::post::dsl::*;
+ use lemmy_db_schema::schema::post::dsl::*;
diesel::delete(post.find(post_id)).execute(conn)
}
fn create(conn: &PgConnection, new_post: &PostForm) -> Result<Self, Error> {
- use crate::schema::post::dsl::*;
+ use lemmy_db_schema::schema::post::dsl::*;
insert_into(post).values(new_post).get_result::<Self>(conn)
}
fn update(conn: &PgConnection, post_id: i32, new_post: &PostForm) -> Result<Self, Error> {
- use crate::schema::post::dsl::*;
+ use lemmy_db_schema::schema::post::dsl::*;
diesel::update(post.find(post_id))
.set(new_post)
.get_result::<Self>(conn)
}
}
- impl ApubObject<PostForm> for Post {
- fn read_from_apub_id(conn: &PgConnection, object_id: &str) -> Result<Self, Error> {
- use crate::schema::post::dsl::*;
- post.filter(ap_id.eq(object_id)).first::<Self>(conn)
- }
-
- fn upsert(conn: &PgConnection, post_form: &PostForm) -> Result<Post, Error> {
- use crate::schema::post::dsl::*;
- insert_into(post)
- .values(post_form)
- .on_conflict(ap_id)
- .do_update()
- .set(post_form)
- .get_result::<Self>(conn)
- }
+ pub trait Post_ {
+ //fn read(conn: &PgConnection, post_id: i32) -> Result<Post, Error>;
+ fn list_for_community(conn: &PgConnection, the_community_id: i32) -> Result<Vec<Post>, Error>;
+ fn update_ap_id(conn: &PgConnection, post_id: i32, apub_id: String) -> Result<Post, Error>;
+ fn permadelete_for_creator(conn: &PgConnection, for_creator_id: i32) -> Result<Vec<Post>, Error>;
+ fn update_deleted(conn: &PgConnection, post_id: i32, new_deleted: bool) -> Result<Post, Error>;
+ fn update_removed(conn: &PgConnection, post_id: i32, new_removed: bool) -> Result<Post, Error>;
+ fn update_removed_for_creator(
+ conn: &PgConnection,
+ for_creator_id: i32,
+ for_community_id: Option<i32>,
+ new_removed: bool,
+ ) -> Result<Vec<Post>, Error>;
+ fn update_locked(conn: &PgConnection, post_id: i32, new_locked: bool) -> Result<Post, Error>;
+ fn update_stickied(conn: &PgConnection, post_id: i32, new_stickied: bool) -> Result<Post, Error>;
+ fn is_post_creator(user_id: i32, post_creator_id: i32) -> bool;
}
- impl Post {
- pub fn list_for_community(
- conn: &PgConnection,
- the_community_id: i32,
- ) -> Result<Vec<Self>, Error> {
- use crate::schema::post::dsl::*;
+ impl Post_ for Post {
- // TODO: this is a duplicate?
- //fn read(conn: &PgConnection, post_id: i32) -> Result<Self, Error> {
- // use lemmy_db_schema::schema::post::dsl::*;
- // post.filter(id.eq(post_id)).first::<Self>(conn)
- //}
-
+ fn list_for_community(conn: &PgConnection, the_community_id: i32) -> Result<Vec<Self>, Error> {
+ use lemmy_db_schema::schema::post::dsl::*;
post
.filter(community_id.eq(the_community_id))
.then_order_by(published.desc())
.load::<Self>(conn)
}
- pub fn update_ap_id(conn: &PgConnection, post_id: i32, apub_id: String) -> Result<Self, Error> {
- use crate::schema::post::dsl::*;
+ fn update_ap_id(conn: &PgConnection, post_id: i32, apub_id: String) -> Result<Self, Error> {
+ use lemmy_db_schema::schema::post::dsl::*;
diesel::update(post.find(post_id))
.set(ap_id.eq(apub_id))
.get_result::<Self>(conn)
}
- pub fn permadelete_for_creator(
- conn: &PgConnection,
- for_creator_id: i32,
- ) -> Result<Vec<Self>, Error> {
- use crate::schema::post::dsl::*;
+ fn permadelete_for_creator(conn: &PgConnection, for_creator_id: i32) -> Result<Vec<Self>, Error> {
+ use lemmy_db_schema::schema::post::dsl::*;
let perma_deleted = "*Permananently Deleted*";
let perma_deleted_url = "https://deleted.com";
.get_results::<Self>(conn)
}
- pub fn update_deleted(
- conn: &PgConnection,
- post_id: i32,
- new_deleted: bool,
- ) -> Result<Self, Error> {
- use crate::schema::post::dsl::*;
+ fn update_deleted(conn: &PgConnection, post_id: i32, new_deleted: bool) -> Result<Self, Error> {
+ use lemmy_db_schema::schema::post::dsl::*;
diesel::update(post.find(post_id))
.set((deleted.eq(new_deleted), updated.eq(naive_now())))
.get_result::<Self>(conn)
}
- pub fn update_removed(
- conn: &PgConnection,
- post_id: i32,
- new_removed: bool,
- ) -> Result<Self, Error> {
- use crate::schema::post::dsl::*;
+ fn update_removed(conn: &PgConnection, post_id: i32, new_removed: bool) -> Result<Self, Error> {
+ use lemmy_db_schema::schema::post::dsl::*;
diesel::update(post.find(post_id))
.set((removed.eq(new_removed), updated.eq(naive_now())))
.get_result::<Self>(conn)
}
- pub fn update_removed_for_creator(
+ fn update_removed_for_creator(
conn: &PgConnection,
for_creator_id: i32,
for_community_id: Option<i32>,
new_removed: bool,
) -> Result<Vec<Self>, Error> {
- use crate::schema::post::dsl::*;
+ use lemmy_db_schema::schema::post::dsl::*;
let mut update = diesel::update(post).into_boxed();
update = update.filter(creator_id.eq(for_creator_id));
.get_results::<Self>(conn)
}
- pub fn update_locked(conn: &PgConnection, post_id: i32, new_locked: bool) -> Result<Self, Error> {
- use crate::schema::post::dsl::*;
+ fn update_locked(conn: &PgConnection, post_id: i32, new_locked: bool) -> Result<Self, Error> {
+ use lemmy_db_schema::schema::post::dsl::*;
diesel::update(post.find(post_id))
.set(locked.eq(new_locked))
.get_result::<Self>(conn)
}
- pub fn update_stickied(
- conn: &PgConnection,
- post_id: i32,
- new_stickied: bool,
- ) -> Result<Self, Error> {
- use crate::schema::post::dsl::*;
+ fn update_stickied(conn: &PgConnection, post_id: i32, new_stickied: bool) -> Result<Self, Error> {
+ use lemmy_db_schema::schema::post::dsl::*;
diesel::update(post.find(post_id))
.set(stickied.eq(new_stickied))
.get_result::<Self>(conn)
}
- pub fn is_post_creator(user_id: i32, post_creator_id: i32) -> bool {
+ fn is_post_creator(user_id: i32, post_creator_id: i32) -> bool {
user_id == post_creator_id
}
}
- #[derive(Identifiable, Queryable, Associations, PartialEq, Debug)]
- #[belongs_to(Post)]
- #[table_name = "post_like"]
- pub struct PostLike {
- pub id: i32,
- pub post_id: i32,
- pub user_id: i32,
- pub score: i16,
- pub published: chrono::NaiveDateTime,
- }
+ impl ApubObject<PostForm> for Post {
+ fn read_from_apub_id(conn: &PgConnection, object_id: &str) -> Result<Self, Error> {
+ use lemmy_db_schema::schema::post::dsl::*;
+ post.filter(ap_id.eq(object_id)).first::<Self>(conn)
+ }
- #[derive(Insertable, AsChangeset, Clone)]
- #[table_name = "post_like"]
- pub struct PostLikeForm {
- pub post_id: i32,
- pub user_id: i32,
- pub score: i16,
+ fn upsert(conn: &PgConnection, post_form: &PostForm) -> Result<Post, Error> {
+ use lemmy_db_schema::schema::post::dsl::*;
+ insert_into(post)
+ .values(post_form)
+ .on_conflict(ap_id)
+ .do_update()
+ .set(post_form)
+ .get_result::<Self>(conn)
+ }
}
impl Likeable<PostLikeForm> for PostLike {
fn like(conn: &PgConnection, post_like_form: &PostLikeForm) -> Result<Self, Error> {
- use crate::schema::post_like::dsl::*;
+ use lemmy_db_schema::schema::post_like::dsl::*;
insert_into(post_like)
.values(post_like_form)
.on_conflict((post_id, user_id))
.get_result::<Self>(conn)
}
fn remove(conn: &PgConnection, user_id: i32, post_id: i32) -> Result<usize, Error> {
- use crate::schema::post_like::dsl;
+ use lemmy_db_schema::schema::post_like::dsl;
diesel::delete(
dsl::post_like
.filter(dsl::post_id.eq(post_id))
}
}
- #[derive(Identifiable, Queryable, Associations, PartialEq, Debug)]
- #[belongs_to(Post)]
- #[table_name = "post_saved"]
- pub struct PostSaved {
- pub id: i32,
- pub post_id: i32,
- pub user_id: i32,
- pub published: chrono::NaiveDateTime,
- }
-
- #[derive(Insertable, AsChangeset)]
- #[table_name = "post_saved"]
- pub struct PostSavedForm {
- pub post_id: i32,
- pub user_id: i32,
- }
-
impl Saveable<PostSavedForm> for PostSaved {
fn save(conn: &PgConnection, post_saved_form: &PostSavedForm) -> Result<Self, Error> {
- use crate::schema::post_saved::dsl::*;
+ use lemmy_db_schema::schema::post_saved::dsl::*;
insert_into(post_saved)
.values(post_saved_form)
.on_conflict((post_id, user_id))
.get_result::<Self>(conn)
}
fn unsave(conn: &PgConnection, post_saved_form: &PostSavedForm) -> Result<usize, Error> {
- use crate::schema::post_saved::dsl::*;
+ use lemmy_db_schema::schema::post_saved::dsl::*;
diesel::delete(
post_saved
.filter(post_id.eq(post_saved_form.post_id))
}
}
- #[derive(Identifiable, Queryable, Associations, PartialEq, Debug)]
- #[belongs_to(Post)]
- #[table_name = "post_read"]
- pub struct PostRead {
- pub id: i32,
-
- pub post_id: i32,
-
- pub user_id: i32,
-
- pub published: chrono::NaiveDateTime,
- }
-
- #[derive(Insertable, AsChangeset)]
- #[table_name = "post_read"]
- pub struct PostReadForm {
- pub post_id: i32,
-
- pub user_id: i32,
- }
-
impl Readable<PostReadForm> for PostRead {
fn mark_as_read(conn: &PgConnection, post_read_form: &PostReadForm) -> Result<Self, Error> {
- use crate::schema::post_read::dsl::*;
+ use lemmy_db_schema::schema::post_read::dsl::*;
insert_into(post_read)
.values(post_read_form)
.get_result::<Self>(conn)
}
fn mark_as_unread(conn: &PgConnection, post_read_form: &PostReadForm) -> Result<usize, Error> {
- use crate::schema::post_read::dsl::*;
+ use lemmy_db_schema::schema::post_read::dsl::*;
diesel::delete(
post_read
.filter(post_id.eq(post_read_form.post_id))
#[cfg(test)]
mod tests {
- use crate::{
- source::{community::*, post::*, user::*},
- tests::establish_unpooled_connection,
- ListingType,
- SortType,
+ use crate::{source::post::*, tests::establish_unpooled_connection, ListingType, SortType};
+ use lemmy_db_schema::source::{
+ community::{Community, CommunityForm},
+ user::*,
};
#[test]
- use crate::{naive_now, schema::site, Crud};
+ use crate::Crud;
use diesel::{dsl::*, result::Error, *};
- use serde::Serialize;
-
- #[derive(Queryable, Identifiable, PartialEq, Debug, Clone, Serialize)]
- #[table_name = "site"]
- pub struct Site {
- pub id: i32,
- pub name: String,
- pub description: Option<String>,
- pub creator_id: i32,
- pub published: chrono::NaiveDateTime,
- pub updated: Option<chrono::NaiveDateTime>,
- pub enable_downvotes: bool,
- pub open_registration: bool,
- pub enable_nsfw: bool,
- pub icon: Option<String>,
- pub banner: Option<String>,
- }
-
- #[derive(Insertable, AsChangeset)]
- #[table_name = "site"]
- pub struct SiteForm {
- pub name: String,
- pub description: Option<String>,
- pub creator_id: i32,
- pub updated: Option<chrono::NaiveDateTime>,
- pub enable_downvotes: bool,
- pub open_registration: bool,
- pub enable_nsfw: bool,
- // 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<Option<String>>,
- pub banner: Option<Option<String>>,
- }
+ use lemmy_db_schema::{naive_now, source::site::*};
impl Crud<SiteForm> for Site {
fn read(conn: &PgConnection, _site_id: i32) -> Result<Self, Error> {
- use crate::schema::site::dsl::*;
+ use lemmy_db_schema::schema::site::dsl::*;
site.first::<Self>(conn)
}
fn create(conn: &PgConnection, new_site: &SiteForm) -> Result<Self, Error> {
- use crate::schema::site::dsl::*;
+ use lemmy_db_schema::schema::site::dsl::*;
insert_into(site).values(new_site).get_result::<Self>(conn)
}
fn update(conn: &PgConnection, site_id: i32, new_site: &SiteForm) -> Result<Self, Error> {
- use crate::schema::site::dsl::*;
+ use lemmy_db_schema::schema::site::dsl::*;
diesel::update(site.find(site_id))
.set(new_site)
.get_result::<Self>(conn)
}
- use crate::schema::site::dsl::*;
+ fn delete(conn: &PgConnection, site_id: i32) -> Result<usize, Error> {
++ use lemmy_db_schema::schema::site::dsl::*;
+ diesel::delete(site.find(site_id)).execute(conn)
+ }
}
- impl Site {
- pub fn transfer(conn: &PgConnection, new_creator_id: i32) -> Result<Self, Error> {
- use crate::schema::site::dsl::*;
+ pub trait Site_ {
+ fn transfer(conn: &PgConnection, new_creator_id: i32) -> Result<Site, Error>;
++ fn read_simple(conn: &PgConnection) -> Result<Site, Error>;
+ }
+
+ impl Site_ for Site {
+ fn transfer(conn: &PgConnection, new_creator_id: i32) -> Result<Site, Error> {
+ use lemmy_db_schema::schema::site::dsl::*;
diesel::update(site.find(1))
.set((creator_id.eq(new_creator_id), updated.eq(naive_now())))
.get_result::<Self>(conn)
}
- pub fn read_simple(conn: &PgConnection) -> Result<Self, Error> {
- use crate::schema::site::dsl::*;
+
++ fn read_simple(conn: &PgConnection) -> Result<Self, Error> {
++ use lemmy_db_schema::schema::site::dsl::*;
+ site.first::<Self>(conn)
+ }
}
functions::hot_rank,
fuzzy_search,
limit_and_offset,
+ views::ViewToVec,
+ ListingType,
+ MaybeOptional,
+ SortType,
+ ToSafe,
+ };
+ use diesel::{result::Error, *};
+ use lemmy_db_schema::{
schema::{
comment,
comment_aggregates,
post::Post,
user::{UserAlias1, UserSafe, UserSafeAlias1, User_},
},
- views::ViewToVec,
- ListingType,
- MaybeOptional,
- SortType,
- ToSafe,
};
- use diesel::{result::Error, *};
use serde::Serialize;
#[derive(Debug, PartialEq, Serialize, Clone)]
my_vote,
})
}
+
+ /// Gets the recipient user id.
+ /// If there is no parent comment, its the post creator
+ pub fn get_recipient_id(&self) -> i32 {
+ match &self.recipient {
+ Some(parent_commenter) => parent_commenter.id,
+ None => self.post.creator_id,
+ }
+ }
}
pub struct CommentQueryBuilder<'a> {
#[cfg(test)]
mod tests {
- use crate::{
- source::{comment::*, community::*, post::*, user::*},
- tests::establish_unpooled_connection,
- views::comment_view::*,
- Crud,
- Likeable,
- *,
- };
+ use crate::{tests::establish_unpooled_connection, views::comment_view::*, Crud, Likeable, *};
+ use lemmy_db_schema::source::{comment::*, community::*, post::*, user::*};
#[test]
fn test_crud() {
let _inserted_comment_like = CommentLike::like(&conn, &comment_like_form).unwrap();
+ let agg = CommentAggregates::read(&conn, inserted_comment.id).unwrap();
+
let expected_comment_view_no_user = CommentView {
creator_banned_from_community: false,
my_vote: None,
published: inserted_community.published,
},
counts: CommentAggregates {
- id: inserted_comment.id, // TODO
+ id: agg.id,
comment_id: inserted_comment.id,
score: 1,
upvotes: 1,
functions::hot_rank,
fuzzy_search,
limit_and_offset,
+ views::ViewToVec,
+ ListingType,
+ MaybeOptional,
+ SortType,
+ ToSafe,
+ };
+ use diesel::{result::Error, *};
+ use lemmy_db_schema::{
schema::{
community,
community_follower,
post::{Post, PostRead, PostSaved},
user::{UserSafe, User_},
},
- views::ViewToVec,
- ListingType,
- MaybeOptional,
- SortType,
- ToSafe,
};
- use diesel::{result::Error, *};
use serde::Serialize;
#[derive(Debug, PartialEq, Serialize, Clone)]
}
pub fn my_user_id<T: MaybeOptional<i32>>(mut self, my_user_id: T) -> Self {
- self.community_id = my_user_id.get_optional();
+ self.my_user_id = my_user_id.get_optional();
self
}
mod tests {
use crate::{
aggregates::post_aggregates::PostAggregates,
- source::{community::*, post::*, user::*},
tests::establish_unpooled_connection,
views::post_view::{PostQueryBuilder, PostView},
Crud,
Likeable,
*,
};
+ use lemmy_db_schema::source::{community::*, post::*, user::*};
#[test]
fn test_crud() {
let read_post_listing_with_user =
PostView::read(&conn, inserted_post.id, Some(inserted_user.id)).unwrap();
+ let agg = PostAggregates::read(&conn, inserted_post.id).unwrap();
+
// the non user version
let expected_post_listing_no_user = PostView {
post: Post {
published: inserted_community.published,
},
counts: PostAggregates {
- id: inserted_post.id, // TODO this might fail
+ id: agg.id,
post_id: inserted_post.id,
comments: 0,
score: 1,
- use crate::{
- aggregates::site_aggregates::SiteAggregates,
-use crate::ToSafe;
++use crate::{aggregates::site_aggregates::SiteAggregates, ToSafe};
+ use diesel::{result::Error, *};
+ use lemmy_db_schema::{
- schema::{site, user_},
+ schema::{site, site_aggregates, user_},
source::{
site::Site,
user::{UserSafe, User_},
},
- ToSafe,
};
- use diesel::{result::Error, *};
use serde::Serialize;
#[derive(Debug, Serialize, Clone)]
pub struct SiteView {
pub site: Site,
pub creator: UserSafe,
+ pub counts: SiteAggregates,
}
impl SiteView {
pub fn read(conn: &PgConnection) -> Result<Self, Error> {
- let (site, creator) = site::table
+ let (site, creator, counts) = site::table
.inner_join(user_::table)
- .select((site::all_columns, User_::safe_columns_tuple()))
- .first::<(Site, UserSafe)>(conn)?;
+ .inner_join(site_aggregates::table)
+ .select((
+ site::all_columns,
+ User_::safe_columns_tuple(),
+ site_aggregates::all_columns,
+ ))
+ .first::<(Site, UserSafe, SiteAggregates)>(conn)?;
- Ok(SiteView { site, creator })
+ Ok(SiteView {
+ site,
+ creator,
+ counts,
+ })
}
}
table! {
site_aggregates (id) {
id -> Int4,
+ site_id -> Int4,
users -> Int8,
posts -> Int8,
comments -> Int8,
joinable!(post_saved -> post (post_id));
joinable!(post_saved -> user_ (user_id));
joinable!(site -> user_ (creator_id));
+joinable!(site_aggregates -> site (site_id));
joinable!(user_aggregates -> user_ (user_id));
joinable!(user_ban -> user_ (user_id));
joinable!(user_mention -> comment (comment_id));
--- /dev/null
-#[derive(Identifiable, Queryable, Associations, PartialEq, Serialize, Deserialize, Debug, Clone)]
+ use crate::{schema::comment_report, source::comment::Comment};
+ use serde::{Deserialize, Serialize};
+
++#[derive(
++ Identifiable, Queryable, Associations, PartialEq, Serialize, Deserialize, Debug, Clone,
++)]
+ #[belongs_to(Comment)]
+ #[table_name = "comment_report"]
+ pub struct CommentReport {
+ pub id: i32,
+ pub creator_id: i32,
+ pub comment_id: i32,
+ pub original_comment_text: String,
+ pub reason: String,
+ pub resolved: bool,
+ pub resolver_id: Option<i32>,
+ pub published: chrono::NaiveDateTime,
+ pub updated: Option<chrono::NaiveDateTime>,
+ }
+
+ #[derive(Insertable, AsChangeset, Clone)]
+ #[table_name = "comment_report"]
+ pub struct CommentReportForm {
+ pub creator_id: i32,
+ pub comment_id: i32,
+ pub original_comment_text: String,
+ pub reason: String,
+ }
--- /dev/null
-#[derive(Identifiable, Queryable, Associations, PartialEq, Serialize, Deserialize, Debug, Clone)]
+ use crate::{schema::post_report, source::post::Post};
+ use serde::{Deserialize, Serialize};
+
++#[derive(
++ Identifiable, Queryable, Associations, PartialEq, Serialize, Deserialize, Debug, Clone,
++)]
+ #[belongs_to(Post)]
+ #[table_name = "post_report"]
+ pub struct PostReport {
+ pub id: i32,
+ pub creator_id: i32,
+ pub post_id: i32,
+ pub original_post_name: String,
+ pub original_post_url: Option<String>,
+ pub original_post_body: Option<String>,
+ pub reason: String,
+ pub resolved: bool,
+ pub resolver_id: Option<i32>,
+ pub published: chrono::NaiveDateTime,
+ pub updated: Option<chrono::NaiveDateTime>,
+ }
+
+ #[derive(Insertable, AsChangeset, Clone)]
+ #[table_name = "post_report"]
+ pub struct PostReportForm {
+ pub creator_id: i32,
+ pub post_id: i32,
+ pub original_post_name: String,
+ pub original_post_url: Option<String>,
+ pub original_post_body: Option<String>,
+ pub reason: String,
+ }
pub mod post;
pub mod site;
pub mod user;
-pub mod websocket;
use diesel::PgConnection;
- use lemmy_db::{
- source::{
- comment::Comment,
- post::Post,
- user::User_,
- user_mention::{UserMention, UserMentionForm},
- },
- Crud,
- DbPool,
+ use lemmy_db::{source::user::User, Crud, DbPool};
+ use lemmy_db_schema::source::{
+ comment::Comment,
+ post::Post,
+ user::User_,
+ user_mention::{UserMention, UserMentionForm},
};
use lemmy_utils::{email::send_email, settings::Settings, utils::MentionData, LemmyError};
use log::error;
--use lemmy_db::{
- source::{category::*, user::*},
- aggregates::site_aggregates::SiteAggregates,
-- views::{
-- comment_view::CommentView,
-- community::community_view::CommunityView,
-- moderator::{
-- mod_add_community_view::ModAddCommunityView,
-- mod_add_view::ModAddView,
-- mod_ban_from_community_view::ModBanFromCommunityView,
-- mod_ban_view::ModBanView,
-- 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,
-- },
-- post_view::PostView,
-- site_view::SiteView,
-- user_view::UserViewSafe,
++use lemmy_db::views::{
++ comment_view::CommentView,
++ community::community_view::CommunityView,
++ moderator::{
++ mod_add_community_view::ModAddCommunityView,
++ mod_add_view::ModAddView,
++ mod_ban_from_community_view::ModBanFromCommunityView,
++ mod_ban_view::ModBanView,
++ 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,
},
++ post_view::PostView,
++ site_view::SiteView,
++ user_view::UserViewSafe,
};
+ use lemmy_db_schema::source::{category::*, user::User_};
use serde::{Deserialize, Serialize};
#[derive(Deserialize)]
pub auth: Option<String>,
}
-// TODO combine siteresponse and getsiteresponse
#[derive(Serialize, Clone)]
pub struct SiteResponse {
- pub site: SiteView,
+ pub site_view: SiteView,
}
#[derive(Serialize)]
pub struct GetSiteResponse {
- pub site: Option<SiteView>, // Because the site might not be set up yet
- pub counts: SiteAggregates,
+ pub site_view: Option<SiteView>, // Because the site might not be set up yet
pub admins: Vec<UserViewSafe>,
pub banned: Vec<UserViewSafe>,
pub online: usize,
*,
};
use lemmy_db::{
+ source::{comment::Comment_, post::Post_, private_message::PrivateMessage_},
+ Crud,
+ };
+ use lemmy_db_schema::{
naive_now,
source::{
comment::Comment,
private_message::PrivateMessage,
user::{UserForm, User_},
},
- Crud,
};
use lemmy_utils::{
apub::{generate_actor_keypair, make_apub_endpoint, EndpointType},
}
fn user_updates_2020_04_02(conn: &PgConnection) -> Result<(), LemmyError> {
- use lemmy_db::schema::user_::dsl::*;
+ use lemmy_db_schema::schema::user_::dsl::*;
info!("Running user_updates_2020_04_02");
.filter(local.eq(true))
.load::<User_>(conn)?;
- sql_query("alter table user_ disable trigger refresh_user").execute(conn)?;
-
for cuser in &incorrect_users {
let keypair = generate_actor_keypair()?;
User_::update(&conn, cuser.id, &form)?;
}
- sql_query("alter table user_ enable trigger refresh_user").execute(conn)?;
-
info!("{} user rows updated.", incorrect_users.len());
Ok(())
}
fn community_updates_2020_04_02(conn: &PgConnection) -> Result<(), LemmyError> {
- use lemmy_db::schema::community::dsl::*;
+ use lemmy_db_schema::schema::community::dsl::*;
info!("Running community_updates_2020_04_02");
.filter(local.eq(true))
.load::<Community>(conn)?;
- sql_query("alter table community disable trigger refresh_community").execute(conn)?;
-
for ccommunity in &incorrect_communities {
let keypair = generate_actor_keypair()?;
Community::update(&conn, ccommunity.id, &form)?;
}
- sql_query("alter table community enable trigger refresh_community").execute(conn)?;
-
info!("{} community rows updated.", incorrect_communities.len());
Ok(())
}
fn post_updates_2020_04_03(conn: &PgConnection) -> Result<(), LemmyError> {
- use lemmy_db::schema::post::dsl::*;
+ use lemmy_db_schema::schema::post::dsl::*;
info!("Running post_updates_2020_04_03");
.filter(local.eq(true))
.load::<Post>(conn)?;
- sql_query("alter table post disable trigger refresh_post").execute(conn)?;
-
for cpost in &incorrect_posts {
let apub_id = make_apub_endpoint(EndpointType::Post, &cpost.id.to_string()).to_string();
Post::update_ap_id(&conn, cpost.id, apub_id)?;
info!("{} post rows updated.", incorrect_posts.len());
- sql_query("alter table post enable trigger refresh_post").execute(conn)?;
-
Ok(())
}
fn comment_updates_2020_04_03(conn: &PgConnection) -> Result<(), LemmyError> {
- use lemmy_db::schema::comment::dsl::*;
+ use lemmy_db_schema::schema::comment::dsl::*;
info!("Running comment_updates_2020_04_03");
.filter(local.eq(true))
.load::<Comment>(conn)?;
- sql_query("alter table comment disable trigger refresh_comment").execute(conn)?;
-
for ccomment in &incorrect_comments {
let apub_id = make_apub_endpoint(EndpointType::Comment, &ccomment.id.to_string()).to_string();
Comment::update_ap_id(&conn, ccomment.id, apub_id)?;
}
- sql_query("alter table comment enable trigger refresh_comment").execute(conn)?;
-
info!("{} comment rows updated.", incorrect_comments.len());
Ok(())
}
fn private_message_updates_2020_05_05(conn: &PgConnection) -> Result<(), LemmyError> {
- use lemmy_db::schema::private_message::dsl::*;
+ use lemmy_db_schema::schema::private_message::dsl::*;
info!("Running private_message_updates_2020_05_05");
}
fn post_thumbnail_url_updates_2020_07_27(conn: &PgConnection) -> Result<(), LemmyError> {
- use lemmy_db::schema::post::dsl::*;
+ use lemmy_db_schema::schema::post::dsl::*;
info!("Running post_thumbnail_url_updates_2020_07_27");
user_inbox::user_inbox,
},
};
- use lemmy_db::{
- source::{
- community::{Community, CommunityForm},
- user::{User_, *},
- },
- Crud,
- ListingType,
- SortType,
+ use lemmy_db::{Crud, ListingType, SortType};
+ use lemmy_db_schema::source::{
+ community::{Community, CommunityForm},
+ user::{UserForm, User_},
};
use lemmy_rate_limit::{rate_limiter::RateLimiter, RateLimit};
use lemmy_utils::{apub::generate_actor_keypair, settings::Settings};
let activity_queue = create_activity_queue();
let chat_server = ChatServer::startup(
pool.clone(),
- rate_limiter.clone(),
+ rate_limiter,
|c, i, o, d| Box::pin(match_websocket_operation(c, i, o, d)),
Client::default(),
- activity_queue.clone(),
+ activity_queue,
)
.start();
LemmyContext::create(
lang: "browser".into(),
show_avatars: true,
send_notifications_to_email: false,
- actor_id: Some(format!("http://localhost:8536/u/{}", name).to_string()),
+ actor_id: Some(format!("http://localhost:8536/u/{}", name)),
bio: None,
local: true,
private_key: Some(user_keypair.private_key),
}
#[actix_rt::test]
+#[ignore]
async fn test_shared_inbox_expired_signature() {
let request = create_http_request();
let context = create_context();
}
#[actix_rt::test]
+#[ignore]
async fn test_user_inbox_expired_signature() {
let request = create_http_request();
let context = create_context();
}
#[actix_rt::test]
+#[ignore]
async fn test_community_inbox_expired_signature() {
let context = create_context();
let connection = &context.pool().get().unwrap();