didww-v3 1.0.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.
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