green_barrel/fields/
image.rs1use core::fmt::Debug;
4use regex::Regex;
5use serde::{Deserialize, Serialize};
6use std::{error::Error, fs, path::Path};
7use uuid::Uuid;
8
9use crate::models::helpers::ImageData;
10
11#[derive(Serialize, Deserialize, Clone, Debug)]
12pub struct ImageField {
13 pub id: String,
16 pub label: String,
18 pub field_type: String,
20 pub input_type: String,
22 pub name: String,
24 pub value: Option<ImageData>,
26 pub default: Option<ImageData>,
28 pub media_root: String,
30 pub media_url: String,
32 pub target_dir: String,
35 pub accept: String,
37 pub placeholder: String,
39 pub required: bool,
41 pub disabled: bool,
43 pub readonly: bool,
45 pub thumbnails: Vec<(String, u32)>,
49 pub is_quality: bool,
51 pub is_hide: bool,
53 pub other_attrs: String,
55 pub css_classes: String,
57 pub hint: String,
59 pub warning: String,
61 pub errors: Vec<String>,
63 pub group: u32,
66}
67
68impl Default for ImageField {
69 fn default() -> Self {
70 Self {
71 id: String::new(),
72 label: String::new(),
73 field_type: String::from("ImageField"),
74 input_type: String::from("file"),
75 name: String::new(),
76 value: None,
77 default: None,
78 media_root: String::from("./resources/media"),
79 media_url: String::from("/media"),
80 target_dir: String::from("images"),
81 accept: String::new(),
82 placeholder: String::new(),
83 required: false,
84 disabled: false,
85 readonly: false,
86 thumbnails: Vec::new(),
87 is_quality: true,
88 is_hide: false,
89 other_attrs: String::new(),
90 css_classes: String::new(),
91 hint: String::new(),
92 warning: String::new(),
93 errors: Vec::new(),
94 group: 9,
95 }
96 }
97}
98
99impl ImageField {
100 pub fn get(&self) -> Option<ImageData> {
102 self.value.clone()
103 }
104 pub fn set(&mut self, image_path: &str, is_delete: bool, media_root: Option<&str>) {
106 if Regex::new(r"(?:(?:/|\\)\d{4}(?:/|\\)\d{2}(?:/|\\)\d{2}\-barrel(?:/|\\))")
107 .unwrap()
108 .is_match(image_path)
109 {
110 panic!("This image is not allowed to be reused - {image_path}")
111 }
112 let image_path = if !image_path.is_empty() {
113 Self::copy_file_to_tmp(image_path, media_root).unwrap()
114 } else {
115 String::new()
116 };
117 self.value = Some(ImageData {
118 path: image_path,
119 is_delete,
120 ..Default::default()
121 });
122 }
123 pub fn copy_file_to_tmp(
125 image_path: &str,
126 media_root: Option<&str>,
127 ) -> Result<String, Box<dyn Error>> {
128 let media_root = if let Some(media_root) = media_root {
129 media_root.to_string()
130 } else {
131 "./resources/media".to_string()
132 };
133 let f_path = Path::new(image_path);
134 if !f_path.is_file() {
135 Err(format!("File is missing - {image_path}"))?
136 }
137 let dir_tmp = format!("{media_root}/tmp");
138 fs::create_dir_all(dir_tmp.clone())?;
139 let f_name = Uuid::new_v4().to_string();
140 let ext = f_path.extension().unwrap().to_str().unwrap();
141 let f_tmp = format!("{dir_tmp}/{f_name}.{ext}");
142 fs::copy(image_path, f_tmp.clone())?;
143 Ok(f_tmp)
144 }
145}