<commit_before>/**
 * 因为css module设置比较复杂,单独分离出来
 */
let ExtractTextPlugin = require('extract-text-webpack-plugin')

/**
 * cssModules 启用antdcss modules
 * false 是否分离样式文件
 */
module.exports = ({ __DEV__, cssModules = true, extract = true }) => {
  if (!extract) {
    ExtractTextPlugin = {
      extract: ({ use }) => {
        return use
      }
    }
  }
  const localIdentName = '[name]__[local]___[hash:base64:5]'
  const styleLoader = { loader: 'style-loader', options: { sourceMap: true } }
  const postCSSLoader = { loader: 'postcss-loader', options: { sourceMap: true } }
  const cssLoader = {
    loader: 'css-loader',
    options: {
      // importLoaders: 2,
      minimize: !__DEV__,
      sourceMap: true
    }
  }

  const regMap = {
    less: {
      reg: /\.(css|less)$/,
      loader: {
        loader: 'less-loader',
        options: {
          sourceMap: true,
        }
      }
    },
    stylus: {
      reg: /\.styl$/,
      loader: {
        loader: 'stylus-loader',
        options: {
          options: {
            sourceMap: true,
          },
        }
      }
    }
  }

  let getReulsByType = (type) => {
    const { reg, loader } = regMap[type]
    return [{
      test: reg,
      include: /node_modules/, //针对 node_modeuls里面的less文件
      use: ExtractTextPlugin.extract({
        fallback: styleLoader,
        use: [
          ...(extract ? [] : [styleLoader]),
          cssLoader,
          postCSSLoader,
          loader
        ]
      })
    },
    {
      test: reg,
      exclude: /node_modules/, //针对 非 node_modeuls里面的css文件
      use: ExtractTextPlugin.extract({
        fallback: styleLoader,
        use: [
          ...(extract ? [] : [styleLoader]),
          {
            ...cssLoader,
            ... {
              options: {
                modules: cssModules,
                localIdentName,
                minimize: !__DEV__,
              }
            }
          },
          postCSSLoader,
          loader
        ]
      })
    }]
  }
  return [
    ...getReulsByType('less'),
    ...getReulsByType('stylus')
  ]
}
<commit_msg>css.rules<commit_after>/**
 * 因为css module设置比较复杂,单独分离出来
 */
let ExtractTextPlugin = require('extract-text-webpack-plugin')

/**
 * cssModules 启用antdcss modules
 * false 是否分离样式文件
 */
module.exports = ({ __DEV__, cssModules = true, extract = true }) => {
  if (!extract) {
    ExtractTextPlugin = {
      extract: ({ use }) => {
        return use
      }
    }
  }
  const localIdentName = '[name]__[local]___[hash:base64:5]'
  const styleLoader = { loader: 'style-loader', options: { sourceMap: true } }
  const postCSSLoader = { loader: 'postcss-loader', options: { sourceMap: true } }
  const cssLoader = {
    loader: 'css-loader',
    options: {
      importLoaders: 3,
      modules: cssModules,
      localIdentName,
      minimize: !__DEV__,
      sourceMap: true
    }
  }

  const regMap = {
    less: {
      reg: /\.(css|less)$/,
      loader: {
        loader: 'less-loader',
        options: {
          sourceMap: true,
        }
      }
    },
    stylus: {
      reg: /\.styl$/,
      loader: {
        loader: 'stylus-loader',
        options: {
          options: {
            sourceMap: true,
          },
        }
      }
    }
  }

  let getReulsByType = (type) => {
    const { reg, loader } = regMap[type]
    const getCssLoaderInstance = () => {
      return {
        test: reg,
        use: ExtractTextPlugin.extract({
          fallback: styleLoader,
          use: [
            ...(extract ? [] : [styleLoader]),
            cssLoader,
            postCSSLoader,
            loader
          ]
        })
      }
    }
    return [
      {
        ...getCssLoaderInstance(),
        include: /node_modules/, //针对 node_modeuls里面的less文件
      },
      {
        ...getCssLoaderInstance(),
        exclude: /node_modules/, //针对 非 node_modeuls里面的css文件
      }
    ]
  }
  return [
    ...getReulsByType('less'),
    ...getReulsByType('stylus')
  ]
}
<|endoftext|>


<commit_before>// Copyright (c) 2012 IT Agenten - http://www.it-agenten.com
//
// 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 NON-INFRINGEMENT. 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.

// This 'provider' stores the images created via mongoose-attachments in the
// local file system.
// It requires that the option 'directory' points to the absolute path of
// the directory where it will create subfolders per image type.
//
// Example:
// type is 'thumb'
// and 'directory' points to /path/to/public/images/
// When storing data into the schema, the thumbnail created by mongoose-attachemnts
// is stored as /path/to/public/images/thumb/<ObjectID>-thumb.<format>
//
// The absolute path to the image is stored in Model.image.<type>.path

var attachments = require('mongoose-attachments');
var fs = require('fs');
var path = require('path');
var util = require('util');

function FsStorage(options) {
	attachments.StorageProvider.call(this, options);
}
util.inherits(FsStorage, attachments.StorageProvider);

/*
 * Returns the file system path (absolute)
 * and not the actual URL.
 */
FsStorage.prototype.getUrl = function( path ){
	return path;
};

FsStorage.prototype.createOrReplace = function(attachment, callback) {
	var self = this;
	var dirname = path.join(path.dirname(attachment.path), attachment.style.name);
	if (!fs.existsSync(dirname)) {
		var pathParts = dirname.split(path.sep);
		var p = "/";
		for (var i=0; i<pathParts.length; i++) {
			p = path.join(p, pathParts[i]);
			if (!fs.existsSync(p)) {
				fs.mkdirSync(p, '0750');
			}
		}
	}

	var basename = path.basename(attachment.path);
	if (path.extname(basename).length == 0) {
		basename = basename + "." + attachment.model.extension;
	}
	attachment.path = path.join(dirname, basename);
	fs.rename(attachment.filename, attachment.path, function(error) {
		if (error) {
			callback(error);
		} else {
			attachment.defaultUrl = self.getUrl( attachment.path );
			callback(null, attachment);
		}
	});
};

// register the File System Storage Provider into the registry
attachments.registerStorageProvider('fs', FsStorage);

// export it just in case the user needs it
module.exports = FsStorage;
<commit_msg>fallbacks on path.existsSync for backwards compatibility with node < 0.8; see https://github.com/firebaseco/mongoose-attachments-localfs/issues/2<commit_after>// Copyright (c) 2012 IT Agenten - http://www.it-agenten.com
//
// 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 NON-INFRINGEMENT. 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.

// This 'provider' stores the images created via mongoose-attachments in the
// local file system.
// It requires that the option 'directory' points to the absolute path of
// the directory where it will create subfolders per image type.
//
// Example:
// type is 'thumb'
// and 'directory' points to /path/to/public/images/
// When storing data into the schema, the thumbnail created by mongoose-attachemnts
// is stored as /path/to/public/images/thumb/<ObjectID>-thumb.<format>
//
// The absolute path to the image is stored in Model.image.<type>.path

var attachments = require('mongoose-attachments');
var fs = require('fs');
var path = require('path');
var util = require('util');

function FsStorage(options) {
	attachments.StorageProvider.call(this, options);
}
util.inherits(FsStorage, attachments.StorageProvider);

/*
 * Returns the file system path (absolute)
 * and not the actual URL.
 */
FsStorage.prototype.getUrl = function( path ){
	return path;
};

FsStorage.prototype.createOrReplace = function(attachment, callback) {
	var self = this;
	var dirname = path.join(path.dirname(attachment.path), attachment.style.name);
        var existsSync = (fs.existsSync ? fs.existsSync : path.existsSync);
	if (!existsSync(dirname)) {
		var pathParts = dirname.split(path.sep);
		var p = "/";
		for (var i=0; i<pathParts.length; i++) {
			p = path.join(p, pathParts[i]);
			if (!existsSync(p)) {
				fs.mkdirSync(p, '0750');
			}
		}
	}

	var basename = path.basename(attachment.path);
	if (path.extname(basename).length == 0) {
		basename = basename + "." + attachment.model.extension;
	}
	attachment.path = path.join(dirname, basename);
	fs.rename(attachment.filename, attachment.path, function(error) {
		if (error) {
			callback(error);
		} else {
			attachment.defaultUrl = self.getUrl( attachment.path );
			callback(null, attachment);
		}
	});
};

// register the File System Storage Provider into the registry
attachments.registerStorageProvider('fs', FsStorage);

// export it just in case the user needs it
module.exports = FsStorage;
<|endoftext|>


<commit_before>/**
 * Copyright (c) 2014, Tidepool Project
 *
 * This program is free software; you can redistribute it and/or modify it under
 * the terms of the associated License, which is identical to the BSD 2-Clause
 * License as published by the Open Source Initiative at opensource.org.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE. See the License for more details.
 *
 * You should have received a copy of the License along with this program; if
 * not, you can obtain one from Tidepool Project at tidepool.org.
 */

var _ = require('lodash');

var common = require('./common');
var publicPersonInfo = common.publicPersonInfo;

var invitationKeySize = 6;
var invitationTokenSize = 12;

function generateInvitationKey() {
  return common.generateRandomId(invitationKeySize);
}

function generateInvitationToken() {
  return common.generateRandomId(invitationTokenSize);
}

var patch = function(mock, api) {
  var data = mock.data;
  var getParam = mock.getParam;
  var getDelayFor = mock.getDelayFor;

  function getPendingInvitation(options) {
    return _.find(data.confirmations, function(confirmation) {
      var match = (
        confirmation.type === 'invite' &&
        confirmation.creatorId === options.from &&
        confirmation.status === 'pending'
      );

      if (options.to) {
        match = match && confirmation.userid === options.to;
      }
      if (options.email) {
        match = match && confirmation.email === options.email;
      }
      if (options.key) {
        match = match && confirmation.key === options.key;
      }

      return match;
    });
  }

  function replaceCreatorIdWithUser(invitation) {
    var creator = data.users[invitation.creatorId];
    creator = _.cloneDeep(creator);
    creator = publicPersonInfo(creator);
    return _.assign({}, _.omit(invitation, 'creatorId'), {
      creator: creator
    });
  }

  var setPermissions = common.setPermissions.bind(null, data);

  api.invitation.getReceived = function(callback) {
    api.log('[mock] GET /invitations/received');

    setTimeout(function() {
      var invitations = _.filter(data.confirmations, function(confirmation) {
        return (
          confirmation.type === 'invite' &&
          confirmation.userid === api.userId &&
          confirmation.status === 'pending'
        );
      });

      invitations = _.map(invitations, function(invitation) {
        return _.pick(invitation, 'key', 'creatorId', 'context');
      });

      invitations = _.map(invitations, replaceCreatorIdWithUser);

      callback(null, invitations);
    }, getDelayFor('api.invitation.getReceived'));
  };

  api.invitation.accept = function(key, fromUserId, callback) {
    api.log('[mock] POST /invitations/from/' + fromUserId + '/accept');

    setTimeout(function() {
      var userId = api.userId;

      var invitation = getPendingInvitation({
        from: fromUserId,
        to: userId,
        key: key
      });

      if (!invitation) {
        var err = {status: 404, response: 'Not found'};
        return callback(err);
      }

      setPermissions(fromUserId, userId, invitation.context);
      // Note: we are mutating the object in the mock data here
      invitation.status = 'completed';

      callback();
    }, getDelayFor('api.invitation.accept'));
  };

  api.invitation.dismiss = function(key, fromUserId, callback) {
    api.log('[mock] POST /invitations/from/' + fromUserId + '/dismiss');

    setTimeout(function() {
      var userId = api.userId;

      var invitation = getPendingInvitation({
        from: fromUserId,
        to: userId,
        key: key
      });

      if (!invitation) {
        var err = {status: 404, response: 'Not found'};
        return callback(err);
      }

      // Note: we are mutating the object in the mock data here
      invitation.status = 'declined';

      callback();
    }, getDelayFor('api.invitation.dismiss'));
  };

  api.invitation.getSent = function(callback) {
    api.log('[mock] GET /invitations/sent');

    setTimeout(function() {
      var invitations = _.filter(data.confirmations, function(confirmation) {
        return (
          confirmation.type === 'invite' &&
          confirmation.creatorId === api.userId &&
          confirmation.status === 'pending'
        );
      });

      invitations = _.map(invitations, function(invitation) {
        return _.pick(invitation, 'key', 'email', 'context');
      });

      callback(null, invitations);
    }, getDelayFor('api.invitation.getSent'));
  };

  api.invitation.send = function(toEmail, permissions, callback) {
    api.log('[mock] POST /invitations');

    setTimeout(function() {
      var err;
      var userId = api.userId;
      var existingInvitation = _.find(data.confirmations, function(confirmation) {
        return (
          confirmation.type === 'invite' &&
          confirmation.email === toEmail &&
          confirmation.creatorId === userId
        );
      });

      if (existingInvitation) {
        err = {status: 409, response: 'Invitation already sent to that email'};
        return callback(err);
      }

      var invitation = {
        key: generateInvitationKey(),
        type: 'invite',
        status: 'pending',
        email: toEmail,
        creatorId: userId,
        context: permissions,
        token: generateInvitationToken()
      };

      var existingUser = _.find(data.users, function(user, id) {
        return _.contains(user.emails, toEmail);
      });
      if (existingUser) {
        // Does user matched with email already belong to the group?
        var members = common.getMembersForGroup(data, userId);
        var existingMember = _.find(members, {userid: existingUser.userid});
        if (existingMember) {
          err = {status: 409, response: 'User with that email already part of the group'};
          return callback(err);
        }

        invitation.userid = existingUser.userid;
      }

      data.confirmations.push(invitation);

      invitation = _.pick(invitation, 'key', 'email', 'context');
      callback(null, invitation);
    }, getDelayFor('api.invitation.send'));
  };

  api.invitation.cancel = function(toEmail, callback) {
    api.log('[mock] POST /invitations/to/' + toEmail + '/cancel');

    setTimeout(function() {
      var userId = api.userId;

      var invitation = getPendingInvitation({
        from: userId,
        email: toEmail
      });

      if (!invitation) {
        var err = {status: 404, response: 'Not found'};
        return callback(err);
      }

      // Note: we are mutating the object in the mock data here
      invitation.status = 'canceled';

      callback();
    }, getDelayFor('api.invitation.cancel'));
  };

  api.invitation.getForToken = function(token, callback) {
    api.log('[mock] GET /invitations/token/' + token);

    setTimeout(function() {
      var invitation = _.find(data.confirmations, function(confirmation) {
        return (
          confirmation.type === 'invite' &&
          confirmation.token === token &&
          confirmation.status === 'pending'
        );
      });

      if (!invitation) {
        var err = {status: 404, response: 'Not found'};
        return callback(err);
      }

      invitation = replaceCreatorIdWithUser(invitation);
      // If invitation was sent to existing user account, add user object
      if (invitation.userid) {
        var user = data.users[invitation.userid];
        user = _.cloneDeep(user);
        user = publicPersonInfo(user);
        invitation = _.assign({}, _.omit(invitation, 'userid'), {
          user: user
        });
      }

      invitation = _.pick(invitation, 'key', 'user', 'email', 'creator', 'context');
      callback(null, invitation);
    }, getDelayFor('api.invitation.getForToken'));
  };

  return api;
};

module.exports = patch;
<commit_msg>Mock api allow resend canceled invite<commit_after>/**
 * Copyright (c) 2014, Tidepool Project
 *
 * This program is free software; you can redistribute it and/or modify it under
 * the terms of the associated License, which is identical to the BSD 2-Clause
 * License as published by the Open Source Initiative at opensource.org.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE. See the License for more details.
 *
 * You should have received a copy of the License along with this program; if
 * not, you can obtain one from Tidepool Project at tidepool.org.
 */

var _ = require('lodash');

var common = require('./common');
var publicPersonInfo = common.publicPersonInfo;

var invitationKeySize = 6;
var invitationTokenSize = 12;

function generateInvitationKey() {
  return common.generateRandomId(invitationKeySize);
}

function generateInvitationToken() {
  return common.generateRandomId(invitationTokenSize);
}

var patch = function(mock, api) {
  var data = mock.data;
  var getParam = mock.getParam;
  var getDelayFor = mock.getDelayFor;

  function getPendingInvitation(options) {
    return _.find(data.confirmations, function(confirmation) {
      var match = (
        confirmation.type === 'invite' &&
        confirmation.creatorId === options.from &&
        confirmation.status === 'pending'
      );

      if (options.to) {
        match = match && confirmation.userid === options.to;
      }
      if (options.email) {
        match = match && confirmation.email === options.email;
      }
      if (options.key) {
        match = match && confirmation.key === options.key;
      }

      return match;
    });
  }

  function replaceCreatorIdWithUser(invitation) {
    var creator = data.users[invitation.creatorId];
    creator = _.cloneDeep(creator);
    creator = publicPersonInfo(creator);
    return _.assign({}, _.omit(invitation, 'creatorId'), {
      creator: creator
    });
  }

  var setPermissions = common.setPermissions.bind(null, data);

  api.invitation.getReceived = function(callback) {
    api.log('[mock] GET /invitations/received');

    setTimeout(function() {
      var invitations = _.filter(data.confirmations, function(confirmation) {
        return (
          confirmation.type === 'invite' &&
          confirmation.userid === api.userId &&
          confirmation.status === 'pending'
        );
      });

      invitations = _.map(invitations, function(invitation) {
        return _.pick(invitation, 'key', 'creatorId', 'context');
      });

      invitations = _.map(invitations, replaceCreatorIdWithUser);

      callback(null, invitations);
    }, getDelayFor('api.invitation.getReceived'));
  };

  api.invitation.accept = function(key, fromUserId, callback) {
    api.log('[mock] POST /invitations/from/' + fromUserId + '/accept');

    setTimeout(function() {
      var userId = api.userId;

      var invitation = getPendingInvitation({
        from: fromUserId,
        to: userId,
        key: key
      });

      if (!invitation) {
        var err = {status: 404, response: 'Not found'};
        return callback(err);
      }

      setPermissions(fromUserId, userId, invitation.context);
      // Note: we are mutating the object in the mock data here
      invitation.status = 'completed';

      callback();
    }, getDelayFor('api.invitation.accept'));
  };

  api.invitation.dismiss = function(key, fromUserId, callback) {
    api.log('[mock] POST /invitations/from/' + fromUserId + '/dismiss');

    setTimeout(function() {
      var userId = api.userId;

      var invitation = getPendingInvitation({
        from: fromUserId,
        to: userId,
        key: key
      });

      if (!invitation) {
        var err = {status: 404, response: 'Not found'};
        return callback(err);
      }

      // Note: we are mutating the object in the mock data here
      invitation.status = 'declined';

      callback();
    }, getDelayFor('api.invitation.dismiss'));
  };

  api.invitation.getSent = function(callback) {
    api.log('[mock] GET /invitations/sent');

    setTimeout(function() {
      var invitations = _.filter(data.confirmations, function(confirmation) {
        return (
          confirmation.type === 'invite' &&
          confirmation.creatorId === api.userId &&
          confirmation.status === 'pending'
        );
      });

      invitations = _.map(invitations, function(invitation) {
        return _.pick(invitation, 'key', 'email', 'context');
      });

      callback(null, invitations);
    }, getDelayFor('api.invitation.getSent'));
  };

  api.invitation.send = function(toEmail, permissions, callback) {
    api.log('[mock] POST /invitations');

    setTimeout(function() {
      var err;
      var userId = api.userId;
      var existingInvitation = _.find(data.confirmations, function(confirmation) {
        return (
          confirmation.type === 'invite' &&
          confirmation.email === toEmail &&
          confirmation.creatorId === userId &&
          confirmation.status !== 'canceled'
        );
      });

      if (existingInvitation) {
        err = {status: 409, response: 'Invitation already sent to that email'};
        return callback(err);
      }

      var invitation = {
        key: generateInvitationKey(),
        type: 'invite',
        status: 'pending',
        email: toEmail,
        creatorId: userId,
        context: permissions,
        token: generateInvitationToken()
      };

      var existingUser = _.find(data.users, function(user, id) {
        return _.contains(user.emails, toEmail);
      });
      if (existingUser) {
        // Does user matched with email already belong to the group?
        var members = common.getMembersForGroup(data, userId);
        var existingMember = _.find(members, {userid: existingUser.userid});
        if (existingMember) {
          err = {status: 409, response: 'User with that email already part of the group'};
          return callback(err);
        }

        invitation.userid = existingUser.userid;
      }

      data.confirmations.push(invitation);

      invitation = _.pick(invitation, 'key', 'email', 'context');
      callback(null, invitation);
    }, getDelayFor('api.invitation.send'));
  };

  api.invitation.cancel = function(toEmail, callback) {
    api.log('[mock] POST /invitations/to/' + toEmail + '/cancel');

    setTimeout(function() {
      var userId = api.userId;

      var invitation = getPendingInvitation({
        from: userId,
        email: toEmail
      });

      if (!invitation) {
        var err = {status: 404, response: 'Not found'};
        return callback(err);
      }

      // Note: we are mutating the object in the mock data here
      invitation.status = 'canceled';

      callback();
    }, getDelayFor('api.invitation.cancel'));
  };

  api.invitation.getForToken = function(token, callback) {
    api.log('[mock] GET /invitations/token/' + token);

    setTimeout(function() {
      var invitation = _.find(data.confirmations, function(confirmation) {
        return (
          confirmation.type === 'invite' &&
          confirmation.token === token &&
          confirmation.status === 'pending'
        );
      });

      if (!invitation) {
        var err = {status: 404, response: 'Not found'};
        return callback(err);
      }

      invitation = replaceCreatorIdWithUser(invitation);
      // If invitation was sent to existing user account, add user object
      if (invitation.userid) {
        var user = data.users[invitation.userid];
        user = _.cloneDeep(user);
        user = publicPersonInfo(user);
        invitation = _.assign({}, _.omit(invitation, 'userid'), {
          user: user
        });
      }

      invitation = _.pick(invitation, 'key', 'user', 'email', 'creator', 'context');
      callback(null, invitation);
    }, getDelayFor('api.invitation.getForToken'));
  };

  return api;
};

module.exports = patch;
<|endoftext|>


<commit_before>var async = require('async');
var CheckEvent = require('../models/checkEvent');
var Check = require('../models/check');

var PAUSED = -1;
var DOWN = 0;
var UP = 1;

/*
 * Usage:
 *   var builder = new IntervalBuilder();
 *   builder.addTarget(check1);
 *   builder.addTarget(check2);
 *   builder.build(begin, end, function(err, intervals, downtime) {
 *     // do things
 *   });
 */
var IntervalBuilder = function() {
  this.objectIds = [];
  this.nbObjects = 0;
  this.states = {};
  this.intervals = []; // intervals are [begin, end, state]
  this.currentState = null;
  this.currentInterval = [];
  this.downtime = 0;
  this.duration = 0;
};

IntervalBuilder.prototype.addTarget = function(objectId) {
  this.objectIds.push(objectId._id ? objectId._id : objectId);
  this.nbObjects++;
};

IntervalBuilder.prototype.build = function(begin, end, callback) {
  var self = this;

  async.auto({
    initialState: function(next) { self.determineInitialState(begin, next); },
    interval: ['initialState', function(next) { self.buildIntervalsForPeriod(begin, end, next); }],
    check: ['initialState', 'interval', function (next) {self.getCurrentCheck(next)}],
    duration: ['initialState', 'interval', 'check', function (next, results) { self.calculateDuration(results.check, begin, end, next); }],
    downtime: ['initialState', 'interval', 'check', 'duration', function (next, results) { self.calculateDowntime(results.check, begin, end, next); }]
    }, function(err, results) {
      if (err) {
        return callback(err);
      }

      self.duration = results.duration;
      self.downtime = results.downtime;

      return callback(null, self.intervals, self.downtime, self.duration);
  });
};

IntervalBuilder.prototype.getCurrentCheck = function(callback) {
  Check.findOne({ _id: this.objectIds[0] }, callback);
};

IntervalBuilder.prototype.isMultiTarget = function() {
  return this.nbObjects > 1;
};

IntervalBuilder.prototype.determineInitialState = function(timestamp, callback) {
  var self = this;
  async.forEach(this.objectIds, function(objectId, next) {
    CheckEvent.find()
    .where('check').equals(objectId)
    .where('timestamp').lte(timestamp)
    .sort({ timestamp: -1 })
    .findOne(function(err, checkEvent) {
      if (err) return next(err);
      if (!checkEvent) {
        // No ping ever - start the period as paused
        self.addEvent(objectId, 'paused', timestamp);
        return next();
      }
      self.addEvent(objectId, checkEvent.message);
      next();
    });
  }, function(err) {
    if (err) return callback(err);
    self.updateCurrentState(timestamp);
    return callback(null);
  });
};

IntervalBuilder.prototype.calculateDuration = function(check, begin, end, callback) {
  var durationBegin = Math.max(begin, check.firstTested),
    durationEnd = Math.min(end, check.lastTested),
    duration = durationEnd - durationBegin;

  if (this.isMultiTarget()) {
    // it's a tag - no other way
    return callback(null, duration);
  }

  this.intervals.forEach(function(interval) {
    if (interval[2] != PAUSED || interval[1] < durationBegin || interval[0] > durationEnd) {
      return;
    }

    interval[0] = Math.max(durationBegin, interval[0]);
    interval[1] = Math.min(durationEnd, interval[1]);

    duration -= interval[1] - interval[0];
  });

  return callback(null, duration);
};

IntervalBuilder.prototype.calculateDowntime = function(check, begin, end, callback) {
  var durationBegin = Math.max(begin, check.firstTested);
  var durationEnd = Math.min(end, check.lastTested);

  if (this.isMultiTarget()) {
    // it's a tag - no other way
    return callback(null, this.currentState == DOWN ? durationEnd - durationBegin : 0);
  }

  var downtime = 0;
  var currentIntervalEnd = null;
  this.intervals.forEach(function(interval) {
    currentIntervalEnd = interval[1];
    if (interval[2] != DOWN || interval[1] < durationBegin || interval[0] > durationEnd) {
      return true; // will act as a continue
    }

    interval[0] = Math.max(durationBegin, interval[0]);
    interval[1] = Math.min(durationEnd, interval[1]);

    downtime += interval[1] - interval[0];
  });

  if (!check.isUp) {
    if(currentIntervalEnd === null) {
      downtime += durationEnd - durationBegin;
    }else {
      downtime += durationEnd - currentIntervalEnd;
    }
  }

  return callback(null, downtime);
};

IntervalBuilder.prototype.buildIntervalsForPeriod = function(begin, end, callback) {
  var self = this;
  CheckEvent.find()
  .where('check').in(this.objectIds)
  .where('timestamp').gt(begin).lte(end)
  .sort({ timestamp: 1 })
  .find(function(err, checkEvents) {
    if (err) return callback(err);
    checkEvents.forEach(function(checkEvent) {
      if (self.addEvent(checkEvent.check, checkEvent.message)) {
        self.updateCurrentState(checkEvent.timestamp);
      }
    });
    callback(null);
  });
};

/**
 * Add an event for a given check.
 *
 * Returns true if the event modifies the state of a given check, false otherwise
 */
IntervalBuilder.prototype.addEvent = function(objectId, message) {
  switch (message) {
    case 'up':
      if (!this.isUp(objectId)) {
        this.states[objectId] = UP;
        return true;
      }
      break;
    case 'down':
      if (!this.isDown(objectId)) {
        this.states[objectId] = DOWN;
        return true;
      }
      break;
    case 'paused':
    case 'restarted':
    default:
      if (!this.isPaused(objectId)) {
        this.states[objectId] = PAUSED;
        return true;
      }
      break;
  }
  return false;
};

/**
 * Return true if the global state was updated, false otherwise.
 */
IntervalBuilder.prototype.updateCurrentState = function(timestamp) {
  timestamp = this.getTimestamp(timestamp);
  var currentState = this.getGlobalState();
  if (currentState !== this.currentState) {
    var intervalCompleted = this.completeCurrentInterval(timestamp);
    this.currentInterval = currentState == 1 ? [] : [timestamp];
    if(intervalCompleted || this.currentState === null) {
        this.currentState = currentState;
    }
    return true;
  }
  return false;
};

IntervalBuilder.prototype.getGlobalState = function() {
  var ups = 0;
  var paused = 0;
  for (var objectId in this.states) {
    if (this.isUp(objectId)) ups++;
    if (this.isPaused(objectId)) paused++;
  }
  if (!this.isMultiTarget() && paused > 0) {
    return PAUSED; // global state is paused because there is only one check
  }
  if ((ups + paused) == this.nbObjects) {
    return UP; // ignore paused in multiTarget
  }
  return DOWN; // at least one of the targets is paused
};

IntervalBuilder.prototype.isUp = function(objectId) {
  return this.states[objectId] == UP;
};

IntervalBuilder.prototype.isDown = function(objectId) {
  return this.states[objectId] == DOWN;
};

IntervalBuilder.prototype.isPaused = function(objectId) {
  return this.states[objectId] == PAUSED;
};

IntervalBuilder.prototype.getTimestamp = function(date) {
  return date.valueOf ? date.valueOf() : date;
};

IntervalBuilder.prototype.completeCurrentInterval = function(timestamp) {
  if (this.currentInterval.length != 1) {
    // no current interval - ignore
    return false;
  }
  if (this.currentState == DOWN) {
    this.downtime += timestamp - this.currentInterval[0];
  }

  this.intervals.push(this.currentInterval.concat([timestamp, this.currentState]));
  return true;
};

module.exports = IntervalBuilder;
<commit_msg>Fix regression on aggregated data<commit_after>var async = require('async');
var CheckEvent = require('../models/checkEvent');
var Check = require('../models/check');

var PAUSED = -1;
var DOWN = 0;
var UP = 1;

/*
 * Usage:
 *   var builder = new IntervalBuilder();
 *   builder.addTarget(check1);
 *   builder.addTarget(check2);
 *   builder.build(begin, end, function(err, intervals, downtime) {
 *     // do things
 *   });
 */
var IntervalBuilder = function() {
  this.objectIds = [];
  this.nbObjects = 0;
  this.states = {};
  this.intervals = []; // intervals are [begin, end, state]
  this.currentState = null;
  this.currentInterval = [];
  this.downtime = 0;
  this.duration = 0;
};

IntervalBuilder.prototype.addTarget = function(objectId) {
  this.objectIds.push(objectId._id ? objectId._id : objectId);
  this.nbObjects++;
};

IntervalBuilder.prototype.build = function(begin, end, callback) {
  var self = this;

  async.auto({
    initialState: function(next) {
        self.determineInitialState(begin, next);
    },
    interval: ['initialState', function(next) {
        self.buildIntervalsForPeriod(begin, end, next);
    }],
    check: ['initialState', 'interval', function (next) {
        self.getCurrentCheck(next)
    }],
    duration: ['initialState', 'interval', 'check', function (next, results) {
        self.calculateDuration(results.check, begin, end, next);
    }],
    downtime: ['initialState', 'interval', 'check', 'duration', function (next, results) {
        self.calculateDowntime(results.check, begin, end, next);
    }]
    }, function(err, results) {
      if (err) {
        return callback(err);
      }

      self.duration = results.duration;
      self.downtime = results.downtime;

      return callback(null, self.intervals, self.downtime, self.duration);
  });
};

IntervalBuilder.prototype.getCurrentCheck = function(callback) {
  Check.findOne({ _id: this.objectIds[0] }, callback);
};

IntervalBuilder.prototype.isMultiTarget = function() {
  return this.nbObjects > 1;
};

IntervalBuilder.prototype.determineInitialState = function(timestamp, callback) {
  var self = this;
  async.forEach(this.objectIds, function(objectId, next) {
    CheckEvent.find()
    .where('check').equals(objectId)
    .where('timestamp').lte(timestamp)
    .sort({ timestamp: -1 })
    .findOne(function(err, checkEvent) {
      if (err) return next(err);
      if (!checkEvent) {
        // No ping ever - start the period as paused
        self.addEvent(objectId, 'paused', timestamp);
        return next();
      }
      self.addEvent(objectId, checkEvent.message);
      next();
    });
  }, function(err) {
    if (err) return callback(err);
    self.updateCurrentState(timestamp);
    return callback(null);
  });
};

IntervalBuilder.prototype.calculateDuration = function(check, begin, end, callback) {
  var durationBegin = Math.max(begin, check.firstTested),
    durationEnd = Math.min(end, check.lastTested),
    duration = durationEnd - durationBegin;

  if (this.isMultiTarget()) {
    // it's a tag - no other way
    return callback(null, duration);
  }

  this.intervals.forEach(function(interval) {
    if (interval[2] != PAUSED || interval[1] < durationBegin || interval[0] > durationEnd) {
      return;
    }

    interval[0] = Math.max(durationBegin, interval[0]);
    interval[1] = Math.min(durationEnd, interval[1]);

    duration -= interval[1] - interval[0];
  });

  return callback(null, duration);
};

IntervalBuilder.prototype.calculateDowntime = function(check, begin, end, callback) {
  var durationBegin = Math.max(begin, check.firstTested);
  var durationEnd = Math.min(end, check.lastTested);

  if (this.isMultiTarget()) {
    // it's a tag - no other way
    return callback(null, this.currentState == DOWN ? durationEnd - durationBegin : 0);
  }

  var downtime = 0;
  var currentIntervalEnd = null;
  this.intervals.forEach(function(interval) {
    currentIntervalEnd = interval[1];
    if (interval[2] != DOWN || interval[1] < durationBegin || interval[0] > durationEnd) {
      return true; // will act as a continue
    }

    interval[0] = Math.max(durationBegin, interval[0]);
    interval[1] = Math.min(durationEnd, interval[1]);

    downtime += interval[1] - interval[0];
  });

  if (!check.isUp) {
    if(currentIntervalEnd === null) {
      downtime += durationEnd - durationBegin;
    }else {
      downtime += durationEnd - currentIntervalEnd;
    }
  }

  return callback(null, downtime);
};

IntervalBuilder.prototype.buildIntervalsForPeriod = function(begin, end, callback) {
  var self = this;
  CheckEvent.find()
  .where('check').in(this.objectIds)
  .where('timestamp').gt(begin).lte(end)
  .sort({ timestamp: 1 })
  .find(function(err, checkEvents) {
    if (err) return callback(err);
    checkEvents.forEach(function(checkEvent) {
      if (self.addEvent(checkEvent.check, checkEvent.message)) {
        self.updateCurrentState(checkEvent.timestamp);
      }
    });
    callback(null);
  });
};

/**
 * Add an event for a given check.
 *
 * Returns true if the event modifies the state of a given check, false otherwise
 */
IntervalBuilder.prototype.addEvent = function(objectId, message) {
  switch (message) {
    case 'up':
      if (!this.isUp(objectId)) {
        this.states[objectId] = UP;
        return true;
      }
      break;
    case 'down':
      if (!this.isDown(objectId)) {
        this.states[objectId] = DOWN;
        return true;
      }
      break;
    case 'paused':
    case 'restarted':
    default:
      if (!this.isPaused(objectId)) {
        this.states[objectId] = PAUSED;
        return true;
      }
      break;
  }
  return false;
};

/**
 * Return true if the global state was updated, false otherwise.
 */
IntervalBuilder.prototype.updateCurrentState = function(timestamp) {
  timestamp = this.getTimestamp(timestamp);
  var currentState = this.getGlobalState();
  if (currentState !== this.currentState) {
    this.completeCurrentInterval(timestamp);
    this.currentInterval = currentState == 1 ? [] : [timestamp];
    this.currentState = currentState;
    return true;
  }
  return false;
};

IntervalBuilder.prototype.getGlobalState = function() {
  var ups = 0;
  var paused = 0;
  for (var objectId in this.states) {
    if (this.isUp(objectId)) ups++;
    if (this.isPaused(objectId)) paused++;
  }
  if (!this.isMultiTarget() && paused > 0) {
    return PAUSED; // global state is paused because there is only one check
  }
  if ((ups + paused) == this.nbObjects) {
    return UP; // ignore paused in multiTarget
  }
  return DOWN; // at least one of the targets is paused
};

IntervalBuilder.prototype.isUp = function(objectId) {
  return this.states[objectId] == UP;
};

IntervalBuilder.prototype.isDown = function(objectId) {
  return this.states[objectId] == DOWN;
};

IntervalBuilder.prototype.isPaused = function(objectId) {
  return this.states[objectId] == PAUSED;
};

IntervalBuilder.prototype.getTimestamp = function(date) {
  return date.valueOf ? date.valueOf() : date;
};

IntervalBuilder.prototype.completeCurrentInterval = function(timestamp) {
  if (this.currentInterval.length != 1) {
    // no current interval - ignore
    return false;
  }
  if (this.currentState == DOWN) {
    this.downtime += timestamp - this.currentInterval[0];
  }

  this.intervals.push(this.currentInterval.concat([timestamp, this.currentState]));
  return true;
};

module.exports = IntervalBuilder;
<|endoftext|>


<commit_before>#!/usr/bin/env node
const server = require('./server')
const serverInfo = server.listen(0, () => {
    const spawn = require('child_process').spawn
    const ls = spawn('mocha-phantomjs',  [`http://localhost:${serverInfo.address().port}/tests.html`])
    let response = []
    ls.stdout.on('data', (data) => {
        response.push(data.toString())
    })
    ls.on('close', code => {
        console.log(response.join(''))
        process.exit(code)
    })
    console.log('Server started at localhost:' + serverInfo.address().port)
})
<commit_msg>Output test results asynchronously<commit_after>#!/usr/bin/env node
const server = require('./server')
const serverInfo = server.listen(0, () => {
    const spawn = require('child_process').spawn
    const mochaPhantomjs = spawn('mocha-phantomjs',  [`http://localhost:${serverInfo.address().port}/tests.html`])
    mochaPhantomjs.stdout.pipe(process.stdout)
    mochaPhantomjs.on('close', code => {
        process.exit(code)
    })
    mochaPhantomjs.on('error', err => {
        console.log(err)
        process.exit(1)
    })
    console.log('Server started at localhost:' + serverInfo.address().port)
})
<|endoftext|>


<commit_before>var express = require('express');
var app = express();
var bodyParser = require('body-parser');
var fs = require('fs');
app.use(bodyParser.urlencoded({extended: false}));
app.use(bodyParser.json());
var AlarmManager = require('./MasterOfTime/controller/AlarmManager');
const Runner = require('./MasterOfTime/controller/AlarmRunner');

var alarmManager = new AlarmManager();

const requestSender = require('request');
const push = require('./MasterOfTime/controller/push')
const reply = require('./MasterOfTime/controller/reply');
const LINE_CONSTS = require('./MasterOfTime/model/line');

app.set('port', process.env.PORT || 8000);

var https_server = app.listen(app.get('port'), function() {
	console.log('Express https server listening on port ' + https_server.address().port);
});

app.get('/', (req, res) => {
	console.log('[GET]/');
	res.writeHead(200, {'Content-Type' : 'text/html'});
	res.end('
Hello, I\'m the Master of Time!
');
});

app.get('/hook', (req, res) => {
	console.log('[GET]hook!');
	res.writeHead(200, {'Content-Type' : 'text/html'});
	res.end('
Hello, I\'m the Master of Time!
');
});

app.post('/hook', (req, res) => {
	var eventObj = req.body.events[0];
	var source = eventObj.source;
	var message = eventObj.message;
	console.log('======================', new Date() ,'======================');
	console.log('[request]', req.body);
	console.log('[request source] ', source);
	console.log('[request message]', message);
	console.log('[request text]', message.text);
	if(message.type == "text") {
		var runner = Runner.getRunner(message.text);
		if(runner) {
			var id;
			if(source.type == "user") {
				id = source.userId;
			}
			else if(source.type == "group") {
				id = source.groupId;
			}
			 else if(source.type == "room") {
				id = source.roomId;
			}
			console.log('[Request Source] type: ', source.type);
			console.log('[Request Source] id: ', id);
			runner.setId(id);
			runner.setChannelAccessToken(LINE_CONSTS.CHANNEL_ACCESS_TOKEN);
			runner.run();
		}
		else {	// if runner is null or undefined
			console.log(message.text);
			var message = [{"type": "text", "text" : "요청 메시지가 잘못 되었습니다 :)"}];
			reply.send(LINE_CONSTS.CHANNEL_ACCESS_TOKEN, eventObj.replyToken, message);
		}
	}
	res.sendStatus(200);
});

app.get('/log', function(req, res){
	fs.readFile('server.log','utf8',function(err, data){
		if(err){
			console.log(err);
			res.status(500).send('Internal Sever Error');
		}
		data = data.replace(/(?:\r\n|\r|\n)/g,'
');
		res.send(data);
	});
});

app.get('/remove', function(req, res){
  alarmManager.run('remove');
  res.send('remove');
});

// app.get('/on', function(req, res){
//   alarmManager.run('on');
//   res.send('on');
// });

// app.get('/off', function(req, res){
//   alarmManager.run('off');
//   res.send('off');
// });

// app.get('/list', function(req, res){
//   alarmManager.run('list');
//   res.send('list');
// });

app.post('/alarm', function(req, res){
	var desc = req.body.desc;
	var id = req.body.id;
	var name = req.body.alarmName;
	console.log('[Alarm Request] desc: ', desc);
	console.log('[Alarm Request] id: ', id);
	console.log('[Alarm Request] alarmName: ', name);
	var displayText = name + ' 알람: ' + desc;
	var message = [{"type": "text", "text" : displayText}];
	push.send(LINE_CONSTS.CHANNEL_ACCESS_TOKEN, id, message);
});

// app.post('/list', function(req, res){
//   var list = req.body.list;
//   res.send("
"+list+"
");
//   console.log(list);
// });

app.get('/clear', function(req, res){
  alarmManager.run('clear');
  res.send('clear');
});

// app.listen(8000, function(){
//   console.log('Connected 8000 port!');
// });

module.exports = app;
<commit_msg>reply message<commit_after>var express = require('express');
var app = express();
var bodyParser = require('body-parser');
var fs = require('fs');
app.use(bodyParser.urlencoded({extended: false}));
app.use(bodyParser.json());
var AlarmManager = require('./MasterOfTime/controller/AlarmManager');
const Runner = require('./MasterOfTime/controller/AlarmRunner');

var alarmManager = new AlarmManager();

const requestSender = require('request');
const push = require('./MasterOfTime/controller/push')
const reply = require('./MasterOfTime/controller/reply');
const LINE_CONSTS = require('./MasterOfTime/model/line');

app.set('port', process.env.PORT || 8000);

var https_server = app.listen(app.get('port'), function() {
	console.log('Express https server listening on port ' + https_server.address().port);
});

app.get('/', (req, res) => {
	console.log('[GET]/');
	res.writeHead(200, {'Content-Type' : 'text/html'});
	res.end('
Hello, I\'m the Master of Time!
');
});

app.get('/hook', (req, res) => {
	console.log('[GET]hook!');
	res.writeHead(200, {'Content-Type' : 'text/html'});
	res.end('
Hello, I\'m the Master of Time!
');
});

app.post('/hook', (req, res) => {
	var eventObj = req.body.events[0];
	var source = eventObj.source;
	var message = eventObj.message;
	console.log('======================', new Date() ,'======================');
	console.log('[request]', req.body);
	console.log('[request source] ', source);
	console.log('[request message]', message);
	console.log('[request text]', message.text);
	if(message.type == "text") {
		var runner = Runner.getRunner(message.text);
		if(runner) {
			var id;
			if(source.type == "user") {
				id = source.userId;
			}
			else if(source.type == "group") {
				id = source.groupId;
			}
			 else if(source.type == "room") {
				id = source.roomId;
			}
			console.log('[Request Source] type: ', source.type);
			console.log('[Request Source] id: ', id);
			runner.setId(id);
			runner.setChannelAccessToken(LINE_CONSTS.CHANNEL_ACCESS_TOKEN);

			resultMessage = runner.run();
			reply.send(LINE_CONSTS.CHANNEL_ACCESS_TOKEN, eventObj.replyToken, resultMessage.message);

		}
		else {	// if runner is null or undefined
			console.log(message.text);
			var message = [{"type": "text", "text" : "요청 메시지가 잘못 되었습니다 :)"}];
			reply.send(LINE_CONSTS.CHANNEL_ACCESS_TOKEN, eventObj.replyToken, message);
		}
	}
	res.sendStatus(200);
});

app.get('/log', function(req, res){
	fs.readFile('server.log','utf8',function(err, data){
		if(err){
			console.log(err);
			res.status(500).send('Internal Sever Error');
		}
		data = data.replace(/(?:\r\n|\r|\n)/g,'
');
		res.send(data);
	});
});

app.get('/remove', function(req, res){
  alarmManager.run('remove');
  res.send('remove');
});

// app.get('/on', function(req, res){
//   alarmManager.run('on');
//   res.send('on');
// });

// app.get('/off', function(req, res){
//   alarmManager.run('off');
//   res.send('off');
// });

// app.get('/list', function(req, res){
//   alarmManager.run('list');
//   res.send('list');
// });

app.post('/alarm', function(req, res){
	var desc = req.body.desc;
	var id = req.body.id;
	var name = req.body.alarmName;
	console.log('[Alarm Request] desc: ', desc);
	console.log('[Alarm Request] id: ', id);
	console.log('[Alarm Request] alarmName: ', name);
	var displayText = name + ' 알람: ' + desc;
	var message = [{"type": "text", "text" : displayText}];
	push.send(LINE_CONSTS.CHANNEL_ACCESS_TOKEN, id, message);
	res.sendStatus(200);
});

// app.post('/list', function(req, res){
//   var list = req.body.list;
//   res.send("
"+list+"
");
//   console.log(list);
//	res.sendStatus(200);
// });

app.get('/clear', function(req, res){
	alarmManager.run('clear');
	res.send('clear');
});

// app.listen(8000, function(){
//   console.log('Connected 8000 port!');
// });

module.exports = app;
<|endoftext|>


<commit_before>/**
 * @fileOverview
 * @author Kris Walker <kris@kixx.name>
 *
 * Copyright (c) 2010 The Fireworks Project <www.fireworksproject.com>
 * Some rights are reserved, but licensed to you under the MIT license.
 * See MIT-LICENSE or http://opensource.org/licenses/mit-license.php
 * for more information.
 */

/*jslint
  laxbreak: true
, onevar: true
, undef: true
, nomen: true
, eqeqeq: true
, plusplus: true
, bitwise: true
, regexp: true
, newcap: true
, immed: true
, strict: true
*/

/*global require: false, exports: true, console: false */

'use strict';

var Cc =   require('chrome').Cc
  , Ci =   require('chrome').Ci
  , Cr =   require('chrome').Cr
  , file = require('file')
  , Path
  ;

function nsIFile(path) {
  var file = Cc['@mozilla.org/file/local;1']
             .createInstance(Ci.nsILocalFile);
  file.initWithPath(path);
  return file;
}

exports.Path = exports.path = Path = function (str) {
    if (!(this instanceof Path)) {
        return new Path(str);
    }
    this.path = str;
};

Path.prototype = {

      join: function join(paths) {
          paths = [this.path].concat(Array.prototype.slice.call(arguments));
          try {
              return new Path(file.join.apply(file, paths));
          } catch (e) {
              if (e.result === Cr.NS_ERROR_FILE_UNRECOGNIZED_PATH) {
                  throw new TypeError('unrecognized path: '+ paths);
              }
              throw e;
          }
      }

    , rm: function rm() {
          var f = nsIFile(this.path);
          if (f.exists()) {
              f.remove(true);
          }
          return this;
      }

    , mkpath: function mkpath() {
          file.mkpath(this.path);
          return this;
      }

    , mtime: function mtime() {
        try {
          return new Date(nsIFile(this.path).lastModifiedTime);
        } catch (e) {
            if (e.result === Cr.NS_ERROR_FILE_TARGET_DOES_NOT_EXIST) {
                return new Date(0);
            }
            else {
                throw e;
            }
        }
      }
};
<commit_msg>exists() and read() method for file Paths.<commit_after>/**
 * @fileOverview
 * @author Kris Walker <kris@kixx.name>
 *
 * Copyright (c) 2010 The Fireworks Project <www.fireworksproject.com>
 * Some rights are reserved, but licensed to you under the MIT license.
 * See MIT-LICENSE or http://opensource.org/licenses/mit-license.php
 * for more information.
 */

/*jslint
  laxbreak: true
, onevar: true
, undef: true
, nomen: true
, eqeqeq: true
, plusplus: true
, bitwise: true
, regexp: true
, newcap: true
, immed: true
, strict: true
*/

/*global require: false, exports: true, console: false */

'use strict';

var Cc =   require('chrome').Cc
  , Ci =   require('chrome').Ci
  , Cr =   require('chrome').Cr
  , file = require('file')
  , Path
  ;

function nsIFile(path) {
  var file = Cc['@mozilla.org/file/local;1']
             .createInstance(Ci.nsILocalFile);
  file.initWithPath(path);
  return file;
}

exports.Path = exports.path = Path = function (str) {
    if (!(this instanceof Path)) {
        return new Path(str);
    }
    this.path = str;
};

Path.prototype = {
    toString: function toString() {
        return this.path;
    }

  , valueOf: function valueOf() {
        return this.toString();
    }

  , join: function join(paths) {
        paths = [this.path].concat(Array.prototype.slice.call(arguments));
        try {
            return new Path(file.join.apply(file, paths));
        } catch (e) {
            if (e.result === Cr.NS_ERROR_FILE_UNRECOGNIZED_PATH) {
                throw new TypeError('unrecognized path: '+ paths);
            }
            throw e;
        }
    }

  , exists: function exists() {
        return nsIFile(this.path).exists();
    }

  , rm: function rm() {
        var f = nsIFile(this.path);
        if (f.exists()) {
            f.remove(true);
        }
        return this;
    }

  , mkpath: function mkpath() {
        file.mkpath(this.path);
        return this;
    }

  , mtime: function mtime() {
      try {
        return new Date(nsIFile(this.path).lastModifiedTime);
      } catch (e) {
          if (e.result === Cr.NS_ERROR_FILE_TARGET_DOES_NOT_EXIST) {
              return new Date(0);
          }
          else {
              throw e;
          }
      }
    }

  , read: function read() {
      return file.read(this.path);
    }
};

<|endoftext|>


<commit_before>/*
* Controller for the admin view.
*
* @author Markus Riegel <riegel.markus@googlemail.com>
*/

angular.module('viewAdminController',[
])

.controller('ViewAdminController',[
'$scope','LpUserService',
function($scope,LpUserService){

}]);
<commit_msg>basic data loading<commit_after>/*
* Controller for the admin view.
*
* @author Markus Riegel <riegel.markus@googlemail.com>
*/

angular.module('viewAdminController',[
	'lpUserService',
	'lpItemService'
])

.controller('ViewAdminController',[
'$scope','LpUserService','LpItemService',
function($scope,LpUserService,LpItemService){

	$scope.users;
	$scope.items;

	LpUserService.readUserList(function(users)){
		$scope.users = users;
	}

	LpItemService.loadItems(function(items){
		$scope.items = items;
	})

}]);
<|endoftext|>


<commit_before>'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.create = undefined;

require('babel-polyfill');

var _fs = require('fs');

var _path = require('path');

var _lodash = require('lodash.merge');

var _lodash2 = _interopRequireDefault(_lodash);

var _Tipsbot = require('./Tipsbot');

var _Tipsbot2 = _interopRequireDefault(_Tipsbot);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

var tokenPath = (0, _path.resolve)(__dirname, '..', '..', 'token.js');
var defaultToken = (0, _fs.existsSync)(tokenPath) ? require(tokenPath) : null;
var defaultName = 'Tipsbot';
var defaultTips = (0, _path.resolve)(__dirname, '..', '..', 'data', 'pragmatic-programmer.json');
var defaultChannel = 'general';
var defaultSchedule = '0 9 * * 1,2,3,4,5'; // 09:00 on monday-friday
var defaultStartIndex = 0;
var defaultIconURL = '';

var create = exports.create = function create() {
  var options = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];

  var defaults = {
    token: process.env.BOT_API_KEY || defaultToken,
    name: process.env.BOT_NAME || defaultName,
    filePath: process.env.BOT_FILE_PATH || defaultTips,
    channel: process.env.BOT_CHANNEL || defaultChannel,
    schedule: process.env.BOT_SCHEDULE || defaultSchedule,
    startIndex: process.env.BOT_START_INDEX || defaultStartIndex,
    iconURL: process.env.BOT_ICON_URL || defaultIconURL
  };

  return new _Tipsbot2.default((0, _lodash2.default)(defaults, options));
};<commit_msg>Add latest fix to build<commit_after>'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.create = undefined;

require('babel-polyfill');

var _fs = require('fs');

var _path = require('path');

var _lodash = require('lodash.merge');

var _lodash2 = _interopRequireDefault(_lodash);

var _Tipsbot = require('./Tipsbot');

var _Tipsbot2 = _interopRequireDefault(_Tipsbot);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

var tokenPath = (0, _path.resolve)(__dirname, '..', '..', 'token.js');
var defaultToken = (0, _fs.existsSync)(tokenPath) ? require(tokenPath) : '';
var defaultName = 'Tipsbot';
var defaultTips = (0, _path.resolve)(__dirname, '..', '..', 'data', 'pragmatic-programmer.json');
var defaultChannel = 'general';
var defaultSchedule = '0 9 * * 1-5'; // 09:00 on monday-friday
var defaultStartIndex = 0;
var defaultIconURL = '';

var create = exports.create = function create() {
  var options = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];

  var defaults = {
    token: process.env.BOT_API_KEY || defaultToken,
    name: process.env.BOT_NAME || defaultName,
    filePath: process.env.BOT_FILE_PATH || defaultTips,
    channel: process.env.BOT_CHANNEL || defaultChannel,
    schedule: process.env.BOT_SCHEDULE || defaultSchedule,
    startIndex: process.env.BOT_START_INDEX || defaultStartIndex,
    iconURL: process.env.BOT_ICON_URL || defaultIconURL
  };

  return new _Tipsbot2.default((0, _lodash2.default)(defaults, options));
};<|endoftext|>


<commit_before>/*
 * Licensed to Apereo under one or more contributor license
 * agreements. See the NOTICE file distributed with this work
 * for additional information regarding copyright ownership.
 * Apereo licenses this file to you 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 the following location:
 *
 *   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.
 */
'use strict';

define(['angular'], function(angular) {
  return angular.module('portal.main.services', [])

  .factory('mainService', [
    '$http', '$log', '$sessionStorage',
    'miscService', 'SERVICE_LOC', 'APP_FLAGS', '$rootScope', 'NAMES',
    function($http, $log, $sessionStorage,
             miscService, SERVICE_LOC, APP_FLAGS, $rootScope, NAMES) {
      var prom = $http.get(SERVICE_LOC.sessionInfo, {cache: true});
      var userPromise;

      var getUser = function() {
        if (userPromise) {
          return userPromise;
        }

        userPromise = prom
          .then(function(result, status) { // success function
            var person = result.data.person;
            if (APP_FLAGS.loginOnLoad) {
              // quick check to make sure you are who your browser says you are
              if (
                $sessionStorage.portal && $sessionStorage.portal.username &&
                person.userName !== $sessionStorage.portal.username &&
                person.originalUsername !== $sessionStorage.portal.username
              ) {
                $log.warn('Thought they were '
                  + $sessionStorage.portal.username
                  + ' but session sent back '
                  + person.userName +'. Redirect!');
                delete $sessionStorage.portal;
                miscService.redirectUser(
                  302, 'Wrong User than populated in session storage.');
              }
            }
            return person;
          })
          .catch(function(data, status) { // failure function
            miscService.redirectUser(status, 'Get User Info');
          });
        return userPromise;
    };

    return {
      getUser: getUser,
    };
  }]);
});
<commit_msg>refactor: add mainService dependency on $document<commit_after>/*
 * Licensed to Apereo under one or more contributor license
 * agreements. See the NOTICE file distributed with this work
 * for additional information regarding copyright ownership.
 * Apereo licenses this file to you 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 the following location:
 *
 *   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.
 */
'use strict';

define(['angular'], function(angular) {
  return angular.module('portal.main.services', [])

  .factory('mainService', [
    '$http', '$log', '$sessionStorage',
    'miscService', 'SERVICE_LOC', 'APP_FLAGS', '$rootScope', 'NAMES',
    '$document',
    function($http, $log, $sessionStorage,
             miscService, SERVICE_LOC, APP_FLAGS, $rootScope, NAMES,
             $document) {
      var prom = $http.get(SERVICE_LOC.sessionInfo, {cache: true});
      var userPromise;

      var getUser = function() {
        if (userPromise) {
          return userPromise;
        }

        userPromise = prom
          .then(function(result, status) { // success function
            var person = result.data.person;
            if (APP_FLAGS.loginOnLoad) {
              // quick check to make sure you are who your browser says you are
              if (
                $sessionStorage.portal && $sessionStorage.portal.username &&
                person.userName !== $sessionStorage.portal.username &&
                person.originalUsername !== $sessionStorage.portal.username
              ) {
                $log.warn('Thought they were '
                  + $sessionStorage.portal.username
                  + ' but session sent back '
                  + person.userName +'. Redirect!');
                delete $sessionStorage.portal;
                miscService.redirectUser(
                  302, 'Wrong User than populated in session storage.');
              }
            }
            return person;
          })
          .catch(function(data, status) { // failure function
            miscService.redirectUser(status, 'Get User Info');
          });
        return userPromise;
    };

    return {
      getUser: getUser,
    };
  }]);
});
<|endoftext|>


<commit_before>var fs = require('graceful-fs')
var index = require('./index.js')
var recursive = require('recursive-readdir')
var Entities = require('html-entities').XmlEntities
var entities = new Entities()
var _ = require('lodash')
var debug = require('debug')('canary-perch:extract')

var numberOfFiles
var finished

var extractor = function (hosts, inputIndex, outputIndex, inputType, outputType, dictDir) {
  this.hosts = hosts
  this.inputIndex = inputIndex
  this.outputIndex = outputIndex
  this.inputType = inputType
  this.outputType = outputType
  this.dictDir = dictDir
}

extractor.prototype.readDictionaries = function () {
  var Extractor = this
  var folder = Extractor.dictDir + '/json/'
  var client = index.ESClient(Extractor.hosts)
  debug('starting extractions with dictionaries from: ' + folder)
  recursive(folder, function (err, files) {
    if (err) throw err
    numberOfFiles = files.length
    finished = _.after(numberOfFiles, () => {
      if (err) throw err
      console.log('all extractions finished')
    })
    files.forEach(function (file) {
      fs.readFile(file, 'utf8', function (err, data) {
        if (err) throw err
        Extractor.dictionaryQuery(JSON.parse(data), client)
      })
    })
  })
}

// Pass it the full dictionary first time. On the last successful upload of data
// run again with the first entry removed and repeate until empty
extractor.prototype.dictionaryQuery = function (dictionary, client) {
  var Extractor = this
  debug('extracting from dictionary: ' + dictionary.id)
  setTimeout(function () {
    if (dictionary.entries.length) {
      var entry = dictionary.entries.shift()
      Extractor.dictionarySingleQuery(entry, dictionary, client)
    } else {
      console.log('finished extraction')
      finished()
      return
    }
  }, 0)
}

extractor.prototype.dictionarySingleQuery = function (entry, dictionary, client) {
  debug('searching for term: ' + entry.term)
  var Extractor = this
  client.search({
    index: Extractor.inputIndex,
    type: Extractor.inputType,
    body: {
      _source: false,
      fields: ['cprojectID'],
      query: {
        match_phrase: {
          fulltext: entry.term
        }
      },
      highlight: {
        encoder: 'html',
        fields: {
          fulltext: { boundary_chars: '.,!?\t\n' }
        }
      }
    }
  }, function (error, response) {
    if (error) {
      console.log(error)
    }
    if (!error) {
      debug('response: ' + JSON.stringify(response))
      if (response.hits.hits.length === 0) {
        Extractor.dictionaryQuery.bind(Extractor, dictionary, undefined, client)
      } else {
        for (var j = 0; j < response.hits.hits.length; j++) {
          Extractor.uploadOneDocFacts(response.hits.hits[j], dictionary, entry, client)
        }
        Extractor.dictionaryQuery.bind(Extractor, dictionary, undefined, client)
      }
    }
  })
}

// insert all the facts from one document as returned by ES
extractor.prototype.uploadOneDocFacts = function (oneDocFacts, dictionary, entry, client) {
  var Extractor = this
  // console.log('snippet array is: ' + snippetArray)
  var snippetArray = oneDocFacts.highlight.fulltext
  for (var i = 0; i < snippetArray.length; i++) {
    var match = snippetArray[i]
    var fact = {}
    if (match.indexOf('') !== -1) {
      fact.prefix = match.split('')[0]
      fact.term = match.split('')[1].split('')[0]
      fact.postfix = match.split('')[1]
    } else {
      fact.prefix = ''
      fact.term = match
      fact.postfix = ''
    }
    fact.prefix = entities.decode(fact.prefix)
    fact.term = entities.decode(fact.term)
    fact.postfix = entities.decode(fact.postfix)
    fact.docId = oneDocFacts._id
    fact.cprojectID = oneDocFacts.fields.cprojectID
    Extractor.uploadOneFact(fact, dictionary, entry, client)
  }
}

extractor.prototype.uploadOneFact = function (fact, dictionary, entry, client) {
  var Extractor = this
  // console.log("uploading one fact")
  client.index({
    index: Extractor.outputIndex,
    type: Extractor.outputType,
    body: {
      'prefix': fact.prefix,
      'post': fact.postfix,
      'term': fact.term,
      'documentID': fact.docId,
      'cprojectID': fact.cprojectID,
      'identifiers': entry.identifiers
    }
  }, function (err) {
    if (err) console.log(err)
  })
}

module.exports = extractor
<commit_msg>actaully execute bound next dictionary query<commit_after>var fs = require('graceful-fs')
var index = require('./index.js')
var recursive = require('recursive-readdir')
var Entities = require('html-entities').XmlEntities
var entities = new Entities()
var _ = require('lodash')
var debug = require('debug')('canary-perch:extract')

var numberOfFiles
var finished

var extractor = function (hosts, inputIndex, outputIndex, inputType, outputType, dictDir) {
  this.hosts = hosts
  this.inputIndex = inputIndex
  this.outputIndex = outputIndex
  this.inputType = inputType
  this.outputType = outputType
  this.dictDir = dictDir
}

extractor.prototype.readDictionaries = function () {
  var Extractor = this
  var folder = Extractor.dictDir + '/json/'
  var client = index.ESClient(Extractor.hosts)
  debug('starting extractions with dictionaries from: ' + folder)
  recursive(folder, function (err, files) {
    if (err) throw err
    numberOfFiles = files.length
    finished = _.after(numberOfFiles, () => {
      if (err) throw err
      console.log('all extractions finished')
    })
    files.forEach(function (file) {
      fs.readFile(file, 'utf8', function (err, data) {
        if (err) throw err
        Extractor.dictionaryQuery(JSON.parse(data), client)
      })
    })
  })
}

// Pass it the full dictionary first time. On the last successful upload of data
// run again with the first entry removed and repeate until empty
extractor.prototype.dictionaryQuery = function (dictionary, client) {
  var Extractor = this
  debug('extracting ' + dictionary.entries.length + ' entries from dictionary: ' + dictionary.id)
  if (dictionary.entries.length) {
    var entry = dictionary.entries.shift()
    Extractor.dictionarySingleQuery(entry, dictionary, client)
  } else {
    console.log('finished extraction')
    finished()
    return
  }
}

extractor.prototype.dictionarySingleQuery = function (entry, dictionary, client) {
  debug('searching for term: ' + entry.term)
  var Extractor = this
  client.search({
    index: Extractor.inputIndex,
    type: Extractor.inputType,
    body: {
      _source: false,
      fields: ['cprojectID'],
      query: {
        match_phrase: {
          fulltext: entry.term
        }
      },
      highlight: {
        encoder: 'html',
        fields: {
          fulltext: { boundary_chars: '.,!?\t\n' }
        }
      }
    }
  }, function (error, response) {
    if (error) {
      console.log(error)
    }
    if (!error) {
      debug('response: ' + JSON.stringify(response))
      if (response.hits.hits.length === 0) {
        Extractor.dictionaryQuery.bind(Extractor, dictionary, client)()
      } else {
        for (var j = 0; j < response.hits.hits.length; j++) {
          Extractor.uploadOneDocFacts(response.hits.hits[j], dictionary, entry, client)
        }

        Extractor.dictionaryQuery.bind(Extractor, dictionary, client)()
      }
    }
  })
}

// insert all the facts from one document as returned by ES
extractor.prototype.uploadOneDocFacts = function (oneDocFacts, dictionary, entry, client) {
  var Extractor = this
  // console.log('snippet array is: ' + snippetArray)
  var snippetArray = oneDocFacts.highlight.fulltext
  for (var i = 0; i < snippetArray.length; i++) {
    var match = snippetArray[i]
    var fact = {}
    if (match.indexOf('') !== -1) {
      fact.prefix = match.split('')[0]
      fact.term = match.split('')[1].split('')[0]
      fact.postfix = match.split('')[1]
    } else {
      fact.prefix = ''
      fact.term = match
      fact.postfix = ''
    }
    fact.prefix = entities.decode(fact.prefix)
    fact.term = entities.decode(fact.term)
    fact.postfix = entities.decode(fact.postfix)
    fact.docId = oneDocFacts._id
    fact.cprojectID = oneDocFacts.fields.cprojectID
    Extractor.uploadOneFact(fact, dictionary, entry, client)
  }
}

extractor.prototype.uploadOneFact = function (fact, dictionary, entry, client) {
  var Extractor = this
  // console.log("uploading one fact")
  client.index({
    index: Extractor.outputIndex,
    type: Extractor.outputType,
    body: {
      'prefix': fact.prefix,
      'post': fact.postfix,
      'term': fact.term,
      'documentID': fact.docId,
      'cprojectID': fact.cprojectID,
      'identifiers': entry.identifiers
    }
  }, function (err) {
    if (err) console.log(err)
  })
}

module.exports = extractor
<|endoftext|>


<commit_before>var hookshot = require('hookshot');
hookshot('refs/heads/master', 'git fetch origin && git checkout origin/master').listen(9732)
<commit_msg>Updating hookshot calls.<commit_after>var hookshot = require('hookshot');
hookshot('refs/heads/master', 'git fetch origin && git checkout origin/master && service ghost-coqui restart').listen(9732)
<|endoftext|>


<commit_before>/**
 * Details Collection
 *
 */
define([
  'jquery',
  'backbone',
  'underscore',
  'collections/base_jobs',
  'components/functor'
], function($,
            Backbone,
            _,
            JobsCollection,
            Functor) {

  var DetailsCollection;

  var slice = Array.prototype.slice;

  DetailsCollection = JobsCollection.extend({

    initialize: function() {
      this.listenTo(this, {
        add: this.serialize,
        remove: this.serialize
      });
    },

    deserialize: function(path) {
      var modelNames = _.uniq(path.split('/')),
          collection = this,
          modelNamesMap,
          models,
          untrackedModels,
          name;

      modelNamesMap = _.object(modelNames,
                               _.times(modelNames.length, Functor(true)));

      models = app.jobsCollection.filter(function(job) {
        if (!!(name = job.get('name'))) { return !!modelNamesMap[name]; }
        return false;
      });

      untrackedModels = _.filter(models, function(model) {
        var name = model.get('name'),
            other = collection.where({name: name});

        return !(!name || !!other.length);
      });

      this.add(untrackedModels);
    },

    serialize: function(model, collection, options) {
      var base = ['jobs'],
          isFake = options && options.create,
          names,
          path;

      if (isFake || model.isNew()) {
        return false;
      }

      if (this.length) {
        names = _.chain(this.where({persisted: true})).map(function(job) {
          return job.get('name');
        }).reject(function(name) {
          return name === '-';
        }).value();
        path = base.concat(names).join('/');
      } else {
        path = '/'
      }

      console.log('details serialize', path);

      // TODO: hack to fix jobs/:jobName////////////// infinite redirect
      if (path.slice(-1) == '-') {
        return false;
      }

      app.router.navigate(path, {trigger: true});
    }
  });

  return DetailsCollection;
})
<commit_msg>Stop triggering route on job nav<commit_after>/**
 * Details Collection
 */
define([
  'jquery',
  'backbone',
  'underscore',
  'collections/base_jobs',
  'components/functor'
], function($,
            Backbone,
            _,
            JobsCollection,
            Functor) {

  'use strict';

  var DetailsCollection = JobsCollection.extend({

    initialize: function() {
      this.listenTo(this, {
        add: this.serialize,
        remove: this.serialize
      });
    },

    deserialize: function(path) {
      var modelNames = _.uniq(path.split('/')),
          collection = this,
          modelNamesMap,
          models,
          untrackedModels,
          name;

      modelNamesMap = _.object(modelNames,
                               _.times(modelNames.length, Functor(true)));

      models = app.jobsCollection.filter(function(job) {
        if (!!(name = job.get('name'))) { return !!modelNamesMap[name]; }
        return false;
      });

      untrackedModels = _.filter(models, function(model) {
        var name = model.get('name'),
            other = collection.where({name: name});

        return !(!name || !!other.length);
      });

      this.add(untrackedModels);
    },

    serialize: function(model, collection, options) {
      var base = ['jobs'],
          isFake = options && options.create,
          names,
          path;

      if (isFake || model.isNew()) {
        return false;
      }

      if (this.length) {
        names = _.chain(this.where({persisted: true})).map(function(job) {
          return job.get('name');
        }).reject(function(name) {
          return name === '-';
        }).value();
        path = base.concat(names).join('/');
      } else {
        path = '/';
      }

      console.log('details serialize', path);

      // TODO: hack to fix jobs/:jobName////////////// infinite redirect
      if (path.slice(-1) === '-') {
        return false;
      }

      app.router.navigate(path);
    }
  });

  return DetailsCollection;
});
<|endoftext|>


<commit_before>import path from 'path';
import express from 'express';
import bodyParser from 'body-parser';
import config from '../config';
import logger from './logger';
import apiRouter from './api-router';
import { notFound, logErrors, clientErrorHandler, errorHandler } from './error-handlers';
import { NotFoundException } from './exceptions';

// Set Winston console log level
logger.transports.console.level = config.logger.console.level;

// console.log === console.log in webpack.config
//eslint-disable-next-line no-console
console.log('express:',
  `NODE_ENV: "${process.env.NODE_ENV}",`,
  `isProd: ${config.isProd},`,
  `isDev: ${config.isDev},`,
  `isTest: ${config.isTest},`,
  `isHot: ${config.isHot},`,
  `loglevel: "${config.logger.console.level}",`,
  `public: "${config.server.publicPath}",`,
  `api: "${config.apiPath}"`);

let devMiddleware = null;

const app = express();
app.disable('x-powered-by');

// Middleware for handling JSON, Raw, Text and URL encoded form data
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());

if (config.server.compress) {
  // compression middleware compresses your server responses which makes them
  // smaller (applies also to assets). You can read more about that technique
  // and other good practices on official Express.js docs http://mxs.is/googmy
  const compression = require('compression'); // eslint-disable-line global-require
  app.use(compression());
}

if (config.proxy) {
  // Proxy to api server
  const proxy = require('http-proxy-middleware'); // eslint-disable-line global-require

  const useProxy = (proxyConfig) => {
    app.use(proxy(proxyConfig.context, {
      ...proxyConfig.options,
      onProxyReq(req) {
        logger.info(`Proxy to: ${req.path}`);
      }
    }));
  };

  if (Array.isArray(config.proxy)) {
    config.proxy.forEach( p => {
      useProxy(p);
    });
  }
  else {
    useProxy(config.proxy);
  }
}
else {
  // Api routes
  app.use(config.apiPath, apiRouter);
}

// Uncomment to disable historyApiFallback without modifying config files
//config.server.historyApiFallback = false;

if (config.server.historyApiFallback) {
  // This rewrites all routes requests to the root /index.html file
  // (ignoring file requests). If you want to implement universal
  // rendering, you'll want to remove this middleware.
  const history = require('connect-history-api-fallback'); // eslint-disable-line global-require
  app.use(history(config.server.historyApiFallback));
}

if (config.isProd && !config.isTest) {
  app.use(config.server.publicPath, express.static(config.server.contentBase));

  app.get('*', (req, res, next) => {

    const reqPath = req.path.startsWith(config.server.publicPath)
      ? req.path.replace(config.server.publicPath, '')
      : req.path;

    const target = reqPath.indexOf('.') > -1
      ? path.join(config.server.contentBase, reqPath)
      : path.join(config.server.contentBase, 'index.html');

    logger.info('### app.get * from:', req.path, 'to:', target);

    res.sendFile(target, err => {
      if (err) {
        next(NotFoundException(req.path));
      }
    });
  });
}

if (config.isDev || config.isTest) {
  // Step 1: Create & configure a webpack compiler
  const webpack = require('webpack'); // eslint-disable-line global-require
  const webpackConfig = require('../webpack.config.babel'); // eslint-disable-line global-require
  const webpackCompiler = webpack(webpackConfig);
  webpackCompiler.apply(new webpack.ProgressPlugin());

  // Step 2: Attach the dev middleware to the compiler & the server
  // Config options:
  //   see: https://github.com/webpack/webpack-dev-middleware
  //   see: https://webpack.js.org/configuration/dev-server/
  //   see: https://webpack.js.org/configuration/stats/
  //   see: https://webpack.github.io/docs/webpack-dev-server.html
  //   see: https://github.com/chimurai/http-proxy-middleware
  //   see: https://github.com/bripkens/connect-history-api-fallback
  //   NOTE: Only use options compatible with webpack-dev-middleware
  const webpackDevMiddleware = require('webpack-dev-middleware'); // eslint-disable-line global-require

  devMiddleware = webpackDevMiddleware(webpackCompiler, {
    publicPath: webpackConfig.output.publicPath,
    hot: config.isHot,
    noInfo: true,
    stats: {
      errors: true,
      colors: true,
    },
  });
  app.use(devMiddleware);

  // Step 3: Attach the hot middleware to the compiler & the server
  // Config options:
  //   See: https://github.com/glenjamin/webpack-hot-middleware
  if (config.isHot) {
    app.use(require('webpack-hot-middleware')(webpackCompiler));

    /*
    const webpackHotMiddleware = require('webpack-hot-middleware'); // eslint-disable-line global-require
    const hotMiddleware = webpackHotMiddleware(webpackCompiler, {
      path: '/__webpack_hmr'
      // You can use full urls, like:
      // path: `http://${host}:${port}${publicPath}/__webpack_hmr`
      // Remember to update webpack-hot-middleware in ../webpack-config.babel
    });
    app.use(hotMiddleware);
    */
  }

  // Add public path after step 3
  app.use(config.server.publicPath, express.static(config.server.contentBase));

  // Since webpackDevMiddleware uses memory-fs internally to store build
  // artifacts, we use it instead
  const memoryFs = devMiddleware.fileSystem;

  app.get('*', (req, res, next) => {

    const reqPath = req.path.startsWith(config.server.publicPath)
      ? req.path.replace(config.server.publicPath, '')
      : req.path;

    const target = reqPath.indexOf('.') > -1
      ? path.join(webpackCompiler.outputPath, reqPath)
      : path.join(webpackCompiler.outputPath, 'index.html');

    if (target.endsWith('.html')) {
      // 1: Read from memory fs
      logger.info('1 app.get * from:', req.path, 'to:', target);
      memoryFs.readFile(target, (err, file) => {
        if (err) {
          next(NotFoundException(req.path));
        } else {
          res.send(file.toString());
        }
      });
    }
    else {
      // 2: Try reading from outputPath, i.e. "dist"
      logger.info('2 app.get * from:', req.path, 'to:', target);
      res.sendFile(target, err => {
        if (err) {
          // 3: Try reading from src
          const src = path.join(config.server.contentBase, reqPath);
          logger.info('3 app.get * from:', req.path, 'to:', src);

          res.sendFile(src, err => {
            if (err) {
              next(NotFoundException(req.path));
            }
          });
        }
      });
    }
  });
}

// Catch 404 and forward to error handler
app.use(notFound);

// Error handlers
app.use(logErrors);          // Log errors
app.use(clientErrorHandler); // Client error handler
app.use(errorHandler);       // Catch all error handler

// See: https://nodejs.org/api/process.html#process_event_unhandledrejection
process.on('unhandledRejection', (reason, p) => {
  logger.error('Unhandled Rejection at:', p, 'reason:', reason);
});

// See: https://nodejs.org/api/process.html#process_event_uncaughtexception
process.on('uncaughtException', err => {
  logger.error('Server Uncaught Exception ', err);
  process.exit(1);
});

export default app;
export { devMiddleware };
<commit_msg>Modified webpack-dev-middleware config<commit_after>import path from 'path';
import express from 'express';
import bodyParser from 'body-parser';
import config from '../config';
import logger from './logger';
import apiRouter from './api-router';
import { notFound, logErrors, clientErrorHandler, errorHandler } from './error-handlers';
import { NotFoundException } from './exceptions';

// Set Winston console log level
logger.transports.console.level = config.logger.console.level;

// console.log === console.log in webpack.config
//eslint-disable-next-line no-console
console.log('express:',
  `NODE_ENV: "${process.env.NODE_ENV}",`,
  `isProd: ${config.isProd},`,
  `isDev: ${config.isDev},`,
  `isTest: ${config.isTest},`,
  `isHot: ${config.isHot},`,
  `loglevel: "${config.logger.console.level}",`,
  `public: "${config.server.publicPath}",`,
  `api: "${config.apiPath}"`);

let devMiddleware = null;

const app = express();
app.disable('x-powered-by');

// Middleware for handling JSON, Raw, Text and URL encoded form data
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());

if (config.server.compress) {
  // compression middleware compresses your server responses which makes them
  // smaller (applies also to assets). You can read more about that technique
  // and other good practices on official Express.js docs http://mxs.is/googmy
  const compression = require('compression'); // eslint-disable-line global-require
  app.use(compression());
}

if (config.proxy) {
  // Proxy to api server
  const proxy = require('http-proxy-middleware'); // eslint-disable-line global-require

  const useProxy = (proxyConfig) => {
    app.use(proxy(proxyConfig.context, {
      ...proxyConfig.options,
      onProxyReq(req) {
        logger.info(`Proxy to: ${req.path}`);
      }
    }));
  };

  if (Array.isArray(config.proxy)) {
    config.proxy.forEach( p => {
      useProxy(p);
    });
  }
  else {
    useProxy(config.proxy);
  }
}
else {
  // Api routes
  app.use(config.apiPath, apiRouter);
}

// Uncomment to disable historyApiFallback without modifying config files
//config.server.historyApiFallback = false;

if (config.server.historyApiFallback) {
  // This rewrites all routes requests to the root /index.html file
  // (ignoring file requests). If you want to implement universal
  // rendering, you'll want to remove this middleware.
  const history = require('connect-history-api-fallback'); // eslint-disable-line global-require
  app.use(history(config.server.historyApiFallback));
}

if (config.isProd && !config.isTest) {
  app.use(config.server.publicPath, express.static(config.server.contentBase));

  app.get('*', (req, res, next) => {

    const reqPath = req.path.startsWith(config.server.publicPath)
      ? req.path.replace(config.server.publicPath, '')
      : req.path;

    const target = reqPath.indexOf('.') > -1
      ? path.join(config.server.contentBase, reqPath)
      : path.join(config.server.contentBase, 'index.html');

    logger.info('### app.get * from:', req.path, 'to:', target);

    res.sendFile(target, err => {
      if (err) {
        next(NotFoundException(req.path));
      }
    });
  });
}

if (config.isDev || config.isTest) {
  // Step 1: Create & configure a webpack compiler
  const webpack = require('webpack'); // eslint-disable-line global-require
  const webpackConfig = require('../webpack.config.babel'); // eslint-disable-line global-require
  const webpackCompiler = webpack(webpackConfig);
  webpackCompiler.apply(new webpack.ProgressPlugin());

  // Step 2: Attach the dev middleware to the compiler & the server
  // Config options:
  //   see: https://github.com/webpack/webpack-dev-middleware
  //   see: https://webpack.js.org/configuration/dev-server/
  //   see: https://webpack.js.org/configuration/stats/
  //   see: https://webpack.github.io/docs/webpack-dev-server.html
  //   see: https://github.com/chimurai/http-proxy-middleware
  //   see: https://github.com/bripkens/connect-history-api-fallback
  //   NOTE: Only use options compatible with webpack-dev-middleware
  const webpackDevMiddleware = require('webpack-dev-middleware'); // eslint-disable-line global-require

  devMiddleware = webpackDevMiddleware(webpackCompiler, {
    publicPath: webpackConfig.output.publicPath,
    hot: config.isHot,
    stats: 'none',
    /*
    stats: {
      errors: true,
      colors: true,
    },
    */
  });
  app.use(devMiddleware);

  // Step 3: Attach the hot middleware to the compiler & the server
  // Config options:
  //   See: https://github.com/glenjamin/webpack-hot-middleware
  if (config.isHot) {
    app.use(require('webpack-hot-middleware')(webpackCompiler));

    /*
    const webpackHotMiddleware = require('webpack-hot-middleware'); // eslint-disable-line global-require
    const hotMiddleware = webpackHotMiddleware(webpackCompiler, {
      path: '/__webpack_hmr'
      // You can use full urls, like:
      // path: `http://${host}:${port}${publicPath}/__webpack_hmr`
      // Remember to update webpack-hot-middleware in ../webpack-config.babel
    });
    app.use(hotMiddleware);
    */
  }

  // Add public path after step 3
  app.use(config.server.publicPath, express.static(config.server.contentBase));

  // Since webpackDevMiddleware uses memory-fs internally to store build
  // artifacts, we use it instead
  const memoryFs = devMiddleware.fileSystem;

  app.get('*', (req, res, next) => {

    const reqPath = req.path.startsWith(config.server.publicPath)
      ? req.path.replace(config.server.publicPath, '')
      : req.path;

    const target = reqPath.indexOf('.') > -1
      ? path.join(webpackCompiler.outputPath, reqPath)
      : path.join(webpackCompiler.outputPath, 'index.html');

    if (target.endsWith('.html')) {
      // 1: Read from memory fs
      logger.info('1 app.get * from:', req.path, 'to:', target);
      memoryFs.readFile(target, (err, file) => {
        if (err) {
          next(NotFoundException(req.path));
        } else {
          res.send(file.toString());
        }
      });
    }
    else {
      // 2: Try reading from outputPath, i.e. "dist"
      logger.info('2 app.get * from:', req.path, 'to:', target);
      res.sendFile(target, err => {
        if (err) {
          // 3: Try reading from src
          const src = path.join(config.server.contentBase, reqPath);
          logger.info('3 app.get * from:', req.path, 'to:', src);

          res.sendFile(src, err => {
            if (err) {
              next(NotFoundException(req.path));
            }
          });
        }
      });
    }
  });
}

// Catch 404 and forward to error handler
app.use(notFound);

// Error handlers
app.use(logErrors);          // Log errors
app.use(clientErrorHandler); // Client error handler
app.use(errorHandler);       // Catch all error handler

// See: https://nodejs.org/api/process.html#process_event_unhandledrejection
process.on('unhandledRejection', (reason, p) => {
  logger.error('Unhandled Rejection at:', p, 'reason:', reason);
});

// See: https://nodejs.org/api/process.html#process_event_uncaughtexception
process.on('uncaughtException', err => {
  logger.error('Server Uncaught Exception ', err);
  process.exit(1);
});

export default app;
export { devMiddleware };
<|endoftext|>


<commit_before>(function() {
  'use strict';

  var exports = fxpay.utils = {};

  exports.defaults = function(object, defaults) {
    object = object || {};
    // Similar to _.defaults except this takes only a single defaults object.
    Object.keys(defaults).forEach(function(key) {
      if (typeof object[key] === 'undefined') {
        object[key] = defaults[key];
      }
    });
    return object;
  };

  exports.getSelfOrigin = function(settings) {
    if (!settings) {
      settings = fxpay.getattr('settings');
    }
    if (settings.appSelf) {
      if (!settings.appSelf.origin) {
        throw new Error('app does not have an origin');
      }
      return settings.appSelf.origin;
    } else {
      var win = settings.window;
      if (win.location.origin) {
        return win.location.origin;
      } else {
        return win.location.protocol + '//' + win.location.hostname;
      }
    }
  };

  exports.getUrlOrigin = function(url) {
    var a = document.createElement('a');
    a.href = url;
    return a.origin || (a.protocol + '//' + a.host);
  };

  exports.getCenteredCoordinates = function(w, h) {
    // Centering calcs that work on multiple monitors (bug 1122683).
    var x = window.screenX +
      Math.max(0, Math.floor((window.innerWidth - w) / 2));
    var y = window.screenY +
      Math.max(0, Math.floor((window.innerHeight - h) / 2));
    return [x, y];
  };

  exports.reCenterWindow = function(winRef, w, h) {
    var xy = exports.getCenteredCoordinates(w, h);
    winRef.resizeTo(w, h);
    winRef.moveTo(xy[0], xy[1]);
  };

  exports.openWindow = function(options) {
    var settings = fxpay.getattr('settings');
    var defaults = {
      url: '',
      title: 'FxPay',
      w: settings.winWidth,
      h: settings.winHeight,
    };

    options = exports.defaults(options, defaults);
    var xy = exports.getCenteredCoordinates(options.w, options.h);

    var winOptString = 'toolbar=no,location=no,directories=no,' +
      'menubar=no,scrollbars=no,resizable=no,copyhistory=no,' +
      'width=' + options.w + ',height=' + options.h +
      ',top=' + xy[1] + ',left=' + xy[0];

    var windowRef = settings.window.open(options.url, options.title,
                                         winOptString);
    if (!windowRef) {
      settings.log.error('window.open() failed. URL:', options.url);
    }
    return windowRef;
  };

})();
<commit_msg>Make width and height optional<commit_after>(function() {
  'use strict';

  var exports = fxpay.utils = {};

  exports.defaults = function(object, defaults) {
    object = object || {};
    // Similar to _.defaults except this takes only a single defaults object.
    Object.keys(defaults).forEach(function(key) {
      if (typeof object[key] === 'undefined') {
        object[key] = defaults[key];
      }
    });
    return object;
  };

  exports.getSelfOrigin = function(settings) {
    if (!settings) {
      settings = fxpay.getattr('settings');
    }
    if (settings.appSelf) {
      if (!settings.appSelf.origin) {
        throw new Error('app does not have an origin');
      }
      return settings.appSelf.origin;
    } else {
      var win = settings.window;
      if (win.location.origin) {
        return win.location.origin;
      } else {
        return win.location.protocol + '//' + win.location.hostname;
      }
    }
  };

  exports.getUrlOrigin = function(url) {
    var a = document.createElement('a');
    a.href = url;
    return a.origin || (a.protocol + '//' + a.host);
  };

  exports.getCenteredCoordinates = function(w, h) {
    // Centering calcs that work on multiple monitors (bug 1122683).
    var x = window.screenX +
      Math.max(0, Math.floor((window.innerWidth - w) / 2));
    var y = window.screenY +
      Math.max(0, Math.floor((window.innerHeight - h) / 2));
    return [x, y];
  };

  exports.reCenterWindow = function(winRef, w, h) {
    var settings = fxpay.getattr('settings');
    w = w || settings.winWidth;
    h = h || settings.winHeight;
    var xy = exports.getCenteredCoordinates(w, h);
    winRef.resizeTo(w, h);
    winRef.moveTo(xy[0], xy[1]);
  };

  exports.openWindow = function(options) {
    var settings = fxpay.getattr('settings');
    var defaults = {
      url: '',
      title: 'FxPay',
      w: settings.winWidth,
      h: settings.winHeight,
    };

    options = exports.defaults(options, defaults);
    var xy = exports.getCenteredCoordinates(options.w, options.h);

    var winOptString = 'toolbar=no,location=no,directories=no,' +
      'menubar=no,scrollbars=no,resizable=no,copyhistory=no,' +
      'width=' + options.w + ',height=' + options.h +
      ',top=' + xy[1] + ',left=' + xy[0];

    var windowRef = settings.window.open(options.url, options.title,
                                         winOptString);
    if (!windowRef) {
      settings.log.error('window.open() failed. URL:', options.url);
    }
    return windowRef;
  };

})();
<|endoftext|>