<commit_before>/*global require*/
'use strict';

require.config({
    shim: {
        underscore: {
            exports: '_'
        },
        backbone: {
            deps: [
                'underscore',
                'jquery'
            ],
            exports: 'Backbone'
        },
        'jquery-ui': {
            exports: '$',
            deps: ['jquery', 'bootstrap-dropdown']
        },
    },
    paths: {
        jquery: '../components/jquery/jquery',
        'jquery-ui': 'vendor/jquery-ui/js/jquery-ui-1.10.2.custom',
        backbone: '../components/backbone-amd/backbone',
        underscore: '../components/underscore-amd/underscore',
        'bootstrap-dropdown': '../components/bootstrap/js/bootstrap-dropdown',
        templates: 'templates/compiled',
    }
});

/* Define our globals */
function log(text) {
    // performance.now is available in Chrome stable, Firefox 15+, and IE10.
    console.log(window.performance.now() + ': ' + text);
}
log('Logging initialized.'); // To suppress "never used" linter warning.
// Application namespace.
// Initialization happens lazily later.
window.App = {
    Models: {
        App: null,
        Gallery: null,
    },
    Views: {
        App: null,
        Gallery: null,
    },
    Collections: {
    },
};

require([
    'backbone',
    'routes/application-router',
], function (Backbone, Router) {
    window.App.Router = new Router();
    Backbone.history.start();
});

<commit_msg>Fix opera / window.performance<commit_after>/*global require*/
'use strict';

require.config({
    shim: {
        underscore: {
            exports: '_'
        },
        backbone: {
            deps: [
                'underscore',
                'jquery'
            ],
            exports: 'Backbone'
        },
        'jquery-ui': {
            exports: '$',
            deps: ['jquery', 'bootstrap-dropdown']
        },
    },
    paths: {
        jquery: '../components/jquery/jquery',
        'jquery-ui': 'vendor/jquery-ui/js/jquery-ui-1.10.2.custom',
        backbone: '../components/backbone-amd/backbone',
        underscore: '../components/underscore-amd/underscore',
        'bootstrap-dropdown': '../components/bootstrap/js/bootstrap-dropdown',
        templates: 'templates/compiled',
    }
});

/* Define our globals */
// performance.now is available in Chrome stable, Firefox 15+, and IE10.
if (!window.performance) {
    // Opera, for example
    window.performance = {
        now: function () {return '';}
    };
}
function log(text) {
    console.log(window.performance.now() + ': ' + text);
}
log('Logging initialized.'); // To suppress "never used" linter warning.
// Application namespace.
// Initialization happens lazily later.
window.App = {
    Models: {
        App: null,
        Gallery: null,
    },
    Views: {
        App: null,
        Gallery: null,
    },
    Collections: {
    },
};

require([
    'backbone',
    'routes/application-router',
], function (Backbone, Router) {
    window.App.Router = new Router();
    Backbone.history.start();
});

<|endoftext|>


<commit_before>describe("About Arrays", function() {

  //We shall contemplate truth by testing reality, via spec expectations.
  it("should create arrays", function() {
    var emptyArray = [];
    expect(typeof(emptyArray)).toBe(FILL_ME_IN); //A mistake? - http:javascript.crockford.com/remedial.html
    expect(emptyArray.length).toBe(FILL_ME_IN);

    var multiTypeArray = [0, 1, "two", function () { return 3; }, {value1: 4, value2: 5}, [6, 7]];
    expect(multiTypeArray[0]).toBe(FILL_ME_IN);
    expect(multiTypeArray[2]).toBe(FILL_ME_IN);
    expect(multiTypeArray[3]()).toBe(FILL_ME_IN);
    expect(multiTypeArray[4].value1).toBe(FILL_ME_IN);
    expect(multiTypeArray[4]["value2"]).toBe(FILL_ME_IN);
    expect(multiTypeArray[5][0]).toBe(FILL_ME_IN);
  });

  it("should understand array literals", function () {
    var array = [];
    expect(array).toEqual([]);

    array[0] = 1;
    expect(array).toEqual([1]);

    array[1] = 2;
    expect(array).toEqual([1, FILL_ME_IN]);

    array.push(3);
    expect(array).toEqual(FILL_ME_IN);
  });

  it("should understand array length", function () {
    var fourNumberArray = [1, 2, 3, 4];

    expect(fourNumberArray.length).toBe(FILL_ME_IN);
    fourNumberArray.push(5, 6);
    expect(fourNumberArray.length).toBe(FILL_ME_IN);

    var tenEmptyElementArray = new Array(10);
    expect(tenEmptyElementArray.length).toBe(FILL_ME_IN);

    tenEmptyElementArray.length = 5;
    expect(tenEmptyElementArray.length).toBe(FILL_ME_IN);
  });

  it("should slice arrays", function () {
    var array = ["peanut", "butter", "and", "jelly"];

    expect(array.slice(0, 1)).toEqual(FILL_ME_IN);
    expect(array.slice(0, 2)).toEqual(FILL_ME_IN);
    expect(array.slice(2, 2)).toEqual(FILL_ME_IN);
    expect(array.slice(2, 20)).toEqual(FILL_ME_IN);
    expect(array.slice(3, 0)).toEqual(FILL_ME_IN);
    expect(array.slice(3, 100)).toEqual(FILL_ME_IN);
    expect(array.slice(5, 1)).toEqual(FILL_ME_IN);
  });

  it("should know array references", function () {
    var array = [ "zero", "one", "two", "three", "four", "five" ];

    function passedByReference(refArray) {
      refArray[1] = "changed in function";
    }
    passedByReference(array);
    expect(array[1]).toBe(FILL_ME_IN);

    var assignedArray = array;
    assignedArray[5] = "changed in assignedArray";
    expect(array[5]).toBe(FILL_ME_IN);

    var copyOfArray = array.slice();
    copyOfArray[3] = "changed in copyOfArray";
    expect(array[3]).toBe(FILL_ME_IN);
  });

  it("should push and pop", function () {
    var array = [1, 2];
    array.push(3);

    expect(array).toEqual(FILL_ME_IN);

    var poppedValue = array.pop();
    expect(poppedValue).toBe(FILL_ME_IN);
    expect(array).toEqual(FILL_ME_IN);
  });

  it("should know about shifting arrays", function () {
    var array = [1, 2];

    array.unshift(3);
    expect(array).toEqual(FILL_ME_IN);

    var shiftedValue = array.shift();
    expect(shiftedValue).toEqual(FILL_ME_IN);
    expect(array).toEqual(FILL_ME_IN);
  });
});
<commit_msg>About Arrays: create arrays passes all tests<commit_after>describe("About Arrays", function() {

  //We shall contemplate truth by testing reality, via spec expectations.
  it("should create arrays", function() {
    var emptyArray = [];
    expect(typeof(emptyArray)).toBe('object'); //A mistake? - http:javascript.crockford.com/remedial.html
    expect(emptyArray.length).toBe(0);

    var multiTypeArray = [0, 1, "two", function () { return 3; }, {value1: 4, value2: 5}, [6, 7]];
    expect(multiTypeArray[0]).toBe(0);
    expect(multiTypeArray[2]).toBe("two");
    expect(multiTypeArray[3]()).toBe(3);
    expect(multiTypeArray[4].value1).toBe(4);
    expect(multiTypeArray[4]["value2"]).toBe(5);
    expect(multiTypeArray[5][0]).toBe(6);
  });

  it("should understand array literals", function () {
    var array = [];
    expect(array).toEqual([]);

    array[0] = 1;
    expect(array).toEqual([1]);

    array[1] = 2;
    expect(array).toEqual([1, FILL_ME_IN]);

    array.push(3);
    expect(array).toEqual(FILL_ME_IN);
  });

  it("should understand array length", function () {
    var fourNumberArray = [1, 2, 3, 4];

    expect(fourNumberArray.length).toBe(FILL_ME_IN);
    fourNumberArray.push(5, 6);
    expect(fourNumberArray.length).toBe(FILL_ME_IN);

    var tenEmptyElementArray = new Array(10);
    expect(tenEmptyElementArray.length).toBe(FILL_ME_IN);

    tenEmptyElementArray.length = 5;
    expect(tenEmptyElementArray.length).toBe(FILL_ME_IN);
  });

  it("should slice arrays", function () {
    var array = ["peanut", "butter", "and", "jelly"];

    expect(array.slice(0, 1)).toEqual(FILL_ME_IN);
    expect(array.slice(0, 2)).toEqual(FILL_ME_IN);
    expect(array.slice(2, 2)).toEqual(FILL_ME_IN);
    expect(array.slice(2, 20)).toEqual(FILL_ME_IN);
    expect(array.slice(3, 0)).toEqual(FILL_ME_IN);
    expect(array.slice(3, 100)).toEqual(FILL_ME_IN);
    expect(array.slice(5, 1)).toEqual(FILL_ME_IN);
  });

  it("should know array references", function () {
    var array = [ "zero", "one", "two", "three", "four", "five" ];

    function passedByReference(refArray) {
      refArray[1] = "changed in function";
    }
    passedByReference(array);
    expect(array[1]).toBe(FILL_ME_IN);

    var assignedArray = array;
    assignedArray[5] = "changed in assignedArray";
    expect(array[5]).toBe(FILL_ME_IN);

    var copyOfArray = array.slice();
    copyOfArray[3] = "changed in copyOfArray";
    expect(array[3]).toBe(FILL_ME_IN);
  });

  it("should push and pop", function () {
    var array = [1, 2];
    array.push(3);

    expect(array).toEqual(FILL_ME_IN);

    var poppedValue = array.pop();
    expect(poppedValue).toBe(FILL_ME_IN);
    expect(array).toEqual(FILL_ME_IN);
  });

  it("should know about shifting arrays", function () {
    var array = [1, 2];

    array.unshift(3);
    expect(array).toEqual(FILL_ME_IN);

    var shiftedValue = array.shift();
    expect(shiftedValue).toEqual(FILL_ME_IN);
    expect(array).toEqual(FILL_ME_IN);
  });
});
<|endoftext|>


<commit_before>var xmpp = require('../lib/node-xmpp');

/* This is a very basic C2S server example. One of the key design decisions of node-xmpp is to keep it very lightweight */
/* If you need a full blown server check out https://github.com/superfeedr/xmpp-server */

// Sets up the server.
var c2s = new xmpp.C2SServer({
    port: 5222,
    domain: 'localhost'//,
    // tls: {
    //     keyPath: './examples/localhost-key.pem',
    //     certPath: './examples/localhost-cert.pem'
    // }

});

// On Connect event. When a client connects.
c2s.on("connect", function(client) {
    // That's the way you add mods to a given server.

    // Allows the developer to register the jid against anything they want
    c2s.on("register", function(opts, cb) {
        console.log("REGISTER");
    cb(true);
    });

    // Allows the developer to authenticate users against anything they want.
    client.on("authenticate", function(opts, cb) {
        console.log("AUTH" + opts.jid + " -> " +opts.password);
    cb(null); // cb(false);
    });

    client.on("online", function() {
        console.log("ONLINE");
        client.send(new xmpp.Message({ type: 'chat' }).c('body').t("Hello there, little client."));
    });

    // Stanza handling
    client.on("stanza", function(stanza) {
        console.log("STANZA" + stanza);
    });

    // On Disconnect event. When a client disconnects
    client.on("disconnect", function(client) {
        console.log("DISCONNECT");
    });

});
<commit_msg>Clean up c2s example<commit_after>'use strict';

var xmpp = require('../lib/node-xmpp')

/* This is a very basic C2S server example. One of the key design decisions
* of node-xmpp is to keep it very lightweight
* If you need a full blown server check out https://github.com/superfeedr/xmpp-server
*/

// Sets up the server.
var c2s = new xmpp.C2SServer({
    port: 5222,
    domain: 'localhost'
    // tls: {
    //     keyPath: './examples/localhost-key.pem',
    //     certPath: './examples/localhost-cert.pem'
    // }

})

// On Connect event. When a client connects.
c2s.on('connect', function(client) {
    // That's the way you add mods to a given server.

    // Allows the developer to register the jid against anything they want
    c2s.on('register', function(opts, cb) {
        console.log('REGISTER')
        cb(true)
    })

    // Allows the developer to authenticate users against anything they want.
    client.on('authenticate', function(opts, cb) {
        console.log('AUTH' + opts.jid + ' -> ' +opts.password)
        cb(null) // cb(false)
    })

    client.on('online', function() {
        console.log('ONLINE')
        client.send(new xmpp.Message({ type: 'chat' }).c('body').t('Hello there, little client.'))
    })

    // Stanza handling
    client.on('stanza', function(stanza) {
        console.log('STANZA' + stanza)
    })

    // On Disconnect event. When a client disconnects
    client.on('disconnect', function() {
        console.log('DISCONNECT')
    })

})
<|endoftext|>


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

const fs = require('fs')
const _ = require('lodash')
const exec = require('child_process').exec

const driver = `
'use strict'

const webDriver = require('selenium-webdriver')
const chrome = require('selenium-webdriver/chrome')
const service = new chrome.ServiceBuilder(require('chromedriver').path).build()
chrome.setDefaultService(service)

const driver = new webDriver.Builder()
  .withCapabilities(webDriver.Capabilities.chrome())
  .build()

module.exports = driver
`

const env = `
'use strict'

require('chai')
  .use(require('chai-as-promised'))
  .should()

var configure = function () {
  this.setDefaultTimeout(60 * 1000)
}

module.exports = configure
`

const hook = `
'use strict'

module.exports = function () {
  const driver = require('./driver')
  this.World = require('./world').World // overwrite default World constructor
  this.setDefaultTimeout(3600000)

  this.AfterFeatures(function () {
    return driver.quit()
  })
}
`

const world = `'use strict'

const driver = require('./driver')
const tamarin = require('tamarin')

module.exports = {
  World: class extends tamarin {
    constructor () {
      super(driver)
    }
  }
}
`

const feature = `
Feature: Do a Google Search
  Using a web browser
  I want to perform a Google search

  Scenario: Google Search for tamarin images
    Given I visit http://google.com
    Then I expect the title to be "Google"
    When I search for "Tamarin"
    When I click the "Images" menu link
    Then I expect to see some "Image" results
`

const steps = `
'use strict'

const page = {
  'search': { css: '[title="Search"]' },
  'navLink': (linkText) => ({ xpath: \`//*[@role="navigation"]//a[text()="\${linkText}"]\` }),
  'results': (type, searchTerm) => ({ css: \`img[alt="\${type} result for \${searchTerm}"]\` })
}

module.exports = function () {
  this.Given(/^I visit (https?:\\/\\/.*\\..*)$/, function visitStep (url) {
    return this.visit(url)
  })

  this.Then(/^I expect the title to be "([^"]*)"$/, function waitForTitleStep (title) {
    return this.waitForTitle(title)
  })

  this.Then(/^I expect the "([^"]*)" cookie to exist$/, function waitForTitleStep (name) {
    return this.waitForCookie(name)
  })

  this.Then(/^I expect the "([^"]*)" cookie to be "([^"]*)"$/, function waitForTitleStep (name, expectedValue) {
    return this.waitForCookie(name).should.eventually.have.property('value', expectedValue)
  })

  this.Then(/^I expect the url to contain "([^"]*)"$/, function (partial) {
    return this.waitForUrl().should.eventually.contain(partial)
  })

  this.When(/^I search for "([^"]*)"$/, function enterSearchTermStep (searchTerm) {
    return this.setData('searchTerm', searchTerm)
      .then(() => this.sendKeys(page.search, searchTerm + '\\n'))
  })

  this.When(/^I click the "([^"]*)" menu link$/, function clickMenuLinkStep (linkText) {
    return this.click(page.navLink(linkText))
  })

  this.Then(/^I expect to see some "([^"]*)" results$/, function waitForResultsStep (type) {
    return this.getData('searchTerm')
      .then((searchTerm) => this.waitFor(page.results(type, searchTerm)))
  })
}
`

const structure = {
  features: {
    support: {
      'driver.js': driver,
      'env.js': env,
      'hook.js': hook,
      'world.js': world
    },
    step_definitions: {
      'steps.js': steps
    },
    'main.feature': feature
  }
}

function generate (dir, node) {
  const keys = Object.keys(node)
  keys.forEach((id) => {
    console.log(`Processing: ${id}`)
    if (_.isString(node[id])) {
      const filename = `${dir}/${id}`
      console.log(`saving ${filename}`)
      fs.writeFileSync(filename, node[id])
    } else {
      const subDir = `${dir}/${id}`
      if (!fs.existsSync(subDir)) {
        fs.mkdirSync(subDir)
      }
      generate(subDir, node[id])
    }
  })
}

generate(process.cwd(), structure)

const modules = [
  'tamarin',
  'cucumber',
  'chai',
  'chai-as-promised',
  'chromedriver'
]

const command = `npm install ${modules.join(' ')} -D`
console.log(command)
exec(command).stderr.pipe(process.stderr)

<commit_msg>Generating a tamarin test<commit_after>#!/usr/bin/env node

const fs = require('fs')
const _ = require('lodash')
const exec = require('child_process').exec

const driver = `
'use strict'

const webDriver = require('selenium-webdriver')
const chrome = require('selenium-webdriver/chrome')
const service = new chrome.ServiceBuilder(require('chromedriver').path).build()
chrome.setDefaultService(service)

const driver = new webDriver.Builder()
  .withCapabilities(webDriver.Capabilities.chrome())
  .build()

module.exports = driver
`

const env = `
'use strict'

require('chai')
  .use(require('chai-as-promised'))
  .should()

var configure = function () {
  this.setDefaultTimeout(60 * 1000)
}

module.exports = configure
`

const hook = `
'use strict'

module.exports = function () {
  const driver = require('./driver')
  this.World = require('./world').World // overwrite default World constructor
  this.setDefaultTimeout(3600000)

  this.AfterFeatures(function () {
    return driver.quit()
  })
}
`

const world = `'use strict'

const driver = require('./driver')
const tamarin = require('tamarin')

module.exports = {
  World: class extends tamarin {
    constructor () {
      super(driver)
    }
  }
}
`

const feature = `
Feature: Do a Google Search
  Using a web browser
  I want to perform a Google search

  Scenario: Google Search for tamarin images
    Given I visit http://google.com
    Then I expect the title to be "Google"
    When I search for "Tamarin"
    When I click the "Images" menu link
    Then I expect to see some "Image" results
`

const steps = `
'use strict'

const page = {
  'search': { css: '[title="Search"]' },
  'navLink': (linkText) => ({ xpath: \`//*[@role="navigation"]//a[text()="\${linkText}"]\` }),
  'results': (type, searchTerm) => ({ css: \`img[alt="\${type} result for \${searchTerm}"]\` })
}

module.exports = function () {
  this.Given(/^I visit (https?:\\/\\/.*\\..*)$/, function visitStep (url) {
    return this.visit(url)
  })

  this.Then(/^I expect the title to be "([^"]*)"$/, function waitForTitleStep (title) {
    return this.waitForTitle(title)
  })

  this.Then(/^I expect the "([^"]*)" cookie to exist$/, function waitForTitleStep (name) {
    return this.waitForCookie(name)
  })

  this.Then(/^I expect the "([^"]*)" cookie to be "([^"]*)"$/, function waitForTitleStep (name, expectedValue) {
    return this.waitForCookie(name).should.eventually.have.property('value', expectedValue)
  })

  this.Then(/^I expect the url to contain "([^"]*)"$/, function (partial) {
    return this.waitForUrl().should.eventually.contain(partial)
  })

  this.When(/^I search for "([^"]*)"$/, function enterSearchTermStep (searchTerm) {
    return this.setData('searchTerm', searchTerm)
      .then(() => this.sendKeys(page.search, searchTerm + '\\n'))
  })

  this.When(/^I click the "([^"]*)" menu link$/, function clickMenuLinkStep (linkText) {
    return this.click(page.navLink(linkText))
  })

  this.Then(/^I expect to see some "([^"]*)" results$/, function waitForResultsStep (type) {
    return this.getData('searchTerm')
      .then((searchTerm) => this.waitFor(page.results(type, searchTerm)))
  })
}
`

const structure = {
  features: {
    support: {
      'driver.js': driver,
      'env.js': env,
      'hook.js': hook,
      'world.js': world
    },
    step_definitions: {
      'steps.js': steps
    },
    'main.feature': feature
  }
}

function generate (dir, node) {
  const keys = Object.keys(node)
  keys.forEach((id) => {
    console.log(`Processing: ${id}`)
    if (_.isString(node[id])) {
      const filename = `${dir}/${id}`
      console.log(`saving ${filename}`)
      fs.writeFileSync(filename, node[id])
    } else {
      const subDir = `${dir}/${id}`
      if (!fs.existsSync(subDir)) {
        fs.mkdirSync(subDir)
      }
      generate(subDir, node[id])
    }
  })
}

generate(process.cwd(), structure)

const modules = [
  'tamarin',
  'cucumber',
  'chai',
  'chai-as-promised',
  'chromedriver'
]

const command = `npm install ${modules.join(' ')} -D`
console.log(command)
exec(command).stderr.pipe(console.log)

<|endoftext|>


<commit_before>var logger = require('npmlog');
var semver = require('semver');
var mkdirp = require('mkdirp');
var difftool = require('diff');

var fs = require('fs');
var path = require('path');

var file = require('../utils/file');
var md5sum = require('../utils/md5sum');
var request = require('../utils/request');

var dataDir = path.resolve(__dirname, '../../data');

var cwd = process.cwd();
var baseDir = (process.env.HOME || '/tmp/');
var cacheDir = path.resolve(baseDir, '.mauer/cache');
var modulesDir = path.resolve(cwd, '.mauer');

mkdirp.sync(cacheDir);
mkdirp.sync(modulesDir);

function installPackage (package) {

  var tokens = package.split('@');

  // allow only valid package names
  if (tokens.length > 2) {
    logger.error('', 'Invalid package "%s"', package);
    return;
  }

  var name = tokens[0];
  var packageDir = path.join(dataDir, name);
  if (!file.exists(packageDir)) {
    logger.error('', 'Unrecognised package "%s"', package);
    return;
  }

  var version = latestVersion(name, tokens[1]);
  if (version) {
    logger.info('installing', name, version);
    getPackage(name, version, function (err, cache) {
      if (err) {
        throw err;
      }
      setupPackage(name, version, cache);
      logger.info('done', name);
    });
  }
}

function latestVersion (package, version) {

  var packageDir = path.join(dataDir, package);
  var metaFile = path.join(packageDir, 'meta.json');
  var meta = require(metaFile);

  if (version && version !== 'latest') {
    var parsed = semver.parse(version);
    if (parsed) {
      version = parsed.splice(1,3).join('.');
    } else {
      logger.error('', 'Unsupported "%s@%s"', package, version);
      return;
    }
  }

  // If no version is passed, fallback to the latest version
  if (!version || version === 'latest') {
    version = meta.versions.sort(semver.rcompare)[0];
  } else if (meta.versions.indexOf(version) < 0) {
    logger.error('', 'Unsupported "%s@%s"', package, version);
    return;
  }

  return version;
}

function getPackage (package, version, callback) {
  var dir = path.join(dataDir, package, version);

  // pre-load the expected MD5 checksum
  var md5File = path.join(dir, 'md5sum');
  var expectedSum = file.read(md5File);

  // create the cache directory, if it doesn't exist
  var cachedFile = path.join(cacheDir, package, version);
  mkdirp.sync(path.join(cacheDir, package));

  // if the cached file exists
  // and if the md5 sum of the cached file matches
  if (file.exists(cachedFile) && md5sum(cachedFile, expectedSum)) {
    logger.info('using', 'cached file for %s@%s', package, version);
    callback(null, cachedFile);
  }
  // otherwise download the file again
  else {
    logger.info('downloading', '%s@%s', package, version);
    var urlsFile = path.join(dir, 'urls');
    var urls = file.read(urlsFile);
    urls = urls.split(/[\r\n]/g);

    // TODO: try a random url every time
    var url = urls[0];
    downloadPackage(url, cachedFile, expectedSum, callback);
  }
}

function downloadPackage (url, cachedFile, expectedSum, callback) {
  var stream = fs.createWriteStream(cachedFile);
  request(url, stream, function (err, md5) {
    // var size = fs.statSync(cachedFile).size;
    // size = filesize(size, 2, false);
    logger.info('downloaded', url);
    if (md5 === expectedSum) {
      logger.info('checksum verfied', md5);
      callback(null, cachedFile);
    } else {
      logger.error('checksum failed', 'expected %s, got %s',
        expectedSum, md5);
      callback(new Error('checksum failed'));
    }
  });
}

function setupPackage (name, version, cache) {
  var destDir = path.resolve(modulesDir, name);
  mkdirp.sync(destDir);

  // copy over the cached file
  var source = path.join(destDir, 'source');
  logger.verbose('setting up', name);
  file.copy(cache, source);

  // patch, if needed
  patchPackage(name, version);

  // finalize
  deployPackage(name, version);
}

function patchPackage (name, version) {
  var destDir = path.resolve(modulesDir, name);
  var original = file.read(path.join(destDir, 'source'));
  var patchName = [name, version].join('@');
  var patchFile = path.resolve(cwd, 'patches', patchName);

  var content = original;
  if (file.exists(patchFile)) {
    logger.info('patching', patchName);
    var patch = file.read(patchFile);
    content = difftool.applyPatch(original, patch);
  }

  var dest = path.join(destDir, 'patched');
  file.write(dest, content);
}

function deployPackage (name, version) {
  var destDir = path.resolve(modulesDir, name);
  logger.verbose('linking', name, version);

  // delete current copy & move over the patched version
  var patched = path.join(destDir, 'patched');
  // TODO: use mauer.json for the path mappings to symlink the files
  var lib = path.resolve(cwd, 'public/vendor', name + '.js');
  if (file.exists(lib)) {
    file.delete(lib);
  }
  file.link(patched, lib);
}

function install () {
  var packages = [].slice.call(arguments);

  // if specific package installation was asked for
  if (packages.length > 0) {
    packages.forEach(installPackage);
  }
  // otherwise install everything on mauer.json
  else {
    var mauerFile = path.join(cwd, 'mauer.json');
    if (!file.exists(mauerFile)) {
      logger.error('config', 'mauer.json not found');
      return;
    } else {
      var mauerConfig = require(mauerFile);
      var dependencies = mauerConfig.dependencies;
      // TODO: handle malformed config

      var name, version;
      for (name in dependencies) {
        version = dependencies[name];
        installPackage([name, version].join('@'));
      }
    }
  }
}

module.exports = install;
<commit_msg>respect mauer config<commit_after>var logger = require('npmlog');
var semver = require('semver');
var mkdirp = require('mkdirp');
var difftool = require('diff');

var fs = require('fs');
var path = require('path');

var file = require('../utils/file');
var md5sum = require('../utils/md5sum');
var request = require('../utils/request');

var dataDir = path.resolve(__dirname, '../../data');

var cwd = process.cwd();
var baseDir = (process.env.HOME || '/tmp/');
var cacheDir = path.resolve(baseDir, '.mauer/cache');
var modulesDir = path.resolve(cwd, '.mauer');

var config = {
  'dependencyDir': 'public/vendor',
  'patchesDir': 'patches'
};

mkdirp.sync(cacheDir);
mkdirp.sync(modulesDir);

function installPackage (package) {

  var tokens = package.split('@');

  // allow only valid package names
  if (tokens.length > 2) {
    logger.error('', 'Invalid package "%s"', package);
    return;
  }

  var name = tokens[0];
  var packageDir = path.join(dataDir, name);
  if (!file.exists(packageDir)) {
    logger.error('', 'Unrecognised package "%s"', package);
    return;
  }

  var version = latestVersion(name, tokens[1]);
  if (version) {
    logger.info('installing', name, version);
    getPackage(name, version, function (err, cache) {
      if (err) {
        throw err;
      }
      setupPackage(name, version, cache);
      logger.info('done', name);
    });
  }
}

function latestVersion (package, version) {

  var packageDir = path.join(dataDir, package);
  var metaFile = path.join(packageDir, 'meta.json');
  var meta = require(metaFile);

  if (version && version !== 'latest') {
    var parsed = semver.parse(version);
    if (parsed) {
      version = parsed.splice(1,3).join('.');
    } else {
      logger.error('', 'Unsupported "%s@%s"', package, version);
      return;
    }
  }

  // If no version is passed, fallback to the latest version
  if (!version || version === 'latest') {
    version = meta.versions.sort(semver.rcompare)[0];
  } else if (meta.versions.indexOf(version) < 0) {
    logger.error('', 'Unsupported "%s@%s"', package, version);
    return;
  }

  return version;
}

function getPackage (package, version, callback) {
  var dir = path.join(dataDir, package, version);

  // pre-load the expected MD5 checksum
  var md5File = path.join(dir, 'md5sum');
  var expectedSum = file.read(md5File);

  // create the cache directory, if it doesn't exist
  var cachedFile = path.join(cacheDir, package, version);
  mkdirp.sync(path.join(cacheDir, package));

  // if the cached file exists
  // and if the md5 sum of the cached file matches
  if (file.exists(cachedFile) && md5sum(cachedFile, expectedSum)) {
    logger.info('using', 'cached file for %s@%s', package, version);
    callback(null, cachedFile);
  }
  // otherwise download the file again
  else {
    logger.info('downloading', '%s@%s', package, version);
    var urlsFile = path.join(dir, 'urls');
    var urls = file.read(urlsFile);
    urls = urls.split(/[\r\n]/g);

    // TODO: try a random url every time
    var url = urls[0];
    downloadPackage(url, cachedFile, expectedSum, callback);
  }
}

function downloadPackage (url, cachedFile, expectedSum, callback) {
  var stream = fs.createWriteStream(cachedFile);
  request(url, stream, function (err, md5) {
    // var size = fs.statSync(cachedFile).size;
    // size = filesize(size, 2, false);
    logger.info('downloaded', url);
    if (md5 === expectedSum) {
      logger.info('checksum verfied', md5);
      callback(null, cachedFile);
    } else {
      logger.error('checksum failed', 'expected %s, got %s',
        expectedSum, md5);
      callback(new Error('checksum failed'));
    }
  });
}

function setupPackage (name, version, cache) {
  var destDir = path.resolve(modulesDir, name);
  mkdirp.sync(destDir);

  // copy over the cached file
  var source = path.join(destDir, 'source');
  logger.verbose('setting up', name);
  file.copy(cache, source);

  // patch, if needed
  patchPackage(name, version);

  // finalize
  deployPackage(name, version);
}

function patchPackage (name, version) {
  var destDir = path.resolve(modulesDir, name);
  var original = file.read(path.join(destDir, 'source'));
  var patchName = [name, version].join('@');
  var patchFile = path.resolve(cwd, config.patchesDir, patchName);

  var content = original;
  if (file.exists(patchFile)) {
    logger.info('patching', patchName);
    var patch = file.read(patchFile);
    content = difftool.applyPatch(original, patch);
  }

  var dest = path.join(destDir, 'patched');
  file.write(dest, content);
}

function deployPackage (name, version) {
  var destDir = path.resolve(modulesDir, name);
  logger.verbose('linking', name, version);

  // delete current copy & move over the patched version
  var patched = path.join(destDir, 'patched');
  // TODO: use mauer.json for the path mappings to symlink the files
  var lib = path.resolve(cwd, config.dependencyDir, name + '.js');
  if (file.exists(lib)) {
    file.delete(lib);
  }
  file.link(patched, lib);
}

function installAll (mauerFile) {
  // TODO: handle malformed config
  var mauerConfig = require(mauerFile);
  var dependencies = mauerConfig.dependencies;

  config.patchesDir = mauerConfig.patchesDir;
  config.dependencyDir = mauerConfig.dependencyDir;

  // ensure that the destination directory exists
  mkdirp.sync(config.dependencyDir);

  var name, version;
  for (name in dependencies) {
    version = dependencies[name];
    installPackage([name, version].join('@'));
  }
}

function install () {
  var packages = [].slice.call(arguments);

  // if specific package installation was asked for
  if (packages.length > 0) {
    packages.forEach(installPackage);
  }
  // otherwise install everything on mauer.json
  else {
    var mauerFile = path.join(cwd, 'mauer.json');
    if (!file.exists(mauerFile)) {
      logger.error('config', 'mauer.json not found');
      return;
    } else {
      installAll (mauerFile);
    }
  }
}

module.exports = install;
<|endoftext|>


<commit_before>require('pixi')
require('p2')
require('phaser')

import { GameGroups } from '../sockets'

class HUD {
  constructor(game, player) {
    this.game = game

    this.player = player
    this.HUDElement = {}
    this.initHUD()

    GameGroups.HUD.setAll('fixedToCamera', true)
  }

  updateHealth() {
    this.HUDElement.currentHealth.setText(`HP: ${this.player.stats.hp}/${this.player.stats.maxHp}`)
  }

  updateWeapon() {
    this.HUDElement.currentWeapon.setText(`WEAPON: ${this.player.weaponKey}`)
  }

  updateStats() {
    this.HUDElement.currentStats.setText(`ATK: ${this.player.weapon.damage()}/DEF: ${this.player.stats.defense + this.player.armor.defense}`)
  }

  updateFeed(newFeed) {
    this.HUDElement.currentFeed.setText(`${newFeed}`)
    setTimeout(() => this.HUDElement.currentFeed.setText(''), 4000)
  }

  initHUD() {
    const gameX = this.game.width
    const gameY = this.game.height

    this.HUDElement.playerName = this.game.add.text(30, 25, `NAME: ${this.player.name}`, {
      font: '15px Press Start 2P',
      fill: '#2a2029',
      strokeThickness: 1
    })

    this.HUDElement.currentHealth = this.game.add.text(30, 55, `HP: ${this.player.stats.hp}/${this.player.stats.maxHp}`, {
      font: '15px Press Start 2P',
      fill: '#2a2029',
      strokeThickness: 1
    })

    this.HUDElement.currentStats = this.game.add.text(30, 85, `ATK: ${this.player.weapon.damage()}/DEF: ${this.player.stats.defense + this.player.armor.defense}`, {
      font: '15px Press Start 2P',
      fill: '#2a2029',
      strokeThickness: 1
    })

    this.HUDElement.currentWeapon = this.game.add.text(30, 115, `WEAPON: ${this.player.weaponKey}`, {
      font: '15px Press Start 2P',
      fill: '#2a2029',
      strokeThickness: 1
    })

    this.HUDElement.currentFeed = this.game.add.text(gameX / 2, gameY - 35, `Welcome to StackQuest`, {
      font: '17px Press Start 2P',
      fill: '#2a2029',
      strokeThickness: 1
    })
    this.HUDElement.currentFeed.anchor.set(0.5)

    for (const elements in this.HUDElement) {
      GameGroups.HUD.add(this.HUDElement[elements])
    }
  }
}

export default HUD
<commit_msg>add: player count in each room;<commit_after>require('pixi')
require('p2')
require('phaser')

import { GameGroups, GamePlayers } from '../sockets'

class HUD {
  constructor(game, player) {
    this.game = game

    this.player = player
    this.HUDElement = {}
    this.initHUD()

    GameGroups.HUD.setAll('fixedToCamera', true)
  }

  updateHealth() {
    this.HUDElement.currentHealth.setText(`HP: ${this.player.stats.hp}/${this.player.stats.maxHp}`)
  }

  updateWeapon() {
    this.HUDElement.currentWeapon.setText(`WEAPON: ${this.player.weaponKey}`)
  }

  updateStats() {
    this.HUDElement.currentStats.setText(`ATK: ${this.player.weapon.damage()}/DEF: ${this.player.stats.defense + this.player.armor.defense}`)
  }

  updateFeed(newFeed) {
    this.HUDElement.currentFeed.setText(`${newFeed}`)
    setTimeout(() => this.HUDElement.currentFeed.setText(''), 4000)
  }

  initHUD() {
    const gameX = this.game.width
    const gameY = this.game.height

    this.HUDElement.playerName = this.game.add.text(30, 25, `NAME: ${this.player.name}`, {
      font: '15px Press Start 2P',
      fill: '#2a2029',
      strokeThickness: 1
    })

    this.HUDElement.currentHealth = this.game.add.text(30, 55, `HP: ${this.player.stats.hp}/${this.player.stats.maxHp}`, {
      font: '15px Press Start 2P',
      fill: '#2a2029',
      strokeThickness: 1
    })

    this.HUDElement.currentStats = this.game.add.text(30, 85, `ATK: ${this.player.weapon.damage()}/DEF: ${this.player.stats.defense + this.player.armor.defense}`, {
      font: '15px Press Start 2P',
      fill: '#2a2029',
      strokeThickness: 1
    })

    this.HUDElement.currentWeapon = this.game.add.text(30, 115, `WEAPON: ${this.player.weaponKey}`, {
      font: '15px Press Start 2P',
      fill: '#2a2029',
      strokeThickness: 1
    })

    this.HUDElement.numPlayers = this.game.add.text(30, 115, `Players in World: ${Object.keys(GamePlayers).length}`, {
      font: '15px Press Start 2P',
      fill: '#2a2029',
      strokeThickness: 1
    })

    this.HUDElement.currentFeed = this.game.add.text(gameX / 2, gameY - 35, `Welcome to StackQuest`, {
      font: '15px Press Start 2P',
      fill: '#2a2029',
      strokeThickness: 1
    })
    this.HUDElement.currentFeed.anchor.set(0.5)

    for (const elements in this.HUDElement) {
      GameGroups.HUD.add(this.HUDElement[elements])
    }
  }
}

export default HUD
<|endoftext|>


<commit_before>openerp.report = function(instance) {
    var wkhtmltopdf_state;

    instance.web.ActionManager = instance.web.ActionManager.extend({
        ir_actions_report_xml: function(action, options) {
            var self = this;
            instance.web.blockUI();
            action = _.clone(action);
            _t =  instance.web._t;

            // QWeb reports
            if ('report_type' in action && (action.report_type == 'qweb-html' || action.report_type == 'qweb-pdf' || action.report_type == 'controller')) {
                var report_url = '';
                switch (action.report_type) {
                    case 'qweb-html':
                        report_url = '/report/html/' + action.report_name;
                        break;
                    case 'qweb-pdf':
                        report_url = '/report/pdf/' + action.report_name;
                        break;
                    case 'controller':
                        report_url = action.report_file;
                        break;
                    default:
                        report_url = '/report/html/' + action.report_name;
                        break;
                }

                // generic report: no query string
                // particular: query string of action.data.form and context
                if (!('data' in action) || !(action.data)) {
                    if ('active_ids' in action.context) {
                        report_url += "/" + action.context.active_ids.join(',');
                    }
                } else {
                    report_url += "?options=" + encodeURI(JSON.stringify(action.data));
                    report_url += "&context=" + encodeURI(JSON.stringify(action.context));
                }

                if (action.report_type == 'qweb-html') {
                    window.open(report_url, '_blank', 'height=900,width=1280');
                    instance.web.unblockUI();
                } else {
                    // Trigger the download of the pdf/controller report
                    var c = openerp.webclient.crashmanager;
                    var response = new Array();
                    response[0] = report_url;
                    response[1] = action.report_type;

                    if (action.report_type == 'qweb-pdf') {
                        (wkhtmltopdf_state = wkhtmltopdf_state || openerp.session.rpc('/report/check_wkhtmltopdf')).then(function (presence) {
                            // Fallback of qweb-pdf if wkhtmltopdf is not installed
                            if (presence == 'install' && action.report_type == 'qweb-pdf') {
                                self.do_notify(_t('Report'), _t('Unable to find Wkhtmltopdf on this \
    system. The report will be shown in html.

\
    wkhtmltopdf.org'), true);
                                window.open(report_url.substring(12), '_blank', 'height=768,width=1024');
                                instance.web.unblockUI();
                                return;
                            } else {
                                if (presence == 'upgrade') {
                                    self.do_notify(_t('Report'), _t('You should upgrade your version of\
     Wkhtmltopdf to at least 0.12.0 in order to get a correct display of headers and footers as well as\
     support for table-breaking between pages.

wkhtmltopdf.org'), true);
                                }
                            }
                        });
                    }
                    self.session.get_file({
                        url: '/report/download',
                        data: {data: JSON.stringify(response)},
                        complete: openerp.web.unblockUI,
                        error: c.rpc_error.bind(c)
                    });
                }
            } else {
                return self._super(action, options);
            }
        }
    });
};
<commit_msg>[FIX] action manager: use EncodeURIComponent instead of EncodeURI because of bad encoding of the ampersand in the secund (resulting in impossibility to encode 'Belgium Profit & Loss' for instance)<commit_after>openerp.report = function(instance) {
    var wkhtmltopdf_state;

    instance.web.ActionManager = instance.web.ActionManager.extend({
        ir_actions_report_xml: function(action, options) {
            var self = this;
            instance.web.blockUI();
            action = _.clone(action);
            _t =  instance.web._t;

            // QWeb reports
            if ('report_type' in action && (action.report_type == 'qweb-html' || action.report_type == 'qweb-pdf' || action.report_type == 'controller')) {
                var report_url = '';
                switch (action.report_type) {
                    case 'qweb-html':
                        report_url = '/report/html/' + action.report_name;
                        break;
                    case 'qweb-pdf':
                        report_url = '/report/pdf/' + action.report_name;
                        break;
                    case 'controller':
                        report_url = action.report_file;
                        break;
                    default:
                        report_url = '/report/html/' + action.report_name;
                        break;
                }

                // generic report: no query string
                // particular: query string of action.data.form and context
                if (!('data' in action) || !(action.data)) {
                    if ('active_ids' in action.context) {
                        report_url += "/" + action.context.active_ids.join(',');
                    }
                } else {
                    report_url += "?options=" + encodeURIComponent(JSON.stringify(action.data));
                    report_url += "&context=" + encodeURIComponent(JSON.stringify(action.context));
                }

                if (action.report_type == 'qweb-html') {
                    window.open(report_url, '_blank', 'height=900,width=1280');
                    instance.web.unblockUI();
                } else {
                    // Trigger the download of the pdf/controller report
                    var c = openerp.webclient.crashmanager;
                    var response = new Array();
                    response[0] = report_url;
                    response[1] = action.report_type;

                    if (action.report_type == 'qweb-pdf') {
                        (wkhtmltopdf_state = wkhtmltopdf_state || openerp.session.rpc('/report/check_wkhtmltopdf')).then(function (presence) {
                            // Fallback of qweb-pdf if wkhtmltopdf is not installed
                            if (presence == 'install' && action.report_type == 'qweb-pdf') {
                                self.do_notify(_t('Report'), _t('Unable to find Wkhtmltopdf on this \
    system. The report will be shown in html.

\
    wkhtmltopdf.org'), true);
                                window.open(report_url.substring(12), '_blank', 'height=768,width=1024');
                                instance.web.unblockUI();
                                return;
                            } else {
                                if (presence == 'upgrade') {
                                    self.do_notify(_t('Report'), _t('You should upgrade your version of\
     Wkhtmltopdf to at least 0.12.0 in order to get a correct display of headers and footers as well as\
     support for table-breaking between pages.

wkhtmltopdf.org'), true);
                                }
                            }
                        });
                    }
                    self.session.get_file({
                        url: '/report/download',
                        data: {data: JSON.stringify(response)},
                        complete: openerp.web.unblockUI,
                        error: c.rpc_error.bind(c)
                    });
                }
            } else {
                return self._super(action, options);
            }
        }
    });
};
<|endoftext|>


<commit_before>var querystring = require('querystring');
var crypto = require('crypto');
var config = require('./config');
var Request = require('./Request');
var timeOffset = 1000 * 60 * 10;
var paramError = new Error('缺少参数');

/**
 * 初始化
 * @param {Object} options
 * @constructor
 *
 * options 可选值：
 * appKey {string} 应用的appKey
 * appSecret {string} 应用的appSecret
 * callbackUrl {string} 用于开放应用，应用管理后台设置的回调地址
 * redirectUrl {string} 用于开放应用，可选，自定义回调地址，默认同 callbackUrl
 * scope {Array} 用于开放应用，可选，权限范围，默认为 ['read_basic']
 * private {boolean} 可选，是否为私有应用，默认为 false
 */
var Auth = function (options) {
  if (arguments.length < 1 || !options.appKey || !options.appSecret) {
    throw paramError;
  }
  if (!options.private) {
    if (!options.callbackUrl) {
      throw paramError;
    }
    options.scope || (options.scope = ['read_basic']);
  }
  this.options = options;
  this.protocol = (options && options.protocol) || config.httpProtocol;
  this.host = (options && options.host) || config.appHost;
  this._request = new Request({
    protocol: this.protocol,
  });
};

Auth.prototype = {
  /**
   * 验证 Hmac
   * @param {Object} queryObj 回调地址的参数对象
   * @return {boolean}
   */
  verifyHmac: function (queryObj) {
    if (arguments.length < 1) {
      throw paramError;
    }
    var hmac = queryObj.hmac;
    delete queryObj.hmac;
    return (Date.now() - new Date(queryObj.time_stamp).getTime() < timeOffset) &&
      (hmac === crypto.createHmac('sha256', this.options.appSecret)
        .update(decodeURIComponent(querystring.stringify(queryObj)), 'utf8')
        .digest('hex'));
  },
  /**
   * 获取应用授权页面地址，用于开放应用
   * @param {string} shopKey
   * @param {string} state
   * @return {string}
   */
  getAuthorizeUrl: function (shopKey, state) {
    if (arguments.length < 1) {
      throw paramError;
    }
    return this.protocol + '://' + this.host + '/oauth2/authorize?' + querystring.stringify({
      response_type: 'code',
      client_id: this.options.appKey,
      shop_key: shopKey,
      scope: this.options.scope.join(','),
      state: state,
      redirect_uri: this.options.redirectUrl
    }, null, null, { encodeURIComponent: null });
  },
  /**
   * 获取 token
   * @param {string} code，用于开放应用
   */
  getToken: function (code) {
    var params;
    var headers = { 'Content-Type': 'application/x-www-form-urlencoded' };

    if (this.options.private) {
      headers.Authorization = 'Basic ' + new Buffer(this.options.appKey + ':' + this.options.appSecret).toString('base64');
      params = {
        grant_type: 'client_credentials'
      };
    } else {
      if (arguments.length < 1) {
        throw paramError;
      }
      params = {
        grant_type: 'authorization_code',
        code: code,
        client_id: this.options.appKey,
        redirect_uri: this.options.redirectUrl ? this.options.redirectUrl : this.options.callbackUrl
      };
    }

    var option = {
      hostname: this.host,
      path: '/oauth2/token',
      method: 'POST',
      headers: headers
    };
    return this._request.request(option, params).then(function (data) {
      if (!data.token.length) {
        throw new Error('无效的 token');
      }
      return data.token;
    });
  },
  customerData: function (secret_key, customer_data) {
    var customer_str = JSON.stringify(customer_data);
    var cipher = crypto.createCipher('aes-256-cbc', secret_key);
    var crypted = cipher.update(customer_str, 'utf8', 'hex');
    return cipher.final('hex');
  }
};

module.exports = Auth;
<commit_msg>所有参数先什么再使用；<commit_after>var querystring = require('querystring');
var crypto = require('crypto');
var config = require('./config');
var Request = require('./Request');
var timeOffset = 1000 * 60 * 10;
var paramError = new Error('缺少参数');

/**
 * 初始化
 * @param {Object} options
 * @constructor
 *
 * options 可选值：
 * appKey {string} 应用的appKey
 * appSecret {string} 应用的appSecret
 * callbackUrl {string} 用于开放应用，应用管理后台设置的回调地址
 * redirectUrl {string} 用于开放应用，可选，自定义回调地址，默认同 callbackUrl
 * scope {Array} 用于开放应用，可选，权限范围，默认为 ['read_basic']
 * private {boolean} 可选，是否为私有应用，默认为 false
 */
var Auth = function (options) {
  if (arguments.length < 1 || !options.appKey || !options.appSecret) {
    throw paramError;
  }
  if (!options.private) {
    if (!options.callbackUrl) {
      throw paramError;
    }
    options.scope || (options.scope = ['read_basic']);
  }

  this.app_key = options.appKey || '';
  this.app_secret = options.appSecret || '';
  this.private = options.private || false;
  this.callback_url = options.callbackUrl || '';
  this.scope = options.scope || '';
  this.redirect_url = options.redirectUrl || '';
  this.protocol = options.protocol || config.httpProtocol;
  this.host = options.host || config.appHost;
  this._request = new Request({
    protocol: this.protocol,
  });
};

Auth.prototype = {
  /**
   * 验证 Hmac
   * @param {Object} queryObj 回调地址的参数对象
   * @return {boolean}
   */
  verifyHmac: function (queryObj) {
    if (arguments.length < 1) {
      throw paramError;
    }
    var hmac = queryObj.hmac;
    delete queryObj.hmac;
    return (Date.now() - new Date(queryObj.time_stamp).getTime() < timeOffset) &&
      (hmac === crypto.createHmac('sha256', this.app_secret)
        .update(decodeURIComponent(querystring.stringify(queryObj)), 'utf8')
        .digest('hex'));
  },
  /**
   * 获取应用授权页面地址，用于开放应用
   * @param {string} shopKey
   * @param {string} state
   * @return {string}
   */
  getAuthorizeUrl: function (shopKey, state) {
    if (arguments.length < 1) {
      throw paramError;
    }
    return this.protocol + '://' + this.host + '/oauth2/authorize?' + querystring.stringify({
      response_type: 'code',
      client_id: this.app_key,
      shop_key: shopKey,
      scope: this.scope.join(','),
      state: state,
      redirect_uri: this.redirect_url
    }, null, null, { encodeURIComponent: null });
  },
  /**
   * 获取 token
   * @param {string} code，用于开放应用
   */
  getToken: function (code) {
    var params;
    var headers = { 'Content-Type': 'application/x-www-form-urlencoded' };

    if (this.private) {
      headers.Authorization = 'Basic ' + new Buffer(this.app_key + ':' + this.app_secret).toString('base64');
      params = {
        grant_type: 'client_credentials'
      };
    } else {
      if (arguments.length < 1) {
        throw paramError;
      }
      params = {
        grant_type: 'authorization_code',
        code: code,
        client_id: this.app_key,
        redirect_uri: this.redirect_url ? this.redirect_url : this.callback_url
      };
    }

    var option = {
      hostname: this.host,
      path: '/oauth2/token',
      method: 'POST',
      headers: headers
    };
    return this._request.request(option, params).then(function (data) {
      if (!data.token.length) {
        throw new Error('无效的 token');
      }
      return data.token;
    });
  },
  customerData: function (secret_key, customer_data) {
    var customer_str = JSON.stringify(customer_data);
    var cipher = crypto.createCipher('aes-256-cbc', secret_key);
    var crypted = cipher.update(customer_str, 'utf8', 'hex');
    return cipher.final('hex');
  }
};

module.exports = Auth;
<|endoftext|>


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

// 1) validate a zip file argument was supplied
// 2) unzip the zip file using node_appc
// 3) copy the "mobileweb" directory to "tizen"
// 4) remove tizen/templates/app/default/resources/mobileweb directory
// 4) copy tizen files (cli, templates, titanium) on top of "tizen" directory
// 5) copy titanium-sdk/lib/tiappxml.js on top of node_modules/titanium-sdk/lib
// 6) read manifest.json, parse json, add "tizen" to platforms, stringify json, write manifest
// 7) run dependencies.json builder using titanium_mobile/support/mobileweb/dependencyAnalyzer
// 8) re-zip distribution file with "VERSION-tizen.zip"

//input parameters:
// path to zip
// output file name
// working directory

//TODO: use smarter way for logging

console.log("cli args: " + process.argv);

var fs = require('fs'),
	path = require('path'),
	async = require('async'),
	appc = require('node-appc'),
	xmldom = require('xmldom'),
	wrench = require('wrench'),
	scriptArgs = process.argv.slice(2),
	workingDir = scriptArgs[1],
	titaniumTizenDir = __dirname,
	sdkRoot,
	resultPath;

console.log('[DEBUG] scriptArgs(zip, working): ' + scriptArgs);

async.series([
	function(next){
		//Validation
		if(validateArgs(scriptArgs)){

			var archiveName = path.basename(scriptArgs[0]);
			//build name for output zip with SDK
			archiveName = archiveName.replace('.zip', '-tizen.zip');
			resultPath = path.join(path.dirname(scriptArgs[0]), archiveName);
			console.log('[DEBUG] created output file name: ' + resultPath);
			next(null, 'ok');
		}
	}
	, function(next){
		console.log('Start unzip');
		//Unzip
		var resultCb = function(errorMsg){
			if(errorMsg){
				//TODO: do not ignore error, right now it is required for Windows since 7z return error always
				//next('Unzip failed' + errorMsg, 'ok');
				console.log('[DEBUG] unzip finished with error: ' + errorMsg);
				next(null, 'ok');
			}else{
				next(null, 'ok');
			}
		};
		if(process.platform === 'win32'){
			unzip7za(scriptArgs[0], scriptArgs[1], resultCb);
		}else{
			appc.zip.unzip(scriptArgs[0], scriptArgs[1], resultCb);
		}
	}
	, function(next){
		console.log('[DEBUG] Create tizen platform, initially copy it from mobileweb');
 		copymobilWebToTizen(function(){
 			console.log('[DEBUG] copymobilWebToTizen calling next()');
 			next(null, 'ok');
 		});
	}
	, function(next){
		console.log('[DEBUG] fixing manifest.json');
		fixManifest();
		next(null, 'ok');
	}, function(next){
		executeDependenciesAnalyzer(function(){
			next(null, 'ok');
		});
	}, function(next){
		if(process.platform === 'win32'){
			console.log('Start packaging on win32');
			packagingSDK7z(function(){
				next(null, 'ok');
			});
		} else {
			packagingSDKLinux(function(){
				next('Packaging on linux', null);
			});
			next('Packaging on linux', null);
		}
	}
	], function(err){
		if(err)
			console.log(err)
		else {
			// Waits for defined functions to finish
			console.log('Finished')
		}
});

//validating inpup parameters
function validateArgs(params){
	var workOk = true;
	if(!fs.existsSync(params[0])){
		console.log('Error: param 1 should point existng zip archive. Current value: ' + params[0]);
		workOk = false;
	}
	var stats = fs.statSync(params[1]);
	if(!stats.isDirectory() ){
		console.log('Error: param 3 should point existing directory. Current value: ' + params[1]);
		workOk = false;
	}
	return workOk;
}

function copymobilWebToTizen(finish){
	//todo: need same for linux
	var basePath = path.join(workingDir, 'mobilesdk', 'win32');
	console.log('[DEBUG] Looking for sdk in  folder:' + basePath);
	appc.fs.visitDirs(basePath,
		function(name, dpath){
			sdkRoot = dpath;
			console.log('[DEBUG] Full path to SDK folder:' + sdkRoot);
		},
		function(){
			//visitDirs finished, sdk root detected, do copy
			console.log('[DEBUG] wrench.copyDirSyncRecursive from ' + path.join(sdkRoot, 'mobileweb') + " to "+ path.join(sdkRoot, 'tizen'));
			wrench.copyDirSyncRecursive(path.join(sdkRoot, 'mobileweb'), path.join(sdkRoot, 'tizen'));

			console.log('[DEBUG] copyDirSyncRecursiveEx from ' +path.join(titaniumTizenDir, 'titanium', 'Ti') + " to "+ path.join(sdkRoot, 'tizen', 'titanium', 'Ti'));
			copyDirSyncRecursiveEx(path.join(titaniumTizenDir, 'titanium', 'Ti'), path.join(sdkRoot, 'tizen', 'titanium', 'Ti'));

			copyDirSyncRecursiveEx(path.join(titaniumTizenDir, 'cli', 'commands'), path.join(sdkRoot, 'tizen', 'cli', 'commands'));

			copyFileSync(path.join(titaniumTizenDir, 'titanium', 'Ti.js'), path.join(sdkRoot, 'tizen', 'titanium', 'Ti.js'));

			//remove tizen/templates/app/default/resources/mobileweb directory
			console.log('[DEBUG]rmdirSyncRecursive from ' + path.join(sdkRoot, 'tizen', 'templates', 'app', 'default', 'Resources', 'mobileweb'));
			wrench.rmdirSyncRecursive(path.join(sdkRoot, 'tizen', 'templates', 'app', 'default', 'Resources', 'mobileweb'), false);

			//config.tmpl template for
			copyFileSync(path.join(titaniumTizenDir, 'templates', 'app', 'config.tmpl'), path.join(sdkRoot, 'tizen', 'templates', 'app', 'config.tmpl'));

			wrench.copyDirSyncRecursive(path.join(titaniumTizenDir,'templates', 'app', 'default', 'Resources', 'tizen'), path.join(sdkRoot, 'tizen', 'templates', 'app', 'default', 'Resources', 'tizen'));

			copyFileSync(path.join(titaniumTizenDir, 'src', 'loader.js'), path.join(sdkRoot, 'tizen', 'src', 'loader.js'));

			copyDirSyncRecursiveEx(path.join(titaniumTizenDir, 'dependencyAnalyzer'), path.join(sdkRoot, 'tizen', 'dependencyAnalyzer'));

			//signer app for tizen
			fs.mkdirSync(path.join(sdkRoot, 'tizen', 'utils'));
			copyFileSync(path.join(titaniumTizenDir, 'utils', 'signapp.jar'), path.join(sdkRoot, 'tizen', 'utils', 'signapp.jar'));

			finish();
		}
	);
}

function fixManifest(){
	var manifestPath = path.join(sdkRoot, "manifest.json");
	var manifestStr = fs.readFileSync(manifestPath, 'utf8').toString();
	var manifestObject = JSON.parse(manifestStr);
	manifestObject.platforms.push("tizen");
	fs.writeFileSync(manifestPath, JSON.stringify(manifestObject), 'utf8');
}

function executeDependenciesAnalyzer(finished){
	console.log('[DEBUG] executeDependenciesAnalyzer ');
	var runner = require('child_process');
	var scriptpath = path.join(sdkRoot, 'tizen', 'dependencyAnalyzer', 'dependencyAnalyzer.js');
	var analyzerCmd = 'node "' + scriptpath + '"';

	console.log('starting dependency analyzer: ' + analyzerCmd);
	options = { cwd: path.join(sdkRoot, 'tizen', 'dependencyAnalyzer') };
	runner.exec(
		analyzerCmd,
		function (err, stdout, stderr) {
			console.log(stdout);
			if(err != null){
				console.log('[Error] executeDependenciesAnalyzer failed');
				console.log(stderr);
			}else{
				console.log('executeDependenciesAnalyzer ok');
			}
			finished();
		});
}

function copyFileSync(srcFile, destFile) {
	console.log('[DEBUG] copyFileSync from ' + srcFile + " to "+ destFile);
	var bytesRead, fdr, fdw, pos;
	var BUF_LENGTH = 64 * 1024;
	var _buff = new Buffer(BUF_LENGTH);
	fdr = fs.openSync(srcFile, 'r');
	fdw = fs.openSync(destFile, 'w');
	bytesRead = 1;
	pos = 0;
	while (bytesRead > 0) {
		bytesRead = fs.readSync(fdr, _buff, 0, BUF_LENGTH, pos);
		fs.writeSync(fdw, _buff, 0, bytesRead);
		pos += bytesRead;
	}
	fs.closeSync(fdr);
	return fs.closeSync(fdw);
}

function copyDirSyncRecursiveEx(sourceDir, newDirLocation) {
	console.log('[DEBUG] copyDirSyncRecursiveEx src ' + sourceDir + " destination "+ newDirLocation);
    /*  Create the directory where all our junk is moving to; read the mode of the source directory and mirror it */
    var checkDir = fs.statSync(sourceDir);
    try {
    	if(!fs.existsSync(newDirLocation)){
        	fs.mkdirSync(newDirLocation, checkDir.mode);
    	}
    } catch (e) {
        //if the directory already exists, that's okay
        if (e.code !== 'EEXIST') throw e;
    }

    var files = fs.readdirSync(sourceDir);
	console.log('[DEBUG] copyDirSyncRecursiveEx created filelist for ' + sourceDir + " it contains "+ files.length);
    for(var i = 0; i < files.length; i++) {
        var currFile = fs.lstatSync(sourceDir + "/" + files[i]);
        if(currFile.isDirectory()) {
            /*  recursion this thing right on back. */
            copyDirSyncRecursiveEx(sourceDir + "/" + files[i], newDirLocation + "/" + files[i]);
        } else if(currFile.isSymbolicLink()) {
        	console.log('[WARRNING] copyDirSyncRecursiveEx symlink instead of file: ' + sourceDir + "/" + files[i]);
            var symlinkFull = fs.readlinkSync(sourceDir + "/" + files[i]);
            fs.symlinkSync(symlinkFull, newDirLocation + "/" + files[i]);
        } else {
            /*  At this point, we've hit a file actually worth copying... so copy it on over. */
            copyFileSync(sourceDir + "/" + files[i], newDirLocation + "/" + files[i])
        }
    }
}

function find7za(){
	var zippath = path.normalize(path.join(path.dirname(require.resolve('node-appc')), '..','tools','7zip','7za.exe'));
	console.log('7za.exe detected. Path is ' + path.normalize(zippath));

	if(fs.existsSync(zippath)){
		return zippath;
	}else{
		console.log('Not found 7za.exe path is wrong ' + path.normalize(zippath));
	}
}

function packagingSDK7z(finish){
	console.log('Packaging application into zip');
	var packer = require('child_process');
	// Create the tasks to unzip each entry in the zip file
	var child,
	stdout = '',
	stderr = '';

	child = packer.spawn(path.resolve(find7za().toString()), ['a', resultPath, workingDir + '/*', '-tzip']);
	child.stdout.on('data', function (data) {
		stdout += data.toString();
	});
	child.on('exit', function (code, signal) {
		if (finish) {
			if (code) {
				// if we're on windows, the error message is actually in stdout, so scan for it
				if (process.platform === 'win32') {
					var foundError = false,
						err = [];

					stdout.split('\n').forEach(function (line) {
						if (/^Error\:/.test(line)) {
							foundError = true;
						}
						if (foundError) {
							line && err.push(line.trim());
						}
					});

					if (err.length) {
						stderr = err.join('\n') + stderr;
					}
				}
				finish();
			} else {
				finish();
			}
		}
	});
}

function unzip7za(src, dest, callback){
	var packer = require('child_process');
	// Create the tasks to unzip each entry in the zip file
	var child,
	stdout = '',
	stderr = '';

	child = packer.spawn(path.resolve(find7za().toString()), ['x', src, '-o' + dest, '-y', '-bd']);
	child.stdout.on('data', function (data) {
		stdout += data.toString();
	});
	child.on('exit', function (code, signal) {
		if (callback) {
			if (code) {
				// if we're on windows, the error message is actually in stdout, so scan for it
				if (process.platform === 'win32') {
					var foundError = false,
						err = [];

					stdout.split('\n').forEach(function (line) {
						if (/^Error\:/.test(line)) {
							foundError = true;
						}
						if (foundError) {
							line && err.push(line.trim());
						}
					});

					if (err.length) {
						stderr = err.join('\n') + stderr;
					}
				}
				callback(null);
			} else {
				callback(null);
			}
		}
	});
}

function packagingSDKLinux(finish){
	console.log('Packaging application into zip with linux zip');
	var packer = require('child_process');
	var async = require('async');
	var cmdzip = 'zip -r "' + resultPath + '" *';
	console.log('zip cmd: ' + cmdzip);
	packer.exec(
		cmdzip,
		{
			cwd: workingDir
		},
		function (err, stdout, stderr) {
			console.log(stdout);
			if(err != null){
				console.log('failed packaging for tizen platform with errors:\n' + stderr);
			}else{
				console.log('compressing ok');
			}
			finish(null);
		});
}
<commit_msg>building win32 sdk working on linux<commit_after>#!/usr/bin/env node

// 1) validate a zip file argument was supplied
// 2) unzip the zip file using node_appc
// 3) copy the "mobileweb" directory to "tizen"
// 4) remove tizen/templates/app/default/resources/mobileweb directory
// 4) copy tizen files (cli, templates, titanium) on top of "tizen" directory
// 5) copy titanium-sdk/lib/tiappxml.js on top of node_modules/titanium-sdk/lib
// 6) read manifest.json, parse json, add "tizen" to platforms, stringify json, write manifest
// 7) run dependencies.json builder using titanium_mobile/support/mobileweb/dependencyAnalyzer
// 8) re-zip distribution file with "VERSION-tizen.zip"

//input parameters:
// path to zip
// output file name
// working directory

console.log("cli args: " + process.argv);

var fs = require('fs'),
	path = require('path'),
	async = require('async'),
	appc = require('node-appc'),
	xmldom = require('xmldom'),
	wrench = require('wrench'),
	scriptArgs = process.argv.slice(2),
	workingDir = scriptArgs[1],
	titaniumTizenDir = __dirname,
	sdkRoot,
	resultPath;

console.log('[DEBUG] scriptArgs(zip, working directory): ' + scriptArgs);

async.series([
	function(next){
		//Validation
		if(validateArgs(scriptArgs)){
			var archiveName = path.basename(scriptArgs[0]);
			//build name for output zip with SDK
			archiveName = archiveName.replace('.zip', '-tizen.zip');
			resultPath = path.join(path.dirname(scriptArgs[0]), archiveName);
			console.log('[DEBUG] created output file name: ' + resultPath);
			next(null, 'ok');
		}
	}
	, function(next){
		console.log('Start unzip');
		//Unzip callback
		var resultCb = function(errorMsg){
			if(errorMsg){
				console.log('[DEBUG] unzip finished with error: ' + errorMsg);
				next(null, 'ok');
			}else{
				next(null, 'ok');
			}
		};
		if(process.platform === 'win32'){
			unzip7za(scriptArgs[0], scriptArgs[1], resultCb);
		}else{
			appc.zip.unzip(scriptArgs[0], scriptArgs[1], resultCb);
		}
	}
	, function(next){
		console.log('[DEBUG] Create tizen platform, initially copy it from mobileweb');
 		copymobilWebToTizen(function(){
 			console.log('[DEBUG] copymobilWebToTizen calling next()');
 			next(null, 'ok');
 		});
	}
	, function(next){
		console.log('[DEBUG] fixing manifest.json');
		fixManifest();
		next(null, 'ok');
	}, function(next){
		executeDependenciesAnalyzer(function(){
			next(null, 'ok');
		});
	}, function(next){
		if(process.platform === 'win32'){
			console.log('Start packaging on win32');
			packagingSDK7z(function(){
				next(null, 'ok');
			});
		} else {
			packagingSDKLinux(function(){
				next('Packaging on linux', null);
			});
		}
	}
	], function(err){
		if(err)
			console.log(err)
		console.log('Finished.')

});

//validating input parameters
function validateArgs(params){
	var workOk = true;
	if(!fs.existsSync(params[0])){
		console.log('Error: param 1 should point existng zip archive. Current value: ' + params[0]);
		workOk = false;
	}
	var stats = fs.statSync(params[1]);
	if(!stats.isDirectory() ){
		console.log('Error: param 3 should point existing directory. Current value: ' + params[1]);
		workOk = false;
	}
	return workOk;
}

function copymobilWebToTizen(finish){
	var basePath = path.join(workingDir, 'mobilesdk', 'win32');
	console.log('[DEBUG] Looking for sdk in  folder:' + basePath);
	appc.fs.visitDirs(basePath,
		function(name, dpath){
			sdkRoot = dpath;
			console.log('[DEBUG] Full path to SDK folder:' + sdkRoot);
		},
		function(){
			//visitDirs finished, sdk root detected, do copy
			console.log('[DEBUG] wrench.copyDirSyncRecursive from ' + path.join(sdkRoot, 'mobileweb') + " to "+ path.join(sdkRoot, 'tizen'));
			wrench.copyDirSyncRecursive(path.join(sdkRoot, 'mobileweb'), path.join(sdkRoot, 'tizen'));

			console.log('[DEBUG] copyDirSyncRecursiveEx from ' +path.join(titaniumTizenDir, 'titanium', 'Ti') + " to "+ path.join(sdkRoot, 'tizen', 'titanium', 'Ti'));
			copyDirSyncRecursiveEx(path.join(titaniumTizenDir, 'titanium', 'Ti'), path.join(sdkRoot, 'tizen', 'titanium', 'Ti'));

			copyDirSyncRecursiveEx(path.join(titaniumTizenDir, 'cli', 'commands'), path.join(sdkRoot, 'tizen', 'cli', 'commands'));

			copyFileSync(path.join(titaniumTizenDir, 'titanium', 'Ti.js'), path.join(sdkRoot, 'tizen', 'titanium', 'Ti.js'));

			//remove tizen/templates/app/default/resources/mobileweb directory
			console.log('[DEBUG]rmdirSyncRecursive from ' + path.join(sdkRoot, 'tizen', 'templates', 'app', 'default', 'Resources', 'mobileweb'));
			wrench.rmdirSyncRecursive(path.join(sdkRoot, 'tizen', 'templates', 'app', 'default', 'Resources', 'mobileweb'), false);

			//config.tmpl template for
			copyFileSync(path.join(titaniumTizenDir, 'templates', 'app', 'config.tmpl'), path.join(sdkRoot, 'tizen', 'templates', 'app', 'config.tmpl'));

			wrench.copyDirSyncRecursive(path.join(titaniumTizenDir,'templates', 'app', 'default', 'Resources', 'tizen'), path.join(sdkRoot, 'tizen', 'templates', 'app', 'default', 'Resources', 'tizen'));

			copyFileSync(path.join(titaniumTizenDir, 'src', 'loader.js'), path.join(sdkRoot, 'tizen', 'src', 'loader.js'));

			copyDirSyncRecursiveEx(path.join(titaniumTizenDir, 'dependencyAnalyzer'), path.join(sdkRoot, 'tizen', 'dependencyAnalyzer'));

			//signer app for tizen
			fs.mkdirSync(path.join(sdkRoot, 'tizen', 'utils'));
			copyFileSync(path.join(titaniumTizenDir, 'utils', 'signapp.jar'), path.join(sdkRoot, 'tizen', 'utils', 'signapp.jar'));

			finish();
		}
	);
}

function fixManifest(){
	var manifestPath = path.join(sdkRoot, "manifest.json");
	var manifestStr = fs.readFileSync(manifestPath, 'utf8').toString();
	var manifestObject = JSON.parse(manifestStr);
	manifestObject.platforms.push("tizen");
	fs.writeFileSync(manifestPath, JSON.stringify(manifestObject), 'utf8');
}

function executeDependenciesAnalyzer(finished){
	console.log('[DEBUG] executeDependenciesAnalyzer ');
	var runner = require('child_process');
	var scriptpath = path.join(sdkRoot, 'tizen', 'dependencyAnalyzer', 'dependencyAnalyzer.js');
	var analyzerCmd = 'node "' + scriptpath + '"';

	console.log('starting dependency analyzer: ' + analyzerCmd);
	options = { cwd: path.join(sdkRoot, 'tizen', 'dependencyAnalyzer') };
	runner.exec(
		analyzerCmd,
		function (err, stdout, stderr) {
			console.log(stdout);
			if(err != null){
				console.log('[Error] executeDependenciesAnalyzer failed');
				console.log(stderr);
			}else{
				console.log('executeDependenciesAnalyzer ok');
			}
			finished();
		});
}

function copyFileSync(srcFile, destFile) {
	console.log('[DEBUG] copyFileSync from ' + srcFile + " to "+ destFile);
	var bytesRead, fdr, fdw, pos;
	var BUF_LENGTH = 64 * 1024;
	var _buff = new Buffer(BUF_LENGTH);
	fdr = fs.openSync(srcFile, 'r');
	fdw = fs.openSync(destFile, 'w');
	bytesRead = 1;
	pos = 0;
	while (bytesRead > 0) {
		bytesRead = fs.readSync(fdr, _buff, 0, BUF_LENGTH, pos);
		fs.writeSync(fdw, _buff, 0, bytesRead);
		pos += bytesRead;
	}
	fs.closeSync(fdr);
	return fs.closeSync(fdw);
}

function copyDirSyncRecursiveEx(sourceDir, newDirLocation) {
	console.log('[DEBUG] copyDirSyncRecursiveEx src ' + sourceDir + " destination "+ newDirLocation);
    /*  Create the directory where all our junk is moving to; read the mode of the source directory and mirror it */
    var checkDir = fs.statSync(sourceDir);
    try {
    	if(!fs.existsSync(newDirLocation)){
        	fs.mkdirSync(newDirLocation, checkDir.mode);
    	}
    } catch (e) {
        //if the directory already exists, that's okay
        if (e.code !== 'EEXIST') throw e;
    }

    var files = fs.readdirSync(sourceDir);
	console.log('[DEBUG] copyDirSyncRecursiveEx created filelist for ' + sourceDir + " it contains "+ files.length);
    for(var i = 0; i < files.length; i++) {
        var currFile = fs.lstatSync(sourceDir + "/" + files[i]);
        if(currFile.isDirectory()) {
            /*  recursion this thing right on back. */
            copyDirSyncRecursiveEx(sourceDir + "/" + files[i], newDirLocation + "/" + files[i]);
        } else if(currFile.isSymbolicLink()) {
        	console.log('[WARRNING] copyDirSyncRecursiveEx symlink instead of file: ' + sourceDir + "/" + files[i]);
            var symlinkFull = fs.readlinkSync(sourceDir + "/" + files[i]);
            fs.symlinkSync(symlinkFull, newDirLocation + "/" + files[i]);
        } else {
            /*  At this point, we've hit a file actually worth copying... so copy it on over. */
            copyFileSync(sourceDir + "/" + files[i], newDirLocation + "/" + files[i])
        }
    }
}

function find7za(){
	var zippath = path.normalize(path.join(path.dirname(require.resolve('node-appc')), '..','tools','7zip','7za.exe'));
	console.log('7za.exe detected. Path is ' + path.normalize(zippath));

	if(fs.existsSync(zippath)){
		return zippath;
	}else{
		console.log('Not found 7za.exe path is wrong ' + path.normalize(zippath));
	}
}

function packagingSDK7z(finish){
	console.log('Packaging application into zip');
	var packer = require('child_process');
	// Create the tasks to unzip each entry in the zip file
	var child,
	stdout = '',
	stderr = '';

	child = packer.spawn(path.resolve(find7za().toString()), ['a', resultPath, workingDir + '/*', '-tzip']);
	child.stdout.on('data', function (data) {
		stdout += data.toString();
	});
	child.on('exit', function (code, signal) {
		if (finish) {
			if (code) {
				// if we're on windows, the error message is actually in stdout, so scan for it
				if (process.platform === 'win32') {
					var foundError = false,
						err = [];

					stdout.split('\n').forEach(function (line) {
						if (/^Error\:/.test(line)) {
							foundError = true;
						}
						if (foundError) {
							line && err.push(line.trim());
						}
					});

					if (err.length) {
						stderr = err.join('\n') + stderr;
					}
				}
				finish();
			} else {
				finish();
			}
		}
	});
}

function unzip7za(src, dest, callback){
	var packer = require('child_process');
	// Create the tasks to unzip each entry in the zip file
	var child,
	stdout = '',
	stderr = '';

	child = packer.spawn(path.resolve(find7za().toString()), ['x', src, '-o' + dest, '-y', '-bd']);
	child.stdout.on('data', function (data) {
		stdout += data.toString();
	});
	child.on('exit', function (code, signal) {
		if (callback) {
			if (code) {
				// if we're on windows, the error message is actually in stdout, so scan for it
				if (process.platform === 'win32') {
					var foundError = false,
						err = [];

					stdout.split('\n').forEach(function (line) {
						if (/^Error\:/.test(line)) {
							foundError = true;
						}
						if (foundError) {
							line && err.push(line.trim());
						}
					});

					if (err.length) {
						stderr = err.join('\n') + stderr;
					}
				}
				callback(null);
			} else {
				callback(null);
			}
		}
	});
}

function packagingSDKLinux(finish){
	console.log('Packaging Titanium Mobile');
	var packer = require('child_process');
	var child = packer.spawn(
		'zip',
		['-r', resultPath, '*'],
		{
			cwd: workingDir
		});
	var stderr = '';

	child.stderr.on('data', function (data) {
		stderr += data;
	});

	child.on('exit', function (code, signal) {
		console.log(stderr);
		finish(null);
	});
}
<|endoftext|>


<commit_before>var progressBar = require("../progress-bar");
var updated     = require("./updated");
var readline    = require("readline-sync");
var semver      = require("semver");
var chalk       = require("chalk");
var child       = require("child_process");
var async       = require("async");
var fs          = require("fs");

var checkUpdatedPackages = updated.checkUpdatedPackages;

exports.description = "Publish updated packages to npm";

exports.execute = function (config) {
  var changedPackages = [];
  var changedFiles = [config.versionLoc];

  var FORCE_VERSION = process.env.FORCE_VERSION;
  FORCE_VERSION = FORCE_VERSION ? FORCE_VERSION.split(",") : [];

  var NEW_VERSION = getVersion();
  fs.writeFileSync(config.versionLoc, NEW_VERSION, "utf8");

  //

  try {
    changedPackages = checkUpdatedPackages(config);
    console.log("Packages to be updated");
    console.log(changedPackages.map(function(pkg) {
      return "- " + pkg;
    }).join("\n"));
    updateChangedPackages();
    updateTag();
    publish();
  } catch (err) {
    onError(err);
  }

  //

  var createdTag = false;

  function updateTag() {
    var NEW_TAG_NAME = "v" + NEW_VERSION;
    execSync("git commit -m " + NEW_TAG_NAME);
    execSync("git tag " + NEW_TAG_NAME);
    createdTag = true;
  }

  function removeTag() {
    if (createdTag) {
      console.error(chalk.red("Attempting to roll back tag creation."));
      execSync("git tag -d v" + NEW_VERSION);
    }
  }

  function getVersion() {
    var input = readline.question("New version (Leave blank for patch version): ");

    var ver = semver.valid(input);
    if (!ver) {
      ver = semver.inc(config.currentVersion, input || "patch");
    }

    if (ver) {
      return ver;
    } else {
      console.log("Version provided is not valid semver.");
      return getVersion();
    }
  }

  function execSync(cmd) {
    return child.execSync(cmd, {
      encoding: "utf8"
    }).trim();
  }

  function getPackageLocation(name) {
    return config.packagesLoc + "/" + name;
  }

  function updateDepsObject(deps) {
    for (var depName in deps) {
      // ensure this was generated and we're on the same major
      if (deps[depName][0] !== "^" || deps[depName][1] !== NEW_VERSION[0]) continue;

      if (changedPackages.indexOf(depName) >= 0) {
        deps[depName] = "^" + NEW_VERSION;
      }
    }
  }

  function updateChangedPackages() {
    changedPackages.forEach(function (name) {
      var pkgLoc = getPackageLocation(name) + "/package.json";
      var pkg = require(pkgLoc);

      // set new version
      pkg.version = NEW_VERSION;

      // updated dependencies
      updateDepsObject(pkg.dependencies);
      updateDepsObject(pkg.devDependencies);

      // write new package
      fs.writeFileSync(pkgLoc, JSON.stringify(pkg, null, "  ") + "\n");

      // push to be git committed
      changedFiles.push(pkgLoc);
    });

    changedFiles.forEach(function (loc) {
      execSync("git add " + loc);
    });
  }

  function publish() {
    changedPackages.forEach(function (name) {
      // prepublish script
      var prePub = getPackageLocation(name) + "/scripts/prepublish.js";
      if (fs.existsSync(prePub)) require(prePub);
    });

    console.log("Publishing tagged packages...");
    var tick = progressBar(changedPackages.length);

    async.parallelLimit(changedPackages.map(function (name) {
      var retries = 0;

      return function run(done) {
        var loc = getPackageLocation(name);

        child.exec("cd " + loc + " && npm publish --tag prerelease", function (err, stdout, stderr) {
          if (err || stderr) {
            err = stderr || err.stack;
            if (err.indexOf("You cannot publish over the previously published version") < 0) {
              if (++retries < 5) {
                console.log(chalk.yellow("Attempting to retry publishing " + name + "..."));
                return run(done);
              } else {
                console.log(chalk.red("Ran out of retries while publishing " + name));
                return done(err);
              }
            } else {
              // publishing over an existing package which is likely due to a timeout or something
              return done();
            }
          }

          tick(name);

          // postpublish script
          var postPub = loc + "/scripts/postpublish.js";
          if (fs.existsSync(postPub)) require(postPub);

          done();
        });
      };
    }), 4, function (err) {
      onError(err);
      ship();
    });
  }

  function onError(err) {
    if (!err) return;

    console.log();
    console.error(chalk.red("There was a problem publishing."));
    removeTag();
    console.error(err.stack || err);
    process.exit(1);
  }

  function ship() {
    console.log("Setting latest npm tags...");
    var tick = progressBar(changedPackages.length);

    async.parallelLimit(changedPackages.map(function (name) {
      return function (done) {
        while (true) {
          try {
            execSync("npm dist-tag rm " + name + " prerelease");
            if (process.env.NPM_DIST_TAG) {
              execSync("npm dist-tag add " + name + "@" + NEW_VERSION + " " + process.env.NPM_DIST_TAG);
            } else {
              execSync("npm dist-tag add " + name + "@" + NEW_VERSION + " stable");
              execSync("npm dist-tag add " + name + "@" + NEW_VERSION + " latest");
            }
            tick(name);
            break;
          } catch (err) {
            console.error(err.stack);
          }
        }
        done();
      };
    }), 4, function (err) {
      onError(err);
      execSync("git push");
      execSync("git push --tags");
      console.log();
      console.log(chalk.green("Successfully published " + NEW_VERSION + "."));
      process.exit();
    });
  }
};
<commit_msg>Cleanup publish script<commit_after>var progressBar = require("../progress-bar");
var updated     = require("./updated");
var readline    = require("readline-sync");
var semver      = require("semver");
var chalk       = require("chalk");
var child       = require("child_process");
var async       = require("async");
var fs          = require("fs");

var checkUpdatedPackages = updated.checkUpdatedPackages;

exports.description = "Publish updated packages to npm";

function execSync(cmd) {
  return child.execSync(cmd, {
    encoding: "utf8"
  }).trim();
}

function getPackageLocation(packagesLoc, name) {
  return packagesLoc + "/" + name;
}

function gitAddTag(version) {
  var NEW_TAG_NAME = "v" + version;
  execSync("git commit -m " + NEW_TAG_NAME);
  execSync("git tag " + NEW_TAG_NAME);
}

function gitRemoveTag(version) {
  console.error(chalk.red("Attempting to roll back tag creation."));
  execSync("git tag -d v" + version);
}

function userGetVersion(currentVersion) {
  var input = readline.question("New version (Leave blank for patch version): ");

  var ver = semver.valid(input);

  if (!ver) {
    ver = semver.inc(currentVersion, input || "patch");
  }

  if (ver) {
    return ver;
  } else {
    console.log("Version provided is not valid semver.");
    return userGetVersion(currentVersion);
  }
}

function writeFile(loc, contents) {
  fs.writeFileSync(loc, contents, "utf8");
}

function gitAddFile(file) {
  execSync("git add " + file);
}

function gitAddFiles(files) {
  files.forEach(gitAddFile);
}

function updateDepsObject(deps, changedPackages, version) {
  for (var depName in deps) {
    // ensure this was generated and we're on the same major
    if (deps[depName][0] !== "^" || deps[depName][1] !== version[0]) continue;

    if (changedPackages.indexOf(depName) >= 0) {
      deps[depName] = "^" + version;
    }
  }
}

function updateChangedPackages(changedPackages, packagesLoc, version) {
  var changedFiles = [];

  changedPackages.forEach(function (name) {
    var pkgLoc = getPackageLocation(packagesLoc, name) + "/package.json";
    var pkg = require(pkgLoc);

    // set new version
    pkg.version = version;

    // updated dependencies
    updateDepsObject(pkg.dependencies, changedPackages, version);
    updateDepsObject(pkg.devDependencies, changedPackages, version);

    // write new package
    fs.writeFileSync(pkgLoc, JSON.stringify(pkg, null, "  ") + "\n");

    // push to be git committed
    changedFiles.push(pkgLoc);
  });

  gitAddFiles(changedFiles);
}

function execPrepublish(packagesLoc, package) {
  // prepublish script
  var prePub = getPackageLocation(packagesLoc, package) + "/scripts/prepublish.js";

  // Execute prepublish script if it exists
  if (fs.existsSync(prePub)) {
    require(prePub);
  }
}

function execPostPublish(packagesLoc, package) {
  // postpublish script
  var prePub = getPackageLocation(packagesLoc, package) + "/scripts/postpublish.js";

  // Execute postpublish script if it exists
  if (fs.existsSync(prePub)) {
    require(prePub);
  }
}

function npmPublishAsPrerelease(changedPackages, packagesLoc, callback) {
  changedPackages.forEach(function (package) {
    execPrepublish(packagesLoc, package);
  });

  console.log("Publishing tagged packages...");

  var tick = progressBar(changedPackages.length);

  async.parallelLimit(changedPackages.map(function (package) {
    var retries = 0;

    return function run(done) {
      var loc = getPackageLocation(packagesLoc, package);

      child.exec("cd " + loc + " && npm publish --tag prerelease", function (err, stdout, stderr) {
        if (err || stderr) {
          err = stderr || err.stack;
          if (err.indexOf("You cannot publish over the previously published version") < 0) {
            if (++retries < 5) {
              console.log(chalk.yellow("Attempting to retry publishing " + package + "..."));
              return run(done);
            } else {
              console.log(chalk.red("Ran out of retries while publishing " + package));
              return done(err);
            }
          } else {
            // publishing over an existing package which is likely due to a timeout or something
            return done();
          }
        }

        tick(package);
        execPostPublish(packagesLoc, package);
        done();
      });
    };
  }), 4, callback);
}

function npmSetLatest(changedPackages, version, callback) {
  console.log("Setting latest npm tags...");

  var tick = progressBar(changedPackages.length);

  async.parallelLimit(changedPackages.map(function (package) {
    return function (done) {
      while (true) {
        try {
          execSync("npm dist-tag rm " + package + " prerelease");
          if (process.env.NPM_DIST_TAG) {
            execSync("npm dist-tag add " + package + "@" + version + " " + process.env.NPM_DIST_TAG);
          } else {
            execSync("npm dist-tag add " + package + "@" + version + " stable");
            execSync("npm dist-tag add " + package + "@" + version + " latest");
          }
          tick(package);
          break;
        } catch (err) {
          console.error(err.stack);
        }
      }
      done();
    };
  }), 4, callback);
}

exports.execute = function (config) {
  var changedPackages = [];
  var createdTag = false;

  var NEW_VERSION = userGetVersion(config.currentVersion);

  writeFile(config.versionLoc, NEW_VERSION, "utf8");
  gitAddFile(config.versionLoc);

  console.log(NEW_VERSION);

  try {
    // Find all changed packages to publish
    changedPackages = checkUpdatedPackages(config);

    // Log them to the console
    console.log("Packages to be updated");
    console.log(changedPackages.map(function (pkg) {
      return "- " + pkg;
    }).join("\n"));

    //
    updateChangedPackages(changedPackages, config.packagesLoc, NEW_VERSION);

    //
    gitAddTag(NEW_VERSION);
    createdTag = true;

    npmPublishAsPrerelease(changedPackages, config.packagesLoc, function (err) {
      if (err) return onError(err);

      npmSetLatest(changedPackages, NEW_VERSION, function (err) {
        if (err) return onError(err);
        execSync("git push");
        execSync("git push --tags");
        console.log();
        console.log(chalk.green("Successfully published " + NEW_VERSION + "."));
        process.exit();
      });
    });
  } catch (err) {
    onError(err);
  }

  function onError(err) {
    if (!err) return;

    console.log();
    console.error(chalk.red("There was a problem publishing."));
    if (createdTag) {
      gitRemoveTag();
    }
    console.error(err.stack || err);
    process.exit(1);
  }
};
<|endoftext|>


<commit_before>'use strict';

var client = require('ari-client');
var Maze = require('./maze');
var Participant = require('./participant');
var Pregame = require('./pregame');
var WebSocket = require('./ws');

var Game = function(ari) {
	this.ari = ari;
	this.participants = [];
	this.participant_id = 1;
	this.hiders = 0;
	this.seekers = 0;
	this.state = new Pregame(this);
	this.maze = new Maze(ari);

	this.webSocketServer = new WebSocket();

	this.add_participant = function(channel, role) {
		var participant = new Participant(channel, role, this.participant_id++);
		if (role == 'seeker') {
			this.seekers++;
		} else if (role == 'hider') {
			this.hiders++;
		}
		this.participants.push(participant);
		this.webSocketServer.notify_observers(JSON.stringify({ type: 'join_game', channel: channel.id, id: participant.id, role: participant.role }));

		return participant;
	}

	this.joinRoom = function(room, participant) {
		if (participant.room) {
			console.log('Channel %s leaving room %d(bridge %s)', participant.channel.id, participant.room.id, participant.room.bridge.id);
			var i = participant.room.occupants.indexOf(participant);
			participant.room.occupants.splice(i, 1);
			if (participant.role == 'seeker') {
				participant.room.bridge.play({media: 'sound:confbridge-leave'});
			}
			this.webSocketServer.notify_observers(JSON.stringify({ type: 'leave_room', room: participant.room.id, channel: participant.channel.id, id: participant.id, role: participant.role }));
		}
		participant.room = room;
		if (room) {
			console.log('Channel %s entering room %d(bridge %s) as %s', participant.channel.id, room.id, room.bridge.id, participant.role);
			room.occupants.push(participant);
			// addChannel will move the channel as appropriate, we don't need to explicitly remove
			if (participant.role == 'seeker') {
				room.bridge.play({media: 'sound:confbridge-join'});
			}
			room.bridge.addChannel({channel: participant.channel.id});
			participant.play_sound(ari, 'number:' + room.id);
			this.webSocketServer.notify_observers(JSON.stringify({ type: 'join_room', room: participant.room.id, channel: participant.channel.id, id: participant.id, role: participant.role }));
		}
	}
};

client.connect('http://127.0.0.1:8088', 'asterisk', 'asterisk', function(err, ari) {
	var game;

	function onDtmfReceived(event, channel) {
		var participant = game.participants.filter(function(item) {
			return item.channel.id === channel.id;
		})[0];
		game.state.onDtmfReceived(event, participant);
	}

	function onStasisStart(event, channel) {
		game.state.onStasisStart(event, channel);
		channel.on('ChannelDtmfReceived', onDtmfReceived);
	}

	function onStasisEnd(event, channel) {
		console.log('Channel %s leaving hide and seek', channel.id);
                var participant = game.participants.filter(function(item) {
                        return item.channel.id === channel.id;
                })[0];
		// Drop the respective count
		if (participant.role == 'seeker') {
			game.seekers--;
		} else if (participant.role == 'hider') {
			game.hiders--;
		}
		console.log('Seeker count is now %d and hider count is now %d', game.seekers, game.hiders);
		// It's safe to call joinRoom with a null room, it'll just end up removing it from the one it is in
		game.joinRoom(null, participant);
		game.webSocketServer.notify_observers(JSON.stringify({ type: 'leave_game', channel: channel.id, id: participant.id, role: participant.role }));
		// Since the channel is going away remove it as a valid participant
		var i = game.participants.indexOf(participant);
		game.participants.splice(i, 1);

		if (game.hiders == 0 || game.seekers == 0) {
			console.log('The game has no hiders or seekers left in it, considering it ended');
			game.webSocketServer.notify_observers(JSON.stringify({ type: 'game_ended' }));
			game.maze.play_sound_all('sound:beep');
		}
	}

	game = new Game(ari);
	ari.on('StasisStart', onStasisStart);
	ari.on('StasisEnd', onStasisEnd);
	ari.start('hide-n-seek');
})
.catch(function (err) {
	console.log(err);
});
<commit_msg>client.js: use environment variables for the Asterisk HOST and PORT<commit_after>'use strict';

var client = require('ari-client');
var Maze = require('./maze');
var Participant = require('./participant');
var Pregame = require('./pregame');
var WebSocket = require('./ws');

var host = process.env.HOST || 'http://127.0.0.1';
var port = process.env.PORT || '8088';

var Game = function(ari) {
	this.ari = ari;
	this.participants = [];
	this.participant_id = 1;
	this.hiders = 0;
	this.seekers = 0;
	this.state = new Pregame(this);
	this.maze = new Maze(ari);

	this.webSocketServer = new WebSocket();

	this.add_participant = function(channel, role) {
		var participant = new Participant(channel, role, this.participant_id++);
		if (role == 'seeker') {
			this.seekers++;
		} else if (role == 'hider') {
			this.hiders++;
		}
		this.participants.push(participant);
		this.webSocketServer.notify_observers(JSON.stringify({ type: 'join_game', channel: channel.id, id: participant.id, role: participant.role }));

		return participant;
	}

	this.joinRoom = function(room, participant) {
		if (participant.room) {
			console.log('Channel %s leaving room %d(bridge %s)', participant.channel.id, participant.room.id, participant.room.bridge.id);
			var i = participant.room.occupants.indexOf(participant);
			participant.room.occupants.splice(i, 1);
			if (participant.role == 'seeker') {
				participant.room.bridge.play({media: 'sound:confbridge-leave'});
			}
			this.webSocketServer.notify_observers(JSON.stringify({ type: 'leave_room', room: participant.room.id, channel: participant.channel.id, id: participant.id, role: participant.role }));
		}
		participant.room = room;
		if (room) {
			console.log('Channel %s entering room %d(bridge %s) as %s', participant.channel.id, room.id, room.bridge.id, participant.role);
			room.occupants.push(participant);
			// addChannel will move the channel as appropriate, we don't need to explicitly remove
			if (participant.role == 'seeker') {
				room.bridge.play({media: 'sound:confbridge-join'});
			}
			room.bridge.addChannel({channel: participant.channel.id});
			participant.play_sound(ari, 'number:' + room.id);
			this.webSocketServer.notify_observers(JSON.stringify({ type: 'join_room', room: participant.room.id, channel: participant.channel.id, id: participant.id, role: participant.role }));
		}
	}
};

console.log('connecting to Asterisk on ' + host + ':' + port);
client.connect(host + ':' + port, 'asterisk', 'asterisk')
.then(function(ari) {
	var game;

	function onDtmfReceived(event, channel) {
		var participant = game.participants.filter(function(item) {
			return item.channel.id === channel.id;
		})[0];
		game.state.onDtmfReceived(event, participant);
	}

	function onStasisStart(event, channel) {
		game.state.onStasisStart(event, channel);
		channel.on('ChannelDtmfReceived', onDtmfReceived);
	}

	function onStasisEnd(event, channel) {
		console.log('Channel %s leaving hide and seek', channel.id);
                var participant = game.participants.filter(function(item) {
                        return item.channel.id === channel.id;
                })[0];
		// Drop the respective count
		if (participant.role == 'seeker') {
			game.seekers--;
		} else if (participant.role == 'hider') {
			game.hiders--;
		}
		console.log('Seeker count is now %d and hider count is now %d', game.seekers, game.hiders);
		// It's safe to call joinRoom with a null room, it'll just end up removing it from the one it is in
		game.joinRoom(null, participant);
		game.webSocketServer.notify_observers(JSON.stringify({ type: 'leave_game', channel: channel.id, id: participant.id, role: participant.role }));
		// Since the channel is going away remove it as a valid participant
		var i = game.participants.indexOf(participant);
		game.participants.splice(i, 1);

		if (game.hiders == 0 || game.seekers == 0) {
			console.log('The game has no hiders or seekers left in it, considering it ended');
			game.webSocketServer.notify_observers(JSON.stringify({ type: 'game_ended' }));
			game.maze.play_sound_all('sound:beep');
		}
	}

	game = new Game(ari);
	ari.on('StasisStart', onStasisStart);
	ari.on('StasisEnd', onStasisEnd);
	ari.start('hide-n-seek');
})
.catch(function (err) {
	console.log(err); // TODO: don't know why this isn't called on invalid host/port
});
<|endoftext|>