<commit_before>// Ideas:
//  - support [arrays] and {objects} in serial() and parallel()
//  - support <flow-func>(tasks, callback) syntax, aka async.compatible
//  - select return value from serial(), parallel(), auto() like
//      serial(...).select(1)    // second
//      parallel(...).select(-1) // last
//      auto(...).select('job')  // named
//      // custom synchronous extractor
//      <flow-func>(...).select(function (res) { return res.... })
//  - error/handle to handle errors from serial(), parallel(), auto() like
//      serial(...).error(function (err, callback) {....})
//  - pf.resend(callback, null, results[1]);
//    pf.resend(results[1], callback)
//    pf.send(job_id, callback)
//    pf.sending(job_id, callback)
//
//  Use continuations everywhere? Not possible?
//  This thing is really works best with returning continuation funcs, not node style.
//  But everything is node style :(
//  Another nail is that writing small funcs really suck in return continuation style.
//
//  - Move to async calling style and rename?
//  - Support both styles?
//  - Move to return continuation style? And write a dead library?

// Combinators

exports.waterfall = function () {
    // TODO: check tasks types?
    var tasks = [].slice.call(arguments);

    return function () {
        var args = [].slice.call(arguments);
        var callback = args.pop();
        var index = -1;
        if (typeof callback !== 'function')
            throw TypeError("Can't use " + callback + " as callback")

        function handler(err) {
            if (err) return callback(err);
            index++;
            if (index >= tasks.length) return callback.apply(null, arguments);

            var args = [].slice.call(arguments, 1);
            tasks[index].apply(null, args.concat([handler]))
        }

        handler.apply(null, [null].concat(args));
    }
}

exports.serial = function () {
    var tasks = [].slice.call(arguments);

    return function (callback) {
        var results = [];
        var index = -1;
        if (typeof callback !== 'function')
            throw TypeError("Can't use " + callback + " as callback")

        function handler(err) {
            if (err) return callback(err);
            index++;
            if (index) {
                if (arguments.length <= 2) results.push(arguments[1])
                else results.push([].slice.call(arguments, 1))
            }
            if (index >= tasks.length) return callback(null, results);

            tasks[index](handler);
        }

        handler(null);
    }
}

exports.parallel = function () {
    var tasks = [].slice.call(arguments);

    return function (callback) {
        var left = tasks.length;
        var results = [];
        if (typeof callback !== 'function')
            throw TypeError("Can't use " + callback + " as callback")

        function handler(i) {
            return function (err) {
                if (err) return callback(err);
                left--;
                if (arguments.length <= 2) results[i] = arguments[1]
                else results[i] = [].slice.call(arguments, 1)
                if (!left) return callback(null, results);
            }
        }

        // TODO: handle empty tasks
        for (var i = 0; i < tasks.length; i++) {
            tasks[i](handler(i))
        }
    }
}

exports.manual = function (states) {
    return function () {
        var args = [].slice.call(arguments);
        var next = {};
        var callback = next.end = args.pop();
        if (typeof callback !== 'function')
            throw TypeError("Can't use " + callback + " as callback")

        Object.keys(states).forEach(function (state) {
            next[state] = function (err) {
                if (err) return callback(err)

                var args = [].slice.call(arguments, 1)
                args.push(next)
                states[state].apply(null, args)
            }
        })
        args.push(next);

        states.start.apply(null, args);
    }
}

exports.auto = function (jobs) {
    // TODO: checks if all jobs are reachable
    var defs = {};

    // Parse definition
    Object.keys(jobs).forEach(function (name, i) {
        var def = jobs[name];
        defs[name] = typeof def == 'function'
            ? {deps: [], func: def}
            : {deps: def.slice(0, -1), func: def[def.length - 1]};
    })

    // TODO: handle empty tasks
    return function (callback) {
        var left = Object.keys(jobs).length;
        var run = {};
        var results = {};
        if (typeof callback !== 'function')
            throw TypeError("Can't use " + callback + " as callback")

        function recheck() {
            Object.keys(defs).forEach(function (name) {
                var def = defs[name];
                if (run[name]) return;
                if (def.deps.every(function (dep) { return results.hasOwnProperty(dep) })) {
                    var args = def.deps.map(function (dep) { return results[dep] });
                    args.push(handler(name));
                    run[name] = true;
                    def.func.apply(null, args);
                }
            })
        }

        function handler(name) {
            return function (err) {
                if (err) return callback(err);
                left--;

                if (arguments.length <= 2) results[name] = arguments[1]
                else results[name] = [].slice.call(arguments, 1)
                if (left) recheck()
                else callback(null, results);
            }
        }

        recheck()
    }
}

// Decorators

exports.retry = function (options, func) {
    // handle defaults
    if (typeof options == 'function') {
        func = options
        options = {}
    }
    else if (typeof options == 'number') {
        options = {attempts: options}
    }
    options.attempts = options.attempts || 5;

    // handle timeout
    var timeout = options.timeout;
    var factor = options.factor || 1
    if (typeof options.timeout == 'number') {
        options.timeout = function (attempt) {
            return timeout * Math.pow(factor, attempt - 1)
        }
    }

    return function () {
        var attempt = 0;
        var args = [].slice.call(arguments);
        var callback = args.pop();
        args.push(retry);

        function retry(err) {
            attempt++
            if (err && attempt < options.attempts) {
                if (timeout)
                    setTimeout(function () { func.apply(null, args) }, options.timeout(attempt))
                else
                    func.apply(null, args)
            }
            else
                callback.apply(null, arguments)
        }
        func.apply(null, args)
    }
}

exports.limit = function (options, func) {
    // handle defaults
    if (typeof options == 'number') {
        options = {limit: options}
    }

    var states = {};

    return function () {
        var args = [].slice.call(arguments);
        var callback = args.pop();
        var by = options.by ? options.by.apply(null, args) : '';
        if (!states[by]) states[by] = {running: 0, queue: []};
        var state = states[by];

        function done() {
            state.running--;
            callback.apply(null, arguments);
            if (state.queue.length)
                func.apply(null, state.queue.shift());
        }
        args.push(done);

        if (state.running < options.limit) {
            state.running++;
            func.apply(null, args);
        } else {
            state.queue.push(args);
        }
    }
}

// Collections

exports.map = function (tasks, worker) {
    return exports.parallel.apply(null, tasks.map(function (task) {
        return worker.bind(null, task)
    }))
}
<commit_msg>Provide introspection on limit()<commit_after>// Ideas:
//  - support [arrays] and {objects} in serial() and parallel()
//  - support <flow-func>(tasks, callback) syntax, aka async.compatible
//  - select return value from serial(), parallel(), auto() like
//      serial(...).select(1)    // second
//      parallel(...).select(-1) // last
//      auto(...).select('job')  // named
//      // custom synchronous extractor
//      <flow-func>(...).select(function (res) { return res.... })
//  - error/handle to handle errors from serial(), parallel(), auto() like
//      serial(...).error(function (err, callback) {....})
//  - pf.resend(callback, null, results[1]);
//    pf.resend(results[1], callback)
//    pf.send(job_id, callback)
//    pf.sending(job_id, callback)
//
//  Use continuations everywhere? Not possible?
//  This thing is really works best with returning continuation funcs, not node style.
//  But everything is node style :(
//  Another nail is that writing small funcs really suck in return continuation style.
//
//  - Move to async calling style and rename?
//  - Support both styles?
//  - Move to return continuation style? And write a dead library?

// Combinators

exports.waterfall = function () {
    // TODO: check tasks types?
    var tasks = [].slice.call(arguments);

    return function () {
        var args = [].slice.call(arguments);
        var callback = args.pop();
        var index = -1;
        if (typeof callback !== 'function')
            throw TypeError("Can't use " + callback + " as callback")

        function handler(err) {
            if (err) return callback(err);
            index++;
            if (index >= tasks.length) return callback.apply(null, arguments);

            var args = [].slice.call(arguments, 1);
            tasks[index].apply(null, args.concat([handler]))
        }

        handler.apply(null, [null].concat(args));
    }
}

exports.serial = function () {
    var tasks = [].slice.call(arguments);

    return function (callback) {
        var results = [];
        var index = -1;
        if (typeof callback !== 'function')
            throw TypeError("Can't use " + callback + " as callback")

        function handler(err) {
            if (err) return callback(err);
            index++;
            if (index) {
                if (arguments.length <= 2) results.push(arguments[1])
                else results.push([].slice.call(arguments, 1))
            }
            if (index >= tasks.length) return callback(null, results);

            tasks[index](handler);
        }

        handler(null);
    }
}

exports.parallel = function () {
    var tasks = [].slice.call(arguments);

    return function (callback) {
        var left = tasks.length;
        var results = [];
        if (typeof callback !== 'function')
            throw TypeError("Can't use " + callback + " as callback")

        function handler(i) {
            return function (err) {
                if (err) return callback(err);
                left--;
                if (arguments.length <= 2) results[i] = arguments[1]
                else results[i] = [].slice.call(arguments, 1)
                if (!left) return callback(null, results);
            }
        }

        // TODO: handle empty tasks
        for (var i = 0; i < tasks.length; i++) {
            tasks[i](handler(i))
        }
    }
}

exports.manual = function (states) {
    return function () {
        var args = [].slice.call(arguments);
        var next = {};
        var callback = next.end = args.pop();
        if (typeof callback !== 'function')
            throw TypeError("Can't use " + callback + " as callback")

        Object.keys(states).forEach(function (state) {
            next[state] = function (err) {
                if (err) return callback(err)

                var args = [].slice.call(arguments, 1)
                args.push(next)
                states[state].apply(null, args)
            }
        })
        args.push(next);

        states.start.apply(null, args);
    }
}

exports.auto = function (jobs) {
    // TODO: checks if all jobs are reachable
    var defs = {};

    // Parse definition
    Object.keys(jobs).forEach(function (name, i) {
        var def = jobs[name];
        defs[name] = typeof def == 'function'
            ? {deps: [], func: def}
            : {deps: def.slice(0, -1), func: def[def.length - 1]};
    })

    // TODO: handle empty tasks
    return function (callback) {
        var left = Object.keys(jobs).length;
        var run = {};
        var results = {};
        if (typeof callback !== 'function')
            throw TypeError("Can't use " + callback + " as callback")

        function recheck() {
            Object.keys(defs).forEach(function (name) {
                var def = defs[name];
                if (run[name]) return;
                if (def.deps.every(function (dep) { return results.hasOwnProperty(dep) })) {
                    var args = def.deps.map(function (dep) { return results[dep] });
                    args.push(handler(name));
                    run[name] = true;
                    def.func.apply(null, args);
                }
            })
        }

        function handler(name) {
            return function (err) {
                if (err) return callback(err);
                left--;

                if (arguments.length <= 2) results[name] = arguments[1]
                else results[name] = [].slice.call(arguments, 1)
                if (left) recheck()
                else callback(null, results);
            }
        }

        recheck()
    }
}

// Decorators

exports.retry = function (options, func) {
    // handle defaults
    if (typeof options == 'function') {
        func = options
        options = {}
    }
    else if (typeof options == 'number') {
        options = {attempts: options}
    }
    options.attempts = options.attempts || 5;

    // handle timeout
    var timeout = options.timeout;
    var factor = options.factor || 1
    if (typeof options.timeout == 'number') {
        options.timeout = function (attempt) {
            return timeout * Math.pow(factor, attempt - 1)
        }
    }

    return function () {
        var attempt = 0;
        var args = [].slice.call(arguments);
        var callback = args.pop();
        args.push(retry);

        function retry(err) {
            attempt++
            if (err && attempt < options.attempts) {
                if (timeout)
                    setTimeout(function () { func.apply(null, args) }, options.timeout(attempt))
                else
                    func.apply(null, args)
            }
            else
                callback.apply(null, arguments)
        }
        func.apply(null, args)
    }
}

exports.limit = function (options, func) {
    // handle defaults
    if (typeof options == 'number') {
        options = {limit: options}
    }

    var states = {};
    var limited = function () {
        var args = [].slice.call(arguments);
        var callback = args.pop();
        var by = options.by ? options.by.apply(null, args) : 'only';
        if (!states[by]) states[by] = {running: 0, queue: []};
        var state = states[by];

        function done() {
            state.running--;
            callback.apply(null, arguments);
            if (state.queue.length)
                func.apply(null, state.queue.shift());
        }
        args.push(done);

        if (state.running < options.limit) {
            state.running++;
            func.apply(null, args);
        } else {
            state.queue.push(args);
        }
    }
    limited.states = states;
    if (!options.by) limited.state = states.only = {running: 0, queue: []};

    return limited;
}

// Collections

exports.map = function (tasks, worker) {
    return exports.parallel.apply(null, tasks.map(function (task) {
        return worker.bind(null, task)
    }))
}
<|endoftext|>


<commit_before>module.exports = exports = require('./lib/delve');
<commit_msg>Export the error classes<commit_after>module.exports = require('./lib/delve');
exports.Error = require('./lib/errors');
<|endoftext|>


<commit_before>const fs = require('fs');

let core = null;
try {
  fs.accessSync(__dirname + '/lib/index.js', fs.R_OK);
  core = require('./lib');
  //Use babel polyfill when node version < 8
  if (!global._babelPolyfill && process.version.substr(1, 1) < 8) {
    require('babel-polyfill');
  }
} catch (e) {
  core = require('./src');
}

/**
 * @type {{EvaEngine: EvaEngine, Command: Command, DI, Entities: Entities, engine, express, commands, dependencies: {Joi, constitute, sequelize: ("sequelize".sequelize.SequelizeStatic|"sequelize".sequelize), mysql}, exceptions, middlewares, sequelize: ("sequelize".sequelize.SequelizeStatic|"sequelize".sequelize), Joi, swagger, services, providers: {services, middlewares}, wrapper: ((p1:*)=>(p1?:*, p2?:*, p3?:*)), utils}}
 */
exports = module.exports = core;
<commit_msg>fix: support node v10<commit_after>const fs = require('fs');

let core = null;
try {
  fs.accessSync(__dirname + '/lib/index.js', fs.R_OK);
  core = require('./lib');
  //Use babel polyfill when node version < 8
  if (!global._babelPolyfill && process.version.replace('v', '').split('.')[0] < 8) {
    require('babel-polyfill');
  }
} catch (e) {
  core = require('./src');
}

/**
 * @type {{EvaEngine: EvaEngine, Command: Command, DI, Entities: Entities, engine, express, commands, dependencies: {Joi, constitute, sequelize: ("sequelize".sequelize.SequelizeStatic|"sequelize".sequelize), mysql}, exceptions, middlewares, sequelize: ("sequelize".sequelize.SequelizeStatic|"sequelize".sequelize), Joi, swagger, services, providers: {services, middlewares}, wrapper: ((p1:*)=>(p1?:*, p2?:*, p3?:*)), utils}}
 */
exports = module.exports = core;
<|endoftext|>


<commit_before>#!/usr/bin/env node
const core_parts = {
	core: 'git@github.com:WebArtWork/core.git',
	sem: 'https://github.com/WebArtWork/sem.git'
};
/*
*	Supportive
*/
	const fs = require('fs');
	const git = require('gitty');
	const npmi = require('npmi');
	const isDirectory = source => fs.lstatSync(source).isDirectory();
	const getDirectories = source => {
		if (!fs.existsSync(source)) {
			return [];
		}
		return fs.readdirSync(source).map(name => require('path').join(source, name)).filter(isDirectory);
	}
	const fetch = (folder, repo, cb, branch='master')=>{
		fs.mkdirSync(folder, { recursive: true });
		folder = git(folder);
		folder.init(function(){
			folder.addRemote('origin', repo, function(err){
				folder.fetch('--all', function(err){
					folder.reset('origin/'+branch, cb);
				});
			});
		});
	};
	const parallel = function(arr, callback){
		let counter = arr.length;
		if(counter===0) return callback();
		for (let i = 0; i < arr.length; i++) {
			arr[i](function(){
				if(--counter===0) callback();
			});
		}
	}
/*
*	Variables
*/
	const parts = getDirectories(process.cwd()+'/server');
	const _parts = {};
/*
*	Read Project Config
*/
	let config = {};
	if (fs.existsSync(process.cwd()+'/config.json')) {
		config = JSON.parse(fs.readFileSync(process.cwd()+'/config.json'));
		fs.mkdirSync(process.cwd()+'/client', { recursive: true });
		fs.mkdirSync(process.cwd()+'/server', { recursive: true });
	}
	if (fs.existsSync(process.cwd()+'/server.json')) {
		let serverConfig = fs.readFileSync(process.cwd()+'/server.json');
		for(let each in serverConfig){
			config[each] = serverConfig[each];
		}
	}
/*
*	Execute runners
*/
	const execute_runners = function(){
		const argv = process.argv.slice();
		argv.shift();
		argv.shift();
		if(argv.length){
			let command = argv.shift();
			for (var i = 0; i < parts.length; i++) {
				if(_parts[parts[i]].runner){
					let runners = require(_parts[parts[i]].__root+'/'+_parts[parts[i]].runner);
					if(typeof runners == 'object' && !Array.isArray(runners)){
						for(let each in runners){
							if(each.toLowerCase() == command.toLowerCase()){
								runners[each](argv);
								break;
							}
						}
					}
				}
			}
		}
		process.exit(1);
	}
/*
*	Read Project Parts
*/
	const read_project_parts = function(){
		for (let i = parts.length-1; i >= 0; i--) {
			parts[i] = parts[i].split('\\').pop();
			if (fs.existsSync(process.cwd()+'/server/'+parts[i]+'/part.json')) {
				_parts[parts[i]] = JSON.parse(fs.readFileSync(process.cwd()+'/server/'+parts[i]+'/part.json'));
				_parts[parts[i]].__root = process.cwd()+'/server/'+parts[i];
			}else{
				parts.splice(i, 1);
			}
		}
		for(let each in config.parts){
			if (fs.existsSync(__dirname+'/server/'+each)) {
				if (fs.existsSync(__dirname+'/server/'+each+'/part.json')) {
					parts.unshift(each);
					_parts[each] = JSON.parse(fs.readFileSync(__dirname+'/server/'+each+'/part.json'));
					_parts[each].__root = __dirname+'/server/'+each;
				}
			}
		}
		if(!parts.length){
			for(let each in core_parts){
				if (fs.existsSync(__dirname+'/server/'+each+'/part.json')) {
					parts.unshift(each);
					_parts[each] = JSON.parse(fs.readFileSync(__dirname+'/server/'+each+'/part.json'));
					_parts[each].__root = __dirname+'/server/'+each;
				}
			}
		}
		let installs = [];
		const add_install = function(name, version, path){
			installs.push(function(next){
				npmi({
					name: name,
					version: version,
					path: path,
					forceInstall: true,
					npmLoad: {
						loglevel: 'silent'
					}
				}, next);
			});
		}
		for (var i = 0; i < parts.length; i++) {
			for(let each in _parts[parts[i]].dependencies){
				if (fs.existsSync(_parts[parts[i]].__root+'/node_modules/'+each)) {
					continue;
				}
				add_install(each, _parts[parts[i]].dependencies[each], _parts[parts[i]].__root);
			}
		}
		parallel(installs, execute_runners);
	}
/*
*	Read and Install Common Parts
*/
	let installs = [];
	for(let each in core_parts){
		if (!fs.existsSync(__dirname+'/server/'+each)) {
			installs.push(function(next){
				fetch(__dirname+'/server/'+each, core_parts[each], next);
			});
		}
	}
	parallel(installs, read_project_parts);
/*
*	End of waw
*/<commit_msg>added info to runners<commit_after>#!/usr/bin/env node
const core_parts = {
	core: 'git@github.com:WebArtWork/core.git',
	sem: 'https://github.com/WebArtWork/sem.git'
};
/*
*	Supportive
*/
	const fs = require('fs');
	const git = require('gitty');
	const npmi = require('npmi');
	const isDirectory = source => fs.lstatSync(source).isDirectory();
	const getDirectories = source => {
		if (!fs.existsSync(source)) {
			return [];
		}
		return fs.readdirSync(source).map(name => require('path').join(source, name)).filter(isDirectory);
	}
	const fetch = (folder, repo, cb, branch='master')=>{
		fs.mkdirSync(folder, { recursive: true });
		folder = git(folder);
		folder.init(function(){
			folder.addRemote('origin', repo, function(err){
				folder.fetch('--all', function(err){
					folder.reset('origin/'+branch, cb);
				});
			});
		});
	};
	const parallel = function(arr, callback){
		let counter = arr.length;
		if(counter===0) return callback();
		for (let i = 0; i < arr.length; i++) {
			arr[i](function(){
				if(--counter===0) callback();
			});
		}
	}
/*
*	Variables
*/
	const parts = getDirectories(process.cwd()+'/server');
	const _parts = {};
/*
*	Read Project Config
*/
	const config = {};
	if (fs.existsSync(process.cwd()+'/config.json')) {
		config = JSON.parse(fs.readFileSync(process.cwd()+'/config.json'));
		fs.mkdirSync(process.cwd()+'/client', { recursive: true });
		fs.mkdirSync(process.cwd()+'/server', { recursive: true });
	}
	if (fs.existsSync(process.cwd()+'/server.json')) {
		let serverConfig = fs.readFileSync(process.cwd()+'/server.json');
		for(let each in serverConfig){
			config[each] = serverConfig[each];
		}
	}
/*
*	Execute runners
*/
	const execute_runners = function(){
		const argv = process.argv.slice();
		argv.shift();
		argv.shift();
		if(argv.length){
			let command = argv.shift();
			for (var i = 0; i < parts.length; i++) {
				if(_parts[parts[i]].runner){
					let runners = require(_parts[parts[i]].__root+'/'+_parts[parts[i]].runner);
					if(typeof runners == 'object' && !Array.isArray(runners)){
						for(let each in runners){
							if(each.toLowerCase() == command.toLowerCase()){
								runners[each](argv, config, _parts[parts[i]], process.cwd(), _parts[parts[i]].__root, __dirname);
								break;
							}
						}
					}
				}
			}
		}
		process.exit(1);
	}
/*
*	Read Project Parts
*/
	const read_project_parts = function(){
		for (let i = parts.length-1; i >= 0; i--) {
			parts[i] = parts[i].split('\\').pop();
			if (fs.existsSync(process.cwd()+'/server/'+parts[i]+'/part.json')) {
				_parts[parts[i]] = JSON.parse(fs.readFileSync(process.cwd()+'/server/'+parts[i]+'/part.json'));
				_parts[parts[i]].__root = process.cwd()+'/server/'+parts[i];
			}else{
				parts.splice(i, 1);
			}
		}
		for(let each in config.parts){
			if (fs.existsSync(__dirname+'/server/'+each)) {
				if (fs.existsSync(__dirname+'/server/'+each+'/part.json')) {
					parts.unshift(each);
					_parts[each] = JSON.parse(fs.readFileSync(__dirname+'/server/'+each+'/part.json'));
					_parts[each].__root = __dirname+'/server/'+each;
				}
			}
		}
		if(!parts.length){
			for(let each in core_parts){
				if (fs.existsSync(__dirname+'/server/'+each+'/part.json')) {
					parts.unshift(each);
					_parts[each] = JSON.parse(fs.readFileSync(__dirname+'/server/'+each+'/part.json'));
					_parts[each].__root = __dirname+'/server/'+each;
				}
			}
		}
		let installs = [];
		const add_install = function(name, version, path){
			installs.push(function(next){
				npmi({
					name: name,
					version: version,
					path: path,
					forceInstall: true,
					npmLoad: {
						loglevel: 'silent'
					}
				}, next);
			});
		}
		for (var i = 0; i < parts.length; i++) {
			for(let each in _parts[parts[i]].dependencies){
				if (fs.existsSync(_parts[parts[i]].__root+'/node_modules/'+each)) {
					continue;
				}
				add_install(each, _parts[parts[i]].dependencies[each], _parts[parts[i]].__root);
			}
		}
		parallel(installs, execute_runners);
	}
/*
*	Read and Install Common Parts
*/
	let installs = [];
	for(let each in core_parts){
		if (!fs.existsSync(__dirname+'/server/'+each)) {
			installs.push(function(next){
				fetch(__dirname+'/server/'+each, core_parts[each], next);
			});
		}
	}
	parallel(installs, read_project_parts);
/*
*	End of waw
*/<|endoftext|>


<commit_before>'use strict';
const _ = require('lodash');
const fs = require('fs');
const csv = require('./lib/csv-parser.js');
const urls = require('./lib/url-generator.js');
const http = require('./lib/request.js');
const util = require('./lib/util.js');
const casher = require('./lib/casher.js');
const Promise = require('bluebird');

const getSP500 = () => {
  return util.loadFileContent(`${__dirname}/resources/SP500.csv`)
  .then(csv.jsonCSV)
  .then(metas => _.filter(metas, meta => _.has(meta, 'ticker') && meta.ticker !== ''));
};

const requestStock = (metadata) => {
  let url = urls.createWikiUrl(metadata);
  return http.request(url);
};

const cacheStock = (data, metadata) => {
  return util.writeFileContent(`${__dirname}/resources/cached/${metadata.ticker}.json`, data);
}

const timeoutRequestStock = (metas, delay) => {
  setTimeout(() => {
    let metadata = metas.shift();
    // console.log('metadata', metadata);
    // console.log('metas.length', metas.length);
    requestStock(metadata)
      .then(data => cacheStock(data, metadata))
      .then(() => {
        console.log('saved');
        if(metas.length > 0) {
          timeoutRequestStock(metas, delay);
        } else {
          console.log('all parsed!');
        }
      })
      .catch((err) => {
        console.log(err, metadata);
      });
  }, delay);
};

const getAllFreeCodeStocksOfSP500 = (delay, startTicker) => {
  return getSP500()
    .then(metas => _.filter(metas, meta => _.has(meta, 'free_code')))
    .then((metas) => {
      if(startTicker) {
        let index = _.findIndex(metas, { ticker: startTicker });
        return _.slice(metas, index);
      }
      return metas;
    });
};

const cacheAllFreecodeStocksOfSP500 = (delay, startTicker) => {
  return getAllFreeCodeStocksOfSP500(delay, startTicker)
    // .then(metas => _.filter(metas, meta => _.includes(meta.ticker, '-')))
    .then((metas) => {
      console.log(metas.length);
      timeoutRequestStock(metas, delay);
    })
    .catch(console.log);
};

// cacheAllFreecodeStocksOfSP500(200);

// console.log(require('./resources/cached/CAT.json'));

const stockMarket = require('./analysis.js');

const testStockGetData = () => {
  return getSP500()
  .then(stockMarket)
  .then((stocks) => {
    let stock =  stocks.getStock({ ticker: 'AAPL' });
    return stock;
  })
  .then((stock) => {
    return stock.getData(['Date', 'Close', 'Ex-Dividend']);
  })
  .then(console.log)
  .catch(console.log);
}

const createStockCubeFile = () => {
  let market;
  return getSP500()
  .then(stockMarket)
  .then(instance => market = instance)
  .then(() => market.getStocksByMetas())
  .then(stocks => market.getUniqueDates(stocks))
  .then(dates => casher.createStockCubeFile(`${__dirname}/resources/aggregation/SP500/index.json`, dates))
  .then(console.log)
  .catch(console.log);
}

// createStockCubeFile();

const loadStockCube = () => {
  return util.loadFileContent(`${__dirname}/resources/aggregation/SP500/index.json`)
  .then(JSON.parse);
}

const loadSP500Market = () => {
  return getSP500()
  .then(stockMarket);
}

const getUncrawledStockMetas = (cube, market) => {
  let crawledTickers = _.map(cube.tickers, 'ticker');
  let metas = market.getMetas();
  return _.filter(metas, (meta) => {
    return _.includes(crawledTickers, meta.ticker) === false;
  });
}

const crawlSP500Index = () => {
  return Promise.all([loadStockCube(), loadSP500Market()])
  .then(([cube, market]) => {
    let metas = getUncrawledStockMetas(cube, market);
    // _.forEach(metas, (meta) => {
    //
    // });
  })
  .then(console.log)
  .catch(console.log);
}

crawlSP500Index();
<commit_msg>update<commit_after>'use strict';
const _ = require('lodash');
const fs = require('fs');
const csv = require('./lib/csv-parser.js');
const urls = require('./lib/url-generator.js');
const http = require('./lib/request.js');
const util = require('./lib/util.js');
const casher = require('./lib/casher.js');
const Promise = require('bluebird');

const getSP500 = () => {
  return util.loadFileContent(`${__dirname}/resources/SP500.csv`)
  .then(csv.jsonCSV)
  .then(metas => _.filter(metas, meta => _.has(meta, 'ticker') && meta.ticker !== ''));
};

const requestStock = (metadata) => {
  let url = urls.createWikiUrl(metadata);
  return http.request(url);
};

const cacheStock = (data, metadata) => {
  return util.writeFileContent(`${__dirname}/resources/cached/${metadata.ticker}.json`, data);
}

const timeoutRequestStock = (metas, delay) => {
  setTimeout(() => {
    let metadata = metas.shift();
    // console.log('metadata', metadata);
    // console.log('metas.length', metas.length);
    requestStock(metadata)
      .then(data => cacheStock(data, metadata))
      .then(() => {
        console.log('saved');
        if(metas.length > 0) {
          timeoutRequestStock(metas, delay);
        } else {
          console.log('all parsed!');
        }
      })
      .catch((err) => {
        console.log(err, metadata);
      });
  }, delay);
};

const getAllFreeCodeStocksOfSP500 = (delay, startTicker) => {
  return getSP500()
    .then(metas => _.filter(metas, meta => _.has(meta, 'free_code')))
    .then((metas) => {
      if(startTicker) {
        let index = _.findIndex(metas, { ticker: startTicker });
        return _.slice(metas, index);
      }
      return metas;
    });
};

const cacheAllFreecodeStocksOfSP500 = (delay, startTicker) => {
  return getAllFreeCodeStocksOfSP500(delay, startTicker)
    // .then(metas => _.filter(metas, meta => _.includes(meta.ticker, '-')))
    .then((metas) => {
      console.log(metas.length);
      timeoutRequestStock(metas, delay);
    })
    .catch(console.log);
};

// cacheAllFreecodeStocksOfSP500(200);

// console.log(require('./resources/cached/CAT.json'));

const stockMarket = require('./analysis.js');

const testStockGetData = () => {
  return getSP500()
  .then(stockMarket)
  .then((stocks) => {
    let stock =  stocks.getStock({ ticker: 'AAPL' });
    return stock;
  })
  .then((stock) => {
    return stock.getData(['Date', 'Close', 'Ex-Dividend']);
  })
  .then(console.log)
  .catch(console.log);
}

const createStockCubeFile = () => {
  let market;
  return getSP500()
  .then(stockMarket)
  .then(instance => market = instance)
  .then(() => market.getStocksByMetas())
  .then(stocks => market.getUniqueDates(stocks))
  .then(dates => casher.createStockCubeFile(`${__dirname}/resources/aggregation/SP500/index.json`, dates))
  .then(console.log)
  .catch(console.log);
}

// createStockCubeFile();

const loadStockCube = () => {
  return util.loadFileContent(`${__dirname}/resources/aggregation/SP500/index.json`)
  .then(JSON.parse);
}

const loadSP500Market = () => {
  return getSP500()
  .then(stockMarket);
}

const getUncrawledStockMetas = (cube, market) => {
  let crawledTickers = _.map(cube.tickers, 'ticker');
  let metas = market.getMetas();
  return _.filter(metas, (meta) => {
    return _.includes(crawledTickers, meta.ticker) === false;
  });
}

const crawlSP500Index = () => {
  let allDates, market;
  return Promise.all([loadStockCube(), loadSP500Market()])
  .then(([cube, marketInstance]) => {
    market = marketInstance;
    let metas = getUncrawledStockMetas(cube, market);
    metas = _.take(metas, 10);
    return Promise.all(_.map(metas, meta => market.getStock(meta)));
  })
  .then((stocks) => {
    allDates = market.getUniqueDates(stocks);
    console.log('allDates.length', allDates.length);
    return stocks;
  })
  .then((stocks) => {
    return _.map(stocks, stock => stock.fitCloseDataBy(allDates));
  })
  .then((dataset) => {
    // return _.sum(_.map(dataset, _.sum));
    let range = _.range(dataset.length);
    return _.map(allDates, (date, index) => {
      return _.sum(_.map(range, slot => dataset[slot][index]));
    });
  })
  .then(index => _.slice(index, -10))
  .then(console.log)
  .catch(console.log);
}

crawlSP500Index();

// getSP500()
// .then(stockMarket)
// .then(console.log)
// .catch(console.log);
<|endoftext|>


<commit_before>
/**
 * Module dependencies.
 */
import WPError from 'wp-error';
import superagent from 'superagent';
import debugFactory from 'debug';

/**
 * Module variables
 */
const debug = debugFactory( 'wpcom-xhr-request' );

/**
 * WordPress.com REST API base endpoint.
 */
let proxyOrigin = 'https://public-api.wordpress.com';

/**
 * Default WordPress.com REST API Version.
 */
const defaultApiVersion = '1';

/**
 * Performs an XMLHttpRequest against the WordPress.com REST API.
 *
 * @param {Object|String} originalParams - request parameters
 * @param {Function} fn - callback function
 * @return { XHR } xhr instance
 * @api public
 */
export default function request( originalParams, fn ) {
	let params = Object.assign( {}, originalParams );

	if ( 'string' === typeof params ) {
		params = { path: params };
	}

	// method
	const requestMethod = ( params.method || 'GET' ).toLowerCase();
	debug( 'API HTTP Method: %o', requestMethod );
	delete params.method;

	// apiNamespace (WP-API)
	const { apiNamespace } = params;
	delete params.apiNamespace;

	// apiVersion (REST-API)
	const apiVersion = params.apiVersion || defaultApiVersion;
	delete params.apiVersion;

	// proxyOrigin
	proxyOrigin = params.proxyOrigin || proxyOrigin;
	delete params.proxyOrigin;

	// request base path
	let basePath = '/rest/v' + apiVersion;

	// If this is a WP-API request, adjust basePath
	if ( apiNamespace && /\//.test( apiNamespace ) ) {
		// New-style WP-API URL: /wpcom/v2/sites/%s/post-counts
		basePath = '/' + apiNamespace;
	} else if ( apiNamespace ) {
		// Old-style WP-API URL (deprecated): /wp-json/sites/%s/wpcom/v2/post-counts
		basePath = '/wp-json';
	}

	// is REST-API api?
	const isRestAPI = apiNamespace === undefined;

	// Envelope mode FALSE as default
	let isEnvelopeMode = false;

	// process response in evelope mode TRUE as default
	const processResponseInEnvelopeMode = params.processResponseInEnvelopeMode !== false;

	const url = proxyOrigin + basePath + params.path;
	debug( 'API URL: %o', url );
	delete params.path;

	// create HTTP Request object
	const req = superagent[ requestMethod ]( url );

	// Token authentication
	if ( params.authToken ) {
		req.set( 'Authorization', 'Bearer ' + params.authToken );
		delete params.authToken;
	}

	// URL querystring values
	if ( params.query ) {
		req.query( params.query );
		debug( 'API send URL querystring: %o', params.query );

		isEnvelopeMode = isRestAPI
			? params.query.http_envelope
			: params.query._envelope;

		delete params.query;
	}

	// POST API request body
	if ( params.body ) {
		req.send( params.body );
		debug( 'API send POST body: %o', params.body );
		delete params.body;
	}

	// POST FormData (for `multipart/form-data`, usually a file upload)
	if ( params.formData ) {
		for ( let i = 0; i < params.formData.length; i++ ) {
			const data = params.formData[ i ];
			const key = data[ 0 ];
			const value = data[ 1 ];
			debug( 'adding FormData field %o', key );
			req.field( key, value );
		}
	}

	const requestHeaders = params.headers || {};
	for ( const key in requestHeaders ) {
		const value = requestHeaders[ key ];
		debug( 'adding HTTP header %o: %o', key, value );
		req.set( key, value );
	}

	if ( ! req.get( 'Accept' ) ) {
		// set a default "Accept" header preferring a JSON response
		req.set( 'Accept', '*/json,*/*' );
	}

	// start the request
	req.end( ( error, response ) => {
		if ( error && ! response ) {
			return fn( error );
		}

		let { body, headers, statusCode } = response;
		const { ok } = response;
		const { path, method } = response.req;
		headers.status = statusCode;

		debug( '%o -> %o headers', url, headers );
		debug( '%o -> %o status code', url, statusCode );

		if ( ok ) {
			if ( isEnvelopeMode && processResponseInEnvelopeMode ) {
				debug( 'processing response in envelope mode' );

				if ( isRestAPI ) {
					// in the REST-API the response comes wrapped in `code`, `headers` and `body` fields
					headers = body.headers;
					statusCode = body.code;
					body = body.body;
				} else {
					// in the WP-API the response comes wrapped in `body`, `status` and `headers`
					headers = body.headers;
					statusCode = body.status;
					body = body.body;
				}

				// let's add the status into the headers
				headers.status = statusCode;

				if ( null !== statusCode && 2 !== Math.floor( statusCode / 100 ) ) {
					debug( 'Error detected!' );
					const wpe = WPError( { path, method }, statusCode, body );
					return fn( wpe, null, headers );
				}
			}
			return fn( null, body, headers );
		}

		const wpe = WPError( { path, method }, statusCode, body );
		return fn( wpe, null, headers );
	} );

	return req.xhr;
}
<commit_msg>core: refact core using ES2015<commit_after>
/**
 * Module dependencies.
 */
import WPError from 'wp-error';
import superagent from 'superagent';
import debugFactory from 'debug';

/**
 * Module variables
 */
const debug = debugFactory( 'wpcom-xhr-request' );

/**
 * Defauts
 */
const defaults = {
	apiVersion: '1',
	apiNamespace: 'wp/v2',
	authToken: null,
	body: null,
	formData: null,
	headers: null,
	method: 'get',
	query: null,
	processResponseInEnvelopeMode: true,
	proxyOrigin: 'https://public-api.wordpress.com',
	url: ''
};

/**
 * Send the request
 *
 * @param  {Superagent} req - request instance
 * @param  {Object} settings - request settings
 * @param  {Function} fn - callback function
 * @return {Superagent} request instance
 */
const sendResponse = ( req, settings, fn ) => {
	const {
		isEnvelopeMode,
		isRestAPI,
		processResponseInEnvelopeMode
	} = settings;

	req.end( ( error, response ) => {
		if ( error && ! response ) {
			return fn( error );
		}

		let { body, headers, statusCode } = response;

		const { ok } = response;
		const { path, method } = response.req;
		headers.status = statusCode;

		if ( ok ) {
			if ( isEnvelopeMode && processResponseInEnvelopeMode ) {
				// override `error`, body` and `headers`
				if ( isRestAPI ) {
					headers = body.headers;
					statusCode = body.code;
					body = body.body;
				} else {
					headers = body.headers;
					statusCode = body.status;
					body = body.body;
				}

				headers.status = statusCode;

				if ( null !== statusCode && 2 !== Math.floor( statusCode / 100 ) ) {
					debug( 'Error detected!' );
					const wpe = WPError( { path, method }, statusCode, body );
					return fn( wpe, null, headers );
				}
			}
			return fn( null, body, headers );
		}

		const wpe = WPError( { path, method }, statusCode, body );
		return fn( wpe, null, headers );
	} );

	return req;
};

/**
 * Performs an XMLHttpRequest against the WordPress.com REST API.
 *
 * @param {Object|String} options - `request path` or `request parameters`
 * @param {Function} fn - callback function
 * @return { XHR } xhr instance
 * @api public
 */
export default function request( options, fn ) {
	if ( 'string' === typeof options ) {
		options = { path: options };
	}

	const settings = Object.assign( {}, defaults, options );

	// is REST-API api?
	settings.isRestAPI = options.apiNamespace === undefined;

	// normalize request-method name
	settings.method = settings.method.toLowerCase();

	const {
		apiNamespace,
		apiVersion,
		authToken,
		body,
		formData,
		headers,
		isRestAPI,
		method,
		query,
		proxyOrigin
	} = settings;

	// request base path
	let basePath;

	if ( isRestAPI ) {
		basePath = `/rest/v${ apiVersion }`;
	} else if ( apiNamespace && /\//.test( apiNamespace ) ) {
		basePath = '/' + apiNamespace;	// wpcom/v2
	} else {
		basePath = '/wp-json'; // /wp-json/sites/%s/wpcom/v2 (deprecated)
	}

	// Envelope mode FALSE as default
	settings.isEnvelopeMode = false;

	settings.url = proxyOrigin + basePath + settings.path;
	debug( 'API URL: %o', settings.url );

	// create HTTP Request instance
	const req = superagent[ method ]( settings.url );

	// querystring
	if ( query ) {
		req.query( query );
		debug( 'API send URL querystring: %o', query );

		settings.isEnvelopeMode = isRestAPI ? query.http_envelope : query._envelope;
		debug( 'envelope mode: %o', settings.isEnvelopeMode );
	}

	// body
	if ( body ) {
		req.send( body );
		debug( 'API send POST body: %o', body );
	}

	// POST FormData (for `multipart/form-data`, usually a file upload)
	if ( formData ) {
		for ( let i = 0; i < formData.length; i++ ) {
			const data = formData[ i ];
			const key = data[ 0 ];
			const value = data[ 1 ];
			debug( 'adding FormData field %o: %o', key, value );
			req.field( key, value );
		}
	}

	// headers
	if ( headers ) {
		req.set( headers );
		debug( 'adding HTTP headers: %o', headers );
	}

	if ( authToken ) {
		req.set( 'Authorization', `Bearer ${ authToken }` );
	}

	if ( ! req.get( 'Accept' ) ) {
		// set a default "Accept" header preferring a JSON response
		req.set( 'Accept', '*/json,*/*' );
	}

	sendResponse( req, settings, fn );

	return req.xhr;
}
<|endoftext|>


<commit_before>#! /usr/bin/env node

// ==============================
// MODULES
// ==============================
var tpb 		= require('thepiratebay');
var strike 		= require('strike-api');
var spawn 		= require('child_process').spawn;
var exec 		= require('child_process').exec;
var inquirer 	= require('inquirer');
var program 	= require('commander');
var tStream 	= require('torrent-stream');
var jf			= require('jsonfile');
var Promise		= require('bluebird');
var moment 		= require('moment');
var db 			= require('text-db')('storage');

// ==============================
// VARIABLES
// ==============================
/*
 * value of each key corresponds to tpb search query options
 * 1 - name descending
 * 2 - name ascending
 * 3 - date descending
 * 4 - date ascending
 * 5 - size descending
 * 6 - size ascending
 * 7 - seeds descending
 * 8 - seeds ascending
 * 9 - leeches descending
 * 10 - leeches ascending
 */
var orderEnum = {
	NAME: '1',
	DATE: '4',
	SIZE: '5',
	SEEDS: '7',
	LEECHES: '10'
}

// ==============================
// FUNCTIONS
// ==============================

/*
 * @param: magnet - a magnet link to save
 * Saves a magnet link to file for future retrieval
 */
function enableMarathon(magnet) {
	db.setItem("marathonMagnet", magnet);
	console.log("Enabled marathon! Just run `termflix marathon` to select the next file!");
}

/*
 * @param: args - the arguments the user entered
 * Starts streaming the torrent using peerflix
 */
function playMagnet(args) {
	var magnet = args[0];
	var engine = tStream(magnet);

	engine.on('ready', function() {
		if (engine.files.length > 1) {
			// var fileIndexHash = [];
			var fileNames = [];
			var fileHash = [];
			var subtitleFileNames = [];
			engine.files.forEach(function(file, i){
				fileHash[file.name] = file;
				// fileIndexHash[file.name] = i;
				fileNames.push(file.name);
				if (file.name.slice(file.name.length - 4) == '.srt') {
					subtitleFileNames.push(file.name);
				}
			});
			var questions = [
				{
					type: 'list',
					name: 'fileName',
					message: 'Which file from this torrent do you want to play?',
					choices: fileNames
				},
				{
					type: 'confirm',
					name: 'enableMarathon',
					message: 'Enable marathon mode for these files?',
					default: true
				}
			];

			inquirer.prompt(questions, function(answers) {
				var file = answers.fileName;
				// var fileIndex = fileIndexHash[file];
				var fileIndex = fileNames.indexOf(file);
				args.push('--index=' + fileIndex);

				if (answers.enableMarathon) {
					enableMarathon(magnet);
				}

				// if (answers.addSubtitle) {
				// 	fileHash[subtitleFileNames[0]].select();
				// 	args.push('--subtitles \"/tmp/torrent-stream/%s\"', fileHash[subtitleFileNames[0]].path)
				// }

				// if (answers.wantsSubtitle) {
				// 	var subtitleFile = answers.subtitleFile;
				// }

				// return args;
				var cmd = spawn('peerflix', args);
				cmd.stdout.pipe(process.stdout);
				cmd.stderr.pipe(process.stdout);
			});
		} else {
			// return args;
			var cmd = spawn('peerflix', args);
			cmd.stdout.pipe(process.stdout);
			cmd.stderr.pipe(process.stdout);
		}
	});
}

/*
 * Gets the saved marathon torrent and lets the user pick which file within the folder to play.
 * Prints out a message if there is no saved marathon magnet.
 */
function marathonCommand() {
	var magnet = db.getItem("marathonMagnet");

	if (magnet != undefined) {
		playMagnet([magnet, '--vlc']);
	} else {
		console.log("Sorry, you probably haven't enabled marathon mode for any torrent folder yet!");
	}
}

/*
 * @param: magnet - a magnet link for a torrent
 * @param: options - an options object
 * Starts streaming the torrent form a magnet link and passes
 * any options off to the playMagnet function
 */
function playCommand(magnet, options) {
	var ops = options.parent.rawArgs.splice(4);
	var playArgs = [magnet, '--remove'];
	ops.forEach(function(op) {
		playArgs.push(op);
	});
	playMagnet(playArgs);
}

/*
 * @param: orderOption - the optin string entered with --option
 * @return: an object with "order" and "infoField" fields
 * Converts the given orderOption to the corrent order enum type. Also chooses
 * the right name for infoField based on what name the torrent search api uses
 * for the given orderOption.
 */
function convertOrder(orderOption) {

	orderObj = {};

	switch (orderOption) {
		case 'name':
			orderObj.order = orderEnum.NAME;
			orderObj.infoField = 'torrent_title';
			break;
		case 'date':
			orderObj.order = orderEnum.DATE;
			orderObj.infoField = 'upload_date';
			break;
		case 'size':
			orderObj.order = orderEnum.SIZE;
			orderObj.infoField = 'size';
			break;
		case 'seeds':
			orderObj.order = orderEnum.SEEDS;
			orderObj.infoField = 'seeds';
			break;
		case 'leeches':
			orderObj.order = orderEnum.LEECHES;
			orderObj.infoField = 'leeches';
			break;
		default:
			orderObj.order = orderEnum.SEEDS;
			orderObj.infoField = 'seeds';
	}

	return orderObj;
}

/*
 * @param: order - an order enum type
 * @param: infoField - the info field corresponding to the order enum
 * @param: torrents - an array of torrent objects
 * @return: a sorted array of torrent objects
 * Sorts the torrents in the torrent object by the given order.
 */
function sortTorrents(order, infoField, torrents) {
	sortedTorrents = [];
	if (order == orderEnum.DATE) {
		torrents.forEach(function(torrent) {
			var date = moment(torrent[infoField], "MMM DD, YYYY");
			sortedTorrents.push({
				torrent: torrent,
				sortValue: date.valueOf()
			});
		});
	} else {
		torrents.forEach(function(torrent) {
			sortedTorrents.push({
				torrent: torrent,
				sortValue: torrent[infoField]
			});
		})
	}

	if (order == orderEnum.NAME || order == orderEnum.LEECHES) {
		sortedTorrents.sort(function(a, b) {
			if (a.sortValue > b.sortValue) {
				return 1;
			}
			if (a.sortValue < b.sortValue) {
				return -1;
			}
			return 0;
		});
	} else {
		sortedTorrents.sort(function(a, b) {
			if (a.sortValue > b.sortValue) {
				return -1;
			}
			if (a.sortValue < b.sortValue) {
				return 1;
			}
			return 0;
		});
	}

	result = [];
	sortedTorrents.forEach(function(torrent) {
		result.push(torrent.torrent);
	});
	return result;
}

/*
 * @param: query - the search query the user entered
 * @param: options - an options object
 * Searches the pirate bay for videos with the given query and returns
 * a list of torrent objects
 */
function searchCommand(query, options) {
	var torrentHash = [];
	var torrentInfos = [];
	var orderBy = options.order;
	var infoField = convertOrder(orderBy).infoField;
	var order = convertOrder(orderBy).order;

	strike.search(query).then(function(res) {
		var results = res.torrents;
		if (results.length == 0) {
			inquirer.prompt([
				{
					type: 'input',
					name: 'title',
					message: 'Sorry, 0 results. Enter new search: ',

				}
			], function(answers) {
					searchCommand(answers.title, options);
			});
		} else {
			results = sortTorrents(order, infoField, results);
			results.forEach(function(result) {
				torrentHash[result.torrent_title] = result.magnet_uri;
				if (order == orderEnum.NAME) {
					torrentInfos.push(result.torrent_title + ' :: ');
				} else {
					torrentInfos.push(result.torrent_title + ' :: ' + result[infoField]);
				}
			});

			inquirer.prompt([
				{
					type: 'list',
					name: 'title',
					message: 'Which torrent do you want to stream?',
					choices: torrentInfos
				}
			], function(answers) {
				var title = answers.title;
				var titleString = title.substring(0, title.indexOf(' :: '));
				playMagnet([torrentHash[titleString], '--vlc']);
			});
		}
	});
}

// ==============================
// COMMANDS
// ==============================
program
	.version('0.1.0');

program
	.command('play [magnet]')
	.description('stream a torrent file with the given magnet link')
	.option('-v, --vlc', 'open the torrent stream with vlc player')
	.action(function(magnet, options) {
		playCommand(magnet, options);
	});
program
	.command('search [query]')
	.description('search the pirate bay with a query')
	.option('-o, --order [orderBy]',
		'order results by a given field:' +
		'seeds (default) | name | date | size | leeches')
	.action(function(query, options) {
		searchCommand(query, options);
	});
program
	.command('marathon')
	.description("if you've enabled a marthon, this will let you select the next file to watch in a folder")
	.action(function() {
		marathonCommand();
	});

program.parse(process.argv);
<commit_msg>Explicitly close torrent engine on quit<commit_after>#! /usr/bin/env node

// ==============================
// MODULES
// ==============================
var tpb 		= require('thepiratebay');
var strike 		= require('strike-api');
var spawn 		= require('child_process').spawn;
var exec 		= require('child_process').exec;
var inquirer 	= require('inquirer');
var program 	= require('commander');
var tStream 	= require('torrent-stream');
var jf			= require('jsonfile');
var Promise		= require('bluebird');
var moment 		= require('moment');
var db 			= require('text-db')('storage');

// ==============================
// VARIABLES
// ==============================
/*
 * value of each key corresponds to tpb search query options
 * 1 - name descending
 * 2 - name ascending
 * 3 - date descending
 * 4 - date ascending
 * 5 - size descending
 * 6 - size ascending
 * 7 - seeds descending
 * 8 - seeds ascending
 * 9 - leeches descending
 * 10 - leeches ascending
 */
var orderEnum = {
	NAME: '1',
	DATE: '4',
	SIZE: '5',
	SEEDS: '7',
	LEECHES: '10'
}

var engine;

// ==============================
// FUNCTIONS
// ==============================

/*
 * @param: magnet - a magnet link to save
 * Saves a magnet link to file for future retrieval
 */
function enableMarathon(magnet) {
	db.setItem("marathonMagnet", magnet);
	console.log("Enabled marathon! Just run `termflix marathon` to select the next file!");
}

/*
 * @param: args - the arguments the user entered
 * Starts streaming the torrent using peerflix
 */
function playMagnet(args) {
	var magnet = args[0];
	engine = tStream(magnet);

	engine.on('ready', function() {
		if (engine.files.length > 1) {
			// var fileIndexHash = [];
			var fileNames = [];
			var fileHash = [];
			var subtitleFileNames = [];
			engine.files.forEach(function(file, i){
				fileHash[file.name] = file;
				// fileIndexHash[file.name] = i;
				fileNames.push(file.name);
				if (file.name.slice(file.name.length - 4) == '.srt') {
					subtitleFileNames.push(file.name);
				}
			});
			var questions = [
				{
					type: 'list',
					name: 'fileName',
					message: 'Which file from this torrent do you want to play?',
					choices: fileNames
				},
				{
					type: 'confirm',
					name: 'enableMarathon',
					message: 'Enable marathon mode for these files?',
					default: true
				}
			];

			inquirer.prompt(questions, function(answers) {
				var file = answers.fileName;
				// var fileIndex = fileIndexHash[file];
				var fileIndex = fileNames.indexOf(file);
				args.push('--index=' + fileIndex);

				if (answers.enableMarathon) {
					enableMarathon(magnet);
				}

				// if (answers.addSubtitle) {
				// 	fileHash[subtitleFileNames[0]].select();
				// 	args.push('--subtitles \"/tmp/torrent-stream/%s\"', fileHash[subtitleFileNames[0]].path)
				// }

				// if (answers.wantsSubtitle) {
				// 	var subtitleFile = answers.subtitleFile;
				// }

				// return args;
				var cmd = spawn('peerflix', args);
				cmd.stdout.pipe(process.stdout);
				cmd.stderr.pipe(process.stdout);
			});
		} else {
			// return args;
			var cmd = spawn('peerflix', args);
			cmd.stdout.pipe(process.stdout);
			cmd.stderr.pipe(process.stdout);
		}
	});
}

/*
 * Gets the saved marathon torrent and lets the user pick which file within the folder to play.
 * Prints out a message if there is no saved marathon magnet.
 */
function marathonCommand() {
	var magnet = db.getItem("marathonMagnet");

	if (magnet != undefined) {
		playMagnet([magnet, '--vlc']);
	} else {
		console.log("Sorry, you probably haven't enabled marathon mode for any torrent folder yet!");
	}
}

/*
 * @param: magnet - a magnet link for a torrent
 * @param: options - an options object
 * Starts streaming the torrent form a magnet link and passes
 * any options off to the playMagnet function
 */
function playCommand(magnet, options) {
	var ops = options.parent.rawArgs.splice(4);
	var playArgs = [magnet, '--remove'];
	ops.forEach(function(op) {
		playArgs.push(op);
	});
	playMagnet(playArgs);
}

/*
 * @param: orderOption - the optin string entered with --option
 * @return: an object with "order" and "infoField" fields
 * Converts the given orderOption to the corrent order enum type. Also chooses
 * the right name for infoField based on what name the torrent search api uses
 * for the given orderOption.
 */
function convertOrder(orderOption) {

	orderObj = {};

	switch (orderOption) {
		case 'name':
			orderObj.order = orderEnum.NAME;
			orderObj.infoField = 'torrent_title';
			break;
		case 'date':
			orderObj.order = orderEnum.DATE;
			orderObj.infoField = 'upload_date';
			break;
		case 'size':
			orderObj.order = orderEnum.SIZE;
			orderObj.infoField = 'size';
			break;
		case 'seeds':
			orderObj.order = orderEnum.SEEDS;
			orderObj.infoField = 'seeds';
			break;
		case 'leeches':
			orderObj.order = orderEnum.LEECHES;
			orderObj.infoField = 'leeches';
			break;
		default:
			orderObj.order = orderEnum.SEEDS;
			orderObj.infoField = 'seeds';
	}

	return orderObj;
}

/*
 * @param: order - an order enum type
 * @param: infoField - the info field corresponding to the order enum
 * @param: torrents - an array of torrent objects
 * @return: a sorted array of torrent objects
 * Sorts the torrents in the torrent object by the given order.
 */
function sortTorrents(order, infoField, torrents) {
	sortedTorrents = [];
	if (order == orderEnum.DATE) {
		torrents.forEach(function(torrent) {
			var date = moment(torrent[infoField], "MMM DD, YYYY");
			sortedTorrents.push({
				torrent: torrent,
				sortValue: date.valueOf()
			});
		});
	} else {
		torrents.forEach(function(torrent) {
			sortedTorrents.push({
				torrent: torrent,
				sortValue: torrent[infoField]
			});
		})
	}

	if (order == orderEnum.NAME || order == orderEnum.LEECHES) {
		sortedTorrents.sort(function(a, b) {
			if (a.sortValue > b.sortValue) {
				return 1;
			}
			if (a.sortValue < b.sortValue) {
				return -1;
			}
			return 0;
		});
	} else {
		sortedTorrents.sort(function(a, b) {
			if (a.sortValue > b.sortValue) {
				return -1;
			}
			if (a.sortValue < b.sortValue) {
				return 1;
			}
			return 0;
		});
	}

	result = [];
	sortedTorrents.forEach(function(torrent) {
		result.push(torrent.torrent);
	});
	return result;
}

/*
 * @param: query - the search query the user entered
 * @param: options - an options object
 * Searches the pirate bay for videos with the given query and returns
 * a list of torrent objects
 */
function searchCommand(query, options) {
	var torrentHash = [];
	var torrentInfos = [];
	var orderBy = options.order;
	var infoField = convertOrder(orderBy).infoField;
	var order = convertOrder(orderBy).order;

	strike.search(query).then(function(res) {
		var results = res.torrents;
		if (results.length == 0) {
			inquirer.prompt([
				{
					type: 'input',
					name: 'title',
					message: 'Sorry, 0 results. Enter new search: ',

				}
			], function(answers) {
					searchCommand(answers.title, options);
			});
		} else {
			results = sortTorrents(order, infoField, results);
			results.forEach(function(result) {
				torrentHash[result.torrent_title] = result.magnet_uri;
				if (order == orderEnum.NAME) {
					torrentInfos.push(result.torrent_title + ' :: ');
				} else {
					torrentInfos.push(result.torrent_title + ' :: ' + result[infoField]);
				}
			});

			inquirer.prompt([
				{
					type: 'list',
					name: 'title',
					message: 'Which torrent do you want to stream?',
					choices: torrentInfos
				}
			], function(answers) {
				var title = answers.title;
				var titleString = title.substring(0, title.indexOf(' :: '));
				playMagnet([torrentHash[titleString], '--vlc']);
			});
		}
	});
}

// ==============================
// COMMANDS
// ==============================
program
	.version('0.1.0');

program
	.command('play [magnet]')
	.description('stream a torrent file with the given magnet link')
	.option('-v, --vlc', 'open the torrent stream with vlc player')
	.action(function(magnet, options) {
		playCommand(magnet, options);
	});
program
	.command('search [query]')
	.description('search the pirate bay with a query')
	.option('-o, --order [orderBy]',
		'order results by a given field:' +
		'seeds (default) | name | date | size | leeches')
	.action(function(query, options) {
		searchCommand(query, options);
	});
program
	.command('marathon')
	.description("if you've enabled a marthon, this will let you select the next file to watch in a folder")
	.action(function() {
		marathonCommand();
	});

program.parse(process.argv);

process.on('SIGINT', function() {
	if (engine) {
		console.log("\n Closing...");
		engine.remove(function() {
			process.exit();
		});
	}
});

<|endoftext|>


<commit_before>var path  = require("path"),
  util    = require("util"),
  base    = process.cwd(),

  styles = {
    normal: [0, 0],
    bold: [1, 22],
    dim: [2, 22],
    italic: [3, 23],
    underline: [4, 24],
    strikethrough: [9, 29],

    default: [39, 39],
    black: [30, 39],
    red: [31, 39],
    green: [32, 39],
    yellow: [33, 39],
    blue: [34, 39],
    magenta: [35, 39],
    cyan: [36, 39],
    light_gray: [37, 39],
    dark_gray: [90, 39],
    light_red: [91, 39],
    light_green: [92, 39],
    light_yellow: [93, 39],
    light_blue: [94, 39],
    light_magenta: [95, 39],
    light_cyan: [96, 39],
    white: [97, 39],
  };

function StrColor(s) {
    if (!(this instanceof StrColor)) return new StrColor(s);

    var self = this;

    self.str = " " + String(s);
    self.orig = self.str;

    self.log = function (){
        // self.str = "[LOG]" + self.orig;
        self.light_gray.bold.print.apply(self, arguments);
    }

    self.info = function (){
        // self.str = "[INFO]" + self.orig;
        self.blue.bold.print.apply(self, arguments);
    }

    self.warn = function (){
        // self.str = "[WARN]" + self.orig;
        self.yellow.bold.print.apply(self, arguments);
    }

    self.success = function (){
        // self.str = "[SUCCESS]" + self.orig;
        self.green.bold.print.apply(self, arguments);
    }

    self.error = function (err){
        // self.str = "[ERROR]" + self.orig;
        var stack, mark;
        if (err instanceof Error) {
            self.red.bold.print.call(self, "[%s] %s", err.name, err.message);
            stack = Array.prototype.slice.call(getStack() || [], 1, 25);
            for (var i = 0, len = stack.length; i < len; i++) {
                mark = i < len - 1 ? "├─" : "└─";
                StrColor("  " + mark).light_red.print("%s:%s <%s>()", stack[i].getFileName(),
                    stack[i].getLineNumber(), stack[i].getFunctionName() || "anonymous");
            }
        } else
            self.red.bold.print.apply(self, arguments);
    }

    self.print = function (){
        console.log(self.str + " " + util.format.apply(null, arguments));
        self.str = self.orig;
    };

    self.toString = function (){
        return this.str;
    };

    Object.keys(styles).forEach(function (key){
        Object.defineProperty(self, key, {
            get: function (){
                var s = styles[key];
                self.str = '\u001b[' + s[0] + 'm' + self.str + '\u001b[' + s[1] + 'm';
                return self;
            }
        });
    });
}

function getStack(){
    var orig, err, stack;
    orig = Error.prepareStackTrace;
    Error.prepareStackTrace = function(_, stack){ return stack; };
    err = new Error;
    Error.captureStackTrace(err, arguments.callee);
    stack = err.stack;
    Error.prepareStackTrace = orig;

    return stack;
}

function debug (name) {
    var stack   = getStack(),
      filename  = path.relative(base, stack[1].getFileName()),
      line      = stack[1].getLineNumber(),
      debugName = name || (module.exports.app_name + ":" + filename + ":" + line);

    return StrColor(debugName);
};

module.exports = debug;
module.exports.app_name = base;
module.exports.StrColor = StrColor;
<commit_msg>Initial commit<commit_after>var path  = require("path"),
  util    = require("util"),
  base    = process.cwd(),

  styles = {
    normal: [0, 0],
    bold: [1, 22],
    dim: [2, 22],
    italic: [3, 23],
    underline: [4, 24],
    strikethrough: [9, 29],

    default: [39, 39],
    black: [30, 39],
    red: [31, 39],
    green: [32, 39],
    yellow: [33, 39],
    blue: [34, 39],
    magenta: [35, 39],
    cyan: [36, 39],
    light_gray: [37, 39],
    dark_gray: [90, 39],
    light_red: [91, 39],
    light_green: [92, 39],
    light_yellow: [93, 39],
    light_blue: [94, 39],
    light_magenta: [95, 39],
    light_cyan: [96, 39],
    white: [97, 39],
  };

function StrColor(s) {
    if (!(this instanceof StrColor)) return new StrColor(s);

    var self = this;

    self.str = " " + String(s);
    self.orig = self.str;

    self.log = function (){
        // self.str = "[LOG]" + self.orig;
        self.light_gray.bold.print.apply(self, arguments);
    }

    self.info = function (){
        // self.str = "[INFO]" + self.orig;
        self.blue.bold.print.apply(self, arguments);
    }

    self.warn = function (){
        // self.str = "[WARN]" + self.orig;
        self.yellow.bold.print.apply(self, arguments);
    }

    self.success = function (){
        // self.str = "[SUCCESS]" + self.orig;
        self.green.bold.print.apply(self, arguments);
    }

    self.error = function (err){
        // self.str = "[ERROR]" + self.orig;
        var stack, mark;
        if (err instanceof Error) {
            self.red.bold.print.call(self, "[%s] %s", err.name, err.message);
            stack = Array.prototype.slice.call(getStack() || [], 1, 25);
            for (var i = 0, len = stack.length; i < len; i++) {
                mark = i < len - 1 ? "├─" : "└─";
                StrColor("  " + mark).light_red.print("%s:%s <%s>()", stack[i].getFileName(),
                    stack[i].getLineNumber(), stack[i].getFunctionName() || "anonymous");
            }
        } else
            self.red.bold.print.apply(self, arguments);
    }

    self.print = function (){
        console.log(self.str + " " + util.format.apply(null, arguments));
        self.str = self.orig;
    };

    self.toString = function (){
        return this.str;
    };

    Object.keys(styles).forEach(function (key){
        Object.defineProperty(self, key, {
            get: function (){
                var s = styles[key];
                self.str = '\u001b[' + s[0] + 'm' + self.str + '\u001b[' + s[1] + 'm';
                return self;
            }
        });
    });
}

function getStack(){
    var orig, err, stack;
    orig = Error.prepareStackTrace;
    Error.prepareStackTrace = function(_, stack){ return stack; };
    err = new Error;
    Error.captureStackTrace(err, arguments.callee);
    stack = err.stack;
    Error.prepareStackTrace = orig;

    return stack;
}

function debug (name) {
    var stack   = getStack(),
      filename  = path.relative(base, stack[1].getFileName()),
      line      = stack[1].getLineNumber(),
      debugName = name || (module.exports.app_name + ":" + filename + ":" + line);

    return StrColor(debugName);
};

module.exports = debug;
module.exports.app_name = path.basename(base);
module.exports.StrColor = StrColor;
<|endoftext|>


<commit_before>export default function hasFlag(flag, argv = process.argv) {
	const prefix = flag.startsWith('-') ? '' : (flag.length === 1 ? '-' : '--');
	const position = argv.indexOf(prefix + flag);
	const terminatorPosition = argv.indexOf('--');
	return position !== -1 && (terminatorPosition === -1 || position < terminatorPosition);
}
<commit_msg>Explicitly import `process` (#13)<commit_after>import process from 'process'; // eslint-disable-line node/prefer-global/process

export default function hasFlag(flag, argv = process.argv) {
	const prefix = flag.startsWith('-') ? '' : (flag.length === 1 ? '-' : '--');
	const position = argv.indexOf(prefix + flag);
	const terminatorPosition = argv.indexOf('--');
	return position !== -1 && (terminatorPosition === -1 || position < terminatorPosition);
}
<|endoftext|>


<commit_before>'use strict';

const fs = require('fs');
const css = require('css');
const hash = require('hash-sum');
const cssWhat = require('css-what');
const stripBom = require('strip-bom');
const compiler = require('vue-template-compiler');

/**
 * @fork https://github.com/fb55/css-what/blob/master/stringify.js
 * @type {Function} stringify
 */
cssWhat.stringify = require('./css-what/stringify');

/**
 * In Browser Environment
 * @type {Boolean} browserEnv
 */
let browserEnv = false;
try {
    document;
    browserEnv = true;
} catch (e) {}

/**
 * Save Loaders of different Language
 * @type {Object} store
 */
let store = {
    style : {
        defaults : '',
        langs : {},
    },
    script : {
        defaults : '',
        langs : {},
    },
    template : {
        defaults : '',
        langs : {},
    },
};

/**
 * Set default Loader of different Language
 * @param {String} type | style | script | template |
 * @param {String} lang scss, ts, jade etc.
 */
function set ( type, lang ) {
    store[type].defaults = lang;
}

/**
 * Register Loader of different Language
 * @param {String} type | style | script | template |
 * @param {String} lang scss, ts, jade etc.
 * @param {Function} handler handler
 */
function register ( type, lang, handler ) {
    store[type].langs[lang] = handler;
}

/**
 * Require extension vue hook
 * @param {Module} module module
 * @param {String} filePath file path
 * @export {Vue} Vue Component after compile
 */
function loader ( module, filePath ) {

    let content = fs.readFileSync(filePath, 'utf8');
    let moduleId = `_v-${ hash(filePath) }`;

    let vueTemplate = '';
    let vueComponent = compiler.parseComponent(stripBom(content));

    let script = vueComponent.script;
    let styles = vueComponent.styles;
    let template = vueComponent.template;

    let scoped = styles.some(({ attrs }) => attrs.scoped);

    [].concat(script, template, styles).forEach(( tag ) => {
        if (tag) {
            let type = tag.type;
            let content = tag.content;
            let lang = tag.attrs.lang || store[type].defaults;
            let handler = store[type].langs[lang];
            if (handler) {
                content = handler(content, filePath);
            }
            switch (type) {
                case 'style':
                    if (browserEnv) {
                        /**
                         * Only in Browser Environment, append style to head
                         */
                        if (content instanceof Promise) {
                            /**
                             * Style support async
                             */
                            content.then(sync);
                        } else {
                            sync(content);
                        }
                        function sync ( content ) {
                            if (tag.attrs.scoped) {
                                let ast = css.parse(content);
                                ast.stylesheet.rules.forEach(( rule ) => {
                                    rule.selectors = rule.selectors.map(( selector ) => {
                                        let [ patterns ] = cssWhat(selector);
                                        let index = patterns.length - 1;
                                        for (; index >= 0; index--) {
                                            let { type } = patterns[index];
                                            if (type !== 'pseudo' && type !== 'pseudo-element') {
                                                break;
                                            }
                                        }
                                        patterns.splice(index + 1, 0, {
                                            value : '',
                                            name : moduleId,
                                            action : 'exists',
                                            type : 'attribute',
                                            ignoreCase : false,
                                        });
                                        return stringify([patterns]);
                                    });
                                });
                                content = css.stringify(ast);
                            }
                            let style = document.createElement('style');
                            style.innerHTML = content;
                            document.head.appendChild(style);
                        }
                    }
                    break;
                case 'script':
                    module._compile(content, filePath);
                    break;
                case 'template':
                    if (browserEnv) {
                        /**
                         * Only in Browser Environment, set Attribute for each element
                         */
                        if (scoped) {
                            let div = document.createElement('div');
                            div.innerHTML = content;
                            let root = div.firstElementChild;
                            walk(root, ( element ) => {
                                element.setAttribute(moduleId, '');
                            });
                            function walk ( element, handler ) {
                                handler(element);
                                let children = element.children || [];
                                [].forEach.call(children, ( child ) => {
                                    walk(child, handler);
                                });
                            }
                            content = div.innerHTML;
                        }
                    }
                    vueTemplate = content;
                    break;
            }
        }
    });

    module.exports.template = vueTemplate;
}

/**
 * Exports API to expand
 */
['style', 'script', 'template'].forEach(( type ) => {
    loader[type] = {
        set ( lang ) {
            set(type, lang);
            return this;
        },
        register ( lang, handler ) {
            register(type, lang, handler);
            return this;
        },
    };
});

/**
 * Register Loader as default .vue hook
 */
require.extensions['.vue'] = require.extensions['.vue'] || loader;

/**
 * @export {Function} loader
 */
module.exports = loader;
<commit_msg>fixed a bug<commit_after>'use strict';

const fs = require('fs');
const css = require('css');
const hash = require('hash-sum');
const cssWhat = require('css-what');
const stripBom = require('strip-bom');
const compiler = require('vue-template-compiler');

/**
 * @fork https://github.com/fb55/css-what/blob/master/stringify.js
 * @type {Function} stringify
 */
cssWhat.stringify = require('./css-what/stringify');

/**
 * In Browser Environment
 * @type {Boolean} browserEnv
 */
let browserEnv = false;
try {
    document;
    browserEnv = true;
} catch (e) {}

/**
 * Save Loaders of different Language
 * @type {Object} store
 */
let store = {
    style : {
        defaults : '',
        langs : {},
    },
    script : {
        defaults : '',
        langs : {},
    },
    template : {
        defaults : '',
        langs : {},
    },
};

/**
 * Set default Loader of different Language
 * @param {String} type | style | script | template |
 * @param {String} lang scss, ts, jade etc.
 */
function set ( type, lang ) {
    store[type].defaults = lang;
}

/**
 * Register Loader of different Language
 * @param {String} type | style | script | template |
 * @param {String} lang scss, ts, jade etc.
 * @param {Function} handler handler
 */
function register ( type, lang, handler ) {
    store[type].langs[lang] = handler;
}

/**
 * Require extension vue hook
 * @param {Module} module module
 * @param {String} filePath file path
 * @export {Vue} Vue Component after compile
 */
function loader ( module, filePath ) {

    let content = fs.readFileSync(filePath, 'utf8');
    let moduleId = `_v-${ hash(filePath) }`;

    let vueTemplate = '';
    let vueComponent = compiler.parseComponent(stripBom(content));

    let script = vueComponent.script;
    let styles = vueComponent.styles;
    let template = vueComponent.template;

    let scoped = styles.some(({ attrs }) => attrs.scoped);

    [].concat(script, template, styles).forEach(( tag ) => {
        if (tag) {
            let type = tag.type;
            let content = tag.content;
            let lang = tag.attrs.lang || store[type].defaults;
            let handler = store[type].langs[lang];
            if (handler) {
                content = handler(content, filePath);
            }
            switch (type) {
                case 'style':
                    if (browserEnv) {
                        /**
                         * Only in Browser Environment, append style to head
                         */
                        if (content instanceof Promise) {
                            /**
                             * Style support async
                             */
                            content.then(sync);
                        } else {
                            sync(content);
                        }
                        function sync ( content ) {
                            if (tag.attrs.scoped) {
                                let ast = css.parse(content);
                                ast.stylesheet.rules.forEach(( rule ) => {
                                    rule.selectors = rule.selectors.map(( selector ) => {
                                        let [ patterns ] = cssWhat(selector);
                                        let index = patterns.length - 1;
                                        for (; index >= 0; index--) {
                                            let { type } = patterns[index];
                                            if (type !== 'pseudo' && type !== 'pseudo-element') {
                                                break;
                                            }
                                        }
                                        patterns.splice(index + 1, 0, {
                                            value : '',
                                            name : moduleId,
                                            action : 'exists',
                                            type : 'attribute',
                                            ignoreCase : false,
                                        });
                                        return cssWhat.stringify([patterns]);
                                    });
                                });
                                content = css.stringify(ast);
                            }
                            let style = document.createElement('style');
                            style.innerHTML = content;
                            document.head.appendChild(style);
                        }
                    }
                    break;
                case 'script':
                    module._compile(content, filePath);
                    break;
                case 'template':
                    if (browserEnv) {
                        /**
                         * Only in Browser Environment, set Attribute for each element
                         */
                        if (scoped) {
                            let div = document.createElement('div');
                            div.innerHTML = content;
                            let root = div.firstElementChild;
                            walk(root, ( element ) => {
                                element.setAttribute(moduleId, '');
                            });
                            function walk ( element, handler ) {
                                handler(element);
                                let children = element.children || [];
                                [].forEach.call(children, ( child ) => {
                                    walk(child, handler);
                                });
                            }
                            content = div.innerHTML;
                        }
                    }
                    vueTemplate = content;
                    break;
            }
        }
    });

    module.exports.template = vueTemplate;
}

/**
 * Exports API to expand
 */
['style', 'script', 'template'].forEach(( type ) => {
    loader[type] = {
        set ( lang ) {
            set(type, lang);
            return this;
        },
        register ( lang, handler ) {
            register(type, lang, handler);
            return this;
        },
    };
});

/**
 * Register Loader as default .vue hook
 */
require.extensions['.vue'] = require.extensions['.vue'] || loader;

/**
 * @export {Function} loader
 */
module.exports = loader;
<|endoftext|>


<commit_before>'use strict';
var ಠ = 'data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw=='; // transparent image, used as accessor and replacing image
var propRegex = /(object-fit|object-position)\s*:\s*([-\w\s%]+)/g;
var testImg = new Image();
var supportsObjectFit = 'object-fit' in testImg.style;
var supportsObjectPosition = 'object-position' in testImg.style;
var supportsCurrentSrc = typeof testImg.currentSrc === 'string';
var nativeGetAttribute = testImg.getAttribute;
var nativeSetAttribute = testImg.setAttribute;
var autoModeEnabled = false;

function getStyle(el) {
	var style = getComputedStyle(el).fontFamily;
	var parsed;
	var props = {};
	while ((parsed = propRegex.exec(style)) !== null) {
		props[parsed[1]] = parsed[2];
	}
	return props;
}

function fixOne(el, requestedSrc) {
	if (el[ಠ].parsingSrcset) {
		return;
	}
	var style = getStyle(el);
	style['object-fit'] = style['object-fit'] || 'fill'; // default value

	// If the fix was already applied, don't try to skip fixing,
	// - because once you go ofi you never go back.
	// - Wait, that doesn't rhyme.
	// - This ain't rap, bro.
	if (!el[ಠ].s) {
		// fill is the default behavior so no action is necessary
		if (style['object-fit'] === 'fill') {
			return;
		}

		// Where object-fit is supported and object-position isn't (Safari < 10)
		if (
			!el[ಠ].skipTest && // unless user wants to apply regardless of browser support
			supportsObjectFit && // if browser already supports object-fit
			!style['object-position'] // unless object-position is used
		) {
			return;
		}
	}

	var src = el.currentSrc || el.src;

	if (requestedSrc) {
		// explicitly requested src takes precedence
		// TODO: this still should overwrite srcset
		src = requestedSrc;
	} else if (el.srcset && !supportsCurrentSrc && window.picturefill) {
		var pf = window.picturefill._.ns;
		// prevent infinite loop
		// fillImg sets the src which in turn calls fixOne
		el[ಠ].parsingSrcset = true;

		// parse srcset with picturefill where currentSrc isn't available
		if (!el[pf] || !el[pf].evaled) {
			// force synchronous srcset parsing
			window.picturefill._.fillImg(el, {reselect: true});
		}

		if (!el[pf].curSrc) {
			// force picturefill to parse srcset
			el[pf].supported = false;
			window.picturefill._.fillImg(el, {reselect: true});
		}
		delete el[ಠ].parsingSrcset;

		// retrieve parsed currentSrc, if any
		src = el[pf].curSrc || src;
	}

	// store info on object for later use
	if (el[ಠ].s) {
		el[ಠ].s = src;
		if (requestedSrc) {
			// the attribute reflects the user input
			// the property is the resolved URL
			el[ಠ].srcAttr = requestedSrc;
		}
	} else {
		el[ಠ] = {
			s: src,
			srcAttr: requestedSrc || nativeGetAttribute.call(el, 'src'),
			srcsetAttr: el.srcset
		};
		el.src = ಠ;

		// remove srcset because it overrides src
		if (el.srcset) {
			el.srcset = '';

			// restore non-browser-readable srcset property
			Object.defineProperty(el, 'srcset', {
				value: el[ಠ].srcsetAttr
			});
		}

		keepSrcUsable(el);
	}

	el.style.backgroundImage = 'url("' + src + '")';
	el.style.backgroundPosition = style['object-position'] || 'center';
	el.style.backgroundRepeat = 'no-repeat';

	if (/scale-down/.test(style['object-fit'])) {
		// `object-fit: scale-down` is either `contain` or `auto`
		if (!el[ಠ].i) {
			el[ಠ].i = new Image();
			el[ಠ].i.src = src;
		}

		// naturalWidth is only available when the image headers are loaded,
		// this loop will poll it every 100ms.
		// There's currently no check to prevent this loop from starting twice
		// as a consequence of calling ofi() twice on the same image, but it's light
		// and causes no issues, so it's not worth ensuring that it doesn't.
		(function loop() {
			// https://bugs.chromium.org/p/chromium/issues/detail?id=495908
			if (el[ಠ].i.naturalWidth) {
				if (el[ಠ].i.naturalWidth > el.width || el[ಠ].i.naturalHeight > el.height) {
					el.style.backgroundSize = 'contain';
				} else {
					el.style.backgroundSize = 'auto';
				}
				return;
			}
			setTimeout(loop, 100);
		})();
	} else {
		el.style.backgroundSize = style['object-fit'].replace('none', 'auto').replace('fill', '100% 100%');
	}
}

function keepSrcUsable(el) {
	var descriptors = {
		get: function () {
			return el[ಠ].s;
		},
		set: function (src) {
			delete el[ಠ].i; // scale-down's img sizes need to be updated too
			fixOne(el, src);
			return src;
		}
	};
	Object.defineProperty(el, 'src', descriptors);
	Object.defineProperty(el, 'currentSrc', {get: descriptors.get}); // it should be read-only
}

function hijackAttributes() {
	if (!supportsObjectPosition) {
		HTMLImageElement.prototype.getAttribute = function (name) {
			if (this[ಠ] && (name === 'src' || name === 'srcset')) {
				return this[ಠ][name + 'Attr'];
			}
			return nativeGetAttribute.call(this, name);
		};

		HTMLImageElement.prototype.setAttribute = function (name, value) {
			if (this[ಠ] && (name === 'src' || name === 'srcset')) {
				this[name === 'src' ? 'src' : name + 'Attr'] = String(value);
			} else {
				nativeSetAttribute.call(this, name, value);
			}
		};
	}
}

export default function fix(imgs, opts) {
	var startAutoMode = !autoModeEnabled && !imgs;
	opts = opts || {};
	imgs = imgs || 'img';
	if (supportsObjectPosition && !opts.skipTest) {
		return false;
	}

	// use imgs as a selector or just select all images
	if (typeof imgs === 'string') {
		imgs = document.querySelectorAll('img');
	} else if (!imgs.length) {
		imgs = [imgs];
	}

	// apply fix to all
	for (var i = 0; i < imgs.length; i++) {
		imgs[i][ಠ] = imgs[i][ಠ] || opts;
		fixOne(imgs[i]);
	}

	if (startAutoMode) {
		document.body.addEventListener('load', function (e) {
			if (e.target.tagName === 'IMG') {
				fix(e.target, {
					skipTest: opts.skipTest
				});
			}
		}, true);
		autoModeEnabled = true;
		imgs = 'img'; // reset to a generic selector for watchMQ
	}

	// if requested, watch media queries for object-fit change
	if (opts.watchMQ) {
		window.addEventListener('resize', fix.bind(null, imgs, {
			skipTest: opts.skipTest
		}));
	}
}

fix.supportsObjectFit = supportsObjectFit;
fix.supportsObjectPosition = supportsObjectPosition;

hijackAttributes();
<commit_msg>Don't break images in iOS 7-<commit_after>'use strict';
var ಠ = 'data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw=='; // transparent image, used as accessor and replacing image
var propRegex = /(object-fit|object-position)\s*:\s*([-\w\s%]+)/g;
var testImg = new Image();
var supportsObjectFit = 'object-fit' in testImg.style;
var supportsObjectPosition = 'object-position' in testImg.style;
var supportsCurrentSrc = typeof testImg.currentSrc === 'string';
var nativeGetAttribute = testImg.getAttribute;
var nativeSetAttribute = testImg.setAttribute;
var autoModeEnabled = false;

function getStyle(el) {
	var style = getComputedStyle(el).fontFamily;
	var parsed;
	var props = {};
	while ((parsed = propRegex.exec(style)) !== null) {
		props[parsed[1]] = parsed[2];
	}
	return props;
}

function fixOne(el, requestedSrc) {
	if (el[ಠ].parsingSrcset) {
		return;
	}
	var style = getStyle(el);
	style['object-fit'] = style['object-fit'] || 'fill'; // default value

	// If the fix was already applied, don't try to skip fixing,
	// - because once you go ofi you never go back.
	// - Wait, that doesn't rhyme.
	// - This ain't rap, bro.
	if (!el[ಠ].s) {
		// fill is the default behavior so no action is necessary
		if (style['object-fit'] === 'fill') {
			return;
		}

		// Where object-fit is supported and object-position isn't (Safari < 10)
		if (
			!el[ಠ].skipTest && // unless user wants to apply regardless of browser support
			supportsObjectFit && // if browser already supports object-fit
			!style['object-position'] // unless object-position is used
		) {
			return;
		}
	}

	var src = el.currentSrc || el.src;

	if (requestedSrc) {
		// explicitly requested src takes precedence
		// TODO: this still should overwrite srcset
		src = requestedSrc;
	} else if (el.srcset && !supportsCurrentSrc && window.picturefill) {
		var pf = window.picturefill._.ns;
		// prevent infinite loop
		// fillImg sets the src which in turn calls fixOne
		el[ಠ].parsingSrcset = true;

		// parse srcset with picturefill where currentSrc isn't available
		if (!el[pf] || !el[pf].evaled) {
			// force synchronous srcset parsing
			window.picturefill._.fillImg(el, {reselect: true});
		}

		if (!el[pf].curSrc) {
			// force picturefill to parse srcset
			el[pf].supported = false;
			window.picturefill._.fillImg(el, {reselect: true});
		}
		delete el[ಠ].parsingSrcset;

		// retrieve parsed currentSrc, if any
		src = el[pf].curSrc || src;
	}

	// store info on object for later use
	if (el[ಠ].s) {
		el[ಠ].s = src;
		if (requestedSrc) {
			// the attribute reflects the user input
			// the property is the resolved URL
			el[ಠ].srcAttr = requestedSrc;
		}
	} else {
		el[ಠ] = {
			s: src,
			srcAttr: requestedSrc || nativeGetAttribute.call(el, 'src'),
			srcsetAttr: el.srcset
		};
		el.src = ಠ;

		try {
			// remove srcset because it overrides src
			if (el.srcset) {
				el.srcset = '';

				// restore non-browser-readable srcset property
				Object.defineProperty(el, 'srcset', {
					value: el[ಠ].srcsetAttr
				});
			}

			keepSrcUsable(el);
		} catch (err) {/**/}
	}

	el.style.backgroundImage = 'url("' + src + '")';
	el.style.backgroundPosition = style['object-position'] || 'center';
	el.style.backgroundRepeat = 'no-repeat';

	if (/scale-down/.test(style['object-fit'])) {
		// `object-fit: scale-down` is either `contain` or `auto`
		if (!el[ಠ].i) {
			el[ಠ].i = new Image();
			el[ಠ].i.src = src;
		}

		// naturalWidth is only available when the image headers are loaded,
		// this loop will poll it every 100ms.
		// There's currently no check to prevent this loop from starting twice
		// as a consequence of calling ofi() twice on the same image, but it's light
		// and causes no issues, so it's not worth ensuring that it doesn't.
		(function loop() {
			// https://bugs.chromium.org/p/chromium/issues/detail?id=495908
			if (el[ಠ].i.naturalWidth) {
				if (el[ಠ].i.naturalWidth > el.width || el[ಠ].i.naturalHeight > el.height) {
					el.style.backgroundSize = 'contain';
				} else {
					el.style.backgroundSize = 'auto';
				}
				return;
			}
			setTimeout(loop, 100);
		})();
	} else {
		el.style.backgroundSize = style['object-fit'].replace('none', 'auto').replace('fill', '100% 100%');
	}
}

function keepSrcUsable(el) {
	var descriptors = {
		get: function () {
			return el[ಠ].s;
		},
		set: function (src) {
			delete el[ಠ].i; // scale-down's img sizes need to be updated too
			fixOne(el, src);
			return src;
		}
	};
	Object.defineProperty(el, 'src', descriptors);
	Object.defineProperty(el, 'currentSrc', {get: descriptors.get}); // it should be read-only
}

function hijackAttributes() {
	if (!supportsObjectPosition) {
		HTMLImageElement.prototype.getAttribute = function (name) {
			if (this[ಠ] && (name === 'src' || name === 'srcset')) {
				return this[ಠ][name + 'Attr'];
			}
			return nativeGetAttribute.call(this, name);
		};

		HTMLImageElement.prototype.setAttribute = function (name, value) {
			if (this[ಠ] && (name === 'src' || name === 'srcset')) {
				this[name === 'src' ? 'src' : name + 'Attr'] = String(value);
			} else {
				nativeSetAttribute.call(this, name, value);
			}
		};
	}
}

export default function fix(imgs, opts) {
	var startAutoMode = !autoModeEnabled && !imgs;
	opts = opts || {};
	imgs = imgs || 'img';
	if (supportsObjectPosition && !opts.skipTest) {
		return false;
	}

	// use imgs as a selector or just select all images
	if (typeof imgs === 'string') {
		imgs = document.querySelectorAll('img');
	} else if (!imgs.length) {
		imgs = [imgs];
	}

	// apply fix to all
	for (var i = 0; i < imgs.length; i++) {
		imgs[i][ಠ] = imgs[i][ಠ] || opts;
		fixOne(imgs[i]);
	}

	if (startAutoMode) {
		document.body.addEventListener('load', function (e) {
			if (e.target.tagName === 'IMG') {
				fix(e.target, {
					skipTest: opts.skipTest
				});
			}
		}, true);
		autoModeEnabled = true;
		imgs = 'img'; // reset to a generic selector for watchMQ
	}

	// if requested, watch media queries for object-fit change
	if (opts.watchMQ) {
		window.addEventListener('resize', fix.bind(null, imgs, {
			skipTest: opts.skipTest
		}));
	}
}

fix.supportsObjectFit = supportsObjectFit;
fix.supportsObjectPosition = supportsObjectPosition;

hijackAttributes();
<|endoftext|>


<commit_before>'use strict'

if (['staging', 'production'].indexOf(process.env.NODE_ENV) === -1) {
  require('dotenv').config({path: `${__dirname}/.env`})
}

const isPrd = process.env.NODE_ENV === 'production'

const express = require('express')
const nodeWit = require('node-wit')
const bodyParser = require('body-parser')
const sessions = require('./sessions')

const app = express()

const Logger = nodeWit.Logger
const levels = nodeWit.logLevels
const Wit = nodeWit.Wit

const logger = new Logger(!isPrd ? levels.ERROR : levels.DEBUG)
const client = new Wit(process.env.WIT_TOKEN, require('./wit-actions'), logger)

function witProcessing (sessionId, msg) {
  // console.log(sessions)
  const ctx = sessions.list[sessionId].context
  console.log(sessionId)
  console.log(ctx)
  client.runActions(sessionId, msg, ctx, (error, context) => {
    if (error) console.error(error)
    sessions.list[sessionId].context = context
  }, process.WIT_PROCESSING_STEPS)
}

// parse application/x-www-form-urlencoded
app.use(bodyParser.urlencoded({ extended: false }))

// parse application/json
app.use(bodyParser.json())

app.get('/', (req, res) => {
  res.send('Impero Movie UK')
})

app.get('/webhook/', (req, res) => {
  if (req.query['hub.verify_token'] === process.env.VERIFY_TOKEN) {
    res.send(req.query['hub.challenge'])
  } else {
    res.send('Error, wrong validation token')
  }
})

app.post('/webhook/', (req, res) => {
  const messagingEvents = req.body.entry[0].messaging

  messagingEvents.forEach((messagingEvent) => {
    const sender = messagingEvent.sender.id
    if (messagingEvent.message && messagingEvent.message.text) {
      const sessionId = sessions.findOrCreateSession(sender)
      witProcessing(sessionId, messagingEvent.message.text)
    }
  })

  res.sendStatus(200)
})

app.listen(3000, () => {
  console.log('impero-movie-uk app is now listening on port 3000.')
  console.log(`Env: ${process.env.NODE_ENV}`)
  console.log(`Verify token: ${process.env.VERIFY_TOKEN}`)
  console.log(`Page access token: ${process.env.PAGE_ACCESS_TOKEN}`)
  console.log(`WIT token: ${process.env.WIT_TOKEN}`)
})
<commit_msg>update WIT logger<commit_after>'use strict'

if (['staging', 'production'].indexOf(process.env.NODE_ENV) === -1) {
  require('dotenv').config({path: `${__dirname}/.env`})
}

const isPrd = process.env.NODE_ENV === 'production'

const express = require('express')
const nodeWit = require('node-wit')
const bodyParser = require('body-parser')
const sessions = require('./sessions')

const app = express()

const Logger = nodeWit.Logger
const levels = nodeWit.logLevels
const Wit = nodeWit.Wit

const logger = new Logger(isPrd ? levels.ERROR : levels.DEBUG)
const client = new Wit(process.env.WIT_TOKEN, require('./wit-actions'), logger)

function witProcessing (sessionId, msg) {
  // console.log(sessions)
  const ctx = sessions.list[sessionId].context
  console.log(sessionId)
  console.log(ctx)
  client.runActions(sessionId, msg, ctx, (error, context) => {
    if (error) console.error(error)
    sessions.list[sessionId].context = context
  }, process.WIT_PROCESSING_STEPS)
}

// parse application/x-www-form-urlencoded
app.use(bodyParser.urlencoded({ extended: false }))

// parse application/json
app.use(bodyParser.json())

app.get('/', (req, res) => {
  res.send('Impero Movie UK')
})

app.get('/webhook/', (req, res) => {
  if (req.query['hub.verify_token'] === process.env.VERIFY_TOKEN) {
    res.send(req.query['hub.challenge'])
  } else {
    res.send('Error, wrong validation token')
  }
})

app.post('/webhook/', (req, res) => {
  const messagingEvents = req.body.entry[0].messaging

  messagingEvents.forEach((messagingEvent) => {
    const sender = messagingEvent.sender.id
    if (messagingEvent.message && messagingEvent.message.text) {
      const sessionId = sessions.findOrCreateSession(sender)
      witProcessing(sessionId, messagingEvent.message.text)
    }
  })

  res.sendStatus(200)
})

app.listen(3000, () => {
  console.log('impero-movie-uk app is now listening on port 3000.')
  console.log(`Env: ${process.env.NODE_ENV}`)
  console.log(`Verify token: ${process.env.VERIFY_TOKEN}`)
  console.log(`Page access token: ${process.env.PAGE_ACCESS_TOKEN}`)
  console.log(`WIT token: ${process.env.WIT_TOKEN}`)
})
<|endoftext|>