conclas 0.1.1

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: 7751fc99f5429f11198d9d8523ba0573c5c90deb
4
+ data.tar.gz: 8a6aaa2290a3d95c9c06274d072a1720dde9ce12
5
+ SHA512:
6
+ metadata.gz: 29e34752937802828779c34d7ff9ef650f40c817c8f19efef4bc44bafc8427ab152420d1640e831e36eb591024147b3f8f2c815412d318909d7beb789477bcf7
7
+ data.tar.gz: 330251a347d13682e988e285cc974b84a3500e027110932a5302b865fb03ae35105f7c6376cb050a59408536c1d5c552fc6d3fb6054d55b624cfb002c1a8c6f4
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 conclas.gemspec
4
+ gemspec
data/README.rst ADDED
@@ -0,0 +1,41 @@
1
+ ============
2
+ conclas
3
+ ============
4
+ The conclas is a client written in Ruby to use the service Conclas.
5
+
6
+ ============
7
+ Install
8
+ ============
9
+ Conclas Ruby Client can be installed using pip:
10
+
11
+ .. code::
12
+
13
+ $ gem install conclas
14
+
15
+ If you prefer to install manually, you must follow the following steps. First clone the repository client ruby ConClas. This is the `link <http://conclas.com>`_
16
+ . After cloning the repository run the following command:
17
+
18
+ .. code::
19
+
20
+ $ gem build conclas.gemspec
21
+
22
+ Now that we have prepared the package, we will install it. To do this, run the following command:
23
+
24
+ .. code::
25
+
26
+ $ gem install conclas-<version of gem>.gem
27
+
28
+ ==============
29
+ Running tests
30
+ ==============
31
+ To run the tests, run the following command:
32
+
33
+ .. code::
34
+
35
+ $ ruby tests/test_conclas.rb
36
+
37
+ ==============
38
+ Documentation
39
+ ==============
40
+ To understand more about the client python ConClas, see our `documentation <http://conclas-platform.cleverapps.io/docs/>`_
41
+ .
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 "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
data/conclas.gemspec ADDED
@@ -0,0 +1,24 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'conclas/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "conclas"
8
+ spec.version = ConClas::VERSION
9
+ spec.authors = ["ConClas"]
10
+ spec.email = ["hello@conclas.com"]
11
+
12
+ spec.summary = "Client Ruby ConClas"
13
+ spec.description = "The ConClas is a client written in Ruby to use the service ConClas."
14
+ spec.homepage = "http://rubygems.org/gems/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.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_development_dependency "bundler", "~> 1.11"
22
+ spec.add_development_dependency "rake", "~> 10.0"
23
+ spec.add_development_dependency "rspec", "~> 3.0"
24
+ end
data/lib/conclas.rb ADDED
@@ -0,0 +1,12 @@
1
+ require "conclas/utils/json_maker"
2
+ require "conclas/utils/string_helper"
3
+ require "conclas/core/conclas_response"
4
+ require "conclas/core/requester"
5
+ require "conclas/core/exceptions/api_custom_exceptions"
6
+ require "conclas/core/exceptions/client_exceptions"
7
+
8
+ require "conclas/version"
9
+ require "conclas/api"
10
+
11
+ module ConClas
12
+ end
@@ -0,0 +1,129 @@
1
+ # coding: utf-8
2
+
3
+ require 'conclas/core/requester'
4
+ require 'conclas/core/exceptions/client_exceptions'
5
+ require 'conclas/core/conclas_response'
6
+ require 'conclas/utils/json_maker'
7
+ require 'conclas/utils/string_helper'
8
+ require 'json'
9
+
10
+ BASE_URL = "http://api.conclas.com/v1"
11
+ METHODS = {
12
+ :direct => "/classify/direct/",
13
+ :indirect => "/classify/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
+ @response = 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 response
45
+ @response
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
+ response = Core::ConClasResponse.new(
55
+ @req.body,
56
+ @req.code,
57
+ @req.header.to_hash.inspect)
58
+
59
+ if response.request_successful?
60
+ if check_request
61
+ populate_properties
62
+ end
63
+ end
64
+ end
65
+
66
+ def check_request
67
+ if @req.code.to_i.between?(400, 499)
68
+ raise Exceptions::HTTPError, "Client Error #{@req.code}(#{@req.message})."
69
+ elsif @req.code.to_i.between?(500, 600)
70
+ raise Exceptions::HTTPError, "Server Error #{@req.code}(#{@req.message})."
71
+ else
72
+ true
73
+ end
74
+ end
75
+
76
+ def populate_properties
77
+ @status_code = @req.code
78
+ @headers = @req.header.to_hash.inspect
79
+ @response = JSON.parse(@req.body, :quirks_mode => true)
80
+ end
81
+
82
+ def check_api_args_method(contents, start_from_category=nil, callback=nil)
83
+ if contents.length == 0 || !contents.is_a?(Array)
84
+ raise InvalidParameterException, "The parameter 'contents' needs a value"
85
+ end
86
+
87
+ if contents.length > 1000
88
+ raise DocMaxException, "The content size exceeded the limit."
89
+ end
90
+ #if !start_from_category.nil?
91
+ # if Utils::StringHelper.is_empty start_from_category
92
+ # raise Exceptions::InvalidParameterException, "The parameter 'start_from_category' needs a value"
93
+ # end
94
+ #end
95
+
96
+ if !callback.nil?
97
+ if Utils::StringHelper.is_empty callback
98
+ raise Exceptions::InvalidParameterException, "The parameter 'callback' needs a value"
99
+ end
100
+ end
101
+ end
102
+
103
+ private :populate_properties, :check_api_args_method, :make_request
104
+
105
+
106
+ #main methods
107
+ def direct_classify(contents)
108
+ check_api_args_method(contents)
109
+ hashe_data = {:contents => contents}
110
+ #if !start_from_category.nil?
111
+ # hashe_data[:start_from_category] = start_from_category
112
+ #end
113
+ json_body_request = Utils::JsonMaker.new(hashe_data).get_json
114
+ url = BASE_URL + METHODS[:direct]
115
+ make_request(url, json_body_request)
116
+ end
117
+
118
+ def indirect_classify(contents, callback)
119
+ check_api_args_method(contents, callback)
120
+ hashe_data = {:contents => contents, :callback => callback}
121
+ #if !start_from_category.nil?
122
+ # hashe_data[:start_from_category] = start_from_category
123
+ #end
124
+ json_body_request = Utils::JsonMaker.new(hashe_data).get_json
125
+ url = BASE_URL + METHODS[:indirect]
126
+ make_request(url, json_body_request)
127
+ end
128
+ end
129
+ end
@@ -0,0 +1,62 @@
1
+ # coding: utf-8
2
+
3
+ require '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(error)
17
+ code = error["code"].to_i
18
+
19
+ case code
20
+ when 2
21
+ raise Exceptions::PaymentRequiredException, error["message"]
22
+ when 3
23
+ raise Exceptions::BannedAccountException, error["message"]
24
+ when 4
25
+ raise Exceptions::AccountExceedFreeLimitException, error["message"]
26
+ when 10
27
+ raise Exceptions::MissingTokenException, error["message"]
28
+ when 11
29
+ raise Exceptions::InvalidTokenException, error["message"]
30
+ when 12
31
+ raise Exceptions::IncorrectCredentialsException, error["message"]
32
+ when 13
33
+ raise Exceptions::InvalidModeException, error["message"]
34
+ when 14
35
+ raise Exceptions::InvalidBodyMessageException, error["message"]
36
+ when 15
37
+ raise Exceptions::InvalidBodyFormatException, error["message"]
38
+ when 16
39
+ raise Exceptions::ApiLimitationException, error["message"]
40
+ when 30
41
+ raise Exceptions::LCoreUnsupportedLanguageException, error["message"]
42
+ when 31
43
+ raise Exceptions::LCoreInternalException, error["message"]
44
+ when 32
45
+ raise Exceptions::ContentTimeoutException, error["message"]
46
+ else
47
+ raise "Error not categorized"
48
+ end
49
+ end
50
+
51
+ private :raise_exception
52
+
53
+ def request_successful?
54
+ if @result.key?("errors")
55
+ error = @result["errors"][0]
56
+ raise_exception(error)
57
+ end
58
+ true
59
+ end
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,31 @@
1
+ # coding: utf-8
2
+
3
+ module ConClas
4
+ module Exceptions
5
+ class InvalidTokenException < StandardError; end
6
+
7
+ class IncorrectCredentialsException < StandardError; end
8
+
9
+ class MissingTokenException < StandardError; end
10
+
11
+ class InvalidBodyFormatException < StandardError; end
12
+
13
+ class InvalidBodyMessageException < StandardError; end
14
+
15
+ class InvalidModeException < StandardError; end
16
+
17
+ class ApiLimitationException < StandardError; end
18
+
19
+ class PaymentRequiredException < StandardError; end
20
+
21
+ class BannedAccountException < StandardError; end
22
+
23
+ class AccountExceedFreeLimitException < StandardError; end
24
+
25
+ class LCoreUnsupportedLanguageException < StandardError; end
26
+
27
+ class LCoreInternalException < StandardError; end
28
+
29
+ class ContentTimeoutException < StandardError; end
30
+ end
31
+ end
@@ -0,0 +1,23 @@
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 HTTPError < StandardError; end
22
+ end
23
+ 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 'conclas/core/exceptions/client_exceptions'
5
+
6
+ module ConClas
7
+
8
+ module Utils
9
+ REGEX = /(^(https?:\/\/(?:www\.|(?!www)))[\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.1"
3
+ end
data/test.rb ADDED
@@ -0,0 +1,6 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'conclas'
5
+
6
+ puts ConClas::VERSION
@@ -0,0 +1,35 @@
1
+ # coding: utf-8
2
+
3
+ lib = File.expand_path('../../lib', __FILE__)
4
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
5
+
6
+ require 'conclas'
7
+ require 'test/unit'
8
+
9
+
10
+ TOKEN = 'API_KEY'
11
+
12
+ class TestConClas < Test::Unit::TestCase
13
+ def test_direct_classify
14
+ api = ConClas::Api.new(TOKEN)
15
+ contents = [
16
+ {
17
+ "url" => "http://techcrunch.com/2016/05/23/we-need-more-driverless-car-accidents/"
18
+ }
19
+ ]
20
+ test_result = [{"language"=>"en", "categories"=>[["Law & Government", 0.007575757575757573]]}]
21
+ api.direct_classify(contents)
22
+ assert_equal(test_result, api.response["results"])
23
+ end
24
+
25
+ def test_indirect_classify
26
+ api = ConClas::Api.new(TOKEN)
27
+ contents = [
28
+ {
29
+ "url" => "http://techcrunch.com/2016/05/23/we-need-more-driverless-car-accidents/"
30
+ }
31
+ ]
32
+ api.indirect_classify(contents, "http://www.mysite.com/callback")
33
+ assert_equal(true, api.response.key?("ids"))
34
+ end
35
+ end
metadata ADDED
@@ -0,0 +1,108 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: conclas
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.1
5
+ platform: ruby
6
+ authors:
7
+ - ConClas
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2016-06-29 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 ConClas is a client written in Ruby to use the service ConClas.
56
+ email:
57
+ - hello@conclas.com
58
+ executables:
59
+ - console
60
+ - setup
61
+ extensions: []
62
+ extra_rdoc_files: []
63
+ files:
64
+ - ".gitignore"
65
+ - ".rspec"
66
+ - ".travis.yml"
67
+ - Gemfile
68
+ - README.rst
69
+ - Rakefile
70
+ - bin/console
71
+ - bin/setup
72
+ - conclas.gemspec
73
+ - lib/conclas.rb
74
+ - lib/conclas/api.rb
75
+ - lib/conclas/core/conclas_response.rb
76
+ - lib/conclas/core/exceptions/api_custom_exceptions.rb
77
+ - lib/conclas/core/exceptions/client_exceptions.rb
78
+ - lib/conclas/core/requester.rb
79
+ - lib/conclas/utils/json_maker.rb
80
+ - lib/conclas/utils/string_helper.rb
81
+ - lib/conclas/version.rb
82
+ - test.rb
83
+ - tests/test_conclas.rb
84
+ homepage: http://rubygems.org/gems/conclas
85
+ licenses:
86
+ - MIT
87
+ metadata: {}
88
+ post_install_message:
89
+ rdoc_options: []
90
+ require_paths:
91
+ - lib
92
+ required_ruby_version: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ required_rubygems_version: !ruby/object:Gem::Requirement
98
+ requirements:
99
+ - - ">="
100
+ - !ruby/object:Gem::Version
101
+ version: '0'
102
+ requirements: []
103
+ rubyforge_project:
104
+ rubygems_version: 2.5.1
105
+ signing_key:
106
+ specification_version: 4
107
+ summary: Client Ruby ConClas
108
+ test_files: []