|
import os |
|
import subprocess |
|
import platform |
|
from smolagents import tool |
|
|
|
def get_libreoffice_path(): |
|
""" |
|
Get the correct LibreOffice path based on the operating system. |
|
|
|
Returns: |
|
str: Path to LibreOffice executable or None if not found |
|
""" |
|
system = platform.system() |
|
|
|
if system == "Darwin": |
|
|
|
possible_paths = [ |
|
"/Applications/LibreOffice.app/Contents/MacOS/soffice", |
|
"/Applications/LibreOffice Developer Edition.app/Contents/MacOS/soffice", |
|
"/opt/homebrew/bin/soffice", |
|
"/usr/local/bin/soffice" |
|
] |
|
|
|
for path in possible_paths: |
|
if os.path.exists(path): |
|
return path |
|
|
|
elif system == "Linux": |
|
|
|
possible_paths = [ |
|
"/usr/bin/libreoffice", |
|
"/usr/bin/soffice", |
|
"/snap/bin/libreoffice", |
|
"/usr/local/bin/libreoffice" |
|
] |
|
|
|
for path in possible_paths: |
|
if os.path.exists(path): |
|
return path |
|
|
|
elif system == "Windows": |
|
|
|
possible_paths = [ |
|
r"C:\Program Files\LibreOffice\program\soffice.exe", |
|
r"C:\Program Files (x86)\LibreOffice\program\soffice.exe" |
|
] |
|
|
|
for path in possible_paths: |
|
if os.path.exists(path): |
|
return path |
|
|
|
|
|
try: |
|
result = subprocess.run(['which', 'soffice'], capture_output=True, text=True) |
|
if result.returncode == 0: |
|
return result.stdout.strip() |
|
except: |
|
pass |
|
|
|
try: |
|
result = subprocess.run(['which', 'libreoffice'], capture_output=True, text=True) |
|
if result.returncode == 0: |
|
return result.stdout.strip() |
|
except: |
|
pass |
|
|
|
return None |
|
|
|
@tool |
|
def convert_to_pdf_with_libreoffice(input_file: str, output_dir: str = None) -> str: |
|
""" |
|
Convert a document to PDF using LibreOffice. |
|
|
|
Args: |
|
input_file: Path to the input document |
|
output_dir: Directory to save the PDF (optional, defaults to same directory as input) |
|
|
|
Returns: |
|
str: Path to the generated PDF file or error message |
|
""" |
|
libreoffice_path = get_libreoffice_path() |
|
|
|
if not libreoffice_path: |
|
return "LibreOffice not found. Please install LibreOffice from https://www.libreoffice.org/" |
|
|
|
if not os.path.exists(input_file): |
|
return f"Input file not found: {input_file}" |
|
|
|
if output_dir is None: |
|
output_dir = os.path.dirname(input_file) |
|
|
|
if not os.path.exists(output_dir): |
|
os.makedirs(output_dir, exist_ok=True) |
|
|
|
try: |
|
|
|
cmd = [ |
|
libreoffice_path, |
|
'--headless', |
|
'--convert-to', 'pdf', |
|
'--outdir', output_dir, |
|
input_file |
|
] |
|
|
|
result = subprocess.run(cmd, capture_output=True, text=True, timeout=60) |
|
|
|
if result.returncode == 0: |
|
|
|
base_name = os.path.splitext(os.path.basename(input_file))[0] |
|
pdf_path = os.path.join(output_dir, f"{base_name}.pdf") |
|
|
|
if os.path.exists(pdf_path): |
|
return pdf_path |
|
else: |
|
return f"PDF conversion completed but file not found at expected location: {pdf_path}" |
|
else: |
|
return f"LibreOffice conversion failed: {result.stderr}" |
|
|
|
except subprocess.TimeoutExpired: |
|
return "LibreOffice conversion timed out after 60 seconds" |
|
except Exception as e: |
|
return f"Error during LibreOffice conversion: {str(e)}" |
|
|
|
@tool |
|
def check_libreoffice_availability() -> bool: |
|
""" |
|
Check if LibreOffice is available on the system. |
|
|
|
Returns: |
|
bool: True if LibreOffice is available, False otherwise |
|
""" |
|
libreoffice_path = get_libreoffice_path() |
|
return libreoffice_path is not None |
|
|
|
@tool |
|
def get_libreoffice_info() -> str: |
|
""" |
|
Get detailed information about LibreOffice installation for troubleshooting. |
|
|
|
Returns: |
|
str: Detailed information about LibreOffice availability and installation |
|
""" |
|
libreoffice_path = get_libreoffice_path() |
|
|
|
if not libreoffice_path: |
|
system = platform.system() |
|
install_info = { |
|
"Darwin": "Install with: brew install libreoffice OR download from https://www.libreoffice.org/", |
|
"Linux": "Install with: sudo apt install libreoffice OR sudo yum install libreoffice", |
|
"Windows": "Download from https://www.libreoffice.org/" |
|
} |
|
|
|
return f"LibreOffice not found on {system}. {install_info.get(system, 'Install from https://www.libreoffice.org/')}" |
|
|
|
try: |
|
|
|
result = subprocess.run([libreoffice_path, '--version'], capture_output=True, text=True, timeout=10) |
|
version_info = result.stdout.strip() if result.returncode == 0 else "Version unknown" |
|
|
|
return f"LibreOffice found at: {libreoffice_path}\nVersion: {version_info}" |
|
except: |
|
return f"LibreOffice found at: {libreoffice_path}\nVersion: Unable to determine" |
|
|
|
if __name__ == "__main__": |
|
|
|
print(check_libreoffice_availability()) |