<commit_before>var valid = require('./valid');

function _notAllowed(req, res) { res.send(new Response.MethodNotAllowed()); }

function _noCache(req, res, next) {
  res.set({
    'Cache-Control' : 'no-cache, no-store, must-revalidate',
    'Pragma'        : 'no-cache',
    'Expires'       : 0
  });

  next();
}

module.exports = function (api) {
  api.use(function (req, res, next) {
    res.header('Access-Control-Allow-Origin', req.headers['origin'] || '*');
    res.header('Access-Control-Allow-Headers', 'Content-Type, If-Modified-Since, X-Debug');
    res.header('Access-Control-Expose-Headers', 'Cache-Control, Content-Disposition, Content-Type, Expires, Last-Modified, Location, Pragma, Vary');
    res.header('Access-Control-Allow-Methods', 'HEAD, GET, POST, PUT, PATCH, DELETE, OPTIONS');
    res.header('Access-Control-Allow-Credentials', 'true');
    res.header('Access-Control-Max-Age', 60 * 60);

    if ('OPTIONS' == req.method) {
      res.status(200).end();
      return;
    }

    next();
  });

  api.get ('/', _notAllowed);

  api.post('/', _noCache, function (req, res, next) {
    Promise.try(function () {
      req.body = _.pick(req.body, (v) => (!_.isEmpty(v) || _.isFinite(v)));

      valid(req.body, {
        uid  : 'required',
        ts   : 'required|numeric',
        lat  : 'required|numeric|minVal:-90|maxVal:90',
        lon  : 'required|numeric|minVal:-180|maxVal:180',
        prec : 'numeric'
      });

      return db.query(['INSERT INTO "protests"."members"("received", "uid", "ts", "position", "precision", "note")',
          'VALUES (',
            'to_timestamp($1) AT TIME ZONE \'UTC\',',
            '$2,',
            'to_timestamp($3) AT TIME ZONE \'UTC\',',
            'topology.ST_GeomFromText(\'POINT($4, $5)\'),',
            '$6,',
            '$7',
          ') RETURNING *'].join(' '), [
            req.now,
            req.body['uid'],
            req.body['ts'],
            parseFloat(req.body['lat']), parseFloat(req.body['lon']),
            parseInt(req.body['prec']),
            req.body['msg'] || null
          ]
        );
    }).then(function (result) {
      console.log(result);
    }).then(function () {
      var dummy = { id: '0', lat: 44.452714, lon: 26.085903, size: 250 };

      switch (req.get('X-Debug')) {
        case 'same':
          dummy.lat = req.body.lat;
          dummy.lon = req.body.lon;

          break;
      }

      res.send(new Response.OK(dummy));
    }).catch(valid.Error, function (e) {
      throw new Response.BadRequest(_.values(_.values(e.errors)[0])[0][0]);
    }).catch(function (err) {
      next(err);
    }).done();
  });
};
<commit_msg>debug<commit_after>var valid = require('./valid');

function _notAllowed(req, res) { res.send(new Response.MethodNotAllowed()); }

function _noCache(req, res, next) {
  res.set({
    'Cache-Control' : 'no-cache, no-store, must-revalidate',
    'Pragma'        : 'no-cache',
    'Expires'       : 0
  });

  next();
}

module.exports = function (api) {
  api.use(function (req, res, next) {
    res.header('Access-Control-Allow-Origin', req.headers['origin'] || '*');
    res.header('Access-Control-Allow-Headers', 'Content-Type, If-Modified-Since, X-Debug');
    res.header('Access-Control-Expose-Headers', 'Cache-Control, Content-Disposition, Content-Type, Expires, Last-Modified, Location, Pragma, Vary');
    res.header('Access-Control-Allow-Methods', 'HEAD, GET, POST, PUT, PATCH, DELETE, OPTIONS');
    res.header('Access-Control-Allow-Credentials', 'true');
    res.header('Access-Control-Max-Age', 60 * 60);

    if ('OPTIONS' == req.method) {
      res.status(200).end();
      return;
    }

    next();
  });

  api.get ('/', _notAllowed);

  api.post('/', _noCache, function (req, res, next) {
    Promise.try(function () {
      req.body = _.pick(req.body, (v) => (!_.isEmpty(v) || _.isFinite(v)));

      valid(req.body, {
        uid  : 'required',
        ts   : 'required|numeric',
        lat  : 'required|numeric|minVal:-90|maxVal:90',
        lon  : 'required|numeric|minVal:-180|maxVal:180',
        prec : 'numeric'
      });

      console.log([
            req.now,
            req.body['uid'],
            req.body['ts'],
            parseFloat(req.body['lat']), parseFloat(req.body['lon']),
            parseInt(req.body['prec']),
            req.body['msg'] || null
          ]);

      return db.query(['INSERT INTO "protests"."members"("received", "uid", "ts", "position", "precision", "note")',
          'VALUES (',
            'to_timestamp($1) AT TIME ZONE \'UTC\',',
            '$2,',
            'to_timestamp($3) AT TIME ZONE \'UTC\',',
            'topology.ST_GeomFromText(\'POINT($4, $5)\'),',
            '$6,',
            '$7',
          ') RETURNING *'].join(' '), [
            req.now,
            req.body['uid'],
            req.body['ts'],
            parseFloat(req.body['lat']), parseFloat(req.body['lon']),
            parseInt(req.body['prec']),
            req.body['msg'] || null
          ]
        );
    }).then(function (result) {
      console.log(result);
    }).then(function () {
      var dummy = { id: '0', lat: 44.452714, lon: 26.085903, size: 250 };

      switch (req.get('X-Debug')) {
        case 'same':
          dummy.lat = req.body.lat;
          dummy.lon = req.body.lon;

          break;
      }

      res.send(new Response.OK(dummy));
    }).catch(valid.Error, function (e) {
      throw new Response.BadRequest(_.values(_.values(e.errors)[0])[0][0]);
    }).catch(function (err) {
      next(err);
    }).done();
  });
};
<|endoftext|>


<commit_before>'use strict';
var url = require('url');
var neo4j = require('neo4j-driver').v1;
var _ = require('underscore');
var nodeify = require('ascallback');

module.exports = function(options) {
  var db;
  if (!options || !options.nodeify) db =  new Seraph(options);
  else {
    db = new Proxy(new Seraph(options), {
      get: function(target, name) {
        if (name in target && typeof target[name] == 'function') {
          return function() {
            var args = [].slice.call(arguments, 0, arguments.length - 1);
            var cb = arguments[arguments.length - 1];
            nodeify(target[name].apply(target, args), cb);
          }
        } else {
          return target[name]
        }
      }
    });
  }

  var recursiveProxy = (obj) => {
    return new Proxy(obj, {
      get: (_, k) => {
        if (!obj[k]) return undefined;
        if (typeof obj[k] == 'object') return recursiveProxy(obj[k]);
        return db[obj[k]].bind(db);
      }
    });
  }

  return new Proxy(db, {
    get: (target, key) => {
      if (target[key]) return target[key];
      var proxy = proxyMap[key];
      if (!proxy) return undefined;
      if (typeof proxy == 'object') return recursiveProxy(proxy);
      else return db[proxy].bind(db);
    }
  })
}

var proxyMap = {
  node: {
    save: 'save',
    read: 'read',
    nodesWithLabel: 'nodesWithLabel',
    readLabels: 'readLabels'
  },
  constraints: {
    uniqueness: {
      create: 'createUniquenessConstraint'
    }
  },
  rel: {
    read: 'readRel',
    create: 'createRel'
  }
}

class Seraph {
  constructor(options) {
    if (!options) options = 'bolt://neo4j:neo4j@localhost';
    if (typeof options != 'object') {
      var server = url.parse(options);
      options = {
        user: server.auth ? server.auth.split(':')[0] : 'neo4j',
        pass: server.auth ? server.auth.split(':')[1] : 'neo4j'
      };
      delete server.auth;
      options.server = url.format(server);
    }

    options.user = options.user || 'neo4j';
    options.pass = options.pass || 'neo4j';
    options.server = options.server || 'bolt://localhost';
    options.id = options.id || 'id';

    this.options = options;
    this.driver = options.driver ||  neo4j.driver(options.server, neo4j.auth.basic(options.user, options.pass));
    this.label = options.label === false ? false : true;
    this.unboxInts = options.unboxInts === false ? false : true;

  }

  _unboxInt(i) {
    return this.unboxInts ? i.toNumber() : i;
  }

  _unboxAll(obj) {
    Object.keys(obj).forEach((key) => {
      if (neo4j.isInt(obj[key])) obj[key] = this._unboxInt(obj[key]);
    });
    return obj;
  }

  _getId(obj, requireData) {
    return new Promise((resolve, reject) => {
      var id;
      if (requireData) {
        id = typeof obj == 'object' ? obj[this.options.id] : undefined;
      } else {
        id = typeof obj == 'object' ? obj[this.options.id] : obj;
      }

      if (id != null) id = parseInt(id, 10);
      if (isNaN(id) || id == null) return reject(new Error("Invalid ID"));
      resolve(neo4j.int(id));
    });
  }

  _processResult(result, singleOrNull) {
    var records = result.records;
    var assemble = (field) => {
      if (typeof field != 'object' || !field) return field;
      else if (neo4j.isInt(field)) return this._unboxInt(field);
      else if (field instanceof neo4j.types.Node) {
        var obj = field.properties;
        if (this.options.label) obj.labels = field.labels;
        obj[this.options.id] = this._unboxInt(field.identity);
        return this._unboxAll(obj);
      }
      else if (field instanceof neo4j.types.Relationship) {
        field.start = this._unboxInt(field.start);
        field.end = this._unboxInt(field.end);
        field[this.options.id] = this._unboxInt(field.identity);
        if (this.options.id != 'identity') delete field.identity;
        field.properties = this._unboxAll(field.properties);
        return field;
      }
      else return field;
    }
    var processed = records.map((record) => {
      if (record.keys.length == 1) return assemble(record._fields[0]);
      else {
        var row = {};
        Object.keys(record).forEach((key) => {
          row[key] = assemble(record._fields[record._fieldLookup[key]])
        });
        return row;
      }
    });
    if (singleOrNull) processed = this._selectSingleOrNull(processed);
    return processed;
  }

  _selectSingleOrNull(results) {
    return results.length > 0 ? results[0] : null;
  }

  _session() {
    return this.options.session || this.driver.session();
  }

  _endSession(sess) {
    return (passthrough) => {
      if (this.options.session != sess) sess.close();
      return passthrough;
    }
  }

  _aggregate(fn, arr, argnum, allargs) {
    var sess = this.options.session ? this : this.session();
    var aggregated = Promise.all(arr.map(arg => {
      allargs[argnum] = arg;
      return fn.apply(sess, allargs);
    }))
    if (!this.options.session) {
      aggregated = aggregated
        .then((r) => { return sess.close(), r })
        .catch((e) => {
          sess.close();
          return new Promise((_, r) => r(e))
        });
    }
    return aggregated;
  }

  _run(query, params) {
    var sess = this._session();
    return sess.run(query, params)
      .then(this._endSession(sess))
      .catch((e) => {
        this._endSession(sess)();
        return new Promise((_, r) => r(e));
      });
  }

  session() {
    var sess = this.driver.session();
    var sessSeraph = new Seraph(this.options);
    sessSeraph.session = sess;
    return sessSeraph;
  }

  close() {
    this.options.session && this.options.session.close();
  }

  query(cypher, params) {
    return this._run(cypher, params)
      .then((result) => this._processResult(result));
  }

  read(node, prop) {
    if (Array.isArray(node)) return this._aggregate(this.read, node, 0, arguments);
    return this._getId(node)
      .then((id) => {
        return this._run(`
          MATCH (node) WHERE id(node) = {id}
          RETURN ${prop ? "node." + prop : "node"}
        `, {id});
      })
      .then((result) => this._processResult(result, true))
  }

  save(node, label) {
    if (Array.isArray(node)) return this._aggregate(this.save, node, 0, arguments);
    if (arguments[2] != null) return this._saveProperty(node, arguments[1], arguments[2]);

    if (label) {
      if (!Array.isArray(label)) label = [label];
      label = label.map(l => `SET node:${l}`).join(' ');
    } else {
      label = '';
    }

    return this._getId(node)
      .then(id => {
        var props = _.omit(node, this.options.id);
        return this._run(`
          MATCH (node) WHERE id(node) = {id}
          SET node = {props} ${label}
          RETURN node
        `, { id, props });
      })
      .catch(() => {
        return this._run(`
          CREATE (node)
          SET node = {node} ${label}
          RETURN node
        `, {node})
      })
      .then((result) => this._processResult(result, true))
  }

  _saveProperty(node, key, value) {
    return this._getId(node)
      .then(id => {
        return this._run(`
          MATCH (node) WHERE id(node) = {id}
          SET node.${key} = {value}
          RETURN node
        `, { id, value });
      })
      .then((result) => this._processResult(result, true))
  }

  delete(node, detach) {
    if (Array.isArray(node)) return this._aggregate(this.delete, node, 0, arguments);
    if (detach != null && typeof detach != 'boolean') return this.remove(node, detach);

    return this._getId(node)
      .then(id => {
        return this._run(`
          MATCH (node) WHERE id(node) = {id}
          ${detach ? 'detach' : ''} DELETE node
        `, { id })
      })
      .then(() => true);
  }

  remove(node, prop) {
    if (Array.isArray(node)) return this._aggregate(this.remove, node, 0, arguments);
    return this._getId(node)
      .then(id => {
        return this._run(`
          MATCH (node) WHERE id(node) = {id}
          REMOVE node.${prop}
          RETURN node
        `, { id })
      })
      .then((result) => this._processResult(result, true))
  }

  nodesWithLabel(label) {
    return this._run(`MATCH (n:${label}) RETURN n`)
      .then((result) => this._processResult(result));
  }

  readLabels(node) {
    return this._getId(node)
      .then(id => this._run(`MATCH (node) WHERE id(node) = {id} RETURN labels(node)`, { id }))
      .then((result) => {
        var rows = this._processResult(result)
        return rows[0] || [];
      })
  }

  readRel(rel) {
    if (Array.isArray(rel)) return this._aggregate(this.readRel, rel, 0, arguments);
    return this._getId(rel)
      .then(id => {
        return this._run(`
          MATCH (a)-[rel]-(b)
          WHERE id(rel) = {id}
          RETURN rel
        `, { id })
      })
      .then((result) => this._processResult(result, true))
  }

  relate() { return this.createRel.apply(this, arguments) }
  createRel(startNode, type, endNode, properties) {
    if (Array.isArray(startNode)) return this._aggregate(this.createRel, startNode, 0, arguments);
    if (Array.isArray(endNode)) return this._aggregate(this.createRel, endNode, 2, arguments);
    properties = properties || {};

    return Promise.all([ this._getId(startNode), this._getId(endNode) ])
      .then(ids => {
        return this._run(`
          MATCH (start), (end)
          WHERE id(start) = {startId} AND id(end) = {endId}
          CREATE (start)-[rel:\`${type}\`]->(end)
          SET rel = {properties}
          RETURN rel
        `, { startId: ids[0], endId: ids[1], properties });
      })
      .then((result) => this._processResult(result, true))
  }

  createUniquenessConstraint(label, key) {
    return this._run(`CREATE CONSTRAINT ON (n:${label}) ASSERT n.${key} IS UNIQUE`)
      //compat. query returns nothing anyway
      .then(() => { return { type: 'UNIQUENESS', label: label, property_keys: [key] } });
  }

}
<commit_msg>bolt: update rel<commit_after>'use strict';
var url = require('url');
var neo4j = require('neo4j-driver').v1;
var _ = require('underscore');
var nodeify = require('ascallback');

module.exports = function(options) {
  var db;
  if (!options || !options.nodeify) db =  new Seraph(options);
  else {
    db = new Proxy(new Seraph(options), {
      get: function(target, name) {
        if (name in target && typeof target[name] == 'function') {
          return function() {
            var args = [].slice.call(arguments, 0, arguments.length - 1);
            var cb = arguments[arguments.length - 1];
            nodeify(target[name].apply(target, args), cb);
          }
        } else {
          return target[name]
        }
      }
    });
  }

  var recursiveProxy = (obj) => {
    return new Proxy(obj, {
      get: (_, k) => {
        if (!obj[k]) return undefined;
        if (typeof obj[k] == 'object') return recursiveProxy(obj[k]);
        return db[obj[k]].bind(db);
      }
    });
  }

  return new Proxy(db, {
    get: (target, key) => {
      if (target[key]) return target[key];
      var proxy = proxyMap[key];
      if (!proxy) return undefined;
      if (typeof proxy == 'object') return recursiveProxy(proxy);
      else return db[proxy].bind(db);
    }
  })
}

var proxyMap = {
  node: {
    save: 'save',
    read: 'read',
    nodesWithLabel: 'nodesWithLabel',
    readLabels: 'readLabels'
  },
  constraints: {
    uniqueness: {
      create: 'createUniquenessConstraint'
    }
  },
  rel: {
    read: 'readRel',
    create: 'createRel',
    update: 'updateRel'
  }
}

class Seraph {
  constructor(options) {
    if (!options) options = 'bolt://neo4j:neo4j@localhost';
    if (typeof options != 'object') {
      var server = url.parse(options);
      options = {
        user: server.auth ? server.auth.split(':')[0] : 'neo4j',
        pass: server.auth ? server.auth.split(':')[1] : 'neo4j'
      };
      delete server.auth;
      options.server = url.format(server);
    }

    options.user = options.user || 'neo4j';
    options.pass = options.pass || 'neo4j';
    options.server = options.server || 'bolt://localhost';
    options.id = options.id || 'id';

    this.options = options;
    this.driver = options.driver ||  neo4j.driver(options.server, neo4j.auth.basic(options.user, options.pass));
    this.label = options.label === false ? false : true;
    this.unboxInts = options.unboxInts === false ? false : true;

  }

  _unboxInt(i) {
    return this.unboxInts ? i.toNumber() : i;
  }

  _unboxAll(obj) {
    Object.keys(obj).forEach((key) => {
      if (neo4j.isInt(obj[key])) obj[key] = this._unboxInt(obj[key]);
    });
    return obj;
  }

  _getId(obj, requireData) {
    return new Promise((resolve, reject) => {
      var id;
      if (requireData) {
        id = typeof obj == 'object' ? obj[this.options.id] : undefined;
      } else {
        id = typeof obj == 'object' ? obj[this.options.id] : obj;
      }

      if (id != null) id = parseInt(id, 10);
      if (isNaN(id) || id == null) return reject(new Error("Invalid ID"));
      resolve(neo4j.int(id));
    });
  }

  _processResult(result, singleOrNull) {
    var records = result.records;
    var assemble = (field) => {
      if (typeof field != 'object' || !field) return field;
      else if (neo4j.isInt(field)) return this._unboxInt(field);
      else if (field instanceof neo4j.types.Node) {
        var obj = field.properties;
        if (this.options.label) obj.labels = field.labels;
        obj[this.options.id] = this._unboxInt(field.identity);
        return this._unboxAll(obj);
      }
      else if (field instanceof neo4j.types.Relationship) {
        field.start = this._unboxInt(field.start);
        field.end = this._unboxInt(field.end);
        field[this.options.id] = this._unboxInt(field.identity);
        if (this.options.id != 'identity') delete field.identity;
        field.properties = this._unboxAll(field.properties);
        return field;
      }
      else return field;
    }
    var processed = records.map((record) => {
      if (record.keys.length == 1) return assemble(record._fields[0]);
      else {
        var row = {};
        Object.keys(record).forEach((key) => {
          row[key] = assemble(record._fields[record._fieldLookup[key]])
        });
        return row;
      }
    });
    if (singleOrNull) processed = this._selectSingleOrNull(processed);
    return processed;
  }

  _selectSingleOrNull(results) {
    return results.length > 0 ? results[0] : null;
  }

  _session() {
    return this.options.session || this.driver.session();
  }

  _endSession(sess) {
    return (passthrough) => {
      if (this.options.session != sess) sess.close();
      return passthrough;
    }
  }

  _aggregate(fn, arr, argnum, allargs) {
    var sess = this.options.session ? this : this.session();
    var aggregated = Promise.all(arr.map(arg => {
      allargs[argnum] = arg;
      return fn.apply(sess, allargs);
    }))
    if (!this.options.session) {
      aggregated = aggregated
        .then((r) => { return sess.close(), r })
        .catch((e) => {
          sess.close();
          return new Promise((_, r) => r(e))
        });
    }
    return aggregated;
  }

  _run(query, params) {
    var sess = this._session();
    return sess.run(query, params)
      .then(this._endSession(sess))
      .catch((e) => {
        this._endSession(sess)();
        return new Promise((_, r) => r(e));
      });
  }

  session() {
    var sess = this.driver.session();
    var sessSeraph = new Seraph(this.options);
    sessSeraph.session = sess;
    return sessSeraph;
  }

  close() {
    this.options.session && this.options.session.close();
  }

  query(cypher, params) {
    return this._run(cypher, params)
      .then((result) => this._processResult(result));
  }

  read(node, prop) {
    if (Array.isArray(node)) return this._aggregate(this.read, node, 0, arguments);
    return this._getId(node)
      .then((id) => {
        return this._run(`
          MATCH (node) WHERE id(node) = {id}
          RETURN ${prop ? "node." + prop : "node"}
        `, {id});
      })
      .then((result) => this._processResult(result, true))
  }

  save(node, label) {
    if (Array.isArray(node)) return this._aggregate(this.save, node, 0, arguments);
    if (arguments[2] != null) return this._saveProperty(node, arguments[1], arguments[2]);

    if (label) {
      if (!Array.isArray(label)) label = [label];
      label = label.map(l => `SET node:${l}`).join(' ');
    } else {
      label = '';
    }

    return this._getId(node)
      .then(id => {
        var props = _.omit(node, this.options.id);
        return this._run(`
          MATCH (node) WHERE id(node) = {id}
          SET node = {props} ${label}
          RETURN node
        `, { id, props });
      })
      .catch(() => {
        return this._run(`
          CREATE (node)
          SET node = {node} ${label}
          RETURN node
        `, {node})
      })
      .then((result) => this._processResult(result, true))
  }

  _saveProperty(node, key, value) {
    return this._getId(node)
      .then(id => {
        return this._run(`
          MATCH (node) WHERE id(node) = {id}
          SET node.${key} = {value}
          RETURN node
        `, { id, value });
      })
      .then((result) => this._processResult(result, true))
  }

  delete(node, detach) {
    if (Array.isArray(node)) return this._aggregate(this.delete, node, 0, arguments);
    if (detach != null && typeof detach != 'boolean') return this.remove(node, detach);

    return this._getId(node)
      .then(id => {
        return this._run(`
          MATCH (node) WHERE id(node) = {id}
          ${detach ? 'detach' : ''} DELETE node
        `, { id })
      })
      .then(() => true);
  }

  remove(node, prop) {
    if (Array.isArray(node)) return this._aggregate(this.remove, node, 0, arguments);
    return this._getId(node)
      .then(id => {
        return this._run(`
          MATCH (node) WHERE id(node) = {id}
          REMOVE node.${prop}
          RETURN node
        `, { id })
      })
      .then((result) => this._processResult(result, true))
  }

  nodesWithLabel(label) {
    return this._run(`MATCH (n:${label}) RETURN n`)
      .then((result) => this._processResult(result));
  }

  readLabels(node) {
    return this._getId(node)
      .then(id => this._run(`MATCH (node) WHERE id(node) = {id} RETURN labels(node)`, { id }))
      .then((result) => {
        var rows = this._processResult(result)
        return rows[0] || [];
      })
  }

  readRel(rel) {
    if (Array.isArray(rel)) return this._aggregate(this.readRel, rel, 0, arguments);
    return this._getId(rel)
      .then(id => {
        return this._run(`
          MATCH (a)-[rel]-(b)
          WHERE id(rel) = {id}
          RETURN rel
        `, { id })
      })
      .then((result) => this._processResult(result, true))
  }

  relate() { return this.createRel.apply(this, arguments) }
  createRel(startNode, type, endNode, properties) {
    if (Array.isArray(startNode)) return this._aggregate(this.createRel, startNode, 0, arguments);
    if (Array.isArray(endNode)) return this._aggregate(this.createRel, endNode, 2, arguments);
    properties = properties || {};

    return Promise.all([ this._getId(startNode), this._getId(endNode) ])
      .then(ids => {
        return this._run(`
          MATCH (start), (end)
          WHERE id(start) = {startId} AND id(end) = {endId}
          CREATE (start)-[rel:\`${type}\`]->(end)
          SET rel = {properties}
          RETURN rel
        `, { startId: ids[0], endId: ids[1], properties });
      })
      .then((result) => this._processResult(result, true))
  }

  updateRel(rel) {
    if (Array.isArray(rel)) return this._aggregate(this.updateRel, rel, 0, arguments);
    if (arguments[2] != null) return this._updateRelProperty.apply(this, arguments);
    return this._getId(rel)
      .then(id => {
        return this._run(`
          MATCH (a)-[rel]-(b)
          WHERE id(rel) = {id}
          SET rel = {props}
          RETURN rel
        `, { id, props: rel.properties });
      })
      .then((result) => this._processResult(result, true))
  }

  _updateRelProperties(rel, key, value) {
    return this._getId(rel)
      .then(id => {
        return this._run(`
          MATCH (a)-[rel]-(b)
          WHERE id(rel) = {id}
          SET rel.\`${key}\` = {value}
          RETURN rel
        `, { id, value });
      })
      .then((result) => this._processResult(result, true))
  }

  createUniquenessConstraint(label, key) {
    return this._run(`CREATE CONSTRAINT ON (n:${label}) ASSERT n.${key} IS UNIQUE`)
      //compat. query returns nothing anyway
      .then(() => { return { type: 'UNIQUENESS', label: label, property_keys: [key] } });
  }

}
<|endoftext|>


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

    angular.module('app').factory('MatchupService', MatchupService);

    MatchupService.$inject = ['$http', 'API_KEY'];

    function MatchupService($http, API_KEY) {

        var URL_GET_GAMES = 'https://ps-foosball.mybluemix.net/api/Games?filter=';
        var CACHED_GAME_COUNT = 10;

        return {
            getMatchupRecord: getMatchupRecord
        };

        function getMatchupRecord(team0Id, team1Id) {
            var url = URL_GET_GAMES + buildQueryString(team0Id, team1Id);
            console.log(url);
            var httpConfig = getHttpConfig(url);
            return $http(httpConfig).then(
                function (response) {
                    return parseMatchup(response.data, team0Id, team1Id);
                },
                function (err) {
                    return [];
                }
            );
        }

        function parseMatchup(games, team0Id, team1Id) {
            var team0Wins = 0;
            var team0Goals = 0;
            var team1Wins = 0;
            var team1Goals = 0;
            var cachedGames = [];

            for (var i = 0; i < games.length; i++) {
                var game = games[i];

                if (game.team0Score === game.team1Score ||
                    game.team0Score > 10 || game.team0Score < 0 ||
                    game.team1Score > 10 || game.team1Score < 0 ||
                    (game.team0Score !== 10 && game.team1Score !== 10)) {
                    // Sanity check the database. There are some games
                    // that have weird point totals or end in ties.
                    // Those games don't make sense; ignore them.
                    continue;
                }

                var newIndex = i;
                if (cachedGames.length >= CACHED_GAME_COUNT) {
                    cachedGames = _.tail(cachedGames);
                    newIndex = CACHED_GAME_COUNT - 1;
                }

                cachedGames[newIndex] = game;

                if (game.team0Id === team0Id) {
                    if (game.team0Score > game.team1Score) {
                        team0Wins++;
                    } else {
                        team1Wins++;
                    }
                    team0Goals += game.team0Score;
                    team1Goals += game.team1Score;
                } else {
                    if (game.team0Score > game.team1Score) {
                        team1Wins++;
                    } else {
                        team0Wins++;
                    }
                    team0Goals += game.team1Score;
                    team1Goals += game.team0Score;
                }
            }

            return {
                team0Wins: team0Wins,
                team0Goals: team0Goals,
                team1Wins: team1Wins,
                team1Goals: team1Goals,
                games: cachedGames
            };
        }

        function getHttpConfig(url) {
            return {
                method: 'GET',
                url: url,
                headers: {
                    'x-ps-simple-auth': API_KEY,
                }
            };
        }

        function buildQueryString(team0Id, team1Id) {
            var query = {
                where: {
                    and: [
                        {
                            or: [
                                {
                                    and: [
                                        {team0Id: team0Id},
                                        {team1Id: team1Id}
                                    ]
                                },
                                {
                                    and: [
                                        {team0Id: team1Id},
                                        {team1Id: team0Id}
                                    ]
                                }
                            ]
                        },
                        {
                            or: [
                                {status: 'force-complete'},
                                {status: 'complete'},
                                {status: 'force-completed'}
                            ]
                        }
                    ]
                },
                include: ['team0', 'team1']
            };

            return JSON.stringify(query);
        }
    }
})();<commit_msg>Fixed empty-game bug on matchup page<commit_after>(function() {
    'use strict';

    angular.module('app').factory('MatchupService', MatchupService);

    MatchupService.$inject = ['$http', 'API_KEY'];

    function MatchupService($http, API_KEY) {

        var URL_GET_GAMES = 'https://ps-foosball.mybluemix.net/api/Games?filter=';
        var CACHED_GAME_COUNT = 10;

        return {
            getMatchupRecord: getMatchupRecord
        };

        function getMatchupRecord(team0Id, team1Id) {
            var url = URL_GET_GAMES + buildQueryString(team0Id, team1Id);
            console.log(url);
            var httpConfig = getHttpConfig(url);
            return $http(httpConfig).then(
                function (response) {
                    return parseMatchup(response.data, team0Id, team1Id);
                },
                function (err) {
                    return [];
                }
            );
        }

        function parseMatchup(games, team0Id, team1Id) {
            var team0Wins = 0;
            var team0Goals = 0;
            var team1Wins = 0;
            var team1Goals = 0;
            var cachedGames = [];

            for (var i = 0; i < games.length; i++) {
                var game = games[i];

                if (game.team0Score === game.team1Score ||
                    game.team0Score > 10 || game.team0Score < 0 ||
                    game.team1Score > 10 || game.team1Score < 0 ||
                    (game.team0Score !== 10 && game.team1Score !== 10)) {
                    // Sanity check the database. There are some games
                    // that have weird point totals or end in ties.
                    // Those games don't make sense; ignore them.
                    continue;
                }

                if (cachedGames.length >= CACHED_GAME_COUNT) {
                    cachedGames = _.tail(cachedGames);
                }
                cachedGames[cachedGames.length] = game;

                if (game.team0Id === team0Id) {
                    if (game.team0Score > game.team1Score) {
                        team0Wins++;
                    } else {
                        team1Wins++;
                    }
                    team0Goals += game.team0Score;
                    team1Goals += game.team1Score;
                } else {
                    if (game.team0Score > game.team1Score) {
                        team1Wins++;
                    } else {
                        team0Wins++;
                    }
                    team0Goals += game.team1Score;
                    team1Goals += game.team0Score;
                }
            }

            console.log(JSON.stringify(cachedGames, 0, 2));
            console.log(JSON.stringify(games, 0, 2));
            return {
                team0Wins: team0Wins,
                team0Goals: team0Goals,
                team1Wins: team1Wins,
                team1Goals: team1Goals,
                games: cachedGames
            };
        }

        function getHttpConfig(url) {
            return {
                method: 'GET',
                url: url,
                headers: {
                    'x-ps-simple-auth': API_KEY,
                }
            };
        }

        function buildQueryString(team0Id, team1Id) {
            var query = {
                where: {
                    and: [
                        {
                            or: [
                                {
                                    and: [
                                        {team0Id: team0Id},
                                        {team1Id: team1Id}
                                    ]
                                },
                                {
                                    and: [
                                        {team0Id: team1Id},
                                        {team1Id: team0Id}
                                    ]
                                }
                            ]
                        },
                        {
                            or: [
                                {status: 'force-complete'},
                                {status: 'complete'},
                                {status: 'force-completed'}
                            ]
                        }
                    ]
                },
                include: ['team0', 'team1']
            };

            return JSON.stringify(query);
        }
    }
})();<|endoftext|>


<commit_before>/**
 * Sample React Native App
 * https://github.com/facebook/react-native
 */
'use strict';

var React = require('react-native');
var {
  AppRegistry,
  StyleSheet,
  Text,
  View,
} = React;

var AwesomeProject = React.createClass({
  render: function() {
    return (
      <View style={styles.container}>
        <Text style={styles.welcome}>
          Welcome to React Native!
        </Text>
        <Text style={styles.instructions}>
          To get started, edit index.ios.js
        </Text>
        <Text style={styles.instructions}>
          Press Cmd+R to reload,{'\n'}
          Cmd+D or shake for dev menu
        </Text>
      </View>
    );
  }
});

var styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    backgroundColor: '#F5FCFF',
  },
  welcome: {
    fontSize: 20,
    textAlign: 'center',
    margin: 10,
  },
  instructions: {
    textAlign: 'center',
    color: '#333333',
    marginBottom: 5,
  },
});

AppRegistry.registerComponent('AwesomeProject', () => AwesomeProject);
<commit_msg>Render a movie<commit_after>/**
 * Sample React Native App
 * https://github.com/facebook/react-native
 */
'use strict';

var MOCKED_MOVIES_DATA = [
  {title: 'Title', year: '2015', posters: {thumbnail: 'http://i.imgur.com/UePbdph.jpg'}},
];

var React = require('react-native');
var {
  AppRegistry,
  StyleSheet,
  Image,
  Text,
  View,
} = React;

var AwesomeProject = React.createClass({
  render: function() {
    var movie = MOCKED_MOVIES_DATA[0];
    return (
      <View style={styles.container}>
        <Text>{movie.title}</Text>
        <Text>{movie.year}</Text>
        <Image source={{uri: movie.posters.thumbnail}} style={styles.thumbnail} />
      </View>
    );
  }
});

var styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    backgroundColor: '#F5FCFF',
  },
  welcome: {
    fontSize: 20,
    textAlign: 'center',
    margin: 10,
  },
  instructions: {
    textAlign: 'center',
    color: '#333333',
    marginBottom: 5,
  },
  thumbnail: {
    width: 53,
    height: 81,
  },
});

AppRegistry.registerComponent('AwesomeProject', () => AwesomeProject);
<|endoftext|>


<commit_before>'use babel';

import { CompositeDisposable } from 'atom';

function isDescendantOfType(parentType, child) {
     var node = child.parentNode;
     while (node != null) {
         if (node.localName == parentType) {
             return true;
         }
         node = node.parentNode;
     }
     return false;
}

function getListener (options) {
  let mainAxis = options.direction == 'left' || options.direction == 'right' ? 'X' : 'Y'
  let crossAxis = mainAxis == 'X' ? 'Y' : 'X'
  let reversed = options.direction == 'right' || options.direction == 'down'
  let keyboard = options.keyboard
  let previousScroll = 0
  let timeout
  return function (e) {
    if (keyboard == null || keyboard == 'none') {
      if (Math.abs(e['delta' + mainAxis]) < Math.abs(e['delta' + crossAxis]) || !isDescendantOfType('atom-text-editor', e.target)) {
          return
      }
    } else {
      if (Math.abs(e['delta' + mainAxis]) < Math.abs(e['delta' + crossAxis]) || !(e[keyboard]) || !isDescendantOfType('atom-text-editor', e.target)) {
        return
      }
    }
    e.preventDefault();
    e.stopImmediatePropagation();
    previousScroll += e['delta' + mainAxis]
    clearTimeout(timeout)
    timeout = setTimeout(() => previousScroll = 0, 50)

    if (previousScroll > 50) {
      previousScroll -= 50
      let editor
      if (editor = atom.workspace.getActiveTextEditor()) {
        editor[reversed ? 'undo' : 'redo']()
      }
    } else if (previousScroll < -50) {
      previousScroll += 50
      let editor
      if (editor = atom.workspace.getActiveTextEditor()) {
        editor[reversed ? 'redo' : 'undo']()
      }
    }
  }
}

export default {

  config: {
    autoToggle: {
      title: 'Auto Toggle',
      description: 'Enabled on Atom startup.',
      type: 'boolean',
      default: true
    },
    direction: {
      title: 'Scroll direction',
      description: 'Set the scroll direction action. Must be up/down on devices without touchpad or sidescroll.',
      type: 'string',
      default: 'left',
      enum: [
        {value: 'left', description: 'Scroll left to undo, right to redo'},
        {value: 'right', description: 'Scroll right to undo, left to redo'},
        {value: 'up', description: 'Scroll up to undo, down to redo'},
        {value: 'down', description: 'Scroll down to undo, up to redo'},
      ],
    },
    modifierKey: {
      title: 'Keyboard Modifier',
      description: 'Enable support for a keyboard modifier key + scroll.',
      type: 'string',
      default: 'none',
      enum: [
        {value: 'none', description: 'No modifier key used.'},
        {value: 'altKey', description: 'Alt key'},
        {value: 'ctrlKey', description: 'Control key'},
      ],
    }
  },
  subscriptions: null,
  listener: null,
  active: false,

  activate(state) {
    this.subscriptions = new CompositeDisposable();

    this.subscriptions.add(atom.commands.add('atom-workspace', {
      'scroll-through-time:toggle': () => this.toggle(),
      'scroll-through-time:enable': () => this.toggle(true),
      'scroll-through-time:disable': () => this.toggle(false)
    }));

    this.subscriptions.add(
      atom.config.observe('scroll-through-time.direction', (newValue) => {
        this.removeListener()
        this.listener = getListener({direction: newValue, keyboard: this.getConfig('modifierKey')})
        if (this.active) {
          this.setupListener()
        }
      }));

    this.subscriptions.add(
      atom.config.observe('scroll-through-time.modifierKey', (newValue) => {
          this.removeListener()
          this.listener = getListener({direction: this.getConfig('direction'), keyboard: newValue})
          if (this.active) {
            this.setupListener()
          }
      }));

    if (this.getConfig('autoToggle') || state.active) {
      this.toggle(true)
    }
  },

  deactivate() {
    this.active = false
    this.removeListener()
    this.subscriptions.dispose();
  },

  serialize() {
    return {
      active: this.active,
    };
  },

  setupListener() {
    window.addEventListener(
      'mousewheel',
      this.listener,
      {passive: false, capture: true}
    )
  },

  removeListener() {
    window.removeEventListener('mousewheel', this.listener)
  },

  toggle(force) {
    this.active = typeof force !== 'undefined'
      ? force
      : !this.active
    return (
      this.active ?
      this.setupListener() :
      this.removeListener()
    );
  },

  getConfig (config) {
    return atom.config.get(`scroll-through-time.${config}`)
  }

};
<commit_msg>fix indent<commit_after>'use babel';

import { CompositeDisposable } from 'atom';

function isDescendantOfType(parentType, child) {
  var node = child.parentNode;
  while (node != null) {
    if (node.localName == parentType) {
      return true;
    }
    node = node.parentNode;
  }
  return false;
}

function getListener (options) {
  let mainAxis = options.direction == 'left' || options.direction == 'right' ? 'X' : 'Y'
  let crossAxis = mainAxis == 'X' ? 'Y' : 'X'
  let reversed = options.direction == 'right' || options.direction == 'down'
  let keyboard = options.keyboard
  let previousScroll = 0
  let timeout
  return function (e) {
    if (keyboard == null || keyboard == 'none') {
      if (Math.abs(e['delta' + mainAxis]) < Math.abs(e['delta' + crossAxis]) || !isDescendantOfType('atom-text-editor', e.target)) {
          return
      }
    } else {
      if (Math.abs(e['delta' + mainAxis]) < Math.abs(e['delta' + crossAxis]) || !(e[keyboard]) || !isDescendantOfType('atom-text-editor', e.target)) {
        return
      }
    }
    e.preventDefault();
    e.stopImmediatePropagation();
    previousScroll += e['delta' + mainAxis]
    clearTimeout(timeout)
    timeout = setTimeout(() => previousScroll = 0, 50)

    if (previousScroll > 50) {
      previousScroll -= 50
      let editor
      if (editor = atom.workspace.getActiveTextEditor()) {
        editor[reversed ? 'undo' : 'redo']()
      }
    } else if (previousScroll < -50) {
      previousScroll += 50
      let editor
      if (editor = atom.workspace.getActiveTextEditor()) {
        editor[reversed ? 'redo' : 'undo']()
      }
    }
  }
}

export default {

  config: {
    autoToggle: {
      title: 'Auto Toggle',
      description: 'Enabled on Atom startup.',
      type: 'boolean',
      default: true
    },
    direction: {
      title: 'Scroll direction',
      description: 'Set the scroll direction action. Must be up/down on devices without touchpad or sidescroll.',
      type: 'string',
      default: 'left',
      enum: [
        {value: 'left', description: 'Scroll left to undo, right to redo'},
        {value: 'right', description: 'Scroll right to undo, left to redo'},
        {value: 'up', description: 'Scroll up to undo, down to redo'},
        {value: 'down', description: 'Scroll down to undo, up to redo'},
      ],
    },
    modifierKey: {
      title: 'Keyboard Modifier',
      description: 'Enable support for a keyboard modifier key + scroll.',
      type: 'string',
      default: 'none',
      enum: [
        {value: 'none', description: 'No modifier key used.'},
        {value: 'altKey', description: 'Alt key'},
        {value: 'ctrlKey', description: 'Control key'},
      ],
    }
  },
  subscriptions: null,
  listener: null,
  active: false,

  activate(state) {
    this.subscriptions = new CompositeDisposable();

    this.subscriptions.add(atom.commands.add('atom-workspace', {
      'scroll-through-time:toggle': () => this.toggle(),
      'scroll-through-time:enable': () => this.toggle(true),
      'scroll-through-time:disable': () => this.toggle(false)
    }));

    this.subscriptions.add(
      atom.config.observe('scroll-through-time.direction', (newValue) => {
        this.removeListener()
        this.listener = getListener({direction: newValue, keyboard: this.getConfig('modifierKey')})
        if (this.active) {
          this.setupListener()
        }
      }));

    this.subscriptions.add(
      atom.config.observe('scroll-through-time.modifierKey', (newValue) => {
          this.removeListener()
          this.listener = getListener({direction: this.getConfig('direction'), keyboard: newValue})
          if (this.active) {
            this.setupListener()
          }
      }));

    if (this.getConfig('autoToggle') || state.active) {
      this.toggle(true)
    }
  },

  deactivate() {
    this.active = false
    this.removeListener()
    this.subscriptions.dispose();
  },

  serialize() {
    return {
      active: this.active,
    };
  },

  setupListener() {
    window.addEventListener(
      'mousewheel',
      this.listener,
      {passive: false, capture: true}
    )
  },

  removeListener() {
    window.removeEventListener('mousewheel', this.listener)
  },

  toggle(force) {
    this.active = typeof force !== 'undefined'
      ? force
      : !this.active
    return (
      this.active ?
      this.setupListener() :
      this.removeListener()
    );
  },

  getConfig (config) {
    return atom.config.get(`scroll-through-time.${config}`)
  }

};
<|endoftext|>


<commit_before>import React from 'react'
import PropTypes from 'prop-types'
import TeamItem from './TeamItem'

import TEAM_SHAPE from '../../constants/ApiTeam'

const TeamList = (props) => (

    {props.teams.length > 0 &&

      {props.teams.length} teams attending

    }

      {props.teams.map((team) =>
        <TeamItem
          key={team.key}
          team_number={team.team_number}
          nickname={team.nickname}
        />
      )}

)

TeamList.propTypes = {
  teams: PropTypes.arrayOf(TEAM_SHAPE).isRequired,
}

export default TeamList
<commit_msg>[eventwizard2] Fix typing error<commit_after>import React from 'react'
import PropTypes from 'prop-types'
import TeamItem from './TeamItem'

import TEAM_SHAPE from '../../constants/ApiTeam'

const TeamList = (props) => (

    {props.teams.length > 0 &&

      {props.teams.length} teams attending

    }

      {props.teams.map((team) =>
        <TeamItem
          key={team.key}
          team_number={team.team_number}
          nickname={team.nickname}
        />
      )}

)

TeamList.propTypes = {
  teams: PropTypes.arrayOf(PropTypes.shape(TEAM_SHAPE)).isRequired,
}

export default TeamList
<|endoftext|>


<commit_before>// Node.JS standard modules

var crypto = require('crypto'),
    fs = require('fs');

// 3rd-party modules

var Q = require('q'),
    mmm = require('mmmagic'),
    magic = new mmm.Magic(mmm.MAGIC_MIME_TYPE);

// custom modules

// this module

/**
 * represents an individual file in the CDN, with required actions
 * @constructor
 */
var File = function(options) {
  var self = this,
      dfrd = Q.defer(),
      promises = [];

  this.localPath = options.localPath || '';
  this.path = options.path || '';
  this.mime = '';
  this.md5 = '';
  this.size = options.size;
  this.action = ''; // 'PUT' or 'DELETE'
  this.headers = {}; // only those missing from destination
  this.promise = dfrd.promise;

  if (options.mime) {
    this.mime = options.mime;
  } else if (this.localPath) {
    promises.push(this.detectMIME());
  }

  if (options.md5) {
    this.md5 = options.md5;
  } else if (this.localPath) {
    promises.push(this.calculateMD5());
  }

  Q.all(promises).then(function() {
    process.nextTick(function() {
      dfrd.resolve(self);
    });
  });

  return this;
};

File.prototype.toString = function() {
  var string = '',
      mime = this.mime;

  mime = mime.replace('application', 'app.');
  mime = mime.replace('javascript', 'js.');
  if (this.action === 'PUT') {
    string += '+';
  }
  if (this.action === 'DELETE') {
    string += '-';
  }
  string += this.path + ': ';
  string += '#' + this.md5.substr(0, 6) + ' ';
  string += this.size + ' ';
  string += mime;
  return string;
};

File.prototype.setMIME = function(mime) {
  var parts,
      ext;
  if (mime.indexOf('text/') === 0) {
    parts = this.path.split('.');
    ext = parts[parts.length - 1];
    switch (ext) {
      case 'css':
        this.mime = 'text/css';
        break;
      case 'html':
        this.mime = 'text/html';
        break;
      case 'js':
        this.mime = 'application/javascript';
        break;
      case 'xml':
        this.mime = 'application/xml';
        break;
      default:
        this.mime = mime;
    }
  } else {
    this.mime = mime;
  }
};

File.prototype.detectMIME = function() {
  var self = this,
      dfrd = Q.defer();

  Q.ninvoke(magic, 'detectFile', this.localPath)
  .then(function(result) {
    self.setMIME(result);
    dfrd.resolve();
  }).fail(function(err) {
    dfrd.reject(err);
  }).done();
  return dfrd.promise;
};

File.prototype.calculateMD5 = function() {
  var self = this,
      dfrd = Q.defer(),
      md5 = crypto.createHash('md5'),
      rs;

  rs = fs.createReadStream(this.localPath);
  rs.on('error', function(err) {
    dfrd.reject(err);
  });
  rs.on('data', function(data) {
    md5.update(data);
  });
  rs.once('end', function() {
    self.md5 = md5.digest('hex');
    dfrd.resolve();
  });
  return dfrd.promise;
};

// exports

module.exports = File;
<commit_msg>can now clone a File by passing it to the constructor - tweaks to File#toString()<commit_after>// Node.JS standard modules

var crypto = require('crypto'),
    fs = require('fs');

// 3rd-party modules

var Q = require('q'),
    mmm = require('mmmagic'),
    magic = new mmm.Magic(mmm.MAGIC_MIME_TYPE);

// custom modules

// this module

/**
 * represents an individual file in the CDN, with required actions
 * @constructor
 */
var File = function(options) {
  var self = this,
      dfrd = Q.defer(),
      promises = [];

  this.localPath = options.localPath || '';
  this.path = options.path || '';
  this.mime = '';
  this.md5 = '';
  this.size = options.size;
  this.action = options.action || ''; // 'PUT' or 'DELETE'
  this.headers = null; // only those missing from destination
  this.promise = dfrd.promise;
  this.isDirty = options.isDirty || false;

  if (options.headers) {
    this.headers = JSON.parse(JSON.stringify(options.headers));
  } else {
    this.headers = {};
  }

  if (options.mime) {
    this.mime = options.mime;
  } else if (this.localPath) {
    promises.push(this.detectMIME());
  }

  if (options.md5) {
    this.md5 = options.md5;
  } else if (this.localPath) {
    promises.push(this.calculateMD5());
  }

  Q.all(promises).then(function() {
    process.nextTick(function() {
      dfrd.resolve(self);
    });
  });

  return this;
};

File.prototype.toString = function() {
  var string = '',
      mime = this.mime;

  mime = mime.replace('application', 'app.');
  mime = mime.replace('javascript', 'js.');
  if (this.action === 'PUT') {
    string += '+';
  } else if (this.action === 'DELETE') {
    string += '-';
  } else if (Object.keys(this.headers).length) {
    string += '*';
  }
  string += this.path + ': ';
  string += '#' + this.md5.substr(0, 6) + ' ';
  string += this.size + ' ';
  string += mime;
  return string;
};

File.prototype.setMIME = function(mime) {
  var parts,
      ext;
  if (mime.indexOf('text/') === 0) {
    parts = this.path.split('.');
    ext = parts[parts.length - 1];
    switch (ext) {
      case 'css':
        this.mime = 'text/css';
        break;
      case 'html':
        this.mime = 'text/html';
        break;
      case 'js':
        this.mime = 'application/javascript';
        break;
      case 'xml':
        this.mime = 'application/xml';
        break;
      default:
        this.mime = mime;
    }
  } else {
    this.mime = mime;
  }
};

File.prototype.detectMIME = function() {
  var self = this,
      dfrd = Q.defer();

  Q.ninvoke(magic, 'detectFile', this.localPath)
  .then(function(result) {
    self.setMIME(result);
    dfrd.resolve();
  }).fail(function(err) {
    dfrd.reject(err);
  }).done();
  return dfrd.promise;
};

File.prototype.calculateMD5 = function() {
  var self = this,
      dfrd = Q.defer(),
      md5 = crypto.createHash('md5'),
      rs;

  rs = fs.createReadStream(this.localPath);
  rs.on('error', function(err) {
    dfrd.reject(err);
  });
  rs.on('data', function(data) {
    md5.update(data);
  });
  rs.once('end', function() {
    self.md5 = md5.digest('hex');
    dfrd.resolve();
  });
  return dfrd.promise;
};

// exports

module.exports = File;
<|endoftext|>


<commit_before>export { default as Dropdown } from "./components/Dropdown";
export { default as DropdownItem } from "./components/DropdownItem";
<commit_msg>feat(dropdown): export dropdown wrappers<commit_after>export { default as Dropdown } from "./components/Dropdown";
export { default as DropdownItem } from "./components/DropdownItem";
export { default as DropdownWrapper } from "./styledComponents/DropdownWrapper";
export {
  default as DropdownMenuWrapper
} from "./styledComponents/DropdownMenuWrapper";
export {
  default as DropdownItemWrapper
} from "./styledComponents/DropdownItemWrapper";
<|endoftext|>


<commit_before>/**
 *
 *      ioBroker email Adapter
 *
 *      (c) 2014-2018 bluefox <dogafox@gmail.com>
 *
 *      MIT License
 *
 */
'use strict';

var utils =   require(__dirname + '/lib/utils'); // Get common adapter utils
//noinspection JSUnresolvedFunction
var adapter = utils.Adapter('email');

adapter.on('message', function (obj) {
    //noinspection JSUnresolvedVariable
    if (obj && obj.command === 'send') processMessage(obj);
    processMessages();
});

adapter.on('ready', function () {
    // it must be like this
    /*
    adapter.getForeignObject('system.config', function (err, obj) {
        if (obj && obj.native && obj.native.secret) {
            //noinspection JSUnresolvedVariable
            adapter.config.transportOptions.auth.pass = decrypt(obj.native.secret, adapter.config.transportOptions.auth.pass);
        } else {
            //noinspection JSUnresolvedVariable
            adapter.config.transportOptions.auth.pass = decrypt('Zgfr56gFe87jJOM', adapter.config.transportOptions.auth.pass);
        }
        main();
    });
    */

    //noinspection JSUnresolvedVariable
    adapter.config.transportOptions.auth.pass = decrypt('Zgfr56gFe87jJOM', adapter.config.transportOptions.auth.pass);
    main();
});

var emailTransport;
var stopTimer       =  null;
var lastMessageTime = 0;
var lastMessageText = '';
function decrypt(key, value) {
    var result = '';
    for (var i = 0; i < value.length; ++i) {
        result += String.fromCharCode(key[i % key.length].charCodeAt(0) ^ value.charCodeAt(i));
    }
    return result;
}

// Terminate adapter after 30 seconds idle
function stop() {
    if (stopTimer) {
        clearTimeout(stopTimer);
        stopTimer = null;
    }

    // Stop only if subscribe mode
    //noinspection JSUnresolvedVariable
    if (adapter.common && adapter.common.mode === 'subscribe') {
        stopTimer = setTimeout(function () {
            stopTimer = null;
            adapter.stop();
        }, 30000);
    }
}

function processMessage(obj) {
    if (!obj || !obj.message) return;

    // filter out double messages
    var json = JSON.stringify(obj.message);
    if (lastMessageTime && lastMessageText === JSON.stringify(obj.message) && new Date().getTime() - lastMessageTime < 1000) {
        adapter.log.debug('Filter out double message [first was for ' + (new Date().getTime() - lastMessageTime) + 'ms]: ' + json);
        return;
    }
    lastMessageTime = new Date().getTime();
    lastMessageText = json;

    if (stopTimer) {
        clearTimeout(stopTimer);
        stopTimer = null;
    }

    if (obj.message.options) {
        var options = JSON.parse(JSON.stringify(obj.message.options));
        delete obj.message.options;
        sendEmail(null, options, obj.message, function (error) {
            if (obj.callback) adapter.sendTo(obj.from, 'send', {error: error}, obj.callback);
        });
    } else {
        emailTransport = sendEmail(emailTransport, adapter.config.transportOptions, obj.message);
    }

    stop();
}

function processMessages() {
    //noinspection JSUnresolvedFunction
    adapter.getMessage(function (err, obj) {
        if (obj) {
            processMessage(obj);
            processMessages();
        }
    });
}

function main() {
    // Adapter is started only if some one writes into "system.adapter.email.X.messagebox" new value
    processMessages();
    stop();
}

function sendEmail(transport, options, message, callback) {
    if (!message) message = {};

    options = options || adapter.config.transportOptions;

    if (!transport) {
        //noinspection JSUnresolvedVariable
        if (!options.host || !options.port) {
            //noinspection JSUnresolvedVariable
            if (options.host    !== undefined) delete options.host;
            //noinspection JSUnresolvedVariable
            if (options.port    !== undefined) delete options.port;
            //noinspection JSUnresolvedVariable
            if (options.secure  !== undefined) delete options.secure;
        } else {
            //noinspection JSUnresolvedVariable
            if (options.service !== undefined) delete options.service;
        }
        //noinspection JSUnresolvedVariable
        if (options.service === 'web.de') {
            //noinspection JSUnresolvedVariable
            options.domains = ['web.de'];
            //noinspection JSUnresolvedVariable
            options.host = 'smtp.web.de';
            //noinspection JSUnresolvedVariable
            options.port = '587';
            //options.tls = {ciphers: 'SSLv3'};
            //noinspection JSUnresolvedVariable
            delete options.service;
        } else if (options.service === 'Office365') {
            //noinspection JSUnresolvedVariable
            options.secureConnection = false;
            //noinspection JSUnresolvedVariable
            options.tls = {ciphers: 'SSLv3'};
            //noinspection JSUnresolvedVariable
            options.domains = ['web.de'];
            //noinspection JSUnresolvedVariable
            options.host = 'smtp.office365.com';
            //noinspection JSUnresolvedVariable
            options.port = '587';
            //noinspection JSUnresolvedVariable
            delete options.service;
        } else if (options.service === 'ith') {
            //noinspection JSUnresolvedVariable
            options.secureConnection = false;
            //noinspection JSUnresolvedVariable
            options.tls = {ciphers: 'SSLv3', rejectUnauthorized: false };
            //noinspection JSUnresolvedVariable
            options.requireTLS = true;
            //noinspection JSUnresolvedVariable
            options.host = 'mail.ithnet.com';
            //noinspection JSUnresolvedVariable
            options.port = '587';
            //noinspection JSUnresolvedVariable
            delete options.service;
        }
        //noinspection JSUnresolvedFunction, JSUnresolvedVariable
        transport = require('nodemailer').createTransport(options);
    }

    if (typeof message !== 'object') message = {text: message};

    //noinspection JSUnresolvedVariable
    message.from =    message.from    || adapter.config.defaults.from;
    //noinspection JSUnresolvedVariable
    message.to =      message.to      || adapter.config.defaults.to;
    //noinspection JSUnresolvedVariable
    message.subject = message.subject || adapter.config.defaults.subject;
    //noinspection JSUnresolvedVariable
    message.text =    message.text    || adapter.config.defaults.text;

    adapter.log.info('Send email: ' + JSON.stringify(message));

    //noinspection JSUnresolvedFunction
    transport.sendMail(message, function (error, info) {
        if (error) {
            adapter.log.error('Error ' + JSON.stringify(error));
            if (callback) callback(error.response || error.message || error.code || JSON.stringify(error));
        } else {
            //noinspection JSUnresolvedVariable
            adapter.log.info('sent to ' + message.to);
            adapter.log.debug('Response: ' + info.response);
            if (callback) callback(null);
        }
        stop();
    });
    return transport;
}
<commit_msg>add adapter-core<commit_after>/**
 *
 *      ioBroker email Adapter
 *
 *      (c) 2014-2018 bluefox <dogafox@gmail.com>
 *
 *      MIT License
 *
 */
'use strict';

var utils = require('@iobroker/adapter-core'); // Get common adapter utils
//noinspection JSUnresolvedFunction
var adapter = utils.Adapter('email');

adapter.on('message', function (obj) {
    //noinspection JSUnresolvedVariable
    if (obj && obj.command === 'send') processMessage(obj);
    processMessages();
});

adapter.on('ready', function () {
    // it must be like this
    /*
    adapter.getForeignObject('system.config', function (err, obj) {
        if (obj && obj.native && obj.native.secret) {
            //noinspection JSUnresolvedVariable
            adapter.config.transportOptions.auth.pass = decrypt(obj.native.secret, adapter.config.transportOptions.auth.pass);
        } else {
            //noinspection JSUnresolvedVariable
            adapter.config.transportOptions.auth.pass = decrypt('Zgfr56gFe87jJOM', adapter.config.transportOptions.auth.pass);
        }
        main();
    });
    */

    //noinspection JSUnresolvedVariable
    adapter.config.transportOptions.auth.pass = decrypt('Zgfr56gFe87jJOM', adapter.config.transportOptions.auth.pass);
    main();
});

var emailTransport;
var stopTimer       =  null;
var lastMessageTime = 0;
var lastMessageText = '';
function decrypt(key, value) {
    var result = '';
    for (var i = 0; i < value.length; ++i) {
        result += String.fromCharCode(key[i % key.length].charCodeAt(0) ^ value.charCodeAt(i));
    }
    return result;
}

// Terminate adapter after 30 seconds idle
function stop() {
    if (stopTimer) {
        clearTimeout(stopTimer);
        stopTimer = null;
    }

    // Stop only if subscribe mode
    //noinspection JSUnresolvedVariable
    if (adapter.common && adapter.common.mode === 'subscribe') {
        stopTimer = setTimeout(function () {
            stopTimer = null;
            adapter.stop();
        }, 30000);
    }
}

function processMessage(obj) {
    if (!obj || !obj.message) return;

    // filter out double messages
    var json = JSON.stringify(obj.message);
    if (lastMessageTime && lastMessageText === JSON.stringify(obj.message) && new Date().getTime() - lastMessageTime < 1000) {
        adapter.log.debug('Filter out double message [first was for ' + (new Date().getTime() - lastMessageTime) + 'ms]: ' + json);
        return;
    }
    lastMessageTime = new Date().getTime();
    lastMessageText = json;

    if (stopTimer) {
        clearTimeout(stopTimer);
        stopTimer = null;
    }

    if (obj.message.options) {
        var options = JSON.parse(JSON.stringify(obj.message.options));
        delete obj.message.options;
        sendEmail(null, options, obj.message, function (error) {
            if (obj.callback) adapter.sendTo(obj.from, 'send', {error: error}, obj.callback);
        });
    } else {
        emailTransport = sendEmail(emailTransport, adapter.config.transportOptions, obj.message);
    }

    stop();
}

function processMessages() {
    //noinspection JSUnresolvedFunction
    adapter.getMessage(function (err, obj) {
        if (obj) {
            processMessage(obj);
            processMessages();
        }
    });
}

function main() {
    // Adapter is started only if some one writes into "system.adapter.email.X.messagebox" new value
    processMessages();
    stop();
}

function sendEmail(transport, options, message, callback) {
    if (!message) message = {};

    options = options || adapter.config.transportOptions;

    if (!transport) {
        //noinspection JSUnresolvedVariable
        if (!options.host || !options.port) {
            //noinspection JSUnresolvedVariable
            if (options.host    !== undefined) delete options.host;
            //noinspection JSUnresolvedVariable
            if (options.port    !== undefined) delete options.port;
            //noinspection JSUnresolvedVariable
            if (options.secure  !== undefined) delete options.secure;
        } else {
            //noinspection JSUnresolvedVariable
            if (options.service !== undefined) delete options.service;
        }
        //noinspection JSUnresolvedVariable
        if (options.service === 'web.de') {
            //noinspection JSUnresolvedVariable
            options.domains = ['web.de'];
            //noinspection JSUnresolvedVariable
            options.host = 'smtp.web.de';
            //noinspection JSUnresolvedVariable
            options.port = '587';
            //options.tls = {ciphers: 'SSLv3'};
            //noinspection JSUnresolvedVariable
            delete options.service;
        } else if (options.service === 'Office365') {
            //noinspection JSUnresolvedVariable
            options.secureConnection = false;
            //noinspection JSUnresolvedVariable
            options.tls = {ciphers: 'SSLv3'};
            //noinspection JSUnresolvedVariable
            options.domains = ['web.de'];
            //noinspection JSUnresolvedVariable
            options.host = 'smtp.office365.com';
            //noinspection JSUnresolvedVariable
            options.port = '587';
            //noinspection JSUnresolvedVariable
            delete options.service;
        } else if (options.service === 'ith') {
            //noinspection JSUnresolvedVariable
            options.secureConnection = false;
            //noinspection JSUnresolvedVariable
            options.tls = {ciphers: 'SSLv3', rejectUnauthorized: false };
            //noinspection JSUnresolvedVariable
            options.requireTLS = true;
            //noinspection JSUnresolvedVariable
            options.host = 'mail.ithnet.com';
            //noinspection JSUnresolvedVariable
            options.port = '587';
            //noinspection JSUnresolvedVariable
            delete options.service;
        }
        //noinspection JSUnresolvedFunction, JSUnresolvedVariable
        transport = require('nodemailer').createTransport(options);
    }

    if (typeof message !== 'object') message = {text: message};

    //noinspection JSUnresolvedVariable
    message.from =    message.from    || adapter.config.defaults.from;
    //noinspection JSUnresolvedVariable
    message.to =      message.to      || adapter.config.defaults.to;
    //noinspection JSUnresolvedVariable
    message.subject = message.subject || adapter.config.defaults.subject;
    //noinspection JSUnresolvedVariable
    message.text =    message.text    || adapter.config.defaults.text;

    adapter.log.info('Send email: ' + JSON.stringify(message));

    //noinspection JSUnresolvedFunction
    transport.sendMail(message, function (error, info) {
        if (error) {
            adapter.log.error('Error ' + JSON.stringify(error));
            if (callback) callback(error.response || error.message || error.code || JSON.stringify(error));
        } else {
            //noinspection JSUnresolvedVariable
            adapter.log.info('sent to ' + message.to);
            adapter.log.debug('Response: ' + info.response);
            if (callback) callback(null);
        }
        stop();
    });
    return transport;
}
<|endoftext|>


<commit_before>/**
 * Browsertime (http://www.browsertime.com)
 * Copyright (c) 2014, Peter Hedenskog, Tobias Lidskog
 * and other contributors
 * Released under the Apache 2.0 License
 */
var stats = require('./statistics'),
    fs = require('fs'),
    async = require('async'),
    path = require('path'),
    log = require('winston'),
    url = require('url'),
    util = require('util'),
    EventEmitter = require('async-node-events');

function Browsertime(b) {
  EventEmitter.call(this);

  this.result = [];
  this.scripts = [];
  this.browserVersion = '';
  this.os = '';
  this.browserName = '';
  this.userAgent = '';
  this.browsers = b;
}

util.inherits(Browsertime, EventEmitter);

Browsertime.prototype.fetch = function(options, callback) {

  callback = callback || function() {};

  this._setupDefaults(options);
  this._populateScripts(options);
  this._setupLogging(options);

  var self = this;

  async.series([
    function(cb) {
      self.emit('beforeRun', cb);
    },
    function(cb) {
      self._do(options, cb);
    },
    function(cb) {
      self.emit('afterRun', cb);
    }
  ], function(err, result) {
    callback(err);
  });
};

Browsertime.prototype._do = function(options, cb) {
  var browserRuns = [];
  var self = this;
  for (var i = 1; i <= options.runs; i++) {
    browserRuns.push(self._collectFromTheBrowser(options, i, options.runs));
  }

  async.series(browserRuns,
    function(err, results) {
      if (err) {
        log.error(err.message);
        return cb(err);
      }
      var data = self._getFormattedResult(options);
      self._saveToFile(data, options, cb);
    });
};

Browsertime.prototype._collectFromTheBrowser = function(options, iteration, totalIterations) {
  var self = this;

  return function(callback) {
    async.series([
          function(cb) {
            self.emit('callingBrowser', cb);
          }
        ],
        function(err, results) {
          var driver = self.browsers.getBrowser(options.browser).getDriver(options);

          driver.getCapabilities().then(function(cap) {
            self.browserVersion = cap.get('version');
            self.os = cap.get('platform');
            self.browserName = cap.get('browserName');
          });

          // fetch the URL and wait until the load event ends or we get the time out
          log.info('Fetching ' + options.url + ' (' + iteration + ' of ' + totalIterations + ')');
          driver.get(options.url);
          driver.wait(function() {
                return driver.executeScript('return window.performance.timing.loadEventEnd>0')
                    .then(function(b) {
                      return b;
                    });
              },
              60000
          ).then(function() {
                // lets run all scripts
                var promises = [];
                self.scripts.forEach(function(script) {
                  promises.push(driver.executeScript(script));
                });

                var callbacks = [];
                promises.forEach(function(promise) {
                  callbacks.push(function(cb) {
                    promise.then(function(value) {
                      cb(null, value);
                    });
                  });
                });

                // when we are finished, push the result and stop the browser
                async.parallel(callbacks,
                    function(err, results) {
                      var eachRun = {};
                      results.forEach(function(metric) {
                        Object.keys(metric).forEach(function(key) {
                          eachRun[key] = metric[key];
                        });
                      });
                      self.result.push(eachRun);
                      driver.quit();
                      callback();
                    });
              },
              function() {
                driver.quit().thenFinally(function() {
                  return callback(new Error('The url ' + options.url + ' timed out'));
                });
              });
        });
  };
};

Browsertime.prototype._getFormattedResult = function(options) {
  // fetch timings for each run and make some statistics
  var timings = {};
  this.result.forEach(function(run) {
    stats.setupTimingsStatistics(timings, run);
    stats.setupStatistics(timings, run, 'speedIndex');
    stats.setupStatistics(timings, run, 'firstPaint');
    stats.setupUserTimingsStatistics(timings, run);
  });
  return {
    url: options.url,
    runs: options.runs,
    browserName: this.browserName,
    browserVersion: this.browserVersion,
    platform: this.os,
    userAgent: options.userAgent || this.userAgent,
    windowSize: 'unknown',
    browserTimeVersion: require('../package.json').version,
    statistics: stats.formatStatistics(timings),
    data: this.result
  };
};

Browsertime.prototype._saveToFile = function(data, options, cb) {
  var self = this;

  // lets store the files
  async.parallel([
      function(callback) {
        fs.writeFile(options.filename, JSON.stringify(data), function(err) {
          log.info('Storing ' + options.filename);
          callback(err);
        });
      },
      function(callback) {
        self.emit('savingResults', { data: data }, callback);
      }
    ], cb);
};

Browsertime.prototype._setupDefaults = function(options) {

  options.runs = options.runs || 3;
  options.filename = options.filename || path.join(process.cwd(), url.parse(options.url).hostname + '.json');
  options.seleniumServer = options.seleniumServer || 'http://localhost:4444/wd/hub';
};

Browsertime.prototype._setupLogging = function(options) {
  log.clear();
  log.add(log.transports.File, {
    filename: options.logDir?path.join(options.logDir,'browsertime.log'):'browsertime.log',
    level: 'info',
    json: false
  });

  // we only write to the console if we don't use silent
  if (!options.silent) {
    log.add(log.transports.Console, {
      level: 'info'
    });
  }
};

Browsertime.prototype._populateScripts = function(options) {
  var scriptRoots = [path.join(__dirname, 'scripts')];
  if (options.scriptPath) {
    scriptRoots.push(path.resolve(options.scriptPath));
  }

  var self = this;

  scriptRoots.forEach(function(rootPath) {
    fs.readdirSync(rootPath).forEach(function(file) {
      self.scripts.push(require(path.join(rootPath, file)));
    });
  });
};

module.exports = Browsertime;
<commit_msg>Revert timeout handling for now.<commit_after>/**
 * Browsertime (http://www.browsertime.com)
 * Copyright (c) 2014, Peter Hedenskog, Tobias Lidskog
 * and other contributors
 * Released under the Apache 2.0 License
 */
var stats = require('./statistics'),
    fs = require('fs'),
    async = require('async'),
    path = require('path'),
    log = require('winston'),
    url = require('url'),
    util = require('util'),
    EventEmitter = require('async-node-events');

function Browsertime(b) {
  EventEmitter.call(this);

  this.result = [];
  this.scripts = [];
  this.browserVersion = '';
  this.os = '';
  this.browserName = '';
  this.userAgent = '';
  this.browsers = b;
}

util.inherits(Browsertime, EventEmitter);

Browsertime.prototype.fetch = function(options, callback) {

  callback = callback || function() {};

  this._setupDefaults(options);
  this._populateScripts(options);
  this._setupLogging(options);

  var self = this;

  async.series([
    function(cb) {
      self.emit('beforeRun', cb);
    },
    function(cb) {
      self._do(options, cb);
    },
    function(cb) {
      self.emit('afterRun', cb);
    }
  ], function(err, result) {
    callback(err);
  });
};

Browsertime.prototype._do = function(options, cb) {
  var browserRuns = [];
  var self = this;
  for (var i = 1; i <= options.runs; i++) {
    browserRuns.push(self._collectFromTheBrowser(options, i, options.runs));
  }

  async.series(browserRuns,
    function(err, results) {
      if (err) {
        log.error(err.message);
        return cb(err);
      }
      var data = self._getFormattedResult(options);
      self._saveToFile(data, options, cb);
    });
};

Browsertime.prototype._collectFromTheBrowser = function(options, iteration, totalIterations) {
  var self = this;

  return function(callback) {
    async.series([
        function(cb) {
          self.emit('callingBrowser', cb);
        }
      ],
      function(err, results) {
        var driver = self.browsers.getBrowser(options.browser).getDriver(options);

        driver.getCapabilities().then(function(cap) {
          self.browserVersion = cap.get('version');
          self.os = cap.get('platform');
          self.browserName = cap.get('browserName');
        });

        // fetch the URL and wait until the load event ends or we get the time out
        log.info('Fetching ' + options.url + ' (' + iteration + ' of ' + totalIterations + ')');
        driver.get(options.url);
        driver.wait(function() {
          return driver.executeScript('return window.performance.timing.loadEventEnd>0').then(function(
            fetched) {
            return fetched;
          });
        }, 60000, 'The url ' + options.url + ' timed out');

        // lets run all scripts
        var promises = [];
        self.scripts.forEach(function(script) {
          promises.push(driver.executeScript(script));
        });

        var callbacks = [];
        promises.forEach(function(promise) {
          callbacks.push(function(cb) {
            promise.then(function(value) {
              cb(null, value);
            });
          });
        });

        // when we are finished, push the result and stop the browser
        async.parallel(callbacks,
          function(err, results) {
            var eachRun = {};
            results.forEach(function(metric) {
              Object.keys(metric).forEach(function(key) {
                eachRun[key] = metric[key];
              });
            });
            self.result.push(eachRun);
            driver.quit();
            callback();
          });
      });
  };
};

Browsertime.prototype._getFormattedResult = function(options) {
  // fetch timings for each run and make some statistics
  var timings = {};
  this.result.forEach(function(run) {
    stats.setupTimingsStatistics(timings, run);
    stats.setupStatistics(timings, run, 'speedIndex');
    stats.setupStatistics(timings, run, 'firstPaint');
    stats.setupUserTimingsStatistics(timings, run);
  });
  return {
    url: options.url,
    runs: options.runs,
    browserName: this.browserName,
    browserVersion: this.browserVersion,
    platform: this.os,
    userAgent: options.userAgent || this.userAgent,
    windowSize: 'unknown',
    browserTimeVersion: require('../package.json').version,
    statistics: stats.formatStatistics(timings),
    data: this.result
  };
};

Browsertime.prototype._saveToFile = function(data, options, cb) {
  var self = this;

  // lets store the files
  async.parallel([
      function(callback) {
        fs.writeFile(options.filename, JSON.stringify(data), function(err) {
          log.info('Storing ' + options.filename);
          callback(err);
        });
      },
      function(callback) {
        self.emit('savingResults', { data: data }, callback);
      }
    ], cb);
};

Browsertime.prototype._setupDefaults = function(options) {

  options.runs = options.runs || 3;
  options.filename = options.filename || path.join(process.cwd(), url.parse(options.url).hostname + '.json');
  options.seleniumServer = options.seleniumServer || 'http://localhost:4444/wd/hub';
};

Browsertime.prototype._setupLogging = function(options) {
  log.clear();
  log.add(log.transports.File, {
    filename: options.logDir?path.join(options.logDir,'browsertime.log'):'browsertime.log',
    level: 'info',
    json: false
  });

  // we only write to the console if we don't use silent
  if (!options.silent) {
    log.add(log.transports.Console, {
      level: 'info'
    });
  }
};

Browsertime.prototype._populateScripts = function(options) {
  var scriptRoots = [path.join(__dirname, 'scripts')];
  if (options.scriptPath) {
    scriptRoots.push(path.resolve(options.scriptPath));
  }

  var self = this;

  scriptRoots.forEach(function(rootPath) {
    fs.readdirSync(rootPath).forEach(function(file) {
      self.scripts.push(require(path.join(rootPath, file)));
    });
  });
};

module.exports = Browsertime;
<|endoftext|>


<commit_before>'use strict';

var find_options = require('./query');

function storage (collection, ctx) {
  var ObjectID = require('mongodb').ObjectID;

  function create(obj, fn) {
    if (! obj.hasOwnProperty('created_at')){
      obj.created_at = (new Date()).toISOString();
    }
    api().insert(obj, function (err, doc) {
      if (err != null && err.message) {
        console.log('Error inserting the device status object', err.message);
        fn(err.message, null);
        return;
      }
      fn(null, doc.ops);
      ctx.bus.emit('data-received');
    });
  }

  function last(fn) {
    return list({count: 1}, function (err, entries) {
      if (entries && entries.length > 0) {
        fn(err, entries[0]);
      } else {
        fn(err, null);
      }
    });
  }

  function query_for (opts) {
    return find_options(opts, storage.queryOpts);
  }

  function list(opts, fn) {
    // these functions, find, sort, and limit, are used to
    // dynamically configure the request, based on the options we've
    // been given

    // determine sort options
    function sort ( ) {
      return opts && opts.sort || {created_at: -1};
    }

    // configure the limit portion of the current query
    function limit ( ) {
      if (opts && opts.count) {
        return this.limit(parseInt(opts.count));
      }
      return this;
    }

    // handle all the results
    function toArray (err, entries) {
      fn(err, entries);
    }

    // now just stitch them all together
    limit.call(api( )
        .find(query_for(opts))
        .sort(sort( ))
    ).toArray(toArray);
  }

  function remove (opts, fn) {
    return api( ).remove(query_for(opts), fn);
  }

  function api() {
    return ctx.store.collection(collection);
  }

  api.list = list;
  api.create = create;
  api.query_for = query_for;
  api.last = last;
  api.remove = remove;
  api.aggregate = require('./aggregate')({ }, api);
  api.indexedFields = [
    'created_at'
    , 'NSCLIENT_ID'
  ];
  return api;
}

storage.queryOpts = {
  dateField: 'created_at'
};

module.exports = storage;
<commit_msg>Set query options correctly for devicestatus<commit_after>'use strict';

var find_options = require('./query');

function storage (collection, ctx) {
  var ObjectID = require('mongodb').ObjectID;

  function create(obj, fn) {
    if (! obj.hasOwnProperty('created_at')){
      obj.created_at = (new Date()).toISOString();
    }
    api().insert(obj, function (err, doc) {
      if (err != null && err.message) {
        console.log('Error inserting the device status object', err.message);
        fn(err.message, null);
        return;
      }
      fn(null, doc.ops);
      ctx.bus.emit('data-received');
    });
  }

  function last(fn) {
    return list({count: 1}, function (err, entries) {
      if (entries && entries.length > 0) {
        fn(err, entries[0]);
      } else {
        fn(err, null);
      }
    });
  }

  function query_for (opts) {
    return find_options(opts, storage.queryOpts);
  }

  function list(opts, fn) {
    // these functions, find, sort, and limit, are used to
    // dynamically configure the request, based on the options we've
    // been given

    // determine sort options
    function sort ( ) {
      return opts && opts.sort || {created_at: -1};
    }

    // configure the limit portion of the current query
    function limit ( ) {
      if (opts && opts.count) {
        return this.limit(parseInt(opts.count));
      }
      return this;
    }

    // handle all the results
    function toArray (err, entries) {
      fn(err, entries);
    }

    // now just stitch them all together
    limit.call(api( )
        .find(query_for(opts))
        .sort(sort( ))
    ).toArray(toArray);
  }

  function remove (opts, fn) {
    return api( ).remove(query_for(opts), fn);
  }

  function api() {
    return ctx.store.collection(collection);
  }

  api.list = list;
  api.create = create;
  api.query_for = query_for;
  api.last = last;
  api.remove = remove;
  api.aggregate = require('./aggregate')({ }, api);
  api.indexedFields = [
    'created_at'
    , 'NSCLIENT_ID'
  ];
  return api;
}

storage.queryOpts = {
  dateField: 'date'
  , useEpoch: true
};

module.exports = storage;
<|endoftext|>


<commit_before>/**
 *
 *      ioBroker email Adapter
 *
 *      (c) 2014-2016 bluefox <dogafox@gmail.com>
 *
 *      MIT License
 *
 */

var nodemailer;
var utils =   require(__dirname + '/lib/utils'); // Get common adapter utils
//noinspection JSUnresolvedFunction
var adapter = utils.adapter('email');

adapter.on('message', function (obj) {
    //noinspection JSUnresolvedVariable
    if (obj && obj.command === 'send') processMessage(obj);
    processMessages();
});

adapter.on('ready', function () {
    //noinspection JSUnresolvedVariable
    adapter.config.transportOptions.auth.pass = decrypt('Zgfr56gFe87jJOM', adapter.config.transportOptions.auth.pass);
    main();
});

var emailTransport;
var stopTimer       =  null;
var lastMessageTime = 0;
var lastMessageText = '';
function decrypt(key, value) {
    var result = '';
    for (var i = 0; i < value.length; ++i) {
        result += String.fromCharCode(key[i % key.length].charCodeAt(0) ^ value.charCodeAt(i));
    }
    return result;
}

// Terminate adapter after 30 seconds idle
function stop() {
    if (stopTimer) {
        clearTimeout(stopTimer);
        stopTimer = null;
    }

    // Stop only if subscribe mode
    //noinspection JSUnresolvedVariable
    if (adapter.common && adapter.common.mode === 'subscribe') {
        stopTimer = setTimeout(function () {
            stopTimer = null;
            adapter.stop();
        }, 30000);
    }
}

function processMessage(obj) {
    if (!obj || !obj.message) return;

    // filter out double messages
    var json = JSON.stringify(obj.message);
    if (lastMessageTime && lastMessageText === JSON.stringify(obj.message) && new Date().getTime() - lastMessageTime < 1000) {
        adapter.log.debug('Filter out double message [first was for ' + (new Date().getTime() - lastMessageTime) + 'ms]: ' + json);
        return;
    }
    lastMessageTime = new Date().getTime();
    lastMessageText = json;

    if (stopTimer) {
        clearTimeout(stopTimer);
        stopTimer = null;
    }

    if (obj.message.options) {
        var options = JSON.parse(JSON.stringify(obj.message.options));
        delete obj.message.options;
        sendEmail(null, options, obj.message, function (error) {
            if (obj.callback) adapter.sendTo(obj.from, 'send', {error: error}, obj.callback);
        });
    } else {
        emailTransport = sendEmail(emailTransport, adapter.config.transportOptions, obj.message);
    }

    stop();
}

function processMessages() {
    //noinspection JSUnresolvedFunction
    adapter.getMessage(function (err, obj) {
        if (obj) {
            processMessage(obj);
            processMessages();
        }
    });
}

function main() {
    // Adapter is started only if some one writes into "system.adapter.email.X.messagebox" new value
    processMessages();
    stop();
}

function sendEmail(transport, options, message, callback) {
    if (!message) message = {};

    options = options || adapter.config.transportOptions;

    if (!transport) {
        //noinspection JSUnresolvedVariable
        if (!options.host || !options.port) {
            //noinspection JSUnresolvedVariable
            if (options.host    !== undefined) delete options.host;
            //noinspection JSUnresolvedVariable
            if (options.port    !== undefined) delete options.port;
            //noinspection JSUnresolvedVariable
            if (options.secure  !== undefined) delete options.secure;
        } else {
            //noinspection JSUnresolvedVariable
            if (options.service !== undefined) delete options.service;
        }
        //noinspection JSUnresolvedVariable
        if (options.service === 'web.de') {
            //noinspection JSUnresolvedVariable
            options.domains = ['web.de'];
            //noinspection JSUnresolvedVariable
            options.host = 'smtp.web.de';
            //noinspection JSUnresolvedVariable
            options.port = '587';
            //options.tls = {ciphers: 'SSLv3'};
            //noinspection JSUnresolvedVariable
            delete options.service;
        } else if (options.service === 'Office365') {
            //noinspection JSUnresolvedVariable
            options.secureConnection = false;
            //noinspection JSUnresolvedVariable
            options.tls = {ciphers: 'SSLv3'};
            //noinspection JSUnresolvedVariable
            options.domains = ['web.de'];
            //noinspection JSUnresolvedVariable
            options.host = 'smtp.office365.com';
            //noinspection JSUnresolvedVariable
            options.port = '587';
            //noinspection JSUnresolvedVariable
            delete options.service;
        }

        //noinspection JSUnresolvedFunction, JSUnresolvedVariable
        transport = require('nodemailer').createTransport(options);
    }

    if (typeof message !== 'object') message = {text: message};

    //noinspection JSUnresolvedVariable
    message.from =    message.from    || adapter.config.defaults.from;
    //noinspection JSUnresolvedVariable
    message.to =      message.to      || adapter.config.defaults.to;
    //noinspection JSUnresolvedVariable
    message.subject = message.subject || adapter.config.defaults.subject;
    //noinspection JSUnresolvedVariable
    message.text =    message.text    || adapter.config.defaults.text;

    adapter.log.info('Send email: ' + JSON.stringify(message));

    //noinspection JSUnresolvedFunction
    transport.sendMail(message, function (error, info) {
        if (error) {
            adapter.log.error('Error ' + JSON.stringify(error));
            if (callback) callback(error.response || error.message || error.code || JSON.stringify(error));
        } else {
            //noinspection JSUnresolvedVariable
            adapter.log.info('sent to ' + message.to);
            adapter.log.debug('Response: ' + info.response);
            if (callback) callback(null);
        }
        stop();
    });
    return transport;
}<commit_msg>(bluefox) prepare for encoding of the password<commit_after>/**
 *
 *      ioBroker email Adapter
 *
 *      (c) 2014-2016 bluefox <dogafox@gmail.com>
 *
 *      MIT License
 *
 */

var nodemailer;
var utils =   require(__dirname + '/lib/utils'); // Get common adapter utils
//noinspection JSUnresolvedFunction
var adapter = utils.adapter('email');

adapter.on('message', function (obj) {
    //noinspection JSUnresolvedVariable
    if (obj && obj.command === 'send') processMessage(obj);
    processMessages();
});

adapter.on('ready', function () {
    // it must be like this
    /*
    adapter.getForeignObject('system.config', function (err, obj) {
        if (obj && obj.native && obj.native.secret) {
            //noinspection JSUnresolvedVariable
            adapter.config.transportOptions.auth.pass = decrypt(obj.native.secret, adapter.config.transportOptions.auth.pass);
        } else {
            //noinspection JSUnresolvedVariable
            adapter.config.transportOptions.auth.pass = decrypt('Zgfr56gFe87jJOM', adapter.config.transportOptions.auth.pass);
        }
        main();
    });
    */

    //noinspection JSUnresolvedVariable
    adapter.config.transportOptions.auth.pass = decrypt('Zgfr56gFe87jJOM', adapter.config.transportOptions.auth.pass);
    main();
});

var emailTransport;
var stopTimer       =  null;
var lastMessageTime = 0;
var lastMessageText = '';
function decrypt(key, value) {
    var result = '';
    for (var i = 0; i < value.length; ++i) {
        result += String.fromCharCode(key[i % key.length].charCodeAt(0) ^ value.charCodeAt(i));
    }
    return result;
}

// Terminate adapter after 30 seconds idle
function stop() {
    if (stopTimer) {
        clearTimeout(stopTimer);
        stopTimer = null;
    }

    // Stop only if subscribe mode
    //noinspection JSUnresolvedVariable
    if (adapter.common && adapter.common.mode === 'subscribe') {
        stopTimer = setTimeout(function () {
            stopTimer = null;
            adapter.stop();
        }, 30000);
    }
}

function processMessage(obj) {
    if (!obj || !obj.message) return;

    // filter out double messages
    var json = JSON.stringify(obj.message);
    if (lastMessageTime && lastMessageText === JSON.stringify(obj.message) && new Date().getTime() - lastMessageTime < 1000) {
        adapter.log.debug('Filter out double message [first was for ' + (new Date().getTime() - lastMessageTime) + 'ms]: ' + json);
        return;
    }
    lastMessageTime = new Date().getTime();
    lastMessageText = json;

    if (stopTimer) {
        clearTimeout(stopTimer);
        stopTimer = null;
    }

    if (obj.message.options) {
        var options = JSON.parse(JSON.stringify(obj.message.options));
        delete obj.message.options;
        sendEmail(null, options, obj.message, function (error) {
            if (obj.callback) adapter.sendTo(obj.from, 'send', {error: error}, obj.callback);
        });
    } else {
        emailTransport = sendEmail(emailTransport, adapter.config.transportOptions, obj.message);
    }

    stop();
}

function processMessages() {
    //noinspection JSUnresolvedFunction
    adapter.getMessage(function (err, obj) {
        if (obj) {
            processMessage(obj);
            processMessages();
        }
    });
}

function main() {
    // Adapter is started only if some one writes into "system.adapter.email.X.messagebox" new value
    processMessages();
    stop();
}

function sendEmail(transport, options, message, callback) {
    if (!message) message = {};

    options = options || adapter.config.transportOptions;

    if (!transport) {
        //noinspection JSUnresolvedVariable
        if (!options.host || !options.port) {
            //noinspection JSUnresolvedVariable
            if (options.host    !== undefined) delete options.host;
            //noinspection JSUnresolvedVariable
            if (options.port    !== undefined) delete options.port;
            //noinspection JSUnresolvedVariable
            if (options.secure  !== undefined) delete options.secure;
        } else {
            //noinspection JSUnresolvedVariable
            if (options.service !== undefined) delete options.service;
        }
        //noinspection JSUnresolvedVariable
        if (options.service === 'web.de') {
            //noinspection JSUnresolvedVariable
            options.domains = ['web.de'];
            //noinspection JSUnresolvedVariable
            options.host = 'smtp.web.de';
            //noinspection JSUnresolvedVariable
            options.port = '587';
            //options.tls = {ciphers: 'SSLv3'};
            //noinspection JSUnresolvedVariable
            delete options.service;
        } else if (options.service === 'Office365') {
            //noinspection JSUnresolvedVariable
            options.secureConnection = false;
            //noinspection JSUnresolvedVariable
            options.tls = {ciphers: 'SSLv3'};
            //noinspection JSUnresolvedVariable
            options.domains = ['web.de'];
            //noinspection JSUnresolvedVariable
            options.host = 'smtp.office365.com';
            //noinspection JSUnresolvedVariable
            options.port = '587';
            //noinspection JSUnresolvedVariable
            delete options.service;
        }

        //noinspection JSUnresolvedFunction, JSUnresolvedVariable
        transport = require('nodemailer').createTransport(options);
    }

    if (typeof message !== 'object') message = {text: message};

    //noinspection JSUnresolvedVariable
    message.from =    message.from    || adapter.config.defaults.from;
    //noinspection JSUnresolvedVariable
    message.to =      message.to      || adapter.config.defaults.to;
    //noinspection JSUnresolvedVariable
    message.subject = message.subject || adapter.config.defaults.subject;
    //noinspection JSUnresolvedVariable
    message.text =    message.text    || adapter.config.defaults.text;

    adapter.log.info('Send email: ' + JSON.stringify(message));

    //noinspection JSUnresolvedFunction
    transport.sendMail(message, function (error, info) {
        if (error) {
            adapter.log.error('Error ' + JSON.stringify(error));
            if (callback) callback(error.response || error.message || error.code || JSON.stringify(error));
        } else {
            //noinspection JSUnresolvedVariable
            adapter.log.info('sent to ' + message.to);
            adapter.log.debug('Response: ' + info.response);
            if (callback) callback(null);
        }
        stop();
    });
    return transport;
}<|endoftext|>