From 305e8ac3d7d8a501c195a9f09221f69fb1e3c5a8 Mon Sep 17 00:00:00 2001 From: "(none)" <(none)> Date: Wed, 8 Mar 2023 23:21:41 +0000 Subject: [PATCH] Add html formatter --- Readme.md | 1 + tools/cli.js | 1 + tools/formatters/html.js | 162 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 164 insertions(+) create mode 100644 tools/formatters/html.js diff --git a/Readme.md b/Readme.md index 99a2c27..18dd392 100644 --- a/Readme.md +++ b/Readme.md @@ -93,6 +93,7 @@ ibackuptool -b $UDID --report all ### Reporting formats iBackupTool now supports multiple kinds of data export, which can be selected using the `-f` flag. - `table` - Selected data columns in an ascii table +- `html` - HTML file containing table with selected columns (same data as `table`) - `json` - Selected data columns for display (same data as `table`) - `csv` - CSV file containing selected columns (same data as `table`) diff --git a/tools/cli.js b/tools/cli.js index 500e166..eeac9e4 100755 --- a/tools/cli.js +++ b/tools/cli.js @@ -14,6 +14,7 @@ const { runSingleReport, runSwitchedReport } = require('./util/report_runner') var formatters = { 'json': require('./formatters/json'), 'table': require('./formatters/table'), + 'html': require('./formatters/html'), 'raw': require('./formatters/raw-json'), 'raw-json': require('./formatters/raw-json'), 'csv': require('./formatters/csv'), diff --git a/tools/formatters/html.js b/tools/formatters/html.js new file mode 100644 index 0000000..33cfa1b --- /dev/null +++ b/tools/formatters/html.js @@ -0,0 +1,162 @@ +const fs = require('fs-extra') +const path = require('path') +const log = require('../util/log') + +module.exports.format = function (data, options) { + // Default columns to an empty object + options.colums = options.columns || {} + + // Check if the array is empty. If so, return an empty string. + if (data instanceof Array && data.length === 0) { + return '' + } + + // If we didn't get a data object, make it an array for ease of use. + if (!(data instanceof Array) && typeof data === 'object') { + data = [data] + } + + // Do some preprocessing to find the columns. + if ((!options.columns || Object.keys(options.colums).length === 0) && data.length > 0) { + // Extract the fields from the first object. + options.columns = Object.keys(data[0]) + log.verbose('assigning html columns to', options.columns) + } + + function processRow (el) { + var row = {} + // Iterate over the columns and add each item to the new row. + for (var key of options.columns) { + if (typeof options.columns[key] === 'function') { + var val = options.columns[key](el) + } else { + var val = el[key] + } + if (typeof val === 'object') { + try { + val = JSON.stringify(val, null, " ") + } catch (e) { + val = "[Object]" + } + } + row[key] = val + } + return row + } + + const processedData = data.map(processRow) + const fieldNames = Object.keys(processedData[0]) + const isLongString = (s) => typeof s === 'string' ? s.length > 40 : false; + + const header_row = '
${el}${row[key]}