Skip to content

Instantly share code, notes, and snippets.

@TheBeachMaster
Forked from moose56/image-queue.js
Created August 18, 2020 11:56
Show Gist options
  • Save TheBeachMaster/766b81647205fc7c50da6ee2837622ca to your computer and use it in GitHub Desktop.
Save TheBeachMaster/766b81647205fc7c50da6ee2837622ca to your computer and use it in GitHub Desktop.
A fork of https://gist.github.com/sararob/275b252d1eda3a5baa27d6464d2f2198 to use async/await rather than callbacks
'use strict';
// Dependencies
// we can remove a dependency by using the vision
// package directly
const vision = require('@google-cloud/vision')({
projectId: 'sara-bigquery',
keyfileName: 'keyfile.json'
});
const fs = require('fs');
const async = require('async');
// Convert the newline delimited JSON file into JSON to send to our queue
let imageIds = [];
const data = fs.readFileSync('./image-ids.json').toString();
imageIds = data.split("\n").map(function(obj) {
return JSON.parse(obj);
});
let imageData = [];
const features = [
{ "type": "FACE_DETECTION" },
{ "type": "LABEL_DETECTION" },
{ "type": "LANDMARK_DETECTION" },
{ "type": "WEB_DETECTION" },
{ "type": "IMAGE_PROPERTIES" }
];
// specify this function as async and remove the callback param
// as it will no longer be needed. The async library will implicitly
// convert any thrown errors to be the resulting error of the function
// and any returned value to be the result.
async function callVision(task) {
console.log(`processing ${task.object_id}`);
let visionReq = {
"image": {
"source": {
"imageUri": `gs://gcs-storage-bucket/${task.id}.jpg`
}
},
"features": features
}
// As this function is async we can use try/catch and
// await on functions that return promises
try {
// use the version of the api that returns a promise
// i.e. do not pass a callback. we can then 'await' the
// result
let data = await vision.annotate(visionReq);
let annotations = data[0];
let imgMetadata = annotations[0];
if (!imgMetadata['imagePropertiesAnnotation']) {
throw new Error('no data');
}
imgMetadata['object_id'] = task.name;
imageData.push(imgMetadata);
// we are not returning anything so return
// is called implicitly. No need to call
// callback
catch (err) {
// with await we can catch errors in the 'normal'
// way and throw them to the calling code
throw err;
}
}
// The queue sends the image ID to callVision() and writes the response to a local file
// once the entire queue has finished processing
let q = async.queue(callVision, 20);
// any thrown errors in the callVision function
// will be err here. Any returned values would
// also be available here as a second parameter
q.push(imageIds, (err) => {
if (err) {
console.log(err)
}
});
function done() {
q.drain = null;
fs.writeFileSync('./responses.json', JSON.stringify(imageData));
}
// Will only be executed when the queue is drained
q.drain = done;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment