format strings here instead of in component template, gen uniqueID

This commit is contained in:
joshuaboud 2022-06-15 17:21:25 -03:00
parent 85be57d26a
commit 58315a56b2
No known key found for this signature in database
GPG Key ID: 17EFB59E2A8BF50E

View File

@ -1,10 +1,12 @@
import { useSpawn, errorString } from "@45drives/cockpit-helpers"; import { useSpawn, errorString } from "@45drives/cockpit-helpers";
import { UNIT_SEPARATOR, RECORD_SEPARATOR } from "../constants"; import { UNIT_SEPARATOR, RECORD_SEPARATOR } from "../constants";
import { szudzikPair } from "./szudzikPair";
import { escapeStringHTML } from "./escapeStringHTML";
/** /**
* Get list of directory entry objects from list of directory entry names * Get list of directory entry objects from list of directory entry names
* *
* find -H path -maxdepth 1 -mindepth 1 -printf '%f:%m:%M:%s:%u:%g:%B@:%T@:%A@:%y:%Y:%l\n' * find -H path -maxdepth 1 -mindepth 1 -printf '%D:%i%f:%m:%M:%s:%u:%g:%B@:%T@:%A@:%y:%Y:%l\n'
* *
* @param {String} cwd - Working directory to run find in * @param {String} cwd - Working directory to run find in
* @param {String} host - Host to run find on * @param {String} host - Host to run find on
@ -14,6 +16,8 @@ import { UNIT_SEPARATOR, RECORD_SEPARATOR } from "../constants";
*/ */
async function getDirEntryObjects(cwd, host, extraFindArgs = [], failCallback = console.error, byteFormatter = cockpit.format_bytes) { async function getDirEntryObjects(cwd, host, extraFindArgs = [], failCallback = console.error, byteFormatter = cockpit.format_bytes) {
const fields = [ const fields = [
'%D', // dev id
'%i', // inode
'%f', // name '%f', // name
'%p', // full path '%p', // full path
'%m', // mode (octal) '%m', // mode (octal)
@ -86,12 +90,19 @@ async function getDirEntryStats(cwd, host, outputFormat, extraFindArguments = []
function parseRawEntryStats(records, cwd, host, failCallback, byteFormatter = cockpit.format_bytes) { function parseRawEntryStats(records, cwd, host, failCallback, byteFormatter = cockpit.format_bytes) {
return records.map(fields => { return records.map(fields => {
try { try {
let [name, path, mode, modeStr, size, owner, group, ctime, mtime, atime, type, symlinkTargetType, symlinkTargetName] = fields; let [devId, inode, name, path, mode, modeStr, size, owner, group, ctime, mtime, atime, type, symlinkTargetType, symlinkTargetName] = fields;
[size, ctime, mtime, atime] = [size, ctime, mtime, atime].map(num => parseInt(num)); [size, ctime, mtime, atime] = [size, ctime, mtime, atime].map(num => parseInt(num));
[ctime, mtime, atime] = [ctime, mtime, atime].map(ts => ts ? new Date(ts * 1000) : null); [devId, inode] = [devId, inode].map(num => BigInt(num));
[ctime, mtime, atime] = [ctime, mtime, atime].map(ts => (ts && ts > 0) ? new Date(ts * 1000) : null);
let [ctimeStr, mtimeStr, atimeStr] = [ctime, mtime, atime].map(date => date?.toLocaleString() ?? '-');
let [nameHTML, symlinkTargetNameHTML] = [name, symlinkTargetName].map(escapeStringHTML);
mode = parseInt(mode, 8); mode = parseInt(mode, 8);
return { return {
uniqueId: szudzikPair(host, devId, inode),
devId,
inode,
name, name,
nameHTML,
path, path,
mode, mode,
modeStr, modeStr,
@ -102,10 +113,14 @@ function parseRawEntryStats(records, cwd, host, failCallback, byteFormatter = co
ctime, ctime,
mtime, mtime,
atime, atime,
ctimeStr,
mtimeStr,
atimeStr,
type, type,
target: { target: {
type: symlinkTargetType, type: symlinkTargetType,
rawPath: symlinkTargetName, rawPath: symlinkTargetName,
rawPathHTML: symlinkTargetNameHTML,
path: type === 'l' ? symlinkTargetName.replace(/^(?!\/)/, `${cwd}/`) : '', path: type === 'l' ? symlinkTargetName.replace(/^(?!\/)/, `${cwd}/`) : '',
broken: ['L', 'N', '?'].includes(symlinkTargetType), // L: loop N: nonexistent ?: error broken: ['L', 'N', '?'].includes(symlinkTargetType), // L: loop N: nonexistent ?: error
}, },
@ -143,6 +158,9 @@ export default getDirEntryObjects;
* Object representing file system entry * Object representing file system entry
* *
* @typedef {Object} DirectoryEntryObj * @typedef {Object} DirectoryEntryObj
* @property {BigInt} uniqueId - Unique ID generated from pairing function on [devId, inode]
* @property {BigInt} devId - Device ID containing the file
* @property {BigInt} inode - The file's inode
* @property {String} name - File/directory name * @property {String} name - File/directory name
* @property {String} path - Full path to entry * @property {String} path - Full path to entry
* @property {Number} mode - File mode (number) * @property {Number} mode - File mode (number)
@ -154,6 +172,9 @@ export default getDirEntryObjects;
* @property {Date} ctime - Creation time * @property {Date} ctime - Creation time
* @property {Date} mtime - Last Modified time * @property {Date} mtime - Last Modified time
* @property {Date} atime - Last Accessed time * @property {Date} atime - Last Accessed time
* @property {String} ctimeStr - Creation time string
* @property {String} mtimeStr - Last Modified time string
* @property {String} atimeStr - Last Accessed time string
* @property {String} type - Type of inode returned by find * @property {String} type - Type of inode returned by find
* @property {Object} target - Object for symlink target * @property {Object} target - Object for symlink target
* @property {String} target.rawPath - Symlink target path directly grabbed from find * @property {String} target.rawPath - Symlink target path directly grabbed from find