ConvertFile
Converts a file from one format to a different format by using the convert-to function of Libre Office. For a list of supported input/output formats see: https://wiki.openoffice.org/wiki/Framework/Article/Filter/FilterList_OOo_3_0
- Type
- python
- Pack
- CommonScripts
Source
import glob
import os
import shutil
import subprocess
import tempfile
import traceback
import hashlib
import demistomock as demisto
from CommonServerPython import *
def find_zombie_processes():
"""find zombie proceses
Returns:
([process ids], raw ps output) -- return a tuple of zombie process ids and raw ps output
"""
ps_out = subprocess.check_output(
["ps", "-e", "-o", "pid,ppid,state,cmd"], # pragma: no cover
stderr=subprocess.STDOUT,
universal_newlines=True,
) # pragma: no cover
lines = ps_out.splitlines()
pid = str(os.getpid())
zombies = []
if len(lines) > 1:
for line in lines[1:]:
pinfo = line.split()
if pinfo[2] == "Z" and pinfo[1] == pid: # zombie process
zombies.append(pinfo[0])
return zombies, ps_out
def convert_file(file_path: str, out_format: str, all_files: bool, outdir: str, entry_id) -> list[str]:
try:
run_cmd = [
"soffice",
"--headless",
"-env:UserInstallation=file:///tmp/convertfile/.config",
"--convert-to",
out_format,
file_path,
"--outdir",
outdir,
]
env = os.environ.copy()
env["HOME"] = "/tmp/convertfile"
res = subprocess.check_output(run_cmd, stderr=subprocess.STDOUT, universal_newlines=True, env=env) # pragma: no cover
demisto.debug(f"completed running: {run_cmd}. With result: {res}")
if all_files:
files = glob.glob(outdir + "/*")
else:
ext = out_format.split(":")[0]
files = glob.glob(outdir + "/*." + ext)
if not files:
raise ValueError(f"Failed convert for output format: {out_format}. Convert process log: {res}")
return files
finally:
# make sure we don't have zombie processes (seen when converting pdf to html)
try:
zombies, ps_out = find_zombie_processes()
if zombies: # pragma no cover
demisto.info(f"Found zombie processes will waitpid: {ps_out}")
for pid in zombies:
waitres = os.waitpid(int(pid), os.WNOHANG)
demisto.info(f"waitpid result: {waitres}")
else:
demisto.debug(f"No zombie processes found for ps output: {ps_out}")
except Exception as ex:
error = f"Failed checking for zombie processes: {ex}. Trace: {traceback.format_exc()}"
return_results(
CommandResults(outputs_prefix="ConvertedFile", outputs={"EntryID": entry_id, "Convertable": "no", "ERROR": error})
)
def make_sha(file_path):
with open(file_path, "rb") as file:
file_data = file.read()
hash_object = hashlib.sha256(file_data)
sha256_hash = hash_object.hexdigest()
return sha256_hash
def main():
entry_id = demisto.args()["entry_id"] # pragma: no cover
out_format = demisto.args().get("format", "pdf") # pragma: no cover
all_files = demisto.args().get("all_files", "no") == "yes" # pragma: no cover
# URLS
try:
result = demisto.getFilePath(entry_id) # pragma: no cover
if not result:
return_results(
CommandResults(
outputs_prefix="ConvertedFile",
outputs={"EntryID": entry_id, "Convertable": "no", "ERROR": f"Couldn't find entry id: {entry_id}"},
)
)
demisto.debug(f"going to convert: {result}")
file_path = result["path"]
file_path_name_only = os.path.splitext(os.path.basename(file_path))[0]
file_name = result.get("name")
if file_name: # remove the extension
file_name = os.path.splitext(file_name)[0]
with tempfile.TemporaryDirectory() as outdir:
files = convert_file(file_path, out_format, all_files, outdir, entry_id)
if not files:
return_results(
CommandResults(
outputs_prefix="ConvertedFile",
outputs={
"EntryID": entry_id,
"Convertable": "no",
"ERROR": f"No file result returned for convert format: {out_format}",
},
)
)
return
for f in files:
try:
temp = demisto.uniqueFile()
shutil.copy(f, demisto.investigation()["id"] + "_" + temp) # pragma: no cover
name = os.path.basename(f)
if file_name:
name = name.replace(file_path_name_only, file_name)
demisto.results(
{
"Contents": "",
"ContentsFormat": formats["text"],
"Type": entryTypes["file"],
"File": name,
"FileID": temp,
}
)
sha256 = make_sha(f)
return_results(
CommandResults(
outputs_prefix="ConvertedFile", outputs={"Name": name, "FileSHA256": sha256, "Convertable": "yes"}
)
)
except Exception as e:
return_results(
CommandResults(
outputs_prefix="ConvertedFile",
outputs={"Name": name, "EntryID": entry_id, "Convertable": "no", "ERROR": str(e)},
)
)
except subprocess.CalledProcessError as e:
return_results(
CommandResults(outputs_prefix="ConvertedFile", outputs={"EntryID": entry_id, "Convertable": "no", "ERROR": str(e)})
)
except Exception as e:
return_results(
CommandResults(outputs_prefix="ConvertedFile", outputs={"EntryID": entry_id, "Convertable": "no", "ERROR": str(e)})
)
# python2 uses __builtin__ python3 uses builtins
if __name__ == "__builtin__" or __name__ == "builtins": # pragma: no cover
main()
README
Converts a file from one format to a different format by using the convert-to function of Libre Office. For a list of supported input/output formats see: https://wiki.openoffice.org/wiki/Framework/Article/Filter/FilterList_OOo_3_0
Troubleshooting
Operation not permitted
If you get an error such as:
cannot access 'soffice': Operation not permitted
Or:
/usr/bin/soffice: 191: exec: /usr/bin/oosplash: not found
You may need to upgrade Docker, runc, and the libseccomp rpm on your host machine.
Script Data
| Name | Description |
|---|---|
| Script Type | python3 |
| Tags | Utility |
| Cortex XSOAR Version | 5.0.0 |
Used In
This script is used in the following playbooks and scripts.
- Extract Indicators From File - Generic v2
Inputs
| Argument Name | Description |
|---|---|
| entry_id | The War Room entryID of the file to convert. |
| format | Output format to which to convert. Can specify only file extension, such as: “pdf” or <ext:writer> such as “txt:Text (Encoded)”. Default is “pdf”. |
| all_files | If “yes”, will return all generated files. If “no”, will return only the main file. Relevant for formats that might generate multiple files, such as html (which will generate image files additionally to the main html file). Default is “no”. |
Outputs
| Path | Description | Type |
|---|---|---|
| File.Name | The name of the output file. | String |
| File.Extension | The extension of the file. | String |
| File.EntryID | The entry ID of the file. | String |
| File.Info | Additional information about the file. | String |
| File.Type | The file type. | String |