v1.0.7, fix Identical filenames caused settings to overwrite each other
This commit is contained in:
39
src/main.rs
39
src/main.rs
@ -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");
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user