<commit_before>/**
 * @file TimeItems component
 * @author sunday(sunday.wei@derbysoft.com)
 */

import React, {Component} from 'react';
import PropTypes from 'prop-types';
import classNames from 'classnames';

import Event from '../_vendors/Event';

class TimeItems extends Component {

    constructor(props, ...restArgs) {

        super(props, ...restArgs);

        this.clickHandle = ::this.clickHandle;
        this.mousemoveHandle = ::this.mousemoveHandle;
        this.mouseoutHandle = ::this.mouseoutHandle;

    }

    clickHandle(value) {

        if (!value) {
            return;
        }

        if (this.itemsEl) {
            this.scrollTo(this.itemsEl, (+value) * 30, 200);
        }

        const {onChange} = this.props;
        onChange && onChange(value);

    }

    mousemoveHandle() {
        this.itemsEl.style.overflowY = 'auto';
    }

    scrollTo(element, to, duration) {

        // jump to target if duration zero
        if (duration <= 0) {
            element.scrollTop = to;
            return;
        }

        const difference = to - element.scrollTop,
            perTick = difference / duration * 10;

        setTimeout(() => {
            element.scrollTop = element.scrollTop + perTick;
            if (element.scrollTop === to) return;
            this.scrollTo(element, to, duration - 10);
        }, 10);

    };

    mouseoutHandle() {
        this.itemsEl.style.overflowY = 'hidden';
    }

    componentDidMount() {

        const {value} = this.props;
        this.itemsEl = this.refs.timeItems;

        this.scrollTo(this.itemsEl, (+value) * 30, 0);
        Event.addEvent(this.itemsEl, 'mouseover', this.mousemoveHandle);
        Event.addEvent(this.itemsEl, 'mouseout', this.mouseoutHandle);

    }

    componentWillUnmount() {
        Event.removeEvent(this.itemsEl, 'mouseover', this.mousemoveHandle);
        Event.removeEvent(this.itemsEl, 'mouseout', this.mouseoutHandle);
    }

    render() {

        const {className, style, data, value} = this.props,
            {width} = style,

            itemsClassName = classNames('time-items', {
                [className]: className
            }),

            liStyle = {};

        if (width == '100%') {
            liStyle.paddingLeft = '140px';
        } else if (width == '50%') {
            liStyle.paddingLeft = '60px';
        } else {
            liStyle.paddingLeft = '36px';
        }

        return (

                    {
                        data && data.length ?
                            data.map((item, key) => {

                                const className = classNames('time-item', {
                                    disabled: !item.value,
                                    active: item.text == value
                                });

                                return (

 {
                                            this.clickHandle(item.text);
                                        }}>
                                        {item.text}

                                );
                            })
                            :
                            null
                    }

        );

    }
}

TimeItems.propTypes = {
    className: PropTypes.string,
    style: PropTypes.object,
    data: PropTypes.array
};

export default TimeItems;<commit_msg>update TimeItems<commit_after>/**
 * @file TimeItems component
 * @author sunday(sunday.wei@derbysoft.com)
 */

import React, {Component} from 'react';
import PropTypes from 'prop-types';
import classNames from 'classnames';

import Event from '../_vendors/Event';

class TimeItems extends Component {

    constructor(props, ...restArgs) {

        super(props, ...restArgs);

        this.clickHandle = ::this.clickHandle;
        this.mousemoveHandle = ::this.mousemoveHandle;
        this.mouseoutHandle = ::this.mouseoutHandle;

    }

    clickHandle(value) {

        if (!value) {
            return;
        }

        if (this.itemsEl) {
            this.scrollTo(this.itemsEl, (+value) * 30, 200);
        }

        const {onChange} = this.props;
        onChange && onChange(value);

    }

    mousemoveHandle() {
        this.itemsEl && (this.itemsEl.style.overflowY = 'auto');
    }

    scrollTo(element, to, duration) {

        // jump to target if duration zero
        if (duration <= 0) {
            element.scrollTop = to;
            return;
        }

        const difference = to - element.scrollTop,
            perTick = difference / duration * 10;

        setTimeout(() => {
            element.scrollTop = element.scrollTop + perTick;
            if (element.scrollTop === to) return;
            this.scrollTo(element, to, duration - 10);
        }, 10);

    };

    mouseoutHandle() {
        this.itemsEl && (this.itemsEl.style.overflowY = 'hidden');
    }

    componentDidMount() {

        const {value} = this.props;
        this.itemsEl = this.refs.timeItems;

        this.scrollTo(this.itemsEl, (+value) * 30, 0);
        Event.addEvent(this.itemsEl, 'mouseover', this.mousemoveHandle);
        Event.addEvent(this.itemsEl, 'mouseout', this.mouseoutHandle);

    }

    componentWillUnmount() {
        Event.removeEvent(this.itemsEl, 'mouseover', this.mousemoveHandle);
        Event.removeEvent(this.itemsEl, 'mouseout', this.mouseoutHandle);
    }

    render() {

        const {className, style, data, value} = this.props,
            {width} = style,

            itemsClassName = classNames('time-items', {
                [className]: className
            }),

            liStyle = {};

        if (width == '100%') {
            liStyle.paddingLeft = '140px';
        } else if (width == '50%') {
            liStyle.paddingLeft = '60px';
        } else {
            liStyle.paddingLeft = '36px';
        }

        return (

                    {
                        data && data.length ?
                            data.map((item, key) => {

                                const className = classNames('time-item', {
                                    disabled: !item.value,
                                    active: item.text == value
                                });

                                return (

 {
                                            this.clickHandle(item.text);
                                        }}>
                                        {item.text}

                                );
                            })
                            :
                            null
                    }

        );

    }
}

TimeItems.propTypes = {
    className: PropTypes.string,
    style: PropTypes.object,
    data: PropTypes.array
};

export default TimeItems;<|endoftext|>


<commit_before>window.feednami = {}
feednami.load = function(options,callback){
  var apiRoot = 'https://api.feednami.com/api/v1'
  var feedUrl = options
  if(typeof options == 'object'){
    feedUrl = options.url
  }
  var qs = 'url='+feedUrl
  if(options.format){
    qs += '&include_xml_document&format='+options.format
  }
  if(options.includeXml){
    qs += '&include_xml_document'
  }
  var url = apiRoot+'/feeds/load?'+qs
  if(window.XDomainRequest){
    var script = document.createElement('script')
    var callbackName = 'jsonp_callback_'
    + new Date().getTime() + '_'
    + Math.round(1000000 * Math.random());
    url += '&jsonp_callback='+callbackName
    window[callbackName] = function(data) {
      callback(data);
      document.body.removeChild(script);
      window[callbackName] = null
      try{
        delete window[callbackName];
      }
      catch(e){

      }
    };
    script.src = url
    document.body.appendChild(script)
  }
  else{
    var req = new XMLHttpRequest()
    req.onreadystatechange = function(){
      if(req.readyState == 4){
        callback(JSON.parse(req.responseText))
      }
    }
    req.open('GET',url)
    req.send()
  }
}
feednami.loadGoogleFormat = function(feedUrl,callback){
  return feednami.load({
    url: feedUrl,
    format: 'google',
    includeXml: true
  },callback)
}<commit_msg>URL encode feed url<commit_after>window.feednami = {}
feednami.load = function(options,callback){
  var apiRoot = 'https://api.feednami.com/api/v1'
  var feedUrl = options
  if(typeof options == 'object'){
    feedUrl = options.url
  }
  var qs = 'url='+encodeURIComponent(feedUrl)
  if(options.format){
    qs += '&include_xml_document&format='+options.format
  }
  if(options.includeXml){
    qs += '&include_xml_document'
  }
  var url = apiRoot+'/feeds/load?'+qs
  if(window.XDomainRequest){
    var script = document.createElement('script')
    var callbackName = 'jsonp_callback_'
    + new Date().getTime() + '_'
    + Math.round(1000000 * Math.random());
    url += '&jsonp_callback='+callbackName
    window[callbackName] = function(data) {
      callback(data);
      document.body.removeChild(script);
      window[callbackName] = null
      try{
        delete window[callbackName];
      }
      catch(e){

      }
    };
    script.src = url
    document.body.appendChild(script)
  }
  else{
    var req = new XMLHttpRequest()
    req.onreadystatechange = function(){
      if(req.readyState == 4){
        callback(JSON.parse(req.responseText))
      }
    }
    req.open('GET',url)
    req.send()
  }
}
feednami.loadGoogleFormat = function(feedUrl,callback){
  return feednami.load({
    url: feedUrl,
    format: 'google',
    includeXml: true
  },callback)
}<|endoftext|>


<commit_before>import React, { Component } from 'react'
import PropTypes from 'prop-types'
import { isEqual, differenceWith } from 'lodash'
import hoistStatics from 'hoist-non-react-statics'
import { watchEvents, unWatchEvents } from './actions/query'
import { getEventsFromInput, createCallable, wrapDisplayName } from './utils'
import ReactReduxFirebaseContext from './ReactReduxFirebaseContext'

// Reserved props that should not be passed into a firebaseConnect wrapped
// component. Will throw an error if they are.
const RESERVED_PROPS = ['_firebaseRef', '_dispatch']

/**
 * @name createFirebaseConnect
 * @description Function that creates a Higher Order Component that
 * automatically listens/unListens to provided firebase paths using
 * React's Lifecycle hooks.
 * **WARNING!!** This is an advanced feature, and should only be used when
 * needing to access a firebase instance created under a different store key.
 * @param {String} [storeKey='store'] - Name of redux store which contains
 * Firebase state (state.firebase)
 * @return {Function} - HOC that accepts a watchArray and wraps a component
 * @example
Basic

 * // this.props.firebase set on App component as firebase object with helpers
 * import { createFirebaseConnect } from 'react-redux-firebase'
 * // create firebase connect that uses another redux store
 * const firebaseConnect = createFirebaseConnect('anotherStore')
 * // use the firebaseConnect to wrap a component
 * export default firebaseConnect()(SomeComponent)
 */
export const createFirebaseConnect = (storeKey = 'store') => (
  dataOrFn = []
) => WrappedComponent => {
  class FirebaseConnectWrapped extends Component {
    static displayName = wrapDisplayName(
      WrappedComponent,
      'FirebaseConnectWrapped'
    )
    static wrappedComponent = WrappedComponent

    firebaseEvents = []
    firebase = null
    prevData = null

    componentDidMount() {
      const { _firebaseRef, _dispatch } = this.props

      // Check props to see

      // Allow function to be passed
      const inputAsFunc = createCallable(dataOrFn)
      this.prevData = inputAsFunc(this.props, this.props)

      const { ref, helpers, storage, database, auth } = _firebaseRef
      this.firebase = { ref, storage, database, auth, ...helpers }

      this._firebaseEvents = getEventsFromInput(this.prevData)

      watchEvents(_firebaseRef, _dispatch, this._firebaseEvents)
    }

    componentWillUnmount() {
      const { _firebaseRef, _dispatch } = this.props
      unWatchEvents(_firebaseRef, _dispatch, this._firebaseEvents)
    }

    componentWillReceiveProps(np) {
      const { _firebaseRef, _dispatch } = this.props
      const inputAsFunc = createCallable(dataOrFn)
      const data = inputAsFunc(np, this.store)

      // Handle a data parameter having changed
      if (!isEqual(data, this.prevData)) {
        const itemsToSubscribe = differenceWith(data, this.prevData, isEqual)
        const itemsToUnsubscribe = differenceWith(this.prevData, data, isEqual)

        this.prevData = data
        // UnWatch all current events
        unWatchEvents(
          _firebaseRef,
          _dispatch,
          getEventsFromInput(itemsToUnsubscribe)
        )
        // Get watch events from new data
        this._firebaseEvents = getEventsFromInput(data)

        // Watch new events
        watchEvents(
          _firebaseRef,
          _dispatch,
          getEventsFromInput(itemsToSubscribe)
        )
      }
    }

    render() {
      return <WrappedComponent {...this.props} />
    }
  }

  FirebaseConnectWrapped.propTypes = {
    _dispatch: PropTypes.func.isRequired,
    _firebaseRef: PropTypes.object.isRequired
  }

  const HoistedComp = hoistStatics(FirebaseConnectWrapped, WrappedComponent)

  const FirebaseConnect = props => {
    // Check that reserved props are not supplied to a FirebaseConnected
    // component and if they are, throw an error so the developer can rectify
    // this issue.
    const clashes = Object.keys(props).filter(
      k => !!RESERVED_PROPS.find(r => r === k)
    )

    if (clashes) {
      throw new Error(
        `Supplied prop/s "${clashes.join(
          '", "'
        )}" are reserved for internal firebaseConnect() use.`
      )
    }

    return (
      <ReactReduxFirebaseContext.Consumer>
        {_firebaseRef => (
          <HoistedComp
            _firebaseRef={_firebaseRef}
            _dispatch={_firebaseRef.dispatch}
            {...props}
          />
        )}
      </ReactReduxFirebaseContext.Consumer>
    )
  }

  FirebaseConnect.displayName = wrapDisplayName(
    WrappedComponent,
    'FirebaseConnect'
  )

  return FirebaseConnect
}

/**
/**
 * @name firebaseConnect
 * @extends React.Component
 * @description Higher Order Component that automatically listens/unListens
 * to provided firebase paths using React's Lifecycle hooks.
 * @param {Array} watchArray - Array of objects or strings for paths to sync
 * from Firebase. Can also be a function that returns the array. The function
 * is passed the current props and the firebase object.
 * @return {Function} - that accepts a component to wrap and returns the wrapped component
 * @example
Basic

 * // props.firebase set on App component as firebase object with helpers
 * import { firebaseConnect } from 'react-redux-firebase'
 * export default firebaseConnect()(App)
 * @example
Ordered Data

 * import { compose } from 'redux'
 * import { connect } from 'react-redux'
 * import { firebaseConnect } from 'react-redux-firebase'
 *
 * const enhance = compose(
 *   firebaseConnect([
 *     'todos' // sync /todos from firebase into redux
 *   ]),
 *   connect((state) => ({
 *     todos: state.firebase.ordered.todos
 *   })
 * )
 *
 * // use enhnace to pass todos list as props.todos
 * const Todos = enhance(({ todos })) =>
 *

 *     {JSON.stringify(todos, null, 2)}
 *

 * )
 *
 * export default enhance(Todos)
 * @example
Data that depends on props

 * import { compose } from 'redux'
 * import { connect } from 'react-redux'
 * import { firebaseConnect, getVal } from 'react-redux-firebase'
 *
 * const enhance = compose(
 *   firebaseConnect((props) => ([
 *     `posts/${props.postId}` // sync /posts/postId from firebase into redux
 *   ]),
 *   connect((state, props) => ({
 *     post: getVal(state.firebase.data, `posts/${props.postId}`),
 *   })
 * )
 *
 * const Post = ({ post }) => (
 *

 *     {JSON.stringify(post, null, 2)}
 *

 * )
 *
 * export default enhance(Post)
 */
export default createFirebaseConnect()
<commit_msg>Tweaked to cause rebuild on travis<commit_after>import React, { Component } from 'react'
import PropTypes from 'prop-types'
import { isEqual, differenceWith } from 'lodash'
import hoistStatics from 'hoist-non-react-statics'
import { watchEvents, unWatchEvents } from './actions/query'
import { getEventsFromInput, createCallable, wrapDisplayName } from './utils'
import ReactReduxFirebaseContext from './ReactReduxFirebaseContext'

// Reserved props that should not be passed into a firebaseConnect wrapped
// component. Will throw an error if they are.
const RESERVED_PROPS = ['_firebaseRef', '_dispatch']

/**
 * @name createFirebaseConnect
 * @description Function that creates a Higher Order Component that
 * automatically listens/unListens to provided firebase paths using
 * React's Lifecycle hooks.
 * **WARNING!!** This is an advanced feature, and should only be used when
 * needing to access a firebase instance created under a different store key.
 * @param {String} [storeKey='store'] - Name of redux store which contains
 * Firebase state (state.firebase)
 * @return {Function} - HOC that accepts a watchArray and wraps a component
 * @example
Basic

 * // this.props.firebase set on App component as firebase object with helpers
 * import { createFirebaseConnect } from 'react-redux-firebase'
 * // create firebase connect that uses another redux store
 * const firebaseConnect = createFirebaseConnect('anotherStore')
 * // use the firebaseConnect to wrap a component
 * export default firebaseConnect()(SomeComponent)
 */
export const createFirebaseConnect = (storeKey = 'store') => (
  dataOrFn = []
) => WrappedComponent => {
  class FirebaseConnectWrapped extends Component {
    static displayName = wrapDisplayName(
      WrappedComponent,
      'FirebaseConnectWrapped'
    )
    static wrappedComponent = WrappedComponent

    firebaseEvents = []
    firebase = null
    prevData = null

    componentDidMount() {
      const { _firebaseRef, _dispatch } = this.props

      // Check props to see

      // Allow function to be passed
      const inputAsFunc = createCallable(dataOrFn)
      this.prevData = inputAsFunc(this.props, this.props)

      const { ref, helpers, storage, database, auth } = _firebaseRef
      this.firebase = { ref, storage, database, auth, ...helpers }

      this._firebaseEvents = getEventsFromInput(this.prevData)

      watchEvents(_firebaseRef, _dispatch, this._firebaseEvents)
    }

    componentWillUnmount() {
      const { _firebaseRef, _dispatch } = this.props
      unWatchEvents(_firebaseRef, _dispatch, this._firebaseEvents)
    }

    componentWillReceiveProps(np) {
      const { _firebaseRef, _dispatch } = this.props
      const inputAsFunc = createCallable(dataOrFn)
      const data = inputAsFunc(np, this.store)

      // Handle a data parameter having changed
      if (!isEqual(data, this.prevData)) {
        const itemsToSubscribe = differenceWith(data, this.prevData, isEqual)
        const itemsToUnsubscribe = differenceWith(this.prevData, data, isEqual)

        this.prevData = data
        // UnWatch all current events
        unWatchEvents(
          _firebaseRef,
          _dispatch,
          getEventsFromInput(itemsToUnsubscribe)
        )
        // Get watch events from new data
        this._firebaseEvents = getEventsFromInput(data)

        // Watch new events
        watchEvents(
          _firebaseRef,
          _dispatch,
          getEventsFromInput(itemsToSubscribe)
        )
      }
    }

    render() {
      return <WrappedComponent {...this.props} />
    }
  }

  FirebaseConnectWrapped.propTypes = {
    _dispatch: PropTypes.func.isRequired,
    _firebaseRef: PropTypes.object.isRequired
  }

  const HoistedComp = hoistStatics(FirebaseConnectWrapped, WrappedComponent)

  const FirebaseConnect = props => {
    // Check that reserved props are not supplied to a FirebaseConnected
    // component and if they are, throw an error so the developer can rectify
    // this issue.
    const clashes = Object.keys(props).filter(
      k => !!RESERVED_PROPS.find(r => r === k)
    )

    if (clashes) {
      throw new Error(
        `Supplied prop/s "${clashes.join(
          '", "'
        )}" are reserved for internal firebaseConnect() useage.`
      )
    }

    return (
      <ReactReduxFirebaseContext.Consumer>
        {_firebaseRef => (
          <HoistedComp
            _firebaseRef={_firebaseRef}
            _dispatch={_firebaseRef.dispatch}
            {...props}
          />
        )}
      </ReactReduxFirebaseContext.Consumer>
    )
  }

  FirebaseConnect.displayName = wrapDisplayName(
    WrappedComponent,
    'FirebaseConnect'
  )

  return FirebaseConnect
}

/**
/**
 * @name firebaseConnect
 * @extends React.Component
 * @description Higher Order Component that automatically listens/unListens
 * to provided firebase paths using React's Lifecycle hooks.
 * @param {Array} watchArray - Array of objects or strings for paths to sync
 * from Firebase. Can also be a function that returns the array. The function
 * is passed the current props and the firebase object.
 * @return {Function} - that accepts a component to wrap and returns the wrapped component
 * @example
Basic

 * // props.firebase set on App component as firebase object with helpers
 * import { firebaseConnect } from 'react-redux-firebase'
 * export default firebaseConnect()(App)
 * @example
Ordered Data

 * import { compose } from 'redux'
 * import { connect } from 'react-redux'
 * import { firebaseConnect } from 'react-redux-firebase'
 *
 * const enhance = compose(
 *   firebaseConnect([
 *     'todos' // sync /todos from firebase into redux
 *   ]),
 *   connect((state) => ({
 *     todos: state.firebase.ordered.todos
 *   })
 * )
 *
 * // use enhnace to pass todos list as props.todos
 * const Todos = enhance(({ todos })) =>
 *

 *     {JSON.stringify(todos, null, 2)}
 *

 * )
 *
 * export default enhance(Todos)
 * @example
Data that depends on props

 * import { compose } from 'redux'
 * import { connect } from 'react-redux'
 * import { firebaseConnect, getVal } from 'react-redux-firebase'
 *
 * const enhance = compose(
 *   firebaseConnect((props) => ([
 *     `posts/${props.postId}` // sync /posts/postId from firebase into redux
 *   ]),
 *   connect((state, props) => ({
 *     post: getVal(state.firebase.data, `posts/${props.postId}`),
 *   })
 * )
 *
 * const Post = ({ post }) => (
 *

 *     {JSON.stringify(post, null, 2)}
 *

 * )
 *
 * export default enhance(Post)
 */
export default createFirebaseConnect()
<|endoftext|>


<commit_before>'use strict';

var bcrypt = require('bcrypt-nodejs'),
    Server = require('socket.io'),
    express = require('express'),
    http = require('http'),
    path = require('path'),
    mongo = require('mongojs');

var util = require('util');
var session = require('./session');
var _ = require('lodash');
var cors = require('cors');

var _validTokens = {};

function throwErr (func) {
    return function(err, data) {
        if (err) {
            throw err;
        } else {
            func.call(null, data);
        }
    };
}

function validateScene (sceneData) {
    // convert _id so mongo recognizes it
    if (sceneData.hasOwnProperty('_id')) {
        sceneData._id = mongo.ObjectId(sceneData._id);
    }

    // add _ids to all mediaObjects
    if (sceneData.hasOwnProperty('scene')) {
        if (! Array.isArray(sceneData.scene) ) {
            throw new Error('"scene" property must be an array of objects');
        } else {
            sceneData.scene.forEach(function(mediaObject) {
                if (! mediaObject.hasOwnProperty('_id')) {
                    mediaObject._id = mongo.ObjectId();
                }
            });
        }
    }

    return sceneData;
}

function validateSceneGraph (sceneGraphData) {
    //convert _id so mongo recognizes it
    if (sceneGraphData.hasOwnProperty('_id')) {
        sceneGraphData._id = mongo.ObjectId(sceneGraphData._id);
    }

    //TODO most likely more detailed validation can occur

    return sceneGraphData;
}

function addApiCalls (hub, io, socket) {
    function idSearch (id) {
        return {_id: mongo.ObjectId(id)};
    }

    function _findScene (sceneId, cb) {
        return hub.db.mediaScenes.findOne(idSearch(sceneId), cb);
    }

    function _findSceneGraph(sceneGraphId, cb) {
        return hub.db.mediaSceneGraphs.findOne(idSearch(sceneGraphId), cb);
    }

    socket.on('listScenes', function(callback) {

        console.log("listScenes groupID: " + socket.groupID);

        //console.log("listScenes");
        //console.log("groupID: " + socket.groupID);

        //AJF: if the groupID is 0 (admin) then list all scenes
        if(socket.groupID == 0)
            hub.db.mediaScenes.find({'$query': {}, '$orderby': {name: 1}}, {name: 1}, callback);
        else
        {
            hub.db.mediaScenes.find({'$query': {_groupID: socket.groupID}, '$orderby': {name: 1}}, {name: 1}, callback);
        }

    });

    socket.on('listSceneGraphs', function(callback) {
        hub.db.mediaSceneGraphs.find({'$query': {}}, callback);

    });

    socket.on('saveScene', function(sceneData, callback) {
        try {

            console.log("saveScene");

            var data = validateScene(sceneData);

            //AJF: save the groupID acquired from the socket
            data._groupID = socket.groupID;

            hub.db.mediaScenes.save(data, function(err, scene) {
                io.to(scene._id.toString()).emit('sceneUpdate', scene);

                if (callback) {
                    callback(err, scene);
                }
            });
        } catch(err) {
            if (callback) {
                callback(err.message);
            }
        }
    });

    socket.on('saveSceneGraph', function(sceneGraphData, callback) {
        try {
            var data = validateSceneGraph(sceneGraphData);

            hub.db.mediaSceneGraphs.save(data, function(err, sceneGraph) {
                io.to(sceneGraph._id.toString()).emit('sceneGraphUpdate', sceneGraph);

                if (callback) {
                    callback(err, sceneGraph);
                }
            });

        } catch(err) {
            if(callback) {
                callback(err.message);
            }
        }
    });

    socket.on('loadScene', _findScene);

    socket.on('loadSceneGraph', _findSceneGraph);

    //TODO loadSceneGraphByName

    socket.on('loadSceneByName', function(name, callback) {
        hub.db.mediaScenes.findOne({name: name}, callback);
    });

    socket.on('deleteScene', function(sceneId, callback) {
        hub.db.mediaScenes.remove(idSearch(sceneId), function(err) {
            if (callback) {
                callback(err);
            }
        });
    });

    socket.on('subScene', function(sceneId, callback) {
        _findScene(sceneId, function(err, scene) {
            socket.join(sceneId);

            if (callback) {
                callback(err, scene);
            }
        });
    });

    socket.on('unsubScene', function(sceneId, callback) {
        _findScene(sceneId, function(err, scene) {
            socket.leave(sceneId);
            if (callback) {
                callback(err);
            }
        });
    });

    socket.on('sendCommand', function(roomId, commandName, commandValue) {
        io.to(roomId).emit('command', {name: commandName, value: commandValue});
    });

    socket.on('register', function(roomId) {
        socket.join(roomId);
    });
}

var Hub = function(config) {
    this.config = config;
    this.db = mongo.connect(config.mongo, ['mediaScenes', 'sessions', 'mediaSceneGraphs']);
    session.setClient(this.db);
};

Hub.prototype.listen = function(callback) {
    var self = this,
        app = express(),
        server = http.Server(app),
        io = new Server(server);

    this.server = server;

    app.use(cors());

    // require a valid session token for all api calls
    var validateSession =  function(req, res, next) {
        session.find(req.query.token, function(err, data) {
            if (err || ! data) {
                res.sendStatus(401);
            } else {
                next();
            }
        });
    };

    // allow cross origin requests
    io.set('origins', '*:*');
    io.sockets.on('connection', function (socket) {
        var disconnectTimer = setTimeout(function() {
            socket.disconnect();
        }, 10000);

        socket.on('auth', function (creds, callback) {

            function succeed (record) {

                //AJF: set the groupID on the socket to be used in further local calls

                //AJF: set the groupID on the socket to be used in further calls

                socket.groupID = record._groupID;
                addApiCalls(self, io, socket);
                clearTimeout(disconnectTimer);
                callback(null, record._id.toString(), socket.id, record._groupID.toString());//AJF: try to return the groupID...
            }

            function fail (msg) {
                callback(msg);
                socket.disconnect();
            }

            if (creds.hasOwnProperty('password') && creds.password && creds.password !== '') {
                //AJF: Compares the passwords and determines what group the user logging into belongs to
                if ( bcrypt.compareSync(creds.password, self.config.secret) ) {
                    session.create(0, throwErr(succeed));
                } else if (bcrypt.compareSync(creds.password, self.config.secret_1)) {
                    session.create(1, throwErr(succeed));
                } else if (bcrypt.compareSync(creds.password, self.config.secret_2)) {
                    session.create(2, throwErr(succeed));
                } else if (bcrypt.compareSync(creds.password, self.config.secret_101)) {
                    session.create(101, throwErr(succeed));
                } else if (bcrypt.compareSync(creds.password, self.config.secret_102)) {
                    session.create(102, throwErr(succeed));
                } else if (bcrypt.compareSync(creds.password, self.config.secret_103)) {
                    session.create(103, throwErr(succeed));
                } else if (bcrypt.compareSync(creds.password, self.config.secret_104)) {
                    session.create(104, throwErr(succeed));
                } else if (bcrypt.compareSync(creds.password, self.config.secret_105)) {
                    session.create(105, throwErr(succeed));
                } else if (bcrypt.compareSync(creds.password, self.config.secret_106)) {
                    session.create(106, throwErr(succeed));
                } else if (bcrypt.compareSync(creds.password, self.config.secret_107)) {
                    session.create(107, throwErr(succeed));
                } else if (bcrypt.compareSync(creds.password, self.config.secret_108)) {
                    session.create(108, throwErr(succeed));
                } else if (bcrypt.compareSync(creds.password, self.config.secret_109)) {
                    session.create(109, throwErr(succeed));
                } else if (bcrypt.compareSync(creds.password, self.config.secret_110)) {
                    session.create(110, throwErr(succeed));
                } else {
                    fail('Invalid Password');
                }

            } else if (creds.hasOwnProperty('token') && creds.token && creds.token !== '') {
                console.log("Finding session via token");
                session.find(creds.token, function(err, data) {
                        if (data) {
                            succeed(data);
                        } else {
                            fail('Invalid Token');
                        }
                    });
            } else {
                fail('Password must be provided');
            }
        });

    });

    server.listen(self.config.port, callback);
};

Hub.prototype.close = function(cb) {
    this.server.close(cb);
};

module.exports = {
    createHub: function(mongoUrl) {
        return new Hub(mongoUrl);
    }
};
<commit_msg>Updates to return groupID in listScenes callback<commit_after>'use strict';

var bcrypt = require('bcrypt-nodejs'),
    Server = require('socket.io'),
    express = require('express'),
    http = require('http'),
    path = require('path'),
    mongo = require('mongojs');

var util = require('util');
var session = require('./session');
var _ = require('lodash');
var cors = require('cors');

var _validTokens = {};

function throwErr (func) {
    return function(err, data) {
        if (err) {
            throw err;
        } else {
            func.call(null, data);
        }
    };
}

function validateScene (sceneData) {
    // convert _id so mongo recognizes it
    if (sceneData.hasOwnProperty('_id')) {
        sceneData._id = mongo.ObjectId(sceneData._id);
    }

    // add _ids to all mediaObjects
    if (sceneData.hasOwnProperty('scene')) {
        if (! Array.isArray(sceneData.scene) ) {
            throw new Error('"scene" property must be an array of objects');
        } else {
            sceneData.scene.forEach(function(mediaObject) {
                if (! mediaObject.hasOwnProperty('_id')) {
                    mediaObject._id = mongo.ObjectId();
                }
            });
        }
    }

    return sceneData;
}

function validateSceneGraph (sceneGraphData) {
    //convert _id so mongo recognizes it
    if (sceneGraphData.hasOwnProperty('_id')) {
        sceneGraphData._id = mongo.ObjectId(sceneGraphData._id);
    }

    //TODO most likely more detailed validation can occur

    return sceneGraphData;
}

function addApiCalls (hub, io, socket) {
    function idSearch (id) {
        return {_id: mongo.ObjectId(id)};
    }

    function _findScene (sceneId, cb) {
        return hub.db.mediaScenes.findOne(idSearch(sceneId), cb);
    }

    function _findSceneGraph(sceneGraphId, cb) {
        return hub.db.mediaSceneGraphs.findOne(idSearch(sceneGraphId), cb);
    }

    socket.on('listScenes', function(callback) {

        console.log("listScenes groupID: " + socket.groupID);

        //console.log("listScenes");
        //console.log("groupID: " + socket.groupID);

        //AJF: if the groupID is 0 (admin) then list all scenes
        if(socket.groupID == 0)
            hub.db.mediaScenes.find({'$query': {}, '$orderby': {name: 1}}, {name: 1, _groupID: 2}, callback);
        else
        {
            hub.db.mediaScenes.find({'$query': {_groupID: socket.groupID}, '$orderby': {name: 1}}, {name: 1, _groupID: 2}, callback);
        }

    });

    socket.on('listSceneGraphs', function(callback) {
        hub.db.mediaSceneGraphs.find({'$query': {}}, callback);

    });

    socket.on('saveScene', function(sceneData, callback) {
        try {

            console.log("saveScene");

            var data = validateScene(sceneData);

            //AJF: save the groupID acquired from the socket
            data._groupID = socket.groupID;

            hub.db.mediaScenes.save(data, function(err, scene) {
                io.to(scene._id.toString()).emit('sceneUpdate', scene);

                if (callback) {
                    callback(err, scene);
                }
            });
        } catch(err) {
            if (callback) {
                callback(err.message);
            }
        }
    });

    socket.on('saveSceneGraph', function(sceneGraphData, callback) {
        try {
            var data = validateSceneGraph(sceneGraphData);

            hub.db.mediaSceneGraphs.save(data, function(err, sceneGraph) {
                io.to(sceneGraph._id.toString()).emit('sceneGraphUpdate', sceneGraph);

                if (callback) {
                    callback(err, sceneGraph);
                }
            });

        } catch(err) {
            if(callback) {
                callback(err.message);
            }
        }
    });

    socket.on('loadScene', _findScene);

    socket.on('loadSceneGraph', _findSceneGraph);

    //TODO loadSceneGraphByName

    socket.on('loadSceneByName', function(name, callback) {
        hub.db.mediaScenes.findOne({name: name}, callback);
    });

    socket.on('deleteScene', function(sceneId, callback) {
        hub.db.mediaScenes.remove(idSearch(sceneId), function(err) {
            if (callback) {
                callback(err);
            }
        });
    });

    socket.on('subScene', function(sceneId, callback) {
        _findScene(sceneId, function(err, scene) {
            socket.join(sceneId);

            if (callback) {
                callback(err, scene);
            }
        });
    });

    socket.on('unsubScene', function(sceneId, callback) {
        _findScene(sceneId, function(err, scene) {
            socket.leave(sceneId);
            if (callback) {
                callback(err);
            }
        });
    });

    socket.on('sendCommand', function(roomId, commandName, commandValue) {
        io.to(roomId).emit('command', {name: commandName, value: commandValue});
    });

    socket.on('register', function(roomId) {
        socket.join(roomId);
    });
}

var Hub = function(config) {
    this.config = config;
    this.db = mongo.connect(config.mongo, ['mediaScenes', 'sessions', 'mediaSceneGraphs']);
    session.setClient(this.db);
};

Hub.prototype.listen = function(callback) {
    var self = this,
        app = express(),
        server = http.Server(app),
        io = new Server(server);

    this.server = server;

    app.use(cors());

    // require a valid session token for all api calls
    var validateSession =  function(req, res, next) {
        session.find(req.query.token, function(err, data) {
            if (err || ! data) {
                res.sendStatus(401);
            } else {
                next();
            }
        });
    };

    // allow cross origin requests
    io.set('origins', '*:*');
    io.sockets.on('connection', function (socket) {
        var disconnectTimer = setTimeout(function() {
            socket.disconnect();
        }, 10000);

        socket.on('auth', function (creds, callback) {

            function succeed (record) {

                //AJF: set the groupID on the socket to be used in further local calls

                //AJF: set the groupID on the socket to be used in further calls

                socket.groupID = record._groupID;
                addApiCalls(self, io, socket);
                clearTimeout(disconnectTimer);
                callback(null, record._id.toString(), socket.id, record._groupID.toString());//AJF: try to return the groupID...
            }

            function fail (msg) {
                callback(msg);
                socket.disconnect();
            }

            if (creds.hasOwnProperty('password') && creds.password && creds.password !== '') {
                //AJF: Compares the passwords and determines what group the user logging into belongs to
                if ( bcrypt.compareSync(creds.password, self.config.secret) ) {
                    session.create(0, throwErr(succeed));
                } else if (bcrypt.compareSync(creds.password, self.config.secret_1)) {
                    session.create(1, throwErr(succeed));
                } else if (bcrypt.compareSync(creds.password, self.config.secret_2)) {
                    session.create(2, throwErr(succeed));
                } else if (bcrypt.compareSync(creds.password, self.config.secret_101)) {
                    session.create(101, throwErr(succeed));
                } else if (bcrypt.compareSync(creds.password, self.config.secret_102)) {
                    session.create(102, throwErr(succeed));
                } else if (bcrypt.compareSync(creds.password, self.config.secret_103)) {
                    session.create(103, throwErr(succeed));
                } else if (bcrypt.compareSync(creds.password, self.config.secret_104)) {
                    session.create(104, throwErr(succeed));
                } else if (bcrypt.compareSync(creds.password, self.config.secret_105)) {
                    session.create(105, throwErr(succeed));
                } else if (bcrypt.compareSync(creds.password, self.config.secret_106)) {
                    session.create(106, throwErr(succeed));
                } else if (bcrypt.compareSync(creds.password, self.config.secret_107)) {
                    session.create(107, throwErr(succeed));
                } else if (bcrypt.compareSync(creds.password, self.config.secret_108)) {
                    session.create(108, throwErr(succeed));
                } else if (bcrypt.compareSync(creds.password, self.config.secret_109)) {
                    session.create(109, throwErr(succeed));
                } else if (bcrypt.compareSync(creds.password, self.config.secret_110)) {
                    session.create(110, throwErr(succeed));
                } else {
                    fail('Invalid Password');
                }

            } else if (creds.hasOwnProperty('token') && creds.token && creds.token !== '') {
                console.log("Finding session via token");
                session.find(creds.token, function(err, data) {
                        if (data) {
                            succeed(data);
                        } else {
                            fail('Invalid Token');
                        }
                    });
            } else {
                fail('Password must be provided');
            }
        });

    });

    server.listen(self.config.port, callback);
};

Hub.prototype.close = function(cb) {
    this.server.close(cb);
};

module.exports = {
    createHub: function(mongoUrl) {
        return new Hub(mongoUrl);
    }
};
<|endoftext|>


<commit_before>////////////////////////////////////////////////////////////
// Sails
// common.js
////////////////////////////////////////////////////////////

// Define global app state and configuration object
sails = {
	config	: {}
};

// Initialize logger
sails.log = require('./logger');

// TODO: Deprecate global access to everything
// (use sails.* instead)
config = sails.config;

// External dependencies
var rigging = require('rigging');
express = require('express');
ejs = require('ejs');
fs = require('fs');
path = require('path');
async = require('async');
Sequelize = require("sequelize");
_ = require('underscore');
Email = require("email").Email;
//debug = require('./logger.js').debug;
_.str = require('underscore.string');
_.mixin(_.str.exports());
_.str.include('Underscore.string', 'string');
_u = util; // shortcut for legacy

// Internal dependencies
var acl = require("./acl"),
	util = require('./util'),
	configuration = require("./configuration");

// Load and initialize the app
exports.lift = function liftSails(userConfig) {
	exports.load(userConfig, function() {
		exports.initialize(userConfig);
	});
};

// Load the dependencies and app-specific components
exports.load = function loadSails(userConfig, cb) {

	// Validate and merge user config with defaults
	sails.config = _.recursive.extend(configuration.defaults(userConfig), userConfig || {});
	userConfig = configuration.validate(sails.config,userConfig);

	// Load routes config globally
	urlMappings = _.extend({}, fs.existsSync(sails.config.appPath + '/routes.js') ? require(sails.config.appPath + '/routes') : {});

	// EXPERIMENTAL connect v2 support
	// see https://github.com/senchalabs/connect/issues/588
	//var connect = require('connect');
	//var connectCookie = require('cookie');
	//var cookieSecret = "k3yboard_kat";
	//parseCookie = function(cookie) {
	//	return connect.utils.parseSignedCookies(connectCookie.parse(decodeURIComponent(cookie)),cookieSecret);
	//}
	var connect = require('connect');
	parseCookie = connect.utils.parseCookie;
	ConnectSession = connect.middleware.session.Session;

	// Override the environment variable so express mirrors the sails env:
	process.env['NODE_ENV'] = sails.config.environment;

	// Import ORM library
	db = require(__dirname + '/orm.js').db;

	// Sync again to absorb any new tables created due to N->N associations
	db.sync(function() {
		afterModelInitialization();

		// Perform callback
		cb && cb();
	});
};

// After database is initialized
function afterModelInitialization() {
	// Run database boostrap script
	db.bootstrap();

	// Start express HTTP server (and make it available as an export)
	if (sails.config.express.serverOptions) {
		module.exports = app = express.createServer(sails.config.express.serverOptions);
	}
	else {
		module.exports = app = express.createServer();
	}

	// Configure express server
	app.enable("jsonp callback");
	app.configure(function() {
		app.set('views', sails.config.viewPath);
		app.set('view engine', sails.config.viewEngine);
		app.set('view options', {
			layout: sails.config.layout
		});

		if (sails.config.express.bodyParser) {
			app.use(sails.config.express.bodyParser);
		}

		// If this is development mode,
		if(sails.config.environment === 'development') {
			// Allow access to static dirs
			app.use(express['static'](sails.config.staticPath));

			// Allow access to compiled and uncompiled rigging directories
			app.use('/rigging_static',express['static'](sails.config.rigging.outputPath));
			_.each(sails.config.rigging.sequence,function (item) {
				// Validate that this is a directory
				var isDir = false;
				try {
					if (fs.statSync(item).isDirectory()) {
						app.use('/rigging_static',express['static'](item));
					}
				} catch (e) {
					sails.log.warn("Files not allowed in rigging.sequence in development mode-- only directories.");
					process.exit(1);
				}
			});

			// Set up error handling
			app.use(express.errorHandler({
				dumpExceptions: true,
				showStack: true
			}));

		} else if(sails.config.environment === 'production') {
			var oneYear = sails.config.cache.maxAge;
			app.use(express['static'](sails.config.staticPath, {
				maxAge: oneYear
			}));
			app.use('/rigging_production',express['static'](sails.config.rigging.outputPath, {
				maxAge: oneYear
			}));

			// ignore errors
			app.use(express.errorHandler());
		}

		if (sails.config.express.cookieParser) {
			app.use(sails.config.express.cookieParser);
		}

		// Connect session to express
		app.use(express.session(sails.config.session));

		// Add annoying Sails header instead of annoying Express header
		app.use(function(req, res, next) {
			res.header("X-Powered-By", 'Sails <sailsjs.com>)');
			next();
		});

		// Allow usage of custom express middleware
		if (sails.config.express.customMiddleware) {
			sails.config.express.customMiddleware(app);
		}

		// Allow full REST simulation for clients which don't support it natively
		// (by using _method parameter)
		if (sails.config.express.methodOverride) {
			app.use(sails.config.express.methodOverride);
		}

		// Set up express router
		app.use(app.router);
	});

	// By convention, serve .json files using the ejs engine
	app.register('.json', ejs);

	// Automatically grab and instantiate services from directory
	// CASE SENSITIVE :: USES FILENAME (i.e. ApiService)
	_.each(require('require-all')({
		dirname: sails.config.appPath + '/services',
		filter: /(.+)\.js$/
	}), function(service, filename) {
		var serviceName = filename;
		global[serviceName] = service;
	});
}

// Get socket interpreter
var socketInterpreter = require("./interpreter");

// Initialize the app (start the servers)
exports.initialize = function initSails(userConfig) {

	// Listen for websocket connections (and rejects) through socket.io
	io = require('socket.io').listen(app);

	// Set up controllers
	sails.controllers = require("./controllers");

	// Load policies
	sails.policies = require("./policies").policies;
	sails.acl = require("./policies").acl;

	// Map Routes
	// *** NOTE: MUST BE AFTER app.configure in order for bodyparser to work ***
	var router = require('./router');

	// Link Express HTTP requests to a function which handles them
	router.listen(function(url, fn, httpVerb) {
		// Use all,get,post,put,or delete conditionally based on http verb
		// null === *any* of the HTTP verbs
		if(!httpVerb) {
			app.all(url, fn);
		} else {
			_.isFunction(app[httpVerb]) && app[httpVerb](url, fn);
		}
	});

	// Link Socket.io requests to a controller/action
	// When a socket.io client connects, listen for the actions in the routing table
	io.sockets.on('connection', function(socket) {
		sails.log.debug("New socket.io client connected!", socket.id);

		// Prune data from the session to avoid sharing anything inadvertently
		// By default, very restrictive
		var pruneFn = sails.config.sessionPruneFn ||
		function(session) {
			return {};
		};

		// Respond w/ information about session
		socket.emit('sessionUpdated', pruneFn(socket.handshake.session));

		// Map routes
		socket.on('message', function(socketReq, fn) {
			socketInterpreter.route(socketReq, fn, socket);
		});
	});

	// Compile Mast components, if Rigging is in place
	sails.log.info("Initializing rigging middleware...");
	rigging.compile(sails.config.rigging.sequence, {
		environment: sails.config.environment,
		outputPath: sails.config.rigging.outputPath
	}, startServers);

	// Add beforeShutdown event
	if(_.isFunction(sails.config.beforeShutdown)) {
		process.on('SIGINT', function() {
			process.exit();
		});
		process.on('SIGTERM', function() {
			process.exit();
		});
		process.on('exit', function() {
			sails.config.beforeShutdown();
		});
	}

	// start the ws(s):// and http(s):// servers
	function startServers() {

		// Start http(s):// server
		app.listen(sails.config.port);
		if(!app.address()) {
			sails.log.warn('Error detecting app.address().');
			sails.log.warn('*************', 'Usually this means you have another instance of Sails, or something else, running on this port.', '*************');
		} else {

			sails.log.info("Sails server running on port " + app.address().port + ' in '+ app.settings.env + ' mode');
		}

		// Configure auth for ws(s):// server
		io.set('authorization', function(data, accept) {
			// Attach authorization middleware to socket event receiver
			if(data.headers.cookie) {
				data.cookie = parseCookie(data.headers.cookie);

				data.sessionID = data.cookie[sails.config.session.key];
				data.sessionStore = sails.config.session.store;

				// (literally) get the session data from the session store
				sails.config.session.store.get(data.sessionID, function(err, session) {
					if(err || !session) {

						// TODO: Cookie is invalid, so regenerate a new one

						// if we cannot grab a session, turn down the connection
						accept('Cannot load session from socket.io! (perhaps session id is invalid?)\n' + err, false);
					}

					// Save the session data and accept the connection
					else {
						// Create a session object, passing our just-acquired session data
						data.session = new ConnectSession(data, session);
						accept(null, true);
					}
				});
			} else {
				return accept('No cookie transmitted with socket.io connection.', false);
			}
		});
	}
};
<commit_msg>If rigging returns an error, throw it instead of silently failing and trying to run the app.<commit_after>////////////////////////////////////////////////////////////
// Sails
// common.js
////////////////////////////////////////////////////////////

// Define global app state and configuration object
sails = {
	config	: {}
};

// Initialize logger
sails.log = require('./logger');

// TODO: Deprecate global access to everything
// (use sails.* instead)
config = sails.config;

// External dependencies
var rigging = require('rigging');
express = require('express');
ejs = require('ejs');
fs = require('fs');
path = require('path');
async = require('async');
Sequelize = require("sequelize");
_ = require('underscore');
Email = require("email").Email;
//debug = require('./logger.js').debug;
_.str = require('underscore.string');
_.mixin(_.str.exports());
_.str.include('Underscore.string', 'string');
_u = util; // shortcut for legacy

// Internal dependencies
var acl = require("./acl"),
	util = require('./util'),
	configuration = require("./configuration");

// Load and initialize the app
exports.lift = function liftSails(userConfig) {
	exports.load(userConfig, function() {
		exports.initialize(userConfig);
	});
};

// Load the dependencies and app-specific components
exports.load = function loadSails(userConfig, cb) {

	// Validate and merge user config with defaults
	sails.config = _.recursive.extend(configuration.defaults(userConfig), userConfig || {});
	userConfig = configuration.validate(sails.config,userConfig);

	// Load routes config globally
	urlMappings = _.extend({}, fs.existsSync(sails.config.appPath + '/routes.js') ? require(sails.config.appPath + '/routes') : {});

	// EXPERIMENTAL connect v2 support
	// see https://github.com/senchalabs/connect/issues/588
	//var connect = require('connect');
	//var connectCookie = require('cookie');
	//var cookieSecret = "k3yboard_kat";
	//parseCookie = function(cookie) {
	//	return connect.utils.parseSignedCookies(connectCookie.parse(decodeURIComponent(cookie)),cookieSecret);
	//}
	var connect = require('connect');
	parseCookie = connect.utils.parseCookie;
	ConnectSession = connect.middleware.session.Session;

	// Override the environment variable so express mirrors the sails env:
	process.env['NODE_ENV'] = sails.config.environment;

	// Import ORM library
	db = require(__dirname + '/orm.js').db;

	// Sync again to absorb any new tables created due to N->N associations
	db.sync(function() {
		afterModelInitialization();

		// Perform callback
		cb && cb();
	});
};

// After database is initialized
function afterModelInitialization() {
	// Run database boostrap script
	db.bootstrap();

	// Start express HTTP server (and make it available as an export)
	if (sails.config.express.serverOptions) {
		module.exports = app = express.createServer(sails.config.express.serverOptions);
	}
	else {
		module.exports = app = express.createServer();
	}

	// Configure express server
	app.enable("jsonp callback");
	app.configure(function() {
		app.set('views', sails.config.viewPath);
		app.set('view engine', sails.config.viewEngine);
		app.set('view options', {
			layout: sails.config.layout
		});

		if (sails.config.express.bodyParser) {
			app.use(sails.config.express.bodyParser);
		}

		// If this is development mode,
		if(sails.config.environment === 'development') {
			// Allow access to static dirs
			app.use(express['static'](sails.config.staticPath));

			// Allow access to compiled and uncompiled rigging directories
			app.use('/rigging_static',express['static'](sails.config.rigging.outputPath));
			_.each(sails.config.rigging.sequence,function (item) {
				// Validate that this is a directory
				var isDir = false;
				try {
					if (fs.statSync(item).isDirectory()) {
						app.use('/rigging_static',express['static'](item));
					}
				} catch (e) {
					sails.log.warn("Files not allowed in rigging.sequence in development mode-- only directories.");
					process.exit(1);
				}
			});

			// Set up error handling
			app.use(express.errorHandler({
				dumpExceptions: true,
				showStack: true
			}));

		} else if(sails.config.environment === 'production') {
			var oneYear = sails.config.cache.maxAge;
			app.use(express['static'](sails.config.staticPath, {
				maxAge: oneYear
			}));
			app.use('/rigging_production',express['static'](sails.config.rigging.outputPath, {
				maxAge: oneYear
			}));

			// ignore errors
			app.use(express.errorHandler());
		}

		if (sails.config.express.cookieParser) {
			app.use(sails.config.express.cookieParser);
		}

		// Connect session to express
		app.use(express.session(sails.config.session));

		// Add annoying Sails header instead of annoying Express header
		app.use(function(req, res, next) {
			res.header("X-Powered-By", 'Sails <sailsjs.com>)');
			next();
		});

		// Allow usage of custom express middleware
		if (sails.config.express.customMiddleware) {
			sails.config.express.customMiddleware(app);
		}

		// Allow full REST simulation for clients which don't support it natively
		// (by using _method parameter)
		if (sails.config.express.methodOverride) {
			app.use(sails.config.express.methodOverride);
		}

		// Set up express router
		app.use(app.router);
	});

	// By convention, serve .json files using the ejs engine
	app.register('.json', ejs);

	// Automatically grab and instantiate services from directory
	// CASE SENSITIVE :: USES FILENAME (i.e. ApiService)
	_.each(require('require-all')({
		dirname: sails.config.appPath + '/services',
		filter: /(.+)\.js$/
	}), function(service, filename) {
		var serviceName = filename;
		global[serviceName] = service;
	});
}

// Get socket interpreter
var socketInterpreter = require("./interpreter");

// Initialize the app (start the servers)
exports.initialize = function initSails(userConfig) {

	// Listen for websocket connections (and rejects) through socket.io
	io = require('socket.io').listen(app);

	// Set up controllers
	sails.controllers = require("./controllers");

	// Load policies
	sails.policies = require("./policies").policies;
	sails.acl = require("./policies").acl;

	// Map Routes
	// *** NOTE: MUST BE AFTER app.configure in order for bodyparser to work ***
	var router = require('./router');

	// Link Express HTTP requests to a function which handles them
	router.listen(function(url, fn, httpVerb) {
		// Use all,get,post,put,or delete conditionally based on http verb
		// null === *any* of the HTTP verbs
		if(!httpVerb) {
			app.all(url, fn);
		} else {
			_.isFunction(app[httpVerb]) && app[httpVerb](url, fn);
		}
	});

	// Link Socket.io requests to a controller/action
	// When a socket.io client connects, listen for the actions in the routing table
	io.sockets.on('connection', function(socket) {
		sails.log.debug("New socket.io client connected!", socket.id);

		// Prune data from the session to avoid sharing anything inadvertently
		// By default, very restrictive
		var pruneFn = sails.config.sessionPruneFn ||
		function(session) {
			return {};
		};

		// Respond w/ information about session
		socket.emit('sessionUpdated', pruneFn(socket.handshake.session));

		// Map routes
		socket.on('message', function(socketReq, fn) {
			socketInterpreter.route(socketReq, fn, socket);
		});
	});

	// Compile Mast components, if Rigging is in place
	sails.log.info("Initializing rigging middleware...");
	rigging.compile(sails.config.rigging.sequence, {
		environment: sails.config.environment,
		outputPath: sails.config.rigging.outputPath
	}, function (err) {
		if (err) throw err;
		startServers();
	});

	// Add beforeShutdown event
	if(_.isFunction(sails.config.beforeShutdown)) {
		process.on('SIGINT', function() {
			process.exit();
		});
		process.on('SIGTERM', function() {
			process.exit();
		});
		process.on('exit', function() {
			sails.config.beforeShutdown();
		});
	}

	// start the ws(s):// and http(s):// servers
	function startServers() {

		// Start http(s):// server
		app.listen(sails.config.port);
		if(!app.address()) {
			sails.log.warn('Error detecting app.address().');
			sails.log.warn('*************', 'Usually this means you have another instance of Sails, or something else, running on this port.', '*************');
		} else {

			sails.log.info("Sails server running on port " + app.address().port + ' in '+ app.settings.env + ' mode');
		}

		// Configure auth for ws(s):// server
		io.set('authorization', function(data, accept) {
			// Attach authorization middleware to socket event receiver
			if(data.headers.cookie) {
				data.cookie = parseCookie(data.headers.cookie);

				data.sessionID = data.cookie[sails.config.session.key];
				data.sessionStore = sails.config.session.store;

				// (literally) get the session data from the session store
				sails.config.session.store.get(data.sessionID, function(err, session) {
					if(err || !session) {

						// TODO: Cookie is invalid, so regenerate a new one

						// if we cannot grab a session, turn down the connection
						accept('Cannot load session from socket.io! (perhaps session id is invalid?)\n' + err, false);
					}

					// Save the session data and accept the connection
					else {
						// Create a session object, passing our just-acquired session data
						data.session = new ConnectSession(data, session);
						accept(null, true);
					}
				});
			} else {
				return accept('No cookie transmitted with socket.io connection.', false);
			}
		});
	}
};
<|endoftext|>


<commit_before>'use strict';

require('colors');
var path = require('path');
var shell = require('shelljs');

// Init the local storage
var homeDir = process.env[(process.platform === 'win32') ? 'USERPROFILE' : 'HOME'];
var localDir = path.join(homeDir, '.dockgrant');
var store = require('data-store')('app', {cwd: localDir});

var level = 'info';

module.exports = {

    /**
     * Method for obtaining a valid ip for running the virtualBox image. The function
     * calculates the ip from the last acquired ip. In order to avoid concurrency problems
     * there is a lock variable to control the acquisition
     * @returns {*} Valid IP
     */
    getIp: function () {

        if (!store.get('ip_lock')) {

            var ip;

            // Set-up lock
            store.set('ip_lock', true);

            var lastAcquiredIp = store.get('last_ip');
            if (lastAcquiredIp) {

                var ip_regex = /(\d+)\.(\d+)\.(\d+)\.(\d+)(?:\.(\d+))?(?::(\d+))?/ig;
                var ip_parts = ip_regex.exec(lastAcquiredIp);
                if (ip_parts[4] === '254') {
                    ip = '192.168.1.2';
                    this.log('debug', 'Last possible ip, returning to the first one');
                } else {
                    ip = '192.168.1.' + ((ip_parts[4] % 254) + 1);
                }
            } else {
                this.log('debug', 'No ip defined, setting up the first one');
                ip = '192.168.1.2';
            }

            // Release lock
            store.set('last_ip', ip);
            this.log('debug', 'Returning ip: ' + ip);
            store.set('ip_lock', false);

            return ip;

        } else {
            // If the lock is enabled, wait for 100ms and try again
            this.log('warn', 'The lock for las acquired IP is blocking the acquisition. Waiting 100ms');
            setTimeout(this.getIp(), 100)
        }
    },

    /**
     * Generic log function for printing the logs
     * @param _level Level of debug
     * @param _msg Message to print
     */
    log: function (_level, _msg) {

        switch (_level) {
            case 'debug':
                if (this.getLogLevel() === 'debug') {
                    console.log((_msg + '').cyan);
                }
                break;
            case 'warn':
                console.warn((_msg + '').yellow);
                break;
            case 'error':
                console.error((_msg + '').red);
                break;
            default :
                console.log(_msg);
        }
    },

    /**
     * Method for exiting the program with a concrete exit code
     * @param _code Exit code
     */
    exit: function (_code) {
        this.log('debug', 'exiting program with code <' + _code + '>');
        process.exit(_code);
    },

    /**
     * Returns the full execution path of the bin command
     * @returns {string} bin command path
     */
    getBinPath: function () {
        return 'node ' + path.join(__dirname, '../src/dockgrant.js') + ' ';
    },

    /**
     * Function for testing if a concrete command is installed on the system
     * @param _command Command to test
     * @param _program Installed program
     */
    isCommandAvailable: function (_command, _program) {

        if (shell.exec(_command, {silent: true}).code !== 0) {
            this.log('error', 'The command <' + _program + '> is not available');
            this.exit(1);
        } else {
            this.log('debug', 'The command <' + _program + '> is available!');
        }
    },

    /**
     * Method for converting an array to a javascript object
     * @param arr Array
     * @returns {{}} Object with the values
     */
    toObject: function (arr) {
        var rv = {};
        for (var i = 0; i < arr.length; ++i) {
            if (arr[i] !== undefined) {
                rv[i] = arr[i];
            }
        }
        return rv;
    },

    /**
     * Sets the log level of the application
     * @param _level Level of log
     */
    setLogLevel: function (_level) {
        level = _level;
    },

    /**
     * Returns the log level of the application
     * @returns {string}
     */
    getLogLevel: function () {
        return level;
    }

};
<commit_msg>Codacy issues<commit_after>'use strict';

require('colors');
var path = require('path');
var shell = require('shelljs');

// Init the local storage
var homeDir = process.env[(process.platform === 'win32') ? 'USERPROFILE' : 'HOME'];
var localDir = path.join(homeDir, '.dockgrant');
var store = require('data-store')('app', {cwd: localDir});

var level = 'info';

module.exports = {

    /**
     * Method for obtaining a valid ip for running the virtualBox image. The function
     * calculates the ip from the last acquired ip. In order to avoid concurrency problems
     * there is a lock variable to control the acquisition
     * @returns {*} Valid IP
     */
    getIp: function () {

        if (!store.get('ip_lock')) {

            var ip;

            // Set-up lock
            store.set('ip_lock', true);

            var lastAcquiredIp = store.get('last_ip');
            if (lastAcquiredIp) {

                var ipRegex = /(\d+)\.(\d+)\.(\d+)\.(\d+)(?:\.(\d+))?(?::(\d+))?/ig;
                var ipParts = ipRegex.exec(lastAcquiredIp);
                if (ipParts[4] === '254') {
                    ip = '192.168.1.2';
                    this.log('debug', 'Last possible ip, returning to the first one');
                } else {
                    ip = '192.168.1.' + ((ipParts[4] % 254) + 1);
                }
            } else {
                this.log('debug', 'No ip defined, setting up the first one');
                ip = '192.168.1.2';
            }

            // Release lock
            store.set('last_ip', ip);
            this.log('debug', 'Returning ip: ' + ip);
            store.set('ip_lock', false);

            return ip;

        } else {
            // If the lock is enabled, wait for 100ms and try again
            this.log('warn', 'The lock for las acquired IP is blocking the acquisition. Waiting 100ms');
            setTimeout(this.getIp(), 100);
        }
    },

    /**
     * Generic log function for printing the logs
     * @param _level Level of debug
     * @param _msg Message to print
     */
    log: function (_level, _msg) {

        switch (_level) {
            case 'debug':
                if (this.getLogLevel() === 'debug') {
                    console.log((_msg + '').cyan);
                }
                break;
            case 'warn':
                console.warn((_msg + '').yellow);
                break;
            case 'error':
                console.error((_msg + '').red);
                break;
            default :
                console.log(_msg);
        }
    },

    /**
     * Method for exiting the program with a concrete exit code
     * @param _code Exit code
     */
    exit: function (_code) {
        this.log('debug', 'exiting program with code <' + _code + '>');
        process.exit(_code);
    },

    /**
     * Returns the full execution path of the bin command
     * @returns {string} bin command path
     */
    getBinPath: function () {
        return 'node ' + path.join(__dirname, '../src/dockgrant.js') + ' ';
    },

    /**
     * Function for testing if a concrete command is installed on the system
     * @param _command Command to test
     * @param _program Installed program
     */
    isCommandAvailable: function (_command, _program) {

        if (shell.exec(_command, {silent: true}).code !== 0) {
            this.log('error', 'The command <' + _program + '> is not available');
            this.exit(1);
        } else {
            this.log('debug', 'The command <' + _program + '> is available!');
        }
    },

    /**
     * Method for converting an array to a javascript object
     * @param arr Array
     * @returns {{}} Object with the values
     */
    toObject: function (arr) {
        var rv = {};
        for (var i = 0; i < arr.length; ++i) {
            if (arr[i] !== undefined) {
                rv[i] = arr[i];
            }
        }
        return rv;
    },

    /**
     * Sets the log level of the application
     * @param _level Level of log
     */
    setLogLevel: function (_level) {
        level = _level;
    },

    /**
     * Returns the log level of the application
     * @returns {string}
     */
    getLogLevel: function () {
        return level;
    }

};
<|endoftext|>


<commit_before>'use strict';

const OFF = 'off';
const ERROR = 'error';
const WARN = 'warn';

const COMPLEXITY_MAX = 5;
const TABWIDTH = 2;
const NESTED_CALLBACK_MAX = 4;
const ARGUMENTS_MAX = 4;

module.exports = {
  extends: 'eslint:recommended',
  env: {
    node: true,
  },
  globals: {
    require: false,
    module: false,
  },
  parserOptions: {
    ecmaVersion: 6,
    sourceType: 'script',
    arrowFunctions: true,
    binaryLiterals: true,
    blockBindings: true,
    classes: false,
    defaultParams: true,
    destructuring: true,
    forOf: true,
    generators: false,
    modules: false,
    objectLiteralComputedProperties: true,
    objectLiteralDuplicateProperties: true,
    objectLiteralShorthandMethods: true,
    objectLiteralShorthandProperties: true,
    octalLiterals: false,
    regexUFlag: true,
    regexYFlag: true,
    restParams: true,
    spread: true,
    superInFunctions: true,
    templateStrings: true,
    unicodeCodePointEscapes: true,
  },
  rules: {
    'accessor-pairs': [
      ERROR,
      { getWithoutSet: false, setWithoutGet: true },
    ],
    'array-bracket-spacing': [
      ERROR,
      'never',
    ],
    'array-callback-return': ERROR,
    'arrow-body-style': [
      ERROR,
      'as-needed',
    ],
    'arrow-parens': [
      ERROR,
      'as-needed',
      { requireForBlockBody: true },
    ],
    'arrow-spacing': ERROR,
    'block-spacing': [
      ERROR,
      'always',
    ],
    'brace-style': OFF,
    'callback-return': [
      ERROR, [
        'callback',
        'cb',
        'next',
        'done',
      ],
    ],
    camelcase: OFF,
    'capitalized-comments': OFF,
    'class-methods-use-this': ERROR,
    'comma-dangle': [
      ERROR,
      'always-multiline',
    ],
    'comma-spacing': [
      ERROR,
      { before: false, after: true },
    ],
    'comma-style': [
      ERROR,
      'last',
    ],
    complexity: [
      WARN,
      COMPLEXITY_MAX,
    ],
    'computed-property-spacing': [
      ERROR,
      'never',
    ],
    'consistent-return': ERROR,
    'consistent-this': [
      ERROR,
      '_this',
    ],
    'constructor-super': ERROR,
    curly: ERROR,
    'default-case': ERROR,
    'dot-location': [
      ERROR,
      'property',
    ],
    'dot-notation': ERROR,
    'eol-last': ERROR,
    eqeqeq: [
      ERROR,
      'smart',
    ],
    'func-call-spacing': [
      ERROR,
      'never',
    ],
    'func-names': WARN,
    'func-name-matching': OFF,
    'func-style': [
      ERROR,
      'declaration',
      { allowArrowFunctions: true },
    ],
    'global-require': ERROR,
    'guard-for-in': ERROR,
    'handle-callback-err': ERROR,
    'id-blacklist': OFF,
    'id-length': OFF,
    'id-match': OFF,
    indent: [
      ERROR,
      TABWIDTH,
      { SwitchCase: 1 },
    ],
    'init-declarations': OFF,
    'jsx-quotes': OFF,
    'key-spacing': [
      ERROR,
      { beforeColon: false, afterColon: true },
    ],
    'line-comment-position': OFF,
    'linebreak-style': [ERROR, 'unix'],
    'lines-around-comment': OFF,
    'lines-around-directive': OFF,
    'max-len': [
      WARN,
      100,
      TABWIDTH,
      { ignoreComments: true },
    ],
    'max-lines': [
      WARN,
      { max: 1000 },
    ],
    'max-nested-callbacks': [
      ERROR,
      NESTED_CALLBACK_MAX,
    ],
    'max-params': [
      ERROR,
      ARGUMENTS_MAX,
    ],
    'max-statements-per-line': [
      WARN,
      { max: 2 },
    ],
    'multiline-ternary': OFF,
    'new-cap': [
      ERROR,
      { newIsCap: true, capIsNew: true },
    ],
    'new-parens': ERROR,
    'newline-after-var': WARN,
    'newline-before-return': OFF,
    'newline-per-chained-call': [
      WARN,
      { ignoreChainWithDepth: 2 },
    ],
    'no-alert': ERROR,
    'no-array-constructor': ERROR,
    'no-await-in-loop': ERROR,
    'no-caller': ERROR,
    'no-case-declarations': ERROR,
    'no-catch-shadow': ERROR,
    'no-class-assign': ERROR,
    'no-confusing-arrow': OFF,
    'no-cond-assign': ERROR,
    'no-console': ERROR,
    'no-const-assign': ERROR,
    'no-constant-condition': ERROR,
    'no-continue': OFF,
    'no-control-regex': ERROR,
    'no-debugger': ERROR,
    'no-delete-var': ERROR,
    'no-div-regex': ERROR,
    'no-dupe-args': ERROR,
    'no-dupe-class-members': OFF,
    'no-dupe-keys': ERROR,
    'no-duplicate-case': ERROR,
    'no-duplicate-imports': ERROR,
    'no-else-return': ERROR,
    'no-empty': ERROR,
    'no-empty-character-class': ERROR,
    'no-empty-pattern': ERROR,
    'no-global-assign': ERROR,
    'no-labels': ERROR,
    'no-eq-null': ERROR,
    'no-eval': ERROR,
    'no-ex-assign': ERROR,
    'no-extend-native': ERROR,
    'no-extra-bind': ERROR,
    'no-extra-boolean-cast': ERROR,
    'no-extra-label': OFF,
    'no-extra-parens': OFF,
    'no-extra-semi': ERROR,
    'no-fallthrough': ERROR,
    'no-floating-decimal': ERROR,
    'no-func-assign': ERROR,
    'no-implicit-coercion': OFF,
    'no-implicit-globals': OFF,
    'no-implied-eval': ERROR,
    'no-inline-comments': OFF,
    'no-inner-declarations': ERROR,
    'no-invalid-regexp': ERROR,
    'no-invalid-this': WARN,
    'no-irregular-whitespace': ERROR,
    'no-iterator': ERROR,
    'no-label-var': ERROR,
    'no-lone-blocks': ERROR,
    'no-lonely-if': ERROR,
    'no-loop-func': ERROR,
    'no-magic-numbers': [
      ERROR,
      {
        ignoreArrayIndexes: true,
        ignore: [
          -1,
          0, 1,
          100, 101, 102,
          200, 201, 202, 203, 204, 205, 206, 207, 210, 226,
          300, 301, 302, 303, 304, 305, 306, 307, 308, 310,
          400, 401, 402, 403, 404, 405, 406, 407, 408, 409,
          410, 411, 412, 413, 414, 415, 416, 417, 418,
          421, 422, 423, 424, 425, 426, 427, 428, 429,
          431, 449, 450, 451, 456, 499,
          500, 501, 502, 503, 504, 505, 506, 507, 508, 509,
          510, 511, 520,
        ],
      },
    ],
    'no-mixed-operators': [
      ERROR,
      { allowSamePrecedence: false },
    ],
    'no-mixed-requires': OFF,
    'no-mixed-spaces-and-tabs': ERROR,
    'no-multi-spaces': ERROR,
    'no-multi-str': ERROR,
    'no-multiple-empty-lines': [
      ERROR,
      { max: 2 },
    ],
    'no-native-reassign': ERROR,
    'no-negated-condition': OFF,
    'no-negated-in-lhs': ERROR,
    'no-nested-ternary': OFF,
    'no-new': WARN,
    'no-new-func': ERROR,
    'no-new-object': ERROR,
    'no-new-require': ERROR,
    'no-new-symbol': ERROR,
    'no-obj-calls': ERROR,
    'no-octal': ERROR,
    'no-octal-escape': ERROR,
    'no-param-reassign': OFF,
    'no-path-concat': ERROR,
    'no-process-env': OFF,
    'no-process-exit': OFF,
    'no-proto': ERROR,
    'no-prototype-builtins': WARN,
    'no-redeclare': ERROR,
    'no-regex-spaces': ERROR,
    'no-reserved-keys': OFF,
    'no-restricted-globals': OFF,
    'no-restricted-imports': OFF,
    'no-restricted-modules': OFF,
    'no-restricted-syntax': OFF,
    'no-restricted-properties': [
      ERROR,
      {
        object: 'describe',
        property: 'only',
        message: 'Using describe.only is not allowed',
      }, {
        object: 'it',
        property: 'only',
        message: 'Using it.only is not allowed',
      },
    ],
    'no-return-assign': ERROR,
    'no-return-await': ERROR,
    'no-script-url': ERROR,
    'no-self-assign': ERROR,
    'no-self-compare': ERROR,
    'no-sequences': ERROR,
    'no-shadow': WARN,
    'no-shadow-restricted-names': ERROR,
    'no-spaced-func': ERROR,
    'no-sparse-arrays': ERROR,
    'no-sync': OFF,
    'no-tabs': ERROR,
    'no-ternary': OFF,
    'no-template-curly-in-string': WARN,
    'no-throw-literal': ERROR,
    'no-this-before-super': ERROR,
    'no-trailing-spaces': ERROR,
    'no-undef': ERROR,
    'no-undef-init': ERROR,
    'no-undefined': ERROR,
    'no-underscore-dangle': OFF,
    'no-unexpected-multiline': ERROR,
    'no-unmodified-loop-condition': ERROR,
    'no-unneeded-ternary': ERROR,
    'no-unreachable': ERROR,
    'no-unsafe-finally': ERROR,
    'no-unsafe-negation': ERROR,
    'no-unused-expressions': ERROR,
    'no-unused-labels': OFF,
    'no-unused-vars': [
      ERROR,
      { args: 'none' },
    ],
    'no-use-before-define': [
      ERROR,
      'nofunc',
    ],
    'no-useless-call': ERROR,
    'no-useless-computed-key': ERROR,
    'no-useless-concat': ERROR,
    'no-useless-constructor': ERROR,
    'no-useless-escape': WARN,
    'no-useless-rename': WARN,
    'no-useless-return': ERROR,
    'no-void': ERROR,
    'no-warning-comments': OFF,
    'no-with': ERROR,
    'no-whitespace-before-property': WARN,
    'object-curly-newline': OFF,
    'object-curly-spacing': [
      ERROR,
      'always',
    ],
    'object-property-newline': [
      ERROR,
      { allowMultiplePropertiesPerLine: true },
    ],
    'one-var': [
      ERROR,
      'never',
    ],
    'one-var-declaration-per-line': OFF,
    'operator-assignment': [
      ERROR,
      'always',
    ],
    'operator-linebreak': [
      ERROR,
      'after',
    ],
    'padded-blocks': OFF,
    'prefer-arrow-callback': OFF,
    'prefer-numeric-literals': ERROR,
    'prefer-reflect': OFF,
    'prefer-rest-params': WARN,
    'prefer-spread': OFF,
    'prefer-template': OFF,
    'quote-props': [
      ERROR,
      'as-needed',
    ],
    quotes: [
      ERROR,
      'single',
    ],
    radix: ERROR,
    'require-await': WARN,
    'require-jsdoc': OFF,
    'require-yield': ERROR,
    'rest-spread-spacing': [
      ERROR,
      'never',
    ],
    semi: [
      ERROR,
      'always',
    ],
    'semi-spacing': [
      ERROR,
      { before: false, after: true },
    ],
    'sort-imports': OFF,
    'sort-keys': OFF,
    'sort-vars': OFF,
    'space-after-keywords': OFF,
    'space-before-blocks': [
      ERROR,
      'always',
    ],
    'space-before-function-paren': [
      ERROR,
      'never',
    ],
    'keyword-spacing': [
      'error',
      {
        before: true,
        after: true,
        overrides: {
          if: { after: false },
          for: { after: false },
          while: { after: false },
        },
      },
    ],
    'space-in-parens': [
      ERROR,
      'never',
    ],
    'space-infix-ops': ERROR,
    'space-unary-ops': ERROR,
    'spaced-comment': [
      ERROR,
      'always',
    ],
    'symbol-description': ERROR,
    'template-curly-spacing': [
      ERROR,
      'never',
    ],
    'unicode-bom': ERROR,
    'valid-jsdoc': ERROR,
    'valid-typeof': ERROR,
    'vars-on-top': ERROR,
    'wrap-iife': ERROR,
    'wrap-regex': ERROR,
    yoda: [
      ERROR,
      'always',
    ],
  },
};
<commit_msg>feat(rules): add eslint v3.13.0 rules<commit_after>'use strict';

const OFF = 'off';
const ERROR = 'error';
const WARN = 'warn';

const COMPLEXITY_MAX = 5;
const TABWIDTH = 2;
const NESTED_CALLBACK_MAX = 4;
const ARGUMENTS_MAX = 4;

module.exports = {
  extends: 'eslint:recommended',
  env: {
    node: true,
  },
  globals: {
    require: false,
    module: false,
  },
  parserOptions: {
    ecmaVersion: 6,
    sourceType: 'script',
    arrowFunctions: true,
    binaryLiterals: true,
    blockBindings: true,
    classes: false,
    defaultParams: true,
    destructuring: true,
    forOf: true,
    generators: false,
    modules: false,
    objectLiteralComputedProperties: true,
    objectLiteralDuplicateProperties: true,
    objectLiteralShorthandMethods: true,
    objectLiteralShorthandProperties: true,
    octalLiterals: false,
    regexUFlag: true,
    regexYFlag: true,
    restParams: true,
    spread: true,
    superInFunctions: true,
    templateStrings: true,
    unicodeCodePointEscapes: true,
  },
  rules: {
    'accessor-pairs': [
      ERROR,
      { getWithoutSet: false, setWithoutGet: true },
    ],
    'array-bracket-spacing': [
      ERROR,
      'never',
    ],
    'array-callback-return': ERROR,
    'arrow-body-style': [
      ERROR,
      'as-needed',
    ],
    'arrow-parens': [
      ERROR,
      'as-needed',
      { requireForBlockBody: true },
    ],
    'arrow-spacing': ERROR,
    'block-spacing': [
      ERROR,
      'always',
    ],
    'brace-style': OFF,
    'callback-return': [
      ERROR, [
        'callback',
        'cb',
        'next',
        'done',
      ],
    ],
    camelcase: OFF,
    'capitalized-comments': OFF,
    'class-methods-use-this': ERROR,
    'comma-dangle': [
      ERROR,
      'always-multiline',
    ],
    'comma-spacing': [
      ERROR,
      { before: false, after: true },
    ],
    'comma-style': [
      ERROR,
      'last',
    ],
    complexity: [
      WARN,
      COMPLEXITY_MAX,
    ],
    'computed-property-spacing': [
      ERROR,
      'never',
    ],
    'consistent-return': ERROR,
    'consistent-this': [
      ERROR,
      '_this',
    ],
    'constructor-super': ERROR,
    curly: ERROR,
    'default-case': ERROR,
    'dot-location': [
      ERROR,
      'property',
    ],
    'dot-notation': ERROR,
    'eol-last': ERROR,
    eqeqeq: [
      ERROR,
      'smart',
    ],
    'func-call-spacing': [
      ERROR,
      'never',
    ],
    'func-names': WARN,
    'func-name-matching': OFF,
    'func-style': [
      ERROR,
      'declaration',
      { allowArrowFunctions: true },
    ],
    'global-require': ERROR,
    'guard-for-in': ERROR,
    'handle-callback-err': ERROR,
    'id-blacklist': OFF,
    'id-length': OFF,
    'id-match': OFF,
    indent: [
      ERROR,
      TABWIDTH,
      { SwitchCase: 1 },
    ],
    'init-declarations': OFF,
    'jsx-quotes': OFF,
    'key-spacing': [
      ERROR,
      { beforeColon: false, afterColon: true },
    ],
    'line-comment-position': OFF,
    'linebreak-style': [ERROR, 'unix'],
    'lines-around-comment': OFF,
    'lines-around-directive': OFF,
    'max-len': [
      WARN,
      100,
      TABWIDTH,
      { ignoreComments: true },
    ],
    'max-lines': [
      WARN,
      { max: 1000 },
    ],
    'max-nested-callbacks': [
      ERROR,
      NESTED_CALLBACK_MAX,
    ],
    'max-params': [
      ERROR,
      ARGUMENTS_MAX,
    ],
    'max-statements-per-line': [
      WARN,
      { max: 2 },
    ],
    'multiline-ternary': OFF,
    'new-cap': [
      ERROR,
      { newIsCap: true, capIsNew: true },
    ],
    'new-parens': ERROR,
    'newline-after-var': WARN,
    'newline-before-return': OFF,
    'newline-per-chained-call': [
      WARN,
      { ignoreChainWithDepth: 2 },
    ],
    'no-alert': ERROR,
    'no-array-constructor': ERROR,
    'no-await-in-loop': ERROR,
    'no-caller': ERROR,
    'no-case-declarations': ERROR,
    'no-catch-shadow': ERROR,
    'no-class-assign': ERROR,
    'no-confusing-arrow': OFF,
    'no-cond-assign': ERROR,
    'no-console': ERROR,
    'no-const-assign': ERROR,
    'no-constant-condition': ERROR,
    'no-continue': OFF,
    'no-control-regex': ERROR,
    'no-debugger': ERROR,
    'no-delete-var': ERROR,
    'no-div-regex': ERROR,
    'no-dupe-args': ERROR,
    'no-dupe-class-members': OFF,
    'no-dupe-keys': ERROR,
    'no-duplicate-case': ERROR,
    'no-duplicate-imports': ERROR,
    'no-else-return': ERROR,
    'no-empty': ERROR,
    'no-empty-character-class': ERROR,
    'no-empty-pattern': ERROR,
    'no-global-assign': ERROR,
    'no-labels': ERROR,
    'no-eq-null': ERROR,
    'no-eval': ERROR,
    'no-ex-assign': ERROR,
    'no-extend-native': ERROR,
    'no-extra-bind': ERROR,
    'no-extra-boolean-cast': ERROR,
    'no-extra-label': OFF,
    'no-extra-parens': OFF,
    'no-extra-semi': ERROR,
    'no-fallthrough': ERROR,
    'no-floating-decimal': ERROR,
    'no-func-assign': ERROR,
    'no-implicit-coercion': OFF,
    'no-implicit-globals': OFF,
    'no-implied-eval': ERROR,
    'no-inline-comments': OFF,
    'no-inner-declarations': ERROR,
    'no-invalid-regexp': ERROR,
    'no-invalid-this': WARN,
    'no-irregular-whitespace': ERROR,
    'no-iterator': ERROR,
    'no-label-var': ERROR,
    'no-lone-blocks': ERROR,
    'no-lonely-if': ERROR,
    'no-loop-func': ERROR,
    'no-magic-numbers': [
      ERROR,
      {
        ignoreArrayIndexes: true,
        ignore: [
          -1,
          0, 1,
          100, 101, 102,
          200, 201, 202, 203, 204, 205, 206, 207, 210, 226,
          300, 301, 302, 303, 304, 305, 306, 307, 308, 310,
          400, 401, 402, 403, 404, 405, 406, 407, 408, 409,
          410, 411, 412, 413, 414, 415, 416, 417, 418,
          421, 422, 423, 424, 425, 426, 427, 428, 429,
          431, 449, 450, 451, 456, 499,
          500, 501, 502, 503, 504, 505, 506, 507, 508, 509,
          510, 511, 520,
        ],
      },
    ],
    'no-mixed-operators': [
      ERROR,
      { allowSamePrecedence: false },
    ],
    'no-mixed-requires': OFF,
    'no-mixed-spaces-and-tabs': ERROR,
    'no-multi-spaces': ERROR,
    'no-multi-str': ERROR,
    'no-multiple-empty-lines': [
      ERROR,
      { max: 2 },
    ],
    'no-native-reassign': ERROR,
    'no-negated-condition': OFF,
    'no-negated-in-lhs': ERROR,
    'no-nested-ternary': OFF,
    'no-new': WARN,
    'no-new-func': ERROR,
    'no-new-object': ERROR,
    'no-new-require': ERROR,
    'no-new-symbol': ERROR,
    'no-obj-calls': ERROR,
    'no-octal': ERROR,
    'no-octal-escape': ERROR,
    'no-param-reassign': OFF,
    'no-path-concat': ERROR,
    'no-process-env': OFF,
    'no-process-exit': OFF,
    'no-proto': ERROR,
    'no-prototype-builtins': WARN,
    'no-redeclare': ERROR,
    'no-regex-spaces': ERROR,
    'no-reserved-keys': OFF,
    'no-restricted-globals': OFF,
    'no-restricted-imports': OFF,
    'no-restricted-modules': OFF,
    'no-restricted-syntax': OFF,
    'no-restricted-properties': [
      ERROR,
      {
        object: 'describe',
        property: 'only',
        message: 'Using describe.only is not allowed',
      }, {
        object: 'it',
        property: 'only',
        message: 'Using it.only is not allowed',
      },
    ],
    'no-return-assign': ERROR,
    'no-return-await': ERROR,
    'no-script-url': ERROR,
    'no-self-assign': ERROR,
    'no-self-compare': ERROR,
    'no-sequences': ERROR,
    'no-shadow': WARN,
    'no-shadow-restricted-names': ERROR,
    'no-spaced-func': ERROR,
    'no-sparse-arrays': ERROR,
    'no-sync': OFF,
    'no-tabs': ERROR,
    'no-ternary': OFF,
    'no-template-curly-in-string': WARN,
    'no-throw-literal': ERROR,
    'no-this-before-super': ERROR,
    'no-trailing-spaces': ERROR,
    'no-undef': ERROR,
    'no-undef-init': ERROR,
    'no-undefined': ERROR,
    'no-underscore-dangle': OFF,
    'no-unexpected-multiline': ERROR,
    'no-unmodified-loop-condition': ERROR,
    'no-unneeded-ternary': ERROR,
    'no-unreachable': ERROR,
    'no-unsafe-finally': ERROR,
    'no-unsafe-negation': ERROR,
    'no-unused-expressions': ERROR,
    'no-unused-labels': OFF,
    'no-unused-vars': [
      ERROR,
      { args: 'none' },
    ],
    'no-use-before-define': [
      ERROR,
      'nofunc',
    ],
    'no-useless-call': ERROR,
    'no-useless-computed-key': ERROR,
    'no-useless-concat': ERROR,
    'no-useless-constructor': ERROR,
    'no-useless-escape': WARN,
    'no-useless-rename': WARN,
    'no-useless-return': ERROR,
    'no-void': ERROR,
    'no-warning-comments': OFF,
    'no-with': ERROR,
    'no-whitespace-before-property': WARN,
    'object-curly-newline': OFF,
    'object-curly-spacing': [
      ERROR,
      'always',
    ],
    'object-property-newline': [
      ERROR,
      { allowMultiplePropertiesPerLine: true },
    ],
    'one-var': [
      ERROR,
      'never',
    ],
    'one-var-declaration-per-line': OFF,
    'operator-assignment': [
      ERROR,
      'always',
    ],
    'operator-linebreak': [
      ERROR,
      'after',
    ],
    'padded-blocks': OFF,
    'prefer-arrow-callback': OFF,
    'prefer-destructuring': OFF,
    'prefer-numeric-literals': ERROR,
    'prefer-reflect': OFF,
    'prefer-rest-params': WARN,
    'prefer-spread': OFF,
    'prefer-template': OFF,
    'quote-props': [
      ERROR,
      'as-needed',
    ],
    quotes: [
      ERROR,
      'single',
    ],
    radix: ERROR,
    'require-await': WARN,
    'require-jsdoc': OFF,
    'require-yield': ERROR,
    'rest-spread-spacing': [
      ERROR,
      'never',
    ],
    semi: [
      ERROR,
      'always',
    ],
    'semi-spacing': [
      ERROR,
      { before: false, after: true },
    ],
    'sort-imports': OFF,
    'sort-keys': OFF,
    'sort-vars': OFF,
    'space-after-keywords': OFF,
    'space-before-blocks': [
      ERROR,
      'always',
    ],
    'space-before-function-paren': [
      ERROR,
      'never',
    ],
    'keyword-spacing': [
      'error',
      {
        before: true,
        after: true,
        overrides: {
          if: { after: false },
          for: { after: false },
          while: { after: false },
        },
      },
    ],
    'space-in-parens': [
      ERROR,
      'never',
    ],
    'space-infix-ops': ERROR,
    'space-unary-ops': ERROR,
    'spaced-comment': [
      ERROR,
      'always',
    ],
    'symbol-description': ERROR,
    'template-curly-spacing': [
      ERROR,
      'never',
    ],
    'unicode-bom': ERROR,
    'valid-jsdoc': ERROR,
    'valid-typeof': ERROR,
    'vars-on-top': ERROR,
    'wrap-iife': ERROR,
    'wrap-regex': ERROR,
    yoda: [
      ERROR,
      'always',
    ],
  },
};
<|endoftext|>