diff --git a/tagserverApp/.editorconfig b/tagserverApp/.editorconfig new file mode 100644 index 0000000..0f09989 --- /dev/null +++ b/tagserverApp/.editorconfig @@ -0,0 +1,10 @@ +# editorconfig.org +root = true + +[*] +indent_style = space +indent_size = 2 +end_of_line = lf +charset = utf-8 +trim_trailing_whitespace = true +insert_final_newline = true diff --git a/tagserverApp/.sailsrc b/tagserverApp/.sailsrc new file mode 100644 index 0000000..fa89f5e --- /dev/null +++ b/tagserverApp/.sailsrc @@ -0,0 +1,5 @@ +{ + "generators": { + "modules": {} + } +} \ No newline at end of file diff --git a/tagserverApp/Gruntfile.js b/tagserverApp/Gruntfile.js new file mode 100644 index 0000000..f4b2289 --- /dev/null +++ b/tagserverApp/Gruntfile.js @@ -0,0 +1,81 @@ +/** + * Gruntfile + * + * This Node script is executed when you run `grunt` or `sails lift`. + * It's purpose is to load the Grunt tasks in your project's `tasks` + * folder, and allow you to add and remove tasks as you see fit. + * For more information on how this works, check out the `README.md` + * file that was generated in your `tasks` folder. + * + * WARNING: + * Unless you know what you're doing, you shouldn't change this file. + * Check out the `tasks` directory instead. + */ + +module.exports = function(grunt) { + + + // Load the include-all library in order to require all of our grunt + // configurations and task registrations dynamically. + var includeAll; + try { + includeAll = require('include-all'); + } catch (e0) { + try { + includeAll = require('sails/node_modules/include-all'); + } + catch(e1) { + console.error('Could not find `include-all` module.'); + console.error('Skipping grunt tasks...'); + console.error('To fix this, please run:'); + console.error('npm install include-all --save`'); + console.error(); + + grunt.registerTask('default', []); + return; + } + } + + + /** + * Loads Grunt configuration modules from the specified + * relative path. These modules should export a function + * that, when run, should either load/configure or register + * a Grunt task. + */ + function loadTasks(relPath) { + return includeAll({ + dirname: require('path').resolve(__dirname, relPath), + filter: /(.+)\.js$/ + }) || {}; + } + + /** + * Invokes the function from a Grunt configuration module with + * a single argument - the `grunt` object. + */ + function invokeConfigFn(tasks) { + for (var taskName in tasks) { + if (tasks.hasOwnProperty(taskName)) { + tasks[taskName](grunt); + } + } + } + + + + + // Load task functions + var taskConfigurations = loadTasks('./tasks/config'), + registerDefinitions = loadTasks('./tasks/register'); + + // (ensure that a default task exists) + if (!registerDefinitions.default) { + registerDefinitions.default = function (grunt) { grunt.registerTask('default', []); }; + } + + // Run task functions to configure Grunt. + invokeConfigFn(taskConfigurations); + invokeConfigFn(registerDefinitions); + +}; diff --git a/tagserverApp/README.md b/tagserverApp/README.md new file mode 100644 index 0000000..a5e1f40 --- /dev/null +++ b/tagserverApp/README.md @@ -0,0 +1,3 @@ +# tagserverApp + +a [Sails](http://sailsjs.org) application diff --git a/tagserverApp/api/controllers/.gitkeep b/tagserverApp/api/controllers/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/tagserverApp/api/controllers/Data_typeController.js b/tagserverApp/api/controllers/Data_typeController.js new file mode 100644 index 0000000..57e10b7 --- /dev/null +++ b/tagserverApp/api/controllers/Data_typeController.js @@ -0,0 +1,11 @@ +/** + * Data_typeController + * + * @description :: Server-side logic for managing data_types + * @help :: See http://sailsjs.org/#!/documentation/concepts/Controllers + */ + +module.exports = { + +}; + diff --git a/tagserverApp/api/controllers/DeviceController.js b/tagserverApp/api/controllers/DeviceController.js new file mode 100644 index 0000000..8534541 --- /dev/null +++ b/tagserverApp/api/controllers/DeviceController.js @@ -0,0 +1,11 @@ +/** + * DeviceController + * + * @description :: Server-side logic for managing devices + * @help :: See http://sailsjs.org/#!/documentation/concepts/Controllers + */ + +module.exports = { + +}; + diff --git a/tagserverApp/api/controllers/Device_typeController.js b/tagserverApp/api/controllers/Device_typeController.js new file mode 100644 index 0000000..9f0e45a --- /dev/null +++ b/tagserverApp/api/controllers/Device_typeController.js @@ -0,0 +1,11 @@ +/** + * Device_typeController + * + * @description :: Server-side logic for managing device_types + * @help :: See http://sailsjs.org/#!/documentation/concepts/Controllers + */ + +module.exports = { + +}; + diff --git a/tagserverApp/api/controllers/TagController.js b/tagserverApp/api/controllers/TagController.js new file mode 100644 index 0000000..f76951d --- /dev/null +++ b/tagserverApp/api/controllers/TagController.js @@ -0,0 +1,11 @@ +/** + * TagController + * + * @description :: Server-side logic for managing tags + * @help :: See http://sailsjs.org/#!/documentation/concepts/Controllers + */ + +module.exports = { + +}; + diff --git a/tagserverApp/api/controllers/Tag_classController.js b/tagserverApp/api/controllers/Tag_classController.js new file mode 100644 index 0000000..952a3dd --- /dev/null +++ b/tagserverApp/api/controllers/Tag_classController.js @@ -0,0 +1,11 @@ +/** + * Tag_classController + * + * @description :: Server-side logic for managing tag_classes + * @help :: See http://sailsjs.org/#!/documentation/concepts/Controllers + */ + +module.exports = { + +}; + diff --git a/tagserverApp/api/controllers/Tag_valController.js b/tagserverApp/api/controllers/Tag_valController.js new file mode 100644 index 0000000..860767c --- /dev/null +++ b/tagserverApp/api/controllers/Tag_valController.js @@ -0,0 +1,11 @@ +/** + * Tag_valController + * + * @description :: Server-side logic for managing tag_vals + * @help :: See http://sailsjs.org/#!/documentation/concepts/Controllers + */ + +module.exports = { + +}; + diff --git a/tagserverApp/api/models/.gitkeep b/tagserverApp/api/models/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/tagserverApp/api/models/Data_type.js b/tagserverApp/api/models/Data_type.js new file mode 100644 index 0000000..b6fb655 --- /dev/null +++ b/tagserverApp/api/models/Data_type.js @@ -0,0 +1,23 @@ +/** + * Data_type.js + * + * @description :: TODO: You might write a short summary of how this model works and what it represents here. + * @docs :: http://sailsjs.org/documentation/concepts/models-and-orm/models + */ + +module.exports = { + connection: 'mysqlDb', + tableName: 'data_types', + attributes: { + id: { + type: 'integer', + unique: true, + autoIncrement: true, + primaryKey: true + }, + data_type: { + type: 'string', + unique: true + } + } +}; diff --git a/tagserverApp/api/models/Device.js b/tagserverApp/api/models/Device.js new file mode 100644 index 0000000..d4e1307 --- /dev/null +++ b/tagserverApp/api/models/Device.js @@ -0,0 +1,26 @@ +/** + * Device.js + * + * @description :: TODO: You might write a short summary of how this model works and what it represents here. + * @docs :: http://sailsjs.org/documentation/concepts/models-and-orm/models + */ + +module.exports = { + connection: 'mysqlDb', + tableName: 'devices', + attributes: { + id: { + type: 'integer', + unique: true, + autoIncrement: true, + primaryKey: true + }, + device_type: { + model: 'device_type', + columnName: 'device_type' + }, + address: { + type: 'string' + } + } +}; diff --git a/tagserverApp/api/models/Device_type.js b/tagserverApp/api/models/Device_type.js new file mode 100644 index 0000000..587299b --- /dev/null +++ b/tagserverApp/api/models/Device_type.js @@ -0,0 +1,23 @@ +/** + * Device_type.js + * + * @description :: TODO: You might write a short summary of how this model works and what it represents here. + * @docs :: http://sailsjs.org/documentation/concepts/models-and-orm/models + */ + +module.exports = { + connection: 'mysqlDb', + tableName: 'device_types', + attributes: { + id: { + type: 'integer', + unique: true, + autoIncrement: true, + primaryKey: true + }, + dType: { + type: 'string', + unique: true + } + } +}; diff --git a/tagserverApp/api/models/Tag.js b/tagserverApp/api/models/Tag.js new file mode 100644 index 0000000..27c6716 --- /dev/null +++ b/tagserverApp/api/models/Tag.js @@ -0,0 +1,55 @@ +/** + * Tag.js + * + * @description :: TODO: You might write a short summary of how this model works and what it represents here. + * @docs :: http://sailsjs.org/documentation/concepts/models-and-orm/models + */ + +module.exports = { + connection: 'mysqlDb', + tableName: 'tags', + attributes: { + id: { + type: 'integer', + unique: true, + autoIncrement: true, + primaryKey: true + }, + name: { + type: 'string' + }, + tag_class: { + model:'tag_class' + }, + tag: { + type: 'string' + }, + deviceID: { + model:'device' + }, + description: { + type: 'string' + }, + data_type: { + model: 'data_type' + }, + change_threshold: { + type: 'float' + }, + guarantee_sec: { + type: 'integer' + }, + map_function: { + type: 'string' + }, + units:{ + type: 'string' + }, + minExpected: { + type: 'float' + }, + maxExpected: { + type: 'float' + } + } +}; diff --git a/tagserverApp/api/models/Tag_class.js b/tagserverApp/api/models/Tag_class.js new file mode 100644 index 0000000..e8c887a --- /dev/null +++ b/tagserverApp/api/models/Tag_class.js @@ -0,0 +1,26 @@ +/** + * Tag_class.js + * + * @description :: TODO: You might write a short summary of how this model works and what it represents here. + * @docs :: http://sailsjs.org/documentation/concepts/models-and-orm/models + */ + +module.exports = { + connection: 'mysqlDb', + tableName: 'tag_classes', + attributes: { + id: { + type: 'integer', + unique: true, + autoIncrement: true, + primaryKey: true + }, + class_type: { + type: 'string', + unique: true + }, + description: { + type: 'string' + } + } +}; diff --git a/tagserverApp/api/models/Tag_val.js b/tagserverApp/api/models/Tag_val.js new file mode 100644 index 0000000..7673d38 --- /dev/null +++ b/tagserverApp/api/models/Tag_val.js @@ -0,0 +1,25 @@ +/** + * Tag_val.js + * + * @description :: TODO: You might write a short summary of how this model works and what it represents here. + * @docs :: http://sailsjs.org/documentation/concepts/models-and-orm/models + */ + +module.exports = { + connection: 'mysqlDb', + tableName: 'tag_vals', + attributes: { + id: { + type: 'integer', + unique: true, + autoIncrement: true, + primaryKey: true + }, + tagID:{ + model: 'tag' + }, + val:{ + type: 'float' + } + } +}; diff --git a/tagserverApp/api/policies/sessionAuth.js b/tagserverApp/api/policies/sessionAuth.js new file mode 100644 index 0000000..8f9a264 --- /dev/null +++ b/tagserverApp/api/policies/sessionAuth.js @@ -0,0 +1,21 @@ +/** + * sessionAuth + * + * @module :: Policy + * @description :: Simple policy to allow any authenticated user + * Assumes that your login action in one of your controllers sets `req.session.authenticated = true;` + * @docs :: http://sailsjs.org/#!/documentation/concepts/Policies + * + */ +module.exports = function(req, res, next) { + + // User is allowed, proceed to the next policy, + // or if this is the last policy, the controller + if (req.session.authenticated) { + return next(); + } + + // User is not allowed + // (default res.forbidden() behavior can be overridden in `config/403.js`) + return res.forbidden('You are not permitted to perform this action.'); +}; diff --git a/tagserverApp/api/responses/badRequest.js b/tagserverApp/api/responses/badRequest.js new file mode 100644 index 0000000..0d37825 --- /dev/null +++ b/tagserverApp/api/responses/badRequest.js @@ -0,0 +1,76 @@ +/** + * 400 (Bad Request) Handler + * + * Usage: + * return res.badRequest(); + * return res.badRequest(data); + * return res.badRequest(data, 'some/specific/badRequest/view'); + * + * e.g.: + * ``` + * return res.badRequest( + * 'Please choose a valid `password` (6-12 characters)', + * 'trial/signup' + * ); + * ``` + */ + +module.exports = function badRequest(data, options) { + + // Get access to `req`, `res`, & `sails` + var req = this.req; + var res = this.res; + var sails = req._sails; + + // Set status code + res.status(400); + + // Log error to console + if (data !== undefined) { + sails.log.verbose('Sending 400 ("Bad Request") response: \n',data); + } + else sails.log.verbose('Sending 400 ("Bad Request") response'); + + // Only include errors in response if application environment + // is not set to 'production'. In production, we shouldn't + // send back any identifying information about errors. + if (sails.config.environment === 'production' && sails.config.keepResponseErrors !== true) { + data = undefined; + } + + // If the user-agent wants JSON, always respond with JSON + // If views are disabled, revert to json + if (req.wantsJSON || sails.config.hooks.views === false) { + return res.jsonx(data); + } + + // If second argument is a string, we take that to mean it refers to a view. + // If it was omitted, use an empty object (`{}`) + options = (typeof options === 'string') ? { view: options } : options || {}; + + // Attempt to prettify data for views, if it's a non-error object + var viewData = data; + if (!(viewData instanceof Error) && 'object' == typeof viewData) { + try { + viewData = require('util').inspect(data, {depth: null}); + } + catch(e) { + viewData = undefined; + } + } + + // If a view was provided in options, serve it. + // Otherwise try to guess an appropriate view, or if that doesn't + // work, just send JSON. + if (options.view) { + return res.view(options.view, { data: viewData, title: 'Bad Request' }); + } + + // If no second argument provided, try to serve the implied view, + // but fall back to sending JSON(P) if no view can be inferred. + else return res.guessView({ data: viewData, title: 'Bad Request' }, function couldNotGuessView () { + return res.jsonx(data); + }); + +}; + diff --git a/tagserverApp/api/responses/created.js b/tagserverApp/api/responses/created.js new file mode 100644 index 0000000..3140113 --- /dev/null +++ b/tagserverApp/api/responses/created.js @@ -0,0 +1,60 @@ +/** + * 201 (CREATED) Response + * + * Usage: + * return res.created(); + * return res.created(data); + * return res.created(data, 'auth/login'); + * + * @param {Object} data + * @param {String|Object} options + * - pass string to render specified view + */ + +module.exports = function created (data, options) { + + // Get access to `req`, `res`, & `sails` + var req = this.req; + var res = this.res; + var sails = req._sails; + + sails.log.silly('res.created() :: Sending 201 ("CREATED") response'); + + // Set status code + res.status(201); + + // If appropriate, serve data as JSON(P) + // If views are disabled, revert to json + if (req.wantsJSON || sails.config.hooks.views === false) { + return res.jsonx(data); + } + + // If second argument is a string, we take that to mean it refers to a view. + // If it was omitted, use an empty object (`{}`) + options = (typeof options === 'string') ? { view: options } : options || {}; + + // Attempt to prettify data for views, if it's a non-error object + var viewData = data; + if (!(viewData instanceof Error) && 'object' == typeof viewData) { + try { + viewData = require('util').inspect(data, {depth: null}); + } + catch(e) { + viewData = undefined; + } + } + + // If a view was provided in options, serve it. + // Otherwise try to guess an appropriate view, or if that doesn't + // work, just send JSON. + if (options.view) { + return res.view(options.view, { data: viewData, title: 'Created' }); + } + + // If no second argument provided, try to serve the implied view, + // but fall back to sending JSON(P) if no view can be inferred. + else return res.guessView({ data: viewData, title: 'Created' }, function couldNotGuessView () { + return res.jsonx(data); + }); + +}; diff --git a/tagserverApp/api/responses/forbidden.js b/tagserverApp/api/responses/forbidden.js new file mode 100644 index 0000000..ca94852 --- /dev/null +++ b/tagserverApp/api/responses/forbidden.js @@ -0,0 +1,89 @@ +/** + * 403 (Forbidden) Handler + * + * Usage: + * return res.forbidden(); + * return res.forbidden(err); + * return res.forbidden(err, 'some/specific/forbidden/view'); + * + * e.g.: + * ``` + * return res.forbidden('Access denied.'); + * ``` + */ + +module.exports = function forbidden (data, options) { + + // Get access to `req`, `res`, & `sails` + var req = this.req; + var res = this.res; + var sails = req._sails; + + // Set status code + res.status(403); + + // Log error to console + if (data !== undefined) { + sails.log.verbose('Sending 403 ("Forbidden") response: \n',data); + } + else sails.log.verbose('Sending 403 ("Forbidden") response'); + + // Only include errors in response if application environment + // is not set to 'production'. In production, we shouldn't + // send back any identifying information about errors. + if (sails.config.environment === 'production' && sails.config.keepResponseErrors !== true) { + data = undefined; + } + + // If the user-agent wants JSON, always respond with JSON + // If views are disabled, revert to json + if (req.wantsJSON || sails.config.hooks.views === false) { + return res.jsonx(data); + } + + // If second argument is a string, we take that to mean it refers to a view. + // If it was omitted, use an empty object (`{}`) + options = (typeof options === 'string') ? { view: options } : options || {}; + + // Attempt to prettify data for views, if it's a non-error object + var viewData = data; + if (!(viewData instanceof Error) && 'object' == typeof viewData) { + try { + viewData = require('util').inspect(data, {depth: null}); + } + catch(e) { + viewData = undefined; + } + } + + // If a view was provided in options, serve it. + // Otherwise try to guess an appropriate view, or if that doesn't + // work, just send JSON. + if (options.view) { + return res.view(options.view, { data: viewData, title: 'Forbidden' }); + } + + // If no second argument provided, try to serve the default view, + // but fall back to sending JSON(P) if any errors occur. + else return res.view('403', { data: viewData, title: 'Forbidden' }, function (err, html) { + + // If a view error occured, fall back to JSON(P). + if (err) { + // + // Additionally: + // • If the view was missing, ignore the error but provide a verbose log. + if (err.code === 'E_VIEW_FAILED') { + sails.log.verbose('res.forbidden() :: Could not locate view for error page (sending JSON instead). Details: ',err); + } + // Otherwise, if this was a more serious error, log to the console with the details. + else { + sails.log.warn('res.forbidden() :: When attempting to render error page view, an error occured (sending JSON instead). Details: ', err); + } + return res.jsonx(data); + } + + return res.send(html); + }); + +}; + diff --git a/tagserverApp/api/responses/notFound.js b/tagserverApp/api/responses/notFound.js new file mode 100644 index 0000000..8f0cd03 --- /dev/null +++ b/tagserverApp/api/responses/notFound.js @@ -0,0 +1,94 @@ +/** + * 404 (Not Found) Handler + * + * Usage: + * return res.notFound(); + * return res.notFound(err); + * return res.notFound(err, 'some/specific/notfound/view'); + * + * e.g.: + * ``` + * return res.notFound(); + * ``` + * + * NOTE: + * If a request doesn't match any explicit routes (i.e. `config/routes.js`) + * or route blueprints (i.e. "shadow routes", Sails will call `res.notFound()` + * automatically. + */ + +module.exports = function notFound (data, options) { + + // Get access to `req`, `res`, & `sails` + var req = this.req; + var res = this.res; + var sails = req._sails; + + // Set status code + res.status(404); + + // Log error to console + if (data !== undefined) { + sails.log.verbose('Sending 404 ("Not Found") response: \n',data); + } + else sails.log.verbose('Sending 404 ("Not Found") response'); + + // Only include errors in response if application environment + // is not set to 'production'. In production, we shouldn't + // send back any identifying information about errors. + if (sails.config.environment === 'production' && sails.config.keepResponseErrors !== true) { + data = undefined; + } + + // If the user-agent wants JSON, always respond with JSON + // If views are disabled, revert to json + if (req.wantsJSON || sails.config.hooks.views === false) { + return res.jsonx(data); + } + + // If second argument is a string, we take that to mean it refers to a view. + // If it was omitted, use an empty object (`{}`) + options = (typeof options === 'string') ? { view: options } : options || {}; + + // Attempt to prettify data for views, if it's a non-error object + var viewData = data; + if (!(viewData instanceof Error) && 'object' == typeof viewData) { + try { + viewData = require('util').inspect(data, {depth: null}); + } + catch(e) { + viewData = undefined; + } + } + + // If a view was provided in options, serve it. + // Otherwise try to guess an appropriate view, or if that doesn't + // work, just send JSON. + if (options.view) { + return res.view(options.view, { data: viewData, title: 'Not Found' }); + } + + // If no second argument provided, try to serve the default view, + // but fall back to sending JSON(P) if any errors occur. + else return res.view('404', { data: viewData, title: 'Not Found' }, function (err, html) { + + // If a view error occured, fall back to JSON(P). + if (err) { + // + // Additionally: + // • If the view was missing, ignore the error but provide a verbose log. + if (err.code === 'E_VIEW_FAILED') { + sails.log.verbose('res.notFound() :: Could not locate view for error page (sending JSON instead). Details: ',err); + } + // Otherwise, if this was a more serious error, log to the console with the details. + else { + sails.log.warn('res.notFound() :: When attempting to render error page view, an error occured (sending JSON instead). Details: ', err); + } + return res.jsonx(data); + } + + return res.send(html); + }); + +}; + diff --git a/tagserverApp/api/responses/ok.js b/tagserverApp/api/responses/ok.js new file mode 100644 index 0000000..eb70144 --- /dev/null +++ b/tagserverApp/api/responses/ok.js @@ -0,0 +1,60 @@ +/** + * 200 (OK) Response + * + * Usage: + * return res.ok(); + * return res.ok(data); + * return res.ok(data, 'auth/login'); + * + * @param {Object} data + * @param {String|Object} options + * - pass string to render specified view + */ + +module.exports = function sendOK (data, options) { + + // Get access to `req`, `res`, & `sails` + var req = this.req; + var res = this.res; + var sails = req._sails; + + sails.log.silly('res.ok() :: Sending 200 ("OK") response'); + + // Set status code + res.status(200); + + // If appropriate, serve data as JSON(P) + // If views are disabled, revert to json + if (req.wantsJSON || sails.config.hooks.views === false) { + return res.jsonx(data); + } + + // If second argument is a string, we take that to mean it refers to a view. + // If it was omitted, use an empty object (`{}`) + options = (typeof options === 'string') ? { view: options } : options || {}; + + // Attempt to prettify data for views, if it's a non-error object + var viewData = data; + if (!(viewData instanceof Error) && 'object' == typeof viewData) { + try { + viewData = require('util').inspect(data, {depth: null}); + } + catch(e) { + viewData = undefined; + } + } + + // If a view was provided in options, serve it. + // Otherwise try to guess an appropriate view, or if that doesn't + // work, just send JSON. + if (options.view) { + return res.view(options.view, { data: viewData, title: 'OK' }); + } + + // If no second argument provided, try to serve the implied view, + // but fall back to sending JSON(P) if no view can be inferred. + else return res.guessView({ data: viewData, title: 'OK' }, function couldNotGuessView () { + return res.jsonx(data); + }); + +}; diff --git a/tagserverApp/api/responses/serverError.js b/tagserverApp/api/responses/serverError.js new file mode 100644 index 0000000..537c248 --- /dev/null +++ b/tagserverApp/api/responses/serverError.js @@ -0,0 +1,89 @@ +/** + * 500 (Server Error) Response + * + * Usage: + * return res.serverError(); + * return res.serverError(err); + * return res.serverError(err, 'some/specific/error/view'); + * + * NOTE: + * If something throws in a policy or controller, or an internal + * error is encountered, Sails will call `res.serverError()` + * automatically. + */ + +module.exports = function serverError (data, options) { + + // Get access to `req`, `res`, & `sails` + var req = this.req; + var res = this.res; + var sails = req._sails; + + // Set status code + res.status(500); + + // Log error to console + if (data !== undefined) { + sails.log.error('Sending 500 ("Server Error") response: \n',data); + } + else sails.log.error('Sending empty 500 ("Server Error") response'); + + // Only include errors in response if application environment + // is not set to 'production'. In production, we shouldn't + // send back any identifying information about errors. + if (sails.config.environment === 'production' && sails.config.keepResponseErrors !== true) { + data = undefined; + } + + // If the user-agent wants JSON, always respond with JSON + // If views are disabled, revert to json + if (req.wantsJSON || sails.config.hooks.views === false) { + return res.jsonx(data); + } + + // If second argument is a string, we take that to mean it refers to a view. + // If it was omitted, use an empty object (`{}`) + options = (typeof options === 'string') ? { view: options } : options || {}; + + // Attempt to prettify data for views, if it's a non-error object + var viewData = data; + if (!(viewData instanceof Error) && 'object' == typeof viewData) { + try { + viewData = require('util').inspect(data, {depth: null}); + } + catch(e) { + viewData = undefined; + } + } + + // If a view was provided in options, serve it. + // Otherwise try to guess an appropriate view, or if that doesn't + // work, just send JSON. + if (options.view) { + return res.view(options.view, { data: viewData, title: 'Server Error' }); + } + + // If no second argument provided, try to serve the default view, + // but fall back to sending JSON(P) if any errors occur. + else return res.view('500', { data: viewData, title: 'Server Error' }, function (err, html) { + + // If a view error occured, fall back to JSON(P). + if (err) { + // + // Additionally: + // • If the view was missing, ignore the error but provide a verbose log. + if (err.code === 'E_VIEW_FAILED') { + sails.log.verbose('res.serverError() :: Could not locate view for error page (sending JSON instead). Details: ',err); + } + // Otherwise, if this was a more serious error, log to the console with the details. + else { + sails.log.warn('res.serverError() :: When attempting to render error page view, an error occured (sending JSON instead). Details: ', err); + } + return res.jsonx(data); + } + + return res.send(html); + }); + +}; + diff --git a/tagserverApp/api/services/.gitkeep b/tagserverApp/api/services/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/tagserverApp/app.js b/tagserverApp/app.js new file mode 100644 index 0000000..85c0af7 --- /dev/null +++ b/tagserverApp/app.js @@ -0,0 +1,59 @@ +/** + * app.js + * + * Use `app.js` to run your app without `sails lift`. + * To start the server, run: `node app.js`. + * + * This is handy in situations where the sails CLI is not relevant or useful. + * + * For example: + * => `node app.js` + * => `forever start app.js` + * => `node debug app.js` + * => `modulus deploy` + * => `heroku scale` + * + * + * The same command-line arguments are supported, e.g.: + * `node app.js --silent --port=80 --prod` + */ + +// Ensure we're in the project directory, so relative paths work as expected +// no matter where we actually lift from. +process.chdir(__dirname); + +// Ensure a "sails" can be located: +(function() { + var sails; + try { + sails = require('sails'); + } catch (e) { + console.error('To run an app using `node app.js`, you usually need to have a version of `sails` installed in the same directory as your app.'); + console.error('To do that, run `npm install sails`'); + console.error(''); + console.error('Alternatively, if you have sails installed globally (i.e. you did `npm install -g sails`), you can use `sails lift`.'); + console.error('When you run `sails lift`, your app will still use a local `./node_modules/sails` dependency if it exists,'); + console.error('but if it doesn\'t, the app will run with the global sails instead!'); + return; + } + + // Try to get `rc` dependency + var rc; + try { + rc = require('rc'); + } catch (e0) { + try { + rc = require('sails/node_modules/rc'); + } catch (e1) { + console.error('Could not find dependency: `rc`.'); + console.error('Your `.sailsrc` file(s) will be ignored.'); + console.error('To resolve this, run:'); + console.error('npm install rc --save'); + rc = function () { return {}; }; + } + } + + + // Start server + sails.lift(rc('sails')); +})(); diff --git a/tagserverApp/assets/favicon.ico b/tagserverApp/assets/favicon.ico new file mode 100644 index 0000000..0092ec9 Binary files /dev/null and b/tagserverApp/assets/favicon.ico differ diff --git a/tagserverApp/assets/images/.gitkeep b/tagserverApp/assets/images/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/tagserverApp/assets/js/dependencies/sails.io.js b/tagserverApp/assets/js/dependencies/sails.io.js new file mode 100644 index 0000000..9229fed --- /dev/null +++ b/tagserverApp/assets/js/dependencies/sails.io.js @@ -0,0 +1,1533 @@ +/** + * To use sails.io.js in an AMD environment (e.g. with require.js), + * replace this file with the sails.io.js file from the root of: + * https://github.com/balderdashy/sails.io.js + * and download a standalone copy of socket.io-client from: + * https://github.com/socketio/socket.io-client + * then follow the instructions at: + * https://github.com/balderdashy/sails.io.js#requirejsamd-usage + */ + +// socket.io-client version 1.4.4 +// https://github.com/socketio/socket.io-client + +!function(a){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=a();else if("function"==typeof define&&define.amd)define([],a);else{var b;b="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,b.io=a()}}(function(){var a;return function b(a,c,d){function e(g,h){if(!c[g]){if(!a[g]){var i="function"==typeof require&&require;if(!h&&i)return i(g,!0);if(f)return f(g,!0);var j=new Error("Cannot find module '"+g+"'");throw j.code="MODULE_NOT_FOUND",j}var k=c[g]={exports:{}};a[g][0].call(k.exports,function(b){var c=a[g][1][b];return e(c?c:b)},k,k.exports,b,a,c,d)}return c[g].exports}for(var f="function"==typeof require&&require,g=0;g0&&(this.extraHeaders=b.extraHeaders),this.open()}function e(a){var b={};for(var c in a)a.hasOwnProperty(c)&&(b[c]=a[c]);return b}var f=a("./transports"),g=a("component-emitter"),h=a("debug")("engine.io-client:socket"),i=a("indexof"),j=a("engine.io-parser"),k=a("parseuri"),l=a("parsejson"),m=a("parseqs");b.exports=d,d.priorWebsocketSuccess=!1,g(d.prototype),d.protocol=j.protocol,d.Socket=d,d.Transport=a("./transport"),d.transports=a("./transports"),d.parser=a("engine.io-parser"),d.prototype.createTransport=function(a){h('creating transport "%s"',a);var b=e(this.query);b.EIO=j.protocol,b.transport=a,this.id&&(b.sid=this.id);var c=new f[a]({agent:this.agent,hostname:this.hostname,port:this.port,secure:this.secure,path:this.path,query:b,forceJSONP:this.forceJSONP,jsonp:this.jsonp,forceBase64:this.forceBase64,enablesXDR:this.enablesXDR,timestampRequests:this.timestampRequests,timestampParam:this.timestampParam,policyPort:this.policyPort,socket:this,pfx:this.pfx,key:this.key,passphrase:this.passphrase,cert:this.cert,ca:this.ca,ciphers:this.ciphers,rejectUnauthorized:this.rejectUnauthorized,perMessageDeflate:this.perMessageDeflate,extraHeaders:this.extraHeaders});return c},d.prototype.open=function(){var a;if(this.rememberUpgrade&&d.priorWebsocketSuccess&&-1!=this.transports.indexOf("websocket"))a="websocket";else{if(0===this.transports.length){var b=this;return void setTimeout(function(){b.emit("error","No transports available")},0)}a=this.transports[0]}this.readyState="opening";try{a=this.createTransport(a)}catch(c){return this.transports.shift(),void this.open()}a.open(),this.setTransport(a)},d.prototype.setTransport=function(a){h("setting transport %s",a.name);var b=this;this.transport&&(h("clearing existing transport %s",this.transport.name),this.transport.removeAllListeners()),this.transport=a,a.on("drain",function(){b.onDrain()}).on("packet",function(a){b.onPacket(a)}).on("error",function(a){b.onError(a)}).on("close",function(){b.onClose("transport close")})},d.prototype.probe=function(a){function b(){if(m.onlyBinaryUpgrades){var b=!this.supportsBinary&&m.transport.supportsBinary;l=l||b}l||(h('probe transport "%s" opened',a),k.send([{type:"ping",data:"probe"}]),k.once("packet",function(b){if(!l)if("pong"==b.type&&"probe"==b.data){if(h('probe transport "%s" pong',a),m.upgrading=!0,m.emit("upgrading",k),!k)return;d.priorWebsocketSuccess="websocket"==k.name,h('pausing current transport "%s"',m.transport.name),m.transport.pause(function(){l||"closed"!=m.readyState&&(h("changing transport and sending upgrade packet"),j(),m.setTransport(k),k.send([{type:"upgrade"}]),m.emit("upgrade",k),k=null,m.upgrading=!1,m.flush())})}else{h('probe transport "%s" failed',a);var c=new Error("probe error");c.transport=k.name,m.emit("upgradeError",c)}}))}function c(){l||(l=!0,j(),k.close(),k=null)}function e(b){var d=new Error("probe error: "+b);d.transport=k.name,c(),h('probe transport "%s" failed because of error: %s',a,b),m.emit("upgradeError",d)}function f(){e("transport closed")}function g(){e("socket closed")}function i(a){k&&a.name!=k.name&&(h('"%s" works - aborting "%s"',a.name,k.name),c())}function j(){k.removeListener("open",b),k.removeListener("error",e),k.removeListener("close",f),m.removeListener("close",g),m.removeListener("upgrading",i)}h('probing transport "%s"',a);var k=this.createTransport(a,{probe:1}),l=!1,m=this;d.priorWebsocketSuccess=!1,k.once("open",b),k.once("error",e),k.once("close",f),this.once("close",g),this.once("upgrading",i),k.open()},d.prototype.onOpen=function(){if(h("socket open"),this.readyState="open",d.priorWebsocketSuccess="websocket"==this.transport.name,this.emit("open"),this.flush(),"open"==this.readyState&&this.upgrade&&this.transport.pause){h("starting upgrade probes");for(var a=0,b=this.upgrades.length;b>a;a++)this.probe(this.upgrades[a])}},d.prototype.onPacket=function(a){if("opening"==this.readyState||"open"==this.readyState)switch(h('socket receive: type "%s", data "%s"',a.type,a.data),this.emit("packet",a),this.emit("heartbeat"),a.type){case"open":this.onHandshake(l(a.data));break;case"pong":this.setPing(),this.emit("pong");break;case"error":var b=new Error("server error");b.code=a.data,this.onError(b);break;case"message":this.emit("data",a.data),this.emit("message",a.data)}else h('packet received with socket readyState "%s"',this.readyState)},d.prototype.onHandshake=function(a){this.emit("handshake",a),this.id=a.sid,this.transport.query.sid=a.sid,this.upgrades=this.filterUpgrades(a.upgrades),this.pingInterval=a.pingInterval,this.pingTimeout=a.pingTimeout,this.onOpen(),"closed"!=this.readyState&&(this.setPing(),this.removeListener("heartbeat",this.onHeartbeat),this.on("heartbeat",this.onHeartbeat))},d.prototype.onHeartbeat=function(a){clearTimeout(this.pingTimeoutTimer);var b=this;b.pingTimeoutTimer=setTimeout(function(){"closed"!=b.readyState&&b.onClose("ping timeout")},a||b.pingInterval+b.pingTimeout)},d.prototype.setPing=function(){var a=this;clearTimeout(a.pingIntervalTimer),a.pingIntervalTimer=setTimeout(function(){h("writing ping packet - expecting pong within %sms",a.pingTimeout),a.ping(),a.onHeartbeat(a.pingTimeout)},a.pingInterval)},d.prototype.ping=function(){var a=this;this.sendPacket("ping",function(){a.emit("ping")})},d.prototype.onDrain=function(){this.writeBuffer.splice(0,this.prevBufferLen),this.prevBufferLen=0,0===this.writeBuffer.length?this.emit("drain"):this.flush()},d.prototype.flush=function(){"closed"!=this.readyState&&this.transport.writable&&!this.upgrading&&this.writeBuffer.length&&(h("flushing %d packets in socket",this.writeBuffer.length),this.transport.send(this.writeBuffer),this.prevBufferLen=this.writeBuffer.length,this.emit("flush"))},d.prototype.write=d.prototype.send=function(a,b,c){return this.sendPacket("message",a,b,c),this},d.prototype.sendPacket=function(a,b,c,d){if("function"==typeof b&&(d=b,b=void 0),"function"==typeof c&&(d=c,c=null),"closing"!=this.readyState&&"closed"!=this.readyState){c=c||{},c.compress=!1!==c.compress;var e={type:a,data:b,options:c};this.emit("packetCreate",e),this.writeBuffer.push(e),d&&this.once("flush",d),this.flush()}},d.prototype.close=function(){function a(){d.onClose("forced close"),h("socket closing - telling transport to close"),d.transport.close()}function b(){d.removeListener("upgrade",b),d.removeListener("upgradeError",b),a()}function c(){d.once("upgrade",b),d.once("upgradeError",b)}if("opening"==this.readyState||"open"==this.readyState){this.readyState="closing";var d=this;this.writeBuffer.length?this.once("drain",function(){this.upgrading?c():a()}):this.upgrading?c():a()}return this},d.prototype.onError=function(a){h("socket error %j",a),d.priorWebsocketSuccess=!1,this.emit("error",a),this.onClose("transport error",a)},d.prototype.onClose=function(a,b){if("opening"==this.readyState||"open"==this.readyState||"closing"==this.readyState){h('socket close with reason: "%s"',a);var c=this;clearTimeout(this.pingIntervalTimer),clearTimeout(this.pingTimeoutTimer),this.transport.removeAllListeners("close"),this.transport.close(),this.transport.removeAllListeners(),this.readyState="closed",this.id=null,this.emit("close",a,b),c.writeBuffer=[],c.prevBufferLen=0}},d.prototype.filterUpgrades=function(a){for(var b=[],c=0,d=a.length;d>c;c++)~i(this.transports,a[c])&&b.push(a[c]);return b}}).call(this,"undefined"!=typeof self?self:"undefined"!=typeof window?window:"undefined"!=typeof global?global:{})},{"./transport":4,"./transports":5,"component-emitter":15,debug:17,"engine.io-parser":19,indexof:23,parsejson:26,parseqs:27,parseuri:28}],4:[function(a,b,c){function d(a){this.path=a.path,this.hostname=a.hostname,this.port=a.port,this.secure=a.secure,this.query=a.query,this.timestampParam=a.timestampParam,this.timestampRequests=a.timestampRequests,this.readyState="",this.agent=a.agent||!1,this.socket=a.socket,this.enablesXDR=a.enablesXDR,this.pfx=a.pfx,this.key=a.key,this.passphrase=a.passphrase,this.cert=a.cert,this.ca=a.ca,this.ciphers=a.ciphers,this.rejectUnauthorized=a.rejectUnauthorized,this.extraHeaders=a.extraHeaders}var e=a("engine.io-parser"),f=a("component-emitter");b.exports=d,f(d.prototype),d.prototype.onError=function(a,b){var c=new Error(a);return c.type="TransportError",c.description=b,this.emit("error",c),this},d.prototype.open=function(){return("closed"==this.readyState||""==this.readyState)&&(this.readyState="opening",this.doOpen()),this},d.prototype.close=function(){return("opening"==this.readyState||"open"==this.readyState)&&(this.doClose(),this.onClose()),this},d.prototype.send=function(a){if("open"!=this.readyState)throw new Error("Transport not open");this.write(a)},d.prototype.onOpen=function(){this.readyState="open",this.writable=!0,this.emit("open")},d.prototype.onData=function(a){var b=e.decodePacket(a,this.socket.binaryType);this.onPacket(b)},d.prototype.onPacket=function(a){this.emit("packet",a)},d.prototype.onClose=function(){this.readyState="closed",this.emit("close")}},{"component-emitter":15,"engine.io-parser":19}],5:[function(a,b,c){(function(b){function d(a){var c,d=!1,h=!1,i=!1!==a.jsonp;if(b.location){var j="https:"==location.protocol,k=location.port;k||(k=j?443:80),d=a.hostname!=location.hostname||k!=a.port,h=a.secure!=j}if(a.xdomain=d,a.xscheme=h,c=new e(a),"open"in c&&!a.forceJSONP)return new f(a);if(!i)throw new Error("JSONP disabled");return new g(a)}var e=a("xmlhttprequest-ssl"),f=a("./polling-xhr"),g=a("./polling-jsonp"),h=a("./websocket");c.polling=d,c.websocket=h}).call(this,"undefined"!=typeof self?self:"undefined"!=typeof window?window:"undefined"!=typeof global?global:{})},{"./polling-jsonp":6,"./polling-xhr":7,"./websocket":9,"xmlhttprequest-ssl":10}],6:[function(a,b,c){(function(c){function d(){}function e(a){f.call(this,a),this.query=this.query||{},h||(c.___eio||(c.___eio=[]),h=c.___eio),this.index=h.length;var b=this;h.push(function(a){b.onData(a)}),this.query.j=this.index,c.document&&c.addEventListener&&c.addEventListener("beforeunload",function(){b.script&&(b.script.onerror=d)},!1)}var f=a("./polling"),g=a("component-inherit");b.exports=e;var h,i=/\n/g,j=/\\n/g;g(e,f),e.prototype.supportsBinary=!1,e.prototype.doClose=function(){this.script&&(this.script.parentNode.removeChild(this.script),this.script=null),this.form&&(this.form.parentNode.removeChild(this.form),this.form=null,this.iframe=null),f.prototype.doClose.call(this)},e.prototype.doPoll=function(){var a=this,b=document.createElement("script");this.script&&(this.script.parentNode.removeChild(this.script),this.script=null),b.async=!0,b.src=this.uri(),b.onerror=function(b){a.onError("jsonp poll error",b)};var c=document.getElementsByTagName("script")[0];c?c.parentNode.insertBefore(b,c):(document.head||document.body).appendChild(b),this.script=b;var d="undefined"!=typeof navigator&&/gecko/i.test(navigator.userAgent);d&&setTimeout(function(){var a=document.createElement("iframe");document.body.appendChild(a),document.body.removeChild(a)},100)},e.prototype.doWrite=function(a,b){function c(){d(),b()}function d(){if(e.iframe)try{e.form.removeChild(e.iframe)}catch(a){e.onError("jsonp polling iframe removal error",a)}try{var b='