v1.0.7, fix Identical filenames caused settings to overwrite each other

This commit is contained in:
2026-09-19 03:09:26 +03:00
parent 6312d813a7
commit 1015949c15

View File

@ -22,7 +22,7 @@ use tracing::info;
async fn get_version() -> impl IntoResponse {
Json(serde_json::json!({
"version": "1.0.6",
"version": "1.0.7",
"timestamp": chrono::Utc::now().timestamp()
}))
}
@ -192,17 +192,19 @@ async fn create_print(
) -> Result<Json<JobView>, (StatusCode, String)> {
info!("📥 Получен запрос на печать");
let mut settings_map: HashMap<String, PrintSettings> = HashMap::new();
let mut settings_list: Vec<Option<PrintSettings>> = Vec::new();
let mut files_data: Vec<(String, bytes::Bytes)> = Vec::new();
while let Some(field) = multipart.next_field().await.unwrap_or(None) {
let field_name = field.name().unwrap_or("").to_string();
if field_name == "settings" {
if let Ok(text) = field.text().await {
if let Ok(s) = serde_json::from_str::<PrintSettings>(&text) {
settings_map.insert(s.filename.clone(), s);
}
}
let parsed = match field.text().await {
Ok(text) => serde_json::from_str::<PrintSettings>(&text).ok(),
Err(_) => None,
};
// Пушим даже при ошибке парсинга (None), чтобы индексы не съезжали
settings_list.push(parsed);
} else if field_name == "files" {
let file_name = field.file_name().unwrap_or("unknown").to_string();
if let Ok(data) = field.bytes().await {
@ -216,21 +218,26 @@ async fn create_print(
}
let mut job_files: Vec<JobFile> = Vec::new();
for (file_name, data) in files_data {
for (i, (file_name, data)) in files_data.into_iter().enumerate() {
let ext = Path::new(&file_name)
.extension()
.and_then(|e| e.to_str())
.unwrap_or("")
.to_lowercase();
let temp = if ext.is_empty() {
NamedTempFile::new()
} else {
NamedTempFile::with_suffix(&format!(".{}", ext))
};
if let Ok(temp) = temp {
let path = temp.into_temp_path();
if fs::write(&*path, &data).await.is_ok() {
let settings = settings_map.get(&file_name).cloned();
// i-й файл ↔ i-й набор настроек — имена могут совпадать
let settings = settings_list.get(i).cloned().flatten();
job_files.push(JobFile {
name: file_name,
path,
@ -258,6 +265,7 @@ async fn create_print(
let view = job.view();
store.lock().unwrap().insert(job_id.clone(), job);
Ok(Json(view))
}
@ -526,27 +534,18 @@ fn run_lp(path: &Path, settings: Option<&PrintSettings>, duplex_pass: Option<&st
}
}
// ──────────────────────────────────────────────────────────
// СЛОТЫ:
// • Первый проход дуплекса (odd) → Upper
// • Второй проход дуплекса (even) → Lower (ручная подача)
// • Обычная печать (не дуплекс) → Upper
// ──────────────────────────────────────────────────────────
match duplex_pass {
Some("odd") => {
// ПЕРВЫЙ проход — обычный лоток
cmd.arg("-o").arg("InputSlot=Upper");
cmd.arg("-o").arg("page-set=odd");
cmd.arg("-o").arg("page-set=odd"); // Нечётные страницы
}
Some("even") => {
// ВТОРОЙ проход — ручная подача
cmd.arg("-o").arg("InputSlot=Lower");
cmd.arg("-o").arg("page-set=even");
cmd.arg("-o").arg("page-set=even"); // Чётные страницы
cmd.arg("-o").arg("outputorder=reverse");
cmd.arg("-o").arg("orientation-requested=6");
}
_ => {
// Обычная односторонняя печать
cmd.arg("-o").arg("InputSlot=Upper");
}
}