Compare commits
1 Commits
ca7be6a025
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
| 264b1c1e30 |
@ -1,23 +1,52 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
# Универсальный фильтр CUPS для конвертации офисных документов в PDF через LibreOffice
|
# Универсальный фильтр CUPS для конвертации офисных документов в PDF
|
||||||
|
|
||||||
LO_BIN="/pkg/gnu/libreoffice/core/lib/libreoffice/program/soffice"
|
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"
|
echo "=== Filter started at $(date) ===" > "$LOG_FILE"
|
||||||
OUTPUT_FILE="$TEMP_DIR/output.pdf"
|
echo "Arguments: $@" >> "$LOG_FILE"
|
||||||
|
echo "Input file arg (\$6): $6" >> "$LOG_FILE"
|
||||||
|
|
||||||
# Конвертация в PDF. LibreOffice сам определит формат по содержимому файла.
|
if [ $# -lt 5 ]; then
|
||||||
# Для электронных таблиц (xls/ods) иногда полезно явно указать фильтр,
|
echo "ERROR: $0 job-id user title copies options [file]" >&2
|
||||||
# но обычно --convert-to pdf работает автоматически и корректно.
|
exit 1
|
||||||
"$LO_BIN" --headless --invisible --convert-to pdf --outdir "$TEMP_DIR" "$INPUT_FILE" > /dev/null 2>&1
|
fi
|
||||||
|
|
||||||
if [ -f "$OUTPUT_FILE" ]; then
|
TEMP_DIR=$(mktemp -d)
|
||||||
cat "$OUTPUT_FILE"
|
# Гарантируем очистку временной директории при завершении скрипта
|
||||||
rm -rf "$TEMP_DIR"
|
trap "rm -rf '$TEMP_DIR'" EXIT
|
||||||
exit 0
|
|
||||||
else
|
if [ -n "$6" ]; then
|
||||||
echo "ERROR: LibreOffice conversion failed for $INPUT_FILE" >&2
|
INPUT_FILE="$6"
|
||||||
rm -rf "$TEMP_DIR"
|
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
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|||||||
@ -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 )
|
||||||
@ -1,7 +1,9 @@
|
|||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
use std::fs;
|
use std::fs;
|
||||||
use std::os::unix::fs::MetadataExt;
|
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::parser::{self, pkginfo, env::get_custom_env};
|
||||||
use crate::utils::shell;
|
use crate::utils::shell;
|
||||||
use super::run::download::download;
|
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_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 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");
|
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);
|
check_build_dependency(repo, pkg_md_path);
|
||||||
@ -35,12 +40,34 @@ pub fn install(repo: &String, pkgname: &String) {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
config(repo, pkgname);
|
config(repo, pkgname);
|
||||||
|
|
||||||
|
sync_pkgdata(repo, pkgname, &pkg_dir);
|
||||||
|
|
||||||
if !pkg_dir.join("disabled").exists() { link(repo, pkgname) }
|
if !pkg_dir.join("disabled").exists() { link(repo, pkgname) }
|
||||||
let full_env = &get_custom_env(repo, pkgname, pkg_md_path);
|
let full_env = &get_custom_env(repo, pkgname, pkg_md_path);
|
||||||
shell::run_install_repo_hook_script(repo, full_env);
|
shell::run_install_repo_hook_script(repo, full_env);
|
||||||
shell::run_install_hook_script(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) {
|
fn update_built_link(src: &std::path::Path, dest: &std::path::Path) {
|
||||||
let _ = fs::remove_file(dest);
|
let _ = fs::remove_file(dest);
|
||||||
if let Err(e) = fs::hard_link(src, dest) {
|
if let Err(e) = fs::hard_link(src, dest) {
|
||||||
|
|||||||
Reference in New Issue
Block a user