From dcc37dbe5914b07daa722025fbe8dc00c78bc1dc Mon Sep 17 00:00:00 2001 From: Starbeamrainbowlabs Date: Thu, 2 Jul 2020 16:25:54 +0100 Subject: [PATCH] Implement initial stream-slice subcommand --- src/Helpers/MathsHelpers.mjs | 15 ++++++++ src/Subcommands/stream-slice/index.mjs | 48 ++++++++++++++++++++++++++ src/Subcommands/stream-slice/meta.toml | 25 ++++++++++++++ 3 files changed, 88 insertions(+) create mode 100644 src/Helpers/MathsHelpers.mjs create mode 100644 src/Subcommands/stream-slice/index.mjs create mode 100644 src/Subcommands/stream-slice/meta.toml diff --git a/src/Helpers/MathsHelpers.mjs b/src/Helpers/MathsHelpers.mjs new file mode 100644 index 0000000..8b9dd1d --- /dev/null +++ b/src/Helpers/MathsHelpers.mjs @@ -0,0 +1,15 @@ +"use strict"; + +/** + * Convenience function for calculating the percentage betwween 2 given values. + * @param {Number} count_so_far The fractional part (e.g. items done so far) + * @param {Number} total The total part (e.g. the total number of items to do) + * @param {Number} [range=100] The range to transform to (default: 100) + * @return {Number} The calculated percentage. + */ +function percentage(count_so_far, total, range=100) { + if(count_so_far == 0) return 0; + return (count_so_far/total)*range; +} + +export { percentage }; diff --git a/src/Subcommands/stream-slice/index.mjs b/src/Subcommands/stream-slice/index.mjs new file mode 100644 index 0000000..ad409b4 --- /dev/null +++ b/src/Subcommands/stream-slice/index.mjs @@ -0,0 +1,48 @@ +"use strict"; + +import fs from 'fs'; + +import Terrain50 from 'terrain50'; + +import a from '../../Helpers/Ansi.mjs'; +import l from '../../Helpers/Log.mjs'; + +import { percentage } from '../../Helpers/MathsHelpers.mjs'; + +export default async function(settings) { + // 1: Parse settings + let stream_in = process.stdin; + if(settings.cli.input !== "-") { + l.log(`Reading from ${a.hicol}${settings.cli.input}${a.reset}`); + stream_in = fs.createReadStream(settings.cli.input); + } + else + l.log(`Reading from stdin`); + + let stream_out = process.stdout; + if(settings.cli.output !== "-") { + l.log(`Writing to ${a.hicol}${settings.cli.output}${a.reset}`); + stream_out = fs.createWriteStream(settings.cli.output); + } + else + l.log(`Writing to stdout`); + + let count = settings.cli.count, + offset = settings.cli.offset; + + // ------------------------------------------------------------------------ + + let i = -1; + for await(let next of Terrain50.ParseStream(stream_in)) { + i++; + + if(i < offset) continue; + + let is_last = i - offset >= count; + await next.serialise(stream_out, is_last); + + let percentage = percentage(i - offset, count); + process.stderr.write(`Written ${i - offset} / count objects (~${count.toFixed(2)}%) \r`); + } + l.log(`Slicing complete`); +} diff --git a/src/Subcommands/stream-slice/meta.toml b/src/Subcommands/stream-slice/meta.toml new file mode 100644 index 0000000..7f0b7f3 --- /dev/null +++ b/src/Subcommands/stream-slice/meta.toml @@ -0,0 +1,25 @@ +description = "Extract a slice from a larger stream of objects" + +[[arguments]] +name = "input" +description = "The input file to extract a slice from (default: stdin)" +default_value = "-" +type = "string" + +[[arguments]] +name = "output" +description = "The output file to write to (default: stdout)" +default_value = "-" +type = "string" + +[[arguments]] +name = "count" +description = "The number of objects to extract (default: 1)" +default_value = 1 +type = "integer" + +[[arguments]] +name = "offset" +description = "The number of objects to skip before beginning extraction (default: 0)" +default_value = 0 +type = "integer"