mirror of
https://github.com/LemmyNet/lemmy.git
synced 2024-11-25 02:41:01 +00:00
Adding community description in addition to sidebar, like site. (#5120)
* Adding community description in addition to sidebar, like site. - Also made changes to lemmy's group apub to be similar to its site, which uses content for the sidebar, and summary for the short description. - Fixes #5078 * Fixing tests. * Remove comment. * Fix name for description checker.
This commit is contained in:
parent
d6d01a3b62
commit
cdc1cf3bf7
19 changed files with 100 additions and 43 deletions
|
@ -48,7 +48,9 @@ pub struct CreateCommunity {
|
|||
pub name: String,
|
||||
/// A longer title.
|
||||
pub title: String,
|
||||
/// A longer sidebar, or description of your community, in markdown.
|
||||
/// A sidebar for the community in markdown.
|
||||
pub sidebar: Option<String>,
|
||||
/// A shorter, one line description of your community.
|
||||
pub description: Option<String>,
|
||||
/// An icon URL.
|
||||
pub icon: Option<String>,
|
||||
|
@ -147,7 +149,9 @@ pub struct EditCommunity {
|
|||
pub community_id: CommunityId,
|
||||
/// A longer title.
|
||||
pub title: Option<String>,
|
||||
/// A longer sidebar, or description of your community, in markdown.
|
||||
/// A sidebar for the community in markdown.
|
||||
pub sidebar: Option<String>,
|
||||
/// A shorter, one line description of your community.
|
||||
pub description: Option<String>,
|
||||
/// An icon URL.
|
||||
pub icon: Option<String>,
|
||||
|
|
|
@ -221,6 +221,7 @@ pub struct CreateSite {
|
|||
/// Edits a site.
|
||||
pub struct EditSite {
|
||||
pub name: Option<String>,
|
||||
/// A sidebar for the site, in markdown.
|
||||
pub sidebar: Option<String>,
|
||||
/// A shorter, one line description of your site.
|
||||
pub description: Option<String>,
|
||||
|
|
|
@ -36,7 +36,11 @@ use lemmy_utils::{
|
|||
error::{LemmyErrorExt, LemmyErrorType, LemmyResult},
|
||||
utils::{
|
||||
slurs::check_slurs,
|
||||
validation::{is_valid_actor_name, is_valid_body_field},
|
||||
validation::{
|
||||
is_valid_actor_name,
|
||||
is_valid_body_field,
|
||||
site_or_community_description_length_check,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -57,8 +61,18 @@ pub async fn create_community(
|
|||
let url_blocklist = get_url_blocklist(&context).await?;
|
||||
check_slurs(&data.name, &slur_regex)?;
|
||||
check_slurs(&data.title, &slur_regex)?;
|
||||
let description =
|
||||
process_markdown_opt(&data.description, &slur_regex, &url_blocklist, &context).await?;
|
||||
let sidebar = process_markdown_opt(&data.sidebar, &slur_regex, &url_blocklist, &context).await?;
|
||||
|
||||
// Ensure that the sidebar has fewer than the max num characters...
|
||||
if let Some(sidebar) = &sidebar {
|
||||
is_valid_body_field(sidebar, false)?;
|
||||
}
|
||||
|
||||
let description = data.description.clone();
|
||||
if let Some(desc) = &description {
|
||||
site_or_community_description_length_check(desc)?;
|
||||
check_slurs(desc, &slur_regex)?;
|
||||
}
|
||||
|
||||
let icon = diesel_url_create(data.icon.as_deref())?;
|
||||
let icon = proxy_image_link_api(icon, &context).await?;
|
||||
|
@ -68,10 +82,6 @@ pub async fn create_community(
|
|||
|
||||
is_valid_actor_name(&data.name, local_site.actor_name_max_length as usize)?;
|
||||
|
||||
if let Some(desc) = &data.description {
|
||||
is_valid_body_field(desc, false)?;
|
||||
}
|
||||
|
||||
// Double check for duplicate community actor_ids
|
||||
let community_actor_id = generate_local_apub_endpoint(
|
||||
EndpointType::Community,
|
||||
|
@ -88,6 +98,7 @@ pub async fn create_community(
|
|||
let keypair = generate_actor_keypair()?;
|
||||
|
||||
let community_form = CommunityInsertForm {
|
||||
sidebar,
|
||||
description,
|
||||
icon,
|
||||
banner,
|
||||
|
|
|
@ -41,16 +41,18 @@ pub async fn update_community(
|
|||
let url_blocklist = get_url_blocklist(&context).await?;
|
||||
check_slurs_opt(&data.title, &slur_regex)?;
|
||||
|
||||
let description = diesel_string_update(
|
||||
process_markdown_opt(&data.description, &slur_regex, &url_blocklist, &context)
|
||||
let sidebar = diesel_string_update(
|
||||
process_markdown_opt(&data.sidebar, &slur_regex, &url_blocklist, &context)
|
||||
.await?
|
||||
.as_deref(),
|
||||
);
|
||||
|
||||
if let Some(Some(desc)) = &description {
|
||||
is_valid_body_field(desc, false)?;
|
||||
if let Some(Some(sidebar)) = &sidebar {
|
||||
is_valid_body_field(sidebar, false)?;
|
||||
}
|
||||
|
||||
let description = diesel_string_update(data.description.as_deref());
|
||||
|
||||
let old_community = Community::read(&mut context.pool(), data.community_id).await?;
|
||||
|
||||
let icon = diesel_url_update(data.icon.as_deref())?;
|
||||
|
@ -84,6 +86,7 @@ pub async fn update_community(
|
|||
|
||||
let community_form = CommunityUpdateForm {
|
||||
title: data.title.clone(),
|
||||
sidebar,
|
||||
description,
|
||||
icon,
|
||||
banner,
|
||||
|
|
|
@ -29,13 +29,13 @@ use lemmy_db_views::structs::{LocalUserView, SiteView};
|
|||
use lemmy_utils::{
|
||||
error::{LemmyErrorType, LemmyResult},
|
||||
utils::{
|
||||
slurs::{check_slurs, check_slurs_opt},
|
||||
slurs::check_slurs,
|
||||
validation::{
|
||||
build_and_check_regex,
|
||||
check_site_visibility_valid,
|
||||
is_valid_body_field,
|
||||
site_description_length_check,
|
||||
site_name_length_check,
|
||||
site_or_community_description_length_check,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
@ -167,8 +167,8 @@ fn validate_create_payload(local_site: &LocalSite, create_site: &CreateSite) ->
|
|||
check_slurs(&create_site.name, &slur_regex)?;
|
||||
|
||||
if let Some(desc) = &create_site.description {
|
||||
site_description_length_check(desc)?;
|
||||
check_slurs_opt(&create_site.description, &slur_regex)?;
|
||||
site_or_community_description_length_check(desc)?;
|
||||
check_slurs(desc, &slur_regex)?;
|
||||
}
|
||||
|
||||
site_default_post_listing_type_check(&create_site.default_post_listing_type)?;
|
||||
|
|
|
@ -40,8 +40,8 @@ use lemmy_utils::{
|
|||
check_site_visibility_valid,
|
||||
check_urls_are_valid,
|
||||
is_valid_body_field,
|
||||
site_description_length_check,
|
||||
site_name_length_check,
|
||||
site_or_community_description_length_check,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
@ -219,7 +219,7 @@ fn validate_update_payload(local_site: &LocalSite, edit_site: &EditSite) -> Lemm
|
|||
}
|
||||
|
||||
if let Some(desc) = &edit_site.description {
|
||||
site_description_length_check(desc)?;
|
||||
site_or_community_description_length_check(desc)?;
|
||||
check_slurs_opt(&edit_site.description, &slur_regex)?;
|
||||
}
|
||||
|
||||
|
|
|
@ -3,11 +3,13 @@
|
|||
"type": "Group",
|
||||
"preferredUsername": "tenforward",
|
||||
"name": "Ten Forward",
|
||||
"summary": "<p>Lounge and recreation facility</p>\n<hr />\n<p>Welcome to the Enterprise!.</p>\n",
|
||||
"summary": "A description of ten forward.",
|
||||
"content": "<p>Lounge and recreation facility</p>\n<hr />\n<p>Welcome to the Enterprise!.</p>\n",
|
||||
"source": {
|
||||
"content": "Lounge and recreation facility\n\n---\n\nWelcome to the Enterprise!",
|
||||
"mediaType": "text/markdown"
|
||||
},
|
||||
"mediaType": "text/html",
|
||||
"sensitive": false,
|
||||
"icon": {
|
||||
"type": "Image",
|
||||
|
|
|
@ -13,6 +13,7 @@ use crate::{
|
|||
use activitypub_federation::{
|
||||
config::Data,
|
||||
kinds::actor::GroupType,
|
||||
protocol::values::MediaTypeHtml,
|
||||
traits::{Actor, Object},
|
||||
};
|
||||
use chrono::{DateTime, Utc};
|
||||
|
@ -107,8 +108,10 @@ impl Object for ApubCommunity {
|
|||
id: self.id().into(),
|
||||
preferred_username: self.name.clone(),
|
||||
name: Some(self.title.clone()),
|
||||
summary: self.description.as_ref().map(|b| markdown_to_html(b)),
|
||||
source: self.description.clone().map(Source::new),
|
||||
content: self.sidebar.as_ref().map(|d| markdown_to_html(d)),
|
||||
source: self.sidebar.clone().map(Source::new),
|
||||
summary: self.description.clone(),
|
||||
media_type: self.sidebar.as_ref().map(|_| MediaTypeHtml::Html),
|
||||
icon: self.icon.clone().map(ImageObject::new),
|
||||
image: self.banner.clone().map(ImageObject::new),
|
||||
sensitive: Some(self.nsfw),
|
||||
|
@ -144,10 +147,9 @@ impl Object for ApubCommunity {
|
|||
let local_site = LocalSite::read(&mut context.pool()).await.ok();
|
||||
let slur_regex = &local_site_opt_to_slur_regex(&local_site);
|
||||
let url_blocklist = get_url_blocklist(context).await?;
|
||||
let description = read_from_string_or_source_opt(&group.summary, &None, &group.source);
|
||||
let description =
|
||||
process_markdown_opt(&description, slur_regex, &url_blocklist, context).await?;
|
||||
let description = markdown_rewrite_remote_links_opt(description, context).await;
|
||||
let sidebar = read_from_string_or_source_opt(&group.content, &None, &group.source);
|
||||
let sidebar = process_markdown_opt(&sidebar, slur_regex, &url_blocklist, context).await?;
|
||||
let sidebar = markdown_rewrite_remote_links_opt(sidebar, context).await;
|
||||
let icon = proxy_image_link_opt_apub(group.icon.map(|i| i.url), context).await?;
|
||||
let banner = proxy_image_link_opt_apub(group.image.map(|i| i.url), context).await?;
|
||||
|
||||
|
@ -161,7 +163,8 @@ impl Object for ApubCommunity {
|
|||
last_refreshed_at: Some(naive_now()),
|
||||
icon,
|
||||
banner,
|
||||
description,
|
||||
sidebar,
|
||||
description: group.summary,
|
||||
followers_url: group.followers.clone().map(Into::into),
|
||||
inbox_url: Some(
|
||||
group
|
||||
|
@ -299,10 +302,16 @@ pub(crate) mod tests {
|
|||
|
||||
assert_eq!(community.title, "Ten Forward");
|
||||
assert!(!community.local);
|
||||
|
||||
// Test the sidebar and description
|
||||
assert_eq!(
|
||||
community.description.as_ref().map(std::string::String::len),
|
||||
community.sidebar.as_ref().map(std::string::String::len),
|
||||
Some(63)
|
||||
);
|
||||
assert_eq!(
|
||||
community.description,
|
||||
Some("A description of ten forward.".into())
|
||||
);
|
||||
|
||||
Community::delete(&mut context.pool(), community.id).await?;
|
||||
Site::delete(&mut context.pool(), site.id).await?;
|
||||
|
|
|
@ -7,7 +7,7 @@ use crate::{
|
|||
community_outbox::ApubCommunityOutbox,
|
||||
},
|
||||
local_site_data_cached,
|
||||
objects::{community::ApubCommunity, read_from_string_or_source_opt},
|
||||
objects::community::ApubCommunity,
|
||||
protocol::{
|
||||
objects::{Endpoints, LanguageTag},
|
||||
ImageObject,
|
||||
|
@ -21,6 +21,7 @@ use activitypub_federation::{
|
|||
protocol::{
|
||||
helpers::deserialize_skip_error,
|
||||
public_key::PublicKey,
|
||||
values::MediaTypeHtml,
|
||||
verification::verify_domains_match,
|
||||
},
|
||||
};
|
||||
|
@ -50,9 +51,13 @@ pub struct Group {
|
|||
|
||||
/// title
|
||||
pub(crate) name: Option<String>,
|
||||
pub(crate) summary: Option<String>,
|
||||
// sidebar
|
||||
pub(crate) content: Option<String>,
|
||||
#[serde(deserialize_with = "deserialize_skip_error", default)]
|
||||
pub(crate) source: Option<Source>,
|
||||
pub(crate) media_type: Option<MediaTypeHtml>,
|
||||
// short instance description
|
||||
pub(crate) summary: Option<String>,
|
||||
#[serde(deserialize_with = "deserialize_skip_error", default)]
|
||||
pub(crate) icon: Option<ImageObject>,
|
||||
/// banner
|
||||
|
@ -86,8 +91,7 @@ impl Group {
|
|||
|
||||
check_slurs(&self.preferred_username, slur_regex)?;
|
||||
check_slurs_opt(&self.name, slur_regex)?;
|
||||
let description = read_from_string_or_source_opt(&self.summary, &None, &self.source);
|
||||
check_slurs_opt(&description, slur_regex)?;
|
||||
check_slurs_opt(&self.summary, slur_regex)?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
|
|
@ -32,9 +32,9 @@ pub struct Instance {
|
|||
pub(crate) content: Option<String>,
|
||||
#[serde(deserialize_with = "deserialize_skip_error", default)]
|
||||
pub(crate) source: Option<Source>,
|
||||
pub(crate) media_type: Option<MediaTypeHtml>,
|
||||
// short instance description
|
||||
pub(crate) summary: Option<String>,
|
||||
pub(crate) media_type: Option<MediaTypeHtml>,
|
||||
/// instance icon
|
||||
pub(crate) icon: Option<ImageObject>,
|
||||
/// instance banner
|
||||
|
|
|
@ -508,6 +508,7 @@ mod tests {
|
|||
id: inserted_community.id,
|
||||
name: "TIL".into(),
|
||||
title: "nada".to_owned(),
|
||||
sidebar: None,
|
||||
description: None,
|
||||
nsfw: false,
|
||||
removed: false,
|
||||
|
|
|
@ -170,7 +170,7 @@ diesel::table! {
|
|||
name -> Varchar,
|
||||
#[max_length = 255]
|
||||
title -> Varchar,
|
||||
description -> Nullable<Text>,
|
||||
sidebar -> Nullable<Text>,
|
||||
removed -> Bool,
|
||||
published -> Timestamptz,
|
||||
updated -> Nullable<Timestamptz>,
|
||||
|
@ -196,6 +196,8 @@ diesel::table! {
|
|||
#[max_length = 255]
|
||||
featured_url -> Nullable<Varchar>,
|
||||
visibility -> CommunityVisibility,
|
||||
#[max_length = 150]
|
||||
description -> Nullable<Varchar>,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -24,8 +24,8 @@ pub struct Community {
|
|||
pub name: String,
|
||||
/// A longer title, that can contain other characters, and doesn't have to be unique.
|
||||
pub title: String,
|
||||
/// A sidebar / markdown description.
|
||||
pub description: Option<String>,
|
||||
/// A sidebar for the community in markdown.
|
||||
pub sidebar: Option<String>,
|
||||
/// Whether the community is removed by a mod.
|
||||
pub removed: bool,
|
||||
pub published: DateTime<Utc>,
|
||||
|
@ -66,6 +66,8 @@ pub struct Community {
|
|||
#[serde(skip)]
|
||||
pub featured_url: Option<DbUrl>,
|
||||
pub visibility: CommunityVisibility,
|
||||
/// A shorter, one-line description of the site.
|
||||
pub description: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, derive_new::new)]
|
||||
|
@ -77,7 +79,7 @@ pub struct CommunityInsertForm {
|
|||
pub title: String,
|
||||
pub public_key: String,
|
||||
#[new(default)]
|
||||
pub description: Option<String>,
|
||||
pub sidebar: Option<String>,
|
||||
#[new(default)]
|
||||
pub removed: Option<bool>,
|
||||
#[new(default)]
|
||||
|
@ -114,6 +116,8 @@ pub struct CommunityInsertForm {
|
|||
pub posting_restricted_to_mods: Option<bool>,
|
||||
#[new(default)]
|
||||
pub visibility: Option<CommunityVisibility>,
|
||||
#[new(default)]
|
||||
pub description: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Default)]
|
||||
|
@ -121,7 +125,7 @@ pub struct CommunityInsertForm {
|
|||
#[cfg_attr(feature = "full", diesel(table_name = community))]
|
||||
pub struct CommunityUpdateForm {
|
||||
pub title: Option<String>,
|
||||
pub description: Option<Option<String>>,
|
||||
pub sidebar: Option<Option<String>>,
|
||||
pub removed: Option<bool>,
|
||||
pub published: Option<DateTime<Utc>>,
|
||||
pub updated: Option<Option<DateTime<Utc>>>,
|
||||
|
@ -141,6 +145,7 @@ pub struct CommunityUpdateForm {
|
|||
pub hidden: Option<bool>,
|
||||
pub posting_restricted_to_mods: Option<bool>,
|
||||
pub visibility: Option<CommunityVisibility>,
|
||||
pub description: Option<Option<String>>,
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Eq, Debug)]
|
||||
|
|
|
@ -391,6 +391,7 @@ mod tests {
|
|||
actor_id: inserted_community.actor_id.clone(),
|
||||
local: true,
|
||||
title: inserted_community.title,
|
||||
sidebar: None,
|
||||
description: None,
|
||||
updated: None,
|
||||
banner: None,
|
||||
|
|
|
@ -1092,6 +1092,7 @@ mod tests {
|
|||
actor_id: data.inserted_community.actor_id.clone(),
|
||||
local: true,
|
||||
title: "nada".to_owned(),
|
||||
sidebar: None,
|
||||
description: None,
|
||||
updated: None,
|
||||
banner: None,
|
||||
|
|
|
@ -1834,6 +1834,7 @@ mod tests {
|
|||
actor_id: inserted_community.actor_id.clone(),
|
||||
local: true,
|
||||
title: "nada".to_owned(),
|
||||
sidebar: None,
|
||||
description: None,
|
||||
updated: None,
|
||||
banner: None,
|
||||
|
|
|
@ -191,8 +191,8 @@ pub fn site_name_length_check(name: &str) -> LemmyResult<()> {
|
|||
)
|
||||
}
|
||||
|
||||
/// Checks the site description length, the limit as defined in the DB.
|
||||
pub fn site_description_length_check(description: &str) -> LemmyResult<()> {
|
||||
/// Checks the site / community description length, the limit as defined in the DB.
|
||||
pub fn site_or_community_description_length_check(description: &str) -> LemmyResult<()> {
|
||||
max_length_check(
|
||||
description,
|
||||
SITE_DESCRIPTION_MAX_LENGTH,
|
||||
|
@ -368,8 +368,8 @@ mod tests {
|
|||
is_valid_matrix_id,
|
||||
is_valid_post_title,
|
||||
is_valid_url,
|
||||
site_description_length_check,
|
||||
site_name_length_check,
|
||||
site_or_community_description_length_check,
|
||||
BIO_MAX_LENGTH,
|
||||
SITE_DESCRIPTION_MAX_LENGTH,
|
||||
SITE_NAME_MAX_LENGTH,
|
||||
|
@ -537,14 +537,14 @@ mod tests {
|
|||
|
||||
#[test]
|
||||
fn test_valid_site_description() {
|
||||
assert!(site_description_length_check(
|
||||
assert!(site_or_community_description_length_check(
|
||||
&(0..SITE_DESCRIPTION_MAX_LENGTH)
|
||||
.map(|_| 'A')
|
||||
.collect::<String>()
|
||||
)
|
||||
.is_ok());
|
||||
|
||||
let invalid_result = site_description_length_check(
|
||||
let invalid_result = site_or_community_description_length_check(
|
||||
&(0..SITE_DESCRIPTION_MAX_LENGTH + 1)
|
||||
.map(|_| 'A')
|
||||
.collect::<String>(),
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
ALTER TABLE community
|
||||
DROP COLUMN description;
|
||||
|
||||
ALTER TABLE community RENAME COLUMN sidebar TO description;
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
-- Renaming description to sidebar
|
||||
ALTER TABLE community RENAME COLUMN description TO sidebar;
|
||||
|
||||
-- Adding a short description column
|
||||
ALTER TABLE community
|
||||
ADD COLUMN description varchar(150);
|
||||
|
Loading…
Reference in a new issue