slybroadcast 1.0.1

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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: c5d5237a871e54e136af720e5a604309b8d3c45c
4
+ data.tar.gz: 4704755f03fc6022a4550ad3bbb62c373b9913a6
5
+ SHA512:
6
+ metadata.gz: cec36c0eb8674270090483e5a19e8ad38dd27e0b19632ea8ff360257db8e808996e278f965013e98c0390de93e31291d1883758ff3736c977cd03d591e9c4881
7
+ data.tar.gz: a71cc3cf1b98692ca98f5fa2b120a5b77dc4aece6e5d23bb1af87a64f02ef52261b030c0b659588f2d5fe82c36734712cc0c4bc04b915e6d341b68443f6f4639
data/.gitignore ADDED
@@ -0,0 +1,50 @@
1
+ *.gem
2
+ *.rbc
3
+ /.config
4
+ /coverage/
5
+ /InstalledFiles
6
+ /pkg/
7
+ /spec/reports/
8
+ /spec/examples.txt
9
+ /test/tmp/
10
+ /test/version_tmp/
11
+ /tmp/
12
+
13
+ # Used by dotenv library to load environment variables.
14
+ # .env
15
+
16
+ ## Specific to RubyMotion:
17
+ .dat*
18
+ .repl_history
19
+ build/
20
+ *.bridgesupport
21
+ build-iPhoneOS/
22
+ build-iPhoneSimulator/
23
+
24
+ ## Specific to RubyMotion (use of CocoaPods):
25
+ #
26
+ # We recommend against adding the Pods directory to your .gitignore. However
27
+ # you should judge for yourself, the pros and cons are mentioned at:
28
+ # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control
29
+ #
30
+ # vendor/Pods/
31
+
32
+ ## Documentation cache and generated files:
33
+ /.yardoc/
34
+ /_yardoc/
35
+ /doc/
36
+ /rdoc/
37
+
38
+ ## Environment normalization:
39
+ /.bundle/
40
+ /vendor/bundle
41
+ /lib/bundler/man/
42
+
43
+ # for a library or gem, you might want to ignore these files since the code is
44
+ # intended to run in multiple environments; otherwise, check them in:
45
+ # Gemfile.lock
46
+ # .ruby-version
47
+ # .ruby-gemset
48
+
49
+ # unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
50
+ .rvmrc
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2017 Martin Aceto
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,2 @@
1
+ # slybroadcast
2
+ A minimal Slybroadcast Ruby client implementation
data/Rakefile ADDED
@@ -0,0 +1,9 @@
1
+ require 'rake/testtask'
2
+
3
+ Rake::TestTask.new do |t|
4
+ t.pattern = 'test/*.rb'
5
+ t.verbose = true
6
+ end
7
+
8
+ desc "Run tests"
9
+ task :default => :test
@@ -0,0 +1 @@
1
+ require_relative 'slybroadcast/client'
@@ -0,0 +1,155 @@
1
+ require 'singleton'
2
+ require 'uri'
3
+ require 'net/http'
4
+ require_relative 'exceptions'
5
+ require_relative 'parsers/campaign_status_response'
6
+ require_relative 'parsers/campaign_actions_response'
7
+ require_relative 'parsers/remaining_messages_response'
8
+
9
+ # usage:
10
+ # Slybroadcast::Client.credentials = {
11
+ # c_uid: 'user@example.com',
12
+ # c_password: 'secret'
13
+ # }
14
+ # Slybroadcast::Client.verify
15
+ #
16
+ # or
17
+ #
18
+ # Slybroadcast::Client.verify({
19
+ # c_uid: 'user@example.com',
20
+ # c_password: 'secret'
21
+ # })
22
+ module Slybroadcast
23
+ class Client
24
+ include Singleton
25
+
26
+ API_URI = 'https://www.mobile-sphere.com/gateway'.freeze
27
+ ENDPOINTS = {
28
+ verify: 'vmb.php',
29
+ campaign_call_status: 'vmb.php',
30
+ campaign_pause: 'vmb.php',
31
+ campaign_resume: 'vmb.php',
32
+ campaign_cancel: 'vmb.php',
33
+ account_message_balance: 'vmb.php',
34
+ download_audio_file: 'vmb.dla.php',
35
+ list_audio_files: 'vmb.aflist.php'
36
+ }.freeze
37
+
38
+ class << self
39
+ attr_accessor :credentials
40
+
41
+ def method_missing(method, *args, &block)
42
+ instance.send(method, *args, &block)
43
+ end
44
+ end
45
+
46
+ def verify(**options)
47
+ params = set_credentials(options.merge(c_option: :user_verify))
48
+ res = Net::HTTP.post_form(
49
+ endpoint_url,
50
+ set_credentials(options.merge(c_option: :user_verify))
51
+ )
52
+ raise Exceptions::InvalidCredentials, 'Invalid `c_uid` or `c_password`' unless res.body.eql?("OK")
53
+ true
54
+ end
55
+
56
+ def campaign_call_status(**options)
57
+ params = set_credentials(options)
58
+
59
+ res = Net::HTTP.post_form(
60
+ endpoint_url,
61
+ params
62
+ )
63
+ result = Parsers::CampaignStatusResponse.new(res.body)
64
+ result.success? ? result : handle_error(result.error)
65
+ end
66
+
67
+ def campaign_pause(**options)
68
+ params = set_credentials(options.merge(c_option: 'pause'))
69
+ res = Net::HTTP.post_form(
70
+ endpoint_url,
71
+ params
72
+ )
73
+ result = Parsers::CampaignActionsResponse.new(res.body)
74
+ result.success? ? result : handle_error(result.error)
75
+ end
76
+
77
+ def campaign_resume(**options)
78
+ params = set_credentials(options.merge(c_option: 'run'))
79
+ res = Net::HTTP.post_form(
80
+ endpoint_url,
81
+ params
82
+ )
83
+ result = Parsers::CampaignActionsResponse.new(res.body)
84
+ result.success? ? result : handle_error(result.error)
85
+ end
86
+
87
+ def campaign_cancel(**options)
88
+ params = set_credentials(options.merge(c_option: 'stop'))
89
+ res = Net::HTTP.post_form(
90
+ endpoint_url,
91
+ params
92
+ )
93
+ result = Parsers::CampaignActionsResponse.new(res.body)
94
+ result.success? ? result : handle_error(result.error)
95
+ end
96
+
97
+ def account_message_balance
98
+ params = set_credentials(remain_message: '1')
99
+ res = Net::HTTP.post_form(
100
+ endpoint_url,
101
+ params
102
+ )
103
+ result = Parsers::RemainingMessagesResponse.new(res.body)
104
+ result.success? ? result : handle_error(result.error)
105
+ end
106
+
107
+ def download_audio_file(**options)
108
+ params = set_credentials(options)
109
+ res = Net::HTTP.post_form(
110
+ endpoint_url,
111
+ params
112
+ )
113
+ result = Parsers::RemainingMessagesResponse.new(res.body)
114
+ result.success? ? result : handle_error(result.error)
115
+ end
116
+
117
+ def list_audio_files
118
+ params = set_credentials(c_method: 'get_audio_list')
119
+ res = Net::HTTP.post_form(
120
+ endpoint_url,
121
+ params
122
+ )
123
+ res.body
124
+ end
125
+
126
+ private
127
+
128
+ def endpoint_url
129
+ method = caller_locations(1,1).first.label.to_sym
130
+ URI(File.join(API_URI, ENDPOINTS.fetch(method)))
131
+ end
132
+
133
+ def set_credentials(params)
134
+ (self.class.credentials || {}).merge(params)
135
+ end
136
+
137
+ def handle_error(err)
138
+ case err
139
+ when 'c_uid: required'
140
+ raise Exceptions::InvalidCredentials, err
141
+ when 'Bad Audio, can\'t download'
142
+ raise Exceptions::BadAudio, err
143
+ when 'session_id: required'
144
+ raise Exceptions::SessionIdRequired, err
145
+ when 'already finished'
146
+ raise Exceptions::CampaignAlreadyFinished, err
147
+ when 'invalid or not found'
148
+ raise Exceptions::CampaignNotFound, err
149
+ else
150
+ raise StandardError, err
151
+ end
152
+ end
153
+
154
+ end
155
+ end
@@ -0,0 +1,20 @@
1
+ module Slybroadcast
2
+ module Exceptions
3
+
4
+ class InvalidCredentials < ::ArgumentError
5
+ end
6
+
7
+ class BadAudio < ::TypeError
8
+ end
9
+
10
+ class CampaignNotFound < ::RuntimeError
11
+ end
12
+
13
+ class CampaignAlreadyFinished < ::RuntimeError
14
+ end
15
+
16
+ class SessionIdRequired < ::ArgumentError
17
+ end
18
+
19
+ end
20
+ end
@@ -0,0 +1,33 @@
1
+ module Parsers
2
+ class CampaignActionsResponse
3
+ attr_accessor :success
4
+ attr_accessor :error
5
+ attr_accessor :session_id
6
+
7
+ def initialize(body)
8
+ response_parse(body)
9
+ end
10
+
11
+ def failed?
12
+ not success?
13
+ end
14
+
15
+ def success?
16
+ success
17
+ end
18
+
19
+ private
20
+
21
+ def response_parse(body)
22
+ response = body.split("\n")
23
+ @success = response[0].strip == 'OK'
24
+
25
+ unless success
26
+ @error = response[1].gsub(/\d\s?/, '').strip
27
+ else
28
+ @session_id = response[1].gsub(/[^0-9]/i, '').strip
29
+ end
30
+ end
31
+
32
+ end
33
+ end
@@ -0,0 +1,35 @@
1
+ module Parsers
2
+ class CampaignStatusResponse
3
+ attr_accessor :success
4
+ attr_accessor :error
5
+ attr_accessor :session_id
6
+ attr_accessor :number_of_phone
7
+
8
+ def initialize(body)
9
+ response_parse(body)
10
+ end
11
+
12
+ def failed?
13
+ not success?
14
+ end
15
+
16
+ def success?
17
+ success
18
+ end
19
+
20
+ private
21
+
22
+ def response_parse(body)
23
+ response = body.split("\n")
24
+ @success = response[0].strip == 'OK'
25
+
26
+ unless success
27
+ @error = response[1]
28
+ else
29
+ @session_id = response[1].split("=")[1]
30
+ @number_of_phone = response[2].split("=")[1]
31
+ end
32
+ end
33
+
34
+ end
35
+ end
@@ -0,0 +1,27 @@
1
+ module Parsers
2
+ class DownloadAudioFileResponse
3
+ attr_accessor :success
4
+ attr_accessor :error
5
+
6
+ def initialize(body)
7
+ response_parse(body)
8
+ end
9
+
10
+ def failed?
11
+ not success?
12
+ end
13
+
14
+ def success?
15
+ success
16
+ end
17
+
18
+ private
19
+
20
+ def response_parse(body)
21
+ response = body.split("\n")
22
+ @success = response[0].strip == 'OK'
23
+ @error = response[1].strip unless success
24
+ end
25
+
26
+ end
27
+ end
@@ -0,0 +1,35 @@
1
+ module Parsers
2
+ class RemainingMessagesResponse
3
+ attr_accessor :success
4
+ attr_accessor :error
5
+ attr_accessor :remaining_messages
6
+ attr_accessor :pending_messages
7
+
8
+ def initialize(body)
9
+ response_parse(body)
10
+ end
11
+
12
+ def failed?
13
+ not success?
14
+ end
15
+
16
+ def success?
17
+ success
18
+ end
19
+
20
+ private
21
+
22
+ def response_parse(body)
23
+ response = body.split("\n")
24
+ @success = response[0].include?('remaining')
25
+
26
+ unless success
27
+ @error = response[1].strip
28
+ else
29
+ @remaining_messages = response[0].gsub(/[^0-9]/i, '').strip
30
+ @pending_messages = response[1].gsub(/[^0-9]/i, '').strip
31
+ end
32
+ end
33
+
34
+ end
35
+ end
@@ -0,0 +1,3 @@
1
+ module Slybroadcast
2
+ VERSION = '1.0.1'.freeze
3
+ end
@@ -0,0 +1,19 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "slybroadcast/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "slybroadcast"
7
+ s.version = Slybroadcast::VERSION
8
+ s.platform = Gem::Platform::RUBY
9
+ s.authors = ["Martin Aceto"]
10
+ s.email = ["martin.aceto@gmail.com"]
11
+ s.homepage = "https://github.com/maceto/slybroadcast.git"
12
+ s.summary = %q{Slybroadcast Ruby client}
13
+ s.description = %q{A minimal Slybroadcast Ruby client implementation}
14
+ s.license = 'MIT'
15
+
16
+ s.files = `git ls-files`.split("\n")
17
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
18
+ s.require_paths = ["lib"]
19
+ end
data/test/client.rb ADDED
@@ -0,0 +1,186 @@
1
+ require_relative "helper"
2
+
3
+ describe Slybroadcast::Client do
4
+ describe 'verify' do
5
+
6
+ it 'should be true' do
7
+
8
+ mocked_reponse = MiniTest::Mock.new
9
+ mocked_reponse.expect(:body, "OK")
10
+
11
+ Net::HTTP.stub :post_form, mocked_reponse do
12
+ assert Slybroadcast::Client.verify({})
13
+ end
14
+
15
+ end
16
+
17
+ it 'should be false' do
18
+
19
+ mocked_reponse = MiniTest::Mock.new
20
+ mocked_reponse.expect(:body, "ERROR")
21
+
22
+ Net::HTTP.stub :post_form, mocked_reponse do
23
+ assert_raises Slybroadcast::Exceptions::InvalidCredentials do
24
+ Slybroadcast::Client.verify({})
25
+ end
26
+ end
27
+
28
+ end
29
+
30
+ end
31
+
32
+ describe 'campaign_call_status' do
33
+
34
+ it 'should return session ID' do
35
+
36
+ mocked_reponse = MiniTest::Mock.new
37
+ mocked_reponse.expect(:body, "OK\nsession ID=123456\nNumber of Phone=2")
38
+
39
+ Net::HTTP.stub :post_form, mocked_reponse do
40
+ result = Slybroadcast::Client.campaign_call_status({})
41
+ assert_equal result.session_id, "123456"
42
+ assert_equal result.number_of_phone, "2"
43
+ end
44
+
45
+ end
46
+
47
+ it 'should raise Exceptions::InvalidCredentials' do
48
+
49
+ mocked_reponse = MiniTest::Mock.new
50
+ mocked_reponse.expect(:body, "ERROR\nc_uid: required")
51
+
52
+ Net::HTTP.stub :post_form, mocked_reponse do
53
+ assert_raises Slybroadcast::Exceptions::InvalidCredentials do
54
+ Slybroadcast::Client.campaign_call_status({})
55
+ end
56
+ end
57
+
58
+ end
59
+
60
+ end
61
+
62
+ describe 'campaign_pause' do
63
+
64
+ it 'should return session ID' do
65
+
66
+ mocked_reponse = MiniTest::Mock.new
67
+ mocked_reponse.expect(:body, "OK\nsession ID=123456")
68
+
69
+ Net::HTTP.stub :post_form, mocked_reponse do
70
+ result = Slybroadcast::Client.campaign_pause({})
71
+ assert_equal result.session_id, "123456"
72
+ end
73
+
74
+ end
75
+
76
+ it 'should raise Exceptions::SessionIdRequired' do
77
+
78
+ mocked_reponse = MiniTest::Mock.new
79
+ mocked_reponse.expect(:body, "ERROR\nsession_id: required")
80
+
81
+ Net::HTTP.stub :post_form, mocked_reponse do
82
+ assert_raises Slybroadcast::Exceptions::SessionIdRequired do
83
+ Slybroadcast::Client.campaign_pause({})
84
+ end
85
+ end
86
+
87
+ end
88
+
89
+ end
90
+
91
+
92
+ describe 'campaign_resume' do
93
+
94
+ it 'should return session ID' do
95
+
96
+ mocked_reponse = MiniTest::Mock.new
97
+ mocked_reponse.expect(:body, "OK\nsession ID=123456")
98
+
99
+ Net::HTTP.stub :post_form, mocked_reponse do
100
+ result = Slybroadcast::Client.campaign_resume({})
101
+ assert_equal result.session_id, "123456"
102
+ end
103
+
104
+ end
105
+
106
+ it 'should raise Exceptions::SessionIdRequired' do
107
+
108
+ mocked_reponse = MiniTest::Mock.new
109
+ mocked_reponse.expect(:body, "ERROR\nsession_id: required")
110
+
111
+ Net::HTTP.stub :post_form, mocked_reponse do
112
+ assert_raises Slybroadcast::Exceptions::SessionIdRequired do
113
+ Slybroadcast::Client.campaign_resume({})
114
+ end
115
+ end
116
+
117
+ end
118
+
119
+ end
120
+
121
+ describe 'campaign_cancel' do
122
+
123
+ it 'should return session ID' do
124
+
125
+ mocked_reponse = MiniTest::Mock.new
126
+ mocked_reponse.expect(:body, "OK\nsession ID=123456")
127
+
128
+ Net::HTTP.stub :post_form, mocked_reponse do
129
+ result = Slybroadcast::Client.campaign_cancel({})
130
+ assert_equal result.session_id, "123456"
131
+ end
132
+
133
+ end
134
+
135
+ it 'should raise Exceptions::SessionIdRequired' do
136
+
137
+ mocked_reponse = MiniTest::Mock.new
138
+ mocked_reponse.expect(:body, "ERROR\nsession_id: required")
139
+
140
+ Net::HTTP.stub :post_form, mocked_reponse do
141
+ assert_raises Slybroadcast::Exceptions::SessionIdRequired do
142
+ Slybroadcast::Client.campaign_cancel({})
143
+ end
144
+ end
145
+
146
+ end
147
+
148
+ end
149
+
150
+ describe 'account_message_balance' do
151
+
152
+ it 'should return remaining messages' do
153
+
154
+ mocked_reponse = MiniTest::Mock.new
155
+ mocked_reponse.expect(:body, "remaining messages=12345\npending messages=123")
156
+
157
+ Net::HTTP.stub :post_form, mocked_reponse do
158
+ result = Slybroadcast::Client.account_message_balance
159
+ assert_equal result.remaining_messages, "12345"
160
+ assert_equal result.pending_messages, "123"
161
+ end
162
+
163
+ end
164
+
165
+ it 'should raise StandardError' do
166
+
167
+ mocked_reponse = MiniTest::Mock.new
168
+ mocked_reponse.expect(:body, "ERROR")
169
+
170
+ Net::HTTP.stub :post_form, mocked_reponse do
171
+ assert_raises StandardError do
172
+ Slybroadcast::Client.account_message_balance
173
+ end
174
+ end
175
+
176
+ end
177
+
178
+ end
179
+
180
+ describe 'download_audio_file' do
181
+ end
182
+
183
+ describe 'list_audio_files' do
184
+ end
185
+
186
+ end
data/test/helper.rb ADDED
@@ -0,0 +1,4 @@
1
+ require 'minitest/autorun'
2
+ require_relative '../lib/slybroadcast'
3
+
4
+ ENV['RACK_ENV'] = 'test'
metadata ADDED
@@ -0,0 +1,61 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: slybroadcast
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Martin Aceto
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2017-05-05 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: A minimal Slybroadcast Ruby client implementation
14
+ email:
15
+ - martin.aceto@gmail.com
16
+ executables: []
17
+ extensions: []
18
+ extra_rdoc_files: []
19
+ files:
20
+ - ".gitignore"
21
+ - LICENSE
22
+ - README.md
23
+ - Rakefile
24
+ - lib/slybroadcast.rb
25
+ - lib/slybroadcast/client.rb
26
+ - lib/slybroadcast/exceptions.rb
27
+ - lib/slybroadcast/parsers/campaign_actions_response.rb
28
+ - lib/slybroadcast/parsers/campaign_status_response.rb
29
+ - lib/slybroadcast/parsers/download_audio_file_response.rb
30
+ - lib/slybroadcast/parsers/remaining_messages_response.rb
31
+ - lib/slybroadcast/version.rb
32
+ - slybroadcast.gemspec
33
+ - test/client.rb
34
+ - test/helper.rb
35
+ homepage: https://github.com/maceto/slybroadcast.git
36
+ licenses:
37
+ - MIT
38
+ metadata: {}
39
+ post_install_message:
40
+ rdoc_options: []
41
+ require_paths:
42
+ - lib
43
+ required_ruby_version: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ required_rubygems_version: !ruby/object:Gem::Requirement
49
+ requirements:
50
+ - - ">="
51
+ - !ruby/object:Gem::Version
52
+ version: '0'
53
+ requirements: []
54
+ rubyforge_project:
55
+ rubygems_version: 2.4.6
56
+ signing_key:
57
+ specification_version: 4
58
+ summary: Slybroadcast Ruby client
59
+ test_files:
60
+ - test/client.rb
61
+ - test/helper.rb