<commit_before>var express = require('express');
var router = express.Router();
var util = require('../util/common');
var log4js = require('log4js');
var log = log4js.getLogger('api');
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var modelSchema = require('../models/model');
var config  = require('../config.json').mongodb;
var connStr = 'mongodb://'+config.server+':'+config.port+'/'+config.db;
var connOpt = {};
config.user && (connOpt.user = config.user);
config.pwd && (connOpt.pass = config.pwd);
var db = mongoose.createConnection(connStr, connOpt);
var moduleFolder = './public/modules';
var distFolder = './public/dist';

var Project = db.model('projects', modelSchema.projectSchema);
var Module = db.model('modules', modelSchema.moduleSchema);

var moduleDependenciesReg = /define\s*\([^\[]*(?:\[([^\]]+)])?\s*(?:,\s*)/m;

/**
 * 获取项目列表
 */
router.get('/project/list', function (req, res, next) {
    Project.find({}, function (err, data) {
        if(err){
            log.log('ERROR',err);
            return res.json({
                code: 1,
                msg: 'server error.'
            });
        }
        res.json({
            code: 0,
            data: data
        });
    });
});

/**
 * 根据pid获取项目信息
 */
router.get('/project/view/:pid', function (req, res, next) {
    var pid = req.params['pid'];
    if(!pid){
        return res.json({
            code: 1,
            msg: 'lost the required parameter project id.'
        });
    }
    Project.findById(pid, function (err, data) {
        if(err){
            log.log('ERROR',err);
            return res.json({
                code: 2,
                msg: err.message
            });
        }
        res.json({
            code: 0,
            data: data
        });
    });
});

/**
 * 保存项目信息
 */
router.post('/project/add', function (req, res, next) {
    var body = req.body;
    var projectName = body.projectName || '';
    var userGroup = body.userGroup || '';

    if(projectName) {
        var p = new Project({
            name: projectName,
            userGroup: userGroup.split(',')
        });
        p.save(function (err) {
            if (err) {
                log.log('ERROR',err);
                return res.json({
                    code: 1,
                    msg: JSON.stringify(err)
                });
            }
            res.json({
                code: 0,
                msg: 'success'
            });
        });
    }
    else{
        res.json({
            code: 2,
            msg: 'lost required parameter projectName.'
        });
    }
});

/**
 * 根据pid获取模块
 */
router.get('/module/list/:pid', function (req, res, next) {
    var pid = req.params['pid'];
    if(!pid){
        return res.json({
            code: 1,
            msg: 'lost the required parameter project id.'
        });
    }
    Module.find({pid: pid},{_id:1, id: 1, name: 1, pid:1}, function (err, data) {
        if(err){
            log.log('ERROR',err);
            return res.json({
                code: 2,
                msg: 'server error.'
            });
        }
        res.json({
            code: 0,
            data: data
        });
    });
});

/**
 * 根据mid获取当前模块信息
 */
router.get('/module/view/:mid', function (req, res, next) {
    var mid = req.params['mid'];

    if(mid){
        Module.findById(mid, function (err, data) {
            if(err){
                log.log('ERROR',err);
                return res.json({
                    code: 2,
                    msg: err.message
                });
            }
            res.json({
                code: 0,
                data: data
            });
        });
    }
    else{
        return res.json({
            code: 1,
            msg: 'lost the required parameter mid.'
        });
    }
});

/**
 * 校验模块标识符是否合法
 */
router.get('/module/check/:id', function (req, res, next) {
    var id = req.params['id'];

    checkModuleId(id, function (result) {
        if(-2 === result){
            return res.json({
                code: -2,
                msg: 'mongo error.'
            });
        }else if(-1 === result){
            return res.json({
                code: -1,
                msg: 'file system error.'
            });
        }
        else if(0 === result){
            return res.json({
                code: 0,
                msg: 'not file and not record.'
            });
        }
        else if(1 === result){
            return res.json({
                code: 1,
                msg: 'file exist.'
            });
        }
        else if(2 === result){
            return res.json({
                code: 2,
                msg: 'module exist.'
            });
        }
    });
});

/**
 * 保存模块信息
 */
router.post('/module/save', function (req, res, next) {
    var body = req.body,
        _id = body._id,
        id = body.id,
        pid = body.pid,
        name = body.name,
        path = body.path,
        author = body.author,
        code = body.code,
        demo = body.demo,
        lastModify = body.lastModify,
        m,
        deps={},
        uses = [];

    deps.exists = [];
    deps.lostes = [];
    deps.map = {};

    var getDependenciesPromise = new Promise(function (resolve, reject) {
        // 依赖分析
        var myDeps = code.match(moduleDependenciesReg);
        if (myDeps) {
            myDepsList = (myDeps[1] && myDeps[1].split(',') || []).map(function (v) {
                return v.replace(/\s*'|\s*"/g, '');
            });
            if (myDepsList.length) {
                directive = '|'+myDepsList.join('|')+'|';
                getDependencies(myDepsList, deps, function (ret, data) {
                    if(ret) {
                        resolve(deps);
                    }
                    else{
                        reject(data.message);
                    }
                });
            }
            else {
                directive = "";
                resolve(deps);
            }
        }
        else{
            directive = "";
            resolve(deps)
        }
    });

    getDependenciesPromise.then(function (value) {
        return new Promise(function (resolve, reject) {
            Module.find({
                $or:[{'deps.exists': id},{'deps.lostes':id}]
            }, function (err, data) {
                if(err){
                    return reject(err.message);
                }
                if(data && data.length){
                    data.forEach(function (v) {
                        uses.push({
                            _id: v._id,
                            pid: v.pid,
                            id: v.id,
                            name: v.name
                        });
                    });
                    resolve(uses);
                }
                else{
                    resolve(uses);
                }
            });
        });
    }).then(save).catch(function (value) {
        log.log('ERROR',value);
        res.json({
            code: 103,
            msg: value
        });
    });

    function save(useMyList) {
        if (_id) {
            // update
            Module.update({_id: _id}, {
                name: name,
                author: author,
                code: code,
                demo: demo,
                deps: deps,
                path: path,
                uses: useMyList,
                lastModify: Date.now()
            }, function (err) {
                if (err) {
                    log.log('ERROR',err);
                    return res.json({
                        code: 10,
                        msg: err.message
                    });
                }

                // 写文件
                util.saveFile(moduleFolder + '/' + id + '.js', code, function (result) {
                    if (-1 === result) {
                        return res.json({
                            code: 12,
                            msg: 'async file error.'
                        });
                    }
                    else if (1 === result) {
                        return res.json({
                            code: 0,
                            msg: 'success'
                        });
                    }
                });
            });
        }
        else {
            // add
            m = new Module({
                id: id,
                pid: pid,
                name: name,
                path: path,
                author: author,
                code: code,
                demo: demo,
                deps: deps,
                uses: useMyList,
                lastModify: lastModify
            });
            m.save(function (err, data) {
                if (err) {
                    log.log('ERROR',err);
                    return res.json({
                        code: 1,
                        msg: err.message
                    });
                }
                // 写文件
                util.saveFile(moduleFolder + '/' + id + '.js', code, function (result) {
                    if (-1 === result) {
                        // 回滚
                        Module.findOneAndRemove({_id: data._id}, function () {
                        });
                        return res.json({
                            code: 2,
                            msg: '保存模块出错.'
                        });
                    }
                    else if (1 === result) {
                        return res.json({
                            code: 0,
                            msg: 'success'
                        });
                    }
                });
            });
        }

    }
});

/**
 * 加载已存在的模块文件
 */
router.post('/module/load', function (req, res, next) {
    var filename = req.body.filename;
    util.readFile(moduleFolder+'/'+filename+'.js', function (result, data) {
        if(result) {
            return res.json({
                code: 0,
                data: data
            });
        }else{
            return res.json({
                code: 1,
                msg: data.message
            });
        }

    });
});

/**
 * 模块压缩
 */
router.post('/compress', function (req, res, next) {
    var modules = req.body.modules.split(',');
    var combName = req.body.combName || '';
    var ms = [];
    if(modules.length) {
        modules.forEach(function (item) {
            if (item && '' != (item = item.trim())) {
                ms.push(moduleFolder+'/'+item+'.js');
            }
        });
        if(ms.length === 1) combName = ms[0].replace(moduleFolder, distFolder);

        util.compress(ms, combName, function (result) {
            if(-1 === result){
                log.log('INFO', 'compress module failure when save the file.');
                return res.json({
                    code: 3,
                    msg: 'save file failure.'
                });
            }
            else if( 1 === result){
                return res.json({
                    code: 0,
                    msg: 'success'
                });
            }
            else{
                return res.json({
                    code: 10,
                    msg: 'server error.'
                });
            }
        });
    }
    else{
        return res.json({
            code: 2,
            msg: 'lost required parameter modules.'
        });
    }
});

/**
 * 搜索接口
 */
router.post('/search', function (req, res, next) {
    var key = req.body.keys;
    if(key){
        Module.find({name: new RegExp('.*?'+key+'.*?')}, function (err, data) {
            if(err){
                log.log('ERROR',err);
                return res.json({
                    code: 1,
                    msg: err.message
                });
            }
            return res.json({
                code: 0,
                data: data
            });
        });
    }
});

/**
 * 模块依赖分析
 */
router.get('/module/dependencies/:mid', function (req, res, next) {
    var mid = req.params['mid'], deps={};
    deps.exists = [];
    deps.lostes = [];
    deps.map = {};
    if(mid) {
        Module.findById(mid, function (err, data) {
            if (err) {
                log.log("ERROR", err);
                return res.json({
                    code: 1,
                    msg: err.message
                });
            }
            if (data && data.code) {
                var myDeps = data.code.match(moduleDependenciesReg);
                if (myDeps) {
                    var myDepsList = (myDeps[1] && myDeps[1].split(',') || []).map(function (v) {
                        return v.replace(/\s*'|\s*"/g, '');
                    });
                    if (myDepsList.length) {
                        getDependencies(myDepsList, deps, function (ret, data) {
                            if(ret) {
                                return res.json({
                                    code: 0,
                                    data: data
                                });
                            }
                            else{
                                return res.json({
                                    code: 3,
                                    msg: data.message
                                });
                            }
                        });
                    }
                    else {
                        return res.json({
                            code: 0,
                            data: deps
                        });
                    }
                }
                else{
                    return res.json({
                        code: 0,
                        data: deps
                    });
                }
            }
            else {
                return res.json({
                    code: 2,
                    msg: 'lost the module.'
                });
            }
        });
    }
});

/**
 * 校验模块标识符是否可用
 * @param id  标识符
 * @param cb  处理函数
 */
function checkModuleId(id, cb) {
    // 查库
    Module.find({id: id}, function (err, data) {
        if (err) {
            log.log('ERROR',err);
            return cb(-2); // 出错
        }
        if (data.length) {
            cb(2); // 库里有
        }
        else {
            // 库里无，扫描文件夹
            util.fileInFolder(id + '.js', moduleFolder, cb);
        }
    });
}

/**
 * 获取模块组的依赖列表
 * @param depList  模块组
 * @param deps  依赖表 ， Ref
 * @param cb    回调函数
 */
function getDependencies(depList, deps, cb) {
    depList = depList.filter(function (dep) {
        return !(deps.exists.indexOf(dep) > -1 || deps.lostes.indexOf(dep) > -1);
    });
    if (depList.length) {
        Module.find({id: new RegExp(depList.join('|'))}, function (err, data) {
            if (err) {
                log.log('ERROR', err);
                return cb(false, err);
            }
            if (data.length) {
                var curModuleDeps = [];
                data.forEach(function (m) {
                    var mDeps = m.code.match(moduleDependenciesReg);
                    if (mDeps) {
                        var mDepList = (mDeps[1] && mDeps[1].split(',') || []).map(function (v) {
                            return v.replace(/\s*'|\s*"/g, '');
                        });
                        mDepList.length && (curModuleDeps = curModuleDeps.concat(mDepList));
                    }
                    deps.exists.push(m.id);
                    deps.map[m.id] = {
                        name: m.name,
                        mid: m._id,
                        pid: m.pid
                    };
                    depList.splice(depList.indexOf(m.id), 1);
                });
                depList.length && (deps.lostes = deps.lostes.concat(depList));
                curModuleDeps = util.uniq(curModuleDeps);
                // !deps.directive && (deps.directive = lodash.clone(deps, true));
                getDependencies(curModuleDeps, deps, cb);
            }
            else {
                deps.lostes = deps.lostes.concat(depList);
                // !deps.directive && (deps.directive = lodash.clone(deps, true));
                getDependencies([], deps, cb);
            }
        });
    }
    else {
        cb(true, deps);
    }
}

module.exports = router;<commit_msg>add search condition<commit_after>var express = require('express');
var router = express.Router();
var util = require('../util/common');
var log4js = require('log4js');
var log = log4js.getLogger('api');
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var modelSchema = require('../models/model');
var config = require('../config.json').mongodb;
var connStr = 'mongodb://' + config.server + ':' + config.port + '/' + config.db;
var connOpt = {};
config.user && (connOpt.user = config.user);
config.pwd && (connOpt.pass = config.pwd);
var db = mongoose.createConnection(connStr, connOpt);
var moduleFolder = './public/modules';
var distFolder = './public/dist';

var Project = db.model('projects', modelSchema.projectSchema);
var Module = db.model('modules', modelSchema.moduleSchema);

var moduleDependenciesReg = /define\s*\([^\[]*(?:\[([^\]]+)])?\s*(?:,\s*)/m;

/**
 * 获取项目列表
 */
router.get('/project/list', function (req, res, next) {
    Project.find({}, function (err, data) {
        if (err) {
            log.log('ERROR', err);
            return res.json({
                code: 1,
                msg: 'server error.'
            });
        }
        res.json({
            code: 0,
            data: data
        });
    });
});

/**
 * 根据pid获取项目信息
 */
router.get('/project/view/:pid', function (req, res, next) {
    var pid = req.params['pid'];
    if (!pid) {
        return res.json({
            code: 1,
            msg: 'lost the required parameter project id.'
        });
    }
    Project.findById(pid, function (err, data) {
        if (err) {
            log.log('ERROR', err);
            return res.json({
                code: 2,
                msg: err.message
            });
        }
        res.json({
            code: 0,
            data: data
        });
    });
});

/**
 * 保存项目信息
 */
router.post('/project/add', function (req, res, next) {
    var body = req.body;
    var projectName = body.projectName || '';
    var userGroup = body.userGroup || '';

    if (projectName) {
        var p = new Project({
            name: projectName,
            userGroup: userGroup.split(',')
        });
        p.save(function (err) {
            if (err) {
                log.log('ERROR', err);
                return res.json({
                    code: 1,
                    msg: JSON.stringify(err)
                });
            }
            res.json({
                code: 0,
                msg: 'success'
            });
        });
    }
    else {
        res.json({
            code: 2,
            msg: 'lost required parameter projectName.'
        });
    }
});

/**
 * 根据pid获取模块
 */
router.get('/module/list/:pid', function (req, res, next) {
    var pid = req.params['pid'];
    if (!pid) {
        return res.json({
            code: 1,
            msg: 'lost the required parameter project id.'
        });
    }
    Module.find({pid: pid}, {_id: 1, id: 1, name: 1, pid: 1}, function (err, data) {
        if (err) {
            log.log('ERROR', err);
            return res.json({
                code: 2,
                msg: 'server error.'
            });
        }
        res.json({
            code: 0,
            data: data
        });
    });
});

/**
 * 根据mid获取当前模块信息
 */
router.get('/module/view/:mid', function (req, res, next) {
    var mid = req.params['mid'];

    if (mid) {
        Module.findById(mid, function (err, data) {
            if (err) {
                log.log('ERROR', err);
                return res.json({
                    code: 2,
                    msg: err.message
                });
            }
            res.json({
                code: 0,
                data: data
            });
        });
    }
    else {
        return res.json({
            code: 1,
            msg: 'lost the required parameter mid.'
        });
    }
});

/**
 * 校验模块标识符是否合法
 */
router.get('/module/check/:id', function (req, res, next) {
    var id = req.params['id'];

    checkModuleId(id, function (result) {
        if (-2 === result) {
            return res.json({
                code: -2,
                msg: 'mongo error.'
            });
        } else if (-1 === result) {
            return res.json({
                code: -1,
                msg: 'file system error.'
            });
        }
        else if (0 === result) {
            return res.json({
                code: 0,
                msg: 'not file and not record.'
            });
        }
        else if (1 === result) {
            return res.json({
                code: 1,
                msg: 'file exist.'
            });
        }
        else if (2 === result) {
            return res.json({
                code: 2,
                msg: 'module exist.'
            });
        }
    });
});

/**
 * 保存模块信息
 */
router.post('/module/save', function (req, res, next) {
    var body = req.body,
        _id = body._id,
        id = body.id,
        pid = body.pid,
        name = body.name,
        path = body.path,
        author = body.author,
        code = body.code,
        demo = body.demo,
        lastModify = body.lastModify,
        m,
        deps = {},
        uses = [];

    deps.exists = [];
    deps.lostes = [];
    deps.map = {};

    var getDependenciesPromise = new Promise(function (resolve, reject) {
        // 依赖分析
        var myDeps = code.match(moduleDependenciesReg);
        if (myDeps) {
            myDepsList = (myDeps[1] && myDeps[1].split(',') || []).map(function (v) {
                return v.replace(/\s*'|\s*"/g, '');
            });
            if (myDepsList.length) {
                directive = '|' + myDepsList.join('|') + '|';
                getDependencies(myDepsList, deps, function (ret, data) {
                    if (ret) {
                        resolve(deps);
                    }
                    else {
                        reject(data.message);
                    }
                });
            }
            else {
                directive = "";
                resolve(deps);
            }
        }
        else {
            directive = "";
            resolve(deps)
        }
    });

    getDependenciesPromise.then(function (value) {
        return new Promise(function (resolve, reject) {
            Module.find({
                $or: [{'deps.exists': id}, {'deps.lostes': id}]
            }, function (err, data) {
                if (err) {
                    return reject(err.message);
                }
                if (data && data.length) {
                    data.forEach(function (v) {
                        uses.push({
                            _id: v._id,
                            pid: v.pid,
                            id: v.id,
                            name: v.name
                        });
                    });
                    resolve(uses);
                }
                else {
                    resolve(uses);
                }
            });
        });
    }).then(save).catch(function (value) {
        log.log('ERROR', value);
        res.json({
            code: 103,
            msg: value
        });
    });

    function save(useMyList) {
        if (_id) {
            // update
            Module.update({_id: _id}, {
                name: name,
                author: author,
                code: code,
                demo: demo,
                deps: deps,
                path: path,
                uses: useMyList,
                lastModify: Date.now()
            }, function (err) {
                if (err) {
                    log.log('ERROR', err);
                    return res.json({
                        code: 10,
                        msg: err.message
                    });
                }

                // 写文件
                util.saveFile(moduleFolder + '/' + id + '.js', code, function (result) {
                    if (-1 === result) {
                        return res.json({
                            code: 12,
                            msg: 'async file error.'
                        });
                    }
                    else if (1 === result) {
                        return res.json({
                            code: 0,
                            msg: 'success'
                        });
                    }
                });
            });
        }
        else {
            // add
            m = new Module({
                id: id,
                pid: pid,
                name: name,
                path: path,
                author: author,
                code: code,
                demo: demo,
                deps: deps,
                uses: useMyList,
                lastModify: lastModify
            });
            m.save(function (err, data) {
                if (err) {
                    log.log('ERROR', err);
                    return res.json({
                        code: 1,
                        msg: err.message
                    });
                }
                // 写文件
                util.saveFile(moduleFolder + '/' + id + '.js', code, function (result) {
                    if (-1 === result) {
                        // 回滚
                        Module.findOneAndRemove({_id: data._id}, function () {
                        });
                        return res.json({
                            code: 2,
                            msg: '保存模块出错.'
                        });
                    }
                    else if (1 === result) {
                        return res.json({
                            code: 0,
                            msg: 'success'
                        });
                    }
                });
            });
        }

    }
});

/**
 * 加载已存在的模块文件
 */
router.post('/module/load', function (req, res, next) {
    var filename = req.body.filename;
    util.readFile(moduleFolder + '/' + filename + '.js', function (result, data) {
        if (result) {
            return res.json({
                code: 0,
                data: data
            });
        } else {
            return res.json({
                code: 1,
                msg: data.message
            });
        }

    });
});

/**
 * 模块压缩
 */
router.post('/compress', function (req, res, next) {
    var modules = req.body.modules.split(',');
    var combName = req.body.combName || '';
    var ms = [];
    if (modules.length) {
        modules.forEach(function (item) {
            if (item && '' != (item = item.trim())) {
                ms.push(moduleFolder + '/' + item + '.js');
            }
        });
        if (ms.length === 1) combName = ms[0].replace(moduleFolder, distFolder);

        util.compress(ms, combName, function (result) {
            if (-1 === result) {
                log.log('INFO', 'compress module failure when save the file.');
                return res.json({
                    code: 3,
                    msg: 'save file failure.'
                });
            }
            else if (1 === result) {
                return res.json({
                    code: 0,
                    msg: 'success'
                });
            }
            else {
                return res.json({
                    code: 10,
                    msg: 'server error.'
                });
            }
        });
    }
    else {
        return res.json({
            code: 2,
            msg: 'lost required parameter modules.'
        });
    }
});

/**
 * 搜索接口
 */
router.post('/search', function (req, res, next) {
    var key = req.body.keys;
    if (key) {
        var re = new RegExp('.*?' + key + '.*?');
        Module.find({
                $or: [
                    {name: re},
                    {id: key}
                ]
            }, function (err, data) {
                if (err) {
                    log.log('ERROR', err);
                    return res.json({
                        code: 1,
                        msg: err.message
                    });
                }
                return res.json({
                    code: 0,
                    data: data
                });
            }
        );
    }
});

/**
 * 模块依赖分析
 */
router.get('/module/dependencies/:mid', function (req, res, next) {
    var mid = req.params['mid'], deps = {};
    deps.exists = [];
    deps.lostes = [];
    deps.map = {};
    if (mid) {
        Module.findById(mid, function (err, data) {
            if (err) {
                log.log("ERROR", err);
                return res.json({
                    code: 1,
                    msg: err.message
                });
            }
            if (data && data.code) {
                var myDeps = data.code.match(moduleDependenciesReg);
                if (myDeps) {
                    var myDepsList = (myDeps[1] && myDeps[1].split(',') || []).map(function (v) {
                        return v.replace(/\s*'|\s*"/g, '');
                    });
                    if (myDepsList.length) {
                        getDependencies(myDepsList, deps, function (ret, data) {
                            if (ret) {
                                return res.json({
                                    code: 0,
                                    data: data
                                });
                            }
                            else {
                                return res.json({
                                    code: 3,
                                    msg: data.message
                                });
                            }
                        });
                    }
                    else {
                        return res.json({
                            code: 0,
                            data: deps
                        });
                    }
                }
                else {
                    return res.json({
                        code: 0,
                        data: deps
                    });
                }
            }
            else {
                return res.json({
                    code: 2,
                    msg: 'lost the module.'
                });
            }
        });
    }
});

/**
 * 校验模块标识符是否可用
 * @param id  标识符
 * @param cb  处理函数
 */
function checkModuleId(id, cb) {
    // 查库
    Module.find({id: id}, function (err, data) {
        if (err) {
            log.log('ERROR', err);
            return cb(-2); // 出错
        }
        if (data.length) {
            cb(2); // 库里有
        }
        else {
            // 库里无，扫描文件夹
            util.fileInFolder(id + '.js', moduleFolder, cb);
        }
    });
}

/**
 * 获取模块组的依赖列表
 * @param depList  模块组
 * @param deps  依赖表 ， Ref
 * @param cb    回调函数
 */
function getDependencies(depList, deps, cb) {
    depList = depList.filter(function (dep) {
        return !(deps.exists.indexOf(dep) > -1 || deps.lostes.indexOf(dep) > -1);
    });
    if (depList.length) {
        Module.find({id: new RegExp(depList.join('|'))}, function (err, data) {
            if (err) {
                log.log('ERROR', err);
                return cb(false, err);
            }
            if (data.length) {
                var curModuleDeps = [];
                data.forEach(function (m) {
                    var mDeps = m.code.match(moduleDependenciesReg);
                    if (mDeps) {
                        var mDepList = (mDeps[1] && mDeps[1].split(',') || []).map(function (v) {
                            return v.replace(/\s*'|\s*"/g, '');
                        });
                        mDepList.length && (curModuleDeps = curModuleDeps.concat(mDepList));
                    }
                    deps.exists.push(m.id);
                    deps.map[m.id] = {
                        name: m.name,
                        mid: m._id,
                        pid: m.pid
                    };
                    depList.splice(depList.indexOf(m.id), 1);
                });
                depList.length && (deps.lostes = deps.lostes.concat(depList));
                curModuleDeps = util.uniq(curModuleDeps);
                // !deps.directive && (deps.directive = lodash.clone(deps, true));
                getDependencies(curModuleDeps, deps, cb);
            }
            else {
                deps.lostes = deps.lostes.concat(depList);
                // !deps.directive && (deps.directive = lodash.clone(deps, true));
                getDependencies([], deps, cb);
            }
        });
    }
    else {
        cb(true, deps);
    }
}

module.exports = router;<|endoftext|>


<commit_before>//
'use strict';
require('dotenv').load();
//

const fs = require('fs');
const express = require('express');
const request = require('request');
const multer = require('multer');
const crypto = require('crypto');
const mime = require('mime');
const bodyParser = require('body-parser');

const util = require('../custom_modules/util');
const geoJson = require('../custom_modules/geotagging');
const connect = require('../custom_modules/connect');

const credentials = connect.getCredentials();
const sanitizeInput = util.sanitizeInput;
const dbUrl = credentials.cloudantNoSQLDB[0].credentials.url;

const cloudant = require('cloudant')(dbUrl);
const db_class = cloudant.use('classes');
const db_obs = cloudant.use('observations');
const db_test = cloudant.use('test');

const router = express.Router();
router.use(bodyParser.urlencoded({extended: true}))
router.use(bodyParser.json());

const VR3 = require('watson-developer-cloud/visual-recognition/v3');
const vr = new VR3({
  api_key: credentials.watson_vision_combined[0].credentials.api_key,
  version_date: VR3.VERSION_DATE_2016_05_20
});

///////////////////////////////////////////////////////////////////////////////
// STORAGE
///////////////////////////////////////////////////////////////////////////////

const storage = multer.diskStorage({
    destination: function(req, file, cb) {
        cb(null, './public/uploads/')
    },
    filename: function(req, file, cb) {
        crypto.pseudoRandomBytes(16, function(err, raw) {
            cb(null, raw.toString('hex') + Date.now() + '.' + mime.extension(file.mimetype));
        });
    }
});

const upload = multer({storage: storage});

///////////////////////////////////////////////////////////////////////////////
// API
///////////////////////////////////////////////////////////////////////////////

router.post('/classify', upload.single('file'), (req, res) => {

    const params = {
        image_file: fs.createReadStream('./' + req.file.path),
        classifier_ids: 'TexasInvasives_190947980'
    }
    geoJson.extractData('./' + req.file.path).then((data) => {
        let match;
        let coordinates = geoJson.extractLatLng(data) || '';
        vr.classify(params, (error, results) => {
            if (error) {
                console.error(error);
            } else {
                match = util.calcMatch(results);
                db_class.get(match.class.replace(' ', '_'), (err, body) => {
                    res.json({
                      coordinates: coordinates,
                      properties: body.data,
                      confidence: match.score,
                      path: req.file.path,
                      filename: req.file.filename,
                      size: req.file.size
                    });
                });
            }
        });
    }).catch((error) => {
        let coordinates = '';
        let match;
        vr.classify(params, (error, results) => {
            if (error) {
                console.error(error);
            } else {
                match = util.calcMatch(results);
                db_class.get(match.class.replace(' ', '_'), (err, body) => {
                    res.json({
                      coordinates: coordinates,
                      properties: body.data,
                      confidence: match.score,
                      path: req.file.path,
                      filename: req.file.filename,
                      size: req.file.size
                    });
                });
            }
        });
    });
});

router.delete('/store', (req, res) => {
  fs.unlink('./' + req.body.path, (err) => {
    if (err) {
      console.error(err);
    } else {
      res.json(200);
    }
  });
});

router.post('/store', (req, res) => {
    console.log(req.body);
    let file = fs.createReadStream('./' + req.body.path);
    let results;
    request({
        url: `https://dal.objectstorage.open.softlayer.com/v1/AUTH_7defd160d60c4e43b5f9dd6691e7e1a0/images/${req.body.filename}`,
        method: 'PUT',
        headers: {
            'X-Auth-Token': req.app.get('storageToken'),
            'Content-type': 'application/octet-stream',
            'Content-length': req.body.size
        },
        body: file
    }, (err, response) => {
        if (err) {
          console.error(err);
          fs.unlink('./' + req.body.path);
        } else {
          fs.unlink('./' + req.body.path);
        }
    });
    if (req.body.lng) {
        db_test.insert({
            "type": "Feature",
            "geometry": {
                "type": "Point",
                "coordinates": [req.body.lng, req.body.lat]
            },
            "properties": {
                'date': new Date(),
                'species': req.body.name,
                'confidence': req.body.confidence,
                'valid_name': 'user_verified'
            }
        }, function(err, body) {
            console.log(err);
            if (!err)
                res.json(body);
            }
        )
    } else {
        db_test.insert({
            "type": "Feature",
            "geometry": {
                "type": "Point",
                "coordinates": ""
            },
            "properties": {
                'date': new Date(),
                'species': req.body.name,
                'confidence': req.body.confidence,
                'valid_name': 'user_verified'
            }
        }, function(err, body) {
            console.log(err);
            if (!err)
                res.json(body);
            }
        )
    }
});

///////////////////////////////////////////////////////////////////////////////
// FIN
module.exports = router;
///////////////////////////////////////////////////////////////////////////////
<commit_msg>temp mv uploads out of public folder<commit_after>//
'use strict';
require('dotenv').load();
//

const fs = require('fs');
const express = require('express');
const request = require('request');
const multer = require('multer');
const crypto = require('crypto');
const mime = require('mime');
const bodyParser = require('body-parser');

const util = require('../custom_modules/util');
const geoJson = require('../custom_modules/geotagging');
const connect = require('../custom_modules/connect');

const credentials = connect.getCredentials();
const sanitizeInput = util.sanitizeInput;
const dbUrl = credentials.cloudantNoSQLDB[0].credentials.url;

const cloudant = require('cloudant')(dbUrl);
const db_class = cloudant.use('classes');
const db_obs = cloudant.use('observations');
const db_test = cloudant.use('test');

const router = express.Router();
router.use(bodyParser.urlencoded({extended: true}))
router.use(bodyParser.json());

const VR3 = require('watson-developer-cloud/visual-recognition/v3');
const vr = new VR3({
  api_key: credentials.watson_vision_combined[0].credentials.api_key,
  version_date: VR3.VERSION_DATE_2016_05_20
});

///////////////////////////////////////////////////////////////////////////////
// STORAGE
///////////////////////////////////////////////////////////////////////////////

const storage = multer.diskStorage({
    destination: function(req, file, cb) {
        cb(null, './uploads/')
    },
    filename: function(req, file, cb) {
        crypto.pseudoRandomBytes(16, function(err, raw) {
            cb(null, raw.toString('hex') + Date.now() + '.' + mime.extension(file.mimetype));
        });
    }
});

const upload = multer({storage: storage});

///////////////////////////////////////////////////////////////////////////////
// API
///////////////////////////////////////////////////////////////////////////////

router.post('/classify', upload.single('file'), (req, res) => {

    const params = {
        image_file: fs.createReadStream('./' + req.file.path),
        classifier_ids: 'TexasInvasives_190947980'
    }
    geoJson.extractData('./' + req.file.path).then((data) => {
        let match;
        let coordinates = geoJson.extractLatLng(data) || '';
        vr.classify(params, (error, results) => {
            if (error) {
                console.error(error);
            } else {
                match = util.calcMatch(results);
                db_class.get(match.class.replace(' ', '_'), (err, body) => {
                    res.json({
                      coordinates: coordinates,
                      properties: body.data,
                      confidence: match.score,
                      path: req.file.path,
                      filename: req.file.filename,
                      size: req.file.size
                    });
                });
            }
        });
    }).catch((error) => {
        let coordinates = '';
        let match;
        vr.classify(params, (error, results) => {
            if (error) {
                console.error(error);
            } else {
                match = util.calcMatch(results);
                db_class.get(match.class.replace(' ', '_'), (err, body) => {
                    res.json({
                      coordinates: coordinates,
                      properties: body.data,
                      confidence: match.score,
                      path: req.file.path,
                      filename: req.file.filename,
                      size: req.file.size
                    });
                });
            }
        });
    });
});

router.delete('/store', (req, res) => {
  fs.unlink('./' + req.body.path, (err) => {
    if (err) {
      console.error(err);
    } else {
      res.json(200);
    }
  });
});

router.post('/store', (req, res) => {
    console.log(req.body);
    let file = fs.createReadStream('./' + req.body.path);
    let results;
    request({
        url: `https://dal.objectstorage.open.softlayer.com/v1/AUTH_7defd160d60c4e43b5f9dd6691e7e1a0/images/${req.body.filename}`,
        method: 'PUT',
        headers: {
            'X-Auth-Token': req.app.get('storageToken'),
            'Content-type': 'application/octet-stream',
            'Content-length': req.body.size
        },
        body: file
    }, (err, response) => {
        if (err) {
          console.error(err);
          fs.unlink('./' + req.body.path);
        } else {
          fs.unlink('./' + req.body.path);
        }
    });
    if (req.body.lng) {
        db_test.insert({
            "type": "Feature",
            "geometry": {
                "type": "Point",
                "coordinates": [req.body.lng, req.body.lat]
            },
            "properties": {
                'date': new Date(),
                'species': req.body.name,
                'confidence': req.body.confidence,
                'valid_name': 'user_verified'
            }
        }, function(err, body) {
            console.log(err);
            if (!err)
                res.json(body);
            }
        )
    } else {
        db_test.insert({
            "type": "Feature",
            "geometry": {
                "type": "Point",
                "coordinates": ""
            },
            "properties": {
                'date': new Date(),
                'species': req.body.name,
                'confidence': req.body.confidence,
                'valid_name': 'user_verified'
            }
        }, function(err, body) {
            console.log(err);
            if (!err)
                res.json(body);
            }
        )
    }
});

///////////////////////////////////////////////////////////////////////////////
// FIN
module.exports = router;
///////////////////////////////////////////////////////////////////////////////
<|endoftext|>


<commit_before><commit_msg>Update static/vendors/ace-builds/src/mode-batchfile.js<commit_after><|endoftext|>


<commit_before>/**
 * Created by linus on 07/01/15.
 */

var express = require('express');
var router = express.Router();

router.get('/', function (req, res) {
    if (req.query.q == 'Viktor' || req.query.q == 'viktor' || req.query.q == 'Larsson' || req.query.q == 'larsson'
        || req.query.q == 'Viktor Larsson' || req.query.q == 'viktor larsson' || req.query.q == 'Viktor larsson'
        || req.query.q == 'viktor Larsson') {
        res.status(200).json({name: 'Viktor Larsson', gender: 'unsertain', status: "Not Awesome"});
    } else {
        res.status(200).json({name: 'Linus', gender: 'Manly man', status: "Awesome as hell"});
    }
    ;
});

module.exports = router;<commit_msg>committed file api.js<commit_after>/**
 * Created by linus on 07/01/15.
 */

var express = require('express');
var router = express.Router();
var faker = require('../node_modules/faker');

router.get('/', function (req, res) {
    res.status(200).json({message:{text:faker.lorem.paragraph(),id:faker.internet.password()}})
});

module.exports = router;<|endoftext|>


<commit_before><commit_msg>disable logs<commit_after><|endoftext|>


<commit_before>var express = require('express');
var apiRouter = express.Router();
var db = require('../database/data');
var passportAuth = require('./passport-auth')
var util = require('util')
var crypto = require('crypto')

apiRouter.get('/api/version', function(req, res) {
    res.json({
        'version': '1.0.0.0'
    });
});

apiRouter.get('/api/items', function(req, res) {
    res.json(db);
})

apiRouter.get('/api/items/:type', function(req, res) {
    var type = req.params.type;
    if (!type) {
        res.json(db);
    } else {
        res.json(db.filter(function(item) {
            return item.type === type;
        }));
    }
})

apiRouter.get('/api/item/:id', function(req, res) {
    var id = req.params.id;
    console.log(id);
    res.json(db.filter(function(item) {
        return item.id == id;
    }));
})

// GET /auth/qq
// QQ登录认证时 `state` 为必填参数
// 系client端的状态值，用于第三方应用防止CSRF攻击，成功授权后回调时会原样带回
apiRouter.get('/api/auth/qq', function(req, res, next) {
    req.session = req.session || {};
    req.session.authState = crypto.createHash('sha1')
        .update(-(new Date()) + '')
        .digest('hex');
    passportAuth.authenticate('qq', {
        state: req.session.authState
    })(req, res, next);
});

// GET /auth/qq/callback
// 通过比较认证返回的`state`状态值与服务器端`session`中的`state`状态值
// 决定是否继续本次授权
apiRouter.get('/api/auth/qq/callback', function(req, res, next) {

    if (req.session && req.session.authState && req.session.authState === req.query.state) {
        res.redirect('/home');
        passportAuth
            .authenticate('qq', {
                failureRedirect: '/about'
            })(req, res, next);
    } else {
        return next(new Error('Auth State Mismatch'));
    }
}, function(req, res) {
    res.redirect('/welcome');
});

module.exports = apiRouter;<commit_msg>test qq redirect<commit_after>var express = require('express');
var apiRouter = express.Router();
var db = require('../database/data');
var passportAuth = require('./passport-auth')
var util = require('util')
var crypto = require('crypto')

apiRouter.get('/api/version', function (req, res) {
    res.json({
        'version': '1.0.0.0'
    });
});

apiRouter.get('/api/items', function (req, res) {
    res.json(db);
})

apiRouter.get('/api/items/:type', function (req, res) {
    var type = req.params.type;
    if (!type) {
        res.json(db);
    } else {
        res.json(db.filter(function (item) {
            return item.type === type;
        }));
    }
})

apiRouter.get('/api/item/:id', function (req, res) {
    var id = req.params.id;
    console.log(id);
    res.json(db.filter(function (item) {
        return item.id == id;
    }));
})

// GET /auth/qq
// QQ登录认证时 `state` 为必填参数
// 系client端的状态值，用于第三方应用防止CSRF攻击，成功授权后回调时会原样带回
apiRouter.get('/api/auth/qq', function (req, res, next) {
    req.session = req.session || {};
    req.session.authState = crypto.createHash('sha1')
        .update(-(new Date()) + '')
        .digest('hex');
    passportAuth.authenticate('qq', {
        state: req.session.authState
    })(req, res, next);
});

// GET /auth/qq/callback
// 通过比较认证返回的`state`状态值与服务器端`session`中的`state`状态值
// 决定是否继续本次授权
apiRouter.get('/api/auth/qq/callback', function (req, res, next) {
   // if (req.session && req.session.authState && req.session.authState === req.query.state) {
        passportAuth.authenticate('qq', { failureRedirect: '/about' })(req, res, next);
   // } else {
   //     return next(new Error('Auth State Mismatch'));
   // }
}, function (req, res) {
    res.redirect('/');
});

module.exports = apiRouter;<|endoftext|>


<commit_before>const express = require('express')
const router = express.Router()
const geartrack = require('geartrack')
const roundrobin = require('rr')
const cache = require('../services/cacheMiddleware')

// default cache time - 10 min
const CACHE_TIME = 10 * 60

// All this routes will be cached
// Error responses can manipulate cache time
router.use(cache(CACHE_TIME))

// All common providers, name, cssClass for color
let providers = {
  'sky': new Provider('Sky56', 'primary'),
  'correoses': new Provider('Correos ES', 'yellow'),
  'expresso24': new Provider('Expresso24', 'warning'),
  'singpost': new Provider('Singpost', 'danger'),
  'ctt': new Provider('CTT', 'primary'),
  'directlink': new Provider('Direct Link', 'yellow'),
  'trackchinapost': new Provider('Track China Post', 'danger'),
  'cainiao': new Provider('Cainiao', 'danger'),
  'yanwen': new Provider('Yanwen', 'success'),
  'cjah': new Provider('Cjah Tracking', 'success'),
  'postNL': new Provider('Post NL', 'warning'),
  'malaysiaPos': new Provider('Malasya Pos', 'danger'),
  'winit': new Provider('Winit', 'primary'),
  'panasia': new Provider('Panasia', 'info'),
  'pitneybowes': new Provider('Pitney Bowes', 'primary'),
  'dhl': new Provider('DHL', 'yellow'),
  'track24': new Provider('Track24', 'info'),
  'correos': new Provider('Correos Express Novo', 'danger'),
  'correosOld': new Provider('Correos Express Antigo', 'danger'),
  'mrw': new Provider('MRW', 'primary'),
  'ips': new Provider('IPS', 'yellow'),
}

/**
 * Adicional data
 */
router.get('/adicional', validateId, validatePostalCode, function (req, res) {
  let id = req.query.id, postalcode = req.query.postalcode

  //return processErrorResponse(new Error('DOWN - '), res, 'Adicional')

  geartrack.adicional.getInfo(id, postalcode, (err, adicionalEntity) => {
    if (err) {
      // sets the status code and the appropriate message
      return processErrorResponse(err, res, 'Adicional')
    }

    res.json(adicionalEntity)
  })
})

let proxys = []
if (process.env.GEARTRACK_PROXYS) {
  proxys = process.env.GEARTRACK_PROXYS.split(',').map(ip => ip.trim()).filter(ip => ip.length > 0)
}

/**
 * General providers that only need an id
 */
router.get('/:provider', validateId, function (req, res, next) {
  const id = req.query.id
  const tracker = req.params.provider

  let providerObj = providers[tracker]

  if (!providerObj) // no provider found
    return next()

  if(geartrack[tracker].getInfoProxy && proxys.length > 0) { // this tracker supports proxy requests
    let proxy = roundrobin(proxys)
    let proxyUrl = 'http://' + proxy + '/' + tracker

    geartrack[tracker].getInfoProxy(id, proxyUrl, providerCallback(res, providerObj))
  } else {
    geartrack[tracker].getInfo(id, providerCallback(res, providerObj))
  }
})

function providerCallback (res, providerObj) {
  return (err, entity) => {
    if (err) {
      // sets the status code and the appropriate message
      return processErrorResponse(err, res, providerObj.name)
    }

    if (entity.constructor &&
      entity.constructor.name &&
      entity.constructor.name == 'SkyInfo' &&
      entity.messages &&
      entity.messages.length == 0 &&
      entity.status &&
      entity.status.length == 0) {
      // Sky has no info
      return processErrorResponse(new Error('DEFAULT - no info'), res, providerObj.name)
    }

    entity.provider = providerObj.name // name shown: 'Informação [provider]'
    entity.color = providerObj.cssClass // color of the background, may use bootstrap classes

    res.json(entity)
  }
}

/*
 |--------------------------------------------------------------------------
 | Process Error Response
 |--------------------------------------------------------------------------
 */
function processErrorResponse (err, res, provider) {
  let cacheSeconds = CACHE_TIME // default cache time
  let code = 400
  let message = ''

  let type = getErrorType(err.message)
  let bugsnag = res.app.get('bugsnag')

  switch (type) {
    case 'BUSY':
      message = 'O servidor está sobrecarregado, tenta novamente daqui a uns segundos.'
      cacheSeconds = 0 // prevent cache
      break
    case 'UNAVAILABLE':
      message = 'O servidor não está disponível de momento. Tenta mais tarde.'
      break
    case 'DOWN':
    case 'EMPTY':
      if(bugsnag) bugsnag.notify(err) // send error to be analysed
      message = 'De momento este serviço está com problemas. Tenta mais tarde.'
      break
    case 'PARSER':
      if(bugsnag) bugsnag.notify(err) // send error to be analysed
      message = 'De momento estamos com dificuldade em aceder à informação deste servidor. Tenta mais tarde.'
      breakK
    case 'ACTION_REQUIRED':
      if(bugsnag) bugsnag.notify(err) // send error to be analysed
      cacheSeconds = 0 // prevent cache
      message = 'Este tracker requere um passo adicional no seu website. Depois de efetuares esse passo volta e atualiza a pagina para tentarmos de novo! :)'
      break
    default: // NO_DATA
      message = 'Ainda não existe informação disponível para este ID.'
      break
  }

  res.locals.expire = cacheSeconds
  return res.status(code).json({
    error: message,
    provider: provider
  })
}

function getErrorType (errorMessage) {
  let idx = errorMessage.indexOf(' - ')
  return errorMessage.substring(0, idx)
}

/*
 |--------------------------------------------------------------------------
 | Validation Middlewares
 |--------------------------------------------------------------------------
 */
function validateId (req, res, next) {
  let id = req.query.id

  if (!id) {
    res.status(400).json({error: 'ID must be passed in the query string!'})
    return
  }

  next()
}

function validatePostalCode (req, res, next) {
  let postalcode = req.query.postalcode

  if (!postalcode) {
    res.status(400).json({error: 'Postalcode must be passed in the query string!'})
    return
  }

  next()
}

/*
 |--------------------------------------------------------------------------
 | Utils
 |--------------------------------------------------------------------------
 */
function Provider (name, cssClass) {
  this.name = name
  this.cssClass = cssClass
}

function getRandomIntInclusive (min, max) {
  min = Math.ceil(min)
  max = Math.floor(max)
  return Math.floor(Math.random() * (max - min + 1)) + min
}

module.exports = router
<commit_msg>:art: Removed notifier when a provider is down<commit_after>const express = require('express')
const router = express.Router()
const geartrack = require('geartrack')
const roundrobin = require('rr')
const cache = require('../services/cacheMiddleware')

// default cache time - 10 min
const CACHE_TIME = 10 * 60

// All this routes will be cached
// Error responses can manipulate cache time
router.use(cache(CACHE_TIME))

// All common providers, name, cssClass for color
let providers = {
  'sky': new Provider('Sky56', 'primary'),
  'correoses': new Provider('Correos ES', 'yellow'),
  'expresso24': new Provider('Expresso24', 'warning'),
  'singpost': new Provider('Singpost', 'danger'),
  'ctt': new Provider('CTT', 'primary'),
  'directlink': new Provider('Direct Link', 'yellow'),
  'trackchinapost': new Provider('Track China Post', 'danger'),
  'cainiao': new Provider('Cainiao', 'danger'),
  'yanwen': new Provider('Yanwen', 'success'),
  'cjah': new Provider('Cjah Tracking', 'success'),
  'postNL': new Provider('Post NL', 'warning'),
  'malaysiaPos': new Provider('Malasya Pos', 'danger'),
  'winit': new Provider('Winit', 'primary'),
  'panasia': new Provider('Panasia', 'info'),
  'pitneybowes': new Provider('Pitney Bowes', 'primary'),
  'dhl': new Provider('DHL', 'yellow'),
  'track24': new Provider('Track24', 'info'),
  'correos': new Provider('Correos Express Novo', 'danger'),
  'correosOld': new Provider('Correos Express Antigo', 'danger'),
  'mrw': new Provider('MRW', 'primary'),
  'ips': new Provider('IPS', 'yellow'),
}

/**
 * Adicional data
 */
router.get('/adicional', validateId, validatePostalCode, function (req, res) {
  let id = req.query.id, postalcode = req.query.postalcode

  //return processErrorResponse(new Error('DOWN - '), res, 'Adicional')

  geartrack.adicional.getInfo(id, postalcode, (err, adicionalEntity) => {
    if (err) {
      // sets the status code and the appropriate message
      return processErrorResponse(err, res, 'Adicional')
    }

    res.json(adicionalEntity)
  })
})

let proxys = []
if (process.env.GEARTRACK_PROXYS) {
  proxys = process.env.GEARTRACK_PROXYS.split(',').map(ip => ip.trim()).filter(ip => ip.length > 0)
}

/**
 * General providers that only need an id
 */
router.get('/:provider', validateId, function (req, res, next) {
  const id = req.query.id
  const tracker = req.params.provider

  let providerObj = providers[tracker]

  if (!providerObj) // no provider found
    return next()

  if(geartrack[tracker].getInfoProxy && proxys.length > 0) { // this tracker supports proxy requests
    let proxy = roundrobin(proxys)
    let proxyUrl = 'http://' + proxy + '/' + tracker

    geartrack[tracker].getInfoProxy(id, proxyUrl, providerCallback(res, providerObj))
  } else {
    geartrack[tracker].getInfo(id, providerCallback(res, providerObj))
  }
})

function providerCallback (res, providerObj) {
  return (err, entity) => {
    if (err) {
      // sets the status code and the appropriate message
      return processErrorResponse(err, res, providerObj.name)
    }

    if (entity.constructor &&
      entity.constructor.name &&
      entity.constructor.name == 'SkyInfo' &&
      entity.messages &&
      entity.messages.length == 0 &&
      entity.status &&
      entity.status.length == 0) {
      // Sky has no info
      return processErrorResponse(new Error('DEFAULT - no info'), res, providerObj.name)
    }

    entity.provider = providerObj.name // name shown: 'Informação [provider]'
    entity.color = providerObj.cssClass // color of the background, may use bootstrap classes

    res.json(entity)
  }
}

/*
 |--------------------------------------------------------------------------
 | Process Error Response
 |--------------------------------------------------------------------------
 */
function processErrorResponse (err, res, provider) {
  let cacheSeconds = CACHE_TIME // default cache time
  let code = 400
  let message = ''

  let type = getErrorType(err.message)
  let bugsnag = res.app.get('bugsnag')

  switch (type) {
    case 'BUSY':
      message = 'O servidor está sobrecarregado, tenta novamente daqui a uns segundos.'
      cacheSeconds = 0 // prevent cache
      break
    case 'UNAVAILABLE':
      message = 'O servidor não está disponível de momento. Tenta mais tarde.'
      break
    case 'DOWN':
    case 'EMPTY':
      message = 'De momento este serviço está com problemas. Tenta mais tarde.'
      break
    case 'PARSER':
      if(bugsnag) bugsnag.notify(err) // send error to be analysed
      message = 'De momento estamos com dificuldade em aceder à informação deste servidor. Tenta mais tarde.'
      breakK
    case 'ACTION_REQUIRED':
      if(bugsnag) bugsnag.notify(err) // send error to be analysed
      cacheSeconds = 0 // prevent cache
      message = 'Este tracker requere um passo adicional no seu website. Depois de efetuares esse passo volta e atualiza a pagina para tentarmos de novo! :)'
      break
    default: // NO_DATA
      message = 'Ainda não existe informação disponível para este ID.'
      break
  }

  res.locals.expire = cacheSeconds
  return res.status(code).json({
    error: message,
    provider: provider
  })
}

function getErrorType (errorMessage) {
  let idx = errorMessage.indexOf(' - ')
  return errorMessage.substring(0, idx)
}

/*
 |--------------------------------------------------------------------------
 | Validation Middlewares
 |--------------------------------------------------------------------------
 */
function validateId (req, res, next) {
  let id = req.query.id

  if (!id) {
    res.status(400).json({error: 'ID must be passed in the query string!'})
    return
  }

  next()
}

function validatePostalCode (req, res, next) {
  let postalcode = req.query.postalcode

  if (!postalcode) {
    res.status(400).json({error: 'Postalcode must be passed in the query string!'})
    return
  }

  next()
}

/*
 |--------------------------------------------------------------------------
 | Utils
 |--------------------------------------------------------------------------
 */
function Provider (name, cssClass) {
  this.name = name
  this.cssClass = cssClass
}

function getRandomIntInclusive (min, max) {
  min = Math.ceil(min)
  max = Math.floor(max)
  return Math.floor(Math.random() * (max - min + 1)) + min
}

module.exports = router
<|endoftext|>


<commit_before>var express = require('express');
var router = express.Router();
var request = require('request');
var itemCtrl = require('../controllers/itemCtrl');
var listCtrl = require('../controllers/listCtrl');

var apikeys = ['c7cIi88CYsXPaT1sxqhLSLz2OaROEEOdjFFHff79', 'BD5eu8hQLzoGG2jmEjkF4EBhT9HU4uEeJcjFz9oW', 'CSnXW6BKcazu7RgncwWKqLCGzodQNDxWLm1Q0VP3'];

var current_key = 0;

// Get Food
router.get('/get_food/:food', function(req, res, next) {
  var food = req.params.food;
  var return_data = {};
  var data = null;

  if (current_key == apikeys.length) {
    current_key = 0;
  }

  request('http://api.nal.usda.gov/ndb/search/?format=json&q=' + food + '&sort=r&offset=0&api_key=' + apikeys[current_key], function (error, res1, body) {
    console.log("Ratelimit Remaining on key " + current_key +": " + res1.caseless.dict["x-ratelimit-remaining"]);
    if (res1.caseless.dict["x-ratelimit-remaining"] <= 20) {
      if (current_key == apikeys.length - 1) {
        current_key = 0;
      }
      else {
        current_key++;
      }
    }

    if (!error && res1.statusCode == 200) {
      data = JSON.parse(res1.body);
      for (var item in data.list.item) {
        return_data[data.list.item[item]["name"]] = data.list.item[item]["ndbno"];
      }
      res.send(return_data);
    }
    else {
      console.log("ERROR!", body);
      res.status(500).send("Invalid food query!");
    }
  });
});

router.get('/get_nutrition/:food_id', function(req, res, next) {
  var food = req.params.food_id;
  var interested = ["Energy", "Sugars, total", "Total lipid (fat)", "Carbohydrate, by difference", "Fiber, total dietary"];
  var return_data = {};

  request('http://api.nal.usda.gov/ndb/reports/?ndbno=' + food + '&type=b&format=json&api_key=' + apikeys[current_key], function(error, res2, body) {
    console.log("Ratelimit Remaining on key " + current_key +": " + res2.caseless.dict["x-ratelimit-remaining"]);
    if (res2.caseless.dict["x-ratelimit-remaining"] <= 20) {
      if (current_key == apikeys.length - 1) {
        current_key = 0;
      }
      else {
        current_key++;
      }
    }

    if (!error && res2.statusCode == 200) {
      data = JSON.parse(res2.body);
      var nutrients = data.report.food["nutrients"];
      return_data["name"] = data.report.food.name;
      for (var item in nutrients) {
        if (interested.indexOf(nutrients[item]["name"]) != -1) {
          return_data[nutrients[item]["name"]] = nutrients[item]["measures"][0]["value"];
        }
      }
      res.send(return_data);
      itemCtrl.findOrCreate({api_id: food, nutrition: return_data}, res);
    }
    else {
      console.log("Error in get_nutrition: " + error);
    }
  });
});

router.get('/add_list/:list/:food_id', function(req, res, next) {
  var food_id = req.params.food_id;
  var list = req.params.list;
  listCtrl.addItem({name: list, api_id: food_id, user_id: req.cookies.user});
  res.send('adds a food to the users list');
});

router.get('/get_list', function(req, res, next) {
  var list_name = req.query.lname;
  //console.log(req.query.lname);
  console.log(req.cookies.user);
  var hold = listCtrl.findOrCreate({name: "TestList", user_id: req.cookies.user});
  for(val in hold){
    res.send(val);
  }
  //console.log(hold);

});

router.post('/create_list', function(req, res, next) {
  var list = req.body.list;
  var name = req.body.name;
  console.log(req.cookies.user);
  listCtrl.findOrCreate({name: name, user_id: req.cookies.user});
  for (var item in list) {
    console.log(list[item]["id"]);
    listCtrl.addItem({name: name, api_id: list[item]["id"], user_id: req.cookies.user});
  }
  res.send('added list to db');
});

router.get('/update_list/:list', function(req, res, next) {
  var list = req.params.list;
  res.send('updates a users list');
});

router.get('/del_list/:list', function(req, res, next) {
  var list = req.params.list;
  listCtrl.delete({name: list_name, user_id: req.cookies.user});
  res.send('deletes a users list');
});

module.exports = router;
<commit_msg>-- Testing about 6<commit_after>var express = require('express');
var router = express.Router();
var request = require('request');
var itemCtrl = require('../controllers/itemCtrl');
var listCtrl = require('../controllers/listCtrl');

var apikeys = ['c7cIi88CYsXPaT1sxqhLSLz2OaROEEOdjFFHff79', 'BD5eu8hQLzoGG2jmEjkF4EBhT9HU4uEeJcjFz9oW', 'CSnXW6BKcazu7RgncwWKqLCGzodQNDxWLm1Q0VP3'];

var current_key = 0;

// Get Food
router.get('/get_food/:food', function(req, res, next) {
  var food = req.params.food;
  var return_data = {};
  var data = null;

  if (current_key == apikeys.length) {
    current_key = 0;
  }

  request('http://api.nal.usda.gov/ndb/search/?format=json&q=' + food + '&sort=r&offset=0&api_key=' + apikeys[current_key], function (error, res1, body) {
    console.log("Ratelimit Remaining on key " + current_key +": " + res1.caseless.dict["x-ratelimit-remaining"]);
    if (res1.caseless.dict["x-ratelimit-remaining"] <= 20) {
      if (current_key == apikeys.length - 1) {
        current_key = 0;
      }
      else {
        current_key++;
      }
    }

    if (!error && res1.statusCode == 200) {
      data = JSON.parse(res1.body);
      for (var item in data.list.item) {
        return_data[data.list.item[item]["name"]] = data.list.item[item]["ndbno"];
      }
      res.send(return_data);
    }
    else {
      console.log("ERROR!", body);
      res.status(500).send("Invalid food query!");
    }
  });
});

router.get('/get_nutrition/:food_id', function(req, res, next) {
  var food = req.params.food_id;
  var interested = ["Energy", "Sugars, total", "Total lipid (fat)", "Carbohydrate, by difference", "Fiber, total dietary"];
  var return_data = {};

  request('http://api.nal.usda.gov/ndb/reports/?ndbno=' + food + '&type=b&format=json&api_key=' + apikeys[current_key], function(error, res2, body) {
    console.log("Ratelimit Remaining on key " + current_key +": " + res2.caseless.dict["x-ratelimit-remaining"]);
    if (res2.caseless.dict["x-ratelimit-remaining"] <= 20) {
      if (current_key == apikeys.length - 1) {
        current_key = 0;
      }
      else {
        current_key++;
      }
    }

    if (!error && res2.statusCode == 200) {
      data = JSON.parse(res2.body);
      var nutrients = data.report.food["nutrients"];
      return_data["name"] = data.report.food.name;
      for (var item in nutrients) {
        if (interested.indexOf(nutrients[item]["name"]) != -1) {
          return_data[nutrients[item]["name"]] = nutrients[item]["measures"][0]["value"];
        }
      }
      res.send(return_data);
      itemCtrl.findOrCreate({api_id: food, nutrition: return_data}, res);
    }
    else {
      console.log("Error in get_nutrition: " + error);
    }
  });
});

router.get('/add_list/:list/:food_id', function(req, res, next) {
  var food_id = req.params.food_id;
  var list = req.params.list;
  listCtrl.addItem({name: list, api_id: food_id, user_id: req.cookies.user});
  res.send('adds a food to the users list');
});

router.get('/get_list', function(req, res, next) {
  var list_name = req.query.lname;
  //console.log(req.query.lname);
  console.log(req.cookies.user);
  var hold = listCtrl.findOrCreate({name: "TestList", user_id: req.cookies.user});
  for(val in hold){
    //res.send(val);
  }
  res.send({this: "test", please: "work"});
  //console.log(hold);

});

router.post('/create_list', function(req, res, next) {
  var list = req.body.list;
  var name = req.body.name;
  console.log(req.cookies.user);
  listCtrl.findOrCreate({name: name, user_id: req.cookies.user});
  for (var item in list) {
    console.log(list[item]["id"]);
    listCtrl.addItem({name: name, api_id: list[item]["id"], user_id: req.cookies.user});
  }
  res.send('added list to db');
});

router.get('/update_list/:list', function(req, res, next) {
  var list = req.params.list;
  res.send('updates a users list');
});

router.get('/del_list/:list', function(req, res, next) {
  var list = req.params.list;
  listCtrl.delete({name: list_name, user_id: req.cookies.user});
  res.send('deletes a users list');
});

module.exports = router;
<|endoftext|>


<commit_before>/* REQUIREMENTS */
//////////////////
// Config
var config = require('../config/config.js'),
  secret = config.secret,
  // Express
  express = require('express'),
  router = express.Router(),
  // Models
  Mail = require('../models/email.js'), // Mail model
  Transaction = require('../models/transaction.js'), // Transaction model
  // Coinbase
  Client = require('coinbase').Client,
  client = new Client({
    'apiKey': config.coinbase.testnet.key,
    'apiSecret': config.coinbase.testnet.secret,
    'baseApiUri': 'https://api.sandbox.coinbase.com/v1/'
  }),
  Account = require('coinbase').model.Account,
  btcAccount = new Account(client, {
    'id': '55335c04fb9854796c00000c'
  }),
  // Mailgun
  Mailgun = require('mailgun').Mailgun,
  mg = new Mailgun(config.mailgun),

  // JSON Web Tokens
  jwt = require('jsonwebtoken');

module.exports = function(app, passport) {

  /* API ROUTES */

  //welcome to the api
  app.get('/api', function(req, res) {
    res.send('Welcome to the API');
  });

  // `/mailman`
  app.post('/api/mailman', function(req, res) {
    console.log('mailman recieved an email');
    console.log('It contained the following');
    console.log(req.body);

    // proceed if mailman was CCed into the mail.
    if (req.body.Cc && req.body.Cc.indexOf('mailman@mailman.ninja')) {

      // regex expression to find "re:", "fw:" "fwd:", etc.
      var junkRegex = /([\[\(] *)?(RE|FWD?) *([-:;)\]][ :;\])-]*|$)|\]+ *$/igm;

      Mail.findOne({
        subjectStripped: req.body.subject.replace(junkRegex, "")
      }, function(err, mail) {
        if (err) {
          console.log(err);
        } else if (mail && (mail.to === req.body.from &&
            mail.from === req.body.to)) {
          // if the mail exists and is being sent back from the original sender
          console.log('Recieved confirmation of a reply from original sender for mail:' + mail.id); //debug

          // TODO pay the recepient
          // LOTSA CODE

        } else if (!mail) {
          // if no such mail exists
          console.log('Mailman was notified of a new NEW mail'); //debug

          // save the metadata
          mail = new Mail();
          mail.type = "reward";
          mail.to = req.body.to;
          mail.date = req.body.Date;
          mail.cc = req.body.Cc;
          mail.sender = req.body.sender;
          mail.from = req.body.from;
          mail.subject = req.body.subject;

          // strip all re, and fwd from subject before saving as the stripped subject
          mail.subjectStripped = req.body.subject.replace(junkRegex, "");

          //create the address
          btcAccount.createAddress({
            "callback_url": 'http://the.mailman.ninja/api/payment/' + mail.id,
            "label": ""
          }, function(err, address) {
            if (err) {
              // output error and save mail
              console.log(err);
              mail.save();
            } else {
              // save the address and save the mail
              console.log('Created address' + address.address); //debug
              mail.btcAddress = address.address;
              mail.save(
                console.log('New mail saved') //debug
              );

              // send an invoice to the sender
              mg.sendText('Mailman <mailman@mailman.ninja>', [mail.sender],
                'RE: ' + mail.subject,
                'Hi, pay the reward here: ' + mail.btcAddress,
                'noreply@mailman.ninja', {},
                function(err) {
                  if (err) {
                    console.log('Unable to deliver invoice for mail ' +
                      mail.id + '\nerror: ' + err);
                  } else {
                    console.log('sent invoice for reward mail');
                  }
                });
            }
          });
        }
      });
    } else {
      console.log('mailman was not in the CC field');
    }
  });

  // When a callback is recieved for a payment made.
  // '/payment/:mail_id'
  app.post('/api/payment/:mail_id', function(req, res) {

    /* Example object to be recieved

      {
      "address": "1AmB4bxKGvozGcZnSSVJoM6Q56EBhzMiQ5",
      "amount": 1.23456,
      "transaction": {
        "hash": "7b95769dce68b9aa84e4aeda8d448e6cc17695a63cc2d361318eb0f6efdf8f82"
      }
    */
    console.log('Recieved a payment notification'); //debug
    jwt.verify(token, secret, function(err, decoded) {
      if (err) {
        return res.status(403).send({
          success: false,
          message: 'Invalid token'
        });
      } else if (decoded.mail_id !== req.params.mail_id) {

        console.log('Token mismatch');
        console.log('Possible attack!');
        console.log('Mail ID : ' + mail_id);
        console.log('Token ID : ' + decoded.mail_id);

        return res.status(403).send({
          success: false,
          message: 'Token mismatch'
        });

      } else if (decoded) {
        req.decoded = decoded;

        // find the mail with this id
        Mail.findById(req.params.mail_id, function(err, mail) {
          if (err) {
            console.log(err);
          } else {
            // save the callback object in the db
            // save the transaction
            var transaction = new Transaction();
            transaction.address = req.body.address;
            transaction.amount = req.body.amount;
            transaction.transaction.hash = req.transaction.hash;
            transaction.save(
              // append the transaction to the mail
              Mail.findByIdAndUpdate(mail._id, {
                  $push: {
                    'transaction': transaction
                  }
                }, {
                  safe: true,
                  upsert: true
                },
                function(err, model) {
                  console.log(err);
                }
              )
            );

            //determine what sort of mail this was
            if (mail.type === 'reward') {

              // mail the person saying there is a reward available
              mg.sendText('Mailman <mailman@mailman.ninja>', [mail.to],
                'RE: ' + mail.subject,
                'Hi, there\'s a ' + req.body.amount + ' BTC ' +
                'reward on replying to this email.\n ' +
                'Just keep `mailman@mailman.ninja` in the CC field so that I ' +
                'know you\'ve replied!',
                'noreply@mailman.ninja', {},
                function(err) {
                  if (err) {
                    console.log('Unable to deliver invoice for mail ' +
                      mail.id + '\nerror: ' + err);
                  } else {
                    console.log('Success');
                  }
                });
              // if the mail is an incoming mail sent to a user
            } else if (mail.type === 'incoming') {

              // TODO the code below has yet to be checked
              // infact, i don't think i've added the relevent schema changes
              User.findOne({
                'local.username': mail.username
              }, function(err, user) {

                mg.sendText('Mailman <mailman@mailman.ninja>', [mail.to],
                  'RE: ' + mail.subject,
                  'Hi, there\'s a ' + req.body.amount + ' BTC ' +
                  'reward on replying to this email.\n ' +
                  'Just keep `mailman@mailman.ninja` in the CC field so that I ' +
                  'know you\'ve replied!',
                  'noreply@mailman.ninja', {},
                  function(err) {
                    if (err) console.log('Unable to deliver invoice for mail ' +
                      mail.id + '\nerror: ' + err);
                    else console.log('Success');
                  });
              });

              // pay the recepient their share of the fee
            }
          }
        });
      }
    });
  });

  // new mail to specifc user
  app.post('/api/mail/:user_id', function(req, res) {
    console.log(req.body.lol);
    res.send(req.body['lol-hello']);

    var mail = new Mail();

    mail.type = "incoming";
    mail.incomingEmail = req.params.user.id;
    mail.to = req.body.to;
    mail.date = req.body.Date;
    mail.cc = req.body.Cc;
    mail.recipient = req.body.recipient;
    mail.sender = req.body.sender;
    mail.from = req.body.from;
    mail.subject = req.body.subject;
    mail.bodyPlain = req.body['body-plain'];
    mail.strippedText = req.body['stripped-text'];
    mail.strippedSignature = req.body['stripped-signature'];
    mail.bodyHtml = req.body['body-html'];
    mail.strippedHtml = req.body['stripped-html'];
    mail.attachmentCount = req.body['attachment-count'];
    mail.attachmentx = req.body['attachment-x'];
    mail.messageHeaders = req.body['message-headers'];
    mail.contentIdMap = req.body['content-id-map'];

    var callbackToken = jwt.sign({
      'mail_id': mail.id,
    }, secret);

    var addressArgs = {
      'callback_url': 'http://the.mailman.ninja/api/payment/' + mail.id +
        '?token=' + callbackToken,
      'label': mail.id
    };

    btcAccount.createAddress(addressArgs, function(err, address) {
      if (err) {
        // output error and save mail
        console.log(err);
        mail.save();
      } else {
        // save the address and save the mail
        mail.btcAddress = address.address;
        mail.save();

        // send an invoice to the sender
        mg.sendText('Mailman <mailman@mailman.ninja>', [mail.sender],
          'RE: ' + mail.subject,
          'Hi, your email will only be delivered if you pay for its delivery.\n' +
          'Please pay at this address: ' + mail.btcAddress,
          'noreply@mailman.ninja', {},
          function(err) {
            if (err) console.log('Unable to deliver invoice for mail ' +
              mail.id + '\nerror: ' + err);
            else console.log('Success');
          });
      }
    });

  });

  // User authorization (login)
  app.post('/api/user/auth', passport.authenticate('local-login', {
    successRedirect: '/user', // redirect to the user
    failureRedirect: '/', // redirect back to the home page on error
    failureFlash: true // allow flash messages
  }));

  // User signup
  app.post('/api/user/new', passport.authenticate('local-signup', {
    successRedirect: '/profile', // redirect to the secure profile section
    failureRedirect: '/signup', // redirect back to the signup page if there is an error
    failureFlash: true // allow flash messages
  }));

  // User logout
  app.get('/api/user/logout', function(req, res) {
    req.logout();
    res.redirect('/');
  });

};
<commit_msg>log the cc field<commit_after>/* REQUIREMENTS */
//////////////////
// Config
var config = require('../config/config.js'),
  secret = config.secret,
  // Express
  express = require('express'),
  router = express.Router(),
  // Models
  Mail = require('../models/email.js'), // Mail model
  Transaction = require('../models/transaction.js'), // Transaction model
  // Coinbase
  Client = require('coinbase').Client,
  client = new Client({
    'apiKey': config.coinbase.testnet.key,
    'apiSecret': config.coinbase.testnet.secret,
    'baseApiUri': 'https://api.sandbox.coinbase.com/v1/'
  }),
  Account = require('coinbase').model.Account,
  btcAccount = new Account(client, {
    'id': '55335c04fb9854796c00000c'
  }),
  // Mailgun
  Mailgun = require('mailgun').Mailgun,
  mg = new Mailgun(config.mailgun),

  // JSON Web Tokens
  jwt = require('jsonwebtoken');

module.exports = function(app, passport) {

  /* API ROUTES */

  //welcome to the api
  app.get('/api', function(req, res) {
    res.send('Welcome to the API');
  });

  // `/mailman`
  app.post('/api/mailman', function(req, res) {
    console.log('mailman recieved an email');
    console.log('It contained the following');
    console.log('The CC field said: ' + req.body.CC);

    // proceed if mailman was CCed into the mail.
    if (req.body.Cc && req.body.Cc.indexOf('mailman@mailman.ninja')) {

      // regex expression to find "re:", "fw:" "fwd:", etc.
      var junkRegex = /([\[\(] *)?(RE|FWD?) *([-:;)\]][ :;\])-]*|$)|\]+ *$/igm;

      Mail.findOne({
        subjectStripped: req.body.subject.replace(junkRegex, "")
      }, function(err, mail) {
        if (err) {
          console.log(err);
        } else if (mail && (mail.to === req.body.from &&
            mail.from === req.body.to)) {
          // if the mail exists and is being sent back from the original sender
          console.log('Recieved confirmation of a reply from original sender for mail:' + mail.id); //debug

          // TODO pay the recepient
          // LOTSA CODE

        } else if (!mail) {
          // if no such mail exists
          console.log('Mailman was notified of a new NEW mail'); //debug

          // save the metadata
          mail = new Mail();
          mail.type = "reward";
          mail.to = req.body.to;
          mail.date = req.body.Date;
          mail.cc = req.body.Cc;
          mail.sender = req.body.sender;
          mail.from = req.body.from;
          mail.subject = req.body.subject;

          // strip all re, and fwd from subject before saving as the stripped subject
          mail.subjectStripped = req.body.subject.replace(junkRegex, "");

          //create the address
          btcAccount.createAddress({
            "callback_url": 'http://the.mailman.ninja/api/payment/' + mail.id,
            "label": ""
          }, function(err, address) {
            if (err) {
              // output error and save mail
              console.log(err);
              mail.save();
            } else {
              // save the address and save the mail
              console.log('Created address' + address.address); //debug
              mail.btcAddress = address.address;
              mail.save(
                console.log('New mail saved') //debug
              );

              // send an invoice to the sender
              mg.sendText('Mailman <mailman@mailman.ninja>', [mail.sender],
                'RE: ' + mail.subject,
                'Hi, pay the reward here: ' + mail.btcAddress,
                'noreply@mailman.ninja', {},
                function(err) {
                  if (err) {
                    console.log('Unable to deliver invoice for mail ' +
                      mail.id + '\nerror: ' + err);
                  } else {
                    console.log('sent invoice for reward mail');
                  }
                });
            }
          });
        }
      });
    } else {
      console.log('mailman was not in the CC field');
    }
  });

  // When a callback is recieved for a payment made.
  // '/payment/:mail_id'
  app.post('/api/payment/:mail_id', function(req, res) {

    /* Example object to be recieved

      {
      "address": "1AmB4bxKGvozGcZnSSVJoM6Q56EBhzMiQ5",
      "amount": 1.23456,
      "transaction": {
        "hash": "7b95769dce68b9aa84e4aeda8d448e6cc17695a63cc2d361318eb0f6efdf8f82"
      }
    */
    console.log('Recieved a payment notification'); //debug
    jwt.verify(token, secret, function(err, decoded) {
      if (err) {
        return res.status(403).send({
          success: false,
          message: 'Invalid token'
        });
      } else if (decoded.mail_id !== req.params.mail_id) {

        console.log('Token mismatch');
        console.log('Possible attack!');
        console.log('Mail ID : ' + mail_id);
        console.log('Token ID : ' + decoded.mail_id);

        return res.status(403).send({
          success: false,
          message: 'Token mismatch'
        });

      } else if (decoded) {
        req.decoded = decoded;

        // find the mail with this id
        Mail.findById(req.params.mail_id, function(err, mail) {
          if (err) {
            console.log(err);
          } else {
            // save the callback object in the db
            // save the transaction
            var transaction = new Transaction();
            transaction.address = req.body.address;
            transaction.amount = req.body.amount;
            transaction.transaction.hash = req.transaction.hash;
            transaction.save(
              // append the transaction to the mail
              Mail.findByIdAndUpdate(mail._id, {
                  $push: {
                    'transaction': transaction
                  }
                }, {
                  safe: true,
                  upsert: true
                },
                function(err, model) {
                  console.log(err);
                }
              )
            );

            //determine what sort of mail this was
            if (mail.type === 'reward') {

              // mail the person saying there is a reward available
              mg.sendText('Mailman <mailman@mailman.ninja>', [mail.to],
                'RE: ' + mail.subject,
                'Hi, there\'s a ' + req.body.amount + ' BTC ' +
                'reward on replying to this email.\n ' +
                'Just keep `mailman@mailman.ninja` in the CC field so that I ' +
                'know you\'ve replied!',
                'noreply@mailman.ninja', {},
                function(err) {
                  if (err) {
                    console.log('Unable to deliver invoice for mail ' +
                      mail.id + '\nerror: ' + err);
                  } else {
                    console.log('Success');
                  }
                });
              // if the mail is an incoming mail sent to a user
            } else if (mail.type === 'incoming') {

              // TODO the code below has yet to be checked
              // infact, i don't think i've added the relevent schema changes
              User.findOne({
                'local.username': mail.username
              }, function(err, user) {

                mg.sendText('Mailman <mailman@mailman.ninja>', [mail.to],
                  'RE: ' + mail.subject,
                  'Hi, there\'s a ' + req.body.amount + ' BTC ' +
                  'reward on replying to this email.\n ' +
                  'Just keep `mailman@mailman.ninja` in the CC field so that I ' +
                  'know you\'ve replied!',
                  'noreply@mailman.ninja', {},
                  function(err) {
                    if (err) console.log('Unable to deliver invoice for mail ' +
                      mail.id + '\nerror: ' + err);
                    else console.log('Success');
                  });
              });

              // pay the recepient their share of the fee
            }
          }
        });
      }
    });
  });

  // new mail to specifc user
  app.post('/api/mail/:user_id', function(req, res) {
    console.log(req.body.lol);
    res.send(req.body['lol-hello']);

    var mail = new Mail();

    mail.type = "incoming";
    mail.incomingEmail = req.params.user.id;
    mail.to = req.body.to;
    mail.date = req.body.Date;
    mail.cc = req.body.Cc;
    mail.recipient = req.body.recipient;
    mail.sender = req.body.sender;
    mail.from = req.body.from;
    mail.subject = req.body.subject;
    mail.bodyPlain = req.body['body-plain'];
    mail.strippedText = req.body['stripped-text'];
    mail.strippedSignature = req.body['stripped-signature'];
    mail.bodyHtml = req.body['body-html'];
    mail.strippedHtml = req.body['stripped-html'];
    mail.attachmentCount = req.body['attachment-count'];
    mail.attachmentx = req.body['attachment-x'];
    mail.messageHeaders = req.body['message-headers'];
    mail.contentIdMap = req.body['content-id-map'];

    var callbackToken = jwt.sign({
      'mail_id': mail.id,
    }, secret);

    var addressArgs = {
      'callback_url': 'http://the.mailman.ninja/api/payment/' + mail.id +
        '?token=' + callbackToken,
      'label': mail.id
    };

    btcAccount.createAddress(addressArgs, function(err, address) {
      if (err) {
        // output error and save mail
        console.log(err);
        mail.save();
      } else {
        // save the address and save the mail
        mail.btcAddress = address.address;
        mail.save();

        // send an invoice to the sender
        mg.sendText('Mailman <mailman@mailman.ninja>', [mail.sender],
          'RE: ' + mail.subject,
          'Hi, your email will only be delivered if you pay for its delivery.\n' +
          'Please pay at this address: ' + mail.btcAddress,
          'noreply@mailman.ninja', {},
          function(err) {
            if (err) console.log('Unable to deliver invoice for mail ' +
              mail.id + '\nerror: ' + err);
            else console.log('Success');
          });
      }
    });

  });

  // User authorization (login)
  app.post('/api/user/auth', passport.authenticate('local-login', {
    successRedirect: '/user', // redirect to the user
    failureRedirect: '/', // redirect back to the home page on error
    failureFlash: true // allow flash messages
  }));

  // User signup
  app.post('/api/user/new', passport.authenticate('local-signup', {
    successRedirect: '/profile', // redirect to the secure profile section
    failureRedirect: '/signup', // redirect back to the signup page if there is an error
    failureFlash: true // allow flash messages
  }));

  // User logout
  app.get('/api/user/logout', function(req, res) {
    req.logout();
    res.redirect('/');
  });

};
<|endoftext|>


<commit_before>var express = require('express');
var router = express.Router();
var Client = require('telapi').client;
var bodyParser = require('body-parser')
var numbers = [];

var telapi = new Client(process.env.TELAPI_SID, process.env.TELAPI_TOKEN);

router.post('/', function(req, res) {
  if(req.body.user.name == null | req.body.user.phone == null || req.body.user.email == null) {
    return res.send(400, "You need to put in your user information in the settings page.");
  }
  for(var i = 0; i < req.body.selected.length; i++) {
    numbers.push(req.body.selected[i].number);
  }
  console.log(req.body.selected);
  console.log(numbers);
  for(var i = 0; i < numbers.length; i++) {
    telapi.create("sms_messages", {
      "From": process.env.TELAPI_NUMBER,
      "To": numbers[i],
      "Body": req.body.user.name + " is having a hard time and needs your help. Message them to let them know you are there for them."
    }, function (response) {
        res.send("Messages sent successfully");
      },
      function (error) {
        res.send(400, "An error occurred while sending messages");
      }
    );
  }
});

module.exports = router;
<commit_msg>add logging to figure out error where numbers do not exist<commit_after>var express = require('express');
var router = express.Router();
var Client = require('telapi').client;
var bodyParser = require('body-parser')
var numbers = [];

var telapi = new Client(process.env.TELAPI_SID, process.env.TELAPI_TOKEN);

router.post('/', function(req, res) {
  if(req.body.user.name == null | req.body.user.phone == null || req.body.user.email == null) {
    return res.send(400, "You need to put in your user information in the settings page.");
  }
  for(var i = 0; i < req.body.selected.length; i++) {
    numbers.push(req.body.selected[i].number);
  }
  console.log(req.body.selected);
  console.log(numbers);
  for(var i = 0; i < numbers.length; i++) {
    telapi.create("sms_messages", {
      "From": process.env.TELAPI_NUMBER,
      "To": numbers[i],
      "Body": req.body.user.name + " is having a hard time and needs your help. Message them to let them know you are there for them."
    }, function (response) {
        res.send("Messages sent successfully");
      },
      function (error) {
        res.send(400, "An error occurred while sending messages");
      }
    );
  }
  numbers = [];
});

module.exports = router;
<|endoftext|>


<commit_before>//
// Setup Scrollable view.  Want to make the bottom portion of the
// screen that fits thumbnails to be horizontally scrollable.
//

var scrollView1 = Titanium.UI.createScrollView({
	contentWidth:'auto',
	contentHeight:'auto',
	bottom:0,
	left:10,
	width:300,
	height:125,
	borderRadius:0,
	//backgroundColor:'blue',
    backgroundImage:'../images/png/corkboard.jpg',
	showVerticalScrollIndicator:false,
	showHorizontalScrollIndicator:true
});

var view1 = Ti.UI.createView({
    //backgroundImage:'../images/png/corkboard.jpg',
	//backgroundColor:'green',
	borderRadius:0,
	width:700,
	height:150,
	top:0
});

//
// Get image list from server
//

Ti.API.info( "Making ajax call for data to: " + win.site_url + "data/index/class/GetPhotos/method/getAllEventPhotos/id/" + win.idKey );

//loader.open( "GET", win.site_url + "data/index/class/GetPhotos/method/getPhotoDummyOwners/id/" + win.idKey );
win.loader.open( "GET", win.site_url + "data/index/class/GetPhotos/method/getAllEventPhotos/id/" + win.idKey );

win.loader.onload = function()
{

//    Ti.API.info( "Event Info: " + this.responseText );

    results = eval('('+this.responseText+')');

    var widthCounter = 5;

    // Set max number of photos in slider
    var maxPhotos = 7;

    if( results.length < maxPhotos ){
        maxPhotos = results.length;
    }

    // Only show 7 images here
    for(var i=0; i<maxPhotos; i++){

        var av_image = Titanium.UI.createImageView({
            image:'http://'+results[i].server_location+results[i].thumb_url, // the image for the image view
            top:10,
            left:widthCounter,
            height:82,
	    	//backgroundColor: "#FFFFFF",
            //borderColor: "#3F5696",
            //borderWidth: 0,
            //borderRadius: 3,
            width:70
        });

        // Pass the url to the event listener
        av_image.photo_url = 'http://'+results[i].server_location+results[i].image_url;
        av_image.server_location = results[i].server_location;
        av_image.image_url = results[i].image_url;
        av_image.back_location = 'home';

        // Event listener when the user clicks on the photo in the slider
        av_image.addEventListener('click',function(e)
        {
            // Open photo to full page
            Ti.API.info( "User clicked on photo: " + e.source.photo_url );

            // Variables passed into this event listener
            win.windowFullPhoto.back_location = e.source.back_location;
            win.windowFullPhoto.photo_url = e.source.photo_url;
            win.windowFullPhoto.image_url = e.source.image_url;
            win.windowFullPhoto.server_location = e.source.server_location;

            win.windowFullPhoto.open();
            win.hide();

        });

        view1.add(av_image);

        widthCounter = widthCounter + 80;
    }
};

// Send the HTTP request
win.loader.send();

scrollView1.add(view1);

win.add(scrollView1);

<commit_msg>Change the photo slider so that it only scrolls horizontally and not vertically<commit_after>//
// Setup Scrollable view.  Want to make the bottom portion of the
// screen that fits thumbnails to be horizontally scrollable.
//

var scrollView1 = Titanium.UI.createScrollView({
	contentWidth:'auto',
	contentHeight:'40',
	bottom:0,
	left:10,
	width:300,
	height:125,
	borderRadius:0,
	//backgroundColor:'blue',
    backgroundImage:'../images/png/corkboard.jpg',
	showVerticalScrollIndicator:false,
	showHorizontalScrollIndicator:true
});

var view1 = Ti.UI.createView({
    //backgroundImage:'../images/png/corkboard.jpg',
	//backgroundColor:'green',
	borderRadius:0,
	width:700,
	height:150,
	top:0
});

//
// Get image list from server
//

Ti.API.info( "Making ajax call for data to: " + win.site_url + "data/index/class/GetPhotos/method/getAllEventPhotos/id/" + win.idKey );

//loader.open( "GET", win.site_url + "data/index/class/GetPhotos/method/getPhotoDummyOwners/id/" + win.idKey );
win.loader.open( "GET", win.site_url + "data/index/class/GetPhotos/method/getAllEventPhotos/id/" + win.idKey );

win.loader.onload = function()
{

//    Ti.API.info( "Event Info: " + this.responseText );

    results = eval('('+this.responseText+')');

    var widthCounter = 5;

    // Set max number of photos in slider
    var maxPhotos = 7;

    if( results.length < maxPhotos ){
        maxPhotos = results.length;
    }

    // Only show 7 images here
    for(var i=0; i<maxPhotos; i++){

        var av_image = Titanium.UI.createImageView({
            image:'http://'+results[i].server_location+results[i].thumb_url, // the image for the image view
            top:10,
            left:widthCounter,
            height:82,
	    	//backgroundColor: "#FFFFFF",
            //borderColor: "#3F5696",
            //borderWidth: 0,
            //borderRadius: 3,
            width:70
        });

        // Pass the url to the event listener
        av_image.photo_url = 'http://'+results[i].server_location+results[i].image_url;
        av_image.server_location = results[i].server_location;
        av_image.image_url = results[i].image_url;
        av_image.back_location = 'home';

        // Event listener when the user clicks on the photo in the slider
        av_image.addEventListener('click',function(e)
        {
            // Open photo to full page
            Ti.API.info( "User clicked on photo: " + e.source.photo_url );

            // Variables passed into this event listener
            win.windowFullPhoto.back_location = e.source.back_location;
            win.windowFullPhoto.photo_url = e.source.photo_url;
            win.windowFullPhoto.image_url = e.source.image_url;
            win.windowFullPhoto.server_location = e.source.server_location;

            win.windowFullPhoto.open();
            win.hide();

        });

        view1.add(av_image);

        widthCounter = widthCounter + 80;
    }
};

// Send the HTTP request
win.loader.send();

scrollView1.add(view1);

win.add(scrollView1);

<|endoftext|>