diff --git a/1-hello-world/app.js b/1-hello-world/app.js index 4d99aead3e..84f84b97d1 100644 --- a/1-hello-world/app.js +++ b/1-hello-world/app.js @@ -20,7 +20,7 @@ var app = express(); // [START hello_world] // Say hello! -app.get('/', function(req, res) { +app.get('/', function (req, res) { res.status(200).send('Hello, world!'); }); // [END hello_world] diff --git a/2-structured-data/books/model-cloudsql.js b/2-structured-data/books/model-cloudsql.js index 1ae0d69563..94efa810a6 100644 --- a/2-structured-data/books/model-cloudsql.js +++ b/2-structured-data/books/model-cloudsql.js @@ -16,7 +16,7 @@ var extend = require('lodash').assign; var mysql = require('mysql'); -module.exports = function(config) { +module.exports = function (config) { function getConnection() { return mysql.createConnection(extend({ @@ -30,7 +30,7 @@ module.exports = function(config) { var connection = getConnection(); connection.query( 'SELECT * FROM `books` LIMIT ? OFFSET ?', [limit, token], - function(err, results) { + function (err, results) { if (err) { return cb(err); } var hasMore = results.length === limit ? token + results.length : false; cb(null, results, hasMore); @@ -43,7 +43,7 @@ module.exports = function(config) { // [START create] function create(data, cb) { var connection = getConnection(); - connection.query('INSERT INTO `books` SET ?', data, function(err, res) { + connection.query('INSERT INTO `books` SET ?', data, function (err, res) { if (err) { return cb(err); } read(res.insertId, cb); }); @@ -54,7 +54,7 @@ module.exports = function(config) { function read(id, cb) { var connection = getConnection(); connection.query( - 'SELECT * FROM `books` WHERE `id` = ?', id, function(err, results) { + 'SELECT * FROM `books` WHERE `id` = ?', id, function (err, results) { if (err) { return cb(err); } if (!results.length) { return cb({ @@ -71,7 +71,7 @@ module.exports = function(config) { function update(id, data, cb) { var connection = getConnection(); connection.query( - 'UPDATE `books` SET ? WHERE `id` = ?', [data, id], function(err) { + 'UPDATE `books` SET ? WHERE `id` = ?', [data, id], function (err) { if (err) { return cb(err); } read(id, cb); }); @@ -95,7 +95,6 @@ module.exports = function(config) { }; }; - if (!module.parent) { var prompt = require('prompt'); prompt.start(); @@ -104,7 +103,7 @@ if (!module.parent) { 'Running this script directly will allow you to initialize your mysql ' + 'database.\n This script will not modify any existing tables.\n'); - prompt.get(['host', 'user', 'password'], function(err, result) { + prompt.get(['host', 'user', 'password'], function (err, result) { if (err) { return; } createSchema(result); }); @@ -129,7 +128,7 @@ function createSchema(config) { '`createdBy` VARCHAR(255) NULL, ' + '`createdById` VARCHAR(255) NULL, ' + 'PRIMARY KEY (`id`));', - function(err) { + function (err) { if (err) { throw err; } console.log('Successfully created schema'); connection.end(); diff --git a/2-structured-data/books/model-datastore.js b/2-structured-data/books/model-datastore.js index 5dc682cf5c..9931441cd8 100644 --- a/2-structured-data/books/model-datastore.js +++ b/2-structured-data/books/model-datastore.js @@ -15,15 +15,13 @@ var gcloud = require('gcloud'); - -module.exports = function(config) { +module.exports = function (config) { // [START config] - var ds = gcloud.datastore.dataset(config.gcloud); + var ds = gcloud.datastore(config.gcloud); var kind = 'Book'; // [END config] - // Translates from Datastore's entity format to // the format expected by the application. // @@ -45,7 +43,6 @@ module.exports = function(config) { return obj.data; } - // Translates from the application's format to the datastore's // extended entity property format. It also handles marking any // specified properties as non-indexed. Does not translate the key. @@ -72,7 +69,7 @@ module.exports = function(config) { function toDatastore(obj, nonIndexed) { nonIndexed = nonIndexed || []; var results = []; - Object.keys(obj).forEach(function(k) { + Object.keys(obj).forEach(function (k) { if (obj[k] === undefined) { return; } results.push({ name: k, @@ -83,7 +80,6 @@ module.exports = function(config) { return results; } - // Lists all books in the Datastore sorted alphabetically by title. // The ``limit`` argument determines the maximum amount of results to // return per page. The ``token`` argument allows requesting additional @@ -95,7 +91,7 @@ module.exports = function(config) { .order('title') .start(token); - ds.runQuery(q, function(err, entities, nextQuery) { + ds.runQuery(q, function (err, entities, nextQuery) { if (err) { return cb(err); } var hasMore = entities.length === limit ? nextQuery.startVal : false; cb(null, entities.map(fromDatastore), hasMore); @@ -103,7 +99,6 @@ module.exports = function(config) { } // [END list] - // Creates a new book or updates an existing book with new data. The provided // data is automatically translated into Datastore format. The book will be // queued for background processing. @@ -123,7 +118,7 @@ module.exports = function(config) { ds.save( entity, - function(err) { + function (err) { data.id = entity.key.id; cb(err, err ? null : data); } @@ -131,10 +126,9 @@ module.exports = function(config) { } // [END update] - function read(id, cb) { var key = ds.key([kind, parseInt(id, 10)]); - ds.get(key, function(err, entity) { + ds.get(key, function (err, entity) { if (err) { return cb(err); } if (!entity) { return cb({ @@ -146,16 +140,14 @@ module.exports = function(config) { }); } - function _delete(id, cb) { var key = ds.key([kind, parseInt(id, 10)]); ds.delete(key, cb); } - // [START exports] return { - create: function(data, cb) { + create: function (data, cb) { update(null, data, cb); }, read: read, @@ -164,5 +156,4 @@ module.exports = function(config) { list: list }; // [END exports] - }; diff --git a/2-structured-data/package.json b/2-structured-data/package.json index a9a0474a9a..9d137e25e4 100644 --- a/2-structured-data/package.json +++ b/2-structured-data/package.json @@ -32,11 +32,11 @@ "dependencies": { "body-parser": "^1.15.0", "express": "^4.13.4", - "gcloud": "^0.28.0", + "gcloud": "^0.30.2", "jade": "^1.11.0", - "kerberos": "^0.0.18", - "lodash": "^4.5.1", - "mongodb": "^2.1.7", + "kerberos": "^0.0.19", + "lodash": "^4.8.2", + "mongodb": "^2.1.15", "mysql": "^2.10.2", "prompt": "^1.0.0" }, diff --git a/3-binary-data/books/model-cloudsql.js b/3-binary-data/books/model-cloudsql.js index e0278ac8c6..80edb89a14 100644 --- a/3-binary-data/books/model-cloudsql.js +++ b/3-binary-data/books/model-cloudsql.js @@ -17,7 +17,7 @@ var extend = require('lodash').assign; var mysql = require('mysql'); -module.exports = function(config) { +module.exports = function (config) { function getConnection() { return mysql.createConnection(extend({ @@ -31,7 +31,7 @@ module.exports = function(config) { var connection = getConnection(); connection.query( 'SELECT * FROM `books` LIMIT ? OFFSET ?', [limit, token], - function(err, results) { + function (err, results) { if (err) { return cb(err); } var hasMore = results.length === limit ? token + results.length : false; cb(null, results, hasMore); @@ -43,7 +43,7 @@ module.exports = function(config) { function create(data, cb) { var connection = getConnection(); - connection.query('INSERT INTO `books` SET ?', data, function(err, res) { + connection.query('INSERT INTO `books` SET ?', data, function (err, res) { if (err) { return cb(err); } read(res.insertId, cb); }); @@ -54,7 +54,7 @@ module.exports = function(config) { function read(id, cb) { var connection = getConnection(); connection.query( - 'SELECT * FROM `books` WHERE `id` = ?', id, function(err, results) { + 'SELECT * FROM `books` WHERE `id` = ?', id, function (err, results) { if (err) { return cb(err); } if (!results.length) { return cb({ @@ -71,7 +71,7 @@ module.exports = function(config) { function update(id, data, cb) { var connection = getConnection(); connection.query( - 'UPDATE `books` SET ? WHERE `id` = ?', [data, id], function(err) { + 'UPDATE `books` SET ? WHERE `id` = ?', [data, id], function (err) { if (err) { return cb(err); } read(id, cb); }); @@ -106,7 +106,7 @@ if (!module.parent) { 'Running this script directly will allow you to initialize your mysql ' + 'database.\n This script will not modify any existing tables.\n'); - prompt.get(['host', 'user', 'password'], function(err, result) { + prompt.get(['host', 'user', 'password'], function (err, result) { if (err) { return; } createSchema(result); }); @@ -132,7 +132,7 @@ function createSchema(config) { '`createdBy` VARCHAR(255) NULL, ' + '`createdById` VARCHAR(255) NULL, ' + 'PRIMARY KEY (`id`));', - function(err) { + function (err) { if (err) { throw err; } console.log('Successfully created schema'); connection.end(); diff --git a/3-binary-data/books/model-datastore.js b/3-binary-data/books/model-datastore.js index 1979693049..2b2ddd80c6 100644 --- a/3-binary-data/books/model-datastore.js +++ b/3-binary-data/books/model-datastore.js @@ -16,9 +16,9 @@ var gcloud = require('gcloud'); -module.exports = function(config) { +module.exports = function (config) { - var ds = gcloud.datastore.dataset(config.gcloud); + var ds = gcloud.datastore(config.gcloud); var kind = 'Book'; @@ -70,7 +70,7 @@ module.exports = function(config) { function toDatastore(obj, nonIndexed) { nonIndexed = nonIndexed || []; var results = []; - Object.keys(obj).forEach(function(k) { + Object.keys(obj).forEach(function (k) { if (obj[k] === undefined) { return; } results.push({ name: k, @@ -92,7 +92,7 @@ module.exports = function(config) { .order('title') .start(token); - ds.runQuery(q, function(err, entities, nextQuery) { + ds.runQuery(q, function (err, entities, nextQuery) { if (err) { return cb(err); } var hasMore = entities.length === limit ? nextQuery.startVal : false; cb(null, entities.map(fromDatastore), hasMore); @@ -118,7 +118,7 @@ module.exports = function(config) { ds.save( entity, - function(err) { + function (err) { data.id = entity.key.id; cb(err, err ? null : data); } @@ -128,7 +128,7 @@ module.exports = function(config) { function read(id, cb) { var key = ds.key([kind, parseInt(id, 10)]); - ds.get(key, function(err, entity) { + ds.get(key, function (err, entity) { if (err) { return cb(err); } if (!entity) { return cb({ @@ -148,7 +148,7 @@ module.exports = function(config) { return { - create: function(data, cb) { + create: function (data, cb) { update(null, data, cb); }, read: read, diff --git a/3-binary-data/lib/images.js b/3-binary-data/lib/images.js index 4aa78eb828..919b566ce0 100644 --- a/3-binary-data/lib/images.js +++ b/3-binary-data/lib/images.js @@ -16,7 +16,7 @@ var gcloud = require('gcloud'); -module.exports = function(gcloudConfig, cloudStorageBucket) { +module.exports = function (gcloudConfig, cloudStorageBucket) { var storage = gcloud.storage(gcloudConfig); var bucket = storage.bucket(cloudStorageBucket); @@ -46,12 +46,12 @@ module.exports = function(gcloudConfig, cloudStorageBucket) { var file = bucket.file(gcsname); var stream = file.createWriteStream(); - stream.on('error', function(err) { + stream.on('error', function (err) { req.file.cloudStorageError = err; next(err); }); - stream.on('finish', function() { + stream.on('finish', function () { req.file.cloudStorageObject = gcsname; req.file.cloudStoragePublicUrl = getPublicUrl(gcsname); next(); @@ -71,7 +71,7 @@ module.exports = function(gcloudConfig, cloudStorageBucket) { var multer = require('multer')({ inMemory: true, fileSize: 5 * 1024 * 1024, // no larger than 5mb - rename: function(fieldname, filename) { + rename: function (fieldname, filename) { // generate a unique filename return filename.replace(/\W+/g, '-').toLowerCase() + Date.now(); } diff --git a/3-binary-data/package.json b/3-binary-data/package.json index b3d783c007..eecc4e5b3d 100644 --- a/3-binary-data/package.json +++ b/3-binary-data/package.json @@ -32,11 +32,11 @@ "dependencies": { "body-parser": "^1.15.0", "express": "^4.13.4", - "gcloud": "^0.28.0", + "gcloud": "^0.30.2", "jade": "^1.11.0", - "kerberos": "^0.0.18", - "lodash": "^4.5.1", - "mongodb": "^2.1.7", + "kerberos": "^0.0.19", + "lodash": "^4.8.2", + "mongodb": "^2.1.15", "multer": "^1.1.0", "mysql": "^2.10.2", "prompt": "^1.0.0" diff --git a/4-auth/books/crud.js b/4-auth/books/crud.js index 5f1961250c..15fc9f4ce7 100644 --- a/4-auth/books/crud.js +++ b/4-auth/books/crud.js @@ -15,7 +15,7 @@ var express = require('express'); -module.exports = function(model, images, oauth2) { +module.exports = function (model, images, oauth2) { var router = express.Router(); diff --git a/4-auth/books/model-cloudsql.js b/4-auth/books/model-cloudsql.js index 2df73df4a6..52447ec41f 100644 --- a/4-auth/books/model-cloudsql.js +++ b/4-auth/books/model-cloudsql.js @@ -17,7 +17,7 @@ var extend = require('lodash').assign; var mysql = require('mysql'); -module.exports = function(config) { +module.exports = function (config) { function getConnection() { return mysql.createConnection(extend({ @@ -31,7 +31,7 @@ module.exports = function(config) { var connection = getConnection(); connection.query( 'SELECT * FROM `books` LIMIT ? OFFSET ?', [limit, token], - function(err, results) { + function (err, results) { if (err) { return cb(err); } var hasMore = results.length === limit ? token + results.length : false; cb(null, results, hasMore); @@ -48,7 +48,7 @@ module.exports = function(config) { connection.query( 'SELECT * FROM `books` WHERE `createdById` = ? LIMIT ? OFFSET ?', [userId, limit, token], - function(err, results) { + function (err, results) { if (err) { return cb(err); } var hasMore = results.length === limit ? token + results.length : false; cb(null, results, hasMore); @@ -60,7 +60,7 @@ module.exports = function(config) { function create(data, cb) { var connection = getConnection(); - connection.query('INSERT INTO `books` SET ?', data, function(err, res) { + connection.query('INSERT INTO `books` SET ?', data, function (err, res) { if (err) { return cb(err); } read(res.insertId, cb); }); @@ -71,7 +71,7 @@ module.exports = function(config) { function read(id, cb) { var connection = getConnection(); connection.query( - 'SELECT * FROM `books` WHERE `id` = ?', id, function(err, results) { + 'SELECT * FROM `books` WHERE `id` = ?', id, function (err, results) { if (err) { return cb(err); } if (!results.length) { return cb({ @@ -88,7 +88,7 @@ module.exports = function(config) { function update(id, data, cb) { var connection = getConnection(); connection.query( - 'UPDATE `books` SET ? WHERE `id` = ?', [data, id], function(err) { + 'UPDATE `books` SET ? WHERE `id` = ?', [data, id], function (err) { if (err) { return cb(err); } read(id, cb); }); @@ -124,7 +124,7 @@ if (!module.parent) { 'Running this script directly will allow you to initialize your mysql ' + 'database.\n This script will not modify any existing tables.\n'); - prompt.get(['host', 'user', 'password'], function(err, result) { + prompt.get(['host', 'user', 'password'], function (err, result) { if (err) { return; } createSchema(result); }); @@ -150,7 +150,7 @@ function createSchema(config) { '`createdBy` VARCHAR(255) NULL, ' + '`createdById` VARCHAR(255) NULL, ' + 'PRIMARY KEY (`id`));', - function(err) { + function (err) { if (err) { throw err; } console.log('Successfully created schema'); connection.end(); diff --git a/4-auth/books/model-datastore.js b/4-auth/books/model-datastore.js index 2fac0d88de..5f9562889b 100644 --- a/4-auth/books/model-datastore.js +++ b/4-auth/books/model-datastore.js @@ -15,13 +15,11 @@ var gcloud = require('gcloud'); +module.exports = function (config) { -module.exports = function(config) { - - var ds = gcloud.datastore.dataset(config.gcloud); + var ds = gcloud.datastore(config.gcloud); var kind = 'Book'; - // Translates from Datastore's entity format to // the format expected by the application. // @@ -43,7 +41,6 @@ module.exports = function(config) { return obj.data; } - // Translates from the application's format to the datastore's // extended entity property format. It also handles marking any // specified properties as non-indexed. Does not translate the key. @@ -70,7 +67,7 @@ module.exports = function(config) { function toDatastore(obj, nonIndexed) { nonIndexed = nonIndexed || []; var results = []; - Object.keys(obj).forEach(function(k) { + Object.keys(obj).forEach(function (k) { if (obj[k] === undefined) { return; } results.push({ name: k, @@ -81,7 +78,6 @@ module.exports = function(config) { return results; } - // Lists all books in the Datastore sorted alphabetically by title. // The ``limit`` argument determines the maximum amount of results to // return per page. The ``token`` argument allows requesting additional @@ -92,7 +88,7 @@ module.exports = function(config) { .order('title') .start(token); - ds.runQuery(q, function(err, entities, nextQuery) { + ds.runQuery(q, function (err, entities, nextQuery) { if (err) { return cb(err); } var hasMore = entities.length === limit ? nextQuery.startVal : false; cb(null, entities.map(fromDatastore), hasMore); @@ -108,7 +104,7 @@ module.exports = function(config) { .limit(limit) .start(token); - ds.runQuery(q, function(err, entities, nextQuery) { + ds.runQuery(q, function (err, entities, nextQuery) { if (err) { return cb(err); } var hasMore = entities.length === limit ? nextQuery.startVal : false; cb(null, entities.map(fromDatastore), hasMore); @@ -116,7 +112,6 @@ module.exports = function(config) { } // [END listby] - // Creates a new book or updates an existing book with new data. The provided // data is automatically translated into Datastore format. The book will be // queued for background processing. @@ -135,17 +130,16 @@ module.exports = function(config) { ds.save( entity, - function(err) { + function (err) { data.id = entity.key.id; cb(err, err ? null : data); } ); } - function read(id, cb) { var key = ds.key([kind, parseInt(id, 10)]); - ds.get(key, function(err, entity) { + ds.get(key, function (err, entity) { if (err) { return cb(err); } if (!entity) { return cb({ @@ -157,15 +151,13 @@ module.exports = function(config) { }); } - function _delete(id, cb) { var key = ds.key([kind, parseInt(id, 10)]); ds.delete(key, cb); } - return { - create: function(data, cb) { + create: function (data, cb) { update(null, data, cb); }, read: read, @@ -174,5 +166,4 @@ module.exports = function(config) { list: list, listBy: listBy }; - }; diff --git a/4-auth/lib/images.js b/4-auth/lib/images.js index f2d17de98e..ced0b145c9 100644 --- a/4-auth/lib/images.js +++ b/4-auth/lib/images.js @@ -16,7 +16,7 @@ var gcloud = require('gcloud'); -module.exports = function(gcloudConfig, cloudStorageBucket) { +module.exports = function (gcloudConfig, cloudStorageBucket) { var storage = gcloud.storage(gcloudConfig); var bucket = storage.bucket(cloudStorageBucket); @@ -42,12 +42,12 @@ module.exports = function(gcloudConfig, cloudStorageBucket) { var file = bucket.file(gcsname); var stream = file.createWriteStream(); - stream.on('error', function(err) { + stream.on('error', function (err) { req.file.cloudStorageError = err; next(err); }); - stream.on('finish', function() { + stream.on('finish', function () { req.file.cloudStorageObject = gcsname; req.file.cloudStoragePublicUrl = getPublicUrl(gcsname); next(); @@ -64,7 +64,7 @@ module.exports = function(gcloudConfig, cloudStorageBucket) { var multer = require('multer')({ inMemory: true, fileSize: 5 * 1024 * 1024, // no larger than 5mb - rename: function(fieldname, filename) { + rename: function (fieldname, filename) { // generate a unique filename return filename.replace(/\W+/g, '-').toLowerCase() + Date.now(); } diff --git a/4-auth/lib/oauth2.js b/4-auth/lib/oauth2.js index b514ebc52b..8244ec0e0e 100644 --- a/4-auth/lib/oauth2.js +++ b/4-auth/lib/oauth2.js @@ -37,12 +37,12 @@ // // app.use(oauth2.router); // -// app.get('/users_only', oauth2.required, function(req, res){ +// app.get('/users_only', oauth2.required, function (req, res){ // // only logged-in users can access. // // other users are redirected to the login page. // }); // -// app.get('/aware', oauth2.aware, function(req, res){ +// app.get('/aware', oauth2.aware, function (req, res){ // if(req.oauth2client) // user is logged in. // }); @@ -52,7 +52,7 @@ var googleapis = require('googleapis'); var express = require('express'); -module.exports = function(config) { +module.exports = function (config) { var router = express.Router(); @@ -117,7 +117,7 @@ module.exports = function(config) { // the application and then return them to the original URL they // requested. function authRequired(req, res, next) { - authAware(req, res, function() { + authAware(req, res, function () { if (!req.oauth2client) { req.session.oauth2return = req.originalUrl; return res.redirect('/oauth2/authorize'); @@ -148,7 +148,7 @@ module.exports = function(config) { // when sending a user to this URL then they will be redirected to that // URL when the flow is finished. // [START authorize] - router.get('/oauth2/authorize', function(req, res) { + router.get('/oauth2/authorize', function (req, res) { /* jshint camelcase: false */ var stateToken = generateStateToken(); var authorizeUrl = getClient().generateAuthUrl({ @@ -170,18 +170,18 @@ module.exports = function(config) { // and then redirect the user to the `return` URL specified to // `/oauth2/authorize`. // [START callback] - router.get('/oauth2callback', function(req, res) { + router.get('/oauth2callback', function (req, res) { if (!req.query.code || req.query.state !== req.session.oauth2statetoken) { return res.status(400).send('Invalid auth code or state token.'); } - getClient().getToken(req.query.code, function(err, tokens) { + getClient().getToken(req.query.code, function (err, tokens) { if (err) { return res.status(400).send(err.message); } req.session.oauth2tokens = tokens; /* Get the user's info and store it in the session */ var client = getClient(); client.setCredentials(tokens); - getUserProfile(client, function(err, profile) { + getUserProfile(client, function (err, profile) { if (err) { return res.status('500').send(err.message); } req.session.profile = { id: profile.id, @@ -198,7 +198,7 @@ module.exports = function(config) { // Deletes the user's credentials and profile from the session. // This does not revoke any active tokens. - router.get('/oauth2/logout', function(req, res) { + router.get('/oauth2/logout', function (req, res) { delete req.session.oauth2tokens; delete req.session.profile; res.redirect(req.query.return || req.session.oauth2return || '/'); diff --git a/4-auth/package.json b/4-auth/package.json index 96e651cbe4..748129f804 100644 --- a/4-auth/package.json +++ b/4-auth/package.json @@ -34,12 +34,12 @@ "body-parser": "^1.15.0", "cookie-session": "^2.0.0-alpha.1", "express": "^4.13.4", - "gcloud": "^0.28.0", - "googleapis": "^2.1.7", + "gcloud": "^0.30.2", + "googleapis": "^4.0.0", "jade": "^1.11.0", - "kerberos": "^0.0.18", - "lodash": "^4.5.1", - "mongodb": "^2.1.7", + "kerberos": "^0.0.19", + "lodash": "^4.8.2", + "mongodb": "^2.1.15", "multer": "^1.1.0", "mysql": "^2.10.2", "prompt": "^1.0.0" diff --git a/5-logging/books/model-cloudsql.js b/5-logging/books/model-cloudsql.js index f4bb94ae8b..6f89ddbff2 100644 --- a/5-logging/books/model-cloudsql.js +++ b/5-logging/books/model-cloudsql.js @@ -17,7 +17,7 @@ var extend = require('lodash').assign; var mysql = require('mysql'); -module.exports = function(config) { +module.exports = function (config) { function getConnection() { return mysql.createConnection(extend({ @@ -31,7 +31,7 @@ module.exports = function(config) { var connection = getConnection(); connection.query( 'SELECT * FROM `books` LIMIT ? OFFSET ?', [limit, token], - function(err, results) { + function (err, results) { if (err) { return cb(err); } var hasMore = results.length === limit ? token + results.length : false; cb(null, results, hasMore); @@ -47,7 +47,7 @@ module.exports = function(config) { connection.query( 'SELECT * FROM `books` WHERE `createdById` = ? LIMIT ? OFFSET ?', [userId, limit, token], - function(err, results) { + function (err, results) { if (err) { return cb(err); } var hasMore = results.length === limit ? token + results.length : false; cb(null, results, hasMore); @@ -58,7 +58,7 @@ module.exports = function(config) { function create(data, cb) { var connection = getConnection(); - connection.query('INSERT INTO `books` SET ?', data, function(err, res) { + connection.query('INSERT INTO `books` SET ?', data, function (err, res) { if (err) { return cb(err); } read(res.insertId, cb); }); @@ -69,7 +69,7 @@ module.exports = function(config) { function read(id, cb) { var connection = getConnection(); connection.query( - 'SELECT * FROM `books` WHERE `id` = ?', id, function(err, results) { + 'SELECT * FROM `books` WHERE `id` = ?', id, function (err, results) { if (err) { return cb(err); } if (!results.length) { return cb({ @@ -86,7 +86,7 @@ module.exports = function(config) { function update(id, data, cb) { var connection = getConnection(); connection.query( - 'UPDATE `books` SET ? WHERE `id` = ?', [data, id], function(err) { + 'UPDATE `books` SET ? WHERE `id` = ?', [data, id], function (err) { if (err) { return cb(err); } read(id, cb); }); @@ -122,7 +122,7 @@ if (!module.parent) { 'Running this script directly will allow you to initialize your mysql ' + 'database.\n This script will not modify any existing tables.\n'); - prompt.get(['host', 'user', 'password'], function(err, result) { + prompt.get(['host', 'user', 'password'], function (err, result) { if (err) { return; } createSchema(result); }); @@ -148,7 +148,7 @@ function createSchema(config) { '`createdBy` VARCHAR(255) NULL, ' + '`createdById` VARCHAR(255) NULL, ' + 'PRIMARY KEY (`id`));', - function(err) { + function (err) { if (err) { throw err; } console.log('Successfully created schema'); connection.end(); diff --git a/5-logging/books/model-datastore.js b/5-logging/books/model-datastore.js index 98487b2331..c768d47a2a 100644 --- a/5-logging/books/model-datastore.js +++ b/5-logging/books/model-datastore.js @@ -15,13 +15,11 @@ var gcloud = require('gcloud'); +module.exports = function (config) { -module.exports = function(config) { - - var ds = gcloud.datastore.dataset(config.gcloud); + var ds = gcloud.datastore(config.gcloud); var kind = 'Book'; - // Translates from Datastore's entity format to // the format expected by the application. // @@ -43,7 +41,6 @@ module.exports = function(config) { return obj.data; } - // Translates from the application's format to the datastore's // extended entity property format. It also handles marking any // specified properties as non-indexed. Does not translate the key. @@ -70,7 +67,7 @@ module.exports = function(config) { function toDatastore(obj, nonIndexed) { nonIndexed = nonIndexed || []; var results = []; - Object.keys(obj).forEach(function(k) { + Object.keys(obj).forEach(function (k) { if (obj[k] === undefined) { return; } results.push({ name: k, @@ -81,7 +78,6 @@ module.exports = function(config) { return results; } - // Lists all books in the Datastore sorted alphabetically by title. // The ``limit`` argument determines the maximum amount of results to // return per page. The ``token`` argument allows requesting additional @@ -92,14 +88,13 @@ module.exports = function(config) { .order('title') .start(token); - ds.runQuery(q, function(err, entities, nextQuery) { + ds.runQuery(q, function (err, entities, nextQuery) { if (err) { return cb(err); } var hasMore = entities.length === limit ? nextQuery.startVal : false; cb(null, entities.map(fromDatastore), hasMore); }); } - // Similar to ``list``, but only lists the books created by the specified // user. function listBy(userId, limit, token, cb) { @@ -108,14 +103,13 @@ module.exports = function(config) { .limit(limit) .start(token); - ds.runQuery(q, function(err, entities, nextQuery) { + ds.runQuery(q, function (err, entities, nextQuery) { if (err) { return cb(err); } var hasMore = entities.length === limit ? nextQuery.startVal : false; cb(null, entities.map(fromDatastore), hasMore); }); } - // Creates a new book or updates an existing book with new data. The provided // data is automatically translated into Datastore format. The book will be // queued for background processing. @@ -134,17 +128,16 @@ module.exports = function(config) { ds.save( entity, - function(err) { + function (err) { data.id = entity.key.id; cb(err, err ? null : data); } ); } - function read(id, cb) { var key = ds.key([kind, parseInt(id, 10)]); - ds.get(key, function(err, entity) { + ds.get(key, function (err, entity) { if (err) { return cb(err); } if (!entity) { return cb({ @@ -156,15 +149,13 @@ module.exports = function(config) { }); } - function _delete(id, cb) { var key = ds.key([kind, parseInt(id, 10)]); ds.delete(key, cb); } - return { - create: function(data, cb) { + create: function (data, cb) { update(null, data, cb); }, read: read, @@ -173,5 +164,4 @@ module.exports = function(config) { list: list, listBy: listBy }; - }; diff --git a/5-logging/lib/images.js b/5-logging/lib/images.js index f2d17de98e..ced0b145c9 100644 --- a/5-logging/lib/images.js +++ b/5-logging/lib/images.js @@ -16,7 +16,7 @@ var gcloud = require('gcloud'); -module.exports = function(gcloudConfig, cloudStorageBucket) { +module.exports = function (gcloudConfig, cloudStorageBucket) { var storage = gcloud.storage(gcloudConfig); var bucket = storage.bucket(cloudStorageBucket); @@ -42,12 +42,12 @@ module.exports = function(gcloudConfig, cloudStorageBucket) { var file = bucket.file(gcsname); var stream = file.createWriteStream(); - stream.on('error', function(err) { + stream.on('error', function (err) { req.file.cloudStorageError = err; next(err); }); - stream.on('finish', function() { + stream.on('finish', function () { req.file.cloudStorageObject = gcsname; req.file.cloudStoragePublicUrl = getPublicUrl(gcsname); next(); @@ -64,7 +64,7 @@ module.exports = function(gcloudConfig, cloudStorageBucket) { var multer = require('multer')({ inMemory: true, fileSize: 5 * 1024 * 1024, // no larger than 5mb - rename: function(fieldname, filename) { + rename: function (fieldname, filename) { // generate a unique filename return filename.replace(/\W+/g, '-').toLowerCase() + Date.now(); } diff --git a/5-logging/lib/logging.js b/5-logging/lib/logging.js index 1d45af6af1..c4eba2299b 100644 --- a/5-logging/lib/logging.js +++ b/5-logging/lib/logging.js @@ -17,7 +17,7 @@ var winston = require('winston'); var expressWinston = require('express-winston'); -module.exports = function() { +module.exports = function () { var colorize = process.env.NODE_ENV === 'production' ? false : true; // Logger to capture all requests and output them to the console. diff --git a/5-logging/lib/oauth2.js b/5-logging/lib/oauth2.js index dcbce38ebe..e460e1c258 100644 --- a/5-logging/lib/oauth2.js +++ b/5-logging/lib/oauth2.js @@ -37,12 +37,12 @@ // // app.use(oauth2.router); // -// app.get('/users_only', oauth2.required, function(req, res){ +// app.get('/users_only', oauth2.required, function (req, res){ // // only logged-in users can access. // // other users are redirected to the login page. // }); // -// app.get('/aware', oauth2.aware, function(req, res){ +// app.get('/aware', oauth2.aware, function (req, res){ // if(req.oauth2client) // user is logged in. // }); @@ -52,7 +52,7 @@ var googleapis = require('googleapis'); var express = require('express'); -module.exports = function(config) { +module.exports = function (config) { var router = express.Router(); @@ -114,7 +114,7 @@ module.exports = function(config) { // the application and then return them to the original URL they // requested. function authRequired(req, res, next) { - authAware(req, res, function() { + authAware(req, res, function () { if (!req.oauth2client) { req.session.oauth2return = req.originalUrl; return res.redirect('/oauth2/authorize'); @@ -143,7 +143,7 @@ module.exports = function(config) { // to `/oauth2callback`. If the `return` query parameter is specified // when sending a user to this URL then they will be redirected to that // URL when the flow is finished. - router.get('/oauth2/authorize', function(req, res) { + router.get('/oauth2/authorize', function (req, res) { /* jshint camelcase: false */ var stateToken = generateStateToken(); var authorizeUrl = getClient().generateAuthUrl({ @@ -163,18 +163,18 @@ module.exports = function(config) { // tokens), save the credentials and user's profile information to the session // and then redirect the user to the `return` URL specified to // `/oauth2/authorize`. - router.get('/oauth2callback', function(req, res) { + router.get('/oauth2callback', function (req, res) { if (!req.query.code || req.query.state !== req.session.oauth2statetoken) { return res.status(400).send('Invalid auth code or state token.'); } - getClient().getToken(req.query.code, function(err, tokens) { + getClient().getToken(req.query.code, function (err, tokens) { if (err) { return res.status(400).send(err.message); } req.session.oauth2tokens = tokens; /* Get the user's info and store it in the session */ var client = getClient(); client.setCredentials(tokens); - getUserProfile(client, function(err, profile) { + getUserProfile(client, function (err, profile) { if (err) { return res.status('500').send(err.message); } req.session.profile = { id: profile.id, @@ -190,7 +190,7 @@ module.exports = function(config) { // Deletes the user's credentials and profile from the session. // This does not revoke any active tokens. - router.get('/oauth2/logout', function(req, res) { + router.get('/oauth2/logout', function (req, res) { delete req.session.oauth2tokens; delete req.session.profile; res.redirect(req.query.return || req.session.oauth2return || '/'); diff --git a/5-logging/package.json b/5-logging/package.json index 42fa55d8fe..af6faa8805 100644 --- a/5-logging/package.json +++ b/5-logging/package.json @@ -34,17 +34,17 @@ "body-parser": "^1.15.0", "cookie-session": "^2.0.0-alpha.1", "express": "^4.13.4", - "express-winston": "^1.2.0", - "gcloud": "^0.28.0", - "googleapis": "^2.1.7", + "express-winston": "^1.3.0", + "gcloud": "^0.30.2", + "googleapis": "^4.0.0", "jade": "^1.11.0", - "kerberos": "^0.0.18", - "lodash": "^4.5.1", - "mongodb": "^2.1.7", + "kerberos": "^0.0.19", + "lodash": "^4.8.2", + "mongodb": "^2.1.15", "multer": "^1.1.0", "mysql": "^2.10.2", "prompt": "^1.0.0", - "winston": "^2.1.1" + "winston": "^2.2.0" }, "devDependencies": { "jshint": "^2.9.1", diff --git a/6-pubsub/books/model-cloudsql.js b/6-pubsub/books/model-cloudsql.js index af068a31dc..d9209bbada 100644 --- a/6-pubsub/books/model-cloudsql.js +++ b/6-pubsub/books/model-cloudsql.js @@ -29,7 +29,7 @@ module.exports = function (config, background) { var connection = getConnection(); connection.query( 'SELECT * FROM `books` LIMIT ? OFFSET ?', [limit, token], - function(err, results) { + function (err, results) { if (err) { return cb(err); } var hasMore = results.length === limit ? token + results.length : false; cb(null, results, hasMore); @@ -44,7 +44,7 @@ module.exports = function (config, background) { connection.query( 'SELECT * FROM `books` WHERE `createdById` = ? LIMIT ? OFFSET ?', [userId, limit, token], - function(err, results) { + function (err, results) { if (err) { return cb(err); } var hasMore = results.length === limit ? token + results.length : false; cb(null, results, hasMore); @@ -55,7 +55,7 @@ module.exports = function (config, background) { // [START create] function create(data, cb) { var connection = getConnection(); - connection.query('INSERT INTO `books` SET ?', data, function(err, res) { + connection.query('INSERT INTO `books` SET ?', data, function (err, res) { if (err) { return cb(err); } background.queueBook(res.insertId); read(res.insertId, cb); @@ -67,7 +67,7 @@ module.exports = function (config, background) { function read(id, cb) { var connection = getConnection(); connection.query( - 'SELECT * FROM `books` WHERE `id` = ?', id, function(err, results) { + 'SELECT * FROM `books` WHERE `id` = ?', id, function (err, results) { if (err) { return cb(err); } if (!results.length) { return cb({ @@ -84,7 +84,7 @@ module.exports = function (config, background) { function update(id, data, cb) { var connection = getConnection(); connection.query( - 'UPDATE `books` SET ? WHERE `id` = ?', [data, id], function(err) { + 'UPDATE `books` SET ? WHERE `id` = ?', [data, id], function (err) { if (err) { return cb(err); } background.queueBook(id); read(id, cb); @@ -118,7 +118,7 @@ if (!module.parent) { 'Running this script directly will allow you to initialize your mysql ' + 'database.\n This script will not modify any existing tables.\n'); - prompt.get(['host', 'user', 'password'], function(err, result) { + prompt.get(['host', 'user', 'password'], function (err, result) { if (err) { return; } createSchema(result); }); @@ -143,7 +143,7 @@ function createSchema(config) { '`createdBy` VARCHAR(255) NULL, ' + '`createdById` VARCHAR(255) NULL, ' + 'PRIMARY KEY (`id`));', - function(err) { + function (err) { if (err) { throw err; } console.log('Successfully created schema'); connection.end(); diff --git a/6-pubsub/books/model-datastore.js b/6-pubsub/books/model-datastore.js index 49da6cfbd0..d9aa171774 100644 --- a/6-pubsub/books/model-datastore.js +++ b/6-pubsub/books/model-datastore.js @@ -17,7 +17,7 @@ var gcloud = require('gcloud'); module.exports = function (config, background) { - var ds = gcloud.datastore.dataset(config.gcloud); + var ds = gcloud.datastore(config.gcloud); var kind = 'Book'; // Translates from Datastore's entity format to @@ -67,7 +67,7 @@ module.exports = function (config, background) { function toDatastore(obj, nonIndexed) { nonIndexed = nonIndexed || []; var results = []; - Object.keys(obj).forEach(function(k) { + Object.keys(obj).forEach(function (k) { if (obj[k] === undefined) { return; } results.push({ name: k, @@ -88,7 +88,7 @@ module.exports = function (config, background) { .order('title') .start(token); - ds.runQuery(q, function(err, entities, nextQuery) { + ds.runQuery(q, function (err, entities, nextQuery) { if (err) { return cb(err); } var hasMore = entities.length === limit ? nextQuery.startVal : false; cb(null, entities.map(fromDatastore), hasMore); @@ -103,7 +103,7 @@ module.exports = function (config, background) { .limit(limit) .start(token); - ds.runQuery(q, function(err, entities, nextQuery) { + ds.runQuery(q, function (err, entities, nextQuery) { if (err) { return cb(err); } var hasMore = entities.length === limit ? nextQuery.startVal : false; cb(null, entities.map(fromDatastore), hasMore); @@ -129,7 +129,7 @@ module.exports = function (config, background) { ds.save( entity, - function(err) { + function (err) { if(err) { return cb(err); } data.id = entity.key.id; background.queueBook(data.id); @@ -141,7 +141,7 @@ module.exports = function (config, background) { function read(id, cb) { var key = ds.key([kind, parseInt(id, 10)]); - ds.get(key, function(err, entity) { + ds.get(key, function (err, entity) { if (err) { return cb(err); } if (!entity) { return cb({ @@ -159,7 +159,7 @@ module.exports = function (config, background) { } return { - create: function(data, cb) { + create: function (data, cb) { update(null, data, cb); }, read: read, diff --git a/6-pubsub/lib/background.js b/6-pubsub/lib/background.js index fa2f3f37cc..1fbd7e3e22 100644 --- a/6-pubsub/lib/background.js +++ b/6-pubsub/lib/background.js @@ -20,7 +20,7 @@ var topicName = 'book-process-queue'; var subscriptionName = 'shared-worker-subscription'; -module.exports = function(gcloudConfig, logging) { +module.exports = function (gcloudConfig, logging) { var pubsub = gcloud.pubsub(config.gcloud); @@ -32,7 +32,7 @@ module.exports = function(gcloudConfig, logging) { // will essentially drop any messages. // [START topic] function getTopic(cb) { - pubsub.createTopic(topicName, function(err, topic) { + pubsub.createTopic(topicName, function (err, topic) { // topic already exists. if (err && err.code === 409) { return cb(null, pubsub.topic(topicName)); @@ -49,16 +49,16 @@ module.exports = function(gcloudConfig, logging) { // to each worker. // [START subscribe] function subscribe(cb) { - getTopic(function(err, topic) { + getTopic(function (err, topic) { if (err) { return cb(err); } topic.subscribe(subscriptionName, { autoAck: true, reuseExisting: true - }, function(err, subscription) { + }, function (err, subscription) { if (err) { return cb(err); } - subscription.on('message', function(message) { + subscription.on('message', function (message) { cb(null, message.data); }); @@ -74,7 +74,7 @@ module.exports = function(gcloudConfig, logging) { // Adds a book to the queue to be processed by the worker. // [START queue] function queueBook(bookId) { - getTopic(function(err, topic) { + getTopic(function (err, topic) { if (err) { logging.error('Error occurred while getting pubsub topic', err); return; @@ -85,7 +85,7 @@ module.exports = function(gcloudConfig, logging) { action: 'processBook', bookId: bookId } - }, function(err) { + }, function (err) { if (err) { logging.error('Error occurred while queuing background task', err); } else { diff --git a/6-pubsub/lib/images.js b/6-pubsub/lib/images.js index e1bbde18b5..27ac8609b4 100644 --- a/6-pubsub/lib/images.js +++ b/6-pubsub/lib/images.js @@ -31,18 +31,18 @@ module.exports = function (gcloudConfig, cloudStorageBucket, logging) { request .get(sourceUrl) - .on('error', function(err) { + .on('error', function (err) { logging.warn('Could not fetch image ' + sourceUrl, err); cb(err); }) .pipe(file.createWriteStream()) - .on('finish', function() { + .on('finish', function () { logging.info('Uploaded image ' + destFileName); - file.makePublic(function(){ + file.makePublic(function (){ cb(null, getPublicUrl(destFileName)); }); }) - .on('error', function(err) { + .on('error', function (err) { logging.error('Could not upload image', err); cb(err); }); @@ -70,12 +70,12 @@ module.exports = function (gcloudConfig, cloudStorageBucket, logging) { var file = bucket.file(gcsname); var stream = file.createWriteStream(); - stream.on('error', function(err) { + stream.on('error', function (err) { req.file.cloudStorageError = err; next(err); }); - stream.on('finish', function() { + stream.on('finish', function () { req.file.cloudStorageObject = gcsname; req.file.cloudStoragePublicUrl = getPublicUrl(gcsname); next(); @@ -92,7 +92,7 @@ module.exports = function (gcloudConfig, cloudStorageBucket, logging) { var multer = require('multer')({ inMemory: true, fileSize: 5 * 1024 * 1024, // no larger than 5mb - rename: function(fieldname, filename) { + rename: function (fieldname, filename) { // generate a unique filename return filename.replace(/\W+/g, '-').toLowerCase() + Date.now(); } diff --git a/6-pubsub/lib/logging.js b/6-pubsub/lib/logging.js index 133411900b..3957338dd0 100644 --- a/6-pubsub/lib/logging.js +++ b/6-pubsub/lib/logging.js @@ -17,7 +17,7 @@ var winston = require('winston'); var expressWinston = require('express-winston'); -module.exports = function() { +module.exports = function () { var colorize = process.env.NODE_ENV === 'production' ? false : true; // Logger to capture all requests and output them to the console. diff --git a/6-pubsub/lib/oauth2.js b/6-pubsub/lib/oauth2.js index dcbce38ebe..e460e1c258 100644 --- a/6-pubsub/lib/oauth2.js +++ b/6-pubsub/lib/oauth2.js @@ -37,12 +37,12 @@ // // app.use(oauth2.router); // -// app.get('/users_only', oauth2.required, function(req, res){ +// app.get('/users_only', oauth2.required, function (req, res){ // // only logged-in users can access. // // other users are redirected to the login page. // }); // -// app.get('/aware', oauth2.aware, function(req, res){ +// app.get('/aware', oauth2.aware, function (req, res){ // if(req.oauth2client) // user is logged in. // }); @@ -52,7 +52,7 @@ var googleapis = require('googleapis'); var express = require('express'); -module.exports = function(config) { +module.exports = function (config) { var router = express.Router(); @@ -114,7 +114,7 @@ module.exports = function(config) { // the application and then return them to the original URL they // requested. function authRequired(req, res, next) { - authAware(req, res, function() { + authAware(req, res, function () { if (!req.oauth2client) { req.session.oauth2return = req.originalUrl; return res.redirect('/oauth2/authorize'); @@ -143,7 +143,7 @@ module.exports = function(config) { // to `/oauth2callback`. If the `return` query parameter is specified // when sending a user to this URL then they will be redirected to that // URL when the flow is finished. - router.get('/oauth2/authorize', function(req, res) { + router.get('/oauth2/authorize', function (req, res) { /* jshint camelcase: false */ var stateToken = generateStateToken(); var authorizeUrl = getClient().generateAuthUrl({ @@ -163,18 +163,18 @@ module.exports = function(config) { // tokens), save the credentials and user's profile information to the session // and then redirect the user to the `return` URL specified to // `/oauth2/authorize`. - router.get('/oauth2callback', function(req, res) { + router.get('/oauth2callback', function (req, res) { if (!req.query.code || req.query.state !== req.session.oauth2statetoken) { return res.status(400).send('Invalid auth code or state token.'); } - getClient().getToken(req.query.code, function(err, tokens) { + getClient().getToken(req.query.code, function (err, tokens) { if (err) { return res.status(400).send(err.message); } req.session.oauth2tokens = tokens; /* Get the user's info and store it in the session */ var client = getClient(); client.setCredentials(tokens); - getUserProfile(client, function(err, profile) { + getUserProfile(client, function (err, profile) { if (err) { return res.status('500').send(err.message); } req.session.profile = { id: profile.id, @@ -190,7 +190,7 @@ module.exports = function(config) { // Deletes the user's credentials and profile from the session. // This does not revoke any active tokens. - router.get('/oauth2/logout', function(req, res) { + router.get('/oauth2/logout', function (req, res) { delete req.session.oauth2tokens; delete req.session.profile; res.redirect(req.query.return || req.session.oauth2return || '/'); diff --git a/6-pubsub/package.json b/6-pubsub/package.json index fc88a3d9d4..ec3914fda2 100644 --- a/6-pubsub/package.json +++ b/6-pubsub/package.json @@ -34,18 +34,18 @@ "body-parser": "^1.15.0", "cookie-session": "^2.0.0-alpha.1", "express": "^4.13.4", - "express-winston": "^1.2.0", - "gcloud": "^0.28.0", - "googleapis": "^2.1.7", + "express-winston": "^1.3.0", + "gcloud": "^0.30.2", + "googleapis": "^4.0.0", "jade": "^1.11.0", - "kerberos": "^0.0.18", - "lodash": "^4.5.1", - "mongodb": "^2.1.7", + "kerberos": "^0.0.19", + "lodash": "^4.8.2", + "mongodb": "^2.1.15", "multer": "^1.1.0", "mysql": "^2.10.2", "prompt": "^1.0.0", - "request": "^2.69.0", - "winston": "^2.1.1" + "request": "^2.70.0", + "winston": "^2.2.0" }, "devDependencies": { "jshint": "^2.9.1", diff --git a/6-pubsub/worker.js b/6-pubsub/worker.js index 6b33e0432a..5ae71df58a 100644 --- a/6-pubsub/worker.js +++ b/6-pubsub/worker.js @@ -23,17 +23,15 @@ var images = require('./lib/images')( config.gcloud, config.cloudStorageBucket, logging); var background = require('./lib/background')(config.gcloud, logging); - // We'll pass this to the model so that we don't get an infinite loop of book // processing requests. var backgroundStub = { - queueBook: function(){} + queueBook: function (){} }; var model = require('./books/model-' + config.dataBackend)( config, backgroundStub); - // When running on Google App Engine Managed VMs, the worker needs // to respond to HTTP requests and can optionally supply a health check. // [START server] @@ -41,8 +39,7 @@ var app = express(); app.use(logging.requestLogger); - -app.get('/_ah/health', function(req, res) { +app.get('/_ah/health', function (req, res) { res.status(200).send('ok'); }); @@ -50,39 +47,39 @@ app.get('/_ah/health', function(req, res) { // Keep count of how many books this worker has processed var bookCount = 0; -app.get('/', function(req, res) { +app.get('/', function (req, res) { res.send('This worker has processed ' + bookCount + ' books.'); }); - app.use(logging.errorLogger); +if (module === require.main) { + var server = app.listen(config.port || 8080, function () { + var host = server.address().address; + var port = server.address().port; -var server = app.listen(config.port || 8080, function () { - var host = server.address().address; - var port = server.address().port; - - console.log('App listening at http://%s:%s', host, port); -}); + console.log('App listening at http://%s:%s', host, port); + }); +} // [END server] - -// Subscribe to Cloud Pub/Sub and receive messages to process books. -// The subscription will continue to listen for messages until the process -// is killed. -// [START subscribe] -background.subscribe(function(err, message) { - // Any errors received are considered fatal. - if(err) { throw err; } - if (message.action === 'processBook') { - logging.info('Received request to process book ' + message.bookId); - processBook(message.bookId); - } else { - logging.warn('Unknown request', message); - } -}); -// [END subscribe] - +if (module === require.main) { + // Subscribe to Cloud Pub/Sub and receive messages to process books. + // The subscription will continue to listen for messages until the process + // is killed. + // [START subscribe] + background.subscribe(function (err, message) { + // Any errors received are considered fatal. + if(err) { throw err; } + if (message.action === 'processBook') { + logging.info('Received request to process book ' + message.bookId); + processBook(message.bookId); + } else { + logging.warn('Unknown request', message); + } + }); + // [END subscribe] +} // Processes a book by reading its existing data, attempting to find // more information, and updating the database with the new information. @@ -90,16 +87,16 @@ background.subscribe(function(err, message) { function processBook(bookId) { waterfall([ // Load the current data - function(cb) { + function (cb) { model.read(bookId, cb); }, // Find the information from Google findBookInfo, // Save the updated data - function(updated, cb) { + function (updated, cb) { model.update(updated.id, updated, cb, true); } - ], function(err) { + ], function (err) { if (err) { logging.error('Error occurred', err); } else { @@ -116,7 +113,7 @@ function processBook(bookId) { // if available. // [START find] function findBookInfo(book, cb) { - queryBooksApi(book.title, function(err, r) { + queryBooksApi(book.title, function (err, r) { if (err) { return cb(err); } if (!r.items) { return cb('Not found'); } var top = r.items[0]; @@ -137,7 +134,7 @@ function findBookInfo(book, cb) { var imageName = book.id + '.jpg'; images.downloadAndUploadImage( - imageUrl, imageName, function(err, publicUrl) { + imageUrl, imageName, function (err, publicUrl) { if (!err) { book.imageUrl = publicUrl; } cb(null, book); }); @@ -153,7 +150,7 @@ function queryBooksApi(query, cb) { request( 'https://www.googleapis.com/books/v1/volumes?q=' + encodeURIComponent(query), - function(err, resp, body) { + function (err, resp, body) { if (err || resp.statusCode !== 200) { return cb(err || 'Response returned ' + resp.statusCode); } @@ -163,5 +160,7 @@ function queryBooksApi(query, cb) { } // [END query] - - +exports.app = app; +exports.processBook = processBook; +exports.findBookInfo = findBookInfo; +exports.queryBooksApi = queryBooksApi; diff --git a/7-gce/books/model-cloudsql.js b/7-gce/books/model-cloudsql.js index 63f3526a73..8d2f7cd988 100644 --- a/7-gce/books/model-cloudsql.js +++ b/7-gce/books/model-cloudsql.js @@ -29,7 +29,7 @@ module.exports = function (config, background) { var connection = getConnection(); connection.query( 'SELECT * FROM `books` LIMIT ? OFFSET ?', [limit, token], - function(err, results) { + function (err, results) { if (err) { return cb(err); } var hasMore = results.length === limit ? token + results.length : false; cb(null, results, hasMore); @@ -44,7 +44,7 @@ module.exports = function (config, background) { connection.query( 'SELECT * FROM `books` WHERE `createdById` = ? LIMIT ? OFFSET ?', [userId, limit, token], - function(err, results) { + function (err, results) { if (err) { return cb(err); } var hasMore = results.length === limit ? token + results.length : false; cb(null, results, hasMore); @@ -54,7 +54,7 @@ module.exports = function (config, background) { function create(data, cb) { var connection = getConnection(); - connection.query('INSERT INTO `books` SET ?', data, function(err, res) { + connection.query('INSERT INTO `books` SET ?', data, function (err, res) { if (err) { return cb(err); } background.queueBook(res.insertId); read(res.insertId, cb); @@ -65,7 +65,7 @@ module.exports = function (config, background) { function read(id, cb) { var connection = getConnection(); connection.query( - 'SELECT * FROM `books` WHERE `id` = ?', id, function(err, results) { + 'SELECT * FROM `books` WHERE `id` = ?', id, function (err, results) { if (err) { return cb(err); } if (!results.length) { return cb({ @@ -81,7 +81,7 @@ module.exports = function (config, background) { function update(id, data, cb) { var connection = getConnection(); connection.query( - 'UPDATE `books` SET ? WHERE `id` = ?', [data, id], function(err) { + 'UPDATE `books` SET ? WHERE `id` = ?', [data, id], function (err) { if (err) { return cb(err); } background.queueBook(id); read(id, cb); @@ -114,7 +114,7 @@ if (!module.parent) { 'Running this script directly will allow you to initialize your mysql ' + 'database.\n This script will not modify any existing tables.\n'); - prompt.get(['host', 'user', 'password'], function(err, result) { + prompt.get(['host', 'user', 'password'], function (err, result) { if (err) { return; } createSchema(result); }); @@ -139,7 +139,7 @@ function createSchema(config) { '`createdBy` VARCHAR(255) NULL, ' + '`createdById` VARCHAR(255) NULL, ' + 'PRIMARY KEY (`id`));', - function(err) { + function (err) { if (err) { throw err; } console.log('Successfully created schema'); connection.end(); diff --git a/7-gce/books/model-datastore.js b/7-gce/books/model-datastore.js index affc980b35..933f736efe 100644 --- a/7-gce/books/model-datastore.js +++ b/7-gce/books/model-datastore.js @@ -17,7 +17,7 @@ var gcloud = require('gcloud'); module.exports = function (config, background) { - var ds = gcloud.datastore.dataset(config.gcloud); + var ds = gcloud.datastore(config.gcloud); var kind = 'Book'; // Translates from Datastore's entity format to @@ -67,7 +67,7 @@ module.exports = function (config, background) { function toDatastore(obj, nonIndexed) { nonIndexed = nonIndexed || []; var results = []; - Object.keys(obj).forEach(function(k) { + Object.keys(obj).forEach(function (k) { if (obj[k] === undefined) { return; } results.push({ name: k, @@ -88,7 +88,7 @@ module.exports = function (config, background) { .order('title') .start(token); - ds.runQuery(q, function(err, entities, nextQuery) { + ds.runQuery(q, function (err, entities, nextQuery) { if (err) { return cb(err); } var hasMore = entities.length === limit ? nextQuery.startVal : false; cb(null, entities.map(fromDatastore), hasMore); @@ -103,7 +103,7 @@ module.exports = function (config, background) { .limit(limit) .start(token); - ds.runQuery(q, function(err, entities, nextQuery) { + ds.runQuery(q, function (err, entities, nextQuery) { if (err) { return cb(err); } var hasMore = entities.length === limit ? nextQuery.startVal : false; cb(null, entities.map(fromDatastore), hasMore); @@ -128,7 +128,7 @@ module.exports = function (config, background) { ds.save( entity, - function(err) { + function (err) { if(err) { return cb(err); } data.id = entity.key.id; background.queueBook(data.id); @@ -139,7 +139,7 @@ module.exports = function (config, background) { function read(id, cb) { var key = ds.key([kind, parseInt(id, 10)]); - ds.get(key, function(err, entity) { + ds.get(key, function (err, entity) { if (err) { return cb(err); } if (!entity) { return cb({ @@ -157,7 +157,7 @@ module.exports = function (config, background) { } return { - create: function(data, cb) { + create: function (data, cb) { update(null, data, cb); }, read: read, diff --git a/7-gce/lib/background.js b/7-gce/lib/background.js index b20b7f4707..21f62f794f 100644 --- a/7-gce/lib/background.js +++ b/7-gce/lib/background.js @@ -20,7 +20,7 @@ var topicName = 'book-process-queue'; var subscriptionName = 'shared-worker-subscription'; -module.exports = function(gcloudConfig, logging) { +module.exports = function (gcloudConfig, logging) { var pubsub = gcloud.pubsub(config.gcloud); @@ -31,7 +31,7 @@ module.exports = function(gcloudConfig, logging) { // publishing anything to it as topics without subscribers // will essentially drop any messages. function getTopic(cb) { - pubsub.createTopic(topicName, function(err, topic) { + pubsub.createTopic(topicName, function (err, topic) { // topic already exists. if (err && err.code === 409) { return cb(null, pubsub.topic(topicName)); @@ -46,16 +46,16 @@ module.exports = function(gcloudConfig, logging) { // subscription, which means that pub/sub will evenly distribute messages // to each worker. function subscribe(cb) { - getTopic(function(err, topic) { + getTopic(function (err, topic) { if (err) { return cb(err); } topic.subscribe(subscriptionName, { autoAck: true, reuseExisting: true - }, function(err, subscription) { + }, function (err, subscription) { if (err) { return cb(err); } - subscription.on('message', function(message) { + subscription.on('message', function (message) { cb(null, message.data); }); @@ -69,7 +69,7 @@ module.exports = function(gcloudConfig, logging) { // Adds a book to the queue to be processed by the worker. function queueBook(bookId) { - getTopic(function(err, topic) { + getTopic(function (err, topic) { if (err) { logging.error('Error occurred while getting pubsub topic', err); return; @@ -80,7 +80,7 @@ module.exports = function(gcloudConfig, logging) { action: 'processBook', bookId: bookId } - }, function(err) { + }, function (err) { if (err) { logging.error('Error occurred while queuing background task', err); } else { diff --git a/7-gce/lib/images.js b/7-gce/lib/images.js index e6cc36e0fe..8bf9f56bb4 100644 --- a/7-gce/lib/images.js +++ b/7-gce/lib/images.js @@ -30,18 +30,18 @@ module.exports = function (gcloudConfig, cloudStorageBucket, logging) { request .get(sourceUrl) - .on('error', function(err) { + .on('error', function (err) { logging.warn('Could not fetch image ' + sourceUrl, err); cb(err); }) .pipe(file.createWriteStream()) - .on('finish', function() { + .on('finish', function () { logging.info('Uploaded image ' + destFileName); - file.makePublic(function(){ + file.makePublic(function (){ cb(null, getPublicUrl(destFileName)); }); }) - .on('error', function(err) { + .on('error', function (err) { logging.error('Could not upload image', err); cb(err); }); @@ -68,12 +68,12 @@ module.exports = function (gcloudConfig, cloudStorageBucket, logging) { var file = bucket.file(gcsname); var stream = file.createWriteStream(); - stream.on('error', function(err) { + stream.on('error', function (err) { req.file.cloudStorageError = err; next(err); }); - stream.on('finish', function() { + stream.on('finish', function () { req.file.cloudStorageObject = gcsname; req.file.cloudStoragePublicUrl = getPublicUrl(gcsname); next(); @@ -90,7 +90,7 @@ module.exports = function (gcloudConfig, cloudStorageBucket, logging) { var multer = require('multer')({ inMemory: true, fileSize: 5 * 1024 * 1024, // no larger than 5mb - rename: function(fieldname, filename) { + rename: function (fieldname, filename) { // generate a unique filename return filename.replace(/\W+/g, '-').toLowerCase() + Date.now(); } diff --git a/7-gce/lib/logging.js b/7-gce/lib/logging.js index 133411900b..3957338dd0 100644 --- a/7-gce/lib/logging.js +++ b/7-gce/lib/logging.js @@ -17,7 +17,7 @@ var winston = require('winston'); var expressWinston = require('express-winston'); -module.exports = function() { +module.exports = function () { var colorize = process.env.NODE_ENV === 'production' ? false : true; // Logger to capture all requests and output them to the console. diff --git a/7-gce/lib/oauth2.js b/7-gce/lib/oauth2.js index dcbce38ebe..e460e1c258 100644 --- a/7-gce/lib/oauth2.js +++ b/7-gce/lib/oauth2.js @@ -37,12 +37,12 @@ // // app.use(oauth2.router); // -// app.get('/users_only', oauth2.required, function(req, res){ +// app.get('/users_only', oauth2.required, function (req, res){ // // only logged-in users can access. // // other users are redirected to the login page. // }); // -// app.get('/aware', oauth2.aware, function(req, res){ +// app.get('/aware', oauth2.aware, function (req, res){ // if(req.oauth2client) // user is logged in. // }); @@ -52,7 +52,7 @@ var googleapis = require('googleapis'); var express = require('express'); -module.exports = function(config) { +module.exports = function (config) { var router = express.Router(); @@ -114,7 +114,7 @@ module.exports = function(config) { // the application and then return them to the original URL they // requested. function authRequired(req, res, next) { - authAware(req, res, function() { + authAware(req, res, function () { if (!req.oauth2client) { req.session.oauth2return = req.originalUrl; return res.redirect('/oauth2/authorize'); @@ -143,7 +143,7 @@ module.exports = function(config) { // to `/oauth2callback`. If the `return` query parameter is specified // when sending a user to this URL then they will be redirected to that // URL when the flow is finished. - router.get('/oauth2/authorize', function(req, res) { + router.get('/oauth2/authorize', function (req, res) { /* jshint camelcase: false */ var stateToken = generateStateToken(); var authorizeUrl = getClient().generateAuthUrl({ @@ -163,18 +163,18 @@ module.exports = function(config) { // tokens), save the credentials and user's profile information to the session // and then redirect the user to the `return` URL specified to // `/oauth2/authorize`. - router.get('/oauth2callback', function(req, res) { + router.get('/oauth2callback', function (req, res) { if (!req.query.code || req.query.state !== req.session.oauth2statetoken) { return res.status(400).send('Invalid auth code or state token.'); } - getClient().getToken(req.query.code, function(err, tokens) { + getClient().getToken(req.query.code, function (err, tokens) { if (err) { return res.status(400).send(err.message); } req.session.oauth2tokens = tokens; /* Get the user's info and store it in the session */ var client = getClient(); client.setCredentials(tokens); - getUserProfile(client, function(err, profile) { + getUserProfile(client, function (err, profile) { if (err) { return res.status('500').send(err.message); } req.session.profile = { id: profile.id, @@ -190,7 +190,7 @@ module.exports = function(config) { // Deletes the user's credentials and profile from the session. // This does not revoke any active tokens. - router.get('/oauth2/logout', function(req, res) { + router.get('/oauth2/logout', function (req, res) { delete req.session.oauth2tokens; delete req.session.profile; res.redirect(req.query.return || req.session.oauth2return || '/'); diff --git a/7-gce/package.json b/7-gce/package.json index fc88a3d9d4..ec3914fda2 100644 --- a/7-gce/package.json +++ b/7-gce/package.json @@ -34,18 +34,18 @@ "body-parser": "^1.15.0", "cookie-session": "^2.0.0-alpha.1", "express": "^4.13.4", - "express-winston": "^1.2.0", - "gcloud": "^0.28.0", - "googleapis": "^2.1.7", + "express-winston": "^1.3.0", + "gcloud": "^0.30.2", + "googleapis": "^4.0.0", "jade": "^1.11.0", - "kerberos": "^0.0.18", - "lodash": "^4.5.1", - "mongodb": "^2.1.7", + "kerberos": "^0.0.19", + "lodash": "^4.8.2", + "mongodb": "^2.1.15", "multer": "^1.1.0", "mysql": "^2.10.2", "prompt": "^1.0.0", - "request": "^2.69.0", - "winston": "^2.1.1" + "request": "^2.70.0", + "winston": "^2.2.0" }, "devDependencies": { "jshint": "^2.9.1", diff --git a/7-gce/worker.js b/7-gce/worker.js index 19cc848e4a..532786bf32 100644 --- a/7-gce/worker.js +++ b/7-gce/worker.js @@ -27,7 +27,7 @@ var background = require('./lib/background')(config.gcloud, logging); // We'll pass this to the model so that we don't get an infinite loop of book // processing requests. var backgroundStub = { - queueBook: function(){} + queueBook: function (){} }; var model = require('./books/model-' + config.dataBackend)( @@ -41,7 +41,7 @@ var app = express(); app.use(logging.requestLogger); -app.get('/_ah/health', function(req, res) { +app.get('/_ah/health', function (req, res) { res.status(200).send('ok'); }); @@ -49,7 +49,7 @@ app.get('/_ah/health', function(req, res) { // Keep count of how many books this worker has processed var bookCount = 0; -app.get('/', function(req, res) { +app.get('/', function (req, res) { res.send('This worker has processed ' + bookCount + ' books.'); }); @@ -68,7 +68,7 @@ var server = app.listen(config.port || 8080, function () { // Subscribe to Cloud Pub/Sub and receive messages to process books. // The subscription will continue to listen for messages until the process // is killed. -background.subscribe(function(err, message) { +background.subscribe(function (err, message) { // Any errors received are considered fatal. if(err) { throw err; } if (message.action === 'processBook') { @@ -85,16 +85,16 @@ background.subscribe(function(err, message) { function processBook(bookId) { waterfall([ // Load the current data - function(cb) { + function (cb) { model.read(bookId, cb); }, // Find the information from Google findBookInfo, // Save the updated data - function(updated, cb) { + function (updated, cb) { model.update(updated.id, updated, cb, true); } - ], function(err) { + ], function (err) { if (err) { logging.error('Error occurred', err); } else { @@ -109,7 +109,7 @@ function processBook(bookId) { // the book's data. Also uploads a cover image to Cloud Storage // if available. function findBookInfo(book, cb) { - queryBooksApi(book.title, function(err, r) { + queryBooksApi(book.title, function (err, r) { if (err) { return cb(err); } if (!r.items) { return cb('Not found'); } var top = r.items[0]; @@ -130,7 +130,7 @@ function findBookInfo(book, cb) { var imageName = book.id + '.jpg'; images.downloadAndUploadImage( - imageUrl, imageName, function(err, publicUrl) { + imageUrl, imageName, function (err, publicUrl) { if (!err) { book.imageUrl = publicUrl; } cb(null, book); }); @@ -144,7 +144,7 @@ function queryBooksApi(query, cb) { request( 'https://www.googleapis.com/books/v1/volumes?q=' + encodeURIComponent(query), - function(err, resp, body) { + function (err, resp, body) { if (err || resp.statusCode !== 200) { return cb(err || 'Response returned ' + resp.statusCode); } diff --git a/package.json b/package.json index 60f4f79c0a..65baa34d79 100644 --- a/package.json +++ b/package.json @@ -32,21 +32,21 @@ "body-parser": "^1.15.0", "cookie-session": "^2.0.0-alpha.1", "express": "^4.13.4", - "express-winston": "^1.2.0", + "express-winston": "^1.3.0", "gcloud": "^0.28.0", "googleapis": "^2.1.7", "jade": "^1.11.0", "kerberos": "^0.0.18", - "lodash": "^4.5.1", - "mongodb": "^2.1.7", + "lodash": "^4.8.2", + "mongodb": "^2.1.15", "multer": "^1.1.0", "mysql": "^2.10.2", "prompt": "^1.0.0", - "request": "^2.69.0", - "winston": "^2.1.1" + "request": "^2.70.0", + "winston": "^2.2.0" }, "devDependencies": { - "coveralls": "^2.11.6", + "coveralls": "^2.11.9", "istanbul": "^0.4.2", "jshint": "^2.9.1", "mocha": "^2.4.5",