<commit_before>'use strict';
var BaseEvent = require('broker').events.ApplicationEvent;
var logger = require('hoist-logger');
var util = require('util');
var BBPromise = require('bluebird');
var Model = require('hoist-model');
var Session = Model.Session;
var AppUser = Model.AppUser;
var Organisation = Model.Organisation;
var Application = Model.Application;
var path = require('path');
var _ = require('lodash');
var kueProxy = require('../kue_proxy');
var moment = require('moment');

function ApplicationEvent(properties) {
  BaseEvent.call(this, properties);
  _.bindAll(this);
}

util.inherits(ApplicationEvent, BaseEvent);

ApplicationEvent.QueueName = 'application_event';
ApplicationEvent.prototype.getModuleDescription = function (moduleName, application) {
  return BBPromise.try(function () {
    var module = null;
    var settings = application.settings[this.environment];
    if (settings) {
      module = _.find(settings.modules, function (moduleDesc) {
        return moduleDesc.name === moduleName;
      });
    }
    return module;
  }, [], this);
};
ApplicationEvent.prototype.getContext = function (application) {
  var context = {};
  var pipeline = [];
  context.applicationId = this.applicationId;
  context.environment = this.environment;
  if (this.sessionId) {
    pipeline.push(Session.findOneAsync({
        _id: this.sessionId
      })
      .then(function (session) {
        if (session) {
          context.sessionId = session._id;
          if (session.appUser) {
            return AppUser.findOneAsync({
              _id: session.appUser
            }).then(function (appUser) {
              if (appUser) {
                context.user = appUser.toObject();
              }
            });
          }
        }
      }));
  }

  context.application = application.toObject();

  return BBPromise.all(pipeline).then(function () {
    return context;
  });
};
ApplicationEvent.prototype.getEventDescription = function (application) {
  var environment = this.environment || 'live';
  var settings = application.settings[environment];
  return settings.on[this.eventName];
};
ApplicationEvent.prototype.process = function (callback) {
  var log = new Model.ExecutionLogEvent({
    application: this.applicationId,
    environment: this.environment,
    eventId: this.eventId,
    correlationId: this.correlationId,
    moduleName: this.eventName,
    message: 'event ' + this.eventName + ' started processing'
  });
  log.saveAsync();
  return Application.findOneAsync({
      _id: this.applicationId
    })
    .bind(this)
    .then(function (application) {
      return Organisation.findOneAsync({
        _id: application.organisation
      }).bind(this).then(function (org) {
        var eventDescription = this.getEventDescription(application);
        if (!eventDescription) {
          this.emit('done');
          return;
        }
        var modules = eventDescription.modules;
        if (!modules || modules.length < 1) {
          this.emit('done');
          return;
        }
        this.timeouts = {};
        this.pingInterval = setInterval(_.bind(function () {
          logger.debug('emitting ping');
          this.emit('ping');
        }, this), 30000);
        this.executionCount = modules.length;
        return BBPromise.all(_.map(modules, _.bind(function (moduleName) {
            return this.getModuleDescription(moduleName, application);
          }, this)))
          .bind(this)
          .then(function (moduleDescriptions) {
            var lastDeployTimestamp = moment(application.lastDeploy[this.environment]);
            var applicationDeployFolder = path.join(org.gitFolder, application.gitRepo, lastDeployTimestamp.format('X'));
            return BBPromise.all(_.map(moduleDescriptions, _.bind(function (moduleDescription) {
              return this.getContext(application)
                .bind(this)
                .then(function (context) {
                  var log = new Model.ExecutionLogEvent({
                    application: this.applicationId,
                    environment: this.environment,
                    eventId: this.eventId,
                    correlationId: this.correlationId,
                    moduleName: moduleDescription.name,
                    message: 'module ' + moduleDescription.name + ' queued'
                  });
                  log.saveAsync();
                  var jobData = {
                    application: context.application,
                    user: context.user,
                    environment: context.environment,
                    event: this.toJSON(),
                    applicationPath: applicationDeployFolder,
                    modulePath: moduleDescription.src,
                    moduleName: moduleDescription.name,
                    module: moduleDescription,
                    title: 'running module ' + moduleDescription.name
                  };
                  kueProxy.get().create('RunModule', jobData)
                    .save(_.bind(function (err) {
                      if (err) {
                        logger.alert(err);
                        logger.error(err, 'unable to save execution job');
                      }
                    }, this));

                });
            }, this)));

          });

      });
    }).then(function () {
      var log = new Model.ExecutionLogEvent({
        application: this.applicationId,
        environment: this.environment,
        moduleName: this.eventName,
        eventId: this.eventId,
        correlationId: this.correlationId,
        message: 'event ' + this.eventName + ' processed'
      });
      log.saveAsync();
      clearInterval(this.pingInterval);
      this.emit('done');
    }).nodeify(callback);
};
module.exports = ApplicationEvent;
<commit_msg>ensure save is called on eventlog<commit_after>'use strict';
var BaseEvent = require('broker').events.ApplicationEvent;
var logger = require('hoist-logger');
var util = require('util');
var BBPromise = require('bluebird');
var Model = require('hoist-model');
var Session = Model.Session;
var AppUser = Model.AppUser;
var Organisation = Model.Organisation;
var Application = Model.Application;
var path = require('path');
var _ = require('lodash');
var kueProxy = require('../kue_proxy');
var moment = require('moment');

function ApplicationEvent(properties) {
  BaseEvent.call(this, properties);
  _.bindAll(this);
}

util.inherits(ApplicationEvent, BaseEvent);

ApplicationEvent.QueueName = 'application_event';
ApplicationEvent.prototype.getModuleDescription = function (moduleName, application) {
  return BBPromise.try(function () {
    var module = null;
    var settings = application.settings[this.environment];
    if (settings) {
      module = _.find(settings.modules, function (moduleDesc) {
        return moduleDesc.name === moduleName;
      });
    }
    return module;
  }, [], this);
};
ApplicationEvent.prototype.getContext = function (application) {
  var context = {};
  var pipeline = [];
  context.applicationId = this.applicationId;
  context.environment = this.environment;
  if (this.sessionId) {
    pipeline.push(Session.findOneAsync({
        _id: this.sessionId
      })
      .then(function (session) {
        if (session) {
          context.sessionId = session._id;
          if (session.appUser) {
            return AppUser.findOneAsync({
              _id: session.appUser
            }).then(function (appUser) {
              if (appUser) {
                context.user = appUser.toObject();
              }
            });
          }
        }
      }));
  }

  context.application = application.toObject();

  return BBPromise.all(pipeline).then(function () {
    return context;
  });
};
ApplicationEvent.prototype.getEventDescription = function (application) {
  var environment = this.environment || 'live';
  var settings = application.settings[environment];
  return settings.on[this.eventName];
};
ApplicationEvent.prototype.process = function (callback) {
  var log = new Model.ExecutionLogEvent({
    application: this.applicationId,
    environment: this.environment,
    eventId: this.eventId,
    correlationId: this.correlationId,
    moduleName: this.eventName,
    message: 'event ' + this.eventName + ' started processing'
  });
  log.saveAsync();
  return Application.findOneAsync({
      _id: this.applicationId
    })
    .bind(this)
    .then(function (application) {
      return Organisation.findOneAsync({
        _id: application.organisation
      }).bind(this).then(function (org) {
        var eventDescription = this.getEventDescription(application);
        if (!eventDescription) {
          this.emit('done');
          return;
        }
        var modules = eventDescription.modules;
        if (!modules || modules.length < 1) {
          this.emit('done');
          return;
        }
        this.timeouts = {};
        this.pingInterval = setInterval(_.bind(function () {
          logger.debug('emitting ping');
          this.emit('ping');
        }, this), 30000);
        this.executionCount = modules.length;
        return BBPromise.all(_.map(modules, _.bind(function (moduleName) {
            return this.getModuleDescription(moduleName, application);
          }, this)))
          .bind(this)
          .then(function (moduleDescriptions) {
            var lastDeployTimestamp = moment(application.lastDeploy[this.environment]);
            var applicationDeployFolder = path.join(org.gitFolder, application.gitRepo, lastDeployTimestamp.format('X'));
            return BBPromise.all(_.map(moduleDescriptions, _.bind(function (moduleDescription) {
              return this.getContext(application)
                .bind(this)
                .then(function (context) {
                  var log = new Model.ExecutionLogEvent({
                    application: this.applicationId,
                    environment: this.environment,
                    eventId: this.eventId,
                    correlationId: this.correlationId,
                    moduleName: moduleDescription.name,
                    message: 'module ' + moduleDescription.name + ' queued'
                  });

                  var jobData = {
                    application: context.application,
                    user: context.user,
                    environment: context.environment,
                    event: this.toJSON(),
                    applicationPath: applicationDeployFolder,
                    modulePath: moduleDescription.src,
                    moduleName: moduleDescription.name,
                    module: moduleDescription,
                    title: 'running module ' + moduleDescription.name
                  };
                  var job = kueProxy.get().create('RunModule', jobData);
                  return BBPromise.promisify(job.save, job)().then(function () {
                    return log.saveAsync();
                  });
                });
            }, this)));

          });

      });
    }).then(function () {
      var log = new Model.ExecutionLogEvent({
        application: this.applicationId,
        environment: this.environment,
        moduleName: this.eventName,
        eventId: this.eventId,
        correlationId: this.correlationId,
        message: 'event ' + this.eventName + ' processed'
      });
      log.saveAsync();
      clearInterval(this.pingInterval);
      this.emit('done');
    }).nodeify(callback);
};
module.exports = ApplicationEvent;
<|endoftext|>


<commit_before>/**
 * express-restify-mongoose.js
 *
 * Copyright (C) 2013 by Florian Holzapfel
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the 'Software'), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 **/
var util = require('util');

function filterjson(json, excludedkeys) {
    var excludedarr = excludedkeys.split(',');
    for (var i = 0; i < json.length; ++i) {
        for (var j = 0; j < excludedarr.length; ++j) {
            delete (json[i][excludedarr[j]]);
        }
    }
    return json;
}

function filterItem(item, model, excludedkeys) {
    // just deleting the excluded keys from item does
    // not modify the object. therefore we build a copy
    var excludedarr = excludedkeys.split(',');
    var it = {};

    for (var key in item) {
        if ((model.schema.options.versionKey &&
            key === model.schema.options.versionKey) ||
            key === '_id') {
            it[key] = item[key];
        } else if (model.schema.paths.hasOwnProperty(key)) {
            if (excludedarr.indexOf(key) === -1) {
                it[key] = item[key];
            }
        }
    }
    return it;
}

function filterItems(items, model, excludedKeys) {
    return items.map(function (item) {
        return filterItem(item, model, excludedKeys);
    });
}

function outputExpress(res, result) {
    res.type('json');
    res.send(JSON.stringify(result));
}

function outputRestify(res, result) {
    res.send(result);
}

var restify = function (app, model, options) {
    var postProcess, exclude, lean,
        usingExpress = true,
        queryOptions = {
            protected: ['skip', 'limit', 'sort', 'populate', 'select', 'lean'],
            current: {}
        };

    options         = options || {};
    options.prefix  = options.prefix || '/api';
    options.version = options.version || '/v1';
    postProcess     = options.postProcess || function () {};
    exclude         = options.exclude;
    lean            = typeof options.lean === 'undefined' ? true : options.lean;

    if (options.plural !== false) {
        options.plural = true;
    }

    if (options.middleware) {
        if (!options.middleware instanceof Array) {
            var m = options.middleware;
            options.middleware = [ m ];
        }
    } else {
        options.middleware = [];
    }

    function cleanQuery(req, res, next) {
        queryOptions.current = {};
        for (var key in req.query) {
            if (!model.schema.paths.hasOwnProperty(key)) {
                if (queryOptions.protected.indexOf(key) !== -1) {
                    queryOptions.current[key] = req.query[key];
                }
                delete req.query[key];
            }
        }
        next();
    }

    options.middleware.unshift(cleanQuery);

    var outputFn = options.restify ? outputRestify : outputExpress;
    app.delete = app.del;

    var apiUri = options.plural === true ? '%s%s/%ss' : '%s%s/%s';
    var modelName = options.lowercase === true ? model.modelName.toLowerCase()
                        : model.modelName;

    var uri_items = util.format(apiUri, options.prefix, options.version,
        modelName);
    var uri_item = util.format(apiUri + '/:id', options.prefix, options.version,
        modelName);
    var uri_count = util.format(apiUri + '/count', options.prefix,
        options.version, modelName);

    function buildQuery(query, options) {
        var excludedarr = exclude ? exclude.split(',') : [];

        var arr, i, re;
        for (var key in options) {
            if (excludedarr.indexOf(key) !== -1) {
                // caller tries to query for excluded keys. for security
                // reasons, we will skip the first -1 objects (to provoke
                // an error) and immediately return
                return query.skip(-1);
            }

            query.where(key);
            var value = options[key];

            if ('~' === value[0]) {
                re = new RegExp(value.substring(1), 'i');
                query.where(key).regex(re);
            } else if ('>' === value[0]) {
                if ('=' === value[1]) {
                    query.gte(value.substr(2));
                } else {
                    query.gt(value.substr(1));
                }
            } else if ('<' === value[0]) {
                if ('=' === value[1]) {
                    query.lte(value.substr(2));
                } else {
                    query.lt(value.substr(1));
                }
            } else {
                query.equals(value);
            }
        }

        if (queryOptions.current.skip) {
            query.skip(queryOptions.current.skip);
        }
        if (queryOptions.current.limit) {
            query.limit(queryOptions.current.limit);
        }
        if (queryOptions.current.sort) {
            query.sort(queryOptions.current.sort);
        }
        if (queryOptions.current.populate) {
            arr = queryOptions.current.populate.split(',');
            for (i = 0; i < arr.length; ++i) {
                query = query.populate(arr[i]);
            }
        }
        if (queryOptions.current.select) {
            var selectObj = {};
            if (queryOptions.current.select) {
                arr = queryOptions.current.select.split(',');
                for (i = 0; i < arr.length; ++i) {
                    selectObj[arr[i]] = 1;
                }
            }
            query = query.select(selectObj);
        }
        return query;
    }

    function ensureContentType(req, res, next) {
        var ct = req.headers['content-type'];
        if (-1 === ct.indexOf('application/json')) {
            res.send(400, 'Bad request');
        } else {
            next();
        }
    }

    function createObject(req, res, next) {
        if (model.schema.options._id)
          delete req.body._id;
        if (model.schema.options.versionKey) {
            delete req.body[model.schema.options.versionKey];
        }

        var key, path;

        if (Array.isArray(req.body)) {
            for (var i = 0; i < req.body.length; ++i) {
                for (key in req.body[i]) {
                    path = model.schema.path(key);
                    if ((path.instance === 'ObjectID') &&
                        (typeof req.body[i][key] === 'object')) {
                        req.body[i][key] = req.body[i][key]._id;
                    }
                }
            }
        } else {
            for (key in req.body) {
                path = model.schema.path(key);
                if (typeof path === 'undefined') {
                    continue;
                }
                if ((path.instance === 'ObjectID') &&
                    (typeof req.body[key] === 'object')) {
                    req.body[key] = req.body[key]._id;
                }
            }
        }

        model.create(req.body, function (err, item) {
            if (err) {
                res.setHeader('Content-Type', 'application/json');
                res.send(400, JSON.stringify(err));
            } else {
                var result = null;

                if (Array.isArray(req.body)) {
                    var items = Array.prototype.slice.call(arguments, 1);

                    if (exclude) {
                        result = [];
                        for (var i = 0; i < items.length; ++i) {
                            result.push(filterItem(items[i], model, exclude));
                        }
                    } else {
                        result = items;
                    }
                } else {
                    result = exclude ? filterItem(item, model, exclude) : item;
                }

                outputFn(res, result);
                next();
            }
        });
    }

    function modifyObject(req, res, next) {
        delete req.body._id;
        if (model.schema.options.versionKey) {
            delete req.body[model.schema.options.versionKey];
        }

        for (var key in req.body) {
            var path = model.schema.path(key);
            if (typeof path === 'undefined') {
                continue;
            }
            if ((path.instance === 'ObjectID') &&
               (typeof req.body[key] === 'object')) {
                req.body[key] = req.body[key]._id;
            }
        }

        model.findOneAndUpdate({ _id: req.params.id }, req.body, {},
            function (err, item) {
                if (err) {
                    res.send(404);
                } else {
                    if (exclude) {
                        item = filterItem(item, model, exclude);
                    }
                    outputFn(res, item);
                    next();
                }
            });
    }

    var write_middleware = options.middleware.slice(0);
    write_middleware.push(ensureContentType);

    app.get(uri_items, options.middleware, function (req, res, next) {
        buildQuery(model.find(), req.query).lean(lean)
        .exec(function (err, items) {
            if (err) {
                res.send(400, 'Bad request');
            } else {
                if (exclude) {
                    items = lean ? filterjson(items, exclude) :
                    filterItems(items, model, exclude);
                }
                outputFn(res, items);
                next();
            }
        });
    }, postProcess);

    app.get(uri_count, options.middleware, function (req, res, next) {
        buildQuery(model.count(), req.query).exec(function (err, count) {
            if (err) {
                res.send(400, 'Bad request');
            } else {
                outputFn(res, { count: count });
                next();
            }
        });
    }, postProcess);

    app.post(uri_items, write_middleware, createObject, postProcess);
    app.put(uri_items, write_middleware, createObject, postProcess);

    // TODO: reconsider this function
    app.delete(uri_items, options.middleware, function (req, res, next) {
        buildQuery(model.find(), req.query).remove(function (err) {
            if (err) {
                res.send(400, 'Bad request');
            } else {
                res.send(200);
                next();
            }
        });
    }, postProcess);

    app.get(uri_item, options.middleware, function (req, res, next) {
        buildQuery(model.findById(req.params.id), req.query)
            .findOne(function (err, item) {
            if (err || !item) {
                res.send(404);
            } else {
                if (exclude) {
                    item = filterItem(item, model, exclude);
                }
                outputFn(res, item);
                next();
            }
        });
    }, postProcess);

    // TODO: POST (create) doesn't make sense here
    app.post(uri_item, write_middleware, modifyObject, postProcess);

    app.put(uri_item, write_middleware, modifyObject, postProcess);

    app.delete(uri_item, options.middleware, function (req, res, next) {
        model.remove({ _id: req.params.id }, function (err) {
            if (err) {
                res.send(404);
            } else {
                res.send(200);
                next();
            }
        });
    }, postProcess);
};

module.exports.serve = restify;
<commit_msg>FIX: jshint fails, travis ci test broken<commit_after>/**
 * express-restify-mongoose.js
 *
 * Copyright (C) 2013 by Florian Holzapfel
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the 'Software'), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 **/
var util = require('util');

function filterjson(json, excludedkeys) {
    var excludedarr = excludedkeys.split(',');
    for (var i = 0; i < json.length; ++i) {
        for (var j = 0; j < excludedarr.length; ++j) {
            delete (json[i][excludedarr[j]]);
        }
    }
    return json;
}

function filterItem(item, model, excludedkeys) {
    // just deleting the excluded keys from item does
    // not modify the object. therefore we build a copy
    var excludedarr = excludedkeys.split(',');
    var it = {};

    for (var key in item) {
        if ((model.schema.options.versionKey &&
            key === model.schema.options.versionKey) ||
            key === '_id') {
            it[key] = item[key];
        } else if (model.schema.paths.hasOwnProperty(key)) {
            if (excludedarr.indexOf(key) === -1) {
                it[key] = item[key];
            }
        }
    }
    return it;
}

function filterItems(items, model, excludedKeys) {
    return items.map(function (item) {
        return filterItem(item, model, excludedKeys);
    });
}

function outputExpress(res, result) {
    res.type('json');
    res.send(JSON.stringify(result));
}

function outputRestify(res, result) {
    res.send(result);
}

var restify = function (app, model, options) {
    var postProcess, exclude, lean,
        usingExpress = true,
        queryOptions = {
            protected: ['skip', 'limit', 'sort', 'populate', 'select', 'lean'],
            current: {}
        };

    options         = options || {};
    options.prefix  = options.prefix || '/api';
    options.version = options.version || '/v1';
    postProcess     = options.postProcess || function () {};
    exclude         = options.exclude;
    lean            = typeof options.lean === 'undefined' ? true : options.lean;

    if (options.plural !== false) {
        options.plural = true;
    }

    if (options.middleware) {
        if (!options.middleware instanceof Array) {
            var m = options.middleware;
            options.middleware = [ m ];
        }
    } else {
        options.middleware = [];
    }

    function cleanQuery(req, res, next) {
        queryOptions.current = {};
        for (var key in req.query) {
            if (!model.schema.paths.hasOwnProperty(key)) {
                if (queryOptions.protected.indexOf(key) !== -1) {
                    queryOptions.current[key] = req.query[key];
                }
                delete req.query[key];
            }
        }
        next();
    }

    options.middleware.unshift(cleanQuery);

    var outputFn = options.restify ? outputRestify : outputExpress;
    app.delete = app.del;

    var apiUri = options.plural === true ? '%s%s/%ss' : '%s%s/%s';
    var modelName = options.lowercase === true ? model.modelName.toLowerCase()
                        : model.modelName;

    var uri_items = util.format(apiUri, options.prefix, options.version,
        modelName);
    var uri_item = util.format(apiUri + '/:id', options.prefix, options.version,
        modelName);
    var uri_count = util.format(apiUri + '/count', options.prefix,
        options.version, modelName);

    function buildQuery(query, options) {
        var excludedarr = exclude ? exclude.split(',') : [];

        var arr, i, re;
        for (var key in options) {
            if (excludedarr.indexOf(key) !== -1) {
                // caller tries to query for excluded keys. for security
                // reasons, we will skip the first -1 objects (to provoke
                // an error) and immediately return
                return query.skip(-1);
            }

            query.where(key);
            var value = options[key];

            if ('~' === value[0]) {
                re = new RegExp(value.substring(1), 'i');
                query.where(key).regex(re);
            } else if ('>' === value[0]) {
                if ('=' === value[1]) {
                    query.gte(value.substr(2));
                } else {
                    query.gt(value.substr(1));
                }
            } else if ('<' === value[0]) {
                if ('=' === value[1]) {
                    query.lte(value.substr(2));
                } else {
                    query.lt(value.substr(1));
                }
            } else {
                query.equals(value);
            }
        }

        if (queryOptions.current.skip) {
            query.skip(queryOptions.current.skip);
        }
        if (queryOptions.current.limit) {
            query.limit(queryOptions.current.limit);
        }
        if (queryOptions.current.sort) {
            query.sort(queryOptions.current.sort);
        }
        if (queryOptions.current.populate) {
            arr = queryOptions.current.populate.split(',');
            for (i = 0; i < arr.length; ++i) {
                query = query.populate(arr[i]);
            }
        }
        if (queryOptions.current.select) {
            var selectObj = {};
            if (queryOptions.current.select) {
                arr = queryOptions.current.select.split(',');
                for (i = 0; i < arr.length; ++i) {
                    selectObj[arr[i]] = 1;
                }
            }
            query = query.select(selectObj);
        }
        return query;
    }

    function ensureContentType(req, res, next) {
        var ct = req.headers['content-type'];
        if (-1 === ct.indexOf('application/json')) {
            res.send(400, 'Bad request');
        } else {
            next();
        }
    }

    function createObject(req, res, next) {
        if (model.schema.options._id) {
            delete req.body._id;
        }
        if (model.schema.options.versionKey) {
            delete req.body[model.schema.options.versionKey];
        }

        var key, path;

        if (Array.isArray(req.body)) {
            for (var i = 0; i < req.body.length; ++i) {
                for (key in req.body[i]) {
                    path = model.schema.path(key);
                    if ((path.instance === 'ObjectID') &&
                        (typeof req.body[i][key] === 'object')) {
                        req.body[i][key] = req.body[i][key]._id;
                    }
                }
            }
        } else {
            for (key in req.body) {
                path = model.schema.path(key);
                if (typeof path === 'undefined') {
                    continue;
                }
                if ((path.instance === 'ObjectID') &&
                    (typeof req.body[key] === 'object')) {
                    req.body[key] = req.body[key]._id;
                }
            }
        }

        model.create(req.body, function (err, item) {
            if (err) {
                res.setHeader('Content-Type', 'application/json');
                res.send(400, JSON.stringify(err));
            } else {
                var result = null;

                if (Array.isArray(req.body)) {
                    var items = Array.prototype.slice.call(arguments, 1);

                    if (exclude) {
                        result = [];
                        for (var i = 0; i < items.length; ++i) {
                            result.push(filterItem(items[i], model, exclude));
                        }
                    } else {
                        result = items;
                    }
                } else {
                    result = exclude ? filterItem(item, model, exclude) : item;
                }

                outputFn(res, result);
                next();
            }
        });
    }

    function modifyObject(req, res, next) {
        delete req.body._id;
        if (model.schema.options.versionKey) {
            delete req.body[model.schema.options.versionKey];
        }

        for (var key in req.body) {
            var path = model.schema.path(key);
            if (typeof path === 'undefined') {
                continue;
            }
            if ((path.instance === 'ObjectID') &&
               (typeof req.body[key] === 'object')) {
                req.body[key] = req.body[key]._id;
            }
        }

        model.findOneAndUpdate({ _id: req.params.id }, req.body, {},
            function (err, item) {
                if (err) {
                    res.send(404);
                } else {
                    if (exclude) {
                        item = filterItem(item, model, exclude);
                    }
                    outputFn(res, item);
                    next();
                }
            });
    }

    var write_middleware = options.middleware.slice(0);
    write_middleware.push(ensureContentType);

    app.get(uri_items, options.middleware, function (req, res, next) {
        buildQuery(model.find(), req.query).lean(lean)
        .exec(function (err, items) {
            if (err) {
                res.send(400, 'Bad request');
            } else {
                if (exclude) {
                    items = lean ? filterjson(items, exclude) :
                    filterItems(items, model, exclude);
                }
                outputFn(res, items);
                next();
            }
        });
    }, postProcess);

    app.get(uri_count, options.middleware, function (req, res, next) {
        buildQuery(model.count(), req.query).exec(function (err, count) {
            if (err) {
                res.send(400, 'Bad request');
            } else {
                outputFn(res, { count: count });
                next();
            }
        });
    }, postProcess);

    app.post(uri_items, write_middleware, createObject, postProcess);
    app.put(uri_items, write_middleware, createObject, postProcess);

    // TODO: reconsider this function
    app.delete(uri_items, options.middleware, function (req, res, next) {
        buildQuery(model.find(), req.query).remove(function (err) {
            if (err) {
                res.send(400, 'Bad request');
            } else {
                res.send(200);
                next();
            }
        });
    }, postProcess);

    app.get(uri_item, options.middleware, function (req, res, next) {
        buildQuery(model.findById(req.params.id), req.query)
            .findOne(function (err, item) {
            if (err || !item) {
                res.send(404);
            } else {
                if (exclude) {
                    item = filterItem(item, model, exclude);
                }
                outputFn(res, item);
                next();
            }
        });
    }, postProcess);

    // TODO: POST (create) doesn't make sense here
    app.post(uri_item, write_middleware, modifyObject, postProcess);

    app.put(uri_item, write_middleware, modifyObject, postProcess);

    app.delete(uri_item, options.middleware, function (req, res, next) {
        model.remove({ _id: req.params.id }, function (err) {
            if (err) {
                res.send(404);
            } else {
                res.send(200);
                next();
            }
        });
    }, postProcess);
};

module.exports.serve = restify;
<|endoftext|>


<commit_before>const classcode = require('./makecases').classcode
const classname = require('./makecases').classname

// turn all types that are 'array' in apib into scala List[MyType]
function fixArrayReferences(result, input, options) {
  const arraymap = arrays(input, options)
  for (const [tname, aname] of arraymap) {
    var re = new RegExp(tname,"g");
    result = result.replace(re, aname)
  }
  return result
}

//
// generator functions to create scala code
//

// create each case class
function* classes(input, options) {
  if (!input.content[0].content) throw new Error("bad input")
  for (const item of input.content[0].content) {
    if (item.element !== 'dataStructure') throw new Error("not a datastructure: " + JSON.stringify(item))
    const name = classname(item)
    if (item.content[0].element === 'object') {
      yield [name, classcode(name, item, options)]
    }
  }
}

// old-name/new-name map for renames for all the array objects to be List[MyType]
function* arrays(input, options) {
  if (!input.content[0].content) throw new Error("bad input")
  for (const item of input.content[0].content) {
    if (item.element !== 'dataStructure') throw new Error("not a datastructure: " + JSON.stringify(item))
    const name = classname(item)
    if (item.content[0].element === 'array') {
      const tpe = item.content[0].content[0].element
      yield [name, `List[${tpe}]`]
    }
  }
}

exports.getConfig = function () {
  return {
    formats: ['1A'],
    options: [
      { //remove this string from the names of types, ie: Schema suffix
        name: 'trimname',
        description: 'remove this string from all type names, ie: MyObjectSchema becoms MyObject',
        default: 'Schema'
      },
      { //lookup as themeSuperclass
        name: 'superclass',
        description: 'case classes extend this abstract class',
        default: 'MyCase'
      },
      { //lookup as themeDoubles
        name: 'doubles',
        description: 'a comma separated list of keys that should map to double instead of int',
        default: ''
      }
    ]
  };
}

exports.render = function (input, options, done) {

  // prepend with abstract class
  const result = [`abstract class ${options.themeSuperclass}\n`]

  // generate case class text
  const code = classes(input, options)
  for (const [name, scala] of code) {
    result.push(`\n${scala}\n`)
  }

  // turn refs to array in apib into List[MyType]
  let resultStr = fixArrayReferences(result.join(''), input, options)

  // remove type suffixes from apip files
  var re1 = new RegExp(options.themeTrimname,"g");
  resultStr = resultStr.replace(re1, '')

  done(null, resultStr)
};

<commit_msg>refactor<commit_after>const classcode = require('./makecases').classcode
const classname = require('./makecases').classname

// turn all types that are 'array' in apib into scala List[MyType]
function fixArrayReferences(result, input, options) {
  const arraymap = arrays(input, options)
  for (const [tname, aname] of arraymap) {
    var re = new RegExp(tname,"g");
    result = result.replace(re, aname)
  }
  return result
}

//
// generator functions to create scala code
//

// create each case class
function* classes(input, options) {
  if (!input.content[0].content) throw new Error("bad input")
  for (const item of input.content[0].content) {
    if (item.element !== 'dataStructure') throw new Error("not a datastructure: " + JSON.stringify(item))
    if (item.content[0].element === 'object') {
      const name = classname(item)
      yield [name, classcode(name, item, options)]
    }
  }
}

// old-name/new-name map for renames for all the array objects to be List[MyType]
function* arrays(input, options) {
  if (!input.content[0].content) throw new Error("bad input")
  for (const item of input.content[0].content) {
    if (item.element !== 'dataStructure') throw new Error("not a datastructure: " + JSON.stringify(item))
    if (item.content[0].element === 'array') {
      const name = classname(item)
      const tpe = item.content[0].content[0].element
      yield [name, `List[${tpe}]`]
    }
  }
}

exports.getConfig = function () {
  return {
    formats: ['1A'],
    options: [
      { //remove this string from the names of types, ie: Schema suffix
        name: 'trimname',
        description: 'remove this string from all type names, ie: MyObjectSchema becoms MyObject',
        default: 'Schema'
      },
      { //lookup as themeSuperclass
        name: 'superclass',
        description: 'case classes extend this abstract class',
        default: 'MyCase'
      },
      { //lookup as themeDoubles
        name: 'doubles',
        description: 'a comma separated list of keys that should map to double instead of int',
        default: ''
      }
    ]
  };
}

exports.render = function (input, options, done) {

  // prepend with abstract class
  const result = [`abstract class ${options.themeSuperclass}\n`]

  // generate case class text
  const code = classes(input, options)
  for (const [name, scala] of code) {
    result.push(`\n${scala}\n`)
  }

  // turn refs to array in apib into List[MyType]
  let resultStr = fixArrayReferences(result.join(''), input, options)

  // remove type suffixes from apip files
  var re1 = new RegExp(options.themeTrimname,"g");
  resultStr = resultStr.replace(re1, '')

  done(null, resultStr)
};

<|endoftext|>


<commit_before>import React from 'react';
import styles from './Content.css';

export default class Content extends React.Component {
  render() {
    return (

Hello, SydJS!

    );
  }
}
<commit_msg>Content for switching between different views<commit_after>import React from 'react';
import styles from './Content.css';

export default class Content extends React.Component {

  userCardClick() {
    const self = this;

    return (num) => {
      console.log(`userCardClick got ${num}`);
      // self.setState({
      //   component: <DetailView people={users} initial={num} clicked={this.detailClick()} />,
      // });
    };
  }

  detailClick() {
    const self = this;

    return () => {
      self.setState({
        component: <UserCards clicked={this.userCardClick()}/>
      });
    };
  }

  componentDidMount() {
    this.setState({
      component: <UserCards clicked={this.userCardClick()}/>
    });
  }

  render() {
    return (

        {this.state.component}

    );
  }
}
<|endoftext|>


<commit_before>define(function () {

    function OnDataChange (bezl) {
        if (bezl.data.Accounts && bezl.vars.loading) {
            bezl.vars.loading = false;

            // If there was a previously selected account in localStorage, grab a reference
            // so we can know whether to mark them as selected
            bezl.vars.selectedAccount = {};
            if (typeof(Storage) !== "undefined" && localStorage.getItem("selectedAccount")) {
                bezl.vars.selectedAccount = JSON.parse(localStorage.getItem("selectedAccount"));
            }

            // Perform additional processing on the returned data
            for (var i = 0; i < bezl.data.Accounts.length; i++) {
                // Add a Selected property to the account record
                if (bezl.data.Accounts[i].ID == bezl.vars.selectedAccount.ID) {
                    bezl.data.Accounts[i].Selected = true;
                } else {
                    bezl.data.Accounts[i].Selected = false;
                }

                // Create an AddressURL column with an encoded version of each Address
                // so that it can be part of a Google Maps AddressURL
                bezl.data.Accounts[i].AddressURL = encodeURI(bezl.data.Accounts[i].Address);

                // Determine the distance from the current location, if applicable
                if (bezl.data.Accounts[i].Geocode_Location) {
                    bezl.data.Accounts[i].Distance = CalcDistance(bezl.vars.currentLat
                                                                , bezl.vars.currentLng
                                                                , parseFloat(bezl.data.Accounts[i].Geocode_Location.split(',')[0].split(':')[1])
                                                                , parseFloat(bezl.data.Accounts[i].Geocode_Location.split(',')[1].split(':')[1]));
                }

                // Set up any of the properties we wish to consolidate additional
                // data into from subsequent queries
                bezl.data.Accounts[i].Contacts = [];
                bezl.data.Accounts[i].CRMCalls = [];
                bezl.data.Accounts[i].Tasks = [];
                bezl.data.Accounts[i].Attachments = [];

                // Make all records visible to start off with
                bezl.data.Accounts[i].show = true;

                // Date pipe has rounding issue, truncate at "T" to get correct Date
                if(bezl.data.Accounts[i].LastContact) {
                    bezl.data.Accounts[i].LastContact = bezl.data.Accounts[i].LastContact.split("T")[0];
                }
            };
        }

        // If we got the account contacts back, merge those in
        if (bezl.data.Accounts && bezl.data.AccountContacts && bezl.vars.loadingContacts) {
            bezl.vars.loadingContacts = false;

            for (var i = 0; i < bezl.data.AccountContacts.length; i++) {
                for (var x = 0; x < bezl.data.Accounts.length; x++) {
                    if (bezl.data.AccountContacts[i].ID == bezl.data.Accounts[x].ID) {
                        bezl.data.Accounts[x].Contacts.push(bezl.data.AccountContacts[i]);
                    }
                }
            }
        }

        // If we got the account calls back, merge those in
        if (bezl.data.Accounts && bezl.data.CRMCalls && bezl.vars.loadingCalls) {
            bezl.vars.loadingCalls = false;

            for (var x = 0; x < bezl.data.Accounts.length; x++) {
                for (var i = 0; i < bezl.data.CRMCalls.length; i++) {
                    if (bezl.data.CRMCalls[i].ID == bezl.data.Accounts[x].ID) {
                        bezl.data.Accounts[x].CRMCalls.push(bezl.data.CRMCalls[i]);
                    }
                }
            }
        }

        // If we got the account tasks back, merge those in
        if (bezl.data.Accounts && bezl.data.Tasks && bezl.vars.loadingTasks) {
            bezl.vars.loadingTasks = false;

            for (var x = 0; x < bezl.data.Accounts.length; x++) {
                for (var i = 0; i < bezl.data.Tasks.length; i++) {
                    if (bezl.data.Tasks[i].ID == bezl.data.Accounts[x].ID) {
                        // Not sure if this is the best place to do this...
                        // Convert any ISO 8601 datetime strings to just date strings
                        bezl.data.Tasks[i].StartDate = (bezl.data.Tasks[i].StartDate || 'T').split('T')[0]
                        bezl.data.Tasks[i].DueDate = (bezl.data.Tasks[i].EndDate || 'T').split('T')[0]

                        bezl.data.Accounts[x].Tasks.push(bezl.data.Tasks[i]);
                    }
                }
            }
        }

        // If we got the account attachments back, merge those in
        if (bezl.data.Accounts && bezl.data.Attachments && bezl.vars.loadingAttachments) {
            bezl.vars.loadingAttachments = false;

            for (var x = 0; x < bezl.data.Accounts.length; x++) {
                for (var i = 0; i < bezl.data.Attachments.length; i++) {
                    if (bezl.data.Attachments[i].ID == bezl.data.Accounts[x].ID) {
                        bezl.data.Accounts[x].Attachments.push(bezl.data.Attachments[i]);
                    }
                }
            }
        }
    }

    function CalcDistance(lat1, lon1, lat2, lon2, unit) {
        var radlat1 = Math.PI * lat1/180
        var radlat2 = Math.PI * lat2/180
        var theta = lon1-lon2
        var radtheta = Math.PI * theta/180
        var dist = Math.sin(radlat1) * Math.sin(radlat2) + Math.cos(radlat1) * Math.cos(radlat2) * Math.cos(radtheta);
        dist = Math.acos(dist)
        dist = dist * 180/Math.PI
        dist = dist * 60 * 1.1515
        if (unit=="K") { dist = dist * 1.609344 }
        if (unit=="N") { dist = dist * 0.8684 }
        return Math.round(dist)
    }

    return {
        onDataChange: OnDataChange
    }
});
<commit_msg>Fix field name.<commit_after>define(function () {

    function OnDataChange (bezl) {
        if (bezl.data.Accounts && bezl.vars.loading) {
            bezl.vars.loading = false;

            // If there was a previously selected account in localStorage, grab a reference
            // so we can know whether to mark them as selected
            bezl.vars.selectedAccount = {};
            if (typeof(Storage) !== "undefined" && localStorage.getItem("selectedAccount")) {
                bezl.vars.selectedAccount = JSON.parse(localStorage.getItem("selectedAccount"));
            }

            // Perform additional processing on the returned data
            for (var i = 0; i < bezl.data.Accounts.length; i++) {
                // Add a Selected property to the account record
                if (bezl.data.Accounts[i].ID == bezl.vars.selectedAccount.ID) {
                    bezl.data.Accounts[i].Selected = true;
                } else {
                    bezl.data.Accounts[i].Selected = false;
                }

                // Create an AddressURL column with an encoded version of each Address
                // so that it can be part of a Google Maps AddressURL
                bezl.data.Accounts[i].AddressURL = encodeURI(bezl.data.Accounts[i].Address);

                // Determine the distance from the current location, if applicable
                if (bezl.data.Accounts[i].Geocode_Location) {
                    bezl.data.Accounts[i].Distance = CalcDistance(bezl.vars.currentLat
                                                                , bezl.vars.currentLng
                                                                , parseFloat(bezl.data.Accounts[i].Geocode_Location.split(',')[0].split(':')[1])
                                                                , parseFloat(bezl.data.Accounts[i].Geocode_Location.split(',')[1].split(':')[1]));
                }

                // Set up any of the properties we wish to consolidate additional
                // data into from subsequent queries
                bezl.data.Accounts[i].Contacts = [];
                bezl.data.Accounts[i].CRMCalls = [];
                bezl.data.Accounts[i].Tasks = [];
                bezl.data.Accounts[i].Attachments = [];

                // Make all records visible to start off with
                bezl.data.Accounts[i].show = true;

                // Date pipe has rounding issue, truncate at "T" to get correct Date
                if(bezl.data.Accounts[i].LastContact) {
                    bezl.data.Accounts[i].LastContact = bezl.data.Accounts[i].LastContact.split("T")[0];
                }
            };
        }

        // If we got the account contacts back, merge those in
        if (bezl.data.Accounts && bezl.data.AccountContacts && bezl.vars.loadingContacts) {
            bezl.vars.loadingContacts = false;

            for (var i = 0; i < bezl.data.AccountContacts.length; i++) {
                for (var x = 0; x < bezl.data.Accounts.length; x++) {
                    if (bezl.data.AccountContacts[i].ID == bezl.data.Accounts[x].ID) {
                        bezl.data.Accounts[x].Contacts.push(bezl.data.AccountContacts[i]);
                    }
                }
            }
        }

        // If we got the account calls back, merge those in
        if (bezl.data.Accounts && bezl.data.CRMCalls && bezl.vars.loadingCalls) {
            bezl.vars.loadingCalls = false;

            for (var x = 0; x < bezl.data.Accounts.length; x++) {
                for (var i = 0; i < bezl.data.CRMCalls.length; i++) {
                    if (bezl.data.CRMCalls[i].ID == bezl.data.Accounts[x].ID) {
                        bezl.data.Accounts[x].CRMCalls.push(bezl.data.CRMCalls[i]);
                    }
                }
            }
        }

        // If we got the account tasks back, merge those in
        if (bezl.data.Accounts && bezl.data.Tasks && bezl.vars.loadingTasks) {
            bezl.vars.loadingTasks = false;

            for (var x = 0; x < bezl.data.Accounts.length; x++) {
                for (var i = 0; i < bezl.data.Tasks.length; i++) {
                    if (bezl.data.Tasks[i].ID == bezl.data.Accounts[x].ID) {
                        // Not sure if this is the best place to do this...
                        // Convert any ISO 8601 datetime strings to just date strings
                        bezl.data.Tasks[i].StartDate = (bezl.data.Tasks[i].StartDate || 'T').split('T')[0]
                        bezl.data.Tasks[i].DueDate = (bezl.data.Tasks[i].DueDate || 'T').split('T')[0]

                        bezl.data.Accounts[x].Tasks.push(bezl.data.Tasks[i]);
                    }
                }
            }
        }

        // If we got the account attachments back, merge those in
        if (bezl.data.Accounts && bezl.data.Attachments && bezl.vars.loadingAttachments) {
            bezl.vars.loadingAttachments = false;

            for (var x = 0; x < bezl.data.Accounts.length; x++) {
                for (var i = 0; i < bezl.data.Attachments.length; i++) {
                    if (bezl.data.Attachments[i].ID == bezl.data.Accounts[x].ID) {
                        bezl.data.Accounts[x].Attachments.push(bezl.data.Attachments[i]);
                    }
                }
            }
        }
    }

    function CalcDistance(lat1, lon1, lat2, lon2, unit) {
        var radlat1 = Math.PI * lat1/180
        var radlat2 = Math.PI * lat2/180
        var theta = lon1-lon2
        var radtheta = Math.PI * theta/180
        var dist = Math.sin(radlat1) * Math.sin(radlat2) + Math.cos(radlat1) * Math.cos(radlat2) * Math.cos(radtheta);
        dist = Math.acos(dist)
        dist = dist * 180/Math.PI
        dist = dist * 60 * 1.1515
        if (unit=="K") { dist = dist * 1.609344 }
        if (unit=="N") { dist = dist * 0.8684 }
        return Math.round(dist)
    }

    return {
        onDataChange: OnDataChange
    }
});
<|endoftext|>


<commit_before>'use strict';

var debug = require('debug')('usvc:jsonrpc:server');
var EventEmitter = require('events').EventEmitter;
var util = require('util');
var when = require('when');
var jayson = require('jayson');
var flat = require('flat');
var json_signing = require('./json_signing');

var express = require('express');
var bodyParser = require('body-parser');

function JSONRPCServer(exportedFacets, options, service, name) {
  this.exportedFacets = exportedFacets;
  this.options = options || {};
  this.service = service;
  this.name = name;
}
util.inherits(JSONRPCServer, EventEmitter);

JSONRPCServer.prototype.initialise = function() {
  var dependencies = this.service.facets.apply(this.service, this.exportedFacets);

  return dependencies.then(function(exportedFacets) {
    var methods = {};

    exportedFacets.map(function(facet) {
      var flattened = flat.flatten(facet.rpc_methods);

      for (var name in flattened) {
        methods[facet.name + '.' + name] = flattened[name].bind(facet);
      }
    }.bind(this));

    this.methods = methods;
    debug('export', this.methods);

    return this._setupServer();
  }.bind(this));
};

JSONRPCServer.prototype._setupServer = function() {
  return when.try(function() {
    var portKey = this.name + ':port';
    var port = this.service.config.get(portKey);

    if (!port) {
      throw new Error('JSON RPC Client requires configuration at ' + portKey);
    }

    this.signingFunctions = json_signing.getSigningFunctions(this.service, this.name);

    var hostKey = this.name + ':host';
    var host = this.service.config.get(hostKey);

    var wrappedMethods = {};
    for (var name in this.methods) {
      if (!this.methods.hasOwnProperty(name)) continue;
      var method = this.methods[name];

      (function(name, method) {
        wrappedMethods[name] = function() {
          var args = [].slice.apply(arguments);
          var callback = args.pop();

          debug('call', args);

          var argsPromise;

          if (this.signingFunctions) {
            argsPromise = this.signingFunctions.verify(args[0]).then(function(decoded) {
              if (decoded.method != name) {
                throw {code:403, message:'Method name mismatch during signature verification'};
              }
              debug('verified', decoded.method, decoded.arguments);
              return decoded.arguments;
            }, function() {
              throw {code:403, message:'Verification of signed message failed'};
            });
          } else {
            argsPromise = when(args);
          }

          // promisify the maybe-promise result
          var promise = argsPromise.then(function(args) {
            return when.try(function() {
              return method.apply(this, args);
            }.bind(this));
          }.bind(this));

          // wrap back out to node callback style
          promise.done(function(val) {
            debug('result', val);
            callback(null, val);
          }, function(err) {
            debug('error', err.stack);
            // must be the correct format, check for node Errors and
            // magicify into {code: ..., message: ...}
            if (err.hasOwnProperty('message')) {
              callback(err);
            } else {
              callback({message: err.toString()});
            }
          });
        }.bind(this);
      }.bind(this))(name, method);
    }

    var portKey = this.name + ':port';
    var port = this.service.config.get(portKey);

    this.server = jayson.server(wrappedMethods);
    var app = express();

    var deferred = when.defer();
    var args = [port];

    if (host) {
      args.push(host);
    }

    args.push(function(err) {
      if (err) {
        deferred.reject(err);
      } else {
        deferred.resolve(true);
      }
    });

    app.use(bodyParser.json());

    app.get('/status', function (req, res) {
      res.status(200).send({status: 'ok'});
    });

    app.use(this.server.middleware());

    app.listen(port, function() {
      debug(this.name, 'Listening on ' + port);
      deferred.resolve(app);
    }.bind(this));

    return deferred.promise;
  }.bind(this));
};

JSONRPCServer.prototype.call = function(method) {
  var remoteArgs = [].slice.apply(arguments).slice(1);

  return this.methods[method].apply(undefined, remoteArgs);
};

module.exports = JSONRPCServer;
<commit_msg>Better checking of input validity for RPC calls.<commit_after>'use strict';

var debug = require('debug')('usvc:jsonrpc:server');
var EventEmitter = require('events').EventEmitter;
var util = require('util');
var when = require('when');
var jayson = require('jayson');
var flat = require('flat');
var json_signing = require('./json_signing');

var express = require('express');
var bodyParser = require('body-parser');

function JSONRPCServer(exportedFacets, options, service, name) {
  this.exportedFacets = exportedFacets;
  this.options = options || {};
  this.service = service;
  this.name = name;
}
util.inherits(JSONRPCServer, EventEmitter);

JSONRPCServer.prototype.initialise = function() {
  var dependencies = this.service.facets.apply(this.service, this.exportedFacets);

  return dependencies.then(function(exportedFacets) {
    var methods = {};

    exportedFacets.map(function(facet) {
      var flattened = flat.flatten(facet.rpc_methods);

      for (var name in flattened) {
        methods[facet.name + '.' + name] = flattened[name].bind(facet);
      }
    }.bind(this));

    this.methods = methods;
    debug('export', this.methods);

    return this._setupServer();
  }.bind(this));
};

JSONRPCServer.prototype._setupServer = function() {
  return when.try(function() {
    var portKey = this.name + ':port';
    var port = this.service.config.get(portKey);

    if (!port) {
      throw new Error('JSON RPC Client requires configuration at ' + portKey);
    }

    this.signingFunctions = json_signing.getSigningFunctions(this.service, this.name);

    var hostKey = this.name + ':host';
    var host = this.service.config.get(hostKey);

    var wrappedMethods = {};
    for (var name in this.methods) {
      if (!this.methods.hasOwnProperty(name)) continue;
      var method = this.methods[name];

      (function(name, method) {
        wrappedMethods[name] = function() {
          var args = [].slice.apply(arguments);
          var callback = args.pop();

          debug('call', args);

          var argsPromise;

          if (this.signingFunctions) {
            // ensure that we have an argument and that it is a string
            var encoded = args[0];
            if (typeof encoded !== 'string') {
              encoded = '';
            };

            // decode and check JWT signature
            argsPromise = this.signingFunctions.verify(encoded).then(function(decoded) {
              if (decoded.method != name) {
                throw {code:403, message:'Method name mismatch during signature verification'};
              }
              debug('verified', decoded.method, decoded.arguments);
              return decoded.arguments;
            }, function() {
              throw {code:403, message:'Verification of signed message failed'};
            });
          } else {
            // not using JWT signing, allow plaintext RPC
            argsPromise = when(args);
          }

          // promisify the maybe-promise result
          var promise = argsPromise.then(function(args) {
            return when.try(function() {
              return method.apply(this, args);
            }.bind(this));
          }.bind(this));

          // wrap back out to node callback style
          promise.done(function(val) {
            debug('result', val);
            callback(null, val);
          }, function(err) {
            debug('error', err.stack);
            // must be the correct format, check for node Errors and
            // magicify into {code: ..., message: ...}
            if (err.hasOwnProperty('message')) {
              callback(err);
            } else {
              callback({message: err.toString()});
            }
          });
        }.bind(this);
      }.bind(this))(name, method);
    }

    var portKey = this.name + ':port';
    var port = this.service.config.get(portKey);

    this.server = jayson.server(wrappedMethods);
    var app = express();

    var deferred = when.defer();
    var args = [port];

    if (host) {
      args.push(host);
    }

    args.push(function(err) {
      if (err) {
        deferred.reject(err);
      } else {
        deferred.resolve(true);
      }
    });

    app.use(bodyParser.json());

    app.get('/status', function (req, res) {
      res.status(200).send({status: 'ok'});
    });

    app.use(this.server.middleware());

    app.listen(port, function() {
      debug(this.name, 'Listening on ' + port);
      deferred.resolve(app);
    }.bind(this));

    return deferred.promise;
  }.bind(this));
};

JSONRPCServer.prototype.call = function(method) {
  var remoteArgs = [].slice.apply(arguments).slice(1);

  return this.methods[method].apply(undefined, remoteArgs);
};

module.exports = JSONRPCServer;
<|endoftext|>


<commit_before>import endpoints from 'config/api.4chan'
import parser from './parser'

export default class Api {
    constructor(client) {
        this.client = client
    }

    fetchBoard(boardID, config) {
        const url = endpoints.board(boardID);
        return this.client
            .get(url, config)
            .then(res => res.data)
            .then(board => parser.parseBoard(board, boardID))
    }

    fetchThread({ boardID, threadID }, config) {
        const url = endpoints.thread(boardID, threadID);
        return this.client
            .get(url, config)
            .then(res => {
                const thread = res.data.posts;
                return {
                    thread: parser.parseThread(thread, boardID),
                    lastModified: res.headers["last-modified"] || 0
                }
            })
    }

    fetchBoardList(config) {
        const url = endpoints.boardlist();
        return this.client
            .get(url, config)
            .then(res => res.data.boards)
            .then(boardList => parser.parseBoardList(boardList))
    }

    fetchArchive({boardID, threadID}) {

    }
}
<commit_msg>feat(api): Initial submitThreadPost<commit_after>import endpoints from 'config/api.4chan'
import Parser from './parser'

export default class Api {
    constructor(client) {
        this.client = client
    }

    fetchBoard(boardID, config) {
        const url = endpoints.board(boardID);
        return this.client
            .get(url, config)
            .then(res => res.data)
            .then(board => Parser.parseBoard(board, boardID))
    }

    fetchThread({ boardID, threadID }, config) {
        const url = endpoints.thread(boardID, threadID);
        return this.client
            .get(url, config)
            .then(res => {
                const thread = res.data.posts;
                return {
                    thread: Parser.parseThread(thread, boardID),
                    lastModified: res.headers["last-modified"] || 0
                }
            })
    }

    fetchBoardList(config) {
        const url = endpoints.boardlist();
        return this.client
            .get(url, config)
            .then(res => res.data.boards)
            .then(boardList => Parser.parseBoardList(boardList))
    }

    fetchArchive({boardID, threadID}) {
        // TODO:  Web scrape archive and parse into consumable structure
    }

    submitThreadPost() {

    }
}
<|endoftext|>


<commit_before>var async = require('async');

/**
 * A feathers service to manage CRUD on MongoDB databases.
 * Pass in a connected MongoClient and it will allow you to create,
 * read, update, and delete databases on the client.
 */
module.exports = function(db, scope) {

	var adminDB = db.admin();

	var dbService = {
		// Scope is either 'server' or 'database'.
		// If scope is server, use adminDB, otherwise, it's a single db.
		scope:scope,
		find: function(params, callback) {

			var dbList = [];

	  	// Async function to add stats to each db.
	  	function addStats(database, cb){
  			// If a databaseName is present, it's a single db.  No need to switch.
				changeDB = database.databaseName ? database : db.db(database.name);

	  		// Get the stats
	  		changeDB.stats(function(err, stats){
	  			// Remove 1 from collection count, unless it's zero. Not sure why it's 1 off.
	  			if (stats.collections) {
		  			stats.collections--;
	  			}
	  			// Rename collections to avoid collisions on the client app.
	  			stats.collectionCount = stats.collections;
	  			delete stats.collections;
	  			// Add the stats to the corresponding database.
	  			dbList.push(stats);
		  		cb(null, database);
	  		});
	  	}

			if (scope === 'server') {
				// Get a list of all databases on the server.
			  adminDB.listDatabases(function(err, dbs){

			  	async.each(dbs.databases, addStats, function(err){
		  	    if (err) {
		  	    	console.log(err)
		  	    	callback(err);
		  	    } else {
		  	    	dbList.sort(function(a, b){
		  	    		return a.db.toLowerCase().localeCompare(b.db.toLowerCase());
		  	    	});
						  callback(null, dbList);
		  	    }
			  	});
			  });

			// We only have access to one database.
			} else {
				addStats(db, function(err){
				  callback(null, dbList);
				});
			}

		},

		create: function(data, params, callback) {
			console.log(data);
			callback(null, data);
		},

		update: function(id, data, params, callback) {
			console.log(data);
			callback(err, data);
		},

		remove: function(id, params, callback) {
			console.log(data);
			callback(err, data);
		},

		setup: function(app) {
			console.log(path);
			// this.service = app.service.bind(app);
		}
	};

	return dbService;
};
<commit_msg>Can create dbs.  find now sets up db name as _id.<commit_after>var async = require('async');

/**
 * A feathers service to manage CRUD on MongoDB databases.
 * Pass in a connected MongoClient and it will allow you to create,
 * read, update, and delete databases on the client.
 */
module.exports = function(db, scope) {

	var adminDB = db.admin();

	var dbService = {

		setup: function(app) {
			this.db = db;
			this.service = app.service.bind(app);
		},

		// Scope is either 'server' or 'database'.
		// If scope is server, use adminDB, otherwise, it's a single db.
		scope:scope,
		find: function(params, callback) {

			console.log('find');

			var dbList = [];

	  	// Async function to add stats to each db.
	  	function addStats(database, cb){
  			// If a databaseName is present, it's a single db.  No need to switch.
				var changeDB = database.databaseName ? database : db.db(database.name);

	  		// Get the stats
	  		changeDB.stats(function(err, stats){
	  			// Remove 1 from collection count, unless it's zero. Not sure why it's 1 off.
	  			if (stats.collections) {
		  			stats.collections--;
	  			}

	  			// Add the db name as the _id
	  			stats._id = stats.db;
	  			stats.name = stats.db;

	  			// Rename collections to avoid collisions on the client app.
	  			stats.collectionCount = stats.collections;
	  			delete stats.collections;
	  			// Add the stats to the corresponding database.
	  			dbList.push(stats);
		  		cb(null, database);
	  		});
	  	}

	  	// If scope is server, we have multiple database access.
			if (scope === 'server') {
				// Get a list of all databases on the server.
			  adminDB.listDatabases(function(err, dbs){

			  	async.each(dbs.databases, addStats, function(err){
		  	    if (err) {
		  	    	console.log(err);
		  	    	return callback(err);
		  	    } else {
		  	    	dbList.sort(function(a, b){
		  	    		return a.db.toLowerCase().localeCompare(b.db.toLowerCase());
		  	    	});
						  callback(null, dbList);
		  	    }
			  	});
			  });

			// We only have access to one database.
			} else {
				addStats(db, function(err){
					if (err) {
					  return callback(err);
					}
				  return callback(null, dbList);
				});
			}

		},

		create: function(data, params, callback) {
			if (!data.name) {
				return callback({error:'name is required'});
			}
			db.db(data.name);

			// Create dummy stats. Use the db name as the _id.
			data = {
				_id: data.name,
		    db: data.name,
		    objects: 0,
		    avgObjSize: 0,
		    dataSize: 0,
		    storageSize: 0,
		    numExtents: 0,
		    indexes: 0,
		    indexSize: 0,
		    fileSize: 0,
		    nsSizeMB: 0,
		    dataFileVersion: {},
		    ok: 1,
		    collectionCount: 0
		  };
			return callback(null, data);
		},

		update: function(id, data, params, callback) {
			console.log(data);
			callback(null, data);
		},

		remove: function(id, params, callback) {
			console.log(params);
			callback(null, id);
		}
	};

	return dbService;
};
<|endoftext|>


<commit_before>import React from 'react';
import ActionButton from 'react-native-action-button';
import Icon from 'react-native-vector-icons/FontAwesome';
import {styles} from './GlobalStyles.js'
import CountDownTimer from 'react_native_countdowntimer'

var dateFormat = require('dateformat');

import {
  StackNavigator,
  TabNavigator,
} from 'react-navigation';

import {
  RefreshControl,
  StyleSheet,
  Text,
  View,
  FlatList,
  Dimensions,
  Image,
  ActivityIndicator,
  TouchableHighlight,
} from 'react-native';

const api = 'https://f1portal.herokuapp.com';
const today = new Date();
var seasonRound;

export default class CalendarScreen extends React.Component {

  static navigationOptions = {
    tabBarLabel: 'Calendar',
    tabBarIcon: ({ tintColor }) => (
      <Image
        source={require('../images/icons/calendar.png')}
        style={[styles.icon, {tintColor: tintColor}]}
      />
    ),
    tabBarPosition: 'bottom',
  };

  constructor(props) {
    super(props);
    this.state = {
      dataSource: [],
      calendarJson: [],
      isLoading: true,
      refreshing: false,
    };

  }

  componentDidMount() {

    return fetch(api + '/get_schedule')
      .then((response) => response.json())
      .then((responseJson) => {
        this.setState({
          isLoading: false,
          calendarJson: responseJson,
          dataSource: responseJson.MRData.RaceTable.Races,
        });
      })
      .catch((error) => {
        console.error(error);
      });

  }

  raceInfoClick(raceInfo){
    console.log("Clicked on " + raceInfo.raceName);
  }

  scrollToLatest(){
    console.log("Scrolled to latest race");
    this.refs.flatlist.scrollToIndex({index: seasonRound, animated: true});
  }

  renderRow(data) {

    var standingCell = data.item;
    var imageURL = standingCell.Circuit.imageURL;
    var raceDate = new Date(standingCell.date + "T" + standingCell.time)
    var imgStyle;
    if (data.index < seasonRound) {
      imgStyle = local_styles.elapsedRaceImageView;
      raceNameTextStyle = local_styles.elapsedRaceNameText;
      raceCircuitTextStyle = local_styles.elapsedRaceCircuitText;
      raceDateTextStyle = local_styles.elapsedRaceDateText;
    } else {
      imgStyle = local_styles.raceImageView;
      raceNameTextStyle = local_styles.raceNameText;
      raceCircuitTextStyle = local_styles.raceCircuitText;
      raceDateTextStyle = local_styles.raceDateText;
    }

    var date = raceDate.toISOString();

    return(
      <TouchableHighlight onPress={() => this.raceInfoClick(standingCell)}>
        <Image
          style={local_styles.raceImage}
          source={
            {uri: imageURL}
          }>

            <View style={imgStyle}>

              <View style={local_styles.raceNameTextView}>
                <Text style={raceNameTextStyle}>
                  {standingCell.raceName}
                </Text>
                <Text style={raceCircuitTextStyle}>
                  {standingCell.Circuit.circuitName}
                </Text>
              </View>
              <View style={local_styles.raceDateTextView}>
                <Text style={raceDateTextStyle}>
                  {dateFormat(raceDate, "mmmm dS")}
                </Text>
                <CountDownTimer
                  date={date}
                  days={{plural: 'Days ',singular: 'day '}}
                  hours=':'
                  mins=':'
                  segs=''

                  daysStyle={styles.time}
                  hoursStyle={styles.time}
                  minsStyle={styles.time}
                  secsStyle={styles.time}
                  firstColonStyle={styles.colon}
                  secondColonStyle={styles.colon}
                />
              </View>
            </View>
        </Image>
      </TouchableHighlight>
    )

  }

  render() {

    var racesList = this.state.dataSource;
    for (var i = 0; i < racesList.length; i++) {
      var raceDate = new Date(racesList[i].date + "T" + racesList[i].time)
      raceDate.setHours(raceDate.getHours() + 2);
      if (raceDate > today) {
        seasonRound = i;
        console.log("Season round: " + i);
        break
      }
    }

    if (this.state.isLoading) {
      return (
        <View style={{flex: 1, justifyContent: 'center', alignItems: 'center'}}>
          <ActivityIndicator />
        </View>
      );
    }

    return (

      <View style={styles.container}>

        <View style={styles.header}>
          <Text style={styles.headerText}>
            Race Calendar
          </Text>
        </View>

        <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center'}}>
          <FlatList ref="flatlist"
            data={this.state.dataSource}
            renderItem={this.renderRow.bind(this)}
            getItemLayout={this.getItemLayout}
            keyExtractor={item => item.raceName}
          />
        </View>

        <ActionButton
         buttonColor="#FAFAFA"
         onPress={() => this.scrollToLatest()}
         icon={<Icon name="chevron-down" size={30} color="red" />}>
         >
        </ActionButton>
      </View>

    );
  }

  getItemLayout = (data, index) => (
    { length: 170, offset: 170 * index, index }
  )
}

var local_styles = StyleSheet.create({
  actionButtonIcon: {
    fontSize: 20,
    height: 22,
    color: 'white',
  },
  raceImage: {
    width: Dimensions.get('window').width,
    height: 170,
  },
  elapsedRaceImageView: {
    flex: 1,
    flexDirection: 'row',
    justifyContent: 'flex-start',
    width: Dimensions.get('window').width,
    backgroundColor: 'rgba(255,255,255,0.75)',
    borderBottomWidth: 5,
    borderBottomColor: 'white',
  },
  raceImageView: {
    flex: 1,
    flexDirection: 'row',
    justifyContent: 'flex-start',
    width: Dimensions.get('window').width,
    backgroundColor: 'rgba(0,0,0,0.3)',
    borderBottomWidth: 5,
    borderBottomColor: 'white',
  },
  elapsedRaceCircuitText: {
    paddingLeft: 15,
    fontSize: 12,
    textAlign: 'left',
    color: '#404040',
  },
  raceCircuitText: {
    paddingLeft: 15,
    fontSize: 12,
    textAlign: 'left',
    color: 'white',
    textShadowColor: 'black',
    textShadowOffset: {width: 1, height: 1},
    textShadowRadius: 3,
  },
  elapsedRaceNameText: {
    paddingLeft: 15,
    paddingTop: 15,
    fontSize: 19,
    fontWeight: '500',
    textAlign: 'left',
    color: '#404040',
  },
  raceNameText: {
    paddingLeft: 15,
    paddingTop: 15,
    fontSize: 19,
    fontWeight: '500',
    textAlign: 'left',
    color: 'white',
    textShadowColor: 'black',
    textShadowOffset: {width: 1, height: 1},
    textShadowRadius: 3,
  },
  raceNameTextView:{
    flex: 5,
    alignItems: 'flex-start',
  },
  elapsedRaceDateText: {
    paddingRight: 15,
    paddingTop: 15,
    fontSize: 16,
    textAlign: 'right',
    color: '#606060',
  },
  raceDateText: {
    paddingRight: 15,
    paddingTop: 15,
    fontSize: 16,
    textAlign: 'right',
    color: 'white',
    textShadowColor: 'black',
    textShadowOffset: {width: 1, height: 1},
    textShadowRadius: 3,
  },
  raceDateTextView:{
    flex: 3,
    alignItems: 'flex-end',
  },

});
<commit_msg>Only next race has countdown<commit_after>import React from 'react';
import ActionButton from 'react-native-action-button';
import Icon from 'react-native-vector-icons/FontAwesome';
import {styles} from './GlobalStyles.js'
import CountDownTimer from 'react_native_countdowntimer'

var dateFormat = require('dateformat');

import {
  StackNavigator,
  TabNavigator,
} from 'react-navigation';

import {
  RefreshControl,
  StyleSheet,
  Text,
  View,
  FlatList,
  Dimensions,
  Image,
  ActivityIndicator,
  TouchableHighlight,
} from 'react-native';

const api = 'https://f1portal.herokuapp.com';
const today = new Date();
var seasonRound;

export default class CalendarScreen extends React.Component {

  static navigationOptions = {
    tabBarLabel: 'Calendar',
    tabBarIcon: ({ tintColor }) => (
      <Image
        source={require('../images/icons/calendar.png')}
        style={[styles.icon, {tintColor: tintColor}]}
      />
    ),
    tabBarPosition: 'bottom',
  };

  constructor(props) {
    super(props);
    this.state = {
      dataSource: [],
      calendarJson: [],
      isLoading: true,
      refreshing: false,
    };

  }

  componentDidMount() {

    return fetch(api + '/get_schedule')
      .then((response) => response.json())
      .then((responseJson) => {
        this.setState({
          isLoading: false,
          calendarJson: responseJson,
          dataSource: responseJson.MRData.RaceTable.Races,
        });
      })
      .catch((error) => {
        console.error(error);
      });

  }

  raceInfoClick(raceInfo){
    console.log("Clicked on " + raceInfo.raceName);
  }

  scrollToLatest(){
    console.log("Scrolled to latest race");
    this.refs.flatlist.scrollToIndex({index: seasonRound, animated: true});
  }

  renderRow(data) {

    var standingCell = data.item;
    var imageURL = standingCell.Circuit.imageURL;
    var raceDate = new Date(standingCell.date + "T" + standingCell.time)
    var imgStyle;
    if (data.index < seasonRound) {
      imgStyle = local_styles.elapsedRaceImageView;
      raceNameTextStyle = local_styles.elapsedRaceNameText;
      raceCircuitTextStyle = local_styles.elapsedRaceCircuitText;
      raceDateTextStyle = local_styles.elapsedRaceDateText;
    } else {
      imgStyle = local_styles.raceImageView;
      raceNameTextStyle = local_styles.raceNameText;
      raceCircuitTextStyle = local_styles.raceCircuitText;
      raceDateTextStyle = local_styles.raceDateText;
    }

    var date = raceDate.toISOString();

    return(
      <TouchableHighlight onPress={() => this.raceInfoClick(standingCell)}>
        <Image
          style={local_styles.raceImage}
          source={
            {uri: imageURL}
          }>

            <View style={imgStyle}>

              <View style={local_styles.raceNameTextView}>
                <Text style={raceNameTextStyle}>
                  {standingCell.raceName}
                </Text>
                <Text style={raceCircuitTextStyle}>
                  {standingCell.Circuit.circuitName}
                </Text>
              </View>
              <View style={local_styles.raceDateTextView}>

                <Text style={raceDateTextStyle}>
                  {dateFormat(raceDate, "mmmm dS")}
                </Text>

                {(data.index === seasonRound) &&

                  <CountDownTimer
                    date={date}
                    days={{plural: 'Days ',singular: 'day '}}
                    hours=':'
                    mins=':'
                    segs=''

                    daysStyle={styles.time}
                    hoursStyle={styles.time}
                    minsStyle={styles.time}
                    secsStyle={styles.time}
                    firstColonStyle={styles.colon}
                    secondColonStyle={styles.colon}
                  />

                }

              </View>
            </View>
        </Image>
      </TouchableHighlight>
    )

  }

  render() {

    var racesList = this.state.dataSource;
    for (var i = 0; i < racesList.length; i++) {
      var raceDate = new Date(racesList[i].date + "T" + racesList[i].time)
      raceDate.setHours(raceDate.getHours() + 2);
      if (raceDate > today) {
        seasonRound = i;
        console.log("Season round: " + i);
        break
      }
    }

    if (this.state.isLoading) {
      return (
        <View style={{flex: 1, justifyContent: 'center', alignItems: 'center'}}>
          <ActivityIndicator />
        </View>
      );
    }

    return (

      <View style={styles.container}>

        <View style={styles.header}>
          <Text style={styles.headerText}>
            Race Calendar
          </Text>
        </View>

        <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center'}}>
          <FlatList ref="flatlist"
            data={this.state.dataSource}
            renderItem={this.renderRow.bind(this)}
            getItemLayout={this.getItemLayout}
            keyExtractor={item => item.raceName}
          />
        </View>

        <ActionButton
         buttonColor="#FAFAFA"
         onPress={() => this.scrollToLatest()}
         icon={<Icon name="chevron-down" size={30} color="red" />}>
         >
        </ActionButton>
      </View>

    );
  }

  getItemLayout = (data, index) => (
    { length: 170, offset: 170 * index, index }
  )
}

var local_styles = StyleSheet.create({
  actionButtonIcon: {
    fontSize: 20,
    height: 22,
    color: 'white',
  },
  raceImage: {
    width: Dimensions.get('window').width,
    height: 170,
  },
  elapsedRaceImageView: {
    flex: 1,
    flexDirection: 'row',
    justifyContent: 'flex-start',
    width: Dimensions.get('window').width,
    backgroundColor: 'rgba(255,255,255,0.75)',
    borderBottomWidth: 5,
    borderBottomColor: 'white',
  },
  raceImageView: {
    flex: 1,
    flexDirection: 'row',
    justifyContent: 'flex-start',
    width: Dimensions.get('window').width,
    backgroundColor: 'rgba(0,0,0,0.3)',
    borderBottomWidth: 5,
    borderBottomColor: 'white',
  },
  elapsedRaceCircuitText: {
    paddingLeft: 15,
    fontSize: 12,
    textAlign: 'left',
    color: '#404040',
  },
  raceCircuitText: {
    paddingLeft: 15,
    fontSize: 12,
    textAlign: 'left',
    color: 'white',
    textShadowColor: 'black',
    textShadowOffset: {width: 1, height: 1},
    textShadowRadius: 3,
  },
  elapsedRaceNameText: {
    paddingLeft: 15,
    paddingTop: 15,
    fontSize: 19,
    fontWeight: '500',
    textAlign: 'left',
    color: '#404040',
  },
  raceNameText: {
    paddingLeft: 15,
    paddingTop: 15,
    fontSize: 19,
    fontWeight: '500',
    textAlign: 'left',
    color: 'white',
    textShadowColor: 'black',
    textShadowOffset: {width: 1, height: 1},
    textShadowRadius: 3,
  },
  raceNameTextView:{
    flex: 5,
    alignItems: 'flex-start',
  },
  elapsedRaceDateText: {
    paddingRight: 15,
    paddingTop: 15,
    fontSize: 16,
    textAlign: 'right',
    color: '#606060',
  },
  raceDateText: {
    paddingRight: 15,
    paddingTop: 15,
    fontSize: 16,
    textAlign: 'right',
    color: 'white',
    textShadowColor: 'black',
    textShadowOffset: {width: 1, height: 1},
    textShadowRadius: 3,
  },
  raceDateTextView:{
    flex: 3,
    alignItems: 'flex-end',
  },

});
<|endoftext|>


<commit_before>"use strict";

var restify = require('restify');
var async = require('async');
var Anyfetch = require('anyfetch');

module.exports.get = function get(req, res, next) {
  if(!req.query.context) {
    return next(new restify.ConflictError("Missing query parameter"));
  }
  async.waterfall([
    function getDocuments(cb) {
      var anyfetchClient = new Anyfetch(req.accessToken.token);
      anyfetchClient.getDocuments({
        search: req.query.context,
        render_templates: true,
        sort: "-modificationDate",
        fields: "data",
      }, cb);
    },
    function remapDocuments(documentsRes, cb) {
      res.set("Cache-Control", "max-age=3600");
      res.send(200, documentsRes.body.data.map(function mapDocuments(document) {
        return {
          documentId: document.id,
          typeId: document.document_type.id,
          providerId: document.provider.client.id,
          date: document.modification_date,
          snippet: document.rendered_snippet,
          title: document.rendered_title
        };
      }));
      cb();
    }
  ], next);
};
<commit_msg>Add 'count' parameters<commit_after>"use strict";

var restify = require('restify');
var async = require('async');
var Anyfetch = require('anyfetch');

module.exports.get = function get(req, res, next) {
  if(!req.query.context) {
    return next(new restify.ConflictError("Missing query parameter"));
  }
  async.waterfall([
    function getDocuments(cb) {
      var params = {
        search: req.query.context,
        render_templates: true,
        sort: "-modificationDate",
        fields: "data",
      };

      if(req.query.count) {
        params.count = req.query.count;
      }

      var anyfetchClient = new Anyfetch(req.accessToken.token);
      anyfetchClient.getDocuments(params, cb);
    },
    function remapDocuments(documentsRes, cb) {
      res.set("Cache-Control", "max-age=3600");
      res.send(200, documentsRes.body.data.map(function mapDocuments(document) {
        return {
          documentId: document.id,
          typeId: document.document_type.id,
          providerId: document.provider.client.id,
          date: document.modification_date,
          snippet: document.rendered_snippet,
          title: document.rendered_title
        };
      }));
      cb();
    }
  ], next);
};
<|endoftext|>