Browse files

Initial commit

  • Loading branch information...
0 parents commit 7f5baa6a0540c3eb27d2d3ea2171d693f651baaf @tj tj committed Apr 20, 2011
Showing with 342 additions and 0 deletions.
  1. +3 −0 .gitignore
  2. +4 −0 .npmignore
  3. +5 −0 History.md
  4. +5 −0 Makefile
  5. +104 −0 Readme.md
  6. +29 −0 examples/download.js
  7. +83 −0 examples/formats.js
  8. +2 −0 index.js
  9. +97 −0 lib/node-progress.js
  10. +10 −0 package.json
3 .gitignore
@@ -0,0 +1,3 @@
+.DS_Store
+node_modules
+*.sock
4 .npmignore
@@ -0,0 +1,4 @@
+support
+test
+examples
+*.sock
5 History.md
@@ -0,0 +1,5 @@
+
+0.0.1 / 2010-01-03
+==================
+
+ * Initial release
5 Makefile
@@ -0,0 +1,5 @@
+
+test:
+ @echo "populate me"
+
+.PHONY: test
104 Readme.md
@@ -0,0 +1,104 @@
+
+# node-progress
+
+ Flexible ascii progress bar
+
+## Usage
+
+ First we create a `ProgressBar`, giving it a format string
+ as well as the `total`, telling the progress bar when it will
+ be considered complete. After that all we need to do is `tick()` appropriately.
+
+ var ProgressBar = require('progress');
+
+ var bar = new ProgressBar(':bar', { total: 10 });
+ var timer = setInterval(function(){
+ bar.tick();
+ if (bar.complete) {
+ console.log('\ncomplete\n');
+ clearInterval(timer);
+ }
+ }, 100);
+
+## Options:
+
+ - `total` total number of ticks to complete
+ - `stream` the output stream defaulting to stdout
+ - `complete` completion character defaulting to "="
+ - `incomplete` incomplete character defaulting to "-"
+
+## Tokens:
+
+ - `:bar` the progress bar itself
+ - `:current` current tick number
+ - `:total` total ticks
+ - `:elapsed` time elapsed in seconds
+ - `:percent` completion percentage
+ - `:eta` eta in seconds
+
+## Examples
+
+### Download
+
+ In our download example each tick has a variable influence, so we pass the chunk length which adjusts the progress bar appropriately relative to the total length.
+
+ var ProgressBar = require('../')
+ , https = require('https');
+
+ var req = https.request({
+ host: 'download.github.com'
+ , port: 443
+ , path: '/visionmedia-node-jscoverage-0d4608a.zip'
+ });
+
+ req.on('response', function(res){
+ var len = parseInt(res.headers['content-length'], 10);
+
+ console.log();
+ var bar = new ProgressBar(' downloading [:bar] :percent :etas', {
+ complete: '='
+ , incomplete: ' '
+ , width: 20
+ , total: len
+ });
+
+ res.on('data', function(chunk){
+ bar.tick(chunk.length);
+ });
+
+ res.on('end', function(){
+ console.log('\n');
+ });
+ });
+
+ req.end();
+
+ The code above will generate a progress bar that looks like this:
+
+ downloading [===== ] 29% 3.7s
+
+
+## License
+
+(The MIT License)
+
+Copyright (c) 2011 TJ Holowaychuk <tj@vision-media.ca>
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+'Software'), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29 examples/download.js
@@ -0,0 +1,29 @@
+
+/**
+ * Module dependencies.
+ */
+
+var ProgressBar = require('../');
+
+// simulated download, passing the chunk lengths to tick()
+
+var contentLength = 128 * 1024;
+
+var bar = new ProgressBar(' downloading [:bar] :percent :etas', {
+ complete: '='
+ , incomplete: ' '
+ , width: 20
+ , total: contentLength
+});
+
+(function next() {
+ if (contentLength) {
+ var chunk = Math.random() * 10 * 1024;
+ bar.tick(chunk);
+ if (bar.complete) {
+ console.log();
+ } else {
+ setTimeout(next, Math.random() * 1000);
+ }
+ }
+})();
83 examples/formats.js
@@ -0,0 +1,83 @@
+
+/**
+ * Module dependencies.
+ */
+
+var ProgressBar = require('../');
+
+var bar = new ProgressBar(':bar', { total: 10 });
+
+console.log('processing:');
+var id = setInterval(function(){
+ bar.tick();
+ if (bar.complete) {
+ console.log('\ncomplete\n');
+ clearInterval(id);
+ bar2();
+ }
+}, 100);
+
+function bar2() {
+ var bar = new ProgressBar(' processing: [:bar]', {
+ total: 15
+ , complete: '*'
+ , incomplete: ' '
+ });
+
+ var id = setInterval(function(){
+ bar.tick();
+ if (bar.complete) {
+ console.log('\n');
+ clearInterval(id);
+ bar3();
+ }
+ }, 100);
+}
+
+function bar3() {
+ var bar = new ProgressBar(' download |:bar| :percent', {
+ complete: '='
+ , incomplete: ' '
+ , width: 40
+ , total: 20
+ });
+
+ var id = setInterval(function(){
+ bar.tick();
+ if (bar.complete) {
+ console.log('\n');
+ clearInterval(id);
+ bar4();
+ }
+ }, 100);
+}
+
+function bar4() {
+ var bar = new ProgressBar(' :current of :total :percent', {
+ total: 20
+ });
+
+ var id = setInterval(function(){
+ bar.tick();
+ if (bar.complete) {
+ console.log('\n');
+ clearInterval(id);
+ bar5();
+ }
+ }, 100);
+}
+
+function bar5() {
+ var bar = new ProgressBar(' [:bar] :elapseds elapsed, eta :etas', {
+ width: 8
+ , total: 50
+ });
+
+ var id = setInterval(function(){
+ bar.tick();
+ if (bar.complete) {
+ console.log('\n');
+ clearInterval(id);
+ }
+ }, 300);
+}
2 index.js
@@ -0,0 +1,2 @@
+
+module.exports = require('./lib/node-progress');
97 lib/node-progress.js
@@ -0,0 +1,97 @@
+
+/*!
+ * node-progress
+ * Copyright(c) 2011 TJ Holowaychuk <tj@vision-media.ca>
+ * MIT Licensed
+ */
+
+/**
+ * Expose `ProgressBar`.
+ */
+
+exports = module.exports = ProgressBar;
+
+/**
+ * Library version.
+ */
+
+exports.version = '0.0.1';
+
+/**
+ * Initialize a `ProgressBar` with the given
+ * `fmt` string and `options`.
+ *
+ * Options:
+ *
+ * - `total` total number of ticks to complete
+ * - `stream` the output stream defaulting to stdout
+ * - `complete` completion character defaulting to "="
+ * - `incomplete` incomplete character defaulting to "-"
+ *
+ * Tokens:
+ *
+ * - `:bar` the progress bar itself
+ * - `:current` current tick number
+ * - `:total` total ticks
+ * - `:elapsed` time elapsed in seconds
+ * - `:percent` completion percentage
+ * - `:eta` eta in seconds
+ *
+ * @param {String} fmt
+ * @param {Object} options
+ * @api public
+ */
+
+function ProgressBar(fmt, options) {
+ options = options || {};
+ if ('string' != typeof fmt) throw new Error('format required');
+ if ('number' != typeof options.total) throw new Error('total required');
+ this.stream = options.stream || process.stdout;
+ this.fmt = fmt;
+ this.curr = 0;
+ this.total = options.total;
+ this.width = options.width || this.total;
+ this.chars = {
+ complete: options.complete || '='
+ , incomplete: options.incomplete || '-'
+ };
+}
+
+/**
+ * "tick" the progress bar with optional `len`.
+ *
+ * @param {Number} len
+ * @api public
+ */
+
+ProgressBar.prototype.tick = function(len){
+ len = len || 1;
+
+ // start time for eta
+ if (0 == this.curr) this.start = new Date;
+
+ // progress complete
+ if ((this.curr += len) >= this.total) {
+ this.complete = true;
+ return;
+ }
+
+ var percent = this.curr / this.total * 100
+ , complete = Math.round(this.width * (this.curr / this.total))
+ , incomplete = this.width - complete
+ , elapsed = new Date - this.start
+ , eta = elapsed * (1 - (this.curr / this.total));
+
+ complete = Array(complete).join(this.chars.complete);
+ incomplete = Array(incomplete).join(this.chars.incomplete);
+
+ var str = this.fmt
+ .replace(':bar', complete + incomplete)
+ .replace(':current', this.curr)
+ .replace(':total', this.total)
+ .replace(':elapsed', (elapsed / 1000).toFixed(1))
+ .replace(':eta', (eta / 1000).toFixed(1))
+ .replace(':percent', percent.toFixed(0) + '%');
+
+ this.stream.write('\r' + str);
+};
10 package.json
@@ -0,0 +1,10 @@
+{
+ "name": "progress"
+ , "version": "0.0.1"
+ , "description": "Flexible ascii progress bar"
+ , "keywords": ["cli", "progress"]
+ , "author": "TJ Holowaychuk <tj@vision-media.ca>"
+ , "dependencies": {}
+ , "main": "index"
+ , "engines": { "node": "0.4.x" }
+}

0 comments on commit 7f5baa6

Please sign in to comment.