Latest Threat Research:SANDWORM_MODE: Shai-Hulud-Style npm Worm Hijacks CI Workflows and Poisons AI Toolchains.Details
Socket
Book a DemoInstallSign in
Socket

pomo

Package Overview
Dependencies
Maintainers
1
Versions
7
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

pomo - npm Package Compare versions

Comparing version
1.0.7
to
1.1.0
_misc/tomato-small.png

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

+133
var strRepeat = require('../../lib/helpers').strRepeat;
var duration = require('../../lib/helpers').duration;
var qz = require('../../lib/helpers').quantize;
var c = require('../../lib/helpers').c;
var clear = require('../../lib/helpers').clear;
var format = require('util').format;
var moment = require('moment');
/**
* Landing strip reporter.
*/
exports.extend = function(pomo) {
var self = this;
pomo.on({
'start': function() {
clear();
var str = format("time for %s (%s)",
pomo.reason, duration(pomo.work.duration));
if (pomo.snack)
str += format("\na %s break follows",
duration(pomo.snack.duration));
self.info(str);
},
// Work-to-snack transition
'snack': function() {
self.info(format("time for a break (%s)",
duration(pomo.snack.duration)));
},
'timer': function(mode, perc, elapsed, remaining, words) {
self.showStrip.apply(this, arguments);
},
// All done
'finish': function() {
self.info("done");
},
'interrupt': function() {
console.log("");
self.info("interrupted");
}
});
};
/**
* Print the landing strip.
* Method signature is same as runner.on('timer')
*/
exports.showStrip = function(mode, percent, elapsed, remaining) {
if (mode === null) return;
var color = (mode === 'snack' ? 32 : 34);
var dot = '⋅';
var peg = '✈';
var check = '✔';
var len = 50;
var left = parseInt(len * percent, 10);
var right = len - left;
// The thing in the middle
var glyph = ((percent === 1) ? c(color, dot) : peg);
// Progress bar
var progress =
c(color, strRepeat(dot, left)) +
glyph +
c(color, strRepeat(dot, right));
var line = '';
line += " " + progress + ' ';
// Quant
elapsed = qz(elapsed);
remaining = qz(remaining);
// Start
if (percent === 0) {
line += '';
// Finished
} else if (percent === 1) {
line += ' ' + c(color, duration(elapsed));
line += ' ' + c(32, check);
// Last few seconds
} else if (remaining < 60000) {
line += ' ' + c(31, 'last ' + duration(remaining).replace(/ .*$/, ''));
// All else
} else {
line += ' ' + c(color, duration(elapsed));
if (elapsed >= 1000) {
line += ' ' + c(30, dot + ' ' + duration(remaining).replace(/ .*$/, '+') + ' left');
}
}
// Clear it out and print
process.stdout.write("\033[2K\r" + line + ' ');
if (percent === 1) process.stdout.write("\n");
};
/**
* Prints a line, used by .info
*/
exports.print = function(msg) {
process.stdout.write(c(33,' > '));
console.log(msg.replace(/\n/g, '\n '));
};
/**
* Prints a line
*
* .info('hello there')
* " > 03:34pm - hello there"
*/
exports.info = function(msg) {
var dot = ' ⋅ ';
console.log('');
this.print(moment().format('HH:mma') + dot + msg);
console.log('');
};
var fs = require('fs');
var ini = require('ini');
var moment = require('moment');
var format = require('util').format;
var duration = require('../../lib/helpers').shortDuration;
/**
* Logs the given `pomodoro` to `file`.
*
* pomodoro == {
* reason: 'xx'
* duration: 30000
* break: 5000
* date:
* interrupted: false
* }
*/
exports.extend = function(pomo, logfile) {
var self = this;
pomo.on('exit', function() {
if (!pomo.work.startDate) return;
self.log(logfile, {
reason : pomo.reason,
start : pomo.start,
end : pomo.end || pomo.now(),
duration : pomo.work.elapsed(),
'break' : pomo.snack.elapsed(),
interrupted : pomo.interrupted
});
});
};
exports.log = function(file, pomodoro) {
var data = this.load(this.read(file)) || {};
// Heading
var date = moment(pomodoro.start).format('YYYY-MM-DD ddd').toLowerCase();
// Key
var time = format("%s - %s",
moment(pomodoro.start).format('h:mma'),
moment(pomodoro.end).format('h:mma'));
var str = format("%s (%s%s%s)",
pomodoro.reason,
duration(pomodoro.duration),
(pomodoro['break'] ? (' + ' + duration(pomodoro['break'])) : ''),
(pomodoro.interrupted ? ', stopped' : ''));
if (!data[date]) data[date] = {};
data[date][time] = str;
var output = this.dump(data);
this.write(file, output);
};
/**
* Dump/load from object to/from sting
* @api internal
*/
exports.dump = function(obj) {
return ini.stringify(obj);
};
exports.load = function(str) {
return ini.parse(str);
};
/**
* Reads file
* @api internal
*/
exports.read = function(file) {
try {
return fs.readFileSync(file, 'utf-8');
} catch(e) {
return '';
}
};
exports.write = function(file, output) {
fs.writeFileSync(file, output, { encoding: 'utf-8' });
};
var Helpers = require('../../lib/helpers');
var speak = require('../../lib/speak');
var moment = require('moment');
var format = require('util').format;
/**
* Reporter for speaking and growling.
*/
exports.extend = function(pomo, options) {
var self = this;
var say = function(words) {
if (!options.quiet) self.speak(words);
self.growl(words);
};
pomo.on({
'start': function() {
say(format("%s, %s for %s",
moment(pomo.now()).format("h:mm a"),
pomo.work.duration.humanize(),
pomo.reason));
},
'snack': function() {
say(format("Done! %s, break for %s",
moment().format("hh:mm a"),
pomo.snack.duration.humanize()));
},
'finish': function() {
say(pomo.reason + ": all done!");
},
'timer': function(_, _, _, _, words) {
if (words) say(words);
}
});
};
exports.speak = speak;
exports.growl = function(msg) {
var fruit = require.resolve('../../data/tomato.png');
require('growl')(msg, { title: 'Pomo', image: fruit });
};
var fs = require('fs');
var path = require('path');
var strRepeat = require('../../lib/helpers').strRepeat;
var duration = require('../../lib/helpers').duration;
var qz = require('../../lib/helpers').quantize;
/**
* Tmux reporter.
*/
exports.extend = function(pomo, options) {
var self = this;
var fn = path.resolve((options.file || '').replace(/^~/, home()));
pomo.on({
'timer': function(mode, percent, elapsed, remaining) {
var str = self.get.apply(this, arguments);
fs.writeFile(fn, str, function(err) { if (err) throw(err); });
},
'exit': function() {
fs.writeFileSync(fn, '');
}
});
};
exports.dot = '⋅';
exports.peg = '◦';
exports.len = 8;
exports.color = { work: 4, snack: 2 };
/**
* Returns the timer msg
*/
exports.get = function(mode, percent, elapsed, remaining) {
var dot = exports.dot;
var peg = exports.peg;
var len = exports.len;
var color = exports.color[mode];
elapsed = qz(elapsed);
remaining = qz(remaining);
var left = parseInt(len * percent, 10);
var right = len - left;
var progress =
'#[fg=0]' +
strRepeat(dot, left) +
'#[fg='+color+']' +
peg +
'#[fg=0]' +
strRepeat(dot, right);
var dur = '';
if (+remaining > 0 && +elapsed > 0)
dur = '#[fg='+color+']' +
duration(remaining).replace(/ .*$/, '') + ' ';
return dur + progress + '#[fg=0]';
};
function home() {
return process.env[(process.platform == 'win32') ? 'USERPROFILE' : 'HOME'];
}
var EventEmitter = require('events').EventEmitter;
var moment = require('moment');
var Q = require('q');
var _ = require('underscore');
var Timer = require('./timer');
/**
* Manages a work and snack timer and emits events along the way.
*
* Events:
* - start
* - timer (mode, perc, elapsed, remaining, words) - fired on update/start/finish
* - finish
* - interrupt
* - exit (happens after finish or interrupt)
*
* The timer event can be fired with:
*
* - Initial printout ('work', 0, 0, 0)
* - Progress ('work', 0.5, 2000, 4000, null)
* - Progress ('work', 0.5, 2000, 4000, "last 2 seconds")
* - Done ('work', 1, ...)
* - Interrupt (null)
*
* Example:
*
* var runner = new Runner(25, 5);
* runner
* .on('start', function() { ... })
* .on('work:start', function() { ... })
* .run();
*/
var Runner = module.exports = function(work, snack, options) {
// Timers
this.work = new Timer(work, {mode: 'work'});
this.snack = snack ? new Timer(snack, {mode: 'snack'}) : null;
// Start and end times
this.start = null;
this.end = null;
this.interrupted = false;
// Misc
this.reason = options.reason;
this.events = new EventEmitter();
};
/**
* Executes the test trunner.
*/
Runner.prototype.run = function() {
var self = this;
var events = self.events;
process.on('SIGINT', function() {
self.interrupted = true;
events.emit('interrupt');
events.emit('timer', null);
events.emit('exit');
process.exit(0);
});
function progress(a, b, c, d, e) {
events.emit('timer', a, b, c, d, e);
}
return Q['try'](function() { /* Work: initial */
self.work.progress = progress;
if (self.snack) self.snack.progress = progress;
events.emit('start');
self.work.initial();
self.start = self.now();
self.interrupted = false;
return Q.delay(1000);
}).then(function() { /* Work: start */
return self.work.start();
}).then(function() { /* Snack */
if (!self.snack) return;
return Q['try'](function() { /* Snack: initial */
events.emit('snack');
self.snack.initial();
return Q.delay(3000);
}).then(function() { /* Snack: start */
self.end = self.now();
return self.snack.start();
});
}).then(function() { /* Everything finish */
events.emit('finish');
events.emit('exit');
}).done();
};
/**
* Returns the current date.
* (Here to be stubbable)
*/
Runner.prototype.now = function() {
return moment(this.work.now());
};
/**
* Interrupts the current run.
*/
Runner.prototype.interrupt = function() {
this.events.emit('interrupt');
this.work.interrupt();
this.snack.interrupt();
return this;
};
/**
* Binds to an event.
*/
Runner.prototype.on = function(event, fn) {
var self = this;
if (typeof event === 'object') {
_.each(event, function(listener, e) {
self.on(e, listener);
});
return this;
}
_.each(event.trim().split(' '), function(event) {
self.events.on(event, _(fn).bind(this));
});
return this;
};
module.exports = Runner;
var which = require('../lib/helpers').which;
var exec = require('../lib/helpers').exec;
var format = require('util').format;
var pkgs = {
say: "say %s",
espeak: "echo %s | espeak"
};
var sayCmd =
which('say') ? pkgs.say :
which('espeak') ? pkgs.espeak : null;
/**
* Polyfill for speaking
* Uses `say` on OSX and `espeak` on linux
*/
module.exports = function(words) {
exec(format(sayCmd, JSON.stringify(words)));
};
require('./setup');
describe('misc', function() {
it('should require files fine', function() {
require('../lib/speak');
require('../lib/helpers');
require('../lib/timer');
require('../lib/runner');
require('../lib/reporters/tmux');
require('../lib/reporters/speaker');
require('../lib/reporters/landing');
require('../lib/reporters/logger');
});
});
require('./setup');
var Landing = require('../lib/reporters/landing');
var Tmux = require('../lib/reporters/tmux');
var Logger = require('../lib/reporters/logger');
var Speaker = require('../lib/reporters/speaker');
var Runner = require('../lib/runner');
var EventEmitter = require('events').EventEmitter;
var Helpers = require('../lib/helpers');
var _ = require('underscore');
var fs = require('fs');
var Q = require('q');
describe('Simulations', function() {
var pomo = {};
var events;
// Stub `pomo`
beforeEach(function() {
pomo = new Runner(25, 5, { reason: 'torture' });
events = pomo.events;
sinon.stub(pomo, 'now', function() {
return moment('jan 1 2013 03:00 am');
});
});
/**
* Test the tmux reporter
*/
describe('tmux', function() {
var file;
beforeEach(function() {
Tmux.dot = '.';
Tmux.peg = 'X';
Tmux.color = { work: 2, snack: 4 };
file = '/tmp/pomo_simulation_test_'+Math.random();
Tmux.extend(pomo, { file: file });
});
it('initial', pt(function(done) {
return Q['try'](function() {
events.emit('start');
events.emit('timer', 'work', 0, 0, 10000, null);
return Q.delay(50);
}).then(function() {
assert.equal(read(file), '#[fg=0]#[fg=2]X#[fg=0]........#[fg=0]');
});
}));
it('progress', pt(function() {
return Q['try'](function() {
events.emit('timer', 'work', 0.4, 4000, 10000, null);
return Q.delay(50);
}).then(function() {
assert.equal(read(file), '#[fg=2]10s #[fg=0]...#[fg=2]X#[fg=0].....#[fg=0]');
});
}));
});
/**
* Test the Speak reporter
*/
describe('speaker', function() {
var speak, growl;
beforeEach(function() {
speak = sinon.stub(Speaker, 'speak');
growl = sinon.stub(Speaker, 'growl');
Speaker.extend(pomo, { quiet: false });
});
afterEach(function() {
Speaker.speak.restore();
Speaker.growl.restore();
});
it('initial', function() {
events.emit('start');
events.emit('timer', 'work', 0, 0, 10000, null);
assert.isTrue(speak.calledOnce);
assert.jsonEqual(speak.firstCall.args, ["3:00 am, 25 minutes for torture"]);
});
it('5 minutes in', function() {
events.emit('timer', 'work', 0.2, 5*minutes, 25*minutes, '5 minutes in');
assert.isTrue(speak.calledOnce);
assert.jsonEqual(speak.firstCall.args, ["5 minutes in"]);
});
it('done', function() {
events.emit('snack');
assert(Speaker.speak.calledOnce);
});
});
});
function read(file) {
return fs.readFileSync(file, 'utf-8');
}
require('./setup');
if (process.env['fast']) return;
var Runner = require('../lib/runner');
var secs = 1000;
describe('Runner', function() {
this.timeout(30*secs);
it('should work', function(done) {
var runner = new Runner(5 / 60, 5 / 60, { reason: "Tea" });
var events = [];
runner.on({
'start': function() {
events.push(['start', v(arguments)]);
},
'timer': function(mode, perc, elapsed, remaining, words) {
process.stdout.write('.');
events.push(['timer', [ mode, r(perc, 0.1), r(elapsed, 500), r(remaining, 500), words ] ]);
},
'snack': function() {
events.push(['snack', v(arguments)]);
},
'finish': function() {
events.push(['finish', v(arguments)]);
assert.jsonEqual(events, [
[ 'start', [] ],
// mode perc ela rem words
[ 'timer', [ 'work', 0, 0, 0, null ] ],
[ 'timer', [ 'work', 0, 0, 5000, null ] ],
[ 'timer', [ 'work', 0.2, 1000, 4000, null ] ],
[ 'timer', [ 'work', 0.4, 2000, 3000, 3 ] ],
[ 'timer', [ 'work', 0.6, 3000, 2000, 2 ] ],
[ 'timer', [ 'work', 0.8, 4000, 1000, 1 ] ],
[ 'timer', [ 'work', 1.0, 5000, 0, null ] ],
[ 'snack', [] ],
// mode perc ela rem words
[ 'timer', [ 'snack', 0, 0, 0, null ] ],
[ 'timer', [ 'snack', 0, 0, 5000, null ] ],
[ 'timer', [ 'snack', 0.2, 1000, 4000, null ] ],
[ 'timer', [ 'snack', 0.4, 2000, 3000, 3 ] ],
[ 'timer', [ 'snack', 0.6, 3000, 2000, 2 ] ],
[ 'timer', [ 'snack', 0.8, 4000, 1000, 1 ] ],
[ 'timer', [ 'snack', 1.0, 5000, 0, null ] ],
[ 'finish', [] ]
]);
done();
}
}).run();
});
});
// "normalizes" an arguments object
function v(args) {
return [].slice.call(args).map(function(item) {
return (item && item.valueOf) ? item.valueOf() : item;
});
}
// Round
function r(number, precision) {
return Math.round(1000 * precision * Math.round(number / precision)) / 1000;
}
+10
-1

@@ -0,1 +1,8 @@

## v1.1.0 - June 20, 2013
* Big refactor!
* Refactored to allow custom reporters in the future
* Linux speech support (uses espeak instead of say)
* Growl support for other platforms (uses [growl] package)
## v1.0.7 - June 19, 2013

@@ -17,3 +24,3 @@

* Fix 'a minute to go!' announcement.
* The progress bar and speaking is now better synchronized.
* The progress bar and speaking is now better synchronizedk

@@ -28,1 +35,3 @@ ## v1.0.3 - June 18, 2013

* Initial release.
[growl]: https://npmjs.org/package/growl
+15
-5
var _ = require('underscore');
var moment = require('moment');
var fs = require('fs');
var path = require('path');
var exists = fs.existsSync || path.existsSync;
var format = require('util').format;

@@ -22,8 +26,14 @@ exports.strRepeat = function(str, n) {

exports.speak = function(words) {
exec('say '+JSON.stringify(words));
};
/**
* Taken from npm package growl
*/
exports.growl = function(words) {
exec("echo " + JSON.stringify(words) + " | growlnotify Pomo");
var which = exports.which = function(name) {
var paths = process.env.PATH.split(':');
var loc;
for (var i = 0, len = paths.length; i < len; ++i) {
loc = path.join(paths[i], name);
if (exists(loc)) return loc;
}
};

@@ -30,0 +40,0 @@

@@ -22,3 +22,3 @@ var moment = require('moment');

* * speed - duration (in ms) in between progress updates
* * mode - 'break' or 'work'
* * mode - 'snack' or 'work'
*

@@ -30,4 +30,3 @@ */

this.say = options.say || function(){};
this.progress = options.progress || [];
this.progress = options.progress || function(){};
this.mode = options.mode || 'work';

@@ -72,7 +71,2 @@ this.speed = options.speed || 1000;

function run() {
// Throttle to once every N updates
n = ((n + 1) % (1000 / speed));
if (n === 0) timer.speakTime();
// Update progress bar
timer.update();

@@ -86,3 +80,3 @@

progress(timer.elapsed());
setTimeout(run, speed);
timer._id = setTimeout(run, speed);
}

@@ -120,12 +114,2 @@ }

/**
* Speak the remaining time
* ("2 minutes remaining")
*/
Timer.prototype.speakTime = function() {
var msg = this.getMessage();
if (msg) this.say(msg);
};
/**
* Returns the message for the current second (to be spoken).

@@ -161,2 +145,9 @@ */

Timer.prototype.interrupt = function() {
if (this._id) {
clearTimeout(this._id);
delete this._id;
}
};
/**

@@ -166,3 +157,3 @@ * Run progress meters

Timer.prototype.doProgress = function() {
Timer.prototype.progress = function() {
var args = arguments;

@@ -179,3 +170,3 @@ this.progress.forEach(function(callback) {

Timer.prototype.initial = function() {
this.doProgress(0, 0, 0, this.mode);
this.progress(this.mode, 0, 0, 0);
};

@@ -185,11 +176,7 @@

if (this.percent() < 1)
this.doProgress(this.percent(), this.elapsed(), this.remaining(), this.mode);
this.progress(this.mode, this.percent(), this.elapsed(), this.remaining(), this.getMessage());
};
Timer.prototype.done = function() {
this.doProgress(1, this.duration, 0, this.mode);
this.progress(this.mode, 1, this.duration, 0);
};
Timer.prototype.abort = function() {
this.doProgress(null);
};

@@ -10,3 +10,3 @@ {

"author": "Rico Sta. Cruz <hi@ricostacruz.com>",
"version": "1.0.7",
"version": "1.1.0",
"repository": {

@@ -33,4 +33,5 @@ "type": "git",

"q": "~0.9.6",
"ini": "~1.1.0"
"ini": "~1.1.0",
"growl": "~1.7.0"
}
}
+21
-11

@@ -1,2 +0,2 @@

# Pomo.js
# Pomo ![Pomo](http://rstacruz.github.io/pomo.js/tomato-small.png)

@@ -24,15 +24,20 @@ ```

* Ridiculously simple (just type `pomojs`)
* Configurable work and break durations (`pomojs --work 10 --break 2`)
* Announces via text-to-speech ("5 minutes to go!")
* Growls (via growlnotify)
* No support for long breaks (this is a feature. problem?)
* Tmux support (status bar integration)
* Optional logging
* ridiculously simple (just type `pomojs`)
* configurable work and break durations (`pomojs --work 10 --break 2`)
* announces via text-to-speech ("5 minutes to go!")
* notifications
* no support for long breaks (this is a feature. problem?)
* tmux support (status bar integration, shown above)
* optional logging
### Requirements
* node.js and OSX
* growlnotify
* node.js (required)
* osx 10.8+: `gem install terminal-notifier`
* linux: `sudo apt-get install libnotify-bin`
* osx (others): [growlnotify]
* linux: `sudo apt-get install espeak`
see [growl] readme for growl requirements.
----

@@ -94,4 +99,6 @@

MIT
Tomato icon by artbees. (via [iconfinder.net][icon])
(c) 2013, Rico Sta. Cruz. MIT
[visionmedia/pomo]: https://github.com/visionmedia/pomo

@@ -101,1 +108,4 @@ [pmd]: http://me.dt.in.th/page/pmd

[pomo-tmux]: https://github.com/visionmedia/pomo#tmux-status-bar-integration
[icon]: http://www.iconfinder.com/icondetails/56019/128/tomato_vegetable_icon
[growl]: https://npmjs.org/package/growl
[growlnotify]: http://growl.info/downloads
require('./setup');
var logger = require('../lib/logger');
var logger = require('../lib/reporters/logger');
var fs = require('fs');

@@ -35,6 +35,7 @@ var mins = 60 * 1000;

it('should work fresh', function() {
logger('x.txt', {
logger.log('x.txt', {
reason: 'working',
duration: 35*mins, 'break': 5*mins,
date: moment('May 5, 2013 1:00 pm').toDate()
start: moment('May 5, 2013 1:00 pm').toDate(),
end: moment('May 5, 2013 1:40 pm').toDate()
});

@@ -54,6 +55,7 @@

it('no break', function() {
logger('x.txt', {
logger.log('x.txt', {
reason: 'working',
duration: 35*mins, 'break': 0,
date: moment('May 5, 2013 1:00 pm').toDate()
start: moment('May 5, 2013 1:00 pm').toDate(),
end: moment('May 5, 2013 1:35 pm').toDate()
});

@@ -69,18 +71,21 @@

it('should consolidate', function() {
logger('x.txt', {
it('should consolistart', function() {
logger.log('x.txt', {
reason: 'working',
duration: 35*mins, 'break': 5*mins,
date: moment('May 5, 2013 3:00 pm').toDate()
start: moment('May 5, 2013 3:00 pm').toDate(),
end: moment('May 5, 2013 3:40 pm').toDate()
});
logger('x.txt', {
logger.log('x.txt', {
reason: 'working again',
duration: 30*mins, 'break': 5*mins,
date: moment('May 5, 2013 3:30 pm').toDate(),
start: moment('May 5, 2013 4:00 pm').toDate(),
end: moment('May 5, 2013 4:35 pm').toDate(),
interrupted: true
});
logger('x.txt', {
logger.log('x.txt', {
reason: 'also working',
duration: 25*mins, 'break': 5*mins,
date: moment('May 6, 2013 5:00 am').toDate()
start: moment('May 6, 2013 5:00 am').toDate(),
end: moment('May 6, 2013 5:30 am').toDate()
});

@@ -93,3 +98,3 @@

'3:00pm - 3:40pm': 'working (35m + 5m)',
'3:30pm - 4:05pm': 'working again (30m + 5m, stopped)'
'4:00pm - 4:35pm': 'working again (30m + 5m, stopped)'
},

@@ -96,0 +101,0 @@ '2013-05-06 mon': {

@@ -129,16 +129,2 @@ require('./setup');

/**
* Test calls to speak()
*/
describe('speakTime()', function() {
it("say '2 minutes to go'", function() {
timer = makeTimer({ mins: 2.1, elapsed: 6*secs });
timer.speakTime();
assert.equal(say.callCount, 1);
assert.match(say.firstCall.args[0], /2 minutes to go/);
});
});
/**
* Create a mock timer object

@@ -145,0 +131,0 @@ */

var strRepeat = require('./helpers').strRepeat;
var duration = require('./helpers').duration;
var qz = require('./helpers').quantize;
var c = require('./helpers').c;
var format = require('util').format;
module.exports = function(percent, elapsed, remaining, mode) {
if (percent === null) return;
var color = (mode === 'break' ? 32 : 34);
var dot = '⋅';
var peg = '✈';
var check = '✔';
var len = 50;
var left = parseInt(len * percent, 10);
var right = len - left;
// The thing in the middle
var glyph = ((percent === 1) ? c(color, dot) : peg);
// Progress bar
var progress =
c(color, strRepeat(dot, left)) +
glyph +
c(color, strRepeat(dot, right));
var line = '';
line += " " + progress + ' ';
// Quant
elapsed = qz(elapsed);
remaining = qz(remaining);
// Start
if (percent === 0) {
line += '';
// Finished
} else if (percent === 1) {
line += ' ' + c(color, duration(elapsed));
line += ' ' + c(32, check);
// Last few seconds
} else if (remaining < 60000) {
line += ' ' + c(31, 'last ' + duration(remaining).replace(/ .*$/, ''));
// All else
} else {
line += ' ' + c(color, duration(elapsed));
if (elapsed >= 1000) {
line += ' ' + c(30, dot + ' ' + duration(remaining).replace(/ .*$/, '+') + ' left');
}
}
// Clear it out and print
process.stdout.write("\033[2K\r" + line + ' ');
if (percent === 1) process.stdout.write("\n");
};
var fs = require('fs');
var ini = require('ini');
var moment = require('moment');
var duration = require('./helpers').shortDuration;
var format = require('util').format;
/**
* Logs the given `pomodoro` to `file`.
*
* pomodoro == {
* reason: 'xx'
* duration: 30000
* break: 5000
* date:
* interrupted: false
* }
*/
var logger = module.exports = function(file, pomodoro) {
var data = logger.load(logger.read(file)) || {};
// Infer the end date.
var end = moment(+pomodoro.date + (pomodoro['break']||0) + pomodoro.duration);
// Heading
var date = moment(pomodoro.date).format('YYYY-MM-DD ddd').toLowerCase();
// Key
var time = format("%s - %s",
moment(pomodoro.date).format('h:mma'),
moment(end).format('h:mma'));
var str = format("%s (%s%s%s)",
pomodoro.reason,
duration(pomodoro.duration),
(pomodoro['break'] ? (' + ' + duration(pomodoro['break'])) : ''),
(pomodoro.interrupted ? ', stopped' : ''));
if (!data[date]) data[date] = {};
data[date][time] = str;
var output = logger.dump(data);
logger.write(file, output);
};
logger.dump = function(obj) {
return ini.stringify(obj);
};
logger.load = function(str) {
return ini.parse(str);
};
/**
* Reads file
* @api internal
*/
logger.read = function(file) {
try {
return fs.readFileSync(file, 'utf-8');
} catch(e) {
return '';
}
};
logger.write = function(file, output) {
fs.writeFileSync(file, output, { encoding: 'utf-8' });
};
var c = require('./helpers').c;
var moment = require('moment');
exports.info = function(msg) {
process.stdout.write(c(33,' > '));
console.log(msg.replace(/\n/g, '\n '));
};
exports.now = function(msg) {
var dot = ' ⋅ ';
console.log('');
exports.info(moment().format('HH:mma') + dot + msg);
console.log('');
};
var fs = require('fs');
var path = require('path');
var strRepeat = require('./helpers').strRepeat;
var duration = require('./helpers').duration;
var qz = require('./helpers').quantize;
var fn = path.resolve(home(), '.pomo_stat');
module.exports = function(percent, elapsed, remaining, mode) {
var str = get.apply(this, arguments);
// Do it synchronously at the end to ensure sequential-ness
if (+remaining < 5000)
fs.writeFileSync(fn, str);
else
fs.writeFile(fn, str, function(err) { if (err) throw(err); });
};
function get(percent, elapsed, remaining, mode) {
elapsed = qz(elapsed);
remaining = qz(remaining);
if (percent === null) return ' ';
if (+remaining === 0 && mode === 'break') return '';
var color = (mode === 'break' ? 2 : 4);
var dot = '⋅';
var peg = '◦';
var check = '✔';
var len = 8;
var left = parseInt(len * percent, 10);
var right = len - left;
var progress =
'#[fg=0]' +
strRepeat(dot, left) +
'#[fg='+color+']' +
peg +
'#[fg=0]' +
strRepeat(dot, right);
var dur = '';
if (+remaining > 0 && elapsed > 0)
dur = '#[fg='+color+']' +
duration(remaining).replace(/ .*$/, '');
return dur + ' ' + progress + '#[fg=0]';
}
function home() {
return process.env[(process.platform == 'win32') ? 'USERPROFILE' : 'HOME'];
}

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet