From 9219a48598ea93e7780db8a651fbb83749b12d3d Mon Sep 17 00:00:00 2001 From: Gus Class Date: Wed, 26 Jul 2017 17:51:19 -0700 Subject: [PATCH 1/9] Upgrades vision to partial-GAPIC --- vision/detect.js | 188 ++++++++++++-------------- vision/faceDetection.js | 31 +++-- vision/package.json | 2 +- vision/quickstart.js | 6 +- vision/system-test/detect.test.js | 4 +- vision/system-test/quickstart.test.js | 41 +----- 6 files changed, 119 insertions(+), 153 deletions(-) diff --git a/vision/detect.js b/vision/detect.js index 6df64401fa..5db9fb81d8 100644 --- a/vision/detect.js +++ b/vision/detect.js @@ -26,18 +26,17 @@ function detectFaces (fileName) { // The path to the local image file, e.g. "/path/to/image.png" // const fileName = '/path/to/image.png'; - // Performs face detection on the local file - vision.detectFaces(fileName) + vision.faceDetection({ source: { filename: fileName } }) .then((results) => { - const faces = results[0]; + const faces = results[0].faceAnnotations; console.log('Faces:'); faces.forEach((face, i) => { console.log(` Face #${i + 1}:`); - console.log(` Joy: ${face.joy}`); - console.log(` Anger: ${face.anger}`); - console.log(` Sorrow: ${face.sorrow}`); - console.log(` Surprise: ${face.surprise}`); + console.log(` Joy: ${face.joyLikelihood}`); + console.log(` Anger: ${face.angerLikelihood}`); + console.log(` Sorrow: ${face.sorrowLikelihood}`); + console.log(` Surprise: ${face.surpriseLikelihood}`); }); }) .catch((err) => { @@ -49,11 +48,9 @@ function detectFaces (fileName) { function detectFacesGCS (bucketName, fileName) { // [START vision_face_detection_gcs] // Imports the Google Cloud client libraries - const Storage = require('@google-cloud/storage'); const Vision = require('@google-cloud/vision'); // Instantiates clients - const storage = Storage(); const vision = Vision(); // The name of the bucket where the file resides, e.g. "my-bucket" @@ -62,18 +59,20 @@ function detectFacesGCS (bucketName, fileName) { // The path to the file within the bucket, e.g. "path/to/image.png" // const fileName = 'path/to/image.png'; - // Performs face detection on the remote file - vision.detectFaces(storage.bucket(bucketName).file(fileName)) + const gcsPath = `gs://` + bucketName + `/` + fileName; + + // Performs face detection on the gcs file + vision.faceDetection({ source: { imageUri: gcsPath } }) .then((results) => { - const faces = results[0]; + const faces = results[0].faceAnnotations; console.log('Faces:'); faces.forEach((face, i) => { console.log(` Face #${i + 1}:`); - console.log(` Joy: ${face.joy}`); - console.log(` Anger: ${face.anger}`); - console.log(` Sorrow: ${face.sorrow}`); - console.log(` Surprise: ${face.surprise}`); + console.log(` Joy: ${face.joyLikelihood}`); + console.log(` Anger: ${face.angerLikelihood}`); + console.log(` Sorrow: ${face.sorrowLikelihood}`); + console.log(` Surprise: ${face.surpriseLikelihood}`); }); }) .catch((err) => { @@ -94,10 +93,9 @@ function detectLabels (fileName) { // const fileName = '/path/to/image.png'; // Performs label detection on the local file - vision.detectLabels(fileName) + vision.labelDetection({ source: { filename: fileName } }) .then((results) => { - const labels = results[0]; - + const labels = results[0].labelAnnotations; console.log('Labels:'); labels.forEach((label) => console.log(label)); }) @@ -110,11 +108,9 @@ function detectLabels (fileName) { function detectLabelsGCS (bucketName, fileName) { // [START vision_label_detection_gcs] // Imports the Google Cloud client libraries - const Storage = require('@google-cloud/storage'); const Vision = require('@google-cloud/vision'); // Instantiates clients - const storage = Storage(); const vision = Vision(); // The name of the bucket where the file resides, e.g. "my-bucket" @@ -123,23 +119,23 @@ function detectLabelsGCS (bucketName, fileName) { // The path to the file within the bucket, e.g. "path/to/image.png" // const fileName = 'path/to/image.png'; - // Performs label detection on the remote file - vision.detectLabels(storage.bucket(bucketName).file(fileName)) - .then((results) => { - const labels = results[0]; + const gcsPath = `gs://` + bucketName + `/` + fileName; + // Performs label detection on the gcs file + vision.labelDetection({ source: { imageUri: gcsPath } }) + .then((results) => { + const labels = results[0].labelAnnotations; console.log('Labels:'); labels.forEach((label) => console.log(label)); }) .catch((err) => { console.error('ERROR:', err); }); - // [END vision_label_detection_gcs] + // [END vision_label_detection] } function detectLandmarks (fileName) { // [START vision_landmark_detection] - // Imports the Google Cloud client library const Vision = require('@google-cloud/vision'); // Instantiates a client @@ -149,10 +145,9 @@ function detectLandmarks (fileName) { // const fileName = '/path/to/image.png'; // Performs landmark detection on the local file - vision.detectLandmarks(fileName) + vision.landmarkDetection({ source: {filename: fileName} }) .then((results) => { - const landmarks = results[0]; - + const landmarks = results[0].landmarkAnnotations; console.log('Landmarks:'); landmarks.forEach((landmark) => console.log(landmark)); }) @@ -165,11 +160,9 @@ function detectLandmarks (fileName) { function detectLandmarksGCS (bucketName, fileName) { // [START vision_landmark_detection_gcs] // Imports the Google Cloud client libraries - const Storage = require('@google-cloud/storage'); const Vision = require('@google-cloud/vision'); // Instantiates clients - const storage = Storage(); const vision = Vision(); // The name of the bucket where the file resides, e.g. "my-bucket" @@ -178,11 +171,12 @@ function detectLandmarksGCS (bucketName, fileName) { // The path to the file within the bucket, e.g. "path/to/image.png" // const fileName = 'path/to/image.png'; - // Performs landmark detection on the remote file - vision.detectLandmarks(storage.bucket(bucketName).file(fileName)) - .then((results) => { - const landmarks = results[0]; + const gcsPath = `gs://` + bucketName + `/` + fileName; + // Performs landmark detection on the gcs file + vision.landmarkDetection({ source: {imageUri: gcsPath} }) + .then((results) => { + const landmarks = results[0].landmarkAnnotations; console.log('Landmarks:'); landmarks.forEach((landmark) => console.log(landmark)); }) @@ -194,7 +188,6 @@ function detectLandmarksGCS (bucketName, fileName) { function detectText (fileName) { // [START vision_text_detection] - // Imports the Google Cloud client library const Vision = require('@google-cloud/vision'); // Instantiates a client @@ -204,10 +197,9 @@ function detectText (fileName) { // const fileName = '/path/to/image.png'; // Performs text detection on the local file - vision.detectText(fileName) + vision.textDetection({ source: { filename: fileName } }) .then((results) => { - const detections = results[0]; - + const detections = results[0].textAnnotations; console.log('Text:'); detections.forEach((text) => console.log(text)); }) @@ -220,11 +212,9 @@ function detectText (fileName) { function detectTextGCS (bucketName, fileName) { // [START vision_text_detection_gcs] // Imports the Google Cloud client libraries - const Storage = require('@google-cloud/storage'); const Vision = require('@google-cloud/vision'); // Instantiates clients - const storage = Storage(); const vision = Vision(); // The name of the bucket where the file resides, e.g. "my-bucket" @@ -233,11 +223,12 @@ function detectTextGCS (bucketName, fileName) { // The path to the file within the bucket, e.g. "path/to/image.png" // const fileName = 'path/to/image.png'; - // Performs text detection on the remote file - vision.detectText(storage.bucket(bucketName).file(fileName)) - .then((results) => { - const detections = results[0]; + const gcsPath = `gs://` + bucketName + `/` + fileName; + // Performs text detection on the gcs file + vision.textDetection({ source: { imageUri: gcsPath } }) + .then((results) => { + const detections = results[0].textAnnotations; console.log('Text:'); detections.forEach((text) => console.log(text)); }) @@ -249,7 +240,6 @@ function detectTextGCS (bucketName, fileName) { function detectLogos (fileName) { // [START vision_logo_detection] - // Imports the Google Cloud client library const Vision = require('@google-cloud/vision'); // Instantiates a client @@ -259,10 +249,9 @@ function detectLogos (fileName) { // const fileName = '/path/to/image.png'; // Performs logo detection on the local file - vision.detectLogos(fileName) + vision.logoDetection({ source: { filename: fileName } }) .then((results) => { - const logos = results[0]; - + const logos = results[0].logoAnnotations; console.log('Logos:'); logos.forEach((logo) => console.log(logo)); }) @@ -275,11 +264,9 @@ function detectLogos (fileName) { function detectLogosGCS (bucketName, fileName) { // [START vision_logo_detection_gcs] // Imports the Google Cloud client libraries - const Storage = require('@google-cloud/storage'); const Vision = require('@google-cloud/vision'); // Instantiates clients - const storage = Storage(); const vision = Vision(); // The name of the bucket where the file resides, e.g. "my-bucket" @@ -288,11 +275,12 @@ function detectLogosGCS (bucketName, fileName) { // The path to the file within the bucket, e.g. "path/to/image.png" // const fileName = 'path/to/image.png'; - // Performs logo detection on the remote file - vision.detectLogos(storage.bucket(bucketName).file(fileName)) - .then((results) => { - const logos = results[0]; + const gcsPath = `gs://` + bucketName + `/` + fileName; + // Performs logo detection on the gcs file + vision.logoDetection({ source: { imageUri: gcsPath } }) + .then((results) => { + const logos = results[0].logoAnnotations; console.log('Logos:'); logos.forEach((logo) => console.log(logo)); }) @@ -304,7 +292,6 @@ function detectLogosGCS (bucketName, fileName) { function detectProperties (fileName) { // [START vision_image_property_detection] - // Imports the Google Cloud client library const Vision = require('@google-cloud/vision'); // Instantiates a client @@ -313,13 +300,12 @@ function detectProperties (fileName) { // The path to the local image file, e.g. "/path/to/image.png" // const fileName = '/path/to/image.png'; - // Performs image property detection on the local file - vision.detectProperties(fileName) + // Performs property detection on the local file + vision.imageProperties({ source: { filename: fileName } }) .then((results) => { - const properties = results[0]; - - console.log('Colors:'); - properties.colors.forEach((color) => console.log(color)); + const properties = results[0].imagePropertiesAnnotation; + const colors = properties.dominantColors.colors; + colors.forEach((color) => console.log(color)); }) .catch((err) => { console.error('ERROR:', err); @@ -330,11 +316,9 @@ function detectProperties (fileName) { function detectPropertiesGCS (bucketName, fileName) { // [START vision_image_property_detection_gcs] // Imports the Google Cloud client libraries - const Storage = require('@google-cloud/storage'); const Vision = require('@google-cloud/vision'); // Instantiates clients - const storage = Storage(); const vision = Vision(); // The name of the bucket where the file resides, e.g. "my-bucket" @@ -343,13 +327,14 @@ function detectPropertiesGCS (bucketName, fileName) { // The path to the file within the bucket, e.g. "path/to/image.png" // const fileName = 'path/to/image.png'; - // Performs image property detection on the remote file - vision.detectProperties(storage.bucket(bucketName).file(fileName)) - .then((results) => { - const properties = results[0]; + const gcsPath = `gs://` + bucketName + `/` + fileName; - console.log('Colors:'); - properties.colors.forEach((color) => console.log(color)); + // Performs property detection on the gcs file + vision.imageProperties({ source: { imageUri: gcsPath } }) + .then((results) => { + const properties = results[0].imagePropertiesAnnotation; + const colors = properties.dominantColors.colors; + colors.forEach((color) => console.log(color)); }) .catch((err) => { console.error('ERROR:', err); @@ -359,7 +344,6 @@ function detectPropertiesGCS (bucketName, fileName) { function detectSafeSearch (fileName) { // [START vision_safe_search_detection] - // Imports the Google Cloud client library const Vision = require('@google-cloud/vision'); // Instantiates a client @@ -368,10 +352,10 @@ function detectSafeSearch (fileName) { // The path to the local image file, e.g. "/path/to/image.png" // const fileName = '/path/to/image.png'; - // Performs safe search property detection on the local file - vision.detectSafeSearch(fileName) + // Performs safe search detection on the local file + vision.safeSearchDetection({ source: { filename: fileName } }) .then((results) => { - const detections = results[0]; + const detections = results[0].safeSearchAnnotation; console.log(`Adult: ${detections.adult}`); console.log(`Spoof: ${detections.spoof}`); @@ -387,11 +371,9 @@ function detectSafeSearch (fileName) { function detectSafeSearchGCS (bucketName, fileName) { // [START vision_safe_search_detection_gcs] // Imports the Google Cloud client libraries - const Storage = require('@google-cloud/storage'); const Vision = require('@google-cloud/vision'); // Instantiates clients - const storage = Storage(); const vision = Vision(); // The name of the bucket where the file resides, e.g. "my-bucket" @@ -400,10 +382,12 @@ function detectSafeSearchGCS (bucketName, fileName) { // The path to the file within the bucket, e.g. "path/to/image.png" // const fileName = 'path/to/image.png'; + const gcsPath = `gs://` + bucketName + `/` + fileName; + // Performs safe search property detection on the remote file - vision.detectSafeSearch(storage.bucket(bucketName).file(fileName)) + vision.safeSearchDetection({ source: { imageUri: gcsPath } }) .then((results) => { - const detections = results[0]; + const detections = results[0].safeSearchAnnotation; console.log(`Adult: ${detections.adult}`); console.log(`Spoof: ${detections.spoof}`); @@ -429,13 +413,15 @@ function detectCropHints (fileName) { // const fileName = 'my-file.jpg'; // Find crop hints for the local file - vision.detectCrops(fileName) + vision.cropHints({ + source: {filename: fileName}, + options: {aspect_ratios: 0.25} }) .then((results) => { - const cropHints = results[0]; + const cropHints = results[0].cropHintsAnnotation; - cropHints.forEach((hintBounds, hintIdx) => { + cropHints.cropHints.forEach((hintBounds, hintIdx) => { console.log(`Crop Hint ${hintIdx}:`); - hintBounds.forEach((bound, boundIdx) => { + hintBounds.boundingPoly.vertices.forEach((bound, boundIdx) => { console.log(` Bound ${boundIdx}: (${bound.x}, ${bound.y})`); }); }); @@ -450,11 +436,9 @@ function detectCropHintsGCS (bucketName, fileName) { // [START vision_crop_hint_detection_gcs] // Imports the Google Cloud client libraries - const Storage = require('@google-cloud/storage'); const Vision = require('@google-cloud/vision'); // Instantiates clients - const storage = Storage(); const vision = Vision(); // The name of the bucket where the file resides, e.g. "my-bucket" @@ -463,14 +447,16 @@ function detectCropHintsGCS (bucketName, fileName) { // The path to the file within the bucket, e.g. "path/to/image.png" // const fileName = 'my-file.jpg'; + const gcsPath = `gs://` + bucketName + `/` + fileName; + // Find crop hints for the remote file - vision.detectCrops(storage.bucket(bucketName).file(fileName)) + vision.cropHints({source: {imageUri: gcsPath}}) .then((results) => { - const cropHints = results[0]; + const cropHints = results[0].cropHintsAnnotation; - cropHints.forEach((hintBounds, hintIdx) => { + cropHints.cropHints.forEach((hintBounds, hintIdx) => { console.log(`Crop Hint ${hintIdx}:`); - hintBounds.forEach((bound, boundIdx) => { + hintBounds.boundingPoly.vertices.forEach((bound, boundIdx) => { console.log(` Bound ${boundIdx}: (${bound.x}, ${bound.y})`); }); }); @@ -494,9 +480,9 @@ function detectWeb (fileName) { // const fileName = 'my-file.jpg'; // Detect similar images on the web to a local file - vision.detectSimilar(fileName) + vision.webDetection({ source: { filename: fileName } }) .then((results) => { - const webDetection = results[1].responses[0].webDetection; + const webDetection = results[0].webDetection; if (webDetection.fullMatchingImages.length) { console.log(`Full matches found: ${webDetection.fullMatchingImages.length}`); @@ -532,11 +518,9 @@ function detectWebGCS (bucketName, fileName) { // [START vision_web_detection_gcs] // Imports the Google Cloud client libraries - const Storage = require('@google-cloud/storage'); const Vision = require('@google-cloud/vision'); // Instantiates clients - const storage = Storage(); const vision = Vision(); // The name of the bucket where the file resides, e.g. "my-bucket" @@ -545,10 +529,12 @@ function detectWebGCS (bucketName, fileName) { // The path to the file within the bucket, e.g. "path/to/image.png" // const fileName = 'my-file.jpg'; + const gcsPath = `gs://` + bucketName + `/` + fileName; + // Detect similar images on the web to a remote file - vision.detectSimilar(storage.bucket(bucketName).file(fileName)) + vision.webDetection({ source: { imageUri: gcsPath } }) .then((results) => { - const webDetection = results[1].responses[0].webDetection; + const webDetection = results[0].webDetection; if (webDetection.fullMatchingImages.length) { console.log(`Full matches found: ${webDetection.fullMatchingImages.length}`); @@ -593,9 +579,9 @@ function detectFulltext (fileName) { // const fileName = 'my-file.jpg'; // Read a local image as a text document - vision.readDocument(fileName) + vision.documentTextDetection({ source: { filename: fileName } }) .then((results) => { - const fullTextAnnotation = results[1].responses[0].fullTextAnnotation; + const fullTextAnnotation = results[0].fullTextAnnotation; console.log(fullTextAnnotation.text); }) .catch((err) => { @@ -608,11 +594,9 @@ function detectFulltextGCS (bucketName, fileName) { // [START vision_fulltext_detection_gcs] // Imports the Google Cloud client libraries - const Storage = require('@google-cloud/storage'); const Vision = require('@google-cloud/vision'); // Instantiates clients - const storage = Storage(); const vision = Vision(); // The name of the bucket where the file resides, e.g. "my-bucket" @@ -621,10 +605,12 @@ function detectFulltextGCS (bucketName, fileName) { // The path to the file within the bucket, e.g. "path/to/image.png" // const fileName = 'my-file.jpg'; + const gcsPath = `gs://` + bucketName + `/` + fileName; + // Read a remote image as a text document - vision.readDocument(storage.bucket(bucketName).file(fileName)) + vision.documentTextDetection({ source: { imageUri: gcsPath } }) .then((results) => { - const fullTextAnnotation = results[1].responses[0].fullTextAnnotation; + const fullTextAnnotation = results[0].fullTextAnnotation; console.log(fullTextAnnotation.text); }) .catch((err) => { diff --git a/vision/faceDetection.js b/vision/faceDetection.js index 63d67953c1..21fa671b06 100644 --- a/vision/faceDetection.js +++ b/vision/faceDetection.js @@ -33,14 +33,17 @@ var fs = require('fs'); */ function detectFaces (inputFile, callback) { // Make a call to the Vision API to detect the faces - vision.detectFaces(inputFile, function (err, faces) { - if (err) { - return callback(err); - } - var numFaces = faces.length; - console.log('Found ' + numFaces + (numFaces === 1 ? ' face' : ' faces')); - callback(null, faces); - }); + const request = { source: { filename: inputFile } }; + vision.faceDetection(request) + .then((results) => { + const faces = results[0].faceAnnotations; + var numFaces = faces.length; + console.log('Found ' + numFaces + (numFaces === 1 ? ' face' : ' faces')); + callback(null, faces); + }) + .catch((err) => { + console.error('ERROR:', err); + }); } /** @@ -64,12 +67,18 @@ function highlightFaces (inputFile, faces, outputFile, Canvas, callback) { context.strokeStyle = 'rgba(0,255,0,0.8)'; context.lineWidth = '5'; - faces.forEach(function (face) { + faces.forEach((face) => { context.beginPath(); - face.bounds.face.forEach(function (bounds) { + let origX = 0; + let origY = 0; + face.boundingPoly.vertices.forEach(function (bounds, i) { + if (i === 0) { + origX = bounds.x; + origY = bounds.y; + } context.lineTo(bounds.x, bounds.y); }); - context.lineTo(face.bounds.face[0].x, face.bounds.face[0].y); + context.lineTo(origX, origY); context.stroke(); }); diff --git a/vision/package.json b/vision/package.json index 10f58666a7..cc676cc244 100644 --- a/vision/package.json +++ b/vision/package.json @@ -19,7 +19,7 @@ }, "dependencies": { "@google-cloud/storage": "1.1.0", - "@google-cloud/vision": "0.11.2", + "@google-cloud/vision": "^0.12.0", "async": "2.3.0", "natural": "0.5.1", "redis": "2.7.1", diff --git a/vision/quickstart.js b/vision/quickstart.js index 16afa9a407..998c0e44b8 100644 --- a/vision/quickstart.js +++ b/vision/quickstart.js @@ -31,12 +31,12 @@ const visionClient = Vision({ const fileName = './resources/wakeupcat.jpg'; // Performs label detection on the image file -visionClient.detectLabels(fileName) +visionClient.labelDetection({ source: { filename: fileName } }) .then((results) => { - const labels = results[0]; + const labels = results[0].labelAnnotations; console.log('Labels:'); - labels.forEach((label) => console.log(label)); + labels.forEach((label) => console.log(label.description)); }) .catch((err) => { console.error('ERROR:', err); diff --git a/vision/system-test/detect.test.js b/vision/system-test/detect.test.js index f1c563e247..ac6693b97b 100644 --- a/vision/system-test/detect.test.js +++ b/vision/system-test/detect.test.js @@ -113,13 +113,13 @@ test(`should detect logos in a remote file`, async (t) => { test(`should detect properties in a local file`, async (t) => { const output = await tools.runAsync(`${cmd} properties ${files[1].localPath}`, cwd); - t.true(output.includes(`Colors:`)); + t.true(output.includes(`{ color: { red: 69, green: 42, blue: 27`)); t.true(output.split(`\n`).length > 4, `Multiple colors were detected.`); }); test(`should detect properties in a remote file`, async (t) => { const output = await tools.runAsync(`${cmd} properties-gcs ${bucketName} ${files[1].name}`, cwd); - t.true(output.includes(`Colors:`)); + t.true(output.includes(`{ color: { red: 69, green: 42, blue: 27`)); t.true(output.split(`\n`).length > 4, `Multiple colors were detected.`); }); diff --git a/vision/system-test/quickstart.test.js b/vision/system-test/quickstart.test.js index 6a404c840d..ff392e4b62 100644 --- a/vision/system-test/quickstart.test.js +++ b/vision/system-test/quickstart.test.js @@ -16,46 +16,17 @@ 'use strict'; const path = require(`path`); -const proxyquire = require(`proxyquire`).noPreserveCache(); -const sinon = require(`sinon`); const test = require(`ava`); const tools = require(`@google-cloud/nodejs-repo-tools`); -const vision = proxyquire(`@google-cloud/vision`, {})(); - test.before(tools.stubConsole); test.after.always(tools.restoreConsole); -test.cb(`should detect labels`, (t) => { - const filePath = path.join(__dirname, `../resources/wakeupcat.jpg`); - const expectedFileName = `./resources/wakeupcat.jpg`; - const visionMock = { - detectLabels: (_fileName) => { - t.is(_fileName, expectedFileName); - - return vision.detectLabels(filePath) - .then(([labels]) => { - t.true(Array.isArray(labels)); - - setTimeout(() => { - try { - t.is(console.log.callCount, 6); - t.deepEqual(console.log.getCall(0).args, [`Labels:`]); - labels.forEach((label, i) => { - t.deepEqual(console.log.getCall(i + 1).args, [label]); - }); - t.end(); - } catch (err) { - t.end(err); - } - }, 200); - - return [labels]; - }); - } - }; +const cmd = `node quickstart.js`; +const cwd = path.join(__dirname, `..`); - proxyquire(`../quickstart`, { - '@google-cloud/vision': sinon.stub().returns(visionMock) - }); +test(`should detect labels in a remote file`, async (t) => { + const output = await tools.runAsync(`${cmd}`, cwd); + t.true(output.includes(`Labels:`)); + t.true(output.includes(`cat`)); }); From dcd348b778dea1b3f62779c7ed956771fd070c6f Mon Sep 17 00:00:00 2001 From: Gus Class Date: Wed, 26 Jul 2017 21:01:35 -0700 Subject: [PATCH 2/9] Updates redis sample --- vision/textDetection.js | 70 ++++++++++++++++++++++------------------- 1 file changed, 38 insertions(+), 32 deletions(-) diff --git a/vision/textDetection.js b/vision/textDetection.js index b5bb64bef5..9c1c803e2a 100644 --- a/vision/textDetection.js +++ b/vision/textDetection.js @@ -130,14 +130,14 @@ function lookup (words, callback) { function extractDescription (texts) { var document = ''; texts.forEach(function (text) { - document += (text.desc || ''); + document += (text.description || ''); }); return document; } -function extractDescriptions (filename, index, texts, callback) { - if (texts.length) { - index.add(filename, extractDescription(texts), callback); +function extractDescriptions (filename, index, response, callback) { + if (response.textAnnotations.length) { + index.add(filename, extractDescription(response.textAnnotations), callback); } else { console.log(filename + ' had no discernable text.'); index.setContainsNoText(filename, callback); @@ -147,36 +147,42 @@ function extractDescriptions (filename, index, texts, callback) { // [START get_text] function getTextFromFiles (index, inputFiles, callback) { - var options = { verbose: true }; - // Make a call to the Vision API to detect text - vision.detectText(inputFiles, options, function (err, detections) { - if (err) { - return callback(err); - } - var textResponse = {}; - var tasks = []; - inputFiles.forEach(function (filename, i) { - var response = detections[i]; - if (response.error) { - console.log('API Error for ' + filename, response.error); - return; - } else if (Array.isArray(response)) { - textResponse[filename] = 1; - } else { - textResponse[filename] = 0; - } - tasks.push(function (cb) { - extractDescriptions(filename, index, response, cb); - }); - }); - async.parallel(tasks, function (err) { - if (err) { - return callback(err); - } - callback(null, textResponse); - }); + let requests = []; + inputFiles.forEach((filename) => { + let request = { + image: {content: fs.readFileSync(filename).toString('base64')}, + features: {type: 'TEXT_DETECTION'} + }; + requests.push(request); }); + vision.batchAnnotateImages({requests: requests}) + .then((results) => { + // console.log(JSON.stringify(results, undefined, 2)); + let detections = results[0].responses; + var textResponse = {}; + var tasks = []; + inputFiles.forEach(function (filename, i) { + var response = detections[i]; + if (response.error) { + console.log('API Error for ' + filename, response.error); + return; + } else if (Array.isArray(response)) { + textResponse[filename] = 1; + } else { + textResponse[filename] = 0; + } + tasks.push(function (cb) { + extractDescriptions(filename, index, response, cb); + }); + }); + async.parallel(tasks, function (err) { + if (err) { + return callback(err); + } + callback(null, textResponse); + }); + }); } // Run the example From 5d718f5628a3fb0b594cebefbf3dc0a07ec1a848 Mon Sep 17 00:00:00 2001 From: Ace Nassri Date: Fri, 28 Jul 2017 14:50:46 -0700 Subject: [PATCH 3/9] Address jmdobry's comments --- vision/detect.js | 20 ++++++++++---------- vision/faceDetection.js | 11 ++++++----- vision/textDetection.js | 1 - 3 files changed, 16 insertions(+), 16 deletions(-) diff --git a/vision/detect.js b/vision/detect.js index 5db9fb81d8..1c38659428 100644 --- a/vision/detect.js +++ b/vision/detect.js @@ -59,7 +59,7 @@ function detectFacesGCS (bucketName, fileName) { // The path to the file within the bucket, e.g. "path/to/image.png" // const fileName = 'path/to/image.png'; - const gcsPath = `gs://` + bucketName + `/` + fileName; + const gcsPath = `gs://${bucketName}/${fileName}`; // Performs face detection on the gcs file vision.faceDetection({ source: { imageUri: gcsPath } }) @@ -119,7 +119,7 @@ function detectLabelsGCS (bucketName, fileName) { // The path to the file within the bucket, e.g. "path/to/image.png" // const fileName = 'path/to/image.png'; - const gcsPath = `gs://` + bucketName + `/` + fileName; + const gcsPath = `gs://${bucketName}/${fileName}`; // Performs label detection on the gcs file vision.labelDetection({ source: { imageUri: gcsPath } }) @@ -171,7 +171,7 @@ function detectLandmarksGCS (bucketName, fileName) { // The path to the file within the bucket, e.g. "path/to/image.png" // const fileName = 'path/to/image.png'; - const gcsPath = `gs://` + bucketName + `/` + fileName; + const gcsPath = `gs://${bucketName}/${fileName}`; // Performs landmark detection on the gcs file vision.landmarkDetection({ source: {imageUri: gcsPath} }) @@ -223,7 +223,7 @@ function detectTextGCS (bucketName, fileName) { // The path to the file within the bucket, e.g. "path/to/image.png" // const fileName = 'path/to/image.png'; - const gcsPath = `gs://` + bucketName + `/` + fileName; + const gcsPath = `gs://${bucketName}/${fileName}`; // Performs text detection on the gcs file vision.textDetection({ source: { imageUri: gcsPath } }) @@ -275,7 +275,7 @@ function detectLogosGCS (bucketName, fileName) { // The path to the file within the bucket, e.g. "path/to/image.png" // const fileName = 'path/to/image.png'; - const gcsPath = `gs://` + bucketName + `/` + fileName; + const gcsPath = `gs://${bucketName}/${fileName}`; // Performs logo detection on the gcs file vision.logoDetection({ source: { imageUri: gcsPath } }) @@ -327,7 +327,7 @@ function detectPropertiesGCS (bucketName, fileName) { // The path to the file within the bucket, e.g. "path/to/image.png" // const fileName = 'path/to/image.png'; - const gcsPath = `gs://` + bucketName + `/` + fileName; + const gcsPath = `gs://${bucketName}/${fileName}`; // Performs property detection on the gcs file vision.imageProperties({ source: { imageUri: gcsPath } }) @@ -382,7 +382,7 @@ function detectSafeSearchGCS (bucketName, fileName) { // The path to the file within the bucket, e.g. "path/to/image.png" // const fileName = 'path/to/image.png'; - const gcsPath = `gs://` + bucketName + `/` + fileName; + const gcsPath = `gs://${bucketName}/${fileName}`; // Performs safe search property detection on the remote file vision.safeSearchDetection({ source: { imageUri: gcsPath } }) @@ -447,7 +447,7 @@ function detectCropHintsGCS (bucketName, fileName) { // The path to the file within the bucket, e.g. "path/to/image.png" // const fileName = 'my-file.jpg'; - const gcsPath = `gs://` + bucketName + `/` + fileName; + const gcsPath = `gs://${bucketName}/${fileName}`; // Find crop hints for the remote file vision.cropHints({source: {imageUri: gcsPath}}) @@ -529,7 +529,7 @@ function detectWebGCS (bucketName, fileName) { // The path to the file within the bucket, e.g. "path/to/image.png" // const fileName = 'my-file.jpg'; - const gcsPath = `gs://` + bucketName + `/` + fileName; + const gcsPath = `gs://${bucketName}/${fileName}`; // Detect similar images on the web to a remote file vision.webDetection({ source: { imageUri: gcsPath } }) @@ -605,7 +605,7 @@ function detectFulltextGCS (bucketName, fileName) { // The path to the file within the bucket, e.g. "path/to/image.png" // const fileName = 'my-file.jpg'; - const gcsPath = `gs://` + bucketName + `/` + fileName; + const gcsPath = `gs://${bucketName}/${fileName}`; // Read a remote image as a text document vision.documentTextDetection({ source: { imageUri: gcsPath } }) diff --git a/vision/faceDetection.js b/vision/faceDetection.js index 21fa671b06..6163ccfb7a 100644 --- a/vision/faceDetection.js +++ b/vision/faceDetection.js @@ -43,6 +43,7 @@ function detectFaces (inputFile, callback) { }) .catch((err) => { console.error('ERROR:', err); + callback(err); }); } @@ -50,7 +51,7 @@ function detectFaces (inputFile, callback) { * Draws a polygon around the faces, then saves to outputFile. */ function highlightFaces (inputFile, faces, outputFile, Canvas, callback) { - fs.readFile(inputFile, function (err, image) { + fs.readFile(inputFile, (err, image) => { if (err) { return callback(err); } @@ -71,7 +72,7 @@ function highlightFaces (inputFile, faces, outputFile, Canvas, callback) { context.beginPath(); let origX = 0; let origY = 0; - face.boundingPoly.vertices.forEach(function (bounds, i) { + face.boundingPoly.vertices.forEach((bounds, i) => { if (i === 0) { origX = bounds.x; origY = bounds.y; @@ -87,7 +88,7 @@ function highlightFaces (inputFile, faces, outputFile, Canvas, callback) { var writeStream = fs.createWriteStream(outputFile); var pngStream = canvas.pngStream(); - pngStream.on('data', function (chunk) { + pngStream.on('data', (chunk) => { writeStream.write(chunk); }); pngStream.on('error', console.log); @@ -98,13 +99,13 @@ function highlightFaces (inputFile, faces, outputFile, Canvas, callback) { // Run the example function main (inputFile, outputFile, Canvas, callback) { outputFile = outputFile || 'out.png'; - detectFaces(inputFile, function (err, faces) { + detectFaces(inputFile, (err, faces) => { if (err) { return callback(err); } console.log('Highlighting...'); - highlightFaces(inputFile, faces, outputFile, Canvas, function (err) { + highlightFaces(inputFile, faces, outputFile, Canvas, (err) => { if (err) { return callback(err); } diff --git a/vision/textDetection.js b/vision/textDetection.js index 9c1c803e2a..65201266e8 100644 --- a/vision/textDetection.js +++ b/vision/textDetection.js @@ -158,7 +158,6 @@ function getTextFromFiles (index, inputFiles, callback) { }); vision.batchAnnotateImages({requests: requests}) .then((results) => { - // console.log(JSON.stringify(results, undefined, 2)); let detections = results[0].responses; var textResponse = {}; var tasks = []; From 4f8f7fc5a7fed87038c203a91f8e11c84a2c5bfc Mon Sep 17 00:00:00 2001 From: Ace Nassri Date: Fri, 28 Jul 2017 14:55:45 -0700 Subject: [PATCH 4/9] Revert changes to vision quickstart test --- vision/system-test/quickstart.test.js | 41 +++++++++++++++++++++++---- 1 file changed, 35 insertions(+), 6 deletions(-) diff --git a/vision/system-test/quickstart.test.js b/vision/system-test/quickstart.test.js index ff392e4b62..6a404c840d 100644 --- a/vision/system-test/quickstart.test.js +++ b/vision/system-test/quickstart.test.js @@ -16,17 +16,46 @@ 'use strict'; const path = require(`path`); +const proxyquire = require(`proxyquire`).noPreserveCache(); +const sinon = require(`sinon`); const test = require(`ava`); const tools = require(`@google-cloud/nodejs-repo-tools`); +const vision = proxyquire(`@google-cloud/vision`, {})(); + test.before(tools.stubConsole); test.after.always(tools.restoreConsole); -const cmd = `node quickstart.js`; -const cwd = path.join(__dirname, `..`); +test.cb(`should detect labels`, (t) => { + const filePath = path.join(__dirname, `../resources/wakeupcat.jpg`); + const expectedFileName = `./resources/wakeupcat.jpg`; + const visionMock = { + detectLabels: (_fileName) => { + t.is(_fileName, expectedFileName); + + return vision.detectLabels(filePath) + .then(([labels]) => { + t.true(Array.isArray(labels)); + + setTimeout(() => { + try { + t.is(console.log.callCount, 6); + t.deepEqual(console.log.getCall(0).args, [`Labels:`]); + labels.forEach((label, i) => { + t.deepEqual(console.log.getCall(i + 1).args, [label]); + }); + t.end(); + } catch (err) { + t.end(err); + } + }, 200); + + return [labels]; + }); + } + }; -test(`should detect labels in a remote file`, async (t) => { - const output = await tools.runAsync(`${cmd}`, cwd); - t.true(output.includes(`Labels:`)); - t.true(output.includes(`cat`)); + proxyquire(`../quickstart`, { + '@google-cloud/vision': sinon.stub().returns(visionMock) + }); }); From c00ba7a9b9708a1b4dc5a6d14eea9fd6e8ee37db Mon Sep 17 00:00:00 2001 From: Gus Class Date: Mon, 31 Jul 2017 12:26:25 -0700 Subject: [PATCH 5/9] Updates quickstart test to match semi-gapic --- vision/system-test/quickstart.test.js | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/vision/system-test/quickstart.test.js b/vision/system-test/quickstart.test.js index 6a404c840d..1b3cd42281 100644 --- a/vision/system-test/quickstart.test.js +++ b/vision/system-test/quickstart.test.js @@ -15,7 +15,6 @@ 'use strict'; -const path = require(`path`); const proxyquire = require(`proxyquire`).noPreserveCache(); const sinon = require(`sinon`); const test = require(`ava`); @@ -27,30 +26,30 @@ test.before(tools.stubConsole); test.after.always(tools.restoreConsole); test.cb(`should detect labels`, (t) => { - const filePath = path.join(__dirname, `../resources/wakeupcat.jpg`); const expectedFileName = `./resources/wakeupcat.jpg`; const visionMock = { - detectLabels: (_fileName) => { + labelDetection: (_request) => { + let _fileName = _request.source.filename; t.is(_fileName, expectedFileName); - return vision.detectLabels(filePath) - .then(([labels]) => { + return vision.labelDetection(_request) + .then((results) => { + const labels = results[0].labelAnnotations; t.true(Array.isArray(labels)); - setTimeout(() => { try { t.is(console.log.callCount, 6); t.deepEqual(console.log.getCall(0).args, [`Labels:`]); labels.forEach((label, i) => { - t.deepEqual(console.log.getCall(i + 1).args, [label]); + t.deepEqual(console.log.getCall(i + 1).args, [label.description]); }); + t.end(); } catch (err) { t.end(err); } }, 200); - - return [labels]; + return results; }); } }; From a766be3a8f1318b7d2e65d7cbd30722a344426b0 Mon Sep 17 00:00:00 2001 From: Gus Class Date: Mon, 31 Jul 2017 14:00:00 -0700 Subject: [PATCH 6/9] Changing system test to nudge CI --- vision/system-test/quickstart.test.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/vision/system-test/quickstart.test.js b/vision/system-test/quickstart.test.js index 1b3cd42281..1ceaf5d9ca 100644 --- a/vision/system-test/quickstart.test.js +++ b/vision/system-test/quickstart.test.js @@ -41,7 +41,8 @@ test.cb(`should detect labels`, (t) => { t.is(console.log.callCount, 6); t.deepEqual(console.log.getCall(0).args, [`Labels:`]); labels.forEach((label, i) => { - t.deepEqual(console.log.getCall(i + 1).args, [label.description]); + t.deepEqual(console.log.getCall(i + 1).args, + [label.description]); }); t.end(); From de3b44b638d421bd6621ac44ead29abcffa8cd41 Mon Sep 17 00:00:00 2001 From: Gus Class Date: Mon, 31 Jul 2017 15:35:54 -0700 Subject: [PATCH 7/9] Changes await in case it's a timing issue on circle --- vision/system-test/quickstart.test.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/vision/system-test/quickstart.test.js b/vision/system-test/quickstart.test.js index 1ceaf5d9ca..a5716cbb4d 100644 --- a/vision/system-test/quickstart.test.js +++ b/vision/system-test/quickstart.test.js @@ -44,12 +44,11 @@ test.cb(`should detect labels`, (t) => { t.deepEqual(console.log.getCall(i + 1).args, [label.description]); }); - t.end(); } catch (err) { t.end(err); } - }, 200); + }, 1000); return results; }); } From c308488d19a386dde37e5e829fa679e81f3514a9 Mon Sep 17 00:00:00 2001 From: Jason Dobry Date: Mon, 31 Jul 2017 15:48:57 -0700 Subject: [PATCH 8/9] Update yarn.lock --- vision/yarn.lock | 176 ++++++++++++++++++++++++++++++----------------- 1 file changed, 111 insertions(+), 65 deletions(-) diff --git a/vision/yarn.lock b/vision/yarn.lock index b4df5411d6..f108246e8b 100644 --- a/vision/yarn.lock +++ b/vision/yarn.lock @@ -37,21 +37,6 @@ ansi-styles "^2.2.1" esutils "^2.0.2" -"@google-cloud/common-grpc@^0.3.0": - version "0.3.1" - resolved "https://registry.yarnpkg.com/@google-cloud/common-grpc/-/common-grpc-0.3.1.tgz#c29b8ce83bef2da409eb838fa187960bb8c3df2e" - dependencies: - "@google-cloud/common" "^0.13.0" - dot-prop "^2.4.0" - duplexify "^3.5.0" - extend "^3.0.0" - google-proto-files "^0.11.0" - grpc "^1.2.3" - is "^3.2.0" - modelo "^4.2.0" - retry-request "^1.3.2" - through2 "^2.0.3" - "@google-cloud/common@^0.13.0": version "0.13.0" resolved "https://registry.yarnpkg.com/@google-cloud/common/-/common-0.13.0.tgz#d062439a75b38eb76c4704d20f5b45301a69f17f" @@ -75,21 +60,21 @@ string-format-obj "^1.1.0" through2 "^2.0.3" -"@google-cloud/nodejs-repo-tools@1.4.5": - version "1.4.5" - resolved "https://registry.yarnpkg.com/@google-cloud/nodejs-repo-tools/-/nodejs-repo-tools-1.4.5.tgz#fa2f8fcf29969e05de184fa4b8f03363903566e3" +"@google-cloud/nodejs-repo-tools@1.4.14": + version "1.4.14" + resolved "https://registry.yarnpkg.com/@google-cloud/nodejs-repo-tools/-/nodejs-repo-tools-1.4.14.tgz#b778687bcd798ea172a01d2b92db43ad95a8b0ce" dependencies: ava "0.19.1" colors "1.1.2" - fs-extra "3.0.0" + fs-extra "3.0.1" got "6.7.1" - handlebars "4.0.6" + handlebars "4.0.8" lodash "4.17.4" proxyquire "1.7.11" - sinon "2.1.0" + sinon "2.2.0" string "3.3.3" supertest "3.0.0" - yargs "7.1.0" + yargs "8.0.1" "@google-cloud/storage@1.1.0": version "1.1.0" @@ -112,22 +97,16 @@ string-format-obj "^1.0.0" through2 "^2.0.0" -"@google-cloud/vision@0.11.2": - version "0.11.2" - resolved "https://registry.yarnpkg.com/@google-cloud/vision/-/vision-0.11.2.tgz#95eae7b1b036d66c10014659db36461a6e9c76c7" +"@google-cloud/vision@^0.12.0": + version "0.12.0" + resolved "https://registry.yarnpkg.com/@google-cloud/vision/-/vision-0.12.0.tgz#ffab0a18e0e6ea841e6c4e81273cd46809fdf03e" dependencies: "@google-cloud/common" "^0.13.0" - "@google-cloud/common-grpc" "^0.3.0" - arrify "^1.0.0" async "^2.0.1" extend "^3.0.0" - google-gax "^0.13.0" - google-proto-files "^0.11.0" + google-gax "^0.13.2" + google-proto-files "^0.12.0" is "^3.0.1" - prop-assign "^1.0.0" - propprop "^0.3.0" - rgb-hex "^1.0.0" - string-format-obj "^1.0.0" abbrev@1: version "1.0.9" @@ -830,7 +809,7 @@ camelcase@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-3.0.0.tgz#32fc4b9fcdaf845fcdf7e73bb97cac2261f0ab0a" -camelcase@^4.0.0: +camelcase@^4.0.0, camelcase@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-4.1.0.tgz#d545635be1e33c542649c69173e5de6acfae34dd" @@ -1092,6 +1071,14 @@ cross-spawn@^4.0.0: lru-cache "^4.0.1" which "^1.2.9" +cross-spawn@^5.0.1: + version "5.1.0" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-5.1.0.tgz#e8bd0efee58fcff6f8f94510a0a554bbfa235449" + dependencies: + lru-cache "^4.0.1" + shebang-command "^1.2.0" + which "^1.2.9" + cryptiles@2.x.x: version "2.0.5" resolved "https://registry.yarnpkg.com/cryptiles/-/cryptiles-2.0.5.tgz#3bdfecdc608147c1c67202fa291e7dca59eaa3b8" @@ -1188,12 +1175,6 @@ diff@^3.0.0, diff@^3.0.1, diff@^3.1.0: version "3.2.0" resolved "https://registry.yarnpkg.com/diff/-/diff-3.2.0.tgz#c9ce393a4b7cbd0b058a725c93df299027868ff9" -dot-prop@^2.4.0: - version "2.4.0" - resolved "https://registry.yarnpkg.com/dot-prop/-/dot-prop-2.4.0.tgz#848e28f7f1d50740c6747ab3cb07670462b6f89c" - dependencies: - is-obj "^1.0.0" - dot-prop@^4.1.0: version "4.1.1" resolved "https://registry.yarnpkg.com/dot-prop/-/dot-prop-4.1.1.tgz#a8493f0b7b5eeec82525b5c7587fa7de7ca859c1" @@ -1321,6 +1302,18 @@ execa@^0.5.0: signal-exit "^3.0.0" strip-eof "^1.0.0" +execa@^0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/execa/-/execa-0.7.0.tgz#944becd34cc41ee32a63a9faf27ad5a65fc59777" + dependencies: + cross-spawn "^5.0.1" + get-stream "^3.0.0" + is-stream "^1.1.0" + npm-run-path "^2.0.0" + p-finally "^1.0.0" + signal-exit "^3.0.0" + strip-eof "^1.0.0" + expand-brackets@^0.1.4: version "0.1.5" resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-0.1.5.tgz#df07284e342a807cd733ac5af72411e581d1177b" @@ -1439,9 +1432,9 @@ formidable@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/formidable/-/formidable-1.1.1.tgz#96b8886f7c3c3508b932d6bd70c4d3a88f35f1a9" -fs-extra@3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-3.0.0.tgz#244e0c4b0b8818f54040ec049d8a2bddc1202861" +fs-extra@3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-3.0.1.tgz#3794f378c58b342ea7dbbb23095109c4b3b62291" dependencies: graceful-fs "^4.1.2" jsonfile "^3.0.0" @@ -1641,9 +1634,9 @@ google-auto-auth@^0.6.0: object-assign "^3.0.0" request "^2.79.0" -google-gax@^0.13.0: - version "0.13.2" - resolved "https://registry.yarnpkg.com/google-gax/-/google-gax-0.13.2.tgz#61a7b55fad465b17d3680f88070b2e419131e98e" +google-gax@^0.13.2: + version "0.13.4" + resolved "https://registry.yarnpkg.com/google-gax/-/google-gax-0.13.4.tgz#462d0cf654b0abeef5ee5f059d0f7b6c0d0a6121" dependencies: extend "^3.0.0" google-auto-auth "^0.5.2" @@ -1661,9 +1654,9 @@ google-p12-pem@^0.1.0: dependencies: node-forge "^0.6.46" -google-proto-files@^0.11.0: - version "0.11.0" - resolved "https://registry.yarnpkg.com/google-proto-files/-/google-proto-files-0.11.0.tgz#3d753120718e5e8574f38def739d54cf7a057553" +google-proto-files@^0.12.0: + version "0.12.1" + resolved "https://registry.yarnpkg.com/google-proto-files/-/google-proto-files-0.12.1.tgz#6434dc7e025a0d0c82e5f04e615c737d6a4c4387" google-proto-files@^0.9.1: version "0.9.1" @@ -1693,7 +1686,7 @@ graceful-fs@^4.1.11, graceful-fs@^4.1.2, graceful-fs@^4.1.6: version "1.0.1" resolved "https://registry.yarnpkg.com/graceful-readlink/-/graceful-readlink-1.0.1.tgz#4cafad76bc62f02fa039b2f94e9a3dd3a391a725" -grpc@^1.2, grpc@^1.2.3: +grpc@^1.2: version "1.2.3" resolved "https://registry.yarnpkg.com/grpc/-/grpc-1.2.3.tgz#60b4b533a8783fa0b389b6cfa5d5bee34786049f" dependencies: @@ -1712,9 +1705,9 @@ gtoken@^1.1.0, gtoken@^1.2.1: mime "^1.2.11" request "^2.72.0" -handlebars@4.0.6: - version "4.0.6" - resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.0.6.tgz#2ce4484850537f9c97a8026d5399b935c4ed4ed7" +handlebars@4.0.8: + version "4.0.8" + resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.0.8.tgz#22b875cd3f0e6cbea30314f144e82bc7a72ff420" dependencies: async "^1.4.0" optimist "^0.6.1" @@ -2377,6 +2370,12 @@ md5-o-matic@^0.1.1: version "0.1.1" resolved "https://registry.yarnpkg.com/md5-o-matic/-/md5-o-matic-0.1.1.tgz#822bccd65e117c514fab176b25945d54100a03c3" +mem@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/mem/-/mem-1.1.0.tgz#5edd52b485ca1d900fe64895505399a0dfa45f76" + dependencies: + mimic-fn "^1.0.0" + meow@^3.7.0: version "3.7.0" resolved "https://registry.yarnpkg.com/meow/-/meow-3.7.0.tgz#72cb668b425228290abbfa856892587308a801fb" @@ -2648,6 +2647,14 @@ os-locale@^1.4.0: dependencies: lcid "^1.0.0" +os-locale@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-2.1.0.tgz#42bc2900a6b5b8bd17376c8e882b65afccf24bf2" + dependencies: + execa "^0.7.0" + lcid "^1.0.0" + mem "^1.1.0" + os-tmpdir@^1.0.0, os-tmpdir@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" @@ -2859,14 +2866,6 @@ process-nextick-args@^1.0.7, process-nextick-args@~1.0.6: version "1.0.7" resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-1.0.7.tgz#150e20b756590ad3f91093f25a4f2ad8bff30ba3" -prop-assign@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/prop-assign/-/prop-assign-1.0.0.tgz#9767a1fbfd7093908647a6e846d31b4feaa70459" - -propprop@^0.3.0: - version "0.3.1" - resolved "https://registry.yarnpkg.com/propprop/-/propprop-0.3.1.tgz#a049a3568b896440067d15d8ec9f33735e570178" - protobufjs@^5.0.0: version "5.0.1" resolved "https://registry.yarnpkg.com/protobufjs/-/protobufjs-5.0.1.tgz#589ecdda1a555fd69df4699adc142d36f133aa0b" @@ -3228,10 +3227,6 @@ retry-request@^1.3.2: request "2.76.0" through2 "^2.0.0" -rgb-hex@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/rgb-hex/-/rgb-hex-1.0.0.tgz#bfaf8cd9cd9164b5a26d71eb4f15a0965324b3c1" - right-align@^0.1.1: version "0.1.3" resolved "https://registry.yarnpkg.com/right-align/-/right-align-0.1.3.tgz#61339b722fe6a3515689210d24e14c96148613ef" @@ -3270,6 +3265,16 @@ set-immediate-shim@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz#4b2b1b27eb808a9f8dcc481a58e5e56f599f3f61" +shebang-command@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea" + dependencies: + shebang-regex "^1.0.0" + +shebang-regex@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3" + signal-exit@^3.0.0, signal-exit@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d" @@ -3287,6 +3292,19 @@ sinon@2.1.0: text-encoding "0.6.4" type-detect "^4.0.0" +sinon@2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/sinon/-/sinon-2.2.0.tgz#3b1b42ff5defcbf51a52a62aca6d61171b9fd262" + dependencies: + diff "^3.1.0" + formatio "1.2.0" + lolex "^1.6.0" + native-promise-only "^0.8.1" + path-to-regexp "^1.7.0" + samsam "^1.1.3" + text-encoding "0.6.4" + type-detect "^4.0.0" + slash@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/slash/-/slash-1.0.0.tgz#c41f2f6c39fc16d1cd17ad4b5d896114ae470d55" @@ -3718,6 +3736,10 @@ which-module@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/which-module/-/which-module-1.0.0.tgz#bba63ca861948994ff307736089e3b96026c2a4f" +which-module@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a" + which@^1.2.8, which@^1.2.9: version "1.2.14" resolved "https://registry.yarnpkg.com/which/-/which-1.2.14.tgz#9a87c4378f03e827cecaf1acdf56c736c01c14e5" @@ -3808,6 +3830,12 @@ yargs-parser@^5.0.0: dependencies: camelcase "^3.0.0" +yargs-parser@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-7.0.0.tgz#8d0ac42f16ea55debd332caf4c4038b3e3f5dfd9" + dependencies: + camelcase "^4.1.0" + yargs@7.1.0: version "7.1.0" resolved "https://registry.yarnpkg.com/yargs/-/yargs-7.1.0.tgz#6ba318eb16961727f5d284f8ea003e8d6154d0c8" @@ -3826,6 +3854,24 @@ yargs@7.1.0: y18n "^3.2.1" yargs-parser "^5.0.0" +yargs@8.0.1: + version "8.0.1" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-8.0.1.tgz#420ef75e840c1457a80adcca9bc6fa3849de51aa" + dependencies: + camelcase "^4.1.0" + cliui "^3.2.0" + decamelize "^1.1.1" + get-caller-file "^1.0.1" + os-locale "^2.0.0" + read-pkg-up "^2.0.0" + require-directory "^2.1.1" + require-main-filename "^1.0.1" + set-blocking "^2.0.0" + string-width "^2.0.0" + which-module "^2.0.0" + y18n "^3.2.1" + yargs-parser "^7.0.0" + yargs@^3.10.0, yargs@~3.10.0: version "3.10.0" resolved "https://registry.yarnpkg.com/yargs/-/yargs-3.10.0.tgz#f7ee7bd857dd7c1d2d38c0e74efbd681d1431fd1" From c150b7706549f2591541d2ef46218bc659752f4a Mon Sep 17 00:00:00 2001 From: Jason Dobry Date: Mon, 31 Jul 2017 16:07:13 -0700 Subject: [PATCH 9/9] Remove explicit project id from vision quickstart. --- vision/quickstart.js | 18 ++++++----- vision/system-test/quickstart.test.js | 44 +++++---------------------- 2 files changed, 18 insertions(+), 44 deletions(-) diff --git a/vision/quickstart.js b/vision/quickstart.js index 998c0e44b8..56914608e5 100644 --- a/vision/quickstart.js +++ b/vision/quickstart.js @@ -1,5 +1,5 @@ /** - * Copyright 2016, Google, Inc. + * Copyright 2017, Google, Inc. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -19,19 +19,21 @@ // Imports the Google Cloud client library const Vision = require('@google-cloud/vision'); -// Your Google Cloud Platform project ID -const projectId = 'YOUR_PROJECT_ID'; - // Instantiates a client -const visionClient = Vision({ - projectId: projectId -}); +const vision = Vision(); // The name of the image file to annotate const fileName = './resources/wakeupcat.jpg'; +// Prepare the request object +const request = { + source: { + filename: fileName + } +}; + // Performs label detection on the image file -visionClient.labelDetection({ source: { filename: fileName } }) +vision.labelDetection(request) .then((results) => { const labels = results[0].labelAnnotations; diff --git a/vision/system-test/quickstart.test.js b/vision/system-test/quickstart.test.js index a5716cbb4d..e3304caec6 100644 --- a/vision/system-test/quickstart.test.js +++ b/vision/system-test/quickstart.test.js @@ -1,5 +1,5 @@ /** - * Copyright 2016, Google, Inc. + * Copyright 2017, Google, Inc. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -15,46 +15,18 @@ 'use strict'; -const proxyquire = require(`proxyquire`).noPreserveCache(); -const sinon = require(`sinon`); +const path = require(`path`); const test = require(`ava`); const tools = require(`@google-cloud/nodejs-repo-tools`); -const vision = proxyquire(`@google-cloud/vision`, {})(); +const cmd = `node quickstart.js`; +const cwd = path.join(__dirname, `..`); test.before(tools.stubConsole); test.after.always(tools.restoreConsole); -test.cb(`should detect labels`, (t) => { - const expectedFileName = `./resources/wakeupcat.jpg`; - const visionMock = { - labelDetection: (_request) => { - let _fileName = _request.source.filename; - t.is(_fileName, expectedFileName); - - return vision.labelDetection(_request) - .then((results) => { - const labels = results[0].labelAnnotations; - t.true(Array.isArray(labels)); - setTimeout(() => { - try { - t.is(console.log.callCount, 6); - t.deepEqual(console.log.getCall(0).args, [`Labels:`]); - labels.forEach((label, i) => { - t.deepEqual(console.log.getCall(i + 1).args, - [label.description]); - }); - t.end(); - } catch (err) { - t.end(err); - } - }, 1000); - return results; - }); - } - }; - - proxyquire(`../quickstart`, { - '@google-cloud/vision': sinon.stub().returns(visionMock) - }); +test(`should detect labels in a remote file`, async (t) => { + const output = await tools.runAsync(`${cmd}`, cwd); + t.true(output.includes(`Labels:`)); + t.true(output.includes(`cat`)); });