155 lines
3.9 KiB
Rust
155 lines
3.9 KiB
Rust
use crate::api::models::{AlbumQuery, ImageQuery, ImageSort, PicOxError};
|
|
use crate::model::album::Album;
|
|
use chrono::{DateTime, Utc};
|
|
use j_db::database::Database;
|
|
use j_db::model::JdbModel;
|
|
use rand::prelude::SliceRandom;
|
|
use rand::thread_rng;
|
|
use serde::{Deserialize, Serialize};
|
|
use std::path::PathBuf;
|
|
use url::Url;
|
|
|
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
pub enum StorageLocation {
|
|
FileStore { path: PathBuf },
|
|
Link,
|
|
}
|
|
|
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
pub struct Image {
|
|
pub filename: String,
|
|
pub tags: Vec<String>,
|
|
pub create_date: DateTime<Utc>,
|
|
pub link: Url,
|
|
pub created_by: u64,
|
|
pub storage_location: StorageLocation,
|
|
pub album: u64,
|
|
|
|
id: Option<u64>,
|
|
}
|
|
|
|
impl Image {
|
|
pub fn new(
|
|
filename: &str,
|
|
tags: Vec<String>,
|
|
link: Url,
|
|
created_by: u64,
|
|
storage_location: StorageLocation,
|
|
album: u64,
|
|
) -> Self {
|
|
Self {
|
|
filename: filename.to_string(),
|
|
tags,
|
|
create_date: Utc::now(),
|
|
link,
|
|
created_by,
|
|
storage_location,
|
|
album,
|
|
id: None,
|
|
}
|
|
}
|
|
|
|
pub fn query_image(db: &Database, image_query: &ImageQuery) -> Result<Vec<Self>, PicOxError> {
|
|
let album_id = if let Some(album) = &image_query.album {
|
|
Some(
|
|
Album::find_album_by_query(
|
|
db,
|
|
AlbumQuery {
|
|
album_name: Some(album.to_string()),
|
|
},
|
|
)
|
|
.first()
|
|
.ok_or(PicOxError::AlbumNotFound)?
|
|
.id()
|
|
.unwrap(),
|
|
)
|
|
} else {
|
|
None
|
|
};
|
|
|
|
let mut images: Vec<Image> = db
|
|
.filter(|_, img: &Image| {
|
|
if let Some(album_id) = album_id {
|
|
if img.album != album_id {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
if !image_query.image_type.is_empty() {
|
|
let path = img.link.to_file_path().unwrap();
|
|
let ext = path.extension().unwrap().to_str().unwrap();
|
|
|
|
if !image_query.image_type.contains(&ext.to_string())
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
|
|
if !image_query.tags.is_empty() {
|
|
let mut found = false;
|
|
for tag in &image_query.tags {
|
|
if img.tags.contains(tag) {
|
|
found = true;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if !found {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
true
|
|
})?
|
|
.collect();
|
|
|
|
match image_query.order {
|
|
ImageSort::Random => {
|
|
images.shuffle(&mut thread_rng());
|
|
}
|
|
ImageSort::DateAscending => {
|
|
images.sort_by(|img_a, img_b| img_a.create_date.cmp(&img_b.create_date))
|
|
}
|
|
ImageSort::DateDescending => {
|
|
images.sort_by(|img_a, img_b| img_b.create_date.cmp(&img_a.create_date))
|
|
}
|
|
ImageSort::None => {}
|
|
}
|
|
|
|
if images.len() > image_query.limit {
|
|
images.drain(image_query.limit..);
|
|
}
|
|
|
|
Ok(images)
|
|
}
|
|
}
|
|
|
|
impl j_db::model::JdbModel for Image {
|
|
fn id(&self) -> Option<u64> {
|
|
self.id
|
|
}
|
|
|
|
fn set_id(&mut self, id: u64) {
|
|
self.id = Some(id)
|
|
}
|
|
|
|
fn tree() -> String {
|
|
"Image".to_string()
|
|
}
|
|
}
|
|
|
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
pub enum ImageData {
|
|
Bytes(Vec<u8>),
|
|
Link(String),
|
|
}
|
|
|
|
impl ImageData {
|
|
pub fn size(&self) -> usize {
|
|
match self {
|
|
ImageData::Bytes(data) => data.len(),
|
|
ImageData::Link(_) => 0,
|
|
}
|
|
}
|
|
}
|