diff options
Diffstat (limited to 'packages/meshbay-hub/src/meshbay_hub')
| -rw-r--r-- | packages/meshbay-hub/src/meshbay_hub/static/csv.js | 14 | ||||
| -rw-r--r-- | packages/meshbay-hub/src/meshbay_hub/static/node-page.js | 7 |
2 files changed, 16 insertions, 5 deletions
diff --git a/packages/meshbay-hub/src/meshbay_hub/static/csv.js b/packages/meshbay-hub/src/meshbay_hub/static/csv.js new file mode 100644 index 0000000..310bdca --- /dev/null +++ b/packages/meshbay-hub/src/meshbay_hub/static/csv.js @@ -0,0 +1,14 @@ +/** + * One CSV cell, quoted when it has to be, and never a formula. + * + * A spreadsheet runs a cell that starts with `=`, `+`, `-` or `@` (or a tab or a + * carriage return in front of one) as a formula. The audit export carries text + * a member chose — a refused blob's kind, a file name — so such a cell is given + * a leading apostrophe, which spreadsheets read as "this is text", and which is + * what other exports do. + */ +export function csvCell(value) { + let s = value == null ? '' : String(value); + if (/^[=+\-@\t\r]/.test(s)) s = `'${s}`; + return /[",\n\r]/.test(s) ? `"${s.replace(/"/g, '""')}"` : s; +} diff --git a/packages/meshbay-hub/src/meshbay_hub/static/node-page.js b/packages/meshbay-hub/src/meshbay_hub/static/node-page.js index f940934..41e9567 100644 --- a/packages/meshbay-hub/src/meshbay_hub/static/node-page.js +++ b/packages/meshbay-hub/src/meshbay_hub/static/node-page.js @@ -1,3 +1,4 @@ +import { csvCell } from './csv.js'; import { html, useState, useEffect, useCallback, useRef, } from './vendor/htm-preact.js'; @@ -585,17 +586,13 @@ export function NodePage({ groups, token, username }) { const cols = ['timestamp', 'event', 'user', 'user_id', 'ip', 'group', 'group_id', 'detail']; - const esc = (v) => { - const s = v == null ? '' : String(v); - return /[",\n\r]/.test(s) ? '"' + s.replace(/"/g, '""') + '"' : s; - }; const lines = [cols.join(',')]; for (const e of rows) { lines.push([ new Date(e.timestamp * 1000).toISOString(), e.event, e.username || '', e.user_id || '', e.ip || '', e.group_name || '', e.group_id || '', e.detail || '', - ].map(esc).join(',')); + ].map(csvCell).join(',')); } const csv = lines.join('\r\n') + '\r\n'; const stamp = new Date().toISOString().slice(0, 19).replace(/[:T]/g, '-'); |