import { createReadStream, createWriteStream } from 'fs'; import es from 'event-stream'; import { basename, extname, join } from 'path'; import { obj2csvRow } from '../utils/csv'; import { HandleLogRowOptions, handleLogRow, } from '../utils/log'; import { print, printSuccess, PrintTime } from '../utils/print'; import { checkConf, getProgressBarInstance, promiseQueue } from '../utils/common'; import { getFileRowsNumber } from '../utils/shell'; export interface HandleLog { inputFilePath: string, outputFilePath: string, options: HandleLogRowOptions, } export interface HandleLogs { inputDirPath: string, outputDirPath: string, files: string[], options: HandleLogRowOptions, } export async function handleLog({ inputFilePath, outputFilePath, options, }: HandleLog): Promise { const parseTimeStr = `[${basename(inputFilePath)}] 解析耗时`; PrintTime.start(parseTimeStr); let isFirst = true; let i = 0; const total = await getFileRowsNumber(inputFilePath); const readStream = createReadStream(inputFilePath, { encoding: 'utf-8' }); const writeStream = createWriteStream(outputFilePath); const bar = getProgressBarInstance(`${basename(inputFilePath)}: `, total); const handleComplete = () => { print(''); print('-----------------------------------------------------'); printSuccess(`[${basename(inputFilePath)}] 解析完成,共计 [${i}] 行`); PrintTime.end(parseTimeStr); print(`正确数据已经输出到 [${outputFilePath}]`); print('-----------------------------------------------------'); print(''); }; async function handleLine(line: string, cb: (unknown: unknown, line: string) => void) { const obj = handleLogRow(line, options); if (line === '') { cb(null, ''); return; } const { keys } = options; let rowStr = await obj2csvRow(keys, obj); if (isFirst) { isFirst = false; rowStr = `${keys.join(',')}\n${rowStr}`; } cb(null, rowStr); i += 1; bar.tick(); } return new Promise((resolve) => { readStream .pipe(es.split()) .pipe(es.map((handleLine))) .pipe(es.wait(() => { handleComplete(); resolve(); })) .pipe(writeStream); }); } export function handleLogs(conf:HandleLogs): void { checkConf(conf); const { inputDirPath, outputDirPath, files, options, } = conf; promiseQueue(files.map((fileName) => { const ext = extname(fileName); const plainFileName = fileName.replace(ext, ''); return () => handleLog({ inputFilePath: join(inputDirPath, fileName), outputFilePath: join(outputDirPath, `${plainFileName}.csv`), options, }); })); }