├── .gitignore ├── .travis.yml ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── endpoints-frameworks ├── README.md ├── index.html └── main.js ├── package.json ├── speech ├── README.md └── explore-api │ ├── .gitignore │ ├── README.md │ ├── index.html │ ├── js │ ├── app.js │ └── app.test.js │ ├── karma.conf.js │ ├── key.js.example │ ├── mocks │ ├── audio.flac.js │ └── gapi.speech.js │ └── resources │ └── audio.flac └── vision ├── README.md └── explore-api ├── .gitignore ├── README.md ├── cat-data.js ├── index.html ├── karma.conf.js ├── key.js.example ├── main.js └── main.test.js /.gitignore: -------------------------------------------------------------------------------- 1 | *.DS_Store 2 | coverage 3 | node_modules 4 | npm-debug.log 5 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | # Copyright 2016, Google, Inc. 2 | # Licensed under the Apache License, Version 2.0 (the "License"); 3 | # you may not use this file except in compliance with the License. 4 | # You may obtain a copy of the License at 5 | # 6 | # http://www.apache.org/licenses/LICENSE-2.0 7 | # 8 | # Unless required by applicable law or agreed to in writing, software 9 | # distributed under the License is distributed on an "AS IS" BASIS, 10 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | # See the License for the specific language governing permissions and 12 | # limitations under the License. 13 | 14 | sudo: false 15 | language: node_js 16 | node_js: 17 | - "6" 18 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | Contributor License Agreements 2 | ------------------------------ 3 | 4 | Before we can accept your pull requests you'll need to sign a Contributor License Agreement (CLA): 5 | 6 | * If you are an individual writing original source code and you own the intellectual property, then you'll need to sign an [individual CLA](https://developers.google.com/open-source/cla/individual). 7 | 8 | * If you work for a company that wants to allow you to contribute your work, then you'll need to sign a [corporate CLA](https://developers.google.com/open-source/cla/corporate>). 9 | 10 | You can sign these electronically (just scroll to the bottom). After that, we'll be able to accept your pull requests. 11 | 12 | Style 13 | ----- 14 | 15 | Samples in this repository follow the [JavaScript Semi-Standard 16 | Style](https://github.com/Flet/semistandard). 17 | 18 | You can run `npm run lint` to match our JavaScript coding standards. 19 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |  2 | 3 | This project is no longer actively developed or maintained. 4 | 5 | # Google Cloud Platform web samples 6 | 7 | This repo contains web application samples for [Google Cloud 8 | Platform](https://cloud.google.com/). 9 | 10 | [](https://travis-ci.org/GoogleCloudPlatform/web-docs-samples) 12 | [](https://coveralls.io/github/GoogleCloudPlatform/web-docs-samples?branch=HEAD) 13 | [](https://github.com/Flet/semistandard) 14 | 15 | For more detailed introduction to a product, check the README.md in the 16 | corresponding folder. 17 | 18 | ## Contributing changes 19 | 20 | * See [CONTRIBUTING.md](CONTRIBUTING.md) 21 | 22 | ## Licensing 23 | 24 | * See [LICENSE](LICENSE) 25 | -------------------------------------------------------------------------------- /endpoints-frameworks/README.md: -------------------------------------------------------------------------------- 1 | # Endpoints Frameworks Client 2 | 3 | This example shows how to use Google Sign-In to make an authenticated request 4 | to the Endpoints Frameworks sample code running on the App Engine 5 | standard environment. 6 | 7 | To run the sample JavaScript app: 8 | 9 | * You must have deployed the Endpoints Frameworks sample API. For details on 10 | deploying the sample API, see the following: 11 | 12 | * [Java: Getting Started with Endpoints Frameworks](https://cloud.google.com/endpoints/docs/frameworks/java/get-started-frameworks-java) 13 | * [Python: Getting Started with Endpoints Frameworks](https://cloud.google.com/endpoints/docs/frameworks/python/get-started-frameworks-python) 14 | 15 | * You need a web server on your local computer to serve the sample `index.html` 16 | file, such as Python 2.7's `SimpleHTTPServer`, but you can use any web server. 17 | 18 | * In `main.js`, replace `YOUR_PROJECT_ID` with the ID of the project that you 19 | used for the Endpoints Frameworks sample API. 20 | 21 | * Get a [client ID](https://support.google.com/googleapi/answer/6158849?hl=en) 22 | and copy it to the clipboard. 23 | 24 | * In `main.js`, replace `YOUR_CLIENT_ID` with the client ID that you just 25 | created. 26 | 27 | * Add your client ID to the Endpoints Frameworks sample API: 28 | 29 | * Java: Replace `YOUR_OAUTH_CLIENT_ID` with your client ID in the `Echo.java` 30 | file included in the sample. 31 | * Python: Replace `your-oauth-client-id.com` with your client ID in the 32 | `main.py` file included in the sample. 33 | 34 | Additional details for running the sample JavaScript app will be in the 35 | Endpoints Frameworks documentation soon. We'll update this README with links 36 | to the Java and Python versions of the doc. 37 | 38 | To learn more about Google Sign-In, see [Google Sign-In JavaScript client 39 | reference](https://developers.google.com/identity/sign-in/web/reference). 40 | -------------------------------------------------------------------------------- /endpoints-frameworks/index.html: -------------------------------------------------------------------------------- 1 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /endpoints-frameworks/main.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2018, Google, LLC. 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | */ 15 | 16 | var gapi = gapi || {}; 17 | 18 | /* eslint-disable no-unused-vars */ 19 | 20 | // [START load_auth2_library] 21 | function loadAuthClient () { 22 | gapi.load('auth2', initGoogleAuth); 23 | } 24 | // [END load_auth2_library] 25 | 26 | // [START init_google_auth] 27 | function initGoogleAuth (clientId = 'YOUR_CLIENT_ID') { 28 | gapi.auth2.init({ 29 | client_id: clientId, 30 | scope: 'https://www.googleapis.com/auth/userinfo.email' 31 | }).then(() => { 32 | document.getElementById('sign-in-btn').disabled = false; 33 | }).catch(err => { 34 | console.log(err); 35 | }); 36 | } 37 | // [END init_google_auth] 38 | 39 | // [START user_signin] 40 | function signIn () { 41 | gapi.auth2.getAuthInstance().signIn().then(() => { 42 | document.getElementById('sign-in-btn').hidden = true; 43 | document.getElementById('sign-out-btn').hidden = false; 44 | document.getElementById('send-request-btn').disabled = false; 45 | }).catch(err => { 46 | console.log(err); 47 | }); 48 | } 49 | // [END user_signin] 50 | 51 | // [START send_sample_request] 52 | function sendSampleRequest (projectId = 'YOUR_PROJECT_ID') { 53 | var user = gapi.auth2.getAuthInstance().currentUser.get(); 54 | var idToken = user.getAuthResponse().id_token; 55 | var endpoint = `https://${projectId}.appspot.com/_ah/api/echo/v1/email`; 56 | var xhr = new XMLHttpRequest(); 57 | xhr.open('GET', endpoint + '?access_token=' + encodeURIComponent(idToken)); 58 | xhr.onreadystatechange = function () { 59 | if (this.readyState === XMLHttpRequest.DONE && this.status === 200) { 60 | window.alert(xhr.responseText); 61 | } 62 | }; 63 | xhr.send(); 64 | } 65 | // [END send_sample_request] 66 | 67 | // [START user_signout] 68 | function signOut () { 69 | gapi.auth2.getAuthInstance().signOut().then(() => { 70 | document.getElementById('sign-in-btn').hidden = false; 71 | document.getElementById('sign-out-btn').hidden = true; 72 | document.getElementById('send-request-btn').disabled = true; 73 | }).catch(err => { 74 | console.log(err); 75 | }); 76 | } 77 | // [END user_signout] 78 | 79 | /* eslint-enable no-unused-vars */ 80 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "web-docs-samples", 3 | "description": "Web samples found on https://cloud.google.com.", 4 | "version": "0.0.1", 5 | "private": true, 6 | "license": "Apache-2.0", 7 | "author": "Google, Inc.", 8 | "contributors": [ 9 | { 10 | "name": "Tim Swast", 11 | "email": "swast@google.com" 12 | } 13 | ], 14 | "repository": { 15 | "type": "git", 16 | "url": "git+https://github.com/GoogleCloudPlatform/web-docs-samples.git" 17 | }, 18 | "bugs": { 19 | "url": "https://github.com/GoogleCloudPlatform/web-docs-samples/issues" 20 | }, 21 | "homepage": "https://github.com/GoogleCloudPlatform/web-docs-samples#readme", 22 | "semistandard": { 23 | "globals": [ 24 | "$", 25 | "assert", 26 | "before", 27 | "describe", 28 | "Event", 29 | "fail", 30 | "FileReader", 31 | "Image", 32 | "it", 33 | "processFile", 34 | "XMLHttpRequest" 35 | ], 36 | "ignore": [ 37 | "**/node_modules/**", 38 | "coverage/", 39 | "vision/browser/key.js" 40 | ] 41 | }, 42 | "scripts": { 43 | "karma_speech": "karma start speech/explore-api/karma.conf.js", 44 | "karma_vision": "karma start vision/explore-api/karma.conf.js", 45 | "lint": "semistandard \"**/*.js\"", 46 | "test": "npm run lint && npm run karma_speech && npm run karma_vision" 47 | }, 48 | "devDependencies": { 49 | "chai": "^3.5.0", 50 | "karma": "^1.1.1", 51 | "karma-chai": "^0.1.0", 52 | "karma-chrome-launcher": "^1.0.1", 53 | "karma-coverage": "^1.1.0", 54 | "karma-detect-browsers": "^2.1.0", 55 | "karma-firefox-launcher": "^1.0.0", 56 | "karma-mocha": "^1.1.1", 57 | "karma-phantomjs-launcher": "^1.0.1", 58 | "karma-safari-launcher": "^1.0.0", 59 | "karma-sinon": "^1.0.5", 60 | "mocha": "^2.5.3", 61 | "semistandard": "^8.0.0", 62 | "sinon": "^1.17.7" 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /speech/README.md: -------------------------------------------------------------------------------- 1 | # Google Cloud Speech API examples 2 | 3 | This directory contains samples using the [Google Cloud Speech 4 | API](https://cloud.google.com/speech/). 5 | -------------------------------------------------------------------------------- /speech/explore-api/.gitignore: -------------------------------------------------------------------------------- 1 | key.js 2 | twistd.* 3 | -------------------------------------------------------------------------------- /speech/explore-api/README.md: -------------------------------------------------------------------------------- 1 | # Google Cloud Speech API Client Side JS examples 2 | Transmits audio to the Speech API and presents the transcription. 3 | 4 | This directory contains [Cloud Speech API](https://cloud.google.com/speech/) 5 | Client Side JS samples. 6 | 7 | ## Prereqisites 8 | 1. [Sign up for Google Cloud Platform Account](http://cloud.google.com) 9 | 2. [Enable Cloud Speech API](https://cloud.google.com/speech/docs/getting-started) 10 | 3. [Create a Browser Key](https://cloud.google.com/vision/docs/auth-template/cloud-api-auth) 11 | 12 | ## Setup 13 | 1. Rename the file *key.js.example* to *key.js*. 14 | 2. Update the line `var apiKey = 'YOUR API KEY HERE';` in *key.js* with your 15 | API key. 16 | 3. Start a web server in the sample folder and navigate to index.html. For 17 | example, `python -m SimpleHTTPServer` or 18 | `npm install -g httpserver && httpserver 8080`. 19 | 20 | From here, the demo allows you to upload sound files and process them using the 21 | Cloud Speech API. An example audio file, `resources/audio.flac` is included for 22 | verifying the sample works. 23 | -------------------------------------------------------------------------------- /speech/explore-api/index.html: -------------------------------------------------------------------------------- 1 | 19 | 20 | 21 | 22 | 23 | 24 | 29 | 30 | 31 | 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /speech/explore-api/js/app.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * Copyright 2017 Google Inc. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | var apiKey = apiKey || {}; 18 | var gapi = gapi || {}; 19 | 20 | /* eslint-disable no-unused-vars */ 21 | function initGapi () { 22 | console.log('loading gapi'); 23 | gapi.client.setApiKey(apiKey); 24 | 25 | // Load the speech client library and present the demo UI 26 | gapi.client.load('speech', 'v1beta1', function () { 27 | document.getElementById('post-load-div').style.display = 'block'; 28 | }); 29 | } 30 | /* eslint-enable no-unused-vars */ 31 | 32 | /** 33 | * Used to send file to speech API when user clicks transcribe button. 34 | */ 35 | /* eslint-disable no-unused-vars */ 36 | function handleFile () { 37 | var selectedFile = $('#inputFile')[0].files[0]; 38 | sendBlobToSpeech(selectedFile, 'flac', 16000); 39 | } 40 | /* eslint-enable no-unused-vars */ 41 | 42 | /** 43 | * Callback used to update sample UI when transcription completes. 44 | * 45 | * @param r The data from the API call containing an array of transcription 46 | * results. 47 | */ 48 | function uiCallback (r) { 49 | if (r.results && r.results[0]) { 50 | // Prepend top result 51 | var div = $(''); 52 | div.html(r.results[0].alternatives[0].transcript); 53 | $('#results').prepend(div); 54 | } 55 | } 56 | 57 | /** 58 | * Sends a file blob to the speech API endpoint. 59 | * 60 | * @param blob the Blob to send. 61 | * @param encoding the encoding type (e.g. 'flac' or 'LINEAR16'). 62 | * @param rate the encoding rate, ideally 16000. 63 | */ 64 | function sendBlobToSpeech (blob, encoding, rate) { 65 | var speechSender = new FileReader(); 66 | speechSender.addEventListener('loadend', function () { 67 | /* eslint-disable no-undef */ 68 | sendBytesToSpeech(btoa(speechSender.result), encoding, rate, uiCallback); 69 | /* eslint-enable no-undef */ 70 | }); 71 | speechSender.readAsBinaryString(blob); 72 | } 73 | 74 | /** 75 | * Sends post data to the speech API endpoint. 76 | * 77 | * @param bytes The raw data to send. 78 | * @param encoding The encoding for the data transcribe. 79 | * @param rate The rate that the data is encoded at. 80 | * @param callback A function to send result data to. 81 | */ 82 | function sendBytesToSpeech (bytes, encoding, rate, callback) { 83 | gapi.client.speech.speech.syncrecognize({ 84 | config: { 85 | encoding: encoding, 86 | sampleRate: rate 87 | }, 88 | audio: { 89 | content: bytes 90 | } 91 | }).execute(function (r) { 92 | callback(r); 93 | }); 94 | } 95 | -------------------------------------------------------------------------------- /speech/explore-api/js/app.test.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * Copyright 2017 Google Inc. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | 'use strict'; 19 | 20 | var mockAudio = mockAudio || {}; 21 | var sendBytesToSpeech = sendBytesToSpeech || {}; 22 | 23 | describe('speech/explore-api/js/app.js', function () { 24 | var result = {}; 25 | before(function (done) { 26 | var callback = function (r) { 27 | result = r; 28 | }; 29 | sendBytesToSpeech(mockAudio, 'FLAC', 16000, callback); 30 | done(); 31 | }); 32 | 33 | it('Response contains Brooklyn.', function (done) { 34 | assert(result.results[0].alternatives[0].transcript.indexOf('Bridge') > 0); 35 | done(); 36 | }); 37 | }); 38 | 39 | describe('speech/explore-api/js/app.js', function () { 40 | before(function (done) { 41 | var resultsArea = document.createElement('div'); 42 | resultsArea.id = 'results'; 43 | document.body.appendChild(resultsArea); 44 | 45 | var postLoadDiv = document.createElement('div'); 46 | postLoadDiv.id = 'post-load-div'; 47 | postLoadDiv.style.display = 'none'; 48 | document.body.appendChild(postLoadDiv); 49 | 50 | done(); 51 | }); 52 | 53 | it('Shows UI after GAPI load.', function (done) { 54 | /* eslint-disable no-undef */ 55 | initGapi(); 56 | /* eslint-enable no-undef */ 57 | assert(document.getElementById('post-load-div').style.display === 'block'); 58 | done(); 59 | }); 60 | 61 | it('Updates results UI.', function (done) { 62 | /* eslint-disable no-undef */ 63 | sendBytesToSpeech(mockAudio, 'FLAC', 16000, uiCallback); 64 | /* eslint-enable no-undef */ 65 | assert(document.getElementById('results').innerText.indexOf('Bridge') > 0); 66 | done(); 67 | }); 68 | }); 69 | -------------------------------------------------------------------------------- /speech/explore-api/karma.conf.js: -------------------------------------------------------------------------------- 1 | // Copyright 2017, Google, Inc. 2 | // Licensed under the Apache License, Version 2.0 (the "License") 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | module.exports = function (config) { 15 | config.set({ 16 | 17 | // base path that will be used to resolve all patterns (eg. files, exclude) 18 | basePath: '../..', 19 | 20 | // Just test in PhantomJS 21 | browsers: ['PhantomJS'], 22 | 23 | // frameworks to use 24 | // available frameworks: https://npmjs.org/browse/keyword/karma-adapter 25 | frameworks: ['chai', 'mocha'], 26 | 27 | // list of files / patterns to load in the browser 28 | files: [ 29 | 'https://ajax.googleapis.com/ajax/libs/jquery/2.2.2/jquery.min.js', 30 | './speech/explore-api/js/app.js', 31 | './speech/explore-api/js/app.test.js', 32 | './speech/explore-api/mocks/audio.flac.js', 33 | './speech/explore-api/mocks/gapi.speech.js' 34 | ], 35 | 36 | // list of files to exclude 37 | exclude: [ 38 | ], 39 | 40 | // preprocess matching files before serving them to the browser 41 | // available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor 42 | preprocessors: { 43 | './speech/explore-api/js/app.js': ['coverage'] 44 | }, 45 | 46 | // test results reporter to use 47 | // possible values: 'dots', 'progress' 48 | // available reporters: https://npmjs.org/browse/keyword/karma-reporter 49 | reporters: [ 50 | 'coverage', 51 | 'progress' 52 | ], 53 | 54 | // web server port 55 | port: 9876, 56 | 57 | // enable / disable colors in the output (reporters and logs) 58 | colors: true, 59 | 60 | // level of logging 61 | // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG 62 | logLevel: config.LOG_INFO, 63 | 64 | // enable / disable watching file and executing tests whenever any file changes 65 | autoWatch: true, 66 | 67 | // Continuous Integration mode 68 | // if true, Karma captures browsers, runs the tests and exits 69 | singleRun: true, 70 | 71 | // Concurrency level 72 | // how many browser should be started simultaneous 73 | concurrency: Infinity 74 | }); 75 | }; 76 | -------------------------------------------------------------------------------- /speech/explore-api/key.js.example: -------------------------------------------------------------------------------- 1 | // Replace with an API key from https://console.cloud.google.com 2 | var apiKey = 'YOUR API KEY HERE'; 3 | -------------------------------------------------------------------------------- /speech/explore-api/mocks/audio.flac.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable no-unused-vars */ 2 | var mockAudio = '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'; 3 | -------------------------------------------------------------------------------- /speech/explore-api/mocks/gapi.speech.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * Copyright 2017 Google Inc. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | /** 19 | * Mock Google API Client for test scaffolding. 20 | */ 21 | /* eslint-disable no-unused-vars */ 22 | var gapi = { 23 | client: { 24 | setApiKey: function (key) { 25 | }, 26 | load: function (endpoint, version, complete) { 27 | complete(true); 28 | }, 29 | speech: { 30 | speech: { 31 | syncrecognize: function (requestParams) { 32 | return { 33 | execute: function (callback) { 34 | callback({ 35 | result: { 36 | results: [ { 37 | alternatives: [ { 38 | confidence: 0.98267894, 39 | transcript: 'how old is the Brooklyn Bridge' 40 | } ] 41 | } ] 42 | }, 43 | results: [ { 44 | alternatives: [ { 45 | confidence: 0.98267894, 46 | transcript: 'how old is the Brooklyn Bridge' 47 | } ] 48 | } ] 49 | }); 50 | } 51 | }; 52 | } 53 | } 54 | } 55 | } 56 | }; 57 | /* eslint-enable no-unused-vars */ 58 | -------------------------------------------------------------------------------- /speech/explore-api/resources/audio.flac: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GoogleCloudPlatform/web-docs-samples/e0a86c19d3f8e534108d99dba1afe145d701a18e/speech/explore-api/resources/audio.flac -------------------------------------------------------------------------------- /vision/README.md: -------------------------------------------------------------------------------- 1 | # Google Cloud Vision API examples 2 | 3 | This directory contains samples using the [Google Cloud Vision 4 | API](https://cloud.google.com/vision/). 5 | -------------------------------------------------------------------------------- /vision/explore-api/.gitignore: -------------------------------------------------------------------------------- 1 | key.js 2 | -------------------------------------------------------------------------------- /vision/explore-api/README.md: -------------------------------------------------------------------------------- 1 | # Google Cloud Vision API Client Side JS examples 2 | 3 | This directory contains [Cloud Vision API](https://cloud.google.com/vision/) Client Side JS samples. 4 | 5 | ## Prereqisites 6 | 1. [Sign up for Google Cloud Platform Account](http://cloud.google.com) 7 | 2. [Enable Cloud Vision API](https://cloud.google.com/vision/docs/getting-started) 8 | 3. [Create a Browser Key](https://cloud.google.com/vision/docs/auth-template/cloud-api-auth) for making calls to Cloud Vision API 9 | 10 | 11 | ## Setup 12 | 1. Rename the file *key.js.example* to *key.js*. 13 | 2. Update the line `var apiKey = 'YOUR API KEY HERE';` in *key.js* with your API key. 14 | 3. Start a web server in the sample folder and navigate to index.html. 15 | 16 | 17 | From here, the demo allows you to upload images and process them using the various [Cloud Vision API annotation types](https://cloud.google.com/vision/reference/rest/v1/images/annotate#Type). 18 | 19 | -------------------------------------------------------------------------------- /vision/explore-api/cat-data.js: -------------------------------------------------------------------------------- 1 | // Copyright 2016, Google, Inc. 2 | // Licensed under the Apache License, Version 2.0 (the "License") 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // 6 | // http://www.apache.org/licenses/LICENSE-2.0 7 | // 8 | // Unless required by applicable law or agreed to in writing, software 9 | // distributed under the License is distributed on an "AS IS" BASIS, 10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | // See the License for the specific language governing permissions and 12 | // limitations under the License. 13 | 14 | 'use strict'; 15 | 16 | window.CAT_IMAGE_DATA_URI = 'data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAASABIAAD/4QDIRXhpZgAATU0AKgAAAAgABwESAAMAAAABAAEAAAEaAAUAAAABAAAAYgEbAAUAAAABAAAAagEoAAMAAAABAAIAAAExAAIAAAAPAAAAcgEyAAIAAAAUAAAAgodpAAQAAAABAAAAlgAAAAAAAABIAAAAAQAAAEgAAAABUGl4ZWxtYXRvciAzLjUAADIwMTY6MDc6MjEgMTc6MDc6NTYAAAOgAQADAAAAAQABAACgAgAEAAAAAQAAAOGgAwAEAAAAAQAAAOEAAAAA/+EJ9Gh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8APD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4gPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iWE1QIENvcmUgNS40LjAiPiA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPiA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtbG5zOmRjPSJodHRwOi8vcHVybC5vcmcvZGMvZWxlbWVudHMvMS4xLyIgeG1wOk1vZGlmeURhdGU9IjIwMTYtMDctMjFUMTc6MDc6NTYiIHhtcDpDcmVhdG9yVG9vbD0iUGl4ZWxtYXRvciAzLjUiPiA8ZGM6c3ViamVjdD4gPHJkZjpCYWcvPiA8L2RjOnN1YmplY3Q+IDwvcmRmOkRlc2NyaXB0aW9uPiA8L3JkZjpSREY+IDwveDp4bXBtZXRhPiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg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'; 17 | -------------------------------------------------------------------------------- /vision/explore-api/index.html: -------------------------------------------------------------------------------- 1 | 13 | 14 | 15 | 16 | 17 |
39 |
40 |
41 |
--------------------------------------------------------------------------------
/vision/explore-api/karma.conf.js:
--------------------------------------------------------------------------------
1 | // Copyright 2016, Google, Inc.
2 | // Licensed under the Apache License, Version 2.0 (the "License")
3 | // you may not use this file except in compliance with the License.
4 | // You may obtain a copy of the License at
5 | //
6 | // http://www.apache.org/licenses/LICENSE-2.0
7 | //
8 | // Unless required by applicable law or agreed to in writing, software
9 | // distributed under the License is distributed on an "AS IS" BASIS,
10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 | // See the License for the specific language governing permissions and
12 | // limitations under the License.
13 |
14 | // Karma configuration
15 | // Generated on Thu Jul 21 2016 15:49:38 GMT-0700 (PDT)
16 |
17 | module.exports = function (config) {
18 | config.set({
19 |
20 | // base path that will be used to resolve all patterns (eg. files, exclude)
21 | basePath: '../..',
22 |
23 | // Just test in PhantomJS
24 | browsers: ['PhantomJS'],
25 |
26 | // frameworks to use
27 | // available frameworks: https://npmjs.org/browse/keyword/karma-adapter
28 | frameworks: ['chai', 'sinon', 'mocha'],
29 |
30 | // list of files / patterns to load in the browser
31 | files: [
32 | './vision/explore-api/cat-data.js',
33 | 'https://ajax.googleapis.com/ajax/libs/jquery/2.2.2/jquery.min.js',
34 | './vision/explore-api/key.js',
35 | './vision/explore-api/main.js',
36 | './vision/explore-api/main.test.js'
37 | ],
38 |
39 | // list of files to exclude
40 | exclude: [
41 | ],
42 |
43 | // preprocess matching files before serving them to the browser
44 | // available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor
45 | preprocessors: {
46 | './vision/explore-api/main.js': ['coverage']
47 | },
48 |
49 | // test results reporter to use
50 | // possible values: 'dots', 'progress'
51 | // available reporters: https://npmjs.org/browse/keyword/karma-reporter
52 | reporters: [
53 | 'coverage',
54 | 'progress'
55 | ],
56 |
57 | // web server port
58 | port: 9876,
59 |
60 | // enable / disable colors in the output (reporters and logs)
61 | colors: true,
62 |
63 | // level of logging
64 | // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
65 | logLevel: config.LOG_INFO,
66 |
67 | // enable / disable watching file and executing tests whenever any file changes
68 | autoWatch: true,
69 |
70 | // Continuous Integration mode
71 | // if true, Karma captures browsers, runs the tests and exits
72 | singleRun: true,
73 |
74 | // Concurrency level
75 | // how many browser should be started simultaneous
76 | concurrency: Infinity
77 | });
78 | };
79 |
--------------------------------------------------------------------------------
/vision/explore-api/key.js.example:
--------------------------------------------------------------------------------
1 | // Copyright 2016, Google, Inc.
2 | // Licensed under the Apache License, Version 2.0 (the "License")
3 | // you may not use this file except in compliance with the License.
4 | // You may obtain a copy of the License at
5 | //
6 | // http://www.apache.org/licenses/LICENSE-2.0
7 | //
8 | // Unless required by applicable law or agreed to in writing, software
9 | // distributed under the License is distributed on an "AS IS" BASIS,
10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 | // See the License for the specific language governing permissions and
12 | // limitations under the License.
13 |
14 | // Replace with the key you created at https://cloud.google.com/console
15 | window.apiKey = 'YOUR API KEY HERE';
16 |
--------------------------------------------------------------------------------
/vision/explore-api/main.js:
--------------------------------------------------------------------------------
1 | // Copyright 2015, Google, Inc.
2 | // Licensed under the Apache License, Version 2.0 (the "License")
3 | // you may not use this file except in compliance with the License.
4 | // You may obtain a copy of the License at
5 | //
6 | // http://www.apache.org/licenses/LICENSE-2.0
7 | //
8 | // Unless required by applicable law or agreed to in writing, software
9 | // distributed under the License is distributed on an "AS IS" BASIS,
10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 | // See the License for the specific language governing permissions and
12 | // limitations under the License.
13 |
14 | 'use strict';
15 |
16 | var CV_URL = 'https://vision.googleapis.com/v1/images:annotate?key=' + window.apiKey;
17 |
18 | $(function () {
19 | $('#fileform').on('submit', uploadFiles);
20 | });
21 |
22 | /**
23 | * 'submit' event handler - reads the image bytes and sends it to the Cloud
24 | * Vision API.
25 | */
26 | function uploadFiles (event) {
27 | event.preventDefault(); // Prevent the default form post
28 |
29 | // Grab the file and asynchronously convert to base64.
30 | var file = $('#fileform [name=fileField]')[0].files[0];
31 | var reader = new FileReader();
32 | reader.onloadend = processFile;
33 | reader.readAsDataURL(file);
34 | }
35 |
36 | /**
37 | * Event handler for a file's data url - extract the image data and pass it off.
38 | */
39 | function processFile (event) {
40 | var content = event.target.result;
41 | sendFileToCloudVision(content.replace('data:image/jpeg;base64,', ''));
42 | }
43 |
44 | /**
45 | * Sends the given file contents to the Cloud Vision API and outputs the
46 | * results.
47 | */
48 | function sendFileToCloudVision (content) {
49 | var type = $('#fileform [name=type]').val();
50 |
51 | // Strip out the file prefix when you convert to json.
52 | var request = {
53 | requests: [{
54 | image: {
55 | content: content
56 | },
57 | features: [{
58 | type: type,
59 | maxResults: 200
60 | }]
61 | }]
62 | };
63 |
64 | $('#results').text('Loading...');
65 | $.post({
66 | url: CV_URL,
67 | data: JSON.stringify(request),
68 | contentType: 'application/json'
69 | }).fail(function (jqXHR, textStatus, errorThrown) {
70 | $('#results').text('ERRORS: ' + textStatus + ' ' + errorThrown);
71 | }).done(displayJSON);
72 | }
73 |
74 | /**
75 | * Displays the results.
76 | */
77 | function displayJSON (data) {
78 | var contents = JSON.stringify(data, null, 4);
79 | $('#results').text(contents);
80 | var evt = new Event('results-displayed');
81 | evt.results = contents;
82 | document.dispatchEvent(evt);
83 | }
84 |
--------------------------------------------------------------------------------
/vision/explore-api/main.test.js:
--------------------------------------------------------------------------------
1 | // Copyright 2016, Google, Inc.
2 | // Licensed under the Apache License, Version 2.0 (the "License")
3 | // you may not use this file except in compliance with the License.
4 | // You may obtain a copy of the License at
5 | //
6 | // http://www.apache.org/licenses/LICENSE-2.0
7 | //
8 | // Unless required by applicable law or agreed to in writing, software
9 | // distributed under the License is distributed on an "AS IS" BASIS,
10 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 | // See the License for the specific language governing permissions and
12 | // limitations under the License.
13 |
14 | 'use strict';
15 |
16 | describe('vision/explore-api/main.js', function () {
17 | before(function (done) {
18 | var fileform = document.createElement('form');
19 | fileform.id = 'fileform';
20 | document.body.appendChild(fileform);
21 |
22 | var typeSelect = document.createElement('select');
23 | typeSelect.name = 'type';
24 | fileform.appendChild(typeSelect);
25 |
26 | var labelOption = document.createElement('option');
27 | labelOption.value = 'LABEL_DETECTION';
28 | labelOption.textContent = labelOption.value;
29 | typeSelect.appendChild(labelOption);
30 |
31 | var results = document.createElement('code');
32 | results.id = 'results';
33 | document.body.appendChild(results);
34 |
35 | done();
36 | });
37 |
38 | /* eslint-disable no-undef */
39 | beforeEach(function () {
40 | window.xhr = sinon.useFakeXMLHttpRequest();
41 | window.requests = [];
42 |
43 | window.xhr.onCreate = function (xhr) {
44 | window.requests.push(xhr);
45 | };
46 | });
47 |
48 | afterEach(function () {
49 | window.xhr.restore();
50 | });
51 | /* eslint-enable no-undef */
52 |
53 | var response = {
54 | 'responses': [
55 | {
56 | 'labelAnnotations': [
57 | {
58 | 'mid': '/m/01yrx',
59 | 'description': 'cat',
60 | 'score': 0.9256294
61 | },
62 | {
63 | 'mid': '/m/04rky',
64 | 'description': 'mammal',
65 | 'score': 0.9081582
66 | },
67 | {
68 | 'mid': '/m/01l7qd',
69 | 'description': 'whiskers',
70 | 'score': 0.79939437
71 | },
72 | {
73 | 'mid': '/m/07k6w8',
74 | 'description': 'small to medium sized cats',
75 | 'score': 0.66373956
76 | },
77 | {
78 | 'mid': '/m/0307l',
79 | 'description': 'cat like mammal',
80 | 'score': 0.6595098
81 | },
82 | {
83 | 'mid': '/m/01m3tw',
84 | 'description': 'animal shelter',
85 | 'score': 0.5288319
86 | }
87 | ]
88 | }
89 | ]
90 | };
91 |
92 | it('Should request with image and appropriate max', function (done) {
93 | processFile({target: {result: window.CAT_IMAGE_DATA_URI}});
94 |
95 | window.requests[0].respond(
96 | 200,
97 | {
98 | 'Content-Type': 'application/json'
99 | },
100 | JSON.stringify(response)
101 | );
102 | var params = JSON.parse(window.requests[0].requestBody);
103 |
104 | // Check request parameters are set
105 | assert(params.requests[0].image.content.length > 1024);
106 | assert(params.requests[0].features[0].maxResults > 0);
107 | done();
108 | });
109 |
110 | it('Should label cats.', function (done) {
111 | document.addEventListener('results-displayed', function (evt) {
112 | assert(evt.results.indexOf('"description": "cat"') >= 0);
113 | done();
114 | });
115 |
116 | processFile({target: {result: window.CAT_IMAGE_DATA_URI}});
117 |
118 | window.requests[0].respond(
119 | 200,
120 | {
121 | 'Content-Type': 'application/json'
122 | },
123 | JSON.stringify(response)
124 | );
125 | });
126 | });
127 |
--------------------------------------------------------------------------------