<commit_before>// Copyright 2013 Joyent, Inc.  All rights reserved.

var assert = require('assert');
var fs = require('fs');
var http = require('http');
var https = require('https');
var util = require('util');
var path = require('path');

var Logger = require('bunyan');
var restify = require('restify');
var SDC = require('sdc-clients');
var account = require('./account');
var analytics = require('./analytics');
var auth = require('./auth');
var datacenters = require('./datacenters');
var datasets = require('./datasets');
var docs = require('./docs');
var keys = require('./keys');
var machines = require('./machines');
var metadata = require('./metadata');
var packages = require('./packages');
var snapshots = require('./snapshots');
var tags = require('./tags');
var throttle = require('./throttle');
var networks = require('./networks');
var usage = require('./usage');
var audit = require('./audit');
var rules = require('./rules');

// PUBAPI-646: Backwards compatible authorization parser
var authorizationParser = require('./authorization');

// --- Globals

var HTML_FMT = '
%s
\n';
var VERSION = false;
var sprintf = util.format;

var userThrottle = throttle.getUserThrottle;
var ipThrottle = throttle.getIpThrottle;

// --- Internal functions

/**
 * Returns the current semver version stored in CloudAPI's package.json.
 * This is used to set in the API versioning and in the Server header.
 *
 * @return {String} version.
 */
function version() {
    if (!VERSION) {
        var pkg = fs.readFileSync(__dirname + '/../package.json', 'utf8');
        VERSION = JSON.parse(pkg).version;
    }

    return VERSION;
}

/**
 * Creates an SDC.UFDS client instance pointing to the UFDS server provided
 * in options. callback will be called either with Error - cb(err) - or
 * with the recently instantiated client object: cb(null, ufds_client)
 */
function createUfdsClient(options, callback) {
    var ufds = new SDC.UFDS(options);

    ufds.once('connect', function () {
        ufds.removeAllListeners('error');
        ufds.on('error', function (err) {
            options.log.error(err, 'UFDS disconnected');
        });
        ufds.on('connect', function () {
            options.log.info('UFDS reconnected');
        });
        callback(null, ufds);
    });

    ufds.once('error', function (err) {
        // You are screwed. It's likely that the bind credentials were bad.
        // Treat this as fatal and move on:
        options.log.error({err: err}, 'UFDS connection error');
        callback(err);
    });

    // Prevent process exiting due to LDAP client emitting "OtherError" on
    // request timeout:
    // JPC-1217: The following is making CloudAPI raise pretty much every
    // exception, including server.on('uncaughtException'). Commenting out for
    // testing.
    // process.on('uncaughtException', function preventOtherError(e) {
    //    if (e && e.name && e.name === 'OtherError' &&
    //        /request\stimeout/.test(e.message)) {
    //        return;
    //    } else {
    //        throw e;
    //    }
    // });
}

function createHTTPClients(options) {
    return {
        ca: new SDC.CA(options.ca),
        vmapi: new SDC.VMAPI(options.vmapi),
        napi: new SDC.NAPI(options.napi),
        fwapi: new SDC.FWAPI(options.fwapi),
        imgapi: new SDC.IMGAPI.createClient(options.imgapi),
        usageapi: SDC.UsageAPI(options.usageapi),
        keyapi: options.keyapi
    };
}

function createClients(options, callback) {
    assert.ok(options);
    assert.ok(options.ca);
    assert.ok(options.vmapi);
    assert.ok(options.napi);
    assert.ok(options.imgapi);
    assert.ok(options.usageapi);
    assert.ok(options.ufds);
    assert.ok(options.ufds_master);
    assert.ok(options.keyapi);

    options.ufds.log = options.log;
    options.ufds_master.log = options.log;
    options.ca.log = options.log;
    options.vmapi.log = options.log;
    options.napi.log = options.log;
    options.imgapi.log = options.log;
    options.usageapi.log = options.log;

    // On this case, we'll point pkg and ufds to the same UFDS server,
    // given we're running into "ufds-master" headnode
    var ufds_is_master = (options.ufds_master.url === 'ldaps://');

    // Single ufds server
    if (ufds_is_master) {
        createUfdsClient(options.ufds, function (err, ufds) {
            if (err) {
                return callback(err);
            }
            var clients = createHTTPClients(options);
            clients.ufds = ufds;
            clients.pkg = new SDC.Package(ufds);
            clients.ufds_master = ufds;
            clients.is_ufds_master = true;
            return callback(null, clients);
        });
    } else {
        // Master and HN local UFDS servers:
        createUfdsClient(options.ufds_master, function (err, ufds_master) {
            if (err) {
                return callback(err);
            }
            return createUfdsClient(options.ufds, function (err2, ufds) {
                if (err2) {
                    return callback(err2);
                }
                var clients = createHTTPClients(options);
                clients.ufds = ufds;
                clients.ufds_master = ufds_master;
                clients.is_ufds_master = false;
                clients.pkg = new SDC.Package(ufds);
                return callback(null, clients);
            });
        });
    }
}

/**
 * Load enabled pre|post provision plugins
 *
 * @param {Array} where each member is an {Object} representing a plugin config
 * @returns {Object} with first member being preProvision methods to call, and
 *          second member postProvision
 */

function loadPlugins(plugins, log) {
    assert.ok(plugins);
    // Load enabled pre|post provision plugins:
    var p = {};
    var cfg = {};
    var preProvision = [];
    var postProvision = [];
    var pluginsDir = path.resolve(__dirname, '../plugins');
    plugins.forEach(function (plugin) {
        if (plugin.enabled) {
            log.info('Loading plugin: %s', plugin.name);
            cfg[plugin.name] = plugin.config;
            p[plugin.name] = require(util.format(
                    pluginsDir + '/%s', plugin.name));
            if (typeof (p[plugin.name].preProvision) === 'function') {
                preProvision.push(p[plugin.name].preProvision(
                        cfg[plugin.name]));
            }

            if (typeof (p[plugin.name].postProvision) === 'function') {
                postProvision.push(p[plugin.name].postProvision(
                        cfg[plugin.name]));
            }
        }
    });

    return [preProvision, postProvision];
}

// --- API

module.exports = {

    createServer: function (config, callback) {

        var log = config.log;
        var globalAgentInterval;
        var server;
        var machineThrottle;

        config.name = 'Joyent SmartDataCenter ' + version();
        config.version = [version(), '7.0.0', '6.5.0'];
        config.formatters = {
            'text/html': function formatHTML(req, res, body) {
                if (typeof (body) === 'string') {
                    return body;
                }

                var html;
                if (body instanceof Error) {
                    html = sprintf(HTML_FMT, body.stack);
                } else if (Buffer.isBuffer(body)) {
                    html = sprintf(HTML_FMT, body.toString('base64'));
                } else {
                    html = sprintf(HTML_FMT, body.toString());
                }

                return html;
            },
            'text/css': function formatCSS(req, res, body) {
                if (typeof (body) === 'string') {
                    return body;
                }

                return '';
            },

            'image/png': function formatPNG(req, res, body) {
                return body;
            }
        };

        return createClients(config, function (error, clients) {
            if (error) {
                log.error({err: error}, 'Create clients error');
                throw error;
            }
            // ufds client itself comes plenty of listeners to buble up
            // ldap client events. Let's sightly increase limits
            clients.ufds.setMaxListeners(15);
            clients.ufds.on('timeout', function (msg) {
                log.warn({message: msg},
                    'local UFDS client timeout (recycling)');
                // server.emit('uncaughtException', req, res, null,
                //    new restify.InternalError('Backend Timeout Error'));
                try {
                    clients.ufds.client.socket.destroy();
                } catch (e) {
                    log.fatal({err: e},
                        'could not destroy the timed out local UFDS socket');
                }
            });

            if (!clients.is_ufds_master) {
                clients.ufds_master.setMaxListeners(15);
                clients.ufds_master.on('timeout', function (msg) {
                    log.warn({message: msg},
                        'UFDS Master client timeout (recycling)');
                    //server.emit('uncaughtException', req, res, null,
                    //    new restify.InternalError('Backend Timeout Error'));
                    try {
                        clients.ufds.client.socket.destroy();
                    } catch (e) {
                        log.fatal({err: e},
                        'could not destroy the timed out master UFDS socket');
                    }
                });
            }

            server = restify.createServer(config);

            server.use(restify.acceptParser(server.acceptable));
            server.use(authorizationParser());
            server.use(restify.dateParser());
            server.use(restify.queryParser());
            server.use(restify.bodyParser({
                overrideParams: true,
                mapParams: true
            }));
            server.use(restify.fullResponse());

            // docs handler here has to run before auth stuff
            docs.mount(server);

            server.use(function setupSDCProxies(req, res, next) {
                req.config = config;
                req.sdc = clients;
                return next();
            });

            // Run authentication and authorization before everything else
            server.use(auth.basicAuth);
            server.use(auth.signatureAuth);
            server.use(auth.assertAuthenticated);
            server.use(auth.loadAccount);
            server.use(auth.authorize);

            server.use(function sendZeroContentLengthon65(req, res, next) {
                if (req.method === 'HEAD' && /6\.5/.test(req.getVersion())) {
                    res.contentLength = 0;
                }

                return next();
            });

            server.use(function readOnlyMode(req, res, next) {
                if ((req.method === 'PUT' ||
                    req.method === 'POST' ||
                    req.method === 'DELETE') &&
                    typeof (req.config.read_only) !== 'undefined' &&
                    req.config.read_only === true) {
                    return next(new restify.ServiceUnavailableError(
                        'SmartDataCenter is being upgraded'));
                }

                return next();
            });

            server.use(function backCompatXHeaders(req, res, next) {
                res.once('header', function () {
                    if (res.getHeader('Request-Id')) {
                        res.setHeader('X-Request-Id',
                            res.getHeader('Request-Id'));
                    }

                    if (res.getHeader('Api-Version')) {
                        res.setHeader('X-Api-Version',
                            res.getHeader('Api-Version'));
                    }

                    if (res.getHeader('Response-Time')) {
                        res.setHeader('X-Response-Time',
                            res.getHeader('Response-Time'));
                    }
                });
                return next();
            });

            // Save Context for Machines Audit:
            server.use(function saveContext(req, res, next) {
                if (!/\/machines/.test(req.url)) {
                    return next();
                }

                if (req.method !== 'PUT' && req.method !== 'POST' &&
                    req.method !== 'DELETE') {
                    return next();
                }

                var authType = 'signature';

                if (req.authorization.scheme.toLowerCase() === 'basic') {
                    authType = 'basic';
                }

                if (typeof (req.headers['X-Auth-Token']) !== 'undefined') {
                    authType = 'token';
                }

                req._auditCtx = {
                    type: authType,
                    ip: req.connection.remoteAddress
                };

                if (authType === 'basic') {
                    req._auditCtx.user = req.username.login;
                } else if (req.authorization.signature) {
                    req._auditCtx.keyId = req.authorization.signature.keyId;
                }

                return next();
            });

            // Now mount all the API handlers
            server.use(datasets.load);
            datasets.mount(server, userThrottle(config, 'datasets'), config);

            server.use(packages.load);
            packages.mount(server, userThrottle(config, 'packages'));

            server.use(networks.load);
            networks.mount(server, userThrottle(config, 'networks'));

            var plugins =  [];
            if (typeof (config.plugins) !== 'undefined' &&
                    Array.isArray(config.plugins)) {
                plugins = loadPlugins(config.plugins, log);
            }

            // Wait for datasets and packages to mount everything else:
            account.mount(server, userThrottle(config, 'account'));
            datacenters.mount(server, userThrottle(config, 'datacenter'));
            keys.mount(server, userThrottle(config, 'keys'));

            machineThrottle = userThrottle(config, 'machines');
            // Make sure we pass the pre|post provision hooks from the plugins
            machines.mount(server, machineThrottle, plugins[0], plugins[1]);
            metadata.mount(server, machineThrottle);
            snapshots.mount(server, machineThrottle);
            tags.mount(server, machineThrottle);
            audit.mount(server, machineThrottle);
            rules.mount(server, machineThrottle);

            analytics.mount(server, userThrottle(config, 'analytics'));

            // Register an audit logger (avoid it while testing):
            if (typeof (config.test) === 'undefined') {
                server.on('after', restify.auditLogger({
                    log: new Logger({
                        name: 'audit',
                        streams: [
                            {
                                level: 'info',
                                stream: process.stdout
                            }
                        ]
                    })
                }));
            }

            // Closure to wrap up the port setting
            server.start = function start(cb) {
                if (config.read_only === true) {
                    log.warn('Starting Cloud API on read only mode.');
                }
                return server.listen(config.port, cb);
            };

            // Setup a logger on HTTP Agent queueing
            globalAgentInterval = setInterval(function () {
                var agent = http.globalAgent;
                if (agent.requests && agent.requests.length > 0) {
                    log.warn('http.globalAgent queueing, depth=%d',
                                agent.requests.length);
                }

                agent = https.globalAgent;
                if (agent.requests && agent.requests.length > 0) {
                    log.warn('https.globalAgent queueing, depth=%d',
                                agent.requests.length);
                }
            }, 1000);

            // If we make JSON main format, res.send(error) will send our
            // Restify formatted error objects, and properly hide the v8
            // backtrace.
            server.acceptable.unshift('application/json');

            server.on('close', function () {
                clearInterval(globalAgentInterval);
                clients.ufds.close(function (err) {
                    if (err) {
                        throw err;
                    }
                    if (!clients.ufds_master.closed) {
                        clients.ufds_master.close(function (err2) {
                            if (err2) {
                                throw err2;
                            }
                        });
                    }
                });
            });

            server._clients = clients;
            return callback(server);

        });

    }

};
<commit_msg>PUBAPI-714: Audit log using a child of main application log instead of creating its own one.<commit_after>// Copyright 2013 Joyent, Inc.  All rights reserved.

var assert = require('assert');
var fs = require('fs');
var http = require('http');
var https = require('https');
var util = require('util');
var path = require('path');

var Logger = require('bunyan');
var restify = require('restify');
var SDC = require('sdc-clients');
var account = require('./account');
var analytics = require('./analytics');
var auth = require('./auth');
var datacenters = require('./datacenters');
var datasets = require('./datasets');
var docs = require('./docs');
var keys = require('./keys');
var machines = require('./machines');
var metadata = require('./metadata');
var packages = require('./packages');
var snapshots = require('./snapshots');
var tags = require('./tags');
var throttle = require('./throttle');
var networks = require('./networks');
var usage = require('./usage');
var audit = require('./audit');
var rules = require('./rules');

// PUBAPI-646: Backwards compatible authorization parser
var authorizationParser = require('./authorization');

// --- Globals

var HTML_FMT = '
%s
\n';
var VERSION = false;
var sprintf = util.format;

var userThrottle = throttle.getUserThrottle;
var ipThrottle = throttle.getIpThrottle;

// --- Internal functions

/**
 * Returns the current semver version stored in CloudAPI's package.json.
 * This is used to set in the API versioning and in the Server header.
 *
 * @return {String} version.
 */
function version() {
    if (!VERSION) {
        var pkg = fs.readFileSync(__dirname + '/../package.json', 'utf8');
        VERSION = JSON.parse(pkg).version;
    }

    return VERSION;
}

/**
 * Creates an SDC.UFDS client instance pointing to the UFDS server provided
 * in options. callback will be called either with Error - cb(err) - or
 * with the recently instantiated client object: cb(null, ufds_client)
 */
function createUfdsClient(options, callback) {
    var ufds = new SDC.UFDS(options);

    ufds.once('connect', function () {
        ufds.removeAllListeners('error');
        ufds.on('error', function (err) {
            options.log.error(err, 'UFDS disconnected');
        });
        ufds.on('connect', function () {
            options.log.info('UFDS reconnected');
        });
        callback(null, ufds);
    });

    ufds.once('error', function (err) {
        // You are screwed. It's likely that the bind credentials were bad.
        // Treat this as fatal and move on:
        options.log.error({err: err}, 'UFDS connection error');
        callback(err);
    });

    // Prevent process exiting due to LDAP client emitting "OtherError" on
    // request timeout:
    // JPC-1217: The following is making CloudAPI raise pretty much every
    // exception, including server.on('uncaughtException'). Commenting out for
    // testing.
    // process.on('uncaughtException', function preventOtherError(e) {
    //    if (e && e.name && e.name === 'OtherError' &&
    //        /request\stimeout/.test(e.message)) {
    //        return;
    //    } else {
    //        throw e;
    //    }
    // });
}

function createHTTPClients(options) {
    return {
        ca: new SDC.CA(options.ca),
        vmapi: new SDC.VMAPI(options.vmapi),
        napi: new SDC.NAPI(options.napi),
        fwapi: new SDC.FWAPI(options.fwapi),
        imgapi: new SDC.IMGAPI.createClient(options.imgapi),
        usageapi: SDC.UsageAPI(options.usageapi),
        keyapi: options.keyapi
    };
}

function createClients(options, callback) {
    assert.ok(options);
    assert.ok(options.ca);
    assert.ok(options.vmapi);
    assert.ok(options.napi);
    assert.ok(options.imgapi);
    assert.ok(options.usageapi);
    assert.ok(options.ufds);
    assert.ok(options.ufds_master);
    assert.ok(options.keyapi);

    options.ufds.log = options.log;
    options.ufds_master.log = options.log;
    options.ca.log = options.log;
    options.vmapi.log = options.log;
    options.napi.log = options.log;
    options.imgapi.log = options.log;
    options.usageapi.log = options.log;

    // On this case, we'll point pkg and ufds to the same UFDS server,
    // given we're running into "ufds-master" headnode
    var ufds_is_master = (options.ufds_master.url === 'ldaps://');

    // Single ufds server
    if (ufds_is_master) {
        createUfdsClient(options.ufds, function (err, ufds) {
            if (err) {
                return callback(err);
            }
            var clients = createHTTPClients(options);
            clients.ufds = ufds;
            clients.pkg = new SDC.Package(ufds);
            clients.ufds_master = ufds;
            clients.is_ufds_master = true;
            return callback(null, clients);
        });
    } else {
        // Master and HN local UFDS servers:
        createUfdsClient(options.ufds_master, function (err, ufds_master) {
            if (err) {
                return callback(err);
            }
            return createUfdsClient(options.ufds, function (err2, ufds) {
                if (err2) {
                    return callback(err2);
                }
                var clients = createHTTPClients(options);
                clients.ufds = ufds;
                clients.ufds_master = ufds_master;
                clients.is_ufds_master = false;
                clients.pkg = new SDC.Package(ufds);
                return callback(null, clients);
            });
        });
    }
}

/**
 * Load enabled pre|post provision plugins
 *
 * @param {Array} where each member is an {Object} representing a plugin config
 * @returns {Object} with first member being preProvision methods to call, and
 *          second member postProvision
 */

function loadPlugins(plugins, log) {
    assert.ok(plugins);
    // Load enabled pre|post provision plugins:
    var p = {};
    var cfg = {};
    var preProvision = [];
    var postProvision = [];
    var pluginsDir = path.resolve(__dirname, '../plugins');
    plugins.forEach(function (plugin) {
        if (plugin.enabled) {
            log.info('Loading plugin: %s', plugin.name);
            cfg[plugin.name] = plugin.config;
            p[plugin.name] = require(util.format(
                    pluginsDir + '/%s', plugin.name));
            if (typeof (p[plugin.name].preProvision) === 'function') {
                preProvision.push(p[plugin.name].preProvision(
                        cfg[plugin.name]));
            }

            if (typeof (p[plugin.name].postProvision) === 'function') {
                postProvision.push(p[plugin.name].postProvision(
                        cfg[plugin.name]));
            }
        }
    });

    return [preProvision, postProvision];
}

// --- API

module.exports = {

    createServer: function (config, callback) {

        var log = config.log;
        var globalAgentInterval;
        var server;
        var machineThrottle;

        config.name = 'Joyent SmartDataCenter ' + version();
        config.version = [version(), '7.0.0', '6.5.0'];
        config.formatters = {
            'text/html': function formatHTML(req, res, body) {
                if (typeof (body) === 'string') {
                    return body;
                }

                var html;
                if (body instanceof Error) {
                    html = sprintf(HTML_FMT, body.stack);
                } else if (Buffer.isBuffer(body)) {
                    html = sprintf(HTML_FMT, body.toString('base64'));
                } else {
                    html = sprintf(HTML_FMT, body.toString());
                }

                return html;
            },
            'text/css': function formatCSS(req, res, body) {
                if (typeof (body) === 'string') {
                    return body;
                }

                return '';
            },

            'image/png': function formatPNG(req, res, body) {
                return body;
            }
        };

        return createClients(config, function (error, clients) {
            if (error) {
                log.error({err: error}, 'Create clients error');
                throw error;
            }
            // ufds client itself comes plenty of listeners to buble up
            // ldap client events. Let's sightly increase limits
            clients.ufds.setMaxListeners(15);
            clients.ufds.on('timeout', function (msg) {
                log.warn({message: msg},
                    'local UFDS client timeout (recycling)');
                // server.emit('uncaughtException', req, res, null,
                //    new restify.InternalError('Backend Timeout Error'));
                try {
                    clients.ufds.client.socket.destroy();
                } catch (e) {
                    log.fatal({err: e},
                        'could not destroy the timed out local UFDS socket');
                }
            });

            if (!clients.is_ufds_master) {
                clients.ufds_master.setMaxListeners(15);
                clients.ufds_master.on('timeout', function (msg) {
                    log.warn({message: msg},
                        'UFDS Master client timeout (recycling)');
                    //server.emit('uncaughtException', req, res, null,
                    //    new restify.InternalError('Backend Timeout Error'));
                    try {
                        clients.ufds.client.socket.destroy();
                    } catch (e) {
                        log.fatal({err: e},
                        'could not destroy the timed out master UFDS socket');
                    }
                });
            }

            server = restify.createServer(config);

            server.use(restify.acceptParser(server.acceptable));
            server.use(authorizationParser());
            server.use(restify.dateParser());
            server.use(restify.queryParser());
            server.use(restify.bodyParser({
                overrideParams: true,
                mapParams: true
            }));
            server.use(restify.fullResponse());

            // docs handler here has to run before auth stuff
            docs.mount(server);

            server.use(function setupSDCProxies(req, res, next) {
                req.config = config;
                req.sdc = clients;
                return next();
            });

            // Run authentication and authorization before everything else
            server.use(auth.basicAuth);
            server.use(auth.signatureAuth);
            server.use(auth.assertAuthenticated);
            server.use(auth.loadAccount);
            server.use(auth.authorize);

            server.use(function sendZeroContentLengthon65(req, res, next) {
                if (req.method === 'HEAD' && /6\.5/.test(req.getVersion())) {
                    res.contentLength = 0;
                }

                return next();
            });

            server.use(function readOnlyMode(req, res, next) {
                if ((req.method === 'PUT' ||
                    req.method === 'POST' ||
                    req.method === 'DELETE') &&
                    typeof (req.config.read_only) !== 'undefined' &&
                    req.config.read_only === true) {
                    return next(new restify.ServiceUnavailableError(
                        'SmartDataCenter is being upgraded'));
                }

                return next();
            });

            server.use(function backCompatXHeaders(req, res, next) {
                res.once('header', function () {
                    if (res.getHeader('Request-Id')) {
                        res.setHeader('X-Request-Id',
                            res.getHeader('Request-Id'));
                    }

                    if (res.getHeader('Api-Version')) {
                        res.setHeader('X-Api-Version',
                            res.getHeader('Api-Version'));
                    }

                    if (res.getHeader('Response-Time')) {
                        res.setHeader('X-Response-Time',
                            res.getHeader('Response-Time'));
                    }
                });
                return next();
            });

            // Save Context for Machines Audit:
            server.use(function saveContext(req, res, next) {
                if (!/\/machines/.test(req.url)) {
                    return next();
                }

                if (req.method !== 'PUT' && req.method !== 'POST' &&
                    req.method !== 'DELETE') {
                    return next();
                }

                var authType = 'signature';

                if (req.authorization.scheme.toLowerCase() === 'basic') {
                    authType = 'basic';
                }

                if (typeof (req.headers['X-Auth-Token']) !== 'undefined') {
                    authType = 'token';
                }

                req._auditCtx = {
                    type: authType,
                    ip: req.connection.remoteAddress
                };

                if (authType === 'basic') {
                    req._auditCtx.user = req.username.login;
                } else if (req.authorization.signature) {
                    req._auditCtx.keyId = req.authorization.signature.keyId;
                }

                return next();
            });

            // Now mount all the API handlers
            server.use(datasets.load);
            datasets.mount(server, userThrottle(config, 'datasets'), config);

            server.use(packages.load);
            packages.mount(server, userThrottle(config, 'packages'));

            server.use(networks.load);
            networks.mount(server, userThrottle(config, 'networks'));

            var plugins =  [];
            if (typeof (config.plugins) !== 'undefined' &&
                    Array.isArray(config.plugins)) {
                plugins = loadPlugins(config.plugins, log);
            }

            // Wait for datasets and packages to mount everything else:
            account.mount(server, userThrottle(config, 'account'));
            datacenters.mount(server, userThrottle(config, 'datacenter'));
            keys.mount(server, userThrottle(config, 'keys'));

            machineThrottle = userThrottle(config, 'machines');
            // Make sure we pass the pre|post provision hooks from the plugins
            machines.mount(server, machineThrottle, plugins[0], plugins[1]);
            metadata.mount(server, machineThrottle);
            snapshots.mount(server, machineThrottle);
            tags.mount(server, machineThrottle);
            audit.mount(server, machineThrottle);
            rules.mount(server, machineThrottle);

            analytics.mount(server, userThrottle(config, 'analytics'));

            // Register an audit logger (avoid it while testing):
            if (typeof (config.test) === 'undefined') {
                server.on('after', restify.auditLogger({
                    log: log.child({component: 'audit'})
                }));
            }

            // Closure to wrap up the port setting
            server.start = function start(cb) {
                if (config.read_only === true) {
                    log.warn('Starting Cloud API on read only mode.');
                }
                return server.listen(config.port, cb);
            };

            // Setup a logger on HTTP Agent queueing
            globalAgentInterval = setInterval(function () {
                var agent = http.globalAgent;
                if (agent.requests && agent.requests.length > 0) {
                    log.warn('http.globalAgent queueing, depth=%d',
                                agent.requests.length);
                }

                agent = https.globalAgent;
                if (agent.requests && agent.requests.length > 0) {
                    log.warn('https.globalAgent queueing, depth=%d',
                                agent.requests.length);
                }
            }, 1000);

            // If we make JSON main format, res.send(error) will send our
            // Restify formatted error objects, and properly hide the v8
            // backtrace.
            server.acceptable.unshift('application/json');

            server.on('close', function () {
                clearInterval(globalAgentInterval);
                clients.ufds.close(function (err) {
                    if (err) {
                        throw err;
                    }
                    if (!clients.ufds_master.closed) {
                        clients.ufds_master.close(function (err2) {
                            if (err2) {
                                throw err2;
                            }
                        });
                    }
                });
            });

            server._clients = clients;
            return callback(server);

        });

    }

};
<|endoftext|>


<commit_before>/**
 * Handles writting the notes to the browser console in synchronization with the reveal.js
 */
var ConsoleNotes = (function() {

  function log(event) {
    // event.previousSlide, event.currentSlide, event.indexh, event.indexv
	  var notes = event.currentSlide.querySelector(".notes");

		if (notes) {
      var html = notes.innerHTML;
      if (true == notes.getAttrubute("data-trim")) {
        html = html.replace(/\n\s+/g, "\n");
      }
	    console.info(html);
	  }
  }

  // Fires when slide is changed
  Reveal.addEventListener("slidechanged", log);
})();
<commit_msg>Update console-notes.js<commit_after>/**
 * Handles writting the notes to the browser console in synchronization with the reveal.js
 */
var ConsoleNotes = (function() {

  function log(event) {
    // event.previousSlide, event.currentSlide, event.indexh, event.indexv
    var notes = event.currentSlide.querySelector(".notes");

    if (notes) {
      var html = notes.innerHTML;
      if (true == notes.getAttrubute("data-trim")) {
        html = html.replace(/\n\s+/g, "\n");
      }
      console.info(html);
    }
  }

  // Fires when slide is changed
  Reveal.addEventListener("slidechanged", log);
})();
<|endoftext|>


<commit_before>// app.js
//
// main function for activity pump application
//
// Copyright 2011-2012, E14N https://e14n.com/
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

var urlparse = require("url").parse,
    auth = require("connect-auth"),
    Step = require("step"),
    databank = require("databank"),
    express = require("express"),
    _ = require("underscore"),
    fs = require("fs"),
    path = require("path"),
    Logger = require("bunyan"),
    uuid = require("node-uuid"),
    DialbackClient = require("dialback-client"),
    api = require("../routes/api"),
    web = require("../routes/web"),
    shared = require("../routes/shared"),
    webfinger = require("../routes/webfinger"),
    clientreg = require("../routes/clientreg"),
    oauth = require("../routes/oauth"),
    confirm = require("../routes/confirm"),
    uploads = require("../routes/uploads"),
    schema = require("./schema").schema,
    HTTPError = require("./httperror").HTTPError,
    Provider = require("./provider").Provider,
    URLMaker = require("./urlmaker").URLMaker,
    rawBody = require("./rawbody").rawBody,
    Distributor = require("./distributor"),
    pumpsocket = require("./pumpsocket"),
    Firehose = require("./firehose"),
    Mailer = require("./mailer"),
    version = require("./version").version,
    Credentials = require("./model/credentials").Credentials,
    ActivitySpam = require("./activityspam"),
    Databank = databank.Databank,
    DatabankObject = databank.DatabankObject,
    DatabankStore = require('connect-databank')(express);

var makeApp = function(config, callback) {

    var params,
        defaults = {port: 31337,
                    hostname: "127.0.0.1",
                    site: "pump.io",
                    sockjs: true,
                    debugClient: false,
                    firehose: "ofirehose.com",
                    requireEmail: false,
                    disableRegistration: false},
        port,
        hostname,
        address,
        log,
        db,
        logParams = {
            name: "pump.io",
            serializers: {
                req: Logger.stdSerializers.req,
                res: Logger.stdSerializers.res,
                principal: function(principal) {
                    if (principal) {
                        return {id: principal.id, type: principal.objectType};
                    } else {
                        return {id: "<none>"};
                    }
                },
                client: function(client) {
                    if (client) {
                        return {key: client.consumer_key, title: client.title || "<none>"};
                    } else {
                        return {key: "<none>", title: "<none>"};
                    }
                }
            }
        };

    // Fill in defaults if they're not there

    config = _.defaults(config, defaults);

    port     = config.port;
    hostname = config.hostname;
    address  = config.address || config.hostname;

    if (process.getuid) {
        if (port < 1024 && process.getuid() !== 0) {
            callback(new Error("Can't listen to ports lower than 1024 on POSIX systems unless you're root."), null);
            return;
        }
    }

    if (config.logfile) {
        logParams.streams = [{path: config.logfile}];
    } else if (config.nologger) {
        logParams.streams = [{path: "/dev/null"}];
    } else {
        logParams.streams = [{stream: process.stderr}];
    }

    log = new Logger(logParams);

    log.info("Initializing pump.io");

    // Initiate the DB

    if (_(config).has("params")) {
        params = config.params;
    } else {
        params = {};
    }

    if (_(params).has("schema")) {
        _.extend(params.schema, schema);
    } else {
        params.schema = schema;
    }

    db = Databank.get(config.driver, params);

    // Connect...

    log.info("Connecting to databank with driver '"+config.driver+"'");

    db.connect({}, function(err) {

        var useHTTPS = _(config).has('key'),
            useBounce = _(config).has('bounce') && config.bounce,
            app,
            io,
            bounce,
            dialbackClient,
            requestLogger = function(log) {
                return function(req, res, next) {
                    var weblog = log.child({"req_id": uuid.v4(), component: "web"});
                    var end = res.end;
                    req.log = weblog;
                    res.end = function(chunk, encoding) {
                        var rec;
                        res.end = end;
                        res.end(chunk, encoding);
                        rec = {req: req, res: res};
                        if (_(req).has("principal")) {
                            rec.principal = req.principal;
                        }
                        if (_(req).has("client")) {
                            rec.client = req.client;
                        }
                        weblog.info(rec);
                    };
                    next();
                };
            };

        if (err) {
            log.error(err);
            callback(err, null);
            return;
        }

        if (useHTTPS) {
            log.info("Setting up HTTPS server.");
            app = express.createServer({key: fs.readFileSync(config.key),
                                        cert: fs.readFileSync(config.cert)});

            if (useBounce) {
                log.info("Setting up micro-HTTP server to bounce to HTTPS.");
                bounce = express.createServer(function(req, res, next) {
                    var host = req.header('Host');
                    res.redirect('https://'+host+req.url, 301);
                });
            }

        } else {
            log.info("Setting up HTTP server.");
            app = express.createServer();
        }

        app.config = config;

        if (config.smtpserver) {
            Mailer.setup(config, log);
        }

        var cleanup = config.cleanup || 600000;
        var dbstore = new DatabankStore(db, log, cleanup);

        if (!_(config).has("noweb") || !config.noweb) {
            app.session = express.session({secret: (_(config).has('sessionSecret')) ? config.sessionSecret : "insecure",
                                           store: dbstore});
        }

        // Configuration

        app.configure(function() {

            var serverVersion = 'pump.io/'+version + ' express/'+express.version + ' node.js/'+process.version,
                versionStamp = function(req, res, next) {
                    res.setHeader('Server', serverVersion);
                    next();
                },
                canonicalHost = function(req, res, next) {
                    var host = req.header('Host'),
                        urlHost = urlparse(URLMaker.makeURL("/")).host;
                    if (host && host.toLowerCase() != urlHost) {
                        res.redirect(URLMaker.makeURL(req.url), 301);
                    } else {
                        next();
                    }
                };

            // Templates are in public
            app.set("views", __dirname + "/../public/template");
            app.set("view engine", "utml");
            app.use(requestLogger(log));

            app.use(canonicalHost);

            app.use(rawBody);
            app.use(express.bodyParser());
            app.use(express.cookieParser());
            app.use(express.query());
            app.use(express.methodOverride());
            app.use(express.favicon());

            app.use(versionStamp);

            app.provider = new Provider(log);

            app.use(function(req, res, next) {
                res.local("config", config);
                res.local("data", {});
                res.local("page", {});
                res.local("template", {});
                // Initialize null
                res.local("principalUser", null);
                res.local("principal", null);
                res.local("user", null);
                res.local("client", null);
                res.local("nologin", false);
                res.local("version", version);
                res.local("messages", []);
                res.local("notifications", []);
                next();
            });

            app.use(auth([auth.Oauth({name: "client",
                                      realm: "OAuth",
                                      oauth_provider: app.provider,
                                      oauth_protocol: (useHTTPS) ? 'https' : 'http',
                                      authenticate_provider: null,
                                      authorize_provider: null,
                                      authorization_finished_provider: null
                                     }),
                          auth.Oauth({name: "user",
                                      realm: "OAuth",
                                      oauth_provider: app.provider,
                                      oauth_protocol: (useHTTPS) ? 'https' : 'http',
                                      authenticate_provider: oauth.authenticate,
                                      authorize_provider: oauth.authorize,
                                      authorization_finished_provider: oauth.authorizationFinished
                                     })
                         ]));

            app.use(express["static"](__dirname + "/../public"));

            app.use(app.router);

        });

        app.error(function(err, req, res, next) {
            log.error(err);
            if (err instanceof HTTPError) {
                if (req.xhr || req.originalUrl.substr(0, 5) === '/api/') {
                    res.json({error: err.message}, err.code);
                } else if (req.accepts("html")) {
                    res.status(err.code);
                    res.render("error", {page: {title: "Error"},
                                         error: err});
                } else {
                    res.writeHead(err.code, {"Content-Type": "text/plain"});
                    res.end(err.message);
                }
            } else {
                next(err);
            }
        });

        // Routes

        api.addRoutes(app);
        webfinger.addRoutes(app);
        clientreg.addRoutes(app);
        shared.addRoutes(app);

        if (_.has(config, "uploaddir")) {
            // Simple boolean flag
            config.canUpload = true;
            uploads.addRoutes(app);
        }

        if (config.requireEmail) {
            confirm.addRoutes(app);
        }

        // Use "noweb" to disable Web site (API engine only)

        if (!_(config).has("noweb") || !config.noweb) {
            web.addRoutes(app);
        } else {
            // A route to show the API doc at root
            app.get("/", function(req, res, next) {

                var Showdown = require("showdown"),
                    converter = new Showdown.converter();

                Step(
                    function() {
                        fs.readFile(path.join(__dirname, "..", "API.md"), this);
                    },
                    function (err, data) {
                        var html, markdown;
                        if (err) {
                            next(err);
                        } else {
                            markdown = data.toString();
                            html = converter.makeHtml(markdown);
                            res.render("doc", {page: {title: "API"},
                                               html: html});
                        }
                    }
                );
            });
        }

        DatabankObject.bank = db;

        URLMaker.hostname = hostname;
        URLMaker.port = (config.urlPort) ? config.urlPort : port;

        Distributor.log = log.child({component: "distributor"});

        if (_(config).has('serverUser')) {
            app.on('listening', function() {
                process.setuid(config.serverUser);
            });
        }

        if (config.sockjs) {
            pumpsocket.connect(app, log);
        }

        if (config.firehose) {
            log.info({firehose: config.firehose}, "Setting up firehose");
            Firehose.setup(config.firehose, log);
        }

        if (config.spamhost) {
            if (!config.spamclientid ||
                !config.spamclientsecret) {
                throw new Error("Need client ID and secret for spam host");
            }
            log.info({spamhost: config.spamhost}, "Configuring spam host");
            ActivitySpam.init({
                host: config.spamhost,
                clientID: config.spamclientid,
                clientSecret: config.spamclientsecret,
                logger: log
            });
        }

        dialbackClient = new DialbackClient({
            hostname: hostname,
            bank: db,
            app: app,
            url: "/api/dialback"
        });

        Credentials.dialbackClient = dialbackClient;

        app.run = function(callback) {
            var self = this,
                removeListeners = function() {
                    self.removeListener("listening", listenSuccessHandler);
                    self.removeListener("err", listenErrorHandler);
                },
                listenErrorHandler = function(err) {
                    removeListeners();
                    log.error(err);
                    callback(err);
                },
                listenSuccessHandler = function() {
                    var removeBounceListeners = function() {
                        bounce.removeListener("listening", bounceSuccess);
                        bounce.removeListener("err", bounceError);
                    },
                        bounceError = function(err) {
                            removeBounceListeners();
                            log.error(err);
                            callback(err);
                        },
                        bounceSuccess = function() {
                            log.info("Finished setting up bounce server.");
                            removeBounceListeners();
                            callback(null);
                        };

                    log.info("Finished setting up main server.");

                    removeListeners();
                    if (useBounce) {
                        bounce.on("error", bounceError);
                        bounce.on("listening", bounceSuccess);
                        bounce.listen(80, address);
                    } else {
                        callback(null);
                    }
                };
            this.on("error", listenErrorHandler);
            this.on("listening", listenSuccessHandler);
            log.info("Listening on "+port+" for host " + address);
            this.listen(port, address);
        };

        callback(null, app);
    });
};

exports.makeApp = makeApp;
<commit_msg>Include url in page object for locals by default<commit_after>// app.js
//
// main function for activity pump application
//
// Copyright 2011-2012, E14N https://e14n.com/
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

var urlparse = require("url").parse,
    auth = require("connect-auth"),
    Step = require("step"),
    databank = require("databank"),
    express = require("express"),
    _ = require("underscore"),
    fs = require("fs"),
    path = require("path"),
    Logger = require("bunyan"),
    uuid = require("node-uuid"),
    DialbackClient = require("dialback-client"),
    api = require("../routes/api"),
    web = require("../routes/web"),
    shared = require("../routes/shared"),
    webfinger = require("../routes/webfinger"),
    clientreg = require("../routes/clientreg"),
    oauth = require("../routes/oauth"),
    confirm = require("../routes/confirm"),
    uploads = require("../routes/uploads"),
    schema = require("./schema").schema,
    HTTPError = require("./httperror").HTTPError,
    Provider = require("./provider").Provider,
    URLMaker = require("./urlmaker").URLMaker,
    rawBody = require("./rawbody").rawBody,
    Distributor = require("./distributor"),
    pumpsocket = require("./pumpsocket"),
    Firehose = require("./firehose"),
    Mailer = require("./mailer"),
    version = require("./version").version,
    Credentials = require("./model/credentials").Credentials,
    ActivitySpam = require("./activityspam"),
    Databank = databank.Databank,
    DatabankObject = databank.DatabankObject,
    DatabankStore = require('connect-databank')(express);

var makeApp = function(config, callback) {

    var params,
        defaults = {port: 31337,
                    hostname: "127.0.0.1",
                    site: "pump.io",
                    sockjs: true,
                    debugClient: false,
                    firehose: "ofirehose.com",
                    requireEmail: false,
                    disableRegistration: false},
        port,
        hostname,
        address,
        log,
        db,
        logParams = {
            name: "pump.io",
            serializers: {
                req: Logger.stdSerializers.req,
                res: Logger.stdSerializers.res,
                principal: function(principal) {
                    if (principal) {
                        return {id: principal.id, type: principal.objectType};
                    } else {
                        return {id: "<none>"};
                    }
                },
                client: function(client) {
                    if (client) {
                        return {key: client.consumer_key, title: client.title || "<none>"};
                    } else {
                        return {key: "<none>", title: "<none>"};
                    }
                }
            }
        };

    // Fill in defaults if they're not there

    config = _.defaults(config, defaults);

    port     = config.port;
    hostname = config.hostname;
    address  = config.address || config.hostname;

    if (process.getuid) {
        if (port < 1024 && process.getuid() !== 0) {
            callback(new Error("Can't listen to ports lower than 1024 on POSIX systems unless you're root."), null);
            return;
        }
    }

    if (config.logfile) {
        logParams.streams = [{path: config.logfile}];
    } else if (config.nologger) {
        logParams.streams = [{path: "/dev/null"}];
    } else {
        logParams.streams = [{stream: process.stderr}];
    }

    log = new Logger(logParams);

    log.info("Initializing pump.io");

    // Initiate the DB

    if (_(config).has("params")) {
        params = config.params;
    } else {
        params = {};
    }

    if (_(params).has("schema")) {
        _.extend(params.schema, schema);
    } else {
        params.schema = schema;
    }

    db = Databank.get(config.driver, params);

    // Connect...

    log.info("Connecting to databank with driver '"+config.driver+"'");

    db.connect({}, function(err) {

        var useHTTPS = _(config).has('key'),
            useBounce = _(config).has('bounce') && config.bounce,
            app,
            io,
            bounce,
            dialbackClient,
            requestLogger = function(log) {
                return function(req, res, next) {
                    var weblog = log.child({"req_id": uuid.v4(), component: "web"});
                    var end = res.end;
                    req.log = weblog;
                    res.end = function(chunk, encoding) {
                        var rec;
                        res.end = end;
                        res.end(chunk, encoding);
                        rec = {req: req, res: res};
                        if (_(req).has("principal")) {
                            rec.principal = req.principal;
                        }
                        if (_(req).has("client")) {
                            rec.client = req.client;
                        }
                        weblog.info(rec);
                    };
                    next();
                };
            };

        if (err) {
            log.error(err);
            callback(err, null);
            return;
        }

        if (useHTTPS) {
            log.info("Setting up HTTPS server.");
            app = express.createServer({key: fs.readFileSync(config.key),
                                        cert: fs.readFileSync(config.cert)});

            if (useBounce) {
                log.info("Setting up micro-HTTP server to bounce to HTTPS.");
                bounce = express.createServer(function(req, res, next) {
                    var host = req.header('Host');
                    res.redirect('https://'+host+req.url, 301);
                });
            }

        } else {
            log.info("Setting up HTTP server.");
            app = express.createServer();
        }

        app.config = config;

        if (config.smtpserver) {
            Mailer.setup(config, log);
        }

        var cleanup = config.cleanup || 600000;
        var dbstore = new DatabankStore(db, log, cleanup);

        if (!_(config).has("noweb") || !config.noweb) {
            app.session = express.session({secret: (_(config).has('sessionSecret')) ? config.sessionSecret : "insecure",
                                           store: dbstore});
        }

        // Configuration

        app.configure(function() {

            var serverVersion = 'pump.io/'+version + ' express/'+express.version + ' node.js/'+process.version,
                versionStamp = function(req, res, next) {
                    res.setHeader('Server', serverVersion);
                    next();
                },
                canonicalHost = function(req, res, next) {
                    var host = req.header('Host'),
                        urlHost = urlparse(URLMaker.makeURL("/")).host;
                    if (host && host.toLowerCase() != urlHost) {
                        res.redirect(URLMaker.makeURL(req.url), 301);
                    } else {
                        next();
                    }
                };

            // Templates are in public
            app.set("views", __dirname + "/../public/template");
            app.set("view engine", "utml");
            app.use(requestLogger(log));

            app.use(canonicalHost);

            app.use(rawBody);
            app.use(express.bodyParser());
            app.use(express.cookieParser());
            app.use(express.query());
            app.use(express.methodOverride());
            app.use(express.favicon());

            app.use(versionStamp);

            app.provider = new Provider(log);

            app.use(function(req, res, next) {
                res.local("config", config);
                res.local("data", {});
                res.local("page", {url: req.originalUrl});
                res.local("template", {});
                // Initialize null
                res.local("principalUser", null);
                res.local("principal", null);
                res.local("user", null);
                res.local("client", null);
                res.local("nologin", false);
                res.local("version", version);
                res.local("messages", []);
                res.local("notifications", []);
                next();
            });

            app.use(auth([auth.Oauth({name: "client",
                                      realm: "OAuth",
                                      oauth_provider: app.provider,
                                      oauth_protocol: (useHTTPS) ? 'https' : 'http',
                                      authenticate_provider: null,
                                      authorize_provider: null,
                                      authorization_finished_provider: null
                                     }),
                          auth.Oauth({name: "user",
                                      realm: "OAuth",
                                      oauth_provider: app.provider,
                                      oauth_protocol: (useHTTPS) ? 'https' : 'http',
                                      authenticate_provider: oauth.authenticate,
                                      authorize_provider: oauth.authorize,
                                      authorization_finished_provider: oauth.authorizationFinished
                                     })
                         ]));

            app.use(express["static"](__dirname + "/../public"));

            app.use(app.router);

        });

        app.error(function(err, req, res, next) {
            log.error(err);
            if (err instanceof HTTPError) {
                if (req.xhr || req.originalUrl.substr(0, 5) === '/api/') {
                    res.json({error: err.message}, err.code);
                } else if (req.accepts("html")) {
                    res.status(err.code);
                    res.render("error", {page: {title: "Error"},
                                         error: err});
                } else {
                    res.writeHead(err.code, {"Content-Type": "text/plain"});
                    res.end(err.message);
                }
            } else {
                next(err);
            }
        });

        // Routes

        api.addRoutes(app);
        webfinger.addRoutes(app);
        clientreg.addRoutes(app);
        shared.addRoutes(app);

        if (_.has(config, "uploaddir")) {
            // Simple boolean flag
            config.canUpload = true;
            uploads.addRoutes(app);
        }

        if (config.requireEmail) {
            confirm.addRoutes(app);
        }

        // Use "noweb" to disable Web site (API engine only)

        if (!_(config).has("noweb") || !config.noweb) {
            web.addRoutes(app);
        } else {
            // A route to show the API doc at root
            app.get("/", function(req, res, next) {

                var Showdown = require("showdown"),
                    converter = new Showdown.converter();

                Step(
                    function() {
                        fs.readFile(path.join(__dirname, "..", "API.md"), this);
                    },
                    function (err, data) {
                        var html, markdown;
                        if (err) {
                            next(err);
                        } else {
                            markdown = data.toString();
                            html = converter.makeHtml(markdown);
                            res.render("doc", {page: {title: "API"},
                                               html: html});
                        }
                    }
                );
            });
        }

        DatabankObject.bank = db;

        URLMaker.hostname = hostname;
        URLMaker.port = (config.urlPort) ? config.urlPort : port;

        Distributor.log = log.child({component: "distributor"});

        if (_(config).has('serverUser')) {
            app.on('listening', function() {
                process.setuid(config.serverUser);
            });
        }

        if (config.sockjs) {
            pumpsocket.connect(app, log);
        }

        if (config.firehose) {
            log.info({firehose: config.firehose}, "Setting up firehose");
            Firehose.setup(config.firehose, log);
        }

        if (config.spamhost) {
            if (!config.spamclientid ||
                !config.spamclientsecret) {
                throw new Error("Need client ID and secret for spam host");
            }
            log.info({spamhost: config.spamhost}, "Configuring spam host");
            ActivitySpam.init({
                host: config.spamhost,
                clientID: config.spamclientid,
                clientSecret: config.spamclientsecret,
                logger: log
            });
        }

        dialbackClient = new DialbackClient({
            hostname: hostname,
            bank: db,
            app: app,
            url: "/api/dialback"
        });

        Credentials.dialbackClient = dialbackClient;

        app.run = function(callback) {
            var self = this,
                removeListeners = function() {
                    self.removeListener("listening", listenSuccessHandler);
                    self.removeListener("err", listenErrorHandler);
                },
                listenErrorHandler = function(err) {
                    removeListeners();
                    log.error(err);
                    callback(err);
                },
                listenSuccessHandler = function() {
                    var removeBounceListeners = function() {
                        bounce.removeListener("listening", bounceSuccess);
                        bounce.removeListener("err", bounceError);
                    },
                        bounceError = function(err) {
                            removeBounceListeners();
                            log.error(err);
                            callback(err);
                        },
                        bounceSuccess = function() {
                            log.info("Finished setting up bounce server.");
                            removeBounceListeners();
                            callback(null);
                        };

                    log.info("Finished setting up main server.");

                    removeListeners();
                    if (useBounce) {
                        bounce.on("error", bounceError);
                        bounce.on("listening", bounceSuccess);
                        bounce.listen(80, address);
                    } else {
                        callback(null);
                    }
                };
            this.on("error", listenErrorHandler);
            this.on("listening", listenSuccessHandler);
            log.info("Listening on "+port+" for host " + address);
            this.listen(port, address);
        };

        callback(null, app);
    });
};

exports.makeApp = makeApp;
<|endoftext|>


<commit_before>/*
 *	create.init.js,一个基于createjs游戏框架初始化插件
 *	https://github.com/coderray/createjs.init.js
 * 	296773006@qq.com | Ray
 * 	2016.10.13
 */
var initCjs = (function(w,cjs){
	var def = {
		"scaleMode":"exactFit",//适配模式:exactFit | fixedWidth | noScale | showAll
		"frameRate":60,
		"autoRender":true,
		"autoLoad":true,
		"loadType":0,//0代表div显示加载，1代表使用canvas绘制loading
		"useSound":true,//是否使用soundjs
		"width":640,//设计图宽高
		"height":1014,
		"url":"images/",
		"debug":false,
		"id":'',
		"preload":[],
		"bgColor":"#fff",
		"callback":false,
		'onProgress':false,
		'onComplete':false
	}
	var stage,
		canvas,
		W = window,
		D = document,
		SCREEN_W = W.innerWidth,
		SCREEN_H = W.innerHeight,
		DPR = W.devicePixelRatio || 1,
		CANS_W = SCREEN_W*DPR,
		CANS_H = SCREEN_H*DPR,
		SCALE_X = 1,
		SCALE_Y = 1;
	function init(opts){
		//重设参数
		if(typeof opts == 'object'){
			for(var key in opts){
				def[key] = opts[key];
			}
		}
		//拼接完整资源路径
		def.preload.map(function(item,index){
			if(typeof item == 'object'){
				def.preload[index].src = def.url + item.src;
			}else{
				def.preload[index] = def.url + item;
			}
		});
		//创建舞台和设定样式
		if(!def.id){
			var div = D.createElement("div"),
				body = D.getElementsByTagName("body")[0],
				head = D.getElementsByTagName("head")[0],
				style = D.createElement("style");
			style.innerHTML = "html,body{height:100%}.canvas-wrap{position:relative;width:100%;height:100%;left:0;top:0;}.canvas-wrap canvas{width:100%;height:100%;}";
			div.className = "canvas-wrap";
			canvas = D.createElement("canvas");
			canvas.id = "canvas";
			head.appendChild(style);
			div.appendChild(canvas);
			body.appendChild(div);
		}else{
			if(!D.getElementById(def.id)){
				console.warn("id指定错误,请确认id值是否正确。");
				return false;
			}else{
				canvas = D.getElementById(def.id);
				canvas.setAttribute("style","width: 100%;height: 100%;");
			}
		}
		//适配模式
		canvas.width = CANS_W;
		canvas.height = CANS_H;
		stage = new cjs.Stage(canvas);
		this.stage = stage;
		this.width = def.width;
		this.height = def.height;
		SCALE_X = CANS_W/def.width;
		SCALE_Y = CANS_H/def.height;
		var _scaleX = SCALE_X,
			_scaleY = SCALE_Y;
		switch (def.scaleMode){
			case 'fixedWidth':
				_scaleY = SCALE_X;
				break;
			case 'showAll':
				if(def.width/def.height > SCREEN_W/SCREEN_H){
					_scaleX = SCALE_Y;
				}else{
					_scaleY = SCALE_X;
				}
				break;
			case 'exactFit':
			default:
				break;
		}
		stage.scaleX = _scaleX;
		stage.scaleY = _scaleY;
		//渲染帧率
		function _autoRun(){
			stage.update();
		}
		cjs.Ticker.timingMode = cjs.Ticker.RAF;
		cjs.Ticker.framerate = def.frameRate;
		this.startTick = function(){
			cjs.Ticker.addEventListener('tick',_autoRun);
		}
		this.stopTick = function(){
			cjs.Ticker.removeEventListener('tick',_autoRun);
		}
		//是否自动渲染
		if(def.autoRender){
			this.startTick();
		}
		//加载队列
		var queue = new cjs.LoadQueue();
		this.loader = queue;
		//是否使用soundjs
		if(def.useSound){
			queue.installPlugin(cjs.Sound);
		}
		//资源加载
		this.loading = function(){
			queue.on("progress", function(){
				(def.onProgress && typeof def.onProgress == 'function') && def.onProgress(queue.progress);
			},this);
			queue.on("complete", function(){
				(def.onComplete && typeof def.onComplete == 'function') && def.onComplete(queue.progress);
				return true;
			},this);
			queue.loadManifest(def.preload);
		}
		//是否自动加载
		if(def.autoLoad){
			this.loading();
		}
	}
	return init;
})(window,createjs);<commit_msg>修改加载soundjs配置<commit_after>//init
var initCjs = (function(w,cjs){
	var def = {
		"scaleMode":"exactFit",//适配模式:exactFit | fixedWidth | noScale | showAll
		"frameRate":60,
		"autoRender":true,
		"autoLoad":true,
		"useLoad":true,
		"loadType":0,//0代表div显示加载，1代表使用canvas绘制loading
		"useSound":true,//是否使用soundjs
		"width":640,//设计图宽高
		"height":1014,
		"url":"images/",
		"debug":false,
		"id":'',
		"preload":[],
		"bgColor":"#fff",
		"callback":false,
		'onProgress':false,
		'onComplete':false
	}
	var stage,
		canvas,
		W = window,
		D = document,
		SCREEN_W = W.innerWidth,
		SCREEN_H = W.innerHeight,
		DPR = W.devicePixelRatio || 1,
		CANS_W = SCREEN_W*DPR,
		CANS_H = SCREEN_H*DPR,
		SCALE_X = 1,
		SCALE_Y = 1;
	function init(opts){
		//重设参数
		if(typeof opts == 'object'){
			for(var key in opts){
				def[key] = opts[key];
			}
		}
		//拼接完整资源路径
		def.preload.map(function(item,index){
			if(typeof item == 'object'){
				def.preload[index].src = def.url + item.src;
			}else{
				def.preload[index] = def.url + item;
			}
		});
		//创建舞台和设定样式
		if(!def.id){
			var div = D.createElement("div"),
				body = D.getElementsByTagName("body")[0],
				head = D.getElementsByTagName("head")[0],
				style = D.createElement("style");
			style.innerHTML = "html,body{height:100%}.canvas-wrap{position:relative;width:100%;height:100%;left:0;top:0;}.canvas-wrap canvas{width:100%;height:100%;}";
			div.className = "canvas-wrap";
			canvas = D.createElement("canvas");
			canvas.id = "canvas";
			head.appendChild(style);
			div.appendChild(canvas);
			body.appendChild(div);
		}else{
			if(!D.getElementById(def.id)){
				console.warn("id指定错误,请确认id值是否正确。");
				return false;
			}else{
				canvas = D.getElementById(def.id);
				canvas.setAttribute("style","width: 100%;height: 100%;");
			}
		}
		//适配模式
		canvas.width = CANS_W;
		canvas.height = CANS_H;
		stage = new cjs.Stage(canvas);
		this.stage = stage;
		this.width = def.width;
		this.height = def.height;
		SCALE_X = CANS_W/def.width;
		SCALE_Y = CANS_H/def.height;
		this.scaleX = SCALE_X;
		this.scaleY = SCALE_Y;
		var _scaleX = SCALE_X,
			_scaleY = SCALE_Y;
		switch (def.scaleMode){
			case 'fixedWidth':
				_scaleY = SCALE_X;
				break;
			case 'showAll':
				if(def.width/def.height > SCREEN_W/SCREEN_H){
					_scaleX = SCALE_Y;
				}else{
					_scaleY = SCALE_X;
				}
				break;
			case 'exactFit':
			default:
				break;
		}
		stage.scaleX = _scaleX;
		stage.scaleY = _scaleY;
		//渲染帧率
		function _autoRun(){
			stage.update();
		}
		cjs.Ticker.timingMode = cjs.Ticker.RAF;
		cjs.Ticker.framerate = def.frameRate;
		this.startTick = function(){
			cjs.Ticker.addEventListener('tick',_autoRun);
		}
		this.stopTick = function(){
			cjs.Ticker.removeEventListener('tick',_autoRun);
		}
		//是否自动渲染
		if(def.autoRender){
			this.startTick();
		}
		//加载队列
		if(def.useLoad){
			var queue = new cjs.LoadQueue();
			this.loader = queue;
			//是否加载soundjs
			if(def.useSound){
				queue.installPlugin(cjs.Sound);
			}
		}
		//资源加载
		this.loading = function(){
			if(def.useLoad){
				queue.on("progress", function(){
					(def.onProgress && typeof def.onProgress == 'function') && def.onProgress(queue.progress);
				},this);
				queue.on("complete", function(){
					(def.onComplete && typeof def.onComplete == 'function') && def.onComplete(queue.progress);
					return true;
				},this);
				queue.loadManifest(def.preload);
			}
		}
		//是否自动加载
		if(def.autoLoad){
			this.loading();
		}
	}
	return init;
})(window,createjs);<|endoftext|>


<commit_before>'use strict';

var mbaasApi = require('fh-mbaas-api')
  , express = require('express')
  , app = express()
  , mbaasExpress = mbaasApi.mbaasExpress()
  , config = require('./config')
  , cors = require('cors')
  , mediator = require('fh-wfm-mediator/lib/mediator')
  , bodyParser = require('body-parser')
  ;

require('fh-wfm-appform/lib/server')(mbaasApi);

var authServiceGuid = process.env.WFM_AUTH_GUID;
var securableEndpoints = [];

app.set('port', config.get('PORT'));
app.set('base url', config.get('IP'));

// Enable CORS for all requests
app.use(cors());

// Note: the order which we add middleware to Express here is important!
app.use('/sys', mbaasExpress.sys(securableEndpoints));
// Note: important that this is added just before your own Routes
app.use(mbaasExpress.fhmiddleware());

//Ensuring that any requests to the endpoints must have valid sessions
//Otherwise, the requests will be rejected.
app.use(require('fh-wfm-user/lib/middleware/validateSession')(mediator, mbaasApi, ['/authpolicy']));
app.use('/mbaas', mbaasExpress.mbaas);

// fhlint-begin: custom-routes

// app specific router
var router = express.Router();

app.use('/sys/info/ping', function(req, res) {
  res.send('ok.');
});
app.use('/api', bodyParser.json({limit: '10mb'}));
app.use('/box', bodyParser.json());
app.use('/api', router);
app.post('/cloud/:datasetId', function(req, res) {
  res.send('ok');
});
app.use(require('fh-wfm-user/lib/middleware/validateSession')(mediator, mbaasApi, ['/authpolicy']));

// setup the wfm sync & routes
require('fh-wfm-file/lib/router')(mediator, app);
require('fh-wfm-message/lib/server')(mediator, app, mbaasApi);
require('fh-wfm-result/lib/server')(mediator, app, mbaasApi);
require('fh-wfm-user/lib/router/cloud')(mediator, app, authServiceGuid);
require('fh-wfm-workflow/lib/server')(mediator, app, mbaasApi);
require('fh-wfm-workorder/lib/server')(mediator, app, mbaasApi);

// app modules
require('./app/message')(mediator);
require('./app/workorder')(mediator);
require('./app/result')(mediator);
require('./app/workflow')(mediator);
require('./app/group')(mediator);
require('./app/file')(mediator);

// fhlint-end

// Important that this is last!
app.use(mbaasExpress.errorHandler());

module.exports = exports = app;
<commit_msg>Added session authentication to sync<commit_after>'use strict';

var mbaasApi = require('fh-mbaas-api')
  , express = require('express')
  , app = express()
  , mbaasExpress = mbaasApi.mbaasExpress()
  , config = require('./config')
  , cors = require('cors')
  , mediator = require('fh-wfm-mediator/lib/mediator')
  , bodyParser = require('body-parser')
  ;

require('fh-wfm-appform/lib/server')(mbaasApi);

var authServiceGuid = process.env.WFM_AUTH_GUID;
var securableEndpoints = [];

app.set('port', config.get('PORT'));
app.set('base url', config.get('IP'));

// Enable CORS for all requests
app.use(cors());

// Note: the order which we add middleware to Express here is important!
app.use('/sys', mbaasExpress.sys(securableEndpoints));
// Note: important that this is added just before your own Routes
app.use(mbaasExpress.fhmiddleware());

//Ensuring that any requests to the endpoints must have valid sessions
//Otherwise, the requests will be rejected.
app.use('/mbaas/sync', bodyParser.json({limit: '10mb'}), require('fh-wfm-user/lib/middleware/validateSession')(mediator, mbaasApi, ['/authpolicy']));

app.use('/mbaas', mbaasExpress.mbaas);

// fhlint-begin: custom-routes

// app specific router
var router = express.Router();

app.use('/sys/info/ping', function(req, res) {
  res.send('ok.');
});
app.use('/api', bodyParser.json({limit: '10mb'}));
app.use('/box', bodyParser.json());
app.use('/api', router);
app.post('/cloud/:datasetId', function(req, res) {
  res.send('ok');
});
app.use(require('fh-wfm-user/lib/middleware/validateSession')(mediator, mbaasApi, ['/authpolicy']));

// setup the wfm sync & routes
require('fh-wfm-file/lib/router')(mediator, app);
require('fh-wfm-message/lib/server')(mediator, app, mbaasApi);
require('fh-wfm-result/lib/server')(mediator, app, mbaasApi);
require('fh-wfm-user/lib/router/cloud')(mediator, app, authServiceGuid);
require('fh-wfm-workflow/lib/server')(mediator, app, mbaasApi);
require('fh-wfm-workorder/lib/server')(mediator, app, mbaasApi);

// app modules
require('./app/message')(mediator);
require('./app/workorder')(mediator);
require('./app/result')(mediator);
require('./app/workflow')(mediator);
require('./app/group')(mediator);
require('./app/file')(mediator);

// fhlint-end

// Important that this is last!
app.use(mbaasExpress.errorHandler());

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


<commit_before>$(function() {
	var today = new Date();

	$("#data").datepicker({
		dateFormat: "dd/mm/yy",
		minDate: validaMinDate(),
		maxDate: today
	});

	$('#lancarDiario').click(function(){
		var form = $('#data-form');

		if ($('select[name="fal_quantidade_aulas"]').val() != '')
       		submitAjax(form);
       	else
       		alert('showMsgQtdAulas');
	})

	$('#buscarAlunos').click(function(){
		removeValoresEditar();

		$(".alert-success, .alert-danger").addClass('hide');
		if(validaFormDiario()){
			$('#lancarDiario').removeAttr('disabled');
			buscarAlunos();
			validaDiarioEditar();
		}
	})

	$('#data').change(function(){
		$('#auxLancamentos').html('');
		validaDiaLetivo($(this).val());
	})

	buscarTurmas();

	$('select[name="tur_id"]').on('change', function(){
		$('#auxLancamentos').html('');
		buscarDisciplinaPorTurmaProfessor($(this).val());
	})

	$('select[name="dis_id"]').on('change', function(){
		$('#auxLancamentos').html('');
	})
});

function submitAjax(form){
	$.ajax({
		data: form.serialize(),
		url: '../diario/salvar',
		type: 'POST',
		dataType: 'json',
		async: false,
		success: function(r){
			if(r == 'editado')
				$(".alert-success.editado").removeClass('hide');
			else if (r)
				$(".alert-success.inserido").removeClass('hide');
			else
				$(".alert-danger").removeClass('hide');

			$('#auxLancamentos').html('');
		}
	})
}

function buscarAlunos(){
	var turma = $('select[name="tur_id"]').val();

	$.ajax({
		data: 'tur_id='+turma,
		url: '../turma/buscarTurma',
		type: 'POST',
		dataType: 'json',
		async: false,
		success: function(r){
			if(r){
				preencheAlunos(r);
			}
		}
	})
}

function preencheAlunos(dados){
	var cont = dados.alunos.length;
	var alunos = '';
	var faltas = '';
	var mtop = '';
	var aniversario = '';
	var year = $('#data').val().substr(6, 4);
	var dia = $('#data').val().substr(0, 2);
	var mes = $('#data').val().substr(3, 2);
	var dataPrincipal = new Date(year, mes - 1, dia);
	var auxSunday = dataPrincipal.getDate() - dataPrincipal.getDay();
	var dataAluno = '';
	auxSunday = dataPrincipal.getDay() == 0 ? auxSunday - 6 : auxSunday + 1;

	var lastSunday = new Date(dataPrincipal.setDate(auxSunday));
	var nextMonday = new Date(dataPrincipal.setDate(auxSunday + 6));

	for(var i = 0; i < cont; i++){
		mtop = (i > 0) ? ' style="margin-top: 5px" ' : '';

		alunos += '<input disabled="disabled" class="form-control" value="'+ dados.alunos[i].alu_nome +'" '+ mtop +'>';

		faltas += '<input class="form-control" maxlength="2" name="faltas['+ dados.alunos[i].alu_id +']" value="0" '+ mtop +'>';

		dataAluno = new Date(dados.alunos[i].alu_data_nascimento + ' 00:00:00');
		dataAluno = new Date(dataAluno.setFullYear(year));

		var auxData = dados.alunos[i].alu_data_nascimento.split('-');
		var data = auxData[2] + '/' + auxData[1];
		var icon = '';
		var pull = '';

		var first = i == 0 ? 'first' : '';
		if(dataAluno >= lastSunday && dataAluno <= nextMonday){
			icon = '';
			pull = ' pull-left ';
		}

		aniversario += '
<input disabled="disabled" class="form-control '+ pull +' input-mini" value="'+ data +'" '+ mtop +'>';

		aniversario += icon + '
';
	}

	var html = '
'+
                    'Conteúdo: '+
                    '<textarea class="form-control" name="conteudo" rows="3" style="resize: none"></textarea>'+
                '
'+
                '

'+
                '
'+
                    'Tarefa/Casa: '+
                    '<textarea class="form-control" name="tarefa" rows="2" style="resize: none"></textarea>'+
                '
'+
                '

'+
                '
'+
                    'Observações: '+
                    '<textarea class="form-control" name="observacao" rows="2" style="resize: none"></textarea>'+
                '
'+
                '

'+
                '

'+
                ''+
                '
'+
                ''+
				'Aniversariantes da Semana'+
				'
'+
                '
'+
                    'Aluno: '+
                    alunos+
                '
'+
                '
'+
                    'Faltas: '+
                    faltas+
                '
'+
                '
'+
                	'Aniversário: '+
                    aniversario+
                '
'+
                '

'+
                '
'+
                	'Quantidade de Aulas * '+
                	'<select data-required="true" class="form-control" name="fal_quantidade_aulas">'+
                		'<option value="">Selecione</option>'+
                		'<option value="1">1</option>'+
                		'<option value="2">2</option>'+
                		'<option value="3">3</option>'+
                	'</select>'+
                '
';

    $('#auxLancamentos').html(html);
}

function validaFormDiario(){
	var retorno = true;

	$('.form-group input, .form-group select').css('border-color', '#ccc');

	$('input[data-required="true"], select[data-required="true"]').each(function(){
		if ($(this).val() == ''){
			$(this).css('border-color', '#a94442');
			retorno = false;
		}
	})

	return retorno;
}

function validaDiaLetivo(dia_letivo){
	var tur_id = $('select[name="tur_id"]').val();

	if (tur_id){
		$.ajax({
			data: 'dia_letivo='+dia_letivo+'&tur_id='+tur_id,
			url: '../dia_letivo/buscarDiaLetivo',
			type: 'POST',
			dataType: 'json',
			async: false,
			success: function(r){
				if (r.length < 1){
					$('#data').val('');
					alert('A data selecionada não é um dia letivo.');
				}
			}
		})
	} else {
		alert('Selecione uma turma antes de selcionar uma data');
		$('#data').val('');
	}
}

function validaMinDate(){
	var perfil = $('input[name="per"]').val();
	var minDate = new Date(new Date().getFullYear(), 0, 1);

	//if (perfil == 4){
	if (4==5){
		var today = new Date();
		var first = today.getDate() - today.getDay();
		first = today.getDay() == 0 ? first - 6 : first + 1;

		minDate = new Date(today.setDate(first));
	}

	return minDate;
}

function buscarTurmas(){
	$.ajax({
		url: '../turma/buscarTurmaPerfil',
		type: 'POST',
		dataType: 'json',
		async: false,
		success: function(r){
			if (r){
				var html = '<option value="">Selecione</option>';
				var cont = r.length;

				for(var i = 0; i < cont; i++){
					html += "<option value='"+ r[i].tur_id +"'>"+ r[i].tur_nome +" "+ r[i].tur_ano +"</option>";
				}

				$('select[name="tur_id"]').html(html);
			}
		}
	})
}

function buscarDisciplinaPorTurmaProfessor(tur_id){
	$('#data').val('');

	if(tur_id){
		$.ajax({
			data: 'tur_id='+tur_id,
			url: '../disciplina/buscarDisciplinaPorTurmaProfessor',
			type: 'POST',
			dataType: 'json',
			async: false,
			success: function(r){
				if (r){
					var html = '<option value="">Selecione</option>';
					var cont = r.length;

					for(var i = 0; i < cont; i++){
						html += "<option value='"+ r[i].dis_id +"'>"+ r[i].dis_nome +"</option>";
					}

					$('select[name="dis_id"]').html(html);
				}
			}
		})
	}
}

function validaDiarioEditar(){

	var tur_id = $('select[name="tur_id"]').val();
	var dis_id = $('select[name="dis_id"]').val();
	var dia = $('input[name="dia_letivo"]').val();
	var perfil = $('input[name="per"]').val();

	$.ajax({
		data: 'tur_id='+tur_id+'&dis_id='+dis_id+'&dia='+dia,
		url: '../diario/buscarDiario',
		type: 'POST',
		dataType: 'json',
		async: false,
		success: function(r){
			if (r && r.conteudo){
				preencheCamposEditar(r);
				if(perfil == 4)
					removeValoresEditar();
			}
		}
	})
}

function preencheCamposEditar(dados){
	var cont = dados.faltas.length;
	var faltas = '';

	$('textarea[name="conteudo"]').val(dados.conteudo.con_conteudo);
	$('input[name="con_id"]').val(dados.conteudo.con_id);

	$('textarea[name="observacao"]').val(dados.observacao.obs_observacao);
	$('input[name="obs_id"]').val(dados.observacao.obs_id);

	$('textarea[name="tarefa"]').val(dados.tarefa.tar_tarefa);
	$('input[name="tar_id"]').val(dados.tarefa.tar_id);

	for(var i = 0; i < cont; i++){
		$('input[name="faltas['+ dados.faltas[i].alu_id +']"]').val(dados.faltas[i].fal_falta);
		faltas = $('input[name="atds_id"]').val();
		$('input[name="atds_id"]').val(dados.faltas[i].fal_id + '/' + dados.faltas[i].alu_id + '@' + faltas);
	}
}

function removeValoresEditar(){
	$('input[name="con_id"], input[name="atds_id"], input[name="obs_id"], input[name="tar_id"]').val('');
	$('#lancarDiario').attr('disabled', 'disabled');
}<commit_msg>correcao diario script2<commit_after>$(function() {
	var today = new Date();

	$("#data").datepicker({
		dateFormat: "dd/mm/yy",
		minDate: validaMinDate(),
		maxDate: today
	});

	$('#lancarDiario').click(function(){
		var form = $('#data-form');

		if ($('select[name="fal_quantidade_aulas"]').val() != '')
       		submitAjax(form);
       	else
       		alert('showMsgQtdAulas');
	})

	$('#buscarAlunos').click(function(){
		removeValoresEditar();

		$(".alert-success, .alert-danger").addClass('hide');
		if(validaFormDiario()){
			$('#lancarDiario').removeAttr('disabled');
			buscarAlunos();
			validaDiarioEditar();
		}
	})

	$('#data').change(function(){
		$('#auxLancamentos').html('');
		validaDiaLetivo($(this).val());
	})

	buscarTurmas();

	$('select[name="tur_id"]').on('change', function(){
		$('#auxLancamentos').html('');
		buscarDisciplinaPorTurmaProfessor($(this).val());
	})

	$('select[name="dis_id"]').on('change', function(){
		$('#auxLancamentos').html('');
	})
});

function submitAjax(form){
	$.ajax({
		data: form.serialize(),
		url: '../diario/salvar',
		type: 'POST',
		dataType: 'json',
		async: false,
		success: function(r){
			if(r == 'editado')
				$(".alert-success.editado").removeClass('hide');
			else if (r)
				$(".alert-success.inserido").removeClass('hide');
			else
				$(".alert-danger").removeClass('hide');

			$('#auxLancamentos').html('');
		}
	})
}

function buscarAlunos(){
	var turma = $('select[name="tur_id"]').val();

	$.ajax({
		data: 'tur_id='+turma,
		url: '../turma/buscarTurma',
		type: 'POST',
		dataType: 'json',
		async: false,
		success: function(r){
			if(r){
				preencheAlunos(r);
			}
		}
	})
}

function preencheAlunos(dados){
	var cont = dados.alunos.length;
	var alunos = '';
	var faltas = '';
	var mtop = '';
	var aniversario = '';
	var year = $('#data').val().substr(6, 4);
	var dia = $('#data').val().substr(0, 2);
	var mes = $('#data').val().substr(3, 2);
	var dataPrincipal = new Date(year, mes - 1, dia);
	var auxSunday = dataPrincipal.getDate() - dataPrincipal.getDay();
	var dataAluno = '';
	auxSunday = dataPrincipal.getDay() == 0 ? auxSunday - 6 : auxSunday + 1;

	var lastSunday = new Date(dataPrincipal.setDate(auxSunday));
	var nextMonday = new Date(dataPrincipal.setDate(auxSunday + 6));

	for(var i = 0; i < cont; i++){
		mtop = (i > 0) ? ' style="margin-top: 5px" ' : '';

		alunos += '<input disabled="disabled" class="form-control" value="'+ dados.alunos[i].alu_nome +'" '+ mtop +'>';

		faltas += '<input class="form-control" maxlength="2" name="faltas['+ dados.alunos[i].alu_id +']" value="0" '+ mtop +'>';

		dataAluno = new Date(dados.alunos[i].alu_data_nascimento + ' 00:00:00');
		dataAluno = new Date(dataAluno.setFullYear(year));

		var auxData = dados.alunos[i].alu_data_nascimento.split('-');
		var data = auxData[2] + '/' + auxData[1];
		var icon = '';
		var pull = '';

		var first = i == 0 ? 'first' : '';
		if(dataAluno >= lastSunday && dataAluno <= nextMonday){
			icon = '';
			pull = ' pull-left ';
		}

		aniversario += '
<input disabled="disabled" class="form-control '+ pull +' input-mini" value="'+ data +'" '+ mtop +'>';

		aniversario += icon + '
';
	}

	var html = '
'+
                    'Conteúdo: '+
                    '<textarea class="form-control" name="conteudo" rows="3" style="resize: none"></textarea>'+
                '
'+
                '

'+
                '
'+
                    'Tarefa/Casa: '+
                    '<textarea class="form-control" name="tarefa" rows="2" style="resize: none"></textarea>'+
                '
'+
                '

'+
                '
'+
                    'Observações: '+
                    '<textarea class="form-control" name="observacao" rows="2" style="resize: none"></textarea>'+
                '
'+
                '

'+
                '

'+
                ''+
                '
'+
                ''+
				'Aniversariantes da Semana'+
				'
'+
                '
'+
                    'Aluno: '+
                    alunos+
                '
'+
                '
'+
                    'Faltas: '+
                    faltas+
                '
'+
                '
'+
                	'Aniversário: '+
                    aniversario+
                '
'+
                '

'+
                '
'+
                	'Quantidade de Aulas * '+
                	'<select data-required="true" class="form-control" name="fal_quantidade_aulas">'+
                		'<option value="">Selecione</option>'+
                		'<option value="1">1</option>'+
                		'<option value="2">2</option>'+
                		'<option value="3">3</option>'+
                	'</select>'+
                '
';

    $('#auxLancamentos').html(html);
}

function validaFormDiario(){
	var retorno = true;

	$('.form-group input, .form-group select').css('border-color', '#ccc');

	$('input[data-required="true"], select[data-required="true"]').each(function(){
		if ($(this).val() == ''){
			$(this).css('border-color', '#a94442');
			retorno = false;
		}
	})

	return retorno;
}

function validaDiaLetivo(dia_letivo){
	var tur_id = $('select[name="tur_id"]').val();

	if (tur_id){
		$.ajax({
			data: 'dia_letivo='+dia_letivo+'&tur_id='+tur_id,
			url: '../dia_letivo/buscarDiaLetivo',
			type: 'POST',
			dataType: 'json',
			async: false,
			success: function(r){
				if (r.length < 1){
					$('#data').val('');
					alert('A data selecionada não é um dia letivo.');
				}
			}
		})
	} else {
		alert('Selecione uma turma antes de selcionar uma data');
		$('#data').val('');
	}
}

function validaMinDate(){
	var perfil = $('input[name="per"]').val();
	var minDate = new Date(new Date().getFullYear(), 0, 1);

	//if (perfil == 4){
	if (4==5){
		var today = new Date();
		var first = today.getDate() - today.getDay();
		first = today.getDay() == 0 ? first - 6 : first + 1;

		minDate = new Date(today.setDate(first));
	}

	return minDate;
}

function buscarTurmas(){
	$.ajax({
		url: '../turma/buscarTurmaPerfil',
		type: 'POST',
		dataType: 'json',
		async: false,
		success: function(r){
			if (r){
				var html = '<option value="">Selecione</option>';
				var cont = r.length;

				for(var i = 0; i < cont; i++){
					html += "<option value='"+ r[i].tur_id +"'>"+ r[i].tur_nome +" "+ r[i].tur_ano +"</option>";
				}

				$('select[name="tur_id"]').html(html);
			}
		}
	})
}

function buscarDisciplinaPorTurmaProfessor(tur_id){
	$('#data').val('');

	if(tur_id){
		$.ajax({
			data: 'tur_id='+tur_id,
			url: '../disciplina/buscarDisciplinaPorTurmaProfessor',
			type: 'POST',
			dataType: 'json',
			async: false,
			success: function(r){
				if (r){
					var html = '<option value="">Selecione</option>';
					var cont = r.length;

					for(var i = 0; i < cont; i++){
						html += "<option value='"+ r[i].dis_id +"'>"+ r[i].dis_nome +"</option>";
					}

					$('select[name="dis_id"]').html(html);
				}
			}
		})
	}
}

function validaDiarioEditar(){

	var tur_id = $('select[name="tur_id"]').val();
	var dis_id = $('select[name="dis_id"]').val();
	var dia = $('input[name="dia_letivo"]').val();
	var perfil = $('input[name="per"]').val();

	$.ajax({
		data: 'tur_id='+tur_id+'&dis_id='+dis_id+'&dia='+dia,
		url: '../diario/buscarDiario',
		type: 'POST',
		dataType: 'json',
		async: false,
		success: function(r){
			if (r && r.conteudo){
				preencheCamposEditar(r);
				if(perfil == 4)
					removeValoresEditar();
			}
		}
	})
}

function preencheCamposEditar(dados){
	var cont = dados.faltas.length;
	var faltas = '';

	$('textarea[name="conteudo"]').val(dados.conteudo.con_conteudo);
	$('input[name="con_id"]').val(dados.conteudo.con_id);

	$('textarea[name="observacao"]').val(dados.observacao.obs_observacao);
	$('input[name="obs_id"]').val(dados.observacao.obs_id);

	$('textarea[name="tarefa"]').val(dados.tarefa.tar_tarefa);
	$('input[name="tar_id"]').val(dados.tarefa.tar_id);

	$('select[name="fal_quantidade_aulas"]').val(dados.faltas[0].fal_quantidade_aulas);

	for(var i = 0; i < cont; i++){
		$('input[name="faltas['+ dados.faltas[i].alu_id +']"]').val(dados.faltas[i].fal_falta);
		faltas = $('input[name="atds_id"]').val();
		$('input[name="atds_id"]').val(dados.faltas[i].fal_id + '/' + dados.faltas[i].alu_id + '@' + faltas);
	}
}

function removeValoresEditar(){
	$('input[name="con_id"], input[name="atds_id"], input[name="obs_id"], input[name="tar_id"]').val('');
	$('#lancarDiario').attr('disabled', 'disabled');
}<|endoftext|>