UNPKG

18 kBJavaScriptView Raw
1'use strict';
2
3var _construct = require('babel-runtime/core-js/reflect/construct');
4
5var _construct2 = _interopRequireDefault(_construct);
6
7var _toConsumableArray2 = require('babel-runtime/helpers/toConsumableArray');
8
9var _toConsumableArray3 = _interopRequireDefault(_toConsumableArray2);
10
11var _create = require('babel-runtime/core-js/object/create');
12
13var _create2 = _interopRequireDefault(_create);
14
15var _assign = require('babel-runtime/core-js/object/assign');
16
17var _assign2 = _interopRequireDefault(_assign);
18
19var _set = require('babel-runtime/core-js/set');
20
21var _set2 = _interopRequireDefault(_set);
22
23var _map = require('babel-runtime/core-js/map');
24
25var _map2 = _interopRequireDefault(_map);
26
27var _regenerator = require('babel-runtime/regenerator');
28
29var _regenerator2 = _interopRequireDefault(_regenerator);
30
31var _asyncToGenerator2 = require('babel-runtime/helpers/asyncToGenerator');
32
33var _asyncToGenerator3 = _interopRequireDefault(_asyncToGenerator2);
34
35var _classCallCheck2 = require('babel-runtime/helpers/classCallCheck');
36
37var _classCallCheck3 = _interopRequireDefault(_classCallCheck2);
38
39var _createClass2 = require('babel-runtime/helpers/createClass');
40
41var _createClass3 = _interopRequireDefault(_createClass2);
42
43var _url = require('url');
44
45var Url = _interopRequireWildcard(_url);
46
47var _cheerio = require('cheerio');
48
49var Cheerio = _interopRequireWildcard(_cheerio);
50
51var _nodeFetch = require('node-fetch');
52
53var _nodeFetch2 = _interopRequireDefault(_nodeFetch);
54
55var _bluebird = require('bluebird');
56
57var _fs = require('fs');
58
59var _path = require('path');
60
61function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }
62
63function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
64
65/* eslint no-console:0 */
66
67
68var readFileAsync = _bluebird.Promise.promisify(_fs.readFile);
69
70var IsSatire = function () {
71 /**
72 * @param {Array} uri [ 'http://...', 'extraneous argument', ... ]
73 * @return {String} "http://..."
74 */
75
76 function IsSatire() {
77 var uri = arguments.length <= 0 || arguments[0] === undefined ? process.argv.slice(2) : arguments[0];
78 (0, _classCallCheck3.default)(this, IsSatire);
79
80 var target = typeof uri !== 'string' ? uri.slice(0, 1).toString() : uri;
81 return this.init(target).catch(function (err) {
82 return console.log(err);
83 });
84 }
85
86 /**
87 * @param {String} uri 'http://...'
88 * @return {*}
89 */
90
91
92 (0, _createClass3.default)(IsSatire, [{
93 key: 'init',
94 value: function () {
95 var ref = (0, _asyncToGenerator3.default)(_regenerator2.default.mark(function _callee(uri) {
96 var _Url$parse, protocol;
97
98 return _regenerator2.default.wrap(function _callee$(_context) {
99 while (1) {
100 switch (_context.prev = _context.next) {
101 case 0:
102 _Url$parse = Url.parse(uri);
103 protocol = _Url$parse.protocol;
104 _context.next = 4;
105 return this.configurationFor(uri);
106
107 case 4:
108 this.config = _context.sent;
109 return _context.abrupt('return', protocol !== null ? this.scanUrl(uri) : this.displayHelp());
110
111 case 6:
112 case 'end':
113 return _context.stop();
114 }
115 }
116 }, _callee, this);
117 }));
118
119 function init(_x2) {
120 return ref.apply(this, arguments);
121 }
122
123 return init;
124 }()
125 }, {
126 key: 'configurationFor',
127 value: function () {
128 var ref = (0, _asyncToGenerator3.default)(_regenerator2.default.mark(function _callee2(uri) {
129 var config;
130 return _regenerator2.default.wrap(function _callee2$(_context2) {
131 while (1) {
132 switch (_context2.prev = _context2.next) {
133 case 0:
134 config = new _map2.default();
135 _context2.t0 = config;
136 _context2.t1 = _set2.default;
137 _context2.t2 = JSON;
138 _context2.next = 6;
139 return readFileAsync((0, _path.join)(__dirname, '..', 'data', 'known.json'), 'utf-8');
140
141 case 6:
142 _context2.t3 = _context2.sent;
143 _context2.t4 = _context2.t2.parse.call(_context2.t2, _context2.t3).sites;
144 _context2.t5 = new _context2.t1(_context2.t4);
145
146 _context2.t0.set.call(_context2.t0, 'blacklist', _context2.t5);
147
148 _context2.t6 = config;
149 _context2.t7 = (0, _create2.default)(null);
150 _context2.t8 = JSON;
151 _context2.next = 15;
152 return readFileAsync((0, _path.join)(__dirname, '..', 'data', 'fingerprint.json'), 'utf-8');
153
154 case 15:
155 _context2.t9 = _context2.sent;
156 _context2.t10 = _context2.t8.parse.call(_context2.t8, _context2.t9).checks;
157 _context2.t11 = (0, _assign2.default)(_context2.t7, _context2.t10);
158
159 _context2.t6.set.call(_context2.t6, 'fingerprint', _context2.t11);
160
161 config.set('uri', uri);
162 return _context2.abrupt('return', config);
163
164 case 21:
165 case 'end':
166 return _context2.stop();
167 }
168 }
169 }, _callee2, this);
170 }));
171
172 function configurationFor(_x3) {
173 return ref.apply(this, arguments);
174 }
175
176 return configurationFor;
177 }()
178 }, {
179 key: 'displayHelp',
180 value: function displayHelp() {
181 console.log('usage: is-satire http(s)://...\n');
182 return process.exit(0);
183 }
184 }, {
185 key: 'isBlacklisted',
186 value: function isBlacklisted(hostname) {
187 return this.blacklist.has(hostname);
188 }
189
190 /**
191 * @param {String} url "http://..."
192 * @param {Array} arr [ '/about', '/about-us', ... ]
193 * @return {Array} [ '/about', '/terms', ... ]
194 */
195
196 }, {
197 key: 'analyzePaths',
198 value: function () {
199 var ref = (0, _asyncToGenerator3.default)(_regenerator2.default.mark(function _callee4(url, arr) {
200 return _regenerator2.default.wrap(function _callee4$(_context4) {
201 while (1) {
202 switch (_context4.prev = _context4.next) {
203 case 0:
204 _context4.next = 2;
205 return arr.reduce(function () {
206 var ref = (0, _asyncToGenerator3.default)(_regenerator2.default.mark(function _callee3(paths, path, data, httpStatus, isValidPath) {
207 return _regenerator2.default.wrap(function _callee3$(_context3) {
208 while (1) {
209 switch (_context3.prev = _context3.next) {
210 case 0:
211 _context3.next = 2;
212 return paths;
213
214 case 2:
215 paths = _context3.sent;
216 _context3.next = 5;
217 return (0, _nodeFetch2.default)(Url.resolve(url, path));
218
219 case 5:
220 data = _context3.sent;
221
222 /* avoid non200's & shortlinks */
223 isValidPath = 200 === data.status && !data.headers.get('link');
224
225 if (isValidPath) {
226 _context3.next = 9;
227 break;
228 }
229
230 return _context3.abrupt('return', paths);
231
232 case 9:
233 _context3.t0 = paths;
234 _context3.t1 = this;
235 _context3.next = 13;
236 return data.text();
237
238 case 13:
239 _context3.t2 = _context3.sent;
240 _context3.t3 = this.fingerprint.keywords;
241 _context3.next = 17;
242 return _context3.t1.findKeywords.call(_context3.t1, _context3.t2, _context3.t3);
243
244 case 17:
245 _context3.t4 = _context3.sent;
246 _context3.t5 = path;
247 _context3.t6 = {
248 keywordsFound: _context3.t4,
249 path: _context3.t5
250 };
251
252 _context3.t0.push.call(_context3.t0, _context3.t6);
253
254 return _context3.abrupt('return', paths);
255
256 case 22:
257 case 'end':
258 return _context3.stop();
259 }
260 }
261 }, _callee3, this);
262 }));
263 return function (_x6, _x7, _x8, _x9, _x10) {
264 return ref.apply(this, arguments);
265 };
266 }().bind(this), []);
267
268 case 2:
269 return _context4.abrupt('return', _context4.sent);
270
271 case 3:
272 case 'end':
273 return _context4.stop();
274 }
275 }
276 }, _callee4, this);
277 }));
278
279 function analyzePaths(_x4, _x5) {
280 return ref.apply(this, arguments);
281 }
282
283 return analyzePaths;
284 }()
285
286 /**
287 * @param {Array} data [ '<!html><head...', ... ]
288 * @param {Array} arr [ 'parody', 'satire', ... ]
289 * @return {Array} [ 'satire']
290 */
291
292 }, {
293 key: 'findKeywords',
294 value: function () {
295 var ref = (0, _asyncToGenerator3.default)(_regenerator2.default.mark(function _callee6(data, arr) {
296 var $, pageContent, keywordsRegex, maybeHasKeyword;
297 return _regenerator2.default.wrap(function _callee6$(_context6) {
298 while (1) {
299 switch (_context6.prev = _context6.next) {
300 case 0:
301 _context6.next = 2;
302 return Cheerio.load(data);
303
304 case 2:
305 $ = _context6.sent;
306 _context6.next = 5;
307 return this.fingerprint.elements.map(function (el) {
308 return $(el).text();
309 });
310
311 case 5:
312 pageContent = _context6.sent;
313 keywordsRegex = new RegExp(this.fingerprint.keywords.join('|'));
314 _context6.next = 9;
315 return pageContent.some(function (text) {
316 return keywordsRegex.test(text);
317 });
318
319 case 9:
320 maybeHasKeyword = _context6.sent;
321
322 if (maybeHasKeyword) {
323 _context6.next = 14;
324 break;
325 }
326
327 _context6.next = 13;
328 return [];
329
330 case 13:
331 return _context6.abrupt('return', _context6.sent);
332
333 case 14:
334 _context6.next = 16;
335 return arr.reduce(function () {
336 var ref = (0, _asyncToGenerator3.default)(_regenerator2.default.mark(function _callee5(keywords, keyword) {
337 return _regenerator2.default.wrap(function _callee5$(_context5) {
338 while (1) {
339 switch (_context5.prev = _context5.next) {
340 case 0:
341 _context5.next = 2;
342 return keywords;
343
344 case 2:
345 keywords = _context5.sent;
346
347 if (new RegExp(keyword).test(pageContent)) keywords.push(keyword);
348 return _context5.abrupt('return', keywords);
349
350 case 5:
351 case 'end':
352 return _context5.stop();
353 }
354 }
355 }, _callee5, this);
356 }));
357 return function (_x13, _x14) {
358 return ref.apply(this, arguments);
359 };
360 }(), []);
361
362 case 16:
363 return _context6.abrupt('return', _context6.sent);
364
365 case 17:
366 case 'end':
367 return _context6.stop();
368 }
369 }
370 }, _callee6, this);
371 }));
372
373 function findKeywords(_x11, _x12) {
374 return ref.apply(this, arguments);
375 }
376
377 return findKeywords;
378 }()
379
380 /**
381 * @param {Array} data [ { keywordsFound: [ 'satire', ... ] } ]
382 * @return {Array} [ 'satire', 'fictional', ... ]
383 */
384
385 }, {
386 key: 'calculateLikelihood',
387 value: function () {
388 var ref = (0, _asyncToGenerator3.default)(_regenerator2.default.mark(function _callee8(data) {
389 var keywordsFound;
390 return _regenerator2.default.wrap(function _callee8$(_context8) {
391 while (1) {
392 switch (_context8.prev = _context8.next) {
393 case 0:
394 _context8.next = 2;
395 return data.reduce(function () {
396 var ref = (0, _asyncToGenerator3.default)(_regenerator2.default.mark(function _callee7(keywords, key) {
397 return _regenerator2.default.wrap(function _callee7$(_context7) {
398 while (1) {
399 switch (_context7.prev = _context7.next) {
400 case 0:
401 _context7.next = 2;
402 return keywords;
403
404 case 2:
405 keywords = _context7.sent;
406 return _context7.abrupt('return', keywords.concat(key.keywordsFound));
407
408 case 4:
409 case 'end':
410 return _context7.stop();
411 }
412 }
413 }, _callee7, this);
414 }));
415 return function (_x16, _x17) {
416 return ref.apply(this, arguments);
417 };
418 }(), []);
419
420 case 2:
421 keywordsFound = _context8.sent;
422 _context8.next = 5;
423 return [].concat((0, _toConsumableArray3.default)(new _set2.default(keywordsFound)));
424
425 case 5:
426 return _context8.abrupt('return', _context8.sent);
427
428 case 6:
429 case 'end':
430 return _context8.stop();
431 }
432 }
433 }, _callee8, this);
434 }));
435
436 function calculateLikelihood(_x15) {
437 return ref.apply(this, arguments);
438 }
439
440 return calculateLikelihood;
441 }()
442
443 /**
444 * @return {String} "there's a ... likelihood that this is..."
445 */
446
447 }, {
448 key: 'beginScan',
449 value: function () {
450 var ref = (0, _asyncToGenerator3.default)(_regenerator2.default.mark(function _callee9() {
451 var analysis;
452 return _regenerator2.default.wrap(function _callee9$(_context9) {
453 while (1) {
454 switch (_context9.prev = _context9.next) {
455 case 0:
456 _context9.next = 2;
457 return this.analyzePaths(this.target, this.fingerprint.paths);
458
459 case 2:
460 analysis = _context9.sent;
461 _context9.next = 5;
462 return this.calculateLikelihood(analysis);
463
464 case 5:
465 return _context9.abrupt('return', _context9.sent);
466
467 case 6:
468 case 'end':
469 return _context9.stop();
470 }
471 }
472 }, _callee9, this);
473 }));
474
475 function beginScan() {
476 return ref.apply(this, arguments);
477 }
478
479 return beginScan;
480 }()
481
482 /**
483 * @param {String} url "http://..."
484 * @return {*}
485 */
486
487 }, {
488 key: 'scanUrl',
489 value: function () {
490 var ref = (0, _asyncToGenerator3.default)(_regenerator2.default.mark(function _callee10(uri) {
491 var result;
492 return _regenerator2.default.wrap(function _callee10$(_context10) {
493 while (1) {
494 switch (_context10.prev = _context10.next) {
495 case 0:
496 console.log('checking ' + Url.parse(uri).hostname + '...');
497
498 if (!this.isBlacklisted(Url.parse(uri).hostname)) {
499 _context10.next = 3;
500 break;
501 }
502
503 return _context10.abrupt('return', console.log(uri + ' is a known satire site!'));
504
505 case 3:
506 _context10.next = 5;
507 return this.beginScan();
508
509 case 5:
510 result = _context10.sent;
511
512 console.log('Found Keywords: ' + result.join(', '));
513 if (result.length === 0) console.log('this does not seem to be a satire site. but i could be wrong.');
514 if (result.length === 1) console.log('there\'s a small likelihood that this is a satire site.');
515 if (result.length > 1) console.log('there\'s a strong likelihood that this is a satire site.');
516 _context10.next = 12;
517 return false;
518
519 case 12:
520 return _context10.abrupt('return', _context10.sent);
521
522 case 13:
523 case 'end':
524 return _context10.stop();
525 }
526 }
527 }, _callee10, this);
528 }));
529
530 function scanUrl(_x18) {
531 return ref.apply(this, arguments);
532 }
533
534 return scanUrl;
535 }()
536 }, {
537 key: 'target',
538 get: function get() {
539 return this.config.get('uri');
540 }
541 }, {
542 key: 'blacklist',
543 get: function get() {
544 return this.config.get('blacklist');
545 }
546 }, {
547 key: 'fingerprint',
548 get: function get() {
549 return this.config.get('fingerprint');
550 }
551 }]);
552 return IsSatire;
553}();
554
555(0, _construct2.default)(IsSatire, [process.argv.slice(2)]);
\No newline at end of file