From 1cffbbcf3558712ea8f087e1129ce0263b994c37 Mon Sep 17 00:00:00 2001 From: kasisnu <5044120+kasisnu@users.noreply.github.com> Date: Tue, 5 Dec 2023 23:09:11 +0530 Subject: [PATCH] something --- .../queries/media_files/list_media_files.rs | 46 +++++---- crates/service/web/storyteller_web/Cargo.toml | 3 + .../media_file_social_meta_lite.rs | 96 +++++++++++++++++++ .../src/http_server/common_responses/mod.rs | 3 +- .../endpoints/media_files/list_media_files.rs | 18 ++-- .../service/web/storyteller_web/src/routes.rs | 5 + 6 files changed, 145 insertions(+), 26 deletions(-) create mode 100644 crates/service/web/storyteller_web/src/http_server/common_responses/media_file_social_meta_lite.rs diff --git a/crates/lib/mysql_queries/src/queries/media_files/list_media_files.rs b/crates/lib/mysql_queries/src/queries/media_files/list_media_files.rs index 0c881234b2..f39aae5f2c 100644 --- a/crates/lib/mysql_queries/src/queries/media_files/list_media_files.rs +++ b/crates/lib/mysql_queries/src/queries/media_files/list_media_files.rs @@ -1,5 +1,6 @@ use chrono::{DateTime, Utc}; -use sqlx::{MySql, MySqlPool, QueryBuilder}; +use log::warn; +use sqlx::{Execute, MySql, MySqlPool, QueryBuilder}; use enums::by_table::media_files::media_file_origin_category::MediaFileOriginCategory; use enums::by_table::media_files::media_file_origin_model_type::MediaFileOriginModelType; @@ -8,6 +9,7 @@ use enums::by_table::media_files::media_file_type::MediaFileType; use enums::common::visibility::Visibility; use errors::AnyhowResult; use tokens::tokens::media_files::MediaFileToken; +use tokens::tokens::users::UserToken; pub struct MediaFileListPage { pub records: Vec, @@ -34,6 +36,10 @@ pub struct MediaFileListItem { pub maybe_public_bucket_prefix: Option, pub maybe_public_bucket_extension: Option, + pub creator_user_token: UserToken, + pub creator_username: String, + pub creator_display_name: String, + pub creator_email_gravatar_hash: String, pub creator_set_visibility: Visibility, pub created_at: DateTime, @@ -42,13 +48,11 @@ pub struct MediaFileListItem { #[derive(Clone, Copy)] pub enum ViewAs { - Author, Moderator, AnotherUser, } pub struct ListMediaFilesArgs<'a> { - pub username: &'a str, pub limit: usize, pub maybe_filter_media_type: Option, pub maybe_offset: Option, @@ -61,7 +65,6 @@ pub async fn list_media_files(args: ListMediaFilesArgs<'_>) -> AnyhowResult) -> AnyhowResult(); let results = query.fetch_all(args.mysql_pool).await?; - let first_id = results.first() .map(|raw_result| raw_result.id); @@ -81,7 +83,7 @@ pub async fn list_media_files(args: ListMediaFilesArgs<'_>) -> AnyhowResult) -> AnyhowResult) -> AnyhowResult( maybe_filter_media_type: Option, - username: &'a str, limit: usize, maybe_offset: Option, cursor_is_reversed: bool, view_as: ViewAs, ) -> QueryBuilder<'a, MySql> { - // NB: Query cannot be statically checked by sqlx - let mut query_builder: QueryBuilder = QueryBuilder::new( + let mut query_string = String::from( r#" + SELECT m.id, - m.token as `token: tokens::tokens::media_files::MediaFileToken`, + m.token as media_file_token, m.origin_category as `origin_category: enums::by_table::media_files::media_file_origin_category::MediaFileOriginCategory`, m.origin_product_category as `origin_product_category: enums::by_table::media_files::media_file_origin_product_category::MediaFileOriginProductCategory`, @@ -133,21 +138,25 @@ SELECT m.maybe_public_bucket_prefix, m.maybe_public_bucket_extension, + users.token as creator_user_token, + users.username as creator_username, + users.display_name as creator_display_name, + users.email_gravatar_hash as creator_email_gravatar_hash, m.creator_set_visibility as `creator_set_visibility: enums::common::visibility::Visibility`, m.created_at, m.updated_at FROM media_files AS m -LEFT OUTER JOIN users AS u - ON m.maybe_creator_user_token = u.token - -WHERE u.username = ? +LEFT OUTER JOIN users + ON m.maybe_creator_user_token = users.token +WHERE m.maybe_creator_user_token IS NOT NULL AND m.user_deleted_at IS NULL AND m.mod_deleted_at IS NULL "# ); - query_builder.push_bind(username); + // NB: Query cannot be statically checked by sqlx + let mut query_builder: QueryBuilder = QueryBuilder::new(query_string); if let Some(media_type) = maybe_filter_media_type { query_builder.push(" AND m.media_file_type = ? "); @@ -155,7 +164,6 @@ AND m.mod_deleted_at IS NULL } match view_as { - ViewAs::Author => {} ViewAs::Moderator => {} ViewAs::AnotherUser => { query_builder.push(" AND m.creator_set_visibility = 'public' "); @@ -184,7 +192,7 @@ AND m.mod_deleted_at IS NULL #[derive(sqlx::FromRow)] struct MediaFileListItemInternal { id: i64, - token: MediaFileToken, + media_file_token: String, origin_category: MediaFileOriginCategory, origin_product_category: MediaFileOriginProductCategory, @@ -196,6 +204,10 @@ struct MediaFileListItemInternal { maybe_public_bucket_prefix: Option, maybe_public_bucket_extension: Option, + creator_user_token: String, + creator_username: String, + creator_display_name: String, + creator_email_gravatar_hash: String, creator_set_visibility: Visibility, created_at: DateTime, diff --git a/crates/service/web/storyteller_web/Cargo.toml b/crates/service/web/storyteller_web/Cargo.toml index 50328fb0c6..15786af059 100644 --- a/crates/service/web/storyteller_web/Cargo.toml +++ b/crates/service/web/storyteller_web/Cargo.toml @@ -167,3 +167,6 @@ diesel = { version = "2.1.3", features = ["mysql"] } [dev-dependencies] speculoos = "0.9.0" # Fluent assertions + +[profile.dev.package.sqlx-macros] +opt-level = 3 \ No newline at end of file diff --git a/crates/service/web/storyteller_web/src/http_server/common_responses/media_file_social_meta_lite.rs b/crates/service/web/storyteller_web/src/http_server/common_responses/media_file_social_meta_lite.rs new file mode 100644 index 0000000000..3cd2ba5848 --- /dev/null +++ b/crates/service/web/storyteller_web/src/http_server/common_responses/media_file_social_meta_lite.rs @@ -0,0 +1,96 @@ +use tokens::tokens::media_files::MediaFileToken; + + +/// Everything we need to refer to a media_file on the public web interface. +#[derive(Clone, Serialize)] +pub struct MediaFileSocialMetaLight { + /// The token for the media_file + pub media_file_token: MediaFileToken, + + pub favorites_count: u64, + pub comments_count: u64, + pub signed_in_user_favorited: bool, +} + +impl MediaFileSocialMetaLight { + + pub fn from_db_fields( + media_file_token: &MediaFileToken, + favorites_count: u64, + comments_count: u64, + signed_in_user_favorited: bool, + ) -> Self { + Self { + media_file_token: media_file_token.clone(), + favorites_count, + comments_count, + signed_in_user_favorited, + } + } + + pub fn from_optional_db_fields( + maybe_media_file_token: Option<&MediaFileToken>, + favorites_count: u64, + comments_count: u64, + signed_in_user_favorited: bool, + ) -> Option { + Self::from_optional_db_fields_owned( + maybe_media_file_token.map(|u| u.clone()), + favorites_count, + comments_count, + signed_in_user_favorited, + ) + } + + pub fn from_optional_db_fields_owned( + maybe_media_file_token: Option, + favorites_count: u64, + comments_count: u64, + signed_in_user_favorited: bool, + ) -> Option { + match (maybe_media_file_token) { + (Some(media_file_token)) => { + Some(Self { + media_file_token, + favorites_count, + comments_count, + signed_in_user_favorited, + }) + } + _ => { + None + } + } + } +} + +#[derive(Clone, Serialize)] +pub struct DefaultAvatarInfo { + pub image_index: u8, + pub color_index: u8, +} + + +#[cfg(test)] +mod tests { + use tokens::tokens::media_files::MediaFileToken; + + use crate::http_server::common_responses::media_file_social_meta_lite::MediaFileSocialMetaLight; + + #[test] + fn test_from_optional_db_fields() { + let media_file_token = MediaFileToken::new_from_str("token"); + let media_filename = "media_filename"; + let display_name = "display_name"; + let gravatar_hash= "adsf"; + + let media_file_details = MediaFileSocialMetaLight::from_optional_db_fields( + Some(&media_file_token), + 0,0,false + ); + + let media_file_details = media_file_details.expect("Should not be optional."); + + assert_eq!(media_file_details.media_file_token, media_file_token); + } +} diff --git a/crates/service/web/storyteller_web/src/http_server/common_responses/mod.rs b/crates/service/web/storyteller_web/src/http_server/common_responses/mod.rs index d84a319a04..f22f30d692 100644 --- a/crates/service/web/storyteller_web/src/http_server/common_responses/mod.rs +++ b/crates/service/web/storyteller_web/src/http_server/common_responses/mod.rs @@ -1,3 +1,4 @@ pub mod pagination_cursors; pub mod pagination_page; -pub mod user_details_lite; \ No newline at end of file +pub mod user_details_lite; +pub mod media_file_social_meta_lite; \ No newline at end of file diff --git a/crates/service/web/storyteller_web/src/http_server/endpoints/media_files/list_media_files.rs b/crates/service/web/storyteller_web/src/http_server/endpoints/media_files/list_media_files.rs index db8346409f..ca8fea8bd0 100644 --- a/crates/service/web/storyteller_web/src/http_server/endpoints/media_files/list_media_files.rs +++ b/crates/service/web/storyteller_web/src/http_server/endpoints/media_files/list_media_files.rs @@ -12,7 +12,7 @@ use enums::by_table::media_files::media_file_origin_model_type::MediaFileOriginM use enums::by_table::media_files::media_file_origin_product_category::MediaFileOriginProductCategory; use enums::by_table::media_files::media_file_type::MediaFileType; use enums::common::visibility::Visibility; -use mysql_queries::queries::media_files::list_media_files_for_user::{list_media_files_for_user, ListMediaFileForUserArgs, ViewAs}; +use mysql_queries::queries::media_files::list_media_files::{list_media_files, ListMediaFilesArgs, ViewAs}; use tokens::tokens::media_files::MediaFileToken; use crate::http_server::common_responses::pagination_cursors::PaginationCursors; @@ -50,7 +50,7 @@ pub struct MediaFileListItem { pub maybe_public_bucket_prefix: Option, pub maybe_public_bucket_extension: Option, - pub maybe_creator: Option, + pub creator: UserDetailsLight, pub creator_set_visibility: Visibility, @@ -91,7 +91,6 @@ pub async fn list_media_files_handler( server_state: web::Data> ) -> Result { - info!("Fetching inference results for user: {}", &path.username); let maybe_user_session = server_state .session_checker @@ -108,7 +107,6 @@ pub async fn list_media_files_handler( match maybe_user_session { None => {}, Some(session) => { - is_author = session.username == path.username; is_mod = session.can_ban_users; }, }; @@ -130,15 +128,13 @@ pub async fn list_media_files_handler( None }; - let view_as = if is_author { - ViewAs::Author - } else if is_mod { + let view_as = if is_mod { ViewAs::Moderator } else { ViewAs::AnotherUser }; - let query_results = list_media_files_for_user(ListMediaFileForUserArgs { + let query_results = list_media_files(ListMediaFilesArgs { limit, maybe_filter_media_type: query.filter_media_type, maybe_offset: cursor, @@ -189,6 +185,12 @@ pub async fn list_media_files_handler( public_bucket_directory_hash: record.public_bucket_directory_hash, maybe_public_bucket_prefix: record.maybe_public_bucket_prefix, maybe_public_bucket_extension: record.maybe_public_bucket_extension, + creator: UserDetailsLight::from_db_fields( + &record.creator_user_token, + &record.creator_username, + &record.creator_display_name, + &record.creator_email_gravatar_hash, + ), creator_set_visibility: record.creator_set_visibility, created_at: record.created_at, updated_at: record.updated_at, diff --git a/crates/service/web/storyteller_web/src/routes.rs b/crates/service/web/storyteller_web/src/routes.rs index 9aafd5340c..1e303b33c4 100644 --- a/crates/service/web/storyteller_web/src/routes.rs +++ b/crates/service/web/storyteller_web/src/routes.rs @@ -44,6 +44,7 @@ use crate::http_server::endpoints::investor_demo::enable_demo_mode_handler::enab use crate::http_server::endpoints::leaderboard::get_leaderboard::leaderboard_handler; use crate::http_server::endpoints::media_files::delete_media_file::delete_media_file_handler; use crate::http_server::endpoints::media_files::get_media_file::get_media_file_handler; +use crate::http_server::endpoints::media_files::list_media_files::list_media_files_handler; use crate::http_server::endpoints::media_files::list_media_files_for_user::list_media_files_for_user_handler; use crate::http_server::endpoints::media_uploads::list_user_media_uploads_of_type::list_user_media_uploads_of_type_handler; use crate::http_server::endpoints::media_uploads::upload_audio::upload_audio_handler; @@ -1007,6 +1008,10 @@ fn add_media_file_routes (app: App) -> App .route(web::delete().to(delete_media_file_handler)) .route(web::head().to(|| HttpResponse::Ok())) ) + .service(web::resource("/feed") + .route(web::get().to(list_media_files_handler)) + .route(web::head().to(|| HttpResponse::Ok())) + ) .service(web::resource("/user/{username}") .route(web::get().to(list_media_files_for_user_handler)) .route(web::head().to(|| HttpResponse::Ok()))