didww-v3 1.0.0

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/.gitignore +12 -0
  3. data/.rspec +3 -0
  4. data/.rubocop.yml +313 -0
  5. data/.travis.yml +5 -0
  6. data/Gemfile +6 -0
  7. data/LICENSE.txt +21 -0
  8. data/README.md +57 -0
  9. data/Rakefile +6 -0
  10. data/bin/console +19 -0
  11. data/bin/setup +8 -0
  12. data/didww-v3.gemspec +46 -0
  13. data/lib/didww.rb +3 -0
  14. data/lib/didww/client.rb +120 -0
  15. data/lib/didww/complex_objects/base.rb +89 -0
  16. data/lib/didww/complex_objects/cdr_export_filter.rb +23 -0
  17. data/lib/didww/complex_objects/configurations.rb +11 -0
  18. data/lib/didww/complex_objects/configurations/base.rb +11 -0
  19. data/lib/didww/complex_objects/configurations/const.rb +149 -0
  20. data/lib/didww/complex_objects/configurations/h323_configuration.rb +35 -0
  21. data/lib/didww/complex_objects/configurations/iax2_configuration.rb +45 -0
  22. data/lib/didww/complex_objects/configurations/pstn_configuration.rb +16 -0
  23. data/lib/didww/complex_objects/configurations/sip_configuration.rb +203 -0
  24. data/lib/didww/complex_objects/did_order_item.rb +14 -0
  25. data/lib/didww/middleware.rb +18 -0
  26. data/lib/didww/resources/balance.rb +20 -0
  27. data/lib/didww/resources/base.rb +29 -0
  28. data/lib/didww/resources/cdr_export.rb +47 -0
  29. data/lib/didww/resources/city.rb +9 -0
  30. data/lib/didww/resources/country.rb +17 -0
  31. data/lib/didww/resources/did.rb +49 -0
  32. data/lib/didww/resources/did_group.rb +66 -0
  33. data/lib/didww/resources/did_group_type.rb +9 -0
  34. data/lib/didww/resources/order.rb +67 -0
  35. data/lib/didww/resources/region.rb +9 -0
  36. data/lib/didww/resources/stock_keeping_unit.rb +19 -0
  37. data/lib/didww/resources/trunk.rb +70 -0
  38. data/lib/didww/resources/trunk/const.rb +61 -0
  39. data/lib/didww/resources/trunk_group.rb +23 -0
  40. data/lib/didww/version.rb +3 -0
  41. metadata +307 -0
@@ -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,46 @@
1
+
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'didww/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = 'didww-v3'
8
+ spec.version = DIDWW::VERSION
9
+ spec.authors = ['Alex Korobeinikov']
10
+ spec.email = ['alex.k@didww.com']
11
+
12
+ spec.summary = %q{Ruby client for DIDWW API v3}
13
+ spec.description = %q{Ruby client for DIDWW API v3}
14
+ spec.homepage = 'https://github.com/didww/didww-v3-ruby'
15
+ spec.license = 'MIT'
16
+
17
+ spec.files = `git ls-files -z`.split("\x0").reject do |f|
18
+ f.match(%r{^(test|spec|features)/})
19
+ end
20
+ spec.bindir = 'exe'
21
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
22
+ spec.require_paths = ['lib']
23
+
24
+ spec.add_development_dependency 'bundler', '~> 1.16'
25
+ spec.add_development_dependency 'rake', '~> 10.0'
26
+ spec.add_development_dependency 'rspec', '~> 3.0'
27
+
28
+ # development
29
+ spec.add_development_dependency 'pry'
30
+ spec.add_development_dependency 'byebug'
31
+ spec.add_development_dependency 'awesome_print'
32
+ spec.add_development_dependency 'http_logger'
33
+ spec.add_development_dependency 'rubocop'
34
+
35
+ # test
36
+ spec.add_development_dependency 'simplecov'
37
+ spec.add_development_dependency 'smart_rspec'
38
+ spec.add_development_dependency 'webmock'
39
+
40
+ spec.add_dependency 'activesupport'
41
+ spec.add_dependency 'faraday'
42
+ spec.add_dependency 'json_api_client'
43
+ spec.add_dependency 'http'
44
+ spec.add_dependency 'down'
45
+
46
+ end
@@ -0,0 +1,3 @@
1
+ require 'didww/version'
2
+ require 'didww/client'
3
+ require 'didww/middleware'
@@ -0,0 +1,120 @@
1
+ require 'active_support/core_ext/module/attribute_accessors'
2
+ require 'json_api_client'
3
+
4
+ require 'didww/resources/base'
5
+
6
+ module DIDWW
7
+ module Client
8
+ BASE_URLS = {
9
+ sandbox: 'https://sandbox-api.didww.com/v3/' .freeze,
10
+ production: 'https://api.didww.com/v3/' .freeze
11
+ }.freeze
12
+ DEFAULT_MODE = :sandbox
13
+
14
+ mattr_accessor :api_key, :api_mode, :http_verbose
15
+
16
+ class << self
17
+ def configure
18
+ yield self if block_given?
19
+ connect!
20
+ require_didww_resources
21
+ self
22
+ end
23
+
24
+ def api_mode
25
+ @@api_mode || DEFAULT_MODE
26
+ end
27
+
28
+ def api_key
29
+ @@api_key
30
+ end
31
+
32
+ def api_base_url
33
+ BASE_URLS[api_mode]
34
+ end
35
+
36
+ def balance
37
+ Resource::Balance.all.first
38
+ end
39
+
40
+ def cities
41
+ Resource::City
42
+ end
43
+
44
+ def countries
45
+ Resource::Country
46
+ end
47
+
48
+ def did_group_types
49
+ Resource::DidGroupType
50
+ end
51
+
52
+ def did_groups
53
+ Resource::DidGroup
54
+ end
55
+
56
+ def dids
57
+ Resource::Did
58
+ end
59
+
60
+ def orders
61
+ Resource::Order
62
+ end
63
+
64
+ def regions
65
+ Resource::Region
66
+ end
67
+
68
+ def trunk_groups
69
+ Resource::TrunkGroup
70
+ end
71
+
72
+ def trunks
73
+ Resource::Trunk
74
+ end
75
+
76
+ def cdr_exports
77
+ Resource::CdrExport
78
+ end
79
+
80
+ def api_mode=(arg)
81
+ unless BASE_URLS.keys.include?(arg)
82
+ raise ArgumentError.new("Mode should be in #{BASE_URLS.keys} (given '#{arg}').")
83
+ end
84
+ @@api_mode = arg
85
+ end
86
+
87
+ private
88
+
89
+ def http_verbose?
90
+ ENV['HTTP_VERBOSE'] == 'true' || http_verbose
91
+ end
92
+
93
+ def connect!
94
+ DIDWW::Resource::Base.site = api_base_url
95
+ DIDWW::Resource::Base.connection do |connection|
96
+ connection.use Faraday::Response::Logger if http_verbose?
97
+ connection.use DIDWW::Middleware
98
+ end
99
+ JsonApiClient::Paginating::Paginator.page_param = 'number'
100
+ JsonApiClient::Paginating::Paginator.per_page_param = 'size'
101
+ end
102
+
103
+ def require_didww_resources
104
+ require 'didww/resources/balance'
105
+ require 'didww/resources/city'
106
+ require 'didww/resources/country'
107
+ require 'didww/resources/did_group_type'
108
+ require 'didww/resources/did_group'
109
+ require 'didww/resources/did'
110
+ require 'didww/resources/order'
111
+ require 'didww/resources/region'
112
+ require 'didww/resources/trunk_group'
113
+ require 'didww/resources/trunk'
114
+ require 'didww/resources/stock_keeping_unit'
115
+ require 'didww/resources/cdr_export'
116
+ end
117
+
118
+ end
119
+ end
120
+ end
@@ -0,0 +1,89 @@
1
+ require 'json_api_client/schema'
2
+
3
+ module DIDWW
4
+ module ComplexObject
5
+ class Base
6
+ class << self
7
+ # Specifies the JSON API resource type. By default this is inferred
8
+ # from the resource class name.
9
+ def type
10
+ name.demodulize.underscore.pluralize
11
+ end
12
+
13
+ def property(name, options = {})
14
+ property = schema.add(name, options)
15
+ define_method(name) { attributes[name] }
16
+ define_method("#{name}=".to_sym) do |val|
17
+ attributes[name] = property.cast(val)
18
+ end
19
+ end
20
+
21
+ def schema
22
+ @schema ||= JsonApiClient::Schema.new
23
+ end
24
+
25
+ # Type casting for JsonApiClient parser/setters
26
+ def cast(value, default)
27
+ case value
28
+ when self
29
+ value
30
+ when Hash
31
+ cast_single_object(value)
32
+ when Array
33
+ value.map { |item| cast(item, item) }
34
+ else
35
+ default
36
+ end
37
+ end
38
+
39
+ protected
40
+
41
+ def cast_single_object(hash)
42
+ hash = hash.with_indifferent_access
43
+ klass = class_for_type(hash[:type])
44
+ klass ? klass.new(hash[:attributes] || {}) : hash
45
+ end
46
+
47
+ # Returns a ComplexObject class if given JSON API type matches any
48
+ def class_for_type(type)
49
+ "#{parent.name}::#{type.classify}".safe_constantize
50
+ end
51
+ end
52
+
53
+ def type
54
+ self.class.type
55
+ end
56
+
57
+ def attributes
58
+ @attributes ||= ActiveSupport::HashWithIndifferentAccess.new
59
+ end
60
+
61
+ def initialize(params = {})
62
+ params.each { |k, v| self[k] = v }
63
+ self.class.schema.each_property do |property|
64
+ attributes[property.name] = property.default unless attributes.has_key?(property.name) || property.default.nil?
65
+ end
66
+ end
67
+
68
+ def [](key)
69
+ attributes[key]
70
+ end
71
+
72
+ def []=(key, value)
73
+ public_send("#{key}=", value)
74
+ end
75
+
76
+ # When we represent this resource for serialization (create/update), we do so
77
+ # with this implementation
78
+ def as_json(*)
79
+ { type: type }.with_indifferent_access.tap do |h|
80
+ h[:attributes] = attributes.as_json
81
+ end
82
+ end
83
+
84
+ def as_json_api(*); as_json end
85
+ end
86
+ end
87
+ end
88
+
89
+ JsonApiClient::Schema.register complex_object: DIDWW::ComplexObject::Base
@@ -0,0 +1,23 @@
1
+ require 'json_api_client/schema'
2
+
3
+ module DIDWW
4
+ module ComplexObject
5
+ class CdrExportFilter < Base
6
+ # Type casting for JsonApiClient parser/setters
7
+ def self.cast_single_object(hash)
8
+ new(hash)
9
+ end
10
+
11
+ property :year, type: :integer
12
+ property :month, type: :integer
13
+ property :did_number, type: :string
14
+
15
+ def as_json(*)
16
+ super[:attributes]
17
+ end
18
+
19
+ end
20
+ end
21
+ end
22
+
23
+ JsonApiClient::Schema.register cdr_export_filter: DIDWW::ComplexObject::CdrExportFilter
@@ -0,0 +1,11 @@
1
+ require 'didww/complex_objects/configurations/base'
2
+ require 'didww/complex_objects/configurations/sip_configuration'
3
+ require 'didww/complex_objects/configurations/iax2_configuration'
4
+ require 'didww/complex_objects/configurations/pstn_configuration'
5
+ require 'didww/complex_objects/configurations/h323_configuration'
6
+
7
+ module DIDWW
8
+ module ComplexObject
9
+ include Configuration
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ require 'didww/complex_objects/configurations/const'
2
+
3
+ module DIDWW
4
+ module ComplexObject
5
+ module Configuration
6
+ class Base < ComplexObject::Base
7
+ include CONST
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,149 @@
1
+ module DIDWW
2
+ module ComplexObject
3
+ module Configuration
4
+ module CONST
5
+ RX_DTMF_FORMATS = {
6
+ 1 => 'RFC 2833' .freeze,
7
+ 2 => 'SIP INFO application/dtmf-relay OR application/dtmf'.freeze,
8
+ 3 => 'RFC 2833 OR SIP INFO' .freeze
9
+ }.freeze
10
+
11
+ TX_DTMF_FORMATS = {
12
+ 0 => 'Disable sending' .freeze,
13
+ 1 => 'RFC 2833' .freeze,
14
+ 2 => 'SIP INFO application/dtmf-relay' .freeze,
15
+ 4 => 'SIP INFO application/dtmf' .freeze
16
+ }.freeze
17
+
18
+ SST_REFRESH_METHODS = {
19
+ 1 => 'Invite' .freeze,
20
+ 2 => 'Update' .freeze,
21
+ 3 => 'Update fallback Invite' .freeze
22
+ }.freeze
23
+
24
+ TRANSPORT_PROTOCOLS = {
25
+ 1 => 'UDP' .freeze,
26
+ 2 => 'TCP' .freeze
27
+ }.freeze
28
+
29
+ REROUTING_DISCONNECT_CODES = {
30
+ 56 => '400 | Bad Request' .freeze,
31
+ 57 => '401 | Unauthorized' .freeze,
32
+ 58 => '402 | Payment Required' .freeze,
33
+ 59 => '403 | Forbidden' .freeze,
34
+ 60 => '404 | Not Found' .freeze,
35
+ 64 => '408 | Request Timeout' .freeze,
36
+ 65 => '409 | Conflict' .freeze,
37
+ 66 => '410 | Gone' .freeze,
38
+ 67 => '412 | Conditional Request Failed' .freeze,
39
+ 68 => '413 | Request Entity Too Large' .freeze,
40
+ 69 => '414 | Request-URI Too Long' .freeze,
41
+ 70 => '415 | Unsupported Media Type' .freeze,
42
+ 71 => '416 | Unsupported URI Scheme' .freeze,
43
+ 72 => '417 | Unknown Resource-Priority' .freeze,
44
+ 73 => '420 | Bad Extension' .freeze,
45
+ 74 => '421 | Extension Required' .freeze,
46
+ 75 => '422 | Session Interval Too Small' .freeze,
47
+ 76 => '423 | Interval Too Brief' .freeze,
48
+ 77 => '424 | Bad Location Information' .freeze,
49
+ 78 => '428 | Use Identity Header' .freeze,
50
+ 79 => '429 | Provide Referrer Identity' .freeze,
51
+ 80 => '433 | Anonymity Disallowed' .freeze,
52
+ 81 => '436 | Bad Identity-Info' .freeze,
53
+ 82 => '437 | Unsupported Certificate' .freeze,
54
+ 83 => '438 | Invalid Identity Header' .freeze,
55
+ 84 => '480 | Temporarily Unavailable' .freeze,
56
+ 86 => '482 | Loop Detected' .freeze,
57
+ 87 => '483 | Too Many Hops' .freeze,
58
+ 88 => '484 | Address Incomplete' .freeze,
59
+ 89 => '485 | Ambiguous' .freeze,
60
+ 90 => '486 | Busy Here' .freeze,
61
+ 91 => '487 | Request Terminated' .freeze,
62
+ 92 => '488 | Not Acceptable Here' .freeze,
63
+ 96 => '494 | Security Agreement Required' .freeze,
64
+ 97 => '500 | Server Internal Error' .freeze,
65
+ 98 => '501 | Not Implemented' .freeze,
66
+ 99 => '502 | Bad Gateway' .freeze,
67
+ 100 => '503 | Service Unavailable' .freeze,
68
+ 101 => '504 | Server Time-out' .freeze,
69
+ 102 => '505 | Version Not Supported' .freeze,
70
+ 103 => '513 | Message Too Large' .freeze,
71
+ 104 => '580 | Precondition Failure' .freeze,
72
+ 105 => '600 | Busy Everywhere' .freeze,
73
+ 106 => '603 | Decline' .freeze,
74
+ 107 => '604 | Does Not Exist Anywhere' .freeze,
75
+ 108 => '606 | Not Acceptable' .freeze,
76
+ 1505 => 'Ringing timeout' .freeze
77
+ }.freeze
78
+
79
+ CODECS = {
80
+ 6 => 'telephone-event' .freeze,
81
+ 7 => 'G723' .freeze,
82
+ 8 => 'G729' .freeze,
83
+ 9 => 'PCMU' .freeze,
84
+ 10 => 'PCMA' .freeze,
85
+ 12 => 'speex' .freeze,
86
+ 13 => 'GSM' .freeze,
87
+ 14 => 'G726-32' .freeze,
88
+ 15 => 'G721' .freeze,
89
+ 16 => 'G726-24' .freeze,
90
+ 17 => 'G726-40' .freeze,
91
+ 18 => 'G726-16' .freeze,
92
+ 19 => 'L16' .freeze
93
+ }.freeze
94
+
95
+ DEFAULT_REROUTING_DISCONNECT_CODE_IDS = [
96
+ 56,
97
+ 58,
98
+ 59,
99
+ 60,
100
+ 64,
101
+ 65,
102
+ 66,
103
+ 67,
104
+ 68,
105
+ 69,
106
+ 70,
107
+ 71,
108
+ 72,
109
+ 73,
110
+ 74,
111
+ 75,
112
+ 76,
113
+ 77,
114
+ 78,
115
+ 79,
116
+ 80,
117
+ 81,
118
+ 82,
119
+ 83,
120
+ 84,
121
+ 86,
122
+ 87,
123
+ 88,
124
+ 89,
125
+ 90,
126
+ 91,
127
+ 92,
128
+ 96,
129
+ 97,
130
+ 98,
131
+ 99,
132
+ 101,
133
+ 102,
134
+ 103,
135
+ 104,
136
+ 105,
137
+ 106,
138
+ 107,
139
+ 108,
140
+ 1505
141
+ ].freeze
142
+
143
+ DEFAULT_CODEC_IDS = [ 9, 10, 8, 7, 6 ].freeze
144
+
145
+ DID_PLACEHOLDER = '{DID}'.freeze
146
+ end
147
+ end
148
+ end
149
+ end