chore: switch to method chaining over macro
This commit is contained in:
@@ -14,7 +14,6 @@ use futures::{
|
|||||||
FutureExt, SinkExt, StreamExt, TryStreamExt,
|
FutureExt, SinkExt, StreamExt, TryStreamExt,
|
||||||
};
|
};
|
||||||
use redis_kiss::{PayloadType, REDIS_PAYLOAD_TYPE, REDIS_URI};
|
use redis_kiss::{PayloadType, REDIS_PAYLOAD_TYPE, REDIS_URI};
|
||||||
use revolt_config::report_internal_error;
|
|
||||||
use revolt_database::{
|
use revolt_database::{
|
||||||
events::{client::EventV1, server::ClientMessage},
|
events::{client::EventV1, server::ClientMessage},
|
||||||
iso8601_timestamp::Timestamp,
|
iso8601_timestamp::Timestamp,
|
||||||
@@ -27,7 +26,7 @@ use async_std::{
|
|||||||
sync::{Mutex, RwLock},
|
sync::{Mutex, RwLock},
|
||||||
task::spawn,
|
task::spawn,
|
||||||
};
|
};
|
||||||
use revolt_result::create_error;
|
use revolt_result::{create_error, ToRevoltError};
|
||||||
use sentry::Level;
|
use sentry::Level;
|
||||||
|
|
||||||
use crate::config::{ProtocolConfiguration, WebsocketHandshakeCallback};
|
use crate::config::{ProtocolConfiguration, WebsocketHandshakeCallback};
|
||||||
@@ -110,21 +109,21 @@ pub async fn client(db: &'static Database, stream: TcpStream, addr: SocketAddr)
|
|||||||
let user_id = state.cache.user_id.clone();
|
let user_id = state.cache.user_id.clone();
|
||||||
|
|
||||||
// Notify socket we have authenticated.
|
// Notify socket we have authenticated.
|
||||||
if report_internal_error!(write.send(config.encode(&EventV1::Authenticated)).await).is_err() {
|
if write.send(config.encode(&EventV1::Authenticated)).await.to_internal_error().is_err() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Download required data to local cache and send Ready payload.
|
// Download required data to local cache and send Ready payload.
|
||||||
let ready_payload = match report_internal_error!(
|
let ready_payload = match state
|
||||||
state
|
|
||||||
.generate_ready_payload(db, config.get_ready_payload_fields())
|
.generate_ready_payload(db, config.get_ready_payload_fields())
|
||||||
.await
|
.await
|
||||||
) {
|
.to_internal_error()
|
||||||
|
{
|
||||||
Ok(ready_payload) => ready_payload,
|
Ok(ready_payload) => ready_payload,
|
||||||
Err(_) => return,
|
Err(_) => return,
|
||||||
};
|
};
|
||||||
|
|
||||||
if report_internal_error!(write.send(config.encode(&ready_payload)).await).is_err() {
|
if write.send(config.encode(&ready_payload)).await.to_internal_error().is_err() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -219,14 +218,15 @@ async fn listener(
|
|||||||
write: &Mutex<WsWriter>,
|
write: &Mutex<WsWriter>,
|
||||||
) {
|
) {
|
||||||
let redis_config = RedisConfig::from_url(&REDIS_URI).unwrap();
|
let redis_config = RedisConfig::from_url(&REDIS_URI).unwrap();
|
||||||
let subscriber = match report_internal_error!(
|
let subscriber = match fred::types::Builder::from_config(redis_config)
|
||||||
fred::types::Builder::from_config(redis_config).build_subscriber_client()
|
.build_subscriber_client()
|
||||||
) {
|
.to_internal_error()
|
||||||
|
{
|
||||||
Ok(subscriber) => subscriber,
|
Ok(subscriber) => subscriber,
|
||||||
Err(_) => return,
|
Err(_) => return,
|
||||||
};
|
};
|
||||||
|
|
||||||
if report_internal_error!(subscriber.init().await).is_err() {
|
if subscriber.init().await.to_internal_error().is_err() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -249,13 +249,13 @@ async fn listener(
|
|||||||
// Check for state changes for subscriptions.
|
// Check for state changes for subscriptions.
|
||||||
match state.apply_state().await {
|
match state.apply_state().await {
|
||||||
SubscriptionStateChange::Reset => {
|
SubscriptionStateChange::Reset => {
|
||||||
if report_internal_error!(subscriber.unsubscribe_all().await).is_err() {
|
if subscriber.unsubscribe_all().await.to_internal_error().is_err() {
|
||||||
break 'out;
|
break 'out;
|
||||||
}
|
}
|
||||||
|
|
||||||
let subscribed = state.subscribed.read().await;
|
let subscribed = state.subscribed.read().await;
|
||||||
for id in subscribed.iter() {
|
for id in subscribed.iter() {
|
||||||
if report_internal_error!(subscriber.subscribe(id).await).is_err() {
|
if subscriber.subscribe(id).await.to_internal_error().is_err() {
|
||||||
break 'out;
|
break 'out;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -268,7 +268,7 @@ async fn listener(
|
|||||||
#[cfg(debug_assertions)]
|
#[cfg(debug_assertions)]
|
||||||
info!("{addr:?} unsubscribing from {id}");
|
info!("{addr:?} unsubscribing from {id}");
|
||||||
|
|
||||||
if report_internal_error!(subscriber.unsubscribe(id).await).is_err() {
|
if subscriber.unsubscribe(id).await.to_internal_error().is_err() {
|
||||||
break 'out;
|
break 'out;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -277,7 +277,7 @@ async fn listener(
|
|||||||
#[cfg(debug_assertions)]
|
#[cfg(debug_assertions)]
|
||||||
info!("{addr:?} subscribing to {id}");
|
info!("{addr:?} subscribing to {id}");
|
||||||
|
|
||||||
if report_internal_error!(subscriber.subscribe(id).await).is_err() {
|
if subscriber.subscribe(id).await.to_internal_error().is_err() {
|
||||||
break 'out;
|
break 'out;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -302,7 +302,7 @@ async fn listener(
|
|||||||
_ = t2 => {},
|
_ = t2 => {},
|
||||||
message = t1 => {
|
message = t1 => {
|
||||||
// Handle incoming events.
|
// Handle incoming events.
|
||||||
let message = match report_internal_error!(message) {
|
let message = match message.to_internal_error() {
|
||||||
Ok(message) => message,
|
Ok(message) => message,
|
||||||
Err(_) => break 'out
|
Err(_) => break 'out
|
||||||
};
|
};
|
||||||
@@ -311,15 +311,15 @@ async fn listener(
|
|||||||
PayloadType::Json => message
|
PayloadType::Json => message
|
||||||
.value
|
.value
|
||||||
.as_str()
|
.as_str()
|
||||||
.and_then(|s| report_internal_error!(serde_json::from_str::<EventV1>(s.as_ref())).ok()),
|
.and_then(|s| serde_json::from_str::<EventV1>(s.as_ref()).to_internal_error().ok()),
|
||||||
PayloadType::Msgpack => message
|
PayloadType::Msgpack => message
|
||||||
.value
|
.value
|
||||||
.as_bytes()
|
.as_bytes()
|
||||||
.and_then(|b| report_internal_error!(rmp_serde::from_slice::<EventV1>(b)).ok()),
|
.and_then(|b| rmp_serde::from_slice::<EventV1>(b).to_internal_error().ok()),
|
||||||
PayloadType::Bincode => message
|
PayloadType::Bincode => message
|
||||||
.value
|
.value
|
||||||
.as_bytes()
|
.as_bytes()
|
||||||
.and_then(|b| report_internal_error!(bincode::deserialize::<EventV1>(b)).ok()),
|
.and_then(|b| bincode::deserialize::<EventV1>(b).to_internal_error().ok()),
|
||||||
};
|
};
|
||||||
|
|
||||||
let Some(mut event) = event else {
|
let Some(mut event) = event else {
|
||||||
@@ -379,7 +379,7 @@ async fn listener(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
report_internal_error!(subscriber.quit().await).ok();
|
subscriber.quit().await.to_internal_error().ok();
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(clippy::too_many_arguments)]
|
#[allow(clippy::too_many_arguments)]
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
use bson::to_document;
|
use bson::to_document;
|
||||||
use bson::Document;
|
use bson::Document;
|
||||||
use revolt_config::report_internal_error;
|
|
||||||
use revolt_result::Result;
|
use revolt_result::Result;
|
||||||
|
use revolt_result::ToRevoltError;
|
||||||
|
|
||||||
use crate::File;
|
use crate::File;
|
||||||
use crate::FileUsedFor;
|
use crate::FileUsedFor;
|
||||||
@@ -106,7 +106,7 @@ impl AbstractAttachments for MongoDb {
|
|||||||
},
|
},
|
||||||
doc! {
|
doc! {
|
||||||
"$set": {
|
"$set": {
|
||||||
"used_for": report_internal_error!(to_document(&used_for))?,
|
"used_for": to_document(&used_for).to_internal_error()?,
|
||||||
"uploader_id": uploader_id
|
"uploader_id": uploader_id
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -55,13 +55,12 @@ pub async fn fetch_from_s3(bucket_id: &str, path: &str, nonce: &str) -> Result<V
|
|||||||
|
|
||||||
// Send a request for the file
|
// Send a request for the file
|
||||||
let mut obj =
|
let mut obj =
|
||||||
report_internal_error!(client.get_object().bucket(bucket_id).key(path).send().await)?;
|
client.get_object().bucket(bucket_id).key(path).send().await.to_internal_error()?;
|
||||||
|
|
||||||
// Read the file from remote
|
// Read the file from remote
|
||||||
let mut buf = vec![];
|
let mut buf = vec![];
|
||||||
while let Some(bytes) = obj.body.next().await {
|
while let Some(bytes) = obj.body.next().await {
|
||||||
let data = report_internal_error!(bytes)?;
|
buf.write_all(&bytes.to_internal_error()?).to_internal_error()?;
|
||||||
report_internal_error!(buf.write_all(&data))?;
|
|
||||||
// is there a more efficient way to do this?
|
// is there a more efficient way to do this?
|
||||||
// we just want the Vec<u8>
|
// we just want the Vec<u8>
|
||||||
}
|
}
|
||||||
@@ -100,15 +99,14 @@ pub async fn upload_to_s3(bucket_id: &str, path: &str, buf: &[u8]) -> Result<Str
|
|||||||
.to_internal_error()?;
|
.to_internal_error()?;
|
||||||
|
|
||||||
// Upload the file to remote
|
// Upload the file to remote
|
||||||
report_internal_error!(
|
client
|
||||||
client
|
.put_object()
|
||||||
.put_object()
|
.bucket(bucket_id)
|
||||||
.bucket(bucket_id)
|
.key(path)
|
||||||
.key(path)
|
.body(buf.into())
|
||||||
.body(buf.into())
|
.send()
|
||||||
.send()
|
.await
|
||||||
.await
|
.to_internal_error()?;
|
||||||
)?;
|
|
||||||
|
|
||||||
Ok(BASE64_STANDARD.encode(nonce))
|
Ok(BASE64_STANDARD.encode(nonce))
|
||||||
}
|
}
|
||||||
@@ -118,14 +116,13 @@ pub async fn delete_from_s3(bucket_id: &str, path: &str) -> Result<()> {
|
|||||||
let config = config().await;
|
let config = config().await;
|
||||||
let client = create_client(config.files.s3);
|
let client = create_client(config.files.s3);
|
||||||
|
|
||||||
report_internal_error!(
|
client
|
||||||
client
|
.delete_object()
|
||||||
.delete_object()
|
.bucket(bucket_id)
|
||||||
.bucket(bucket_id)
|
.key(path)
|
||||||
.key(path)
|
.send()
|
||||||
.send()
|
.await
|
||||||
.await
|
.to_internal_error()?;
|
||||||
)?;
|
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@@ -145,8 +142,7 @@ pub fn image_size(f: &NamedTempFile) -> Option<(usize, usize)> {
|
|||||||
pub fn image_size_vec(v: &[u8], mime: &str) -> Option<(usize, usize)> {
|
pub fn image_size_vec(v: &[u8], mime: &str) -> Option<(usize, usize)> {
|
||||||
match mime {
|
match mime {
|
||||||
"image/svg+xml" => {
|
"image/svg+xml" => {
|
||||||
let tree =
|
let tree = usvg::Tree::from_data(v, &Default::default()).to_internal_error().ok()?;
|
||||||
report_internal_error!(usvg::Tree::from_data(v, &Default::default())).ok()?;
|
|
||||||
|
|
||||||
let size = tree.size();
|
let size = tree.size();
|
||||||
Some((size.width() as usize, size.height() as usize))
|
Some((size.width() as usize, size.height() as usize))
|
||||||
@@ -221,9 +217,9 @@ pub fn decode_image<R: Read + BufRead + Seek>(reader: &mut R, mime: &str) -> Res
|
|||||||
"image/svg+xml" => {
|
"image/svg+xml" => {
|
||||||
// usvg doesn't support Read trait so copy to buffer
|
// usvg doesn't support Read trait so copy to buffer
|
||||||
let mut buf = Vec::new();
|
let mut buf = Vec::new();
|
||||||
report_internal_error!(reader.read_to_end(&mut buf))?;
|
reader.read_to_end(&mut buf).to_internal_error()?;
|
||||||
|
|
||||||
let tree = report_internal_error!(usvg::Tree::from_data(&buf, &Default::default()))?;
|
let tree = usvg::Tree::from_data(&buf, &Default::default()).to_internal_error()?;
|
||||||
let size = tree.size();
|
let size = tree.size();
|
||||||
let mut pixmap = Pixmap::new(size.width() as u32, size.height() as u32)
|
let mut pixmap = Pixmap::new(size.width() as u32, size.height() as u32)
|
||||||
.ok_or_else(|| create_error!(ImageProcessingFailed))?;
|
.ok_or_else(|| create_error!(ImageProcessingFailed))?;
|
||||||
@@ -241,10 +237,11 @@ pub fn decode_image<R: Read + BufRead + Seek>(reader: &mut R, mime: &str) -> Res
|
|||||||
))
|
))
|
||||||
}
|
}
|
||||||
// Check if we can read using image-rs crate
|
// Check if we can read using image-rs crate
|
||||||
_ => report_internal_error!(report_internal_error!(
|
_ => image::ImageReader::new(reader)
|
||||||
image::ImageReader::new(reader).with_guessed_format()
|
.with_guessed_format()
|
||||||
)?
|
.to_internal_error()?
|
||||||
.decode()),
|
.decode()
|
||||||
|
.to_internal_error()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -12,12 +12,12 @@ use axum::{
|
|||||||
};
|
};
|
||||||
use axum_typed_multipart::{FieldData, TryFromMultipart, TypedMultipart};
|
use axum_typed_multipart::{FieldData, TryFromMultipart, TypedMultipart};
|
||||||
use lazy_static::lazy_static;
|
use lazy_static::lazy_static;
|
||||||
use revolt_config::{config, report_internal_error};
|
use revolt_config::config;
|
||||||
use revolt_database::{iso8601_timestamp::Timestamp, Database, FileHash, Metadata, User};
|
use revolt_database::{iso8601_timestamp::Timestamp, Database, FileHash, Metadata, User};
|
||||||
use revolt_files::{
|
use revolt_files::{
|
||||||
create_thumbnail, decode_image, fetch_from_s3, upload_to_s3, AUTHENTICATION_TAG_SIZE_BYTES,
|
create_thumbnail, decode_image, fetch_from_s3, upload_to_s3, AUTHENTICATION_TAG_SIZE_BYTES,
|
||||||
};
|
};
|
||||||
use revolt_result::{create_error, Error, Result};
|
use revolt_result::{create_error, Error, Result, ToRevoltError};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use sha2::Digest;
|
use sha2::Digest;
|
||||||
use tempfile::NamedTempFile;
|
use tempfile::NamedTempFile;
|
||||||
@@ -181,7 +181,7 @@ async fn upload_file(
|
|||||||
|
|
||||||
// Load file to memory
|
// Load file to memory
|
||||||
let mut buf = Vec::<u8>::new();
|
let mut buf = Vec::<u8>::new();
|
||||||
report_internal_error!(file.contents.read_to_end(&mut buf))?;
|
file.contents.read_to_end(&mut buf).to_internal_error()?;
|
||||||
|
|
||||||
// Take note of original file size
|
// Take note of original file size
|
||||||
let original_file_size = buf.len();
|
let original_file_size = buf.len();
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
|
||||||
use revolt_config::{config, report_internal_error};
|
use revolt_config::config;
|
||||||
use revolt_result::Result;
|
use revolt_result::{Result, ToRevoltError};
|
||||||
|
|
||||||
/// Initialise ClamAV
|
/// Initialise ClamAV
|
||||||
pub async fn init() {
|
pub async fn init() {
|
||||||
@@ -38,12 +38,12 @@ pub async fn is_malware(buf: &[u8]) -> Result<bool> {
|
|||||||
if config.files.clamd_host.is_empty() {
|
if config.files.clamd_host.is_empty() {
|
||||||
Ok(false)
|
Ok(false)
|
||||||
} else {
|
} else {
|
||||||
let scan_response = report_internal_error!(revolt_clamav_client::scan_buffer_tcp(
|
let scan_response =
|
||||||
buf,
|
revolt_clamav_client::scan_buffer_tcp(buf, config.files.clamd_host, None)
|
||||||
config.files.clamd_host,
|
.to_internal_error()?;
|
||||||
None
|
|
||||||
))?;
|
|
||||||
|
|
||||||
report_internal_error!(revolt_clamav_client::clean(&scan_response)).map(|v| !v)
|
revolt_clamav_client::clean(&scan_response)
|
||||||
|
.to_internal_error()
|
||||||
|
.map(|v| !v)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,9 +2,8 @@ use std::io::{Cursor, Read};
|
|||||||
|
|
||||||
use exif::Reader;
|
use exif::Reader;
|
||||||
use image::{ImageFormat, ImageReader};
|
use image::{ImageFormat, ImageReader};
|
||||||
use revolt_config::report_internal_error;
|
|
||||||
use revolt_database::Metadata;
|
use revolt_database::Metadata;
|
||||||
use revolt_result::{create_error, Result};
|
use revolt_result::{create_error, Result, ToRevoltError};
|
||||||
use tempfile::NamedTempFile;
|
use tempfile::NamedTempFile;
|
||||||
use tokio::process::Command;
|
use tokio::process::Command;
|
||||||
|
|
||||||
@@ -41,11 +40,11 @@ pub async fn strip_metadata(
|
|||||||
let mut cursor = Cursor::new(buf);
|
let mut cursor = Cursor::new(buf);
|
||||||
|
|
||||||
// Decode the image
|
// Decode the image
|
||||||
let image = report_internal_error!(report_internal_error!(ImageReader::new(
|
let image = ImageReader::new(&mut cursor)
|
||||||
&mut cursor
|
.with_guessed_format()
|
||||||
)
|
.to_internal_error()?
|
||||||
.with_guessed_format())?
|
.decode()
|
||||||
.decode());
|
.to_internal_error()?;
|
||||||
|
|
||||||
// Reset read position
|
// Reset read position
|
||||||
cursor.set_position(0);
|
cursor.set_position(0);
|
||||||
@@ -66,15 +65,15 @@ pub async fn strip_metadata(
|
|||||||
|
|
||||||
// Apply the EXIF rotation
|
// Apply the EXIF rotation
|
||||||
// See https://jdhao.github.io/2019/07/31/image_rotation_exif_info/
|
// See https://jdhao.github.io/2019/07/31/image_rotation_exif_info/
|
||||||
report_internal_error!(match &rotation {
|
match &rotation {
|
||||||
2 => image?.fliph(),
|
2 => image.fliph(),
|
||||||
3 => image?.rotate180(),
|
3 => image.rotate180(),
|
||||||
4 => image?.rotate180().fliph(),
|
4 => image.rotate180().fliph(),
|
||||||
5 => image?.rotate90().fliph(),
|
5 => image.rotate90().fliph(),
|
||||||
6 => image?.rotate90(),
|
6 => image.rotate90(),
|
||||||
7 => image?.rotate270().fliph(),
|
7 => image.rotate270().fliph(),
|
||||||
8 => image?.rotate270(),
|
8 => image.rotate270(),
|
||||||
_ => image?,
|
_ => image,
|
||||||
}
|
}
|
||||||
.write_to(
|
.write_to(
|
||||||
&mut writer,
|
&mut writer,
|
||||||
@@ -85,7 +84,7 @@ pub async fn strip_metadata(
|
|||||||
"image/tiff" => ImageFormat::Tiff,
|
"image/tiff" => ImageFormat::Tiff,
|
||||||
_ => todo!(),
|
_ => todo!(),
|
||||||
},
|
},
|
||||||
))?;
|
).to_internal_error()?;
|
||||||
|
|
||||||
// Calculate dimensions after rotation.
|
// Calculate dimensions after rotation.
|
||||||
let (width, height) = match &rotation {
|
let (width, height) = match &rotation {
|
||||||
@@ -113,44 +112,43 @@ pub async fn strip_metadata(
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Temporary output file
|
// Temporary output file
|
||||||
let mut out_file = report_internal_error!(NamedTempFile::new())?;
|
let mut out_file = NamedTempFile::new().to_internal_error()?;
|
||||||
|
|
||||||
// Process the file with ffmpeg
|
// Process the file with ffmpeg
|
||||||
report_internal_error!(
|
Command::new("ffmpeg")
|
||||||
Command::new("ffmpeg")
|
.args([
|
||||||
.args([
|
// Overwrite the temporary file
|
||||||
// Overwrite the temporary file
|
"-y",
|
||||||
"-y",
|
// Read original uploaded file
|
||||||
// Read original uploaded file
|
"-i",
|
||||||
"-i",
|
file.path().to_str().ok_or(create_error!(InternalError))?,
|
||||||
file.path().to_str().ok_or(create_error!(InternalError))?,
|
// Strip any metadata
|
||||||
// Strip any metadata
|
"-map_metadata",
|
||||||
"-map_metadata",
|
"-1",
|
||||||
"-1",
|
// Copy video / audio data to new file
|
||||||
// Copy video / audio data to new file
|
"-c:v",
|
||||||
"-c:v",
|
"copy",
|
||||||
"copy",
|
"-c:a",
|
||||||
"-c:a",
|
"copy",
|
||||||
"copy",
|
// Select correct file format
|
||||||
// Select correct file format
|
"-f",
|
||||||
"-f",
|
ext,
|
||||||
ext,
|
// Save to new temporary file
|
||||||
// Save to new temporary file
|
out_file
|
||||||
out_file
|
.path()
|
||||||
.path()
|
.to_str()
|
||||||
.to_str()
|
.ok_or(create_error!(InternalError))?,
|
||||||
.ok_or(create_error!(InternalError))?,
|
])
|
||||||
])
|
.output()
|
||||||
.output()
|
.await
|
||||||
.await
|
.to_internal_error()?;
|
||||||
)?;
|
|
||||||
|
|
||||||
// Probe the file again
|
// Probe the file again
|
||||||
let metadata = crate::metadata::generate_metadata(&out_file, mime);
|
let metadata = crate::metadata::generate_metadata(&out_file, mime);
|
||||||
|
|
||||||
// Read the file from disk
|
// Read the file from disk
|
||||||
let mut buf = Vec::<u8>::new();
|
let mut buf = Vec::<u8>::new();
|
||||||
report_internal_error!(out_file.read_to_end(&mut buf))?;
|
out_file.read_to_end(&mut buf).to_internal_error()?;
|
||||||
|
|
||||||
Ok((buf, metadata))
|
Ok((buf, metadata))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,10 +6,9 @@ use reqwest::{
|
|||||||
header::{self, CONTENT_TYPE},
|
header::{self, CONTENT_TYPE},
|
||||||
redirect, Client, Response,
|
redirect, Client, Response,
|
||||||
};
|
};
|
||||||
use revolt_config::report_internal_error;
|
|
||||||
use revolt_files::{create_thumbnail, decode_image, image_size_vec, is_valid_image, video_size};
|
use revolt_files::{create_thumbnail, decode_image, image_size_vec, is_valid_image, video_size};
|
||||||
use revolt_models::v0::{Embed, Image, ImageSize, Video};
|
use revolt_models::v0::{Embed, Image, ImageSize, Video};
|
||||||
use revolt_result::{create_error, Error, Result};
|
use revolt_result::{create_error, Error, Result, ToRevoltError};
|
||||||
use std::{
|
use std::{
|
||||||
io::{Cursor, Write},
|
io::{Cursor, Write},
|
||||||
time::Duration,
|
time::Duration,
|
||||||
@@ -76,7 +75,7 @@ impl Request {
|
|||||||
let Request { response, mime } = Request::new(url).await?;
|
let Request { response, mime } = Request::new(url).await?;
|
||||||
|
|
||||||
if matches!(mime.type_(), mime::IMAGE | mime::VIDEO) {
|
if matches!(mime.type_(), mime::IMAGE | mime::VIDEO) {
|
||||||
let bytes = report_internal_error!(response.bytes().await);
|
let bytes = response.bytes().await.to_internal_error();
|
||||||
|
|
||||||
let result = match bytes {
|
let result = match bytes {
|
||||||
Ok(bytes) => {
|
Ok(bytes) => {
|
||||||
@@ -100,8 +99,8 @@ impl Request {
|
|||||||
))
|
))
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
let mut file = report_internal_error!(tempfile::NamedTempFile::new())?;
|
let mut file = tempfile::NamedTempFile::new().to_internal_error()?;
|
||||||
report_internal_error!(file.write_all(&bytes))?;
|
file.write_all(&bytes).to_internal_error()?;
|
||||||
|
|
||||||
if video_size(&file).is_some() {
|
if video_size(&file).is_some() {
|
||||||
Ok((mime.to_string(), bytes.to_vec()))
|
Ok((mime.to_string(), bytes.to_vec()))
|
||||||
@@ -144,7 +143,7 @@ impl Request {
|
|||||||
};
|
};
|
||||||
|
|
||||||
if let Some((width, height)) = image_size_vec(
|
if let Some((width, height)) = image_size_vec(
|
||||||
&report_internal_error!(request.response.bytes().await)?,
|
&request.response.bytes().await.to_internal_error()?,
|
||||||
request.mime.as_ref(),
|
request.mime.as_ref(),
|
||||||
) {
|
) {
|
||||||
Ok(Some(Image {
|
Ok(Some(Image {
|
||||||
@@ -181,10 +180,9 @@ impl Request {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut file = report_internal_error!(tempfile::NamedTempFile::new())?;
|
let mut file = tempfile::NamedTempFile::new().to_internal_error()?;
|
||||||
report_internal_error!(
|
file.write_all(&response.bytes().await.to_internal_error()?)
|
||||||
file.write_all(&report_internal_error!(response.bytes().await)?)
|
.to_internal_error()?;
|
||||||
)?;
|
|
||||||
|
|
||||||
if let Some((width, height)) = video_size(&file) {
|
if let Some((width, height)) = video_size(&file) {
|
||||||
Ok(Some(Video {
|
Ok(Some(Video {
|
||||||
@@ -230,7 +228,7 @@ impl Request {
|
|||||||
let encoding =
|
let encoding =
|
||||||
Encoding::for_label(encoding_name.as_bytes()).unwrap_or(&UTF_8_INIT);
|
Encoding::for_label(encoding_name.as_bytes()).unwrap_or(&UTF_8_INIT);
|
||||||
|
|
||||||
let bytes = report_internal_error!(request.response.bytes().await)?;
|
let bytes = request.response.bytes().await.to_internal_error()?;
|
||||||
let (text, _, _) = encoding.decode(&bytes);
|
let (text, _, _) = encoding.decode(&bytes);
|
||||||
|
|
||||||
crate::website_embed::create_website_embed(&url, &text)
|
crate::website_embed::create_website_embed(&url, &text)
|
||||||
|
|||||||
Reference in New Issue
Block a user