Náhledy přes magick + malé změny
Tento commit je obsažen v:
rodič
11b3c852a8
revize
7a0d219f08
@ -152,7 +152,7 @@ impl From<sqlx::Error> for NekrochanError {
|
|||||||
Self::OverboardError
|
Self::OverboardError
|
||||||
} else {
|
} else {
|
||||||
error!("{e:#?}");
|
error!("{e:#?}");
|
||||||
|
|
||||||
Self::InternalError
|
Self::InternalError
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
72
src/files.rs
72
src/files.rs
@ -2,7 +2,6 @@ use actix_multipart::form::tempfile::TempFile;
|
|||||||
use anyhow::Error;
|
use anyhow::Error;
|
||||||
use chrono::Utc;
|
use chrono::Utc;
|
||||||
use glob::glob;
|
use glob::glob;
|
||||||
use image::io::Reader as ImageReader;
|
|
||||||
use std::{collections::HashSet, process::Command};
|
use std::{collections::HashSet, process::Command};
|
||||||
use tokio::{
|
use tokio::{
|
||||||
fs::{remove_file, rename},
|
fs::{remove_file, rename},
|
||||||
@ -144,18 +143,34 @@ async fn process_image(
|
|||||||
new_name: String,
|
new_name: String,
|
||||||
thumb_name: Option<String>,
|
thumb_name: Option<String>,
|
||||||
) -> Result<(u32, u32), NekrochanError> {
|
) -> Result<(u32, u32), NekrochanError> {
|
||||||
let original_name_ = original_name.clone();
|
let new_name_ = new_name.clone();
|
||||||
|
|
||||||
let img = spawn_blocking(move || {
|
let identify_out = spawn_blocking(move || {
|
||||||
ImageReader::open(format!("/tmp/{new_name}"))?
|
Command::new("identify")
|
||||||
.decode()
|
.args(["-format", "%wx%h", &format!("/tmp/{new_name_}[0]")])
|
||||||
.map_err(|_| {
|
.output()
|
||||||
NekrochanError::FileError(original_name_, "nepodařilo se dekódovat obrázek")
|
|
||||||
})
|
|
||||||
})
|
})
|
||||||
.await??;
|
.await??;
|
||||||
|
|
||||||
let (width, height) = (img.width(), img.height());
|
let invalid_dimensions = "imagemagick vrátil neplatné rozměry";
|
||||||
|
let out_string = String::from_utf8_lossy(&identify_out.stdout);
|
||||||
|
|
||||||
|
let (width, height) = out_string
|
||||||
|
.trim()
|
||||||
|
.split_once('x')
|
||||||
|
.ok_or(NekrochanError::FileError(
|
||||||
|
original_name.clone(),
|
||||||
|
invalid_dimensions,
|
||||||
|
))?;
|
||||||
|
|
||||||
|
let (width, height) = (
|
||||||
|
width
|
||||||
|
.parse()
|
||||||
|
.map_err(|_| NekrochanError::FileError(original_name.clone(), invalid_dimensions))?,
|
||||||
|
height
|
||||||
|
.parse()
|
||||||
|
.map_err(|_| NekrochanError::FileError(original_name.clone(), invalid_dimensions))?,
|
||||||
|
);
|
||||||
|
|
||||||
if width > cfg.files.max_width || height > cfg.files.max_height {
|
if width > cfg.files.max_width || height > cfg.files.max_height {
|
||||||
return Err(NekrochanError::FileError(
|
return Err(NekrochanError::FileError(
|
||||||
@ -168,29 +183,27 @@ async fn process_image(
|
|||||||
return Ok((width, height));
|
return Ok((width, height));
|
||||||
};
|
};
|
||||||
|
|
||||||
let thumb_w = if width > cfg.files.thumb_size {
|
let thumb_size = cfg.files.thumb_size;
|
||||||
cfg.files.thumb_size
|
|
||||||
} else {
|
|
||||||
width
|
|
||||||
};
|
|
||||||
|
|
||||||
let thumb_h = if height > cfg.files.thumb_size {
|
let output = spawn_blocking(move || {
|
||||||
cfg.files.thumb_size
|
Command::new("convert")
|
||||||
} else {
|
.arg(&format!("/tmp/{new_name}"))
|
||||||
height
|
.arg("-thumbnail")
|
||||||
};
|
.arg(&format!("{thumb_size}x{thumb_size}>"))
|
||||||
|
.arg(&format!("./uploads/thumb/{thumb_name}"))
|
||||||
spawn_blocking(move || {
|
.output()
|
||||||
let thumb = img.thumbnail(thumb_w, thumb_h);
|
|
||||||
|
|
||||||
thumb
|
|
||||||
.save(format!("./uploads/thumb/{thumb_name}"))
|
|
||||||
.map_err(|_| {
|
|
||||||
NekrochanError::FileError(original_name, "nepodařilo se vytvořit náhled obrázku")
|
|
||||||
})
|
|
||||||
})
|
})
|
||||||
.await??;
|
.await??;
|
||||||
|
|
||||||
|
if !output.status.success() {
|
||||||
|
println!("{}", String::from_utf8_lossy(&output.stderr));
|
||||||
|
|
||||||
|
return Err(NekrochanError::FileError(
|
||||||
|
original_name,
|
||||||
|
"nepodařilo se vytvořit náhled obrázku",
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
Ok((width, height))
|
Ok((width, height))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -226,8 +239,7 @@ async fn process_video(
|
|||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
let invalid_dimensions = "ffprobe vrátil neplatné rozměry";
|
let invalid_dimensions = "ffmeg vrátil neplatné rozměry";
|
||||||
|
|
||||||
let out_string = String::from_utf8_lossy(&ffprobe_out.stdout);
|
let out_string = String::from_utf8_lossy(&ffprobe_out.stdout);
|
||||||
|
|
||||||
let (width, height) = out_string
|
let (width, height) = out_string
|
||||||
|
@ -13,6 +13,7 @@ lazy_static! {
|
|||||||
pub fn czech_humantime(time: &DateTime<Utc>) -> askama::Result<String> {
|
pub fn czech_humantime(time: &DateTime<Utc>) -> askama::Result<String> {
|
||||||
let duration = (Utc::now() - *time).abs();
|
let duration = (Utc::now() - *time).abs();
|
||||||
|
|
||||||
|
let seconds = duration.num_seconds();
|
||||||
let minutes = duration.num_minutes();
|
let minutes = duration.num_minutes();
|
||||||
let hours = duration.num_hours();
|
let hours = duration.num_hours();
|
||||||
let days = duration.num_days();
|
let days = duration.num_days();
|
||||||
@ -22,6 +23,14 @@ pub fn czech_humantime(time: &DateTime<Utc>) -> askama::Result<String> {
|
|||||||
|
|
||||||
let mut time = "Teď".into();
|
let mut time = "Teď".into();
|
||||||
|
|
||||||
|
if seconds > 0 {
|
||||||
|
time = format!(
|
||||||
|
"{} {}",
|
||||||
|
seconds,
|
||||||
|
czech_plural("sekunda|sekundy|sekund", seconds)?
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
if minutes > 0 {
|
if minutes > 0 {
|
||||||
time = format!(
|
time = format!(
|
||||||
"{} {}",
|
"{} {}",
|
||||||
|
@ -135,8 +135,9 @@ where
|
|||||||
<B as MessageBody>::Error: ResponseError + 'static,
|
<B as MessageBody>::Error: ResponseError + 'static,
|
||||||
{
|
{
|
||||||
let (req, res) = res.into_parts();
|
let (req, res) = res.into_parts();
|
||||||
|
let status = res.status();
|
||||||
|
|
||||||
let error_code = res.status().as_u16();
|
let error_code = status.as_u16();
|
||||||
let error_message = match res.into_body().try_into_bytes().ok() {
|
let error_message = match res.into_body().try_into_bytes().ok() {
|
||||||
Some(bytes) => String::from_utf8(bytes.to_vec()).unwrap_or_default(),
|
Some(bytes) => String::from_utf8(bytes.to_vec()).unwrap_or_default(),
|
||||||
None => String::default(),
|
None => String::default(),
|
||||||
@ -147,7 +148,9 @@ where
|
|||||||
error_message,
|
error_message,
|
||||||
};
|
};
|
||||||
|
|
||||||
let res = template_response(&template)?;
|
let mut res = template_response(&template)?;
|
||||||
|
*(res.status_mut()) = status;
|
||||||
|
|
||||||
let res = ServiceResponse::new(req, res).map_into_right_body();
|
let res = ServiceResponse::new(req, res).map_into_right_body();
|
||||||
|
|
||||||
Ok(ErrorHandlerResponse::Response(res))
|
Ok(ErrorHandlerResponse::Response(res))
|
||||||
|
@ -1,8 +1,7 @@
|
|||||||
use std::collections::HashMap;
|
|
||||||
|
|
||||||
use fancy_regex::{Captures, Regex};
|
use fancy_regex::{Captures, Regex};
|
||||||
use lazy_static::lazy_static;
|
use lazy_static::lazy_static;
|
||||||
use sqlx::query_as;
|
use sqlx::query_as;
|
||||||
|
use std::collections::HashMap;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
ctx::Ctx,
|
ctx::Ctx,
|
||||||
|
@ -339,8 +339,8 @@ summary {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.thumb {
|
.thumb {
|
||||||
max-width: 150px;
|
max-width: 200px;
|
||||||
max-height: 150px;
|
max-height: 200px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.post-content {
|
.post-content {
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
<b>/{{ post.board }}/{{ post.id }}</b>
|
<b>/{{ post.board }}/{{ post.id }}</b>
|
||||||
{% if let Some(file) = post.files.0.get(0) %}
|
{% if let Some(file) = post.files.0.get(0) %}
|
||||||
<a href="{{ post.post_url_notarget() }}">
|
<a href="{{ post.post_url_notarget() }}">
|
||||||
<img src="{{ file.thumb_url() }}">
|
<img class="thumb" src="{{ file.thumb_url() }}">
|
||||||
</a>
|
</a>
|
||||||
{% else %}
|
{% else %}
|
||||||
<p><b><a href="{{ post.post_url_notarget() }}">[Link]</a></b></p>
|
<p><b><a href="{{ post.post_url_notarget() }}">[Link]</a></b></p>
|
||||||
|
Načítá se…
Odkázat v novém úkolu
Zablokovat Uživatele