rumeme 0.1.2 → 0.1.3

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/CHANGELOG CHANGED
@@ -1,3 +1,14 @@
1
+ Version 0.1.3 - 2010-03-11
2
+ ===============================================================================
3
+
4
+ antlypls (5):
5
+ fix rake file
6
+ change long messages settings
7
+ minor code cleanup
8
+ refactor internals
9
+ code cleanup
10
+
11
+
1
12
  Version 0.1.2 - 2010-03-11
2
13
  ===============================================================================
3
14
 
@@ -21,3 +32,4 @@ antlypls (5):
21
32
 
22
33
 
23
34
 
35
+
data/Rakefile CHANGED
@@ -132,12 +132,12 @@ task :push_gem do
132
132
  system "gem push pkg/#{gemspec.name}-#{gemspec.version}.gem"
133
133
  end
134
134
 
135
- desc 'release gem'
136
- task :release, :part do |t, args|
135
+ desc 'Preparing release'
136
+ task :prepare_release, :part do |t, args|
137
137
  Rake::Task['bump'].invoke(args[:part])
138
138
  Rake::Task['change'].invoke
139
139
  Rake::Task['push'].invoke
140
- Rake::Task['gem'].invoke
141
- Rake::Task['push_gem'].invoke
142
140
  end
143
141
 
142
+ desc 'Building and publishing gem'
143
+ task :publish_release => [:gem, :push_gem]
@@ -1,11 +1,17 @@
1
1
  module Rumeme
2
+ # Holds configuration attributes for sms interface
2
3
  class Configuration
3
4
  attr_accessor :username
4
5
  attr_accessor :password
5
6
  attr_accessor :use_message_id
6
7
  attr_accessor :secure
7
- attr_accessor :allow_splitting
8
- attr_accessor :allow_long_messages
8
+
9
+ #
10
+ # possible values
11
+ # :send - sends messages as is without any modification
12
+ # :split - splits messages into small (less than 160 ch) messages
13
+ # :cut - sends only first 160 symbols
14
+ attr_accessor :long_messages_strategy
9
15
  end
10
16
  end
11
17
 
@@ -7,6 +7,7 @@ module Rumeme
7
7
 
8
8
  # This is the main class used to interface with the M4U SMS messaging server.
9
9
  class SmsInterface
10
+
10
11
  # allow_splitting, allow_long_messages, response_code, response_message, username, password, use_message_id, secure, http_connection, server_list, message_list,
11
12
  # http_proxy, http_proxy_port, http_proxy_auth, https_proxy, https_proxy_port, https_proxy_auth, text_buffer,
12
13
 
@@ -18,24 +19,21 @@ module Rumeme
18
19
  # The allowLongMessages parameter enables messages longer than 160
19
20
  # characters to be sent as special concatenated messages. For this
20
21
  # to take effect, the allowSplitting parameter must be set to false.
21
-
22
22
  def initialize
23
23
  @username = Rumeme.configuration.username
24
24
  @password = Rumeme.configuration.password
25
25
  @use_message_id = Rumeme.configuration.use_message_id
26
26
  @secure = Rumeme.configuration.secure
27
+ @long_messages_strategy = Rumeme.configuration.long_messages_strategy
27
28
 
28
- @allow_splitting, @allow_long_messages = Rumeme.configuration.allow_splitting, Rumeme.configuration.allow_long_messages
29
-
30
29
  @response_code = -1
31
30
  @response_message = nil
32
31
  @message_list = []
33
- @http_connection = nil
34
32
  @http_proxy = nil
35
33
  @http_proxy_port = 80
36
34
  @http_proxy_auth = nil
37
35
  @https_proxy = nil
38
- @https_proxy_port = 443;
36
+ @https_proxy_port = 443
39
37
  @https_proxy_auth = nil
40
38
  @text_buffer = nil
41
39
  @server_list = ["smsmaster.m4u.com.au", "smsmaster1.m4u.com.au", "smsmaster2.m4u.com.au"]
@@ -61,67 +59,16 @@ module Rumeme
61
59
  raise 'proxy is not supported'
62
60
  end
63
61
 
64
- # Return the response code received from calls to
65
- # changePassword, getCreditsRemaining, sendMessages, and
66
- # checkReplies.
67
- attr_reader :response_code
68
-
69
- # Return the message that was returned with the response code.
70
- attr_reader :response_message
71
-
72
62
  # Add a message to be sent.
73
- def add_message args
74
- p 'in add_message '
63
+ def add_message args
64
+ p 'in add_message '
75
65
  args[:phone_number] = strip_invalid(args[:phone_number]) #not good idea, modifying original args, from outer scope (antlypls)
76
66
 
77
67
  raise ArgumentError.new("phone_number is empty") if args[:phone_number].nil? || args[:phone_number].empty?
78
68
  raise ArgumentError.new("message is empty") if args[:message].nil? || args[:message].empty?
79
69
 
80
- if args[:message].length <= 160
81
- @message_list << SmsMessage.new(args)
82
- return
83
- end
84
-
85
- if (@allow_long_messages) # Use concatenation.
86
- args[:message] = args[:message][0..1071] # 1071??? WTF ??? see php code (antlypls)
87
- @message_list << SmsMessage.new(args)
88
- return
89
- end
90
-
91
- if !@allow_splitting
92
- args[:message] = args[:message][0..160] # maybe 159 ? (antlypls)
93
- @message_list << SmsMessage.new(args)
94
- return
95
- end
96
-
97
- ml = []
98
- maxlen = 152
99
- message_text = args[:message]
100
- while message_text.length > maxlen
101
- if (pos = message_text[0..maxlen].rindex(" ")) == 0
102
- pos = maxlen - 1
103
- end
104
-
105
- ml << message_text[0..pos+1]
106
- message_text = message_text[pos + 1 .. -1]
107
- maxlen = 147;
108
- end
109
- ml << message_text
110
-
111
- ml.each_index {|i|
112
- ni = i + 1
113
- if (i == 0)
114
- m = ml[i]
115
- else
116
- m = "(#{ni}/#{ml.size})#{ml[i]}"
117
- end
118
-
119
- if (ni != ml.size )
120
- m << "...(#{ni}/#{ml.size})"
121
- end
122
-
123
- @message_list << SmsMessage.new(args.merge({:message => m, :delay => args[:delay] + 30*i}))
124
- }
70
+ messages = process_long_message(args[:message])
71
+ @message_list.concat(messages.map{|m| SmsMessage.new(args.merge({:message => m}))})
125
72
  end
126
73
 
127
74
  # Clear all the messages from the list.
@@ -129,26 +76,13 @@ module Rumeme
129
76
  @message_list.clear
130
77
  end
131
78
 
132
- # Open a connection to the specified server.
133
- # proxy is not supported
134
79
  def open_server_connection server, secure
135
- p "in open_server_connection: #{server} #{secure}"
136
- if secure
137
- @http_connection = Net::HTTP.new(server, 443)
138
- @http_connection.use_ssl = true
139
-
140
- else
141
- @http_connection = Net::HTTP.new(server, 80)
142
- end
80
+ port, use_ssl = secure ? [443, true] : [80, false]
143
81
 
144
- p @http_connection.inspect
145
-
146
- @http_connection.nil? ? false : true
147
- end
148
-
149
- # 4 php api compatibility, returns response code from latest http flush
150
- def read_response_code
151
- @latest_response_code
82
+ http_connection = Net::HTTP.new(server, port)
83
+ http_connection.verify_mode = OpenSSL::SSL::VERIFY_NONE
84
+ http_connection.use_ssl = use_ssl
85
+ http_connection
152
86
  end
153
87
 
154
88
  # Change the password on the local machine and server.
@@ -159,60 +93,31 @@ module Rumeme
159
93
 
160
94
  # Return the list of replies we have received.
161
95
  def check_replies auto_confirm = true
162
- connect
163
96
  p 'in check_replies'
164
- return nil if @http_connection.nil?
165
- @text_buffer << "CHECKREPLY2.0\r\n.\r\n"
166
-
167
- if (!flush_buffer || read_response_code != 150)
168
- close
169
- return nil
170
- end
171
97
 
172
- p @response_message
98
+ response_message, response_code = post_data_to_server("CHECKREPLY2.0\r\n.\r\n")
99
+ return if response_code != 150
173
100
 
174
- messages = @response_message.split("\r\n")[1..-2].map{|message_line| SmsReply.parse(message_line, @use_message_id)}
175
-
176
- close
177
-
178
- if auto_confirm && messages.size > 0
179
- confirm_replies_received
180
- end
101
+ messages = response_message.split("\r\n")[1..-2].map{|message_line| SmsReply.parse(message_line, @use_message_id)}
102
+ confirm_replies_received if auto_confirm && messages.size > 0
181
103
 
182
104
  return messages
183
105
  end
184
106
 
185
107
  # sends confirmation to server
186
108
  def confirm_replies_received
187
- connect
188
109
  p 'in confirm_replies_received'
189
- return nil if @http_connection.nil?
190
- ok = true
191
-
192
- @text_buffer << "CONFIRM_RECEIVED\r\n.\r\n";
193
- if !flush_buffer
194
- ok = false
195
- end
196
-
197
- close
198
- p "result: #{ok}"
199
-
200
- return ok;
110
+ post_data_to_server "CONFIRM_RECEIVED\r\n.\r\n"
201
111
  end
202
112
 
203
113
  # Returns the credits remaining (for prepaid users only).
204
114
  def get_credits_remaining
205
- connect
206
- return -2 if @http_connection.nil?
207
- @text_buffer << "MESSAGES\r\n.\r\n"
115
+ p 'in get_credits_remaining'
208
116
 
209
- if (!flush_buffer)
210
- close
211
- return -2
212
- end
117
+ response_message, response_code = post_data_to_server("MESSAGES\r\n.\r\n")
213
118
 
214
119
  if response_message =~ /^(\d+)\s+OK\s+(\d+).+/
215
- if $1.to_i != 100
120
+ if response_code != 100
216
121
  p 'M4U code is not 100'
217
122
  return -1
218
123
  end
@@ -226,70 +131,90 @@ module Rumeme
226
131
  # Sends all the messages that have been added with the
227
132
  # add_message command.
228
133
  def send_messages
229
- connect
230
- return false if @http_connection.nil?
231
- @text_buffer << "MESSAGES2.0\r\n"
134
+ text_buffer = "MESSAGES2.0\r\n"
232
135
 
233
136
  @message_list.each {|sm|
234
137
  s = "#{sm.message_id} #{sm.phone_number} #{sm.delay} #{sm.validity_period} "
235
138
  s << (sm.delivery_report ? "1 " : "0 ")
236
- s << "#{sm.message}\r\n";
237
- @text_buffer << s
139
+ s << "#{sm.message}\r\n"
140
+ text_buffer << s
238
141
  }
142
+ text_buffer << ".\r\n"
239
143
 
240
- ok = true
241
- @text_buffer << ".\r\n";
242
- if (!flush_buffer || (read_response_code / 100) != 1)
243
- ok = false;
244
- end
144
+ response_message, response_code = post_data_to_server(text_buffer)
245
145
 
246
- close
247
- return ok
146
+ return response_code == 100 ? true : false
248
147
  end
249
148
 
250
149
  private
251
150
 
151
+ def process_long_message message
152
+ return [message] if message.length <= 160
153
+ case @long_messages_strategy
154
+ when :send
155
+ [message]
156
+ when :cut
157
+ [message[0..160]]
158
+ when :split
159
+ SmsInterface.split_message message
160
+ else
161
+ raise 'unknown long_messages_strategy'
162
+ end
163
+ end
164
+
165
+ def self.split_message message
166
+ messages = split_message_internal message
167
+ i = 1
168
+ ["#{messages[0]}...(1/#{messages.size})"].concat(messages[1..-1].map {|m| "(#{i+=1}/#{messages.size})#{m}"})
169
+ end
170
+
171
+ def self.split_message_internal message
172
+ list =[]
173
+
174
+ head, message = head_tail_split(message, 152)
175
+ list << head
176
+
177
+ while !message.nil? do
178
+ head, message = head_tail_split(message, 155)
179
+ list << head
180
+ end
181
+
182
+ list
183
+ end
184
+
185
+ def self.head_tail_split message, max_len
186
+ return [message, nil] if message.length < max_len
187
+ pattern = /\s\.,!;:-\)/
188
+ index = message[0..max_len].rindex(pattern) || max_len
189
+ [message[0..index], message[index+1 .. -1]]
190
+ end
191
+
252
192
  # Strip invalid characters from the phone number.
253
193
  def strip_invalid phone
254
194
  return if phone.nil?
255
195
  "+#{phone.gsub(/[^0-9]/, '')}"
256
196
  end
257
197
 
258
- # Connect to the M4U server
259
- def connect
260
- p 'in connect'
261
- return unless @http_connection.nil?
262
-
263
- @server_list.all? {|server| !open_server_connection(server, @secure)} # unusefull code open_server_connection,
264
- # does not connect to server, just creates http object,
265
- # so we can't check availability of the server at this moment (antlypls)
198
+ def post_data_to_server data
199
+ p 'post_data_to_server'
266
200
 
267
- return if @http_connection.nil?
201
+ http_connection = open_server_connection(@server_list[0], @secure)
268
202
 
269
- @text_buffer = "m4u\r\nUSER=#{@username}"
203
+ text_buffer = "m4u\r\nUSER=#{@username}"
270
204
  if @use_message_id
271
- @text_buffer << "#"
205
+ text_buffer << "#"
272
206
  end
273
- @text_buffer << "\r\nPASSWORD=#{@password}\r\nVER=PHP1.0\r\n";
274
- end
207
+ text_buffer << "\r\nPASSWORD=#{@password}\r\nVER=PHP1.0\r\n"
275
208
 
276
- # only for php compatibility, just free object reference
277
- def close
278
- @http_connection = nil unless @http_connection.nil?
279
- end
209
+ text_buffer << data
280
210
 
281
- # Flush the text buffer to the HTTP connection.
282
- def flush_buffer
283
- p 'in flush_buffer'
284
- p "buffer: #{@text_buffer}"
285
- headers = {
286
- 'Content-Length' => @text_buffer.length.to_s
287
- }
211
+ p "buffer: #{text_buffer}"
212
+ headers = {'Content-Length' => text_buffer.length.to_s}
288
213
 
289
214
  path = '/'
290
215
 
291
216
  begin
292
- resp, data = @http_connection.post(path, @text_buffer, headers)
217
+ resp, data = http_connection.post(path, text_buffer, headers)
293
218
  p resp.inspect
294
219
  p data.inspect
295
220
  rescue
@@ -297,28 +222,25 @@ module Rumeme
297
222
  return false
298
223
  end
299
224
 
300
-
301
225
  if resp.code.to_i != 200
302
226
  p 'http response code != 200'
303
227
  return false
304
228
  end
305
229
 
306
- @latest_response_code = @response_code = resp.code.to_i
307
-
308
230
  doc = Nokogiri::HTML(data)
309
231
 
310
232
  return false if doc.xpath('//title').text != "M4U SMSMASTER"
311
233
 
312
- @response_message = @latest_response = doc.xpath('//body').text.strip
313
- if @response_message =~ /^(\d+)\s+/
314
- @latest_response_code = @response_code = $1.to_i
234
+ response_message = doc.xpath('//body').text.strip
235
+ response_code = nil
236
+ if response_message =~ /^(\d+)\s+/
237
+ response_code = $1.to_i
315
238
  end
316
239
 
317
- p "latest response code: #{ @latest_response_code}"
318
- p "response #{@response_message.inspect}"
240
+ p "latest response code: #{response_code}"
241
+ p "response #{response_message }"
319
242
 
320
- @text_buffer = ''
321
- return true
243
+ [response_message, response_code]
322
244
  end
323
245
  end
324
246
  end
@@ -1,3 +1,3 @@
1
1
  module Rumeme
2
- VERSION = "0.1.2".freeze
2
+ VERSION = "0.1.3".freeze
3
3
  end
metadata CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
5
5
  segments:
6
6
  - 0
7
7
  - 1
8
- - 2
9
- version: 0.1.2
8
+ - 3
9
+ version: 0.1.3
10
10
  platform: ruby
11
11
  authors:
12
12
  - antlypls