<commit_before>"use strict";

const common = require('../common');
const client = common.createClient();

const moment = require('moment');

/**
 * The elasticsearch aggregation logic for products. To maintain good performance, it
 * contains the assumption that a product (name + brand) cannot be sold
 * more than 10000 times.
 * @var
 */
const aggregateProduct = {
    prods: {
      terms: {
        field: 'complete_name'
      },
      aggs: {
        hits: {
          top_hits: {
            size: 10000,
            _source: {
              include: "_id"
            },
            sort: [
                {sold_date: { order: "desc" }},
                {created_at: { order: "asc" }}
            ]
          }
        }
      }
    }
};

 /**
 * The fields of the Product.
 * @var
 */
const productFields = ['name', 'brand', 'sold_date', 'notes'];

/**
 * Helper class that brings together all the route handlers (declared as static methods)
 * that work on the product doc and the utility functions used by them.
 * @class ProductHandler
 */
class ProductHandler {

    /**
     * Parses the elasticsearch response and returns an array of objects that represent the products.
     * @function
     *
     * @param {object} req the current {@link http://expressjs.com/4x/api.html#req|request object}.
     * @param {object} resp the elasticsearch response.
     */
    static processElasticsearchResults(req, resp) {

        function getField(hit, field, field_type) {
            if (hit.highlight && hit.highlight[field + '.' + field_type])
                return hit.highlight[field + '.' + field_type][0];

            return hit._source[field];
        }

        let hits = resp.hits.hits;
        let aggregations = resp.aggregations.prods.buckets;

        let lookup = {};
        for (let i = 0; i < hits.length; i++) {
            lookup[hits[i]._id] = hits[i];
        }

        let results = [];
        for (let i = 0; i < aggregations.length; i++) {
            let objects = [];
            let obj;
            for (let j = 0; j < aggregations[i].hits.hits.hits.length; j++) {
                obj = lookup[aggregations[i].hits.hits.hits[j]._id];

                objects[objects.length] = {
                    id: obj._id,
                    date: obj._source.sold_date ? common.toLocalFormattedDate(req, obj._source.sold_date) : '-',
                    notes: obj._source.notes ? obj._source.notes : '-'
                };
            }

            obj = lookup[aggregations[i].hits.hits.hits[0]._id];
            results[results.length] = {
                name: getField(obj, 'name', 'autocomplete'),
                brand: getField(obj, 'brand', 'autocomplete'),
                count: aggregations[i].doc_count,
                objects: objects
            };
        }

        return results;
    }

    /**
     * The handler that performs the products search, returning an aggregate structure that
     * groups together all the products with the same name and brand.
     * @method
     *
     * @param {object} req the current {@link http://expressjs.com/4x/api.html#req|request object}.
     * @param {object} res the {@link http://expressjs.com/4x/api.html#res|response object}.
     * @param {function} next the next middleware function to invoke, if any.
     */
    static search(req, res, next) {
        let queryBody;
        if (req.query.text.trim()) {
            queryBody = {
                query: {
                    multi_match: {
                        query: req.query.text,
                        operator: 'and',
                        type: 'cross_fields',
                        fields: [
                            "name.autocomplete",
                            "brand.autocomplete"
                        ]
                    }
                },
                highlight: {
                    fields: {
                        '*': {
                            'pre_tags': [''],
                            'post_tags': ['']
                        }
                    }
                },
                aggs: aggregateProduct
            };
        }
        else {
            queryBody = {
                query: {
                    match_all: {}
                },
                aggs: aggregateProduct
            };
        }

        client.search({
            index: req.config.mainIndex,
            type: 'product',
            size: 50,
            body: queryBody
        }, (err, resp, respcode) =>
            res.json({
                products: ProductHandler.processElasticsearchResults(req, resp)
            })
        );
    }

    /**
     * Validates the Product data and returns the list of the errors if any.
     * @method
     *
     * @param {object} req the current {@link http://expressjs.com/4x/api.html#req|request object}.
     */
    static validateData(req) {
        // Trim all the fields that allow the user to write text
        for (let i = 0; i < productFields.length; i++)
            req.sanitize(productFields[i]).trim();

        req.checkBody('name', req.i18n.__('The name is mandatory')).notEmpty();

        if (req.body.first_see) {
            req.checkBody('sold_date', req.i18n.__(
                'The sold date does not seem a valid date')).isValidDate();
        }

        return req.validationErrors();
    }

    /**
     * Converts the source object to the format used to save the related document
     * on elasticsearch.
     * @method
     *
     * @param {object} req the current {@link http://expressjs.com/4x/api.html#req|request object}.
     * @param {object} sourceObj the source object originated from the Product form.
     */
    static toElasticsearchFormat(req, sourceObj) {
        let obj = {};
        for (let i = 0; i < productFields.length; i++) {
            let field = productFields[i];
            if (sourceObj[field]) {
                if (field == 'sold_date')
                    obj[field] = common.toISODate(req, sourceObj[field]);
                else
                    obj[field] = sourceObj[field];
            }
        }

        obj.complete_name = obj.name;
        if (obj.brand) {
            obj.complete_name += obj.brand;
        }

        return obj;
    }

    /**
     * Converts the source object to the format used to present the product data.
     * @method
     *
     * @param {object} req the current {@link http://expressjs.com/4x/api.html#req|request object}.
     * @param {object} sourceObj the source object originated from the elasticsearch response.
     */
    static toViewFormat(req, sourceObj) {
        let obj = {};
        for (let i = 0; i < productFields.length; i++) {
            let field = productFields[i];
            if (sourceObj[field]) {
                if (field == 'sold_date')
                    obj[field] = common.toLocalFormattedDate(req, sourceObj[field]);
                else
                    obj[field] = sourceObj[field];
            }
        }
        return obj;
    }

    /**
     * The handler that returns a single product object identified by the given product id.
     * @method
     *
     * @param {object} req the current {@link http://expressjs.com/4x/api.html#req|request object}.
     * @param {object} res the {@link http://expressjs.com/4x/api.html#res|response object}.
     * @param {function} next the next middleware function to invoke, if any.
     */
    static fetch(req, res, next) {
        client.get({
            index: req.config.mainIndex,
            type: 'product',
            id: req.params.id
        }, (err, resp, respcode) =>
            res.json(ProductHandler.toViewFormat(req, resp._source))
        );
    }

    /**
     * The handler that creates a product object from the data passed in the request body.
     * @method
     *
     * @param {object} req the current {@link http://expressjs.com/4x/api.html#req|request object}.
     * @param {object} res the {@link http://expressjs.com/4x/api.html#res|response object}.
     * @param {function} next the next middleware function to invoke, if any.
     */
    static create(req, res, next) {
        const errors = ProductHandler.validateData(req);
        if (errors) {
            res.status(400).json({errors: errors});
            return;
        }

        const args = {
            index: req.config.mainIndex,
            type: 'product',
            refresh: true
        };

        args.body = ProductHandler.toElasticsearchFormat(req, req.body);
        args.body.created_at = moment().format('YYYY-MM-DD');
        client.index(args,
            (err, resp, respcode) =>
            common.saveCallback(req, res, err, resp, true)
        );
    }

    /**
     * The handler that updates a product object from the data passed in the request body.
     * @method
     *
     * @param {object} req the current {@link http://expressjs.com/4x/api.html#req|request object}.
     * @param {object} res the {@link http://expressjs.com/4x/api.html#res|response object}.
     * @param {function} next the next middleware function to invoke, if any.
     */
    static update(req, res, next) {
        const errors = ProductHandler.validateData(req);
        if (errors) {
            res.status(400).json({errors: errors});
            return;
        }

        const args = {
            index: req.config.mainIndex,
            type: 'product',
            id: req.params.id,
            body: {doc: ProductHandler.toElasticsearchFormat(req, req.body)},
            refresh: true
        };

        client.update(args,
            (err, resp, respcode) =>
            common.saveCallback(req, res, err, resp, false)
        );
    }

    /**
     * The handler that deletes a product object identified by the given id.
     * @method
     *
     * @param {object} req the current {@link http://expressjs.com/4x/api.html#req|request object}.
     * @param {object} res the {@link http://expressjs.com/4x/api.html#res|response object}.
     * @param {function} next the next middleware function to invoke, if any.
     */
    static delete(req, res, next) {
        client.delete({
            index: req.config.mainIndex,
            type: 'product',
            refresh: true,
            id: req.params.id
        }, function(err, resp, respcode) {
            if (err) {
                console.log(err);
                res.status(400).end();
            }
            else {
                res.status(200).end();
            }
        });
    }
}

module.exports = ProductHandler;<commit_msg>Remove the default limit of 10 elements per aggregation.<commit_after>"use strict";

const common = require('../common');
const client = common.createClient();

const moment = require('moment');

/**
 * The elasticsearch aggregation logic for products. To maintain good performance, it
 * contains the assumption that a product (name + brand) cannot be sold
 * more than 10000 times.
 * @var
 */
const aggregateProduct = {
    prods: {
      terms: {
        field: 'complete_name',
        size: 0  // no limits on the aggregation terms returned
      },
      aggs: {
        hits: {
          top_hits: {
            size: 10000,
            _source: {
              include: "_id"
            },
            sort: [
                {sold_date: { order: "desc" }},
                {created_at: { order: "asc" }}
            ]
          }
        }
      }
    }
};

 /**
 * The fields of the Product.
 * @var
 */
const productFields = ['name', 'brand', 'sold_date', 'notes'];

/**
 * Helper class that brings together all the route handlers (declared as static methods)
 * that work on the product doc and the utility functions used by them.
 * @class ProductHandler
 */
class ProductHandler {

    /**
     * Parses the elasticsearch response and returns an array of objects that represent the products.
     * @function
     *
     * @param {object} req the current {@link http://expressjs.com/4x/api.html#req|request object}.
     * @param {object} resp the elasticsearch response.
     */
    static processElasticsearchResults(req, resp) {

        function getField(hit, field, field_type) {
            if (hit.highlight && hit.highlight[field + '.' + field_type])
                return hit.highlight[field + '.' + field_type][0];

            return hit._source[field];
        }

        let hits = resp.hits.hits;
        let aggregations = resp.aggregations.prods.buckets;

        let lookup = {};
        for (let i = 0; i < hits.length; i++) {
            lookup[hits[i]._id] = hits[i];
        }

        let results = [];
        for (let i = 0; i < aggregations.length; i++) {
            let objects = [];
            let obj;
            for (let j = 0; j < aggregations[i].hits.hits.hits.length; j++) {
                obj = lookup[aggregations[i].hits.hits.hits[j]._id];

                objects[objects.length] = {
                    id: obj._id,
                    date: obj._source.sold_date ? common.toLocalFormattedDate(req, obj._source.sold_date) : '-',
                    notes: obj._source.notes ? obj._source.notes : '-'
                };
            }

            obj = lookup[aggregations[i].hits.hits.hits[0]._id];
            results[results.length] = {
                name: getField(obj, 'name', 'autocomplete'),
                brand: getField(obj, 'brand', 'autocomplete'),
                count: aggregations[i].doc_count,
                objects: objects
            };
        }

        return results;
    }

    /**
     * The handler that performs the products search, returning an aggregate structure that
     * groups together all the products with the same name and brand.
     * @method
     *
     * @param {object} req the current {@link http://expressjs.com/4x/api.html#req|request object}.
     * @param {object} res the {@link http://expressjs.com/4x/api.html#res|response object}.
     * @param {function} next the next middleware function to invoke, if any.
     */
    static search(req, res, next) {
        let queryBody;
        if (req.query.text.trim()) {
            queryBody = {
                query: {
                    multi_match: {
                        query: req.query.text,
                        operator: 'and',
                        type: 'cross_fields',
                        fields: [
                            "name.autocomplete",
                            "brand.autocomplete"
                        ]
                    }
                },
                highlight: {
                    fields: {
                        '*': {
                            'pre_tags': [''],
                            'post_tags': ['']
                        }
                    }
                },
                aggs: aggregateProduct
            };
        }
        else {
            queryBody = {
                query: {
                    match_all: {}
                },
                aggs: aggregateProduct
            };
        }

        client.search({
            index: req.config.mainIndex,
            type: 'product',
            size: 50,
            body: queryBody
        }, (err, resp, respcode) =>
            res.json({
                products: ProductHandler.processElasticsearchResults(req, resp)
            })
        );
    }

    /**
     * Validates the Product data and returns the list of the errors if any.
     * @method
     *
     * @param {object} req the current {@link http://expressjs.com/4x/api.html#req|request object}.
     */
    static validateData(req) {
        // Trim all the fields that allow the user to write text
        for (let i = 0; i < productFields.length; i++)
            req.sanitize(productFields[i]).trim();

        req.checkBody('name', req.i18n.__('The name is mandatory')).notEmpty();

        if (req.body.first_see) {
            req.checkBody('sold_date', req.i18n.__(
                'The sold date does not seem a valid date')).isValidDate();
        }

        return req.validationErrors();
    }

    /**
     * Converts the source object to the format used to save the related document
     * on elasticsearch.
     * @method
     *
     * @param {object} req the current {@link http://expressjs.com/4x/api.html#req|request object}.
     * @param {object} sourceObj the source object originated from the Product form.
     */
    static toElasticsearchFormat(req, sourceObj) {
        let obj = {};
        for (let i = 0; i < productFields.length; i++) {
            let field = productFields[i];
            if (sourceObj[field]) {
                if (field == 'sold_date')
                    obj[field] = common.toISODate(req, sourceObj[field]);
                else
                    obj[field] = sourceObj[field];
            }
        }

        obj.complete_name = obj.name;
        if (obj.brand) {
            obj.complete_name += obj.brand;
        }

        return obj;
    }

    /**
     * Converts the source object to the format used to present the product data.
     * @method
     *
     * @param {object} req the current {@link http://expressjs.com/4x/api.html#req|request object}.
     * @param {object} sourceObj the source object originated from the elasticsearch response.
     */
    static toViewFormat(req, sourceObj) {
        let obj = {};
        for (let i = 0; i < productFields.length; i++) {
            let field = productFields[i];
            if (sourceObj[field]) {
                if (field == 'sold_date')
                    obj[field] = common.toLocalFormattedDate(req, sourceObj[field]);
                else
                    obj[field] = sourceObj[field];
            }
        }
        return obj;
    }

    /**
     * The handler that returns a single product object identified by the given product id.
     * @method
     *
     * @param {object} req the current {@link http://expressjs.com/4x/api.html#req|request object}.
     * @param {object} res the {@link http://expressjs.com/4x/api.html#res|response object}.
     * @param {function} next the next middleware function to invoke, if any.
     */
    static fetch(req, res, next) {
        client.get({
            index: req.config.mainIndex,
            type: 'product',
            id: req.params.id
        }, (err, resp, respcode) =>
            res.json(ProductHandler.toViewFormat(req, resp._source))
        );
    }

    /**
     * The handler that creates a product object from the data passed in the request body.
     * @method
     *
     * @param {object} req the current {@link http://expressjs.com/4x/api.html#req|request object}.
     * @param {object} res the {@link http://expressjs.com/4x/api.html#res|response object}.
     * @param {function} next the next middleware function to invoke, if any.
     */
    static create(req, res, next) {
        const errors = ProductHandler.validateData(req);
        if (errors) {
            res.status(400).json({errors: errors});
            return;
        }

        const args = {
            index: req.config.mainIndex,
            type: 'product',
            refresh: true
        };

        args.body = ProductHandler.toElasticsearchFormat(req, req.body);
        args.body.created_at = moment().format('YYYY-MM-DD');
        client.index(args,
            (err, resp, respcode) =>
            common.saveCallback(req, res, err, resp, true)
        );
    }

    /**
     * The handler that updates a product object from the data passed in the request body.
     * @method
     *
     * @param {object} req the current {@link http://expressjs.com/4x/api.html#req|request object}.
     * @param {object} res the {@link http://expressjs.com/4x/api.html#res|response object}.
     * @param {function} next the next middleware function to invoke, if any.
     */
    static update(req, res, next) {
        const errors = ProductHandler.validateData(req);
        if (errors) {
            res.status(400).json({errors: errors});
            return;
        }

        const args = {
            index: req.config.mainIndex,
            type: 'product',
            id: req.params.id,
            body: {doc: ProductHandler.toElasticsearchFormat(req, req.body)},
            refresh: true
        };

        client.update(args,
            (err, resp, respcode) =>
            common.saveCallback(req, res, err, resp, false)
        );
    }

    /**
     * The handler that deletes a product object identified by the given id.
     * @method
     *
     * @param {object} req the current {@link http://expressjs.com/4x/api.html#req|request object}.
     * @param {object} res the {@link http://expressjs.com/4x/api.html#res|response object}.
     * @param {function} next the next middleware function to invoke, if any.
     */
    static delete(req, res, next) {
        client.delete({
            index: req.config.mainIndex,
            type: 'product',
            refresh: true,
            id: req.params.id
        }, function(err, resp, respcode) {
            if (err) {
                console.log(err);
                res.status(400).end();
            }
            else {
                res.status(200).end();
            }
        });
    }
}

module.exports = ProductHandler;<|endoftext|>


<commit_before>var keystone = require('keystone'),
	async = require('async'),
	_ = require('underscore'),
	moment = require('moment');

exports = module.exports = function(req, res) {

	var data = {};

	async.series([
		function(next) {
			if (!req.body.user) return next();
			keystone.list('User').model.findById(req.body.user).exec(function(err, user) {
				if (err || !user) return res.apiResponse({ success: false });
				data.user = user;
				return next();
			});
		},
		function(next) {
			keystone.list('Meetup').model.findOne()
				.where('date').gte(moment().startOf('day').toDate())
				.where('state', 'active')
				.sort('date')
				.exec(function(err, meetup) {
					data.meetup = meetup;
					return next();
				});
		},
		function(next) {
			keystone.list('Talk').model.find()
				.where('meetup', data.meetup)
				.populate('who')
				.sort('sortOrder')
				.exec(function(err, talks) {
					data.talks = talks;
					return next();
				});
		},
		function(next) {
			if (!req.body.user) return next();
			keystone.list('RSVP').model.findOne()
				.where('who', data.user)
				.where('meetup', data.meetup)
				.exec(function(err, rsvp) {
					data.rsvp = rsvp;
					return next();
				});
		}
	], function(err) {
		var response = {
			success: true,
			meetup: false,
			user: false
		}
		var from = data.meetup ? _.first(data.meetup.time.split('-')).trim() : false;
			date = data.meetup ? moment(data.meetup.date + (from ? ' ' + from : ''), 'YYYY-MM-DD' + (from ? ' ha' : '')) : false;
		if (data.meetup && moment().isBefore(date)) {
			response.meetup = {
				id: data.meetup._id,

				name: data.meetup.name,

				date: date.toDate(),

				ticketsAvailable: data.meetup.rsvpsAvailable,
				ticketsRemaining: data.meetup.remainingRSVPs,

				talks: data.talks,

				rsvped: data.rsvp ? true : false,
				attending: data.rsvp && data.rsvp.attending ? true : false,
			}
		}
		if (data.user) {
			response.user = {
				date: new Date().getTime(),
				userId: data.user.id,
				name: {
					first: data.user.name.first,
					last: data.user.name.last,
					full: data.user.name.full
				},
				email: data.user.email,
				services: {
					github: {},
					facebook: {},
					twitter: {},
					pushNotifications: data.user.services.pushNotifications
				}
			}
		}
		res.apiResponse(response);
	});
}
<commit_msg>Tweaking status API.<commit_after>var keystone = require('keystone'),
	async = require('async'),
	_ = require('underscore'),
	moment = require('moment');

exports = module.exports = function(req, res) {

	var data = {};

	async.series([
		function(next) {
			if (!req.body.user) return next();
			keystone.list('User').model.findById(req.body.user).exec(function(err, user) {
				if (err || !user) return res.apiResponse({ success: false });
				data.user = user;
				return next();
			});
		},
		function(next) {
			keystone.list('Meetup').model.findOne()
				.where('date').gte(moment().startOf('day').toDate())
				.where('state', 'active')
				.sort('date')
				.exec(function(err, meetup) {
					data.meetup = meetup;
					return next();
				});
		},
		function(next) {
			keystone.list('Talk').model.find()
				.where('meetup', data.meetup)
				.populate('who')
				.sort('sortOrder')
				.exec(function(err, talks) {
					data.talks = talks;
					return next();
				});
		},
		function(next) {
			if (!req.body.user) return next();
			keystone.list('RSVP').model.findOne()
				.where('who', data.user)
				.where('meetup', data.meetup)
				.exec(function(err, rsvp) {
					data.rsvp = rsvp;
					return next();
				});
		}
	], function(err) {
		var response = {
			success: true,
			meetup: false,
			user: false
		}
		// TODO: Would really help if meetups had an actual time field
		var day = moment(data.meetup.date).format('YYYY-MM-DD'),
			from = data.meetup ? _.first(data.meetup.time.split('-')).trim() : false,
			date = data.meetup ? moment(day + (from ? ' ' + from : ''), 'YYYY-MM-DD' + (from ? ' ha' : '')) : false;
		if (data.meetup && moment().isBefore(date)) {
			response.meetup = {
				id: data.meetup._id,

				name: data.meetup.name,

				date: date.toDate(),

				ticketsAvailable: data.meetup.rsvpsAvailable,
				ticketsRemaining: data.meetup.remainingRSVPs,

				talks: data.talks,

				rsvped: data.rsvp ? true : false,
				attending: data.rsvp && data.rsvp.attending ? true : false,
			}
		}
		if (data.user) {
			response.user = {
				date: new Date().getTime(),
				userId: data.user.id,
				name: {
					first: data.user.name.first,
					last: data.user.name.last,
					full: data.user.name.full
				},
				email: data.user.email,
				services: {
					github: {},
					facebook: {},
					twitter: {},
					pushNotifications: data.user.services.pushNotifications
				}
			}
		}
		res.apiResponse(response);
	});
}
<|endoftext|>


<commit_before>var path = require('path');
var _ = require('lodash');
var constants = require('../services/const');
var firebaseServ = require('../services/FirebaseServ');
var userAgentServ = require('../services/UserAgentServ');

var defaultThumb = require('../services/const').defaultThumb;
module.exports = function oneListingSale(express) {
    var oneListingSaleRouter = express.Router();
    oneListingSaleRouter.get('/:mls', function (req, res, next) {
        var mls = req.params.mls;
        var userAgent = req.get('user-agent');
        var rootUrl = (req.protocol || 'http') + '://' + req.get('host');
        var fullUrl = rootUrl + req.originalUrl;

        if (userAgentServ.amIBot(userAgent)) {
            var homeUrl = constants.url + 'homes/sale/' + mls;
            firebaseServ.getItem(homeUrl).then(function (home) {
                /*og listing properties*/
                home.img = home.images ? home.images[0] : defaultThumb;
                home.fullAddress = home.address.street + ', ' + home.address.city + ', ' + home.address.state + ', ' + home.address.zip;
                home.description = home.type + ': Price: ' + home.price + home.beds + 'beds,' + home.bath + 'baths, in' + home.address.city;
                var vm = {
                    url: fullUrl,
                    title: home.fullAddress,
                    og: {
                        url: fullUrl,
                        title: home.fullAddress,
                        description: 'Check out and schedule a showing for a ' + home.description,
                        image: home.img
                    }
                };
                vm.home = home;

                res.render('one-listing', {vm: vm});

            }, function (Error) {
                console.log(Error.message);

            });
        } else {
            next();
        }
    });

    /*Redirect user to AngularJs App*/
    var appFolder = require('./dirServ')();
    oneListingSaleRouter.use(express.static(appFolder));

    oneListingSaleRouter.get('/:mls/', function (req, res) {
        res.sendFile('index.html', {root: appFolder});
    });
    return oneListingSaleRouter;

};
<commit_msg>Facebook share functionality for a listing<commit_after>var path = require('path');
var _ = require('lodash');
var constants = require('../services/const');
var firebaseServ = require('../services/FirebaseServ');
var userAgentServ = require('../services/UserAgentServ');

var defaultThumb = require('../services/const').defaultThumb;
module.exports = function oneListingSale(express) {
    var oneListingSaleRouter = express.Router();
    oneListingSaleRouter.get('/:mls', function (req, res, next) {
        var mls = req.params.mls;
        var userAgent = req.get('user-agent');
        var rootUrl = (req.protocol || 'http') + '://' + req.get('host');
        var fullUrl = rootUrl + req.originalUrl;

        if (userAgentServ.amIBot(userAgent)) {
            var homeUrl = constants.url + 'homes/sale/' + mls;
            firebaseServ.getItem(homeUrl).then(function (home) {
                /*og listing properties*/
                home.img = home.images ? home.images[0] : defaultThumb;
                home.fullAddress = home.address.street + ', ' + home.address.city + ', ' + home.address.state + ', ' + home.address.zip;
                home.fullDescription = 'Check out and schedule a showing for a ' + home.type + ': Price: $' + home.price + ', ' + home.beds + ' beds,' + home.bath + ' baths, in' + home.address.city + ', ' + home.address.zip;
                var vm = {
                    url: fullUrl,
                    title: home.fullAddress,
                    image: home.img,
                    og: {
                        url: fullUrl,
                        title: home.fullAddress,
                        description: home.fullDescription,
                        image: home.img
                    }
                };
                vm.home = home;

                res.render('one-listing', {vm: vm});

            }, function (Error) {
                console.log(Error.message);

            });
        } else {
            next();
        }
    });

    /*Redirect user to AngularJs App*/
    var appFolder = require('./dirServ')();
    oneListingSaleRouter.use(express.static(appFolder));

    oneListingSaleRouter.get('/:mls/', function (req, res) {
        res.sendFile('index.html', {root: appFolder});
    });
    return oneListingSaleRouter;

};
<|endoftext|>


<commit_before>import {
	Clock,
	Color,
	LinearEncoding,
	Matrix4,
	Mesh,
	RepeatWrapping,
	ShaderMaterial,
	TextureLoader,
	UniformsLib,
	UniformsUtils,
	Vector2,
	Vector4
} from '../../../build/three.module.js';
import { Reflector } from '../objects/Reflector.js';
import { Refractor } from '../objects/Refractor.js';

/**
 * References:
 *	http://www.valvesoftware.com/publications/2010/siggraph2010_vlachos_waterflow.pdf
 * 	http://graphicsrunner.blogspot.de/2010/08/water-using-flow-maps.html
 *
 */

class Water extends Mesh {

	constructor( geometry, options = {} ) {

		super( geometry );

		this.type = 'Water';

		const scope = this;

		const color = ( options.color !== undefined ) ? new Color( options.color ) : new Color( 0xFFFFFF );
		const textureWidth = options.textureWidth || 512;
		const textureHeight = options.textureHeight || 512;
		const clipBias = options.clipBias || 0;
		const flowDirection = options.flowDirection || new Vector2( 1, 0 );
		const flowSpeed = options.flowSpeed || 0.03;
		const reflectivity = options.reflectivity || 0.02;
		const scale = options.scale || 1;
		const shader = options.shader || Water.WaterShader;
		const encoding = options.encoding !== undefined ? options.encoding : LinearEncoding;

		const textureLoader = new TextureLoader();

		const flowMap = options.flowMap || undefined;
		const normalMap0 = options.normalMap0 || textureLoader.load( 'textures/water/Water_1_M_Normal.jpg' );
		const normalMap1 = options.normalMap1 || textureLoader.load( 'textures/water/Water_2_M_Normal.jpg' );

		const cycle = 0.15; // a cycle of a flow map phase
		const halfCycle = cycle * 0.5;
		const textureMatrix = new Matrix4();
		const clock = new Clock();

		// internal components

		if ( Reflector === undefined ) {

			console.error( 'THREE.Water: Required component Reflector not found.' );
			return;

		}

		if ( Refractor === undefined ) {

			console.error( 'THREE.Water: Required component Refractor not found.' );
			return;

		}

		const reflector = new Reflector( geometry, {
			textureWidth: textureWidth,
			textureHeight: textureHeight,
			clipBias: clipBias,
			encoding: encoding
		} );

		const refractor = new Refractor( geometry, {
			textureWidth: textureWidth,
			textureHeight: textureHeight,
			clipBias: clipBias,
			encoding: encoding
		} );

		reflector.matrixAutoUpdate = false;
		refractor.matrixAutoUpdate = false;

		// material

		this.material = new ShaderMaterial( {
			uniforms: UniformsUtils.merge( [
				UniformsLib[ 'fog' ],
				shader.uniforms
			] ),
			vertexShader: shader.vertexShader,
			fragmentShader: shader.fragmentShader,
			transparent: true,
			fog: true
		} );

		if ( flowMap !== undefined ) {

			this.material.defines.USE_FLOWMAP = '';
			this.material.uniforms[ 'tFlowMap' ] = {
				type: 't',
				value: flowMap
			};

		} else {

			this.material.uniforms[ 'flowDirection' ] = {
				type: 'v2',
				value: flowDirection
			};

		}

		// maps

		normalMap0.wrapS = normalMap0.wrapT = RepeatWrapping;
		normalMap1.wrapS = normalMap1.wrapT = RepeatWrapping;

		this.material.uniforms[ 'tReflectionMap' ].value = reflector.getRenderTarget().texture;
		this.material.uniforms[ 'tRefractionMap' ].value = refractor.getRenderTarget().texture;
		this.material.uniforms[ 'tNormalMap0' ].value = normalMap0;
		this.material.uniforms[ 'tNormalMap1' ].value = normalMap1;

		// water

		this.material.uniforms[ 'color' ].value = color;
		this.material.uniforms[ 'reflectivity' ].value = reflectivity;
		this.material.uniforms[ 'textureMatrix' ].value = textureMatrix;

		// inital values

		this.material.uniforms[ 'config' ].value.x = 0; // flowMapOffset0
		this.material.uniforms[ 'config' ].value.y = halfCycle; // flowMapOffset1
		this.material.uniforms[ 'config' ].value.z = halfCycle; // halfCycle
		this.material.uniforms[ 'config' ].value.w = scale; // scale

		// functions

		function updateTextureMatrix( camera ) {

			textureMatrix.set(
				0.5, 0.0, 0.0, 0.5,
				0.0, 0.5, 0.0, 0.5,
				0.0, 0.0, 0.5, 0.5,
				0.0, 0.0, 0.0, 1.0
			);

			textureMatrix.multiply( camera.projectionMatrix );
			textureMatrix.multiply( camera.matrixWorldInverse );
			textureMatrix.multiply( scope.matrixWorld );

		}

		function updateFlow() {

			const delta = clock.getDelta();
			const config = scope.material.uniforms[ 'config' ];

			config.value.x += flowSpeed * delta; // flowMapOffset0
			config.value.y = config.value.x + halfCycle; // flowMapOffset1

			// Important: The distance between offsets should be always the value of "halfCycle".
			// Moreover, both offsets should be in the range of [ 0, cycle ].
			// This approach ensures a smooth water flow and avoids "reset" effects.

			if ( config.value.x >= cycle ) {

				config.value.x = 0;
				config.value.y = halfCycle;

			} else if ( config.value.y >= cycle ) {

				config.value.y = config.value.y - cycle;

			}

		}

		//

		this.onBeforeRender = function ( renderer, scene, camera ) {

			updateTextureMatrix( camera );
			updateFlow();

			scope.visible = false;

			reflector.matrixWorld.copy( scope.matrixWorld );
			refractor.matrixWorld.copy( scope.matrixWorld );

			reflector.onBeforeRender( renderer, scene, camera );
			refractor.onBeforeRender( renderer, scene, camera );

			scope.visible = true;

		};

	}

}

Water.prototype.isWater = true;

Water.WaterShader = {

	uniforms: {

		'color': {
			type: 'c',
			value: null
		},

		'reflectivity': {
			type: 'f',
			value: 0
		},

		'tReflectionMap': {
			type: 't',
			value: null
		},

		'tRefractionMap': {
			type: 't',
			value: null
		},

		'tNormalMap0': {
			type: 't',
			value: null
		},

		'tNormalMap1': {
			type: 't',
			value: null
		},

		'textureMatrix': {
			type: 'm4',
			value: null
		},

		'config': {
			type: 'v4',
			value: new Vector4()
		}

	},

	vertexShader: /* glsl */`

		#include <common>
		#include <fog_pars_vertex>
		#include <logdepthbuf_pars_vertex>

		uniform mat4 textureMatrix;

		varying vec4 vCoord;
		varying vec2 vUv;
		varying vec3 vToEye;

		void main() {

			vUv = uv;
			vCoord = textureMatrix * vec4( position, 1.0 );

			vec4 worldPosition = modelMatrix * vec4( position, 1.0 );
			vToEye = cameraPosition - worldPosition.xyz;

			vec4 mvPosition =  viewMatrix * worldPosition; // used in fog_vertex
			gl_Position = projectionMatrix * mvPosition;

			#include <logdepthbuf_vertex>
			#include <fog_vertex>

		}`,

	fragmentShader: /* glsl */`

		#include <common>
		#include <fog_pars_fragment>
		#include <logdepthbuf_pars_fragment>

		uniform sampler2D tReflectionMap;
		uniform sampler2D tRefractionMap;
		uniform sampler2D tNormalMap0;
		uniform sampler2D tNormalMap1;

		#ifdef USE_FLOWMAP
			uniform sampler2D tFlowMap;
		#else
			uniform vec2 flowDirection;
		#endif

		uniform vec3 color;
		uniform float reflectivity;
		uniform vec4 config;

		varying vec4 vCoord;
		varying vec2 vUv;
		varying vec3 vToEye;

		void main() {

			#include <logdepthbuf_fragment>

			float flowMapOffset0 = config.x;
			float flowMapOffset1 = config.y;
			float halfCycle = config.z;
			float scale = config.w;

			vec3 toEye = normalize( vToEye );

			// determine flow direction
			vec2 flow;
			#ifdef USE_FLOWMAP
				flow = texture2D( tFlowMap, vUv ).rg * 2.0 - 1.0;
			#else
				flow = flowDirection;
			#endif
			flow.x *= - 1.0;

			// sample normal maps (distort uvs with flowdata)
			vec4 normalColor0 = texture2D( tNormalMap0, ( vUv * scale ) + flow * flowMapOffset0 );
			vec4 normalColor1 = texture2D( tNormalMap1, ( vUv * scale ) + flow * flowMapOffset1 );

			// linear interpolate to get the final normal color
			float flowLerp = abs( halfCycle - flowMapOffset0 ) / halfCycle;
			vec4 normalColor = mix( normalColor0, normalColor1, flowLerp );

			// calculate normal vector
			vec3 normal = normalize( vec3( normalColor.r * 2.0 - 1.0, normalColor.b,  normalColor.g * 2.0 - 1.0 ) );

			// calculate the fresnel term to blend reflection and refraction maps
			float theta = max( dot( toEye, normal ), 0.0 );
			float reflectance = reflectivity + ( 1.0 - reflectivity ) * pow( ( 1.0 - theta ), 5.0 );

			// calculate final uv coords
			vec3 coord = vCoord.xyz / vCoord.w;
			vec2 uv = coord.xy + coord.z * normal.xz * 0.05;

			vec4 reflectColor = texture2D( tReflectionMap, vec2( 1.0 - uv.x, uv.y ) );
			vec4 refractColor = texture2D( tRefractionMap, uv );

			// multiply water color with the mix of both textures
			gl_FragColor = vec4( color, 1.0 ) * mix( refractColor, reflectColor, reflectance );

			#include <tonemapping_fragment>
			#include <encodings_fragment>
			#include <fog_fragment>

		}`

};

export { Water };
<commit_msg>Water2: Remove encoding option. (#22955)<commit_after>import {
	Clock,
	Color,
	Matrix4,
	Mesh,
	RepeatWrapping,
	ShaderMaterial,
	TextureLoader,
	UniformsLib,
	UniformsUtils,
	Vector2,
	Vector4
} from '../../../build/three.module.js';
import { Reflector } from '../objects/Reflector.js';
import { Refractor } from '../objects/Refractor.js';

/**
 * References:
 *	http://www.valvesoftware.com/publications/2010/siggraph2010_vlachos_waterflow.pdf
 * 	http://graphicsrunner.blogspot.de/2010/08/water-using-flow-maps.html
 *
 */

class Water extends Mesh {

	constructor( geometry, options = {} ) {

		super( geometry );

		this.type = 'Water';

		const scope = this;

		const color = ( options.color !== undefined ) ? new Color( options.color ) : new Color( 0xFFFFFF );
		const textureWidth = options.textureWidth || 512;
		const textureHeight = options.textureHeight || 512;
		const clipBias = options.clipBias || 0;
		const flowDirection = options.flowDirection || new Vector2( 1, 0 );
		const flowSpeed = options.flowSpeed || 0.03;
		const reflectivity = options.reflectivity || 0.02;
		const scale = options.scale || 1;
		const shader = options.shader || Water.WaterShader;

		const textureLoader = new TextureLoader();

		const flowMap = options.flowMap || undefined;
		const normalMap0 = options.normalMap0 || textureLoader.load( 'textures/water/Water_1_M_Normal.jpg' );
		const normalMap1 = options.normalMap1 || textureLoader.load( 'textures/water/Water_2_M_Normal.jpg' );

		const cycle = 0.15; // a cycle of a flow map phase
		const halfCycle = cycle * 0.5;
		const textureMatrix = new Matrix4();
		const clock = new Clock();

		// internal components

		if ( Reflector === undefined ) {

			console.error( 'THREE.Water: Required component Reflector not found.' );
			return;

		}

		if ( Refractor === undefined ) {

			console.error( 'THREE.Water: Required component Refractor not found.' );
			return;

		}

		const reflector = new Reflector( geometry, {
			textureWidth: textureWidth,
			textureHeight: textureHeight,
			clipBias: clipBias
		} );

		const refractor = new Refractor( geometry, {
			textureWidth: textureWidth,
			textureHeight: textureHeight,
			clipBias: clipBias
		} );

		reflector.matrixAutoUpdate = false;
		refractor.matrixAutoUpdate = false;

		// material

		this.material = new ShaderMaterial( {
			uniforms: UniformsUtils.merge( [
				UniformsLib[ 'fog' ],
				shader.uniforms
			] ),
			vertexShader: shader.vertexShader,
			fragmentShader: shader.fragmentShader,
			transparent: true,
			fog: true
		} );

		if ( flowMap !== undefined ) {

			this.material.defines.USE_FLOWMAP = '';
			this.material.uniforms[ 'tFlowMap' ] = {
				type: 't',
				value: flowMap
			};

		} else {

			this.material.uniforms[ 'flowDirection' ] = {
				type: 'v2',
				value: flowDirection
			};

		}

		// maps

		normalMap0.wrapS = normalMap0.wrapT = RepeatWrapping;
		normalMap1.wrapS = normalMap1.wrapT = RepeatWrapping;

		this.material.uniforms[ 'tReflectionMap' ].value = reflector.getRenderTarget().texture;
		this.material.uniforms[ 'tRefractionMap' ].value = refractor.getRenderTarget().texture;
		this.material.uniforms[ 'tNormalMap0' ].value = normalMap0;
		this.material.uniforms[ 'tNormalMap1' ].value = normalMap1;

		// water

		this.material.uniforms[ 'color' ].value = color;
		this.material.uniforms[ 'reflectivity' ].value = reflectivity;
		this.material.uniforms[ 'textureMatrix' ].value = textureMatrix;

		// inital values

		this.material.uniforms[ 'config' ].value.x = 0; // flowMapOffset0
		this.material.uniforms[ 'config' ].value.y = halfCycle; // flowMapOffset1
		this.material.uniforms[ 'config' ].value.z = halfCycle; // halfCycle
		this.material.uniforms[ 'config' ].value.w = scale; // scale

		// functions

		function updateTextureMatrix( camera ) {

			textureMatrix.set(
				0.5, 0.0, 0.0, 0.5,
				0.0, 0.5, 0.0, 0.5,
				0.0, 0.0, 0.5, 0.5,
				0.0, 0.0, 0.0, 1.0
			);

			textureMatrix.multiply( camera.projectionMatrix );
			textureMatrix.multiply( camera.matrixWorldInverse );
			textureMatrix.multiply( scope.matrixWorld );

		}

		function updateFlow() {

			const delta = clock.getDelta();
			const config = scope.material.uniforms[ 'config' ];

			config.value.x += flowSpeed * delta; // flowMapOffset0
			config.value.y = config.value.x + halfCycle; // flowMapOffset1

			// Important: The distance between offsets should be always the value of "halfCycle".
			// Moreover, both offsets should be in the range of [ 0, cycle ].
			// This approach ensures a smooth water flow and avoids "reset" effects.

			if ( config.value.x >= cycle ) {

				config.value.x = 0;
				config.value.y = halfCycle;

			} else if ( config.value.y >= cycle ) {

				config.value.y = config.value.y - cycle;

			}

		}

		//

		this.onBeforeRender = function ( renderer, scene, camera ) {

			updateTextureMatrix( camera );
			updateFlow();

			scope.visible = false;

			reflector.matrixWorld.copy( scope.matrixWorld );
			refractor.matrixWorld.copy( scope.matrixWorld );

			reflector.onBeforeRender( renderer, scene, camera );
			refractor.onBeforeRender( renderer, scene, camera );

			scope.visible = true;

		};

	}

}

Water.prototype.isWater = true;

Water.WaterShader = {

	uniforms: {

		'color': {
			type: 'c',
			value: null
		},

		'reflectivity': {
			type: 'f',
			value: 0
		},

		'tReflectionMap': {
			type: 't',
			value: null
		},

		'tRefractionMap': {
			type: 't',
			value: null
		},

		'tNormalMap0': {
			type: 't',
			value: null
		},

		'tNormalMap1': {
			type: 't',
			value: null
		},

		'textureMatrix': {
			type: 'm4',
			value: null
		},

		'config': {
			type: 'v4',
			value: new Vector4()
		}

	},

	vertexShader: /* glsl */`

		#include <common>
		#include <fog_pars_vertex>
		#include <logdepthbuf_pars_vertex>

		uniform mat4 textureMatrix;

		varying vec4 vCoord;
		varying vec2 vUv;
		varying vec3 vToEye;

		void main() {

			vUv = uv;
			vCoord = textureMatrix * vec4( position, 1.0 );

			vec4 worldPosition = modelMatrix * vec4( position, 1.0 );
			vToEye = cameraPosition - worldPosition.xyz;

			vec4 mvPosition =  viewMatrix * worldPosition; // used in fog_vertex
			gl_Position = projectionMatrix * mvPosition;

			#include <logdepthbuf_vertex>
			#include <fog_vertex>

		}`,

	fragmentShader: /* glsl */`

		#include <common>
		#include <fog_pars_fragment>
		#include <logdepthbuf_pars_fragment>

		uniform sampler2D tReflectionMap;
		uniform sampler2D tRefractionMap;
		uniform sampler2D tNormalMap0;
		uniform sampler2D tNormalMap1;

		#ifdef USE_FLOWMAP
			uniform sampler2D tFlowMap;
		#else
			uniform vec2 flowDirection;
		#endif

		uniform vec3 color;
		uniform float reflectivity;
		uniform vec4 config;

		varying vec4 vCoord;
		varying vec2 vUv;
		varying vec3 vToEye;

		void main() {

			#include <logdepthbuf_fragment>

			float flowMapOffset0 = config.x;
			float flowMapOffset1 = config.y;
			float halfCycle = config.z;
			float scale = config.w;

			vec3 toEye = normalize( vToEye );

			// determine flow direction
			vec2 flow;
			#ifdef USE_FLOWMAP
				flow = texture2D( tFlowMap, vUv ).rg * 2.0 - 1.0;
			#else
				flow = flowDirection;
			#endif
			flow.x *= - 1.0;

			// sample normal maps (distort uvs with flowdata)
			vec4 normalColor0 = texture2D( tNormalMap0, ( vUv * scale ) + flow * flowMapOffset0 );
			vec4 normalColor1 = texture2D( tNormalMap1, ( vUv * scale ) + flow * flowMapOffset1 );

			// linear interpolate to get the final normal color
			float flowLerp = abs( halfCycle - flowMapOffset0 ) / halfCycle;
			vec4 normalColor = mix( normalColor0, normalColor1, flowLerp );

			// calculate normal vector
			vec3 normal = normalize( vec3( normalColor.r * 2.0 - 1.0, normalColor.b,  normalColor.g * 2.0 - 1.0 ) );

			// calculate the fresnel term to blend reflection and refraction maps
			float theta = max( dot( toEye, normal ), 0.0 );
			float reflectance = reflectivity + ( 1.0 - reflectivity ) * pow( ( 1.0 - theta ), 5.0 );

			// calculate final uv coords
			vec3 coord = vCoord.xyz / vCoord.w;
			vec2 uv = coord.xy + coord.z * normal.xz * 0.05;

			vec4 reflectColor = texture2D( tReflectionMap, vec2( 1.0 - uv.x, uv.y ) );
			vec4 refractColor = texture2D( tRefractionMap, uv );

			// multiply water color with the mix of both textures
			gl_FragColor = vec4( color, 1.0 ) * mix( refractColor, reflectColor, reflectance );

			#include <tonemapping_fragment>
			#include <encodings_fragment>
			#include <fog_fragment>

		}`

};

export { Water };
<|endoftext|>


<commit_before>(function (env) {
    "use strict";
    env.ddg_spice_bitcoin_balance = function(api_result){

        if (!api_result || api_result.error) {
            return Spice.failed('bitcoin_balance');
        }

        Spice.add({
            id: "bitcoinBalance",
            name: "Bitcoin Address",
            data: {
                balance: api_result.balance / 100000000
                //The balance field on the API returns satoshis, so we divide by 100000000 to convert to BTC.
            },
            meta: {
                sourceName: "Chain.com",
                sourceUrl: "http://chain.com"
            },
            templates: {
                group: 'info',
                options:{
                    content: Spice.bitcoin_balance.content,
                    moreAt: true
                }
            }
        });
    };
}(this));<commit_msg>"more" at links to Bitcoin address page at chain.com<commit_after>(function (env) {
    "use strict";
    env.ddg_spice_bitcoin_balance = function(api_result){

        if (!api_result || api_result.error) {
            return Spice.failed('bitcoin_balance');
        }

        Spice.add({
            id: "bitcoinBalance",
            name: "Bitcoin Address",
            data: {
                balance: api_result.balance / 100000000.0
                //The balance field on the API returns satoshis, so we divide by 100000000 to convert to BTC.
            },
            meta: {
                sourceName: "Chain.com",
                sourceUrl: "https://chain.com/bitcoin/addresses/" + api_result.hash
            },
            templates: {
                group: 'info',
                options:{
                    content: Spice.bitcoin_balance.content,
                    moreAt: true
                }
            }
        });
    };
}(this));<|endoftext|>


<commit_before>const mongoose = require('mongoose');
const MODULES_PATH = './../modules/';
const MODEL_PATH = 'users/';
const MODEL = 'user_model';
const Model = require(MODULES_PATH + MODEL_PATH + MODEL);

const Returns = [
  {'save': Object}
, {'insert': Object}
, {'create': Object}
, {'update': Object}
, {'remove': Object}
];

function testReturn(action, data) {
  console.log('action', action, data)
};

// save
// Deve retornar o mesmo objeto do Schema acrescido de:
// _id
// __v
// Verificar cada valor persistido

// var saveReturn = { __v: 0,
//   _id: "",
//   created_at: "",
//   category: '""',
//   price: "",
//   alcohol: "",
//   description: "",
//   name: "" }

// save
// { __v: 0,
//   _id: 560b790c5747b5491c662170,
//   created_at: Wed Sep 30 2015 02:54:20 GMT-0300 (BRT),
//   category: 'pilsen',
//   price: 3,
//   alcohol: 4.5,
//   description: 'Mijo de rato',
//   name: 'Skol' }<commit_msg>Validador do find do mongoose - ideia<commit_after>const mongoose = require('mongoose');
const MODULES_PATH = './../modules/';
const MODEL_PATH = 'users/';
const MODEL = 'user_model';
const Model = require(MODULES_PATH + MODEL_PATH + MODEL);

const Returns = [
  {'save': Object}
, {'insert': Object}
, {'create': Object}
, {'update': Object}
, {'remove': Object}
];

function testReturn(action, data) {
  console.log('action', action, data)
};

// Create: save
// Verifica se veio como Object
// Roda o teste primitivo para Object
// Deve retornar o mesmo objeto do Schema acrescido de:
// _id
// __v
// Verificar cada valor persistido

// var saveReturn = { __v: 0,
//   _id: "",
//   created_at: "",
//   category: '""',
//   price: "",
//   alcohol: "",
//   description: "",
//   name: "" }

// Retrieve: find
// armazena o count() da coleção
// Verifica se veio como Array
// Roda o teste primitivo para Array
// Verifica a quantidade de registros retornados

<|endoftext|>


<commit_before>var log = require('../../log').logger('manual');
var config = require('../../config');
var stream = require('stream');
var util = require('util');
var events = require('events')
var Q = require('q');

var T_RENEW = 200;
var SAFETY_FACTOR = 2.0;
var count;
var RENEW_SEGMENTS = 10;
var FIXED_MOVES_QUEUE_SIZE = 3;
var count = 0;

function ManualDriver(drv, st) {
	this.stream = st;
	this.driver = drv;

	this.fixedQueue = [];

	this.exited = false;

	// True while the tool is known to be in motion
	this.moving = false;

	// True while the user intends (as far as we know) for the tool to continue moving
	this.keep_moving = false;

	// Set to true to exit the manual state once the current operation is completed
	this.exit_pending = false;

	this.stop_pending = false;

	// Current trajectory
	this.current_axis = null;
	this.current_speed = null;
	this.completeCallback = null;
	this.status_handler = this._onG2Status.bind(this);
	this.driver.on('status',this.status_handler);
//	var this.deferred = this.enter();
}
util.inherits(ManualDriver, events.EventEmitter);

ManualDriver.prototype.enter = function() {
	var jerkXY = config.machine._cache.manual.xy_jerk || 250;
	var jerkZ = config.machine._cache.manual.z_jerk || 250;
    this.stream.write('M100.1 ({xjm:'+jerkXY+'})\n');
    this.stream.write('M100.1 ({yjm:'+jerkXY+'})\n');
    this.stream.write('M100.1 ({zjm:'+jerkZ+'})\n');
    this.stream.write('M100.1 ({zl:0})\n');
	this.driver.prime();
	this.deferred = Q.defer();
	return this.deferred.promise;

}

ManualDriver.prototype.exit = function() {
	if(this.isMoving()) {
		// Don't exit yet - just pend.
		this.exit_pending = true;
		this.stopMotion();

	} else {
		config.driver.restoreSome(['xjm','yjm','zjm', 'zl'], function() {
		    //log.info("Finished running stream: " + stat);
		    this._done();
        }.bind(this));
		this.driver.removeListener('status', this.status_handler);
		this.exited = true;
	}
}

ManualDriver.prototype.startMotion = function(axis,  speed, second_axis, second_speed) {
	log.debug("startMotion called")
	var dir = speed < 0 ? -1.0 : 1.0;
	var second_dir = second_speed < 0 ? -1.0 : 1.0;
	speed = Math.abs(speed);
	if(this.moving) {
		log.debug("Already moving")
		if(axis === this.currentAxis && speed === this.currentSpeed) {
			this.maintainMotion();
		} else {
			this.stopMotion();
			// Deal with direction changes here
		}
	} else {
		if (second_axis){
			this.second_axis = second_axis;
			this.second_currentDirection = second_dir;
		} else {
			this.second_axis = null;
			this.second_currentDirection = null;
		}
		log.debug("Not moving")
		// Set Heading
		this.currentAxis = axis;
		this.currentSpeed = speed;
		this.currentDirection = dir;

		this.moving = this.keep_moving = true;
		this.renewDistance = speed*(T_RENEW/60000)*SAFETY_FACTOR;
		this.stream.write('G91 F' + this.currentSpeed.toFixed(3) + '\n');
		this._renewMoves();
	}
}

ManualDriver.prototype.maintainMotion = function() {
	if(this.moving) {
		this.keep_moving = true;
	}
}

ManualDriver.prototype.stopMotion = function() {
	if(this._limit()) { return; }
	this.keep_moving = false;
	if(this.moving) {
		this.stop_pending = true;
		this.driver.feedHold();
		this.driver.queueFlush(function() {
			this.driver.resume();
		}.bind(this));
	} else {
		this.stop_pending = false;
	}
}

ManualDriver.prototype.quitMove = function(){

	if(this._limit()) { return; }
	this.keep_moving = false;
	if(this.moving) {
		this.stop_pending = true;
		this.driver.quit();
		this.driver.queueFlush(function() {
			this.driver.resume();
		}.bind(this));
	} else {
		this.stop_pending = false;
	}

}

ManualDriver.prototype.goto = function(pos) {
	var move = "G90\nG0 ";

	for (var key in pos) {
		if (pos.hasOwnProperty(key)) {
			move += key + pos[key] + " ";
		}
	}

	move += "\nG91\n";
	this.driver.prime();
	this.stream.write(move);
	this.moving = true;

}

ManualDriver.prototype.set = function(pos) {

	var gc = 'G10 L20 P2 ';

	Object.keys(pos).forEach(function(key) {
		console.log(pos);
		gc += key + pos[key].toFixed(5);
	}.bind(this));

		this.stream.write(gc + '\n');
		this.driver.prime();
		setTimeout(function() {
			config.driver.reverseUpdate(['g55x','g55y','g55z','g55a','g55b'], function(err, data) {console.log(data)});
			this.moving = false;
		}.bind(this), 500);

}

ManualDriver.prototype._handleNudges = function() {
	count = this.fixedQueue.length;

	if(this.fixedQueue.length > 0) {
		while(this.fixedQueue.length > 0) {
			var move = this.fixedQueue.shift();
			this.moving = true;
			this.keep_moving = false;
			var axis = move.axis.toUpperCase();

			if('XYZABCUVW'.indexOf(axis) >= 0) {
				var moves = ['G91'];
				if(move.second_axis) {
					var second_axis = move.second_axis.toUpperCase();
					if(move.speed) {
						moves.push('G1 ' + axis + move.distance.toFixed(5) +' '+ second_axis + move.second_distance.toFixed(5) + ' F' + move.speed.toFixed(3))
					} else {
						moves.push('G0 ' + axis + move.distance.toFixed(5)  +' '+ move.second_axis.toUpperCase + move.second_distance.toFixed(5) + ' F' + move.speed.toFixed(3))
					}
				} else {
					if(move.speed) {
						moves.push('G1 ' + axis + move.distance.toFixed(5) + ' F' + move.speed.toFixed(3))
					} else {
						moves.push('G0 ' + axis + move.distance.toFixed(5) + ' F' + move.speed.toFixed(3))
					}
				}

				moves.forEach(function(move) {
					this.stream.write(move + '\n');
					//this.stream.write('G4 P0.050\n');
				}.bind(this));
			}
		}
		this.driver.prime();
	} else {
		this.moving = this.keep_moving = false;
	}
	return count;
}

ManualDriver.prototype.nudge = function(axis, speed, distance, second_axis, second_distance) {
    if(this.fixedQueue.length >= FIXED_MOVES_QUEUE_SIZE) {
	log.warn('fixedMove(): Move queue is already full!');
    	    return;
	}
	if(second_axis) {
		this.fixedQueue.push({axis: axis, speed: speed, distance: distance, second_axis : second_axis, second_distance: second_distance});
	} else {
		this.fixedQueue.push({axis: axis, speed: speed, distance: distance});
	}

    if(this.moving) {
	//	this.fixedQueue.push({axis: axis, speed: speed, distance: distance});
		log.warn("fixedMove(): Queueing move, due to already moving.");
	} else {
		this._handleNudges();
	}
}

ManualDriver.prototype.isMoving = function() {
	return this.moving;
}

ManualDriver.prototype._renewMoves = function() {
	if(this.moving && this.keep_moving) {
		log.debug('Renewing moves because of reasons')
		this.keep_moving = false;
		var segment = this.currentDirection*(this.renewDistance / RENEW_SEGMENTS);
		var second_segment = this.second_currentDirection*(this.renewDistance / RENEW_SEGMENTS);
		if (this.second_axis){
			for(var i=0; i<RENEW_SEGMENTS; i++) {
				var move = 'G1 ' + this.currentAxis + segment.toFixed(5) +' '+ this.second_axis + second_segment.toFixed(5) +'\n'
				this.stream.write(move);
			}

		} else {
			for(var i=0; i<RENEW_SEGMENTS; i++) {
				var move = 'G1 ' + this.currentAxis + segment.toFixed(5) + '\n'
				this.stream.write(move);
			}
		}

		this.driver.prime();
		setTimeout(function() {
			this._renewMoves()
		}.bind(this), T_RENEW)
	} else {
		this.stopMotion();
	}
}

ManualDriver.prototype._onG2Status = function(status) {
	switch(status.stat) {
		case this.driver.STAT_INTERLOCK:
		case this.driver.STAT_SHUTDOWN:
		case this.driver.STAT_PANIC:
			this.emit('crash');
			break;
		case this.driver.STAT_ALARM:
			if(this._limit()) { return; }
			break;
		case this.driver.STAT_RUNNING:
			this.moving = true;
			break;
		case this.driver.STAT_STOP:
		case this.driver.STAT_END:
		case this.driver.STAT_HOLDING:
			if(this._handleNudges()) {
				// Nudges got handled
			} else {
				// No nudges
				if(this.exit_pending) {
					this.exit();
				}
				this.stop_pending = false;
			}
			break;
	}
};

ManualDriver.prototype._limit = function() {
	var er = this.driver.getLastException();
	if(er && er.st == 203) {
		var msg = er.msg.replace(/\[[^\[\]]*\]/,'');
		this.keep_moving = false;
		this.moving = false;
		this.driver.clearLastException();
		this.emit('crash', {error : msg});
		return true;
	}
	return false;
}

ManualDriver.prototype._done = function() {
	this.moving = false;
    this.keep_moving = false;
    this.stream = null;
	this.deferred.resolve();
}

module.exports = ManualDriver;<commit_msg>taking out log<commit_after>var log = require('../../log').logger('manual');
var config = require('../../config');
var stream = require('stream');
var util = require('util');
var events = require('events')
var Q = require('q');

var T_RENEW = 200;
var SAFETY_FACTOR = 2.0;
var count;
var RENEW_SEGMENTS = 10;
var FIXED_MOVES_QUEUE_SIZE = 3;
var count = 0;

function ManualDriver(drv, st) {
	this.stream = st;
	this.driver = drv;

	this.fixedQueue = [];

	this.exited = false;

	// True while the tool is known to be in motion
	this.moving = false;

	// True while the user intends (as far as we know) for the tool to continue moving
	this.keep_moving = false;

	// Set to true to exit the manual state once the current operation is completed
	this.exit_pending = false;

	this.stop_pending = false;

	// Current trajectory
	this.current_axis = null;
	this.current_speed = null;
	this.completeCallback = null;
	this.status_handler = this._onG2Status.bind(this);
	this.driver.on('status',this.status_handler);
//	var this.deferred = this.enter();
}
util.inherits(ManualDriver, events.EventEmitter);

ManualDriver.prototype.enter = function() {
	var jerkXY = config.machine._cache.manual.xy_jerk || 250;
	var jerkZ = config.machine._cache.manual.z_jerk || 250;
    this.stream.write('M100.1 ({xjm:'+jerkXY+'})\n');
    this.stream.write('M100.1 ({yjm:'+jerkXY+'})\n');
    this.stream.write('M100.1 ({zjm:'+jerkZ+'})\n');
    this.stream.write('M100.1 ({zl:0})\n');
	this.driver.prime();
	this.deferred = Q.defer();
	return this.deferred.promise;

}

ManualDriver.prototype.exit = function() {
	if(this.isMoving()) {
		// Don't exit yet - just pend.
		this.exit_pending = true;
		this.stopMotion();

	} else {
		config.driver.restoreSome(['xjm','yjm','zjm', 'zl'], function() {
		    //log.info("Finished running stream: " + stat);
		    this._done();
        }.bind(this));
		this.driver.removeListener('status', this.status_handler);
		this.exited = true;
	}
}

ManualDriver.prototype.startMotion = function(axis,  speed, second_axis, second_speed) {
	log.debug("startMotion called")
	var dir = speed < 0 ? -1.0 : 1.0;
	var second_dir = second_speed < 0 ? -1.0 : 1.0;
	speed = Math.abs(speed);
	if(this.moving) {
		log.debug("Already moving")
		if(axis === this.currentAxis && speed === this.currentSpeed) {
			this.maintainMotion();
		} else {
			this.stopMotion();
			// Deal with direction changes here
		}
	} else {
		if (second_axis){
			this.second_axis = second_axis;
			this.second_currentDirection = second_dir;
		} else {
			this.second_axis = null;
			this.second_currentDirection = null;
		}
		log.debug("Not moving")
		// Set Heading
		this.currentAxis = axis;
		this.currentSpeed = speed;
		this.currentDirection = dir;

		this.moving = this.keep_moving = true;
		this.renewDistance = speed*(T_RENEW/60000)*SAFETY_FACTOR;
		this.stream.write('G91 F' + this.currentSpeed.toFixed(3) + '\n');
		this._renewMoves();
	}
}

ManualDriver.prototype.maintainMotion = function() {
	if(this.moving) {
		this.keep_moving = true;
	}
}

ManualDriver.prototype.stopMotion = function() {
	if(this._limit()) { return; }
	this.keep_moving = false;
	if(this.moving) {
		this.stop_pending = true;
		this.driver.feedHold();
		this.driver.queueFlush(function() {
			this.driver.resume();
		}.bind(this));
	} else {
		this.stop_pending = false;
	}
}

ManualDriver.prototype.quitMove = function(){

	if(this._limit()) { return; }
	this.keep_moving = false;
	if(this.moving) {
		this.stop_pending = true;
		this.driver.quit();
		this.driver.queueFlush(function() {
			this.driver.resume();
		}.bind(this));
	} else {
		this.stop_pending = false;
	}

}

ManualDriver.prototype.goto = function(pos) {
	var move = "G90\nG0 ";

	for (var key in pos) {
		if (pos.hasOwnProperty(key)) {
			move += key + pos[key] + " ";
		}
	}

	move += "\nG91\n";
	this.driver.prime();
	this.stream.write(move);
	this.moving = true;

}

ManualDriver.prototype.set = function(pos) {

	var gc = 'G10 L20 P2 ';

	Object.keys(pos).forEach(function(key) {
		gc += key + pos[key].toFixed(5);
	}.bind(this));

		this.stream.write(gc + '\n');
		this.driver.prime();
		setTimeout(function() {
			config.driver.reverseUpdate(['g55x','g55y','g55z','g55a','g55b'], function(err, data) {console.log(data)});
			this.moving = false;
		}.bind(this), 500);

}

ManualDriver.prototype._handleNudges = function() {
	count = this.fixedQueue.length;

	if(this.fixedQueue.length > 0) {
		while(this.fixedQueue.length > 0) {
			var move = this.fixedQueue.shift();
			this.moving = true;
			this.keep_moving = false;
			var axis = move.axis.toUpperCase();

			if('XYZABCUVW'.indexOf(axis) >= 0) {
				var moves = ['G91'];
				if(move.second_axis) {
					var second_axis = move.second_axis.toUpperCase();
					if(move.speed) {
						moves.push('G1 ' + axis + move.distance.toFixed(5) +' '+ second_axis + move.second_distance.toFixed(5) + ' F' + move.speed.toFixed(3))
					} else {
						moves.push('G0 ' + axis + move.distance.toFixed(5)  +' '+ move.second_axis.toUpperCase + move.second_distance.toFixed(5) + ' F' + move.speed.toFixed(3))
					}
				} else {
					if(move.speed) {
						moves.push('G1 ' + axis + move.distance.toFixed(5) + ' F' + move.speed.toFixed(3))
					} else {
						moves.push('G0 ' + axis + move.distance.toFixed(5) + ' F' + move.speed.toFixed(3))
					}
				}

				moves.forEach(function(move) {
					this.stream.write(move + '\n');
					//this.stream.write('G4 P0.050\n');
				}.bind(this));
			}
		}
		this.driver.prime();
	} else {
		this.moving = this.keep_moving = false;
	}
	return count;
}

ManualDriver.prototype.nudge = function(axis, speed, distance, second_axis, second_distance) {
    if(this.fixedQueue.length >= FIXED_MOVES_QUEUE_SIZE) {
	log.warn('fixedMove(): Move queue is already full!');
    	    return;
	}
	if(second_axis) {
		this.fixedQueue.push({axis: axis, speed: speed, distance: distance, second_axis : second_axis, second_distance: second_distance});
	} else {
		this.fixedQueue.push({axis: axis, speed: speed, distance: distance});
	}

    if(this.moving) {
	//	this.fixedQueue.push({axis: axis, speed: speed, distance: distance});
		log.warn("fixedMove(): Queueing move, due to already moving.");
	} else {
		this._handleNudges();
	}
}

ManualDriver.prototype.isMoving = function() {
	return this.moving;
}

ManualDriver.prototype._renewMoves = function() {
	if(this.moving && this.keep_moving) {
		log.debug('Renewing moves because of reasons')
		this.keep_moving = false;
		var segment = this.currentDirection*(this.renewDistance / RENEW_SEGMENTS);
		var second_segment = this.second_currentDirection*(this.renewDistance / RENEW_SEGMENTS);
		if (this.second_axis){
			for(var i=0; i<RENEW_SEGMENTS; i++) {
				var move = 'G1 ' + this.currentAxis + segment.toFixed(5) +' '+ this.second_axis + second_segment.toFixed(5) +'\n'
				this.stream.write(move);
			}

		} else {
			for(var i=0; i<RENEW_SEGMENTS; i++) {
				var move = 'G1 ' + this.currentAxis + segment.toFixed(5) + '\n'
				this.stream.write(move);
			}
		}

		this.driver.prime();
		setTimeout(function() {
			this._renewMoves()
		}.bind(this), T_RENEW)
	} else {
		this.stopMotion();
	}
}

ManualDriver.prototype._onG2Status = function(status) {
	switch(status.stat) {
		case this.driver.STAT_INTERLOCK:
		case this.driver.STAT_SHUTDOWN:
		case this.driver.STAT_PANIC:
			this.emit('crash');
			break;
		case this.driver.STAT_ALARM:
			if(this._limit()) { return; }
			break;
		case this.driver.STAT_RUNNING:
			this.moving = true;
			break;
		case this.driver.STAT_STOP:
		case this.driver.STAT_END:
		case this.driver.STAT_HOLDING:
			if(this._handleNudges()) {
				// Nudges got handled
			} else {
				// No nudges
				if(this.exit_pending) {
					this.exit();
				}
				this.stop_pending = false;
			}
			break;
	}
};

ManualDriver.prototype._limit = function() {
	var er = this.driver.getLastException();
	if(er && er.st == 203) {
		var msg = er.msg.replace(/\[[^\[\]]*\]/,'');
		this.keep_moving = false;
		this.moving = false;
		this.driver.clearLastException();
		this.emit('crash', {error : msg});
		return true;
	}
	return false;
}

ManualDriver.prototype._done = function() {
	this.moving = false;
    this.keep_moving = false;
    this.stream = null;
	this.deferred.resolve();
}

module.exports = ManualDriver;<|endoftext|>


<commit_before>"use strict";

// Dependencies
var _ = require('lodash');
var express = require('express');
var path = require('path');
var env = process.env['NODE_ENV'] || 'development';
var port = process.env['PORT'] || 1337;
var pid = process.pid;

// Middleware
var cors = require('cors');
var bodyParser = require('body-parser');
var compress = require('compression');
var methodOverride = require('method-override');
var morgan  = require('morgan');
var favicon = require('serve-favicon');
var hbs = require('hbs');

// Bootie
var Bootie = require('bootie');

// Start express app
var app = express();
app.set('port', port);
app.enable('trust proxy'); // This lets req.ip show the real IP address on Heroku

// Config
var config = require('./config');
app.use(config.middleware);

// Middleware before Router

// Favicon
app.use(favicon(__dirname + '/public/favicon.ico'));

// Gzip compression (needs to be before static to compress assets)
app.use(compress());

// Logger
// app.use(morgan('dev'));
// Don't log 304
app.use(morgan({
  // format: 'dev',
  format: ':method :url :status - :remote-addr | :user-agent - :date - :response-time ms',
  skip: function(req, res) {
    return res.statusCode === 304;
  }
}));

// Enable CORS
app.use(cors());

// Support pseudo PUT/DELETE via headers
app.use(methodOverride());

// Static assets
var oneDay = 86400000;
var oneYear = 31536000000;
app.use(express.static(path.join(__dirname, '/public'), {
  maxAge: oneDay
}));

// Parse application/json and application/x-www-form-urlencoded
app.use(bodyParser());

// Parse application/vnd.api+json as json
app.use(bodyParser.json({ type: 'application/vnd.api+json' }));

// Database
// Connects to 2 mongo urls
var database = new Bootie.Database(config.database);

// Router
var TestController = require('./controllers/test');
var TestCrudController = require('./controllers/test_crud');

var router = new Bootie.Router({
  version: "v2",
  controllers: {
    test: new TestController(),
    test_crud: new TestCrudController({
      db: database.mongodbs.primary,
      cache: database.caches.primary
    })
  }
});
app.use(router.url, router);

// Middleware after Router

// Start the HTTP server
var server = app.listen(app.get('port'), function() {
  console.log('Listening on port %d', server.address().port);
});<commit_msg>example<commit_after>"use strict";

// Dependencies
var _ = require('lodash');
var express = require('express');
var path = require('path');
var env = process.env['NODE_ENV'] || 'development';
var port = process.env['PORT'] || 1337;
var pid = process.pid;

// Middleware
var cors = require('cors');
var bodyParser = require('body-parser');
var compress = require('compression');
var methodOverride = require('method-override');
var morgan  = require('morgan');
var favicon = require('serve-favicon');
var hbs = require('hbs');

// Bootie
var Bootie = require('bootie');

// Start express app
var app = express();
app.set('port', port);
app.enable('trust proxy'); // This lets req.ip show the real IP address on Heroku

// Config
var config = require('./config');
app.use(config.middleware);

// Middleware before Router

// Favicon
app.use(favicon(__dirname + '/public/favicon.ico'));

// Gzip compression (needs to be before static to compress assets)
app.use(compress());

// Logger
// app.use(morgan('dev'));
// Don't log 304
app.use(morgan({
  // format: 'dev',
  format: ':method :url :status - :remote-addr | :user-agent - :date - :response-time ms',
  skip: function(req, res) {
    return res.statusCode === 304;
  }
}));

// Enable CORS
app.use(cors());

// Support pseudo PUT/DELETE via headers
app.use(methodOverride());

// Static assets
var oneDay = 86400000;
var oneYear = 31536000000;
app.use(express.static(path.join(__dirname, '/public'), {
  maxAge: oneDay
}));

// Parse application/x-www-form-urlencoded
app.use(bodyParser.urlencoded({
  extended: true
}));

// Parse application/json
app.use(bodyParser.json());

// Parse application/vnd.api+json as json
app.use(bodyParser.json({ type: 'application/vnd.api+json' }));

// Database
// Connects to 2 mongo urls
var database = new Bootie.Database(config.database);

// Router
var TestController = require('./controllers/test');
var TestCrudController = require('./controllers/test_crud');

var router = new Bootie.Router({
  version: "v2",
  controllers: {
    test: new TestController(),
    test_crud: new TestCrudController({
      db: database.mongodbs.primary,
      cache: database.caches.primary
    })
  }
});
app.use(router.url, router);

// Middleware after Router

// Start the HTTP server
var server = app.listen(app.get('port'), function() {
  console.log('Listening on port %d', server.address().port);
});<|endoftext|>


<commit_before>#!/usr/bin/env node

"use strict"

var fs = require('fs')
var http = require('http')
var Parse = require('parse').Parse

Parse.initialize("Dxi3BvGT3mHiDC7B1YjeEuiUQKtWIeQNofT5FIIx", "QG352rxcZvLrYeV4jOCsIZvM8mIeQyhvHzDNINAb")
var VolTextObject = Parse.Object.extend("VolumeText")
var DocGeoSpansObject = Parse.Object.extend("DocGeoSpans")

var args = process.argv.slice(2)

function failure(op, error) {
  console.log("Failure " + op + " " + error.message + " (" + error.code + ")")
}

// From http://stackoverflow.com/questions/11944932/how-to-download-a-file-with-node-js
var download = function(url, dest, cb) {
  var file = fs.createWriteStream(dest)
  var request = http.get(url, function(response) {
    response.pipe(file)
    file.on('finish', function() {
      file.close(cb)  // close() is async, call cb after close completes.
    })
  }).on('error', function(err) { // Handle errors
    fs.unlink(dest) // Delete the file async. (But we don't check the result)
    failure("loading " + url, err)
  })
};

function loadSpanFile(item, cb) {
  var dest = item.user + "-" + item.vol + ".txt"
  console.log("Downloading " + item.spans + " into " + dest)
  download(item.spans, dest, cb)
}

function loadSpanFiles(items) {
  if (items.length > 0) {
    var item = items[0]
    loadSpanFile(item, function() {
      loadSpanFiles(items.slice(1))
    })
  }
}

function loadSpanInfo(aftercb) {
  var query = new Parse.Query(DocGeoSpansObject)
  query.limit(1000)
  query.find().then(function(results) {
    var items = results.map(function(result) {
      var item = {user: result.get("user"), vol: result.get("vol"),
        spans: result.get("spans").url()}
      console.log("Found entry: user=" + item.user + ", vol=" + item.vol +
                  ", spans=" + item.spans)
      return item
    })
    aftercb(items)
  }, function(error) {
    failure("loading span info", error)
  })
}

loadSpanInfo(loadSpanFiles)
<commit_msg>download-docgeo-spans.js: Output warning if file already exists<commit_after>#!/usr/bin/env node

"use strict"

var fs = require('fs')
var http = require('http')
var Parse = require('parse').Parse

Parse.initialize("Dxi3BvGT3mHiDC7B1YjeEuiUQKtWIeQNofT5FIIx", "QG352rxcZvLrYeV4jOCsIZvM8mIeQyhvHzDNINAb")
var VolTextObject = Parse.Object.extend("VolumeText")
var DocGeoSpansObject = Parse.Object.extend("DocGeoSpans")

var args = process.argv.slice(2)

function failure(op, error) {
  console.log("Failure " + op + " " + error.message + " (" + error.code + ")")
}

// From http://stackoverflow.com/questions/11944932/how-to-download-a-file-with-node-js
var download = function(url, dest, cb) {
  if (fs.existsSync(dest)) {
    console.log("WARNING: File " + dest + " already exists!")
  }
  var file = fs.createWriteStream(dest)
  var request = http.get(url, function(response) {
    response.pipe(file)
    file.on('finish', function() {
      file.close(cb)  // close() is async, call cb after close completes.
    })
  }).on('error', function(err) { // Handle errors
    fs.unlink(dest) // Delete the file async. (But we don't check the result)
    failure("loading " + url, err)
  })
};

function loadSpanFile(item, cb) {
  var dest = item.user + "-" + item.vol + ".txt"
  console.log("Downloading " + item.spans + " into " + dest)
  download(item.spans, dest, cb)
}

function loadSpanFiles(items) {
  if (items.length > 0) {
    var item = items[0]
    loadSpanFile(item, function() {
      loadSpanFiles(items.slice(1))
    })
  }
}

function loadSpanInfo(aftercb) {
  var query = new Parse.Query(DocGeoSpansObject)
  query.limit(1000)
  query.find().then(function(results) {
    var items = results.map(function(result) {
      var item = {user: result.get("user"), vol: result.get("vol"),
        spans: result.get("spans").url()}
      console.log("Found entry: user=" + item.user + ", vol=" + item.vol +
                  ", spans=" + item.spans)
      return item
    })
    aftercb(items)
  }, function(error) {
    failure("loading span info", error)
  })
}

loadSpanInfo(loadSpanFiles)
<|endoftext|>


<commit_before>import mongoose, { Schema } from 'mongoose';
import timestamps from 'mongoose-timestamp';
import mongooseStringQuery from 'mongoose-string-query';

export const PodcastSchema = new Schema(
	{
		url: {
			type: String,
			trim: true,
		},
		feedUrl: {
			type: String,
			trim: true,
			index: true,
			unique: true,
			required: true,
		},
		title: {
			type: String,
			trim: true,
			required: true,
		},
		description: {
			type: String,
			trim: true,
			default: '',
		},
		summary: {
			type: String,
			trim: true,
			default: '',
		},
		categories: {
			type: String,
			trim: true,
			default: '',
		},
		featured: {
			type: Boolean,
			default: false,
		},
		images: {
			featured: {
				type: String,
				trim: true,
				default: '',
			},
			banner: {
				type: String,
				trim: true,
				default: '',
			},
			favicon: {
				type: String,
				trim: true,
				default: '',
			},
			og: {
				type: String,
				trim: true,
				default: '',
			},
		},
		public: {
			type: Boolean,
			default: true,
		},
		publicationDate: {
			type: Date,
			default: Date.now,
		},
		valid: {
			type: Boolean,
			default: true,
		},
		lastScraped: {
			type: Date,
			default: Date.now,
		},
		interest: {
			type: String,
			default: '',
			index: true,
		},
		language: {
			type: String,
			default: '',
		},
	},
	{ collection: 'podcasts' },
);

PodcastSchema.plugin(timestamps);
PodcastSchema.plugin(mongooseStringQuery);

module.exports = exports = mongoose.model('Podcast', PodcastSchema);
<commit_msg>added is parsing<commit_after>import mongoose, { Schema } from 'mongoose';
import timestamps from 'mongoose-timestamp';
import mongooseStringQuery from 'mongoose-string-query';

export const PodcastSchema = new Schema(
	{
		url: {
			type: String,
			trim: true,
		},
		feedUrl: {
			type: String,
			trim: true,
			index: true,
			unique: true,
			required: true,
		},
		title: {
			type: String,
			trim: true,
			required: true,
		},
		description: {
			type: String,
			trim: true,
			default: '',
		},
		summary: {
			type: String,
			trim: true,
			default: '',
		},
		categories: {
			type: String,
			trim: true,
			default: '',
		},
		featured: {
			type: Boolean,
			default: false,
		},
		isParsing: {
			type: Boolean,
			default: false,
		},
		images: {
			featured: {
				type: String,
				trim: true,
				default: '',
			},
			banner: {
				type: String,
				trim: true,
				default: '',
			},
			favicon: {
				type: String,
				trim: true,
				default: '',
			},
			og: {
				type: String,
				trim: true,
				default: '',
			},
		},
		public: {
			type: Boolean,
			default: true,
		},
		publicationDate: {
			type: Date,
			default: Date.now,
		},
		valid: {
			type: Boolean,
			default: true,
		},
		lastScraped: {
			type: Date,
			default: Date.now,
		},
		interest: {
			type: String,
			default: '',
			index: true,
		},
		language: {
			type: String,
			default: '',
		},
	},
	{ collection: 'podcasts' },
);

PodcastSchema.plugin(timestamps);
PodcastSchema.plugin(mongooseStringQuery);

module.exports = exports = mongoose.model('Podcast', PodcastSchema);
<|endoftext|>


<commit_before>(function() { 'use strict';
  angular.module('webcam').controller('webcamController', webcamController);
  webcamController.$inject = ['$scope', '$log'];
  function webcamController($scope, $log) {
    /* jshint validthis: true */
    var vm = this;
    vm.config = {
      delay: 2,
      shots: 3,
      flashFallbackUrl: 'bower_components/webcamjs/webcam.swf',
      shutterUrl: 'shutter.mp3',
      flashNotDetectedText: 'Seu browser não atende os requisitos mínimos para utilização da camera. ' +
      'Instale o ADOBE Flash player ou utilize os browsers (Google Chrome, Firefox ou Edge)'
    };

    vm.showButtons = false;
    vm.captureButtonEnable = false;

    vm.onCaptureComplete = function(src) {
      $log.log('webcamController.onCaptureComplete : ', src);
    };
    vm.onError = function(err) {
      $log.error('webcamController.onError : ', err);
      vm.showButtons = false;
    };
    vm.onLoad = function() {
      $log.info('webcamController.onLoad');
      vm.showButtons = true;
    };
    vm.onLive = function() {
      $log.info('webcamController.onLive');
      vm.captureButtonEnable = true;
    };
    vm.onCaptureProgress = function(src, progress) {
      var result = {
        src: src,
        progress: progress
      }
      $log.info('webcamController.onCaptureProgress : ', result);
    };
    vm.capture = function() {
      $scope.$broadcast('ngWebcam_capture'); };
    vm.on = function() {
      $scope.$broadcast('ngWebcam_on');
    };
    vm.off = function() {
      $scope.$broadcast('ngWebcam_off');
      vm.captureButtonEnable = false;
    };
  }
})();<commit_msg>Update app sample<commit_after>(function() { 'use strict';
  angular.module('webcam').controller('webcamController', webcamController);
  webcamController.$inject = ['$scope', '$log'];
  function webcamController($scope, $log) {
    /* jshint validthis: true */
    var vm = this;
    vm.config = {
      delay: 2,
      shots: 3,
      viewerWidth: 480,
      viewerHeight: 320,
      flashFallbackUrl: 'bower_components/webcamjs/webcam.swf',
      shutterUrl: 'shutter.mp3',
      flashNotDetectedText: 'Seu browser não atende os requisitos mínimos para utilização da camera. ' +
      'Instale o ADOBE Flash player ou utilize os browsers (Google Chrome, Firefox ou Edge)'
    };

    vm.showButtons = false;
    vm.captureButtonEnable = false;

    vm.onCaptureComplete = function(src) {
      $log.log('webcamController.onCaptureComplete : ', src);
    };
    vm.onError = function(err) {
      $log.error('webcamController.onError : ', err);
      vm.showButtons = false;
    };
    vm.onLoad = function() {
      $log.info('webcamController.onLoad');
      vm.showButtons = true;
    };
    vm.onLive = function() {
      $log.info('webcamController.onLive');
      vm.captureButtonEnable = true;
    };
    vm.onCaptureProgress = function(src, progress) {
      var result = {
        src: src,
        progress: progress
      }
      $log.info('webcamController.onCaptureProgress : ', result);
    };
    vm.capture = function() {
      $scope.$broadcast('ngWebcam_capture'); };
    vm.on = function() {
      $scope.$broadcast('ngWebcam_on');
    };
    vm.off = function() {
      $scope.$broadcast('ngWebcam_off');
      vm.captureButtonEnable = false;
    };
  }
})();<|endoftext|>


<commit_before>define([
  'extensions/views/table',
  'modernizr'
],
function (TableView, Modernizr) {

  return TableView.extend({

    initialize: function () {
      this.$table = this.$('table');

      this.tableCollection = new this.collection.constructor(this.collection.models, this.collection.options);

      this.listenTo(this.tableCollection, 'sort', this.renderSort);

      this.listenTo(this.collection, 'sync', this.syncToTableCollection);

      TableView.prototype.initialize.apply(this, arguments);
    },

    events: {
      'click th a': 'sortCol'
    },

    syncToTableCollection: function () {
      this.tableCollection.models = _.clone(this.collection.models);
    },

    renderSort: function () {
      if (this.$table.find('tbody')) {
        this.$table.find('tbody').remove();
      }
      $(this.renderBody(this.tableCollection)).appendTo(this.$table);
      this.render();
    },

    sortCol: function (e) {
      e.preventDefault();

      var th = $(e.target).parent(),
        ths = this.$table.find('th'),
        column = ths.index(th),
        isSorted = th.hasClass('desc') || th.hasClass('asc'),
        isDescending = isSorted && th.hasClass('desc') || false,
        columns = this.getColumns(),
        sortBy = columns[column].key;

      if (_.isArray(sortBy)) {
        sortBy = sortBy[0];
      }

      ths.removeClass('asc');
      ths.removeClass('desc');
      ths.attr('aria-sort', 'none');

      if (isDescending) {
        th.addClass('asc');
        th.attr('aria-sort', 'ascending');
      } else {
        th.addClass('desc');
        th.attr('aria-sort', 'descending');
      }

      this.tableCollection.comparator = function (a, b) {
        var firstVal = a.get(sortBy),
          firstTime = a.get('_timestamp') || a.get('_start_at'),
          secondVal = b.get(sortBy),
          secondTime = b.get('_timestamp') || b.get('_start_at'),
          nullValues = (firstVal !== null || secondVal !== null),
          ret;

        if (nullValues && firstVal < secondVal) {
          ret = -1;
        } else if (nullValues && firstVal > secondVal) {
          ret = 1;
        } else {
          if (nullValues) {
            if (firstVal === null) {
              ret = -1;
            }
            if (secondVal === null) {
              ret = 1;
            }
          } else {
            if (firstTime < secondTime) {
              ret = -1;
            } else if (firstTime > secondTime) {
              ret = 1;
            } else {
              ret = 0;
            }
          }
        }

        if (!isDescending) {
          ret = -ret;
        }
        return ret;
      };

      this.tableCollection.sort();
    },

    render: function () {
      if (Modernizr.touch) {
        this.$table.addClass('touch-table');
      }

      this.$table.removeClass('floated-header');
      var headers = this.$table.find('thead th'),
          headerLinks = this.$table.find('thead th a'),
          body = this.$table.find('tbody td');

      headers.attr('width', '');
      if (headerLinks.length === 0) {
        headers.each(function () {
          $(this).attr('aria-sort', 'none');
          $(this).wrapInner('');
        });
      }
      body.attr('width', '');

      if (body.length > headers.length) {
        _.each(headers, function (th, index) {
          th.width = th.offsetWidth;
          body[index].width = th.offsetWidth;
        }, this);
        this.$('table').addClass('floated-header');
      }

    }

  });

});<commit_msg>Use correct collection moethods instead of referencing internals<commit_after>define([
  'extensions/views/table',
  'modernizr'
],
function (TableView, Modernizr) {

  return TableView.extend({

    initialize: function () {
      this.$table = this.$('table');

      this.tableCollection = new this.collection.constructor(this.collection.models, this.collection.options);

      this.listenTo(this.tableCollection, 'sort', this.renderSort);

      this.listenTo(this.collection, 'sync', this.syncToTableCollection);

      TableView.prototype.initialize.apply(this, arguments);
    },

    events: {
      'click th a': 'sortCol'
    },

    syncToTableCollection: function () {
      this.tableCollection.reset(this.collection.toJSON());
    },

    renderSort: function () {
      if (this.$table.find('tbody')) {
        this.$table.find('tbody').remove();
      }
      $(this.renderBody(this.tableCollection)).appendTo(this.$table);
      this.render();
    },

    sortCol: function (e) {
      e.preventDefault();

      var th = $(e.target).parent(),
        ths = this.$table.find('th'),
        column = ths.index(th),
        isSorted = th.hasClass('desc') || th.hasClass('asc'),
        isDescending = isSorted && th.hasClass('desc') || false,
        columns = this.getColumns(),
        sortBy = columns[column].key;

      if (_.isArray(sortBy)) {
        sortBy = sortBy[0];
      }

      ths.removeClass('asc');
      ths.removeClass('desc');
      ths.attr('aria-sort', 'none');

      if (isDescending) {
        th.addClass('asc');
        th.attr('aria-sort', 'ascending');
      } else {
        th.addClass('desc');
        th.attr('aria-sort', 'descending');
      }

      this.tableCollection.comparator = function (a, b) {
        var firstVal = a.get(sortBy),
          firstTime = a.get('_timestamp') || a.get('_start_at'),
          secondVal = b.get(sortBy),
          secondTime = b.get('_timestamp') || b.get('_start_at'),
          nullValues = (firstVal !== null || secondVal !== null),
          ret;

        if (nullValues && firstVal < secondVal) {
          ret = -1;
        } else if (nullValues && firstVal > secondVal) {
          ret = 1;
        } else {
          if (nullValues) {
            if (firstVal === null) {
              ret = -1;
            }
            if (secondVal === null) {
              ret = 1;
            }
          } else {
            if (firstTime < secondTime) {
              ret = -1;
            } else if (firstTime > secondTime) {
              ret = 1;
            } else {
              ret = 0;
            }
          }
        }

        if (!isDescending) {
          ret = -ret;
        }
        return ret;
      };

      this.tableCollection.sort();
    },

    render: function () {
      if (Modernizr.touch) {
        this.$table.addClass('touch-table');
      }

      this.$table.removeClass('floated-header');
      var headers = this.$table.find('thead th'),
          headerLinks = this.$table.find('thead th a'),
          body = this.$table.find('tbody td');

      headers.attr('width', '');
      if (headerLinks.length === 0) {
        headers.each(function () {
          $(this).attr('aria-sort', 'none');
          $(this).wrapInner('');
        });
      }
      body.attr('width', '');

      if (body.length > headers.length) {
        _.each(headers, function (th, index) {
          th.width = th.offsetWidth;
          body[index].width = th.offsetWidth;
        }, this);
        this.$('table').addClass('floated-header');
      }

    }

  });

});<|endoftext|>