<commit_before>const fs = require('fs');
const readline = require('readline');
const zlib = require('zlib');
const Elastic = require('./Elastic');
const AWS = require('aws-sdk');
const get = require('./api');
module.exports = class Aggregate {
    constructor(c, mongo, config) {
        this.c = c;
        this.mongo = mongo;
        this.config = config;
    }

    save(params, done) {

        let self = this;
        try {
            fs.accessSync('output.tmp');
            fs.unlinkSync('output.tmp');
        } catch (e) {
            //do nothing
        }

        self.c.a('Downloading ' + JSON.stringify(params));

        let download = () => new AWS.S3().getObject(params).createReadStream();
        let save = fs.createWriteStream(params.Key);
        let gunzip = zlib.createGunzip();
        download().pipe(gunzip).pipe(save);

        save.on('error', (err) => {
            console.log(err);
            self.c.a('Error Saving ' + params.Key, 3);
            done(new Error('Error Saving ' + params.Key));
        });

        save.on('close', () => {
            self.c.a('Saved ' + params.Key);
            self.lines(params.Key, (nolines) => {
                if (nolines < 10) {
                    self.c.a(params.Key + ' only has ' + nolines + ' lines to process, deleting item', 3, 'poller aggregate');
                    done();
                } else {
                    self.c.a(params.Key + ' has ' + nolines + ' lines to process');
                    self.read(params.Key, nolines, done);
                }
            });
        });
    }

    lines(file, cb) {
        let nolines = 0;
        let stream;
        let reader;

        reader = fs.createReadStream(file);
        stream = readline.createInterface({
            input: reader,
            terminal: false
        });

        stream.on('line', () => nolines++);
        stream.on('close', () => {
            cb(nolines);
        });

    }

    read(key, nolines, done) {
        let self = this;
        self.elastic = new Elastic(self);
        self.c.a('Processing started for ' + key + ' over ' + nolines + ' lines');
        self.key = key;
        //a barge is full of many containers
        let container = '';
        let lines = 0;
        let reader = fs.createReadStream(key);
        let stream = readline.createInterface({
            input: reader,
            terminal: false
        });

        //elastic setup

        let all = 0;
        let over = 0;
        let leftover = '';
        self.start = new Date().getTime();
        self.nolines = nolines;

        stream.on('line', async (line) => {

            let json = JSON.parse(line);

            if (json.action_name === 'action_name') { return; }
            line = null;
            let date = new Date(json.date);
            let dateString = '';
            dateString += date.getFullYear();
            dateString += '-';
            dateString += date.getMonth() + 1;
            dateString += '-';
            dateString += date.getDate();

            let type;
            let app;
            let obj = {};

            //bbc stuff
            if (json.name) obj.bbc_counter = json.name;
            if (json.cps_asset_id) obj.bbc_cps = json.cps_asset_id;

            if (json.app_type) obj.bbc_app = json.app_type;
            if (json.app_name) obj.bbc_name = json.app_name;
            if (json.app) obj.bbc_app_v = json.app;

            //general
            if (json.date) obj.date = json.date;
            if (json.ns_vid) obj.user = json.ns_vid;
            if (json.ns_jspageurl) { obj.url = json.ns_jspageurl; }

            //referral
            if (json.rp) {
                if (json.rp.type) obj.ref_type = json.rp.type;
                if (json.rp.name) obj.ref_name = json.rp.name;
                if (json.rp.page) obj.ref_page = json.rp.page;
                if (json.rp.host) obj.ref_host = json.rp.host;
                if (json.rp.search) obj.ref_term = json.rp.search;
            }
            if (json.postID) obj.ref_post = json.postID;
            if (json.edition) obj.edition = json.edition;

            //device
            if (json.ns_v_platform) obj.device_platform = json.ns_v_platform;
            if (json.ua) {
                if (json.ua.os && json.ua.os.family) obj.device_os = json.ua.os.family;
                if (json.ua.family) obj.device_browser = json.ua.family;
                if (json.ua.device && json.ua.device.family) obj.device_family = json.ua.device.family;
            }

            //location
            if (json.loc) {
                if (json.loc.cont) obj.loc_cont = json.loc.cont;
                if (json.loc.country) obj.loc_country = json.loc.country;
                if (json.loc.city) obj.loc_city = json.loc.city;
                if (json.loc.ll[0] && json.loc.ll[1]) obj.loc_ll = [json.loc.ll[1], json.loc.ll[0]];
            }

            let cpsMeta;
            try {
                cpsMeta = await get.cps(obj.bbc_cps, self.mongo);
                if (cpsMeta.section_uri) obj.bbc_section = cpsMeta.section_uri;
                if (cpsMeta.type) obj.bbc_page = cpsMeta.type;
                if (cpsMeta.site_name) obj.bbc_site = cpsMeta.site_name;
            } catch (e) {
                //self.c.a('error finding docuent', 2, '');
            }

            let bbc_hid;
            if (json.bbc_hid) {
                try {
                    bbc_hid = await get.demos(json.bbc_hid);
                    if (bbc_hid.age && bbc_hid.gender) {
                        obj.age = bbc_hid.age;
                        obj.gender = bbc_hid.gender;
                    }
                } catch (e) {

                }
            }

            //make sure app name is valid
            let n = json.app_name;
            if (n === 'afrique' ||
                n === 'arabic' ||
                n === 'azeri' ||
                n === 'bengali' ||
                n === 'burmese' ||
                n === 'gahuza' ||
                n === 'hausa' ||
                n === 'hindi' ||
                n === 'indonesia' ||
                n === 'kyrgyz' ||
                n === 'mundo' ||
                n === 'nepali' ||
                n === 'news' ||
                n === 'pashto' ||
                n === 'persian' ||
                n === 'portuguese' ||
                n === 'russian' ||
                n === 'sinhala' ||
                n === 'swahili' ||
                n === 'tamil' ||
                n === 'turkce' ||
                n === 'ukchina' ||
                n === 'ukrainian' ||
                n === 'urdu' ||
                n === 'uzbek' ||
                n === 'vietnamese' ||
                n === 'zhongwen_simp' ||
                n === 'zhongwen_trad' ||
                n === 'thai' ||
                n === 'amharic' ||
                n === 'tigrinya' ||
                n === 'afaanoromoo' ||
                n === 'pidgin'
                ) {
                app = n;
            } else {
                app = obj.bbc_counter.substring(0, obj.bbc_counter.indexOf('.'));
            }

            let meta;

            if (json.type === 'view') {
                if (obj.bbc_cps !== undefined) {
                    fs.appendFileSync('mongo.tmp', JSON.stringify(obj) + '\n');
                    if (self.config.output.elastic !== undefined && self.config.output.elastic.active === true) {
                        meta = JSON.stringify({ index: { '_index': 'comscore-' + dateString, '_type': 'view' } });
                        fs.appendFileSync('elastic.tmp', meta + '\n');
                        fs.appendFileSync('elastic.tmp', JSON.stringify(obj) + '\n');
                    }
                }

            } else if (json.ns_st_ci === undefined) {
                if (json.action_name) obj.action_name = json.action_name;
                if (json.action_type) obj.action_type = json.action_type;

                // if (self.config.output.elastic !== undefined && self.config.output.elastic.active === true) {
                //     meta = JSON.stringify({ "index": { "_index": "comscore-" + dateString, "_type": type } });
                //     fs.appendFileSync('elastic.tmp', meta + '\n');
                //     fs.appendFileSync('elastic.tmp', JSON.stringify(obj) + '\n');
                // }

            } else {
                //video
                if (json.ns_st_ci) obj.video_id = json.ns_st_ci;
                if (json.ns_st_cl) obj.video_length = parseInt(json.ns_st_cl);
                if (json.ns_st_ev) obj.video_event = json.ns_st_ev;
                if (json.ns_st_id) obj.video_playid = json.ns_st_id;
                if (json.ns_st_po) obj.video_position = parseInt(json.ns_st_po);
                if (json.ns_st_pt) obj.video_accumulated = parseInt(json.ns_st_pt);

                // if (self.config.output.elastic !== undefined && self.config.output.elastic.active === true) {
                //     meta = JSON.stringify({ "index": { "_index": "comscore-" + dateString, "_type": type } });
                //     fs.appendFileSync('elastic.tmp', meta + '\n');
                //     fs.appendFileSync('elastic.tmp', JSON.stringify(obj) + '\n');
                // }
            }

            obj.file = key;

            lines++;
            all++;

            //containers reach their maximum line size and then added to the barge.
            //a new conainer is then used for the next one.

            if (lines % 10000 === 0) {
                self.c.a('Processing ' + lines + '/' + nolines, 1, key);
            }

            if (lines === nolines - 1) {
                self.c.a('Finsied Processing ' + lines + '/' + nolines, 1, key);
                // self.distribute(done);
            }

            obj = null;
            json = null;
            container = null;
        });

        stream.on('error', (err) => {
            self.c.a('Error reading ' + key, 3);
        });
    }

    cleanup(done) {
        let self = this;
        let end = new Date().getTime();
        let total = end - self.start;
        self.c.a('Finished Docking', 1, self.key);
        fs.unlinkSync(self.key);
        fs.unlinkSync('mongo.tmp');

        if (self.config.output.elastic !== undefined && self.config.output.elastic.active === true) {
            fs.unlinkSync('elastic.tmp');
        }

        if (self.config.output.mongo !== undefined && self.config.output.mongo.active === true) {
            self.mongo.create();
        }
        //restart polling
        done();
    }

    distribute(done) {
        let self = this;

        // this is shitty i know - i'l changed this to a promise all at some point.
        if (self.config.output.mongo !== undefined && self.config.output.mongo.active === true) {
            self.mongo.ship(() => {
                self.c.a('Mongo Finsihed', 1, self.key);
                if (self.config.output.elastic !== undefined && self.config.output.elastic.active === true) {
                    self.elastic.shipES(self.key, (err) => {
                        if (err) throw err;
                        self.cleanup(done);
                    });
                } else {
                    self.cleanup(done);
                }
            });
        } else if (self.config.output.elastic !== undefined && self.config.output.elastic.active === true) {
            self.elastic.shipES(self.key, (err) => {
                if (err) throw err;
                self.cleanup(done);
            });
        } else {
            self.cleanup(done);
        }
    }
};<commit_msg>distribute biaaaaatch<commit_after>const fs = require('fs');
const readline = require('readline');
const zlib = require('zlib');
const Elastic = require('./Elastic');
const AWS = require('aws-sdk');
const get = require('./api');
module.exports = class Aggregate {
    constructor(c, mongo, config) {
        this.c = c;
        this.mongo = mongo;
        this.config = config;
    }

    save(params, done) {

        let self = this;
        try {
            fs.accessSync('output.tmp');
            fs.unlinkSync('output.tmp');
        } catch (e) {
            //do nothing
        }

        self.c.a('Downloading ' + JSON.stringify(params));

        let download = () => new AWS.S3().getObject(params).createReadStream();
        let save = fs.createWriteStream(params.Key);
        let gunzip = zlib.createGunzip();
        download().pipe(gunzip).pipe(save);

        save.on('error', (err) => {
            console.log(err);
            self.c.a('Error Saving ' + params.Key, 3);
            done(new Error('Error Saving ' + params.Key));
        });

        save.on('close', () => {
            self.c.a('Saved ' + params.Key);
            self.lines(params.Key, (nolines) => {
                if (nolines < 10) {
                    self.c.a(params.Key + ' only has ' + nolines + ' lines to process, deleting item', 3, 'poller aggregate');
                    done();
                } else {
                    self.c.a(params.Key + ' has ' + nolines + ' lines to process');
                    self.read(params.Key, nolines, done);
                }
            });
        });
    }

    lines(file, cb) {
        let nolines = 0;
        let stream;
        let reader;

        reader = fs.createReadStream(file);
        stream = readline.createInterface({
            input: reader,
            terminal: false
        });

        stream.on('line', () => nolines++);
        stream.on('close', () => {
            cb(nolines);
        });

    }

    read(key, nolines, done) {
        let self = this;
        self.elastic = new Elastic(self);
        self.c.a('Processing started for ' + key + ' over ' + nolines + ' lines');
        self.key = key;
        //a barge is full of many containers
        let container = '';
        let lines = 0;
        let reader = fs.createReadStream(key);
        let stream = readline.createInterface({
            input: reader,
            terminal: false
        });

        //elastic setup

        let all = 0;
        let over = 0;
        let leftover = '';
        self.start = new Date().getTime();
        self.nolines = nolines;

        stream.on('line', async (line) => {

            let json = JSON.parse(line);

            if (json.action_name === 'action_name') { return; }
            line = null;
            let date = new Date(json.date);
            let dateString = '';
            dateString += date.getFullYear();
            dateString += '-';
            dateString += date.getMonth() + 1;
            dateString += '-';
            dateString += date.getDate();

            let type;
            let app;
            let obj = {};

            //bbc stuff
            if (json.name) obj.bbc_counter = json.name;
            if (json.cps_asset_id) obj.bbc_cps = json.cps_asset_id;

            if (json.app_type) obj.bbc_app = json.app_type;
            if (json.app_name) obj.bbc_name = json.app_name;
            if (json.app) obj.bbc_app_v = json.app;

            //general
            if (json.date) obj.date = json.date;
            if (json.ns_vid) obj.user = json.ns_vid;
            if (json.ns_jspageurl) { obj.url = json.ns_jspageurl; }

            //referral
            if (json.rp) {
                if (json.rp.type) obj.ref_type = json.rp.type;
                if (json.rp.name) obj.ref_name = json.rp.name;
                if (json.rp.page) obj.ref_page = json.rp.page;
                if (json.rp.host) obj.ref_host = json.rp.host;
                if (json.rp.search) obj.ref_term = json.rp.search;
            }
            if (json.postID) obj.ref_post = json.postID;
            if (json.edition) obj.edition = json.edition;

            //device
            if (json.ns_v_platform) obj.device_platform = json.ns_v_platform;
            if (json.ua) {
                if (json.ua.os && json.ua.os.family) obj.device_os = json.ua.os.family;
                if (json.ua.family) obj.device_browser = json.ua.family;
                if (json.ua.device && json.ua.device.family) obj.device_family = json.ua.device.family;
            }

            //location
            if (json.loc) {
                if (json.loc.cont) obj.loc_cont = json.loc.cont;
                if (json.loc.country) obj.loc_country = json.loc.country;
                if (json.loc.city) obj.loc_city = json.loc.city;
                if (json.loc.ll[0] && json.loc.ll[1]) obj.loc_ll = [json.loc.ll[1], json.loc.ll[0]];
            }

            let cpsMeta;
            try {
                cpsMeta = await get.cps(obj.bbc_cps, self.mongo);
                if (cpsMeta.section_uri) obj.bbc_section = cpsMeta.section_uri;
                if (cpsMeta.type) obj.bbc_page = cpsMeta.type;
                if (cpsMeta.site_name) obj.bbc_site = cpsMeta.site_name;
            } catch (e) {
                //self.c.a('error finding docuent', 2, '');
            }

            let bbc_hid;
            if (json.bbc_hid) {
                try {
                    bbc_hid = await get.demos(json.bbc_hid);
                    if (bbc_hid.age && bbc_hid.gender) {
                        obj.age = bbc_hid.age;
                        obj.gender = bbc_hid.gender;
                    }
                } catch (e) {

                }
            }

            //make sure app name is valid
            let n = json.app_name;
            if (n === 'afrique' ||
                n === 'arabic' ||
                n === 'azeri' ||
                n === 'bengali' ||
                n === 'burmese' ||
                n === 'gahuza' ||
                n === 'hausa' ||
                n === 'hindi' ||
                n === 'indonesia' ||
                n === 'kyrgyz' ||
                n === 'mundo' ||
                n === 'nepali' ||
                n === 'news' ||
                n === 'pashto' ||
                n === 'persian' ||
                n === 'portuguese' ||
                n === 'russian' ||
                n === 'sinhala' ||
                n === 'swahili' ||
                n === 'tamil' ||
                n === 'turkce' ||
                n === 'ukchina' ||
                n === 'ukrainian' ||
                n === 'urdu' ||
                n === 'uzbek' ||
                n === 'vietnamese' ||
                n === 'zhongwen_simp' ||
                n === 'zhongwen_trad' ||
                n === 'thai' ||
                n === 'amharic' ||
                n === 'tigrinya' ||
                n === 'afaanoromoo' ||
                n === 'pidgin'
                ) {
                app = n;
            } else {
                app = obj.bbc_counter.substring(0, obj.bbc_counter.indexOf('.'));
            }

            let meta;

            if (json.type === 'view') {
                if (obj.bbc_cps !== undefined) {
                    fs.appendFileSync('mongo.tmp', JSON.stringify(obj) + '\n');
                    if (self.config.output.elastic !== undefined && self.config.output.elastic.active === true) {
                        meta = JSON.stringify({ index: { '_index': 'comscore-' + dateString, '_type': 'view' } });
                        fs.appendFileSync('elastic.tmp', meta + '\n');
                        fs.appendFileSync('elastic.tmp', JSON.stringify(obj) + '\n');
                    }
                }

            } else if (json.ns_st_ci === undefined) {
                if (json.action_name) obj.action_name = json.action_name;
                if (json.action_type) obj.action_type = json.action_type;

                // if (self.config.output.elastic !== undefined && self.config.output.elastic.active === true) {
                //     meta = JSON.stringify({ "index": { "_index": "comscore-" + dateString, "_type": type } });
                //     fs.appendFileSync('elastic.tmp', meta + '\n');
                //     fs.appendFileSync('elastic.tmp', JSON.stringify(obj) + '\n');
                // }

            } else {
                //video
                if (json.ns_st_ci) obj.video_id = json.ns_st_ci;
                if (json.ns_st_cl) obj.video_length = parseInt(json.ns_st_cl);
                if (json.ns_st_ev) obj.video_event = json.ns_st_ev;
                if (json.ns_st_id) obj.video_playid = json.ns_st_id;
                if (json.ns_st_po) obj.video_position = parseInt(json.ns_st_po);
                if (json.ns_st_pt) obj.video_accumulated = parseInt(json.ns_st_pt);

                // if (self.config.output.elastic !== undefined && self.config.output.elastic.active === true) {
                //     meta = JSON.stringify({ "index": { "_index": "comscore-" + dateString, "_type": type } });
                //     fs.appendFileSync('elastic.tmp', meta + '\n');
                //     fs.appendFileSync('elastic.tmp', JSON.stringify(obj) + '\n');
                // }
            }

            obj.file = key;

            lines++;
            all++;

            //containers reach their maximum line size and then added to the barge.
            //a new conainer is then used for the next one.

            if (lines % 10000 === 0) {
                self.c.a('Processing ' + lines + '/' + nolines, 1, key);
            }

            if (lines === nolines - 1) {
                self.c.a('Finsied Processing ' + lines + '/' + nolines, 1, key);
                self.distribute(done);
            }

            obj = null;
            json = null;
            container = null;
        });

        stream.on('error', (err) => {
            self.c.a('Error reading ' + key, 3);
        });
    }

    cleanup(done) {
        let self = this;
        let end = new Date().getTime();
        let total = end - self.start;
        self.c.a('Finished Docking', 1, self.key);
        fs.unlinkSync(self.key);
        fs.unlinkSync('mongo.tmp');

        if (self.config.output.elastic !== undefined && self.config.output.elastic.active === true) {
            fs.unlinkSync('elastic.tmp');
        }

        if (self.config.output.mongo !== undefined && self.config.output.mongo.active === true) {
            self.mongo.create();
        }
        //restart polling
        done();
    }

    distribute(done) {
        let self = this;

        // this is shitty i know - i'l changed this to a promise all at some point.
        if (self.config.output.mongo !== undefined && self.config.output.mongo.active === true) {
            self.mongo.ship(() => {
                self.c.a('Mongo Finsihed', 1, self.key);
                if (self.config.output.elastic !== undefined && self.config.output.elastic.active === true) {
                    self.elastic.shipES(self.key, (err) => {
                        if (err) throw err;
                        self.cleanup(done);
                    });
                } else {
                    self.cleanup(done);
                }
            });
        } else if (self.config.output.elastic !== undefined && self.config.output.elastic.active === true) {
            self.elastic.shipES(self.key, (err) => {
                if (err) throw err;
                self.cleanup(done);
            });
        } else {
            self.cleanup(done);
        }
    }
};<|endoftext|>


<commit_before>var path = require('path');

(module.exports = function(flow){
  var content = [];
  var nodeCount = flow.files.queue.length;
  var edgeCount = 0;

  // build graph file content
  flow.files.queue.forEach(function(file){
    edgeCount += file.linkTo.length;

    if (!name(file))
      return;

    content.push({
      type: file.type,
      name: name(file)
    });
  });

  // add archive as single result file

  var content = [
    '"files":' + JSON.stringify(content),
    '"links":' + JSON.stringify(
      flow.files.links.map(function(link){
        var fn1 = name(link[0], true);
        var fn2 = name(link[1]);
        return fn1 && fn2 ? [fn1, fn2] : null;
      }).filter(Boolean)
    ),
    '"warns":' + JSON.stringify(flow.warns.map(function(warn){
      warn.message = String(warn.message);
      if (warn.file)
        warn.file = flow.files.resolve(warn.file);
      return warn;
    }))
  ];

  if (flow.l10n)
    content.push(
      '"l10n":' + JSON.stringify(flow.l10n.version == 2
        ? getL10nDictionaries(flow)
        : getL10nLocations(flow))
    );

  flow.result = '{\n' + content.join(',\n') + '\n' + '}';
}).handlerName = 'Make file map';

function resolveLinkTo(link){
  var n = name(link[0]);
  if (n)
    return [n];
  else
    return link[0].linkTo.map(resolveLinkTo).reduce(function(item, res){
      if (item)
        return res.concat(item);
      else
        return res;
    }, []);
}

function name(file, implicit){
  if (file.filename)
    file.graphName = file.relpath;

  if (file.sourceFilename)
    file.graphName = file.sourceFilename;

  if (!file.graphName && implicit && file.inline && file.htmlFile)
    return file.htmlFile.relpath;

  return file.graphName;
}

function getL10nLocations(flow){
  var result = {};
  for (var dictionaryName in flow.l10n.dictionaries)
  {
    var tokens = {};
    for (var token in flow.l10n.dictionaries[dictionaryName].tokens)
      tokens[token] = {
        base: flow.l10n.dictionaries[dictionaryName].tokens[token]
      };

    for (var culture in flow.l10n.cultureDictionaries)
    {
      for (var token in flow.l10n.cultureDictionaries[culture][dictionaryName])
      {
        if (!tokens[token])
          tokens[token] = {};

        tokens[token][culture] = flow.l10n.cultureDictionaries[culture][dictionaryName][token];
      }
    }

    result[dictionaryName] = {
      path: '/' + path.relative(flow.options.base, flow.l10n.dictionaries[dictionaryName].path).replace(/\\/g, '/'),
      tokens: tokens
    };
  }
  return result;
}

function getL10nDictionaries(flow){
  var result = {};

  for (var filename in flow.l10n.dictionaries)
  {
    var dict = flow.l10n.dictionaries[filename];
    var file = dict.file;

    var data = {};

    for (var key in dict.tokens)
    {
      var token = dict.tokens[key];
      var refs = [];

      for (var i = 0, ref; ref = token.ref[i]; i++)
        if (refs.indexOf(ref.file.relpath) == -1)
          refs.push(ref.file.relpath);

      data[key] = {
        type: token.type,
        implicit: token.implicit,
        files: refs
      };
    }

    result[file.relpath] = data;
  }

  return result;
}
<commit_msg>extract: return paths relative to base, remove old basis l10n support<commit_after>var path = require('path');

(module.exports = function(flow){
  var content = [];
  var nodeCount = flow.files.queue.length;
  var edgeCount = 0;

  // build graph file content
  flow.files.queue.forEach(function(file){
    edgeCount += file.linkTo.length;

    if (!name(file))
      return;

    content.push({
      type: file.type,
      name: name(file)
    });
  });

  // add archive as single result file

  var content = [
    '"files":' + JSON.stringify(content),
    '"links":' + JSON.stringify(
      flow.files.links.map(function(link){
        var fn1 = name(link[0], true);
        var fn2 = name(link[1]);
        return fn1 && fn2 ? [fn1, fn2] : null;
      }).filter(Boolean)
    ),
    '"warns":' + JSON.stringify(flow.warns.map(function(warn){
      warn.message = String(warn.message);
      if (warn.file)
        warn.file = flow.files.resolve(warn.file);
      return warn;
    }))
  ];

  if (flow.l10n && flow.l10n.version == 2)
    content.push('"l10n":' + JSON.stringify(getL10nDictionaries(flow)));

  flow.result = '{\n' + content.join(',\n') + '\n' + '}';
}).handlerName = 'Make file map';

function resolveLinkTo(link){
  var n = name(link[0]);
  if (n)
    return [n];
  else
    return link[0].linkTo.map(resolveLinkTo).reduce(function(item, res){
      if (item)
        return res.concat(item);
      else
        return res;
    }, []);
}

function name(file, implicit){
  function rel(name){
    return name ? String(name).replace(/^\//, '') : name;
  }

  if (file.filename)
    file.graphName = file.filename;

  if (file.sourceFilename)
    file.graphName = file.sourceFilename;

  if (!file.graphName && implicit && file.inline && file.htmlFile)
    return rel(file.htmlFile.filename);

  return rel(file.graphName);
}

function getL10nDictionaries(flow){
  var result = {};

  for (var filename in flow.l10n.dictionaries)
  {
    var dict = flow.l10n.dictionaries[filename];
    var file = dict.file;

    var data = {};

    for (var key in dict.tokens)
    {
      var token = dict.tokens[key];
      var refs = [];

      for (var i = 0, ref; ref = token.ref[i]; i++)
      {
        var filename = name(ref.file);
        if (refs.indexOf(filename) == -1)
          refs.push(filename);
      }

      data[key] = {
        type: token.type,
        implicit: token.implicit,
        files: refs
      };
    }

    result[name(file)] = data;
  }

  return result;
}
<|endoftext|>


<commit_before>'use strict';

var assert = require('assert');
require('../fixture/sandbox.js');

describe('DB', function() {
  it('should throw error when mechanism is not specified', function() {
    assert.throws(function() {
      new lfr.Db();
    }, Error);

    assert.doesNotThrow(function() {
      var FakeMechanism = createFakeMechanism();

      new lfr.Db(new FakeMechanism(''));
    });
  });

  it('should handle adding data to the database', function(done) {
    var FakeMechanism = createFakeMechanism();

    var db = new lfr.Db(new FakeMechanism('cloud.liferay.com/myApp/user'));

    // Add coverage for optional callback
    db.add({
      name: 'Johan',
      age: 25
    });

    db.add(null, function(err) {
      assert.strictEqual(true, err instanceof Error);
    });

    db.add({
      name: 'Johan',
      age: 25
    }, function(err, data) {
        assert.strictEqual(err, null, 'Should not return error');
        assert.ok(data, null, 'Should return some data');

        done();
      });
  });

  it('should handle querying data from the database', function(done) {
    var FakeMechanism = createFakeMechanism();

    var db = new lfr.Db(new FakeMechanism('cloud.liferay.com/myApp/user'));

    // Add coverage for optional callback
    db.find({
      name: 'Johan',
      age: 25
    });

    db.find(null, function(err) {
      assert.strictEqual(true, err instanceof Error);
    });

    db.find({
      name: 'Johan',
      age: 25
    }, function(err, data) {
        assert.strictEqual(err, null, 'Should not return error');
        assert.ok(data, null, 'Should return some data');

        done();
      });
  });

  it('should handle removing data from the database', function(done) {
    var FakeMechanism = createFakeMechanism();

    var db = new lfr.Db(new FakeMechanism('cloud.liferay.com/myApp/user'));

    // Add coverage for optional callback
    db.remove({
      name: 'Johan',
      age: 25
    });

    db.remove(null, function(err) {
      assert.strictEqual(true, err instanceof Error);
    });

    db.remove({
      name: 'Johan',
      age: 25
    }, function(err, data) {
        assert.strictEqual(err, null, 'Should not return error');
        assert.ok(data, null, 'Should return some data');

        done();
      });
  });

  it('should handle updating data into the database', function(done) {
    var FakeMechanism = createFakeMechanism();

    var db = new lfr.Db(new FakeMechanism('cloud.liferay.com/myApp/user'));

    // Add coverage for optional callback
    db.update({
      name: 'Johan',
      age: 25
    });

    db.update(null, function(err) {
      assert.strictEqual(true, err instanceof Error);
    });

    db.update({
      name: 'Johan',
      age: 25
    }, function(err, data) {
        assert.strictEqual(err, null, 'Should not return error');
        assert.ok(data, null, 'Should return some data');

        done();
      });
  });

  function createFakeMechanism() {
    var FakeMechanism = function(uri) {
      this.uri_ = uri;
    };

    var mechanismImpl = function(data, callback) {
      setTimeout(function() {
        if (data) {
          callback(null, 'Success');
        } else {
          callback(new Error('There is no data provided'), 'Failure');
        }
      }, 10);
    };

    FakeMechanism.prototype.add = mechanismImpl;
    FakeMechanism.prototype.find = mechanismImpl;
    FakeMechanism.prototype.remove = mechanismImpl;
    FakeMechanism.prototype.update = mechanismImpl;
    return FakeMechanism;
  }

});
<commit_msg>Source formatting<commit_after>'use strict';

var assert = require('assert');
require('../fixture/sandbox.js');

describe('Db', function() {
  it('should throw error when mechanism is not specified', function() {
    assert.throws(function() {
      new lfr.Db();
    }, Error);

    assert.doesNotThrow(function() {
      var FakeMechanism = createFakeMechanism();

      new lfr.Db(new FakeMechanism(''));
    });
  });

  it('should handle adding data to the database', function(done) {
    var FakeMechanism = createFakeMechanism();

    var db = new lfr.Db(new FakeMechanism('cloud.liferay.com/myApp/user'));

    // Add coverage for optional callback
    db.add({
      name: 'Johan',
      age: 25
    });

    db.add(null, function(err) {
      assert.strictEqual(true, err instanceof Error);
    });

    db.add({
      name: 'Johan',
      age: 25
    }, function(err, data) {
        assert.strictEqual(err, null, 'Should not return error');
        assert.ok(data, null, 'Should return some data');

        done();
      });
  });

  it('should handle querying data from the database', function(done) {
    var FakeMechanism = createFakeMechanism();

    var db = new lfr.Db(new FakeMechanism('cloud.liferay.com/myApp/user'));

    // Add coverage for optional callback
    db.find({
      name: 'Johan',
      age: 25
    });

    db.find(null, function(err) {
      assert.strictEqual(true, err instanceof Error);
    });

    db.find({
      name: 'Johan',
      age: 25
    }, function(err, data) {
        assert.strictEqual(err, null, 'Should not return error');
        assert.ok(data, null, 'Should return some data');

        done();
      });
  });

  it('should handle removing data from the database', function(done) {
    var FakeMechanism = createFakeMechanism();

    var db = new lfr.Db(new FakeMechanism('cloud.liferay.com/myApp/user'));

    // Add coverage for optional callback
    db.remove({
      name: 'Johan',
      age: 25
    });

    db.remove(null, function(err) {
      assert.strictEqual(true, err instanceof Error);
    });

    db.remove({
      name: 'Johan',
      age: 25
    }, function(err, data) {
        assert.strictEqual(err, null, 'Should not return error');
        assert.ok(data, null, 'Should return some data');

        done();
      });
  });

  it('should handle updating data into the database', function(done) {
    var FakeMechanism = createFakeMechanism();

    var db = new lfr.Db(new FakeMechanism('cloud.liferay.com/myApp/user'));

    // Add coverage for optional callback
    db.update({
      name: 'Johan',
      age: 25
    });

    db.update(null, function(err) {
      assert.strictEqual(true, err instanceof Error);
    });

    db.update({
      name: 'Johan',
      age: 25
    }, function(err, data) {
        assert.strictEqual(err, null, 'Should not return error');
        assert.ok(data, null, 'Should return some data');

        done();
      });
  });

  function createFakeMechanism() {
    var FakeMechanism = function(uri) {
      this.uri_ = uri;
    };

    var mechanismImpl = function(data, callback) {
      setTimeout(function() {
        if (data) {
          callback(null, 'Success');
        } else {
          callback(new Error('There is no data provided'), 'Failure');
        }
      }, 10);
    };

    FakeMechanism.prototype.add = mechanismImpl;
    FakeMechanism.prototype.find = mechanismImpl;
    FakeMechanism.prototype.remove = mechanismImpl;
    FakeMechanism.prototype.update = mechanismImpl;
    return FakeMechanism;
  }

});
<|endoftext|>


<commit_before>// dependencies, which are already loaded by Argus
// - Q
// - jQuery

// helper for JSON flatten
JSON.flatten = function(data) {
  var result = {};
  function recurse (cur, prop) {
    if (Object(cur) !== cur) {
      result[prop] = cur;
    } else if (Array.isArray(cur)) {
      for(var i=0, l=cur.length; i<l; i++)
        recurse(cur[i], prop + "[" + i + "]");
      if (l == 0)
        result[prop] = [];
    } else {
      var isEmpty = true;
      for (var p in cur) {
        isEmpty = false;
        recurse(cur[p], prop ? prop+"."+p : p);
      }
      if (isEmpty && prop)
        result[prop] = {};
    }
  }
  recurse(data, "");
  return result;
};

function ArgusData(urlBase, validMetricExploreExpression){
  this.base = urlBase + '/argusws/metrics?expression=',
  this.expression = validMetricExploreExpression,
  this.url = this.base + this.expression,
  this.name = '',
  this.seriesNames = [],
  this.dataTable,
  this.queryArgus.bind(this); // IIFE to initalize this.jsonData

}

ArgusData.prototype.queryArgus = function(e){
  var deferred = Q.defer();
  $.ajax({
    url: e.url,
    async: true,
    crossDomain: true,
    dataType: 'json',
    xhrFields: {
      withCredentials: true
    },
    success: function (data) {
      e.jsonData = data;
      // flatten the data
      // for (let i=0; i < e.jsonData.length; i++){
      //   e.jsonData[i] = JSON.flatten(e.jsonData[i]);
      // }
      // // get/set the metric name
      // e.name = e.jsonData[0]['metric'];
      // // get/set the series names
      // e.jsonData.forEach(function(currentValue){
      //   e.seriesNames.push(currentValue['tags.device'])
      // });
      deferred.resolve();
    }
  });
  return deferred.promise;
};
<commit_msg>e.dataTable<commit_after>// dependencies, which are already loaded by Argus
// - Q
// - jQuery

// helper for JSON flatten
JSON.flatten = function(data) {
  var result = {};
  function recurse (cur, prop) {
    if (Object(cur) !== cur) {
      result[prop] = cur;
    } else if (Array.isArray(cur)) {
      for(var i=0, l=cur.length; i<l; i++)
        recurse(cur[i], prop + "[" + i + "]");
      if (l == 0)
        result[prop] = [];
    } else {
      var isEmpty = true;
      for (var p in cur) {
        isEmpty = false;
        recurse(cur[p], prop ? prop+"."+p : p);
      }
      if (isEmpty && prop)
        result[prop] = {};
    }
  }
  recurse(data, "");
  return result;
};

function ArgusData(urlBase, validMetricExploreExpression){
  this.base = urlBase + '/argusws/metrics?expression=',
  this.expression = validMetricExploreExpression,
  this.url = this.base + this.expression,
  this.name = '',
  this.seriesNames = [],
  this.dataTable = [],
  this.queryArgus.bind(this); // IIFE to initalize this.jsonData

}

ArgusData.prototype.queryArgus = function(e){
  var deferred = Q.defer();
  $.ajax({
    url: e.url,
    async: true,
    crossDomain: true,
    dataType: 'json',
    xhrFields: {
      withCredentials: true
    },
    success: function (data) {
      e.jsonData = data;
      for (let i=0; i < e.jsonData.length; i++){
        e.dataTable[e.dataTable.length]=Object.keys(e.jsonData[i].datapoints);
        e.dataTable[e.dataTable.length]=Object.values(e.jsonData[i].datapoints);
      }
      // flatten the data
      // for (let i=0; i < e.jsonData.length; i++){
      //   e.jsonData[i] = JSON.flatten(e.jsonData[i]);
      // }
      // get/set the metric name
      e.name = e.jsonData[0]['metric'];
      // get/set the series names
      e.jsonData.forEach(function(currentValue){
        e.seriesNames.push(currentValue['tags.device']);
      });
      deferred.resolve();
    }
  });
  return deferred.promise;
};
<|endoftext|>


<commit_before>'use strict';

var document = new (require('jsdom/lib/jsdom/level3/core')
		.dom.level3.core.Document)()
  , pg = __dirname + '/__playground';

module.exports = function (t, a) {
	var dom, el1, el2, builder;
	builder = Object.create(t).init(['foo', 'bar', 'var'])
		.init(document, require);
	dom = builder.build(function () {
			var late;

			foo("foo text");

			late = bar({ 'class': "test-class", other: "test-other", id: "internal" },
				foo("raz"),
				foo("dwa"),
				foo("trzy"));

			_var();

			late(foo("cztery"));
			late(foo("pięć"));

			late().setAttribute("foo", "bar");

			_element('not-standard', { foo: true, bar: false },
				"not standard content");

			_direct(el1 = document.createElement('div'),
				el2 = document.createElement('p'));
			el2.setAttribute('id', 'external');

			_text("text sibling");

			_comment("comment sibling");

			_cdata("cdata sibling");

		});

	a(dom && dom.nodeType, 11, "Expect document fragment");

	dom = dom.firstChild;
	a(dom.nodeName, 'foo', "Match firstChild");
	a(dom.childNodes.length, 1, "ChildNodes length");
	a(dom.firstChild.nodeType, 3, "Append text node");
	a(dom.firstChild.data, 'foo text', "Append text node content");

	dom = dom.nextSibling;
	a(dom.nodeType, 1, "Sibling element");
	a(dom.nodeName, 'bar', "Sibling element name");
	a(dom.getAttribute('class'), 'test-class', "Element attribute");
	a(dom.getAttribute('other'), 'test-other', "Element other attribute");
	a(dom.childNodes.length, 5, "Late children");
	a(dom.firstChild.nodeType, 1, "Element child type");
	a(dom.firstChild.nodeName, 'foo', "Element child name");
	a(dom.lastChild.textContent, 'pięć', "Late child content");
	a(dom.getAttribute('foo'), 'bar', "Direct attribute");

	dom = dom.nextSibling;
	a(builder.getById('internal'),
		dom.parentNode.removeChild(dom.previousSibling), "Internal id");
	a(dom.nodeName, 'var', "Reserved element name");

	dom  = dom.nextSibling;
	a(dom.nodeName, 'not-standard', "Not standard element");
	a(dom.firstChild.data, 'not standard content',
		"Not standard element content");
	a(dom.getAttribute('foo'), 'foo', "Atribute set with boolean true");
	a(dom.hasAttribute('bar'), false, "Atribute set with boolean false");

	dom  = dom.nextSibling;
	a(dom, el1, "Direct append #1");

	dom  = dom.nextSibling;
	a(dom, el2, "Direct append #2");
	a(builder.getById('external'), el2, "External id");

	dom  = dom.nextSibling;
	a(dom.nodeType, 3, "Sibling text node");
	a(dom.data, 'text sibling', "Sibling text node content");

	dom = dom.nextSibling;
	a(dom.nodeType, 8, "Sibling comment");
	a(dom.data, 'comment sibling', "Sibling comment content");

	dom = dom.nextSibling;
	a(dom.nodeType, 4, "Sibling CDATA");
	a(dom.data, 'cdata sibling', "Sibling CDATA content");

	a(dom.nextSibling, null, "No unexpected DOM elements");

	a(builder.build('./__playground/tpl').firstChild.textContent, 'By require',
		"By require");
};
<commit_msg>External id won't be picked up until element lands in document<commit_after>'use strict';

var document = new (require('jsdom/lib/jsdom/level3/core')
		.dom.level3.core.Document)()
  , pg = __dirname + '/__playground';

module.exports = function (t, a) {
	var dom, el1, el2, builder;
	builder = Object.create(t).init(['foo', 'bar', 'var'])
		.init(document, require);
	dom = builder.build(function () {
			var late;

			foo("foo text");

			late = bar({ 'class': "test-class", other: "test-other", id: "internal" },
				foo("raz"),
				foo("dwa"),
				foo("trzy"));

			_var();

			late(foo("cztery"));
			late(foo("pięć"));

			late().setAttribute("foo", "bar");

			_element('not-standard', { foo: true, bar: false },
				"not standard content");

			_direct(el1 = document.createElement('div'),
				el2 = document.createElement('p'));
			el2.setAttribute('id', 'external');

			_text("text sibling");

			_comment("comment sibling");

			_cdata("cdata sibling");

		});

	a(dom && dom.nodeType, 11, "Expect document fragment");

	dom = dom.firstChild;
	a(dom.nodeName, 'foo', "Match firstChild");
	a(dom.childNodes.length, 1, "ChildNodes length");
	a(dom.firstChild.nodeType, 3, "Append text node");
	a(dom.firstChild.data, 'foo text', "Append text node content");

	dom = dom.nextSibling;
	a(dom.nodeType, 1, "Sibling element");
	a(dom.nodeName, 'bar', "Sibling element name");
	a(dom.getAttribute('class'), 'test-class', "Element attribute");
	a(dom.getAttribute('other'), 'test-other', "Element other attribute");
	a(dom.childNodes.length, 5, "Late children");
	a(dom.firstChild.nodeType, 1, "Element child type");
	a(dom.firstChild.nodeName, 'foo', "Element child name");
	a(dom.lastChild.textContent, 'pięć', "Late child content");
	a(dom.getAttribute('foo'), 'bar', "Direct attribute");

	dom = dom.nextSibling;
	a(builder.getById('internal'),
		dom.parentNode.removeChild(dom.previousSibling), "Internal id");
	a(dom.nodeName, 'var', "Reserved element name");

	dom  = dom.nextSibling;
	a(dom.nodeName, 'not-standard', "Not standard element");
	a(dom.firstChild.data, 'not standard content',
		"Not standard element content");
	a(dom.getAttribute('foo'), 'foo', "Atribute set with boolean true");
	a(dom.hasAttribute('bar'), false, "Atribute set with boolean false");

	dom  = dom.nextSibling;
	a(dom, el1, "Direct append #1");

	dom  = dom.nextSibling;
	a(dom, el2, "Direct append #2");
	// a(builder.getById('external'), el2, "External id");

	dom  = dom.nextSibling;
	a(dom.nodeType, 3, "Sibling text node");
	a(dom.data, 'text sibling', "Sibling text node content");

	dom = dom.nextSibling;
	a(dom.nodeType, 8, "Sibling comment");
	a(dom.data, 'comment sibling', "Sibling comment content");

	dom = dom.nextSibling;
	a(dom.nodeType, 4, "Sibling CDATA");
	a(dom.data, 'cdata sibling', "Sibling CDATA content");

	a(dom.nextSibling, null, "No unexpected DOM elements");

	a(builder.build('./__playground/tpl').firstChild.textContent, 'By require',
		"By require");
};
<|endoftext|>


<commit_before>/*
    GNOME Shell extensions repository
    Copyright (C) 2011-2012  Jasper St. Pierre <jstpierre@mecheye.net>
    Copyright (C) 2016-2017  Yuri Konotopov <ykonotopov@gnome.org>

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU Affero General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.
 */

define(['jquery', 'dbus!API'], function ($, API) {
	"use strict";

	function _makeRawPromise(result) {
		return (new $.Deferred()).resolve(result);
	}

	function _makePromise(result, resolveValue) {
		// Check if result is promise already
		if (isPromise(result))
		{
			return result;
		}

		return _makeRawPromise(typeof(resolveValue) == 'undefined' ? JSON.parse(result) : resolveValue);
	}

	function isPromise(value) {
		return value && typeof(value.then) == 'function';
	}

	return {
		_makePromise: _makePromise,

		ListExtensions: function () {
			return _makePromise(API.listExtensions());
		},

		GetExtensionInfo: function (uuid) {
			return _makePromise(API.getExtensionInfo(uuid));
		},

		GetErrors: function (uuid) {
			return _makePromise(API.getExtensionErrors(uuid));
		},

		LaunchExtensionPrefs: function (uuid) {
			return API.launchExtensionPrefs(uuid);
		},

		LaunchExtensionPrefsDummy: function (uuid) {
		},

		EnableExtension: function (uuid) {
			API.setExtensionEnabled(uuid, true);
		},

		DisableExtension: function (uuid) {
			API.setExtensionEnabled(uuid, false);
		},

		InstallExtensionOne: function (uuid) {
			return _makePromise(API.installExtension(uuid), 'succeeded');
		},

		InstallExtensionTwo: function (uuid) {
			return _makePromise(API.installExtension(uuid, ""), 'succeeded');
		},

		InstallExtensionAsync: function (uuid) {
			var d = new $.Deferred();
			var result = API.installExtension(uuid, d.done.bind(d), d.fail.bind(d));

			if (isPromise(result))
			{
				return result;
			}

			return d;
		},

		UninstallExtension: function (uuid) {
			return _makePromise(API.uninstallExtension(uuid));
		},

		API_onchange: function (proxy) {
			return function (uuid, newState, error) {
				if (proxy.extensionStateChangedHandler !== null)
				{
					proxy.extensionStateChangedHandler(uuid, newState, error);
				}
			};
		},

		API_onshellrestart: function (proxy) {
			return function () {
				if (proxy.shellRestartHandler !== null)
				{
					proxy.shellRestartHandler();
				}
			};
		}
	};
});
<commit_msg>common.js: return promises for enable/disable extension methods<commit_after>/*
    GNOME Shell extensions repository
    Copyright (C) 2011-2012  Jasper St. Pierre <jstpierre@mecheye.net>
    Copyright (C) 2016-2017  Yuri Konotopov <ykonotopov@gnome.org>

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU Affero General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.
 */

define(['jquery', 'dbus!API'], function ($, API) {
	"use strict";

	function _makeRawPromise(result) {
		return (new $.Deferred()).resolve(result);
	}

	function _makePromise(result, resolveValue) {
		// Check if result is promise already
		if (isPromise(result))
		{
			return result;
		}

		return _makeRawPromise(typeof(resolveValue) == 'undefined' ? JSON.parse(result) : resolveValue);
	}

	function isPromise(value) {
		return value && typeof(value.then) == 'function';
	}

	return {
		_makePromise: _makePromise,

		ListExtensions: function () {
			return _makePromise(API.listExtensions());
		},

		GetExtensionInfo: function (uuid) {
			return _makePromise(API.getExtensionInfo(uuid));
		},

		GetErrors: function (uuid) {
			return _makePromise(API.getExtensionErrors(uuid));
		},

		LaunchExtensionPrefs: function (uuid) {
			return API.launchExtensionPrefs(uuid);
		},

		LaunchExtensionPrefsDummy: function (uuid) {
		},

		EnableExtension: function (uuid) {
			return _makePromise(API.setExtensionEnabled(uuid, true), true);
		},

		DisableExtension: function (uuid) {
			return _makePromise(API.setExtensionEnabled(uuid, false), true);
		},

		InstallExtensionOne: function (uuid) {
			return _makePromise(API.installExtension(uuid), 'succeeded');
		},

		InstallExtensionTwo: function (uuid) {
			return _makePromise(API.installExtension(uuid, ""), 'succeeded');
		},

		InstallExtensionAsync: function (uuid) {
			var d = new $.Deferred();
			var result = API.installExtension(uuid, d.done.bind(d), d.fail.bind(d));

			if (isPromise(result))
			{
				return result;
			}

			return d;
		},

		UninstallExtension: function (uuid) {
			return _makePromise(API.uninstallExtension(uuid));
		},

		API_onchange: function (proxy) {
			return function (uuid, newState, error) {
				if (proxy.extensionStateChangedHandler !== null)
				{
					proxy.extensionStateChangedHandler(uuid, newState, error);
				}
			};
		},

		API_onshellrestart: function (proxy) {
			return function () {
				if (proxy.shellRestartHandler !== null)
				{
					proxy.shellRestartHandler();
				}
			};
		}
	};
});
<|endoftext|>


<commit_before>'use strict';

var mkdirp = require('mkdirp');
var fs     = require('fs');
var path   = require('path');
var utils  = require('amd-utils');
var async  = require('async');

var task = {
    id         : 'mkdir',
    author     : 'Indigo United',
    name       : 'Make dir recursively',
    description: 'Make directories',
    options    : {
        dirs: {
            description: 'The directories you want to create. Accepts an array of directories or a single one through a string.'
        },
        mode: {
            description: 'The directory permissions',
            'default': '0777'
        }
    },
    filter     : function (opt, ctx, next) {
        if (!utils.lang.isNumber(opt.mode)) {
            opt.mode = parseInt(opt.mode, 8);
        }
        next();
    },
    tasks      :
    [
        {
            task: function (opt, ctx, next) {
                var dirs = utils.lang.isArray(opt.dirs) ? opt.dirs : [opt.dirs];
                var error;

                async.forEach(dirs, function (dir, next) {
                    dir = path.normalize(dir);

                    fs.stat(dir, function (err) {
                        if (!err || err.code !== 'ENOENT') {
                            error = new Error('EEXIST, target already exists \'' + dir + '\'');
                            error.code = 'EXISTS';
                            return next(error);
                        }

                        mkdirp(dir, opt.mode, next);
                    });
                }, next);
            }
        }
    ]
};

module.exports = task;<commit_msg>Error code typo.<commit_after>'use strict';

var mkdirp = require('mkdirp');
var fs     = require('fs');
var path   = require('path');
var utils  = require('amd-utils');
var async  = require('async');

var task = {
    id         : 'mkdir',
    author     : 'Indigo United',
    name       : 'Make dir recursively',
    description: 'Make directories',
    options    : {
        dirs: {
            description: 'The directories you want to create. Accepts an array of directories or a single one through a string.'
        },
        mode: {
            description: 'The directory permissions',
            'default': '0777'
        }
    },
    filter     : function (opt, ctx, next) {
        if (!utils.lang.isNumber(opt.mode)) {
            opt.mode = parseInt(opt.mode, 8);
        }
        next();
    },
    tasks      :
    [
        {
            task: function (opt, ctx, next) {
                var dirs = utils.lang.isArray(opt.dirs) ? opt.dirs : [opt.dirs];
                var error;

                async.forEach(dirs, function (dir, next) {
                    dir = path.normalize(dir);

                    fs.stat(dir, function (err) {
                        if (!err || err.code !== 'ENOENT') {
                            error = new Error('EEXIST, target already exists \'' + dir + '\'');
                            error.code = 'EEXISTS';
                            return next(error);
                        }

                        mkdirp(dir, opt.mode, next);
                    });
                }, next);
            }
        }
    ]
};

module.exports = task;<|endoftext|>


<commit_before>'use strict';
var Docker = require('dockerode');
var through2 = require('through2');
var bunyan = require('bunyan');
var Promise = require('bluebird');
var util = require('util');
var EventEmitter = require('events').EventEmitter;

var TaskRunnerPlugins = require('./plugins/TaskRunner');
var AssetDownloader = require('./plugins/TaskRunner/AssetDownloader');

// patch dockerode's container.inspect to take opts
require('./_patchDockerodeInspect');

const ASSET_DIR = '/assets';
const SRC_DIR = '/src';

/**
 * Constructor for the container model.
 * @class
 *
 * @param {object} options - An options hash.
 * @param {object} options.assets - Assets server configuration for AssetDownloader.
 * @param {string} options.assets.url - Assets server URL.
 * @param {string} [options.assets.token] - API token for assets server.
 */
var Container = function(options) {
  this.create = this.create.bind(this);
  this.docker = new Docker(options.docker);
  this.build = options.build;
  this.jobConfig = options.jobConfig;
  this.log = options.log ? options.log.child({component: 'container'}) : bunyan.createLogger({name: 'container'});
  this.containerName = options.containerName || null;
  this.containerId = options.containerId || null;
  this.container = this.containerId ? this.docker.getContainer(this.containerId) : null;
  this.image = options.image;
  this.imageConfig = options.imageConfig;
  this.binds = options.binds || [];
  // Whether to attach to log output.
  this.attachLogs = options.attachLogs || false;
  this.assetsOpts = options.assets;
  this.authUrl = options.authUrl;

  EventEmitter.call(this);

  // wrap emit method to also emit a generic event
  var _emit = this.emit;
  this.emit = function(event) {
    var args = Array.prototype.slice.call(arguments);

    // emit original event
    _emit.apply(this, args);

    // emit a "stateChange" event
    args.unshift('stateChange');
    _emit.apply(this, args);
  };
};
util.inherits(Container, EventEmitter);

Container.prototype.buildSetupTasks = Promise.promisify(function(done) {
  var jobConfig = this.jobConfig;

  var container = this;
  var build = this.build;
  var project = build.project;

  var tasks = [];

  // 1. Download the code
  var downloadSource = this._createDownloader(build, project);
  tasks.push(downloadSource);

  // 2. Download the assets
  if (jobConfig.assets && this.assetsOpts) {
    this.assetsOpts.bucket = (project.assets && project.assets.bucket) || project.id;
    this.assetsOpts.assets = jobConfig.assets;
    var ad = new AssetDownloader(container, this.assetsOpts);
    tasks.push(ad);
  }

  done(null, tasks);
});

Container.prototype._createDownloader = function(build, project) {
  // map provider type to downloader class name
  var downloaders = {
    github: 'GithubDownloader',
    stash: 'StashDownloader',
    bitbucket: 'BitbucketDownloader',
  };

  var providerType = project.provider.type;
  var plugin = downloaders[providerType];
  if (!plugin) {
    throw new Error('Download: unsupported provider type: ' + providerType);
  }

  // dynamically require and instantiate a downloder
  var Downloader;
  try {
    Downloader = require(`./plugins/TaskRunner/${plugin}`);
  }
  catch (e) {
    var msg = `Download: failed to load supported downloader for provider ${providerType}: ${e.message}`;
    this.log.error({err: e, plugin}, msg);
    throw new Error(msg);
  }

  return new Downloader(this, {build, project, auth_lookup_url: this.authUrl});
};

Container.prototype.buildUserTasks = Promise.promisify(function(done) {
  var self = this;
  var config = this.jobConfig;
  var tasks = [];
  var steps = config.steps || [];
  steps = Array.isArray(steps) ? steps : [steps];

  steps.forEach(function(step) {
    var plugin = step.plugin || 'Shell';

    if (self.provisionerPlugins[plugin]) {
      var task = new self.provisionerPlugins[plugin](self, step);
      tasks.push(task);
    }
  });

  done(null, tasks);
});

/**
 * First class Promise method.
 *
 * helper method to run scripts, not
 * useful in an app because it doesn't pass up stream before its piped
 * out
 *
 * @return {booelean} - The status of the tasks.
 */
Container.prototype.runTasks = function() {
  this.emit('running tasks');

  var self = this;
  return this.buildUserTasks().each(function(task) {
    return task.run().then(function(result) {
      // result: {stream, exec (Promise), task}
      result.streams.combined.pipe(process.stdout);
      return result.exec.then(function(exec) {
        console.log('Exit code:', exec.ExitCode);

        self.emit('tasks complete', result);
        return result;
      });
    });
  });
};

Container.prototype.runBuild = Promise.promisify(function(done) {
  var self = this;
  self.create(function(error, containerData) {
    if (error) return done(error);

    return self.runTasks().then(function(EvaluatedTasks) {
      return containerData;
    }).nodeify(done);
  });
});

/**
 * Creates and starts this Docker container.
 *
 * The done callback will be called with errors (if one occured).
 */
Container.prototype.create = Promise.promisify(function(done) {
  this.emit('creating');
  done = wrapCallbackWithEmitter(this, 'created', done);

  var self = this;
  var docker = this.docker;

  var commandInfo = self.buildCommandInfo(self.imageConfig);

  var createOptions = {
    name: self.containerName,
    Image: self.image,
    ExposedPorts: commandInfo.exposedPorts,
    Cmd: commandInfo.command,
    Env: [
      `COMMIT_REF=${this.build.commit.ref}`,
      `BUILD_ID=${this.build.id}`,
      `BUILD_DOMAIN=${this.build.links.build}`,
      `SRC_DIR=${SRC_DIR}`,
      `ASSET_DIR=${ASSET_DIR}`,
      `PWD=${SRC_DIR}`,
      `PROBO_ENVIRONMENT=TRUE`,
    ],
  };
  var startOptions = {
    PortBindings: commandInfo.portBindings,
    Binds: self.binds,
  };
  self.log.info('creating container');
  docker.createContainer(createOptions, function(error, container) {
    if (error) return done(error);
    self.id = container.id;
    self.container = container;
    if (error) return done(error);
    self.log.info('container created', {containerId: container.id});
    self.log.info('starting container', {containerId: container.id});
    if (self.attachLogs) {
      container.attach({stream: true, stdout: true, stderr: true}, function(error, stream) {
        // TODO: We should consider collecting log output from the node and
        // sending it to loom.
        container.modem.demuxStream(stream, self.createLogWriteStream(), self.createLogWriteStream());
      });
    }
    container.start(startOptions, function(error, data) {
      if (error) return done(error);
      container.inspect(function(error, data) {
        self.containerInfo = data;
        done(error, data);
      });
    });
  });
});

/**
 * Tries to create a container or finds one by the ID instead
 */
Container.prototype.findOrCreate = function() {

};

/**
 * Returns the current status of the container
 */
Container.prototype.getState = function(done) {
  return this.inspect()
    .then(function(info) { return info.State; })
    .asCallback(done);
};

/**
 * Returns result of .inspect on container
 */
Container.prototype.inspect = Promise.promisify(function(opts, done) {
  if (typeof opts == 'function') {
    done = opts;
    opts = {};
  }
  this.container.inspect(opts, function(err, info) {
    return done(err, info);
  });
});

/**
 * Stop the container
 */
Container.prototype.stop = Promise.promisify(function(done) {
  this.emit('stopping');
  done = wrapCallbackWithEmitter(this, 'stopped', done);
  this.container.stop(done);
});

/**
 * restart (stop/start) container
 */
Container.prototype.restart = Promise.promisify(function(done) {
  this.emit('restarting');
  done = wrapCallbackWithEmitter(this, 'restarted', done);
  this.container.restart(done);
});

/**
 * start container
 */
Container.prototype.start = Promise.promisify(function(done) {
  this.emit('starting');
  done = wrapCallbackWithEmitter(this, 'started', done);
  this.container.start(done);
});

/**
 * DELETE container from the filesystem
 */
Container.prototype.remove = Promise.promisify(function(opts, done) {
  this.emit('removing');

  if (typeof opts == 'function') {
    done = opts;
    opts = {};
  }

  done = wrapCallbackWithEmitter(this, 'removed', done);
  this.container.remove(opts, done);
});

/**
 * Get the particular exposed port from container info.
 */
Container.prototype.getExposedPortFromContainerInfo = function(data, port) {
  try {
    return data.NetworkSettings.Ports[port + '/tcp'][0].HostPort;
  }
  catch (e) {
    throw new Error('Could not find tcp port ' + port + ' on container ' + this.id);
  }
};

/**
 * Gets the disk usage of the container.
 * Current implementation requires the AUFS Storage driver and to be run as root.
 * Errors if there's no root access or not using the AUFS driver
 *
 * @param {Function} done - callback that takes err and an object as arguments. The object has {virtualBytes, realBytes}, for the size of the inderlying image and container layer respectively
 */
Container.prototype.getDiskUsage = Promise.promisify(function(done) {
  var result = {realBytes: undefined, virtualBytes: undefined};

  // stat the container to ensure that it's using the AUFS driver
  this.container.inspect({size: true}, function(err, info) {
    if (err) {
      return done(null, result);
    }

    result.realBytes = (info.SizeRw || null);
    result.virtualBytes = (info.SizeRootFs || null);
    done(null, result);
  });
});

/**
 * Build the command and port exposing logic for starting a penelope powered container.
 *
 * @param {string} image - The name of the image we are extracting build command info for.
 * @return {object} - The command info on what is to be run.
 */
Container.prototype.buildCommandInfo = function(image) {
  if (!image) {
    throw new Error('Use a real `image` in your .probo.yaml file');
  }

  var command = ['penelope'];
  var exposedPorts = {};
  var portBindings = {};
  for (let name in image.services) {
    if (image.services.hasOwnProperty(name)) {
      var service = image.services[name];
      command.push('-n');
      command.push(name);
      command.push('-c');
      command.push(service.command);
      if (service.port) {
        var protocol = service.protocol || 'tcp';
        var portString = service.port + '/' + protocol;
        exposedPorts[portString] = {};
        portBindings[portString] = [{HostPort: null}];
      }
    }
  }
  return {
    command: command,
    exposedPorts: exposedPorts,
    portBindings: portBindings,
  };
};

Container.prototype.provisionerPlugins = TaskRunnerPlugins;

/**
 * Get a log handler stream appropriate to piping output to.
 *
 * @param {object} options Options to pass to for the creation of the log stream.
 * @return {stream} - The stream to write log files to.
 */
Container.prototype.createLogWriteStream = function(options) {
  var stream = through2();
  stream.pipe(process.stdout);
  return stream;
};

function wrapCallbackWithEmitter(emitter, eventName, callback) {
  return function() {
    var args = Array.prototype.slice.call(arguments);
    args.unshift(eventName);
    emitter.emit.apply(emitter, args);
    callback.apply(emitter, arguments);
  };
}

module.exports = Container;
<commit_msg>Conditionally include the build link as an environment variable only if it is available.<commit_after>'use strict';
var Docker = require('dockerode');
var through2 = require('through2');
var bunyan = require('bunyan');
var Promise = require('bluebird');
var util = require('util');
var EventEmitter = require('events').EventEmitter;

var TaskRunnerPlugins = require('./plugins/TaskRunner');
var AssetDownloader = require('./plugins/TaskRunner/AssetDownloader');

// patch dockerode's container.inspect to take opts
require('./_patchDockerodeInspect');

const ASSET_DIR = '/assets';
const SRC_DIR = '/src';

/**
 * Constructor for the container model.
 * @class
 *
 * @param {object} options - An options hash.
 * @param {object} options.assets - Assets server configuration for AssetDownloader.
 * @param {string} options.assets.url - Assets server URL.
 * @param {string} [options.assets.token] - API token for assets server.
 */
var Container = function(options) {
  this.create = this.create.bind(this);
  this.docker = new Docker(options.docker);
  this.build = options.build;
  this.jobConfig = options.jobConfig;
  this.log = options.log ? options.log.child({component: 'container'}) : bunyan.createLogger({name: 'container'});
  this.containerName = options.containerName || null;
  this.containerId = options.containerId || null;
  this.container = this.containerId ? this.docker.getContainer(this.containerId) : null;
  this.image = options.image;
  this.imageConfig = options.imageConfig;
  this.binds = options.binds || [];
  // Whether to attach to log output.
  this.attachLogs = options.attachLogs || false;
  this.assetsOpts = options.assets;
  this.authUrl = options.authUrl;

  EventEmitter.call(this);

  // wrap emit method to also emit a generic event
  var _emit = this.emit;
  this.emit = function(event) {
    var args = Array.prototype.slice.call(arguments);

    // emit original event
    _emit.apply(this, args);

    // emit a "stateChange" event
    args.unshift('stateChange');
    _emit.apply(this, args);
  };
};
util.inherits(Container, EventEmitter);

Container.prototype.buildSetupTasks = Promise.promisify(function(done) {
  var jobConfig = this.jobConfig;

  var container = this;
  var build = this.build;
  var project = build.project;

  var tasks = [];

  // 1. Download the code
  var downloadSource = this._createDownloader(build, project);
  tasks.push(downloadSource);

  // 2. Download the assets
  if (jobConfig.assets && this.assetsOpts) {
    this.assetsOpts.bucket = (project.assets && project.assets.bucket) || project.id;
    this.assetsOpts.assets = jobConfig.assets;
    var ad = new AssetDownloader(container, this.assetsOpts);
    tasks.push(ad);
  }

  done(null, tasks);
});

Container.prototype._createDownloader = function(build, project) {
  // map provider type to downloader class name
  var downloaders = {
    github: 'GithubDownloader',
    stash: 'StashDownloader',
    bitbucket: 'BitbucketDownloader',
  };

  var providerType = project.provider.type;
  var plugin = downloaders[providerType];
  if (!plugin) {
    throw new Error('Download: unsupported provider type: ' + providerType);
  }

  // dynamically require and instantiate a downloder
  var Downloader;
  try {
    Downloader = require(`./plugins/TaskRunner/${plugin}`);
  }
  catch (e) {
    var msg = `Download: failed to load supported downloader for provider ${providerType}: ${e.message}`;
    this.log.error({err: e, plugin}, msg);
    throw new Error(msg);
  }

  return new Downloader(this, {build, project, auth_lookup_url: this.authUrl});
};

Container.prototype.buildUserTasks = Promise.promisify(function(done) {
  var self = this;
  var config = this.jobConfig;
  var tasks = [];
  var steps = config.steps || [];
  steps = Array.isArray(steps) ? steps : [steps];

  steps.forEach(function(step) {
    var plugin = step.plugin || 'Shell';

    if (self.provisionerPlugins[plugin]) {
      var task = new self.provisionerPlugins[plugin](self, step);
      tasks.push(task);
    }
  });

  done(null, tasks);
});

/**
 * First class Promise method.
 *
 * helper method to run scripts, not
 * useful in an app because it doesn't pass up stream before its piped
 * out
 *
 * @return {booelean} - The status of the tasks.
 */
Container.prototype.runTasks = function() {
  this.emit('running tasks');

  var self = this;
  return this.buildUserTasks().each(function(task) {
    return task.run().then(function(result) {
      // result: {stream, exec (Promise), task}
      result.streams.combined.pipe(process.stdout);
      return result.exec.then(function(exec) {
        console.log('Exit code:', exec.ExitCode);

        self.emit('tasks complete', result);
        return result;
      });
    });
  });
};

Container.prototype.runBuild = Promise.promisify(function(done) {
  var self = this;
  self.create(function(error, containerData) {
    if (error) return done(error);

    return self.runTasks().then(function(EvaluatedTasks) {
      return containerData;
    }).nodeify(done);
  });
});

/**
 * Creates and starts this Docker container.
 *
 * The done callback will be called with errors (if one occured).
 */
Container.prototype.create = Promise.promisify(function(done) {
  this.emit('creating');
  done = wrapCallbackWithEmitter(this, 'created', done);

  var self = this;
  var docker = this.docker;

  var commandInfo = self.buildCommandInfo(self.imageConfig);

  var createOptions = {
    name: self.containerName,
    Image: self.image,
    ExposedPorts: commandInfo.exposedPorts,
    Cmd: commandInfo.command,
    Env: [
      `COMMIT_REF=${this.build.commit.ref}`,
      `BUILD_ID=${this.build.id}`,
      `SRC_DIR=${SRC_DIR}`,
      `ASSET_DIR=${ASSET_DIR}`,
      `PWD=${SRC_DIR}`,
      `PROBO_ENVIRONMENT=TRUE`,
    ],
  };
  if (this.build.links && this.build.links.build) {
    createOptions.Env.push(`BUILD_DOMAIN=${this.build.links.build}`);
  }
  var startOptions = {
    PortBindings: commandInfo.portBindings,
    Binds: self.binds,
  };
  self.log.info('creating container');
  docker.createContainer(createOptions, function(error, container) {
    if (error) return done(error);
    self.id = container.id;
    self.container = container;
    if (error) return done(error);
    self.log.info('container created', {containerId: container.id});
    self.log.info('starting container', {containerId: container.id});
    if (self.attachLogs) {
      container.attach({stream: true, stdout: true, stderr: true}, function(error, stream) {
        // TODO: We should consider collecting log output from the node and
        // sending it to loom.
        container.modem.demuxStream(stream, self.createLogWriteStream(), self.createLogWriteStream());
      });
    }
    container.start(startOptions, function(error, data) {
      if (error) return done(error);
      container.inspect(function(error, data) {
        self.containerInfo = data;
        done(error, data);
      });
    });
  });
});

/**
 * Tries to create a container or finds one by the ID instead
 */
Container.prototype.findOrCreate = function() {

};

/**
 * Returns the current status of the container
 */
Container.prototype.getState = function(done) {
  return this.inspect()
    .then(function(info) { return info.State; })
    .asCallback(done);
};

/**
 * Returns result of .inspect on container
 */
Container.prototype.inspect = Promise.promisify(function(opts, done) {
  if (typeof opts == 'function') {
    done = opts;
    opts = {};
  }
  this.container.inspect(opts, function(err, info) {
    return done(err, info);
  });
});

/**
 * Stop the container
 */
Container.prototype.stop = Promise.promisify(function(done) {
  this.emit('stopping');
  done = wrapCallbackWithEmitter(this, 'stopped', done);
  this.container.stop(done);
});

/**
 * restart (stop/start) container
 */
Container.prototype.restart = Promise.promisify(function(done) {
  this.emit('restarting');
  done = wrapCallbackWithEmitter(this, 'restarted', done);
  this.container.restart(done);
});

/**
 * start container
 */
Container.prototype.start = Promise.promisify(function(done) {
  this.emit('starting');
  done = wrapCallbackWithEmitter(this, 'started', done);
  this.container.start(done);
});

/**
 * DELETE container from the filesystem
 */
Container.prototype.remove = Promise.promisify(function(opts, done) {
  this.emit('removing');

  if (typeof opts == 'function') {
    done = opts;
    opts = {};
  }

  done = wrapCallbackWithEmitter(this, 'removed', done);
  this.container.remove(opts, done);
});

/**
 * Get the particular exposed port from container info.
 */
Container.prototype.getExposedPortFromContainerInfo = function(data, port) {
  try {
    return data.NetworkSettings.Ports[port + '/tcp'][0].HostPort;
  }
  catch (e) {
    throw new Error('Could not find tcp port ' + port + ' on container ' + this.id);
  }
};

/**
 * Gets the disk usage of the container.
 * Current implementation requires the AUFS Storage driver and to be run as root.
 * Errors if there's no root access or not using the AUFS driver
 *
 * @param {Function} done - callback that takes err and an object as arguments. The object has {virtualBytes, realBytes}, for the size of the inderlying image and container layer respectively
 */
Container.prototype.getDiskUsage = Promise.promisify(function(done) {
  var result = {realBytes: undefined, virtualBytes: undefined};

  // stat the container to ensure that it's using the AUFS driver
  this.container.inspect({size: true}, function(err, info) {
    if (err) {
      return done(null, result);
    }

    result.realBytes = (info.SizeRw || null);
    result.virtualBytes = (info.SizeRootFs || null);
    done(null, result);
  });
});

/**
 * Build the command and port exposing logic for starting a penelope powered container.
 *
 * @param {string} image - The name of the image we are extracting build command info for.
 * @return {object} - The command info on what is to be run.
 */
Container.prototype.buildCommandInfo = function(image) {
  if (!image) {
    throw new Error('Use a real `image` in your .probo.yaml file');
  }

  var command = ['penelope'];
  var exposedPorts = {};
  var portBindings = {};
  for (let name in image.services) {
    if (image.services.hasOwnProperty(name)) {
      var service = image.services[name];
      command.push('-n');
      command.push(name);
      command.push('-c');
      command.push(service.command);
      if (service.port) {
        var protocol = service.protocol || 'tcp';
        var portString = service.port + '/' + protocol;
        exposedPorts[portString] = {};
        portBindings[portString] = [{HostPort: null}];
      }
    }
  }
  return {
    command: command,
    exposedPorts: exposedPorts,
    portBindings: portBindings,
  };
};

Container.prototype.provisionerPlugins = TaskRunnerPlugins;

/**
 * Get a log handler stream appropriate to piping output to.
 *
 * @param {object} options Options to pass to for the creation of the log stream.
 * @return {stream} - The stream to write log files to.
 */
Container.prototype.createLogWriteStream = function(options) {
  var stream = through2();
  stream.pipe(process.stdout);
  return stream;
};

function wrapCallbackWithEmitter(emitter, eventName, callback) {
  return function() {
    var args = Array.prototype.slice.call(arguments);
    args.unshift(eventName);
    emitter.emit.apply(emitter, args);
    callback.apply(emitter, arguments);
  };
}

module.exports = Container;
<|endoftext|>


<commit_before>import React, { Component, PropTypes } from 'react';

class TaskForm extends Component {
  static propTypes = {
    createTask: PropTypes.func.isRequired
  };

  constructor(props, context) {
    super(props, context);

    // Initial state
    this.state = {title: '', duration: 0};

    // This has to be done FOR ALL methods, so we're binding them, google 'react method bing es6' to understand what is going on
    this.onChangeTitle = ::this.onChangeTitle;
    this.onChangeDuration = ::this.onChangeDuration;
    this.onKeyUp = ::this.onKeyUp;
    this.onSubmit = ::this.onSubmit;
  }

  // Whenever we need to clear the input
  clearInput() {
    this.setState({title: '', duration: 0});
  }

  // When we time anything on the title input, this method is triggered
  onChangeTitle(event) {
    this.setState({title: event.target.value});
  }

  // When we time anything on the duration input, this method is triggered
  onChangeDuration(event) {
    this.setState({duration: event.target.value});
  }

  // As far as I know, this is only used by the tests
  onKeyUp(event) {
    if (event.keyCode === 27) {
      this.clearInput();
    }
  }

  // TODO: It's called when we submit the form, note that now it's only handling the title, you have to modify
  onSubmit(event) {
    event.preventDefault();
    const title = this.state.title.trim();
    if (title.length) this.props.createTask(title);
    this.clearInput();
  }

  // TODO: We need to investigate what the `ref` attr is doing/used for.
  render() {
    return (
      <form className="task-form" onSubmit={this.onSubmit} noValidate>
        <input
          autoComplete="off"
          autoFocus
          className="task-form__input"
          maxLength="64"
          onChange={this.onChangeTitle}
          onKeyUp={this.onKeyUp}
          placeholder="What are you working on?"
          ref={c => this.titleInput = c}
          type="text"
          value={this.state.title}
        />
        <input
         autoComplete="off"
         autoFocus
         className="task-form__input"
         maxLength="64"
         onChange={this.onChangeDuration}
         onKeyUp={this.onKeyUp}
         placeholder="For How Long?"
         ref={c => this.titleInput = c}
         type="text"
         value={this.state.duration}
        />
      </form>
    );
  }
}

export default TaskForm;
<commit_msg>add button<commit_after>import React, { Component, PropTypes } from 'react';

class TaskForm extends Component {
  static propTypes = {
    createTask: PropTypes.func.isRequired
  };

  constructor(props, context) {
    super(props, context);

    // Initial state
    this.state = {title: '', duration: 0};

    // This has to be done FOR ALL methods, so we're binding them, google 'react method bing es6' to understand what is going on
    this.onChangeTitle = ::this.onChangeTitle;
    this.onChangeDuration = ::this.onChangeDuration;
    this.onKeyUp = ::this.onKeyUp;
    this.onSubmit = ::this.onSubmit;
  }

  // Whenever we need to clear the input
  clearInput() {
    this.setState({title: '', duration: 0});
  }

  // When we time anything on the title input, this method is triggered
  onChangeTitle(event) {
    this.setState({title: event.target.value});
  }

  // When we time anything on the duration input, this method is triggered
  onChangeDuration(event) {
    this.setState({duration: event.target.value});
  }

  // As far as I know, this is only used by the tests
  onKeyUp(event) {
    if (event.keyCode === 27) {
      this.clearInput();
    }
  }

  // TODO: It's called when we submit the form, note that now it's only handling the title, you have to modify
  onSubmit(event) {
    event.preventDefault();
    const title = this.state.title.trim();
    if (title.length) this.props.createTask(title);
    this.clearInput();
  }

  // TODO: We need to investigate what the `ref` attr is doing/used for.
  render() {
    return (

        <form className="task-form"  noValidate>
          <input
            autoComplete="off"
            autoFocus
            className="task-form__input"
            maxLength="64"
            onChange={this.onChangeTitle}
            onKeyUp={this.onKeyUp}
            placeholder="What are you working on?"
            ref={c => this.titleInput = c}
            type="text"
            value={this.state.title}
          />
          <input
           autoComplete="off"
           autoFocus
           className="task-form__input"
           maxLength="64"
           onChange={this.onChangeDuration}
           onKeyUp={this.onKeyUp}
           placeholder="For How Long?"
           ref={c => this.titleInput = c}
           type="text"
           value={this.state.duration}
          />
        </form>

Add Task

    );
  }
}

export default TaskForm;
<|endoftext|>


<commit_before>import browserSync from 'browser-sync';
import gulpLoadPlugins from 'gulp-load-plugins';
import runSequence from 'run-sequence';

import * as paths from './paths';
import gulp from './_gulp';

const $ = gulpLoadPlugins();

const BS_OPTIONS = {
  ghostMode: false,
  open: false,
  notify: false,
  port: 9000
};

const BS_SERVER_OPTIONS = {
    baseDir: ['.', paths.SRC_DIR, paths.TMP_DIR],
    middleware: (req, res, next) => {
      res.setHeader('Access-Control-Allow-Origin', '*');
      next();
    }
};

function reportChange(event) {
  $.util.log(
    `File ${event.path} was ${event.type}, running tasks…`
  );
}

gulp.task('reload', () => browserSync.reload());

gulp.task('reload:build', (callback) => {
  return runSequence('build', 'reload', callback);
});

gulp.task('reload:dist', (callback) => {
  return runSequence('dist', 'reload', callback);
});

gulp.task('serve:dev', ['compile:styles', 'js:lint'], (done) => {
  const opts = Object.assign({}, BS_OPTIONS, {server: BS_SERVER_OPTIONS});
  browserSync(opts, done);

  gulp.watch(paths.SRC_SCRIPT, ['js:lint', 'reload'])
  .on('change', reportChange);
  gulp.watch(paths.SRC_INDEX, ['reload']).on('change', reportChange);
  gulp.watch(paths.SRC_STYLE, ['compile:styles', 'reload'])
  .on('change', reportChange);
});

gulp.task('serve:build', ['build'], (done) => {
  let serverOpts = Object.assign(
    {}, BS_SERVER_OPTIONS, {baseDir: [paths.BUILD_DIR]}
  );
  let opts = Object.assign({}, BS_OPTIONS, {server: serverOpts});
  browserSync(opts, done);

  gulp.watch(paths.SRC_ALL, ['reload:build']).on('change', reportChange);
});

gulp.task('serve:dist', ['dist'], (done) => {
  let serverOpts = Object.assign(
    {}, BS_SERVER_OPTIONS, {baseDir: [paths.DIST_DIR]}
  );
  let opts = Object.assign({}, BS_OPTIONS, {server: serverOpts});
  browserSync(opts, done);

  gulp.watch(paths.SRC_ALL, ['reload:dist']).on('change', reportChange);
});
<commit_msg>Refactor our alternate serves<commit_after>import browserSync from 'browser-sync';
import gulpLoadPlugins from 'gulp-load-plugins';
import runSequence from 'run-sequence';

import * as paths from './paths';
import gulp from './_gulp';

const $ = gulpLoadPlugins();

const BS_OPTIONS = {
  ghostMode: false,
  open: false,
  notify: false,
  port: 9000
};

const BS_SERVER_OPTIONS = {
    baseDir: ['.', paths.SRC_DIR, paths.TMP_DIR],
    middleware: (req, res, next) => {
      res.setHeader('Access-Control-Allow-Origin', '*');
      next();
    }
};

function reportChange(event) {
  $.util.log(
    `File ${event.path} was ${event.type}, running tasks…`
  );
}

function _serve(baseDir, reloadTasks, done) {
  const serverOpts = Object.assign(
    {}, BS_SERVER_OPTIONS, {baseDir: baseDir}
  );
  const opts = Object.assign({}, BS_OPTIONS, {server: serverOpts});
  browserSync(opts, done);

  return gulp.watch(paths.SRC_ALL, reloadTasks).on('change', reportChange);
}

gulp.task('reload', () => browserSync.reload());

gulp.task('reload:build', (callback) => {
  return runSequence('build', 'reload', callback);
});

gulp.task('reload:dist', (callback) => {
  return runSequence('dist', 'reload', callback);
});

gulp.task('serve:dev', ['compile:styles', 'js:lint'], (done) => {
  const opts = Object.assign({}, BS_OPTIONS, {server: BS_SERVER_OPTIONS});
  browserSync(opts, done);

  gulp.watch(paths.SRC_SCRIPT, ['js:lint', 'reload'])
  .on('change', reportChange);
  gulp.watch(paths.SRC_INDEX, ['reload']).on('change', reportChange);
  gulp.watch(paths.SRC_STYLE, ['compile:styles', 'reload'])
  .on('change', reportChange);
});

gulp.task('serve:build', ['build'], (done) => {
  return _serve([paths.BUILD_DIR], ['reload:build'], done);
});

gulp.task('serve:dist', ['dist'], (done) => {
  return _serve([paths.DIST_DIR], ['reload:dist'], done);
});
<|endoftext|>