bvr 0.0.1 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.md +8 -0
- data/Guardfile +1 -1
- data/README.md +18 -2
- data/bvr.gemspec +6 -6
- data/lib/bvr.rb +2 -1
- data/lib/bvr/call.rb +21 -11
- data/lib/bvr/call_collection.rb +62 -0
- data/lib/bvr/connection.rb +4 -3
- data/lib/bvr/credit.rb +47 -0
- data/lib/bvr/customer.rb +149 -0
- data/lib/bvr/phone.rb +1 -10
- data/lib/bvr/phone_collection.rb +59 -0
- data/lib/bvr/version.rb +1 -1
- data/spec/fixtures/changepassword.xml +7 -0
- data/spec/fixtures/changeuserinfo.xml +9 -0
- data/spec/fixtures/createcustomer_response.xml +7 -0
- data/spec/fixtures/customerblocked.xml +9 -0
- data/spec/fixtures/getuserinfo.xml +11 -0
- data/spec/fixtures/settransaction.xml +8 -0
- data/spec/fixtures/settransaction_failed.xml +6 -0
- data/spec/fixtures/validateuser.xml +6 -0
- data/spec/helpers/faraday_stub.rb +10 -0
- data/spec/lib/bvr/call_collection_spec.rb +120 -0
- data/spec/lib/bvr/call_spec.rb +60 -0
- data/spec/lib/bvr/connection_spec.rb +5 -18
- data/spec/lib/bvr/credit_spec.rb +166 -0
- data/spec/lib/bvr/customer_spec.rb +335 -0
- data/spec/lib/bvr/phone_collection_spec.rb +95 -0
- data/spec/lib/bvr_spec.rb +20 -0
- metadata +54 -24
- data/lib/bvr/call_overview.rb +0 -46
- data/spec/lib/bvr/call_overview_spec.rb +0 -94
data/CHANGELOG.md
ADDED
data/Guardfile
CHANGED
data/README.md
CHANGED
@@ -24,11 +24,27 @@ Bvr.configure do |config|
|
|
24
24
|
config.username, config.password = ['username', 'password']
|
25
25
|
end
|
26
26
|
`
|
27
|
-
### Retreiving
|
27
|
+
### Retreiving All the info and form, and manage a customer
|
28
28
|
`
|
29
|
-
Bvr::
|
29
|
+
customer = Bvr::Customer.find('customer_id')
|
30
|
+
customer.phones
|
31
|
+
customer.phones.add( Bvr::Phone.new('+4412345678') )
|
32
|
+
customer.balance
|
33
|
+
customer.credit.add(10.20)
|
34
|
+
customer.credit.rm(1.20)
|
35
|
+
customer.block!
|
36
|
+
customer.unblock!
|
37
|
+
calls = customer.calls({recordcount: 100})
|
38
|
+
calls.count = 250
|
39
|
+
calls.size #=> 100
|
40
|
+
calls.next? # => true, 150 are left
|
41
|
+
|
42
|
+
Bvr::Customer.authenticate('customer_id', 'pass')
|
43
|
+
|
30
44
|
`
|
31
45
|
|
46
|
+
A lot of class methods are available, just have a look at the specs
|
47
|
+
|
32
48
|
|
33
49
|
## Contributing
|
34
50
|
|
data/bvr.gemspec
CHANGED
@@ -6,11 +6,11 @@ require 'bvr/version'
|
|
6
6
|
Gem::Specification.new do |spec|
|
7
7
|
spec.name = "bvr"
|
8
8
|
spec.version = Bvr::VERSION
|
9
|
-
spec.authors = ["
|
9
|
+
spec.authors = ["Gregory Horion"]
|
10
10
|
spec.email = ["greg2502@gmail.com"]
|
11
11
|
spec.description = %q{A ruby interface to Bestvoipreselling API}
|
12
12
|
spec.summary = spec.description
|
13
|
-
spec.homepage = ""
|
13
|
+
spec.homepage = "https://github.com/gregory/bvr"
|
14
14
|
spec.license = "MIT"
|
15
15
|
|
16
16
|
spec.files = `git ls-files`.split($/)
|
@@ -19,8 +19,8 @@ Gem::Specification.new do |spec|
|
|
19
19
|
spec.require_paths = ["lib"]
|
20
20
|
|
21
21
|
spec.add_development_dependency "bundler", "~> 1.3"
|
22
|
-
spec.add_development_dependency "rake"
|
23
|
-
spec.add_development_dependency 'rack'
|
24
|
-
spec.add_development_dependency "faraday"
|
25
|
-
spec.add_development_dependency "
|
22
|
+
spec.add_development_dependency "rake", "~> 10.1.1"
|
23
|
+
spec.add_development_dependency 'rack', "~> 1.5.2"
|
24
|
+
spec.add_development_dependency "faraday", "~> 0.8.8"
|
25
|
+
spec.add_development_dependency "xml-simple", "~> 1.1.3"
|
26
26
|
end
|
data/lib/bvr.rb
CHANGED
@@ -1,4 +1,3 @@
|
|
1
|
-
require 'happymapper'
|
2
1
|
Dir[File.dirname(__FILE__) + '/bvr/*.rb'].each{ |file| require file }
|
3
2
|
|
4
3
|
module Bvr
|
@@ -11,6 +10,8 @@ module Bvr
|
|
11
10
|
end
|
12
11
|
|
13
12
|
def connection
|
13
|
+
raise ::Exception.new("Please provide username and password") if @config.nil?
|
14
|
+
|
14
15
|
@connection ||= Bvr::Connection.new
|
15
16
|
end
|
16
17
|
end
|
data/lib/bvr/call.rb
CHANGED
@@ -1,18 +1,28 @@
|
|
1
|
-
require_relative 'phone'
|
2
1
|
module Bvr
|
3
2
|
class Call
|
4
|
-
|
3
|
+
attr_accessor :id, :calltype, :raw_start_time, :raw_dest, :raw_duration, :charge
|
5
4
|
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
5
|
+
def self.new_from_response(h)
|
6
|
+
self.new.tap do |call|
|
7
|
+
call.id = h['CallId']
|
8
|
+
call.calltype = h['CallType']
|
9
|
+
call.raw_start_time = h['StartTime']
|
10
|
+
call.raw_dest = h['Destination']
|
11
|
+
call.raw_duration = h['Duration']
|
12
|
+
call.charge = h['Charge']
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def duration
|
17
|
+
@_duration ||= Time.parse(self.raw_duration, self.start_time)
|
18
|
+
end
|
19
|
+
|
20
|
+
def dest
|
21
|
+
@_dest ||= Bvr::Phone.new(self.raw_dest)
|
22
|
+
end
|
13
23
|
|
14
|
-
def
|
15
|
-
Time.parse(self.
|
24
|
+
def start_time
|
25
|
+
@_start_time ||= Time.parse(self.raw_start_time)
|
16
26
|
end
|
17
27
|
end
|
18
28
|
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
module Bvr
|
2
|
+
class CallCollection
|
3
|
+
# Valid Options:
|
4
|
+
# Variable Value Option Description
|
5
|
+
# command calloverview Mandatory
|
6
|
+
# username X..140 Mandatory the username of the reseller
|
7
|
+
# password X..100 Mandatory the password of the reseller
|
8
|
+
# customer X..140 Mandatory the username of the customer
|
9
|
+
# date YYYY-MM-DD hh:nn:ss Optional the datetime from which to start retrieving the history, current datetime is default
|
10
|
+
# callid N..1000000 Optional the callid from which to start retrieving the history, 0 is default
|
11
|
+
# recordcount 1 - 500 Optional the maximum number of records returned, 10 is default, 500 is maximum
|
12
|
+
# direction forward / backward Optional the direction to search, backward is default
|
13
|
+
VALID_OPTIONS = [:date, :callid, :recordcount, :direction, :customer, :command]
|
14
|
+
API_COMMANDS= {
|
15
|
+
find_by_customer_id: 'calloverview'
|
16
|
+
}
|
17
|
+
|
18
|
+
attr_accessor :query_params, :raw_count, :raw_more_data, :collection
|
19
|
+
|
20
|
+
def self.find_by_customer_id(customer_id, options={})
|
21
|
+
raise ArgumentError.new('Unknown Argument') unless self.valid_options?(options)
|
22
|
+
|
23
|
+
|
24
|
+
params = {
|
25
|
+
command: API_COMMANDS[:find_by_customer_id],
|
26
|
+
customer: customer_id
|
27
|
+
}
|
28
|
+
|
29
|
+
response = Bvr.connection.get(params.merge(options))
|
30
|
+
|
31
|
+
return [] if response['Calls'].nil?
|
32
|
+
|
33
|
+
self.new_from_response(response).tap do |call_collection|
|
34
|
+
call_collection.query_params = options
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def self.new_from_response(h)
|
39
|
+
self.new.tap do |calls_collection|
|
40
|
+
calls_collection.raw_more_data = h['MoreData']
|
41
|
+
calls_collection.raw_count = h['Calls']['Count']
|
42
|
+
calls_collection.collection = h['Calls']['Call'].each_with_object([]) do |callH, array|
|
43
|
+
array << Call.new_from_response(callH)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def count
|
49
|
+
Integer(self.raw_count)
|
50
|
+
end
|
51
|
+
|
52
|
+
def next?
|
53
|
+
self.raw_more_data == 'True'
|
54
|
+
end
|
55
|
+
|
56
|
+
private
|
57
|
+
|
58
|
+
def self.valid_options?(options)
|
59
|
+
options.empty? ? true : options.keys.all? { |option| VALID_OPTIONS.include? option }
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
data/lib/bvr/connection.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
require 'faraday'
|
2
2
|
require 'rack'
|
3
|
+
require 'xmlsimple'
|
3
4
|
|
4
5
|
module Bvr
|
5
6
|
class Connection
|
@@ -20,11 +21,11 @@ module Bvr
|
|
20
21
|
end
|
21
22
|
|
22
23
|
def get(params)
|
23
|
-
|
24
|
-
|
24
|
+
body = self.faraday_connection.get(self.class.uri_from_h(params)).body
|
25
|
+
::XmlSimple.xml_in body, {ForceArray: false}
|
25
26
|
end
|
26
27
|
|
27
|
-
def
|
28
|
+
def self.uri_from_h(queryH)
|
28
29
|
params = {
|
29
30
|
username: Bvr.config.username,
|
30
31
|
password: Bvr.config.password
|
data/lib/bvr/credit.rb
ADDED
@@ -0,0 +1,47 @@
|
|
1
|
+
module Bvr
|
2
|
+
class Credit < Struct.new(:raw_specific_balance, :raw_balance, :customer)
|
3
|
+
API_COMMANDS= {
|
4
|
+
add: 'settransaction'
|
5
|
+
}
|
6
|
+
|
7
|
+
def self.add(id, amount)
|
8
|
+
params = {
|
9
|
+
command: API_COMMANDS[:add],
|
10
|
+
customer: id,
|
11
|
+
amount: amount
|
12
|
+
}
|
13
|
+
|
14
|
+
Bvr.connection.get(params)
|
15
|
+
end
|
16
|
+
|
17
|
+
def add(amount)
|
18
|
+
response = Bvr::Credit.add(self.customer.id, amount)
|
19
|
+
return false unless response['Result'] == 'Success'
|
20
|
+
|
21
|
+
add_amount(amount) && true
|
22
|
+
end
|
23
|
+
|
24
|
+
|
25
|
+
def balance
|
26
|
+
@_balance ||= Float(self.raw_balance)
|
27
|
+
end
|
28
|
+
|
29
|
+
def rm(amount)
|
30
|
+
self.add(-1 * amount)
|
31
|
+
end
|
32
|
+
|
33
|
+
def specific_balance
|
34
|
+
@_specific_balance ||= Float(self.raw_specific_balance)
|
35
|
+
end
|
36
|
+
|
37
|
+
private
|
38
|
+
|
39
|
+
def add_amount(amount)
|
40
|
+
@_specific_balance = self.specific_balance + Float("%.5f" % amount)
|
41
|
+
@_balance = self.balance + Float("%.2f" % amount)
|
42
|
+
|
43
|
+
self.raw_specific_balance = "#{@_specific_balance}"
|
44
|
+
self.raw_balance = "#{@_balance}"
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
data/lib/bvr/customer.rb
ADDED
@@ -0,0 +1,149 @@
|
|
1
|
+
module Bvr
|
2
|
+
class Customer
|
3
|
+
API_COMMANDS = {
|
4
|
+
find: "getuserinfo",
|
5
|
+
create: "createcustomer",
|
6
|
+
block: "changeuserinfo",
|
7
|
+
authenticate: "validateuser",
|
8
|
+
changepassword: 'changepassword'
|
9
|
+
}
|
10
|
+
|
11
|
+
BLOCKED_VALUES = {
|
12
|
+
true => 'True',
|
13
|
+
false => 'False'
|
14
|
+
}
|
15
|
+
|
16
|
+
CREATE_OPTIONS = {
|
17
|
+
mendatory: [
|
18
|
+
:username,
|
19
|
+
:password,
|
20
|
+
:command,
|
21
|
+
:customer,
|
22
|
+
:customerpassword
|
23
|
+
],
|
24
|
+
optional: [
|
25
|
+
:geocalicli,
|
26
|
+
:tariffrate
|
27
|
+
]
|
28
|
+
}
|
29
|
+
|
30
|
+
attr_accessor :id, :email, :raw_blocked, :credit, :password, :phones
|
31
|
+
|
32
|
+
def initialize(id)
|
33
|
+
@id = id
|
34
|
+
@phones = Bvr::PhoneCollection.new(id)
|
35
|
+
end
|
36
|
+
|
37
|
+
def self.authenticate(id, password)
|
38
|
+
params = {
|
39
|
+
command: API_COMMANDS[:authenticate],
|
40
|
+
customer: id,
|
41
|
+
customerpassword: password
|
42
|
+
}
|
43
|
+
|
44
|
+
response = Bvr.connection.get(params)
|
45
|
+
response['Result'] == 'Success'
|
46
|
+
end
|
47
|
+
|
48
|
+
def self.block(id, block=true)
|
49
|
+
params = {
|
50
|
+
command: API_COMMANDS[:changeuserinfo],
|
51
|
+
customer: id,
|
52
|
+
customerblocked: block
|
53
|
+
}
|
54
|
+
|
55
|
+
raise ArgumentError.new('Please provide a boolean') unless !!block == block
|
56
|
+
|
57
|
+
Bvr.connection.get(params)
|
58
|
+
end
|
59
|
+
|
60
|
+
def self.change_password(id, old_password, new_password)
|
61
|
+
params = {
|
62
|
+
command: API_COMMANDS[:changepassword],
|
63
|
+
customer: id,
|
64
|
+
oldcustomerpassword: old_password,
|
65
|
+
newcustomerpassword: new_password
|
66
|
+
}
|
67
|
+
|
68
|
+
Bvr.connection.get(params)
|
69
|
+
end
|
70
|
+
|
71
|
+
def self.create(options)
|
72
|
+
params = { command: API_COMMANDS[:create] }
|
73
|
+
|
74
|
+
options.merge!(params)
|
75
|
+
raise ArgumentError.new('Invalid or unknown Argument') unless self.valid_create_options?(options)
|
76
|
+
|
77
|
+
Bvr.connection.get(options)
|
78
|
+
end
|
79
|
+
|
80
|
+
def self.find(id)
|
81
|
+
params = {
|
82
|
+
command: API_COMMANDS[:find],
|
83
|
+
customer: id
|
84
|
+
}
|
85
|
+
|
86
|
+
response = Bvr.connection.get(params)
|
87
|
+
|
88
|
+
response['Failed'].nil? ? self.new_from_response(response) : nil
|
89
|
+
end
|
90
|
+
|
91
|
+
def self.new_from_response(h)
|
92
|
+
self.new(h["Customer"]).tap do |customer|
|
93
|
+
customer.email = h["EmailAddress"]
|
94
|
+
customer.raw_blocked = h["Blocked"]
|
95
|
+
customer.credit = Bvr::Credit.new(h["SpecificBalance"], h["Balance"], customer)
|
96
|
+
h['GeocallCLI'].each{ |number| customer.phones << Bvr::Phone.new(number)}
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
def balance
|
101
|
+
self.credit.balance
|
102
|
+
end
|
103
|
+
|
104
|
+
def blocked?
|
105
|
+
self.raw_blocked == BLOCKED_VALUES[true]
|
106
|
+
end
|
107
|
+
|
108
|
+
def block!
|
109
|
+
response = Bvr::Customer.block(self.id, true)
|
110
|
+
|
111
|
+
if response['Result'][0] == 'Success'
|
112
|
+
self.raw_blocked = BLOCKED_VALUES[true]
|
113
|
+
end
|
114
|
+
|
115
|
+
return response['Result'][0] == 'Success'
|
116
|
+
end
|
117
|
+
|
118
|
+
def change_password(new_password)
|
119
|
+
response = Bvr::Customer.change_password(self.id, self.password, new_password)
|
120
|
+
return false if response['Result'] != 'Success'
|
121
|
+
|
122
|
+
self.password = new_password
|
123
|
+
end
|
124
|
+
|
125
|
+
def unblock!
|
126
|
+
response = Bvr::Customer.block(self.id, false)
|
127
|
+
|
128
|
+
if response['Result'][0] == 'Success'
|
129
|
+
self.raw_blocked = BLOCKED_VALUES[false]
|
130
|
+
end
|
131
|
+
|
132
|
+
return response['Result'][0] == 'Success'
|
133
|
+
end
|
134
|
+
|
135
|
+
def calls(options={})
|
136
|
+
return @_calls if @_calls && @_calls.query_params == options
|
137
|
+
@_calls = Bvr::CallCollection.find_by_customer_id(self.id, options)
|
138
|
+
end
|
139
|
+
|
140
|
+
private
|
141
|
+
|
142
|
+
def self.valid_create_options?(options)
|
143
|
+
return false if options.empty?
|
144
|
+
valid_options = CREATE_OPTIONS.values.flatten
|
145
|
+
return false unless options.keys.all? { |option| valid_options.include? option }
|
146
|
+
CREATE_OPTIONS[:mendatory].all? { |option| options.keys.include? option }
|
147
|
+
end
|
148
|
+
end
|
149
|
+
end
|
data/lib/bvr/phone.rb
CHANGED
@@ -0,0 +1,59 @@
|
|
1
|
+
module Bvr
|
2
|
+
class PhoneCollection
|
3
|
+
include Enumerable
|
4
|
+
|
5
|
+
API_COMMANDS = {
|
6
|
+
add: 'changeuserinfo'
|
7
|
+
}
|
8
|
+
|
9
|
+
attr_reader :collection, :customer_id
|
10
|
+
|
11
|
+
def initialize(customer_id)
|
12
|
+
@collection = []
|
13
|
+
@customer_id = customer_id
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.add(customer_id, phone, add="add")
|
17
|
+
params = {
|
18
|
+
command: API_COMMANDS[:add],
|
19
|
+
customer: customer_id,
|
20
|
+
geocallcli_options: add,
|
21
|
+
geocallcli: phone
|
22
|
+
}
|
23
|
+
|
24
|
+
Bvr.connection.get(params)
|
25
|
+
end
|
26
|
+
|
27
|
+
def add(phone)
|
28
|
+
return true if self.collection.include? phone
|
29
|
+
|
30
|
+
response = Bvr::PhoneCollection.add(self.customer_id, phone.number)
|
31
|
+
return false unless response['Result'][0] == 'Success'
|
32
|
+
|
33
|
+
self.collection << phone
|
34
|
+
true
|
35
|
+
end
|
36
|
+
|
37
|
+
def each(&block)
|
38
|
+
@collection.each { |em| block.call(em) }
|
39
|
+
end
|
40
|
+
|
41
|
+
def rm(phone)
|
42
|
+
return false unless self.collection.include? phone
|
43
|
+
|
44
|
+
response = Bvr::PhoneCollection.add(self.customer_id, phone.number, "delete")
|
45
|
+
return false unless response['Result'][0] == 'Success'
|
46
|
+
|
47
|
+
self.collection.delete phone
|
48
|
+
true
|
49
|
+
end
|
50
|
+
|
51
|
+
private
|
52
|
+
|
53
|
+
def method_missing(method, arg, &block)
|
54
|
+
return super unless self.collection.respond_to? method
|
55
|
+
|
56
|
+
self.collection.send(method, arg, &block)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|