-
Notifications
You must be signed in to change notification settings - Fork 2k
functions/imagemagick: system tests + Node 8 upgrade #1387
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 12 commits
6701429
927f214
cf24c57
0d0ab0b
99a29b3
b8064e7
c70e2ba
ddd3917
636ded9
548da6e
cc66c33
65b8fa2
a28d1a6
be6893c
bdf699d
796ed8c
b48a34a
dc126bb
91ad2ba
729fc25
d4234ec
4a5a985
7aa4dfd
12c8c69
3f450bb
a2e8dbd
3b000f3
be2e537
92f9558
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -30,115 +30,94 @@ const {BLURRED_BUCKET_NAME} = process.env; | |||||
|
|
||||||
| // [START functions_imagemagick_analyze] | ||||||
| // Blurs uploaded images that are flagged as Adult or Violence. | ||||||
| exports.blurOffensiveImages = event => { | ||||||
| const object = event.data || event; // Node 6: event.data === Node 8+: event | ||||||
|
|
||||||
| // Exit if this is a deletion or a deploy event. | ||||||
| if (object.resourceState === 'not_exists') { | ||||||
| console.log('This is a deletion event.'); | ||||||
| return; | ||||||
| } else if (!object.name) { | ||||||
| console.log('This is a deploy event.'); | ||||||
| return; | ||||||
| } | ||||||
| exports.blurOffensiveImages = async event => { | ||||||
| const object = event; | ||||||
|
|
||||||
| const file = storage.bucket(object.bucket).file(object.name); | ||||||
| const filePath = `gs://${object.bucket}/${object.name}`; | ||||||
|
|
||||||
| // Ignore already-blurred files (to prevent re-invoking this function) | ||||||
| if (file.name.startsWith('blurred-')) { | ||||||
| console.log(`The image ${file.name} is already blurred.`); | ||||||
| return; | ||||||
| } | ||||||
|
|
||||||
| console.log(`Analyzing ${file.name}.`); | ||||||
|
|
||||||
| return client | ||||||
| .safeSearchDetection(filePath) | ||||||
| .catch(err => { | ||||||
| console.error(`Failed to analyze ${file.name}.`, err); | ||||||
| return Promise.reject(err); | ||||||
| }) | ||||||
| .then(([result]) => { | ||||||
| const detections = result.safeSearchAnnotation; | ||||||
|
|
||||||
| if ( | ||||||
| detections.adult === 'VERY_LIKELY' || | ||||||
| detections.violence === 'VERY_LIKELY' | ||||||
| ) { | ||||||
| console.log( | ||||||
| `The image ${file.name} has been detected as inappropriate.` | ||||||
| ); | ||||||
| return blurImage(file, BLURRED_BUCKET_NAME); | ||||||
| } else { | ||||||
| console.log(`The image ${file.name} has been detected as OK.`); | ||||||
| } | ||||||
| }); | ||||||
| try { | ||||||
| const [result] = await client.safeSearchDetection(filePath); | ||||||
| const detections = result.safeSearchAnnotation; | ||||||
|
|
||||||
| if ( | ||||||
| detections.adult === 'VERY_LIKELY' || | ||||||
| detections.violence === 'VERY_LIKELY' | ||||||
| ) { | ||||||
| console.log(`The image ${file.name} has been detected as inappropriate.`); | ||||||
| return blurImage(file, BLURRED_BUCKET_NAME); | ||||||
| } else { | ||||||
| console.log(`The image ${file.name} has been detected as OK.`); | ||||||
ace-n marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||||||
| } | ||||||
| } catch (err) { | ||||||
| console.error(`Failed to analyze ${file.name}.`, err); | ||||||
ace-n marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||
| return Promise.reject(err); | ||||||
| } | ||||||
| }; | ||||||
| // [END functions_imagemagick_analyze] | ||||||
|
|
||||||
| // [START functions_imagemagick_blur] | ||||||
| // Blurs the given file using ImageMagick, and uploads it to another bucket. | ||||||
| function blurImage(file, blurredBucketName) { | ||||||
| const blurImage = async (file, blurredBucketName) => { | ||||||
| const tempLocalPath = `/tmp/${path.parse(file.name).base}`; | ||||||
|
|
||||||
| // Download file from bucket. | ||||||
| return file | ||||||
| .download({destination: tempLocalPath}) | ||||||
| .catch(err => { | ||||||
| console.error('Failed to download file.', err); | ||||||
| return Promise.reject(err); | ||||||
| }) | ||||||
| .then(() => { | ||||||
| console.log( | ||||||
| `Image ${file.name} has been downloaded to ${tempLocalPath}.` | ||||||
| ); | ||||||
|
|
||||||
| // Blur the image using ImageMagick. | ||||||
| return new Promise((resolve, reject) => { | ||||||
| gm(tempLocalPath) | ||||||
| .blur(0, 16) | ||||||
| .write(tempLocalPath, (err, stdout) => { | ||||||
| if (err) { | ||||||
| console.error('Failed to blur image.', err); | ||||||
| reject(err); | ||||||
| } else { | ||||||
| resolve(stdout); | ||||||
| } | ||||||
| }); | ||||||
| }); | ||||||
| }) | ||||||
| .then(() => { | ||||||
| console.log(`Image ${file.name} has been blurred.`); | ||||||
|
|
||||||
| // Upload result to a different bucket, to avoid re-triggering this function. | ||||||
| // You can also re-upload it to the same bucket + tell your Cloud Function to | ||||||
| // ignore files marked as blurred (e.g. those with a "blurred" prefix) | ||||||
| const blurredBucket = storage.bucket(blurredBucketName); | ||||||
|
|
||||||
| // Upload the Blurred image back into the bucket. | ||||||
| return blurredBucket | ||||||
| .upload(tempLocalPath, {destination: file.name}) | ||||||
| .catch(err => { | ||||||
| console.error('Failed to upload blurred image.', err); | ||||||
| return Promise.reject(err); | ||||||
| }); | ||||||
| }) | ||||||
| .then(() => { | ||||||
| console.log( | ||||||
| `Blurred image has been uploaded to: gs://${blurredBucketName}/${file.name}` | ||||||
| ); | ||||||
|
|
||||||
| // Delete the temporary file. | ||||||
| return new Promise((resolve, reject) => { | ||||||
| fs.unlink(tempLocalPath, err => { | ||||||
| try { | ||||||
| await file.download({destination: tempLocalPath}); | ||||||
|
|
||||||
| console.log(`Image ${file.name} has been downloaded to ${tempLocalPath}.`); | ||||||
ace-n marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||||||
| } catch (err) { | ||||||
| console.error('Failed to download file.', err); | ||||||
ace-n marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||||||
| return Promise.reject(err); | ||||||
| } | ||||||
|
|
||||||
| try { | ||||||
| // Blur the image using ImageMagick. | ||||||
| await new Promise((resolve, reject) => { | ||||||
| gm(tempLocalPath) | ||||||
| .blur(0, 16) | ||||||
| .write(tempLocalPath, (err, stdout) => { | ||||||
| if (err) { | ||||||
| reject(err); | ||||||
| console.error('Failed to blur image.', err); | ||||||
|
||||||
| console.error('Failed to blur image.', err); |
ace-n marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| console.error('Failed to blur image.', err); | |
| console.error(`Failed image transform: blur {file.name}:`, err); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
AFAICT our samples generally log either the err object or the relevant parameter (i.e. file.name), but not both.
Should we keep this as-is, or replace err with file.name?
Uh oh!
There was an error while loading. Please reload this page.