- Updated MarketplaceDrawer to include security notes and manual installation hints. - Refactored SkillDetailDrawer to display default icons for skills. - Simplified SkillListItem to use default icons for better readability. - Integrated gateway status checks and warnings in SkillsPage for improved user awareness. - Enhanced error handling for skill installation and fetching, providing clearer feedback to users. - Added new translations for error messages and gateway warnings to improve localization support.
136 lines
4.0 KiB
Python
Executable File
136 lines
4.0 KiB
Python
Executable File
"""Accept all tracked changes in a DOCX file using LibreOffice.
|
|
|
|
Requires LibreOffice (soffice) to be installed.
|
|
"""
|
|
|
|
import argparse
|
|
import logging
|
|
import shutil
|
|
import subprocess
|
|
from pathlib import Path
|
|
|
|
from office.soffice import get_soffice_env
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
LIBREOFFICE_PROFILE = "/tmp/libreoffice_docx_profile"
|
|
MACRO_DIR = f"{LIBREOFFICE_PROFILE}/user/basic/Standard"
|
|
|
|
ACCEPT_CHANGES_MACRO = """<?xml version="1.0" encoding="UTF-8"?>
|
|
<!DOCTYPE script:module PUBLIC "-//OpenOffice.org//DTD OfficeDocument 1.0//EN" "module.dtd">
|
|
<script:module xmlns:script="http://openoffice.org/2000/script" script:name="Module1" script:language="StarBasic">
|
|
Sub AcceptAllTrackedChanges()
|
|
Dim document As Object
|
|
Dim dispatcher As Object
|
|
|
|
document = ThisComponent.CurrentController.Frame
|
|
dispatcher = createUnoService("com.sun.star.frame.DispatchHelper")
|
|
|
|
dispatcher.executeDispatch(document, ".uno:AcceptAllTrackedChanges", "", 0, Array())
|
|
ThisComponent.store()
|
|
ThisComponent.close(True)
|
|
End Sub
|
|
</script:module>"""
|
|
|
|
|
|
def accept_changes(
|
|
input_file: str,
|
|
output_file: str,
|
|
) -> tuple[None, str]:
|
|
input_path = Path(input_file)
|
|
output_path = Path(output_file)
|
|
|
|
if not input_path.exists():
|
|
return None, f"Error: Input file not found: {input_file}"
|
|
|
|
if not input_path.suffix.lower() == ".docx":
|
|
return None, f"Error: Input file is not a DOCX file: {input_file}"
|
|
|
|
try:
|
|
output_path.parent.mkdir(parents=True, exist_ok=True)
|
|
shutil.copy2(input_path, output_path)
|
|
except Exception as e:
|
|
return None, f"Error: Failed to copy input file to output location: {e}"
|
|
|
|
if not _setup_libreoffice_macro():
|
|
return None, "Error: Failed to setup LibreOffice macro"
|
|
|
|
cmd = [
|
|
"soffice",
|
|
"--headless",
|
|
f"-env:UserInstallation=file://{LIBREOFFICE_PROFILE}",
|
|
"--norestore",
|
|
"vnd.sun.star.script:Standard.Module1.AcceptAllTrackedChanges?language=Basic&location=application",
|
|
str(output_path.absolute()),
|
|
]
|
|
|
|
try:
|
|
result = subprocess.run(
|
|
cmd,
|
|
capture_output=True,
|
|
text=True,
|
|
timeout=30,
|
|
check=False,
|
|
env=get_soffice_env(),
|
|
)
|
|
except subprocess.TimeoutExpired:
|
|
return (
|
|
None,
|
|
f"Successfully accepted all tracked changes: {input_file} -> {output_file}",
|
|
)
|
|
|
|
if result.returncode != 0:
|
|
return None, f"Error: LibreOffice failed: {result.stderr}"
|
|
|
|
return (
|
|
None,
|
|
f"Successfully accepted all tracked changes: {input_file} -> {output_file}",
|
|
)
|
|
|
|
|
|
def _setup_libreoffice_macro() -> bool:
|
|
macro_dir = Path(MACRO_DIR)
|
|
macro_file = macro_dir / "Module1.xba"
|
|
|
|
if macro_file.exists() and "AcceptAllTrackedChanges" in macro_file.read_text():
|
|
return True
|
|
|
|
if not macro_dir.exists():
|
|
subprocess.run(
|
|
[
|
|
"soffice",
|
|
"--headless",
|
|
f"-env:UserInstallation=file://{LIBREOFFICE_PROFILE}",
|
|
"--terminate_after_init",
|
|
],
|
|
capture_output=True,
|
|
timeout=10,
|
|
check=False,
|
|
env=get_soffice_env(),
|
|
)
|
|
macro_dir.mkdir(parents=True, exist_ok=True)
|
|
|
|
try:
|
|
macro_file.write_text(ACCEPT_CHANGES_MACRO)
|
|
return True
|
|
except Exception as e:
|
|
logger.warning(f"Failed to setup LibreOffice macro: {e}")
|
|
return False
|
|
|
|
|
|
if __name__ == "__main__":
|
|
parser = argparse.ArgumentParser(
|
|
description="Accept all tracked changes in a DOCX file"
|
|
)
|
|
parser.add_argument("input_file", help="Input DOCX file with tracked changes")
|
|
parser.add_argument(
|
|
"output_file", help="Output DOCX file (clean, no tracked changes)"
|
|
)
|
|
args = parser.parse_args()
|
|
|
|
_, message = accept_changes(args.input_file, args.output_file)
|
|
print(message)
|
|
|
|
if "Error" in message:
|
|
raise SystemExit(1)
|