Last active
September 10, 2018 16:24
-
-
Save Anna-Myzukina/74fb53082bef2daf4cdf1df6f1fa7752 to your computer and use it in GitHub Desktop.
stream-adventure
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//Exercise 1 | |
/** | |
* Make a new directory for your stream-adventure solutions (mkdir stream-adventure and enter it cd ./stream-adventure) | |
Create a new file called beep_boop.js that uses console.log to output "beep boop". | |
*/ | |
console.log("beep boop"); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//Exercise 14 | |
/** | |
* Create a module in a new file named combiner.js, it should return a readable/writable stream using the | |
`stream-combiner` module. | |
*/ | |
var combine = require('stream-combiner'); | |
var through = require('through'); | |
var split = require('split'); | |
var zlib = require('zlib'); | |
module.exports = function () { | |
var grouper = through(write, end); | |
var current; | |
function write (line) { | |
if (line.length === 0) return; | |
var row = JSON.parse(line); | |
if (row.type === 'genre') { | |
if (current) { | |
this.queue(JSON.stringify(current) + '\n'); | |
} | |
current = { name: row.name, books: [] }; | |
} | |
else if (row.type === 'book') { | |
current.books.push(row.name); | |
} | |
} | |
function end () { | |
if (current) { | |
this.queue(JSON.stringify(current) + '\n'); | |
} | |
this.queue(null); | |
} | |
return combine(split(), grouper, zlib.createGzip()); | |
}; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//Exercise 6 | |
/** | |
* Create a new file called concat.js. | |
You will be given text on process.stdin. Buffer the text and reverse it using | |
the `concat-stream` module before writing it to stdout.`concat-stream` is a write stream that you can pass a callback to get the | |
complete contents of a stream as a single buffer.In your adventure you'll only need to buffer input with `concat()` from | |
process.stdin. | |
`npm install concat-stream` in the directory where your solution | |
file is located. | |
*/ | |
var concat = require('concat-stream'); | |
process.stdin.pipe(concat(function (buffer) { | |
process.stdout.write(buffer.toString().split('').reverse().join('')) | |
process.stdout.write('\n') | |
})); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//Exercise 15 | |
/** | |
* Your program will be given a passphrase on `process.argv[2]` and 'aes256' | |
encrypted data will be written to stdin. | |
Simply decrypt the data and stream the result to process.stdout. | |
You can use the `crypto.createDecipher()` api from node core to solve this | |
challenge. Here's an example: | |
var crypto = require('crypto'); | |
var stream = crypto.createDecipher('RC4', 'robots'); | |
stream.pipe(process.stdout); | |
stream.write(Buffer([ 135, 197, 164, 92, 129, 90, 215, 63, 92 ])); | |
stream.end(); | |
Instead of calling `.write()` yourself, just pipe stdin into your decrypter. | |
*/ | |
var crypto = require('crypto'); | |
var passphrase = process.argv[2]; | |
var stream = crypto.createDecipher('aes256', passphrase); | |
process.stdin.pipe(stream).pipe(process.stdout); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//Exercise 13 | |
/** | |
* In this example, you will be given a readable stream, `counter`, as the first | |
argument to your exported function: | |
module.exports = function (counter) { | |
// return a duplex stream to count countries on the writable side | |
// and pass through `counter` on the readable side | |
}; | |
Return a duplex stream with the `counter` as the readable side. You will be | |
written objects with a 2-character `country` field as input, such as these: | |
{"short":"OH","name":"Ohio","country":"US"} | |
{"name":"West Lothian","country":"GB","region":"Scotland"} | |
{"short":"NSW","name":"New South Wales","country":"AU"} | |
Create an object to track the number of occurrences of each unique country code. | |
`npm install duplexer2` in the directory where your solution file is located. | |
*/ | |
var duplexer = require('duplexer2'); | |
var through = require('through2').obj; | |
module.exports = function (counter) { | |
var counts = {}; | |
var input = through(write, end); | |
return duplexer({ objectMode: true }, input, counter); | |
function write(row, _, next) { | |
counts[row.country] = (counts[row.country] || 0) + 1; | |
next(); | |
} | |
function end(done) { | |
counter.setCounts(counts); | |
done(); | |
} | |
}; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//Exercise 12 | |
/** | |
* Write a program that exports a function that spawns a process from a `cmd` | |
string and an `args` array and returns a single duplex stream joining together | |
the stdin and stdout of the spawned process: | |
var spawn = require('child_process').spawn; | |
module.exports = function (cmd, args) { | |
// spawn the process and return a single stream | |
// joining together the stdin and stdout here | |
}; | |
`npm install duplexer2` in the directory where your solution file is located. | |
*/ | |
var spawn = require('child_process').spawn; | |
var duplexer2 = require('duplexer2'); | |
module.exports = function(cmd, args) { | |
var spawnProcess = spawn(cmd, args); | |
return duplexer2(spawnProcess.stdin, spawnProcess.stdout); | |
}; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//Exercise 10 | |
/** | |
* Your program will get some html written to stdin. Convert all the inner html to | |
upper-case for elements with a class name of "loud", | |
and pipe all the html to stdout. | |
You can use `trumpet` and `through2` to solve this adventure. | |
*/ | |
var trumpet = require('trumpet'); | |
var through = require('through2'); | |
var stream = through(write, end); | |
var tr = trumpet(); | |
var loud = tr.select('.loud').createStream(); | |
loud.pipe(stream).pipe(loud); | |
function write(chunk, encoding, next) { | |
this.push(chunk.toString().toUpperCase()); | |
next(); | |
} | |
function end(done) { | |
done(); | |
} | |
process.stdin.pipe(tr).pipe(process.stdout); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//Exercise 8 | |
/** | |
* Send an HTTP POST request to http://localhost:8099 and pipe process.stdin into it. Pipe the response stream to process.stdout. | |
*/ | |
var request = require('request'); | |
var postRequest = request.post('http://localhost:8099'); | |
process.stdin.pipe(postRequest).pipe(process.stdout); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//Exercise 7 | |
/*In this challenge, write an http server that uses a through stream to write | |
back the request stream as upper-cased response data for POST requests.*/ | |
var http = require('http'); | |
var fs = require('fs'); | |
var through = require('through'); | |
// from transform challenge | |
var to_upper = function (buffer) { | |
this.queue(buffer.toString().toUpperCase()) | |
} | |
var server = http.createServer(function (req, res) { | |
if (req.method === 'POST') { | |
req | |
.pipe(through(to_upper)) | |
.pipe(res); | |
} | |
}); | |
server.listen(process.argv[2]); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//Exercise 3 | |
/** | |
* Take data from `process.stdin` and pipe it to `process.stdout`. | |
With `.pipe()`. `process.stdin.pipe()` to be exact. | |
Don't overthink this | |
*/ | |
process.stdin.pipe(process.stdout); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//Exercise 5 | |
/** | |
* convert even-numbered lines to upper-case and odd-numbered | |
lines to lower-case | |
1.npm install split through2 | |
*/ | |
var through = require('through2'); | |
var split = require('split'); | |
var lineCount = 0; | |
var tr = through(function (buf, _, next) { | |
var line = buf.toString(); | |
this.push(lineCount % 2 === 0 | |
? line.toLowerCase() + '\n' | |
: line.toUpperCase() + '\n' | |
); | |
lineCount++; | |
next(); | |
}); | |
process.stdin.pipe(split()).pipe(tr).pipe(process.stdout); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//Exercise 2 | |
/** | |
* You will get a file as the first argument to your program (process.argv[2]). | |
Use `fs.createReadStream()` to pipe the given file to `process.stdout`. | |
`fs.createReadStream()` takes a file as an argument and returns a readable | |
stream that you can call `.pipe()` on. Here's a readable stream that pipes its | |
data to `process.stderr`: | |
var fs = require('fs'); | |
fs.createReadStream('data.txt').pipe(process.stderr); | |
Your program is basically the same idea, but instead of `'data.txt'`, the | |
filename comes from `process.argv[2]` and you should pipe to stdout, not stderr. | |
*/ | |
var fs = require('fs') | |
var filename = process.argv[2] | |
fs.createReadStream(filename).pipe(process.stdout) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//Exercise 16 | |
/** | |
* An encrypted, gzipped tar file will be piped in on process.stdin. To beat this | |
challenge, for each file in the tar input, print a hex-encoded md5 hash of the | |
file contents followed by a single space followed by the filename, then a | |
newline. | |
You will receive the cipher name as process.argv[2] and the cipher passphrase as | |
process.argv[3]. You can pass these arguments directly through to | |
`crypto.createDecipher()`. | |
The built-in zlib library you get when you `require('zlib')` has a | |
`zlib.createGunzip()` that returns a stream for gunzipping. | |
The `tar` module from npm has a `tar.Parse()` function that emits `'entry'` | |
events for each file in the tar input. Each `entry` object is a readable stream | |
of the file contents from the archive and: | |
`entry.type` is the kind of file ('File', 'Directory', etc) | |
`entry.path` is the file path | |
Using the tar module looks like: | |
var tar = require('tar'); | |
var parser = tar.Parse(); | |
parser.on('entry', function (e) { | |
console.dir(e); | |
}); | |
var fs = require('fs'); | |
fs.createReadStream('file.tar').pipe(parser); | |
Use `crypto.createHash('md5', { encoding: 'hex' })` to generate a stream that | |
outputs a hex md5 hash for the content written to it. | |
`npm install tar through` in the directory where your solution file lives. | |
var crypto = require('crypto'); | |
var zlib = require('zlib'); | |
var tar = require('tar'); | |
var through = require('through2'); | |
var decrypter = crypto.createDecipher(process.argv[2], process.argv[3]); | |
var unzipper = zlib.createGunzip(); | |
var parser = tar.Parse(); | |
parser.on('entry', function(e){ | |
var hashStream = crypto.createHash('md5', {encoding: 'hex'}); | |
if (e.type !== 'File') { return; } | |
e.pipe(hashStream) | |
.pipe(through(function(buf, _, next){ | |
this.push(buf.toString()); | |
this.push(" " + e.path + '\n'); | |
next(); | |
})).pipe(process.stdout); | |
}) | |
process.stdin | |
.pipe(decrypter) | |
.pipe(unzipper) | |
.pipe(parser) | |
;*/ | |
var crypto = require('crypto'); | |
var zlib = require('zlib'); | |
var tar = require('tar'); | |
var through = require('through'); | |
var tarParser = tar.Parse().on('entry', function (file) { | |
if (file.type === 'File') { | |
var hexmd5Stream = crypto.createHash('md5', {encoding: 'hex'}) | |
file.pipe(hexmd5Stream).pipe(through(write)) | |
} | |
function write(chunk) { | |
console.log(chunk.toString() +' '+ file.path); | |
} | |
}) | |
var cipherName = process.argv[2] | |
var passphrase = process.argv[3] | |
var decryptor = crypto.createDecipher(cipherName, passphrase) | |
process.stdin.pipe(decryptor).pipe(zlib.createGunzip()).pipe(tarParser) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//Exercise 4 | |
/** | |
* Convert data from `process.stdin` to upper-case data on `process.stdout` | |
using the `through2` module. | |
To get the `through2` module you'll need to do: | |
npm install through2 | |
A transform stream takes input data and applies an operation to the data to | |
produce the output data. | |
Create a through stream with a `write` and `end` function: | |
var through = require('through2'); | |
var stream = through(write, end); | |
The `write` function is called for every buffer of available input: | |
function write (buffer, encoding, next) { | |
// ... | |
} | |
and the `end` function is called when there is no more data: | |
function end () { | |
// ... | |
} | |
Inside the write function, call `this.push()` to produce output data and call | |
`next()` when you're ready to receive the next chunk: | |
function write (buffer, encoding, next) { | |
this.push('I got some data: ' + buffer + '\n'); | |
next(); | |
} | |
and call `done()` to finish the output: | |
function end (done) { | |
done(); | |
} | |
`write` and `end` are both optional. | |
If `write` is not specified, the default implementation passes the input data to | |
the output unmodified. | |
If `end` is not specified, the default implementation calls `this.push(null)` | |
to close the output side when the input side ends. | |
Make sure to pipe `process.stdin` into your transform stream | |
and pipe your transform stream into `process.stdout`, like this: | |
process.stdin.pipe(stream).pipe(process.stdout); | |
To convert a buffer to a string, call `buffer.toString()`. | |
*/ | |
var through = require('through2'); | |
var stream = through(function (buffer) { | |
this.push('I got some data:' + buffer.toString().toUpperCase()); | |
next(); | |
}); | |
process.stdin.pipe(stream).pipe(process.stdout); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//Exercise 9 | |
/** | |
* In this adventure, write some browser code that uses the websocket-stream module | |
to print the string "hello\n". | |
Your solution file will be compiled with browserify and the verify script will | |
prompt you to open `http://localhost:8099` in a browser to verify your solution | |
*/ | |
var ws = require('websocket-stream'); | |
var stream = ws('ws://localhost:8099'); | |
stream.write('hello\n'); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment