add: drawings in questions

This commit is contained in:
trisua 2025-06-20 17:40:55 -04:00
parent 6be729de50
commit 16843a6ab8
28 changed files with 1181 additions and 32 deletions

View file

@ -2,6 +2,7 @@ use std::collections::HashMap;
use oiseau::cache::Cache;
use tetratto_shared::unix_epoch_timestamp;
use crate::model::communities_permissions::CommunityPermission;
use crate::model::uploads::{MediaType, MediaUpload};
use crate::model::{
Error, Result,
communities::Question,
@ -33,6 +34,7 @@ impl DataManager {
// ...
context: serde_json::from_str(&get!(x->10(String))).unwrap(),
ip: get!(x->11(String)),
drawings: serde_json::from_str(&get!(x->12(String))).unwrap(),
}
}
@ -333,13 +335,20 @@ impl DataManager {
Ok(res.unwrap())
}
const MAXIMUM_DRAWING_SIZE: usize = 32768; // 32 KiB
/// Create a new question in the database.
///
/// # Arguments
/// * `data` - a mock [`Question`] object to insert
pub async fn create_question(&self, mut data: Question) -> Result<usize> {
pub async fn create_question(
&self,
mut data: Question,
drawings: Vec<Vec<u8>>,
) -> Result<usize> {
// check if we can post this
if data.is_global {
// global
if data.community > 0 {
// posting to community
data.receiver = 0;
@ -370,6 +379,7 @@ impl DataManager {
}
}
} else {
// single
let receiver = self.get_user_by_id(data.receiver).await?;
if !receiver.settings.enable_questions {
@ -380,6 +390,10 @@ impl DataManager {
return Err(Error::NotAllowed);
}
if !receiver.settings.enable_drawings && drawings.len() > 0 {
return Err(Error::DrawingsDisabled);
}
// check for ip block
if self
.get_ipblock_by_initiator_receiver(receiver.id, &data.ip)
@ -390,6 +404,28 @@ impl DataManager {
}
}
// create uploads
if drawings.len() > 2 {
return Err(Error::MiscError(
"Too many uploads. Please use a maximum of 2".to_string(),
));
}
for drawing in &drawings {
// this is the initial iter to check sizes, we'll do uploads after
if drawing.len() > Self::MAXIMUM_DRAWING_SIZE {
return Err(Error::FileTooLarge);
}
}
for _ in 0..drawings.len() {
data.drawings.push(
self.create_upload(MediaUpload::new(MediaType::Carpgraph, data.owner))
.await?
.id,
);
}
// ...
let conn = match self.0.connect().await {
Ok(c) => c,
@ -398,7 +434,7 @@ impl DataManager {
let res = execute!(
&conn,
"INSERT INTO questions VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12)",
"INSERT INTO questions VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13)",
params![
&(data.id as i64),
&(data.created as i64),
@ -411,7 +447,8 @@ impl DataManager {
&0_i32,
&0_i32,
&serde_json::to_string(&data.context).unwrap(),
&data.ip
&data.ip,
&serde_json::to_string(&data.drawings).unwrap(),
]
);
@ -430,6 +467,23 @@ impl DataManager {
.await?;
}
// write to uploads
for (i, drawing_id) in data.drawings.iter().enumerate() {
let drawing = match drawings.get(i) {
Some(d) => d,
None => {
self.delete_upload(*drawing_id).await?;
continue;
}
};
let upload = self.get_upload_by_id(*drawing_id).await?;
if let Err(e) = std::fs::write(&upload.path(&self.0.0).to_string(), drawing.to_vec()) {
return Err(Error::MiscError(e.to_string()));
}
}
// return
Ok(data.id)
}
@ -495,6 +549,11 @@ impl DataManager {
return Err(Error::DatabaseError(e.to_string()));
}
// delete uploads
for upload in y.drawings {
self.delete_upload(upload).await?;
}
// return
Ok(())
}