elk 0.0.4 → 0.0.5

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.
data/README.MD CHANGED
@@ -52,7 +52,6 @@ Get all numbers
52
52
  Change number settings
53
53
 
54
54
  number.sms_url = 'http://myservice.se/callback/newsms.php'
55
- number.country = 'no'
56
55
  number.save
57
56
  # => true
58
57
 
data/lib/elk.rb CHANGED
@@ -3,42 +3,70 @@ require 'json/pure'
3
3
  require 'open-uri'
4
4
  require 'rest_client'
5
5
  require 'time'
6
- # Internal
7
- require 'elk/number'
8
- require 'elk/sms'
9
6
 
7
+ # Base module
8
+ # Used for to configure username and password through Elk.configure
10
9
  module Elk
10
+ # Base domain for 46elks API
11
11
  BASE_DOMAIN = 'api.46elks.com'
12
+ # API version supported
12
13
  API_VERSION = 'a1'
13
- VERSION = '0.0.4'
14
+ # Elk version
15
+ VERSION = '0.0.5'
14
16
 
17
+ # When the authentication can't be done
15
18
  class AuthError < RuntimeError; end
19
+ # Raised when the API server isn't working
16
20
  class ServerError < RuntimeError; end
21
+ # Generic exception when 46elks API gives a response Elk can't parse
17
22
  class BadResponse < RuntimeError; end
23
+ # Generic exception when Elk calls 46elk API the wrong way
18
24
  class BadRequest < RuntimeError; end
25
+ # Raised when required paremeters are omitted
19
26
  class MissingParameter < RuntimeError; end
20
27
 
21
28
  class << self
29
+ # API Username from 46elks.com
22
30
  attr_accessor :username
31
+ # API Password from 46elks.com
23
32
  attr_accessor :password
33
+ # Defaults to Elk::BASE_DOMAIN, but can be overriden for testing
24
34
  attr_accessor :base_domain
25
35
 
36
+ # Set up authentication credentials, has to be done before using Elk::Number and Elk::SMS
37
+ #
38
+ # Elk.configure do |config|
39
+ # config.username = 'USERNAME'
40
+ # config.password = 'PASSWORD
41
+ # end
26
42
  def configure
27
43
  yield self
28
44
  end
29
45
 
46
+ # Base URL used for calling 46elks API
30
47
  def base_url
48
+ if not username or not password
49
+ raise AuthError, "API username and password required"
50
+ end
51
+
31
52
  "https://#{username}:#{password}@#{(base_domain || BASE_DOMAIN)}/#{API_VERSION}"
32
53
  end
33
54
 
55
+ # Wrapper for Elk.execute(:get)
34
56
  def get(path, parameters = {})
35
57
  execute(:get, path, parameters)
36
58
  end
37
59
 
60
+ # Wrapper for Elk::execute(:post)
38
61
  def post(path, parameters = {})
39
62
  execute(:post, path, parameters)
40
63
  end
41
64
 
65
+ # Wrapper around RestClient::RestClient.execute
66
+ #
67
+ # * Sets accept header to json
68
+ # * Handles some exceptions
69
+ #
42
70
  def execute(method, path, parameters, headers={:accept => :json}, &block)
43
71
  payload = {}.merge(parameters)
44
72
  url = base_url + path
@@ -51,6 +79,7 @@ module Elk
51
79
  raise BadRequest, e.http_body
52
80
  end
53
81
 
82
+ # Wrapper around JSON.parse, symbolize names
54
83
  def parse_json(body)
55
84
  JSON.parse(body, :symbolize_names => true)
56
85
  rescue JSON::ParserError
@@ -59,10 +88,17 @@ module Elk
59
88
  end
60
89
  end
61
90
 
62
- class Hash
91
+ # --
92
+ # TODO: Not that nice to create methods in Hash
93
+ # --
94
+ class Hash #:nodoc: all
63
95
  def require_keys!(required_keys)
64
96
  unless (missing_parameters = required_keys - self.keys).empty?
65
97
  raise Elk::MissingParameter, "Requires #{missing_parameters.collect {|s| ":#{s}"}.join(', ')} parameters"
66
98
  end
67
99
  end
68
- end
100
+ end
101
+
102
+ # Internal
103
+ require 'elk/number'
104
+ require 'elk/sms'
@@ -1,15 +1,17 @@
1
1
  module Elk
2
+ # Allocate and manage numbers used for SMS/MMS/Voice
2
3
  class Number
3
- attr_reader :number_id, :number, :capabilities, :loaded_at
4
- attr_accessor :country, :sms_url
4
+ attr_reader :number_id, :number, :capabilities, :loaded_at #:nodoc:
5
+ attr_accessor :country, :sms_url, :voice_start_url #:nodoc:
5
6
 
6
- def initialize(parameters)
7
+ def initialize(parameters) #:nodoc:
7
8
  set_paramaters(parameters)
8
9
  end
9
10
 
10
- def set_paramaters(parameters)
11
+ def set_paramaters(parameters) #:nodoc:
11
12
  @country = parameters[:country]
12
13
  @sms_url = parameters[:sms_url]
14
+ @voice_start_url = parameters[:voice_start_url]
13
15
  @status = parameters[:active]
14
16
  @number_id = parameters[:id]
15
17
  @number = parameters[:number]
@@ -17,6 +19,7 @@ module Elk
17
19
  @loaded_at = Time.now
18
20
  end
19
21
 
22
+ # Status of a number, if it's :active or :deallocated
20
23
  def status
21
24
  case @status
22
25
  when 'yes'
@@ -28,30 +31,43 @@ module Elk
28
31
  end
29
32
  end
30
33
 
34
+ # Reloads a number from the API server
31
35
  def reload
32
36
  response = Elk.get("/Numbers/#{self.number_id}")
33
37
  self.set_paramaters(Elk.parse_json(response.body))
34
38
  response.code == 200
35
39
  end
36
40
 
41
+ # Updates or allocates a number
37
42
  def save
38
- response = Elk.post("/Numbers/#{self.number_id}", {:country => self.country, :sms_url => self.sms_url})
43
+ attributes = {:sms_url => self.sms_url, :voice_start => self.voice_start_url}
44
+ # If new URL, send country, otherwise not
45
+ if !self.number_id
46
+ attributes[:country] = self.country
47
+ end
48
+ response = Elk.post("/Numbers/#{self.number_id}", attributes)
39
49
  response.code == 200
40
50
  end
41
51
 
52
+ # Deallocates a number, once allocated, a number cannot be used again, ever!
42
53
  def deallocate!
43
54
  response = Elk.post("/Numbers/#{self.number_id}", {:active => 'no'})
44
- @status = 'no'
55
+ self.set_paramaters(Elk.parse_json(response.body))
45
56
  response.code == 200
46
57
  end
47
58
 
48
59
  class << self
60
+ # Allocates a phone number
61
+ #
62
+ # * Required parameters: :country
63
+ # * Optional parameters: :sms_url, :voice_start_url
49
64
  def allocate(parameters)
50
- parameters.require_keys!([:sms_url, :country])
65
+ parameters.require_keys!([:country])
51
66
  response = Elk.post('/Numbers', parameters)
52
67
  self.new(Elk.parse_json(response.body))
53
68
  end
54
69
 
70
+ # Returns all Elk::Numbers, regardless of status (allocated/deallocated)
55
71
  def all
56
72
  response = Elk.get('/Numbers')
57
73
 
@@ -1,12 +1,13 @@
1
1
  module Elk
2
+ # Used to send SMS through 46elks SMS-gateway
2
3
  class SMS
3
- attr_reader :from, :to, :message, :message_id, :created_at, :loaded_at
4
+ attr_reader :from, :to, :message, :message_id, :created_at, :loaded_at #:nodoc:
4
5
 
5
- def initialize(parameters)
6
+ def initialize(parameters) #:nodoc:
6
7
  set_parameters(parameters)
7
8
  end
8
9
 
9
- def set_parameters(parameters)
10
+ def set_parameters(parameters) #:nodoc:
10
11
  @from = parameters[:from]
11
12
  @to = parameters[:to]
12
13
  @message = parameters[:message]
@@ -15,6 +16,7 @@ module Elk
15
16
  @loaded_at = Time.now
16
17
  end
17
18
 
19
+ # Reloads a SMS from server
18
20
  def reload
19
21
  response = Elk.get("/SMS/#{self.message_id}")
20
22
  self.set_parameters(Elk.parse_json(response.body))
@@ -22,6 +24,12 @@ module Elk
22
24
  end
23
25
 
24
26
  class << self
27
+ # Send SMS
28
+ # Required parameters
29
+ #
30
+ # * :from - Either the one of the allocated numbers or arbitrary alphanumeric string of at most 11 characters
31
+ # * :to - Any phone number capable of receiving SMS
32
+ # * :message - Any UTF-8 text Splitting and joining multi-part SMS messages are automatically handled by the API
25
33
  def send(parameters)
26
34
  parameters.require_keys!([:from, :message, :to])
27
35
 
@@ -34,13 +42,13 @@ module Elk
34
42
  self.new(Elk.parse_json(response.body))
35
43
  end
36
44
 
45
+ # Get sent and received messages. Limited by the API to 100 latest
37
46
  def all
38
47
  response = Elk.get('/SMS')
39
48
  Elk.parse_json(response.body)[:smses].collect do |n|
40
49
  self.new(n)
41
50
  end
42
51
  end
43
-
44
52
  end
45
53
  end
46
54
  end
@@ -2,6 +2,31 @@ require 'spec_helper'
2
2
  require 'elk'
3
3
 
4
4
  describe Elk do
5
+ it 'should detect missing username and/or password' do
6
+ expect { Elk.base_url }.to raise_error(Elk::AuthError)
7
+
8
+ Elk.configure do |config|
9
+ config.username = nil
10
+ config.password = 'PASSWORD'
11
+ end
12
+
13
+ expect { Elk.base_url }.to raise_error(Elk::AuthError)
14
+
15
+ Elk.configure do |config|
16
+ config.username = 'USERNAME'
17
+ config.password = nil
18
+ end
19
+
20
+ expect { Elk.base_url }.to raise_error(Elk::AuthError)
21
+
22
+ Elk.configure do |config|
23
+ config.username = 'USERNAME'
24
+ config.password = 'PASSWORD'
25
+ end
26
+
27
+ expect { Elk.base_url }.to_not raise_error(Elk::AuthError)
28
+ end
29
+
5
30
  it 'should handle garbage json' do
6
31
  bad_response_body = fixture('bad_response_body.txt').read
7
32
 
@@ -50,7 +75,7 @@ describe Elk do
50
75
  with(:headers => {'Accept'=>'application/json'}).
51
76
  to_return(fixture('gets_allocated_numbers.txt'))
52
77
  stub_request(:post, "https://USERNAME:PASSWORD@api.46elks.com/a1/Numbers/nea19c8e291676fb7003fa1d63bba7899").
53
- with(:body => {"country" => "no", "sms_url" => "http://otherhost/receive"},
78
+ with(:body => {"sms_url" => "http://otherhost/receive", "voice_start" => ""},
54
79
  :headers => {'Accept'=>'application/json', 'Content-Type'=>'application/x-www-form-urlencoded'}).
55
80
  to_return(fixture('updates_a_number.txt'))
56
81
 
@@ -0,0 +1,4 @@
1
+ --colour
2
+ --format progress
3
+ --loadby mtime
4
+ --reverse
metadata CHANGED
@@ -1,112 +1,79 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: elk
3
- version: !ruby/object:Gem::Version
4
- hash: 23
5
- prerelease: false
6
- segments:
7
- - 0
8
- - 0
9
- - 4
10
- version: 0.0.4
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.5
5
+ prerelease:
11
6
  platform: ruby
12
- authors:
7
+ authors:
13
8
  - Johan Eckerstroem
14
9
  autorequire:
15
10
  bindir: bin
16
11
  cert_chain: []
17
-
18
- date: 2011-07-18 00:00:00 +02:00
19
- default_executable:
20
- dependencies:
21
- - !ruby/object:Gem::Dependency
12
+ date: 2011-10-20 00:00:00.000000000Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
22
15
  name: json_pure
23
- prerelease: false
24
- requirement: &id001 !ruby/object:Gem::Requirement
16
+ requirement: &70113756837920 !ruby/object:Gem::Requirement
25
17
  none: false
26
- requirements:
18
+ requirements:
27
19
  - - ~>
28
- - !ruby/object:Gem::Version
29
- hash: 7
30
- segments:
31
- - 1
32
- - 5
33
- - 2
20
+ - !ruby/object:Gem::Version
34
21
  version: 1.5.2
35
22
  type: :runtime
36
- version_requirements: *id001
37
- - !ruby/object:Gem::Dependency
38
- name: rest-client
39
23
  prerelease: false
40
- requirement: &id002 !ruby/object:Gem::Requirement
24
+ version_requirements: *70113756837920
25
+ - !ruby/object:Gem::Dependency
26
+ name: rest-client
27
+ requirement: &70113756836920 !ruby/object:Gem::Requirement
41
28
  none: false
42
- requirements:
29
+ requirements:
43
30
  - - ~>
44
- - !ruby/object:Gem::Version
45
- hash: 9
46
- segments:
47
- - 1
48
- - 6
49
- - 3
31
+ - !ruby/object:Gem::Version
50
32
  version: 1.6.3
51
33
  type: :runtime
52
- version_requirements: *id002
53
- - !ruby/object:Gem::Dependency
54
- name: rake
55
34
  prerelease: false
56
- requirement: &id003 !ruby/object:Gem::Requirement
35
+ version_requirements: *70113756836920
36
+ - !ruby/object:Gem::Dependency
37
+ name: rake
38
+ requirement: &70113756836380 !ruby/object:Gem::Requirement
57
39
  none: false
58
- requirements:
40
+ requirements:
59
41
  - - ~>
60
- - !ruby/object:Gem::Version
61
- hash: 63
62
- segments:
63
- - 0
64
- - 9
65
- - 2
42
+ - !ruby/object:Gem::Version
66
43
  version: 0.9.2
67
44
  type: :development
68
- version_requirements: *id003
69
- - !ruby/object:Gem::Dependency
70
- name: rspec
71
45
  prerelease: false
72
- requirement: &id004 !ruby/object:Gem::Requirement
46
+ version_requirements: *70113756836380
47
+ - !ruby/object:Gem::Dependency
48
+ name: rspec
49
+ requirement: &70113756835800 !ruby/object:Gem::Requirement
73
50
  none: false
74
- requirements:
51
+ requirements:
75
52
  - - ~>
76
- - !ruby/object:Gem::Version
77
- hash: 23
78
- segments:
79
- - 2
80
- - 6
81
- - 0
53
+ - !ruby/object:Gem::Version
82
54
  version: 2.6.0
83
55
  type: :development
84
- version_requirements: *id004
85
- - !ruby/object:Gem::Dependency
86
- name: webmock
87
56
  prerelease: false
88
- requirement: &id005 !ruby/object:Gem::Requirement
57
+ version_requirements: *70113756835800
58
+ - !ruby/object:Gem::Dependency
59
+ name: webmock
60
+ requirement: &70113756835100 !ruby/object:Gem::Requirement
89
61
  none: false
90
- requirements:
62
+ requirements:
91
63
  - - ~>
92
- - !ruby/object:Gem::Version
93
- hash: 7
94
- segments:
95
- - 1
96
- - 6
97
- - 4
64
+ - !ruby/object:Gem::Version
98
65
  version: 1.6.4
99
66
  type: :development
100
- version_requirements: *id005
101
- description: Used to configure numbers, send/reciev SMS/MMS/Voice messages at 46elks
67
+ prerelease: false
68
+ version_requirements: *70113756835100
69
+ description: Elk can be used to allocate a phone numbers, manage the numbers and send
70
+ SMS through these numbers.
102
71
  email: johan@duh.se
103
72
  executables: []
104
-
105
73
  extensions: []
106
-
107
- extra_rdoc_files:
74
+ extra_rdoc_files:
108
75
  - README.MD
109
- files:
76
+ files:
110
77
  - lib/elk/number.rb
111
78
  - lib/elk/sms.rb
112
79
  - lib/elk.rb
@@ -125,41 +92,32 @@ files:
125
92
  - spec/fixtures/server_error.txt
126
93
  - spec/fixtures/sms_history.txt
127
94
  - spec/fixtures/updates_a_number.txt
95
+ - spec/spec.opts
128
96
  - spec/spec_helper.rb
129
97
  - README.MD
130
- has_rdoc: true
131
- homepage:
98
+ homepage: https://github.com/jage/elk
132
99
  licenses: []
133
-
134
100
  post_install_message:
135
101
  rdoc_options: []
136
-
137
- require_paths:
102
+ require_paths:
138
103
  - lib
139
- required_ruby_version: !ruby/object:Gem::Requirement
104
+ required_ruby_version: !ruby/object:Gem::Requirement
140
105
  none: false
141
- requirements:
142
- - - ">="
143
- - !ruby/object:Gem::Version
144
- hash: 3
145
- segments:
146
- - 0
147
- version: "0"
148
- required_rubygems_version: !ruby/object:Gem::Requirement
106
+ requirements:
107
+ - - ! '>='
108
+ - !ruby/object:Gem::Version
109
+ version: '0'
110
+ required_rubygems_version: !ruby/object:Gem::Requirement
149
111
  none: false
150
- requirements:
151
- - - ">="
152
- - !ruby/object:Gem::Version
153
- hash: 3
154
- segments:
155
- - 0
156
- version: "0"
157
- requirements: []
158
-
112
+ requirements:
113
+ - - ! '>='
114
+ - !ruby/object:Gem::Version
115
+ version: '0'
116
+ requirements:
117
+ - API account at 46elks.com
159
118
  rubyforge_project:
160
- rubygems_version: 1.3.7
119
+ rubygems_version: 1.8.10
161
120
  signing_key:
162
121
  specification_version: 3
163
122
  summary: Client library for 46elks SMS/MMS/Voice service.
164
123
  test_files: []
165
-