Allow value of "attachment" property to be an object
This commit is contained in:
parent
56d1ebf9e5
commit
0bc3c32fcd
2 changed files with 35 additions and 9 deletions
|
@ -59,7 +59,7 @@ pub struct Object {
|
||||||
pub actor: Option<String>,
|
pub actor: Option<String>,
|
||||||
|
|
||||||
#[serde(skip_serializing_if = "Option::is_none")]
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
pub attachment: Option<Vec<Attachment>>,
|
pub attachment: Option<Value>,
|
||||||
|
|
||||||
#[serde(skip_serializing_if = "Option::is_none")]
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
pub cc: Option<Value>,
|
pub cc: Option<Value>,
|
||||||
|
|
|
@ -2,6 +2,7 @@ use std::collections::HashMap;
|
||||||
|
|
||||||
use actix_web::HttpRequest;
|
use actix_web::HttpRequest;
|
||||||
use regex::Regex;
|
use regex::Regex;
|
||||||
|
use serde::de::DeserializeOwned;
|
||||||
use serde_json::Value;
|
use serde_json::Value;
|
||||||
use tokio_postgres::GenericClient;
|
use tokio_postgres::GenericClient;
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
|
@ -39,7 +40,12 @@ use crate::models::relationships::queries::{
|
||||||
};
|
};
|
||||||
use crate::models::users::queries::get_user_by_name;
|
use crate::models::users::queries::get_user_by_name;
|
||||||
use crate::utils::html::clean_html;
|
use crate::utils::html::clean_html;
|
||||||
use super::activity::{Object, Activity, create_activity_accept_follow};
|
use super::activity::{
|
||||||
|
Activity,
|
||||||
|
Attachment,
|
||||||
|
Object,
|
||||||
|
create_activity_accept_follow,
|
||||||
|
};
|
||||||
use super::actor::Actor;
|
use super::actor::Actor;
|
||||||
use super::deliverer::deliver_activity;
|
use super::deliverer::deliver_activity;
|
||||||
use super::fetcher::fetchers::{
|
use super::fetcher::fetchers::{
|
||||||
|
@ -61,7 +67,7 @@ fn parse_actor_id(
|
||||||
) -> Result<String, ValidationError> {
|
) -> Result<String, ValidationError> {
|
||||||
let url_regexp_str = format!(
|
let url_regexp_str = format!(
|
||||||
"^{}/users/(?P<username>[0-9a-z_]+)$",
|
"^{}/users/(?P<username>[0-9a-z_]+)$",
|
||||||
instance_url.replace(".", r"\."),
|
instance_url.replace('.', r"\."),
|
||||||
);
|
);
|
||||||
let url_regexp = Regex::new(&url_regexp_str)
|
let url_regexp = Regex::new(&url_regexp_str)
|
||||||
.map_err(|_| ValidationError("error"))?;
|
.map_err(|_| ValidationError("error"))?;
|
||||||
|
@ -80,7 +86,7 @@ fn parse_object_id(
|
||||||
) -> Result<Uuid, ValidationError> {
|
) -> Result<Uuid, ValidationError> {
|
||||||
let url_regexp_str = format!(
|
let url_regexp_str = format!(
|
||||||
"^{}/objects/(?P<uuid>[0-9a-f-]+)$",
|
"^{}/objects/(?P<uuid>[0-9a-f-]+)$",
|
||||||
instance_url.replace(".", r"\."),
|
instance_url.replace('.', r"\."),
|
||||||
);
|
);
|
||||||
let url_regexp = Regex::new(&url_regexp_str)
|
let url_regexp = Regex::new(&url_regexp_str)
|
||||||
.map_err(|_| ValidationError("error"))?;
|
.map_err(|_| ValidationError("error"))?;
|
||||||
|
@ -93,6 +99,7 @@ fn parse_object_id(
|
||||||
Ok(internal_object_id)
|
Ok(internal_object_id)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Transforms arbitrary property value into array of strings
|
||||||
fn parse_array(value: &Value) -> Result<Vec<String>, ConversionError> {
|
fn parse_array(value: &Value) -> Result<Vec<String>, ConversionError> {
|
||||||
let result = match value {
|
let result = match value {
|
||||||
Value::String(string) => vec![string.to_string()],
|
Value::String(string) => vec![string.to_string()],
|
||||||
|
@ -121,6 +128,23 @@ fn parse_array(value: &Value) -> Result<Vec<String>, ConversionError> {
|
||||||
Ok(result)
|
Ok(result)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Transforms arbitrary property value into array of structs
|
||||||
|
fn parse_property_value<T: DeserializeOwned>(value: &Value) -> Result<Vec<T>, ConversionError> {
|
||||||
|
let objects = match value {
|
||||||
|
Value::Array(array) => array.to_vec(),
|
||||||
|
Value::Object(_) => vec![value.clone()],
|
||||||
|
// Unexpected value type
|
||||||
|
_ => return Err(ConversionError),
|
||||||
|
};
|
||||||
|
let mut items = vec![];
|
||||||
|
for object in objects {
|
||||||
|
let item: T = serde_json::from_value(object)
|
||||||
|
.map_err(|_| ConversionError)?;
|
||||||
|
items.push(item);
|
||||||
|
};
|
||||||
|
Ok(items)
|
||||||
|
}
|
||||||
|
|
||||||
/// Parses object json value and returns its ID as string
|
/// Parses object json value and returns its ID as string
|
||||||
fn get_object_id(object: Value) -> Result<String, ValidationError> {
|
fn get_object_id(object: Value) -> Result<String, ValidationError> {
|
||||||
let object_id = match object.as_str() {
|
let object_id = match object.as_str() {
|
||||||
|
@ -239,7 +263,9 @@ pub async fn import_post(
|
||||||
.ok_or(ValidationError("no content"))?;
|
.ok_or(ValidationError("no content"))?;
|
||||||
let content_cleaned = clean_note_content(&content)?;
|
let content_cleaned = clean_note_content(&content)?;
|
||||||
let mut attachments: Vec<Uuid> = Vec::new();
|
let mut attachments: Vec<Uuid> = Vec::new();
|
||||||
if let Some(list) = object.attachment {
|
if let Some(value) = object.attachment {
|
||||||
|
let list: Vec<Attachment> = parse_property_value(&value)
|
||||||
|
.map_err(|_| ValidationError("invalid attachment property"))?;
|
||||||
let mut downloaded = vec![];
|
let mut downloaded = vec![];
|
||||||
let output_dir = config.media_dir();
|
let output_dir = config.media_dir();
|
||||||
for attachment in list {
|
for attachment in list {
|
||||||
|
@ -261,7 +287,7 @@ pub async fn import_post(
|
||||||
file_name,
|
file_name,
|
||||||
attachment.media_type.or(media_type),
|
attachment.media_type.or(media_type),
|
||||||
));
|
));
|
||||||
}
|
};
|
||||||
for (file_name, media_type) in downloaded {
|
for (file_name, media_type) in downloaded {
|
||||||
let db_attachment = create_attachment(
|
let db_attachment = create_attachment(
|
||||||
db_client,
|
db_client,
|
||||||
|
@ -270,8 +296,8 @@ pub async fn import_post(
|
||||||
media_type,
|
media_type,
|
||||||
).await?;
|
).await?;
|
||||||
attachments.push(db_attachment.id);
|
attachments.push(db_attachment.id);
|
||||||
}
|
};
|
||||||
}
|
};
|
||||||
let mut mentions: Vec<Uuid> = Vec::new();
|
let mut mentions: Vec<Uuid> = Vec::new();
|
||||||
let mut tags = vec![];
|
let mut tags = vec![];
|
||||||
if let Some(list) = object.tag {
|
if let Some(list) = object.tag {
|
||||||
|
@ -336,7 +362,7 @@ pub async fn import_post(
|
||||||
continue;
|
continue;
|
||||||
},
|
},
|
||||||
Err(other_error) => {
|
Err(other_error) => {
|
||||||
return Err(other_error.into());
|
return Err(other_error);
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
Loading…
Reference in a new issue