mirror of
https://github.com/LemmyNet/lemmy.git
synced 2024-12-23 03:11:32 +00:00
community icon/banner
This commit is contained in:
parent
5f49b2aaec
commit
a6f7e76bec
4 changed files with 80 additions and 22 deletions
|
@ -1,3 +1,4 @@
|
||||||
|
use lemmy_db_schema::newtypes::CommunityId;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use serde_with::skip_serializing_none;
|
use serde_with::skip_serializing_none;
|
||||||
#[cfg(feature = "full")]
|
#[cfg(feature = "full")]
|
||||||
|
@ -44,3 +45,10 @@ pub struct UploadImageResponse {
|
||||||
pub filename: String,
|
pub filename: String,
|
||||||
pub delete_token: String,
|
pub delete_token: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Parameter for setting community icon or banner. Can't use POST data here as it already contains
|
||||||
|
/// the image data.
|
||||||
|
#[derive(Debug, Serialize, Deserialize, Clone, Default, PartialEq, Eq, Hash)]
|
||||||
|
pub struct CommunityIdQuery {
|
||||||
|
pub id: CommunityId,
|
||||||
|
}
|
||||||
|
|
|
@ -13,7 +13,6 @@ use lemmy_api_common::{
|
||||||
is_admin,
|
is_admin,
|
||||||
local_site_to_slur_regex,
|
local_site_to_slur_regex,
|
||||||
process_markdown_opt,
|
process_markdown_opt,
|
||||||
proxy_image_link_api,
|
|
||||||
EndpointType,
|
EndpointType,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
@ -31,7 +30,6 @@ use lemmy_db_schema::{
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
traits::{ApubActor, Crud, Followable, Joinable},
|
traits::{ApubActor, Crud, Followable, Joinable},
|
||||||
utils::diesel_url_create,
|
|
||||||
};
|
};
|
||||||
use lemmy_db_views::structs::{LocalUserView, SiteView};
|
use lemmy_db_views::structs::{LocalUserView, SiteView};
|
||||||
use lemmy_utils::{
|
use lemmy_utils::{
|
||||||
|
@ -76,12 +74,6 @@ pub async fn create_community(
|
||||||
check_slurs(desc, &slur_regex)?;
|
check_slurs(desc, &slur_regex)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
let icon = diesel_url_create(data.icon.as_deref())?;
|
|
||||||
let icon = proxy_image_link_api(icon, &context).await?;
|
|
||||||
|
|
||||||
let banner = diesel_url_create(data.banner.as_deref())?;
|
|
||||||
let banner = proxy_image_link_api(banner, &context).await?;
|
|
||||||
|
|
||||||
is_valid_actor_name(&data.name, local_site.actor_name_max_length as usize)?;
|
is_valid_actor_name(&data.name, local_site.actor_name_max_length as usize)?;
|
||||||
|
|
||||||
if let Some(desc) = &data.description {
|
if let Some(desc) = &data.description {
|
||||||
|
@ -108,8 +100,6 @@ pub async fn create_community(
|
||||||
let community_form = CommunityInsertForm {
|
let community_form = CommunityInsertForm {
|
||||||
sidebar,
|
sidebar,
|
||||||
description,
|
description,
|
||||||
icon,
|
|
||||||
banner,
|
|
||||||
nsfw: data.nsfw,
|
nsfw: data.nsfw,
|
||||||
actor_id: Some(community_actor_id.clone()),
|
actor_id: Some(community_actor_id.clone()),
|
||||||
private_key: Some(keypair.private_key),
|
private_key: Some(keypair.private_key),
|
||||||
|
|
|
@ -2,13 +2,15 @@ use super::utils::{adapt_request, delete_old_image, make_send};
|
||||||
use actix_web::{self, web::*, HttpRequest};
|
use actix_web::{self, web::*, HttpRequest};
|
||||||
use lemmy_api_common::{
|
use lemmy_api_common::{
|
||||||
context::LemmyContext,
|
context::LemmyContext,
|
||||||
image::UploadImageResponse,
|
image::{CommunityIdQuery, UploadImageResponse},
|
||||||
request::PictrsResponse,
|
request::PictrsResponse,
|
||||||
|
utils::is_mod_or_admin,
|
||||||
LemmyErrorType,
|
LemmyErrorType,
|
||||||
SuccessResponse,
|
SuccessResponse,
|
||||||
};
|
};
|
||||||
use lemmy_db_schema::{
|
use lemmy_db_schema::{
|
||||||
source::{
|
source::{
|
||||||
|
community::{Community, CommunityUpdateForm},
|
||||||
images::{LocalImage, LocalImageForm},
|
images::{LocalImage, LocalImageForm},
|
||||||
person::{Person, PersonUpdateForm},
|
person::{Person, PersonUpdateForm},
|
||||||
},
|
},
|
||||||
|
@ -50,11 +52,11 @@ pub async fn upload_user_avatar(
|
||||||
let image = do_upload_image(req, body, Avatar, &local_user_view, &context).await?;
|
let image = do_upload_image(req, body, Avatar, &local_user_view, &context).await?;
|
||||||
delete_old_image(&local_user_view.person.avatar, &context).await?;
|
delete_old_image(&local_user_view.person.avatar, &context).await?;
|
||||||
|
|
||||||
let person_form = PersonUpdateForm {
|
let form = PersonUpdateForm {
|
||||||
avatar: Some(Some(image.image_url.into())),
|
avatar: Some(Some(image.image_url.into())),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
};
|
};
|
||||||
Person::update(&mut context.pool(), local_user_view.person.id, &person_form).await?;
|
Person::update(&mut context.pool(), local_user_view.person.id, &form).await?;
|
||||||
|
|
||||||
Ok(Json(SuccessResponse::default()))
|
Ok(Json(SuccessResponse::default()))
|
||||||
}
|
}
|
||||||
|
@ -68,11 +70,55 @@ pub async fn upload_user_banner(
|
||||||
let image = do_upload_image(req, body, Banner, &local_user_view, &context).await?;
|
let image = do_upload_image(req, body, Banner, &local_user_view, &context).await?;
|
||||||
delete_old_image(&local_user_view.person.banner, &context).await?;
|
delete_old_image(&local_user_view.person.banner, &context).await?;
|
||||||
|
|
||||||
let person_form = PersonUpdateForm {
|
let form = PersonUpdateForm {
|
||||||
banner: Some(Some(image.image_url.into())),
|
banner: Some(Some(image.image_url.into())),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
};
|
};
|
||||||
Person::update(&mut context.pool(), local_user_view.person.id, &person_form).await?;
|
Person::update(&mut context.pool(), local_user_view.person.id, &form).await?;
|
||||||
|
|
||||||
|
Ok(Json(SuccessResponse::default()))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn upload_community_icon(
|
||||||
|
req: HttpRequest,
|
||||||
|
query: Query<CommunityIdQuery>,
|
||||||
|
body: Payload,
|
||||||
|
local_user_view: LocalUserView,
|
||||||
|
context: Data<LemmyContext>,
|
||||||
|
) -> LemmyResult<Json<SuccessResponse>> {
|
||||||
|
let community: Community = Community::read(&mut context.pool(), query.id).await?;
|
||||||
|
is_mod_or_admin(&mut context.pool(), &local_user_view.person, community.id).await?;
|
||||||
|
|
||||||
|
let image = do_upload_image(req, body, Avatar, &local_user_view, &context).await?;
|
||||||
|
delete_old_image(&community.icon, &context).await?;
|
||||||
|
|
||||||
|
let form = CommunityUpdateForm {
|
||||||
|
icon: Some(Some(image.image_url.into())),
|
||||||
|
..Default::default()
|
||||||
|
};
|
||||||
|
Community::update(&mut context.pool(), community.id, &form).await?;
|
||||||
|
|
||||||
|
Ok(Json(SuccessResponse::default()))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn upload_community_banner(
|
||||||
|
req: HttpRequest,
|
||||||
|
query: Query<CommunityIdQuery>,
|
||||||
|
body: Payload,
|
||||||
|
local_user_view: LocalUserView,
|
||||||
|
context: Data<LemmyContext>,
|
||||||
|
) -> LemmyResult<Json<SuccessResponse>> {
|
||||||
|
let community: Community = Community::read(&mut context.pool(), query.id).await?;
|
||||||
|
is_mod_or_admin(&mut context.pool(), &local_user_view.person, community.id).await?;
|
||||||
|
|
||||||
|
let image = do_upload_image(req, body, Banner, &local_user_view, &context).await?;
|
||||||
|
delete_old_image(&community.icon, &context).await?;
|
||||||
|
|
||||||
|
let form = CommunityUpdateForm {
|
||||||
|
banner: Some(Some(image.image_url.into())),
|
||||||
|
..Default::default()
|
||||||
|
};
|
||||||
|
Community::update(&mut context.pool(), community.id, &form).await?;
|
||||||
|
|
||||||
Ok(Json(SuccessResponse::default()))
|
Ok(Json(SuccessResponse::default()))
|
||||||
}
|
}
|
||||||
|
@ -84,29 +130,35 @@ pub async fn do_upload_image(
|
||||||
local_user_view: &LocalUserView,
|
local_user_view: &LocalUserView,
|
||||||
context: &Data<LemmyContext>,
|
context: &Data<LemmyContext>,
|
||||||
) -> LemmyResult<UploadImageResponse> {
|
) -> LemmyResult<UploadImageResponse> {
|
||||||
let pictrs_config = context.settings().pictrs()?;
|
let pictrs = context.settings().pictrs()?;
|
||||||
let image_url = format!("{}image", pictrs_config.url);
|
let image_url = format!("{}image", pictrs.url);
|
||||||
|
|
||||||
let mut client_req = adapt_request(&req, image_url);
|
let mut client_req = adapt_request(&req, image_url);
|
||||||
|
|
||||||
client_req = match upload_type {
|
client_req = match upload_type {
|
||||||
Avatar => {
|
Avatar => {
|
||||||
let max_size = context.settings().pictrs()?.max_avatar_size.to_string();
|
let max_size = pictrs.max_avatar_size.to_string();
|
||||||
|
client_req.query(&[
|
||||||
|
("resize", max_size.as_ref()),
|
||||||
|
("allow_animation", "false"),
|
||||||
|
("allow_video", "false"),
|
||||||
|
])
|
||||||
|
}
|
||||||
|
Banner => {
|
||||||
|
let max_size = pictrs.max_banner_size.to_string();
|
||||||
client_req.query(&[
|
client_req.query(&[
|
||||||
("resize", max_size.as_ref()),
|
("resize", max_size.as_ref()),
|
||||||
("allow_animation", "false"),
|
("allow_animation", "false"),
|
||||||
("allow_video", "false"),
|
("allow_video", "false"),
|
||||||
])
|
])
|
||||||
}
|
}
|
||||||
// TODO: same as above but using `max_banner_size`
|
|
||||||
// Banner => {}
|
|
||||||
_ => client_req,
|
_ => client_req,
|
||||||
};
|
};
|
||||||
if let Some(addr) = req.head().peer_addr {
|
if let Some(addr) = req.head().peer_addr {
|
||||||
client_req = client_req.header("X-Forwarded-For", addr.to_string())
|
client_req = client_req.header("X-Forwarded-For", addr.to_string())
|
||||||
};
|
};
|
||||||
let res = client_req
|
let res = client_req
|
||||||
.timeout(Duration::from_secs(pictrs_config.upload_timeout))
|
.timeout(Duration::from_secs(pictrs.upload_timeout))
|
||||||
.body(Body::wrap_stream(make_send(body)))
|
.body(Body::wrap_stream(make_send(body)))
|
||||||
.send()
|
.send()
|
||||||
.await?
|
.await?
|
||||||
|
|
|
@ -162,7 +162,13 @@ use lemmy_routes::images::{
|
||||||
delete_image,
|
delete_image,
|
||||||
download::{get_image, image_proxy},
|
download::{get_image, image_proxy},
|
||||||
pictrs_health,
|
pictrs_health,
|
||||||
upload::{upload_image, upload_user_avatar, upload_user_banner},
|
upload::{
|
||||||
|
upload_community_banner,
|
||||||
|
upload_community_icon,
|
||||||
|
upload_image,
|
||||||
|
upload_user_avatar,
|
||||||
|
upload_user_banner,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
use lemmy_utils::rate_limit::RateLimitCell;
|
use lemmy_utils::rate_limit::RateLimitCell;
|
||||||
|
|
||||||
|
@ -205,6 +211,8 @@ pub fn config(cfg: &mut ServiceConfig, rate_limit: &RateLimitCell) {
|
||||||
.route("/transfer", post().to(transfer_community))
|
.route("/transfer", post().to(transfer_community))
|
||||||
.route("/ban_user", post().to(ban_from_community))
|
.route("/ban_user", post().to(ban_from_community))
|
||||||
.route("/mod", post().to(add_mod_to_community))
|
.route("/mod", post().to(add_mod_to_community))
|
||||||
|
.route("/icon", post().to(upload_community_icon))
|
||||||
|
.route("/banner", post().to(upload_community_banner))
|
||||||
.service(
|
.service(
|
||||||
scope("/pending_follows")
|
scope("/pending_follows")
|
||||||
.route("/count", get().to(get_pending_follows_count))
|
.route("/count", get().to(get_pending_follows_count))
|
||||||
|
|
Loading…
Reference in a new issue