Browse Source

Adding files option implementation

bodicsek 4 years ago
parent
commit
de09a3b62b
1 changed files with 48 additions and 8 deletions
  1. 48 8
      canary-log-viewer.ts

+ 48 - 8
canary-log-viewer.ts

@@ -6,18 +6,21 @@ import packageJson from "./package.json";
 import * as Rx from "rxjs";
 
 import { hideBin } from "yargs/helpers";
-import { map, pluck, takeUntil } from "rxjs/operators";
+import { map, pluck, takeUntil, filter, window, mergeAll, buffer } from "rxjs/operators";
 
 
 const args = yargs(hideBin(process.argv))
     .scriptName(Object.keys(packageJson.bin)[0])
-    .usage("Usage: $0 logfile")
+    .usage(`Usage:
+  $0 logfile`)
     .option("files", {
         boolean: true,
-        describe: "Strip out and save the embedded files from the log file"
+        describe: "Extract and save the embedded files from the log file"
     })
     .argv;
 
+const argsParam0 = args._[0]?.toString();
+
 type LogLine = {
     log: string;
     stream: string;
@@ -25,18 +28,55 @@ type LogLine = {
 };
 
 const rl = readline.createInterface({
-    input: fs.createReadStream(args._[0]?.toString())
+    input: fs.createReadStream(argsParam0)
 });
 
-Rx.fromEvent<string>(rl, "line")
+const readlineObservable = Rx.fromEvent<string>(rl, "line")
+    .pipe(
+        takeUntil(Rx.fromEvent(rl, "close"))
+    );
+
+const fileWindowStartObservable = readlineObservable
+    .pipe(
+        filter(rawLine => rawLine.includes("Dumping image"))
+    );
+
+const fileWindowStopObservable = readlineObservable
+    .pipe(
+        filter(rawLine => rawLine.includes("\\u003c\\u003c\\u003c\\u003c"))
+    );
+
+const logObservable = readlineObservable
     .pipe(
-        takeUntil(Rx.fromEvent(rl, "close")),
+        window(Rx.merge(fileWindowStartObservable, fileWindowStopObservable)),
+        filter((_, i) => i % 2 === (args.files ? 1 : 0)), //keep every second observable for the files stream
+        mergeAll(),
+        filter(rawLine => !rawLine.includes("\\u003c\\u003c\\u003c\\u003c")),
         map<string, LogLine>(line => JSON.parse(line)),
         pluck("log"),
         map(log => log.replace(/\n$/, ""))
-    )
-    .subscribe({
+    );
+
+if (args.files) {
+    logObservable
+        .pipe(
+            buffer(fileWindowStopObservable),
+            map(fileLines => ({ name: fileLines.shift()?.substring(10), content: fileLines.join() }))
+        )
+        .subscribe({
+            next: file => {
+                const filename = `${argsParam0}.${file.name}`;
+                fs.writeFile(filename, Buffer.from(file.content, "base64"), () => {
+                    console.log(`File ${filename} is saved.`)
+                });
+            },
+            error: console.error,
+            complete: () => rl.close()
+        });
+} else {
+    logObservable.subscribe({
         next: console.log,
         error: console.error,
         complete: () => rl.close()
     });
+}