diff --git a/.jscsrc b/.jscsrc index 91d4a292952..0be5bbf66a1 100644 --- a/.jscsrc +++ b/.jscsrc @@ -22,7 +22,9 @@ "excludeFiles": [ "**/src/*/**/*", "**/system-test/*/**/*", + "**/test/**/gapic-*.js", "**/test/*/**/*", - "**/node_modules/" + "**/node_modules/", + "**/.coverage/**/*.js", ] } diff --git a/.jshintignore b/.jshintignore index 626b737fbdc..deb103b74e2 100644 --- a/.jshintignore +++ b/.jshintignore @@ -2,3 +2,5 @@ **/system-test/*/**/* **/test/*/**/* **/node_modules/ +**/coverage +**/gapic*.js diff --git a/packages/video-intelligence/package.json b/packages/video-intelligence/package.json new file mode 100644 index 00000000000..5f4b7637ac1 --- /dev/null +++ b/packages/video-intelligence/package.json @@ -0,0 +1,27 @@ +{ + "name": "@google-cloud/video-intelligence", + "repository": "googlecloudplatform/google-cloud-node", + "version": "0.0.0", + "author": "Google Inc", + "description": "Google Cloud Video Intelligence API client for Node.js", + "main": "src/index.js", + "files": [ + "src" + ], + "dependencies": { + "google-proto-files": "^0.12.0", + "google-gax": "^0.13.2", + "extend": "^3.0.0" + }, + "devDependencies": { + "mocha": "3.2.0" + }, + "license": "Apache-2.0", + "engines": { + "node": ">=4.0.0" + }, + "scripts": { + "publish-module": "node ../../scripts/publish.js video-intelligence", + "test": "mocha" + } +} diff --git a/packages/video-intelligence/src/index.js b/packages/video-intelligence/src/index.js new file mode 100644 index 00000000000..98aa372d51b --- /dev/null +++ b/packages/video-intelligence/src/index.js @@ -0,0 +1,72 @@ +/* + * Copyright 2017 Google Inc. All rights reserved. + * + * 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 + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/*! + * @module video-intelligence + */ + +'use strict'; + +var v1beta1 = require('./v1beta1/index.js'); + +const VERSION = require('../package.json').version; + +/** + * [Google Cloud Video Intelligence API](https://cloud.google.com/video-intelligence) + * makes videos searchable, and discoverable, by extracting metadata with an + * easy to use REST API. You can now search every moment of every video file in + * your catalog and find every occurrence as well as its significance. It + * quickly annotates videos stored in Google Cloud Storage, and helps you + * identify key nouns entities of your video, and when they occur within the + * video. Separate signal from noise, by retrieving relevant information at the + * video, shot or per frame. + * + *

This is an auto-generated API

+ * + * It does not follow the conventions you're familiar with from other parts of + * our library. A handwritten layer is not yet available. + * + * The example below shows you how to instantiate the generated client. For + * further documentation, please browse the + * [Video Intelligence .proto files](https://github.com/googleapis/googleapis/blob/master/google/cloud/videointelligence/v1beta1/video_intelligence.proto) + * on GitHub. + * + * @constructor + * @alias module:video-intelligence + * + * @resource [Cloud Video Intelligence](https://cloud.google.com/video-intelligence) + * + * @param {object} options - [Configuration object](#/docs). + * @param {number=} options.port - The port on which to connect to the remote + * host. + * @param {string=} options.servicePath - The domain name of the API remote + * host. + */ +function VideoIntelligence(options) { + // Define the header options. + options = options || {}; + options.libName = 'gccl'; + options.libVersion = VERSION; + + // Create the image annotator client with the provided options. + var client = v1beta1(options).videoIntelligenceServiceClient(options); + return client; +} + +// The default export should be the latest version. +// Assign all versions as version properties on the default. +module.exports = VideoIntelligence; +module.exports.v1beta1 = v1beta1; diff --git a/packages/video-intelligence/src/v1beta1/index.js b/packages/video-intelligence/src/v1beta1/index.js new file mode 100644 index 00000000000..d7aa3548edb --- /dev/null +++ b/packages/video-intelligence/src/v1beta1/index.js @@ -0,0 +1,34 @@ +/* + * Copyright 2017 Google Inc. All rights reserved. + * + * 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 + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +'use strict'; + +var videoIntelligenceServiceClient = require('./video_intelligence_service_client'); +var gax = require('google-gax'); +var extend = require('extend'); + +function v1beta1(options) { + options = extend({ + scopes: v1beta1.ALL_SCOPES + }, options); + var gaxGrpc = gax.grpc(options); + return videoIntelligenceServiceClient(gaxGrpc); +} + +v1beta1.GAPIC_VERSION = '0.7.1'; +v1beta1.SERVICE_ADDRESS = videoIntelligenceServiceClient.SERVICE_ADDRESS; +v1beta1.ALL_SCOPES = videoIntelligenceServiceClient.ALL_SCOPES; + +module.exports = v1beta1; diff --git a/packages/video-intelligence/src/v1beta1/video_intelligence_service_client.js b/packages/video-intelligence/src/v1beta1/video_intelligence_service_client.js new file mode 100644 index 00000000000..52ee95379f5 --- /dev/null +++ b/packages/video-intelligence/src/v1beta1/video_intelligence_service_client.js @@ -0,0 +1,286 @@ +/* + * Copyright 2017, Google Inc. All rights reserved. + * + * 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 + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * EDITING INSTRUCTIONS + * This file was generated from the file + * https://github.com/googleapis/googleapis/blob/master/google/cloud/videointelligence/v1beta1/video_intelligence.proto, + * and updates to that file get reflected here through a refresh process. + * For the short term, the refresh process will only be runnable by Google + * engineers. + * + * The only allowed edits are to method and file documentation. A 3-way + * merge preserves those additions if the generated source changes. + */ +/* TODO: introduce line-wrapping so that it never exceeds the limit. */ +/* jscs: disable maximumLineLength */ +'use strict'; + +var configData = require('./video_intelligence_service_client_config'); +var extend = require('extend'); +var gax = require('google-gax'); + +var SERVICE_ADDRESS = 'videointelligence.googleapis.com'; + +var DEFAULT_SERVICE_PORT = 443; + +var CODE_GEN_NAME_VERSION = 'gapic/0.7.1'; + +/** + * The scopes needed to make gRPC calls to all of the methods defined in + * this service. + */ +var ALL_SCOPES = [ + 'https://www.googleapis.com/auth/cloud-platform' +]; + +/** + * Service that implements Google Cloud Video Intelligence API. + * + * This will be created through a builder function which can be obtained by the module. + * See the following example of how to initialize the module and how to access to the builder. + * @see {@link videoIntelligenceServiceClient} + * + * @example + * var videointelligenceV1beta1 = require('@google-cloud/videointelligence').v1beta1({ + * // optional auth parameters. + * }); + * var client = videointelligenceV1beta1.videoIntelligenceServiceClient(); + * + * @class + */ +function VideoIntelligenceServiceClient(gaxGrpc, grpcClients, opts) { + opts = extend({ + servicePath: SERVICE_ADDRESS, + port: DEFAULT_SERVICE_PORT, + clientConfig: {} + }, opts); + + var googleApiClient = [ + 'gl-node/' + process.versions.node + ]; + if (opts.libName && opts.libVersion) { + googleApiClient.push(opts.libName + '/' + opts.libVersion); + } + googleApiClient.push( + CODE_GEN_NAME_VERSION, + 'gax/' + gax.version, + 'grpc/' + gaxGrpc.grpcVersion + ); + + this.operationsClient = new gax.lro({ + auth: gaxGrpc.auth, + grpc: gaxGrpc.grpc + }).operationsClient(opts); + + this.longrunningDescriptors = { + annotateVideo: new gax.LongrunningDescriptor( + this.operationsClient, + grpcClients.google.cloud.videointelligence.v1beta1.AnnotateVideoResponse.decode, + grpcClients.google.cloud.videointelligence.v1beta1.AnnotateVideoProgress.decode) + }; + + var defaults = gaxGrpc.constructSettings( + 'google.cloud.videointelligence.v1beta1.VideoIntelligenceService', + configData, + opts.clientConfig, + {'x-goog-api-client': googleApiClient.join(' ')}); + + var self = this; + + this.auth = gaxGrpc.auth; + var videoIntelligenceServiceStub = gaxGrpc.createStub( + grpcClients.google.cloud.videointelligence.v1beta1.VideoIntelligenceService, + opts); + var videoIntelligenceServiceStubMethods = [ + 'annotateVideo' + ]; + videoIntelligenceServiceStubMethods.forEach(function(methodName) { + self['_' + methodName] = gax.createApiCall( + videoIntelligenceServiceStub.then(function(videoIntelligenceServiceStub) { + return function() { + var args = Array.prototype.slice.call(arguments, 0); + return videoIntelligenceServiceStub[methodName].apply(videoIntelligenceServiceStub, args); + }; + }), + defaults[methodName], + self.longrunningDescriptors[methodName]); + }); +} + + +/** + * Get the project ID used by this class. + * @param {function(Error, string)} callback - the callback to be called with + * the current project Id. + */ +VideoIntelligenceServiceClient.prototype.getProjectId = function(callback) { + return this.auth.getProjectId(callback); +}; + +// Service calls + +/** + * Performs asynchronous video annotation. Progress and results can be + * retrieved through the `google.longrunning.Operations` interface. + * `Operation.metadata` contains `AnnotateVideoProgress` (progress). + * `Operation.response` contains `AnnotateVideoResponse` (results). + * + * @param {Object} request + * The request object that will be sent. + * @param {string} request.inputUri + * Input video location. Currently, only + * [Google Cloud Storage](https://cloud.google.com/storage/) URIs are + * supported, which must be specified in the following format: + * `gs://bucket-id/object-id` (other URI formats return + * {@link google.rpc.Code.INVALID_ARGUMENT}). For more information, see + * [Request URIs](https://cloud.google.com/storage/docs/reference-uris). + * A video URI may include wildcards in `object-id`, and thus identify + * multiple videos. Supported wildcards: '*' to match 0 or more characters; + * '?' to match 1 character. If unset, the input video should be embedded + * in the request as `input_content`. If set, `input_content` should be unset. + * @param {number[]} request.features + * Requested video annotation features. + * + * The number should be among the values of [Feature]{@link Feature} + * @param {string=} request.inputContent + * The video data bytes. Encoding: base64. If unset, the input video(s) + * should be specified via `input_uri`. If set, `input_uri` should be unset. + * @param {Object=} request.videoContext + * Additional video context and/or feature-specific parameters. + * + * This object should have the same structure as [VideoContext]{@link VideoContext} + * @param {string=} request.outputUri + * Optional location where the output (in JSON format) should be stored. + * Currently, only [Google Cloud Storage](https://cloud.google.com/storage/) + * URIs are supported, which must be specified in the following format: + * `gs://bucket-id/object-id` (other URI formats return + * {@link google.rpc.Code.INVALID_ARGUMENT}). For more information, see + * [Request URIs](https://cloud.google.com/storage/docs/reference-uris). + * @param {string=} request.locationId + * Optional cloud region where annotation should take place. Supported cloud + * regions: `us-east1`, `us-west1`, `europe-west1`, `asia-east1`. If no region + * is specified, a region will be determined based on video file location. + * @param {Object=} options + * Optional parameters. You can override the default settings for this call, e.g, timeout, + * retries, paginations, etc. See [gax.CallOptions]{@link https://googleapis.github.io/gax-nodejs/global.html#CallOptions} for the details. + * @param {function(?Error, ?Object)=} callback + * The function which will be called with the result of the API call. + * + * The second parameter to the callback is a [gax.Operation]{@link https://googleapis.github.io/gax-nodejs/Operation} object. + * @return {Promise} - The promise which resolves to an array. + * The first element of the array is a [gax.Operation]{@link https://googleapis.github.io/gax-nodejs/Operation} object. + * The promise has a method named "cancel" which cancels the ongoing API call. + * + * @example + * + * var client = videointelligenceV1beta1.videoIntelligenceServiceClient(); + * var inputUri = ''; + * var features = []; + * var request = { + * inputUri: inputUri, + * features: features + * }; + * + * // Handle the operation using the promise pattern. + * client.annotateVideo(request).then(function(responses) { + * var operation = responses[0]; + * var initialApiResponse = responses[1]; + * + * // Operation#promise starts polling for the completion of the LRO. + * return operation.promise(); + * }).then(function(responses) { + * // The final result of the operation. + * var result = responses[0]; + * + * // The metadata value of the completed operation. + * var metadata = responses[1]; + * + * // The response of the api call returning the complete operation. + * var finalApiResponse = responses[2]; + * }).catch(function(err) { + * console.error(err); + * }); + * + * // Handle the operation using the event emitter pattern. + * client.annotateVideo(request).then(function(responses) { + * var operation = responses[0]; + * var initialApiResponse = responses[1]; + * + * // Adding a listener for the "complete" event starts polling for the + * // completion of the operation. + * operation.on('complete', function(result, metadata, finalApiResponse) { + * // doSomethingWith(result); + * }); + * + * // Adding a listener for the "progress" event causes the callback to be + * // called on any change in metadata when the operation is polled. + * operation.on('progress', function(metadata, apiResponse) { + * // doSomethingWith(metadata) + * }) + * + * // Adding a listener for the "error" event handles any errors found during polling. + * operation.on('error', function(err) { + * // throw(err); + * }) + * }).catch(function(err) { + * console.error(err); + * }); + */ +VideoIntelligenceServiceClient.prototype.annotateVideo = function(request, options, callback) { + if (options instanceof Function && callback === undefined) { + callback = options; + options = {}; + } + if (options === undefined) { + options = {}; + } + + return this._annotateVideo(request, options, callback); +}; + +function VideoIntelligenceServiceClientBuilder(gaxGrpc) { + if (!(this instanceof VideoIntelligenceServiceClientBuilder)) { + return new VideoIntelligenceServiceClientBuilder(gaxGrpc); + } + + var videoIntelligenceServiceClient = gaxGrpc.load([{ + root: require('google-proto-files')('..'), + file: 'google/cloud/videointelligence/v1beta1/video_intelligence.proto' + }]); + extend(this, videoIntelligenceServiceClient.google.cloud.videointelligence.v1beta1); + + + /** + * Build a new instance of {@link VideoIntelligenceServiceClient}. + * + * @param {Object=} opts - The optional parameters. + * @param {String=} opts.servicePath + * The domain name of the API remote host. + * @param {number=} opts.port + * The port on which to connect to the remote host. + * @param {grpc.ClientCredentials=} opts.sslCreds + * A ClientCredentials for use with an SSL-enabled channel. + * @param {Object=} opts.clientConfig + * The customized config to build the call settings. See + * {@link gax.constructSettings} for the format. + */ + this.videoIntelligenceServiceClient = function(opts) { + return new VideoIntelligenceServiceClient(gaxGrpc, videoIntelligenceServiceClient, opts); + }; + extend(this.videoIntelligenceServiceClient, VideoIntelligenceServiceClient); +} +module.exports = VideoIntelligenceServiceClientBuilder; +module.exports.SERVICE_ADDRESS = SERVICE_ADDRESS; +module.exports.ALL_SCOPES = ALL_SCOPES; diff --git a/packages/video-intelligence/src/v1beta1/video_intelligence_service_client_config.json b/packages/video-intelligence/src/v1beta1/video_intelligence_service_client_config.json new file mode 100644 index 00000000000..7dd61bbb7b5 --- /dev/null +++ b/packages/video-intelligence/src/v1beta1/video_intelligence_service_client_config.json @@ -0,0 +1,33 @@ +{ + "interfaces": { + "google.cloud.videointelligence.v1beta1.VideoIntelligenceService": { + "retry_codes": { + "idempotent": [ + "DEADLINE_EXCEEDED", + "UNAVAILABLE" + ], + "non_idempotent": [ + "UNAVAILABLE" + ] + }, + "retry_params": { + "default": { + "initial_retry_delay_millis": 1000, + "retry_delay_multiplier": 2.5, + "max_retry_delay_millis": 120000, + "initial_rpc_timeout_millis": 120000, + "rpc_timeout_multiplier": 1.0, + "max_rpc_timeout_millis": 120000, + "total_timeout_millis": 600000 + } + }, + "methods": { + "AnnotateVideo": { + "timeout_millis": 60000, + "retry_codes_name": "idempotent", + "retry_params_name": "default" + } + } + } + } +} diff --git a/packages/video-intelligence/test/gapic-v1beta1.js b/packages/video-intelligence/test/gapic-v1beta1.js new file mode 100644 index 00000000000..444dac98658 --- /dev/null +++ b/packages/video-intelligence/test/gapic-v1beta1.js @@ -0,0 +1,110 @@ +/* + * Copyright 2017 Google Inc. All rights reserved. + * + * 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 + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +var assert = require('assert'); +var videointelligenceV1beta1 = require('../src/v1beta1')(); + +var FAKE_STATUS_CODE = 1; +var error = new Error(); +error.code = FAKE_STATUS_CODE; + +describe('VideoIntelligenceServiceClient', function() { + describe('annotateVideo', function() { + it('invokes annotateVideo without error', function(done) { + var client = videointelligenceV1beta1.videoIntelligenceServiceClient(); + // Mock request + var inputUri = 'inputUri1707300727'; + var features = []; + var request = { + inputUri : inputUri, + features : features + }; + + // Mock response + var expectedResponse = {}; + + // Mock Grpc layer + client._annotateVideo = mockLongRunningGrpcMethod(request, expectedResponse); + + client.annotateVideo(request).then(function(responses) { + var operation = responses[0]; + return operation.promise(); + }).then(function(responses) { + assert.deepStrictEqual(responses[0], expectedResponse); + done(); + }).catch(function(err) { + done(err); + }); + }); + + it('invokes annotateVideo with error', function(done) { + var client = videointelligenceV1beta1.videoIntelligenceServiceClient(); + // Mock request + var inputUri = 'inputUri1707300727'; + var features = []; + var request = { + inputUri : inputUri, + features : features + }; + + // Mock Grpc layer + client._annotateVideo = mockLongRunningGrpcMethod(request, null, error); + + client.annotateVideo(request).then(function(responses) { + var operation = responses[0]; + return operation.promise(); + }).then(function(responses) { + assert.fail(); + }).catch(function(err) { + assert(err instanceof Error); + assert.equal(err.code, FAKE_STATUS_CODE); + done(); + }); + }); + }); + +}); + +function mockSimpleGrpcMethod(expectedRequest, response, error) { + return function(actualRequest, options, callback) { + assert.deepStrictEqual(actualRequest, expectedRequest); + if (error) { + callback(error); + } else if (response) { + callback(null, response); + } else { + callback(null); + } + }; +} + +function mockLongRunningGrpcMethod(expectedRequest, response, error) { + return function(request) { + assert.deepStrictEqual(request, expectedRequest); + var mockOperation = { + promise: function() { + return new Promise(function(resolve, reject) { + if (error) { + reject(error) + } else { + resolve([response]); + } + }); + } + }; + return Promise.resolve([mockOperation]); + }; +} diff --git a/scripts/docs/config.js b/scripts/docs/config.js index 8857ef3ede1..74cc8b665c4 100644 --- a/scripts/docs/config.js +++ b/scripts/docs/config.js @@ -103,6 +103,9 @@ module.exports = { translate: { title: 'Cloud Translation API' }, + 'video-intelligence': { + title: 'Cloud Video Intelligence' + }, vision: { title: 'Cloud Vision' }