From 264b1c1e30de05cd4638537b2fe1fadfe75c12a1 Mon Sep 17 00:00:00 2001 From: TraceLumen Date: Tue, 15 Sep 2026 06:12:48 +0300 Subject: [PATCH] pkg install add sync pkgdata if package already installed --- .../.pkgdata/lib/cups/filter/office-to-pdf | 61 ++++++++++++++----- .../share/cups/{ => mime}/office-to-pdf.convs | 0 .../share/cups/mime/office-to-pdf.types | 13 ++++ src/commands/install.rs | 31 +++++++++- 4 files changed, 87 insertions(+), 18 deletions(-) rename assets/var/gnu/libreoffice/cups/.pkgdata/share/cups/{ => mime}/office-to-pdf.convs (100%) create mode 100644 assets/var/gnu/libreoffice/cups/.pkgdata/share/cups/mime/office-to-pdf.types diff --git a/assets/var/gnu/libreoffice/cups/.pkgdata/lib/cups/filter/office-to-pdf b/assets/var/gnu/libreoffice/cups/.pkgdata/lib/cups/filter/office-to-pdf index 4979ca1..3366742 100755 --- a/assets/var/gnu/libreoffice/cups/.pkgdata/lib/cups/filter/office-to-pdf +++ b/assets/var/gnu/libreoffice/cups/.pkgdata/lib/cups/filter/office-to-pdf @@ -1,23 +1,52 @@ #!/bin/sh -# Универсальный фильтр CUPS для конвертации офисных документов в PDF через LibreOffice +# Универсальный фильтр CUPS для конвертации офисных документов в PDF LO_BIN="/pkg/gnu/libreoffice/core/lib/libreoffice/program/soffice" -TEMP_DIR=$(mktemp -d) +LOG_FILE="/tmp/office-to-pdf-debug.log" -INPUT_FILE="$6" -OUTPUT_FILE="$TEMP_DIR/output.pdf" +echo "=== Filter started at $(date) ===" > "$LOG_FILE" +echo "Arguments: $@" >> "$LOG_FILE" +echo "Input file arg (\$6): $6" >> "$LOG_FILE" -# Конвертация в PDF. LibreOffice сам определит формат по содержимому файла. -# Для электронных таблиц (xls/ods) иногда полезно явно указать фильтр, -# но обычно --convert-to pdf работает автоматически и корректно. -"$LO_BIN" --headless --invisible --convert-to pdf --outdir "$TEMP_DIR" "$INPUT_FILE" > /dev/null 2>&1 - -if [ -f "$OUTPUT_FILE" ]; then - cat "$OUTPUT_FILE" - rm -rf "$TEMP_DIR" - exit 0 -else - echo "ERROR: LibreOffice conversion failed for $INPUT_FILE" >&2 - rm -rf "$TEMP_DIR" +if [ $# -lt 5 ]; then + echo "ERROR: $0 job-id user title copies options [file]" >&2 + exit 1 +fi + +TEMP_DIR=$(mktemp -d) +# Гарантируем очистку временной директории при завершении скрипта +trap "rm -rf '$TEMP_DIR'" EXIT + +if [ -n "$6" ]; then + INPUT_FILE="$6" +else + INPUT_FILE="$TEMP_DIR/input" + cat > "$INPUT_FILE" +fi + +USER_PROFILE="$TEMP_DIR/user_profile" +mkdir -p "$USER_PROFILE" + +echo "Running LibreOffice..." >> "$LOG_FILE" + +# Запуск с HOME во временной папке и флагами, предотвращающими зависания +HOME="$TEMP_DIR" "$LO_BIN" --headless --invisible --norestore --nofirststartwizard "-env:UserInstallation=file://$USER_PROFILE" --convert-to pdf --outdir "$TEMP_DIR" "$INPUT_FILE" >> "$LOG_FILE" 2>&1 +EXIT_CODE=$? + +echo "LibreOffice exit code: $EXIT_CODE" >> "$LOG_FILE" +echo "Contents of TEMP_DIR:" >> "$LOG_FILE" +ls -la "$TEMP_DIR" >> "$LOG_FILE" + +# ИСПРАВЛЕНИЕ: Ищем созданный PDF файл, так как LO использует имя исходного файла +OUTPUT_FILE=$(find "$TEMP_DIR" -maxdepth 1 -name "*.pdf" -type f | head -n 1) + +if [ -n "$OUTPUT_FILE" ] && [ -f "$OUTPUT_FILE" ]; then + echo "SUCCESS: PDF created at $OUTPUT_FILE" >> "$LOG_FILE" + # Передаем содержимое PDF в CUPS + cat "$OUTPUT_FILE" + exit 0 +else + echo "ERROR: LibreOffice conversion failed (No PDF found in temp dir)" >> "$LOG_FILE" + echo "ERROR: LibreOffice conversion failed" >&2 exit 1 fi diff --git a/assets/var/gnu/libreoffice/cups/.pkgdata/share/cups/office-to-pdf.convs b/assets/var/gnu/libreoffice/cups/.pkgdata/share/cups/mime/office-to-pdf.convs similarity index 100% rename from assets/var/gnu/libreoffice/cups/.pkgdata/share/cups/office-to-pdf.convs rename to assets/var/gnu/libreoffice/cups/.pkgdata/share/cups/mime/office-to-pdf.convs diff --git a/assets/var/gnu/libreoffice/cups/.pkgdata/share/cups/mime/office-to-pdf.types b/assets/var/gnu/libreoffice/cups/.pkgdata/share/cups/mime/office-to-pdf.types new file mode 100644 index 0000000..4d34779 --- /dev/null +++ b/assets/var/gnu/libreoffice/cups/.pkgdata/share/cups/mime/office-to-pdf.types @@ -0,0 +1,13 @@ +# Microsoft Office Open XML (DOCX, XLSX, PPTX) +application/vnd.openxmlformats-officedocument.wordprocessingml.document string(0,"\x50\x4b\x03\x04") filename( *.docx ) +application/vnd.openxmlformats-officedocument.spreadsheetml.sheet string(0,"\x50\x4b\x03\x04") filename( *.xlsx ) +application/vnd.openxmlformats-officedocument.presentationml.presentation string(0,"\x50\x4b\x03\x04") filename( *.pptx ) + +# Старые форматы Microsoft (DOC, XLS) - OLE2 compound document +application/vnd.ms-word string(0,"\xd0\xcf\x11\xe0\xa1\xb1\x1a\xe1") filename( *.doc ) +application/vnd.ms-excel string(0,"\xd0\xcf\x11\xe0\xa1\xb1\x1a\xe1") filename( *.xls ) + +# OpenDocument (ODT, ODS, ODP) +application/vnd.oasis.opendocument.text string(0,"\x50\x4b\x03\x04") filename( *.odt ) +application/vnd.oasis.opendocument.spreadsheet string(0,"\x50\x4b\x03\x04") filename( *.ods ) +application/vnd.oasis.opendocument.presentation string(0,"\x50\x4b\x03\x04") filename( *.odp ) diff --git a/src/commands/install.rs b/src/commands/install.rs index a58b5d4..8b774cf 100644 --- a/src/commands/install.rs +++ b/src/commands/install.rs @@ -1,7 +1,9 @@ use std::path::Path; use std::fs; use std::os::unix::fs::MetadataExt; +use std::process::Command; +use crate::commands::link::link; use crate::utils::parser::{self, pkginfo, env::get_custom_env}; use crate::utils::shell; use super::run::download::download; @@ -14,8 +16,11 @@ pub fn install(repo: &String, pkgname: &String) { let pkg_dir = crate::commands::get_aeropkg_base().join(repo).join(pkgname); let pkg_md_path = &crate::commands::get_aeropkg_var().join(format!("{}/{}.md", repo, pkgname)); let builded_pkg_md_path = &crate::commands::get_aeropkg_base().join(repo).join(pkgname).join("build-script.md"); - if builded_pkg_md_path.exists() { - if fs::metadata(builded_pkg_md_path).unwrap().ino() == fs::metadata(pkg_md_path).unwrap().ino() { return } + + if builded_pkg_md_path.exists() && same_inode(&builded_pkg_md_path, pkg_md_path) { + sync_pkgdata(repo, pkgname, &pkg_dir); + if !pkg_dir.join("disabled").exists() { link(repo, pkgname) } + return; } check_build_dependency(repo, pkg_md_path); @@ -35,12 +40,34 @@ pub fn install(repo: &String, pkgname: &String) { } }; config(repo, pkgname); + + sync_pkgdata(repo, pkgname, &pkg_dir); + if !pkg_dir.join("disabled").exists() { link(repo, pkgname) } let full_env = &get_custom_env(repo, pkgname, pkg_md_path); shell::run_install_repo_hook_script(repo, full_env); shell::run_install_hook_script(full_env); } +fn sync_pkgdata(repo: &String, pkgname: &String, pkg_dir: &Path) { + let pkgdata = crate::commands::get_aeropkg_var().join(repo).join(pkgname).join(".pkgdata"); + if pkgdata.exists() { + let status = Command::new("cp") + .args(["-rPlf", &format!("{}/.", pkgdata.to_string_lossy()), &pkg_dir.to_string_lossy()]) + .status(); + if let Err(e) = status { + eprintln!("Warning: failed to copy .pkgdata for {}/{}: {}", repo, pkgname, e); + } + } +} + +fn same_inode(a: &Path, b: &Path) -> bool { + match (fs::metadata(a), fs::metadata(b)) { + (Ok(ma), Ok(mb)) => ma.ino() == mb.ino(), + _ => false, + } +} + fn update_built_link(src: &std::path::Path, dest: &std::path::Path) { let _ = fs::remove_file(dest); if let Err(e) = fs::hard_link(src, dest) {