Allow remote posts without content

This commit is contained in:
silverpill 2022-09-29 15:26:12 +00:00
parent b53a1298a2
commit f9465693a3
4 changed files with 19 additions and 29 deletions

View file

@ -1,6 +1,7 @@
use std::collections::HashMap;
use std::path::Path;
use chrono::Utc;
use serde_json::{Value as JsonValue};
use tokio_postgres::GenericClient;
use uuid::Uuid;
@ -64,10 +65,10 @@ fn parse_object_url(value: &JsonValue) -> Result<String, ConversionError> {
}
pub fn get_note_content(object: &Object) -> Result<String, ValidationError> {
let mut content = object.content.as_ref()
let mut content = object.content.as_deref()
// Lemmy pages and PeerTube videos have "name" property
.or(object.name.as_ref())
.ok_or(ValidationError("no content"))?
.or(object.name.as_deref())
.unwrap_or("")
.to_owned();
if object.object_type != NOTE {
if let Some(ref value) = object.url {
@ -159,6 +160,7 @@ pub async fn handle_note(
err
})?;
let content = get_note_content(&object)?;
let created_at = object.published.unwrap_or(Utc::now());
let mut attachments: Vec<Uuid> = Vec::new();
if let Some(value) = object.attachment {
@ -203,6 +205,10 @@ pub async fn handle_note(
attachments.push(db_attachment.id);
};
};
if content.is_empty() && attachments.is_empty() {
return Err(ValidationError("post is empty").into());
};
let mut mentions: Vec<Uuid> = Vec::new();
let mut tags = vec![];
let mut links = vec![];
@ -361,7 +367,7 @@ pub async fn handle_note(
tags: tags,
links: links,
object_id: Some(object.id),
created_at: object.published,
created_at,
};
let post = create_post(db_client, &author.id, post_data).await?;
Ok(post)

View file

@ -171,7 +171,7 @@ impl TryFrom<StatusData> for PostCreateData {
tags: vec![],
links: vec![],
object_id: None,
created_at: None,
created_at: Utc::now(),
};
Ok(post_data)
}

View file

@ -38,7 +38,6 @@ pub async fn create_post(
) -> Result<Post, DatabaseError> {
let transaction = db_client.transaction().await?;
let post_id = new_uuid();
let created_at = data.created_at.unwrap_or(Utc::now());
// Replying to reposts is not allowed
// Reposting of other reposts or non-public posts is not allowed
let insert_statement = format!(
@ -78,7 +77,7 @@ pub async fn create_post(
&data.repost_of_id,
&data.visibility,
&data.object_id,
&created_at,
&data.created_at,
],
).await.map_err(catch_unique_violation("post"))?;
let post_row = maybe_post_row.ok_or(DatabaseError::NotFound("post"))?;

View file

@ -244,12 +244,13 @@ pub struct PostCreateData {
pub tags: Vec<String>,
pub links: Vec<Uuid>,
pub object_id: Option<String>,
pub created_at: Option<DateTime<Utc>>,
pub created_at: DateTime<Utc>,
}
impl PostCreateData {
/// Validate and clean post data.
/// Validate and clean post data (only for local posts).
pub fn clean(&mut self, character_limit: usize) -> Result<(), ValidationError> {
assert!(self.object_id.is_none());
if self.content.chars().count() > character_limit {
return Err(ValidationError("post is too long"));
};
@ -275,35 +276,19 @@ mod tests {
const POST_CHARACTER_LIMIT: usize = 1000;
#[test]
fn test_validate_post_data() {
fn test_post_data_empty() {
let mut post_data_1 = PostCreateData {
content: " ".to_string(),
in_reply_to_id: None,
repost_of_id: None,
visibility: Visibility::Public,
attachments: vec![],
mentions: vec![],
tags: vec![],
links: vec![],
object_id: None,
created_at: None,
..Default::default()
};
assert_eq!(post_data_1.clean(POST_CHARACTER_LIMIT).is_ok(), false);
}
#[test]
fn test_trimming() {
fn test_post_data_trimming() {
let mut post_data_2 = PostCreateData {
content: "test ".to_string(),
in_reply_to_id: None,
repost_of_id: None,
visibility: Visibility::Public,
attachments: vec![],
mentions: vec![],
tags: vec![],
links: vec![],
object_id: None,
created_at: None,
..Default::default()
};
assert_eq!(post_data_2.clean(POST_CHARACTER_LIMIT).is_ok(), true);
assert_eq!(post_data_2.content.as_str(), "test");