rb_conclas 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 1bdc14b341c69336cde461396e2adee385e29b41
4
+ data.tar.gz: 3659aaaae7ece1c8b3138515cf4f66630b86e727
5
+ SHA512:
6
+ metadata.gz: a191d21e26b0fd6965e66628c2f79989140bbfa26595615eea36824c941b4962158cb681c13794bf73186c6c768b487023c7f62b9591f3b04af5c879993d7772
7
+ data.tar.gz: 2bc84f2f326677e978d93233b25c7f51943bafba4589b9d4e795dd5a17114027b7b48f9ee8a02dcaf829fc6c9e8d775927ffe341e257e74747c1fc27102d1a74
data/.gitignore ADDED
@@ -0,0 +1,9 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --format documentation
2
+ --color
data/.travis.yml ADDED
@@ -0,0 +1,4 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.3.0
4
+ before_install: gem install bundler -v 1.11.2
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in rb_conclas.gemspec
4
+ gemspec
data/README.md ADDED
@@ -0,0 +1,64 @@
1
+ # rb_conclas
2
+
3
+ O rb_conclas é um client escrito em Ruby para utilizar o serviço Conclas
4
+
5
+ # Métodos
6
+ Antes de mais nada, devemos importar a classe Api que possui os dois métodos principais, sendo eles: o **direct_categorise()** e o **indirect_categorise()**. A classe Api fica dentro do módulo *Conclas*. Sendo assim, vejamos o exemplo abaixo:
7
+
8
+ ```ruby
9
+ require 'rb_conclas'
10
+ ```
11
+
12
+ ## *indirect_categorise()*
13
+ O método *indirect_categorise()* faz uma requisição no endpoint *categorise* da API. Ele permite que caso os conteúdos ainda não tenham sidos classificados, jogue-os diretamente em uma fila para classificação.
14
+
15
+ | Parâmetro | Descrição | Tipo | Exigido? |
16
+ |---------------------|---------------------------------------------------------------|------|----------|
17
+ | contents | Passa uma lista de conteúdos utilizados no json da requisição. | Array | Sim |
18
+ ## *direct_categorise()*
19
+ O método *direct_categorise()* faz uma requisição no endpoint *direct_categorise* da API. Este método permite que caso os conteúdos não tenham sido classficados ainda, faça com que esta request seja bloqueada até o conteúdo ser classificado.
20
+
21
+ | Parâmetro | Descrição | Tipo | Exigido? |
22
+ |---------------------|-----------------------------------------------------------------|------|----------|
23
+ | contents | Passa uma lista de conteúdos utilizados no json da requisição. | Array | Sim |
24
+ | callback | Passa uma url para ser chamada após o término da categorização. | String | Sim |
25
+ ### Parâmetro *contents*
26
+ O parâmetro *contents* é muito importante para a requisição, pois nele contém os dados a serem analisados pela API. Ele possui uma lista de dicionários, onde cada dicionário pode conter uma doc(uma chave "values") ou uma url(uma chave "url") mas nunca as duas no mesmo dicionário.
27
+
28
+ A doc nada mais é do que um dicionário, que poderá receber os seguintes valores.
29
+
30
+ | Parâmetro | Descrição |
31
+ |------------|---------------------------------------------------------------------------------------|
32
+ | short_text | Corresponde a uma breve descrição do conteúdo a ser analisado. Geralmente é o título. |
33
+ | long_text | Corresponde ao conteúdo a ser analisado. |
34
+ | brands | Corresponde a marcas que ajudam na categorização do conteúdo. |
35
+ ## Exemplo de utilização
36
+
37
+ ```ruby
38
+ require 'rb_conclas'
39
+
40
+ api = Conclas::Api.new("c6887e5fcff94746bc5f-2a931ed27123")
41
+
42
+ contents = [
43
+ {
44
+ "url" => "meusite.com"
45
+ },
46
+ {
47
+ "doc" => {
48
+ "short_text" => "Título da documento",
49
+ "long_text" => "Conteúdo do página",
50
+ "brands" => "apple samsung"
51
+ }
52
+ }
53
+ ]
54
+
55
+ api.direct_categorise(contents)
56
+ puts api.result
57
+ ```
58
+ Após realizar alguma requisição(seja através do método direct ou indirect) o *rb_conclas* popula algumas variáveis que nos fornecem informações como: headers, código de status e resultado da requisição. Essas propriedades são: **headers**, **result** e **status_code**.
59
+
60
+ | Propriedade | Descrição | Tipo |
61
+ |-------------|--------------------------------------------------------------------------------------|-----------------------------------------------|
62
+ | status_code | Código de status da requisição.(Exemplo, pode retornar 200, caso tudo tenha sido OK) | Fixnum |
63
+ | result | Resultado da requisição, geralmente vem em forma JSON. | Hash |
64
+ | headers | Mostra os headers da requisição | Hash |
data/Rakefile ADDED
@@ -0,0 +1,6 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task :default => :spec
data/bin/console ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "rb_conclas"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start
data/bin/setup ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,130 @@
1
+ # coding: utf-8
2
+
3
+ require 'rb_conclas/core/requester'
4
+ require 'rb_conclas/core/exceptions/client_exceptions'
5
+ require 'rb_conclas/core/conclas_response'
6
+ require 'rb_conclas/utils/json_maker'
7
+ require 'rb_conclas/utils/string_helper'
8
+ require 'json'
9
+
10
+ BASE_URL = "http://localhost:5000/v1"
11
+ METHODS = {
12
+ :direct => "/categorise/direct/",
13
+ :indirect => "/categorise/indirect/"
14
+ }
15
+
16
+ module Conclas
17
+ #module to abstract request
18
+ class Api
19
+ #include methods of class Request
20
+ include Core::Requester
21
+
22
+ def initialize(token, timeout=60, use_ssl=false)
23
+ @timeout = timeout
24
+ if Utils::StringHelper.is_empty token
25
+ raise EmptyParameterException, "The parameter 'token' needs a value"
26
+ end
27
+ @token = token
28
+ @use_ssl = use_ssl
29
+ @status_code = nil
30
+ @headers = nil
31
+ @result = nil
32
+ @req = nil
33
+ end
34
+
35
+ #properties
36
+ def status_code
37
+ @status_code
38
+ end
39
+
40
+ def headers
41
+ @headers
42
+ end
43
+
44
+ def result
45
+ @result
46
+ end
47
+
48
+ #private methods
49
+ def make_request(url, data)
50
+ headers = {"Content-Type" => "application/json",
51
+ "Authorization" => @token}
52
+ @req = Core::Requester.post(url, data, headers, @timeout, @use_ssl)
53
+
54
+ if check_request
55
+
56
+ response = Core::ConclasResponse.new(
57
+ @req.body,
58
+ @req.code,
59
+ @req.header.to_hash.inspect)
60
+
61
+ if response.request_successful?
62
+ populate_properties
63
+ end
64
+ end
65
+ end
66
+
67
+ def check_request
68
+ if @req.code.to_i.between?(400, 499)
69
+ raise Exceptions::HTTPError, "Client Error #{@req.code}(#{@req.message})."
70
+ elsif @req.code.to_i.between?(500, 600)
71
+ raise Exceptions::HTTPError, "Server Error #{@req.code}(#{@req.message})."
72
+ else
73
+ true
74
+ end
75
+ end
76
+
77
+ def populate_properties
78
+ @status_code = @req.code
79
+ @headers = @req.header.to_hash.inspect
80
+ @result = JSON.parse(@req.body, :quirks_mode => true)
81
+ end
82
+
83
+ def check_api_args_method(contents, start_from_category=nil, callback=nil)
84
+ if contents.length == 0 || !contents.is_a?(Array)
85
+ raise InvalidParameterException, "The parameter 'contents' needs a value"
86
+ end
87
+
88
+ if contents.length > 1000
89
+ raise DocMaxException, "The content size exceeded the limit."
90
+ end
91
+ #if !start_from_category.nil?
92
+ # if Utils::StringHelper.is_empty start_from_category
93
+ # raise Exceptions::InvalidParameterException, "The parameter 'start_from_category' needs a value"
94
+ # end
95
+ #end
96
+
97
+ if !callback.nil?
98
+ if Utils::StringHelper.is_empty callback
99
+ raise Exceptions::InvalidParameterException, "The parameter 'callback' needs a value"
100
+ end
101
+ end
102
+ end
103
+
104
+ private :populate_properties, :check_api_args_method, :make_request
105
+
106
+
107
+ #main methods
108
+ def direct_categorise(contents)
109
+ check_api_args_method(contents)
110
+ hashe_data = {:contents => contents}
111
+ #if !start_from_category.nil?
112
+ # hashe_data[:start_from_category] = start_from_category
113
+ #end
114
+ json_body_request = Utils::JsonMaker.new(hashe_data).get_json
115
+ url = BASE_URL + METHODS[:direct]
116
+ make_request(url, json_body_request)
117
+ end
118
+
119
+ def indirect_categorise(contents, callback)
120
+ check_api_args_method(contents, callback)
121
+ hashe_data = {:contents => contents, :callback => callback}
122
+ #if !start_from_category.nil?
123
+ # hashe_data[:start_from_category] = start_from_category
124
+ #end
125
+ json_body_request = Utils::JsonMaker.new(hashe_data).get_json
126
+ url = BASE_URL + METHODS[:indirect]
127
+ make_request(url, json_body_request)
128
+ end
129
+ end
130
+ end
@@ -0,0 +1,45 @@
1
+ # coding: utf-8
2
+
3
+ require 'rb_conclas/core/exceptions/api_custom_exceptions'
4
+ require 'json'
5
+
6
+
7
+ module Conclas
8
+ module Core
9
+ class ConclasResponse
10
+ def initialize(result, status_code, headers)
11
+ @result = JSON.parse(result, :quirks_mode => true)
12
+ @status_code = status_code
13
+ @headers = headers
14
+ end
15
+
16
+ def raise_exception(code)
17
+ if code == 10
18
+ raise Exceptions::InvalidTokenException, "Missing token."
19
+ elsif code == 11
20
+ raise Exceptions::InvalidTokenException, "Token format is invalid."
21
+ elsif code == 12
22
+ raise Exceptions::InvalidTokenException, "Credentials are not correct."
23
+ elsif code == 13
24
+ raise Exceptions::InvalidModeException, "Invalid mode request."
25
+ elsif code == 14
26
+ raise Exceptions::InvalidBodyException, "Invalid Body Message."
27
+ elsif code == 15
28
+ raise Exceptions::InvalidBodyException, "Invalid Body Json format."
29
+ else
30
+ raise "Error not categorized"
31
+ end
32
+ end
33
+
34
+ private :raise_exception
35
+
36
+ def request_successful?
37
+ if @result.key?("errors")
38
+ code = @result["errors"][0]["code"].to_i
39
+ raise_exception(code)
40
+ end
41
+ true
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,11 @@
1
+ # coding: utf-8
2
+
3
+ module Conclas
4
+ module Exceptions
5
+ class InvalidTokenException < StandardError; end
6
+
7
+ class InvalidModeException < StandardError; end
8
+
9
+ class InvalidBodyException < StandardError; end
10
+ end
11
+ end
@@ -0,0 +1,25 @@
1
+ # coding: utf-8
2
+
3
+ module Conclas
4
+ module Exceptions
5
+ class InvalidParameterException < StandardError; end
6
+
7
+ class JsonKeysException < StandardError; end
8
+
9
+ class ContentsKeyException < StandardError; end
10
+
11
+ class EmptyParameterException < StandardError; end
12
+
13
+ class DocMinException < StandardError; end
14
+
15
+ class DocMaxException < StandardError; end
16
+
17
+ class ParameterTypeError < StandardError; end
18
+
19
+ class URLInvalidException < StandardError; end
20
+
21
+ class ConclasRequestException < StandardError; end
22
+
23
+ class HTTPError < StandardError; end
24
+ end
25
+ end
@@ -0,0 +1,28 @@
1
+ # coding: utf-8
2
+
3
+ require 'net/http'
4
+ require 'uri'
5
+ require 'json'
6
+
7
+ module Conclas
8
+ module Core
9
+ # class to make requester to server
10
+ module Requester
11
+ def self.post(url, data, headers, timeout, use_ssl)
12
+ begin
13
+ uri = URI.parse(url) # parse url data(port and host)
14
+
15
+ http = Net::HTTP.new(uri.host, uri.port) #create http object with uri data
16
+ http.use_ssl = use_ssl
17
+ http.read_timeout = timeout
18
+ request = Net::HTTP::Post.new(uri.request_uri, initheader = headers)
19
+ request.body = data
20
+ http.request(request)
21
+ rescue Timeout::Error, Errno::EINVAL, Errno::ECONNRESET, EOFError,
22
+ Net::HTTPBadResponse, Net::ReadTimeout, Net::HTTPHeaderSyntaxError, Net::ProtocolError => e
23
+ raise e
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,110 @@
1
+ # coding: utf-8
2
+
3
+ require 'json'
4
+ require 'rb_conclas/core/exceptions/client_exceptions'
5
+
6
+ module Conclas
7
+
8
+ module Utils
9
+ REGEX = /(^(https?:\/\/(?:www\.|(?!www))|(www\.?))[\w-]+\.[\w]+|(?!w)[\w-]+\.[\w]+)/
10
+
11
+ class JsonMaker
12
+ def initialize(hash_data)
13
+ @data = hash_data
14
+ end
15
+
16
+ #private methods
17
+ def validate_key_doc(key_doc)
18
+ # Validate key "doc"
19
+ key_doc.each do |key, value|
20
+ if key != "short_text" && key != "long_text" && key != "brands"
21
+ raise Exceptions::ContentsKeyException, 'Invalid key "doc".'
22
+ end
23
+ if StringHelper.is_empty value
24
+ raise Exceptions::EmptyParameterException, "The parameter '#{value}' needs a value"
25
+ end
26
+ end
27
+
28
+ if key_doc.key?("short_text") && key_doc.key?("long_text")
29
+ doc_len = key_doc["short_text"].length + key_doc["long_text"].length
30
+ if doc_len < 25
31
+ raise Exceptions::DocMinException, "The doc is not valid."
32
+ end
33
+ end
34
+ # check short_text
35
+ if key_doc.key?("short_text")
36
+ if key_doc["short_text"].length > 1000
37
+ raise Exceptions::DocMaxException, "The short_text doc is not valid."
38
+ end
39
+ end
40
+ #check long_text
41
+ if key_doc.key?("long_text")
42
+ if key_doc["long_text"].length > 20_000
43
+ raise Exceptions::DocMaxException, "The long_text doc is not valid."
44
+ end
45
+ end
46
+
47
+ if key_doc.key?("brands")
48
+ if key_doc["long_text"].length > 5000
49
+ raise Exceptions::DocMaxException, "The brands doc is not valid."
50
+ end
51
+ end
52
+ end
53
+
54
+ def validate_contents
55
+ # Method to validate contents node
56
+ @data[:contents].each do |item|
57
+ if !item.key?("url") && !item.key?("doc")
58
+ raise Exceptions::ContentsKeyException, "The contents is not valid."
59
+ end
60
+ if item.key?("url") && item.key?("doc")
61
+ raise Exceptions::ContentsKeyException, "There can be the key doc in url in the same hash"
62
+ end
63
+
64
+ if item.key?("url")
65
+ if StringHelper.is_empty item["url"]
66
+ raise Exceptions::EmptyParameterException, "The parameter 'url' needs a value"
67
+ end
68
+ if not item["url"].is_a?(String)
69
+ raise Exceptions::ParameterTypeError, "Url must be type string"
70
+ end
71
+ end
72
+
73
+ if item.key?("doc")
74
+ if item["doc"].size == 0
75
+ raise Exceptions::ContentsKeyException, "Key contents invalid"
76
+ else
77
+ validate_key_doc(item["doc"])
78
+ end
79
+ end
80
+ end
81
+ end
82
+
83
+ def check_urls
84
+ # check urls match with regex
85
+ if @data.key?(:callback)
86
+ if REGEX =~ @data["callback"] then
87
+ raise Exceptions::URLInvalidException, "Invalid url callback"
88
+ end
89
+ end
90
+
91
+ @data[:contents].each do |item|
92
+ if item.key?("url")
93
+ if not REGEX =~ item["url"]
94
+ url = item["url"]
95
+ raise Exceptions::URLInvalidException, "Invalid url #{url}"
96
+ end
97
+ end
98
+ end
99
+ end
100
+
101
+ private :validate_contents, :validate_key_doc, :check_urls
102
+
103
+ def get_json
104
+ validate_contents
105
+ check_urls
106
+ @data.to_json
107
+ end
108
+ end
109
+ end
110
+ end
@@ -0,0 +1,14 @@
1
+ # coding: utf-8
2
+
3
+ require 'json'
4
+
5
+ module Conclas
6
+ module Utils
7
+ class StringHelper
8
+ def self.is_empty(str)
9
+ if str.nil? and str.strip.empty? ? true : false
10
+ end
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,3 @@
1
+ module Conclas
2
+ VERSION = "0.1.0"
3
+ end
data/lib/rb_conclas.rb ADDED
@@ -0,0 +1,12 @@
1
+ require "rb_conclas/utils/json_maker"
2
+ require "rb_conclas/utils/string_helper"
3
+ require "rb_conclas/core/conclas_response"
4
+ require "rb_conclas/core/requester"
5
+ require "rb_conclas/core/exceptions/api_custom_exceptions"
6
+ require "rb_conclas/core/exceptions/client_exceptions"
7
+
8
+ require "rb_conclas/version"
9
+ require "rb_conclas/api"
10
+
11
+ module Conclas
12
+ end
@@ -0,0 +1,25 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'rb_conclas/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "rb_conclas"
8
+ spec.version = Conclas::VERSION
9
+ spec.authors = ["Will Filho"]
10
+ spec.email = ["will@simbioseventures.com"]
11
+
12
+ spec.summary = "Client Ruby Conclas"
13
+ spec.description = "The pyconclas is a client written in Python to use the service Conclas."
14
+ spec.homepage = "http://rubygems.org/gems/rb_conclas"
15
+ spec.license = 'MIT'
16
+
17
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
18
+ spec.bindir = "exe"
19
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
20
+ spec.require_paths = ["lib"]
21
+
22
+ spec.add_development_dependency "bundler", "~> 1.11"
23
+ spec.add_development_dependency "rake", "~> 10.0"
24
+ spec.add_development_dependency "rspec", "~> 3.0"
25
+ end
metadata ADDED
@@ -0,0 +1,104 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: rb_conclas
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Will Filho
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2016-05-18 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.11'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.11'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '3.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '3.0'
55
+ description: The pyconclas is a client written in Python to use the service Conclas.
56
+ email:
57
+ - will@simbioseventures.com
58
+ executables: []
59
+ extensions: []
60
+ extra_rdoc_files: []
61
+ files:
62
+ - ".gitignore"
63
+ - ".rspec"
64
+ - ".travis.yml"
65
+ - Gemfile
66
+ - README.md
67
+ - Rakefile
68
+ - bin/console
69
+ - bin/setup
70
+ - lib/rb_conclas.rb
71
+ - lib/rb_conclas/api.rb
72
+ - lib/rb_conclas/core/conclas_response.rb
73
+ - lib/rb_conclas/core/exceptions/api_custom_exceptions.rb
74
+ - lib/rb_conclas/core/exceptions/client_exceptions.rb
75
+ - lib/rb_conclas/core/requester.rb
76
+ - lib/rb_conclas/utils/json_maker.rb
77
+ - lib/rb_conclas/utils/string_helper.rb
78
+ - lib/rb_conclas/version.rb
79
+ - rb_conclas.gemspec
80
+ homepage: http://rubygems.org/gems/rb_conclas
81
+ licenses:
82
+ - MIT
83
+ metadata: {}
84
+ post_install_message:
85
+ rdoc_options: []
86
+ require_paths:
87
+ - lib
88
+ required_ruby_version: !ruby/object:Gem::Requirement
89
+ requirements:
90
+ - - ">="
91
+ - !ruby/object:Gem::Version
92
+ version: '0'
93
+ required_rubygems_version: !ruby/object:Gem::Requirement
94
+ requirements:
95
+ - - ">="
96
+ - !ruby/object:Gem::Version
97
+ version: '0'
98
+ requirements: []
99
+ rubyforge_project:
100
+ rubygems_version: 2.5.1
101
+ signing_key:
102
+ specification_version: 4
103
+ summary: Client Ruby Conclas
104
+ test_files: []