diff --git a/.gitignore b/.gitignore index a8b1cda..52f966b 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ +*~ *.gem *.rbc /.config diff --git a/.ruby-version b/.ruby-version new file mode 100644 index 0000000..f962b8e --- /dev/null +++ b/.ruby-version @@ -0,0 +1 @@ +ruby-2.3.0@rosette-api diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..574671c --- /dev/null +++ b/.travis.yml @@ -0,0 +1,9 @@ +language: ruby +rvm: + - 2.3.0 +script: rspec tests + +notifications: + slack: + rooms: + - secure: 4FRaTAAiYyeUvgw2RhmblgbNiJO4wmd34OBgWcwURjP9oVmFfSwR9r1LNCdUGxrPOghexSY2DjXIuvIrfTfi/xYbhHb3Kw7PEAyB8IuBMlKtY4NSFou62S2VhYpxyg58T+C7P2zi0eDnDE06pwTCoGPaimxMZQY91yQ0yPYDPVXbwe5SjEgamzlwGBxlS/0A6w1iCPHg27/iO2hXtdW3oLS2I0F/Q8Q95RBkX9hpg6yqHlTV7jRbSqvQ9OFBqk/tXMHQvhoPDGgCgQDuykJuaAYx7g9d0YL0eEYYOh9B/TJ/kNOwdRFBu5kuQ2/nFS5Z0S3Y3UIhdYjUmm9gSMnwIbYnrW22EqDJLoT9Zi3Gv7Prg/8/fSkWsof7BJTMSuXUqO1AxDGKIxFv9uSF1daZoY+AC1ooU1xDu1nNvWVYPlkwEdDxxmHpFkGT3ESTZYccPovQl8Z5K0I1BBAVdJKDzm07lE6VHbxkKcvK6gG0TN3uLxnSlQtjkfJ+aVMq1kxeVsB9lEsKs9oezsKzzbftMm525aXPg+OAv+31CUFWxvT/p4ps8Q+AV6aZpoPHkpK8VryyNirUeZ/m4m4ebDHhD9vcN+JqE9gzshT+0U3g19SvLiUMQtbuZ2BUvrq2hh2LEGs03AFZaNg9AEUVA1PQRhV5NILyoS/lbiBYJPT39Sg= diff --git a/Gemfile b/Gemfile new file mode 100644 index 0000000..e031810 --- /dev/null +++ b/Gemfile @@ -0,0 +1,7 @@ +source "https://rubygems.org" + +gem 'rubysl-securerandom', '2.0.0' +gem 'rdoc', '4.2.2' + +gem 'rspec', '3.4.0', group: [:test] +gem 'webmock', '1.24.5', group: [:test] diff --git a/LICENSE b/LICENSE index 8dada3e..fd207b4 100644 --- a/LICENSE +++ b/LICENSE @@ -1,201 +1,18 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ +Basis Technology Corp - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION +Copyright (C) 2015-2015 by Basis Technology Corp and the contributors - 1. Definitions. +Complete list of developers available at our web site: - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. +www.basistech.com - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. +This program is free software: you can redistribute it and/or modify it under the terms of the +GNU Affero General Public License as published by the Free Software Foundation, either version 3 +of the License, or (at your option) any later version. - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. +This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without +even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Affero General Public License for more details. - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "{}" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright {yyyy} {name of copyright owner} - - 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. +You should have received a copy of the GNU Affero General Public License along with this program. +If not, see http://www.gnu.org/licenses/. diff --git a/README.md b/README.md index 20e4fc1..6644b6a 100644 --- a/README.md +++ b/README.md @@ -1,12 +1,25 @@ ---- -# Ruby Examples for Rosette API ---- +[![Build Status](https://travis-ci.org/rosette-api/ruby.svg?branch=develop)](https://travis-ci.org/rosette-api/ruby) -### Summary -This repository provides Ruby script examples for each of the supported Rosette API endpoints. +Ruby client binding for Rosette API +================================== +See the wiki for more information. -### Basic Usage +Installation +------------ -Install Ruby if you haven't already. Instructions can be found [here](https://www.ruby-lang.org/en/documentation/installation/). +`gem install rosette_api` -Once Ruby is installed simply run the example as: `ruby examplefile.rb your_api_key` to see the results. +Basic Usage +----------- + +See [examples](examples) + +API Documentation +----------------- + +See [documentation](http://rosette-api.github.io/ruby) + +Additional Information +---------------------- + +Visit [Rosette API site](https://developer.rosette.com) diff --git a/docker/Dockerfile b/docker/Dockerfile new file mode 100644 index 0000000..a3f2e0d --- /dev/null +++ b/docker/Dockerfile @@ -0,0 +1,22 @@ +FROM ruby +MAINTAINER Fiona Hasanaj + +# install necessary software +RUN apt-get -y update && apt-get install -y \ + vim \ + git + +RUN gem install rubysl-securerandom \ + rspec \ + webmock \ + rdoc + +RUN mkdir /ruby-dev +WORKDIR /ruby-dev +COPY run_ruby.sh run_ruby.sh +RUN chmod 0755 run_ruby.sh + +# allow interactive bash inside docker container +CMD ./run_ruby.sh $API_KEY $FILENAME $ALT_URL + +VOLUME ["/source"] diff --git a/docker/README.md b/docker/README.md new file mode 100644 index 0000000..b1e8aa7 --- /dev/null +++ b/docker/README.md @@ -0,0 +1,12 @@ +--- +# Docker Image for Ruby Examples +--- +### Summary +To simplify the running of the Ruby examples, the Dockerfile will build an image where the examples can be tested against the development source. + +### Basic Usage +Build the docker image, e.g. `docker build -t basistech/ruby:1.1 .` + +Run an example as `docker run -e API_KEY=api-key -v "path-to-local-ruby-dir:/source" basistech/ruby:1.1` + +To test against a specific source file, add `-e FILENAME=filename` before the `-v`, to test against an alternate url, add `-e ALT_URL=alternate_url`, and optionally if you would like to regenerate gh-pages from the changes made to the development source you can add `-e GIT_USERNAME=git-username -e VERSION=version` before the `-v`. In order to push the gh-pages to git remember to mount .ssh and .gitconfig to the root dir `-v path-to-.ssh-dir:/root/.ssh -v path-to-.gitconfig:/root/.gitconfig`. \ No newline at end of file diff --git a/docker/run_ruby.sh b/docker/run_ruby.sh new file mode 100644 index 0000000..acbe8f9 --- /dev/null +++ b/docker/run_ruby.sh @@ -0,0 +1,127 @@ +#!/bin/bash + +ping_url="https://api.rosette.com/rest/v1" +retcode=0 +errors=( "Exception" "processingFailure" ) + +#------------ Start Functions -------------------------- + +#Gets called when the user doesn't provide any args +function HELP { + echo -e "\nusage: source_file.rb API_KEY [ALT_URL]" + echo " API_KEY - Rosette API key (required)" + echo " FILENAME - Ruby source file (optional)" + echo " ALT_URL - Alternate service URL (optional)" + echo " GIT_USERNAME - Git username where you would like to push regenerated gh-pages (optional)" + echo " VERSION - Build version (optional)" + exit 1 +} + +#Checks if Rosette API key is valid +function checkAPI { + match=$(curl "${ping_url}/ping" -H "X-RosetteAPI-Key: ${API_KEY}" | grep -o "forbidden") + if [ ! -z $match ]; then + echo -e "\nInvalid Rosette API Key" + exit 1 + fi +} + +#Checks for valid url +function validateURL() { + match=$(curl "${ping_url}/ping" -H "X-RosetteAPI-Key: ${API_KEY}" | grep -o "Rosette API") + if [ "${match}" = "" ]; then + echo -e "\n${ping_url} server not responding\n" + exit 1 + fi +} + +function runExample() { + echo -e "\n---------- ${1} start -------------" + result="" + if [ -z ${ALT_URL} ]; then + result="$(ruby ${1} ${API_KEY} 2>&1 )" + else + result="$(ruby ${1} ${API_KEY} ${ALT_URL} 2>&1 )" + fi + echo "${result}" + echo -e "\n---------- ${1} end -------------" + for err in "${errors[@]}"; do + if [[ ${result} == *"${err}"* ]]; then + retcode=1 + fi + done +} + +#------------ End Functions ---------------------------- + +#Gets API_KEY, FILENAME and ALT_URL if present +while getopts ":API_KEY:FILENAME:ALT_URL:GIT_USERNAME:VERSION" arg; do + case "${arg}" in + API_KEY) + API_KEY=${OPTARG} + usage + ;; + ALT_URL) + ALT_URL=${OPTARG} + usage + ;; + FILENAME) + FILENAME=${OPTARG} + usage + ;; + GIT_USERNAME) + GIT_USERNAME=${OPTARG} + usage + ;; + VERSION) + VERSION={OPTARG} + usage + ;; + esac +done + +validateURL + +#Copy the mounted content in /source to current WORKDIR +cp -r -n /source/. . + +#Build rosette_api gem +gem build rosette_api.gemspec +gem install ./rosette_api-1.0.3.gem + +#Run the examples +if [ ! -z ${API_KEY} ]; then + checkAPI + cd tests + rspec tests_spec.rb + cd ../examples + if [ ! -z ${FILENAME} ]; then + runExample ${FILENAME} + else + for file in *.rb; do + runExample ${file} + done + fi +else + HELP +fi + +#Generate gh-pages and push them to git account (if git username is provided) +if [ ! -z ${GIT_USERNAME} ] && [ ! -z ${VERSION} ]; then + #clone ruby git repo + cd / + git clone git@github.com:${GIT_USERNAME}/ruby.git + cd ruby + git checkout origin/gh-pages -b gh-pages + git branch -d develop + #generate gh-pages and set ouput dir to git repo (gh-pages branch) + cd /ruby-dev/lib + rdoc -o /doc + cp -r /doc/. /ruby + cd /ruby + git add . + git commit -a -m "publish ruby apidocs ${VERSION}" + git push +fi + +exit ${retcode} diff --git a/examples/README.md b/examples/README.md index 63933b5..0b8d603 100644 --- a/examples/README.md +++ b/examples/README.md @@ -19,21 +19,20 @@ To run all of the examples: Each example, when run, prints its output to the console. | File Name | What it does | -| ------------- |------------- | -| base64_input.rb | Gets the entities from a piece of base64 encoded text| | +| ------------- |------------- | | categories.rb | Gets the category of a document at a URL | | entities.rb | Gets the entities from a piece of text | | entities_linked.rb | Gets the linked (to Wikipedia) entities from a piece of text | | info.rb | Gets information about Rosette API | | language.rb | Gets the language of a piece of text | -| matched-name.rb | Gets the similarity score of two names | +| name_similarity.rb | Gets the similarity score of two names | | morphology_complete.rb | Gets the complete morphological analysis of a piece of text| -| morphology_compound-components.rb | Gets the de-compounded words from a piece of text | -| morphology_han-readings.rb | Gets the Chinese words from a piece of text | +| morphology_compound_components.rb | Gets the de-compounded words from a piece of text | +| morphology_han_readings.rb | Gets the Chinese words from a piece of text | | morphology_lemmas.rb | Gets the lemmas of words from a piece of text | -| morphology_parts-of-speech.rb | Gets the part-of-speech tags for words in a piece of text | +| morphology_parts_of_speech.rb | Gets the part-of-speech tags for words in a piece of text | | ping.rb | Pings the Rosette API to check for reachability | | sentences.rb | Gets the sentences from a piece of text | | sentiment.rb | Gets the sentiment of a local file | | tokens.rb | Gets the tokens (words) from a piece of text | -| translated-name.rb | Translates a name from one language to another | +| name_translation.rb | Translates a name from one language to another | diff --git a/examples/categories.rb b/examples/categories.rb index eaecf30..132bd4e 100644 --- a/examples/categories.rb +++ b/examples/categories.rb @@ -1,35 +1,14 @@ -#!/usr/bin/env ruby -# encoding: utf-8 - -require "net/http" -require "net/https" -require "json" +require 'rosette_api' api_key, url = ARGV -raise "API Key required" unless api_key if !url - url = "https://api.rosette.com/rest/v1/categories" + rosette_api = RosetteAPI.new(api_key) else - url = url + "/categories" + rosette_api = RosetteAPI.new(api_key, url) end -uri = URI.parse(url) -http = Net::HTTP.new(uri.host, uri.port) -http.use_ssl = true if uri.scheme == 'https' - -request = Net::HTTP::Post.new(uri.request_uri) -request["X-RosetteAPI-Key"] = api_key -request["Content-Type"] = "application/json" -request["Accept"] = "application/json" -categories_url_data = "http://www.onlocationvacations.com/2015/03/05/the-new-ghostbusters-movie-begins-filming-in-boston-in-june/" -content = { - contentUri: categories_url_data -} -JSONbody = content.to_json - -request.body = JSONbody - -response = http.request(request) - -puts JSON.pretty_generate(JSON.parse(response.body)) +categories_url_data = 'http://www.onlocationvacations.com/2015/03/05/the-new-ghostbusters-movie-begins-filming-in-boston-in-june/' +params = DocumentParameters.new(content_uri: categories_url_data) +response = rosette_api.get_categories(params) +puts JSON.pretty_generate(response) diff --git a/examples/docker/Dockerfile b/examples/docker/Dockerfile index 1639019..192f63a 100644 --- a/examples/docker/Dockerfile +++ b/examples/docker/Dockerfile @@ -1,8 +1,10 @@ -FROM ruby:2.2.0 +FROM ruby MAINTAINER Fiona Hasanaj # install necessary software -RUN apt-get -y update && apt-get install -y vim && apt-get install -y git && gem install rubysl-securerandom +RUN apt-get -y update && apt-get install -y \ + vim \ + git RUN mkdir /ruby WORKDIR /ruby @@ -10,6 +12,6 @@ COPY run_ruby.sh run_ruby.sh RUN chmod 0755 run_ruby.sh # allow interactive bash inside docker container -CMD ./run_ruby.sh $API_KEY $FILENAME $ALT_URL +CMD ./run_ruby.sh $API_KEY $FILENAME $ALT_URL VOLUME ["/source"] diff --git a/examples/docker/README.md b/examples/docker/README.md index 596d2b8..b92cce2 100644 --- a/examples/docker/README.md +++ b/examples/docker/README.md @@ -2,7 +2,7 @@ # Docker Image for Ruby Examples --- ### Summary -To simplify the running of the Ruby examples, the Dockerfile will build an image. +To simplify the running of the Ruby examples, the Dockerfile will build an image and install the latest rosette_api gem. ### Basic Usage Build the docker image, e.g. `docker build -t basistech/ruby:1.1 .` diff --git a/examples/docker/run_ruby.sh b/examples/docker/run_ruby.sh index 6b28e3d..30f6c1f 100644 --- a/examples/docker/run_ruby.sh +++ b/examples/docker/run_ruby.sh @@ -21,19 +21,6 @@ function checkAPI { if [ ! -z $match ]; then echo -e "\nInvalid Rosette API Key" exit 1 - fi -} - - -# strip the trailing slash off of the alt_url if necessary -function cleanURL() { - if [ ! -z "${ALT_URL}" ]; then - case ${ALT_URL} in - */) ALT_URL=${ALT_URL::-1} - echo "Slash detected" - ;; - esac - ping_url=${ALT_URL} fi } @@ -43,7 +30,7 @@ function validateURL() { if [ "${match}" = "" ]; then echo -e "\n${ping_url} server not responding\n" exit 1 - fi + fi } function runExample() { @@ -56,7 +43,7 @@ function runExample() { fi echo "${result}" echo -e "\n---------- ${1} end -------------" - for err in "${errors[@]}"; do + for err in "${errors[@]}"; do if [[ ${result} == *"${err}"* ]]; then retcode=1 fi @@ -66,7 +53,7 @@ function runExample() { #------------ End Functions ---------------------------- #Gets API_KEY, FILENAME and ALT_URL if present -while getopts ":API_KEY:FILENAME:ALT_URL" arg; do +while getopts ":API_KEY:FILENAME:ALT_URL:GIT_USERNAME:VERSION" arg; do case "${arg}" in API_KEY) API_KEY=${OPTARG} @@ -83,17 +70,17 @@ while getopts ":API_KEY:FILENAME:ALT_URL" arg; do esac done -cleanURL - validateURL +#Intall rosette_api from RubyGems +gem install rosette_api + #Copy the mounted content in /source to current WORKDIR -cp -r -n /source/. . +cp /source/examples/*.* . #Run the examples if [ ! -z ${API_KEY} ]; then checkAPI - cd examples if [ ! -z ${FILENAME} ]; then runExample ${FILENAME} else @@ -101,7 +88,7 @@ if [ ! -z ${API_KEY} ]; then runExample ${file} done fi -else +else HELP fi diff --git a/examples/entities.rb b/examples/entities.rb index 2daead0..ed7625b 100644 --- a/examples/entities.rb +++ b/examples/entities.rb @@ -1,35 +1,14 @@ -#!/usr/bin/env ruby -# encoding: utf-8 - -require "net/http" -require "net/https" -require "json" +require 'rosette_api' api_key, url = ARGV -raise "API Key required" unless api_key if !url - url = "https://api.rosette.com/rest/v1/entities" + rosette_api = RosetteAPI.new(api_key) else - url = url + "/entities" + rosette_api = RosetteAPI.new(api_key, url) end -uri = URI.parse(url) -http = Net::HTTP.new(uri.host, uri.port) -http.use_ssl = true if uri.scheme == 'https' - -request = Net::HTTP::Post.new(uri.request_uri) -request["X-RosetteAPI-Key"] = api_key -request["Content-Type"] = "application/json" -request["Accept"] = "application/json" -entities_text_data = "Bill Murray will appear in new Ghostbusters film: Dr. Peter Venkman was spotted filming a cameo in Boston this… http://dlvr.it/BnsFfS" -content = { - content: entities_text_data -} -JSONbody = content.to_json - -request.body = JSONbody - -response = http.request(request) - -puts JSON.pretty_generate(JSON.parse(response.body)) +entities_text_data = 'Bill Murray will appear in new Ghostbusters film: Dr. Peter Venkman was spotted filming a cameo in Boston this… http://dlvr.it/BnsFfS' +params = DocumentParameters.new(content: entities_text_data) +response = rosette_api.get_entities(params) +puts JSON.pretty_generate(response) diff --git a/examples/entities_linked.rb b/examples/entities_linked.rb index c1c2830..cb96868 100644 --- a/examples/entities_linked.rb +++ b/examples/entities_linked.rb @@ -1,35 +1,14 @@ -#!/usr/bin/env ruby -# encoding: utf-8 - -require "net/http" -require "net/https" -require "json" +require 'rosette_api' api_key, url = ARGV -raise "API Key required" unless api_key if !url - url = "https://api.rosette.com/rest/v1/entities/linked" + rosette_api = RosetteAPI.new(api_key) else - url = url + "/entities/linked" + rosette_api = RosetteAPI.new(api_key, url) end -uri = URI.parse(url) -http = Net::HTTP.new(uri.host, uri.port) -http.use_ssl = true if uri.scheme == 'https' - -request = Net::HTTP::Post.new(uri.request_uri) -request["X-RosetteAPI-Key"] = api_key -request["Content-Type"] = "application/json" -request["Accept"] = "application/json" -entities_linked_text_data = "Last month director Paul Feig announced the movie will have an all-star female cast including Kristen Wiig, Melissa McCarthy, Leslie Jones and Kate McKinnon." -content = { - content: entities_linked_text_data -} -JSONbody = content.to_json - -request.body = JSONbody - -response = http.request(request) - -puts JSON.pretty_generate(JSON.parse(response.body)) +entities_linked_text_data = 'Last month director Paul Feig announced the movie will have an all-star female cast including Kristen Wiig, Melissa McCarthy, Leslie Jones and Kate McKinnon.' +params = DocumentParameters.new(content: entities_linked_text_data, genre: 'social-media') +response = rosette_api.get_entities(params, true) +puts JSON.pretty_generate(response) \ No newline at end of file diff --git a/examples/info.rb b/examples/info.rb index e56cc03..a82e022 100644 --- a/examples/info.rb +++ b/examples/info.rb @@ -1,26 +1,11 @@ -#!/usr/bin/env ruby -# encoding: utf-8 - -require "net/http" -require "net/https" -require "json" +require 'rosette_api' api_key, url = ARGV -raise "API Key required" unless api_key if !url - url = "https://api.rosette.com/rest/v1/info" + rosette_api = RosetteAPI.new(api_key) else - url = url + "/info" + rosette_api = RosetteAPI.new(api_key, url) end - -uri = URI.parse(url) -http = Net::HTTP.new(uri.host, uri.port) -http.use_ssl = true if uri.scheme == 'https' - -request = Net::HTTP::Get.new(uri.request_uri) -request["X-RosetteAPI-Key"] = api_key - -response = http.request(request) - -puts JSON.pretty_generate(JSON.parse(response.body)) +response = rosette_api.info +puts JSON.pretty_generate(response) \ No newline at end of file diff --git a/examples/language.rb b/examples/language.rb index e2560af..8175b2a 100644 --- a/examples/language.rb +++ b/examples/language.rb @@ -1,35 +1,14 @@ -#!/usr/bin/env ruby -# encoding: utf-8 - -require "net/http" -require "net/https" -require "json" +require 'rosette_api' api_key, url = ARGV -raise "API Key required" unless api_key if !url - url = "https://api.rosette.com/rest/v1/language" + rosette_api = RosetteAPI.new(api_key) else - url = url + "/language" + rosette_api = RosetteAPI.new(api_key, url) end -uri = URI.parse(url) -http = Net::HTTP.new(uri.host, uri.port) -http.use_ssl = true if uri.scheme == 'https' - -request = Net::HTTP::Post.new(uri.request_uri) -request["X-RosetteAPI-Key"] = api_key -request["Content-Type"] = "application/json" -request["Accept"] = "application/json" -language_data = "Por favor Señorita, says the man." -content = { - content: language_data -} -JSONbody = content.to_json - -request.body = JSONbody - -response = http.request(request) - -puts JSON.pretty_generate(JSON.parse(response.body)) +language_data = 'Por favor Señorita, says the man.?' +params = DocumentParameters.new(content: language_data) +response = rosette_api.get_language(params) +puts JSON.pretty_generate(response) \ No newline at end of file diff --git a/examples/morphology_complete.rb b/examples/morphology_complete.rb index 1152aed..0842fbd 100644 --- a/examples/morphology_complete.rb +++ b/examples/morphology_complete.rb @@ -1,35 +1,14 @@ -#!/usr/bin/env ruby -# encoding: utf-8 - -require "net/http" -require "net/https" -require "json" +require 'rosette_api' api_key, url = ARGV -raise "API Key required" unless api_key if !url - url = "https://api.rosette.com/rest/v1/morphology/complete" + rosette_api = RosetteAPI.new(api_key) else - url = url + "/morphology/complete" + rosette_api = RosetteAPI.new(api_key, url) end -uri = URI.parse(url) -http = Net::HTTP.new(uri.host, uri.port) -http.use_ssl = true if uri.scheme == 'https' - -request = Net::HTTP::Post.new(uri.request_uri) -request["X-RosetteAPI-Key"] = api_key -request["Content-Type"] = "application/json" -request["Accept"] = "application/json" -morphology_complete_data = "The quick brown fox jumped over the lazy dog. Yes he did." -content = { - content: morphology_complete_data -} -JSONbody = content.to_json - -request.body = JSONbody - -response = http.request(request) - -puts JSON.pretty_generate(JSON.parse(response.body)) +morphology_complete_data = 'The quick brown fox jumped over the lazy dog. Yes he did.' +params = DocumentParameters.new(content: morphology_complete_data) +response = rosette_api.get_morphology_complete(params) +puts JSON.pretty_generate(response) diff --git a/examples/morphology_compound-components.rb b/examples/morphology_compound-components.rb index 9d3c50b..75d1ff0 100644 --- a/examples/morphology_compound-components.rb +++ b/examples/morphology_compound-components.rb @@ -1,35 +1,14 @@ -#!/usr/bin/env ruby -# encoding: utf-8 - -require "net/http" -require "net/https" -require "json" +require 'rosette_api' api_key, url = ARGV -raise "API Key required" unless api_key if !url - url = "https://api.rosette.com/rest/v1/morphology/compound-components" + rosette_api = RosetteAPI.new(api_key) else - url = url + "/morphology/compound-components" + rosette_api = RosetteAPI.new(api_key, url) end -uri = URI.parse(url) -http = Net::HTTP.new(uri.host, uri.port) -http.use_ssl = true if uri.scheme == 'https' - -request = Net::HTTP::Post.new(uri.request_uri) -request["X-RosetteAPI-Key"] = api_key -request["Content-Type"] = "application/json" -request["Accept"] = "application/json" -morphology_compound_components_data = "Rechtsschutzversicherungsgesellschaften" -content = { - content: morphology_compound_components_data -} -JSONbody = content.to_json - -request.body = JSONbody - -response = http.request(request) - -puts JSON.pretty_generate(JSON.parse(response.body)) +morphology_compound_components_data = 'Rechtsschutzversicherungsgesellschaften' +params = DocumentParameters.new(content: morphology_compound_components_data) +response = rosette_api.get_compound_components(params) +puts JSON.pretty_generate(response) \ No newline at end of file diff --git a/examples/morphology_han-readings.rb b/examples/morphology_han-readings.rb index 10ec439..b3d0685 100644 --- a/examples/morphology_han-readings.rb +++ b/examples/morphology_han-readings.rb @@ -1,35 +1,14 @@ -#!/usr/bin/env ruby -# encoding: utf-8 - -require "net/http" -require "net/https" -require "json" +require 'rosette_api' api_key, url = ARGV -raise "API Key required" unless api_key if !url - url = "https://api.rosette.com/rest/v1/morphology/han-readings" + rosette_api = RosetteAPI.new(api_key) else - url = url + "/morphology/han-readings" + rosette_api = RosetteAPI.new(api_key, url) end -uri = URI.parse(url) -http = Net::HTTP.new(uri.host, uri.port) -http.use_ssl = true if uri.scheme == 'https' - -request = Net::HTTP::Post.new(uri.request_uri) -request["X-RosetteAPI-Key"] = api_key -request["Content-Type"] = "application/json" -request["Accept"] = "application/json" -morphology_han_readings_data = "北京大学生物系主任办公室内部会议" -content = { - content: morphology_han_readings_data -} -JSONbody = content.to_json - -request.body = JSONbody - -response = http.request(request) - -puts JSON.pretty_generate(JSON.parse(response.body)) +morphology_han_readings_data = '北京大学生物系主任办公室内部会议' +params = DocumentParameters.new(content: morphology_han_readings_data) +response = rosette_api.get_han_readings(params) +puts JSON.pretty_generate(response) \ No newline at end of file diff --git a/examples/morphology_lemmas.rb b/examples/morphology_lemmas.rb index af0f7b5..ce72907 100644 --- a/examples/morphology_lemmas.rb +++ b/examples/morphology_lemmas.rb @@ -1,35 +1,14 @@ -#!/usr/bin/env ruby -# encoding: utf-8 - -require "net/http" -require "net/https" -require "json" +require 'rosette_api' api_key, url = ARGV -raise "API Key required" unless api_key if !url - url = "https://api.rosette.com/rest/v1/morphology/lemmas" + rosette_api = RosetteAPI.new(api_key) else - url = url + "/morphology/lemmas" + rosette_api = RosetteAPI.new(api_key, url) end -uri = URI.parse(url) -http = Net::HTTP.new(uri.host, uri.port) -http.use_ssl = true if uri.scheme == 'https' - -request = Net::HTTP::Post.new(uri.request_uri) -request["X-RosetteAPI-Key"] = api_key -request["Content-Type"] = "application/json" -request["Accept"] = "application/json" morphology_lemmas_data = "The fact is that the geese just went back to get a rest and I'm not banking on their return soon" -content = { - content: morphology_lemmas_data -} -JSONbody = content.to_json - -request.body = JSONbody - -response = http.request(request) - -puts JSON.pretty_generate(JSON.parse(response.body)) +params = DocumentParameters.new(content: morphology_lemmas_data) +response = rosette_api.get_lemmas(params) +puts JSON.pretty_generate(response) \ No newline at end of file diff --git a/examples/morphology_parts-of-speech.rb b/examples/morphology_parts-of-speech.rb index 472e1db..ea65436 100644 --- a/examples/morphology_parts-of-speech.rb +++ b/examples/morphology_parts-of-speech.rb @@ -1,35 +1,14 @@ -#!/usr/bin/env ruby -# encoding: utf-8 - -require "net/http" -require "net/https" -require "json" +require 'rosette_api' api_key, url = ARGV -raise "API Key required" unless api_key if !url - url = "https://api.rosette.com/rest/v1/morphology/parts-of-speech" + rosette_api = RosetteAPI.new(api_key) else - url = url + "/morphology/parts-of-speech" + rosette_api = RosetteAPI.new(api_key, url) end -uri = URI.parse(url) -http = Net::HTTP.new(uri.host, uri.port) -http.use_ssl = true if uri.scheme == 'https' - -request = Net::HTTP::Post.new(uri.request_uri) -request["X-RosetteAPI-Key"] = api_key -request["Content-Type"] = "application/json" -request["Accept"] = "application/json" morphology_parts_of_speech_data = "The fact is that the geese just went back to get a rest and I'm not banking on their return soon" -content = { - content: morphology_parts_of_speech_data -} -JSONbody = content.to_json - -request.body = JSONbody - -response = http.request(request) - -puts JSON.pretty_generate(JSON.parse(response.body)) +params = DocumentParameters.new(content: morphology_parts_of_speech_data) +response = rosette_api.get_parts_of_speech(params) +puts JSON.pretty_generate(response) \ No newline at end of file diff --git a/examples/name_similarity.rb b/examples/name_similarity.rb index 39ce09f..b8155e0 100644 --- a/examples/name_similarity.rb +++ b/examples/name_similarity.rb @@ -1,37 +1,16 @@ -#!/usr/bin/env ruby -# encoding: utf-8 - -require "net/http" -require "net/https" -require "json" +require 'rosette_api' api_key, url = ARGV -raise "API Key required" unless api_key if !url - url = "https://api.rosette.com/rest/v1/name-similarity" + rosette_api = RosetteAPI.new(api_key) else - url = url + "/name-similarity" + rosette_api = RosetteAPI.new(api_key, url) end -uri = URI.parse(url) -http = Net::HTTP.new(uri.host, uri.port) -http.use_ssl = true if uri.scheme == 'https' - -request = Net::HTTP::Post.new(uri.request_uri) -request["X-RosetteAPI-Key"] = api_key -request["Content-Type"] = "application/json" -request["Accept"] = "application/json" -matched_name_data1 = "Michael Jackson" -matched_name_data2 = "迈克尔·杰克逊" -names = { - name1: { text: matched_name_data1 }, - name2: { text: matched_name_data2 } -} -JSONbody = names.to_json - -request.body = JSONbody - -response = http.request(request) - -puts JSON.pretty_generate(JSON.parse(response.body)) +matched_name_data1 = 'Michael Jackson' +matched_name_data2 = '迈克尔·杰克逊' +name1 = NameParameter.new(matched_name_data1, entity_type: 'PERSON', language:'eng') +params = NameSimilarityParameters.new(name1, matched_name_data2) +response = rosette_api.name_similarity(params) +puts JSON.pretty_generate(response) \ No newline at end of file diff --git a/examples/name_translation.rb b/examples/name_translation.rb index 214c0d4..efc24e3 100644 --- a/examples/name_translation.rb +++ b/examples/name_translation.rb @@ -1,37 +1,14 @@ -#!/usr/bin/env ruby -# encoding: utf-8 - -require "net/http" -require "net/https" -require "json" +require 'rosette_api' api_key, url = ARGV -raise "API Key required" unless api_key if !url - url = "https://api.rosette.com/rest/v1/name-translation" + rosette_api = RosetteAPI.new(api_key) else - url = url + "/name-translation" + rosette_api = RosetteAPI.new(api_key, url) end -uri = URI.parse(url) -http = Net::HTTP.new(uri.host, uri.port) -http.use_ssl = true if uri.scheme == 'https' - -request = Net::HTTP::Post.new(uri.request_uri) -request["X-RosetteAPI-Key"] = api_key -request["Content-Type"] = "application/json" -request["Accept"] = "application/json" -translated_name_data = "معمر محمد أبو منيار القذاف" -content = { - name: translated_name_data, - targetLanguage: "eng", - targetScript: "Latn" -} -JSONbody = content.to_json - -request.body = JSONbody - -response = http.request(request) - -puts JSON.pretty_generate(JSON.parse(response.body)) +translated_name_data = 'معمر محمد أبو منيار القذاف' +params = NameTranslationParameters.new(translated_name_data, 'eng', target_script: 'Latn') +response = rosette_api.name_translation(params) +puts JSON.pretty_generate(response) \ No newline at end of file diff --git a/examples/ping.rb b/examples/ping.rb index 98a5871..fc43e18 100644 --- a/examples/ping.rb +++ b/examples/ping.rb @@ -1,26 +1,11 @@ -#!/usr/bin/env ruby -# encoding: utf-8 - -require "net/http" -require "net/https" -require "json" +require 'rosette_api' api_key, url = ARGV -raise "API Key required" unless api_key if !url - url = "https://api.rosette.com/rest/v1/ping" + rosette_api = RosetteAPI.new(api_key) else - url = url + "/ping" + rosette_api = RosetteAPI.new(api_key, url) end - -uri = URI.parse(url) -http = Net::HTTP.new(uri.host, uri.port) -http.use_ssl = true if uri.scheme == 'https' - -request = Net::HTTP::Get.new(uri.request_uri) -request["X-RosetteAPI-Key"] = api_key - -response = http.request(request) - -puts JSON.pretty_generate(JSON.parse(response.body)) +response = rosette_api.ping +puts JSON.pretty_generate(response) \ No newline at end of file diff --git a/examples/relationships.rb b/examples/relationships.rb index acd69d5..63e98b2 100644 --- a/examples/relationships.rb +++ b/examples/relationships.rb @@ -1,35 +1,14 @@ -#!/usr/bin/env ruby -# encoding: utf-8 - -require "net/http" -require "net/https" -require "json" +require 'rosette_api' api_key, url = ARGV -raise "API Key required" unless api_key if !url - url = "https://api.rosette.com/rest/v1/relationships" + rosette_api = RosetteAPI.new(api_key) else - url = url + "/relationships" + rosette_api = RosetteAPI.new(api_key, url) end -uri = URI.parse(url) -http = Net::HTTP.new(uri.host, uri.port) -http.use_ssl = true if uri.scheme == 'https' - -request = Net::HTTP::Post.new(uri.request_uri) -request["X-RosetteAPI-Key"] = api_key -request["Content-Type"] = "application/json" -request["Accept"] = "application/json" -relationships_text_data = "The Ghostbusters movie was filmed in Boston." -content = { - content: relationships_text_data -} -JSONbody = content.to_json - -request.body = JSONbody - -response = http.request(request) - -puts JSON.pretty_generate(JSON.parse(response.body)) +relationships_text_data = 'The Ghostbusters movie was filmed in Boston.' +params = DocumentParameters.new(content: relationships_text_data) +response = rosette_api.get_relationships(params) +puts JSON.pretty_generate(response) \ No newline at end of file diff --git a/examples/sentences.rb b/examples/sentences.rb index e0b2b48..a840bbd 100644 --- a/examples/sentences.rb +++ b/examples/sentences.rb @@ -1,35 +1,18 @@ -#!/usr/bin/env ruby -# encoding: utf-8 - -require "net/http" -require "net/https" -require "json" +require 'rosette_api' api_key, url = ARGV -raise "API Key required" unless api_key if !url - url = "https://api.rosette.com/rest/v1/sentences" + rosette_api = RosetteAPI.new(api_key) else - url = url + "/sentences" + rosette_api = RosetteAPI.new(api_key, url) end -uri = URI.parse(url) -http = Net::HTTP.new(uri.host, uri.port) -http.use_ssl = true if uri.scheme == 'https' - -request = Net::HTTP::Post.new(uri.request_uri) -request["X-RosetteAPI-Key"] = api_key -request["Content-Type"] = "application/json" -request["Accept"] = "application/json" -sentences_data = "This land is your land. This land is my land\nFrom California to the New York island;\nFrom the red wood forest to the Gulf Stream waters\n\nThis land was made for you and Me.\n\nAs I was walking that ribbon of highway,\nI saw above me that endless skyway:\nI saw below me that golden valley:\nThis land was made for you and me." -content = { - content: sentences_data -} -JSONbody = content.to_json - -request.body = JSONbody - -response = http.request(request) - -puts JSON.pretty_generate(JSON.parse(response.body)) +sentences_data = 'This land is your land. This land is my land\nFrom California to the New York island;\nFrom the' \ + ' wood forest to the Gulf Stream waters\n\nThis land was made for you and Me.\n\nAs I was walking' \ + ' that ribbon of highway,\nI saw above me that endless skyway:\nI saw below me that' \ + ' golden valley:\nThis land was made for you and me.' +params = DocumentParameters.new +params.content = sentences_data +response = rosette_api.get_sentences(params) +puts JSON.pretty_generate(response) \ No newline at end of file diff --git a/examples/sentiment.rb b/examples/sentiment.rb index 0091a0c..8ddb2fd 100644 --- a/examples/sentiment.rb +++ b/examples/sentiment.rb @@ -1,55 +1,23 @@ -#!/usr/bin/env ruby -# encoding: utf-8 - -require "net/http" -require "net/https" -require "json" require 'tempfile' -require 'securerandom' +require 'rosette_api' api_key, url = ARGV -raise "API Key required" unless api_key if !url - url = "https://api.rosette.com/rest/v1/sentiment" + rosette_api = RosetteAPI.new(api_key) else - url = url + "/sentiment" + rosette_api = RosetteAPI.new(api_key, url) end -file = Tempfile.new(['foo', '.html']) -sentiment_file_data ="New Ghostbusters Film

Original Ghostbuster Dan Aykroyd, who also co-wrote the 1984 Ghostbusters film, couldn’t be more pleased with the new all-female Ghostbusters cast, telling The Hollywood Reporter, The Aykroyd family is delighted by this inheritance of the Ghostbusters torch by these most magnificent women in comedy.

" -file.write(sentiment_file_data) -file.open -request_file = {:language => "eng"} - -uri = URI.parse(url) -BOUNDARY = SecureRandom.hex -post_body = [] - -# Add the content data -post_body << "--#{BOUNDARY}\r\n" -post_body << "Content-Disposition: form-data; name=\"content\"; filename=\"#{File.basename(file)}\"\r\n" -post_body << "Content-Type: text/plain\r\n\r\n" -post_body << file.read -# Add the request data -post_body << "\r\n\r\n--#{BOUNDARY}\r\n" -post_body << "Content-Disposition: form-data; name=\"request\"\r\n" -post_body << "Content-Type: application/json\r\n\r\n" -post_body << request_file.to_json -post_body << "\r\n\r\n--#{BOUNDARY}--\r\n" - -# Create the HTTP objects -http = Net::HTTP.new(uri.host, uri.port) -http.use_ssl = true if uri.scheme == 'https' -request = Net::HTTP::Post.new(uri.request_uri) -request.add_field("Content-Type", "multipart/form-data; boundary=#{BOUNDARY}") -request.add_field("X-RosetteAPI-Key", api_key) -request.body = post_body.join - -# Send the request -response = http.request(request) -response_headers = {} -response.header.each_header {|key,value| response_headers[key] = value} -response_headers = {"responseHeaders" => response_headers} -puts JSON.pretty_generate(JSON.parse(response.body).merge(response_headers)) +file = Tempfile.new(%w(foo .html)) +sentiment_file_data = 'New Ghostbusters Film

Original Ghostbuster Dan ' \ + 'Aykroyd, who also co-wrote the 1984 Ghostbusters film, couldn’t be more pleased with the new ' \ + 'all-female Ghostbusters cast, telling The Hollywood Reporter, The Aykroyd family is delighted ' \ + 'by this inheritance of the Ghostbusters torch by these most magnificent women in comedy ' \ + '.

' +file.write(sentiment_file_data) +file.close +params = DocumentParameters.new(file_path: file.path, language: 'eng') +response = rosette_api.get_sentiment(params) +puts JSON.pretty_generate(response) \ No newline at end of file diff --git a/examples/tokens.rb b/examples/tokens.rb index 0258f52..e35194e 100644 --- a/examples/tokens.rb +++ b/examples/tokens.rb @@ -1,35 +1,14 @@ -#!/usr/bin/env ruby -# encoding: utf-8 - -require "net/http" -require "net/https" -require "json" +require 'rosette_api' api_key, url = ARGV -raise "API Key required" unless api_key if !url - url = "https://api.rosette.com/rest/v1/tokens" + rosette_api = RosetteAPI.new(api_key) else - url = url + "/tokens" + rosette_api = RosetteAPI.new(api_key, url) end -uri = URI.parse(url) -http = Net::HTTP.new(uri.host, uri.port) -http.use_ssl = true if uri.scheme == 'https' - -request = Net::HTTP::Post.new(uri.request_uri) -request["X-RosetteAPI-Key"] = api_key -request["Content-Type"] = "application/json" -request["Accept"] = "application/json" -tokens_data = "北京大学生物系主任办公室内部会议" -content = { - content: tokens_data -} -JSONbody = content.to_json - -request.body = JSONbody - -response = http.request(request) - -puts JSON.pretty_generate(JSON.parse(response.body)) +tokens_data = '北京大学生物系主任办公室内部会议' +params = DocumentParameters.new(content: tokens_data) +response = rosette_api.get_tokens(params) +puts JSON.pretty_generate(response) \ No newline at end of file diff --git a/lib/bad_request_error.rb b/lib/bad_request_error.rb new file mode 100644 index 0000000..ec71859 --- /dev/null +++ b/lib/bad_request_error.rb @@ -0,0 +1,8 @@ +require_relative 'rosette_api_error' + +# This class represents Rosette API errors with badRequest status_code. +class BadRequestError < RosetteAPIError + def initialize(message) #:notnew: + super 'badRequest', message + end +end diff --git a/lib/bad_request_format_error.rb b/lib/bad_request_format_error.rb new file mode 100644 index 0000000..71db2b4 --- /dev/null +++ b/lib/bad_request_format_error.rb @@ -0,0 +1,8 @@ +require_relative 'rosette_api_error' + +# This class represents Rosette API errors with badRequestFormat status_code. +class BadRequestFormatError < RosetteAPIError + def initialize(message) #:notnew: + super 'badRequestFormat', message + end +end diff --git a/lib/document_parameters.rb b/lib/document_parameters.rb new file mode 100644 index 0000000..631dfcc --- /dev/null +++ b/lib/document_parameters.rb @@ -0,0 +1,66 @@ +require_relative 'bad_request_format_error' + +# This class encapsulates parameters that will be used by most of the endpoints +# with exclusion of name-similarity and name-translation. +class DocumentParameters + # Content to be analyzed (required if no content_uri and file_path) + attr_accessor :content + # URL to retrieve content from and analyze (required if no content and file_path) + attr_accessor :content_uri + # File path of the file to be analyzed (required if no content and content_uri) + attr_accessor :file_path + # genre to categorize the input data + attr_accessor :genre + # ISO 639-3 language code of the provided content (optional) + attr_accessor :language + + def initialize(options = {}) #:notnew: + options = { + content: nil, + content_uri: nil, + file_path: nil, + genre: nil, + language: nil + }.update options + @content = options[:content] + @content_uri = options[:content_uri] + @file_path = options[:file_path] + @genre = options[:genre] + @language = options[:language] + end + + # Validates the parameters by checking if there are multiple content sources + # set or no content provided at all. + def validate_params + if [@content, @content_uri, @file_path].compact.length > 1 + raise BadRequestFormatError.new 'The format of the request is invalid: multiple content sources;' \ + ' must be one of an attachment, an inline "content" field, or an external' \ + '"contentUri"' + elsif [@content, @content_uri, @file_path].all?(&:nil?) + raise BadRequestFormatError.new 'The format of the request is invalid: no content provided; must' \ + ' be one of an attachment, an inline "content" field, or an external "contentUri"' + end + end + + # Converts this class to Hash with its keys in lower CamelCase. + # + # Returns the new Hash. + def load_params + self.validate_params + self.to_hash.select { |_key, value| !value.nil? } + .map { |key, value| [key.to_s.split('_').map(&:capitalize).join.sub!(/\D/, &:downcase), value] } + .to_h + end + + # Converts this class to Hash. + # + # Returns the new Hash. + def to_hash + { + content: @content, + content_uri: @content_uri, + file_path: @file_path, + language: @language + } + end +end diff --git a/lib/name_parameter.rb b/lib/name_parameter.rb new file mode 100644 index 0000000..a67b484 --- /dev/null +++ b/lib/name_parameter.rb @@ -0,0 +1,44 @@ +# This class represents an entity name in Rosette API. +class NameParameter + # Name's entity type (PERSON, LOCATION, ORGANIZATION) (optional) + attr_accessor :entity_type + # ISO 639-3 code of the name's language (optional) + attr_accessor :language + # ISO 15924 code of the name's script (optional) + attr_accessor :script + # Name to be analyzed + attr_accessor :text + + def initialize(text, options = {}) #:notnew: + options = { + entity_type: nil, + language: nil, + script: nil + }.update options + @text = text + @entity_type = options[:entity_type] + @language = options[:language] + @script = options[:script] + end + + # Converts this class to Hash with its keys in lower CamelCase. + # + # Returns the new Hash. + def load_param + self.to_hash.select { |_key, value| !value.nil? } + .map { |key, value| [key.to_s.split('_').map(&:capitalize).join.sub!(/\D/, &:downcase), value] } + .to_h + end + + # Converts this class to Hash. + # + # Returns the new Hash. + def to_hash + { + entity_type: @entity_type, + language: @language, + script: @script, + text: @text + } + end +end diff --git a/lib/name_similarity_parameters.rb b/lib/name_similarity_parameters.rb new file mode 100644 index 0000000..5a0b605 --- /dev/null +++ b/lib/name_similarity_parameters.rb @@ -0,0 +1,52 @@ +require_relative 'bad_request_error' +require_relative 'name_parameter' + +# This class encapsulates parameters that are needed for name-similarity in +# Rosette API. +class NameSimilarityParameters + # genre to categorize the input data + attr_accessor :genre + # Name to be compared to name2 + attr_accessor :name1 + # Name to be compared to name1 + attr_accessor :name2 + + def initialize(name1, name2, options = {}) #:notnew: + options = { + genre: nil + }.update options + @genre = options[:genre] + @name1 = name1 + @name2 = name2 + end + + # Validates the parameters by checking if name1 and name2 are instances of + # a String or NameParameter. + def validate_params + if [String, NameParameter].none? { |clazz| @name1.is_a? clazz } + raise BadRequestError.new('name1 option can only be an instance of a String or NameParameter') + elsif [String, NameParameter].none? { |clazz| @name2.is_a? clazz } + raise BadRequestError.new('name2 option can only be an instance of a String or NameParameter') + end + end + + # Converts this class to Hash with its keys in lower CamelCase. + # + # Returns the new Hash. + def load_params + self.validate_params + self.to_hash.select { |_key, value| !value.nil? } + .map { |key, value| [key.to_s.split('_').map(&:capitalize).join.sub!(/\D/, &:downcase), value] } + .to_h + end + + # Converts this class to Hash. + # + # Returns the new Hash. + def to_hash + { + name1: @name1.is_a?(NameParameter) ? @name1.load_param : @name1, + name2: @name2.is_a?(NameParameter) ? @name2.load_param : @name2 + } + end +end diff --git a/lib/name_translation_parameters.rb b/lib/name_translation_parameters.rb new file mode 100644 index 0000000..6d8827b --- /dev/null +++ b/lib/name_translation_parameters.rb @@ -0,0 +1,70 @@ +require_relative 'rosette_api_error' + +# This class encapsulates parameters that are needed for name-translation in +# Rosette API. +class NameTranslationParameters + # Name's entity type (PERSON, LOCATION, ORGANIZATION) (optional) + attr_accessor :entity_type + # genre to categorize the input data + attr_accessor :genre + # Name to translate + attr_accessor :name + # ISO 693-3 code of the name's native language the name originates in (optional) + attr_accessor :source_language_of_origin + # ISO 693-3 code of the name's language of use (optional) + attr_accessor :source_language_of_use + # ISO 15924 code of the name's script (optional) + attr_accessor :source_script + # ISO 639-3 code of the translation language + attr_accessor :target_language + # Transliteration scheme for the translation (optional) + attr_accessor :target_scheme + # ISO 15924 code of name's script (optional) + attr_accessor :target_script + + def initialize(name, target_language, options = {}) #:notnew: + options = { + entity_type: nil, + genre: nil, + source_language_of_origin: nil, + source_language_of_use: nil, + source_script: nil, + target_scheme: nil, + target_script: nil + }.update options + @name = name + @entity_type = options[:entity_type] + @genre = options[:genre] + @source_language_of_origin = options[:source_language_of_origin] + @source_language_of_use = options[:source_language_of_use] + @source_script = options[:source_script] + @target_language = target_language + @target_scheme = options[:target_scheme] + @target_script = options[:target_script] + end + + # Converts this class to Hash with its keys in lower CamelCase. + # + # Returns the new Hash. + def load_params + self.to_hash.select { |_key, value| !value.nil? } + .map { |key, value| [key.to_s.split('_').map(&:capitalize).join.sub!(/\D/, &:downcase), value] } + .to_h + end + + # Converts this class to Hash. + # + # Returns the new Hash. + def to_hash + { + entity_type: @entity_type, + name: @name, + source_language_of_origin: @source_language_of_origin, + source_language_of_use: @source_language_of_use, + source_script: @source_script, + target_language: @target_language, + target_scheme: @target_scheme, + target_script: @target_script + } + end +end diff --git a/lib/request_builder.rb b/lib/request_builder.rb new file mode 100644 index 0000000..d254e98 --- /dev/null +++ b/lib/request_builder.rb @@ -0,0 +1,161 @@ +# encoding: UTF-8 +require 'net/http' +require 'net/https' +require 'json' +require 'securerandom' +require_relative 'rosette_api_error' + +# This class handles all Rosette API requests. +class RequestBuilder + # Alternate Rosette API URL + attr_reader :alternate_url + # Parameters to build the body of the request from + attr_accessor :params + # Rosette API key + attr_accessor :user_key + # Rosette API binding version + attr_accessor :binding_version + + def initialize(user_key, alternate_url, params = {}, binding_version) #:notnew: + @user_key = user_key + @alternate_url = alternate_url + @params = params + @retries = 5 + @binding_version = binding_version + end + + # Prepares a plain POST request for Rosette API. + # + # ==== Attributes + # + # * +params+ - Parameters to build the body of the request. + # + # Returns a HTTP connection and the built POST request. + def prepare_plain_request(params) + begin + uri = URI.parse @alternate_url + http = Net::HTTP.new uri.host, uri.port + http.use_ssl = uri.scheme == 'https' + request = Net::HTTP::Post.new uri.request_uri + rescue + raise RosetteAPIError.new 'connectionError', 'Failed to establish connection with Rosette API server.' + end + + request['X-RosetteAPI-Key'] = @user_key + request['Content-Type'] = 'application/json' + request['Accept'] = 'application/json' + request['X-RosetteAPI-Binding'] = 'ruby' + request['X-RosetteAPI-Binding-Version'] = @binding_version + request.body = params.to_json + + [http, request] + end + + # Prepares a multipart/form-data POST request for Rosette API. + # + # ==== Attributes + # + # * +params+ - Parameters to build the body of the request. + # + # Returns a HTTP connection and the built POST request. + def prepare_multipart_request(params) + begin + file = File.open params['filePath'], 'r' + text = file.read + rescue => err + raise err + end + + boundary = SecureRandom.hex + post_body = [] + request_file = params.to_json + + # Add the content data + post_body << "--#{boundary}\r\n" + post_body << "Content-Disposition: form-data; name=\"content\"; filename=\"#{File.basename(file)}\"\r\n" + post_body << "Content-Type: text/plain\r\n\r\n" + post_body << text + + # Add the request data + post_body << "\r\n\r\n--#{boundary}\r\n" + post_body << "Content-Disposition: form-data; name=\"request\"\r\n" + post_body << "Content-Type: application/json\r\n\r\n" + post_body << request_file + post_body << "\r\n\r\n--#{boundary}--\r\n" + + # Create the HTTP objects + uri = URI.parse @alternate_url + http = Net::HTTP.new uri.host, uri.port + http.use_ssl = uri.scheme == 'https' + request = Net::HTTP::Post.new uri.request_uri + request.add_field 'Content-Type', "multipart/form-data; boundary=#{boundary}" + request.add_field 'X-RosetteAPI-Key', @user_key + request.add_field 'X-RosetteAPI-Binding', 'ruby' + request.add_field 'X-RosetteAPI-Binding-Version', @binding_version + request.body = post_body.join + + [http, request] + end + + # Sends a GET request to Rosette API. + # + # Returns JSON response or raises RosetteAPIError if encountered. + def send_get_request + uri = URI.parse @alternate_url + http = Net::HTTP.new uri.host, uri.port + http.use_ssl = uri.scheme == 'https' + + request = Net::HTTP::Get.new uri.request_uri + request['X-RosetteAPI-Key'] = @user_key + + self.get_response http, request + end + + # Sends a POST request to Rosette API. + # + # Returns JSON response or raises RosetteAPIError if encountered. + def send_post_request + if !params['filePath'].nil? + http, request = self.prepare_multipart_request params + else + http, request = self.prepare_plain_request params + end + + self.get_response http, request + end + + # Gets response from HTTP connection. + # + # ==== Attributes + # + # * +http+ - HTTP connection. + # + # * +request+ - Prepared Rosette API request. + # + # Returns JSON response or raises RosetteAPIError if encountered. + def get_response(http, request) + response = http.request request + + if response.code != '200' + message = JSON.parse(response.body)['message'] + code = JSON.parse(response.body)['code'] + if response.code == '429' + if @retries != 0 + @retries = @retries - 1 + sleep 15 + self.get_response(http, request) + else + raise RosetteAPIError.new code, message + end + else + raise RosetteAPIError.new code, message + end + else + response_headers = {} + response.header.each_header { |key, value| response_headers[key] = value } + response_headers = { responseHeaders: response_headers } + + JSON.parse(response.body).merge(response_headers) + end + end +end diff --git a/lib/rosette_api.rb b/lib/rosette_api.rb new file mode 100644 index 0000000..25f852a --- /dev/null +++ b/lib/rosette_api.rb @@ -0,0 +1,322 @@ +require_relative 'request_builder' +require_relative 'document_parameters' +require_relative 'name_translation_parameters' +require_relative 'name_similarity_parameters' +require_relative 'rosette_api_error' +require_relative 'bad_request_error' +require_relative 'bad_request_format_error' + +# This class allows you to access all Rosette API endpoints. +class RosetteAPI + # Version of Ruby binding + BINDING_VERSION = '1.0.2' + # Rosette API language endpoint + LANGUAGE_ENDPOINT = '/language' + # Rosette API morphology endpoint + MORPHOLOGY_ENDPOINT = '/morphology' + # Rosette API entities endpoint + ENTITIES_ENDPOINT = '/entities' + # Rosette API categories endpoint + CATEGORIES_ENDPOINT = '/categories' + # Rosette API relationships endpoint + RELATIONSHIPS_ENDPOINT = '/relationships' + # Rosette API sentiment endpoint + SENTIMENT_ENDPOINT = '/sentiment' + # Rosette API name-translation endpoint + NAME_TRANSLATION_ENDPOINT = '/name-translation' + # Rosette API name-similarity endpoint + NAME_SIMILARITY_ENDPOINT = '/name-similarity' + # Rosette API tokens endpoint + TOKENS_ENDPOINT = '/tokens' + # Rosette API sentences endpoint + SENTENCES_ENDPOINT = '/sentences' + # Rosette API info endpoint + INFO = '/info' + # Rosette API ping endpoint + PING = '/ping' + + # Rosette API key + attr_accessor :user_key + # Alternate Rosette API URL + attr_accessor :alternate_url + + def initialize(user_key, alternate_url = 'https://api.rosette.com/rest/v1') #:notnew: + @user_key = user_key + @alternate_url = alternate_url + + if @alternate_url.to_s.end_with?('/') + @alternate_url = alternate_url.to_s.slice(0..-2) + end + end + + # Identifies in which language(s) the input is written. + # + # ==== Attributes + # + # * +params+ - DocumentParameters helps to build the request body in RequestBuilder. + # + # Returns list of candidate languages in order of descending confidence. + def get_language(params) + check_params params + + params = params.load_params + + RequestBuilder.new(@user_key, @alternate_url + LANGUAGE_ENDPOINT, params, BINDING_VERSION) + .send_post_request + end + + # Extracts parts-of-speech, lemmas (dictionary form), compound components, + # and Han-readings for each token in the input. + # + # ==== Attributes + # + # * +params+ - DocumentParameters helps to build the request body in RequestBuilder. + # + # Returns the lemmas, compound components, Han-readings, and parts-of-speech + # tags of the input for supported languages. + def get_morphology_complete(params) + check_params params + + params = params.load_params + + RequestBuilder.new(@user_key, @alternate_url + MORPHOLOGY_ENDPOINT + '/complete', params, BINDING_VERSION) + .send_post_request + end + + # Extracts compound-components from the input. + # + # ==== Attributes + # + # * +params+ - DocumentParameters helps to build the request body in RequestBuilder. + # + # Returns list of components for each compound word of the input for supported + # languages. + def get_compound_components(params) + check_params params + + params = params.load_params + + RequestBuilder.new(@user_key, @alternate_url + MORPHOLOGY_ENDPOINT + '/compound-components', params, BINDING_VERSION) + .send_post_request + end + + # Extracts Han-readings from the input. + # + # ==== Attributes + # + # * +params+ - DocumentParameters helps to build the request body in RequestBuilder. + # + # Returns list of Han-readings which provide pronunciation information for + # Han script, in both Chinese and Japanese input text. + def get_han_readings(params) + check_params params + + params = params.load_params + + RequestBuilder.new(@user_key, @alternate_url + MORPHOLOGY_ENDPOINT + '/han-readings', params, BINDING_VERSION) + .send_post_request + end + + # Extracts lemmas from the input. + # + # ==== Attributes + # + # * +params+ - DocumentParameters helps to build the request body in RequestBuilder. + # + # Returns list of lemmas for each token of the input for supported languages. + def get_lemmas(params) + check_params params + + params = params.load_params + + RequestBuilder.new(@user_key, @alternate_url + MORPHOLOGY_ENDPOINT + '/lemmas', params, BINDING_VERSION) + .send_post_request + end + + # Extracts parts-of-speech from the input. + # + # ==== Attributes + # + # * +params+ - DocumentParameters helps to build the request body in RequestBuilder. + # + # Returns list of part-of-speech (POS) tags for each of the words of the + # input, depending on the context of how it is used. + def get_parts_of_speech(params) + check_params params + + params = params.load_params + + RequestBuilder.new(@user_key, @alternate_url + MORPHOLOGY_ENDPOINT + '/parts-of-speech', params, BINDING_VERSION) + .send_post_request + end + + # Extracts entities from the input. + # + # ==== Attributes + # + # * +params+ - DocumentParameters helps to build the request body in RequestBuilder. + # * +resolve_entities+ - Enables entities to be linked in application endpoints. + # + # Returns each entity extracted from the input. + def get_entities(params, resolve_entities = false) + check_params params + + raise BadRequestError.new('Expects boolean for resolve_entities') unless !!resolve_entities == resolve_entities + + params = params.load_params + + endpoint = resolve_entities ? (ENTITIES_ENDPOINT + '/linked') : ENTITIES_ENDPOINT + + RequestBuilder.new(@user_key, @alternate_url + endpoint, params, BINDING_VERSION) + .send_post_request + end + + # Extracts entities from the input. + # + # ==== Attributes + # + # * +params+ - DocumentParameters helps to build the request body in RequestBuilder. + # + # Returns list of entities that have been linked to entities in the knowledge + # base. + def get_entities_linked(params) + warn '[DEPRECATION] `get_entities_linked` is deprecated. Please use ' \ + '`get_entities` instead with `resolve_entities` param set to true.' + get_entities(params, true) + end + + # Extracts Tier 1 contextual categories from the input. + # + # ==== Attributes + # + # * +params+ - DocumentParameters helps to build the request body in RequestBuilder. + # + # Returns the contextual categories identified in the input. + def get_categories(params) + check_params params + + params = params.load_params + + RequestBuilder.new(@user_key, @alternate_url + CATEGORIES_ENDPOINT, params, BINDING_VERSION) + .send_post_request + end + + # Extracts relationships from the input. + # + # ==== Attributes + # + # * +params+ - DocumentParameters helps to build the request body in RequestBuilder. + # + # Returns each relationship extracted from the input. + def get_relationships(params) + check_params params + + params = params.load_params + + RequestBuilder.new(@user_key, @alternate_url + RELATIONSHIPS_ENDPOINT, params, BINDING_VERSION) + .send_post_request + end + + # Analyzes the positive and negative sentiment expressed by the input. + # + # ==== Attributes + # + # * +params+ - DocumentParameters helps to build the request body in RequestBuilder. + # + # Returns sentiment analysis results. + def get_sentiment(params) + check_params params + + params = params.load_params + + RequestBuilder.new(@user_key, @alternate_url + SENTIMENT_ENDPOINT, params, BINDING_VERSION) + .send_post_request + end + + # Translates a given name to a supported specified language. + # + # ==== Attributes + # + # * +params+ - NameTranslationParameters helps to build the request body in RequestBuilder. + # + # Returns the translation of a name. + def name_translation(params) + check_params params, 'Expects a NameTranslationParameters type as an argument', NameTranslationParameters + + params = params.load_params + + RequestBuilder.new(@user_key, @alternate_url + NAME_TRANSLATION_ENDPOINT, params, BINDING_VERSION) + .send_post_request + end + + # Compares two entity names (person, location, or organization) and returns a + # match score from 0 to 1. + # + # ==== Attributes + # + # * +params+ - NameSimilarityParameters helps to build the request body in RequestBuilder. + # + # Returns the confidence score of matching 2 names. + def name_similarity(params) + check_params params, 'Expects a NameSimilarityParameters type as an argument', NameSimilarityParameters + + params = params.load_params + + RequestBuilder.new(@user_key, @alternate_url + NAME_SIMILARITY_ENDPOINT, params, BINDING_VERSION) + .send_post_request + end + + # Divides the input into tokens. + # + # ==== Attributes + # + # * +params+ - DocumentParameters helps to build the request body in RequestBuilder. + # + # Returns list of tokens of the input. + def get_tokens(params) + check_params params + + params = params.load_params + + RequestBuilder.new(@user_key, @alternate_url + TOKENS_ENDPOINT, params, BINDING_VERSION) + .send_post_request + end + + # Divides the input into sentences. + # + # ==== Attributes + # + # * +params+ - DocumentParameters helps to build the request body in RequestBuilder. + # + # Returns list of linguistic sentences of the input. + def get_sentences(params) + check_params params + + params = params.load_params + + RequestBuilder.new(@user_key, @alternate_url + SENTENCES_ENDPOINT, params, BINDING_VERSION) + .send_post_request + end + + # Gets information about the Rosette API, returns name, build number + # and build time. + def info + RequestBuilder.new(@user_key, @alternate_url + INFO, BINDING_VERSION) + .send_get_request + end + + # Pings the Rosette API for a response indicting that the service is + # available. + def ping + RequestBuilder.new(@user_key, @alternate_url + PING, BINDING_VERSION) + .send_get_request + end + + private + + # Checks that the right parameter type is being passed in. + def check_params(params, message = 'Expects a DocumentParameters type as an argument', type = DocumentParameters) + raise BadRequestError.new message unless params.is_a? type + end +end + diff --git a/lib/rosette_api_error.rb b/lib/rosette_api_error.rb new file mode 100644 index 0000000..20f9648 --- /dev/null +++ b/lib/rosette_api_error.rb @@ -0,0 +1,13 @@ +# This class encapsulates all Rosette API server errors encountered during +# requests. +class RosetteAPIError < StandardError + # Rosette API error's status code + attr_accessor :status_code + # Rosette API error's message + attr_accessor :message + + def initialize(status_code, message) #:notnew: + @status_code = status_code + @message = message + end +end \ No newline at end of file diff --git a/mock-data/request/categories.json b/mock-data/request/categories.json new file mode 100644 index 0000000..74548df --- /dev/null +++ b/mock-data/request/categories.json @@ -0,0 +1 @@ +{"contentUri":"http://www.onlocationvacations.com/2015/03/05/the-new-ghostbusters-movie-begins-filming-in-boston-in-june/"} \ No newline at end of file diff --git a/mock-data/request/entities.json b/mock-data/request/entities.json new file mode 100644 index 0000000..c3f2150 --- /dev/null +++ b/mock-data/request/entities.json @@ -0,0 +1 @@ +{"content":"Bill Murray will appear in new Ghostbusters film: Dr. Peter Venkman was spotted filming a cameo in Boston this… http://dlvr.it/BnsFfS"} \ No newline at end of file diff --git a/mock-data/request/entities_linked.json b/mock-data/request/entities_linked.json new file mode 100644 index 0000000..8027d1c --- /dev/null +++ b/mock-data/request/entities_linked.json @@ -0,0 +1 @@ +{"content":"Last month director Paul Feig announced the movie will have an all-star female cast including Kristen Wiig, Melissa McCarthy, Leslie Jones and Kate McKinnon."} \ No newline at end of file diff --git a/mock-data/request/language.json b/mock-data/request/language.json new file mode 100644 index 0000000..e7cafb2 --- /dev/null +++ b/mock-data/request/language.json @@ -0,0 +1 @@ +{"content":"Por favor Senorita, says the man.?"} \ No newline at end of file diff --git a/mock-data/request/morphology_complete.json b/mock-data/request/morphology_complete.json new file mode 100644 index 0000000..e6c83eb --- /dev/null +++ b/mock-data/request/morphology_complete.json @@ -0,0 +1 @@ +{"content":"The quick brown fox jumped over the lazy dog. Yes he did."} \ No newline at end of file diff --git a/mock-data/request/morphology_compound_components.json b/mock-data/request/morphology_compound_components.json new file mode 100644 index 0000000..4e436e8 --- /dev/null +++ b/mock-data/request/morphology_compound_components.json @@ -0,0 +1 @@ +{"content":"Rechtsschutzversicherungsgesellschaften"} \ No newline at end of file diff --git a/mock-data/request/morphology_han_readings.json b/mock-data/request/morphology_han_readings.json new file mode 100644 index 0000000..8060d2e --- /dev/null +++ b/mock-data/request/morphology_han_readings.json @@ -0,0 +1 @@ +{"content":"北京大学生物系主任办公室内部会议"} \ No newline at end of file diff --git a/mock-data/request/morphology_lemmas.json b/mock-data/request/morphology_lemmas.json new file mode 100644 index 0000000..a84a11d --- /dev/null +++ b/mock-data/request/morphology_lemmas.json @@ -0,0 +1 @@ +{"content":"The fact is that the geese just went back to get a rest and I'm not banking on their return soon"} \ No newline at end of file diff --git a/mock-data/request/morphology_parts_of_speech.json b/mock-data/request/morphology_parts_of_speech.json new file mode 100644 index 0000000..a84a11d --- /dev/null +++ b/mock-data/request/morphology_parts_of_speech.json @@ -0,0 +1 @@ +{"content":"The fact is that the geese just went back to get a rest and I'm not banking on their return soon"} \ No newline at end of file diff --git a/mock-data/request/name_similarity.json b/mock-data/request/name_similarity.json new file mode 100644 index 0000000..7722333 --- /dev/null +++ b/mock-data/request/name_similarity.json @@ -0,0 +1 @@ +{"name1":"Michael Jackson","name2":"迈克尔·杰克逊"} \ No newline at end of file diff --git a/mock-data/request/name_translation.json b/mock-data/request/name_translation.json new file mode 100644 index 0000000..91704eb --- /dev/null +++ b/mock-data/request/name_translation.json @@ -0,0 +1 @@ +{"name":"معمر محمد أبو منيار القذاف","targetLanguage":"eng","targetScript":"Latn"} \ No newline at end of file diff --git a/mock-data/request/relationships.json b/mock-data/request/relationships.json new file mode 100644 index 0000000..011595c --- /dev/null +++ b/mock-data/request/relationships.json @@ -0,0 +1 @@ +{"content":"The Ghostbusters movie was filmed in Boston."} \ No newline at end of file diff --git a/mock-data/request/sentences.json b/mock-data/request/sentences.json new file mode 100644 index 0000000..ec32d53 --- /dev/null +++ b/mock-data/request/sentences.json @@ -0,0 +1 @@ +{"content":"This land is your land. This land is my land\\nFrom California to the New York island;\\nFrom the wood forest to the Gulf Stream waters\\n\\nThis land was made for you and Me.\\n\\nAs I was walking that ribbon of highway,\\nI saw above me that endless skyway:\\nI saw below me that golden valley:\\nThis land was made for you and me."} \ No newline at end of file diff --git a/mock-data/request/sentiment.json b/mock-data/request/sentiment.json new file mode 100644 index 0000000..2cbc3ad --- /dev/null +++ b/mock-data/request/sentiment.json @@ -0,0 +1 @@ +{"content":"New Ghostbusters Film

Original Ghostbuster Dan Aykroyd, who also co-wrote the 1984 Ghostbusters film, couldn’t be more pleased with the new all-female Ghostbusters cast, telling The Hollywood Reporter, The Aykroyd family is delighted by this inheritance of the Ghostbusters torch by these most magnificent women in comedy.

"} \ No newline at end of file diff --git a/mock-data/request/tokens.json b/mock-data/request/tokens.json new file mode 100644 index 0000000..8060d2e --- /dev/null +++ b/mock-data/request/tokens.json @@ -0,0 +1 @@ +{"content":"北京大学生物系主任办公室内部会议"} \ No newline at end of file diff --git a/rosette_api.gemspec b/rosette_api.gemspec new file mode 100644 index 0000000..dc2298a --- /dev/null +++ b/rosette_api.gemspec @@ -0,0 +1,31 @@ +lib = File.expand_path('../lib', __FILE__) +$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib) + +Gem::Specification.new do |s| + s.specification_version = 2 if s.respond_to? :specification_version= + s.required_rubygems_version = Gem::Requirement.new('>= 0') if s.respond_to? :required_rubygems_version= + s.rubygems_version = '2.2.2' + s.required_ruby_version = '>= 2.0.0' + + s.name = 'rosette_api' + s.version = '1.0.3' + s.license = 'MIT' + + s.summary = 'Rosette API gem that supports multilingual text-analytics.' + s.description = %q{A Ruby client binding for the Rosette API, a multilingual text analytics RESTful API.} + + + + s.authors = ['Basis Technology Corp'] + s.email = %q{support@rosette.com} + s.homepage = %q{https://developer.rosette.com/} + s.date = %q{2016-05-03} + + all_files = `git ls-files -z`.split("\x0") + s.files = all_files.grep(%r{^(bin|lib)/|^.rubocop.yml$}) + s.test_files = ['tests/tests_spec.rb'] + s.require_paths = ['lib'] + s.default_executable = 'rosette_api' + + s.add_runtime_dependency('rubysl-securerandom', '~> 2.0') +end \ No newline at end of file diff --git a/tests/tests_spec.rb b/tests/tests_spec.rb new file mode 100644 index 0000000..b39c1c8 --- /dev/null +++ b/tests/tests_spec.rb @@ -0,0 +1,395 @@ +# encoding: UTF-8 +require 'rosette_api' +require 'rspec' +require 'webmock/rspec' +require 'json' +WebMock.disable_net_connect!(allow_localhost: true) + +describe RosetteAPI do + + describe '.get_language' do + request_file = File.read File.expand_path(File.join(File.dirname(__FILE__), '../mock-data/request/language.json')) + before do + stub_request(:post, 'https://api.rosette.com/rest/v1/language'). + with(body: request_file, + headers: {'Accept' => 'application/json', + 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', + 'Content-Type' => 'application/json', + 'User-Agent' => 'Ruby', + 'X-Rosetteapi-Key' => '0123456789', + 'X-Rosetteapi-Binding' => 'ruby', + 'X-Rosetteapi-Binding-Version' => '1.0.2'}). + to_return(status: 200, body: {'test': 'language'}.to_json, headers: {}) + end + it 'test language' do + params = DocumentParameters.new + params.content = 'Por favor Senorita, says the man.?' + response = RosetteAPI.new('0123456789').get_language(params) + expect(response).instance_of? Hash + end + + it 'badRequestFormat: the format of the request is invalid: multiple content sources' do + params = DocumentParameters.new + params.content = 'Por favor Senorita, says the man.?' + params.content_uri = 'Por favor Senorita, says the man.?' + expect { RosetteAPI.new('0123456789').get_language(params) }.to raise_error(BadRequestFormatError) + end + + it 'badRequestFormat: the format of the request is invalid: no content provided;' do + params = DocumentParameters.new + expect { RosetteAPI.new('0123456789') + .get_language(params) } + .to raise_error(BadRequestFormatError) + end + + end + + describe '.get_morphology_complete' do + request_file = File.read File.expand_path(File.join(File.dirname(__FILE__), '../mock-data/request/morphology_complete.json')) + before do + stub_request(:post, 'https://api.rosette.com/rest/v1/morphology/complete'). + with(body: request_file, + headers: {'Accept' => 'application/json', + 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', + 'Content-Type' => 'application/json', + 'User-Agent' => 'Ruby', + 'X-Rosetteapi-Key' => '0123456789', + 'X-Rosetteapi-Binding' => 'ruby', + 'X-Rosetteapi-Binding-Version' => '1.0.2'}). + to_return(status: 200, body: {'test': 'morphology/complete'}.to_json, headers: {}) + end + it 'test morphology complete' do + params = DocumentParameters.new + params.content = 'The quick brown fox jumped over the lazy dog. Yes he did.' + response = RosetteAPI.new('0123456789').get_morphology_complete(params) + expect(response).instance_of? Hash + end + end + + describe '.get_compound_components' do + request_file = File.read File.expand_path(File.join(File.dirname(__FILE__), '../mock-data/request/morphology_compound_components.json')) + before do + stub_request(:post, 'https://api.rosette.com/rest/v1/morphology/compound-components'). + with(body: request_file, + headers: {'Accept' => 'application/json', + 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', + 'Content-Type' => 'application/json', + 'User-Agent' => 'Ruby', + 'X-Rosetteapi-Key' => '0123456789', + 'X-Rosetteapi-Binding' => 'ruby', + 'X-Rosetteapi-Binding-Version' => '1.0.2'}). + to_return(status: 200, body: {'test': 'morphology/compound-components'}.to_json, headers: {}) + end + it 'test morphology compound components' do + params = DocumentParameters.new + params.content = 'Rechtsschutzversicherungsgesellschaften' + response = RosetteAPI.new('0123456789').get_compound_components(params) + expect(response).instance_of? Hash + end + end + + describe '.get_han_readings' do + request_file = File.read File.expand_path(File.join(File.dirname(__FILE__), '../mock-data/request/morphology_han_readings.json')), encoding: 'utf-8' + before do + stub_request(:post, 'https://api.rosette.com/rest/v1/morphology/han-readings'). + with(body: request_file, + headers: {'Accept' => 'application/json', + 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', + 'Content-Type' => 'application/json', + 'User-Agent' => 'Ruby', + 'X-Rosetteapi-Key' => '0123456789', + 'X-Rosetteapi-Binding' => 'ruby', + 'X-Rosetteapi-Binding-Version' => '1.0.2'}). + to_return(status: 200, body: {'test': 'morphology/han-readings'}.to_json, headers: {}) + end + it 'test morphology han readings' do + params = DocumentParameters.new + params.content = '北京大学生物系主任办公室内部会议' + response = RosetteAPI.new('0123456789').get_han_readings(params) + expect(response).instance_of? Hash + end + end + + describe '.get_parts_of_speech' do + request_file = File.read File.expand_path(File.join(File.dirname(__FILE__), '../mock-data/request/morphology_parts_of_speech.json')) + before do + stub_request(:post, 'https://api.rosette.com/rest/v1/morphology/parts-of-speech'). + with(body: request_file, + headers: {'Accept' => 'application/json', + 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', + 'Content-Type' => 'application/json', + 'User-Agent' => 'Ruby', + 'X-Rosetteapi-Key' => '0123456789', + 'X-Rosetteapi-Binding' => 'ruby', + 'X-Rosetteapi-Binding-Version' => '1.0.2'}). + to_return(status: 200, body: {'test': 'morphology/parts-of-speech'}.to_json, headers: {}) + end + it 'test morphology parts of speech' do + params = DocumentParameters.new + params.content = "The fact is that the geese just went back to get a rest and I'm not banking on their return soon" + response = RosetteAPI.new('0123456789').get_parts_of_speech(params) + expect(response).instance_of? Hash + end + end + + describe '.get_lemmas' do + request_file = File.read File.expand_path(File.join(File.dirname(__FILE__), '../mock-data/request/morphology_lemmas.json')) + before do + stub_request(:post, 'https://api.rosette.com/rest/v1/morphology/lemmas'). + with(body: request_file, + headers: {'Accept' => 'application/json', + 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', + 'Content-Type' => 'application/json', + 'User-Agent' => 'Ruby', + 'X-Rosetteapi-Key' => '0123456789', + 'X-Rosetteapi-Binding' => 'ruby', + 'X-Rosetteapi-Binding-Version' => '1.0.2'}). + to_return(status: 200, body: {'test': 'morphology/lemmas'}.to_json, headers: {}) + end + it 'test morphology lemmas' do + params = DocumentParameters.new + params.content = "The fact is that the geese just went back to get a rest and I'm not banking on their return soon" + response = RosetteAPI.new('0123456789').get_lemmas(params) + expect(response).instance_of? Hash + end + end + + describe '.get_entities' do + request_file = File.read File.expand_path(File.join(File.dirname(__FILE__), '../mock-data/request/entities.json')), encoding: 'utf-8' + before do + stub_request(:post, 'https://api.rosette.com/rest/v1/entities'). + with(body: request_file, + headers: {'Accept' => 'application/json', + 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', + 'Content-Type' => 'application/json', + 'User-Agent' => 'Ruby', + 'X-Rosetteapi-Key' => '0123456789', + 'X-Rosetteapi-Binding' => 'ruby', + 'X-Rosetteapi-Binding-Version' => '1.0.2'}). + to_return(status: 200, body: {'test': 'entities'}.to_json, headers: {}) + end + it 'test entities' do + params = DocumentParameters.new + params.content = 'Bill Murray will appear in new Ghostbusters film: Dr. Peter Venkman was spotted filming a' \ + ' cameo in Boston this… http://dlvr.it/BnsFfS' + response = RosetteAPI.new('0123456789').get_entities(params) + expect(response).instance_of? Hash + end + end + + describe '.get_entities_linked' do + request_file = File.read File.expand_path(File.join(File.dirname(__FILE__), '../mock-data/request/entities_linked.json')) + before do + stub_request(:post, 'https://api.rosette.com/rest/v1/entities/linked'). + with(body: request_file, + headers: {'Accept' => 'application/json', + 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', + 'Content-Type' => 'application/json', + 'User-Agent' => 'Ruby', + 'X-Rosetteapi-Key' => '0123456789', + 'X-Rosetteapi-Binding' => 'ruby', + 'X-Rosetteapi-Binding-Version' => '1.0.2'}). + to_return(status: 200, body: {'test': 'entities/linked'}.to_json, headers: {}) + end + it 'test entities linked' do + params = DocumentParameters.new + params.content = 'Last month director Paul Feig announced the movie will have an all-star female cast including' \ + ' Kristen Wiig, Melissa McCarthy, Leslie Jones and Kate McKinnon.' + response = RosetteAPI.new('0123456789').get_entities(params, true) + expect(response).instance_of? Hash + end + + it 'test entities linked for resolve_entities is not a boolean' do + params = DocumentParameters.new + params.content = 'Last month director Paul Feig announced the movie will have an all-star female cast including' \ + ' Kristen Wiig, Melissa McCarthy, Leslie Jones and Kate McKinnon.' + expect { RosetteAPI.new('0123456789').get_entities(params, 'smth') }.to raise_error(BadRequestError) + end + end + + describe '.get_categories' do + request_file = File.read File.expand_path(File.join(File.dirname(__FILE__), '../mock-data/request/categories.json')) + before do + stub_request(:post, 'https://api.rosette.com/rest/v1/categories'). + with(body: request_file, + headers: {'Accept' => 'application/json', + 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', + 'Content-Type' => 'application/json', + 'User-Agent' => 'Ruby', + 'X-Rosetteapi-Key' => '0123456789', + 'X-Rosetteapi-Binding' => 'ruby', + 'X-Rosetteapi-Binding-Version' => '1.0.2'}). + to_return(status: 200, body: {'test': 'categories'}.to_json, headers: {}) + end + it 'test categories' do + params = DocumentParameters.new + params.content_uri = 'http://www.onlocationvacations.com/2015/03/05/the-new-ghostbusters-movie-begins-filming-in-boston-in-june/' + response = RosetteAPI.new('0123456789').get_categories(params) + expect(response).instance_of? Hash + end + end + + describe '.get_relationships' do + request_file = File.read File.expand_path(File.join(File.dirname(__FILE__), '../mock-data/request/relationships.json')) + before do + stub_request(:post, 'https://api.rosette.com/rest/v1/relationships'). + with(body: request_file, + headers: {'Accept' => 'application/json', + 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', + 'Content-Type' => 'application/json', + 'User-Agent' => 'Ruby', + 'X-Rosetteapi-Key' => '0123456789', + 'X-Rosetteapi-Binding' => 'ruby', + 'X-Rosetteapi-Binding-Version' => '1.0.2'}). + to_return(status: 200, body: {'test': 'relationships'}.to_json, headers: {}) + end + it 'test relationships' do + params = DocumentParameters.new + params.content = 'The Ghostbusters movie was filmed in Boston.' + response = RosetteAPI.new('0123456789').get_relationships(params) + expect(response).instance_of? Hash + end + end + + describe '.name_translation' do + request_file = File.read File.expand_path(File.join(File.dirname(__FILE__), '../mock-data/request/name_translation.json')), encoding: 'utf-8' + before do + stub_request(:post, 'https://api.rosette.com/rest/v1/name-translation'). + with(body: request_file, + headers: {'Accept' => 'application/json', + 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', + 'Content-Type' => 'application/json', + 'User-Agent' => 'Ruby', + 'X-Rosetteapi-Key' => '0123456789', + 'X-Rosetteapi-Binding' => 'ruby', + 'X-Rosetteapi-Binding-Version' => '1.0.2'}). + to_return(status: 200, body: {'test': 'name-translation'}.to_json, headers: {}) + end + it 'test name translation' do + params = NameTranslationParameters.new('معمر محمد أبو منيار القذاف'.encode('UTF-8'), 'eng') + params.target_script = 'Latn' + response = RosetteAPI.new('0123456789').name_translation(params) + expect(response).instance_of? Hash + end + + it 'badRequest: Expects NameTransaltionParameters type as an argument' do + params = NameSimilarityParameters.new('Michael Jackson', '迈克尔·杰克逊') + expect { RosetteAPI.new('0123456789').name_translation(params) }.to raise_error(BadRequestError) + end + end + + describe '.name_similarity' do + request_file = File.read File.expand_path(File.join(File.dirname(__FILE__), '../mock-data/request/name_similarity.json')), encoding: 'utf-8' + before do + stub_request(:post, 'https://api.rosette.com/rest/v1/name-similarity'). + with(body: request_file, + headers: {'Accept' => 'application/json', + 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', + 'Content-Type' => 'application/json', + 'User-Agent' => 'Ruby', + 'X-Rosetteapi-Key' => '0123456789', + 'X-Rosetteapi-Binding' => 'ruby', + 'X-Rosetteapi-Binding-Version' => '1.0.2'}). + to_return(status: 200, body: {'test': 'name-similarity'}.to_json, headers: {}) + end + it 'test name similarity' do + params = NameSimilarityParameters.new('Michael Jackson', '迈克尔·杰克逊') + response = RosetteAPI.new('0123456789').name_similarity(params) + expect(response).instance_of? Hash + end + + it 'badRequestFormat: name1 option can only be an instance of a String or NameParameter' do + params = NameSimilarityParameters.new(123, 'Michael Jackson') + expect { RosetteAPI.new('0123456789').name_similarity(params) }.to raise_error(BadRequestError) + end + + it 'badRequestFormat: name2 option can only be an instance of a String or NameParameter' do + params = NameSimilarityParameters.new('Michael Jackson', 123) + expect { RosetteAPI.new('0123456789').name_similarity(params) }.to raise_error(BadRequestError) + end + + it 'badRequest: Expects NameSimilarityParameters type as an argument' do + params = NameTranslationParameters.new('معمر محمد أبو منيار القذاف'.encode('UTF-8'), 'eng') + expect { RosetteAPI.new('0123456789').name_similarity(params) }.to raise_error(BadRequestError) + end + end + + describe '.get_tokens' do + request_file = File.read File.expand_path(File.join(File.dirname(__FILE__), '../mock-data/request/tokens.json')), encoding: 'utf-8' + before do + stub_request(:post, 'https://api.rosette.com/rest/v1/tokens'). + with(body: request_file, + headers: {'Accept' => 'application/json', + 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', + 'Content-Type' => 'application/json', + 'User-Agent' => 'Ruby', + 'X-Rosetteapi-Key' => '0123456789', + 'X-Rosetteapi-Binding' => 'ruby', + 'X-Rosetteapi-Binding-Version' => '1.0.2'}). + to_return(status: 200, body: {'test': 'tokens'}.to_json, headers: {}) + end + it 'test tokens' do + params = DocumentParameters.new + params.content = '北京大学生物系主任办公室内部会议' + response = RosetteAPI.new('0123456789').get_tokens(params) + expect(response).instance_of? Hash + end + end + + describe '.get_sentences' do + request_file = File.read File.expand_path(File.join(File.dirname(__FILE__), '../mock-data/request/sentences.json')) + before do + stub_request(:post, 'https://api.rosette.com/rest/v1/sentences'). + with(body: request_file, + headers: {'Accept' => 'application/json', + 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', + 'Content-Type' => 'application/json', + 'User-Agent' => 'Ruby', + 'X-Rosetteapi-Key' => '0123456789', + 'X-Rosetteapi-Binding' => 'ruby', + 'X-Rosetteapi-Binding-Version' => '1.0.2'}). + to_return(status: 200, body: {'test': 'sentences'}.to_json, headers: {}) + end + it 'test sentences' do + params = DocumentParameters.new + params.content = 'This land is your land. This land is my land\nFrom California to the New York island;\nFrom' \ + ' the wood forest to the Gulf Stream waters\n\nThis land was made for you and Me.\n\nAs I was' \ + ' walking that ribbon of highway,\nI saw above me that endless skyway:\nI saw below me that' \ + ' golden valley:\nThis land was made for you and me.' + response = RosetteAPI.new('0123456789').get_sentences(params) + expect(response).instance_of? Hash + end + end + + describe '.info' do + before do + stub_request(:get, 'https://api.rosette.com/rest/v1/info'). + with(headers: {'Accept' => '*/*', + 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', + 'User-Agent' => 'Ruby', + 'X-Rosetteapi-Key' => '0123456789'}). + to_return(status: 200, body: {'test': 'info'}.to_json, headers: {}) + end + it 'test info' do + response = RosetteAPI.new('0123456789').info + expect(response).instance_of? Hash + end + end + + describe '.ping' do + before do + stub_request(:get, 'https://api.rosette.com/rest/v1/ping'). + with(headers: {'Accept' => '*/*', + 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', + 'User-Agent' => 'Ruby', + 'X-Rosetteapi-Key' => '0123456789'}). + to_return(status: 200, body: {'test': 'ping'}.to_json, headers: {}) + end + it 'test ping' do + response = RosetteAPI.new('0123456789').ping + expect(response).instance_of? Hash + end + end + + +end