<commit_before>import {
    action,
    intercept,
    observable,
    reaction,
    toJS,
    when }               from 'mobx';
import { isEmptyObject } from '_common/utility';
import Validator         from 'Utils/Validator';
import { isProduction }  from '../../config';

/**
 * BaseStore class is the base class for all defined stores in the application. It handles some stuff such as:
 *  1. Creating snapshot object from the store.
 *  2. Saving the store's snapshot in local/session storage and keeping them in sync.
 */
export default class BaseStore {

    /**
     * An enum object to define LOCAL_STORAGE and SESSION_STORAGE
     */
    static STORAGES = Object.freeze({
        LOCAL_STORAGE  : Symbol('LOCAL_STORAGE'),
        SESSION_STORAGE: Symbol('SESSION_STORAGE'),
    });

    @observable
    validation_errors = {};

    @observable
    validation_rules = {};

    switchAccountDisposer = null;
    switch_account_listener = null;

    /**
     * Constructor of the base class that gets properties' name of child which should be saved in storages
     *
     * @param {Object} options - An object that contains the following properties:
     *     @property {Object}   root_store - An object that contains the root store of the app.
     *     @property {String[]} local_storage_properties - A list of properties' names that should be kept in localStorage.
     *     @property {String[]} session_storage_properties - A list of properties' names that should be kept in sessionStorage.
     *     @property {Object}   validation_rules - An object that contains the validation rules for each property of the store.
     */
    constructor(options = {}) {
        const {
            root_store,
            local_storage_properties,
            session_storage_properties,
            validation_rules,
        } = options;

        Object.defineProperty(this, 'root_store', {
            enumerable: false,
            writable  : true,
        });
        Object.defineProperty(this, 'local_storage_properties', {
            enumerable: false,
            writable  : true,
        });
        Object.defineProperty(this, 'session_storage_properties', {
            enumerable: false,
            writable  : true,
        });

        this.root_store                 = root_store;
        this.local_storage_properties   = local_storage_properties || [];
        this.session_storage_properties = session_storage_properties || [];
        this.setValidationRules(validation_rules);

        this.setupReactionForLocalStorage();
        this.setupReactionForSessionStorage();
        this.retrieveFromStorage();
    }

    /**
     * Returns an snapshot of the current store
     *
     * @param {String[]} properties - A list of properties' names that should be in the snapshot.
     *
     * @return {Object} Returns a cloned object of the store.
     */
    getSnapshot(properties) {
        let snapshot = toJS(this);

        if (!isEmptyObject(this.root_store)) {
            snapshot.root_store = this.root_store;
        }

        if (properties && properties.length) {
            snapshot = properties.reduce(
                (result, p) => Object.assign(result, { [p]: snapshot[p] }),
                {},
            );
        }

        return snapshot;
    }

    /**
     * Sets up a reaction on properties which are mentioned in `local_storage_properties`
     *  and invokes `saveToStorage` when there are any changes on them.
     *
     */
    setupReactionForLocalStorage() {
        if (this.local_storage_properties.length) {
            reaction(
                () => this.local_storage_properties.map(i => this[i]),
                () => this.saveToStorage(this.local_storage_properties, BaseStore.STORAGES.LOCAL_STORAGE),
            );
        }
    }

    /**
     * Sets up a reaction on properties which are mentioned in `session_storage_properties`
     *  and invokes `saveToStorage` when there are any changes on them.
     *
     */
    setupReactionForSessionStorage() {
        if (this.session_storage_properties.length) {
            reaction(
                () => this.session_storage_properties.map(i => this[i]),
                () => this.saveToStorage(this.session_storage_properties, BaseStore.STORAGES.SESSION_STORAGE),
            );
        }
    }

    /**
     * Removes properties that are not passed from the snapshot of the store and saves it to the passed storage
     *
     * @param {String[]} properties - A list of the store's properties' names which should be saved in the storage.
     * @param {Symbol}   storage    - A symbol object that defines the storage which the snapshot should be stored in it.
     *
     */
    saveToStorage(properties, storage) {
        const snapshot = JSON.stringify(this.getSnapshot(properties), (key, value) => {
            if (value !== null) return value;
            return undefined;
        });

        if (storage === BaseStore.STORAGES.LOCAL_STORAGE) {
            localStorage.setItem(this.constructor.name, snapshot);
        } else if (storage === BaseStore.STORAGES.SESSION_STORAGE) {
            sessionStorage.setItem(this.constructor.name, snapshot);
        }
    }

    /**
     * Retrieves saved snapshot of the store and assigns to the current instance.
     *
     */
    @action
    retrieveFromStorage() {
        const local_storage_snapshot   = JSON.parse(localStorage.getItem(this.constructor.name, {}));
        const session_storage_snapshot = JSON.parse(sessionStorage.getItem(this.constructor.name, {}));

        const snapshot = { ...local_storage_snapshot, ...session_storage_snapshot };

        Object.keys(snapshot).forEach((k) => this[k] = snapshot[k]);
    }

    /**
     * Sets validation error messages for an observable property of the store
     *
     * @param {String} propertyName - The observable property's name
     * @param {String} messages - An array of strings that contains validation error messages for the particular property.
     *
     */
    @action
    setValidationErrorMessages(propertyName, messages) {
        this.validation_errors[propertyName] = messages;
    }

    /**
     * Sets validation rules
     *
     * @param {object} rules
     *
     */
    @action
    setValidationRules(rules = {}) {
        Object.keys(rules).forEach(key => {
            this.addRule(key, rules[key]);
        });
    }

    /**
     * Adds rules to the particular property
     *
     * @param {String} property
     * @param {String} rules
     *
     */
    @action
    addRule(property, rules) {
        this.validation_rules[property] = rules;

        intercept(this, property, change => {
            this.validateProperty(property, change.newValue);
            return change;
        });
    }

    /**
     * Validates a particular property of the store
     *
     * @param {String} property - The name of the property in the store
     * @param {object} value    - The value of the property, it can be undefined.
     *
     */
    @action
    validateProperty(property, value) {
        const trigger          = this.validation_rules[property].trigger;
        const inputs           = { [property]: value !== undefined ? value : this[property] };
        const validation_rules = { [property]: (this.validation_rules[property].rules || []) };

        if (!!trigger && Object.hasOwnProperty.call(this, trigger)) {
            inputs[trigger]           = this[trigger];
            validation_rules[trigger] = this.validation_rules[trigger].rules || [];
        }

        const validator = new Validator(
            inputs,
            validation_rules,
            this,
        );

        validator.isPassed();

        Object.keys(inputs).forEach(key => {
            this.setValidationErrorMessages(key, validator.errors.get(key));
        });
    }

    /**
     * Validates all properties which validation rule has been set for.
     *
     */
    @action
    validateAllProperties() {
        this.validation_errors = {};
        Object.keys(this.validation_rules).forEach(p => {
            this.validateProperty(p, this[p]);
        });
    }
}
<commit_msg>remove ununsed imports<commit_after>import {
    action,
    intercept,
    observable,
    reaction,
    toJS }               from 'mobx';
import { isEmptyObject } from '_common/utility';
import Validator         from 'Utils/Validator';

/**
 * BaseStore class is the base class for all defined stores in the application. It handles some stuff such as:
 *  1. Creating snapshot object from the store.
 *  2. Saving the store's snapshot in local/session storage and keeping them in sync.
 */
export default class BaseStore {

    /**
     * An enum object to define LOCAL_STORAGE and SESSION_STORAGE
     */
    static STORAGES = Object.freeze({
        LOCAL_STORAGE  : Symbol('LOCAL_STORAGE'),
        SESSION_STORAGE: Symbol('SESSION_STORAGE'),
    });

    @observable
    validation_errors = {};

    @observable
    validation_rules = {};

    switchAccountDisposer = null;
    switch_account_listener = null;

    /**
     * Constructor of the base class that gets properties' name of child which should be saved in storages
     *
     * @param {Object} options - An object that contains the following properties:
     *     @property {Object}   root_store - An object that contains the root store of the app.
     *     @property {String[]} local_storage_properties - A list of properties' names that should be kept in localStorage.
     *     @property {String[]} session_storage_properties - A list of properties' names that should be kept in sessionStorage.
     *     @property {Object}   validation_rules - An object that contains the validation rules for each property of the store.
     */
    constructor(options = {}) {
        const {
            root_store,
            local_storage_properties,
            session_storage_properties,
            validation_rules,
        } = options;

        Object.defineProperty(this, 'root_store', {
            enumerable: false,
            writable  : true,
        });
        Object.defineProperty(this, 'local_storage_properties', {
            enumerable: false,
            writable  : true,
        });
        Object.defineProperty(this, 'session_storage_properties', {
            enumerable: false,
            writable  : true,
        });

        this.root_store                 = root_store;
        this.local_storage_properties   = local_storage_properties || [];
        this.session_storage_properties = session_storage_properties || [];
        this.setValidationRules(validation_rules);

        this.setupReactionForLocalStorage();
        this.setupReactionForSessionStorage();
        this.retrieveFromStorage();
    }

    /**
     * Returns an snapshot of the current store
     *
     * @param {String[]} properties - A list of properties' names that should be in the snapshot.
     *
     * @return {Object} Returns a cloned object of the store.
     */
    getSnapshot(properties) {
        let snapshot = toJS(this);

        if (!isEmptyObject(this.root_store)) {
            snapshot.root_store = this.root_store;
        }

        if (properties && properties.length) {
            snapshot = properties.reduce(
                (result, p) => Object.assign(result, { [p]: snapshot[p] }),
                {},
            );
        }

        return snapshot;
    }

    /**
     * Sets up a reaction on properties which are mentioned in `local_storage_properties`
     *  and invokes `saveToStorage` when there are any changes on them.
     *
     */
    setupReactionForLocalStorage() {
        if (this.local_storage_properties.length) {
            reaction(
                () => this.local_storage_properties.map(i => this[i]),
                () => this.saveToStorage(this.local_storage_properties, BaseStore.STORAGES.LOCAL_STORAGE),
            );
        }
    }

    /**
     * Sets up a reaction on properties which are mentioned in `session_storage_properties`
     *  and invokes `saveToStorage` when there are any changes on them.
     *
     */
    setupReactionForSessionStorage() {
        if (this.session_storage_properties.length) {
            reaction(
                () => this.session_storage_properties.map(i => this[i]),
                () => this.saveToStorage(this.session_storage_properties, BaseStore.STORAGES.SESSION_STORAGE),
            );
        }
    }

    /**
     * Removes properties that are not passed from the snapshot of the store and saves it to the passed storage
     *
     * @param {String[]} properties - A list of the store's properties' names which should be saved in the storage.
     * @param {Symbol}   storage    - A symbol object that defines the storage which the snapshot should be stored in it.
     *
     */
    saveToStorage(properties, storage) {
        const snapshot = JSON.stringify(this.getSnapshot(properties), (key, value) => {
            if (value !== null) return value;
            return undefined;
        });

        if (storage === BaseStore.STORAGES.LOCAL_STORAGE) {
            localStorage.setItem(this.constructor.name, snapshot);
        } else if (storage === BaseStore.STORAGES.SESSION_STORAGE) {
            sessionStorage.setItem(this.constructor.name, snapshot);
        }
    }

    /**
     * Retrieves saved snapshot of the store and assigns to the current instance.
     *
     */
    @action
    retrieveFromStorage() {
        const local_storage_snapshot   = JSON.parse(localStorage.getItem(this.constructor.name, {}));
        const session_storage_snapshot = JSON.parse(sessionStorage.getItem(this.constructor.name, {}));

        const snapshot = { ...local_storage_snapshot, ...session_storage_snapshot };

        Object.keys(snapshot).forEach((k) => this[k] = snapshot[k]);
    }

    /**
     * Sets validation error messages for an observable property of the store
     *
     * @param {String} propertyName - The observable property's name
     * @param {String} messages - An array of strings that contains validation error messages for the particular property.
     *
     */
    @action
    setValidationErrorMessages(propertyName, messages) {
        this.validation_errors[propertyName] = messages;
    }

    /**
     * Sets validation rules
     *
     * @param {object} rules
     *
     */
    @action
    setValidationRules(rules = {}) {
        Object.keys(rules).forEach(key => {
            this.addRule(key, rules[key]);
        });
    }

    /**
     * Adds rules to the particular property
     *
     * @param {String} property
     * @param {String} rules
     *
     */
    @action
    addRule(property, rules) {
        this.validation_rules[property] = rules;

        intercept(this, property, change => {
            this.validateProperty(property, change.newValue);
            return change;
        });
    }

    /**
     * Validates a particular property of the store
     *
     * @param {String} property - The name of the property in the store
     * @param {object} value    - The value of the property, it can be undefined.
     *
     */
    @action
    validateProperty(property, value) {
        const trigger          = this.validation_rules[property].trigger;
        const inputs           = { [property]: value !== undefined ? value : this[property] };
        const validation_rules = { [property]: (this.validation_rules[property].rules || []) };

        if (!!trigger && Object.hasOwnProperty.call(this, trigger)) {
            inputs[trigger]           = this[trigger];
            validation_rules[trigger] = this.validation_rules[trigger].rules || [];
        }

        const validator = new Validator(
            inputs,
            validation_rules,
            this,
        );

        validator.isPassed();

        Object.keys(inputs).forEach(key => {
            this.setValidationErrorMessages(key, validator.errors.get(key));
        });
    }

    /**
     * Validates all properties which validation rule has been set for.
     *
     */
    @action
    validateAllProperties() {
        this.validation_errors = {};
        Object.keys(this.validation_rules).forEach(p => {
            this.validateProperty(p, this[p]);
        });
    }
}
<|endoftext|>


<commit_before>/*jslint node: true */

'use strict';

var util = require('util');
var oneDay = 86400;

module.exports = function (session) {

  var Store = session.Store || session.session.Store,
    PGStore;

  PGStore = function (options) {
    options = options || {};
    Store.call(this, options);

    this.schemaName = options.schemaName || null;
    this.tableName = options.tableName || 'session';

    this.conString = options.conString || process.env.DATABASE_URL;
    this.ttl =  options.ttl;
    this.pg = options.pg || require('pg');
    this.ownsPg = !options.pg;

    this.errorLog = options.errorLog || console.error.bind(console);

    if (options.pruneSessionInterval === false) {
      this.pruneSessionInterval = false;
    } else {
      this.pruneSessionInterval = (options.pruneSessionInterval || 60) * 1000;
      setImmediate(function () {
        this.pruneSessions();
      }.bind(this));
    }
  };

  /**
   * Inherit from `Store`.
   */

  util.inherits(PGStore, Store);

  /**
   * Closes the session store
   *
   * Currently only stops the automatic pruning, if any, from continuing
   *
   * @access public
   */

  PGStore.prototype.close = function () {
    this.closed = true;

    if (this.pruneTimer) {
      clearTimeout(this.pruneTimer);
      this.pruneTimer = undefined;
    }

    if (this.ownsPg) {
      this.pg.end();
    }
  };

  /**
   * Does garbage collection for expired session in the database
   *
   * @param {Function} [fn] - standard Node.js callback called on completion
   * @access public
   */

  PGStore.prototype.pruneSessions = function (fn) {
    this.query('DELETE FROM ' + this.quotedTable() + ' WHERE expire < NOW()', function (err) {
      if (fn && typeof fn === 'function') {
        return fn(err);
      }

      if (err) {
        this.errorLog('Failed to prune sessions:', err.message);
      }

      if (this.pruneSessionInterval && !this.closed) {
        if (this.pruneTimer) {
          clearTimeout(this.pruneTimer);
        }
        this.pruneTimer = setTimeout(this.pruneSessions.bind(this, true), this.pruneSessionInterval);
      }
    }.bind(this));
  };

  /**
   * Get the quoted table.
   *
   * @return {String} the quoted schema + table for use in queries
   * @access private
   */

  PGStore.prototype.quotedTable = function () {
    var result = '"' + this.tableName + '"';

    if (this.schemaName) {
      result = '"' + this.schemaName + '".' + result;
    }

    return result;
  };

  /**
   * Figure out when a session should expire
   *
   * @param {Number} [maxAge] - the maximum age of the session cookie
   * @return {Number} the unix timestamp, in seconds
   * @access private
   */

  PGStore.prototype.getExpireTime = function (maxAge) {
    var ttl = this.ttl;

    ttl = ttl || (typeof maxAge === 'number' ? maxAge / 1000 : oneDay);
    ttl = Math.ceil(ttl + Date.now() / 1000);

    return ttl;
  };

  /**
   * Query the database.
   *
   * @param {String} query - the database query to perform
   * @param {(Array|Function)} [params] - the parameters of the query or the callback function
   * @param {Function} [fn] - standard Node.js callback returning the resulting rows
   * @access private
   */

  PGStore.prototype.query = function (query, params, fn) {
    if (!fn && typeof params === 'function') {
      fn = params;
    }
    this.pg.connect(this.conString, function (err, client, done) {
      if (err) {
        done(client);
        if (fn) { fn(err); }
      } else {
        client.query(query, params || [], function (err, result) {
          done(err || false);
          if (fn) { fn(err, result && result.rows[0] ? result.rows[0] : false); }
        });
      }
    });
  };

  /**
   * Attempt to fetch session by the given `sid`.
   *
   * @param {String} sid – the session id
   * @param {Function} fn – a standard Node.js callback returning the parsed session object
   * @access public
   */

  PGStore.prototype.get = function (sid, fn) {
    this.query('SELECT sess FROM ' + this.quotedTable() + ' WHERE sid = $1 AND expire >= NOW()', [sid], function (err, data) {
      if (err) { return fn(err); }
      if (!data) { return fn(); }
      try {
        return fn(null, ('string' === typeof data.sess) ? JSON.parse(data.sess) : data.sess);
      } catch (e) {
        return this.destroy(sid, fn);
      }
    }.bind(this));
  };

  /**
   * Commit the given `sess` object associated with the given `sid`.
   *
   * @param {String} sid – the session id
   * @param {Object} sess – the session object to store
   * @param {Function} fn – a standard Node.js callback returning the parsed session object
   * @access public
   */

  PGStore.prototype.set = function (sid, sess, fn) {
    var self = this;
    var expireTime = this.getExpireTime(sess.cookie.maxAge);
    var query = 'UPDATE ' + this.quotedTable() + ' SET sess = $1, expire = to_timestamp($2) WHERE sid = $3 RETURNING sid';

    this.query(query, [sess, expireTime, sid], function (err, data) {
      if (!err && data === false) {
        query = 'INSERT INTO ' + self.quotedTable() + ' (sess, expire, sid) SELECT $1, to_timestamp($2), $3 WHERE NOT EXISTS (SELECT 1 FROM ' + self.quotedTable() + ' WHERE sid = $4)';

        self.query(query, [sess, expireTime, sid, sid], function (err) {
          if (fn) { fn.apply(this, err); }
        });
      } else {
        if (fn) { fn.apply(this, err); }
      }
    });
  };

  /**
   * Destroy the session associated with the given `sid`.
   *
   * @param {String} sid – the session id
   * @access public
   */

  PGStore.prototype.destroy = function (sid, fn) {
    this.query('DELETE FROM ' + this.quotedTable() + ' WHERE sid = $1', [sid], function (err) {
      if (fn) { fn(err); }
    });
  };

  /**
   * Touch the given session object associated with the given session ID.
   *
   * @param {String} sid – the session id
   * @param {Object} sess – the session object to store
   * @param {Function} fn – a standard Node.js callback returning the parsed session object
   * @access public
   */

  PGStore.prototype.touch = function (sid, sess, fn) {
    var expireTime = this.getExpireTime(sess.cookie.maxAge);

    this.query(
      'UPDATE ' + this.quotedTable() + ' SET expire = to_timestamp($1) WHERE sid = $2 RETURNING sid',
      [expireTime, sid],
      function (err) { fn(err); }
    );
  };

  return PGStore;
};
<commit_msg>Bug fix: Properly handle two param query() call<commit_after>/*jslint node: true */

'use strict';

var util = require('util');
var oneDay = 86400;

module.exports = function (session) {

  var Store = session.Store || session.session.Store,
    PGStore;

  PGStore = function (options) {
    options = options || {};
    Store.call(this, options);

    this.schemaName = options.schemaName || null;
    this.tableName = options.tableName || 'session';

    this.conString = options.conString || process.env.DATABASE_URL;
    this.ttl =  options.ttl;
    this.pg = options.pg || require('pg');
    this.ownsPg = !options.pg;

    this.errorLog = options.errorLog || console.error.bind(console);

    if (options.pruneSessionInterval === false) {
      this.pruneSessionInterval = false;
    } else {
      this.pruneSessionInterval = (options.pruneSessionInterval || 60) * 1000;
      setImmediate(function () {
        this.pruneSessions();
      }.bind(this));
    }
  };

  /**
   * Inherit from `Store`.
   */

  util.inherits(PGStore, Store);

  /**
   * Closes the session store
   *
   * Currently only stops the automatic pruning, if any, from continuing
   *
   * @access public
   */

  PGStore.prototype.close = function () {
    this.closed = true;

    if (this.pruneTimer) {
      clearTimeout(this.pruneTimer);
      this.pruneTimer = undefined;
    }

    if (this.ownsPg) {
      this.pg.end();
    }
  };

  /**
   * Does garbage collection for expired session in the database
   *
   * @param {Function} [fn] - standard Node.js callback called on completion
   * @access public
   */

  PGStore.prototype.pruneSessions = function (fn) {
    this.query('DELETE FROM ' + this.quotedTable() + ' WHERE expire < NOW()', function (err) {
      if (fn && typeof fn === 'function') {
        return fn(err);
      }

      if (err) {
        this.errorLog('Failed to prune sessions:', err.message);
      }

      if (this.pruneSessionInterval && !this.closed) {
        if (this.pruneTimer) {
          clearTimeout(this.pruneTimer);
        }
        this.pruneTimer = setTimeout(this.pruneSessions.bind(this, true), this.pruneSessionInterval);
      }
    }.bind(this));
  };

  /**
   * Get the quoted table.
   *
   * @return {String} the quoted schema + table for use in queries
   * @access private
   */

  PGStore.prototype.quotedTable = function () {
    var result = '"' + this.tableName + '"';

    if (this.schemaName) {
      result = '"' + this.schemaName + '".' + result;
    }

    return result;
  };

  /**
   * Figure out when a session should expire
   *
   * @param {Number} [maxAge] - the maximum age of the session cookie
   * @return {Number} the unix timestamp, in seconds
   * @access private
   */

  PGStore.prototype.getExpireTime = function (maxAge) {
    var ttl = this.ttl;

    ttl = ttl || (typeof maxAge === 'number' ? maxAge / 1000 : oneDay);
    ttl = Math.ceil(ttl + Date.now() / 1000);

    return ttl;
  };

  /**
   * Query the database.
   *
   * @param {String} query - the database query to perform
   * @param {(Array|Function)} [params] - the parameters of the query or the callback function
   * @param {Function} [fn] - standard Node.js callback returning the resulting rows
   * @access private
   */

  PGStore.prototype.query = function (query, params, fn) {
    if (!fn && typeof params === 'function') {
      fn = params;
      params = [];
    }
    this.pg.connect(this.conString, function (err, client, done) {
      if (err) {
        done(client);
        if (fn) { fn(err); }
      } else {
        client.query(query, params || [], function (err, result) {
          done(err || false);
          if (fn) { fn(err, result && result.rows[0] ? result.rows[0] : false); }
        });
      }
    });
  };

  /**
   * Attempt to fetch session by the given `sid`.
   *
   * @param {String} sid – the session id
   * @param {Function} fn – a standard Node.js callback returning the parsed session object
   * @access public
   */

  PGStore.prototype.get = function (sid, fn) {
    this.query('SELECT sess FROM ' + this.quotedTable() + ' WHERE sid = $1 AND expire >= NOW()', [sid], function (err, data) {
      if (err) { return fn(err); }
      if (!data) { return fn(); }
      try {
        return fn(null, ('string' === typeof data.sess) ? JSON.parse(data.sess) : data.sess);
      } catch (e) {
        return this.destroy(sid, fn);
      }
    }.bind(this));
  };

  /**
   * Commit the given `sess` object associated with the given `sid`.
   *
   * @param {String} sid – the session id
   * @param {Object} sess – the session object to store
   * @param {Function} fn – a standard Node.js callback returning the parsed session object
   * @access public
   */

  PGStore.prototype.set = function (sid, sess, fn) {
    var self = this;
    var expireTime = this.getExpireTime(sess.cookie.maxAge);
    var query = 'UPDATE ' + this.quotedTable() + ' SET sess = $1, expire = to_timestamp($2) WHERE sid = $3 RETURNING sid';

    this.query(query, [sess, expireTime, sid], function (err, data) {
      if (!err && data === false) {
        query = 'INSERT INTO ' + self.quotedTable() + ' (sess, expire, sid) SELECT $1, to_timestamp($2), $3 WHERE NOT EXISTS (SELECT 1 FROM ' + self.quotedTable() + ' WHERE sid = $4)';

        self.query(query, [sess, expireTime, sid, sid], function (err) {
          if (fn) { fn.apply(this, err); }
        });
      } else {
        if (fn) { fn.apply(this, err); }
      }
    });
  };

  /**
   * Destroy the session associated with the given `sid`.
   *
   * @param {String} sid – the session id
   * @access public
   */

  PGStore.prototype.destroy = function (sid, fn) {
    this.query('DELETE FROM ' + this.quotedTable() + ' WHERE sid = $1', [sid], function (err) {
      if (fn) { fn(err); }
    });
  };

  /**
   * Touch the given session object associated with the given session ID.
   *
   * @param {String} sid – the session id
   * @param {Object} sess – the session object to store
   * @param {Function} fn – a standard Node.js callback returning the parsed session object
   * @access public
   */

  PGStore.prototype.touch = function (sid, sess, fn) {
    var expireTime = this.getExpireTime(sess.cookie.maxAge);

    this.query(
      'UPDATE ' + this.quotedTable() + ' SET expire = to_timestamp($1) WHERE sid = $2 RETURNING sid',
      [expireTime, sid],
      function (err) { fn(err); }
    );
  };

  return PGStore;
};
<|endoftext|>


<commit_before>// Load in our dependencies
var utils = require('./utils');

// TODO: Handle updating parameters via a `.set` method which emits to `org.freedesktop...PropertiesChanged`
//   We don't plan on supporting a dynamically changing `Raise`/`Quit` as that fucks with the logic a lot...
//   Maybe we could do something like a diff but I think it's overkill

// Define our constructor
function PlayerInterface(params) {
  // http://specifications.freedesktop.org/mpris-spec/latest/Media_Player.html
  // Define our info and interface
  var playerParams = params.Player;
  this.info = {
    // Methods
    Next: playerParams.Next || utils.noop,
    Previous: playerParams.Previous || utils.noop,
    Pause: playerParams.Pause || utils.noop,
    PlayPause: playerParams.PlayPause || utils.noop,
    Stop: playerParams.Stop || utils.noop,
    Play: playerParams.Play || utils.noop,
    Seek: playerParams.Seek || utils.noop,
    SetPosition: playerParams.SetPosition || utils.noop,
    OpenUri: playerParams.OpenUri || utils.noop,

    // TODO: Handle signals
    // Properties
    // TODO: Handle properties
    // TODO: Document enum
    PlaybackStatus: 'Playing', // Playback_Status, Read only
    // TODO: Document enum
    LoopStatus: 'None', // Loop_Status, Read/Write (optional)
    // TODO: Document allowance for rate varying
    Rate: 1.0, // Playback_Rate, Read/Write
    // TODO: Document shuffle
    Shuffle: true, // Read/Write (optional)
    // TODO: Document metadata
    Metadata: {'mpris:length': 2000}, // Metadata_Map, Read only
    // TODO: Need to make sure >= 0 on set
    Volume: 10.0, // Volume, Read/Write
    // TODO: Figure out `position`
    Position: 1000, // Time_In_Us, Read only
    MinimumRate: 1.0, // Playback_Rate, Read only
    MaximumRate: 1.0, // Playback_Rate, Read only
    CanGoNext: true, // Read only
    CanGoPrevious: true, // Read only
    CanPlay: true, // Read only
    CanPause: true, // Read only
    CanSeek: true, // Read only
    CanControl: true // Read only
  };
  this.interface = {
    name: 'org.mpris.MediaPlayer2.Player',
    methods: {
      Next: [],
      Previous: [],
      Pause: [],
      PlayPause: [],
      Stop: [],
      Play: [],
      // jscs:disable disallowSpacesInsideArrayBrackets
      Seek: ['x' /* Offset */],
      SetPosition: ['o' /* TrackId */, 'x' /* Position */],
      OpenUri: ['s' /* Uri */]
      // jscs:enable disallowSpacesInsideArrayBrackets
    },
    // TODO: Handle signals
    // TODO: Handle properties
    properties: {
      PlaybackStatus: 's',
      LoopStatus: 's',
      Rate: 'd',
      Shuffle: 'b',
      // Aaaand metadata is fucked. Yep, fuck this...
      // Metadata: 'a{sv}',
      Volume: 'd',
      Position: 'x',
      MinimumRate: 'd',
      MaximumRate: 'd',
      CanGoNext: 'b',
      CanGoPrevious: 'b',
      CanPlay: 'b',
      CanPause: 'b',
      CanSeek: 'b',
      CanControl: 'b'
    }
  };
}
PlayerInterface.exportInterface = function (dbus, params) {
  // Generate a new PlayerInterface, attach it to dbus, and return the interface
  var playerInterface = new PlayerInterface(params);
  playerInterface.exportInterface(dbus);
  return playerInterface;
};
PlayerInterface.prototype = {
  exportInterface: function (dbus) {
    // https://github.com/sidorares/node-dbus/blob/v0.2.0/lib/bus.js#L195
    dbus.exportInterface(this.info, '/org/mpris/MediaPlayer2', this.interface);
  }
};

// Export our constructor
module.exports = PlayerInterface;
<commit_msg>Looks like we had our struct wrong<commit_after>// Load in our dependencies
var utils = require('./utils');

// TODO: Handle updating parameters via a `.set` method which emits to `org.freedesktop...PropertiesChanged`
//   We don't plan on supporting a dynamically changing `Raise`/`Quit` as that fucks with the logic a lot...
//   Maybe we could do something like a diff but I think it's overkill

// Define our constructor
function PlayerInterface(params) {
  // http://specifications.freedesktop.org/mpris-spec/latest/Media_Player.html
  // Define our info and interface
  var playerParams = params.Player;
  this.info = {
    // Methods
    Next: playerParams.Next || utils.noop,
    Previous: playerParams.Previous || utils.noop,
    Pause: playerParams.Pause || utils.noop,
    PlayPause: playerParams.PlayPause || utils.noop,
    Stop: playerParams.Stop || utils.noop,
    Play: playerParams.Play || utils.noop,
    Seek: playerParams.Seek || utils.noop,
    SetPosition: playerParams.SetPosition || utils.noop,
    OpenUri: playerParams.OpenUri || utils.noop,

    // TODO: Handle signals
    // Properties
    // TODO: Handle properties
    // TODO: Document enum
    PlaybackStatus: 'Playing', // Playback_Status, Read only
    // TODO: Document enum
    LoopStatus: 'None', // Loop_Status, Read/Write (optional)
    // TODO: Document allowance for rate varying
    Rate: 1.0, // Playback_Rate, Read/Write
    // TODO: Document shuffle
    Shuffle: true, // Read/Write (optional)
    // TODO: Document metadata
    Metadata: [{'mpris:length': 2000}], // Metadata_Map, Read only
    // TODO: Need to make sure >= 0 on set
    Volume: 10.0, // Volume, Read/Write
    // TODO: Figure out `position`
    Position: 1000, // Time_In_Us, Read only
    MinimumRate: 1.0, // Playback_Rate, Read only
    MaximumRate: 1.0, // Playback_Rate, Read only
    CanGoNext: true, // Read only
    CanGoPrevious: true, // Read only
    CanPlay: true, // Read only
    CanPause: true, // Read only
    CanSeek: true, // Read only
    CanControl: true // Read only
  };
  this.interface = {
    name: 'org.mpris.MediaPlayer2.Player',
    methods: {
      Next: [],
      Previous: [],
      Pause: [],
      PlayPause: [],
      Stop: [],
      Play: [],
      // jscs:disable disallowSpacesInsideArrayBrackets
      Seek: ['x' /* Offset */],
      SetPosition: ['o' /* TrackId */, 'x' /* Position */],
      OpenUri: ['s' /* Uri */]
      // jscs:enable disallowSpacesInsideArrayBrackets
    },
    // TODO: Handle signals
    // TODO: Handle properties
    properties: {
      PlaybackStatus: 's',
      LoopStatus: 's',
      Rate: 'd',
      Shuffle: 'b',
      Metadata: 'a{sv}',
      Volume: 'd',
      Position: 'x',
      MinimumRate: 'd',
      MaximumRate: 'd',
      CanGoNext: 'b',
      CanGoPrevious: 'b',
      CanPlay: 'b',
      CanPause: 'b',
      CanSeek: 'b',
      CanControl: 'b'
    }
  };
}
PlayerInterface.exportInterface = function (dbus, params) {
  // Generate a new PlayerInterface, attach it to dbus, and return the interface
  var playerInterface = new PlayerInterface(params);
  playerInterface.exportInterface(dbus);
  return playerInterface;
};
PlayerInterface.prototype = {
  exportInterface: function (dbus) {
    // https://github.com/sidorares/node-dbus/blob/v0.2.0/lib/bus.js#L195
    dbus.exportInterface(this.info, '/org/mpris/MediaPlayer2', this.interface);
  }
};

// Export our constructor
module.exports = PlayerInterface;
<|endoftext|>


<commit_before>// INITIALIZE AND CENTER MAP
function initMap() {
  var map = new google.maps.Map(document.getElementById('map'), {
    zoom: 4,
    center: {lat: 63.986807, lng: -22.627967},
    //mapTypeId: google.maps.MapTypeId.HYBRID,
    styles: [
            {elementType: 'geometry', stylers: [{color: '#242f3e'}]},
            {elementType: 'labels.text.stroke', stylers: [{color: '#242f3e'}]},
            {elementType: 'labels.text.fill', stylers: [{color: '#746855'}]},
            {
              featureType: 'administrative.locality',
              elementType: 'labels.text.fill',
              stylers: [{color: '#d59563'}]
            },
            {
              featureType: 'poi',
              elementType: 'labels.text.fill',
              stylers: [{color: '#d59563'}]
            },
            {
              featureType: 'poi.park',
              elementType: 'geometry',
              stylers: [{color: '#263c3f'}]
            },
            {
              featureType: 'poi.park',
              elementType: 'labels.text.fill',
              stylers: [{color: '#6b9a76'}]
            },
            {
              featureType: 'road',
              elementType: 'geometry',
              stylers: [{color: '#38414e'}]
            },
            {
              featureType: 'road',
              elementType: 'geometry.stroke',
              stylers: [{color: '#212a37'}]
            },
            {
              featureType: 'road',
              elementType: 'labels.text.fill',
              stylers: [{color: '#9ca5b3'}]
            },
            {
              featureType: 'road.highway',
              elementType: 'geometry',
              stylers: [{color: '#746855'}]
            },
            {
              featureType: 'road.highway',
              elementType: 'geometry.stroke',
              stylers: [{color: '#1f2835'}]
            },
            {
              featureType: 'road.highway',
              elementType: 'labels.text.fill',
              stylers: [{color: '#f3d19c'}]
            },
            {
              featureType: 'transit',
              elementType: 'geometry',
              stylers: [{color: '#2f3948'}]
            },
            {
              featureType: 'transit.station',
              elementType: 'labels.text.fill',
              stylers: [{color: '#d59563'}]
            },
            {
              featureType: 'water',
              elementType: 'geometry',
              stylers: [{color: '#17263c'}]
            },
            {
              featureType: 'water',
              elementType: 'labels.text.fill',
              stylers: [{color: '#515c6d'}]
            },
            {
              featureType: 'water',
              elementType: 'labels.text.stroke',
              stylers: [{color: '#17263c'}]
            }
          ]
  });

  var geocoder = new google.maps.Geocoder();

  // Table click event handler
  $(document).on("click", "#flight-data tr", function(e) {
    geocodeAddress(this.id, geocoder, map);
  });
}

// Get the address location for the airport and mark it on the map
function geocodeAddress(destination, geocoder, resultsMap) {
  var address = destination;
  var localAirport = {lat: 63.986807, lng: -22.627967};

  resultsMap.setCenter(localAirport);

  var markerLocalAirport = new google.maps.Marker({
    map: resultsMap,
    position: localAirport
  });

// Convert Kelvin to Celsius
function toCelsius(kelvin) {
	var celsius = kelvin - 273.15;

	return celsius;
}

// GEOCODE Location of table-listed city, get weather report and mark it on the map with an info window
  geocoder.geocode({'address': address}, function(results, status) {
    if (status === 'OK') {
      var destinationAirport = results[0].geometry.location;

      // Get weather by city
        $.ajax({
          'url': 'http://api.openweathermap.org/data/2.5/weather?q=' + address + '&APPID=fc1985651a1e35c2012d94faa3c8f43e',
          'type': 'GET',
          'dataType': 'json',
          success: function(response) {
            var celsius = toCelsius(response.main.temp);
            var wind = response.wind.speed;

            console.log(address + ', Temperature: ' + celsius + ' °C, Wind Speed: ' + wind + ' km/h');
            /*alert(	address + '\nTemperature: ' + celsius +
            		' °C \nWind Speed: ' + wind + ' km/h');*/
          }
        });

      var contentString = address;

      var infowindow = new google.maps.InfoWindow({
        content: contentString
      });

      var markerDestinationAirport = new google.maps.Marker({
        map: resultsMap,
        position: destinationAirport,
        title: address
      });

      markerDestinationAirport.addListener('click', function() {
        infowindow.open(resultsMap, markerDestinationAirport);
      });

      var flightPlanCoordinates = [
        localAirport,
        destinationAirport
      ];
      var flightPath = new google.maps.Polyline({
        path: flightPlanCoordinates,
        geodesic: true,
        strokeColor: 'white',
        strokeOpacity: 1.0,
        strokeWeight: 1
      });

      flightPath.setMap(resultsMap);

    } else {
      alert('Geocode was not successful for the following reason: ' + status);
    }
  });
}

// POPULATE FLIGHT TABLE

$.ajax({
  'url': 'http://apis.is/flight',
  'type': 'GET',
  'dataType': 'json',
  'data': {'language': 'en', 'type': 'departures'},
  success: function(response) {
    console.log(response);
    SetTable(response);
  }
});

function SetTable(data) {
  var d = data.results;

  for (var i = 0; i < d.length; i++) {
  $(  '
' +
      '' + d[i].to + '	' +
      '' + d[i].airline + '	' +
      '' + d[i].date + '	' +
      '' + d[i].flightNumber + '	' +
      '' + d[i].plannedArrival + '	' +
      '' + d[i].realArrival + '	' +
      '
'
    ).insertAfter('#table-data');
  }
}<commit_msg>Commented<commit_after>// INITIALIZE AND CENTER MAP
function initMap() {
  var map = new google.maps.Map(document.getElementById('map'), {
    zoom: 4,
    center: {lat: 63.986807, lng: -22.627967},
    //mapTypeId: google.maps.MapTypeId.HYBRID,
    styles: [
            {elementType: 'geometry', stylers: [{color: '#242f3e'}]},
            {elementType: 'labels.text.stroke', stylers: [{color: '#242f3e'}]},
            {elementType: 'labels.text.fill', stylers: [{color: '#746855'}]},
            {
              featureType: 'administrative.locality',
              elementType: 'labels.text.fill',
              stylers: [{color: '#d59563'}]
            },
            {
              featureType: 'poi',
              elementType: 'labels.text.fill',
              stylers: [{color: '#d59563'}]
            },
            {
              featureType: 'poi.park',
              elementType: 'geometry',
              stylers: [{color: '#263c3f'}]
            },
            {
              featureType: 'poi.park',
              elementType: 'labels.text.fill',
              stylers: [{color: '#6b9a76'}]
            },
            {
              featureType: 'road',
              elementType: 'geometry',
              stylers: [{color: '#38414e'}]
            },
            {
              featureType: 'road',
              elementType: 'geometry.stroke',
              stylers: [{color: '#212a37'}]
            },
            {
              featureType: 'road',
              elementType: 'labels.text.fill',
              stylers: [{color: '#9ca5b3'}]
            },
            {
              featureType: 'road.highway',
              elementType: 'geometry',
              stylers: [{color: '#746855'}]
            },
            {
              featureType: 'road.highway',
              elementType: 'geometry.stroke',
              stylers: [{color: '#1f2835'}]
            },
            {
              featureType: 'road.highway',
              elementType: 'labels.text.fill',
              stylers: [{color: '#f3d19c'}]
            },
            {
              featureType: 'transit',
              elementType: 'geometry',
              stylers: [{color: '#2f3948'}]
            },
            {
              featureType: 'transit.station',
              elementType: 'labels.text.fill',
              stylers: [{color: '#d59563'}]
            },
            {
              featureType: 'water',
              elementType: 'geometry',
              stylers: [{color: '#17263c'}]
            },
            {
              featureType: 'water',
              elementType: 'labels.text.fill',
              stylers: [{color: '#515c6d'}]
            },
            {
              featureType: 'water',
              elementType: 'labels.text.stroke',
              stylers: [{color: '#17263c'}]
            }
          ]
  });

  var geocoder = new google.maps.Geocoder();

  // Table click event handler
  $(document).on("click", "#flight-data tr", function(e) {
    geocodeAddress(this.id, geocoder, map);
  });
}

// Get the address location for the airport and mark it on the map
function geocodeAddress(destination, geocoder, resultsMap) {
  var address = destination;
  var localAirport = {lat: 63.986807, lng: -22.627967};

  resultsMap.setCenter(localAirport);

  var markerLocalAirport = new google.maps.Marker({
    map: resultsMap,
    position: localAirport
  });

// Convert Kelvin to Celsius
function toCelsius(kelvin) {
	var celsius = kelvin - 273.15;

	return celsius;
}

// GEOCODE Location of table-listed city, get weather report and mark it on the map with an info window
  geocoder.geocode({'address': address}, function(results, status) {
    if (status === 'OK') {
      var destinationAirport = results[0].geometry.location;

      // Get weather by city
        $.ajax({
          'url': 'http://api.openweathermap.org/data/2.5/weather?q=' + address + '&APPID=fc1985651a1e35c2012d94faa3c8f43e',
          'type': 'GET',
          'dataType': 'json',
          success: function(response) {
            var celsius = toCelsius(response.main.temp);
            var wind = response.wind.speed;

            console.log(address + ', Temperature: ' + celsius + ' °C, Wind Speed: ' + wind + ' km/h');
            /*alert(	address + '\nTemperature: ' + celsius +
            		' °C \nWind Speed: ' + wind + ' km/h');*/
          }
        });

      // Content of InfoWindow
      var contentString = address;

      // Create InfoWindow
      var infowindow = new google.maps.InfoWindow({
        content: contentString
      });

      // Marker for destination
      var markerDestinationAirport = new google.maps.Marker({
        map: resultsMap,
        position: destinationAirport,
        title: address
      });

      // Click event listener
      markerDestinationAirport.addListener('click', function() {
        infowindow.open(resultsMap, markerDestinationAirport);
      });

      // Flight Path Coordinates Curve
      var flightPlanCoordinates = [
        localAirport,
        destinationAirport
      ];

      // Draw Fight Path On Map
      var flightPath = new google.maps.Polyline({
        path: flightPlanCoordinates,
        geodesic: true,
        strokeColor: 'white',
        strokeOpacity: 1.0,
        strokeWeight: 1
      });

      flightPath.setMap(resultsMap);

    } else {
      alert('Geocode was not successful for the following reason: ' + status);
    }
  });
}

// POPULATE FLIGHT TABLE

$.ajax({
  'url': 'http://apis.is/flight',
  'type': 'GET',
  'dataType': 'json',
  'data': {'language': 'en', 'type': 'departures'},
  success: function(response) {
    console.log(response);
    SetTable(response);
  }
});

function SetTable(data) {
  var d = data.results;

  for (var i = 0; i < d.length; i++) {
  $(  '
' +
      '' + d[i].to + '	' +
      '' + d[i].airline + '	' +
      '' + d[i].date + '	' +
      '' + d[i].flightNumber + '	' +
      '' + d[i].plannedArrival + '	' +
      '' + d[i].realArrival + '	' +
      '
'
    ).insertAfter('#table-data');
  }
}<|endoftext|>


<commit_before>/*jslint indent: 2, nomen: true, maxlen: 100, white: true  plusplus: true, browser: true*/
/*global describe, beforeEach, afterEach, it, spyOn, expect*/
/*global $*/

(function() {
  "use strict";

  describe("The notification view", function() {

    var view, div, fakeNotification, dummyCollection, jQueryDummy;

    beforeEach(function() {
      div = document.createElement("div");
      div.id = "navigationBar";
      document.body.appendChild(div);

      dummyCollection = new window.NotificationCollection();

      fakeNotification = {
        title: "Hallo",
        date: 1398239658,
        content: "",
        priority: "",
        tags: "",
        seen: false
      };

      view = new window.NotificationView({
        collection: dummyCollection
      });

      view.render();
    });

    afterEach(function() {
      document.body.removeChild(div);
    });

    it("assert basics", function () {
      expect(view.events).toEqual({
        "click .navlogo #stat_hd" : "toggleNotification",
        "click .notificationItem .fa" : "removeNotification",
        "click #removeAllNotifications" : "removeAllNotifications"
      });
    });

    it("toggleNotification should run function", function () {
      jQueryDummy = {
        toggle: function () {
        }
      };
      spyOn(jQueryDummy, "toggle");
      spyOn(window, "$").andReturn(
        jQueryDummy
      );
      view.toggleNotification();
      expect(jQueryDummy.toggle).not.toHaveBeenCalled();
    });

    it("toggleNotification should run function", function () {
      view.collection.add(fakeNotification);
      jQueryDummy = {
        toggle: function () {
        }
      };
      spyOn(jQueryDummy, "toggle");
      spyOn(window, "$").andReturn(
        jQueryDummy
      );
      view.toggleNotification();
      expect(jQueryDummy.toggle).toHaveBeenCalled();
    });

  });

}());
<commit_msg>updated notification vierw spec<commit_after>/*jslint indent: 2, nomen: true, maxlen: 100, white: true  plusplus: true, browser: true*/
/*global describe, beforeEach, afterEach, it, spyOn, expect*/
/*global $*/

(function() {
  "use strict";

  describe("The notification view", function() {

    var view, div, fakeNotification, dummyCollection, jQueryDummy;

    beforeEach(function() {
      div = document.createElement("div");
      div.id = "navigationBar";
      document.body.appendChild(div);

      dummyCollection = new window.NotificationCollection();

      fakeNotification = {
        title: "Hallo",
        date: 1398239658,
        content: "",
        priority: "",
        tags: "",
        seen: false
      };

      view = new window.NotificationView({
        collection: dummyCollection
      });

      view.render();
    });

    afterEach(function() {
      document.body.removeChild(div);
    });

    it("assert basics", function () {
      expect(view.events).toEqual({
        "click .navlogo #stat_hd" : "toggleNotification",
        "click .notificationItem .fa" : "removeNotification",
        "click #removeAllNotifications" : "removeAllNotifications"
      });
    });

    it("toggleNotification should run function", function () {
      jQueryDummy = {
        toggle: function () {
        }
      };
      spyOn(jQueryDummy, "toggle");
      spyOn(window, "$").andReturn(
        jQueryDummy
      );
      view.toggleNotification();
      expect(jQueryDummy.toggle).not.toHaveBeenCalled();
    });

    it("toggleNotification should run function", function () {
      view.collection.add(fakeNotification);
      jQueryDummy = {
        toggle: function () {
        }
      };
      spyOn(jQueryDummy, "toggle");
      spyOn(window, "$").andReturn(
        jQueryDummy
      );
      view.toggleNotification();
      expect(jQueryDummy.toggle).toHaveBeenCalled();
    });

    it("toggleNotification should run function", function () {
      spyOn(view.collection, "reset");
      view.removeAllNotifications();
      expect(view.collection.reset).toHaveBeenCalled();
      expect($('#notification_menu').is(":visible")).toBeFalsy();
    });

  });

}());
<|endoftext|>


<commit_before>var argv = require('yargs').argv;
var Server = require('ws').Server;
var Realm = require('realm');

var daemon = require('./lib/daemon.js');
var realmSchema = require('./lib/realm-schema.js');
var realmApi = require('./lib/realm-api.js');

const mqkey = {
  consumerKey: ''
};

const pzgpsRealm = new Realm({
  schema: [realmSchema.Location, realmSchema.Climb]
});

const location = {
  current: {}
};

if (argv.mq) {
  try {
    mqkey.consumerKey = require('./lib/mqkey.js').consumerKey;
  } catch (err) {
    console.warn('Failed to import mqkey', err);
  }
}

var wss = new Server({
  port: (argv.port) ? argv.port : '9000'
});

const dmon = daemon.init({
  port: (argv.daemonPort) ? argv.daemonPort : 2947
});
dmon.start();
const listener = daemon.listen({});

// set up server listener
wss.on('connection', socket => {
  console.log('new websocket connection, (', wss.clients.length, ' total)');

  // send out the location data on an interval
  var intervalId = setInterval(function () {
    socket.send(JSON.stringify(location.current));
  }, 2000);

  socket.on('message', data => { // (data, flags)
    var parsedData = JSON.parse(data);
    // console.log('new message from client', parsedData);

    // there's room for more protocols here...
    if (parsedData.action === 'getConsumerKey' && mqkey.consumerKey) {
      socket.send(JSON.stringify(mqkey));
    }

    if (parsedData.action === 'setLocation') {
      var location = realmApi.set(pzgpsRealm, location.current);
      Object.assign(location, {
        realmData: true
      });
      socket.send(JSON.stringify(location));
    }
  });

  socket.on('close', () => {
    clearInterval(intervalId);
    console.log('websocket connection closed, (', wss.clients.length, ' remain)');
  });
});

// set up event listeners
listener.on('connected', () => console.log('listener is conected'));
listener.on('DEVICE', data => console.log('device', data));
listener.on('TPV', tpvData => {
  location.current = tpvData;
});

listener.connect();
listener.watch();
listener.device();
<commit_msg>more prototyping ideas, does not work, #12<commit_after>var argv = require('yargs').argv;
var Server = require('ws').Server;
var Realm = require('realm');

var daemon = require('./lib/daemon.js');
var realmSchema = require('./lib/realm-schema.js');
var realmApi = require('./lib/realm-api.js');

const mqkey = {
  consumerKey: ''
};

const pzgpsRealm = new Realm({
  schema: [realmSchema.Location, realmSchema.Climb]
});

const location = {
  current: {}
};

if (argv.mq) {
  try {
    mqkey.consumerKey = require('./lib/mqkey.js').consumerKey;
  } catch (err) {
    console.warn('Failed to import mqkey', err);
  }
}

var wss = new Server({
  port: (argv.port) ? argv.port : '9000'
});

const dmon = daemon.init({
  port: (argv.daemonPort) ? argv.daemonPort : 2947
});
dmon.start();
const listener = daemon.listen({});

// set up server listener
wss.on('connection', socket => {
  console.log('new websocket connection, (', wss.clients.length, ' total)');

  // send out the location data on an interval
  var intervalId = setInterval(function () {
    socket.send(JSON.stringify(location.current));
  }, 2000);

  socket.on('message', data => { // (data, flags)
    var parsedData = JSON.parse(data);
    // console.log('new message from client', parsedData);

    // there's room for more protocols here...
    if (parsedData.action === 'getConsumerKey' && mqkey.consumerKey) {
      socket.send(JSON.stringify(mqkey));
    }

    if (parsedData.action === 'newClimb') {
      var climb = Object.assign({}, {
        name: parsedData.name,
        pitches: parsedData.pitches,
        rating: parsedData.rating,
        location: location.current
      });

      let loc = realmApi.set(pzgpsRealm, climb);

      Object.assign(loc, {
        realmData: true
      });

      socket.send(JSON.stringify(loc));
    } // end setLocation
  });

  socket.on('close', () => {
    clearInterval(intervalId);
    console.log('websocket connection closed, (', wss.clients.length, ' remain)');
  });
});

// set up event listeners
listener.on('connected', () => console.log('listener is conected'));
listener.on('DEVICE', data => console.log('device', data));
listener.on('TPV', tpvData => {
  location.current = tpvData;
});

listener.connect();
listener.watch();
listener.device();
<|endoftext|>


<commit_before>var Address = require('ipaddr.js');

var isNumeric = function(n) { return !isNaN(parseFloat(n)) && isFinite(n); };

var ipMatch = function(clientIp, list) {
	if (clientIp && Address.isValid(clientIp)) {
		// `Address.process` return the IP instance in IPv4 or IPv6 form.
		// It will return IPv4 instance if it's a IPv4 mapped IPv6 address
		clientIp = Address.process(clientIp);

		return list.some(function(e) {
			// IPv6 address has 128 bits and IPv4 has 32 bits.
			// Setting the routing prefix to all bits in a CIDR address means only the specified address is allowed.
			e = e || '';
			e = e.indexOf('/') === -1 ? e + '/128' : e;

			var range = e.split('/');
			if (range.length === 2 && Address.isValid(range[0]) && isNumeric(range[1])) {
				var ip = Address.process(range[0]);
				var bit = parseInt(range[1], 10);

				// `IP.kind()` return `'ipv4'` or `'ipv6'`. Only same type can be `match`.
				if (clientIp.kind() === ip.kind()) {
					return clientIp.match(ip, bit);
				}
			}

			return false;
		});
	}

	return false;
};

function AccessControl(opts) {
	var _options = {
		// mode: `'deny'` or `'allow'`. See README.md or below.
		mode: 'deny',
		// denys: The blacklist. Works differently in different `mode`. See README.md or below.
		denys: [],
		// allows: The whitelist. Works differently in different `mode`. See README.md or below.
		allows: [],
		// forceConnectionAddress: Use the connection address (`req.connection.remoteAddress`) even `express.set('trust proxy', [])` set the `req.ip`.
		forceConnectionAddress: false,
		// log: Pass a log function or `false` to disable log.
		// `Function(String clientIp, Boolean access)`
		log: function(clientIp, access) {
			console.log(clientIp + (access ? ' accessed.' : ' denied.'));
		},

		// statusCode: The HTTP status code sent when denied. Set to 301 or 302 means redirect to `redirectTo`.
		statusCode: 401,
		// redirectTo: The URL to redirect when denied and `statusCode` is set to redirect.
		redirectTo: '',
		// message: The message sent when denied and `statusCode` is not set to redirect.
		message: 'Unauthorized'
	};

	// Override default options.
	opts = opts || {};
	for (var p in opts) if (opts.hasOwnProperty(p)) _options[p] = opts[p];
	_options.allowMode = _options.mode === 'allow';
	_options.statusCode = parseInt(_options.statusCode, 10);
	_options.forceConnectionAddress = !!_options.forceConnectionAddress;

	// The middleware.
	return function(req, res, next) {
		var clientIp = _options.forceConnectionAddress === true
			? req.connection.remoteAddress
			: req.ip || req.connection.remoteAddress;

		var inAllows = ipMatch(clientIp, _options.allows);
		var inDenys = ipMatch(clientIp, _options.denys);

		// If it is `'allow'` mode, and the IP *IS NOT* in the whitelist (`allows`) list (or excluded by blacklist (`denys`)), deny it.
		// If it is `'deny'` mode, and the IP *IS* in the blacklist (`denys`) list (and not excluded by whitelist (`allows`)), deny it.
		var isDenied = (_options.allowMode === true && (inAllows && !inDenys) === false) || (_options.allowMode === false && (inDenys && !inAllows) === true);

		if (typeof _options.log === 'function') {
			_options.log.apply(null, [req.ip || req.connection.remoteAddress, !isDenied]);
		}

		if (isDenied) {
			if (_options.statusCode === 301 || _options.statusCode === 302) {
				res.redirect(_options.statusCode, _options.redirectTo);
			} else {
				res.status(_options.statusCode).send(_options.message).end();
			}
		} else {
			next();
		}
	}
}

AccessControl.ipMatch = ipMatch;

module.exports = exports = AccessControl;<commit_msg>Remove res.end() because res.send calls it for you [Fix #1]<commit_after>var Address = require('ipaddr.js');

var isNumeric = function(n) { return !isNaN(parseFloat(n)) && isFinite(n); };

var ipMatch = function(clientIp, list) {
	if (clientIp && Address.isValid(clientIp)) {
		// `Address.process` return the IP instance in IPv4 or IPv6 form.
		// It will return IPv4 instance if it's a IPv4 mapped IPv6 address
		clientIp = Address.process(clientIp);

		return list.some(function(e) {
			// IPv6 address has 128 bits and IPv4 has 32 bits.
			// Setting the routing prefix to all bits in a CIDR address means only the specified address is allowed.
			e = e || '';
			e = e.indexOf('/') === -1 ? e + '/128' : e;

			var range = e.split('/');
			if (range.length === 2 && Address.isValid(range[0]) && isNumeric(range[1])) {
				var ip = Address.process(range[0]);
				var bit = parseInt(range[1], 10);

				// `IP.kind()` return `'ipv4'` or `'ipv6'`. Only same type can be `match`.
				if (clientIp.kind() === ip.kind()) {
					return clientIp.match(ip, bit);
				}
			}

			return false;
		});
	}

	return false;
};

function AccessControl(opts) {
	var _options = {
		// mode: `'deny'` or `'allow'`. See README.md or below.
		mode: 'deny',
		// denys: The blacklist. Works differently in different `mode`. See README.md or below.
		denys: [],
		// allows: The whitelist. Works differently in different `mode`. See README.md or below.
		allows: [],
		// forceConnectionAddress: Use the connection address (`req.connection.remoteAddress`) even `express.set('trust proxy', [])` set the `req.ip`.
		forceConnectionAddress: false,
		// log: Pass a log function or `false` to disable log.
		// `Function(String clientIp, Boolean access)`
		log: function(clientIp, access) {
			console.log(clientIp + (access ? ' accessed.' : ' denied.'));
		},

		// statusCode: The HTTP status code sent when denied. Set to 301 or 302 means redirect to `redirectTo`.
		statusCode: 401,
		// redirectTo: The URL to redirect when denied and `statusCode` is set to redirect.
		redirectTo: '',
		// message: The message sent when denied and `statusCode` is not set to redirect.
		message: 'Unauthorized'
	};

	// Override default options.
	opts = opts || {};
	for (var p in opts) if (opts.hasOwnProperty(p)) _options[p] = opts[p];
	_options.allowMode = _options.mode === 'allow';
	_options.statusCode = parseInt(_options.statusCode, 10);
	_options.forceConnectionAddress = !!_options.forceConnectionAddress;

	// The middleware.
	return function(req, res, next) {
		var clientIp = _options.forceConnectionAddress === true
			? req.connection.remoteAddress
			: req.ip || req.connection.remoteAddress;

		var inAllows = ipMatch(clientIp, _options.allows);
		var inDenys = ipMatch(clientIp, _options.denys);

		// If it is `'allow'` mode, and the IP *IS NOT* in the whitelist (`allows`) list (or excluded by blacklist (`denys`)), deny it.
		// If it is `'deny'` mode, and the IP *IS* in the blacklist (`denys`) list (and not excluded by whitelist (`allows`)), deny it.
		var isDenied = (_options.allowMode === true && (inAllows && !inDenys) === false) || (_options.allowMode === false && (inDenys && !inAllows) === true);

		if (typeof _options.log === 'function') {
			_options.log.apply(null, [req.ip || req.connection.remoteAddress, !isDenied]);
		}

		if (isDenied) {
			if (_options.statusCode === 301 || _options.statusCode === 302) {
				res.redirect(_options.statusCode, _options.redirectTo);
			} else {
				res.status(_options.statusCode).send(_options.message);
			}
		} else {
			next();
		}
	}
}

AccessControl.ipMatch = ipMatch;

module.exports = exports = AccessControl;<|endoftext|>


<commit_before>'use strict';

var psi = require('psi');
var getCss = require('get-css');
var Table = require('cli-table');
var cssStats = require('css-statistics');
var humanizeUrl = require('humanize-url');
var normalizeUrl = require('normalize-url');

module.exports = function scrutinize(url, options, callback) {
  if (typeof url != 'string') {
    throw new TypeError('scrutinize expects a url');
  }

  options = options || {};
  options.verbose = options.verbose || false;
  options.key = options.key || process.env.GAPPS_API_KEY;
  options.url = url;

  callback = callback || function() {};

  var scrutinyData = {};

  var normalizedUrl = normalizeUrl(url);
  var humanizedUrl = humanizeUrl(url);

  psi(url, options, function(err, data) {
    var table = new Table({
      head: [humanizedUrl, data.title],
      colWidths: [40, 120]
    });

    var ruleResults = data.formattedResults.ruleResults;
    var pageStats = data.pageStats;

    scrutinyData.psi = {};
    scrutinyData.psi.score = data.score;
    scrutinyData.psi.numberResources = pageStats.numberResources;
    scrutinyData.psi.numberHosts = pageStats.numberHosts;
    scrutinyData.psi.ruleResults = [];

    table.push(
      { 'Page Speed Score': data.score },
      { Requests: pageStats.numberResources + ' files from ' + pageStats.numberHosts + ' hosts' }
    );

    Object.keys(ruleResults).forEach(function(key) {
      var resultObject = ruleResults[key];
      var tableRow = {};
      var headers = [];
      var urls = [];

      resultObject.urlBlocks.forEach(function(urlBlock) {
        urls = [];

        (urlBlock.urls || []).forEach(function(url) {
          (url.result.args || []).forEach(function(urlArg) {
            if (urlArg.type === 'URL') {
              urls.push(urlArg.value);
            }
          });
        });
        var formattedString = formatString(urlBlock.header.format, urlBlock.header.args);

        if (urls.length) {
          formattedString = formattedString + '\n\n' + urls.join('\n');
        }

        scrutinyData.psi.ruleResults.push(formattedString);
        headers.push(formattedString);
      });

      tableRow[resultObject.localizedRuleName] = headers.join('\n');

      if (resultObject.ruleImpact > 0) {
        table.push(tableRow);
      }
    });

    if (options.verbose) {
      console.log('Page Speed Insights')
      console.log(table.toString());
    }

    callback(err, scrutinyData);
  });
}

function formatString(stringToFormat, headerArgs) {
  if (!headerArgs || headerArgs.length == 0) {
    return stringToFormat;
  }

  return stringToFormat.replace(/(\$[\d+])/g, function(match) {
    // Chop off the '$', account for 0-indexed array
    var argIndex = Number(match.split(/\$/)[1]) - 1;

    return typeof headerArgs[argIndex] != 'undefined' ? headerArgs[argIndex].value : match;
  });
}
<commit_msg>Add css stats table<commit_after>'use strict';

var psi = require('psi');
var getCss = require('get-css');
var Table = require('cli-table');
var cssStats = require('css-statistics');
var humanizeUrl = require('humanize-url');
var normalizeUrl = require('normalize-url');

module.exports = function scrutinize(url, options, callback) {
  if (typeof url != 'string') {
    throw new TypeError('scrutinize expects a url');
  }

  options = options || {};
  options.verbose = options.verbose || false;
  options.key = options.key || process.env.GAPPS_API_KEY;
  options.url = url;

  callback = callback || function() {};

  var scrutinyData = {};

  var normalizedUrl = normalizeUrl(url);
  var humanizedUrl = humanizeUrl(url);

  psi(url, options, function(err, data) {
    if (err) {
      console.log(err);
    }

    var table = new Table({
      head: [humanizedUrl, data.title],
      colWidths: [40, 120]
    });

    var ruleResults = data.formattedResults.ruleResults;
    var pageStats = data.pageStats;

    scrutinyData.psi = {};
    scrutinyData.psi.score = data.score;
    scrutinyData.psi.numberResources = pageStats.numberResources;
    scrutinyData.psi.numberHosts = pageStats.numberHosts;
    scrutinyData.psi.ruleResults = [];

    table.push(
      { 'Page Speed Score': data.score },
      { Requests: pageStats.numberResources + ' files from ' + pageStats.numberHosts + ' hosts' }
    );

    Object.keys(ruleResults).forEach(function(key) {
      var resultObject = ruleResults[key];
      var tableRow = {};
      var headers = [];
      var urls = [];

      resultObject.urlBlocks.forEach(function(urlBlock) {
        urls = [];

        (urlBlock.urls || []).forEach(function(url) {
          (url.result.args || []).forEach(function(urlArg) {
            if (urlArg.type === 'URL') {
              urls.push(urlArg.value);
            }
          });
        });
        var formattedString = formatString(urlBlock.header.format, urlBlock.header.args);

        if (urls.length) {
          formattedString = formattedString + '\n\n' + urls.join('\n');
        }

        scrutinyData.psi.ruleResults.push(formattedString);
        headers.push(formattedString);
      });

      tableRow[resultObject.localizedRuleName] = headers.join('\n');

      if (resultObject.ruleImpact > 0) {
        table.push(tableRow);
      }
    });

    if (options.verbose) {
      console.log('Page Speed Insights')
      console.log(table.toString());
    }

    getCss(normalizedUrl).then(function(css) {
      var stats = cssStats(css.css).aggregates;

      scrutinyData.css = {};
      scrutinyData.css.selectorCount = stats.selectors;
      scrutinyData.css.mediaQueriesCount = stats.mediaQueries.length;
      scrutinyData.css.colors = stats.colors.total;
      scrutinyData.css.widths = stats.widths.total;
      scrutinyData.css.fontSizes = stats.fontSizes.total;
      scrutinyData.css.backgroundColors = stats.backgroundColors.total;

      var table = new Table({
        head: [humanizedUrl, data.title],
        colWidths: [40, 120]
      });

      table.push(
        { 'Total Selectors': scrutinyData.css.selectorCount },
        { 'Media Queries': scrutinyData.css.mediaQueriesCount },
        { 'Colors': scrutinyData.css.colors },
        { 'Widths': scrutinyData.css.widths },
        { 'Font Sizes': scrutinyData.css.fontSizes },
        { 'Background Colors': scrutinyData.css.backgroundColors }
      );
      console.log('CSS Stats');
      console.log(table.toString());

      callback(err, scrutinyData);
    });
  });
}

function formatString(stringToFormat, headerArgs) {
  if (!headerArgs || headerArgs.length == 0) {
    return stringToFormat;
  }

  return stringToFormat.replace(/(\$[\d+])/g, function(match) {
    // Chop off the '$', account for 0-indexed array
    var argIndex = Number(match.split(/\$/)[1]) - 1;

    return typeof headerArgs[argIndex] != 'undefined' ? headerArgs[argIndex].value : match;
  });
}
<|endoftext|>


<commit_before>'use strict';

module.exports = {
	env: {
		es6: true,
	},
	extends: ['eslint:recommended', require.resolve('eslint-config-prettier')],
	parserOptions: {
		ecmaVersion: 2017,
		sourceType: 'module',
	},
	plugins: ['liferayportal', 'no-only-tests'],
	rules: {
		'liferayportal/arrowfunction-newline': 0,
		'no-console': 0,
		'no-constant-condition': 0,
		'no-empty': 0,
		'no-only-tests/no-only-tests': 'error',
		'no-unused-vars': [2, {args: 'after-used'}],
		'no-process-env': 0,
		'comma-spacing': 0,
		indent: ['error', 'tab'],
		'keyword-spacing': 1,
		'max-len': [
			2,
			{
				code: 80,
				comments: 120,
				ignoreRegExpLiterals: true,
				ignoreStrings: true,
				ignoreTemplateLiterals: true,
				ignoreUrls: true,
				tabWidth: 4,
			},
		],
		'no-tabs': 0,
		'arrow-parens': 0, // Setting for Prettier
	},
};
<commit_msg>Add no-unused-expressions rule to the default set (#19)<commit_after>'use strict';

module.exports = {
	env: {
		es6: true,
	},
	extends: ['eslint:recommended', require.resolve('eslint-config-prettier')],
	parserOptions: {
		ecmaVersion: 2017,
		sourceType: 'module',
	},
	plugins: ['liferayportal', 'no-only-tests'],
	rules: {
		'liferayportal/arrowfunction-newline': 0,
		'no-console': 0,
		'no-constant-condition': 0,
		'no-empty': 0,
		'no-only-tests/no-only-tests': 'error',
		'no-unused-expressions': 'error',
		'no-process-env': 0,
		'comma-spacing': 0,
		indent: ['error', 'tab'],
		'keyword-spacing': 1,
		'max-len': [
			2,
			{
				code: 80,
				comments: 120,
				ignoreRegExpLiterals: true,
				ignoreStrings: true,
				ignoreTemplateLiterals: true,
				ignoreUrls: true,
				tabWidth: 4,
			},
		],
		'no-tabs': 0,
		'arrow-parens': 0, // Setting for Prettier
	},
};
<|endoftext|>


<commit_before>'use strict';

var express = require('express');
var favicon = require('serve-favicon');
var path = require('path');

module.exports = function(app, baseDir, config) {
    var env = app.get('env');
    var servedDirectory = 'app';

    if ('development' === env) {
        // Disable caching of scripts for easier testing
        app.use(function noCache(req, res, next) {
            if (req.url.indexOf('/js/') === 0) {
                res.header('Cache-Control', 'no-cache, no-store, must-revalidate');
                res.header('Pragma', 'no-cache');
                res.header('Expires', 0);
            }
            next();
        });

        app.use(config.baseUrl, express.static(path.join(__dirname, '.tmp')));
    }

    if ('production' === env) {
        // prerender.io
        app.use(require('prerender-node').set('prerenderToken', process.env.PRERENDER_TOKEN).set('protocol', 'https'));

        servedDirectory = 'dist';
        app.use(favicon(path.join(__dirname, 'dist', 'favicon.ico')));
    }

    app.use(config.baseUrl, express.static(path.join(__dirname, servedDirectory)));
    app.use(config.baseUrl + '/scripts/template.js', express.static(path.join(baseDir, config.scenarioTemplate)));
    app.use(config.baseUrl + '/scripts/constants.js', express.static(path.join(baseDir, config.constants)));

    app.get(config.baseUrl + '/scripts/server-config.js', function (req, res) {
        res.type('application/javascript').send('window.serverConfig = ' + JSON.stringify(config.serverConfig || {}) + ';');
    });

    app.route(config.baseUrl + '/*').get(function(req, res) {
        res.sendfile(path.join(__dirname, servedDirectory, 'index.html'));
    });
};
<commit_msg>Updated deprecated Express call<commit_after>'use strict';

var express = require('express');
var favicon = require('serve-favicon');
var path = require('path');

module.exports = function(app, baseDir, config) {
    var env = app.get('env');
    var servedDirectory = 'app';

    if ('development' === env) {
        // Disable caching of scripts for easier testing
        app.use(function noCache(req, res, next) {
            if (req.url.indexOf('/js/') === 0) {
                res.header('Cache-Control', 'no-cache, no-store, must-revalidate');
                res.header('Pragma', 'no-cache');
                res.header('Expires', 0);
            }
            next();
        });

        app.use(config.baseUrl, express.static(path.join(__dirname, '.tmp')));
    }

    if ('production' === env) {
        // prerender.io
        app.use(require('prerender-node').set('prerenderToken', process.env.PRERENDER_TOKEN).set('protocol', 'https'));

        servedDirectory = 'dist';
        app.use(favicon(path.join(__dirname, 'dist', 'favicon.ico')));
    }

    app.use(config.baseUrl, express.static(path.join(__dirname, servedDirectory)));
    app.use(config.baseUrl + '/scripts/template.js', express.static(path.join(baseDir, config.scenarioTemplate)));
    app.use(config.baseUrl + '/scripts/constants.js', express.static(path.join(baseDir, config.constants)));

    app.get(config.baseUrl + '/scripts/server-config.js', function (req, res) {
        res.type('application/javascript').send('window.serverConfig = ' + JSON.stringify(config.serverConfig || {}) + ';');
    });

    app.route(config.baseUrl + '/*').get(function(req, res) {
        res.sendFile(path.join(__dirname, servedDirectory, 'index.html'));
    });
};
<|endoftext|>


<commit_before>var fs = require('fs');
var token = require(process.env.HOME + '/.dagsen-bot-token.js');

var request = require('request');
var Telegram = require('telegram-bot');
var tg = new Telegram(token);

tg.on('message', function(msg) {
  console.log('got msg: ' + msg.text);
  if (!msg.text) return;

  if (!msg.text.indexOf('/mat')) {
    console.log('retreiving menu...');
    request('http://api.teknolog.fi/taffa/sv/today', function(err, res, body) {
      tg.sendMessage({
        text: body,
        chat_id: msg.chat.id
      });
    });
  } else if (!msg.text.indexOf('/ute')) {
    console.log('retreiving weather...');
    request('http://outside.aalto.fi/data.txt', function(err, res, body) {
      outside = JSON.parse(body);
      message = 'Temperatur: ' + Number(outside['gent-outside-t']).toFixed(1).replace('.', ',') + ' \xB0C\n';
      message += 'Luftfuktighet: ' + Number(outside['gent-outside-h']).toFixed(0).replace('.', ',') + ' RH%\n';
      message += 'Lufttryck: ' + Number(outside['gent-outside-b']).toFixed(0).replace('.', ',') + ' hPa\n';
      message += 'Illuminans: '  + Number(outside['gent-outside-l']).toFixed(0).replace('.', ',') + ' lx\n';
      tg.sendMessage({
        text: message,
        chat_id: msg.chat.id
      });
    });
  } else if (!msg.text.indexOf('/fredag')) {
    tg.sendMessage({
      text: new Date().getDay() === 5 ? 'IT\'S FRIDAY!' : 'Nope.',
      chat_id: msg.chat.id
    });
  } else if (!msg.text.indexOf('/onsdag') || !msg.text.indexOf('/tulttan')) {
    tg.sendMessage({
      text: new Date().getDay() === 3 ? 'Ja, det är onsdag.' : 'Nope.',
      chat_id: msg.chat.id
    });
  } else if (!msg.text.indexOf('/music')) {
	var music_list = fs.readFile('./music.json', function(e, data) {
	  if (e) {
		console.log(e);
		return;
	  }
	  data = JSON.parse(data);
	  var r = Math.floor(Math.random() * data.length); // Choosing a random item from the URL list
	  var video_url = data[r];
	  tg.sendMessage({
	    text: video_url,
	    chat_id: msg.chat.id
	  });
	});
  }
});

tg.start();
<commit_msg>retab<commit_after>var fs = require('fs');
var token = require(process.env.HOME + '/.dagsen-bot-token.js');

var request = require('request');
var Telegram = require('telegram-bot');
var tg = new Telegram(token);

tg.on('message', function(msg) {
  console.log('got msg: ' + msg.text);
  if (!msg.text) return;

  if (!msg.text.indexOf('/mat')) {
    console.log('retreiving menu...');
    request('http://api.teknolog.fi/taffa/sv/today', function(err, res, body) {
      tg.sendMessage({
        text: body,
        chat_id: msg.chat.id
      });
    });
  } else if (!msg.text.indexOf('/ute')) {
    console.log('retreiving weather...');
    request('http://outside.aalto.fi/data.txt', function(err, res, body) {
      outside = JSON.parse(body);
      message = 'Temperatur: ' + Number(outside['gent-outside-t']).toFixed(1).replace('.', ',') + ' \xB0C\n';
      message += 'Luftfuktighet: ' + Number(outside['gent-outside-h']).toFixed(0).replace('.', ',') + ' RH%\n';
      message += 'Lufttryck: ' + Number(outside['gent-outside-b']).toFixed(0).replace('.', ',') + ' hPa\n';
      message += 'Illuminans: '  + Number(outside['gent-outside-l']).toFixed(0).replace('.', ',') + ' lx\n';
      tg.sendMessage({
        text: message,
        chat_id: msg.chat.id
      });
    });
  } else if (!msg.text.indexOf('/fredag')) {
    tg.sendMessage({
      text: new Date().getDay() === 5 ? 'IT\'S FRIDAY!' : 'Nope.',
      chat_id: msg.chat.id
    });
  } else if (!msg.text.indexOf('/onsdag') || !msg.text.indexOf('/tulttan')) {
    tg.sendMessage({
      text: new Date().getDay() === 3 ? 'Ja, det är onsdag.' : 'Nope.',
      chat_id: msg.chat.id
    });
  } else if (!msg.text.indexOf('/music')) {
    var music_list = fs.readFile('./music.json', function(e, data) {
      if (e) {
        console.log(e);
        return;
      }
      data = JSON.parse(data);
      var r = Math.floor(Math.random() * data.length); // Choosing a random item from the URL list
      var video_url = data[r];
      tg.sendMessage({
        text: video_url,
        chat_id: msg.chat.id
      });
    });
  }
});

tg.start();
<|endoftext|>


<commit_before>'use strict';

var fs = require('fs');
var path = require('path');
var os = require('os');
var exec = require('child_process').exec;
var File = require('vinyl');
var fs = require('fs-extra');
var uuid = require('uuid');
var format = require('string-format');
var temp = require('temp');

format.extend(String.prototype);

var clobber_dir_name = '.clobber';
var cmd_sr_build = 'java -jar "{0}" -build {1} -label {2} -outfile {3} -logdir {4}';
var cmd_sr_run = 'java -jar "{0}" -run {1} -jdbc {2} -user {3} -password {4} -logdir {5}';

exports.get_instance= function(config){
return function(changed_file, outcome) {
  var result;
  var runid = uuid.v1();

  var file = new File({
    cwd: process.cwd(),
    path: changed_file.path
  });
  file.name = file.path.replace(/^.*[\\\/]/, '');
  file.dirnamerelative = file.relative.replace(path.sep + file.name, '');
  temp.mkdir(clobber_dir_name, function(err, target_working_dir){
    if (err) throw err;
    var target_build_dir = path.join(target_working_dir, 'build');
    fs.mkdirsSync(path.join(target_build_dir, file.dirnamerelative));
    fs.copySync(file.relative, path.join(target_build_dir, file.relative));
    fs.copySync('ScriptRunner', path.join(target_build_dir, 'ScriptRunner'));
    fs.emptyDirSync(path.join(target_build_dir, 'ScriptRunner', 'Utils'));
    fs.rmdirSync(path.join(target_build_dir, 'ScriptRunner', 'Utils'));
    fs.emptyDirSync(path.join(target_build_dir, 'ScriptRunner', 'Jobs'));
    fs.rmdirSync(path.join(target_build_dir, 'ScriptRunner', 'Jobs'));
    var build_label = 'clobber-{0}-{1}'.format(os.hostname(), runid);
    var build_cmd = cmd_sr_build.format(
      config.scriptrunner.jarLocation,
      target_build_dir,
      build_label,
      path.join(target_working_dir, build_label + '.zip'),
      target_working_dir
    );
    var run_cmd = cmd_sr_run.format(
      config.scriptrunner.jarLocation,
      path.join(target_working_dir, build_label + '.zip'),
      config.scriptrunner.jdbc,
      config.scriptrunner.user,
      config.scriptrunner.password, target_working_dir
    );

    exec(build_cmd, function(err) {
      if (err) {
        outcome({
          "result":"error",
          "file_location":changed_file.path,
          "err":err
        });
      }
      exec(run_cmd, function(err) {
        if (err) {
          outcome({
            "result":"error",
            "file_location":changed_file.path,
            "err":err
          });
        }
        fs.emptyDirSync(target_working_dir);
        fs.rmdirSync(target_working_dir);
        outcome({
          "result":"success",
          "file_location":changed_file.path,
          "build_location":target_working_dir
        });
      });

    });
  });
};
};
<commit_msg>clobbing<commit_after>'use strict';

var fs = require('fs');
var path = require('path');
var os = require('os');
var exec = require('child_process').exec;
var File = require('vinyl');
var fs = require('fs-extra');
var uuid = require('uuid');
var format = require('string-format');
var temp = require('temp');

format.extend(String.prototype);

var clobber_dir_name = '.clobber';
var cmd_sr_build = 'java -jar "{0}" -build {1} -label {2} -outfile {3} -logdir {4}';
var cmd_sr_run = 'java -jar "{0}" -run {1} -jdbc {2} -user {3} -password {4} -logdir {5}';

exports.get_instance= function(config){
return function(changed_file_path, outcome) {
  var result;
  var runid = uuid.v1();
  console.log(changed_file_path);
  var fileRelativeDir = path.relative(config.scriptrunner.codeSourcePath,path.dirname(changed_file_path));

  temp.mkdir(clobber_dir_name, function(err, target_working_dir){
    if (err) throw err;
    var target_build_dir = path.join(target_working_dir, 'build');
    //make the directory to the changed file
    var target_build_file_path = path.join(target_build_dir, fileRelativeDir, path.basename(changed_file_path));

    fs.ensureFile(target_build_file_path, function(err){
      console.log(err);
      fs.copySync(changed_file_path, target_build_file_path);
    });

    fs.copySync(
      path.join(config.scriptrunner.codeSourcePath,'ScriptRunner'),
      path.join(target_build_dir, 'ScriptRunner')
    );

    fs.emptyDirSync(path.join(target_build_dir, 'ScriptRunner', 'Utils'));
    fs.rmdirSync(path.join(target_build_dir, 'ScriptRunner', 'Utils'));
    fs.emptyDirSync(path.join(target_build_dir, 'ScriptRunner', 'Jobs'));
    fs.rmdirSync(path.join(target_build_dir, 'ScriptRunner', 'Jobs'));
    var build_label = 'clobber-{0}-{1}'.format(os.hostname(), runid);
    var build_cmd = cmd_sr_build.format(
      config.scriptrunner.jarLocation,
      target_build_dir,
      build_label,
      path.join(target_working_dir, build_label + '.zip'),
      target_working_dir
    );
    var run_cmd = cmd_sr_run.format(
      config.scriptrunner.jarLocation,
      path.join(target_working_dir, build_label + '.zip'),
      config.scriptrunner.jdbc,
      config.scriptrunner.user,
      config.scriptrunner.password, target_working_dir
    );

    exec(build_cmd, function(err) {
      if (err) {
        outcome({
          "result":"error",
          "file_location":changed_file_path,
          "err":err
        });
      }
      exec(run_cmd, function(err) {
        if (err) {
          outcome({
            "result":"error",
            "file_location":changed_file_path,
            "err":err
          });
        }
        fs.emptyDirSync(target_working_dir);
        fs.rmdirSync(target_working_dir);
        outcome({
          "result":"success",
          "file_location":changed_file_path,
          "build_location":target_working_dir
        });
      });

    });
  });
};
};
<|endoftext|>


<commit_before>import fs from 'fs'
import path from 'path'
import isThere from 'is-there'
import jsonfile from 'jsonfile'
import R from 'ramda'
import {spawnSync} from 'child_process'
import chalk from 'chalk'

const red = chalk.red
const bad = chalk.red.bold

let dirList = []
let modules = {}
let gotErrs = 0

if (isThere('.npm-interlink')) {
  console.log('Configuration .npm-interlink found.')
  dirList = fs.readFileSync('.npm-interlink').toString().split('\n').filter(item => {
    return item !== ''
  })
} else {
  dirList = fs.readdirSync('.').filter(file => {
    return fs.statSync(file).isDirectory()
  })
}

function keys (something) {
  return R.keys(something) || []
}

function hasErr (spawned) {
  if (spawned.status !== 0 || spawned.error || spawned.stderr.toString()) {
    console.error(red(R.pick(['status', 'error'], spawned)))
    if (spawned.stderr) console.error(red(spawned.stderr.toString()))
    gotErrs++
    return true
  } else {
    return false
  }
}

for (let dir of dirList) {
  if (isThere(path.join(dir, 'package.json'))) {
    try {
      let pkg = jsonfile.readFileSync(path.join(dir, 'package.json'))
      modules[pkg.name] = {}
      modules[pkg.name].dir = dir
      modules[pkg.name].links = R.union(keys(pkg.dependencies), keys(pkg.devDependencies))
      console.log(`\$ cd ${dir} && npm link #${pkg.name}`)
      let res = spawnSync('npm', ['link'], {cwd: dir})
      if (!hasErr(res)) {
        console.log(`Linked ${pkg.name}.`)
      }
    } catch (e) {
      console.error(e)
      gotErrs++
    }
  } else {
    console.log(`Skipping ${dir} - package.json not found.`)
  }
}

for (let name in modules) {
  let names = R.keys(modules)
  modules[name].links = R.intersection(modules[name].links, names)
  console.log(`Linking ${name} modules: [${modules[name].links}]...`)
  for (let pkg of modules[name].links) {
    console.log(`\$ cd ${modules[name].dir} && npm link ${pkg}`)
    let res = spawnSync('npm', ['link', pkg], {cwd: modules[name].dir})
    if (hasErr(res)) {
      console.error(`Module ${name} failed to link ${pkg}.`)
    }
  }
}

/*
console.log('If no errors above, the following should be interlinked:')
for (let name in modules) {
  console.log(`${name}: [${modules[name].links}]`)
}
*/

if (gotErrs > 0) {
  console.error(bad(`Got ${gotErrs} error${gotErrs > 1 ? 's' : ''}.`))
  process.exit(1)
}
<commit_msg>use more of the red color and make it so that stdout is more clear about what failed of succeeded<commit_after>import fs from 'fs'
import path from 'path'
import isThere from 'is-there'
import jsonfile from 'jsonfile'
import R from 'ramda'
import {spawnSync} from 'child_process'
import chalk from 'chalk'

const red = chalk.red
const bad = chalk.red.bold

let dirList = []
let modules = {}
let gotErrs = 0

if (isThere('.npm-interlink')) {
  console.log('Configuration .npm-interlink found.')
  dirList = fs.readFileSync('.npm-interlink').toString().split('\n').filter(item => {
    return item !== ''
  })
} else {
  dirList = fs.readdirSync('.').filter(file => {
    return fs.statSync(file).isDirectory()
  })
}

function keys (something) {
  return R.keys(something) || []
}

function hasErr (spawned) {
  if (spawned.status !== 0 || spawned.error || spawned.stderr.toString()) {
    console.error(red(R.pick(['status', 'error'], spawned)))
    if (spawned.stderr) console.error(red(spawned.stderr.toString()))
    gotErrs++
    return true
  } else {
    return false
  }
}

for (let dir of dirList) {
  if (isThere(path.join(dir, 'package.json'))) {
    try {
      let pkg = jsonfile.readFileSync(path.join(dir, 'package.json'))
      modules[pkg.name] = {}
      modules[pkg.name].dir = dir
      modules[pkg.name].links = R.union(keys(pkg.dependencies), keys(pkg.devDependencies))
      console.log(`\$ cd ${dir} && npm link #${pkg.name}`)
      let res = spawnSync('npm', ['link'], {cwd: dir})
      if (!hasErr(res)) {
        console.log(`Linked ${pkg.name}.`)
      } else {
        console.log(bad(`Module ${pkg.name} failed to link itself.`))
      }
    } catch (e) {
      console.error(red(e))
      gotErrs++
    }
  } else {
    console.log(`Skipping ${dir} - package.json not found.`)
  }
}

for (let name in modules) {
  let names = R.keys(modules)
  modules[name].links = R.intersection(modules[name].links, names)
  console.log(`Linking ${name} modules: [${modules[name].links}]...`)
  for (let pkg of modules[name].links) {
    console.log(`\$ cd ${modules[name].dir} && npm link ${pkg}`)
    let res = spawnSync('npm', ['link', pkg], {cwd: modules[name].dir})
    if (hasErr(res)) {
      console.log(bad(`Module ${name} failed to link ${pkg}.`))
    }
  }
}

/*
console.log('If no errors above, the following should be interlinked:')
for (let name in modules) {
  console.log(`${name}: [${modules[name].links}]`)
}
*/

if (gotErrs > 0) {
  console.error(bad(`Got ${gotErrs} error${gotErrs > 1 ? 's' : ''}.`))
  process.exit(1)
}
<|endoftext|>


<commit_before>var _ = require('underscore');
var Backbone = require('backbone');
var QueryRowModel = require('./query-row-model');

var TYPES_POINT = 'point';
var TYPES_LINE = 'line';
var TYPES_POLYGON = 'polygon';

var GEOJSON_TO_FEATURE_TYPE = {
  Point: TYPES_POINT,
  MultiPoint: TYPES_POINT,
  LineString: TYPES_LINE,
  MultiLineString: TYPES_LINE,
  Polygon: TYPES_POLYGON,
  MultiPolygon: TYPES_POLYGON
};

var BLACKLISTED_COLUMNS = ['cartodb_id', 'created_at', 'the_geom_webmercator', 'updated_at'];

var FeatureDefinitionModel = Backbone.Model.extend({

  initialize: function (attrs, options) {
    if (!options.configModel) throw new Error('configModel is required');
    if (!options.layerDefinitionModel) throw new Error('layerDefinitionModel is required');

    this._configModel = options.configModel;
    this._layerDefinitionModel = options.layerDefinitionModel;
    this._featureType = options.featureType;
  },

  isNew: function () {
    return !this.has('cartodb_id');
  },

  isPoint: function () {
    return this._isType(TYPES_POINT);
  },

  isPolygon: function () {
    return this._isType(TYPES_POLYGON);
  },

  isLine: function () {
    return this._isType(TYPES_LINE);
  },

  _isType: function (type) {
    return this._getType() === type;
  },

  isEditable: function () {
    return !this._layerDefinitionModel.hasAnalyses() &&
      !this._layerDefinitionModel.hasCustomQueryApplied();
  },

  isEqual: function (featureDefinition) {
    return this.id === featureDefinition.id &&
      this.getLayerId() === featureDefinition.getLayerId();
  },

  getLayerId: function () {
    return this._layerDefinitionModel.id;
  },

  getFeatureType: function () {
    if (this.isPoint()) {
      return 'point';
    }
    if (this.isLine()) {
      return 'line';
    }
    if (this.isPolygon()) {
      return 'polygon';
    }
  },

  fetch: function (options) {
    options = options || {};
    this._getQueryRowModel().fetch({
      success: function (data) {
        this.set(data.toJSON());
        options.success && options.success();
      }.bind(this)
    });
  },

  save: function (options) {
    options = options || {};
    var columns = this._layerDefinitionModel.getColumnNamesFromSchema();
    var attrs = _.pick(this.toJSON(), _.difference(columns, BLACKLISTED_COLUMNS));

    this._getQueryRowModel().save(attrs, {
      success: function (mdl) {
        this.set(mdl.toJSON());
        this.trigger('save');
        options.success && options.success();
      }.bind(this),
      error: function () {
        options.error && options.error();
      }
    });
  },

  _getQueryRowModel: function () {
    this._queryRowModel = this._queryRowModel || new QueryRowModel({ cartodb_id: this.get('id') }, {
      tableName: this._layerDefinitionModel.getTableName(),
      configModel: this._configModel
    });

    return this._queryRowModel;
  },

  _getType: function () {
    var the_geom = this.get('the_geom');
    var type = the_geom && this._convertGeoJSONTypeToFeatureType(the_geom) || this._featureType;

    return type;
  },

  _convertGeoJSONTypeToFeatureType: function (the_geom) {
    var geoJSON = null;

    try {
      geoJSON = JSON.parse(the_geom);
    } catch (err) {
      // if the geom is not a valid json value
    }

    var geometryType = geoJSON && geoJSON.type;
    var featureType = GEOJSON_TO_FEATURE_TYPE[geometryType];
    if (!featureType) {
      throw new Error("unsupported geometry type: '" + geometryType + "'");
    }

    return featureType;
  }

});

module.exports = FeatureDefinitionModel;
<commit_msg>Extracted function<commit_after>var _ = require('underscore');
var Backbone = require('backbone');
var QueryRowModel = require('./query-row-model');

var TYPES_POINT = 'point';
var TYPES_LINE = 'line';
var TYPES_POLYGON = 'polygon';

var GEOJSON_TO_FEATURE_TYPE = {
  Point: TYPES_POINT,
  MultiPoint: TYPES_POINT,
  LineString: TYPES_LINE,
  MultiLineString: TYPES_LINE,
  Polygon: TYPES_POLYGON,
  MultiPolygon: TYPES_POLYGON
};

var convertGeoJSONTypeToFeatureType = function (the_geom) {
  var geoJSON = null;

  try {
    geoJSON = JSON.parse(the_geom);
  } catch (err) {
    // if the geom is not a valid json value
  }

  var geometryType = geoJSON && geoJSON.type;
  var featureType = GEOJSON_TO_FEATURE_TYPE[geometryType];
  if (!featureType) {
    throw new Error("unsupported geometry type: '" + geometryType + "'");
  }

  return featureType;
};

var BLACKLISTED_COLUMNS = ['cartodb_id', 'created_at', 'the_geom_webmercator', 'updated_at'];

var FeatureDefinitionModel = Backbone.Model.extend({

  initialize: function (attrs, options) {
    if (!options.configModel) throw new Error('configModel is required');
    if (!options.layerDefinitionModel) throw new Error('layerDefinitionModel is required');

    this._configModel = options.configModel;
    this._layerDefinitionModel = options.layerDefinitionModel;
    this._featureType = options.featureType;
  },

  isNew: function () {
    return !this.has('cartodb_id');
  },

  isPoint: function () {
    return this._isType(TYPES_POINT);
  },

  isPolygon: function () {
    return this._isType(TYPES_POLYGON);
  },

  isLine: function () {
    return this._isType(TYPES_LINE);
  },

  _isType: function (type) {
    return this._getType() === type;
  },

  isEditable: function () {
    return !this._layerDefinitionModel.hasAnalyses() &&
      !this._layerDefinitionModel.hasCustomQueryApplied();
  },

  isEqual: function (featureDefinition) {
    return this.id === featureDefinition.id &&
      this.getLayerId() === featureDefinition.getLayerId();
  },

  getLayerId: function () {
    return this._layerDefinitionModel.id;
  },

  getFeatureType: function () {
    if (this.isPoint()) {
      return 'point';
    }
    if (this.isLine()) {
      return 'line';
    }
    if (this.isPolygon()) {
      return 'polygon';
    }
  },

  fetch: function (options) {
    options = options || {};
    this._getQueryRowModel().fetch({
      success: function (data) {
        this.set(data.toJSON());
        options.success && options.success();
      }.bind(this)
    });
  },

  save: function (options) {
    options = options || {};
    var columns = this._layerDefinitionModel.getColumnNamesFromSchema();
    var attrs = _.pick(this.toJSON(), _.difference(columns, BLACKLISTED_COLUMNS));

    this._getQueryRowModel().save(attrs, {
      success: function (mdl) {
        this.set(mdl.toJSON());
        this.trigger('save');
        options.success && options.success();
      }.bind(this),
      error: function () {
        options.error && options.error();
      }
    });
  },

  _getQueryRowModel: function () {
    this._queryRowModel = this._queryRowModel || new QueryRowModel({ cartodb_id: this.get('id') }, {
      tableName: this._layerDefinitionModel.getTableName(),
      configModel: this._configModel
    });

    return this._queryRowModel;
  },

  _getType: function () {
    var the_geom = this.get('the_geom');
    var type = the_geom && convertGeoJSONTypeToFeatureType(the_geom) || this._featureType;

    return type;
  }
});

module.exports = FeatureDefinitionModel;
<|endoftext|>