scaleapi-ruby 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (41) hide show
  1. checksums.yaml +7 -0
  2. data/.document +5 -0
  3. data/CONTRIBUTING.md +29 -0
  4. data/Gemfile +19 -0
  5. data/Gemfile.lock +121 -0
  6. data/LICENSE.md +25 -0
  7. data/README.md +237 -0
  8. data/Rakefile +52 -0
  9. data/VERSION +1 -0
  10. data/lib/scale.rb +42 -0
  11. data/lib/scale/api.rb +104 -0
  12. data/lib/scale/callbacks/base.rb +25 -0
  13. data/lib/scale/callbacks/task.rb +23 -0
  14. data/lib/scale/endpoints/endpoint.rb +31 -0
  15. data/lib/scale/endpoints/tasks/cancel_task.rb +23 -0
  16. data/lib/scale/endpoints/tasks/create_annotation_task.rb +16 -0
  17. data/lib/scale/endpoints/tasks/create_categorization_task.rb +16 -0
  18. data/lib/scale/endpoints/tasks/create_comparison_task.rb +16 -0
  19. data/lib/scale/endpoints/tasks/create_phonecall_task.rb +16 -0
  20. data/lib/scale/endpoints/tasks/create_transcription_task.rb +16 -0
  21. data/lib/scale/endpoints/tasks/list_tasks.rb +27 -0
  22. data/lib/scale/endpoints/tasks/retrieve_task.rb +23 -0
  23. data/lib/scale/endpoints/tasks/task_endpoint.rb +22 -0
  24. data/lib/scale/generic_error.rb +4 -0
  25. data/lib/scale/http_error.rb +16 -0
  26. data/lib/scale/resources/base.rb +6 -0
  27. data/lib/scale/resources/task.rb +26 -0
  28. data/test/callbacks/test_task_callback.rb +35 -0
  29. data/test/fixtures/callback.json +29 -0
  30. data/test/fixtures/vcr_cassettes/tasks.yml +2629 -0
  31. data/test/helper.rb +42 -0
  32. data/test/tasks/test_cancel_task.rb +21 -0
  33. data/test/tasks/test_create_annotation_task.rb +40 -0
  34. data/test/tasks/test_create_categorization_task.rb +40 -0
  35. data/test/tasks/test_create_comparison_task.rb +43 -0
  36. data/test/tasks/test_create_phonecall_task.rb +41 -0
  37. data/test/tasks/test_create_transcription_task.rb +41 -0
  38. data/test/tasks/test_list_tasks.rb +14 -0
  39. data/test/tasks/test_retrieve_task.rb +37 -0
  40. data/test/test_api.rb +27 -0
  41. metadata +182 -0
data/Rakefile ADDED
@@ -0,0 +1,52 @@
1
+ # encoding: utf-8
2
+
3
+ require 'rubygems'
4
+ require 'bundler'
5
+ begin
6
+ Bundler.setup(:default, :development)
7
+ rescue Bundler::BundlerError => e
8
+ $stderr.puts e.message
9
+ $stderr.puts "Run `bundle install` to install missing gems"
10
+ exit e.status_code
11
+ end
12
+ require 'rake'
13
+
14
+ require 'juwelier'
15
+ Juwelier::Tasks.new do |gem|
16
+ # gem is a Gem::Specification... see http://guides.rubygems.org/specification-reference/ for more options
17
+ gem.name = "scaleapi-ruby"
18
+ gem.homepage = "http://github.com/wikiti/scaleapi-ruby"
19
+ gem.license = "MIT"
20
+ gem.summary = %Q{A ruby gem wrapper for the Scale API}
21
+ gem.description = %Q{A ruby gem wrapper for the Scale API, containing all the endpoints available.}
22
+ gem.email = "info@danielherzog.es"
23
+ gem.authors = ["Daniel Herzog"]
24
+
25
+ # dependencies defined in Gemfile
26
+ end
27
+ Juwelier::RubygemsDotOrgTasks.new
28
+
29
+ require 'rake/testtask'
30
+ Rake::TestTask.new(:test) do |test|
31
+ test.libs << 'lib' << 'test'
32
+ test.pattern = 'test/**/test_*.rb'
33
+ test.verbose = true
34
+ end
35
+
36
+ desc "Code coverage detail"
37
+ task :simplecov do
38
+ ENV['COVERAGE'] = "true"
39
+ Rake::Task['test'].execute
40
+ end
41
+
42
+ task :default => :test
43
+
44
+ require 'rdoc/task'
45
+ Rake::RDocTask.new do |rdoc|
46
+ version = File.exist?('VERSION') ? File.read('VERSION') : ""
47
+
48
+ rdoc.rdoc_dir = 'rdoc'
49
+ rdoc.title = "scaleapi-ruby #{version}"
50
+ rdoc.rdoc_files.include('README*')
51
+ rdoc.rdoc_files.include('lib/**/*.rb')
52
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.0.1
data/lib/scale.rb ADDED
@@ -0,0 +1,42 @@
1
+ require 'uri'
2
+ require 'time'
3
+ require 'rest-client'
4
+ require 'json'
5
+
6
+ require 'active_support/core_ext/hash/indifferent_access'
7
+
8
+ require 'scale/api'
9
+ require 'scale/generic_error'
10
+ require 'scale/http_error'
11
+
12
+ require 'scale/resources/base'
13
+ require 'scale/resources/task'
14
+
15
+ require 'scale/endpoints/endpoint'
16
+
17
+ require 'scale/endpoints/tasks/task_endpoint'
18
+ require 'scale/endpoints/tasks/create_annotation_task'
19
+ require 'scale/endpoints/tasks/create_categorization_task'
20
+ require 'scale/endpoints/tasks/create_transcription_task'
21
+ require 'scale/endpoints/tasks/create_comparison_task'
22
+ require 'scale/endpoints/tasks/create_phonecall_task'
23
+ require 'scale/endpoints/tasks/retrieve_task'
24
+ require 'scale/endpoints/tasks/cancel_task'
25
+ require 'scale/endpoints/tasks/list_tasks'
26
+
27
+ require 'scale/callbacks/base'
28
+ require 'scale/callbacks/task'
29
+
30
+ module Scale
31
+ def self.setup(params = {})
32
+ Scale::API.new params
33
+ end
34
+
35
+ def self.hash(data = nil)
36
+ ActiveSupport::HashWithIndifferentAccess.new data
37
+ end
38
+
39
+ def self.descendants(klass)
40
+ ObjectSpace.each_object(::Class).select {|d| d < klass }
41
+ end
42
+ end
data/lib/scale/api.rb ADDED
@@ -0,0 +1,104 @@
1
+ module Scale
2
+ class API
3
+ DEFAULT_PARAMS = {
4
+ endpoint: 'https://api.scaleapi.com/v1/',
5
+ default_request_params: {}
6
+ }.freeze
7
+
8
+ attr_reader :endpoint, :api_key, :callback_key, :default_request_params, :params
9
+
10
+ def initialize(params = {})
11
+ params = DEFAULT_PARAMS.merge params
12
+
13
+ @params = Scale.hash(params)
14
+ @endpoint = fetch_attribute :endpoint
15
+ @api_key = fetch_attribute :api_key
16
+ @callback_key = fetch_attribute :callback_key
17
+ @default_request_params = fetch_attribute :default_request_params
18
+
19
+ validate!
20
+ end
21
+
22
+ def request(type, path, payload = {})
23
+ RestClient::Request.new(
24
+ method: type,
25
+ url: url(path),
26
+ user: api_key,
27
+ payload: Scale.hash(default_request_params).merge(Scale.hash(payload)),
28
+ headers: { accept: :json, content_type: :json }
29
+ ).execute
30
+ rescue RestClient::Exception => e
31
+ raise HttpError, e
32
+ end
33
+
34
+ def build_callback(data, type = 'task', options = {})
35
+ options = Scale.hash options
36
+ matchers = Scale.descendants(Scale::Callbacks::Base)
37
+ klass = matchers.find { |c| c.match? type }
38
+
39
+ validate_callback_handler! klass
40
+ validate_callback_token! options[:callback_key]
41
+
42
+ klass.new data
43
+ end
44
+
45
+ def valid_callback_key?(key)
46
+ key.to_s == callback_key.to_s
47
+ end
48
+
49
+ # Endpoint helper. If the method is not defined, then try looking into the available endpoints.
50
+ def method_missing(m, *array)
51
+ endpoint = Scale.descendants(Scale::Endpoints::Endpoint).find { |e| e.match? m }
52
+ return endpoint.new(self, *array).process if endpoint
53
+ super
54
+ end
55
+
56
+ protected
57
+
58
+ def validate!
59
+ validate_endpoint!
60
+ validate_api_key!
61
+ validate_callback_key!
62
+ end
63
+
64
+ def fetch_attribute(name)
65
+ params[name] || send(name)
66
+ end
67
+
68
+ def url(path)
69
+ "#{endpoint.end_with?('/') ? endpoint : endpoint + '/'}#{path}"
70
+ end
71
+
72
+ # -------------------
73
+ # Validators
74
+ # -------------------
75
+
76
+ def validate_callback_handler!(klass)
77
+ raise GenericError, "Callback handler '#{name}' not found. Try #{matchers.map(&:shortcut).join ','}" unless klass
78
+ end
79
+
80
+ def validate_callback_token!(key)
81
+ return if callback_key.nil?
82
+ raise GenericError, "Invalid HTTP callback with key #{key}" unless valid_callback_key? key
83
+ end
84
+
85
+ def validate_callback_key!
86
+ return if callback_key.nil?
87
+ raise GenericError, invalid_attribute('callback_key') unless api_key.to_s != ''
88
+ end
89
+
90
+ def validate_endpoint!
91
+ valid = URI.parse "endpoint" rescue nil
92
+ raise GenericError, invalid_attribute('endpoint') unless valid
93
+ end
94
+
95
+ def validate_api_key!
96
+ raise GenericError, invalid_attribute('api_key') unless api_key.to_s != ''
97
+ end
98
+
99
+ def invalid_attribute(name)
100
+ "Invalid Scale API `#{name}`. Please, set a valid `#{name}` parameter"
101
+ end
102
+
103
+ end
104
+ end
@@ -0,0 +1,25 @@
1
+ module Scale
2
+ module Callbacks
3
+ class Base
4
+ attr_reader :response, :json
5
+
6
+ def initialize(data)
7
+ @json = Scale.hash(data)
8
+ @response = json[:response]
9
+ end
10
+
11
+ def status_code
12
+ response[:status_code]
13
+ end
14
+
15
+
16
+ def self.shortcut
17
+ raise NotImplementedError
18
+ end
19
+
20
+ def self.match?(method)
21
+ shortcut.to_s == method.to_s
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,23 @@
1
+ module Scale
2
+ module Callbacks
3
+ class Task < Base
4
+ attr_reader :task
5
+
6
+ def initialize(json)
7
+ super
8
+ build_task
9
+ end
10
+
11
+ def self.shortcut
12
+ 'task'
13
+ end
14
+
15
+ private
16
+
17
+ def build_task
18
+ task_data = json[:task].merge task_id: json[:task_id]
19
+ @task = Scale::Resources::Task.new task_data
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,31 @@
1
+ module Scale
2
+ module Endpoints
3
+ class Endpoint
4
+ attr_reader :api, :args, :params
5
+
6
+ def initialize(api, *args)
7
+ @api = api
8
+ @args = args
9
+ @params = Scale.hash(args.pop) if args.last.is_a?(Hash)
10
+ end
11
+
12
+ def process
13
+ raise NotImplementedError
14
+ end
15
+
16
+ def self.shortcut
17
+ nil
18
+ end
19
+
20
+ def self.match?(method)
21
+ shortcut.to_s == method.to_s
22
+ end
23
+
24
+ protected
25
+
26
+ def fetch_param(name)
27
+ params[name.to_s] || params[name.to_sym]
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,23 @@
1
+ module Scale
2
+ module Endpoints
3
+ module Tasks
4
+ class CancelTask < TaskEndpoint
5
+ attr_reader :task_id
6
+
7
+ def initialize(api, *args)
8
+ super
9
+ @task_id = args.first
10
+ end
11
+
12
+ def process
13
+ response = api.request :post, path("#{task_id}/cancel")
14
+ build_task response
15
+ end
16
+
17
+ def self.shortcut
18
+ 'cancel_task'
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,16 @@
1
+ module Scale
2
+ module Endpoints
3
+ module Tasks
4
+ class CreateAnnotationTask < TaskEndpoint
5
+ def process
6
+ response = api.request :post, path('annotation'), params
7
+ build_task response
8
+ end
9
+
10
+ def self.shortcut
11
+ 'create_annotation_task'
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,16 @@
1
+ module Scale
2
+ module Endpoints
3
+ module Tasks
4
+ class CreateCategorizationTask < TaskEndpoint
5
+ def process
6
+ response = api.request :post, path('categorize'), params
7
+ build_task response
8
+ end
9
+
10
+ def self.shortcut
11
+ 'create_categorization_task'
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,16 @@
1
+ module Scale
2
+ module Endpoints
3
+ module Tasks
4
+ class CreateComparisonTask < TaskEndpoint
5
+ def process
6
+ response = api.request :post, path('comparison'), params
7
+ build_task response
8
+ end
9
+
10
+ def self.shortcut
11
+ 'create_comparison_task'
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,16 @@
1
+ module Scale
2
+ module Endpoints
3
+ module Tasks
4
+ class CreatePhonecallTask < TaskEndpoint
5
+ def process
6
+ response = api.request :post, path('phonecall'), params
7
+ build_task response
8
+ end
9
+
10
+ def self.shortcut
11
+ 'create_phonecall_task'
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,16 @@
1
+ module Scale
2
+ module Endpoints
3
+ module Tasks
4
+ class CreateTranscriptionTask < TaskEndpoint
5
+ def process
6
+ response = api.request :post, path('transcription'), params
7
+ build_task response
8
+ end
9
+
10
+ def self.shortcut
11
+ 'create_transcription_task'
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,27 @@
1
+ module Scale
2
+ module Endpoints
3
+ module Tasks
4
+ class ListTasks < TaskEndpoint
5
+ def process
6
+ response = api.request :get, path
7
+ build_tasks response
8
+ end
9
+
10
+ def self.shortcut
11
+ 'tasks'
12
+ end
13
+
14
+ protected
15
+
16
+ def path
17
+ "tasks"
18
+ end
19
+
20
+ def build_tasks(response)
21
+ response = parse(response)
22
+ response.map { |obj| build_task obj }
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,23 @@
1
+ module Scale
2
+ module Endpoints
3
+ module Tasks
4
+ class RetrieveTask < TaskEndpoint
5
+ attr_reader :task_id
6
+
7
+ def initialize(api, *args)
8
+ super
9
+ @task_id = args.first
10
+ end
11
+
12
+ def process
13
+ response = api.request :get, path(task_id)
14
+ build_task response
15
+ end
16
+
17
+ def self.shortcut
18
+ 'retrieve_task'
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end