voipms_rates 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 2f7dbba975776307743338eaaea14dfcc16ac458
4
+ data.tar.gz: ed82f5766454b66d3d54ee26ce3e04dab092f1d4
5
+ SHA512:
6
+ metadata.gz: 42206a0d55a8e60b0fe57b6b37c8f4bc971b29484e63c8b917df2d05f1ad45e6a070401df39e33942f19f6ebf57c9f3b2f8b8045742b8da92458657b74fa66ac
7
+ data.tar.gz: f8d81ff82ea99a071c7d2ee74f42fdcb382f77170c6f0964d02dc2eaf7a1680f8b09abae47055509305247237e3abfe2ea29e638b12e11a14f12859c47a43e47
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in plugin-template.gemspec
4
+ gemspec
data/README.md ADDED
@@ -0,0 +1,55 @@
1
+ VoipmsRates
2
+ ==========================
3
+
4
+ This [Adhearsion](adhearsion.com) plugin fetches the per minute rate from voip.ms for any phone number. It uses the
5
+ public [voip.ms API](https://voip.ms/rates/xml.php).
6
+
7
+ > Note that this is intended to be used within an Adhearsion app. If you require this gem to use anywhere else than an
8
+ > Adhearsion app, it will probably not work out of the box.
9
+
10
+ # Installation
11
+ Add `gem 'voipms_rates'` to your Gemfile and run `bundle install`.
12
+
13
+ # Configuration
14
+ The gem will fetch the standard rate by default. If you have changed the routing settings in your voip.ms account
15
+ (voip.ms > Main Menu > Account Settings > Account Routing) and use premium routing for Canadian and/or international
16
+ numbers, you can override the defaults by adding the following lines to your app's `config/adhearsion.rb`:
17
+
18
+ ```ruby
19
+ ##
20
+ # voipms_rates settings override
21
+ config.voipms_rates.canada_use_premium = true # default value is false
22
+ config.voipms_rates.intl_use_premium = true # default value is false
23
+ ```
24
+
25
+ Alternatively, you can set the `AHN_VOIPMS_RATES_CANADA_USE_PREMIUM` and `AHN_VOIPMS_RATES_INTL_USE_PREMIUM`
26
+ environment variables to `true`.
27
+
28
+ # Usage
29
+ In your app's controller:
30
+
31
+ ```ruby
32
+ include VoipmsRates::ControllerMethods
33
+
34
+ def run
35
+ @rate = get_rate_for(call.to)
36
+ say "This call will cost #{@rate} USD per minute."
37
+ end
38
+ end
39
+ ```
40
+
41
+ ## `get_rate_for`
42
+ Expects one argument, either the [E.164](http://en.wikipedia.org/wiki/E.164) phone number without `+` or the `call.to`
43
+ string directly from the controller.
44
+
45
+ Example of an E.164 phone number:
46
+
47
+ Consider the following US number: `(555) 123-4567`. The US country code is `+1`, which we add to the beginning of the
48
+ phone number. Thus, we get `+1 (555) 123-4567`. We then strip any special chracters and the leading `+` whih results in
49
+ `15551234567`. This is the number `get_rate_for` expects.
50
+
51
+ The method can also handle standard SIP strings. For the sample US phone number above, that would be
52
+ `sip:15551234567@127.0.0.1`. This string is stored in `call.to` within the controller for the dialled number.
53
+
54
+ # License
55
+ MIT, see the `LICENSE` file within the repo.
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,3 @@
1
+ require "voipms_rates/version"
2
+ require "voipms_rates/plugin"
3
+ require "voipms_rates/controller_methods"
@@ -0,0 +1,4 @@
1
+ # VoipmsRates = Module.new
2
+ require "voipms_rates/version"
3
+ require "voipms_rates/plugin"
4
+ require "voipms_rates/controller_methods"
@@ -0,0 +1,69 @@
1
+ module VoipmsRates
2
+ module ControllerMethods
3
+
4
+ require 'rest-client'
5
+ require 'nokogiri'
6
+
7
+ # Parameters:
8
+ # phone_number [Int] The number for which we want to get the rate
9
+ def get_rate_for(phone_number)
10
+ if phone_number.match(/(\d*)@.*/)
11
+ @digits = phone_number.match(/(\d*)@.*/)[1]
12
+ elsif phone_number.match(/[\d]+/)
13
+ @digits = phone_number.match(/(\d+)/)[1]
14
+ else
15
+ raise(TypeError, "Unexpected input, received '#{phone_number}'", caller)
16
+ end
17
+
18
+ return try_patterns(@digits)
19
+ end
20
+
21
+ def try_patterns(digits)
22
+ rates_endpoint = Adhearsion.config[:voipms_rates].rates_endpoint
23
+ # The rates API only works with part of the phone number. If it gets the full phone number, it won't find the
24
+ # rate. If it doesn't get enough digits, it won't find the rate either. And if it gets too many digits, it won't
25
+ # find the rate...
26
+ # For example:
27
+ # To get the rate for '33912345678' (France), you would need to send '339'
28
+ # To get the rate for '15145551234' (Canada), you would need to send '1514'
29
+ # To get the rate for '12125551234' (USA), you would need to send '1'
30
+ #
31
+ high_count = digits.length >= 5 ? 5 : digits.length # This speeds things up with shorter numbers
32
+ for i in high_count.downto(1) do
33
+ pattern = digits[0, i]
34
+ api_response = RestClient.get(rates_endpoint, {
35
+ params: {
36
+ pattern: pattern
37
+ }
38
+ })
39
+
40
+ xml_doc = Nokogiri::XML(api_response)
41
+
42
+ if xml_doc.xpath('/results')[0]
43
+ country = xml_doc.at_xpath('/results/item/short_description').content.to_s
44
+ return xml_doc.at_xpath('/results/item/rate_premium').content.to_f if ((country === 'Canada' && Adhearsion.config[:voipms_rates].canada_use_premium) || ((country != 'Canada' || country != 'USA') && Adhearsion.config[:voipms_rates].intl_use_premium))
45
+ return xml_doc.at_xpath('/results/item/rate').content.to_f
46
+
47
+ # We use the premium route for Canada but the value route for all other destinations.
48
+ # Because the API sends back both premium and value rates, this has to be done:
49
+ #
50
+ # country = xml_doc.at_xpath('/results/item/short_description').content.to_s
51
+ # case country
52
+ # when 'Canada'
53
+ # return xml_doc.at_xpath('/results/item/rate_premium').content.to_f
54
+ # else
55
+ # return xml_doc.at_xpath('/results/item/rate').content.to_f
56
+ # end
57
+ elsif i === 1 && xml_doc.xpath('error')[0]
58
+ error_code = xml_doc.at_xpath('/error/code').content.to_s
59
+ error_desc = xml_doc.at_xpath('/error/description').content.to_s
60
+
61
+ logger.error("No rate found for '#{pattern}', error code '#{error_code}' (#{error_desc})")
62
+ return nil
63
+ end
64
+ end
65
+ end
66
+
67
+ private :try_patterns
68
+ end
69
+ end
@@ -0,0 +1,69 @@
1
+ module VoipmsRates
2
+ module ControllerMethods
3
+
4
+ require 'rest-client'
5
+ require 'nokogiri'
6
+
7
+ # Parameters:
8
+ # phone_number [Int] The number for which we want to get the rate
9
+ def get_rate_for(phone_number)
10
+ if phone_number.match(/(\d*)@.*/)
11
+ @digits = phone_number.match(/(\d*)@.*/)[1]
12
+ elsif phone_number.match(/[\d]+/)
13
+ @digits = phone_number.match(/(\d+)/)[1]
14
+ else
15
+ raise(TypeError)
16
+ end
17
+
18
+ return try_patterns(@digits)
19
+ end
20
+
21
+ def try_patterns(digits)
22
+ rates_endpoint = Adhearsion.config[:voipms_rates].rates_endpoint
23
+ # The rates API only works with part of the phone number. If it gets the full phone number, it won't find the
24
+ # rate. If it doesn't get enough digits, it won't find the rate either. And if it gets too many digits, it won't
25
+ # find the rate...
26
+ # For example:
27
+ # To get the rate for '33912345678' (France), you would need to send '339'
28
+ # To get the rate for '15145551234' (Canada), you would need to send '1514'
29
+ # To get the rate for '12125551234' (USA), you would need to send '1'
30
+ #
31
+ high_count = digits.length >= 5 ? 5 : digits.length # This speeds things up with shorter numbers
32
+ for i in high_count.downto(1) do
33
+ pattern = digits[0, i]
34
+ api_response = RestClient.get(rates_endpoint, {
35
+ params: {
36
+ pattern: pattern
37
+ }
38
+ })
39
+
40
+ xml_doc = Nokogiri::XML(api_response)
41
+
42
+ if xml_doc.xpath('/results')[0]
43
+ country = xml_doc.at_xpath('/results/item/short_description').content.to_s
44
+ return xml_doc.at_xpath('/results/item/rate_premium').content.to_f if ((country === 'Canada' && Adhearsion.config[:voipms_rates].canada_use_premium) || ((country != 'Canada' || country != 'USA') && Adhearsion.config[:voipms_rates].intl_use_premium))
45
+ return xml_doc.at_xpath('/results/item/rate').content.to_f
46
+
47
+ # We use the premium route for Canada but the value route for all other destinations.
48
+ # Because the API sends back both premium and value rates, this has to be done:
49
+ #
50
+ # country = xml_doc.at_xpath('/results/item/short_description').content.to_s
51
+ # case country
52
+ # when 'Canada'
53
+ # return xml_doc.at_xpath('/results/item/rate_premium').content.to_f
54
+ # else
55
+ # return xml_doc.at_xpath('/results/item/rate').content.to_f
56
+ # end
57
+ elsif i === 1 && xml_doc.xpath('error')[0]
58
+ error_code = xml_doc.at_xpath('/error/code').content.to_s
59
+ error_desc = xml_doc.at_xpath('/error/description').content.to_s
60
+
61
+ logger.error("No rate found for '#{pattern}', error code '#{error_code}' (#{error_desc})")
62
+ return nil
63
+ end
64
+ end
65
+ end
66
+
67
+ private :try_patterns
68
+ end
69
+ end
@@ -0,0 +1,52 @@
1
+ module VoipmsRates
2
+ class Plugin < Adhearsion::Plugin
3
+
4
+ require_relative "version"
5
+
6
+ # Actions to perform when the plugin is loaded
7
+ #
8
+ init :voipms_rates do
9
+ logger.warn "VoipmsRates has been loaded"
10
+ end
11
+
12
+ # Basic configuration for the plugin
13
+ #
14
+ config :voipms_rates do
15
+ rates_endpoint 'https://www.voip.ms/rates/xmlapi.php', desc: "The URL for voip.ms' rates API endpoint"
16
+ canada_use_premium false, desc: "Set to true if you are using premium routing for calls to Canada or false for
17
+ standard routing (change this setting on voip.ms > Account Settings > Account Routing)"
18
+ intl_use_premium false, desc: "Set to true if you are using premium routing for International calls or false for
19
+ standard routing (change this setting on voip.ms > Account Settings > Account Routing)"
20
+ end
21
+
22
+ # Defining a Rake task is easy
23
+ # The following can be invoked with:
24
+ # rake plugin_demo:info
25
+ #
26
+ tasks do
27
+ namespace :voipms_rates do
28
+ desc "Prints the PluginTemplate information"
29
+ task :info do
30
+ STDOUT.puts "VoipmsRates plugin v. #{VERSION}"
31
+ end
32
+
33
+ desc "Checks the current Canada routing setting (Should match your settings on voip.ms > Account Settings >
34
+ Account Routing)"
35
+ task :canada_use_premium do
36
+ rate = Adhearsion.config[:voipms_rates].canada_use_premium ? 'premium' : 'standard'
37
+ STDOUT.puts "Using Canada #{rate} routes rate."
38
+ STDOUT.puts "The value can be changed in your app's config file at config/adhearsion.rb"
39
+ end
40
+
41
+ desc "Checks the current International routing setting (Should match your settings on voip.ms > Account
42
+ Settings > Account Routing)"
43
+ task :intl_use_premium do
44
+ rate = Adhearsion.config[:voipms_rates].intl_use_premium ? 'premium' : 'standard'
45
+ STDOUT.puts "Using international #{rate} routes rate."
46
+ STDOUT.puts "The value can be changed in your app's config file at config/adhearsion.rb"
47
+ end
48
+ end
49
+ end
50
+
51
+ end
52
+ end
@@ -0,0 +1,53 @@
1
+ module VoipmsRates
2
+ class Plugin < Adhearsion::Plugin
3
+
4
+ require_relative "version"
5
+
6
+ # Actions to perform when the plugin is loaded
7
+ #
8
+ init :voipms_rates do
9
+ logger.warn "VoipmsRates has been loaded"
10
+ end
11
+
12
+ # Basic configuration for the plugin
13
+ #
14
+ config :voipms_rates do
15
+ rates_endpoint 'https://www.voip.ms/rates/xmlapi.php', desc: "The URL for voip.ms' rates API endpoint"
16
+ canada_use_premium false, desc: "Set to true if you are using premium routing for calls to Canada or false for
17
+ standard routing (change this setting on voip.ms > Account Settings > Account Routing)"
18
+ intl_use_premium false, desc: "Set to true if you are using premium routing for International calls or false for
19
+ standard routing (change this setting on voip.ms > Account Settings > Account Routing)"
20
+ end
21
+
22
+ # Defining a Rake task is easy
23
+ # The following can be invoked with:
24
+ # rake plugin_demo:info
25
+ #
26
+ tasks do
27
+ namespace :voipms_rates do
28
+ desc "Prints the PluginTemplate information"
29
+ task :info do
30
+ STDOUT.puts "VoipmsRates plugin v. #{VERSION}"
31
+ end
32
+
33
+ desc "Checks the current Canada routing setting (Should match your settings on voip.ms > Account Settings >
34
+ Account Routing)"
35
+ task :canada_use_premium do
36
+ rate = Adhearsion.config[:voipms_rates].canada_use_premium ? 'premium' : 'standard'
37
+ STDOUT.puts "Using Canada #{rate} routes rate."
38
+ # TODO edit with instructions to set in config file
39
+ STDOUT.puts "The value can be changed in your app's config file at config/adhearsion.rb"
40
+ end
41
+
42
+ desc "Checks the current International routing setting (Should match your settings on voip.ms > Account
43
+ Settings > Account Routing)"
44
+ task :intl_use_premium do
45
+ rate = Adhearsion.config[:voipms_rates].intl_use_premium ? 'premium' : 'standard'
46
+ STDOUT.puts "Using international #{rate} routes rate."
47
+ STDOUT.puts "The value can be changed in your app's config file at config/adhearsion.rb"
48
+ end
49
+ end
50
+ end
51
+
52
+ end
53
+ end
@@ -0,0 +1,3 @@
1
+ module VoipmsRates
2
+ VERSION = "1.0.0"
3
+ end
@@ -0,0 +1,3 @@
1
+ module VoipmsRates
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,21 @@
1
+ require 'adhearsion'
2
+ require 'voipms_rates'
3
+ require 'webmock/rspec'
4
+
5
+ # Require any .rb file in spec/support
6
+ Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each {|f| require f}
7
+
8
+ RSpec.configure do |config|
9
+ config.color = true
10
+ config.tty = true
11
+
12
+ config.filter_run :focus => true
13
+ config.run_all_when_everything_filtered = true
14
+
15
+ # config.before(:each) do
16
+ # stub_request(:get, /https:\/\/www\.voip\.ms\/rates\/xmlapi\.php/).
17
+ # with(:headers => {'Accept'=>'*/*; q=0.5, application/xml', 'Accept-Encoding'=>'gzip, deflate', 'User-Agent'=>'Ruby'}).
18
+ # to_return(:status => 200, :body => "", :headers => {})
19
+ # end
20
+ end
21
+
@@ -0,0 +1,21 @@
1
+ require 'adhearsion'
2
+ require 'voipms_rates'
3
+ require 'webmock/rspec'
4
+
5
+ # Require any .rb file in spec/support
6
+ Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each {|f| require f}
7
+
8
+ RSpec.configure do |config|
9
+ config.color = true
10
+ config.tty = true
11
+
12
+ config.filter_run :focus => true
13
+ config.run_all_when_everything_filtered = true
14
+
15
+ config.before(:each) do
16
+ stub_request(:get, /https:\/\/www\.voip\.ms\/rates\/xmlapi\.php/).
17
+ with(:headers => {'Accept'=>'*/*; q=0.5, application/xml', 'Accept-Encoding'=>'gzip, deflate', 'User-Agent'=>'Ruby'}).
18
+ to_return(:status => 200, :body => "", :headers => {})
19
+ end
20
+ end
21
+
@@ -0,0 +1,5 @@
1
+ require 'vcr'
2
+ VCR.configure do |config|
3
+ config.cassette_library_dir = 'fixtures/vcr_cassettes'
4
+ config.hook_into :webmock
5
+ end
@@ -0,0 +1,5 @@
1
+ require 'vcr'
2
+ VCR.configure do |config|
3
+ config.cassette_library_dir = 'fixtures/vcr_cassettes'
4
+ config.hook_into :webmock
5
+ end
@@ -0,0 +1,100 @@
1
+ require 'spec_helper'
2
+
3
+ module VoipmsRates
4
+ describe ControllerMethods do
5
+ describe "mixed in to a CallController" do
6
+
7
+ class TestController < Adhearsion::CallController
8
+ include VoipmsRates::ControllerMethods
9
+ end
10
+
11
+ let(:mock_call) { double 'Call' }
12
+
13
+ subject do
14
+ TestController.new mock_call
15
+ end
16
+
17
+ describe '#get_rate_for' do
18
+
19
+ let(:canadian_number) { '15145551234' }
20
+ let(:us_number) { '12125551234' }
21
+ let(:french_number) { '33953123456' }
22
+ let(:unroutable_number) { '9' }
23
+ let(:sip_string) { 'sip:15145551234@127.0.0.1' }
24
+ let(:invalid_string) { 'invalid number' }
25
+
26
+ context 'when the premium rate is requested' do
27
+
28
+ context 'with a valid number' do
29
+ it 'returns the premium rate for Canada' do
30
+ # This setting is toggled with `rake voipms_rates:canada_use_premium`
31
+ Adhearsion.config[:voipms_rates].canada_use_premium = true
32
+ VCR.use_cassette('canada_premium_rate') do
33
+ expect(subject.get_rate_for(canadian_number)).to eq(0.009)
34
+ end
35
+ Adhearsion.config[:voipms_rates].canada_use_premium = false
36
+ end
37
+
38
+ it 'returns the premium rate for the US' do
39
+ VCR.use_cassette('us_premium_rate') do
40
+ expect(subject.get_rate_for(us_number)).to eq(0.01)
41
+ end
42
+ end
43
+
44
+ it 'returns the premium rate for France' do
45
+ # This setting is toggled with `rake voipms_rates:intl_use_premium`
46
+ Adhearsion.config[:voipms_rates].intl_use_premium = true
47
+ VCR.use_cassette('france_premium_rate') do
48
+ expect(subject.get_rate_for(french_number)).to eq(0.0431)
49
+ end
50
+ Adhearsion.config[:voipms_rates].intl_use_premium = false
51
+ end
52
+ end
53
+
54
+ context 'with an unroutable number' do
55
+ it 'returns "nil"' do
56
+ VCR.use_cassette('unroutable_number') do
57
+ expect(subject.get_rate_for(unroutable_number)).to eq(nil)
58
+ end
59
+ end
60
+ end
61
+ end
62
+
63
+ context "when the premium rate isn't requested" do
64
+ context 'with a valid number' do
65
+ it 'returns the value rate' do
66
+ VCR.use_cassette('canada_standard_rate') do
67
+ expect(subject.get_rate_for(canadian_number)).to eq(0.0052)
68
+ end
69
+ end
70
+ end
71
+
72
+ context 'with an unroutable number' do
73
+ it 'returns "nil"' do
74
+ VCR.use_cassette('unroutable_number') do
75
+ expect(subject.get_rate_for(unroutable_number)).to eq(nil)
76
+ end
77
+ end
78
+ end
79
+
80
+ context 'with a sip string' do
81
+ it 'returns the rate' do
82
+ VCR.use_cassette('sip_string') do
83
+ expect(subject.get_rate_for(sip_string)).to eq(0.0052)
84
+ end
85
+ end
86
+ end
87
+ end
88
+
89
+ context 'with an invalid string' do
90
+ it 'returns a TypeError' do
91
+ VCR.use_cassette('invalid_string') do
92
+ expect{subject.get_rate_for(invalid_string)}.to raise_error(TypeError)
93
+ end
94
+ end
95
+ end
96
+ end
97
+
98
+ end
99
+ end
100
+ end
@@ -0,0 +1,100 @@
1
+ require 'spec_helper'
2
+
3
+ module VoipmsRates
4
+ describe ControllerMethods do
5
+ describe "mixed in to a CallController" do
6
+
7
+ class TestController < Adhearsion::CallController
8
+ include VoipmsRates::ControllerMethods
9
+ end
10
+
11
+ let(:mock_call) { double 'Call' }
12
+
13
+ subject do
14
+ TestController.new mock_call
15
+ end
16
+
17
+ describe '#get_rate_for' do
18
+
19
+ let(:canadian_number) { '15145551234' }
20
+ let(:us_number) { '12125551234' }
21
+ let(:french_number) { '33953123456' }
22
+ let(:unroutable_number) { '9' }
23
+ let(:sip_string) { 'sip:15145551234@127.0.0.1' }
24
+ let(:invalid_string) { 'invalid number' }
25
+
26
+ context 'when the premium rate is requested' do
27
+
28
+ context 'with a valid number' do
29
+ it 'returns the premium rate for Canada' do
30
+ # This setting is toggled with `rake voipms_rates:canada_use_premium`
31
+ Adhearsion.config[:voipms_rates].canada_use_premium = true
32
+ VCR.use_cassette('canada_premium_rate') do
33
+ expect(subject.get_rate_for(canadian_number)).to eq(0.009)
34
+ end
35
+ Adhearsion.config[:voipms_rates].canada_use_premium = false
36
+ end
37
+
38
+ it 'returns the premium rate for the US' do
39
+ VCR.use_cassette('us_premium_rate') do
40
+ expect(subject.get_rate_for(us_number)).to eq(0.01)
41
+ end
42
+ end
43
+
44
+ it 'returns the premium rate for France' do
45
+ # This setting is toggled with `rake voipms_rates:intl_use_premium`
46
+ Adhearsion.config[:voipms_rates].intl_use_premium = true
47
+ VCR.use_cassette('france_premium_rate') do
48
+ expect(subject.get_rate_for(french_number)).to eq(0.0431)
49
+ end
50
+ Adhearsion.config[:voipms_rates].intl_use_premium = false
51
+ end
52
+ end
53
+
54
+ context 'with an unroutable number' do
55
+ it 'returns "nil"' do
56
+ VCR.use_cassette('unroutable_number') do
57
+ expect(subject.get_rate_for(unroutable_number)).to eq(nil)
58
+ end
59
+ end
60
+ end
61
+ end
62
+
63
+ context "when the premium rate isn't requested" do
64
+ context 'with a valid number' do
65
+ it 'returns the value rate' do
66
+ VCR.use_cassette('canada_standard_rate') do
67
+ expect(subject.get_rate_for(canadian_number)).to eq(0.0052)
68
+ end
69
+ end
70
+ end
71
+
72
+ context 'with an unroutable number' do
73
+ it 'returns "nil"' do
74
+ VCR.use_cassette('unroutable_number') do
75
+ expect(subject.get_rate_for(unroutable_number)).to eq(nil)
76
+ end
77
+ end
78
+ end
79
+
80
+ context 'with a sip string' do
81
+ it 'returns the rate' do
82
+ VCR.use_cassette('sip_string') do
83
+ expect(subject.get_rate_for(sip_string)).to eq(0.0052)
84
+ end
85
+ end
86
+ end
87
+ end
88
+
89
+ context 'with an invalid string' do
90
+ it 'returns a TypeError' do
91
+ VCR.use_cassette('invalid_string') do
92
+ expect{subject.get_rate_for(invalid_string)}.to raise_error
93
+ end
94
+ end
95
+ end
96
+ end
97
+
98
+ end
99
+ end
100
+ end
metadata ADDED
@@ -0,0 +1,208 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: voipms_rates
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Coaxial
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-05-20 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: adhearsion
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '2.6'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '2.6'
27
+ - !ruby/object:Gem::Dependency
28
+ name: activesupport
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: 3.0.10
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: 3.0.10
41
+ - !ruby/object:Gem::Dependency
42
+ name: rest-client
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: 1.8.0
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: 1.8.0
55
+ - !ruby/object:Gem::Dependency
56
+ name: nokogiri
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: 1.6.6.2
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: 1.6.6.2
69
+ - !ruby/object:Gem::Dependency
70
+ name: bundler
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '1.0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '1.0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: rspec
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '2.5'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: '2.5'
97
+ - !ruby/object:Gem::Dependency
98
+ name: rake
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ - !ruby/object:Gem::Dependency
112
+ name: guard-rspec
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ">="
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
125
+ - !ruby/object:Gem::Dependency
126
+ name: webmock
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - "~>"
130
+ - !ruby/object:Gem::Version
131
+ version: 1.21.0
132
+ type: :development
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - "~>"
137
+ - !ruby/object:Gem::Version
138
+ version: 1.21.0
139
+ - !ruby/object:Gem::Dependency
140
+ name: vcr
141
+ requirement: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - "~>"
144
+ - !ruby/object:Gem::Version
145
+ version: 2.9.3
146
+ type: :development
147
+ prerelease: false
148
+ version_requirements: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - "~>"
151
+ - !ruby/object:Gem::Version
152
+ version: 2.9.3
153
+ description: Uses the voip.ms public API to fetch premium or value rates per minute
154
+ for any phone number.
155
+ email:
156
+ - py@poujade.org
157
+ executables: []
158
+ extensions: []
159
+ extra_rdoc_files: []
160
+ files:
161
+ - Gemfile
162
+ - README.md
163
+ - Rakefile
164
+ - lib/voipms_rates.rb
165
+ - lib/voipms_rates.rb~
166
+ - lib/voipms_rates/controller_methods.rb
167
+ - lib/voipms_rates/controller_methods.rb~
168
+ - lib/voipms_rates/plugin.rb
169
+ - lib/voipms_rates/plugin.rb~
170
+ - lib/voipms_rates/version.rb
171
+ - lib/voipms_rates/version.rb~
172
+ - spec/spec_helper.rb
173
+ - spec/spec_helper.rb~
174
+ - spec/support/vcr_setup.rb
175
+ - spec/support/vcr_setup.rb~
176
+ - spec/voipms_rates/controller_methods_spec.rb
177
+ - spec/voipms_rates/controller_methods_spec.rb~
178
+ homepage: ''
179
+ licenses:
180
+ - MIT
181
+ metadata: {}
182
+ post_install_message:
183
+ rdoc_options: []
184
+ require_paths:
185
+ - lib
186
+ required_ruby_version: !ruby/object:Gem::Requirement
187
+ requirements:
188
+ - - ">="
189
+ - !ruby/object:Gem::Version
190
+ version: '0'
191
+ required_rubygems_version: !ruby/object:Gem::Requirement
192
+ requirements:
193
+ - - ">="
194
+ - !ruby/object:Gem::Version
195
+ version: '0'
196
+ requirements: []
197
+ rubyforge_project: voipms_rates
198
+ rubygems_version: 2.2.2
199
+ signing_key:
200
+ specification_version: 4
201
+ summary: Get voip.ms calling rates for given phone numbers.
202
+ test_files:
203
+ - spec/spec_helper.rb
204
+ - spec/spec_helper.rb~
205
+ - spec/support/vcr_setup.rb
206
+ - spec/support/vcr_setup.rb~
207
+ - spec/voipms_rates/controller_methods_spec.rb
208
+ - spec/voipms_rates/controller_methods_spec.rb~