<commit_before>/**
 * Download landsat products.
 *
 * Command-line arguments are interpreted as scene ids.
 * If arguments are provided, then only download those scenes.
 *
 * If no arguments are provided, download 10 scenes from
 * the last days scenes sql view.
 *
 */

/////////////////////////////////////////////////////////////////////

// Libraries
var yaml = require('yamljs')
var pg = require('pg')
var fs = require('fs')
var winston = require('winston')
var axios = require('axios')
var request = require('request')
var Promise = require('bluebird')
Promise.longStackTraces()

// Modules
var usgs_constants = require("./lib/usgs_api/usgs_constants.js")
var usgs_functions = require("./lib/usgs_api/usgs_functions.js")
var usgs_helpers = require("./lib/usgs_api/usgs_helpers.js")
var pg_handler = require('./lib/postgres/postgres_handlers.js')
var app_helpers = require('./lib/helpers/app_helpers.js')()

// Settings for USGS
const CONFIG_YAML = yaml.load('./lib/usgs_api/config.yaml')

// Base URL for http promise library
axios.defaults.baseURL = usgs_constants.USGS_URL

// USGS API key promise
var api_key_promise = usgs_helpers.get_api_key()

// Database connection
const db_config = yaml.load("./lib/postgres/config.yaml")
var pg_pool = pg_handler.pg_pool(db_config)

// Logging
const TODAY_DATE = app_helpers.get_date_string()
const LOG_LEVEL_INFO = 'info'
const LOG_LEVEL_ERROR = 'error'
const LOG_FILE = 'download_landsat_data'

app_helpers.delete_old_files(LOG_FILE, 'logs/', '.log')
app_helpers.set_logger_level('debug')
app_helpers.set_logfile(LOG_FILE)
app_helpers.write_message(LOG_LEVEL_INFO, 'START '+LOG_FILE, '')

// SQL queries
const last_days_scenes_query_text = "SELECT * FROM vw_last_days_scenes "
  + "LIMIT 10"

const custom_request_query_template = ""
  + "SELECT * FROM landsat_metadata "
  + "WHERE needs_ordering = 'NO' "
  + "AND scene_id in "

// Constants for handling the USGS API
const USGS_DL_RESPONSE_CODE = usgs_helpers.get_usgs_response_code('download')
const CONCURRENT_DL_LIMIT = 10
const USGS_DL_PRODUCTS = ['STANDARD']
const DL_DIR = CONFIG_YAML.download_directory

// The number of concurrent downloads in progress
var active_downloads = 0

///////////////////////////////////////////////////////////////////////////////////

const main = function() {
  var query_text = make_initial_query()
  var dataset_names = usgs_constants.LANDSAT_DATASETS
  pg_handler.pool_query_db(pg_pool, query_text, [], function (query_result) {
    var scenes_by_dataset = usgs_helpers.sort_scene_records_by_dataset(query_result.rows)
    usgs_helpers.process_scenes_by_dataset(
      dataset_names,
      scenes_by_dataset,
      process_scenes_for_dataset
    )
  })

}

const make_initial_query = function () {
  if (process.argv[2]) {
    const scenes = process.argv.slice(2)
    return custom_request_query_template + app_helpers.list_array_to_sql_list(scenes)
  }
  else {
    return last_days_scenes_query_text
  }
}

/**
 * Process scenes belonging to the same landsat dataset.
 * Limit concurrent downloads so we don't overload the USGS server.
 *
 */
const process_scenes_for_dataset = function (dataset_name, scenes) {
  if (scenes && scenes.length && active_downloads < CONCURRENT_DL_LIMIT) {
    return api_key_promise.then(function (apiKey) {
      const scene_id = scenes.pop()
      return process_scene(dataset_name, scene_id, apiKey)
    }).catch(function (err) {
      app_helpers.write_message(
        LOG_LEVEL_ERROR,
        'ERROR retrieving api key',
        err.stack
      )
    }).then(function() {
      if (active_downloads < CONCURRENT_DL_LIMIT) {
        return process_scenes_for_dataset(dataset_name, scenes)
      }
      else {
        app_helpers.write_message(
          LOG_LEVEL_INFO,
          'Rate limit for attempted downloads reached',
          CONCURRENT_DL_LIMIT
        )
      }
    })
  }
}

/**
 * Get the download link for a scene and start the download.
 *
 */
const process_scene = function (dataset_name, scene_id, apiKey) {
  const request_body = usgs_functions.usgsapi_download(
    apiKey,
    usgs_constants.NODE_EE,
    dataset_name,
    USGS_DL_PRODUCTS,
    [scene_id]
  )
  return usgs_helpers.get_usgsapi_response(
    USGS_DL_RESPONSE_CODE,
    request_body
  ).catch(function (err) {
    app_helpers.write_message(LOG_LEVEL_ERROR, err.stack)
  }).then(function (response) {
    if (response && response.length) {
      app_helpers.write_message(
        LOG_LEVEL_INFO,
        'START downloading ',
        scene_id + '.tar.gz'
      )
      return start_download(scene_id, response[0])
    }
  })

}

/**
 * Start a download for a scene's products.
 *
 * @param scene_id of the product we are downloading
 * @param url is the download link generated by the USGS API
 */
const start_download = function (scene_id, url) {
  const filename = make_filename(scene_id)
  const path = DL_DIR + filename
  if (fs.existsSync(path)) {
    app_helpers.write_message(
      LOG_LEVEL_INFO,
      'File already exists. Deleting old file.'
    )
    fs.unlinkSync(path)
  }
  const file = fs.createWriteStream(path)
  request
    .get(url)
    .on('error', function (err) {
      app_helpers.write_message(LOG_LEVEL_ERROR, err)
    })
    .on('response', function (response) {
      handle_response(response, scene_id)
    })
    .pipe(file)
    .on('finish', function () {
      active_downloads -= 1
      update_record(scene_id)
      app_helpers.write_message(
        LOG_LEVEL_INFO,
        'DONE downloading',
        filename
      )
    })
  return Promise.resolve(active_downloads += 1)
}

/**
 * Check the http response from a download url.
 *
 * @param response is an instance of http.incomingMessage
 * @param scene_id is the id of the scene being downloaded
 *
 */
const handle_response = function (response, scene_id) {
  if (response.statusCode > 200) {
    app_helpers.write_message(
      LOG_LEVEL_ERROR,
      'USGS responded with status code '
      + response.statusCode
      + ' while attempting to download archive for '
      + scene_id
    )
  }
}

/**
 * Update a scene record to reflect that
 * the scene's products were successfully downloaded.
 *
 */
const update_record = function (scene_id) {
  const query_text = ""
    + "UPDATE * FROM landsat_metadata "
    + "WHERE scene_id in ("+scene_id+") "
    + "SET "
      + "needs_ordering = 'NO', "
      + "ordered = 'YES', "
      + "download_available = 'YES', "
      + "needs_downloading = 'NO', "
      + "downloaded = 'YES', "
      + "needs_processing = 'YES'"
  pg_handler.pool_query_db(pg_pool, query_text, [], function () {
    app_helpers.write_message(
      LOG_LEVEL_INFO,
      'Updated database record for scene ' + scene_id
    )
  })
}

const make_filename = function (scene_id) {
  return scene_id + '.tar.gz'
}

main()<commit_msg>Fix update query in download script<commit_after>/**
 * Download landsat products.
 *
 * Command-line arguments are interpreted as scene ids.
 * If arguments are provided, then only download those scenes.
 *
 * If no arguments are provided, download 10 scenes from
 * the last days scenes sql view.
 *
 */

/////////////////////////////////////////////////////////////////////

// Libraries
var yaml = require('yamljs')
var pg = require('pg')
var fs = require('fs')
var winston = require('winston')
var axios = require('axios')
var request = require('request')
var Promise = require('bluebird')
Promise.longStackTraces()

// Modules
var usgs_constants = require("./lib/usgs_api/usgs_constants.js")
var usgs_functions = require("./lib/usgs_api/usgs_functions.js")
var usgs_helpers = require("./lib/usgs_api/usgs_helpers.js")
var pg_handler = require('./lib/postgres/postgres_handlers.js')
var app_helpers = require('./lib/helpers/app_helpers.js')()

// Settings for USGS
const CONFIG_YAML = yaml.load('./lib/usgs_api/config.yaml')

// Base URL for http promise library
axios.defaults.baseURL = usgs_constants.USGS_URL

// USGS API key promise
var api_key_promise = usgs_helpers.get_api_key()

// Database connection
const db_config = yaml.load("./lib/postgres/config.yaml")
var pg_pool = pg_handler.pg_pool(db_config)

// Logging
const TODAY_DATE = app_helpers.get_date_string()
const LOG_LEVEL_INFO = 'info'
const LOG_LEVEL_ERROR = 'error'
const LOG_FILE = 'download_landsat_data'

app_helpers.delete_old_files(LOG_FILE, 'logs/', '.log')
app_helpers.set_logger_level('debug')
app_helpers.set_logfile(LOG_FILE)
app_helpers.write_message(LOG_LEVEL_INFO, 'START '+LOG_FILE, '')

// SQL queries
const last_days_scenes_query_text = "SELECT * FROM vw_last_days_scenes "
  + "LIMIT 10"

const custom_request_query_template = ""
  + "SELECT * FROM landsat_metadata "
  + "WHERE needs_ordering = 'NO' "
  + "AND scene_id in "

// Constants for handling the USGS API
const USGS_DL_RESPONSE_CODE = usgs_helpers.get_usgs_response_code('download')
const CONCURRENT_DL_LIMIT = 10
const USGS_DL_PRODUCTS = ['STANDARD']
const DL_DIR = CONFIG_YAML.download_directory

// The number of concurrent downloads in progress
var active_downloads = 0

///////////////////////////////////////////////////////////////////////////////////

const main = function() {
  var query_text = make_initial_query()
  var dataset_names = usgs_constants.LANDSAT_DATASETS
  pg_handler.pool_query_db(pg_pool, query_text, [], function (query_result) {
    var scenes_by_dataset = usgs_helpers.sort_scene_records_by_dataset(query_result.rows)
    usgs_helpers.process_scenes_by_dataset(
      dataset_names,
      scenes_by_dataset,
      process_scenes_for_dataset
    )
  })

}

const make_initial_query = function () {
  if (process.argv[2]) {
    const scenes = process.argv.slice(2)
    return custom_request_query_template + app_helpers.list_array_to_sql_list(scenes)
  }
  else {
    return last_days_scenes_query_text
  }
}

/**
 * Process scenes belonging to the same landsat dataset.
 * Limit concurrent downloads so we don't overload the USGS server.
 *
 */
const process_scenes_for_dataset = function (dataset_name, scenes) {
  if (scenes && scenes.length && active_downloads < CONCURRENT_DL_LIMIT) {
    return api_key_promise.then(function (apiKey) {
      const scene_id = scenes.pop()
      return process_scene(dataset_name, scene_id, apiKey)
    }).catch(function (err) {
      app_helpers.write_message(
        LOG_LEVEL_ERROR,
        'ERROR retrieving api key',
        err.stack
      )
    }).then(function() {
      if (active_downloads < CONCURRENT_DL_LIMIT) {
        return process_scenes_for_dataset(dataset_name, scenes)
      }
      else {
        app_helpers.write_message(
          LOG_LEVEL_INFO,
          'Rate limit for attempted downloads reached',
          CONCURRENT_DL_LIMIT
        )
      }
    })
  }
}

/**
 * Get the download link for a scene and start the download.
 *
 */
const process_scene = function (dataset_name, scene_id, apiKey) {
  const request_body = usgs_functions.usgsapi_download(
    apiKey,
    usgs_constants.NODE_EE,
    dataset_name,
    USGS_DL_PRODUCTS,
    [scene_id]
  )
  return usgs_helpers.get_usgsapi_response(
    USGS_DL_RESPONSE_CODE,
    request_body
  ).catch(function (err) {
    app_helpers.write_message(LOG_LEVEL_ERROR, err.stack)
  }).then(function (response) {
    if (response && response.length) {
      app_helpers.write_message(
        LOG_LEVEL_INFO,
        'START downloading ',
        scene_id + '.tar.gz'
      )
      return start_download(scene_id, response[0])
    }
  })

}

/**
 * Start a download for a scene's products.
 *
 * @param scene_id of the product we are downloading
 * @param url is the download link generated by the USGS API
 */
const start_download = function (scene_id, url) {
  const filename = make_filename(scene_id)
  const path = DL_DIR + filename
  if (fs.existsSync(path)) {
    app_helpers.write_message(
      LOG_LEVEL_INFO,
      'File already exists. Deleting old file.'
    )
    fs.unlinkSync(path)
  }
  const file = fs.createWriteStream(path)
  request
    .get(url)
    .on('error', function (err) {
      app_helpers.write_message(LOG_LEVEL_ERROR, err)
    })
    .on('response', function (response) {
      handle_response(response, scene_id)
    })
    .pipe(file)
    .on('finish', function () {
      active_downloads -= 1
      update_record(scene_id)
      app_helpers.write_message(
        LOG_LEVEL_INFO,
        'DONE downloading',
        filename
      )
    })
  return Promise.resolve(active_downloads += 1)
}

/**
 * Check the http response from a download url.
 *
 * @param response is an instance of http.incomingMessage
 * @param scene_id is the id of the scene being downloaded
 *
 */
const handle_response = function (response, scene_id) {
  if (response.statusCode > 200) {
    app_helpers.write_message(
      LOG_LEVEL_ERROR,
      'USGS responded with status code '
      + response.statusCode
      + ' while attempting to download archive for '
      + scene_id
    )
  }
}

/**
 * Update a scene record to reflect that
 * the scene's products were successfully downloaded.
 *
 */
const update_record = function (scene_id) {
  const query_text = ""
    + "UPDATE landsat_metadata "
    + "SET "
      + "needs_downloading = 'NO', "
      + "downloaded = 'YES', "
      + "needs_processing = 'YES' "
      + "WHERE scene_id = " + scene_id
  pg_handler.pool_query_db(pg_pool, query_text, [], function () {
    app_helpers.write_message(
      LOG_LEVEL_INFO,
      'Updated database record for scene ' + scene_id
    )
  })
}

const make_filename = function (scene_id) {
  return scene_id + '.tar.gz'
}

main()<|endoftext|>


<commit_before>// Futuramente ver se é viável extinguir esse objeto, estendendo o objeto window do com o método singleton, dando poder a cada objeto de recuperar seu próprio singleton

// testing
// b = $('body')
// s = Singleton.saveState(o, 'id')
// Singleton.recover('id')

$(function() {

    Singleton = {

        instances: [],

        recover: function(identifier) {

            var obj = null;

            this.instances.each(function (i) {
                if ( typeof identifier === 'object' ) {
                    if ( i[identifier] === identifier) {
                        obj = i[identifier];
                    }
                } else {
                    if ( i['identifier'] === identifier) {
                        obj = i['instance'];
                    }
                }
            });

            if (obj) {
                return obj;
            }
            console.error('Instance not found!');
            return false;
        },

        // instanciar primeiro e guardar depois
        // parâmetros polimórficos. Instance e params poderão ser typeof string ou object
        saveState: function(instance, identifier) {
            var
                identifierExists_ = function() {
                    var
                        id = null,
                        obj = Singleton;

                    obj.instances.each(function (i) {
                        if ( i['identifier'] === identifier ) {
                            id = true;
                        }
                    });

                    if ( id ) {
                        return true;
                    }
                    return false;
                },

                instanceExists_ = function() {
                    var
                        id = null,
                        obj = Singleton;

                    obj.instances.each(function (i) {
                        if ( i['instance'] === instance ) {
                            id = true;
                        }
                    });

                    if ( id ) {
                        return true;
                    }
                    return false;
                },

                newObject = {};

            // adds a new
            if ( !instanceExists_() ) {
                if( identifier ) {
                    if ( !identifierExists_() ) {
                        newObject['identifier'] = identifier;
                        newObject['instance'] = instance;
                    } else {
                        console.error('Identifier already exists!');
                        return false;
                    }
                } else {
                    // O CODIGO DEVE MUDAR AQUI
                    console.warn('Identifier has not been defined!');
                    // newObject[instance.toString()] = instance;
                    newObject[instance] = instance;
                }
                this.instances.push(newObject);
            } else {
                if( identifier ) {
                    if ( !identifierExists_() ) {
                        newObject['identifier'] = identifier;
                        newObject['instance'] = instance;
                        this.instances = this.instances.without(instance);
                        this.instances.push(newObject);
                    } else {
                        console.error('Identifier already exists!');
                        return false;
                    }
                }
            }

            return this.instances[this.instances.length -1];

        },

    }
})
<commit_msg>Update singleton.js<commit_after>// Futuramente ver se é viável extinguir esse objeto, estendendo o objeto window do com o método singleton, dando poder a cada objeto de recuperar seu próprio singleton

// testing
// b = $('body')
// s = Singleton.saveState(o, 'id')
// Singleton.recover('id')

$(function() {

    Singleton = {

        instances: [],

        recover: function(identifier) {

            var obj = null;

            this.instances.map(function (i) {
                if ( typeof identifier === 'object' ) {
                    if ( i[identifier] === identifier) {
                        obj = i[identifier];
                    }
                } else {
                    if ( i['identifier'] === identifier) {
                        obj = i['instance'];
                    }
                }
            });

            if (obj) {
                return obj;
            }
            console.error('Instance not found!');
            return false;
        },

        // instanciar primeiro e guardar depois
        // parâmetros polimórficos. Instance e params poderão ser typeof string ou object
        saveState: function(instance, identifier) {
            var
                identifierExists_ = function() {
                    var
                        id = null,
                        obj = Singleton;

                    obj.instances.map(function (i) {
                        if ( i['identifier'] === identifier ) {
                            id = true;
                        }
                    });

                    if ( id ) {
                        return true;
                    }
                    return false;
                },

                instanceExists_ = function() {
                    var
                        id = null,
                        obj = Singleton;

                    obj.instances.map(function (i) {
                        if ( i['instance'] === instance ) {
                            id = true;
                        }
                    });

                    if ( id ) {
                        return true;
                    }
                    return false;
                },

                newObject = {};

            // adds a new
            if ( !instanceExists_() ) {
                if( identifier ) {
                    if ( !identifierExists_() ) {
                        newObject['identifier'] = identifier;
                        newObject['instance'] = instance;
                    } else {
                        console.error('Identifier already exists!');
                        return false;
                    }
                } else {
                    // O CODIGO DEVE MUDAR AQUI
                    console.warn('Identifier has not been defined!');
                    // newObject[instance.toString()] = instance;
                    newObject[instance] = instance;
                }
                this.instances.push(newObject);
            } else {
                if( identifier ) {
                    if ( !identifierExists_() ) {
                        newObject['identifier'] = identifier;
                        newObject['instance'] = instance;
                        this.instances = this.instances.without(instance);
                        this.instances.push(newObject);
                    } else {
                        console.error('Identifier already exists!');
                        return false;
                    }
                }
            }

            return this.instances[this.instances.length -1];

        },

    }
})
<|endoftext|>


<commit_before>const commander = require("commander");
const process = require("process");
const { spawn } = require("cross-spawn");
const fs = require("fs-extra");
const path = require("path");
const lazyMethodRequire = require("./lib/LazyMethodRequire").default(__dirname);

const newApp = lazyMethodRequire("./commands/new");
const startClient = lazyMethodRequire("./commands/start-client");
const startServer = lazyMethodRequire("./commands/start-server");
const startTest = lazyMethodRequire("./commands/test");
const generate = lazyMethodRequire("./commands/generate");
const destroy = lazyMethodRequire("./commands/destroy");
const dockerize = lazyMethodRequire("./commands/dockerize");

const updateLastVersionUsed = require("./lib/updateVersion");
const getVersion = require("./lib/getVersion");
const logger = require("./lib/logger");
const logsColorScheme = require("./lib/logsColorScheme");
const { highlight } = logsColorScheme;

const utils = require("./lib/utils");
const { quitUnlessGluestickProject } = utils;

const autoUpgrade = require("./autoUpgrade");

const isProduction = process.env.NODE_ENV === "production";

const IS_WINDOWS = process.platform === "win32";

const currentGluestickVersion = getVersion();

const debugServerOption = ["-D, --debug-server", "debug server side rendering with node-inspector"];
const debugTestOption = ["-B, --debug-test", "debug tests with node-inspector"];
const nodeTestOption = ["-m, --mocha-only", "run tests in Node.js"];
const mochaReporterOption = ["-r, --reporter [type]", "run tests in Node.js"];
const firefoxOption = ["-F, --firefox", "Use Firefox with test runner"];
const singleRunOption = ["-S, --single", "Run test suite only once"];

commander
  .version(currentGluestickVersion);

commander
  .command("touch")
  .description("update project version")
  .action(checkGluestickProject)
  .action(() => updateLastVersionUsed(currentGluestickVersion));

commander
  .command("new")
  .description("generate a new application")
  .arguments("<app_name>")
  .action((app_name) => {
    if(newApp(app_name)) {
      updateLastVersionUsed(currentGluestickVersion, false);
    }
  });

commander
  .command("generate <container|component|reducer>")
  .description("generate a new container")
  .arguments("<name>")
  .action(checkGluestickProject)
  .action((type, name) => generate(type, name, (err) => {
    if (err) { logger.error(err); }
  }))
  .action(() => updateLastVersionUsed(currentGluestickVersion));

commander
  .command("destroy <container|component|reducer>")
  .description("destroy a generated container")
  .arguments("<name>")
  .action(checkGluestickProject)
  .action(destroy)
  .action(() => updateLastVersionUsed(currentGluestickVersion));

commander
  .command("start")
  .description("start everything")
  .option("-T, --no-tests", "ignore test hook")
  .option(...debugServerOption)
  .option(...debugTestOption)
  .option(...mochaReporterOption)
  .option(...nodeTestOption)
  .action(checkGluestickProject)
  .action(() => notifyUpdates())
  .action(startAll)
  .action(() => updateLastVersionUsed(currentGluestickVersion));

commander
  .command("build")
  .description("create production asset build")
  .action(checkGluestickProject)
  .action(() => startClient(true))
  .action(() => updateLastVersionUsed(currentGluestickVersion));

commander
  .command("dockerize")
  .description("create docker image")
  .arguments("<name>")
  .action(checkGluestickProject)
  .action(upgradeAndDockerize)
  .action(() => updateLastVersionUsed(currentGluestickVersion));

commander
  .command("start-client", null, {noHelp: true})
  .description("start client")
  .action(checkGluestickProject)
  .action(() => startClient(false))
  .action(() => updateLastVersionUsed(currentGluestickVersion));

commander
  .command("start-server", null, {noHelp: true})
  .description("start server")
  .option(...debugServerOption)
  .option(...debugTestOption)
  .option(...mochaReporterOption)
  .action(checkGluestickProject)
  .action((options) => startServer(options.debugServer))
  .action(() => updateLastVersionUsed(currentGluestickVersion));

commander
  .command("start-test", null, {noHelp: true})
  .option(...firefoxOption)
  .option(...singleRunOption)
  .option(...nodeTestOption)
  .option(...debugTestOption)
  .option(...mochaReporterOption)
  .description("start test")
  .action(checkGluestickProject)
  .action(startTest)
  .action(() => updateLastVersionUsed(currentGluestickVersion));

commander
  .command("test")
  .option(...firefoxOption)
  .option(...singleRunOption)
  .option(...nodeTestOption)
  .option(...debugTestOption)
  .option(...mochaReporterOption)
  .description("start tests")
  .action(checkGluestickProject)
  .action(() => updateLastVersionUsed(currentGluestickVersion))
  .action(() => {
    const proc = spawnProcess("test", commander.rawArgs.slice(3));
    proc.on("close", code => { process.exit(code); });
  });

// This is a catch all command. DO NOT PLACE ANY COMMANDS BELOW THIS
commander
  .command("*", null, {noHelp: true})
  .action(function(cmd){
    logger.error(`Command '${highlight(cmd)}' not recognized`);
    commander.help();
  });

commander.parse(process.argv);

function checkGluestickProject () {
  quitUnlessGluestickProject(commander.rawArgs[2]);
}

function notifyUpdates () {
  const indexFilePath = path.join(process.cwd(), "Index.js");
  const data = fs.readFileSync(indexFilePath);
  if (data.indexOf("Helmet.rewind()") === -1) {
    logger.info(`
##########################################################################
Upgrade Notice: Newer versions of Index.js now include react-helmet
for allowing dynamic changes to document header data. You will need to
manually update your Index.js file to receive this change.
For a simple example see:
https://github.com/TrueCar/gluestick/blob/develop/templates/new/Index.js
##########################################################################
    `);
  }
}

function spawnProcess (type, args=[]) {
  let childProcess;
  const postFix = IS_WINDOWS ? ".cmd" : "";
  switch (type) {
    case "client":
      childProcess = spawn("gluestick" + postFix, ["start-client", ...args], {stdio: "inherit", env: Object.assign({}, process.env)});
      break;
    case "server":
      childProcess = spawn("gluestick" + postFix, ["start-server", ...args], {stdio: "inherit", env: Object.assign({}, process.env, {NODE_ENV: isProduction ? "production": "development-server"})});
      break;
    case "test":
      childProcess = spawn("gluestick" + postFix, ["start-test", ...args], {stdio: "inherit", env: Object.assign({}, process.env, {NODE_ENV: isProduction ? "production": "development-test"})});
      break;
    default:
      break;
  }
  childProcess.on("error", function () { logger.error(JSON.stringify(arguments)); });
  return childProcess;
}

/*
 * Start server and (optionally) tests in different processes.
 *
 * @param {object} options        Command-line options object directly from Commander
 */
async function startAll(options) {
  try {
    await autoUpgrade();
  }
  catch (e) {
    logger.error(`During auto upgrade: ${e}`);
    process.exit();
  }

  spawnProcess("client");
  spawnProcess("server", (options.debugServer ? ["--debug-server"] : []));

  // Start tests unless they asked us not to or we are in production mode
  if (!isProduction && !options.noTests) {
    spawnProcess("test", commander.rawArgs.slice(3));
  }
}

async function upgradeAndDockerize (name) {
  await autoUpgrade();
  dockerize(name);
}

<commit_msg>Rename "--no-tests" to "--skip-tests". Commander seems to have special handling for "no".<commit_after>const commander = require("commander");
const process = require("process");
const { spawn } = require("cross-spawn");
const fs = require("fs-extra");
const path = require("path");
const lazyMethodRequire = require("./lib/LazyMethodRequire").default(__dirname);

const newApp = lazyMethodRequire("./commands/new");
const startClient = lazyMethodRequire("./commands/start-client");
const startServer = lazyMethodRequire("./commands/start-server");
const startTest = lazyMethodRequire("./commands/test");
const generate = lazyMethodRequire("./commands/generate");
const destroy = lazyMethodRequire("./commands/destroy");
const dockerize = lazyMethodRequire("./commands/dockerize");

const updateLastVersionUsed = require("./lib/updateVersion");
const getVersion = require("./lib/getVersion");
const logger = require("./lib/logger");
const logsColorScheme = require("./lib/logsColorScheme");
const { highlight } = logsColorScheme;

const utils = require("./lib/utils");
const { quitUnlessGluestickProject } = utils;

const autoUpgrade = require("./autoUpgrade");

const isProduction = process.env.NODE_ENV === "production";

const IS_WINDOWS = process.platform === "win32";

const currentGluestickVersion = getVersion();

const debugServerOption = ["-D, --debug-server", "debug server side rendering with node-inspector"];
const debugTestOption = ["-B, --debug-test", "debug tests with node-inspector"];
const nodeTestOption = ["-m, --mocha-only", "run tests in Node.js"];
const mochaReporterOption = ["-r, --reporter [type]", "run tests in Node.js"];
const firefoxOption = ["-F, --firefox", "Use Firefox with test runner"];
const singleRunOption = ["-S, --single", "Run test suite only once"];

commander
  .version(currentGluestickVersion);

commander
  .command("touch")
  .description("update project version")
  .action(checkGluestickProject)
  .action(() => updateLastVersionUsed(currentGluestickVersion));

commander
  .command("new")
  .description("generate a new application")
  .arguments("<app_name>")
  .action((app_name) => {
    if(newApp(app_name)) {
      updateLastVersionUsed(currentGluestickVersion, false);
    }
  });

commander
  .command("generate <container|component|reducer>")
  .description("generate a new container")
  .arguments("<name>")
  .action(checkGluestickProject)
  .action((type, name) => generate(type, name, (err) => {
    if (err) { logger.error(err); }
  }))
  .action(() => updateLastVersionUsed(currentGluestickVersion));

commander
  .command("destroy <container|component|reducer>")
  .description("destroy a generated container")
  .arguments("<name>")
  .action(checkGluestickProject)
  .action(destroy)
  .action(() => updateLastVersionUsed(currentGluestickVersion));

commander
  .command("start")
  .description("start everything")
  .option("-T, --skip-tests", "ignore test hook")
  .option(...debugServerOption)
  .option(...debugTestOption)
  .option(...mochaReporterOption)
  .option(...nodeTestOption)
  .action(checkGluestickProject)
  .action(() => notifyUpdates())
  .action(startAll)
  .action(() => updateLastVersionUsed(currentGluestickVersion));

commander
  .command("build")
  .description("create production asset build")
  .action(checkGluestickProject)
  .action(() => startClient(true))
  .action(() => updateLastVersionUsed(currentGluestickVersion));

commander
  .command("dockerize")
  .description("create docker image")
  .arguments("<name>")
  .action(checkGluestickProject)
  .action(upgradeAndDockerize)
  .action(() => updateLastVersionUsed(currentGluestickVersion));

commander
  .command("start-client", null, {noHelp: true})
  .description("start client")
  .action(checkGluestickProject)
  .action(() => startClient(false))
  .action(() => updateLastVersionUsed(currentGluestickVersion));

commander
  .command("start-server", null, {noHelp: true})
  .description("start server")
  .option(...debugServerOption)
  .option(...debugTestOption)
  .option(...mochaReporterOption)
  .action(checkGluestickProject)
  .action((options) => startServer(options.debugServer))
  .action(() => updateLastVersionUsed(currentGluestickVersion));

commander
  .command("start-test", null, {noHelp: true})
  .option(...firefoxOption)
  .option(...singleRunOption)
  .option(...nodeTestOption)
  .option(...debugTestOption)
  .option(...mochaReporterOption)
  .description("start test")
  .action(checkGluestickProject)
  .action(startTest)
  .action(() => updateLastVersionUsed(currentGluestickVersion));

commander
  .command("test")
  .option(...firefoxOption)
  .option(...singleRunOption)
  .option(...nodeTestOption)
  .option(...debugTestOption)
  .option(...mochaReporterOption)
  .description("start tests")
  .action(checkGluestickProject)
  .action(() => updateLastVersionUsed(currentGluestickVersion))
  .action(() => {
    const proc = spawnProcess("test", commander.rawArgs.slice(3));
    proc.on("close", code => { process.exit(code); });
  });

// This is a catch all command. DO NOT PLACE ANY COMMANDS BELOW THIS
commander
  .command("*", null, {noHelp: true})
  .action(function(cmd){
    logger.error(`Command '${highlight(cmd)}' not recognized`);
    commander.help();
  });

commander.parse(process.argv);

function checkGluestickProject () {
  quitUnlessGluestickProject(commander.rawArgs[2]);
}

function notifyUpdates () {
  const indexFilePath = path.join(process.cwd(), "Index.js");
  const data = fs.readFileSync(indexFilePath);
  if (data.indexOf("Helmet.rewind()") === -1) {
    logger.info(`
##########################################################################
Upgrade Notice: Newer versions of Index.js now include react-helmet
for allowing dynamic changes to document header data. You will need to
manually update your Index.js file to receive this change.
For a simple example see:
https://github.com/TrueCar/gluestick/blob/develop/templates/new/Index.js
##########################################################################
    `);
  }
}

function spawnProcess (type, args=[]) {
  let childProcess;
  const postFix = IS_WINDOWS ? ".cmd" : "";
  switch (type) {
    case "client":
      childProcess = spawn("gluestick" + postFix, ["start-client", ...args], {stdio: "inherit", env: Object.assign({}, process.env)});
      break;
    case "server":
      childProcess = spawn("gluestick" + postFix, ["start-server", ...args], {stdio: "inherit", env: Object.assign({}, process.env, {NODE_ENV: isProduction ? "production": "development-server"})});
      break;
    case "test":
      childProcess = spawn("gluestick" + postFix, ["start-test", ...args], {stdio: "inherit", env: Object.assign({}, process.env, {NODE_ENV: isProduction ? "production": "development-test"})});
      break;
    default:
      break;
  }
  childProcess.on("error", function () { logger.error(JSON.stringify(arguments)); });
  return childProcess;
}

/*
 * Start server and (optionally) tests in different processes.
 *
 * @param {object} options        Command-line options object directly from Commander
 */
async function startAll(options) {
  try {
    await autoUpgrade();
  }
  catch (e) {
    logger.error(`During auto upgrade: ${e}`);
    process.exit();
  }

  spawnProcess("client");
  spawnProcess("server", (options.debugServer ? ["--debug-server"] : []));

  // Start tests unless they asked us not to or we are in production mode
  if (!isProduction && !options.skipTests) {
    spawnProcess("test", commander.rawArgs.slice(3));
  }
}

async function upgradeAndDockerize (name) {
  await autoUpgrade();
  dockerize(name);
}

<|endoftext|>


<commit_before>import _ from 'lodash';
import fs from 'fs';
import Promise from 'bluebird';
import urlParse from 'url-parse';

module.exports = function ({vorpal, driver: {current}}){

  vorpal
    .command('switchWindow', 'Switch to a window')
    .action(function *(){
      const {value: windows} = yield current.windowHandles();
      console.log(windows)
      const windowWithUrl = yield Promise.mapSeries(windows, (id =>
        current
        // .window(`{${id}}`) &&
        .window(id)
        .then(data =>
          current
            .url()
            .then(({value: url}) => console.log(id, url) || ({id, url}))

        ))
      );
      windowWithUrl.forEach(({id, url}, i) => vorpal.log(`[${i}] ${id} => ${url}`));
      return this.prompt({
        type: 'input',
        name: 'window',
        deafult: 0,
        message: 'Select the browser window to switch to?'
      }, (index) => {
        const {id: selectedWindowId} =_.get(windowWithUrl, `[${index}]`, 0);
        console.log(selectedWindowId)
        current.window(selectedWindowId);
      })
      return Promise.resolve();
    });

  vorpal
    .command('switchSession', 'Switch to a session')
    .action(function *(){
      const {value: sessions} = yield current.sessions();
      const sessionsWithUrls = yield Promise.all(sessions.map(({id}) =>
            current
              .sessionID(id)
              .url()
              .then(({value: url}) => ({id, url}))
          ));
      sessionsWithUrls.forEach(({id, url}, i) => vorpal.log(`[${i}] ${id} => ${url}`));
      return this.prompt({
        type: 'input',
        name: 'session',
        deafult: 0,
        message: 'Select the browser session to switch to?'
      }, (sessionId) => {
        current.sessionID(_.get(sessionsWithUrls, `[${sessionId}]`, 0))
      })
      return Promise.resolve();
    });

  vorpal
    .command('syncCookies [file]', 'Sync Browser cookies with the file')
    .action(async ({file = '/tmp/cookies.json'} = {}) => {
      let currentCookies = await current.cookie();
      currentCookies = currentCookies.value;
      try {
        const savedCookies = require(file);
        // console.log('file' , fileContent);
        // const savedCookies = JSON.parse(fileContent);
        currentCookies = _.unionBy(savedCookies, currentCookies, JSON.stringify);
        console.log('cookies are merged');
      } catch (e){
        console.log('cookies in the file are discared');
      }
      console.log(currentCookies)
      fs.writeFileSync(file, JSON.stringify(currentCookies) + '\n');
      await Promise.mapSeries(currentCookies,
        cookie => current.setCookie(cookie).catch(e => e)
      );
    });
};
<commit_msg>feat(framework): added goto builtin method to go to urls without protocol<commit_after>import _ from 'lodash';
import fs from 'fs';
import Promise from 'bluebird';
import URL from 'url-parse';

module.exports = ({ vorpal, driver: { current } }) => {
  vorpal
    .command('goto <url>', 'Open the given url. Prefix http:// if not available')
    .action(function* ({ url }) {
      const fullUrl = new URL(url);
      fullUrl.set('protocol', fullUrl.protocol || 'http');
      console.log(`navigating to ${fullUrl.toString()}`);
      return current.url(fullUrl.toString());
    });

  vorpal
    .command('switchWindow', 'Switch to a window')
    .action(function* () {
      const { value: windows } = yield current.windowHandles();
      console.log(windows);
      const windowWithUrl = yield Promise.mapSeries(windows,
        (id =>
          current
          .window(id)
          .then(() =>
            current
            .url()
            .then(({ value: url }) => console.log(id, url) || ({ id, url })))
        ));
      windowWithUrl.forEach(({ id, url }, i) => vorpal.log(`[${i}] ${id} => ${url}`));
      return this.prompt({
        type: 'input',
        name: 'window',
        deafult: 0,
        message: 'Select the browser window to switch to?',
      }, (index) => {
        const { id: selectedWindowId } =_.get(windowWithUrl, `[${index}]`, 0);
        console.log(selectedWindowId);
        current.window(selectedWindowId);
      });
    });

  vorpal
    .command('switchSession', 'Switch to a session')
    .action(function* () {
      const { value: sessions } = yield current.sessions();
      const sessionsWithUrls = yield Promise.all(sessions.map(({ id }) =>
            current
              .sessionID(id)
              .url()
              .then(({ value: url }) => ({ id, url }))));
      sessionsWithUrls.forEach(({ id, url }, i) => vorpal.log(`[${i}] ${id} => ${url}`));
      return this.prompt({
        type: 'input',
        name: 'session',
        deafult: 0,
        message: 'Select the browser session to switch to?',
      }, (sessionId) => {
        current.sessionID(_.get(sessionsWithUrls, `[${sessionId}]`, 0));
      });
    });

  vorpal
    .command('syncCookies [file]', 'Sync Browser cookies with the file')
    .action(async ({ file = '/tmp/cookies.json' } = {}) => {
      let currentCookies = await current.cookie();
      currentCookies = currentCookies.value;
      try {
        const savedCookies = require(file);
        // console.log('file' , fileContent);
        // const savedCookies = JSON.parse(fileContent);
        currentCookies = _.unionBy(savedCookies, currentCookies, JSON.stringify);
        console.log('cookies are merged');
      } catch (e) {
        console.log('cookies in the file are discared');
      }
      console.log(currentCookies);
      fs.writeFileSync(file, `${JSON.stringify(currentCookies)}\n`);
      await Promise.mapSeries(currentCookies, cookie => current.setCookie(cookie).catch(e => e)
      );
    });
};
<|endoftext|>


<commit_before>var
    esPhinx,
    Iterable;

(function($) {
    "use strict";

    $.extend({
        text: function(text) {
            return $(window.document.createTextNode(text));
        }
    });

    $.prototype.extend({

        //
|

        // text: function() {
        // },

        insertAfter: function(element) {
            var
                elements = $(element),

                callback = function(element2Insert) {
                    var
                        iteratorBlock = function(element) {
                            // element = $(element);
                            // sibling = element.next();
                            // debugger
                            // if (sibling.some()) {
                            //     $(element).insertBefore(sibling);
                            // } else {
                            //     element.parent().append(element);
                            // }
                            element.parentNode.insertBefore(element2Insert,
                                                            element.nextSibling);
                        };

                    elements.each(iteratorBlock);
                };

            this.each(callback);

            return this;
        },

        insertBefore: function(element) {
            var
                elements = $(element),

                callback = function(element2Insert) {
                    var
                        iteratorBlock = function(element) {
                            element.parentNode.insertBefore(element2Insert, element);
                        };

                    elements.each(iteratorBlock);
                };

            this.each(callback);

            return this;
        },

        append: function(node) {
            var
                nodes,

                callback = function(element) {
                    var
                        iteratorBlock = function(node) {
                            element.appendChild(node);
                        };

                    nodes.each(iteratorBlock);
                };

            nodes = $(node);
            if (nodes.empty()) {
                nodes = $(window.document.createTextNode(node));
            }

            this.each(callback);

            return this;
        },

        prepend: function(node) {
            var
                firstNode,

                callback = function(element) {
                    firstNode = $(element).firstNode();
                    if (firstNode.some()) {
                        node.insertBefore(firstNode);
                    } else {
                        $(element).append(node);
                    }
                };

            node = $(node);
            if (node.empty()) {
                node = $(window.document.createTextNode(node));
            }

            this.each(callback);

            return this;
        },

        textContent: function() {
            var
                tagName = this.tagName(),
                node = this.asNode();

            if (tagName != "pre") {
                return node.textContent.replace(/\n[ \t]*/g, "")
                    .replace(/(\n){2,}/g, "");
            }

            return node.textContent;
        },

        // "extends?" would make more sense in the relationship between classes
        isA: function(constructor) {
            return this.asNode() instanceof constructor;
        },

        // remove: function(object, delay = 0) {
        remove: function(object, delay) {
            if (typeof delay != "number") {delay = 0;}

            var
                self = this,

                remove = function(element) {
                    element.remove();
                },

                resolveArguments = function() {
                    if (typeof object == "number") {
                        delay = object;
                        object = undefined;
                    } else if (typeof delay != "number") {
                        delay = 0;
                    }
                };

            resolveArguments();

            if (object) {
                // recursivity
                $(object).remove(delay);
            } else {
                if (delay) {
                    window.setTimeout(function() {
                        self.each(remove);
                    }, delay);
                } else {
                    self.each(remove);
                }
            }

            return self;
        },

        clean: function() {
            var
                callback = function(element) {
                    element.innerHTML = null;
                };

            this.each(callback);

            return this;
        },

        hasClass: function(classList) {
            var
                element = $(this.asNode()),
                pattern;

            if (arguments.length > 1) {
                classList = Array.from(arguments);
                pattern = new RegExp("(?=.*(\\b" + classList
                    .join("(?=(\\b| ))))(?=.*(\\b") +
                                     "(?=(\\b| )))).*", "g");
            } else {
                pattern = new RegExp("(?=.*(\\b" + classList.split(" ")
                    .join("(?=(\\b| ))))(?=.*(\\b") +
                                     "(?=(\\b| )))).*", "g");
            }

            return pattern.test(element.attribute("class"));
        },

        is: function(comparedNode) {
            var
                asIterable,
                comparedAsIterable,
                asIterableIterator,
                comparedAsIterableIterator,
                response = false,

                callback = function(node) {
                    var
                        iteratorBlock = function(compared) {
                            if (node.isEqualNode(compared)) {
                                response = true;
                                this.finalize();
                                asIterableIterator.finalize();
                            }
                        };

                    if (comparedNode.some()) {
                        comparedAsIterable = Array.from(comparedNode);
                        comparedAsIterableIterator = Iterable.Proxy
                            .new(comparedAsIterable);
                        comparedAsIterableIterator
                            .each(iteratorBlock);
                    }
                };

            if (Object.hasSameClass(comparedNode, this) ||
                typeof comparedNode == "string" ||
                comparedNode instanceof window.Node ||
                comparedNode instanceof Array) {
                comparedNode = $(comparedNode);
            }

            if (this.some()) {
                asIterable = this.asArray();

                asIterableIterator = Iterable.Proxy.new(asIterable);
                asIterableIterator.each(callback);
            }

            return response;
        }

    });

}(esPhinx));

/*$.prototype.ancestors = function(nodeName) {
    var _parents = []
        ,parent = null
    ;
    collection.forEach(function(e) {
        parent = e.parentNode;
        if (nodeName) {
            if (parent.nodeName.toLowerCase() == nodeName) {
                _parents.push(parent);
            } else {
                while (true) {
                    parent = parent.parentNode;
                    if(parent){
                        if(parent.nodeName.toLowerCase() == nodeName) {
                            _parents.push(parent);
                            break;
                        }
                    } else {
                        break;
                    }
                }
            }
        } else {
            if(parent){
                _parents.push(parent);
            }
        }
    });
    return _parents;
}*/
<commit_msg>refactor node<commit_after>var
    esPhinx,
    Iterable;

(function($) {
    "use strict";

    $.extend({
        text: function(text) {
            return $(window.document.createTextNode(text));
        }
    });

    $.prototype.extend({

        //
|

        // text: function() {
        // },

        hasClass: function(classList) {
            var
                element = $(this.asNode()),
                pattern;

            if (arguments.length > 1) {
                classList = Array.from(arguments);
            } else {
                classList = classList.split(" ");
            }

            pattern = new RegExp("(?=.*(\\b" + classList
                                 .join("(?=(\\b| ))))(?=.*(\\b") +
                                     "(?=(\\b| )))).*", "g");

            return pattern.test(element.attribute("class"));
        },

        insertAfter: function(element) {
            var
                elements = $(element),

                callback = function(element2Insert) {
                    var
                        iteratorBlock = function(element) {
                            // element = $(element);
                            // sibling = element.next();
                            // debugger
                            // if (sibling.some()) {
                            //     $(element).insertBefore(sibling);
                            // } else {
                            //     element.parent().append(element);
                            // }
                            element.parentNode.insertBefore(element2Insert,
                                                            element.nextSibling);
                        };

                    elements.each(iteratorBlock);
                };

            this.each(callback);

            return this;
        },

        insertBefore: function(element) {
            var
                elements = $(element),

                callback = function(element2Insert) {
                    var
                        iteratorBlock = function(element) {
                            element.parentNode.insertBefore(element2Insert, element);
                        };

                    elements.each(iteratorBlock);
                };

            this.each(callback);

            return this;
        },

        append: function(node) {
            var
                nodes,

                callback = function(element) {
                    var
                        iteratorBlock = function(node) {
                            element.appendChild(node);
                        };

                    nodes.each(iteratorBlock);
                };

            nodes = $(node);
            if (nodes.empty()) {
                nodes = $(window.document.createTextNode(node));
            }

            this.each(callback);

            return this;
        },

        prepend: function(node) {
            var
                firstNode,

                callback = function(element) {
                    firstNode = $(element).firstNode();
                    if (firstNode.some()) {
                        node.insertBefore(firstNode);
                    } else {
                        $(element).append(node);
                    }
                };

            node = $(node);
            if (node.empty()) {
                node = $(window.document.createTextNode(node));
            }

            this.each(callback);

            return this;
        },

        textContent: function() {
            var
                tagName = this.tagName(),
                node = this.asNode();

            if (tagName != "pre") {
                return node.textContent.replace(/\n[ \t]*/g, "")
                    .replace(/(\n){2,}/g, "");
            }

            return node.textContent;
        },

        // "extends?" would make more sense in the relationship between classes
        isA: function(constructor) {
            return this.asNode() instanceof constructor;
        },

        // remove: function(object, delay = 0) {
        remove: function(object, delay) {
            if (typeof delay != "number") {delay = 0;}

            var
                self = this,

                remove = function(element) {
                    element.remove();
                },

                resolveArguments = function() {
                    if (typeof object == "number") {
                        delay = object;
                        object = undefined;
                    } else if (typeof delay != "number") {
                        delay = 0;
                    }
                };

            resolveArguments();

            if (object) {
                // recursivity
                $(object).remove(delay);
            } else {
                if (delay) {
                    window.setTimeout(function() {
                        self.each(remove);
                    }, delay);
                } else {
                    self.each(remove);
                }
            }

            return self;
        },

        clean: function() {
            var
                callback = function(element) {
                    element.innerHTML = null;
                };

            this.each(callback);

            return this;
        },

        is: function(comparedNode) {
            var
                asIterable,
                comparedAsIterable,
                asIterableIterator,
                comparedAsIterableIterator,
                response = false,

                callback = function(node) {
                    var
                        iteratorBlock = function(compared) {
                            if (node.isEqualNode(compared)) {
                                response = true;
                                this.finalize();
                                asIterableIterator.finalize();
                            }
                        };

                    if (comparedNode.some()) {
                        comparedAsIterable = Array.from(comparedNode);
                        comparedAsIterableIterator = Iterable.Proxy
                            .new(comparedAsIterable);
                        comparedAsIterableIterator
                            .each(iteratorBlock);
                    }
                };

            if (Object.hasSameClass(comparedNode, this) ||
                typeof comparedNode == "string" ||
                comparedNode instanceof window.Node ||
                comparedNode instanceof Array) {
                comparedNode = $(comparedNode);
            }

            if (this.some()) {
                asIterable = this.asArray();

                asIterableIterator = Iterable.Proxy.new(asIterable);
                asIterableIterator.each(callback);
            }

            return response;
        }

    });

}(esPhinx));

/*$.prototype.ancestors = function(nodeName) {
    var _parents = []
        ,parent = null
    ;
    collection.forEach(function(e) {
        parent = e.parentNode;
        if (nodeName) {
            if (parent.nodeName.toLowerCase() == nodeName) {
                _parents.push(parent);
            } else {
                while (true) {
                    parent = parent.parentNode;
                    if(parent){
                        if(parent.nodeName.toLowerCase() == nodeName) {
                            _parents.push(parent);
                            break;
                        }
                    } else {
                        break;
                    }
                }
            }
        } else {
            if(parent){
                _parents.push(parent);
            }
        }
    });
    return _parents;
}*/
<|endoftext|>


<commit_before>'use strict';

var fs = require("fs");
var path = require("path");
var join = path.join;
var crypto = require("crypto");
var spawn = require("child_process").spawn;
var wrench = require("wrench");
var archiver = require("archiver");
var rm = require('rimraf');
var Promise = require('es6-promise').Promise;

function ChromeExtension(attrs) {
  if ((this instanceof ChromeExtension) !== true) {
    return new ChromeExtension(attrs);
  }

  /*
   Defaults
   */
  this.manifest = '';

  this.loaded = false;

  this.package = null;

  this.rootDirectory = '';

  this.publicKey = null;

  this.privateKey = null;

  this.signature = null;

  this.contents = null;

  this.codebase = null;

  /*
  Copying attributes
   */
  for (var name in attrs) {
    this[name] = attrs[name];
  }

  this.path = join("tmp", "crx-" + (Math.random() * 1e17).toString(36))
}

ChromeExtension.prototype = {

  /**
   * Destroys generated files.
   *
   * @returns {Promise}
   */
  destroy: function () {
    var path = this.path;

    return new Promise(function(resolve, reject){
      rm(path, function(err){
        if (err){
          return reject(err);
        }

        resolve();
      });
    });
  },

  pack: function (cb) {
    if (!this.loaded) return this.load(function (err) {
      return err ? cb(err) : this.pack(cb)
    });

    this.generatePublicKey(function (err) {
      if (err) return cb(err);

      var manifest = JSON.stringify(this.manifest);

      this.writeFile("manifest.json", manifest, function (err) {
        if (err) return cb(err);

        this.loadContents(function (err) {
          if (err) return cb(err);

          this.generateSignature();
          this.generatePackage();

          cb.call(this, null, this.package)
        })
      })
    })
  },

  load: function (cb) {
    if (!fs.existsSync("tmp")) {
      fs.mkdirSync("tmp");
    }

    wrench.copyDirRecursive(this.rootDirectory, this.path, function (err) {
      if (err) {
        throw err
      }
      this.manifest = require(join(process.cwd(), this.path, "manifest.json"));
      this.loaded = true;

      cb.call(this);
    }.bind(this));
  },

  readFile: function (name, cb) {
    var path = join(this.path, name);

    fs.readFile(path, "binary", function (err, data) {
      if (err) return cb.call(this, err);

      cb.call(this, null, this[name] = data)
    }.bind(this));
  },

  writeFile: function (path, data, cb) {
    path = join(this.path, path);

    fs.writeFile(path, data, function (err, data) {
      if (err) return cb.call(this, err);

      cb.call(this)
    }.bind(this));
  },

  generatePublicKey: function (cb) {
    var rsa = spawn("openssl", ["rsa", "-pubout", "-outform", "DER"])

    rsa.stdout.on("data", function (data) {
      this.publicKey = data;
      cb && cb.call(this, null, this)
    }.bind(this));

    rsa.stdin.end(this.privateKey)
  },

  generateSignature: function () {
    return this.signature = new Buffer(
      crypto
        .createSign("sha1")
        .update(this.contents)
        .sign(this.privateKey),

      "binary"
    )
  },

  loadContents: function (cb) {
    var archive = archiver("zip");
    this.contents = "";

    var files = wrench.readdirSyncRecursive(this.path);

    files.forEach(function (current) {
      var stat = fs.statSync(join(this.path, current));

      if (stat.isFile() && current !== "key.pem") {
        archive.append(fs.createReadStream(join(this.path, current)), {name: current})
      }
    }, this);

    archive.finalize();

    // Relates to the issue: "Event 'finished' no longer valid #18"
    // https://github.com/jed/crx/issues/18
    // TODO: Buffer concat could be a problem when building a big extension.
    //       So ideally only the 'finish' callback must be used.
    archive.on('readable', function () {
      this.contents = !this.contents.length ? archive.read() : Buffer.concat([this.contents, archive.read()]);
    }.bind(this));

    archive.on('finish', function () {
      cb.call(this);
    }.bind(this));

    archive.on("error", function (err) {
      throw err;
    });
  },

  generatePackage: function () {
    var signature = this.signature;
    var publicKey = this.publicKey;
    var contents = this.contents;

    var keyLength = publicKey.length;
    var sigLength = signature.length;
    var zipLength = contents.length;
    var length = 16 + keyLength + sigLength + zipLength;

    var crx = new Buffer(length);

    crx.write("Cr24" + Array(13).join("\x00"), "binary");

    crx[4] = 2;
    crx.writeUInt32LE(keyLength, 8);
    crx.writeUInt32LE(sigLength, 12);

    publicKey.copy(crx, 16);
    signature.copy(crx, 16 + keyLength);
    contents.copy(crx, 16 + keyLength + sigLength);

    return this.package = crx
  },

  generateAppId: function () {
    return this.appId = crypto
      .createHash("sha256")
      .update(this.publicKey)
      .digest("hex")
      .slice(0, 32)
      .replace(/./g, function (x) {
        return (parseInt(x, 16) + 10).toString(26);
      });
  },

  generateUpdateXML: function () {
    if (!this.codebase) throw new Error("No URL provided for update.xml.");

    return this.updateXML =
      Buffer(
        "<?xml version='1.0' encoding='UTF-8'?>\n" +
        "<gupdate xmlns='http://www.google.com/update2/response' protocol='2.0'>\n" +
        "  <app appid='" + this.generateAppId() + "'>\n" +
        "    <updatecheck codebase='" + this.codebase + "' version='" + this.manifest.version + "' />\n" +
        "  </app>\n" +
        "</gupdate>"
      );
  }
};

module.exports = ChromeExtension;
<commit_msg>`load` as promise.<commit_after>'use strict';

var fs = require("fs");
var path = require("path");
var join = path.join;
var crypto = require("crypto");
var spawn = require("child_process").spawn;
var wrench = require("wrench");
var archiver = require("archiver");
var rm = require('rimraf');
var Promise = require('es6-promise').Promise;

function ChromeExtension(attrs) {
  if ((this instanceof ChromeExtension) !== true) {
    return new ChromeExtension(attrs);
  }

  /*
   Defaults
   */
  this.manifest = '';

  this.loaded = false;

  this.package = null;

  this.rootDirectory = '';

  this.publicKey = null;

  this.privateKey = null;

  this.signature = null;

  this.contents = null;

  this.codebase = null;

  /*
  Copying attributes
   */
  for (var name in attrs) {
    this[name] = attrs[name];
  }

  this.path = join("tmp", "crx-" + (Math.random() * 1e17).toString(36))
}

ChromeExtension.prototype = {

  /**
   * Destroys generated files.
   *
   * @returns {Promise}
   */
  destroy: function () {
    var path = this.path;

    return new Promise(function(resolve, reject){
      rm(path, function(err){
        if (err){
          return reject(err);
        }

        resolve();
      });
    });
  },

  pack: function (cb) {
    if (!this.loaded) {
      return this.load().then(this.pack.bind(this, cb));
    }

    this.generatePublicKey(function (err) {
      if (err) return cb(err);

      var manifest = JSON.stringify(this.manifest);

      this.writeFile("manifest.json", manifest, function (err) {
        if (err) return cb(err);

        this.loadContents(function (err) {
          if (err) return cb(err);

          this.generateSignature();
          this.generatePackage();

          cb.call(this, null, this.package)
        })
      })
    })
  },

  /**
   * Loads extension manifest and copies its content to a workable path.
   *
   * @returns {Promise}
   */
  load: function () {
    if (!fs.existsSync("tmp")) {
      fs.mkdirSync("tmp");
    }

    var selfie = this;

    return new Promise(function(resolve, reject){
      wrench.copyDirRecursive(selfie.rootDirectory, selfie.path, function (err) {
        if (err) {
          return reject(err);
        }

        selfie.manifest = require(join(process.cwd(), selfie.path, "manifest.json"));
        selfie.loaded = true;

        resolve(selfie);
      });
    });
  },

  readFile: function (name, cb) {
    var path = join(this.path, name);

    fs.readFile(path, "binary", function (err, data) {
      if (err) return cb.call(this, err);

      cb.call(this, null, this[name] = data)
    }.bind(this));
  },

  writeFile: function (path, data, cb) {
    path = join(this.path, path);

    fs.writeFile(path, data, function (err, data) {
      if (err) return cb.call(this, err);

      cb.call(this)
    }.bind(this));
  },

  generatePublicKey: function (cb) {
    var rsa = spawn("openssl", ["rsa", "-pubout", "-outform", "DER"])

    rsa.stdout.on("data", function (data) {
      this.publicKey = data;
      cb && cb.call(this, null, this)
    }.bind(this));

    rsa.stdin.end(this.privateKey)
  },

  generateSignature: function () {
    return this.signature = new Buffer(
      crypto
        .createSign("sha1")
        .update(this.contents)
        .sign(this.privateKey),

      "binary"
    )
  },

  loadContents: function (cb) {
    var archive = archiver("zip");
    this.contents = "";

    var files = wrench.readdirSyncRecursive(this.path);

    files.forEach(function (current) {
      var stat = fs.statSync(join(this.path, current));

      if (stat.isFile() && current !== "key.pem") {
        archive.append(fs.createReadStream(join(this.path, current)), {name: current})
      }
    }, this);

    archive.finalize();

    // Relates to the issue: "Event 'finished' no longer valid #18"
    // https://github.com/jed/crx/issues/18
    // TODO: Buffer concat could be a problem when building a big extension.
    //       So ideally only the 'finish' callback must be used.
    archive.on('readable', function () {
      this.contents = !this.contents.length ? archive.read() : Buffer.concat([this.contents, archive.read()]);
    }.bind(this));

    archive.on('finish', function () {
      cb.call(this);
    }.bind(this));

    archive.on("error", function (err) {
      throw err;
    });
  },

  generatePackage: function () {
    var signature = this.signature;
    var publicKey = this.publicKey;
    var contents = this.contents;

    var keyLength = publicKey.length;
    var sigLength = signature.length;
    var zipLength = contents.length;
    var length = 16 + keyLength + sigLength + zipLength;

    var crx = new Buffer(length);

    crx.write("Cr24" + Array(13).join("\x00"), "binary");

    crx[4] = 2;
    crx.writeUInt32LE(keyLength, 8);
    crx.writeUInt32LE(sigLength, 12);

    publicKey.copy(crx, 16);
    signature.copy(crx, 16 + keyLength);
    contents.copy(crx, 16 + keyLength + sigLength);

    return this.package = crx
  },

  generateAppId: function () {
    return this.appId = crypto
      .createHash("sha256")
      .update(this.publicKey)
      .digest("hex")
      .slice(0, 32)
      .replace(/./g, function (x) {
        return (parseInt(x, 16) + 10).toString(26);
      });
  },

  generateUpdateXML: function () {
    if (!this.codebase) throw new Error("No URL provided for update.xml.");

    return this.updateXML =
      Buffer(
        "<?xml version='1.0' encoding='UTF-8'?>\n" +
        "<gupdate xmlns='http://www.google.com/update2/response' protocol='2.0'>\n" +
        "  <app appid='" + this.generateAppId() + "'>\n" +
        "    <updatecheck codebase='" + this.codebase + "' version='" + this.manifest.version + "' />\n" +
        "  </app>\n" +
        "</gupdate>"
      );
  }
};

module.exports = ChromeExtension;
<|endoftext|>


<commit_before>/*jslint evil: false, bitwise:false, strict: true, undef: true, white:true, onevar:false, browser:true, plusplus:false */
/*global jQuery, Capture:true, window */
/**
 *  Capture.js
 *  v1.0.0
 *  Copyright 2011 Adam Craven
 *  Freely distributable under the MIT License.
 *  https://github.com/AdmCrvn/Capture
 */
(function ($) {
    "use strict";

    if (typeof Capture !== "undefined") {
        throw new Error('Capture is already defined');
    }

    var bind = Function.prototype.bind;
    var slice = Array.prototype.slice;
    var toString = Object.prototype.toString;
    var UNDEFINED;

    // All properties with prefix of 'on' are treated as event delegates
    var eventMethodPrefix = /^on(.+)/;

    /**
     *  Native ECMAScript 5 bind if supported or passes to jQuery proxy.
     *  @param  {function}  fn    Function to bind.
     *  @param  {object}  scope Scope in which to bind the function.
     */
    function bindScope(fn, scope) {
        if (bind && fn.bind === bind) {
            return bind.apply(fn, slice.call(arguments, 1));
        }
        return $.proxy(fn, scope);
    }

    /**
     *  Validates the view when captured, checking for basic errors
     */
    function validate(element, view) {
        if (!view) {
            throw new Error('Capture.js; No view passed. You must attach a view object or constructor. e.g. $("el").capture(view)');
        }

        if (toString.call(view) !== '[object Object]') {
            throw new Error('Capture.js; Invalid view type. The view must be an object or a constructor.');
        }

        if (element.length === 0 || !element.each) {
            throw new Error('Capture.js; No element found. You must attach the view to an element.');
        }
    }

    /**
     *  Adds listeners to the view.
     *  By default all methods that have the valid prefix 'on', their selectors will be bound
     *
     *  @example view controller method the function will bind event delegates with
     *    onclick : {
     *      '.selector' : function(e) {
     *
     *      }
     *    }
     */
    function addEventListeners(view) {
        var eventHolder;
        var eventType;
        var method;
        var selector;
        var listenerElement = view.element;
        var handlerFn;

        // Loop through all methods looking for event delegates
        for (method in view) {
            if (view.hasOwnProperty(method) && method.match(eventMethodPrefix) && typeof view[method] === "object") {
                eventHolder = view[method];
                // e.g. click
                eventType = method.match(eventMethodPrefix)[1];

                for (selector in eventHolder) {
                    if (eventHolder.hasOwnProperty(selector)) {
                        handlerFn = eventHolder[selector];
                        // If the selector is the same as the listenerElement
                        // Or using special 'element' property
                        if (listenerElement.is(selector) || handlerFn === eventHolder.element) {
                            // Attach event to current element
                            listenerElement.bind(eventType, bindScope(handlerFn, view));
                        } else {
                            // Bind event delegate to the element. Setting the context to the view
                            listenerElement.delegate(selector, eventType, bindScope(handlerFn, view));
                        }
                    }
                }
            }
        }
    }

    /**
     *  Connect the view controller and element together
     *
     *  @param {Object} element         Element to attach view unto.
     *  @param {Object} View            View to capture.
     *  @param {Any}    [optionalArgs]  One or more extra arguments that are passed to the view.init.
     *
     *  @returns {object} New instance of an initalised view controller
     */
    function connectView(element, view, optionalArgs) {
        view.element = element;

        if (view.init && view.hasOwnProperty('init')) {
            if (optionalArgs) {
                view.init.apply(view, optionalArgs);
            } else {
                view.init.call(view);
            }
        }

        addEventListeners(view);

        return view;
    }

    /**
     * View Controller base constructor.
     * When an object is wrapped with Capture.view, it inherits methods directly
     * from this constructor
     * @constructor
     */
    function ViewBaseClass() {}

    ViewBaseClass.prototype = {
        // Remove all event handlers
        removeEventListeners : function () {
            this.element.unbind();
            this.element.undelegate();
        },
        // Reattach all event listners
        reattachEventListeners : function () {
            this.removeEventListeners();
            addEventListeners(this);
        }
    };

    /**
     *  Capture attaches a view to an element via event delegates.
     *
     *  @param {String/Object}   element Element to attach view unto.
     *  @param {Object/Function} View    To be instantiated as a capture view.
     *  @param {AnyType}         [1..*]  One or more extra arguments that are passed to the view.init.
     *
     *  @returns {object}    Instantiated view
     *
     *  @example
     *   Capture('#gallery', view)
     */
    window.Capture = function (element, view) {
        // If wrapped by Capture.view, it will be a function.
        view = (typeof view === "function") ? view() : view;

        element = $(element);

        validate(element, view);

        return connectView(element.eq(0), view, (arguments.length > 2) ? slice.call(arguments, 2) : UNDEFINED);
    };

    /**
     *  This wraps the view until called by capture.
     *  It instantiates the view controller and sets inheritance to view base class.
     *
     *  @param {Object/Function} View    To be instantiated as a capture view
     *
     *  @returns {function} The view to be initalised by capture
     */
    Capture.view = function (View) {
        return function () {
            // If a constructor has been passed, instantiate it now
            var view = (typeof View === "function") ? new View() : View;

            // Deep copy view into instance of ViewBaseClass
            return $.extend(true, new ViewBaseClass(), view);
        };
    };

    /**
     *  jQuery method to capture a view on the existing element.
     *  Doesn't return an error if element doesn't exist, as per jQuery philosophy.
     *
     *  @param  {object}  view  The View to be initialised from on the element
     *  @param {AnyType}         [1..*]  One or more extra arguments that are passed to the view.init.
     *
     *  @returns {object}    Instantiated view
     *
     *  @example
     *  $('#element').capture(view)
     */
    $.fn.capture = function (view) {
        if (this.length === 0 || !this.each) {
            return;
        }
        return window.Capture.apply(null, [this].concat(slice.call(arguments, 0)));
    };

})(jQuery);
<commit_msg>Better error messages<commit_after>/*jslint evil: false, bitwise:false, strict: true, undef: true, white:true, onevar:false, browser:true, plusplus:false */
/*global jQuery, Capture:true, window */
/**
 *  Capture.js
 *  v1.0.0
 *  Copyright 2011 Adam Craven
 *  Freely distributable under the MIT License.
 *  https://github.com/AdmCrvn/Capture
 */
(function ($) {
    "use strict";

    if (typeof Capture !== "undefined") {
        throw new Error('Capture is already defined');
    }

    var bind = Function.prototype.bind;
    var slice = Array.prototype.slice;
    var toString = Object.prototype.toString;
    var UNDEFINED;

    // All properties with prefix of 'on' are treated as event delegates
    var eventMethodPrefix = /^on(.+)/;

    /**
     *  Native ECMAScript 5 bind if supported or passes to jQuery proxy.
     *  @param  {function}  fn    Function to bind.
     *  @param  {object}  scope Scope in which to bind the function.
     */
    function bindScope(fn, scope) {
        if (bind && fn.bind === bind) {
            return bind.apply(fn, slice.call(arguments, 1));
        }
        return $.proxy(fn, scope);
    }

    /**
     *  Validates the view when captured, checking for basic errors
     */
    function validate(element, view) {
        if (!view) {
            throw new Error("Capture.js; View undefined.\n You must attach a view object or constructor. e.g. Capture('element', view)");
        }

        if (toString.call(view) !== '[object Object]') {
            throw new Error('Capture.js; View wrong type.\n The view must be an object or a constructor.');
        }

        if (element.length === 0 || !element.each) {
            throw new Error('Capture.js; No element found.\n You must attach the view to an element.');
        }
    }

    /**
     *  Adds listeners to the view.
     *  By default all methods that have the valid prefix 'on', their selectors will be bound
     *
     *  @example view controller method the function will bind event delegates with
     *    onclick : {
     *      '.selector' : function(e) {
     *
     *      }
     *    }
     */
    function addEventListeners(view) {
        var eventHolder;
        var eventType;
        var method;
        var selector;
        var listenerElement = view.element;
        var handlerFn;

        // Loop through all methods looking for event delegates
        for (method in view) {
            if (view.hasOwnProperty(method) && method.match(eventMethodPrefix) && typeof view[method] === "object") {
                eventHolder = view[method];
                // e.g. click
                eventType = method.match(eventMethodPrefix)[1];

                for (selector in eventHolder) {
                    if (eventHolder.hasOwnProperty(selector)) {
                        handlerFn = eventHolder[selector];
                        // If the selector is the same as the listenerElement
                        // Or using special 'element' property
                        if (listenerElement.is(selector) || handlerFn === eventHolder.element) {
                            // Attach event to current element
                            listenerElement.bind(eventType, bindScope(handlerFn, view));
                        } else {
                            // Bind event delegate to the element. Setting the context to the view
                            listenerElement.delegate(selector, eventType, bindScope(handlerFn, view));
                        }
                    }
                }
            }
        }
    }

    /**
     *  Connect the view controller and element together
     *
     *  @param {Object} element         Element to attach view unto.
     *  @param {Object} View            View to capture.
     *  @param {Any}    [optionalArgs]  One or more extra arguments that are passed to the view.init.
     *
     *  @returns {object} New instance of an initalised view controller
     */
    function connectView(element, view, optionalArgs) {
        view.element = element;

        if (view.init && view.hasOwnProperty('init')) {
            if (optionalArgs) {
                view.init.apply(view, optionalArgs);
            } else {
                view.init.call(view);
            }
        }

        addEventListeners(view);

        return view;
    }

    /**
     * View Controller base constructor.
     * When an object is wrapped with Capture.view, it inherits methods directly
     * from this constructor
     * @constructor
     */
    function ViewBaseClass() {}

    ViewBaseClass.prototype = {
        // Remove all event handlers
        removeEventListeners : function () {
            this.element.unbind();
            this.element.undelegate();
        },
        // Reattach all event listners
        reattachEventListeners : function () {
            this.removeEventListeners();
            addEventListeners(this);
        }
    };

    /**
     *  Capture attaches a view to an element via event delegates.
     *
     *  @param {String/Object}   element Element to attach view unto.
     *  @param {Object/Function} View    To be instantiated as a capture view.
     *  @param {AnyType}         [1..*]  One or more extra arguments that are passed to the view.init.
     *
     *  @returns {object}    Instantiated view
     *
     *  @example
     *   Capture('#gallery', view)
     */
    window.Capture = function (element, view) {
        // If wrapped by Capture.view, it will be a function.
        view = (typeof view === "function") ? view() : view;

        element = $(element);

        validate(element, view);

        return connectView(element.eq(0), view, (arguments.length > 2) ? slice.call(arguments, 2) : UNDEFINED);
    };

    /**
     *  This wraps the view until called by capture.
     *  It instantiates the view controller and sets inheritance to view base class.
     *
     *  @param {Object/Function} View    To be instantiated as a capture view
     *
     *  @returns {function} The view to be initalised by capture
     */
    Capture.view = function (View) {
        return function () {
            // If a constructor has been passed, instantiate it now
            var view = (typeof View === "function") ? new View() : View;

            // Deep copy view into instance of ViewBaseClass
            return $.extend(true, new ViewBaseClass(), view);
        };
    };

    /**
     *  jQuery method to capture a view on the existing element.
     *  Doesn't return an error if element doesn't exist, as per jQuery philosophy.
     *
     *  @param  {object}  view  The View to be initialised from on the element
     *  @param {AnyType}         [1..*]  One or more extra arguments that are passed to the view.init.
     *
     *  @returns {object}    Instantiated view
     *
     *  @example
     *  $('#element').capture(view)
     */
    $.fn.capture = function (view) {
        if (this.length === 0 || !this.each) {
            return;
        }
        return window.Capture.apply(null, [this].concat(slice.call(arguments, 0)));
    };

})(jQuery);
<|endoftext|>


<commit_before>import React from 'react'
import Header from './Header'
const { shape, string } = React.PropTypes

const Details = React.createClass({
  propTypes: {
    show: shape({
      title: string,
      description: string,
      year: string,
      poster: string,
      trailer: string
    })
  },
  render () {
    const { title, description, year, poster, trailer } = this.props.show
    return (

{title}

({year})

          <img src={`/public/img/posters/${poster}`} />

{description}

          <iframe src={`https://www.youtube-nocookie.com/embed/${trailer}?rel=0&controls=0&showinfo=0`}
            frameBorder='0' allowFullScreen />

          {JSON.stringify(this.props, null, 4)}

      )
  }
})

export default Details
<commit_msg>updated details to use componentdidmonet with axios<commit_after>import React from 'react'
import axios from 'axios'
import Header from './Header'
const { shape, string } = React.PropTypes

const Details = React.createClass({
  propTypes: {
    show: shape({
      title: string,
      description: string,
      year: string,
      poster: string,
      trailer: string,
      imdbID: string
    })
  },
  getInitialState () {
    return {
      omdbData: {}
    }
  },
  componentDidMount () {
    axios.get(`http://www.omdbapi.com/?i=${this.props.show.imdbID}`).then((response) => {
      this.setState({omdbData: response.data})
    })
    .catch((error) => console.error('axios error', error))
  },
  render () {
    const { title, description, year, poster, trailer } = this.props.show
    return (

{title}

({year})

          <img src={`/public/img/posters/${poster}`} />

{description}

          <iframe src={`https://www.youtube-nocookie.com/embed/${trailer}?rel=0&controls=0&showinfo=0`}
            frameBorder='0' allowFullScreen />

          {JSON.stringify(this.props, null, 4)}

      )
  }
})

export default Details
<|endoftext|>


<commit_before>// Init navit
//
'use strict';

/*global window, TEST*/
const _     = require('lodash');
const co    = require('bluebird-co').co;
const navit = require('navit');
const url   = require('url');

module.exports = function (N) {

  function navitPlugins(navit) {

    // Authenticate user by login. You should reload page after use this or use before `.open`
    //
    // - login (String) - if empty - do logout, if exists - login, if not exists - create and login
    // - callback(user) (Function) - optional
    //
    navit.registerMethod('do.auth', function do_auth(login, fn) {
      let userLogin = _.isFunction(login) ? login() : login;
      let domain = url.parse(TEST.N.config.bind.default.mount).hostname;

      // If `login` not specified - do logout
      if (!login) {
        this.cookie({
          name: 'sid',
          value: '',
          domain,
          expires: Date.now() - 1000
        });

        return this;
      }

      let cookieObj = {
        name: 'sid',
        value: '', // changed by a function below
        domain,
        httponly: true,
        secure: false,
        expires: (new Date()).getTime() + (1000 * 60 * 60 * 24 * 365) // expires in 1 year
      };

      let user;

      this.fn(callback => co(function* auth() {
        let user = yield TEST.N.models.users.User
                                 .findOne({ nick: login })
                                 .lean(false); // some tests use user.save()

        // Create user entry if it doesn't exist
        //
        if (!user) {
          user = new TEST.N.models.users.User({ nick: login });

          yield user.save();
        }

        // Create user token
        //
        let token = yield TEST.N.models.users.TokenLogin
                                  .findOne({ user: user._id })
                                  .lean(true);

        if (!token) {
          token = new TEST.N.models.users.TokenLogin({ user: user._id });

          yield token.save();
        }

        cookieObj.value = token.session_id;

        // Invoke callback for `do.auth(login, callback)`
        //
        if (fn) fn(user);

      }).asCallback(callback));

      // Set cookie
      //
      this.cookie(function () {
        return cookieObj;
      });

      return this;
    });

    // Wait for nodeca scripts load and check status
    //
    navit.batch.create('waitNodecaBooted', function () {
      this
        .wait(function () {
          try {
            return window.NodecaLoader.booted;
          } catch (__) {}
          return false;
        })
        .test.status(200);
    });

    navit.afterOpen = function () {
      this.batch('waitNodecaBooted');
    };
  }

  N.wire.on('init:tests', function init_navit() {
    global.TEST.browser = navit({ engine: 'electron' }).use(navitPlugins);

    N.wire.before([ 'exit.shutdown', 'exit.terminate' ], function navit_shutdown(__, callback) {
      TEST.browser.exit(() => callback());
    });
  });
};
<commit_msg>lint fixes<commit_after>// Init navit
//
'use strict';

/*global window, TEST*/
const _     = require('lodash');
const co    = require('bluebird-co').co;
const navit = require('navit');
const url   = require('url');

module.exports = function (N) {

  function navitPlugins(navit) {

    // Authenticate user by login. You should reload page after use this or use before `.open`
    //
    // - login (String) - if empty - do logout, if exists - login, if not exists - create and login
    // - callback(user) (Function) - optional
    //
    navit.registerMethod('do.auth', function do_auth(login, fn) {
      let userLogin = _.isFunction(login) ? login() : login;
      let domain = url.parse(TEST.N.config.bind.default.mount).hostname;

      // If `login` not specified - do logout
      if (!userLogin) {
        this.cookie({
          name: 'sid',
          value: '',
          domain,
          expires: Date.now() - 1000
        });

        return this;
      }

      let cookieObj = {
        name: 'sid',
        value: '', // changed by a function below
        domain,
        httponly: true,
        secure: false,
        expires: (new Date()).getTime() + (1000 * 60 * 60 * 24 * 365) // expires in 1 year
      };

      this.fn(callback => co(function* auth() {
        let user = yield TEST.N.models.users.User
                                 .findOne({ nick: userLogin })
                                 .lean(false); // some tests use user.save()

        // Create user entry if it doesn't exist
        //
        if (!user) {
          user = new TEST.N.models.users.User({ nick: userLogin });

          yield user.save();
        }

        // Create user token
        //
        let token = yield TEST.N.models.users.TokenLogin
                                  .findOne({ user: user._id })
                                  .lean(true);

        if (!token) {
          token = new TEST.N.models.users.TokenLogin({ user: user._id });

          yield token.save();
        }

        cookieObj.value = token.session_id;

        // Invoke callback for `do.auth(login, callback)`
        //
        if (fn) fn(user);

      }).asCallback(callback));

      // Set cookie
      //
      this.cookie(function () {
        return cookieObj;
      });

      return this;
    });

    // Wait for nodeca scripts load and check status
    //
    navit.batch.create('waitNodecaBooted', function () {
      this
        .wait(function () {
          try {
            return window.NodecaLoader.booted;
          } catch (__) {}
          return false;
        })
        .test.status(200);
    });

    navit.afterOpen = function () {
      this.batch('waitNodecaBooted');
    };
  }

  N.wire.on('init:tests', function init_navit() {
    global.TEST.browser = navit({ engine: 'electron' }).use(navitPlugins);

    N.wire.before([ 'exit.shutdown', 'exit.terminate' ], function navit_shutdown(__, callback) {
      TEST.browser.exit(() => callback());
    });
  });
};
<|endoftext|>