<commit_before>/*
 *  Copyright 2011 Rackspace
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *
 */

var fs = require('fs');

var express = require('express');
var async = require('async');
var _ = require('underscore');

var db = require('../db');
var urls = require('../urls');
var middleware = require('../middleware');
var settings = require('../../settings');
var utils = require('../../utils');
var Release_Notes_Worker = require('../release_notes_worker');

var RELATED_APIS = require('../events').RELATED_APIS;

function get_devops(req, devops, api){
  var _devops = devops[req.params.project];
  if (!api){
    return _devops;
  }
  return _devops.related_apis[api];
}

module.exports.install = function(app, devops, polling_data, idjson){
  app.get(
    '/favicon.ico',
    function(req, res) {
      res.send("favicon");
  });

  app.get(
    urls.DEFECTS,
    function(req, res) {
      res.render('defects.jade');
  });

  app.get(
    urls.DEVHEALTH,
    function(req, res) {
      res.render('devhealth.jade');
    });

  app.get(
    urls.RELEASE_NOTES,
    function(req, res) {
      var context = {notes: null, errors: null};
      var start = req.query.start;
      var end = req.query.end;
      var worker;

      if(!start && !end){
        context.start = new Date(new Date().valueOf() - 31 * 24 * 60 *60 * 1000).toISOString();
        context.end = new Date().toISOString();
        return res.render('release_notes.jade', context);
      }
      context.start = start;
      context.end = end;
      if ((!start && end) || (!end && start)){
        context.errors = "Supply start and end!";
        return res.render('release_notes.jade', context);
      }

      try{
        start = new Date(start);
        end = new Date(end);
      }catch(e){
        context.errors = "I could not parse a date!" + e;
        return res.render('release_notes.jade', context);
      }

      if (start.toString() === 'Invalid Date' || end.toString() === 'Invalid Date'){
        context.errors = "I could not parse a date!";
        return res.render('release_notes.jade', context);
      }

      // we now know that the dates are valid
      context.start = start.toISOString();
      context.end = end.toISOString();

      worker = new Release_Notes_Worker(polling_data[req.params.project], start, end);
      worker.work(function(err, results){
        var v1_config = get_devops(req, devops, 'version_one');
        var dread_config = get_devops(req, devops, 'dreadnot');

        if (err){
          context.errors = err;
        }
        _.defaults(context, results);
        context.v1_host = v1_config ? v1_config.host : null;
        context.dread_host = dread_config ? dread_config.host : null;
        res.render('release_notes.jade', context);
      });
  });

  app.get(
    urls.INDEX,
    function(req, res) {
      var project = get_devops(req, devops);
      var events = project.events;

      var max = 0;
      var event;

      var now = (new Date()).getTime();
      var future_events = [];
      for (var i=0; i<events.length; i++){
        event = events[i];
        if (_.isNull(event.timestamp)){
          continue;
        }
        // convert to seconds
        event.seconds = event.timestamp * 1000;
        // get max
        if (event.seconds > max){
          max = event.seconds;
        }
        // make valid events list
        if (event.seconds > now){
          future_events.push(event);
        }
      }
      if (future_events.length > 1) {
        future_events.sort(function(x,y) {
          return y.timestamp < x.timestamp;
        });
      }
      _.each(future_events, function(event){
        event.days_remaining = Math.floor((event.seconds - now) / (1000*60*60*24));
        // figure out the amount and offset from the right 100px and from the left 25px
        var amt = ((event.seconds - now) / (max - now + 1)) * 0.8;
        event.position = amt * 100;
      });
      res.render('index.jade', {events: future_events, project: project});
  });
  app.get(
    urls.ABOUT,
    function(req, res) {
      res.render("about.jade", {name: "About"});
    });

  app.get(
    urls.META_INDEX,
    function(req, res) {
      var context = {
        name: 'Dashboards',
        projects: _.keys(devops),
        external_projects: settings.external_projects,
        links: settings.metadashboard_uris
      };
      res.render('meta_index.jade', context);
    });

  app.get(
    urls.SERVICE_HEALTH,
    function(req, res){
      var context = {};
        db.get_service_stats(req.params.project, function(err, results){
          context.hosts = results;
          context.health = {
            healthy: "health-healthy",
            unhealthy: "health-unhealthy",
          };
          res.render('service_health.jade', context);
        });
      });

  app.get(
    urls.HIGH_SCORES,
    function(req, res){
      var correlated_data = {};
      var project = req.params.project;
      var start_date = req.params.start;
      var end_date = req.params.end;

      db.get_highscores(project, start_date, end_date, function(errors, results){
        var place;
        var row;
        var i;
        var in_version_one;
        var github_name;

        while (results.length >= 1){
          row = results.pop();

          if (row.related_api === RELATED_APIS.github){
            correlated_data[row.username] = row;
            continue;
          }

          in_version_one = _.has(idjson, row.username);
          if (!in_version_one){
            correlated_data[row.username] = row;
            continue;
          }

          github_name = idjson[row.username];
          if (_.has(correlated_data, github_name)){
            correlated_data[github_name].score += row.score;
            continue;
          }

          row.username = github_name;
          correlated_data[row.username] = row;
        }
        correlated_data = _.values(correlated_data).sort(function(a, b){
          return b.score - a.score;
        });

        for (i = 0; i < correlated_data.length; i++){
          switch (i+1){
            case 1:
              place = '1st';
              break;
            case 2:
              place = '2nd';
              break;
            case 3:
              place = '3rd';
              break;
            default:
              place = i + 1 + 'th';
              break;
          }
          correlated_data[i].place = place;
        }

        res.render('highscores.jade', {data: correlated_data, errors: errors});
      });
    }
  );

  app.post(
    urls.STATS_API,
    [middleware.basic_auth,
     express.bodyParser()],
    function(req, res) {
      var project = req.params.project;
      var data = req.body;
      var msg;
      //TODO: use swiz for this
      if (!data || _.isEmpty(data)){
        return res.send('You must give me data.  Did you specify the mime type?', 400);
      }
      //TODO: do we need to parse for safety?
      db.add_service_stat(project, req.socket.remoteAddress, data, function(err, results){
        if (err){
          return res.send('oh noes', 400);
        }
        res.json('OK');
      });
    });
};
<commit_msg>default of one week instead of one month<commit_after>/*
 *  Copyright 2011 Rackspace
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *
 */

var fs = require('fs');

var express = require('express');
var async = require('async');
var _ = require('underscore');

var db = require('../db');
var urls = require('../urls');
var middleware = require('../middleware');
var settings = require('../../settings');
var utils = require('../../utils');
var Release_Notes_Worker = require('../release_notes_worker');

var RELATED_APIS = require('../events').RELATED_APIS;

function get_devops(req, devops, api){
  var _devops = devops[req.params.project];
  if (!api){
    return _devops;
  }
  return _devops.related_apis[api];
}

module.exports.install = function(app, devops, polling_data, idjson){
  app.get(
    '/favicon.ico',
    function(req, res) {
      res.send("favicon");
  });

  app.get(
    urls.DEFECTS,
    function(req, res) {
      res.render('defects.jade');
  });

  app.get(
    urls.DEVHEALTH,
    function(req, res) {
      res.render('devhealth.jade');
    });

  app.get(
    urls.RELEASE_NOTES,
    function(req, res) {
      var context = {notes: null, errors: null};
      var start = req.query.start;
      var end = req.query.end;
      var worker;

      if(!start && !end){
        context.start = new Date(new Date().valueOf() - 7 * 24 * 60 *60 * 1000).toISOString();
        context.end = new Date().toISOString();
        return res.render('release_notes.jade', context);
      }
      context.start = start;
      context.end = end;
      if ((!start && end) || (!end && start)){
        context.errors = "Supply start and end!";
        return res.render('release_notes.jade', context);
      }

      try{
        start = new Date(start);
        end = new Date(end);
      }catch(e){
        context.errors = "I could not parse a date!" + e;
        return res.render('release_notes.jade', context);
      }

      if (start.toString() === 'Invalid Date' || end.toString() === 'Invalid Date'){
        context.errors = "I could not parse a date!";
        return res.render('release_notes.jade', context);
      }

      // we now know that the dates are valid
      context.start = start.toISOString();
      context.end = end.toISOString();

      worker = new Release_Notes_Worker(polling_data[req.params.project], start, end);
      worker.work(function(err, results){
        var v1_config = get_devops(req, devops, 'version_one');
        var dread_config = get_devops(req, devops, 'dreadnot');

        if (err){
          context.errors = err;
        }
        _.defaults(context, results);
        context.v1_host = v1_config ? v1_config.host : null;
        context.dread_host = dread_config ? dread_config.host : null;
        res.render('release_notes.jade', context);
      });
  });

  app.get(
    urls.INDEX,
    function(req, res) {
      var project = get_devops(req, devops);
      var events = project.events;

      var max = 0;
      var event;

      var now = (new Date()).getTime();
      var future_events = [];
      for (var i=0; i<events.length; i++){
        event = events[i];
        if (_.isNull(event.timestamp)){
          continue;
        }
        // convert to seconds
        event.seconds = event.timestamp * 1000;
        // get max
        if (event.seconds > max){
          max = event.seconds;
        }
        // make valid events list
        if (event.seconds > now){
          future_events.push(event);
        }
      }
      if (future_events.length > 1) {
        future_events.sort(function(x,y) {
          return y.timestamp < x.timestamp;
        });
      }
      _.each(future_events, function(event){
        event.days_remaining = Math.floor((event.seconds - now) / (1000*60*60*24));
        // figure out the amount and offset from the right 100px and from the left 25px
        var amt = ((event.seconds - now) / (max - now + 1)) * 0.8;
        event.position = amt * 100;
      });
      res.render('index.jade', {events: future_events, project: project});
  });
  app.get(
    urls.ABOUT,
    function(req, res) {
      res.render("about.jade", {name: "About"});
    });

  app.get(
    urls.META_INDEX,
    function(req, res) {
      var context = {
        name: 'Dashboards',
        projects: _.keys(devops),
        external_projects: settings.external_projects,
        links: settings.metadashboard_uris
      };
      res.render('meta_index.jade', context);
    });

  app.get(
    urls.SERVICE_HEALTH,
    function(req, res){
      var context = {};
        db.get_service_stats(req.params.project, function(err, results){
          context.hosts = results;
          context.health = {
            healthy: "health-healthy",
            unhealthy: "health-unhealthy",
          };
          res.render('service_health.jade', context);
        });
      });

  app.get(
    urls.HIGH_SCORES,
    function(req, res){
      var correlated_data = {};
      var project = req.params.project;
      var start_date = req.params.start;
      var end_date = req.params.end;

      db.get_highscores(project, start_date, end_date, function(errors, results){
        var place;
        var row;
        var i;
        var in_version_one;
        var github_name;

        while (results.length >= 1){
          row = results.pop();

          if (row.related_api === RELATED_APIS.github){
            correlated_data[row.username] = row;
            continue;
          }

          in_version_one = _.has(idjson, row.username);
          if (!in_version_one){
            correlated_data[row.username] = row;
            continue;
          }

          github_name = idjson[row.username];
          if (_.has(correlated_data, github_name)){
            correlated_data[github_name].score += row.score;
            continue;
          }

          row.username = github_name;
          correlated_data[row.username] = row;
        }
        correlated_data = _.values(correlated_data).sort(function(a, b){
          return b.score - a.score;
        });

        for (i = 0; i < correlated_data.length; i++){
          switch (i+1){
            case 1:
              place = '1st';
              break;
            case 2:
              place = '2nd';
              break;
            case 3:
              place = '3rd';
              break;
            default:
              place = i + 1 + 'th';
              break;
          }
          correlated_data[i].place = place;
        }

        res.render('highscores.jade', {data: correlated_data, errors: errors});
      });
    }
  );

  app.post(
    urls.STATS_API,
    [middleware.basic_auth,
     express.bodyParser()],
    function(req, res) {
      var project = req.params.project;
      var data = req.body;
      var msg;
      //TODO: use swiz for this
      if (!data || _.isEmpty(data)){
        return res.send('You must give me data.  Did you specify the mime type?', 400);
      }
      //TODO: do we need to parse for safety?
      db.add_service_stat(project, req.socket.remoteAddress, data, function(err, results){
        if (err){
          return res.send('oh noes', 400);
        }
        res.json('OK');
      });
    });
};
<|endoftext|>


<commit_before>/* Purpose: Export development and production webpack configuration objects */

'use strict'

// Load modules
let env = require('../env')
let alert = require('../lib/alert')
let fs = require('fs-extra')
let abs = require('path').resolve
let us = require('underscore')
let webpack = require('webpack')

// Empty cache folder
fs.emptyDirSync(abs(env.cache, 'build'))

// Create configuration
let createConfiguration = function (mode) {
  // Check mode
  if (mode !== 'development' && mode !== 'production') {
    alert('Webpack configuration needs "production" or "development" as parameter.', 'issue')
  }

  // Define loaders
  let ExtractTextPlugin = require('extract-text-webpack-plugin')
  let loaders = [
    // JS files
    {
      test: /\.js$/,
      loader: 'babel',
      include: [
        abs(__dirname, '../lib'),
        abs(__dirname, '../scripts'),
        abs(env.app, 'app')
      ]
    },
    // Vue files
    {
      test: /\.vue$/,
      loader: 'vue'
    },
    // JSON files
    {
      test: /\.json$/,
      loader: 'json'
    },
    // CSS files
    {
      test: /\.css$/,
      loader: mode === 'development' ? 'vue-style-loader!css-loader' : ExtractTextPlugin.extract('css-loader' + (env.cfg.buildSourcemaps === true ? '?sourceMap' : ''))
    },
    // Image files
    {
      test: /\.(png|jpe?g|gif)(\?.*)?$/,
      loader: 'url',
      query: {
        limit: 1,
        name: 'img/[name].[hash:7].[ext]'
      }
    },
    // Favicon
    {
      test: /favicon\.ico$/,
      loader: 'url',
      query: {
        limit: 1,
        name: '[name].[ext]'
      }
    },
    // Font files
    {
      test: /\.(woff2?|eot|ttf|otf|svg)(\?.*)?$/,
      loader: 'url',
      query: {
        limit: 1,
        name: 'fonts/[name].[hash:7].[ext]'
      }
    }
  ]

  // Start configuration object
  let config = {
    entry: {
      app: [abs(__dirname, '../lib/app.js')]
    },
    output: {
      path: mode === 'development' ? abs(env.app) : abs(env.cache, 'build/www'),
      filename: '[name].[hash:7].js'
    },
    resolve: {
      extensions: ['', '.js', '.vue', '.json'],
      alias: {
        'vue$': 'vue/dist/vue.common.js'
      }
    },
    module: {
      loaders: loaders
    },
    plugins: []
  }

  // Add themes on production build
  if (mode === 'production') {
    if (env.cfg.theme === 'ios-material' || env.cfg.theme === 'material-ios') {
      config.entry = us.extend({
        ios: [abs(__dirname, '../lib/ios.js')],
        material: [abs(__dirname, '../lib/material.js')]
      }, config.entry)
    } else {
      config.entry.app.unshift(abs(__dirname, '../lib/' + env.cfg.theme + '.js'))
    }
  }

  // Add environment variables
  let firebaseConfig = mode === 'production' ? env.cfg.firebase : env.cfg.devFirebase
  config.plugins.push(
    new webpack.DefinePlugin({
      'process.env': {
        THEME: '"' + env.cfg.theme + '"',
        APP_ROOT_FROM_SCRIPTS: '"' + (env.installed ? '../../../app/' : '../app/') + '"',
        PROJECT_ROOT_FROM_SCRIPTS: '"' + (env.installed ? '../../../' : '../') + '"',
        CACHE_ROOT_FROM_SCRIPTS: '"' + (env.installed ? '../../../node_modules/.app-framework-cache/' : '../node_modules/.app-framework-cache/') + '"',
        USE_GLOBAL_DATA_OBJECT: '"' + env.cfg.useGlobalDataObject + '"',
        FONT_FRAMEWORK7: '"' + env.cfg.useIconFonts.framework7 + '"',
        FONT_MATERIAL: '"' + env.cfg.useIconFonts.material + '"',
        USE_FIREBASE_APP: '"' + (firebaseConfig.authDomain !== '' || firebaseConfig.databaseURL !== '' || firebaseConfig.storageBucket !== '') + '"',
        USE_FIREBASE_AUTH: '"' + (firebaseConfig.authDomain !== '') + '"',
        USE_FIREBASE_DATABASE: '"' + (firebaseConfig.databaseURL !== '') + '"',
        USE_FIREBASE_STORAGE: '"' + (firebaseConfig.storageBucket !== '') + '"',
        FONT_ION: '"' + env.cfg.useIconFonts.ion + '"',
        FONT_AWESOME: '"' + env.cfg.useIconFonts.fontawesome + '"',
        RESET_LOCAL_STORAGE: '"' + env.cfg.resetLocalStorageOnVersionChange + '"',
        NODE_ENV: '"' + mode + '"',
        DEV_BUILD: '"' + (env.arg.dev === true) + '"'
      }
    })
  )

  // Optimize ordering, reduce size
  config.plugins.push(new webpack.optimize.OccurrenceOrderPlugin())

  // Avoid exit with error in CLI
  if (mode === 'development') {
    config.plugins.push(new webpack.NoErrorsPlugin())
  }

  // Add hot file reload in development mode
  if (mode === 'development') {
    config.entry['app'].unshift(abs(__dirname, '../lib/dev-client.js'))
    config.plugins.push(new webpack.HotModuleReplacementPlugin())
  }

  // Extract CSS code to extra file
  if (mode === 'production') {
    config.plugins.push(
      new ExtractTextPlugin('[name].[hash:7].css')
    )
    config.vue = {
      loaders: {
        css: ExtractTextPlugin.extract('vue-style-loader', 'css-loader' + (env.cfg.buildSourcemaps === true ? '?sourceMap' : ''))
      }
    }
  }

  // Define icon tags for production
  let iconTags = ''
  if (mode === 'production') {
    iconTags = '<meta name="theme-color" content="' + env.cfg.iconBackgroundColor + '" />' +
               '<link rel="apple-touch-icon" sizes="180x180" href="apple-touch-icon.png" />' +
               '<link rel="icon" type="image/png" href="favicon-32x32.png" sizes="32x32" />' +
               '<link rel="icon" type="image/png" href="favicon-16x16.png" sizes="16x16" />' +
               '<link rel="manifest" href="manifest.json" />'
  } else {
    iconTags = ''
  }

  // Plugin: HTML index file generation
  let HtmlPlugin = require('html-webpack-plugin')
  config.plugins.push(
    new HtmlPlugin({
      filename: mode === 'development' ? abs(env.app, 'index.html') : abs(env.cache, 'build/www/index.html'),
      template: abs(__dirname, '../index.ejs'),
      title: env.cfg.title,
      iconTags: iconTags, // favicon.ico will be loaded by browser default from root directory
      manifest: mode === 'production' ? ' manifest="manifest.appcache"' : '',
      inject: true,
      minify: mode === 'production' ? {
        removeComments: true,
        collapseWhitespace: true,
        removeAttributeQuotes: true
      } : undefined
    })
  )

  // Add source maps
  if (mode === 'development') {
    config.devtool = '#source-map'
  } else if (mode === 'production' && env.cfg.buildSourcemaps === true) {
    config.devtool = '#source-map'
  } else {
    config.devtool = undefined
  }

  // Add JS compression
  if (mode === 'production') {
    config.plugins.push(
      new webpack.optimize.UglifyJsPlugin({
        compress: {
          warnings: false
        }
      })
    )
  }

  // Add cache manifest
  if (mode === 'production') {
    let AppCachePlugin = require('appcache-webpack-plugin')
    config.plugins.push(
      new AppCachePlugin({
        cache: null,
        network: ['*'],
        fallback: null,
        settings: null,
        exclude: [/\.(js|css)\.map$/],
        output: 'manifest.appcache'
      })
    )
  }

  // Return object
  return config
}

// Export configuration
module.exports = {
  development: createConfiguration('development'),
  production: createConfiguration('production')
}
<commit_msg>Include entire app directory in babel loader<commit_after>/* Purpose: Export development and production webpack configuration objects */

'use strict'

// Load modules
let env = require('../env')
let alert = require('../lib/alert')
let fs = require('fs-extra')
let abs = require('path').resolve
let us = require('underscore')
let webpack = require('webpack')

// Empty cache folder
fs.emptyDirSync(abs(env.cache, 'build'))

// Create configuration
let createConfiguration = function (mode) {
  // Check mode
  if (mode !== 'development' && mode !== 'production') {
    alert('Webpack configuration needs "production" or "development" as parameter.', 'issue')
  }

  // Define loaders
  let ExtractTextPlugin = require('extract-text-webpack-plugin')
  let loaders = [
    // JS files
    {
      test: /\.js$/,
      loader: 'babel',
      include: [
        abs(__dirname, '../lib'),
        abs(__dirname, '../scripts'),
        abs(env.app)
      ]
    },
    // Vue files
    {
      test: /\.vue$/,
      loader: 'vue'
    },
    // JSON files
    {
      test: /\.json$/,
      loader: 'json'
    },
    // CSS files
    {
      test: /\.css$/,
      loader: mode === 'development' ? 'vue-style-loader!css-loader' : ExtractTextPlugin.extract('css-loader' + (env.cfg.buildSourcemaps === true ? '?sourceMap' : ''))
    },
    // Image files
    {
      test: /\.(png|jpe?g|gif)(\?.*)?$/,
      loader: 'url',
      query: {
        limit: 1,
        name: 'img/[name].[hash:7].[ext]'
      }
    },
    // Favicon
    {
      test: /favicon\.ico$/,
      loader: 'url',
      query: {
        limit: 1,
        name: '[name].[ext]'
      }
    },
    // Font files
    {
      test: /\.(woff2?|eot|ttf|otf|svg)(\?.*)?$/,
      loader: 'url',
      query: {
        limit: 1,
        name: 'fonts/[name].[hash:7].[ext]'
      }
    }
  ]

  // Start configuration object
  let config = {
    entry: {
      app: [abs(__dirname, '../lib/app.js')]
    },
    output: {
      path: mode === 'development' ? abs(env.app) : abs(env.cache, 'build/www'),
      filename: '[name].[hash:7].js'
    },
    resolve: {
      extensions: ['', '.js', '.vue', '.json'],
      alias: {
        'vue$': 'vue/dist/vue.common.js'
      }
    },
    module: {
      loaders: loaders
    },
    plugins: []
  }

  // Add themes on production build
  if (mode === 'production') {
    if (env.cfg.theme === 'ios-material' || env.cfg.theme === 'material-ios') {
      config.entry = us.extend({
        ios: [abs(__dirname, '../lib/ios.js')],
        material: [abs(__dirname, '../lib/material.js')]
      }, config.entry)
    } else {
      config.entry.app.unshift(abs(__dirname, '../lib/' + env.cfg.theme + '.js'))
    }
  }

  // Add environment variables
  let firebaseConfig = mode === 'production' ? env.cfg.firebase : env.cfg.devFirebase
  config.plugins.push(
    new webpack.DefinePlugin({
      'process.env': {
        THEME: '"' + env.cfg.theme + '"',
        APP_ROOT_FROM_SCRIPTS: '"' + (env.installed ? '../../../app/' : '../app/') + '"',
        PROJECT_ROOT_FROM_SCRIPTS: '"' + (env.installed ? '../../../' : '../') + '"',
        CACHE_ROOT_FROM_SCRIPTS: '"' + (env.installed ? '../../../node_modules/.app-framework-cache/' : '../node_modules/.app-framework-cache/') + '"',
        USE_GLOBAL_DATA_OBJECT: '"' + env.cfg.useGlobalDataObject + '"',
        FONT_FRAMEWORK7: '"' + env.cfg.useIconFonts.framework7 + '"',
        FONT_MATERIAL: '"' + env.cfg.useIconFonts.material + '"',
        USE_FIREBASE_APP: '"' + (firebaseConfig.authDomain !== '' || firebaseConfig.databaseURL !== '' || firebaseConfig.storageBucket !== '') + '"',
        USE_FIREBASE_AUTH: '"' + (firebaseConfig.authDomain !== '') + '"',
        USE_FIREBASE_DATABASE: '"' + (firebaseConfig.databaseURL !== '') + '"',
        USE_FIREBASE_STORAGE: '"' + (firebaseConfig.storageBucket !== '') + '"',
        FONT_ION: '"' + env.cfg.useIconFonts.ion + '"',
        FONT_AWESOME: '"' + env.cfg.useIconFonts.fontawesome + '"',
        RESET_LOCAL_STORAGE: '"' + env.cfg.resetLocalStorageOnVersionChange + '"',
        NODE_ENV: '"' + mode + '"',
        DEV_BUILD: '"' + (env.arg.dev === true) + '"'
      }
    })
  )

  // Optimize ordering, reduce size
  config.plugins.push(new webpack.optimize.OccurrenceOrderPlugin())

  // Avoid exit with error in CLI
  if (mode === 'development') {
    config.plugins.push(new webpack.NoErrorsPlugin())
  }

  // Add hot file reload in development mode
  if (mode === 'development') {
    config.entry['app'].unshift(abs(__dirname, '../lib/dev-client.js'))
    config.plugins.push(new webpack.HotModuleReplacementPlugin())
  }

  // Extract CSS code to extra file
  if (mode === 'production') {
    config.plugins.push(
      new ExtractTextPlugin('[name].[hash:7].css')
    )
    config.vue = {
      loaders: {
        css: ExtractTextPlugin.extract('vue-style-loader', 'css-loader' + (env.cfg.buildSourcemaps === true ? '?sourceMap' : ''))
      }
    }
  }

  // Define icon tags for production
  let iconTags = ''
  if (mode === 'production') {
    iconTags = '<meta name="theme-color" content="' + env.cfg.iconBackgroundColor + '" />' +
               '<link rel="apple-touch-icon" sizes="180x180" href="apple-touch-icon.png" />' +
               '<link rel="icon" type="image/png" href="favicon-32x32.png" sizes="32x32" />' +
               '<link rel="icon" type="image/png" href="favicon-16x16.png" sizes="16x16" />' +
               '<link rel="manifest" href="manifest.json" />'
  } else {
    iconTags = ''
  }

  // Plugin: HTML index file generation
  let HtmlPlugin = require('html-webpack-plugin')
  config.plugins.push(
    new HtmlPlugin({
      filename: mode === 'development' ? abs(env.app, 'index.html') : abs(env.cache, 'build/www/index.html'),
      template: abs(__dirname, '../index.ejs'),
      title: env.cfg.title,
      iconTags: iconTags, // favicon.ico will be loaded by browser default from root directory
      manifest: mode === 'production' ? ' manifest="manifest.appcache"' : '',
      inject: true,
      minify: mode === 'production' ? {
        removeComments: true,
        collapseWhitespace: true,
        removeAttributeQuotes: true
      } : undefined
    })
  )

  // Add source maps
  if (mode === 'development') {
    config.devtool = '#source-map'
  } else if (mode === 'production' && env.cfg.buildSourcemaps === true) {
    config.devtool = '#source-map'
  } else {
    config.devtool = undefined
  }

  // Add JS compression
  if (mode === 'production') {
    config.plugins.push(
      new webpack.optimize.UglifyJsPlugin({
        compress: {
          warnings: false
        }
      })
    )
  }

  // Add cache manifest
  if (mode === 'production') {
    let AppCachePlugin = require('appcache-webpack-plugin')
    config.plugins.push(
      new AppCachePlugin({
        cache: null,
        network: ['*'],
        fallback: null,
        settings: null,
        exclude: [/\.(js|css)\.map$/],
        output: 'manifest.appcache'
      })
    )
  }

  // Return object
  return config
}

// Export configuration
module.exports = {
  development: createConfiguration('development'),
  production: createConfiguration('production')
}
<|endoftext|>


<commit_before>'use strict';

const path                     = require('path');
const Dotenv                   = require('dotenv-webpack');
const HtmlWebpackPlugin        = require('html-webpack-plugin');
const BundleAnalyzerPlugin     = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
const FlowStatusWebpackPlugin  = require('flow-status-webpack-plugin');
const CaseSensitivePathsPlugin = require('case-sensitive-paths-webpack-plugin');
const babelrc                  = require('../babel/babelrc');
const addCssRule               = require('./css');

function common(config) {
  const {
    js, css, html,
    dev, prod
  } = config;

  const base = {
    bail  : true,
    target: 'web',
    module: {
      rules: [
        {
          test: /\.js|jsx$/,
          use : {
            loader : 'babel-loader',
            options: babelrc(js)
          },
          exclude: path.join(process.cwd(), 'node_modules')
        },
        {
          test: /\.(png|jpg|jpeg|gif|svg|ttf|woff2?)$/,
          use : process.env.NODE_ENV === 'production' && prod.url ?
            'url-loader' : 'file-loader'
        }
      ]
    },
    plugins: [
      new CaseSensitivePathsPlugin(),
      new Dotenv({
        path: path.join(process.cwd(), (
          process.env.NODE_ENV === 'production' ? prod.env : dev.env
        ) || '.env')
      })
    ]
  };

  if (html.filename && html.template) {
    base.plugins.push(new HtmlWebpackPlugin({
      filename: html.filename,
      template: html.template
    }));
  }
  else {
    base.plugins.push(new HtmlWebpackPlugin());
  }

  if (dev.analyzer && process.env.NODE_ENV !== 'production') {
    base.plugins.push(new BundleAnalyzerPlugin());
  }

  if (js.flow) {
    base.plugins.push(new FlowStatusWebpackPlugin({
      flowArgs   : `--from ${process.cwd()}`,
      failOnError: true
    }));
  }

  return addCssRule(base, prod.extract, css.modules, css.postcss);
};

module.exports = common;
<commit_msg>fix(webpack): add systemvars to dotenv<commit_after>'use strict';

const path                     = require('path');
const Dotenv                   = require('dotenv-webpack');
const HtmlWebpackPlugin        = require('html-webpack-plugin');
const BundleAnalyzerPlugin     = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
const FlowStatusWebpackPlugin  = require('flow-status-webpack-plugin');
const CaseSensitivePathsPlugin = require('case-sensitive-paths-webpack-plugin');
const babelrc                  = require('../babel/babelrc');
const addCssRule               = require('./css');

function common(config) {
  const {
    js, css, html,
    dev, prod
  } = config;

  const base = {
    bail  : true,
    target: 'web',
    module: {
      rules: [
        {
          test: /\.js|jsx$/,
          use : {
            loader : 'babel-loader',
            options: babelrc(js)
          },
          exclude: path.join(process.cwd(), 'node_modules')
        },
        {
          test: /\.(png|jpg|jpeg|gif|svg|ttf|woff2?)$/,
          use : process.env.NODE_ENV === 'production' && prod.url ?
            'url-loader' : 'file-loader'
        }
      ]
    },
    plugins: [
      new CaseSensitivePathsPlugin(),
      new Dotenv({
        path: path.join(process.cwd(), (
          process.env.NODE_ENV === 'production' ? prod.env : dev.env
        ) || '.env'),
        systemvars: true
      })
    ]
  };

  if (html.filename && html.template) {
    base.plugins.push(new HtmlWebpackPlugin({
      filename: html.filename,
      template: html.template
    }));
  }
  else {
    base.plugins.push(new HtmlWebpackPlugin());
  }

  if (dev.analyzer && process.env.NODE_ENV !== 'production') {
    base.plugins.push(new BundleAnalyzerPlugin());
  }

  if (js.flow) {
    base.plugins.push(new FlowStatusWebpackPlugin({
      flowArgs   : `--from ${process.cwd()}`,
      failOnError: true
    }));
  }

  return addCssRule(base, prod.extract, css.modules, css.postcss);
};

module.exports = common;
<|endoftext|>


<commit_before>/*
 * logger.js: Core logger object used by winston.
 *
 * (C) 2010 Charlie Robbins
 * MIT LICENCE
 *
 */

var events = require('events'),
    util = require('util'),
    async = require('async'),
    config = require('./config'),
    common = require('./common'),
    exception = require('./exception');

//
// Time constants
//
var ticksPerMillisecond = 10000;

//
// ### function Logger (options)
// #### @options {Object} Options for this instance.
// Constructor function for the Logger object responsible
// for persisting log messages and metadata to one or more transports.
//
var Logger = exports.Logger = function (options) {
  events.EventEmitter.call(this);
  options = options || {};

  var self = this,
      handleExceptions = false;

  //
  // Set Levels and default logging level
  //
  this.padLevels = options.padLevels || false;
  this.setLevels(options.levels);

  //
  // Setup other intelligent default settings.
  //
  this.level             = options.level || 'info';
  this.emitErrs          = options.emitErrs || false;
  this.stripColors       = options.stripColors || false;
  this.transports        = {};
  this.exceptionHandlers = {};
  this.profilers         = {};
  this._names            = [];
  this._hnames           = [];

  if (options.transports) {
    options.transports.forEach(function (transport) {
      self.add(transport, null, true);

      if (transport.handleExceptions) {
        handleExceptions = true;
      }
    });
  }

  if (options.exceptionHandlers) {
    options.exceptionHandlers.forEach(function (handler) {
      self._hnames.push(handler.name);
      self.exceptionHandlers[handler.name] = handler;
    });
  }

  if (options.handleExceptions || handleExceptions) {
    this.handleExceptions();
  }
};

//
// Inherit from `events.EventEmitter`.
//
util.inherits(Logger, events.EventEmitter);

//
// ### function extend (target)
// #### @target {Object} Target to extend.
// Extends the target object with a 'log' method
// along with a method for each level in this instance.
//
Logger.prototype.extend = function (target) {
  var self = this;
  ['log', 'profile'].concat(Object.keys(this.levels)).forEach(function (method) {
    target[method] = function () {
      return self[method].apply(self, arguments);
    };
  });

  return this;
};

//
// ### function log (level, msg, [meta], callback)
// #### @level {string} Level at which to log the message.
// #### @msg {string} Message to log
// #### @meta {Object} **Optional** Additional metadata to attach
// #### @callback {function} Continuation to respond to when complete.
// Core logging method exposed to Winston. Metadata is optional.
//
Logger.prototype.log = function (level, msg) {
  var self = this,
      callback,
      meta;

  if (arguments.length === 3) {
    if (typeof arguments[2] === 'function') {
      meta = {};
      callback = arguments[2];
    }
    else if (typeof arguments[2] === 'object') {
      meta = arguments[2];
    }
  }
  else if (arguments.length === 4) {
    meta = arguments[2];
    callback = arguments[3];
  }

  // If we should pad for levels, do so
  if (this.padLevels) {
    msg = new Array(this.levelLength - level.length).join(' ') + msg;
  }

  function onError (err) {
    if (callback) {
      callback(err);
    }
    else if (self.emitErrs) {
      self.emit('error', err);
    };
  }

  if (this.transports.length === 0) {
    return onError(new Error('Cannot log with no transports.'));
  }
  else if (typeof self.levels[level] === 'undefined') {
    return onError(new Error('Unknown log level: ' + level));
  }

  //
  // For consideration of terminal 'color" programs like colors.js,
  // which can add ANSI escape color codes to strings, we destyle the
  // ANSI color escape codes when `this.stripColors` is set.
  //
  // see: http://en.wikipedia.org/wiki/ANSI_escape_code
  //
  if (this.stripColors) {
    var code = /\u001b\[\d+m/g;
    msg = ('' + msg).replace(code, '');
  }

  for (var i = 0, l = this._names.length; i < l; i++) {
    var transport = this.transports[this._names[i]];
    if ((transport.level && self.levels[transport.level] <= self.levels[level])
      || (!transport.level && self.levels[self.level] <= self.levels[level])) {
      transport.log(level, msg, meta, function (err) {
        self.emit('logging', transport, level, msg, meta);
      });
    }
  }

  //
  // Immediately respond to the callback
  //
  if (callback) {
    callback(null, level, msg, meta);
  }

  return this;
};

//
// ### function close ()
// Cleans up resources (streams, event listeners) for all
// transports associated with this instance (if necessary).
//
Logger.prototype.close = function () {
  var self = this;

  this._names.forEach(function (name) {
    var transport = self.transports[name];
    if (transport && transport.close) {
      transport.close();
    }
  });
};

//
// ### function handleExceptions ()
// Handles `uncaughtException` events for the current process
//
Logger.prototype.handleExceptions = function () {
  var args = Array.prototype.slice.call(arguments),
      handlers = [],
      self = this;

  args.forEach(function (a) {
    if (Array.isArray(a)) {
      handlers = handlers.concat(a);
    }
    else {
      handlers.push(a);
    }
  });

  handlers.forEach(function (handler) {
    self.exceptionHandlers[handler.name] = handler;
  });

  this._hnames = Object.keys(self.exceptionHandlers);

  if (!this.catchExceptions) {
    this.catchExceptions = this._uncaughtException.bind(this);
    process.on('uncaughtException', this.catchExceptions);
  }
};

//
// ### function unhandleExceptions ()
// Removes any handlers to `uncaughtException` events
// for the current process
//
Logger.prototype.unhandleExceptions = function () {
  var self = this;

  if (this.catchExceptions) {
    Object.keys(this.exceptionHandlers).forEach(function (name) {
      if (handler.close) {
        handler.close();
      }
    });

    this.exceptionHandlers = {};
    Object.keys(this.transports).forEach(function (name) {
      var transport = self.transports[name];
      if (transport.handleExceptions) {
        transport.handleExceptions = false;
      }
    })

    process.removeListener('uncaughtException', this.catchExceptions);
    this.catchExceptions = false;
  }
};

//
// ### function add (transport, [options])
// #### @transport {Transport} Prototype of the Transport object to add.
// #### @options {Object} **Optional** Options for the Transport to add.
// #### @instance {Boolean} **Optional** Value indicating if `transport` is already instantiated.
// Adds a transport of the specified type to this instance.
//
Logger.prototype.add = function (transport, options, created) {
  var instance = created ? transport : (new (transport)(options));

  if (!instance.name && !instance.log) {
    throw new Error('Unknown transport with no log() method');
  }
  else if (this.transports[instance.name]) {
    throw new Error('Transport already attached: ' + instance.name);
  }

  this.transports[instance.name] = instance;
  this._names = Object.keys(this.transports);

  //
  // Listen for the `error` event on the new Transport
  //
  instance._onError = this._onError.bind(this, instance)
  instance.on('error', instance._onError);

  return this;
};

//
// ### function remove (transport)
// #### @transport {Transport} Transport to remove.
// Removes a transport of the specified type from this instance.
//
Logger.prototype.remove = function (transport) {
  var name = transport.name || transport.prototype.name;

  if (!this.transports[name]) {
    throw new Error('Transport ' + name + ' not attached to this instance');
  }

  var instance = this.transports[name];
  delete this.transports[name];
  this._names = Object.keys(this.transports);

  if (instance.close) {
    instance.close();
  }

  instance.removeListener('error', instance._onError);
  return this;
};

//
// ### function profile (id, [msg, meta, callback])
// #### @id {string} Unique id of the profiler
// #### @msg {string} **Optional** Message to log
// #### @meta {Object} **Optional** Additional metadata to attach
// #### @callback {function} **Optional** Continuation to respond to when complete.
// Tracks the time inbetween subsequent calls to this method
// with the same `id` parameter. The second call to this method
// will log the difference in milliseconds along with the message.
//
Logger.prototype.profile = function (id) {
  var now = Date.now(), then, args,
      msg, meta, callback;

  if (this.profilers[id] && arguments.length !== 1) {
    then = this.profilers[id];
    delete this.profilers[id];

    // Support variable arguments: msg, meta, callback
    args     = Array.prototype.slice.call(arguments);
    callback = typeof args[args.length - 1] === 'function' ? args.pop() : null;
    meta     = typeof args[args.length - 1] === 'object' ? args.pop() : {};
    msg      = args.length === 2 ? args[1] : id;

    // Set the duration property of the metadata
    meta.duration = now - then + 'ms';
    return this.info(msg, meta, callback);
  }
  else {
    this.profilers[id] = now;
  }

  return this;
};

//
// ### function setLevels (target)
// #### @target {Object} Target levels to use on this instance
// Sets the `target` levels specified on this instance.
//
Logger.prototype.setLevels = function (target) {
  return common.setLevels(this, this.levels, target);
};

//
// ### function cli ()
// Configures this instance to have the default
// settings for command-line interfaces: no timestamp,
// colors enabled, padded output, and additional levels.
//
Logger.prototype.cli = function () {
  this.padLevels = true;
  this.setLevels(config.cli.levels);
  config.addColors(config.cli.colors);

  if (this.transports.console) {
    this.transports.console.colorize = true;
    this.transports.console.timestamp = false;
  }

  return this;
};

//
// ### @private function _uncaughtException (err)
// #### @err {Error} Error to handle
// Logs all relevant information around the `err` and
// exits the current process.
//
Logger.prototype._uncaughtException = function (err) {
  var self = this,
      responded = false,
      info = exception.getAllInfo(err),
      handlers = this._getExceptionHandlers(),
      timeout;

  function logAndWait (transport, next) {
    transport.logException('uncaughtException', info, next);
  }

  function gracefulExit () {
    if (!responded) {
      //
      // Remark: Currently ignoring any exceptions from transports
      //         when catching uncaught exceptions.
      //
      clearTimeout(timeout);
      responded = true;
      process.exit(1);
    }
  }

  if (!handlers || handlers.length === 0) {
    return gracefulExit();
  }

  //
  // Log to all transports and allow the operation to take
  // only up to `3000ms`.
  //
  async.forEach(handlers, logAndWait, gracefulExit);
  timeout = setTimeout(gracefulExit, 3000);
};

//
// ### @private function _getExceptionHandlers ()
// Returns the list of transports and exceptionHandlers
// for this instance.
//
Logger.prototype._getExceptionHandlers = function () {
  var self = this;

  return this._hnames.map(function (name) {
    return self.exceptionHandlers[name];
  }).concat(this._names.map(function (name) {
    return self.transports[name].handleExceptions && self.transports[name];
  })).filter(Boolean);
};

//
// ### @private function _onError (transport, err)
// #### @transport {Object} Transport on which the error occured
// #### @err {Error} Error that occurred on the transport
// Bubbles the error, `err`, that occured on the specified `transport`
// up from this instance if `emitErrs` has been set.
//
Logger.prototype._onError = function (transport, err) {
  if (this.emitErrs) {
    this.emit('error', err, transport);
  }
};<commit_msg>[fix] Automatically call `.addColors()` if colors option is passed to `winston.Logger`. Fixes #41<commit_after>/*
 * logger.js: Core logger object used by winston.
 *
 * (C) 2010 Charlie Robbins
 * MIT LICENCE
 *
 */

var events = require('events'),
    util = require('util'),
    async = require('async'),
    config = require('./config'),
    common = require('./common'),
    exception = require('./exception');

//
// Time constants
//
var ticksPerMillisecond = 10000;

//
// ### function Logger (options)
// #### @options {Object} Options for this instance.
// Constructor function for the Logger object responsible
// for persisting log messages and metadata to one or more transports.
//
var Logger = exports.Logger = function (options) {
  events.EventEmitter.call(this);
  options = options || {};

  var self = this,
      handleExceptions = false;

  //
  // Set Levels and default logging level
  //
  this.padLevels = options.padLevels || false;
  this.setLevels(options.levels);
  if (options.colors) {
    config.addColors(options.colors);
  }

  //
  // Setup other intelligent default settings.
  //
  this.level             = options.level || 'info';
  this.emitErrs          = options.emitErrs || false;
  this.stripColors       = options.stripColors || false;
  this.transports        = {};
  this.exceptionHandlers = {};
  this.profilers         = {};
  this._names            = [];
  this._hnames           = [];

  if (options.transports) {
    options.transports.forEach(function (transport) {
      self.add(transport, null, true);

      if (transport.handleExceptions) {
        handleExceptions = true;
      }
    });
  }

  if (options.exceptionHandlers) {
    options.exceptionHandlers.forEach(function (handler) {
      self._hnames.push(handler.name);
      self.exceptionHandlers[handler.name] = handler;
    });
  }

  if (options.handleExceptions || handleExceptions) {
    this.handleExceptions();
  }
};

//
// Inherit from `events.EventEmitter`.
//
util.inherits(Logger, events.EventEmitter);

//
// ### function extend (target)
// #### @target {Object} Target to extend.
// Extends the target object with a 'log' method
// along with a method for each level in this instance.
//
Logger.prototype.extend = function (target) {
  var self = this;
  ['log', 'profile'].concat(Object.keys(this.levels)).forEach(function (method) {
    target[method] = function () {
      return self[method].apply(self, arguments);
    };
  });

  return this;
};

//
// ### function log (level, msg, [meta], callback)
// #### @level {string} Level at which to log the message.
// #### @msg {string} Message to log
// #### @meta {Object} **Optional** Additional metadata to attach
// #### @callback {function} Continuation to respond to when complete.
// Core logging method exposed to Winston. Metadata is optional.
//
Logger.prototype.log = function (level, msg) {
  var self = this,
      callback,
      meta;

  if (arguments.length === 3) {
    if (typeof arguments[2] === 'function') {
      meta = {};
      callback = arguments[2];
    }
    else if (typeof arguments[2] === 'object') {
      meta = arguments[2];
    }
  }
  else if (arguments.length === 4) {
    meta = arguments[2];
    callback = arguments[3];
  }

  // If we should pad for levels, do so
  if (this.padLevels) {
    msg = new Array(this.levelLength - level.length).join(' ') + msg;
  }

  function onError (err) {
    if (callback) {
      callback(err);
    }
    else if (self.emitErrs) {
      self.emit('error', err);
    };
  }

  if (this.transports.length === 0) {
    return onError(new Error('Cannot log with no transports.'));
  }
  else if (typeof self.levels[level] === 'undefined') {
    return onError(new Error('Unknown log level: ' + level));
  }

  //
  // For consideration of terminal 'color" programs like colors.js,
  // which can add ANSI escape color codes to strings, we destyle the
  // ANSI color escape codes when `this.stripColors` is set.
  //
  // see: http://en.wikipedia.org/wiki/ANSI_escape_code
  //
  if (this.stripColors) {
    var code = /\u001b\[\d+m/g;
    msg = ('' + msg).replace(code, '');
  }

  for (var i = 0, l = this._names.length; i < l; i++) {
    var transport = this.transports[this._names[i]];
    if ((transport.level && self.levels[transport.level] <= self.levels[level])
      || (!transport.level && self.levels[self.level] <= self.levels[level])) {
      transport.log(level, msg, meta, function (err) {
        self.emit('logging', transport, level, msg, meta);
      });
    }
  }

  //
  // Immediately respond to the callback
  //
  if (callback) {
    callback(null, level, msg, meta);
  }

  return this;
};

//
// ### function close ()
// Cleans up resources (streams, event listeners) for all
// transports associated with this instance (if necessary).
//
Logger.prototype.close = function () {
  var self = this;

  this._names.forEach(function (name) {
    var transport = self.transports[name];
    if (transport && transport.close) {
      transport.close();
    }
  });
};

//
// ### function handleExceptions ()
// Handles `uncaughtException` events for the current process
//
Logger.prototype.handleExceptions = function () {
  var args = Array.prototype.slice.call(arguments),
      handlers = [],
      self = this;

  args.forEach(function (a) {
    if (Array.isArray(a)) {
      handlers = handlers.concat(a);
    }
    else {
      handlers.push(a);
    }
  });

  handlers.forEach(function (handler) {
    self.exceptionHandlers[handler.name] = handler;
  });

  this._hnames = Object.keys(self.exceptionHandlers);

  if (!this.catchExceptions) {
    this.catchExceptions = this._uncaughtException.bind(this);
    process.on('uncaughtException', this.catchExceptions);
  }
};

//
// ### function unhandleExceptions ()
// Removes any handlers to `uncaughtException` events
// for the current process
//
Logger.prototype.unhandleExceptions = function () {
  var self = this;

  if (this.catchExceptions) {
    Object.keys(this.exceptionHandlers).forEach(function (name) {
      if (handler.close) {
        handler.close();
      }
    });

    this.exceptionHandlers = {};
    Object.keys(this.transports).forEach(function (name) {
      var transport = self.transports[name];
      if (transport.handleExceptions) {
        transport.handleExceptions = false;
      }
    })

    process.removeListener('uncaughtException', this.catchExceptions);
    this.catchExceptions = false;
  }
};

//
// ### function add (transport, [options])
// #### @transport {Transport} Prototype of the Transport object to add.
// #### @options {Object} **Optional** Options for the Transport to add.
// #### @instance {Boolean} **Optional** Value indicating if `transport` is already instantiated.
// Adds a transport of the specified type to this instance.
//
Logger.prototype.add = function (transport, options, created) {
  var instance = created ? transport : (new (transport)(options));

  if (!instance.name && !instance.log) {
    throw new Error('Unknown transport with no log() method');
  }
  else if (this.transports[instance.name]) {
    throw new Error('Transport already attached: ' + instance.name);
  }

  this.transports[instance.name] = instance;
  this._names = Object.keys(this.transports);

  //
  // Listen for the `error` event on the new Transport
  //
  instance._onError = this._onError.bind(this, instance)
  instance.on('error', instance._onError);

  return this;
};

//
// ### function remove (transport)
// #### @transport {Transport} Transport to remove.
// Removes a transport of the specified type from this instance.
//
Logger.prototype.remove = function (transport) {
  var name = transport.name || transport.prototype.name;

  if (!this.transports[name]) {
    throw new Error('Transport ' + name + ' not attached to this instance');
  }

  var instance = this.transports[name];
  delete this.transports[name];
  this._names = Object.keys(this.transports);

  if (instance.close) {
    instance.close();
  }

  instance.removeListener('error', instance._onError);
  return this;
};

//
// ### function profile (id, [msg, meta, callback])
// #### @id {string} Unique id of the profiler
// #### @msg {string} **Optional** Message to log
// #### @meta {Object} **Optional** Additional metadata to attach
// #### @callback {function} **Optional** Continuation to respond to when complete.
// Tracks the time inbetween subsequent calls to this method
// with the same `id` parameter. The second call to this method
// will log the difference in milliseconds along with the message.
//
Logger.prototype.profile = function (id) {
  var now = Date.now(), then, args,
      msg, meta, callback;

  if (this.profilers[id] && arguments.length !== 1) {
    then = this.profilers[id];
    delete this.profilers[id];

    // Support variable arguments: msg, meta, callback
    args     = Array.prototype.slice.call(arguments);
    callback = typeof args[args.length - 1] === 'function' ? args.pop() : null;
    meta     = typeof args[args.length - 1] === 'object' ? args.pop() : {};
    msg      = args.length === 2 ? args[1] : id;

    // Set the duration property of the metadata
    meta.duration = now - then + 'ms';
    return this.info(msg, meta, callback);
  }
  else {
    this.profilers[id] = now;
  }

  return this;
};

//
// ### function setLevels (target)
// #### @target {Object} Target levels to use on this instance
// Sets the `target` levels specified on this instance.
//
Logger.prototype.setLevels = function (target) {
  return common.setLevels(this, this.levels, target);
};

//
// ### function cli ()
// Configures this instance to have the default
// settings for command-line interfaces: no timestamp,
// colors enabled, padded output, and additional levels.
//
Logger.prototype.cli = function () {
  this.padLevels = true;
  this.setLevels(config.cli.levels);
  config.addColors(config.cli.colors);

  if (this.transports.console) {
    this.transports.console.colorize = true;
    this.transports.console.timestamp = false;
  }

  return this;
};

//
// ### @private function _uncaughtException (err)
// #### @err {Error} Error to handle
// Logs all relevant information around the `err` and
// exits the current process.
//
Logger.prototype._uncaughtException = function (err) {
  var self = this,
      responded = false,
      info = exception.getAllInfo(err),
      handlers = this._getExceptionHandlers(),
      timeout;

  function logAndWait (transport, next) {
    transport.logException('uncaughtException', info, next);
  }

  function gracefulExit () {
    if (!responded) {
      //
      // Remark: Currently ignoring any exceptions from transports
      //         when catching uncaught exceptions.
      //
      clearTimeout(timeout);
      responded = true;
      process.exit(1);
    }
  }

  if (!handlers || handlers.length === 0) {
    return gracefulExit();
  }

  //
  // Log to all transports and allow the operation to take
  // only up to `3000ms`.
  //
  async.forEach(handlers, logAndWait, gracefulExit);
  timeout = setTimeout(gracefulExit, 3000);
};

//
// ### @private function _getExceptionHandlers ()
// Returns the list of transports and exceptionHandlers
// for this instance.
//
Logger.prototype._getExceptionHandlers = function () {
  var self = this;

  return this._hnames.map(function (name) {
    return self.exceptionHandlers[name];
  }).concat(this._names.map(function (name) {
    return self.transports[name].handleExceptions && self.transports[name];
  })).filter(Boolean);
};

//
// ### @private function _onError (transport, err)
// #### @transport {Object} Transport on which the error occured
// #### @err {Error} Error that occurred on the transport
// Bubbles the error, `err`, that occured on the specified `transport`
// up from this instance if `emitErrs` has been set.
//
Logger.prototype._onError = function (transport, err) {
  if (this.emitErrs) {
    this.emit('error', err, transport);
  }
};<|endoftext|>


<commit_before>//
//  match-js
//  A simple yet powerful pattern matching library for Javascript.
//
//  Read readme.md for instructions and LICENSE license.
//
//  Copyright (c) 2009 Johan Dahlberg
//
var Match = (function() {
    var NO_MATCH = { __matchtype__: 'no-match', toString: function() { return 'no-match' }};
    var TYPE_RE = /function\s([A-Za-z_1-9$]+)/;;

    function is_prim_type(obj) {
        return obj == String || obj == Number || obj == Date || obj == Boolean
    }

    function is_empty(value) {
        return value == null || value == undefined;
    }

    function get_resolver(obj) {
        var ctor;

        // Check if we got an instance __compare__ method (most valuable)
        if(obj && obj['__compare__']) return function(value) {
            return obj.__compare__(value);
        }

        // Check if we got an instance __equals__ method (most second most
        // valuable)
        else if(obj && obj['__equals__']) return function(value) {
            if(obj.__equals__(value)) return [value];
            throw NO_MATCH;
        }

        // Check if the instance constructor class has an __compare__ method.
        else if(obj && obj.constructor && obj.constructor['__compare__']) return function(value) {
            return obj.constructor.__compare__(obj, value);
        }

        // Check if the instance constructor class has an __equals__ method.
        else if(obj && obj.constructor && obj.constructor['__equals__']) return function(value) {
            var comp = obj.constructor.__equals__;
            if(comp(obj, value)) return [value];
            throw NO_MATCH;
        }

        // Check for native type's (Strings, Number and Regexp's)
        else if(is_prim_type(obj)) return function(value) {
            if(is_empty(value) || value.constructor !== obj) throw NO_MATCH;
            return [value];
        }

        // Check for null and undefined types
        else if(is_empty(obj)) return function(value) {
            if(obj !== value) throw NO_MATCH;
            return [value];
        }

        // Didnt match any of the special case resolvers. Find it in
        // the TYPE_RESOLVERS list instead.
        var type_name = TYPE_RE(obj.constructor.toString())[1];
        ctor = TYPE_RESOLVERS[type_name];
        if(!ctor) ctor = TYPE_RESOLVERS['Object'];
        return ctor(obj);
    }

    var TYPE_RESOLVERS = {

        // Function (class constructor) resolver.
        Function: function(ctor) {
            return function(value) {
                if(!value || value.constructor !== ctor) throw NO_MATCH;
                return [value];
            }
        },

        // Array resolver
        Array: function(arr) {
            if(arr.length == 0) {
                return function(value) {
                    if(value.constructor != Array || value.length != 0)
                        throw NO_MATCH;
                }
            } else {
                var resolvers = []
                for(var i = 0; i < arr.length; i++){
                  resolvers[i] = get_resolver(arr[i]);
                }
                return function(value) {
                    var result = [];
                    if(!value || value.constructor != Array) throw NO_MATCH;
                    for(var count=0; count < resolvers.length; count++) {
                        result = result.concat(
                             resolvers[count](value[count])
                        );
                    }
                    return result;
                }
            }
        },

        // Boolean resolver
        Boolean: function(b) {
            return function(value) {
                if(b !== value) throw NO_MATCH;
                return [];
            }
        },

        // Regexp resolver
        RegExp: function(regexp) {
            return function(value) {
                if(!value || !regexp.test(value)) throw NO_MATCH;
                return [];
            }
        },

        // Number resolver
        Number: function(no) {
            return function(value) {
                if(no !== value) throw NO_MATCH;
                return [];
            }
        },

        // String resolver
        String: function(str) {
            return function(value) {
                if(str !== value) throw NO_MATCH;
                return [];
            }
        },

        Object: function(obj) {
            var resolvers = {};
            for(var key in obj) {
                resolvers[key] = get_resolver(obj[key]);
            }
            return function(value) {
                if(value === null || value === undefined) throw NO_MATCH;
                var result = [];
                for(var key in resolvers) {
                    result = result.concat(
                        resolvers[key](value[key])
                    );
                }
                return result;
            }
        }
    }

    var Result = function() {
        var args = Array.prototype.slice.call(arguments);
        var cases = [], default_case;
        while(args.length) {
            var left = args.shift()
            if(left.__matchtype__ == 'matcher') {
                // This is a filter-
                cases.unshift({ filter: left });
            } else if(left.constructor == Function && !args.length) {
                // The ´default´ case. This callback is called when no other
                // case is matching. This MUST be the last argument.
                default_case = left;
            } else {
                var right = args.shift();
                var resolver = get_resolver(left), callback;
                if(right.constructor == Array) {
                    // The right argument is an array. The first argument in the
                    // Array is the callback. The remaining arguments are the
                    // arguments to parse to the callback.
                    var fn = right.shift();
                    callback = function() { return fn.apply(null, right.concat(arguments)) };
                } else if(right.constructor == Function) {
                    callback = right;
                }
                cases.unshift({ resolver: resolver, callback: callback });
            }
        }

        // Matches against defined patterns. The first argument is the object
        // to match agaisnt. The second argument is optional and respresent the
        // value that is return if no pattern was matched.
        var Matcher = function(orig, nomatch_res) {
            var l = cases.length,
                errors = [],
                obj = orig,
                nomatch = nomatch_res || undefined; // undefined is default
            while(l-- > 0) {
                var c = cases[l]
                if(c.resolver) {
                    try {
                        var result = c.resolver(obj);
                    } catch(ex) {
                        if(ex == NO_MATCH) continue;
                        throw ex;
                    }
                    // We got a match! Concat the result array with the
                    // (filtered) object and the original object.
                    return c.callback.apply(this, result.concat([obj, orig]));
                } else if(c.filter){
                    // Run the object through the provided filter.
                    obj = c.filter(obj);
                }
            }

            // Check if a default case is defined.
            if(default_case) default_case.apply(this, [obj, orig]);

            // No pattern was matched. Return the default nomatch value.
            else return nomatch;
        };

        // Identify the new matcher as a Matcher
        Matcher.__matchtype__ = 'matcher';

        // Return the Matcher.
        return Matcher;
    }

    // A comparer that ignores a value in the pattern
    var pass = {
        __compare__: function(value) {
            return [];
        }
    }

    // A comparer that includes a value without matching.
    var incl = {
        __compare__: function(value) {
            return [value];
        }
    }

    // Export public members
    Result.TYPE_RESOLVERS = TYPE_RESOLVERS;
    Result.NO_MATCH = NO_MATCH;
    Result.get_resolver = get_resolver;
    Result.pass = pass;
    Result.incl = incl;

    return Result;
})();
try{ exports.Match = Match } catch(e) {}; // Support for node.js<commit_msg>Added nested matching for classes (requires constructor.super_,)  Latest revision of node supports this.<commit_after>//
//  match-js
//  A simple yet powerful pattern matching library for Javascript.
//
//  Read readme.md for instructions and LICENSE license.
//
//  Copyright (c) 2009 Johan Dahlberg
//
var Match = (function() {
    var NO_MATCH = { __matchtype__: 'no-match', toString: function() { return 'no-match' }};
    var TYPE_RE = /function\s([A-Za-z_1-9$]+)/;;

    function is_prim_type(obj) {
        return obj == String || obj == Number || obj == Date || obj == Boolean
    }

    function is_empty(value) {
        return value == null || value == undefined;
    }

    function get_resolver(obj) {
        var ctor;

        // Check if we got an instance __compare__ method (most valuable)
        if(obj && obj['__compare__']) return function(value) {
            return obj.__compare__(value);
        }

        // Check if we got an instance __equals__ method (most second most
        // valuable)
        else if(obj && obj['__equals__']) return function(value) {
            if(obj.__equals__(value)) return [value];
            throw NO_MATCH;
        }

        // Check if the instance constructor class has an __compare__ method.
        else if(obj && obj.constructor && obj.constructor['__compare__']) return function(value) {
            return obj.constructor.__compare__(obj, value);
        }

        // Check if the instance constructor class has an __equals__ method.
        else if(obj && obj.constructor && obj.constructor['__equals__']) return function(value) {
            var comp = obj.constructor.__equals__;
            if(comp(obj, value)) return [value];
            throw NO_MATCH;
        }

        // Check for native type's (Strings, Number and Regexp's)
        else if(is_prim_type(obj)) return function(value) {
            if(is_empty(value) || value.constructor !== obj) throw NO_MATCH;
            return [value];
        }

        // Check for null and undefined types
        else if(is_empty(obj)) return function(value) {
            if(obj !== value) throw NO_MATCH;
            return [value];
        }

        // Didnt match any of the special case resolvers. Find it in
        // the TYPE_RESOLVERS list instead.
        var type_name = TYPE_RE(obj.constructor.toString())[1];
        ctor = TYPE_RESOLVERS[type_name];
        if(!ctor) ctor = TYPE_RESOLVERS['Object'];
        return ctor(obj);
    }

    var TYPE_RESOLVERS = {

        // Function (class constructor) resolver.
        Function: function(ctor) {
            return function(value) {
                var c = value !== undefined ? value.constructor : undefined;
                if(c) {
                    if(c === ctor) return [value];
                    while((c = c.super_)) if(c === ctor) return [value];
                }
                throw NO_MATCH;
            }
        },

        // Array resolver
        Array: function(arr) {
            if(arr.length == 0) {
                return function(value) {
                    if(value.constructor != Array || value.length != 0)
                        throw NO_MATCH;
                }
            } else {
                var resolvers = []
                for(var i = 0; i < arr.length; i++){
                  resolvers[i] = get_resolver(arr[i]);
                }
                return function(value) {
                    var result = [];
                    if(!value || value.constructor != Array) throw NO_MATCH;
                    for(var count=0; count < resolvers.length; count++) {
                        result = result.concat(
                             resolvers[count](value[count])
                        );
                    }
                    return result;
                }
            }
        },

        // Boolean resolver
        Boolean: function(b) {
            return function(value) {
                if(b !== value) throw NO_MATCH;
                return [];
            }
        },

        // Regexp resolver
        RegExp: function(regexp) {
            return function(value) {
                if(!value || !regexp.test(value)) throw NO_MATCH;
                return [];
            }
        },

        // Number resolver
        Number: function(no) {
            return function(value) {
                if(no !== value) throw NO_MATCH;
                return [];
            }
        },

        // String resolver
        String: function(str) {
            return function(value) {
                if(str !== value) throw NO_MATCH;
                return [];
            }
        },

        Object: function(obj) {
            var resolvers = {};
            for(var key in obj) {
                resolvers[key] = get_resolver(obj[key]);
            }
            return function(value) {
                if(value === null || value === undefined) throw NO_MATCH;
                var result = [];
                for(var key in resolvers) {
                    result = result.concat(
                        resolvers[key](value[key])
                    );
                }
                return result;
            }
        }
    }

    var Result = function() {
        var args = Array.prototype.slice.call(arguments);
        var cases = [], default_case;
        while(args.length) {
            var left = args.shift()
            if(left.__matchtype__ == 'matcher') {
                // This is a filter-
                cases.unshift({ filter: left });
            } else if(left.constructor == Function && !args.length) {
                // The ´default´ case. This callback is called when no other
                // case is matching. This MUST be the last argument.
                default_case = left;
            } else {
                var right = args.shift();
                var resolver = get_resolver(left), callback;
                if(right.constructor == Array) {
                    // The right argument is an array. The first argument in the
                    // Array is the callback. The remaining arguments are the
                    // arguments to parse to the callback.
                    var fn = right.shift();
                    callback = function() { return fn.apply(null, right.concat(arguments)) };
                } else if(right.constructor == Function) {
                    callback = right;
                }
                cases.unshift({ resolver: resolver, callback: callback });
            }
        }

        // Matches against defined patterns. The first argument is the object
        // to match agaisnt. The second argument is optional and respresent the
        // value that is return if no pattern was matched.
        var Matcher = function(orig, nomatch_res) {
            var l = cases.length,
                errors = [],
                obj = orig,
                nomatch = nomatch_res || undefined; // undefined is default
            while(l-- > 0) {
                var c = cases[l]
                if(c.resolver) {
                    try {
                        var result = c.resolver(obj);
                    } catch(ex) {
                        if(ex == NO_MATCH) continue;
                        throw ex;
                    }
                    // We got a match! Concat the result array with the
                    // (filtered) object and the original object.
                    return c.callback.apply(this, result.concat([obj, orig]));
                } else if(c.filter){
                    // Run the object through the provided filter.
                    obj = c.filter(obj);
                }
            }

            // Check if a default case is defined.
            if(default_case) default_case.apply(this, [obj, orig]);

            // No pattern was matched. Return the default nomatch value.
            else return nomatch;
        };

        // Identify the new matcher as a Matcher
        Matcher.__matchtype__ = 'matcher';

        // Return the Matcher.
        return Matcher;
    }

    // A comparer that ignores a value in the pattern
    var pass = {
        __compare__: function(value) {
            return [];
        }
    }

    // A comparer that includes a value without matching.
    var incl = {
        __compare__: function(value) {
            return [value];
        }
    }

    // Export public members
    Result.TYPE_RESOLVERS = TYPE_RESOLVERS;
    Result.NO_MATCH = NO_MATCH;
    Result.get_resolver = get_resolver;
    Result.pass = pass;
    Result.incl = incl;

    return Result;
})();
try{ exports.Match = Match } catch(e) {}; // Support for node.js<|endoftext|>


<commit_before>/*
The MIT License (MIT)
Copyright (c) 2013 Calvin Montgomery

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/

// Helper function for formatting a time value in seconds
// to the format hh:mm:ss
function formatTime(sec) {
    if(sec == "--:--")
        return sec;

    sec = Math.floor(sec);
    var hours="", minutes="", seconds="";
    if(sec > 3600) {
        hours = ""+Math.floor(sec / 3600);
        if(hours.length < 2)
            hours = "0"+hours;
        sec = sec % 3600;
    }
    minutes = ""+Math.floor(sec / 60);
    while(minutes.length < 2) {
        minutes = "0"+minutes;
    }
    seconds = ""+(sec % 60);
    while(seconds.length < 2) {
        seconds = "0"+seconds;
    }

    var time = "";
    if(hours != "")
        time = hours + ":";
    time += minutes + ":" + seconds;
    return time;
}

exports.formatTime = formatTime;

// Represents a media entry
var Media = function(id, title, seconds, type) {
    this.id = id;
    this.title = title;
    this.seconds = seconds == "--:--" ? "--:--" : parseInt(seconds);
    this.duration = formatTime(this.seconds);
    if(seconds == "--:--") {
        this.seconds = 0;
    }
    this.type = type;
    this.queueby = "";
    this.temp = false;
}

Media.prototype.dup = function() {
    var m = new Media(this.id, this.title, this.seconds, this.type);
    m.queueby = this.queueby;
    m.temp = this.temp;
    return m;
}

// Returns an object containing the data in this Media but not the
// prototype
Media.prototype.pack = function() {
    return {
        id: this.id,
        title: this.title,
        seconds: this.seconds,
        duration: this.duration,
        type: this.type,
        queueby: this.queueby,
        temp: this.temp
    };
}

// Same as pack() but includes the currentTime variable set by the channel
// when the media is being synchronized
Media.prototype.fullupdate = function() {
    return {
        id: this.id,
        title: this.title,
        seconds: this.seconds,
        duration: this.duration,
        type: this.type,
        currentTime: this.currentTime,
        queueby: this.queueby,
        temp: this.temp
    };
}

Media.prototype.timeupdate = function() {
    return {
        currentTime: this.currentTime
    };
}

exports.Media = Media;
<commit_msg>Quickfix for race condition on player load<commit_after>/*
The MIT License (MIT)
Copyright (c) 2013 Calvin Montgomery

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/

// Helper function for formatting a time value in seconds
// to the format hh:mm:ss
function formatTime(sec) {
    if(sec == "--:--")
        return sec;

    sec = Math.floor(sec);
    var hours="", minutes="", seconds="";
    if(sec > 3600) {
        hours = ""+Math.floor(sec / 3600);
        if(hours.length < 2)
            hours = "0"+hours;
        sec = sec % 3600;
    }
    minutes = ""+Math.floor(sec / 60);
    while(minutes.length < 2) {
        minutes = "0"+minutes;
    }
    seconds = ""+(sec % 60);
    while(seconds.length < 2) {
        seconds = "0"+seconds;
    }

    var time = "";
    if(hours != "")
        time = hours + ":";
    time += minutes + ":" + seconds;
    return time;
}

exports.formatTime = formatTime;

// Represents a media entry
var Media = function(id, title, seconds, type) {
    this.id = id;
    this.title = title;
    this.seconds = seconds == "--:--" ? "--:--" : parseInt(seconds);
    this.duration = formatTime(this.seconds);
    if(seconds == "--:--") {
        this.seconds = 0;
    }
    this.type = type;
    this.queueby = "";
    this.temp = false;
}

Media.prototype.dup = function() {
    var m = new Media(this.id, this.title, this.seconds, this.type);
    m.queueby = this.queueby;
    m.temp = this.temp;
    return m;
}

// Returns an object containing the data in this Media but not the
// prototype
Media.prototype.pack = function() {
    return {
        id: this.id,
        title: this.title,
        seconds: this.seconds,
        duration: this.duration,
        type: this.type,
        queueby: this.queueby,
        temp: this.temp
    };
}

// Same as pack() but includes the currentTime variable set by the channel
// when the media is being synchronized
Media.prototype.fullupdate = function() {
    return {
        id: this.id,
        title: this.title,
        seconds: this.seconds,
        duration: this.duration,
        type: this.type,
        currentTime: this.currentTime,
        queueby: this.queueby,
        temp: this.temp
    };
}

Media.prototype.timeupdate = function() {
    return this.fullupdate();
    //return {
    //    currentTime: this.currentTime
    //};
}

exports.Media = Media;
<|endoftext|>


<commit_before>var request = require('request')
var asciify = require('asciify')
var fs = require('fs')

var addContributor = require('./contributors.js')
var buildPage = require('./buildpage.js')

var baseURL = 'https://api.github.com/repos/jlord/patchwork/'
var stats = {}

// what happens when multiple people are doing this?!

module.exports = function(pullreq, req) {
  console.log("PR", JSON.parse(pullreq, null, " "))
  if (pullreq.action && pullreq.action === "closed") return
  if (pullreq.pull_request) pullreq = pullreq.pull_request

  stats.prNum = pullreq.number

  // make sure it's not a non-workshop, normal PR
  if (pullreq.base.ref.match(pullreq.user.login)) return

  var options = {
      url: baseURL +'pulls/' + stats.prNum,
      json: true,
      headers: {
          'User-Agent': 'request',
          'Authorization': 'token ' + process.env['REPOROBOT_TOKEN']
      }
  }

  function getTime(error, response, body) {
    if (error) console.log(error)

      if (!error && response.statusCode == 200) {
        var info = body
        stats.time = info.created_at
        stats.username = info.user.login
        getFile(stats.prNum)
      }
  }

  request(options, getTime)

  function getFile(prNum) {
    var options = {
        url: baseURL + 'pulls/' + prNum + '/files',
        json: true,
        headers: {
            'User-Agent': 'request',
            'Authorization': 'token ' + process.env['REPOROBOT_TOKEN']
        }
    }

    request(options, function returnFiles(error, response, body) {
      // add callback
      if (error) console.log(error)

        if (!error && response.statusCode == 200) {
          console.log(["body", JSON.parse(body, null, " ")])
          var prInfo = body[0]
          verifyFilename(prInfo)
        }
    })
  }
}

function verifyFilename(prInfo) {
  var filename = prInfo.filename
  console.log(["filename from PR", filename])
  if (filename.match('contributors/add-' + stats.username + '.txt')) {
    console.log([ new Date(), stats.username, " Filename: MATCH"])
    verifyContent(prInfo)
  }
  else {
    var message = 'Filename is different than expected: contributors/add-' + stats.username + '.txt'
    writeComment(message, stats.prNum)
  }
}

function verifyContent(prInfo) {
  // pull out the actual pr content
  var patchArray = prInfo.patch.split('@@')
  var patch = patchArray.pop()
  // generate the expected content
  asciify(stats.username, {font:'isometric2'}, function(err, res){
    if (err) console.log(err)
    if (res.match(patch)) {
      stats.userArt = res
      console.log([new Date(), stats.username, " Content: MATCH"])
      mergePR(stats.prNum)
    }
    else {
      var message = "Ascii art wasn't as expected, did something change?"
      writeComment(message, stats.prNum)
    }
  })
}

function writeComment(message, prNum) {
  console.log([new Date(), "uh oh, writing comment for ", stats.username])
   var options = {
      url: baseURL + 'issues/' + prNum + '/comments',
      headers: {
          'User-Agent': 'request',
          'Authorization': 'token ' + process.env['REPOROBOT_TOKEN']
      },
      json: {'body': message}
  }

  request.post(options, function done(error, response, body) {
    if (error) console.log(error)
  })
}

function mergePR(prNum) {
  addContributor(stats, buildPage)
  var message = "Merging PR from @" + stats.username
  var options = {
     url: baseURL + 'pulls/' + prNum + '/merge',
     headers: {
         'User-Agent': 'request',
         'Authorization': 'token ' + process.env['REPOROBOT_TOKEN']
     },
     json: {'commit_message': message}
 }

 request.put(options, function done(error, response, body) {
   if (error) console.log(error)
   if (!error && response.statusCode == 200) {
       console.log([new Date(), "MERGED", stats.username, "pull request" ])
       // add contributor to file and rebuild page
       addContributor(stats, buildPage)
   }
 })
}<commit_msg>testing pull request action<commit_after>var request = require('request')
var asciify = require('asciify')
var fs = require('fs')

var addContributor = require('./contributors.js')
var buildPage = require('./buildpage.js')

var baseURL = 'https://api.github.com/repos/jlord/patchwork/'
var stats = {}

// what happens when multiple people are doing this?!

module.exports = function(pullreq, req) {
  console.log(["PR", pullreq])
  if (pullreq.action && pullreq.action === "closed") return
  if (pullreq.pull_request) pullreq = pullreq.pull_request

  stats.prNum = pullreq.number

  // make sure it's not a non-workshop, normal PR
  if (pullreq.base.ref.match(pullreq.user.login)) return

  var options = {
      url: baseURL +'pulls/' + stats.prNum,
      json: true,
      headers: {
          'User-Agent': 'request',
          'Authorization': 'token ' + process.env['REPOROBOT_TOKEN']
      }
  }

  function getTime(error, response, body) {
    if (error) console.log(error)

      if (!error && response.statusCode == 200) {
        var info = body
        stats.time = info.created_at
        stats.username = info.user.login
        getFile(stats.prNum)
      }
  }

  request(options, getTime)

  function getFile(prNum) {
    var options = {
        url: baseURL + 'pulls/' + prNum + '/files',
        json: true,
        headers: {
            'User-Agent': 'request',
            'Authorization': 'token ' + process.env['REPOROBOT_TOKEN']
        }
    }

    request(options, function returnFiles(error, response, body) {
      // add callback
      if (error) console.log(error)

        if (!error && response.statusCode == 200) {
          console.log(["body", JSON.parse(body, null, " ")])
          var prInfo = body[0]
          verifyFilename(prInfo)
        }
    })
  }
}

function verifyFilename(prInfo) {
  var filename = prInfo.filename
  console.log(["filename from PR", filename])
  if (filename.match('contributors/add-' + stats.username + '.txt')) {
    console.log([ new Date(), stats.username, " Filename: MATCH"])
    verifyContent(prInfo)
  }
  else {
    var message = 'Filename is different than expected: contributors/add-' + stats.username + '.txt'
    writeComment(message, stats.prNum)
  }
}

function verifyContent(prInfo) {
  // pull out the actual pr content
  var patchArray = prInfo.patch.split('@@')
  var patch = patchArray.pop()
  // generate the expected content
  asciify(stats.username, {font:'isometric2'}, function(err, res){
    if (err) console.log(err)
    if (res.match(patch)) {
      stats.userArt = res
      console.log([new Date(), stats.username, " Content: MATCH"])
      mergePR(stats.prNum)
    }
    else {
      var message = "Ascii art wasn't as expected, did something change?"
      writeComment(message, stats.prNum)
    }
  })
}

function writeComment(message, prNum) {
  console.log([new Date(), "uh oh, writing comment for ", stats.username])
   var options = {
      url: baseURL + 'issues/' + prNum + '/comments',
      headers: {
          'User-Agent': 'request',
          'Authorization': 'token ' + process.env['REPOROBOT_TOKEN']
      },
      json: {'body': message}
  }

  request.post(options, function done(error, response, body) {
    if (error) console.log(error)
  })
}

function mergePR(prNum) {
  addContributor(stats, buildPage)
  var message = "Merging PR from @" + stats.username
  var options = {
     url: baseURL + 'pulls/' + prNum + '/merge',
     headers: {
         'User-Agent': 'request',
         'Authorization': 'token ' + process.env['REPOROBOT_TOKEN']
     },
     json: {'commit_message': message}
 }

 request.put(options, function done(error, response, body) {
   if (error) console.log(error)
   if (!error && response.statusCode == 200) {
       console.log([new Date(), "MERGED", stats.username, "pull request" ])
       // add contributor to file and rebuild page
       addContributor(stats, buildPage)
   }
 })
}<|endoftext|>


<commit_before>'use strict';

/*
 * upgrader upgrades the controller
 *
 * Gets the energy from the storage
 * Shouts out the player idiot values
 */

roles.upgrader = {};
roles.upgrader.settings = {
  param: ['controller.level', 'storage.store.energy', 'memory.enemies.length'],
  prefixString: {
    1: 'MCW',
  },
  layoutString: {
    1: 'MWW',
    4: 'W',
  },
  amount: {
    4: [1],
  },
};

roles.upgrader.updateSettings = function(room, creep) {
  // One work part one energy per tick multiplied by config value with  lifetime
  // So have at least a specific amount of energy in storage that the upgrader
  // can use.
  // Example with upgraderStorageFactor 2:
  // 6453 energy in storage are 2 workParts
  // 3000 energy will be put in the controller
  let workParts = Math.floor((room.storage.store.energy + 1) / (CREEP_LIFE_TIME * config.room.upgraderStorageFactor));
  workParts = Math.min(workParts, 47);
  if (room.controller.level === 8) {
    workParts = Math.min(workParts, 15);
  }
  const maxLayoutAmount = Math.max(0, workParts - 1);
  if (config.debug.upgrader) {
    room.log(`upgrader updateSettings - storage.energy: ${room.storage.store.energy} upgraderStorageFactor: ${config.room.upgraderStorageFactor} workParts: ${workParts} maxLayoutAmount: ${maxLayoutAmount}`);
  }
  return {
    maxLayoutAmount: maxLayoutAmount,
  };
};

roles.upgrader.stayInRoom = true;
// TODO disabled because the upgrader took energy from the extension
roles.upgrader.buildRoad = false;
roles.upgrader.killPrevious = true;

roles.upgrader.boostActions = ['upgradeController'];

roles.upgrader.work = function(creep) {
  return creep.handleUpgrader();
};

roles.upgrader.action = function(creep) {
  creep.mySignController();

  if (!creep.memory.routing.targetId && creep.memory.routing.reached) {
    creep.memory.routing.reached = false;
    creep.memory.routing.targetId = creep.room.controller.id;
  }
  if (creep.memory.routing.reached && creep.memory.routing.pathPos === 0) {
    creep.memory.routing.reached = false;
  }
  return creep.handleUpgrader();
};

roles.upgrader.execute = function(creep) {
  creep.log('Execute!!!');
};
<commit_msg>Fix upgrader<commit_after>'use strict';

/*
 * upgrader upgrades the controller
 *
 * Gets the energy from the storage
 * Shouts out the player idiot values
 */

roles.upgrader = {};
roles.upgrader.settings = {
  param: ['controller.level', 'storage.store.energy', 'memory.enemies.length'],
  prefixString: {
    1: 'MCW',
  },
  layoutString: {
    1: 'MWW',
    4: 'W',
  },
  amount: {
    4: [1],
  },
};

roles.upgrader.updateSettings = function(room, creep) {
  if (!room.storage) {
    return false;
  }
  // One work part one energy per tick multiplied by config value with  lifetime
  // So have at least a specific amount of energy in storage that the upgrader
  // can use.
  // Example with upgraderStorageFactor 2:
  // 6453 energy in storage are 2 workParts
  // 3000 energy will be put in the controller
  let workParts = Math.floor((room.storage.store.energy + 1) / (CREEP_LIFE_TIME * config.room.upgraderStorageFactor));
  workParts = Math.min(workParts, 47);
  if (room.controller.level === 8) {
    workParts = Math.min(workParts, 15);
  }
  const maxLayoutAmount = Math.max(0, workParts - 1);
  if (config.debug.upgrader) {
    room.log(`upgrader updateSettings - storage.energy: ${room.storage.store.energy} upgraderStorageFactor: ${config.room.upgraderStorageFactor} workParts: ${workParts} maxLayoutAmount: ${maxLayoutAmount}`);
  }
  return {
    maxLayoutAmount: maxLayoutAmount,
  };
};

roles.upgrader.stayInRoom = true;
// TODO disabled because the upgrader took energy from the extension
roles.upgrader.buildRoad = false;
roles.upgrader.killPrevious = true;

roles.upgrader.boostActions = ['upgradeController'];

roles.upgrader.work = function(creep) {
  return creep.handleUpgrader();
};

roles.upgrader.action = function(creep) {
  creep.mySignController();

  if (!creep.memory.routing.targetId && creep.memory.routing.reached) {
    creep.memory.routing.reached = false;
    creep.memory.routing.targetId = creep.room.controller.id;
  }
  if (creep.memory.routing.reached && creep.memory.routing.pathPos === 0) {
    creep.memory.routing.reached = false;
  }
  return creep.handleUpgrader();
};

roles.upgrader.execute = function(creep) {
  creep.log('Execute!!!');
};
<|endoftext|>


<commit_before>let task = {'id': 0, 'name': 'Hello world', 'status': 2, 'due_date': Date.now()};

var apiRouter = (api) => {
  api.get('/tasks', (req, res) => {
    res.setHeader('Content-type', 'application/json');
    res.status(200).send(JSON.stringify(task));
  });
}

module.exports = apiRouter;
<commit_msg>API return with status 201 on post request on /tasks<commit_after>let task = {'id': 0, 'name': 'Hello world', 'status': 2, 'due_date': Date.now()};

var apiRouter = (api) => {
  api.get('/tasks', (req, res) => {
    res.setHeader('Content-type', 'application/json');
    res.status(200).send(JSON.stringify(task));
  });
  api.post('/tasks', (req, res) => {
    res.status(201).send();
  });
}

module.exports = apiRouter;
<|endoftext|>


<commit_before>// SEP-PCC REST ROUTES
'use strict'

const controllers = require('../controllers');
const joi = require('joi');

module.exports = [
	{
		method: 'GET',
		path:'/api/sep/log/{id?}',
		config: {
			handler: controllers.pcc.issuerLog,
			validate: {
				params: {
					id: joi.number().integer().required()
				},
				failAction: function (request, reply, source, error) {
					return reply(JSON.parse('{"error":{"code": "04", "message": "REQUEST_FORMAT_ERROR"}}'));
				}
			}
		}
	},
	{
		method: 'POST',
		path:'/api/sep/auth',
		config: {
			handler: controllers.pcc.auth,
			validate: {
				headers: joi.object({
					'content-type': joi.string().valid([
						'application/json',
						'application/json;charset=utf-8',
						'application/json; charset=utf-8'
					]).insensitive().required()
				}).options({ allowUnknown: true }),
				payload: {
					cardInfo: joi.object({
						pan: joi.string().alphanum().min(16).max(16).required(),
						securityCode: joi.number().integer().min(100).max(999).required(),
						holderName: joi.string().required(),
						expirationDate: joi.string().required()
					}).required(),
					acquirerInfo: joi.object({
						orderId: joi.string().alphanum().required(),
						timestamp: joi.string().required()
					}).required(),
					transactionAmount: joi.number().required()
				},
				failAction: function (request, reply, source, error) {
					return reply(JSON.parse('{"transactionStatus":{"code": "04", "message": "REQUEST_FORMAT_ERROR"}}'));
				}
			}
		}
	}
];
<commit_msg>Fix validation for acquirer order id<commit_after>// SEP-PCC REST ROUTES
'use strict'

const controllers = require('../controllers');
const joi = require('joi');

module.exports = [
	{
		method: 'GET',
		path:'/api/sep/log/{id?}',
		config: {
			handler: controllers.pcc.issuerLog,
			validate: {
				params: {
					id: joi.number().integer().required()
				},
				failAction: function (request, reply, source, error) {
					return reply(JSON.parse('{"error":{"code": "04", "message": "REQUEST_FORMAT_ERROR"}}'));
				}
			}
		}
	},
	{
		method: 'POST',
		path:'/api/sep/auth',
		config: {
			handler: controllers.pcc.auth,
			validate: {
				headers: joi.object({
					'content-type': joi.string().valid([
						'application/json',
						'application/json;charset=utf-8',
						'application/json; charset=utf-8'
					]).insensitive().required()
				}).options({ allowUnknown: true }),
				payload: {
					cardInfo: joi.object({
						pan: joi.string().alphanum().min(16).max(16).required(),
						securityCode: joi.number().integer().min(100).max(999).required(),
						holderName: joi.string().required(),
						expirationDate: joi.string().required()
					}).required(),
					acquirerInfo: joi.object({
						orderId: joi.number().integer().required(),
						timestamp: joi.string().required()
					}).required(),
					transactionAmount: joi.number().required()
				},
				failAction: function (request, reply, source, error) {
					return reply(JSON.parse('{"transactionStatus":{"code": "04", "message": "REQUEST_FORMAT_ERROR"}}'));
				}
			}
		}
	}
];
<|endoftext|>