Skip to content

Commit

Permalink
Adding combined person content and person saved tables. (#5251)
Browse files Browse the repository at this point in the history
* Combined tables try 2

* Finishing up combined report table.

* Fix ts optionals.

* Adding tests, triggers, and history updates for report_combined.

* Adding profile.

* Add cursor pagination to report_combined view (#5244)

* add pagination cursor

* store timestamp instead of id in cursor (partial)

* Revert "store timestamp instead of id in cursor (partial)"

This reverts commit 89359dd.

* use paginated query builder

* Fixing migration and paged API.

* Using dullbananas trigger procedure

* Removing pointless list routes, reorganizing tests.

* Fixing column XOR check.

* Forgot to remove list report actions.

* Cleanup.

* Use internal tagging.

* Fixing api tests.

* Adding a few indexes.

* Fixing migration name.

* Fixing unique constraints.

* Addressing PR comments.

* Start working on profile combined

* Adding views and replaceable schema.

* A few changes to profile view.

- Separating the profile fetch from its combined content fetch.
- Starting to separate saved_only into its own combined view.

* Finishing up combined person_saved and person_content.

* Fixing api tests.

* Moving to api-v4 routes.

* Fixing imports.

* Update crates/db_views/src/report_combined_view.rs

Co-authored-by: dullbananas <dull.bananas0@gmail.com>

* Update crates/db_views/src/report_combined_view.rs

Co-authored-by: dullbananas <dull.bananas0@gmail.com>

* Update crates/db_views/src/report_combined_view.rs

Co-authored-by: dullbananas <dull.bananas0@gmail.com>

* Update migrations/2024-12-02-181601_add_report_combined_table/up.sql

Co-authored-by: dullbananas <dull.bananas0@gmail.com>

* Update migrations/2024-12-02-181601_add_report_combined_table/up.sql

Co-authored-by: dullbananas <dull.bananas0@gmail.com>

* Fixing import and fmt.

* Fixing null types in postgres.

* Comment out err.

* Fixing TS issues.

* Using dullbananas trigger procedure

* Addressing PR comments.

* Removing serialization

* Removing serialization

* Fixing duped trigger.

* Remove saved_only test.

* Remove pointless post_tags types.

* Remove pointless index.

* Changing published to saved for person_saved_combined.

---------

Co-authored-by: dullbananas <dull.bananas0@gmail.com>
  • Loading branch information
dessalines and dullbananas authored Jan 5, 2025
1 parent 4142199 commit 0bfbd74
Show file tree
Hide file tree
Showing 34 changed files with 1,493 additions and 310 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 1 addition & 4 deletions crates/api/src/comment/save.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,7 @@ pub async fn save_comment(
context: Data<LemmyContext>,
local_user_view: LocalUserView,
) -> LemmyResult<Json<CommentResponse>> {
let comment_saved_form = CommentSavedForm {
comment_id: data.comment_id,
person_id: local_user_view.person.id,
};
let comment_saved_form = CommentSavedForm::new(data.comment_id, local_user_view.person.id);

if data.save {
CommentSaved::save(&mut context.pool(), &comment_saved_form)
Expand Down
42 changes: 42 additions & 0 deletions crates/api/src/local_user/list_saved.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
use activitypub_federation::config::Data;
use actix_web::web::{Json, Query};
use lemmy_api_common::{
context::LemmyContext,
person::{ListPersonSaved, ListPersonSavedResponse},
utils::check_private_instance,
};
use lemmy_db_views::{
person_saved_combined_view::PersonSavedCombinedQuery,
structs::{LocalUserView, SiteView},
};
use lemmy_utils::error::LemmyResult;

#[tracing::instrument(skip(context))]
pub async fn list_person_saved(
data: Query<ListPersonSaved>,
context: Data<LemmyContext>,
local_user_view: LocalUserView,
) -> LemmyResult<Json<ListPersonSavedResponse>> {
let local_site = SiteView::read_local(&mut context.pool()).await?;

check_private_instance(&Some(local_user_view.clone()), &local_site.local_site)?;

// parse pagination token
let page_after = if let Some(pa) = &data.page_cursor {
Some(pa.read(&mut context.pool()).await?)
} else {
None
};
let page_back = data.page_back;
let type_ = data.type_;

let saved = PersonSavedCombinedQuery {
type_,
page_after,
page_back,
}
.list(&mut context.pool(), &local_user_view)
.await?;

Ok(Json(ListPersonSavedResponse { saved }))
}
1 change: 1 addition & 0 deletions crates/api/src/local_user/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ pub mod get_captcha;
pub mod list_banned;
pub mod list_logins;
pub mod list_media;
pub mod list_saved;
pub mod login;
pub mod logout;
pub mod notifications;
Expand Down
2 changes: 0 additions & 2 deletions crates/api_common/src/comment.rs
Original file line number Diff line number Diff line change
Expand Up @@ -131,8 +131,6 @@ pub struct GetComments {
#[cfg_attr(feature = "full", ts(optional))]
pub parent_id: Option<CommentId>,
#[cfg_attr(feature = "full", ts(optional))]
pub saved_only: Option<bool>,
#[cfg_attr(feature = "full", ts(optional))]
pub liked_only: Option<bool>,
#[cfg_attr(feature = "full", ts(optional))]
pub disliked_only: Option<bool>,
Expand Down
73 changes: 60 additions & 13 deletions crates/api_common/src/person.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,16 @@ use lemmy_db_schema::{
source::{login_token::LoginToken, site::Site},
CommentSortType,
ListingType,
PersonContentType,
PostListingMode,
PostSortType,
};
use lemmy_db_views::structs::{CommentView, LocalImageView, PostView};
use lemmy_db_views::structs::{
LocalImageView,
PersonContentCombinedPaginationCursor,
PersonContentCombinedView,
PersonSavedCombinedPaginationCursor,
};
use lemmy_db_views_actor::structs::{
CommentReplyView,
CommunityModeratorView,
Expand Down Expand Up @@ -222,16 +228,6 @@ pub struct GetPersonDetails {
/// Example: dessalines , or dessalines@xyz.tld
#[cfg_attr(feature = "full", ts(optional))]
pub username: Option<String>,
#[cfg_attr(feature = "full", ts(optional))]
pub sort: Option<PostSortType>,
#[cfg_attr(feature = "full", ts(optional))]
pub page: Option<i64>,
#[cfg_attr(feature = "full", ts(optional))]
pub limit: Option<i64>,
#[cfg_attr(feature = "full", ts(optional))]
pub community_id: Option<CommunityId>,
#[cfg_attr(feature = "full", ts(optional))]
pub saved_only: Option<bool>,
}

#[skip_serializing_none]
Expand All @@ -243,11 +239,62 @@ pub struct GetPersonDetailsResponse {
pub person_view: PersonView,
#[cfg_attr(feature = "full", ts(optional))]
pub site: Option<Site>,
pub comments: Vec<CommentView>,
pub posts: Vec<PostView>,
pub moderates: Vec<CommunityModeratorView>,
}

#[skip_serializing_none]
#[derive(Debug, Serialize, Deserialize, Clone, Default, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "full", derive(TS))]
#[cfg_attr(feature = "full", ts(export))]
/// Gets a person's content (posts and comments)
///
/// Either person_id, or username are required.
pub struct ListPersonContent {
#[cfg_attr(feature = "full", ts(optional))]
pub type_: Option<PersonContentType>,
#[cfg_attr(feature = "full", ts(optional))]
pub person_id: Option<PersonId>,
/// Example: dessalines , or dessalines@xyz.tld
#[cfg_attr(feature = "full", ts(optional))]
pub username: Option<String>,
#[cfg_attr(feature = "full", ts(optional))]
pub page_cursor: Option<PersonContentCombinedPaginationCursor>,
#[cfg_attr(feature = "full", ts(optional))]
pub page_back: Option<bool>,
}

#[skip_serializing_none]
#[derive(Debug, Serialize, Deserialize, Clone)]
#[cfg_attr(feature = "full", derive(TS))]
#[cfg_attr(feature = "full", ts(export))]
/// A person's content response.
pub struct ListPersonContentResponse {
pub content: Vec<PersonContentCombinedView>,
}

#[skip_serializing_none]
#[derive(Debug, Serialize, Deserialize, Clone, Default, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "full", derive(TS))]
#[cfg_attr(feature = "full", ts(export))]
/// Gets your saved posts and comments
pub struct ListPersonSaved {
#[cfg_attr(feature = "full", ts(optional))]
pub type_: Option<PersonContentType>,
#[cfg_attr(feature = "full", ts(optional))]
pub page_cursor: Option<PersonSavedCombinedPaginationCursor>,
#[cfg_attr(feature = "full", ts(optional))]
pub page_back: Option<bool>,
}

#[skip_serializing_none]
#[derive(Debug, Serialize, Deserialize, Clone)]
#[cfg_attr(feature = "full", derive(TS))]
#[cfg_attr(feature = "full", ts(export))]
/// A person's saved content response.
pub struct ListPersonSavedResponse {
pub saved: Vec<PersonContentCombinedView>,
}

#[derive(Debug, Serialize, Deserialize, Clone, Copy, Default, PartialEq, Eq)]
#[cfg_attr(feature = "full", derive(TS))]
#[cfg_attr(feature = "full", ts(export))]
Expand Down
2 changes: 0 additions & 2 deletions crates/api_common/src/site.rs
Original file line number Diff line number Diff line change
Expand Up @@ -94,8 +94,6 @@ pub struct Search {
#[cfg_attr(feature = "full", ts(optional))]
pub post_url_only: Option<bool>,
#[cfg_attr(feature = "full", ts(optional))]
pub saved_only: Option<bool>,
#[cfg_attr(feature = "full", ts(optional))]
pub liked_only: Option<bool>,
#[cfg_attr(feature = "full", ts(optional))]
pub disliked_only: Option<bool>,
Expand Down
2 changes: 0 additions & 2 deletions crates/apub/src/api/list_comments.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,6 @@ pub async fn list_comments(
&site_view.local_site,
));
let max_depth = data.max_depth;
let saved_only = data.saved_only;

let liked_only = data.liked_only;
let disliked_only = data.disliked_only;
Expand Down Expand Up @@ -78,7 +77,6 @@ pub async fn list_comments(
listing_type,
sort,
max_depth,
saved_only,
liked_only,
disliked_only,
community_id,
Expand Down
52 changes: 52 additions & 0 deletions crates/apub/src/api/list_person_content.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
use super::resolve_person_id_from_id_or_username;
use activitypub_federation::config::Data;
use actix_web::web::{Json, Query};
use lemmy_api_common::{
context::LemmyContext,
person::{ListPersonContent, ListPersonContentResponse},
utils::check_private_instance,
};
use lemmy_db_views::{
person_content_combined_view::PersonContentCombinedQuery,
structs::{LocalUserView, SiteView},
};
use lemmy_utils::error::LemmyResult;

#[tracing::instrument(skip(context))]
pub async fn list_person_content(
data: Query<ListPersonContent>,
context: Data<LemmyContext>,
local_user_view: Option<LocalUserView>,
) -> LemmyResult<Json<ListPersonContentResponse>> {
let local_site = SiteView::read_local(&mut context.pool()).await?;

check_private_instance(&local_user_view, &local_site.local_site)?;

let person_details_id = resolve_person_id_from_id_or_username(
&data.person_id,
&data.username,
&context,
&local_user_view,
)
.await?;

// parse pagination token
let page_after = if let Some(pa) = &data.page_cursor {
Some(pa.read(&mut context.pool()).await?)
} else {
None
};
let page_back = data.page_back;
let type_ = data.type_;

let content = PersonContentCombinedQuery {
creator_id: person_details_id,
type_,
page_after,
page_back,
}
.list(&mut context.pool(), &local_user_view)
.await?;

Ok(Json(ListPersonContentResponse { content }))
}
2 changes: 0 additions & 2 deletions crates/apub/src/api/list_posts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,6 @@ pub async fn list_posts(
} else {
data.community_id
};
let saved_only = data.saved_only;
let read_only = data.read_only;
let show_hidden = data.show_hidden;
let show_read = data.show_read;
Expand Down Expand Up @@ -78,7 +77,6 @@ pub async fn list_posts(
listing_type,
sort,
community_id,
saved_only,
read_only,
liked_only,
disliked_only,
Expand Down
35 changes: 33 additions & 2 deletions crates/apub/src/api/mod.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,18 @@
use crate::{fetcher::resolve_actor_identifier, objects::person::ApubPerson};
use activitypub_federation::config::Data;
use lemmy_api_common::{context::LemmyContext, LemmyErrorType};
use lemmy_db_schema::{
newtypes::CommunityId,
source::{local_site::LocalSite, local_user::LocalUser},
newtypes::{CommunityId, PersonId},
source::{local_site::LocalSite, local_user::LocalUser, person::Person},
CommentSortType,
ListingType,
PostSortType,
};
use lemmy_db_views::structs::LocalUserView;
use lemmy_utils::error::LemmyResult;

pub mod list_comments;
pub mod list_person_content;
pub mod list_posts;
pub mod read_community;
pub mod read_person;
Expand Down Expand Up @@ -61,3 +67,28 @@ fn comment_sort_type_with_default(
.unwrap_or(local_site.default_comment_sort_type),
)
}

async fn resolve_person_id_from_id_or_username(
person_id: &Option<PersonId>,
username: &Option<String>,
context: &Data<LemmyContext>,
local_user_view: &Option<LocalUserView>,
) -> LemmyResult<PersonId> {
// Check to make sure a person name or an id is given
if username.is_none() && person_id.is_none() {
Err(LemmyErrorType::NoIdGiven)?
}

Ok(match person_id {
Some(id) => *id,
None => {
if let Some(username) = username {
resolve_actor_identifier::<ApubPerson, Person>(username, context, local_user_view, true)
.await?
.id
} else {
Err(LemmyErrorType::NotFound)?
}
}
})
}
Loading

0 comments on commit 0bfbd74

Please sign in to comment.