ReadQRCode
Extracts the text from a QR code. The output of this script includes the output of the script "extractIndicators" run on the text extracted from the QR code.
- Type
- python
- Pack
- CommonScripts
Source
import demistomock as demisto # noqa
from CommonServerPython import * # noqa
from typing import IO
from pyzbar import pyzbar
import cv2
import tempfile
# pylint: disable=E1101 # disable pylint not recognizing cv2's attributes.
class StderrRedirect:
"""Context manager to redirect stderr."""
temp_stderr: IO
old_stderr: int
def __enter__(self):
demisto.debug("entering StderrRedirect")
self.temp_stderr = tempfile.TemporaryFile()
self.old_stderr = os.dup(sys.stderr.fileno()) # make a copy of stderr
os.dup2(self.temp_stderr.fileno(), sys.stderr.fileno()) # redirect stderr to the temporary file
def __exit__(self, exc_type, exc_value, exc_traceback):
demisto.debug(f"exiting StderrRedirect: {exc_type=}, {exc_value=}, {exc_traceback=}")
self.temp_stderr.seek(0)
demisto.debug(f"stderr: {self.temp_stderr.read()}")
os.dup2(self.old_stderr, sys.stderr.fileno()) # restore stderr
os.close(self.old_stderr)
self.temp_stderr.close()
def read_qr_code(filename: str) -> list:
with StderrRedirect(): # redirect stderr to catch cv2 warnings which are sent directly to stderr
img = cv2.imread(filename)
if img is None:
raise TypeError(f"Could not read image from file: {filename}")
demisto.debug(f"loaded file: {filename}")
text = [d.data.decode() for d in pyzbar.decode(img, symbols=[pyzbar.ZBarSymbol.QRCODE])]
demisto.debug(f"pybar decode: {text}")
if not text:
demisto.debug("Couldn't extract text with pyzbar, retrying with cv2.")
text = [cv2.QRCodeDetector().detectAndDecode(img)[0]]
return text
def extract_indicators_from_text(text: list) -> dict:
res = demisto.executeCommand("extractIndicators", {"text": text})
if is_error(res):
demisto.debug(f'Error in "extractIndicators": {get_error(res)}')
return {}
return json.loads(res[0]["Contents"]) # type: ignore
def extract_info_from_qr_code(entry_id: str) -> CommandResults:
try:
filename = demisto.getFilePath(entry_id)["path"]
if os.path.getsize(filename) == 0:
demisto.debug(f"File with entry ID {entry_id} is empty, skipping QR code reading.")
return CommandResults(
readable_output="The file is empty. No QR code could be read.",
entry_type=EntryType.WARNING,
)
text = read_qr_code(filename)
if not any(text):
return CommandResults(readable_output="No QR code was found in the image.")
indicators = extract_indicators_from_text(text)
except (cv2.error, TypeError) as e: # generic error raised by cv2
raise DemistoException("Error parsing file. Please make sure it is a valid image file.") from e
except ValueError as e: # raised by demisto.getFilePath when the entry_id is not found
demisto.debug(f"ValueError: {e}, {e.args}")
raise DemistoException(f"Invalid entry ID: {entry_id=}") from e
return CommandResults(
outputs_prefix="QRCodeReader",
outputs=({"Text": text} | indicators),
readable_output=tableToMarkdown("QR Code Read", {"Text": text}),
)
def main():
try:
return_results(extract_info_from_qr_code(demisto.args()["entry_id"]))
except Exception as e:
return_error(f"Failed to execute ReadQRCode. Error: {e}")
if __name__ in ("__main__", "__builtin__", "builtins"):
main()
README
Extract text from QR codes.
The output of this script includes the output of the script “extractIndicators” run on the text extracted from the QR code.
This script uses the following python libraries to decode:
pyzbaropencv-contrib-python
Script Data
| Name | Description |
|---|---|
| Script Type | python3 |
| Cortex XSOAR Version | 6.10.0 |
Inputs
| Argument Name | Description |
|---|---|
| entry_id | The entry ID of the QR code image. |
Outputs
| Path | Description | Type |
|---|---|---|
| QRCodeReader.Text | The raw text extracted from the QR code image. | String |
| QRCodeReader.Domain | The domains extracted from the QR code image if they are present. | String |
| QRCodeReader.URL | The URLs extracted from the QR code image if they are present. | String |
| QRCodeReader.IP | The IPs extracted from the QR code image if they are present. | String |
Script Examples
Example command
!ReadQRCode entry_id=1234@1234abcd-12ab-12ab-12ab-1234abcd
Context Example
{
"QRCodeReader": {
"Domain": [
"xsoar.pan.dev"
],
"Text": "https://xsoar.pan.dev/",
"URL": [
"https://xsoar.pan.dev/"
]
}
}
Human Readable Output
QR Code Read
Text https://xsoar.pan.dev/