| 
						
					 | 
				
			
			 | 
			 | 
			
				@@ -2,10 +2,14 @@ use std::{
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    collections::{BTreeSet, HashMap},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    fs::File,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    io::{Read, Write},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    num::NonZeroU32,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    ops::DerefMut,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    sync::atomic::Ordering
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				};
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				use image::DynamicImage;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				use fast_image_resize as fir;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				use fast_image_resize::PixelType;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				use rustracing_jaeger::Span;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				use tiny_http::{Request, Response, ResponseBox, StatusCode};
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
	
		
			
				
					
					| 
						
					 | 
				
			
			 | 
			 | 
			
				@@ -15,7 +19,7 @@ use crate::{
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    dto,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    header,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    metrics,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    routes::{filters::UserInfo, get_reply, AppError, ChannelReader}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    routes::{filters::UserInfo, fs::resize_dimensions, get_reply, AppError, ChannelReader}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				};
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				pub fn root(_: &Span, _: &mut Request, _: &mut DBConnection, info: UserInfo) -> Result<ResponseBox, AppError> {
 | 
			
		
		
	
	
		
			
				
					
					| 
						
					 | 
				
			
			 | 
			 | 
			
				@@ -164,6 +168,7 @@ pub fn upload(
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    let mut file_size = 0_i64;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    let file_name = format!("./files/{}", node.id);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    let mut file_buf = Vec::<u8>::new();
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        let _span = metrics::span("receive_file", span);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        let mut buf = vec![0_u8; 8 * 1024 * 1024];
 | 
			
		
		
	
	
		
			
				
					
					| 
						
					 | 
				
			
			 | 
			 | 
			
				@@ -176,6 +181,9 @@ pub fn upload(
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            if r == 0 {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                break;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            if file_size < 20 * 1024 * 1024 {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                file_buf.write_all(&buf[..r]).unwrap();
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            file.write_all(&buf[..r]).unwrap();
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            file_size += r as i64;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        }
 | 
			
		
		
	
	
		
			
				
					
					| 
						
					 | 
				
			
			 | 
			 | 
			
				@@ -185,19 +193,73 @@ pub fn upload(
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        .with_label_values(&[node.owner_id.to_string().as_str()])
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        .add(file_size - node.size.unwrap_or(0));
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        let _span = metrics::span("generate_preview", span);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        let prev_span = metrics::span("generate_preview", span);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        node.has_preview = (|| {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            if file_size > 20 * 1024 * 1024 {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            if file_size > file_buf.len() as i64 {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                return None;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            let mime = mime_guess::from_path(std::path::Path::new(&node.name)).first()?.to_string();
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            let img = image::load(
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                std::io::BufReader::new(File::open(file_name.clone()).unwrap()),
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                image::ImageFormat::from_mime_type(mime)?
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            )
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            .ok()?;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            let img = img.resize(300, 300, image::imageops::FilterType::Triangle);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            img.save(std::path::Path::new(&(file_name + "_preview.jpg"))).expect("Failed to save preview image");
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            let img = {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                let _span = metrics::span("generate_preview_load", &prev_span);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                image::load_from_memory_with_format(
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                    file_buf.as_slice(),
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                    image::ImageFormat::from_mime_type(mime)?
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                )
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                .ok()?
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            };
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            let img = {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                let _span = metrics::span("generate_preview_convert", &prev_span);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                let width = NonZeroU32::try_from(img.width()).unwrap();
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                let height = NonZeroU32::try_from(img.height()).unwrap();
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                match img {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                    DynamicImage::ImageLuma8(v) => fir::Image::from_vec_u8(width, height, v.into_raw(), fir::PixelType::U8),
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                    DynamicImage::ImageLumaA8(v) => fir::Image::from_vec_u8(width, height, v.into_raw(), fir::PixelType::U8x2),
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                    DynamicImage::ImageRgb8(v) => fir::Image::from_vec_u8(width, height, v.into_raw(), fir::PixelType::U8x3),
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                    DynamicImage::ImageRgba8(v) => fir::Image::from_vec_u8(width, height, v.into_raw(), fir::PixelType::U8x4),
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                    DynamicImage::ImageLuma16(_) => fir::Image::from_vec_u8(width, height, img.to_luma8().into_raw(), fir::PixelType::U8),
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                    DynamicImage::ImageLumaA16(_) => fir::Image::from_vec_u8(width, height, img.to_luma_alpha8().into_raw(), fir::PixelType::U8x2),
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                    DynamicImage::ImageRgb16(_) => fir::Image::from_vec_u8(width, height, img.to_rgb8().into_raw(), fir::PixelType::U8x3),
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                    DynamicImage::ImageRgba16(_) => fir::Image::from_vec_u8(width, height, img.to_rgba8().into_raw(), fir::PixelType::U8x4),
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                    DynamicImage::ImageRgb32F(_) => fir::Image::from_vec_u8(width, height, img.to_rgb8().into_raw(), fir::PixelType::U8x3),
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                    DynamicImage::ImageRgba32F(_) => fir::Image::from_vec_u8(width, height, img.to_rgba8().into_raw(), fir::PixelType::U8x4),
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                    _ => fir::Image::from_vec_u8(width, height, img.to_rgba8().into_raw(), fir::PixelType::U8x4)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                }.expect("Failed to convert preview image")
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            };
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            let img = {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                let _span = metrics::span("generate_preview_resize", &prev_span);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                let new_dim = resize_dimensions(img.width().get(), img.height().get());
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                let mut dst = fir::Image::new(
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                    NonZeroU32::try_from(new_dim.0).unwrap(),
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                    NonZeroU32::try_from(new_dim.1).unwrap(),
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                    img.pixel_type()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                );
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                fir::Resizer::new(fir::ResizeAlg::SuperSampling(
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                    fir::FilterType::Hamming,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                    2
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                ))
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                .resize(&img.view(), &mut dst.view_mut())
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                .expect("Failed to resize preview image");
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                dst
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            };
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            let _span = metrics::span("generate_preview_save", &prev_span);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            let mut file = std::io::BufWriter::new(
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                File::create(std::path::Path::new(&(file_name + "_preview.jpg")))
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                    .expect("Failed to open preview image file")
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            );
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            image::codecs::jpeg::JpegEncoder::new(&mut file)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                .encode(
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                    img.buffer(),
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                    img.width().get(),
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                    img.height().get(),
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                    match img.pixel_type() {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                        PixelType::U8 => image::ColorType::L8,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                        PixelType::U8x2 => image::ColorType::La8,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                        PixelType::U8x3 => image::ColorType::Rgb8,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                        PixelType::U8x4 => image::ColorType::Rgba8,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                        _ => unreachable!()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                    }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                )
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                .expect("Failed to save preview image");
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            Some(())
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        })()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        .is_some();
 | 
			
		
		
	
	
		
			
				
					
					| 
						
					 | 
				
			
			 | 
			 | 
			
				 
 |