"""
Given a CSV file in the War Room by entry ID, searches based on column and value.
If the column is not present, simply parse the CSV into a list of lists or list of dicts (if header row supplied).
"""
import csv
from CommonServerPython import *
def search_dicts(k, v, data):
"""
Search a list of dicts by key
"""
match = []
for row in data:
if k in row and v == row[k]:
match.append(row)
if len(match) == 1:
# If we only get one result: return just it as a dictr
return match[0]
else:
return match
def search_lists(k, v, data):
"""
Search a list of lists by index
"""
match = []
k = int(k)
for row in data:
row_values = list(row.values())
if row_values[k] == v:
match.append(row)
if len(match) == 1:
# If we only get one result: return just it.
return match[0]
else:
return match
def main():
d_args = demisto.args()
entry_id = d_args.get("entryID")
header_row = d_args.get("header_row")
search_column = d_args.get("column")
search_value = d_args.get("value")
add_row = d_args.get("add_header_row")
res = demisto.getFilePath(entry_id)
if not res:
return_error(f"Entry {entry_id} not found")
file_path = res["path"]
file_name = res["name"]
if not file_name.lower().endswith(".csv"):
return_error(
f'"{file_name}" is not in csv format. Please ensure the file is in correct format and has a ".csv" extension'
)
csv_data: list = []
with open(file_path) as csv_file:
if header_row:
csv_reader = csv.DictReader(csv_file)
for line in csv_reader:
csv_data.append(line)
elif add_row:
headers = add_row.split(",")
csv_reader = csv.DictReader(csv_file, fieldnames=headers)
for line in csv_reader:
csv_data.append(line)
if len(line) != len(add_row.split(",")):
return_error("Added row via add_header_row has invalid length.")
else:
csv_reader = csv.DictReader(csv_file, fieldnames=[])
for line in csv_reader:
line_values = list(line.values())
if line_values:
csv_data.append(line_values[0])
# If we're searching the CSV
if search_column:
if header_row:
csv_data = search_dicts(search_column, search_value, csv_data)
else:
# Lists are 0-indexed but this makes it more human readable (column 0 is column 1)
try:
search_column = int(search_column) - 1
except ValueError:
return_error(f"CSV column spec must be integer if header_row not supplied (got {search_column})")
csv_data = search_lists(search_column, search_value, csv_data)
output = {
"LookupCSV": {
"FoundResult": bool(csv_data and search_column),
"Result": csv_data if csv_data else None,
"SearchValue": search_value if search_value else "",
}
}
demisto.results({"Type": entryTypes["note"], "ContentsFormat": formats["json"], "Contents": csv_data, "EntryContext": output})
if __name__ in ("__builtin__", "builtins"):
main()