Scratch that Itch!
Command-line Node
for fun and profit
Scratch that Itch!
Command-line Node
for fun and profit
Hello!
_ _ .~-,
| | | | .' `,>
__| | ___ __ _| | .D’ ,> <7`,
/ _` |/ _ \/ _` | | ,` | ,> <7 }
| (_| | __/ (_| | | { D !> <7 /
\__,_|\___|\__,_|_| { / j_7` !
_ _ _ _ _ : / j'
(_) | | | (_) | `, ]
__ ___| |_| |__ _| |_ F }
\ \ /\ / / | __| '_ \ | | __| F , {
\ V V /| | |_| | | | | | |_ F `. rr
\_/\_/ |_|\__|_| |_| |_|\__| .F | `=-"
_,-` .F `,
,`; .F j
: 7 F ;
: `^, F` ,'
`, `^, ,F` . , /
`, `^-^-^-^-` ; | ;
`. : .`/ ,-^,-
`-. } ,'' `,_.-^ /'
`-,___ ; .'` -_ ,7
``=-....-={ ,/ `-','`Q
\ | .-'-.]
`, `. .` 0 `.
`, l_ `| __ |`
.C.-,___`==, | || |
Hello!
- Steve Jobs or Mark Twain or whatever
YOLO for Unix™
“Do One Thing Well”
⬢
process
process.stdout ☞ console.log
process.stderr ☞ console.error
%> npm i --save lodash
process.argv
[ "npm", "i", "--save", "lodash" ]
😍
var request = require('request');
request('http://www.google.com', function (error, response, body) {
if (!error && response.statusCode == 200) {
console.log(body) // Show the HTML for the Google homepage.
}
});
var request = require('request');
var cheerio = require('cheerio');
request(
'http://flightaware.com/live/flight/UAL1750',
function (error, response, body) {
if (!error && response.statusCode == 200) {
var $ = cheerio.load(body);
// Showtime!
}
}
);
var table = $('.track-panel-data');
var trs = table.find('tr');
trs.each(function (i) {
var header = trs.eq(i).find('th').text().trim().toLowerCase();
var val = trs.eq(i).find('td').contents().first().text().trim();
data[header] = val;
});
var origin = $('.track-panel-departure .hint').attr('title');
var destination = $('.track-panel-arrival .hint').attr('title');
var times = $('.track-panel-actualtime');
var departure = times.eq(0);
if (departure.children().first().hasClass('flightStatusGood')) {
departure = chalk.green(departure.text().trim());
} else {
departure = chalk.red(departure.text().trim());
}
var arrival = times.eq(1);
if (arrival.children().first().hasClass('flightStatusGood')) {
arrival = chalk.green(arrival.text().trim());
} else {
arrival = chalk.red(arrival.text().trim());
}
> flight US1750
Status: Arrived over an hour ago.
Departure: 06:50PM EDT
Philadelphia Intl (Philadelphia, PA) - KPHL
Arrival: 09:00PM PDT
San Francisco Intl (San Francisco, CA) - KSFO
[------------------------------------✈ ]
46 min elapsed, 47 min left
[------------------------------------✈ ]
46 min elapsed, 47 min left
1 2 3 4 5 6 7 8
---------|---------|---------|---------|---------|---------|---------|---------|
> node
> process.stdout.columns
80
Status: Arrived over an hour ago.
Departure: 06:50PM EDT
Philadelphia Intl (Philadelphia, PA) - KPHL
Arrival: 09:00PM PDT
San Francisco Intl (San Francisco, CA) - KSFO
[------------------------------------✈ ]
46 min elapsed, 47 min left
this is green
'this is \u001b[32mgreen\u001b[39m'
this is green
'this is ' + chalk.green('green')
npm install -g flight-status
-
With the exception of FlightXML, you will only access the FlightAware web site with an interactive web browser and not with any program, collection agent, or "robot" for the purpose of automated retrieval of content.
"Scraping is brittle"
Is This
<div class="before">
VITAL INFORMATION
</div>
<div class="after">
VITAL INFORMATION
</div>
$('.before') // oh no
More brittle than this?
{
"before": "VITAL INFORMATION"
}
{
"after": "VITAL INFORMATION"
}
obj.before // oh no
ABIOGENICALLY ABORIGINALITY ABSORBABILITY ABSTRACTIVELY ACCEPTABILITY ACCESSIBILITY ACCIDENTALITY ACCIDENTOLOGY ACHROMATICITY ACQUIESCENTLY ACQUIESCINGLY ACQUIRABILITY ACQUISITIVELY ACRIMONIOUSLY ACROBATICALLY ACRONYMICALLY ACTINOBIOLOGY ACTINOTHERAPY ADDITIONALITY ADENOIDECTOMY ADIABATICALLY ADIATHERMANCY ADJUSTABILITY ADMISSIBILITY ADMONISHINGLY ADRENALECTOMY ADSORBABILITY ADUMBRATIVELY ADVENTUROUSLY ADVERSATIVELY AEROLITHOLOGY AESTHETICALLY AFFECTABILITY AFFECTIONALLY AFFIRMATIVELY AFFORDABILITY AGGRAVATINGLY AGGREGATIVELY AGONISTICALLY AGRONOMICALLY ALCOHOLICALLY ALCOHOLOMETRY ALGEBRAICALLY ALGOLOGICALLY ALLEGORICALLY ALLERGENICITY ALLOTYPICALLY ALTERNATIVELY ALUMINOTHERMY AMBIDEXTERITY AMBISEXUALITY AMPHIDIPLOIDY ANACHRONOUSLY ANAEROBICALLY ANALYZABILITY ANAPHORICALLY ANECDOTICALLY ANFRACTUOSITY ANSWERABILITY ANTHROPOLATRY ANTHROPOMETRY ANTHROPOPATHY ANTHROPOPHAGY ANTHROPOSOPHY ANTIAUTHORITY ANTIFERTILITY ANTIGENICALLY ANTINOMICALLY ANTIOBSCENITY ANTISEXUALITY ANTISOCIALITY ANTITYPICALLY APATHETICALLY APERIODICALLY APLANATICALLY APODICTICALLY APOLITICALITY APOMICTICALLY APOSTOLICALLY APPEALABILITY APPELLATIVELY APPLICABILITY APPLICATIVELY APPREHENSIBLY APPROPINQUITY APPROPRIATELY APPROXIMATELY APTITUDINALLY ARCHAEOBOTANY ARCHAEZOOLOGY ARCHEOZOOLOGY ARTERIOGRAPHY ARTHRITICALLY ARTIFICIALITY ASCERTAINABLY ASSIGNABILITY ASSOCIABILITY ASSOCIATIVELY ASSOCIATIVITY ASSORTATIVELY ASTHMATICALLY ASTONISHINGLY ASYNDETICALLY ATAVISTICALLY ATHEISTICALLY ATHEMATICALLY ATOMISTICALLY ATTAINABILITY ATTITUDINALLY ATTRIBUTIVELY AUDIOVISUALLY AUTHENTICALLY AUTOBIOGRAPHY AUTOMATICALLY AUTONOMICALLY AUTOSTABILITY AVOCATIONALLY AXIOLOGICALLY AXIOMATICALLY
> a9r a11y
ABIOGENICALLY
ABORIGINALITY
ABSORBABILITY
ABSTRACTIVELY
AFFIRMATIVELY
...
> a9r --random a11y
ADVENTUROUSLY
>
> a9r --random a11y
process.argv
[ "--random", "a11y" ]
> a9r a11y --random
process.argv
[ "a11y", "--random" ]
var opts = require("nomnom")
.option('pattern', { position: 0 })
.option('random', { flag: true })
.parse();
var query = opts.pattern;
var isRandom = opts.random;
var words = require('sowpods'); // Scrabble dictionary, all upper-case
query = query.toUpperCase(); // A11Y
var length = query.length; // 4
var firstLetter = query[0]; // A
var lastLetter = query[length - 1]; // Y
var num = parseInt(query.substr(1, length - 2), 10); // 11
var searchString = '^' + firstLetter + '[A-Z]{' + num + '}' + lastLetter + '$';
var search = new RegExp(searchString); // /^A[A-Z]{11}Y$/
var results = words.filter(function (word) {
return re.search(word);
});
if (opts.random) {
var index = Math.floor(Math.random() * results.length);
var result = results[index];
console.log(result);
} else {
console.log(results.join('\n'));
}
var query = opts.pattern;
var isRandom = opts.random;
var validation = /^[a-zA-Z]\d+[a-zA-Z]$/;
if (!query || !query.match(validation)) {
console.error('Please specify a valid pattern');
process.exit(1);
}
query = query.toUpperCase(); // A11Y
{
"name": "a9r",
"version": "1.0",
"description": "the abbreviator",
"main": "index.js",
"bin": {
"a9r": "index.js"
},
...
}
npm link
/usr/local/bin/a9r -> /usr/local/lib/node_modules/a9r/index.js
/usr/local/lib/node_modules/a9r -> /Users/potch/projects/a9r
T4s!
@potch · github.com/potch
Tutors!
@potch · github.com/potch
Tweets!
@potch · github.com/potch
Tiaras!
@potch · github.com/potch
Tetris!
@potch · github.com/potch
Tushes!
@potch · github.com/potch
Thanks.
@potch · github.com/potch