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
python · Common Scripts
Details
| ID | ConvertFile |
|---|---|
| Language | python |
| From Version | 5.0.0 |
| Docker Image | demisto/office-utils:2.0.0.9067966 |
| Tags | Utility |
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 |
import glob import logging import os import subprocess import demistomock as demisto import pytest from CommonServerPython import entryTypes from ConvertFile import find_zombie_processes, main, make_sha from unittest.mock import patch RETURN_ERROR_TARGET = "ConvertFile.return_error" @pytest.fixture(autouse=True) def set_logging(caplog): """set logging to DEBUG for better understanding when the tests fails""" caplog.set_level(logging.DEBUG) # easier to debug if the test fails @pytest.mark.parametrize("file", ["test1"]) def test_convert_to_pdf(mocker, file): mocker.patch.object(demisto, "args", return_value={"entry_id": "test"}) ext = os.path.splitext(file)[1] mocker.patch.object(demisto, "getFilePath", return_value={"path": "test_data/" + file, "name": "test" + ext}) mocker.patch.object(demisto, "results") mocker.patch("ConvertFile.make_sha", return_value="mocked_sha") mocker.patch.object(subprocess, "check_output", return_value=b"mocked_output") mocker.patch.object(glob, "glob", return_value=["file1"]) mocker.patch("ConvertFile.shutil.copy") mocker.patch("ConvertFile.os.path.basename", return_value="test1_name") main() results1 = demisto.results.call_args_list[0][0] results2 = demisto.results.call_args_list[1][0] assert demisto.results.call_count == 2 assert results1[0]["Type"] == entryTypes["file"] assert results1[0]["File"] == "test" assert "ERROR" not in str(results1) assert results2[0]["Type"] == entryTypes["note"] assert results2[0]["EntryContext"]["ConvertedFile"]["FileSHA256"] == "mocked_sha" assert results2[0]["EntryContext"]["ConvertedFile"]["Convertable"] == "yes" def test_convert_file_returns_no_files(mocker): mocker.patch.object(demisto, "args", return_value={"entry_id": "test"}) ext = os.path.splitext("test1")[1] mocker.patch.object(demisto, "getFilePath", return_value={"path": "test_data/" + "test1", "name": "test" + ext}) mocker.patch.object(demisto, "results") mocker.patch("ConvertFile.convert_file", return_value=[]) main() results = demisto.results.call_args_list[0][0] assert "No file result returned for convert format:" in str(results) def test_bad_entry_id(mocker): mocker.patch.object(demisto, "args", return_value={"entry_id": "test"}) mocker.patch.object(demisto, "getFilePath", return_value=None) mocker.patch.object(demisto, "results") main() results = demisto.results.call_args_list[0][0] assert "Couldn't find entry id:" in str(results) def test_convert_failure(mocker): # test with BAD format to see that we do not fail and that outputs contain the ERROR field file = "MS-DOCX-190319.docx" # disable-secrets-detection mocker.patch.object(demisto, "args", return_value={"entry_id": "test", "format": "BAD", "all_files": "yes"}) ext = os.path.splitext(file)[1] mocker.patch.object(demisto, "getFilePath", return_value={"path": "test_data/" + file, "name": "test" + ext}) mocker.patch.object(demisto, "results") # validate our mocks are good assert demisto.args()["entry_id"] == "test" main() result = [x[0] for x in demisto.results.call_args_list][0] assert "ERROR" in str(result) def test_zombie_prcesses(mocker): ps_output = """ PID PPID S CMD 1 0 S python /tmp/pyrunner/_script_docker_python_loop.py 39 1 Z [soffice.bin] <defunct> 55 1 Z [gpgconf] <defunct> 57 1 Z [gpgconf] <defunct> 59 1 Z [gpg] <defunct> 61 1 Z [gpgsm] <defunct> 63 1 Z [gpgconf] <defunct> 98 1 Z [gpgconf] <defunct> 100 1 Z [gpgconf] <defunct> 102 1 Z [gpg] <defunct> """ mocker.patch.object(subprocess, "check_output", return_value=ps_output) mocker.patch.object(os, "getpid", return_value=1) zombies, output = find_zombie_processes() assert len(zombies) == 9 assert output == ps_output def test_make_sha_with_mocked_file_data(mocker): # Mocking the file reading process file_data = b"Test file content" mock_open = mocker.patch("builtins.open", mocker.mock_open(read_data=file_data)) mock_sha256 = mocker.MagicMock() mock_sha256.hexdigest.return_value = "mocked_sha256_hash" with patch("hashlib.sha256", return_value=mock_sha256): sha256_hash = make_sha("test_file.txt") mock_open.assert_called_once_with("test_file.txt", "rb") assert sha256_hash == "mocked_sha256_hash"